From 8a032256bf29f2c86ebcfaf5a9da3cdb49e890c2 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 1 May 2020 17:25:39 +0100 Subject: [PATCH 001/644] don't define __USE_MINGW_ANSI_STDIO in makefiles (according to modern MinGW versions, defining this macro directly is deprecated) --- src/win32/Makefile.cfg | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/win32/Makefile.cfg b/src/win32/Makefile.cfg index 27926b208..90ebbd794 100644 --- a/src/win32/Makefile.cfg +++ b/src/win32/Makefile.cfg @@ -59,7 +59,8 @@ endif ifndef SDL OPTS+=-D_WINDOWS endif - OPTS+=-D__USE_MINGW_ANSI_STDIO=0 + # Do we need this? + #OPTS+=-D__USE_MINGW_ANSI_STDIO=0 ifndef SDL LIBS+=-lmingw32 -mwindows -ldinput -ldxguid -lgdi32 -lwinmm From 43e53368b5ca27d55e05f9ece3013f6f8209aaa9 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 12 Jul 2020 21:31:25 +0100 Subject: [PATCH 002/644] added tabbing to some of the preprocessor code in i_tcp.c and mserv.c to make it easier to read them (and to allow me to understand what I need to do for the next commit) --- src/i_tcp.c | 196 ++++++++++++++++++++++++++-------------------------- src/mserv.c | 76 ++++++++++---------- 2 files changed, 135 insertions(+), 137 deletions(-) diff --git a/src/i_tcp.c b/src/i_tcp.c index 5180869a5..3c5923d2c 100644 --- a/src/i_tcp.c +++ b/src/i_tcp.c @@ -20,127 +20,127 @@ #endif #ifndef NO_IPV6 -#define HAVE_IPV6 + #define HAVE_IPV6 #endif #ifdef _WIN32 -#define USE_WINSOCK -#if defined (_WIN64) || defined (HAVE_IPV6) -#define USE_WINSOCK2 -#else //_WIN64/HAVE_IPV6 -#define USE_WINSOCK1 -#endif + #define USE_WINSOCK + #if defined (_WIN64) || defined (HAVE_IPV6) + #define USE_WINSOCK2 + #else //_WIN64/HAVE_IPV6 + #define USE_WINSOCK1 + #endif #endif //WIN32 OS #ifdef USE_WINSOCK2 -#include + #include #endif #include "doomdef.h" #if defined (NOMD5) && !defined (NONET) -//#define NONET + //#define NONET #endif #ifdef NONET -#undef HAVE_MINIUPNPC + #undef HAVE_MINIUPNPC #else -#ifdef USE_WINSOCK1 -#include -#elif !defined (SCOUW2) && !defined (SCOUW7) -#ifndef USE_WINSOCK -#include -#endif //normal BSD API + #ifdef USE_WINSOCK1 + #include + #elif !defined (SCOUW2) && !defined (SCOUW7) + #ifndef USE_WINSOCK + #include + #endif //normal BSD API -#ifndef USE_WINSOCK -#ifdef __APPLE_CC__ -#ifndef _BSD_SOCKLEN_T_ -#define _BSD_SOCKLEN_T_ -#endif //_BSD_SOCKLEN_T_ -#endif //__APPLE_CC__ -#include -#include -#endif //normal BSD API + #ifndef USE_WINSOCK + #ifdef __APPLE_CC__ + #ifndef _BSD_SOCKLEN_T_ + #define _BSD_SOCKLEN_T_ + #endif //_BSD_SOCKLEN_T_ + #endif //__APPLE_CC__ + #include + #include + #endif //normal BSD API -#ifndef USE_WINSOCK -#include -#include -#endif //normal BSD API + #ifndef USE_WINSOCK + #include + #include + #endif //normal BSD API -#include -#include + #include + #include -#if (defined (__unix__) && !defined (MSDOS)) || defined(__APPLE__) || defined (UNIXCOMMON) - #include -#endif // UNIXCOMMON -#endif // !NONET + #if (defined (__unix__) && !defined (MSDOS)) || defined(__APPLE__) || defined (UNIXCOMMON) + #include + #endif // UNIXCOMMON + #endif // !defined (SCOUW2) && !defined (SCOUW7)) -#ifdef USE_WINSOCK - // some undefined under win32 - #undef errno - //#define errno WSAGetLastError() //Alam_GBC: this is the correct way, right? - #define errno h_errno // some very strange things happen when not using h_error?!? - #ifdef EWOULDBLOCK - #undef EWOULDBLOCK - #endif - #define EWOULDBLOCK WSAEWOULDBLOCK - #ifdef EMSGSIZE - #undef EMSGSIZE - #endif - #define EMSGSIZE WSAEMSGSIZE - #ifdef ECONNREFUSED - #undef ECONNREFUSED - #endif - #define ECONNREFUSED WSAECONNREFUSED - #ifdef ETIMEDOUT - #undef ETIMEDOUT - #endif - #define ETIMEDOUT WSAETIMEDOUT - #ifndef IOC_VENDOR - #define IOC_VENDOR 0x18000000 - #endif - #ifndef _WSAIOW - #define _WSAIOW(x,y) (IOC_IN|(x)|(y)) - #endif - #ifndef SIO_UDP_CONNRESET - #define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR,12) - #endif - #ifndef AI_ADDRCONFIG - #define AI_ADDRCONFIG 0x00000400 - #endif - #ifndef STATUS_INVALID_PARAMETER - #define STATUS_INVALID_PARAMETER 0xC000000D - #endif -#endif + #ifdef USE_WINSOCK + // some undefined under win32 + #undef errno + //#define errno WSAGetLastError() //Alam_GBC: this is the correct way, right? + #define errno h_errno // some very strange things happen when not using h_error?!? + #ifdef EWOULDBLOCK + #undef EWOULDBLOCK + #endif + #define EWOULDBLOCK WSAEWOULDBLOCK + #ifdef EMSGSIZE + #undef EMSGSIZE + #endif + #define EMSGSIZE WSAEMSGSIZE + #ifdef ECONNREFUSED + #undef ECONNREFUSED + #endif + #define ECONNREFUSED WSAECONNREFUSED + #ifdef ETIMEDOUT + #undef ETIMEDOUT + #endif + #define ETIMEDOUT WSAETIMEDOUT + #ifndef IOC_VENDOR + #define IOC_VENDOR 0x18000000 + #endif + #ifndef _WSAIOW + #define _WSAIOW(x,y) (IOC_IN|(x)|(y)) + #endif + #ifndef SIO_UDP_CONNRESET + #define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR,12) + #endif + #ifndef AI_ADDRCONFIG + #define AI_ADDRCONFIG 0x00000400 + #endif + #ifndef STATUS_INVALID_PARAMETER + #define STATUS_INVALID_PARAMETER 0xC000000D + #endif + #endif // USE_WINSOCK -#ifdef __DJGPP__ -#ifdef WATTCP // Alam_GBC: Wattcp may need this -#include -#define strerror strerror_s -#else // wattcp -#include -#endif // libsocket -#endif // djgpp + #ifdef __DJGPP__ + #ifdef WATTCP // Alam_GBC: Wattcp may need this + #include + #define strerror strerror_s + #else // wattcp + #include + #endif // libsocket + #endif // djgpp -typedef union -{ - struct sockaddr any; - struct sockaddr_in ip4; -#ifdef HAVE_IPV6 - struct sockaddr_in6 ip6; -#endif -} mysockaddr_t; + typedef union + { + struct sockaddr any; + struct sockaddr_in ip4; + #ifdef HAVE_IPV6 + struct sockaddr_in6 ip6; + #endif + } mysockaddr_t; -#ifdef HAVE_MINIUPNPC -#ifdef STATIC_MINIUPNPC -#define STATICLIB -#endif -#include "miniupnpc/miniwget.h" -#include "miniupnpc/miniupnpc.h" -#include "miniupnpc/upnpcommands.h" -#undef STATICLIB -static UINT8 UPNP_support = TRUE; -#endif + #ifdef HAVE_MINIUPNPC + #ifdef STATIC_MINIUPNPC + #define STATICLIB + #endif + #include "miniupnpc/miniwget.h" + #include "miniupnpc/miniupnpc.h" + #include "miniupnpc/upnpcommands.h" + #undef STATICLIB + static UINT8 UPNP_support = TRUE; + #endif // HAVE_MINIUPNC #endif // !NONET diff --git a/src/mserv.c b/src/mserv.c index 05a5344ba..58fb36bcb 100644 --- a/src/mserv.c +++ b/src/mserv.c @@ -19,37 +19,35 @@ #include #if (defined (NOMSERV)) && !defined (NONET) -#define NONET + #define NONET #endif #ifndef NONET + #ifndef NO_IPV6 + #define HAVE_IPV6 + #endif + #ifdef _WIN32 + #define RPC_NO_WINDOWS_H + #ifdef HAVE_IPV6 + #include + #else + #include // socket(),... + #endif //!HAVE_IPV6 + #else + #include + #ifdef __APPLE_CC__ + #ifndef _BSD_SOCKLEN_T_ + #define _BSD_SOCKLEN_T_ + #endif + #endif + #include // socket(),... + #include // sockaddr_in + #include // getaddrinfo(),... + #include -#ifndef NO_IPV6 -#define HAVE_IPV6 -#endif - -#ifdef _WIN32 -#define RPC_NO_WINDOWS_H -#ifdef HAVE_IPV6 -#include -#else -#include // socket(),... -#endif //!HAVE_IPV6 -#else -#include -#ifdef __APPLE_CC__ -#ifndef _BSD_SOCKLEN_T_ -#define _BSD_SOCKLEN_T_ -#endif -#endif -#include // socket(),... -#include // sockaddr_in -#include // getaddrinfo(),... -#include - -#include // timeval,... (TIMEOUT) -#include -#endif // _WIN32 + #include // timeval,... (TIMEOUT) + #include + #endif // _WIN32 #endif // !NONET #include "doomstat.h" @@ -155,18 +153,18 @@ typedef struct // win32 or djgpp #if defined (_WIN32) || defined (__DJGPP__) -#define ioctl ioctlsocket -#define close closesocket -#ifdef WATTCP -#define strerror strerror_s -#endif -#ifdef _WIN32 -#undef errno -#define errno h_errno // some very strange things happen when not using h_error -#endif -#ifndef AI_ADDRCONFIG -#define AI_ADDRCONFIG 0x00000400 -#endif + #define ioctl ioctlsocket + #define close closesocket + #ifdef WATTCP + #define strerror strerror_s + #endif + #ifdef _WIN32 + #undef errno + #define errno h_errno // some very strange things happen when not using h_error + #endif + #ifndef AI_ADDRCONFIG + #define AI_ADDRCONFIG 0x00000400 + #endif #endif #ifndef NONET From e133d8ec373b35e9b4e4a11bd0f8d09adb46d51e Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 12 Jul 2020 22:08:35 +0100 Subject: [PATCH 003/644] i_tcp.c: SCOUW2 and SCOUW7 haven't been defined since we got rid of Doom Legacy's makefiles for UnixWare 2/7 (which are ANCIENT), so get rid of them! --- src/i_tcp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/i_tcp.c b/src/i_tcp.c index 3c5923d2c..e20e43ea4 100644 --- a/src/i_tcp.c +++ b/src/i_tcp.c @@ -47,7 +47,7 @@ #else #ifdef USE_WINSOCK1 #include - #elif !defined (SCOUW2) && !defined (SCOUW7) + #else #ifndef USE_WINSOCK #include #endif //normal BSD API @@ -73,7 +73,7 @@ #if (defined (__unix__) && !defined (MSDOS)) || defined(__APPLE__) || defined (UNIXCOMMON) #include #endif // UNIXCOMMON - #endif // !defined (SCOUW2) && !defined (SCOUW7)) + #endif #ifdef USE_WINSOCK // some undefined under win32 From 0f4487eb68475d772b24469815c82f429c98abbb Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 12 Jul 2020 22:24:10 +0100 Subject: [PATCH 004/644] * i_tcp.c: merge these three ifndef USE_WINSOCK blocks together * mserv.c: added i_tcp.c's USE_WINSOCK macros so socklen_t isn't redundantly defined if Winsock 2 is used --- src/i_tcp.c | 6 ------ src/mserv.c | 15 ++++++++++++++- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/i_tcp.c b/src/i_tcp.c index e20e43ea4..4738b9df8 100644 --- a/src/i_tcp.c +++ b/src/i_tcp.c @@ -50,9 +50,6 @@ #else #ifndef USE_WINSOCK #include - #endif //normal BSD API - - #ifndef USE_WINSOCK #ifdef __APPLE_CC__ #ifndef _BSD_SOCKLEN_T_ #define _BSD_SOCKLEN_T_ @@ -60,9 +57,6 @@ #endif //__APPLE_CC__ #include #include - #endif //normal BSD API - - #ifndef USE_WINSOCK #include #include #endif //normal BSD API diff --git a/src/mserv.c b/src/mserv.c index 58fb36bcb..84fdca80e 100644 --- a/src/mserv.c +++ b/src/mserv.c @@ -22,6 +22,19 @@ #define NONET #endif +#ifndef NO_IPV6 + #define HAVE_IPV6 +#endif + +#ifdef _WIN32 + #define USE_WINSOCK + #if /*defined (_WIN64) ||*/ defined (HAVE_IPV6) + #define USE_WINSOCK2 + #else //_WIN64/HAVE_IPV6 + #define USE_WINSOCK1 + #endif +#endif //WIN32 OS + #ifndef NONET #ifndef NO_IPV6 #define HAVE_IPV6 @@ -196,7 +209,7 @@ typedef unsigned long SOCKET_TYPE; #define ERRSOCKET (-1) #endif -#if (defined (WATTCP) && !defined (__libsocket_socklen_t)) || defined (_WIN32) +#if (defined (WATTCP) && !defined (__libsocket_socklen_t)) || defined (USE_WINSOCK1) typedef int socklen_t; #endif From b8a794e37fb5e0c8be987585c940637aa066b7eb Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 12 Jul 2020 22:29:15 +0100 Subject: [PATCH 005/644] socklen_t isn't actually needed in either i_tcp.c or mserv.c if NONET is on! (also added some more tabbing) --- src/i_tcp.c | 43 +++++++++++++++++++++---------------------- src/mserv.c | 31 +++++++++++++++---------------- 2 files changed, 36 insertions(+), 38 deletions(-) diff --git a/src/i_tcp.c b/src/i_tcp.c index 4738b9df8..efd381765 100644 --- a/src/i_tcp.c +++ b/src/i_tcp.c @@ -171,32 +171,31 @@ #define DEFAULTPORT "5029" #if defined (USE_WINSOCK) && !defined (NONET) -typedef SOCKET SOCKET_TYPE; -#define ERRSOCKET (SOCKET_ERROR) + typedef SOCKET SOCKET_TYPE; + #define ERRSOCKET (SOCKET_ERROR) #else -#if (defined (__unix__) && !defined (MSDOS)) || defined (__APPLE__) || defined (__HAIKU__) -typedef int SOCKET_TYPE; -#else -typedef unsigned long SOCKET_TYPE; -#endif -#define ERRSOCKET (-1) -#endif - -#if (defined (WATTCP) && !defined (__libsocket_socklen_t)) || defined (USE_WINSOCK1) -typedef int socklen_t; + #if (defined (__unix__) && !defined (MSDOS)) || defined (__APPLE__) || defined (__HAIKU__) + typedef int SOCKET_TYPE; + #else + typedef unsigned long SOCKET_TYPE; + #endif + #define ERRSOCKET (-1) #endif #ifndef NONET -static SOCKET_TYPE mysockets[MAXNETNODES+1] = {ERRSOCKET}; -static size_t mysocketses = 0; -static int myfamily[MAXNETNODES+1] = {0}; -static SOCKET_TYPE nodesocket[MAXNETNODES+1] = {ERRSOCKET}; -static mysockaddr_t clientaddress[MAXNETNODES+1]; -static mysockaddr_t broadcastaddress[MAXNETNODES+1]; -static size_t broadcastaddresses = 0; -static boolean nodeconnected[MAXNETNODES+1]; -static mysockaddr_t banned[MAXBANS]; -static UINT8 bannedmask[MAXBANS]; + #if (defined (WATTCP) && !defined (__libsocket_socklen_t)) || defined (USE_WINSOCK1) + typedef int socklen_t; + #endif + static SOCKET_TYPE mysockets[MAXNETNODES+1] = {ERRSOCKET}; + static size_t mysocketses = 0; + static int myfamily[MAXNETNODES+1] = {0}; + static SOCKET_TYPE nodesocket[MAXNETNODES+1] = {ERRSOCKET}; + static mysockaddr_t clientaddress[MAXNETNODES+1]; + static mysockaddr_t broadcastaddress[MAXNETNODES+1]; + static size_t broadcastaddresses = 0; + static boolean nodeconnected[MAXNETNODES+1]; + static mysockaddr_t banned[MAXBANS]; + static UINT8 bannedmask[MAXBANS]; #endif static size_t numbans = 0; diff --git a/src/mserv.c b/src/mserv.c index 84fdca80e..da163d7f6 100644 --- a/src/mserv.c +++ b/src/mserv.c @@ -198,26 +198,25 @@ static INT32 msnode = -1; UINT16 current_port = 0; #if defined (_WIN32) && !defined (NONET) -typedef SOCKET SOCKET_TYPE; -#define ERRSOCKET (SOCKET_ERROR) + typedef SOCKET SOCKET_TYPE; + #define ERRSOCKET (SOCKET_ERROR) #else -#if (defined (__unix__) && !defined (MSDOS)) || defined (__APPLE__) || defined (__HAIKU__) -typedef int SOCKET_TYPE; -#else -typedef unsigned long SOCKET_TYPE; -#endif -#define ERRSOCKET (-1) -#endif - -#if (defined (WATTCP) && !defined (__libsocket_socklen_t)) || defined (USE_WINSOCK1) -typedef int socklen_t; + #if (defined (__unix__) && !defined (MSDOS)) || defined (__APPLE__) || defined (__HAIKU__) + typedef int SOCKET_TYPE; + #else + typedef unsigned long SOCKET_TYPE; + #endif + #define ERRSOCKET (-1) #endif #ifndef NONET -static SOCKET_TYPE socket_fd = ERRSOCKET; // WINSOCK socket -static struct timeval select_timeout; -static fd_set wset; -static size_t recvfull(SOCKET_TYPE s, char *buf, size_t len, int flags); + #if (defined (WATTCP) && !defined (__libsocket_socklen_t)) || defined (USE_WINSOCK1) + typedef int socklen_t; + #endif + static SOCKET_TYPE socket_fd = ERRSOCKET; // WINSOCK socket + static struct timeval select_timeout; + static fd_set wset; + static size_t recvfull(SOCKET_TYPE s, char *buf, size_t len, int flags); #endif // Room list is an external variable now. From ed70675df35eee1c185f07f8a774fa9c44117d5b Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 12 Jul 2020 22:37:36 +0100 Subject: [PATCH 006/644] added some helpful comments, remove duplicate code --- src/i_tcp.c | 1 + src/mserv.c | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/i_tcp.c b/src/i_tcp.c index efd381765..ab8a69a9f 100644 --- a/src/i_tcp.c +++ b/src/i_tcp.c @@ -183,6 +183,7 @@ #endif #ifndef NONET + // define socklen_t in DOS/Windows if it is not already defined #if (defined (WATTCP) && !defined (__libsocket_socklen_t)) || defined (USE_WINSOCK1) typedef int socklen_t; #endif diff --git a/src/mserv.c b/src/mserv.c index da163d7f6..72243e950 100644 --- a/src/mserv.c +++ b/src/mserv.c @@ -26,9 +26,11 @@ #define HAVE_IPV6 #endif +// -- Monster Iestyn 12/07/20 +// define Winsock related macros like in i_tcp.c (this is really all for socklen_t tbh) #ifdef _WIN32 #define USE_WINSOCK - #if /*defined (_WIN64) ||*/ defined (HAVE_IPV6) + #if /*defined (_WIN64) ||*/ defined (HAVE_IPV6) // (to be consistent with below code) #define USE_WINSOCK2 #else //_WIN64/HAVE_IPV6 #define USE_WINSOCK1 @@ -36,9 +38,6 @@ #endif //WIN32 OS #ifndef NONET - #ifndef NO_IPV6 - #define HAVE_IPV6 - #endif #ifdef _WIN32 #define RPC_NO_WINDOWS_H #ifdef HAVE_IPV6 @@ -210,6 +209,7 @@ UINT16 current_port = 0; #endif #ifndef NONET + // define socklen_t in DOS/Windows if it is not already defined #if (defined (WATTCP) && !defined (__libsocket_socklen_t)) || defined (USE_WINSOCK1) typedef int socklen_t; #endif From 3b79ca4fae6fce10d9a45bbc3fa81e0d66cc9600 Mon Sep 17 00:00:00 2001 From: Zippy_Zolton Date: Sun, 18 Oct 2020 16:00:01 -0500 Subject: [PATCH 007/644] Improved text colormaps --- src/console.c | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/src/console.c b/src/console.c index 3eee67bb8..76c46538c 100644 --- a/src/console.c +++ b/src/console.c @@ -359,27 +359,31 @@ static void CON_SetupColormaps(void) for (i = 0; i < (256*15); i++, ++memorysrc) *memorysrc = (UINT8)(i & 0xFF); // remap each color to itself... -#define colset(map, a, b, c) \ +#define colset(map, a, b, c, d, e) \ map[1] = (UINT8)a;\ - map[3] = (UINT8)b;\ - map[9] = (UINT8)c + map[2] = (UINT8)b;\ + map[3] = (UINT8)c;\ + map[8] = (UINT8)d;\ + map[9] = (UINT8)e - colset(magentamap, 177, 178, 184); - colset(yellowmap, 82, 73, 66); - colset(lgreenmap, 97, 98, 106); - colset(bluemap, 146, 147, 155); - colset(redmap, 210, 32, 39); - colset(graymap, 6, 8, 14); - colset(orangemap, 51, 52, 57); - colset(skymap, 129, 130, 133); - colset(purplemap, 160, 161, 163); - colset(aquamap, 120, 121, 123); - colset(peridotmap, 88, 188, 190); - colset(azuremap, 144, 145, 170); - colset(brownmap, 219, 221, 224); - colset(rosymap, 200, 201, 203); - colset(invertmap, 27, 26, 22); + colset(magentamap, 177, 178, 180, 181, 183); + colset(yellowmap, 82, 73, 74, 75, 76); + colset(lgreenmap, 96, 112, 113, 114, 115); + colset(bluemap, 148, 149, 150, 151, 152); + colset(redmap, 33, 34, 35, 37, 39); + colset(graymap, 9, 11, 13, 15, 17); + colset(orangemap, 50, 52, 54, 56, 58); + colset(skymap, 129, 130, 132, 134, 135); + colset(purplemap, 161, 162, 163, 164, 166); + colset(aquamap, 121, 122, 123, 124, 125); + colset(peridotmap, 73, 188, 189, 190, 191); + colset(azuremap, 144, 145, 170, 171, 172); + colset(brownmap, 224, 226, 228, 230, 232); + colset(rosymap, 200, 201, 202, 203, 204); + colset(invertmap, 30, 29, 27, 25, 23); invertmap[26] = (UINT8)3; + invertmap[30] = (UINT8)1; + invertmap[31] = (UINT8)0; #undef colset From 14aec09d1317ef6cdec97352e383a7418dcba976 Mon Sep 17 00:00:00 2001 From: Zippy_Zolton Date: Sun, 18 Oct 2020 16:21:06 -0500 Subject: [PATCH 008/644] possibly fixed --- src/console.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/console.c b/src/console.c index 76c46538c..66e04c198 100644 --- a/src/console.c +++ b/src/console.c @@ -360,11 +360,11 @@ static void CON_SetupColormaps(void) *memorysrc = (UINT8)(i & 0xFF); // remap each color to itself... #define colset(map, a, b, c, d, e) \ - map[1] = (UINT8)a;\ + map[0] = (UINT8)a;\ map[2] = (UINT8)b;\ - map[3] = (UINT8)c;\ - map[8] = (UINT8)d;\ - map[9] = (UINT8)e + map[4] = (UINT8)c;\ + map[6] = (UINT8)d;\ + map[8] = (UINT8)e colset(magentamap, 177, 178, 180, 181, 183); colset(yellowmap, 82, 73, 74, 75, 76); From 94cee68d4141ae09453c55fdf4eca4623c286707 Mon Sep 17 00:00:00 2001 From: Zippy_Zolton Date: Sun, 18 Oct 2020 16:41:14 -0500 Subject: [PATCH 009/644] Calloc --- src/console.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/console.c b/src/console.c index 66e04c198..b0eb2ce0f 100644 --- a/src/console.c +++ b/src/console.c @@ -333,7 +333,7 @@ static void CONS_backcolor_Change(void) static void CON_SetupColormaps(void) { INT32 i; - UINT8 *memorysrc = (UINT8 *)Z_Malloc((256*15), PU_STATIC, NULL); + UINT8 *memorysrc = (UINT8 *)Z_Calloc((256*15), PU_STATIC, NULL); magentamap = memorysrc; yellowmap = (magentamap+256); From 2403cbd57ba725c92e028d99467ac8828f1f51c5 Mon Sep 17 00:00:00 2001 From: Zippy_Zolton Date: Sun, 18 Oct 2020 17:01:31 -0500 Subject: [PATCH 010/644] possibly final --- src/console.c | 49 ++++++++++++++++++++++++++----------------------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/src/console.c b/src/console.c index b0eb2ce0f..8780bf5d2 100644 --- a/src/console.c +++ b/src/console.c @@ -360,30 +360,33 @@ static void CON_SetupColormaps(void) *memorysrc = (UINT8)(i & 0xFF); // remap each color to itself... #define colset(map, a, b, c, d, e) \ - map[0] = (UINT8)a;\ - map[2] = (UINT8)b;\ - map[4] = (UINT8)c;\ - map[6] = (UINT8)d;\ - map[8] = (UINT8)e + map[1] = (UINT8)a;\ + map[3] = (UINT8)b;\ + map[5] = (UINT8)c;\ + map[7] = (UINT8)d;\ + map[9] = (UINT8)e - colset(magentamap, 177, 178, 180, 181, 183); - colset(yellowmap, 82, 73, 74, 75, 76); - colset(lgreenmap, 96, 112, 113, 114, 115); - colset(bluemap, 148, 149, 150, 151, 152); - colset(redmap, 33, 34, 35, 37, 39); - colset(graymap, 9, 11, 13, 15, 17); - colset(orangemap, 50, 52, 54, 56, 58); - colset(skymap, 129, 130, 132, 134, 135); - colset(purplemap, 161, 162, 163, 164, 166); - colset(aquamap, 121, 122, 123, 124, 125); - colset(peridotmap, 73, 188, 189, 190, 191); - colset(azuremap, 144, 145, 170, 171, 172); - colset(brownmap, 224, 226, 228, 230, 232); - colset(rosymap, 200, 201, 202, 203, 204); - colset(invertmap, 30, 29, 27, 25, 23); - invertmap[26] = (UINT8)3; - invertmap[30] = (UINT8)1; - invertmap[31] = (UINT8)0; + colset(magentamap, 178, 179, 181, 182, 184); + colset(yellowmap, 83, 74, 75, 76, 77); + colset(lgreenmap, 97, 113, 114, 115, 116); + colset(bluemap, 149, 150, 151, 152, 153); + colset(redmap, 34, 35, 36, 38, 40); + colset(graymap, 10, 12, 14, 16, 18); + colset(orangemap, 51, 53, 55, 57, 59); + colset(skymap, 130, 131, 133, 135, 136); + colset(purplemap, 162, 163, 164, 165, 167); + colset(aquamap, 122, 123, 124, 125, 126); + colset(peridotmap, 74, 189, 190, 191, 192); + colset(azuremap, 145, 146, 171, 172, 173); + colset(brownmap, 225, 227, 229, 231, 233); + colset(rosymap, 201, 202, 203, 204, 205); + colset(invertmap, 31, 30, 28, 26, 24); + invertmap[27] = (UINT8)6; + invertmap[28] = (UINT8)5; + invertmap[29] = (UINT8)4; + invertmap[30] = (UINT8)3; + invertmap[31] = (UINT8)2; + invertmap[32] = (UINT8)1; #undef colset From e2d686ba42b42f4b1ab902672b5c10ad0f4a5dd2 Mon Sep 17 00:00:00 2001 From: Zippy_Zolton Date: Sun, 18 Oct 2020 17:45:46 -0500 Subject: [PATCH 011/644] update --- src/console.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/console.c b/src/console.c index 8780bf5d2..bffa6d18c 100644 --- a/src/console.c +++ b/src/console.c @@ -360,11 +360,11 @@ static void CON_SetupColormaps(void) *memorysrc = (UINT8)(i & 0xFF); // remap each color to itself... #define colset(map, a, b, c, d, e) \ - map[1] = (UINT8)a;\ - map[3] = (UINT8)b;\ - map[5] = (UINT8)c;\ - map[7] = (UINT8)d;\ - map[9] = (UINT8)e + map[1] = (UINT8)a;\ + map[3] = (UINT8)b;\ + map[5] = (UINT8)c;\ + map[9] = (UINT8)d;\ + map[15] = (UINT8)e colset(magentamap, 178, 179, 181, 182, 184); colset(yellowmap, 83, 74, 75, 76, 77); @@ -381,6 +381,7 @@ static void CON_SetupColormaps(void) colset(brownmap, 225, 227, 229, 231, 233); colset(rosymap, 201, 202, 203, 204, 205); colset(invertmap, 31, 30, 28, 26, 24); + invertmap[26] = (UINT8)7; invertmap[27] = (UINT8)6; invertmap[28] = (UINT8)5; invertmap[29] = (UINT8)4; From 5dc90289dc7ced8b21386b78d15dae012ca5d53b Mon Sep 17 00:00:00 2001 From: Zippy_Zolton Date: Sun, 18 Oct 2020 21:59:34 -0500 Subject: [PATCH 012/644] thanks goldie --- src/console.c | 68 +++++++++++++++++++++++++++++---------------------- 1 file changed, 39 insertions(+), 29 deletions(-) diff --git a/src/console.c b/src/console.c index bffa6d18c..7927ea925 100644 --- a/src/console.c +++ b/src/console.c @@ -333,7 +333,7 @@ static void CONS_backcolor_Change(void) static void CON_SetupColormaps(void) { INT32 i; - UINT8 *memorysrc = (UINT8 *)Z_Calloc((256*15), PU_STATIC, NULL); + UINT8 *memorysrc = (UINT8 *)Z_Malloc((256*15), PU_STATIC, NULL); magentamap = memorysrc; yellowmap = (magentamap+256); @@ -359,38 +359,48 @@ static void CON_SetupColormaps(void) for (i = 0; i < (256*15); i++, ++memorysrc) *memorysrc = (UINT8)(i & 0xFF); // remap each color to itself... -#define colset(map, a, b, c, d, e) \ - map[1] = (UINT8)a;\ - map[3] = (UINT8)b;\ - map[5] = (UINT8)c;\ - map[9] = (UINT8)d;\ - map[15] = (UINT8)e +#define colset(map, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) \ + map[0x0] = (UINT8)a;\ + map[0x1] = (UINT8)b;\ + map[0x2] = (UINT8)c;\ + map[0x3] = (UINT8)d;\ + map[0x4] = (UINT8)e;\ + map[0x5] = (UINT8)f;\ + map[0x6] = (UINT8)g;\ + map[0x7] = (UINT8)h;\ + map[0x8] = (UINT8)i;\ + map[0x9] = (UINT8)j;\ + map[0xA] = (UINT8)k;\ + map[0xB] = (UINT8)l;\ + map[0xC] = (UINT8)m;\ + map[0xD] = (UINT8)n;\ + map[0xE] = (UINT8)o;\ + map[0xF] = (UINT8)p; - colset(magentamap, 178, 179, 181, 182, 184); - colset(yellowmap, 83, 74, 75, 76, 77); - colset(lgreenmap, 97, 113, 114, 115, 116); - colset(bluemap, 149, 150, 151, 152, 153); - colset(redmap, 34, 35, 36, 38, 40); - colset(graymap, 10, 12, 14, 16, 18); - colset(orangemap, 51, 53, 55, 57, 59); - colset(skymap, 130, 131, 133, 135, 136); - colset(purplemap, 162, 163, 164, 165, 167); - colset(aquamap, 122, 123, 124, 125, 126); - colset(peridotmap, 74, 189, 190, 191, 192); - colset(azuremap, 145, 146, 171, 172, 173); - colset(brownmap, 225, 227, 229, 231, 233); - colset(rosymap, 201, 202, 203, 204, 205); - colset(invertmap, 31, 30, 28, 26, 24); - invertmap[26] = (UINT8)7; - invertmap[27] = (UINT8)6; - invertmap[28] = (UINT8)5; - invertmap[29] = (UINT8)4; - invertmap[30] = (UINT8)3; - invertmap[31] = (UINT8)2; - invertmap[32] = (UINT8)1; + // I tried to make them kinda close to the originals, tell me how I did! ~Golden + + // 0x1 0x3 0x9 0xF + colset(magentamap, 177, 177, 178, 178, 179, 179, 180, 180, 181, 181, 182, 182, 183, 183, 184, 184); + colset(yellowmap, 82, 82, 72, 73, 74, 74, 64, 64, 65, 65, 65, 66, 66, 66, 67, 67); + colset(lgreenmap, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111); + colset(bluemap, 147, 147, 148, 148, 149, 149, 149, 150, 150, 150, 151, 151, 151, 152, 152, 152); + colset(redmap, 210, 210, 211, 211, 32, 32, 33, 33, 34, 34, 35, 35, 37, 37, 38, 38); + colset(graymap, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20); + colset(orangemap, 51, 51, 52, 52, 53, 53, 54, 54, 55, 55, 56, 56, 57, 57, 58, 58); + colset(skymap, 129, 129, 130, 130, 131, 131, 132, 132, 133, 133, 134, 134, 135, 135, 136, 136); + colset(purplemap, 160, 160, 161, 161, 162, 162, 162, 163, 163, 163, 164, 164, 164, 165, 165, 165); + colset(aquamap, 128, 120, 121, 121, 122, 122, 123, 123, 123, 123, 124, 124, 124, 125, 125, 125); + colset(peridotmap, 72, 72, 188, 188, 188, 189, 189, 189, 189, 190, 190, 191, 191, 104, 105, 106); + colset(azuremap, 144, 144, 145, 145, 146, 146, 146, 170, 170, 170, 171, 171, 171, 172, 172, 172); + colset(brownmap, 218, 219, 220, 221, 221, 222, 223, 223, 224, 224, 225, 226, 227, 228, 229, 230); + colset(rosymap, 200, 200, 201, 201, 201, 202, 202, 203, 203, 203, 204, 204, 205, 205, 206, 206); #undef colset + // Yeah just straight up invert it like a normal person + for (i = 0x00; i <= 0x1F; i++) + invertmap[0x1F - i] = i; + // Init back colormap CON_SetupBackColormap(); } From fed2fffaa1debb65e26acab4bddf91fd22d3cb22 Mon Sep 17 00:00:00 2001 From: Zippy_Zolton Date: Sun, 18 Oct 2020 22:52:40 -0500 Subject: [PATCH 013/644] better colors --- src/console.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/console.c b/src/console.c index 7927ea925..feffdd338 100644 --- a/src/console.c +++ b/src/console.c @@ -378,22 +378,23 @@ static void CON_SetupColormaps(void) map[0xF] = (UINT8)p; // I tried to make them kinda close to the originals, tell me how I did! ~Golden + // decent but i made most of the colors better thanks for th help :3 // 0x1 0x3 0x9 0xF - colset(magentamap, 177, 177, 178, 178, 179, 179, 180, 180, 181, 181, 182, 182, 183, 183, 184, 184); + colset(magentamap, 176, 176, 177, 177, 178, 178, 179, 179, 180, 180, 181, 181, 182, 182, 183, 183); colset(yellowmap, 82, 82, 72, 73, 74, 74, 64, 64, 65, 65, 65, 66, 66, 66, 67, 67); - colset(lgreenmap, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111); - colset(bluemap, 147, 147, 148, 148, 149, 149, 149, 150, 150, 150, 151, 151, 151, 152, 152, 152); - colset(redmap, 210, 210, 211, 211, 32, 32, 33, 33, 34, 34, 35, 35, 37, 37, 38, 38); + colset(lgreenmap, 96, 96, 97, 97, 98, 98, 99, 99, 100, 100, 101, 101, 102, 102, 103, 103); + colset(bluemap, 144, 144, 145, 145, 146, 146, 146, 147, 147, 147, 148, 148, 148, 149, 149, 149); + colset(redmap, 210, 210, 210, 32, 32, 32, 33, 33, 33, 34, 34, 34, 35, 35, 35, 35); colset(graymap, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20); colset(orangemap, 51, 51, 52, 52, 53, 53, 54, 54, 55, 55, 56, 56, 57, 57, 58, 58); - colset(skymap, 129, 129, 130, 130, 131, 131, 132, 132, 133, 133, 134, 134, 135, 135, 136, 136); - colset(purplemap, 160, 160, 161, 161, 162, 162, 162, 163, 163, 163, 164, 164, 164, 165, 165, 165); - colset(aquamap, 128, 120, 121, 121, 122, 122, 123, 123, 123, 123, 124, 124, 124, 125, 125, 125); - colset(peridotmap, 72, 72, 188, 188, 188, 189, 189, 189, 189, 190, 190, 191, 191, 104, 105, 106); - colset(azuremap, 144, 144, 145, 145, 146, 146, 146, 170, 170, 170, 171, 171, 171, 172, 172, 172); + colset(skymap, 128, 128, 129, 129, 130, 130, 131, 131, 132, 132, 133, 133, 134, 134, 135, 135); + colset(purplemap, 144, 144, 160, 160, 160, 161, 161, 161, 162, 162, 162, 162, 163, 163, 163, 163); + colset(aquamap, 128, 128, 120, 120, 121, 121, 122, 122, 123, 123, 124, 124, 124, 125, 125, 125); + colset(peridotmap, 72, 72, 188, 188, 188, 189, 189, 189, 189, 190, 190, 191, 191, 104, 104, 104); + colset(azuremap, 144, 144, 145, 145, 146, 146, 146, 147, 147, 147, 170, 170, 170, 171, 171, 171); colset(brownmap, 218, 219, 220, 221, 221, 222, 223, 223, 224, 224, 225, 226, 227, 228, 229, 230); - colset(rosymap, 200, 200, 201, 201, 201, 202, 202, 203, 203, 203, 204, 204, 205, 205, 206, 206); + colset(rosymap, 200, 200, 201, 201, 201, 202, 202, 203, 203, 203, 204, 204, 204, 205, 205, 205); #undef colset From e5c891932aaff1ac8c8f285dd57648079c4d878b Mon Sep 17 00:00:00 2001 From: Zippy_Zolton Date: Sun, 18 Oct 2020 23:47:14 -0500 Subject: [PATCH 014/644] improvement --- src/console.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/console.c b/src/console.c index feffdd338..0d32eae85 100644 --- a/src/console.c +++ b/src/console.c @@ -381,13 +381,13 @@ static void CON_SetupColormaps(void) // decent but i made most of the colors better thanks for th help :3 // 0x1 0x3 0x9 0xF - colset(magentamap, 176, 176, 177, 177, 178, 178, 179, 179, 180, 180, 181, 181, 182, 182, 183, 183); + colset(magentamap, 177, 177, 178, 178, 179, 179, 180, 180, 181, 181, 182, 182, 183, 183, 184, 184); colset(yellowmap, 82, 82, 72, 73, 74, 74, 64, 64, 65, 65, 65, 66, 66, 66, 67, 67); - colset(lgreenmap, 96, 96, 97, 97, 98, 98, 99, 99, 100, 100, 101, 101, 102, 102, 103, 103); - colset(bluemap, 144, 144, 145, 145, 146, 146, 146, 147, 147, 147, 148, 148, 148, 149, 149, 149); - colset(redmap, 210, 210, 210, 32, 32, 32, 33, 33, 33, 34, 34, 34, 35, 35, 35, 35); + colset(lgreenmap, 97, 97, 98, 98, 99, 99, 100, 100, 101, 101, 102, 102, 103, 103, 104, 104); + colset(bluemap, 147, 147, 147, 148, 148, 148, 149, 149, 149, 150, 150, 151, 151, 151, 152, 152); + colset(redmap, 33, 33, 33, 34, 34, 34, 35, 35, 35, 36, 36, 36, 37, 37, 37, 37); colset(graymap, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20); - colset(orangemap, 51, 51, 52, 52, 53, 53, 54, 54, 55, 55, 56, 56, 57, 57, 58, 58); + colset(orangemap, 52, 52, 53, 53, 54, 54, 55, 55, 56, 56, 57, 57, 58, 58, 59, 59); colset(skymap, 128, 128, 129, 129, 130, 130, 131, 131, 132, 132, 133, 133, 134, 134, 135, 135); colset(purplemap, 144, 144, 160, 160, 160, 161, 161, 161, 162, 162, 162, 162, 163, 163, 163, 163); colset(aquamap, 128, 128, 120, 120, 121, 121, 122, 122, 123, 123, 124, 124, 124, 125, 125, 125); From d633f2495aeb95f40dce30a7be337621f7f79bee Mon Sep 17 00:00:00 2001 From: Zippy_Zolton Date: Mon, 19 Oct 2020 14:12:28 -0500 Subject: [PATCH 015/644] red abd bkyue sikbucx --- src/console.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/console.c b/src/console.c index 0d32eae85..7b32889ea 100644 --- a/src/console.c +++ b/src/console.c @@ -384,8 +384,8 @@ static void CON_SetupColormaps(void) colset(magentamap, 177, 177, 178, 178, 179, 179, 180, 180, 181, 181, 182, 182, 183, 183, 184, 184); colset(yellowmap, 82, 82, 72, 73, 74, 74, 64, 64, 65, 65, 65, 66, 66, 66, 67, 67); colset(lgreenmap, 97, 97, 98, 98, 99, 99, 100, 100, 101, 101, 102, 102, 103, 103, 104, 104); - colset(bluemap, 147, 147, 147, 148, 148, 148, 149, 149, 149, 150, 150, 151, 151, 151, 152, 152); - colset(redmap, 33, 33, 33, 34, 34, 34, 35, 35, 35, 36, 36, 36, 37, 37, 37, 37); + colset(bluemap, 147, 147, 147, 148, 148, 148, 149, 149, 150, 150, 151, 151, 152, 152, 153, 153); + colset(redmap, 33, 33, 33, 34, 34, 34, 35, 35, 37, 37, 39, 39, 41, 41, 43, 43); colset(graymap, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20); colset(orangemap, 52, 52, 53, 53, 54, 54, 55, 55, 56, 56, 57, 57, 58, 58, 59, 59); colset(skymap, 128, 128, 129, 129, 130, 130, 131, 131, 132, 132, 133, 133, 134, 134, 135, 135); From 81c9d2eae9576b6497e9b53749d36ae15739a3db Mon Sep 17 00:00:00 2001 From: Zippy_Zolton Date: Mon, 19 Oct 2020 18:41:23 -0500 Subject: [PATCH 016/644] forgot to send this like 3 hours ago --- src/console.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/console.c b/src/console.c index 7b32889ea..81d3abaac 100644 --- a/src/console.c +++ b/src/console.c @@ -384,8 +384,8 @@ static void CON_SetupColormaps(void) colset(magentamap, 177, 177, 178, 178, 179, 179, 180, 180, 181, 181, 182, 182, 183, 183, 184, 184); colset(yellowmap, 82, 82, 72, 73, 74, 74, 64, 64, 65, 65, 65, 66, 66, 66, 67, 67); colset(lgreenmap, 97, 97, 98, 98, 99, 99, 100, 100, 101, 101, 102, 102, 103, 103, 104, 104); - colset(bluemap, 147, 147, 147, 148, 148, 148, 149, 149, 150, 150, 151, 151, 152, 152, 153, 153); - colset(redmap, 33, 33, 33, 34, 34, 34, 35, 35, 37, 37, 39, 39, 41, 41, 43, 43); + colset(bluemap, 146, 146, 147, 147, 148, 148, 149, 149, 150, 150, 151, 151, 152, 152, 153, 153); + colset(redmap, 32, 32, 33, 33, 34, 34, 35, 35, 37, 37, 39, 39, 41, 41, 43, 43); colset(graymap, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20); colset(orangemap, 52, 52, 53, 53, 54, 54, 55, 55, 56, 56, 57, 57, 58, 58, 59, 59); colset(skymap, 128, 128, 129, 129, 130, 130, 131, 131, 132, 132, 133, 133, 134, 134, 135, 135); From 04eae86d0a4bfbe0abe762bf705f5c1bddff5579 Mon Sep 17 00:00:00 2001 From: Zippy_Zolton Date: Mon, 19 Oct 2020 19:58:50 -0500 Subject: [PATCH 017/644] t --- src/console.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/console.c b/src/console.c index 81d3abaac..239706679 100644 --- a/src/console.c +++ b/src/console.c @@ -384,8 +384,8 @@ static void CON_SetupColormaps(void) colset(magentamap, 177, 177, 178, 178, 179, 179, 180, 180, 181, 181, 182, 182, 183, 183, 184, 184); colset(yellowmap, 82, 82, 72, 73, 74, 74, 64, 64, 65, 65, 65, 66, 66, 66, 67, 67); colset(lgreenmap, 97, 97, 98, 98, 99, 99, 100, 100, 101, 101, 102, 102, 103, 103, 104, 104); - colset(bluemap, 146, 146, 147, 147, 148, 148, 149, 149, 150, 150, 151, 151, 152, 152, 153, 153); - colset(redmap, 32, 32, 33, 33, 34, 34, 35, 35, 37, 37, 39, 39, 41, 41, 43, 43); + colset(bluemap, 146, 146, 147, 147, 148, 148, 149, 149, 150, 150, 151, 151, 151, 152, 152, 152); + colset(redmap, 32, 32, 33, 33, 34, 34, 35, 35, 37, 37, 39, 39, 39, 41, 41, 41); colset(graymap, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20); colset(orangemap, 52, 52, 53, 53, 54, 54, 55, 55, 56, 56, 57, 57, 58, 58, 59, 59); colset(skymap, 128, 128, 129, 129, 130, 130, 131, 131, 132, 132, 133, 133, 134, 134, 135, 135); From 4e985d71457fde8f342e4069ac5a251b4ed611f6 Mon Sep 17 00:00:00 2001 From: Zippy_Zolton Date: Mon, 19 Oct 2020 20:36:59 -0500 Subject: [PATCH 018/644] blue & red really seem like a hassle don't they --- src/console.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/console.c b/src/console.c index 239706679..b66c73bd4 100644 --- a/src/console.c +++ b/src/console.c @@ -384,8 +384,8 @@ static void CON_SetupColormaps(void) colset(magentamap, 177, 177, 178, 178, 179, 179, 180, 180, 181, 181, 182, 182, 183, 183, 184, 184); colset(yellowmap, 82, 82, 72, 73, 74, 74, 64, 64, 65, 65, 65, 66, 66, 66, 67, 67); colset(lgreenmap, 97, 97, 98, 98, 99, 99, 100, 100, 101, 101, 102, 102, 103, 103, 104, 104); - colset(bluemap, 146, 146, 147, 147, 148, 148, 149, 149, 150, 150, 151, 151, 151, 152, 152, 152); - colset(redmap, 32, 32, 33, 33, 34, 34, 35, 35, 37, 37, 39, 39, 39, 41, 41, 41); + colset(bluemap, 146, 146, 147, 147, 148, 148, 148, 149, 149, 149, 150, 150, 150, 151, 151, 151); + colset(redmap, 32, 32, 33, 33, 34, 34, 34, 35, 35, 35, 37, 37, 37, 39, 39, 39); colset(graymap, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20); colset(orangemap, 52, 52, 53, 53, 54, 54, 55, 55, 56, 56, 57, 57, 58, 58, 59, 59); colset(skymap, 128, 128, 129, 129, 130, 130, 131, 131, 132, 132, 133, 133, 134, 134, 135, 135); From 0b48f1052a1941b5f2fcf7ef790aca319c5ea4bd Mon Sep 17 00:00:00 2001 From: Zippy_Zolton Date: Tue, 20 Oct 2020 14:03:27 -0500 Subject: [PATCH 019/644] pencilvoid aqua --- src/console.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/console.c b/src/console.c index b66c73bd4..ed15e583e 100644 --- a/src/console.c +++ b/src/console.c @@ -390,7 +390,7 @@ static void CON_SetupColormaps(void) colset(orangemap, 52, 52, 53, 53, 54, 54, 55, 55, 56, 56, 57, 57, 58, 58, 59, 59); colset(skymap, 128, 128, 129, 129, 130, 130, 131, 131, 132, 132, 133, 133, 134, 134, 135, 135); colset(purplemap, 144, 144, 160, 160, 160, 161, 161, 161, 162, 162, 162, 162, 163, 163, 163, 163); - colset(aquamap, 128, 128, 120, 120, 121, 121, 122, 122, 123, 123, 124, 124, 124, 125, 125, 125); + colset(aquamap, 128, 120, 120, 121, 121, 122, 123, 123, 123, 124, 124, 124, 125, 125, 126, 126); colset(peridotmap, 72, 72, 188, 188, 188, 189, 189, 189, 189, 190, 190, 191, 191, 104, 104, 104); colset(azuremap, 144, 144, 145, 145, 146, 146, 146, 147, 147, 147, 170, 170, 170, 171, 171, 171); colset(brownmap, 218, 219, 220, 221, 221, 222, 223, 223, 224, 224, 225, 226, 227, 228, 229, 230); From b65ac1df30ad11101ff30e4199181d743478e1f3 Mon Sep 17 00:00:00 2001 From: Zippy_Zolton Date: Tue, 20 Oct 2020 14:40:10 -0500 Subject: [PATCH 020/644] sonicx azure --- src/console.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/console.c b/src/console.c index ed15e583e..c181f670c 100644 --- a/src/console.c +++ b/src/console.c @@ -392,7 +392,7 @@ static void CON_SetupColormaps(void) colset(purplemap, 144, 144, 160, 160, 160, 161, 161, 161, 162, 162, 162, 162, 163, 163, 163, 163); colset(aquamap, 128, 120, 120, 121, 121, 122, 123, 123, 123, 124, 124, 124, 125, 125, 126, 126); colset(peridotmap, 72, 72, 188, 188, 188, 189, 189, 189, 189, 190, 190, 191, 191, 104, 104, 104); - colset(azuremap, 144, 144, 145, 145, 146, 146, 146, 147, 147, 147, 170, 170, 170, 171, 171, 171); + colset(azuremap, 144, 144, 145, 145, 146, 146, 146, 170, 170, 170, 171, 171, 171, 172, 172, 172); colset(brownmap, 218, 219, 220, 221, 221, 222, 223, 223, 224, 224, 225, 226, 227, 228, 229, 230); colset(rosymap, 200, 200, 201, 201, 201, 202, 202, 203, 203, 203, 204, 204, 204, 205, 205, 205); From 45dd26476a7d20a8f3ffd041a96e4de9103471bc Mon Sep 17 00:00:00 2001 From: Zippy_Zolton Date: Tue, 20 Oct 2020 14:52:25 -0500 Subject: [PATCH 021/644] SonicX8000 purple, peridot, rosy --- src/console.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/console.c b/src/console.c index c181f670c..64c07f619 100644 --- a/src/console.c +++ b/src/console.c @@ -389,12 +389,12 @@ static void CON_SetupColormaps(void) colset(graymap, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20); colset(orangemap, 52, 52, 53, 53, 54, 54, 55, 55, 56, 56, 57, 57, 58, 58, 59, 59); colset(skymap, 128, 128, 129, 129, 130, 130, 131, 131, 132, 132, 133, 133, 134, 134, 135, 135); - colset(purplemap, 144, 144, 160, 160, 160, 161, 161, 161, 162, 162, 162, 162, 163, 163, 163, 163); + colset(purplemap, 144, 144, 160, 160, 161, 161, 161, 162, 162, 162, 163, 163, 163, 164, 164, 164); colset(aquamap, 128, 120, 120, 121, 121, 122, 123, 123, 123, 124, 124, 124, 125, 125, 126, 126); - colset(peridotmap, 72, 72, 188, 188, 188, 189, 189, 189, 189, 190, 190, 191, 191, 104, 104, 104); + colset(peridotmap, 72, 72, 188, 188, 189, 189, 189, 190, 190, 190, 191, 191, 191, 104, 104, 104); colset(azuremap, 144, 144, 145, 145, 146, 146, 146, 170, 170, 170, 171, 171, 171, 172, 172, 172); colset(brownmap, 218, 219, 220, 221, 221, 222, 223, 223, 224, 224, 225, 226, 227, 228, 229, 230); - colset(rosymap, 200, 200, 201, 201, 201, 202, 202, 203, 203, 203, 204, 204, 204, 205, 205, 205); + colset(rosymap, 200, 200, 201, 201, 202, 202, 202, 203, 203, 203, 204, 204, 204, 205, 205, 205); #undef colset From 03198ab31dd9a5e9eb791b1134d55677a2f0c782 Mon Sep 17 00:00:00 2001 From: Zippy_Zolton Date: Tue, 20 Oct 2020 14:59:30 -0500 Subject: [PATCH 022/644] SonicX aqua --- src/console.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/console.c b/src/console.c index 64c07f619..daa5f7f1b 100644 --- a/src/console.c +++ b/src/console.c @@ -390,7 +390,7 @@ static void CON_SetupColormaps(void) colset(orangemap, 52, 52, 53, 53, 54, 54, 55, 55, 56, 56, 57, 57, 58, 58, 59, 59); colset(skymap, 128, 128, 129, 129, 130, 130, 131, 131, 132, 132, 133, 133, 134, 134, 135, 135); colset(purplemap, 144, 144, 160, 160, 161, 161, 161, 162, 162, 162, 163, 163, 163, 164, 164, 164); - colset(aquamap, 128, 120, 120, 121, 121, 122, 123, 123, 123, 124, 124, 124, 125, 125, 126, 126); + colset(aquamap, 120, 120, 121, 121, 122, 122, 122, 123, 123, 123, 124, 124, 124, 125, 125, 125); colset(peridotmap, 72, 72, 188, 188, 189, 189, 189, 190, 190, 190, 191, 191, 191, 104, 104, 104); colset(azuremap, 144, 144, 145, 145, 146, 146, 146, 170, 170, 170, 171, 171, 171, 172, 172, 172); colset(brownmap, 218, 219, 220, 221, 221, 222, 223, 223, 224, 224, 225, 226, 227, 228, 229, 230); From 0f771edfd527f5c96d00d8da9d5065ac02f8b9f2 Mon Sep 17 00:00:00 2001 From: Zippy_Zolton Date: Tue, 20 Oct 2020 15:11:00 -0500 Subject: [PATCH 023/644] SonicX orange --- src/console.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/console.c b/src/console.c index daa5f7f1b..5d85ca663 100644 --- a/src/console.c +++ b/src/console.c @@ -387,7 +387,7 @@ static void CON_SetupColormaps(void) colset(bluemap, 146, 146, 147, 147, 148, 148, 148, 149, 149, 149, 150, 150, 150, 151, 151, 151); colset(redmap, 32, 32, 33, 33, 34, 34, 34, 35, 35, 35, 37, 37, 37, 39, 39, 39); colset(graymap, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20); - colset(orangemap, 52, 52, 53, 53, 54, 54, 55, 55, 56, 56, 57, 57, 58, 58, 59, 59); + colset(orangemap, 51, 51, 52, 52, 53, 53, 54, 54, 55, 55, 56, 56, 57, 57, 58, 58); colset(skymap, 128, 128, 129, 129, 130, 130, 131, 131, 132, 132, 133, 133, 134, 134, 135, 135); colset(purplemap, 144, 144, 160, 160, 161, 161, 161, 162, 162, 162, 163, 163, 163, 164, 164, 164); colset(aquamap, 120, 120, 121, 121, 122, 122, 122, 123, 123, 123, 124, 124, 124, 125, 125, 125); From 88c882fa9cf9845a0331a7f43011c1a8befe2499 Mon Sep 17 00:00:00 2001 From: Zippy_Zolton Date: Tue, 20 Oct 2020 19:59:33 -0500 Subject: [PATCH 024/644] 81 --- src/console.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/console.c b/src/console.c index 5d85ca663..24ec6443c 100644 --- a/src/console.c +++ b/src/console.c @@ -382,7 +382,7 @@ static void CON_SetupColormaps(void) // 0x1 0x3 0x9 0xF colset(magentamap, 177, 177, 178, 178, 179, 179, 180, 180, 181, 181, 182, 182, 183, 183, 184, 184); - colset(yellowmap, 82, 82, 72, 73, 74, 74, 64, 64, 65, 65, 65, 66, 66, 66, 67, 67); + colset(yellowmap, 81, 81, 73, 73, 74, 74, 74, 65, 65, 65, 66, 66, 66, 67, 67, 67); colset(lgreenmap, 97, 97, 98, 98, 99, 99, 100, 100, 101, 101, 102, 102, 103, 103, 104, 104); colset(bluemap, 146, 146, 147, 147, 148, 148, 148, 149, 149, 149, 150, 150, 150, 151, 151, 151); colset(redmap, 32, 32, 33, 33, 34, 34, 34, 35, 35, 35, 37, 37, 37, 39, 39, 39); From 288ffebea7d79454e455cb6eb2fc44ff25b94db1 Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 24 Oct 2020 15:52:02 -0700 Subject: [PATCH 025/644] Do not save cleared ban list when reloading bans --- src/d_clisrv.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index e314d419f..43ac12c93 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2918,16 +2918,14 @@ static void Ban_Add(const char *reason) reasontail = reasonlist; } -static void Command_ClearBans(void) +static void Ban_Clear(void) { banreason_t *temp; - if (!I_ClearBans) - return; - I_ClearBans(); - D_SaveBan(); + reasontail = NULL; + while (reasonhead) { temp = reasonhead->next; @@ -2937,6 +2935,15 @@ static void Command_ClearBans(void) } } +static void Command_ClearBans(void) +{ + if (!I_ClearBans) + return; + + Ban_Clear(); + D_SaveBan(); +} + static void Ban_Load_File(boolean warning) { FILE *f; @@ -2944,6 +2951,9 @@ static void Ban_Load_File(boolean warning) const char *address, *mask; char buffer[MAX_WADPATH]; + if (!I_ClearBans) + return; + f = fopen(va("%s"PATHSEP"%s", srb2home, "ban.txt"), "r"); if (!f) @@ -2953,13 +2963,7 @@ static void Ban_Load_File(boolean warning) return; } - if (I_ClearBans) - Command_ClearBans(); - else - { - fclose(f); - return; - } + Ban_Clear(); for (i=0; fgets(buffer, (int)sizeof(buffer), f); i++) { From 9278f04fbfa6083f10f980c1fe2914c64aae4dfa Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 24 Oct 2020 15:59:11 -0700 Subject: [PATCH 026/644] Delete ban.txt if no bans to save --- src/d_clisrv.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 43ac12c93..12145c5c8 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2870,11 +2870,15 @@ void D_SaveBan(void) size_t i; banreason_t *reasonlist = reasonhead; const char *address, *mask; + const char *path = va("%s"PATHSEP"%s", srb2home, "ban.txt"); if (!reasonhead) + { + remove(path); return; + } - f = fopen(va("%s"PATHSEP"%s", srb2home, "ban.txt"), "w"); + f = fopen(path, "w"); if (!f) { From 86ad187f05adef9a74290e3d29aff0efa2552aba Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Thu, 22 Oct 2020 00:31:28 +0300 Subject: [PATCH 027/644] NPO2 slope span optimization --- src/CMakeLists.txt | 1 + src/libdivide.h | 2082 ++++++++++++++++++++++++++ src/r_draw.c | 1 + src/r_draw8_npo2.c | 188 ++- src/sdl/Srb2SDL-vc10.vcxproj | 1 + src/sdl/Srb2SDL-vc10.vcxproj.filters | 3 + 6 files changed, 2196 insertions(+), 80 deletions(-) create mode 100644 src/libdivide.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6c0e20e8e..416000ac7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -87,6 +87,7 @@ set(SRB2_CORE_HEADERS i_video.h info.h keys.h + libdivide.h lzf.h m_aatree.h m_anigif.h diff --git a/src/libdivide.h b/src/libdivide.h new file mode 100644 index 000000000..51f9a633b --- /dev/null +++ b/src/libdivide.h @@ -0,0 +1,2082 @@ +// libdivide.h - Optimized integer division +// https://libdivide.com +// +// Copyright (C) 2010 - 2019 ridiculous_fish, +// Copyright (C) 2016 - 2019 Kim Walisch, +// +// libdivide is dual-licensed under the Boost or zlib licenses. +// You may use libdivide under the terms of either of these. +// See LICENSE.txt for more details. + +// NOTICE: This version of libdivide has been modified for use with SRB2. +// Changes made: +// - unused parts commented out (to avoid the need to fix C90 compilation issues with them) +// - C90 compilation issues fixed with used parts +// - use I_Error for errors + +#ifndef LIBDIVIDE_H +#define LIBDIVIDE_H + +#define LIBDIVIDE_VERSION "3.0" +#define LIBDIVIDE_VERSION_MAJOR 3 +#define LIBDIVIDE_VERSION_MINOR 0 + +#include + +#if defined(__cplusplus) + #include + #include + #include +#else + #include + #include +#endif + +#if defined(LIBDIVIDE_AVX512) + #include +#elif defined(LIBDIVIDE_AVX2) + #include +#elif defined(LIBDIVIDE_SSE2) + #include +#endif + +#if defined(_MSC_VER) + #include + // disable warning C4146: unary minus operator applied + // to unsigned type, result still unsigned + #pragma warning(disable: 4146) + #define LIBDIVIDE_VC +#endif + +#if !defined(__has_builtin) + #define __has_builtin(x) 0 +#endif + +#if defined(__SIZEOF_INT128__) + #define HAS_INT128_T + // clang-cl on Windows does not yet support 128-bit division + #if !(defined(__clang__) && defined(LIBDIVIDE_VC)) + #define HAS_INT128_DIV + #endif +#endif + +#if defined(__x86_64__) || defined(_M_X64) + #define LIBDIVIDE_X86_64 +#endif + +#if defined(__i386__) + #define LIBDIVIDE_i386 +#endif + +#if defined(__GNUC__) || defined(__clang__) + #define LIBDIVIDE_GCC_STYLE_ASM +#endif + +#if defined(__cplusplus) || defined(LIBDIVIDE_VC) + #define LIBDIVIDE_FUNCTION __FUNCTION__ +#else + #define LIBDIVIDE_FUNCTION __func__ +#endif + +#define LIBDIVIDE_ERROR(msg) \ + I_Error("libdivide.h:%d: %s(): Error: %s\n", \ + __LINE__, LIBDIVIDE_FUNCTION, msg); + +#if defined(LIBDIVIDE_ASSERTIONS_ON) + #define LIBDIVIDE_ASSERT(x) \ + if (!(x)) { \ + I_Error("libdivide.h:%d: %s(): Assertion failed: %s\n", \ + __LINE__, LIBDIVIDE_FUNCTION, #x); \ + } +#else + #define LIBDIVIDE_ASSERT(x) +#endif + +#ifdef __cplusplus +namespace libdivide { +#endif + +// pack divider structs to prevent compilers from padding. +// This reduces memory usage by up to 43% when using a large +// array of libdivide dividers and improves performance +// by up to 10% because of reduced memory bandwidth. +#pragma pack(push, 1) + +struct libdivide_u32_t { + uint32_t magic; + uint8_t more; +}; + +struct libdivide_s32_t { + int32_t magic; + uint8_t more; +}; + +struct libdivide_u64_t { + uint64_t magic; + uint8_t more; +}; + +struct libdivide_s64_t { + int64_t magic; + uint8_t more; +}; + +struct libdivide_u32_branchfree_t { + uint32_t magic; + uint8_t more; +}; + +struct libdivide_s32_branchfree_t { + int32_t magic; + uint8_t more; +}; + +struct libdivide_u64_branchfree_t { + uint64_t magic; + uint8_t more; +}; + +struct libdivide_s64_branchfree_t { + int64_t magic; + uint8_t more; +}; + +#pragma pack(pop) + +// Explanation of the "more" field: +// +// * Bits 0-5 is the shift value (for shift path or mult path). +// * Bit 6 is the add indicator for mult path. +// * Bit 7 is set if the divisor is negative. We use bit 7 as the negative +// divisor indicator so that we can efficiently use sign extension to +// create a bitmask with all bits set to 1 (if the divisor is negative) +// or 0 (if the divisor is positive). +// +// u32: [0-4] shift value +// [5] ignored +// [6] add indicator +// magic number of 0 indicates shift path +// +// s32: [0-4] shift value +// [5] ignored +// [6] add indicator +// [7] indicates negative divisor +// magic number of 0 indicates shift path +// +// u64: [0-5] shift value +// [6] add indicator +// magic number of 0 indicates shift path +// +// s64: [0-5] shift value +// [6] add indicator +// [7] indicates negative divisor +// magic number of 0 indicates shift path +// +// In s32 and s64 branchfree modes, the magic number is negated according to +// whether the divisor is negated. In branchfree strategy, it is not negated. + +enum { + LIBDIVIDE_32_SHIFT_MASK = 0x1F, + LIBDIVIDE_64_SHIFT_MASK = 0x3F, + LIBDIVIDE_ADD_MARKER = 0x40, + LIBDIVIDE_NEGATIVE_DIVISOR = 0x80 +}; + +//static inline struct libdivide_s32_t libdivide_s32_gen(int32_t d); +static inline struct libdivide_u32_t libdivide_u32_gen(uint32_t d); +//static inline struct libdivide_s64_t libdivide_s64_gen(int64_t d); +//static inline struct libdivide_u64_t libdivide_u64_gen(uint64_t d); + +/*static inline struct libdivide_s32_branchfree_t libdivide_s32_branchfree_gen(int32_t d); +static inline struct libdivide_u32_branchfree_t libdivide_u32_branchfree_gen(uint32_t d); +static inline struct libdivide_s64_branchfree_t libdivide_s64_branchfree_gen(int64_t d); +static inline struct libdivide_u64_branchfree_t libdivide_u64_branchfree_gen(uint64_t d);*/ + +//static inline int32_t libdivide_s32_do(int32_t numer, const struct libdivide_s32_t *denom); +static inline uint32_t libdivide_u32_do(uint32_t numer, const struct libdivide_u32_t *denom); +//static inline int64_t libdivide_s64_do(int64_t numer, const struct libdivide_s64_t *denom); +//static inline uint64_t libdivide_u64_do(uint64_t numer, const struct libdivide_u64_t *denom); + +/*static inline int32_t libdivide_s32_branchfree_do(int32_t numer, const struct libdivide_s32_branchfree_t *denom); +static inline uint32_t libdivide_u32_branchfree_do(uint32_t numer, const struct libdivide_u32_branchfree_t *denom); +static inline int64_t libdivide_s64_branchfree_do(int64_t numer, const struct libdivide_s64_branchfree_t *denom); +static inline uint64_t libdivide_u64_branchfree_do(uint64_t numer, const struct libdivide_u64_branchfree_t *denom);*/ + +/*static inline int32_t libdivide_s32_recover(const struct libdivide_s32_t *denom); +static inline uint32_t libdivide_u32_recover(const struct libdivide_u32_t *denom); +static inline int64_t libdivide_s64_recover(const struct libdivide_s64_t *denom); +static inline uint64_t libdivide_u64_recover(const struct libdivide_u64_t *denom);*/ + +/*static inline int32_t libdivide_s32_branchfree_recover(const struct libdivide_s32_branchfree_t *denom); +static inline uint32_t libdivide_u32_branchfree_recover(const struct libdivide_u32_branchfree_t *denom); +static inline int64_t libdivide_s64_branchfree_recover(const struct libdivide_s64_branchfree_t *denom); +static inline uint64_t libdivide_u64_branchfree_recover(const struct libdivide_u64_branchfree_t *denom);*/ + +//////// Internal Utility Functions + +static inline uint32_t libdivide_mullhi_u32(uint32_t x, uint32_t y) { + uint64_t xl = x, yl = y; + uint64_t rl = xl * yl; + return (uint32_t)(rl >> 32); +} + +static inline int32_t libdivide_mullhi_s32(int32_t x, int32_t y) { + int64_t xl = x, yl = y; + int64_t rl = xl * yl; + // needs to be arithmetic shift + return (int32_t)(rl >> 32); +} + +static inline uint64_t libdivide_mullhi_u64(uint64_t x, uint64_t y) { +#if defined(LIBDIVIDE_VC) && \ + defined(LIBDIVIDE_X86_64) + return __umulh(x, y); +#elif defined(HAS_INT128_T) + __uint128_t xl = x, yl = y; + __uint128_t rl = xl * yl; + return (uint64_t)(rl >> 64); +#else + // full 128 bits are x0 * y0 + (x0 * y1 << 32) + (x1 * y0 << 32) + (x1 * y1 << 64) + uint32_t mask = 0xFFFFFFFF; + uint32_t x0 = (uint32_t)(x & mask); + uint32_t x1 = (uint32_t)(x >> 32); + uint32_t y0 = (uint32_t)(y & mask); + uint32_t y1 = (uint32_t)(y >> 32); + uint32_t x0y0_hi = libdivide_mullhi_u32(x0, y0); + uint64_t x0y1 = x0 * (uint64_t)y1; + uint64_t x1y0 = x1 * (uint64_t)y0; + uint64_t x1y1 = x1 * (uint64_t)y1; + uint64_t temp = x1y0 + x0y0_hi; + uint64_t temp_lo = temp & mask; + uint64_t temp_hi = temp >> 32; + + return x1y1 + temp_hi + ((temp_lo + x0y1) >> 32); +#endif +} + +static inline int64_t libdivide_mullhi_s64(int64_t x, int64_t y) { +#if defined(LIBDIVIDE_VC) && \ + defined(LIBDIVIDE_X86_64) + return __mulh(x, y); +#elif defined(HAS_INT128_T) + __int128_t xl = x, yl = y; + __int128_t rl = xl * yl; + return (int64_t)(rl >> 64); +#else + // full 128 bits are x0 * y0 + (x0 * y1 << 32) + (x1 * y0 << 32) + (x1 * y1 << 64) + uint32_t mask = 0xFFFFFFFF; + uint32_t x0 = (uint32_t)(x & mask); + uint32_t y0 = (uint32_t)(y & mask); + int32_t x1 = (int32_t)(x >> 32); + int32_t y1 = (int32_t)(y >> 32); + uint32_t x0y0_hi = libdivide_mullhi_u32(x0, y0); + int64_t t = x1 * (int64_t)y0 + x0y0_hi; + int64_t w1 = x0 * (int64_t)y1 + (t & mask); + + return x1 * (int64_t)y1 + (t >> 32) + (w1 >> 32); +#endif +} + +static inline int32_t libdivide_count_leading_zeros32(uint32_t val) { +#if defined(__GNUC__) || \ + __has_builtin(__builtin_clz) + // Fast way to count leading zeros + return __builtin_clz(val); +#elif defined(LIBDIVIDE_VC) + unsigned long result; + if (_BitScanReverse(&result, val)) { + return 31 - result; + } + return 0; +#else + if (val == 0) + return 32; + int32_t result = 8; + uint32_t hi = 0xFFU << 24; + while ((val & hi) == 0) { + hi >>= 8; + result += 8; + } + while (val & hi) { + result -= 1; + hi <<= 1; + } + return result; +#endif +} + +static inline int32_t libdivide_count_leading_zeros64(uint64_t val) { +#if defined(__GNUC__) || \ + __has_builtin(__builtin_clzll) + // Fast way to count leading zeros + return __builtin_clzll(val); +#elif defined(LIBDIVIDE_VC) && defined(_WIN64) + unsigned long result; + if (_BitScanReverse64(&result, val)) { + return 63 - result; + } + return 0; +#else + uint32_t hi = val >> 32; + uint32_t lo = val & 0xFFFFFFFF; + if (hi != 0) return libdivide_count_leading_zeros32(hi); + return 32 + libdivide_count_leading_zeros32(lo); +#endif +} + +// libdivide_64_div_32_to_32: divides a 64-bit uint {u1, u0} by a 32-bit +// uint {v}. The result must fit in 32 bits. +// Returns the quotient directly and the remainder in *r +static inline uint32_t libdivide_64_div_32_to_32(uint32_t u1, uint32_t u0, uint32_t v, uint32_t *r) { +#if (defined(LIBDIVIDE_i386) || defined(LIBDIVIDE_X86_64)) && \ + defined(LIBDIVIDE_GCC_STYLE_ASM) + uint32_t result; + __asm__("divl %[v]" + : "=a"(result), "=d"(*r) + : [v] "r"(v), "a"(u0), "d"(u1) + ); + return result; +#else + uint64_t n = ((uint64_t)u1 << 32) | u0; + uint32_t result = (uint32_t)(n / v); + *r = (uint32_t)(n - result * (uint64_t)v); + return result; +#endif +} + +// libdivide_128_div_64_to_64: divides a 128-bit uint {u1, u0} by a 64-bit +// uint {v}. The result must fit in 64 bits. +// Returns the quotient directly and the remainder in *r +/*static uint64_t libdivide_128_div_64_to_64(uint64_t u1, uint64_t u0, uint64_t v, uint64_t *r) { +#if defined(LIBDIVIDE_X86_64) && \ + defined(LIBDIVIDE_GCC_STYLE_ASM) + uint64_t result; + __asm__("divq %[v]" + : "=a"(result), "=d"(*r) + : [v] "r"(v), "a"(u0), "d"(u1) + ); + return result; +#elif defined(HAS_INT128_T) && \ + defined(HAS_INT128_DIV) + __uint128_t n = ((__uint128_t)u1 << 64) | u0; + uint64_t result = (uint64_t)(n / v); + *r = (uint64_t)(n - result * (__uint128_t)v); + return result; +#else + // Code taken from Hacker's Delight: + // http://www.hackersdelight.org/HDcode/divlu.c. + // License permits inclusion here per: + // http://www.hackersdelight.org/permissions.htm + + const uint64_t b = (1ULL << 32); // Number base (32 bits) + uint64_t un1, un0; // Norm. dividend LSD's + uint64_t vn1, vn0; // Norm. divisor digits + uint64_t q1, q0; // Quotient digits + uint64_t un64, un21, un10; // Dividend digit pairs + uint64_t rhat; // A remainder + int32_t s; // Shift amount for norm + + // If overflow, set rem. to an impossible value, + // and return the largest possible quotient + if (u1 >= v) { + *r = (uint64_t) -1; + return (uint64_t) -1; + } + + // count leading zeros + s = libdivide_count_leading_zeros64(v); + if (s > 0) { + // Normalize divisor + v = v << s; + un64 = (u1 << s) | (u0 >> (64 - s)); + un10 = u0 << s; // Shift dividend left + } else { + // Avoid undefined behavior of (u0 >> 64). + // The behavior is undefined if the right operand is + // negative, or greater than or equal to the length + // in bits of the promoted left operand. + un64 = u1; + un10 = u0; + } + + // Break divisor up into two 32-bit digits + vn1 = v >> 32; + vn0 = v & 0xFFFFFFFF; + + // Break right half of dividend into two digits + un1 = un10 >> 32; + un0 = un10 & 0xFFFFFFFF; + + // Compute the first quotient digit, q1 + q1 = un64 / vn1; + rhat = un64 - q1 * vn1; + + while (q1 >= b || q1 * vn0 > b * rhat + un1) { + q1 = q1 - 1; + rhat = rhat + vn1; + if (rhat >= b) + break; + } + + // Multiply and subtract + un21 = un64 * b + un1 - q1 * v; + + // Compute the second quotient digit + q0 = un21 / vn1; + rhat = un21 - q0 * vn1; + + while (q0 >= b || q0 * vn0 > b * rhat + un0) { + q0 = q0 - 1; + rhat = rhat + vn1; + if (rhat >= b) + break; + } + + *r = (un21 * b + un0 - q0 * v) >> s; + return q1 * b + q0; +#endif +}*/ + +// Bitshift a u128 in place, left (signed_shift > 0) or right (signed_shift < 0) +static inline void libdivide_u128_shift(uint64_t *u1, uint64_t *u0, int32_t signed_shift) { + if (signed_shift > 0) { + uint32_t shift = signed_shift; + *u1 <<= shift; + *u1 |= *u0 >> (64 - shift); + *u0 <<= shift; + } + else if (signed_shift < 0) { + uint32_t shift = -signed_shift; + *u0 >>= shift; + *u0 |= *u1 << (64 - shift); + *u1 >>= shift; + } +} + +// Computes a 128 / 128 -> 64 bit division, with a 128 bit remainder. +/*static uint64_t libdivide_128_div_128_to_64(uint64_t u_hi, uint64_t u_lo, uint64_t v_hi, uint64_t v_lo, uint64_t *r_hi, uint64_t *r_lo) { +#if defined(HAS_INT128_T) && \ + defined(HAS_INT128_DIV) + __uint128_t ufull = u_hi; + __uint128_t vfull = v_hi; + ufull = (ufull << 64) | u_lo; + vfull = (vfull << 64) | v_lo; + uint64_t res = (uint64_t)(ufull / vfull); + __uint128_t remainder = ufull - (vfull * res); + *r_lo = (uint64_t)remainder; + *r_hi = (uint64_t)(remainder >> 64); + return res; +#else + // Adapted from "Unsigned Doubleword Division" in Hacker's Delight + // We want to compute u / v + typedef struct { uint64_t hi; uint64_t lo; } u128_t; + u128_t u = {u_hi, u_lo}; + u128_t v = {v_hi, v_lo}; + + if (v.hi == 0) { + // divisor v is a 64 bit value, so we just need one 128/64 division + // Note that we are simpler than Hacker's Delight here, because we know + // the quotient fits in 64 bits whereas Hacker's Delight demands a full + // 128 bit quotient + *r_hi = 0; + return libdivide_128_div_64_to_64(u.hi, u.lo, v.lo, r_lo); + } + // Here v >= 2**64 + // We know that v.hi != 0, so count leading zeros is OK + // We have 0 <= n <= 63 + uint32_t n = libdivide_count_leading_zeros64(v.hi); + + // Normalize the divisor so its MSB is 1 + u128_t v1t = v; + libdivide_u128_shift(&v1t.hi, &v1t.lo, n); + uint64_t v1 = v1t.hi; // i.e. v1 = v1t >> 64 + + // To ensure no overflow + u128_t u1 = u; + libdivide_u128_shift(&u1.hi, &u1.lo, -1); + + // Get quotient from divide unsigned insn. + uint64_t rem_ignored; + uint64_t q1 = libdivide_128_div_64_to_64(u1.hi, u1.lo, v1, &rem_ignored); + + // Undo normalization and division of u by 2. + u128_t q0 = {0, q1}; + libdivide_u128_shift(&q0.hi, &q0.lo, n); + libdivide_u128_shift(&q0.hi, &q0.lo, -63); + + // Make q0 correct or too small by 1 + // Equivalent to `if (q0 != 0) q0 = q0 - 1;` + if (q0.hi != 0 || q0.lo != 0) { + q0.hi -= (q0.lo == 0); // borrow + q0.lo -= 1; + } + + // Now q0 is correct. + // Compute q0 * v as q0v + // = (q0.hi << 64 + q0.lo) * (v.hi << 64 + v.lo) + // = (q0.hi * v.hi << 128) + (q0.hi * v.lo << 64) + + // (q0.lo * v.hi << 64) + q0.lo * v.lo) + // Each term is 128 bit + // High half of full product (upper 128 bits!) are dropped + u128_t q0v = {0, 0}; + q0v.hi = q0.hi*v.lo + q0.lo*v.hi + libdivide_mullhi_u64(q0.lo, v.lo); + q0v.lo = q0.lo*v.lo; + + // Compute u - q0v as u_q0v + // This is the remainder + u128_t u_q0v = u; + u_q0v.hi -= q0v.hi + (u.lo < q0v.lo); // second term is borrow + u_q0v.lo -= q0v.lo; + + // Check if u_q0v >= v + // This checks if our remainder is larger than the divisor + if ((u_q0v.hi > v.hi) || + (u_q0v.hi == v.hi && u_q0v.lo >= v.lo)) { + // Increment q0 + q0.lo += 1; + q0.hi += (q0.lo == 0); // carry + + // Subtract v from remainder + u_q0v.hi -= v.hi + (u_q0v.lo < v.lo); + u_q0v.lo -= v.lo; + } + + *r_hi = u_q0v.hi; + *r_lo = u_q0v.lo; + + LIBDIVIDE_ASSERT(q0.hi == 0); + return q0.lo; +#endif +}*/ + +////////// UINT32 + +static inline struct libdivide_u32_t libdivide_internal_u32_gen(uint32_t d, int branchfree) { + struct libdivide_u32_t result; + uint32_t floor_log_2_d; + + if (d == 0) { + LIBDIVIDE_ERROR("divider must be != 0"); + } + + floor_log_2_d = 31 - libdivide_count_leading_zeros32(d); + + // Power of 2 + if ((d & (d - 1)) == 0) { + // We need to subtract 1 from the shift value in case of an unsigned + // branchfree divider because there is a hardcoded right shift by 1 + // in its division algorithm. Because of this we also need to add back + // 1 in its recovery algorithm. + result.magic = 0; + result.more = (uint8_t)(floor_log_2_d - (branchfree != 0)); + } else { + uint8_t more; + uint32_t rem, proposed_m; + uint32_t e; + proposed_m = libdivide_64_div_32_to_32(1U << floor_log_2_d, 0, d, &rem); + + LIBDIVIDE_ASSERT(rem > 0 && rem < d); + e = d - rem; + + // This power works if e < 2**floor_log_2_d. + if (!branchfree && (e < (1U << floor_log_2_d))) { + // This power works + more = floor_log_2_d; + } else { + // We have to use the general 33-bit algorithm. We need to compute + // (2**power) / d. However, we already have (2**(power-1))/d and + // its remainder. By doubling both, and then correcting the + // remainder, we can compute the larger division. + // don't care about overflow here - in fact, we expect it + const uint32_t twice_rem = rem + rem; + proposed_m += proposed_m; + if (twice_rem >= d || twice_rem < rem) proposed_m += 1; + more = floor_log_2_d | LIBDIVIDE_ADD_MARKER; + } + result.magic = 1 + proposed_m; + result.more = more; + // result.more's shift should in general be ceil_log_2_d. But if we + // used the smaller power, we subtract one from the shift because we're + // using the smaller power. If we're using the larger power, we + // subtract one from the shift because it's taken care of by the add + // indicator. So floor_log_2_d happens to be correct in both cases. + } + return result; +} + +struct libdivide_u32_t libdivide_u32_gen(uint32_t d) { + return libdivide_internal_u32_gen(d, 0); +} + +/*struct libdivide_u32_branchfree_t libdivide_u32_branchfree_gen(uint32_t d) { + if (d == 1) { + LIBDIVIDE_ERROR("branchfree divider must be != 1"); + } + struct libdivide_u32_t tmp = libdivide_internal_u32_gen(d, 1); + struct libdivide_u32_branchfree_t ret = {tmp.magic, (uint8_t)(tmp.more & LIBDIVIDE_32_SHIFT_MASK)}; + return ret; +}*/ + +uint32_t libdivide_u32_do(uint32_t numer, const struct libdivide_u32_t *denom) { + uint8_t more = denom->more; + if (!denom->magic) { + return numer >> more; + } + else { + uint32_t q = libdivide_mullhi_u32(denom->magic, numer); + if (more & LIBDIVIDE_ADD_MARKER) { + uint32_t t = ((numer - q) >> 1) + q; + return t >> (more & LIBDIVIDE_32_SHIFT_MASK); + } + else { + // All upper bits are 0, + // don't need to mask them off. + return q >> more; + } + } +} + +/*uint32_t libdivide_u32_branchfree_do(uint32_t numer, const struct libdivide_u32_branchfree_t *denom) { + uint32_t q = libdivide_mullhi_u32(denom->magic, numer); + uint32_t t = ((numer - q) >> 1) + q; + return t >> denom->more; +} + +uint32_t libdivide_u32_recover(const struct libdivide_u32_t *denom) { + uint8_t more = denom->more; + uint8_t shift = more & LIBDIVIDE_32_SHIFT_MASK; + + if (!denom->magic) { + return 1U << shift; + } else if (!(more & LIBDIVIDE_ADD_MARKER)) { + // We compute q = n/d = n*m / 2^(32 + shift) + // Therefore we have d = 2^(32 + shift) / m + // We need to ceil it. + // We know d is not a power of 2, so m is not a power of 2, + // so we can just add 1 to the floor + uint32_t hi_dividend = 1U << shift; + uint32_t rem_ignored; + return 1 + libdivide_64_div_32_to_32(hi_dividend, 0, denom->magic, &rem_ignored); + } else { + // Here we wish to compute d = 2^(32+shift+1)/(m+2^32). + // Notice (m + 2^32) is a 33 bit number. Use 64 bit division for now + // Also note that shift may be as high as 31, so shift + 1 will + // overflow. So we have to compute it as 2^(32+shift)/(m+2^32), and + // then double the quotient and remainder. + uint64_t half_n = 1ULL << (32 + shift); + uint64_t d = (1ULL << 32) | denom->magic; + // Note that the quotient is guaranteed <= 32 bits, but the remainder + // may need 33! + uint32_t half_q = (uint32_t)(half_n / d); + uint64_t rem = half_n % d; + // We computed 2^(32+shift)/(m+2^32) + // Need to double it, and then add 1 to the quotient if doubling th + // remainder would increase the quotient. + // Note that rem<<1 cannot overflow, since rem < d and d is 33 bits + uint32_t full_q = half_q + half_q + ((rem<<1) >= d); + + // We rounded down in gen (hence +1) + return full_q + 1; + } +} + +uint32_t libdivide_u32_branchfree_recover(const struct libdivide_u32_branchfree_t *denom) { + uint8_t more = denom->more; + uint8_t shift = more & LIBDIVIDE_32_SHIFT_MASK; + + if (!denom->magic) { + return 1U << (shift + 1); + } else { + // Here we wish to compute d = 2^(32+shift+1)/(m+2^32). + // Notice (m + 2^32) is a 33 bit number. Use 64 bit division for now + // Also note that shift may be as high as 31, so shift + 1 will + // overflow. So we have to compute it as 2^(32+shift)/(m+2^32), and + // then double the quotient and remainder. + uint64_t half_n = 1ULL << (32 + shift); + uint64_t d = (1ULL << 32) | denom->magic; + // Note that the quotient is guaranteed <= 32 bits, but the remainder + // may need 33! + uint32_t half_q = (uint32_t)(half_n / d); + uint64_t rem = half_n % d; + // We computed 2^(32+shift)/(m+2^32) + // Need to double it, and then add 1 to the quotient if doubling th + // remainder would increase the quotient. + // Note that rem<<1 cannot overflow, since rem < d and d is 33 bits + uint32_t full_q = half_q + half_q + ((rem<<1) >= d); + + // We rounded down in gen (hence +1) + return full_q + 1; + } +}*/ + +/////////// UINT64 + +/*static inline struct libdivide_u64_t libdivide_internal_u64_gen(uint64_t d, int branchfree) { + if (d == 0) { + LIBDIVIDE_ERROR("divider must be != 0"); + } + + struct libdivide_u64_t result; + uint32_t floor_log_2_d = 63 - libdivide_count_leading_zeros64(d); + + // Power of 2 + if ((d & (d - 1)) == 0) { + // We need to subtract 1 from the shift value in case of an unsigned + // branchfree divider because there is a hardcoded right shift by 1 + // in its division algorithm. Because of this we also need to add back + // 1 in its recovery algorithm. + result.magic = 0; + result.more = (uint8_t)(floor_log_2_d - (branchfree != 0)); + } else { + uint64_t proposed_m, rem; + uint8_t more; + // (1 << (64 + floor_log_2_d)) / d + proposed_m = libdivide_128_div_64_to_64(1ULL << floor_log_2_d, 0, d, &rem); + + LIBDIVIDE_ASSERT(rem > 0 && rem < d); + const uint64_t e = d - rem; + + // This power works if e < 2**floor_log_2_d. + if (!branchfree && e < (1ULL << floor_log_2_d)) { + // This power works + more = floor_log_2_d; + } else { + // We have to use the general 65-bit algorithm. We need to compute + // (2**power) / d. However, we already have (2**(power-1))/d and + // its remainder. By doubling both, and then correcting the + // remainder, we can compute the larger division. + // don't care about overflow here - in fact, we expect it + proposed_m += proposed_m; + const uint64_t twice_rem = rem + rem; + if (twice_rem >= d || twice_rem < rem) proposed_m += 1; + more = floor_log_2_d | LIBDIVIDE_ADD_MARKER; + } + result.magic = 1 + proposed_m; + result.more = more; + // result.more's shift should in general be ceil_log_2_d. But if we + // used the smaller power, we subtract one from the shift because we're + // using the smaller power. If we're using the larger power, we + // subtract one from the shift because it's taken care of by the add + // indicator. So floor_log_2_d happens to be correct in both cases, + // which is why we do it outside of the if statement. + } + return result; +} + +struct libdivide_u64_t libdivide_u64_gen(uint64_t d) { + return libdivide_internal_u64_gen(d, 0); +} + +struct libdivide_u64_branchfree_t libdivide_u64_branchfree_gen(uint64_t d) { + if (d == 1) { + LIBDIVIDE_ERROR("branchfree divider must be != 1"); + } + struct libdivide_u64_t tmp = libdivide_internal_u64_gen(d, 1); + struct libdivide_u64_branchfree_t ret = {tmp.magic, (uint8_t)(tmp.more & LIBDIVIDE_64_SHIFT_MASK)}; + return ret; +} + +uint64_t libdivide_u64_do(uint64_t numer, const struct libdivide_u64_t *denom) { + uint8_t more = denom->more; + if (!denom->magic) { + return numer >> more; + } + else { + uint64_t q = libdivide_mullhi_u64(denom->magic, numer); + if (more & LIBDIVIDE_ADD_MARKER) { + uint64_t t = ((numer - q) >> 1) + q; + return t >> (more & LIBDIVIDE_64_SHIFT_MASK); + } + else { + // All upper bits are 0, + // don't need to mask them off. + return q >> more; + } + } +} + +uint64_t libdivide_u64_branchfree_do(uint64_t numer, const struct libdivide_u64_branchfree_t *denom) { + uint64_t q = libdivide_mullhi_u64(denom->magic, numer); + uint64_t t = ((numer - q) >> 1) + q; + return t >> denom->more; +} + +uint64_t libdivide_u64_recover(const struct libdivide_u64_t *denom) { + uint8_t more = denom->more; + uint8_t shift = more & LIBDIVIDE_64_SHIFT_MASK; + + if (!denom->magic) { + return 1ULL << shift; + } else if (!(more & LIBDIVIDE_ADD_MARKER)) { + // We compute q = n/d = n*m / 2^(64 + shift) + // Therefore we have d = 2^(64 + shift) / m + // We need to ceil it. + // We know d is not a power of 2, so m is not a power of 2, + // so we can just add 1 to the floor + uint64_t hi_dividend = 1ULL << shift; + uint64_t rem_ignored; + return 1 + libdivide_128_div_64_to_64(hi_dividend, 0, denom->magic, &rem_ignored); + } else { + // Here we wish to compute d = 2^(64+shift+1)/(m+2^64). + // Notice (m + 2^64) is a 65 bit number. This gets hairy. See + // libdivide_u32_recover for more on what we do here. + // TODO: do something better than 128 bit math + + // Full n is a (potentially) 129 bit value + // half_n is a 128 bit value + // Compute the hi half of half_n. Low half is 0. + uint64_t half_n_hi = 1ULL << shift, half_n_lo = 0; + // d is a 65 bit value. The high bit is always set to 1. + const uint64_t d_hi = 1, d_lo = denom->magic; + // Note that the quotient is guaranteed <= 64 bits, + // but the remainder may need 65! + uint64_t r_hi, r_lo; + uint64_t half_q = libdivide_128_div_128_to_64(half_n_hi, half_n_lo, d_hi, d_lo, &r_hi, &r_lo); + // We computed 2^(64+shift)/(m+2^64) + // Double the remainder ('dr') and check if that is larger than d + // Note that d is a 65 bit value, so r1 is small and so r1 + r1 + // cannot overflow + uint64_t dr_lo = r_lo + r_lo; + uint64_t dr_hi = r_hi + r_hi + (dr_lo < r_lo); // last term is carry + int dr_exceeds_d = (dr_hi > d_hi) || (dr_hi == d_hi && dr_lo >= d_lo); + uint64_t full_q = half_q + half_q + (dr_exceeds_d ? 1 : 0); + return full_q + 1; + } +} + +uint64_t libdivide_u64_branchfree_recover(const struct libdivide_u64_branchfree_t *denom) { + uint8_t more = denom->more; + uint8_t shift = more & LIBDIVIDE_64_SHIFT_MASK; + + if (!denom->magic) { + return 1ULL << (shift + 1); + } else { + // Here we wish to compute d = 2^(64+shift+1)/(m+2^64). + // Notice (m + 2^64) is a 65 bit number. This gets hairy. See + // libdivide_u32_recover for more on what we do here. + // TODO: do something better than 128 bit math + + // Full n is a (potentially) 129 bit value + // half_n is a 128 bit value + // Compute the hi half of half_n. Low half is 0. + uint64_t half_n_hi = 1ULL << shift, half_n_lo = 0; + // d is a 65 bit value. The high bit is always set to 1. + const uint64_t d_hi = 1, d_lo = denom->magic; + // Note that the quotient is guaranteed <= 64 bits, + // but the remainder may need 65! + uint64_t r_hi, r_lo; + uint64_t half_q = libdivide_128_div_128_to_64(half_n_hi, half_n_lo, d_hi, d_lo, &r_hi, &r_lo); + // We computed 2^(64+shift)/(m+2^64) + // Double the remainder ('dr') and check if that is larger than d + // Note that d is a 65 bit value, so r1 is small and so r1 + r1 + // cannot overflow + uint64_t dr_lo = r_lo + r_lo; + uint64_t dr_hi = r_hi + r_hi + (dr_lo < r_lo); // last term is carry + int dr_exceeds_d = (dr_hi > d_hi) || (dr_hi == d_hi && dr_lo >= d_lo); + uint64_t full_q = half_q + half_q + (dr_exceeds_d ? 1 : 0); + return full_q + 1; + } +}*/ + +/////////// SINT32 + +/*static inline struct libdivide_s32_t libdivide_internal_s32_gen(int32_t d, int branchfree) { + if (d == 0) { + LIBDIVIDE_ERROR("divider must be != 0"); + } + + struct libdivide_s32_t result; + + // If d is a power of 2, or negative a power of 2, we have to use a shift. + // This is especially important because the magic algorithm fails for -1. + // To check if d is a power of 2 or its inverse, it suffices to check + // whether its absolute value has exactly one bit set. This works even for + // INT_MIN, because abs(INT_MIN) == INT_MIN, and INT_MIN has one bit set + // and is a power of 2. + uint32_t ud = (uint32_t)d; + uint32_t absD = (d < 0) ? -ud : ud; + uint32_t floor_log_2_d = 31 - libdivide_count_leading_zeros32(absD); + // check if exactly one bit is set, + // don't care if absD is 0 since that's divide by zero + if ((absD & (absD - 1)) == 0) { + // Branchfree and normal paths are exactly the same + result.magic = 0; + result.more = floor_log_2_d | (d < 0 ? LIBDIVIDE_NEGATIVE_DIVISOR : 0); + } else { + LIBDIVIDE_ASSERT(floor_log_2_d >= 1); + + uint8_t more; + // the dividend here is 2**(floor_log_2_d + 31), so the low 32 bit word + // is 0 and the high word is floor_log_2_d - 1 + uint32_t rem, proposed_m; + proposed_m = libdivide_64_div_32_to_32(1U << (floor_log_2_d - 1), 0, absD, &rem); + const uint32_t e = absD - rem; + + // We are going to start with a power of floor_log_2_d - 1. + // This works if works if e < 2**floor_log_2_d. + if (!branchfree && e < (1U << floor_log_2_d)) { + // This power works + more = floor_log_2_d - 1; + } else { + // We need to go one higher. This should not make proposed_m + // overflow, but it will make it negative when interpreted as an + // int32_t. + proposed_m += proposed_m; + const uint32_t twice_rem = rem + rem; + if (twice_rem >= absD || twice_rem < rem) proposed_m += 1; + more = floor_log_2_d | LIBDIVIDE_ADD_MARKER; + } + + proposed_m += 1; + int32_t magic = (int32_t)proposed_m; + + // Mark if we are negative. Note we only negate the magic number in the + // branchfull case. + if (d < 0) { + more |= LIBDIVIDE_NEGATIVE_DIVISOR; + if (!branchfree) { + magic = -magic; + } + } + + result.more = more; + result.magic = magic; + } + return result; +} + +struct libdivide_s32_t libdivide_s32_gen(int32_t d) { + return libdivide_internal_s32_gen(d, 0); +} + +struct libdivide_s32_branchfree_t libdivide_s32_branchfree_gen(int32_t d) { + struct libdivide_s32_t tmp = libdivide_internal_s32_gen(d, 1); + struct libdivide_s32_branchfree_t result = {tmp.magic, tmp.more}; + return result; +} + +int32_t libdivide_s32_do(int32_t numer, const struct libdivide_s32_t *denom) { + uint8_t more = denom->more; + uint8_t shift = more & LIBDIVIDE_32_SHIFT_MASK; + + if (!denom->magic) { + uint32_t sign = (int8_t)more >> 7; + uint32_t mask = (1U << shift) - 1; + uint32_t uq = numer + ((numer >> 31) & mask); + int32_t q = (int32_t)uq; + q >>= shift; + q = (q ^ sign) - sign; + return q; + } else { + uint32_t uq = (uint32_t)libdivide_mullhi_s32(denom->magic, numer); + if (more & LIBDIVIDE_ADD_MARKER) { + // must be arithmetic shift and then sign extend + int32_t sign = (int8_t)more >> 7; + // q += (more < 0 ? -numer : numer) + // cast required to avoid UB + uq += ((uint32_t)numer ^ sign) - sign; + } + int32_t q = (int32_t)uq; + q >>= shift; + q += (q < 0); + return q; + } +} + +int32_t libdivide_s32_branchfree_do(int32_t numer, const struct libdivide_s32_branchfree_t *denom) { + uint8_t more = denom->more; + uint8_t shift = more & LIBDIVIDE_32_SHIFT_MASK; + // must be arithmetic shift and then sign extend + int32_t sign = (int8_t)more >> 7; + int32_t magic = denom->magic; + int32_t q = libdivide_mullhi_s32(magic, numer); + q += numer; + + // If q is non-negative, we have nothing to do + // If q is negative, we want to add either (2**shift)-1 if d is a power of + // 2, or (2**shift) if it is not a power of 2 + uint32_t is_power_of_2 = (magic == 0); + uint32_t q_sign = (uint32_t)(q >> 31); + q += q_sign & ((1U << shift) - is_power_of_2); + + // Now arithmetic right shift + q >>= shift; + // Negate if needed + q = (q ^ sign) - sign; + + return q; +} + +int32_t libdivide_s32_recover(const struct libdivide_s32_t *denom) { + uint8_t more = denom->more; + uint8_t shift = more & LIBDIVIDE_32_SHIFT_MASK; + if (!denom->magic) { + uint32_t absD = 1U << shift; + if (more & LIBDIVIDE_NEGATIVE_DIVISOR) { + absD = -absD; + } + return (int32_t)absD; + } else { + // Unsigned math is much easier + // We negate the magic number only in the branchfull case, and we don't + // know which case we're in. However we have enough information to + // determine the correct sign of the magic number. The divisor was + // negative if LIBDIVIDE_NEGATIVE_DIVISOR is set. If ADD_MARKER is set, + // the magic number's sign is opposite that of the divisor. + // We want to compute the positive magic number. + int negative_divisor = (more & LIBDIVIDE_NEGATIVE_DIVISOR); + int magic_was_negated = (more & LIBDIVIDE_ADD_MARKER) + ? denom->magic > 0 : denom->magic < 0; + + // Handle the power of 2 case (including branchfree) + if (denom->magic == 0) { + int32_t result = 1U << shift; + return negative_divisor ? -result : result; + } + + uint32_t d = (uint32_t)(magic_was_negated ? -denom->magic : denom->magic); + uint64_t n = 1ULL << (32 + shift); // this shift cannot exceed 30 + uint32_t q = (uint32_t)(n / d); + int32_t result = (int32_t)q; + result += 1; + return negative_divisor ? -result : result; + } +} + +int32_t libdivide_s32_branchfree_recover(const struct libdivide_s32_branchfree_t *denom) { + return libdivide_s32_recover((const struct libdivide_s32_t *)denom); +}*/ + +///////////// SINT64 + +/*static inline struct libdivide_s64_t libdivide_internal_s64_gen(int64_t d, int branchfree) { + if (d == 0) { + LIBDIVIDE_ERROR("divider must be != 0"); + } + + struct libdivide_s64_t result; + + // If d is a power of 2, or negative a power of 2, we have to use a shift. + // This is especially important because the magic algorithm fails for -1. + // To check if d is a power of 2 or its inverse, it suffices to check + // whether its absolute value has exactly one bit set. This works even for + // INT_MIN, because abs(INT_MIN) == INT_MIN, and INT_MIN has one bit set + // and is a power of 2. + uint64_t ud = (uint64_t)d; + uint64_t absD = (d < 0) ? -ud : ud; + uint32_t floor_log_2_d = 63 - libdivide_count_leading_zeros64(absD); + // check if exactly one bit is set, + // don't care if absD is 0 since that's divide by zero + if ((absD & (absD - 1)) == 0) { + // Branchfree and non-branchfree cases are the same + result.magic = 0; + result.more = floor_log_2_d | (d < 0 ? LIBDIVIDE_NEGATIVE_DIVISOR : 0); + } else { + // the dividend here is 2**(floor_log_2_d + 63), so the low 64 bit word + // is 0 and the high word is floor_log_2_d - 1 + uint8_t more; + uint64_t rem, proposed_m; + proposed_m = libdivide_128_div_64_to_64(1ULL << (floor_log_2_d - 1), 0, absD, &rem); + const uint64_t e = absD - rem; + + // We are going to start with a power of floor_log_2_d - 1. + // This works if works if e < 2**floor_log_2_d. + if (!branchfree && e < (1ULL << floor_log_2_d)) { + // This power works + more = floor_log_2_d - 1; + } else { + // We need to go one higher. This should not make proposed_m + // overflow, but it will make it negative when interpreted as an + // int32_t. + proposed_m += proposed_m; + const uint64_t twice_rem = rem + rem; + if (twice_rem >= absD || twice_rem < rem) proposed_m += 1; + // note that we only set the LIBDIVIDE_NEGATIVE_DIVISOR bit if we + // also set ADD_MARKER this is an annoying optimization that + // enables algorithm #4 to avoid the mask. However we always set it + // in the branchfree case + more = floor_log_2_d | LIBDIVIDE_ADD_MARKER; + } + proposed_m += 1; + int64_t magic = (int64_t)proposed_m; + + // Mark if we are negative + if (d < 0) { + more |= LIBDIVIDE_NEGATIVE_DIVISOR; + if (!branchfree) { + magic = -magic; + } + } + + result.more = more; + result.magic = magic; + } + return result; +} + +struct libdivide_s64_t libdivide_s64_gen(int64_t d) { + return libdivide_internal_s64_gen(d, 0); +} + +struct libdivide_s64_branchfree_t libdivide_s64_branchfree_gen(int64_t d) { + struct libdivide_s64_t tmp = libdivide_internal_s64_gen(d, 1); + struct libdivide_s64_branchfree_t ret = {tmp.magic, tmp.more}; + return ret; +} + +int64_t libdivide_s64_do(int64_t numer, const struct libdivide_s64_t *denom) { + uint8_t more = denom->more; + uint8_t shift = more & LIBDIVIDE_64_SHIFT_MASK; + + if (!denom->magic) { // shift path + uint64_t mask = (1ULL << shift) - 1; + uint64_t uq = numer + ((numer >> 63) & mask); + int64_t q = (int64_t)uq; + q >>= shift; + // must be arithmetic shift and then sign-extend + int64_t sign = (int8_t)more >> 7; + q = (q ^ sign) - sign; + return q; + } else { + uint64_t uq = (uint64_t)libdivide_mullhi_s64(denom->magic, numer); + if (more & LIBDIVIDE_ADD_MARKER) { + // must be arithmetic shift and then sign extend + int64_t sign = (int8_t)more >> 7; + // q += (more < 0 ? -numer : numer) + // cast required to avoid UB + uq += ((uint64_t)numer ^ sign) - sign; + } + int64_t q = (int64_t)uq; + q >>= shift; + q += (q < 0); + return q; + } +} + +int64_t libdivide_s64_branchfree_do(int64_t numer, const struct libdivide_s64_branchfree_t *denom) { + uint8_t more = denom->more; + uint8_t shift = more & LIBDIVIDE_64_SHIFT_MASK; + // must be arithmetic shift and then sign extend + int64_t sign = (int8_t)more >> 7; + int64_t magic = denom->magic; + int64_t q = libdivide_mullhi_s64(magic, numer); + q += numer; + + // If q is non-negative, we have nothing to do. + // If q is negative, we want to add either (2**shift)-1 if d is a power of + // 2, or (2**shift) if it is not a power of 2. + uint64_t is_power_of_2 = (magic == 0); + uint64_t q_sign = (uint64_t)(q >> 63); + q += q_sign & ((1ULL << shift) - is_power_of_2); + + // Arithmetic right shift + q >>= shift; + // Negate if needed + q = (q ^ sign) - sign; + + return q; +} + +int64_t libdivide_s64_recover(const struct libdivide_s64_t *denom) { + uint8_t more = denom->more; + uint8_t shift = more & LIBDIVIDE_64_SHIFT_MASK; + if (denom->magic == 0) { // shift path + uint64_t absD = 1ULL << shift; + if (more & LIBDIVIDE_NEGATIVE_DIVISOR) { + absD = -absD; + } + return (int64_t)absD; + } else { + // Unsigned math is much easier + int negative_divisor = (more & LIBDIVIDE_NEGATIVE_DIVISOR); + int magic_was_negated = (more & LIBDIVIDE_ADD_MARKER) + ? denom->magic > 0 : denom->magic < 0; + + uint64_t d = (uint64_t)(magic_was_negated ? -denom->magic : denom->magic); + uint64_t n_hi = 1ULL << shift, n_lo = 0; + uint64_t rem_ignored; + uint64_t q = libdivide_128_div_64_to_64(n_hi, n_lo, d, &rem_ignored); + int64_t result = (int64_t)(q + 1); + if (negative_divisor) { + result = -result; + } + return result; + } +} + +int64_t libdivide_s64_branchfree_recover(const struct libdivide_s64_branchfree_t *denom) { + return libdivide_s64_recover((const struct libdivide_s64_t *)denom); +}*/ + +#if defined(LIBDIVIDE_AVX512) + +static inline __m512i libdivide_u32_do_vector(__m512i numers, const struct libdivide_u32_t *denom); +static inline __m512i libdivide_s32_do_vector(__m512i numers, const struct libdivide_s32_t *denom); +static inline __m512i libdivide_u64_do_vector(__m512i numers, const struct libdivide_u64_t *denom); +static inline __m512i libdivide_s64_do_vector(__m512i numers, const struct libdivide_s64_t *denom); + +static inline __m512i libdivide_u32_branchfree_do_vector(__m512i numers, const struct libdivide_u32_branchfree_t *denom); +static inline __m512i libdivide_s32_branchfree_do_vector(__m512i numers, const struct libdivide_s32_branchfree_t *denom); +static inline __m512i libdivide_u64_branchfree_do_vector(__m512i numers, const struct libdivide_u64_branchfree_t *denom); +static inline __m512i libdivide_s64_branchfree_do_vector(__m512i numers, const struct libdivide_s64_branchfree_t *denom); + +//////// Internal Utility Functions + +static inline __m512i libdivide_s64_signbits(__m512i v) {; + return _mm512_srai_epi64(v, 63); +} + +static inline __m512i libdivide_s64_shift_right_vector(__m512i v, int amt) { + return _mm512_srai_epi64(v, amt); +} + +// Here, b is assumed to contain one 32-bit value repeated. +static inline __m512i libdivide_mullhi_u32_vector(__m512i a, __m512i b) { + __m512i hi_product_0Z2Z = _mm512_srli_epi64(_mm512_mul_epu32(a, b), 32); + __m512i a1X3X = _mm512_srli_epi64(a, 32); + __m512i mask = _mm512_set_epi32(-1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0); + __m512i hi_product_Z1Z3 = _mm512_and_si512(_mm512_mul_epu32(a1X3X, b), mask); + return _mm512_or_si512(hi_product_0Z2Z, hi_product_Z1Z3); +} + +// b is one 32-bit value repeated. +static inline __m512i libdivide_mullhi_s32_vector(__m512i a, __m512i b) { + __m512i hi_product_0Z2Z = _mm512_srli_epi64(_mm512_mul_epi32(a, b), 32); + __m512i a1X3X = _mm512_srli_epi64(a, 32); + __m512i mask = _mm512_set_epi32(-1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0); + __m512i hi_product_Z1Z3 = _mm512_and_si512(_mm512_mul_epi32(a1X3X, b), mask); + return _mm512_or_si512(hi_product_0Z2Z, hi_product_Z1Z3); +} + +// Here, y is assumed to contain one 64-bit value repeated. +// https://stackoverflow.com/a/28827013 +static inline __m512i libdivide_mullhi_u64_vector(__m512i x, __m512i y) { + __m512i lomask = _mm512_set1_epi64(0xffffffff); + __m512i xh = _mm512_shuffle_epi32(x, (_MM_PERM_ENUM) 0xB1); + __m512i yh = _mm512_shuffle_epi32(y, (_MM_PERM_ENUM) 0xB1); + __m512i w0 = _mm512_mul_epu32(x, y); + __m512i w1 = _mm512_mul_epu32(x, yh); + __m512i w2 = _mm512_mul_epu32(xh, y); + __m512i w3 = _mm512_mul_epu32(xh, yh); + __m512i w0h = _mm512_srli_epi64(w0, 32); + __m512i s1 = _mm512_add_epi64(w1, w0h); + __m512i s1l = _mm512_and_si512(s1, lomask); + __m512i s1h = _mm512_srli_epi64(s1, 32); + __m512i s2 = _mm512_add_epi64(w2, s1l); + __m512i s2h = _mm512_srli_epi64(s2, 32); + __m512i hi = _mm512_add_epi64(w3, s1h); + hi = _mm512_add_epi64(hi, s2h); + + return hi; +} + +// y is one 64-bit value repeated. +static inline __m512i libdivide_mullhi_s64_vector(__m512i x, __m512i y) { + __m512i p = libdivide_mullhi_u64_vector(x, y); + __m512i t1 = _mm512_and_si512(libdivide_s64_signbits(x), y); + __m512i t2 = _mm512_and_si512(libdivide_s64_signbits(y), x); + p = _mm512_sub_epi64(p, t1); + p = _mm512_sub_epi64(p, t2); + return p; +} + +////////// UINT32 + +__m512i libdivide_u32_do_vector(__m512i numers, const struct libdivide_u32_t *denom) { + uint8_t more = denom->more; + if (!denom->magic) { + return _mm512_srli_epi32(numers, more); + } + else { + __m512i q = libdivide_mullhi_u32_vector(numers, _mm512_set1_epi32(denom->magic)); + if (more & LIBDIVIDE_ADD_MARKER) { + // uint32_t t = ((numer - q) >> 1) + q; + // return t >> denom->shift; + uint32_t shift = more & LIBDIVIDE_32_SHIFT_MASK; + __m512i t = _mm512_add_epi32(_mm512_srli_epi32(_mm512_sub_epi32(numers, q), 1), q); + return _mm512_srli_epi32(t, shift); + } + else { + return _mm512_srli_epi32(q, more); + } + } +} + +__m512i libdivide_u32_branchfree_do_vector(__m512i numers, const struct libdivide_u32_branchfree_t *denom) { + __m512i q = libdivide_mullhi_u32_vector(numers, _mm512_set1_epi32(denom->magic)); + __m512i t = _mm512_add_epi32(_mm512_srli_epi32(_mm512_sub_epi32(numers, q), 1), q); + return _mm512_srli_epi32(t, denom->more); +} + +////////// UINT64 + +__m512i libdivide_u64_do_vector(__m512i numers, const struct libdivide_u64_t *denom) { + uint8_t more = denom->more; + if (!denom->magic) { + return _mm512_srli_epi64(numers, more); + } + else { + __m512i q = libdivide_mullhi_u64_vector(numers, _mm512_set1_epi64(denom->magic)); + if (more & LIBDIVIDE_ADD_MARKER) { + // uint32_t t = ((numer - q) >> 1) + q; + // return t >> denom->shift; + uint32_t shift = more & LIBDIVIDE_64_SHIFT_MASK; + __m512i t = _mm512_add_epi64(_mm512_srli_epi64(_mm512_sub_epi64(numers, q), 1), q); + return _mm512_srli_epi64(t, shift); + } + else { + return _mm512_srli_epi64(q, more); + } + } +} + +__m512i libdivide_u64_branchfree_do_vector(__m512i numers, const struct libdivide_u64_branchfree_t *denom) { + __m512i q = libdivide_mullhi_u64_vector(numers, _mm512_set1_epi64(denom->magic)); + __m512i t = _mm512_add_epi64(_mm512_srli_epi64(_mm512_sub_epi64(numers, q), 1), q); + return _mm512_srli_epi64(t, denom->more); +} + +////////// SINT32 + +__m512i libdivide_s32_do_vector(__m512i numers, const struct libdivide_s32_t *denom) { + uint8_t more = denom->more; + if (!denom->magic) { + uint32_t shift = more & LIBDIVIDE_32_SHIFT_MASK; + uint32_t mask = (1U << shift) - 1; + __m512i roundToZeroTweak = _mm512_set1_epi32(mask); + // q = numer + ((numer >> 31) & roundToZeroTweak); + __m512i q = _mm512_add_epi32(numers, _mm512_and_si512(_mm512_srai_epi32(numers, 31), roundToZeroTweak)); + q = _mm512_srai_epi32(q, shift); + __m512i sign = _mm512_set1_epi32((int8_t)more >> 7); + // q = (q ^ sign) - sign; + q = _mm512_sub_epi32(_mm512_xor_si512(q, sign), sign); + return q; + } + else { + __m512i q = libdivide_mullhi_s32_vector(numers, _mm512_set1_epi32(denom->magic)); + if (more & LIBDIVIDE_ADD_MARKER) { + // must be arithmetic shift + __m512i sign = _mm512_set1_epi32((int8_t)more >> 7); + // q += ((numer ^ sign) - sign); + q = _mm512_add_epi32(q, _mm512_sub_epi32(_mm512_xor_si512(numers, sign), sign)); + } + // q >>= shift + q = _mm512_srai_epi32(q, more & LIBDIVIDE_32_SHIFT_MASK); + q = _mm512_add_epi32(q, _mm512_srli_epi32(q, 31)); // q += (q < 0) + return q; + } +} + +__m512i libdivide_s32_branchfree_do_vector(__m512i numers, const struct libdivide_s32_branchfree_t *denom) { + int32_t magic = denom->magic; + uint8_t more = denom->more; + uint8_t shift = more & LIBDIVIDE_32_SHIFT_MASK; + // must be arithmetic shift + __m512i sign = _mm512_set1_epi32((int8_t)more >> 7); + __m512i q = libdivide_mullhi_s32_vector(numers, _mm512_set1_epi32(magic)); + q = _mm512_add_epi32(q, numers); // q += numers + + // If q is non-negative, we have nothing to do + // If q is negative, we want to add either (2**shift)-1 if d is + // a power of 2, or (2**shift) if it is not a power of 2 + uint32_t is_power_of_2 = (magic == 0); + __m512i q_sign = _mm512_srai_epi32(q, 31); // q_sign = q >> 31 + __m512i mask = _mm512_set1_epi32((1U << shift) - is_power_of_2); + q = _mm512_add_epi32(q, _mm512_and_si512(q_sign, mask)); // q = q + (q_sign & mask) + q = _mm512_srai_epi32(q, shift); // q >>= shift + q = _mm512_sub_epi32(_mm512_xor_si512(q, sign), sign); // q = (q ^ sign) - sign + return q; +} + +////////// SINT64 + +__m512i libdivide_s64_do_vector(__m512i numers, const struct libdivide_s64_t *denom) { + uint8_t more = denom->more; + int64_t magic = denom->magic; + if (magic == 0) { // shift path + uint32_t shift = more & LIBDIVIDE_64_SHIFT_MASK; + uint64_t mask = (1ULL << shift) - 1; + __m512i roundToZeroTweak = _mm512_set1_epi64(mask); + // q = numer + ((numer >> 63) & roundToZeroTweak); + __m512i q = _mm512_add_epi64(numers, _mm512_and_si512(libdivide_s64_signbits(numers), roundToZeroTweak)); + q = libdivide_s64_shift_right_vector(q, shift); + __m512i sign = _mm512_set1_epi32((int8_t)more >> 7); + // q = (q ^ sign) - sign; + q = _mm512_sub_epi64(_mm512_xor_si512(q, sign), sign); + return q; + } + else { + __m512i q = libdivide_mullhi_s64_vector(numers, _mm512_set1_epi64(magic)); + if (more & LIBDIVIDE_ADD_MARKER) { + // must be arithmetic shift + __m512i sign = _mm512_set1_epi32((int8_t)more >> 7); + // q += ((numer ^ sign) - sign); + q = _mm512_add_epi64(q, _mm512_sub_epi64(_mm512_xor_si512(numers, sign), sign)); + } + // q >>= denom->mult_path.shift + q = libdivide_s64_shift_right_vector(q, more & LIBDIVIDE_64_SHIFT_MASK); + q = _mm512_add_epi64(q, _mm512_srli_epi64(q, 63)); // q += (q < 0) + return q; + } +} + +__m512i libdivide_s64_branchfree_do_vector(__m512i numers, const struct libdivide_s64_branchfree_t *denom) { + int64_t magic = denom->magic; + uint8_t more = denom->more; + uint8_t shift = more & LIBDIVIDE_64_SHIFT_MASK; + // must be arithmetic shift + __m512i sign = _mm512_set1_epi32((int8_t)more >> 7); + + // libdivide_mullhi_s64(numers, magic); + __m512i q = libdivide_mullhi_s64_vector(numers, _mm512_set1_epi64(magic)); + q = _mm512_add_epi64(q, numers); // q += numers + + // If q is non-negative, we have nothing to do. + // If q is negative, we want to add either (2**shift)-1 if d is + // a power of 2, or (2**shift) if it is not a power of 2. + uint32_t is_power_of_2 = (magic == 0); + __m512i q_sign = libdivide_s64_signbits(q); // q_sign = q >> 63 + __m512i mask = _mm512_set1_epi64((1ULL << shift) - is_power_of_2); + q = _mm512_add_epi64(q, _mm512_and_si512(q_sign, mask)); // q = q + (q_sign & mask) + q = libdivide_s64_shift_right_vector(q, shift); // q >>= shift + q = _mm512_sub_epi64(_mm512_xor_si512(q, sign), sign); // q = (q ^ sign) - sign + return q; +} + +#elif defined(LIBDIVIDE_AVX2) + +static inline __m256i libdivide_u32_do_vector(__m256i numers, const struct libdivide_u32_t *denom); +static inline __m256i libdivide_s32_do_vector(__m256i numers, const struct libdivide_s32_t *denom); +static inline __m256i libdivide_u64_do_vector(__m256i numers, const struct libdivide_u64_t *denom); +static inline __m256i libdivide_s64_do_vector(__m256i numers, const struct libdivide_s64_t *denom); + +static inline __m256i libdivide_u32_branchfree_do_vector(__m256i numers, const struct libdivide_u32_branchfree_t *denom); +static inline __m256i libdivide_s32_branchfree_do_vector(__m256i numers, const struct libdivide_s32_branchfree_t *denom); +static inline __m256i libdivide_u64_branchfree_do_vector(__m256i numers, const struct libdivide_u64_branchfree_t *denom); +static inline __m256i libdivide_s64_branchfree_do_vector(__m256i numers, const struct libdivide_s64_branchfree_t *denom); + +//////// Internal Utility Functions + +// Implementation of _mm256_srai_epi64(v, 63) (from AVX512). +static inline __m256i libdivide_s64_signbits(__m256i v) { + __m256i hiBitsDuped = _mm256_shuffle_epi32(v, _MM_SHUFFLE(3, 3, 1, 1)); + __m256i signBits = _mm256_srai_epi32(hiBitsDuped, 31); + return signBits; +} + +// Implementation of _mm256_srai_epi64 (from AVX512). +static inline __m256i libdivide_s64_shift_right_vector(__m256i v, int amt) { + const int b = 64 - amt; + __m256i m = _mm256_set1_epi64x(1ULL << (b - 1)); + __m256i x = _mm256_srli_epi64(v, amt); + __m256i result = _mm256_sub_epi64(_mm256_xor_si256(x, m), m); + return result; +} + +// Here, b is assumed to contain one 32-bit value repeated. +static inline __m256i libdivide_mullhi_u32_vector(__m256i a, __m256i b) { + __m256i hi_product_0Z2Z = _mm256_srli_epi64(_mm256_mul_epu32(a, b), 32); + __m256i a1X3X = _mm256_srli_epi64(a, 32); + __m256i mask = _mm256_set_epi32(-1, 0, -1, 0, -1, 0, -1, 0); + __m256i hi_product_Z1Z3 = _mm256_and_si256(_mm256_mul_epu32(a1X3X, b), mask); + return _mm256_or_si256(hi_product_0Z2Z, hi_product_Z1Z3); +} + +// b is one 32-bit value repeated. +static inline __m256i libdivide_mullhi_s32_vector(__m256i a, __m256i b) { + __m256i hi_product_0Z2Z = _mm256_srli_epi64(_mm256_mul_epi32(a, b), 32); + __m256i a1X3X = _mm256_srli_epi64(a, 32); + __m256i mask = _mm256_set_epi32(-1, 0, -1, 0, -1, 0, -1, 0); + __m256i hi_product_Z1Z3 = _mm256_and_si256(_mm256_mul_epi32(a1X3X, b), mask); + return _mm256_or_si256(hi_product_0Z2Z, hi_product_Z1Z3); +} + +// Here, y is assumed to contain one 64-bit value repeated. +// https://stackoverflow.com/a/28827013 +static inline __m256i libdivide_mullhi_u64_vector(__m256i x, __m256i y) { + __m256i lomask = _mm256_set1_epi64x(0xffffffff); + __m256i xh = _mm256_shuffle_epi32(x, 0xB1); // x0l, x0h, x1l, x1h + __m256i yh = _mm256_shuffle_epi32(y, 0xB1); // y0l, y0h, y1l, y1h + __m256i w0 = _mm256_mul_epu32(x, y); // x0l*y0l, x1l*y1l + __m256i w1 = _mm256_mul_epu32(x, yh); // x0l*y0h, x1l*y1h + __m256i w2 = _mm256_mul_epu32(xh, y); // x0h*y0l, x1h*y0l + __m256i w3 = _mm256_mul_epu32(xh, yh); // x0h*y0h, x1h*y1h + __m256i w0h = _mm256_srli_epi64(w0, 32); + __m256i s1 = _mm256_add_epi64(w1, w0h); + __m256i s1l = _mm256_and_si256(s1, lomask); + __m256i s1h = _mm256_srli_epi64(s1, 32); + __m256i s2 = _mm256_add_epi64(w2, s1l); + __m256i s2h = _mm256_srli_epi64(s2, 32); + __m256i hi = _mm256_add_epi64(w3, s1h); + hi = _mm256_add_epi64(hi, s2h); + + return hi; +} + +// y is one 64-bit value repeated. +static inline __m256i libdivide_mullhi_s64_vector(__m256i x, __m256i y) { + __m256i p = libdivide_mullhi_u64_vector(x, y); + __m256i t1 = _mm256_and_si256(libdivide_s64_signbits(x), y); + __m256i t2 = _mm256_and_si256(libdivide_s64_signbits(y), x); + p = _mm256_sub_epi64(p, t1); + p = _mm256_sub_epi64(p, t2); + return p; +} + +////////// UINT32 + +__m256i libdivide_u32_do_vector(__m256i numers, const struct libdivide_u32_t *denom) { + uint8_t more = denom->more; + if (!denom->magic) { + return _mm256_srli_epi32(numers, more); + } + else { + __m256i q = libdivide_mullhi_u32_vector(numers, _mm256_set1_epi32(denom->magic)); + if (more & LIBDIVIDE_ADD_MARKER) { + // uint32_t t = ((numer - q) >> 1) + q; + // return t >> denom->shift; + uint32_t shift = more & LIBDIVIDE_32_SHIFT_MASK; + __m256i t = _mm256_add_epi32(_mm256_srli_epi32(_mm256_sub_epi32(numers, q), 1), q); + return _mm256_srli_epi32(t, shift); + } + else { + return _mm256_srli_epi32(q, more); + } + } +} + +__m256i libdivide_u32_branchfree_do_vector(__m256i numers, const struct libdivide_u32_branchfree_t *denom) { + __m256i q = libdivide_mullhi_u32_vector(numers, _mm256_set1_epi32(denom->magic)); + __m256i t = _mm256_add_epi32(_mm256_srli_epi32(_mm256_sub_epi32(numers, q), 1), q); + return _mm256_srli_epi32(t, denom->more); +} + +////////// UINT64 + +__m256i libdivide_u64_do_vector(__m256i numers, const struct libdivide_u64_t *denom) { + uint8_t more = denom->more; + if (!denom->magic) { + return _mm256_srli_epi64(numers, more); + } + else { + __m256i q = libdivide_mullhi_u64_vector(numers, _mm256_set1_epi64x(denom->magic)); + if (more & LIBDIVIDE_ADD_MARKER) { + // uint32_t t = ((numer - q) >> 1) + q; + // return t >> denom->shift; + uint32_t shift = more & LIBDIVIDE_64_SHIFT_MASK; + __m256i t = _mm256_add_epi64(_mm256_srli_epi64(_mm256_sub_epi64(numers, q), 1), q); + return _mm256_srli_epi64(t, shift); + } + else { + return _mm256_srli_epi64(q, more); + } + } +} + +__m256i libdivide_u64_branchfree_do_vector(__m256i numers, const struct libdivide_u64_branchfree_t *denom) { + __m256i q = libdivide_mullhi_u64_vector(numers, _mm256_set1_epi64x(denom->magic)); + __m256i t = _mm256_add_epi64(_mm256_srli_epi64(_mm256_sub_epi64(numers, q), 1), q); + return _mm256_srli_epi64(t, denom->more); +} + +////////// SINT32 + +__m256i libdivide_s32_do_vector(__m256i numers, const struct libdivide_s32_t *denom) { + uint8_t more = denom->more; + if (!denom->magic) { + uint32_t shift = more & LIBDIVIDE_32_SHIFT_MASK; + uint32_t mask = (1U << shift) - 1; + __m256i roundToZeroTweak = _mm256_set1_epi32(mask); + // q = numer + ((numer >> 31) & roundToZeroTweak); + __m256i q = _mm256_add_epi32(numers, _mm256_and_si256(_mm256_srai_epi32(numers, 31), roundToZeroTweak)); + q = _mm256_srai_epi32(q, shift); + __m256i sign = _mm256_set1_epi32((int8_t)more >> 7); + // q = (q ^ sign) - sign; + q = _mm256_sub_epi32(_mm256_xor_si256(q, sign), sign); + return q; + } + else { + __m256i q = libdivide_mullhi_s32_vector(numers, _mm256_set1_epi32(denom->magic)); + if (more & LIBDIVIDE_ADD_MARKER) { + // must be arithmetic shift + __m256i sign = _mm256_set1_epi32((int8_t)more >> 7); + // q += ((numer ^ sign) - sign); + q = _mm256_add_epi32(q, _mm256_sub_epi32(_mm256_xor_si256(numers, sign), sign)); + } + // q >>= shift + q = _mm256_srai_epi32(q, more & LIBDIVIDE_32_SHIFT_MASK); + q = _mm256_add_epi32(q, _mm256_srli_epi32(q, 31)); // q += (q < 0) + return q; + } +} + +__m256i libdivide_s32_branchfree_do_vector(__m256i numers, const struct libdivide_s32_branchfree_t *denom) { + int32_t magic = denom->magic; + uint8_t more = denom->more; + uint8_t shift = more & LIBDIVIDE_32_SHIFT_MASK; + // must be arithmetic shift + __m256i sign = _mm256_set1_epi32((int8_t)more >> 7); + __m256i q = libdivide_mullhi_s32_vector(numers, _mm256_set1_epi32(magic)); + q = _mm256_add_epi32(q, numers); // q += numers + + // If q is non-negative, we have nothing to do + // If q is negative, we want to add either (2**shift)-1 if d is + // a power of 2, or (2**shift) if it is not a power of 2 + uint32_t is_power_of_2 = (magic == 0); + __m256i q_sign = _mm256_srai_epi32(q, 31); // q_sign = q >> 31 + __m256i mask = _mm256_set1_epi32((1U << shift) - is_power_of_2); + q = _mm256_add_epi32(q, _mm256_and_si256(q_sign, mask)); // q = q + (q_sign & mask) + q = _mm256_srai_epi32(q, shift); // q >>= shift + q = _mm256_sub_epi32(_mm256_xor_si256(q, sign), sign); // q = (q ^ sign) - sign + return q; +} + +////////// SINT64 + +__m256i libdivide_s64_do_vector(__m256i numers, const struct libdivide_s64_t *denom) { + uint8_t more = denom->more; + int64_t magic = denom->magic; + if (magic == 0) { // shift path + uint32_t shift = more & LIBDIVIDE_64_SHIFT_MASK; + uint64_t mask = (1ULL << shift) - 1; + __m256i roundToZeroTweak = _mm256_set1_epi64x(mask); + // q = numer + ((numer >> 63) & roundToZeroTweak); + __m256i q = _mm256_add_epi64(numers, _mm256_and_si256(libdivide_s64_signbits(numers), roundToZeroTweak)); + q = libdivide_s64_shift_right_vector(q, shift); + __m256i sign = _mm256_set1_epi32((int8_t)more >> 7); + // q = (q ^ sign) - sign; + q = _mm256_sub_epi64(_mm256_xor_si256(q, sign), sign); + return q; + } + else { + __m256i q = libdivide_mullhi_s64_vector(numers, _mm256_set1_epi64x(magic)); + if (more & LIBDIVIDE_ADD_MARKER) { + // must be arithmetic shift + __m256i sign = _mm256_set1_epi32((int8_t)more >> 7); + // q += ((numer ^ sign) - sign); + q = _mm256_add_epi64(q, _mm256_sub_epi64(_mm256_xor_si256(numers, sign), sign)); + } + // q >>= denom->mult_path.shift + q = libdivide_s64_shift_right_vector(q, more & LIBDIVIDE_64_SHIFT_MASK); + q = _mm256_add_epi64(q, _mm256_srli_epi64(q, 63)); // q += (q < 0) + return q; + } +} + +__m256i libdivide_s64_branchfree_do_vector(__m256i numers, const struct libdivide_s64_branchfree_t *denom) { + int64_t magic = denom->magic; + uint8_t more = denom->more; + uint8_t shift = more & LIBDIVIDE_64_SHIFT_MASK; + // must be arithmetic shift + __m256i sign = _mm256_set1_epi32((int8_t)more >> 7); + + // libdivide_mullhi_s64(numers, magic); + __m256i q = libdivide_mullhi_s64_vector(numers, _mm256_set1_epi64x(magic)); + q = _mm256_add_epi64(q, numers); // q += numers + + // If q is non-negative, we have nothing to do. + // If q is negative, we want to add either (2**shift)-1 if d is + // a power of 2, or (2**shift) if it is not a power of 2. + uint32_t is_power_of_2 = (magic == 0); + __m256i q_sign = libdivide_s64_signbits(q); // q_sign = q >> 63 + __m256i mask = _mm256_set1_epi64x((1ULL << shift) - is_power_of_2); + q = _mm256_add_epi64(q, _mm256_and_si256(q_sign, mask)); // q = q + (q_sign & mask) + q = libdivide_s64_shift_right_vector(q, shift); // q >>= shift + q = _mm256_sub_epi64(_mm256_xor_si256(q, sign), sign); // q = (q ^ sign) - sign + return q; +} + +#elif defined(LIBDIVIDE_SSE2) + +static inline __m128i libdivide_u32_do_vector(__m128i numers, const struct libdivide_u32_t *denom); +static inline __m128i libdivide_s32_do_vector(__m128i numers, const struct libdivide_s32_t *denom); +static inline __m128i libdivide_u64_do_vector(__m128i numers, const struct libdivide_u64_t *denom); +static inline __m128i libdivide_s64_do_vector(__m128i numers, const struct libdivide_s64_t *denom); + +static inline __m128i libdivide_u32_branchfree_do_vector(__m128i numers, const struct libdivide_u32_branchfree_t *denom); +static inline __m128i libdivide_s32_branchfree_do_vector(__m128i numers, const struct libdivide_s32_branchfree_t *denom); +static inline __m128i libdivide_u64_branchfree_do_vector(__m128i numers, const struct libdivide_u64_branchfree_t *denom); +static inline __m128i libdivide_s64_branchfree_do_vector(__m128i numers, const struct libdivide_s64_branchfree_t *denom); + +//////// Internal Utility Functions + +// Implementation of _mm_srai_epi64(v, 63) (from AVX512). +static inline __m128i libdivide_s64_signbits(__m128i v) { + __m128i hiBitsDuped = _mm_shuffle_epi32(v, _MM_SHUFFLE(3, 3, 1, 1)); + __m128i signBits = _mm_srai_epi32(hiBitsDuped, 31); + return signBits; +} + +// Implementation of _mm_srai_epi64 (from AVX512). +static inline __m128i libdivide_s64_shift_right_vector(__m128i v, int amt) { + const int b = 64 - amt; + __m128i m = _mm_set1_epi64x(1ULL << (b - 1)); + __m128i x = _mm_srli_epi64(v, amt); + __m128i result = _mm_sub_epi64(_mm_xor_si128(x, m), m); + return result; +} + +// Here, b is assumed to contain one 32-bit value repeated. +static inline __m128i libdivide_mullhi_u32_vector(__m128i a, __m128i b) { + __m128i hi_product_0Z2Z = _mm_srli_epi64(_mm_mul_epu32(a, b), 32); + __m128i a1X3X = _mm_srli_epi64(a, 32); + __m128i mask = _mm_set_epi32(-1, 0, -1, 0); + __m128i hi_product_Z1Z3 = _mm_and_si128(_mm_mul_epu32(a1X3X, b), mask); + return _mm_or_si128(hi_product_0Z2Z, hi_product_Z1Z3); +} + +// SSE2 does not have a signed multiplication instruction, but we can convert +// unsigned to signed pretty efficiently. Again, b is just a 32 bit value +// repeated four times. +static inline __m128i libdivide_mullhi_s32_vector(__m128i a, __m128i b) { + __m128i p = libdivide_mullhi_u32_vector(a, b); + // t1 = (a >> 31) & y, arithmetic shift + __m128i t1 = _mm_and_si128(_mm_srai_epi32(a, 31), b); + __m128i t2 = _mm_and_si128(_mm_srai_epi32(b, 31), a); + p = _mm_sub_epi32(p, t1); + p = _mm_sub_epi32(p, t2); + return p; +} + +// Here, y is assumed to contain one 64-bit value repeated. +// https://stackoverflow.com/a/28827013 +static inline __m128i libdivide_mullhi_u64_vector(__m128i x, __m128i y) { + __m128i lomask = _mm_set1_epi64x(0xffffffff); + __m128i xh = _mm_shuffle_epi32(x, 0xB1); // x0l, x0h, x1l, x1h + __m128i yh = _mm_shuffle_epi32(y, 0xB1); // y0l, y0h, y1l, y1h + __m128i w0 = _mm_mul_epu32(x, y); // x0l*y0l, x1l*y1l + __m128i w1 = _mm_mul_epu32(x, yh); // x0l*y0h, x1l*y1h + __m128i w2 = _mm_mul_epu32(xh, y); // x0h*y0l, x1h*y0l + __m128i w3 = _mm_mul_epu32(xh, yh); // x0h*y0h, x1h*y1h + __m128i w0h = _mm_srli_epi64(w0, 32); + __m128i s1 = _mm_add_epi64(w1, w0h); + __m128i s1l = _mm_and_si128(s1, lomask); + __m128i s1h = _mm_srli_epi64(s1, 32); + __m128i s2 = _mm_add_epi64(w2, s1l); + __m128i s2h = _mm_srli_epi64(s2, 32); + __m128i hi = _mm_add_epi64(w3, s1h); + hi = _mm_add_epi64(hi, s2h); + + return hi; +} + +// y is one 64-bit value repeated. +static inline __m128i libdivide_mullhi_s64_vector(__m128i x, __m128i y) { + __m128i p = libdivide_mullhi_u64_vector(x, y); + __m128i t1 = _mm_and_si128(libdivide_s64_signbits(x), y); + __m128i t2 = _mm_and_si128(libdivide_s64_signbits(y), x); + p = _mm_sub_epi64(p, t1); + p = _mm_sub_epi64(p, t2); + return p; +} + +////////// UINT32 + +__m128i libdivide_u32_do_vector(__m128i numers, const struct libdivide_u32_t *denom) { + uint8_t more = denom->more; + if (!denom->magic) { + return _mm_srli_epi32(numers, more); + } + else { + __m128i q = libdivide_mullhi_u32_vector(numers, _mm_set1_epi32(denom->magic)); + if (more & LIBDIVIDE_ADD_MARKER) { + // uint32_t t = ((numer - q) >> 1) + q; + // return t >> denom->shift; + uint32_t shift = more & LIBDIVIDE_32_SHIFT_MASK; + __m128i t = _mm_add_epi32(_mm_srli_epi32(_mm_sub_epi32(numers, q), 1), q); + return _mm_srli_epi32(t, shift); + } + else { + return _mm_srli_epi32(q, more); + } + } +} + +__m128i libdivide_u32_branchfree_do_vector(__m128i numers, const struct libdivide_u32_branchfree_t *denom) { + __m128i q = libdivide_mullhi_u32_vector(numers, _mm_set1_epi32(denom->magic)); + __m128i t = _mm_add_epi32(_mm_srli_epi32(_mm_sub_epi32(numers, q), 1), q); + return _mm_srli_epi32(t, denom->more); +} + +////////// UINT64 + +__m128i libdivide_u64_do_vector(__m128i numers, const struct libdivide_u64_t *denom) { + uint8_t more = denom->more; + if (!denom->magic) { + return _mm_srli_epi64(numers, more); + } + else { + __m128i q = libdivide_mullhi_u64_vector(numers, _mm_set1_epi64x(denom->magic)); + if (more & LIBDIVIDE_ADD_MARKER) { + // uint32_t t = ((numer - q) >> 1) + q; + // return t >> denom->shift; + uint32_t shift = more & LIBDIVIDE_64_SHIFT_MASK; + __m128i t = _mm_add_epi64(_mm_srli_epi64(_mm_sub_epi64(numers, q), 1), q); + return _mm_srli_epi64(t, shift); + } + else { + return _mm_srli_epi64(q, more); + } + } +} + +__m128i libdivide_u64_branchfree_do_vector(__m128i numers, const struct libdivide_u64_branchfree_t *denom) { + __m128i q = libdivide_mullhi_u64_vector(numers, _mm_set1_epi64x(denom->magic)); + __m128i t = _mm_add_epi64(_mm_srli_epi64(_mm_sub_epi64(numers, q), 1), q); + return _mm_srli_epi64(t, denom->more); +} + +////////// SINT32 + +__m128i libdivide_s32_do_vector(__m128i numers, const struct libdivide_s32_t *denom) { + uint8_t more = denom->more; + if (!denom->magic) { + uint32_t shift = more & LIBDIVIDE_32_SHIFT_MASK; + uint32_t mask = (1U << shift) - 1; + __m128i roundToZeroTweak = _mm_set1_epi32(mask); + // q = numer + ((numer >> 31) & roundToZeroTweak); + __m128i q = _mm_add_epi32(numers, _mm_and_si128(_mm_srai_epi32(numers, 31), roundToZeroTweak)); + q = _mm_srai_epi32(q, shift); + __m128i sign = _mm_set1_epi32((int8_t)more >> 7); + // q = (q ^ sign) - sign; + q = _mm_sub_epi32(_mm_xor_si128(q, sign), sign); + return q; + } + else { + __m128i q = libdivide_mullhi_s32_vector(numers, _mm_set1_epi32(denom->magic)); + if (more & LIBDIVIDE_ADD_MARKER) { + // must be arithmetic shift + __m128i sign = _mm_set1_epi32((int8_t)more >> 7); + // q += ((numer ^ sign) - sign); + q = _mm_add_epi32(q, _mm_sub_epi32(_mm_xor_si128(numers, sign), sign)); + } + // q >>= shift + q = _mm_srai_epi32(q, more & LIBDIVIDE_32_SHIFT_MASK); + q = _mm_add_epi32(q, _mm_srli_epi32(q, 31)); // q += (q < 0) + return q; + } +} + +__m128i libdivide_s32_branchfree_do_vector(__m128i numers, const struct libdivide_s32_branchfree_t *denom) { + int32_t magic = denom->magic; + uint8_t more = denom->more; + uint8_t shift = more & LIBDIVIDE_32_SHIFT_MASK; + // must be arithmetic shift + __m128i sign = _mm_set1_epi32((int8_t)more >> 7); + __m128i q = libdivide_mullhi_s32_vector(numers, _mm_set1_epi32(magic)); + q = _mm_add_epi32(q, numers); // q += numers + + // If q is non-negative, we have nothing to do + // If q is negative, we want to add either (2**shift)-1 if d is + // a power of 2, or (2**shift) if it is not a power of 2 + uint32_t is_power_of_2 = (magic == 0); + __m128i q_sign = _mm_srai_epi32(q, 31); // q_sign = q >> 31 + __m128i mask = _mm_set1_epi32((1U << shift) - is_power_of_2); + q = _mm_add_epi32(q, _mm_and_si128(q_sign, mask)); // q = q + (q_sign & mask) + q = _mm_srai_epi32(q, shift); // q >>= shift + q = _mm_sub_epi32(_mm_xor_si128(q, sign), sign); // q = (q ^ sign) - sign + return q; +} + +////////// SINT64 + +__m128i libdivide_s64_do_vector(__m128i numers, const struct libdivide_s64_t *denom) { + uint8_t more = denom->more; + int64_t magic = denom->magic; + if (magic == 0) { // shift path + uint32_t shift = more & LIBDIVIDE_64_SHIFT_MASK; + uint64_t mask = (1ULL << shift) - 1; + __m128i roundToZeroTweak = _mm_set1_epi64x(mask); + // q = numer + ((numer >> 63) & roundToZeroTweak); + __m128i q = _mm_add_epi64(numers, _mm_and_si128(libdivide_s64_signbits(numers), roundToZeroTweak)); + q = libdivide_s64_shift_right_vector(q, shift); + __m128i sign = _mm_set1_epi32((int8_t)more >> 7); + // q = (q ^ sign) - sign; + q = _mm_sub_epi64(_mm_xor_si128(q, sign), sign); + return q; + } + else { + __m128i q = libdivide_mullhi_s64_vector(numers, _mm_set1_epi64x(magic)); + if (more & LIBDIVIDE_ADD_MARKER) { + // must be arithmetic shift + __m128i sign = _mm_set1_epi32((int8_t)more >> 7); + // q += ((numer ^ sign) - sign); + q = _mm_add_epi64(q, _mm_sub_epi64(_mm_xor_si128(numers, sign), sign)); + } + // q >>= denom->mult_path.shift + q = libdivide_s64_shift_right_vector(q, more & LIBDIVIDE_64_SHIFT_MASK); + q = _mm_add_epi64(q, _mm_srli_epi64(q, 63)); // q += (q < 0) + return q; + } +} + +__m128i libdivide_s64_branchfree_do_vector(__m128i numers, const struct libdivide_s64_branchfree_t *denom) { + int64_t magic = denom->magic; + uint8_t more = denom->more; + uint8_t shift = more & LIBDIVIDE_64_SHIFT_MASK; + // must be arithmetic shift + __m128i sign = _mm_set1_epi32((int8_t)more >> 7); + + // libdivide_mullhi_s64(numers, magic); + __m128i q = libdivide_mullhi_s64_vector(numers, _mm_set1_epi64x(magic)); + q = _mm_add_epi64(q, numers); // q += numers + + // If q is non-negative, we have nothing to do. + // If q is negative, we want to add either (2**shift)-1 if d is + // a power of 2, or (2**shift) if it is not a power of 2. + uint32_t is_power_of_2 = (magic == 0); + __m128i q_sign = libdivide_s64_signbits(q); // q_sign = q >> 63 + __m128i mask = _mm_set1_epi64x((1ULL << shift) - is_power_of_2); + q = _mm_add_epi64(q, _mm_and_si128(q_sign, mask)); // q = q + (q_sign & mask) + q = libdivide_s64_shift_right_vector(q, shift); // q >>= shift + q = _mm_sub_epi64(_mm_xor_si128(q, sign), sign); // q = (q ^ sign) - sign + return q; +} + +#endif + +/////////// C++ stuff + +#ifdef __cplusplus + +// The C++ divider class is templated on both an integer type +// (like uint64_t) and an algorithm type. +// * BRANCHFULL is the default algorithm type. +// * BRANCHFREE is the branchfree algorithm type. +enum { + BRANCHFULL, + BRANCHFREE +}; + +#if defined(LIBDIVIDE_AVX512) + #define LIBDIVIDE_VECTOR_TYPE __m512i +#elif defined(LIBDIVIDE_AVX2) + #define LIBDIVIDE_VECTOR_TYPE __m256i +#elif defined(LIBDIVIDE_SSE2) + #define LIBDIVIDE_VECTOR_TYPE __m128i +#endif + +#if !defined(LIBDIVIDE_VECTOR_TYPE) + #define LIBDIVIDE_DIVIDE_VECTOR(ALGO) +#else + #define LIBDIVIDE_DIVIDE_VECTOR(ALGO) \ + LIBDIVIDE_VECTOR_TYPE divide(LIBDIVIDE_VECTOR_TYPE n) const { \ + return libdivide_##ALGO##_do_vector(n, &denom); \ + } +#endif + +// The DISPATCHER_GEN() macro generates C++ methods (for the given integer +// and algorithm types) that redirect to libdivide's C API. +#define DISPATCHER_GEN(T, ALGO) \ + libdivide_##ALGO##_t denom; \ + dispatcher() { } \ + dispatcher(T d) \ + : denom(libdivide_##ALGO##_gen(d)) \ + { } \ + T divide(T n) const { \ + return libdivide_##ALGO##_do(n, &denom); \ + } \ + LIBDIVIDE_DIVIDE_VECTOR(ALGO) \ + T recover() const { \ + return libdivide_##ALGO##_recover(&denom); \ + } + +// The dispatcher selects a specific division algorithm for a given +// type and ALGO using partial template specialization. +template struct dispatcher { }; + +template<> struct dispatcher { DISPATCHER_GEN(int32_t, s32) }; +template<> struct dispatcher { DISPATCHER_GEN(int32_t, s32_branchfree) }; +template<> struct dispatcher { DISPATCHER_GEN(uint32_t, u32) }; +template<> struct dispatcher { DISPATCHER_GEN(uint32_t, u32_branchfree) }; +template<> struct dispatcher { DISPATCHER_GEN(int64_t, s64) }; +template<> struct dispatcher { DISPATCHER_GEN(int64_t, s64_branchfree) }; +template<> struct dispatcher { DISPATCHER_GEN(uint64_t, u64) }; +template<> struct dispatcher { DISPATCHER_GEN(uint64_t, u64_branchfree) }; + +// This is the main divider class for use by the user (C++ API). +// The actual division algorithm is selected using the dispatcher struct +// based on the integer and algorithm template parameters. +template +class divider { +public: + // We leave the default constructor empty so that creating + // an array of dividers and then initializing them + // later doesn't slow us down. + divider() { } + + // Constructor that takes the divisor as a parameter + divider(T d) : div(d) { } + + // Divides n by the divisor + T divide(T n) const { + return div.divide(n); + } + + // Recovers the divisor, returns the value that was + // used to initialize this divider object. + T recover() const { + return div.recover(); + } + + bool operator==(const divider& other) const { + return div.denom.magic == other.denom.magic && + div.denom.more == other.denom.more; + } + + bool operator!=(const divider& other) const { + return !(*this == other); + } + +#if defined(LIBDIVIDE_VECTOR_TYPE) + // Treats the vector as packed integer values with the same type as + // the divider (e.g. s32, u32, s64, u64) and divides each of + // them by the divider, returning the packed quotients. + LIBDIVIDE_VECTOR_TYPE divide(LIBDIVIDE_VECTOR_TYPE n) const { + return div.divide(n); + } +#endif + +private: + // Storage for the actual divisor + dispatcher::value, + std::is_signed::value, sizeof(T), ALGO> div; +}; + +// Overload of operator / for scalar division +template +T operator/(T n, const divider& div) { + return div.divide(n); +} + +// Overload of operator /= for scalar division +template +T& operator/=(T& n, const divider& div) { + n = div.divide(n); + return n; +} + +#if defined(LIBDIVIDE_VECTOR_TYPE) + // Overload of operator / for vector division + template + LIBDIVIDE_VECTOR_TYPE operator/(LIBDIVIDE_VECTOR_TYPE n, const divider& div) { + return div.divide(n); + } + // Overload of operator /= for vector division + template + LIBDIVIDE_VECTOR_TYPE& operator/=(LIBDIVIDE_VECTOR_TYPE& n, const divider& div) { + n = div.divide(n); + return n; + } +#endif + +// libdivdie::branchfree_divider +template +using branchfree_divider = divider; + +} // namespace libdivide + +#endif // __cplusplus + +#endif // LIBDIVIDE_H diff --git a/src/r_draw.c b/src/r_draw.c index 2b798c3bf..cb8187521 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -25,6 +25,7 @@ #include "w_wad.h" #include "z_zone.h" #include "console.h" // Until buffering gets finished +#include "libdivide.h" // used by NPO2 tilted span functions #ifdef HWRENDER #include "hardware/hw_main.h" diff --git a/src/r_draw8_npo2.c b/src/r_draw8_npo2.c index 020155694..b280cbd49 100644 --- a/src/r_draw8_npo2.c +++ b/src/r_draw8_npo2.c @@ -83,6 +83,9 @@ void R_DrawTiltedSpan_NPO2_8(void) double endz, endu, endv; UINT32 stepu, stepv; + struct libdivide_u32_t x_divider = libdivide_u32_gen(ds_flatwidth); + struct libdivide_u32_t y_divider = libdivide_u32_gen(ds_flatheight); + iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); // Lighting is simple. It's just linear interpolation from start to end @@ -122,12 +125,13 @@ void R_DrawTiltedSpan_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + else + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; if (y < 0) - y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); - - x %= ds_flatwidth; - y %= ds_flatheight; + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + else + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; *dest = colormap[source[((y * ds_flatwidth) + x)]]; } @@ -174,12 +178,13 @@ void R_DrawTiltedSpan_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + else + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; if (y < 0) - y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); - - x %= ds_flatwidth; - y %= ds_flatheight; + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + else + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; *dest = colormap[source[((y * ds_flatwidth) + x)]]; } @@ -205,12 +210,13 @@ void R_DrawTiltedSpan_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + else + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; if (y < 0) - y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); - - x %= ds_flatwidth; - y %= ds_flatheight; + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + else + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; *dest = colormap[source[((y * ds_flatwidth) + x)]]; } @@ -241,12 +247,13 @@ void R_DrawTiltedSpan_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + else + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; if (y < 0) - y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); - - x %= ds_flatwidth; - y %= ds_flatheight; + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + else + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; *dest = colormap[source[((y * ds_flatwidth) + x)]]; } @@ -279,6 +286,9 @@ void R_DrawTiltedTranslucentSpan_NPO2_8(void) double endz, endu, endv; UINT32 stepu, stepv; + struct libdivide_u32_t x_divider = libdivide_u32_gen(ds_flatwidth); + struct libdivide_u32_t y_divider = libdivide_u32_gen(ds_flatheight); + iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); // Lighting is simple. It's just linear interpolation from start to end @@ -317,12 +327,13 @@ void R_DrawTiltedTranslucentSpan_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + else + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; if (y < 0) - y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); - - x %= ds_flatwidth; - y %= ds_flatheight; + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + else + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; *dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dest); } @@ -369,12 +380,13 @@ void R_DrawTiltedTranslucentSpan_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + else + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; if (y < 0) - y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); - - x %= ds_flatwidth; - y %= ds_flatheight; + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + else + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; *dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dest); } @@ -400,12 +412,13 @@ void R_DrawTiltedTranslucentSpan_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + else + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; if (y < 0) - y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); - - x %= ds_flatwidth; - y %= ds_flatheight; + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + else + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; *dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dest); } @@ -436,12 +449,13 @@ void R_DrawTiltedTranslucentSpan_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + else + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; if (y < 0) - y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); - - x %= ds_flatwidth; - y %= ds_flatheight; + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + else + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; *dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dest); } @@ -473,6 +487,9 @@ void R_DrawTiltedSplat_NPO2_8(void) double endz, endu, endv; UINT32 stepu, stepv; + struct libdivide_u32_t x_divider = libdivide_u32_gen(ds_flatwidth); + struct libdivide_u32_t y_divider = libdivide_u32_gen(ds_flatheight); + iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); // Lighting is simple. It's just linear interpolation from start to end @@ -512,12 +529,13 @@ void R_DrawTiltedSplat_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + else + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; if (y < 0) - y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); - - x %= ds_flatwidth; - y %= ds_flatheight; + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + else + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; val = source[((y * ds_flatwidth) + x)]; } @@ -568,12 +586,13 @@ void R_DrawTiltedSplat_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + else + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; if (y < 0) - y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); - - x %= ds_flatwidth; - y %= ds_flatheight; + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + else + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; val = source[((y * ds_flatwidth) + x)]; } @@ -601,12 +620,13 @@ void R_DrawTiltedSplat_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + else + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; if (y < 0) - y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); - - x %= ds_flatwidth; - y %= ds_flatheight; + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + else + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; val = source[((y * ds_flatwidth) + x)]; } @@ -640,12 +660,13 @@ void R_DrawTiltedSplat_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + else + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; if (y < 0) - y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); - - x %= ds_flatwidth; - y %= ds_flatheight; + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + else + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; val = source[((y * ds_flatwidth) + x)]; } @@ -864,6 +885,9 @@ void R_DrawTiltedTranslucentWaterSpan_NPO2_8(void) double endz, endu, endv; UINT32 stepu, stepv; + struct libdivide_u32_t x_divider = libdivide_u32_gen(ds_flatwidth); + struct libdivide_u32_t y_divider = libdivide_u32_gen(ds_flatheight); + iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); // Lighting is simple. It's just linear interpolation from start to end @@ -903,12 +927,13 @@ void R_DrawTiltedTranslucentWaterSpan_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + else + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; if (y < 0) - y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); - - x %= ds_flatwidth; - y %= ds_flatheight; + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + else + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; *dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dsrc++); } @@ -955,12 +980,13 @@ void R_DrawTiltedTranslucentWaterSpan_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + else + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; if (y < 0) - y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); - - x %= ds_flatwidth; - y %= ds_flatheight; + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + else + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; *dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dsrc++); } @@ -986,12 +1012,13 @@ void R_DrawTiltedTranslucentWaterSpan_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + else + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; if (y < 0) - y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); - - x %= ds_flatwidth; - y %= ds_flatheight; + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + else + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; *dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dsrc++); } @@ -1022,12 +1049,13 @@ void R_DrawTiltedTranslucentWaterSpan_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + else + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; if (y < 0) - y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); - - x %= ds_flatwidth; - y %= ds_flatheight; + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + else + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; *dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dsrc++); } diff --git a/src/sdl/Srb2SDL-vc10.vcxproj b/src/sdl/Srb2SDL-vc10.vcxproj index c2d6456e4..9b3214067 100644 --- a/src/sdl/Srb2SDL-vc10.vcxproj +++ b/src/sdl/Srb2SDL-vc10.vcxproj @@ -244,6 +244,7 @@ + diff --git a/src/sdl/Srb2SDL-vc10.vcxproj.filters b/src/sdl/Srb2SDL-vc10.vcxproj.filters index 438746ac7..425bbfcc0 100644 --- a/src/sdl/Srb2SDL-vc10.vcxproj.filters +++ b/src/sdl/Srb2SDL-vc10.vcxproj.filters @@ -402,6 +402,9 @@ P_Play + + R_Rend + R_Rend From 724d126015db83170329f606572491f1f191b9c9 Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Sat, 31 Oct 2020 16:39:05 +0200 Subject: [PATCH 028/644] Clarify licensing-related text in libdivide.h --- src/libdivide.h | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/src/libdivide.h b/src/libdivide.h index 51f9a633b..915da0070 100644 --- a/src/libdivide.h +++ b/src/libdivide.h @@ -8,8 +8,37 @@ // You may use libdivide under the terms of either of these. // See LICENSE.txt for more details. -// NOTICE: This version of libdivide has been modified for use with SRB2. -// Changes made: + +// NOTICE: This is an altered source version of libdivide. +// Libdivide is used here under the terms of the zlib license. +// Here is the zlib license text from https://github.com/ridiculousfish/libdivide/blob/master/LICENSE.txt +/* + zlib License + ------------ + + Copyright (C) 2010 - 2019 ridiculous_fish, + Copyright (C) 2016 - 2019 Kim Walisch, + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + + +// This version of libdivide has been modified for use with SRB2. +// Changes made include: // - unused parts commented out (to avoid the need to fix C90 compilation issues with them) // - C90 compilation issues fixed with used parts // - use I_Error for errors From 425b56c2889c9342fb4c4e007be24371816c4e5e Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 6 Nov 2020 13:34:21 -0800 Subject: [PATCH 029/644] Remove win32 specific timer --- src/sdl/i_system.c | 98 ---------------------------------------------- 1 file changed, 98 deletions(-) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 10c0747bf..70ae938e9 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -54,11 +54,7 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); #include #endif -#if defined (_WIN32) -DWORD TimeFunction(int requested_frequency); -#else int TimeFunction(int requested_frequency); -#endif #include #ifdef _WIN32 @@ -2044,80 +2040,6 @@ ticcmd_t *I_BaseTiccmd2(void) return &emptycmd2; } -#if defined (_WIN32) -static HMODULE winmm = NULL; -static DWORD starttickcount = 0; // hack for win2k time bug -static p_timeGetTime pfntimeGetTime = NULL; - -// --------- -// I_GetTime -// Use the High Resolution Timer if available, -// else use the multimedia timer which has 1 millisecond precision on Windowz 95, -// but lower precision on Windows NT -// --------- - -DWORD TimeFunction(int requested_frequency) -{ - DWORD newtics = 0; - // this var acts as a multiplier if sub-millisecond precision is asked but is not available - int excess_frequency = requested_frequency / 1000; - - if (!starttickcount) // high precision timer - { - LARGE_INTEGER currtime; // use only LowPart if high resolution counter is not available - static LARGE_INTEGER basetime = {{0, 0}}; - - // use this if High Resolution timer is found - static LARGE_INTEGER frequency; - - if (!basetime.LowPart) - { - if (!QueryPerformanceFrequency(&frequency)) - frequency.QuadPart = 0; - else - QueryPerformanceCounter(&basetime); - } - - if (frequency.LowPart && QueryPerformanceCounter(&currtime)) - { - newtics = (INT32)((currtime.QuadPart - basetime.QuadPart) * requested_frequency - / frequency.QuadPart); - } - else if (pfntimeGetTime) - { - currtime.LowPart = pfntimeGetTime(); - if (!basetime.LowPart) - basetime.LowPart = currtime.LowPart; - if (requested_frequency > 1000) - newtics = currtime.LowPart - basetime.LowPart * excess_frequency; - else - newtics = (currtime.LowPart - basetime.LowPart)/(1000/requested_frequency); - } - } - else - { - if (requested_frequency > 1000) - newtics = (GetTickCount() - starttickcount) * excess_frequency; - else - newtics = (GetTickCount() - starttickcount)/(1000/requested_frequency); - } - - return newtics; -} - -static void I_ShutdownTimer(void) -{ - pfntimeGetTime = NULL; - if (winmm) - { - p_timeEndPeriod pfntimeEndPeriod = (p_timeEndPeriod)(LPVOID)GetProcAddress(winmm, "timeEndPeriod"); - if (pfntimeEndPeriod) - pfntimeEndPeriod(1); - FreeLibrary(winmm); - winmm = NULL; - } -} -#else // // I_GetTime // returns time in 1/TICRATE second tics @@ -2140,7 +2062,6 @@ int TimeFunction(int requested_frequency) return ticks; } -#endif tic_t I_GetTime(void) { @@ -2157,27 +2078,8 @@ int I_GetTimeMicros(void) // void I_StartupTimer(void) { -#ifdef _WIN32 - // for win2k time bug - if (M_CheckParm("-gettickcount")) - { - starttickcount = GetTickCount(); - CONS_Printf("%s", M_GetText("Using GetTickCount()\n")); - } - winmm = LoadLibraryA("winmm.dll"); - if (winmm) - { - p_timeEndPeriod pfntimeBeginPeriod = (p_timeEndPeriod)(LPVOID)GetProcAddress(winmm, "timeBeginPeriod"); - if (pfntimeBeginPeriod) - pfntimeBeginPeriod(1); - pfntimeGetTime = (p_timeGetTime)(LPVOID)GetProcAddress(winmm, "timeGetTime"); - } - I_AddExitFunc(I_ShutdownTimer); -#endif } - - void I_Sleep(void) { if (cv_sleep.value != -1) From cc8bd7ef5928b01729dfe6b20bc94b0e43dad16f Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Sat, 7 Nov 2020 00:19:43 +0200 Subject: [PATCH 030/644] Clarify license file mention in libdivide.h --- src/libdivide.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libdivide.h b/src/libdivide.h index 915da0070..1a589c7e5 100644 --- a/src/libdivide.h +++ b/src/libdivide.h @@ -6,7 +6,7 @@ // // libdivide is dual-licensed under the Boost or zlib licenses. // You may use libdivide under the terms of either of these. -// See LICENSE.txt for more details. +// See LICENSE.txt in the libdivide source code repository for more details. // NOTICE: This is an altered source version of libdivide. From 84ce53db60bce109fe87a895d5341ac3f7cd0673 Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 7 Nov 2020 01:31:24 -0800 Subject: [PATCH 031/644] Use high precision timer, replace I_GetTimeMicros with I_GetPreciseTime and I_PreciseToMicros --- src/doomtype.h | 4 ++++ src/i_system.h | 8 +++++++- src/sdl/i_system.c | 35 +++++++++++++---------------------- 3 files changed, 24 insertions(+), 23 deletions(-) diff --git a/src/doomtype.h b/src/doomtype.h index 4e13ba96d..c239c7b8e 100644 --- a/src/doomtype.h +++ b/src/doomtype.h @@ -379,4 +379,8 @@ Needed for some lua shenanigans. #define FIELDFROM( type, field, have, want ) \ (void *)((intptr_t)(field) - offsetof (type, have) + offsetof (type, want)) +#ifdef HAVE_SDL +typedef UINT64 precise_t; +#endif + #endif //__DOOMTYPE__ diff --git a/src/i_system.h b/src/i_system.h index dd0b65f6d..12f0d751d 100644 --- a/src/i_system.h +++ b/src/i_system.h @@ -46,7 +46,13 @@ UINT32 I_GetFreeMem(UINT32 *total); */ tic_t I_GetTime(void); -int I_GetTimeMicros(void);// provides microsecond counter for render stats +/** \brief Returns precise time value for performance measurement. + */ +precise_t I_GetPreciseTime(void); + +/** \brief Returns the difference between precise times as microseconds. + */ +int I_PreciseToMicros(precise_t); /** \brief The I_Sleep function diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 70ae938e9..8a70847e1 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -54,8 +54,6 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); #include #endif -int TimeFunction(int requested_frequency); - #include #ifdef _WIN32 #include @@ -2045,32 +2043,23 @@ ticcmd_t *I_BaseTiccmd2(void) // returns time in 1/TICRATE second tics // -// millisecond precision only -int TimeFunction(int requested_frequency) -{ - static Uint64 basetime = 0; - Uint64 ticks = SDL_GetTicks(); - - if (!basetime) - basetime = ticks; - - ticks -= basetime; - - ticks = (ticks*requested_frequency); - - ticks = (ticks/1000); - - return ticks; -} +static Uint64 timer_frequency; +static Uint64 tic_epoch; tic_t I_GetTime(void) { - return TimeFunction(NEWTICRATE); + const Uint64 now = SDL_GetPerformanceCounter(); + return (now - tic_epoch) * NEWTICRATE / timer_frequency; } -int I_GetTimeMicros(void) +precise_t I_GetPreciseTime(void) { - return TimeFunction(1000000); + return SDL_GetPerformanceCounter(); +} + +int I_PreciseToMicros(precise_t d) +{ + return d / (timer_frequency / 1000000); } // @@ -2078,6 +2067,8 @@ int I_GetTimeMicros(void) // void I_StartupTimer(void) { + timer_frequency = SDL_GetPerformanceFrequency(); + tic_epoch = SDL_GetPerformanceCounter(); } void I_Sleep(void) From e5f37523b846665f3812d75741a590ea132ff681 Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 7 Nov 2020 01:32:25 -0800 Subject: [PATCH 032/644] Use precise time for gif timing --- src/m_anigif.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/m_anigif.c b/src/m_anigif.c index 0d3206d11..4e28c3e72 100644 --- a/src/m_anigif.c +++ b/src/m_anigif.c @@ -18,7 +18,7 @@ #include "z_zone.h" #include "v_video.h" #include "i_video.h" -#include "i_system.h" // I_GetTimeMicros +#include "i_system.h" // I_GetPreciseTime #include "m_misc.h" #include "st_stuff.h" // st_palette @@ -47,8 +47,8 @@ static RGBA_t *gif_framepalette = NULL; static FILE *gif_out = NULL; static INT32 gif_frames = 0; -static UINT32 gif_prevframeus = 0; // "us" is microseconds -static UINT32 gif_delayus = 0; +static precise_t gif_prevframetime = 0; +static UINT32 gif_delayus = 0; // "us" is microseconds static UINT8 gif_writeover = 0; @@ -601,7 +601,7 @@ static void GIF_framewrite(void) if (gif_dynamicdelay) { // golden's attempt at creating a "dynamic delay" UINT16 mingifdelay = 10; // minimum gif delay in milliseconds (keep at 10 because gifs can't get more precise). - gif_delayus += (I_GetTimeMicros() - gif_prevframeus); // increase delay by how much time was spent between last measurement + gif_delayus += I_PreciseToMicros(I_GetPreciseTime() - gif_prevframetime); // increase delay by how much time was spent between last measurement if (gif_delayus/1000 >= mingifdelay) // delay is big enough to be able to effect gif frame delay? { @@ -695,7 +695,7 @@ static void GIF_framewrite(void) } fwrite(gifframe_data, 1, (p - gifframe_data), gif_out); ++gif_frames; - gif_prevframeus = I_GetTimeMicros(); + gif_prevframetime = I_GetPreciseTime(); } @@ -723,7 +723,7 @@ INT32 GIF_open(const char *filename) GIF_headwrite(); gif_frames = 0; - gif_prevframeus = I_GetTimeMicros(); + gif_prevframetime = I_GetPreciseTime(); gif_delayus = 0; return 1; } From b72789b0c90045a6c500663854c73ff17ee067cd Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 7 Nov 2020 01:32:59 -0800 Subject: [PATCH 033/644] Huge perfstats refactor I needed to update it to make it functional with the precise timer. But I also got sick of looking at the mess of sprintf followed by draw call. --- src/d_clisrv.c | 4 +- src/d_main.c | 14 +- src/hardware/hw_batching.c | 8 +- src/hardware/hw_main.c | 38 +- src/hardware/hw_main.h | 14 +- src/lua_hooklib.c | 6 +- src/m_perfstats.c | 807 +++++++++++++++++++------------------ src/m_perfstats.h | 14 +- src/p_tick.c | 18 +- src/r_main.c | 40 +- src/r_main.h | 18 +- 11 files changed, 511 insertions(+), 470 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index e314d419f..d9a7ce62c 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -5445,14 +5445,14 @@ void TryRunTics(tic_t realtics) { DEBFILE(va("============ Running tic %d (local %d)\n", gametic, localgametic)); - ps_tictime = I_GetTimeMicros(); + ps_tictime = I_GetPreciseTime(); G_Ticker((gametic % NEWTICRATERATIO) == 0); ExtraDataTicker(); gametic++; consistancy[gametic%BACKUPTICS] = Consistancy(); - ps_tictime = I_GetTimeMicros() - ps_tictime; + ps_tictime = I_GetPreciseTime() - ps_tictime; // Leave a certain amount of tics present in the net buffer as long as we've ran at least one tic this frame. if (client && gamestate == GS_LEVEL && leveltime > 3 && neededtic <= gametic + cv_netticbuffer.value) diff --git a/src/d_main.c b/src/d_main.c index ce1331fe3..caf6f0c22 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -436,7 +436,7 @@ static void D_Display(void) if (!automapactive && !dedicated && cv_renderview.value) { - ps_rendercalltime = I_GetTimeMicros(); + ps_rendercalltime = I_GetPreciseTime(); if (players[displayplayer].mo || players[displayplayer].playerstate == PST_DEAD) { topleft = screens[0] + viewwindowy*vid.width + viewwindowx; @@ -483,7 +483,7 @@ static void D_Display(void) if (postimgtype2) V_DoPostProcessor(1, postimgtype2, postimgparam2); } - ps_rendercalltime = I_GetTimeMicros() - ps_rendercalltime; + ps_rendercalltime = I_GetPreciseTime() - ps_rendercalltime; } if (lastdraw) @@ -497,7 +497,7 @@ static void D_Display(void) lastdraw = false; } - ps_uitime = I_GetTimeMicros(); + ps_uitime = I_GetPreciseTime(); if (gamestate == GS_LEVEL) { @@ -510,7 +510,7 @@ static void D_Display(void) } else { - ps_uitime = I_GetTimeMicros(); + ps_uitime = I_GetPreciseTime(); } } @@ -552,7 +552,7 @@ static void D_Display(void) CON_Drawer(); - ps_uitime = I_GetTimeMicros() - ps_uitime; + ps_uitime = I_GetPreciseTime() - ps_uitime; // // wipe update @@ -638,9 +638,9 @@ static void D_Display(void) M_DrawPerfStats(); } - ps_swaptime = I_GetTimeMicros(); + ps_swaptime = I_GetPreciseTime(); I_FinishUpdate(); // page flip or blit buffer - ps_swaptime = I_GetTimeMicros() - ps_swaptime; + ps_swaptime = I_GetPreciseTime() - ps_swaptime; } needpatchflush = false; diff --git a/src/hardware/hw_batching.c b/src/hardware/hw_batching.c index 5ea9f55d4..fb3417158 100644 --- a/src/hardware/hw_batching.c +++ b/src/hardware/hw_batching.c @@ -248,12 +248,12 @@ void HWR_RenderBatches(void) } // sort polygons - ps_hw_batchsorttime = I_GetTimeMicros(); + ps_hw_batchsorttime = I_GetPreciseTime(); if (cv_glshaders.value && gl_shadersavailable) qsort(polygonIndexArray, polygonArraySize, sizeof(unsigned int), comparePolygons); else qsort(polygonIndexArray, polygonArraySize, sizeof(unsigned int), comparePolygonsNoShaders); - ps_hw_batchsorttime = I_GetTimeMicros() - ps_hw_batchsorttime; + ps_hw_batchsorttime = I_GetPreciseTime() - ps_hw_batchsorttime; // sort order // 1. shader // 2. texture @@ -261,7 +261,7 @@ void HWR_RenderBatches(void) // 4. colors + light level // not sure about what order of the last 2 should be, or if it even matters - ps_hw_batchdrawtime = I_GetTimeMicros(); + ps_hw_batchdrawtime = I_GetPreciseTime(); currentShader = polygonArray[polygonIndexArray[0]].shader; currentTexture = polygonArray[polygonIndexArray[0]].texture; @@ -446,7 +446,7 @@ void HWR_RenderBatches(void) polygonArraySize = 0; unsortedVertexArraySize = 0; - ps_hw_batchdrawtime = I_GetTimeMicros() - ps_hw_batchdrawtime; + ps_hw_batchdrawtime = I_GetPreciseTime() - ps_hw_batchdrawtime; } diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 4268556e3..3df494272 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -146,11 +146,11 @@ static angle_t gl_aimingangle; static void HWR_SetTransformAiming(FTransform *trans, player_t *player, boolean skybox); // Render stats -int ps_hw_skyboxtime = 0; -int ps_hw_nodesorttime = 0; -int ps_hw_nodedrawtime = 0; -int ps_hw_spritesorttime = 0; -int ps_hw_spritedrawtime = 0; +precise_t ps_hw_skyboxtime = 0; +precise_t ps_hw_nodesorttime = 0; +precise_t ps_hw_nodedrawtime = 0; +precise_t ps_hw_spritesorttime = 0; +precise_t ps_hw_spritedrawtime = 0; // Render stats for batching int ps_hw_numpolys = 0; @@ -160,8 +160,8 @@ int ps_hw_numshaders = 0; int ps_hw_numtextures = 0; int ps_hw_numpolyflags = 0; int ps_hw_numcolors = 0; -int ps_hw_batchsorttime = 0; -int ps_hw_batchdrawtime = 0; +precise_t ps_hw_batchsorttime = 0; +precise_t ps_hw_batchdrawtime = 0; boolean gl_shadersavailable = true; @@ -4503,7 +4503,7 @@ static void HWR_CreateDrawNodes(void) // that is already lying around. This should all be in some sort of linked list or lists. sortindex = Z_Calloc(sizeof(size_t) * (numplanes + numpolyplanes + numwalls), PU_STATIC, NULL); - ps_hw_nodesorttime = I_GetTimeMicros(); + ps_hw_nodesorttime = I_GetPreciseTime(); for (i = 0; i < numplanes; i++, p++) { @@ -4558,9 +4558,9 @@ static void HWR_CreateDrawNodes(void) } } - ps_hw_nodesorttime = I_GetTimeMicros() - ps_hw_nodesorttime; + ps_hw_nodesorttime = I_GetPreciseTime() - ps_hw_nodesorttime; - ps_hw_nodedrawtime = I_GetTimeMicros(); + ps_hw_nodedrawtime = I_GetPreciseTime(); // Okay! Let's draw it all! Woo! HWD.pfnSetTransform(&atransform); @@ -4597,7 +4597,7 @@ static void HWR_CreateDrawNodes(void) } } - ps_hw_nodedrawtime = I_GetTimeMicros() - ps_hw_nodedrawtime; + ps_hw_nodedrawtime = I_GetPreciseTime() - ps_hw_nodedrawtime; numwalls = 0; numplanes = 0; @@ -5778,10 +5778,10 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) if (viewnumber == 0) // Only do it if it's the first screen being rendered HWD.pfnClearBuffer(true, false, &ClearColor); // Clear the Color Buffer, stops HOMs. Also seems to fix the skybox issue on Intel GPUs. - ps_hw_skyboxtime = I_GetTimeMicros(); + ps_hw_skyboxtime = I_GetPreciseTime(); if (skybox && drawsky) // If there's a skybox and we should be drawing the sky, draw the skybox HWR_RenderSkyboxView(viewnumber, player); // This is drawn before everything else so it is placed behind - ps_hw_skyboxtime = I_GetTimeMicros() - ps_hw_skyboxtime; + ps_hw_skyboxtime = I_GetPreciseTime() - ps_hw_skyboxtime; { // do we really need to save player (is it not the same)? @@ -5894,7 +5894,7 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) ps_numbspcalls = 0; ps_numpolyobjects = 0; - ps_bsptime = I_GetTimeMicros(); + ps_bsptime = I_GetPreciseTime(); validcount++; @@ -5932,7 +5932,7 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) } #endif - ps_bsptime = I_GetTimeMicros() - ps_bsptime; + ps_bsptime = I_GetPreciseTime() - ps_bsptime; if (cv_glbatching.value) HWR_RenderBatches(); @@ -5948,12 +5948,12 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) // Draw MD2 and sprites ps_numsprites = gl_visspritecount; - ps_hw_spritesorttime = I_GetTimeMicros(); + ps_hw_spritesorttime = I_GetPreciseTime(); HWR_SortVisSprites(); - ps_hw_spritesorttime = I_GetTimeMicros() - ps_hw_spritesorttime; - ps_hw_spritedrawtime = I_GetTimeMicros(); + ps_hw_spritesorttime = I_GetPreciseTime() - ps_hw_spritesorttime; + ps_hw_spritedrawtime = I_GetPreciseTime(); HWR_DrawSprites(); - ps_hw_spritedrawtime = I_GetTimeMicros() - ps_hw_spritedrawtime; + ps_hw_spritedrawtime = I_GetPreciseTime() - ps_hw_spritedrawtime; #ifdef NEWCORONAS //Hurdler: they must be drawn before translucent planes, what about gl fog? diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index 85072dfd9..4db0a9231 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -113,11 +113,11 @@ extern FTransform atransform; // Render stats -extern int ps_hw_skyboxtime; -extern int ps_hw_nodesorttime; -extern int ps_hw_nodedrawtime; -extern int ps_hw_spritesorttime; -extern int ps_hw_spritedrawtime; +extern precise_t ps_hw_skyboxtime; +extern precise_t ps_hw_nodesorttime; +extern precise_t ps_hw_nodedrawtime; +extern precise_t ps_hw_spritesorttime; +extern precise_t ps_hw_spritedrawtime; // Render stats for batching extern int ps_hw_numpolys; @@ -127,8 +127,8 @@ extern int ps_hw_numshaders; extern int ps_hw_numtextures; extern int ps_hw_numpolyflags; extern int ps_hw_numcolors; -extern int ps_hw_batchsorttime; -extern int ps_hw_batchdrawtime; +extern precise_t ps_hw_batchsorttime; +extern precise_t ps_hw_batchdrawtime; extern boolean gl_shadersavailable; diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 65d483dc1..602dbf0ec 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -25,7 +25,7 @@ #include "m_perfstats.h" #include "d_netcmd.h" // for cv_perfstats -#include "i_system.h" // I_GetTimeMicros +#include "i_system.h" // I_GetPreciseTime static UINT8 hooksAvailable[(hook_MAX/8)+1]; @@ -480,7 +480,7 @@ void LUAh_ThinkFrame(void) continue; if (cv_perfstats.value == 3) - time_taken = I_GetTimeMicros(); + time_taken = I_GetPreciseTime(); PushHook(gL, hookp); if (lua_pcall(gL, 0, 0, 1)) { if (!hookp->error || cv_debug & DBG_LUA) @@ -491,7 +491,7 @@ void LUAh_ThinkFrame(void) if (cv_perfstats.value == 3) { lua_Debug ar; - time_taken = I_GetTimeMicros() - time_taken; + time_taken = I_GetPreciseTime() - time_taken; // we need the function, let's just retrieve it again PushHook(gL, hookp); lua_getinfo(gL, ">S", &ar); diff --git a/src/m_perfstats.c b/src/m_perfstats.c index 085adda80..1596a87e5 100644 --- a/src/m_perfstats.c +++ b/src/m_perfstats.c @@ -22,32 +22,37 @@ #include "hardware/hw_main.h" #endif -int ps_tictime = 0; +struct perfstatcol; +struct perfstatrow; -int ps_playerthink_time = 0; -int ps_thinkertime = 0; +typedef struct perfstatcol perfstatcol_t; +typedef struct perfstatrow perfstatrow_t; -int ps_thlist_times[NUM_THINKERLISTS]; -static const char* thlist_names[] = { - "Polyobjects: %d", - "Main: %d", - "Mobjs: %d", - "Dynamic slopes: %d", - "Precipitation: %d", - NULL +struct perfstatcol { + INT32 lores_x; + INT32 hires_x; + INT32 color; + perfstatrow_t * rows; }; -static const char* thlist_shortnames[] = { - "plyobjs %d", - "main %d", - "mobjs %d", - "dynslop %d", - "precip %d", - NULL + +struct perfstatrow { + const char * lores_label; + const char * hires_label; + void * value; }; +static precise_t ps_frametime = 0; + +precise_t ps_tictime = 0; + +precise_t ps_playerthink_time = 0; +precise_t ps_thinkertime = 0; + +precise_t ps_thlist_times[NUM_THINKERLISTS]; + int ps_checkposition_calls = 0; -int ps_lua_thinkframe_time = 0; +precise_t ps_lua_thinkframe_time = 0; int ps_lua_mobjhooks = 0; // dynamically allocated resizeable array for thinkframe hook stats @@ -55,6 +60,8 @@ ps_hookinfo_t *thinkframe_hooks = NULL; int thinkframe_hooks_length = 0; int thinkframe_hooks_capacity = 16; +static INT32 draw_row; + void PS_SetThinkFrameHookInfo(int index, UINT32 time_taken, char* short_src) { if (!thinkframe_hooks) @@ -76,379 +83,413 @@ void PS_SetThinkFrameHookInfo(int index, UINT32 time_taken, char* short_src) thinkframe_hooks_length = index + 1; } +static void PS_SetFrameTime(void) +{ + precise_t currenttime = I_GetPreciseTime(); + ps_frametime = currenttime - ps_prevframetime; + ps_prevframetime = currenttime; +} + +static boolean M_HighResolution(void) +{ + return (vid.width >= 640 && vid.height >= 400); +} + +enum { + PERF_TIME, + PERF_COUNT, +}; + +static void M_DrawPerfString(perfstatcol_t *col, int type) +{ + const boolean hires = M_HighResolution(); + + INT32 draw_flags = V_MONOSPACE | col->color; + + perfstatrow_t * row; + + int value; + + if (hires) + draw_flags |= V_ALLOWLOWERCASE; + + for (row = col->rows; row->lores_label; ++row) + { + if (type == PERF_TIME) + value = I_PreciseToMicros(*(precise_t *)row->value); + else + value = *(int *)row->value; + + if (hires) + { + V_DrawSmallString(col->hires_x, draw_row, draw_flags, + va("%s %d", row->hires_label, value)); + + draw_row += 5; + } + else + { + V_DrawThinString(col->lores_x, draw_row, draw_flags, + va("%s %d", row->lores_label, value)); + + draw_row += 8; + } + } +} + +static void M_DrawPerfTiming(perfstatcol_t *col) +{ + M_DrawPerfString(col, PERF_TIME); +} + +static void M_DrawPerfCount(perfstatcol_t *col) +{ + M_DrawPerfString(col, PERF_COUNT); +} + +static void M_DrawRenderStats(void) +{ + const boolean hires = M_HighResolution(); + + const int half_row = hires ? 5 : 4; + + precise_t extrarendertime; + + perfstatrow_t frametime_row[] = { + {"frmtime", "Frame time: ", &ps_frametime}, + {0} + }; + + perfstatrow_t rendercalltime_row[] = { + {"drwtime", "3d rendering: ", &ps_rendercalltime}, + {0} + }; + + perfstatrow_t opengltime_row[] = { + {"skybox ", "Skybox render: ", &ps_hw_skyboxtime}, + {"bsptime", "RenderBSPNode: ", &ps_bsptime}, + {"nodesrt", "Drwnode sort: ", &ps_hw_nodesorttime}, + {"nodedrw", "Drwnode render:", &ps_hw_nodedrawtime}, + {"sprsort", "Sprite sort: ", &ps_hw_spritesorttime}, + {"sprdraw", "Sprite render: ", &ps_hw_spritedrawtime}, + {"other ", "Other: ", &extrarendertime}, + {0} + }; + + perfstatrow_t softwaretime_row[] = { + {"bsptime", "RenderBSPNode: ", &ps_bsptime}, + {"sprclip", "R_ClipSprites: ", &ps_sw_spritecliptime}, + {"portals", "Portals+Skybox:", &ps_sw_portaltime}, + {"planes ", "R_DrawPlanes: ", &ps_sw_planetime}, + {"masked ", "R_DrawMasked: ", &ps_sw_maskedtime}, + {"other ", "Other: ", &extrarendertime}, + {0} + }; + + perfstatrow_t uiswaptime_row[] = { + {"ui ", "UI render: ", &ps_uitime}, + {"finupdt", "I_FinishUpdate:", &ps_swaptime}, + {0} + }; + + perfstatrow_t tictime_row[] = { + {"logic ", "Game logic: ", &ps_tictime}, + {0} + }; + + perfstatrow_t rendercalls_row[] = { + {"bspcall", "BSP calls: ", &ps_numbspcalls}, + {"sprites", "Sprites: ", &ps_numsprites}, + {"drwnode", "Drawnodes: ", &ps_numdrawnodes}, + {"plyobjs", "Polyobjects: ", &ps_numpolyobjects}, + {0} + }; + + perfstatrow_t batchtime_row[] = { + {"batsort", "Batch sort: ", &ps_hw_batchsorttime}, + {"batdraw", "Batch render:", &ps_hw_batchdrawtime}, + {0} + }; + + perfstatrow_t batchcount_row[] = { + {"polygon", "Polygons: ", &ps_hw_numpolys}, + {"vertex ", "Vertices: ", &ps_hw_numverts}, + {0} + }; + + perfstatrow_t batchcalls_row[] = { + {"drwcall", "Draw calls:", &ps_hw_numcalls}, + {"shaders", "Shaders: ", &ps_hw_numshaders}, + {"texture", "Textures: ", &ps_hw_numtextures}, + {"polyflg", "Polyflags: ", &ps_hw_numpolyflags}, + {"colors ", "Colors: ", &ps_hw_numcolors}, + {0} + }; + + perfstatcol_t frametime_col = {20, 20, V_YELLOWMAP, frametime_row}; + perfstatcol_t rendercalltime_col = {20, 20, V_YELLOWMAP, rendercalltime_row}; + + perfstatcol_t opengltime_col = {24, 24, V_YELLOWMAP, opengltime_row}; + perfstatcol_t softwaretime_col = {24, 24, V_YELLOWMAP, softwaretime_row}; + + perfstatcol_t uiswaptime_col = {20, 20, V_YELLOWMAP, uiswaptime_row}; + perfstatcol_t tictime_col = {20, 20, V_GRAYMAP, tictime_row}; + + perfstatcol_t rendercalls_col = {90, 115, V_BLUEMAP, rendercalls_row}; + + perfstatcol_t batchtime_col = {90, 115, V_REDMAP, batchtime_row}; + + perfstatcol_t batchcount_col = {155, 200, V_PURPLEMAP, batchcount_row}; + perfstatcol_t batchcalls_col = {220, 200, V_PURPLEMAP, batchcalls_row}; + + + boolean rendering = ( + gamestate == GS_LEVEL || + (gamestate == GS_TITLESCREEN && titlemapinaction) + ); + + draw_row = 10; + M_DrawPerfTiming(&frametime_col); + + if (rendering) + { + M_DrawPerfTiming(&rendercalltime_col); + + // Remember to update this calculation when adding more 3d rendering stats! + extrarendertime = ps_rendercalltime - ps_bsptime; + +#ifdef HWRENDER + if (rendermode == render_opengl) + { + extrarendertime -= + ps_hw_skyboxtime + + ps_hw_nodesorttime + + ps_hw_nodedrawtime + + ps_hw_spritesorttime + + ps_hw_spritedrawtime; + + if (cv_glbatching.value) + { + extrarendertime -= + ps_hw_batchsorttime + + ps_hw_batchdrawtime; + } + + M_DrawPerfTiming(&opengltime_col); + } + else +#endif + { + extrarendertime -= + ps_sw_spritecliptime + + ps_sw_portaltime + + ps_sw_planetime + + ps_sw_maskedtime; + + M_DrawPerfTiming(&softwaretime_col); + } + } + + M_DrawPerfTiming(&uiswaptime_col); + + draw_row += half_row; + M_DrawPerfTiming(&tictime_col); + + if (rendering) + { + draw_row = 10; + M_DrawPerfCount(&rendercalls_col); + +#ifdef HWRENDER + if (rendermode == render_opengl && cv_glbatching.value) + { + draw_row += half_row; + M_DrawPerfTiming(&batchtime_col); + + draw_row = 10; + M_DrawPerfCount(&batchcount_col); + + if (hires) + draw_row += half_row; + else + draw_row = 10; + + M_DrawPerfCount(&batchcalls_col); + } +#endif + } +} + +static void M_DrawTickStats(void) +{ + int i = 0; + thinker_t *thinker; + int thinkercount = 0; + int polythcount = 0; + int mainthcount = 0; + int mobjcount = 0; + int nothinkcount = 0; + int scenerycount = 0; + int regularcount = 0; + int dynslopethcount = 0; + int precipcount = 0; + int removecount = 0; + + precise_t extratime = + ps_tictime - + ps_playerthink_time - + ps_thinkertime - + ps_lua_thinkframe_time; + + perfstatrow_t tictime_row[] = { + {"logic ", "Game logic: ", &ps_tictime}, + {0} + }; + + perfstatrow_t thinker_time_row[] = { + {"plrthnk", "P_PlayerThink: ", &ps_playerthink_time}, + {"thnkers", "P_RunThinkers: ", &ps_thinkertime}, + {0} + }; + + perfstatrow_t detailed_thinker_time_row[] = { + {"plyobjs", "Polyobjects: ", &ps_thlist_times[THINK_POLYOBJ]}, + {"main ", "Main: ", &ps_thlist_times[THINK_MAIN]}, + {"mobjs ", "Mobjs: ", &ps_thlist_times[THINK_MOBJ]}, + {"dynslop", "Dynamic slopes: ", &ps_thlist_times[THINK_DYNSLOPE]}, + {"precip ", "Precipitation: ", &ps_thlist_times[THINK_PRECIP]}, + {0} + }; + + perfstatrow_t extra_thinker_time_row[] = { + {"lthinkf", "LUAh_ThinkFrame:", &ps_lua_thinkframe_time}, + {"other ", "Other: ", &extratime}, + {0} + }; + + perfstatrow_t thinkercount_row[] = { + {"thnkers", "Thinkers: ", &thinkercount}, + {0} + }; + + perfstatrow_t detailed_thinkercount_row[] = { + {"plyobjs", "Polyobjects: ", &polythcount}, + {"main ", "Main: ", &mainthcount}, + {"mobjs ", "Mobjs: ", &mobjcount}, + {0} + }; + + perfstatrow_t mobjthinkercount_row[] = { + {"regular", "Regular: ", ®ularcount}, + {"scenery", "Scenery: ", &scenerycount}, + {0} + }; + + perfstatrow_t nothinkcount_row[] = { + {"nothink", "Nothink: ", ¬hinkcount}, + {0} + }; + + perfstatrow_t detailed_thinkercount_row2[] = { + {"dynslop", "Dynamic slopes: ", &dynslopethcount}, + {"precip ", "Precipitation: ", &precipcount}, + {"remove ", "Pending removal:", &removecount}, + {0} + }; + + perfstatrow_t misc_calls_row[] = { + {"lmhook", "Lua mobj hooks: ", &ps_lua_mobjhooks}, + {"chkpos", "P_CheckPosition:", &ps_checkposition_calls}, + {0} + }; + + perfstatcol_t tictime_col = {20, 20, V_YELLOWMAP, tictime_row}; + perfstatcol_t thinker_time_col = {24, 24, V_YELLOWMAP, thinker_time_row}; + perfstatcol_t detailed_thinker_time_col = {28, 28, V_YELLOWMAP, detailed_thinker_time_row}; + perfstatcol_t extra_thinker_time_col = {24, 24, V_YELLOWMAP, extra_thinker_time_row}; + + perfstatcol_t thinkercount_col = {90, 115, V_BLUEMAP, thinkercount_row}; + perfstatcol_t detailed_thinkercount_col = {94, 119, V_BLUEMAP, detailed_thinkercount_row}; + perfstatcol_t mobjthinkercount_col = {98, 123, V_BLUEMAP, mobjthinkercount_row}; + perfstatcol_t nothinkcount_col = {98, 123, V_BLUEMAP, nothinkcount_row}; + perfstatcol_t detailed_thinkercount_col2 = {94, 119, V_BLUEMAP, detailed_thinkercount_row2}; + perfstatcol_t misc_calls_col = {170, 216, V_PURPLEMAP, misc_calls_row}; + + for (i = 0; i < NUM_THINKERLISTS; i++) + { + for (thinker = thlist[i].next; thinker != &thlist[i]; thinker = thinker->next) + { + thinkercount++; + if (thinker->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + removecount++; + else if (i == THINK_POLYOBJ) + polythcount++; + else if (i == THINK_MAIN) + mainthcount++; + else if (i == THINK_MOBJ) + { + if (thinker->function.acp1 == (actionf_p1)P_MobjThinker) + { + mobj_t *mobj = (mobj_t*)thinker; + mobjcount++; + if (mobj->flags & MF_NOTHINK) + nothinkcount++; + else if (mobj->flags & MF_SCENERY) + scenerycount++; + else + regularcount++; + } + } + else if (i == THINK_DYNSLOPE) + dynslopethcount++; + else if (i == THINK_PRECIP) + precipcount++; + } + } + + draw_row = 10; + M_DrawPerfTiming(&tictime_col); + M_DrawPerfTiming(&thinker_time_col); + M_DrawPerfTiming(&detailed_thinker_time_col); + M_DrawPerfTiming(&extra_thinker_time_col); + + draw_row = 10; + M_DrawPerfCount(&thinkercount_col); + M_DrawPerfCount(&detailed_thinkercount_col); + M_DrawPerfCount(&mobjthinkercount_col); + + if (nothinkcount) + M_DrawPerfCount(¬hinkcount_col); + + M_DrawPerfCount(&detailed_thinkercount_col2); + + if (M_HighResolution()) + { + V_DrawSmallString(212, 10, V_MONOSPACE | V_ALLOWLOWERCASE | V_PURPLEMAP, "Calls:"); + + draw_row = 15; + } + else + { + draw_row = 10; + } + + M_DrawPerfCount(&misc_calls_col); +} + void M_DrawPerfStats(void) { char s[100]; - int currenttime = I_GetTimeMicros(); - int frametime = currenttime - ps_prevframetime; - ps_prevframetime = currenttime; + + PS_SetFrameTime(); if (cv_perfstats.value == 1) // rendering { - if (vid.width < 640 || vid.height < 400) // low resolution - { - snprintf(s, sizeof s - 1, "frmtime %d", frametime); - V_DrawThinString(20, 10, V_MONOSPACE | V_YELLOWMAP, s); - if (!(gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction))) - { - snprintf(s, sizeof s - 1, "ui %d", ps_uitime); - V_DrawThinString(20, 18, V_MONOSPACE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "finupdt %d", ps_swaptime); - V_DrawThinString(20, 26, V_MONOSPACE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "logic %d", ps_tictime); - V_DrawThinString(20, 38, V_MONOSPACE | V_GRAYMAP, s); - return; - } - snprintf(s, sizeof s - 1, "drwtime %d", ps_rendercalltime); - V_DrawThinString(20, 18, V_MONOSPACE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "bspcall %d", ps_numbspcalls); - V_DrawThinString(90, 10, V_MONOSPACE | V_BLUEMAP, s); - snprintf(s, sizeof s - 1, "sprites %d", ps_numsprites); - V_DrawThinString(90, 18, V_MONOSPACE | V_BLUEMAP, s); - snprintf(s, sizeof s - 1, "drwnode %d", ps_numdrawnodes); - V_DrawThinString(90, 26, V_MONOSPACE | V_BLUEMAP, s); - snprintf(s, sizeof s - 1, "plyobjs %d", ps_numpolyobjects); - V_DrawThinString(90, 34, V_MONOSPACE | V_BLUEMAP, s); -#ifdef HWRENDER - if (rendermode == render_opengl) // OpenGL specific stats - { - snprintf(s, sizeof s - 1, "skybox %d", ps_hw_skyboxtime); - V_DrawThinString(24, 26, V_MONOSPACE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "bsptime %d", ps_bsptime); - V_DrawThinString(24, 34, V_MONOSPACE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "nodesrt %d", ps_hw_nodesorttime); - V_DrawThinString(24, 42, V_MONOSPACE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "nodedrw %d", ps_hw_nodedrawtime); - V_DrawThinString(24, 50, V_MONOSPACE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "sprsort %d", ps_hw_spritesorttime); - V_DrawThinString(24, 58, V_MONOSPACE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "sprdraw %d", ps_hw_spritedrawtime); - V_DrawThinString(24, 66, V_MONOSPACE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "other %d", - ps_rendercalltime - ps_hw_skyboxtime - ps_bsptime - ps_hw_nodesorttime - - ps_hw_nodedrawtime - ps_hw_spritesorttime - ps_hw_spritedrawtime - - ps_hw_batchsorttime - ps_hw_batchdrawtime); - V_DrawThinString(24, 74, V_MONOSPACE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "ui %d", ps_uitime); - V_DrawThinString(20, 82, V_MONOSPACE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "finupdt %d", ps_swaptime); - V_DrawThinString(20, 90, V_MONOSPACE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "logic %d", ps_tictime); - V_DrawThinString(20, 102, V_MONOSPACE | V_GRAYMAP, s); - if (cv_glbatching.value) - { - snprintf(s, sizeof s - 1, "batsort %d", ps_hw_batchsorttime); - V_DrawThinString(90, 46, V_MONOSPACE | V_REDMAP, s); - snprintf(s, sizeof s - 1, "batdraw %d", ps_hw_batchdrawtime); - V_DrawThinString(90, 54, V_MONOSPACE | V_REDMAP, s); - - snprintf(s, sizeof s - 1, "polygon %d", ps_hw_numpolys); - V_DrawThinString(155, 10, V_MONOSPACE | V_PURPLEMAP, s); - snprintf(s, sizeof s - 1, "drwcall %d", ps_hw_numcalls); - V_DrawThinString(155, 18, V_MONOSPACE | V_PURPLEMAP, s); - snprintf(s, sizeof s - 1, "shaders %d", ps_hw_numshaders); - V_DrawThinString(155, 26, V_MONOSPACE | V_PURPLEMAP, s); - snprintf(s, sizeof s - 1, "vertex %d", ps_hw_numverts); - V_DrawThinString(155, 34, V_MONOSPACE | V_PURPLEMAP, s); - snprintf(s, sizeof s - 1, "texture %d", ps_hw_numtextures); - V_DrawThinString(220, 10, V_MONOSPACE | V_PURPLEMAP, s); - snprintf(s, sizeof s - 1, "polyflg %d", ps_hw_numpolyflags); - V_DrawThinString(220, 18, V_MONOSPACE | V_PURPLEMAP, s); - snprintf(s, sizeof s - 1, "colors %d", ps_hw_numcolors); - V_DrawThinString(220, 26, V_MONOSPACE | V_PURPLEMAP, s); - } - else - { - // reset these vars so the "other" measurement isn't off - ps_hw_batchsorttime = 0; - ps_hw_batchdrawtime = 0; - } - } - else // software specific stats -#endif - { - snprintf(s, sizeof s - 1, "bsptime %d", ps_bsptime); - V_DrawThinString(24, 26, V_MONOSPACE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "sprclip %d", ps_sw_spritecliptime); - V_DrawThinString(24, 34, V_MONOSPACE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "portals %d", ps_sw_portaltime); - V_DrawThinString(24, 42, V_MONOSPACE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "planes %d", ps_sw_planetime); - V_DrawThinString(24, 50, V_MONOSPACE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "masked %d", ps_sw_maskedtime); - V_DrawThinString(24, 58, V_MONOSPACE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "other %d", - ps_rendercalltime - ps_bsptime - ps_sw_spritecliptime - - ps_sw_portaltime - ps_sw_planetime - ps_sw_maskedtime); - V_DrawThinString(24, 66, V_MONOSPACE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "ui %d", ps_uitime); - V_DrawThinString(20, 74, V_MONOSPACE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "finupdt %d", ps_swaptime); - V_DrawThinString(20, 82, V_MONOSPACE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "logic %d", ps_tictime); - V_DrawThinString(20, 94, V_MONOSPACE | V_GRAYMAP, s); - } - } - else // high resolution - { - snprintf(s, sizeof s - 1, "Frame time: %d", frametime); - V_DrawSmallString(20, 10, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); - if (!(gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction))) - { - snprintf(s, sizeof s - 1, "UI render: %d", ps_uitime); - V_DrawSmallString(20, 15, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "I_FinishUpdate: %d", ps_swaptime); - V_DrawSmallString(20, 20, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "Game logic: %d", ps_tictime); - V_DrawSmallString(20, 30, V_MONOSPACE | V_ALLOWLOWERCASE | V_GRAYMAP, s); - return; - } - snprintf(s, sizeof s - 1, "3d rendering: %d", ps_rendercalltime); - V_DrawSmallString(20, 15, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "BSP calls: %d", ps_numbspcalls); - V_DrawSmallString(115, 10, V_MONOSPACE | V_ALLOWLOWERCASE | V_BLUEMAP, s); - snprintf(s, sizeof s - 1, "Sprites: %d", ps_numsprites); - V_DrawSmallString(115, 15, V_MONOSPACE | V_ALLOWLOWERCASE | V_BLUEMAP, s); - snprintf(s, sizeof s - 1, "Drawnodes: %d", ps_numdrawnodes); - V_DrawSmallString(115, 20, V_MONOSPACE | V_ALLOWLOWERCASE | V_BLUEMAP, s); - snprintf(s, sizeof s - 1, "Polyobjects: %d", ps_numpolyobjects); - V_DrawSmallString(115, 25, V_MONOSPACE | V_ALLOWLOWERCASE | V_BLUEMAP, s); -#ifdef HWRENDER - if (rendermode == render_opengl) // OpenGL specific stats - { - snprintf(s, sizeof s - 1, "Skybox render: %d", ps_hw_skyboxtime); - V_DrawSmallString(24, 20, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "RenderBSPNode: %d", ps_bsptime); - V_DrawSmallString(24, 25, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "Drwnode sort: %d", ps_hw_nodesorttime); - V_DrawSmallString(24, 30, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "Drwnode render: %d", ps_hw_nodedrawtime); - V_DrawSmallString(24, 35, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "Sprite sort: %d", ps_hw_spritesorttime); - V_DrawSmallString(24, 40, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "Sprite render: %d", ps_hw_spritedrawtime); - V_DrawSmallString(24, 45, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); - // Remember to update this calculation when adding more 3d rendering stats! - snprintf(s, sizeof s - 1, "Other: %d", - ps_rendercalltime - ps_hw_skyboxtime - ps_bsptime - ps_hw_nodesorttime - - ps_hw_nodedrawtime - ps_hw_spritesorttime - ps_hw_spritedrawtime - - ps_hw_batchsorttime - ps_hw_batchdrawtime); - V_DrawSmallString(24, 50, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "UI render: %d", ps_uitime); - V_DrawSmallString(20, 55, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "I_FinishUpdate: %d", ps_swaptime); - V_DrawSmallString(20, 60, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "Game logic: %d", ps_tictime); - V_DrawSmallString(20, 70, V_MONOSPACE | V_ALLOWLOWERCASE | V_GRAYMAP, s); - if (cv_glbatching.value) - { - snprintf(s, sizeof s - 1, "Batch sort: %d", ps_hw_batchsorttime); - V_DrawSmallString(115, 35, V_MONOSPACE | V_ALLOWLOWERCASE | V_REDMAP, s); - snprintf(s, sizeof s - 1, "Batch render: %d", ps_hw_batchdrawtime); - V_DrawSmallString(115, 40, V_MONOSPACE | V_ALLOWLOWERCASE | V_REDMAP, s); - - snprintf(s, sizeof s - 1, "Polygons: %d", ps_hw_numpolys); - V_DrawSmallString(200, 10, V_MONOSPACE | V_ALLOWLOWERCASE | V_PURPLEMAP, s); - snprintf(s, sizeof s - 1, "Vertices: %d", ps_hw_numverts); - V_DrawSmallString(200, 15, V_MONOSPACE | V_ALLOWLOWERCASE | V_PURPLEMAP, s); - snprintf(s, sizeof s - 1, "Draw calls: %d", ps_hw_numcalls); - V_DrawSmallString(200, 25, V_MONOSPACE | V_ALLOWLOWERCASE | V_PURPLEMAP, s); - snprintf(s, sizeof s - 1, "Shaders: %d", ps_hw_numshaders); - V_DrawSmallString(200, 30, V_MONOSPACE | V_ALLOWLOWERCASE | V_PURPLEMAP, s); - snprintf(s, sizeof s - 1, "Textures: %d", ps_hw_numtextures); - V_DrawSmallString(200, 35, V_MONOSPACE | V_ALLOWLOWERCASE | V_PURPLEMAP, s); - snprintf(s, sizeof s - 1, "Polyflags: %d", ps_hw_numpolyflags); - V_DrawSmallString(200, 40, V_MONOSPACE | V_ALLOWLOWERCASE | V_PURPLEMAP, s); - snprintf(s, sizeof s - 1, "Colors: %d", ps_hw_numcolors); - V_DrawSmallString(200, 45, V_MONOSPACE | V_ALLOWLOWERCASE | V_PURPLEMAP, s); - } - else - { - // reset these vars so the "other" measurement isn't off - ps_hw_batchsorttime = 0; - ps_hw_batchdrawtime = 0; - } - } - else // software specific stats -#endif - { - snprintf(s, sizeof s - 1, "RenderBSPNode: %d", ps_bsptime); - V_DrawSmallString(24, 20, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "R_ClipSprites: %d", ps_sw_spritecliptime); - V_DrawSmallString(24, 25, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "Portals+Skybox: %d", ps_sw_portaltime); - V_DrawSmallString(24, 30, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "R_DrawPlanes: %d", ps_sw_planetime); - V_DrawSmallString(24, 35, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "R_DrawMasked: %d", ps_sw_maskedtime); - V_DrawSmallString(24, 40, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); - // Remember to update this calculation when adding more 3d rendering stats! - snprintf(s, sizeof s - 1, "Other: %d", - ps_rendercalltime - ps_bsptime - ps_sw_spritecliptime - - ps_sw_portaltime - ps_sw_planetime - ps_sw_maskedtime); - V_DrawSmallString(24, 45, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "UI render: %d", ps_uitime); - V_DrawSmallString(20, 50, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "I_FinishUpdate: %d", ps_swaptime); - V_DrawSmallString(20, 55, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "Game logic: %d", ps_tictime); - V_DrawSmallString(20, 65, V_MONOSPACE | V_ALLOWLOWERCASE | V_GRAYMAP, s); - } - } + M_DrawRenderStats(); } else if (cv_perfstats.value == 2) // logic { - int i = 0; - thinker_t *thinker; - int thinkercount = 0; - int polythcount = 0; - int mainthcount = 0; - int mobjcount = 0; - int nothinkcount = 0; - int scenerycount = 0; - int dynslopethcount = 0; - int precipcount = 0; - int removecount = 0; - // y offset for drawing columns - int yoffset1 = 0; - int yoffset2 = 0; - - for (i = 0; i < NUM_THINKERLISTS; i++) - { - for (thinker = thlist[i].next; thinker != &thlist[i]; thinker = thinker->next) - { - thinkercount++; - if (thinker->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - removecount++; - else if (i == THINK_POLYOBJ) - polythcount++; - else if (i == THINK_MAIN) - mainthcount++; - else if (i == THINK_MOBJ) - { - if (thinker->function.acp1 == (actionf_p1)P_MobjThinker) - { - mobj_t *mobj = (mobj_t*)thinker; - mobjcount++; - if (mobj->flags & MF_NOTHINK) - nothinkcount++; - else if (mobj->flags & MF_SCENERY) - scenerycount++; - } - } - else if (i == THINK_DYNSLOPE) - dynslopethcount++; - else if (i == THINK_PRECIP) - precipcount++; - } - } - - if (vid.width < 640 || vid.height < 400) // low resolution - { - snprintf(s, sizeof s - 1, "logic %d", ps_tictime); - V_DrawThinString(20, 10, V_MONOSPACE | V_YELLOWMAP, s); - if (!(gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction))) - return; - snprintf(s, sizeof s - 1, "plrthnk %d", ps_playerthink_time); - V_DrawThinString(24, 18, V_MONOSPACE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "thnkers %d", ps_thinkertime); - V_DrawThinString(24, 26, V_MONOSPACE | V_YELLOWMAP, s); - for (i = 0; i < NUM_THINKERLISTS; i++) - { - yoffset1 += 8; - snprintf(s, sizeof s - 1, thlist_shortnames[i], ps_thlist_times[i]); - V_DrawThinString(28, 26+yoffset1, V_MONOSPACE | V_YELLOWMAP, s); - } - snprintf(s, sizeof s - 1, "lthinkf %d", ps_lua_thinkframe_time); - V_DrawThinString(24, 34+yoffset1, V_MONOSPACE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "other %d", - ps_tictime - ps_playerthink_time - ps_thinkertime - ps_lua_thinkframe_time); - V_DrawThinString(24, 42+yoffset1, V_MONOSPACE | V_YELLOWMAP, s); - - snprintf(s, sizeof s - 1, "thnkers %d", thinkercount); - V_DrawThinString(90, 10, V_MONOSPACE | V_BLUEMAP, s); - snprintf(s, sizeof s - 1, "plyobjs %d", polythcount); - V_DrawThinString(94, 18, V_MONOSPACE | V_BLUEMAP, s); - snprintf(s, sizeof s - 1, "main %d", mainthcount); - V_DrawThinString(94, 26, V_MONOSPACE | V_BLUEMAP, s); - snprintf(s, sizeof s - 1, "mobjs %d", mobjcount); - V_DrawThinString(94, 34, V_MONOSPACE | V_BLUEMAP, s); - snprintf(s, sizeof s - 1, "regular %d", mobjcount - scenerycount - nothinkcount); - V_DrawThinString(98, 42, V_MONOSPACE | V_BLUEMAP, s); - snprintf(s, sizeof s - 1, "scenery %d", scenerycount); - V_DrawThinString(98, 50, V_MONOSPACE | V_BLUEMAP, s); - if (nothinkcount) - { - snprintf(s, sizeof s - 1, "nothink %d", nothinkcount); - V_DrawThinString(98, 58, V_MONOSPACE | V_BLUEMAP, s); - yoffset2 += 8; - } - snprintf(s, sizeof s - 1, "dynslop %d", dynslopethcount); - V_DrawThinString(94, 58+yoffset2, V_MONOSPACE | V_BLUEMAP, s); - snprintf(s, sizeof s - 1, "precip %d", precipcount); - V_DrawThinString(94, 66+yoffset2, V_MONOSPACE | V_BLUEMAP, s); - snprintf(s, sizeof s - 1, "remove %d", removecount); - V_DrawThinString(94, 74+yoffset2, V_MONOSPACE | V_BLUEMAP, s); - - snprintf(s, sizeof s - 1, "lmhooks %d", ps_lua_mobjhooks); - V_DrawThinString(170, 10, V_MONOSPACE | V_PURPLEMAP, s); - snprintf(s, sizeof s - 1, "chkpos %d", ps_checkposition_calls); - V_DrawThinString(170, 18, V_MONOSPACE | V_PURPLEMAP, s); - } - else // high resolution - { - snprintf(s, sizeof s - 1, "Game logic: %d", ps_tictime); - V_DrawSmallString(20, 10, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); - if (!(gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction))) - return; - snprintf(s, sizeof s - 1, "P_PlayerThink: %d", ps_playerthink_time); - V_DrawSmallString(24, 15, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "P_RunThinkers: %d", ps_thinkertime); - V_DrawSmallString(24, 20, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); - for (i = 0; i < NUM_THINKERLISTS; i++) - { - yoffset1 += 5; - snprintf(s, sizeof s - 1, thlist_names[i], ps_thlist_times[i]); - V_DrawSmallString(28, 20+yoffset1, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); - } - snprintf(s, sizeof s - 1, "LUAh_ThinkFrame: %d", ps_lua_thinkframe_time); - V_DrawSmallString(24, 25+yoffset1, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); - snprintf(s, sizeof s - 1, "Other: %d", - ps_tictime - ps_playerthink_time - ps_thinkertime - ps_lua_thinkframe_time); - V_DrawSmallString(24, 30+yoffset1, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, s); - - snprintf(s, sizeof s - 1, "Thinkers: %d", thinkercount); - V_DrawSmallString(115, 10+yoffset2, V_MONOSPACE | V_ALLOWLOWERCASE | V_BLUEMAP, s); - snprintf(s, sizeof s - 1, "Polyobjects: %d", polythcount); - V_DrawSmallString(119, 15+yoffset2, V_MONOSPACE | V_ALLOWLOWERCASE | V_BLUEMAP, s); - snprintf(s, sizeof s - 1, "Main: %d", mainthcount); - V_DrawSmallString(119, 20+yoffset2, V_MONOSPACE | V_ALLOWLOWERCASE | V_BLUEMAP, s); - snprintf(s, sizeof s - 1, "Mobjs: %d", mobjcount); - V_DrawSmallString(119, 25+yoffset2, V_MONOSPACE | V_ALLOWLOWERCASE | V_BLUEMAP, s); - snprintf(s, sizeof s - 1, "Regular: %d", mobjcount - scenerycount - nothinkcount); - V_DrawSmallString(123, 30+yoffset2, V_MONOSPACE | V_ALLOWLOWERCASE | V_BLUEMAP, s); - snprintf(s, sizeof s - 1, "Scenery: %d", scenerycount); - V_DrawSmallString(123, 35+yoffset2, V_MONOSPACE | V_ALLOWLOWERCASE | V_BLUEMAP, s); - if (nothinkcount) - { - snprintf(s, sizeof s - 1, "Nothink: %d", nothinkcount); - V_DrawSmallString(123, 40+yoffset2, V_MONOSPACE | V_ALLOWLOWERCASE | V_BLUEMAP, s); - yoffset2 += 5; - } - snprintf(s, sizeof s - 1, "Dynamic slopes: %d", dynslopethcount); - V_DrawSmallString(119, 40+yoffset2, V_MONOSPACE | V_ALLOWLOWERCASE | V_BLUEMAP, s); - snprintf(s, sizeof s - 1, "Precipitation: %d", precipcount); - V_DrawSmallString(119, 45+yoffset2, V_MONOSPACE | V_ALLOWLOWERCASE | V_BLUEMAP, s); - snprintf(s, sizeof s - 1, "Pending removal: %d", removecount); - V_DrawSmallString(119, 50+yoffset2, V_MONOSPACE | V_ALLOWLOWERCASE | V_BLUEMAP, s); - - snprintf(s, sizeof s - 1, "Calls:"); - V_DrawSmallString(212, 10, V_MONOSPACE | V_ALLOWLOWERCASE | V_PURPLEMAP, s); - snprintf(s, sizeof s - 1, "Lua mobj hooks: %d", ps_lua_mobjhooks); - V_DrawSmallString(216, 15, V_MONOSPACE | V_ALLOWLOWERCASE | V_PURPLEMAP, s); - snprintf(s, sizeof s - 1, "P_CheckPosition: %d", ps_checkposition_calls); - V_DrawSmallString(216, 20, V_MONOSPACE | V_ALLOWLOWERCASE | V_PURPLEMAP, s); - } + M_DrawTickStats(); } else if (cv_perfstats.value == 3) // lua thinkframe { diff --git a/src/m_perfstats.h b/src/m_perfstats.h index 01a818c1c..132bea38c 100644 --- a/src/m_perfstats.h +++ b/src/m_perfstats.h @@ -16,17 +16,17 @@ #include "lua_script.h" #include "p_local.h" -extern int ps_tictime; +extern precise_t ps_tictime; -extern int ps_playerthink_time; -extern int ps_thinkertime; +extern precise_t ps_playerthink_time; +extern precise_t ps_thinkertime; -extern int ps_thlist_times[]; +extern precise_t ps_thlist_times[]; -extern int ps_checkposition_calls; +extern int ps_checkposition_calls; -extern int ps_lua_thinkframe_time; -extern int ps_lua_mobjhooks; +extern precise_t ps_lua_thinkframe_time; +extern int ps_lua_mobjhooks; typedef struct { diff --git a/src/p_tick.c b/src/p_tick.c index 451e5e626..19fdc221b 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -22,7 +22,7 @@ #include "lua_script.h" #include "lua_hook.h" #include "m_perfstats.h" -#include "i_system.h" // I_GetTimeMicros +#include "i_system.h" // I_GetPreciseTime // Object place #include "m_cheat.h" @@ -323,7 +323,7 @@ static inline void P_RunThinkers(void) size_t i; for (i = 0; i < NUM_THINKERLISTS; i++) { - ps_thlist_times[i] = I_GetTimeMicros(); + ps_thlist_times[i] = I_GetPreciseTime(); for (currentthinker = thlist[i].next; currentthinker != &thlist[i]; currentthinker = currentthinker->next) { #ifdef PARANOIA @@ -331,7 +331,7 @@ static inline void P_RunThinkers(void) #endif currentthinker->function.acp1(currentthinker); } - ps_thlist_times[i] = I_GetTimeMicros() - ps_thlist_times[i]; + ps_thlist_times[i] = I_GetPreciseTime() - ps_thlist_times[i]; } } @@ -650,11 +650,11 @@ void P_Ticker(boolean run) LUAh_PreThinkFrame(); - ps_playerthink_time = I_GetTimeMicros(); + ps_playerthink_time = I_GetPreciseTime(); for (i = 0; i < MAXPLAYERS; i++) if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo)) P_PlayerThink(&players[i]); - ps_playerthink_time = I_GetTimeMicros() - ps_playerthink_time; + ps_playerthink_time = I_GetPreciseTime() - ps_playerthink_time; } // Keep track of how long they've been playing! @@ -669,18 +669,18 @@ void P_Ticker(boolean run) if (run) { - ps_thinkertime = I_GetTimeMicros(); + ps_thinkertime = I_GetPreciseTime(); P_RunThinkers(); - ps_thinkertime = I_GetTimeMicros() - ps_thinkertime; + ps_thinkertime = I_GetPreciseTime() - ps_thinkertime; // Run any "after all the other thinkers" stuff for (i = 0; i < MAXPLAYERS; i++) if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo)) P_PlayerAfterThink(&players[i]); - ps_lua_thinkframe_time = I_GetTimeMicros(); + ps_lua_thinkframe_time = I_GetPreciseTime(); LUAh_ThinkFrame(); - ps_lua_thinkframe_time = I_GetTimeMicros() - ps_lua_thinkframe_time; + ps_lua_thinkframe_time = I_GetPreciseTime() - ps_lua_thinkframe_time; } // Run shield positioning diff --git a/src/r_main.c b/src/r_main.c index 5165b3c87..7f2dd6729 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -34,7 +34,7 @@ #include "m_random.h" // quake camera shake #include "r_portal.h" #include "r_main.h" -#include "i_system.h" // I_GetTimeMicros +#include "i_system.h" // I_GetPreciseTime #ifdef HWRENDER #include "hardware/hw_main.h" @@ -100,17 +100,17 @@ lighttable_t *zlight[LIGHTLEVELS][MAXLIGHTZ]; extracolormap_t *extra_colormaps = NULL; // Render stats -int ps_prevframetime = 0; -int ps_rendercalltime = 0; -int ps_uitime = 0; -int ps_swaptime = 0; +precise_t ps_prevframetime = 0; +precise_t ps_rendercalltime = 0; +precise_t ps_uitime = 0; +precise_t ps_swaptime = 0; -int ps_bsptime = 0; +precise_t ps_bsptime = 0; -int ps_sw_spritecliptime = 0; -int ps_sw_portaltime = 0; -int ps_sw_planetime = 0; -int ps_sw_maskedtime = 0; +precise_t ps_sw_spritecliptime = 0; +precise_t ps_sw_portaltime = 0; +precise_t ps_sw_planetime = 0; +precise_t ps_sw_maskedtime = 0; int ps_numbspcalls = 0; int ps_numsprites = 0; @@ -1491,9 +1491,9 @@ void R_RenderPlayerView(player_t *player) ProfZeroTimer(); #endif ps_numbspcalls = ps_numpolyobjects = ps_numdrawnodes = 0; - ps_bsptime = I_GetTimeMicros(); + ps_bsptime = I_GetPreciseTime(); R_RenderBSPNode((INT32)numnodes - 1); - ps_bsptime = I_GetTimeMicros() - ps_bsptime; + ps_bsptime = I_GetPreciseTime() - ps_bsptime; ps_numsprites = visspritecount; #ifdef TIMING RDMSR(0x10, &mycount); @@ -1504,9 +1504,9 @@ void R_RenderPlayerView(player_t *player) //profile stuff --------------------------------------------------------- Mask_Post(&masks[nummasks - 1]); - ps_sw_spritecliptime = I_GetTimeMicros(); + ps_sw_spritecliptime = I_GetPreciseTime(); R_ClipSprites(drawsegs, NULL); - ps_sw_spritecliptime = I_GetTimeMicros() - ps_sw_spritecliptime; + ps_sw_spritecliptime = I_GetPreciseTime() - ps_sw_spritecliptime; // Add skybox portals caused by sky visplanes. @@ -1514,7 +1514,7 @@ void R_RenderPlayerView(player_t *player) Portal_AddSkyboxPortals(); // Portal rendering. Hijacks the BSP traversal. - ps_sw_portaltime = I_GetTimeMicros(); + ps_sw_portaltime = I_GetPreciseTime(); if (portal_base) { portal_t *portal; @@ -1554,20 +1554,20 @@ void R_RenderPlayerView(player_t *player) Portal_Remove(portal); } } - ps_sw_portaltime = I_GetTimeMicros() - ps_sw_portaltime; + ps_sw_portaltime = I_GetPreciseTime() - ps_sw_portaltime; - ps_sw_planetime = I_GetTimeMicros(); + ps_sw_planetime = I_GetPreciseTime(); R_DrawPlanes(); #ifdef FLOORSPLATS R_DrawVisibleFloorSplats(); #endif - ps_sw_planetime = I_GetTimeMicros() - ps_sw_planetime; + ps_sw_planetime = I_GetPreciseTime() - ps_sw_planetime; // draw mid texture and sprite // And now 3D floors/sides! - ps_sw_maskedtime = I_GetTimeMicros(); + ps_sw_maskedtime = I_GetPreciseTime(); R_DrawMasked(masks, nummasks); - ps_sw_maskedtime = I_GetTimeMicros() - ps_sw_maskedtime; + ps_sw_maskedtime = I_GetPreciseTime() - ps_sw_maskedtime; free(masks); } diff --git a/src/r_main.h b/src/r_main.h index 379b5b8df..eb3d0eedd 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -78,17 +78,17 @@ boolean R_DoCulling(line_t *cullheight, line_t *viewcullheight, fixed_t vz, fixe // Render stats -extern int ps_prevframetime;// time when previous frame was rendered -extern int ps_rendercalltime; -extern int ps_uitime; -extern int ps_swaptime; +extern precise_t ps_prevframetime;// time when previous frame was rendered +extern precise_t ps_rendercalltime; +extern precise_t ps_uitime; +extern precise_t ps_swaptime; -extern int ps_bsptime; +extern precise_t ps_bsptime; -extern int ps_sw_spritecliptime; -extern int ps_sw_portaltime; -extern int ps_sw_planetime; -extern int ps_sw_maskedtime; +extern precise_t ps_sw_spritecliptime; +extern precise_t ps_sw_portaltime; +extern precise_t ps_sw_planetime; +extern precise_t ps_sw_maskedtime; extern int ps_numbspcalls; extern int ps_numsprites; From 515d7eeb9ea6cd84afffc6e0b93e63bbf3d7635f Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 7 Nov 2020 01:54:54 -0800 Subject: [PATCH 034/644] Let's try an experiment: move the epoch forward as I_GetTime is called This will make it even longer until time wraps around. Have you ever run a srb2 server for 4 years straight? --- src/sdl/i_system.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 8a70847e1..d4ef86c5a 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -2044,12 +2044,20 @@ ticcmd_t *I_BaseTiccmd2(void) // static Uint64 timer_frequency; + +static double tic_frequency; static Uint64 tic_epoch; tic_t I_GetTime(void) { + static double elapsed; + const Uint64 now = SDL_GetPerformanceCounter(); - return (now - tic_epoch) * NEWTICRATE / timer_frequency; + + elapsed += (now - tic_epoch) / tic_frequency; + tic_epoch = now; // moving epoch + + return (tic_t)elapsed; } precise_t I_GetPreciseTime(void) @@ -2069,6 +2077,8 @@ void I_StartupTimer(void) { timer_frequency = SDL_GetPerformanceFrequency(); tic_epoch = SDL_GetPerformanceCounter(); + + tic_frequency = timer_frequency / NEWTICRATE; } void I_Sleep(void) From c0dbc562bb186069558bc44dd619d85f41323c4c Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 7 Nov 2020 13:48:37 -0800 Subject: [PATCH 035/644] Fix floating point math --- src/sdl/i_system.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index d4ef86c5a..d2c819c37 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -2067,7 +2067,7 @@ precise_t I_GetPreciseTime(void) int I_PreciseToMicros(precise_t d) { - return d / (timer_frequency / 1000000); + return (int)(d / (timer_frequency / 1000000.0)); } // @@ -2078,7 +2078,7 @@ void I_StartupTimer(void) timer_frequency = SDL_GetPerformanceFrequency(); tic_epoch = SDL_GetPerformanceCounter(); - tic_frequency = timer_frequency / NEWTICRATE; + tic_frequency = timer_frequency / (double)NEWTICRATE; } void I_Sleep(void) From 1320f10839cb28d3fe5363a4feeee1cdd6fbb149 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Sat, 7 Nov 2020 23:53:46 -0500 Subject: [PATCH 036/644] Allow access to skin.sprites[] Only numframes so far though, as there's already a function for what spriteframe provides. --- src/lua_baselib.c | 2 ++ src/lua_libs.h | 2 ++ src/lua_skinlib.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 66 insertions(+), 1 deletion(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 132ebc1a8..ab074c8ad 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -162,6 +162,8 @@ static const struct { {META_SKIN, "skin_t"}, {META_POWERS, "player_t.powers"}, {META_SOUNDSID, "skin_t.soundsid"}, + {META_SKINSPRITES, "skin_t.sprites"}, + {META_SKINSPRITESLIST, "skin_t.sprites[]"}, {META_VERTEX, "vertex_t"}, {META_LINE, "line_t"}, diff --git a/src/lua_libs.h b/src/lua_libs.h index 03bd99cd2..82fdccf10 100644 --- a/src/lua_libs.h +++ b/src/lua_libs.h @@ -34,6 +34,8 @@ extern lua_State *gL; #define META_SKIN "SKIN_T*" #define META_POWERS "PLAYER_T*POWERS" #define META_SOUNDSID "SKIN_T*SOUNDSID" +#define META_SKINSPRITES "SKIN_T*SPRITES" +#define META_SKINSPRITESLIST "SKIN_T*SPRITES[]" #define META_VERTEX "VERTEX_T*" #define META_LINE "LINE_T*" diff --git a/src/lua_skinlib.c b/src/lua_skinlib.c index 3e4ddb9f0..1cd9df631 100644 --- a/src/lua_skinlib.c +++ b/src/lua_skinlib.c @@ -54,7 +54,8 @@ enum skin { skin_contspeed, skin_contangle, skin_soundsid, - skin_availability + skin_availability, + skin_sprites }; static const char *const skin_opt[] = { "valid", @@ -93,6 +94,7 @@ static const char *const skin_opt[] = { "contangle", "soundsid", "availability", + "sprites", NULL}; #define UNIMPLEMENTED luaL_error(L, LUA_QL("skin_t") " field " LUA_QS " is not implemented for Lua and cannot be accessed.", skin_opt[field]) @@ -214,6 +216,9 @@ static int skin_get(lua_State *L) case skin_availability: lua_pushinteger(L, skin->availability); break; + case skin_sprites: + LUA_PushUserdata(L, skin->sprites, META_SKINSPRITES); + break; } return 1; } @@ -324,6 +329,49 @@ static int soundsid_num(lua_State *L) return 1; } +enum spritesopt { + numframes = 0 +}; + +static const char *const sprites_opt[] = { + "numframes", + NULL}; + +// skin.sprites[i] -> sprites[i] +static int lib_getSkinSprite(lua_State *L) +{ + spritedef_t *sprites = *((spritedef_t **)luaL_checkudata(L, 1, META_SKINSPRITES)); + playersprite_t i = luaL_checkinteger(L, 2); + + if (i < 0 || i >= NUMPLAYERSPRITES*2) + return luaL_error(L, "skin.sprites[] index %d out of range (0 - %d)", i, (NUMPLAYERSPRITES*2)-1); + + LUA_PushLightUserdata(L, &sprites[i], META_SKINSPRITESLIST); + return 1; +} + +// #skin.sprites -> NUMPLAYERSPRITES*2 +static int lib_numSkinsSprites(lua_State *L) +{ + lua_pushinteger(L, NUMPLAYERSPRITES*2); + return 1; +} + +static int sprite_get(lua_State *L) +{ + spritedef_t *sprite = (spritedef_t *)luaL_checkudata(L, 1, META_SKINSPRITESLIST); + enum spritesopt field = luaL_checkoption(L, 2, NULL, sprites_opt); + + switch (field) + { + case numframes: + lua_pushinteger(L, sprite->numframes); + break; + } + return 1; +} + + int LUA_SkinLib(lua_State *L) { luaL_newmetatable(L, META_SKIN); @@ -345,6 +393,19 @@ int LUA_SkinLib(lua_State *L) lua_setfield(L, -2, "__len"); lua_pop(L,1); + luaL_newmetatable(L, META_SKINSPRITES); + lua_pushcfunction(L, lib_getSkinSprite); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, lib_numSkinsSprites); + lua_setfield(L, -2, "__len"); + lua_pop(L,1); + + luaL_newmetatable(L, META_SKINSPRITESLIST); + lua_pushcfunction(L, sprite_get); + lua_setfield(L, -2, "__index"); + lua_pop(L,1); + lua_newuserdata(L, 0); lua_createtable(L, 0, 2); lua_pushcfunction(L, lib_getSkin); From 83a87042f1e76c8b378b188e9389830e50de0e3d Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Sun, 8 Nov 2020 13:25:56 -0500 Subject: [PATCH 037/644] Push skin->sprites as light userdata --- src/lua_skinlib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lua_skinlib.c b/src/lua_skinlib.c index 1cd9df631..d4d7bae12 100644 --- a/src/lua_skinlib.c +++ b/src/lua_skinlib.c @@ -217,7 +217,7 @@ static int skin_get(lua_State *L) lua_pushinteger(L, skin->availability); break; case skin_sprites: - LUA_PushUserdata(L, skin->sprites, META_SKINSPRITES); + LUA_PushLightUserdata(L, skin->sprites, META_SKINSPRITES); break; } return 1; @@ -340,7 +340,7 @@ static const char *const sprites_opt[] = { // skin.sprites[i] -> sprites[i] static int lib_getSkinSprite(lua_State *L) { - spritedef_t *sprites = *((spritedef_t **)luaL_checkudata(L, 1, META_SKINSPRITES)); + spritedef_t *sprites = (spritedef_t *)luaL_checkudata(L, 1, META_SKINSPRITES); playersprite_t i = luaL_checkinteger(L, 2); if (i < 0 || i >= NUMPLAYERSPRITES*2) From d26172661d6fac5720950c93365609dcf009cc68 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Sun, 8 Nov 2020 13:31:59 -0500 Subject: [PATCH 038/644] Remove spritedef field --- src/lua_skinlib.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/lua_skinlib.c b/src/lua_skinlib.c index d4d7bae12..e2f16756a 100644 --- a/src/lua_skinlib.c +++ b/src/lua_skinlib.c @@ -21,7 +21,6 @@ enum skin { skin_valid = 0, skin_name, - skin_spritedef, skin_wadnum, skin_flags, skin_realname, @@ -60,7 +59,6 @@ enum skin { static const char *const skin_opt[] = { "valid", "name", - "spritedef", "wadnum", "flags", "realname", @@ -115,8 +113,6 @@ static int skin_get(lua_State *L) case skin_name: lua_pushstring(L, skin->name); break; - case skin_spritedef: - return UNIMPLEMENTED; case skin_wadnum: // !!WARNING!! May differ between clients due to music wads, therefore NOT NETWORK SAFE return UNIMPLEMENTED; From 365255990d7454dac7d345bdc719a9c64573c0f3 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Thu, 12 Nov 2020 21:25:31 +0100 Subject: [PATCH 039/644] Add shorthand aliases for fixed-point functions --- src/lua_mathlib.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/lua_mathlib.c b/src/lua_mathlib.c index 7cbe7a6cc..10ba42ee0 100644 --- a/src/lua_mathlib.c +++ b/src/lua_mathlib.c @@ -192,18 +192,30 @@ static luaL_Reg lib[] = { {"cos", lib_finecosine}, {"tan", lib_finetangent}, {"FixedAngle", lib_fixedangle}, + {"fixangle" , lib_fixedangle}, {"AngleFixed", lib_anglefixed}, + {"anglefix" , lib_anglefixed}, {"InvAngle", lib_invangle}, {"FixedMul", lib_fixedmul}, + {"fixmul" , lib_fixedmul}, {"FixedInt", lib_fixedint}, + {"fixint" , lib_fixedint}, {"FixedDiv", lib_fixeddiv}, + {"fixdiv" , lib_fixeddiv}, {"FixedRem", lib_fixedrem}, + {"fixrem" , lib_fixedrem}, {"FixedSqrt", lib_fixedsqrt}, + {"fixsqrt" , lib_fixedsqrt}, {"FixedHypot", lib_fixedhypot}, + {"fixhypot" , lib_fixedhypot}, {"FixedFloor", lib_fixedfloor}, + {"fixfloor" , lib_fixedfloor}, {"FixedTrunc", lib_fixedtrunc}, + {"fixtrunc" , lib_fixedtrunc}, {"FixedCeil", lib_fixedceil}, + {"fixceil" , lib_fixedceil}, {"FixedRound", lib_fixedround}, + {"fixround" , lib_fixedround}, {"GetSecSpecial", lib_getsecspecial}, {"All7Emeralds", lib_all7emeralds}, {"ColorOpposite", lib_coloropposite}, From 3d1677bade6b46e2973b3df9e90cb962994d09f7 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Thu, 12 Nov 2020 21:33:47 +0100 Subject: [PATCH 040/644] Add a shorthand alias for FRACUNIT --- src/dehacked.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dehacked.c b/src/dehacked.c index 0380cc30e..86c09d03a 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -9511,6 +9511,7 @@ struct { // fixed_t constants, from m_fixed.h {"FRACUNIT",FRACUNIT}, + {"FU" ,FRACUNIT}, {"FRACBITS",FRACBITS}, // doomdef.h constants From a38a6a9dc0463ba255e2d014e2e81a1fb8cfa137 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 13 Nov 2020 20:49:18 +0000 Subject: [PATCH 041/644] Split off actual skin-setting code from SetPlayerSkinByNum so that both SetPlayerSkin and SetPlayerSkinByNum can call it, rather than to each other --- src/r_skins.c | 160 ++++++++++++++++++++++++++------------------------ 1 file changed, 84 insertions(+), 76 deletions(-) diff --git a/src/r_skins.c b/src/r_skins.c index 25904e95e..dab282d26 100644 --- a/src/r_skins.c +++ b/src/r_skins.c @@ -216,6 +216,85 @@ INT32 R_SkinAvailable(const char *name) return -1; } +// Auxillary function that actually sets the skin +static void SetSkin(player_t *player, INT32 skinnum) +{ + skin_t *skin = &skins[skinnum]; + UINT16 newcolor = 0; + + player->skin = skinnum; + + player->camerascale = skin->camerascale; + player->shieldscale = skin->shieldscale; + + player->charability = (UINT8)skin->ability; + player->charability2 = (UINT8)skin->ability2; + + player->charflags = (UINT32)skin->flags; + + player->thokitem = skin->thokitem < 0 ? (UINT32)mobjinfo[MT_PLAYER].painchance : (UINT32)skin->thokitem; + player->spinitem = skin->spinitem < 0 ? (UINT32)mobjinfo[MT_PLAYER].damage : (UINT32)skin->spinitem; + player->revitem = skin->revitem < 0 ? (mobjtype_t)mobjinfo[MT_PLAYER].raisestate : (UINT32)skin->revitem; + player->followitem = skin->followitem; + + if (((player->powers[pw_shield] & SH_NOSTACK) == SH_PINK) && (player->revitem == MT_LHRT || player->spinitem == MT_LHRT || player->thokitem == MT_LHRT)) // Healers can't keep their buff. + player->powers[pw_shield] &= SH_STACK; + + player->actionspd = skin->actionspd; + player->mindash = skin->mindash; + player->maxdash = skin->maxdash; + + player->normalspeed = skin->normalspeed; + player->runspeed = skin->runspeed; + player->thrustfactor = skin->thrustfactor; + player->accelstart = skin->accelstart; + player->acceleration = skin->acceleration; + + player->jumpfactor = skin->jumpfactor; + + player->height = skin->height; + player->spinheight = skin->spinheight; + + if (!(cv_debug || devparm) && !(netgame || multiplayer || demoplayback)) + { + if (player == &players[consoleplayer]) + CV_StealthSetValue(&cv_playercolor, skin->prefcolor); + else if (player == &players[secondarydisplayplayer]) + CV_StealthSetValue(&cv_playercolor2, skin->prefcolor); + player->skincolor = newcolor = skin->prefcolor; + if (player->bot && botingame) + { + botskin = (UINT8)(skinnum + 1); + botcolor = skin->prefcolor; + } + } + + if (player->followmobj) + { + P_RemoveMobj(player->followmobj); + P_SetTarget(&player->followmobj, NULL); + } + + if (player->mo) + { + fixed_t radius = FixedMul(skin->radius, player->mo->scale); + if ((player->powers[pw_carry] == CR_NIGHTSMODE) && (skin->sprites[SPR2_NFLY].numframes == 0)) // If you don't have a sprite for flying horizontally, use the default NiGHTS skin. + { + skin = &skins[DEFAULTNIGHTSSKIN]; + player->followitem = skin->followitem; + if (!(cv_debug || devparm) && !(netgame || multiplayer || demoplayback)) + newcolor = skin->prefcolor; // will be updated in thinker to flashing + } + player->mo->skin = skin; + if (newcolor) + player->mo->color = newcolor; + P_SetScale(player->mo, player->mo->scale); + player->mo->radius = radius; + + P_SetPlayerMobjState(player->mo, player->mo->state-states); // Prevent visual errors when switching between skins with differing number of frames + } +} + // network code calls this when a 'skin change' is received void SetPlayerSkin(INT32 playernum, const char *skinname) { @@ -224,7 +303,7 @@ void SetPlayerSkin(INT32 playernum, const char *skinname) if ((i != -1) && R_SkinUsable(playernum, i)) { - SetPlayerSkinByNum(playernum, i); + SetSkin(playernum, i); return; } @@ -233,7 +312,7 @@ void SetPlayerSkin(INT32 playernum, const char *skinname) else if(server || IsPlayerAdmin(consoleplayer)) CONS_Alert(CONS_WARNING, M_GetText("Player %d (%s) skin '%s' not found\n"), playernum, player_names[playernum], skinname); - SetPlayerSkinByNum(playernum, 0); + SetSkin(player, 0); } // Same as SetPlayerSkin, but uses the skin #. @@ -241,82 +320,10 @@ void SetPlayerSkin(INT32 playernum, const char *skinname) void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum) { player_t *player = &players[playernum]; - skin_t *skin = &skins[skinnum]; - UINT16 newcolor = 0; if (skinnum >= 0 && skinnum < numskins && R_SkinUsable(playernum, skinnum)) // Make sure it exists! { - player->skin = skinnum; - - player->camerascale = skin->camerascale; - player->shieldscale = skin->shieldscale; - - player->charability = (UINT8)skin->ability; - player->charability2 = (UINT8)skin->ability2; - - player->charflags = (UINT32)skin->flags; - - player->thokitem = skin->thokitem < 0 ? (UINT32)mobjinfo[MT_PLAYER].painchance : (UINT32)skin->thokitem; - player->spinitem = skin->spinitem < 0 ? (UINT32)mobjinfo[MT_PLAYER].damage : (UINT32)skin->spinitem; - player->revitem = skin->revitem < 0 ? (mobjtype_t)mobjinfo[MT_PLAYER].raisestate : (UINT32)skin->revitem; - player->followitem = skin->followitem; - - if (((player->powers[pw_shield] & SH_NOSTACK) == SH_PINK) && (player->revitem == MT_LHRT || player->spinitem == MT_LHRT || player->thokitem == MT_LHRT)) // Healers can't keep their buff. - player->powers[pw_shield] &= SH_STACK; - - player->actionspd = skin->actionspd; - player->mindash = skin->mindash; - player->maxdash = skin->maxdash; - - player->normalspeed = skin->normalspeed; - player->runspeed = skin->runspeed; - player->thrustfactor = skin->thrustfactor; - player->accelstart = skin->accelstart; - player->acceleration = skin->acceleration; - - player->jumpfactor = skin->jumpfactor; - - player->height = skin->height; - player->spinheight = skin->spinheight; - - if (!(cv_debug || devparm) && !(netgame || multiplayer || demoplayback)) - { - if (playernum == consoleplayer) - CV_StealthSetValue(&cv_playercolor, skin->prefcolor); - else if (playernum == secondarydisplayplayer) - CV_StealthSetValue(&cv_playercolor2, skin->prefcolor); - player->skincolor = newcolor = skin->prefcolor; - if (player->bot && botingame) - { - botskin = (UINT8)(skinnum + 1); - botcolor = skin->prefcolor; - } - } - - if (player->followmobj) - { - P_RemoveMobj(player->followmobj); - P_SetTarget(&player->followmobj, NULL); - } - - if (player->mo) - { - fixed_t radius = FixedMul(skin->radius, player->mo->scale); - if ((player->powers[pw_carry] == CR_NIGHTSMODE) && (skin->sprites[SPR2_NFLY].numframes == 0)) // If you don't have a sprite for flying horizontally, use the default NiGHTS skin. - { - skin = &skins[DEFAULTNIGHTSSKIN]; - player->followitem = skin->followitem; - if (!(cv_debug || devparm) && !(netgame || multiplayer || demoplayback)) - newcolor = skin->prefcolor; // will be updated in thinker to flashing - } - player->mo->skin = skin; - if (newcolor) - player->mo->color = newcolor; - P_SetScale(player->mo, player->mo->scale); - player->mo->radius = radius; - - P_SetPlayerMobjState(player->mo, player->mo->state-states); // Prevent visual errors when switching between skins with differing number of frames - } + SetSkin(player, skinnum); return; } @@ -324,7 +331,8 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum) CONS_Alert(CONS_WARNING, M_GetText("Requested skin %d not found\n"), skinnum); else if(server || IsPlayerAdmin(consoleplayer)) CONS_Alert(CONS_WARNING, "Player %d (%s) skin %d not found\n", playernum, player_names[playernum], skinnum); - SetPlayerSkinByNum(playernum, 0); // not found put the sonic skin + + SetSkin(player, 0); // not found put the sonic skin } // From 8814980a06acfcc1493b20828a5671594f9bc2e4 Mon Sep 17 00:00:00 2001 From: Riku Salminen <38985578+Riku-S@users.noreply.github.com> Date: Sat, 14 Nov 2020 19:18:36 +0200 Subject: [PATCH 042/644] Emeralds and tokens now reset when restarting marathon mode in first level --- src/g_game.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/g_game.c b/src/g_game.c index 228295b62..528721e2f 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2218,6 +2218,10 @@ void G_Ticker(boolean run) { marathonmode |= MA_INIT; marathontime = 0; + + tokenlist = 0; + token = 0; + emeralds = 0; } else if (G_GametypeUsesLives() && players[consoleplayer].playerstate == PST_LIVE && players[consoleplayer].lives != INFLIVES) players[consoleplayer].lives -= 1; From 0a1beab8c80591a90107017b0d0712f74ecba720 Mon Sep 17 00:00:00 2001 From: Riku Salminen <38985578+Riku-S@users.noreply.github.com> Date: Sat, 14 Nov 2020 20:17:35 +0200 Subject: [PATCH 043/644] Reset a couple of other variables while we're at it --- src/g_game.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 528721e2f..d6861b252 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2216,12 +2216,32 @@ void G_Ticker(boolean run) // Costs a life to retry ... unless the player in question is dead already, or you haven't even touched the first starpost in marathon run. if (marathonmode && gamemap == spmarathon_start && !players[consoleplayer].starposttime) { + player_t *p = &players[consoleplayer]; marathonmode |= MA_INIT; marathontime = 0; - tokenlist = 0; - token = 0; - emeralds = 0; + numgameovers = tokenlist = token = 0; + countdown = countdown2 = exitfadestarted = 0; + + p->playerstate = PST_REBORN; + p->starpostx = p->starposty = p->starpostz = 0; + + p->lives = startinglivesbalance[0]; + p->continues = 1; + + p->score = 0; + + // The latter two should clear by themselves, but just in case + p->pflags &= ~(PF_TAGIT|PF_GAMETYPEOVER|PF_FULLSTASIS); + + // Clear cheatcodes too, just in case. + p->pflags &= ~(PF_GODMODE|PF_NOCLIP|PF_INVIS); + + p->xtralife = 0; + + // Reset unlockable triggers + unlocktriggers = 0; + } else if (G_GametypeUsesLives() && players[consoleplayer].playerstate == PST_LIVE && players[consoleplayer].lives != INFLIVES) players[consoleplayer].lives -= 1; From fb40a2836597f3aa751f0ac68aab2a87b93ecf02 Mon Sep 17 00:00:00 2001 From: SMS Alfredo <65426124+SMS-Alfredo@users.noreply.github.com> Date: Tue, 17 Nov 2020 11:47:33 -0600 Subject: [PATCH 044/644] Do deh thing --- src/p_user.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/p_user.c b/src/p_user.c index 10b7e970e..a9194fbb2 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -4524,6 +4524,7 @@ void P_DoJump(player_t *player, boolean soundandstate) player->mo->eflags &= ~MFE_APPLYPMOMZ; player->pflags |= P_GetJumpFlags(player);; + player->pflags &= ~PF_SPINNING; if (soundandstate) { From ad9bf6085f0845c9fde5348c7299136735a83d84 Mon Sep 17 00:00:00 2001 From: SMS Alfredo <65426124+SMS-Alfredo@users.noreply.github.com> Date: Wed, 18 Nov 2020 11:28:31 -0600 Subject: [PATCH 045/644] Fix no spin characters being able to damage enemies with their jump out of a spin without removing PF_SPINNING --- src/p_user.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index a9194fbb2..c1b11965b 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1135,7 +1135,8 @@ boolean P_PlayerCanDamage(player_t *player, mobj_t *thing) return true; // Spinning. - if (player->pflags & PF_SPINNING) + if ((player->pflags & PF_SPINNING) + && !((player->pflags & PF_JUMPED) && (player->pflags & PF_NOJUMPDAMAGE))) return true; if (player->dashmode >= DASHMODE_THRESHOLD && (player->charflags & (SF_DASHMODE|SF_MACHINE)) == (SF_DASHMODE|SF_MACHINE)) @@ -4524,7 +4525,6 @@ void P_DoJump(player_t *player, boolean soundandstate) player->mo->eflags &= ~MFE_APPLYPMOMZ; player->pflags |= P_GetJumpFlags(player);; - player->pflags &= ~PF_SPINNING; if (soundandstate) { From 16fd754a398901eb403faff323adbe646451fa36 Mon Sep 17 00:00:00 2001 From: SMS Alfredo <65426124+SMS-Alfredo@users.noreply.github.com> Date: Wed, 18 Nov 2020 11:49:17 -0600 Subject: [PATCH 046/644] Allow forcespin sectors to work on no spin characters --- src/p_spec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index a1afdd00d..99a0a0994 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4503,7 +4503,7 @@ DoneSection2: P_InstaThrust(player->mo, player->mo->angle, linespeed); - if ((lines[i].flags & ML_EFFECT5) && (player->charability2 == CA2_SPINDASH)) // Roll! + if (lines[i].flags & ML_EFFECT5) // Roll! { if (!(player->pflags & PF_SPINNING)) player->pflags |= PF_SPINNING; @@ -4669,7 +4669,7 @@ DoneSection2: break; case 7: // Make player spin - if (!(player->pflags & PF_SPINNING) && P_IsObjectOnGround(player->mo) && (player->charability2 == CA2_SPINDASH)) + if (!(player->pflags & PF_SPINNING) && P_IsObjectOnGround(player->mo)) { player->pflags |= PF_SPINNING; P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); From 09644d69c084484762995f27ef3598ef383aa297 Mon Sep 17 00:00:00 2001 From: SMS Alfredo <65426124+SMS-Alfredo@users.noreply.github.com> Date: Wed, 18 Nov 2020 12:01:06 -0600 Subject: [PATCH 047/644] Don't force S_PLAY_SPIN when landing with PF_SPINNING if you have certain PA flags --- src/p_user.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index c1b11965b..9f5484105 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2330,7 +2330,8 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff) P_MobjCheckWater(player->mo); if (player->pflags & PF_SPINNING) { - if (player->mo->state-states != S_PLAY_ROLL && !(player->pflags & PF_STARTDASH)) + if (player->mo->state-states != S_PLAY_ROLL && !(player->pflags & PF_STARTDASH) && player->panim != PA_ROLL + && player->panim != PA_ETC && player->panim != PA_ABILITY && player->panim != PA_ABILITY2) { P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); S_StartSound(player->mo, sfx_spin); From 01a03a4daa330958ef4633691e4d150379e0d803 Mon Sep 17 00:00:00 2001 From: SMS Alfredo <65426124+SMS-Alfredo@users.noreply.github.com> Date: Wed, 18 Nov 2020 12:03:48 -0600 Subject: [PATCH 048/644] lmao formatting --- src/p_user.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 9f5484105..004ff71d1 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2330,8 +2330,9 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff) P_MobjCheckWater(player->mo); if (player->pflags & PF_SPINNING) { - if (player->mo->state-states != S_PLAY_ROLL && !(player->pflags & PF_STARTDASH) && player->panim != PA_ROLL - && player->panim != PA_ETC && player->panim != PA_ABILITY && player->panim != PA_ABILITY2) + if (player->mo->state-states != S_PLAY_ROLL && !(player->pflags & PF_STARTDASH) + && player->panim != PA_ROLL && player->panim != PA_ETC + && player->panim != PA_ABILITY && player->panim != PA_ABILITY2) { P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); S_StartSound(player->mo, sfx_spin); From 7ad8aa14770d923ac3501e44af4eff4ea7cd802e Mon Sep 17 00:00:00 2001 From: SMS Alfredo <65426124+SMS-Alfredo@users.noreply.github.com> Date: Wed, 18 Nov 2020 12:27:09 -0600 Subject: [PATCH 049/644] Allow the Forcespin sector type to be used with intangible fofs Didn't think simply removing the P_IsObjectOnGround was gonna work, but apparently it does. --- src/p_spec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_spec.c b/src/p_spec.c index 99a0a0994..9e0203619 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4669,7 +4669,7 @@ DoneSection2: break; case 7: // Make player spin - if (!(player->pflags & PF_SPINNING) && P_IsObjectOnGround(player->mo)) + if (!(player->pflags & PF_SPINNING)) { player->pflags |= PF_SPINNING; P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); From 9163e7309227965894719d1bd08d1f68a1c9c08c Mon Sep 17 00:00:00 2001 From: SMS Alfredo <65426124+SMS-Alfredo@users.noreply.github.com> Date: Wed, 18 Nov 2020 12:35:40 -0600 Subject: [PATCH 050/644] Allow no spin characters to water skip while spinning --- src/p_mobj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 4fc561b20..004207a07 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -3393,7 +3393,7 @@ void P_MobjCheckWater(mobj_t *mobj) } // skipping stone! - if (p && (p->charability2 == CA2_SPINDASH) && p->speed/2 > abs(mobj->momz) + if (p && p->speed/2 > abs(mobj->momz) && ((p->pflags & (PF_SPINNING|PF_JUMPED)) == PF_SPINNING) && ((!(mobj->eflags & MFE_VERTICALFLIP) && thingtop - mobj->momz > mobj->watertop) || ((mobj->eflags & MFE_VERTICALFLIP) && mobj->z - mobj->momz < mobj->waterbottom))) From 949c0c181d49cdead1ab094f1635caf10715c41e Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Thu, 15 Oct 2020 10:54:18 -0500 Subject: [PATCH 051/644] Add aPNG downscaling, and its associated consvar. --- src/d_netcmd.c | 1 + src/m_misc.c | 36 +++++++++++++++++++++++++++++------- src/m_misc.h | 2 +- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 87abd596a..0fc5c78c1 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -669,6 +669,7 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_zlib_strategya); CV_RegisterVar(&cv_zlib_window_bitsa); CV_RegisterVar(&cv_apng_delay); + CV_RegisterVar(&cv_apng_downscale); // GIF variables CV_RegisterVar(&cv_gif_optimize); CV_RegisterVar(&cv_gif_downscale); diff --git a/src/m_misc.c b/src/m_misc.c index d97d8f94b..ad2d133ab 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -163,6 +163,9 @@ consvar_t cv_zlib_levela = CVAR_INIT ("apng_compress_level", "4", CV_SAVE, zlib_ consvar_t cv_zlib_strategya = CVAR_INIT ("apng_strategy", "RLE", CV_SAVE, zlib_strategy_t, NULL); consvar_t cv_zlib_window_bitsa = CVAR_INIT ("apng_window_size", "32k", CV_SAVE, zlib_window_bits_t, NULL); consvar_t cv_apng_delay = CVAR_INIT ("apng_speed", "1x", CV_SAVE, apng_delay_t, NULL); +consvar_t cv_apng_downscale = CVAR_INIT ("apng_downscale", "On", CV_SAVE, CV_OnOff, NULL); + +static boolean apng_downscale = false; // So nobody can do something dumb like changing cvars mid output boolean takescreenshot = false; // Take a screenshot this tic @@ -981,25 +984,38 @@ static inline boolean M_PNGLib(void) static void M_PNGFrame(png_structp png_ptr, png_infop png_info_ptr, png_bytep png_buf) { + png_uint_16 downscale = apng_downscale ? vid.dupx : 1; + png_uint_32 pitch = png_get_rowbytes(png_ptr, png_info_ptr); - PNG_CONST png_uint_32 height = vid.height; - png_bytepp row_pointers = png_malloc(png_ptr, height* sizeof (png_bytep)); - png_uint_32 y; + PNG_CONST png_uint_32 width = vid.width / downscale; + PNG_CONST png_uint_32 height = vid.height / downscale; + png_bytepp row_pointers = png_malloc(png_ptr, height * sizeof (png_bytep)); + png_uint_32 x, y; png_uint_16 framedelay = (png_uint_16)cv_apng_delay.value; apng_frames++; for (y = 0; y < height; y++) { - row_pointers[y] = png_buf; - png_buf += pitch; + row_pointers[y] = malloc(pitch * sizeof(png_byte)); + for (x = 0; x < width; x++) + row_pointers[y][x] = png_buf[x * downscale]; + png_buf += pitch * (downscale * downscale); } + //for (x = 0; x < width; x++) + //{ + // printf("%d", x); + // row_pointers[y][x] = 0; + //} + /* row_pointers[y] = calloc(1, sizeof(png_bytep)); + png_buf += pitch * 2; + }*/ #ifndef PNG_STATIC if (aPNG_write_frame_head) #endif aPNG_write_frame_head(apng_ptr, apng_info_ptr, row_pointers, - vid.width, /* width */ + width, /* width */ height, /* height */ 0, /* x offset */ 0, /* y offset */ @@ -1030,6 +1046,12 @@ static void M_PNGfix_acTL(png_structp png_ptr, png_infop png_info_ptr, static boolean M_SetupaPNG(png_const_charp filename, png_bytep pal) { + png_uint_16 downscale; + + apng_downscale = (!!cv_apng_downscale.value); + + downscale = apng_downscale ? vid.dupx : 1; + apng_FILE = fopen(filename,"wb+"); // + mode for reading if (!apng_FILE) { @@ -1080,7 +1102,7 @@ static boolean M_SetupaPNG(png_const_charp filename, png_bytep pal) png_set_compression_strategy(apng_ptr, cv_zlib_strategya.value); png_set_compression_window_bits(apng_ptr, cv_zlib_window_bitsa.value); - M_PNGhdr(apng_ptr, apng_info_ptr, vid.width, vid.height, pal); + M_PNGhdr(apng_ptr, apng_info_ptr, vid.width / downscale, vid.height / downscale, pal); M_PNGText(apng_ptr, apng_info_ptr, true); diff --git a/src/m_misc.h b/src/m_misc.h index dbded37d0..c5ef9f9f2 100644 --- a/src/m_misc.h +++ b/src/m_misc.h @@ -33,7 +33,7 @@ extern consvar_t cv_screenshot_option, cv_screenshot_folder, cv_screenshot_color extern consvar_t cv_moviemode, cv_movie_folder, cv_movie_option; extern consvar_t cv_zlib_memory, cv_zlib_level, cv_zlib_strategy, cv_zlib_window_bits; extern consvar_t cv_zlib_memorya, cv_zlib_levela, cv_zlib_strategya, cv_zlib_window_bitsa; -extern consvar_t cv_apng_delay; +extern consvar_t cv_apng_delay, cv_apng_downscale; void M_StartMovie(void); void M_SaveFrame(void); From 12ac096a950d953cb3cb115061662b4f5461d06f Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Thu, 15 Oct 2020 11:00:34 -0500 Subject: [PATCH 052/644] Add a menu option for aPNG downscaling. --- src/m_menu.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 5860f00ca..ffd5c6510 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1551,18 +1551,19 @@ static menuitem_t OP_ScreenshotOptionsMenu[] = {IT_STRING|IT_CVAR, NULL, "Window Size", &cv_zlib_window_bits, 57}, {IT_HEADER, NULL, "Movie Mode (F9)", NULL, 64}, - {IT_STRING|IT_CVAR, NULL, "Storage Location", &cv_movie_option, 70}, - {IT_STRING|IT_CVAR|IT_CV_STRING, NULL, "Custom Folder", &cv_movie_folder, 75}, - {IT_STRING|IT_CVAR, NULL, "Capture Mode", &cv_moviemode, 90}, + {IT_STRING|IT_CVAR, NULL, "Storage Location", &cv_movie_option, 70}, + {IT_STRING|IT_CVAR|IT_CV_STRING, NULL, "Custom Folder", &cv_movie_folder, 75}, + {IT_STRING|IT_CVAR, NULL, "Capture Mode", &cv_moviemode, 90}, - {IT_STRING|IT_CVAR, NULL, "Region Optimizing", &cv_gif_optimize, 95}, + {IT_STRING|IT_CVAR, NULL, "Region Optimizing", &cv_gif_optimize, 95}, {IT_STRING|IT_CVAR, NULL, "Downscaling", &cv_gif_downscale, 100}, {IT_STRING|IT_CVAR, NULL, "Local Color Table", &cv_gif_localcolortable, 105}, - {IT_STRING|IT_CVAR, NULL, "Memory Level", &cv_zlib_memorya, 95}, - {IT_STRING|IT_CVAR, NULL, "Compression Level", &cv_zlib_levela, 100}, - {IT_STRING|IT_CVAR, NULL, "Strategy", &cv_zlib_strategya, 105}, - {IT_STRING|IT_CVAR, NULL, "Window Size", &cv_zlib_window_bitsa, 110}, + {IT_STRING|IT_CVAR, NULL, "Downscaling", &cv_apng_downscale, 95}, + {IT_STRING|IT_CVAR, NULL, "Memory Level", &cv_zlib_memorya, 100}, + {IT_STRING|IT_CVAR, NULL, "Compression Level", &cv_zlib_levela, 105}, + {IT_STRING|IT_CVAR, NULL, "Strategy", &cv_zlib_strategya, 110}, + {IT_STRING|IT_CVAR, NULL, "Window Size", &cv_zlib_window_bitsa, 115}, }; enum @@ -1575,7 +1576,7 @@ enum op_screenshot_gif_start = 13, op_screenshot_gif_end = 15, op_screenshot_apng_start = 16, - op_screenshot_apng_end = 19, + op_screenshot_apng_end = 20, }; static menuitem_t OP_EraseDataMenu[] = From 55f169f3c96152ac259a8e48a71ccf4ee43cea79 Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Thu, 15 Oct 2020 11:04:52 -0500 Subject: [PATCH 053/644] Move the GIF downscaling menu option up one to create some parity. --- src/m_menu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index ffd5c6510..ff9842f66 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1555,8 +1555,8 @@ static menuitem_t OP_ScreenshotOptionsMenu[] = {IT_STRING|IT_CVAR|IT_CV_STRING, NULL, "Custom Folder", &cv_movie_folder, 75}, {IT_STRING|IT_CVAR, NULL, "Capture Mode", &cv_moviemode, 90}, - {IT_STRING|IT_CVAR, NULL, "Region Optimizing", &cv_gif_optimize, 95}, - {IT_STRING|IT_CVAR, NULL, "Downscaling", &cv_gif_downscale, 100}, + {IT_STRING|IT_CVAR, NULL, "Downscaling", &cv_gif_downscale, 95}, + {IT_STRING|IT_CVAR, NULL, "Region Optimizing", &cv_gif_optimize, 100}, {IT_STRING|IT_CVAR, NULL, "Local Color Table", &cv_gif_localcolortable, 105}, {IT_STRING|IT_CVAR, NULL, "Downscaling", &cv_apng_downscale, 95}, From 377a9c10f09cd829dab666419a771cc63b411a67 Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 21 Nov 2020 13:37:12 -0800 Subject: [PATCH 054/644] Lua: disallow bitwise not on anything but number values This fixes a crash. --- src/blua/lcode.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/blua/lcode.c b/src/blua/lcode.c index 5c7fed454..efb20e96b 100644 --- a/src/blua/lcode.c +++ b/src/blua/lcode.c @@ -686,6 +686,15 @@ static void codearith (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) { } +static void codeunaryarith (FuncState *fs, OpCode op, expdesc *e) { + expdesc e2; + e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0; + if (!isnumeral(e)) + luaK_exp2anyreg(fs, e); /* cannot operate on non-numeric constants */ + codearith(fs, op, e, &e2); +} + + static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1, expdesc *e2) { int o1 = luaK_exp2RK(fs, e1); @@ -706,18 +715,8 @@ void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) { expdesc e2; e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0; switch (op) { - case OPR_MINUS: { - if (!isnumeral(e)) - luaK_exp2anyreg(fs, e); /* cannot operate on non-numeric constants */ - codearith(fs, OP_UNM, e, &e2); - break; - } - case OPR_BNOT: { - if (e->k == VK) - luaK_exp2anyreg(fs, e); /* cannot operate on non-numeric constants */ - codearith(fs, OP_BNOT, e, &e2); - break; - } + case OPR_MINUS: codeunaryarith(fs, OP_UNM, e); break; + case OPR_BNOT: codeunaryarith(fs, OP_BNOT, e); break; case OPR_NOT: codenot(fs, e); break; case OPR_LEN: { luaK_exp2anyreg(fs, e); /* cannot operate on constants */ From 5a8e653cd5c6c33a129c40e3f5fa3fb17896b909 Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 21 Nov 2020 13:43:32 -0800 Subject: [PATCH 055/644] More concise --- src/blua/lcode.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/blua/lcode.c b/src/blua/lcode.c index efb20e96b..fd4aaff24 100644 --- a/src/blua/lcode.c +++ b/src/blua/lcode.c @@ -689,7 +689,7 @@ static void codearith (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) { static void codeunaryarith (FuncState *fs, OpCode op, expdesc *e) { expdesc e2; e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0; - if (!isnumeral(e)) + if (op == OP_LEN || !isnumeral(e)) luaK_exp2anyreg(fs, e); /* cannot operate on non-numeric constants */ codearith(fs, op, e, &e2); } @@ -712,17 +712,11 @@ static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1, void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) { - expdesc e2; - e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0; switch (op) { case OPR_MINUS: codeunaryarith(fs, OP_UNM, e); break; case OPR_BNOT: codeunaryarith(fs, OP_BNOT, e); break; case OPR_NOT: codenot(fs, e); break; - case OPR_LEN: { - luaK_exp2anyreg(fs, e); /* cannot operate on constants */ - codearith(fs, OP_LEN, e, &e2); - break; - } + case OPR_LEN: codeunaryarith(fs, OP_LEN, e); break; default: lua_assert(0); } } From 79bbb3fe468e8a8835d1a4a8d5c3ef5d520c6e88 Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 21 Nov 2020 15:19:54 -0800 Subject: [PATCH 056/644] Remove Direct Draw from the Makefiles MINGW/MINGW64 implies SDL. --- src/Makefile | 88 +----------------------------------------- src/Makefile.cfg | 4 +- src/win32/Makefile.cfg | 29 +------------- 3 files changed, 4 insertions(+), 117 deletions(-) diff --git a/src/Makefile b/src/Makefile index 5d5db056f..dccbdd596 100644 --- a/src/Makefile +++ b/src/Makefile @@ -13,8 +13,7 @@ # -DHAVE_SDL -> use for the SDL interface # # Sets: -# Compile the DirectX/Mingw version with 'make MINGW=1' -# Compile the SDL/Mingw version with 'make MINGW=1 SDL=1' +# Compile the SDL/Mingw version with 'make MINGW=1' # Compile the SDL/Linux version with 'make LINUX=1' # Compile the SDL/Solaris version with 'make SOLARIS=1' # Compile the SDL/FreeBSD version with 'gmake FREEBSD=1' @@ -103,7 +102,6 @@ ifeq ($(OS),Windows_NT) # all windows are Windows_NT... # go for a 32-bit sdl mingw exe by default MINGW=1 - SDL=1 WINDOWSHELL=1 else # if you on the *nix @@ -552,12 +550,6 @@ all: pre-build $(BIN)/$(PNDNAME) endif -ifdef MINGW -ifndef SDL -all: pre-build $(BIN)/$(EXENAME) dll -endif -endif - ifdef SDL all: pre-build $(BIN)/$(EXENAME) endif @@ -637,57 +629,6 @@ endif $(OBJDIR): -$(MKDIR) $(OBJDIR) -ifndef SDL -ifdef NOHW -dll : -else -dll : opengl_dll -endif -ifdef MINGW -all_dll: opengl_dll ds3d_dll fmod_dll openal_dll - -opengl_dll: $(BIN)/r_opengl.dll -$(BIN)/r_opengl.dll: $(OBJDIR)/ogl_win.o $(OBJDIR)/r_opengl.o - -$(MKDIR) $(BIN) - @echo Linking R_OpenGL.dll... - $(CC) --shared $^ -o $@ -g -Wl,--add-stdcall-alias -lgdi32 -static-libgcc -ifndef NOUPX - -$(UPX) $(UPX_OPTS) $@ -endif - -ds3d_dll: $(BIN)/s_ds3d.dll -$(BIN)/s_ds3d.dll: $(OBJDIR)/s_ds3d.o - @echo Linking S_DS3d.dll... - $(CC) --shared $^ -o $@ -g -Wl,--add-stdcall-alias -ldsound -luuid - -fmod_dll: $(BIN)/s_fmod.dll -$(BIN)/s_fmod.dll: $(OBJDIR)/s_fmod.o - -$(MKDIR) $(BIN) - @echo Linking S_FMOD.dll... - $(CC) --shared $^ -o $@ -g -Wl,--add-stdcall-alias -lfmod - -openal_dll: $(BIN)/s_openal.dll -$(BIN)/s_openal.dll: $(OBJDIR)/s_openal.o - -$(MKDIR) $(BIN) - @echo Linking S_OpenAL.dll... - $(CC) --shared $^ -o $@ -g -Wl,--add-stdcall-alias -lopenal32 -else -all_dll: fmod_so openal_so - -fmod_so: $(BIN)/s_fmod.so -$(BIN)/s_fmod.so: $(OBJDIR)/s_fmod.o - -$(MKDIR) $(BIN) - @echo Linking S_FMOD.so... - $(CC) --shared $^ -o $@ -g --nostartfiles -lm -lfmod - -openal_so: $(BIN)/s_openal.so -$(BIN)/s_openal.so: $(OBJDIR)/s_openal.o - -$(MKDIR) $(BIN) - @echo Linking S_OpenAL.so... - $(CC) --shared $^ -o $@ -g --nostartfiles -lm -lopenal -endif - -else ifdef SDL ifdef MINGW $(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \ @@ -710,8 +651,6 @@ $(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h endif endif -endif - #dependecy made by gcc itself ! $(OBJS): ifndef DUMMY @@ -774,31 +713,6 @@ $(OBJDIR)/SRB2.res: win32/Srb2win.rc win32/afxres.h win32/resource.h $(WINDRES) -i $< -O rc $(WINDRESFLAGS) --include-dir=win32 -o $@ -O coff -ifdef MINGW -ifndef SDL -ifndef NOHW -$(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \ - doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \ - command.h hardware/hw_data.h hardware/hw_defs.h \ - hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \ - hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \ - am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \ - p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h - $(CC) $(CFLAGS) $(WFLAGS) -D_WINDOWS -mwindows -c $< -o $@ - -$(OBJDIR)/ogl_win.o: hardware/r_opengl/ogl_win.c hardware/r_opengl/r_opengl.h \ - doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \ - command.h hardware/hw_data.h hardware/hw_defs.h \ - hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \ - hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \ - am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \ - p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h - $(CC) $(CFLAGS) $(WFLAGS) -D_WINDOWS -mwindows -c $< -o $@ -endif - -endif -endif - ifdef SDL ifdef MINGW diff --git a/src/Makefile.cfg b/src/Makefile.cfg index db7230bb4..f081eacdf 100644 --- a/src/Makefile.cfg +++ b/src/Makefile.cfg @@ -420,14 +420,14 @@ ifdef CYGWIN32 BIN:=$(BIN)/Cygwin else ifdef MINGW64 - INTERFACE=win32 #NASMFORMAT=win64 + SDL=1 OBJDIR:=$(OBJDIR)/Mingw64 BIN:=$(BIN)/Mingw64 else ifdef MINGW - INTERFACE=win32 NASMFORMAT=win32 + SDL=1 OBJDIR:=$(OBJDIR)/Mingw BIN:=$(BIN)/Mingw endif diff --git a/src/win32/Makefile.cfg b/src/win32/Makefile.cfg index bf68f8c97..888072c9c 100644 --- a/src/win32/Makefile.cfg +++ b/src/win32/Makefile.cfg @@ -56,15 +56,8 @@ ifndef GCC44 #OPTS+=-mms-bitfields endif -ifndef SDL - OPTS+=-D_WINDOWS -endif OPTS+=-D__USE_MINGW_ANSI_STDIO=0 -ifndef SDL - LIBS+=-lmingw32 -mwindows -ldinput -ldxguid -lgdi32 -lwinmm -endif - LIBS+=-ladvapi32 -lkernel32 -lmsvcrt -luser32 ifdef MINGW64 LIBS+=-lws2_32 @@ -77,11 +70,7 @@ endif endif # name of the exefile -ifdef SDL EXENAME?=srb2win.exe -else - EXENAME?=srb2dd.exe -endif ifdef SDL i_system_o+=$(OBJDIR)/SRB2.res @@ -89,22 +78,6 @@ ifdef SDL ifndef NOHW OPTS+=-DUSE_WGL_SWAP endif -else - D_FILES+=$(D_DIR)/fmodex.dll - CFLAGS+=-I../libs/fmodex/inc - LDFLAGS+=-L../libs/fmodex/lib -ifdef MINGW64 - LIBS+=-lfmodex64_vc -else - LIBS+=-lfmodex_vc -endif - i_cdmus_o=$(OBJDIR)/win_cd.o - i_net_o=$(OBJDIR)/win_net.o - i_system_o=$(OBJDIR)/win_sys.o $(OBJDIR)/SRB2.res - i_sound_o=$(OBJDIR)/win_snd.o - i_main_o=$(OBJDIR)/win_main.o - #i_main_o+=$(OBJDIR)/win_dbg.o - OBJS=$(OBJDIR)/dx_error.o $(OBJDIR)/fabdxlib.o $(OBJDIR)/win_vid.o $(OBJDIR)/win_dll.o endif @@ -162,4 +135,4 @@ ifdef MINGW64 else CURL_LDFLAGS+=-L../libs/curl/lib32 -lcurl endif #MINGW64 -endif \ No newline at end of file +endif From f51be77aa21e125c4abd16da2f660c4da03daa84 Mon Sep 17 00:00:00 2001 From: Riku Salminen <38985578+Riku-S@users.noreply.github.com> Date: Sun, 22 Nov 2020 23:19:24 +0200 Subject: [PATCH 057/644] Now the fix actually does what the MR says... +lua banks --- src/g_game.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/g_game.c b/src/g_game.c index d6861b252..1afaf8956 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2242,6 +2242,12 @@ void G_Ticker(boolean run) // Reset unlockable triggers unlocktriggers = 0; + emeralds = 0; + tokenbits = 0; + tokenlist = 0; + token = 0; + + memset(&luabanks, 0, sizeof(luabanks)); } else if (G_GametypeUsesLives() && players[consoleplayer].playerstate == PST_LIVE && players[consoleplayer].lives != INFLIVES) players[consoleplayer].lives -= 1; From b9fa50f7ef00000bc1f79e5d47582aeae971b37f Mon Sep 17 00:00:00 2001 From: Riku Salminen <38985578+Riku-S@users.noreply.github.com> Date: Sun, 22 Nov 2020 23:23:32 +0200 Subject: [PATCH 058/644] No need to reset tokens twice --- src/g_game.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 1afaf8956..b91087b2b 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2243,9 +2243,6 @@ void G_Ticker(boolean run) unlocktriggers = 0; emeralds = 0; - tokenbits = 0; - tokenlist = 0; - token = 0; memset(&luabanks, 0, sizeof(luabanks)); } From 7bbd563b73dc44ba1373bb3d038f5230a2d6329a Mon Sep 17 00:00:00 2001 From: SMS Alfredo <65426124+SMS-Alfredo@users.noreply.github.com> Date: Sun, 22 Nov 2020 23:23:35 -0600 Subject: [PATCH 059/644] Remove unneeded S_PLAY_ROLL check --- src/p_user.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 004ff71d1..0ffa5e1af 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2330,8 +2330,7 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff) P_MobjCheckWater(player->mo); if (player->pflags & PF_SPINNING) { - if (player->mo->state-states != S_PLAY_ROLL && !(player->pflags & PF_STARTDASH) - && player->panim != PA_ROLL && player->panim != PA_ETC + if (!(player->pflags & PF_STARTDASH) && player->panim != PA_ROLL && player->panim != PA_ETC && player->panim != PA_ABILITY && player->panim != PA_ABILITY2) { P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); From 7b05ffd92d101d58aaaf8f5234413ff4ab8a0dd1 Mon Sep 17 00:00:00 2001 From: SMS Alfredo <65426124+SMS-Alfredo@users.noreply.github.com> Date: Mon, 23 Nov 2020 09:18:05 -0600 Subject: [PATCH 060/644] Revert "Fix no spin characters being able to damage enemies with their jump out of a spin without removing PF_SPINNING" This reverts commit ad9bf6085f0845c9fde5348c7299136735a83d84. --- src/p_user.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 0ffa5e1af..2ec8f5995 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1135,8 +1135,7 @@ boolean P_PlayerCanDamage(player_t *player, mobj_t *thing) return true; // Spinning. - if ((player->pflags & PF_SPINNING) - && !((player->pflags & PF_JUMPED) && (player->pflags & PF_NOJUMPDAMAGE))) + if (player->pflags & PF_SPINNING) return true; if (player->dashmode >= DASHMODE_THRESHOLD && (player->charflags & (SF_DASHMODE|SF_MACHINE)) == (SF_DASHMODE|SF_MACHINE)) @@ -4526,6 +4525,7 @@ void P_DoJump(player_t *player, boolean soundandstate) player->mo->eflags &= ~MFE_APPLYPMOMZ; player->pflags |= P_GetJumpFlags(player);; + player->pflags &= ~PF_SPINNING; if (soundandstate) { From ea7e06a61635860ff266da3864ec0b4ecd8dd295 Mon Sep 17 00:00:00 2001 From: SMS Alfredo <65426124+SMS-Alfredo@users.noreply.github.com> Date: Mon, 23 Nov 2020 09:21:00 -0600 Subject: [PATCH 061/644] Remove PF_SPINNING when jumping if you have SF_NOJUMPDAMAGE --- src/p_user.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index 2ec8f5995..da7ad4cb9 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -4525,7 +4525,9 @@ void P_DoJump(player_t *player, boolean soundandstate) player->mo->eflags &= ~MFE_APPLYPMOMZ; player->pflags |= P_GetJumpFlags(player);; - player->pflags &= ~PF_SPINNING; + + if (!(player->charflags & SF_NOJUMPDAMAGE)) + player->pflags &= ~PF_SPINNING; if (soundandstate) { From fe066b3ef28a6b5f3bb91ca10a5ed319469e41d8 Mon Sep 17 00:00:00 2001 From: SMS Alfredo <65426124+SMS-Alfredo@users.noreply.github.com> Date: Mon, 23 Nov 2020 09:23:02 -0600 Subject: [PATCH 062/644] ...snickerdoodles --- src/p_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index da7ad4cb9..6c3c6f136 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -4526,7 +4526,7 @@ void P_DoJump(player_t *player, boolean soundandstate) player->pflags |= P_GetJumpFlags(player);; - if (!(player->charflags & SF_NOJUMPDAMAGE)) + if (player->charflags & SF_NOJUMPDAMAGE) player->pflags &= ~PF_SPINNING; if (soundandstate) From 87968c946beb499c66f20c226f00067f8c0c1fd3 Mon Sep 17 00:00:00 2001 From: lachwright Date: Tue, 24 Nov 2020 14:56:22 +1100 Subject: [PATCH 063/644] Prevent non-CA2_SPINDASH characters from getting crushed by roll-jumping into a crevice --- src/p_user.c | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index b8e7d1746..7dfa9d83a 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8614,6 +8614,7 @@ void P_MovePlayer(player_t *player) P_DoFiring(player, cmd); { + boolean atspinheight = false; fixed_t oldheight = player->mo->height; // Less height while spinning. Good for spinning under things...? @@ -8623,32 +8624,35 @@ void P_MovePlayer(player_t *player) || player->powers[pw_tailsfly] || player->pflags & PF_GLIDING || (player->charability == CA_GLIDEANDCLIMB && player->mo->state-states == S_PLAY_GLIDE_LANDING) || (player->charability == CA_FLY && player->mo->state-states == S_PLAY_FLY_TIRED)) + { player->mo->height = P_GetPlayerSpinHeight(player); + atspinheight = true; + } else player->mo->height = P_GetPlayerHeight(player); if (player->mo->eflags & MFE_VERTICALFLIP && player->mo->height != oldheight) // adjust z height for reverse gravity, similar to how it's done for scaling player->mo->z -= player->mo->height - oldheight; - } - // Crush test... - if ((player->mo->ceilingz - player->mo->floorz < player->mo->height) - && !(player->mo->flags & MF_NOCLIP)) - { - if ((player->charability2 == CA2_SPINDASH) && !(player->pflags & PF_SPINNING)) + // Crush test... + if ((player->mo->ceilingz - player->mo->floorz < player->mo->height) + && !(player->mo->flags & MF_NOCLIP)) { - player->pflags |= PF_SPINNING; - P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); - } - else if (player->mo->ceilingz - player->mo->floorz < player->mo->height) - { - if ((netgame || multiplayer) && player->spectator) - P_DamageMobj(player->mo, NULL, NULL, 1, DMG_SPECTATOR); // Respawn crushed spectators - else - P_DamageMobj(player->mo, NULL, NULL, 1, DMG_CRUSHED); + if (!atspinheight) + { + player->pflags |= PF_SPINNING; + P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); + } + else if (player->mo->ceilingz - player->mo->floorz < player->mo->height) + { + if ((netgame || multiplayer) && player->spectator) + P_DamageMobj(player->mo, NULL, NULL, 1, DMG_SPECTATOR); // Respawn crushed spectators + else + P_DamageMobj(player->mo, NULL, NULL, 1, DMG_CRUSHED); - if (player->playerstate == PST_DEAD) - return; + if (player->playerstate == PST_DEAD) + return; + } } } From 76822cef2bdab3fd0d43f607b29682e060dd03a1 Mon Sep 17 00:00:00 2001 From: Zachary McAlpin Date: Tue, 24 Nov 2020 20:41:11 -0600 Subject: [PATCH 064/644] Expose the selectheading option from mapheader_t in Lua --- src/lua_maplib.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 95cc8c101..83744c74d 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -2189,6 +2189,8 @@ static int mapheaderinfo_get(lua_State *L) lua_pushinteger(L, header->levelflags); else if (fastcmp(field,"menuflags")) lua_pushinteger(L, header->menuflags); + else if (fastcmp(field,"selectheading")) + lua_pushstring(L, header->selectheading); else if (fastcmp(field,"startrings")) lua_pushinteger(L, header->startrings); else if (fastcmp(field, "sstimer")) From b2d6d4f83fb07ddc8f3dfb850f9de8fc43152109 Mon Sep 17 00:00:00 2001 From: SMS Alfredo <65426124+SMS-Alfredo@users.noreply.github.com> Date: Wed, 25 Nov 2020 12:35:36 -0600 Subject: [PATCH 065/644] Expose `player.skin` and `player.availabilities` to Lua as Read-only --- src/lua_playerlib.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 412dc3eff..0eb54808f 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -158,6 +158,10 @@ static int player_get(lua_State *L) lua_pushinteger(L, plr->flashpal); else if (fastcmp(field,"skincolor")) lua_pushinteger(L, plr->skincolor); + else if (fastcmp(field,"skin")) + lua_pushinteger(L, plr->skin); + else if (fastcmp(field,"availabilities")) + lua_pushinteger(L, plr->availabilities); else if (fastcmp(field,"score")) lua_pushinteger(L, plr->score); else if (fastcmp(field,"dashspeed")) @@ -469,6 +473,10 @@ static int player_set(lua_State *L) return luaL_error(L, "player.skincolor %d out of range (0 - %d).", newcolor, numskincolors-1); plr->skincolor = newcolor; } + else if (fastcmp(field,"skin")) + return NOSET; + else if (fastcmp(field,"availabilities")) + return NOSET; else if (fastcmp(field,"score")) plr->score = (UINT32)luaL_checkinteger(L, 3); else if (fastcmp(field,"dashspeed")) From 5c71fe07103e7f3febbb94bc0d9a6a7bd9426fc0 Mon Sep 17 00:00:00 2001 From: SMS Alfredo <65426124+SMS-Alfredo@users.noreply.github.com> Date: Wed, 25 Nov 2020 14:31:24 -0600 Subject: [PATCH 066/644] Allow player.lastlinehit and player.lastsidehit to be used outside of Knuckles' climbing ability --- src/p_map.c | 14 +++++++++++--- src/p_mobj.c | 4 ++++ src/p_user.c | 6 ------ 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index 922c0d9ec..4f344a9b0 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -3443,9 +3443,17 @@ static boolean PTR_SlideTraverse(intercept_t *in) P_ProcessSpecialSector(slidemo->player, slidemo->subsector->sector, li->polyobj->lines[0]->backsector); } - if (slidemo->player && slidemo->player->charability == CA_GLIDEANDCLIMB - && (slidemo->player->pflags & PF_GLIDING || slidemo->player->climbing)) - PTR_GlideClimbTraverse(li); + if (slidemo->player) + { + if (slidemo->player->charability == CA_GLIDEANDCLIMB + && (slidemo->player->pflags & PF_GLIDING || slidemo->player->climbing)) + PTR_GlideClimbTraverse(li); + else + { + slidemo->player->lastsidehit = li->sidenum[P_PointOnLineSide(slidemo->x, slidemo->y, li)]; + slidemo->player->lastlinehit = (INT16)(li - lines); + } + } if (in->frac < bestslidefrac && (!slidemo->player || !slidemo->player->climbing)) { diff --git a/src/p_mobj.c b/src/p_mobj.c index 4fc561b20..8dab1b2cf 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11404,6 +11404,10 @@ void P_SpawnPlayer(INT32 playernum) p->normalspeed = skins[p->skin].normalspeed; p->jumpfactor = skins[p->skin].jumpfactor; } + + // Clear lastlinehit and lastsidehit + p->lastsidehit = -1; + p->lastlinehit = -1; //awayview stuff p->awayviewmobj = NULL; diff --git a/src/p_user.c b/src/p_user.c index 10b7e970e..73f6339a9 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8601,12 +8601,6 @@ void P_MovePlayer(player_t *player) player->climbing--; } - if (!player->climbing) - { - player->lastsidehit = -1; - player->lastlinehit = -1; - } - // Make sure you're not teetering when you shouldn't be. if (player->panim == PA_EDGE && (player->mo->momx || player->mo->momy || player->mo->momz)) From db6b0c6aa0f305cfbf2bd98885b83c0a098237f1 Mon Sep 17 00:00:00 2001 From: Zippy_Zolton Date: Wed, 25 Nov 2020 21:46:45 -0600 Subject: [PATCH 067/644] Fix normal one-up sound playing in Mario mode --- src/p_user.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index c5f919c78..57eb1e072 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1491,10 +1491,10 @@ void P_PlayLivesJingle(player_t *player) if (player && !P_IsLocalPlayer(player)) return; - if (use1upSound || cv_1upsound.value) - S_StartSound(NULL, sfx_oneup); - else if (mariomode) + if (mariomode) S_StartSound(NULL, sfx_marioa); + else if (use1upSound || cv_1upsound.value) + S_StartSound(NULL, sfx_oneup); else { P_PlayJingle(player, JT_1UP); From b9f6069cd07b14d15b2bd26da2f49db3ae96e608 Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 28 Nov 2020 02:19:52 -0800 Subject: [PATCH 068/644] Replace TC macros with an enum that automatically counts up Also fixes TC_DASHMODE not being accessible to Lua. --- src/lua_hudlib.c | 6 ++++-- src/r_draw.h | 18 +++++++++++------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index f4e5d5ccf..04fbf41a0 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -896,8 +896,10 @@ static int libd_getColormap(lua_State *L) else if (lua_type(L, 1) == LUA_TNUMBER) // skin number { skinnum = (INT32)luaL_checkinteger(L, 1); - if (skinnum < TC_BLINK || skinnum >= MAXSKINS) - return luaL_error(L, "skin number %d is out of range (%d - %d)", skinnum, TC_BLINK, MAXSKINS-1); + if (skinnum >= MAXSKINS) + return luaL_error(L, "skin number %d is out of range (>%d)", skinnum, MAXSKINS-1); + else if (skinnum < 0 && skinnum > TC_DEFAULT) + return luaL_error(L, "translation colormap index is out of range"); } else // skin name { diff --git a/src/r_draw.h b/src/r_draw.h index 9957541ca..d1eb83033 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -106,13 +106,17 @@ extern lumpnum_t viewborderlump[8]; #define GTC_CACHE 1 -#define TC_DEFAULT -1 -#define TC_BOSS -2 -#define TC_METALSONIC -3 // For Metal Sonic battle -#define TC_ALLWHITE -4 // For Cy-Brak-demon -#define TC_RAINBOW -5 // For single colour -#define TC_BLINK -6 // For item blinking, according to kart -#define TC_DASHMODE -7 // For Metal Sonic's dashmode +enum +{ + TC_BOSS = INT8_MIN, + TC_METALSONIC, // For Metal Sonic battle + TC_ALLWHITE, // For Cy-Brak-demon + TC_RAINBOW, // For single colour + TC_BLINK, // For item blinking, according to kart + TC_DASHMODE, // For Metal Sonic's dashmode + + TC_DEFAULT +}; // Custom player skin translation // Initialize color translation tables, for player rendering etc. From 75c5c8ba6a0ffc54ff609fe1ae644b70c53edb68 Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 28 Nov 2020 02:22:08 -0800 Subject: [PATCH 069/644] Add missing *individual* skin flags --- src/d_player.h | 2 +- src/r_skins.c | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/d_player.h b/src/d_player.h index eb0372832..79f2a3b92 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -51,7 +51,7 @@ typedef enum SF_NONIGHTSSUPER = 1<<15, // Disable super colors for NiGHTS (if you have SF_SUPER) SF_NOSUPERSPRITES = 1<<16, // Don't use super sprites while super SF_NOSUPERJUMPBOOST = 1<<17, // Disable the jump boost given while super (i.e. Knuckles) - SF_CANBUSTWALLS = 1<<18, // Can naturally bust walls on contact? (i.e. Knuckles) + SF_CANBUSTWALLS = 1<<18, // Can naturally bust walls on contact? (i.e. Knuckles) // free up to and including 1<<31 } skinflags_t; diff --git a/src/r_skins.c b/src/r_skins.c index 25904e95e..522d9236a 100644 --- a/src/r_skins.c +++ b/src/r_skins.c @@ -511,6 +511,9 @@ static boolean R_ProcessPatchableFields(skin_t *skin, char *stoken, char *value) GETFLAG(MULTIABILITY) GETFLAG(NONIGHTSROTATION) GETFLAG(NONIGHTSSUPER) + GETFLAG(NOSUPERSPRITES) + GETFLAG(NOSUPERJUMPBOOST) + GETFLAG(CANBUSTWALLS) #undef GETFLAG else // let's check if it's a sound, otherwise error out From 6b4d4226649eebb200f1f00e0f863f39a28ea57d Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 28 Nov 2020 20:00:01 -0800 Subject: [PATCH 070/644] Don't add pk3 if there are holes ZIP tools often read the final central directory, but SRB2 may not if there are multiple central directories. It's just easier to not allow "holes", or unaccounted for bytes in the file. --- src/w_wad.c | 111 ++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 85 insertions(+), 26 deletions(-) diff --git a/src/w_wad.c b/src/w_wad.c index aca530fa5..19432e937 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -716,7 +716,7 @@ UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup) #endif size_t packetsize; UINT8 md5sum[16]; - boolean important; + int important; if (!(refreshdirmenu & REFRESHDIR_ADDFILE)) refreshdirmenu = REFRESHDIR_NORMAL|REFRESHDIR_ADDFILE; // clean out cons_alerts that happened earlier @@ -746,10 +746,18 @@ UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup) if ((handle = W_OpenWadFile(&filename, true)) == NULL) return W_InitFileError(filename, startup); + important = W_VerifyNMUSlumps(filename); + + if (important == -1) + { + fclose(handle); + return W_InitFileError(filename, startup); + } + // Check if wad files will overflow fileneededbuffer. Only the filename part // is send in the packet; cf. // see PutFileNeeded in d_netfil.c - if ((important = !W_VerifyNMUSlumps(filename))) + if ((important = !important)) { packetsize = packetsizetally + nameonlylength(filename) + 22; @@ -1919,8 +1927,16 @@ static lumpchecklist_t folderblacklist[] = static int W_VerifyPK3 (FILE *fp, lumpchecklist_t *checklist, boolean status) { + int verified = true; + zend_t zend; zentry_t zentry; + zlentry_t zlentry; + + long file_size;/* size of zip file */ + long data_size;/* size of data inside zip file */ + + long old_position; UINT16 numlumps; size_t i; @@ -1936,6 +1952,8 @@ W_VerifyPK3 (FILE *fp, lumpchecklist_t *checklist, boolean status) // Central directory bullshit fseek(fp, 0, SEEK_END); + file_size = ftell(fp); + if (!ResFindSignature(fp, pat_end, max(0, ftell(fp) - (22 + 65536)))) return true; @@ -1943,6 +1961,8 @@ W_VerifyPK3 (FILE *fp, lumpchecklist_t *checklist, boolean status) if (fread(&zend, 1, sizeof zend, fp) < sizeof zend) return true; + data_size = sizeof zend; + numlumps = zend.entries; fseek(fp, zend.cdiroffset, SEEK_SET); @@ -1957,40 +1977,79 @@ W_VerifyPK3 (FILE *fp, lumpchecklist_t *checklist, boolean status) if (memcmp(zentry.signature, pat_central, 4)) return true; - fullname = malloc(zentry.namelen + 1); - if (fgets(fullname, zentry.namelen + 1, fp) != fullname) - return true; - - // Strip away file address and extension for the 8char name. - if ((trimname = strrchr(fullname, '/')) != 0) - trimname++; - else - trimname = fullname; // Care taken for root files. - - if (*trimname) // Ignore directories, well kinda + if (verified == true) { - if ((dotpos = strrchr(trimname, '.')) == 0) - dotpos = fullname + strlen(fullname); // Watch for files without extension. + fullname = malloc(zentry.namelen + 1); + if (fgets(fullname, zentry.namelen + 1, fp) != fullname) + return true; - memset(lumpname, '\0', 9); // Making sure they're initialized to 0. Is it necessary? - strncpy(lumpname, trimname, min(8, dotpos - trimname)); + // Strip away file address and extension for the 8char name. + if ((trimname = strrchr(fullname, '/')) != 0) + trimname++; + else + trimname = fullname; // Care taken for root files. - if (! W_VerifyName(lumpname, checklist, status)) - return false; + if (*trimname) // Ignore directories, well kinda + { + if ((dotpos = strrchr(trimname, '.')) == 0) + dotpos = fullname + strlen(fullname); // Watch for files without extension. - // Check for directories next, if it's blacklisted it will return false - if (W_VerifyName(fullname, folderblacklist, status)) - return false; + memset(lumpname, '\0', 9); // Making sure they're initialized to 0. Is it necessary? + strncpy(lumpname, trimname, min(8, dotpos - trimname)); + + if (! W_VerifyName(lumpname, checklist, status)) + verified = false; + + // Check for directories next, if it's blacklisted it will return false + else if (W_VerifyName(fullname, folderblacklist, status)) + verified = false; + } + + free(fullname); + + // skip and ignore comments/extra fields + if (fseek(fp, zentry.xtralen + zentry.commlen, SEEK_CUR) != 0) + return true; + } + else + { + if (fseek(fp, zentry.namelen + zentry.xtralen + zentry.commlen, SEEK_CUR) != 0) + return true; } - free(fullname); + data_size += + sizeof zentry + zentry.namelen + zentry.xtralen + zentry.commlen; - // skip and ignore comments/extra fields - if (fseek(fp, zentry.xtralen + zentry.commlen, SEEK_CUR) != 0) + old_position = ftell(fp); + + if (fseek(fp, zentry.offset, SEEK_SET) != 0) return true; + + if (fread(&zlentry, 1, sizeof(zlentry_t), fp) < sizeof (zlentry_t)) + return true; + + data_size += + sizeof zlentry + zlentry.namelen + zlentry.xtralen + zlentry.compsize; + + fseek(fp, old_position, SEEK_SET); } - return true; + if (data_size < file_size) + { + const char * error = "ZIP file has holes (%ld extra bytes)\n"; + CONS_Alert(CONS_ERROR, error, (file_size - data_size)); + return -1; + } + else if (data_size > file_size) + { + const char * error = "Reported size of ZIP file contents exceeds file size (%ld extra bytes)\n"; + CONS_Alert(CONS_ERROR, error, (data_size - file_size)); + return -1; + } + else + { + return verified; + } } // Note: This never opens lumps themselves and therefore doesn't have to From 95dfb93a117a76f60e9a7cd0e316a7e9d81ca87a Mon Sep 17 00:00:00 2001 From: SMS Alfredo <65426124+SMS-Alfredo@users.noreply.github.com> Date: Sat, 28 Nov 2020 22:03:02 -0600 Subject: [PATCH 071/644] Allow non-player objects to apply the CR_PLAYER carry type without crashing the game --- src/p_user.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 10b7e970e..6205a40dd 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -12580,13 +12580,16 @@ void P_PlayerAfterThink(player_t *player) player->powers[pw_carry] = CR_NONE; else { - P_TryMove(player->mo, tails->x + P_ReturnThrustX(tails, tails->player->drawangle, 4*FRACUNIT), tails->y + P_ReturnThrustY(tails, tails->player->drawangle, 4*FRACUNIT), true); + if (tails->player) + P_TryMove(player->mo, tails->x + P_ReturnThrustX(tails, tails->player->drawangle, 4*FRACUNIT), tails->y + P_ReturnThrustY(tails, tails->player->drawangle, 4*FRACUNIT), true); + else + P_TryMove(player->mo, tails->x + P_ReturnThrustX(tails, tails->angle, 4*FRACUNIT), tails->y + P_ReturnThrustY(tails, tails->angle, 4*FRACUNIT), true); player->mo->momx = tails->momx; player->mo->momy = tails->momy; player->mo->momz = tails->momz; } - if (G_CoopGametype() && (!tails->player || tails->player->bot != 1)) + if (G_CoopGametype() && tails->player && tails->player->bot != 1) { player->mo->angle = tails->angle; @@ -12601,7 +12604,7 @@ void P_PlayerAfterThink(player_t *player) { if (player->mo->state-states != S_PLAY_RIDE) P_SetPlayerMobjState(player->mo, S_PLAY_RIDE); - if ((tails->skin && ((skin_t *)(tails->skin))->sprites[SPR2_SWIM].numframes) && (tails->eflags & MFE_UNDERWATER)) + if (tails->player && (tails->skin && ((skin_t *)(tails->skin))->sprites[SPR2_SWIM].numframes) && (tails->eflags & MFE_UNDERWATER)) tails->player->powers[pw_tailsfly] = 0; } else From 445d0407959ae36f93f7d7265ec5e36093782e8f Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 28 Nov 2020 20:51:21 -0800 Subject: [PATCH 072/644] Don't print W_VerifyFile errors more than once --- src/d_main.c | 6 +----- src/d_netcmd.c | 8 +++++++- src/w_wad.c | 23 +++++++++++++++++------ src/w_wad.h | 2 +- 4 files changed, 26 insertions(+), 13 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 1045d4d99..ace1b5ed4 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -998,7 +998,7 @@ static void IdentifyVersion(void) #define MUSICTEST(str) \ {\ const char *musicpath = va(pandf,srb2waddir,str);\ - int ms = W_VerifyNMUSlumps(musicpath); \ + int ms = W_VerifyNMUSlumps(musicpath, false); \ if (ms == 1) \ D_AddFile(startupwadfiles, musicpath); \ else if (ms == 0) \ @@ -1187,11 +1187,7 @@ void D_SRB2Main(void) const char *s = M_GetNextParm(); if (s) // Check for NULL? - { - if (!W_VerifyNMUSlumps(s)) - G_SetGameModified(true); D_AddFile(startuppwads, s); - } } } } diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 31c10f58a..49a465ce7 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -3294,7 +3294,13 @@ static void Command_Addfile(void) if (!isprint(fn[i]) || fn[i] == ';') return; - musiconly = W_VerifyNMUSlumps(fn); + musiconly = W_VerifyNMUSlumps(fn, false); + + if (musiconly == -1) + { + addedfiles[numfilesadded++] = fn; + continue; + } if (!musiconly) { diff --git a/src/w_wad.c b/src/w_wad.c index 19432e937..2429eaf92 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -66,6 +66,7 @@ #include "p_setup.h" // P_ScanThings #endif #include "m_misc.h" // M_MapNumber +#include "g_game.h" // G_SetGameModified #ifdef HWRENDER #include "hardware/hw_main.h" @@ -683,9 +684,9 @@ static UINT16 W_InitFileError (const char *filename, boolean exitworthy) if (exitworthy) { #ifdef _DEBUG - CONS_Error("A WAD file was not found or not valid.\nCheck the log to see which ones.\n"); + CONS_Error(va("%s was not found or not valid.\nCheck the log for more details.\n", filename)); #else - I_Error("A WAD file was not found or not valid.\nCheck the log to see which ones.\n"); + I_Error("%s was not found or not valid.\nCheck the log for more details.\n", filename); #endif } else @@ -746,12 +747,12 @@ UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup) if ((handle = W_OpenWadFile(&filename, true)) == NULL) return W_InitFileError(filename, startup); - important = W_VerifyNMUSlumps(filename); + important = W_VerifyNMUSlumps(filename, startup); if (important == -1) { fclose(handle); - return W_InitFileError(filename, startup); + return INT16_MAX; } // Check if wad files will overflow fileneededbuffer. Only the filename part @@ -819,6 +820,9 @@ UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup) return W_InitFileError(filename, startup); } + if (important && !mainfile) + G_SetGameModified(true); + // // link wad file to search files // @@ -2088,12 +2092,13 @@ static int W_VerifyFile(const char *filename, lumpchecklist_t *checklist, * be sent. * * \param filename Filename of the wad to check. + * \param exit_on_error Whether to exit upon file error. * \return 1 if file contains only music/sound lumps, 0 if it contains other * stuff (maps, sprites, dehacked lumps, and so on). -1 if there no * file exists with that filename * \author Alam Arias */ -int W_VerifyNMUSlumps(const char *filename) +int W_VerifyNMUSlumps(const char *filename, boolean exit_on_error) { // MIDI, MOD/S3M/IT/XM/OGG/MP3/WAV, WAVE SFX // ENDOOM text and palette lumps @@ -2167,7 +2172,13 @@ int W_VerifyNMUSlumps(const char *filename) {NULL, 0}, }; - return W_VerifyFile(filename, NMUSlist, false); + + int status = W_VerifyFile(filename, NMUSlist, false); + + if (status == -1) + W_InitFileError(filename, exit_on_error); + + return status; } /** \brief Generates a virtual resource used for level data loading. diff --git a/src/w_wad.h b/src/w_wad.h index 1e86eea5a..d0a86bcb4 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -206,6 +206,6 @@ void W_UnlockCachedPatch(void *patch); void W_VerifyFileMD5(UINT16 wadfilenum, const char *matchmd5); -int W_VerifyNMUSlumps(const char *filename); +int W_VerifyNMUSlumps(const char *filename, boolean exit_on_error); #endif // __W_WAD__ From 59d26465939ea9941f7d29e67a5b270c9362a21d Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Sun, 29 Nov 2020 08:30:50 -0600 Subject: [PATCH 073/644] Send a `quitting` argument to the GameQuit Lua hook --- src/d_clisrv.c | 6 +++--- src/d_netcmd.c | 4 ++-- src/lua_hook.h | 2 +- src/lua_hooklib.c | 5 +++-- src/m_menu.c | 4 ++-- src/sdl/i_video.c | 2 +- 6 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index b198011a0..8951fe204 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -3027,7 +3027,7 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum) if (pnum == consoleplayer) { if (Playing()) - LUAh_GameQuit(); + LUAh_GameQuit(false); #ifdef DUMPCONSISTENCY if (msg == KICK_MSG_CON_FAIL) SV_SavedGame(); #endif @@ -3728,7 +3728,7 @@ static void HandleShutdown(SINT8 node) { (void)node; if (Playing()) - LUAh_GameQuit(); + LUAh_GameQuit(false); D_QuitNetGame(); CL_Reset(); D_StartTitle(); @@ -3744,7 +3744,7 @@ static void HandleTimeout(SINT8 node) { (void)node; if (Playing()) - LUAh_GameQuit(); + LUAh_GameQuit(false); D_QuitNetGame(); CL_Reset(); D_StartTitle(); diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 31c10f58a..ec46aa4c3 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -3607,7 +3607,7 @@ static void Command_Playintro_f(void) FUNCNORETURN static ATTRNORETURN void Command_Quit_f(void) { if (Playing()) - LUAh_GameQuit(); + LUAh_GameQuit(true); I_Quit(); } @@ -4270,7 +4270,7 @@ void Command_ExitGame_f(void) INT32 i; if (Playing()) - LUAh_GameQuit(); + LUAh_GameQuit(false); D_QuitNetGame(); CL_Reset(); diff --git a/src/lua_hook.h b/src/lua_hook.h index 796f3a9d2..dd41814b5 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -117,6 +117,6 @@ boolean LUAh_SeenPlayer(player_t *player, player_t *seenfriend); // Hook for MT_ #endif #define LUAh_PlayerThink(player) LUAh_PlayerHook(player, hook_PlayerThink) // Hook for P_PlayerThink boolean LUAh_ShouldJingleContinue(player_t *player, const char *musname); // Hook for whether a jingle of the given music should continue playing -void LUAh_GameQuit(void); // Hook for game quitting +void LUAh_GameQuit(boolean quitting); // Hook for game quitting boolean LUAh_PlayerCmd(player_t *player, ticcmd_t *cmd); // Hook for building player's ticcmd struct (Ported from SRB2Kart) boolean LUAh_MusicChange(const char *oldname, char *newname, UINT16 *mflags, boolean *looping, UINT32 *position, UINT32 *prefadems, UINT32 *fadeinms); // Hook for music changes \ No newline at end of file diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 117aa48a3..a206f80db 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -1846,7 +1846,7 @@ boolean LUAh_ShouldJingleContinue(player_t *player, const char *musname) } // Hook for game quitting -void LUAh_GameQuit(void) +void LUAh_GameQuit(boolean quitting) { hook_p hookp; if (!gL || !(hooksAvailable[hook_GameQuit/8] & (1<<(hook_GameQuit%8)))) @@ -1860,7 +1860,8 @@ void LUAh_GameQuit(void) continue; PushHook(gL, hookp); - if (lua_pcall(gL, 0, 0, 1)) { + lua_pushboolean(gL, quitting); + if (lua_pcall(gL, 1, 0, 1)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); diff --git a/src/m_menu.c b/src/m_menu.c index 77648f877..135137c12 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -6938,7 +6938,7 @@ static void M_UltimateCheat(INT32 choice) { (void)choice; if (Playing()) - LUAh_GameQuit(); + LUAh_GameQuit(true); I_Quit(); } @@ -13373,7 +13373,7 @@ void M_QuitResponse(INT32 ch) if (ch != 'y' && ch != KEY_ENTER) return; if (Playing()) - LUAh_GameQuit(); + LUAh_GameQuit(true); if (!(netgame || cv_debug)) { S_ResetCaptions(); diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index b8b3b9d34..310275d55 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1058,7 +1058,7 @@ void I_GetEvent(void) break; case SDL_QUIT: if (Playing()) - LUAh_GameQuit(); + LUAh_GameQuit(true); I_Quit(); break; } From b389700de3a9523b946ecdb5cc8450ea70d422a4 Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Sun, 29 Nov 2020 08:32:04 -0600 Subject: [PATCH 074/644] Always call GameQuit when quitting via the Quit menu option on the title screen. --- src/m_menu.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 135137c12..258b01318 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -13372,8 +13372,7 @@ void M_QuitResponse(INT32 ch) if (ch != 'y' && ch != KEY_ENTER) return; - if (Playing()) - LUAh_GameQuit(true); + LUAh_GameQuit(true); if (!(netgame || cv_debug)) { S_ResetCaptions(); From 119d2e9e37ec60c5a729e4dd255a96f37be8d7b2 Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Sun, 29 Nov 2020 16:53:29 -0600 Subject: [PATCH 075/644] Remove the rest of the Playing() checks for GameQuit hook --- src/d_clisrv.c | 9 +++------ src/d_netcmd.c | 6 ++---- src/m_menu.c | 3 +-- src/sdl/i_video.c | 3 +-- 4 files changed, 7 insertions(+), 14 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 8951fe204..52f091fee 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -3026,8 +3026,7 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum) if (pnum == consoleplayer) { - if (Playing()) - LUAh_GameQuit(false); + LUAh_GameQuit(false); #ifdef DUMPCONSISTENCY if (msg == KICK_MSG_CON_FAIL) SV_SavedGame(); #endif @@ -3727,8 +3726,7 @@ static void HandleConnect(SINT8 node) static void HandleShutdown(SINT8 node) { (void)node; - if (Playing()) - LUAh_GameQuit(false); + LUAh_GameQuit(false); D_QuitNetGame(); CL_Reset(); D_StartTitle(); @@ -3743,8 +3741,7 @@ static void HandleShutdown(SINT8 node) static void HandleTimeout(SINT8 node) { (void)node; - if (Playing()) - LUAh_GameQuit(false); + LUAh_GameQuit(false); D_QuitNetGame(); CL_Reset(); D_StartTitle(); diff --git a/src/d_netcmd.c b/src/d_netcmd.c index ec46aa4c3..7d5a598db 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -3606,8 +3606,7 @@ static void Command_Playintro_f(void) */ FUNCNORETURN static ATTRNORETURN void Command_Quit_f(void) { - if (Playing()) - LUAh_GameQuit(true); + LUAh_GameQuit(true); I_Quit(); } @@ -4269,8 +4268,7 @@ void Command_ExitGame_f(void) { INT32 i; - if (Playing()) - LUAh_GameQuit(false); + LUAh_GameQuit(false); D_QuitNetGame(); CL_Reset(); diff --git a/src/m_menu.c b/src/m_menu.c index 258b01318..5ec9132f7 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -6937,8 +6937,7 @@ static void M_SelectableClearMenus(INT32 choice) static void M_UltimateCheat(INT32 choice) { (void)choice; - if (Playing()) - LUAh_GameQuit(true); + LUAh_GameQuit(true); I_Quit(); } diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 310275d55..5ebff8700 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1057,8 +1057,7 @@ void I_GetEvent(void) M_SetupJoystickMenu(0); break; case SDL_QUIT: - if (Playing()) - LUAh_GameQuit(true); + LUAh_GameQuit(true); I_Quit(); break; } From f913d60a9faab27ddf9182051b8d1190af87ac17 Mon Sep 17 00:00:00 2001 From: Zippy_Zolton Date: Sun, 29 Nov 2020 17:16:57 -0600 Subject: [PATCH 076/644] Make P_DoSuperTransformation (with giverings) add 50 rings instead of setting it --- src/p_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index c5f919c78..04c5e1387 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1342,7 +1342,7 @@ void P_DoSuperTransformation(player_t *player, boolean giverings) P_SetPlayerMobjState(player->mo, S_PLAY_SUPER_TRANS1); if (giverings) - player->rings = 50; + player->rings += 50; // Just in case. if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOSSMUSIC)) From 412f3fc42b4c8b57ca0bd0eee0fd67c2f8abae71 Mon Sep 17 00:00:00 2001 From: Zippy_Zolton Date: Sun, 29 Nov 2020 17:39:54 -0600 Subject: [PATCH 077/644] P_GivePlayerRings --- src/p_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index 04c5e1387..166027c8d 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1342,7 +1342,7 @@ void P_DoSuperTransformation(player_t *player, boolean giverings) P_SetPlayerMobjState(player->mo, S_PLAY_SUPER_TRANS1); if (giverings) - player->rings += 50; + P_GivePlayerRings(player, 50) // Just in case. if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOSSMUSIC)) From da1a3029a90a43475afd0a8f7a356c94697366ea Mon Sep 17 00:00:00 2001 From: Zippy_Zolton Date: Mon, 30 Nov 2020 12:04:35 -0600 Subject: [PATCH 078/644] overhaul --- src/p_user.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 166027c8d..66cce3082 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1341,8 +1341,8 @@ void P_DoSuperTransformation(player_t *player, boolean giverings) // Transformation animation P_SetPlayerMobjState(player->mo, S_PLAY_SUPER_TRANS1); - if (giverings) - P_GivePlayerRings(player, 50) + if (giverings) && player->rings > 50 + player->rings = 50 // Just in case. if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOSSMUSIC)) From 20d181198374a092d5639f149f635ae3f69885c3 Mon Sep 17 00:00:00 2001 From: Zippy_Zolton Date: Mon, 30 Nov 2020 12:05:45 -0600 Subject: [PATCH 079/644] oops --- src/p_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index 66cce3082..e357c8b5c 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1342,7 +1342,7 @@ void P_DoSuperTransformation(player_t *player, boolean giverings) P_SetPlayerMobjState(player->mo, S_PLAY_SUPER_TRANS1); if (giverings) && player->rings > 50 - player->rings = 50 + player->rings = 50; // Just in case. if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOSSMUSIC)) From 9770368ee9b2e60fb375b60da71e66f130c44e06 Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+Ikkarin@users.noreply.github.com> Date: Mon, 30 Nov 2020 18:21:06 -0300 Subject: [PATCH 080/644] Initialize junk line tag lists --- src/p_enemy.c | 8 ++++++++ src/p_inter.c | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/src/p_enemy.c b/src/p_enemy.c index 22de9bc67..63a14636d 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -3924,6 +3924,10 @@ void A_BossDeath(mobj_t *mo) } else { + // Initialize my junk + junk.tags.tags = NULL; + junk.tags.count = 0; + // Bring the egg trap up to the surface // Incredibly shitty code ahead Tag_FSet(&junk.tags, LE_CAPSULE0); @@ -4053,6 +4057,10 @@ bossjustdie: } case MT_KOOPA: { + // Initialize my junk + junk.tags.tags = NULL; + junk.tags.count = 0; + Tag_FSet(&junk.tags, LE_KOOPA); EV_DoCeiling(&junk, raiseToHighest); return; diff --git a/src/p_inter.c b/src/p_inter.c index 415c679e4..9bfe54e54 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1388,6 +1388,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (player->bot) return; + // Initialize my junk + junk.tags.tags = NULL; + junk.tags.count = 0; + Tag_FSet(&junk.tags, LE_AXE); EV_DoElevator(&junk, bridgeFall, false); From 69248cc684541678162920b5573b125ec3f6bc73 Mon Sep 17 00:00:00 2001 From: Zippy_Zolton Date: Mon, 30 Nov 2020 16:39:24 -0600 Subject: [PATCH 081/644] thanks zap --- src/p_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index e357c8b5c..31aadffa6 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1341,7 +1341,7 @@ void P_DoSuperTransformation(player_t *player, boolean giverings) // Transformation animation P_SetPlayerMobjState(player->mo, S_PLAY_SUPER_TRANS1); - if (giverings) && player->rings > 50 + if (giverings && player->rings < 50) player->rings = 50; // Just in case. From c8ae28bbaf3a16ca445647da47968573078507e9 Mon Sep 17 00:00:00 2001 From: Nev3r Date: Tue, 1 Dec 2020 18:35:24 +0100 Subject: [PATCH 082/644] Follow GZDoom's convention for stringargs. --- src/p_setup.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 918ffbd4e..e02cb34aa 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1628,9 +1628,9 @@ static void ParseTextmapLinedefParameter(UINT32 i, char *param, char *val) return; lines[i].args[argnum] = atol(val); } - else if (fastncmp(param, "stringarg", 9) && strlen(param) > 9) + else if (strlen(param) == 7 && fastncmp(param, "arg", 3) && fastncmp(param + 4, "str", 3)) { - size_t argnum = param[9] - '0'; + size_t argnum = param[3] - '0'; if (argnum >= NUMLINESTRINGARGS) return; lines[i].stringargs[argnum] = Z_Malloc(strlen(val) + 1, PU_LEVEL, NULL); @@ -1727,9 +1727,9 @@ static void ParseTextmapThingParameter(UINT32 i, char *param, char *val) return; mapthings[i].args[argnum] = atol(val); } - else if (fastncmp(param, "stringarg", 9) && strlen(param) > 9) + else if (strlen(param) == 7 && fastncmp(param, "arg", 3) && fastncmp(param + 4, "str", 3)) { - size_t argnum = param[9] - '0'; + size_t argnum = param[3] - '0'; if (argnum >= NUMMAPTHINGSTRINGARGS) return; mapthings[i].stringargs[argnum] = Z_Malloc(strlen(val) + 1, PU_LEVEL, NULL); From 4d716cb1707b3822dd333f57214faf8e8875aac1 Mon Sep 17 00:00:00 2001 From: Nev3r Date: Tue, 1 Dec 2020 19:44:58 +0100 Subject: [PATCH 083/644] Move the numerical arg check below so that the string gets checked first (who decided to give them such similar names anyway). --- src/p_setup.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index e02cb34aa..41d8822e2 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1621,13 +1621,6 @@ static void ParseTextmapLinedefParameter(UINT32 i, char *param, char *val) P_SetLinedefV1(i, atol(val)); else if (fastcmp(param, "v2")) P_SetLinedefV2(i, atol(val)); - else if (fastncmp(param, "arg", 3) && strlen(param) > 3) - { - size_t argnum = atol(param + 3); - if (argnum >= NUMLINEARGS) - return; - lines[i].args[argnum] = atol(val); - } else if (strlen(param) == 7 && fastncmp(param, "arg", 3) && fastncmp(param + 4, "str", 3)) { size_t argnum = param[3] - '0'; @@ -1636,6 +1629,13 @@ static void ParseTextmapLinedefParameter(UINT32 i, char *param, char *val) lines[i].stringargs[argnum] = Z_Malloc(strlen(val) + 1, PU_LEVEL, NULL); M_Memcpy(lines[i].stringargs[argnum], val, strlen(val) + 1); } + else if (fastncmp(param, "arg", 3) && strlen(param) > 3) + { + size_t argnum = atol(param + 3); + if (argnum >= NUMLINEARGS) + return; + lines[i].args[argnum] = atol(val); + } else if (fastcmp(param, "sidefront")) lines[i].sidenum[0] = atol(val); else if (fastcmp(param, "sideback")) @@ -1720,13 +1720,6 @@ static void ParseTextmapThingParameter(UINT32 i, char *param, char *val) else if (fastcmp(param, "ambush") && fastcmp("true", val)) mapthings[i].options |= MTF_AMBUSH; - else if (fastncmp(param, "arg", 3) && strlen(param) > 3) - { - size_t argnum = atol(param + 3); - if (argnum >= NUMMAPTHINGARGS) - return; - mapthings[i].args[argnum] = atol(val); - } else if (strlen(param) == 7 && fastncmp(param, "arg", 3) && fastncmp(param + 4, "str", 3)) { size_t argnum = param[3] - '0'; @@ -1735,6 +1728,13 @@ static void ParseTextmapThingParameter(UINT32 i, char *param, char *val) mapthings[i].stringargs[argnum] = Z_Malloc(strlen(val) + 1, PU_LEVEL, NULL); M_Memcpy(mapthings[i].stringargs[argnum], val, strlen(val) + 1); } + else if (fastncmp(param, "arg", 3) && strlen(param) > 3) + { + size_t argnum = atol(param + 3); + if (argnum >= NUMMAPTHINGARGS) + return; + mapthings[i].args[argnum] = atol(val); + } } /** From a given position table, run a specified parser function through a {}-encapsuled text. From b2544395926ed4c5f7ec02a91e486feb6ba5b78d Mon Sep 17 00:00:00 2001 From: Radicalicious Date: Wed, 2 Dec 2020 00:17:57 -0500 Subject: [PATCH 084/644] Update hw_light.c --- src/hardware/hw_light.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hardware/hw_light.c b/src/hardware/hw_light.c index 987d70c69..76fecd7aa 100644 --- a/src/hardware/hw_light.c +++ b/src/hardware/hw_light.c @@ -340,6 +340,7 @@ light_t *t_lspr[NUMSPRITES] = &lspr[NOLIGHT], // SPR_BMCH &lspr[NOLIGHT], // SPR_SMCE &lspr[NOLIGHT], // SPR_BMCE + &lspr[NOLIGHT], // SPR_BSPB &lspr[NOLIGHT], // SPR_YSPB &lspr[NOLIGHT], // SPR_RSPB &lspr[REDBALL_L], // SPR_SFBR From a67862665a054538788fdb7b01575198bc37a35d Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+Ikkarin@users.noreply.github.com> Date: Wed, 2 Dec 2020 12:05:40 -0300 Subject: [PATCH 085/644] Don't spawn the projectile if you're just gonna delete it --- src/p_mobj.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 7ba6d1fad..a259847ea 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -5654,14 +5654,10 @@ static void P_Boss9Thinker(mobj_t *mobj) if (P_RandomRange(1,(dist>>FRACBITS)/16) == 1) break; } - if (spawner) + if (spawner && dist) { mobj_t *missile = P_SpawnMissile(spawner, mobj, MT_MSGATHER); - - if (dist == 0) - missile->fuse = 0; - else - missile->fuse = (dist/P_AproxDistance(missile->momx, missile->momy)); + missile->fuse = (dist/P_AproxDistance(missile->momx, missile->momy)); if (missile->fuse > mobj->fuse) P_RemoveMobj(missile); From 0ffb241c0a1705273c0c93790b67d2ce3474ad0e Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Wed, 2 Dec 2020 15:31:11 -0300 Subject: [PATCH 086/644] Fix 3D floor culling with polyobject segs --- src/r_segs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/r_segs.c b/src/r_segs.c index 1ed1f0285..3bc0d011c 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -1191,7 +1191,7 @@ static void R_RenderSegLoop (void) // Lactozilla: Cull part of the column by the 3D floor if it can't be seen // "bottom" is the top pixel of the floor column - if (ffbottom >= bottom-1 && R_FFloorCanClip(&ffloor[i])) + if (ffbottom >= bottom-1 && R_FFloorCanClip(&ffloor[i]) && !curline->polyseg) { rw_floormarked = true; floorclip[rw_x] = fftop; @@ -1239,7 +1239,7 @@ static void R_RenderSegLoop (void) // Lactozilla: Cull part of the column by the 3D floor if it can't be seen // "top" is the height of the ceiling column - if (fftop <= top+1 && R_FFloorCanClip(&ffloor[i])) + if (fftop <= top+1 && R_FFloorCanClip(&ffloor[i]) && !curline->polyseg) { rw_ceilingmarked = true; ceilingclip[rw_x] = ffbottom; From 47b8c0648b2b87fdf7ec388e1f0c3b48239c8cff Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Wed, 2 Dec 2020 15:34:11 -0300 Subject: [PATCH 087/644] Don't clip if the 3D floor is fog --- src/r_segs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_segs.c b/src/r_segs.c index 3bc0d011c..c79071e9b 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -540,7 +540,7 @@ static boolean R_IsFFloorTranslucent(visffloor_t *pfloor) // Polyobjects have no ffloors, and they're handled in the conditional above. if (pfloor->ffloor != NULL) - return (pfloor->ffloor->flags & FF_TRANSLUCENT); + return (pfloor->ffloor->flags & (FF_TRANSLUCENT|FF_FOG)); return false; } From c98108df2764e1cdcd8537655d3b479be1b3b4ea Mon Sep 17 00:00:00 2001 From: Radicalicious Date: Thu, 3 Dec 2020 00:46:28 +0000 Subject: [PATCH 088/644] Revert "Update hw_light.c" This reverts commit b2544395926ed4c5f7ec02a91e486feb6ba5b78d --- src/hardware/hw_light.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/hardware/hw_light.c b/src/hardware/hw_light.c index 76fecd7aa..987d70c69 100644 --- a/src/hardware/hw_light.c +++ b/src/hardware/hw_light.c @@ -340,7 +340,6 @@ light_t *t_lspr[NUMSPRITES] = &lspr[NOLIGHT], // SPR_BMCH &lspr[NOLIGHT], // SPR_SMCE &lspr[NOLIGHT], // SPR_BMCE - &lspr[NOLIGHT], // SPR_BSPB &lspr[NOLIGHT], // SPR_YSPB &lspr[NOLIGHT], // SPR_RSPB &lspr[REDBALL_L], // SPR_SFBR From b5526312e7fb36ae58a27f44b3e6e979246ac42e Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Wed, 2 Dec 2020 19:47:00 -0600 Subject: [PATCH 089/644] Fix missing stuff --- src/deh_tables.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/deh_tables.c b/src/deh_tables.c index 5733d9b0e..3240aee14 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -4331,6 +4331,7 @@ const char *const MOBJFLAG2_LIST[] = { "AMBUSH", // Alternate behaviour typically set by MTF_AMBUSH "LINKDRAW", // Draw vissprite of mobj immediately before/after tracer's vissprite (dependent on dispoffset and position) "SHIELD", // Thinker calls P_AddShield/P_ShieldLook (must be partnered with MF_SCENERY to use) + "SPLAT", // Object is a splat NULL }; @@ -4871,6 +4872,36 @@ struct int_const_s const INT_CONST[] = { {"tr_trans90",tr_trans90}, {"NUMTRANSMAPS",NUMTRANSMAPS}, + // Alpha styles (blend modes) + {"AST_COPY",AST_COPY}, + {"AST_TRANSLUCENT",AST_TRANSLUCENT}, + {"AST_ADD",AST_ADD}, + {"AST_SUBTRACT",AST_SUBTRACT}, + {"AST_REVERSESUBTRACT",AST_REVERSESUBTRACT}, + {"AST_MODULATE",AST_MODULATE}, + {"AST_OVERLAY",AST_OVERLAY}, + + // Render flags + {"RF_HORIZONTALFLIP",RF_HORIZONTALFLIP}, + {"RF_VERTICALFLIP",RF_VERTICALFLIP}, + {"RF_ABSOLUTEOFFSETS",RF_ABSOLUTEOFFSETS}, + {"RF_FLIPOFFSETS",RF_FLIPOFFSETS}, + {"RF_SPLATMASK",RF_SLOPESPLAT}, + {"RF_SLOPESPLAT",RF_SLOPESPLAT}, + {"RF_OBJECTSLOPESPLAT",RF_OBJECTSLOPESPLAT}, + {"RF_NOSPLATBILLBOARD",RF_NOSPLATBILLBOARD}, + {"RF_NOSPLATROLLANGLE",RF_NOSPLATROLLANGLE}, + {"RF_BLENDMASK",RF_BLENDMASK}, + {"RF_FULLBRIGHT",RF_FULLBRIGHT}, + {"RF_FULLDARK",RF_FULLDARK}, + {"RF_NOCOLORMAPS",RF_NOCOLORMAPS}, + {"RF_SPRITETYPEMASK",RF_SPRITETYPEMASK}, + {"RF_PAPERSPRITE",RF_PAPERSPRITE}, + {"RF_FLOORSPRITE",RF_FLOORSPRITE}, + {"RF_SHADOWDRAW",RF_SHADOWDRAW}, + {"RF_SHADOWEFFECTS",RF_SHADOWEFFECTS}, + {"RF_DROPSHADOW",RF_DROPSHADOW}, + // Level flags {"LF_SCRIPTISFILE",LF_SCRIPTISFILE}, {"LF_SPEEDMUSIC",LF_SPEEDMUSIC}, From c28bd8005eea0cf8ab83326ddb1b0d35deca0e9d Mon Sep 17 00:00:00 2001 From: Zippy_Zolton Date: Thu, 3 Dec 2020 01:28:54 -0600 Subject: [PATCH 090/644] Fix fire objects disappearing in lava --- src/p_mobj.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 7ba6d1fad..d06e57d66 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7937,7 +7937,7 @@ static boolean P_MobjPushableThink(mobj_t *mobj) P_PushableThinker(mobj); // Extinguish fire objects in water. (Yes, it's extraordinarily rare to have a pushable flame object, but Brak uses such a case.) - if (mobj->flags & MF_FIRE && mobj->type != MT_PUMA && mobj->type != MT_FIREBALL + if (mobj->flags & MF_FIRE && mobj->eflags ! MFE_TOUCHLAVA && (mobj->eflags & (MFE_UNDERWATER | MFE_TOUCHWATER))) { P_KillMobj(mobj, NULL, NULL, 0); @@ -9705,7 +9705,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) P_MobjCheckWater(mobj); // Extinguish fire objects in water - if (mobj->flags & MF_FIRE && mobj->type != MT_PUMA && mobj->type != MT_FIREBALL + if (mobj->flags & MF_FIRE && mobj->eflags ! MFE_TOUCHLAVA && (mobj->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER))) { P_KillMobj(mobj, NULL, NULL, 0); From 29f56fb2d8c3dc7d2010023278433aad10481960 Mon Sep 17 00:00:00 2001 From: Zippy_Zolton Date: Thu, 3 Dec 2020 02:05:10 -0600 Subject: [PATCH 091/644] g --- src/p_mobj.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index d06e57d66..4494c72b7 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7937,7 +7937,7 @@ static boolean P_MobjPushableThink(mobj_t *mobj) P_PushableThinker(mobj); // Extinguish fire objects in water. (Yes, it's extraordinarily rare to have a pushable flame object, but Brak uses such a case.) - if (mobj->flags & MF_FIRE && mobj->eflags ! MFE_TOUCHLAVA + if ((mobj->flags & MF_FIRE) && !(mobj->eflags & MFE_TOUCHLAVA) && (mobj->eflags & (MFE_UNDERWATER | MFE_TOUCHWATER))) { P_KillMobj(mobj, NULL, NULL, 0); @@ -9705,7 +9705,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) P_MobjCheckWater(mobj); // Extinguish fire objects in water - if (mobj->flags & MF_FIRE && mobj->eflags ! MFE_TOUCHLAVA + if ((mobj->flags & MF_FIRE) && !(mobj->eflags & MFE_TOUCHLAVA) && (mobj->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER))) { P_KillMobj(mobj, NULL, NULL, 0); From fae845f935db2973da75e5f74197ada426bcd9a8 Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+Ikkarin@users.noreply.github.com> Date: Thu, 3 Dec 2020 17:50:10 -0300 Subject: [PATCH 092/644] Initialize in p_spec.c too + magic number replacement --- src/p_spec.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index a1afdd00d..4996573a9 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4420,15 +4420,19 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers // clear the special so you can't push the button twice. sector->special = 0; + // Initialize my junk + junk.tags.tags = NULL; + junk.tags.count = 0; + // Move the button down - Tag_FSet(&junk.tags, 680); + Tag_FSet(&junk.tags, LE_CAPSULE0); EV_DoElevator(&junk, elevateDown, false); // Open the top FOF - Tag_FSet(&junk.tags, 681); + Tag_FSet(&junk.tags, LE_CAPSULE1); EV_DoFloor(&junk, raiseFloorToNearestFast); // Open the bottom FOF - Tag_FSet(&junk.tags, 682); + Tag_FSet(&junk.tags, LE_CAPSULE2); EV_DoCeiling(&junk, lowerToLowestFast); // Mark all players with the time to exit thingy! From 4c53eabc59c8d2d60d90d9019cf5b1939b627647 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Thu, 3 Dec 2020 21:14:27 -0500 Subject: [PATCH 093/644] Reword the error to be more consistent with other errors --- src/lua_skinlib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lua_skinlib.c b/src/lua_skinlib.c index e2f16756a..ea368a9cd 100644 --- a/src/lua_skinlib.c +++ b/src/lua_skinlib.c @@ -340,7 +340,7 @@ static int lib_getSkinSprite(lua_State *L) playersprite_t i = luaL_checkinteger(L, 2); if (i < 0 || i >= NUMPLAYERSPRITES*2) - return luaL_error(L, "skin.sprites[] index %d out of range (0 - %d)", i, (NUMPLAYERSPRITES*2)-1); + return luaL_error(L, LUA_QL("skin_t") " field 'sprites' index %d out of range (0 - %d)", i, (NUMPLAYERSPRITES*2)-1); LUA_PushLightUserdata(L, &sprites[i], META_SKINSPRITESLIST); return 1; From 2017eb4d9ed67f880c9c418561073c358762c679 Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Wed, 2 Dec 2020 16:57:08 -0300 Subject: [PATCH 094/644] Fix polyobject segs messing with 3D floors they shouldn't be --- src/r_segs.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/r_segs.c b/src/r_segs.c index 1ed1f0285..7c913e023 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -1477,10 +1477,18 @@ static void R_RenderSegLoop (void) } for (i = 0; i < numffloors; i++) + { + if (curline->polyseg && (ffloor[i].polyobj != curline->polyseg)) + continue; + ffloor[i].f_frac += ffloor[i].f_step; + } for (i = 0; i < numbackffloors; i++) { + if (curline->polyseg && (ffloor[i].polyobj != curline->polyseg)) + continue; + ffloor[i].f_clip[rw_x] = ffloor[i].c_clip[rw_x] = (INT16)((ffloor[i].b_frac >> HEIGHTBITS) & 0xFFFF); ffloor[i].b_frac += ffloor[i].b_step; } From 621efbfa158e49a33f6ba8a55c267cb10f85b602 Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 4 Dec 2020 00:30:08 -0800 Subject: [PATCH 095/644] Lua taglib for accessing taggroups The global "tags" can be iterated upon for every unique tag which is set in the level. If a tag is set on a sector/line/thing, it will be included. Taking the length of "tags" will give you the number of these unique tags. (If a tag is set on multiple sectors/lines/things, it will only be counted once though.) For sectors, lines and mapthings, call the field "tagged". This function takes one argument, which is the tag. The return value can be iterated over for all the sectors/lines/things with that tag. The length can also be taken for the number of such objects. If no argument is given, the global tag is default. --- src/CMakeLists.txt | 1 + src/blua/Makefile.cfg | 1 + src/doomtype.h | 22 +++++++++++ src/lua_libs.h | 1 + src/lua_maplib.c | 60 +++++++++-------------------- src/lua_mobjlib.c | 31 +++++---------- src/lua_script.c | 59 ++++++++++++++++++++++++++-- src/lua_script.h | 48 ++++++++++++++++++++--- src/taglist.c | 90 +++++++++++++++++++++++-------------------- src/taglist.h | 10 +++++ 10 files changed, 208 insertions(+), 115 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d35e774e9..87a0499b6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -276,6 +276,7 @@ set(SRB2_LUA_SOURCES lua_hudlib.c lua_infolib.c lua_maplib.c + lua_taglib.c lua_mathlib.c lua_mobjlib.c lua_playerlib.c diff --git a/src/blua/Makefile.cfg b/src/blua/Makefile.cfg index eae95ba3a..3a2962e65 100644 --- a/src/blua/Makefile.cfg +++ b/src/blua/Makefile.cfg @@ -47,6 +47,7 @@ OBJS:=$(OBJS) \ $(OBJDIR)/lua_skinlib.o \ $(OBJDIR)/lua_thinkerlib.o \ $(OBJDIR)/lua_maplib.o \ + $(OBJDIR)/lua_taglib.o \ $(OBJDIR)/lua_polyobjlib.o \ $(OBJDIR)/lua_blockmaplib.o \ $(OBJDIR)/lua_hudlib.o diff --git a/src/doomtype.h b/src/doomtype.h index 4e13ba96d..08317c65a 100644 --- a/src/doomtype.h +++ b/src/doomtype.h @@ -379,4 +379,26 @@ Needed for some lua shenanigans. #define FIELDFROM( type, field, have, want ) \ (void *)((intptr_t)(field) - offsetof (type, have) + offsetof (type, want)) +typedef UINT8 bitarray_t; + +#define BIT_ARRAY_SIZE(n) (((n) + 7) >> 3) + +static inline int +in_bit_array (const bitarray_t * const array, const int value) +{ + return (array[value >> 3] & (1<<(value & 7))); +} + +static inline void +set_bit_array (bitarray_t * const array, const int value) +{ + array[value >> 3] |= (1<<(value & 7)); +} + +static inline void +unset_bit_array (bitarray_t * const array, const int value) +{ + array[value >> 3] &= ~(1<<(value & 7)); +} + #endif //__DOOMTYPE__ diff --git a/src/lua_libs.h b/src/lua_libs.h index 062a3fe50..aa0638683 100644 --- a/src/lua_libs.h +++ b/src/lua_libs.h @@ -93,6 +93,7 @@ int LUA_PlayerLib(lua_State *L); int LUA_SkinLib(lua_State *L); int LUA_ThinkerLib(lua_State *L); int LUA_MapLib(lua_State *L); +int LUA_TagLib(lua_State *L); int LUA_PolyObjLib(lua_State *L); int LUA_BlockmapLib(lua_State *L); int LUA_HudLib(lua_State *L); diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 95cc8c101..a3df28cca 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -1385,25 +1385,15 @@ static int lib_iterateSectors(lua_State *L) static int lib_getSector(lua_State *L) { - int field; INLEVEL - lua_settop(L, 2); - lua_remove(L, 1); // dummy userdata table is unused. - if (lua_isnumber(L, 1)) + if (lua_isnumber(L, 2)) { - size_t i = lua_tointeger(L, 1); + size_t i = lua_tointeger(L, 2); if (i >= numsectors) return 0; LUA_PushUserdata(L, §ors[i], META_SECTOR); return 1; } - field = luaL_checkoption(L, 1, NULL, array_opt); - switch(field) - { - case 0: // iterate - lua_pushcfunction(L, lib_iterateSectors); - return 1; - } return 0; } @@ -1489,25 +1479,15 @@ static int lib_iterateLines(lua_State *L) static int lib_getLine(lua_State *L) { - int field; INLEVEL - lua_settop(L, 2); - lua_remove(L, 1); // dummy userdata table is unused. - if (lua_isnumber(L, 1)) + if (lua_isnumber(L, 2)) { - size_t i = lua_tointeger(L, 1); + size_t i = lua_tointeger(L, 2); if (i >= numlines) return 0; LUA_PushUserdata(L, &lines[i], META_LINE); return 1; } - field = luaL_checkoption(L, 1, NULL, array_opt); - switch(field) - { - case 0: // iterate - lua_pushcfunction(L, lib_iterateLines); - return 1; - } return 0; } @@ -2358,15 +2338,13 @@ int LUA_MapLib(lua_State *L) //lua_setfield(L, -2, "__len"); lua_pop(L, 1); - lua_newuserdata(L, 0); - lua_createtable(L, 0, 2); - lua_pushcfunction(L, lib_getSector); - lua_setfield(L, -2, "__index"); - - lua_pushcfunction(L, lib_numsectors); - lua_setfield(L, -2, "__len"); - lua_setmetatable(L, -2); - lua_setglobal(L, "sectors"); + LUA_PushTaggableObjectArray(L, "sectors", + lib_iterateSectors, + lib_getSector, + lib_numsectors, + tags_sectors, + &numsectors, §ors, + sizeof (sector_t), META_SECTOR); lua_newuserdata(L, 0); lua_createtable(L, 0, 2); @@ -2378,15 +2356,13 @@ int LUA_MapLib(lua_State *L) lua_setmetatable(L, -2); lua_setglobal(L, "subsectors"); - lua_newuserdata(L, 0); - lua_createtable(L, 0, 2); - lua_pushcfunction(L, lib_getLine); - lua_setfield(L, -2, "__index"); - - lua_pushcfunction(L, lib_numlines); - lua_setfield(L, -2, "__len"); - lua_setmetatable(L, -2); - lua_setglobal(L, "lines"); + LUA_PushTaggableObjectArray(L, "lines", + lib_iterateLines, + lib_getLine, + lib_numlines, + tags_lines, + &numlines, &lines, + sizeof (line_t), META_LINE); lua_newuserdata(L, 0); lua_createtable(L, 0, 2); diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index 7aae18c90..134f104ee 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -22,8 +22,6 @@ #include "lua_hud.h" // hud_running errors #include "lua_hook.h" // hook_cmd_running errors -static const char *const array_opt[] ={"iterate",NULL}; - enum mobj_e { mobj_valid = 0, mobj_x, @@ -1003,25 +1001,15 @@ static int lib_iterateMapthings(lua_State *L) static int lib_getMapthing(lua_State *L) { - int field; INLEVEL - lua_settop(L, 2); - lua_remove(L, 1); // dummy userdata table is unused. - if (lua_isnumber(L, 1)) + if (lua_isnumber(L, 2)) { - size_t i = lua_tointeger(L, 1); + size_t i = lua_tointeger(L, 2); if (i >= nummapthings) return 0; LUA_PushUserdata(L, &mapthings[i], META_MAPTHING); return 1; } - field = luaL_checkoption(L, 1, NULL, array_opt); - switch(field) - { - case 0: // iterate - lua_pushcfunction(L, lib_iterateMapthings); - return 1; - } return 0; } @@ -1068,14 +1056,13 @@ int LUA_MobjLib(lua_State *L) lua_setfield(L, -2, "__len"); lua_pop(L,1); - lua_newuserdata(L, 0); - lua_createtable(L, 0, 2); - lua_pushcfunction(L, lib_getMapthing); - lua_setfield(L, -2, "__index"); + LUA_PushTaggableObjectArray(L, "mapthings", + lib_iterateMapthings, + lib_getMapthing, + lib_nummapthings, + tags_mapthings, + &nummapthings, &mapthings, + sizeof (mapthing_t), META_MAPTHING); - lua_pushcfunction(L, lib_nummapthings); - lua_setfield(L, -2, "__len"); - lua_setmetatable(L, -2); - lua_setglobal(L, "mapthings"); return 0; } diff --git a/src/lua_script.c b/src/lua_script.c index eb4737f76..ee60a41c6 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -53,6 +53,7 @@ static lua_CFunction liblist[] = { LUA_SkinLib, // skin_t, skins[] LUA_ThinkerLib, // thinker_t LUA_MapLib, // line_t, side_t, sector_t, subsector_t + LUA_TagLib, // tags LUA_PolyObjLib, // polyobj_t LUA_BlockmapLib, // blockmap stuff LUA_HudLib, // HUD stuff @@ -739,25 +740,37 @@ void LUA_PushLightUserdata (lua_State *L, void *data, const char *meta) // Pushes it to the stack and stores it in the registry. void LUA_PushUserdata(lua_State *L, void *data, const char *meta) { + if (LUA_RawPushUserdata(L, data) == LPUSHED_NEW) + { + luaL_getmetatable(L, meta); + lua_setmetatable(L, -2); + } +} + +// Same as LUA_PushUserdata but don't set a metatable yet. +lpushed_t LUA_RawPushUserdata(lua_State *L, void *data) +{ + lpushed_t status = LPUSHED_NIL; + void **userdata; if (!data) { // push a NULL lua_pushnil(L); - return; + return status; } lua_getfield(L, LUA_REGISTRYINDEX, LREG_VALID); I_Assert(lua_istable(L, -1)); + lua_pushlightuserdata(L, data); lua_rawget(L, -2); + if (lua_isnil(L, -1)) { // no userdata? deary me, we'll have to make one. lua_pop(L, 1); // pop the nil // create the userdata userdata = lua_newuserdata(L, sizeof(void *)); *userdata = data; - luaL_getmetatable(L, meta); - lua_setmetatable(L, -2); // Set it in the registry so we can find it again lua_pushlightuserdata(L, data); // k (store the userdata via the data's pointer) @@ -765,8 +778,15 @@ void LUA_PushUserdata(lua_State *L, void *data, const char *meta) lua_rawset(L, -4); // stack is left with the userdata on top, as if getting it had originally succeeded. + + status = LPUSHED_NEW; } + else + status = LPUSHED_EXISTING; + lua_remove(L, -2); // remove LREG_VALID + + return status; } // When userdata is freed, use this function to remove it from Lua. @@ -1681,3 +1701,36 @@ int Lua_optoption(lua_State *L, int narg, return i; return -1; } + +void LUA_PushTaggableObjectArray +( lua_State *L, + const char *field, + lua_CFunction iterator, + lua_CFunction indexer, + lua_CFunction counter, + taggroup_t *garray[], + size_t * max_elements, + void * element_array, + size_t sizeof_element, + const char *meta) +{ + lua_newuserdata(L, 0); + lua_createtable(L, 0, 2); + lua_createtable(L, 0, 2); + lua_pushcfunction(L, iterator); + lua_setfield(L, -2, "iterate"); + + LUA_InsertTaggroupIterator(L, garray, + max_elements, element_array, sizeof_element, meta); + + lua_createtable(L, 0, 1); + lua_pushcfunction(L, indexer); + lua_setfield(L, -2, "__index"); + lua_setmetatable(L, -2); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, counter); + lua_setfield(L, -2, "__len"); + lua_setmetatable(L, -2); + lua_setglobal(L, field); +} diff --git a/src/lua_script.h b/src/lua_script.h index 79ba0bb38..2dc34446a 100644 --- a/src/lua_script.h +++ b/src/lua_script.h @@ -10,10 +10,14 @@ /// \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" #include "g_state.h" +#include "taglist.h" #include "blua/lua.h" #include "blua/lualib.h" @@ -46,12 +50,6 @@ void LUA_LoadLump(UINT16 wad, UINT16 lump, boolean noresults); void LUA_DumpFile(const char *filename); #endif fixed_t LUA_EvalMath(const char *word); -void LUA_PushLightUserdata(lua_State *L, void *data, const char *meta); -void LUA_PushUserdata(lua_State *L, void *data, const char *meta); -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_Archive(void); void LUA_UnArchive(void); @@ -63,6 +61,42 @@ int Lua_optoption(lua_State *L, int narg, const char *def, const char *const lst[]); void LUAh_NetArchiveHook(lua_CFunction archFunc); +void LUA_PushTaggableObjectArray +( lua_State *L, + const char *field, + lua_CFunction iterator, + lua_CFunction indexer, + lua_CFunction counter, + taggroup_t *garray[], + size_t * max_elements, + void * element_array, + size_t sizeof_element, + const char *meta); + +void LUA_InsertTaggroupIterator +( lua_State *L, + taggroup_t *garray[], + size_t * max_elements, + void * element_array, + size_t sizeof_element, + const char * meta); + +typedef enum { + LPUSHED_NIL, + LPUSHED_NEW, + LPUSHED_EXISTING, +} lpushed_t; + +void LUA_PushLightUserdata(lua_State *L, void *data, const char *meta); +void LUA_PushUserdata(lua_State *L, void *data, const char *meta); +lpushed_t LUA_RawPushUserdata(lua_State *L, void *data); + +void LUA_InvalidateUserdata(void *data); + +void LUA_InvalidateLevel(void); +void LUA_InvalidateMapthings(void); +void LUA_InvalidatePlayer(player_t *player); + // Console wrapper void COM_Lua_f(void); @@ -98,3 +132,5 @@ void COM_Lua_f(void); #define INLEVEL if (! ISINLEVEL)\ return luaL_error(L, "This can only be used in a level!"); + +#endif/*LUA_SCRIPT_H*/ diff --git a/src/taglist.c b/src/taglist.c index b11216b6c..658605734 100644 --- a/src/taglist.c +++ b/src/taglist.c @@ -15,6 +15,11 @@ #include "z_zone.h" #include "r_data.h" +// Bit array of whether a tag exists for sectors/lines/things. +bitarray_t tags_available[BIT_ARRAY_SIZE (MAXTAGS)]; + +size_t num_tags; + // Taggroups are used to list elements of the same tag, for iteration. // Since elements can now have multiple tags, it means an element may appear // in several taggroups at the same time. These are built on level load. @@ -105,6 +110,33 @@ size_t Taggroup_Find (const taggroup_t *group, const size_t id) return -1; } +/// Iterate thru elements in a global taggroup. +INT32 Taggroup_Iterate +( taggroup_t *garray[], + const size_t max_elements, + const mtag_t tag, + const size_t p) +{ + const taggroup_t *group; + + if (tag == MTAG_GLOBAL) + { + if (p < max_elements) + return p; + return -1; + } + + group = garray[(UINT16)tag]; + + if (group) + { + if (p < group->count) + return group->elements[p]; + return -1; + } + return -1; +} + /// Add an element to a global taggroup. void Taggroup_Add (taggroup_t *garray[], const mtag_t tag, size_t id) { @@ -120,6 +152,11 @@ void Taggroup_Add (taggroup_t *garray[], const mtag_t tag, size_t id) if (Taggroup_Find(group, id) != (size_t)-1) return; + if (! in_bit_array(tags_available, tag)) + num_tags++; + + set_bit_array(tags_available, tag); + // Create group if empty. if (!group) { @@ -161,6 +198,11 @@ void Taggroup_Remove (taggroup_t *garray[], const mtag_t tag, size_t id) if ((rempos = Taggroup_Find(group, id)) == (size_t)-1) return; + if (in_bit_array(tags_available, tag)) + num_tags--; + + unset_bit_array(tags_available, tag); + // Strip away taggroup if no elements left. if (!(newcount = --group->count)) { @@ -209,6 +251,9 @@ void Taglist_InitGlobalTables(void) { size_t i, j; + memset(tags_available, 0, sizeof tags_available); + num_tags = 0; + for (i = 0; i < MAXTAGS; i++) { tags_sectors[i] = NULL; @@ -236,56 +281,17 @@ void Taglist_InitGlobalTables(void) INT32 Tag_Iterate_Sectors (const mtag_t tag, const size_t p) { - if (tag == MTAG_GLOBAL) - { - if (p < numsectors) - return p; - return -1; - } - - if (tags_sectors[(UINT16)tag]) - { - if (p < tags_sectors[(UINT16)tag]->count) - return tags_sectors[(UINT16)tag]->elements[p]; - return -1; - } - return -1; + return Taggroup_Iterate(tags_sectors, numsectors, tag, p); } INT32 Tag_Iterate_Lines (const mtag_t tag, const size_t p) { - if (tag == MTAG_GLOBAL) - { - if (p < numlines) - return p; - return -1; - } - - if (tags_lines[(UINT16)tag]) - { - if (p < tags_lines[(UINT16)tag]->count) - return tags_lines[(UINT16)tag]->elements[p]; - return -1; - } - return -1; + return Taggroup_Iterate(tags_lines, numlines, tag, p); } INT32 Tag_Iterate_Things (const mtag_t tag, const size_t p) { - if (tag == MTAG_GLOBAL) - { - if (p < nummapthings) - return p; - return -1; - } - - if (tags_mapthings[(UINT16)tag]) - { - if (p < tags_mapthings[(UINT16)tag]->count) - return tags_mapthings[(UINT16)tag]->elements[p]; - return -1; - } - return -1; + return Taggroup_Iterate(tags_mapthings, nummapthings, tag, p); } INT32 Tag_FindLineSpecial(const INT16 special, const mtag_t tag) diff --git a/src/taglist.h b/src/taglist.h index 0e6d9f842..e5db08806 100644 --- a/src/taglist.h +++ b/src/taglist.h @@ -43,6 +43,10 @@ typedef struct size_t count; } taggroup_t; +extern bitarray_t tags_available[]; + +extern size_t num_tags; + extern taggroup_t* tags_sectors[]; extern taggroup_t* tags_lines[]; extern taggroup_t* tags_mapthings[]; @@ -51,6 +55,12 @@ void Taggroup_Add (taggroup_t *garray[], const mtag_t tag, size_t id); void Taggroup_Remove (taggroup_t *garray[], const mtag_t tag, size_t id); size_t Taggroup_Find (const taggroup_t *group, const size_t id); +INT32 Taggroup_Iterate +( taggroup_t *garray[], + const size_t max_elements, + const mtag_t tag, + const size_t p); + void Taglist_InitGlobalTables(void); INT32 Tag_Iterate_Sectors (const mtag_t tag, const size_t p); From 96851e52a10bb87c02fcc579a8407a003d9f7be5 Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 4 Dec 2020 02:27:14 -0800 Subject: [PATCH 096/644] hehehehehe what if I forgot to git add? --- src/lua_taglib.c | 186 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 186 insertions(+) create mode 100644 src/lua_taglib.c diff --git a/src/lua_taglib.c b/src/lua_taglib.c new file mode 100644 index 000000000..e6c82fea3 --- /dev/null +++ b/src/lua_taglib.c @@ -0,0 +1,186 @@ +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 2020 by James R. +// Copyright (C) 2020 by Sonic Team Junior. +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- +/// \file lua_taglib.c +/// \brief tag list iterator for Lua scripting + +#include "doomdef.h" +#include "taglist.h" +#include "r_state.h" + +#include "lua_script.h" +#include "lua_libs.h" + +static int tag_iterator(lua_State *L) +{ + INT32 tag = lua_isnil(L, 2) ? -1 : lua_tonumber(L, 2); + do + { + if (++tag >= MAXTAGS) + return 0; + } + while (! in_bit_array(tags_available, tag)) ; + lua_pushnumber(L, tag); + return 1; +} + +enum { +#define UPVALUE lua_upvalueindex + up_garray = UPVALUE(1), + up_max_elements = UPVALUE(2), + up_element_array = UPVALUE(3), + up_sizeof_element = UPVALUE(4), + up_meta = UPVALUE(5), +#undef UPVALUE +}; + +static INT32 next_element(lua_State *L, const mtag_t tag, const size_t p) +{ + taggroup_t ** garray = lua_touserdata(L, up_garray); + const size_t * max_elements = lua_touserdata(L, up_max_elements); + return Taggroup_Iterate(garray, *max_elements, tag, p); +} + +static void push_element(lua_State *L, void *element) +{ + if (LUA_RawPushUserdata(L, element) == LPUSHED_NEW) + { + lua_pushvalue(L, up_meta); + lua_setmetatable(L, -2); + } +} + +static void push_next_element(lua_State *L, const INT32 element) +{ + char * element_array = *(char **)lua_touserdata(L, up_element_array); + const size_t sizeof_element = lua_tonumber(L, up_sizeof_element); + push_element(L, &element_array[element * sizeof_element]); +} + +struct element_iterator_state { + mtag_t tag; + size_t p; +}; + +static int element_iterator(lua_State *L) +{ + struct element_iterator_state * state = lua_touserdata(L, 1); + const INT32 element = next_element(L, state->tag, state->p); + + if (element == -1) + return 0; + else + { + push_next_element(L, element); + state->p++; + return 1; + } +} + +static int lib_iterateTags(lua_State *L) +{ + if (lua_gettop(L) < 2) + { + lua_pushcfunction(L, tag_iterator); + return 1; + } + else + return tag_iterator(L); +} + +static int lib_numTags(lua_State *L) +{ + lua_pushnumber(L, num_tags); + return 1; +} + +static int lib_getTaggroup(lua_State *L) +{ + struct element_iterator_state *state; + + mtag_t tag; + + if (lua_gettop(L) > 1) + return luaL_error(L, "too many arguments"); + + if (lua_isnoneornil(L, 1)) + { + tag = MTAG_GLOBAL; + } + else + { + tag = lua_tonumber(L, 1); + luaL_argcheck(L, tag >= -1, 1, "tag out of range"); + } + + state = lua_newuserdata(L, sizeof *state); + state->tag = tag; + state->p = 0; + + lua_pushvalue(L, lua_upvalueindex(1)); + lua_setmetatable(L, -2); + + return 1; +} + +static int lib_numTaggroupElements(lua_State *L) +{ + const mtag_t tag = *(mtag_t *)lua_touserdata(L, 1); + if (tag == MTAG_GLOBAL) + lua_pushnumber(L, *(size_t *)lua_touserdata(L, up_max_elements)); + else + { + const taggroup_t ** garray = lua_touserdata(L, up_garray); + lua_pushnumber(L, garray[tag] ? garray[tag]->count : 0); + } + return 1; +} + +void LUA_InsertTaggroupIterator +( lua_State *L, + taggroup_t *garray[], + size_t * max_elements, + void * element_array, + size_t sizeof_element, + const char * meta) +{ + lua_createtable(L, 0, 2); + lua_pushlightuserdata(L, garray); + lua_pushlightuserdata(L, max_elements); + + lua_pushvalue(L, -2); + lua_pushvalue(L, -2); + lua_pushlightuserdata(L, element_array); + lua_pushnumber(L, sizeof_element); + luaL_getmetatable(L, meta); + lua_pushcclosure(L, element_iterator, 5); + lua_setfield(L, -4, "__call"); + + lua_pushcclosure(L, lib_numTaggroupElements, 2); + lua_setfield(L, -2, "__len"); + lua_pushcclosure(L, lib_getTaggroup, 1); + lua_setfield(L, -2, "tagged"); +} + +int LUA_TagLib(lua_State *L) +{ + lua_newuserdata(L, 0); + lua_createtable(L, 0, 2); + lua_createtable(L, 0, 1); + lua_pushcfunction(L, lib_iterateTags); + lua_setfield(L, -2, "iterate"); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, lib_numTags); + lua_setfield(L, -2, "__len"); + lua_setmetatable(L, -2); + lua_setglobal(L, "tags"); + + return 0; +} From c2217bb42689502a9511a752b6e6aae3fc60aa07 Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 4 Dec 2020 04:54:12 -0800 Subject: [PATCH 097/644] Mkae Lua taggroups indexable They are 1-indexed. --- src/lua_taglib.c | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/src/lua_taglib.c b/src/lua_taglib.c index e6c82fea3..2e2a0d277 100644 --- a/src/lua_taglib.c +++ b/src/lua_taglib.c @@ -71,16 +71,9 @@ struct element_iterator_state { static int element_iterator(lua_State *L) { struct element_iterator_state * state = lua_touserdata(L, 1); - const INT32 element = next_element(L, state->tag, state->p); - - if (element == -1) - return 0; - else - { - push_next_element(L, element); - state->p++; - return 1; - } + lua_pushnumber(L, ++state->p); + lua_gettable(L, 1); + return 1; } static int lib_iterateTags(lua_State *L) @@ -129,6 +122,21 @@ static int lib_getTaggroup(lua_State *L) return 1; } +static int lib_getTaggroupElement(lua_State *L) +{ + const size_t p = luaL_checknumber(L, 2) - 1; + const mtag_t tag = *(mtag_t *)lua_touserdata(L, 1); + const INT32 element = next_element(L, tag, p); + + if (element == -1) + return 0; + else + { + push_next_element(L, element); + return 1; + } +} + static int lib_numTaggroupElements(lua_State *L) { const mtag_t tag = *(mtag_t *)lua_touserdata(L, 1); @@ -150,7 +158,7 @@ void LUA_InsertTaggroupIterator size_t sizeof_element, const char * meta) { - lua_createtable(L, 0, 2); + lua_createtable(L, 0, 3); lua_pushlightuserdata(L, garray); lua_pushlightuserdata(L, max_elements); @@ -159,11 +167,14 @@ void LUA_InsertTaggroupIterator lua_pushlightuserdata(L, element_array); lua_pushnumber(L, sizeof_element); luaL_getmetatable(L, meta); - lua_pushcclosure(L, element_iterator, 5); - lua_setfield(L, -4, "__call"); + lua_pushcclosure(L, lib_getTaggroupElement, 5); + lua_setfield(L, -4, "__index"); lua_pushcclosure(L, lib_numTaggroupElements, 2); lua_setfield(L, -2, "__len"); + + lua_pushcfunction(L, element_iterator); + lua_setfield(L, -2, "__call"); lua_pushcclosure(L, lib_getTaggroup, 1); lua_setfield(L, -2, "tagged"); } From 314fd2783a2b22c2803b9063994a2dd48ddd98a7 Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 4 Dec 2020 13:47:22 -0800 Subject: [PATCH 098/644] Lua tag lists Index and take length of tag lists like a table, 1-indexed. There are three methods which may be used on tag lists: list:iterate() - returns an iterator over the tags in the list list:has(tag) - returns a boolean whether the tag is in the list list.shares(list2) - returns whether two lists share a tag "find" is also an alias to "has". Each method may be accessed from the global taglist library too, e.g. taglist.iterate(list) Tag lists may be compared with an equality operator too. This will tell you if the two lists are composed of identical tags. Accessible from sector.taglist, line.taglist and mapthing.taglist. --- src/lua_baselib.c | 3 + src/lua_libs.h | 3 + src/lua_maplib.c | 12 ++++ src/lua_mobjlib.c | 7 +++ src/lua_script.h | 2 + src/lua_taglib.c | 156 ++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 183 insertions(+) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 4667fdbf4..1324322a2 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -184,12 +184,15 @@ static const struct { {META_CVAR, "consvar_t"}, {META_SECTORLINES, "sector_t.lines"}, + {META_SECTORTAGLIST, "sector_t.taglist"}, {META_SIDENUM, "line_t.sidenum"}, {META_LINEARGS, "line_t.args"}, {META_LINESTRINGARGS, "line_t.stringargs"}, + {META_LINETAGLIST, "line_t.taglist"}, {META_THINGARGS, "mapthing.args"}, {META_THINGSTRINGARGS, "mapthing.stringargs"}, + {META_THINGTAGLIST, "mapthing_t.taglist"}, #ifdef HAVE_LUA_SEGS {META_NODEBBOX, "node_t.bbox"}, {META_NODECHILDREN, "node_t.children"}, diff --git a/src/lua_libs.h b/src/lua_libs.h index aa0638683..991fae3fd 100644 --- a/src/lua_libs.h +++ b/src/lua_libs.h @@ -56,11 +56,14 @@ extern lua_State *gL; #define META_CVAR "CONSVAR_T*" #define META_SECTORLINES "SECTOR_T*LINES" +#define META_SECTORTAGLIST "SECTOR_T*TAGLIST" #define META_SIDENUM "LINE_T*SIDENUM" #define META_LINEARGS "LINE_T*ARGS" #define META_LINESTRINGARGS "LINE_T*STRINGARGS" +#define META_LINETAGLIST "LINE_T*TAGLIST" #define META_THINGARGS "MAPTHING_T*ARGS" #define META_THINGSTRINGARGS "MAPTHING_T*STRINGARGS" +#define META_THINGTAGLIST "THING_T*TAGLIST" #define META_POLYOBJVERTICES "POLYOBJ_T*VERTICES" #define META_POLYOBJLINES "POLYOBJ_T*LINES" #ifdef HAVE_LUA_SEGS diff --git a/src/lua_maplib.c b/src/lua_maplib.c index a3df28cca..25edf83d8 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -37,6 +37,7 @@ enum sector_e { sector_lightlevel, sector_special, sector_tag, + sector_taglist, sector_thinglist, sector_heightsec, sector_camsec, @@ -55,6 +56,7 @@ static const char *const sector_opt[] = { "lightlevel", "special", "tag", + "taglist", "thinglist", "heightsec", "camsec", @@ -89,6 +91,7 @@ enum line_e { line_flags, line_special, line_tag, + line_taglist, line_args, line_stringargs, line_sidenum, @@ -113,6 +116,7 @@ static const char *const line_opt[] = { "flags", "special", "tag", + "taglist", "args", "stringargs", "sidenum", @@ -581,6 +585,9 @@ static int sector_get(lua_State *L) case sector_tag: lua_pushinteger(L, Tag_FGet(§or->tags)); return 1; + case sector_taglist: + LUA_PushUserdata(L, §or->tags, META_SECTORTAGLIST); + return 1; case sector_thinglist: // thinglist lua_pushcfunction(L, lib_iterateSectorThinglist); LUA_PushUserdata(L, sector->thinglist, META_MOBJ); @@ -682,6 +689,8 @@ static int sector_set(lua_State *L) case sector_tag: Tag_SectorFSet((UINT32)(sector - sectors), (INT16)luaL_checkinteger(L, 3)); break; + case sector_taglist: + return LUA_ErrSetDirectly(L, "sector_t", "taglist"); } return 0; } @@ -821,6 +830,9 @@ static int line_get(lua_State *L) case line_tag: lua_pushinteger(L, Tag_FGet(&line->tags)); return 1; + case line_taglist: + LUA_PushUserdata(L, &line->tags, META_LINETAGLIST); + return 1; case line_args: LUA_PushUserdata(L, line->args, META_LINEARGS); return 1; diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index 134f104ee..8d205780d 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -902,6 +902,11 @@ static int mapthing_get(lua_State *L) number = mt->extrainfo; else if(fastcmp(field,"tag")) number = Tag_FGet(&mt->tags); + else if(fastcmp(field,"taglist")) + { + LUA_PushUserdata(L, &mt->tags, META_THINGTAGLIST); + return 1; + } else if(fastcmp(field,"args")) { LUA_PushUserdata(L, mt->args, META_THINGARGS); @@ -964,6 +969,8 @@ static int mapthing_set(lua_State *L) } else if (fastcmp(field,"tag")) Tag_FSet(&mt->tags, (INT16)luaL_checkinteger(L, 3)); + else if (fastcmp(field,"taglist")) + return LUA_ErrSetDirectly(L, "mapthing_t", "taglist"); else if(fastcmp(field,"mobj")) mt->mobj = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); else diff --git a/src/lua_script.h b/src/lua_script.h index 2dc34446a..77fbb7c1d 100644 --- a/src/lua_script.h +++ b/src/lua_script.h @@ -102,6 +102,8 @@ void COM_Lua_f(void); #define LUA_ErrInvalid(L, type) luaL_error(L, "accessed " type " doesn't exist anymore, please check 'valid' before using " type "."); +#define LUA_ErrSetDirectly(L, type, field) luaL_error(L, type " field " LUA_QL(field) " cannot be set directly.") + // Deprecation warnings // Shows once upon use. Then doesn't show again. #define LUA_Deprecated(L,this_func,use_instead)\ diff --git a/src/lua_taglib.c b/src/lua_taglib.c index 2e2a0d277..73f033312 100644 --- a/src/lua_taglib.c +++ b/src/lua_taglib.c @@ -150,6 +150,137 @@ static int lib_numTaggroupElements(lua_State *L) return 1; } +static void push_taglist(lua_State *L, int idx) +{ + lua_getmetatable(L, idx); + lua_pushliteral(L, "taglist"); + lua_rawget(L, -2); + lua_remove(L, -2); +} + +static int has_valid_field(lua_State *L) +{ + int equal; + lua_pushliteral(L, "valid"); + equal = lua_rawequal(L, 2, -1); + lua_pop(L, 1); + return equal; +} + +static taglist_t * valid_taglist(lua_State *L, int idx, boolean getting) +{ + taglist_t *list = *(taglist_t **)lua_touserdata(L, idx); + + if (list == NULL) + { + if (getting && has_valid_field(L)) + lua_pushboolean(L, 0); + else + LUA_ErrInvalid(L, "taglist_t");/* doesn't actually return */ + return NULL; + } + else + return list; +} + +static taglist_t * check_taglist(lua_State *L, int idx) +{ + luaL_checktype(L, idx, LUA_TUSERDATA); + push_taglist(L, idx); + luaL_argcheck(L, lua_toboolean(L, -1), idx, "must be a tag list"); + return valid_taglist(L, idx, false); +} + +static int taglist_get(lua_State *L) +{ + const taglist_t *list = valid_taglist(L, 1, true); + + if (list == NULL)/* valid check */ + return 1; + + if (lua_isnumber(L, 2)) + { + const size_t i = lua_tonumber(L, 2); + + if (list && i <= list->count) + { + lua_pushnumber(L, list->tags[i - 1]); + return 1; + } + else + return 0; + } + else if (has_valid_field(L)) + { + lua_pushboolean(L, 1); + return 1; + } + else + { + push_taglist(L, 1); + lua_replace(L, 1); + lua_rawget(L, 1); + return 1; + } +} + +static int taglist_len(lua_State *L) +{ + const taglist_t *list = valid_taglist(L, 1, false); + lua_pushnumber(L, list->count); + return 1; +} + +static int taglist_equal(lua_State *L) +{ + const taglist_t *lhs = check_taglist(L, 1); + const taglist_t *rhs = check_taglist(L, 2); + lua_pushboolean(L, Tag_Compare(lhs, rhs)); + return 1; +} + +static int taglist_iterator(lua_State *L) +{ + const taglist_t *list = valid_taglist(L, 1, false); + const size_t i = 1 + lua_tonumber(L, lua_upvalueindex(1)); + if (i <= list->count) + { + lua_pushnumber(L, list->tags[i - 1]); + /* watch me exploit an upvalue as a control because + I want to use the control as the value */ + lua_pushnumber(L, i); + lua_replace(L, lua_upvalueindex(1)); + return 1; + } + else + return 0; +} + +static int taglist_iterate(lua_State *L) +{ + check_taglist(L, 1); + lua_pushnumber(L, 0); + lua_pushcclosure(L, taglist_iterator, 1); + lua_pushvalue(L, 1); + return 2; +} + +static int taglist_find(lua_State *L) +{ + const taglist_t *list = check_taglist(L, 1); + const mtag_t tag = luaL_checknumber(L, 2); + lua_pushboolean(L, Tag_Find(list, tag)); + return 1; +} + +static int taglist_shares(lua_State *L) +{ + const taglist_t *lhs = check_taglist(L, 1); + const taglist_t *rhs = check_taglist(L, 2); + lua_pushboolean(L, Tag_Share(lhs, rhs)); + return 1; +} + void LUA_InsertTaggroupIterator ( lua_State *L, taggroup_t *garray[], @@ -179,6 +310,13 @@ void LUA_InsertTaggroupIterator lua_setfield(L, -2, "tagged"); } +static luaL_Reg taglist_lib[] = { + {"iterate", taglist_iterate}, + {"find", taglist_find}, + {"shares", taglist_shares}, + {0} +}; + int LUA_TagLib(lua_State *L) { lua_newuserdata(L, 0); @@ -193,5 +331,23 @@ int LUA_TagLib(lua_State *L) lua_setmetatable(L, -2); lua_setglobal(L, "tags"); + luaL_newmetatable(L, META_THINGTAGLIST); + luaL_register(L, "taglist", taglist_lib); + lua_getfield(L, -1, "find"); + lua_setfield(L, -2, "has"); + lua_setfield(L, -2, "taglist"); + + lua_pushcfunction(L, taglist_get); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, taglist_len); + lua_setfield(L, -2, "__len"); + + lua_pushcfunction(L, taglist_equal); + lua_setfield(L, -2, "__eq"); + lua_pushvalue(L, -1); + lua_setfield(L, LUA_REGISTRYINDEX, META_LINETAGLIST); + lua_setfield(L, LUA_REGISTRYINDEX, META_SECTORTAGLIST); + return 0; } From 828d7e71ce62d1dae4ddcd7fe9319229005eac75 Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 5 Dec 2020 00:36:54 -0800 Subject: [PATCH 099/644] Fix uninitialized last element when using Taggroup_Remove --- src/taglist.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/taglist.c b/src/taglist.c index 658605734..7dbad65c4 100644 --- a/src/taglist.c +++ b/src/taglist.c @@ -188,7 +188,7 @@ void Taggroup_Remove (taggroup_t *garray[], const mtag_t tag, size_t id) { taggroup_t *group; size_t rempos; - size_t newcount; + size_t oldcount; if (tag == MTAG_GLOBAL) return; @@ -204,7 +204,7 @@ void Taggroup_Remove (taggroup_t *garray[], const mtag_t tag, size_t id) unset_bit_array(tags_available, tag); // Strip away taggroup if no elements left. - if (!(newcount = --group->count)) + if (!(oldcount = group->count--)) { Z_Free(group->elements); Z_Free(group); @@ -212,19 +212,18 @@ void Taggroup_Remove (taggroup_t *garray[], const mtag_t tag, size_t id) } else { - size_t *newelements = Z_Malloc(newcount * sizeof(size_t), PU_LEVEL, NULL); + size_t *newelements = Z_Malloc(group->count * sizeof(size_t), PU_LEVEL, NULL); size_t i; // Copy the previous entries save for the one to remove. for (i = 0; i < rempos; i++) newelements[i] = group->elements[i]; - for (i = rempos + 1; i < group->count; i++) + for (i = rempos + 1; i < oldcount; i++) newelements[i - 1] = group->elements[i]; Z_Free(group->elements); group->elements = newelements; - group->count = newcount; } } From ae663e724774007e0242fc509c87402a3ff7b7c4 Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 5 Dec 2020 00:46:51 -0800 Subject: [PATCH 100/644] Don't realloc twice when adding to the taggroup --- src/taglist.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/taglist.c b/src/taglist.c index 7dbad65c4..cfd9cbb9c 100644 --- a/src/taglist.c +++ b/src/taglist.c @@ -170,16 +170,15 @@ void Taggroup_Add (taggroup_t *garray[], const mtag_t tag, size_t id) for (i = 0; i < group->count; i++) if (group->elements[i] > id) break; - - group->elements = Z_Realloc(group->elements, (group->count + 1) * sizeof(size_t), PU_LEVEL, NULL); - - // Offset existing elements to make room for the new one. - if (i < group->count) - memmove(&group->elements[i + 1], &group->elements[i], group->count - i); } + group->elements = Z_Realloc(group->elements, (group->count + 1) * sizeof(size_t), PU_LEVEL, NULL); + + // Offset existing elements to make room for the new one. + if (i < group->count) + memmove(&group->elements[i + 1], &group->elements[i], group->count - i); + group->count++; - group->elements = Z_Realloc(group->elements, group->count * sizeof(size_t), PU_LEVEL, NULL); group->elements[i] = id; } From e5a3e6a845e105566dd6def263cd2d7326155d42 Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 5 Dec 2020 01:14:52 -0800 Subject: [PATCH 101/644] Fix removing a tag unsetting the bit array even if more elements with that tag exist --- src/lua_taglib.c | 2 +- src/taglist.c | 28 +++++++++++++++++++++++----- src/taglist.h | 1 + 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/lua_taglib.c b/src/lua_taglib.c index 73f033312..07646af87 100644 --- a/src/lua_taglib.c +++ b/src/lua_taglib.c @@ -145,7 +145,7 @@ static int lib_numTaggroupElements(lua_State *L) else { const taggroup_t ** garray = lua_touserdata(L, up_garray); - lua_pushnumber(L, garray[tag] ? garray[tag]->count : 0); + lua_pushnumber(L, Taggroup_Count(garray[tag])); } return 1; } diff --git a/src/taglist.c b/src/taglist.c index cfd9cbb9c..a759f4d02 100644 --- a/src/taglist.c +++ b/src/taglist.c @@ -110,6 +110,12 @@ size_t Taggroup_Find (const taggroup_t *group, const size_t id) return -1; } +/// group->count, but also checks for NULL +size_t Taggroup_Count (const taggroup_t *group) +{ + return group ? group->count : 0; +} + /// Iterate thru elements in a global taggroup. INT32 Taggroup_Iterate ( taggroup_t *garray[], @@ -153,9 +159,10 @@ void Taggroup_Add (taggroup_t *garray[], const mtag_t tag, size_t id) return; if (! in_bit_array(tags_available, tag)) + { num_tags++; - - set_bit_array(tags_available, tag); + set_bit_array(tags_available, tag); + } // Create group if empty. if (!group) @@ -182,6 +189,16 @@ void Taggroup_Add (taggroup_t *garray[], const mtag_t tag, size_t id) group->elements[i] = id; } +static size_t total_elements_with_tag (const mtag_t tag) +{ + return + ( + Taggroup_Count(tags_sectors[tag]) + + Taggroup_Count(tags_lines[tag]) + + Taggroup_Count(tags_mapthings[tag]) + ); +} + /// Remove an element from a global taggroup. void Taggroup_Remove (taggroup_t *garray[], const mtag_t tag, size_t id) { @@ -197,10 +214,11 @@ void Taggroup_Remove (taggroup_t *garray[], const mtag_t tag, size_t id) if ((rempos = Taggroup_Find(group, id)) == (size_t)-1) return; - if (in_bit_array(tags_available, tag)) + if (group->count == 1 && total_elements_with_tag(tag) == 1) + { num_tags--; - - unset_bit_array(tags_available, tag); + unset_bit_array(tags_available, tag); + } // Strip away taggroup if no elements left. if (!(oldcount = group->count--)) diff --git a/src/taglist.h b/src/taglist.h index e5db08806..a0529ab6b 100644 --- a/src/taglist.h +++ b/src/taglist.h @@ -54,6 +54,7 @@ extern taggroup_t* tags_mapthings[]; void Taggroup_Add (taggroup_t *garray[], const mtag_t tag, size_t id); void Taggroup_Remove (taggroup_t *garray[], const mtag_t tag, size_t id); size_t Taggroup_Find (const taggroup_t *group, const size_t id); +size_t Taggroup_Count (const taggroup_t *group); INT32 Taggroup_Iterate ( taggroup_t *garray[], From 8dd964e3a726a30ad50e7cfc3a5d0356351f24bf Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 5 Dec 2020 02:02:06 -0800 Subject: [PATCH 102/644] Lua: taglist.add and taglist.remove for sector tag lists --- src/lua_baselib.c | 6 ++- src/lua_libs.h | 10 +++-- src/lua_maplib.c | 2 +- src/lua_mobjlib.c | 2 +- src/lua_taglib.c | 110 +++++++++++++++++++++++++++++++++++++++------- 5 files changed, 108 insertions(+), 22 deletions(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 1324322a2..59c1d411b 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -155,6 +155,8 @@ static const struct { {META_PIVOTLIST, "spriteframepivot_t[]"}, {META_FRAMEPIVOT, "spriteframepivot_t"}, + {META_TAGLIST, "taglist"}, + {META_MOBJ, "mobj_t"}, {META_MAPTHING, "mapthing_t"}, @@ -184,15 +186,15 @@ static const struct { {META_CVAR, "consvar_t"}, {META_SECTORLINES, "sector_t.lines"}, +#ifdef MUTABLE_TAGS {META_SECTORTAGLIST, "sector_t.taglist"}, +#endif {META_SIDENUM, "line_t.sidenum"}, {META_LINEARGS, "line_t.args"}, {META_LINESTRINGARGS, "line_t.stringargs"}, - {META_LINETAGLIST, "line_t.taglist"}, {META_THINGARGS, "mapthing.args"}, {META_THINGSTRINGARGS, "mapthing.stringargs"}, - {META_THINGTAGLIST, "mapthing_t.taglist"}, #ifdef HAVE_LUA_SEGS {META_NODEBBOX, "node_t.bbox"}, {META_NODECHILDREN, "node_t.children"}, diff --git a/src/lua_libs.h b/src/lua_libs.h index 991fae3fd..e7f4ae253 100644 --- a/src/lua_libs.h +++ b/src/lua_libs.h @@ -12,6 +12,8 @@ extern lua_State *gL; +#define MUTABLE_TAGS + #define LREG_VALID "VALID_USERDATA" #define LREG_EXTVARS "LUA_VARS" #define LREG_STATEACTION "STATE_ACTION" @@ -27,6 +29,8 @@ extern lua_State *gL; #define META_PIVOTLIST "SPRITEFRAMEPIVOT_T[]" #define META_FRAMEPIVOT "SPRITEFRAMEPIVOT_T*" +#define META_TAGLIST "TAGLIST" + #define META_MOBJ "MOBJ_T*" #define META_MAPTHING "MAPTHING_T*" @@ -56,14 +60,14 @@ extern lua_State *gL; #define META_CVAR "CONSVAR_T*" #define META_SECTORLINES "SECTOR_T*LINES" -#define META_SECTORTAGLIST "SECTOR_T*TAGLIST" +#ifdef MUTABLE_TAGS +#define META_SECTORTAGLIST "sector_t.taglist" +#endif #define META_SIDENUM "LINE_T*SIDENUM" #define META_LINEARGS "LINE_T*ARGS" #define META_LINESTRINGARGS "LINE_T*STRINGARGS" -#define META_LINETAGLIST "LINE_T*TAGLIST" #define META_THINGARGS "MAPTHING_T*ARGS" #define META_THINGSTRINGARGS "MAPTHING_T*STRINGARGS" -#define META_THINGTAGLIST "THING_T*TAGLIST" #define META_POLYOBJVERTICES "POLYOBJ_T*VERTICES" #define META_POLYOBJLINES "POLYOBJ_T*LINES" #ifdef HAVE_LUA_SEGS diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 25edf83d8..3520cdbda 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -831,7 +831,7 @@ static int line_get(lua_State *L) lua_pushinteger(L, Tag_FGet(&line->tags)); return 1; case line_taglist: - LUA_PushUserdata(L, &line->tags, META_LINETAGLIST); + LUA_PushUserdata(L, &line->tags, META_TAGLIST); return 1; case line_args: LUA_PushUserdata(L, line->args, META_LINEARGS); diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index 8d205780d..65adceb15 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -904,7 +904,7 @@ static int mapthing_get(lua_State *L) number = Tag_FGet(&mt->tags); else if(fastcmp(field,"taglist")) { - LUA_PushUserdata(L, &mt->tags, META_THINGTAGLIST); + LUA_PushUserdata(L, &mt->tags, META_TAGLIST); return 1; } else if(fastcmp(field,"args")) diff --git a/src/lua_taglib.c b/src/lua_taglib.c index 07646af87..7994b6625 100644 --- a/src/lua_taglib.c +++ b/src/lua_taglib.c @@ -17,6 +17,10 @@ #include "lua_script.h" #include "lua_libs.h" +#ifdef MUTABLE_TAGS +#include "z_zone.h" +#endif + static int tag_iterator(lua_State *L) { INT32 tag = lua_isnil(L, 2) ? -1 : lua_tonumber(L, 2); @@ -281,6 +285,63 @@ static int taglist_shares(lua_State *L) return 1; } +/* only sector tags are mutable... */ + +#ifdef MUTABLE_TAGS +static size_t sector_of_taglist(taglist_t *list) +{ + return (sector_t *)((char *)list - offsetof (sector_t, tags)) - sectors; +} + +static int this_taglist(lua_State *L) +{ + lua_settop(L, 1); + return 1; +} + +static int taglist_add(lua_State *L) +{ + taglist_t *list = *(taglist_t **)luaL_checkudata(L, 1, META_SECTORTAGLIST); + const mtag_t tag = luaL_checknumber(L, 2); + + if (! Tag_Find(list, tag)) + { + Taggroup_Add(tags_sectors, tag, sector_of_taglist(list)); + Tag_Add(list, tag); + } + + return this_taglist(L); +} + +static int taglist_remove(lua_State *L) +{ + taglist_t *list = *(taglist_t **)luaL_checkudata(L, 1, META_SECTORTAGLIST); + const mtag_t tag = luaL_checknumber(L, 2); + + size_t i; + + for (i = 0; i < list->count; ++i) + { + if (list->tags[i] == tag) + { + if (list->count > 1) + { + memmove(&list->tags[i], &list->tags[i + 1], + (list->count - 1 - i) * sizeof (mtag_t)); + list->tags = Z_Realloc(list->tags, + (--list->count) * sizeof (mtag_t), PU_LEVEL, NULL); + Taggroup_Remove(tags_sectors, tag, sector_of_taglist(list)); + } + else/* reset to default tag */ + Tag_SectorFSet(sector_of_taglist(list), 0); + break; + } + } + + return this_taglist(L); +} +#endif/*MUTABLE_TAGS*/ + void LUA_InsertTaggroupIterator ( lua_State *L, taggroup_t *garray[], @@ -314,9 +375,38 @@ static luaL_Reg taglist_lib[] = { {"iterate", taglist_iterate}, {"find", taglist_find}, {"shares", taglist_shares}, +#ifdef MUTABLE_TAGS + {"add", taglist_add}, + {"remove", taglist_remove}, +#endif {0} }; +static void open_taglist(lua_State *L) +{ + luaL_register(L, "taglist", taglist_lib); + + lua_getfield(L, -1, "find"); + lua_setfield(L, -2, "has"); +} + +static void set_taglist_metatable(lua_State *L, const char *meta) +{ + lua_createtable(L, 0, 4); + lua_getglobal(L, "taglist"); + lua_setfield(L, -2, "taglist"); + + lua_pushcfunction(L, taglist_get); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, taglist_len); + lua_setfield(L, -2, "__len"); + + lua_pushcfunction(L, taglist_equal); + lua_setfield(L, -2, "__eq"); + lua_setfield(L, LUA_REGISTRYINDEX, meta); +} + int LUA_TagLib(lua_State *L) { lua_newuserdata(L, 0); @@ -331,23 +421,13 @@ int LUA_TagLib(lua_State *L) lua_setmetatable(L, -2); lua_setglobal(L, "tags"); - luaL_newmetatable(L, META_THINGTAGLIST); - luaL_register(L, "taglist", taglist_lib); - lua_getfield(L, -1, "find"); - lua_setfield(L, -2, "has"); - lua_setfield(L, -2, "taglist"); + open_taglist(L); - lua_pushcfunction(L, taglist_get); - lua_setfield(L, -2, "__index"); + set_taglist_metatable(L, META_TAGLIST); - lua_pushcfunction(L, taglist_len); - lua_setfield(L, -2, "__len"); - - lua_pushcfunction(L, taglist_equal); - lua_setfield(L, -2, "__eq"); - lua_pushvalue(L, -1); - lua_setfield(L, LUA_REGISTRYINDEX, META_LINETAGLIST); - lua_setfield(L, LUA_REGISTRYINDEX, META_SECTORTAGLIST); +#ifdef MUTABLE_TAGS + set_taglist_metatable(L, META_SECTORTAGLIST); +#endif return 0; } From 5d1040c92441a2634410caf2da673eea335e92be Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 5 Dec 2020 02:08:00 -0800 Subject: [PATCH 103/644] Reset taggroup iterator on successive calls --- src/lua_taglib.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lua_taglib.c b/src/lua_taglib.c index 7994b6625..cfaf84872 100644 --- a/src/lua_taglib.c +++ b/src/lua_taglib.c @@ -75,6 +75,8 @@ struct element_iterator_state { static int element_iterator(lua_State *L) { struct element_iterator_state * state = lua_touserdata(L, 1); + if (lua_isnoneornil(L, 3)) + state->p = 0; lua_pushnumber(L, ++state->p); lua_gettable(L, 1); return 1; From 0b0f2e1e35aa822566986bcd6dc1526f3828f25e Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 5 Dec 2020 02:26:00 -0800 Subject: [PATCH 104/644] Invalidate taglist userdata --- src/lua_script.c | 5 +++++ src/lua_taglib.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/lua_script.c b/src/lua_script.c index ee60a41c6..bc88928f3 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -846,6 +846,7 @@ void LUA_InvalidateLevel(void) { LUA_InvalidateUserdata(§ors[i]); LUA_InvalidateUserdata(§ors[i].lines); + LUA_InvalidateUserdata(§ors[i].tags); if (sectors[i].ffloors) { for (rover = sectors[i].ffloors; rover; rover = rover->next) @@ -855,6 +856,7 @@ void LUA_InvalidateLevel(void) for (i = 0; i < numlines; i++) { LUA_InvalidateUserdata(&lines[i]); + LUA_InvalidateUserdata(&lines[i].tags); LUA_InvalidateUserdata(lines[i].sidenum); } for (i = 0; i < numsides; i++) @@ -886,7 +888,10 @@ void LUA_InvalidateMapthings(void) return; for (i = 0; i < nummapthings; i++) + { LUA_InvalidateUserdata(&mapthings[i]); + LUA_InvalidateUserdata(&mapthings[i].tags); + } } void LUA_InvalidatePlayer(player_t *player) diff --git a/src/lua_taglib.c b/src/lua_taglib.c index cfaf84872..284b171a3 100644 --- a/src/lua_taglib.c +++ b/src/lua_taglib.c @@ -182,7 +182,7 @@ static taglist_t * valid_taglist(lua_State *L, int idx, boolean getting) if (getting && has_valid_field(L)) lua_pushboolean(L, 0); else - LUA_ErrInvalid(L, "taglist_t");/* doesn't actually return */ + LUA_ErrInvalid(L, "taglist");/* doesn't actually return */ return NULL; } else From f6af04ecbb45b34488c5c2160b44f6dcda1770cb Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Sat, 5 Dec 2020 05:00:59 -0600 Subject: [PATCH 105/644] Fix weird spelling mistake --- src/deh_tables.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/deh_tables.c b/src/deh_tables.c index 3240aee14..ff596deea 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -4886,7 +4886,7 @@ struct int_const_s const INT_CONST[] = { {"RF_VERTICALFLIP",RF_VERTICALFLIP}, {"RF_ABSOLUTEOFFSETS",RF_ABSOLUTEOFFSETS}, {"RF_FLIPOFFSETS",RF_FLIPOFFSETS}, - {"RF_SPLATMASK",RF_SLOPESPLAT}, + {"RF_SPLATMASK",RF_SPLATMASK}, {"RF_SLOPESPLAT",RF_SLOPESPLAT}, {"RF_OBJECTSLOPESPLAT",RF_OBJECTSLOPESPLAT}, {"RF_NOSPLATBILLBOARD",RF_NOSPLATBILLBOARD}, From 854140932940517a5800b9c93939081f189f2b08 Mon Sep 17 00:00:00 2001 From: katsy Date: Sat, 5 Dec 2020 23:13:47 -0500 Subject: [PATCH 106/644] add noclipheight on chaingrab --- src/p_inter.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/p_inter.c b/src/p_inter.c index 415c679e4..189cbcea7 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1641,6 +1641,9 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) // Can't jump first frame player->pflags |= PF_JUMPSTASIS; + // Disable interaction with ground + player->mo->flags |= MF_NOCLIPHEIGHT; + return; } case MT_EGGMOBILE2_POGO: From 3dbb44e7b1afa8d42cf9b83ffcdc02525871f1af Mon Sep 17 00:00:00 2001 From: katsy Date: Sat, 5 Dec 2020 23:17:01 -0500 Subject: [PATCH 107/644] ensure the new flag is cleared properly --- src/p_user.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/p_user.c b/src/p_user.c index c5f919c78..65397c287 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1085,6 +1085,9 @@ void P_ResetPlayer(player_t *player) player->powers[pw_carry] = CR_NONE; } + if (player->powers[pw_carry] == CR_MACESPIN || player->powers[pw_carry] == CR_GENERIC) + player->mo->flags &= ~MF_NOCLIPHEIGHT; + if (!(player->powers[pw_carry] == CR_NIGHTSMODE || player->powers[pw_carry] == CR_NIGHTSFALL || player->powers[pw_carry] == CR_BRAKGOOP || player->powers[pw_carry] == CR_MINECART)) player->powers[pw_carry] = CR_NONE; @@ -4426,6 +4429,8 @@ void P_DoJump(player_t *player, boolean soundandstate) if (!(player->mo->tracer->flags & MF_MISSILE)) // Missiles remember their owner! P_SetTarget(&player->mo->tracer->target, NULL); P_SetTarget(&player->mo->tracer, NULL); + player->mo->flags &= ~MF_NOCLIPHEIGHT; + } else if (player->powers[pw_carry] == CR_ROPEHANG) { @@ -5257,6 +5262,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) player->powers[pw_carry] = CR_NONE; P_SetTarget(&player->mo->tracer, NULL); player->powers[pw_flashing] = TICRATE/4; + player->mo->flags &= ~MF_NOCLIPHEIGHT; } // can't jump while in air, can't jump while jumping else if (onground || player->climbing || player->powers[pw_carry]) From a7fa2b2e490268da0d75c82e91e825c21bf521a9 Mon Sep 17 00:00:00 2001 From: katsy Date: Sun, 6 Dec 2020 00:09:40 -0500 Subject: [PATCH 108/644] Replace p_mobj.c From 768ee5705743d8f42a4b72cac52da7dc910e1ecb Mon Sep 17 00:00:00 2001 From: katsy Date: Sun, 6 Dec 2020 00:10:28 -0500 Subject: [PATCH 109/644] Replace p_user.c --- src/p_user.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 65397c287..c5f919c78 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1085,9 +1085,6 @@ void P_ResetPlayer(player_t *player) player->powers[pw_carry] = CR_NONE; } - if (player->powers[pw_carry] == CR_MACESPIN || player->powers[pw_carry] == CR_GENERIC) - player->mo->flags &= ~MF_NOCLIPHEIGHT; - if (!(player->powers[pw_carry] == CR_NIGHTSMODE || player->powers[pw_carry] == CR_NIGHTSFALL || player->powers[pw_carry] == CR_BRAKGOOP || player->powers[pw_carry] == CR_MINECART)) player->powers[pw_carry] = CR_NONE; @@ -4429,8 +4426,6 @@ void P_DoJump(player_t *player, boolean soundandstate) if (!(player->mo->tracer->flags & MF_MISSILE)) // Missiles remember their owner! P_SetTarget(&player->mo->tracer->target, NULL); P_SetTarget(&player->mo->tracer, NULL); - player->mo->flags &= ~MF_NOCLIPHEIGHT; - } else if (player->powers[pw_carry] == CR_ROPEHANG) { @@ -5262,7 +5257,6 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) player->powers[pw_carry] = CR_NONE; P_SetTarget(&player->mo->tracer, NULL); player->powers[pw_flashing] = TICRATE/4; - player->mo->flags &= ~MF_NOCLIPHEIGHT; } // can't jump while in air, can't jump while jumping else if (onground || player->climbing || player->powers[pw_carry]) From fd4674971a3a2ca7dac8203d801420aa76b06dec Mon Sep 17 00:00:00 2001 From: katsy Date: Sun, 6 Dec 2020 00:10:45 -0500 Subject: [PATCH 110/644] Replace p_inter.c --- src/p_inter.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 189cbcea7..415c679e4 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1641,9 +1641,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) // Can't jump first frame player->pflags |= PF_JUMPSTASIS; - // Disable interaction with ground - player->mo->flags |= MF_NOCLIPHEIGHT; - return; } case MT_EGGMOBILE2_POGO: From 2fcf613a3114803c90e3a7db51035265b5ab066b Mon Sep 17 00:00:00 2001 From: katsy Date: Sun, 6 Dec 2020 00:13:10 -0500 Subject: [PATCH 111/644] brak barrier is scaled up by 2x in gameplay, the actual object's parameters should be halved --- src/info.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/info.c b/src/info.c index 29a79b1d6..d2f53c55c 100644 --- a/src/info.c +++ b/src/info.c @@ -6458,8 +6458,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_fizzle, // deathsound 10*FRACUNIT, // speed - 48*FRACUNIT, // radius - 160*FRACUNIT, // height + 24*FRACUNIT, // radius + 80*FRACUNIT, // height 0, // display offset DMG_ELECTRIC, // mass 1, // damage From ffd20ee7538609d2e8dbc841ff43ab3685badabe Mon Sep 17 00:00:00 2001 From: katsy Date: Sun, 6 Dec 2020 07:44:49 +0000 Subject: [PATCH 112/644] Revert "ensure the new flag is cleared properly" This reverts commit 3dbb44e7b1afa8d42cf9b83ffcdc02525871f1af --- src/p_user.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 65397c287..c5f919c78 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1085,9 +1085,6 @@ void P_ResetPlayer(player_t *player) player->powers[pw_carry] = CR_NONE; } - if (player->powers[pw_carry] == CR_MACESPIN || player->powers[pw_carry] == CR_GENERIC) - player->mo->flags &= ~MF_NOCLIPHEIGHT; - if (!(player->powers[pw_carry] == CR_NIGHTSMODE || player->powers[pw_carry] == CR_NIGHTSFALL || player->powers[pw_carry] == CR_BRAKGOOP || player->powers[pw_carry] == CR_MINECART)) player->powers[pw_carry] = CR_NONE; @@ -4429,8 +4426,6 @@ void P_DoJump(player_t *player, boolean soundandstate) if (!(player->mo->tracer->flags & MF_MISSILE)) // Missiles remember their owner! P_SetTarget(&player->mo->tracer->target, NULL); P_SetTarget(&player->mo->tracer, NULL); - player->mo->flags &= ~MF_NOCLIPHEIGHT; - } else if (player->powers[pw_carry] == CR_ROPEHANG) { @@ -5262,7 +5257,6 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) player->powers[pw_carry] = CR_NONE; P_SetTarget(&player->mo->tracer, NULL); player->powers[pw_flashing] = TICRATE/4; - player->mo->flags &= ~MF_NOCLIPHEIGHT; } // can't jump while in air, can't jump while jumping else if (onground || player->climbing || player->powers[pw_carry]) From 5853a0b4d837fbb83c092c2a91ef4566ab906e64 Mon Sep 17 00:00:00 2001 From: katsy Date: Sun, 6 Dec 2020 07:44:59 +0000 Subject: [PATCH 113/644] Revert "add noclipheight on chaingrab" This reverts commit 854140932940517a5800b9c93939081f189f2b08 --- src/p_inter.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 189cbcea7..415c679e4 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1641,9 +1641,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) // Can't jump first frame player->pflags |= PF_JUMPSTASIS; - // Disable interaction with ground - player->mo->flags |= MF_NOCLIPHEIGHT; - return; } case MT_EGGMOBILE2_POGO: From 8f4d23197c299d59778eede6a8c8424058f851d6 Mon Sep 17 00:00:00 2001 From: katsy Date: Sun, 6 Dec 2020 04:32:30 -0500 Subject: [PATCH 114/644] space --- src/info.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/info.c b/src/info.c index d2f53c55c..56e764b5d 100644 --- a/src/info.c +++ b/src/info.c @@ -6459,7 +6459,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_fizzle, // deathsound 10*FRACUNIT, // speed 24*FRACUNIT, // radius - 80*FRACUNIT, // height + 80*FRACUNIT, // height 0, // display offset DMG_ELECTRIC, // mass 1, // damage From 233990099db1380560bfa64bb89c95340ed01124 Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Sun, 6 Dec 2020 04:28:12 -0600 Subject: [PATCH 115/644] Make caret coloring support letters. --- src/dehacked.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/dehacked.c b/src/dehacked.c index e98ff71cf..b42663267 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -59,6 +59,12 @@ ATTRINLINE static FUNCINLINE char myfget_color(MYFILE *f) if (c >= '0' && c <= '9') return 0x80+(c-'0'); + + c = tolower(c); + + if (c >= 'a' && c <= 'f') + return 0x80+10+(c-'a'); + return 0x80; // Unhandled -- default to no color } From 3b85abdee7e557818486ef06f6714cb374360c11 Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+Ikkarin@users.noreply.github.com> Date: Sun, 6 Dec 2020 14:11:08 -0300 Subject: [PATCH 116/644] Kill saloon doors without a tracer, add height check for non-blocking doors --- src/p_map.c | 6 ++++-- src/p_mobj.c | 6 ++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index 922c0d9ec..24311c35a 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -982,7 +982,8 @@ static boolean PIT_CheckThing(mobj_t *thing) if (thing->type == MT_SALOONDOOR && tmthing->player) { mobj_t *ref = (tmthing->player->powers[pw_carry] == CR_MINECART && tmthing->tracer && !P_MobjWasRemoved(tmthing->tracer)) ? tmthing->tracer : tmthing; - if ((thing->flags2 & MF2_AMBUSH) || ref != tmthing) + if (((thing->flags2 & MF2_AMBUSH) && (tmthing->z <= thing->z + thing->height) && (tmthing->z + tmthing->height >= thing->z)) + || ref != tmthing) { fixed_t dm = min(FixedHypot(ref->momx, ref->momy), 16*FRACUNIT); angle_t ang = R_PointToAngle2(0, 0, ref->momx, ref->momy) - thing->angle; @@ -995,7 +996,8 @@ static boolean PIT_CheckThing(mobj_t *thing) if (thing->type == MT_SALOONDOORCENTER && tmthing->player) { - if ((thing->flags2 & MF2_AMBUSH) || (tmthing->player->powers[pw_carry] == CR_MINECART && tmthing->tracer && !P_MobjWasRemoved(tmthing->tracer))) + if (((thing->flags2 & MF2_AMBUSH) && (tmthing->z <= thing->z + thing->height) && (tmthing->z + tmthing->height >= thing->z)) + || (tmthing->player->powers[pw_carry] == CR_MINECART && tmthing->tracer && !P_MobjWasRemoved(tmthing->tracer))) return true; } diff --git a/src/p_mobj.c b/src/p_mobj.c index 7ba6d1fad..65113a840 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9651,6 +9651,12 @@ static boolean P_MobjRegularThink(mobj_t *mobj) break; } case MT_SALOONDOOR: + if (!mobj->tracer) // Door center is gone or not spawned? + { + P_RemoveMobj(mobj); // Die + return false; + } + P_SaloonDoorThink(mobj); break; case MT_MINECARTSPAWNER: From 6546fc8ce775298d7818061166434992c598be38 Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Sun, 6 Dec 2020 12:01:31 -0600 Subject: [PATCH 117/644] Fix HWR_DrawCroppedPatch scaling a patch when cropping the top and left sides. --- src/hardware/hw_draw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index b9cb288e9..c5d362520 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -506,13 +506,13 @@ void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, v[0].s = v[3].s = ((sx)/(float)(gpatch->width))*hwrPatch->max_s; if (sx + w > gpatch->width) - v[2].s = v[1].s = hwrPatch->max_s; + v[2].s = v[1].s = hwrPatch->max_s - ((sx+w)/(float)(gpatch->width))*hwrPatch->max_s; else v[2].s = v[1].s = ((sx+w)/(float)(gpatch->width))*hwrPatch->max_s; v[0].t = v[1].t = ((sy)/(float)(gpatch->height))*hwrPatch->max_t; if (sy + h > gpatch->height) - v[2].t = v[3].t = hwrPatch->max_t; + v[2].t = v[3].t = hwrPatch->max_t - ((sy+h)/(float)(gpatch->height))*hwrPatch->max_t; else v[2].t = v[3].t = ((sy+h)/(float)(gpatch->height))*hwrPatch->max_t; From 24ba78214421ff6fe4aafc5480a9d5e6e66c49db Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Sun, 6 Dec 2020 17:29:20 -0300 Subject: [PATCH 118/644] Fix archived mobjs having no default blend mode and sprite scales --- src/p_saveg.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/p_saveg.c b/src/p_saveg.c index adedea049..03229e740 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1506,7 +1506,7 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) { const mobj_t *mobj = (const mobj_t *)th; UINT32 diff; - UINT16 diff2; + UINT32 diff2; // Ignore stationary hoops - these will be respawned from mapthings. if (mobj->type == MT_HOOP) @@ -1638,7 +1638,7 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) diff2 |= MD2_SHADOWSCALE; if (mobj->renderflags) diff2 |= MD2_RENDERFLAGS; - if (mobj->renderflags) + if (mobj->blendmode != AST_TRANSLUCENT) diff2 |= MD2_BLENDMODE; if (mobj->spritexscale != FRACUNIT) diff2 |= MD2_SPRITEXSCALE; @@ -1646,6 +1646,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) diff2 |= MD2_SPRITEYSCALE; if (mobj->spritexoffset) diff2 |= MD2_SPRITEXOFFSET; + if (mobj->spriteyoffset) + diff2 |= MD2_SPRITEYOFFSET; if (mobj->floorspriteslope) { pslope_t *slope = mobj->floorspriteslope; @@ -1667,7 +1669,7 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) WRITEUINT8(save_p, type); WRITEUINT32(save_p, diff); if (diff & MD_MORE) - WRITEUINT16(save_p, diff2); + WRITEUINT32(save_p, diff2); // save pointer, at load time we will search this pointer to reinitilize pointers WRITEUINT32(save_p, (size_t)mobj); @@ -2615,14 +2617,14 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) thinker_t *next; mobj_t *mobj; UINT32 diff; - UINT16 diff2; + UINT32 diff2; INT32 i; fixed_t z, floorz, ceilingz; ffloor_t *floorrover = NULL, *ceilingrover = NULL; diff = READUINT32(save_p); if (diff & MD_MORE) - diff2 = READUINT16(save_p); + diff2 = READUINT32(save_p); else diff2 = 0; @@ -2843,10 +2845,16 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) mobj->renderflags = READUINT32(save_p); if (diff2 & MD2_BLENDMODE) mobj->blendmode = READINT32(save_p); + else + mobj->blendmode = AST_TRANSLUCENT; if (diff2 & MD2_SPRITEXSCALE) mobj->spritexscale = READFIXED(save_p); + else + mobj->spritexscale = FRACUNIT; if (diff2 & MD2_SPRITEYSCALE) mobj->spriteyscale = READFIXED(save_p); + else + mobj->spriteyscale = FRACUNIT; if (diff2 & MD2_SPRITEXOFFSET) mobj->spritexoffset = READFIXED(save_p); if (diff2 & MD2_SPRITEYOFFSET) From 6f9c48a30560b0f2d89f7202371dfc164015b9ba Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Sun, 6 Dec 2020 17:46:35 -0300 Subject: [PATCH 119/644] Move a few mobj spawn defaults to its own function --- src/p_local.h | 1 + src/p_mobj.c | 76 ++++++++++++++++++++++++++++----------------------- src/p_saveg.c | 40 ++------------------------- 3 files changed, 46 insertions(+), 71 deletions(-) diff --git a/src/p_local.h b/src/p_local.h index 8a5084962..96401bb75 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -279,6 +279,7 @@ mobjtype_t P_GetMobjtype(UINT16 mthingtype); void P_RespawnSpecials(void); mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type); +void P_SetMobjSpawnDefaults(mobj_t *mobj); void P_RecalcPrecipInSector(sector_t *sector); void P_PrecipitationEffects(void); diff --git a/src/p_mobj.c b/src/p_mobj.c index 7ba6d1fad..e664d85be 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10438,44 +10438,11 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) mobj->x = x; mobj->y = y; - mobj->radius = info->radius; - mobj->height = info->height; - mobj->flags = info->flags; - - mobj->health = (info->spawnhealth ? info->spawnhealth : 1); - - mobj->reactiontime = info->reactiontime; - - mobj->lastlook = -1; // stuff moved in P_enemy.P_LookForPlayer - - // do not set the state with P_SetMobjState, - // because action routines can not be called yet - st = &states[info->spawnstate]; - - mobj->state = st; - mobj->tics = st->tics; - mobj->sprite = st->sprite; - mobj->frame = st->frame; // FF_FRAMEMASK for frame, and other bits.. - P_SetupStateAnimation(mobj, st); - - mobj->friction = ORIG_FRICTION; - - mobj->movefactor = FRACUNIT; - - // All mobjs are created at 100% scale. - mobj->scale = FRACUNIT; - mobj->destscale = mobj->scale; - mobj->scalespeed = FRACUNIT/12; - // TODO: Make this a special map header if ((maptol & TOL_ERZ3) && !(mobj->type == MT_BLACKEGGMAN)) mobj->destscale = FRACUNIT/2; - // Sprite rendering - mobj->blendmode = AST_TRANSLUCENT; - mobj->spritexscale = mobj->spriteyscale = mobj->scale; - mobj->spritexoffset = mobj->spriteyoffset = 0; - mobj->floorspriteslope = NULL; + P_SetMobjSpawnDefaults(mobj); // set subsector and/or block links P_SetThingPosition(mobj); @@ -10785,6 +10752,8 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) mobj->frame &= ~FF_FRAMEMASK; } + st = &states[info->spawnstate]; + // Call action functions when the state is set if (st->action.acp1 && (mobj->flags & MF_RUNSPAWNFUNC)) { @@ -10815,6 +10784,45 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) return mobj; } +void P_SetMobjSpawnDefaults(mobj_t *mobj) +{ + const mobjinfo_t *info = mobj->info; + state_t *st = &states[info->spawnstate]; + + mobj->radius = info->radius; + mobj->height = info->height; + mobj->flags = info->flags; + + mobj->health = (info->spawnhealth ? info->spawnhealth : 1); + + mobj->reactiontime = info->reactiontime; + + mobj->lastlook = -1; // stuff moved in P_enemy.P_LookForPlayer + + // do not set the state with P_SetMobjState, + // because action routines can not be called yet + mobj->state = st; + mobj->tics = st->tics; + mobj->sprite = st->sprite; + mobj->frame = st->frame; // FF_FRAMEMASK for frame, and other bits.. + P_SetupStateAnimation(mobj, st); + + mobj->friction = ORIG_FRICTION; + + mobj->movefactor = FRACUNIT; + + // All mobjs are created at 100% scale. + mobj->scale = FRACUNIT; + mobj->destscale = mobj->scale; + mobj->scalespeed = FRACUNIT/12; + + // Sprite rendering + mobj->blendmode = AST_TRANSLUCENT; + mobj->spritexscale = mobj->spriteyscale = mobj->scale; + mobj->spritexoffset = mobj->spriteyoffset = 0; + mobj->floorspriteslope = NULL; +} + static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) { state_t *st; diff --git a/src/p_saveg.c b/src/p_saveg.c index 03229e740..c1364e08f 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -2692,7 +2692,10 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) } mobj->type = i; } + mobj->info = &mobjinfo[mobj->type]; + P_SetMobjSpawnDefaults(mobj); + if (diff & MD_POS) { mobj->x = READFIXED(save_p); @@ -2718,35 +2721,21 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) if (diff & MD_RADIUS) mobj->radius = READFIXED(save_p); - else - mobj->radius = mobj->info->radius; if (diff & MD_HEIGHT) mobj->height = READFIXED(save_p); - else - mobj->height = mobj->info->height; if (diff & MD_FLAGS) mobj->flags = READUINT32(save_p); - else - mobj->flags = mobj->info->flags; if (diff & MD_FLAGS2) mobj->flags2 = READUINT32(save_p); if (diff & MD_HEALTH) mobj->health = READINT32(save_p); - else - mobj->health = mobj->info->spawnhealth; if (diff & MD_RTIME) mobj->reactiontime = READINT32(save_p); - else - mobj->reactiontime = mobj->info->reactiontime; if (diff & MD_STATE) mobj->state = &states[READUINT16(save_p)]; - else - mobj->state = &states[mobj->info->spawnstate]; if (diff & MD_TICS) mobj->tics = READINT32(save_p); - else - mobj->tics = mobj->state->tics; if (diff & MD_SPRITE) { mobj->sprite = READUINT16(save_p); if (mobj->sprite == SPR_PLAY) @@ -2762,11 +2751,6 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) mobj->frame = READUINT32(save_p); mobj->anim_duration = READUINT16(save_p); } - else - { - mobj->frame = mobj->state->frame; - mobj->anim_duration = (UINT16)mobj->state->var2; - } if (diff & MD_EFLAGS) mobj->eflags = READUINT16(save_p); if (diff & MD_PLAYER) @@ -2783,20 +2767,14 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) mobj->threshold = READINT32(save_p); if (diff & MD_LASTLOOK) mobj->lastlook = READINT32(save_p); - else - mobj->lastlook = -1; if (diff & MD_TARGET) mobj->target = (mobj_t *)(size_t)READUINT32(save_p); if (diff & MD_TRACER) mobj->tracer = (mobj_t *)(size_t)READUINT32(save_p); if (diff & MD_FRICTION) mobj->friction = READFIXED(save_p); - else - mobj->friction = ORIG_FRICTION; if (diff & MD_MOVEFACTOR) mobj->movefactor = READFIXED(save_p); - else - mobj->movefactor = FRACUNIT; if (diff & MD_FUSE) mobj->fuse = READINT32(save_p); if (diff & MD_WATERTOP) @@ -2805,16 +2783,10 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) mobj->waterbottom = READFIXED(save_p); if (diff & MD_SCALE) mobj->scale = READFIXED(save_p); - else - mobj->scale = FRACUNIT; if (diff & MD_DSCALE) mobj->destscale = READFIXED(save_p); - else - mobj->destscale = mobj->scale; if (diff2 & MD2_SCALESPEED) mobj->scalespeed = READFIXED(save_p); - else - mobj->scalespeed = FRACUNIT/12; if (diff2 & MD2_CUSVAL) mobj->cusval = READINT32(save_p); if (diff2 & MD2_CVMEM) @@ -2845,16 +2817,10 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) mobj->renderflags = READUINT32(save_p); if (diff2 & MD2_BLENDMODE) mobj->blendmode = READINT32(save_p); - else - mobj->blendmode = AST_TRANSLUCENT; if (diff2 & MD2_SPRITEXSCALE) mobj->spritexscale = READFIXED(save_p); - else - mobj->spritexscale = FRACUNIT; if (diff2 & MD2_SPRITEYSCALE) mobj->spriteyscale = READFIXED(save_p); - else - mobj->spriteyscale = FRACUNIT; if (diff2 & MD2_SPRITEXOFFSET) mobj->spritexoffset = READFIXED(save_p); if (diff2 & MD2_SPRITEYOFFSET) From 18ee97c583117e7d10e4914e473e47adbfaa13d4 Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Sun, 6 Dec 2020 20:17:14 -0300 Subject: [PATCH 120/644] Fix animated skincolors in OpenGL --- src/hardware/hw_cache.c | 73 +++++++++++++++++++++++++++++++++-------- src/hardware/hw_data.h | 13 ++++++-- src/hardware/hw_main.c | 4 +-- src/hardware/hw_md2.c | 17 ++++++++-- src/m_menu.c | 11 ++----- src/z_zone.c | 12 +++---- 6 files changed, 95 insertions(+), 35 deletions(-) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index b4fa7ec6c..43fdc89f0 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -108,7 +108,7 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm //Hurdler: 25/04/2000: now support colormap in hardware mode if (mipmap->colormap) - texel = mipmap->colormap[texel]; + texel = mipmap->colormap->data[texel]; // hope compiler will get this switch out of the loops (dreams...) // gcc do it ! but vcc not ! (why don't use cygwin gcc for win32 ?) @@ -218,7 +218,7 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block, //Hurdler: 25/04/2000: now support colormap in hardware mode if (mipmap->colormap) - texel = mipmap->colormap[texel]; + texel = mipmap->colormap->data[texel]; // hope compiler will get this switch out of the loops (dreams...) // gcc do it ! but vcc not ! (why don't use cygwin gcc for win32 ?) @@ -659,7 +659,10 @@ void HWR_FreeTextureColormaps(patch_t *patch) // Free image data from memory. if (next->data) Z_Free(next->data); + if (next->colormap) + Z_Free(next->colormap); next->data = NULL; + next->colormap = NULL; HWD.pfnDeleteTexture(next); // Free the old colormap mipmap from memory. @@ -667,16 +670,29 @@ void HWR_FreeTextureColormaps(patch_t *patch) } } +static boolean FreeTextureCallback(void *mem) +{ + patch_t *patch = (patch_t *)mem; + HWR_FreeTexture(patch); + return false; +} + +static boolean FreeColormapsCallback(void *mem) +{ + patch_t *patch = (patch_t *)mem; + HWR_FreeTextureColormaps(patch); + return false; +} + static void HWR_FreePatchCache(boolean freeall) { - INT32 i; + boolean (*callback)(void *mem) = FreeTextureCallback; - for (i = 0; i < numwadfiles; i++) - { - INT32 j = 0; - for (; j < wadfiles[i]->numlumps; j++) - (freeall ? HWR_FreeTexture : HWR_FreeTextureColormaps)(wadfiles[i]->patchcache[j]); - } + if (!freeall) + callback = FreeColormapsCallback; + + Z_IterateTags(PU_PATCH, PU_PATCH_ROTATED, callback); + Z_IterateTags(PU_SPRITE, PU_HUDGFX, callback); } // free all textures after each level @@ -977,8 +993,28 @@ static void HWR_LoadPatchMipmap(patch_t *patch, GLMipmap_t *grMipmap) Z_ChangeTag(grMipmap->data, PU_HWRCACHE_UNLOCKED); } +// ----------------------+ +// HWR_UpdatePatchMipmap : Updates a mipmap. +// ----------------------+ +static void HWR_UpdatePatchMipmap(patch_t *patch, GLMipmap_t *grMipmap) +{ + GLPatch_t *grPatch = patch->hardware; + HWR_MakePatch(patch, grPatch, grMipmap, true); + + // If hardware does not have the texture, then call pfnSetTexture to upload it + // If it does have the texture, then call pfnUpdateTexture to update it + if (!grMipmap->downloaded) + HWD.pfnSetTexture(grMipmap); + else + HWD.pfnUpdateTexture(grMipmap); + HWR_SetCurrentTexture(grMipmap); + + // The system-memory data can be purged now. + Z_ChangeTag(grMipmap->data, PU_HWRCACHE_UNLOCKED); +} + // -----------------+ -// HWR_GetPatch : Download a patch to the hardware cache and make it ready for use +// HWR_GetPatch : Downloads a patch to the hardware cache and make it ready for use // -----------------+ void HWR_GetPatch(patch_t *patch) { @@ -1006,14 +1042,20 @@ void HWR_GetMappedPatch(patch_t *patch, const UINT8 *colormap) return; } - // search for the mimmap + // search for the mipmap // skip the first (no colormap translated) for (grMipmap = grPatch->mipmap; grMipmap->nextcolormap; ) { grMipmap = grMipmap->nextcolormap; - if (grMipmap->colormap == colormap) + if (grMipmap->colormap && grMipmap->colormap->source == colormap) { - HWR_LoadPatchMipmap(patch, grMipmap); + if (memcmp(grMipmap->colormap->data, colormap, 256 * sizeof(UINT8))) + { + M_Memcpy(grMipmap->colormap->data, colormap, 256 * sizeof(UINT8)); + HWR_UpdatePatchMipmap(patch, grMipmap); + } + else + HWR_LoadPatchMipmap(patch, grMipmap); return; } } @@ -1029,7 +1071,10 @@ void HWR_GetMappedPatch(patch_t *patch, const UINT8 *colormap) I_Error("%s: Out of memory", "HWR_GetMappedPatch"); grMipmap->nextcolormap = newMipmap; - newMipmap->colormap = colormap; + newMipmap->colormap = Z_Calloc(sizeof(*newMipmap->colormap), PU_HWRPATCHCOLMIPMAP, NULL); + newMipmap->colormap->source = colormap; + M_Memcpy(newMipmap->colormap->data, colormap, 256 * sizeof(UINT8)); + HWR_LoadPatchMipmap(patch, newMipmap); } diff --git a/src/hardware/hw_data.h b/src/hardware/hw_data.h index 3ae4ef8bc..11e41b18a 100644 --- a/src/hardware/hw_data.h +++ b/src/hardware/hw_data.h @@ -39,6 +39,15 @@ typedef enum GLTextureFormat_e GL_TEXFMT_ALPHA_INTENSITY_88 = 0x22, } GLTextureFormat_t; +// Colormap structure for mipmaps. +struct GLColormap_s +{ + const UINT8 *source; + UINT8 data[256]; +}; +typedef struct GLColormap_s GLColormap_t; + + // data holds the address of the graphics data cached in heap memory // NULL if the texture is not in Doom heap cache. struct GLMipmap_s @@ -53,7 +62,7 @@ struct GLMipmap_s UINT32 downloaded; // The GPU has this texture. struct GLMipmap_s *nextcolormap; - const UINT8 *colormap; + struct GLColormap_s *colormap; struct GLMipmap_s *nextmipmap; // Linked list of all textures }; @@ -77,7 +86,7 @@ struct GLPatch_s { float max_s,max_t; GLMipmap_t *mipmap; -} ATTRPACK; +}; typedef struct GLPatch_s GLPatch_t; #endif //_HWR_DATA_ diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 5dd2727bc..902ce55bd 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5295,7 +5295,7 @@ static void HWR_ProjectSprite(mobj_t *thing) vis->colormap = R_GetTranslationColormap(TC_DEFAULT, vis->mobj->color ? vis->mobj->color : SKINCOLOR_CYAN, GTC_CACHE); } else - vis->colormap = colormaps; + vis->colormap = NULL; // set top/bottom coords vis->gzt = gzt; @@ -5396,7 +5396,7 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing) vis->flip = flip; vis->mobj = (mobj_t *)thing; - vis->colormap = colormaps; + vis->colormap = NULL; // set top/bottom coords vis->gzt = FIXED_TO_FLOAT(thing->z + spritecachedinfo[lumpoff].topoffset); diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 9c786e67e..2e944d3e6 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1106,11 +1106,19 @@ static void HWR_GetBlendedTexture(patch_t *patch, patch_t *blendpatch, INT32 ski for (grMipmap = grPatch->mipmap; grMipmap->nextcolormap; ) { grMipmap = grMipmap->nextcolormap; - if (grMipmap->colormap == colormap) + if (grMipmap->colormap && grMipmap->colormap->source == colormap) { if (grMipmap->downloaded && grMipmap->data) { - HWD.pfnSetTexture(grMipmap); // found the colormap, set it to the correct texture + if (memcmp(grMipmap->colormap->data, colormap, 256 * sizeof(UINT8))) + { + M_Memcpy(grMipmap->colormap->data, colormap, 256 * sizeof(UINT8)); + HWR_CreateBlendedTexture(patch, blendpatch, grMipmap, skinnum, color); + HWD.pfnUpdateTexture(grMipmap); + } + else + HWD.pfnSetTexture(grMipmap); // found the colormap, set it to the correct texture + Z_ChangeTag(grMipmap->data, PU_HWRMODELTEXTURE_UNLOCKED); return; } @@ -1128,7 +1136,10 @@ static void HWR_GetBlendedTexture(patch_t *patch, patch_t *blendpatch, INT32 ski if (newMipmap == NULL) I_Error("%s: Out of memory", "HWR_GetBlendedTexture"); grMipmap->nextcolormap = newMipmap; - newMipmap->colormap = colormap; + + newMipmap->colormap = Z_Calloc(sizeof(*newMipmap->colormap), PU_HWRPATCHCOLMIPMAP, NULL); + newMipmap->colormap->source = colormap; + M_Memcpy(newMipmap->colormap->data, colormap, 256 * sizeof(UINT8)); HWR_CreateBlendedTexture(patch, blendpatch, newMipmap, skinnum, color); diff --git a/src/m_menu.c b/src/m_menu.c index 77648f877..3a6b5ce22 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -8423,7 +8423,7 @@ static void M_DrawLoadGameData(void) sprdef = &charbotskin->sprites[SPR2_SIGN]; if (!sprdef->numframes) goto skipbot; - colormap = R_GetTranslationColormap(savegameinfo[savetodraw].botskin-1, charbotskin->prefcolor, 0); + colormap = R_GetTranslationColormap(savegameinfo[savetodraw].botskin-1, charbotskin->prefcolor, GTC_CACHE); sprframe = &sprdef->spriteframes[0]; patch = W_CachePatchNum(sprframe->lumppat[0], PU_PATCH); @@ -8433,8 +8433,6 @@ static void M_DrawLoadGameData(void) charbotskin->highresscale, 0, patch, colormap); - Z_Free(colormap); - tempx -= (20<sprites[SPR2_SIGN]; - colormap = R_GetTranslationColormap(savegameinfo[savetodraw].skinnum, charskin->prefcolor, 0); + colormap = R_GetTranslationColormap(savegameinfo[savetodraw].skinnum, charskin->prefcolor, GTC_CACHE); if (!sprdef->numframes) goto skipsign; sprframe = &sprdef->spriteframes[0]; @@ -8483,8 +8481,6 @@ skipsign: charskin->highresscale/2, 0, patch, colormap); skiplife: - if (colormap) - Z_Free(colormap); patch = W_CachePatchName("STLIVEX", PU_PATCH); @@ -11755,7 +11751,7 @@ static void M_DrawSetupMultiPlayerMenu(void) goto faildraw; // ok, draw player sprite for sure now - colormap = R_GetTranslationColormap(setupm_fakeskin, setupm_fakecolor->color, 0); + colormap = R_GetTranslationColormap(setupm_fakeskin, setupm_fakecolor->color, GTC_CACHE); if (multi_frame >= sprdef->numframes) multi_frame = 0; @@ -11773,7 +11769,6 @@ static void M_DrawSetupMultiPlayerMenu(void) FixedDiv(skins[setupm_fakeskin].highresscale, skins[setupm_fakeskin].shieldscale), flags, patch, colormap); - Z_Free(colormap); goto colordraw; faildraw: diff --git a/src/z_zone.c b/src/z_zone.c index ad64a3a07..d7da17e51 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -813,12 +813,12 @@ static void Command_Memfree_f(void) #ifdef HWRENDER if (rendermode == render_opengl) { - CONS_Printf(M_GetText("Patch info headers: %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPATCHINFO)>>10)); - CONS_Printf(M_GetText("Mipmap patches : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPATCHCOLMIPMAP)>>10)); - CONS_Printf(M_GetText("HW Texture cache : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRCACHE)>>10)); - CONS_Printf(M_GetText("Plane polygons : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPLANE)>>10)); - CONS_Printf(M_GetText("HW model textures : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRMODELTEXTURE)>>10)); - CONS_Printf(M_GetText("HW Texture used : %7d KB\n"), HWR_GetTextureUsed()>>10); + CONS_Printf(M_GetText("Patch info headers : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPATCHINFO)>>10)); + CONS_Printf(M_GetText("Cached textures : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRCACHE)>>10)); + CONS_Printf(M_GetText("Texture colormaps : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPATCHCOLMIPMAP)>>10)); + CONS_Printf(M_GetText("Model textures : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRMODELTEXTURE)>>10)); + CONS_Printf(M_GetText("Plane polygons : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPLANE)>>10)); + CONS_Printf(M_GetText("All GPU textures : %7d KB\n"), HWR_GetTextureUsed()>>10); } #endif From 284205baacdd2ffb923ef222a3469178f9ddd12f Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Sun, 6 Dec 2020 22:20:06 -0500 Subject: [PATCH 121/644] Fix SPC looping on libgme versions >= 0.6.3 --- src/sdl/mixer_sound.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index c64164caa..d67536b04 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -1298,6 +1298,9 @@ boolean I_PlaySong(boolean looping) if (gme) { gme_equalizer_t eq = {GME_TREBLE, GME_BASS, 0,0,0,0,0,0,0,0}; +#if GME_VERSION >= 0x000603 + gme_set_autoload_playback_limit(gme, 0); +#endif gme_set_equalizer(gme, &eq); gme_start_track(gme, 0); current_track = 0; From c3a560f51d274b039bc3441bb8f4f2994350ea86 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Sun, 6 Dec 2020 22:30:50 -0500 Subject: [PATCH 122/644] Let's check for looping first --- src/sdl/mixer_sound.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index d67536b04..490ebb5ba 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -1299,7 +1299,8 @@ boolean I_PlaySong(boolean looping) { gme_equalizer_t eq = {GME_TREBLE, GME_BASS, 0,0,0,0,0,0,0,0}; #if GME_VERSION >= 0x000603 - gme_set_autoload_playback_limit(gme, 0); + if (looping) + gme_set_autoload_playback_limit(gme, 0); #endif gme_set_equalizer(gme, &eq); gme_start_track(gme, 0); From 11bbad9be8231c0403c1fb41d7c65c4a62a3fec3 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Sun, 6 Dec 2020 22:58:17 -0500 Subject: [PATCH 123/644] Tab fix --- src/sdl/mixer_sound.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index 490ebb5ba..5cae48077 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -1299,8 +1299,8 @@ boolean I_PlaySong(boolean looping) { gme_equalizer_t eq = {GME_TREBLE, GME_BASS, 0,0,0,0,0,0,0,0}; #if GME_VERSION >= 0x000603 - if (looping) - gme_set_autoload_playback_limit(gme, 0); + if (looping) + gme_set_autoload_playback_limit(gme, 0); #endif gme_set_equalizer(gme, &eq); gme_start_track(gme, 0); From 27217259624c287b131d92e2f762057fa791bd12 Mon Sep 17 00:00:00 2001 From: Zippy_Zolton Date: Mon, 7 Dec 2020 16:46:05 -0600 Subject: [PATCH 124/644] Final lap text for circuit --- src/p_spec.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/p_spec.c b/src/p_spec.c index a1afdd00d..cdab17c97 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4823,6 +4823,8 @@ DoneSection2: if (player->laps >= (UINT8)cv_numlaps.value) CONS_Printf(M_GetText("%s has finished the race.\n"), player_names[player-players]); + else if (player->laps == (UINT8)cv_numlaps.value-1) + CONS_Printf(M_GetText("%s started the %c%s%c!\n"), player_names[player-players], 0x85, M_GetText("final lap"), 0x80); else CONS_Printf(M_GetText("%s started lap %u\n"), player_names[player-players], (UINT32)player->laps+1); From c2de684150262cca19402bcace64c14da3362767 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Mon, 7 Dec 2020 17:52:43 -0500 Subject: [PATCH 125/644] Fix double free occuring when unloading the intermission patches due to the same patch being cached twice --- src/y_inter.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/y_inter.c b/src/y_inter.c index 061cbb5e1..bd3b557d7 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -1229,7 +1229,10 @@ void Y_StartIntermission(void) data.coop.tics = players[consoleplayer].realtime; for (i = 0; i < 4; ++i) - data.coop.bonuspatches[i] = W_CachePatchName(data.coop.bonuses[i].patch, PU_PATCH); + { + if (strlen(data.coop.bonuses[i].patch)) + data.coop.bonuspatches[i] = W_CachePatchName(data.coop.bonuses[i].patch, PU_PATCH); + } data.coop.ptotal = W_CachePatchName("YB_TOTAL", PU_PATCH); // get act number @@ -1733,7 +1736,6 @@ static void Y_SetNullBonus(player_t *player, y_bonus_t *bstruct) { (void)player; memset(bstruct, 0, sizeof(y_bonus_t)); - strncpy(bstruct->patch, "MISSING", sizeof(bstruct->patch)); } // From 45a4b728b354fd867641e6c7c372c052ad827d32 Mon Sep 17 00:00:00 2001 From: Zippy_Zolton Date: Tue, 8 Dec 2020 12:05:06 -0600 Subject: [PATCH 126/644] zwip suggestion --- src/p_spec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_spec.c b/src/p_spec.c index cdab17c97..06eee3b12 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4824,7 +4824,7 @@ DoneSection2: if (player->laps >= (UINT8)cv_numlaps.value) CONS_Printf(M_GetText("%s has finished the race.\n"), player_names[player-players]); else if (player->laps == (UINT8)cv_numlaps.value-1) - CONS_Printf(M_GetText("%s started the %c%s%c!\n"), player_names[player-players], 0x85, M_GetText("final lap"), 0x80); + CONS_Printf(M_GetText("%s started the \205final lap\200!\n"), player_names[player-players]); else CONS_Printf(M_GetText("%s started lap %u\n"), player_names[player-players], (UINT32)player->laps+1); From 1b888c689cb2a5a24e13f7fcf34f0b2235dad86c Mon Sep 17 00:00:00 2001 From: Zippy_Zolton Date: Tue, 8 Dec 2020 15:56:45 -0600 Subject: [PATCH 127/644] CTF text 1 --- src/p_spec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index 06eee3b12..e79e02812 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4600,7 +4600,7 @@ DoneSection2: HU_SetCEchoFlags(V_AUTOFADEOUT|V_ALLOWLOWERCASE); HU_SetCEchoDuration(5); - HU_DoCEcho(va(M_GetText("%s%s%s\\CAPTURED THE %sBLUE FLAG%s.\\\\\\\\"), "\x85", player_names[player-players], "\x80", "\x84", "\x80")); + HU_DoCEcho(va(M_GetText("\205%s\200\\CAPTURED THE \204BLUE FLAG\200.\\\\\\\\"), player_names[player-players])); if (splitscreen || players[consoleplayer].ctfteam == 1) S_StartSound(NULL, sfx_flgcap); @@ -4633,7 +4633,7 @@ DoneSection2: HU_SetCEchoFlags(V_AUTOFADEOUT|V_ALLOWLOWERCASE); HU_SetCEchoDuration(5); - HU_DoCEcho(va(M_GetText("%s%s%s\\CAPTURED THE %sRED FLAG%s.\\\\\\\\"), "\x84", player_names[player-players], "\x80", "\x85", "\x80")); + HU_DoCEcho(va(M_GetText("\204%s\200\\CAPTURED THE \205RED FLAG\200.\\\\\\\\"), player_names[player-players])); if (splitscreen || players[consoleplayer].ctfteam == 2) S_StartSound(NULL, sfx_flgcap); From 7082db485b754bd0a007d44b3e71edcdd9e40c96 Mon Sep 17 00:00:00 2001 From: Zippy_Zolton Date: Tue, 8 Dec 2020 16:09:51 -0600 Subject: [PATCH 128/644] CTF text 2, branch is finished --- src/p_mobj.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 7ba6d1fad..0e80496b5 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9835,7 +9835,7 @@ static void P_FlagFuseThink(mobj_t *mobj) if (mobj->type == MT_REDFLAG) { if (!(mobj->flags2 & MF2_JUSTATTACKED)) - CONS_Printf(M_GetText("The %c%s%c has returned to base.\n"), 0x85, M_GetText("Red flag"), 0x80); + CONS_Printf(M_GetText("The \205Red flag\200 has returned to base.\n")); // Assumedly in splitscreen players will be on opposing teams if (players[consoleplayer].ctfteam == 1 || splitscreen) @@ -9848,7 +9848,7 @@ static void P_FlagFuseThink(mobj_t *mobj) else // MT_BLUEFLAG { if (!(mobj->flags2 & MF2_JUSTATTACKED)) - CONS_Printf(M_GetText("The %c%s%c has returned to base.\n"), 0x84, M_GetText("Blue flag"), 0x80); + CONS_Printf(M_GetText("The \204Blue flag\200 has returned to base.\n")); // Assumedly in splitscreen players will be on opposing teams if (players[consoleplayer].ctfteam == 2 || splitscreen) From e7883f3f8e5514433f0e73d9118a7d51e483b135 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 17 Nov 2020 02:51:11 -0800 Subject: [PATCH 129/644] That moment when you see HAVE_BLUA crawl back from the grave This would mean MapChange hasn't been firing for demos ...since 2.2.5. --- src/d_clisrv.c | 2 -- src/g_demo.c | 2 -- 2 files changed, 4 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index b198011a0..14fc1aea5 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1595,9 +1595,7 @@ static void CL_ReloadReceivedSavegame(void) for (i = 0; i < MAXPLAYERS; i++) { -#ifdef HAVE_BLUA LUA_InvalidatePlayer(&players[i]); -#endif sprintf(player_names[i], "Player %d", i + 1); } diff --git a/src/g_demo.c b/src/g_demo.c index 9d3b86015..593fd7723 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -1956,9 +1956,7 @@ void G_DoPlayDemo(char *defdemoname) // Set skin SetPlayerSkin(0, skin); -#ifdef HAVE_BLUA LUAh_MapChange(gamemap); -#endif displayplayer = consoleplayer = 0; memset(playeringame,0,sizeof(playeringame)); playeringame[0] = true; From 8d382e49fb3411cad1a3ef5ee1e546030c3a9d93 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 17 Nov 2020 04:14:45 -0800 Subject: [PATCH 130/644] Big Large Lua Hooklib Refactor * Hooks are no longer a mess of lua boiler plate. Helper functions reduce hooks to, at the most basic level, only two calls. * Lua tables (the array part) are used to index hooks. Such tables contain only hooks of the same type. * Hook types are defined in one place so you no longer need to sync up the enum and name array. --- src/b_bot.c | 6 +- src/d_clisrv.c | 12 +- src/d_netcmd.c | 10 +- src/doomtype.h | 2 + src/g_demo.c | 2 +- src/g_game.c | 10 +- src/hu_stuff.c | 2 +- src/lua_hook.h | 191 ++-- src/lua_hooklib.c | 2630 +++++++++++++++------------------------------ src/lua_script.c | 4 +- src/lua_script.h | 2 +- src/m_menu.c | 4 +- src/p_enemy.c | 2 +- src/p_inter.c | 16 +- src/p_map.c | 8 +- src/p_mobj.c | 22 +- src/p_setup.c | 4 +- src/p_spec.c | 4 +- src/p_tick.c | 12 +- src/p_user.c | 40 +- src/s_sound.c | 12 +- src/s_sound.h | 10 + src/sdl/i_video.c | 2 +- src/y_inter.c | 2 +- 24 files changed, 1055 insertions(+), 1954 deletions(-) diff --git a/src/b_bot.c b/src/b_bot.c index d3635f32c..93a853dee 100644 --- a/src/b_bot.c +++ b/src/b_bot.c @@ -75,7 +75,7 @@ static void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd) return; // Lua can handle it! - if (LUAh_BotAI(sonic, tails, cmd)) + if (LUA_HookBotAI(sonic, tails, cmd)) return; if (tails->player->powers[pw_carry] == CR_MACESPIN || tails->player->powers[pw_carry] == CR_GENERIC) @@ -363,7 +363,7 @@ void B_BuildTiccmd(player_t *player, ticcmd_t *cmd) CV_SetValue(&cv_analog[1], false); // Let Lua scripts build ticcmds - if (LUAh_BotTiccmd(player, cmd)) + if (LUA_HookTiccmd(player, cmd, Hook(BotTiccmd))) return; // We don't have any main character AI, sorry. D: @@ -461,7 +461,7 @@ boolean B_CheckRespawn(player_t *player) // B_RespawnBot doesn't do anything if the condition above this isn't met { - UINT8 shouldForce = LUAh_BotRespawn(sonic, tails); + UINT8 shouldForce = LUA_Hook2Mobj(sonic, tails, Mobj_Hook(BotRespawn)); if (P_MobjWasRemoved(sonic) || P_MobjWasRemoved(tails)) return (shouldForce == 1); // mobj was removed diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 14fc1aea5..91918ed35 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2537,14 +2537,14 @@ static void CL_RemovePlayer(INT32 playernum, kickreason_t reason) } } - LUAh_PlayerQuit(&players[playernum], reason); // Lua hook for player quitting + LUA_HookPlayerQuit(&players[playernum], reason); // Lua hook for player quitting // don't look through someone's view who isn't there if (playernum == displayplayer) { // Call ViewpointSwitch hooks here. // The viewpoint was forcibly changed. - LUAh_ViewpointSwitch(&players[consoleplayer], &players[consoleplayer], true); + LUA_HookViewpointSwitch(&players[consoleplayer], &players[consoleplayer], true); displayplayer = consoleplayer; } @@ -3025,7 +3025,7 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum) if (pnum == consoleplayer) { if (Playing()) - LUAh_GameQuit(); + LUA_Hook(GameQuit); #ifdef DUMPCONSISTENCY if (msg == KICK_MSG_CON_FAIL) SV_SavedGame(); #endif @@ -3445,7 +3445,7 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum) COM_BufAddText(va("sayto %d %s\n", newplayernum, motd)); if (!rejoined) - LUAh_PlayerJoin(newplayernum); + LUA_HookInt(newplayernum, Hook(PlayerJoin)); } static boolean SV_AddWaitingPlayers(const char *name, const char *name2) @@ -3726,7 +3726,7 @@ static void HandleShutdown(SINT8 node) { (void)node; if (Playing()) - LUAh_GameQuit(); + LUA_Hook(GameQuit); D_QuitNetGame(); CL_Reset(); D_StartTitle(); @@ -3742,7 +3742,7 @@ static void HandleTimeout(SINT8 node) { (void)node; if (Playing()) - LUAh_GameQuit(); + LUA_Hook(GameQuit); D_QuitNetGame(); CL_Reset(); D_StartTitle(); diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 31c10f58a..baad9bcdf 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -2103,7 +2103,7 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum) } mapnumber = M_MapNumber(mapname[3], mapname[4]); - LUAh_MapChange(mapnumber); + LUA_HookInt(mapnumber, Hook(MapChange)); G_InitNew(ultimatemode, mapname, resetplayer, skipprecutscene, FLS); if (demoplayback && !timingdemo) @@ -2688,7 +2688,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum) } // Don't switch team, just go away, please, go awaayyyy, aaauuauugghhhghgh - if (!LUAh_TeamSwitch(&players[playernum], NetPacket.packet.newteam, players[playernum].spectator, NetPacket.packet.autobalance, NetPacket.packet.scrambled)) + if (!LUA_HookTeamSwitch(&players[playernum], NetPacket.packet.newteam, players[playernum].spectator, NetPacket.packet.autobalance, NetPacket.packet.scrambled)) return; //no status changes after hidetime @@ -2849,7 +2849,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum) // Call ViewpointSwitch hooks here. // The viewpoint was forcibly changed. if (displayplayer != consoleplayer) // You're already viewing yourself. No big deal. - LUAh_ViewpointSwitch(&players[consoleplayer], &players[consoleplayer], true); + LUA_HookViewpointSwitch(&players[consoleplayer], &players[consoleplayer], true); displayplayer = consoleplayer; } @@ -3607,7 +3607,7 @@ static void Command_Playintro_f(void) FUNCNORETURN static ATTRNORETURN void Command_Quit_f(void) { if (Playing()) - LUAh_GameQuit(); + LUA_Hook(GameQuit); I_Quit(); } @@ -4270,7 +4270,7 @@ void Command_ExitGame_f(void) INT32 i; if (Playing()) - LUAh_GameQuit(); + LUA_Hook(GameQuit); D_QuitNetGame(); CL_Reset(); diff --git a/src/doomtype.h b/src/doomtype.h index 4e13ba96d..8bfedbe92 100644 --- a/src/doomtype.h +++ b/src/doomtype.h @@ -367,6 +367,8 @@ typedef UINT32 tic_t; #define UINT2RGBA(a) (UINT32)((a&0xff)<<24)|((a&0xff00)<<8)|((a&0xff0000)>>8)|(((UINT32)a&0xff000000)>>24) #endif +#define TOSTR(x) #x + /* preprocessor dumb and needs second macro to expand input */ #define WSTRING2(s) L ## s #define WSTRING(s) WSTRING2 (s) diff --git a/src/g_demo.c b/src/g_demo.c index 593fd7723..e4af7086c 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -1956,7 +1956,7 @@ void G_DoPlayDemo(char *defdemoname) // Set skin SetPlayerSkin(0, skin); - LUAh_MapChange(gamemap); + LUA_HookInt(gamemap, Hook(MapChange)); displayplayer = consoleplayer = 0; memset(playeringame,0,sizeof(playeringame)); playeringame[0] = true; diff --git a/src/g_game.c b/src/g_game.c index 283113bbe..c0aaf6af7 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1689,7 +1689,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) cmd->angleturn = orighookangle; - LUAh_PlayerCmd(player, cmd); + LUA_HookTiccmd(player, cmd, Hook(PlayerCmd)); extra = cmd->angleturn - orighookangle; cmd->angleturn = origangle + extra; @@ -1703,7 +1703,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) { // Call ViewpointSwitch hooks here. // The viewpoint was forcibly changed. - LUAh_ViewpointSwitch(player, &players[consoleplayer], true); + LUA_HookViewpointSwitch(player, &players[consoleplayer], true); displayplayer = consoleplayer; } @@ -2076,7 +2076,7 @@ boolean G_Responder(event_t *ev) continue; // Call ViewpointSwitch hooks here. - canSwitchView = LUAh_ViewpointSwitch(&players[consoleplayer], &players[displayplayer], false); + canSwitchView = LUA_HookViewpointSwitch(&players[consoleplayer], &players[displayplayer], false); if (canSwitchView == 1) // Set viewpoint to this player break; else if (canSwitchView == 2) // Skip this player @@ -2713,7 +2713,7 @@ void G_SpawnPlayer(INT32 playernum) P_SpawnPlayer(playernum); G_MovePlayerToSpawnOrStarpost(playernum); - LUAh_PlayerSpawn(&players[playernum]); // Lua hook for player spawning :) + LUA_HookPlayer(&players[playernum], Hook(PlayerSpawn)); // Lua hook for player spawning :) } void G_MovePlayerToSpawnOrStarpost(INT32 playernum) @@ -3092,7 +3092,7 @@ void G_DoReborn(INT32 playernum) } else { - LUAh_MapChange(gamemap); + LUA_HookInt(gamemap, Hook(MapChange)); titlecardforreload = true; G_DoLoadLevel(true); titlecardforreload = false; diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 7e9144f98..9516b466b 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -684,7 +684,7 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) // run the lua hook even if we were supposed to eat the msg, netgame consistency goes first. - if (LUAh_PlayerMsg(playernum, target, flags, msg)) + if (LUA_HookPlayerMsg(playernum, target, flags, msg)) return; if (spam_eatmsg) diff --git a/src/lua_hook.h b/src/lua_hook.h index 796f3a9d2..f44a2e305 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -12,111 +12,100 @@ #include "r_defs.h" #include "d_player.h" +#include "s_sound.h" -enum hook { - hook_NetVars=0, - hook_MapChange, - hook_MapLoad, - hook_PlayerJoin, - hook_PreThinkFrame, - hook_ThinkFrame, - hook_PostThinkFrame, - hook_MobjSpawn, - hook_MobjCollide, - hook_MobjLineCollide, - hook_MobjMoveCollide, - hook_TouchSpecial, - hook_MobjFuse, - hook_MobjThinker, - hook_BossThinker, - hook_ShouldDamage, - hook_MobjDamage, - hook_MobjDeath, - hook_BossDeath, - hook_MobjRemoved, - hook_JumpSpecial, - hook_AbilitySpecial, - hook_SpinSpecial, - hook_JumpSpinSpecial, - hook_BotTiccmd, - hook_BotAI, - hook_BotRespawn, - hook_LinedefExecute, - hook_PlayerMsg, - hook_HurtMsg, - hook_PlayerSpawn, - hook_ShieldSpawn, - hook_ShieldSpecial, - hook_MobjMoveBlocked, - hook_MapThingSpawn, - hook_FollowMobj, - hook_PlayerCanDamage, - hook_PlayerQuit, - hook_IntermissionThinker, - hook_TeamSwitch, - hook_ViewpointSwitch, - hook_SeenPlayer, - hook_PlayerThink, - hook_ShouldJingleContinue, - hook_GameQuit, - hook_PlayerCmd, - hook_MusicChange, +#define Mobj_Hook_List(X) \ + X (MobjSpawn),/* P_SpawnMobj */\ + X (MobjCollide),/* PIT_CheckThing */\ + X (MobjLineCollide),/* ditto */\ + X (MobjMoveCollide),/* tritto */\ + X (TouchSpecial),/* P_TouchSpecialThing */\ + X (MobjFuse),/* when mobj->fuse runs out */\ + X (MobjThinker),/* P_MobjThinker, P_SceneryThinker */\ + X (BossThinker),/* P_GenericBossThinker */\ + X (ShouldDamage),/* P_DamageMobj (Should mobj take damage?) */\ + X (MobjDamage),/* P_DamageMobj (Mobj actually takes damage!) */\ + X (MobjDeath),/* P_KillMobj */\ + X (BossDeath),/* A_BossDeath */\ + X (MobjRemoved),/* P_RemoveMobj */\ + X (BotRespawn),/* B_CheckRespawn */\ + X (MobjMoveBlocked),/* P_XYMovement (when movement is blocked) */\ + X (MapThingSpawn),/* P_SpawnMapThing */\ + X (FollowMobj),/* P_PlayerAfterThink Smiles mobj-following */\ - hook_MAX // last hook -}; -extern const char *const hookNames[]; +#define Hook_List(X) \ + X (NetVars),/* add to archive table (netsave) */\ + X (MapChange),/* (before map load) */\ + X (MapLoad),\ + X (PlayerJoin),/* Got_AddPlayer */\ + X (PreThinkFrame)/* frame (before mobj and player thinkers) */,\ + X (ThinkFrame),/* frame (after mobj and player thinkers) */\ + X (PostThinkFrame),/* frame (at end of tick, ie after overlays, precipitation, specials) */\ + X (JumpSpecial),/* P_DoJumpStuff (Any-jumping) */\ + X (AbilitySpecial),/* P_DoJumpStuff (Double-jumping) */\ + X (SpinSpecial),/* P_DoSpinAbility (Spin button effect) */\ + X (JumpSpinSpecial),/* P_DoJumpStuff (Spin button effect (mid-air)) */\ + X (BotTiccmd),/* B_BuildTiccmd */\ + X (PlayerMsg),/* chat messages */\ + X (HurtMsg),/* imhurttin */\ + X (PlayerSpawn),/* G_SpawnPlayer */\ + X (ShieldSpawn),/* P_SpawnShieldOrb */\ + X (ShieldSpecial),/* shield abilities */\ + X (PlayerCanDamage),/* P_PlayerCanDamage */\ + X (PlayerQuit),\ + X (IntermissionThinker),/* Y_Ticker */\ + X (TeamSwitch),/* team switching in... uh... *what* speak, spit it the fuck out */\ + X (ViewpointSwitch),/* spy mode (no trickstabs) */\ + X (SeenPlayer),/* MT_NAMECHECK */\ + X (PlayerThink),/* P_PlayerThink */\ + X (GameQuit),\ + X (PlayerCmd),/* building the player's ticcmd struct (Ported from SRB2Kart) */\ + X (MusicChange),\ + +#define String_Hook_List(X) \ + X (BotAI),/* B_BuildTailsTiccmd by skin name */\ + X (LinedefExecute),\ + X (ShouldJingleContinue),/* should jingle of the given music continue playing */\ + +#define Mobj_Hook(name) mobjhook_ ## name +#define Hook(name) hook_ ## name +#define String_Hook(name) stringhook_ ## name + +enum { Mobj_Hook_List (Mobj_Hook) Mobj_Hook(MAX) }; +enum { Hook_List (Hook) Hook(MAX) }; +enum { String_Hook_List (String_Hook) String_Hook(MAX) }; extern boolean hook_cmd_running; -void LUAh_MapChange(INT16 mapnumber); // Hook for map change (before load) -void LUAh_MapLoad(void); // Hook for map load -void LUAh_PlayerJoin(int playernum); // Hook for Got_AddPlayer -void LUAh_PreThinkFrame(void); // Hook for frame (before mobj and player thinkers) -void LUAh_ThinkFrame(void); // Hook for frame (after mobj and player thinkers) -void LUAh_PostThinkFrame(void); // Hook for frame (at end of tick, ie after overlays, precipitation, specials) -boolean LUAh_MobjHook(mobj_t *mo, enum hook which); -boolean LUAh_PlayerHook(player_t *plr, enum hook which); -#define LUAh_MobjSpawn(mo) LUAh_MobjHook(mo, hook_MobjSpawn) // Hook for P_SpawnMobj by mobj type -UINT8 LUAh_MobjCollideHook(mobj_t *thing1, mobj_t *thing2, enum hook which); -UINT8 LUAh_MobjLineCollideHook(mobj_t *thing, line_t *line, enum hook which); -#define LUAh_MobjCollide(thing1, thing2) LUAh_MobjCollideHook(thing1, thing2, hook_MobjCollide) // Hook for PIT_CheckThing by (thing) mobj type -#define LUAh_MobjLineCollide(thing, line) LUAh_MobjLineCollideHook(thing, line, hook_MobjLineCollide) // Hook for PIT_CheckThing by (thing) mobj type -#define LUAh_MobjMoveCollide(thing1, thing2) LUAh_MobjCollideHook(thing1, thing2, hook_MobjMoveCollide) // Hook for PIT_CheckThing by (tmthing) mobj type -boolean LUAh_TouchSpecial(mobj_t *special, mobj_t *toucher); // Hook for P_TouchSpecialThing by mobj type -#define LUAh_MobjFuse(mo) LUAh_MobjHook(mo, hook_MobjFuse) // Hook for mobj->fuse == 0 by mobj type -boolean LUAh_MobjThinker(mobj_t *mo); // Hook for P_MobjThinker or P_SceneryThinker by mobj type -#define LUAh_BossThinker(mo) LUAh_MobjHook(mo, hook_BossThinker) // Hook for P_GenericBossThinker by mobj type -UINT8 LUAh_ShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype); // Hook for P_DamageMobj by mobj type (Should mobj take damage?) -boolean LUAh_MobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype); // Hook for P_DamageMobj by mobj type (Mobj actually takes damage!) -boolean LUAh_MobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damagetype); // Hook for P_KillMobj by mobj type -#define LUAh_BossDeath(mo) LUAh_MobjHook(mo, hook_BossDeath) // Hook for A_BossDeath by mobj type -#define LUAh_MobjRemoved(mo) LUAh_MobjHook(mo, hook_MobjRemoved) // Hook for P_RemoveMobj by mobj type -#define LUAh_JumpSpecial(player) LUAh_PlayerHook(player, hook_JumpSpecial) // Hook for P_DoJumpStuff (Any-jumping) -#define LUAh_AbilitySpecial(player) LUAh_PlayerHook(player, hook_AbilitySpecial) // Hook for P_DoJumpStuff (Double-jumping) -#define LUAh_SpinSpecial(player) LUAh_PlayerHook(player, hook_SpinSpecial) // Hook for P_DoSpinAbility (Spin button effect) -#define LUAh_JumpSpinSpecial(player) LUAh_PlayerHook(player, hook_JumpSpinSpecial) // Hook for P_DoJumpStuff (Spin button effect (mid-air)) -boolean LUAh_BotTiccmd(player_t *bot, ticcmd_t *cmd); // Hook for B_BuildTiccmd -boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd); // Hook for B_BuildTailsTiccmd by skin name -boolean LUAh_BotRespawn(mobj_t *sonic, mobj_t *tails); // Hook for B_CheckRespawn -boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo, sector_t *sector); // Hook for linedef executors -boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg); // Hook for chat messages -boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 damagetype); // Hook for hurt messages -#define LUAh_PlayerSpawn(player) LUAh_PlayerHook(player, hook_PlayerSpawn) // Hook for G_SpawnPlayer -#define LUAh_ShieldSpawn(player) LUAh_PlayerHook(player, hook_ShieldSpawn) // Hook for P_SpawnShieldOrb -#define LUAh_ShieldSpecial(player) LUAh_PlayerHook(player, hook_ShieldSpecial) // Hook for shield abilities -#define LUAh_MobjMoveBlocked(mo) LUAh_MobjHook(mo, hook_MobjMoveBlocked) // Hook for P_XYMovement (when movement is blocked) -boolean LUAh_MapThingSpawn(mobj_t *mo, mapthing_t *mthing); // Hook for P_SpawnMapThing by mobj type -boolean LUAh_FollowMobj(player_t *player, mobj_t *mobj); // Hook for P_PlayerAfterThink Smiles mobj-following -UINT8 LUAh_PlayerCanDamage(player_t *player, mobj_t *mobj); // Hook for P_PlayerCanDamage -void LUAh_PlayerQuit(player_t *plr, kickreason_t reason); // Hook for player quitting -void LUAh_IntermissionThinker(void); // Hook for Y_Ticker -boolean LUAh_TeamSwitch(player_t *player, int newteam, boolean fromspectators, boolean tryingautobalance, boolean tryingscramble); // Hook for team switching in... uh.... -UINT8 LUAh_ViewpointSwitch(player_t *player, player_t *newdisplayplayer, boolean forced); // Hook for spy mode +/* dead simple, LUA_Hook(GameQuit) */ +void LUA_Hook(int hook); +#define LUA_Hook(type) LUA_Hook(Hook(type)) + +int LUA_HookMobj(mobj_t *, int hook); +int LUA_Hook2Mobj(mobj_t *, mobj_t *, int hook); +void LUA_HookInt(INT32 integer, int hook); +int LUA_HookPlayer(player_t *, int hook); +int LUA_HookTiccmd(player_t *, ticcmd_t *, int hook); + +void LUA_HookThinkFrame(void); +int LUA_HookMobjLineCollide(mobj_t *, line_t *); +int LUA_HookTouchSpecial(mobj_t *special, mobj_t *toucher); +int LUA_HookShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype); +int LUA_HookMobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype); +int LUA_HookMobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damagetype); +int LUA_HookBotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd); +void LUA_HookLinedefExecute(line_t *, mobj_t *, sector_t *); +int LUA_HookPlayerMsg(int source, int target, int flags, char *msg); +int LUA_HookHurtMsg(player_t *, mobj_t *inflictor, mobj_t *source, UINT8 damagetype); +int LUA_HookMapThingSpawn(mobj_t *, mapthing_t *); +int LUA_HookFollowMobj(player_t *, mobj_t *); +int LUA_HookPlayerCanDamage(player_t *, mobj_t *); +void LUA_HookPlayerQuit(player_t *, kickreason_t); +int LUA_HookTeamSwitch(player_t *, int newteam, boolean fromspectators, boolean tryingautobalance, boolean tryingscramble); +int LUA_HookViewpointSwitch(player_t *player, player_t *newdisplayplayer, boolean forced); #ifdef SEENAMES -boolean LUAh_SeenPlayer(player_t *player, player_t *seenfriend); // Hook for MT_NAMECHECK +int LUA_HookSeenPlayer(player_t *player, player_t *seenfriend); #endif -#define LUAh_PlayerThink(player) LUAh_PlayerHook(player, hook_PlayerThink) // Hook for P_PlayerThink -boolean LUAh_ShouldJingleContinue(player_t *player, const char *musname); // Hook for whether a jingle of the given music should continue playing -void LUAh_GameQuit(void); // Hook for game quitting -boolean LUAh_PlayerCmd(player_t *player, ticcmd_t *cmd); // Hook for building player's ticcmd struct (Ported from SRB2Kart) -boolean LUAh_MusicChange(const char *oldname, char *newname, UINT16 *mflags, boolean *looping, UINT32 *position, UINT32 *prefadems, UINT32 *fadeinms); // Hook for music changes \ No newline at end of file +int LUA_HookShouldJingleContinue(player_t *, const char *musname); +int LUA_HookPlayerCmd(player_t *, ticcmd_t *); +int LUA_HookMusicChange(const char *oldname, struct MusicChange *); diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 117aa48a3..dce67cef7 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -27,1948 +27,1038 @@ #include "d_netcmd.h" // for cv_perfstats #include "i_system.h" // I_GetTimeMicros -static UINT8 hooksAvailable[(hook_MAX/8)+1]; +#undef LUA_Hook -const char *const hookNames[hook_MAX+1] = { - "NetVars", - "MapChange", - "MapLoad", - "PlayerJoin", - "PreThinkFrame", - "ThinkFrame", - "PostThinkFrame", - "MobjSpawn", - "MobjCollide", - "MobjLineCollide", - "MobjMoveCollide", - "TouchSpecial", - "MobjFuse", - "MobjThinker", - "BossThinker", - "ShouldDamage", - "MobjDamage", - "MobjDeath", - "BossDeath", - "MobjRemoved", - "JumpSpecial", - "AbilitySpecial", - "SpinSpecial", - "JumpSpinSpecial", - "BotTiccmd", - "BotAI", - "BotRespawn", - "LinedefExecute", - "PlayerMsg", - "HurtMsg", - "PlayerSpawn", - "ShieldSpawn", - "ShieldSpecial", - "MobjMoveBlocked", - "MapThingSpawn", - "FollowMobj", - "PlayerCanDamage", - "PlayerQuit", - "IntermissionThinker", - "TeamSwitch", - "ViewpointSwitch", - "SeenPlayer", - "PlayerThink", - "ShouldJingleContinue", - "GameQuit", - "PlayerCmd", - "MusicChange", - NULL +/* ========================================================================= + ABSTRACTION + ========================================================================= */ + +static const char * const mobjHookNames[] = { Mobj_Hook_List (TOSTR) NULL }; +static const char * const hookNames[] = { Hook_List (TOSTR) NULL }; + +static const char * const stringHookNames[] = { + String_Hook_List (TOSTR) NULL }; -// Hook metadata -struct hook_s +/* TODO: remove when doomtype version is merged */ + +#define BIT_ARRAY_LENGTH(n) (((n) + 7) >> 3) + +static inline void set_bit_array (UINT8 *array, const int n) { + array[n >> 3] |= 1 << (n & 7); +} + +static inline int in_bit_array (const UINT8 *array, const int n) { + return array[n >> 3] & (1 << (n & 7)); +} + +typedef struct { + int numGeneric; + int ref; +} stringhook_t; + +static int hookRefs[Hook(MAX)]; +static int mobjHookRefs[NUMMOBJTYPES][Mobj_Hook(MAX)]; + +static stringhook_t stringHooks[String_Hook(MAX)]; + +static int hookReg; + +// After a hook errors once, don't print the error again. +static UINT8 * hooksErrored; + +static boolean mobj_hook_available(int hook_type, mobjtype_t mobj_type) { - struct hook_s *next; - enum hook type; - UINT16 id; - union { - mobjtype_t mt; - char *str; - } s; - boolean error; -}; -typedef struct hook_s* hook_p; + return + ( + mobjHookRefs [MT_NULL] [hook_type] > 0 || + mobjHookRefs[mobj_type][hook_type] > 0 + ); +} -#define FMT_HOOKID "hook_%d" +static int hook_in_list +( + const char * const name, + const char * const * const list +){ + int type; -// For each mobj type, a linked list to its thinker and collision hooks. -// That way, we don't have to iterate through all the hooks. -// We could do that with all other mobj hooks, but it would probably just be -// a waste of memory since they are only called occasionally. Probably... -static hook_p mobjthinkerhooks[NUMMOBJTYPES]; -static hook_p mobjcollidehooks[NUMMOBJTYPES]; + for (type = 0; list[type] != NULL; ++type) + { + if (strcmp(name, list[type]) == 0) + break; + } -// For each mobj type, a linked list for other mobj hooks -static hook_p mobjhooks[NUMMOBJTYPES]; + return type; +} -// A linked list for player hooks -static hook_p playerhooks; - -// A linked list for linedef executor hooks -static hook_p linedefexecutorhooks; - -// For other hooks, a unique linked list -hook_p roothook; - -static void PushHook(lua_State *L, hook_p hookp) +static void get_table(lua_State *L) { - lua_pushfstring(L, FMT_HOOKID, hookp->id); - lua_gettable(L, LUA_REGISTRYINDEX); + lua_pushvalue(L, -1); + lua_rawget(L, -3); + + if (lua_isnil(L, -1)) + { + lua_pop(L, 1); + lua_createtable(L, 1, 0); + lua_pushvalue(L, -2); + lua_pushvalue(L, -2); + lua_rawset(L, -5); + } + + lua_remove(L, -2); +} + +static void new_hook_table(lua_State *L, int *ref) +{ + if (*ref > 0) + lua_getref(L, *ref); + else + { + lua_newtable(L); + lua_pushvalue(L, -1); + *ref = luaL_ref(L, LUA_REGISTRYINDEX); + } +} + +static void add_hook(lua_State *L, int id) +{ + lua_pushnumber(L, 1 + id); + lua_rawseti(L, -2, 1 + lua_objlen(L, -2)); +} + +static void add_mobj_hook(lua_State *L, int hook_type, int id) +{ + mobjtype_t mobj_type = luaL_optnumber(L, 3, MT_NULL); + + luaL_argcheck(L, mobj_type < NUMMOBJTYPES, 3, "invalid mobjtype_t"); + + new_hook_table(L, &mobjHookRefs[mobj_type][hook_type]); + add_hook(L, id); +} + +static void add_string_hook(lua_State *L, int type, int id) +{ + stringhook_t * hook = &stringHooks[type]; + + char * string = NULL; + + switch (type) + { + case String_Hook(BotAI): + case String_Hook(ShouldJingleContinue): + if (lua_isstring(L, 3)) + { // lowercase copy + string = Z_StrDup(lua_tostring(L, 3)); + strlwr(string); + } + break; + + case String_Hook(LinedefExecute): + string = Z_StrDup(luaL_checkstring(L, 3)); + strupr(string); + break; + } + + new_hook_table(L, &hook->ref); + + if (string) + { + lua_pushstring(L, string); + get_table(L); + add_hook(L, id); + } + else + { + lua_pushnumber(L, 1 + id); + lua_rawseti(L, -2, ++hook->numGeneric); + } } // Takes hook, function, and additional arguments (mobj type to act on, etc.) static int lib_addHook(lua_State *L) { - static struct hook_s hook = {NULL, 0, 0, {0}, false}; - static UINT32 nextid; - hook_p hookp, *lastp; + static int nextid; - hook.type = luaL_checkoption(L, 1, NULL, hookNames); - lua_remove(L, 1); - - luaL_checktype(L, 1, LUA_TFUNCTION); + const char * name; + int type; if (!lua_lumploading) return luaL_error(L, "This function cannot be called from within a hook or coroutine!"); - switch(hook.type) + name = luaL_checkstring(L, 1); + luaL_checktype(L, 2, LUA_TFUNCTION); + + /* this is a very special case */ + if (( type = hook_in_list(name, stringHookNames) ) < String_Hook(MAX)) { - // Take a mobjtype enum which this hook is specifically for. - case hook_MobjSpawn: - case hook_MobjCollide: - case hook_MobjLineCollide: - case hook_MobjMoveCollide: - case hook_TouchSpecial: - case hook_MobjFuse: - case hook_MobjThinker: - case hook_BossThinker: - case hook_ShouldDamage: - case hook_MobjDamage: - case hook_MobjDeath: - case hook_BossDeath: - case hook_MobjRemoved: - case hook_HurtMsg: - case hook_MobjMoveBlocked: - case hook_MapThingSpawn: - case hook_FollowMobj: - hook.s.mt = MT_NULL; - if (lua_isnumber(L, 2)) - hook.s.mt = lua_tonumber(L, 2); - luaL_argcheck(L, hook.s.mt < NUMMOBJTYPES, 2, "invalid mobjtype_t"); - break; - case hook_BotAI: - case hook_ShouldJingleContinue: - hook.s.str = NULL; - if (lua_isstring(L, 2)) - { // lowercase copy - hook.s.str = Z_StrDup(lua_tostring(L, 2)); - strlwr(hook.s.str); - } - break; - case hook_LinedefExecute: // Linedef executor functions - hook.s.str = Z_StrDup(luaL_checkstring(L, 2)); - strupr(hook.s.str); - break; - default: - break; + add_string_hook(L, type, nextid); } - lua_settop(L, 1); // lua stack contains only the function now. - - hooksAvailable[hook.type/8] |= 1<<(hook.type%8); - - // set hook.id to the highest id + 1 - hook.id = nextid++; - - // Special cases for some hook types (see the comments above mobjthinkerhooks declaration) - switch(hook.type) + else if (( type = hook_in_list(name, mobjHookNames) ) < Mobj_Hook(MAX)) { - case hook_MobjThinker: - lastp = &mobjthinkerhooks[hook.s.mt]; - break; - case hook_MobjCollide: - case hook_MobjLineCollide: - case hook_MobjMoveCollide: - lastp = &mobjcollidehooks[hook.s.mt]; - break; - case hook_MobjSpawn: - case hook_TouchSpecial: - case hook_MobjFuse: - case hook_BossThinker: - case hook_ShouldDamage: - case hook_MobjDamage: - case hook_MobjDeath: - case hook_BossDeath: - case hook_MobjRemoved: - case hook_MobjMoveBlocked: - case hook_MapThingSpawn: - case hook_FollowMobj: - lastp = &mobjhooks[hook.s.mt]; - break; - case hook_JumpSpecial: - case hook_AbilitySpecial: - case hook_SpinSpecial: - case hook_JumpSpinSpecial: - case hook_PlayerSpawn: - case hook_PlayerCanDamage: - case hook_TeamSwitch: - case hook_ViewpointSwitch: - case hook_SeenPlayer: - case hook_ShieldSpawn: - case hook_ShieldSpecial: - case hook_PlayerThink: - lastp = &playerhooks; - break; - case hook_LinedefExecute: - lastp = &linedefexecutorhooks; - break; - default: - lastp = &roothook; - break; + add_mobj_hook(L, type, nextid); + } + else if (( type = hook_in_list(name, hookNames) ) < Hook(MAX)) + { + new_hook_table(L, &hookRefs[type]); + add_hook(L, nextid); + } + else + { + return luaL_argerror(L, 1, lua_pushfstring(L, "invalid hook " LUA_QS, name)); } - // iterate the hook metadata structs - // set lastp to the last hook struct's "next" pointer. - for (hookp = *lastp; hookp; hookp = hookp->next) - lastp = &hookp->next; - // allocate a permanent memory struct to stuff hook. - hookp = ZZ_Alloc(sizeof(struct hook_s)); - memcpy(hookp, &hook, sizeof(struct hook_s)); - // tack it onto the end of the linked list. - *lastp = hookp; + if (!(nextid & 7)) + { + Z_Realloc(hooksErrored, + BIT_ARRAY_LENGTH (nextid + 1) * sizeof *hooksErrored, + PU_STATIC, &hooksErrored); + hooksErrored[nextid >> 3] = 0; + } // set the hook function in the registry. - lua_pushfstring(L, FMT_HOOKID, hook.id); - lua_pushvalue(L, 1); - lua_settable(L, LUA_REGISTRYINDEX); + lua_getref(L, hookReg); + lua_pushvalue(L, 2);/* the function */ + lua_rawseti(L, -2, ++nextid); + return 0; } int LUA_HookLib(lua_State *L) { - memset(hooksAvailable,0,sizeof(UINT8[(hook_MAX/8)+1])); - roothook = NULL; + new_hook_table(L, &hookReg); lua_register(L, "addHook", lib_addHook); return 0; } -boolean LUAh_MobjHook(mobj_t *mo, enum hook which) +typedef struct Hook_State Hook_State; +typedef void (*Hook_Callback)(Hook_State *); + +struct Hook_State { + int status;/* return status to calling function */ + void * userdata; + int ref;/* ref for primary hook table */ + int hook_type;/* Hook or Hook(MAX) + Mobj_Hook */ + mobjtype_t mobj_type; + const char * string;/* used to fetch table, ran first if set */ + int top;/* index of last argument passed to hook */ + int id;/* id to fetch function from registry */ + int values;/* num arguments passed to hook */ + int results;/* num values returned by hook */ + Hook_Callback results_handler;/* callback when hook successfully returns */ +}; + +enum { + HINDEX = 1,/* hook registry */ + EINDEX = 2,/* error handler */ + SINDEX = 3,/* string itself is pushed in case of string hook */ +}; + +static void push_error_handler(void) { - hook_p hookp; - boolean hooked = false; - if (!gL || !(hooksAvailable[which/8] & (1<<(which%8)))) - return false; - - I_Assert(mo->type < NUMMOBJTYPES); - - if (!(mobjhooks[MT_NULL] || mobjhooks[mo->type])) - return false; - - lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); +} - // Look for all generic mobj hooks - for (hookp = mobjhooks[MT_NULL]; hookp; hookp = hookp->next) +/* repush hook string */ +static void push_string(void) +{ + lua_pushvalue(gL, SINDEX); +} + +static boolean start_hook_stack(void) +{ + lua_settop(gL, 0); + lua_getref(gL, hookReg); + push_error_handler(); + return true; +} + +static boolean init_hook_type +( + Hook_State * hook, + int status, + int hook_type, + mobjtype_t mobj_type, + const char * string, + int ref +){ + boolean ready; + + hook->status = status; + + if (mobj_type > 0) + ready = mobj_hook_available(hook_type, mobj_type); + else + ready = ref > 0; + + if (ready) { - if (hookp->type != which) - continue; + hook->ref = ref; + hook->hook_type = hook_type; + hook->mobj_type = mobj_type; + hook->string = string; + return start_hook_stack(); + } + else + return false; +} - ps_lua_mobjhooks++; - if (lua_gettop(gL) == 1) - LUA_PushUserdata(gL, mo, META_MOBJ); - PushHook(gL, hookp); - lua_pushvalue(gL, -2); - if (lua_pcall(gL, 1, 1, 1)) { - if (!hookp->error || cv_debug & DBG_LUA) - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); - hookp->error = true; - continue; +static boolean prepare_hook +( + Hook_State * hook, + int default_status, + int hook_type +){ + return init_hook_type(hook, default_status, + hook_type, 0, NULL, + hookRefs[hook_type]); +} + +static boolean prepare_mobj_hook +( + Hook_State * hook, + int default_status, + int hook_type, + mobjtype_t mobj_type +){ + return init_hook_type(hook, default_status, + hook_type, mobj_type, NULL, + mobjHookRefs[mobj_type][hook_type]); +} + +static boolean prepare_string_hook +( + Hook_State * hook, + int default_status, + int hook_type, + const char * string +){ + if (init_hook_type(hook, default_status, + hook_type, 0, string, + stringHooks[hook_type].ref)) + { + lua_pushstring(gL, string); + return true; + } + else + return false; +} + +static void init_hook_call +( + Hook_State * hook, + int values, + int results, + Hook_Callback results_handler +){ + hook->top = lua_gettop(gL); + hook->values = values; + hook->results = results; + hook->results_handler = results_handler; +} + +static void get_hook_table(Hook_State *hook) +{ + lua_getref(gL, hook->ref); +} + +static void get_hook(Hook_State *hook, int n) +{ + lua_rawgeti(gL, -1, n); + hook->id = lua_tonumber(gL, -1) - 1; + lua_rawget(gL, HINDEX); +} + +static int call_single_hook_no_copy(Hook_State *hook) +{ + if (lua_pcall(gL, hook->values, hook->results, EINDEX) == 0) + { + if (hook->results > 0) + { + (*hook->results_handler)(hook); + lua_pop(gL, hook->results); + } + } + else + { + /* print the error message once */ + if (cv_debug & DBG_LUA || !in_bit_array(hooksErrored, hook->id)) + { + CONS_Alert(CONS_WARNING, "%s\n", lua_tostring(gL, -1)); + set_bit_array(hooksErrored, hook->id); } - if (lua_toboolean(gL, -1)) - hooked = true; lua_pop(gL, 1); } - for (hookp = mobjhooks[mo->type]; hookp; hookp = hookp->next) - { - if (hookp->type != which) - continue; + return 1; +} - ps_lua_mobjhooks++; - if (lua_gettop(gL) == 1) - LUA_PushUserdata(gL, mo, META_MOBJ); - PushHook(gL, hookp); - lua_pushvalue(gL, -2); - if (lua_pcall(gL, 1, 1, 1)) { - if (!hookp->error || cv_debug & DBG_LUA) - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); - hookp->error = true; - continue; - } +static int call_single_hook(Hook_State *hook) +{ + int i; + + for (i = -(hook->values) + 1; i <= 0; ++i) + lua_pushvalue(gL, hook->top + i); + + return call_single_hook_no_copy(hook); +} + +static int call_hook_table_for(Hook_State *hook, int n) +{ + int k; + + for (k = 1; k <= n; ++k) + { + get_hook(hook, k); + call_single_hook(hook); + } + + return n; +} + +static int call_hook_table(Hook_State *hook) +{ + return call_hook_table_for(hook, lua_objlen(gL, -1)); +} + +static int call_ref(Hook_State *hook, int ref) +{ + int calls; + + if (ref > 0) + { + lua_getref(gL, ref); + calls = call_hook_table(hook); + + return calls; + } + else + return 0; +} + +static int call_string_hooks(Hook_State *hook) +{ + const int numGeneric = stringHooks[hook->hook_type].numGeneric; + + int calls = 0; + + get_hook_table(hook); + + /* call generic string hooks first */ + calls += call_hook_table_for(hook, numGeneric); + + push_string(); + lua_rawget(gL, -2); + calls += call_hook_table(hook); + + return calls; +} + +static int call_generic_mobj_hooks(Hook_State *hook) +{ + const int ref = mobjHookRefs[MT_NULL][hook->hook_type]; + return call_ref(hook, ref); +} + +static int call_hooks +( + Hook_State * hook, + int values, + int results, + Hook_Callback results_handler +){ + int calls = 0; + + init_hook_call(hook, values, results, results_handler); + + if (hook->string) + { + calls += call_string_hooks(hook); + } + else + { + if (hook->mobj_type > 0) + calls += call_generic_mobj_hooks(hook); + + calls += call_ref(hook, hook->ref); + + if (hook->mobj_type > 0) + ps_lua_mobjhooks += calls; + } + + lua_settop(gL, 0); + + return calls; +} + +/* ========================================================================= + COMMON RESULT HANDLERS + ========================================================================= */ + +#define res_none NULL + +static void res_true(Hook_State *hook) +{ + if (lua_toboolean(gL, -1)) + hook->status = true; +} + +static void res_false(Hook_State *hook) +{ + if (!lua_isnil(gL, -1) && !lua_toboolean(gL, -1)) + hook->status = false; +} + +static void res_force(Hook_State *hook) +{ + if (!lua_isnil(gL, -1)) + { if (lua_toboolean(gL, -1)) - hooked = true; - lua_pop(gL, 1); + hook->status = 1; // Force yes + else + hook->status = 2; // Force no } - - lua_settop(gL, 0); - return hooked; } -boolean LUAh_PlayerHook(player_t *plr, enum hook which) +/* ========================================================================= + GENERALISED HOOKS + ========================================================================= */ + +int LUA_HookMobj(mobj_t *mobj, int hook_type) { - hook_p hookp; - boolean hooked = false; - if (!gL || !(hooksAvailable[which/8] & (1<<(which%8)))) - return false; - - lua_settop(gL, 0); - lua_pushcfunction(gL, LUA_GetErrorMessage); - - for (hookp = playerhooks; hookp; hookp = hookp->next) + Hook_State hook; + if (prepare_mobj_hook(&hook, false, hook_type, mobj->type)) { - if (hookp->type != which) - continue; - - ps_lua_mobjhooks++; - if (lua_gettop(gL) == 1) - LUA_PushUserdata(gL, plr, META_PLAYER); - PushHook(gL, hookp); - lua_pushvalue(gL, -2); - if (lua_pcall(gL, 1, 1, 1)) { - if (!hookp->error || cv_debug & DBG_LUA) - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); - hookp->error = true; - continue; - } - if (lua_toboolean(gL, -1)) - hooked = true; - lua_pop(gL, 1); + LUA_PushUserdata(gL, mobj, META_MOBJ); + call_hooks(&hook, 1, 1, res_true); } - - lua_settop(gL, 0); - return hooked; + return hook.status; } -// Hook for map change (before load) -void LUAh_MapChange(INT16 mapnumber) +int LUA_Hook2Mobj(mobj_t *t1, mobj_t *t2, int hook_type) { - hook_p hookp; - if (!gL || !(hooksAvailable[hook_MapChange/8] & (1<<(hook_MapChange%8)))) - return; - - lua_settop(gL, 0); - lua_pushcfunction(gL, LUA_GetErrorMessage); - lua_pushinteger(gL, mapnumber); - - for (hookp = roothook; hookp; hookp = hookp->next) + Hook_State hook; + if (prepare_mobj_hook(&hook, 0, hook_type, t1->type)) { - if (hookp->type != hook_MapChange) - continue; - - PushHook(gL, hookp); - lua_pushvalue(gL, -2); - if (lua_pcall(gL, 1, 0, 1)) { - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); - } + LUA_PushUserdata(gL, t1, META_MOBJ); + LUA_PushUserdata(gL, t2, META_MOBJ); + call_hooks(&hook, 2, 1, res_force); } - - lua_settop(gL, 0); + return hook.status; } -// Hook for map load -void LUAh_MapLoad(void) +void LUA_Hook(int type) { - hook_p hookp; - if (!gL || !(hooksAvailable[hook_MapLoad/8] & (1<<(hook_MapLoad%8)))) - return; + Hook_State hook; + if (prepare_hook(&hook, 0, type)) + call_hooks(&hook, 0, 0, res_none); +} - lua_settop(gL, 0); - lua_pushcfunction(gL, LUA_GetErrorMessage); - lua_pushinteger(gL, gamemap); - - for (hookp = roothook; hookp; hookp = hookp->next) +void LUA_HookInt(INT32 number, int hook_type) +{ + Hook_State hook; + if (prepare_hook(&hook, 0, hook_type)) { - if (hookp->type != hook_MapLoad) - continue; - - PushHook(gL, hookp); - lua_pushvalue(gL, -2); - if (lua_pcall(gL, 1, 0, 1)) { - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); - } + lua_pushinteger(gL, number); + call_hooks(&hook, 1, 0, res_none); } - - lua_settop(gL, 0); } -// Hook for Got_AddPlayer -void LUAh_PlayerJoin(int playernum) +int LUA_HookPlayer(player_t *player, int hook_type) { - hook_p hookp; - if (!gL || !(hooksAvailable[hook_PlayerJoin/8] & (1<<(hook_PlayerJoin%8)))) - return; - - lua_settop(gL, 0); - lua_pushcfunction(gL, LUA_GetErrorMessage); - lua_pushinteger(gL, playernum); - - for (hookp = roothook; hookp; hookp = hookp->next) + Hook_State hook; + if (prepare_hook(&hook, false, hook_type)) { - if (hookp->type != hook_PlayerJoin) - continue; - - PushHook(gL, hookp); - lua_pushvalue(gL, -2); - if (lua_pcall(gL, 1, 0, 1)) { - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); - } + LUA_PushUserdata(gL, player, META_PLAYER); + call_hooks(&hook, 1, 1, res_true); } - - lua_settop(gL, 0); + return hook.status; } -// Hook for frame (before mobj and player thinkers) -void LUAh_PreThinkFrame(void) +int LUA_HookTiccmd(player_t *player, ticcmd_t *cmd, int hook_type) { - hook_p hookp; - if (!gL || !(hooksAvailable[hook_PreThinkFrame/8] & (1<<(hook_PreThinkFrame%8)))) - return; - - lua_pushcfunction(gL, LUA_GetErrorMessage); - - for (hookp = roothook; hookp; hookp = hookp->next) + Hook_State hook; + if (prepare_hook(&hook, false, hook_type)) { - if (hookp->type != hook_PreThinkFrame) - continue; + LUA_PushUserdata(gL, player, META_PLAYER); + LUA_PushUserdata(gL, cmd, META_TICCMD); - PushHook(gL, hookp); - if (lua_pcall(gL, 0, 0, 1)) { - if (!hookp->error || cv_debug & DBG_LUA) - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); - hookp->error = true; - } + if (hook_type == Hook(PlayerCmd)) + hook_cmd_running = true; + + call_hooks(&hook, 2, 1, res_true); + + if (hook_type == Hook(PlayerCmd)) + hook_cmd_running = false; } - - lua_pop(gL, 1); // Pop error handler + return hook.status; } -// Hook for frame (after mobj and player thinkers) -void LUAh_ThinkFrame(void) +/* ========================================================================= + SPECIALIZED HOOKS + ========================================================================= */ + +void LUA_HookThinkFrame(void) { - hook_p hookp; // variables used by perf stats int hook_index = 0; int time_taken = 0; - if (!gL || !(hooksAvailable[hook_ThinkFrame/8] & (1<<(hook_ThinkFrame%8)))) - return; - lua_pushcfunction(gL, LUA_GetErrorMessage); + Hook_State hook; - for (hookp = roothook; hookp; hookp = hookp->next) + int n; + int k; + + if (prepare_hook(&hook, 0, Hook(ThinkFrame))) { - if (hookp->type != hook_ThinkFrame) - continue; + init_hook_call(&hook, 0, 0, res_none); - if (cv_perfstats.value == 3) - time_taken = I_GetTimeMicros(); - PushHook(gL, hookp); - if (lua_pcall(gL, 0, 0, 1)) { - if (!hookp->error || cv_debug & DBG_LUA) - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); - hookp->error = true; - } - if (cv_perfstats.value == 3) + get_hook_table(&hook); + n = lua_objlen(gL, -1); + + for (k = 1; k <= n; ++k) { - lua_Debug ar; - time_taken = I_GetTimeMicros() - time_taken; - // we need the function, let's just retrieve it again - PushHook(gL, hookp); - lua_getinfo(gL, ">S", &ar); - PS_SetThinkFrameHookInfo(hook_index, time_taken, ar.short_src); - hook_index++; - } - } + get_hook(&hook, k); - lua_pop(gL, 1); // Pop error handler -} - -// Hook for frame (at end of tick, ie after overlays, precipitation, specials) -void LUAh_PostThinkFrame(void) -{ - hook_p hookp; - if (!gL || !(hooksAvailable[hook_PostThinkFrame/8] & (1<<(hook_PostThinkFrame%8)))) - return; - - lua_pushcfunction(gL, LUA_GetErrorMessage); - - for (hookp = roothook; hookp; hookp = hookp->next) - { - if (hookp->type != hook_PostThinkFrame) - continue; - - PushHook(gL, hookp); - if (lua_pcall(gL, 0, 0, 1)) { - if (!hookp->error || cv_debug & DBG_LUA) - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); - hookp->error = true; - } - } - - lua_pop(gL, 1); // Pop error handler -} - -// Hook for mobj collisions -UINT8 LUAh_MobjCollideHook(mobj_t *thing1, mobj_t *thing2, enum hook which) -{ - hook_p hookp; - UINT8 shouldCollide = 0; // 0 = default, 1 = force yes, 2 = force no. - if (!gL || !(hooksAvailable[which/8] & (1<<(which%8)))) - return 0; - - I_Assert(thing1->type < NUMMOBJTYPES); - - if (!(mobjcollidehooks[MT_NULL] || mobjcollidehooks[thing1->type])) - return 0; - - lua_settop(gL, 0); - lua_pushcfunction(gL, LUA_GetErrorMessage); - - // Look for all generic mobj collision hooks - for (hookp = mobjcollidehooks[MT_NULL]; hookp; hookp = hookp->next) - { - if (hookp->type != which) - continue; - - ps_lua_mobjhooks++; - if (lua_gettop(gL) == 1) - { - LUA_PushUserdata(gL, thing1, META_MOBJ); - LUA_PushUserdata(gL, thing2, META_MOBJ); - } - PushHook(gL, hookp); - lua_pushvalue(gL, -3); - lua_pushvalue(gL, -3); - if (lua_pcall(gL, 2, 1, 1)) { - if (!hookp->error || cv_debug & DBG_LUA) - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); - hookp->error = true; - continue; - } - if (!lua_isnil(gL, -1)) - { // if nil, leave shouldCollide = 0. - if (lua_toboolean(gL, -1)) - shouldCollide = 1; // Force yes - else - shouldCollide = 2; // Force no - } - lua_pop(gL, 1); - } - - for (hookp = mobjcollidehooks[thing1->type]; hookp; hookp = hookp->next) - { - if (hookp->type != which) - continue; - - ps_lua_mobjhooks++; - if (lua_gettop(gL) == 1) - { - LUA_PushUserdata(gL, thing1, META_MOBJ); - LUA_PushUserdata(gL, thing2, META_MOBJ); - } - PushHook(gL, hookp); - lua_pushvalue(gL, -3); - lua_pushvalue(gL, -3); - if (lua_pcall(gL, 2, 1, 1)) { - if (!hookp->error || cv_debug & DBG_LUA) - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); - hookp->error = true; - continue; - } - if (!lua_isnil(gL, -1)) - { // if nil, leave shouldCollide = 0. - if (lua_toboolean(gL, -1)) - shouldCollide = 1; // Force yes - else - shouldCollide = 2; // Force no - } - lua_pop(gL, 1); - } - - lua_settop(gL, 0); - return shouldCollide; -} - -UINT8 LUAh_MobjLineCollideHook(mobj_t *thing, line_t *line, enum hook which) -{ - hook_p hookp; - UINT8 shouldCollide = 0; // 0 = default, 1 = force yes, 2 = force no. - if (!gL || !(hooksAvailable[which/8] & (1<<(which%8)))) - return 0; - - I_Assert(thing->type < NUMMOBJTYPES); - - if (!(mobjcollidehooks[MT_NULL] || mobjcollidehooks[thing->type])) - return 0; - - lua_settop(gL, 0); - lua_pushcfunction(gL, LUA_GetErrorMessage); - - // Look for all generic mobj collision hooks - for (hookp = mobjcollidehooks[MT_NULL]; hookp; hookp = hookp->next) - { - if (hookp->type != which) - continue; - - ps_lua_mobjhooks++; - if (lua_gettop(gL) == 1) - { - LUA_PushUserdata(gL, thing, META_MOBJ); - LUA_PushUserdata(gL, line, META_LINE); - } - PushHook(gL, hookp); - lua_pushvalue(gL, -3); - lua_pushvalue(gL, -3); - if (lua_pcall(gL, 2, 1, 1)) { - if (!hookp->error || cv_debug & DBG_LUA) - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); - hookp->error = true; - continue; - } - if (!lua_isnil(gL, -1)) - { // if nil, leave shouldCollide = 0. - if (lua_toboolean(gL, -1)) - shouldCollide = 1; // Force yes - else - shouldCollide = 2; // Force no - } - lua_pop(gL, 1); - } - - for (hookp = mobjcollidehooks[thing->type]; hookp; hookp = hookp->next) - { - if (hookp->type != which) - continue; - - ps_lua_mobjhooks++; - if (lua_gettop(gL) == 1) - { - LUA_PushUserdata(gL, thing, META_MOBJ); - LUA_PushUserdata(gL, line, META_LINE); - } - PushHook(gL, hookp); - lua_pushvalue(gL, -3); - lua_pushvalue(gL, -3); - if (lua_pcall(gL, 2, 1, 1)) { - if (!hookp->error || cv_debug & DBG_LUA) - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); - hookp->error = true; - continue; - } - if (!lua_isnil(gL, -1)) - { // if nil, leave shouldCollide = 0. - if (lua_toboolean(gL, -1)) - shouldCollide = 1; // Force yes - else - shouldCollide = 2; // Force no - } - lua_pop(gL, 1); - } - - lua_settop(gL, 0); - return shouldCollide; -} - -// Hook for mobj thinkers -boolean LUAh_MobjThinker(mobj_t *mo) -{ - hook_p hookp; - boolean hooked = false; - if (!gL || !(hooksAvailable[hook_MobjThinker/8] & (1<<(hook_MobjThinker%8)))) - return false; - - I_Assert(mo->type < NUMMOBJTYPES); - - if (!(mobjthinkerhooks[MT_NULL] || mobjthinkerhooks[mo->type])) - return false; - - lua_settop(gL, 0); - lua_pushcfunction(gL, LUA_GetErrorMessage); - - // Look for all generic mobj thinker hooks - for (hookp = mobjthinkerhooks[MT_NULL]; hookp; hookp = hookp->next) - { - ps_lua_mobjhooks++; - if (lua_gettop(gL) == 1) - LUA_PushUserdata(gL, mo, META_MOBJ); - PushHook(gL, hookp); - lua_pushvalue(gL, -2); - if (lua_pcall(gL, 1, 1, 1)) { - if (!hookp->error || cv_debug & DBG_LUA) - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); - hookp->error = true; - continue; - } - if (lua_toboolean(gL, -1)) - hooked = true; - lua_pop(gL, 1); - } - - for (hookp = mobjthinkerhooks[mo->type]; hookp; hookp = hookp->next) - { - ps_lua_mobjhooks++; - if (lua_gettop(gL) == 1) - LUA_PushUserdata(gL, mo, META_MOBJ); - PushHook(gL, hookp); - lua_pushvalue(gL, -2); - if (lua_pcall(gL, 1, 1, 1)) { - if (!hookp->error || cv_debug & DBG_LUA) - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); - hookp->error = true; - continue; - } - if (lua_toboolean(gL, -1)) - hooked = true; - lua_pop(gL, 1); - } - - lua_settop(gL, 0); - return hooked; -} - -// Hook for P_TouchSpecialThing by mobj type -boolean LUAh_TouchSpecial(mobj_t *special, mobj_t *toucher) -{ - hook_p hookp; - boolean hooked = false; - if (!gL || !(hooksAvailable[hook_TouchSpecial/8] & (1<<(hook_TouchSpecial%8)))) - return false; - - I_Assert(special->type < NUMMOBJTYPES); - - if (!(mobjhooks[MT_NULL] || mobjhooks[special->type])) - return false; - - lua_settop(gL, 0); - lua_pushcfunction(gL, LUA_GetErrorMessage); - - // Look for all generic touch special hooks - for (hookp = mobjhooks[MT_NULL]; hookp; hookp = hookp->next) - { - if (hookp->type != hook_TouchSpecial) - continue; - - ps_lua_mobjhooks++; - if (lua_gettop(gL) == 1) - { - LUA_PushUserdata(gL, special, META_MOBJ); - LUA_PushUserdata(gL, toucher, META_MOBJ); - } - PushHook(gL, hookp); - lua_pushvalue(gL, -3); - lua_pushvalue(gL, -3); - if (lua_pcall(gL, 2, 1, 1)) { - if (!hookp->error || cv_debug & DBG_LUA) - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); - hookp->error = true; - continue; - } - if (lua_toboolean(gL, -1)) - hooked = true; - lua_pop(gL, 1); - } - - for (hookp = mobjhooks[special->type]; hookp; hookp = hookp->next) - { - if (hookp->type != hook_TouchSpecial) - continue; - - ps_lua_mobjhooks++; - if (lua_gettop(gL) == 1) - { - LUA_PushUserdata(gL, special, META_MOBJ); - LUA_PushUserdata(gL, toucher, META_MOBJ); - } - PushHook(gL, hookp); - lua_pushvalue(gL, -3); - lua_pushvalue(gL, -3); - if (lua_pcall(gL, 2, 1, 1)) { - if (!hookp->error || cv_debug & DBG_LUA) - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); - hookp->error = true; - continue; - } - if (lua_toboolean(gL, -1)) - hooked = true; - lua_pop(gL, 1); - } - - lua_settop(gL, 0); - return hooked; -} - -// Hook for P_DamageMobj by mobj type (Should mobj take damage?) -UINT8 LUAh_ShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype) -{ - hook_p hookp; - UINT8 shouldDamage = 0; // 0 = default, 1 = force yes, 2 = force no. - if (!gL || !(hooksAvailable[hook_ShouldDamage/8] & (1<<(hook_ShouldDamage%8)))) - return 0; - - I_Assert(target->type < NUMMOBJTYPES); - - if (!(mobjhooks[MT_NULL] || mobjhooks[target->type])) - return 0; - - lua_settop(gL, 0); - lua_pushcfunction(gL, LUA_GetErrorMessage); - - // Look for all generic should damage hooks - for (hookp = mobjhooks[MT_NULL]; hookp; hookp = hookp->next) - { - if (hookp->type != hook_ShouldDamage) - continue; - - ps_lua_mobjhooks++; - if (lua_gettop(gL) == 1) - { - LUA_PushUserdata(gL, target, META_MOBJ); - LUA_PushUserdata(gL, inflictor, META_MOBJ); - LUA_PushUserdata(gL, source, META_MOBJ); - lua_pushinteger(gL, damage); - lua_pushinteger(gL, damagetype); - } - PushHook(gL, hookp); - lua_pushvalue(gL, -6); - lua_pushvalue(gL, -6); - lua_pushvalue(gL, -6); - lua_pushvalue(gL, -6); - lua_pushvalue(gL, -6); - if (lua_pcall(gL, 5, 1, 1)) { - if (!hookp->error || cv_debug & DBG_LUA) - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); - hookp->error = true; - continue; - } - if (!lua_isnil(gL, -1)) - { - if (lua_toboolean(gL, -1)) - shouldDamage = 1; // Force yes - else - shouldDamage = 2; // Force no - } - lua_pop(gL, 1); - } - - for (hookp = mobjhooks[target->type]; hookp; hookp = hookp->next) - { - if (hookp->type != hook_ShouldDamage) - continue; - ps_lua_mobjhooks++; - if (lua_gettop(gL) == 1) - { - LUA_PushUserdata(gL, target, META_MOBJ); - LUA_PushUserdata(gL, inflictor, META_MOBJ); - LUA_PushUserdata(gL, source, META_MOBJ); - lua_pushinteger(gL, damage); - lua_pushinteger(gL, damagetype); - } - PushHook(gL, hookp); - lua_pushvalue(gL, -6); - lua_pushvalue(gL, -6); - lua_pushvalue(gL, -6); - lua_pushvalue(gL, -6); - lua_pushvalue(gL, -6); - if (lua_pcall(gL, 5, 1, 1)) { - if (!hookp->error || cv_debug & DBG_LUA) - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); - hookp->error = true; - continue; - } - if (!lua_isnil(gL, -1)) - { - if (lua_toboolean(gL, -1)) - shouldDamage = 1; // Force yes - else - shouldDamage = 2; // Force no - } - lua_pop(gL, 1); - } - - lua_settop(gL, 0); - return shouldDamage; -} - -// Hook for P_DamageMobj by mobj type (Mobj actually takes damage!) -boolean LUAh_MobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype) -{ - hook_p hookp; - boolean hooked = false; - if (!gL || !(hooksAvailable[hook_MobjDamage/8] & (1<<(hook_MobjDamage%8)))) - return false; - - I_Assert(target->type < NUMMOBJTYPES); - - if (!(mobjhooks[MT_NULL] || mobjhooks[target->type])) - return false; - - lua_settop(gL, 0); - lua_pushcfunction(gL, LUA_GetErrorMessage); - - // Look for all generic mobj damage hooks - for (hookp = mobjhooks[MT_NULL]; hookp; hookp = hookp->next) - { - if (hookp->type != hook_MobjDamage) - continue; - - ps_lua_mobjhooks++; - if (lua_gettop(gL) == 1) - { - LUA_PushUserdata(gL, target, META_MOBJ); - LUA_PushUserdata(gL, inflictor, META_MOBJ); - LUA_PushUserdata(gL, source, META_MOBJ); - lua_pushinteger(gL, damage); - lua_pushinteger(gL, damagetype); - } - PushHook(gL, hookp); - lua_pushvalue(gL, -6); - lua_pushvalue(gL, -6); - lua_pushvalue(gL, -6); - lua_pushvalue(gL, -6); - lua_pushvalue(gL, -6); - if (lua_pcall(gL, 5, 1, 1)) { - if (!hookp->error || cv_debug & DBG_LUA) - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); - hookp->error = true; - continue; - } - if (lua_toboolean(gL, -1)) - hooked = true; - lua_pop(gL, 1); - } - - for (hookp = mobjhooks[target->type]; hookp; hookp = hookp->next) - { - if (hookp->type != hook_MobjDamage) - continue; - - ps_lua_mobjhooks++; - if (lua_gettop(gL) == 1) - { - LUA_PushUserdata(gL, target, META_MOBJ); - LUA_PushUserdata(gL, inflictor, META_MOBJ); - LUA_PushUserdata(gL, source, META_MOBJ); - lua_pushinteger(gL, damage); - lua_pushinteger(gL, damagetype); - } - PushHook(gL, hookp); - lua_pushvalue(gL, -6); - lua_pushvalue(gL, -6); - lua_pushvalue(gL, -6); - lua_pushvalue(gL, -6); - lua_pushvalue(gL, -6); - if (lua_pcall(gL, 5, 1, 1)) { - if (!hookp->error || cv_debug & DBG_LUA) - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); - hookp->error = true; - continue; - } - if (lua_toboolean(gL, -1)) - hooked = true; - lua_pop(gL, 1); - } - - lua_settop(gL, 0); - return hooked; -} - -// Hook for P_KillMobj by mobj type -boolean LUAh_MobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damagetype) -{ - hook_p hookp; - boolean hooked = false; - if (!gL || !(hooksAvailable[hook_MobjDeath/8] & (1<<(hook_MobjDeath%8)))) - return false; - - I_Assert(target->type < NUMMOBJTYPES); - - if (!(mobjhooks[MT_NULL] || mobjhooks[target->type])) - return false; - - lua_settop(gL, 0); - lua_pushcfunction(gL, LUA_GetErrorMessage); - - // Look for all generic mobj death hooks - for (hookp = mobjhooks[MT_NULL]; hookp; hookp = hookp->next) - { - if (hookp->type != hook_MobjDeath) - continue; - - ps_lua_mobjhooks++; - if (lua_gettop(gL) == 1) - { - LUA_PushUserdata(gL, target, META_MOBJ); - LUA_PushUserdata(gL, inflictor, META_MOBJ); - LUA_PushUserdata(gL, source, META_MOBJ); - lua_pushinteger(gL, damagetype); - } - PushHook(gL, hookp); - lua_pushvalue(gL, -5); - lua_pushvalue(gL, -5); - lua_pushvalue(gL, -5); - lua_pushvalue(gL, -5); - if (lua_pcall(gL, 4, 1, 1)) { - if (!hookp->error || cv_debug & DBG_LUA) - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); - hookp->error = true; - continue; - } - if (lua_toboolean(gL, -1)) - hooked = true; - lua_pop(gL, 1); - } - - for (hookp = mobjhooks[target->type]; hookp; hookp = hookp->next) - { - if (hookp->type != hook_MobjDeath) - continue; - - ps_lua_mobjhooks++; - if (lua_gettop(gL) == 1) - { - LUA_PushUserdata(gL, target, META_MOBJ); - LUA_PushUserdata(gL, inflictor, META_MOBJ); - LUA_PushUserdata(gL, source, META_MOBJ); - lua_pushinteger(gL, damagetype); - } - PushHook(gL, hookp); - lua_pushvalue(gL, -5); - lua_pushvalue(gL, -5); - lua_pushvalue(gL, -5); - lua_pushvalue(gL, -5); - if (lua_pcall(gL, 4, 1, 1)) { - if (!hookp->error || cv_debug & DBG_LUA) - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); - hookp->error = true; - continue; - } - if (lua_toboolean(gL, -1)) - hooked = true; - lua_pop(gL, 1); - } - - lua_settop(gL, 0); - return hooked; -} - -// Hook for B_BuildTiccmd -boolean LUAh_BotTiccmd(player_t *bot, ticcmd_t *cmd) -{ - hook_p hookp; - boolean hooked = false; - if (!gL || !(hooksAvailable[hook_BotTiccmd/8] & (1<<(hook_BotTiccmd%8)))) - return false; - - lua_settop(gL, 0); - lua_pushcfunction(gL, LUA_GetErrorMessage); - - for (hookp = roothook; hookp; hookp = hookp->next) - { - if (hookp->type != hook_BotTiccmd) - continue; - - if (lua_gettop(gL) == 1) - { - LUA_PushUserdata(gL, bot, META_PLAYER); - LUA_PushUserdata(gL, cmd, META_TICCMD); - } - PushHook(gL, hookp); - lua_pushvalue(gL, -3); - lua_pushvalue(gL, -3); - if (lua_pcall(gL, 2, 1, 1)) { - if (!hookp->error || cv_debug & DBG_LUA) - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); - hookp->error = true; - continue; - } - if (lua_toboolean(gL, -1)) - hooked = true; - lua_pop(gL, 1); - } - - lua_settop(gL, 0); - return hooked; -} - -// Hook for B_BuildTailsTiccmd by skin name -boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd) -{ - hook_p hookp; - boolean hooked = false; - if (!gL || !(hooksAvailable[hook_BotAI/8] & (1<<(hook_BotAI%8)))) - return false; - - lua_settop(gL, 0); - lua_pushcfunction(gL, LUA_GetErrorMessage); - - for (hookp = roothook; hookp; hookp = hookp->next) - { - if (hookp->type != hook_BotAI - || (hookp->s.str && strcmp(hookp->s.str, ((skin_t*)tails->skin)->name))) - continue; - - if (lua_gettop(gL) == 1) - { - LUA_PushUserdata(gL, sonic, META_MOBJ); - LUA_PushUserdata(gL, tails, META_MOBJ); - } - PushHook(gL, hookp); - lua_pushvalue(gL, -3); - lua_pushvalue(gL, -3); - if (lua_pcall(gL, 2, 8, 1)) { - if (!hookp->error || cv_debug & DBG_LUA) - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); - hookp->error = true; - continue; - } - - // This turns forward, backward, left, right, jump, and spin into a proper ticcmd for tails. - if (lua_istable(gL, 2+1)) { - boolean forward=false, backward=false, left=false, right=false, strafeleft=false, straferight=false, jump=false, spin=false; -#define CHECKFIELD(field) \ - lua_getfield(gL, 2+1, #field);\ - if (lua_toboolean(gL, -1))\ - field = true;\ - lua_pop(gL, 1); - - CHECKFIELD(forward) - CHECKFIELD(backward) - CHECKFIELD(left) - CHECKFIELD(right) - CHECKFIELD(strafeleft) - CHECKFIELD(straferight) - CHECKFIELD(jump) - CHECKFIELD(spin) -#undef CHECKFIELD - B_KeysToTiccmd(tails, cmd, forward, backward, left, right, strafeleft, straferight, jump, spin); - } else - B_KeysToTiccmd(tails, cmd, lua_toboolean(gL, 2+1), lua_toboolean(gL, 2+2), lua_toboolean(gL, 2+3), lua_toboolean(gL, 2+4), lua_toboolean(gL, 2+5), lua_toboolean(gL, 2+6), lua_toboolean(gL, 2+7), lua_toboolean(gL, 2+8)); - - lua_pop(gL, 8); - hooked = true; - } - - lua_settop(gL, 0); - return hooked; -} - -// Hook for B_CheckRespawn -boolean LUAh_BotRespawn(mobj_t *sonic, mobj_t *tails) -{ - hook_p hookp; - UINT8 shouldRespawn = 0; // 0 = default, 1 = force yes, 2 = force no. - if (!gL || !(hooksAvailable[hook_BotRespawn/8] & (1<<(hook_BotRespawn%8)))) - return false; - - lua_settop(gL, 0); - lua_pushcfunction(gL, LUA_GetErrorMessage); - - for (hookp = roothook; hookp; hookp = hookp->next) - { - if (hookp->type != hook_BotRespawn) - continue; - - if (lua_gettop(gL) == 1) - { - LUA_PushUserdata(gL, sonic, META_MOBJ); - LUA_PushUserdata(gL, tails, META_MOBJ); - } - PushHook(gL, hookp); - lua_pushvalue(gL, -3); - lua_pushvalue(gL, -3); - if (lua_pcall(gL, 2, 1, 1)) { - if (!hookp->error || cv_debug & DBG_LUA) - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); - hookp->error = true; - continue; - } - if (!lua_isnil(gL, -1)) - { - if (lua_toboolean(gL, -1)) - shouldRespawn = 1; // Force yes - else - shouldRespawn = 2; // Force no - } - lua_pop(gL, 1); - } - - lua_settop(gL, 0); - return shouldRespawn; -} - -// Hook for linedef executors -boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo, sector_t *sector) -{ - hook_p hookp; - boolean hooked = false; - if (!gL || !(hooksAvailable[hook_LinedefExecute/8] & (1<<(hook_LinedefExecute%8)))) - return 0; - - lua_settop(gL, 0); - lua_pushcfunction(gL, LUA_GetErrorMessage); - - for (hookp = linedefexecutorhooks; hookp; hookp = hookp->next) - { - if (strcmp(hookp->s.str, line->stringargs[0])) - continue; - - ps_lua_mobjhooks++; - if (lua_gettop(gL) == 1) - { - LUA_PushUserdata(gL, line, META_LINE); - LUA_PushUserdata(gL, mo, META_MOBJ); - LUA_PushUserdata(gL, sector, META_SECTOR); - } - PushHook(gL, hookp); - lua_pushvalue(gL, -4); - lua_pushvalue(gL, -4); - lua_pushvalue(gL, -4); - if (lua_pcall(gL, 3, 0, 1)) { - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); - } - hooked = true; - } - - lua_settop(gL, 0); - return hooked; -} - - -boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg) -{ - hook_p hookp; - boolean hooked = false; - if (!gL || !(hooksAvailable[hook_PlayerMsg/8] & (1<<(hook_PlayerMsg%8)))) - return false; - - lua_settop(gL, 0); - lua_pushcfunction(gL, LUA_GetErrorMessage); - - for (hookp = roothook; hookp; hookp = hookp->next) - { - if (hookp->type != hook_PlayerMsg) - continue; - - if (lua_gettop(gL) == 1) - { - LUA_PushUserdata(gL, &players[source], META_PLAYER); // Source player - if (flags & 2 /*HU_CSAY*/) { // csay TODO: make HU_CSAY accessible outside hu_stuff.c - lua_pushinteger(gL, 3); // type - lua_pushnil(gL); // target - } else if (target == -1) { // sayteam - lua_pushinteger(gL, 1); // type - lua_pushnil(gL); // target - } else if (target == 0) { // say - lua_pushinteger(gL, 0); // type - lua_pushnil(gL); // target - } else { // sayto - lua_pushinteger(gL, 2); // type - LUA_PushUserdata(gL, &players[target-1], META_PLAYER); // target + if (cv_perfstats.value == 3) + { + lua_pushvalue(gL, -1);/* need the function again */ + time_taken = I_GetTimeMicros(); } - lua_pushstring(gL, msg); // msg - } - PushHook(gL, hookp); - lua_pushvalue(gL, -5); - lua_pushvalue(gL, -5); - lua_pushvalue(gL, -5); - lua_pushvalue(gL, -5); - if (lua_pcall(gL, 4, 1, 1)) { - if (!hookp->error || cv_debug & DBG_LUA) - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); - hookp->error = true; - continue; - } - if (lua_toboolean(gL, -1)) - hooked = true; - lua_pop(gL, 1); - } - lua_settop(gL, 0); - return hooked; + call_single_hook(&hook); + + if (cv_perfstats.value == 3) + { + lua_Debug ar; + time_taken = I_GetTimeMicros() - time_taken; + lua_getinfo(gL, ">S", &ar); + PS_SetThinkFrameHookInfo(hook_index, time_taken, ar.short_src); + hook_index++; + } + } + + lua_settop(gL, 0); + } } - -// Hook for hurt messages -boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 damagetype) +int LUA_HookMobjLineCollide(mobj_t *mobj, line_t *line) { - hook_p hookp; - boolean hooked = false; - if (!gL || !(hooksAvailable[hook_HurtMsg/8] & (1<<(hook_HurtMsg%8)))) - return false; - - lua_settop(gL, 0); - lua_pushcfunction(gL, LUA_GetErrorMessage); - - for (hookp = roothook; hookp; hookp = hookp->next) + Hook_State hook; + if (prepare_mobj_hook(&hook, 0, Mobj_Hook(MobjLineCollide), mobj->type)) { - if (hookp->type != hook_HurtMsg - || (hookp->s.mt && !(inflictor && hookp->s.mt == inflictor->type))) - continue; + LUA_PushUserdata(gL, mobj, META_MOBJ); + LUA_PushUserdata(gL, line, META_LINE); + call_hooks(&hook, 2, 1, res_force); + } + return hook.status; +} - if (lua_gettop(gL) == 1) +int LUA_HookTouchSpecial(mobj_t *special, mobj_t *toucher) +{ + Hook_State hook; + if (prepare_mobj_hook(&hook, false, Mobj_Hook(TouchSpecial), special->type)) + { + LUA_PushUserdata(gL, special, META_MOBJ); + LUA_PushUserdata(gL, toucher, META_MOBJ); + call_hooks(&hook, 2, 1, res_true); + } + return hook.status; +} + +static int damage_hook +( + mobj_t *target, + mobj_t *inflictor, + mobj_t *source, + INT32 damage, + UINT8 damagetype, + int hook_type, + int values, + Hook_Callback results_handler +){ + Hook_State hook; + if (prepare_mobj_hook(&hook, 0, hook_type, target->type)) + { + LUA_PushUserdata(gL, target, META_MOBJ); + LUA_PushUserdata(gL, inflictor, META_MOBJ); + LUA_PushUserdata(gL, source, META_MOBJ); + if (values == 5) + lua_pushinteger(gL, damage); + lua_pushinteger(gL, damagetype); + call_hooks(&hook, values, 1, results_handler); + } + return hook.status; +} + +int LUA_HookShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype) +{ + return damage_hook(target, inflictor, source, damage, damagetype, + Mobj_Hook(ShouldDamage), 5, res_force); +} + +int LUA_HookMobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype) +{ + return damage_hook(target, inflictor, source, damage, damagetype, + Mobj_Hook(MobjDamage), 5, res_true); +} + +int LUA_HookMobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damagetype) +{ + return damage_hook(target, inflictor, source, 0, damagetype, + Mobj_Hook(MobjDeath), 4, res_true); +} + +typedef struct { + mobj_t * tails; + ticcmd_t * cmd; +} BotAI_State; + +static boolean checkbotkey(const char *field) +{ + return lua_toboolean(gL, -1) && strcmp(lua_tostring(gL, -2), field) == 0; +} + +static void res_botai(Hook_State *hook) +{ + BotAI_State *botai = hook->userdata; + + int k[8]; + + int fields = 0; + + // This turns forward, backward, left, right, jump, and spin into a proper ticcmd for tails. + if (lua_istable(gL, -8)) { + lua_pushnil(gL); // key + while (lua_next(gL, -9)) { +#define check(n, f) (checkbotkey(f) ? (k[(n)-1] = 1) : 0) + if ( + check(1, "forward") || check(2, "backward") || + check(3, "left") || check(4, "right") || + check(5, "strafeleft") || check(6, "straferight") || + check(7, "jump") || check(8, "spin") + ){ + if (8 <= ++fields) + { + lua_pop(gL, 2); // pop key and value + break; + } + } + + lua_pop(gL, 1); // pop value +#undef check + } + } else { + while (fields < 8) { - LUA_PushUserdata(gL, player, META_PLAYER); - LUA_PushUserdata(gL, inflictor, META_MOBJ); - LUA_PushUserdata(gL, source, META_MOBJ); - lua_pushinteger(gL, damagetype); + k[fields] = lua_toboolean(gL, -8 + fields); + fields++; } - PushHook(gL, hookp); - lua_pushvalue(gL, -5); - lua_pushvalue(gL, -5); - lua_pushvalue(gL, -5); - lua_pushvalue(gL, -5); - if (lua_pcall(gL, 4, 1, 1)) { - if (!hookp->error || cv_debug & DBG_LUA) - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); - hookp->error = true; - continue; - } - if (lua_toboolean(gL, -1)) - hooked = true; - lua_pop(gL, 1); } - lua_settop(gL, 0); - return hooked; + B_KeysToTiccmd(botai->tails, botai->cmd, + k[0],k[1],k[2],k[3],k[4],k[5],k[6],k[7]); + + hook->status = true; } -void LUAh_NetArchiveHook(lua_CFunction archFunc) +int LUA_HookBotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd) { - hook_p hookp; - int errorhandlerindex; - if (!gL || !(hooksAvailable[hook_NetVars/8] & (1<<(hook_NetVars%8)))) - return; + const char *skin = ((skin_t *)tails->skin)->name; - // stack: tables - I_Assert(lua_gettop(gL) > 0); - I_Assert(lua_istable(gL, -1)); + Hook_State hook; + BotAI_State botai; - lua_pushcfunction(gL, LUA_GetErrorMessage); - errorhandlerindex = lua_gettop(gL); - - // tables becomes an upvalue of archFunc - lua_pushvalue(gL, -2); - lua_pushcclosure(gL, archFunc, 1); - // stack: tables, archFunc - - for (hookp = roothook; hookp; hookp = hookp->next) + if (prepare_string_hook(&hook, false, String_Hook(BotAI), skin)) { - if (hookp->type != hook_NetVars) - continue; + LUA_PushUserdata(gL, sonic, META_MOBJ); + LUA_PushUserdata(gL, tails, META_MOBJ); - PushHook(gL, hookp); - lua_pushvalue(gL, -2); // archFunc - if (lua_pcall(gL, 1, 0, errorhandlerindex)) { - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); - } + botai.tails = tails; + botai.cmd = cmd; + + hook.userdata = &botai; + + call_hooks(&hook, 2, 8, res_botai); } - lua_pop(gL, 2); // Pop archFunc and error handler - // stack: tables + return hook.status; } -boolean LUAh_MapThingSpawn(mobj_t *mo, mapthing_t *mthing) +void LUA_HookLinedefExecute(line_t *line, mobj_t *mo, sector_t *sector) { - hook_p hookp; - boolean hooked = false; - if (!gL || !(hooksAvailable[hook_MapThingSpawn/8] & (1<<(hook_MapThingSpawn%8)))) - return false; - - if (!(mobjhooks[MT_NULL] || mobjhooks[mo->type])) - return false; - - lua_settop(gL, 0); - lua_pushcfunction(gL, LUA_GetErrorMessage); - - // Look for all generic mobj map thing spawn hooks - for (hookp = mobjhooks[MT_NULL]; hookp; hookp = hookp->next) + Hook_State hook; + if (prepare_string_hook + (&hook, 0, String_Hook(LinedefExecute), line->stringargs[0])) { - if (hookp->type != hook_MapThingSpawn) - continue; - - ps_lua_mobjhooks++; - if (lua_gettop(gL) == 1) - { - LUA_PushUserdata(gL, mo, META_MOBJ); - LUA_PushUserdata(gL, mthing, META_MAPTHING); - } - PushHook(gL, hookp); - lua_pushvalue(gL, -3); - lua_pushvalue(gL, -3); - if (lua_pcall(gL, 2, 1, 1)) { - if (!hookp->error || cv_debug & DBG_LUA) - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); - hookp->error = true; - continue; - } - if (lua_toboolean(gL, -1)) - hooked = true; - lua_pop(gL, 1); + LUA_PushUserdata(gL, line, META_LINE); + LUA_PushUserdata(gL, mo, META_MOBJ); + LUA_PushUserdata(gL, sector, META_SECTOR); + ps_lua_mobjhooks += call_hooks(&hook, 3, 0, res_none); } - - for (hookp = mobjhooks[mo->type]; hookp; hookp = hookp->next) - { - if (hookp->type != hook_MapThingSpawn) - continue; - - ps_lua_mobjhooks++; - if (lua_gettop(gL) == 1) - { - LUA_PushUserdata(gL, mo, META_MOBJ); - LUA_PushUserdata(gL, mthing, META_MAPTHING); - } - PushHook(gL, hookp); - lua_pushvalue(gL, -3); - lua_pushvalue(gL, -3); - if (lua_pcall(gL, 2, 1, 1)) { - if (!hookp->error || cv_debug & DBG_LUA) - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); - hookp->error = true; - continue; - } - if (lua_toboolean(gL, -1)) - hooked = true; - lua_pop(gL, 1); - } - - lua_settop(gL, 0); - return hooked; } -// Hook for P_PlayerAfterThink Smiles mobj-following -boolean LUAh_FollowMobj(player_t *player, mobj_t *mobj) +int LUA_HookPlayerMsg(int source, int target, int flags, char *msg) { - hook_p hookp; - boolean hooked = false; - if (!gL || !(hooksAvailable[hook_FollowMobj/8] & (1<<(hook_FollowMobj%8)))) - return 0; - - if (!(mobjhooks[MT_NULL] || mobjhooks[mobj->type])) - return 0; - - lua_settop(gL, 0); - lua_pushcfunction(gL, LUA_GetErrorMessage); - - // Look for all generic mobj follow item hooks - for (hookp = mobjhooks[MT_NULL]; hookp; hookp = hookp->next) + Hook_State hook; + if (prepare_hook(&hook, false, Hook(PlayerMsg))) { - if (hookp->type != hook_FollowMobj) - continue; - - ps_lua_mobjhooks++; - if (lua_gettop(gL) == 1) - { - LUA_PushUserdata(gL, player, META_PLAYER); - LUA_PushUserdata(gL, mobj, META_MOBJ); + LUA_PushUserdata(gL, &players[source], META_PLAYER); // Source player + if (flags & 2 /*HU_CSAY*/) { // csay TODO: make HU_CSAY accessible outside hu_stuff.c + lua_pushinteger(gL, 3); // type + lua_pushnil(gL); // target + } else if (target == -1) { // sayteam + lua_pushinteger(gL, 1); // type + lua_pushnil(gL); // target + } else if (target == 0) { // say + lua_pushinteger(gL, 0); // type + lua_pushnil(gL); // target + } else { // sayto + lua_pushinteger(gL, 2); // type + LUA_PushUserdata(gL, &players[target-1], META_PLAYER); // target } - PushHook(gL, hookp); - lua_pushvalue(gL, -3); - lua_pushvalue(gL, -3); - if (lua_pcall(gL, 2, 1, 1)) { - if (!hookp->error || cv_debug & DBG_LUA) - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); - hookp->error = true; - continue; - } - if (lua_toboolean(gL, -1)) - hooked = true; - lua_pop(gL, 1); + lua_pushstring(gL, msg); // msg + call_hooks(&hook, 4, 1, res_true); } - - for (hookp = mobjhooks[mobj->type]; hookp; hookp = hookp->next) - { - if (hookp->type != hook_FollowMobj) - continue; - - ps_lua_mobjhooks++; - if (lua_gettop(gL) == 1) - { - LUA_PushUserdata(gL, player, META_PLAYER); - LUA_PushUserdata(gL, mobj, META_MOBJ); - } - PushHook(gL, hookp); - lua_pushvalue(gL, -3); - lua_pushvalue(gL, -3); - if (lua_pcall(gL, 2, 1, 1)) { - if (!hookp->error || cv_debug & DBG_LUA) - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); - hookp->error = true; - continue; - } - if (lua_toboolean(gL, -1)) - hooked = true; - lua_pop(gL, 1); - } - - lua_settop(gL, 0); - return hooked; + return hook.status; } -// Hook for P_PlayerCanDamage -UINT8 LUAh_PlayerCanDamage(player_t *player, mobj_t *mobj) +int LUA_HookHurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 damagetype) { - hook_p hookp; - UINT8 shouldCollide = 0; // 0 = default, 1 = force yes, 2 = force no. - if (!gL || !(hooksAvailable[hook_PlayerCanDamage/8] & (1<<(hook_PlayerCanDamage%8)))) - return 0; - - lua_settop(gL, 0); - lua_pushcfunction(gL, LUA_GetErrorMessage); - - for (hookp = playerhooks; hookp; hookp = hookp->next) + Hook_State hook; + if (prepare_hook(&hook, false, Hook(HurtMsg))) { - if (hookp->type != hook_PlayerCanDamage) - continue; - - ps_lua_mobjhooks++; - if (lua_gettop(gL) == 1) - { - LUA_PushUserdata(gL, player, META_PLAYER); - LUA_PushUserdata(gL, mobj, META_MOBJ); - } - PushHook(gL, hookp); - lua_pushvalue(gL, -3); - lua_pushvalue(gL, -3); - if (lua_pcall(gL, 2, 1, 1)) { - if (!hookp->error || cv_debug & DBG_LUA) - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); - hookp->error = true; - continue; - } - if (!lua_isnil(gL, -1)) - { // if nil, leave shouldCollide = 0. - if (lua_toboolean(gL, -1)) - shouldCollide = 1; // Force yes - else - shouldCollide = 2; // Force no - } - lua_pop(gL, 1); + LUA_PushUserdata(gL, player, META_PLAYER); + LUA_PushUserdata(gL, inflictor, META_MOBJ); + LUA_PushUserdata(gL, source, META_MOBJ); + lua_pushinteger(gL, damagetype); + call_hooks(&hook, 4, 1, res_true); } - - lua_settop(gL, 0); - return shouldCollide; + return hook.status; } -void LUAh_PlayerQuit(player_t *plr, kickreason_t reason) +void LUA_HookNetArchive(lua_CFunction archFunc) { - hook_p hookp; - if (!gL || !(hooksAvailable[hook_PlayerQuit/8] & (1<<(hook_PlayerQuit%8)))) - return; - - lua_settop(gL, 0); - lua_pushcfunction(gL, LUA_GetErrorMessage); - - for (hookp = roothook; hookp; hookp = hookp->next) + const int ref = hookRefs[Hook(NetVars)]; + Hook_State hook; + /* this is a remarkable case where the stack isn't reset */ + if (ref > 0) { - if (hookp->type != hook_PlayerQuit) - continue; + // stack: tables + I_Assert(lua_gettop(gL) > 0); + I_Assert(lua_istable(gL, -1)); - if (lua_gettop(gL) == 1) - { - LUA_PushUserdata(gL, plr, META_PLAYER); // Player that quit - lua_pushinteger(gL, reason); // Reason for quitting - } - PushHook(gL, hookp); - lua_pushvalue(gL, -3); - lua_pushvalue(gL, -3); - if (lua_pcall(gL, 2, 0, 1)) { - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); - } + push_error_handler(); + lua_getref(gL, hookReg); + + lua_insert(gL, HINDEX); + lua_insert(gL, EINDEX); + + // tables becomes an upvalue of archFunc + lua_pushvalue(gL, -1); + lua_pushcclosure(gL, archFunc, 1); + // stack: tables, archFunc + + init_hook_call(&hook, 1, 0, res_none); + call_ref(&hook, ref); + + lua_pop(gL, 2); // pop hook table and archFunc + lua_remove(gL, EINDEX); // pop error handler + lua_remove(gL, HINDEX); // pop hook registry + // stack: tables } - - lua_settop(gL, 0); } -// Hook for Y_Ticker -void LUAh_IntermissionThinker(void) +int LUA_HookMapThingSpawn(mobj_t *mobj, mapthing_t *mthing) { - hook_p hookp; - if (!gL || !(hooksAvailable[hook_IntermissionThinker/8] & (1<<(hook_IntermissionThinker%8)))) - return; - - lua_pushcfunction(gL, LUA_GetErrorMessage); - - for (hookp = roothook; hookp; hookp = hookp->next) + Hook_State hook; + if (prepare_mobj_hook(&hook, false, Mobj_Hook(MapThingSpawn), mobj->type)) { - if (hookp->type != hook_IntermissionThinker) - continue; - - PushHook(gL, hookp); - if (lua_pcall(gL, 0, 0, 1)) { - if (!hookp->error || cv_debug & DBG_LUA) - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); - hookp->error = true; - } + LUA_PushUserdata(gL, mobj, META_MOBJ); + LUA_PushUserdata(gL, mthing, META_MAPTHING); + call_hooks(&hook, 2, 1, res_true); } - - lua_pop(gL, 1); // Pop error handler + return hook.status; } -// Hook for team switching -// It's just an edit of LUAh_ViewpointSwitch. -boolean LUAh_TeamSwitch(player_t *player, int newteam, boolean fromspectators, boolean tryingautobalance, boolean tryingscramble) +int LUA_HookFollowMobj(player_t *player, mobj_t *mobj) { - hook_p hookp; - boolean canSwitchTeam = true; - if (!gL || !(hooksAvailable[hook_TeamSwitch/8] & (1<<(hook_TeamSwitch%8)))) - return true; - - lua_settop(gL, 0); - lua_pushcfunction(gL, LUA_GetErrorMessage); - - for (hookp = playerhooks; hookp; hookp = hookp->next) + Hook_State hook; + if (prepare_mobj_hook(&hook, false, Mobj_Hook(FollowMobj), mobj->type)) { - if (hookp->type != hook_TeamSwitch) - continue; - - if (lua_gettop(gL) == 1) - { - LUA_PushUserdata(gL, player, META_PLAYER); - lua_pushinteger(gL, newteam); - lua_pushboolean(gL, fromspectators); - lua_pushboolean(gL, tryingautobalance); - lua_pushboolean(gL, tryingscramble); - } - PushHook(gL, hookp); - lua_pushvalue(gL, -6); - lua_pushvalue(gL, -6); - lua_pushvalue(gL, -6); - lua_pushvalue(gL, -6); - lua_pushvalue(gL, -6); - if (lua_pcall(gL, 5, 1, 1)) { - if (!hookp->error || cv_debug & DBG_LUA) - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); - hookp->error = true; - continue; - } - if (!lua_isnil(gL, -1) && !lua_toboolean(gL, -1)) - canSwitchTeam = false; // Can't switch team - lua_pop(gL, 1); + LUA_PushUserdata(gL, player, META_PLAYER); + LUA_PushUserdata(gL, mobj, META_MOBJ); + call_hooks(&hook, 2, 1, res_true); } - - lua_settop(gL, 0); - return canSwitchTeam; + return hook.status; } -// Hook for spy mode -UINT8 LUAh_ViewpointSwitch(player_t *player, player_t *newdisplayplayer, boolean forced) +int LUA_HookPlayerCanDamage(player_t *player, mobj_t *mobj) { - hook_p hookp; - UINT8 canSwitchView = 0; // 0 = default, 1 = force yes, 2 = force no. - if (!gL || !(hooksAvailable[hook_ViewpointSwitch/8] & (1<<(hook_ViewpointSwitch%8)))) - return 0; - - lua_settop(gL, 0); - lua_pushcfunction(gL, LUA_GetErrorMessage); - - hud_running = true; // local hook - - for (hookp = playerhooks; hookp; hookp = hookp->next) + Hook_State hook; + if (prepare_hook(&hook, 0, Hook(PlayerCanDamage))) { - if (hookp->type != hook_ViewpointSwitch) - continue; - - if (lua_gettop(gL) == 1) - { - LUA_PushUserdata(gL, player, META_PLAYER); - LUA_PushUserdata(gL, newdisplayplayer, META_PLAYER); - lua_pushboolean(gL, forced); - } - PushHook(gL, hookp); - lua_pushvalue(gL, -4); - lua_pushvalue(gL, -4); - lua_pushvalue(gL, -4); - if (lua_pcall(gL, 3, 1, 1)) { - if (!hookp->error || cv_debug & DBG_LUA) - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); - hookp->error = true; - continue; - } - if (!lua_isnil(gL, -1)) - { // if nil, leave canSwitchView = 0. - if (lua_toboolean(gL, -1)) - canSwitchView = 1; // Force viewpoint switch - else - canSwitchView = 2; // Skip viewpoint switch - } - lua_pop(gL, 1); + LUA_PushUserdata(gL, player, META_PLAYER); + LUA_PushUserdata(gL, mobj, META_MOBJ); + call_hooks(&hook, 2, 1, res_force); } - - lua_settop(gL, 0); - - hud_running = false; - - return canSwitchView; + return hook.status; +} + +void LUA_HookPlayerQuit(player_t *plr, kickreason_t reason) +{ + Hook_State hook; + if (prepare_hook(&hook, 0, Hook(PlayerQuit))) + { + LUA_PushUserdata(gL, plr, META_PLAYER); // Player that quit + lua_pushinteger(gL, reason); // Reason for quitting + call_hooks(&hook, 2, 0, res_none); + } +} + +int LUA_HookTeamSwitch(player_t *player, int newteam, boolean fromspectators, boolean tryingautobalance, boolean tryingscramble) +{ + Hook_State hook; + if (prepare_hook(&hook, true, Hook(TeamSwitch))) + { + LUA_PushUserdata(gL, player, META_PLAYER); + lua_pushinteger(gL, newteam); + lua_pushboolean(gL, fromspectators); + lua_pushboolean(gL, tryingautobalance); + lua_pushboolean(gL, tryingscramble); + call_hooks(&hook, 5, 1, res_false); + } + return hook.status; +} + +int LUA_HookViewpointSwitch(player_t *player, player_t *newdisplayplayer, boolean forced) +{ + Hook_State hook; + if (prepare_hook(&hook, 0, Hook(ViewpointSwitch))) + { + LUA_PushUserdata(gL, player, META_PLAYER); + LUA_PushUserdata(gL, newdisplayplayer, META_PLAYER); + lua_pushboolean(gL, forced); + + hud_running = true; // local hook + call_hooks(&hook, 3, 1, res_force); + hud_running = false; + } + return hook.status; } -// Hook for MT_NAMECHECK #ifdef SEENAMES -boolean LUAh_SeenPlayer(player_t *player, player_t *seenfriend) +int LUA_HookSeenPlayer(player_t *player, player_t *seenfriend) { - hook_p hookp; - boolean hasSeenPlayer = true; - if (!gL || !(hooksAvailable[hook_SeenPlayer/8] & (1<<(hook_SeenPlayer%8)))) - return true; - - lua_settop(gL, 0); - lua_pushcfunction(gL, LUA_GetErrorMessage); - - hud_running = true; // local hook - - for (hookp = playerhooks; hookp; hookp = hookp->next) + Hook_State hook; + if (prepare_hook(&hook, true, Hook(SeenPlayer))) { - if (hookp->type != hook_SeenPlayer) - continue; + LUA_PushUserdata(gL, player, META_PLAYER); + LUA_PushUserdata(gL, seenfriend, META_PLAYER); - if (lua_gettop(gL) == 1) - { - LUA_PushUserdata(gL, player, META_PLAYER); - LUA_PushUserdata(gL, seenfriend, META_PLAYER); - } - PushHook(gL, hookp); - lua_pushvalue(gL, -3); - lua_pushvalue(gL, -3); - if (lua_pcall(gL, 2, 1, 1)) { - if (!hookp->error || cv_debug & DBG_LUA) - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); - hookp->error = true; - continue; - } - if (!lua_isnil(gL, -1) && !lua_toboolean(gL, -1)) - hasSeenPlayer = false; // Hasn't seen player - lua_pop(gL, 1); + hud_running = true; // local hook + call_hooks(&hook, 2, 1, res_false); + hud_running = false; } - - lua_settop(gL, 0); - - hud_running = false; - - return hasSeenPlayer; + return hook.status; } #endif // SEENAMES -boolean LUAh_ShouldJingleContinue(player_t *player, const char *musname) +int LUA_HookShouldJingleContinue(player_t *player, const char *musname) { - hook_p hookp; - boolean keepplaying = false; - if (!gL || !(hooksAvailable[hook_ShouldJingleContinue/8] & (1<<(hook_ShouldJingleContinue%8)))) - return true; - - lua_settop(gL, 0); - lua_pushcfunction(gL, LUA_GetErrorMessage); - - hud_running = true; // local hook - - for (hookp = roothook; hookp; hookp = hookp->next) + Hook_State hook; + if (prepare_string_hook + (&hook, false, String_Hook(ShouldJingleContinue), musname)) { - if (hookp->type != hook_ShouldJingleContinue - || (hookp->s.str && strcmp(hookp->s.str, musname))) - continue; + LUA_PushUserdata(gL, player, META_PLAYER); + push_string(); - if (lua_gettop(gL) == 1) - { - LUA_PushUserdata(gL, player, META_PLAYER); - lua_pushstring(gL, musname); - } - PushHook(gL, hookp); - lua_pushvalue(gL, -3); - lua_pushvalue(gL, -3); - if (lua_pcall(gL, 2, 1, 1)) { - if (!hookp->error || cv_debug & DBG_LUA) - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); - hookp->error = true; - continue; - } - if (!lua_isnil(gL, -1) && lua_toboolean(gL, -1)) - keepplaying = true; // Keep playing this boolean - lua_pop(gL, 1); + hud_running = true; // local hook + call_hooks(&hook, 2, 1, res_true); + hud_running = false; } - - lua_settop(gL, 0); - - hud_running = false; - - return keepplaying; + return hook.status; } -// Hook for game quitting -void LUAh_GameQuit(void) -{ - hook_p hookp; - if (!gL || !(hooksAvailable[hook_GameQuit/8] & (1<<(hook_GameQuit%8)))) - return; - - lua_pushcfunction(gL, LUA_GetErrorMessage); - - for (hookp = roothook; hookp; hookp = hookp->next) - { - if (hookp->type != hook_GameQuit) - continue; - - PushHook(gL, hookp); - if (lua_pcall(gL, 0, 0, 1)) { - if (!hookp->error || cv_debug & DBG_LUA) - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); - hookp->error = true; - } - } - - lua_pop(gL, 1); // Pop error handler -} - -// Hook for building player's ticcmd struct (Ported from SRB2Kart) boolean hook_cmd_running = false; -boolean LUAh_PlayerCmd(player_t *player, ticcmd_t *cmd) + +static void update_music_name(struct MusicChange *musicchange) { - hook_p hookp; - boolean hooked = false; - if (!gL || !(hooksAvailable[hook_PlayerCmd/8] & (1<<(hook_PlayerCmd%8)))) - return false; + size_t length; + const char * new = lua_tolstring(gL, -6, &length); - lua_settop(gL, 0); - lua_pushcfunction(gL, LUA_GetErrorMessage); - - hook_cmd_running = true; - for (hookp = roothook; hookp; hookp = hookp->next) + if (length < 7) { - if (hookp->type != hook_PlayerCmd) - continue; - - if (lua_gettop(gL) == 1) - { - LUA_PushUserdata(gL, player, META_PLAYER); - LUA_PushUserdata(gL, cmd, META_TICCMD); - } - PushHook(gL, hookp); - lua_pushvalue(gL, -3); - lua_pushvalue(gL, -3); - if (lua_pcall(gL, 2, 1, 1)) { - if (!hookp->error || cv_debug & DBG_LUA) - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); - hookp->error = true; - continue; - } - if (lua_toboolean(gL, -1)) - hooked = true; - lua_pop(gL, 1); + strcpy(musicchange->newname, new); + lua_pushvalue(gL, -6);/* may as well keep it for next call */ + } + else + { + memcpy(musicchange->newname, new, 6); + musicchange->newname[6] = '\0'; + lua_pushlstring(gL, new, 6); } - lua_settop(gL, 0); - hook_cmd_running = false; - return hooked; + lua_replace(gL, -7); } -// Hook for music changes -boolean LUAh_MusicChange(const char *oldname, char *newname, UINT16 *mflags, boolean *looping, - UINT32 *position, UINT32 *prefadems, UINT32 *fadeinms) +static void res_musicchange(Hook_State *hook) { - hook_p hookp; - boolean hooked = false; + struct MusicChange *musicchange = hook->userdata; - if (!gL || !(hooksAvailable[hook_MusicChange/8] & (1<<(hook_MusicChange%8)))) - return false; + // output 1: true, false, or string musicname override + if (lua_isstring(gL, -6)) + update_music_name(musicchange); + else if (lua_isboolean(gL, -6) && lua_toboolean(gL, -6)) + hook->status = true; - lua_settop(gL, 0); - lua_pushcfunction(gL, LUA_GetErrorMessage); + // output 2: mflags override + if (lua_isnumber(gL, -5)) + *musicchange->mflags = lua_tonumber(gL, -5); + // output 3: looping override + if (lua_isboolean(gL, -4)) + *musicchange->looping = lua_toboolean(gL, -4); + // output 4: position override + if (lua_isboolean(gL, -3)) + *musicchange->position = lua_tonumber(gL, -3); + // output 5: prefadems override + if (lua_isboolean(gL, -2)) + *musicchange->prefadems = lua_tonumber(gL, -2); + // output 6: fadeinms override + if (lua_isboolean(gL, -1)) + *musicchange->fadeinms = lua_tonumber(gL, -1); +} - for (hookp = roothook; hookp; hookp = hookp->next) - if (hookp->type == hook_MusicChange) - { - PushHook(gL, hookp); - lua_pushstring(gL, oldname); - lua_pushstring(gL, newname); - lua_pushinteger(gL, *mflags); - lua_pushboolean(gL, *looping); - lua_pushinteger(gL, *position); - lua_pushinteger(gL, *prefadems); - lua_pushinteger(gL, *fadeinms); - if (lua_pcall(gL, 7, 6, 1)) { - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1)); - lua_pop(gL, 1); - continue; - } +int LUA_HookMusicChange(const char *oldname, struct MusicChange *param) +{ + Hook_State hook; + if (prepare_hook(&hook, false, Hook(MusicChange))) + { + int n; + int k; - // output 1: true, false, or string musicname override - if (lua_isboolean(gL, -6) && lua_toboolean(gL, -6)) - hooked = true; - else if (lua_isstring(gL, -6)) - strncpy(newname, lua_tostring(gL, -6), 7); - // output 2: mflags override - if (lua_isnumber(gL, -5)) - *mflags = lua_tonumber(gL, -5); - // output 3: looping override - if (lua_isboolean(gL, -4)) - *looping = lua_toboolean(gL, -4); - // output 4: position override - if (lua_isboolean(gL, -3)) - *position = lua_tonumber(gL, -3); - // output 5: prefadems override - if (lua_isboolean(gL, -2)) - *prefadems = lua_tonumber(gL, -2); - // output 6: fadeinms override - if (lua_isboolean(gL, -1)) - *fadeinms = lua_tonumber(gL, -1); + init_hook_call(&hook, 7, 6, res_musicchange); + hook.userdata = param; - lua_pop(gL, 7); // Pop returned values and error handler + lua_pushstring(gL, oldname);/* the only constant value */ + lua_pushstring(gL, param->newname);/* semi constant */ + + get_hook_table(&hook); + n = lua_objlen(gL, -1); + + for (k = 1; k <= n; ++k) { + lua_pushvalue(gL, -3); + lua_pushvalue(gL, -3); + lua_pushinteger(gL, *param->mflags); + lua_pushboolean(gL, *param->looping); + lua_pushinteger(gL, *param->position); + lua_pushinteger(gL, *param->prefadems); + lua_pushinteger(gL, *param->fadeinms); + + call_single_hook_no_copy(&hook); } - lua_settop(gL, 0); - newname[6] = 0; - return hooked; -} \ No newline at end of file + lua_settop(gL, 0); + } + return hook.status; +} diff --git a/src/lua_script.c b/src/lua_script.c index eb4737f76..a649942b8 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -1628,7 +1628,7 @@ void LUA_Archive(void) WRITEUINT32(save_p, UINT32_MAX); // end of mobjs marker, replaces mobjnum. - LUAh_NetArchiveHook(NetArchive); // call the NetArchive hook in archive mode + LUA_HookNetArchive(NetArchive); // call the NetArchive hook in archive mode ArchiveTables(); if (gL) @@ -1663,7 +1663,7 @@ void LUA_UnArchive(void) } } while(mobjnum != UINT32_MAX); // repeat until end of mobjs marker. - LUAh_NetArchiveHook(NetUnArchive); // call the NetArchive hook in unarchive mode + LUA_HookNetArchive(NetUnArchive); // call the NetArchive hook in unarchive mode UnArchiveTables(); if (gL) diff --git a/src/lua_script.h b/src/lua_script.h index 79ba0bb38..e9104f3d5 100644 --- a/src/lua_script.h +++ b/src/lua_script.h @@ -61,7 +61,7 @@ void Got_Luacmd(UINT8 **cp, INT32 playernum); // lua_consolelib.c void LUA_CVarChanged(const char *name); // lua_consolelib.c int Lua_optoption(lua_State *L, int narg, const char *def, const char *const lst[]); -void LUAh_NetArchiveHook(lua_CFunction archFunc); +void LUA_HookNetArchive(lua_CFunction archFunc); // Console wrapper void COM_Lua_f(void); diff --git a/src/m_menu.c b/src/m_menu.c index 77648f877..a9333e36e 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -6938,7 +6938,7 @@ static void M_UltimateCheat(INT32 choice) { (void)choice; if (Playing()) - LUAh_GameQuit(); + LUA_Hook(GameQuit); I_Quit(); } @@ -13373,7 +13373,7 @@ void M_QuitResponse(INT32 ch) if (ch != 'y' && ch != KEY_ENTER) return; if (Playing()) - LUAh_GameQuit(); + LUA_Hook(GameQuit); if (!(netgame || cv_debug)) { S_ResetCaptions(); diff --git a/src/p_enemy.c b/src/p_enemy.c index 22de9bc67..103441701 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -3957,7 +3957,7 @@ void A_BossDeath(mobj_t *mo) } bossjustdie: - if (LUAh_BossDeath(mo)) + if (LUA_HookMobj(mo, Mobj_Hook(BossDeath))) return; else if (P_MobjWasRemoved(mo)) return; diff --git a/src/p_inter.c b/src/p_inter.c index 415c679e4..2d5f2736a 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -365,7 +365,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (special->flags & (MF_ENEMY|MF_BOSS) && special->flags2 & MF2_FRET) return; - if (LUAh_TouchSpecial(special, toucher) || P_MobjWasRemoved(special)) + if (LUA_HookTouchSpecial(special, toucher) || P_MobjWasRemoved(special)) return; // 0 = none, 1 = elemental pierce, 2 = bubble bounce @@ -1935,7 +1935,7 @@ static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *sour if (!netgame) return; // Presumably it's obvious what's happening in splitscreen. - if (LUAh_HurtMsg(player, inflictor, source, damagetype)) + if (LUA_HookHurtMsg(player, inflictor, source, damagetype)) return; deadtarget = (player->mo->health <= 0); @@ -2409,7 +2409,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget target->flags2 &= ~(MF2_SKULLFLY|MF2_NIGHTSPULL); target->health = 0; // This makes it easy to check if something's dead elsewhere. - if (LUAh_MobjDeath(target, inflictor, source, damagetype) || P_MobjWasRemoved(target)) + if (LUA_HookMobjDeath(target, inflictor, source, damagetype) || P_MobjWasRemoved(target)) return; // Let EVERYONE know what happened to a player! 01-29-2002 Tails @@ -3544,7 +3544,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da // Everything above here can't be forced. if (!metalrecording) { - UINT8 shouldForce = LUAh_ShouldDamage(target, inflictor, source, damage, damagetype); + UINT8 shouldForce = LUA_HookShouldDamage(target, inflictor, source, damage, damagetype); if (P_MobjWasRemoved(target)) return (shouldForce == 1); // mobj was removed if (shouldForce == 1) @@ -3585,7 +3585,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da if (!force && target->flags2 & MF2_FRET) // Currently flashing from being hit return false; - if (LUAh_MobjDamage(target, inflictor, source, damage, damagetype) || P_MobjWasRemoved(target)) + if (LUA_HookMobjDamage(target, inflictor, source, damage, damagetype) || P_MobjWasRemoved(target)) return true; if (target->health > 1) @@ -3635,7 +3635,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da || (G_GametypeHasTeams() && player->ctfteam == source->player->ctfteam))) return false; // Don't run eachother over in special stages and team games and such } - if (LUAh_MobjDamage(target, inflictor, source, damage, damagetype)) + if (LUA_HookMobjDamage(target, inflictor, source, damage, damagetype)) return true; P_NiGHTSDamage(target, source); // -5s :( return true; @@ -3689,13 +3689,13 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da if (force || (inflictor && inflictor->flags & MF_MISSILE && inflictor->flags2 & MF2_SUPERFIRE)) // Super Sonic is stunned! { - if (!LUAh_MobjDamage(target, inflictor, source, damage, damagetype)) + if (!LUA_HookMobjDamage(target, inflictor, source, damage, damagetype)) P_SuperDamage(player, inflictor, source, damage); return true; } return false; } - else if (LUAh_MobjDamage(target, inflictor, source, damage, damagetype)) + else if (LUA_HookMobjDamage(target, inflictor, source, damage, damagetype)) return true; else if (player->powers[pw_shield] || (player->bot && !ultimatemode)) //If One-Hit Shield { diff --git a/src/p_map.c b/src/p_map.c index 922c0d9ec..8c548ed3c 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -747,7 +747,7 @@ static boolean PIT_CheckThing(mobj_t *thing) return true; // underneath // REX HAS SEEN YOU - if (!LUAh_SeenPlayer(tmthing->target->player, thing->player)) + if (!LUA_HookSeenPlayer(tmthing->target->player, thing->player)) return false; seenplayer = thing->player; @@ -937,7 +937,7 @@ static boolean PIT_CheckThing(mobj_t *thing) } { - UINT8 shouldCollide = LUAh_MobjCollide(thing, tmthing); // checks hook for thing's type + UINT8 shouldCollide = LUA_Hook2Mobj(thing, tmthing, Mobj_Hook(MobjCollide)); // checks hook for thing's type if (P_MobjWasRemoved(tmthing) || P_MobjWasRemoved(thing)) return true; // one of them was removed??? if (shouldCollide == 1) @@ -945,7 +945,7 @@ static boolean PIT_CheckThing(mobj_t *thing) else if (shouldCollide == 2) return true; // force no collide - shouldCollide = LUAh_MobjMoveCollide(tmthing, thing); // checks hook for tmthing's type + shouldCollide = LUA_Hook2Mobj(tmthing, thing, Mobj_Hook(MobjMoveCollide)); // checks hook for tmthing's type if (P_MobjWasRemoved(tmthing) || P_MobjWasRemoved(thing)) return true; // one of them was removed??? if (shouldCollide == 1) @@ -1927,7 +1927,7 @@ static boolean PIT_CheckLine(line_t *ld) blockingline = ld; { - UINT8 shouldCollide = LUAh_MobjLineCollide(tmthing, blockingline); // checks hook for thing's type + UINT8 shouldCollide = LUA_HookMobjLineCollide(tmthing, blockingline); // checks hook for thing's type if (P_MobjWasRemoved(tmthing)) return true; // one of them was removed??? if (shouldCollide == 1) diff --git a/src/p_mobj.c b/src/p_mobj.c index 7ba6d1fad..5523fa273 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1844,7 +1844,7 @@ void P_XYMovement(mobj_t *mo) B_MoveBlocked(player); } - if (LUAh_MobjMoveBlocked(mo)) + if (LUA_HookMobj(mo, Mobj_Hook(MobjMoveBlocked))) { if (P_MobjWasRemoved(mo)) return; @@ -7513,7 +7513,7 @@ static void P_RosySceneryThink(mobj_t *mobj) static void P_MobjSceneryThink(mobj_t *mobj) { - if (LUAh_MobjThinker(mobj)) + if (LUA_HookMobj(mobj, Mobj_Hook(MobjThinker))) return; if (P_MobjWasRemoved(mobj)) return; @@ -7861,7 +7861,7 @@ static void P_MobjSceneryThink(mobj_t *mobj) if (!mobj->fuse) { - if (!LUAh_MobjFuse(mobj)) + if (!LUA_HookMobj(mobj, Mobj_Hook(MobjFuse))) P_RemoveMobj(mobj); return; } @@ -7920,7 +7920,7 @@ static void P_MobjSceneryThink(mobj_t *mobj) mobj->fuse--; if (!mobj->fuse) { - if (!LUAh_MobjFuse(mobj)) + if (!LUA_HookMobj(mobj, Mobj_Hook(MobjFuse))) P_RemoveMobj(mobj); return; } @@ -7949,7 +7949,7 @@ static boolean P_MobjPushableThink(mobj_t *mobj) static boolean P_MobjBossThink(mobj_t *mobj) { - if (LUAh_BossThinker(mobj)) + if (LUA_HookMobj(mobj, Mobj_Hook(BossThinker))) { if (P_MobjWasRemoved(mobj)) return false; @@ -9870,7 +9870,7 @@ static boolean P_FuseThink(mobj_t *mobj) if (mobj->fuse) return true; - if (LUAh_MobjFuse(mobj) || P_MobjWasRemoved(mobj)) + if (LUA_HookMobj(mobj, Mobj_Hook(MobjFuse)) || P_MobjWasRemoved(mobj)) ; else if (mobj->info->flags & MF_MONITOR) { @@ -10046,13 +10046,13 @@ void P_MobjThinker(mobj_t *mobj) // Check for a Lua thinker first if (!mobj->player) { - if (LUAh_MobjThinker(mobj) || P_MobjWasRemoved(mobj)) + if (LUA_HookMobj(mobj, Mobj_Hook(MobjThinker)) || P_MobjWasRemoved(mobj)) return; } else if (!mobj->player->spectator) { // You cannot short-circuit the player thinker like you can other thinkers. - LUAh_MobjThinker(mobj); + LUA_HookMobj(mobj, Mobj_Hook(MobjThinker)); if (P_MobjWasRemoved(mobj)) return; } @@ -10523,7 +10523,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) // DANGER! This can cause P_SpawnMobj to return NULL! // Avoid using P_RemoveMobj on the newly created mobj in "MobjSpawn" Lua hooks! - if (LUAh_MobjSpawn(mobj)) + if (LUA_HookMobj(mobj, Mobj_Hook(MobjSpawn))) { if (P_MobjWasRemoved(mobj)) return NULL; @@ -10910,7 +10910,7 @@ void P_RemoveMobj(mobj_t *mobj) return; // something already removing this mobj. mobj->thinker.function.acp1 = (actionf_p1)P_RemoveThinkerDelayed; // shh. no recursing. - LUAh_MobjRemoved(mobj); + LUA_HookMobj(mobj, Mobj_Hook(MobjRemoved)); mobj->thinker.function.acp1 = (actionf_p1)P_MobjThinker; // needed for P_UnsetThingPosition, etc. to work. // Rings only, please! @@ -12556,7 +12556,7 @@ static boolean P_SetupBooster(mapthing_t* mthing, mobj_t* mobj, boolean strong) static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean *doangle) { - boolean override = LUAh_MapThingSpawn(mobj, mthing); + boolean override = LUA_HookMapThingSpawn(mobj, mthing); if (P_MobjWasRemoved(mobj)) return false; diff --git a/src/p_setup.c b/src/p_setup.c index 918ffbd4e..01d43bd88 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -65,7 +65,7 @@ #include "md5.h" // map MD5 -// for LUAh_MapLoad +// for MapLoad hook #include "lua_script.h" #include "lua_hook.h" @@ -4271,7 +4271,7 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate) G_CopyTiccmd(&players[i].cmd, &netcmds[buf][i], 1); } P_PreTicker(2); - LUAh_MapLoad(); + LUA_HookInt(gamemap, Hook(MapLoad)); } // No render mode or reloading gamestate, stop here. diff --git a/src/p_spec.c b/src/p_spec.c index a1afdd00d..59b9a0648 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -35,7 +35,7 @@ #include "v_video.h" // V_AUTOFADEOUT|V_ALLOWLOWERCASE #include "m_misc.h" #include "m_cond.h" //unlock triggers -#include "lua_hook.h" // LUAh_LinedefExecute +#include "lua_hook.h" // LUA_HookLinedefExecute #include "f_finale.h" // control text prompt #include "r_skins.h" // skins @@ -3135,7 +3135,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) case 443: // Calls a named Lua function if (line->stringargs[0]) - LUAh_LinedefExecute(line, mo, callsec); + LUA_HookLinedefExecute(line, mo, callsec); else CONS_Alert(CONS_WARNING, "Linedef %s is missing the hook name of the Lua function to call! (This should be given in arg0str)\n", sizeu1(line-lines)); break; diff --git a/src/p_tick.c b/src/p_tick.c index da2a980c4..930223ab9 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -656,7 +656,7 @@ void P_Ticker(boolean run) ps_lua_mobjhooks = 0; ps_checkposition_calls = 0; - LUAh_PreThinkFrame(); + LUA_Hook(PreThinkFrame); ps_playerthink_time = I_GetTimeMicros(); for (i = 0; i < MAXPLAYERS; i++) @@ -687,7 +687,7 @@ void P_Ticker(boolean run) P_PlayerAfterThink(&players[i]); ps_lua_thinkframe_time = I_GetTimeMicros(); - LUAh_ThinkFrame(); + LUA_HookThinkFrame(); ps_lua_thinkframe_time = I_GetTimeMicros() - ps_lua_thinkframe_time; } @@ -760,7 +760,7 @@ void P_Ticker(boolean run) if (modeattacking) G_GhostTicker(); - LUAh_PostThinkFrame(); + LUA_Hook(PostThinkFrame); } P_MapEnd(); @@ -783,7 +783,7 @@ void P_PreTicker(INT32 frames) { P_MapStart(); - LUAh_PreThinkFrame(); + LUA_Hook(PreThinkFrame); for (i = 0; i < MAXPLAYERS; i++) if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo)) @@ -810,7 +810,7 @@ void P_PreTicker(INT32 frames) if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo)) P_PlayerAfterThink(&players[i]); - LUAh_ThinkFrame(); + LUA_HookThinkFrame(); // Run shield positioning P_RunShields(); @@ -819,7 +819,7 @@ void P_PreTicker(INT32 frames) P_UpdateSpecials(); P_RespawnSpecials(); - LUAh_PostThinkFrame(); + LUA_Hook(PostThinkFrame); P_MapEnd(); } diff --git a/src/p_user.c b/src/p_user.c index c5f919c78..178a26126 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1111,7 +1111,7 @@ boolean P_PlayerCanDamage(player_t *player, mobj_t *thing) return false; { - UINT8 shouldCollide = LUAh_PlayerCanDamage(player, thing); + UINT8 shouldCollide = LUA_HookPlayerCanDamage(player, thing); if (P_MobjWasRemoved(thing)) return false; // removed??? if (shouldCollide == 1) @@ -1594,7 +1594,7 @@ boolean P_EvaluateMusicStatus(UINT16 status, const char *musname) break; case JT_OTHER: // Other state - result = LUAh_ShouldJingleContinue(&players[i], musname); + result = LUA_HookShouldJingleContinue(&players[i], musname); break; case JT_NONE: // Null state @@ -1860,7 +1860,7 @@ void P_SpawnShieldOrb(player_t *player) I_Error("P_SpawnShieldOrb: player->mo is NULL!\n"); #endif - if (LUAh_ShieldSpawn(player)) + if (LUA_HookPlayer(player, Hook(ShieldSpawn))) return; if (player->powers[pw_shield] & SH_FORCE) @@ -4577,7 +4577,7 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) if (cmd->buttons & BT_SPIN) { - if (LUAh_SpinSpecial(player)) + if (LUA_HookPlayer(player, Hook(SpinSpecial))) return; } @@ -5043,7 +5043,7 @@ static boolean P_PlayerShieldThink(player_t *player, ticcmd_t *cmd, mobj_t *lock } } } - if (cmd->buttons & BT_SPIN && !LUAh_ShieldSpecial(player)) // Spin button effects + if (cmd->buttons & BT_SPIN && !LUA_HookPlayer(player, Hook(ShieldSpecial))) // Spin button effects { // Force stop if ((player->powers[pw_shield] & ~(SH_FORCEHP|SH_STACK)) == SH_FORCE) @@ -5167,7 +5167,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) // and you don't have a shield, do it! P_DoSuperTransformation(player, false); } - else if (!LUAh_JumpSpinSpecial(player)) + else if (!LUA_HookPlayer(player, Hook(JumpSpinSpecial))) switch (player->charability) { case CA_THOK: @@ -5240,7 +5240,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) if (cmd->buttons & BT_JUMP && !player->exiting && !P_PlayerInPain(player)) { - if (LUAh_JumpSpecial(player)) + if (LUA_HookPlayer(player, Hook(JumpSpecial))) ; // all situations below this require jump button not to be pressed already else if (player->pflags & PF_JUMPDOWN) @@ -5275,7 +5275,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) }*/ else if (player->pflags & PF_JUMPED) { - if (!LUAh_AbilitySpecial(player)) + if (!LUA_HookPlayer(player, Hook(AbilitySpecial))) switch (player->charability) { case CA_THOK: @@ -5468,7 +5468,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) } else if (player->pflags & PF_THOKKED) { - if (!LUAh_AbilitySpecial(player)) + if (!LUA_HookPlayer(player, Hook(AbilitySpecial))) switch (player->charability) { case CA_FLY: @@ -10490,7 +10490,7 @@ boolean P_SpectatorJoinGame(player_t *player) else changeto = (P_RandomFixed() & 1) + 1; - if (!LUAh_TeamSwitch(player, changeto, true, false, false)) + if (!LUA_HookTeamSwitch(player, changeto, true, false, false)) return false; if (player->mo) @@ -10507,7 +10507,7 @@ boolean P_SpectatorJoinGame(player_t *player) { // Call ViewpointSwitch hooks here. // The viewpoint was forcibly changed. - LUAh_ViewpointSwitch(player, &players[consoleplayer], true); + LUA_HookViewpointSwitch(player, &players[consoleplayer], true); displayplayer = consoleplayer; } @@ -10525,7 +10525,7 @@ boolean P_SpectatorJoinGame(player_t *player) // respawn in place and sit there for the rest of the round. if (!((gametyperules & GTR_HIDEFROZEN) && leveltime > (hidetime * TICRATE))) { - if (!LUAh_TeamSwitch(player, 3, true, false, false)) + if (!LUA_HookTeamSwitch(player, 3, true, false, false)) return false; if (player->mo) { @@ -10552,7 +10552,7 @@ boolean P_SpectatorJoinGame(player_t *player) { // Call ViewpointSwitch hooks here. // The viewpoint was forcibly changed. - LUAh_ViewpointSwitch(player, &players[consoleplayer], true); + LUA_HookViewpointSwitch(player, &players[consoleplayer], true); displayplayer = consoleplayer; } @@ -11477,7 +11477,7 @@ void P_PlayerThink(player_t *player) } if (player->playerstate == PST_REBORN) { - LUAh_PlayerThink(player); + LUA_HookPlayer(player, Hook(PlayerThink)); return; } } @@ -11581,7 +11581,7 @@ void P_PlayerThink(player_t *player) if (player->playerstate == PST_DEAD) { - LUAh_PlayerThink(player); + LUA_HookPlayer(player, Hook(PlayerThink)); return; } } @@ -11702,7 +11702,7 @@ void P_PlayerThink(player_t *player) { player->mo->flags2 &= ~MF2_SHADOW; P_DeathThink(player); - LUAh_PlayerThink(player); + LUA_HookPlayer(player, Hook(PlayerThink)); return; } @@ -11744,7 +11744,7 @@ void P_PlayerThink(player_t *player) { if (P_SpectatorJoinGame(player)) { - LUAh_PlayerThink(player); + LUA_HookPlayer(player, Hook(PlayerThink)); return; // player->mo was removed. } } @@ -11849,7 +11849,7 @@ void P_PlayerThink(player_t *player) if (!player->mo) { - LUAh_PlayerThink(player); + LUA_HookPlayer(player, Hook(PlayerThink)); return; // P_MovePlayer removed player->mo. } @@ -12303,7 +12303,7 @@ void P_PlayerThink(player_t *player) } #undef dashmode - LUAh_PlayerThink(player); + LUA_HookPlayer(player, Hook(PlayerThink)); /* // Colormap verification @@ -12863,7 +12863,7 @@ void P_PlayerAfterThink(player_t *player) if (player->followmobj) { - if (LUAh_FollowMobj(player, player->followmobj) || P_MobjWasRemoved(player->followmobj)) + if (LUA_HookFollowMobj(player, player->followmobj) || P_MobjWasRemoved(player->followmobj)) {;} else { diff --git a/src/s_sound.c b/src/s_sound.c index 36bd454c1..106a5bd23 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -2262,6 +2262,16 @@ static void S_ChangeMusicToQueue(void) void S_ChangeMusicEx(const char *mmusic, UINT16 mflags, boolean looping, UINT32 position, UINT32 prefadems, UINT32 fadeinms) { char newmusic[7]; + + struct MusicChange hook_param = { + newmusic, + &mflags, + &looping, + &position, + &prefadems, + &fadeinms + }; + boolean currentmidi = (I_SongType() == MU_MID || I_SongType() == MU_MID_EX); boolean midipref = cv_musicpref.value; @@ -2269,7 +2279,7 @@ void S_ChangeMusicEx(const char *mmusic, UINT16 mflags, boolean looping, UINT32 return; strncpy(newmusic, mmusic, 7); - if (LUAh_MusicChange(music_name, newmusic, &mflags, &looping, &position, &prefadems, &fadeinms)) + if (LUA_HookMusicChange(music_name, &hook_param)) return; newmusic[6] = 0; diff --git a/src/s_sound.h b/src/s_sound.h index 4ac3c70bf..c872c2224 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -265,6 +265,16 @@ boolean S_RecallMusic(UINT16 status, boolean fromfirst); // Music Playback // +/* this is for the sake of the hook */ +struct MusicChange { + char * newname; + UINT16 * mflags; + boolean * looping; + UINT32 * position; + UINT32 * prefadems; + UINT32 * fadeinms; +}; + // Start music track, arbitrary, given its name, and set whether looping // note: music flags 12 bits for tracknum (gme, other formats with more than one track) // 13-15 aren't used yet diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index b8b3b9d34..8ca4f758a 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1058,7 +1058,7 @@ void I_GetEvent(void) break; case SDL_QUIT: if (Playing()) - LUAh_GameQuit(); + LUA_Hook(GameQuit); I_Quit(); break; } diff --git a/src/y_inter.c b/src/y_inter.c index 061cbb5e1..ae4dcdaf0 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -927,7 +927,7 @@ void Y_Ticker(void) if (paused || P_AutoPause()) return; - LUAh_IntermissionThinker(); + LUA_Hook(IntermissionThinker); intertic++; From 0df5d8ff58da2fcb6e20db31257308d8724c651e Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 10 Dec 2020 03:06:41 -0800 Subject: [PATCH 131/644] Oops! --- src/m_anigif.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/m_anigif.c b/src/m_anigif.c index 5c42fc605..41f99254e 100644 --- a/src/m_anigif.c +++ b/src/m_anigif.c @@ -621,7 +621,7 @@ static void GIF_framewrite(void) { float delayf = ceil(100.0f/NEWTICRATE); - delay = (UINT16)((I_GetTimeMicros() - gif_prevframeus)/10/1000); + delay = (UINT16)I_PreciseToMicros((I_GetPreciseTime() - gif_prevframetime))/10/1000; if (delay < (UINT16)(delayf)) delay = (UINT16)(delayf); From 3f7c2ae0b0c450cb8993ffe7664ead05fd9f5000 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 10 Dec 2020 05:39:53 -0800 Subject: [PATCH 132/644] Avoid using multiple tables to fetch hook String hooks still use a table to fetch the id, but the id indexes a C array. Also I fixed a missing call in the MusicChange hook. --- src/lua_hooklib.c | 212 ++++++++++++++++++++++------------------------ 1 file changed, 101 insertions(+), 111 deletions(-) diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 2d5ee44e4..02c427979 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -52,17 +52,24 @@ static inline int in_bit_array (const UINT8 *array, const int n) { return array[n >> 3] & (1 << (n & 7)); } +typedef struct { + int numHooks; + int *ids; +} hook_t; + typedef struct { int numGeneric; int ref; } stringhook_t; -static int hookRefs[Hook(MAX)]; -static int mobjHookRefs[NUMMOBJTYPES][Mobj_Hook(MAX)]; +static hook_t hookIds[Hook(MAX)]; +static hook_t mobjHookIds[NUMMOBJTYPES][Mobj_Hook(MAX)]; +// Lua tables are used to lookup string hook ids. static stringhook_t stringHooks[String_Hook(MAX)]; -static int hookReg; +// This will be indexed by hook id, the value of which fetches the registry. +static int * hookRefs; // After a hook errors once, don't print the error again. static UINT8 * hooksErrored; @@ -71,8 +78,8 @@ static boolean mobj_hook_available(int hook_type, mobjtype_t mobj_type) { return ( - mobjHookRefs [MT_NULL] [hook_type] > 0 || - mobjHookRefs[mobj_type][hook_type] > 0 + mobjHookIds [MT_NULL] [hook_type].numHooks > 0 || + mobjHookIds[mobj_type][hook_type].numHooks > 0 ); } @@ -109,32 +116,10 @@ static void get_table(lua_State *L) lua_remove(L, -2); } -static void new_hook_table(lua_State *L, int *ref) +static void add_hook_to_table(lua_State *L, int id, int n) { - if (*ref > 0) - lua_getref(L, *ref); - else - { - lua_newtable(L); - lua_pushvalue(L, -1); - *ref = luaL_ref(L, LUA_REGISTRYINDEX); - } -} - -static void add_hook(lua_State *L, int id) -{ - lua_pushnumber(L, 1 + id); - lua_rawseti(L, -2, 1 + lua_objlen(L, -2)); -} - -static void add_mobj_hook(lua_State *L, int hook_type, int id) -{ - mobjtype_t mobj_type = luaL_optnumber(L, 3, MT_NULL); - - luaL_argcheck(L, mobj_type < NUMMOBJTYPES, 3, "invalid mobjtype_t"); - - new_hook_table(L, &mobjHookRefs[mobj_type][hook_type]); - add_hook(L, id); + lua_pushnumber(L, id); + lua_rawseti(L, -2, n); } static void add_string_hook(lua_State *L, int type, int id) @@ -160,19 +145,39 @@ static void add_string_hook(lua_State *L, int type, int id) break; } - new_hook_table(L, &hook->ref); + if (hook->ref > 0) + lua_getref(L, hook->ref); + else + { + lua_newtable(L); + lua_pushvalue(L, -1); + hook->ref = luaL_ref(L, LUA_REGISTRYINDEX); + } if (string) { lua_pushstring(L, string); get_table(L); - add_hook(L, id); + add_hook_to_table(L, id, 1 + lua_objlen(L, -1)); } else - { - lua_pushnumber(L, 1 + id); - lua_rawseti(L, -2, ++hook->numGeneric); - } + add_hook_to_table(L, id, ++hook->numGeneric); +} + +static void add_hook(hook_t *map, int id) +{ + Z_Realloc(map->ids, (map->numHooks + 1) * sizeof *map->ids, + PU_STATIC, &map->ids); + map->ids[map->numHooks++] = id; +} + +static void add_mobj_hook(lua_State *L, int hook_type, int id) +{ + mobjtype_t mobj_type = luaL_optnumber(L, 3, MT_NULL); + + luaL_argcheck(L, mobj_type < NUMMOBJTYPES, 3, "invalid mobjtype_t"); + + add_hook(&mobjHookIds[mobj_type][hook_type], id); } // Takes hook, function, and additional arguments (mobj type to act on, etc.) @@ -200,8 +205,7 @@ static int lib_addHook(lua_State *L) } else if (( type = hook_in_list(name, hookNames) ) < Hook(MAX)) { - new_hook_table(L, &hookRefs[type]); - add_hook(L, nextid); + add_hook(&hookIds[type], nextid); } else { @@ -216,17 +220,17 @@ static int lib_addHook(lua_State *L) hooksErrored[nextid >> 3] = 0; } + Z_Realloc(hookRefs, (nextid + 1) * sizeof *hookRefs, PU_STATIC, &hookRefs); + // set the hook function in the registry. - lua_getref(L, hookReg); lua_pushvalue(L, 2);/* the function */ - lua_rawseti(L, -2, ++nextid); + hookRefs[nextid++] = luaL_ref(L, LUA_REGISTRYINDEX); return 0; } int LUA_HookLib(lua_State *L) { - new_hook_table(L, &hookReg); lua_register(L, "addHook", lib_addHook); return 0; } @@ -237,21 +241,19 @@ typedef void (*Hook_Callback)(Hook_State *); struct Hook_State { int status;/* return status to calling function */ void * userdata; - int ref;/* ref for primary hook table */ - int hook_type;/* Hook or Hook(MAX) + Mobj_Hook */ - mobjtype_t mobj_type; + int hook_type; + mobjtype_t mobj_type;/* >0 if mobj hook */ const char * string;/* used to fetch table, ran first if set */ int top;/* index of last argument passed to hook */ - int id;/* id to fetch function from registry */ + int id;/* id to fetch ref */ int values;/* num arguments passed to hook */ int results;/* num values returned by hook */ Hook_Callback results_handler;/* callback when hook successfully returns */ }; enum { - HINDEX = 1,/* hook registry */ - EINDEX = 2,/* error handler */ - SINDEX = 3,/* string itself is pushed in case of string hook */ + EINDEX = 1,/* error handler */ + SINDEX = 2,/* string itself is pushed in case of string hook */ }; static void push_error_handler(void) @@ -268,7 +270,6 @@ static void push_string(void) static boolean start_hook_stack(void) { lua_settop(gL, 0); - lua_getref(gL, hookReg); push_error_handler(); return true; } @@ -280,20 +281,12 @@ static boolean init_hook_type int hook_type, mobjtype_t mobj_type, const char * string, - int ref + int nonzero ){ - boolean ready; - hook->status = status; - if (mobj_type > 0) - ready = mobj_hook_available(hook_type, mobj_type); - else - ready = ref > 0; - - if (ready) + if (nonzero) { - hook->ref = ref; hook->hook_type = hook_type; hook->mobj_type = mobj_type; hook->string = string; @@ -311,7 +304,7 @@ static boolean prepare_hook ){ return init_hook_type(hook, default_status, hook_type, 0, NULL, - hookRefs[hook_type]); + hookIds[hook_type].numHooks); } static boolean prepare_mobj_hook @@ -323,7 +316,7 @@ static boolean prepare_mobj_hook ){ return init_hook_type(hook, default_status, hook_type, mobj_type, NULL, - mobjHookRefs[mobj_type][hook_type]); + mobj_hook_available(hook_type, mobj_type)); } static boolean prepare_string_hook @@ -357,16 +350,17 @@ static void init_hook_call hook->results_handler = results_handler; } -static void get_hook_table(Hook_State *hook) +static void get_hook(Hook_State *hook, const int *ids, int n) { - lua_getref(gL, hook->ref); + hook->id = ids[n]; + lua_getref(gL, hookRefs[hook->id]); } -static void get_hook(Hook_State *hook, int n) +static void get_hook_from_table(Hook_State *hook, int n) { lua_rawgeti(gL, -1, n); - hook->id = lua_tonumber(gL, -1) - 1; - lua_rawget(gL, HINDEX); + hook->id = lua_tonumber(gL, -1); + lua_getref(gL, hookRefs[hook->id]); } static int call_single_hook_no_copy(Hook_State *hook) @@ -409,7 +403,7 @@ static int call_hook_table_for(Hook_State *hook, int n) for (k = 1; k <= n; ++k) { - get_hook(hook, k); + get_hook_from_table(hook, k); call_single_hook(hook); } @@ -421,31 +415,29 @@ static int call_hook_table(Hook_State *hook) return call_hook_table_for(hook, lua_objlen(gL, -1)); } -static int call_ref(Hook_State *hook, int ref) +static int call_mapped(Hook_State *hook, const hook_t *map) { - int calls; + int k; - if (ref > 0) + for (k = 0; k < map->numHooks; ++k) { - lua_getref(gL, ref); - calls = call_hook_table(hook); - - return calls; + get_hook(hook, map->ids, k); + call_single_hook(hook); } - else - return 0; + + return map->numHooks; } static int call_string_hooks(Hook_State *hook) { - const int numGeneric = stringHooks[hook->hook_type].numGeneric; + const stringhook_t *map = &stringHooks[hook->hook_type]; int calls = 0; - get_hook_table(hook); + lua_getref(gL, map->ref); /* call generic string hooks first */ - calls += call_hook_table_for(hook, numGeneric); + calls += call_hook_table_for(hook, map->numGeneric); push_string(); lua_rawget(gL, -2); @@ -454,10 +446,9 @@ static int call_string_hooks(Hook_State *hook) return calls; } -static int call_generic_mobj_hooks(Hook_State *hook) +static int call_mobj_type_hooks(Hook_State *hook, mobjtype_t mobj_type) { - const int ref = mobjHookRefs[MT_NULL][hook->hook_type]; - return call_ref(hook, ref); + return call_mapped(hook, &mobjHookIds[mobj_type][hook->hook_type]); } static int call_hooks @@ -475,16 +466,16 @@ static int call_hooks { calls += call_string_hooks(hook); } - else + else if (hook->mobj_type > 0) { - if (hook->mobj_type > 0) - calls += call_generic_mobj_hooks(hook); + /* call generic mobj hooks first */ + calls += call_mobj_type_hooks(hook, MT_NULL); + calls += call_mobj_type_hooks(hook, hook->mobj_type); - calls += call_ref(hook, hook->ref); - - if (hook->mobj_type > 0) - ps_lua_mobjhooks += calls; + ps_lua_mobjhooks += calls; } + else + calls += call_mapped(hook, &hookIds[hook->hook_type]); lua_settop(gL, 0); @@ -600,25 +591,24 @@ int LUA_HookTiccmd(player_t *player, ticcmd_t *cmd, int hook_type) void LUA_HookThinkFrame(void) { + const int type = Hook(ThinkFrame); + // variables used by perf stats int hook_index = 0; precise_t time_taken = 0; Hook_State hook; - int n; + const hook_t * map = &hookIds[type]; int k; - if (prepare_hook(&hook, 0, Hook(ThinkFrame))) + if (prepare_hook(&hook, 0, type)) { init_hook_call(&hook, 0, 0, res_none); - get_hook_table(&hook); - n = lua_objlen(gL, -1); - - for (k = 1; k <= n; ++k) + for (k = 0; k < map->numHooks; ++k) { - get_hook(&hook, k); + get_hook(&hook, map->ids, k); if (cv_perfstats.value == 3) { @@ -839,19 +829,16 @@ int LUA_HookHurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 d void LUA_HookNetArchive(lua_CFunction archFunc) { - const int ref = hookRefs[Hook(NetVars)]; + const hook_t * map = &hookIds[Hook(NetVars)]; Hook_State hook; /* this is a remarkable case where the stack isn't reset */ - if (ref > 0) + if (map->numHooks > 0) { // stack: tables I_Assert(lua_gettop(gL) > 0); I_Assert(lua_istable(gL, -1)); push_error_handler(); - lua_getref(gL, hookReg); - - lua_insert(gL, HINDEX); lua_insert(gL, EINDEX); // tables becomes an upvalue of archFunc @@ -860,11 +847,10 @@ void LUA_HookNetArchive(lua_CFunction archFunc) // stack: tables, archFunc init_hook_call(&hook, 1, 0, res_none); - call_ref(&hook, ref); + call_mapped(&hook, map); lua_pop(gL, 2); // pop hook table and archFunc lua_remove(gL, EINDEX); // pop error handler - lua_remove(gL, HINDEX); // pop hook registry // stack: tables } } @@ -1031,22 +1017,25 @@ static void res_musicchange(Hook_State *hook) int LUA_HookMusicChange(const char *oldname, struct MusicChange *param) { - Hook_State hook; - if (prepare_hook(&hook, false, Hook(MusicChange))) - { - int n; - int k; + const int type = Hook(MusicChange); + const hook_t * map = &hookIds[type]; + Hook_State hook; + + int k; + + if (prepare_hook(&hook, false, type)) + { init_hook_call(&hook, 7, 6, res_musicchange); hook.userdata = param; lua_pushstring(gL, oldname);/* the only constant value */ lua_pushstring(gL, param->newname);/* semi constant */ - get_hook_table(&hook); - n = lua_objlen(gL, -1); + for (k = 0; k <= map->numHooks; ++k) + { + get_hook(&hook, map->ids, k); - for (k = 1; k <= n; ++k) { lua_pushvalue(gL, -3); lua_pushvalue(gL, -3); lua_pushinteger(gL, *param->mflags); @@ -1060,5 +1049,6 @@ int LUA_HookMusicChange(const char *oldname, struct MusicChange *param) lua_settop(gL, 0); } + return hook.status; } From dbd8903a538e7b87061795ce27ec5c72c26743af Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 10 Dec 2020 08:50:23 -0800 Subject: [PATCH 133/644] Use ref for pushing error handler --- src/lua_hooklib.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 02c427979..1ac9a6952 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -74,6 +74,8 @@ static int * hookRefs; // After a hook errors once, don't print the error again. static UINT8 * hooksErrored; +static int errorRef; + static boolean mobj_hook_available(int hook_type, mobjtype_t mobj_type) { return @@ -231,7 +233,11 @@ static int lib_addHook(lua_State *L) int LUA_HookLib(lua_State *L) { + lua_pushcfunction(L, LUA_GetErrorMessage); + errorRef = luaL_ref(L, LUA_REGISTRYINDEX); + lua_register(L, "addHook", lib_addHook); + return 0; } @@ -258,7 +264,7 @@ enum { static void push_error_handler(void) { - lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getref(gL, errorRef); } /* repush hook string */ From 39a320734dcb53243aaff5228c63870e1295ef44 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Thu, 12 Nov 2020 21:25:31 +0100 Subject: [PATCH 134/644] Add shorthand aliases for fixed-point functions --- src/lua_mathlib.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/lua_mathlib.c b/src/lua_mathlib.c index 7cbe7a6cc..10ba42ee0 100644 --- a/src/lua_mathlib.c +++ b/src/lua_mathlib.c @@ -192,18 +192,30 @@ static luaL_Reg lib[] = { {"cos", lib_finecosine}, {"tan", lib_finetangent}, {"FixedAngle", lib_fixedangle}, + {"fixangle" , lib_fixedangle}, {"AngleFixed", lib_anglefixed}, + {"anglefix" , lib_anglefixed}, {"InvAngle", lib_invangle}, {"FixedMul", lib_fixedmul}, + {"fixmul" , lib_fixedmul}, {"FixedInt", lib_fixedint}, + {"fixint" , lib_fixedint}, {"FixedDiv", lib_fixeddiv}, + {"fixdiv" , lib_fixeddiv}, {"FixedRem", lib_fixedrem}, + {"fixrem" , lib_fixedrem}, {"FixedSqrt", lib_fixedsqrt}, + {"fixsqrt" , lib_fixedsqrt}, {"FixedHypot", lib_fixedhypot}, + {"fixhypot" , lib_fixedhypot}, {"FixedFloor", lib_fixedfloor}, + {"fixfloor" , lib_fixedfloor}, {"FixedTrunc", lib_fixedtrunc}, + {"fixtrunc" , lib_fixedtrunc}, {"FixedCeil", lib_fixedceil}, + {"fixceil" , lib_fixedceil}, {"FixedRound", lib_fixedround}, + {"fixround" , lib_fixedround}, {"GetSecSpecial", lib_getsecspecial}, {"All7Emeralds", lib_all7emeralds}, {"ColorOpposite", lib_coloropposite}, From 3aecc2276430ab55851a89f012a9663fec48f30f Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Thu, 12 Nov 2020 21:33:47 +0100 Subject: [PATCH 135/644] Add a shorthand alias for FRACUNIT --- src/deh_tables.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/deh_tables.c b/src/deh_tables.c index 5733d9b0e..926ca805c 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -4794,6 +4794,7 @@ struct int_const_s const INT_CONST[] = { // fixed_t constants, from m_fixed.h {"FRACUNIT",FRACUNIT}, + {"FU" ,FRACUNIT}, {"FRACBITS",FRACBITS}, // doomdef.h constants From 69d98b22ad19b49072143d98ce4333a474f65826 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 10 Dec 2020 13:40:47 -0800 Subject: [PATCH 136/644] Credits: add Zolton and Ors to the programming section --- src/f_finale.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/f_finale.c b/src/f_finale.c index 688cd4fc7..b23ab4f7a 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1074,6 +1074,7 @@ static const char *credits[] = { "\1Programming", "Alam \"GBC\" Arias", "Logan \"GBA\" Arias", + "Zolton \"Zippy_Zolton\" Auburn", "Colette \"fickleheart\" Bordelon", "Andrew \"orospakr\" Clunis", "Sally \"TehRealSalt\" Cochenour", @@ -1104,6 +1105,7 @@ static const char *credits[] = { "Sean \"Sryder13\" Ryder", "Ehab \"Wolfy\" Saeed", "Tasos \"tatokis\" Sahanidis", // Corrected C FixedMul, making 64-bit builds netplay compatible + "Riku \"Ors\" Salminen", // Demo consistency improvements "Jonas \"MascaraSnake\" Sauer", "Wessel \"sphere\" Smit", "\"SSNTails\"", From 317c107064a1ed88da40b342e07fc4f86d1d6197 Mon Sep 17 00:00:00 2001 From: Zippy_Zolton Date: Thu, 10 Dec 2020 16:09:43 -0600 Subject: [PATCH 137/644] Make player->speed use R_PointToDist2 --- src/p_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index 892f4b678..292e452d7 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -5924,7 +5924,7 @@ static void P_3dMovement(player_t *player) player->rmomy = player->mo->momy - player->cmomy; // Calculates player's speed based on distance-of-a-line formula - player->speed = P_AproxDistance(player->rmomx, player->rmomy); + player->speed = R_PointToDist2(0, 0, player->rmomx, player->rmomy); // Monster Iestyn - 04-11-13 // Quadrants are stupid, excessive and broken, let's do this a much simpler way! From 3472b3ece38bc6d62ff248bfdf34950ec4709105 Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Thu, 10 Dec 2020 21:55:22 -0300 Subject: [PATCH 138/644] Fix ERZ3 mode --- src/p_mobj.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index e664d85be..2393013de 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10438,19 +10438,12 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) mobj->x = x; mobj->y = y; - // TODO: Make this a special map header - if ((maptol & TOL_ERZ3) && !(mobj->type == MT_BLACKEGGMAN)) - mobj->destscale = FRACUNIT/2; - P_SetMobjSpawnDefaults(mobj); // set subsector and/or block links P_SetThingPosition(mobj); I_Assert(mobj->subsector != NULL); - // Make sure scale matches destscale immediately when spawned - P_SetScale(mobj, mobj->destscale); - mobj->floorz = P_GetSectorFloorZAt (mobj->subsector->sector, x, y); mobj->ceilingz = P_GetSectorCeilingZAt(mobj->subsector->sector, x, y); @@ -10816,9 +10809,16 @@ void P_SetMobjSpawnDefaults(mobj_t *mobj) mobj->destscale = mobj->scale; mobj->scalespeed = FRACUNIT/12; + // TODO: Make this a special map header + if ((maptol & TOL_ERZ3) && !(mobj->type == MT_BLACKEGGMAN)) + mobj->destscale = FRACUNIT/2; + + // Make sure scale matches destscale immediately when spawned + P_SetScale(mobj, mobj->destscale); + // Sprite rendering mobj->blendmode = AST_TRANSLUCENT; - mobj->spritexscale = mobj->spriteyscale = mobj->scale; + mobj->spritexscale = mobj->spriteyscale = FRACUNIT; mobj->spritexoffset = mobj->spriteyoffset = 0; mobj->floorspriteslope = NULL; } From 916cacb38f6e7072a1869bd1b964297f05210acb Mon Sep 17 00:00:00 2001 From: Zippy_Zolton Date: Thu, 10 Dec 2020 19:01:09 -0600 Subject: [PATCH 139/644] snailer --- src/p_enemy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 63a14636d..5feae4188 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -1834,7 +1834,7 @@ void A_SnailerThink(mobj_t *actor) fixed_t dist; fixed_t dx, dy; - dist = P_AproxDistance(actor->x - actor->target->x, actor->y - actor->target->y); + dist = R_PointToDist2(0, 0, actor->x - actor->target->x, actor->y - actor->target->y); if (an > ANGLE_45 && an <= ANGLE_90) // fire at 45 degrees to the left { From 440f46144a75d9048c24eef9fcaf34b0cad8181b Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Thu, 10 Dec 2020 22:01:53 -0300 Subject: [PATCH 140/644] Fix intro crash --- src/w_wad.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/w_wad.c b/src/w_wad.c index 2429eaf92..6566800c0 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -1747,6 +1747,9 @@ void *W_CachePatchNum(lumpnum_t lumpnum, INT32 tag) void W_UnlockCachedPatch(void *patch) { + if (!patch) + return; + // The hardware code does its own memory management, as its patches // have different lifetimes from software's. #ifdef HWRENDER @@ -2144,7 +2147,7 @@ int W_VerifyNMUSlumps(const char *filename, boolean exit_on_error) {"LT", 2}, // Titlecard changes {"SLID", 4}, // Continue - {"CONT", 4}, + {"CONT", 4}, {"MINICAPS", 8}, // NiGHTS graphics here and below {"BLUESTAT", 8}, // Sphere status From f79ded7c0b86a6d8e9c23f8fb0ec2c417c03752a Mon Sep 17 00:00:00 2001 From: katsy Date: Thu, 10 Dec 2020 20:52:06 -0500 Subject: [PATCH 141/644] scale minimum dashmode thok on actionspd, not normalspeed --- src/p_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index c5f919c78..c760d52ec 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -5289,7 +5289,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) fixed_t actionspd = player->actionspd; if (player->charflags & SF_DASHMODE) - actionspd = max(player->normalspeed, FixedDiv(player->speed, player->mo->scale)); + actionspd = max(player->actionspd, FixedDiv(player->speed, player->mo->scale)); if (player->mo->eflags & MFE_UNDERWATER) actionspd >>= 1; From f2095b57fd042dfbe58a1e696308d6b8c24083c3 Mon Sep 17 00:00:00 2001 From: Zippy_Zolton Date: Thu, 10 Dec 2020 20:37:50 -0600 Subject: [PATCH 142/644] Player-Colored Elemental Fire for competitive gametypes --- src/deh_tables.c | 7 +++++++ src/hardware/hw_light.c | 1 + src/info.c | 8 ++++++++ src/info.h | 8 ++++++++ src/p_user.c | 10 ++++++++++ 5 files changed, 34 insertions(+) diff --git a/src/deh_tables.c b/src/deh_tables.c index 7877903c5..67d876069 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -1522,6 +1522,13 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_SPINFIRE5", "S_SPINFIRE6", + "S_TEAM_SPINFIRE1", + "S_TEAM_SPINFIRE2", + "S_TEAM_SPINFIRE3", + "S_TEAM_SPINFIRE4", + "S_TEAM_SPINFIRE5", + "S_TEAM_SPINFIRE6", + // Spikes "S_SPIKE1", "S_SPIKE2", diff --git a/src/hardware/hw_light.c b/src/hardware/hw_light.c index 987d70c69..93c61f4e7 100644 --- a/src/hardware/hw_light.c +++ b/src/hardware/hw_light.c @@ -253,6 +253,7 @@ light_t *t_lspr[NUMSPRITES] = &lspr[NOLIGHT], // SPR_SIGN &lspr[NOLIGHT], // SPR_SPIK &lspr[NOLIGHT], // SPR_SFLM + &lspr[NOLIGHT], // SPR_TFLM &lspr[NOLIGHT], // SPR_USPK &lspr[NOLIGHT], // SPR_WSPK &lspr[NOLIGHT], // SPR_WSPB diff --git a/src/info.c b/src/info.c index 56e764b5d..3ae9aeeb4 100644 --- a/src/info.c +++ b/src/info.c @@ -150,6 +150,7 @@ char sprnames[NUMSPRITES + 1][5] = "SIGN", // Level end sign "SPIK", // Spike Ball "SFLM", // Spin fire + "TFLM", // Spin fire (team) "USPK", // Floor spike "WSPK", // Wall spike "WSPB", // Wall spike base @@ -1894,6 +1895,13 @@ state_t states[NUMSTATES] = {SPR_SFLM, FF_FULLBRIGHT|4, 2, {NULL}, 0, 0, S_SPINFIRE6}, // S_SPINFIRE5 {SPR_SFLM, FF_FULLBRIGHT|5, 2, {NULL}, 0, 0, S_SPINFIRE1}, // S_SPINFIRE6 + {SPR_TFLM, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_TEAM_SPINFIRE2}, // S_TEAM_SPINFIRE1 + {SPR_TFLM, FF_FULLBRIGHT|1, 2, {NULL}, 0, 0, S_TEAM_SPINFIRE3}, // S_TEAM_SPINFIRE2 + {SPR_TFLM, FF_FULLBRIGHT|2, 2, {NULL}, 0, 0, S_TEAM_SPINFIRE4}, // S_TEAM_SPINFIRE3 + {SPR_TFLM, FF_FULLBRIGHT|3, 2, {NULL}, 0, 0, S_TEAM_SPINFIRE5}, // S_TEAM_SPINFIRE4 + {SPR_TFLM, FF_FULLBRIGHT|4, 2, {NULL}, 0, 0, S_TEAM_SPINFIRE6}, // S_TEAM_SPINFIRE5 + {SPR_TFLM, FF_FULLBRIGHT|5, 2, {NULL}, 0, 0, S_TEAM_SPINFIRE1}, // S_TEAM_SPINFIRE6 + // Floor Spike {SPR_USPK, 0,-1, {A_SpikeRetract}, 1, 0, S_SPIKE2}, // S_SPIKE1 -- Fully extended {SPR_USPK, 1, 2, {A_Pain}, 0, 0, S_SPIKE3}, // S_SPIKE2 diff --git a/src/info.h b/src/info.h index 604922beb..461afd180 100644 --- a/src/info.h +++ b/src/info.h @@ -684,6 +684,7 @@ typedef enum sprite SPR_SIGN, // Level end sign SPR_SPIK, // Spike Ball SPR_SFLM, // Spin fire + SPR_TFLM, // Spin fire (team) SPR_USPK, // Floor spike SPR_WSPK, // Wall spike SPR_WSPB, // Wall spike base @@ -2324,6 +2325,13 @@ typedef enum state S_SPINFIRE5, S_SPINFIRE6, + S_TEAM_SPINFIRE1, + S_TEAM_SPINFIRE2, + S_TEAM_SPINFIRE3, + S_TEAM_SPINFIRE4, + S_TEAM_SPINFIRE5, + S_TEAM_SPINFIRE6, + // Spikes S_SPIKE1, S_SPIKE2, diff --git a/src/p_user.c b/src/p_user.c index 892f4b678..09d148f41 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -7756,6 +7756,11 @@ void P_ElementalFire(player_t *player, boolean cropcircle) flame->eflags = (flame->eflags & ~MFE_VERTICALFLIP)|(player->mo->eflags & MFE_VERTICALFLIP); P_InstaThrust(flame, flame->angle, FixedMul(3*FRACUNIT, flame->scale)); P_SetObjectMomZ(flame, 3*FRACUNIT, false); + if (!(gametyperules & GTR_FRIENDLY)) + { + P_SetMobjState(flame, S_TEAM_SPINFIRE1); + flame->color = player->mo->color; + } } #undef limitangle #undef numangles @@ -7783,6 +7788,11 @@ void P_ElementalFire(player_t *player, boolean cropcircle) flame->destscale = player->mo->scale; P_SetScale(flame, player->mo->scale); flame->eflags = (flame->eflags & ~MFE_VERTICALFLIP)|(player->mo->eflags & MFE_VERTICALFLIP); + if (!(gametyperules & GTR_FRIENDLY)) + { + P_SetMobjState(flame, S_TEAM_SPINFIRE1); + flame->color = player->mo->color; + } flame->momx = 8; // this is a hack which is used to ensure it still behaves as a missile and can damage others P_XYMovement(flame); From 68de9f4bbe132bd57fbf072bc3dc861dd9f3be81 Mon Sep 17 00:00:00 2001 From: Zippy_Zolton Date: Fri, 11 Dec 2020 12:34:30 -0600 Subject: [PATCH 143/644] Make Ring Drain sectors play the depletion sound instead of the ring sound --- src/p_spec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_spec.c b/src/p_spec.c index 5b9e05c61..8843824ce 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4304,7 +4304,7 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers if (leveltime % (TICRATE/2) == 0 && player->rings > 0) { player->rings--; - S_StartSound(player->mo, sfx_itemup); + S_StartSound(player->mo, sfx_antiri); } break; case 11: // Special Stage Damage From 029e79024ba33f5b9ebfb08bba2be328df64fe14 Mon Sep 17 00:00:00 2001 From: Zwip-Zwap Zapony Date: Fri, 11 Dec 2020 23:43:38 +0100 Subject: [PATCH 144/644] V_DrawCroppedPatch Lua exposure and improvements Separated X and Y scale, and added colormap argument Added V_*SCALEPATCH and V_PERPLAYER flags support Made sx,sy,w,h into fixed-point values Exposed to Lua as "v.drawCropped(...)" (Also fix HWR_DrawStretchyFixedPatch ignoring vscale without pscale) --- src/console.c | 4 +- src/hardware/hw_draw.c | 147 ++++++++++++++++++++++++++++++----------- src/hardware/hw_main.h | 2 +- src/lua_hudlib.c | 40 +++++++++++ src/m_menu.c | 2 +- src/v_video.c | 71 +++++++++++++------- src/v_video.h | 2 +- src/y_inter.c | 2 +- 8 files changed, 202 insertions(+), 68 deletions(-) diff --git a/src/console.c b/src/console.c index b19b8818d..bcf01c989 100644 --- a/src/console.c +++ b/src/console.c @@ -1736,8 +1736,8 @@ static void CON_DrawBackpic(void) } // Draw the patch. - V_DrawCroppedPatch(x << FRACBITS, 0, FRACUNIT, V_NOSCALESTART, con_backpic, - 0, ( BASEVIDHEIGHT - h ), BASEVIDWIDTH, h); + V_DrawCroppedPatch(x << FRACBITS, 0, FRACUNIT, FRACUNIT, V_NOSCALESTART, con_backpic, NULL, + 0, (BASEVIDHEIGHT - h) << FRACBITS, BASEVIDWIDTH << FRACBITS, h << FRACBITS); // Unlock the cached patch. W_UnlockCachedPatch(con_backpic); diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index c5d362520..0322e9d27 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -317,7 +317,7 @@ void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t p } } - if (pscale != FRACUNIT || (splitscreen && option & V_PERPLAYER)) + if (pscale != FRACUNIT || vscale != FRACUNIT || (splitscreen && option & V_PERPLAYER)) { fwidth = (float)(gpatch->width) * fscalew * dupx; fheight = (float)(gpatch->height) * fscaleh * dupy; @@ -382,7 +382,7 @@ void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t p HWD.pfnDrawPolygon(NULL, v, 4, flags); } -void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, INT32 option, fixed_t sx, fixed_t sy, fixed_t w, fixed_t h) +void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, INT32 option, const UINT8 *colormap, fixed_t sx, fixed_t sy, fixed_t w, fixed_t h) { FOutVector v[4]; FBITFIELD flags; @@ -395,13 +395,19 @@ void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, // | /| // |/ | // 0--1 - float dupx, dupy, fscale, fwidth, fheight; + float dupx, dupy, fscalew, fscaleh, fwidth, fheight; + + UINT8 perplayershuffle = 0; if (alphalevel >= 10 && alphalevel < 13) return; // make patch ready in hardware cache - HWR_GetPatch(gpatch); + if (!colormap) + HWR_GetPatch(gpatch); + else + HWR_GetMappedPatch(gpatch, colormap); + hwrPatch = ((GLPatch_t *)gpatch->hardware); dupx = (float)vid.dupx; @@ -423,12 +429,80 @@ void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, } dupx = dupy = (dupx < dupy ? dupx : dupy); - fscale = FIXED_TO_FLOAT(pscale); + fscalew = fscaleh = FIXED_TO_FLOAT(pscale); + if (vscale != pscale) + fscaleh = FIXED_TO_FLOAT(vscale); - // fuck it, no GL support for croppedpatch v_perplayer right now. it's not like it's accessible to Lua or anything, and we only use it for menus... + cx -= (float)(gpatch->leftoffset) * fscalew; + cy -= (float)(gpatch->topoffset) * fscaleh; - cy -= (float)(gpatch->topoffset) * fscale; - cx -= (float)(gpatch->leftoffset) * fscale; + if (splitscreen && (option & V_PERPLAYER)) + { + float adjusty = ((option & V_NOSCALESTART) ? vid.height : BASEVIDHEIGHT)/2.0f; + fscaleh /= 2; + cy /= 2; +#ifdef QUADS + if (splitscreen > 1) // 3 or 4 players + { + float adjustx = ((option & V_NOSCALESTART) ? vid.width : BASEVIDWIDTH)/2.0f; + fscalew /= 2; + cx /= 2; + if (stplyr == &players[displayplayer]) + { + if (!(option & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 1; + if (!(option & (V_SNAPTOLEFT|V_SNAPTORIGHT))) + perplayershuffle |= 4; + option &= ~V_SNAPTOBOTTOM|V_SNAPTORIGHT; + } + else if (stplyr == &players[secondarydisplayplayer]) + { + if (!(option & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 1; + if (!(option & (V_SNAPTOLEFT|V_SNAPTORIGHT))) + perplayershuffle |= 8; + cx += adjustx; + option &= ~V_SNAPTOBOTTOM|V_SNAPTOLEFT; + } + else if (stplyr == &players[thirddisplayplayer]) + { + if (!(option & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 2; + if (!(option & (V_SNAPTOLEFT|V_SNAPTORIGHT))) + perplayershuffle |= 4; + cy += adjusty; + option &= ~V_SNAPTOTOP|V_SNAPTORIGHT; + } + else if (stplyr == &players[fourthdisplayplayer]) + { + if (!(option & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle |= 2; + if (!(option & (V_SNAPTOLEFT|V_SNAPTORIGHT))) + perplayershuffle |= 8; + cx += adjustx; + cy += adjusty; + option &= ~V_SNAPTOTOP|V_SNAPTOLEFT; + } + } + else +#endif + // 2 players + { + if (stplyr == &players[displayplayer]) + { + if (!(option & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle = 1; + option &= ~V_SNAPTOBOTTOM; + } + else //if (stplyr == &players[secondarydisplayplayer]) + { + if (!(option & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) + perplayershuffle = 2; + cy += adjusty; + option &= ~V_SNAPTOTOP; + } + } + } if (!(option & V_NOSCALESTART)) { @@ -437,18 +511,9 @@ void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, if (!(option & V_SCALEPATCHMASK)) { - // if it's meant to cover the whole screen, black out the rest (ONLY IF TOP LEFT ISN'T TRANSPARENT) - // cx and cy are possibly *slightly* off from float maths - // This is done before here compared to software because we directly alter cx and cy to centre - if (cx >= -0.1f && cx <= 0.1f && gpatch->width == BASEVIDWIDTH && cy >= -0.1f && cy <= 0.1f && gpatch->height == BASEVIDHEIGHT) - { - const column_t *column = (const column_t *)((const UINT8 *)(gpatch->columns) + (gpatch->columnofs[0])); - if (!column->topdelta) - { - const UINT8 *source = (const UINT8 *)(column) + 3; - HWR_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0])); - } - } + // if it's meant to cover the whole screen, black out the rest + // no the patch is cropped do not do this ever + // centre screen if (fabsf((float)vid.width - (float)BASEVIDWIDTH * dupx) > 1.0E-36f) { @@ -456,6 +521,10 @@ void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)); else if (!(option & V_SNAPTOLEFT)) cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx))/2; + if (perplayershuffle & 4) + cx -= ((float)vid.width - ((float)BASEVIDWIDTH * dupx))/4; + else if (perplayershuffle & 8) + cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx))/4; } if (fabsf((float)vid.height - (float)BASEVIDHEIGHT * dupy) > 1.0E-36f) { @@ -463,23 +532,27 @@ void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)); else if (!(option & V_SNAPTOTOP)) cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy))/2; + if (perplayershuffle & 1) + cy -= ((float)vid.height - ((float)BASEVIDHEIGHT * dupy))/4; + else if (perplayershuffle & 2) + cy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy))/4; } } } - fwidth = w; - fheight = h; + fwidth = FIXED_TO_FLOAT(w); + fheight = FIXED_TO_FLOAT(h); - if (fwidth > gpatch->width) - fwidth = gpatch->width; + if (sx + w > gpatch->width<width< gpatch->height) - fheight = gpatch->height; + if (sy + h > gpatch->height<height<width))*hwrPatch->max_s; - if (sx + w > gpatch->width) - v[2].s = v[1].s = hwrPatch->max_s - ((sx+w)/(float)(gpatch->width))*hwrPatch->max_s; + v[0].s = v[3].s = (FIXED_TO_FLOAT(sx)/(float)(gpatch->width))*hwrPatch->max_s; + if (sx + w > gpatch->width<max_s; else - v[2].s = v[1].s = ((sx+w)/(float)(gpatch->width))*hwrPatch->max_s; + v[2].s = v[1].s = (FIXED_TO_FLOAT(sx+w)/(float)(gpatch->width))*hwrPatch->max_s; - v[0].t = v[1].t = ((sy)/(float)(gpatch->height))*hwrPatch->max_t; - if (sy + h > gpatch->height) - v[2].t = v[3].t = hwrPatch->max_t - ((sy+h)/(float)(gpatch->height))*hwrPatch->max_t; + v[0].t = v[1].t = (FIXED_TO_FLOAT(sy)/(float)(gpatch->height))*hwrPatch->max_t; + if (sy + h > gpatch->height<max_t; else - v[2].t = v[3].t = ((sy+h)/(float)(gpatch->height))*hwrPatch->max_t; + v[2].t = v[3].t = (FIXED_TO_FLOAT(sy+h)/(float)(gpatch->height))*hwrPatch->max_t; flags = PF_Translucent|PF_NoDepthTest; diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index 4ad09aa3d..708227585 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -39,7 +39,7 @@ void HWR_InitTextureMapping(void); void HWR_SetViewSize(void); void HWR_DrawPatch(patch_t *gpatch, INT32 x, INT32 y, INT32 option); void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, INT32 option, const UINT8 *colormap); -void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t scale, INT32 option, fixed_t sx, fixed_t sy, fixed_t w, fixed_t h); +void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, INT32 option, const UINT8 *colormap, fixed_t sx, fixed_t sy, fixed_t w, fixed_t h); void HWR_MakePatch(const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipmap, boolean makebitmap); void HWR_CreatePlanePolygons(INT32 bspnum); void HWR_CreateStaticLightmaps(INT32 bspnum); diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index e58cd4a58..20eb33f37 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -660,6 +660,45 @@ static int libd_drawStretched(lua_State *L) return 0; } +static int libd_drawCropped(lua_State *L) +{ + fixed_t x, y, hscale, vscale, sx, sy, w, h; + INT32 flags; + patch_t *patch; + const UINT8 *colormap = NULL; + + HUDONLY + x = luaL_checkinteger(L, 1); + y = luaL_checkinteger(L, 2); + hscale = luaL_checkinteger(L, 3); + if (hscale < 0) + return luaL_error(L, "negative horizontal scale"); + vscale = luaL_checkinteger(L, 4); + if (vscale < 0) + return luaL_error(L, "negative vertical scale"); + patch = *((patch_t **)luaL_checkudata(L, 5, META_PATCH)); + flags = luaL_checkinteger(L, 6); + if (!lua_isnoneornil(L, 7)) + colormap = *((UINT8 **)luaL_checkudata(L, 7, META_COLORMAP)); + sx = luaL_checkinteger(L, 8); + if (sx < 0) // Don't crash. Now, we could do "x-=sx*FRACUNIT; sx=0;" here... + return luaL_error(L, "negative crop sx"); + sy = luaL_checkinteger(L, 9); + if (sy < 0) // ...but it's more truthful to just deny it, as negative values would crash + return luaL_error(L, "negative crop sy"); + w = luaL_checkinteger(L, 10); + if (w < 0) // Again, don't crash + return luaL_error(L, "negative crop w"); + h = luaL_checkinteger(L, 11); + if (h < 0) + return luaL_error(L, "negative crop h"); + + flags &= ~V_PARAMMASK; // Don't let crashes happen. + + V_DrawCroppedPatch(x, y, hscale, vscale, flags, patch, colormap, sx, sy, w, h); + return 0; +} + static int libd_drawNum(lua_State *L) { INT32 x, y, flags, num; @@ -1084,6 +1123,7 @@ static luaL_Reg lib_draw[] = { {"draw", libd_draw}, {"drawScaled", libd_drawScaled}, {"drawStretched", libd_drawStretched}, + {"drawCropped", libd_drawCropped}, {"drawNum", libd_drawNum}, {"drawPaddedNum", libd_drawPaddedNum}, {"drawFill", libd_drawFill}, diff --git a/src/m_menu.c b/src/m_menu.c index 5ec9132f7..003e308b0 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4183,7 +4183,7 @@ static void M_DrawStaticBox(fixed_t x, fixed_t y, INT32 flags, fixed_t w, fixed_ if (staticalong > pw) // simplified for base LSSTATIC staticalong -= pw; - V_DrawCroppedPatch(x<> V_SCALEPATCHSHIFT) + { + case 1: // V_NOSCALEPATCH + dupx = dupy = 1; + break; + case 2: // V_SMALLSCALEPATCH + dupx = vid.smalldupx; + dupy = vid.smalldupy; + break; + case 3: // V_MEDSCALEPATCH + dupx = vid.meddupx; + dupy = vid.meddupy; + break; + default: + break; + } + + // only use one dup, to avoid stretching (har har) + dupx = dupy = (dupx < dupy ? dupx : dupy); + fdup = vdup = FixedMul(dupx<topoffset<leftoffset<topoffset<>= 1; + vdup >>= 1; rowfrac <<= 1; y >>= 1; - sy >>= 1; - h >>= 1; #ifdef QUADS if (splitscreen > 1) // 3 or 4 players { fixed_t adjustx = ((scrn & V_NOSCALESTART) ? vid.height : BASEVIDHEIGHT)<<(FRACBITS-1)); + fdup >>= 1; colfrac <<= 1; x >>= 1; - sx >>= 1; - w >>= 1; if (stplyr == &players[displayplayer]) { if (!(scrn & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) @@ -896,7 +921,6 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_ if (!(scrn & (V_SNAPTOLEFT|V_SNAPTORIGHT))) perplayershuffle |= 8; x += adjustx; - sx += adjustx; scrn &= ~V_SNAPTOBOTTOM|V_SNAPTOLEFT; } else if (stplyr == &players[thirddisplayplayer]) @@ -906,7 +930,6 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_ if (!(scrn & (V_SNAPTOLEFT|V_SNAPTORIGHT))) perplayershuffle |= 4; y += adjusty; - sy += adjusty; scrn &= ~V_SNAPTOTOP|V_SNAPTORIGHT; } else //if (stplyr == &players[fourthdisplayplayer]) @@ -916,9 +939,7 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_ if (!(scrn & (V_SNAPTOLEFT|V_SNAPTORIGHT))) perplayershuffle |= 8; x += adjustx; - sx += adjustx; y += adjusty; - sy += adjusty; scrn &= ~V_SNAPTOTOP|V_SNAPTOLEFT; } } @@ -937,7 +958,6 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_ if (!(scrn & (V_SNAPTOTOP|V_SNAPTOBOTTOM))) perplayershuffle |= 2; y += adjusty; - sy += adjusty; scrn &= ~V_SNAPTOTOP; } } @@ -950,7 +970,8 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_ deststop = desttop + vid.rowbytes * vid.height; - if (scrn & V_NOSCALESTART) { + if (scrn & V_NOSCALESTART) + { x >>= FRACBITS; y >>= FRACBITS; desttop += (y*vid.width) + x; @@ -998,7 +1019,7 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_ desttop += (y*vid.width) + x; } - for (col = sx<>FRACBITS) < patch->width && ((col>>FRACBITS) - sx) < w; col += colfrac, ++x, desttop++) + for (col = sx; (col>>FRACBITS) < patch->width && (col - sx) < w; col += colfrac, ++x, desttop++) { INT32 topdelta, prevdelta = -1; if (x < 0) // don't draw off the left of the screen (WRAP PREVENTION) @@ -1015,15 +1036,15 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_ prevdelta = topdelta; source = (const UINT8 *)(column) + 3; dest = desttop; - if (topdelta-sy > 0) + if ((topdelta< 0) { - dest += FixedInt(FixedMul((topdelta-sy)<>FRACBITS) < column->length && (((ofs>>FRACBITS) - sy) + topdelta) < h; ofs += rowfrac) + for (; dest < deststop && (ofs>>FRACBITS) < column->length && ((ofs - sy) + (topdelta<= screens[scrn&V_PARAMMASK]) // don't draw off the top of the screen (CRASH PREVENTION) *dest = patchdrawfunc(dest, source, ofs); diff --git a/src/v_video.h b/src/v_video.h index 8a18f82ad..f3f169079 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -165,7 +165,7 @@ void V_CubeApply(UINT8 *red, UINT8 *green, UINT8 *blue); #define V_DrawSciencePatch(x,y,s,p,sc) V_DrawFixedPatch(x,y,sc,s,p,NULL) #define V_DrawFixedPatch(x,y,sc,s,p,c) V_DrawStretchyFixedPatch(x,y,sc,sc,s,p,c) void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, INT32 scrn, patch_t *patch, const UINT8 *colormap); -void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t *patch, fixed_t sx, fixed_t sy, fixed_t w, fixed_t h); +void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, INT32 scrn, patch_t *patch, const UINT8 *colormap, fixed_t sx, fixed_t sy, fixed_t w, fixed_t h); void V_DrawContinueIcon(INT32 x, INT32 y, INT32 flags, INT32 skinnum, UINT16 skincolor); diff --git a/src/y_inter.c b/src/y_inter.c index 061cbb5e1..f2f676919 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -212,7 +212,7 @@ static void Y_IntermissionTokenDrawer(void) calc = (lowy - y)*2; if (calc > 0) - V_DrawCroppedPatch(32<width, calc); + V_DrawCroppedPatch(32<width< Date: Fri, 11 Dec 2020 20:59:14 -0500 Subject: [PATCH 145/644] make fire spindust dust fullbright --- src/info.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/info.c b/src/info.c index 29a79b1d6..8684c68f5 100644 --- a/src/info.c +++ b/src/info.c @@ -3299,10 +3299,10 @@ state_t states[NUMSTATES] = {SPR_BUBL, 0, 6, {NULL}, 0, 0, S_SPINDUST_BUBBLE3}, // S_SPINDUST_BUBBLE2 {SPR_BUBL, FF_TRANS30|0, 4, {NULL}, 0, 0, S_SPINDUST_BUBBLE4}, // S_SPINDUST_BUBBLE3 {SPR_BUBL, FF_TRANS60|0, 3, {NULL}, 0, 0, S_NULL}, // S_SPINDUST_BUBBLE4 - {SPR_FPRT, 0, 7, {NULL}, 0, 0, S_SPINDUST_FIRE2}, // S_SPINDUST_FIRE1 - {SPR_FPRT, 0, 6, {NULL}, 0, 0, S_SPINDUST_FIRE3}, // S_SPINDUST_FIRE2 - {SPR_FPRT, FF_TRANS30|0, 4, {NULL}, 0, 0, S_SPINDUST_FIRE4}, // S_SPINDUST_FIRE3 - {SPR_FPRT, FF_TRANS60|0, 3, {NULL}, 0, 0, S_NULL}, // S_SPINDUST_FIRE4 + {SPR_FPRT, FF_FULLBRIGHT|0, 7, {NULL}, 0, 0, S_SPINDUST_FIRE2}, // S_SPINDUST_FIRE1 + {SPR_FPRT, FF_FULLBRIGHT|0, 6, {NULL}, 0, 0, S_SPINDUST_FIRE3}, // S_SPINDUST_FIRE2 + {SPR_FPRT, FF_FULLBRIGHT|FF_TRANS30|0, 4, {NULL}, 0, 0, S_SPINDUST_FIRE4}, // S_SPINDUST_FIRE3 + {SPR_FPRT, FF_FULLBRIGHT|FF_TRANS60|0, 3, {NULL}, 0, 0, S_NULL}, // S_SPINDUST_FIRE4 {SPR_TFOG, FF_FULLBRIGHT|FF_TRANS50, 2, {NULL}, 0, 0, S_FOG2}, // S_FOG1 From ab156e17091479257fd6fc6287c7973a73d7329b Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Fri, 11 Dec 2020 23:11:15 -0500 Subject: [PATCH 146/644] Remove music slot compatibility --- src/deh_lua.c | 27 ------------- src/deh_soc.c | 100 ---------------------------------------------- src/deh_soc.h | 5 +-- src/doomdef.h | 4 -- src/lua_baselib.c | 67 +------------------------------ src/s_sound.c | 39 ++---------------- src/s_sound.h | 6 --- 7 files changed, 5 insertions(+), 243 deletions(-) diff --git a/src/deh_lua.c b/src/deh_lua.c index e6a436421..51632079b 100644 --- a/src/deh_lua.c +++ b/src/deh_lua.c @@ -25,10 +25,6 @@ #include "deh_lua.h" #include "deh_tables.h" -#ifdef MUSICSLOT_COMPATIBILITY -#include "deh_soc.h" // for get_mus -#endif - // freeslot takes a name (string only!) // and allocates it to the appropriate free slot. // Returns the slot number allocated for it or nil if failed. @@ -430,29 +426,6 @@ static inline int lib_getenum(lua_State *L) if (mathlib) return luaL_error(L, "sfx '%s' could not be found.\n", word); return 0; } -#ifdef MUSICSLOT_COMPATIBILITY - else if (!mathlib && fastncmp("mus_",word,4)) { - p = word+4; - if ((i = get_mus(p, false)) == 0) - return 0; - lua_pushinteger(L, i); - return 1; - } - else if (mathlib && fastncmp("MUS_",word,4)) { // SOCs are ALL CAPS! - p = word+4; - if ((i = get_mus(p, false)) == 0) - return luaL_error(L, "music '%s' could not be found.\n", word); - lua_pushinteger(L, i); - return 1; - } - else if (mathlib && (fastncmp("O_",word,2) || fastncmp("D_",word,2))) { - p = word+2; - if ((i = get_mus(p, false)) == 0) - return luaL_error(L, "music '%s' could not be found.\n", word); - lua_pushinteger(L, i); - return 1; - } -#endif else if (!mathlib && fastncmp("pw_",word,3)) { p = word+3; for (i = 0; i < NUMPOWERS; i++) diff --git a/src/deh_soc.c b/src/deh_soc.c index 5b12ea1b0..2cd872378 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -1574,19 +1574,6 @@ void readlevelheader(MYFILE *f, INT32 num) sizeof(mapheaderinfo[num-1]->musname), va("Level header %d: music", num)); } } -#ifdef MUSICSLOT_COMPATIBILITY - else if (fastcmp(word, "MUSICSLOT")) - { - i = get_mus(word2, true); - if (i && i <= 1035) - snprintf(mapheaderinfo[num-1]->musname, 7, "%sM", G_BuildMapName(i)); - else if (i && i <= 1050) - strncpy(mapheaderinfo[num-1]->musname, compat_special_music_slots[i - 1036], 7); - else - mapheaderinfo[num-1]->musname[0] = 0; // becomes empty string - mapheaderinfo[num-1]->musname[6] = 0; - } -#endif else if (fastcmp(word, "MUSICTRACK")) mapheaderinfo[num-1]->mustrack = ((UINT16)i - 1); else if (fastcmp(word, "MUSICPOS")) @@ -1964,19 +1951,6 @@ static void readcutscenescene(MYFILE *f, INT32 num, INT32 scenenum) strncpy(cutscenes[num]->scene[scenenum].musswitch, word2, 7); cutscenes[num]->scene[scenenum].musswitch[6] = 0; } -#ifdef MUSICSLOT_COMPATIBILITY - else if (fastcmp(word, "MUSICSLOT")) - { - i = get_mus(word2, true); - if (i && i <= 1035) - snprintf(cutscenes[num]->scene[scenenum].musswitch, 7, "%sM", G_BuildMapName(i)); - else if (i && i <= 1050) - strncpy(cutscenes[num]->scene[scenenum].musswitch, compat_special_music_slots[i - 1036], 7); - else - cutscenes[num]->scene[scenenum].musswitch[0] = 0; // becomes empty string - cutscenes[num]->scene[scenenum].musswitch[6] = 0; - } -#endif else if (fastcmp(word, "MUSICTRACK")) { cutscenes[num]->scene[scenenum].musswitchflags = ((UINT16)i) & MUSIC_TRACKMASK; @@ -2239,19 +2213,6 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum) strncpy(textprompts[num]->page[pagenum].musswitch, word2, 7); textprompts[num]->page[pagenum].musswitch[6] = 0; } -#ifdef MUSICSLOT_COMPATIBILITY - else if (fastcmp(word, "MUSICSLOT")) - { - i = get_mus(word2, true); - if (i && i <= 1035) - snprintf(textprompts[num]->page[pagenum].musswitch, 7, "%sM", G_BuildMapName(i)); - else if (i && i <= 1050) - strncpy(textprompts[num]->page[pagenum].musswitch, compat_special_music_slots[i - 1036], 7); - else - textprompts[num]->page[pagenum].musswitch[0] = 0; // becomes empty string - textprompts[num]->page[pagenum].musswitch[6] = 0; - } -#endif else if (fastcmp(word, "MUSICTRACK")) { textprompts[num]->page[pagenum].musswitchflags = ((UINT16)i) & MUSIC_TRACKMASK; @@ -2577,20 +2538,6 @@ void readmenu(MYFILE *f, INT32 num) menupres[num].musname[6] = 0; titlechanged = true; } -#ifdef MUSICSLOT_COMPATIBILITY - else if (fastcmp(word, "MUSICSLOT")) - { - value = get_mus(word2, true); - if (value && value <= 1035) - snprintf(menupres[num].musname, 7, "%sM", G_BuildMapName(value)); - else if (value && value <= 1050) - strncpy(menupres[num].musname, compat_special_music_slots[value - 1036], 7); - else - menupres[num].musname[0] = 0; // becomes empty string - menupres[num].musname[6] = 0; - titlechanged = true; - } -#endif else if (fastcmp(word, "MUSICTRACK")) { menupres[num].mustrack = ((UINT16)value - 1); @@ -4178,46 +4125,6 @@ sfxenum_t get_sfx(const char *word) return sfx_None; } -#ifdef MUSICSLOT_COMPATIBILITY -UINT16 get_mus(const char *word, UINT8 dehacked_mode) -{ // Returns the value of MUS_ enumerations - UINT16 i; - char lumptmp[4]; - - if (*word >= '0' && *word <= '9') - return atoi(word); - if (!word[2] && toupper(word[0]) >= 'A' && toupper(word[0]) <= 'Z') - return (UINT16)M_MapNumber(word[0], word[1]); - - if (fastncmp("MUS_",word,4)) - word += 4; // take off the MUS_ - else if (fastncmp("O_",word,2) || fastncmp("D_",word,2)) - word += 2; // take off the O_ or D_ - - strncpy(lumptmp, word, 4); - lumptmp[3] = 0; - if (fasticmp("MAP",lumptmp)) - { - word += 3; - if (toupper(word[0]) >= 'A' && toupper(word[0]) <= 'Z') - return (UINT16)M_MapNumber(word[0], word[1]); - else if ((i = atoi(word))) - return i; - - word -= 3; - if (dehacked_mode) - deh_warning("Couldn't find music named 'MUS_%s'",word); - return 0; - } - for (i = 0; compat_special_music_slots[i][0]; ++i) - if (fasticmp(word, compat_special_music_slots[i])) - return i + 1036; - if (dehacked_mode) - deh_warning("Couldn't find music named 'MUS_%s'",word); - return 0; -} -#endif - hudnum_t get_huditem(const char *word) { // Returns the value of HUD_ enumerations hudnum_t i; @@ -4448,13 +4355,6 @@ static fixed_t find_const(const char **rword) free(word); return r; } -#ifdef MUSICSLOT_COMPATIBILITY - else if (fastncmp("MUS_",word,4) || fastncmp("O_",word,2)) { - r = get_mus(word, true); - free(word); - return r; - } -#endif else if (fastncmp("PW_",word,3)) { r = get_power(word); free(word); diff --git a/src/deh_soc.h b/src/deh_soc.h index 2bcb52e70..0082e0e70 100644 --- a/src/deh_soc.h +++ b/src/deh_soc.h @@ -43,7 +43,7 @@ #include "info.h" #include "dehacked.h" -#include "doomdef.h" // MUSICSLOT_COMPATIBILITY, HWRENDER +#include "doomdef.h" // HWRENDER // Crazy word-reading stuff /// \todo Put these in a seperate file or something. @@ -52,9 +52,6 @@ statenum_t get_state(const char *word); spritenum_t get_sprite(const char *word); playersprite_t get_sprite2(const char *word); sfxenum_t get_sfx(const char *word); -#ifdef MUSICSLOT_COMPATIBILITY -UINT16 get_mus(const char *word, UINT8 dehacked_mode); -#endif hudnum_t get_huditem(const char *word); menutype_t get_menutype(const char *word); //INT16 get_gametype(const char *word); diff --git a/src/doomdef.h b/src/doomdef.h index d0b7ea0c2..3958d85d0 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -607,10 +607,6 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; /// Experimental tweaks to analog mode. (Needs a lot of work before it's ready for primetime.) //#define REDSANALOG -/// Backwards compatibility with musicslots. -/// \note You should leave this enabled unless you're working with a future SRB2 version. -#define MUSICSLOT_COMPATIBILITY - /// Experimental attempts at preventing MF_PAPERCOLLISION objects from getting stuck in walls. //#define PAPER_COLLISIONCORRECTION diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 515f6f0ba..3836fffb8 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -2803,46 +2803,13 @@ static int lib_sStopSoundByID(lua_State *L) static int lib_sChangeMusic(lua_State *L) { -#ifdef MUSICSLOT_COMPATIBILITY - const char *music_name; - UINT32 music_num, position, prefadems, fadeinms; - char music_compat_name[7]; + UINT32 position, prefadems, fadeinms; - boolean looping; - player_t *player = NULL; - UINT16 music_flags = 0; - //NOHUD - - if (lua_isnumber(L, 1)) - { - music_num = (UINT32)luaL_checkinteger(L, 1); - music_flags = (UINT16)(music_num & 0x0000FFFF); - if (music_flags && music_flags <= 1035) - snprintf(music_compat_name, 7, "%sM", G_BuildMapName((INT32)music_flags)); - else if (music_flags && music_flags <= 1050) - strncpy(music_compat_name, compat_special_music_slots[music_flags - 1036], 7); - else - music_compat_name[0] = 0; // becomes empty string - music_compat_name[6] = 0; - music_name = (const char *)&music_compat_name; - music_flags = 0; - } - else - { - music_num = 0; - music_name = luaL_checkstring(L, 1); - } - - looping = (boolean)lua_opttrueboolean(L, 2); - -#else const char *music_name = luaL_checkstring(L, 1); boolean looping = (boolean)lua_opttrueboolean(L, 2); player_t *player = NULL; UINT16 music_flags = 0; - //NOHUD -#endif if (!lua_isnone(L, 3) && lua_isuserdata(L, 3)) { player = *((player_t **)luaL_checkudata(L, 3, META_PLAYER)); @@ -2850,13 +2817,7 @@ static int lib_sChangeMusic(lua_State *L) return LUA_ErrInvalid(L, "player_t"); } -#ifdef MUSICSLOT_COMPATIBILITY - if (music_num) - music_flags = (UINT16)((music_num & 0x7FFF0000) >> 16); - else -#endif music_flags = (UINT16)luaL_optinteger(L, 4, 0); - position = (UINT32)luaL_optinteger(L, 5, 0); prefadems = (UINT32)luaL_optinteger(L, 6, 0); fadeinms = (UINT32)luaL_optinteger(L, 7, 0); @@ -3153,33 +3114,7 @@ static int lib_sMusicExists(lua_State *L) { boolean checkMIDI = lua_opttrueboolean(L, 2); boolean checkDigi = lua_opttrueboolean(L, 3); -#ifdef MUSICSLOT_COMPATIBILITY - const char *music_name; - UINT32 music_num; - char music_compat_name[7]; - UINT16 music_flags = 0; - NOHUD - if (lua_isnumber(L, 1)) - { - music_num = (UINT32)luaL_checkinteger(L, 1); - music_flags = (UINT16)(music_num & 0x0000FFFF); - if (music_flags && music_flags <= 1035) - snprintf(music_compat_name, 7, "%sM", G_BuildMapName((INT32)music_flags)); - else if (music_flags && music_flags <= 1050) - strncpy(music_compat_name, compat_special_music_slots[music_flags - 1036], 7); - else - music_compat_name[0] = 0; // becomes empty string - music_compat_name[6] = 0; - music_name = (const char *)&music_compat_name; - } - else - { - music_num = 0; - music_name = luaL_checkstring(L, 1); - } -#else const char *music_name = luaL_checkstring(L, 1); -#endif NOHUD lua_pushboolean(L, S_MusicExists(music_name, checkMIDI, checkDigi)); return 1; diff --git a/src/s_sound.c b/src/s_sound.c index 36bd454c1..ecce7e9c4 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -1354,28 +1354,6 @@ void S_InitSfxChannels(INT32 sfxVolume) /// Music /// ------------------------ -#ifdef MUSICSLOT_COMPATIBILITY -const char *compat_special_music_slots[16] = -{ - "_title", // 1036 title screen - "_intro", // 1037 intro - "_clear", // 1038 level clear - "_inv", // 1039 invincibility - "_shoes", // 1040 super sneakers - "_minv", // 1041 Mario invincibility - "_drown", // 1042 drowning - "_gover", // 1043 game over - "_1up", // 1044 extra life - "_conti", // 1045 continue screen - "_super", // 1046 Super Sonic - "_chsel", // 1047 character select - "_creds", // 1048 credits - "_inter", // 1049 Race Results - "_stjr", // 1050 Sonic Team Jr. Presents - "" -}; -#endif - static char music_name[7]; // up to 6-character name static void *music_data; static UINT16 music_flags; @@ -2465,7 +2443,7 @@ void S_StartEx(boolean reset) static void Command_Tunes_f(void) { const char *tunearg; - UINT16 tunenum, track = 0; + UINT16 track = 0; UINT32 position = 0; const size_t argc = COM_Argc(); @@ -2481,7 +2459,6 @@ static void Command_Tunes_f(void) } tunearg = COM_Argv(1); - tunenum = (UINT16)atoi(tunearg); track = 0; if (!strcasecmp(tunearg, "-show")) @@ -2500,24 +2477,14 @@ static void Command_Tunes_f(void) tunearg = mapheaderinfo[gamemap-1]->musname; track = mapheaderinfo[gamemap-1]->mustrack; } - else if (!tunearg[2] && toupper(tunearg[0]) >= 'A' && toupper(tunearg[0]) <= 'Z') - tunenum = (UINT16)M_MapNumber(tunearg[0], tunearg[1]); - if (tunenum && tunenum >= 1036) - { - 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 + if (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")); if (argc > 2) track = (UINT16)atoi(COM_Argv(2))-1; - if (tunenum) - snprintf(mapmusname, 7, "%sM", G_BuildMapName(tunenum)); - else - strncpy(mapmusname, tunearg, 7); + strncpy(mapmusname, tunearg, 7); if (argc > 4) position = (UINT32)atoi(COM_Argv(4)); diff --git a/src/s_sound.h b/src/s_sound.h index 4ac3c70bf..ab2c411c0 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -319,10 +319,4 @@ void S_StopSoundByNum(sfxenum_t sfxnum); #define S_StartScreamSound S_StartSound #endif -#ifdef MUSICSLOT_COMPATIBILITY -// For compatibility with code/scripts relying on older versions -// This is a list of all the "special" slot names and their associated numbers -extern const char *compat_special_music_slots[16]; -#endif - #endif From 2971156ba7c4699979218a4a8470d93d8faf63aa Mon Sep 17 00:00:00 2001 From: katsy Date: Fri, 11 Dec 2020 23:39:42 -0500 Subject: [PATCH 147/644] Update info.c --- src/info.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/info.c b/src/info.c index 8684c68f5..192e592af 100644 --- a/src/info.c +++ b/src/info.c @@ -3291,16 +3291,16 @@ state_t states[NUMSTATES] = {SPR_WZAP, FF_TRANS10|FF_ANIMATE|FF_RANDOMANIM, 4, {NULL}, 3, 2, S_NULL}, // S_WATERZAP // Spindash dust - {SPR_DUST, 0, 7, {NULL}, 0, 0, S_SPINDUST2}, // S_SPINDUST1 - {SPR_DUST, 1, 6, {NULL}, 0, 0, S_SPINDUST3}, // S_SPINDUST2 - {SPR_DUST, FF_TRANS30|2, 4, {NULL}, 0, 0, S_SPINDUST4}, // S_SPINDUST3 - {SPR_DUST, FF_TRANS60|3, 3, {NULL}, 0, 0, S_NULL}, // S_SPINDUST4 - {SPR_BUBL, 0, 7, {NULL}, 0, 0, S_SPINDUST_BUBBLE2}, // S_SPINDUST_BUBBLE1 - {SPR_BUBL, 0, 6, {NULL}, 0, 0, S_SPINDUST_BUBBLE3}, // S_SPINDUST_BUBBLE2 - {SPR_BUBL, FF_TRANS30|0, 4, {NULL}, 0, 0, S_SPINDUST_BUBBLE4}, // S_SPINDUST_BUBBLE3 - {SPR_BUBL, FF_TRANS60|0, 3, {NULL}, 0, 0, S_NULL}, // S_SPINDUST_BUBBLE4 - {SPR_FPRT, FF_FULLBRIGHT|0, 7, {NULL}, 0, 0, S_SPINDUST_FIRE2}, // S_SPINDUST_FIRE1 - {SPR_FPRT, FF_FULLBRIGHT|0, 6, {NULL}, 0, 0, S_SPINDUST_FIRE3}, // S_SPINDUST_FIRE2 + {SPR_DUST, 0, 7, {NULL}, 0, 0, S_SPINDUST2}, // S_SPINDUST1 + {SPR_DUST, 1, 6, {NULL}, 0, 0, S_SPINDUST3}, // S_SPINDUST2 + {SPR_DUST, FF_TRANS30|2, 4, {NULL}, 0, 0, S_SPINDUST4}, // S_SPINDUST3 + {SPR_DUST, FF_TRANS60|3, 3, {NULL}, 0, 0, S_NULL}, // S_SPINDUST4 + {SPR_BUBL, 0, 7, {NULL}, 0, 0, S_SPINDUST_BUBBLE2}, // S_SPINDUST_BUBBLE1 + {SPR_BUBL, 0, 6, {NULL}, 0, 0, S_SPINDUST_BUBBLE3}, // S_SPINDUST_BUBBLE2 + {SPR_BUBL, FF_TRANS30|0, 4, {NULL}, 0, 0, S_SPINDUST_BUBBLE4}, // S_SPINDUST_BUBBLE3 + {SPR_BUBL, FF_TRANS60|0, 3, {NULL}, 0, 0, S_NULL}, // S_SPINDUST_BUBBLE4 + {SPR_FPRT, FF_FULLBRIGHT|0, 7, {NULL}, 0, 0, S_SPINDUST_FIRE2}, // S_SPINDUST_FIRE1 + {SPR_FPRT, FF_FULLBRIGHT|0, 6, {NULL}, 0, 0, S_SPINDUST_FIRE3}, // S_SPINDUST_FIRE2 {SPR_FPRT, FF_FULLBRIGHT|FF_TRANS30|0, 4, {NULL}, 0, 0, S_SPINDUST_FIRE4}, // S_SPINDUST_FIRE3 {SPR_FPRT, FF_FULLBRIGHT|FF_TRANS60|0, 3, {NULL}, 0, 0, S_NULL}, // S_SPINDUST_FIRE4 From 9ddeb5f5896de0407b2b6fce8c949295a9e6d5e4 Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 12 Dec 2020 02:05:21 -0800 Subject: [PATCH 148/644] Resolve GameQuit hook conflicts --- src/d_clisrv.c | 6 +++--- src/d_netcmd.c | 4 ++-- src/lua_hook.h | 1 + src/lua_hooklib.c | 10 ++++++++++ src/m_menu.c | 4 ++-- src/sdl/i_video.c | 2 +- 6 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 8ecafcc1b..9a24546ea 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -3032,7 +3032,7 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum) if (pnum == consoleplayer) { - LUAh_GameQuit(false); + LUA_HookBool(false, Hook(GameQuit)); #ifdef DUMPCONSISTENCY if (msg == KICK_MSG_CON_FAIL) SV_SavedGame(); #endif @@ -3732,7 +3732,7 @@ static void HandleConnect(SINT8 node) static void HandleShutdown(SINT8 node) { (void)node; - LUAh_GameQuit(false); + LUA_HookBool(false, Hook(GameQuit)); D_QuitNetGame(); CL_Reset(); D_StartTitle(); @@ -3747,7 +3747,7 @@ static void HandleShutdown(SINT8 node) static void HandleTimeout(SINT8 node) { (void)node; - LUAh_GameQuit(false); + LUA_HookBool(false, Hook(GameQuit)); D_QuitNetGame(); CL_Reset(); D_StartTitle(); diff --git a/src/d_netcmd.c b/src/d_netcmd.c index d2f6add0c..25b4b0aa1 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -3612,7 +3612,7 @@ static void Command_Playintro_f(void) */ FUNCNORETURN static ATTRNORETURN void Command_Quit_f(void) { - LUAh_GameQuit(true); + LUA_HookBool(true, Hook(GameQuit)); I_Quit(); } @@ -4274,7 +4274,7 @@ void Command_ExitGame_f(void) { INT32 i; - LUAh_GameQuit(false); + LUA_HookBool(false, Hook(GameQuit)); D_QuitNetGame(); CL_Reset(); diff --git a/src/lua_hook.h b/src/lua_hook.h index f44a2e305..873c14643 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -84,6 +84,7 @@ void LUA_Hook(int hook); int LUA_HookMobj(mobj_t *, int hook); int LUA_Hook2Mobj(mobj_t *, mobj_t *, int hook); void LUA_HookInt(INT32 integer, int hook); +void LUA_HookBool(boolean value, int hook); int LUA_HookPlayer(player_t *, int hook); int LUA_HookTiccmd(player_t *, ticcmd_t *, int hook); diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 1ac9a6952..5492c7921 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -561,6 +561,16 @@ void LUA_HookInt(INT32 number, int hook_type) } } +void LUA_HookBool(boolean value, int hook_type) +{ + Hook_State hook; + if (prepare_hook(&hook, 0, hook_type)) + { + lua_pushboolean(gL, value); + call_hooks(&hook, 1, 0, res_none); + } +} + int LUA_HookPlayer(player_t *player, int hook_type) { Hook_State hook; diff --git a/src/m_menu.c b/src/m_menu.c index 5ec9132f7..c6b1b2b8a 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -6937,7 +6937,7 @@ static void M_SelectableClearMenus(INT32 choice) static void M_UltimateCheat(INT32 choice) { (void)choice; - LUAh_GameQuit(true); + LUA_HookBool(true, Hook(GameQuit)); I_Quit(); } @@ -13371,7 +13371,7 @@ void M_QuitResponse(INT32 ch) if (ch != 'y' && ch != KEY_ENTER) return; - LUAh_GameQuit(true); + LUA_HookBool(true, Hook(GameQuit)); if (!(netgame || cv_debug)) { S_ResetCaptions(); diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 5ebff8700..f3da446d8 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1057,7 +1057,7 @@ void I_GetEvent(void) M_SetupJoystickMenu(0); break; case SDL_QUIT: - LUAh_GameQuit(true); + LUA_HookBool(true, Hook(GameQuit)); I_Quit(); break; } From e55d842d7f4647719fb197621aa368677ae114a4 Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 12 Dec 2020 02:11:23 -0800 Subject: [PATCH 149/644] Kill SEENAMES --- src/d_netcmd.c | 8 +------- src/d_netcmd.h | 2 -- src/deh_tables.c | 4 ---- src/doomdef.h | 3 --- src/g_game.c | 2 -- src/g_game.h | 2 -- src/info.c | 4 ---- src/info.h | 4 ---- src/lua_hook.h | 4 +--- src/lua_hooklib.c | 4 +--- src/m_menu.c | 2 -- src/p_floor.c | 2 -- src/p_local.h | 2 -- src/p_map.c | 6 ++---- src/p_user.c | 2 -- src/st_stuff.c | 2 -- 16 files changed, 5 insertions(+), 48 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 31c10f58a..bea1ab33e 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -214,11 +214,9 @@ consvar_t cv_respawntime = CVAR_INIT ("respawndelay", "3", CV_SAVE|CV_NETVAR|CV_ consvar_t cv_competitionboxes = CVAR_INIT ("competitionboxes", "Mystery", CV_SAVE|CV_NETVAR|CV_CHEAT, competitionboxes_cons_t, NULL); -#ifdef SEENAMES static CV_PossibleValue_t seenames_cons_t[] = {{0, "Off"}, {1, "Colorless"}, {2, "Team"}, {3, "Ally/Foe"}, {0, NULL}}; consvar_t cv_seenames = CVAR_INIT ("seenames", "Ally/Foe", CV_SAVE, seenames_cons_t, 0); consvar_t cv_allowseenames = CVAR_INIT ("allowseenames", "Yes", CV_SAVE|CV_NETVAR, CV_YesNo, NULL); -#endif // names consvar_t cv_playername = CVAR_INIT ("name", "Sonic", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Name_OnChange); @@ -597,9 +595,7 @@ void D_RegisterServerCommands(void) CV_RegisterVar(&cv_pingtimeout); CV_RegisterVar(&cv_showping); -#ifdef SEENAMES - CV_RegisterVar(&cv_allowseenames); -#endif + CV_RegisterVar(&cv_allowseenames); CV_RegisterVar(&cv_dummyconsvar); } @@ -690,9 +686,7 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_defaultplayercolor2); CV_RegisterVar(&cv_defaultskin2); -#ifdef SEENAMES CV_RegisterVar(&cv_seenames); -#endif CV_RegisterVar(&cv_rollingdemos); CV_RegisterVar(&cv_netstat); CV_RegisterVar(&cv_netticbuffer); diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 98d8f1425..ac39626a4 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -31,9 +31,7 @@ extern consvar_t cv_defaultskin; extern consvar_t cv_defaultplayercolor2; extern consvar_t cv_defaultskin2; -#ifdef SEENAMES extern consvar_t cv_seenames, cv_allowseenames; -#endif extern consvar_t cv_usemouse; extern consvar_t cv_usejoystick; extern consvar_t cv_usejoystick2; diff --git a/src/deh_tables.c b/src/deh_tables.c index 5733d9b0e..95e326823 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -3478,9 +3478,7 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_BLUEBRICKDEBRIS", "S_YELLOWBRICKDEBRIS", -#ifdef SEENAMES "S_NAMECHECK", -#endif }; // RegEx to generate this from info.h: ^\tMT_([^,]+), --> \t"MT_\1", @@ -4260,9 +4258,7 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_BLUEBRICKDEBRIS", "MT_YELLOWBRICKDEBRIS", -#ifdef SEENAMES "MT_NAMECHECK", -#endif }; const char *const MOBJFLAG_LIST[] = { diff --git a/src/doomdef.h b/src/doomdef.h index d0b7ea0c2..52abc9597 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -582,9 +582,6 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; /// Dumps the contents of a network save game upon consistency failure for debugging. //#define DUMPCONSISTENCY -/// See name of player in your crosshair -#define SEENAMES - /// Who put weights on my recycler? ... Inuyasha did. /// \note XMOD port. //#define WEIGHTEDRECYCLER diff --git a/src/g_game.c b/src/g_game.c index 283113bbe..844acea74 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -444,9 +444,7 @@ consvar_t cv_firenaxis2 = CVAR_INIT ("joyaxis2_firenormal", "Z-Axis", CV_SAVE, j consvar_t cv_deadzone2 = CVAR_INIT ("joy_deadzone2", "0.125", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL); consvar_t cv_digitaldeadzone2 = CVAR_INIT ("joy_digdeadzone2", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL); -#ifdef SEENAMES player_t *seenplayer; // player we're aiming at right now -#endif // now automatically allocated in D_RegisterClientCommands // so that it doesn't have to be updated depending on the value of MAXPLAYERS diff --git a/src/g_game.h b/src/g_game.h index 2bcf444c2..744d6755a 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -25,9 +25,7 @@ extern char timeattackfolder[64]; extern char customversionstring[32]; #define GAMEDATASIZE (4*8192) -#ifdef SEENAMES extern player_t *seenplayer; -#endif extern char player_names[MAXPLAYERS][MAXPLAYERNAME+1]; extern INT32 player_name_changes[MAXPLAYERS]; diff --git a/src/info.c b/src/info.c index 29a79b1d6..152a74927 100644 --- a/src/info.c +++ b/src/info.c @@ -3924,9 +3924,7 @@ state_t states[NUMSTATES] = {SPR_BRIB, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 31, 1, S_NULL}, // S_BLUEBRICKDEBRIS {SPR_BRIY, FF_ANIMATE|FF_RANDOMANIM, -1, {NULL}, 31, 1, S_NULL}, // S_YELLOWBRICKDEBRIS -#ifdef SEENAMES {SPR_NULL, 0, 1, {NULL}, 0, 0, S_NULL}, // S_NAMECHECK -#endif }; mobjinfo_t mobjinfo[NUMMOBJTYPES] = @@ -21653,7 +21651,6 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, -#ifdef SEENAMES { // MT_NAMECHECK -1, // doomednum S_NAMECHECK, // spawnstate @@ -21680,7 +21677,6 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY|MF_NOSECTOR, // flags S_NULL // raisestate }, -#endif }; skincolor_t skincolors[MAXSKINCOLORS] = { diff --git a/src/info.h b/src/info.h index 604922beb..c6a2a2c44 100644 --- a/src/info.h +++ b/src/info.h @@ -4280,9 +4280,7 @@ typedef enum state S_BLUEBRICKDEBRIS, // for CEZ3 S_YELLOWBRICKDEBRIS, // for CEZ3 -#ifdef SEENAMES S_NAMECHECK, -#endif S_FIRSTFREESLOT, S_LASTFREESLOT = S_FIRSTFREESLOT + NUMSTATEFREESLOTS - 1, @@ -5082,9 +5080,7 @@ typedef enum mobj_type MT_BLUEBRICKDEBRIS, // for CEZ3 MT_YELLOWBRICKDEBRIS, // for CEZ3 -#ifdef SEENAMES MT_NAMECHECK, -#endif MT_FIRSTFREESLOT, MT_LASTFREESLOT = MT_FIRSTFREESLOT + NUMMOBJFREESLOTS - 1, diff --git a/src/lua_hook.h b/src/lua_hook.h index 796f3a9d2..260df0bee 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -112,11 +112,9 @@ void LUAh_PlayerQuit(player_t *plr, kickreason_t reason); // Hook for player qui void LUAh_IntermissionThinker(void); // Hook for Y_Ticker boolean LUAh_TeamSwitch(player_t *player, int newteam, boolean fromspectators, boolean tryingautobalance, boolean tryingscramble); // Hook for team switching in... uh.... UINT8 LUAh_ViewpointSwitch(player_t *player, player_t *newdisplayplayer, boolean forced); // Hook for spy mode -#ifdef SEENAMES boolean LUAh_SeenPlayer(player_t *player, player_t *seenfriend); // Hook for MT_NAMECHECK -#endif #define LUAh_PlayerThink(player) LUAh_PlayerHook(player, hook_PlayerThink) // Hook for P_PlayerThink boolean LUAh_ShouldJingleContinue(player_t *player, const char *musname); // Hook for whether a jingle of the given music should continue playing void LUAh_GameQuit(void); // Hook for game quitting boolean LUAh_PlayerCmd(player_t *player, ticcmd_t *cmd); // Hook for building player's ticcmd struct (Ported from SRB2Kart) -boolean LUAh_MusicChange(const char *oldname, char *newname, UINT16 *mflags, boolean *looping, UINT32 *position, UINT32 *prefadems, UINT32 *fadeinms); // Hook for music changes \ No newline at end of file +boolean LUAh_MusicChange(const char *oldname, char *newname, UINT16 *mflags, boolean *looping, UINT32 *position, UINT32 *prefadems, UINT32 *fadeinms); // Hook for music changes diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 117aa48a3..7bfe00fb5 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -1754,7 +1754,6 @@ UINT8 LUAh_ViewpointSwitch(player_t *player, player_t *newdisplayplayer, boolean } // Hook for MT_NAMECHECK -#ifdef SEENAMES boolean LUAh_SeenPlayer(player_t *player, player_t *seenfriend) { hook_p hookp; @@ -1798,7 +1797,6 @@ boolean LUAh_SeenPlayer(player_t *player, player_t *seenfriend) return hasSeenPlayer; } -#endif // SEENAMES boolean LUAh_ShouldJingleContinue(player_t *player, const char *musname) { @@ -1971,4 +1969,4 @@ boolean LUAh_MusicChange(const char *oldname, char *newname, UINT16 *mflags, boo lua_settop(gL, 0); newname[6] = 0; return hooked; -} \ No newline at end of file +} diff --git a/src/m_menu.c b/src/m_menu.c index 77648f877..8c2131dc8 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1356,9 +1356,7 @@ static menuitem_t OP_VideoOptionsMenu[] = {IT_STRING | IT_CVAR, NULL, "Score/Time/Rings", &cv_timetic, 71}, {IT_STRING | IT_CVAR, NULL, "Show Powerups", &cv_powerupdisplay, 76}, {IT_STRING | IT_CVAR, NULL, "Local ping display", &cv_showping, 81}, // shows ping next to framerate if we want to. -#ifdef SEENAMES {IT_STRING | IT_CVAR, NULL, "Show player names", &cv_seenames, 86}, -#endif {IT_HEADER, NULL, "Console", NULL, 95}, {IT_STRING | IT_CVAR, NULL, "Background color", &cons_backcolor, 101}, diff --git a/src/p_floor.c b/src/p_floor.c index ed49b03a3..7c26065b5 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -1064,9 +1064,7 @@ static mobj_t *SearchMarioNode(msecnode_t *node) case MT_HOOP: case MT_HOOPCOLLIDE: case MT_NIGHTSCORE: -#ifdef SEENAMES case MT_NAMECHECK: // DEFINITELY not this, because it is client-side. -#endif continue; default: break; diff --git a/src/p_local.h b/src/p_local.h index 8a5084962..8caab0d27 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -326,9 +326,7 @@ mobj_t *P_SpawnPointMissile(mobj_t *source, fixed_t xa, fixed_t ya, fixed_t za, mobj_t *P_SpawnAlteredDirectionMissile(mobj_t *source, mobjtype_t type, fixed_t x, fixed_t y, fixed_t z, INT32 shiftingAngle); mobj_t *P_SPMAngle(mobj_t *source, mobjtype_t type, angle_t angle, UINT8 aimtype, UINT32 flags2); #define P_SpawnPlayerMissile(s,t,f) P_SPMAngle(s,t,s->angle,true,f) -#ifdef SEENAMES #define P_SpawnNameFinder(s,t) P_SPMAngle(s,t,s->angle,true,0) -#endif void P_ColorTeamMissile(mobj_t *missile, player_t *source); SINT8 P_MobjFlip(mobj_t *mobj); fixed_t P_GetMobjGravity(mobj_t *mo); diff --git a/src/p_map.c b/src/p_map.c index 922c0d9ec..1b46f9686 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -727,9 +727,8 @@ static boolean PIT_CheckThing(mobj_t *thing) || (thing->player && thing->player->spectator)) return true; -#ifdef SEENAMES - // Do name checks all the way up here - // So that NOTHING ELSE can see MT_NAMECHECK because it is client-side. + // 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) { // Ignore things that aren't players, ignore spectators, ignore yourself. @@ -753,7 +752,6 @@ static boolean PIT_CheckThing(mobj_t *thing) seenplayer = thing->player; return false; } -#endif // Metal Sonic destroys tiny baby objects. if (tmthing->type == MT_METALSONIC_RACE diff --git a/src/p_user.c b/src/p_user.c index c5f919c78..dc9604110 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -11482,7 +11482,6 @@ void P_PlayerThink(player_t *player) } } -#ifdef SEENAMES if (netgame && player == &players[displayplayer] && !(leveltime % (TICRATE/5))) { seenplayer = NULL; @@ -11507,7 +11506,6 @@ void P_PlayerThink(player_t *player) } } } -#endif if (player->awayviewmobj && P_MobjWasRemoved(player->awayviewmobj)) { diff --git a/src/st_stuff.c b/src/st_stuff.c index b25538d88..649644620 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2751,7 +2751,6 @@ static void ST_overlayDrawer(void) void ST_Drawer(void) { -#ifdef SEENAMES if (cv_seenames.value && cv_allowseenames.value && displayplayer == consoleplayer && seenplayer && seenplayer->mo) { INT32 c = 0; @@ -2775,7 +2774,6 @@ void ST_Drawer(void) V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2 + 15, V_HUDTRANSHALF|c, player_names[seenplayer-players]); } -#endif // Doom's status bar only updated if necessary. // However, ours updates every frame regardless, so the "refresh" param was removed From b31c4db89d4b6a65b952fa6613605c886d8cb11a Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 12 Dec 2020 02:37:03 -0800 Subject: [PATCH 150/644] Remove trailing whitespace --- src/console.c | 2 +- src/lua_hooklib.c | 2 +- src/m_menu.c | 2 +- src/p_inter.c | 6 +++--- src/p_map.c | 4 ++-- src/s_sound.c | 4 ++-- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/console.c b/src/console.c index 21f660a56..f3b0aa603 100644 --- a/src/console.c +++ b/src/console.c @@ -1421,7 +1421,7 @@ void CONS_Printf(const char *fmt, ...) if (con_started) CON_Print(txt); - CON_LogMessage(txt); + CON_LogMessage(txt); Lock_state(); diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index ebf6f9deb..d02601ce4 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -1793,6 +1793,6 @@ void LUAh_GameQuit(void) hookp->error = true; } } - + lua_pop(gL, 1); // Pop error handler } diff --git a/src/m_menu.c b/src/m_menu.c index c7786a496..9c21fbc00 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1483,7 +1483,7 @@ static menuitem_t OP_SoundOptionsMenu[] = {IT_STRING | IT_CVAR, NULL, "MIDI Music", &cv_gamemidimusic, 36}, {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "MIDI Music Volume", &cv_midimusicvolume, 41}, - + {IT_STRING | IT_CVAR, NULL, "Music Preference", &cv_musicpref, 51}, {IT_HEADER, NULL, "Miscellaneous", NULL, 61}, diff --git a/src/p_inter.c b/src/p_inter.c index bd044f32a..5f2050b7f 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -470,14 +470,14 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (!(player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2)) { fixed_t setmomz = -toucher->momz; // Store this, momz get changed by P_DoJump within P_DoBubbleBounce - + if (elementalpierce == 2) // Reset bubblewrap, part 1 P_DoBubbleBounce(player); toucher->momz = setmomz; if (elementalpierce == 2) // Reset bubblewrap, part 2 { boolean underwater = toucher->eflags & MFE_UNDERWATER; - + if (underwater) toucher->momz /= 2; toucher->momz -= (toucher->momz/(underwater ? 8 : 4)); // Cap the height! @@ -1613,7 +1613,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (special->tracer && !(special->tracer->flags2 & MF2_STRONGBOX)) macespin = true; - + if (macespin ? (player->powers[pw_ignorelatch] & (1<<15)) : (player->powers[pw_ignorelatch])) return; diff --git a/src/p_map.c b/src/p_map.c index 74c2790f7..1c10a78f3 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1681,7 +1681,7 @@ static boolean PIT_CheckThing(mobj_t *thing) if (!(player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2)) { fixed_t setmomz = -*momz; // Store this, momz get changed by P_DoJump within P_DoBubbleBounce - + if (elementalpierce == 2) // Reset bubblewrap, part 1 P_DoBubbleBounce(player); *momz = setmomz; // Therefore, you should be thrust in the opposite direction, vertically. @@ -1690,7 +1690,7 @@ static boolean PIT_CheckThing(mobj_t *thing) if (elementalpierce == 2) // Reset bubblewrap, part 2 { boolean underwater = tmthing->eflags & MFE_UNDERWATER; - + if (underwater) *momz /= 2; *momz -= (*momz/(underwater ? 8 : 4)); // Cap the height! diff --git a/src/s_sound.c b/src/s_sound.c index 1885cfcf9..64f092b80 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -2152,7 +2152,7 @@ boolean S_RecallMusic(UINT16 status, boolean fromfirst) static lumpnum_t S_GetMusicLumpNum(const char *mname) { boolean midipref = cv_musicpref.value; - + if (S_PrefAvailable(midipref, mname)) return W_GetNumForName(va(midipref ? "d_%s":"o_%s", mname)); else if (S_PrefAvailable(!midipref, mname)) @@ -2302,7 +2302,7 @@ void S_ChangeMusicEx(const char *mmusic, UINT16 mflags, boolean looping, UINT32 I_FadeSong(0, prefadems, S_ChangeMusicToQueue); return; } - else if (strnicmp(music_name, newmusic, 6) || (mflags & MUSIC_FORCERESET) || + else if (strnicmp(music_name, newmusic, 6) || (mflags & MUSIC_FORCERESET) || (midipref != currentmidi && S_PrefAvailable(midipref, newmusic))) { CONS_Debug(DBG_DETAILED, "Now playing song %s\n", newmusic); From c8cc9c7a6f449505b9a809d106e29dc19e3f7a9c Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 12 Dec 2020 02:40:46 -0800 Subject: [PATCH 151/644] Remove trailing whitespace --- src/d_netcmd.c | 2 +- src/hardware/hw_batching.h | 2 +- src/lua_skinlib.c | 2 +- src/p_enemy.c | 2 +- src/p_mobj.c | 2 +- src/p_user.c | 8 ++++---- src/w_wad.c | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 6080b2fd0..f2e168616 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -878,7 +878,7 @@ void D_RegisterClientCommands(void) // CV_RegisterVar(&cv_snapto); CV_RegisterVar(&cv_freedemocamera); - + // add cheat commands COM_AddCommand("noclip", Command_CheatNoClip_f); COM_AddCommand("god", Command_CheatGod_f); diff --git a/src/hardware/hw_batching.h b/src/hardware/hw_batching.h index 3d22324ac..42291a0df 100644 --- a/src/hardware/hw_batching.h +++ b/src/hardware/hw_batching.h @@ -16,7 +16,7 @@ #include "hw_data.h" #include "hw_drv.h" -typedef struct +typedef struct { FSurfaceInfo surf;// surf also has its own polyflags for some reason, but it seems unused unsigned int vertsIndex;// location of verts in unsortedVertexArray diff --git a/src/lua_skinlib.c b/src/lua_skinlib.c index ea368a9cd..56be6bf4f 100644 --- a/src/lua_skinlib.c +++ b/src/lua_skinlib.c @@ -214,7 +214,7 @@ static int skin_get(lua_State *L) break; case skin_sprites: LUA_PushLightUserdata(L, skin->sprites, META_SKINSPRITES); - break; + break; } return 1; } diff --git a/src/p_enemy.c b/src/p_enemy.c index 63a14636d..7f322567e 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -4060,7 +4060,7 @@ bossjustdie: // Initialize my junk junk.tags.tags = NULL; junk.tags.count = 0; - + Tag_FSet(&junk.tags, LE_KOOPA); EV_DoCeiling(&junk, raiseToHighest); return; diff --git a/src/p_mobj.c b/src/p_mobj.c index 1f87762bc..a1edcfe77 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11398,7 +11398,7 @@ void P_SpawnPlayer(INT32 playernum) p->normalspeed = skins[p->skin].normalspeed; p->jumpfactor = skins[p->skin].jumpfactor; } - + // Clear lastlinehit and lastsidehit p->lastsidehit = -1; p->lastlinehit = -1; diff --git a/src/p_user.c b/src/p_user.c index 892f4b678..2377134cc 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2613,10 +2613,10 @@ static void P_CheckBustableBlocks(player_t *player) if ((netgame || multiplayer) && player->spectator) return; - + oldx = player->mo->x; oldy = player->mo->y; - + if (!(player->pflags & PF_BOUNCING)) // Bouncers only get to break downwards, not sideways { P_UnsetThingPosition(player->mo); @@ -2635,7 +2635,7 @@ static void P_CheckBustableBlocks(player_t *player) if (!node->m_sector->ffloors) continue; - + for (rover = node->m_sector->ffloors; rover; rover = rover->next) { if (!P_PlayerCanBust(player, rover)) @@ -4525,7 +4525,7 @@ void P_DoJump(player_t *player, boolean soundandstate) player->mo->eflags &= ~MFE_APPLYPMOMZ; player->pflags |= P_GetJumpFlags(player);; - + if (player->charflags & SF_NOJUMPDAMAGE) player->pflags &= ~PF_SPINNING; diff --git a/src/w_wad.c b/src/w_wad.c index 2429eaf92..4aae2ee46 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -2144,7 +2144,7 @@ int W_VerifyNMUSlumps(const char *filename, boolean exit_on_error) {"LT", 2}, // Titlecard changes {"SLID", 4}, // Continue - {"CONT", 4}, + {"CONT", 4}, {"MINICAPS", 8}, // NiGHTS graphics here and below {"BLUESTAT", 8}, // Sphere status From 93e4f43e4b3a24fc2d8032e8730cbf427e75b297 Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 12 Dec 2020 03:06:57 -0800 Subject: [PATCH 152/644] Hooklib macros names -> uppercase + documentation --- src/b_bot.c | 4 +-- src/d_clisrv.c | 8 ++--- src/d_netcmd.c | 6 ++-- src/g_demo.c | 2 +- src/g_game.c | 6 ++-- src/lua_hook.h | 40 +++++++++++++++------- src/lua_hooklib.c | 84 +++++++++++++++++++++++------------------------ src/m_menu.c | 4 +-- src/p_enemy.c | 2 +- src/p_map.c | 4 +-- src/p_mobj.c | 20 +++++------ src/p_setup.c | 2 +- src/p_tick.c | 8 ++--- src/p_user.c | 26 +++++++-------- src/sdl/i_video.c | 2 +- src/y_inter.c | 2 +- 16 files changed, 117 insertions(+), 103 deletions(-) diff --git a/src/b_bot.c b/src/b_bot.c index 93a853dee..ba5aa3ccf 100644 --- a/src/b_bot.c +++ b/src/b_bot.c @@ -363,7 +363,7 @@ void B_BuildTiccmd(player_t *player, ticcmd_t *cmd) CV_SetValue(&cv_analog[1], false); // Let Lua scripts build ticcmds - if (LUA_HookTiccmd(player, cmd, Hook(BotTiccmd))) + if (LUA_HookTiccmd(player, cmd, HOOK(BotTiccmd))) return; // We don't have any main character AI, sorry. D: @@ -461,7 +461,7 @@ boolean B_CheckRespawn(player_t *player) // B_RespawnBot doesn't do anything if the condition above this isn't met { - UINT8 shouldForce = LUA_Hook2Mobj(sonic, tails, Mobj_Hook(BotRespawn)); + UINT8 shouldForce = LUA_Hook2Mobj(sonic, tails, MOBJ_HOOK(BotRespawn)); if (P_MobjWasRemoved(sonic) || P_MobjWasRemoved(tails)) return (shouldForce == 1); // mobj was removed diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 9a24546ea..2a461be34 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -3032,7 +3032,7 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum) if (pnum == consoleplayer) { - LUA_HookBool(false, Hook(GameQuit)); + LUA_HookBool(false, HOOK(GameQuit)); #ifdef DUMPCONSISTENCY if (msg == KICK_MSG_CON_FAIL) SV_SavedGame(); #endif @@ -3452,7 +3452,7 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum) COM_BufAddText(va("sayto %d %s\n", newplayernum, motd)); if (!rejoined) - LUA_HookInt(newplayernum, Hook(PlayerJoin)); + LUA_HookInt(newplayernum, HOOK(PlayerJoin)); } static boolean SV_AddWaitingPlayers(const char *name, const char *name2) @@ -3732,7 +3732,7 @@ static void HandleConnect(SINT8 node) static void HandleShutdown(SINT8 node) { (void)node; - LUA_HookBool(false, Hook(GameQuit)); + LUA_HookBool(false, HOOK(GameQuit)); D_QuitNetGame(); CL_Reset(); D_StartTitle(); @@ -3747,7 +3747,7 @@ static void HandleShutdown(SINT8 node) static void HandleTimeout(SINT8 node) { (void)node; - LUA_HookBool(false, Hook(GameQuit)); + LUA_HookBool(false, HOOK(GameQuit)); D_QuitNetGame(); CL_Reset(); D_StartTitle(); diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 25b4b0aa1..ee75b059d 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -2103,7 +2103,7 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum) } mapnumber = M_MapNumber(mapname[3], mapname[4]); - LUA_HookInt(mapnumber, Hook(MapChange)); + LUA_HookInt(mapnumber, HOOK(MapChange)); G_InitNew(ultimatemode, mapname, resetplayer, skipprecutscene, FLS); if (demoplayback && !timingdemo) @@ -3612,7 +3612,7 @@ static void Command_Playintro_f(void) */ FUNCNORETURN static ATTRNORETURN void Command_Quit_f(void) { - LUA_HookBool(true, Hook(GameQuit)); + LUA_HookBool(true, HOOK(GameQuit)); I_Quit(); } @@ -4274,7 +4274,7 @@ void Command_ExitGame_f(void) { INT32 i; - LUA_HookBool(false, Hook(GameQuit)); + LUA_HookBool(false, HOOK(GameQuit)); D_QuitNetGame(); CL_Reset(); diff --git a/src/g_demo.c b/src/g_demo.c index e4af7086c..5bfe2684c 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -1956,7 +1956,7 @@ void G_DoPlayDemo(char *defdemoname) // Set skin SetPlayerSkin(0, skin); - LUA_HookInt(gamemap, Hook(MapChange)); + LUA_HookInt(gamemap, HOOK(MapChange)); displayplayer = consoleplayer = 0; memset(playeringame,0,sizeof(playeringame)); playeringame[0] = true; diff --git a/src/g_game.c b/src/g_game.c index e889c7113..209ca0580 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1689,7 +1689,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) cmd->angleturn = orighookangle; - LUA_HookTiccmd(player, cmd, Hook(PlayerCmd)); + LUA_HookTiccmd(player, cmd, HOOK(PlayerCmd)); extra = cmd->angleturn - orighookangle; cmd->angleturn = origangle + extra; @@ -2740,7 +2740,7 @@ void G_SpawnPlayer(INT32 playernum) P_SpawnPlayer(playernum); G_MovePlayerToSpawnOrStarpost(playernum); - LUA_HookPlayer(&players[playernum], Hook(PlayerSpawn)); // Lua hook for player spawning :) + LUA_HookPlayer(&players[playernum], HOOK(PlayerSpawn)); // Lua hook for player spawning :) } void G_MovePlayerToSpawnOrStarpost(INT32 playernum) @@ -3119,7 +3119,7 @@ void G_DoReborn(INT32 playernum) } else { - LUA_HookInt(gamemap, Hook(MapChange)); + LUA_HookInt(gamemap, HOOK(MapChange)); titlecardforreload = true; G_DoLoadLevel(true); titlecardforreload = false; diff --git a/src/lua_hook.h b/src/lua_hook.h index 873c14643..4274f1f3c 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -14,7 +14,14 @@ #include "d_player.h" #include "s_sound.h" -#define Mobj_Hook_List(X) \ +/* +Do you know what an 'X Macro' is? Such a macro is called over each element of +a list and expands the input. I use it for the hook lists because both an enum +and array of hook names need to be kept in order. The X Macro handles this +automatically. +*/ + +#define MOBJ_HOOK_LIST(X) \ X (MobjSpawn),/* P_SpawnMobj */\ X (MobjCollide),/* PIT_CheckThing */\ X (MobjLineCollide),/* ditto */\ @@ -33,7 +40,7 @@ X (MapThingSpawn),/* P_SpawnMapThing */\ X (FollowMobj),/* P_PlayerAfterThink Smiles mobj-following */\ -#define Hook_List(X) \ +#define HOOK_LIST(X) \ X (NetVars),/* add to archive table (netsave) */\ X (MapChange),/* (before map load) */\ X (MapLoad),\ @@ -62,24 +69,33 @@ X (PlayerCmd),/* building the player's ticcmd struct (Ported from SRB2Kart) */\ X (MusicChange),\ -#define String_Hook_List(X) \ +#define STRING_HOOK_LIST(X) \ X (BotAI),/* B_BuildTailsTiccmd by skin name */\ X (LinedefExecute),\ X (ShouldJingleContinue),/* should jingle of the given music continue playing */\ -#define Mobj_Hook(name) mobjhook_ ## name -#define Hook(name) hook_ ## name -#define String_Hook(name) stringhook_ ## name +/* +I chose to access the hook enums through a macro as well. This could provide +a hint to lookup the macro's definition instead of the enum's definition. +(Since each enumeration is not defined in the source code, but by the list +macros above, it is not greppable.) The name passed to the macro can also be +grepped and found in the lists above. +*/ -enum { Mobj_Hook_List (Mobj_Hook) Mobj_Hook(MAX) }; -enum { Hook_List (Hook) Hook(MAX) }; -enum { String_Hook_List (String_Hook) String_Hook(MAX) }; +#define MOBJ_HOOK(name) mobjhook_ ## name +#define HOOK(name) hook_ ## name +#define STRING_HOOK(name) stringhook_ ## name + +enum { MOBJ_HOOK_LIST (MOBJ_HOOK) MOBJ_HOOK(MAX) }; +enum { HOOK_LIST (HOOK) HOOK(MAX) }; +enum { STRING_HOOK_LIST (STRING_HOOK) STRING_HOOK(MAX) }; + +/* dead simple, LUA_HOOK(GameQuit) */ +#define LUA_HOOK(type) LUA_HookVoid(HOOK(type)) extern boolean hook_cmd_running; -/* dead simple, LUA_Hook(GameQuit) */ -void LUA_Hook(int hook); -#define LUA_Hook(type) LUA_Hook(Hook(type)) +void LUA_HookVoid(int hook); int LUA_HookMobj(mobj_t *, int hook); int LUA_Hook2Mobj(mobj_t *, mobj_t *, int hook); diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 5492c7921..4143fbd8e 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -27,17 +27,15 @@ #include "d_netcmd.h" // for cv_perfstats #include "i_system.h" // I_GetPreciseTime -#undef LUA_Hook - /* ========================================================================= ABSTRACTION ========================================================================= */ -static const char * const mobjHookNames[] = { Mobj_Hook_List (TOSTR) NULL }; -static const char * const hookNames[] = { Hook_List (TOSTR) NULL }; +static const char * const mobjHookNames[] = { MOBJ_HOOK_LIST (TOSTR) NULL }; +static const char * const hookNames[] = { HOOK_LIST (TOSTR) NULL }; static const char * const stringHookNames[] = { - String_Hook_List (TOSTR) NULL + STRING_HOOK_LIST (TOSTR) NULL }; /* TODO: remove when doomtype version is merged */ @@ -62,11 +60,11 @@ typedef struct { int ref; } stringhook_t; -static hook_t hookIds[Hook(MAX)]; -static hook_t mobjHookIds[NUMMOBJTYPES][Mobj_Hook(MAX)]; +static hook_t hookIds[HOOK(MAX)]; +static hook_t mobjHookIds[NUMMOBJTYPES][MOBJ_HOOK(MAX)]; // Lua tables are used to lookup string hook ids. -static stringhook_t stringHooks[String_Hook(MAX)]; +static stringhook_t stringHooks[STRING_HOOK(MAX)]; // This will be indexed by hook id, the value of which fetches the registry. static int * hookRefs; @@ -132,8 +130,8 @@ static void add_string_hook(lua_State *L, int type, int id) switch (type) { - case String_Hook(BotAI): - case String_Hook(ShouldJingleContinue): + case STRING_HOOK(BotAI): + case STRING_HOOK(ShouldJingleContinue): if (lua_isstring(L, 3)) { // lowercase copy string = Z_StrDup(lua_tostring(L, 3)); @@ -141,7 +139,7 @@ static void add_string_hook(lua_State *L, int type, int id) } break; - case String_Hook(LinedefExecute): + case STRING_HOOK(LinedefExecute): string = Z_StrDup(luaL_checkstring(L, 3)); strupr(string); break; @@ -197,15 +195,15 @@ static int lib_addHook(lua_State *L) luaL_checktype(L, 2, LUA_TFUNCTION); /* this is a very special case */ - if (( type = hook_in_list(name, stringHookNames) ) < String_Hook(MAX)) + if (( type = hook_in_list(name, stringHookNames) ) < STRING_HOOK(MAX)) { add_string_hook(L, type, nextid); } - else if (( type = hook_in_list(name, mobjHookNames) ) < Mobj_Hook(MAX)) + else if (( type = hook_in_list(name, mobjHookNames) ) < MOBJ_HOOK(MAX)) { add_mobj_hook(L, type, nextid); } - else if (( type = hook_in_list(name, hookNames) ) < Hook(MAX)) + else if (( type = hook_in_list(name, hookNames) ) < HOOK(MAX)) { add_hook(&hookIds[type], nextid); } @@ -544,7 +542,7 @@ int LUA_Hook2Mobj(mobj_t *t1, mobj_t *t2, int hook_type) return hook.status; } -void LUA_Hook(int type) +void LUA_HookVoid(int type) { Hook_State hook; if (prepare_hook(&hook, 0, type)) @@ -590,12 +588,12 @@ int LUA_HookTiccmd(player_t *player, ticcmd_t *cmd, int hook_type) LUA_PushUserdata(gL, player, META_PLAYER); LUA_PushUserdata(gL, cmd, META_TICCMD); - if (hook_type == Hook(PlayerCmd)) + if (hook_type == HOOK(PlayerCmd)) hook_cmd_running = true; call_hooks(&hook, 2, 1, res_true); - if (hook_type == Hook(PlayerCmd)) + if (hook_type == HOOK(PlayerCmd)) hook_cmd_running = false; } return hook.status; @@ -607,7 +605,7 @@ int LUA_HookTiccmd(player_t *player, ticcmd_t *cmd, int hook_type) void LUA_HookThinkFrame(void) { - const int type = Hook(ThinkFrame); + const int type = HOOK(ThinkFrame); // variables used by perf stats int hook_index = 0; @@ -651,7 +649,7 @@ void LUA_HookThinkFrame(void) int LUA_HookMobjLineCollide(mobj_t *mobj, line_t *line) { Hook_State hook; - if (prepare_mobj_hook(&hook, 0, Mobj_Hook(MobjLineCollide), mobj->type)) + if (prepare_mobj_hook(&hook, 0, MOBJ_HOOK(MobjLineCollide), mobj->type)) { LUA_PushUserdata(gL, mobj, META_MOBJ); LUA_PushUserdata(gL, line, META_LINE); @@ -663,7 +661,7 @@ int LUA_HookMobjLineCollide(mobj_t *mobj, line_t *line) int LUA_HookTouchSpecial(mobj_t *special, mobj_t *toucher) { Hook_State hook; - if (prepare_mobj_hook(&hook, false, Mobj_Hook(TouchSpecial), special->type)) + if (prepare_mobj_hook(&hook, false, MOBJ_HOOK(TouchSpecial), special->type)) { LUA_PushUserdata(gL, special, META_MOBJ); LUA_PushUserdata(gL, toucher, META_MOBJ); @@ -700,19 +698,19 @@ static int damage_hook int LUA_HookShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype) { return damage_hook(target, inflictor, source, damage, damagetype, - Mobj_Hook(ShouldDamage), 5, res_force); + MOBJ_HOOK(ShouldDamage), 5, res_force); } int LUA_HookMobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype) { return damage_hook(target, inflictor, source, damage, damagetype, - Mobj_Hook(MobjDamage), 5, res_true); + MOBJ_HOOK(MobjDamage), 5, res_true); } int LUA_HookMobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damagetype) { return damage_hook(target, inflictor, source, 0, damagetype, - Mobj_Hook(MobjDeath), 4, res_true); + MOBJ_HOOK(MobjDeath), 4, res_true); } typedef struct { @@ -737,12 +735,12 @@ static void res_botai(Hook_State *hook) if (lua_istable(gL, -8)) { lua_pushnil(gL); // key while (lua_next(gL, -9)) { -#define check(n, f) (checkbotkey(f) ? (k[(n)-1] = 1) : 0) +#define CHECK(n, f) (checkbotkey(f) ? (k[(n)-1] = 1) : 0) if ( - check(1, "forward") || check(2, "backward") || - check(3, "left") || check(4, "right") || - check(5, "strafeleft") || check(6, "straferight") || - check(7, "jump") || check(8, "spin") + CHECK(1, "forward") || CHECK(2, "backward") || + CHECK(3, "left") || CHECK(4, "right") || + CHECK(5, "strafeleft") || CHECK(6, "straferight") || + CHECK(7, "jump") || CHECK(8, "spin") ){ if (8 <= ++fields) { @@ -752,7 +750,7 @@ static void res_botai(Hook_State *hook) } lua_pop(gL, 1); // pop value -#undef check +#undef CHECK } } else { while (fields < 8) @@ -775,7 +773,7 @@ int LUA_HookBotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd) Hook_State hook; BotAI_State botai; - if (prepare_string_hook(&hook, false, String_Hook(BotAI), skin)) + if (prepare_string_hook(&hook, false, STRING_HOOK(BotAI), skin)) { LUA_PushUserdata(gL, sonic, META_MOBJ); LUA_PushUserdata(gL, tails, META_MOBJ); @@ -795,7 +793,7 @@ void LUA_HookLinedefExecute(line_t *line, mobj_t *mo, sector_t *sector) { Hook_State hook; if (prepare_string_hook - (&hook, 0, String_Hook(LinedefExecute), line->stringargs[0])) + (&hook, 0, STRING_HOOK(LinedefExecute), line->stringargs[0])) { LUA_PushUserdata(gL, line, META_LINE); LUA_PushUserdata(gL, mo, META_MOBJ); @@ -807,7 +805,7 @@ void LUA_HookLinedefExecute(line_t *line, mobj_t *mo, sector_t *sector) int LUA_HookPlayerMsg(int source, int target, int flags, char *msg) { Hook_State hook; - if (prepare_hook(&hook, false, Hook(PlayerMsg))) + if (prepare_hook(&hook, false, HOOK(PlayerMsg))) { LUA_PushUserdata(gL, &players[source], META_PLAYER); // Source player if (flags & 2 /*HU_CSAY*/) { // csay TODO: make HU_CSAY accessible outside hu_stuff.c @@ -832,7 +830,7 @@ int LUA_HookPlayerMsg(int source, int target, int flags, char *msg) int LUA_HookHurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 damagetype) { Hook_State hook; - if (prepare_hook(&hook, false, Hook(HurtMsg))) + if (prepare_hook(&hook, false, HOOK(HurtMsg))) { LUA_PushUserdata(gL, player, META_PLAYER); LUA_PushUserdata(gL, inflictor, META_MOBJ); @@ -845,7 +843,7 @@ int LUA_HookHurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 d void LUA_HookNetArchive(lua_CFunction archFunc) { - const hook_t * map = &hookIds[Hook(NetVars)]; + const hook_t * map = &hookIds[HOOK(NetVars)]; Hook_State hook; /* this is a remarkable case where the stack isn't reset */ if (map->numHooks > 0) @@ -874,7 +872,7 @@ void LUA_HookNetArchive(lua_CFunction archFunc) int LUA_HookMapThingSpawn(mobj_t *mobj, mapthing_t *mthing) { Hook_State hook; - if (prepare_mobj_hook(&hook, false, Mobj_Hook(MapThingSpawn), mobj->type)) + if (prepare_mobj_hook(&hook, false, MOBJ_HOOK(MapThingSpawn), mobj->type)) { LUA_PushUserdata(gL, mobj, META_MOBJ); LUA_PushUserdata(gL, mthing, META_MAPTHING); @@ -886,7 +884,7 @@ int LUA_HookMapThingSpawn(mobj_t *mobj, mapthing_t *mthing) int LUA_HookFollowMobj(player_t *player, mobj_t *mobj) { Hook_State hook; - if (prepare_mobj_hook(&hook, false, Mobj_Hook(FollowMobj), mobj->type)) + if (prepare_mobj_hook(&hook, false, MOBJ_HOOK(FollowMobj), mobj->type)) { LUA_PushUserdata(gL, player, META_PLAYER); LUA_PushUserdata(gL, mobj, META_MOBJ); @@ -898,7 +896,7 @@ int LUA_HookFollowMobj(player_t *player, mobj_t *mobj) int LUA_HookPlayerCanDamage(player_t *player, mobj_t *mobj) { Hook_State hook; - if (prepare_hook(&hook, 0, Hook(PlayerCanDamage))) + if (prepare_hook(&hook, 0, HOOK(PlayerCanDamage))) { LUA_PushUserdata(gL, player, META_PLAYER); LUA_PushUserdata(gL, mobj, META_MOBJ); @@ -910,7 +908,7 @@ int LUA_HookPlayerCanDamage(player_t *player, mobj_t *mobj) void LUA_HookPlayerQuit(player_t *plr, kickreason_t reason) { Hook_State hook; - if (prepare_hook(&hook, 0, Hook(PlayerQuit))) + if (prepare_hook(&hook, 0, HOOK(PlayerQuit))) { LUA_PushUserdata(gL, plr, META_PLAYER); // Player that quit lua_pushinteger(gL, reason); // Reason for quitting @@ -921,7 +919,7 @@ void LUA_HookPlayerQuit(player_t *plr, kickreason_t reason) int LUA_HookTeamSwitch(player_t *player, int newteam, boolean fromspectators, boolean tryingautobalance, boolean tryingscramble) { Hook_State hook; - if (prepare_hook(&hook, true, Hook(TeamSwitch))) + if (prepare_hook(&hook, true, HOOK(TeamSwitch))) { LUA_PushUserdata(gL, player, META_PLAYER); lua_pushinteger(gL, newteam); @@ -936,7 +934,7 @@ int LUA_HookTeamSwitch(player_t *player, int newteam, boolean fromspectators, bo int LUA_HookViewpointSwitch(player_t *player, player_t *newdisplayplayer, boolean forced) { Hook_State hook; - if (prepare_hook(&hook, 0, Hook(ViewpointSwitch))) + if (prepare_hook(&hook, 0, HOOK(ViewpointSwitch))) { LUA_PushUserdata(gL, player, META_PLAYER); LUA_PushUserdata(gL, newdisplayplayer, META_PLAYER); @@ -953,7 +951,7 @@ int LUA_HookViewpointSwitch(player_t *player, player_t *newdisplayplayer, boolea int LUA_HookSeenPlayer(player_t *player, player_t *seenfriend) { Hook_State hook; - if (prepare_hook(&hook, true, Hook(SeenPlayer))) + if (prepare_hook(&hook, true, HOOK(SeenPlayer))) { LUA_PushUserdata(gL, player, META_PLAYER); LUA_PushUserdata(gL, seenfriend, META_PLAYER); @@ -970,7 +968,7 @@ int LUA_HookShouldJingleContinue(player_t *player, const char *musname) { Hook_State hook; if (prepare_string_hook - (&hook, false, String_Hook(ShouldJingleContinue), musname)) + (&hook, false, STRING_HOOK(ShouldJingleContinue), musname)) { LUA_PushUserdata(gL, player, META_PLAYER); push_string(); @@ -1033,7 +1031,7 @@ static void res_musicchange(Hook_State *hook) int LUA_HookMusicChange(const char *oldname, struct MusicChange *param) { - const int type = Hook(MusicChange); + const int type = HOOK(MusicChange); const hook_t * map = &hookIds[type]; Hook_State hook; diff --git a/src/m_menu.c b/src/m_menu.c index c6b1b2b8a..2a44bb2a4 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -6937,7 +6937,7 @@ static void M_SelectableClearMenus(INT32 choice) static void M_UltimateCheat(INT32 choice) { (void)choice; - LUA_HookBool(true, Hook(GameQuit)); + LUA_HookBool(true, HOOK(GameQuit)); I_Quit(); } @@ -13371,7 +13371,7 @@ void M_QuitResponse(INT32 ch) if (ch != 'y' && ch != KEY_ENTER) return; - LUA_HookBool(true, Hook(GameQuit)); + LUA_HookBool(true, HOOK(GameQuit)); if (!(netgame || cv_debug)) { S_ResetCaptions(); diff --git a/src/p_enemy.c b/src/p_enemy.c index 276fc999d..2aec5c989 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -3961,7 +3961,7 @@ void A_BossDeath(mobj_t *mo) } bossjustdie: - if (LUA_HookMobj(mo, Mobj_Hook(BossDeath))) + if (LUA_HookMobj(mo, MOBJ_HOOK(BossDeath))) return; else if (P_MobjWasRemoved(mo)) return; diff --git a/src/p_map.c b/src/p_map.c index e55238ffa..14eac1147 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -937,7 +937,7 @@ static boolean PIT_CheckThing(mobj_t *thing) } { - UINT8 shouldCollide = LUA_Hook2Mobj(thing, tmthing, Mobj_Hook(MobjCollide)); // checks hook for thing's type + UINT8 shouldCollide = LUA_Hook2Mobj(thing, tmthing, MOBJ_HOOK(MobjCollide)); // checks hook for thing's type if (P_MobjWasRemoved(tmthing) || P_MobjWasRemoved(thing)) return true; // one of them was removed??? if (shouldCollide == 1) @@ -945,7 +945,7 @@ static boolean PIT_CheckThing(mobj_t *thing) else if (shouldCollide == 2) return true; // force no collide - shouldCollide = LUA_Hook2Mobj(tmthing, thing, Mobj_Hook(MobjMoveCollide)); // checks hook for tmthing's type + shouldCollide = LUA_Hook2Mobj(tmthing, thing, MOBJ_HOOK(MobjMoveCollide)); // checks hook for tmthing's type if (P_MobjWasRemoved(tmthing) || P_MobjWasRemoved(thing)) return true; // one of them was removed??? if (shouldCollide == 1) diff --git a/src/p_mobj.c b/src/p_mobj.c index c2de01fa7..9d8a7bd7d 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1844,7 +1844,7 @@ void P_XYMovement(mobj_t *mo) B_MoveBlocked(player); } - if (LUA_HookMobj(mo, Mobj_Hook(MobjMoveBlocked))) + if (LUA_HookMobj(mo, MOBJ_HOOK(MobjMoveBlocked))) { if (P_MobjWasRemoved(mo)) return; @@ -7509,7 +7509,7 @@ static void P_RosySceneryThink(mobj_t *mobj) static void P_MobjSceneryThink(mobj_t *mobj) { - if (LUA_HookMobj(mobj, Mobj_Hook(MobjThinker))) + if (LUA_HookMobj(mobj, MOBJ_HOOK(MobjThinker))) return; if (P_MobjWasRemoved(mobj)) return; @@ -7857,7 +7857,7 @@ static void P_MobjSceneryThink(mobj_t *mobj) if (!mobj->fuse) { - if (!LUA_HookMobj(mobj, Mobj_Hook(MobjFuse))) + if (!LUA_HookMobj(mobj, MOBJ_HOOK(MobjFuse))) P_RemoveMobj(mobj); return; } @@ -7916,7 +7916,7 @@ static void P_MobjSceneryThink(mobj_t *mobj) mobj->fuse--; if (!mobj->fuse) { - if (!LUA_HookMobj(mobj, Mobj_Hook(MobjFuse))) + if (!LUA_HookMobj(mobj, MOBJ_HOOK(MobjFuse))) P_RemoveMobj(mobj); return; } @@ -7945,7 +7945,7 @@ static boolean P_MobjPushableThink(mobj_t *mobj) static boolean P_MobjBossThink(mobj_t *mobj) { - if (LUA_HookMobj(mobj, Mobj_Hook(BossThinker))) + if (LUA_HookMobj(mobj, MOBJ_HOOK(BossThinker))) { if (P_MobjWasRemoved(mobj)) return false; @@ -9872,7 +9872,7 @@ static boolean P_FuseThink(mobj_t *mobj) if (mobj->fuse) return true; - if (LUA_HookMobj(mobj, Mobj_Hook(MobjFuse)) || P_MobjWasRemoved(mobj)) + if (LUA_HookMobj(mobj, MOBJ_HOOK(MobjFuse)) || P_MobjWasRemoved(mobj)) ; else if (mobj->info->flags & MF_MONITOR) { @@ -10048,13 +10048,13 @@ void P_MobjThinker(mobj_t *mobj) // Check for a Lua thinker first if (!mobj->player) { - if (LUA_HookMobj(mobj, Mobj_Hook(MobjThinker)) || P_MobjWasRemoved(mobj)) + if (LUA_HookMobj(mobj, MOBJ_HOOK(MobjThinker)) || P_MobjWasRemoved(mobj)) return; } else if (!mobj->player->spectator) { // You cannot short-circuit the player thinker like you can other thinkers. - LUA_HookMobj(mobj, Mobj_Hook(MobjThinker)); + LUA_HookMobj(mobj, MOBJ_HOOK(MobjThinker)); if (P_MobjWasRemoved(mobj)) return; } @@ -10525,7 +10525,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) // DANGER! This can cause P_SpawnMobj to return NULL! // Avoid using P_RemoveMobj on the newly created mobj in "MobjSpawn" Lua hooks! - if (LUA_HookMobj(mobj, Mobj_Hook(MobjSpawn))) + if (LUA_HookMobj(mobj, MOBJ_HOOK(MobjSpawn))) { if (P_MobjWasRemoved(mobj)) return NULL; @@ -10912,7 +10912,7 @@ void P_RemoveMobj(mobj_t *mobj) return; // something already removing this mobj. mobj->thinker.function.acp1 = (actionf_p1)P_RemoveThinkerDelayed; // shh. no recursing. - LUA_HookMobj(mobj, Mobj_Hook(MobjRemoved)); + LUA_HookMobj(mobj, MOBJ_HOOK(MobjRemoved)); mobj->thinker.function.acp1 = (actionf_p1)P_MobjThinker; // needed for P_UnsetThingPosition, etc. to work. // Rings only, please! diff --git a/src/p_setup.c b/src/p_setup.c index 09addd73d..0ab43a8bc 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -4271,7 +4271,7 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate) G_CopyTiccmd(&players[i].cmd, &netcmds[buf][i], 1); } P_PreTicker(2); - LUA_HookInt(gamemap, Hook(MapLoad)); + LUA_HookInt(gamemap, HOOK(MapLoad)); } // No render mode or reloading gamestate, stop here. diff --git a/src/p_tick.c b/src/p_tick.c index 5857100a3..0f342daf1 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -656,7 +656,7 @@ void P_Ticker(boolean run) ps_lua_mobjhooks = 0; ps_checkposition_calls = 0; - LUA_Hook(PreThinkFrame); + LUA_HOOK(PreThinkFrame); ps_playerthink_time = I_GetPreciseTime(); for (i = 0; i < MAXPLAYERS; i++) @@ -760,7 +760,7 @@ void P_Ticker(boolean run) if (modeattacking) G_GhostTicker(); - LUA_Hook(PostThinkFrame); + LUA_HOOK(PostThinkFrame); } P_MapEnd(); @@ -783,7 +783,7 @@ void P_PreTicker(INT32 frames) { P_MapStart(); - LUA_Hook(PreThinkFrame); + LUA_HOOK(PreThinkFrame); for (i = 0; i < MAXPLAYERS; i++) if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo)) @@ -819,7 +819,7 @@ void P_PreTicker(INT32 frames) P_UpdateSpecials(); P_RespawnSpecials(); - LUA_Hook(PostThinkFrame); + LUA_HOOK(PostThinkFrame); P_MapEnd(); } diff --git a/src/p_user.c b/src/p_user.c index 370a0c1f1..e6bd8e5ec 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1860,7 +1860,7 @@ void P_SpawnShieldOrb(player_t *player) I_Error("P_SpawnShieldOrb: player->mo is NULL!\n"); #endif - if (LUA_HookPlayer(player, Hook(ShieldSpawn))) + if (LUA_HookPlayer(player, HOOK(ShieldSpawn))) return; if (player->powers[pw_shield] & SH_FORCE) @@ -4581,7 +4581,7 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) if (cmd->buttons & BT_SPIN) { - if (LUA_HookPlayer(player, Hook(SpinSpecial))) + if (LUA_HookPlayer(player, HOOK(SpinSpecial))) return; } @@ -5047,7 +5047,7 @@ static boolean P_PlayerShieldThink(player_t *player, ticcmd_t *cmd, mobj_t *lock } } } - if (cmd->buttons & BT_SPIN && !LUA_HookPlayer(player, Hook(ShieldSpecial))) // Spin button effects + if (cmd->buttons & BT_SPIN && !LUA_HookPlayer(player, HOOK(ShieldSpecial))) // Spin button effects { // Force stop if ((player->powers[pw_shield] & ~(SH_FORCEHP|SH_STACK)) == SH_FORCE) @@ -5171,7 +5171,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) // and you don't have a shield, do it! P_DoSuperTransformation(player, false); } - else if (!LUA_HookPlayer(player, Hook(JumpSpinSpecial))) + else if (!LUA_HookPlayer(player, HOOK(JumpSpinSpecial))) switch (player->charability) { case CA_THOK: @@ -5244,7 +5244,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) if (cmd->buttons & BT_JUMP && !player->exiting && !P_PlayerInPain(player)) { - if (LUA_HookPlayer(player, Hook(JumpSpecial))) + if (LUA_HookPlayer(player, HOOK(JumpSpecial))) ; // all situations below this require jump button not to be pressed already else if (player->pflags & PF_JUMPDOWN) @@ -5279,7 +5279,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) }*/ else if (player->pflags & PF_JUMPED) { - if (!LUA_HookPlayer(player, Hook(AbilitySpecial))) + if (!LUA_HookPlayer(player, HOOK(AbilitySpecial))) switch (player->charability) { case CA_THOK: @@ -5472,7 +5472,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) } else if (player->pflags & PF_THOKKED) { - if (!LUA_HookPlayer(player, Hook(AbilitySpecial))) + if (!LUA_HookPlayer(player, HOOK(AbilitySpecial))) switch (player->charability) { case CA_FLY: @@ -11479,7 +11479,7 @@ void P_PlayerThink(player_t *player) } if (player->playerstate == PST_REBORN) { - LUA_HookPlayer(player, Hook(PlayerThink)); + LUA_HookPlayer(player, HOOK(PlayerThink)); return; } } @@ -11583,7 +11583,7 @@ void P_PlayerThink(player_t *player) if (player->playerstate == PST_DEAD) { - LUA_HookPlayer(player, Hook(PlayerThink)); + LUA_HookPlayer(player, HOOK(PlayerThink)); return; } } @@ -11704,7 +11704,7 @@ void P_PlayerThink(player_t *player) { player->mo->flags2 &= ~MF2_SHADOW; P_DeathThink(player); - LUA_HookPlayer(player, Hook(PlayerThink)); + LUA_HookPlayer(player, HOOK(PlayerThink)); return; } @@ -11746,7 +11746,7 @@ void P_PlayerThink(player_t *player) { if (P_SpectatorJoinGame(player)) { - LUA_HookPlayer(player, Hook(PlayerThink)); + LUA_HookPlayer(player, HOOK(PlayerThink)); return; // player->mo was removed. } } @@ -11851,7 +11851,7 @@ void P_PlayerThink(player_t *player) if (!player->mo) { - LUA_HookPlayer(player, Hook(PlayerThink)); + LUA_HookPlayer(player, HOOK(PlayerThink)); return; // P_MovePlayer removed player->mo. } @@ -12305,7 +12305,7 @@ void P_PlayerThink(player_t *player) } #undef dashmode - LUA_HookPlayer(player, Hook(PlayerThink)); + LUA_HookPlayer(player, HOOK(PlayerThink)); /* // Colormap verification diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index f3da446d8..0bdb70d1f 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1057,7 +1057,7 @@ void I_GetEvent(void) M_SetupJoystickMenu(0); break; case SDL_QUIT: - LUA_HookBool(true, Hook(GameQuit)); + LUA_HookBool(true, HOOK(GameQuit)); I_Quit(); break; } diff --git a/src/y_inter.c b/src/y_inter.c index ae4dcdaf0..5930d35ec 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -927,7 +927,7 @@ void Y_Ticker(void) if (paused || P_AutoPause()) return; - LUA_Hook(IntermissionThinker); + LUA_HOOK(IntermissionThinker); intertic++; From c5474436af67408342e8dce0ec996d62c9a4c21c Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 7 Nov 2020 19:47:50 -0500 Subject: [PATCH 153/644] Use FixedHypot over P_AproxDistance Not convinced that the small speed benefit from P_AproxDistance is worth the "aproximate"[sic] results it gives. Let's instead try a define to replace it with FixedHypot. In Lua, the function gives a deprecated warning. Inspired by the hyperwall fix for vanilla, except for everything. From little testing, actively improves waypoint checks, bumping, speed checks, wall collisions, Jawz targetting, Lightning Shield attacks, so on. The only way I see this as a potential downgrade is A_Look (and related functions) getting slower, which are barely used in Kart. --- src/lua_baselib.c | 3 ++- src/p_maputl.c | 13 ------------- src/p_maputl.h | 2 +- 3 files changed, 3 insertions(+), 15 deletions(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 515f6f0ba..7b2e42bd5 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -427,7 +427,8 @@ static int lib_pAproxDistance(lua_State *L) fixed_t dx = luaL_checkfixed(L, 1); fixed_t dy = luaL_checkfixed(L, 2); //HUDSAFE - lua_pushfixed(L, P_AproxDistance(dx, dy)); + LUA_Deprecated(L, "P_AproxDistance", "FixedHypot"); + lua_pushfixed(L, FixedHypot(dx, dy)); return 1; } diff --git a/src/p_maputl.c b/src/p_maputl.c index 90718a41c..83905a418 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -24,19 +24,6 @@ #include "p_slopes.h" #include "z_zone.h" -// -// P_AproxDistance -// Gives an estimation of distance (not exact) -// -fixed_t P_AproxDistance(fixed_t dx, fixed_t dy) -{ - dx = abs(dx); - dy = abs(dy); - if (dx < dy) - return dx + dy - (dx>>1); - return dx + dy - (dy>>1); -} - // // P_ClosestPointOnLine // Finds the closest point on a given line to the supplied point diff --git a/src/p_maputl.h b/src/p_maputl.h index 08b606833..df90ab4b4 100644 --- a/src/p_maputl.h +++ b/src/p_maputl.h @@ -41,7 +41,7 @@ typedef boolean (*traverser_t)(intercept_t *in); boolean P_PathTraverse(fixed_t px1, fixed_t py1, fixed_t px2, fixed_t py2, INT32 pflags, traverser_t ptrav); -FUNCMATH fixed_t P_AproxDistance(fixed_t dx, fixed_t dy); +#define P_AproxDistance(dx, dy) FixedHypot(dx, dy) void P_ClosestPointOnLine(fixed_t x, fixed_t y, line_t *line, vertex_t *result); void P_ClosestPointOnLine3D(const vector3_t *p, const vector3_t *line, vector3_t *result); INT32 P_PointOnLineSide(fixed_t x, fixed_t y, line_t *line); From e19196a86e5347edf7f25b335214cede978b91b8 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 7 Nov 2020 23:56:46 -0500 Subject: [PATCH 154/644] Use R_PointToDist2 instead Apparently overflows less often Actually, lets just fix FixedHypot instead. Now FixedHypot uses the code from R_PointToDist2, and R_PointToDist2 just calls FixedHypot. Ultimately, this branch was intended to get rid of a redundant way to retrieve distance and replace it with the one that was actually good at its job. So consolidating FixedHypot and R_PointToDist2 together is just an extension of that. --- src/m_fixed.c | 40 ++++++++++++++++++++++++++++------------ src/r_main.c | 24 +----------------------- 2 files changed, 29 insertions(+), 35 deletions(-) diff --git a/src/m_fixed.c b/src/m_fixed.c index eb10fd5f8..09d6936f2 100644 --- a/src/m_fixed.c +++ b/src/m_fixed.c @@ -18,8 +18,10 @@ #define HAVE_SQRTF #endif #endif + #include "doomdef.h" #include "m_fixed.h" +#include "tables.h" // ANGLETOFINESHIFT #ifdef __USE_C_FIXEDMUL__ @@ -105,20 +107,34 @@ fixed_t FixedSqrt(fixed_t x) fixed_t FixedHypot(fixed_t x, fixed_t y) { - fixed_t ax, yx, yx2, yx1; - if (abs(y) > abs(x)) // |y|>|x| + // Moved the code from R_PointToDist2 to here, + // since R_PointToDist2 did the same thing, + // except less prone to overflowing. + + angle_t angle; + fixed_t dist; + + x = abs(x); + y = abs(y); + + if (y > x) { - ax = abs(y); // |y| => ax - yx = FixedDiv(x, y); // (x/y) + fixed_t temp; + + temp = x; + x = y; + y = temp; } - else // |x|>|y| - { - ax = abs(x); // |x| => ax - yx = FixedDiv(y, x); // (x/y) - } - yx2 = FixedMul(yx, yx); // (x/y)^2 - yx1 = FixedSqrt(1 * FRACUNIT + yx2); // (1 + (x/y)^2)^1/2 - return FixedMul(ax, yx1); // |x|*((1 + (x/y)^2)^1/2) + + if (!y) + return x; + + angle = (tantoangle[FixedDiv(y, x)>>DBITS] + ANGLE_90) >> ANGLETOFINESHIFT; + + // use as cosine + dist = FixedDiv(x, FINESINE(angle)); + + return dist; } vector2_t *FV2_Load(vector2_t *vec, fixed_t x, fixed_t y) diff --git a/src/r_main.c b/src/r_main.c index f82fb589e..f6c05e312 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -357,29 +357,7 @@ angle_t R_PointToAngle2(fixed_t pviewx, fixed_t pviewy, fixed_t x, fixed_t y) fixed_t R_PointToDist2(fixed_t px2, fixed_t py2, fixed_t px1, fixed_t py1) { - angle_t angle; - fixed_t dx, dy, dist; - - dx = abs(px1 - px2); - dy = abs(py1 - py2); - - if (dy > dx) - { - fixed_t temp; - - temp = dx; - dx = dy; - dy = temp; - } - if (!dy) - return dx; - - angle = (tantoangle[FixedDiv(dy, dx)>>DBITS] + ANGLE_90) >> ANGLETOFINESHIFT; - - // use as cosine - dist = FixedDiv(dx, FINESINE(angle)); - - return dist; + return FixedHypot(px1 - px2, py1 - py2); } // Little extra utility. Works in the same way as R_PointToAngle2 From 75633bde5039106c5f916ca2b4d1bde11d274be9 Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 12 Dec 2020 14:53:54 -0800 Subject: [PATCH 155/644] Replace all instances of P_AproxDistance with FixedHypot --- src/b_bot.c | 10 +-- src/g_game.c | 2 +- src/p_ceilng.c | 4 +- src/p_enemy.c | 172 ++++++++++++++++++++++++------------------------ src/p_floor.c | 10 +-- src/p_inter.c | 20 +++--- src/p_map.c | 10 +-- src/p_maputl.h | 1 - src/p_mobj.c | 78 +++++++++++----------- src/p_polyobj.c | 2 +- src/p_setup.c | 2 +- src/p_slopes.c | 2 +- src/p_spec.c | 58 ++++++++-------- src/p_user.c | 56 ++++++++-------- src/r_things.c | 4 +- src/s_sound.c | 4 +- src/st_stuff.c | 2 +- 17 files changed, 218 insertions(+), 219 deletions(-) diff --git a/src/b_bot.c b/src/b_bot.c index d3635f32c..abe69caeb 100644 --- a/src/b_bot.c +++ b/src/b_bot.c @@ -54,11 +54,11 @@ static void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd) boolean _2d = (tails->flags2 & MF2_TWOD) || twodlevel; fixed_t scale = tails->scale; - fixed_t dist = P_AproxDistance(sonic->x - tails->x, sonic->y - tails->y); + fixed_t dist = FixedHypot(sonic->x - tails->x, sonic->y - tails->y); fixed_t zdist = flip * (sonic->z - tails->z); angle_t ang = sonic->angle; - fixed_t pmom = P_AproxDistance(sonic->momx, sonic->momy); - fixed_t bmom = P_AproxDistance(tails->momx, tails->momy); + fixed_t pmom = FixedHypot(sonic->momx, sonic->momy); + fixed_t bmom = FixedHypot(tails->momx, tails->momy); fixed_t followmax = 128 * 8 * scale; // Max follow distance before AI begins to enter "panic" state fixed_t followthres = 92 * scale; // Distance that AI will try to reach fixed_t followmin = 32 * scale; @@ -81,7 +81,7 @@ static void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd) if (tails->player->powers[pw_carry] == CR_MACESPIN || tails->player->powers[pw_carry] == CR_GENERIC) { boolean isrelevant = (sonic->player->powers[pw_carry] == CR_MACESPIN || sonic->player->powers[pw_carry] == CR_GENERIC); - dist = P_AproxDistance(tails->x-sonic->x, tails->y-sonic->y); + dist = FixedHypot(tails->x-sonic->x, tails->y-sonic->y); if (sonic->player->cmd.buttons & BT_JUMP && (sonic->player->pflags & PF_JUMPED) && isrelevant) cmd->buttons |= BT_JUMP; if (isrelevant) @@ -496,7 +496,7 @@ boolean B_CheckRespawn(player_t *player) } // If you can't see Sonic, I guess we should? - if (!P_CheckSight(sonic, tails) && P_AproxDistance(P_AproxDistance(tails->x-sonic->x, tails->y-sonic->y), tails->z-sonic->z) > FixedMul(1024*FRACUNIT, tails->scale)) + if (!P_CheckSight(sonic, tails) && FixedHypot(FixedHypot(tails->x-sonic->x, tails->y-sonic->y), tails->z-sonic->z) > FixedMul(1024*FRACUNIT, tails->scale)) return true; return false; } diff --git a/src/g_game.c b/src/g_game.c index 6171c7b72..3f8d573c8 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1423,7 +1423,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) newtarget = P_SpawnMobj(ticcmd_ztargetfocus[forplayer]->x, ticcmd_ztargetfocus[forplayer]->y, ticcmd_ztargetfocus[forplayer]->z, MT_LOCKON); // positioning, flip handled in P_SceneryThinker P_SetTarget(&newtarget->target, ticcmd_ztargetfocus[forplayer]); - if (P_AproxDistance( + if (FixedHypot( player->mo->x - ticcmd_ztargetfocus[forplayer]->x, player->mo->y - ticcmd_ztargetfocus[forplayer]->y ) > 50*player->mo->scale) diff --git a/src/p_ceilng.c b/src/p_ceilng.c index f12499d5c..2168d1d78 100644 --- a/src/p_ceilng.c +++ b/src/p_ceilng.c @@ -468,7 +468,7 @@ INT32 EV_DoCeiling(line_t *line, ceiling_e type) // Linedef executor excellence case moveCeilingByFrontSector: - ceiling->speed = P_AproxDistance(line->dx, line->dy); + ceiling->speed = FixedHypot(line->dx, line->dy); ceiling->speed = FixedDiv(ceiling->speed,8*FRACUNIT); if (line->frontsector->ceilingheight >= sec->ceilingheight) // Move up { @@ -547,7 +547,7 @@ INT32 EV_DoCeiling(line_t *line, ceiling_e type) */ case bounceCeiling: - ceiling->speed = P_AproxDistance(line->dx, line->dy); // same speed as elevateContinuous + ceiling->speed = FixedHypot(line->dx, line->dy); // same speed as elevateContinuous ceiling->speed = FixedDiv(ceiling->speed,4*FRACUNIT); ceiling->origspeed = ceiling->speed; if (line->frontsector->ceilingheight >= sec->ceilingheight) // Move up diff --git a/src/p_enemy.c b/src/p_enemy.c index 203e04af1..0d94f2a7e 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -334,7 +334,7 @@ boolean P_CheckMeleeRange(mobj_t *actor) return false; pl = actor->target; - dist = P_AproxDistance(pl->x-actor->x, pl->y-actor->y); + dist = FixedHypot(pl->x-actor->x, pl->y-actor->y); if (dist >= FixedMul(MELEERANGE - 20*FRACUNIT, actor->scale) + pl->radius) return false; @@ -360,7 +360,7 @@ boolean P_JetbCheckMeleeRange(mobj_t *actor) return false; pl = actor->target; - dist = P_AproxDistance(pl->x-actor->x, pl->y-actor->y); + dist = FixedHypot(pl->x-actor->x, pl->y-actor->y); if (dist >= (actor->radius + pl->radius)*2) return false; @@ -389,7 +389,7 @@ boolean P_FaceStabCheckMeleeRange(mobj_t *actor) return false; pl = actor->target; - dist = P_AproxDistance(pl->x-actor->x, pl->y-actor->y); + dist = FixedHypot(pl->x-actor->x, pl->y-actor->y); if (dist >= (actor->radius + pl->radius)*4) return false; @@ -413,7 +413,7 @@ boolean P_SkimCheckMeleeRange(mobj_t *actor) return false; pl = actor->target; - dist = P_AproxDistance(pl->x-actor->x, pl->y-actor->y); + dist = FixedHypot(pl->x-actor->x, pl->y-actor->y); if (dist >= FixedMul(MELEERANGE - 20*FRACUNIT, actor->scale) + pl->radius) return false; @@ -449,7 +449,7 @@ boolean P_CheckMissileRange(mobj_t *actor) return false; // OPTIMIZE: get this from a global checksight - dist = P_AproxDistance(actor->x-actor->target->x, actor->y-actor->target->y) - FixedMul(64*FRACUNIT, actor->scale); + dist = FixedHypot(actor->x-actor->target->x, actor->y-actor->target->y) - FixedMul(64*FRACUNIT, actor->scale); if (!actor->info->meleestate) dist -= FixedMul(128*FRACUNIT, actor->scale); // no melee attack, so fire more @@ -750,7 +750,7 @@ boolean P_LookForPlayers(mobj_t *actor, boolean allaround, boolean tracer, fixed continue; // Ignore uncontrolled bodies if (dist > 0 - && P_AproxDistance(P_AproxDistance(player->mo->x - actor->x, player->mo->y - actor->y), player->mo->z - actor->z) > dist) + && FixedHypot(FixedHypot(player->mo->x - actor->x, player->mo->y - actor->y), player->mo->z - actor->z) > dist) continue; // Too far away if (!allaround) @@ -758,7 +758,7 @@ boolean P_LookForPlayers(mobj_t *actor, boolean allaround, boolean tracer, fixed 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); + dist = FixedHypot(player->mo->x - actor->x, player->mo->y - actor->y); // if real close, react anyway if (dist > FixedMul(MELEERANGE, actor->scale)) continue; // behind back @@ -821,7 +821,7 @@ static boolean P_LookForShield(mobj_t *actor) continue; if ((player->powers[pw_shield] & SH_PROTECTELECTRIC) - && (P_AproxDistance(P_AproxDistance(actor->x-player->mo->x, actor->y-player->mo->y), actor->z-player->mo->z) < FixedMul(RING_DIST, player->mo->scale))) + && (FixedHypot(FixedHypot(actor->x-player->mo->x, actor->y-player->mo->y), actor->z-player->mo->z) < FixedMul(RING_DIST, player->mo->scale))) { P_SetTarget(&actor->tracer, player->mo); @@ -1548,8 +1548,8 @@ void A_PointyThink(mobj_t *actor) } else { - if (P_AproxDistance(players[i].mo->x - actor->x, players[i].mo->y - actor->y) < - P_AproxDistance(player->mo->x - actor->x, player->mo->y - actor->y)) + if (FixedHypot(players[i].mo->x - actor->x, players[i].mo->y - actor->y) < + FixedHypot(player->mo->x - actor->x, player->mo->y - actor->y)) player = &players[i]; } } @@ -1561,7 +1561,7 @@ void A_PointyThink(mobj_t *actor) P_SetTarget(&actor->target, player->mo); A_FaceTarget(actor); - if (P_AproxDistance(player->mo->x - actor->x, player->mo->y - actor->y) < P_AproxDistance(player->mo->x + player->mo->momx - actor->x, player->mo->y + player->mo->momy - actor->y)) + if (FixedHypot(player->mo->x - actor->x, player->mo->y - actor->y) < FixedHypot(player->mo->x + player->mo->momx - actor->x, player->mo->y + player->mo->momy - actor->y)) sign = -1; // Player is moving away else sign = 1; // Player is moving closer @@ -1638,7 +1638,7 @@ static void P_ParabolicMove(mobj_t *actor, fixed_t x, fixed_t y, fixed_t z, fixe y -= actor->y; z -= actor->z; - dh = P_AproxDistance(x, y); + dh = FixedHypot(x, y); actor->momx = FixedMul(FixedDiv(x, dh), speed); actor->momy = FixedMul(FixedDiv(y, dh), speed); @@ -1706,7 +1706,7 @@ void A_HoodThink(mobj_t *actor) } dx = (actor->target->x - actor->x), dy = (actor->target->y - actor->y), dz = (actor->target->z - actor->z); - dm = P_AproxDistance(dx, dy); + dm = FixedHypot(dx, dy); // Target dangerously close to robohood, retreat then. if ((dm < 256<target || !crab->info->missilestate || (statenum_t)(crab->state-states) == crab->info->missilestate) return; - if (((ang + ANG1) < ANG2) || P_AproxDistance(crab->x - crab->target->x, crab->y - crab->target->y) < 333*crab->scale) + if (((ang + ANG1) < ANG2) || FixedHypot(crab->x - crab->target->x, crab->y - crab->target->y) < 333*crab->scale) P_SetMobjState(crab, crab->info->missilestate); } @@ -2703,7 +2703,7 @@ void A_LobShot(mobj_t *actor) shot->angle = an = actor->angle; an >>= ANGLETOFINESHIFT; - dist = P_AproxDistance(actor->target->x - shot->x, actor->target->y - shot->y); + dist = FixedHypot(actor->target->x - shot->x, actor->target->y - shot->y); horizontal = dist / airtime; vertical = FixedMul((gravity*airtime)/2, shot->scale); @@ -2721,7 +2721,7 @@ void A_LobShot(mobj_t *actor) diff = actor->z - actor->target->z; { - launchhyp = P_AproxDistance(horizontal, vertical); + launchhyp = FixedHypot(horizontal, vertical); orig = FixedMul(FixedDiv(vertical, horizontal), diff); @@ -3325,7 +3325,7 @@ void A_SkullAttack(mobj_t *actor) S_StartSound(actor, actor->info->activesound); A_FaceTarget(actor); - dist = P_AproxDistance(dest->x - actor->x, dest->y - actor->y); + dist = FixedHypot(dest->x - actor->x, dest->y - actor->y); if (locvar1 == 1) actor->angle += ANGLE_180; @@ -3443,7 +3443,7 @@ void A_BossZoom(mobj_t *actor) an = actor->angle >> ANGLETOFINESHIFT; actor->momx = FixedMul(FixedMul(actor->info->speed*5*FRACUNIT, actor->scale), FINECOSINE(an)); actor->momy = FixedMul(FixedMul(actor->info->speed*5*FRACUNIT, actor->scale), FINESINE(an)); - dist = P_AproxDistance(dest->x - actor->x, dest->y - actor->y); + dist = FixedHypot(dest->x - actor->x, dest->y - actor->y); dist = dist / FixedMul(actor->info->speed*5*FRACUNIT, actor->scale); if (dist < 1) @@ -3599,7 +3599,7 @@ void A_1upThinker(mobj_t *actor) if ((netgame || multiplayer) && players[i].playerstate != PST_LIVE) continue; - temp = P_AproxDistance(players[i].mo->x-actor->x, players[i].mo->y-actor->y); + temp = FixedHypot(players[i].mo->x-actor->x, players[i].mo->y-actor->y); if (temp < dist) { @@ -4144,8 +4144,8 @@ bossjustdie: // If this one's further then the last one, don't go for it. if (mo->target && - P_AproxDistance(P_AproxDistance(mo->x - mo2->x, mo->y - mo2->y), mo->z - mo2->z) > - P_AproxDistance(P_AproxDistance(mo->x - mo->target->x, mo->y - mo->target->y), mo->z - mo->target->z)) + FixedHypot(FixedHypot(mo->x - mo2->x, mo->y - mo2->y), mo->z - mo2->z) > + FixedHypot(FixedHypot(mo->x - mo->target->x, mo->y - mo->target->y), mo->z - mo->target->z)) continue; // Otherwise... Do! @@ -4536,7 +4536,7 @@ void A_BubbleSpawn(mobj_t *actor) // Don't spawn bubbles unless a player is relatively close by (var1). for (i = 0; i < MAXPLAYERS; ++i) if (playeringame[i] && players[i].mo - && P_AproxDistance(actor->x - players[i].mo->x, actor->y - players[i].mo->y) < (locvar1<x - players[i].mo->x, actor->y - players[i].mo->y) < (locvar1<x - players[i].mo->x, actor->y - players[i].mo->y) < (locvar1<x - players[i].mo->x, actor->y - players[i].mo->y) < (locvar1<x-target->x, actor->y-target->y)>>FRACBITS; + dist = FixedHypot(actor->x-target->x, actor->y-target->y)>>FRACBITS; if (dist > FixedMul((locvar2 & 65535), actor->scale)) return; @@ -4800,7 +4800,7 @@ void A_FishJump(mobj_t *actor) // Don't spawn trail unless a player is nearby. for (i = 0; i < MAXPLAYERS; ++i) if (playeringame[i] && players[i].mo - && P_AproxDistance(actor->x - players[i].mo->x, actor->y - players[i].mo->y) < (actor->info->speed)) + && FixedHypot(actor->x - players[i].mo->x, actor->y - players[i].mo->y) < (actor->info->speed)) break; // Stop looking. if (i < MAXPLAYERS) { @@ -4905,7 +4905,7 @@ void A_ThrownRing(mobj_t *actor) // magnetic player. If he gets too far away, make // sure to stop the attraction! if ((!actor->tracer->health) || (actor->tracer->player && (actor->tracer->player->powers[pw_shield] & SH_PROTECTELECTRIC) - && P_AproxDistance(P_AproxDistance(actor->tracer->x-actor->x, + && FixedHypot(FixedHypot(actor->tracer->x-actor->x, actor->tracer->y-actor->y), actor->tracer->z-actor->z) > FixedMul(RING_DIST/4, actor->tracer->scale))) { P_SetTarget(&actor->tracer, NULL); @@ -4964,7 +4964,7 @@ void A_ThrownRing(mobj_t *actor) continue; } - dist = P_AproxDistance(P_AproxDistance(player->mo->x-actor->x, + dist = FixedHypot(FixedHypot(player->mo->x-actor->x, player->mo->y-actor->y), player->mo->z-actor->z); // check distance @@ -5345,7 +5345,7 @@ void A_JetChase(mobj_t *actor) return; // got a new target // If the player is over 3072 fracunits away, then look for another player - if (P_AproxDistance(P_AproxDistance(actor->target->x - actor->x, actor->target->y - actor->y), + if (FixedHypot(FixedHypot(actor->target->x - actor->x, actor->target->y - actor->y), actor->target->z - actor->z) > FixedMul(3072*FRACUNIT, actor->scale) && P_LookForPlayers(actor, true, false, FixedMul(3072*FRACUNIT, actor->scale))) { return; // got a new target @@ -5460,7 +5460,7 @@ void A_JetgShoot(mobj_t *actor) if (actor->reactiontime) return; - dist = P_AproxDistance(actor->target->x - actor->x, actor->target->y - actor->y); + dist = FixedHypot(actor->target->x - actor->x, actor->target->y - actor->y); if (dist > FixedMul(actor->info->painchance*FRACUNIT, actor->scale)) return; @@ -5497,7 +5497,7 @@ void A_ShootBullet(mobj_t *actor) if (!actor->target) return; - dist = P_AproxDistance(P_AproxDistance(actor->target->x - actor->x, actor->target->y - actor->y), actor->target->z - actor->z); + dist = FixedHypot(FixedHypot(actor->target->x - actor->x, actor->target->y - actor->y), actor->target->z - actor->z); if (dist > FixedMul(actor->info->painchance*FRACUNIT, actor->scale)) return; @@ -5522,7 +5522,7 @@ static boolean PIT_MinusCarry(mobj_t *thing) if (!(thing->flags & (MF_PUSHABLE|MF_ENEMY))) return true; - if (P_AproxDistance(minus->x - thing->x, minus->y - thing->y) >= minus->radius*3) + if (FixedHypot(minus->x - thing->x, minus->y - thing->y) >= minus->radius*3) return true; if (abs(thing->z - minus->z) > minus->height) @@ -5566,7 +5566,7 @@ void A_MinusDigging(mobj_t *actor) P_TryMove(par, x, y, false); // If close enough, prepare to attack - if (P_AproxDistance(actor->x - actor->target->x, actor->y - actor->target->y) < actor->radius*2) + if (FixedHypot(actor->x - actor->target->x, actor->y - actor->target->y) < actor->radius*2) { P_SetMobjState(actor, actor->info->meleestate); P_TryMove(actor, actor->target->x, actor->target->y, false); @@ -5858,7 +5858,7 @@ void A_DetonChase(mobj_t *actor) } }*/ // movedir is up/down angle: how much it has to go up as it goes over to the player - xydist = P_AproxDistance(actor->tracer->x - actor->x, actor->tracer->y - actor->y); + xydist = FixedHypot(actor->tracer->x - actor->x, actor->tracer->y - actor->y); exact = R_PointToAngle2(0, 0, xydist, actor->tracer->z - actor->z); actor->movedir = exact; /*if (exact != actor->movedir) @@ -5880,7 +5880,7 @@ void A_DetonChase(mobj_t *actor) // check for melee attack if (actor->tracer) { - if (P_AproxDistance(actor->tracer->x-actor->x, actor->tracer->y-actor->y) < actor->radius+actor->tracer->radius) + if (FixedHypot(actor->tracer->x-actor->x, actor->tracer->y-actor->y) < actor->radius+actor->tracer->radius) { if (!((actor->tracer->z > actor->z + actor->height) || (actor->z > actor->tracer->z + actor->tracer->height))) { @@ -5891,7 +5891,7 @@ void A_DetonChase(mobj_t *actor) } // chase towards player - if ((dist = P_AproxDistance(xydist, actor->tracer->z-actor->z)) + if ((dist = FixedHypot(xydist, actor->tracer->z-actor->z)) > FixedMul((actor->info->painchance << FRACBITS), actor->scale)) { P_SetTarget(&actor->tracer, NULL); // Too far away @@ -5933,7 +5933,7 @@ void A_DetonChase(mobj_t *actor) actor->momy = FixedMul(xyspeed, FINESINE(exact)); // Variable re-use - xyspeed = (P_AproxDistance(actor->tracer->x - actor->x, P_AproxDistance(actor->tracer->y - actor->y, actor->tracer->z - actor->z))>>(FRACBITS+6)); + xyspeed = (FixedHypot(actor->tracer->x - actor->x, FixedHypot(actor->tracer->y - actor->y, actor->tracer->z - actor->z))>>(FRACBITS+6)); if (xyspeed < 1) xyspeed = 1; @@ -6081,7 +6081,7 @@ void A_UnidusBall(mobj_t *actor) if (actor->movecount) { - if (P_AproxDistance(actor->momx, actor->momy) < FixedMul(actor->info->damage/2, actor->scale)) + if (FixedHypot(actor->momx, actor->momy) < FixedMul(actor->info->damage/2, actor->scale)) P_ExplodeMissile(actor); return; } @@ -6113,7 +6113,7 @@ void A_UnidusBall(mobj_t *actor) if (locvar1 == 1 && canthrow) { - if (P_AproxDistance(actor->target->target->x - actor->target->x, actor->target->target->y - actor->target->y) > FixedMul(MISSILERANGE>>1, actor->scale) + if (FixedHypot(actor->target->target->x - actor->target->x, actor->target->target->y - actor->target->y) > FixedMul(MISSILERANGE>>1, actor->scale) || !P_CheckSight(actor, actor->target->target)) return; @@ -6188,7 +6188,7 @@ void A_RockSpawn(mobj_t *actor) return; } - dist = P_AproxDistance(line->dx, line->dy)/16; + dist = FixedHypot(line->dx, line->dy)/16; if (dist < 1) dist = 1; @@ -6354,7 +6354,7 @@ void A_CrawlaCommanderThink(mobj_t *actor) return; } - dist = P_AproxDistance(actor->x - actor->target->x, actor->y - actor->target->y); + dist = FixedHypot(actor->x - actor->target->x, actor->y - actor->target->y); if (actor->target->player && (!hovermode || actor->reactiontime <= 2*TICRATE)) { @@ -6391,7 +6391,7 @@ void A_CrawlaCommanderThink(mobj_t *actor) { fixed_t mom; P_Thrust(actor, actor->angle, 2*actor->scale); - mom = P_AproxDistance(actor->momx, actor->momy); + mom = FixedHypot(actor->momx, actor->momy); if (mom > 20*actor->scale) { mom += 20*actor->scale; @@ -6479,7 +6479,7 @@ void A_RingExplode(mobj_t *actor) if (mo2 == actor) // Don't explode yourself! Endless loop! continue; - if (P_AproxDistance(P_AproxDistance(mo2->x - actor->x, mo2->y - actor->y), mo2->z - actor->z) > FixedMul(actor->info->painchance, actor->scale)) + if (FixedHypot(FixedHypot(mo2->x - actor->x, mo2->y - actor->y), mo2->z - actor->z) > FixedMul(actor->info->painchance, actor->scale)) continue; if (mo2->flags & MF_SHOOTABLE) @@ -7078,7 +7078,7 @@ nomissile: } // chase towards player - if (P_AproxDistance(actor->target->x-actor->x, actor->target->y-actor->y) > actor->radius+actor->target->radius) + if (FixedHypot(actor->target->x-actor->x, actor->target->y-actor->y) > actor->radius+actor->target->radius) { if (--actor->movecount < 0 || !P_Move(actor, actor->info->speed)) P_NewChaseDir(actor); @@ -7317,7 +7317,7 @@ void A_Boss7Chase(mobj_t *actor) // Self-adjust if stuck on the edge if (actor->tracer) { - if (P_AproxDistance(actor->x - actor->tracer->x, actor->y - actor->tracer->y) > 128*FRACUNIT - actor->radius) + if (FixedHypot(actor->x - actor->tracer->x, actor->y - actor->tracer->y) > 128*FRACUNIT - actor->radius) P_InstaThrust(actor, R_PointToAngle2(actor->x, actor->y, actor->tracer->x, actor->tracer->y), FRACUNIT); } @@ -7353,7 +7353,7 @@ void A_Boss7Chase(mobj_t *actor) if (players[i].mo->health <= 0) continue; - if (P_AproxDistance(players[i].mo->x - actor->x, players[i].mo->y - actor->y) > actor->radius) + if (FixedHypot(players[i].mo->x - actor->x, players[i].mo->y - actor->y) > actor->radius) continue; if (players[i].mo->z > actor->z + actor->height - 2*FRACUNIT @@ -7476,7 +7476,7 @@ void A_Boss2PogoSFX(mobj_t *actor) } // Boing! - if (P_AproxDistance(actor->x-actor->target->x, actor->y-actor->target->y) < FixedMul(256*FRACUNIT, actor->scale)) + if (FixedHypot(actor->x-actor->target->x, actor->y-actor->target->y) < FixedMul(256*FRACUNIT, actor->scale)) { actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y); P_InstaThrust(actor, actor->angle, FixedMul(actor->info->speed, actor->scale)); @@ -7509,7 +7509,7 @@ void A_Boss2PogoTarget(mobj_t *actor) return; if (!actor->target || !(actor->target->flags & MF_SHOOTABLE) || (actor->target->player && actor->target->player->powers[pw_flashing]) - || P_AproxDistance(actor->x-actor->target->x, actor->y-actor->target->y) >= FixedMul(512*FRACUNIT, actor->scale)) + || FixedHypot(actor->x-actor->target->x, actor->y-actor->target->y) >= FixedMul(512*FRACUNIT, actor->scale)) { // look for a new target if (P_LookForPlayers(actor, true, false, 512*FRACUNIT)) @@ -7530,7 +7530,7 @@ void A_Boss2PogoTarget(mobj_t *actor) P_InstaThrust(actor, actor->angle+ANGLE_180, FixedMul(FixedMul(actor->info->speed,(locvar2)), actor->scale)); // Move at wandering speed } // Try to land on top of the player. - else if (P_AproxDistance(actor->x-actor->target->x, actor->y-actor->target->y) < FixedMul(512*FRACUNIT, actor->scale)) + else if (FixedHypot(actor->x-actor->target->x, actor->y-actor->target->y) < FixedMul(512*FRACUNIT, actor->scale)) { fixed_t airtime, gravityadd, zoffs; @@ -7558,7 +7558,7 @@ void A_Boss2PogoTarget(mobj_t *actor) airtime = FixedDiv((-actor->momz - FixedSqrt(FixedMul(actor->momz,actor->momz)+zoffs)), gravityadd)<<1; // to try and land on their head rather than on their feet actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y); - P_InstaThrust(actor, actor->angle, FixedDiv(P_AproxDistance(actor->x - actor->target->x, actor->y - actor->target->y), airtime)); + P_InstaThrust(actor, actor->angle, FixedDiv(FixedHypot(actor->x - actor->target->x, actor->y - actor->target->y), airtime)); } // Wander semi-randomly towards the player to get closer. else @@ -7629,7 +7629,7 @@ void A_TurretFire(mobj_t *actor) while (P_SupermanLook4Players(actor) && count < MAXPLAYERS) { - if (P_AproxDistance(actor->x - actor->target->x, actor->y - actor->target->y) < dist) + if (FixedHypot(actor->x - actor->target->x, actor->y - actor->target->y) < dist) { actor->flags2 |= MF2_FIRING; actor->extravalue1 = locvar1; @@ -7667,7 +7667,7 @@ void A_SuperTurretFire(mobj_t *actor) while (P_SupermanLook4Players(actor) && count < MAXPLAYERS) { - if (P_AproxDistance(actor->x - actor->target->x, actor->y - actor->target->y) < dist) + if (FixedHypot(actor->x - actor->target->x, actor->y - actor->target->y) < dist) { actor->flags2 |= MF2_FIRING; actor->flags2 |= MF2_SUPERFIRE; @@ -7788,7 +7788,7 @@ void A_BuzzFly(mobj_t *actor) } // If the player is over 3072 fracunits away, then look for another player - if (P_AproxDistance(P_AproxDistance(actor->target->x - actor->x, actor->target->y - actor->y), + if (FixedHypot(FixedHypot(actor->target->x - actor->x, actor->target->y - actor->y), actor->target->z - actor->z) > FixedMul(3072*FRACUNIT, actor->scale)) { if (multiplayer || netgame) @@ -7807,7 +7807,7 @@ void A_BuzzFly(mobj_t *actor) else realspeed = FixedMul(actor->info->speed, actor->scale); - dist = P_AproxDistance(P_AproxDistance(actor->target->x - actor->x, + dist = FixedHypot(FixedHypot(actor->target->x - actor->x, actor->target->y - actor->y), actor->target->z - actor->z); if (dist < 1) @@ -8165,7 +8165,7 @@ void A_Boss3Path(mobj_t *actor) if (actor->target->x == actor->x && actor->target->y == actor->y) { - dist = P_AproxDistance(P_AproxDistance(actor->target->x - actor->x, actor->target->y - actor->y), actor->target->z + actor->movefactor - actor->z); + dist = FixedHypot(FixedHypot(actor->target->x - actor->x, actor->target->y - actor->y), actor->target->z + actor->movefactor - actor->z); if (dist < 1) dist = 1; @@ -9575,7 +9575,7 @@ void A_SetObjectTypeState(mobj_t *actor) if (mo2->type == (mobjtype_t)loc2lw) { - dist = P_AproxDistance(mo2->x - actor->x, mo2->y - actor->y); + dist = FixedHypot(mo2->x - actor->x, mo2->y - actor->y); if (mo2->health > 0) { @@ -10081,9 +10081,9 @@ void A_CheckRange(mobj_t *actor) return; if (!(locvar1 >> 16)) //target - dist = P_AproxDistance(actor->target->x - actor->x, actor->target->y - actor->y); + dist = FixedHypot(actor->target->x - actor->x, actor->target->y - actor->y); else //tracer - dist = P_AproxDistance(actor->tracer->x - actor->x, actor->tracer->y - actor->y); + dist = FixedHypot(actor->tracer->x - actor->x, actor->tracer->y - actor->y); if (dist <= FixedMul((locvar1 & 65535)*FRACUNIT, actor->scale)) P_SetMobjState(actor, locvar2); @@ -10145,16 +10145,16 @@ void A_CheckTrueRange(mobj_t *actor) if (!(locvar1 >> 16)) // target { height = actor->target->z - actor->z; - dist = P_AproxDistance(actor->target->x - actor->x, actor->target->y - actor->y); + dist = FixedHypot(actor->target->x - actor->x, actor->target->y - actor->y); } else // tracer { height = actor->tracer->z - actor->z; - dist = P_AproxDistance(actor->tracer->x - actor->x, actor->tracer->y - actor->y); + dist = FixedHypot(actor->tracer->x - actor->x, actor->tracer->y - actor->y); } - l = P_AproxDistance(dist, height); + l = FixedHypot(dist, height); if (l <= FixedMul((locvar1 & 65535)*FRACUNIT, actor->scale)) P_SetMobjState(actor, locvar2); @@ -10199,7 +10199,7 @@ void A_CheckThingCount(mobj_t *actor) if (mo2->type == (mobjtype_t)loc1up) { - dist = P_AproxDistance(mo2->x - actor->x, mo2->y - actor->y); + dist = FixedHypot(mo2->x - actor->x, mo2->y - actor->y); if (loc2up == 0) count++; @@ -10808,7 +10808,7 @@ void A_HomingChase(mobj_t *actor) actor->angle = R_PointToAngle2(actor->x, actor->y, dest->x, dest->y); - dist = P_AproxDistance(P_AproxDistance(dest->x - actor->x, dest->y - actor->y), dest->z - actor->z); + dist = FixedHypot(FixedHypot(dest->x - actor->x, dest->y - actor->y), dest->z - actor->z); if (dist < 1) dist = 1; @@ -11394,14 +11394,14 @@ void A_BrakLobShot(mobj_t *actor) g = gravity; // Look up distance between actor and its target - x = P_AproxDistance(actor->target->x - actor->x, actor->target->y - actor->y); + x = FixedHypot(actor->target->x - actor->x, actor->target->y - actor->y); if (!aimDirect) { // Distance should actually be a third of the way over x = FixedDiv(x, 3<x + P_ReturnThrustX(actor, actor->angle, x); newTargetY = actor->y + P_ReturnThrustY(actor, actor->angle, x); - x = P_AproxDistance(newTargetX - actor->x, newTargetY - actor->y); + x = FixedHypot(newTargetX - actor->x, newTargetY - actor->y); // Look up height difference between actor and the ground 1/3 of the way to its target y = P_FloorzAtPos(newTargetX, newTargetY, actor->target->z, actor->target->height) - (actor->z + FixedMul(locvar2*FRACUNIT, actor->scale)); } @@ -11753,7 +11753,7 @@ void A_FlickyCenter(mobj_t *actor) P_LookForPlayers(actor, true, false, actor->extravalue1); - if (actor->target && P_AproxDistance(actor->target->x - originx, actor->target->y - originy) < actor->extravalue1) + if (actor->target && FixedHypot(actor->target->x - originx, actor->target->y - originy) < actor->extravalue1) { actor->extravalue2 = 1; P_TeleportMove(actor, actor->target->x, actor->target->y, actor->target->z); @@ -11809,7 +11809,7 @@ void A_FlickyAim(mobj_t *actor) if ((actor->momx == actor->momy && actor->momy == 0) || (actor->target && P_IsFlickyCenter(actor->target->type) && actor->target->extravalue1 && (actor->target->flags & MF_SLIDEME) - && P_AproxDistance(actor->x - actor->target->x, actor->y - actor->target->y) >= actor->target->extravalue1)) + && FixedHypot(actor->x - actor->target->x, actor->y - actor->target->y) >= actor->target->extravalue1)) flickyhitwall = true; P_InternalFlickyBubble(actor); @@ -11831,12 +11831,12 @@ void A_FlickyAim(mobj_t *actor) actor->movedir *= -1; posvar = ((R_PointToAngle2(actor->target->x, actor->target->y, actor->x, actor->y) + actor->movedir*locvar1) >> ANGLETOFINESHIFT) & FINEMASK; - chasevar = FixedSqrt(max(FRACUNIT, P_AproxDistance(actor->target->x - actor->x, actor->target->y - actor->y) - locvar2)) + locvar2; + chasevar = FixedSqrt(max(FRACUNIT, FixedHypot(actor->target->x - actor->x, actor->target->y - actor->y) - locvar2)) + locvar2; chasex = actor->target->x + FixedMul(FINECOSINE(posvar), chasevar); chasey = actor->target->y + FixedMul(FINESINE(posvar), chasevar); - if (P_AproxDistance(chasex - actor->x, chasey - actor->y)) + if (FixedHypot(chasex - actor->x, chasey - actor->y)) actor->angle = R_PointToAngle2(actor->x, actor->y, chasex, chasey); } else if (flickyhitwall) @@ -11878,7 +11878,7 @@ void P_InternalFlickyFly(mobj_t *actor, fixed_t flyspeed, fixed_t targetdist, fi targetdist = 16*FRACUNIT; //Default! if (actor->target && abs(chasez - actor->z) > targetdist) - targetdist = P_AproxDistance(actor->target->x - actor->x, actor->target->y - actor->y); + targetdist = FixedHypot(actor->target->x - actor->x, actor->target->y - actor->y); if (actor->target && P_IsFlickyCenter(actor->target->type) @@ -11956,7 +11956,7 @@ void A_FlickyCoast(mobj_t *actor) actor->momy = (11*actor->momy)/12; actor->momz = (11*actor->momz)/12; - if (P_AproxDistance(P_AproxDistance(actor->momx, actor->momy), actor->momz) < locvar1) + if (FixedHypot(FixedHypot(actor->momx, actor->momy), actor->momz) < locvar1) P_SetMobjState(actor, locvar2); return; @@ -12220,7 +12220,7 @@ void A_Boss5Jump(mobj_t *actor) g = gravity; // Look up distance between actor and its tracer - x = P_AproxDistance(actor->tracer->x - actor->x, actor->tracer->y - actor->y); + x = FixedHypot(actor->tracer->x - actor->x, actor->tracer->y - actor->y); // Look up height difference between actor and its tracer y = actor->tracer->z - actor->z; @@ -12341,7 +12341,7 @@ void A_MineExplode(mobj_t *actor) actor->z+P_RandomRange(((actor->eflags & MFE_UNDERWATER) ? -dist : 0), dist)*FRACUNIT, type); fixed_t dx = b->x - actor->x, dy = b->y - actor->y, dz = b->z - actor->z; - fixed_t dm = P_AproxDistance(dz, P_AproxDistance(dy, dx)); + fixed_t dm = FixedHypot(dz, FixedHypot(dy, dx)); b->momx = FixedDiv(dx, dm)*3; b->momy = FixedDiv(dy, dm)*3; b->momz = FixedDiv(dz, dm)*3; @@ -12373,7 +12373,7 @@ void A_MineRange(mobj_t *actor) if (!actor->target) return; - dm = P_AproxDistance(actor->z - actor->target->z, P_AproxDistance(actor->y - actor->target->y, actor->x - actor->target->x)); + dm = FixedHypot(actor->z - actor->target->z, FixedHypot(actor->y - actor->target->y, actor->x - actor->target->x)); if ((dm>>FRACBITS) < locvar1) P_SetMobjState(actor, actor->info->meleestate); } @@ -12499,7 +12499,7 @@ void A_MultiShotDist(mobj_t *actor) // Don't spawn dust unless a player is relatively close by (var1). for (i = 0; i < MAXPLAYERS; ++i) if (playeringame[i] && players[i].mo - && P_AproxDistance(actor->x - players[i].mo->x, actor->y - players[i].mo->y) < (1600<x - players[i].mo->x, actor->y - players[i].mo->y) < (1600<tracer && - P_AproxDistance(P_AproxDistance(actor->x - mo2->x, actor->y - mo2->y), actor->z - mo2->z) > - P_AproxDistance(P_AproxDistance(actor->x - actor->tracer->x, actor->y - actor->tracer->y), actor->z - actor->tracer->z)) + FixedHypot(FixedHypot(actor->x - mo2->x, actor->y - mo2->y), actor->z - mo2->z) > + FixedHypot(FixedHypot(actor->x - actor->tracer->x, actor->y - actor->tracer->y), actor->z - actor->tracer->z)) continue; // Otherwise... Do! @@ -13047,7 +13047,7 @@ void A_Boss5CheckOnGround(mobj_t *actor) P_SetMobjState(actor, locvar1); } - if (actor->tracer && P_AproxDistance(actor->tracer->x - actor->x, actor->tracer->y - actor->y) < 2*actor->radius) + if (actor->tracer && FixedHypot(actor->tracer->x - actor->x, actor->tracer->y - actor->y) < 2*actor->radius) { actor->momx = (4*actor->momx)/5; actor->momy = (4*actor->momy)/5; @@ -13507,7 +13507,7 @@ static boolean PIT_TNTExplode(mobj_t *nearby) dx = nearby->x - barrel->x; dy = nearby->y - barrel->y; dz = nearby->z - barrel->z + (nearby->height - barrel->height/2)/2; - dm = P_AproxDistance(P_AproxDistance(dx, dy), dz); + dm = FixedHypot(FixedHypot(dx, dy), dz); if (dm >= exploderadius || !P_CheckSight(barrel, nearby)) // out of range or not visible return true; @@ -13910,7 +13910,7 @@ void A_SnapperThinker(mobj_t *actor) // Look for nearby, valid players to chase angrily at. if ((actor->target || P_LookForPlayers(actor, true, false, 1024*FRACUNIT)) - && P_AproxDistance(actor->target->x - xs, actor->target->y - ys) < 2048*FRACUNIT + && FixedHypot(actor->target->x - xs, actor->target->y - ys) < 2048*FRACUNIT && abs(actor->target->z - actor->z) < 80*FRACUNIT && P_CheckSight(actor, actor->target)) { @@ -13925,7 +13925,7 @@ void A_SnapperThinker(mobj_t *actor) y1 = ys; } - dist = P_AproxDistance(x1 - x0, y1 - y0); + dist = FixedHypot(x1 - x0, y1 - y0); // The snapper either chases what it considers to be a nearby player, or instead decides to go back to its spawnpoint. if (chasing || dist > 32*FRACUNIT) @@ -14110,7 +14110,7 @@ void A_LavafallRocks(mobj_t *actor) // Don't spawn rocks unless a player is relatively close by. for (i = 0; i < MAXPLAYERS; ++i) if (playeringame[i] && players[i].mo - && P_AproxDistance(actor->x - players[i].mo->x, actor->y - players[i].mo->y) < (actor->info->speed >> 1)) + && FixedHypot(actor->x - players[i].mo->x, actor->y - players[i].mo->y) < (actor->info->speed >> 1)) break; // Stop looking. if (i < MAXPLAYERS) @@ -14144,7 +14144,7 @@ void A_LavafallLava(mobj_t *actor) // Don't spawn lava unless a player is nearby. for (i = 0; i < MAXPLAYERS; ++i) if (playeringame[i] && players[i].mo - && P_AproxDistance(actor->x - players[i].mo->x, actor->y - players[i].mo->y) < (actor->info->speed)) + && FixedHypot(actor->x - players[i].mo->x, actor->y - players[i].mo->y) < (actor->info->speed)) break; // Stop looking. if (i >= MAXPLAYERS) @@ -14274,7 +14274,7 @@ void A_RolloutSpawn(mobj_t *actor) if (!(actor->target) || P_MobjWasRemoved(actor->target) - || P_AproxDistance(actor->x - actor->target->x, actor->y - actor->target->y) > locvar1) + || FixedHypot(actor->x - actor->target->x, actor->y - actor->target->y) > locvar1) { actor->target = P_SpawnMobj(actor->x, actor->y, actor->z, locvar2); actor->target->flags2 |= (actor->flags2 & (MF2_AMBUSH | MF2_OBJECTFLIP)) | MF2_SLIDEPUSH; @@ -14302,7 +14302,7 @@ void A_RolloutRock(mobj_t *actor) UINT8 maxframes = actor->info->reactiontime; // number of frames the mobj cycles through fixed_t pi = (22*FRACUNIT/7); fixed_t circumference = FixedMul(2 * pi, actor->radius); // used to calculate when to change frame - fixed_t speed = P_AproxDistance(actor->momx, actor->momy), topspeed = FixedMul(actor->info->speed, actor->scale); + fixed_t speed = FixedHypot(actor->momx, actor->momy), topspeed = FixedMul(actor->info->speed, actor->scale); boolean inwater = actor->eflags & (MFE_TOUCHWATER|MFE_UNDERWATER); if (LUA_CallAction(A_ROLLOUTROCK, actor)) @@ -14344,7 +14344,7 @@ void A_RolloutRock(mobj_t *actor) actor->momy = FixedMul(actor->momy, locvar1); } - speed = P_AproxDistance(actor->momx, actor->momy); // recalculate speed for visual rolling + speed = FixedHypot(actor->momx, actor->momy); // recalculate speed for visual rolling if (speed < actor->scale >> 1) // stop moving if speed is insignificant { @@ -14466,7 +14466,7 @@ void A_DragonSegment(mobj_t *actor) return; } - dist = P_AproxDistance(P_AproxDistance(actor->x - target->x, actor->y - target->y), actor->z - target->z); + dist = FixedHypot(FixedHypot(actor->x - target->x, actor->y - target->y), actor->z - target->z); radius = actor->radius + target->radius; hangle = R_PointToAngle2(target->x, target->y, actor->x, actor->y); zangle = R_PointToAngle2(0, target->z, dist, actor->z); diff --git a/src/p_floor.c b/src/p_floor.c index 7c26065b5..de8f5d4e8 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -1164,7 +1164,7 @@ void T_ThwompSector(thwomp_t *thwomp) if (players[i].mo->z > thwomp->sector->ceilingheight) continue; - if (P_AproxDistance(thwompx - players[i].mo->x, thwompy - players[i].mo->y) > 96*FRACUNIT) + if (FixedHypot(thwompx - players[i].mo->x, thwompy - players[i].mo->y) > 96*FRACUNIT) continue; thwomp->direction = -1; @@ -1892,7 +1892,7 @@ void EV_DoFloor(line_t *line, floor_e floortype) // Linedef executor command, linetype 106. // Line length = speed, front sector floor = destination height. case moveFloorByFrontSector: - dofloor->speed = P_AproxDistance(line->dx, line->dy); + dofloor->speed = FixedHypot(line->dx, line->dy); dofloor->speed = FixedDiv(dofloor->speed,8*FRACUNIT); dofloor->floordestheight = line->frontsector->floorheight; @@ -1958,7 +1958,7 @@ void EV_DoFloor(line_t *line, floor_e floortype) // Linetypes 2/3. // Move floor up and down indefinitely like the old elevators. case bounceFloor: - dofloor->speed = P_AproxDistance(line->dx, line->dy); // same speed as elevateContinuous + dofloor->speed = FixedHypot(line->dx, line->dy); // same speed as elevateContinuous dofloor->speed = FixedDiv(dofloor->speed,4*FRACUNIT); dofloor->origspeed = dofloor->speed; // it gets slowed down at the top and bottom dofloor->floordestheight = line->frontsector->floorheight; @@ -2104,7 +2104,7 @@ void EV_DoElevator(line_t *line, elevator_e elevtype, boolean customspeed) case elevateContinuous: if (customspeed) { - elevator->origspeed = P_AproxDistance(line->dx, line->dy); + elevator->origspeed = FixedHypot(line->dx, line->dy); elevator->origspeed = FixedDiv(elevator->origspeed,4*FRACUNIT); elevator->speed = elevator->origspeed; } @@ -2266,7 +2266,7 @@ void EV_CrumbleChain(sector_t *sec, ffloor_t *rover) if (flags & ML_EFFECT1) { - P_InstaThrust(spawned, R_PointToAngle2(sec->soundorg.x, sec->soundorg.y, a, b), FixedDiv(P_AproxDistance(a - sec->soundorg.x, b - sec->soundorg.y), widthfactor)); + P_InstaThrust(spawned, R_PointToAngle2(sec->soundorg.x, sec->soundorg.y, a, b), FixedDiv(FixedHypot(a - sec->soundorg.x, b - sec->soundorg.y), widthfactor)); P_SetObjectMomZ(spawned, FixedDiv((c - bottomz), heightfactor), false); } diff --git a/src/p_inter.c b/src/p_inter.c index e9a16a3dd..be4133af5 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1002,7 +1002,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) x = (x/count)<x - x, special->y - y), special->z - z); + gatherradius = FixedHypot(FixedHypot(special->x - x, special->y - y), special->z - z); P_RemoveMobj(special); if (player->powers[pw_nights_superloop]) @@ -1028,7 +1028,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) mo2 = (mobj_t *)th; - if (P_AproxDistance(P_AproxDistance(mo2->x - x, mo2->y - y), mo2->z - z) > gatherradius) + if (FixedHypot(FixedHypot(mo2->x - x, mo2->y - y), mo2->z - z) > gatherradius) continue; if (mo2->flags & MF_SHOOTABLE) @@ -1450,8 +1450,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) fixed_t touchx, touchy, touchspeed; angle_t angle; - if (P_AproxDistance(toucher->x-special->x, toucher->y-special->y) > - P_AproxDistance((toucher->x-toucher->momx)-special->x, (toucher->y-toucher->momy)-special->y)) + if (FixedHypot(toucher->x-special->x, toucher->y-special->y) > + FixedHypot((toucher->x-toucher->momx)-special->x, (toucher->y-toucher->momy)-special->y)) { touchx = toucher->x + toucher->momx; touchy = toucher->y + toucher->momy; @@ -1463,7 +1463,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) } angle = R_PointToAngle2(special->x, special->y, touchx, touchy); - touchspeed = P_AproxDistance(toucher->momx, toucher->momy); + touchspeed = FixedHypot(toucher->momx, toucher->momy); toucher->momx = P_ReturnThrustX(special, angle, touchspeed); toucher->momy = P_ReturnThrustY(special, angle, touchspeed); @@ -1509,7 +1509,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) case MT_EGGSHIELD: { angle_t angle = R_PointToAngle2(special->x, special->y, toucher->x, toucher->y) - special->angle; - fixed_t touchspeed = P_AproxDistance(toucher->momx, toucher->momy); + fixed_t touchspeed = FixedHypot(toucher->momx, toucher->momy); if (touchspeed < special->scale) touchspeed = special->scale; @@ -1590,7 +1590,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) { special->momx = toucher->momx; special->momy = toucher->momy; - special->momz = P_AproxDistance(toucher->momx, toucher->momy)/4; + special->momz = FixedHypot(toucher->momx, toucher->momy)/4; if (toucher->momz > 0) special->momz += toucher->momz/8; @@ -1762,7 +1762,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) toucher->momx = toucher->tracer->momx/2; toucher->momy = toucher->tracer->momy/2; - toucher->momz = toucher->tracer->momz + P_AproxDistance(toucher->tracer->momx, toucher->tracer->momy)/2; + toucher->momz = toucher->tracer->momz + FixedHypot(toucher->tracer->momx, toucher->tracer->momy)/2; P_ResetPlayer(player); player->pflags &= ~PF_APPLYAUTOBRAKE; P_SetPlayerMobjState(toucher, S_PLAY_FALL); @@ -2666,7 +2666,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget case MT_BUGGLE: if (inflictor && inflictor->player // did a player kill you? Spawn relative to the player so they're bound to get it - && P_AproxDistance(inflictor->x - target->x, inflictor->y - target->y) <= inflictor->radius + target->radius + FixedMul(8*FRACUNIT, inflictor->scale) // close enough? + && FixedHypot(inflictor->x - target->x, inflictor->y - target->y) <= inflictor->radius + target->radius + FixedMul(8*FRACUNIT, inflictor->scale) // close enough? && inflictor->z <= target->z + target->height + FixedMul(8*FRACUNIT, inflictor->scale) && inflictor->z + inflictor->height >= target->z - FixedMul(8*FRACUNIT, inflictor->scale)) mo = P_SpawnMobj(inflictor->x + inflictor->momx, inflictor->y + inflictor->momy, inflictor->z + (inflictor->height / 2) + inflictor->momz, MT_EXTRALARGEBUBBLE); @@ -3305,7 +3305,7 @@ static void P_SuperDamage(player_t *player, mobj_t *inflictor, mobj_t *source, I // to recover if (inflictor->flags2 & MF2_SCATTER && source) { - fixed_t dist = P_AproxDistance(P_AproxDistance(source->x-player->mo->x, source->y-player->mo->y), source->z-player->mo->z); + fixed_t dist = FixedHypot(FixedHypot(source->x-player->mo->x, source->y-player->mo->y), source->z-player->mo->z); dist = FixedMul(128*FRACUNIT, inflictor->scale) - dist/4; diff --git a/src/p_map.c b/src/p_map.c index b934e3255..63fdebbbd 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -776,7 +776,7 @@ static boolean PIT_CheckThing(mobj_t *thing) if (thing->flags & MF_SOLID) S_StartSound(tmthing, thing->info->deathsound); for (iter = thing->subsector->sector->thinglist; iter; iter = iter->snext) - if (iter->type == thing->type && iter->health > 0 && iter->flags & MF_SOLID && (iter == thing || P_AproxDistance(P_AproxDistance(thing->x - iter->x, thing->y - iter->y), thing->z - iter->z) < 56*thing->scale))//FixedMul(56*FRACUNIT, thing->scale)) + if (iter->type == thing->type && iter->health > 0 && iter->flags & MF_SOLID && (iter == thing || FixedHypot(FixedHypot(thing->x - iter->x, thing->y - iter->y), thing->z - iter->z) < 56*thing->scale))//FixedMul(56*FRACUNIT, thing->scale)) P_KillMobj(iter, tmthing, tmthing, 0); } else @@ -815,7 +815,7 @@ static boolean PIT_CheckThing(mobj_t *thing) if (thing->flags & MF_SOLID) S_StartSound(tmthing, thing->info->deathsound); for (iter = thing->subsector->sector->thinglist; iter; iter = iter->snext) - if (iter->type == thing->type && iter->health > 0 && iter->flags & MF_SOLID && (iter == thing || P_AproxDistance(P_AproxDistance(thing->x - iter->x, thing->y - iter->y), thing->z - iter->z) < 56*thing->scale))//FixedMul(56*FRACUNIT, thing->scale)) + if (iter->type == thing->type && iter->health > 0 && iter->flags & MF_SOLID && (iter == thing || FixedHypot(FixedHypot(thing->x - iter->x, thing->y - iter->y), thing->z - iter->z) < 56*thing->scale))//FixedMul(56*FRACUNIT, thing->scale)) P_KillMobj(iter, tmthing, tmthing, 0); return true; } @@ -3061,7 +3061,7 @@ static void P_HitCameraSlideLine(line_t *ld, camera_t *thiscam) lineangle >>= ANGLETOFINESHIFT; deltaangle >>= ANGLETOFINESHIFT; - movelen = P_AproxDistance(tmxmove, tmymove); + movelen = FixedHypot(tmxmove, tmymove); newlen = FixedMul(movelen, FINECOSINE(deltaangle)); tmxmove = FixedMul(newlen, FINECOSINE(lineangle)); @@ -3147,7 +3147,7 @@ static void P_HitBounceLine(line_t *ld) lineangle >>= ANGLETOFINESHIFT; deltaangle >>= ANGLETOFINESHIFT; - movelen = P_AproxDistance(tmxmove, tmymove); + movelen = FixedHypot(tmxmove, tmymove); tmxmove = FixedMul(movelen, FINECOSINE(deltaangle)); tmymove = FixedMul(movelen, FINESINE(deltaangle)); @@ -4074,7 +4074,7 @@ static boolean PIT_RadiusAttack(mobj_t *thing) dy = abs(thing->y - bombspot->y); dz = abs(thing->z + (thing->height>>1) - bombspot->z); - dist = P_AproxDistance(P_AproxDistance(dx, dy), dz); + dist = FixedHypot(FixedHypot(dx, dy), dz); dist -= thing->radius; if (dist < 0) diff --git a/src/p_maputl.h b/src/p_maputl.h index df90ab4b4..9bc00fa17 100644 --- a/src/p_maputl.h +++ b/src/p_maputl.h @@ -41,7 +41,6 @@ typedef boolean (*traverser_t)(intercept_t *in); boolean P_PathTraverse(fixed_t px1, fixed_t py1, fixed_t px2, fixed_t py2, INT32 pflags, traverser_t ptrav); -#define P_AproxDistance(dx, dy) FixedHypot(dx, dy) void P_ClosestPointOnLine(fixed_t x, fixed_t y, line_t *line, vertex_t *result); void P_ClosestPointOnLine3D(const vector3_t *p, const vector3_t *line, vector3_t *result); INT32 P_PointOnLineSide(fixed_t x, fixed_t y, line_t *line); diff --git a/src/p_mobj.c b/src/p_mobj.c index a1edcfe77..c539db6d2 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1736,7 +1736,7 @@ static void P_PushableCheckBustables(mobj_t *mo) // Run a linedef executor?? if (rover->master->flags & ML_EFFECT5) - P_LinedefExecute((INT16)(P_AproxDistance(rover->master->dx, rover->master->dy)>>FRACBITS), mo, node->m_sector); + P_LinedefExecute((INT16)(FixedHypot(rover->master->dx, rover->master->dy)>>FRACBITS), mo, node->m_sector); goto bustupdone; } @@ -2512,7 +2512,7 @@ boolean P_ZMovement(mobj_t *mo) // float down towards target if too close if (!(mo->flags2 & MF2_SKULLFLY) && !(mo->flags2 & MF2_INFLOAT)) { - dist = P_AproxDistance(mo->x - mo->target->x, mo->y - mo->target->y); + dist = FixedHypot(mo->x - mo->target->x, mo->y - mo->target->y); delta = (mo->target->z + (mo->height>>1)) - mo->z; @@ -3662,11 +3662,11 @@ boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled P_ResetCamera(player, thiscam); else { - fixed_t camspeed = P_AproxDistance(thiscam->momx, thiscam->momy); + fixed_t camspeed = FixedHypot(thiscam->momx, thiscam->momy); P_SlideCameraMove(thiscam); - if (!resetcalled && P_AproxDistance(thiscam->momx, thiscam->momy) == camspeed) + if (!resetcalled && FixedHypot(thiscam->momx, thiscam->momy) == camspeed) { P_ResetCamera(player, thiscam); resetcalled = true; @@ -4149,7 +4149,7 @@ boolean P_BossTargetPlayer(mobj_t *actor, boolean closest) if (closest) { - dist = P_AproxDistance(actor->x - player->mo->x, actor->y - player->mo->y); + dist = FixedHypot(actor->x - player->mo->x, actor->y - player->mo->y); if (!lastdist || dist < lastdist) { lastdist = dist+1; @@ -4518,7 +4518,7 @@ static void P_Boss3Thinker(mobj_t *mobj) if (mobj->tracer->x == mobj->x && mobj->tracer->y == mobj->y) { // apply ambush for old routing, otherwise whack a mole only - dist = P_AproxDistance(P_AproxDistance(mobj->tracer->x - mobj->x, mobj->tracer->y - mobj->y), mobj->tracer->z + mobj->movefactor - mobj->z); + dist = FixedHypot(FixedHypot(mobj->tracer->x - mobj->x, mobj->tracer->y - mobj->y), mobj->tracer->z + mobj->movefactor - mobj->z); if (dist < 1) dist = 1; @@ -5042,7 +5042,7 @@ static void P_Boss5Thinker(mobj_t *mobj) } if (mobj->state == &states[mobj->info->xdeathstate]) mobj->momz -= (2*FRACUNIT)/3; - else if (mobj->tracer && P_AproxDistance(mobj->tracer->x - mobj->x, mobj->tracer->y - mobj->y) < 2*mobj->radius) + else if (mobj->tracer && FixedHypot(mobj->tracer->x - mobj->x, mobj->tracer->y - mobj->y) < 2*mobj->radius) mobj->flags &= ~MF_NOCLIP; } else @@ -5168,7 +5168,7 @@ static void P_Boss7Thinker(mobj_t *mobj) if (players[i].mo->health <= 0) continue; - if (P_AproxDistance(players[i].mo->x - mobj->x, players[i].mo->y - mobj->y) > (mobj->radius + players[i].mo->radius)) + if (FixedHypot(players[i].mo->x - mobj->x, players[i].mo->y - mobj->y) > (mobj->radius + players[i].mo->radius)) continue; if (players[i].mo->z > mobj->z + mobj->height - FRACUNIT @@ -5272,7 +5272,7 @@ static void P_Boss7Thinker(mobj_t *mobj) if (mobj->health <= mobj->info->damage && !(mo2->spawnpoint->options & 7)) continue; // don't jump to center - dist = P_AproxDistance(players[i].mo->x - mo2->x, players[i].mo->y - mo2->y); + dist = FixedHypot(players[i].mo->x - mo2->x, players[i].mo->y - mo2->y); if (!(closestNum == -1 || dist < closestdist)) continue; @@ -5345,7 +5345,7 @@ static void P_Boss7Thinker(mobj_t *mobj) an = mobj->angle; an >>= ANGLETOFINESHIFT; - dist = P_AproxDistance(hitspot->x - mobj->x, hitspot->y - mobj->y); + dist = FixedHypot(hitspot->x - mobj->x, hitspot->y - mobj->y); horizontal = dist / airtime; vertical = (gravity*airtime)/2; @@ -5396,7 +5396,7 @@ static void P_Boss7Thinker(mobj_t *mobj) if (players[i].mo->health <= 0) continue; - if (P_AproxDistance(players[i].mo->x - mobj->x, players[i].mo->y - mobj->y) > mobj->radius*4) + if (FixedHypot(players[i].mo->x - mobj->x, players[i].mo->y - mobj->y) > mobj->radius*4) continue; if (players[i].mo->z > mobj->z + 128*FRACUNIT) @@ -5650,14 +5650,14 @@ static void P_Boss9Thinker(mobj_t *mobj) // Spawn energy particles for (spawner = mobj->hnext; spawner; spawner = spawner->hnext) { - dist = P_AproxDistance(spawner->x - mobj->x, spawner->y - mobj->y); + dist = FixedHypot(spawner->x - mobj->x, spawner->y - mobj->y); if (P_RandomRange(1,(dist>>FRACBITS)/16) == 1) break; } if (spawner && dist) { mobj_t *missile = P_SpawnMissile(spawner, mobj, MT_MSGATHER); - missile->fuse = (dist/P_AproxDistance(missile->momx, missile->momy)); + missile->fuse = (dist/FixedHypot(missile->momx, missile->momy)); if (missile->fuse > mobj->fuse) P_RemoveMobj(missile); @@ -6089,7 +6089,7 @@ nodanger: mobj->flags2 |= MF2_INVERTAIMABLE; // Move normally: Approach the player using normal thrust and simulated friction. - dist = P_AproxDistance(mobj->x-mobj->target->x, mobj->y-mobj->target->y); + dist = FixedHypot(mobj->x-mobj->target->x, mobj->y-mobj->target->y); P_Thrust(mobj, R_PointToAngle2(0, 0, mobj->momx, mobj->momy), -3*FRACUNIT/8); if (dist < 64*FRACUNIT && !(mobj->target->player && mobj->target->player->homing)) P_Thrust(mobj, mobj->angle, -4*FRACUNIT); @@ -6097,7 +6097,7 @@ nodanger: P_Thrust(mobj, mobj->angle, FRACUNIT); else P_Thrust(mobj, mobj->angle + ANGLE_90, FINECOSINE((((angle_t)(leveltime*ANG1))>>ANGLETOFINESHIFT) & FINEMASK)>>1); - mobj->momz += P_AproxDistance(mobj->momx, mobj->momy)/12; // Move up higher the faster you're going. + mobj->momz += FixedHypot(mobj->momx, mobj->momy)/12; // Move up higher the faster you're going. } } } @@ -6303,7 +6303,7 @@ void P_SpawnParaloop(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 numb mobj->angle = R_PointToAngle2(mobj->x, mobj->y, x, y); // change slope - dist = P_AproxDistance(P_AproxDistance(x - mobj->x, y - mobj->y), z - mobj->z); + dist = FixedHypot(FixedHypot(x - mobj->x, y - mobj->y), z - mobj->z); if (dist < 1) dist = 1; @@ -6377,7 +6377,7 @@ void P_Attract(mobj_t *source, mobj_t *dest, boolean nightsgrab) // Home in on y fixed_t tx = dest->x; fixed_t ty = dest->y; fixed_t tz = dest->z + (dest->height/2); // Aim for center - fixed_t xydist = P_AproxDistance(tx - source->x, ty - source->y); + fixed_t xydist = FixedHypot(tx - source->x, ty - source->y); if (!dest || dest->health <= 0 || !dest->player || !source->tracer) return; @@ -6386,7 +6386,7 @@ void P_Attract(mobj_t *source, mobj_t *dest, boolean nightsgrab) // Home in on y source->angle = R_PointToAngle2(source->x, source->y, tx, ty); // change slope - dist = P_AproxDistance(xydist, tz - source->z); + dist = FixedHypot(xydist, tz - source->z); if (dist < 1) dist = 1; @@ -6412,9 +6412,9 @@ void P_Attract(mobj_t *source, mobj_t *dest, boolean nightsgrab) // Home in on y else { if (nightsgrab) - speedmul = P_AproxDistance(dest->momx, dest->momy) + FixedMul(8*FRACUNIT, source->scale); + speedmul = FixedHypot(dest->momx, dest->momy) + FixedMul(8*FRACUNIT, source->scale); else - speedmul = P_AproxDistance(dest->momx, dest->momy) + FixedMul(source->info->speed, source->scale); + speedmul = FixedHypot(dest->momx, dest->momy) + FixedMul(source->info->speed, source->scale); source->momx = FixedMul(FixedDiv(tx - source->x, dist), speedmul); source->momy = FixedMul(FixedDiv(ty - source->y, dist), speedmul); @@ -6422,7 +6422,7 @@ void P_Attract(mobj_t *source, mobj_t *dest, boolean nightsgrab) // Home in on y } // Instead of just unsetting NOCLIP like an idiot, let's check the distance to our target. - ndist = P_AproxDistance(P_AproxDistance(tx - (source->x+source->momx), + ndist = FixedHypot(FixedHypot(tx - (source->x+source->momx), ty - (source->y+source->momy)), tz - (source->z+source->momz)); @@ -7073,7 +7073,7 @@ static void P_MaceSceneryThink(mobj_t *mobj) // The below is selected based on CEZ2's first room. I promise you it is a coincidence that it looks like the weed number. for (i = 0; i < MAXPLAYERS; ++i) if (playeringame[i] && players[i].mo - && P_AproxDistance(P_AproxDistance(mobj->x - players[i].mo->x, mobj->y - players[i].mo->y), mobj->z - players[i].mo->z) < (4200 << FRACBITS)) + && FixedHypot(FixedHypot(mobj->x - players[i].mo->x, mobj->y - players[i].mo->y), mobj->z - players[i].mo->z) < (4200 << FRACBITS)) break; // Stop looking. if (i == MAXPLAYERS) { @@ -8049,7 +8049,7 @@ static boolean P_MobjBossThink(mobj_t *mobj) { if (mobj->target) { - mobj->momz = FixedMul(FixedDiv(mobj->target->z - mobj->z, P_AproxDistance(mobj->x - mobj->target->x, mobj->y - mobj->target->y)), mobj->scale << 1); + mobj->momz = FixedMul(FixedDiv(mobj->target->z - mobj->z, FixedHypot(mobj->x - mobj->target->x, mobj->y - mobj->target->y)), mobj->scale << 1); mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x, mobj->target->y); } else @@ -8293,7 +8293,7 @@ static void P_ArrowThink(mobj_t *mobj) 0------dist(momx,momy) */ - fixed_t dist = P_AproxDistance(mobj->momx, mobj->momy); + fixed_t dist = FixedHypot(mobj->momx, mobj->momy); angle_t angle = R_PointToAngle2(0, 0, dist, mobj->momz); if (angle > ANG20 && angle <= ANGLE_180) @@ -8575,7 +8575,7 @@ static boolean P_EggRobo1Think(mobj_t *mobj) continue; if (players[i].mo->z + players[i].mo->height < mobj->z - 8*mobj->scale) continue; - compdist = P_AproxDistance( + compdist = FixedHypot( players[i].mo->x + players[i].mo->momx - basex, players[i].mo->y + players[i].mo->momy - basey); if (compdist >= dist) @@ -8590,7 +8590,7 @@ static boolean P_EggRobo1Think(mobj_t *mobj) mobj->frame = 3 + ((leveltime & 2) >> 1); mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x, mobj->target->y); - if (P_AproxDistance( + if (FixedHypot( mobj->x - basex, mobj->y - basey) < mobj->scale) @@ -8621,7 +8621,7 @@ static boolean P_EggRobo1Think(mobj_t *mobj) if (!didmove) { - if (P_AproxDistance(mobj->x - basex, mobj->y - basey) < mobj->scale) + if (FixedHypot(mobj->x - basex, mobj->y - basey) < mobj->scale) P_TeleportMove(mobj, basex, basey, mobj->z); else P_TeleportMove(mobj, @@ -9011,7 +9011,7 @@ static void P_PyreFlyThink(mobj_t *mobj) { //Aim for player z position. If too close to floor/ceiling, aim just above/below them. fixed_t destz = min(max(mobj->target->z, mobj->target->floorz + 70*FRACUNIT), mobj->target->ceilingz - 80*FRACUNIT - mobj->height); - fixed_t dist = P_AproxDistance(hdist, destz - mobj->z); + fixed_t dist = FixedHypot(hdist, destz - mobj->z); P_InstaThrust(mobj, R_PointToAngle2(mobj->x, mobj->y, mobj->target->x, mobj->target->y), 2*FRACUNIT); mobj->momz = FixedMul(FixedDiv(destz - mobj->z, dist), 2*FRACUNIT); } @@ -9113,7 +9113,7 @@ static void P_PterabyteThink(mobj_t *mobj) var1 = 2*mobj->info->speed; var2 = 1; A_HomingChase(mobj); - if (P_AproxDistance(mobj->x - mobj->tracer->x, mobj->y - mobj->tracer->y) <= mobj->info->speed) + if (FixedHypot(mobj->x - mobj->tracer->x, mobj->y - mobj->tracer->y) <= mobj->info->speed) { mobj->extravalue1 -= 2; mobj->momx = mobj->momy = mobj->momz = 0; @@ -9138,7 +9138,7 @@ static void P_DragonbomberThink(mobj_t *mobj) { mobj_t *mine = P_SpawnMobjFromMobj(segment, 0, 0, 0, segment->info->painchance); mine->angle = segment->angle; - P_InstaThrust(mine, mobj->angle, P_AproxDistance(mobj->momx, mobj->momy) >> 1); + P_InstaThrust(mine, mobj->angle, FixedHypot(mobj->momx, mobj->momy) >> 1); P_SetObjectMomZ(mine, -2*FRACUNIT, true); S_StartSound(mine, mine->info->seesound); P_SetMobjState(segment, segment->info->raisestate); @@ -9148,7 +9148,7 @@ static void P_DragonbomberThink(mobj_t *mobj) } if (mobj->target) // Are we chasing a player? { - fixed_t dist = P_AproxDistance(mobj->x - mobj->target->x, mobj->y - mobj->target->y); + fixed_t dist = FixedHypot(mobj->x - mobj->target->x, mobj->y - mobj->target->y); if (dist > 2000*mobj->scale) // Not anymore! P_SetTarget(&mobj->target, NULL); else @@ -9256,7 +9256,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) mobj->eflags |= MFE_UNDERWATER; //P_MobjCheckWater(mobj); // solely for MFE_UNDERWATER for A_FlickySpawn { if (mobj->tracer && mobj->tracer->player && mobj->tracer->health > 0 - && P_AproxDistance(P_AproxDistance(mobj->tracer->x - mobj->x, mobj->tracer->y - mobj->y), mobj->tracer->z - mobj->z) <= mobj->radius*16) + && FixedHypot(FixedHypot(mobj->tracer->x - mobj->x, mobj->tracer->y - mobj->y), mobj->tracer->z - mobj->z) <= mobj->radius*16) { var1 = mobj->info->speed; var2 = 1; @@ -9391,7 +9391,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) if (playeringame[i] && players[i].mo && players[i].mare == mobj->threshold && players[i].spheres > 0) { - fixed_t dist = P_AproxDistance(players[i].mo->x - mobj->x, players[i].mo->y - mobj->y); + fixed_t dist = FixedHypot(players[i].mo->x - mobj->x, players[i].mo->y - mobj->y); if (dist < shortest) { P_SetTarget(&mobj->target, players[i].mo); @@ -9422,7 +9422,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) P_KoopaThinker(mobj); break; case MT_FIREBALL: - if (P_AproxDistance(mobj->momx, mobj->momy) <= 16*FRACUNIT) // Once fireballs lose enough speed, kill them + if (FixedHypot(mobj->momx, mobj->momy) <= 16*FRACUNIT) // Once fireballs lose enough speed, kill them { P_KillMobj(mobj, NULL, NULL, 0); return false; @@ -13530,7 +13530,7 @@ mobj_t *P_SpawnXYZMissile(mobj_t *source, mobj_t *dest, mobjtype_t type, th->momx = FixedMul(speed, FINECOSINE(an)); th->momy = FixedMul(speed, FINESINE(an)); - dist = P_AproxDistance(dest->x - x, dest->y - y); + dist = FixedHypot(dest->x - x, dest->y - y); dist = dist / speed; if (dist < 1) @@ -13592,7 +13592,7 @@ mobj_t *P_SpawnAlteredDirectionMissile(mobj_t *source, mobjtype_t type, fixed_t th->momx = FixedMul(speed, FINECOSINE(an)); th->momy = FixedMul(speed, FINESINE(an)); - dist = P_AproxDistance(source->momx*800, source->momy*800); + dist = FixedHypot(source->momx*800, source->momy*800); dist = dist / speed; if (dist < 1) @@ -13657,7 +13657,7 @@ mobj_t *P_SpawnPointMissile(mobj_t *source, fixed_t xa, fixed_t ya, fixed_t za, th->momx = FixedMul(speed, FINECOSINE(an)); th->momy = FixedMul(speed, FINESINE(an)); - dist = P_AproxDistance(xa - x, ya - y); + dist = FixedHypot(xa - x, ya - y); dist = dist / speed; if (dist < 1) @@ -13737,9 +13737,9 @@ mobj_t *P_SpawnMissile(mobj_t *source, mobj_t *dest, mobjtype_t type) th->momy = FixedMul(speed, FINESINE(an)); if (type == MT_TURRETLASER || type == MT_ENERGYBALL) // More accurate! - dist = P_AproxDistance(dest->x+(dest->momx*gsf) - source->x, dest->y+(dest->momy*gsf) - source->y); + dist = FixedHypot(dest->x+(dest->momx*gsf) - source->x, dest->y+(dest->momy*gsf) - source->y); else - dist = P_AproxDistance(dest->x - source->x, dest->y - source->y); + dist = FixedHypot(dest->x - source->x, dest->y - source->y); dist = dist / speed; diff --git a/src/p_polyobj.c b/src/p_polyobj.c index 874edbd50..95734ff86 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -1636,7 +1636,7 @@ void T_PolyObjWaypoint(polywaypoint_t *th) distx = target->x - pox; disty = target->y - poy; distz = target->z - poz; - dist = P_AproxDistance(P_AproxDistance(distx, disty), distz); + dist = FixedHypot(FixedHypot(distx, disty), distz); if (dist < 1) dist = 1; diff --git a/src/p_setup.c b/src/p_setup.c index 41d8822e2..2ee588fbb 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -232,7 +232,7 @@ mobj_t *P_GetClosestWaypoint(UINT8 sequence, mobj_t *mo) if (!mo2) continue; - curdist = P_AproxDistance(P_AproxDistance(mo->x - mo2->x, mo->y - mo2->y), mo->z - mo2->z); + curdist = FixedHypot(FixedHypot(mo->x - mo2->x, mo->y - mo2->y), mo->z - mo2->z); if (result && curdist > bestdist) continue; diff --git a/src/p_slopes.c b/src/p_slopes.c index aa46a8402..d77d0805f 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -885,7 +885,7 @@ void P_ButteredSlope(mobj_t *mo) } if (mo->momx || mo->momy) // Slightly increase thrust based on the object's speed - thrust = FixedMul(thrust, FRACUNIT+P_AproxDistance(mo->momx, mo->momy)/16); + thrust = FixedMul(thrust, FRACUNIT+FixedHypot(mo->momx, mo->momy)/16); // This makes it harder to zigzag up steep slopes, as well as allows greater top speed when rolling down // Let's get the gravity strength for the object... diff --git a/src/p_spec.c b/src/p_spec.c index 5b9e05c61..e696ad5d1 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1240,7 +1240,7 @@ static boolean PolyFlag(line_t *line) polyflagdata_t pfd; pfd.polyObjNum = Tag_FGet(&line->tags); - pfd.speed = P_AproxDistance(line->dx, line->dy) >> FRACBITS; + pfd.speed = FixedHypot(line->dx, line->dy) >> FRACBITS; pfd.angle = R_PointToAngle2(line->v1->x, line->v1->y, line->v2->x, line->v2->y) >> ANGLETOFINESHIFT; pfd.momx = sides[line->sidenum[0]].textureoffset >> FRACBITS; @@ -1567,7 +1567,7 @@ static boolean P_CheckNightsTriggerLine(line_t *triggerline, mobj_t *actor) boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller) { sector_t *ctlsector; - fixed_t dist = P_AproxDistance(triggerline->dx, triggerline->dy)>>FRACBITS; + fixed_t dist = FixedHypot(triggerline->dx, triggerline->dy)>>FRACBITS; size_t i, linecnt, sectori; INT16 specialtype = triggerline->special; @@ -2629,7 +2629,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) sectors[secnum].lightlevel = line->backsector->lightlevel; flick = P_SpawnAdjustableFireFlicker(line->frontsector, §ors[secnum], - P_AproxDistance(line->dx, line->dy)>>FRACBITS); + FixedHypot(line->dx, line->dy)>>FRACBITS); // Make sure the starting light level is in range. if (reallightlevel < flick->minlight) @@ -2644,7 +2644,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) // Use front sector for min, target sector for max, // the same way linetype 61 does it. P_SpawnAdjustableFireFlicker(line->frontsector, §ors[secnum], - P_AproxDistance(line->dx, line->dy)>>FRACBITS); + FixedHypot(line->dx, line->dy)>>FRACBITS); } } break; @@ -2663,7 +2663,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) sectors[secnum].lightlevel = line->backsector->lightlevel; glow = P_SpawnAdjustableGlowingLight(line->frontsector, §ors[secnum], - P_AproxDistance(line->dx, line->dy)>>FRACBITS); + FixedHypot(line->dx, line->dy)>>FRACBITS); // Make sure the starting light level is in range. if (reallightlevel < glow->minlight) @@ -2678,7 +2678,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) // Use front sector for min, target sector for max, // the same way linetype 602 does it. P_SpawnAdjustableGlowingLight(line->frontsector, §ors[secnum], - P_AproxDistance(line->dx, line->dy)>>FRACBITS); + FixedHypot(line->dx, line->dy)>>FRACBITS); } } break; @@ -2760,7 +2760,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) ((line->sidenum[1] != 0xFFFF && !(sides[line->sidenum[0]].rowoffset>>FRACBITS)) ? max(min(sides[line->sidenum[1]].rowoffset>>FRACBITS, 255), 0) : max(min(sides[line->sidenum[0]].rowoffset>>FRACBITS, 255), 0)) - : abs(P_AproxDistance(line->dx, line->dy))>>FRACBITS, + : abs(FixedHypot(line->dx, line->dy))>>FRACBITS, (line->flags & ML_EFFECT4), (line->flags & ML_EFFECT5)); break; @@ -2795,7 +2795,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) else { P_SetTarget(&mo->player->awayviewmobj, altview); - mo->player->awayviewtics = P_AproxDistance(line->dx, line->dy)>>FRACBITS; + mo->player->awayviewtics = FixedHypot(line->dx, line->dy)>>FRACBITS; } @@ -2840,7 +2840,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) case 425: // Calls P_SetMobjState on calling mobj if (mo && !mo->player) - P_SetMobjState(mo, sides[line->sidenum[0]].toptexture); //P_AproxDistance(line->dx, line->dy)>>FRACBITS); + P_SetMobjState(mo, sides[line->sidenum[0]].toptexture); //FixedHypot(line->dx, line->dy)>>FRACBITS); break; case 426: // Moves the mobj to its sector's soundorg and on the floor, and stops it @@ -3026,7 +3026,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) case 438: // Set player scale if (mo) { - mo->destscale = FixedDiv(P_AproxDistance(line->dx, line->dy), 100<destscale = FixedDiv(FixedHypot(line->dx, line->dy), 100<destscale < FRACUNIT/100) mo->destscale = FRACUNIT/100; if (mo->player && bot) @@ -3144,7 +3144,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) { quake.intensity = sides[line->sidenum[0]].textureoffset; quake.radius = sides[line->sidenum[0]].rowoffset; - quake.time = P_AproxDistance(line->dx, line->dy)>>FRACBITS; + quake.time = FixedHypot(line->dx, line->dy)>>FRACBITS; quake.epicenter = NULL; /// \todo @@ -3407,7 +3407,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) case 452: // Set FOF alpha { INT16 destvalue = line->sidenum[1] != 0xffff ? - (INT16)(sides[line->sidenum[1]].textureoffset>>FRACBITS) : (INT16)(P_AproxDistance(line->dx, line->dy)>>FRACBITS); + (INT16)(sides[line->sidenum[1]].textureoffset>>FRACBITS) : (INT16)(FixedHypot(line->dx, line->dy)>>FRACBITS); INT16 sectag = (INT16)(sides[line->sidenum[0]].textureoffset>>FRACBITS); INT16 foftag = (INT16)(sides[line->sidenum[0]].rowoffset>>FRACBITS); sector_t *sec; // Sector that the FOF is visible in @@ -4995,8 +4995,8 @@ DoneSection2: } else { - if (P_AproxDistance(P_AproxDistance(player->mo->x-resultlow.x, player->mo->y-resultlow.y), - player->mo->z-resultlow.z) < P_AproxDistance(P_AproxDistance(player->mo->x-resulthigh.x, + if (FixedHypot(FixedHypot(player->mo->x-resultlow.x, player->mo->y-resultlow.y), + player->mo->z-resultlow.z) < FixedHypot(FixedHypot(player->mo->x-resulthigh.x, player->mo->y-resulthigh.y), player->mo->z-resulthigh.z)) { // Line between Mid and Low is closer @@ -6314,7 +6314,7 @@ void P_SpawnSpecials(boolean fromnetsave) break; case 52: // Continuously Falling sector - EV_DoContinuousFall(lines[i].frontsector, lines[i].backsector, P_AproxDistance(lines[i].dx, lines[i].dy), (lines[i].flags & ML_NOCLIMB)); + EV_DoContinuousFall(lines[i].frontsector, lines[i].backsector, FixedHypot(lines[i].dx, lines[i].dy), (lines[i].flags & ML_NOCLIMB)); break; case 53: // New super cool and awesome moving floor and ceiling type @@ -6386,15 +6386,15 @@ void P_SpawnSpecials(boolean fromnetsave) case 66: // Displace floor by front sector TAG_ITER_SECTORS(0, tag, s) - P_AddPlaneDisplaceThinker(pd_floor, P_AproxDistance(lines[i].dx, lines[i].dy)>>8, sides[lines[i].sidenum[0]].sector-sectors, s, !!(lines[i].flags & ML_NOCLIMB)); + P_AddPlaneDisplaceThinker(pd_floor, FixedHypot(lines[i].dx, lines[i].dy)>>8, sides[lines[i].sidenum[0]].sector-sectors, s, !!(lines[i].flags & ML_NOCLIMB)); break; case 67: // Displace ceiling by front sector TAG_ITER_SECTORS(0, tag, s) - P_AddPlaneDisplaceThinker(pd_ceiling, P_AproxDistance(lines[i].dx, lines[i].dy)>>8, sides[lines[i].sidenum[0]].sector-sectors, s, !!(lines[i].flags & ML_NOCLIMB)); + P_AddPlaneDisplaceThinker(pd_ceiling, FixedHypot(lines[i].dx, lines[i].dy)>>8, sides[lines[i].sidenum[0]].sector-sectors, s, !!(lines[i].flags & ML_NOCLIMB)); break; case 68: // Displace both floor AND ceiling by front sector TAG_ITER_SECTORS(0, tag, s) - P_AddPlaneDisplaceThinker(pd_both, P_AproxDistance(lines[i].dx, lines[i].dy)>>8, sides[lines[i].sidenum[0]].sector-sectors, s, !!(lines[i].flags & ML_NOCLIMB)); + P_AddPlaneDisplaceThinker(pd_both, FixedHypot(lines[i].dx, lines[i].dy)>>8, sides[lines[i].sidenum[0]].sector-sectors, s, !!(lines[i].flags & ML_NOCLIMB)); break; case 100: // FOF (solid, opaque, shadows) @@ -6588,18 +6588,18 @@ void P_SpawnSpecials(boolean fromnetsave) case 150: // Air bobbing platform case 151: // Adjustable air bobbing platform { - fixed_t dist = (lines[i].special == 150) ? 16*FRACUNIT : P_AproxDistance(lines[i].dx, lines[i].dy); + fixed_t dist = (lines[i].special == 150) ? 16*FRACUNIT : FixedHypot(lines[i].dx, lines[i].dy); P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers); P_AddAirbob(lines[i].frontsector, tag, dist, false, !!(lines[i].flags & ML_NOCLIMB), false); break; } case 152: // Adjustable air bobbing platform in reverse P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers); - P_AddAirbob(lines[i].frontsector, tag, P_AproxDistance(lines[i].dx, lines[i].dy), true, !!(lines[i].flags & ML_NOCLIMB), false); + P_AddAirbob(lines[i].frontsector, tag, FixedHypot(lines[i].dx, lines[i].dy), true, !!(lines[i].flags & ML_NOCLIMB), false); break; case 153: // Dynamic Sinking Platform P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers); - P_AddAirbob(lines[i].frontsector, tag, P_AproxDistance(lines[i].dx, lines[i].dy), false, !!(lines[i].flags & ML_NOCLIMB), true); + P_AddAirbob(lines[i].frontsector, tag, FixedHypot(lines[i].dx, lines[i].dy), false, !!(lines[i].flags & ML_NOCLIMB), true); break; case 160: // Float/bob platform @@ -6678,7 +6678,7 @@ void P_SpawnSpecials(boolean fromnetsave) case 194: // Rising Platform 'Platform' - You can jump up through it case 195: // Rising Platform Translucent "platform" { - fixed_t speed = FixedDiv(P_AproxDistance(lines[i].dx, lines[i].dy), 4*FRACUNIT); + fixed_t speed = FixedDiv(FixedHypot(lines[i].dx, lines[i].dy), 4*FRACUNIT); fixed_t ceilingtop = P_FindHighestCeilingSurrounding(lines[i].frontsector); fixed_t ceilingbottom = P_FindLowestCeilingSurrounding(lines[i].frontsector); @@ -7003,14 +7003,14 @@ void P_SpawnSpecials(boolean fromnetsave) sec = sides[*lines[i].sidenum].sector - sectors; TAG_ITER_SECTORS(0, tag, s) P_SpawnAdjustableGlowingLight(§ors[sec], §ors[s], - P_AproxDistance(lines[i].dx, lines[i].dy)>>FRACBITS); + FixedHypot(lines[i].dx, lines[i].dy)>>FRACBITS); break; case 603: // Adjustable flickering light sec = sides[*lines[i].sidenum].sector - sectors; TAG_ITER_SECTORS(0, tag, s) P_SpawnAdjustableFireFlicker(§ors[sec], §ors[s], - P_AproxDistance(lines[i].dx, lines[i].dy)>>FRACBITS); + FixedHypot(lines[i].dx, lines[i].dy)>>FRACBITS); break; case 604: // Adjustable Blinking Light (unsynchronized) @@ -8416,9 +8416,9 @@ static void Add_Pusher(pushertype_e type, fixed_t x_mag, fixed_t y_mag, mobj_t * // "The right triangle of the square of the length of the hypotenuse is equal to the sum of the squares of the lengths of the other two sides." // "Bah! Stupid brains! Don't you know anything besides the Pythagorean Theorem?" - Earthworm Jim if (type == p_downcurrent || type == p_upcurrent || type == p_upwind || type == p_downwind) - p->magnitude = P_AproxDistance(p->x_mag,p->y_mag)<<(FRACBITS-PUSH_FACTOR); + p->magnitude = FixedHypot(p->x_mag,p->y_mag)<<(FRACBITS-PUSH_FACTOR); else - p->magnitude = P_AproxDistance(p->x_mag,p->y_mag); + p->magnitude = FixedHypot(p->x_mag,p->y_mag); if (source) // point source exist? { // where force goes to zero @@ -8469,14 +8469,14 @@ static inline boolean PIT_PushThing(mobj_t *thing) // don't fade wrt Z if health & 2 (mapthing has multi flag) if (tmpusher->source->health & 2) - dist = P_AproxDistance(thing->x - sx,thing->y - sy); + dist = FixedHypot(thing->x - sx,thing->y - sy); else { // Make sure the Z is in range if (thing->z < sz - tmpusher->radius || thing->z > sz + tmpusher->radius) return false; - dist = P_AproxDistance(P_AproxDistance(thing->x - sx, thing->y - sy), + dist = FixedHypot(FixedHypot(thing->x - sx, thing->y - sy), thing->z - sz); } @@ -8811,7 +8811,7 @@ void T_Pusher(pusher_t *p) // Tumbleweeds bounce a bit... if (thing->type == MT_LITTLETUMBLEWEED || thing->type == MT_BIGTUMBLEWEED) - thing->momz += P_AproxDistance(xspeed<<(FRACBITS-PUSH_FACTOR), yspeed<<(FRACBITS-PUSH_FACTOR)) >> 2; + thing->momz += FixedHypot(xspeed<<(FRACBITS-PUSH_FACTOR), yspeed<<(FRACBITS-PUSH_FACTOR)) >> 2; } if (moved) diff --git a/src/p_user.c b/src/p_user.c index 2dcc21009..84fc3e521 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1018,7 +1018,7 @@ void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor) // to recover if ((inflictor->flags2 & MF2_SCATTER) && source) { - fixed_t dist = P_AproxDistance(P_AproxDistance(source->x-player->mo->x, source->y-player->mo->y), source->z-player->mo->z); + fixed_t dist = FixedHypot(FixedHypot(source->x-player->mo->x, source->y-player->mo->y), source->z-player->mo->z); dist = FixedMul(128*FRACUNIT, inflictor->scale) - dist/4; @@ -2701,7 +2701,7 @@ static void P_CheckBustableBlocks(player_t *player) // Run a linedef executor?? if (rover->master->flags & ML_EFFECT5) - P_LinedefExecute((INT16)(P_AproxDistance(rover->master->dx, rover->master->dy)>>FRACBITS), player->mo, node->m_sector); + P_LinedefExecute((INT16)(FixedHypot(rover->master->dx, rover->master->dy)>>FRACBITS), player->mo, node->m_sector); goto bustupdone; } @@ -2764,7 +2764,7 @@ static void P_CheckBouncySectors(player_t *player) if (player->mo->z + player->mo->height < bottomheight) continue; - bouncestrength = P_AproxDistance(rover->master->dx, rover->master->dy)/100; + bouncestrength = FixedHypot(rover->master->dx, rover->master->dy)/100; if (oldz < P_GetFOFTopZ(player->mo, node->m_sector, rover, oldx, oldy, NULL) && oldz + player->mo->height > P_GetFOFBottomZ(player->mo, node->m_sector, rover, oldx, oldy, NULL)) @@ -4981,7 +4981,7 @@ void P_Telekinesis(player_t *player, fixed_t thrust, fixed_t range) if (!((mo2->flags & MF_SHOOTABLE && mo2->flags & MF_ENEMY) || mo2->type == MT_EGGGUARD || mo2->player)) continue; - dist = P_AproxDistance(P_AproxDistance(player->mo->x-mo2->x, player->mo->y-mo2->y), player->mo->z-mo2->z); + dist = FixedHypot(FixedHypot(player->mo->x-mo2->x, player->mo->y-mo2->y), player->mo->z-mo2->z); if (range < dist) continue; @@ -6464,12 +6464,12 @@ static void P_NightsTransferPoints(player_t *player, fixed_t xspeed, fixed_t rad //CONS_Debug(DBG_NIGHTS, "T1 is at %d, %d\n", transfer1->x>>FRACBITS, transfer1->y>>FRACBITS); //CONS_Debug(DBG_NIGHTS, "T2 is at %d, %d\n", transfer2->x>>FRACBITS, transfer2->y>>FRACBITS); - //CONS_Debug(DBG_NIGHTS, "Distance from T1: %d\n", P_AproxDistance(transfer1->x - player->mo->x, transfer1->y - player->mo->y)>>FRACBITS); - //CONS_Debug(DBG_NIGHTS, "Distance from T2: %d\n", P_AproxDistance(transfer2->x - player->mo->x, transfer2->y - player->mo->y)>>FRACBITS); + //CONS_Debug(DBG_NIGHTS, "Distance from T1: %d\n", FixedHypot(transfer1->x - player->mo->x, transfer1->y - player->mo->y)>>FRACBITS); + //CONS_Debug(DBG_NIGHTS, "Distance from T2: %d\n", FixedHypot(transfer2->x - player->mo->x, transfer2->y - player->mo->y)>>FRACBITS); // Transfer1 is closer to the player than transfer2 - if (P_AproxDistance(transfer1->x - player->mo->x, transfer1->y - player->mo->y)>>FRACBITS - < P_AproxDistance(transfer2->x - player->mo->x, transfer2->y - player->mo->y)>>FRACBITS) + if (FixedHypot(transfer1->x - player->mo->x, transfer1->y - player->mo->y)>>FRACBITS + < FixedHypot(transfer2->x - player->mo->x, transfer2->y - player->mo->y)>>FRACBITS) { //CONS_Debug(DBG_NIGHTS, " must be < 0 to transfer\n"); @@ -7709,7 +7709,7 @@ void P_BlackOw(player_t *player) S_StartSound (player->mo, sfx_bkpoof); // Sound the BANG! for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && P_AproxDistance(player->mo->x - players[i].mo->x, + if (playeringame[i] && FixedHypot(player->mo->x - players[i].mo->x, player->mo->y - players[i].mo->y) < 1536*FRACUNIT) P_FlashPal(&players[i], PAL_NUKE, 10); @@ -7883,7 +7883,7 @@ static void P_SkidStuff(player_t *player) P_SpawnSkidDust(player, 0, false); } } - else if (P_AproxDistance(pmx, pmy) >= FixedMul(player->runspeed/2, player->mo->scale) // if you were moving faster than half your run speed last frame + else if (FixedHypot(pmx, pmy) >= FixedMul(player->runspeed/2, player->mo->scale) // if you were moving faster than half your run speed last frame && (player->mo->momx != pmx || player->mo->momy != pmy) // and you are moving differently this frame && P_GetPlayerControlDirection(player) == 2) // and your controls are pointing in the opposite direction to your movement { // check for skidding @@ -8514,7 +8514,7 @@ void P_MovePlayer(player_t *player) P_ResetScore(player); // Show the "THOK!" graphic when spinning quickly across the ground. (even applies to non-spinners, in the case of zoom tubes) - if (player->pflags & PF_SPINNING && P_AproxDistance(player->speed, player->mo->momz) > FixedMul(15<mo->scale) && !(player->pflags & PF_JUMPED)) + if (player->pflags & PF_SPINNING && FixedHypot(player->speed, player->mo->momz) > FixedMul(15<mo->scale) && !(player->pflags & PF_JUMPED)) { P_SpawnSpinMobj(player, player->spinitem); G_GhostAddSpin(); @@ -8735,7 +8735,7 @@ static void P_DoZoomTube(player_t *player) speed = abs(player->speed); // change slope - dist = P_AproxDistance(P_AproxDistance(player->mo->tracer->x - player->mo->x, player->mo->tracer->y - player->mo->y), player->mo->tracer->z - player->mo->z); + dist = FixedHypot(FixedHypot(player->mo->tracer->x - player->mo->x, player->mo->tracer->y - player->mo->y), player->mo->tracer->z - player->mo->z); if (dist < 1) dist = 1; @@ -8776,7 +8776,7 @@ static void P_DoZoomTube(player_t *player) // calculate MOMX/MOMY/MOMZ for next waypoint // change slope - dist = P_AproxDistance(P_AproxDistance(player->mo->tracer->x - player->mo->x, player->mo->tracer->y - player->mo->y), player->mo->tracer->z - player->mo->z); + dist = FixedHypot(FixedHypot(player->mo->tracer->x - player->mo->x, player->mo->tracer->y - player->mo->y), player->mo->tracer->z - player->mo->z); if (dist < 1) dist = 1; @@ -8829,7 +8829,7 @@ static void P_DoRopeHang(player_t *player) sequence = player->mo->tracer->threshold; // change slope - dist = P_AproxDistance(P_AproxDistance(player->mo->tracer->x - player->mo->x, player->mo->tracer->y - player->mo->y), player->mo->tracer->z - playerz); + dist = FixedHypot(FixedHypot(player->mo->tracer->x - player->mo->x, player->mo->tracer->y - player->mo->y), player->mo->tracer->z - playerz); if (dist < 1) dist = 1; @@ -8892,7 +8892,7 @@ static void P_DoRopeHang(player_t *player) // calculate MOMX/MOMY/MOMZ for next waypoint // change slope - dist = P_AproxDistance(P_AproxDistance(player->mo->tracer->x - player->mo->x, player->mo->tracer->y - player->mo->y), player->mo->tracer->z - playerz); + dist = FixedHypot(FixedHypot(player->mo->tracer->x - player->mo->x, player->mo->tracer->y - player->mo->y), player->mo->tracer->z - playerz); if (dist < 1) dist = 1; @@ -8993,7 +8993,7 @@ void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius) if (abs(inflictor->x - mo->x) > radius || abs(inflictor->y - mo->y) > radius || abs(inflictor->z - mo->z) > radius) continue; // Workaround for possible integer overflow in the below -Red - if (P_AproxDistance(P_AproxDistance(inflictor->x - mo->x, inflictor->y - mo->y), inflictor->z - mo->z) > radius) + if (FixedHypot(FixedHypot(inflictor->x - mo->x, inflictor->y - mo->y), inflictor->z - mo->z) > radius) continue; if (mo->type == MT_MINUS && !(mo->flags & (MF_SPECIAL|MF_SHOOTABLE))) @@ -9129,12 +9129,12 @@ mobj_t *P_LookForFocusTarget(player_t *player, mobj_t *exclude, SINT8 direction, { fixed_t zdist = (player->mo->z + player->mo->height/2) - (mo->z + mo->height/2); - dist = P_AproxDistance(player->mo->x-mo->x, player->mo->y-mo->y); + dist = FixedHypot(player->mo->x-mo->x, player->mo->y-mo->y); if (abs(zdist) > dist) continue; // Don't home outside of desired angle! - dist = P_AproxDistance(dist, zdist); + dist = FixedHypot(dist, zdist); if (dist > maxdist) continue; // out of range } @@ -9226,7 +9226,7 @@ mobj_t *P_LookForEnemies(player_t *player, boolean nonenemies, boolean bullet) { fixed_t zdist = (player->mo->z + player->mo->height/2) - (mo->z + mo->height/2); - dist = P_AproxDistance(player->mo->x-mo->x, player->mo->y-mo->y); + dist = FixedHypot(player->mo->x-mo->x, player->mo->y-mo->y); if (bullet) { if ((R_PointToAngle2(0, 0, dist, zdist) + span) > span*2) @@ -9243,7 +9243,7 @@ mobj_t *P_LookForEnemies(player_t *player, boolean nonenemies, boolean bullet) continue; } - dist = P_AproxDistance(dist, zdist); + dist = FixedHypot(dist, zdist); if (dist > maxdist) continue; // out of range } @@ -9303,7 +9303,7 @@ boolean P_HomingAttack(mobj_t *source, mobj_t *enemy) // Home in on your target // change slope zdist = ((P_MobjFlip(source) == -1) ? (enemy->z + enemy->height) - (source->z + source->height) : (enemy->z - source->z)); - dist = P_AproxDistance(P_AproxDistance(enemy->x - source->x, enemy->y - source->y), zdist); + dist = FixedHypot(FixedHypot(enemy->x - source->x, enemy->y - source->y), zdist); if (dist < 1) dist = 1; @@ -10352,7 +10352,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall // follow the player /*if (player->playerstate != PST_DEAD && (camspeed) != 0) { - if (P_AproxDistance(mo->x - thiscam->x, mo->y - thiscam->y) > (checkdist + P_AproxDistance(mo->momx, mo->momy)) * 4 + if (FixedHypot(mo->x - thiscam->x, mo->y - thiscam->y) > (checkdist + FixedHypot(mo->momx, mo->momy)) * 4 || abs(mo->z - thiscam->z) > checkdist * 3) { if (!resetcalled) @@ -10417,7 +10417,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall } /* check z distance too for orbital camera */ - if (P_AproxDistance(P_AproxDistance(vx - mo->x, vy - mo->y), + if (FixedHypot(FixedHypot(vx - mo->x, vy - mo->y), vz - ( mo->z + mo->height / 2 )) < FixedMul(48*FRACUNIT, mo->scale)) mo->flags2 |= MF2_SHADOW; else @@ -10902,7 +10902,7 @@ static void P_ParabolicMove(mobj_t *mo, fixed_t x, fixed_t y, fixed_t z, fixed_t fixed_t dx = x - mo->x; fixed_t dy = y - mo->y; fixed_t dz = z - mo->z; - fixed_t dh = P_AproxDistance(dx, dy); + fixed_t dh = FixedHypot(dx, dy); fixed_t c = FixedDiv(dx, dh); fixed_t s = FixedDiv(dy, dh); fixed_t fixConst = FixedDiv(speed, g); @@ -11774,7 +11774,7 @@ void P_PlayerThink(player_t *player) if (mo2->flags2 & MF2_NIGHTSPULL) continue; - if (P_AproxDistance(P_AproxDistance(mo2->x - x, mo2->y - y), mo2->z - z) > FixedMul(128*FRACUNIT, player->mo->scale)) + if (FixedHypot(FixedHypot(mo2->x - x, mo2->y - y), mo2->z - z) > FixedMul(128*FRACUNIT, player->mo->scale)) continue; // Yay! The thing's in reach! Pull it in! @@ -12010,7 +12010,7 @@ void P_PlayerThink(player_t *player) if (!currentlyonground) acceleration /= 2; // fake skidding! see P_SkidStuff for reference on conditionals - else if (!player->skidtime && !(player->mo->eflags & MFE_GOOWATER) && !(player->pflags & (PF_JUMPED|PF_SPINNING|PF_SLIDING)) && !(player->charflags & SF_NOSKID) && P_AproxDistance(player->mo->momx, player->mo->momy) >= FixedMul(player->runspeed, player->mo->scale)) // modified from player->runspeed/2 'cuz the skid was just TOO frequent ngl + else if (!player->skidtime && !(player->mo->eflags & MFE_GOOWATER) && !(player->pflags & (PF_JUMPED|PF_SPINNING|PF_SLIDING)) && !(player->charflags & SF_NOSKID) && FixedHypot(player->mo->momx, player->mo->momy) >= FixedMul(player->runspeed, player->mo->scale)) // modified from player->runspeed/2 'cuz the skid was just TOO frequent ngl { if (player->mo->state-states != S_PLAY_SKID) P_SetPlayerMobjState(player->mo, S_PLAY_SKID); @@ -12595,7 +12595,7 @@ void P_PlayerAfterThink(player_t *player) P_SetPlayerAngle(player, player->mo->angle); } - if (P_AproxDistance(player->mo->x - tails->x, player->mo->y - tails->y) > player->mo->radius) + if (FixedHypot(player->mo->x - tails->x, player->mo->y - tails->y) > player->mo->radius) player->powers[pw_carry] = CR_NONE; if (player->powers[pw_carry] != CR_NONE) @@ -12784,7 +12784,7 @@ void P_PlayerAfterThink(player_t *player) player->mo->momy = ptera->momy; player->mo->momz = ptera->momz; - if (P_AproxDistance(player->mo->x - ptera->x - ptera->watertop, player->mo->y - ptera->y - ptera->waterbottom) > player->mo->radius) + if (FixedHypot(player->mo->x - ptera->x - ptera->watertop, player->mo->y - ptera->y - ptera->waterbottom) > player->mo->radius) goto dropoff; ptera->watertop >>= 1; diff --git a/src/r_things.c b/src/r_things.c index 083373927..4e296bb1a 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2991,7 +2991,7 @@ boolean R_ThingVisibleWithinDist (mobj_t *thing, if (! R_ThingVisible(thing)) return false; - approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y); + approx_dist = FixedHypot(viewx-thing->x, viewy-thing->y); if (thing->sprite == SPR_HOOP) { @@ -3016,7 +3016,7 @@ boolean R_PrecipThingVisible (precipmobj_t *precipthing, if (( precipthing->precipflags & PCF_INVISIBLE )) return false; - approx_dist = P_AproxDistance(viewx-precipthing->x, viewy-precipthing->y); + approx_dist = FixedHypot(viewx-precipthing->x, viewy-precipthing->y); return ( approx_dist <= limit_dist ); } diff --git a/src/s_sound.c b/src/s_sound.c index 392a5b453..0085dc342 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -943,8 +943,8 @@ void S_UpdateSounds(void) const mobj_t *soundmobj = c->origin; fixed_t dist1, dist2; - dist1 = P_AproxDistance(listener.x-soundmobj->x, listener.y-soundmobj->y); - dist2 = P_AproxDistance(listener2.x-soundmobj->x, listener2.y-soundmobj->y); + dist1 = FixedHypot(listener.x-soundmobj->x, listener.y-soundmobj->y); + dist2 = FixedHypot(listener2.x-soundmobj->x, listener2.y-soundmobj->y); if (dist1 <= dist2) { diff --git a/src/st_stuff.c b/src/st_stuff.c index 649644620..15d1af396 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2458,7 +2458,7 @@ num: static INT32 ST_drawEmeraldHuntIcon(mobj_t *hunt, patch_t **patches, INT32 offset) { INT32 interval, i; - UINT32 dist = ((UINT32)P_AproxDistance(P_AproxDistance(stplyr->mo->x - hunt->x, stplyr->mo->y - hunt->y), stplyr->mo->z - hunt->z))>>FRACBITS; + UINT32 dist = ((UINT32)FixedHypot(FixedHypot(stplyr->mo->x - hunt->x, stplyr->mo->y - hunt->y), stplyr->mo->z - hunt->z))>>FRACBITS; if (dist < 128) { From 5bb221b3bfb501c940e96871cbb068abc8f4a8d4 Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 12 Dec 2020 15:39:13 -0800 Subject: [PATCH 156/644] Yeah Fuck You SEENAMES --- src/lua_hook.h | 2 -- src/lua_hooklib.c | 2 -- 2 files changed, 4 deletions(-) diff --git a/src/lua_hook.h b/src/lua_hook.h index 4274f1f3c..0f8482794 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -120,9 +120,7 @@ int LUA_HookPlayerCanDamage(player_t *, mobj_t *); void LUA_HookPlayerQuit(player_t *, kickreason_t); int LUA_HookTeamSwitch(player_t *, int newteam, boolean fromspectators, boolean tryingautobalance, boolean tryingscramble); int LUA_HookViewpointSwitch(player_t *player, player_t *newdisplayplayer, boolean forced); -#ifdef SEENAMES int LUA_HookSeenPlayer(player_t *player, player_t *seenfriend); -#endif int LUA_HookShouldJingleContinue(player_t *, const char *musname); int LUA_HookPlayerCmd(player_t *, ticcmd_t *); int LUA_HookMusicChange(const char *oldname, struct MusicChange *); diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 4143fbd8e..3a63e446e 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -947,7 +947,6 @@ int LUA_HookViewpointSwitch(player_t *player, player_t *newdisplayplayer, boolea return hook.status; } -#ifdef SEENAMES int LUA_HookSeenPlayer(player_t *player, player_t *seenfriend) { Hook_State hook; @@ -962,7 +961,6 @@ int LUA_HookSeenPlayer(player_t *player, player_t *seenfriend) } return hook.status; } -#endif // SEENAMES int LUA_HookShouldJingleContinue(player_t *player, const char *musname) { From 83e80eef9ba1e60a71970807962ed49c9669eceb Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Sat, 12 Dec 2020 18:54:47 -0500 Subject: [PATCH 157/644] Add deprecation warning when using the level header parameter --- src/deh_soc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/deh_soc.c b/src/deh_soc.c index 2cd872378..2075d6484 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -1574,6 +1574,8 @@ void readlevelheader(MYFILE *f, INT32 num) sizeof(mapheaderinfo[num-1]->musname), va("Level header %d: music", num)); } } + else if (fastcmp(word, "MUSICSLOT")) + deh_warning("Level header %d: MusicSlot parameter is deprecated and will be removed.\nUse \"Music\" instead.", num); else if (fastcmp(word, "MUSICTRACK")) mapheaderinfo[num-1]->mustrack = ((UINT16)i - 1); else if (fastcmp(word, "MUSICPOS")) From 7e0a1709de58ea290a6edef7d7f2b4ec28427ac8 Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Mon, 14 Dec 2020 00:53:42 -0300 Subject: [PATCH 158/644] Fix a crash in Picture_GetPatchPixel with PICFMT_DOOMPATCH formats --- src/r_picformats.c | 9 +++++---- src/r_textures.c | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/r_picformats.c b/src/r_picformats.c index 02f1de4ab..f87362c76 100644 --- a/src/r_picformats.c +++ b/src/r_picformats.c @@ -544,21 +544,22 @@ void *Picture_GetPatchPixel( UINT16 *s16 = NULL; UINT32 *s32 = NULL; softwarepatch_t *doompatch = (softwarepatch_t *)patch; + boolean isdoompatch = Picture_IsDoomPatchFormat(informat); INT16 width; if (patch == NULL) I_Error("Picture_GetPatchPixel: patch == NULL"); - width = (Picture_IsDoomPatchFormat(informat) ? patch->width : SHORT(patch->width)); + width = (isdoompatch ? SHORT(doompatch->width) : patch->width); if (x >= 0 && x < width) { INT32 colx = (flags & PICFLAGS_XFLIP) ? (width-1)-x : x; INT32 topdelta, prevdelta = -1; - INT32 colofs = (Picture_IsDoomPatchFormat(informat) ? LONG(patch->columnofs[colx]) : patch->columnofs[colx]); + INT32 colofs = (isdoompatch ? LONG(doompatch->columnofs[colx]) : patch->columnofs[colx]); - // Column offsets are pointers so no casting required - if (Picture_IsDoomPatchFormat(informat)) + // Column offsets are pointers, so no casting is required. + if (isdoompatch) column = (column_t *)((UINT8 *)doompatch + colofs); else column = (column_t *)((UINT8 *)patch->columns + colofs); diff --git a/src/r_textures.c b/src/r_textures.c index 9de9649e2..a006d739f 100644 --- a/src/r_textures.c +++ b/src/r_textures.c @@ -604,7 +604,7 @@ void *R_GetLevelFlat(levelflat_t *levelflat) levelflat->height = ds_flatheight = SHORT(patch->height); levelflat->picture = Z_Malloc(levelflat->width * levelflat->height, PU_LEVEL, NULL); - converted = Picture_FlatConvert(PICFMT_DOOMPATCH, patch, PICFMT_FLAT, 0, &size, levelflat->width, levelflat->height, patch->topoffset, patch->leftoffset, 0); + converted = Picture_FlatConvert(PICFMT_DOOMPATCH, patch, PICFMT_FLAT, 0, &size, levelflat->width, levelflat->height, SHORT(patch->topoffset), SHORT(patch->leftoffset), 0); M_Memcpy(levelflat->picture, converted, size); Z_Free(converted); } From ca78fc69cad750a5a915cd5519c2cc45c5ff5848 Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Mon, 14 Dec 2020 01:14:55 -0300 Subject: [PATCH 159/644] Restore the viewpoint's angle in R_DrawPlanes instead --- src/r_plane.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/r_plane.c b/src/r_plane.c index c54b32382..b5ac7252f 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -607,6 +607,7 @@ void R_MakeSpans(INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2) void R_DrawPlanes(void) { visplane_t *pl; + angle_t va = viewangle; INT32 i; R_UpdatePlaneRipple(); @@ -621,6 +622,8 @@ void R_DrawPlanes(void) R_DrawSinglePlane(pl); } } + + viewangle = va; } // R_DrawSkyPlane @@ -788,7 +791,6 @@ void R_DrawSinglePlane(visplane_t *pl) ffloor_t *rover; int type; int spanfunctype = BASEDRAWFUNC; - angle_t viewang = viewangle; if (!(pl->minx <= pl->maxx)) return; @@ -1153,8 +1155,6 @@ using the palette colors. } } #endif - - viewangle = viewang; } void R_PlaneBounds(visplane_t *plane) From 6160a2d0fe6a09990a0fca6b0c9e5c4f75191e0e Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Mon, 14 Dec 2020 02:07:12 -0300 Subject: [PATCH 160/644] Fix a misuse of levelflat_t.picture in OpenGL (Kitchen Sink SRB2 port) --- src/hardware/hw_cache.c | 31 +++++++++++++++++++------------ src/hardware/hw_draw.c | 2 +- src/hardware/hw_glob.h | 2 +- src/p_setup.h | 1 + 4 files changed, 22 insertions(+), 14 deletions(-) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index b4fa7ec6c..6048affe0 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -850,7 +850,7 @@ static void HWR_CacheTextureAsFlat(GLMipmap_t *grMipmap, INT32 texturenum) } // Download a Doom 'flat' to the hardware cache and make it ready for use -void HWR_LiterallyGetFlat(lumpnum_t flatlumpnum) +void HWR_GetRawFlat(lumpnum_t flatlumpnum) { GLMipmap_t *grmip; patch_t *patch; @@ -879,7 +879,7 @@ void HWR_GetLevelFlat(levelflat_t *levelflat) return; if (levelflat->type == LEVELFLAT_FLAT) - HWR_LiterallyGetFlat(levelflat->u.flat.lumpnum); + HWR_GetRawFlat(levelflat->u.flat.lumpnum); else if (levelflat->type == LEVELFLAT_TEXTURE) { GLMapTexture_t *grtex; @@ -918,15 +918,17 @@ void HWR_GetLevelFlat(levelflat_t *levelflat) #ifndef NO_PNG_LUMPS else if (levelflat->type == LEVELFLAT_PNG) { - INT32 pngwidth = 0, pngheight = 0; GLMipmap_t *mipmap = levelflat->mipmap; - UINT8 *flat; - size_t size; // Cache the picture. - if (!levelflat->picture) + if (!levelflat->mippic) { - levelflat->picture = Picture_PNGConvert(W_CacheLumpNum(levelflat->u.flat.lumpnum, PU_CACHE), PICFMT_FLAT, &pngwidth, &pngheight, NULL, NULL, W_LumpLength(levelflat->u.flat.lumpnum), NULL, 0); + INT32 pngwidth = 0, pngheight = 0; + void *pic = Picture_PNGConvert(W_CacheLumpNum(levelflat->u.flat.lumpnum, PU_CACHE), PICFMT_FLAT, &pngwidth, &pngheight, NULL, NULL, W_LumpLength(levelflat->u.flat.lumpnum), NULL, 0); + + Z_ChangeTag(pic, PU_LEVEL); + Z_SetUser(pic, &levelflat->mippic); + levelflat->width = (UINT16)pngwidth; levelflat->height = (UINT16)pngheight; } @@ -934,7 +936,7 @@ void HWR_GetLevelFlat(levelflat_t *levelflat) // Make the mipmap. if (mipmap == NULL) { - mipmap = Z_Calloc(sizeof(GLMipmap_t), PU_LEVEL, NULL); + mipmap = Z_Calloc(sizeof(GLMipmap_t), PU_STATIC, NULL); mipmap->format = GL_TEXFMT_P_8; mipmap->flags = TF_WRAPXY|TF_CHROMAKEYED; levelflat->mipmap = mipmap; @@ -942,17 +944,22 @@ void HWR_GetLevelFlat(levelflat_t *levelflat) if (!mipmap->data && !mipmap->downloaded) { + UINT8 *flat; + size_t size; + + if (levelflat->mippic == NULL) + I_Error("HWR_GetLevelFlat: levelflat->mippic == NULL"); + mipmap->width = levelflat->width; mipmap->height = levelflat->height; + size = (mipmap->width * mipmap->height); flat = Z_Malloc(size, PU_LEVEL, &mipmap->data); - if (levelflat->picture == NULL) - I_Error("HWR_GetLevelFlat: levelflat->picture == NULL"); - M_Memcpy(flat, levelflat->picture, size); + M_Memcpy(flat, levelflat->mippic, size); } // Tell the hardware driver to bind the current texture to the flat's mipmap - HWD.pfnSetTexture(mipmap); + HWR_SetCurrentTexture(mipmap); } #endif else // set no texture diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index c5d362520..8c92c6709 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -639,7 +639,7 @@ void HWR_DrawFlatFill (INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatlumpnum v[0].t = v[1].t = (float)((y & flatflag)/dflatsize); v[2].t = v[3].t = (float)(v[0].t + h/dflatsize); - HWR_LiterallyGetFlat(flatlumpnum); + HWR_GetRawFlat(flatlumpnum); //Hurdler: Boris, the same comment as above... but maybe for pics // it not a problem since they don't have any transparent pixel diff --git a/src/hardware/hw_glob.h b/src/hardware/hw_glob.h index 87405d3d4..2aba62248 100644 --- a/src/hardware/hw_glob.h +++ b/src/hardware/hw_glob.h @@ -118,7 +118,7 @@ patch_t *HWR_GetPic(lumpnum_t lumpnum); GLMapTexture_t *HWR_GetTexture(INT32 tex); void HWR_GetLevelFlat(levelflat_t *levelflat); -void HWR_LiterallyGetFlat(lumpnum_t flatlumpnum); +void HWR_GetRawFlat(lumpnum_t flatlumpnum); void HWR_FreeTexture(patch_t *patch); void HWR_FreeTextureData(patch_t *patch); diff --git a/src/p_setup.h b/src/p_setup.h index 34de9c93d..5d13ae7d4 100644 --- a/src/p_setup.h +++ b/src/p_setup.h @@ -80,6 +80,7 @@ typedef struct UINT8 *picture; #ifdef HWRENDER void *mipmap; + void *mippic; #endif } levelflat_t; From 2b2346835920ca359891c1212e8210a3543a4c27 Mon Sep 17 00:00:00 2001 From: katsy Date: Mon, 14 Dec 2020 02:36:00 -0500 Subject: [PATCH 161/644] remove amy --- src/p_mobj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index badf19372..b116b756c 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11798,7 +11798,7 @@ static boolean P_AllowMobjSpawn(mapthing_t* mthing, mobjtype_t i) if (!(G_CoopGametype() || (mthing->options & MTF_EXTRA))) return false; // she doesn't hang out here - if (!mariomode && !(netgame || multiplayer) && players[consoleplayer].skin == 3) + if (!(netgame || multiplayer) && players[consoleplayer].skin == 3) return false; // no doubles break; From 0ce9d9127a7707aceb94c2f263508725438ef9dc Mon Sep 17 00:00:00 2001 From: katsy Date: Mon, 14 Dec 2020 04:01:50 -0500 Subject: [PATCH 162/644] add SF_NOSHIELDABILITY --- src/d_player.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/d_player.h b/src/d_player.h index eb0372832..0e0f623d3 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -51,7 +51,8 @@ typedef enum SF_NONIGHTSSUPER = 1<<15, // Disable super colors for NiGHTS (if you have SF_SUPER) SF_NOSUPERSPRITES = 1<<16, // Don't use super sprites while super SF_NOSUPERJUMPBOOST = 1<<17, // Disable the jump boost given while super (i.e. Knuckles) - SF_CANBUSTWALLS = 1<<18, // Can naturally bust walls on contact? (i.e. Knuckles) + SF_CANBUSTWALLS = 1<<18, // Can naturally bust walls on contact? (i.e. Knuckles) + SF_NOSHIELDABILITY = 1<<19, // Disable shield abilities // free up to and including 1<<31 } skinflags_t; From dfbb1825f460fcc3db33880450fea4c93bd2e648 Mon Sep 17 00:00:00 2001 From: katsy Date: Mon, 14 Dec 2020 04:02:17 -0500 Subject: [PATCH 163/644] ditto --- src/deh_tables.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/deh_tables.c b/src/deh_tables.c index 5733d9b0e..2a0f179d4 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -4987,6 +4987,8 @@ struct int_const_s const INT_CONST[] = { {"SF_NOSUPERSPRITES",SF_NOSUPERSPRITES}, {"SF_NOSUPERJUMPBOOST",SF_NOSUPERJUMPBOOST}, {"SF_CANBUSTWALLS",SF_CANBUSTWALLS}, + {"SF_NOSHIELDABILITY",SF_NOSHIELDABILITY}, + // Dashmode constants {"DASHMODE_THRESHOLD",DASHMODE_THRESHOLD}, From 2bebaf12d0f19e97a84577af8c75fa1e1523172a Mon Sep 17 00:00:00 2001 From: katsy Date: Mon, 14 Dec 2020 04:03:14 -0500 Subject: [PATCH 164/644] add checks for new flag, make emergency jump call shieldspecial --- src/p_user.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index c5f919c78..f06ad998d 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2491,6 +2491,7 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff) player->mo->momx = player->mo->momy = 0; clipmomz = false; } + else if ((player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP) // Bubble shield's bounce attack. { P_DoBubbleBounce(player); @@ -5020,7 +5021,7 @@ static boolean P_PlayerShieldThink(player_t *player, ticcmd_t *cmd, mobj_t *lock if ((player->powers[pw_shield] & SH_NOSTACK) && !player->powers[pw_super] && !(player->pflags & PF_SPINDOWN) && ((!(player->pflags & PF_THOKKED) || (((player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP || (player->powers[pw_shield] & SH_NOSTACK) == SH_ATTRACT) && player->secondjump == UINT8_MAX) ))) // thokked is optional if you're bubblewrapped / 3dblasted { - if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ATTRACT) + if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ATTRACT && !(player->charflags & SF_NOSHIELDABILITY)) { if ((lockonshield = P_LookForEnemies(player, false, false))) { @@ -5043,7 +5044,7 @@ static boolean P_PlayerShieldThink(player_t *player, ticcmd_t *cmd, mobj_t *lock } } } - if (cmd->buttons & BT_SPIN && !LUAh_ShieldSpecial(player)) // Spin button effects + if ((!(player->charflags & SF_NOSHIELDABILITY)) && (cmd->buttons & BT_SPIN && !LUAh_ShieldSpecial(player))) // Spin button effects { // Force stop if ((player->powers[pw_shield] & ~(SH_FORCEHP|SH_STACK)) == SH_FORCE) @@ -5491,7 +5492,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) break; } } - else if ((player->powers[pw_shield] & SH_NOSTACK) == SH_WHIRLWIND && !player->powers[pw_super]) + else if ((!(player->charflags & SF_NOSHIELDABILITY)) && ((player->powers[pw_shield] & SH_NOSTACK) == SH_WHIRLWIND && !player->powers[pw_super] && !LUAh_ShieldSpecial(player))) P_DoJumpShield(player); } From 200e444016f61556fb080d956903364fee304abe Mon Sep 17 00:00:00 2001 From: katsy Date: Mon, 14 Dec 2020 04:05:14 -0500 Subject: [PATCH 165/644] go away whitespace --- src/deh_tables.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/deh_tables.c b/src/deh_tables.c index 2a0f179d4..e92a4f60c 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -4989,7 +4989,6 @@ struct int_const_s const INT_CONST[] = { {"SF_CANBUSTWALLS",SF_CANBUSTWALLS}, {"SF_NOSHIELDABILITY",SF_NOSHIELDABILITY}, - // Dashmode constants {"DASHMODE_THRESHOLD",DASHMODE_THRESHOLD}, {"DASHMODE_MAX",DASHMODE_MAX}, From 4521827e2c2b101db0ba3c8ddd114fd8a1b18bc7 Mon Sep 17 00:00:00 2001 From: katsy Date: Mon, 14 Dec 2020 04:06:28 -0500 Subject: [PATCH 166/644] you too --- src/p_user.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index f06ad998d..917c7ddf6 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2491,7 +2491,6 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff) player->mo->momx = player->mo->momy = 0; clipmomz = false; } - else if ((player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP) // Bubble shield's bounce attack. { P_DoBubbleBounce(player); From 00dff6d2836890bf51803530626047bf40f7b2fa Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 14 Dec 2020 05:53:57 -0800 Subject: [PATCH 167/644] Push "valid" only once --- src/lua_taglib.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/lua_taglib.c b/src/lua_taglib.c index 284b171a3..12d1a3c05 100644 --- a/src/lua_taglib.c +++ b/src/lua_taglib.c @@ -167,7 +167,7 @@ static void push_taglist(lua_State *L, int idx) static int has_valid_field(lua_State *L) { int equal; - lua_pushliteral(L, "valid"); + lua_rawgeti(L, LUA_ENVIRONINDEX, 1); equal = lua_rawequal(L, 2, -1); lua_pop(L, 1); return equal; @@ -392,6 +392,9 @@ static void open_taglist(lua_State *L) lua_setfield(L, -2, "has"); } +#define new_literal(L, s) \ + (lua_pushliteral(L, s), luaL_ref(L, -2)) + static void set_taglist_metatable(lua_State *L, const char *meta) { lua_createtable(L, 0, 4); @@ -399,6 +402,9 @@ static void set_taglist_metatable(lua_State *L, const char *meta) lua_setfield(L, -2, "taglist"); lua_pushcfunction(L, taglist_get); + lua_createtable(L, 0, 1); + new_literal(L, "valid"); + lua_setfenv(L, -2); lua_setfield(L, -2, "__index"); lua_pushcfunction(L, taglist_len); From d0f3a6d737137d2e68c4fb1506f8d7809f8801ae Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 14 Dec 2020 08:08:01 -0800 Subject: [PATCH 168/644] Better check for tag list userdata --- src/lua_taglib.c | 52 +++++++++++++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/src/lua_taglib.c b/src/lua_taglib.c index 12d1a3c05..c9f320fe8 100644 --- a/src/lua_taglib.c +++ b/src/lua_taglib.c @@ -156,13 +156,9 @@ static int lib_numTaggroupElements(lua_State *L) return 1; } -static void push_taglist(lua_State *L, int idx) -{ - lua_getmetatable(L, idx); - lua_pushliteral(L, "taglist"); - lua_rawget(L, -2); - lua_remove(L, -2); -} +#ifdef MUTABLE_TAGS +static int meta_ref[2]; +#endif static int has_valid_field(lua_State *L) { @@ -191,10 +187,19 @@ static taglist_t * valid_taglist(lua_State *L, int idx, boolean getting) static taglist_t * check_taglist(lua_State *L, int idx) { - luaL_checktype(L, idx, LUA_TUSERDATA); - push_taglist(L, idx); - luaL_argcheck(L, lua_toboolean(L, -1), idx, "must be a tag list"); - return valid_taglist(L, idx, false); + if (lua_isuserdata(L, idx) && lua_getmetatable(L, idx)) + { + lua_getref(L, meta_ref[0]); + lua_getref(L, meta_ref[1]); + + if (lua_rawequal(L, -3, -2) || lua_rawequal(L, -3, -1)) + { + lua_pop(L, 3); + return valid_taglist(L, idx, false); + } + } + + return luaL_argerror(L, idx, "must be a tag list"), NULL; } static int taglist_get(lua_State *L) @@ -223,7 +228,7 @@ static int taglist_get(lua_State *L) } else { - push_taglist(L, 1); + lua_getmetatable(L, 1); lua_replace(L, 1); lua_rawget(L, 1); return 1; @@ -395,12 +400,14 @@ static void open_taglist(lua_State *L) #define new_literal(L, s) \ (lua_pushliteral(L, s), luaL_ref(L, -2)) -static void set_taglist_metatable(lua_State *L, const char *meta) +#ifdef MUTABLE_TAGS +static int +#else +static void +#endif +set_taglist_metatable(lua_State *L, const char *meta) { - lua_createtable(L, 0, 4); - lua_getglobal(L, "taglist"); - lua_setfield(L, -2, "taglist"); - + luaL_newmetatable(L, meta); lua_pushcfunction(L, taglist_get); lua_createtable(L, 0, 1); new_literal(L, "valid"); @@ -412,7 +419,9 @@ static void set_taglist_metatable(lua_State *L, const char *meta) lua_pushcfunction(L, taglist_equal); lua_setfield(L, -2, "__eq"); - lua_setfield(L, LUA_REGISTRYINDEX, meta); +#ifdef MUTABLE_TAGS + return luaL_ref(L, LUA_REGISTRYINDEX); +#endif } int LUA_TagLib(lua_State *L) @@ -431,10 +440,11 @@ int LUA_TagLib(lua_State *L) open_taglist(L); - set_taglist_metatable(L, META_TAGLIST); - #ifdef MUTABLE_TAGS - set_taglist_metatable(L, META_SECTORTAGLIST); + meta_ref[0] = set_taglist_metatable(L, META_TAGLIST); + meta_ref[1] = set_taglist_metatable(L, META_SECTORTAGLIST); +#else + set_taglist_metatable(L, META_TAGLIST); #endif return 0; From 3b36005ceb1fa04f8c2875e5d614aeb8c419cef9 Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Mon, 14 Dec 2020 14:13:24 -0300 Subject: [PATCH 169/644] Replace the first entry in the taglist, instead of adding into it --- src/p_setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_setup.c b/src/p_setup.c index 41d8822e2..66243fb0e 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3171,7 +3171,7 @@ static void P_ConvertBinaryMap(void) switch (mapthings[i].type) { case 750: - Tag_Add(&mapthings[i].tags, mapthings[i].angle); + Tag_FSet(&mapthings[i].tags, mapthings[i].angle); break; case 760: case 761: From 9b8bacd08886375c1090d46d8d964f6c1c2b1be6 Mon Sep 17 00:00:00 2001 From: Zippy_Zolton Date: Mon, 14 Dec 2020 12:52:24 -0600 Subject: [PATCH 170/644] Redone colormaps by SonicX8000 --- src/console.c | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/src/console.c b/src/console.c index 982b0d550..3c19c5e18 100644 --- a/src/console.c +++ b/src/console.c @@ -378,24 +378,23 @@ static void CON_SetupColormaps(void) map[0xE] = (UINT8)o;\ map[0xF] = (UINT8)p; - // I tried to make them kinda close to the originals, tell me how I did! ~Golden - // decent but i made most of the colors better thanks for th help :3 + // Tried to keep the colors vanilla while adding some shades in between them ~SonicX8000 - // 0x1 0x3 0x9 0xF - colset(magentamap, 177, 177, 178, 178, 179, 179, 180, 180, 181, 181, 182, 182, 183, 183, 184, 184); - colset(yellowmap, 81, 81, 73, 73, 74, 74, 74, 65, 65, 65, 66, 66, 66, 67, 67, 67); - colset(lgreenmap, 97, 97, 98, 98, 99, 99, 100, 100, 101, 101, 102, 102, 103, 103, 104, 104); - colset(bluemap, 146, 146, 147, 147, 148, 148, 148, 149, 149, 149, 150, 150, 150, 151, 151, 151); - colset(redmap, 32, 32, 33, 33, 34, 34, 34, 35, 35, 35, 37, 37, 37, 39, 39, 39); - colset(graymap, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20); - colset(orangemap, 51, 51, 52, 52, 53, 53, 54, 54, 55, 55, 56, 56, 57, 57, 58, 58); - colset(skymap, 128, 128, 129, 129, 130, 130, 131, 131, 132, 132, 133, 133, 134, 134, 135, 135); - colset(purplemap, 144, 144, 160, 160, 161, 161, 161, 162, 162, 162, 163, 163, 163, 164, 164, 164); - colset(aquamap, 120, 120, 121, 121, 122, 122, 122, 123, 123, 123, 124, 124, 124, 125, 125, 125); - colset(peridotmap, 72, 72, 188, 188, 189, 189, 189, 190, 190, 190, 191, 191, 191, 104, 104, 104); - colset(azuremap, 144, 144, 145, 145, 146, 146, 146, 170, 170, 170, 171, 171, 171, 172, 172, 172); - colset(brownmap, 218, 219, 220, 221, 221, 222, 223, 223, 224, 224, 225, 226, 227, 228, 229, 230); - colset(rosymap, 200, 200, 201, 201, 202, 202, 202, 203, 203, 203, 204, 204, 204, 205, 205, 205); + // 0x1 0x3 0x9 0xF + colset(magentamap, 177, 177, 178, 178, 178, 181, 181, 181, 183, 183, 183, 183, 185, 185, 185, 186); + colset(yellowmap, 82, 82, 73, 73, 73, 64, 64, 64, 66, 66, 66, 66, 67, 67, 67, 68); + colset(lgreenmap, 96, 96, 98, 98, 98, 101, 101, 101, 105, 105, 105, 105, 107, 107, 107, 108); + colset(bluemap, 146, 146, 147, 147, 147, 149, 149, 149, 152, 152, 152, 152, 155, 155, 155, 157); + colset(redmap, 32, 32, 33, 33, 33, 35, 35, 35, 39, 39, 39, 39, 42, 42, 42, 44); + colset(graymap, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23); + colset(orangemap, 50, 50, 52, 52, 52, 54, 54, 54, 56, 56, 56, 56, 59, 59, 59, 60); + colset(skymap, 129, 129, 130, 130, 130, 131, 131, 131, 133, 133, 133, 133, 135, 135, 135, 136); + colset(purplemap, 160, 160, 161, 161, 161, 162, 162, 162, 163, 163, 163, 163, 164, 164, 164, 165); + colset(aquamap, 120, 120, 121, 121, 121, 122, 122, 122, 123, 123, 123, 123, 124, 124, 124, 125); + colset(peridotmap, 72, 72, 188, 188, 189, 189, 189, 189, 190, 190, 190, 190, 191, 191, 191, 94); + colset(azuremap, 144, 144, 145, 145, 145, 146, 146, 146, 170, 170, 170, 170, 171, 171, 171, 172); + colset(brownmap, 219, 219, 221, 221, 221, 222, 222, 222, 224, 224, 224, 224, 227, 227, 227, 229); + colset(rosymap, 200, 200, 201, 201, 201, 202, 202, 202, 203, 203, 203, 203, 204, 204, 204, 205); #undef colset From 07034cf44116b54bf769c80b42c39586b90338b6 Mon Sep 17 00:00:00 2001 From: Zippy_Zolton Date: Mon, 14 Dec 2020 16:14:20 -0600 Subject: [PATCH 171/644] fixes spaces --- src/console.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/console.c b/src/console.c index 3c19c5e18..478f93fc8 100644 --- a/src/console.c +++ b/src/console.c @@ -378,23 +378,23 @@ static void CON_SetupColormaps(void) map[0xE] = (UINT8)o;\ map[0xF] = (UINT8)p; - // Tried to keep the colors vanilla while adding some shades in between them ~SonicX8000 + // Tried to keep the colors vanilla while adding some shades in between them ~SonicX8000 - // 0x1 0x3 0x9 0xF - colset(magentamap, 177, 177, 178, 178, 178, 181, 181, 181, 183, 183, 183, 183, 185, 185, 185, 186); - colset(yellowmap, 82, 82, 73, 73, 73, 64, 64, 64, 66, 66, 66, 66, 67, 67, 67, 68); - colset(lgreenmap, 96, 96, 98, 98, 98, 101, 101, 101, 105, 105, 105, 105, 107, 107, 107, 108); - colset(bluemap, 146, 146, 147, 147, 147, 149, 149, 149, 152, 152, 152, 152, 155, 155, 155, 157); - colset(redmap, 32, 32, 33, 33, 33, 35, 35, 35, 39, 39, 39, 39, 42, 42, 42, 44); - colset(graymap, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23); - colset(orangemap, 50, 50, 52, 52, 52, 54, 54, 54, 56, 56, 56, 56, 59, 59, 59, 60); - colset(skymap, 129, 129, 130, 130, 130, 131, 131, 131, 133, 133, 133, 133, 135, 135, 135, 136); - colset(purplemap, 160, 160, 161, 161, 161, 162, 162, 162, 163, 163, 163, 163, 164, 164, 164, 165); - colset(aquamap, 120, 120, 121, 121, 121, 122, 122, 122, 123, 123, 123, 123, 124, 124, 124, 125); + // 0x1 0x3 0x9 0xF + colset(magentamap, 177, 177, 178, 178, 178, 181, 181, 181, 183, 183, 183, 183, 185, 185, 185, 186); + colset(yellowmap, 82, 82, 73, 73, 73, 64, 64, 64, 66, 66, 66, 66, 67, 67, 67, 68); + colset(lgreenmap, 96, 96, 98, 98, 98, 101, 101, 101, 105, 105, 105, 105, 107, 107, 107, 108); + colset(bluemap, 146, 146, 147, 147, 147, 149, 149, 149, 152, 152, 152, 152, 155, 155, 155, 157); + colset(redmap, 32, 32, 33, 33, 33, 35, 35, 35, 39, 39, 39, 39, 42, 42, 42, 44); + colset(graymap, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23); + colset(orangemap, 50, 50, 52, 52, 52, 54, 54, 54, 56, 56, 56, 56, 59, 59, 59, 60); + colset(skymap, 129, 129, 130, 130, 130, 131, 131, 131, 133, 133, 133, 133, 135, 135, 135, 136); + colset(purplemap, 160, 160, 161, 161, 161, 162, 162, 162, 163, 163, 163, 163, 164, 164, 164, 165); + colset(aquamap, 120, 120, 121, 121, 121, 122, 122, 122, 123, 123, 123, 123, 124, 124, 124, 125); colset(peridotmap, 72, 72, 188, 188, 189, 189, 189, 189, 190, 190, 190, 190, 191, 191, 191, 94); - colset(azuremap, 144, 144, 145, 145, 145, 146, 146, 146, 170, 170, 170, 170, 171, 171, 171, 172); - colset(brownmap, 219, 219, 221, 221, 221, 222, 222, 222, 224, 224, 224, 224, 227, 227, 227, 229); - colset(rosymap, 200, 200, 201, 201, 201, 202, 202, 202, 203, 203, 203, 203, 204, 204, 204, 205); + colset(azuremap, 144, 144, 145, 145, 145, 146, 146, 146, 170, 170, 170, 170, 171, 171, 171, 172); + colset(brownmap, 219, 219, 221, 221, 221, 222, 222, 222, 224, 224, 224, 224, 227, 227, 227, 229); + colset(rosymap, 200, 200, 201, 201, 201, 202, 202, 202, 203, 203, 203, 203, 204, 204, 204, 205); #undef colset From d999e436f1883dead04b1b603a67e3f9efa9e547 Mon Sep 17 00:00:00 2001 From: katsy Date: Mon, 14 Dec 2020 20:23:24 -0500 Subject: [PATCH 172/644] GETFLAG --- src/r_skins.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/r_skins.c b/src/r_skins.c index 522d9236a..6f150f234 100644 --- a/src/r_skins.c +++ b/src/r_skins.c @@ -514,6 +514,7 @@ static boolean R_ProcessPatchableFields(skin_t *skin, char *stoken, char *value) GETFLAG(NOSUPERSPRITES) GETFLAG(NOSUPERJUMPBOOST) GETFLAG(CANBUSTWALLS) + GETFLAG(NOSHIELDABILITY) #undef GETFLAG else // let's check if it's a sound, otherwise error out From fa9db2d64424bb6bfd98b350f43e44a63dfe8095 Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Wed, 16 Dec 2020 00:26:08 -0300 Subject: [PATCH 173/644] Fix vibing slope planes I messed up the multiplication order for texture scaling: it multiplied a floating point number with a fixed point number, instead of multiplying two floats and then converting the result into a fixed point number. --- src/r_plane.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/r_plane.c b/src/r_plane.c index c54b32382..194f85c4a 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -705,9 +705,9 @@ void R_CalculateSlopeVectors(pslope_t *slope, fixed_t planeviewx, fixed_t planev n.z = -xscale * cos(ang); ang = ANG2RAD(planeangle); - temp = P_GetSlopeZAt(slope, planeviewx + yscale * FLOAT_TO_FIXED(sin(ang)), planeviewy + yscale * FLOAT_TO_FIXED(cos(ang))); + temp = P_GetSlopeZAt(slope, planeviewx + FLOAT_TO_FIXED(yscale * sin(ang)), planeviewy + FLOAT_TO_FIXED(yscale * cos(ang))); m.y = FIXED_TO_FLOAT(temp) - zeroheight; - temp = P_GetSlopeZAt(slope, planeviewx + xscale * FLOAT_TO_FIXED(cos(ang)), planeviewy - xscale * FLOAT_TO_FIXED(sin(ang))); + temp = P_GetSlopeZAt(slope, planeviewx + FLOAT_TO_FIXED(xscale * cos(ang)), planeviewy - FLOAT_TO_FIXED(xscale * sin(ang))); n.y = FIXED_TO_FLOAT(temp) - zeroheight; if (ds_powersoftwo) From 45976d230454f37f62ca0c5cef5d1506c73dbccd Mon Sep 17 00:00:00 2001 From: Zippy_Zolton Date: Tue, 15 Dec 2020 22:19:57 -0600 Subject: [PATCH 174/644] magenta and green sonicx --- src/console.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/console.c b/src/console.c index 478f93fc8..c7bfe0fe1 100644 --- a/src/console.c +++ b/src/console.c @@ -381,9 +381,9 @@ static void CON_SetupColormaps(void) // Tried to keep the colors vanilla while adding some shades in between them ~SonicX8000 // 0x1 0x3 0x9 0xF - colset(magentamap, 177, 177, 178, 178, 178, 181, 181, 181, 183, 183, 183, 183, 185, 185, 185, 186); + colset(magentamap, 177, 177, 178, 178, 178, 180, 180, 180, 182, 182, 182, 182, 184, 184, 184, 185); colset(yellowmap, 82, 82, 73, 73, 73, 64, 64, 64, 66, 66, 66, 66, 67, 67, 67, 68); - colset(lgreenmap, 96, 96, 98, 98, 98, 101, 101, 101, 105, 105, 105, 105, 107, 107, 107, 108); + colset(lgreenmap, 96, 96, 98, 98, 98, 101, 101, 101, 104, 104, 104, 104, 106, 106, 106, 107); colset(bluemap, 146, 146, 147, 147, 147, 149, 149, 149, 152, 152, 152, 152, 155, 155, 155, 157); colset(redmap, 32, 32, 33, 33, 33, 35, 35, 35, 39, 39, 39, 39, 42, 42, 42, 44); colset(graymap, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23); From b82cee780a80fd502b99eb20ba0ae4b1bd1e287a Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Wed, 16 Dec 2020 17:35:39 +0100 Subject: [PATCH 175/644] Fix TICCMD_RECEIVED being overridden by gamelogic --- src/g_game.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/g_game.c b/src/g_game.c index 283113bbe..8813afaf1 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2266,14 +2266,21 @@ void G_Ticker(boolean run) { if (playeringame[i]) { + INT16 received; + G_CopyTiccmd(&players[i].cmd, &netcmds[buf][i], 1); + received = (players[i].cmd.angleturn & TICCMD_RECEIVED); + players[i].angleturn += players[i].cmd.angleturn - players[i].oldrelangleturn; players[i].oldrelangleturn = players[i].cmd.angleturn; if (P_ControlStyle(&players[i]) == CS_LMAOGALOG) P_ForceLocalAngle(&players[i], players[i].angleturn << 16); else players[i].cmd.angleturn = players[i].angleturn; + + players[i].cmd.angleturn &= ~TICCMD_RECEIVED; + players[i].cmd.angleturn |= received; } } From 4713b258376da8120a27aa7422e3ab9cbcfa7f3c Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 16 Dec 2020 08:41:58 -0800 Subject: [PATCH 176/644] Bit array conflicts --- src/lua_hooklib.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 3a63e446e..7f5e3dc96 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -38,18 +38,6 @@ static const char * const stringHookNames[] = { STRING_HOOK_LIST (TOSTR) NULL }; -/* TODO: remove when doomtype version is merged */ - -#define BIT_ARRAY_LENGTH(n) (((n) + 7) >> 3) - -static inline void set_bit_array (UINT8 *array, const int n) { - array[n >> 3] |= 1 << (n & 7); -} - -static inline int in_bit_array (const UINT8 *array, const int n) { - return array[n >> 3] & (1 << (n & 7)); -} - typedef struct { int numHooks; int *ids; @@ -215,7 +203,7 @@ static int lib_addHook(lua_State *L) if (!(nextid & 7)) { Z_Realloc(hooksErrored, - BIT_ARRAY_LENGTH (nextid + 1) * sizeof *hooksErrored, + BIT_ARRAY_SIZE (nextid + 1) * sizeof *hooksErrored, PU_STATIC, &hooksErrored); hooksErrored[nextid >> 3] = 0; } From f91489bcb68b409a8349ed8b901be448ee4ca4ce Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Sat, 23 May 2020 17:06:10 -0500 Subject: [PATCH 177/644] Make the colormap returned by v.getColormap() writable. I mean it was already readable anyway... --- src/lua_hudlib.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index e58cd4a58..0da0cb662 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -277,7 +277,7 @@ static int hudinfo_num(lua_State *L) static int colormap_get(lua_State *L) { - const UINT8 *colormap = *((UINT8 **)luaL_checkudata(L, 1, META_COLORMAP)); + UINT8 *colormap = *((UINT8 **)luaL_checkudata(L, 1, META_COLORMAP)); UINT32 i = luaL_checkinteger(L, 2); if (i >= 256) return luaL_error(L, "colormap index %d out of range (0 - %d)", i, 255); @@ -285,6 +285,16 @@ static int colormap_get(lua_State *L) return 1; } +static int colormap_set(lua_State *L) +{ + UINT8 *colormap = *((UINT8 **)luaL_checkudata(L, 1, META_COLORMAP)); + UINT32 i = luaL_checkinteger(L, 2); + if (i >= 256) + return luaL_error(L, "colormap index %d out of range (0 - %d)", i, 255); + colormap[i] = (UINT8)luaL_checkinteger(L, 3); + return 0; +} + static int patch_get(lua_State *L) { patch_t *patch = *((patch_t **)luaL_checkudata(L, 1, META_PATCH)); @@ -1230,6 +1240,9 @@ int LUA_HudLib(lua_State *L) luaL_newmetatable(L, META_COLORMAP); lua_pushcfunction(L, colormap_get); lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, colormap_set); + lua_setfield(L, -2, "__newindex"); lua_pop(L,1); luaL_newmetatable(L, META_PATCH); From 81ee4a75e3186a4936941c33a06f97b74f863f22 Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Sat, 28 Nov 2020 00:09:12 -0600 Subject: [PATCH 178/644] Copy colormaps so Lua cannot modify cached colormaps! (And Z_Free them on garbage collection.) --- src/lua_hudlib.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 0da0cb662..ab091eb2f 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -295,6 +295,13 @@ static int colormap_set(lua_State *L) return 0; } +static int colormap_free(lua_State *L) +{ + UINT8 *colormap = *((UINT8 **)luaL_checkudata(L, 1, META_COLORMAP)); + Z_Free(colormap); + return 0; +} + static int patch_get(lua_State *L) { patch_t *patch = *((patch_t **)luaL_checkudata(L, 1, META_PATCH)); @@ -921,7 +928,7 @@ static int libd_getColormap(lua_State *L) // all was successful above, now we generate the colormap at last! - colormap = R_GetTranslationColormap(skinnum, color, GTC_CACHE); + colormap = R_GetTranslationColormap(skinnum, color, 0); LUA_PushUserdata(L, colormap, META_COLORMAP); // push as META_COLORMAP userdata, specifically for patches to use! return 1; } @@ -930,10 +937,14 @@ static int libd_getStringColormap(lua_State *L) { INT32 flags = luaL_checkinteger(L, 1); UINT8* colormap = NULL; + UINT8* lua_colormap = NULL; HUDONLY colormap = V_GetStringColormap(flags & V_CHARCOLORMASK); if (colormap) { - LUA_PushUserdata(L, colormap, META_COLORMAP); // push as META_COLORMAP userdata, specifically for patches to use! + lua_colormap = Z_Malloc(256 * sizeof(UINT8), PU_LUA, NULL); + memcpy(lua_colormap, colormap, 256 * sizeof(UINT8)); + + LUA_PushUserdata(L, lua_colormap, META_COLORMAP); // push as META_COLORMAP userdata, specifically for patches to use! return 1; } return 0; @@ -1243,6 +1254,9 @@ int LUA_HudLib(lua_State *L) lua_pushcfunction(L, colormap_set); lua_setfield(L, -2, "__newindex"); + + lua_pushcfunction(L, colormap_free); + lua_setfield(L, -2, "__gc"); lua_pop(L,1); luaL_newmetatable(L, META_PATCH); From 4717261459efb5861943cb46a65b0038b5b9eb3c Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Sat, 19 Dec 2020 17:32:45 -0300 Subject: [PATCH 179/644] Optimize Picture_GetPatchPixel --- src/r_picformats.c | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/src/r_picformats.c b/src/r_picformats.c index f87362c76..eeebb94fd 100644 --- a/src/r_picformats.c +++ b/src/r_picformats.c @@ -540,9 +540,7 @@ void *Picture_GetPatchPixel( { fixed_t ofs; column_t *column; - UINT8 *s8 = NULL; - UINT16 *s16 = NULL; - UINT32 *s32 = NULL; + INT32 inbpp = Picture_FormatBPP(informat); softwarepatch_t *doompatch = (softwarepatch_t *)patch; boolean isdoompatch = Picture_IsDoomPatchFormat(informat); INT16 width; @@ -566,30 +564,36 @@ void *Picture_GetPatchPixel( while (column->topdelta != 0xff) { + UINT8 *s8 = NULL; + UINT16 *s16 = NULL; + UINT32 *s32 = NULL; + topdelta = column->topdelta; if (topdelta <= prevdelta) topdelta += prevdelta; prevdelta = topdelta; - s8 = (UINT8 *)(column) + 3; - if (Picture_FormatBPP(informat) == PICDEPTH_32BPP) - s32 = (UINT32 *)s8; - else if (Picture_FormatBPP(informat) == PICDEPTH_16BPP) - s16 = (UINT16 *)s8; - for (ofs = 0; ofs < column->length; ofs++) + + ofs = (y - topdelta); + + if (y >= topdelta && ofs < column->length) { - if ((topdelta + ofs) == y) + s8 = (UINT8 *)(column) + 3; + switch (inbpp) { - if (Picture_FormatBPP(informat) == PICDEPTH_32BPP) + case PICDEPTH_32BPP: + s32 = (UINT32 *)s8; return &s32[ofs]; - else if (Picture_FormatBPP(informat) == PICDEPTH_16BPP) + case PICDEPTH_16BPP: + s16 = (UINT16 *)s8; return &s16[ofs]; - else // PICDEPTH_8BPP + default: // PICDEPTH_8BPP return &s8[ofs]; } } - if (Picture_FormatBPP(informat) == PICDEPTH_32BPP) + + if (inbpp == PICDEPTH_32BPP) column = (column_t *)((UINT32 *)column + column->length); - else if (Picture_FormatBPP(informat) == PICDEPTH_16BPP) + else if (inbpp == PICDEPTH_16BPP) column = (column_t *)((UINT16 *)column + column->length); else column = (column_t *)((UINT8 *)column + column->length); From 1254f691ee6d7262865c71d7c554c6300ffc7849 Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Sat, 19 Dec 2020 17:40:18 -0300 Subject: [PATCH 180/644] Fix unused variable warning when USE_APNG is not defined --- src/m_misc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/m_misc.c b/src/m_misc.c index ad2d133ab..17a398b83 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -165,7 +165,9 @@ consvar_t cv_zlib_window_bitsa = CVAR_INIT ("apng_window_size", "32k", CV_SAVE, consvar_t cv_apng_delay = CVAR_INIT ("apng_speed", "1x", CV_SAVE, apng_delay_t, NULL); consvar_t cv_apng_downscale = CVAR_INIT ("apng_downscale", "On", CV_SAVE, CV_OnOff, NULL); +#ifdef USE_APNG static boolean apng_downscale = false; // So nobody can do something dumb like changing cvars mid output +#endif boolean takescreenshot = false; // Take a screenshot this tic From f9e5681a6b29cc87e220cd7c224f605cd2e843a6 Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Sat, 19 Dec 2020 20:33:29 -0600 Subject: [PATCH 181/644] Actually check for a player smh --- src/p_enemy.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 203e04af1..1cc1686b1 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -7521,7 +7521,7 @@ void A_Boss2PogoTarget(mobj_t *actor) } // Target hit, retreat! - if (actor->target->player->powers[pw_flashing] > TICRATE || actor->flags2 & MF2_FRET) + if ((actor->target->player && actor->target->player->powers[pw_flashing] > TICRATE) || actor->flags2 & MF2_FRET) { UINT8 prandom = P_RandomByte(); actor->z++; // unstick from the floor @@ -7532,7 +7532,7 @@ void A_Boss2PogoTarget(mobj_t *actor) // Try to land on top of the player. else if (P_AproxDistance(actor->x-actor->target->x, actor->y-actor->target->y) < FixedMul(512*FRACUNIT, actor->scale)) { - fixed_t airtime, gravityadd, zoffs; + fixed_t airtime, gravityadd, zoffs, height; // check gravity in the sector (for later math) P_CheckGravity(actor, true); @@ -7554,7 +7554,13 @@ void A_Boss2PogoTarget(mobj_t *actor) // Remember, kids! // Reduced down Calculus lets you avoid bad 'logic math' loops! //airtime = FixedDiv(-actor->momz<<1, gravityadd)<<1; // going from 0 to 0 is much simpler - zoffs = (P_GetPlayerHeight(actor->target->player)>>1) + (actor->target->floorz - actor->floorz); // offset by the difference in floor height plus half the player height, + + if (actor->target->player) + height = P_GetPlayerHeight(actor->target->player) >> 1; + else + height = actor->target->height >> 1; + + zoffs = height + (actor->target->floorz - actor->floorz); // offset by the difference in floor height plus half the player height, airtime = FixedDiv((-actor->momz - FixedSqrt(FixedMul(actor->momz,actor->momz)+zoffs)), gravityadd)<<1; // to try and land on their head rather than on their feet actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y); From 60564197afa4629a5f71bba673381e52874320e3 Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Sat, 19 Dec 2020 21:12:09 -0600 Subject: [PATCH 182/644] Have A_DetonChase check for a player too --- src/p_enemy.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 1cc1686b1..898dcd3cc 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -5920,13 +5920,18 @@ void A_DetonChase(mobj_t *actor) if (actor->reactiontime == -42) { - fixed_t xyspeed; + fixed_t xyspeed, speed; + + if (actor->target->player) + speed = actor->target->player->normalspeed; + else + speed = actor->target->info->speed; actor->reactiontime = -42; exact = actor->movedir>>ANGLETOFINESHIFT; - xyspeed = FixedMul(FixedMul(actor->tracer->player->normalspeed,3*FRACUNIT/4), FINECOSINE(exact)); - actor->momz = FixedMul(FixedMul(actor->tracer->player->normalspeed,3*FRACUNIT/4), FINESINE(exact)); + xyspeed = FixedMul(FixedMul(speed,3*FRACUNIT/4), FINECOSINE(exact)); + actor->momz = FixedMul(FixedMul(speed,3*FRACUNIT/4), FINESINE(exact)); exact = actor->angle>>ANGLETOFINESHIFT; actor->momx = FixedMul(xyspeed, FINECOSINE(exact)); From 08146c9cad42f8a30a6b54386194ed22825d024a Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Sat, 19 Dec 2020 21:30:13 -0600 Subject: [PATCH 183/644] Have A_ThrownRing check for a player too --- src/p_enemy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 898dcd3cc..3e7f52a3f 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -4912,7 +4912,7 @@ void A_ThrownRing(mobj_t *actor) } if (actor->tracer && (actor->tracer->health) - && (actor->tracer->player->powers[pw_shield] & SH_PROTECTELECTRIC))// Already found someone to follow. + && (actor->tracer->player && actor->tracer->player->powers[pw_shield] & SH_PROTECTELECTRIC))// Already found someone to follow. { const INT32 temp = actor->threshold; actor->threshold = 32000; From 6c330bbf16a6dba4919d538d418b6b60f94b8244 Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Mon, 21 Dec 2020 00:03:20 +0200 Subject: [PATCH 184/644] Fix video mode 0 not getting centered --- src/screen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/screen.c b/src/screen.c index 9d36eee39..744523dab 100644 --- a/src/screen.c +++ b/src/screen.c @@ -217,7 +217,7 @@ void SCR_SetMode(void) // Set the video mode in the video interface. if (setmodeneeded) - VID_SetMode(--setmodeneeded); + VID_SetMode(setmodeneeded - 1); V_SetPalette(0); From 971518d22e2c7dcde18d44568bb256581db72370 Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Sun, 20 Dec 2020 21:43:14 -0600 Subject: [PATCH 185/644] Have Lua_OnChange restore the stack to what it was before it was called. So we don't get Luas with access to LUA_GetErrorMessage. --- src/lua_consolelib.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lua_consolelib.c b/src/lua_consolelib.c index 84bfeaee2..5344fee76 100644 --- a/src/lua_consolelib.c +++ b/src/lua_consolelib.c @@ -285,8 +285,8 @@ static void Lua_OnChange(void) /// \todo Network this! XD_LUAVAR - lua_settop(gL, 0); // Just in case... lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_insert(gL, 1); // Because LUA_Call wants it at index 1. // From CV_OnChange registry field, get the function for this cvar by name. lua_getfield(gL, LUA_REGISTRYINDEX, "CV_OnChange"); @@ -301,6 +301,7 @@ static void Lua_OnChange(void) LUA_Call(gL, 1, 0, 1); // call function(cvar) lua_pop(gL, 1); // pop CV_OnChange table + lua_remove(gL, 1); // remove LUA_GetErrorMessage } static int lib_cvRegisterVar(lua_State *L) From 147c38c5ce489e2760f922ec98214005cfa9f99b Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Mon, 21 Dec 2020 02:03:44 -0600 Subject: [PATCH 186/644] Make sliding against objects actually work --- src/p_map.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/p_map.c b/src/p_map.c index b934e3255..a1cad524e 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -2257,6 +2257,8 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) { if (!P_BlockThingsIterator(bx, by, PIT_CheckThing)) blockval = false; + else + tmhitthing = tmfloorthing; if (P_MobjWasRemoved(tmthing)) return false; } From abf0ca6690a3cb66b89030fda85ad24ccfa7b9b1 Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Mon, 21 Dec 2020 17:19:07 -0300 Subject: [PATCH 187/644] Fix "missing initializer" warnings/errors in CVAR_INIT macros --- src/command.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/command.h b/src/command.h index ea5593395..d4033e6ef 100644 --- a/src/command.h +++ b/src/command.h @@ -158,7 +158,7 @@ typedef struct consvar_s //NULL, NULL, 0, NULL, NULL |, 0, NULL, NULL, 0, 0, NUL /* name, defaultvalue, flags, PossibleValue, func */ #define CVAR_INIT( ... ) \ -{ __VA_ARGS__, 0, NULL, NULL, {0}, 0U, (char)0, NULL } +{ __VA_ARGS__, 0, NULL, NULL, {0, {NULL}}, 0U, (char)0, NULL } #ifdef OLD22DEMOCOMPAT typedef struct old_demo_var old_demo_var_t; From ad8abcef0942d8deb055908cbd9d145314e78eca Mon Sep 17 00:00:00 2001 From: SwitchKaze Date: Mon, 21 Dec 2020 15:48:49 -0600 Subject: [PATCH 188/644] Return nil on skincolor invalid field access --- src/lua_infolib.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/lua_infolib.c b/src/lua_infolib.c index 4c6ef3528..6e86f47b7 100644 --- a/src/lua_infolib.c +++ b/src/lua_infolib.c @@ -1635,8 +1635,10 @@ static int skincolor_get(lua_State *L) lua_pushinteger(L, info->chatcolor); else if (fastcmp(field,"accessible")) lua_pushboolean(L, info->accessible); - else + else { CONS_Debug(DBG_LUA, M_GetText("'%s' has no field named '%s'; returning nil.\n"), "skincolor_t", field); + return 0; + } return 1; } From 4d6b677765d48b84addbf107caa7bb5e19f4715f Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 23 Dec 2020 03:02:31 +0000 Subject: [PATCH 189/644] Revert "Merge branch 'plane-sorting-fix-part-3' into 'next'" This reverts merge request !1235 --- src/r_things.c | 62 ++++++++++++++++++++++++++++++++++++-------------- src/r_things.h | 4 +++- 2 files changed, 48 insertions(+), 18 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 083373927..30bf15f85 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1078,6 +1078,14 @@ static void R_SplitSprite(vissprite_t *sprite) sprite->sz = cutfrac; newsprite->szt = (INT16)(sprite->sz - 1); + if (testheight < sprite->pzt && testheight > sprite->pz) + sprite->pz = newsprite->pzt = testheight; + else + { + newsprite->pz = newsprite->gz; + newsprite->pzt = newsprite->gzt; + } + newsprite->szt -= 8; newsprite->cut |= SC_TOP; @@ -1300,12 +1308,16 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, shadow->patch = patch; shadow->heightsec = vis->heightsec; + shadow->thingheight = FRACUNIT; + shadow->pz = groundz + (isflipped ? -shadow->thingheight : 0); + shadow->pzt = shadow->pz + shadow->thingheight; + shadow->mobjflags = 0; shadow->sortscale = vis->sortscale; shadow->dispoffset = vis->dispoffset - 5; shadow->gx = thing->x; shadow->gy = thing->y; - shadow->gzt = groundz + patch->height * shadowyscale / 2; + shadow->gzt = (isflipped ? shadow->pzt : shadow->pz) + patch->height * shadowyscale / 2; shadow->gz = shadow->gzt - patch->height * shadowyscale; shadow->texturemid = FixedMul(thing->scale, FixedDiv(shadow->gzt - viewz, shadowyscale)); if (thing->skin && ((skin_t *)thing->skin)->flags & SF_HIRES) @@ -1935,6 +1947,9 @@ static void R_ProjectSprite(mobj_t *thing) vis->gy = thing->y; vis->gz = gz; vis->gzt = gzt; + vis->thingheight = thing->height; + vis->pz = thing->z; + vis->pzt = vis->pz + vis->thingheight; vis->texturemid = FixedDiv(gzt - viewz, spriteyscale); vis->scalestep = scalestep; vis->paperoffset = paperoffset; @@ -2151,6 +2166,9 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) vis->gy = thing->y; vis->gz = gz; vis->gzt = gzt; + vis->thingheight = 4*FRACUNIT; + vis->pz = thing->z; + vis->pzt = vis->pz + vis->thingheight; vis->texturemid = vis->gzt - viewz; vis->scalestep = 0; vis->paperdistance = 0; @@ -2544,15 +2562,19 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps planeobjectz = P_GetZAt(r2->plane->slope, rover->gx, rover->gy, r2->plane->height); planecameraz = P_GetZAt(r2->plane->slope, viewx, viewy, r2->plane->height); - // bird: if any part of the sprite peeks in front the plane - if (planecameraz < viewz) + if (rover->mobjflags & MF_NOCLIPHEIGHT) { - if (rover->gzt >= planeobjectz) + //Objects with NOCLIPHEIGHT can appear halfway in. + if (planecameraz < viewz && rover->pz+(rover->thingheight/2) >= planeobjectz) + continue; + if (planecameraz > viewz && rover->pzt-(rover->thingheight/2) <= planeobjectz) continue; } - else if (planecameraz > viewz) + else { - if (rover->gz <= planeobjectz) + if (planecameraz < viewz && rover->pz >= planeobjectz) + continue; + if (planecameraz > viewz && rover->pzt <= planeobjectz) continue; } @@ -2585,7 +2607,7 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps } else if (r2->thickseg) { - //fixed_t topplaneobjectz, topplanecameraz, botplaneobjectz, botplanecameraz; + fixed_t topplaneobjectz, topplanecameraz, botplaneobjectz, botplanecameraz; if (rover->x1 > r2->thickseg->x2 || rover->x2 < r2->thickseg->x1) continue; @@ -2596,11 +2618,6 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps if (scale <= rover->sortscale) continue; - // bird: Always sort sprites behind segs. This helps the plane - // sorting above too. Basically if the sprite gets sorted behind - // the seg here, it will be behind the plane too, since planes - // are added after segs in the list. -#if 0 topplaneobjectz = P_GetFFloorTopZAt (r2->ffloor, rover->gx, rover->gy); topplanecameraz = P_GetFFloorTopZAt (r2->ffloor, viewx, viewy); botplaneobjectz = P_GetFFloorBottomZAt(r2->ffloor, rover->gx, rover->gy); @@ -2609,7 +2626,6 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps if ((topplanecameraz > viewz && botplanecameraz < viewz) || (topplanecameraz < viewz && rover->gzt < topplaneobjectz) || (botplanecameraz > viewz && rover->gz > botplaneobjectz)) -#endif { entry = R_CreateDrawNode(NULL); (entry->prev = r2->prev)->next = entry; @@ -2650,11 +2666,23 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps if (!behind) { - // FIXME: calculate gz and gzt for splats properly and use that - if (rover->mobj->z < viewz) - infront = (r2->sprite->mobj->z >= rover->mobj->z); + fixed_t z1 = 0, z2 = 0; + + if (rover->mobj->z - viewz > 0) + { + z1 = rover->pz; + z2 = r2->sprite->pz; + } else - infront = (r2->sprite->mobj->z <= rover->mobj->z); + { + z1 = r2->sprite->pz; + z2 = rover->pz; + } + + z1 -= viewz; + z2 -= viewz; + + infront = (z1 >= z2); } } else diff --git a/src/r_things.h b/src/r_things.h index d15ae818c..f960089a1 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -151,7 +151,8 @@ typedef struct vissprite_s INT32 x1, x2; fixed_t gx, gy; // for line side calculation - fixed_t gz, gzt; // global bottom/top for silhouette clipping and sorting with 3D floors + fixed_t gz, gzt; // global bottom/top for silhouette clipping + fixed_t pz, pzt; // physical bottom/top for sorting with 3D floors fixed_t startfrac; // horizontal position of x1 fixed_t scale; @@ -185,6 +186,7 @@ typedef struct vissprite_s fixed_t xscale; // Precalculated top and bottom screen coords for the sprite. + fixed_t thingheight; // The actual height of the thing (for 3D floors) sector_t *sector; // The sector containing the thing. INT16 sz, szt; From 0d1973075deafd5272f0cb9801f273d16e1736d9 Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Thu, 24 Dec 2020 03:22:08 -0600 Subject: [PATCH 190/644] Nice UDB config there, SRB2. --- extras/conf/udb/Includes/SRB222_things.cfg | 1 + 1 file changed, 1 insertion(+) diff --git a/extras/conf/udb/Includes/SRB222_things.cfg b/extras/conf/udb/Includes/SRB222_things.cfg index 0ea452155..113c1a4c2 100644 --- a/extras/conf/udb/Includes/SRB222_things.cfg +++ b/extras/conf/udb/Includes/SRB222_things.cfg @@ -1247,6 +1247,7 @@ patterns sprite = "SPHRA0"; width = 96; height = 192; + } 609 { title = "Circle of Rings and Spheres (Big)"; From 9327e96e4d4f4d15421b71bbba8a9c44c4244951 Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Sat, 26 Dec 2020 17:19:14 -0600 Subject: [PATCH 191/644] Pause the console refresh while startup wads are loading. --- src/console.c | 13 +++++++++++++ src/console.h | 3 +++ src/d_main.c | 4 ++++ 3 files changed, 20 insertions(+) diff --git a/src/console.c b/src/console.c index c7bfe0fe1..3785136af 100644 --- a/src/console.c +++ b/src/console.c @@ -484,6 +484,19 @@ void CON_Init(void) Unlock_state(); } } + +void CON_StartRefresh(void) +{ + if (con_startup) + con_refresh = true; +} + +void CON_StopRefresh(void) +{ + if (con_startup) + con_refresh = false; +} + // Console input initialization // static void CON_InputInit(void) diff --git a/src/console.h b/src/console.h index 0296f4f6e..db27d9358 100644 --- a/src/console.h +++ b/src/console.h @@ -16,6 +16,9 @@ void CON_Init(void); +void CON_StartRefresh(void); +void CON_StopRefresh(void); + boolean CON_Responder(event_t *ev); #ifdef HAVE_THREADS diff --git a/src/d_main.c b/src/d_main.c index a89f4ed2d..7d25208e7 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1275,10 +1275,14 @@ void D_SRB2Main(void) I_RegisterSysCommands(); + CON_StopRefresh(); // Temporarily stop refreshing the screen for wad loading + CONS_Printf("W_InitMultipleFiles(): Adding extra PWADs.\n"); W_InitMultipleFiles(startuppwads); D_CleanFile(startuppwads); + CON_StartRefresh(); // Restart the refresh! + CONS_Printf("HU_LoadGraphics()...\n"); HU_LoadGraphics(); From 50d46e1fa634abd6672ca6a8bf43daaec528fa80 Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Sun, 27 Dec 2020 00:21:09 -0600 Subject: [PATCH 192/644] Set the target of a spawned ghost to where it came from. --- src/p_user.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/p_user.c b/src/p_user.c index a70dceb8b..8361004d6 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2016,6 +2016,8 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj) { mobj_t *ghost = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_GHOST); + P_SetTarget(&ghost->target, mobj); + P_SetScale(ghost, mobj->scale); ghost->destscale = mobj->scale; From 0de3a64b59e6647a97efef630450f3565d06e4bd Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Tue, 29 Dec 2020 21:36:15 +0100 Subject: [PATCH 193/644] Let Lua toggle the crosshair --- src/hu_stuff.c | 19 +++++++++++-------- src/lua_hud.h | 1 + src/lua_hudlib.c | 1 + 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 7e9144f98..0b24d0690 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -2109,15 +2109,18 @@ void HU_Drawer(void) return; // draw the crosshair, not when viewing demos nor with chasecam - if (!automapactive && cv_crosshair.value && !demoplayback && - (!camera.chase || ticcmd_ztargetfocus[0]) - && !players[displayplayer].spectator) - HU_DrawCrosshair(); + if (LUA_HudEnabled(hud_crosshair)) + { + if (!automapactive && cv_crosshair.value && !demoplayback && + (!camera.chase || ticcmd_ztargetfocus[0]) + && !players[displayplayer].spectator) + HU_DrawCrosshair(); - if (!automapactive && cv_crosshair2.value && !demoplayback && - (!camera2.chase || ticcmd_ztargetfocus[1]) - && !players[secondarydisplayplayer].spectator) - HU_DrawCrosshair2(); + if (!automapactive && cv_crosshair2.value && !demoplayback && + (!camera2.chase || ticcmd_ztargetfocus[1]) + && !players[secondarydisplayplayer].spectator) + HU_DrawCrosshair2(); + } // draw desynch text if (hu_redownloadinggamestate) diff --git a/src/lua_hud.h b/src/lua_hud.h index 4a7c596c8..1e9dca00b 100644 --- a/src/lua_hud.h +++ b/src/lua_hud.h @@ -13,6 +13,7 @@ enum hud { hud_stagetitle = 0, hud_textspectator, + hud_crosshair, // Singleplayer / Co-op hud_score, hud_time, diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index e58cd4a58..8d451e99c 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -39,6 +39,7 @@ static UINT8 hudAvailable; // hud hooks field static const char *const hud_disable_options[] = { "stagetitle", "textspectator", + "crosshair", "score", "time", From ed82b94e64139a12d21376800cb123585f1ebc40 Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Tue, 29 Dec 2020 23:29:00 +0200 Subject: [PATCH 194/644] Take slopes into account in FOF wall cutoff in HWR_ProcessSeg --- src/hardware/hw_main.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index a7e37d231..5de6f8e11 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -1104,7 +1104,6 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom SLOPEPARAMS(gl_backsector->c_slope, worldhigh, worldhighslope, gl_backsector->ceilingheight) SLOPEPARAMS(gl_backsector->f_slope, worldlow, worldlowslope, gl_backsector->floorheight) -#undef SLOPEPARAMS // hack to allow height changes in outdoor areas // This is what gets rid of the upper textures if there should be sky @@ -1589,14 +1588,18 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom { ffloor_t * rover; fixed_t highcut = 0, lowcut = 0; + fixed_t lowcutslope, highcutslope; + + // Used for height comparisons and etc across FOFs and slopes + fixed_t high1, highslope1, low1, lowslope1; INT32 texnum; line_t * newline = NULL; // Multi-Property FOF - ///TODO add slope support (fixing cutoffs, proper wall clipping) - maybe just disable highcut/lowcut if either sector or FOF has a slope - /// to allow fun plane intersecting in OGL? But then people would abuse that and make software look bad. :C - highcut = gl_frontsector->ceilingheight < gl_backsector->ceilingheight ? gl_frontsector->ceilingheight : gl_backsector->ceilingheight; - lowcut = gl_frontsector->floorheight > gl_backsector->floorheight ? gl_frontsector->floorheight : gl_backsector->floorheight; + lowcut = max(worldbottom, worldlow); + highcut = min(worldtop, worldhigh); + lowcutslope = max(worldbottomslope, worldlowslope); + highcutslope = min(worldtopslope, worldhighslope); if (gl_backsector->ffloors) { @@ -1618,7 +1621,11 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom continue; if (!(rover->flags & FF_ALLSIDES) && rover->flags & FF_INVERTSIDES) continue; - if (*rover->topheight < lowcut || *rover->bottomheight > highcut) + + SLOPEPARAMS(*rover->t_slope, high1, highslope1, *rover->topheight) + SLOPEPARAMS(*rover->b_slope, low1, lowslope1, *rover->bottomheight) + + if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope)) continue; texnum = R_GetTextureNum(sides[rover->master->sidenum[0]].midtexture); @@ -1764,7 +1771,11 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom continue; if (!(rover->flags & FF_ALLSIDES || rover->flags & FF_INVERTSIDES)) continue; - if (*rover->topheight < lowcut || *rover->bottomheight > highcut) + + SLOPEPARAMS(*rover->t_slope, high1, highslope1, *rover->topheight) + SLOPEPARAMS(*rover->b_slope, low1, lowslope1, *rover->bottomheight) + + if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope)) continue; texnum = R_GetTextureNum(sides[rover->master->sidenum[0]].midtexture); @@ -1856,6 +1867,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom } } } +#undef SLOPEPARAMS //Hurdler: end of 3d-floors test } From c19539248aa02b64a4cb1c8ecebfde1d4c648eed Mon Sep 17 00:00:00 2001 From: katsy Date: Thu, 31 Dec 2020 04:38:26 -0600 Subject: [PATCH 195/644] add sprung flag to steam --- src/p_map.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/p_map.c b/src/p_map.c index b934e3255..7ca6d653a 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -511,6 +511,7 @@ static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object) if (spring->state != &states[S_STEAM1]) // Only when it bursts break; + object->eflags |= MFE_SPRUNG; object->momz = flipval*FixedMul(speed, FixedSqrt(FixedMul(spring->scale, object->scale))); // scale the speed with both objects' scales, just like with springs! if (p) From 3b4a52b8b85a7c17127f92423d90b273710ca04f Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Mon, 4 Jan 2021 00:03:18 -0600 Subject: [PATCH 196/644] Allows Lua to transport you to a different map in place of a Special Stage. --- src/g_game.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 6171c7b72..e204cdb2c 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3920,12 +3920,13 @@ static void G_DoCompleted(void) { token--; - for (i = 0; i < 7; i++) - if (!(emeralds & (1< Date: Mon, 4 Jan 2021 18:10:41 -0300 Subject: [PATCH 197/644] Allow water running in reverse gravity --- src/p_mobj.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 58124fb9b..5cde1639c 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -3188,13 +3188,16 @@ boolean P_SceneryZMovement(mobj_t *mo) // boolean P_CanRunOnWater(player_t *player, ffloor_t *rover) { - fixed_t topheight = P_GetFFloorTopZAt(rover, player->mo->x, player->mo->y); + boolean flip = player->mo->eflags & MFE_VERTICALFLIP; + fixed_t surfaceheight = flip ? P_GetFFloorBottomZAt(rover, player->mo->x, player->mo->y) : P_GetFFloorTopZAt(rover, player->mo->x, player->mo->y); + fixed_t playerbottom = flip ? (player->mo->z + player->mo->height) : player->mo->z; + boolean doifit = flip ? (surfaceheight - player->mo->floorz >= player->mo->height) : (player->mo->ceilingz - surfaceheight >= player->mo->height); if (!player->powers[pw_carry] && !player->homing - && ((player->powers[pw_super] || player->charflags & SF_RUNONWATER || player->dashmode >= DASHMODE_THRESHOLD) && player->mo->ceilingz-topheight >= player->mo->height) + && ((player->powers[pw_super] || player->charflags & SF_RUNONWATER || player->dashmode >= DASHMODE_THRESHOLD) && doifit) && (rover->flags & FF_SWIMMABLE) && !(player->pflags & PF_SPINNING) && player->speed > FixedMul(player->runspeed, player->mo->scale) && !(player->pflags & PF_SLIDING) - && abs(player->mo->z - topheight) < FixedMul(30*FRACUNIT, player->mo->scale)) + && abs(playerbottom - surfaceheight) < FixedMul(30*FRACUNIT, player->mo->scale)) return true; return false; From 70eb3228f8af551ef6fcec91a5481c311bd4ad6b Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Tue, 5 Jan 2021 13:20:02 -0600 Subject: [PATCH 198/644] Pressing A Key Combination In The Console Crashes SRB2 get stryder7x in on this --- src/console.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/console.c b/src/console.c index c7bfe0fe1..121605b10 100644 --- a/src/console.c +++ b/src/console.c @@ -826,6 +826,12 @@ static void CON_InputDelSelection(void) Lock_state(); + if (!input_cur) + { + Unlock_state(); + return; + } + if (input_cur > input_sel) { start = input_sel; From c8627464c9ace0d5939edf76a610dff458f3a95c Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Wed, 6 Jan 2021 19:40:30 -0500 Subject: [PATCH 199/644] Check if GME_VERSION is defined. I made the assumption it would always be defined, which won't always be the case. --- src/sdl/mixer_sound.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index 5cae48077..412a21ea0 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -1298,7 +1298,7 @@ boolean I_PlaySong(boolean looping) if (gme) { gme_equalizer_t eq = {GME_TREBLE, GME_BASS, 0,0,0,0,0,0,0,0}; -#if GME_VERSION >= 0x000603 +#if defined (GME_VERSION) && GME_VERSION >= 0x000603 if (looping) gme_set_autoload_playback_limit(gme, 0); #endif From 679bf5f999b8574a36a99b62b99824bb1239a635 Mon Sep 17 00:00:00 2001 From: Zwip-Zwap Zapony Date: Fri, 8 Jan 2021 16:25:10 +0100 Subject: [PATCH 200/644] Fix CA_BOUNCE when flipped Fix P_DoAbilityBounce() always using "max", instead of "min" while upside-down and "max" while not --- src/p_user.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index a70dceb8b..5352a969c 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -4880,22 +4880,28 @@ void P_DoBubbleBounce(player_t *player) // void P_DoAbilityBounce(player_t *player, boolean changemomz) { - fixed_t prevmomz; if (player->mo->state-states == S_PLAY_BOUNCE_LANDING) return; + if (changemomz) { - fixed_t minmomz; - prevmomz = player->mo->momz; + fixed_t prevmomz = player->mo->momz, minmomz; + if (P_MobjFlip(player->mo)*prevmomz < 0) prevmomz = 0; else if (player->mo->eflags & MFE_UNDERWATER) prevmomz /= 2; + P_DoJump(player, false); player->pflags &= ~(PF_STARTJUMP|PF_JUMPED); minmomz = FixedMul(player->mo->momz, 3*FRACUNIT/2); - player->mo->momz = max(minmomz, (minmomz + prevmomz)/2); + + if (player->mo->eflags & MFE_VERTICALFLIP) // Use "min" or "max" depending on if the player is flipped + player->mo->momz = min(minmomz, (minmomz + prevmomz)/2); + else + player->mo->momz = max(minmomz, (minmomz + prevmomz)/2); } + S_StartSound(player->mo, sfx_boingf); P_SetPlayerMobjState(player->mo, S_PLAY_BOUNCE_LANDING); player->pflags |= PF_BOUNCING|PF_THOKKED; From 59bc197f3252bdfff838614bba7cd771d4f7440c Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Sun, 10 Jan 2021 10:01:31 -0600 Subject: [PATCH 201/644] Fix a divby0 when you have SF_MULTIABILITY, CA_DOUBLEJUMP, and actionspd -FRACUNIT. --- src/p_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index a70dceb8b..a9e1fe9a2 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -4499,7 +4499,7 @@ void P_DoJump(player_t *player, boolean soundandstate) if (twodlevel || (player->mo->flags2 & MF2_TWOD)) factor += player->jumpfactor / 10; - if (player->charflags & SF_MULTIABILITY && player->charability == CA_DOUBLEJUMP) + if (player->charflags & SF_MULTIABILITY && player->charability == CA_DOUBLEJUMP && (player->actionspd >> FRACBITS) != -1) factor -= max(0, player->secondjump * player->jumpfactor / ((player->actionspd >> FRACBITS) + 1)); // Reduce the jump height each time //if (maptol & TOL_NIGHTS) From eb1e7eff8f2d2a73e833e557f807a810e6ef946a Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Sun, 10 Jan 2021 20:52:03 +0200 Subject: [PATCH 202/644] Take slopes into account even more in FOF wall cutoff in HWR_ProcessSeg --- src/hardware/hw_main.c | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 5de6f8e11..671a21017 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -1641,10 +1641,17 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom hS = P_GetFFloorTopZAt (rover, v2x, v2y); l = P_GetFFloorBottomZAt(rover, v1x, v1y); lS = P_GetFFloorBottomZAt(rover, v2x, v2y); - if (!(*rover->t_slope) && !gl_frontsector->c_slope && !gl_backsector->c_slope && h > highcut) - h = hS = highcut; - if (!(*rover->b_slope) && !gl_frontsector->f_slope && !gl_backsector->f_slope && l < lowcut) - l = lS = lowcut; + // Adjust the heights so the FOF does not overlap with top and bottom textures. + if (h >= highcut && hS >= highcutslope) + { + h = highcut; + hS = highcutslope; + } + if (l <= lowcut && lS <= lowcutslope) + { + l = lowcut; + lS = lowcutslope; + } //Hurdler: HW code starts here //FIXME: check if peging is correct // set top/bottom coords @@ -1790,10 +1797,17 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom hS = P_GetFFloorTopZAt (rover, v2x, v2y); l = P_GetFFloorBottomZAt(rover, v1x, v1y); lS = P_GetFFloorBottomZAt(rover, v2x, v2y); - if (!(*rover->t_slope) && !gl_frontsector->c_slope && !gl_backsector->c_slope && h > highcut) - h = hS = highcut; - if (!(*rover->b_slope) && !gl_frontsector->f_slope && !gl_backsector->f_slope && l < lowcut) - l = lS = lowcut; + // Adjust the heights so the FOF does not overlap with top and bottom textures. + if (h >= highcut && hS >= highcutslope) + { + h = highcut; + hS = highcutslope; + } + if (l <= lowcut && lS <= lowcutslope) + { + l = lowcut; + lS = lowcutslope; + } //Hurdler: HW code starts here //FIXME: check if peging is correct // set top/bottom coords From d252f074b7cd28bea837552b8ff01314141058d0 Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Sun, 10 Jan 2021 21:33:54 +0200 Subject: [PATCH 203/644] Render midtextures on two-sided lines with a z-buffer offset This will fix z-fighting issues when they overlap with FOFs. --- src/hardware/hw_main.c | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index a7e37d231..ca4d3e258 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -831,7 +831,7 @@ static float HWR_ClipViewSegment(INT32 x, polyvertex_t *v1, polyvertex_t *v2) // // HWR_SplitWall // -static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, FSurfaceInfo* Surf, INT32 cutflag, ffloor_t *pfloor) +static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, FSurfaceInfo* Surf, INT32 cutflag, ffloor_t *pfloor, FBITFIELD polyflags) { /* SoM: split up and light walls according to the lightlist. This may also include leaving out parts @@ -969,11 +969,11 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, wallVerts[1].y = endbot; if (cutflag & FF_FOG) - HWR_AddTransparentWall(wallVerts, Surf, texnum, PF_Fog|PF_NoTexture, true, lightnum, colormap); + HWR_AddTransparentWall(wallVerts, Surf, texnum, PF_Fog|PF_NoTexture|polyflags, true, lightnum, colormap); else if (cutflag & FF_TRANSLUCENT) - HWR_AddTransparentWall(wallVerts, Surf, texnum, PF_Translucent, false, lightnum, colormap); + HWR_AddTransparentWall(wallVerts, Surf, texnum, PF_Translucent|polyflags, false, lightnum, colormap); else - HWR_ProjectWall(wallVerts, Surf, PF_Masked, lightnum, colormap); + HWR_ProjectWall(wallVerts, Surf, PF_Masked|polyflags, lightnum, colormap); top = bot; endtop = endbot; @@ -998,11 +998,11 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, wallVerts[1].y = endbot; if (cutflag & FF_FOG) - HWR_AddTransparentWall(wallVerts, Surf, texnum, PF_Fog|PF_NoTexture, true, lightnum, colormap); + HWR_AddTransparentWall(wallVerts, Surf, texnum, PF_Fog|PF_NoTexture|polyflags, true, lightnum, colormap); else if (cutflag & FF_TRANSLUCENT) - HWR_AddTransparentWall(wallVerts, Surf, texnum, PF_Translucent, false, lightnum, colormap); + HWR_AddTransparentWall(wallVerts, Surf, texnum, PF_Translucent|polyflags, false, lightnum, colormap); else - HWR_ProjectWall(wallVerts, Surf, PF_Masked, lightnum, colormap); + HWR_ProjectWall(wallVerts, Surf, PF_Masked|polyflags, lightnum, colormap); } // HWR_DrawSkyWall @@ -1183,7 +1183,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom wallVerts[1].y = FIXED_TO_FLOAT(worldhighslope); if (gl_frontsector->numlights) - HWR_SplitWall(gl_frontsector, wallVerts, gl_toptexture, &Surf, FF_CUTLEVEL, NULL); + HWR_SplitWall(gl_frontsector, wallVerts, gl_toptexture, &Surf, FF_CUTLEVEL, NULL, 0); else if (grTex->mipmap.flags & TF_TRANSPARENT) HWR_AddTransparentWall(wallVerts, &Surf, gl_toptexture, PF_Environment, false, lightnum, colormap); else @@ -1249,7 +1249,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom wallVerts[1].y = FIXED_TO_FLOAT(worldbottomslope); if (gl_frontsector->numlights) - HWR_SplitWall(gl_frontsector, wallVerts, gl_bottomtexture, &Surf, FF_CUTLEVEL, NULL); + HWR_SplitWall(gl_frontsector, wallVerts, gl_bottomtexture, &Surf, FF_CUTLEVEL, NULL, 0); else if (grTex->mipmap.flags & TF_TRANSPARENT) HWR_AddTransparentWall(wallVerts, &Surf, gl_bottomtexture, PF_Environment, false, lightnum, colormap); else @@ -1465,13 +1465,17 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom blendmode = HWR_TranstableToAlpha(gl_curline->polyseg->translucency, &Surf); } + // Render midtextures on two-sided lines with a z-buffer offset. + // This will cause the midtexture appear on top, if a FOF overlaps with it. + blendmode |= PF_Decal; + if (gl_frontsector->numlights) { if (!(blendmode & PF_Masked)) - HWR_SplitWall(gl_frontsector, wallVerts, gl_midtexture, &Surf, FF_TRANSLUCENT, NULL); + HWR_SplitWall(gl_frontsector, wallVerts, gl_midtexture, &Surf, FF_TRANSLUCENT, NULL, PF_Decal); else { - HWR_SplitWall(gl_frontsector, wallVerts, gl_midtexture, &Surf, FF_CUTLEVEL, NULL); + HWR_SplitWall(gl_frontsector, wallVerts, gl_midtexture, &Surf, FF_CUTLEVEL, NULL, PF_Decal); } } else if (!(blendmode & PF_Masked)) @@ -1554,7 +1558,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom // I don't think that solid walls can use translucent linedef types... if (gl_frontsector->numlights) - HWR_SplitWall(gl_frontsector, wallVerts, gl_midtexture, &Surf, FF_CUTLEVEL, NULL); + HWR_SplitWall(gl_frontsector, wallVerts, gl_midtexture, &Surf, FF_CUTLEVEL, NULL, 0); else { if (grTex->mipmap.flags & TF_TRANSPARENT) @@ -1717,7 +1721,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom Surf.PolyColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel, rover->master->frontsector->extra_colormap); if (gl_frontsector->numlights) - HWR_SplitWall(gl_frontsector, wallVerts, 0, &Surf, rover->flags, rover); + HWR_SplitWall(gl_frontsector, wallVerts, 0, &Surf, rover->flags, rover, 0); else HWR_AddTransparentWall(wallVerts, &Surf, 0, blendmode, true, lightnum, colormap); } @@ -1732,7 +1736,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom } if (gl_frontsector->numlights) - HWR_SplitWall(gl_frontsector, wallVerts, texnum, &Surf, rover->flags, rover); + HWR_SplitWall(gl_frontsector, wallVerts, texnum, &Surf, rover->flags, rover, 0); else { if (blendmode != PF_Masked) @@ -1829,7 +1833,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom Surf.PolyColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel, rover->master->frontsector->extra_colormap); if (gl_backsector->numlights) - HWR_SplitWall(gl_backsector, wallVerts, 0, &Surf, rover->flags, rover); + HWR_SplitWall(gl_backsector, wallVerts, 0, &Surf, rover->flags, rover, 0); else HWR_AddTransparentWall(wallVerts, &Surf, 0, blendmode, true, lightnum, colormap); } @@ -1844,7 +1848,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom } if (gl_backsector->numlights) - HWR_SplitWall(gl_backsector, wallVerts, texnum, &Surf, rover->flags, rover); + HWR_SplitWall(gl_backsector, wallVerts, texnum, &Surf, rover->flags, rover, 0); else { if (blendmode != PF_Masked) From 8aac7454b8a90dafe57e454ab98bdce5ddec67b5 Mon Sep 17 00:00:00 2001 From: Zippy_Zolton Date: Sun, 10 Jan 2021 17:20:07 -0600 Subject: [PATCH 204/644] Make Armageddon Shield instantly kill Egg Guards --- src/p_user.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index a70dceb8b..e2aa258e1 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9009,8 +9009,11 @@ void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius) if (mo->type == MT_MINUS && !(mo->flags & (MF_SPECIAL|MF_SHOOTABLE))) mo->flags = (mo->flags & ~MF_NOCLIPTHING)|MF_SPECIAL|MF_SHOOTABLE; - if (mo->type == MT_EGGGUARD && mo->tracer) //nuke Egg Guard's shield! + if (mo->type == MT_EGGGUARD && mo->tracer) // Egg Guard's shield needs to be removed if it has one! + { P_KillMobj(mo->tracer, inflictor, source, DMG_NUKE); + P_KillMobj(mo, inflictor, source, DMG_NUKE); + } if (mo->flags & MF_BOSS || mo->type == MT_PLAYER) //don't OHKO bosses nor players! P_DamageMobj(mo, inflictor, source, 1, DMG_NUKE); From fbcc0c25b3198453d0f96bebdbd5e71724780b5c Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+Ikkarin@users.noreply.github.com> Date: Sun, 10 Jan 2021 23:17:40 -0300 Subject: [PATCH 205/644] Add Logan to the art credits --- src/f_finale.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/f_finale.c b/src/f_finale.c index b23ab4f7a..bd5f16f43 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1149,6 +1149,7 @@ static const char *credits[] = { "Daniel \"Inazuma\" Trinh", "\"VelocitOni\"", "Jarrett \"JEV3\" Voight", + "Logan \"Hyperchaotix\" McCloud", "", "\1Music and Sound", "\1Production", From 90b0242802151bced2c3355757e6670b60066e01 Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+Ikkarin@users.noreply.github.com> Date: Mon, 11 Jan 2021 21:49:31 -0300 Subject: [PATCH 206/644] Put his name at the right order --- src/f_finale.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/f_finale.c b/src/f_finale.c index bd5f16f43..2232b669f 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1138,6 +1138,7 @@ static const char *credits[] = { "Iestyn \"Monster Iestyn\" Jealous", "William \"GuyWithThePie\" Kloppenberg", "Alice \"Alacroix\" de Lemos", + "Logan \"Hyperchaotix\" McCloud", "Alexander \"DrTapeworm\" Moench-Ford", "Andrew \"Senku Niola\" Moran", "\"MotorRoach\"", @@ -1149,7 +1150,6 @@ static const char *credits[] = { "Daniel \"Inazuma\" Trinh", "\"VelocitOni\"", "Jarrett \"JEV3\" Voight", - "Logan \"Hyperchaotix\" McCloud", "", "\1Music and Sound", "\1Production", From d2be3110bda87db82ca9fe74fbb5c375af2c8f88 Mon Sep 17 00:00:00 2001 From: lachwright Date: Wed, 13 Jan 2021 22:28:38 +1100 Subject: [PATCH 207/644] Have Metal Sonic use spinheight while dashing --- src/p_user.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index a70dceb8b..a1bbe8d57 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8652,7 +8652,9 @@ void P_MovePlayer(player_t *player) || (player->pflags & PF_SPINNING) || player->powers[pw_tailsfly] || player->pflags & PF_GLIDING || (player->charability == CA_GLIDEANDCLIMB && player->mo->state-states == S_PLAY_GLIDE_LANDING) - || (player->charability == CA_FLY && player->mo->state-states == S_PLAY_FLY_TIRED)) + || (player->charability == CA_FLY && player->mo->state-states == S_PLAY_FLY_TIRED) + || (player->dashmode >= DASHMODE_THRESHOLD && (player->charflags & SF_MACHINE) + && player->mo->state-states == S_PLAY_DASH && (player->mo->sprite2 & ~FF_SPR2SUPER) == player->mo->state->frame)) { player->mo->height = P_GetPlayerSpinHeight(player); atspinheight = true; From 149535634e757bb6bb833e18d866dc1005b63c0d Mon Sep 17 00:00:00 2001 From: lachwright Date: Thu, 14 Jan 2021 04:24:48 +1100 Subject: [PATCH 208/644] Keep Metal's jet fume at a consistent height during dashmode --- src/p_user.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index a1bbe8d57..47d73ec2a 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -11357,6 +11357,7 @@ static void P_DoMetalJetFume(player_t *player, mobj_t *fume) mobj_t *mo = player->mo; angle_t angle = player->drawangle; fixed_t dist; + fixed_t playerheight = P_GetPlayerHeight(player); panim_t panim = player->panim; tic_t dashmode = player->dashmode; boolean underwater = mo->eflags & MFE_UNDERWATER; @@ -11390,7 +11391,7 @@ static void P_DoMetalJetFume(player_t *player, mobj_t *fume) offsetV = i*P_ReturnThrustY(fume, fume->movedir, radiusV); x = mo->x + radiusX + FixedMul(offsetH, factorX); y = mo->y + radiusY + FixedMul(offsetH, factorY); - z = mo->z + (mo->height >> 1) + offsetV; + z = mo->z + (playerheight >> 1) + offsetV; P_SpawnMobj(x, y, z, MT_SMALLBUBBLE)->scale = mo->scale >> 1; } @@ -11453,7 +11454,7 @@ static void P_DoMetalJetFume(player_t *player, mobj_t *fume) P_UnsetThingPosition(fume); fume->x = mo->x + P_ReturnThrustX(fume, angle, dist); fume->y = mo->y + P_ReturnThrustY(fume, angle, dist); - fume->z = mo->z + ((mo->height - fume->height) >> 1); + fume->z = mo->z + ((playerheight - fume->height) >> 1); P_SetThingPosition(fume); // If dashmode is high enough, spawn a trail From a117ec98599f65b4836b05a33f63f281ef3a434f Mon Sep 17 00:00:00 2001 From: lachwright Date: Thu, 14 Jan 2021 04:34:43 +1100 Subject: [PATCH 209/644] oops that doesn't work in reverse gravity --- src/p_user.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 47d73ec2a..f2b7759fa 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -11357,7 +11357,7 @@ static void P_DoMetalJetFume(player_t *player, mobj_t *fume) mobj_t *mo = player->mo; angle_t angle = player->drawangle; fixed_t dist; - fixed_t playerheight = P_GetPlayerHeight(player); + fixed_t heightoffset = ((mo->eflags & MFE_VERTICALFLIP) ? mo->height - (P_GetPlayerHeight(player) >> 1) : (P_GetPlayerHeight(player) >> 1)); panim_t panim = player->panim; tic_t dashmode = player->dashmode; boolean underwater = mo->eflags & MFE_UNDERWATER; @@ -11391,7 +11391,7 @@ static void P_DoMetalJetFume(player_t *player, mobj_t *fume) offsetV = i*P_ReturnThrustY(fume, fume->movedir, radiusV); x = mo->x + radiusX + FixedMul(offsetH, factorX); y = mo->y + radiusY + FixedMul(offsetH, factorY); - z = mo->z + (playerheight >> 1) + offsetV; + z = mo->z + heightoffset + offsetV; P_SpawnMobj(x, y, z, MT_SMALLBUBBLE)->scale = mo->scale >> 1; } @@ -11454,7 +11454,7 @@ static void P_DoMetalJetFume(player_t *player, mobj_t *fume) P_UnsetThingPosition(fume); fume->x = mo->x + P_ReturnThrustX(fume, angle, dist); fume->y = mo->y + P_ReturnThrustY(fume, angle, dist); - fume->z = mo->z + ((playerheight - fume->height) >> 1); + fume->z = mo->z + heightoffset - (fume->height >> 1); P_SetThingPosition(fume); // If dashmode is high enough, spawn a trail From 794d92767032f718e6c31aa62f3125cd21b2511f Mon Sep 17 00:00:00 2001 From: Shane Ellis Date: Fri, 15 Jan 2021 16:44:26 -0500 Subject: [PATCH 210/644] Add conditions for new player bot type --- src/p_inter.c | 64 ++++++++++++++++++++++++--------------------------- 1 file changed, 30 insertions(+), 34 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index e9a16a3dd..778ec703b 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -151,7 +151,7 @@ boolean P_CanPickupItem(player_t *player, boolean weapon) if (!player->mo || player->mo->health <= 0) return false; - if (player->bot) + if (player->bot && player->bot != 3) { if (weapon) return false; @@ -178,7 +178,7 @@ void P_DoNightsScore(player_t *player) return; // Don't do any fancy shit for failures. dummymo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z+player->mo->height/2, MT_NIGHTSCORE); - if (player->bot) + if (player->bot && player->bot != 3) player = &players[consoleplayer]; if (G_IsSpecialStage(gamemap)) // Global link count? Maybe not a good idea... @@ -470,14 +470,14 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (!(player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2)) { fixed_t setmomz = -toucher->momz; // Store this, momz get changed by P_DoJump within P_DoBubbleBounce - + if (elementalpierce == 2) // Reset bubblewrap, part 1 P_DoBubbleBounce(player); toucher->momz = setmomz; if (elementalpierce == 2) // Reset bubblewrap, part 2 { boolean underwater = toucher->eflags & MFE_UNDERWATER; - + if (underwater) toucher->momz /= 2; toucher->momz -= (toucher->momz/(underwater ? 8 : 4)); // Cap the height! @@ -630,7 +630,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) // ***************************** // // Special Stage Token case MT_TOKEN: - if (player->bot) + if (player->bot && player->bot != 3) return; P_AddPlayerScore(player, 1000); @@ -670,7 +670,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) // Emerald Hunt case MT_EMERHUNT: - if (player->bot) + if (player->bot && player->bot != 3) return; if (hunt1 == special) @@ -701,7 +701,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) case MT_EMERALD5: case MT_EMERALD6: case MT_EMERALD7: - if (player->bot) + if (player->bot && player->bot != 3) return; if (special->threshold) @@ -738,7 +738,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) // Secret emblem thingy case MT_EMBLEM: { - if (demoplayback || player->bot) + if (demoplayback || (player->bot && player->bot != 3)) return; emblemlocations[special->health-1].collected = true; @@ -751,7 +751,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) // CTF Flags case MT_REDFLAG: case MT_BLUEFLAG: - if (player->bot) + if (player->bot && player->bot != 3) return; if (player->powers[pw_flashing] || player->tossdelay) return; @@ -826,7 +826,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) { boolean spec = G_IsSpecialStage(gamemap); boolean cangiveemmy = false; - if (player->bot) + if (player->bot && player->bot != 3) return; if (player->exiting) return; @@ -1072,7 +1072,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) } return; case MT_EGGCAPSULE: - if (player->bot) + if (player->bot && player->bot != 3) return; // make sure everything is as it should be, THEN take rings from players in special stages @@ -1164,7 +1164,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) } return; case MT_NIGHTSSUPERLOOP: - if (player->bot || !(player->powers[pw_carry] == CR_NIGHTSMODE)) + if ((player->bot && player->bot != 3) || !(player->powers[pw_carry] == CR_NIGHTSMODE)) return; if (!G_IsSpecialStage(gamemap)) player->powers[pw_nights_superloop] = (UINT16)special->info->speed; @@ -1186,7 +1186,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) } break; case MT_NIGHTSDRILLREFILL: - if (player->bot || !(player->powers[pw_carry] == CR_NIGHTSMODE)) + if ((player->bot && player->bot != 3) || !(player->powers[pw_carry] == CR_NIGHTSMODE)) return; if (!G_IsSpecialStage(gamemap)) player->drillmeter = special->info->speed; @@ -1208,7 +1208,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) } break; case MT_NIGHTSHELPER: - if (player->bot || !(player->powers[pw_carry] == CR_NIGHTSMODE)) + if ((player->bot && player->bot != 3) || !(player->powers[pw_carry] == CR_NIGHTSMODE)) return; if (!G_IsSpecialStage(gamemap)) { @@ -1240,7 +1240,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) } break; case MT_NIGHTSEXTRATIME: - if (player->bot || !(player->powers[pw_carry] == CR_NIGHTSMODE)) + if ((player->bot && player->bot != 3) || !(player->powers[pw_carry] == CR_NIGHTSMODE)) return; if (!G_IsSpecialStage(gamemap)) { @@ -1272,7 +1272,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) } break; case MT_NIGHTSLINKFREEZE: - if (player->bot || !(player->powers[pw_carry] == CR_NIGHTSMODE)) + if ((player->bot && player->bot != 3) || !(player->powers[pw_carry] == CR_NIGHTSMODE)) return; if (!G_IsSpecialStage(gamemap)) { @@ -1332,7 +1332,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (playeringame[i] && players[i].powers[pw_carry] == CR_NIGHTSMODE) players[i].drillmeter += TICRATE/2; } - else if (player->bot) + else if (player->bot && player->bot != 3) players[consoleplayer].drillmeter += TICRATE/2; else player->drillmeter += TICRATE/2; @@ -1385,13 +1385,9 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) thinker_t *th; mobj_t *mo2; - if (player->bot) + if (player->bot && player->bot != 3) return; - // Initialize my junk - junk.tags.tags = NULL; - junk.tags.count = 0; - Tag_FSet(&junk.tags, LE_AXE); EV_DoElevator(&junk, bridgeFall, false); @@ -1423,7 +1419,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; } case MT_FIREFLOWER: - if (player->bot) + if (player->bot && player->bot != 3) return; S_StartSound(toucher, sfx_mario3); @@ -1617,7 +1613,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (special->tracer && !(special->tracer->flags2 & MF2_STRONGBOX)) macespin = true; - + if (macespin ? (player->powers[pw_ignorelatch] & (1<<15)) : (player->powers[pw_ignorelatch])) return; @@ -1685,7 +1681,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; // Only go in the mouth // Eaten by player! - if ((!player->bot) && (player->powers[pw_underwater] && player->powers[pw_underwater] <= 12*TICRATE + 1)) + if ((!player->bot || player->bot == 3) && (player->powers[pw_underwater] && player->powers[pw_underwater] <= 12*TICRATE + 1)) { player->powers[pw_underwater] = underwatertics + 1; P_RestoreMusic(player); @@ -1696,7 +1692,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (!player->climbing) { - if (player->bot && toucher->state-states != S_PLAY_GASP) + if (player->bot && player->bot != 3 && toucher->state-states != S_PLAY_GASP) S_StartSound(toucher, special->info->deathsound); // Force it to play a sound for bots P_SetPlayerMobjState(toucher, S_PLAY_GASP); P_ResetPlayer(player); @@ -1704,7 +1700,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) toucher->momx = toucher->momy = toucher->momz = 0; - if (player->bot) + if (player->bot && player->bot != 3) return; else break; @@ -1736,7 +1732,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; case MT_MINECARTSPAWNER: - if (!player->bot && special->fuse <= TICRATE && player->powers[pw_carry] != CR_MINECART && !(player->powers[pw_ignorelatch] & (1<<15))) + if (!player->bot && player->bot != 3 && special->fuse <= TICRATE && player->powers[pw_carry] != CR_MINECART && !(player->powers[pw_ignorelatch] & (1<<15))) { mobj_t *mcart = P_SpawnMobj(special->x, special->y, special->z, MT_MINECART); P_SetTarget(&mcart->target, toucher); @@ -1789,7 +1785,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) } return; default: // SOC or script pickup - if (player->bot) + if (player->bot && player->bot != 3) return; P_SetTarget(&special->target, toucher); break; @@ -1813,7 +1809,7 @@ void P_TouchStarPost(mobj_t *post, player_t *player, boolean snaptopost) mobj_t *toucher = player->mo; mobj_t *checkbase = snaptopost ? post : toucher; - if (player->bot) + if (player->bot && player->bot != 3) return; // In circuit, player must have touched all previous starposts if (circuitmap @@ -2555,7 +2551,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget if ((target->player->lives <= 1) && (netgame || multiplayer) && G_GametypeUsesCoopLives() && (cv_cooplives.value == 0)) ; - else if (!target->player->bot && !target->player->spectator && (target->player->lives != INFLIVES) + else if ((!target->player->bot || target->player->bot == 3) && !target->player->spectator && (target->player->lives != INFLIVES) && G_GametypeUsesLives()) { if (!(target->player->pflags & PF_FINISHED)) @@ -3475,7 +3471,7 @@ void P_SpecialStageDamage(player_t *player, mobj_t *inflictor, mobj_t *source) if (inflictor && inflictor->type == MT_LHRT) return; - if (player->powers[pw_shield] || player->bot) //If One-Hit Shield + if (player->powers[pw_shield] || (player->bot && player->bot != 3)) //If One-Hit Shield { P_RemoveShield(player); S_StartSound(player->mo, sfx_shldls); // Ba-Dum! Shield loss. @@ -3566,7 +3562,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da return false; // Make sure that boxes cannot be popped by enemies, red rings, etc. - if (target->flags & MF_MONITOR && ((!source || !source->player || source->player->bot) + if (target->flags & MF_MONITOR && ((!source || !source->player || (source->player->bot && source->player->bot != 3)) || (inflictor && (inflictor->type == MT_REDRING || (inflictor->type >= MT_THROWNBOUNCE && inflictor->type <= MT_THROWNGRENADE))))) return false; } @@ -3701,7 +3697,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da } else if (LUAh_MobjDamage(target, inflictor, source, damage, damagetype)) return true; - else if (player->powers[pw_shield] || (player->bot && !ultimatemode)) //If One-Hit Shield + else if (player->powers[pw_shield] || (player->bot && player->bot != 3 && !ultimatemode)) //If One-Hit Shield { P_ShieldDamage(player, inflictor, source, damage, damagetype); damage = 0; From 4b9a95a53837166a080b200b34982ce867a31ffd Mon Sep 17 00:00:00 2001 From: Shane Ellis Date: Fri, 15 Jan 2021 16:46:15 -0500 Subject: [PATCH 211/644] Add conditions for new player bot type --- src/p_enemy.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 203e04af1..38df59855 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -743,7 +743,7 @@ boolean P_LookForPlayers(mobj_t *actor, boolean allaround, boolean tracer, fixed if (player->mo->health <= 0) continue; // dead - if (player->bot) + if (player->bot && player->bot != 3) continue; // ignore bots if (player->quittime) @@ -1834,7 +1834,7 @@ void A_SnailerThink(mobj_t *actor) fixed_t dist; fixed_t dx, dy; - dist = R_PointToDist2(0, 0, actor->x - actor->target->x, actor->y - actor->target->y); + dist = P_AproxDistance(actor->x - actor->target->x, actor->y - actor->target->y); if (an > ANGLE_45 && an <= ANGLE_90) // fire at 45 degrees to the left { @@ -3924,10 +3924,6 @@ void A_BossDeath(mobj_t *mo) } else { - // Initialize my junk - junk.tags.tags = NULL; - junk.tags.count = 0; - // Bring the egg trap up to the surface // Incredibly shitty code ahead Tag_FSet(&junk.tags, LE_CAPSULE0); @@ -4057,10 +4053,6 @@ bossjustdie: } case MT_KOOPA: { - // Initialize my junk - junk.tags.tags = NULL; - junk.tags.count = 0; - Tag_FSet(&junk.tags, LE_KOOPA); EV_DoCeiling(&junk, raiseToHighest); return; From b995e3cb75b67116d51583c1ae85debf25013621 Mon Sep 17 00:00:00 2001 From: Shane Ellis Date: Fri, 15 Jan 2021 16:48:19 -0500 Subject: [PATCH 212/644] Add conditions for new player bot type --- src/p_user.c | 125 ++++++++++++++++++++------------------------------- 1 file changed, 48 insertions(+), 77 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index a70dceb8b..2466310bb 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1189,7 +1189,7 @@ void P_GivePlayerRings(player_t *player, INT32 num_rings) if (!player) return; - if (player->bot) + if (player->bot && player->bot != 3) player = &players[consoleplayer]; if (!player->mo) @@ -1234,7 +1234,7 @@ void P_GivePlayerSpheres(player_t *player, INT32 num_spheres) if (!player) return; - if (player->bot) + if (player->bot && player->bot != 3) player = &players[consoleplayer]; if (!player->mo) @@ -1261,7 +1261,7 @@ void P_GivePlayerLives(player_t *player, INT32 numlives) if (!player) return; - if (player->bot) + if (player->bot && player->bot != 3) player = &players[consoleplayer]; if (gamestate == GS_LEVEL) @@ -1341,7 +1341,7 @@ void P_DoSuperTransformation(player_t *player, boolean giverings) // Transformation animation P_SetPlayerMobjState(player->mo, S_PLAY_SUPER_TRANS1); - if (giverings && player->rings < 50) + if (giverings) player->rings = 50; // Just in case. @@ -1367,7 +1367,7 @@ void P_AddPlayerScore(player_t *player, UINT32 amount) { UINT32 oldscore; - if (player->bot) + if (player->bot && player->bot != 3) player = &players[consoleplayer]; // NiGHTS does it different! @@ -1491,10 +1491,10 @@ void P_PlayLivesJingle(player_t *player) if (player && !P_IsLocalPlayer(player)) return; - if (mariomode) - S_StartSound(NULL, sfx_marioa); - else if (use1upSound || cv_1upsound.value) + if (use1upSound || cv_1upsound.value) S_StartSound(NULL, sfx_oneup); + else if (mariomode) + S_StartSound(NULL, sfx_marioa); else { P_PlayJingle(player, JT_1UP); @@ -2329,8 +2329,7 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff) P_MobjCheckWater(player->mo); if (player->pflags & PF_SPINNING) { - if (!(player->pflags & PF_STARTDASH) && player->panim != PA_ROLL && player->panim != PA_ETC - && player->panim != PA_ABILITY && player->panim != PA_ABILITY2) + if (player->mo->state-states != S_PLAY_ROLL && !(player->pflags & PF_STARTDASH)) { P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); S_StartSound(player->mo, sfx_spin); @@ -2613,10 +2612,10 @@ static void P_CheckBustableBlocks(player_t *player) if ((netgame || multiplayer) && player->spectator) return; - + oldx = player->mo->x; oldy = player->mo->y; - + if (!(player->pflags & PF_BOUNCING)) // Bouncers only get to break downwards, not sideways { P_UnsetThingPosition(player->mo); @@ -2635,7 +2634,7 @@ static void P_CheckBustableBlocks(player_t *player) if (!node->m_sector->ffloors) continue; - + for (rover = node->m_sector->ffloors; rover; rover = rover->next) { if (!P_PlayerCanBust(player, rover)) @@ -2993,7 +2992,7 @@ static void P_CheckUnderwaterAndSpaceTimer(player_t *player) player->powers[pw_spacetime] = 0; // Underwater audio cues - if (P_IsLocalPlayer(player) && !player->bot) + if (P_IsLocalPlayer(player) && !player->bot && player->bot != 3) { if ((player->powers[pw_underwater] == 25*TICRATE + 1) || (player->powers[pw_underwater] == 20*TICRATE + 1) @@ -4526,9 +4525,6 @@ void P_DoJump(player_t *player, boolean soundandstate) player->pflags |= P_GetJumpFlags(player);; - if (player->charflags & SF_NOJUMPDAMAGE) - player->pflags &= ~PF_SPINNING; - if (soundandstate) { if (!player->spectator) @@ -5024,7 +5020,7 @@ static boolean P_PlayerShieldThink(player_t *player, ticcmd_t *cmd, mobj_t *lock if ((player->powers[pw_shield] & SH_NOSTACK) && !player->powers[pw_super] && !(player->pflags & PF_SPINDOWN) && ((!(player->pflags & PF_THOKKED) || (((player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP || (player->powers[pw_shield] & SH_NOSTACK) == SH_ATTRACT) && player->secondjump == UINT8_MAX) ))) // thokked is optional if you're bubblewrapped / 3dblasted { - if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ATTRACT && !(player->charflags & SF_NOSHIELDABILITY)) + if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ATTRACT) { if ((lockonshield = P_LookForEnemies(player, false, false))) { @@ -5047,7 +5043,7 @@ static boolean P_PlayerShieldThink(player_t *player, ticcmd_t *cmd, mobj_t *lock } } } - if ((!(player->charflags & SF_NOSHIELDABILITY)) && (cmd->buttons & BT_SPIN && !LUAh_ShieldSpecial(player))) // Spin button effects + if (cmd->buttons & BT_SPIN && !LUAh_ShieldSpecial(player)) // Spin button effects { // Force stop if ((player->powers[pw_shield] & ~(SH_FORCEHP|SH_STACK)) == SH_FORCE) @@ -5495,7 +5491,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) break; } } - else if ((!(player->charflags & SF_NOSHIELDABILITY)) && ((player->powers[pw_shield] & SH_NOSTACK) == SH_WHIRLWIND && !player->powers[pw_super] && !LUAh_ShieldSpecial(player))) + else if ((player->powers[pw_shield] & SH_NOSTACK) == SH_WHIRLWIND && !player->powers[pw_super]) P_DoJumpShield(player); } @@ -5924,7 +5920,7 @@ static void P_3dMovement(player_t *player) player->rmomy = player->mo->momy - player->cmomy; // Calculates player's speed based on distance-of-a-line formula - player->speed = R_PointToDist2(0, 0, player->rmomx, player->rmomy); + player->speed = P_AproxDistance(player->rmomx, player->rmomy); // Monster Iestyn - 04-11-13 // Quadrants are stupid, excessive and broken, let's do this a much simpler way! @@ -5957,22 +5953,6 @@ static void P_3dMovement(player_t *player) acceleration = 96 + (FixedDiv(player->speed, player->mo->scale)>>FRACBITS) * 40; topspeed = normalspd; } - else if (player->bot) - { // Bot steals player 1's stats - normalspd = FixedMul(players[consoleplayer].normalspeed, player->mo->scale); - thrustfactor = players[consoleplayer].thrustfactor; - acceleration = players[consoleplayer].accelstart + (FixedDiv(player->speed, player->mo->scale)>>FRACBITS) * players[consoleplayer].acceleration; - - if (player->powers[pw_tailsfly]) - topspeed = normalspd/2; - else if (player->mo->eflags & (MFE_UNDERWATER|MFE_GOOWATER)) - { - topspeed = normalspd/2; - acceleration = 2*acceleration/3; - } - else - topspeed = normalspd; - } else { if (player->powers[pw_super] || player->powers[pw_sneakers]) @@ -7756,11 +7736,6 @@ void P_ElementalFire(player_t *player, boolean cropcircle) flame->eflags = (flame->eflags & ~MFE_VERTICALFLIP)|(player->mo->eflags & MFE_VERTICALFLIP); P_InstaThrust(flame, flame->angle, FixedMul(3*FRACUNIT, flame->scale)); P_SetObjectMomZ(flame, 3*FRACUNIT, false); - if (!(gametyperules & GTR_FRIENDLY)) - { - P_SetMobjState(flame, S_TEAM_SPINFIRE1); - flame->color = player->mo->color; - } } #undef limitangle #undef numangles @@ -7788,11 +7763,6 @@ void P_ElementalFire(player_t *player, boolean cropcircle) flame->destscale = player->mo->scale; P_SetScale(flame, player->mo->scale); flame->eflags = (flame->eflags & ~MFE_VERTICALFLIP)|(player->mo->eflags & MFE_VERTICALFLIP); - if (!(gametyperules & GTR_FRIENDLY)) - { - P_SetMobjState(flame, S_TEAM_SPINFIRE1); - flame->color = player->mo->color; - } flame->momx = 8; // this is a hack which is used to ensure it still behaves as a missile and can damage others P_XYMovement(flame); @@ -8619,6 +8589,12 @@ void P_MovePlayer(player_t *player) player->climbing--; } + if (!player->climbing) + { + player->lastsidehit = -1; + player->lastlinehit = -1; + } + // Make sure you're not teetering when you shouldn't be. if (player->panim == PA_EDGE && (player->mo->momx || player->mo->momy || player->mo->momz)) @@ -8643,7 +8619,6 @@ void P_MovePlayer(player_t *player) P_DoFiring(player, cmd); { - boolean atspinheight = false; fixed_t oldheight = player->mo->height; // Less height while spinning. Good for spinning under things...? @@ -8653,35 +8628,32 @@ void P_MovePlayer(player_t *player) || player->powers[pw_tailsfly] || player->pflags & PF_GLIDING || (player->charability == CA_GLIDEANDCLIMB && player->mo->state-states == S_PLAY_GLIDE_LANDING) || (player->charability == CA_FLY && player->mo->state-states == S_PLAY_FLY_TIRED)) - { player->mo->height = P_GetPlayerSpinHeight(player); - atspinheight = true; - } else player->mo->height = P_GetPlayerHeight(player); if (player->mo->eflags & MFE_VERTICALFLIP && player->mo->height != oldheight) // adjust z height for reverse gravity, similar to how it's done for scaling player->mo->z -= player->mo->height - oldheight; + } - // Crush test... - if ((player->mo->ceilingz - player->mo->floorz < player->mo->height) - && !(player->mo->flags & MF_NOCLIP)) + // Crush test... + if ((player->mo->ceilingz - player->mo->floorz < player->mo->height) + && !(player->mo->flags & MF_NOCLIP)) + { + if ((player->charability2 == CA2_SPINDASH) && !(player->pflags & PF_SPINNING)) { - if (!atspinheight) - { - player->pflags |= PF_SPINNING; - P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); - } - else if (player->mo->ceilingz - player->mo->floorz < player->mo->height) - { - if ((netgame || multiplayer) && player->spectator) - P_DamageMobj(player->mo, NULL, NULL, 1, DMG_SPECTATOR); // Respawn crushed spectators - else - P_DamageMobj(player->mo, NULL, NULL, 1, DMG_CRUSHED); + player->pflags |= PF_SPINNING; + P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); + } + else if (player->mo->ceilingz - player->mo->floorz < player->mo->height) + { + if ((netgame || multiplayer) && player->spectator) + P_DamageMobj(player->mo, NULL, NULL, 1, DMG_SPECTATOR); // Respawn crushed spectators + else + P_DamageMobj(player->mo, NULL, NULL, 1, DMG_CRUSHED); - if (player->playerstate == PST_DEAD) - return; - } + if (player->playerstate == PST_DEAD) + return; } } @@ -9497,11 +9469,11 @@ static void P_DeathThink(player_t *player) if (player->deadtimer < INT32_MAX) player->deadtimer++; - if (player->bot) // don't allow bots to do any of the below, B_CheckRespawn does all they need for respawning already + if (player->bot && player->bot != 3) // don't allow bots to do any of the below, B_CheckRespawn does all they need for respawning already goto notrealplayer; // continue logic - if (!(netgame || multiplayer) && player->lives <= 0) + if (!(netgame || multiplayer) && player->lives <= 0 && player ==&players[consoleplayer]) //Extra players in SP can't be allowed to continue or end game { if (player->deadtimer > (3*TICRATE) && (cmd->buttons & BT_SPIN || cmd->buttons & BT_JUMP) && (!continuesInSession || player->continues > 0)) G_UseContinue(); @@ -11480,7 +11452,7 @@ void P_PlayerThink(player_t *player) player->playerstate = PST_DEAD; } - if (player->bot) + if (player->bot && player->bot != 3) { if (player->playerstate == PST_LIVE || player->playerstate == PST_DEAD) { @@ -11494,6 +11466,7 @@ void P_PlayerThink(player_t *player) } } +#ifdef SEENAMES if (netgame && player == &players[displayplayer] && !(leveltime % (TICRATE/5))) { seenplayer = NULL; @@ -11518,6 +11491,7 @@ void P_PlayerThink(player_t *player) } } } +#endif if (player->awayviewmobj && P_MobjWasRemoved(player->awayviewmobj)) { @@ -12588,16 +12562,13 @@ void P_PlayerAfterThink(player_t *player) player->powers[pw_carry] = CR_NONE; else { - if (tails->player) - P_TryMove(player->mo, tails->x + P_ReturnThrustX(tails, tails->player->drawangle, 4*FRACUNIT), tails->y + P_ReturnThrustY(tails, tails->player->drawangle, 4*FRACUNIT), true); - else - P_TryMove(player->mo, tails->x + P_ReturnThrustX(tails, tails->angle, 4*FRACUNIT), tails->y + P_ReturnThrustY(tails, tails->angle, 4*FRACUNIT), true); + P_TryMove(player->mo, tails->x + P_ReturnThrustX(tails, tails->player->drawangle, 4*FRACUNIT), tails->y + P_ReturnThrustY(tails, tails->player->drawangle, 4*FRACUNIT), true); player->mo->momx = tails->momx; player->mo->momy = tails->momy; player->mo->momz = tails->momz; } - if (G_CoopGametype() && tails->player && tails->player->bot != 1) + if (G_CoopGametype() && (!tails->player || tails->player->bot != 1)) { player->mo->angle = tails->angle; @@ -12612,7 +12583,7 @@ void P_PlayerAfterThink(player_t *player) { if (player->mo->state-states != S_PLAY_RIDE) P_SetPlayerMobjState(player->mo, S_PLAY_RIDE); - if (tails->player && (tails->skin && ((skin_t *)(tails->skin))->sprites[SPR2_SWIM].numframes) && (tails->eflags & MFE_UNDERWATER)) + if ((tails->skin && ((skin_t *)(tails->skin))->sprites[SPR2_SWIM].numframes) && (tails->eflags & MFE_UNDERWATER)) tails->player->powers[pw_tailsfly] = 0; } else From 5e8313e157ab0bef4f2e2a346906aa1a6efdd58b Mon Sep 17 00:00:00 2001 From: Shane Ellis Date: Fri, 15 Jan 2021 16:50:01 -0500 Subject: [PATCH 213/644] Implementation of lua function P_AddPlayer() --- src/lua_baselib.c | 89 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 81 insertions(+), 8 deletions(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index c5f847be6..9bc8813a2 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -155,8 +155,6 @@ static const struct { {META_PIVOTLIST, "spriteframepivot_t[]"}, {META_FRAMEPIVOT, "spriteframepivot_t"}, - {META_TAGLIST, "taglist"}, - {META_MOBJ, "mobj_t"}, {META_MAPTHING, "mapthing_t"}, @@ -165,8 +163,6 @@ static const struct { {META_SKIN, "skin_t"}, {META_POWERS, "player_t.powers"}, {META_SOUNDSID, "skin_t.soundsid"}, - {META_SKINSPRITES, "skin_t.sprites"}, - {META_SKINSPRITESLIST, "skin_t.sprites[]"}, {META_VERTEX, "vertex_t"}, {META_LINE, "line_t"}, @@ -188,9 +184,6 @@ static const struct { {META_CVAR, "consvar_t"}, {META_SECTORLINES, "sector_t.lines"}, -#ifdef MUTABLE_TAGS - {META_SECTORTAGLIST, "sector_t.taglist"}, -#endif {META_SIDENUM, "line_t.sidenum"}, {META_LINEARGS, "line_t.args"}, {META_LINESTRINGARGS, "line_t.stringargs"}, @@ -2639,7 +2632,7 @@ static int lib_rSkinUsable(lua_State *L) else // skin name { const char *skinname = luaL_checkstring(L, 2); - i = R_SkinAvailable(skinname); + if (R_SkinAvailable(skinname) >= 0) if (i == -1) return luaL_error(L, "skin %s (argument 2) is not loaded", skinname); } @@ -3407,6 +3400,85 @@ static int lib_gAddGametype(lua_State *L) return 0; } +// Bot adding function! +// Partly lifted from Got_AddPlayer +static int lib_gAddPlayer(lua_State *L) +{ + INT16 i, newplayernum, botcount = 1; + player_t *newplayer; + INT8 skinnum = 0, bot; + + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + break; + + if (players[i].bot) + botcount++; // How many of us are there already? + } + if (i >= MAXPLAYERS) + { + lua_pushnil(L); + return 1; + } + + + newplayernum = i; + + //if (!splitscreen && !botingame) + CL_ClearPlayer(newplayernum); + + playeringame[newplayernum] = true; + G_AddPlayer(newplayernum); + newplayer = &players[newplayernum]; + + newplayer->jointime = 0; + newplayer->quittime = 0; + + // I hereby name you Bot X + strcpy(player_names[newplayernum], va("Bot %d", botcount)); + + // Read the skin string! + if (!lua_isnoneornil(L, 1)) + { + skinnum = R_SkinAvailable(luaL_checkstring(L, 1)); + skinnum = skinnum < 0 ? 0 : skinnum; + + // Bots can be whatever they want + if (!R_SkinUsable(newplayernum, skinnum)) + newplayer->availabilities |= 1 << skinnum; + } + + // Read the color! + if (!lua_isnoneornil(L, 2)) + newplayer->skincolor = R_GetColorByName(luaL_checkstring(L, 2)); + else + newplayer->skincolor = skins[newplayer->skin].prefcolor; + + // Read the bot name, if given! + if (!lua_isnoneornil(L, 3)) + strcpy(player_names[newplayernum], luaL_checkstring(L, 3)); + + bot = luaL_optinteger(L, 4, 3); + newplayer->bot = (bot >= 0 && bot <= 3) ? bot : 3; + + // Set the skin + SetPlayerSkinByNum(newplayernum, skinnum); + + + if (netgame) + { + char joinmsg[256]; + + strcpy(joinmsg, M_GetText("\x82*Bot %s has joined the game (player %d)")); + strcpy(joinmsg, va(joinmsg, player_names[newplayernum], newplayernum)); + HU_AddChatText(joinmsg, false); + } + + LUA_PushUserdata(L, newplayer, META_PLAYER); + return 0; +} + static int Lcheckmapnumber (lua_State *L, int idx, const char *fun) { if (ISINLEVEL) @@ -3987,6 +4059,7 @@ static luaL_Reg lib[] = { // g_game {"G_AddGametype", lib_gAddGametype}, + {"G_AddPlayer", lib_gAddPlayer}, {"G_BuildMapName",lib_gBuildMapName}, {"G_BuildMapTitle",lib_gBuildMapTitle}, {"G_FindMap",lib_gFindMap}, From 9eeaef2e32c90d2c23a314c2cd99a0b72dde0f0a Mon Sep 17 00:00:00 2001 From: Shane Ellis Date: Fri, 15 Jan 2021 16:55:49 -0500 Subject: [PATCH 214/644] Exception made in R_SkinUsable() for player bot types --- src/r_skins.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/r_skins.c b/src/r_skins.c index 6f150f234..155a64700 100644 --- a/src/r_skins.c +++ b/src/r_skins.c @@ -198,6 +198,7 @@ boolean R_SkinUsable(INT32 playernum, INT32 skinnum) || (Playing() && (R_SkinAvailable(mapheaderinfo[gamemap-1]->forcecharacter) == skinnum)) // Force 1. || (netgame && (cv_forceskin.value == skinnum)) // Force 2. || (metalrecording && skinnum == 5) // Force 3. + || players[playernum].bot //Force (player is a bot) ); } @@ -511,10 +512,6 @@ static boolean R_ProcessPatchableFields(skin_t *skin, char *stoken, char *value) GETFLAG(MULTIABILITY) GETFLAG(NONIGHTSROTATION) GETFLAG(NONIGHTSSUPER) - GETFLAG(NOSUPERSPRITES) - GETFLAG(NOSUPERJUMPBOOST) - GETFLAG(CANBUSTWALLS) - GETFLAG(NOSHIELDABILITY) #undef GETFLAG else // let's check if it's a sound, otherwise error out From f166af4d8b7805e1ce5688cbef386f6ddc6e3ec1 Mon Sep 17 00:00:00 2001 From: Shane Ellis Date: Fri, 15 Jan 2021 17:00:21 -0500 Subject: [PATCH 215/644] CL_RemovePlayer() - Allow for removal of non-consoleplayer and non-secondaryviewplayer player instances (e.g. bot players) --- src/r_skins.c | 5748 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 5019 insertions(+), 729 deletions(-) diff --git a/src/r_skins.c b/src/r_skins.c index 155a64700..88b4d9387 100644 --- a/src/r_skins.c +++ b/src/r_skins.c @@ -1,6 +1,5 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. // Copyright (C) 1999-2020 by Sonic Team Junior. // @@ -8,826 +7,5117 @@ // terms of the GNU General Public License, version 2. // See the 'LICENSE' file for more details. //----------------------------------------------------------------------------- -/// \file r_skins.c -/// \brief Loading skins +/// \file d_clisrv.c +/// \brief SRB2 Network game communication and protocol, all OS independent parts. -#include "doomdef.h" -#include "console.h" -#include "g_game.h" -#include "r_local.h" -#include "st_stuff.h" -#include "w_wad.h" -#include "z_zone.h" -#include "m_misc.h" -#include "info.h" // spr2names -#include "i_video.h" // rendermode +#include +#ifdef __GNUC__ +#include //for unlink +#endif + +#include "i_net.h" #include "i_system.h" -#include "r_things.h" -#include "r_skins.h" +#include "i_video.h" +#include "d_net.h" +#include "d_main.h" +#include "g_game.h" +#include "st_stuff.h" +#include "hu_stuff.h" +#include "keys.h" +#include "g_input.h" // JOY1 +#include "m_menu.h" +#include "console.h" +#include "d_netfil.h" +#include "byteptr.h" +#include "p_saveg.h" +#include "z_zone.h" #include "p_local.h" -#include "dehacked.h" // get_number (for thok) -#include "m_cond.h" -#ifdef HWRENDER -#include "hardware/hw_md2.h" -#endif +#include "m_misc.h" +#include "am_map.h" +#include "m_random.h" +#include "mserv.h" +#include "y_inter.h" +#include "r_local.h" +#include "m_argv.h" +#include "p_setup.h" +#include "lzf.h" +#include "lua_script.h" +#include "lua_hook.h" +#include "md5.h" +#include "m_perfstats.h" -INT32 numskins = 0; -skin_t skins[MAXSKINS]; - -// FIXTHIS: don't work because it must be inistilised before the config load -//#define SKINVALUES -#ifdef SKINVALUES -CV_PossibleValue_t skin_cons_t[MAXSKINS+1]; +#ifndef NONET +// cl loading screen +#include "v_video.h" +#include "f_finale.h" #endif // -// P_GetSkinSprite2 -// For non-super players, tries each sprite2's immediate predecessor until it finds one with a number of frames or ends up at standing. -// For super players, does the same as above - but tries the super equivalent for each sprite2 before the non-super version. +// NETWORKING // +// gametic is the tic about to (or currently being) run +// Server: +// maketic is the tic that hasn't had control made for it yet +// nettics is the tic for each node +// firstticstosend is the lowest value of nettics +// Client: +// neededtic is the tic needed by the client to run the game +// firstticstosend is used to optimize a condition +// Normally maketic >= gametic > 0 -UINT8 P_GetSkinSprite2(skin_t *skin, UINT8 spr2, player_t *player) +#define PREDICTIONQUEUE BACKUPTICS +#define PREDICTIONMASK (PREDICTIONQUEUE-1) +#define MAX_REASONLENGTH 30 + +boolean server = true; // true or false but !server == client +#define client (!server) +boolean nodownload = false; +boolean serverrunning = false; +INT32 serverplayer = 0; +char motd[254], server_context[8]; // Message of the Day, Unique Context (even without Mumble support) + +// Server specific vars +UINT8 playernode[MAXPLAYERS]; +char playeraddress[MAXPLAYERS][64]; + +// Minimum timeout for sending the savegame +// The actual timeout will be longer depending on the savegame length +tic_t jointimeout = (10*TICRATE); +static boolean sendingsavegame[MAXNETNODES]; // Are we sending the savegame? +static boolean resendingsavegame[MAXNETNODES]; // Are we resending the savegame? +static tic_t savegameresendcooldown[MAXNETNODES]; // How long before we can resend again? +static tic_t freezetimeout[MAXNETNODES]; // Until when can this node freeze the server before getting a timeout? + +// Incremented by cv_joindelay when a client joins, decremented each tic. +// If higher than cv_joindelay * 2 (3 joins in a short timespan), joins are temporarily disabled. +static tic_t joindelay = 0; + +UINT16 pingmeasurecount = 1; +UINT32 realpingtable[MAXPLAYERS]; //the base table of ping where an average will be sent to everyone. +UINT32 playerpingtable[MAXPLAYERS]; //table of player latency values. +SINT8 nodetoplayer[MAXNETNODES]; +SINT8 nodetoplayer2[MAXNETNODES]; // say the numplayer for this node if any (splitscreen) +UINT8 playerpernode[MAXNETNODES]; // used specialy for scplitscreen +boolean nodeingame[MAXNETNODES]; // set false as nodes leave game +tic_t servermaxping = 800; // server's max ping. Defaults to 800 +static tic_t nettics[MAXNETNODES]; // what tic the client have received +static tic_t supposedtics[MAXNETNODES]; // nettics prevision for smaller packet +static UINT8 nodewaiting[MAXNETNODES]; +static tic_t firstticstosend; // min of the nettics +static tic_t tictoclear = 0; // optimize d_clearticcmd +static tic_t maketic; + +static INT16 consistancy[BACKUPTICS]; + +static UINT8 player_joining = false; +UINT8 hu_redownloadinggamestate = 0; + +UINT8 adminpassmd5[16]; +boolean adminpasswordset = false; + +// Client specific +static ticcmd_t localcmds; +static ticcmd_t localcmds2; +static boolean cl_packetmissed; +// here it is for the secondary local player (splitscreen) +static UINT8 mynode; // my address pointofview server +static boolean cl_redownloadinggamestate = false; + +static UINT8 localtextcmd[MAXTEXTCMD]; +static UINT8 localtextcmd2[MAXTEXTCMD]; // splitscreen +static tic_t neededtic; +SINT8 servernode = 0; // the number of the server node +/// \brief do we accept new players? +/// \todo WORK! +boolean acceptnewnode = true; + +// engine + +// Must be a power of two +#define TEXTCMD_HASH_SIZE 4 + +typedef struct textcmdplayer_s { - UINT8 super = 0, i = 0; + INT32 playernum; + UINT8 cmd[MAXTEXTCMD]; + struct textcmdplayer_s *next; +} textcmdplayer_t; - if (!skin) - return 0; +typedef struct textcmdtic_s +{ + tic_t tic; + textcmdplayer_t *playercmds[TEXTCMD_HASH_SIZE]; + struct textcmdtic_s *next; +} textcmdtic_t; - if ((playersprite_t)(spr2 & ~FF_SPR2SUPER) >= free_spr2) - return 0; +ticcmd_t netcmds[BACKUPTICS][MAXPLAYERS]; +static textcmdtic_t *textcmds[TEXTCMD_HASH_SIZE] = {NULL}; - while (!skin->sprites[spr2].numframes - && spr2 != SPR2_STND - && ++i < 32) // recursion limiter - { - if (spr2 & FF_SPR2SUPER) - { - super = FF_SPR2SUPER; - spr2 &= ~FF_SPR2SUPER; - continue; - } - switch(spr2) - { - // Normal special cases. - case SPR2_JUMP: - spr2 = ((player - ? player->charflags - : skin->flags) - & SF_NOJUMPSPIN) ? SPR2_SPNG : SPR2_ROLL; - break; - case SPR2_TIRE: - spr2 = ((player - ? player->charability - : skin->ability) - == CA_SWIM) ? SPR2_SWIM : SPR2_FLY; - break; - // Use the handy list, that's what it's there for! - default: - spr2 = spr2defaults[spr2]; - break; - } +consvar_t cv_showjoinaddress = CVAR_INIT ("showjoinaddress", "Off", CV_SAVE|CV_NETVAR, CV_OnOff, NULL); - spr2 |= super; - } +static CV_PossibleValue_t playbackspeed_cons_t[] = {{1, "MIN"}, {10, "MAX"}, {0, NULL}}; +consvar_t cv_playbackspeed = CVAR_INIT ("playbackspeed", "1", 0, playbackspeed_cons_t, NULL); - if (i >= 32) // probably an infinite loop... - return 0; +static inline void *G_DcpyTiccmd(void* dest, const ticcmd_t* src, const size_t n) +{ + const size_t d = n / sizeof(ticcmd_t); + const size_t r = n % sizeof(ticcmd_t); + UINT8 *ret = dest; - return spr2; + if (r) + M_Memcpy(dest, src, n); + else if (d) + G_MoveTiccmd(dest, src, d); + return ret+n; } -static void Sk_SetDefaultValue(skin_t *skin) +static inline void *G_ScpyTiccmd(ticcmd_t* dest, void* src, const size_t n) { - INT32 i; - // - // set default skin values - // - memset(skin, 0, sizeof (skin_t)); - snprintf(skin->name, - sizeof skin->name, "skin %u", (UINT32)(skin-skins)); - skin->name[sizeof skin->name - 1] = '\0'; - skin->wadnum = INT16_MAX; + const size_t d = n / sizeof(ticcmd_t); + const size_t r = n % sizeof(ticcmd_t); + UINT8 *ret = src; - skin->flags = 0; - - strcpy(skin->realname, "Someone"); - strcpy(skin->hudname, "???"); - - skin->starttranscolor = 96; - skin->prefcolor = SKINCOLOR_GREEN; - skin->supercolor = SKINCOLOR_SUPERGOLD1; - skin->prefoppositecolor = 0; // use tables - - skin->normalspeed = 36<runspeed = 28<thrustfactor = 5; - skin->accelstart = 96; - skin->acceleration = 40; - - skin->ability = CA_NONE; - skin->ability2 = CA2_SPINDASH; - skin->jumpfactor = FRACUNIT; - skin->actionspd = 30<mindash = 15<maxdash = 70<radius = mobjinfo[MT_PLAYER].radius; - skin->height = mobjinfo[MT_PLAYER].height; - skin->spinheight = FixedMul(skin->height, 2*FRACUNIT/3); - - skin->shieldscale = FRACUNIT; - skin->camerascale = FRACUNIT; - - skin->thokitem = -1; - skin->spinitem = -1; - skin->revitem = -1; - skin->followitem = 0; - - skin->highresscale = FRACUNIT; - skin->contspeed = 17; - skin->contangle = 0; - - skin->availability = 0; - - for (i = 0; i < sfx_skinsoundslot0; i++) - if (S_sfx[i].skinsound != -1) - skin->soundsid[S_sfx[i].skinsound] = i; + if (r) + M_Memcpy(dest, src, n); + else if (d) + G_MoveTiccmd(dest, src, d); + return ret+n; } -// -// Initialize the basic skins -// -void R_InitSkins(void) -{ -#ifdef SKINVALUES - INT32 i; - for (i = 0; i <= MAXSKINS; i++) - { - skin_cons_t[i].value = 0; - skin_cons_t[i].strvalue = NULL; - } + +// Some software don't support largest packet +// (original sersetup, not exactely, but the probability of sending a packet +// of 512 bytes is like 0.1) +UINT16 software_MAXPACKETLENGTH; + +/** Guesses the full value of a tic from its lowest byte, for a specific node + * + * \param low The lowest byte of the tic value + * \param node The node to deduce the tic for + * \return The full tic value + * + */ +tic_t ExpandTics(INT32 low, INT32 node) +{ + INT32 delta; + + delta = low - (nettics[node] & UINT8_MAX); + + if (delta >= -64 && delta <= 64) + return (nettics[node] & ~UINT8_MAX) + low; + else if (delta > 64) + return (nettics[node] & ~UINT8_MAX) - 256 + low; + else //if (delta < -64) + return (nettics[node] & ~UINT8_MAX) + 256 + low; +} + +// ----------------------------------------------------------------- +// Some extra data function for handle textcmd buffer +// ----------------------------------------------------------------- + +static void (*listnetxcmd[MAXNETXCMD])(UINT8 **p, INT32 playernum); + +void RegisterNetXCmd(netxcmd_t id, void (*cmd_f)(UINT8 **p, INT32 playernum)) +{ +#ifdef PARANOIA + if (id >= MAXNETXCMD) + I_Error("Command id %d too big", id); + if (listnetxcmd[id] != 0) + I_Error("Command id %d already used", id); #endif - - // no default skin! - numskins = 0; + listnetxcmd[id] = cmd_f; } -UINT32 R_GetSkinAvailabilities(void) +void SendNetXCmd(netxcmd_t id, const void *param, size_t nparam) { - INT32 s; - UINT32 response = 0; - - for (s = 0; s < MAXSKINS; s++) + if (localtextcmd[0]+2+nparam > MAXTEXTCMD) { - if (skins[s].availability && unlockables[skins[s].availability - 1].unlocked) - response |= (1 << s); - } - return response; -} - -// returns true if available in circumstances, otherwise nope -// warning don't use with an invalid skinnum other than -1 which always returns true -boolean R_SkinUsable(INT32 playernum, INT32 skinnum) -{ - return ((skinnum == -1) // Simplifies things elsewhere, since there's already plenty of checks for less-than-0... - || (!skins[skinnum].availability) - || (((netgame || multiplayer) && playernum != -1) ? (players[playernum].availabilities & (1 << skinnum)) : (unlockables[skins[skinnum].availability - 1].unlocked)) - || (modeattacking) // If you have someone else's run you might as well take a look - || (Playing() && (R_SkinAvailable(mapheaderinfo[gamemap-1]->forcecharacter) == skinnum)) // Force 1. - || (netgame && (cv_forceskin.value == skinnum)) // Force 2. - || (metalrecording && skinnum == 5) // Force 3. - || players[playernum].bot //Force (player is a bot) - ); -} - -// returns true if the skin name is found (loaded from pwad) -// warning return -1 if not found -INT32 R_SkinAvailable(const char *name) -{ - INT32 i; - - for (i = 0; i < numskins; i++) - { - // search in the skin list - if (stricmp(skins[i].name,name)==0) - return i; - } - return -1; -} - -// network code calls this when a 'skin change' is received -void SetPlayerSkin(INT32 playernum, const char *skinname) -{ - INT32 i = R_SkinAvailable(skinname); - player_t *player = &players[playernum]; - - if ((i != -1) && R_SkinUsable(playernum, i)) - { - SetPlayerSkinByNum(playernum, i); + // for future reference: if (cv_debug) != debug disabled. + CONS_Alert(CONS_ERROR, M_GetText("NetXCmd buffer full, cannot add netcmd %d! (size: %d, needed: %s)\n"), id, localtextcmd[0], sizeu1(nparam)); return; } - - if (P_IsLocalPlayer(player)) - CONS_Alert(CONS_WARNING, M_GetText("Skin '%s' not found.\n"), skinname); - else if(server || IsPlayerAdmin(consoleplayer)) - CONS_Alert(CONS_WARNING, M_GetText("Player %d (%s) skin '%s' not found\n"), playernum, player_names[playernum], skinname); - - SetPlayerSkinByNum(playernum, 0); + localtextcmd[0]++; + localtextcmd[localtextcmd[0]] = (UINT8)id; + if (param && nparam) + { + M_Memcpy(&localtextcmd[localtextcmd[0]+1], param, nparam); + localtextcmd[0] = (UINT8)(localtextcmd[0] + (UINT8)nparam); + } } -// Same as SetPlayerSkin, but uses the skin #. -// network code calls this when a 'skin change' is received -void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum) +// splitscreen player +void SendNetXCmd2(netxcmd_t id, const void *param, size_t nparam) { - player_t *player = &players[playernum]; - skin_t *skin = &skins[skinnum]; - UINT16 newcolor = 0; - - if (skinnum >= 0 && skinnum < numskins && R_SkinUsable(playernum, skinnum)) // Make sure it exists! + if (localtextcmd2[0]+2+nparam > MAXTEXTCMD) { - player->skin = skinnum; + I_Error("No more place in the buffer for netcmd %d\n",id); + return; + } + localtextcmd2[0]++; + localtextcmd2[localtextcmd2[0]] = (UINT8)id; + if (param && nparam) + { + M_Memcpy(&localtextcmd2[localtextcmd2[0]+1], param, nparam); + localtextcmd2[0] = (UINT8)(localtextcmd2[0] + (UINT8)nparam); + } +} - player->camerascale = skin->camerascale; - player->shieldscale = skin->shieldscale; +UINT8 GetFreeXCmdSize(void) +{ + // -1 for the size and another -1 for the ID. + return (UINT8)(localtextcmd[0] - 2); +} - player->charability = (UINT8)skin->ability; - player->charability2 = (UINT8)skin->ability2; +// Frees all textcmd memory for the specified tic +static void D_FreeTextcmd(tic_t tic) +{ + textcmdtic_t **tctprev = &textcmds[tic & (TEXTCMD_HASH_SIZE - 1)]; + textcmdtic_t *textcmdtic = *tctprev; - player->charflags = (UINT32)skin->flags; + while (textcmdtic && textcmdtic->tic != tic) + { + tctprev = &textcmdtic->next; + textcmdtic = textcmdtic->next; + } - player->thokitem = skin->thokitem < 0 ? (UINT32)mobjinfo[MT_PLAYER].painchance : (UINT32)skin->thokitem; - player->spinitem = skin->spinitem < 0 ? (UINT32)mobjinfo[MT_PLAYER].damage : (UINT32)skin->spinitem; - player->revitem = skin->revitem < 0 ? (mobjtype_t)mobjinfo[MT_PLAYER].raisestate : (UINT32)skin->revitem; - player->followitem = skin->followitem; + if (textcmdtic) + { + INT32 i; - if (((player->powers[pw_shield] & SH_NOSTACK) == SH_PINK) && (player->revitem == MT_LHRT || player->spinitem == MT_LHRT || player->thokitem == MT_LHRT)) // Healers can't keep their buff. - player->powers[pw_shield] &= SH_STACK; + // Remove this tic from the list. + *tctprev = textcmdtic->next; - player->actionspd = skin->actionspd; - player->mindash = skin->mindash; - player->maxdash = skin->maxdash; - - player->normalspeed = skin->normalspeed; - player->runspeed = skin->runspeed; - player->thrustfactor = skin->thrustfactor; - player->accelstart = skin->accelstart; - player->acceleration = skin->acceleration; - - player->jumpfactor = skin->jumpfactor; - - player->height = skin->height; - player->spinheight = skin->spinheight; - - if (!(cv_debug || devparm) && !(netgame || multiplayer || demoplayback)) + // Free all players. + for (i = 0; i < TEXTCMD_HASH_SIZE; i++) { - if (playernum == consoleplayer) - CV_StealthSetValue(&cv_playercolor, skin->prefcolor); - else if (playernum == secondarydisplayplayer) - CV_StealthSetValue(&cv_playercolor2, skin->prefcolor); - player->skincolor = newcolor = skin->prefcolor; - if (player->bot && botingame) + textcmdplayer_t *textcmdplayer = textcmdtic->playercmds[i]; + + while (textcmdplayer) { - botskin = (UINT8)(skinnum + 1); - botcolor = skin->prefcolor; + textcmdplayer_t *tcpnext = textcmdplayer->next; + Z_Free(textcmdplayer); + textcmdplayer = tcpnext; } } - if (player->followmobj) - { - P_RemoveMobj(player->followmobj); - P_SetTarget(&player->followmobj, NULL); - } - - if (player->mo) - { - fixed_t radius = FixedMul(skin->radius, player->mo->scale); - if ((player->powers[pw_carry] == CR_NIGHTSMODE) && (skin->sprites[SPR2_NFLY].numframes == 0)) // If you don't have a sprite for flying horizontally, use the default NiGHTS skin. - { - skin = &skins[DEFAULTNIGHTSSKIN]; - player->followitem = skin->followitem; - if (!(cv_debug || devparm) && !(netgame || multiplayer || demoplayback)) - newcolor = skin->prefcolor; // will be updated in thinker to flashing - } - player->mo->skin = skin; - if (newcolor) - player->mo->color = newcolor; - P_SetScale(player->mo, player->mo->scale); - player->mo->radius = radius; - - P_SetPlayerMobjState(player->mo, player->mo->state-states); // Prevent visual errors when switching between skins with differing number of frames - } - return; + // Free this tic's own memory. + Z_Free(textcmdtic); } - - if (P_IsLocalPlayer(player)) - CONS_Alert(CONS_WARNING, M_GetText("Requested skin %d not found\n"), skinnum); - else if(server || IsPlayerAdmin(consoleplayer)) - CONS_Alert(CONS_WARNING, "Player %d (%s) skin %d not found\n", playernum, player_names[playernum], skinnum); - SetPlayerSkinByNum(playernum, 0); // not found put the sonic skin } -// -// Add skins from a pwad, each skin preceded by 'S_SKIN' marker -// - -// Does the same is in w_wad, but check only for -// the first 6 characters (this is so we can have S_SKIN1, S_SKIN2.. -// for wad editors that don't like multiple resources of the same name) -// -static UINT16 W_CheckForSkinMarkerInPwad(UINT16 wadid, UINT16 startlump) +// Gets the buffer for the specified ticcmd, or NULL if there isn't one +static UINT8* D_GetExistingTextcmd(tic_t tic, INT32 playernum) { - UINT16 i; - const char *S_SKIN = "S_SKIN"; - lumpinfo_t *lump_p; + textcmdtic_t *textcmdtic = textcmds[tic & (TEXTCMD_HASH_SIZE - 1)]; + while (textcmdtic && textcmdtic->tic != tic) textcmdtic = textcmdtic->next; - // scan forward, start at - if (startlump < wadfiles[wadid]->numlumps) + // Do we have an entry for the tic? If so, look for player. + if (textcmdtic) { - lump_p = wadfiles[wadid]->lumpinfo + startlump; - for (i = startlump; i < wadfiles[wadid]->numlumps; i++, lump_p++) - if (memcmp(lump_p->name,S_SKIN,6)==0) - return i; + textcmdplayer_t *textcmdplayer = textcmdtic->playercmds[playernum & (TEXTCMD_HASH_SIZE - 1)]; + while (textcmdplayer && textcmdplayer->playernum != playernum) textcmdplayer = textcmdplayer->next; + + if (textcmdplayer) return textcmdplayer->cmd; } - return INT16_MAX; // not found + + return NULL; } -#define HUDNAMEWRITE(value) STRBUFCPY(skin->hudname, value) +// Gets the buffer for the specified ticcmd, creating one if necessary +static UINT8* D_GetTextcmd(tic_t tic, INT32 playernum) +{ + textcmdtic_t *textcmdtic = textcmds[tic & (TEXTCMD_HASH_SIZE - 1)]; + textcmdtic_t **tctprev = &textcmds[tic & (TEXTCMD_HASH_SIZE - 1)]; + textcmdplayer_t *textcmdplayer, **tcpprev; -// turn _ into spaces and . into katana dot -#define SYMBOLCONVERT(name) for (value = name; *value; value++)\ - {\ - if (*value == '_') *value = ' ';\ - else if (*value == '.') *value = '\x1E';\ + // Look for the tic. + while (textcmdtic && textcmdtic->tic != tic) + { + tctprev = &textcmdtic->next; + textcmdtic = textcmdtic->next; + } + + // If we don't have an entry for the tic, make it. + if (!textcmdtic) + { + textcmdtic = *tctprev = Z_Calloc(sizeof (textcmdtic_t), PU_STATIC, NULL); + textcmdtic->tic = tic; + } + + tcpprev = &textcmdtic->playercmds[playernum & (TEXTCMD_HASH_SIZE - 1)]; + textcmdplayer = *tcpprev; + + // Look for the player. + while (textcmdplayer && textcmdplayer->playernum != playernum) + { + tcpprev = &textcmdplayer->next; + textcmdplayer = textcmdplayer->next; + } + + // If we don't have an entry for the player, make it. + if (!textcmdplayer) + { + textcmdplayer = *tcpprev = Z_Calloc(sizeof (textcmdplayer_t), PU_STATIC, NULL); + textcmdplayer->playernum = playernum; + } + + return textcmdplayer->cmd; +} + +static void ExtraDataTicker(void) +{ + INT32 i; + + for (i = 0; i < MAXPLAYERS; i++) + if (playeringame[i] || i == 0) + { + UINT8 *bufferstart = D_GetExistingTextcmd(gametic, i); + + if (bufferstart) + { + UINT8 *curpos = bufferstart; + UINT8 *bufferend = &curpos[curpos[0]+1]; + + curpos++; + while (curpos < bufferend) + { + if (*curpos < MAXNETXCMD && listnetxcmd[*curpos]) + { + const UINT8 id = *curpos; + curpos++; + DEBFILE(va("executing x_cmd %s ply %u ", netxcmdnames[id - 1], i)); + (listnetxcmd[id])(&curpos, i); + DEBFILE("done\n"); } - -// -// Patch skins from a pwad, each skin preceded by 'P_SKIN' marker -// - -// Does the same is in w_wad, but check only for -// the first 6 characters (this is so we can have P_SKIN1, P_SKIN2.. -// for wad editors that don't like multiple resources of the same name) -// -static UINT16 W_CheckForPatchSkinMarkerInPwad(UINT16 wadid, UINT16 startlump) -{ - UINT16 i; - const char *P_SKIN = "P_SKIN"; - lumpinfo_t *lump_p; - - // scan forward, start at - if (startlump < wadfiles[wadid]->numlumps) - { - lump_p = wadfiles[wadid]->lumpinfo + startlump; - for (i = startlump; i < wadfiles[wadid]->numlumps; i++, lump_p++) - if (memcmp(lump_p->name,P_SKIN,6)==0) - return i; - } - return INT16_MAX; // not found -} - -static void R_LoadSkinSprites(UINT16 wadnum, UINT16 *lump, UINT16 *lastlump, skin_t *skin) -{ - UINT16 newlastlump; - UINT8 sprite2; - - *lump += 1; // start after S_SKIN - *lastlump = W_CheckNumForNamePwad("S_END",wadnum,*lump); // stop at S_END - - // old wadding practices die hard -- stop at S_SKIN (or P_SKIN) or S_START if they come before S_END. - newlastlump = W_CheckForSkinMarkerInPwad(wadnum,*lump); - if (newlastlump < *lastlump) *lastlump = newlastlump; - newlastlump = W_CheckForPatchSkinMarkerInPwad(wadnum,*lump); - if (newlastlump < *lastlump) *lastlump = newlastlump; - newlastlump = W_CheckNumForNamePwad("S_START",wadnum,*lump); - if (newlastlump < *lastlump) *lastlump = newlastlump; - - // ...and let's handle super, too - newlastlump = W_CheckNumForNamePwad("S_SUPER",wadnum,*lump); - if (newlastlump < *lastlump) - { - newlastlump++; - // load all sprite sets we are aware of... for super! - for (sprite2 = 0; sprite2 < free_spr2; sprite2++) - R_AddSingleSpriteDef(spr2names[sprite2], &skin->sprites[FF_SPR2SUPER|sprite2], wadnum, newlastlump, *lastlump); - - newlastlump--; - *lastlump = newlastlump; // okay, make the normal sprite set loading end there - } - - // load all sprite sets we are aware of... for normal stuff. - for (sprite2 = 0; sprite2 < free_spr2; sprite2++) - R_AddSingleSpriteDef(spr2names[sprite2], &skin->sprites[sprite2], wadnum, *lump, *lastlump); - - if (skin->sprites[0].numframes == 0) - I_Error("R_LoadSkinSprites: no frames found for sprite SPR2_%s\n", spr2names[0]); -} - -// returns whether found appropriate property -static boolean R_ProcessPatchableFields(skin_t *skin, char *stoken, char *value) -{ - // custom translation table - if (!stricmp(stoken, "startcolor")) - skin->starttranscolor = atoi(value); - -#define FULLPROCESS(field) else if (!stricmp(stoken, #field)) skin->field = get_number(value); - // character type identification - FULLPROCESS(flags) - FULLPROCESS(ability) - FULLPROCESS(ability2) - - FULLPROCESS(thokitem) - FULLPROCESS(spinitem) - FULLPROCESS(revitem) - FULLPROCESS(followitem) -#undef FULLPROCESS - -#define GETFRACBITS(field) else if (!stricmp(stoken, #field)) skin->field = atoi(value)<field = atoi(value); - GETINT(thrustfactor) - GETINT(accelstart) - GETINT(acceleration) - GETINT(contspeed) - GETINT(contangle) -#undef GETINT - -#define GETSKINCOLOR(field) else if (!stricmp(stoken, #field)) \ -{ \ - UINT16 color = R_GetColorByName(value); \ - skin->field = (color ? color : SKINCOLOR_GREEN); \ -} - GETSKINCOLOR(prefcolor) - GETSKINCOLOR(prefoppositecolor) -#undef GETSKINCOLOR - else if (!stricmp(stoken, "supercolor")) - { - UINT16 color = R_GetSuperColorByName(value); - skin->supercolor = (color ? color : SKINCOLOR_SUPERGOLD1); - } - -#define GETFLOAT(field) else if (!stricmp(stoken, #field)) skin->field = FLOAT_TO_FIXED(atof(value)); - GETFLOAT(jumpfactor) - GETFLOAT(highresscale) - GETFLOAT(shieldscale) - GETFLOAT(camerascale) -#undef GETFLOAT - -#define GETFLAG(field) else if (!stricmp(stoken, #field)) { \ - strupr(value); \ - if (atoi(value) || value[0] == 'T' || value[0] == 'Y') \ - skin->flags |= (SF_##field); \ - else \ - skin->flags &= ~(SF_##field); \ -} - // parameters for individual character flags - // these are uppercase so they can be concatenated with SF_ - // 1, true, yes are all valid values - GETFLAG(SUPER) - GETFLAG(NOSUPERSPIN) - GETFLAG(NOSPINDASHDUST) - GETFLAG(HIRES) - GETFLAG(NOSKID) - GETFLAG(NOSPEEDADJUST) - GETFLAG(RUNONWATER) - GETFLAG(NOJUMPSPIN) - GETFLAG(NOJUMPDAMAGE) - GETFLAG(STOMPDAMAGE) - GETFLAG(MARIODAMAGE) - GETFLAG(MACHINE) - GETFLAG(DASHMODE) - GETFLAG(FASTEDGE) - GETFLAG(MULTIABILITY) - GETFLAG(NONIGHTSROTATION) - GETFLAG(NONIGHTSSUPER) -#undef GETFLAG - - else // let's check if it's a sound, otherwise error out - { - boolean found = false; - sfxenum_t i; - size_t stokenadjust; - - // Remove the prefix. (We need to affect an adjusting variable so that we can print error messages if it's not actually a sound.) - if ((stoken[0] == 'D' || stoken[0] == 'd') && (stoken[1] == 'S' || stoken[1] == 's')) // DS* - stokenadjust = 2; - else // sfx_* - stokenadjust = 4; - - // Remove the prefix. (We can affect this directly since we're not going to use it again.) - if ((value[0] == 'D' || value[0] == 'd') && (value[1] == 'S' || value[1] == 's')) // DS* - value += 2; - else // sfx_* - value += 4; - - // copy name of sounds that are remapped - // for this skin - for (i = 0; i < sfx_skinsoundslot0; i++) - { - if (!S_sfx[i].name) - continue; - if (S_sfx[i].skinsound != -1 - && !stricmp(S_sfx[i].name, - stoken + stokenadjust)) - { - skin->soundsid[S_sfx[i].skinsound] = - S_AddSoundFx(value, S_sfx[i].singularity, S_sfx[i].pitch, true); - found = true; + else + { + if (server) + { + SendKick(i, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY); + DEBFILE(va("player %d kicked [gametic=%u] reason as follows:\n", i, gametic)); + } + CONS_Alert(CONS_WARNING, M_GetText("Got unknown net command [%s]=%d (max %d)\n"), sizeu1(curpos - bufferstart), *curpos, bufferstart[0]); + break; + } + } } } - return found; - } + + // If you are a client, you can safely forget the net commands for this tic + // If you are the server, you need to remember them until every client has been acknowledged, + // because if you need to resend a PT_SERVERTICS packet, you will need to put the commands in it + if (client) + D_FreeTextcmd(gametic); +} + +static void D_Clearticcmd(tic_t tic) +{ + INT32 i; + + D_FreeTextcmd(tic); + + for (i = 0; i < MAXPLAYERS; i++) + netcmds[tic%BACKUPTICS][i].angleturn = 0; + + DEBFILE(va("clear tic %5u (%2u)\n", tic, tic%BACKUPTICS)); +} + +void D_ResetTiccmds(void) +{ + INT32 i; + + memset(&localcmds, 0, sizeof(ticcmd_t)); + memset(&localcmds2, 0, sizeof(ticcmd_t)); + + // Reset the net command list + for (i = 0; i < TEXTCMD_HASH_SIZE; i++) + while (textcmds[i]) + D_Clearticcmd(textcmds[i]->tic); +} + +void SendKick(UINT8 playernum, UINT8 msg) +{ + UINT8 buf[2]; + + if (!(server && cv_rejointimeout.value)) + msg &= ~KICK_MSG_KEEP_BODY; + + buf[0] = playernum; + buf[1] = msg; + SendNetXCmd(XD_KICK, &buf, 2); +} + +// ----------------------------------------------------------------- +// end of extra data function +// ----------------------------------------------------------------- + +// ----------------------------------------------------------------- +// extra data function for lmps +// ----------------------------------------------------------------- + +// if extradatabit is set, after the ziped tic you find this: +// +// type | description +// ---------+-------------- +// byte | size of the extradata +// byte | the extradata (xd) bits: see XD_... +// with this byte you know what parameter folow +// if (xd & XDNAMEANDCOLOR) +// byte | color +// char[MAXPLAYERNAME] | name of the player +// endif +// if (xd & XD_WEAPON_PREF) +// byte | original weapon switch: boolean, true if use the old +// | weapon switch methode +// char[NUMWEAPONS] | the weapon switch priority +// byte | autoaim: true if use the old autoaim system +// endif +/*boolean AddLmpExtradata(UINT8 **demo_point, INT32 playernum) +{ + UINT8 *textcmd = D_GetExistingTextcmd(gametic, playernum); + + if (!textcmd) + return false; + + M_Memcpy(*demo_point, textcmd, textcmd[0]+1); + *demo_point += textcmd[0]+1; return true; } -// -// Find skin sprites, sounds & optional status bar face, & add them -// -void R_AddSkins(UINT16 wadnum) +void ReadLmpExtraData(UINT8 **demo_pointer, INT32 playernum) { - UINT16 lump, lastlump = 0; - char *buf; - char *buf2; - char *stoken; - char *value; - size_t size; - skin_t *skin; - boolean hudname, realname; + UINT8 nextra; + UINT8 *textcmd; - // - // search for all skin markers in pwad - // + if (!demo_pointer) + return; - while ((lump = W_CheckForSkinMarkerInPwad(wadnum, lastlump)) != INT16_MAX) + textcmd = D_GetTextcmd(gametic, playernum); + nextra = **demo_pointer; + M_Memcpy(textcmd, *demo_pointer, nextra + 1); + // increment demo pointer + *demo_pointer += nextra + 1; +}*/ + +// ----------------------------------------------------------------- +// end extra data function for lmps +// ----------------------------------------------------------------- + +static INT16 Consistancy(void); + +typedef enum +{ + CL_SEARCHING, + CL_DOWNLOADFILES, + CL_ASKJOIN, + CL_WAITJOINRESPONSE, + CL_DOWNLOADSAVEGAME, + CL_CONNECTED, + CL_ABORTED +} cl_mode_t; + +static void GetPackets(void); + +static cl_mode_t cl_mode = CL_SEARCHING; + +#ifndef NONET +#define SNAKE_SPEED 5 + +#define SNAKE_NUM_BLOCKS_X 20 +#define SNAKE_NUM_BLOCKS_Y 10 +#define SNAKE_BLOCK_SIZE 12 +#define SNAKE_BORDER_SIZE 12 + +#define SNAKE_MAP_WIDTH (SNAKE_NUM_BLOCKS_X * SNAKE_BLOCK_SIZE) +#define SNAKE_MAP_HEIGHT (SNAKE_NUM_BLOCKS_Y * SNAKE_BLOCK_SIZE) + +#define SNAKE_LEFT_X ((BASEVIDWIDTH - SNAKE_MAP_WIDTH) / 2 - SNAKE_BORDER_SIZE) +#define SNAKE_RIGHT_X (SNAKE_LEFT_X + SNAKE_MAP_WIDTH + SNAKE_BORDER_SIZE * 2 - 1) +#define SNAKE_BOTTOM_Y (BASEVIDHEIGHT - 48) +#define SNAKE_TOP_Y (SNAKE_BOTTOM_Y - SNAKE_MAP_HEIGHT - SNAKE_BORDER_SIZE * 2 + 1) + +enum snake_bonustype_s { + SNAKE_BONUS_NONE = 0, + SNAKE_BONUS_SLOW, + SNAKE_BONUS_FAST, + SNAKE_BONUS_GHOST, + SNAKE_BONUS_NUKE, + SNAKE_BONUS_SCISSORS, + SNAKE_BONUS_REVERSE, + SNAKE_BONUS_EGGMAN, + SNAKE_NUM_BONUSES, +}; + +static const char *snake_bonuspatches[] = { + NULL, + "DL_SLOW", + "TVSSC0", + "TVIVC0", + "TVARC0", + "DL_SCISSORS", + "TVRCC0", + "TVEGC0", +}; + +static const char *snake_backgrounds[] = { + "RVPUMICF", + "FRSTRCKF", + "TAR", + "MMFLRB4", + "RVDARKF1", + "RVZWALF1", + "RVZWALF4", + "RVZWALF5", + "RVZGRS02", + "RVZGRS04", +}; + +typedef struct snake_s +{ + boolean paused; + boolean pausepressed; + tic_t time; + tic_t nextupdate; + boolean gameover; + UINT8 background; + + UINT16 snakelength; + enum snake_bonustype_s snakebonus; + tic_t snakebonustime; + UINT8 snakex[SNAKE_NUM_BLOCKS_X * SNAKE_NUM_BLOCKS_Y]; + UINT8 snakey[SNAKE_NUM_BLOCKS_X * SNAKE_NUM_BLOCKS_Y]; + UINT8 snakedir[SNAKE_NUM_BLOCKS_X * SNAKE_NUM_BLOCKS_Y]; + + UINT8 applex; + UINT8 appley; + + enum snake_bonustype_s bonustype; + UINT8 bonusx; + UINT8 bonusy; +} snake_t; + +static snake_t *snake = NULL; + +static void Snake_Initialise(void) +{ + if (!snake) + snake = malloc(sizeof(snake_t)); + + snake->paused = false; + snake->pausepressed = false; + snake->time = 0; + snake->nextupdate = SNAKE_SPEED; + snake->gameover = false; + snake->background = M_RandomKey(sizeof(snake_backgrounds) / sizeof(*snake_backgrounds)); + + snake->snakelength = 1; + snake->snakebonus = SNAKE_BONUS_NONE; + snake->snakex[0] = M_RandomKey(SNAKE_NUM_BLOCKS_X); + snake->snakey[0] = M_RandomKey(SNAKE_NUM_BLOCKS_Y); + snake->snakedir[0] = 0; + snake->snakedir[1] = 0; + + snake->applex = M_RandomKey(SNAKE_NUM_BLOCKS_X); + snake->appley = M_RandomKey(SNAKE_NUM_BLOCKS_Y); + + snake->bonustype = SNAKE_BONUS_NONE; +} + +static UINT8 Snake_GetOppositeDir(UINT8 dir) +{ + if (dir == 1 || dir == 3) + return dir + 1; + else if (dir == 2 || dir == 4) + return dir - 1; + else + return 12 + 5 - dir; +} + +static void Snake_FindFreeSlot(UINT8 *freex, UINT8 *freey, UINT8 headx, UINT8 heady) +{ + UINT8 x, y; + UINT16 i; + + do { - // advance by default - lastlump = lump + 1; + x = M_RandomKey(SNAKE_NUM_BLOCKS_X); + y = M_RandomKey(SNAKE_NUM_BLOCKS_Y); - if (numskins >= MAXSKINS) - { - CONS_Debug(DBG_RENDER, "ignored skin (%d skins maximum)\n", MAXSKINS); - continue; // so we know how many skins couldn't be added - } - buf = W_CacheLumpNumPwad(wadnum, lump, PU_CACHE); - size = W_LumpLengthPwad(wadnum, lump); + for (i = 0; i < snake->snakelength; i++) + if (x == snake->snakex[i] && y == snake->snakey[i]) + break; + } while (i < snake->snakelength || (x == headx && y == heady) + || (x == snake->applex && y == snake->appley) + || (snake->bonustype != SNAKE_BONUS_NONE && x == snake->bonusx && y == snake->bonusy)); - // for strtok - buf2 = malloc(size+1); - if (!buf2) - I_Error("R_AddSkins: No more free memory\n"); - M_Memcpy(buf2,buf,size); - buf2[size] = '\0'; + *freex = x; + *freey = y; +} - // set defaults - skin = &skins[numskins]; - Sk_SetDefaultValue(skin); - skin->wadnum = wadnum; - hudname = realname = false; - // parse - stoken = strtok (buf2, "\r\n= "); - while (stoken) - { - if ((stoken[0] == '/' && stoken[1] == '/') - || (stoken[0] == '#'))// skip comments - { - stoken = strtok(NULL, "\r\n"); // skip end of line - goto next_token; // find the real next token - } +static void Snake_Handle(void) +{ + UINT8 x, y; + UINT8 oldx, oldy; + UINT16 i; - value = strtok(NULL, "\r\n= "); - - if (!value) - I_Error("R_AddSkins: syntax error in S_SKIN lump# %d(%s) in WAD %s\n", lump, W_CheckNameForNumPwad(wadnum,lump), wadfiles[wadnum]->filename); - - // Some of these can't go in R_ProcessPatchableFields because they have side effects for future lines. - // Others can't go in there because we don't want them to be patchable. - if (!stricmp(stoken, "name")) - { - INT32 skinnum = R_SkinAvailable(value); - strlwr(value); - if (skinnum == -1) - STRBUFCPY(skin->name, value); - // the skin name must uniquely identify a single skin - // if the name is already used I make the name 'namex' - // using the default skin name's number set above - else - { - const size_t stringspace = - strlen(value) + sizeof (numskins) + 1; - char *value2 = Z_Malloc(stringspace, PU_STATIC, NULL); - snprintf(value2, stringspace, - "%s%d", value, numskins); - value2[stringspace - 1] = '\0'; - if (R_SkinAvailable(value2) == -1) - // I'm lazy so if NEW name is already used I leave the 'skin x' - // default skin name set in Sk_SetDefaultValue - STRBUFCPY(skin->name, value2); - Z_Free(value2); - } - - // copy to hudname and fullname as a default. - if (!realname) - { - STRBUFCPY(skin->realname, skin->name); - for (value = skin->realname; *value; value++) - { - if (*value == '_') *value = ' '; // turn _ into spaces. - else if (*value == '.') *value = '\x1E'; // turn . into katana dot. - } - } - if (!hudname) - { - HUDNAMEWRITE(skin->name); - strupr(skin->hudname); - SYMBOLCONVERT(skin->hudname) - } - } - else if (!stricmp(stoken, "realname")) - { // Display name (eg. "Knuckles") - realname = true; - STRBUFCPY(skin->realname, value); - SYMBOLCONVERT(skin->realname) - if (!hudname) - HUDNAMEWRITE(skin->realname); - } - else if (!stricmp(stoken, "hudname")) - { // Life icon name (eg. "K.T.E") - hudname = true; - HUDNAMEWRITE(value); - SYMBOLCONVERT(skin->hudname) - if (!realname) - STRBUFCPY(skin->realname, skin->hudname); - } - else if (!stricmp(stoken, "availability")) - { - skin->availability = atoi(value); - if (skin->availability >= MAXUNLOCKABLES) - skin->availability = 0; - } - else if (!R_ProcessPatchableFields(skin, stoken, value)) - CONS_Debug(DBG_SETUP, "R_AddSkins: Unknown keyword '%s' in S_SKIN lump #%d (WAD %s)\n", stoken, lump, wadfiles[wadnum]->filename); - -next_token: - stoken = strtok(NULL, "\r\n= "); - } - free(buf2); - - // Add sprites - R_LoadSkinSprites(wadnum, &lump, &lastlump, skin); - //ST_LoadFaceGraphics(numskins); -- nah let's do this elsewhere - - R_FlushTranslationColormapCache(); - - if (!skin->availability) // Safe to print... - CONS_Printf(M_GetText("Added skin '%s'\n"), skin->name); -#ifdef SKINVALUES - skin_cons_t[numskins].value = numskins; - skin_cons_t[numskins].strvalue = skin->name; -#endif - -#ifdef HWRENDER - if (rendermode == render_opengl) - HWR_AddPlayerModel(numskins); -#endif - - numskins++; + // Handle retry + if (snake->gameover && (PLAYER1INPUTDOWN(gc_jump) || gamekeydown[KEY_ENTER])) + { + Snake_Initialise(); + snake->pausepressed = true; // Avoid accidental pause on respawn } - return; + + // Handle pause + if (PLAYER1INPUTDOWN(gc_pause) || gamekeydown[KEY_ENTER]) + { + if (!snake->pausepressed) + snake->paused = !snake->paused; + snake->pausepressed = true; + } + else + snake->pausepressed = false; + + if (snake->paused) + return; + + snake->time++; + + x = snake->snakex[0]; + y = snake->snakey[0]; + oldx = snake->snakex[1]; + oldy = snake->snakey[1]; + + // Update direction + if (gamekeydown[KEY_LEFTARROW]) + { + if (snake->snakelength < 2 || x <= oldx) + snake->snakedir[0] = 1; + } + else if (gamekeydown[KEY_RIGHTARROW]) + { + if (snake->snakelength < 2 || x >= oldx) + snake->snakedir[0] = 2; + } + else if (gamekeydown[KEY_UPARROW]) + { + if (snake->snakelength < 2 || y <= oldy) + snake->snakedir[0] = 3; + } + else if (gamekeydown[KEY_DOWNARROW]) + { + if (snake->snakelength < 2 || y >= oldy) + snake->snakedir[0] = 4; + } + + if (snake->snakebonustime) + { + snake->snakebonustime--; + if (!snake->snakebonustime) + snake->snakebonus = SNAKE_BONUS_NONE; + } + + snake->nextupdate--; + if (snake->nextupdate) + return; + if (snake->snakebonus == SNAKE_BONUS_SLOW) + snake->nextupdate = SNAKE_SPEED * 2; + else if (snake->snakebonus == SNAKE_BONUS_FAST) + snake->nextupdate = SNAKE_SPEED * 2 / 3; + else + snake->nextupdate = SNAKE_SPEED; + + if (snake->gameover) + return; + + // Find new position + switch (snake->snakedir[0]) + { + case 1: + if (x > 0) + x--; + else + snake->gameover = true; + break; + case 2: + if (x < SNAKE_NUM_BLOCKS_X - 1) + x++; + else + snake->gameover = true; + break; + case 3: + if (y > 0) + y--; + else + snake->gameover = true; + break; + case 4: + if (y < SNAKE_NUM_BLOCKS_Y - 1) + y++; + else + snake->gameover = true; + break; + } + + // Check collision with snake + if (snake->snakebonus != SNAKE_BONUS_GHOST) + for (i = 1; i < snake->snakelength - 1; i++) + if (x == snake->snakex[i] && y == snake->snakey[i]) + { + if (snake->snakebonus == SNAKE_BONUS_SCISSORS) + { + snake->snakebonus = SNAKE_BONUS_NONE; + snake->snakelength = i; + S_StartSound(NULL, sfx_adderr); + } + else + snake->gameover = true; + } + + if (snake->gameover) + { + S_StartSound(NULL, sfx_lose); + return; + } + + // Check collision with apple + if (x == snake->applex && y == snake->appley) + { + if (snake->snakelength + 3 < SNAKE_NUM_BLOCKS_X * SNAKE_NUM_BLOCKS_Y) + { + snake->snakelength++; + snake->snakex [snake->snakelength - 1] = snake->snakex [snake->snakelength - 2]; + snake->snakey [snake->snakelength - 1] = snake->snakey [snake->snakelength - 2]; + snake->snakedir[snake->snakelength - 1] = snake->snakedir[snake->snakelength - 2]; + } + + // Spawn new apple + Snake_FindFreeSlot(&snake->applex, &snake->appley, x, y); + + // Spawn new bonus + if (!(snake->snakelength % 5)) + { + do + { + snake->bonustype = M_RandomKey(SNAKE_NUM_BONUSES - 1) + 1; + } while (snake->snakelength > SNAKE_NUM_BLOCKS_X * SNAKE_NUM_BLOCKS_Y * 3 / 4 + && (snake->bonustype == SNAKE_BONUS_EGGMAN || snake->bonustype == SNAKE_BONUS_FAST || snake->bonustype == SNAKE_BONUS_REVERSE)); + + Snake_FindFreeSlot(&snake->bonusx, &snake->bonusy, x, y); + } + + S_StartSound(NULL, sfx_s3k6b); + } + + if (snake->snakelength > 1 && snake->snakedir[0]) + { + UINT8 dir = snake->snakedir[0]; + + oldx = snake->snakex[1]; + oldy = snake->snakey[1]; + + // Move + for (i = snake->snakelength - 1; i > 0; i--) + { + snake->snakex[i] = snake->snakex[i - 1]; + snake->snakey[i] = snake->snakey[i - 1]; + snake->snakedir[i] = snake->snakedir[i - 1]; + } + + // Handle corners + if (x < oldx && dir == 3) + dir = 5; + else if (x > oldx && dir == 3) + dir = 6; + else if (x < oldx && dir == 4) + dir = 7; + else if (x > oldx && dir == 4) + dir = 8; + else if (y < oldy && dir == 1) + dir = 9; + else if (y < oldy && dir == 2) + dir = 10; + else if (y > oldy && dir == 1) + dir = 11; + else if (y > oldy && dir == 2) + dir = 12; + snake->snakedir[1] = dir; + } + + snake->snakex[0] = x; + snake->snakey[0] = y; + + // Check collision with bonus + if (snake->bonustype != SNAKE_BONUS_NONE && x == snake->bonusx && y == snake->bonusy) + { + S_StartSound(NULL, sfx_ncchip); + + switch (snake->bonustype) + { + case SNAKE_BONUS_SLOW: + snake->snakebonus = SNAKE_BONUS_SLOW; + snake->snakebonustime = 20 * TICRATE; + break; + case SNAKE_BONUS_FAST: + snake->snakebonus = SNAKE_BONUS_FAST; + snake->snakebonustime = 20 * TICRATE; + break; + case SNAKE_BONUS_GHOST: + snake->snakebonus = SNAKE_BONUS_GHOST; + snake->snakebonustime = 10 * TICRATE; + break; + case SNAKE_BONUS_NUKE: + for (i = 0; i < snake->snakelength; i++) + { + snake->snakex [i] = snake->snakex [0]; + snake->snakey [i] = snake->snakey [0]; + snake->snakedir[i] = snake->snakedir[0]; + } + + S_StartSound(NULL, sfx_bkpoof); + break; + case SNAKE_BONUS_SCISSORS: + snake->snakebonus = SNAKE_BONUS_SCISSORS; + snake->snakebonustime = 60 * TICRATE; + break; + case SNAKE_BONUS_REVERSE: + for (i = 0; i < (snake->snakelength + 1) / 2; i++) + { + UINT16 i2 = snake->snakelength - 1 - i; + UINT8 tmpx = snake->snakex [i]; + UINT8 tmpy = snake->snakey [i]; + UINT8 tmpdir = snake->snakedir[i]; + + // Swap first segment with last segment + snake->snakex [i] = snake->snakex [i2]; + snake->snakey [i] = snake->snakey [i2]; + snake->snakedir[i] = Snake_GetOppositeDir(snake->snakedir[i2]); + snake->snakex [i2] = tmpx; + snake->snakey [i2] = tmpy; + snake->snakedir[i2] = Snake_GetOppositeDir(tmpdir); + } + + snake->snakedir[0] = 0; + + S_StartSound(NULL, sfx_gravch); + break; + default: + if (snake->snakebonus != SNAKE_BONUS_GHOST) + { + snake->gameover = true; + S_StartSound(NULL, sfx_lose); + } + } + + snake->bonustype = SNAKE_BONUS_NONE; + } +} + +static void Snake_Draw(void) +{ + INT16 i; + + // Background + V_DrawFlatFill( + SNAKE_LEFT_X + SNAKE_BORDER_SIZE, + SNAKE_TOP_Y + SNAKE_BORDER_SIZE, + SNAKE_MAP_WIDTH, + SNAKE_MAP_HEIGHT, + W_GetNumForName(snake_backgrounds[snake->background]) + ); + + // Borders + V_DrawFill(SNAKE_LEFT_X, SNAKE_TOP_Y, SNAKE_BORDER_SIZE + SNAKE_MAP_WIDTH, SNAKE_BORDER_SIZE, 242); // Top + V_DrawFill(SNAKE_LEFT_X + SNAKE_BORDER_SIZE + SNAKE_MAP_WIDTH, SNAKE_TOP_Y, SNAKE_BORDER_SIZE, SNAKE_BORDER_SIZE + SNAKE_MAP_HEIGHT, 242); // Right + V_DrawFill(SNAKE_LEFT_X + SNAKE_BORDER_SIZE, SNAKE_TOP_Y + SNAKE_BORDER_SIZE + SNAKE_MAP_HEIGHT, SNAKE_BORDER_SIZE + SNAKE_MAP_WIDTH, SNAKE_BORDER_SIZE, 242); // Bottom + V_DrawFill(SNAKE_LEFT_X, SNAKE_TOP_Y + SNAKE_BORDER_SIZE, SNAKE_BORDER_SIZE, SNAKE_BORDER_SIZE + SNAKE_MAP_HEIGHT, 242); // Left + + // Apple + V_DrawFixedPatch( + (SNAKE_LEFT_X + SNAKE_BORDER_SIZE + snake->applex * SNAKE_BLOCK_SIZE + SNAKE_BLOCK_SIZE / 2) * FRACUNIT, + (SNAKE_TOP_Y + SNAKE_BORDER_SIZE + snake->appley * SNAKE_BLOCK_SIZE + SNAKE_BLOCK_SIZE / 2) * FRACUNIT, + FRACUNIT / 4, + 0, + W_CachePatchLongName("DL_APPLE", PU_HUDGFX), + NULL + ); + + // Bonus + if (snake->bonustype != SNAKE_BONUS_NONE) + V_DrawFixedPatch( + (SNAKE_LEFT_X + SNAKE_BORDER_SIZE + snake->bonusx * SNAKE_BLOCK_SIZE + SNAKE_BLOCK_SIZE / 2 ) * FRACUNIT, + (SNAKE_TOP_Y + SNAKE_BORDER_SIZE + snake->bonusy * SNAKE_BLOCK_SIZE + SNAKE_BLOCK_SIZE / 2 + 4) * FRACUNIT, + FRACUNIT / 2, + 0, + W_CachePatchLongName(snake_bonuspatches[snake->bonustype], PU_HUDGFX), + NULL + ); + + // Snake + if (!snake->gameover || snake->time % 8 < 8 / 2) // Blink if game over + { + for (i = snake->snakelength - 1; i >= 0; i--) + { + const char *patchname; + UINT8 dir = snake->snakedir[i]; + + if (i == 0) // Head + { + switch (dir) + { + case 1: patchname = "DL_SNAKEHEAD_L"; break; + case 2: patchname = "DL_SNAKEHEAD_R"; break; + case 3: patchname = "DL_SNAKEHEAD_T"; break; + case 4: patchname = "DL_SNAKEHEAD_B"; break; + default: patchname = "DL_SNAKEHEAD_M"; + } + } + else // Body + { + switch (dir) + { + case 1: patchname = "DL_SNAKEBODY_L"; break; + case 2: patchname = "DL_SNAKEBODY_R"; break; + case 3: patchname = "DL_SNAKEBODY_T"; break; + case 4: patchname = "DL_SNAKEBODY_B"; break; + case 5: patchname = "DL_SNAKEBODY_LT"; break; + case 6: patchname = "DL_SNAKEBODY_RT"; break; + case 7: patchname = "DL_SNAKEBODY_LB"; break; + case 8: patchname = "DL_SNAKEBODY_RB"; break; + case 9: patchname = "DL_SNAKEBODY_TL"; break; + case 10: patchname = "DL_SNAKEBODY_TR"; break; + case 11: patchname = "DL_SNAKEBODY_BL"; break; + case 12: patchname = "DL_SNAKEBODY_BR"; break; + default: patchname = "DL_SNAKEBODY_B"; + } + } + + V_DrawFixedPatch( + (SNAKE_LEFT_X + SNAKE_BORDER_SIZE + snake->snakex[i] * SNAKE_BLOCK_SIZE + SNAKE_BLOCK_SIZE / 2) * FRACUNIT, + (SNAKE_TOP_Y + SNAKE_BORDER_SIZE + snake->snakey[i] * SNAKE_BLOCK_SIZE + SNAKE_BLOCK_SIZE / 2) * FRACUNIT, + i == 0 && dir == 0 ? FRACUNIT / 5 : FRACUNIT / 2, + snake->snakebonus == SNAKE_BONUS_GHOST ? V_TRANSLUCENT : 0, + W_CachePatchLongName(patchname, PU_HUDGFX), + NULL + ); + } + } + + // Length + V_DrawString(SNAKE_RIGHT_X + 4, SNAKE_TOP_Y, V_MONOSPACE, va("%u", snake->snakelength)); + + // Bonus + if (snake->snakebonus != SNAKE_BONUS_NONE + && (snake->snakebonustime >= 3 * TICRATE || snake->time % 4 < 4 / 2)) + V_DrawFixedPatch( + (SNAKE_RIGHT_X + 10) * FRACUNIT, + (SNAKE_TOP_Y + 24) * FRACUNIT, + FRACUNIT / 2, + 0, + W_CachePatchLongName(snake_bonuspatches[snake->snakebonus], PU_HUDGFX), + NULL + ); } // -// Patch skin sprites +// CL_DrawConnectionStatus // -void R_PatchSkins(UINT16 wadnum) +// Keep the local client informed of our status. +// +static inline void CL_DrawConnectionStatus(void) { - UINT16 lump, lastlump = 0; - char *buf; - char *buf2; - char *stoken; - char *value; - size_t size; - skin_t *skin; - boolean noskincomplain, realname, hudname; + INT32 ccstime = I_GetTime(); - // - // search for all skin patch markers in pwad - // + // Draw background fade + if (!menuactive) // menu already draws its own fade + V_DrawFadeScreen(0xFF00, 16); // force default - while ((lump = W_CheckForPatchSkinMarkerInPwad(wadnum, lastlump)) != INT16_MAX) + // Draw the bottom box. + M_DrawTextBox(BASEVIDWIDTH/2-128-8, BASEVIDHEIGHT-16-8, 32, 1); + V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-16-16, V_YELLOWMAP, "Press ESC to abort"); + + if (cl_mode != CL_DOWNLOADFILES) { - INT32 skinnum = 0; + INT32 i, animtime = ((ccstime / 4) & 15) + 16; + UINT8 palstart = (cl_mode == CL_SEARCHING) ? 32 : 96; + // 15 pal entries total. + const char *cltext; - // advance by default - lastlump = lump + 1; + if (!(cl_mode == CL_DOWNLOADSAVEGAME && lastfilenum != -1)) + for (i = 0; i < 16; ++i) + V_DrawFill((BASEVIDWIDTH/2-128) + (i * 16), BASEVIDHEIGHT-16, 16, 8, palstart + ((animtime - i) & 15)); - buf = W_CacheLumpNumPwad(wadnum, lump, PU_CACHE); - size = W_LumpLengthPwad(wadnum, lump); - - // for strtok - buf2 = malloc(size+1); - if (!buf2) - I_Error("R_PatchSkins: No more free memory\n"); - M_Memcpy(buf2,buf,size); - buf2[size] = '\0'; - - skin = NULL; - noskincomplain = realname = hudname = false; - - /* - Parse. Has more phases than the parser in R_AddSkins because it needs to have the patching name first (no default skin name is acceptible for patching, unlike skin creation) - */ - - stoken = strtok(buf2, "\r\n= "); - while (stoken) + switch (cl_mode) { - if ((stoken[0] == '/' && stoken[1] == '/') - || (stoken[0] == '#'))// skip comments - { - stoken = strtok(NULL, "\r\n"); // skip end of line - goto next_token; // find the real next token - } - - value = strtok(NULL, "\r\n= "); - - if (!value) - I_Error("R_PatchSkins: syntax error in P_SKIN lump# %d(%s) in WAD %s\n", lump, W_CheckNameForNumPwad(wadnum,lump), wadfiles[wadnum]->filename); - - if (!skin) // Get the name! - { - if (!stricmp(stoken, "name")) + case CL_DOWNLOADSAVEGAME: + if (lastfilenum != -1) { - strlwr(value); - skinnum = R_SkinAvailable(value); - if (skinnum != -1) - skin = &skins[skinnum]; - else - { - CONS_Debug(DBG_SETUP, "R_PatchSkins: unknown skin name in P_SKIN lump# %d(%s) in WAD %s\n", lump, W_CheckNameForNumPwad(wadnum,lump), wadfiles[wadnum]->filename); - noskincomplain = true; - } - } - } - else // Get the properties! - { - // Some of these can't go in R_ProcessPatchableFields because they have side effects for future lines. - if (!stricmp(stoken, "realname")) - { // Display name (eg. "Knuckles") - realname = true; - STRBUFCPY(skin->realname, value); - SYMBOLCONVERT(skin->realname) - if (!hudname) - HUDNAMEWRITE(skin->realname); - } - else if (!stricmp(stoken, "hudname")) - { // Life icon name (eg. "K.T.E") - hudname = true; - HUDNAMEWRITE(value); - SYMBOLCONVERT(skin->hudname) - if (!realname) - STRBUFCPY(skin->realname, skin->hudname); - } - else if (!R_ProcessPatchableFields(skin, stoken, value)) - CONS_Debug(DBG_SETUP, "R_PatchSkins: Unknown keyword '%s' in P_SKIN lump #%d (WAD %s)\n", stoken, lump, wadfiles[wadnum]->filename); - } + UINT32 currentsize = fileneeded[lastfilenum].currentsize; + UINT32 totalsize = fileneeded[lastfilenum].totalsize; + INT32 dldlength; - if (!skin) + cltext = M_GetText("Downloading game state..."); + Net_GetNetStat(); + + dldlength = (INT32)((currentsize/(double)totalsize) * 256); + if (dldlength > 256) + dldlength = 256; + V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-16, 256, 8, 111); + V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-16, dldlength, 8, 96); + + V_DrawString(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-16, V_20TRANS|V_MONOSPACE, + va(" %4uK/%4uK",currentsize>>10,totalsize>>10)); + + V_DrawRightAlignedString(BASEVIDWIDTH/2+128, BASEVIDHEIGHT-16, V_20TRANS|V_MONOSPACE, + va("%3.1fK/s ", ((double)getbps)/1024)); + } + else + cltext = M_GetText("Waiting to download game state..."); + break; + case CL_ASKJOIN: + case CL_WAITJOINRESPONSE: + cltext = M_GetText("Requesting to join..."); + break; + default: + cltext = M_GetText("Connecting to server..."); break; - -next_token: - stoken = strtok(NULL, "\r\n= "); } - free(buf2); - - if (!skin) // Didn't include a name parameter? What a waste. + V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-16-24, V_YELLOWMAP, cltext); + } + else + { + if (lastfilenum != -1) { - if (!noskincomplain) - CONS_Debug(DBG_SETUP, "R_PatchSkins: no skin name given in P_SKIN lump #%d (WAD %s)\n", lump, wadfiles[wadnum]->filename); + INT32 dldlength; + static char tempname[28]; + fileneeded_t *file = &fileneeded[lastfilenum]; + char *filename = file->filename; + + Snake_Draw(); + + Net_GetNetStat(); + dldlength = (INT32)((file->currentsize/(double)file->totalsize) * 256); + if (dldlength > 256) + dldlength = 256; + V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-16, 256, 8, 111); + V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-16, dldlength, 8, 96); + + memset(tempname, 0, sizeof(tempname)); + // offset filename to just the name only part + filename += strlen(filename) - nameonlylength(filename); + + if (strlen(filename) > sizeof(tempname)-1) // too long to display fully + { + size_t endhalfpos = strlen(filename)-10; + // display as first 14 chars + ... + last 10 chars + // which should add up to 27 if our math(s) is correct + snprintf(tempname, sizeof(tempname), "%.14s...%.10s", filename, filename+endhalfpos); + } + else // we can copy the whole thing in safely + { + strncpy(tempname, filename, sizeof(tempname)-1); + } + + V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-16-24, V_YELLOWMAP, + va(M_GetText("Downloading \"%s\""), tempname)); + V_DrawString(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-16, V_20TRANS|V_MONOSPACE, + va(" %4uK/%4uK",fileneeded[lastfilenum].currentsize>>10,file->totalsize>>10)); + V_DrawRightAlignedString(BASEVIDWIDTH/2+128, BASEVIDHEIGHT-16, V_20TRANS|V_MONOSPACE, + va("%3.1fK/s ", ((double)getbps)/1024)); + } + else + V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-16-24, V_YELLOWMAP, + M_GetText("Waiting to download files...")); + } +} +#endif + +/** Sends a special packet to declare how many players in local + * Used only in arbitratrenetstart() + * Sends a PT_CLIENTJOIN packet to the server + * + * \return True if the packet was successfully sent + * \todo Improve the description... + * Because to be honest, I have no idea what arbitratrenetstart is... + * Is it even used...? + * + */ +static boolean CL_SendJoin(void) +{ + UINT8 localplayers = 1; + if (netgame) + CONS_Printf(M_GetText("Sending join request...\n")); + netbuffer->packettype = PT_CLIENTJOIN; + + if (splitscreen || botingame) + localplayers++; + netbuffer->u.clientcfg.localplayers = localplayers; + netbuffer->u.clientcfg._255 = 255; + netbuffer->u.clientcfg.packetversion = PACKETVERSION; + netbuffer->u.clientcfg.version = VERSION; + netbuffer->u.clientcfg.subversion = SUBVERSION; + strncpy(netbuffer->u.clientcfg.application, SRB2APPLICATION, + sizeof netbuffer->u.clientcfg.application); + + CleanupPlayerName(consoleplayer, cv_playername.zstring); + if (splitscreen) + CleanupPlayerName(1, cv_playername2.zstring);/* 1 is a HACK? oh no */ + + strncpy(netbuffer->u.clientcfg.names[0], cv_playername.zstring, MAXPLAYERNAME); + strncpy(netbuffer->u.clientcfg.names[1], cv_playername2.zstring, MAXPLAYERNAME); + + return HSendPacket(servernode, true, 0, sizeof (clientconfig_pak)); +} + +static INT32 FindRejoinerNum(SINT8 node) +{ + char strippednodeaddress[64]; + const char *nodeaddress; + char *port; + INT32 i; + + // Make sure there is no dead dress before proceeding to the stripping + if (!I_GetNodeAddress) + return -1; + nodeaddress = I_GetNodeAddress(node); + if (!nodeaddress) + return -1; + + // Strip the address of its port + strcpy(strippednodeaddress, nodeaddress); + port = strchr(strippednodeaddress, ':'); + if (port) + *port = '\0'; + + // Check if any player matches the stripped address + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i] && playeraddress[i][0] && playernode[i] == UINT8_MAX + && !strcmp(playeraddress[i], strippednodeaddress)) + return i; + } + + return -1; +} + +static void SV_SendServerInfo(INT32 node, tic_t servertime) +{ + UINT8 *p; + + netbuffer->packettype = PT_SERVERINFO; + netbuffer->u.serverinfo._255 = 255; + netbuffer->u.serverinfo.packetversion = PACKETVERSION; + netbuffer->u.serverinfo.version = VERSION; + netbuffer->u.serverinfo.subversion = SUBVERSION; + strncpy(netbuffer->u.serverinfo.application, SRB2APPLICATION, + sizeof netbuffer->u.serverinfo.application); + // return back the time value so client can compute their ping + netbuffer->u.serverinfo.time = (tic_t)LONG(servertime); + netbuffer->u.serverinfo.leveltime = (tic_t)LONG(leveltime); + + netbuffer->u.serverinfo.numberofplayer = (UINT8)D_NumPlayers(); + netbuffer->u.serverinfo.maxplayer = (UINT8)cv_maxplayers.value; + + if (!node || FindRejoinerNum(node) != -1) + netbuffer->u.serverinfo.refusereason = 0; + else if (!cv_allownewplayer.value) + netbuffer->u.serverinfo.refusereason = 1; + else if (D_NumPlayers() >= cv_maxplayers.value) + netbuffer->u.serverinfo.refusereason = 2; + else + netbuffer->u.serverinfo.refusereason = 0; + + strncpy(netbuffer->u.serverinfo.gametypename, Gametype_Names[gametype], + sizeof netbuffer->u.serverinfo.gametypename); + netbuffer->u.serverinfo.modifiedgame = (UINT8)modifiedgame; + netbuffer->u.serverinfo.cheatsenabled = CV_CheatsEnabled(); + netbuffer->u.serverinfo.isdedicated = (UINT8)dedicated; + strncpy(netbuffer->u.serverinfo.servername, cv_servername.string, + MAXSERVERNAME); + strncpy(netbuffer->u.serverinfo.mapname, G_BuildMapName(gamemap), 7); + + M_Memcpy(netbuffer->u.serverinfo.mapmd5, mapmd5, 16); + + memset(netbuffer->u.serverinfo.maptitle, 0, sizeof netbuffer->u.serverinfo.maptitle); + + if (mapheaderinfo[gamemap-1] && *mapheaderinfo[gamemap-1]->lvlttl) + { + char *read = mapheaderinfo[gamemap-1]->lvlttl, *writ = netbuffer->u.serverinfo.maptitle; + while (writ < (netbuffer->u.serverinfo.maptitle+32) && *read != '\0') + { + if (!(*read & 0x80)) + { + *writ = toupper(*read); + writ++; + } + read++; + } + *writ = '\0'; + //strncpy(netbuffer->u.serverinfo.maptitle, (char *)mapheaderinfo[gamemap-1]->lvlttl, 33); + } + else + strncpy(netbuffer->u.serverinfo.maptitle, "UNKNOWN", 32); + + if (mapheaderinfo[gamemap-1] && !(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE)) + netbuffer->u.serverinfo.iszone = 1; + else + netbuffer->u.serverinfo.iszone = 0; + + if (mapheaderinfo[gamemap-1]) + netbuffer->u.serverinfo.actnum = mapheaderinfo[gamemap-1]->actnum; + + p = PutFileNeeded(); + + HSendPacket(node, false, 0, p - ((UINT8 *)&netbuffer->u)); +} + +static void SV_SendPlayerInfo(INT32 node) +{ + UINT8 i; + netbuffer->packettype = PT_PLAYERINFO; + + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + { + netbuffer->u.playerinfo[i].num = 255; // This slot is empty. continue; } - // Patch sprites - R_LoadSkinSprites(wadnum, &lump, &lastlump, skin); - //ST_LoadFaceGraphics(skinnum); -- nah let's do this elsewhere + netbuffer->u.playerinfo[i].num = i; + strncpy(netbuffer->u.playerinfo[i].name, (const char *)&player_names[i], MAXPLAYERNAME+1); + netbuffer->u.playerinfo[i].name[MAXPLAYERNAME] = '\0'; - R_FlushTranslationColormapCache(); + //fetch IP address + //No, don't do that, you fuckface. + memset(netbuffer->u.playerinfo[i].address, 0, 4); - if (!skin->availability) // Safe to print... - CONS_Printf(M_GetText("Patched skin '%s'\n"), skin->name); + if (G_GametypeHasTeams()) + { + if (!players[i].ctfteam) + netbuffer->u.playerinfo[i].team = 255; + else + netbuffer->u.playerinfo[i].team = (UINT8)players[i].ctfteam; + } + else + { + if (players[i].spectator) + netbuffer->u.playerinfo[i].team = 255; + else + netbuffer->u.playerinfo[i].team = 0; + } + + netbuffer->u.playerinfo[i].score = LONG(players[i].score); + netbuffer->u.playerinfo[i].timeinserver = SHORT((UINT16)(players[i].jointime / TICRATE)); + netbuffer->u.playerinfo[i].skin = (UINT8)(players[i].skin +#ifdef DEVELOP // it's safe to do this only because PLAYERINFO isn't read by the game itself + % 3 +#endif + ); + + // Extra data + netbuffer->u.playerinfo[i].data = 0; //players[i].skincolor; + + if (players[i].pflags & PF_TAGIT) + netbuffer->u.playerinfo[i].data |= 0x20; + + if (players[i].gotflag) + netbuffer->u.playerinfo[i].data |= 0x40; + + if (players[i].powers[pw_super]) + netbuffer->u.playerinfo[i].data |= 0x80; } - return; + + HSendPacket(node, false, 0, sizeof(plrinfo) * MAXPLAYERS); } -#undef HUDNAMEWRITE -#undef SYMBOLCONVERT +/** Sends a PT_SERVERCFG packet + * + * \param node The destination + * \return True if the packet was successfully sent + * + */ +static boolean SV_SendServerConfig(INT32 node) +{ + boolean waspacketsent; + + netbuffer->packettype = PT_SERVERCFG; + + netbuffer->u.servercfg.version = VERSION; + netbuffer->u.servercfg.subversion = SUBVERSION; + + netbuffer->u.servercfg.serverplayer = (UINT8)serverplayer; + netbuffer->u.servercfg.totalslotnum = (UINT8)(doomcom->numslots); + netbuffer->u.servercfg.gametic = (tic_t)LONG(gametic); + netbuffer->u.servercfg.clientnode = (UINT8)node; + netbuffer->u.servercfg.gamestate = (UINT8)gamestate; + netbuffer->u.servercfg.gametype = (UINT8)gametype; + netbuffer->u.servercfg.modifiedgame = (UINT8)modifiedgame; + + memcpy(netbuffer->u.servercfg.server_context, server_context, 8); + + { + const size_t len = sizeof (serverconfig_pak); + +#ifdef DEBUGFILE + if (debugfile) + { + fprintf(debugfile, "ServerConfig Packet about to be sent, size of packet:%s to node:%d\n", + sizeu1(len), node); + } +#endif + + waspacketsent = HSendPacket(node, true, 0, len); + } + +#ifdef DEBUGFILE + if (debugfile) + { + if (waspacketsent) + { + fprintf(debugfile, "ServerConfig Packet was sent\n"); + } + else + { + fprintf(debugfile, "ServerConfig Packet could not be sent right now\n"); + } + } +#endif + + return waspacketsent; +} + +#ifndef NONET +#define SAVEGAMESIZE (768*1024) + +static boolean SV_ResendingSavegameToAnyone(void) +{ + INT32 i; + + for (i = 0; i < MAXNETNODES; i++) + if (resendingsavegame[i]) + return true; + return false; +} + +static void SV_SendSaveGame(INT32 node, boolean resending) +{ + size_t length, compressedlen; + UINT8 *savebuffer; + UINT8 *compressedsave; + UINT8 *buffertosend; + + // first save it in a malloced buffer + savebuffer = (UINT8 *)malloc(SAVEGAMESIZE); + if (!savebuffer) + { + CONS_Alert(CONS_ERROR, M_GetText("No more free memory for savegame\n")); + return; + } + + // Leave room for the uncompressed length. + save_p = savebuffer + sizeof(UINT32); + + P_SaveNetGame(resending); + + length = save_p - savebuffer; + if (length > SAVEGAMESIZE) + { + free(savebuffer); + save_p = NULL; + I_Error("Savegame buffer overrun"); + } + + // Allocate space for compressed save: one byte fewer than for the + // uncompressed data to ensure that the compression is worthwhile. + compressedsave = malloc(length - 1); + if (!compressedsave) + { + CONS_Alert(CONS_ERROR, M_GetText("No more free memory for savegame\n")); + return; + } + + // Attempt to compress it. + if((compressedlen = lzf_compress(savebuffer + sizeof(UINT32), length - sizeof(UINT32), compressedsave + sizeof(UINT32), length - sizeof(UINT32) - 1))) + { + // Compressing succeeded; send compressed data + + free(savebuffer); + + // State that we're compressed. + buffertosend = compressedsave; + WRITEUINT32(compressedsave, length - sizeof(UINT32)); + length = compressedlen + sizeof(UINT32); + } + else + { + // Compression failed to make it smaller; send original + + free(compressedsave); + + // State that we're not compressed + buffertosend = savebuffer; + WRITEUINT32(savebuffer, 0); + } + + AddRamToSendQueue(node, buffertosend, length, SF_RAM, 0); + save_p = NULL; + + // Remember when we started sending the savegame so we can handle timeouts + sendingsavegame[node] = true; + freezetimeout[node] = I_GetTime() + jointimeout + length / 1024; // 1 extra tic for each kilobyte +} + +#ifdef DUMPCONSISTENCY +#define TMPSAVENAME "badmath.sav" +static consvar_t cv_dumpconsistency = CVAR_INIT ("dumpconsistency", "Off", CV_SAVE|CV_NETVAR, CV_OnOff, NULL); + +static void SV_SavedGame(void) +{ + size_t length; + UINT8 *savebuffer; + char tmpsave[256]; + + if (!cv_dumpconsistency.value) + return; + + sprintf(tmpsave, "%s" PATHSEP TMPSAVENAME, srb2home); + + // first save it in a malloced buffer + save_p = savebuffer = (UINT8 *)malloc(SAVEGAMESIZE); + if (!save_p) + { + CONS_Alert(CONS_ERROR, M_GetText("No more free memory for savegame\n")); + return; + } + + P_SaveNetGame(false); + + length = save_p - savebuffer; + if (length > SAVEGAMESIZE) + { + free(savebuffer); + save_p = NULL; + I_Error("Savegame buffer overrun"); + } + + // then save it! + if (!FIL_WriteFile(tmpsave, savebuffer, length)) + CONS_Printf(M_GetText("Didn't save %s for netgame"), tmpsave); + + free(savebuffer); + save_p = NULL; +} + +#undef TMPSAVENAME +#endif +#define TMPSAVENAME "$$$.sav" + + +static void CL_LoadReceivedSavegame(boolean reloading) +{ + UINT8 *savebuffer = NULL; + size_t length, decompressedlen; + char tmpsave[256]; + + sprintf(tmpsave, "%s" PATHSEP TMPSAVENAME, srb2home); + + length = FIL_ReadFile(tmpsave, &savebuffer); + + CONS_Printf(M_GetText("Loading savegame length %s\n"), sizeu1(length)); + if (!length) + { + I_Error("Can't read savegame sent"); + return; + } + + save_p = savebuffer; + + // Decompress saved game if necessary. + decompressedlen = READUINT32(save_p); + if(decompressedlen > 0) + { + UINT8 *decompressedbuffer = Z_Malloc(decompressedlen, PU_STATIC, NULL); + lzf_decompress(save_p, length - sizeof(UINT32), decompressedbuffer, decompressedlen); + Z_Free(savebuffer); + save_p = savebuffer = decompressedbuffer; + } + + paused = false; + demoplayback = false; + titlemapinaction = TITLEMAP_OFF; + titledemo = false; + automapactive = false; + + // load a base level + if (P_LoadNetGame(reloading)) + { + const UINT8 actnum = mapheaderinfo[gamemap-1]->actnum; + CONS_Printf(M_GetText("Map is now \"%s"), G_BuildMapName(gamemap)); + if (strcmp(mapheaderinfo[gamemap-1]->lvlttl, "")) + { + CONS_Printf(": %s", mapheaderinfo[gamemap-1]->lvlttl); + if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE)) + CONS_Printf(M_GetText(" Zone")); + if (actnum > 0) + CONS_Printf(" %2d", actnum); + } + CONS_Printf("\"\n"); + } + else + { + CONS_Alert(CONS_ERROR, M_GetText("Can't load the level!\n")); + Z_Free(savebuffer); + save_p = NULL; + if (unlink(tmpsave) == -1) + CONS_Alert(CONS_ERROR, M_GetText("Can't delete %s\n"), tmpsave); + return; + } + + // done + Z_Free(savebuffer); + save_p = NULL; + if (unlink(tmpsave) == -1) + CONS_Alert(CONS_ERROR, M_GetText("Can't delete %s\n"), tmpsave); + consistancy[gametic%BACKUPTICS] = Consistancy(); + CON_ToggleOff(); + + // Tell the server we have received and reloaded the gamestate + // so they know they can resume the game + netbuffer->packettype = PT_RECEIVEDGAMESTATE; + HSendPacket(servernode, true, 0, 0); +} + +static void CL_ReloadReceivedSavegame(void) +{ + INT32 i; + + for (i = 0; i < MAXPLAYERS; i++) + { +#ifdef HAVE_BLUA + LUA_InvalidatePlayer(&players[i]); +#endif + sprintf(player_names[i], "Player %d", i + 1); + } + + CL_LoadReceivedSavegame(true); + + if (neededtic < gametic) + neededtic = gametic; + maketic = neededtic; + + ticcmd_oldangleturn[0] = players[consoleplayer].oldrelangleturn; + P_ForceLocalAngle(&players[consoleplayer], (angle_t)(players[consoleplayer].angleturn << 16)); + if (splitscreen) + { + ticcmd_oldangleturn[1] = players[secondarydisplayplayer].oldrelangleturn; + P_ForceLocalAngle(&players[secondarydisplayplayer], (angle_t)(players[secondarydisplayplayer].angleturn << 16)); + } + + camera.subsector = R_PointInSubsector(camera.x, camera.y); + camera2.subsector = R_PointInSubsector(camera2.x, camera2.y); + + cl_redownloadinggamestate = false; + + CONS_Printf(M_GetText("Game state reloaded\n")); +} +#endif + +#ifndef NONET +static void SendAskInfo(INT32 node) +{ + const tic_t asktime = I_GetTime(); + netbuffer->packettype = PT_ASKINFO; + netbuffer->u.askinfo.version = VERSION; + netbuffer->u.askinfo.time = (tic_t)LONG(asktime); + + // Even if this never arrives due to the host being firewalled, we've + // now allowed traffic from the host to us in, so once the MS relays + // our address to the host, it'll be able to speak to us. + HSendPacket(node, false, 0, sizeof (askinfo_pak)); +} + +serverelem_t serverlist[MAXSERVERLIST]; +UINT32 serverlistcount = 0; + +#define FORCECLOSE 0x8000 + +static void SL_ClearServerList(INT32 connectedserver) +{ + UINT32 i; + + for (i = 0; i < serverlistcount; i++) + if (connectedserver != serverlist[i].node) + { + Net_CloseConnection(serverlist[i].node|FORCECLOSE); + serverlist[i].node = 0; + } + serverlistcount = 0; +} + +static UINT32 SL_SearchServer(INT32 node) +{ + UINT32 i; + for (i = 0; i < serverlistcount; i++) + if (serverlist[i].node == node) + return i; + + return UINT32_MAX; +} + +static void SL_InsertServer(serverinfo_pak* info, SINT8 node) +{ + UINT32 i; + + // search if not already on it + i = SL_SearchServer(node); + if (i == UINT32_MAX) + { + // not found add it + if (serverlistcount >= MAXSERVERLIST) + return; // list full + + if (info->_255 != 255) + return;/* old packet format */ + + if (info->packetversion != PACKETVERSION) + return;/* old new packet format */ + + if (info->version != VERSION) + return; // Not same version. + + if (info->subversion != SUBVERSION) + return; // Close, but no cigar. + + if (strcmp(info->application, SRB2APPLICATION)) + return;/* that's a different mod */ + + i = serverlistcount++; + } + + serverlist[i].info = *info; + serverlist[i].node = node; + + // resort server list + M_SortServerList(); +} + +#if defined (MASTERSERVER) && defined (HAVE_THREADS) +struct Fetch_servers_ctx +{ + int room; + int id; +}; + +static void +Fetch_servers_thread (struct Fetch_servers_ctx *ctx) +{ + msg_server_t *server_list; + + server_list = GetShortServersList(ctx->room, ctx->id); + + if (server_list) + { + I_lock_mutex(&ms_QueryId_mutex); + { + if (ctx->id != ms_QueryId) + { + free(server_list); + server_list = NULL; + } + } + I_unlock_mutex(ms_QueryId_mutex); + + if (server_list) + { + I_lock_mutex(&m_menu_mutex); + { + if (m_waiting_mode == M_WAITING_SERVERS) + m_waiting_mode = M_NOT_WAITING; + } + I_unlock_mutex(m_menu_mutex); + + I_lock_mutex(&ms_ServerList_mutex); + { + ms_ServerList = server_list; + } + I_unlock_mutex(ms_ServerList_mutex); + } + } + + free(ctx); +} +#endif/*defined (MASTERSERVER) && defined (HAVE_THREADS)*/ + +void CL_QueryServerList (msg_server_t *server_list) +{ + INT32 i; + + for (i = 0; server_list[i].header.buffer[0]; i++) + { + // Make sure MS version matches our own, to + // thwart nefarious servers who lie to the MS. + + /* lol bruh, that version COMES from the servers */ + //if (strcmp(version, server_list[i].version) == 0) + { + INT32 node = I_NetMakeNodewPort(server_list[i].ip, server_list[i].port); + if (node == -1) + break; // no more node free + SendAskInfo(node); + // Force close the connection so that servers can't eat + // up nodes forever if we never get a reply back from them + // (usually when they've not forwarded their ports). + // + // Don't worry, we'll get in contact with the working + // servers again when they send SERVERINFO to us later! + // + // (Note: as a side effect this probably means every + // server in the list will probably be using the same node (e.g. node 1), + // not that it matters which nodes they use when + // the connections are closed afterwards anyway) + // -- Monster Iestyn 12/11/18 + Net_CloseConnection(node|FORCECLOSE); + } + } +} + +void CL_UpdateServerList(boolean internetsearch, INT32 room) +{ + (void)internetsearch; + (void)room; + + SL_ClearServerList(0); + + if (!netgame && I_NetOpenSocket) + { + if (I_NetOpenSocket()) + { + netgame = true; + multiplayer = true; + } + } + + // search for local servers + if (netgame) + SendAskInfo(BROADCASTADDR); + +#ifdef MASTERSERVER + if (internetsearch) + { +#ifdef HAVE_THREADS + struct Fetch_servers_ctx *ctx; + + ctx = malloc(sizeof *ctx); + + /* This called from M_Refresh so I don't use a mutex */ + m_waiting_mode = M_WAITING_SERVERS; + + I_lock_mutex(&ms_QueryId_mutex); + { + ctx->id = ms_QueryId; + } + I_unlock_mutex(ms_QueryId_mutex); + + ctx->room = room; + + I_spawn_thread("fetch-servers", (I_thread_fn)Fetch_servers_thread, ctx); +#else + msg_server_t *server_list; + + server_list = GetShortServersList(room, 0); + + if (server_list) + { + CL_QueryServerList(server_list); + free(server_list); + } +#endif + } +#endif/*MASTERSERVER*/ +} + +#endif // ifndef NONET + +/** Called by CL_ServerConnectionTicker + * + * \param asksent The last time we asked the server to join. We re-ask every second in case our request got lost in transmit. + * \return False if the connection was aborted + * \sa CL_ServerConnectionTicker + * \sa CL_ConnectToServer + * + */ +static boolean CL_ServerConnectionSearchTicker(tic_t *asksent) +{ +#ifndef NONET + INT32 i; + + // serverlist is updated by GetPacket function + if (serverlistcount > 0) + { + // this can be a responce to our broadcast request + if (servernode == -1 || servernode >= MAXNETNODES) + { + i = 0; + servernode = serverlist[i].node; + CONS_Printf(M_GetText("Found, ")); + } + else + { + i = SL_SearchServer(servernode); + if (i < 0) + return true; + } + + // Quit here rather than downloading files and being refused later. + if (serverlist[i].info.refusereason) + { + D_QuitNetGame(); + CL_Reset(); + D_StartTitle(); + if (serverlist[i].info.refusereason == 1) + M_StartMessage(M_GetText("The server is not accepting\njoins for the moment.\n\nPress ESC\n"), NULL, MM_NOTHING); + else if (serverlist[i].info.refusereason == 2) + M_StartMessage(va(M_GetText("Maximum players reached: %d\n\nPress ESC\n"), serverlist[i].info.maxplayer), NULL, MM_NOTHING); + else + M_StartMessage(M_GetText("You can't join.\nI don't know why,\nbut you can't join.\n\nPress ESC\n"), NULL, MM_NOTHING); + return false; + } + + if (client) + { + D_ParseFileneeded(serverlist[i].info.fileneedednum, + serverlist[i].info.fileneeded); + CONS_Printf(M_GetText("Checking files...\n")); + i = CL_CheckFiles(); + if (i == 3) // too many files + { + D_QuitNetGame(); + CL_Reset(); + D_StartTitle(); + M_StartMessage(M_GetText( + "You have too many WAD files loaded\n" + "to add ones the server is using.\n" + "Please restart SRB2 before connecting.\n\n" + "Press ESC\n" + ), NULL, MM_NOTHING); + return false; + } + else if (i == 2) // cannot join for some reason + { + D_QuitNetGame(); + CL_Reset(); + D_StartTitle(); + M_StartMessage(M_GetText( + "You have the wrong addons loaded.\n\n" + "To play on this server, restart\n" + "the game and don't load any addons.\n" + "SRB2 will automatically add\n" + "everything you need when you join.\n\n" + "Press ESC\n" + ), NULL, MM_NOTHING); + return false; + } + else if (i == 1) + cl_mode = CL_ASKJOIN; + else + { + // must download something + // can we, though? + if (!CL_CheckDownloadable()) // nope! + { + D_QuitNetGame(); + CL_Reset(); + D_StartTitle(); + M_StartMessage(M_GetText( + "You cannot connect to this server\n" + "because you cannot download the files\n" + "that you are missing from the server.\n\n" + "See the console or log file for\n" + "more details.\n\n" + "Press ESC\n" + ), NULL, MM_NOTHING); + return false; + } + // no problem if can't send packet, we will retry later + if (CL_SendFileRequest()) + { + cl_mode = CL_DOWNLOADFILES; +#ifndef NONET + Snake_Initialise(); +#endif + } + } + } + else + cl_mode = CL_ASKJOIN; // files need not be checked for the server. + + return true; + } + + // Ask the info to the server (askinfo packet) + if (*asksent + NEWTICRATE < I_GetTime()) + { + SendAskInfo(servernode); + *asksent = I_GetTime(); + } +#else + (void)asksent; + // No netgames, so we skip this state. + cl_mode = CL_ASKJOIN; +#endif // ifndef NONET/else + + return true; +} + +/** Called by CL_ConnectToServer + * + * \param tmpsave The name of the gamestate file??? + * \param oldtic Used for knowing when to poll events and redraw + * \param asksent ??? + * \return False if the connection was aborted + * \sa CL_ServerConnectionSearchTicker + * \sa CL_ConnectToServer + * + */ +static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic_t *asksent) +{ + boolean waitmore; + INT32 i; + +#ifdef NONET + (void)tmpsave; +#endif + + switch (cl_mode) + { + case CL_SEARCHING: + if (!CL_ServerConnectionSearchTicker(asksent)) + return false; + break; + + case CL_DOWNLOADFILES: + waitmore = false; + for (i = 0; i < fileneedednum; i++) + if (fileneeded[i].status == FS_DOWNLOADING + || fileneeded[i].status == FS_REQUESTED) + { + waitmore = true; + break; + } + if (waitmore) + break; // exit the case + +#ifndef NONET + if (snake) + { + free(snake); + snake = NULL; + } +#endif + + cl_mode = CL_ASKJOIN; // don't break case continue to cljoin request now + /* FALLTHRU */ + + case CL_ASKJOIN: + CL_LoadServerFiles(); +#ifndef NONET + // prepare structures to save the file + // WARNING: this can be useless in case of server not in GS_LEVEL + // but since the network layer doesn't provide ordered packets... + CL_PrepareDownloadSaveGame(tmpsave); +#endif + if (CL_SendJoin()) + cl_mode = CL_WAITJOINRESPONSE; + break; + +#ifndef NONET + case CL_DOWNLOADSAVEGAME: + // At this state, the first (and only) needed file is the gamestate + if (fileneeded[0].status == FS_FOUND) + { + // Gamestate is now handled within CL_LoadReceivedSavegame() + CL_LoadReceivedSavegame(false); + cl_mode = CL_CONNECTED; + } // don't break case continue to CL_CONNECTED + else + break; +#endif + + case CL_WAITJOINRESPONSE: + case CL_CONNECTED: + default: + break; + + // Connection closed by cancel, timeout or refusal. + case CL_ABORTED: + cl_mode = CL_SEARCHING; + return false; + + } + + GetPackets(); + Net_AckTicker(); + + // Call it only once by tic + if (*oldtic != I_GetTime()) + { + I_OsPolling(); + for (; eventtail != eventhead; eventtail = (eventtail+1) & (MAXEVENTS-1)) + G_MapEventsToControls(&events[eventtail]); + + if (gamekeydown[KEY_ESCAPE] || gamekeydown[KEY_JOY1+1]) + { + CONS_Printf(M_GetText("Network game synchronization aborted.\n")); +// M_StartMessage(M_GetText("Network game synchronization aborted.\n\nPress ESC\n"), NULL, MM_NOTHING); + +#ifndef NONET + if (snake) + { + free(snake); + snake = NULL; + } +#endif + + D_QuitNetGame(); + CL_Reset(); + D_StartTitle(); + memset(gamekeydown, 0, NUMKEYS); + return false; + } +#ifndef NONET + else if (cl_mode == CL_DOWNLOADFILES && snake) + Snake_Handle(); +#endif + + if (client && (cl_mode == CL_DOWNLOADFILES || cl_mode == CL_DOWNLOADSAVEGAME)) + FileReceiveTicker(); + + // why are these here? this is for servers, we're a client + //if (key == 's' && server) + // doomcom->numnodes = (INT16)pnumnodes; + //FileSendTicker(); + *oldtic = I_GetTime(); + +#ifndef NONET + if (client && cl_mode != CL_CONNECTED && cl_mode != CL_ABORTED) + { + if (cl_mode != CL_DOWNLOADFILES && cl_mode != CL_DOWNLOADSAVEGAME) + { + F_MenuPresTicker(true); // title sky + F_TitleScreenTicker(true); + F_TitleScreenDrawer(); + } + CL_DrawConnectionStatus(); + I_UpdateNoVsync(); // page flip or blit buffer + if (moviemode) + M_SaveFrame(); + S_UpdateSounds(); + S_UpdateClosedCaptions(); + } +#else + CON_Drawer(); + I_UpdateNoVsync(); +#endif + } + else + I_Sleep(); + + return true; +} + +/** Use adaptive send using net_bandwidth and stat.sendbytes + * + * \todo Better description... + * + */ +static void CL_ConnectToServer(void) +{ + INT32 pnumnodes, nodewaited = doomcom->numnodes, i; + tic_t oldtic; +#ifndef NONET + tic_t asksent; + char tmpsave[256]; + + sprintf(tmpsave, "%s" PATHSEP TMPSAVENAME, srb2home); + + lastfilenum = -1; +#endif + + cl_mode = CL_SEARCHING; + +#ifndef NONET + // Don't get a corrupt savegame error because tmpsave already exists + if (FIL_FileExists(tmpsave) && unlink(tmpsave) == -1) + I_Error("Can't delete %s\n", tmpsave); +#endif + + if (netgame) + { + if (servernode < 0 || servernode >= MAXNETNODES) + CONS_Printf(M_GetText("Searching for a server...\n")); + else + CONS_Printf(M_GetText("Contacting the server...\n")); + } + + if (gamestate == GS_INTERMISSION) + Y_EndIntermission(); // clean up intermission graphics etc + + DEBFILE(va("waiting %d nodes\n", doomcom->numnodes)); + G_SetGamestate(GS_WAITINGPLAYERS); + wipegamestate = GS_WAITINGPLAYERS; + + ClearAdminPlayers(); + pnumnodes = 1; + oldtic = I_GetTime() - 1; +#ifndef NONET + asksent = (tic_t) - TICRATE; + + i = SL_SearchServer(servernode); + + if (i != -1) + { + char *gametypestr = serverlist[i].info.gametypename; + CONS_Printf(M_GetText("Connecting to: %s\n"), serverlist[i].info.servername); + gametypestr[sizeof serverlist[i].info.gametypename - 1] = '\0'; + CONS_Printf(M_GetText("Gametype: %s\n"), gametypestr); + CONS_Printf(M_GetText("Version: %d.%d.%u\n"), serverlist[i].info.version/100, + serverlist[i].info.version%100, serverlist[i].info.subversion); + } + SL_ClearServerList(servernode); +#endif + + do + { + // If the connection was aborted for some reason, leave +#ifndef NONET + if (!CL_ServerConnectionTicker(tmpsave, &oldtic, &asksent)) +#else + if (!CL_ServerConnectionTicker((char*)NULL, &oldtic, (tic_t *)NULL)) +#endif + return; + + if (server) + { + pnumnodes = 0; + for (i = 0; i < MAXNETNODES; i++) + if (nodeingame[i]) + pnumnodes++; + } + } + while (!(cl_mode == CL_CONNECTED && (client || (server && nodewaited <= pnumnodes)))); + + DEBFILE(va("Synchronisation Finished\n")); + + displayplayer = consoleplayer; +} + +#ifndef NONET +typedef struct banreason_s +{ + char *reason; + struct banreason_s *prev; //-1 + struct banreason_s *next; //+1 +} banreason_t; + +static banreason_t *reasontail = NULL; //last entry, use prev +static banreason_t *reasonhead = NULL; //1st entry, use next + +static void Command_ShowBan(void) //Print out ban list +{ + size_t i; + const char *address, *mask; + banreason_t *reasonlist = reasonhead; + + if (I_GetBanAddress) + CONS_Printf(M_GetText("Ban List:\n")); + else + return; + + for (i = 0;(address = I_GetBanAddress(i)) != NULL;i++) + { + if (!I_GetBanMask || (mask = I_GetBanMask(i)) == NULL) + CONS_Printf("%s: %s ", sizeu1(i+1), address); + else + CONS_Printf("%s: %s/%s ", sizeu1(i+1), address, mask); + + if (reasonlist && reasonlist->reason) + CONS_Printf("(%s)\n", reasonlist->reason); + else + CONS_Printf("\n"); + + if (reasonlist) reasonlist = reasonlist->next; + } + + if (i == 0 && !address) + CONS_Printf(M_GetText("(empty)\n")); +} + +void D_SaveBan(void) +{ + FILE *f; + size_t i; + banreason_t *reasonlist = reasonhead; + const char *address, *mask; + + if (!reasonhead) + return; + + f = fopen(va("%s"PATHSEP"%s", srb2home, "ban.txt"), "w"); + + if (!f) + { + CONS_Alert(CONS_WARNING, M_GetText("Could not save ban list into ban.txt\n")); + return; + } + + for (i = 0;(address = I_GetBanAddress(i)) != NULL;i++) + { + if (!I_GetBanMask || (mask = I_GetBanMask(i)) == NULL) + fprintf(f, "%s 0", address); + else + fprintf(f, "%s %s", address, mask); + + if (reasonlist && reasonlist->reason) + fprintf(f, " %s\n", reasonlist->reason); + else + fprintf(f, " %s\n", "NA"); + + if (reasonlist) reasonlist = reasonlist->next; + } + + fclose(f); +} + +static void Ban_Add(const char *reason) +{ + banreason_t *reasonlist = malloc(sizeof(*reasonlist)); + + if (!reasonlist) + return; + if (!reason) + reason = "NA"; + + reasonlist->next = NULL; + reasonlist->reason = Z_StrDup(reason); + if ((reasonlist->prev = reasontail) == NULL) + reasonhead = reasonlist; + else + reasontail->next = reasonlist; + reasontail = reasonlist; +} + +static void Command_ClearBans(void) +{ + banreason_t *temp; + + if (!I_ClearBans) + return; + + I_ClearBans(); + D_SaveBan(); + reasontail = NULL; + while (reasonhead) + { + temp = reasonhead->next; + Z_Free(reasonhead->reason); + free(reasonhead); + reasonhead = temp; + } +} + +static void Ban_Load_File(boolean warning) +{ + FILE *f; + size_t i; + const char *address, *mask; + char buffer[MAX_WADPATH]; + + f = fopen(va("%s"PATHSEP"%s", srb2home, "ban.txt"), "r"); + + if (!f) + { + if (warning) + CONS_Alert(CONS_WARNING, M_GetText("Could not open ban.txt for ban list\n")); + return; + } + + if (I_ClearBans) + Command_ClearBans(); + else + { + fclose(f); + return; + } + + for (i=0; fgets(buffer, (int)sizeof(buffer), f); i++) + { + address = strtok(buffer, " \t\r\n"); + mask = strtok(NULL, " \t\r\n"); + + I_SetBanAddress(address, mask); + + Ban_Add(strtok(NULL, "\r\n")); + } + + fclose(f); +} + +static void Command_ReloadBan(void) //recheck ban.txt +{ + Ban_Load_File(true); +} + +static void Command_connect(void) +{ + if (COM_Argc() < 2 || *COM_Argv(1) == 0) + { + CONS_Printf(M_GetText( + "Connect (port): connect to a server\n" + "Connect ANY: connect to the first lan server found\n" + //"Connect SELF: connect to your own server.\n" + )); + return; + } + + if (Playing() || titledemo) + { + CONS_Printf(M_GetText("You cannot connect while in a game. End this game first.\n")); + return; + } + + // modified game check: no longer handled + // we don't request a restart unless the filelist differs + + server = false; +/* + if (!stricmp(COM_Argv(1), "self")) + { + servernode = 0; + server = true; + /// \bug should be but... + //SV_SpawnServer(); + } + else +*/ + { + // used in menu to connect to a server in the list + if (netgame && !stricmp(COM_Argv(1), "node")) + { + servernode = (SINT8)atoi(COM_Argv(2)); + } + else if (netgame) + { + CONS_Printf(M_GetText("You cannot connect while in a game. End this game first.\n")); + return; + } + else if (I_NetOpenSocket) + { + I_NetOpenSocket(); + netgame = true; + multiplayer = true; + + if (!stricmp(COM_Argv(1), "any")) + servernode = BROADCASTADDR; + else if (I_NetMakeNodewPort) + { + if (COM_Argc() >= 3) // address AND port + servernode = I_NetMakeNodewPort(COM_Argv(1), COM_Argv(2)); + else // address only, or address:port + servernode = I_NetMakeNode(COM_Argv(1)); + } + else + { + CONS_Alert(CONS_ERROR, M_GetText("There is no server identification with this network driver\n")); + D_CloseConnection(); + return; + } + } + else + CONS_Alert(CONS_ERROR, M_GetText("There is no network driver\n")); + } + + splitscreen = false; + SplitScreen_OnChange(); + botingame = false; + botskin = 0; + CL_ConnectToServer(); +} +#endif + +static void ResetNode(INT32 node); + +// +// CL_ClearPlayer +// +// Clears the player data so that a future client can use this slot +// +void CL_ClearPlayer(INT32 playernum) +{ + if (players[playernum].mo) + P_RemoveMobj(players[playernum].mo); + memset(&players[playernum], 0, sizeof (player_t)); + memset(playeraddress[playernum], 0, sizeof(*playeraddress)); +} + +// +// CL_RemovePlayer +// +// Removes a player from the current game +// +static void CL_RemovePlayer(INT32 playernum, kickreason_t reason) +{ + // Sanity check: exceptional cases (i.e. c-fails) can cause multiple + // kick commands to be issued for the same player. + if (!playeringame[playernum]) + return; + + if (server && !demoplayback && playernode[playernum] != UINT8_MAX) + { + INT32 node = playernode[playernum]; + playerpernode[node]--; + if (playerpernode[node] <= 0) + { + nodeingame[node] = false; + Net_CloseConnection(node); + ResetNode(node); + } + } + + if (gametyperules & GTR_TEAMFLAGS) + P_PlayerFlagBurst(&players[playernum], false); // Don't take the flag with you! + + // If in a special stage, redistribute the player's spheres across + // the remaining players. + if (G_IsSpecialStage(gamemap)) + { + INT32 i, count, sincrement, spheres, rincrement, rings; + + for (i = 0, count = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i]) + count++; + } + + count--; + sincrement = spheres = players[playernum].spheres; + rincrement = rings = players[playernum].rings; + + if (count) + { + sincrement /= count; + rincrement /= count; + } + + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i] && i != playernum) + { + if (spheres < 2*sincrement) + { + P_GivePlayerSpheres(&players[i], spheres); + spheres = 0; + } + else + { + P_GivePlayerSpheres(&players[i], sincrement); + spheres -= sincrement; + } + + if (rings < 2*rincrement) + { + P_GivePlayerRings(&players[i], rings); + rings = 0; + } + else + { + P_GivePlayerRings(&players[i], rincrement); + rings -= rincrement; + } + } + } + } + + LUAh_PlayerQuit(&players[playernum], reason); // Lua hook for player quitting + + // don't look through someone's view who isn't there + if (playernum == displayplayer) + { + // Call ViewpointSwitch hooks here. + // The viewpoint was forcibly changed. + LUAh_ViewpointSwitch(&players[consoleplayer], &players[consoleplayer], true); + displayplayer = consoleplayer; + } + + // Reset player data + CL_ClearPlayer(playernum); + + // remove avatar of player + playeringame[playernum] = false; + playernode[playernum] = UINT8_MAX; + while (!playeringame[doomcom->numslots-1] && doomcom->numslots > 1) + doomcom->numslots--; + + // Reset the name + sprintf(player_names[playernum], "Player %d", playernum+1); + + player_name_changes[playernum] = 0; + + if (IsPlayerAdmin(playernum)) + { + RemoveAdminPlayer(playernum); // don't stay admin after you're gone + } + + LUA_InvalidatePlayer(&players[playernum]); + + if (G_TagGametype()) //Check if you still have a game. Location flexible. =P + P_CheckSurvivors(); + else if (gametyperules & GTR_RACE) + P_CheckRacers(); +} + +void CL_Reset(void) +{ + if (metalrecording) + G_StopMetalRecording(false); + if (metalplayback) + G_StopMetalDemo(); + if (demorecording) + G_CheckDemoStatus(); + + // reset client/server code + DEBFILE(va("\n-=-=-=-=-=-=-= Client reset =-=-=-=-=-=-=-\n\n")); + + if (servernode > 0 && servernode < MAXNETNODES) + { + nodeingame[(UINT8)servernode] = false; + Net_CloseConnection(servernode); + } + D_CloseConnection(); // netgame = false + multiplayer = false; + servernode = 0; + server = true; + doomcom->numnodes = 1; + doomcom->numslots = 1; + SV_StopServer(); + SV_ResetServer(); + CV_RevertNetVars(); + + // make sure we don't leave any fileneeded gunk over from a failed join + fileneedednum = 0; + memset(fileneeded, 0, sizeof(fileneeded)); + + // D_StartTitle should get done now, but the calling function will handle it +} + +#ifndef NONET +static void Command_GetPlayerNum(void) +{ + INT32 i; + + for (i = 0; i < MAXPLAYERS; i++) + if (playeringame[i]) + { + if (serverplayer == i) + CONS_Printf(M_GetText("num:%2d node:%2d %s\n"), i, playernode[i], player_names[i]); + else + CONS_Printf(M_GetText("\x82num:%2d node:%2d %s\n"), i, playernode[i], player_names[i]); + } +} + +SINT8 nametonum(const char *name) +{ + INT32 playernum, i; + + if (!strcmp(name, "0")) + return 0; + + playernum = (SINT8)atoi(name); + + if (playernum < 0 || playernum >= MAXPLAYERS) + return -1; + + if (playernum) + { + if (playeringame[playernum]) + return (SINT8)playernum; + else + return -1; + } + + for (i = 0; i < MAXPLAYERS; i++) + if (playeringame[i] && !stricmp(player_names[i], name)) + return (SINT8)i; + + CONS_Printf(M_GetText("There is no player named \"%s\"\n"), name); + + return -1; +} + +/** Lists all players and their player numbers. + * + * \sa Command_GetPlayerNum + */ +static void Command_Nodes(void) +{ + INT32 i; + size_t maxlen = 0; + const char *address; + + for (i = 0; i < MAXPLAYERS; i++) + { + const size_t plen = strlen(player_names[i]); + if (playeringame[i] && plen > maxlen) + maxlen = plen; + } + + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i]) + { + CONS_Printf("%.2u: %*s", i, (int)maxlen, player_names[i]); + + if (playernode[i] != UINT8_MAX) + { + CONS_Printf(" - node %.2d", playernode[i]); + if (I_GetNodeAddress && (address = I_GetNodeAddress(playernode[i])) != NULL) + CONS_Printf(" - %s", address); + } + + if (IsPlayerAdmin(i)) + CONS_Printf(M_GetText(" (verified admin)")); + + if (players[i].spectator) + CONS_Printf(M_GetText(" (spectator)")); + + CONS_Printf("\n"); + } + } +} + +static void Command_Ban(void) +{ + if (COM_Argc() < 2) + { + CONS_Printf(M_GetText("Ban : ban and kick a player\n")); + return; + } + + if (!netgame) // Don't kick Tails in splitscreen! + { + CONS_Printf(M_GetText("This only works in a netgame.\n")); + return; + } + + if (server || IsPlayerAdmin(consoleplayer)) + { + UINT8 buf[3 + MAX_REASONLENGTH]; + UINT8 *p = buf; + const SINT8 pn = nametonum(COM_Argv(1)); + const INT32 node = playernode[(INT32)pn]; + + if (pn == -1 || pn == 0) + return; + + WRITEUINT8(p, pn); + + if (server && I_Ban && !I_Ban(node)) // only the server is allowed to do this right now + { + CONS_Alert(CONS_WARNING, M_GetText("Too many bans! Geez, that's a lot of people you're excluding...\n")); + WRITEUINT8(p, KICK_MSG_GO_AWAY); + SendNetXCmd(XD_KICK, &buf, 2); + } + else + { + if (server) // only the server is allowed to do this right now + { + Ban_Add(COM_Argv(2)); + D_SaveBan(); // save the ban list + } + + if (COM_Argc() == 2) + { + WRITEUINT8(p, KICK_MSG_BANNED); + SendNetXCmd(XD_KICK, &buf, 2); + } + else + { + size_t i, j = COM_Argc(); + char message[MAX_REASONLENGTH]; + + //Steal from the motd code so you don't have to put the reason in quotes. + strlcpy(message, COM_Argv(2), sizeof message); + for (i = 3; i < j; i++) + { + strlcat(message, " ", sizeof message); + strlcat(message, COM_Argv(i), sizeof message); + } + + WRITEUINT8(p, KICK_MSG_CUSTOM_BAN); + WRITESTRINGN(p, message, MAX_REASONLENGTH); + SendNetXCmd(XD_KICK, &buf, p - buf); + } + } + } + else + CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n")); + +} + +static void Command_BanIP(void) +{ + if (COM_Argc() < 2) + { + CONS_Printf(M_GetText("banip : ban an ip address\n")); + return; + } + + if (server) // Only the server can use this, otherwise does nothing. + { + const char *address = (COM_Argv(1)); + const char *reason; + + if (COM_Argc() == 2) + reason = NULL; + else + reason = COM_Argv(2); + + + if (I_SetBanAddress && I_SetBanAddress(address, NULL)) + { + if (reason) + CONS_Printf("Banned IP address %s for: %s\n", address, reason); + else + CONS_Printf("Banned IP address %s\n", address); + + Ban_Add(reason); + D_SaveBan(); + } + else + { + return; + } + } +} + +static void Command_Kick(void) +{ + if (COM_Argc() < 2) + { + CONS_Printf(M_GetText("kick : kick a player\n")); + return; + } + + //if (!netgame) // Don't kick Tails in splitscreen! + //{ + // CONS_Printf(M_GetText("This only works in a netgame.\n")); + // return; + //} + + if (server || IsPlayerAdmin(consoleplayer)) + { + UINT8 buf[3 + MAX_REASONLENGTH]; + UINT8 *p = buf; + const SINT8 pn = nametonum(COM_Argv(1)); + + if (splitscreen && (pn == 0 || pn == 1)) + { + CONS_Printf(M_GetText("Splitscreen players cannot be kicked.\n")); + return; + } + if (pn == -1 || pn == 0) + return; + + // Special case if we are trying to kick a player who is downloading the game state: + // trigger a timeout instead of kicking them, because a kick would only + // take effect after they have finished downloading + if (server && playernode[pn] != UINT8_MAX && sendingsavegame[playernode[pn]]) + { + Net_ConnectionTimeout(playernode[pn]); + return; + } + + WRITESINT8(p, pn); + + if (COM_Argc() == 2) + { + WRITEUINT8(p, KICK_MSG_GO_AWAY); + SendNetXCmd(XD_KICK, &buf, 2); + } + else + { + size_t i, j = COM_Argc(); + char message[MAX_REASONLENGTH]; + + //Steal from the motd code so you don't have to put the reason in quotes. + strlcpy(message, COM_Argv(2), sizeof message); + for (i = 3; i < j; i++) + { + strlcat(message, " ", sizeof message); + strlcat(message, COM_Argv(i), sizeof message); + } + + WRITEUINT8(p, KICK_MSG_CUSTOM_KICK); + WRITESTRINGN(p, message, MAX_REASONLENGTH); + SendNetXCmd(XD_KICK, &buf, p - buf); + } + } + else + CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n")); +} +#endif + +static void Got_KickCmd(UINT8 **p, INT32 playernum) +{ + INT32 pnum, msg; + char buf[3 + MAX_REASONLENGTH]; + char *reason = buf; + kickreason_t kickreason = KR_KICK; + boolean keepbody; + + pnum = READUINT8(*p); + msg = READUINT8(*p); + keepbody = (msg & KICK_MSG_KEEP_BODY) != 0; + msg &= ~KICK_MSG_KEEP_BODY; + + if (pnum == serverplayer && IsPlayerAdmin(playernum)) + { + CONS_Printf(M_GetText("Server is being shut down remotely. Goodbye!\n")); + + if (server) + COM_BufAddText("quit\n"); + + return; + } + + // Is playernum authorized to make this kick? + if (playernum != serverplayer && !IsPlayerAdmin(playernum) + && !(playernode[playernum] != UINT8_MAX && playerpernode[playernode[playernum]] == 2 + && nodetoplayer2[playernode[playernum]] == pnum)) + { + // We received a kick command from someone who isn't the + // server or admin, and who isn't in splitscreen removing + // player 2. Thus, it must be someone with a modified + // binary, trying to kick someone but without having + // authorization. + + // We deal with this by changing the kick reason to + // "consistency failure" and kicking the offending user + // instead. + + // Note: Splitscreen in netgames is broken because of + // this. Only the server has any idea of which players + // are using splitscreen on the same computer, so + // clients cannot always determine if a kick is + // legitimate. + + CONS_Alert(CONS_WARNING, M_GetText("Illegal kick command received from %s for player %d\n"), player_names[playernum], pnum); + + // In debug, print a longer message with more details. + // TODO Callum: Should we translate this? +/* + CONS_Debug(DBG_NETPLAY, + "So, you must be asking, why is this an illegal kick?\n" + "Well, let's take a look at the facts, shall we?\n" + "\n" + "playernum (this is the guy who did it), he's %d.\n" + "pnum (the guy he's trying to kick) is %d.\n" + "playernum's node is %d.\n" + "That node has %d players.\n" + "Player 2 on that node is %d.\n" + "pnum's node is %d.\n" + "That node has %d players.\n" + "Player 2 on that node is %d.\n" + "\n" + "If you think this is a bug, please report it, including all of the details above.\n", + playernum, pnum, + playernode[playernum], playerpernode[playernode[playernum]], + nodetoplayer2[playernode[playernum]], + playernode[pnum], playerpernode[playernode[pnum]], + nodetoplayer2[playernode[pnum]]); +*/ + pnum = playernum; + msg = KICK_MSG_CON_FAIL; + keepbody = true; + } + + //CONS_Printf("\x82%s ", player_names[pnum]); + + // If a verified admin banned someone, the server needs to know about it. + // If the playernum isn't zero (the server) then the server needs to record the ban. + if (server && playernum && (msg == KICK_MSG_BANNED || msg == KICK_MSG_CUSTOM_BAN)) + { + if (I_Ban && !I_Ban(playernode[(INT32)pnum])) + CONS_Alert(CONS_WARNING, M_GetText("Too many bans! Geez, that's a lot of people you're excluding...\n")); +#ifndef NONET + else + Ban_Add(reason); +#endif + } + + switch (msg) + { + case KICK_MSG_GO_AWAY: + if (!players[pnum].quittime) + HU_AddChatText(va("\x82*%s has been kicked (Go away)", player_names[pnum]), false); + kickreason = KR_KICK; + break; + case KICK_MSG_PING_HIGH: + HU_AddChatText(va("\x82*%s left the game (Broke ping limit)", player_names[pnum]), false); + kickreason = KR_PINGLIMIT; + break; + case KICK_MSG_CON_FAIL: + HU_AddChatText(va("\x82*%s left the game (Synch Failure)", player_names[pnum]), false); + kickreason = KR_SYNCH; + + if (M_CheckParm("-consisdump")) // Helps debugging some problems + { + INT32 i; + + CONS_Printf(M_GetText("Player kicked is #%d, dumping consistency...\n"), pnum); + + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + CONS_Printf("-------------------------------------\n"); + CONS_Printf("Player %d: %s\n", i, player_names[i]); + CONS_Printf("Skin: %d\n", players[i].skin); + CONS_Printf("Color: %d\n", players[i].skincolor); + CONS_Printf("Speed: %d\n",players[i].speed>>FRACBITS); + if (players[i].mo) + { + if (!players[i].mo->skin) + CONS_Printf("Mobj skin: NULL!\n"); + else + CONS_Printf("Mobj skin: %s\n", ((skin_t *)players[i].mo->skin)->name); + CONS_Printf("Position: %d, %d, %d\n", players[i].mo->x, players[i].mo->y, players[i].mo->z); + if (!players[i].mo->state) + CONS_Printf("State: S_NULL\n"); + else + CONS_Printf("State: %d\n", (statenum_t)(players[i].mo->state-states)); + } + else + CONS_Printf("Mobj: NULL\n"); + CONS_Printf("-------------------------------------\n"); + } + } + break; + case KICK_MSG_TIMEOUT: + HU_AddChatText(va("\x82*%s left the game (Connection timeout)", player_names[pnum]), false); + kickreason = KR_TIMEOUT; + break; + case KICK_MSG_PLAYER_QUIT: + if (netgame && !players[pnum].quittime) // not splitscreen/bots or soulless body + HU_AddChatText(va("\x82*%s left the game", player_names[pnum]), false); + kickreason = KR_LEAVE; + break; + case KICK_MSG_BANNED: + HU_AddChatText(va("\x82*%s has been banned (Don't come back)", player_names[pnum]), false); + kickreason = KR_BAN; + break; + case KICK_MSG_CUSTOM_KICK: + READSTRINGN(*p, reason, MAX_REASONLENGTH+1); + HU_AddChatText(va("\x82*%s has been kicked (%s)", player_names[pnum], reason), false); + kickreason = KR_KICK; + break; + case KICK_MSG_CUSTOM_BAN: + READSTRINGN(*p, reason, MAX_REASONLENGTH+1); + HU_AddChatText(va("\x82*%s has been banned (%s)", player_names[pnum], reason), false); + kickreason = KR_BAN; + break; + } + + if (pnum == consoleplayer) + { + if (Playing()) + LUAh_GameQuit(); +#ifdef DUMPCONSISTENCY + if (msg == KICK_MSG_CON_FAIL) SV_SavedGame(); +#endif + D_QuitNetGame(); + CL_Reset(); + D_StartTitle(); + if (msg == KICK_MSG_CON_FAIL) + M_StartMessage(M_GetText("Server closed connection\n(synch failure)\nPress ESC\n"), NULL, MM_NOTHING); + else if (msg == KICK_MSG_PING_HIGH) + M_StartMessage(M_GetText("Server closed connection\n(Broke ping limit)\nPress ESC\n"), NULL, MM_NOTHING); + else if (msg == KICK_MSG_BANNED) + M_StartMessage(M_GetText("You have been banned by the server\n\nPress ESC\n"), NULL, MM_NOTHING); + else if (msg == KICK_MSG_CUSTOM_KICK) + M_StartMessage(va(M_GetText("You have been kicked\n(%s)\nPress ESC\n"), reason), NULL, MM_NOTHING); + else if (msg == KICK_MSG_CUSTOM_BAN) + M_StartMessage(va(M_GetText("You have been banned\n(%s)\nPress ESC\n"), reason), NULL, MM_NOTHING); + else + M_StartMessage(M_GetText("You have been kicked by the server\n\nPress ESC\n"), NULL, MM_NOTHING); + } + else if (keepbody) + { + if (server && !demoplayback && playernode[pnum] != UINT8_MAX) + { + INT32 node = playernode[pnum]; + playerpernode[node]--; + if (playerpernode[node] <= 0) + { + nodeingame[node] = false; + Net_CloseConnection(node); + ResetNode(node); + } + } + + playernode[pnum] = UINT8_MAX; + + players[pnum].quittime = 1; + } + else + CL_RemovePlayer(pnum, kickreason); +} + +static void Command_ResendGamestate(void) +{ + SINT8 playernum; + + if (COM_Argc() == 1) + { + CONS_Printf(M_GetText("resendgamestate : resend the game state to a player\n")); + return; + } + else if (client) + { + CONS_Printf(M_GetText("Only the server can use this.\n")); + return; + } + + playernum = nametonum(COM_Argv(1)); + if (playernum == -1 || playernum == 0) + return; + + // Send a PT_WILLRESENDGAMESTATE packet to the client so they know what's going on + netbuffer->packettype = PT_WILLRESENDGAMESTATE; + if (!HSendPacket(playernode[playernum], true, 0, 0)) + { + CONS_Alert(CONS_ERROR, M_GetText("A problem occured, please try again.\n")); + return; + } +} + +static CV_PossibleValue_t netticbuffer_cons_t[] = {{0, "MIN"}, {3, "MAX"}, {0, NULL}}; +consvar_t cv_netticbuffer = CVAR_INIT ("netticbuffer", "1", CV_SAVE, netticbuffer_cons_t, NULL); + +consvar_t cv_allownewplayer = CVAR_INIT ("allowjoin", "On", CV_SAVE|CV_NETVAR, CV_OnOff, NULL); +consvar_t cv_joinnextround = CVAR_INIT ("joinnextround", "Off", CV_SAVE|CV_NETVAR, CV_OnOff, NULL); /// \todo not done +static CV_PossibleValue_t maxplayers_cons_t[] = {{2, "MIN"}, {32, "MAX"}, {0, NULL}}; +consvar_t cv_maxplayers = CVAR_INIT ("maxplayers", "8", CV_SAVE|CV_NETVAR, maxplayers_cons_t, NULL); +static CV_PossibleValue_t joindelay_cons_t[] = {{1, "MIN"}, {3600, "MAX"}, {0, "Off"}, {0, NULL}}; +consvar_t cv_joindelay = CVAR_INIT ("joindelay", "10", CV_SAVE|CV_NETVAR, joindelay_cons_t, NULL); +static CV_PossibleValue_t rejointimeout_cons_t[] = {{1, "MIN"}, {60 * FRACUNIT, "MAX"}, {0, "Off"}, {0, NULL}}; +consvar_t cv_rejointimeout = CVAR_INIT ("rejointimeout", "Off", CV_SAVE|CV_NETVAR|CV_FLOAT, rejointimeout_cons_t, NULL); + +static CV_PossibleValue_t resynchattempts_cons_t[] = {{1, "MIN"}, {20, "MAX"}, {0, "No"}, {0, NULL}}; +consvar_t cv_resynchattempts = CVAR_INIT ("resynchattempts", "10", CV_SAVE|CV_NETVAR, resynchattempts_cons_t, NULL); +consvar_t cv_blamecfail = CVAR_INIT ("blamecfail", "Off", CV_SAVE|CV_NETVAR, CV_OnOff, NULL); + +// max file size to send to a player (in kilobytes) +static CV_PossibleValue_t maxsend_cons_t[] = {{0, "MIN"}, {51200, "MAX"}, {0, NULL}}; +consvar_t cv_maxsend = CVAR_INIT ("maxsend", "4096", CV_SAVE|CV_NETVAR, maxsend_cons_t, NULL); +consvar_t cv_noticedownload = CVAR_INIT ("noticedownload", "Off", CV_SAVE|CV_NETVAR, CV_OnOff, NULL); + +// Speed of file downloading (in packets per tic) +static CV_PossibleValue_t downloadspeed_cons_t[] = {{0, "MIN"}, {32, "MAX"}, {0, NULL}}; +consvar_t cv_downloadspeed = CVAR_INIT ("downloadspeed", "16", CV_SAVE|CV_NETVAR, downloadspeed_cons_t, NULL); + +static void Got_AddPlayer(UINT8 **p, INT32 playernum); + +// called one time at init +void D_ClientServerInit(void) +{ + DEBFILE(va("- - -== SRB2 v%d.%.2d.%d "VERSIONSTRING" debugfile ==- - -\n", + VERSION/100, VERSION%100, SUBVERSION)); + +#ifndef NONET + COM_AddCommand("getplayernum", Command_GetPlayerNum); + COM_AddCommand("kick", Command_Kick); + COM_AddCommand("ban", Command_Ban); + COM_AddCommand("banip", Command_BanIP); + COM_AddCommand("clearbans", Command_ClearBans); + COM_AddCommand("showbanlist", Command_ShowBan); + COM_AddCommand("reloadbans", Command_ReloadBan); + COM_AddCommand("connect", Command_connect); + COM_AddCommand("nodes", Command_Nodes); + COM_AddCommand("resendgamestate", Command_ResendGamestate); +#ifdef PACKETDROP + COM_AddCommand("drop", Command_Drop); + COM_AddCommand("droprate", Command_Droprate); +#endif +#ifdef _DEBUG + COM_AddCommand("numnodes", Command_Numnodes); +#endif +#endif + + RegisterNetXCmd(XD_KICK, Got_KickCmd); + RegisterNetXCmd(XD_ADDPLAYER, Got_AddPlayer); +#ifndef NONET +#ifdef DUMPCONSISTENCY + CV_RegisterVar(&cv_dumpconsistency); +#endif + Ban_Load_File(false); +#endif + + gametic = 0; + localgametic = 0; + + // do not send anything before the real begin + SV_StopServer(); + SV_ResetServer(); + if (dedicated) + SV_SpawnServer(); +} + +static void ResetNode(INT32 node) +{ + nodeingame[node] = false; + nodewaiting[node] = 0; + + nettics[node] = gametic; + supposedtics[node] = gametic; + + nodetoplayer[node] = -1; + nodetoplayer2[node] = -1; + playerpernode[node] = 0; + + sendingsavegame[node] = false; + resendingsavegame[node] = false; + savegameresendcooldown[node] = 0; +} + +void SV_ResetServer(void) +{ + INT32 i; + + // +1 because this command will be executed in com_executebuffer in + // tryruntic so gametic will be incremented, anyway maketic > gametic + // is not an issue + + maketic = gametic + 1; + neededtic = maketic; + tictoclear = maketic; + + joindelay = 0; + + for (i = 0; i < MAXNETNODES; i++) + ResetNode(i); + + for (i = 0; i < MAXPLAYERS; i++) + { + LUA_InvalidatePlayer(&players[i]); + playeringame[i] = false; + playernode[i] = UINT8_MAX; + memset(playeraddress[i], 0, sizeof(*playeraddress)); + sprintf(player_names[i], "Player %d", i + 1); + adminplayers[i] = -1; // Populate the entire adminplayers array with -1. + } + + memset(player_name_changes, 0, sizeof player_name_changes); + + mynode = 0; + cl_packetmissed = false; + cl_redownloadinggamestate = false; + + if (dedicated) + { + nodeingame[0] = true; + serverplayer = 0; + } + else + serverplayer = consoleplayer; + + if (server) + servernode = 0; + + doomcom->numslots = 0; + + // clear server_context + memset(server_context, '-', 8); + + DEBFILE("\n-=-=-=-=-=-=-= Server Reset =-=-=-=-=-=-=-\n\n"); +} + +static inline void SV_GenContext(void) +{ + UINT8 i; + // generate server_context, as exactly 8 bytes of randomly mixed A-Z and a-z + // (hopefully M_Random is initialized!! if not this will be awfully silly!) + for (i = 0; i < 8; i++) + { + const char a = M_RandomKey(26*2); + if (a < 26) // uppercase + server_context[i] = 'A'+a; + else // lowercase + server_context[i] = 'a'+(a-26); + } +} + +// +// D_QuitNetGame +// Called before quitting to leave a net game +// without hanging the other players +// +void D_QuitNetGame(void) +{ + if (!netgame || !netbuffer) + return; + + DEBFILE("===========================================================================\n" + " Quitting Game, closing connection\n" + "===========================================================================\n"); + + // abort send/receive of files + CloseNetFile(); + RemoveAllLuaFileTransfers(); + waitingforluafiletransfer = false; + waitingforluafilecommand = false; + + if (server) + { + INT32 i; + + netbuffer->packettype = PT_SERVERSHUTDOWN; + for (i = 0; i < MAXNETNODES; i++) + if (nodeingame[i]) + HSendPacket(i, true, 0, 0); +#ifdef MASTERSERVER + if (serverrunning && ms_RoomId > 0) + UnregisterServer(); +#endif + } + else if (servernode > 0 && servernode < MAXNETNODES && nodeingame[(UINT8)servernode]) + { + netbuffer->packettype = PT_CLIENTQUIT; + HSendPacket(servernode, true, 0, 0); + } + + D_CloseConnection(); + ClearAdminPlayers(); + + DEBFILE("===========================================================================\n" + " Log finish\n" + "===========================================================================\n"); +#ifdef DEBUGFILE + if (debugfile) + { + fclose(debugfile); + debugfile = NULL; + } +#endif +} + +// Adds a node to the game (player will follow at map change or at savegame....) +static inline void SV_AddNode(INT32 node) +{ + nettics[node] = gametic; + supposedtics[node] = gametic; + // little hack because the server connects to itself and puts + // nodeingame when connected not here + if (node) + nodeingame[node] = true; +} + +// Xcmd XD_ADDPLAYER +static void Got_AddPlayer(UINT8 **p, INT32 playernum) +{ + INT16 node, newplayernum; + boolean splitscreenplayer; + boolean rejoined; + player_t *newplayer; + + if (playernum != serverplayer && !IsPlayerAdmin(playernum)) + { + // protect against hacked/buggy client + CONS_Alert(CONS_WARNING, M_GetText("Illegal add player command received from %s\n"), player_names[playernum]); + if (server) + SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY); + return; + } + + node = READUINT8(*p); + newplayernum = READUINT8(*p); + splitscreenplayer = newplayernum & 0x80; + newplayernum &= ~0x80; + + rejoined = playeringame[newplayernum]; + + if (!rejoined) + { + // Clear player before joining, lest some things get set incorrectly + // HACK: don't do this for splitscreen, it relies on preset values + if (!splitscreen && !botingame) + CL_ClearPlayer(newplayernum); + playeringame[newplayernum] = true; + G_AddPlayer(newplayernum); + if (newplayernum+1 > doomcom->numslots) + doomcom->numslots = (INT16)(newplayernum+1); + + if (server && I_GetNodeAddress) + { + const char *address = I_GetNodeAddress(node); + char *port = NULL; + if (address) // MI: fix msvcrt.dll!_mbscat crash? + { + strcpy(playeraddress[newplayernum], address); + port = strchr(playeraddress[newplayernum], ':'); + if (port) + *port = '\0'; + } + } + } + + newplayer = &players[newplayernum]; + + newplayer->jointime = 0; + newplayer->quittime = 0; + + READSTRINGN(*p, player_names[newplayernum], MAXPLAYERNAME); + + // the server is creating my player + if (node == mynode) + { + playernode[newplayernum] = 0; // for information only + if (!splitscreenplayer) + { + consoleplayer = newplayernum; + displayplayer = newplayernum; + secondarydisplayplayer = newplayernum; + DEBFILE("spawning me\n"); + ticcmd_oldangleturn[0] = newplayer->oldrelangleturn; + } + else + { + secondarydisplayplayer = newplayernum; + DEBFILE("spawning my brother\n"); + if (botingame) + newplayer->bot = 1; + ticcmd_oldangleturn[1] = newplayer->oldrelangleturn; + } + P_ForceLocalAngle(newplayer, (angle_t)(newplayer->angleturn << 16)); + D_SendPlayerConfig(); + addedtogame = true; + + if (rejoined) + { + if (newplayer->mo) + { + newplayer->viewheight = 41*newplayer->height/48; + + if (newplayer->mo->eflags & MFE_VERTICALFLIP) + newplayer->viewz = newplayer->mo->z + newplayer->mo->height - newplayer->viewheight; + else + newplayer->viewz = newplayer->mo->z + newplayer->viewheight; + } + + // wake up the status bar + ST_Start(); + // wake up the heads up text + HU_Start(); + + if (camera.chase && !splitscreenplayer) + P_ResetCamera(newplayer, &camera); + if (camera2.chase && splitscreenplayer) + P_ResetCamera(newplayer, &camera2); + } + } + + if (netgame) + { + char joinmsg[256]; + + if (rejoined) + strcpy(joinmsg, M_GetText("\x82*%s has rejoined the game (player %d)")); + else + strcpy(joinmsg, M_GetText("\x82*%s has joined the game (player %d)")); + strcpy(joinmsg, va(joinmsg, player_names[newplayernum], newplayernum)); + + // Merge join notification + IP to avoid clogging console/chat + if (server && cv_showjoinaddress.value && I_GetNodeAddress) + { + const char *address = I_GetNodeAddress(node); + if (address) + strcat(joinmsg, va(" (%s)", address)); + } + + HU_AddChatText(joinmsg, false); + } + + if (server && multiplayer && motd[0] != '\0') + COM_BufAddText(va("sayto %d %s\n", newplayernum, motd)); + + if (!rejoined) + LUAh_PlayerJoin(newplayernum); +} + +static boolean SV_AddWaitingPlayers(const char *name, const char *name2) +{ + INT32 node, n, newplayer = false; + UINT8 buf[2 + MAXPLAYERNAME]; + UINT8 *p; + INT32 newplayernum; + + for (node = 0; node < MAXNETNODES; node++) + { + // splitscreen can allow 2 player in one node + for (; nodewaiting[node] > 0; nodewaiting[node]--) + { + newplayer = true; + + newplayernum = FindRejoinerNum(node); + if (newplayernum == -1) + { + // search for a free playernum + // we can't use playeringame since it is not updated here + for (newplayernum = dedicated ? 1 : 0; newplayernum < MAXPLAYERS; newplayernum++) + { + if (playeringame[newplayernum]) + continue; + for (n = 0; n < MAXNETNODES; n++) + if (nodetoplayer[n] == newplayernum || nodetoplayer2[n] == newplayernum) + break; + if (n == MAXNETNODES) + break; + } + } + + // should never happen since we check the playernum + // before accepting the join + I_Assert(newplayernum < MAXPLAYERS); + + playernode[newplayernum] = (UINT8)node; + + p = buf + 2; + buf[0] = (UINT8)node; + buf[1] = newplayernum; + if (playerpernode[node] < 1) + { + nodetoplayer[node] = newplayernum; + WRITESTRINGN(p, name, MAXPLAYERNAME); + } + else + { + nodetoplayer2[node] = newplayernum; + buf[1] |= 0x80; + WRITESTRINGN(p, name2, MAXPLAYERNAME); + } + playerpernode[node]++; + + SendNetXCmd(XD_ADDPLAYER, &buf, p - buf); + + DEBFILE(va("Server added player %d node %d\n", newplayernum, node)); + } + } + + return newplayer; +} + +void CL_AddSplitscreenPlayer(void) +{ + if (cl_mode == CL_CONNECTED) + CL_SendJoin(); +} + +void CL_RemoveSplitscreenPlayer(void) +{ + if (cl_mode != CL_CONNECTED) + return; + + SendKick(secondarydisplayplayer, KICK_MSG_PLAYER_QUIT); +} + +// is there a game running +boolean Playing(void) +{ + return (server && serverrunning) || (client && cl_mode == CL_CONNECTED); +} + +boolean SV_SpawnServer(void) +{ + if (demoplayback) + G_StopDemo(); // reset engine parameter + if (metalplayback) + G_StopMetalDemo(); + + if (!serverrunning) + { + CONS_Printf(M_GetText("Starting Server....\n")); + serverrunning = true; + SV_ResetServer(); + SV_GenContext(); + if (netgame && I_NetOpenSocket) + { + I_NetOpenSocket(); +#ifdef MASTERSERVER + if (ms_RoomId > 0) + RegisterServer(); +#endif + } + + // non dedicated server just connect to itself + if (!dedicated) + CL_ConnectToServer(); + else doomcom->numslots = 1; + } + + return SV_AddWaitingPlayers(cv_playername.zstring, cv_playername2.zstring); +} + +void SV_StopServer(void) +{ + tic_t i; + + if (gamestate == GS_INTERMISSION) + Y_EndIntermission(); + gamestate = wipegamestate = GS_NULL; + + localtextcmd[0] = 0; + localtextcmd2[0] = 0; + + for (i = firstticstosend; i < firstticstosend + BACKUPTICS; i++) + D_Clearticcmd(i); + + consoleplayer = 0; + cl_mode = CL_SEARCHING; + maketic = gametic+1; + neededtic = maketic; + serverrunning = false; +} + +// called at singleplayer start and stopdemo +void SV_StartSinglePlayerServer(void) +{ + server = true; + netgame = false; + multiplayer = false; + G_SetGametype(GT_COOP); + + // no more tic the game with this settings! + SV_StopServer(); + + if (splitscreen) + multiplayer = true; +} + +static void SV_SendRefuse(INT32 node, const char *reason) +{ + strcpy(netbuffer->u.serverrefuse.reason, reason); + + netbuffer->packettype = PT_SERVERREFUSE; + HSendPacket(node, true, 0, strlen(netbuffer->u.serverrefuse.reason) + 1); + Net_CloseConnection(node); +} + +// used at txtcmds received to check packetsize bound +static size_t TotalTextCmdPerTic(tic_t tic) +{ + INT32 i; + size_t total = 1; // num of textcmds in the tic (ntextcmd byte) + + for (i = 0; i < MAXPLAYERS; i++) + { + UINT8 *textcmd = D_GetExistingTextcmd(tic, i); + if ((!i || playeringame[i]) && textcmd) + total += 2 + textcmd[0]; // "+2" for size and playernum + } + + return total; +} + +/** Called when a PT_CLIENTJOIN packet is received + * + * \param node The packet sender + * + */ +static void HandleConnect(SINT8 node) +{ + char names[MAXSPLITSCREENPLAYERS][MAXPLAYERNAME + 1]; + INT32 rejoinernum; + INT32 i; + + rejoinernum = FindRejoinerNum(node); + + if (bannednode && bannednode[node]) + SV_SendRefuse(node, M_GetText("You have been banned\nfrom the server.")); + else if (netbuffer->u.clientcfg._255 != 255 || + netbuffer->u.clientcfg.packetversion != PACKETVERSION) + SV_SendRefuse(node, "Incompatible packet formats."); + else if (strncmp(netbuffer->u.clientcfg.application, SRB2APPLICATION, + sizeof netbuffer->u.clientcfg.application)) + SV_SendRefuse(node, "Different SRB2 modifications\nare not compatible."); + else if (netbuffer->u.clientcfg.version != VERSION + || netbuffer->u.clientcfg.subversion != SUBVERSION) + SV_SendRefuse(node, va(M_GetText("Different SRB2 versions cannot\nplay a netgame!\n(server version %d.%d.%d)"), VERSION/100, VERSION%100, SUBVERSION)); + else if (!cv_allownewplayer.value && node && rejoinernum == -1) + SV_SendRefuse(node, M_GetText("The server is not accepting\njoins for the moment.")); + else if (D_NumPlayers() >= cv_maxplayers.value && rejoinernum == -1) + SV_SendRefuse(node, va(M_GetText("Maximum players reached: %d"), cv_maxplayers.value)); + else if (netgame && netbuffer->u.clientcfg.localplayers > 1) // Hacked client? + SV_SendRefuse(node, M_GetText("Too many players from\nthis node.")); + else if (netgame && !netbuffer->u.clientcfg.localplayers) // Stealth join? + SV_SendRefuse(node, M_GetText("No players from\nthis node.")); + else if (luafiletransfers) + SV_SendRefuse(node, M_GetText("The server is broadcasting a file\nrequested by a Lua script.\nPlease wait a bit and then\ntry rejoining.")); + else if (netgame && joindelay > 2 * (tic_t)cv_joindelay.value * TICRATE) + SV_SendRefuse(node, va(M_GetText("Too many people are connecting.\nPlease wait %d seconds and then\ntry rejoining."), + (joindelay - 2 * cv_joindelay.value * TICRATE) / TICRATE)); + else + { +#ifndef NONET + boolean newnode = false; +#endif + + for (i = 0; i < netbuffer->u.clientcfg.localplayers - playerpernode[node]; i++) + { + strlcpy(names[i], netbuffer->u.clientcfg.names[i], MAXPLAYERNAME + 1); + if (!EnsurePlayerNameIsGood(names[i], rejoinernum)) + { + SV_SendRefuse(node, "Bad player name"); + return; + } + } + + // client authorised to join + nodewaiting[node] = (UINT8)(netbuffer->u.clientcfg.localplayers - playerpernode[node]); + if (!nodeingame[node]) + { + gamestate_t backupstate = gamestate; +#ifndef NONET + newnode = true; +#endif + SV_AddNode(node); + + if (cv_joinnextround.value && gameaction == ga_nothing) + G_SetGamestate(GS_WAITINGPLAYERS); + if (!SV_SendServerConfig(node)) + { + G_SetGamestate(backupstate); + /// \note Shouldn't SV_SendRefuse be called before ResetNode? + ResetNode(node); + SV_SendRefuse(node, M_GetText("Server couldn't send info, please try again")); + /// \todo fix this !!! + return; // restart the while + } + //if (gamestate != GS_LEVEL) // GS_INTERMISSION, etc? + // SV_SendPlayerConfigs(node); // send bare minimum player info + G_SetGamestate(backupstate); + DEBFILE("new node joined\n"); + } +#ifndef NONET + if (nodewaiting[node]) + { + if ((gamestate == GS_LEVEL || gamestate == GS_INTERMISSION) && newnode) + { + SV_SendSaveGame(node, false); // send a complete game state + DEBFILE("send savegame\n"); + } + SV_AddWaitingPlayers(names[0], names[1]); + joindelay += cv_joindelay.value * TICRATE; + player_joining = true; + } +#endif + } +} + +/** Called when a PT_SERVERSHUTDOWN packet is received + * + * \param node The packet sender (should be the server) + * + */ +static void HandleShutdown(SINT8 node) +{ + (void)node; + if (Playing()) + LUAh_GameQuit(); + D_QuitNetGame(); + CL_Reset(); + D_StartTitle(); + M_StartMessage(M_GetText("Server has shutdown\n\nPress Esc\n"), NULL, MM_NOTHING); +} + +/** Called when a PT_NODETIMEOUT packet is received + * + * \param node The packet sender (should be the server) + * + */ +static void HandleTimeout(SINT8 node) +{ + (void)node; + if (Playing()) + LUAh_GameQuit(); + D_QuitNetGame(); + CL_Reset(); + D_StartTitle(); + M_StartMessage(M_GetText("Server Timeout\n\nPress Esc\n"), NULL, MM_NOTHING); +} + +#ifndef NONET +/** Called when a PT_SERVERINFO packet is received + * + * \param node The packet sender + * \note What happens if the packet comes from a client or something like that? + * + */ +static void HandleServerInfo(SINT8 node) +{ + // compute ping in ms + const tic_t ticnow = I_GetTime(); + const tic_t ticthen = (tic_t)LONG(netbuffer->u.serverinfo.time); + const tic_t ticdiff = (ticnow - ticthen)*1000/NEWTICRATE; + netbuffer->u.serverinfo.time = (tic_t)LONG(ticdiff); + netbuffer->u.serverinfo.servername[MAXSERVERNAME-1] = 0; + netbuffer->u.serverinfo.application + [sizeof netbuffer->u.serverinfo.application - 1] = '\0'; + netbuffer->u.serverinfo.gametypename + [sizeof netbuffer->u.serverinfo.gametypename - 1] = '\0'; + + SL_InsertServer(&netbuffer->u.serverinfo, node); +} +#endif + +static void PT_WillResendGamestate(void) +{ + char tmpsave[256]; + + if (server || cl_redownloadinggamestate) + return; + + // Send back a PT_CANRECEIVEGAMESTATE packet to the server + // so they know they can start sending the game state + netbuffer->packettype = PT_CANRECEIVEGAMESTATE; + if (!HSendPacket(servernode, true, 0, 0)) + return; + + CONS_Printf(M_GetText("Reloading game state...\n")); + + sprintf(tmpsave, "%s" PATHSEP TMPSAVENAME, srb2home); + + // Don't get a corrupt savegame error because tmpsave already exists + if (FIL_FileExists(tmpsave) && unlink(tmpsave) == -1) + I_Error("Can't delete %s\n", tmpsave); + + CL_PrepareDownloadSaveGame(tmpsave); + + cl_redownloadinggamestate = true; +} + +static void PT_CanReceiveGamestate(SINT8 node) +{ + if (client || sendingsavegame[node]) + return; + + CONS_Printf(M_GetText("Resending game state to %s...\n"), player_names[nodetoplayer[node]]); + + SV_SendSaveGame(node, true); // Resend a complete game state + resendingsavegame[node] = true; +} + +/** Handles a packet received from a node that isn't in game + * + * \param node The packet sender + * \todo Choose a better name, as the packet can also come from the server apparently? + * \sa HandlePacketFromPlayer + * \sa GetPackets + * + */ +static void HandlePacketFromAwayNode(SINT8 node) +{ + if (node != servernode) + DEBFILE(va("Received packet from unknown host %d\n", node)); + +// macro for packets that should only be sent by the server +// if it is NOT from the server, bail out and close the connection! +#define SERVERONLY \ + if (node != servernode) \ + { \ + Net_CloseConnection(node); \ + break; \ + } + switch (netbuffer->packettype) + { + case PT_ASKINFOVIAMS: +#if 0 + if (server && serverrunning) + { + INT32 clientnode; + if (ms_RoomId < 0) // ignore if we're not actually on the MS right now + { + Net_CloseConnection(node); // and yes, close connection + return; + } + clientnode = I_NetMakeNode(netbuffer->u.msaskinfo.clientaddr); + if (clientnode != -1) + { + SV_SendServerInfo(clientnode, (tic_t)LONG(netbuffer->u.msaskinfo.time)); + SV_SendPlayerInfo(clientnode); // Send extra info + Net_CloseConnection(clientnode); + // Don't close connection to MS... + } + else + Net_CloseConnection(node); // ...unless the IP address is not valid + } + else + Net_CloseConnection(node); // you're not supposed to get it, so ignore it +#else + Net_CloseConnection(node); +#endif + break; + + case PT_ASKINFO: + if (server && serverrunning) + { + SV_SendServerInfo(node, (tic_t)LONG(netbuffer->u.askinfo.time)); + SV_SendPlayerInfo(node); // Send extra info + } + Net_CloseConnection(node); + break; + + case PT_SERVERREFUSE: // Negative response of client join request + if (server && serverrunning) + { // But wait I thought I'm the server? + Net_CloseConnection(node); + break; + } + SERVERONLY + if (cl_mode == CL_WAITJOINRESPONSE) + { + // Save the reason so it can be displayed after quitting the netgame + char *reason = strdup(netbuffer->u.serverrefuse.reason); + if (!reason) + I_Error("Out of memory!\n"); + + D_QuitNetGame(); + CL_Reset(); + D_StartTitle(); + + M_StartMessage(va(M_GetText("Server refuses connection\n\nReason:\n%s"), + reason), NULL, MM_NOTHING); + + free(reason); + + // Will be reset by caller. Signals refusal. + cl_mode = CL_ABORTED; + } + break; + + case PT_SERVERCFG: // Positive response of client join request + { + if (server && serverrunning && node != servernode) + { // but wait I thought I'm the server? + Net_CloseConnection(node); + break; + } + SERVERONLY + /// \note how would this happen? and is it doing the right thing if it does? + if (cl_mode != CL_WAITJOINRESPONSE) + break; + + if (client) + { + maketic = gametic = neededtic = (tic_t)LONG(netbuffer->u.servercfg.gametic); + G_SetGametype(netbuffer->u.servercfg.gametype); + modifiedgame = netbuffer->u.servercfg.modifiedgame; + memcpy(server_context, netbuffer->u.servercfg.server_context, 8); + } + + nodeingame[(UINT8)servernode] = true; + serverplayer = netbuffer->u.servercfg.serverplayer; + doomcom->numslots = SHORT(netbuffer->u.servercfg.totalslotnum); + mynode = netbuffer->u.servercfg.clientnode; + if (serverplayer >= 0) + playernode[(UINT8)serverplayer] = servernode; + + if (netgame) +#ifndef NONET + CONS_Printf(M_GetText("Join accepted, waiting for complete game state...\n")); +#else + CONS_Printf(M_GetText("Join accepted, waiting for next level change...\n")); +#endif + DEBFILE(va("Server accept join gametic=%u mynode=%d\n", gametic, mynode)); + +#ifndef NONET + /// \note Wait. What if a Lua script uses some global custom variables synched with the NetVars hook? + /// Shouldn't them be downloaded even at intermission time? + /// Also, according to HandleConnect, the server will send the savegame even during intermission... + if (netbuffer->u.servercfg.gamestate == GS_LEVEL/* || + netbuffer->u.servercfg.gamestate == GS_INTERMISSION*/) + cl_mode = CL_DOWNLOADSAVEGAME; + else +#endif + cl_mode = CL_CONNECTED; + break; + } + + // Handled in d_netfil.c + case PT_FILEFRAGMENT: + if (server) + { // But wait I thought I'm the server? + Net_CloseConnection(node); + break; + } + SERVERONLY + PT_FileFragment(); + break; + + case PT_FILEACK: + if (server) + PT_FileAck(); + break; + + case PT_FILERECEIVED: + if (server) + PT_FileReceived(); + break; + + case PT_REQUESTFILE: + if (server) + { + if (!cv_downloading.value || !PT_RequestFile(node)) + Net_CloseConnection(node); // close connection if one of the requested files could not be sent, or you disabled downloading anyway + } + else + Net_CloseConnection(node); // nope + break; + + case PT_NODETIMEOUT: + case PT_CLIENTQUIT: + if (server) + Net_CloseConnection(node); + break; + + case PT_CLIENTCMD: + break; // This is not an "unknown packet" + + case PT_SERVERTICS: + // Do not remove my own server (we have just get a out of order packet) + if (node == servernode) + break; + /* FALLTHRU */ + + default: + DEBFILE(va("unknown packet received (%d) from unknown host\n",netbuffer->packettype)); + Net_CloseConnection(node); + break; // Ignore it + + } +#undef SERVERONLY +} + +/** Handles a packet received from a node that is in game + * + * \param node The packet sender + * \todo Choose a better name + * \sa HandlePacketFromAwayNode + * \sa GetPackets + * + */ +static void HandlePacketFromPlayer(SINT8 node) +{ + INT32 netconsole; + tic_t realend, realstart; + UINT8 *pak, *txtpak, numtxtpak; +#ifndef NOMD5 + UINT8 finalmd5[16];/* Well, it's the cool thing to do? */ +#endif + + txtpak = NULL; + + if (dedicated && node == 0) + netconsole = 0; + else + netconsole = nodetoplayer[node]; +#ifdef PARANOIA + if (netconsole >= MAXPLAYERS) + I_Error("bad table nodetoplayer: node %d player %d", doomcom->remotenode, netconsole); +#endif + + switch (netbuffer->packettype) + { +// -------------------------------------------- SERVER RECEIVE ---------- + case PT_CLIENTCMD: + case PT_CLIENT2CMD: + case PT_CLIENTMIS: + case PT_CLIENT2MIS: + case PT_NODEKEEPALIVE: + case PT_NODEKEEPALIVEMIS: + if (client) + break; + + // To save bytes, only the low byte of tic numbers are sent + // Use ExpandTics to figure out what the rest of the bytes are + realstart = ExpandTics(netbuffer->u.clientpak.client_tic, node); + realend = ExpandTics(netbuffer->u.clientpak.resendfrom, node); + + if (netbuffer->packettype == PT_CLIENTMIS || netbuffer->packettype == PT_CLIENT2MIS + || netbuffer->packettype == PT_NODEKEEPALIVEMIS + || supposedtics[node] < realend) + { + supposedtics[node] = realend; + } + // Discard out of order packet + if (nettics[node] > realend) + { + DEBFILE(va("out of order ticcmd discarded nettics = %u\n", nettics[node])); + break; + } + + // Update the nettics + nettics[node] = realend; + + // Don't do anything for packets of type NODEKEEPALIVE? + if (netconsole == -1 || netbuffer->packettype == PT_NODEKEEPALIVE + || netbuffer->packettype == PT_NODEKEEPALIVEMIS) + break; + + // As long as clients send valid ticcmds, the server can keep running, so reset the timeout + /// \todo Use a separate cvar for that kind of timeout? + freezetimeout[node] = I_GetTime() + connectiontimeout; + + // Copy ticcmd + G_MoveTiccmd(&netcmds[maketic%BACKUPTICS][netconsole], &netbuffer->u.clientpak.cmd, 1); + + // Check ticcmd for "speed hacks" + if (netcmds[maketic%BACKUPTICS][netconsole].forwardmove > MAXPLMOVE || netcmds[maketic%BACKUPTICS][netconsole].forwardmove < -MAXPLMOVE + || netcmds[maketic%BACKUPTICS][netconsole].sidemove > MAXPLMOVE || netcmds[maketic%BACKUPTICS][netconsole].sidemove < -MAXPLMOVE) + { + CONS_Alert(CONS_WARNING, M_GetText("Illegal movement value received from node %d\n"), netconsole); + //D_Clearticcmd(k); + + SendKick(netconsole, KICK_MSG_CON_FAIL); + break; + } + + // Splitscreen cmd + if ((netbuffer->packettype == PT_CLIENT2CMD || netbuffer->packettype == PT_CLIENT2MIS) + && nodetoplayer2[node] >= 0) + G_MoveTiccmd(&netcmds[maketic%BACKUPTICS][(UINT8)nodetoplayer2[node]], + &netbuffer->u.client2pak.cmd2, 1); + + // Check player consistancy during the level + if (realstart <= gametic && realstart + BACKUPTICS - 1 > gametic && gamestate == GS_LEVEL + && consistancy[realstart%BACKUPTICS] != SHORT(netbuffer->u.clientpak.consistancy) + && !resendingsavegame[node] && savegameresendcooldown[node] <= I_GetTime() + && !SV_ResendingSavegameToAnyone()) + { + if (cv_resynchattempts.value) + { + // Tell the client we are about to resend them the gamestate + netbuffer->packettype = PT_WILLRESENDGAMESTATE; + HSendPacket(node, true, 0, 0); + + resendingsavegame[node] = true; + + if (cv_blamecfail.value) + CONS_Printf(M_GetText("Synch failure for player %d (%s); expected %hd, got %hd\n"), + netconsole+1, player_names[netconsole], + consistancy[realstart%BACKUPTICS], + SHORT(netbuffer->u.clientpak.consistancy)); + DEBFILE(va("Restoring player %d (synch failure) [%update] %d!=%d\n", + netconsole, realstart, consistancy[realstart%BACKUPTICS], + SHORT(netbuffer->u.clientpak.consistancy))); + break; + } + else + { + SendKick(netconsole, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY); + DEBFILE(va("player %d kicked (synch failure) [%u] %d!=%d\n", + netconsole, realstart, consistancy[realstart%BACKUPTICS], + SHORT(netbuffer->u.clientpak.consistancy))); + break; + } + } + break; + case PT_TEXTCMD2: // splitscreen special + netconsole = nodetoplayer2[node]; + /* FALLTHRU */ + case PT_TEXTCMD: + if (client) + break; + + if (netconsole < 0 || netconsole >= MAXPLAYERS) + Net_UnAcknowledgePacket(node); + else + { + size_t j; + tic_t tic = maketic; + UINT8 *textcmd; + + // ignore if the textcmd has a reported size of zero + // this shouldn't be sent at all + if (!netbuffer->u.textcmd[0]) + { + DEBFILE(va("GetPacket: Textcmd with size 0 detected! (node %u, player %d)\n", + node, netconsole)); + Net_UnAcknowledgePacket(node); + break; + } + + // ignore if the textcmd size var is actually larger than it should be + // BASEPACKETSIZE + 1 (for size) + textcmd[0] should == datalength + if (netbuffer->u.textcmd[0] > (size_t)doomcom->datalength-BASEPACKETSIZE-1) + { + DEBFILE(va("GetPacket: Bad Textcmd packet size! (expected %d, actual %s, node %u, player %d)\n", + netbuffer->u.textcmd[0], sizeu1((size_t)doomcom->datalength-BASEPACKETSIZE-1), + node, netconsole)); + Net_UnAcknowledgePacket(node); + break; + } + + // check if tic that we are making isn't too large else we cannot send it :( + // doomcom->numslots+1 "+1" since doomcom->numslots can change within this time and sent time + j = software_MAXPACKETLENGTH + - (netbuffer->u.textcmd[0]+2+BASESERVERTICSSIZE + + (doomcom->numslots+1)*sizeof(ticcmd_t)); + + // search a tic that have enougth space in the ticcmd + while ((textcmd = D_GetExistingTextcmd(tic, netconsole)), + (TotalTextCmdPerTic(tic) > j || netbuffer->u.textcmd[0] + (textcmd ? textcmd[0] : 0) > MAXTEXTCMD) + && tic < firstticstosend + BACKUPTICS) + tic++; + + if (tic >= firstticstosend + BACKUPTICS) + { + DEBFILE(va("GetPacket: Textcmd too long (max %s, used %s, mak %d, " + "tosend %u, node %u, player %d)\n", sizeu1(j), sizeu2(TotalTextCmdPerTic(maketic)), + maketic, firstticstosend, node, netconsole)); + Net_UnAcknowledgePacket(node); + break; + } + + // Make sure we have a buffer + if (!textcmd) textcmd = D_GetTextcmd(tic, netconsole); + + DEBFILE(va("textcmd put in tic %u at position %d (player %d) ftts %u mk %u\n", + tic, textcmd[0]+1, netconsole, firstticstosend, maketic)); + + M_Memcpy(&textcmd[textcmd[0]+1], netbuffer->u.textcmd+1, netbuffer->u.textcmd[0]); + textcmd[0] += (UINT8)netbuffer->u.textcmd[0]; + } + break; + case PT_LOGIN: + if (client) + break; + +#ifndef NOMD5 + if (doomcom->datalength < 16)/* ignore partial sends */ + break; + + if (!adminpasswordset) + { + CONS_Printf(M_GetText("Password from %s failed (no password set).\n"), player_names[netconsole]); + break; + } + + // Do the final pass to compare with the sent md5 + D_MD5PasswordPass(adminpassmd5, 16, va("PNUM%02d", netconsole), &finalmd5); + + if (!memcmp(netbuffer->u.md5sum, finalmd5, 16)) + { + CONS_Printf(M_GetText("%s passed authentication.\n"), player_names[netconsole]); + COM_BufInsertText(va("promote %d\n", netconsole)); // do this immediately + } + else + CONS_Printf(M_GetText("Password from %s failed.\n"), player_names[netconsole]); +#endif + break; + case PT_NODETIMEOUT: + case PT_CLIENTQUIT: + if (client) + break; + + // nodeingame will be put false in the execution of kick command + // this allow to send some packets to the quitting client to have their ack back + nodewaiting[node] = 0; + if (netconsole != -1 && playeringame[netconsole]) + { + UINT8 kickmsg; + + if (netbuffer->packettype == PT_NODETIMEOUT) + kickmsg = KICK_MSG_TIMEOUT; + else + kickmsg = KICK_MSG_PLAYER_QUIT; + kickmsg |= KICK_MSG_KEEP_BODY; + + SendKick(netconsole, kickmsg); + nodetoplayer[node] = -1; + + if (nodetoplayer2[node] != -1 && nodetoplayer2[node] >= 0 + && playeringame[(UINT8)nodetoplayer2[node]]) + { + SendKick(nodetoplayer2[node], kickmsg); + nodetoplayer2[node] = -1; + } + } + Net_CloseConnection(node); + nodeingame[node] = false; + break; + case PT_CANRECEIVEGAMESTATE: + PT_CanReceiveGamestate(node); + break; + case PT_ASKLUAFILE: + if (server && luafiletransfers && luafiletransfers->nodestatus[node] == LFTNS_ASKED) + AddLuaFileToSendQueue(node, luafiletransfers->realfilename); + break; + case PT_HASLUAFILE: + if (server && luafiletransfers && luafiletransfers->nodestatus[node] == LFTNS_SENDING) + SV_HandleLuaFileSent(node); + break; + case PT_RECEIVEDGAMESTATE: + sendingsavegame[node] = false; + resendingsavegame[node] = false; + savegameresendcooldown[node] = I_GetTime() + 15 * TICRATE; + break; +// -------------------------------------------- CLIENT RECEIVE ---------- + case PT_SERVERTICS: + // Only accept PT_SERVERTICS from the server. + if (node != servernode) + { + CONS_Alert(CONS_WARNING, M_GetText("%s received from non-host %d\n"), "PT_SERVERTICS", node); + if (server) + SendKick(netconsole, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY); + break; + } + + realstart = netbuffer->u.serverpak.starttic; + realend = realstart + netbuffer->u.serverpak.numtics; + + if (!txtpak) + txtpak = (UINT8 *)&netbuffer->u.serverpak.cmds[netbuffer->u.serverpak.numslots + * netbuffer->u.serverpak.numtics]; + + if (realend > gametic + CLIENTBACKUPTICS) + realend = gametic + CLIENTBACKUPTICS; + cl_packetmissed = realstart > neededtic; + + if (realstart <= neededtic && realend > neededtic) + { + tic_t i, j; + pak = (UINT8 *)&netbuffer->u.serverpak.cmds; + + for (i = realstart; i < realend; i++) + { + // clear first + D_Clearticcmd(i); + + // copy the tics + pak = G_ScpyTiccmd(netcmds[i%BACKUPTICS], pak, + netbuffer->u.serverpak.numslots*sizeof (ticcmd_t)); + + // copy the textcmds + numtxtpak = *txtpak++; + for (j = 0; j < numtxtpak; j++) + { + INT32 k = *txtpak++; // playernum + const size_t txtsize = txtpak[0]+1; + + if (i >= gametic) // Don't copy old net commands + M_Memcpy(D_GetTextcmd(i, k), txtpak, txtsize); + txtpak += txtsize; + } + } + + neededtic = realend; + } + else + { + DEBFILE(va("frame not in bound: %u\n", neededtic)); + /*if (realend < neededtic - 2 * TICRATE || neededtic + 2 * TICRATE < realstart) + I_Error("Received an out of order PT_SERVERTICS packet!\n" + "Got tics %d-%d, needed tic %d\n\n" + "Please report this crash on the Master Board,\n" + "IRC or Discord so it can be fixed.\n", (INT32)realstart, (INT32)realend, (INT32)neededtic);*/ + } + break; + case PT_PING: + // Only accept PT_PING from the server. + if (node != servernode) + { + CONS_Alert(CONS_WARNING, M_GetText("%s received from non-host %d\n"), "PT_PING", node); + if (server) + SendKick(netconsole, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY); + break; + } + + //Update client ping table from the server. + if (client) + { + UINT8 i; + for (i = 0; i < MAXPLAYERS; i++) + if (playeringame[i]) + playerpingtable[i] = (tic_t)netbuffer->u.pingtable[i]; + + servermaxping = (tic_t)netbuffer->u.pingtable[MAXPLAYERS]; + } + + break; + case PT_SERVERCFG: + break; + case PT_FILEFRAGMENT: + // Only accept PT_FILEFRAGMENT from the server. + if (node != servernode) + { + CONS_Alert(CONS_WARNING, M_GetText("%s received from non-host %d\n"), "PT_FILEFRAGMENT", node); + if (server) + SendKick(netconsole, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY); + break; + } + if (client) + PT_FileFragment(); + break; + case PT_FILEACK: + if (server) + PT_FileAck(); + break; + case PT_FILERECEIVED: + if (server) + PT_FileReceived(); + break; + case PT_WILLRESENDGAMESTATE: + PT_WillResendGamestate(); + break; + case PT_SENDINGLUAFILE: + if (client) + CL_PrepareDownloadLuaFile(); + break; + default: + DEBFILE(va("UNKNOWN PACKET TYPE RECEIVED %d from host %d\n", + netbuffer->packettype, node)); + } // end switch +} + +/** Handles all received packets, if any + * + * \todo Add details to this description (lol) + * + */ +static void GetPackets(void) +{ + SINT8 node; // The packet sender + + player_joining = false; + + while (HGetPacket()) + { + node = (SINT8)doomcom->remotenode; + + if (netbuffer->packettype == PT_CLIENTJOIN && server) + { + HandleConnect(node); + continue; + } + if (node == servernode && client && cl_mode != CL_SEARCHING) + { + if (netbuffer->packettype == PT_SERVERSHUTDOWN) + { + HandleShutdown(node); + continue; + } + if (netbuffer->packettype == PT_NODETIMEOUT) + { + HandleTimeout(node); + continue; + } + } + +#ifndef NONET + if (netbuffer->packettype == PT_SERVERINFO) + { + HandleServerInfo(node); + continue; + } +#endif + + if (netbuffer->packettype == PT_PLAYERINFO) + continue; // We do nothing with PLAYERINFO, that's for the MS browser. + + // Packet received from someone already playing + if (nodeingame[node]) + HandlePacketFromPlayer(node); + // Packet received from someone not playing + else + HandlePacketFromAwayNode(node); + } +} + +// +// NetUpdate +// Builds ticcmds for console player, +// sends out a packet +// +// no more use random generator, because at very first tic isn't yet synchronized +// Note: It is called consistAncy on purpose. +// +static INT16 Consistancy(void) +{ + INT32 i; + UINT32 ret = 0; +#ifdef MOBJCONSISTANCY + thinker_t *th; + mobj_t *mo; +#endif + + DEBFILE(va("TIC %u ", gametic)); + + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + ret ^= 0xCCCC; + else if (!players[i].mo); + else + { + ret += players[i].mo->x; + ret -= players[i].mo->y; + ret += players[i].powers[pw_shield]; + ret *= i+1; + } + } + // I give up + // Coop desynching enemies is painful + if (!G_PlatformGametype()) + ret += P_GetRandSeed(); + +#ifdef MOBJCONSISTANCY + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) + { + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + + mo = (mobj_t *)th; + + if (mo->flags & (MF_SPECIAL | MF_SOLID | MF_PUSHABLE | MF_BOSS | MF_MISSILE | MF_SPRING | MF_MONITOR | MF_FIRE | MF_ENEMY | MF_PAIN | MF_STICKY)) + { + ret -= mo->type; + ret += mo->x; + ret -= mo->y; + ret += mo->z; + ret -= mo->momx; + ret += mo->momy; + ret -= mo->momz; + ret += mo->angle; + ret -= mo->flags; + ret += mo->flags2; + ret -= mo->eflags; + if (mo->target) + { + ret += mo->target->type; + ret -= mo->target->x; + ret += mo->target->y; + ret -= mo->target->z; + ret += mo->target->momx; + ret -= mo->target->momy; + ret += mo->target->momz; + ret -= mo->target->angle; + ret += mo->target->flags; + ret -= mo->target->flags2; + ret += mo->target->eflags; + ret -= mo->target->state - states; + ret += mo->target->tics; + ret -= mo->target->sprite; + ret += mo->target->frame; + } + else + ret ^= 0x3333; + if (mo->tracer && mo->tracer->type != MT_OVERLAY) + { + ret += mo->tracer->type; + ret -= mo->tracer->x; + ret += mo->tracer->y; + ret -= mo->tracer->z; + ret += mo->tracer->momx; + ret -= mo->tracer->momy; + ret += mo->tracer->momz; + ret -= mo->tracer->angle; + ret += mo->tracer->flags; + ret -= mo->tracer->flags2; + ret += mo->tracer->eflags; + ret -= mo->tracer->state - states; + ret += mo->tracer->tics; + ret -= mo->tracer->sprite; + ret += mo->tracer->frame; + } + else + ret ^= 0xAAAA; + ret -= mo->state - states; + ret += mo->tics; + ret -= mo->sprite; + ret += mo->frame; + } + } +#endif + + DEBFILE(va("Consistancy = %u\n", (ret & 0xFFFF))); + + return (INT16)(ret & 0xFFFF); +} + +// send the client packet to the server +static void CL_SendClientCmd(void) +{ + size_t packetsize = 0; + + netbuffer->packettype = PT_CLIENTCMD; + + if (cl_packetmissed) + netbuffer->packettype++; + netbuffer->u.clientpak.resendfrom = (UINT8)(neededtic & UINT8_MAX); + netbuffer->u.clientpak.client_tic = (UINT8)(gametic & UINT8_MAX); + + if (gamestate == GS_WAITINGPLAYERS) + { + // Send PT_NODEKEEPALIVE packet + netbuffer->packettype += 4; + packetsize = sizeof (clientcmd_pak) - sizeof (ticcmd_t) - sizeof (INT16); + HSendPacket(servernode, false, 0, packetsize); + } + else if (gamestate != GS_NULL && (addedtogame || dedicated)) + { + G_MoveTiccmd(&netbuffer->u.clientpak.cmd, &localcmds, 1); + netbuffer->u.clientpak.consistancy = SHORT(consistancy[gametic%BACKUPTICS]); + + // Send a special packet with 2 cmd for splitscreen + if (splitscreen || botingame) + { + netbuffer->packettype += 2; + G_MoveTiccmd(&netbuffer->u.client2pak.cmd2, &localcmds2, 1); + packetsize = sizeof (client2cmd_pak); + } + else + packetsize = sizeof (clientcmd_pak); + + HSendPacket(servernode, false, 0, packetsize); + } + + if (cl_mode == CL_CONNECTED || dedicated) + { + // Send extra data if needed + if (localtextcmd[0]) + { + netbuffer->packettype = PT_TEXTCMD; + M_Memcpy(netbuffer->u.textcmd,localtextcmd, localtextcmd[0]+1); + // All extra data have been sent + if (HSendPacket(servernode, true, 0, localtextcmd[0]+1)) // Send can fail... + localtextcmd[0] = 0; + } + + // Send extra data if needed for player 2 (splitscreen) + if (localtextcmd2[0]) + { + netbuffer->packettype = PT_TEXTCMD2; + M_Memcpy(netbuffer->u.textcmd, localtextcmd2, localtextcmd2[0]+1); + // All extra data have been sent + if (HSendPacket(servernode, true, 0, localtextcmd2[0]+1)) // Send can fail... + localtextcmd2[0] = 0; + } + } +} + +// send the server packet +// send tic from firstticstosend to maketic-1 +static void SV_SendTics(void) +{ + tic_t realfirsttic, lasttictosend, i; + UINT32 n; + INT32 j; + size_t packsize; + UINT8 *bufpos; + UINT8 *ntextcmd; + + // send to all client but not to me + // for each node create a packet with x tics and send it + // x is computed using supposedtics[n], max packet size and maketic + for (n = 1; n < MAXNETNODES; n++) + if (nodeingame[n]) + { + // assert supposedtics[n]>=nettics[n] + realfirsttic = supposedtics[n]; + lasttictosend = min(maketic, nettics[n] + CLIENTBACKUPTICS); + + if (realfirsttic >= lasttictosend) + { + // well we have sent all tics we will so use extrabandwidth + // to resent packet that are supposed lost (this is necessary since lost + // packet detection work when we have received packet with firsttic > neededtic + // (getpacket servertics case) + DEBFILE(va("Nothing to send node %u mak=%u sup=%u net=%u \n", + n, maketic, supposedtics[n], nettics[n])); + realfirsttic = nettics[n]; + if (realfirsttic >= lasttictosend || (I_GetTime() + n)&3) + // all tic are ok + continue; + DEBFILE(va("Sent %d anyway\n", realfirsttic)); + } + if (realfirsttic < firstticstosend) + realfirsttic = firstticstosend; + + // compute the length of the packet and cut it if too large + packsize = BASESERVERTICSSIZE; + for (i = realfirsttic; i < lasttictosend; i++) + { + packsize += sizeof (ticcmd_t) * doomcom->numslots; + packsize += TotalTextCmdPerTic(i); + + if (packsize > software_MAXPACKETLENGTH) + { + DEBFILE(va("packet too large (%s) at tic %d (should be from %d to %d)\n", + sizeu1(packsize), i, realfirsttic, lasttictosend)); + lasttictosend = i; + + // too bad: too much player have send extradata and there is too + // much data in one tic. + // To avoid it put the data on the next tic. (see getpacket + // textcmd case) but when numplayer changes the computation can be different + if (lasttictosend == realfirsttic) + { + if (packsize > MAXPACKETLENGTH) + I_Error("Too many players: can't send %s data for %d players to node %d\n" + "Well sorry nobody is perfect....\n", + sizeu1(packsize), doomcom->numslots, n); + else + { + lasttictosend++; // send it anyway! + DEBFILE("sending it anyway\n"); + } + } + break; + } + } + + // Send the tics + netbuffer->packettype = PT_SERVERTICS; + netbuffer->u.serverpak.starttic = realfirsttic; + netbuffer->u.serverpak.numtics = (UINT8)(lasttictosend - realfirsttic); + netbuffer->u.serverpak.numslots = (UINT8)SHORT(doomcom->numslots); + bufpos = (UINT8 *)&netbuffer->u.serverpak.cmds; + + for (i = realfirsttic; i < lasttictosend; i++) + { + bufpos = G_DcpyTiccmd(bufpos, netcmds[i%BACKUPTICS], doomcom->numslots * sizeof (ticcmd_t)); + } + + // add textcmds + for (i = realfirsttic; i < lasttictosend; i++) + { + ntextcmd = bufpos++; + *ntextcmd = 0; + for (j = 0; j < MAXPLAYERS; j++) + { + UINT8 *textcmd = D_GetExistingTextcmd(i, j); + INT32 size = textcmd ? textcmd[0] : 0; + + if ((!j || playeringame[j]) && size) + { + (*ntextcmd)++; + WRITEUINT8(bufpos, j); + M_Memcpy(bufpos, textcmd, size + 1); + bufpos += size + 1; + } + } + } + packsize = bufpos - (UINT8 *)&(netbuffer->u); + + HSendPacket(n, false, 0, packsize); + // when tic are too large, only one tic is sent so don't go backward! + if (lasttictosend-doomcom->extratics > realfirsttic) + supposedtics[n] = lasttictosend-doomcom->extratics; + else + supposedtics[n] = lasttictosend; + if (supposedtics[n] < nettics[n]) supposedtics[n] = nettics[n]; + } + // node 0 is me! + supposedtics[0] = maketic; +} + +// +// TryRunTics +// +static void Local_Maketic(INT32 realtics) +{ + I_OsPolling(); // I_Getevent + D_ProcessEvents(); // menu responder, cons responder, + // game responder calls HU_Responder, AM_Responder, + // and G_MapEventsToControls + if (!dedicated) rendergametic = gametic; + // translate inputs (keyboard/mouse/joystick) into game controls + G_BuildTiccmd(&localcmds, realtics, 1); + if (splitscreen || botingame) + G_BuildTiccmd(&localcmds2, realtics, 2); + + localcmds.angleturn |= TICCMD_RECEIVED; + localcmds2.angleturn |= TICCMD_RECEIVED; +} + +// create missed tic +static void SV_Maketic(void) +{ + INT32 i; + + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + + // We didn't receive this tic + if ((netcmds[maketic % BACKUPTICS][i].angleturn & TICCMD_RECEIVED) == 0) + { + ticcmd_t * ticcmd = &netcmds[(maketic ) % BACKUPTICS][i]; + ticcmd_t *prevticcmd = &netcmds[(maketic - 1) % BACKUPTICS][i]; + + if (players[i].quittime) + { + // Copy the angle/aiming from the previous tic + // and empty the other inputs + memset(ticcmd, 0, sizeof(netcmds[0][0])); + ticcmd->angleturn = prevticcmd->angleturn | TICCMD_RECEIVED; + ticcmd->aiming = prevticcmd->aiming; + } + else + { + DEBFILE(va("MISS tic%4d for player %d\n", maketic, i)); + // Copy the input from the previous tic + *ticcmd = *prevticcmd; + ticcmd->angleturn &= ~TICCMD_RECEIVED; + } + } + } + + // all tic are now proceed make the next + maketic++; +} + +void TryRunTics(tic_t realtics) +{ + // the machine has lagged but it is not so bad + if (realtics > TICRATE/7) // FIXME: consistency failure!! + { + if (server) + realtics = 1; + else + realtics = TICRATE/7; + } + + if (singletics) + realtics = 1; + + if (realtics >= 1) + { + COM_BufTicker(); + if (mapchangepending) + D_MapChange(-1, 0, ultimatemode, false, 2, false, fromlevelselect); // finish the map change + } + + NetUpdate(); + + if (demoplayback) + { + neededtic = gametic + (realtics * cv_playbackspeed.value); + // start a game after a demo + maketic += realtics; + firstticstosend = maketic; + tictoclear = firstticstosend; + } + + GetPackets(); + +#ifdef DEBUGFILE + if (debugfile && (realtics || neededtic > gametic)) + { + //SoM: 3/30/2000: Need long INT32 in the format string for args 4 & 5. + //Shut up stupid warning! + fprintf(debugfile, "------------ Tryruntic: REAL:%d NEED:%d GAME:%d LOAD: %d\n", + realtics, neededtic, gametic, debugload); + debugload = 100000; + } +#endif + + if (player_joining) + return; + + if (neededtic > gametic) + { + if (advancedemo) + { + if (timedemo_quit) + COM_ImmedExecute("quit"); + else + D_StartTitle(); + } + else + // run the count * tics + while (neededtic > gametic) + { + DEBFILE(va("============ Running tic %d (local %d)\n", gametic, localgametic)); + + ps_tictime = I_GetTimeMicros(); + + G_Ticker((gametic % NEWTICRATERATIO) == 0); + ExtraDataTicker(); + gametic++; + consistancy[gametic%BACKUPTICS] = Consistancy(); + + ps_tictime = I_GetTimeMicros() - ps_tictime; + + // Leave a certain amount of tics present in the net buffer as long as we've ran at least one tic this frame. + if (client && gamestate == GS_LEVEL && leveltime > 3 && neededtic <= gametic + cv_netticbuffer.value) + break; + } + } +} + +/* +Ping Update except better: +We call this once per second and check for people's pings. If their ping happens to be too high, we increment some timer and kick them out. +If they're not lagging, decrement the timer by 1. Of course, reset all of this if they leave. +*/ + +static INT32 pingtimeout[MAXPLAYERS]; + +static inline void PingUpdate(void) +{ + INT32 i; + boolean laggers[MAXPLAYERS]; + UINT8 numlaggers = 0; + memset(laggers, 0, sizeof(boolean) * MAXPLAYERS); + + netbuffer->packettype = PT_PING; + + //check for ping limit breakage. + if (cv_maxping.value) + { + for (i = 1; i < MAXPLAYERS; i++) + { + if (playeringame[i] && !players[i].quittime + && (realpingtable[i] / pingmeasurecount > (unsigned)cv_maxping.value)) + { + if (players[i].jointime > 30 * TICRATE) + laggers[i] = true; + numlaggers++; + } + else + pingtimeout[i] = 0; + } + + //kick lagging players... unless everyone but the server's ping sucks. + //in that case, it is probably the server's fault. + if (numlaggers < D_NumPlayers() - 1) + { + for (i = 1; i < MAXPLAYERS; i++) + { + if (playeringame[i] && laggers[i]) + { + pingtimeout[i]++; + // ok your net has been bad for too long, you deserve to die. + if (pingtimeout[i] > cv_pingtimeout.value) + { + pingtimeout[i] = 0; + SendKick(i, KICK_MSG_PING_HIGH | KICK_MSG_KEEP_BODY); + } + } + /* + you aren't lagging, + but you aren't free yet. + In case you'll keep spiking, + we just make the timer go back down. (Very unstable net must still get kicked). + */ + else + pingtimeout[i] = (pingtimeout[i] == 0 ? 0 : pingtimeout[i]-1); + } + } + } + + //make the ping packet and clear server data for next one + for (i = 0; i < MAXPLAYERS; i++) + { + netbuffer->u.pingtable[i] = realpingtable[i] / pingmeasurecount; + //server takes a snapshot of the real ping for display. + //otherwise, pings fluctuate a lot and would be odd to look at. + playerpingtable[i] = realpingtable[i] / pingmeasurecount; + realpingtable[i] = 0; //Reset each as we go. + } + + // send the server's maxping as last element of our ping table. This is useful to let us know when we're about to get kicked. + netbuffer->u.pingtable[MAXPLAYERS] = cv_maxping.value; + + //send out our ping packets + for (i = 0; i < MAXNETNODES; i++) + if (nodeingame[i]) + HSendPacket(i, true, 0, sizeof(INT32) * (MAXPLAYERS+1)); + + pingmeasurecount = 1; //Reset count +} + +void NetUpdate(void) +{ + static tic_t gametime = 0; + static tic_t resptime = 0; + tic_t nowtime; + INT32 i; + INT32 realtics; + + nowtime = I_GetTime(); + realtics = nowtime - gametime; + + if (realtics <= 0) // nothing new to update + return; + if (realtics > 5) + { + if (server) + realtics = 1; + else + realtics = 5; + } + + gametime = nowtime; + + if (server) + { + if (netgame && !(gametime % 35)) // update once per second. + PingUpdate(); + // update node latency values so we can take an average later. + for (i = 0; i < MAXPLAYERS; i++) + if (playeringame[i] && playernode[i] != UINT8_MAX) + realpingtable[i] += G_TicsToMilliseconds(GetLag(playernode[i])); + pingmeasurecount++; + } + + if (client) + maketic = neededtic; + + Local_Maketic(realtics); // make local tic, and call menu? + + if (server) + CL_SendClientCmd(); // send it + + GetPackets(); // get packet from client or from server + + // client send the command after a receive of the server + // the server send before because in single player is beter + +#ifdef MASTERSERVER + MasterClient_Ticker(); // Acking the Master Server +#endif + + if (client) + { + // If the client just finished redownloading the game state, load it + if (cl_redownloadinggamestate && fileneeded[0].status == FS_FOUND) + CL_ReloadReceivedSavegame(); + + CL_SendClientCmd(); // Send tic cmd + hu_redownloadinggamestate = cl_redownloadinggamestate; + } + else + { + if (!demoplayback) + { + INT32 counts; + + hu_redownloadinggamestate = false; + + firstticstosend = gametic; + for (i = 0; i < MAXNETNODES; i++) + if (nodeingame[i] && nettics[i] < firstticstosend) + { + firstticstosend = nettics[i]; + + if (maketic + 1 >= nettics[i] + BACKUPTICS) + Net_ConnectionTimeout(i); + } + + // Don't erase tics not acknowledged + counts = realtics; + + if (maketic + counts >= firstticstosend + BACKUPTICS) + counts = firstticstosend+BACKUPTICS-maketic-1; + + for (i = 0; i < counts; i++) + SV_Maketic(); // Create missed tics and increment maketic + + for (; tictoclear < firstticstosend; tictoclear++) // Clear only when acknowledged + D_Clearticcmd(tictoclear); // Clear the maketic the new tic + + SV_SendTics(); + + neededtic = maketic; // The server is a client too + } + } + + Net_AckTicker(); + + // Handle timeouts to prevent definitive freezes from happenning + if (server) + { + for (i = 1; i < MAXNETNODES; i++) + if (nodeingame[i] && freezetimeout[i] < I_GetTime()) + Net_ConnectionTimeout(i); + + // In case the cvar value was lowered + if (joindelay) + joindelay = min(joindelay - 1, 3 * (tic_t)cv_joindelay.value * TICRATE); + } + + nowtime /= NEWTICRATERATIO; + if (nowtime > resptime) + { + resptime = nowtime; +#ifdef HAVE_THREADS + I_lock_mutex(&m_menu_mutex); +#endif + M_Ticker(); +#ifdef HAVE_THREADS + I_unlock_mutex(m_menu_mutex); +#endif + CON_Ticker(); + } + + FileSendTicker(); +} + +/** Returns the number of players playing. + * \return Number of players. Can be zero if we're running a ::dedicated + * server. + * \author Graue + */ +INT32 D_NumPlayers(void) +{ + INT32 num = 0, ix; + for (ix = 0; ix < MAXPLAYERS; ix++) + if (playeringame[ix]) + num++; + return num; +} + +tic_t GetLag(INT32 node) +{ + return gametic - nettics[node]; +} + +void D_MD5PasswordPass(const UINT8 *buffer, size_t len, const char *salt, void *dest) +{ +#ifdef NOMD5 + (void)buffer; + (void)len; + (void)salt; + memset(dest, 0, 16); +#else + char tmpbuf[256]; + const size_t sl = strlen(salt); + + if (len > 256-sl) + len = 256-sl; + + memcpy(tmpbuf, buffer, len); + memmove(&tmpbuf[len], salt, sl); + //strcpy(&tmpbuf[len], salt); + len += strlen(salt); + if (len < 256) + memset(&tmpbuf[len],0,256-len); + + // Yes, we intentionally md5 the ENTIRE buffer regardless of size... + md5_buffer(tmpbuf, 256, dest); +#endif +} From edc312066dbb7b3dc7c222c490d76f836c70eb6e Mon Sep 17 00:00:00 2001 From: Shane Ellis Date: Fri, 15 Jan 2021 22:01:51 +0000 Subject: [PATCH 216/644] =?UTF-8?q?Revert=20"CL=5FRemovePlayer()=20-=20All?= =?UTF-8?q?ow=20for=20removal=20of=20non-consoleplayer=20and=E2=80=A6"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit f166af4d8b7805e1ce5688cbef386f6ddc6e3ec1 --- src/r_skins.c | 5810 +++++++------------------------------------------ 1 file changed, 760 insertions(+), 5050 deletions(-) diff --git a/src/r_skins.c b/src/r_skins.c index 88b4d9387..155a64700 100644 --- a/src/r_skins.c +++ b/src/r_skins.c @@ -1,5 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- +// Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. // Copyright (C) 1999-2020 by Sonic Team Junior. // @@ -7,5117 +8,826 @@ // terms of the GNU General Public License, version 2. // See the 'LICENSE' file for more details. //----------------------------------------------------------------------------- -/// \file d_clisrv.c -/// \brief SRB2 Network game communication and protocol, all OS independent parts. +/// \file r_skins.c +/// \brief Loading skins -#include -#ifdef __GNUC__ -#include //for unlink -#endif - -#include "i_net.h" -#include "i_system.h" -#include "i_video.h" -#include "d_net.h" -#include "d_main.h" -#include "g_game.h" -#include "st_stuff.h" -#include "hu_stuff.h" -#include "keys.h" -#include "g_input.h" // JOY1 -#include "m_menu.h" +#include "doomdef.h" #include "console.h" -#include "d_netfil.h" -#include "byteptr.h" -#include "p_saveg.h" -#include "z_zone.h" -#include "p_local.h" -#include "m_misc.h" -#include "am_map.h" -#include "m_random.h" -#include "mserv.h" -#include "y_inter.h" +#include "g_game.h" #include "r_local.h" -#include "m_argv.h" -#include "p_setup.h" -#include "lzf.h" -#include "lua_script.h" -#include "lua_hook.h" -#include "md5.h" -#include "m_perfstats.h" +#include "st_stuff.h" +#include "w_wad.h" +#include "z_zone.h" +#include "m_misc.h" +#include "info.h" // spr2names +#include "i_video.h" // rendermode +#include "i_system.h" +#include "r_things.h" +#include "r_skins.h" +#include "p_local.h" +#include "dehacked.h" // get_number (for thok) +#include "m_cond.h" +#ifdef HWRENDER +#include "hardware/hw_md2.h" +#endif -#ifndef NONET -// cl loading screen -#include "v_video.h" -#include "f_finale.h" +INT32 numskins = 0; +skin_t skins[MAXSKINS]; + +// FIXTHIS: don't work because it must be inistilised before the config load +//#define SKINVALUES +#ifdef SKINVALUES +CV_PossibleValue_t skin_cons_t[MAXSKINS+1]; #endif // -// NETWORKING +// P_GetSkinSprite2 +// For non-super players, tries each sprite2's immediate predecessor until it finds one with a number of frames or ends up at standing. +// For super players, does the same as above - but tries the super equivalent for each sprite2 before the non-super version. // -// gametic is the tic about to (or currently being) run -// Server: -// maketic is the tic that hasn't had control made for it yet -// nettics is the tic for each node -// firstticstosend is the lowest value of nettics -// Client: -// neededtic is the tic needed by the client to run the game -// firstticstosend is used to optimize a condition -// Normally maketic >= gametic > 0 -#define PREDICTIONQUEUE BACKUPTICS -#define PREDICTIONMASK (PREDICTIONQUEUE-1) -#define MAX_REASONLENGTH 30 - -boolean server = true; // true or false but !server == client -#define client (!server) -boolean nodownload = false; -boolean serverrunning = false; -INT32 serverplayer = 0; -char motd[254], server_context[8]; // Message of the Day, Unique Context (even without Mumble support) - -// Server specific vars -UINT8 playernode[MAXPLAYERS]; -char playeraddress[MAXPLAYERS][64]; - -// Minimum timeout for sending the savegame -// The actual timeout will be longer depending on the savegame length -tic_t jointimeout = (10*TICRATE); -static boolean sendingsavegame[MAXNETNODES]; // Are we sending the savegame? -static boolean resendingsavegame[MAXNETNODES]; // Are we resending the savegame? -static tic_t savegameresendcooldown[MAXNETNODES]; // How long before we can resend again? -static tic_t freezetimeout[MAXNETNODES]; // Until when can this node freeze the server before getting a timeout? - -// Incremented by cv_joindelay when a client joins, decremented each tic. -// If higher than cv_joindelay * 2 (3 joins in a short timespan), joins are temporarily disabled. -static tic_t joindelay = 0; - -UINT16 pingmeasurecount = 1; -UINT32 realpingtable[MAXPLAYERS]; //the base table of ping where an average will be sent to everyone. -UINT32 playerpingtable[MAXPLAYERS]; //table of player latency values. -SINT8 nodetoplayer[MAXNETNODES]; -SINT8 nodetoplayer2[MAXNETNODES]; // say the numplayer for this node if any (splitscreen) -UINT8 playerpernode[MAXNETNODES]; // used specialy for scplitscreen -boolean nodeingame[MAXNETNODES]; // set false as nodes leave game -tic_t servermaxping = 800; // server's max ping. Defaults to 800 -static tic_t nettics[MAXNETNODES]; // what tic the client have received -static tic_t supposedtics[MAXNETNODES]; // nettics prevision for smaller packet -static UINT8 nodewaiting[MAXNETNODES]; -static tic_t firstticstosend; // min of the nettics -static tic_t tictoclear = 0; // optimize d_clearticcmd -static tic_t maketic; - -static INT16 consistancy[BACKUPTICS]; - -static UINT8 player_joining = false; -UINT8 hu_redownloadinggamestate = 0; - -UINT8 adminpassmd5[16]; -boolean adminpasswordset = false; - -// Client specific -static ticcmd_t localcmds; -static ticcmd_t localcmds2; -static boolean cl_packetmissed; -// here it is for the secondary local player (splitscreen) -static UINT8 mynode; // my address pointofview server -static boolean cl_redownloadinggamestate = false; - -static UINT8 localtextcmd[MAXTEXTCMD]; -static UINT8 localtextcmd2[MAXTEXTCMD]; // splitscreen -static tic_t neededtic; -SINT8 servernode = 0; // the number of the server node -/// \brief do we accept new players? -/// \todo WORK! -boolean acceptnewnode = true; - -// engine - -// Must be a power of two -#define TEXTCMD_HASH_SIZE 4 - -typedef struct textcmdplayer_s +UINT8 P_GetSkinSprite2(skin_t *skin, UINT8 spr2, player_t *player) { - INT32 playernum; - UINT8 cmd[MAXTEXTCMD]; - struct textcmdplayer_s *next; -} textcmdplayer_t; + UINT8 super = 0, i = 0; -typedef struct textcmdtic_s -{ - tic_t tic; - textcmdplayer_t *playercmds[TEXTCMD_HASH_SIZE]; - struct textcmdtic_s *next; -} textcmdtic_t; - -ticcmd_t netcmds[BACKUPTICS][MAXPLAYERS]; -static textcmdtic_t *textcmds[TEXTCMD_HASH_SIZE] = {NULL}; - - -consvar_t cv_showjoinaddress = CVAR_INIT ("showjoinaddress", "Off", CV_SAVE|CV_NETVAR, CV_OnOff, NULL); - -static CV_PossibleValue_t playbackspeed_cons_t[] = {{1, "MIN"}, {10, "MAX"}, {0, NULL}}; -consvar_t cv_playbackspeed = CVAR_INIT ("playbackspeed", "1", 0, playbackspeed_cons_t, NULL); - -static inline void *G_DcpyTiccmd(void* dest, const ticcmd_t* src, const size_t n) -{ - const size_t d = n / sizeof(ticcmd_t); - const size_t r = n % sizeof(ticcmd_t); - UINT8 *ret = dest; - - if (r) - M_Memcpy(dest, src, n); - else if (d) - G_MoveTiccmd(dest, src, d); - return ret+n; -} - -static inline void *G_ScpyTiccmd(ticcmd_t* dest, void* src, const size_t n) -{ - const size_t d = n / sizeof(ticcmd_t); - const size_t r = n % sizeof(ticcmd_t); - UINT8 *ret = src; - - if (r) - M_Memcpy(dest, src, n); - else if (d) - G_MoveTiccmd(dest, src, d); - return ret+n; -} - - - -// Some software don't support largest packet -// (original sersetup, not exactely, but the probability of sending a packet -// of 512 bytes is like 0.1) -UINT16 software_MAXPACKETLENGTH; - -/** Guesses the full value of a tic from its lowest byte, for a specific node - * - * \param low The lowest byte of the tic value - * \param node The node to deduce the tic for - * \return The full tic value - * - */ -tic_t ExpandTics(INT32 low, INT32 node) -{ - INT32 delta; - - delta = low - (nettics[node] & UINT8_MAX); - - if (delta >= -64 && delta <= 64) - return (nettics[node] & ~UINT8_MAX) + low; - else if (delta > 64) - return (nettics[node] & ~UINT8_MAX) - 256 + low; - else //if (delta < -64) - return (nettics[node] & ~UINT8_MAX) + 256 + low; -} - -// ----------------------------------------------------------------- -// Some extra data function for handle textcmd buffer -// ----------------------------------------------------------------- - -static void (*listnetxcmd[MAXNETXCMD])(UINT8 **p, INT32 playernum); - -void RegisterNetXCmd(netxcmd_t id, void (*cmd_f)(UINT8 **p, INT32 playernum)) -{ -#ifdef PARANOIA - if (id >= MAXNETXCMD) - I_Error("Command id %d too big", id); - if (listnetxcmd[id] != 0) - I_Error("Command id %d already used", id); -#endif - listnetxcmd[id] = cmd_f; -} - -void SendNetXCmd(netxcmd_t id, const void *param, size_t nparam) -{ - if (localtextcmd[0]+2+nparam > MAXTEXTCMD) - { - // for future reference: if (cv_debug) != debug disabled. - CONS_Alert(CONS_ERROR, M_GetText("NetXCmd buffer full, cannot add netcmd %d! (size: %d, needed: %s)\n"), id, localtextcmd[0], sizeu1(nparam)); - return; - } - localtextcmd[0]++; - localtextcmd[localtextcmd[0]] = (UINT8)id; - if (param && nparam) - { - M_Memcpy(&localtextcmd[localtextcmd[0]+1], param, nparam); - localtextcmd[0] = (UINT8)(localtextcmd[0] + (UINT8)nparam); - } -} - -// splitscreen player -void SendNetXCmd2(netxcmd_t id, const void *param, size_t nparam) -{ - if (localtextcmd2[0]+2+nparam > MAXTEXTCMD) - { - I_Error("No more place in the buffer for netcmd %d\n",id); - return; - } - localtextcmd2[0]++; - localtextcmd2[localtextcmd2[0]] = (UINT8)id; - if (param && nparam) - { - M_Memcpy(&localtextcmd2[localtextcmd2[0]+1], param, nparam); - localtextcmd2[0] = (UINT8)(localtextcmd2[0] + (UINT8)nparam); - } -} - -UINT8 GetFreeXCmdSize(void) -{ - // -1 for the size and another -1 for the ID. - return (UINT8)(localtextcmd[0] - 2); -} - -// Frees all textcmd memory for the specified tic -static void D_FreeTextcmd(tic_t tic) -{ - textcmdtic_t **tctprev = &textcmds[tic & (TEXTCMD_HASH_SIZE - 1)]; - textcmdtic_t *textcmdtic = *tctprev; - - while (textcmdtic && textcmdtic->tic != tic) - { - tctprev = &textcmdtic->next; - textcmdtic = textcmdtic->next; - } - - if (textcmdtic) - { - INT32 i; - - // Remove this tic from the list. - *tctprev = textcmdtic->next; - - // Free all players. - for (i = 0; i < TEXTCMD_HASH_SIZE; i++) - { - textcmdplayer_t *textcmdplayer = textcmdtic->playercmds[i]; - - while (textcmdplayer) - { - textcmdplayer_t *tcpnext = textcmdplayer->next; - Z_Free(textcmdplayer); - textcmdplayer = tcpnext; - } - } - - // Free this tic's own memory. - Z_Free(textcmdtic); - } -} - -// Gets the buffer for the specified ticcmd, or NULL if there isn't one -static UINT8* D_GetExistingTextcmd(tic_t tic, INT32 playernum) -{ - textcmdtic_t *textcmdtic = textcmds[tic & (TEXTCMD_HASH_SIZE - 1)]; - while (textcmdtic && textcmdtic->tic != tic) textcmdtic = textcmdtic->next; - - // Do we have an entry for the tic? If so, look for player. - if (textcmdtic) - { - textcmdplayer_t *textcmdplayer = textcmdtic->playercmds[playernum & (TEXTCMD_HASH_SIZE - 1)]; - while (textcmdplayer && textcmdplayer->playernum != playernum) textcmdplayer = textcmdplayer->next; - - if (textcmdplayer) return textcmdplayer->cmd; - } - - return NULL; -} - -// Gets the buffer for the specified ticcmd, creating one if necessary -static UINT8* D_GetTextcmd(tic_t tic, INT32 playernum) -{ - textcmdtic_t *textcmdtic = textcmds[tic & (TEXTCMD_HASH_SIZE - 1)]; - textcmdtic_t **tctprev = &textcmds[tic & (TEXTCMD_HASH_SIZE - 1)]; - textcmdplayer_t *textcmdplayer, **tcpprev; - - // Look for the tic. - while (textcmdtic && textcmdtic->tic != tic) - { - tctprev = &textcmdtic->next; - textcmdtic = textcmdtic->next; - } - - // If we don't have an entry for the tic, make it. - if (!textcmdtic) - { - textcmdtic = *tctprev = Z_Calloc(sizeof (textcmdtic_t), PU_STATIC, NULL); - textcmdtic->tic = tic; - } - - tcpprev = &textcmdtic->playercmds[playernum & (TEXTCMD_HASH_SIZE - 1)]; - textcmdplayer = *tcpprev; - - // Look for the player. - while (textcmdplayer && textcmdplayer->playernum != playernum) - { - tcpprev = &textcmdplayer->next; - textcmdplayer = textcmdplayer->next; - } - - // If we don't have an entry for the player, make it. - if (!textcmdplayer) - { - textcmdplayer = *tcpprev = Z_Calloc(sizeof (textcmdplayer_t), PU_STATIC, NULL); - textcmdplayer->playernum = playernum; - } - - return textcmdplayer->cmd; -} - -static void ExtraDataTicker(void) -{ - INT32 i; - - for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] || i == 0) - { - UINT8 *bufferstart = D_GetExistingTextcmd(gametic, i); - - if (bufferstart) - { - UINT8 *curpos = bufferstart; - UINT8 *bufferend = &curpos[curpos[0]+1]; - - curpos++; - while (curpos < bufferend) - { - if (*curpos < MAXNETXCMD && listnetxcmd[*curpos]) - { - const UINT8 id = *curpos; - curpos++; - DEBFILE(va("executing x_cmd %s ply %u ", netxcmdnames[id - 1], i)); - (listnetxcmd[id])(&curpos, i); - DEBFILE("done\n"); - } - else - { - if (server) - { - SendKick(i, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY); - DEBFILE(va("player %d kicked [gametic=%u] reason as follows:\n", i, gametic)); - } - CONS_Alert(CONS_WARNING, M_GetText("Got unknown net command [%s]=%d (max %d)\n"), sizeu1(curpos - bufferstart), *curpos, bufferstart[0]); - break; - } - } - } - } - - // If you are a client, you can safely forget the net commands for this tic - // If you are the server, you need to remember them until every client has been acknowledged, - // because if you need to resend a PT_SERVERTICS packet, you will need to put the commands in it - if (client) - D_FreeTextcmd(gametic); -} - -static void D_Clearticcmd(tic_t tic) -{ - INT32 i; - - D_FreeTextcmd(tic); - - for (i = 0; i < MAXPLAYERS; i++) - netcmds[tic%BACKUPTICS][i].angleturn = 0; - - DEBFILE(va("clear tic %5u (%2u)\n", tic, tic%BACKUPTICS)); -} - -void D_ResetTiccmds(void) -{ - INT32 i; - - memset(&localcmds, 0, sizeof(ticcmd_t)); - memset(&localcmds2, 0, sizeof(ticcmd_t)); - - // Reset the net command list - for (i = 0; i < TEXTCMD_HASH_SIZE; i++) - while (textcmds[i]) - D_Clearticcmd(textcmds[i]->tic); -} - -void SendKick(UINT8 playernum, UINT8 msg) -{ - UINT8 buf[2]; - - if (!(server && cv_rejointimeout.value)) - msg &= ~KICK_MSG_KEEP_BODY; - - buf[0] = playernum; - buf[1] = msg; - SendNetXCmd(XD_KICK, &buf, 2); -} - -// ----------------------------------------------------------------- -// end of extra data function -// ----------------------------------------------------------------- - -// ----------------------------------------------------------------- -// extra data function for lmps -// ----------------------------------------------------------------- - -// if extradatabit is set, after the ziped tic you find this: -// -// type | description -// ---------+-------------- -// byte | size of the extradata -// byte | the extradata (xd) bits: see XD_... -// with this byte you know what parameter folow -// if (xd & XDNAMEANDCOLOR) -// byte | color -// char[MAXPLAYERNAME] | name of the player -// endif -// if (xd & XD_WEAPON_PREF) -// byte | original weapon switch: boolean, true if use the old -// | weapon switch methode -// char[NUMWEAPONS] | the weapon switch priority -// byte | autoaim: true if use the old autoaim system -// endif -/*boolean AddLmpExtradata(UINT8 **demo_point, INT32 playernum) -{ - UINT8 *textcmd = D_GetExistingTextcmd(gametic, playernum); - - if (!textcmd) - return false; - - M_Memcpy(*demo_point, textcmd, textcmd[0]+1); - *demo_point += textcmd[0]+1; - return true; -} - -void ReadLmpExtraData(UINT8 **demo_pointer, INT32 playernum) -{ - UINT8 nextra; - UINT8 *textcmd; - - if (!demo_pointer) - return; - - textcmd = D_GetTextcmd(gametic, playernum); - nextra = **demo_pointer; - M_Memcpy(textcmd, *demo_pointer, nextra + 1); - // increment demo pointer - *demo_pointer += nextra + 1; -}*/ - -// ----------------------------------------------------------------- -// end extra data function for lmps -// ----------------------------------------------------------------- - -static INT16 Consistancy(void); - -typedef enum -{ - CL_SEARCHING, - CL_DOWNLOADFILES, - CL_ASKJOIN, - CL_WAITJOINRESPONSE, - CL_DOWNLOADSAVEGAME, - CL_CONNECTED, - CL_ABORTED -} cl_mode_t; - -static void GetPackets(void); - -static cl_mode_t cl_mode = CL_SEARCHING; - -#ifndef NONET -#define SNAKE_SPEED 5 - -#define SNAKE_NUM_BLOCKS_X 20 -#define SNAKE_NUM_BLOCKS_Y 10 -#define SNAKE_BLOCK_SIZE 12 -#define SNAKE_BORDER_SIZE 12 - -#define SNAKE_MAP_WIDTH (SNAKE_NUM_BLOCKS_X * SNAKE_BLOCK_SIZE) -#define SNAKE_MAP_HEIGHT (SNAKE_NUM_BLOCKS_Y * SNAKE_BLOCK_SIZE) - -#define SNAKE_LEFT_X ((BASEVIDWIDTH - SNAKE_MAP_WIDTH) / 2 - SNAKE_BORDER_SIZE) -#define SNAKE_RIGHT_X (SNAKE_LEFT_X + SNAKE_MAP_WIDTH + SNAKE_BORDER_SIZE * 2 - 1) -#define SNAKE_BOTTOM_Y (BASEVIDHEIGHT - 48) -#define SNAKE_TOP_Y (SNAKE_BOTTOM_Y - SNAKE_MAP_HEIGHT - SNAKE_BORDER_SIZE * 2 + 1) - -enum snake_bonustype_s { - SNAKE_BONUS_NONE = 0, - SNAKE_BONUS_SLOW, - SNAKE_BONUS_FAST, - SNAKE_BONUS_GHOST, - SNAKE_BONUS_NUKE, - SNAKE_BONUS_SCISSORS, - SNAKE_BONUS_REVERSE, - SNAKE_BONUS_EGGMAN, - SNAKE_NUM_BONUSES, -}; - -static const char *snake_bonuspatches[] = { - NULL, - "DL_SLOW", - "TVSSC0", - "TVIVC0", - "TVARC0", - "DL_SCISSORS", - "TVRCC0", - "TVEGC0", -}; - -static const char *snake_backgrounds[] = { - "RVPUMICF", - "FRSTRCKF", - "TAR", - "MMFLRB4", - "RVDARKF1", - "RVZWALF1", - "RVZWALF4", - "RVZWALF5", - "RVZGRS02", - "RVZGRS04", -}; - -typedef struct snake_s -{ - boolean paused; - boolean pausepressed; - tic_t time; - tic_t nextupdate; - boolean gameover; - UINT8 background; - - UINT16 snakelength; - enum snake_bonustype_s snakebonus; - tic_t snakebonustime; - UINT8 snakex[SNAKE_NUM_BLOCKS_X * SNAKE_NUM_BLOCKS_Y]; - UINT8 snakey[SNAKE_NUM_BLOCKS_X * SNAKE_NUM_BLOCKS_Y]; - UINT8 snakedir[SNAKE_NUM_BLOCKS_X * SNAKE_NUM_BLOCKS_Y]; - - UINT8 applex; - UINT8 appley; - - enum snake_bonustype_s bonustype; - UINT8 bonusx; - UINT8 bonusy; -} snake_t; - -static snake_t *snake = NULL; - -static void Snake_Initialise(void) -{ - if (!snake) - snake = malloc(sizeof(snake_t)); - - snake->paused = false; - snake->pausepressed = false; - snake->time = 0; - snake->nextupdate = SNAKE_SPEED; - snake->gameover = false; - snake->background = M_RandomKey(sizeof(snake_backgrounds) / sizeof(*snake_backgrounds)); - - snake->snakelength = 1; - snake->snakebonus = SNAKE_BONUS_NONE; - snake->snakex[0] = M_RandomKey(SNAKE_NUM_BLOCKS_X); - snake->snakey[0] = M_RandomKey(SNAKE_NUM_BLOCKS_Y); - snake->snakedir[0] = 0; - snake->snakedir[1] = 0; - - snake->applex = M_RandomKey(SNAKE_NUM_BLOCKS_X); - snake->appley = M_RandomKey(SNAKE_NUM_BLOCKS_Y); - - snake->bonustype = SNAKE_BONUS_NONE; -} - -static UINT8 Snake_GetOppositeDir(UINT8 dir) -{ - if (dir == 1 || dir == 3) - return dir + 1; - else if (dir == 2 || dir == 4) - return dir - 1; - else - return 12 + 5 - dir; -} - -static void Snake_FindFreeSlot(UINT8 *freex, UINT8 *freey, UINT8 headx, UINT8 heady) -{ - UINT8 x, y; - UINT16 i; - - do - { - x = M_RandomKey(SNAKE_NUM_BLOCKS_X); - y = M_RandomKey(SNAKE_NUM_BLOCKS_Y); - - for (i = 0; i < snake->snakelength; i++) - if (x == snake->snakex[i] && y == snake->snakey[i]) - break; - } while (i < snake->snakelength || (x == headx && y == heady) - || (x == snake->applex && y == snake->appley) - || (snake->bonustype != SNAKE_BONUS_NONE && x == snake->bonusx && y == snake->bonusy)); - - *freex = x; - *freey = y; -} - -static void Snake_Handle(void) -{ - UINT8 x, y; - UINT8 oldx, oldy; - UINT16 i; - - // Handle retry - if (snake->gameover && (PLAYER1INPUTDOWN(gc_jump) || gamekeydown[KEY_ENTER])) - { - Snake_Initialise(); - snake->pausepressed = true; // Avoid accidental pause on respawn - } - - // Handle pause - if (PLAYER1INPUTDOWN(gc_pause) || gamekeydown[KEY_ENTER]) - { - if (!snake->pausepressed) - snake->paused = !snake->paused; - snake->pausepressed = true; - } - else - snake->pausepressed = false; - - if (snake->paused) - return; - - snake->time++; - - x = snake->snakex[0]; - y = snake->snakey[0]; - oldx = snake->snakex[1]; - oldy = snake->snakey[1]; - - // Update direction - if (gamekeydown[KEY_LEFTARROW]) - { - if (snake->snakelength < 2 || x <= oldx) - snake->snakedir[0] = 1; - } - else if (gamekeydown[KEY_RIGHTARROW]) - { - if (snake->snakelength < 2 || x >= oldx) - snake->snakedir[0] = 2; - } - else if (gamekeydown[KEY_UPARROW]) - { - if (snake->snakelength < 2 || y <= oldy) - snake->snakedir[0] = 3; - } - else if (gamekeydown[KEY_DOWNARROW]) - { - if (snake->snakelength < 2 || y >= oldy) - snake->snakedir[0] = 4; - } - - if (snake->snakebonustime) - { - snake->snakebonustime--; - if (!snake->snakebonustime) - snake->snakebonus = SNAKE_BONUS_NONE; - } - - snake->nextupdate--; - if (snake->nextupdate) - return; - if (snake->snakebonus == SNAKE_BONUS_SLOW) - snake->nextupdate = SNAKE_SPEED * 2; - else if (snake->snakebonus == SNAKE_BONUS_FAST) - snake->nextupdate = SNAKE_SPEED * 2 / 3; - else - snake->nextupdate = SNAKE_SPEED; - - if (snake->gameover) - return; - - // Find new position - switch (snake->snakedir[0]) - { - case 1: - if (x > 0) - x--; - else - snake->gameover = true; - break; - case 2: - if (x < SNAKE_NUM_BLOCKS_X - 1) - x++; - else - snake->gameover = true; - break; - case 3: - if (y > 0) - y--; - else - snake->gameover = true; - break; - case 4: - if (y < SNAKE_NUM_BLOCKS_Y - 1) - y++; - else - snake->gameover = true; - break; - } - - // Check collision with snake - if (snake->snakebonus != SNAKE_BONUS_GHOST) - for (i = 1; i < snake->snakelength - 1; i++) - if (x == snake->snakex[i] && y == snake->snakey[i]) - { - if (snake->snakebonus == SNAKE_BONUS_SCISSORS) - { - snake->snakebonus = SNAKE_BONUS_NONE; - snake->snakelength = i; - S_StartSound(NULL, sfx_adderr); - } - else - snake->gameover = true; - } - - if (snake->gameover) - { - S_StartSound(NULL, sfx_lose); - return; - } - - // Check collision with apple - if (x == snake->applex && y == snake->appley) - { - if (snake->snakelength + 3 < SNAKE_NUM_BLOCKS_X * SNAKE_NUM_BLOCKS_Y) - { - snake->snakelength++; - snake->snakex [snake->snakelength - 1] = snake->snakex [snake->snakelength - 2]; - snake->snakey [snake->snakelength - 1] = snake->snakey [snake->snakelength - 2]; - snake->snakedir[snake->snakelength - 1] = snake->snakedir[snake->snakelength - 2]; - } - - // Spawn new apple - Snake_FindFreeSlot(&snake->applex, &snake->appley, x, y); - - // Spawn new bonus - if (!(snake->snakelength % 5)) - { - do - { - snake->bonustype = M_RandomKey(SNAKE_NUM_BONUSES - 1) + 1; - } while (snake->snakelength > SNAKE_NUM_BLOCKS_X * SNAKE_NUM_BLOCKS_Y * 3 / 4 - && (snake->bonustype == SNAKE_BONUS_EGGMAN || snake->bonustype == SNAKE_BONUS_FAST || snake->bonustype == SNAKE_BONUS_REVERSE)); - - Snake_FindFreeSlot(&snake->bonusx, &snake->bonusy, x, y); - } - - S_StartSound(NULL, sfx_s3k6b); - } - - if (snake->snakelength > 1 && snake->snakedir[0]) - { - UINT8 dir = snake->snakedir[0]; - - oldx = snake->snakex[1]; - oldy = snake->snakey[1]; - - // Move - for (i = snake->snakelength - 1; i > 0; i--) - { - snake->snakex[i] = snake->snakex[i - 1]; - snake->snakey[i] = snake->snakey[i - 1]; - snake->snakedir[i] = snake->snakedir[i - 1]; - } - - // Handle corners - if (x < oldx && dir == 3) - dir = 5; - else if (x > oldx && dir == 3) - dir = 6; - else if (x < oldx && dir == 4) - dir = 7; - else if (x > oldx && dir == 4) - dir = 8; - else if (y < oldy && dir == 1) - dir = 9; - else if (y < oldy && dir == 2) - dir = 10; - else if (y > oldy && dir == 1) - dir = 11; - else if (y > oldy && dir == 2) - dir = 12; - snake->snakedir[1] = dir; - } - - snake->snakex[0] = x; - snake->snakey[0] = y; - - // Check collision with bonus - if (snake->bonustype != SNAKE_BONUS_NONE && x == snake->bonusx && y == snake->bonusy) - { - S_StartSound(NULL, sfx_ncchip); - - switch (snake->bonustype) - { - case SNAKE_BONUS_SLOW: - snake->snakebonus = SNAKE_BONUS_SLOW; - snake->snakebonustime = 20 * TICRATE; - break; - case SNAKE_BONUS_FAST: - snake->snakebonus = SNAKE_BONUS_FAST; - snake->snakebonustime = 20 * TICRATE; - break; - case SNAKE_BONUS_GHOST: - snake->snakebonus = SNAKE_BONUS_GHOST; - snake->snakebonustime = 10 * TICRATE; - break; - case SNAKE_BONUS_NUKE: - for (i = 0; i < snake->snakelength; i++) - { - snake->snakex [i] = snake->snakex [0]; - snake->snakey [i] = snake->snakey [0]; - snake->snakedir[i] = snake->snakedir[0]; - } - - S_StartSound(NULL, sfx_bkpoof); - break; - case SNAKE_BONUS_SCISSORS: - snake->snakebonus = SNAKE_BONUS_SCISSORS; - snake->snakebonustime = 60 * TICRATE; - break; - case SNAKE_BONUS_REVERSE: - for (i = 0; i < (snake->snakelength + 1) / 2; i++) - { - UINT16 i2 = snake->snakelength - 1 - i; - UINT8 tmpx = snake->snakex [i]; - UINT8 tmpy = snake->snakey [i]; - UINT8 tmpdir = snake->snakedir[i]; - - // Swap first segment with last segment - snake->snakex [i] = snake->snakex [i2]; - snake->snakey [i] = snake->snakey [i2]; - snake->snakedir[i] = Snake_GetOppositeDir(snake->snakedir[i2]); - snake->snakex [i2] = tmpx; - snake->snakey [i2] = tmpy; - snake->snakedir[i2] = Snake_GetOppositeDir(tmpdir); - } - - snake->snakedir[0] = 0; - - S_StartSound(NULL, sfx_gravch); - break; - default: - if (snake->snakebonus != SNAKE_BONUS_GHOST) - { - snake->gameover = true; - S_StartSound(NULL, sfx_lose); - } - } - - snake->bonustype = SNAKE_BONUS_NONE; - } -} - -static void Snake_Draw(void) -{ - INT16 i; - - // Background - V_DrawFlatFill( - SNAKE_LEFT_X + SNAKE_BORDER_SIZE, - SNAKE_TOP_Y + SNAKE_BORDER_SIZE, - SNAKE_MAP_WIDTH, - SNAKE_MAP_HEIGHT, - W_GetNumForName(snake_backgrounds[snake->background]) - ); - - // Borders - V_DrawFill(SNAKE_LEFT_X, SNAKE_TOP_Y, SNAKE_BORDER_SIZE + SNAKE_MAP_WIDTH, SNAKE_BORDER_SIZE, 242); // Top - V_DrawFill(SNAKE_LEFT_X + SNAKE_BORDER_SIZE + SNAKE_MAP_WIDTH, SNAKE_TOP_Y, SNAKE_BORDER_SIZE, SNAKE_BORDER_SIZE + SNAKE_MAP_HEIGHT, 242); // Right - V_DrawFill(SNAKE_LEFT_X + SNAKE_BORDER_SIZE, SNAKE_TOP_Y + SNAKE_BORDER_SIZE + SNAKE_MAP_HEIGHT, SNAKE_BORDER_SIZE + SNAKE_MAP_WIDTH, SNAKE_BORDER_SIZE, 242); // Bottom - V_DrawFill(SNAKE_LEFT_X, SNAKE_TOP_Y + SNAKE_BORDER_SIZE, SNAKE_BORDER_SIZE, SNAKE_BORDER_SIZE + SNAKE_MAP_HEIGHT, 242); // Left - - // Apple - V_DrawFixedPatch( - (SNAKE_LEFT_X + SNAKE_BORDER_SIZE + snake->applex * SNAKE_BLOCK_SIZE + SNAKE_BLOCK_SIZE / 2) * FRACUNIT, - (SNAKE_TOP_Y + SNAKE_BORDER_SIZE + snake->appley * SNAKE_BLOCK_SIZE + SNAKE_BLOCK_SIZE / 2) * FRACUNIT, - FRACUNIT / 4, - 0, - W_CachePatchLongName("DL_APPLE", PU_HUDGFX), - NULL - ); - - // Bonus - if (snake->bonustype != SNAKE_BONUS_NONE) - V_DrawFixedPatch( - (SNAKE_LEFT_X + SNAKE_BORDER_SIZE + snake->bonusx * SNAKE_BLOCK_SIZE + SNAKE_BLOCK_SIZE / 2 ) * FRACUNIT, - (SNAKE_TOP_Y + SNAKE_BORDER_SIZE + snake->bonusy * SNAKE_BLOCK_SIZE + SNAKE_BLOCK_SIZE / 2 + 4) * FRACUNIT, - FRACUNIT / 2, - 0, - W_CachePatchLongName(snake_bonuspatches[snake->bonustype], PU_HUDGFX), - NULL - ); - - // Snake - if (!snake->gameover || snake->time % 8 < 8 / 2) // Blink if game over - { - for (i = snake->snakelength - 1; i >= 0; i--) - { - const char *patchname; - UINT8 dir = snake->snakedir[i]; - - if (i == 0) // Head - { - switch (dir) - { - case 1: patchname = "DL_SNAKEHEAD_L"; break; - case 2: patchname = "DL_SNAKEHEAD_R"; break; - case 3: patchname = "DL_SNAKEHEAD_T"; break; - case 4: patchname = "DL_SNAKEHEAD_B"; break; - default: patchname = "DL_SNAKEHEAD_M"; - } - } - else // Body - { - switch (dir) - { - case 1: patchname = "DL_SNAKEBODY_L"; break; - case 2: patchname = "DL_SNAKEBODY_R"; break; - case 3: patchname = "DL_SNAKEBODY_T"; break; - case 4: patchname = "DL_SNAKEBODY_B"; break; - case 5: patchname = "DL_SNAKEBODY_LT"; break; - case 6: patchname = "DL_SNAKEBODY_RT"; break; - case 7: patchname = "DL_SNAKEBODY_LB"; break; - case 8: patchname = "DL_SNAKEBODY_RB"; break; - case 9: patchname = "DL_SNAKEBODY_TL"; break; - case 10: patchname = "DL_SNAKEBODY_TR"; break; - case 11: patchname = "DL_SNAKEBODY_BL"; break; - case 12: patchname = "DL_SNAKEBODY_BR"; break; - default: patchname = "DL_SNAKEBODY_B"; - } - } - - V_DrawFixedPatch( - (SNAKE_LEFT_X + SNAKE_BORDER_SIZE + snake->snakex[i] * SNAKE_BLOCK_SIZE + SNAKE_BLOCK_SIZE / 2) * FRACUNIT, - (SNAKE_TOP_Y + SNAKE_BORDER_SIZE + snake->snakey[i] * SNAKE_BLOCK_SIZE + SNAKE_BLOCK_SIZE / 2) * FRACUNIT, - i == 0 && dir == 0 ? FRACUNIT / 5 : FRACUNIT / 2, - snake->snakebonus == SNAKE_BONUS_GHOST ? V_TRANSLUCENT : 0, - W_CachePatchLongName(patchname, PU_HUDGFX), - NULL - ); - } - } - - // Length - V_DrawString(SNAKE_RIGHT_X + 4, SNAKE_TOP_Y, V_MONOSPACE, va("%u", snake->snakelength)); - - // Bonus - if (snake->snakebonus != SNAKE_BONUS_NONE - && (snake->snakebonustime >= 3 * TICRATE || snake->time % 4 < 4 / 2)) - V_DrawFixedPatch( - (SNAKE_RIGHT_X + 10) * FRACUNIT, - (SNAKE_TOP_Y + 24) * FRACUNIT, - FRACUNIT / 2, - 0, - W_CachePatchLongName(snake_bonuspatches[snake->snakebonus], PU_HUDGFX), - NULL - ); -} - -// -// CL_DrawConnectionStatus -// -// Keep the local client informed of our status. -// -static inline void CL_DrawConnectionStatus(void) -{ - INT32 ccstime = I_GetTime(); - - // Draw background fade - if (!menuactive) // menu already draws its own fade - V_DrawFadeScreen(0xFF00, 16); // force default - - // Draw the bottom box. - M_DrawTextBox(BASEVIDWIDTH/2-128-8, BASEVIDHEIGHT-16-8, 32, 1); - V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-16-16, V_YELLOWMAP, "Press ESC to abort"); - - if (cl_mode != CL_DOWNLOADFILES) - { - INT32 i, animtime = ((ccstime / 4) & 15) + 16; - UINT8 palstart = (cl_mode == CL_SEARCHING) ? 32 : 96; - // 15 pal entries total. - const char *cltext; - - if (!(cl_mode == CL_DOWNLOADSAVEGAME && lastfilenum != -1)) - for (i = 0; i < 16; ++i) - V_DrawFill((BASEVIDWIDTH/2-128) + (i * 16), BASEVIDHEIGHT-16, 16, 8, palstart + ((animtime - i) & 15)); - - switch (cl_mode) - { - case CL_DOWNLOADSAVEGAME: - if (lastfilenum != -1) - { - UINT32 currentsize = fileneeded[lastfilenum].currentsize; - UINT32 totalsize = fileneeded[lastfilenum].totalsize; - INT32 dldlength; - - cltext = M_GetText("Downloading game state..."); - Net_GetNetStat(); - - dldlength = (INT32)((currentsize/(double)totalsize) * 256); - if (dldlength > 256) - dldlength = 256; - V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-16, 256, 8, 111); - V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-16, dldlength, 8, 96); - - V_DrawString(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-16, V_20TRANS|V_MONOSPACE, - va(" %4uK/%4uK",currentsize>>10,totalsize>>10)); - - V_DrawRightAlignedString(BASEVIDWIDTH/2+128, BASEVIDHEIGHT-16, V_20TRANS|V_MONOSPACE, - va("%3.1fK/s ", ((double)getbps)/1024)); - } - else - cltext = M_GetText("Waiting to download game state..."); - break; - case CL_ASKJOIN: - case CL_WAITJOINRESPONSE: - cltext = M_GetText("Requesting to join..."); - break; - default: - cltext = M_GetText("Connecting to server..."); - break; - } - V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-16-24, V_YELLOWMAP, cltext); - } - else - { - if (lastfilenum != -1) - { - INT32 dldlength; - static char tempname[28]; - fileneeded_t *file = &fileneeded[lastfilenum]; - char *filename = file->filename; - - Snake_Draw(); - - Net_GetNetStat(); - dldlength = (INT32)((file->currentsize/(double)file->totalsize) * 256); - if (dldlength > 256) - dldlength = 256; - V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-16, 256, 8, 111); - V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-16, dldlength, 8, 96); - - memset(tempname, 0, sizeof(tempname)); - // offset filename to just the name only part - filename += strlen(filename) - nameonlylength(filename); - - if (strlen(filename) > sizeof(tempname)-1) // too long to display fully - { - size_t endhalfpos = strlen(filename)-10; - // display as first 14 chars + ... + last 10 chars - // which should add up to 27 if our math(s) is correct - snprintf(tempname, sizeof(tempname), "%.14s...%.10s", filename, filename+endhalfpos); - } - else // we can copy the whole thing in safely - { - strncpy(tempname, filename, sizeof(tempname)-1); - } - - V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-16-24, V_YELLOWMAP, - va(M_GetText("Downloading \"%s\""), tempname)); - V_DrawString(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-16, V_20TRANS|V_MONOSPACE, - va(" %4uK/%4uK",fileneeded[lastfilenum].currentsize>>10,file->totalsize>>10)); - V_DrawRightAlignedString(BASEVIDWIDTH/2+128, BASEVIDHEIGHT-16, V_20TRANS|V_MONOSPACE, - va("%3.1fK/s ", ((double)getbps)/1024)); - } - else - V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-16-24, V_YELLOWMAP, - M_GetText("Waiting to download files...")); - } -} -#endif - -/** Sends a special packet to declare how many players in local - * Used only in arbitratrenetstart() - * Sends a PT_CLIENTJOIN packet to the server - * - * \return True if the packet was successfully sent - * \todo Improve the description... - * Because to be honest, I have no idea what arbitratrenetstart is... - * Is it even used...? - * - */ -static boolean CL_SendJoin(void) -{ - UINT8 localplayers = 1; - if (netgame) - CONS_Printf(M_GetText("Sending join request...\n")); - netbuffer->packettype = PT_CLIENTJOIN; - - if (splitscreen || botingame) - localplayers++; - netbuffer->u.clientcfg.localplayers = localplayers; - netbuffer->u.clientcfg._255 = 255; - netbuffer->u.clientcfg.packetversion = PACKETVERSION; - netbuffer->u.clientcfg.version = VERSION; - netbuffer->u.clientcfg.subversion = SUBVERSION; - strncpy(netbuffer->u.clientcfg.application, SRB2APPLICATION, - sizeof netbuffer->u.clientcfg.application); - - CleanupPlayerName(consoleplayer, cv_playername.zstring); - if (splitscreen) - CleanupPlayerName(1, cv_playername2.zstring);/* 1 is a HACK? oh no */ - - strncpy(netbuffer->u.clientcfg.names[0], cv_playername.zstring, MAXPLAYERNAME); - strncpy(netbuffer->u.clientcfg.names[1], cv_playername2.zstring, MAXPLAYERNAME); - - return HSendPacket(servernode, true, 0, sizeof (clientconfig_pak)); -} - -static INT32 FindRejoinerNum(SINT8 node) -{ - char strippednodeaddress[64]; - const char *nodeaddress; - char *port; - INT32 i; - - // Make sure there is no dead dress before proceeding to the stripping - if (!I_GetNodeAddress) - return -1; - nodeaddress = I_GetNodeAddress(node); - if (!nodeaddress) - return -1; - - // Strip the address of its port - strcpy(strippednodeaddress, nodeaddress); - port = strchr(strippednodeaddress, ':'); - if (port) - *port = '\0'; - - // Check if any player matches the stripped address - for (i = 0; i < MAXPLAYERS; i++) - { - if (playeringame[i] && playeraddress[i][0] && playernode[i] == UINT8_MAX - && !strcmp(playeraddress[i], strippednodeaddress)) - return i; - } - - return -1; -} - -static void SV_SendServerInfo(INT32 node, tic_t servertime) -{ - UINT8 *p; - - netbuffer->packettype = PT_SERVERINFO; - netbuffer->u.serverinfo._255 = 255; - netbuffer->u.serverinfo.packetversion = PACKETVERSION; - netbuffer->u.serverinfo.version = VERSION; - netbuffer->u.serverinfo.subversion = SUBVERSION; - strncpy(netbuffer->u.serverinfo.application, SRB2APPLICATION, - sizeof netbuffer->u.serverinfo.application); - // return back the time value so client can compute their ping - netbuffer->u.serverinfo.time = (tic_t)LONG(servertime); - netbuffer->u.serverinfo.leveltime = (tic_t)LONG(leveltime); - - netbuffer->u.serverinfo.numberofplayer = (UINT8)D_NumPlayers(); - netbuffer->u.serverinfo.maxplayer = (UINT8)cv_maxplayers.value; - - if (!node || FindRejoinerNum(node) != -1) - netbuffer->u.serverinfo.refusereason = 0; - else if (!cv_allownewplayer.value) - netbuffer->u.serverinfo.refusereason = 1; - else if (D_NumPlayers() >= cv_maxplayers.value) - netbuffer->u.serverinfo.refusereason = 2; - else - netbuffer->u.serverinfo.refusereason = 0; - - strncpy(netbuffer->u.serverinfo.gametypename, Gametype_Names[gametype], - sizeof netbuffer->u.serverinfo.gametypename); - netbuffer->u.serverinfo.modifiedgame = (UINT8)modifiedgame; - netbuffer->u.serverinfo.cheatsenabled = CV_CheatsEnabled(); - netbuffer->u.serverinfo.isdedicated = (UINT8)dedicated; - strncpy(netbuffer->u.serverinfo.servername, cv_servername.string, - MAXSERVERNAME); - strncpy(netbuffer->u.serverinfo.mapname, G_BuildMapName(gamemap), 7); - - M_Memcpy(netbuffer->u.serverinfo.mapmd5, mapmd5, 16); - - memset(netbuffer->u.serverinfo.maptitle, 0, sizeof netbuffer->u.serverinfo.maptitle); - - if (mapheaderinfo[gamemap-1] && *mapheaderinfo[gamemap-1]->lvlttl) - { - char *read = mapheaderinfo[gamemap-1]->lvlttl, *writ = netbuffer->u.serverinfo.maptitle; - while (writ < (netbuffer->u.serverinfo.maptitle+32) && *read != '\0') - { - if (!(*read & 0x80)) - { - *writ = toupper(*read); - writ++; - } - read++; - } - *writ = '\0'; - //strncpy(netbuffer->u.serverinfo.maptitle, (char *)mapheaderinfo[gamemap-1]->lvlttl, 33); - } - else - strncpy(netbuffer->u.serverinfo.maptitle, "UNKNOWN", 32); - - if (mapheaderinfo[gamemap-1] && !(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE)) - netbuffer->u.serverinfo.iszone = 1; - else - netbuffer->u.serverinfo.iszone = 0; - - if (mapheaderinfo[gamemap-1]) - netbuffer->u.serverinfo.actnum = mapheaderinfo[gamemap-1]->actnum; - - p = PutFileNeeded(); - - HSendPacket(node, false, 0, p - ((UINT8 *)&netbuffer->u)); -} - -static void SV_SendPlayerInfo(INT32 node) -{ - UINT8 i; - netbuffer->packettype = PT_PLAYERINFO; - - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i]) - { - netbuffer->u.playerinfo[i].num = 255; // This slot is empty. - continue; - } - - netbuffer->u.playerinfo[i].num = i; - strncpy(netbuffer->u.playerinfo[i].name, (const char *)&player_names[i], MAXPLAYERNAME+1); - netbuffer->u.playerinfo[i].name[MAXPLAYERNAME] = '\0'; - - //fetch IP address - //No, don't do that, you fuckface. - memset(netbuffer->u.playerinfo[i].address, 0, 4); - - if (G_GametypeHasTeams()) - { - if (!players[i].ctfteam) - netbuffer->u.playerinfo[i].team = 255; - else - netbuffer->u.playerinfo[i].team = (UINT8)players[i].ctfteam; - } - else - { - if (players[i].spectator) - netbuffer->u.playerinfo[i].team = 255; - else - netbuffer->u.playerinfo[i].team = 0; - } - - netbuffer->u.playerinfo[i].score = LONG(players[i].score); - netbuffer->u.playerinfo[i].timeinserver = SHORT((UINT16)(players[i].jointime / TICRATE)); - netbuffer->u.playerinfo[i].skin = (UINT8)(players[i].skin -#ifdef DEVELOP // it's safe to do this only because PLAYERINFO isn't read by the game itself - % 3 -#endif - ); - - // Extra data - netbuffer->u.playerinfo[i].data = 0; //players[i].skincolor; - - if (players[i].pflags & PF_TAGIT) - netbuffer->u.playerinfo[i].data |= 0x20; - - if (players[i].gotflag) - netbuffer->u.playerinfo[i].data |= 0x40; - - if (players[i].powers[pw_super]) - netbuffer->u.playerinfo[i].data |= 0x80; - } - - HSendPacket(node, false, 0, sizeof(plrinfo) * MAXPLAYERS); -} - -/** Sends a PT_SERVERCFG packet - * - * \param node The destination - * \return True if the packet was successfully sent - * - */ -static boolean SV_SendServerConfig(INT32 node) -{ - boolean waspacketsent; - - netbuffer->packettype = PT_SERVERCFG; - - netbuffer->u.servercfg.version = VERSION; - netbuffer->u.servercfg.subversion = SUBVERSION; - - netbuffer->u.servercfg.serverplayer = (UINT8)serverplayer; - netbuffer->u.servercfg.totalslotnum = (UINT8)(doomcom->numslots); - netbuffer->u.servercfg.gametic = (tic_t)LONG(gametic); - netbuffer->u.servercfg.clientnode = (UINT8)node; - netbuffer->u.servercfg.gamestate = (UINT8)gamestate; - netbuffer->u.servercfg.gametype = (UINT8)gametype; - netbuffer->u.servercfg.modifiedgame = (UINT8)modifiedgame; - - memcpy(netbuffer->u.servercfg.server_context, server_context, 8); - - { - const size_t len = sizeof (serverconfig_pak); - -#ifdef DEBUGFILE - if (debugfile) - { - fprintf(debugfile, "ServerConfig Packet about to be sent, size of packet:%s to node:%d\n", - sizeu1(len), node); - } -#endif - - waspacketsent = HSendPacket(node, true, 0, len); - } - -#ifdef DEBUGFILE - if (debugfile) - { - if (waspacketsent) - { - fprintf(debugfile, "ServerConfig Packet was sent\n"); - } - else - { - fprintf(debugfile, "ServerConfig Packet could not be sent right now\n"); - } - } -#endif - - return waspacketsent; -} - -#ifndef NONET -#define SAVEGAMESIZE (768*1024) - -static boolean SV_ResendingSavegameToAnyone(void) -{ - INT32 i; - - for (i = 0; i < MAXNETNODES; i++) - if (resendingsavegame[i]) - return true; - return false; -} - -static void SV_SendSaveGame(INT32 node, boolean resending) -{ - size_t length, compressedlen; - UINT8 *savebuffer; - UINT8 *compressedsave; - UINT8 *buffertosend; - - // first save it in a malloced buffer - savebuffer = (UINT8 *)malloc(SAVEGAMESIZE); - if (!savebuffer) - { - CONS_Alert(CONS_ERROR, M_GetText("No more free memory for savegame\n")); - return; - } - - // Leave room for the uncompressed length. - save_p = savebuffer + sizeof(UINT32); - - P_SaveNetGame(resending); - - length = save_p - savebuffer; - if (length > SAVEGAMESIZE) - { - free(savebuffer); - save_p = NULL; - I_Error("Savegame buffer overrun"); - } - - // Allocate space for compressed save: one byte fewer than for the - // uncompressed data to ensure that the compression is worthwhile. - compressedsave = malloc(length - 1); - if (!compressedsave) - { - CONS_Alert(CONS_ERROR, M_GetText("No more free memory for savegame\n")); - return; - } - - // Attempt to compress it. - if((compressedlen = lzf_compress(savebuffer + sizeof(UINT32), length - sizeof(UINT32), compressedsave + sizeof(UINT32), length - sizeof(UINT32) - 1))) - { - // Compressing succeeded; send compressed data - - free(savebuffer); - - // State that we're compressed. - buffertosend = compressedsave; - WRITEUINT32(compressedsave, length - sizeof(UINT32)); - length = compressedlen + sizeof(UINT32); - } - else - { - // Compression failed to make it smaller; send original - - free(compressedsave); - - // State that we're not compressed - buffertosend = savebuffer; - WRITEUINT32(savebuffer, 0); - } - - AddRamToSendQueue(node, buffertosend, length, SF_RAM, 0); - save_p = NULL; - - // Remember when we started sending the savegame so we can handle timeouts - sendingsavegame[node] = true; - freezetimeout[node] = I_GetTime() + jointimeout + length / 1024; // 1 extra tic for each kilobyte -} - -#ifdef DUMPCONSISTENCY -#define TMPSAVENAME "badmath.sav" -static consvar_t cv_dumpconsistency = CVAR_INIT ("dumpconsistency", "Off", CV_SAVE|CV_NETVAR, CV_OnOff, NULL); - -static void SV_SavedGame(void) -{ - size_t length; - UINT8 *savebuffer; - char tmpsave[256]; - - if (!cv_dumpconsistency.value) - return; - - sprintf(tmpsave, "%s" PATHSEP TMPSAVENAME, srb2home); - - // first save it in a malloced buffer - save_p = savebuffer = (UINT8 *)malloc(SAVEGAMESIZE); - if (!save_p) - { - CONS_Alert(CONS_ERROR, M_GetText("No more free memory for savegame\n")); - return; - } - - P_SaveNetGame(false); - - length = save_p - savebuffer; - if (length > SAVEGAMESIZE) - { - free(savebuffer); - save_p = NULL; - I_Error("Savegame buffer overrun"); - } - - // then save it! - if (!FIL_WriteFile(tmpsave, savebuffer, length)) - CONS_Printf(M_GetText("Didn't save %s for netgame"), tmpsave); - - free(savebuffer); - save_p = NULL; -} - -#undef TMPSAVENAME -#endif -#define TMPSAVENAME "$$$.sav" - - -static void CL_LoadReceivedSavegame(boolean reloading) -{ - UINT8 *savebuffer = NULL; - size_t length, decompressedlen; - char tmpsave[256]; - - sprintf(tmpsave, "%s" PATHSEP TMPSAVENAME, srb2home); - - length = FIL_ReadFile(tmpsave, &savebuffer); - - CONS_Printf(M_GetText("Loading savegame length %s\n"), sizeu1(length)); - if (!length) - { - I_Error("Can't read savegame sent"); - return; - } - - save_p = savebuffer; - - // Decompress saved game if necessary. - decompressedlen = READUINT32(save_p); - if(decompressedlen > 0) - { - UINT8 *decompressedbuffer = Z_Malloc(decompressedlen, PU_STATIC, NULL); - lzf_decompress(save_p, length - sizeof(UINT32), decompressedbuffer, decompressedlen); - Z_Free(savebuffer); - save_p = savebuffer = decompressedbuffer; - } - - paused = false; - demoplayback = false; - titlemapinaction = TITLEMAP_OFF; - titledemo = false; - automapactive = false; - - // load a base level - if (P_LoadNetGame(reloading)) - { - const UINT8 actnum = mapheaderinfo[gamemap-1]->actnum; - CONS_Printf(M_GetText("Map is now \"%s"), G_BuildMapName(gamemap)); - if (strcmp(mapheaderinfo[gamemap-1]->lvlttl, "")) - { - CONS_Printf(": %s", mapheaderinfo[gamemap-1]->lvlttl); - if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE)) - CONS_Printf(M_GetText(" Zone")); - if (actnum > 0) - CONS_Printf(" %2d", actnum); - } - CONS_Printf("\"\n"); - } - else - { - CONS_Alert(CONS_ERROR, M_GetText("Can't load the level!\n")); - Z_Free(savebuffer); - save_p = NULL; - if (unlink(tmpsave) == -1) - CONS_Alert(CONS_ERROR, M_GetText("Can't delete %s\n"), tmpsave); - return; - } - - // done - Z_Free(savebuffer); - save_p = NULL; - if (unlink(tmpsave) == -1) - CONS_Alert(CONS_ERROR, M_GetText("Can't delete %s\n"), tmpsave); - consistancy[gametic%BACKUPTICS] = Consistancy(); - CON_ToggleOff(); - - // Tell the server we have received and reloaded the gamestate - // so they know they can resume the game - netbuffer->packettype = PT_RECEIVEDGAMESTATE; - HSendPacket(servernode, true, 0, 0); -} - -static void CL_ReloadReceivedSavegame(void) -{ - INT32 i; - - for (i = 0; i < MAXPLAYERS; i++) - { -#ifdef HAVE_BLUA - LUA_InvalidatePlayer(&players[i]); -#endif - sprintf(player_names[i], "Player %d", i + 1); - } - - CL_LoadReceivedSavegame(true); - - if (neededtic < gametic) - neededtic = gametic; - maketic = neededtic; - - ticcmd_oldangleturn[0] = players[consoleplayer].oldrelangleturn; - P_ForceLocalAngle(&players[consoleplayer], (angle_t)(players[consoleplayer].angleturn << 16)); - if (splitscreen) - { - ticcmd_oldangleturn[1] = players[secondarydisplayplayer].oldrelangleturn; - P_ForceLocalAngle(&players[secondarydisplayplayer], (angle_t)(players[secondarydisplayplayer].angleturn << 16)); - } - - camera.subsector = R_PointInSubsector(camera.x, camera.y); - camera2.subsector = R_PointInSubsector(camera2.x, camera2.y); - - cl_redownloadinggamestate = false; - - CONS_Printf(M_GetText("Game state reloaded\n")); -} -#endif - -#ifndef NONET -static void SendAskInfo(INT32 node) -{ - const tic_t asktime = I_GetTime(); - netbuffer->packettype = PT_ASKINFO; - netbuffer->u.askinfo.version = VERSION; - netbuffer->u.askinfo.time = (tic_t)LONG(asktime); - - // Even if this never arrives due to the host being firewalled, we've - // now allowed traffic from the host to us in, so once the MS relays - // our address to the host, it'll be able to speak to us. - HSendPacket(node, false, 0, sizeof (askinfo_pak)); -} - -serverelem_t serverlist[MAXSERVERLIST]; -UINT32 serverlistcount = 0; - -#define FORCECLOSE 0x8000 - -static void SL_ClearServerList(INT32 connectedserver) -{ - UINT32 i; - - for (i = 0; i < serverlistcount; i++) - if (connectedserver != serverlist[i].node) - { - Net_CloseConnection(serverlist[i].node|FORCECLOSE); - serverlist[i].node = 0; - } - serverlistcount = 0; -} - -static UINT32 SL_SearchServer(INT32 node) -{ - UINT32 i; - for (i = 0; i < serverlistcount; i++) - if (serverlist[i].node == node) - return i; - - return UINT32_MAX; -} - -static void SL_InsertServer(serverinfo_pak* info, SINT8 node) -{ - UINT32 i; - - // search if not already on it - i = SL_SearchServer(node); - if (i == UINT32_MAX) - { - // not found add it - if (serverlistcount >= MAXSERVERLIST) - return; // list full - - if (info->_255 != 255) - return;/* old packet format */ - - if (info->packetversion != PACKETVERSION) - return;/* old new packet format */ - - if (info->version != VERSION) - return; // Not same version. - - if (info->subversion != SUBVERSION) - return; // Close, but no cigar. - - if (strcmp(info->application, SRB2APPLICATION)) - return;/* that's a different mod */ - - i = serverlistcount++; - } - - serverlist[i].info = *info; - serverlist[i].node = node; - - // resort server list - M_SortServerList(); -} - -#if defined (MASTERSERVER) && defined (HAVE_THREADS) -struct Fetch_servers_ctx -{ - int room; - int id; -}; - -static void -Fetch_servers_thread (struct Fetch_servers_ctx *ctx) -{ - msg_server_t *server_list; - - server_list = GetShortServersList(ctx->room, ctx->id); - - if (server_list) - { - I_lock_mutex(&ms_QueryId_mutex); - { - if (ctx->id != ms_QueryId) - { - free(server_list); - server_list = NULL; - } - } - I_unlock_mutex(ms_QueryId_mutex); - - if (server_list) - { - I_lock_mutex(&m_menu_mutex); - { - if (m_waiting_mode == M_WAITING_SERVERS) - m_waiting_mode = M_NOT_WAITING; - } - I_unlock_mutex(m_menu_mutex); - - I_lock_mutex(&ms_ServerList_mutex); - { - ms_ServerList = server_list; - } - I_unlock_mutex(ms_ServerList_mutex); - } - } - - free(ctx); -} -#endif/*defined (MASTERSERVER) && defined (HAVE_THREADS)*/ - -void CL_QueryServerList (msg_server_t *server_list) -{ - INT32 i; - - for (i = 0; server_list[i].header.buffer[0]; i++) - { - // Make sure MS version matches our own, to - // thwart nefarious servers who lie to the MS. - - /* lol bruh, that version COMES from the servers */ - //if (strcmp(version, server_list[i].version) == 0) - { - INT32 node = I_NetMakeNodewPort(server_list[i].ip, server_list[i].port); - if (node == -1) - break; // no more node free - SendAskInfo(node); - // Force close the connection so that servers can't eat - // up nodes forever if we never get a reply back from them - // (usually when they've not forwarded their ports). - // - // Don't worry, we'll get in contact with the working - // servers again when they send SERVERINFO to us later! - // - // (Note: as a side effect this probably means every - // server in the list will probably be using the same node (e.g. node 1), - // not that it matters which nodes they use when - // the connections are closed afterwards anyway) - // -- Monster Iestyn 12/11/18 - Net_CloseConnection(node|FORCECLOSE); - } - } -} - -void CL_UpdateServerList(boolean internetsearch, INT32 room) -{ - (void)internetsearch; - (void)room; - - SL_ClearServerList(0); - - if (!netgame && I_NetOpenSocket) - { - if (I_NetOpenSocket()) - { - netgame = true; - multiplayer = true; - } - } - - // search for local servers - if (netgame) - SendAskInfo(BROADCASTADDR); - -#ifdef MASTERSERVER - if (internetsearch) - { -#ifdef HAVE_THREADS - struct Fetch_servers_ctx *ctx; - - ctx = malloc(sizeof *ctx); - - /* This called from M_Refresh so I don't use a mutex */ - m_waiting_mode = M_WAITING_SERVERS; - - I_lock_mutex(&ms_QueryId_mutex); - { - ctx->id = ms_QueryId; - } - I_unlock_mutex(ms_QueryId_mutex); - - ctx->room = room; - - I_spawn_thread("fetch-servers", (I_thread_fn)Fetch_servers_thread, ctx); -#else - msg_server_t *server_list; - - server_list = GetShortServersList(room, 0); - - if (server_list) - { - CL_QueryServerList(server_list); - free(server_list); - } -#endif - } -#endif/*MASTERSERVER*/ -} - -#endif // ifndef NONET - -/** Called by CL_ServerConnectionTicker - * - * \param asksent The last time we asked the server to join. We re-ask every second in case our request got lost in transmit. - * \return False if the connection was aborted - * \sa CL_ServerConnectionTicker - * \sa CL_ConnectToServer - * - */ -static boolean CL_ServerConnectionSearchTicker(tic_t *asksent) -{ -#ifndef NONET - INT32 i; - - // serverlist is updated by GetPacket function - if (serverlistcount > 0) - { - // this can be a responce to our broadcast request - if (servernode == -1 || servernode >= MAXNETNODES) - { - i = 0; - servernode = serverlist[i].node; - CONS_Printf(M_GetText("Found, ")); - } - else - { - i = SL_SearchServer(servernode); - if (i < 0) - return true; - } - - // Quit here rather than downloading files and being refused later. - if (serverlist[i].info.refusereason) - { - D_QuitNetGame(); - CL_Reset(); - D_StartTitle(); - if (serverlist[i].info.refusereason == 1) - M_StartMessage(M_GetText("The server is not accepting\njoins for the moment.\n\nPress ESC\n"), NULL, MM_NOTHING); - else if (serverlist[i].info.refusereason == 2) - M_StartMessage(va(M_GetText("Maximum players reached: %d\n\nPress ESC\n"), serverlist[i].info.maxplayer), NULL, MM_NOTHING); - else - M_StartMessage(M_GetText("You can't join.\nI don't know why,\nbut you can't join.\n\nPress ESC\n"), NULL, MM_NOTHING); - return false; - } - - if (client) - { - D_ParseFileneeded(serverlist[i].info.fileneedednum, - serverlist[i].info.fileneeded); - CONS_Printf(M_GetText("Checking files...\n")); - i = CL_CheckFiles(); - if (i == 3) // too many files - { - D_QuitNetGame(); - CL_Reset(); - D_StartTitle(); - M_StartMessage(M_GetText( - "You have too many WAD files loaded\n" - "to add ones the server is using.\n" - "Please restart SRB2 before connecting.\n\n" - "Press ESC\n" - ), NULL, MM_NOTHING); - return false; - } - else if (i == 2) // cannot join for some reason - { - D_QuitNetGame(); - CL_Reset(); - D_StartTitle(); - M_StartMessage(M_GetText( - "You have the wrong addons loaded.\n\n" - "To play on this server, restart\n" - "the game and don't load any addons.\n" - "SRB2 will automatically add\n" - "everything you need when you join.\n\n" - "Press ESC\n" - ), NULL, MM_NOTHING); - return false; - } - else if (i == 1) - cl_mode = CL_ASKJOIN; - else - { - // must download something - // can we, though? - if (!CL_CheckDownloadable()) // nope! - { - D_QuitNetGame(); - CL_Reset(); - D_StartTitle(); - M_StartMessage(M_GetText( - "You cannot connect to this server\n" - "because you cannot download the files\n" - "that you are missing from the server.\n\n" - "See the console or log file for\n" - "more details.\n\n" - "Press ESC\n" - ), NULL, MM_NOTHING); - return false; - } - // no problem if can't send packet, we will retry later - if (CL_SendFileRequest()) - { - cl_mode = CL_DOWNLOADFILES; -#ifndef NONET - Snake_Initialise(); -#endif - } - } - } - else - cl_mode = CL_ASKJOIN; // files need not be checked for the server. - - return true; - } - - // Ask the info to the server (askinfo packet) - if (*asksent + NEWTICRATE < I_GetTime()) - { - SendAskInfo(servernode); - *asksent = I_GetTime(); - } -#else - (void)asksent; - // No netgames, so we skip this state. - cl_mode = CL_ASKJOIN; -#endif // ifndef NONET/else - - return true; -} - -/** Called by CL_ConnectToServer - * - * \param tmpsave The name of the gamestate file??? - * \param oldtic Used for knowing when to poll events and redraw - * \param asksent ??? - * \return False if the connection was aborted - * \sa CL_ServerConnectionSearchTicker - * \sa CL_ConnectToServer - * - */ -static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic_t *asksent) -{ - boolean waitmore; - INT32 i; - -#ifdef NONET - (void)tmpsave; -#endif - - switch (cl_mode) - { - case CL_SEARCHING: - if (!CL_ServerConnectionSearchTicker(asksent)) - return false; - break; - - case CL_DOWNLOADFILES: - waitmore = false; - for (i = 0; i < fileneedednum; i++) - if (fileneeded[i].status == FS_DOWNLOADING - || fileneeded[i].status == FS_REQUESTED) - { - waitmore = true; - break; - } - if (waitmore) - break; // exit the case - -#ifndef NONET - if (snake) - { - free(snake); - snake = NULL; - } -#endif - - cl_mode = CL_ASKJOIN; // don't break case continue to cljoin request now - /* FALLTHRU */ - - case CL_ASKJOIN: - CL_LoadServerFiles(); -#ifndef NONET - // prepare structures to save the file - // WARNING: this can be useless in case of server not in GS_LEVEL - // but since the network layer doesn't provide ordered packets... - CL_PrepareDownloadSaveGame(tmpsave); -#endif - if (CL_SendJoin()) - cl_mode = CL_WAITJOINRESPONSE; - break; - -#ifndef NONET - case CL_DOWNLOADSAVEGAME: - // At this state, the first (and only) needed file is the gamestate - if (fileneeded[0].status == FS_FOUND) - { - // Gamestate is now handled within CL_LoadReceivedSavegame() - CL_LoadReceivedSavegame(false); - cl_mode = CL_CONNECTED; - } // don't break case continue to CL_CONNECTED - else - break; -#endif - - case CL_WAITJOINRESPONSE: - case CL_CONNECTED: - default: - break; - - // Connection closed by cancel, timeout or refusal. - case CL_ABORTED: - cl_mode = CL_SEARCHING; - return false; - - } - - GetPackets(); - Net_AckTicker(); - - // Call it only once by tic - if (*oldtic != I_GetTime()) - { - I_OsPolling(); - for (; eventtail != eventhead; eventtail = (eventtail+1) & (MAXEVENTS-1)) - G_MapEventsToControls(&events[eventtail]); - - if (gamekeydown[KEY_ESCAPE] || gamekeydown[KEY_JOY1+1]) - { - CONS_Printf(M_GetText("Network game synchronization aborted.\n")); -// M_StartMessage(M_GetText("Network game synchronization aborted.\n\nPress ESC\n"), NULL, MM_NOTHING); - -#ifndef NONET - if (snake) - { - free(snake); - snake = NULL; - } -#endif - - D_QuitNetGame(); - CL_Reset(); - D_StartTitle(); - memset(gamekeydown, 0, NUMKEYS); - return false; - } -#ifndef NONET - else if (cl_mode == CL_DOWNLOADFILES && snake) - Snake_Handle(); -#endif - - if (client && (cl_mode == CL_DOWNLOADFILES || cl_mode == CL_DOWNLOADSAVEGAME)) - FileReceiveTicker(); - - // why are these here? this is for servers, we're a client - //if (key == 's' && server) - // doomcom->numnodes = (INT16)pnumnodes; - //FileSendTicker(); - *oldtic = I_GetTime(); - -#ifndef NONET - if (client && cl_mode != CL_CONNECTED && cl_mode != CL_ABORTED) - { - if (cl_mode != CL_DOWNLOADFILES && cl_mode != CL_DOWNLOADSAVEGAME) - { - F_MenuPresTicker(true); // title sky - F_TitleScreenTicker(true); - F_TitleScreenDrawer(); - } - CL_DrawConnectionStatus(); - I_UpdateNoVsync(); // page flip or blit buffer - if (moviemode) - M_SaveFrame(); - S_UpdateSounds(); - S_UpdateClosedCaptions(); - } -#else - CON_Drawer(); - I_UpdateNoVsync(); -#endif - } - else - I_Sleep(); - - return true; -} - -/** Use adaptive send using net_bandwidth and stat.sendbytes - * - * \todo Better description... - * - */ -static void CL_ConnectToServer(void) -{ - INT32 pnumnodes, nodewaited = doomcom->numnodes, i; - tic_t oldtic; -#ifndef NONET - tic_t asksent; - char tmpsave[256]; - - sprintf(tmpsave, "%s" PATHSEP TMPSAVENAME, srb2home); - - lastfilenum = -1; -#endif - - cl_mode = CL_SEARCHING; - -#ifndef NONET - // Don't get a corrupt savegame error because tmpsave already exists - if (FIL_FileExists(tmpsave) && unlink(tmpsave) == -1) - I_Error("Can't delete %s\n", tmpsave); -#endif - - if (netgame) - { - if (servernode < 0 || servernode >= MAXNETNODES) - CONS_Printf(M_GetText("Searching for a server...\n")); - else - CONS_Printf(M_GetText("Contacting the server...\n")); - } - - if (gamestate == GS_INTERMISSION) - Y_EndIntermission(); // clean up intermission graphics etc - - DEBFILE(va("waiting %d nodes\n", doomcom->numnodes)); - G_SetGamestate(GS_WAITINGPLAYERS); - wipegamestate = GS_WAITINGPLAYERS; - - ClearAdminPlayers(); - pnumnodes = 1; - oldtic = I_GetTime() - 1; -#ifndef NONET - asksent = (tic_t) - TICRATE; - - i = SL_SearchServer(servernode); - - if (i != -1) - { - char *gametypestr = serverlist[i].info.gametypename; - CONS_Printf(M_GetText("Connecting to: %s\n"), serverlist[i].info.servername); - gametypestr[sizeof serverlist[i].info.gametypename - 1] = '\0'; - CONS_Printf(M_GetText("Gametype: %s\n"), gametypestr); - CONS_Printf(M_GetText("Version: %d.%d.%u\n"), serverlist[i].info.version/100, - serverlist[i].info.version%100, serverlist[i].info.subversion); - } - SL_ClearServerList(servernode); -#endif - - do - { - // If the connection was aborted for some reason, leave -#ifndef NONET - if (!CL_ServerConnectionTicker(tmpsave, &oldtic, &asksent)) -#else - if (!CL_ServerConnectionTicker((char*)NULL, &oldtic, (tic_t *)NULL)) -#endif - return; - - if (server) - { - pnumnodes = 0; - for (i = 0; i < MAXNETNODES; i++) - if (nodeingame[i]) - pnumnodes++; - } - } - while (!(cl_mode == CL_CONNECTED && (client || (server && nodewaited <= pnumnodes)))); - - DEBFILE(va("Synchronisation Finished\n")); - - displayplayer = consoleplayer; -} - -#ifndef NONET -typedef struct banreason_s -{ - char *reason; - struct banreason_s *prev; //-1 - struct banreason_s *next; //+1 -} banreason_t; - -static banreason_t *reasontail = NULL; //last entry, use prev -static banreason_t *reasonhead = NULL; //1st entry, use next - -static void Command_ShowBan(void) //Print out ban list -{ - size_t i; - const char *address, *mask; - banreason_t *reasonlist = reasonhead; - - if (I_GetBanAddress) - CONS_Printf(M_GetText("Ban List:\n")); - else - return; - - for (i = 0;(address = I_GetBanAddress(i)) != NULL;i++) - { - if (!I_GetBanMask || (mask = I_GetBanMask(i)) == NULL) - CONS_Printf("%s: %s ", sizeu1(i+1), address); - else - CONS_Printf("%s: %s/%s ", sizeu1(i+1), address, mask); - - if (reasonlist && reasonlist->reason) - CONS_Printf("(%s)\n", reasonlist->reason); - else - CONS_Printf("\n"); - - if (reasonlist) reasonlist = reasonlist->next; - } - - if (i == 0 && !address) - CONS_Printf(M_GetText("(empty)\n")); -} - -void D_SaveBan(void) -{ - FILE *f; - size_t i; - banreason_t *reasonlist = reasonhead; - const char *address, *mask; - - if (!reasonhead) - return; - - f = fopen(va("%s"PATHSEP"%s", srb2home, "ban.txt"), "w"); - - if (!f) - { - CONS_Alert(CONS_WARNING, M_GetText("Could not save ban list into ban.txt\n")); - return; - } - - for (i = 0;(address = I_GetBanAddress(i)) != NULL;i++) - { - if (!I_GetBanMask || (mask = I_GetBanMask(i)) == NULL) - fprintf(f, "%s 0", address); - else - fprintf(f, "%s %s", address, mask); - - if (reasonlist && reasonlist->reason) - fprintf(f, " %s\n", reasonlist->reason); - else - fprintf(f, " %s\n", "NA"); - - if (reasonlist) reasonlist = reasonlist->next; - } - - fclose(f); -} - -static void Ban_Add(const char *reason) -{ - banreason_t *reasonlist = malloc(sizeof(*reasonlist)); - - if (!reasonlist) - return; - if (!reason) - reason = "NA"; - - reasonlist->next = NULL; - reasonlist->reason = Z_StrDup(reason); - if ((reasonlist->prev = reasontail) == NULL) - reasonhead = reasonlist; - else - reasontail->next = reasonlist; - reasontail = reasonlist; -} - -static void Command_ClearBans(void) -{ - banreason_t *temp; - - if (!I_ClearBans) - return; - - I_ClearBans(); - D_SaveBan(); - reasontail = NULL; - while (reasonhead) - { - temp = reasonhead->next; - Z_Free(reasonhead->reason); - free(reasonhead); - reasonhead = temp; - } -} - -static void Ban_Load_File(boolean warning) -{ - FILE *f; - size_t i; - const char *address, *mask; - char buffer[MAX_WADPATH]; - - f = fopen(va("%s"PATHSEP"%s", srb2home, "ban.txt"), "r"); - - if (!f) - { - if (warning) - CONS_Alert(CONS_WARNING, M_GetText("Could not open ban.txt for ban list\n")); - return; - } - - if (I_ClearBans) - Command_ClearBans(); - else - { - fclose(f); - return; - } - - for (i=0; fgets(buffer, (int)sizeof(buffer), f); i++) - { - address = strtok(buffer, " \t\r\n"); - mask = strtok(NULL, " \t\r\n"); - - I_SetBanAddress(address, mask); - - Ban_Add(strtok(NULL, "\r\n")); - } - - fclose(f); -} - -static void Command_ReloadBan(void) //recheck ban.txt -{ - Ban_Load_File(true); -} - -static void Command_connect(void) -{ - if (COM_Argc() < 2 || *COM_Argv(1) == 0) - { - CONS_Printf(M_GetText( - "Connect (port): connect to a server\n" - "Connect ANY: connect to the first lan server found\n" - //"Connect SELF: connect to your own server.\n" - )); - return; - } - - if (Playing() || titledemo) - { - CONS_Printf(M_GetText("You cannot connect while in a game. End this game first.\n")); - return; - } - - // modified game check: no longer handled - // we don't request a restart unless the filelist differs - - server = false; -/* - if (!stricmp(COM_Argv(1), "self")) - { - servernode = 0; - server = true; - /// \bug should be but... - //SV_SpawnServer(); - } - else -*/ - { - // used in menu to connect to a server in the list - if (netgame && !stricmp(COM_Argv(1), "node")) - { - servernode = (SINT8)atoi(COM_Argv(2)); - } - else if (netgame) - { - CONS_Printf(M_GetText("You cannot connect while in a game. End this game first.\n")); - return; - } - else if (I_NetOpenSocket) - { - I_NetOpenSocket(); - netgame = true; - multiplayer = true; - - if (!stricmp(COM_Argv(1), "any")) - servernode = BROADCASTADDR; - else if (I_NetMakeNodewPort) - { - if (COM_Argc() >= 3) // address AND port - servernode = I_NetMakeNodewPort(COM_Argv(1), COM_Argv(2)); - else // address only, or address:port - servernode = I_NetMakeNode(COM_Argv(1)); - } - else - { - CONS_Alert(CONS_ERROR, M_GetText("There is no server identification with this network driver\n")); - D_CloseConnection(); - return; - } - } - else - CONS_Alert(CONS_ERROR, M_GetText("There is no network driver\n")); - } - - splitscreen = false; - SplitScreen_OnChange(); - botingame = false; - botskin = 0; - CL_ConnectToServer(); -} -#endif - -static void ResetNode(INT32 node); - -// -// CL_ClearPlayer -// -// Clears the player data so that a future client can use this slot -// -void CL_ClearPlayer(INT32 playernum) -{ - if (players[playernum].mo) - P_RemoveMobj(players[playernum].mo); - memset(&players[playernum], 0, sizeof (player_t)); - memset(playeraddress[playernum], 0, sizeof(*playeraddress)); -} - -// -// CL_RemovePlayer -// -// Removes a player from the current game -// -static void CL_RemovePlayer(INT32 playernum, kickreason_t reason) -{ - // Sanity check: exceptional cases (i.e. c-fails) can cause multiple - // kick commands to be issued for the same player. - if (!playeringame[playernum]) - return; - - if (server && !demoplayback && playernode[playernum] != UINT8_MAX) - { - INT32 node = playernode[playernum]; - playerpernode[node]--; - if (playerpernode[node] <= 0) - { - nodeingame[node] = false; - Net_CloseConnection(node); - ResetNode(node); - } - } - - if (gametyperules & GTR_TEAMFLAGS) - P_PlayerFlagBurst(&players[playernum], false); // Don't take the flag with you! - - // If in a special stage, redistribute the player's spheres across - // the remaining players. - if (G_IsSpecialStage(gamemap)) - { - INT32 i, count, sincrement, spheres, rincrement, rings; - - for (i = 0, count = 0; i < MAXPLAYERS; i++) - { - if (playeringame[i]) - count++; - } - - count--; - sincrement = spheres = players[playernum].spheres; - rincrement = rings = players[playernum].rings; - - if (count) - { - sincrement /= count; - rincrement /= count; - } - - for (i = 0; i < MAXPLAYERS; i++) - { - if (playeringame[i] && i != playernum) - { - if (spheres < 2*sincrement) - { - P_GivePlayerSpheres(&players[i], spheres); - spheres = 0; - } - else - { - P_GivePlayerSpheres(&players[i], sincrement); - spheres -= sincrement; - } - - if (rings < 2*rincrement) - { - P_GivePlayerRings(&players[i], rings); - rings = 0; - } - else - { - P_GivePlayerRings(&players[i], rincrement); - rings -= rincrement; - } - } - } - } - - LUAh_PlayerQuit(&players[playernum], reason); // Lua hook for player quitting - - // don't look through someone's view who isn't there - if (playernum == displayplayer) - { - // Call ViewpointSwitch hooks here. - // The viewpoint was forcibly changed. - LUAh_ViewpointSwitch(&players[consoleplayer], &players[consoleplayer], true); - displayplayer = consoleplayer; - } - - // Reset player data - CL_ClearPlayer(playernum); - - // remove avatar of player - playeringame[playernum] = false; - playernode[playernum] = UINT8_MAX; - while (!playeringame[doomcom->numslots-1] && doomcom->numslots > 1) - doomcom->numslots--; - - // Reset the name - sprintf(player_names[playernum], "Player %d", playernum+1); - - player_name_changes[playernum] = 0; - - if (IsPlayerAdmin(playernum)) - { - RemoveAdminPlayer(playernum); // don't stay admin after you're gone - } - - LUA_InvalidatePlayer(&players[playernum]); - - if (G_TagGametype()) //Check if you still have a game. Location flexible. =P - P_CheckSurvivors(); - else if (gametyperules & GTR_RACE) - P_CheckRacers(); -} - -void CL_Reset(void) -{ - if (metalrecording) - G_StopMetalRecording(false); - if (metalplayback) - G_StopMetalDemo(); - if (demorecording) - G_CheckDemoStatus(); - - // reset client/server code - DEBFILE(va("\n-=-=-=-=-=-=-= Client reset =-=-=-=-=-=-=-\n\n")); - - if (servernode > 0 && servernode < MAXNETNODES) - { - nodeingame[(UINT8)servernode] = false; - Net_CloseConnection(servernode); - } - D_CloseConnection(); // netgame = false - multiplayer = false; - servernode = 0; - server = true; - doomcom->numnodes = 1; - doomcom->numslots = 1; - SV_StopServer(); - SV_ResetServer(); - CV_RevertNetVars(); - - // make sure we don't leave any fileneeded gunk over from a failed join - fileneedednum = 0; - memset(fileneeded, 0, sizeof(fileneeded)); - - // D_StartTitle should get done now, but the calling function will handle it -} - -#ifndef NONET -static void Command_GetPlayerNum(void) -{ - INT32 i; - - for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i]) - { - if (serverplayer == i) - CONS_Printf(M_GetText("num:%2d node:%2d %s\n"), i, playernode[i], player_names[i]); - else - CONS_Printf(M_GetText("\x82num:%2d node:%2d %s\n"), i, playernode[i], player_names[i]); - } -} - -SINT8 nametonum(const char *name) -{ - INT32 playernum, i; - - if (!strcmp(name, "0")) + if (!skin) return 0; - playernum = (SINT8)atoi(name); + if ((playersprite_t)(spr2 & ~FF_SPR2SUPER) >= free_spr2) + return 0; - if (playernum < 0 || playernum >= MAXPLAYERS) - return -1; - - if (playernum) + while (!skin->sprites[spr2].numframes + && spr2 != SPR2_STND + && ++i < 32) // recursion limiter { - if (playeringame[playernum]) - return (SINT8)playernum; - else - return -1; + if (spr2 & FF_SPR2SUPER) + { + super = FF_SPR2SUPER; + spr2 &= ~FF_SPR2SUPER; + continue; + } + + switch(spr2) + { + // Normal special cases. + case SPR2_JUMP: + spr2 = ((player + ? player->charflags + : skin->flags) + & SF_NOJUMPSPIN) ? SPR2_SPNG : SPR2_ROLL; + break; + case SPR2_TIRE: + spr2 = ((player + ? player->charability + : skin->ability) + == CA_SWIM) ? SPR2_SWIM : SPR2_FLY; + break; + // Use the handy list, that's what it's there for! + default: + spr2 = spr2defaults[spr2]; + break; + } + + spr2 |= super; } - for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && !stricmp(player_names[i], name)) - return (SINT8)i; + if (i >= 32) // probably an infinite loop... + return 0; - CONS_Printf(M_GetText("There is no player named \"%s\"\n"), name); + return spr2; +} +static void Sk_SetDefaultValue(skin_t *skin) +{ + INT32 i; + // + // set default skin values + // + memset(skin, 0, sizeof (skin_t)); + snprintf(skin->name, + sizeof skin->name, "skin %u", (UINT32)(skin-skins)); + skin->name[sizeof skin->name - 1] = '\0'; + skin->wadnum = INT16_MAX; + + skin->flags = 0; + + strcpy(skin->realname, "Someone"); + strcpy(skin->hudname, "???"); + + skin->starttranscolor = 96; + skin->prefcolor = SKINCOLOR_GREEN; + skin->supercolor = SKINCOLOR_SUPERGOLD1; + skin->prefoppositecolor = 0; // use tables + + skin->normalspeed = 36<runspeed = 28<thrustfactor = 5; + skin->accelstart = 96; + skin->acceleration = 40; + + skin->ability = CA_NONE; + skin->ability2 = CA2_SPINDASH; + skin->jumpfactor = FRACUNIT; + skin->actionspd = 30<mindash = 15<maxdash = 70<radius = mobjinfo[MT_PLAYER].radius; + skin->height = mobjinfo[MT_PLAYER].height; + skin->spinheight = FixedMul(skin->height, 2*FRACUNIT/3); + + skin->shieldscale = FRACUNIT; + skin->camerascale = FRACUNIT; + + skin->thokitem = -1; + skin->spinitem = -1; + skin->revitem = -1; + skin->followitem = 0; + + skin->highresscale = FRACUNIT; + skin->contspeed = 17; + skin->contangle = 0; + + skin->availability = 0; + + for (i = 0; i < sfx_skinsoundslot0; i++) + if (S_sfx[i].skinsound != -1) + skin->soundsid[S_sfx[i].skinsound] = i; +} + +// +// Initialize the basic skins +// +void R_InitSkins(void) +{ +#ifdef SKINVALUES + INT32 i; + + for (i = 0; i <= MAXSKINS; i++) + { + skin_cons_t[i].value = 0; + skin_cons_t[i].strvalue = NULL; + } +#endif + + // no default skin! + numskins = 0; +} + +UINT32 R_GetSkinAvailabilities(void) +{ + INT32 s; + UINT32 response = 0; + + for (s = 0; s < MAXSKINS; s++) + { + if (skins[s].availability && unlockables[skins[s].availability - 1].unlocked) + response |= (1 << s); + } + return response; +} + +// returns true if available in circumstances, otherwise nope +// warning don't use with an invalid skinnum other than -1 which always returns true +boolean R_SkinUsable(INT32 playernum, INT32 skinnum) +{ + return ((skinnum == -1) // Simplifies things elsewhere, since there's already plenty of checks for less-than-0... + || (!skins[skinnum].availability) + || (((netgame || multiplayer) && playernum != -1) ? (players[playernum].availabilities & (1 << skinnum)) : (unlockables[skins[skinnum].availability - 1].unlocked)) + || (modeattacking) // If you have someone else's run you might as well take a look + || (Playing() && (R_SkinAvailable(mapheaderinfo[gamemap-1]->forcecharacter) == skinnum)) // Force 1. + || (netgame && (cv_forceskin.value == skinnum)) // Force 2. + || (metalrecording && skinnum == 5) // Force 3. + || players[playernum].bot //Force (player is a bot) + ); +} + +// returns true if the skin name is found (loaded from pwad) +// warning return -1 if not found +INT32 R_SkinAvailable(const char *name) +{ + INT32 i; + + for (i = 0; i < numskins; i++) + { + // search in the skin list + if (stricmp(skins[i].name,name)==0) + return i; + } return -1; } -/** Lists all players and their player numbers. - * - * \sa Command_GetPlayerNum - */ -static void Command_Nodes(void) +// network code calls this when a 'skin change' is received +void SetPlayerSkin(INT32 playernum, const char *skinname) { - INT32 i; - size_t maxlen = 0; - const char *address; + INT32 i = R_SkinAvailable(skinname); + player_t *player = &players[playernum]; - for (i = 0; i < MAXPLAYERS; i++) + if ((i != -1) && R_SkinUsable(playernum, i)) { - const size_t plen = strlen(player_names[i]); - if (playeringame[i] && plen > maxlen) - maxlen = plen; + SetPlayerSkinByNum(playernum, i); + return; } - for (i = 0; i < MAXPLAYERS; i++) - { - if (playeringame[i]) - { - CONS_Printf("%.2u: %*s", i, (int)maxlen, player_names[i]); + if (P_IsLocalPlayer(player)) + CONS_Alert(CONS_WARNING, M_GetText("Skin '%s' not found.\n"), skinname); + else if(server || IsPlayerAdmin(consoleplayer)) + CONS_Alert(CONS_WARNING, M_GetText("Player %d (%s) skin '%s' not found\n"), playernum, player_names[playernum], skinname); - if (playernode[i] != UINT8_MAX) - { - CONS_Printf(" - node %.2d", playernode[i]); - if (I_GetNodeAddress && (address = I_GetNodeAddress(playernode[i])) != NULL) - CONS_Printf(" - %s", address); - } - - if (IsPlayerAdmin(i)) - CONS_Printf(M_GetText(" (verified admin)")); - - if (players[i].spectator) - CONS_Printf(M_GetText(" (spectator)")); - - CONS_Printf("\n"); - } - } + SetPlayerSkinByNum(playernum, 0); } -static void Command_Ban(void) +// Same as SetPlayerSkin, but uses the skin #. +// network code calls this when a 'skin change' is received +void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum) { - if (COM_Argc() < 2) + player_t *player = &players[playernum]; + skin_t *skin = &skins[skinnum]; + UINT16 newcolor = 0; + + if (skinnum >= 0 && skinnum < numskins && R_SkinUsable(playernum, skinnum)) // Make sure it exists! { - CONS_Printf(M_GetText("Ban : ban and kick a player\n")); - return; - } + player->skin = skinnum; - if (!netgame) // Don't kick Tails in splitscreen! - { - CONS_Printf(M_GetText("This only works in a netgame.\n")); - return; - } + player->camerascale = skin->camerascale; + player->shieldscale = skin->shieldscale; - if (server || IsPlayerAdmin(consoleplayer)) - { - UINT8 buf[3 + MAX_REASONLENGTH]; - UINT8 *p = buf; - const SINT8 pn = nametonum(COM_Argv(1)); - const INT32 node = playernode[(INT32)pn]; + player->charability = (UINT8)skin->ability; + player->charability2 = (UINT8)skin->ability2; - if (pn == -1 || pn == 0) - return; + player->charflags = (UINT32)skin->flags; - WRITEUINT8(p, pn); + player->thokitem = skin->thokitem < 0 ? (UINT32)mobjinfo[MT_PLAYER].painchance : (UINT32)skin->thokitem; + player->spinitem = skin->spinitem < 0 ? (UINT32)mobjinfo[MT_PLAYER].damage : (UINT32)skin->spinitem; + player->revitem = skin->revitem < 0 ? (mobjtype_t)mobjinfo[MT_PLAYER].raisestate : (UINT32)skin->revitem; + player->followitem = skin->followitem; - if (server && I_Ban && !I_Ban(node)) // only the server is allowed to do this right now + if (((player->powers[pw_shield] & SH_NOSTACK) == SH_PINK) && (player->revitem == MT_LHRT || player->spinitem == MT_LHRT || player->thokitem == MT_LHRT)) // Healers can't keep their buff. + player->powers[pw_shield] &= SH_STACK; + + player->actionspd = skin->actionspd; + player->mindash = skin->mindash; + player->maxdash = skin->maxdash; + + player->normalspeed = skin->normalspeed; + player->runspeed = skin->runspeed; + player->thrustfactor = skin->thrustfactor; + player->accelstart = skin->accelstart; + player->acceleration = skin->acceleration; + + player->jumpfactor = skin->jumpfactor; + + player->height = skin->height; + player->spinheight = skin->spinheight; + + if (!(cv_debug || devparm) && !(netgame || multiplayer || demoplayback)) { - CONS_Alert(CONS_WARNING, M_GetText("Too many bans! Geez, that's a lot of people you're excluding...\n")); - WRITEUINT8(p, KICK_MSG_GO_AWAY); - SendNetXCmd(XD_KICK, &buf, 2); + if (playernum == consoleplayer) + CV_StealthSetValue(&cv_playercolor, skin->prefcolor); + else if (playernum == secondarydisplayplayer) + CV_StealthSetValue(&cv_playercolor2, skin->prefcolor); + player->skincolor = newcolor = skin->prefcolor; + if (player->bot && botingame) + { + botskin = (UINT8)(skinnum + 1); + botcolor = skin->prefcolor; + } } - else + + if (player->followmobj) { - if (server) // only the server is allowed to do this right now + P_RemoveMobj(player->followmobj); + P_SetTarget(&player->followmobj, NULL); + } + + if (player->mo) + { + fixed_t radius = FixedMul(skin->radius, player->mo->scale); + if ((player->powers[pw_carry] == CR_NIGHTSMODE) && (skin->sprites[SPR2_NFLY].numframes == 0)) // If you don't have a sprite for flying horizontally, use the default NiGHTS skin. { - Ban_Add(COM_Argv(2)); - D_SaveBan(); // save the ban list + skin = &skins[DEFAULTNIGHTSSKIN]; + player->followitem = skin->followitem; + if (!(cv_debug || devparm) && !(netgame || multiplayer || demoplayback)) + newcolor = skin->prefcolor; // will be updated in thinker to flashing + } + player->mo->skin = skin; + if (newcolor) + player->mo->color = newcolor; + P_SetScale(player->mo, player->mo->scale); + player->mo->radius = radius; + + P_SetPlayerMobjState(player->mo, player->mo->state-states); // Prevent visual errors when switching between skins with differing number of frames + } + return; + } + + if (P_IsLocalPlayer(player)) + CONS_Alert(CONS_WARNING, M_GetText("Requested skin %d not found\n"), skinnum); + else if(server || IsPlayerAdmin(consoleplayer)) + CONS_Alert(CONS_WARNING, "Player %d (%s) skin %d not found\n", playernum, player_names[playernum], skinnum); + SetPlayerSkinByNum(playernum, 0); // not found put the sonic skin +} + +// +// Add skins from a pwad, each skin preceded by 'S_SKIN' marker +// + +// Does the same is in w_wad, but check only for +// the first 6 characters (this is so we can have S_SKIN1, S_SKIN2.. +// for wad editors that don't like multiple resources of the same name) +// +static UINT16 W_CheckForSkinMarkerInPwad(UINT16 wadid, UINT16 startlump) +{ + UINT16 i; + const char *S_SKIN = "S_SKIN"; + lumpinfo_t *lump_p; + + // scan forward, start at + if (startlump < wadfiles[wadid]->numlumps) + { + lump_p = wadfiles[wadid]->lumpinfo + startlump; + for (i = startlump; i < wadfiles[wadid]->numlumps; i++, lump_p++) + if (memcmp(lump_p->name,S_SKIN,6)==0) + return i; + } + return INT16_MAX; // not found +} + +#define HUDNAMEWRITE(value) STRBUFCPY(skin->hudname, value) + +// turn _ into spaces and . into katana dot +#define SYMBOLCONVERT(name) for (value = name; *value; value++)\ + {\ + if (*value == '_') *value = ' ';\ + else if (*value == '.') *value = '\x1E';\ + } + +// +// Patch skins from a pwad, each skin preceded by 'P_SKIN' marker +// + +// Does the same is in w_wad, but check only for +// the first 6 characters (this is so we can have P_SKIN1, P_SKIN2.. +// for wad editors that don't like multiple resources of the same name) +// +static UINT16 W_CheckForPatchSkinMarkerInPwad(UINT16 wadid, UINT16 startlump) +{ + UINT16 i; + const char *P_SKIN = "P_SKIN"; + lumpinfo_t *lump_p; + + // scan forward, start at + if (startlump < wadfiles[wadid]->numlumps) + { + lump_p = wadfiles[wadid]->lumpinfo + startlump; + for (i = startlump; i < wadfiles[wadid]->numlumps; i++, lump_p++) + if (memcmp(lump_p->name,P_SKIN,6)==0) + return i; + } + return INT16_MAX; // not found +} + +static void R_LoadSkinSprites(UINT16 wadnum, UINT16 *lump, UINT16 *lastlump, skin_t *skin) +{ + UINT16 newlastlump; + UINT8 sprite2; + + *lump += 1; // start after S_SKIN + *lastlump = W_CheckNumForNamePwad("S_END",wadnum,*lump); // stop at S_END + + // old wadding practices die hard -- stop at S_SKIN (or P_SKIN) or S_START if they come before S_END. + newlastlump = W_CheckForSkinMarkerInPwad(wadnum,*lump); + if (newlastlump < *lastlump) *lastlump = newlastlump; + newlastlump = W_CheckForPatchSkinMarkerInPwad(wadnum,*lump); + if (newlastlump < *lastlump) *lastlump = newlastlump; + newlastlump = W_CheckNumForNamePwad("S_START",wadnum,*lump); + if (newlastlump < *lastlump) *lastlump = newlastlump; + + // ...and let's handle super, too + newlastlump = W_CheckNumForNamePwad("S_SUPER",wadnum,*lump); + if (newlastlump < *lastlump) + { + newlastlump++; + // load all sprite sets we are aware of... for super! + for (sprite2 = 0; sprite2 < free_spr2; sprite2++) + R_AddSingleSpriteDef(spr2names[sprite2], &skin->sprites[FF_SPR2SUPER|sprite2], wadnum, newlastlump, *lastlump); + + newlastlump--; + *lastlump = newlastlump; // okay, make the normal sprite set loading end there + } + + // load all sprite sets we are aware of... for normal stuff. + for (sprite2 = 0; sprite2 < free_spr2; sprite2++) + R_AddSingleSpriteDef(spr2names[sprite2], &skin->sprites[sprite2], wadnum, *lump, *lastlump); + + if (skin->sprites[0].numframes == 0) + I_Error("R_LoadSkinSprites: no frames found for sprite SPR2_%s\n", spr2names[0]); +} + +// returns whether found appropriate property +static boolean R_ProcessPatchableFields(skin_t *skin, char *stoken, char *value) +{ + // custom translation table + if (!stricmp(stoken, "startcolor")) + skin->starttranscolor = atoi(value); + +#define FULLPROCESS(field) else if (!stricmp(stoken, #field)) skin->field = get_number(value); + // character type identification + FULLPROCESS(flags) + FULLPROCESS(ability) + FULLPROCESS(ability2) + + FULLPROCESS(thokitem) + FULLPROCESS(spinitem) + FULLPROCESS(revitem) + FULLPROCESS(followitem) +#undef FULLPROCESS + +#define GETFRACBITS(field) else if (!stricmp(stoken, #field)) skin->field = atoi(value)<field = atoi(value); + GETINT(thrustfactor) + GETINT(accelstart) + GETINT(acceleration) + GETINT(contspeed) + GETINT(contangle) +#undef GETINT + +#define GETSKINCOLOR(field) else if (!stricmp(stoken, #field)) \ +{ \ + UINT16 color = R_GetColorByName(value); \ + skin->field = (color ? color : SKINCOLOR_GREEN); \ +} + GETSKINCOLOR(prefcolor) + GETSKINCOLOR(prefoppositecolor) +#undef GETSKINCOLOR + else if (!stricmp(stoken, "supercolor")) + { + UINT16 color = R_GetSuperColorByName(value); + skin->supercolor = (color ? color : SKINCOLOR_SUPERGOLD1); + } + +#define GETFLOAT(field) else if (!stricmp(stoken, #field)) skin->field = FLOAT_TO_FIXED(atof(value)); + GETFLOAT(jumpfactor) + GETFLOAT(highresscale) + GETFLOAT(shieldscale) + GETFLOAT(camerascale) +#undef GETFLOAT + +#define GETFLAG(field) else if (!stricmp(stoken, #field)) { \ + strupr(value); \ + if (atoi(value) || value[0] == 'T' || value[0] == 'Y') \ + skin->flags |= (SF_##field); \ + else \ + skin->flags &= ~(SF_##field); \ +} + // parameters for individual character flags + // these are uppercase so they can be concatenated with SF_ + // 1, true, yes are all valid values + GETFLAG(SUPER) + GETFLAG(NOSUPERSPIN) + GETFLAG(NOSPINDASHDUST) + GETFLAG(HIRES) + GETFLAG(NOSKID) + GETFLAG(NOSPEEDADJUST) + GETFLAG(RUNONWATER) + GETFLAG(NOJUMPSPIN) + GETFLAG(NOJUMPDAMAGE) + GETFLAG(STOMPDAMAGE) + GETFLAG(MARIODAMAGE) + GETFLAG(MACHINE) + GETFLAG(DASHMODE) + GETFLAG(FASTEDGE) + GETFLAG(MULTIABILITY) + GETFLAG(NONIGHTSROTATION) + GETFLAG(NONIGHTSSUPER) +#undef GETFLAG + + else // let's check if it's a sound, otherwise error out + { + boolean found = false; + sfxenum_t i; + size_t stokenadjust; + + // Remove the prefix. (We need to affect an adjusting variable so that we can print error messages if it's not actually a sound.) + if ((stoken[0] == 'D' || stoken[0] == 'd') && (stoken[1] == 'S' || stoken[1] == 's')) // DS* + stokenadjust = 2; + else // sfx_* + stokenadjust = 4; + + // Remove the prefix. (We can affect this directly since we're not going to use it again.) + if ((value[0] == 'D' || value[0] == 'd') && (value[1] == 'S' || value[1] == 's')) // DS* + value += 2; + else // sfx_* + value += 4; + + // copy name of sounds that are remapped + // for this skin + for (i = 0; i < sfx_skinsoundslot0; i++) + { + if (!S_sfx[i].name) + continue; + if (S_sfx[i].skinsound != -1 + && !stricmp(S_sfx[i].name, + stoken + stokenadjust)) + { + skin->soundsid[S_sfx[i].skinsound] = + S_AddSoundFx(value, S_sfx[i].singularity, S_sfx[i].pitch, true); + found = true; + } + } + return found; + } + return true; +} + +// +// Find skin sprites, sounds & optional status bar face, & add them +// +void R_AddSkins(UINT16 wadnum) +{ + UINT16 lump, lastlump = 0; + char *buf; + char *buf2; + char *stoken; + char *value; + size_t size; + skin_t *skin; + boolean hudname, realname; + + // + // search for all skin markers in pwad + // + + while ((lump = W_CheckForSkinMarkerInPwad(wadnum, lastlump)) != INT16_MAX) + { + // advance by default + lastlump = lump + 1; + + if (numskins >= MAXSKINS) + { + CONS_Debug(DBG_RENDER, "ignored skin (%d skins maximum)\n", MAXSKINS); + continue; // so we know how many skins couldn't be added + } + buf = W_CacheLumpNumPwad(wadnum, lump, PU_CACHE); + size = W_LumpLengthPwad(wadnum, lump); + + // for strtok + buf2 = malloc(size+1); + if (!buf2) + I_Error("R_AddSkins: No more free memory\n"); + M_Memcpy(buf2,buf,size); + buf2[size] = '\0'; + + // set defaults + skin = &skins[numskins]; + Sk_SetDefaultValue(skin); + skin->wadnum = wadnum; + hudname = realname = false; + // parse + stoken = strtok (buf2, "\r\n= "); + while (stoken) + { + if ((stoken[0] == '/' && stoken[1] == '/') + || (stoken[0] == '#'))// skip comments + { + stoken = strtok(NULL, "\r\n"); // skip end of line + goto next_token; // find the real next token } - if (COM_Argc() == 2) - { - WRITEUINT8(p, KICK_MSG_BANNED); - SendNetXCmd(XD_KICK, &buf, 2); - } - else - { - size_t i, j = COM_Argc(); - char message[MAX_REASONLENGTH]; + value = strtok(NULL, "\r\n= "); - //Steal from the motd code so you don't have to put the reason in quotes. - strlcpy(message, COM_Argv(2), sizeof message); - for (i = 3; i < j; i++) + if (!value) + I_Error("R_AddSkins: syntax error in S_SKIN lump# %d(%s) in WAD %s\n", lump, W_CheckNameForNumPwad(wadnum,lump), wadfiles[wadnum]->filename); + + // Some of these can't go in R_ProcessPatchableFields because they have side effects for future lines. + // Others can't go in there because we don't want them to be patchable. + if (!stricmp(stoken, "name")) + { + INT32 skinnum = R_SkinAvailable(value); + strlwr(value); + if (skinnum == -1) + STRBUFCPY(skin->name, value); + // the skin name must uniquely identify a single skin + // if the name is already used I make the name 'namex' + // using the default skin name's number set above + else { - strlcat(message, " ", sizeof message); - strlcat(message, COM_Argv(i), sizeof message); + const size_t stringspace = + strlen(value) + sizeof (numskins) + 1; + char *value2 = Z_Malloc(stringspace, PU_STATIC, NULL); + snprintf(value2, stringspace, + "%s%d", value, numskins); + value2[stringspace - 1] = '\0'; + if (R_SkinAvailable(value2) == -1) + // I'm lazy so if NEW name is already used I leave the 'skin x' + // default skin name set in Sk_SetDefaultValue + STRBUFCPY(skin->name, value2); + Z_Free(value2); } - WRITEUINT8(p, KICK_MSG_CUSTOM_BAN); - WRITESTRINGN(p, message, MAX_REASONLENGTH); - SendNetXCmd(XD_KICK, &buf, p - buf); - } - } - } - else - CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n")); - -} - -static void Command_BanIP(void) -{ - if (COM_Argc() < 2) - { - CONS_Printf(M_GetText("banip : ban an ip address\n")); - return; - } - - if (server) // Only the server can use this, otherwise does nothing. - { - const char *address = (COM_Argv(1)); - const char *reason; - - if (COM_Argc() == 2) - reason = NULL; - else - reason = COM_Argv(2); - - - if (I_SetBanAddress && I_SetBanAddress(address, NULL)) - { - if (reason) - CONS_Printf("Banned IP address %s for: %s\n", address, reason); - else - CONS_Printf("Banned IP address %s\n", address); - - Ban_Add(reason); - D_SaveBan(); - } - else - { - return; - } - } -} - -static void Command_Kick(void) -{ - if (COM_Argc() < 2) - { - CONS_Printf(M_GetText("kick : kick a player\n")); - return; - } - - //if (!netgame) // Don't kick Tails in splitscreen! - //{ - // CONS_Printf(M_GetText("This only works in a netgame.\n")); - // return; - //} - - if (server || IsPlayerAdmin(consoleplayer)) - { - UINT8 buf[3 + MAX_REASONLENGTH]; - UINT8 *p = buf; - const SINT8 pn = nametonum(COM_Argv(1)); - - if (splitscreen && (pn == 0 || pn == 1)) - { - CONS_Printf(M_GetText("Splitscreen players cannot be kicked.\n")); - return; - } - if (pn == -1 || pn == 0) - return; - - // Special case if we are trying to kick a player who is downloading the game state: - // trigger a timeout instead of kicking them, because a kick would only - // take effect after they have finished downloading - if (server && playernode[pn] != UINT8_MAX && sendingsavegame[playernode[pn]]) - { - Net_ConnectionTimeout(playernode[pn]); - return; - } - - WRITESINT8(p, pn); - - if (COM_Argc() == 2) - { - WRITEUINT8(p, KICK_MSG_GO_AWAY); - SendNetXCmd(XD_KICK, &buf, 2); - } - else - { - size_t i, j = COM_Argc(); - char message[MAX_REASONLENGTH]; - - //Steal from the motd code so you don't have to put the reason in quotes. - strlcpy(message, COM_Argv(2), sizeof message); - for (i = 3; i < j; i++) - { - strlcat(message, " ", sizeof message); - strlcat(message, COM_Argv(i), sizeof message); - } - - WRITEUINT8(p, KICK_MSG_CUSTOM_KICK); - WRITESTRINGN(p, message, MAX_REASONLENGTH); - SendNetXCmd(XD_KICK, &buf, p - buf); - } - } - else - CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n")); -} -#endif - -static void Got_KickCmd(UINT8 **p, INT32 playernum) -{ - INT32 pnum, msg; - char buf[3 + MAX_REASONLENGTH]; - char *reason = buf; - kickreason_t kickreason = KR_KICK; - boolean keepbody; - - pnum = READUINT8(*p); - msg = READUINT8(*p); - keepbody = (msg & KICK_MSG_KEEP_BODY) != 0; - msg &= ~KICK_MSG_KEEP_BODY; - - if (pnum == serverplayer && IsPlayerAdmin(playernum)) - { - CONS_Printf(M_GetText("Server is being shut down remotely. Goodbye!\n")); - - if (server) - COM_BufAddText("quit\n"); - - return; - } - - // Is playernum authorized to make this kick? - if (playernum != serverplayer && !IsPlayerAdmin(playernum) - && !(playernode[playernum] != UINT8_MAX && playerpernode[playernode[playernum]] == 2 - && nodetoplayer2[playernode[playernum]] == pnum)) - { - // We received a kick command from someone who isn't the - // server or admin, and who isn't in splitscreen removing - // player 2. Thus, it must be someone with a modified - // binary, trying to kick someone but without having - // authorization. - - // We deal with this by changing the kick reason to - // "consistency failure" and kicking the offending user - // instead. - - // Note: Splitscreen in netgames is broken because of - // this. Only the server has any idea of which players - // are using splitscreen on the same computer, so - // clients cannot always determine if a kick is - // legitimate. - - CONS_Alert(CONS_WARNING, M_GetText("Illegal kick command received from %s for player %d\n"), player_names[playernum], pnum); - - // In debug, print a longer message with more details. - // TODO Callum: Should we translate this? -/* - CONS_Debug(DBG_NETPLAY, - "So, you must be asking, why is this an illegal kick?\n" - "Well, let's take a look at the facts, shall we?\n" - "\n" - "playernum (this is the guy who did it), he's %d.\n" - "pnum (the guy he's trying to kick) is %d.\n" - "playernum's node is %d.\n" - "That node has %d players.\n" - "Player 2 on that node is %d.\n" - "pnum's node is %d.\n" - "That node has %d players.\n" - "Player 2 on that node is %d.\n" - "\n" - "If you think this is a bug, please report it, including all of the details above.\n", - playernum, pnum, - playernode[playernum], playerpernode[playernode[playernum]], - nodetoplayer2[playernode[playernum]], - playernode[pnum], playerpernode[playernode[pnum]], - nodetoplayer2[playernode[pnum]]); -*/ - pnum = playernum; - msg = KICK_MSG_CON_FAIL; - keepbody = true; - } - - //CONS_Printf("\x82%s ", player_names[pnum]); - - // If a verified admin banned someone, the server needs to know about it. - // If the playernum isn't zero (the server) then the server needs to record the ban. - if (server && playernum && (msg == KICK_MSG_BANNED || msg == KICK_MSG_CUSTOM_BAN)) - { - if (I_Ban && !I_Ban(playernode[(INT32)pnum])) - CONS_Alert(CONS_WARNING, M_GetText("Too many bans! Geez, that's a lot of people you're excluding...\n")); -#ifndef NONET - else - Ban_Add(reason); -#endif - } - - switch (msg) - { - case KICK_MSG_GO_AWAY: - if (!players[pnum].quittime) - HU_AddChatText(va("\x82*%s has been kicked (Go away)", player_names[pnum]), false); - kickreason = KR_KICK; - break; - case KICK_MSG_PING_HIGH: - HU_AddChatText(va("\x82*%s left the game (Broke ping limit)", player_names[pnum]), false); - kickreason = KR_PINGLIMIT; - break; - case KICK_MSG_CON_FAIL: - HU_AddChatText(va("\x82*%s left the game (Synch Failure)", player_names[pnum]), false); - kickreason = KR_SYNCH; - - if (M_CheckParm("-consisdump")) // Helps debugging some problems - { - INT32 i; - - CONS_Printf(M_GetText("Player kicked is #%d, dumping consistency...\n"), pnum); - - for (i = 0; i < MAXPLAYERS; i++) + // copy to hudname and fullname as a default. + if (!realname) { - if (!playeringame[i]) - continue; - CONS_Printf("-------------------------------------\n"); - CONS_Printf("Player %d: %s\n", i, player_names[i]); - CONS_Printf("Skin: %d\n", players[i].skin); - CONS_Printf("Color: %d\n", players[i].skincolor); - CONS_Printf("Speed: %d\n",players[i].speed>>FRACBITS); - if (players[i].mo) + STRBUFCPY(skin->realname, skin->name); + for (value = skin->realname; *value; value++) { - if (!players[i].mo->skin) - CONS_Printf("Mobj skin: NULL!\n"); - else - CONS_Printf("Mobj skin: %s\n", ((skin_t *)players[i].mo->skin)->name); - CONS_Printf("Position: %d, %d, %d\n", players[i].mo->x, players[i].mo->y, players[i].mo->z); - if (!players[i].mo->state) - CONS_Printf("State: S_NULL\n"); - else - CONS_Printf("State: %d\n", (statenum_t)(players[i].mo->state-states)); + if (*value == '_') *value = ' '; // turn _ into spaces. + else if (*value == '.') *value = '\x1E'; // turn . into katana dot. } + } + if (!hudname) + { + HUDNAMEWRITE(skin->name); + strupr(skin->hudname); + SYMBOLCONVERT(skin->hudname) + } + } + else if (!stricmp(stoken, "realname")) + { // Display name (eg. "Knuckles") + realname = true; + STRBUFCPY(skin->realname, value); + SYMBOLCONVERT(skin->realname) + if (!hudname) + HUDNAMEWRITE(skin->realname); + } + else if (!stricmp(stoken, "hudname")) + { // Life icon name (eg. "K.T.E") + hudname = true; + HUDNAMEWRITE(value); + SYMBOLCONVERT(skin->hudname) + if (!realname) + STRBUFCPY(skin->realname, skin->hudname); + } + else if (!stricmp(stoken, "availability")) + { + skin->availability = atoi(value); + if (skin->availability >= MAXUNLOCKABLES) + skin->availability = 0; + } + else if (!R_ProcessPatchableFields(skin, stoken, value)) + CONS_Debug(DBG_SETUP, "R_AddSkins: Unknown keyword '%s' in S_SKIN lump #%d (WAD %s)\n", stoken, lump, wadfiles[wadnum]->filename); + +next_token: + stoken = strtok(NULL, "\r\n= "); + } + free(buf2); + + // Add sprites + R_LoadSkinSprites(wadnum, &lump, &lastlump, skin); + //ST_LoadFaceGraphics(numskins); -- nah let's do this elsewhere + + R_FlushTranslationColormapCache(); + + if (!skin->availability) // Safe to print... + CONS_Printf(M_GetText("Added skin '%s'\n"), skin->name); +#ifdef SKINVALUES + skin_cons_t[numskins].value = numskins; + skin_cons_t[numskins].strvalue = skin->name; +#endif + +#ifdef HWRENDER + if (rendermode == render_opengl) + HWR_AddPlayerModel(numskins); +#endif + + numskins++; + } + return; +} + +// +// Patch skin sprites +// +void R_PatchSkins(UINT16 wadnum) +{ + UINT16 lump, lastlump = 0; + char *buf; + char *buf2; + char *stoken; + char *value; + size_t size; + skin_t *skin; + boolean noskincomplain, realname, hudname; + + // + // search for all skin patch markers in pwad + // + + while ((lump = W_CheckForPatchSkinMarkerInPwad(wadnum, lastlump)) != INT16_MAX) + { + INT32 skinnum = 0; + + // advance by default + lastlump = lump + 1; + + buf = W_CacheLumpNumPwad(wadnum, lump, PU_CACHE); + size = W_LumpLengthPwad(wadnum, lump); + + // for strtok + buf2 = malloc(size+1); + if (!buf2) + I_Error("R_PatchSkins: No more free memory\n"); + M_Memcpy(buf2,buf,size); + buf2[size] = '\0'; + + skin = NULL; + noskincomplain = realname = hudname = false; + + /* + Parse. Has more phases than the parser in R_AddSkins because it needs to have the patching name first (no default skin name is acceptible for patching, unlike skin creation) + */ + + stoken = strtok(buf2, "\r\n= "); + while (stoken) + { + if ((stoken[0] == '/' && stoken[1] == '/') + || (stoken[0] == '#'))// skip comments + { + stoken = strtok(NULL, "\r\n"); // skip end of line + goto next_token; // find the real next token + } + + value = strtok(NULL, "\r\n= "); + + if (!value) + I_Error("R_PatchSkins: syntax error in P_SKIN lump# %d(%s) in WAD %s\n", lump, W_CheckNameForNumPwad(wadnum,lump), wadfiles[wadnum]->filename); + + if (!skin) // Get the name! + { + if (!stricmp(stoken, "name")) + { + strlwr(value); + skinnum = R_SkinAvailable(value); + if (skinnum != -1) + skin = &skins[skinnum]; else - CONS_Printf("Mobj: NULL\n"); - CONS_Printf("-------------------------------------\n"); - } - } - break; - case KICK_MSG_TIMEOUT: - HU_AddChatText(va("\x82*%s left the game (Connection timeout)", player_names[pnum]), false); - kickreason = KR_TIMEOUT; - break; - case KICK_MSG_PLAYER_QUIT: - if (netgame && !players[pnum].quittime) // not splitscreen/bots or soulless body - HU_AddChatText(va("\x82*%s left the game", player_names[pnum]), false); - kickreason = KR_LEAVE; - break; - case KICK_MSG_BANNED: - HU_AddChatText(va("\x82*%s has been banned (Don't come back)", player_names[pnum]), false); - kickreason = KR_BAN; - break; - case KICK_MSG_CUSTOM_KICK: - READSTRINGN(*p, reason, MAX_REASONLENGTH+1); - HU_AddChatText(va("\x82*%s has been kicked (%s)", player_names[pnum], reason), false); - kickreason = KR_KICK; - break; - case KICK_MSG_CUSTOM_BAN: - READSTRINGN(*p, reason, MAX_REASONLENGTH+1); - HU_AddChatText(va("\x82*%s has been banned (%s)", player_names[pnum], reason), false); - kickreason = KR_BAN; - break; - } - - if (pnum == consoleplayer) - { - if (Playing()) - LUAh_GameQuit(); -#ifdef DUMPCONSISTENCY - if (msg == KICK_MSG_CON_FAIL) SV_SavedGame(); -#endif - D_QuitNetGame(); - CL_Reset(); - D_StartTitle(); - if (msg == KICK_MSG_CON_FAIL) - M_StartMessage(M_GetText("Server closed connection\n(synch failure)\nPress ESC\n"), NULL, MM_NOTHING); - else if (msg == KICK_MSG_PING_HIGH) - M_StartMessage(M_GetText("Server closed connection\n(Broke ping limit)\nPress ESC\n"), NULL, MM_NOTHING); - else if (msg == KICK_MSG_BANNED) - M_StartMessage(M_GetText("You have been banned by the server\n\nPress ESC\n"), NULL, MM_NOTHING); - else if (msg == KICK_MSG_CUSTOM_KICK) - M_StartMessage(va(M_GetText("You have been kicked\n(%s)\nPress ESC\n"), reason), NULL, MM_NOTHING); - else if (msg == KICK_MSG_CUSTOM_BAN) - M_StartMessage(va(M_GetText("You have been banned\n(%s)\nPress ESC\n"), reason), NULL, MM_NOTHING); - else - M_StartMessage(M_GetText("You have been kicked by the server\n\nPress ESC\n"), NULL, MM_NOTHING); - } - else if (keepbody) - { - if (server && !demoplayback && playernode[pnum] != UINT8_MAX) - { - INT32 node = playernode[pnum]; - playerpernode[node]--; - if (playerpernode[node] <= 0) - { - nodeingame[node] = false; - Net_CloseConnection(node); - ResetNode(node); - } - } - - playernode[pnum] = UINT8_MAX; - - players[pnum].quittime = 1; - } - else - CL_RemovePlayer(pnum, kickreason); -} - -static void Command_ResendGamestate(void) -{ - SINT8 playernum; - - if (COM_Argc() == 1) - { - CONS_Printf(M_GetText("resendgamestate : resend the game state to a player\n")); - return; - } - else if (client) - { - CONS_Printf(M_GetText("Only the server can use this.\n")); - return; - } - - playernum = nametonum(COM_Argv(1)); - if (playernum == -1 || playernum == 0) - return; - - // Send a PT_WILLRESENDGAMESTATE packet to the client so they know what's going on - netbuffer->packettype = PT_WILLRESENDGAMESTATE; - if (!HSendPacket(playernode[playernum], true, 0, 0)) - { - CONS_Alert(CONS_ERROR, M_GetText("A problem occured, please try again.\n")); - return; - } -} - -static CV_PossibleValue_t netticbuffer_cons_t[] = {{0, "MIN"}, {3, "MAX"}, {0, NULL}}; -consvar_t cv_netticbuffer = CVAR_INIT ("netticbuffer", "1", CV_SAVE, netticbuffer_cons_t, NULL); - -consvar_t cv_allownewplayer = CVAR_INIT ("allowjoin", "On", CV_SAVE|CV_NETVAR, CV_OnOff, NULL); -consvar_t cv_joinnextround = CVAR_INIT ("joinnextround", "Off", CV_SAVE|CV_NETVAR, CV_OnOff, NULL); /// \todo not done -static CV_PossibleValue_t maxplayers_cons_t[] = {{2, "MIN"}, {32, "MAX"}, {0, NULL}}; -consvar_t cv_maxplayers = CVAR_INIT ("maxplayers", "8", CV_SAVE|CV_NETVAR, maxplayers_cons_t, NULL); -static CV_PossibleValue_t joindelay_cons_t[] = {{1, "MIN"}, {3600, "MAX"}, {0, "Off"}, {0, NULL}}; -consvar_t cv_joindelay = CVAR_INIT ("joindelay", "10", CV_SAVE|CV_NETVAR, joindelay_cons_t, NULL); -static CV_PossibleValue_t rejointimeout_cons_t[] = {{1, "MIN"}, {60 * FRACUNIT, "MAX"}, {0, "Off"}, {0, NULL}}; -consvar_t cv_rejointimeout = CVAR_INIT ("rejointimeout", "Off", CV_SAVE|CV_NETVAR|CV_FLOAT, rejointimeout_cons_t, NULL); - -static CV_PossibleValue_t resynchattempts_cons_t[] = {{1, "MIN"}, {20, "MAX"}, {0, "No"}, {0, NULL}}; -consvar_t cv_resynchattempts = CVAR_INIT ("resynchattempts", "10", CV_SAVE|CV_NETVAR, resynchattempts_cons_t, NULL); -consvar_t cv_blamecfail = CVAR_INIT ("blamecfail", "Off", CV_SAVE|CV_NETVAR, CV_OnOff, NULL); - -// max file size to send to a player (in kilobytes) -static CV_PossibleValue_t maxsend_cons_t[] = {{0, "MIN"}, {51200, "MAX"}, {0, NULL}}; -consvar_t cv_maxsend = CVAR_INIT ("maxsend", "4096", CV_SAVE|CV_NETVAR, maxsend_cons_t, NULL); -consvar_t cv_noticedownload = CVAR_INIT ("noticedownload", "Off", CV_SAVE|CV_NETVAR, CV_OnOff, NULL); - -// Speed of file downloading (in packets per tic) -static CV_PossibleValue_t downloadspeed_cons_t[] = {{0, "MIN"}, {32, "MAX"}, {0, NULL}}; -consvar_t cv_downloadspeed = CVAR_INIT ("downloadspeed", "16", CV_SAVE|CV_NETVAR, downloadspeed_cons_t, NULL); - -static void Got_AddPlayer(UINT8 **p, INT32 playernum); - -// called one time at init -void D_ClientServerInit(void) -{ - DEBFILE(va("- - -== SRB2 v%d.%.2d.%d "VERSIONSTRING" debugfile ==- - -\n", - VERSION/100, VERSION%100, SUBVERSION)); - -#ifndef NONET - COM_AddCommand("getplayernum", Command_GetPlayerNum); - COM_AddCommand("kick", Command_Kick); - COM_AddCommand("ban", Command_Ban); - COM_AddCommand("banip", Command_BanIP); - COM_AddCommand("clearbans", Command_ClearBans); - COM_AddCommand("showbanlist", Command_ShowBan); - COM_AddCommand("reloadbans", Command_ReloadBan); - COM_AddCommand("connect", Command_connect); - COM_AddCommand("nodes", Command_Nodes); - COM_AddCommand("resendgamestate", Command_ResendGamestate); -#ifdef PACKETDROP - COM_AddCommand("drop", Command_Drop); - COM_AddCommand("droprate", Command_Droprate); -#endif -#ifdef _DEBUG - COM_AddCommand("numnodes", Command_Numnodes); -#endif -#endif - - RegisterNetXCmd(XD_KICK, Got_KickCmd); - RegisterNetXCmd(XD_ADDPLAYER, Got_AddPlayer); -#ifndef NONET -#ifdef DUMPCONSISTENCY - CV_RegisterVar(&cv_dumpconsistency); -#endif - Ban_Load_File(false); -#endif - - gametic = 0; - localgametic = 0; - - // do not send anything before the real begin - SV_StopServer(); - SV_ResetServer(); - if (dedicated) - SV_SpawnServer(); -} - -static void ResetNode(INT32 node) -{ - nodeingame[node] = false; - nodewaiting[node] = 0; - - nettics[node] = gametic; - supposedtics[node] = gametic; - - nodetoplayer[node] = -1; - nodetoplayer2[node] = -1; - playerpernode[node] = 0; - - sendingsavegame[node] = false; - resendingsavegame[node] = false; - savegameresendcooldown[node] = 0; -} - -void SV_ResetServer(void) -{ - INT32 i; - - // +1 because this command will be executed in com_executebuffer in - // tryruntic so gametic will be incremented, anyway maketic > gametic - // is not an issue - - maketic = gametic + 1; - neededtic = maketic; - tictoclear = maketic; - - joindelay = 0; - - for (i = 0; i < MAXNETNODES; i++) - ResetNode(i); - - for (i = 0; i < MAXPLAYERS; i++) - { - LUA_InvalidatePlayer(&players[i]); - playeringame[i] = false; - playernode[i] = UINT8_MAX; - memset(playeraddress[i], 0, sizeof(*playeraddress)); - sprintf(player_names[i], "Player %d", i + 1); - adminplayers[i] = -1; // Populate the entire adminplayers array with -1. - } - - memset(player_name_changes, 0, sizeof player_name_changes); - - mynode = 0; - cl_packetmissed = false; - cl_redownloadinggamestate = false; - - if (dedicated) - { - nodeingame[0] = true; - serverplayer = 0; - } - else - serverplayer = consoleplayer; - - if (server) - servernode = 0; - - doomcom->numslots = 0; - - // clear server_context - memset(server_context, '-', 8); - - DEBFILE("\n-=-=-=-=-=-=-= Server Reset =-=-=-=-=-=-=-\n\n"); -} - -static inline void SV_GenContext(void) -{ - UINT8 i; - // generate server_context, as exactly 8 bytes of randomly mixed A-Z and a-z - // (hopefully M_Random is initialized!! if not this will be awfully silly!) - for (i = 0; i < 8; i++) - { - const char a = M_RandomKey(26*2); - if (a < 26) // uppercase - server_context[i] = 'A'+a; - else // lowercase - server_context[i] = 'a'+(a-26); - } -} - -// -// D_QuitNetGame -// Called before quitting to leave a net game -// without hanging the other players -// -void D_QuitNetGame(void) -{ - if (!netgame || !netbuffer) - return; - - DEBFILE("===========================================================================\n" - " Quitting Game, closing connection\n" - "===========================================================================\n"); - - // abort send/receive of files - CloseNetFile(); - RemoveAllLuaFileTransfers(); - waitingforluafiletransfer = false; - waitingforluafilecommand = false; - - if (server) - { - INT32 i; - - netbuffer->packettype = PT_SERVERSHUTDOWN; - for (i = 0; i < MAXNETNODES; i++) - if (nodeingame[i]) - HSendPacket(i, true, 0, 0); -#ifdef MASTERSERVER - if (serverrunning && ms_RoomId > 0) - UnregisterServer(); -#endif - } - else if (servernode > 0 && servernode < MAXNETNODES && nodeingame[(UINT8)servernode]) - { - netbuffer->packettype = PT_CLIENTQUIT; - HSendPacket(servernode, true, 0, 0); - } - - D_CloseConnection(); - ClearAdminPlayers(); - - DEBFILE("===========================================================================\n" - " Log finish\n" - "===========================================================================\n"); -#ifdef DEBUGFILE - if (debugfile) - { - fclose(debugfile); - debugfile = NULL; - } -#endif -} - -// Adds a node to the game (player will follow at map change or at savegame....) -static inline void SV_AddNode(INT32 node) -{ - nettics[node] = gametic; - supposedtics[node] = gametic; - // little hack because the server connects to itself and puts - // nodeingame when connected not here - if (node) - nodeingame[node] = true; -} - -// Xcmd XD_ADDPLAYER -static void Got_AddPlayer(UINT8 **p, INT32 playernum) -{ - INT16 node, newplayernum; - boolean splitscreenplayer; - boolean rejoined; - player_t *newplayer; - - if (playernum != serverplayer && !IsPlayerAdmin(playernum)) - { - // protect against hacked/buggy client - CONS_Alert(CONS_WARNING, M_GetText("Illegal add player command received from %s\n"), player_names[playernum]); - if (server) - SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY); - return; - } - - node = READUINT8(*p); - newplayernum = READUINT8(*p); - splitscreenplayer = newplayernum & 0x80; - newplayernum &= ~0x80; - - rejoined = playeringame[newplayernum]; - - if (!rejoined) - { - // Clear player before joining, lest some things get set incorrectly - // HACK: don't do this for splitscreen, it relies on preset values - if (!splitscreen && !botingame) - CL_ClearPlayer(newplayernum); - playeringame[newplayernum] = true; - G_AddPlayer(newplayernum); - if (newplayernum+1 > doomcom->numslots) - doomcom->numslots = (INT16)(newplayernum+1); - - if (server && I_GetNodeAddress) - { - const char *address = I_GetNodeAddress(node); - char *port = NULL; - if (address) // MI: fix msvcrt.dll!_mbscat crash? - { - strcpy(playeraddress[newplayernum], address); - port = strchr(playeraddress[newplayernum], ':'); - if (port) - *port = '\0'; - } - } - } - - newplayer = &players[newplayernum]; - - newplayer->jointime = 0; - newplayer->quittime = 0; - - READSTRINGN(*p, player_names[newplayernum], MAXPLAYERNAME); - - // the server is creating my player - if (node == mynode) - { - playernode[newplayernum] = 0; // for information only - if (!splitscreenplayer) - { - consoleplayer = newplayernum; - displayplayer = newplayernum; - secondarydisplayplayer = newplayernum; - DEBFILE("spawning me\n"); - ticcmd_oldangleturn[0] = newplayer->oldrelangleturn; - } - else - { - secondarydisplayplayer = newplayernum; - DEBFILE("spawning my brother\n"); - if (botingame) - newplayer->bot = 1; - ticcmd_oldangleturn[1] = newplayer->oldrelangleturn; - } - P_ForceLocalAngle(newplayer, (angle_t)(newplayer->angleturn << 16)); - D_SendPlayerConfig(); - addedtogame = true; - - if (rejoined) - { - if (newplayer->mo) - { - newplayer->viewheight = 41*newplayer->height/48; - - if (newplayer->mo->eflags & MFE_VERTICALFLIP) - newplayer->viewz = newplayer->mo->z + newplayer->mo->height - newplayer->viewheight; - else - newplayer->viewz = newplayer->mo->z + newplayer->viewheight; - } - - // wake up the status bar - ST_Start(); - // wake up the heads up text - HU_Start(); - - if (camera.chase && !splitscreenplayer) - P_ResetCamera(newplayer, &camera); - if (camera2.chase && splitscreenplayer) - P_ResetCamera(newplayer, &camera2); - } - } - - if (netgame) - { - char joinmsg[256]; - - if (rejoined) - strcpy(joinmsg, M_GetText("\x82*%s has rejoined the game (player %d)")); - else - strcpy(joinmsg, M_GetText("\x82*%s has joined the game (player %d)")); - strcpy(joinmsg, va(joinmsg, player_names[newplayernum], newplayernum)); - - // Merge join notification + IP to avoid clogging console/chat - if (server && cv_showjoinaddress.value && I_GetNodeAddress) - { - const char *address = I_GetNodeAddress(node); - if (address) - strcat(joinmsg, va(" (%s)", address)); - } - - HU_AddChatText(joinmsg, false); - } - - if (server && multiplayer && motd[0] != '\0') - COM_BufAddText(va("sayto %d %s\n", newplayernum, motd)); - - if (!rejoined) - LUAh_PlayerJoin(newplayernum); -} - -static boolean SV_AddWaitingPlayers(const char *name, const char *name2) -{ - INT32 node, n, newplayer = false; - UINT8 buf[2 + MAXPLAYERNAME]; - UINT8 *p; - INT32 newplayernum; - - for (node = 0; node < MAXNETNODES; node++) - { - // splitscreen can allow 2 player in one node - for (; nodewaiting[node] > 0; nodewaiting[node]--) - { - newplayer = true; - - newplayernum = FindRejoinerNum(node); - if (newplayernum == -1) - { - // search for a free playernum - // we can't use playeringame since it is not updated here - for (newplayernum = dedicated ? 1 : 0; newplayernum < MAXPLAYERS; newplayernum++) - { - if (playeringame[newplayernum]) - continue; - for (n = 0; n < MAXNETNODES; n++) - if (nodetoplayer[n] == newplayernum || nodetoplayer2[n] == newplayernum) - break; - if (n == MAXNETNODES) - break; - } - } - - // should never happen since we check the playernum - // before accepting the join - I_Assert(newplayernum < MAXPLAYERS); - - playernode[newplayernum] = (UINT8)node; - - p = buf + 2; - buf[0] = (UINT8)node; - buf[1] = newplayernum; - if (playerpernode[node] < 1) - { - nodetoplayer[node] = newplayernum; - WRITESTRINGN(p, name, MAXPLAYERNAME); - } - else - { - nodetoplayer2[node] = newplayernum; - buf[1] |= 0x80; - WRITESTRINGN(p, name2, MAXPLAYERNAME); - } - playerpernode[node]++; - - SendNetXCmd(XD_ADDPLAYER, &buf, p - buf); - - DEBFILE(va("Server added player %d node %d\n", newplayernum, node)); - } - } - - return newplayer; -} - -void CL_AddSplitscreenPlayer(void) -{ - if (cl_mode == CL_CONNECTED) - CL_SendJoin(); -} - -void CL_RemoveSplitscreenPlayer(void) -{ - if (cl_mode != CL_CONNECTED) - return; - - SendKick(secondarydisplayplayer, KICK_MSG_PLAYER_QUIT); -} - -// is there a game running -boolean Playing(void) -{ - return (server && serverrunning) || (client && cl_mode == CL_CONNECTED); -} - -boolean SV_SpawnServer(void) -{ - if (demoplayback) - G_StopDemo(); // reset engine parameter - if (metalplayback) - G_StopMetalDemo(); - - if (!serverrunning) - { - CONS_Printf(M_GetText("Starting Server....\n")); - serverrunning = true; - SV_ResetServer(); - SV_GenContext(); - if (netgame && I_NetOpenSocket) - { - I_NetOpenSocket(); -#ifdef MASTERSERVER - if (ms_RoomId > 0) - RegisterServer(); -#endif - } - - // non dedicated server just connect to itself - if (!dedicated) - CL_ConnectToServer(); - else doomcom->numslots = 1; - } - - return SV_AddWaitingPlayers(cv_playername.zstring, cv_playername2.zstring); -} - -void SV_StopServer(void) -{ - tic_t i; - - if (gamestate == GS_INTERMISSION) - Y_EndIntermission(); - gamestate = wipegamestate = GS_NULL; - - localtextcmd[0] = 0; - localtextcmd2[0] = 0; - - for (i = firstticstosend; i < firstticstosend + BACKUPTICS; i++) - D_Clearticcmd(i); - - consoleplayer = 0; - cl_mode = CL_SEARCHING; - maketic = gametic+1; - neededtic = maketic; - serverrunning = false; -} - -// called at singleplayer start and stopdemo -void SV_StartSinglePlayerServer(void) -{ - server = true; - netgame = false; - multiplayer = false; - G_SetGametype(GT_COOP); - - // no more tic the game with this settings! - SV_StopServer(); - - if (splitscreen) - multiplayer = true; -} - -static void SV_SendRefuse(INT32 node, const char *reason) -{ - strcpy(netbuffer->u.serverrefuse.reason, reason); - - netbuffer->packettype = PT_SERVERREFUSE; - HSendPacket(node, true, 0, strlen(netbuffer->u.serverrefuse.reason) + 1); - Net_CloseConnection(node); -} - -// used at txtcmds received to check packetsize bound -static size_t TotalTextCmdPerTic(tic_t tic) -{ - INT32 i; - size_t total = 1; // num of textcmds in the tic (ntextcmd byte) - - for (i = 0; i < MAXPLAYERS; i++) - { - UINT8 *textcmd = D_GetExistingTextcmd(tic, i); - if ((!i || playeringame[i]) && textcmd) - total += 2 + textcmd[0]; // "+2" for size and playernum - } - - return total; -} - -/** Called when a PT_CLIENTJOIN packet is received - * - * \param node The packet sender - * - */ -static void HandleConnect(SINT8 node) -{ - char names[MAXSPLITSCREENPLAYERS][MAXPLAYERNAME + 1]; - INT32 rejoinernum; - INT32 i; - - rejoinernum = FindRejoinerNum(node); - - if (bannednode && bannednode[node]) - SV_SendRefuse(node, M_GetText("You have been banned\nfrom the server.")); - else if (netbuffer->u.clientcfg._255 != 255 || - netbuffer->u.clientcfg.packetversion != PACKETVERSION) - SV_SendRefuse(node, "Incompatible packet formats."); - else if (strncmp(netbuffer->u.clientcfg.application, SRB2APPLICATION, - sizeof netbuffer->u.clientcfg.application)) - SV_SendRefuse(node, "Different SRB2 modifications\nare not compatible."); - else if (netbuffer->u.clientcfg.version != VERSION - || netbuffer->u.clientcfg.subversion != SUBVERSION) - SV_SendRefuse(node, va(M_GetText("Different SRB2 versions cannot\nplay a netgame!\n(server version %d.%d.%d)"), VERSION/100, VERSION%100, SUBVERSION)); - else if (!cv_allownewplayer.value && node && rejoinernum == -1) - SV_SendRefuse(node, M_GetText("The server is not accepting\njoins for the moment.")); - else if (D_NumPlayers() >= cv_maxplayers.value && rejoinernum == -1) - SV_SendRefuse(node, va(M_GetText("Maximum players reached: %d"), cv_maxplayers.value)); - else if (netgame && netbuffer->u.clientcfg.localplayers > 1) // Hacked client? - SV_SendRefuse(node, M_GetText("Too many players from\nthis node.")); - else if (netgame && !netbuffer->u.clientcfg.localplayers) // Stealth join? - SV_SendRefuse(node, M_GetText("No players from\nthis node.")); - else if (luafiletransfers) - SV_SendRefuse(node, M_GetText("The server is broadcasting a file\nrequested by a Lua script.\nPlease wait a bit and then\ntry rejoining.")); - else if (netgame && joindelay > 2 * (tic_t)cv_joindelay.value * TICRATE) - SV_SendRefuse(node, va(M_GetText("Too many people are connecting.\nPlease wait %d seconds and then\ntry rejoining."), - (joindelay - 2 * cv_joindelay.value * TICRATE) / TICRATE)); - else - { -#ifndef NONET - boolean newnode = false; -#endif - - for (i = 0; i < netbuffer->u.clientcfg.localplayers - playerpernode[node]; i++) - { - strlcpy(names[i], netbuffer->u.clientcfg.names[i], MAXPLAYERNAME + 1); - if (!EnsurePlayerNameIsGood(names[i], rejoinernum)) - { - SV_SendRefuse(node, "Bad player name"); - return; - } - } - - // client authorised to join - nodewaiting[node] = (UINT8)(netbuffer->u.clientcfg.localplayers - playerpernode[node]); - if (!nodeingame[node]) - { - gamestate_t backupstate = gamestate; -#ifndef NONET - newnode = true; -#endif - SV_AddNode(node); - - if (cv_joinnextround.value && gameaction == ga_nothing) - G_SetGamestate(GS_WAITINGPLAYERS); - if (!SV_SendServerConfig(node)) - { - G_SetGamestate(backupstate); - /// \note Shouldn't SV_SendRefuse be called before ResetNode? - ResetNode(node); - SV_SendRefuse(node, M_GetText("Server couldn't send info, please try again")); - /// \todo fix this !!! - return; // restart the while - } - //if (gamestate != GS_LEVEL) // GS_INTERMISSION, etc? - // SV_SendPlayerConfigs(node); // send bare minimum player info - G_SetGamestate(backupstate); - DEBFILE("new node joined\n"); - } -#ifndef NONET - if (nodewaiting[node]) - { - if ((gamestate == GS_LEVEL || gamestate == GS_INTERMISSION) && newnode) - { - SV_SendSaveGame(node, false); // send a complete game state - DEBFILE("send savegame\n"); - } - SV_AddWaitingPlayers(names[0], names[1]); - joindelay += cv_joindelay.value * TICRATE; - player_joining = true; - } -#endif - } -} - -/** Called when a PT_SERVERSHUTDOWN packet is received - * - * \param node The packet sender (should be the server) - * - */ -static void HandleShutdown(SINT8 node) -{ - (void)node; - if (Playing()) - LUAh_GameQuit(); - D_QuitNetGame(); - CL_Reset(); - D_StartTitle(); - M_StartMessage(M_GetText("Server has shutdown\n\nPress Esc\n"), NULL, MM_NOTHING); -} - -/** Called when a PT_NODETIMEOUT packet is received - * - * \param node The packet sender (should be the server) - * - */ -static void HandleTimeout(SINT8 node) -{ - (void)node; - if (Playing()) - LUAh_GameQuit(); - D_QuitNetGame(); - CL_Reset(); - D_StartTitle(); - M_StartMessage(M_GetText("Server Timeout\n\nPress Esc\n"), NULL, MM_NOTHING); -} - -#ifndef NONET -/** Called when a PT_SERVERINFO packet is received - * - * \param node The packet sender - * \note What happens if the packet comes from a client or something like that? - * - */ -static void HandleServerInfo(SINT8 node) -{ - // compute ping in ms - const tic_t ticnow = I_GetTime(); - const tic_t ticthen = (tic_t)LONG(netbuffer->u.serverinfo.time); - const tic_t ticdiff = (ticnow - ticthen)*1000/NEWTICRATE; - netbuffer->u.serverinfo.time = (tic_t)LONG(ticdiff); - netbuffer->u.serverinfo.servername[MAXSERVERNAME-1] = 0; - netbuffer->u.serverinfo.application - [sizeof netbuffer->u.serverinfo.application - 1] = '\0'; - netbuffer->u.serverinfo.gametypename - [sizeof netbuffer->u.serverinfo.gametypename - 1] = '\0'; - - SL_InsertServer(&netbuffer->u.serverinfo, node); -} -#endif - -static void PT_WillResendGamestate(void) -{ - char tmpsave[256]; - - if (server || cl_redownloadinggamestate) - return; - - // Send back a PT_CANRECEIVEGAMESTATE packet to the server - // so they know they can start sending the game state - netbuffer->packettype = PT_CANRECEIVEGAMESTATE; - if (!HSendPacket(servernode, true, 0, 0)) - return; - - CONS_Printf(M_GetText("Reloading game state...\n")); - - sprintf(tmpsave, "%s" PATHSEP TMPSAVENAME, srb2home); - - // Don't get a corrupt savegame error because tmpsave already exists - if (FIL_FileExists(tmpsave) && unlink(tmpsave) == -1) - I_Error("Can't delete %s\n", tmpsave); - - CL_PrepareDownloadSaveGame(tmpsave); - - cl_redownloadinggamestate = true; -} - -static void PT_CanReceiveGamestate(SINT8 node) -{ - if (client || sendingsavegame[node]) - return; - - CONS_Printf(M_GetText("Resending game state to %s...\n"), player_names[nodetoplayer[node]]); - - SV_SendSaveGame(node, true); // Resend a complete game state - resendingsavegame[node] = true; -} - -/** Handles a packet received from a node that isn't in game - * - * \param node The packet sender - * \todo Choose a better name, as the packet can also come from the server apparently? - * \sa HandlePacketFromPlayer - * \sa GetPackets - * - */ -static void HandlePacketFromAwayNode(SINT8 node) -{ - if (node != servernode) - DEBFILE(va("Received packet from unknown host %d\n", node)); - -// macro for packets that should only be sent by the server -// if it is NOT from the server, bail out and close the connection! -#define SERVERONLY \ - if (node != servernode) \ - { \ - Net_CloseConnection(node); \ - break; \ - } - switch (netbuffer->packettype) - { - case PT_ASKINFOVIAMS: -#if 0 - if (server && serverrunning) - { - INT32 clientnode; - if (ms_RoomId < 0) // ignore if we're not actually on the MS right now - { - Net_CloseConnection(node); // and yes, close connection - return; - } - clientnode = I_NetMakeNode(netbuffer->u.msaskinfo.clientaddr); - if (clientnode != -1) - { - SV_SendServerInfo(clientnode, (tic_t)LONG(netbuffer->u.msaskinfo.time)); - SV_SendPlayerInfo(clientnode); // Send extra info - Net_CloseConnection(clientnode); - // Don't close connection to MS... - } - else - Net_CloseConnection(node); // ...unless the IP address is not valid - } - else - Net_CloseConnection(node); // you're not supposed to get it, so ignore it -#else - Net_CloseConnection(node); -#endif - break; - - case PT_ASKINFO: - if (server && serverrunning) - { - SV_SendServerInfo(node, (tic_t)LONG(netbuffer->u.askinfo.time)); - SV_SendPlayerInfo(node); // Send extra info - } - Net_CloseConnection(node); - break; - - case PT_SERVERREFUSE: // Negative response of client join request - if (server && serverrunning) - { // But wait I thought I'm the server? - Net_CloseConnection(node); - break; - } - SERVERONLY - if (cl_mode == CL_WAITJOINRESPONSE) - { - // Save the reason so it can be displayed after quitting the netgame - char *reason = strdup(netbuffer->u.serverrefuse.reason); - if (!reason) - I_Error("Out of memory!\n"); - - D_QuitNetGame(); - CL_Reset(); - D_StartTitle(); - - M_StartMessage(va(M_GetText("Server refuses connection\n\nReason:\n%s"), - reason), NULL, MM_NOTHING); - - free(reason); - - // Will be reset by caller. Signals refusal. - cl_mode = CL_ABORTED; - } - break; - - case PT_SERVERCFG: // Positive response of client join request - { - if (server && serverrunning && node != servernode) - { // but wait I thought I'm the server? - Net_CloseConnection(node); - break; - } - SERVERONLY - /// \note how would this happen? and is it doing the right thing if it does? - if (cl_mode != CL_WAITJOINRESPONSE) - break; - - if (client) - { - maketic = gametic = neededtic = (tic_t)LONG(netbuffer->u.servercfg.gametic); - G_SetGametype(netbuffer->u.servercfg.gametype); - modifiedgame = netbuffer->u.servercfg.modifiedgame; - memcpy(server_context, netbuffer->u.servercfg.server_context, 8); - } - - nodeingame[(UINT8)servernode] = true; - serverplayer = netbuffer->u.servercfg.serverplayer; - doomcom->numslots = SHORT(netbuffer->u.servercfg.totalslotnum); - mynode = netbuffer->u.servercfg.clientnode; - if (serverplayer >= 0) - playernode[(UINT8)serverplayer] = servernode; - - if (netgame) -#ifndef NONET - CONS_Printf(M_GetText("Join accepted, waiting for complete game state...\n")); -#else - CONS_Printf(M_GetText("Join accepted, waiting for next level change...\n")); -#endif - DEBFILE(va("Server accept join gametic=%u mynode=%d\n", gametic, mynode)); - -#ifndef NONET - /// \note Wait. What if a Lua script uses some global custom variables synched with the NetVars hook? - /// Shouldn't them be downloaded even at intermission time? - /// Also, according to HandleConnect, the server will send the savegame even during intermission... - if (netbuffer->u.servercfg.gamestate == GS_LEVEL/* || - netbuffer->u.servercfg.gamestate == GS_INTERMISSION*/) - cl_mode = CL_DOWNLOADSAVEGAME; - else -#endif - cl_mode = CL_CONNECTED; - break; - } - - // Handled in d_netfil.c - case PT_FILEFRAGMENT: - if (server) - { // But wait I thought I'm the server? - Net_CloseConnection(node); - break; - } - SERVERONLY - PT_FileFragment(); - break; - - case PT_FILEACK: - if (server) - PT_FileAck(); - break; - - case PT_FILERECEIVED: - if (server) - PT_FileReceived(); - break; - - case PT_REQUESTFILE: - if (server) - { - if (!cv_downloading.value || !PT_RequestFile(node)) - Net_CloseConnection(node); // close connection if one of the requested files could not be sent, or you disabled downloading anyway - } - else - Net_CloseConnection(node); // nope - break; - - case PT_NODETIMEOUT: - case PT_CLIENTQUIT: - if (server) - Net_CloseConnection(node); - break; - - case PT_CLIENTCMD: - break; // This is not an "unknown packet" - - case PT_SERVERTICS: - // Do not remove my own server (we have just get a out of order packet) - if (node == servernode) - break; - /* FALLTHRU */ - - default: - DEBFILE(va("unknown packet received (%d) from unknown host\n",netbuffer->packettype)); - Net_CloseConnection(node); - break; // Ignore it - - } -#undef SERVERONLY -} - -/** Handles a packet received from a node that is in game - * - * \param node The packet sender - * \todo Choose a better name - * \sa HandlePacketFromAwayNode - * \sa GetPackets - * - */ -static void HandlePacketFromPlayer(SINT8 node) -{ - INT32 netconsole; - tic_t realend, realstart; - UINT8 *pak, *txtpak, numtxtpak; -#ifndef NOMD5 - UINT8 finalmd5[16];/* Well, it's the cool thing to do? */ -#endif - - txtpak = NULL; - - if (dedicated && node == 0) - netconsole = 0; - else - netconsole = nodetoplayer[node]; -#ifdef PARANOIA - if (netconsole >= MAXPLAYERS) - I_Error("bad table nodetoplayer: node %d player %d", doomcom->remotenode, netconsole); -#endif - - switch (netbuffer->packettype) - { -// -------------------------------------------- SERVER RECEIVE ---------- - case PT_CLIENTCMD: - case PT_CLIENT2CMD: - case PT_CLIENTMIS: - case PT_CLIENT2MIS: - case PT_NODEKEEPALIVE: - case PT_NODEKEEPALIVEMIS: - if (client) - break; - - // To save bytes, only the low byte of tic numbers are sent - // Use ExpandTics to figure out what the rest of the bytes are - realstart = ExpandTics(netbuffer->u.clientpak.client_tic, node); - realend = ExpandTics(netbuffer->u.clientpak.resendfrom, node); - - if (netbuffer->packettype == PT_CLIENTMIS || netbuffer->packettype == PT_CLIENT2MIS - || netbuffer->packettype == PT_NODEKEEPALIVEMIS - || supposedtics[node] < realend) - { - supposedtics[node] = realend; - } - // Discard out of order packet - if (nettics[node] > realend) - { - DEBFILE(va("out of order ticcmd discarded nettics = %u\n", nettics[node])); - break; - } - - // Update the nettics - nettics[node] = realend; - - // Don't do anything for packets of type NODEKEEPALIVE? - if (netconsole == -1 || netbuffer->packettype == PT_NODEKEEPALIVE - || netbuffer->packettype == PT_NODEKEEPALIVEMIS) - break; - - // As long as clients send valid ticcmds, the server can keep running, so reset the timeout - /// \todo Use a separate cvar for that kind of timeout? - freezetimeout[node] = I_GetTime() + connectiontimeout; - - // Copy ticcmd - G_MoveTiccmd(&netcmds[maketic%BACKUPTICS][netconsole], &netbuffer->u.clientpak.cmd, 1); - - // Check ticcmd for "speed hacks" - if (netcmds[maketic%BACKUPTICS][netconsole].forwardmove > MAXPLMOVE || netcmds[maketic%BACKUPTICS][netconsole].forwardmove < -MAXPLMOVE - || netcmds[maketic%BACKUPTICS][netconsole].sidemove > MAXPLMOVE || netcmds[maketic%BACKUPTICS][netconsole].sidemove < -MAXPLMOVE) - { - CONS_Alert(CONS_WARNING, M_GetText("Illegal movement value received from node %d\n"), netconsole); - //D_Clearticcmd(k); - - SendKick(netconsole, KICK_MSG_CON_FAIL); - break; - } - - // Splitscreen cmd - if ((netbuffer->packettype == PT_CLIENT2CMD || netbuffer->packettype == PT_CLIENT2MIS) - && nodetoplayer2[node] >= 0) - G_MoveTiccmd(&netcmds[maketic%BACKUPTICS][(UINT8)nodetoplayer2[node]], - &netbuffer->u.client2pak.cmd2, 1); - - // Check player consistancy during the level - if (realstart <= gametic && realstart + BACKUPTICS - 1 > gametic && gamestate == GS_LEVEL - && consistancy[realstart%BACKUPTICS] != SHORT(netbuffer->u.clientpak.consistancy) - && !resendingsavegame[node] && savegameresendcooldown[node] <= I_GetTime() - && !SV_ResendingSavegameToAnyone()) - { - if (cv_resynchattempts.value) - { - // Tell the client we are about to resend them the gamestate - netbuffer->packettype = PT_WILLRESENDGAMESTATE; - HSendPacket(node, true, 0, 0); - - resendingsavegame[node] = true; - - if (cv_blamecfail.value) - CONS_Printf(M_GetText("Synch failure for player %d (%s); expected %hd, got %hd\n"), - netconsole+1, player_names[netconsole], - consistancy[realstart%BACKUPTICS], - SHORT(netbuffer->u.clientpak.consistancy)); - DEBFILE(va("Restoring player %d (synch failure) [%update] %d!=%d\n", - netconsole, realstart, consistancy[realstart%BACKUPTICS], - SHORT(netbuffer->u.clientpak.consistancy))); - break; - } - else - { - SendKick(netconsole, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY); - DEBFILE(va("player %d kicked (synch failure) [%u] %d!=%d\n", - netconsole, realstart, consistancy[realstart%BACKUPTICS], - SHORT(netbuffer->u.clientpak.consistancy))); - break; - } - } - break; - case PT_TEXTCMD2: // splitscreen special - netconsole = nodetoplayer2[node]; - /* FALLTHRU */ - case PT_TEXTCMD: - if (client) - break; - - if (netconsole < 0 || netconsole >= MAXPLAYERS) - Net_UnAcknowledgePacket(node); - else - { - size_t j; - tic_t tic = maketic; - UINT8 *textcmd; - - // ignore if the textcmd has a reported size of zero - // this shouldn't be sent at all - if (!netbuffer->u.textcmd[0]) - { - DEBFILE(va("GetPacket: Textcmd with size 0 detected! (node %u, player %d)\n", - node, netconsole)); - Net_UnAcknowledgePacket(node); - break; - } - - // ignore if the textcmd size var is actually larger than it should be - // BASEPACKETSIZE + 1 (for size) + textcmd[0] should == datalength - if (netbuffer->u.textcmd[0] > (size_t)doomcom->datalength-BASEPACKETSIZE-1) - { - DEBFILE(va("GetPacket: Bad Textcmd packet size! (expected %d, actual %s, node %u, player %d)\n", - netbuffer->u.textcmd[0], sizeu1((size_t)doomcom->datalength-BASEPACKETSIZE-1), - node, netconsole)); - Net_UnAcknowledgePacket(node); - break; - } - - // check if tic that we are making isn't too large else we cannot send it :( - // doomcom->numslots+1 "+1" since doomcom->numslots can change within this time and sent time - j = software_MAXPACKETLENGTH - - (netbuffer->u.textcmd[0]+2+BASESERVERTICSSIZE - + (doomcom->numslots+1)*sizeof(ticcmd_t)); - - // search a tic that have enougth space in the ticcmd - while ((textcmd = D_GetExistingTextcmd(tic, netconsole)), - (TotalTextCmdPerTic(tic) > j || netbuffer->u.textcmd[0] + (textcmd ? textcmd[0] : 0) > MAXTEXTCMD) - && tic < firstticstosend + BACKUPTICS) - tic++; - - if (tic >= firstticstosend + BACKUPTICS) - { - DEBFILE(va("GetPacket: Textcmd too long (max %s, used %s, mak %d, " - "tosend %u, node %u, player %d)\n", sizeu1(j), sizeu2(TotalTextCmdPerTic(maketic)), - maketic, firstticstosend, node, netconsole)); - Net_UnAcknowledgePacket(node); - break; - } - - // Make sure we have a buffer - if (!textcmd) textcmd = D_GetTextcmd(tic, netconsole); - - DEBFILE(va("textcmd put in tic %u at position %d (player %d) ftts %u mk %u\n", - tic, textcmd[0]+1, netconsole, firstticstosend, maketic)); - - M_Memcpy(&textcmd[textcmd[0]+1], netbuffer->u.textcmd+1, netbuffer->u.textcmd[0]); - textcmd[0] += (UINT8)netbuffer->u.textcmd[0]; - } - break; - case PT_LOGIN: - if (client) - break; - -#ifndef NOMD5 - if (doomcom->datalength < 16)/* ignore partial sends */ - break; - - if (!adminpasswordset) - { - CONS_Printf(M_GetText("Password from %s failed (no password set).\n"), player_names[netconsole]); - break; - } - - // Do the final pass to compare with the sent md5 - D_MD5PasswordPass(adminpassmd5, 16, va("PNUM%02d", netconsole), &finalmd5); - - if (!memcmp(netbuffer->u.md5sum, finalmd5, 16)) - { - CONS_Printf(M_GetText("%s passed authentication.\n"), player_names[netconsole]); - COM_BufInsertText(va("promote %d\n", netconsole)); // do this immediately - } - else - CONS_Printf(M_GetText("Password from %s failed.\n"), player_names[netconsole]); -#endif - break; - case PT_NODETIMEOUT: - case PT_CLIENTQUIT: - if (client) - break; - - // nodeingame will be put false in the execution of kick command - // this allow to send some packets to the quitting client to have their ack back - nodewaiting[node] = 0; - if (netconsole != -1 && playeringame[netconsole]) - { - UINT8 kickmsg; - - if (netbuffer->packettype == PT_NODETIMEOUT) - kickmsg = KICK_MSG_TIMEOUT; - else - kickmsg = KICK_MSG_PLAYER_QUIT; - kickmsg |= KICK_MSG_KEEP_BODY; - - SendKick(netconsole, kickmsg); - nodetoplayer[node] = -1; - - if (nodetoplayer2[node] != -1 && nodetoplayer2[node] >= 0 - && playeringame[(UINT8)nodetoplayer2[node]]) - { - SendKick(nodetoplayer2[node], kickmsg); - nodetoplayer2[node] = -1; - } - } - Net_CloseConnection(node); - nodeingame[node] = false; - break; - case PT_CANRECEIVEGAMESTATE: - PT_CanReceiveGamestate(node); - break; - case PT_ASKLUAFILE: - if (server && luafiletransfers && luafiletransfers->nodestatus[node] == LFTNS_ASKED) - AddLuaFileToSendQueue(node, luafiletransfers->realfilename); - break; - case PT_HASLUAFILE: - if (server && luafiletransfers && luafiletransfers->nodestatus[node] == LFTNS_SENDING) - SV_HandleLuaFileSent(node); - break; - case PT_RECEIVEDGAMESTATE: - sendingsavegame[node] = false; - resendingsavegame[node] = false; - savegameresendcooldown[node] = I_GetTime() + 15 * TICRATE; - break; -// -------------------------------------------- CLIENT RECEIVE ---------- - case PT_SERVERTICS: - // Only accept PT_SERVERTICS from the server. - if (node != servernode) - { - CONS_Alert(CONS_WARNING, M_GetText("%s received from non-host %d\n"), "PT_SERVERTICS", node); - if (server) - SendKick(netconsole, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY); - break; - } - - realstart = netbuffer->u.serverpak.starttic; - realend = realstart + netbuffer->u.serverpak.numtics; - - if (!txtpak) - txtpak = (UINT8 *)&netbuffer->u.serverpak.cmds[netbuffer->u.serverpak.numslots - * netbuffer->u.serverpak.numtics]; - - if (realend > gametic + CLIENTBACKUPTICS) - realend = gametic + CLIENTBACKUPTICS; - cl_packetmissed = realstart > neededtic; - - if (realstart <= neededtic && realend > neededtic) - { - tic_t i, j; - pak = (UINT8 *)&netbuffer->u.serverpak.cmds; - - for (i = realstart; i < realend; i++) - { - // clear first - D_Clearticcmd(i); - - // copy the tics - pak = G_ScpyTiccmd(netcmds[i%BACKUPTICS], pak, - netbuffer->u.serverpak.numslots*sizeof (ticcmd_t)); - - // copy the textcmds - numtxtpak = *txtpak++; - for (j = 0; j < numtxtpak; j++) { - INT32 k = *txtpak++; // playernum - const size_t txtsize = txtpak[0]+1; - - if (i >= gametic) // Don't copy old net commands - M_Memcpy(D_GetTextcmd(i, k), txtpak, txtsize); - txtpak += txtsize; - } - } - - neededtic = realend; - } - else - { - DEBFILE(va("frame not in bound: %u\n", neededtic)); - /*if (realend < neededtic - 2 * TICRATE || neededtic + 2 * TICRATE < realstart) - I_Error("Received an out of order PT_SERVERTICS packet!\n" - "Got tics %d-%d, needed tic %d\n\n" - "Please report this crash on the Master Board,\n" - "IRC or Discord so it can be fixed.\n", (INT32)realstart, (INT32)realend, (INT32)neededtic);*/ - } - break; - case PT_PING: - // Only accept PT_PING from the server. - if (node != servernode) - { - CONS_Alert(CONS_WARNING, M_GetText("%s received from non-host %d\n"), "PT_PING", node); - if (server) - SendKick(netconsole, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY); - break; - } - - //Update client ping table from the server. - if (client) - { - UINT8 i; - for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i]) - playerpingtable[i] = (tic_t)netbuffer->u.pingtable[i]; - - servermaxping = (tic_t)netbuffer->u.pingtable[MAXPLAYERS]; - } - - break; - case PT_SERVERCFG: - break; - case PT_FILEFRAGMENT: - // Only accept PT_FILEFRAGMENT from the server. - if (node != servernode) - { - CONS_Alert(CONS_WARNING, M_GetText("%s received from non-host %d\n"), "PT_FILEFRAGMENT", node); - if (server) - SendKick(netconsole, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY); - break; - } - if (client) - PT_FileFragment(); - break; - case PT_FILEACK: - if (server) - PT_FileAck(); - break; - case PT_FILERECEIVED: - if (server) - PT_FileReceived(); - break; - case PT_WILLRESENDGAMESTATE: - PT_WillResendGamestate(); - break; - case PT_SENDINGLUAFILE: - if (client) - CL_PrepareDownloadLuaFile(); - break; - default: - DEBFILE(va("UNKNOWN PACKET TYPE RECEIVED %d from host %d\n", - netbuffer->packettype, node)); - } // end switch -} - -/** Handles all received packets, if any - * - * \todo Add details to this description (lol) - * - */ -static void GetPackets(void) -{ - SINT8 node; // The packet sender - - player_joining = false; - - while (HGetPacket()) - { - node = (SINT8)doomcom->remotenode; - - if (netbuffer->packettype == PT_CLIENTJOIN && server) - { - HandleConnect(node); - continue; - } - if (node == servernode && client && cl_mode != CL_SEARCHING) - { - if (netbuffer->packettype == PT_SERVERSHUTDOWN) - { - HandleShutdown(node); - continue; - } - if (netbuffer->packettype == PT_NODETIMEOUT) - { - HandleTimeout(node); - continue; - } - } - -#ifndef NONET - if (netbuffer->packettype == PT_SERVERINFO) - { - HandleServerInfo(node); - continue; - } -#endif - - if (netbuffer->packettype == PT_PLAYERINFO) - continue; // We do nothing with PLAYERINFO, that's for the MS browser. - - // Packet received from someone already playing - if (nodeingame[node]) - HandlePacketFromPlayer(node); - // Packet received from someone not playing - else - HandlePacketFromAwayNode(node); - } -} - -// -// NetUpdate -// Builds ticcmds for console player, -// sends out a packet -// -// no more use random generator, because at very first tic isn't yet synchronized -// Note: It is called consistAncy on purpose. -// -static INT16 Consistancy(void) -{ - INT32 i; - UINT32 ret = 0; -#ifdef MOBJCONSISTANCY - thinker_t *th; - mobj_t *mo; -#endif - - DEBFILE(va("TIC %u ", gametic)); - - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i]) - ret ^= 0xCCCC; - else if (!players[i].mo); - else - { - ret += players[i].mo->x; - ret -= players[i].mo->y; - ret += players[i].powers[pw_shield]; - ret *= i+1; - } - } - // I give up - // Coop desynching enemies is painful - if (!G_PlatformGametype()) - ret += P_GetRandSeed(); - -#ifdef MOBJCONSISTANCY - for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) - { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; - - mo = (mobj_t *)th; - - if (mo->flags & (MF_SPECIAL | MF_SOLID | MF_PUSHABLE | MF_BOSS | MF_MISSILE | MF_SPRING | MF_MONITOR | MF_FIRE | MF_ENEMY | MF_PAIN | MF_STICKY)) - { - ret -= mo->type; - ret += mo->x; - ret -= mo->y; - ret += mo->z; - ret -= mo->momx; - ret += mo->momy; - ret -= mo->momz; - ret += mo->angle; - ret -= mo->flags; - ret += mo->flags2; - ret -= mo->eflags; - if (mo->target) - { - ret += mo->target->type; - ret -= mo->target->x; - ret += mo->target->y; - ret -= mo->target->z; - ret += mo->target->momx; - ret -= mo->target->momy; - ret += mo->target->momz; - ret -= mo->target->angle; - ret += mo->target->flags; - ret -= mo->target->flags2; - ret += mo->target->eflags; - ret -= mo->target->state - states; - ret += mo->target->tics; - ret -= mo->target->sprite; - ret += mo->target->frame; - } - else - ret ^= 0x3333; - if (mo->tracer && mo->tracer->type != MT_OVERLAY) - { - ret += mo->tracer->type; - ret -= mo->tracer->x; - ret += mo->tracer->y; - ret -= mo->tracer->z; - ret += mo->tracer->momx; - ret -= mo->tracer->momy; - ret += mo->tracer->momz; - ret -= mo->tracer->angle; - ret += mo->tracer->flags; - ret -= mo->tracer->flags2; - ret += mo->tracer->eflags; - ret -= mo->tracer->state - states; - ret += mo->tracer->tics; - ret -= mo->tracer->sprite; - ret += mo->tracer->frame; - } - else - ret ^= 0xAAAA; - ret -= mo->state - states; - ret += mo->tics; - ret -= mo->sprite; - ret += mo->frame; - } - } -#endif - - DEBFILE(va("Consistancy = %u\n", (ret & 0xFFFF))); - - return (INT16)(ret & 0xFFFF); -} - -// send the client packet to the server -static void CL_SendClientCmd(void) -{ - size_t packetsize = 0; - - netbuffer->packettype = PT_CLIENTCMD; - - if (cl_packetmissed) - netbuffer->packettype++; - netbuffer->u.clientpak.resendfrom = (UINT8)(neededtic & UINT8_MAX); - netbuffer->u.clientpak.client_tic = (UINT8)(gametic & UINT8_MAX); - - if (gamestate == GS_WAITINGPLAYERS) - { - // Send PT_NODEKEEPALIVE packet - netbuffer->packettype += 4; - packetsize = sizeof (clientcmd_pak) - sizeof (ticcmd_t) - sizeof (INT16); - HSendPacket(servernode, false, 0, packetsize); - } - else if (gamestate != GS_NULL && (addedtogame || dedicated)) - { - G_MoveTiccmd(&netbuffer->u.clientpak.cmd, &localcmds, 1); - netbuffer->u.clientpak.consistancy = SHORT(consistancy[gametic%BACKUPTICS]); - - // Send a special packet with 2 cmd for splitscreen - if (splitscreen || botingame) - { - netbuffer->packettype += 2; - G_MoveTiccmd(&netbuffer->u.client2pak.cmd2, &localcmds2, 1); - packetsize = sizeof (client2cmd_pak); - } - else - packetsize = sizeof (clientcmd_pak); - - HSendPacket(servernode, false, 0, packetsize); - } - - if (cl_mode == CL_CONNECTED || dedicated) - { - // Send extra data if needed - if (localtextcmd[0]) - { - netbuffer->packettype = PT_TEXTCMD; - M_Memcpy(netbuffer->u.textcmd,localtextcmd, localtextcmd[0]+1); - // All extra data have been sent - if (HSendPacket(servernode, true, 0, localtextcmd[0]+1)) // Send can fail... - localtextcmd[0] = 0; - } - - // Send extra data if needed for player 2 (splitscreen) - if (localtextcmd2[0]) - { - netbuffer->packettype = PT_TEXTCMD2; - M_Memcpy(netbuffer->u.textcmd, localtextcmd2, localtextcmd2[0]+1); - // All extra data have been sent - if (HSendPacket(servernode, true, 0, localtextcmd2[0]+1)) // Send can fail... - localtextcmd2[0] = 0; - } - } -} - -// send the server packet -// send tic from firstticstosend to maketic-1 -static void SV_SendTics(void) -{ - tic_t realfirsttic, lasttictosend, i; - UINT32 n; - INT32 j; - size_t packsize; - UINT8 *bufpos; - UINT8 *ntextcmd; - - // send to all client but not to me - // for each node create a packet with x tics and send it - // x is computed using supposedtics[n], max packet size and maketic - for (n = 1; n < MAXNETNODES; n++) - if (nodeingame[n]) - { - // assert supposedtics[n]>=nettics[n] - realfirsttic = supposedtics[n]; - lasttictosend = min(maketic, nettics[n] + CLIENTBACKUPTICS); - - if (realfirsttic >= lasttictosend) - { - // well we have sent all tics we will so use extrabandwidth - // to resent packet that are supposed lost (this is necessary since lost - // packet detection work when we have received packet with firsttic > neededtic - // (getpacket servertics case) - DEBFILE(va("Nothing to send node %u mak=%u sup=%u net=%u \n", - n, maketic, supposedtics[n], nettics[n])); - realfirsttic = nettics[n]; - if (realfirsttic >= lasttictosend || (I_GetTime() + n)&3) - // all tic are ok - continue; - DEBFILE(va("Sent %d anyway\n", realfirsttic)); - } - if (realfirsttic < firstticstosend) - realfirsttic = firstticstosend; - - // compute the length of the packet and cut it if too large - packsize = BASESERVERTICSSIZE; - for (i = realfirsttic; i < lasttictosend; i++) - { - packsize += sizeof (ticcmd_t) * doomcom->numslots; - packsize += TotalTextCmdPerTic(i); - - if (packsize > software_MAXPACKETLENGTH) - { - DEBFILE(va("packet too large (%s) at tic %d (should be from %d to %d)\n", - sizeu1(packsize), i, realfirsttic, lasttictosend)); - lasttictosend = i; - - // too bad: too much player have send extradata and there is too - // much data in one tic. - // To avoid it put the data on the next tic. (see getpacket - // textcmd case) but when numplayer changes the computation can be different - if (lasttictosend == realfirsttic) - { - if (packsize > MAXPACKETLENGTH) - I_Error("Too many players: can't send %s data for %d players to node %d\n" - "Well sorry nobody is perfect....\n", - sizeu1(packsize), doomcom->numslots, n); - else - { - lasttictosend++; // send it anyway! - DEBFILE("sending it anyway\n"); - } - } - break; - } - } - - // Send the tics - netbuffer->packettype = PT_SERVERTICS; - netbuffer->u.serverpak.starttic = realfirsttic; - netbuffer->u.serverpak.numtics = (UINT8)(lasttictosend - realfirsttic); - netbuffer->u.serverpak.numslots = (UINT8)SHORT(doomcom->numslots); - bufpos = (UINT8 *)&netbuffer->u.serverpak.cmds; - - for (i = realfirsttic; i < lasttictosend; i++) - { - bufpos = G_DcpyTiccmd(bufpos, netcmds[i%BACKUPTICS], doomcom->numslots * sizeof (ticcmd_t)); - } - - // add textcmds - for (i = realfirsttic; i < lasttictosend; i++) - { - ntextcmd = bufpos++; - *ntextcmd = 0; - for (j = 0; j < MAXPLAYERS; j++) - { - UINT8 *textcmd = D_GetExistingTextcmd(i, j); - INT32 size = textcmd ? textcmd[0] : 0; - - if ((!j || playeringame[j]) && size) - { - (*ntextcmd)++; - WRITEUINT8(bufpos, j); - M_Memcpy(bufpos, textcmd, size + 1); - bufpos += size + 1; + CONS_Debug(DBG_SETUP, "R_PatchSkins: unknown skin name in P_SKIN lump# %d(%s) in WAD %s\n", lump, W_CheckNameForNumPwad(wadnum,lump), wadfiles[wadnum]->filename); + noskincomplain = true; } } } - packsize = bufpos - (UINT8 *)&(netbuffer->u); + else // Get the properties! + { + // Some of these can't go in R_ProcessPatchableFields because they have side effects for future lines. + if (!stricmp(stoken, "realname")) + { // Display name (eg. "Knuckles") + realname = true; + STRBUFCPY(skin->realname, value); + SYMBOLCONVERT(skin->realname) + if (!hudname) + HUDNAMEWRITE(skin->realname); + } + else if (!stricmp(stoken, "hudname")) + { // Life icon name (eg. "K.T.E") + hudname = true; + HUDNAMEWRITE(value); + SYMBOLCONVERT(skin->hudname) + if (!realname) + STRBUFCPY(skin->realname, skin->hudname); + } + else if (!R_ProcessPatchableFields(skin, stoken, value)) + CONS_Debug(DBG_SETUP, "R_PatchSkins: Unknown keyword '%s' in P_SKIN lump #%d (WAD %s)\n", stoken, lump, wadfiles[wadnum]->filename); + } - HSendPacket(n, false, 0, packsize); - // when tic are too large, only one tic is sent so don't go backward! - if (lasttictosend-doomcom->extratics > realfirsttic) - supposedtics[n] = lasttictosend-doomcom->extratics; - else - supposedtics[n] = lasttictosend; - if (supposedtics[n] < nettics[n]) supposedtics[n] = nettics[n]; + if (!skin) + break; + +next_token: + stoken = strtok(NULL, "\r\n= "); } - // node 0 is me! - supposedtics[0] = maketic; -} + free(buf2); -// -// TryRunTics -// -static void Local_Maketic(INT32 realtics) -{ - I_OsPolling(); // I_Getevent - D_ProcessEvents(); // menu responder, cons responder, - // game responder calls HU_Responder, AM_Responder, - // and G_MapEventsToControls - if (!dedicated) rendergametic = gametic; - // translate inputs (keyboard/mouse/joystick) into game controls - G_BuildTiccmd(&localcmds, realtics, 1); - if (splitscreen || botingame) - G_BuildTiccmd(&localcmds2, realtics, 2); - - localcmds.angleturn |= TICCMD_RECEIVED; - localcmds2.angleturn |= TICCMD_RECEIVED; -} - -// create missed tic -static void SV_Maketic(void) -{ - INT32 i; - - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i]) + if (!skin) // Didn't include a name parameter? What a waste. + { + if (!noskincomplain) + CONS_Debug(DBG_SETUP, "R_PatchSkins: no skin name given in P_SKIN lump #%d (WAD %s)\n", lump, wadfiles[wadnum]->filename); continue; - - // We didn't receive this tic - if ((netcmds[maketic % BACKUPTICS][i].angleturn & TICCMD_RECEIVED) == 0) - { - ticcmd_t * ticcmd = &netcmds[(maketic ) % BACKUPTICS][i]; - ticcmd_t *prevticcmd = &netcmds[(maketic - 1) % BACKUPTICS][i]; - - if (players[i].quittime) - { - // Copy the angle/aiming from the previous tic - // and empty the other inputs - memset(ticcmd, 0, sizeof(netcmds[0][0])); - ticcmd->angleturn = prevticcmd->angleturn | TICCMD_RECEIVED; - ticcmd->aiming = prevticcmd->aiming; - } - else - { - DEBFILE(va("MISS tic%4d for player %d\n", maketic, i)); - // Copy the input from the previous tic - *ticcmd = *prevticcmd; - ticcmd->angleturn &= ~TICCMD_RECEIVED; - } - } - } - - // all tic are now proceed make the next - maketic++; -} - -void TryRunTics(tic_t realtics) -{ - // the machine has lagged but it is not so bad - if (realtics > TICRATE/7) // FIXME: consistency failure!! - { - if (server) - realtics = 1; - else - realtics = TICRATE/7; - } - - if (singletics) - realtics = 1; - - if (realtics >= 1) - { - COM_BufTicker(); - if (mapchangepending) - D_MapChange(-1, 0, ultimatemode, false, 2, false, fromlevelselect); // finish the map change - } - - NetUpdate(); - - if (demoplayback) - { - neededtic = gametic + (realtics * cv_playbackspeed.value); - // start a game after a demo - maketic += realtics; - firstticstosend = maketic; - tictoclear = firstticstosend; - } - - GetPackets(); - -#ifdef DEBUGFILE - if (debugfile && (realtics || neededtic > gametic)) - { - //SoM: 3/30/2000: Need long INT32 in the format string for args 4 & 5. - //Shut up stupid warning! - fprintf(debugfile, "------------ Tryruntic: REAL:%d NEED:%d GAME:%d LOAD: %d\n", - realtics, neededtic, gametic, debugload); - debugload = 100000; - } -#endif - - if (player_joining) - return; - - if (neededtic > gametic) - { - if (advancedemo) - { - if (timedemo_quit) - COM_ImmedExecute("quit"); - else - D_StartTitle(); - } - else - // run the count * tics - while (neededtic > gametic) - { - DEBFILE(va("============ Running tic %d (local %d)\n", gametic, localgametic)); - - ps_tictime = I_GetTimeMicros(); - - G_Ticker((gametic % NEWTICRATERATIO) == 0); - ExtraDataTicker(); - gametic++; - consistancy[gametic%BACKUPTICS] = Consistancy(); - - ps_tictime = I_GetTimeMicros() - ps_tictime; - - // Leave a certain amount of tics present in the net buffer as long as we've ran at least one tic this frame. - if (client && gamestate == GS_LEVEL && leveltime > 3 && neededtic <= gametic + cv_netticbuffer.value) - break; - } - } -} - -/* -Ping Update except better: -We call this once per second and check for people's pings. If their ping happens to be too high, we increment some timer and kick them out. -If they're not lagging, decrement the timer by 1. Of course, reset all of this if they leave. -*/ - -static INT32 pingtimeout[MAXPLAYERS]; - -static inline void PingUpdate(void) -{ - INT32 i; - boolean laggers[MAXPLAYERS]; - UINT8 numlaggers = 0; - memset(laggers, 0, sizeof(boolean) * MAXPLAYERS); - - netbuffer->packettype = PT_PING; - - //check for ping limit breakage. - if (cv_maxping.value) - { - for (i = 1; i < MAXPLAYERS; i++) - { - if (playeringame[i] && !players[i].quittime - && (realpingtable[i] / pingmeasurecount > (unsigned)cv_maxping.value)) - { - if (players[i].jointime > 30 * TICRATE) - laggers[i] = true; - numlaggers++; - } - else - pingtimeout[i] = 0; } - //kick lagging players... unless everyone but the server's ping sucks. - //in that case, it is probably the server's fault. - if (numlaggers < D_NumPlayers() - 1) - { - for (i = 1; i < MAXPLAYERS; i++) - { - if (playeringame[i] && laggers[i]) - { - pingtimeout[i]++; - // ok your net has been bad for too long, you deserve to die. - if (pingtimeout[i] > cv_pingtimeout.value) - { - pingtimeout[i] = 0; - SendKick(i, KICK_MSG_PING_HIGH | KICK_MSG_KEEP_BODY); - } - } - /* - you aren't lagging, - but you aren't free yet. - In case you'll keep spiking, - we just make the timer go back down. (Very unstable net must still get kicked). - */ - else - pingtimeout[i] = (pingtimeout[i] == 0 ? 0 : pingtimeout[i]-1); - } - } + // Patch sprites + R_LoadSkinSprites(wadnum, &lump, &lastlump, skin); + //ST_LoadFaceGraphics(skinnum); -- nah let's do this elsewhere + + R_FlushTranslationColormapCache(); + + if (!skin->availability) // Safe to print... + CONS_Printf(M_GetText("Patched skin '%s'\n"), skin->name); } - - //make the ping packet and clear server data for next one - for (i = 0; i < MAXPLAYERS; i++) - { - netbuffer->u.pingtable[i] = realpingtable[i] / pingmeasurecount; - //server takes a snapshot of the real ping for display. - //otherwise, pings fluctuate a lot and would be odd to look at. - playerpingtable[i] = realpingtable[i] / pingmeasurecount; - realpingtable[i] = 0; //Reset each as we go. - } - - // send the server's maxping as last element of our ping table. This is useful to let us know when we're about to get kicked. - netbuffer->u.pingtable[MAXPLAYERS] = cv_maxping.value; - - //send out our ping packets - for (i = 0; i < MAXNETNODES; i++) - if (nodeingame[i]) - HSendPacket(i, true, 0, sizeof(INT32) * (MAXPLAYERS+1)); - - pingmeasurecount = 1; //Reset count + return; } -void NetUpdate(void) -{ - static tic_t gametime = 0; - static tic_t resptime = 0; - tic_t nowtime; - INT32 i; - INT32 realtics; - - nowtime = I_GetTime(); - realtics = nowtime - gametime; - - if (realtics <= 0) // nothing new to update - return; - if (realtics > 5) - { - if (server) - realtics = 1; - else - realtics = 5; - } - - gametime = nowtime; - - if (server) - { - if (netgame && !(gametime % 35)) // update once per second. - PingUpdate(); - // update node latency values so we can take an average later. - for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && playernode[i] != UINT8_MAX) - realpingtable[i] += G_TicsToMilliseconds(GetLag(playernode[i])); - pingmeasurecount++; - } - - if (client) - maketic = neededtic; - - Local_Maketic(realtics); // make local tic, and call menu? - - if (server) - CL_SendClientCmd(); // send it - - GetPackets(); // get packet from client or from server - - // client send the command after a receive of the server - // the server send before because in single player is beter - -#ifdef MASTERSERVER - MasterClient_Ticker(); // Acking the Master Server -#endif - - if (client) - { - // If the client just finished redownloading the game state, load it - if (cl_redownloadinggamestate && fileneeded[0].status == FS_FOUND) - CL_ReloadReceivedSavegame(); - - CL_SendClientCmd(); // Send tic cmd - hu_redownloadinggamestate = cl_redownloadinggamestate; - } - else - { - if (!demoplayback) - { - INT32 counts; - - hu_redownloadinggamestate = false; - - firstticstosend = gametic; - for (i = 0; i < MAXNETNODES; i++) - if (nodeingame[i] && nettics[i] < firstticstosend) - { - firstticstosend = nettics[i]; - - if (maketic + 1 >= nettics[i] + BACKUPTICS) - Net_ConnectionTimeout(i); - } - - // Don't erase tics not acknowledged - counts = realtics; - - if (maketic + counts >= firstticstosend + BACKUPTICS) - counts = firstticstosend+BACKUPTICS-maketic-1; - - for (i = 0; i < counts; i++) - SV_Maketic(); // Create missed tics and increment maketic - - for (; tictoclear < firstticstosend; tictoclear++) // Clear only when acknowledged - D_Clearticcmd(tictoclear); // Clear the maketic the new tic - - SV_SendTics(); - - neededtic = maketic; // The server is a client too - } - } - - Net_AckTicker(); - - // Handle timeouts to prevent definitive freezes from happenning - if (server) - { - for (i = 1; i < MAXNETNODES; i++) - if (nodeingame[i] && freezetimeout[i] < I_GetTime()) - Net_ConnectionTimeout(i); - - // In case the cvar value was lowered - if (joindelay) - joindelay = min(joindelay - 1, 3 * (tic_t)cv_joindelay.value * TICRATE); - } - - nowtime /= NEWTICRATERATIO; - if (nowtime > resptime) - { - resptime = nowtime; -#ifdef HAVE_THREADS - I_lock_mutex(&m_menu_mutex); -#endif - M_Ticker(); -#ifdef HAVE_THREADS - I_unlock_mutex(m_menu_mutex); -#endif - CON_Ticker(); - } - - FileSendTicker(); -} - -/** Returns the number of players playing. - * \return Number of players. Can be zero if we're running a ::dedicated - * server. - * \author Graue - */ -INT32 D_NumPlayers(void) -{ - INT32 num = 0, ix; - for (ix = 0; ix < MAXPLAYERS; ix++) - if (playeringame[ix]) - num++; - return num; -} - -tic_t GetLag(INT32 node) -{ - return gametic - nettics[node]; -} - -void D_MD5PasswordPass(const UINT8 *buffer, size_t len, const char *salt, void *dest) -{ -#ifdef NOMD5 - (void)buffer; - (void)len; - (void)salt; - memset(dest, 0, 16); -#else - char tmpbuf[256]; - const size_t sl = strlen(salt); - - if (len > 256-sl) - len = 256-sl; - - memcpy(tmpbuf, buffer, len); - memmove(&tmpbuf[len], salt, sl); - //strcpy(&tmpbuf[len], salt); - len += strlen(salt); - if (len < 256) - memset(&tmpbuf[len],0,256-len); - - // Yes, we intentionally md5 the ENTIRE buffer regardless of size... - md5_buffer(tmpbuf, 256, dest); -#endif -} +#undef HUDNAMEWRITE +#undef SYMBOLCONVERT From 079fe9ba7e488e880561318e1200e8630289d117 Mon Sep 17 00:00:00 2001 From: Shane Ellis Date: Fri, 15 Jan 2021 17:08:16 -0500 Subject: [PATCH 217/644] Command_Kick() - Allow removal of non-consoleplayer/secondaryviewplayer player instances (e.g. player bots) --- src/d_clisrv.c | 66 ++++++++++++++++++++++++++------------------------ 1 file changed, 34 insertions(+), 32 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 4fdc7e7ee..88b4d9387 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1595,7 +1595,9 @@ static void CL_ReloadReceivedSavegame(void) for (i = 0; i < MAXPLAYERS; i++) { +#ifdef HAVE_BLUA LUA_InvalidatePlayer(&players[i]); +#endif sprintf(player_names[i], "Player %d", i + 1); } @@ -2258,15 +2260,11 @@ void D_SaveBan(void) size_t i; banreason_t *reasonlist = reasonhead; const char *address, *mask; - const char *path = va("%s"PATHSEP"%s", srb2home, "ban.txt"); if (!reasonhead) - { - remove(path); return; - } - f = fopen(path, "w"); + f = fopen(va("%s"PATHSEP"%s", srb2home, "ban.txt"), "w"); if (!f) { @@ -2310,14 +2308,16 @@ static void Ban_Add(const char *reason) reasontail = reasonlist; } -static void Ban_Clear(void) +static void Command_ClearBans(void) { banreason_t *temp; + if (!I_ClearBans) + return; + I_ClearBans(); - + D_SaveBan(); reasontail = NULL; - while (reasonhead) { temp = reasonhead->next; @@ -2327,15 +2327,6 @@ static void Ban_Clear(void) } } -static void Command_ClearBans(void) -{ - if (!I_ClearBans) - return; - - Ban_Clear(); - D_SaveBan(); -} - static void Ban_Load_File(boolean warning) { FILE *f; @@ -2343,9 +2334,6 @@ static void Ban_Load_File(boolean warning) const char *address, *mask; char buffer[MAX_WADPATH]; - if (!I_ClearBans) - return; - f = fopen(va("%s"PATHSEP"%s", srb2home, "ban.txt"), "r"); if (!f) @@ -2355,7 +2343,13 @@ static void Ban_Load_File(boolean warning) return; } - Ban_Clear(); + if (I_ClearBans) + Command_ClearBans(); + else + { + fclose(f); + return; + } for (i=0; fgets(buffer, (int)sizeof(buffer), f); i++) { @@ -2815,11 +2809,11 @@ static void Command_Kick(void) return; } - if (!netgame) // Don't kick Tails in splitscreen! - { - CONS_Printf(M_GetText("This only works in a netgame.\n")); - return; - } + //if (!netgame) // Don't kick Tails in splitscreen! + //{ + // CONS_Printf(M_GetText("This only works in a netgame.\n")); + // return; + //} if (server || IsPlayerAdmin(consoleplayer)) { @@ -2827,9 +2821,14 @@ static void Command_Kick(void) UINT8 *p = buf; const SINT8 pn = nametonum(COM_Argv(1)); + if (splitscreen && (pn == 0 || pn == 1)) + { + CONS_Printf(M_GetText("Splitscreen players cannot be kicked.\n")); + return; + } if (pn == -1 || pn == 0) return; - + // Special case if we are trying to kick a player who is downloading the game state: // trigger a timeout instead of kicking them, because a kick would only // take effect after they have finished downloading @@ -3032,7 +3031,8 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum) if (pnum == consoleplayer) { - LUAh_GameQuit(false); + if (Playing()) + LUAh_GameQuit(); #ifdef DUMPCONSISTENCY if (msg == KICK_MSG_CON_FAIL) SV_SavedGame(); #endif @@ -3732,7 +3732,8 @@ static void HandleConnect(SINT8 node) static void HandleShutdown(SINT8 node) { (void)node; - LUAh_GameQuit(false); + if (Playing()) + LUAh_GameQuit(); D_QuitNetGame(); CL_Reset(); D_StartTitle(); @@ -3747,7 +3748,8 @@ static void HandleShutdown(SINT8 node) static void HandleTimeout(SINT8 node) { (void)node; - LUAh_GameQuit(false); + if (Playing()) + LUAh_GameQuit(); D_QuitNetGame(); CL_Reset(); D_StartTitle(); @@ -4850,14 +4852,14 @@ void TryRunTics(tic_t realtics) { DEBFILE(va("============ Running tic %d (local %d)\n", gametic, localgametic)); - ps_tictime = I_GetPreciseTime(); + ps_tictime = I_GetTimeMicros(); G_Ticker((gametic % NEWTICRATERATIO) == 0); ExtraDataTicker(); gametic++; consistancy[gametic%BACKUPTICS] = Consistancy(); - ps_tictime = I_GetPreciseTime() - ps_tictime; + ps_tictime = I_GetTimeMicros() - ps_tictime; // Leave a certain amount of tics present in the net buffer as long as we've ran at least one tic this frame. if (client && gamestate == GS_LEVEL && leveltime > 3 && neededtic <= gametic + cv_netticbuffer.value) From a68fee3303b0804cd35c186c4d89b858b790c385 Mon Sep 17 00:00:00 2001 From: Shane Ellis Date: Fri, 15 Jan 2021 17:22:38 -0500 Subject: [PATCH 218/644] oops --- src/p_inter.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/p_inter.c b/src/p_inter.c index 778ec703b..8190f5cfa 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1387,6 +1387,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (player->bot && player->bot != 3) return; + + // Initialize my junk + junk.tags.tags = NULL; + junk.tags.count = 0; Tag_FSet(&junk.tags, LE_AXE); EV_DoElevator(&junk, bridgeFall, false); From 56e9b99f283923855efc6cf621d988700c305634 Mon Sep 17 00:00:00 2001 From: Shane Ellis Date: Fri, 15 Jan 2021 22:28:01 +0000 Subject: [PATCH 219/644] Revert "Add conditions for new player bot type" This reverts commit 4b9a95a53837166a080b200b34982ce867a31ffd --- src/p_enemy.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 38df59855..203e04af1 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -743,7 +743,7 @@ boolean P_LookForPlayers(mobj_t *actor, boolean allaround, boolean tracer, fixed if (player->mo->health <= 0) continue; // dead - if (player->bot && player->bot != 3) + if (player->bot) continue; // ignore bots if (player->quittime) @@ -1834,7 +1834,7 @@ void A_SnailerThink(mobj_t *actor) fixed_t dist; fixed_t dx, dy; - dist = P_AproxDistance(actor->x - actor->target->x, actor->y - actor->target->y); + dist = R_PointToDist2(0, 0, actor->x - actor->target->x, actor->y - actor->target->y); if (an > ANGLE_45 && an <= ANGLE_90) // fire at 45 degrees to the left { @@ -3924,6 +3924,10 @@ void A_BossDeath(mobj_t *mo) } else { + // Initialize my junk + junk.tags.tags = NULL; + junk.tags.count = 0; + // Bring the egg trap up to the surface // Incredibly shitty code ahead Tag_FSet(&junk.tags, LE_CAPSULE0); @@ -4053,6 +4057,10 @@ bossjustdie: } case MT_KOOPA: { + // Initialize my junk + junk.tags.tags = NULL; + junk.tags.count = 0; + Tag_FSet(&junk.tags, LE_KOOPA); EV_DoCeiling(&junk, raiseToHighest); return; From 161e1c42cb6bed9ca7af062df4f7fd091f0299b7 Mon Sep 17 00:00:00 2001 From: Shane Ellis Date: Fri, 15 Jan 2021 17:29:15 -0500 Subject: [PATCH 220/644] Update p_enemy.c --- src/p_enemy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 203e04af1..637eba83f 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -743,7 +743,7 @@ boolean P_LookForPlayers(mobj_t *actor, boolean allaround, boolean tracer, fixed if (player->mo->health <= 0) continue; // dead - if (player->bot) + if (player->bot && player->bot != 3) continue; // ignore bots if (player->quittime) From 759ff44dfd366bfd42ae252d90f78a1e85b947c2 Mon Sep 17 00:00:00 2001 From: Shane Ellis Date: Fri, 15 Jan 2021 22:32:02 +0000 Subject: [PATCH 221/644] Revert "Add conditions for new player bot type" This reverts commit b995e3cb75b67116d51583c1ae85debf25013621 --- src/p_user.c | 125 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 77 insertions(+), 48 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 2466310bb..a70dceb8b 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1189,7 +1189,7 @@ void P_GivePlayerRings(player_t *player, INT32 num_rings) if (!player) return; - if (player->bot && player->bot != 3) + if (player->bot) player = &players[consoleplayer]; if (!player->mo) @@ -1234,7 +1234,7 @@ void P_GivePlayerSpheres(player_t *player, INT32 num_spheres) if (!player) return; - if (player->bot && player->bot != 3) + if (player->bot) player = &players[consoleplayer]; if (!player->mo) @@ -1261,7 +1261,7 @@ void P_GivePlayerLives(player_t *player, INT32 numlives) if (!player) return; - if (player->bot && player->bot != 3) + if (player->bot) player = &players[consoleplayer]; if (gamestate == GS_LEVEL) @@ -1341,7 +1341,7 @@ void P_DoSuperTransformation(player_t *player, boolean giverings) // Transformation animation P_SetPlayerMobjState(player->mo, S_PLAY_SUPER_TRANS1); - if (giverings) + if (giverings && player->rings < 50) player->rings = 50; // Just in case. @@ -1367,7 +1367,7 @@ void P_AddPlayerScore(player_t *player, UINT32 amount) { UINT32 oldscore; - if (player->bot && player->bot != 3) + if (player->bot) player = &players[consoleplayer]; // NiGHTS does it different! @@ -1491,10 +1491,10 @@ void P_PlayLivesJingle(player_t *player) if (player && !P_IsLocalPlayer(player)) return; - if (use1upSound || cv_1upsound.value) - S_StartSound(NULL, sfx_oneup); - else if (mariomode) + if (mariomode) S_StartSound(NULL, sfx_marioa); + else if (use1upSound || cv_1upsound.value) + S_StartSound(NULL, sfx_oneup); else { P_PlayJingle(player, JT_1UP); @@ -2329,7 +2329,8 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff) P_MobjCheckWater(player->mo); if (player->pflags & PF_SPINNING) { - if (player->mo->state-states != S_PLAY_ROLL && !(player->pflags & PF_STARTDASH)) + if (!(player->pflags & PF_STARTDASH) && player->panim != PA_ROLL && player->panim != PA_ETC + && player->panim != PA_ABILITY && player->panim != PA_ABILITY2) { P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); S_StartSound(player->mo, sfx_spin); @@ -2612,10 +2613,10 @@ static void P_CheckBustableBlocks(player_t *player) if ((netgame || multiplayer) && player->spectator) return; - + oldx = player->mo->x; oldy = player->mo->y; - + if (!(player->pflags & PF_BOUNCING)) // Bouncers only get to break downwards, not sideways { P_UnsetThingPosition(player->mo); @@ -2634,7 +2635,7 @@ static void P_CheckBustableBlocks(player_t *player) if (!node->m_sector->ffloors) continue; - + for (rover = node->m_sector->ffloors; rover; rover = rover->next) { if (!P_PlayerCanBust(player, rover)) @@ -2992,7 +2993,7 @@ static void P_CheckUnderwaterAndSpaceTimer(player_t *player) player->powers[pw_spacetime] = 0; // Underwater audio cues - if (P_IsLocalPlayer(player) && !player->bot && player->bot != 3) + if (P_IsLocalPlayer(player) && !player->bot) { if ((player->powers[pw_underwater] == 25*TICRATE + 1) || (player->powers[pw_underwater] == 20*TICRATE + 1) @@ -4525,6 +4526,9 @@ void P_DoJump(player_t *player, boolean soundandstate) player->pflags |= P_GetJumpFlags(player);; + if (player->charflags & SF_NOJUMPDAMAGE) + player->pflags &= ~PF_SPINNING; + if (soundandstate) { if (!player->spectator) @@ -5020,7 +5024,7 @@ static boolean P_PlayerShieldThink(player_t *player, ticcmd_t *cmd, mobj_t *lock if ((player->powers[pw_shield] & SH_NOSTACK) && !player->powers[pw_super] && !(player->pflags & PF_SPINDOWN) && ((!(player->pflags & PF_THOKKED) || (((player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP || (player->powers[pw_shield] & SH_NOSTACK) == SH_ATTRACT) && player->secondjump == UINT8_MAX) ))) // thokked is optional if you're bubblewrapped / 3dblasted { - if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ATTRACT) + if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ATTRACT && !(player->charflags & SF_NOSHIELDABILITY)) { if ((lockonshield = P_LookForEnemies(player, false, false))) { @@ -5043,7 +5047,7 @@ static boolean P_PlayerShieldThink(player_t *player, ticcmd_t *cmd, mobj_t *lock } } } - if (cmd->buttons & BT_SPIN && !LUAh_ShieldSpecial(player)) // Spin button effects + if ((!(player->charflags & SF_NOSHIELDABILITY)) && (cmd->buttons & BT_SPIN && !LUAh_ShieldSpecial(player))) // Spin button effects { // Force stop if ((player->powers[pw_shield] & ~(SH_FORCEHP|SH_STACK)) == SH_FORCE) @@ -5491,7 +5495,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) break; } } - else if ((player->powers[pw_shield] & SH_NOSTACK) == SH_WHIRLWIND && !player->powers[pw_super]) + else if ((!(player->charflags & SF_NOSHIELDABILITY)) && ((player->powers[pw_shield] & SH_NOSTACK) == SH_WHIRLWIND && !player->powers[pw_super] && !LUAh_ShieldSpecial(player))) P_DoJumpShield(player); } @@ -5920,7 +5924,7 @@ static void P_3dMovement(player_t *player) player->rmomy = player->mo->momy - player->cmomy; // Calculates player's speed based on distance-of-a-line formula - player->speed = P_AproxDistance(player->rmomx, player->rmomy); + player->speed = R_PointToDist2(0, 0, player->rmomx, player->rmomy); // Monster Iestyn - 04-11-13 // Quadrants are stupid, excessive and broken, let's do this a much simpler way! @@ -5953,6 +5957,22 @@ static void P_3dMovement(player_t *player) acceleration = 96 + (FixedDiv(player->speed, player->mo->scale)>>FRACBITS) * 40; topspeed = normalspd; } + else if (player->bot) + { // Bot steals player 1's stats + normalspd = FixedMul(players[consoleplayer].normalspeed, player->mo->scale); + thrustfactor = players[consoleplayer].thrustfactor; + acceleration = players[consoleplayer].accelstart + (FixedDiv(player->speed, player->mo->scale)>>FRACBITS) * players[consoleplayer].acceleration; + + if (player->powers[pw_tailsfly]) + topspeed = normalspd/2; + else if (player->mo->eflags & (MFE_UNDERWATER|MFE_GOOWATER)) + { + topspeed = normalspd/2; + acceleration = 2*acceleration/3; + } + else + topspeed = normalspd; + } else { if (player->powers[pw_super] || player->powers[pw_sneakers]) @@ -7736,6 +7756,11 @@ void P_ElementalFire(player_t *player, boolean cropcircle) flame->eflags = (flame->eflags & ~MFE_VERTICALFLIP)|(player->mo->eflags & MFE_VERTICALFLIP); P_InstaThrust(flame, flame->angle, FixedMul(3*FRACUNIT, flame->scale)); P_SetObjectMomZ(flame, 3*FRACUNIT, false); + if (!(gametyperules & GTR_FRIENDLY)) + { + P_SetMobjState(flame, S_TEAM_SPINFIRE1); + flame->color = player->mo->color; + } } #undef limitangle #undef numangles @@ -7763,6 +7788,11 @@ void P_ElementalFire(player_t *player, boolean cropcircle) flame->destscale = player->mo->scale; P_SetScale(flame, player->mo->scale); flame->eflags = (flame->eflags & ~MFE_VERTICALFLIP)|(player->mo->eflags & MFE_VERTICALFLIP); + if (!(gametyperules & GTR_FRIENDLY)) + { + P_SetMobjState(flame, S_TEAM_SPINFIRE1); + flame->color = player->mo->color; + } flame->momx = 8; // this is a hack which is used to ensure it still behaves as a missile and can damage others P_XYMovement(flame); @@ -8589,12 +8619,6 @@ void P_MovePlayer(player_t *player) player->climbing--; } - if (!player->climbing) - { - player->lastsidehit = -1; - player->lastlinehit = -1; - } - // Make sure you're not teetering when you shouldn't be. if (player->panim == PA_EDGE && (player->mo->momx || player->mo->momy || player->mo->momz)) @@ -8619,6 +8643,7 @@ void P_MovePlayer(player_t *player) P_DoFiring(player, cmd); { + boolean atspinheight = false; fixed_t oldheight = player->mo->height; // Less height while spinning. Good for spinning under things...? @@ -8628,32 +8653,35 @@ void P_MovePlayer(player_t *player) || player->powers[pw_tailsfly] || player->pflags & PF_GLIDING || (player->charability == CA_GLIDEANDCLIMB && player->mo->state-states == S_PLAY_GLIDE_LANDING) || (player->charability == CA_FLY && player->mo->state-states == S_PLAY_FLY_TIRED)) + { player->mo->height = P_GetPlayerSpinHeight(player); + atspinheight = true; + } else player->mo->height = P_GetPlayerHeight(player); if (player->mo->eflags & MFE_VERTICALFLIP && player->mo->height != oldheight) // adjust z height for reverse gravity, similar to how it's done for scaling player->mo->z -= player->mo->height - oldheight; - } - // Crush test... - if ((player->mo->ceilingz - player->mo->floorz < player->mo->height) - && !(player->mo->flags & MF_NOCLIP)) - { - if ((player->charability2 == CA2_SPINDASH) && !(player->pflags & PF_SPINNING)) + // Crush test... + if ((player->mo->ceilingz - player->mo->floorz < player->mo->height) + && !(player->mo->flags & MF_NOCLIP)) { - player->pflags |= PF_SPINNING; - P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); - } - else if (player->mo->ceilingz - player->mo->floorz < player->mo->height) - { - if ((netgame || multiplayer) && player->spectator) - P_DamageMobj(player->mo, NULL, NULL, 1, DMG_SPECTATOR); // Respawn crushed spectators - else - P_DamageMobj(player->mo, NULL, NULL, 1, DMG_CRUSHED); + if (!atspinheight) + { + player->pflags |= PF_SPINNING; + P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); + } + else if (player->mo->ceilingz - player->mo->floorz < player->mo->height) + { + if ((netgame || multiplayer) && player->spectator) + P_DamageMobj(player->mo, NULL, NULL, 1, DMG_SPECTATOR); // Respawn crushed spectators + else + P_DamageMobj(player->mo, NULL, NULL, 1, DMG_CRUSHED); - if (player->playerstate == PST_DEAD) - return; + if (player->playerstate == PST_DEAD) + return; + } } } @@ -9469,11 +9497,11 @@ static void P_DeathThink(player_t *player) if (player->deadtimer < INT32_MAX) player->deadtimer++; - if (player->bot && player->bot != 3) // don't allow bots to do any of the below, B_CheckRespawn does all they need for respawning already + if (player->bot) // don't allow bots to do any of the below, B_CheckRespawn does all they need for respawning already goto notrealplayer; // continue logic - if (!(netgame || multiplayer) && player->lives <= 0 && player ==&players[consoleplayer]) //Extra players in SP can't be allowed to continue or end game + if (!(netgame || multiplayer) && player->lives <= 0) { if (player->deadtimer > (3*TICRATE) && (cmd->buttons & BT_SPIN || cmd->buttons & BT_JUMP) && (!continuesInSession || player->continues > 0)) G_UseContinue(); @@ -11452,7 +11480,7 @@ void P_PlayerThink(player_t *player) player->playerstate = PST_DEAD; } - if (player->bot && player->bot != 3) + if (player->bot) { if (player->playerstate == PST_LIVE || player->playerstate == PST_DEAD) { @@ -11466,7 +11494,6 @@ void P_PlayerThink(player_t *player) } } -#ifdef SEENAMES if (netgame && player == &players[displayplayer] && !(leveltime % (TICRATE/5))) { seenplayer = NULL; @@ -11491,7 +11518,6 @@ void P_PlayerThink(player_t *player) } } } -#endif if (player->awayviewmobj && P_MobjWasRemoved(player->awayviewmobj)) { @@ -12562,13 +12588,16 @@ void P_PlayerAfterThink(player_t *player) player->powers[pw_carry] = CR_NONE; else { - P_TryMove(player->mo, tails->x + P_ReturnThrustX(tails, tails->player->drawangle, 4*FRACUNIT), tails->y + P_ReturnThrustY(tails, tails->player->drawangle, 4*FRACUNIT), true); + if (tails->player) + P_TryMove(player->mo, tails->x + P_ReturnThrustX(tails, tails->player->drawangle, 4*FRACUNIT), tails->y + P_ReturnThrustY(tails, tails->player->drawangle, 4*FRACUNIT), true); + else + P_TryMove(player->mo, tails->x + P_ReturnThrustX(tails, tails->angle, 4*FRACUNIT), tails->y + P_ReturnThrustY(tails, tails->angle, 4*FRACUNIT), true); player->mo->momx = tails->momx; player->mo->momy = tails->momy; player->mo->momz = tails->momz; } - if (G_CoopGametype() && (!tails->player || tails->player->bot != 1)) + if (G_CoopGametype() && tails->player && tails->player->bot != 1) { player->mo->angle = tails->angle; @@ -12583,7 +12612,7 @@ void P_PlayerAfterThink(player_t *player) { if (player->mo->state-states != S_PLAY_RIDE) P_SetPlayerMobjState(player->mo, S_PLAY_RIDE); - if ((tails->skin && ((skin_t *)(tails->skin))->sprites[SPR2_SWIM].numframes) && (tails->eflags & MFE_UNDERWATER)) + if (tails->player && (tails->skin && ((skin_t *)(tails->skin))->sprites[SPR2_SWIM].numframes) && (tails->eflags & MFE_UNDERWATER)) tails->player->powers[pw_tailsfly] = 0; } else From 6103d7a51e2e7905d5298f5fde80be3554d1751f Mon Sep 17 00:00:00 2001 From: Shane Ellis Date: Fri, 15 Jan 2021 17:41:16 -0500 Subject: [PATCH 222/644] Update p_user.c --- src/p_user.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index a70dceb8b..9e86e2d73 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -777,7 +777,7 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) UINT8 oldmare, oldmarelap, oldmarebonuslap; // Bots can't be NiGHTSerized, silly!1 :P - if (player->bot) + if (player->bot && player->bot != 3) return; if (player->powers[pw_carry] != CR_NIGHTSMODE) @@ -1189,7 +1189,7 @@ void P_GivePlayerRings(player_t *player, INT32 num_rings) if (!player) return; - if (player->bot) + if (player->bot && player->bot != 3) player = &players[consoleplayer]; if (!player->mo) @@ -1234,7 +1234,7 @@ void P_GivePlayerSpheres(player_t *player, INT32 num_spheres) if (!player) return; - if (player->bot) + if (player->bot && player->bot != 3) player = &players[consoleplayer]; if (!player->mo) @@ -1261,7 +1261,7 @@ void P_GivePlayerLives(player_t *player, INT32 numlives) if (!player) return; - if (player->bot) + if (player->bot && player->bot != 3) player = &players[consoleplayer]; if (gamestate == GS_LEVEL) @@ -1367,7 +1367,7 @@ void P_AddPlayerScore(player_t *player, UINT32 amount) { UINT32 oldscore; - if (player->bot) + if (player->bot && player->bot != 3) player = &players[consoleplayer]; // NiGHTS does it different! @@ -5957,7 +5957,7 @@ static void P_3dMovement(player_t *player) acceleration = 96 + (FixedDiv(player->speed, player->mo->scale)>>FRACBITS) * 40; topspeed = normalspd; } - else if (player->bot) + else if (player->bot && player->bot != 3) { // Bot steals player 1's stats normalspd = FixedMul(players[consoleplayer].normalspeed, player->mo->scale); thrustfactor = players[consoleplayer].thrustfactor; @@ -9497,11 +9497,11 @@ static void P_DeathThink(player_t *player) if (player->deadtimer < INT32_MAX) player->deadtimer++; - if (player->bot) // don't allow bots to do any of the below, B_CheckRespawn does all they need for respawning already + if (player->bot && player->bot != 3) // don't allow bots to do any of the below, B_CheckRespawn does all they need for respawning already goto notrealplayer; // continue logic - if (!(netgame || multiplayer) && player->lives <= 0) + if (!(netgame || multiplayer) && player->lives <= 0 && player == &players[consoleplayer]) //Extra players in SP can't be allowed to continue or end game { if (player->deadtimer > (3*TICRATE) && (cmd->buttons & BT_SPIN || cmd->buttons & BT_JUMP) && (!continuesInSession || player->continues > 0)) G_UseContinue(); @@ -11480,7 +11480,7 @@ void P_PlayerThink(player_t *player) player->playerstate = PST_DEAD; } - if (player->bot) + if (player->bot && player->bot != 3) { if (player->playerstate == PST_LIVE || player->playerstate == PST_DEAD) { From 00462323c3fe6dda7ece834cfa92431525f54e85 Mon Sep 17 00:00:00 2001 From: Shane Ellis Date: Fri, 15 Jan 2021 22:42:35 +0000 Subject: [PATCH 223/644] Revert "Implementation of lua function P_AddPlayer()" This reverts commit 5e8313e157ab0bef4f2e2a346906aa1a6efdd58b --- src/lua_baselib.c | 89 +++++------------------------------------------ 1 file changed, 8 insertions(+), 81 deletions(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 9bc8813a2..c5f847be6 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -155,6 +155,8 @@ static const struct { {META_PIVOTLIST, "spriteframepivot_t[]"}, {META_FRAMEPIVOT, "spriteframepivot_t"}, + {META_TAGLIST, "taglist"}, + {META_MOBJ, "mobj_t"}, {META_MAPTHING, "mapthing_t"}, @@ -163,6 +165,8 @@ static const struct { {META_SKIN, "skin_t"}, {META_POWERS, "player_t.powers"}, {META_SOUNDSID, "skin_t.soundsid"}, + {META_SKINSPRITES, "skin_t.sprites"}, + {META_SKINSPRITESLIST, "skin_t.sprites[]"}, {META_VERTEX, "vertex_t"}, {META_LINE, "line_t"}, @@ -184,6 +188,9 @@ static const struct { {META_CVAR, "consvar_t"}, {META_SECTORLINES, "sector_t.lines"}, +#ifdef MUTABLE_TAGS + {META_SECTORTAGLIST, "sector_t.taglist"}, +#endif {META_SIDENUM, "line_t.sidenum"}, {META_LINEARGS, "line_t.args"}, {META_LINESTRINGARGS, "line_t.stringargs"}, @@ -2632,7 +2639,7 @@ static int lib_rSkinUsable(lua_State *L) else // skin name { const char *skinname = luaL_checkstring(L, 2); - if (R_SkinAvailable(skinname) >= 0) + i = R_SkinAvailable(skinname); if (i == -1) return luaL_error(L, "skin %s (argument 2) is not loaded", skinname); } @@ -3400,85 +3407,6 @@ static int lib_gAddGametype(lua_State *L) return 0; } -// Bot adding function! -// Partly lifted from Got_AddPlayer -static int lib_gAddPlayer(lua_State *L) -{ - INT16 i, newplayernum, botcount = 1; - player_t *newplayer; - INT8 skinnum = 0, bot; - - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i]) - break; - - if (players[i].bot) - botcount++; // How many of us are there already? - } - if (i >= MAXPLAYERS) - { - lua_pushnil(L); - return 1; - } - - - newplayernum = i; - - //if (!splitscreen && !botingame) - CL_ClearPlayer(newplayernum); - - playeringame[newplayernum] = true; - G_AddPlayer(newplayernum); - newplayer = &players[newplayernum]; - - newplayer->jointime = 0; - newplayer->quittime = 0; - - // I hereby name you Bot X - strcpy(player_names[newplayernum], va("Bot %d", botcount)); - - // Read the skin string! - if (!lua_isnoneornil(L, 1)) - { - skinnum = R_SkinAvailable(luaL_checkstring(L, 1)); - skinnum = skinnum < 0 ? 0 : skinnum; - - // Bots can be whatever they want - if (!R_SkinUsable(newplayernum, skinnum)) - newplayer->availabilities |= 1 << skinnum; - } - - // Read the color! - if (!lua_isnoneornil(L, 2)) - newplayer->skincolor = R_GetColorByName(luaL_checkstring(L, 2)); - else - newplayer->skincolor = skins[newplayer->skin].prefcolor; - - // Read the bot name, if given! - if (!lua_isnoneornil(L, 3)) - strcpy(player_names[newplayernum], luaL_checkstring(L, 3)); - - bot = luaL_optinteger(L, 4, 3); - newplayer->bot = (bot >= 0 && bot <= 3) ? bot : 3; - - // Set the skin - SetPlayerSkinByNum(newplayernum, skinnum); - - - if (netgame) - { - char joinmsg[256]; - - strcpy(joinmsg, M_GetText("\x82*Bot %s has joined the game (player %d)")); - strcpy(joinmsg, va(joinmsg, player_names[newplayernum], newplayernum)); - HU_AddChatText(joinmsg, false); - } - - LUA_PushUserdata(L, newplayer, META_PLAYER); - return 0; -} - static int Lcheckmapnumber (lua_State *L, int idx, const char *fun) { if (ISINLEVEL) @@ -4059,7 +3987,6 @@ static luaL_Reg lib[] = { // g_game {"G_AddGametype", lib_gAddGametype}, - {"G_AddPlayer", lib_gAddPlayer}, {"G_BuildMapName",lib_gBuildMapName}, {"G_BuildMapTitle",lib_gBuildMapTitle}, {"G_FindMap",lib_gFindMap}, From 4e029dbc67a51529d88c2e16c696da97b5f73703 Mon Sep 17 00:00:00 2001 From: Shane Ellis Date: Fri, 15 Jan 2021 17:45:41 -0500 Subject: [PATCH 224/644] Update lua_baselib.c --- src/lua_baselib.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index c5f847be6..438c20b81 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -3407,6 +3407,82 @@ static int lib_gAddGametype(lua_State *L) return 0; } +// Bot adding function! +// Partly lifted from Got_AddPlayer +static int lib_gAddPlayer(lua_State *L) +{ + INT16 i, newplayernum, botcount = 1; + player_t *newplayer; + INT8 skinnum = 0, bot; + + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + break; + + if (players[i].bot) + botcount++; // How many of us are there already? + } + if (i >= MAXPLAYERS) + { + lua_pushnil(L); + return 1; + } + + + newplayernum = i; + + //if (!splitscreen && !botingame) + CL_ClearPlayer(newplayernum); + + playeringame[newplayernum] = true; + G_AddPlayer(newplayernum); + newplayer = &players[newplayernum]; + + newplayer->jointime = 0; + newplayer->quittime = 0; + + // I hereby name you Bot X + strcpy(player_names[newplayernum], va("Bot %d", botcount)); + + // Read the skin string! + if (!lua_isnoneornil(L, 1)) + { + skinnum = R_SkinAvailable(luaL_checkstring(L, 1)); + skinnum = skinnum < 0 ? 0 : skinnum; + } + + // Read the color! + if (!lua_isnoneornil(L, 2)) + newplayer->skincolor = R_GetColorByName(luaL_checkstring(L, 2)); + else + newplayer->skincolor = skins[newplayer->skin].prefcolor; + + // Read the bot name, if given! + if (!lua_isnoneornil(L, 3)) + strcpy(player_names[newplayernum], luaL_checkstring(L, 3)); + + bot = luaL_optinteger(L, 4, 3); + newplayer->bot = (bot >= 0 && bot <= 3) ? bot : 3; + + // Set the skin (needed to set bot first!) + SetPlayerSkinByNum(newplayernum, skinnum); + + + if (netgame) + { + char joinmsg[256]; + + strcpy(joinmsg, M_GetText("\x82*Bot %s has joined the game (player %d)")); + strcpy(joinmsg, va(joinmsg, player_names[newplayernum], newplayernum)); + HU_AddChatText(joinmsg, false); + } + + LUA_PushUserdata(L, newplayer, META_PLAYER); + return 0; +} + + static int Lcheckmapnumber (lua_State *L, int idx, const char *fun) { if (ISINLEVEL) @@ -3987,6 +4063,7 @@ static luaL_Reg lib[] = { // g_game {"G_AddGametype", lib_gAddGametype}, + {"G_AddPlayer", lib_gAddPlayer}, {"G_BuildMapName",lib_gBuildMapName}, {"G_BuildMapTitle",lib_gBuildMapTitle}, {"G_FindMap",lib_gFindMap}, From 8fa8ca622249af77e1aad9ffe6e2800f92448380 Mon Sep 17 00:00:00 2001 From: Shane Ellis Date: Fri, 15 Jan 2021 17:47:26 -0500 Subject: [PATCH 225/644] Update r_skins.c --- src/r_skins.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/r_skins.c b/src/r_skins.c index 155a64700..a29209873 100644 --- a/src/r_skins.c +++ b/src/r_skins.c @@ -512,6 +512,10 @@ static boolean R_ProcessPatchableFields(skin_t *skin, char *stoken, char *value) GETFLAG(MULTIABILITY) GETFLAG(NONIGHTSROTATION) GETFLAG(NONIGHTSSUPER) + GETFLAG(NOSUPERSPRITES) + GETFLAG(NOSUPERJUMPBOOST) + GETFLAG(CANBUSTWALLS) + GETFLAG(NOSHIELDABILITY) #undef GETFLAG else // let's check if it's a sound, otherwise error out From 93562b782e9e001d82fa6d8c94860ea3170a2bc9 Mon Sep 17 00:00:00 2001 From: Shane Ellis Date: Fri, 15 Jan 2021 22:50:20 +0000 Subject: [PATCH 226/644] =?UTF-8?q?Revert=20"Command=5FKick()=20-=20Allow?= =?UTF-8?q?=20removal=20of=20non-consoleplayer/secondaryviewplayer=20playe?= =?UTF-8?q?r=E2=80=A6"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 079fe9ba7e488e880561318e1200e8630289d117 --- src/d_clisrv.c | 66 ++++++++++++++++++++++++-------------------------- 1 file changed, 32 insertions(+), 34 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 88b4d9387..4fdc7e7ee 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1595,9 +1595,7 @@ static void CL_ReloadReceivedSavegame(void) for (i = 0; i < MAXPLAYERS; i++) { -#ifdef HAVE_BLUA LUA_InvalidatePlayer(&players[i]); -#endif sprintf(player_names[i], "Player %d", i + 1); } @@ -2260,11 +2258,15 @@ void D_SaveBan(void) size_t i; banreason_t *reasonlist = reasonhead; const char *address, *mask; + const char *path = va("%s"PATHSEP"%s", srb2home, "ban.txt"); if (!reasonhead) + { + remove(path); return; + } - f = fopen(va("%s"PATHSEP"%s", srb2home, "ban.txt"), "w"); + f = fopen(path, "w"); if (!f) { @@ -2308,16 +2310,14 @@ static void Ban_Add(const char *reason) reasontail = reasonlist; } -static void Command_ClearBans(void) +static void Ban_Clear(void) { banreason_t *temp; - if (!I_ClearBans) - return; - I_ClearBans(); - D_SaveBan(); + reasontail = NULL; + while (reasonhead) { temp = reasonhead->next; @@ -2327,6 +2327,15 @@ static void Command_ClearBans(void) } } +static void Command_ClearBans(void) +{ + if (!I_ClearBans) + return; + + Ban_Clear(); + D_SaveBan(); +} + static void Ban_Load_File(boolean warning) { FILE *f; @@ -2334,6 +2343,9 @@ static void Ban_Load_File(boolean warning) const char *address, *mask; char buffer[MAX_WADPATH]; + if (!I_ClearBans) + return; + f = fopen(va("%s"PATHSEP"%s", srb2home, "ban.txt"), "r"); if (!f) @@ -2343,13 +2355,7 @@ static void Ban_Load_File(boolean warning) return; } - if (I_ClearBans) - Command_ClearBans(); - else - { - fclose(f); - return; - } + Ban_Clear(); for (i=0; fgets(buffer, (int)sizeof(buffer), f); i++) { @@ -2809,11 +2815,11 @@ static void Command_Kick(void) return; } - //if (!netgame) // Don't kick Tails in splitscreen! - //{ - // CONS_Printf(M_GetText("This only works in a netgame.\n")); - // return; - //} + if (!netgame) // Don't kick Tails in splitscreen! + { + CONS_Printf(M_GetText("This only works in a netgame.\n")); + return; + } if (server || IsPlayerAdmin(consoleplayer)) { @@ -2821,14 +2827,9 @@ static void Command_Kick(void) UINT8 *p = buf; const SINT8 pn = nametonum(COM_Argv(1)); - if (splitscreen && (pn == 0 || pn == 1)) - { - CONS_Printf(M_GetText("Splitscreen players cannot be kicked.\n")); - return; - } if (pn == -1 || pn == 0) return; - + // Special case if we are trying to kick a player who is downloading the game state: // trigger a timeout instead of kicking them, because a kick would only // take effect after they have finished downloading @@ -3031,8 +3032,7 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum) if (pnum == consoleplayer) { - if (Playing()) - LUAh_GameQuit(); + LUAh_GameQuit(false); #ifdef DUMPCONSISTENCY if (msg == KICK_MSG_CON_FAIL) SV_SavedGame(); #endif @@ -3732,8 +3732,7 @@ static void HandleConnect(SINT8 node) static void HandleShutdown(SINT8 node) { (void)node; - if (Playing()) - LUAh_GameQuit(); + LUAh_GameQuit(false); D_QuitNetGame(); CL_Reset(); D_StartTitle(); @@ -3748,8 +3747,7 @@ static void HandleShutdown(SINT8 node) static void HandleTimeout(SINT8 node) { (void)node; - if (Playing()) - LUAh_GameQuit(); + LUAh_GameQuit(false); D_QuitNetGame(); CL_Reset(); D_StartTitle(); @@ -4852,14 +4850,14 @@ void TryRunTics(tic_t realtics) { DEBFILE(va("============ Running tic %d (local %d)\n", gametic, localgametic)); - ps_tictime = I_GetTimeMicros(); + ps_tictime = I_GetPreciseTime(); G_Ticker((gametic % NEWTICRATERATIO) == 0); ExtraDataTicker(); gametic++; consistancy[gametic%BACKUPTICS] = Consistancy(); - ps_tictime = I_GetTimeMicros() - ps_tictime; + ps_tictime = I_GetPreciseTime() - ps_tictime; // Leave a certain amount of tics present in the net buffer as long as we've ran at least one tic this frame. if (client && gamestate == GS_LEVEL && leveltime > 3 && neededtic <= gametic + cv_netticbuffer.value) From 9bbebcbe9e4d6ed144bed21c0cf0b37d6918f20c Mon Sep 17 00:00:00 2001 From: Shane Ellis Date: Fri, 15 Jan 2021 17:55:14 -0500 Subject: [PATCH 227/644] Update d_clisrv.c --- src/d_clisrv.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 4fdc7e7ee..4574e5a1c 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2815,18 +2815,22 @@ static void Command_Kick(void) return; } - if (!netgame) // Don't kick Tails in splitscreen! - { - CONS_Printf(M_GetText("This only works in a netgame.\n")); - return; - } - if (server || IsPlayerAdmin(consoleplayer)) { UINT8 buf[3 + MAX_REASONLENGTH]; UINT8 *p = buf; const SINT8 pn = nametonum(COM_Argv(1)); + // Unlike bans, kicks are used especially to remove bot players, so we'll + // need to run a more specific check which allows kicking offline, but + // not against splitscreen players. + if (splitscreen && (pn == 0 || pn == 1)) + { + CONS_Printf(M_GetText("Splitscreen players cannot be kicked.\n")); + return; + } + + if (pn == -1 || pn == 0) return; From 225e7c72ace052a5945454b46ba14ab623209396 Mon Sep 17 00:00:00 2001 From: Shane Ellis Date: Fri, 15 Jan 2021 18:00:00 -0500 Subject: [PATCH 228/644] Update p_mobj.c --- src/p_mobj.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 58124fb9b..f27ab2914 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1840,7 +1840,7 @@ void P_XYMovement(mobj_t *mo) moved = false; if (player) { - if (player->bot) + if (player->bot and player->bot != 3) B_MoveBlocked(player); } @@ -4135,7 +4135,7 @@ boolean P_BossTargetPlayer(mobj_t *actor, boolean closest) player = &players[actor->lastlook]; - if (player->pflags & PF_INVIS || player->bot || player->spectator) + if (player->pflags & PF_INVIS || (player->bot && player->bot != 3) || player->spectator) continue; // ignore notarget if (!player->mo || P_MobjWasRemoved(player->mo)) From 505ba1ff631c91d3f91a65bd728817fe19ea6d76 Mon Sep 17 00:00:00 2001 From: Shane Ellis Date: Fri, 15 Jan 2021 18:06:36 -0500 Subject: [PATCH 229/644] Update g_game.c --- src/g_game.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/g_game.c b/src/g_game.c index f1cae8cf5..43906e558 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2974,7 +2974,8 @@ void G_DoReborn(INT32 playernum) // Make sure objectplace is OFF when you first start the level! OP_ResetObjectplace(); - if (player->bot && playernum != consoleplayer) + // Tailsbot + if (player->bot && player->bot != 3 && playernum != consoleplayer) { // Bots respawn next to their master. mobj_t *oldmo = NULL; @@ -2992,6 +2993,28 @@ void G_DoReborn(INT32 playernum) return; } + + // Additional players (e.g. independent bots) in Single Player + if (playernum != consoleplayer && !(netgame || multiplayer)) + { + mobj_t *oldmo = NULL; + // Do nothing if out of lives + if (player->lives <= 0) + return; + + // Otherwise do respawn, starting by removing the player object + if (player->mo) + { + oldmo = player->mo; + P_RemoveMobj(player->mo); + } + // Do spawning + G_SpawnPlayer(playernum); + if (oldmo) + G_ChangePlayerReferences(oldmo, players[playernum].mo); + + return; //Exit function to avoid proccing other SP related mechanics + } if (countdowntimeup || (!(netgame || multiplayer) && (gametyperules & GTR_CAMPAIGN))) resetlevel = true; From 1583bf126b3105f98d647634a4256d22bc1e7e4d Mon Sep 17 00:00:00 2001 From: Shane Ellis Date: Fri, 15 Jan 2021 18:31:09 -0500 Subject: [PATCH 230/644] lua habits --- src/p_mobj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index f27ab2914..a660a8a92 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1840,7 +1840,7 @@ void P_XYMovement(mobj_t *mo) moved = false; if (player) { - if (player->bot and player->bot != 3) + if (player->bot && player->bot != 3) B_MoveBlocked(player); } From 0e9b4acb587491b6f5d0b9c9c898a1c37811de85 Mon Sep 17 00:00:00 2001 From: Shane Ellis Date: Fri, 15 Jan 2021 19:29:03 -0500 Subject: [PATCH 231/644] Update g_game.c (Account for bot type 3) --- src/g_game.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/g_game.c b/src/g_game.c index 43906e558..5e2b4e708 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2627,8 +2627,10 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) p->totalring = totalring; p->mare = mare; - if (bot) + if (bot == 2) p->bot = 1; // reset to AI-controlled + else + p->bot = bot; p->pity = pity; p->rings = rings; p->spheres = spheres; From b73a15a0bfe628e8c1001dc97aef7d2720940ff5 Mon Sep 17 00:00:00 2001 From: Shane Ellis Date: Fri, 15 Jan 2021 22:50:15 -0500 Subject: [PATCH 232/644] fixed G_AddPlayer not sending return value --- src/lua_baselib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 438c20b81..f54662278 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -3479,7 +3479,7 @@ static int lib_gAddPlayer(lua_State *L) } LUA_PushUserdata(L, newplayer, META_PLAYER); - return 0; + return 1; } From e19b0856846bbdcc860c735b9da95082965f604b Mon Sep 17 00:00:00 2001 From: Shane Ellis Date: Fri, 15 Jan 2021 22:56:48 -0500 Subject: [PATCH 233/644] Netcode failsafe. At least until I can figure out the best way to produce bot cmds outside of player sends. --- src/b_bot.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/b_bot.c b/src/b_bot.c index d3635f32c..35b14bd78 100644 --- a/src/b_bot.c +++ b/src/b_bot.c @@ -362,6 +362,12 @@ void B_BuildTiccmd(player_t *player, ticcmd_t *cmd) // Bot AI isn't programmed in analog. CV_SetValue(&cv_analog[1], false); + // Bot cmd functions and hooks are not currently netplay compatible + // Necessary failsafe, as a bot in the P2 position in a netgame can inherit + // the last input from a hook triggered in splitscreen or SP. + if (netgame) + return; + // Let Lua scripts build ticcmds if (LUAh_BotTiccmd(player, cmd)) return; From f3ad648874a910cbd7d7dc508ed4b74de29b5373 Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Sun, 6 Dec 2020 17:46:35 -0300 Subject: [PATCH 234/644] Revert "Move a few mobj spawn defaults to its own function" This reverts commit 6f9c48a30560b0f2d89f7202371dfc164015b9ba. # Conflicts: # src/p_mobj.c --- src/p_local.h | 1 - src/p_mobj.c | 87 ++++++++++++++++++++++----------------------------- src/p_saveg.c | 40 +++++++++++++++++++++-- 3 files changed, 75 insertions(+), 53 deletions(-) diff --git a/src/p_local.h b/src/p_local.h index 9359290fa..8caab0d27 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -279,7 +279,6 @@ mobjtype_t P_GetMobjtype(UINT16 mthingtype); void P_RespawnSpecials(void); mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type); -void P_SetMobjSpawnDefaults(mobj_t *mobj); void P_RecalcPrecipInSector(sector_t *sector); void P_PrecipitationEffects(void); diff --git a/src/p_mobj.c b/src/p_mobj.c index 58124fb9b..4945eed48 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10440,7 +10440,44 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) mobj->x = x; mobj->y = y; - P_SetMobjSpawnDefaults(mobj); + mobj->radius = info->radius; + mobj->height = info->height; + mobj->flags = info->flags; + + mobj->health = (info->spawnhealth ? info->spawnhealth : 1); + + mobj->reactiontime = info->reactiontime; + + mobj->lastlook = -1; // stuff moved in P_enemy.P_LookForPlayer + + // do not set the state with P_SetMobjState, + // because action routines can not be called yet + st = &states[info->spawnstate]; + + mobj->state = st; + mobj->tics = st->tics; + mobj->sprite = st->sprite; + mobj->frame = st->frame; // FF_FRAMEMASK for frame, and other bits.. + P_SetupStateAnimation(mobj, st); + + mobj->friction = ORIG_FRICTION; + + mobj->movefactor = FRACUNIT; + + // All mobjs are created at 100% scale. + mobj->scale = FRACUNIT; + mobj->destscale = mobj->scale; + mobj->scalespeed = FRACUNIT/12; + + // TODO: Make this a special map header + if ((maptol & TOL_ERZ3) && !(mobj->type == MT_BLACKEGGMAN)) + mobj->destscale = FRACUNIT/2; + + // Sprite rendering + mobj->blendmode = AST_TRANSLUCENT; + mobj->spritexscale = mobj->spriteyscale = mobj->scale; + mobj->spritexoffset = mobj->spriteyoffset = 0; + mobj->floorspriteslope = NULL; // set subsector and/or block links P_SetThingPosition(mobj); @@ -10747,8 +10784,6 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) mobj->frame &= ~FF_FRAMEMASK; } - st = &states[info->spawnstate]; - // Call action functions when the state is set if (st->action.acp1 && (mobj->flags & MF_RUNSPAWNFUNC)) { @@ -10779,52 +10814,6 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) return mobj; } -void P_SetMobjSpawnDefaults(mobj_t *mobj) -{ - const mobjinfo_t *info = mobj->info; - state_t *st = &states[info->spawnstate]; - - mobj->radius = info->radius; - mobj->height = info->height; - mobj->flags = info->flags; - - mobj->health = (info->spawnhealth ? info->spawnhealth : 1); - - mobj->reactiontime = info->reactiontime; - - mobj->lastlook = -1; // stuff moved in P_enemy.P_LookForPlayer - - // do not set the state with P_SetMobjState, - // because action routines can not be called yet - mobj->state = st; - mobj->tics = st->tics; - mobj->sprite = st->sprite; - mobj->frame = st->frame; // FF_FRAMEMASK for frame, and other bits.. - P_SetupStateAnimation(mobj, st); - - mobj->friction = ORIG_FRICTION; - - mobj->movefactor = FRACUNIT; - - // All mobjs are created at 100% scale. - mobj->scale = FRACUNIT; - mobj->destscale = mobj->scale; - mobj->scalespeed = FRACUNIT/12; - - // TODO: Make this a special map header - if ((maptol & TOL_ERZ3) && !(mobj->type == MT_BLACKEGGMAN)) - mobj->destscale = FRACUNIT/2; - - // Make sure scale matches destscale immediately when spawned - P_SetScale(mobj, mobj->destscale); - - // Sprite rendering - mobj->blendmode = AST_TRANSLUCENT; - mobj->spritexscale = mobj->spriteyscale = FRACUNIT; - mobj->spritexoffset = mobj->spriteyoffset = 0; - mobj->floorspriteslope = NULL; -} - static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) { state_t *st; diff --git a/src/p_saveg.c b/src/p_saveg.c index c1364e08f..03229e740 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -2692,10 +2692,7 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) } mobj->type = i; } - mobj->info = &mobjinfo[mobj->type]; - P_SetMobjSpawnDefaults(mobj); - if (diff & MD_POS) { mobj->x = READFIXED(save_p); @@ -2721,21 +2718,35 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) if (diff & MD_RADIUS) mobj->radius = READFIXED(save_p); + else + mobj->radius = mobj->info->radius; if (diff & MD_HEIGHT) mobj->height = READFIXED(save_p); + else + mobj->height = mobj->info->height; if (diff & MD_FLAGS) mobj->flags = READUINT32(save_p); + else + mobj->flags = mobj->info->flags; if (diff & MD_FLAGS2) mobj->flags2 = READUINT32(save_p); if (diff & MD_HEALTH) mobj->health = READINT32(save_p); + else + mobj->health = mobj->info->spawnhealth; if (diff & MD_RTIME) mobj->reactiontime = READINT32(save_p); + else + mobj->reactiontime = mobj->info->reactiontime; if (diff & MD_STATE) mobj->state = &states[READUINT16(save_p)]; + else + mobj->state = &states[mobj->info->spawnstate]; if (diff & MD_TICS) mobj->tics = READINT32(save_p); + else + mobj->tics = mobj->state->tics; if (diff & MD_SPRITE) { mobj->sprite = READUINT16(save_p); if (mobj->sprite == SPR_PLAY) @@ -2751,6 +2762,11 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) mobj->frame = READUINT32(save_p); mobj->anim_duration = READUINT16(save_p); } + else + { + mobj->frame = mobj->state->frame; + mobj->anim_duration = (UINT16)mobj->state->var2; + } if (diff & MD_EFLAGS) mobj->eflags = READUINT16(save_p); if (diff & MD_PLAYER) @@ -2767,14 +2783,20 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) mobj->threshold = READINT32(save_p); if (diff & MD_LASTLOOK) mobj->lastlook = READINT32(save_p); + else + mobj->lastlook = -1; if (diff & MD_TARGET) mobj->target = (mobj_t *)(size_t)READUINT32(save_p); if (diff & MD_TRACER) mobj->tracer = (mobj_t *)(size_t)READUINT32(save_p); if (diff & MD_FRICTION) mobj->friction = READFIXED(save_p); + else + mobj->friction = ORIG_FRICTION; if (diff & MD_MOVEFACTOR) mobj->movefactor = READFIXED(save_p); + else + mobj->movefactor = FRACUNIT; if (diff & MD_FUSE) mobj->fuse = READINT32(save_p); if (diff & MD_WATERTOP) @@ -2783,10 +2805,16 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) mobj->waterbottom = READFIXED(save_p); if (diff & MD_SCALE) mobj->scale = READFIXED(save_p); + else + mobj->scale = FRACUNIT; if (diff & MD_DSCALE) mobj->destscale = READFIXED(save_p); + else + mobj->destscale = mobj->scale; if (diff2 & MD2_SCALESPEED) mobj->scalespeed = READFIXED(save_p); + else + mobj->scalespeed = FRACUNIT/12; if (diff2 & MD2_CUSVAL) mobj->cusval = READINT32(save_p); if (diff2 & MD2_CVMEM) @@ -2817,10 +2845,16 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) mobj->renderflags = READUINT32(save_p); if (diff2 & MD2_BLENDMODE) mobj->blendmode = READINT32(save_p); + else + mobj->blendmode = AST_TRANSLUCENT; if (diff2 & MD2_SPRITEXSCALE) mobj->spritexscale = READFIXED(save_p); + else + mobj->spritexscale = FRACUNIT; if (diff2 & MD2_SPRITEYSCALE) mobj->spriteyscale = READFIXED(save_p); + else + mobj->spriteyscale = FRACUNIT; if (diff2 & MD2_SPRITEXOFFSET) mobj->spritexoffset = READFIXED(save_p); if (diff2 & MD2_SPRITEYOFFSET) From ce8e389a2d9cec8c36f43a9573f0d9a29bf50d18 Mon Sep 17 00:00:00 2001 From: Shane Ellis Date: Sat, 23 Jan 2021 09:49:57 -0500 Subject: [PATCH 235/644] Add lua player.botleader and player.buttons_last (read+write) --- src/lua_playerlib.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 0eb54808f..a8dc64a15 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -370,6 +370,10 @@ static int player_get(lua_State *L) lua_pushboolean(L, plr->outofcoop); else if (fastcmp(field,"bot")) lua_pushinteger(L, plr->bot); + else if (fastcmp(field,"botleader")) + LUA_PushUserdata(L, plr->botleader, META_PLAYER); + else if (fastcmp(field,"buttons_last")) + lua_pushinteger(L, plr->buttons_last); else if (fastcmp(field,"jointime")) lua_pushinteger(L, plr->jointime); else if (fastcmp(field,"quittime")) From c391d76c11331dec29f3eedddb9bcc9344eb82e7 Mon Sep 17 00:00:00 2001 From: Shane Ellis Date: Sat, 23 Jan 2021 10:06:47 -0500 Subject: [PATCH 236/644] buttons_last -> lastbuttons --- src/lua_playerlib.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index a8dc64a15..51eb4ac0c 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -372,8 +372,8 @@ static int player_get(lua_State *L) lua_pushinteger(L, plr->bot); else if (fastcmp(field,"botleader")) LUA_PushUserdata(L, plr->botleader, META_PLAYER); - else if (fastcmp(field,"buttons_last")) - lua_pushinteger(L, plr->buttons_last); + else if (fastcmp(field,"lastbuttons")) + lua_pushinteger(L, plr->lastbuttons); else if (fastcmp(field,"jointime")) lua_pushinteger(L, plr->jointime); else if (fastcmp(field,"quittime")) @@ -723,6 +723,15 @@ static int player_set(lua_State *L) plr->outofcoop = lua_toboolean(L, 3); else if (fastcmp(field,"bot")) return NOSET; + else if (fastcmp(field,"botleader")) + { + player_t *player = NULL; + if (!lua_isnil(L, 3)) + player = *((player_t **)luaL_checkudata(L, 3, META_PLAYER)); + plr->botleader = player; + } + else if (fastcmp(field,"lastbuttons")) + plr->lastbuttons = (UINT16)luaL_checkinteger(L, 3); else if (fastcmp(field,"jointime")) plr->jointime = (tic_t)luaL_checkinteger(L, 3); else if (fastcmp(field,"quittime")) From 2abf89e8000b6dbda26d5dd59b9306c5d32624b6 Mon Sep 17 00:00:00 2001 From: Shane Ellis Date: Sat, 23 Jan 2021 10:13:16 -0500 Subject: [PATCH 237/644] Update G_AddPlayer() --- src/lua_baselib.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index f54662278..525ce89ec 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -3432,8 +3432,7 @@ static int lib_gAddPlayer(lua_State *L) newplayernum = i; - //if (!splitscreen && !botingame) - CL_ClearPlayer(newplayernum); + CL_ClearPlayer(newplayernum); playeringame[newplayernum] = true; G_AddPlayer(newplayernum); @@ -3442,30 +3441,34 @@ static int lib_gAddPlayer(lua_State *L) newplayer->jointime = 0; newplayer->quittime = 0; - // I hereby name you Bot X + // Set the bot name (defaults to Bot #) strcpy(player_names[newplayernum], va("Bot %d", botcount)); - // Read the skin string! + // Read the skin argument (defaults to Sonic) if (!lua_isnoneornil(L, 1)) { skinnum = R_SkinAvailable(luaL_checkstring(L, 1)); skinnum = skinnum < 0 ? 0 : skinnum; } - // Read the color! + // Read the color (defaults to skin prefcolor) if (!lua_isnoneornil(L, 2)) newplayer->skincolor = R_GetColorByName(luaL_checkstring(L, 2)); else newplayer->skincolor = skins[newplayer->skin].prefcolor; - // Read the bot name, if given! + // Read the bot name, if given if (!lua_isnoneornil(L, 3)) strcpy(player_names[newplayernum], luaL_checkstring(L, 3)); bot = luaL_optinteger(L, 4, 3); newplayer->bot = (bot >= 0 && bot <= 3) ? bot : 3; - - // Set the skin (needed to set bot first!) + + // If our bot is a 2P type, we'll need to set its leader so it can spawn + if (newplayer->bot == BOT_2PAI || newplayer->bot == BOT_2PHUMAN) + B_UpdateBotleader(newplayer); + + // Set the skin (can't do this until AFTER bot type is set!) SetPlayerSkinByNum(newplayernum, skinnum); From 2e528216ac855fbfdf9f73df3a534a237936ccbd Mon Sep 17 00:00:00 2001 From: Shane Ellis Date: Sat, 23 Jan 2021 10:15:33 -0500 Subject: [PATCH 238/644] Updated references to player->bot --- src/p_user.c | 48 ++++++++++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 9e86e2d73..c631f49b2 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -776,8 +776,8 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) { UINT8 oldmare, oldmarelap, oldmarebonuslap; - // Bots can't be NiGHTSerized, silly!1 :P - if (player->bot && player->bot != 3) + //! Bots can't be NiGHTSerized, silly!1 :P + if (player->bot == BOT_2PAI || player->bot || BOT_2PHUMAN) return; if (player->powers[pw_carry] != CR_NIGHTSMODE) @@ -1188,9 +1188,9 @@ void P_GivePlayerRings(player_t *player, INT32 num_rings) { if (!player) return; - - if (player->bot && player->bot != 3) - player = &players[consoleplayer]; + //! + if ((player->bot == BOT_2PAI || player->bot == BOT_2PHUMAN) && player->botleader) + player = player->botleader; if (!player->mo) return; @@ -1234,8 +1234,8 @@ void P_GivePlayerSpheres(player_t *player, INT32 num_spheres) if (!player) return; - if (player->bot && player->bot != 3) - player = &players[consoleplayer]; + if ((player->bot == BOT_2PAI || player->bot == BOT_2PHUMAN) && player->botleader) + player = player->botleader; if (!player->mo) return; @@ -1261,8 +1261,8 @@ void P_GivePlayerLives(player_t *player, INT32 numlives) if (!player) return; - if (player->bot && player->bot != 3) - player = &players[consoleplayer]; + if ((player->bot == BOT_2PAI || player->bot == BOT_2PHUMAN) && player->botleader) + player = player->botleader; if (gamestate == GS_LEVEL) { @@ -1367,8 +1367,8 @@ void P_AddPlayerScore(player_t *player, UINT32 amount) { UINT32 oldscore; - if (player->bot && player->bot != 3) - player = &players[consoleplayer]; + if ((player->bot == BOT_2PAI || player->bot == BOT_2PHUMAN) && player->botleader) + player = player->botleader; // NiGHTS does it different! if (gamestate == GS_LEVEL && mapheaderinfo[gamemap-1]->typeoflevel & TOL_NIGHTS) @@ -5370,7 +5370,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) player->powers[pw_tailsfly] = tailsflytics + 1; // Set the fly timer player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE|PF_SPINNING|PF_STARTDASH); - if (player->bot == 1) + if (player->bot == BOT_2PAI) player->pflags |= PF_THOKKED; else player->pflags |= (PF_THOKKED|PF_CANCARRY); @@ -5957,7 +5957,8 @@ static void P_3dMovement(player_t *player) acceleration = 96 + (FixedDiv(player->speed, player->mo->scale)>>FRACBITS) * 40; topspeed = normalspd; } - else if (player->bot && player->bot != 3) + //! Kill this! + /* else if (player->bot == BOT_2PAI || player->bot == BOT_2PHUMAN) { // Bot steals player 1's stats normalspd = FixedMul(players[consoleplayer].normalspeed, player->mo->scale); thrustfactor = players[consoleplayer].thrustfactor; @@ -5972,7 +5973,7 @@ static void P_3dMovement(player_t *player) } else topspeed = normalspd; - } + } */ else { if (player->powers[pw_super] || player->powers[pw_sneakers]) @@ -9497,7 +9498,7 @@ static void P_DeathThink(player_t *player) if (player->deadtimer < INT32_MAX) player->deadtimer++; - if (player->bot && player->bot != 3) // don't allow bots to do any of the below, B_CheckRespawn does all they need for respawning already + if (player->bot == BOT_2PAI || player->bot == BOT_2PHUMAN) // don't allow followbots to do any of the below, B_CheckRespawn does all they need for respawning already goto notrealplayer; // continue logic @@ -11473,6 +11474,9 @@ void P_PlayerThink(player_t *player) I_Error("p_playerthink: players[%s].mo == NULL", sizeu1(playeri)); #endif + //! Reset terrain blocked status for this frame + player->blocked = false; + // todo: Figure out what is actually causing these problems in the first place... if (player->mo->health <= 0 && player->playerstate == PST_LIVE) //you should be DEAD! { @@ -11480,7 +11484,7 @@ void P_PlayerThink(player_t *player) player->playerstate = PST_DEAD; } - if (player->bot && player->bot != 3) + if (player->bot == BOT_2PAI || player->bot == BOT_2PHUMAN) { if (player->playerstate == PST_LIVE || player->playerstate == PST_DEAD) { @@ -11623,8 +11627,8 @@ void P_PlayerThink(player_t *player) INT32 i; for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i] || players[i].spectator || players[i].bot) + { //! + if (!playeringame[i] || players[i].spectator || players[i].bot == BOT_2PAI || players[i].bot == BOT_2PHUMAN) continue; if (players[i].lives <= 0) continue; @@ -11655,8 +11659,8 @@ void P_PlayerThink(player_t *player) INT32 i, total = 0, exiting = 0; for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i] || players[i].spectator || players[i].bot) + { //! + if (!playeringame[i] || players[i].spectator || players[i].bot == BOT_2PAI || players[i].bot == BOT_2PHUMAN) continue; if (players[i].quittime > 30 * TICRATE) continue; @@ -12596,8 +12600,8 @@ void P_PlayerAfterThink(player_t *player) player->mo->momy = tails->momy; player->mo->momz = tails->momz; } - - if (G_CoopGametype() && tails->player && tails->player->bot != 1) + //! + if (G_CoopGametype() && tails->player && tails->player->bot != BOT_2PAI) { player->mo->angle = tails->angle; From 2016caa70b584286af7aff80e83eb63c32f16534 Mon Sep 17 00:00:00 2001 From: Shane Ellis Date: Sat, 23 Jan 2021 10:16:27 -0500 Subject: [PATCH 239/644] Update references to player->bot --- src/p_mobj.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index a660a8a92..43d81077e 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1839,10 +1839,9 @@ void P_XYMovement(mobj_t *mo) // blocked move moved = false; - if (player) { - if (player->bot && player->bot != 3) - B_MoveBlocked(player); - } + //!!! + if (player) + B_MoveBlocked(player); if (LUAh_MobjMoveBlocked(mo)) { @@ -4135,7 +4134,7 @@ boolean P_BossTargetPlayer(mobj_t *actor, boolean closest) player = &players[actor->lastlook]; - if (player->pflags & PF_INVIS || (player->bot && player->bot != 3) || player->spectator) + if (player->pflags & PF_INVIS || player->bot == BOT_2PAI || player->bot == BOT_2PHUMAN || player->spectator) continue; // ignore notarget if (!player->mo || P_MobjWasRemoved(player->mo)) @@ -4176,7 +4175,7 @@ boolean P_SupermanLook4Players(mobj_t *actor) if (players[c].pflags & PF_INVIS) continue; // ignore notarget - if (!players[c].mo || players[c].bot) + if (!players[c].mo || players[c].bot == BOT_2PAI || players[c].bot == BOT_2PHUMAN) continue; if (players[c].mo->health <= 0) @@ -7307,7 +7306,7 @@ static void P_RosySceneryThink(mobj_t *mobj) continue; if (!players[i].mo) continue; - if (players[i].bot) + if (players[i].bot == BOT_2PAI || players[i].bot == BOT_2PHUMAN) continue; if (!players[i].mo->health) continue; From fd536e91a3bb73c44adcc13486631c18e83d9620 Mon Sep 17 00:00:00 2001 From: Shane Ellis Date: Sat, 23 Jan 2021 10:17:05 -0500 Subject: [PATCH 240/644] void B_UpdateBotleader(player_t *player); --- src/b_bot.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/b_bot.h b/src/b_bot.h index 2806bd68f..53114df48 100644 --- a/src/b_bot.h +++ b/src/b_bot.h @@ -10,6 +10,7 @@ /// \file b_bot.h /// \brief Basic bot handling +void B_UpdateBotleader(player_t *player); void B_BuildTiccmd(player_t *player, ticcmd_t *cmd); void B_KeysToTiccmd(mobj_t *mo, ticcmd_t *cmd, boolean forward, boolean backward, boolean left, boolean right, boolean strafeleft, boolean straferight, boolean jump, boolean spin); boolean B_CheckRespawn(player_t *player); From b8fea55f6777d3fa9891d845c6d1430f66acb363 Mon Sep 17 00:00:00 2001 From: Shane Ellis Date: Sat, 23 Jan 2021 10:25:35 -0500 Subject: [PATCH 241/644] Update b_bot.c --- src/b_bot.c | 251 +++++++++++++++++++++++++++++----------------------- 1 file changed, 139 insertions(+), 112 deletions(-) diff --git a/src/b_bot.c b/src/b_bot.c index 35b14bd78..151aaa633 100644 --- a/src/b_bot.c +++ b/src/b_bot.c @@ -18,29 +18,41 @@ #include "b_bot.h" #include "lua_hook.h" -// If you want multiple bots, variables like this will -// have to be stuffed in something accessible through player_t. -static boolean lastForward = false; -static boolean lastBlocked = false; -static boolean blocked = false; - -static boolean jump_last = false; -static boolean spin_last = false; -static UINT8 anxiety = 0; -static boolean panic = false; -static UINT8 flymode = 0; -static boolean spinmode = false; -static boolean thinkfly = false; - -static inline void B_ResetAI(void) +void B_UpdateBotleader(player_t *player) { - jump_last = false; - spin_last = false; - anxiety = 0; - panic = false; - flymode = 0; - spinmode = false; - thinkfly = false; + UINT32 i; + fixed_t dist; + fixed_t neardist = INT32_MAX; + player_t *nearplayer = NULL; + //Find new botleader + //if (!player->botleader) + //{ + for (i = 0; i < MAXPLAYERS; i++) + { + if (players[i].bot || players[i].playerstate != PST_LIVE || players[i].spectator || !players[i].mo) + continue; + if (!player->mo) //Can't do distance calculations if there's no player object, so we'll just take the first we find + { + player->botleader = &players[i]; + return; + } + //Update best candidate based on nearest distance + dist = R_PointToDist2(player->mo->x, player->mo->y, players[i].mo->x, players[i].mo->y); + if (neardist > dist) + { + neardist = dist; + nearplayer = &players[i]; + } + } + //Set botleader to best candidate (or null if none available) + player->botleader = nearplayer; + //} +} + +static inline void B_ResetAI(botmem_t *mem) +{ + mem->thinkstate = AI_FOLLOW; + mem->catchup_tics = 0; } static void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd) @@ -49,39 +61,48 @@ static void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd) player_t *player = sonic->player, *bot = tails->player; ticcmd_t *pcmd = &player->cmd; - boolean water = tails->eflags & MFE_UNDERWATER; + botmem_t *mem = &bot->botmem; + boolean water = (tails->eflags & MFE_UNDERWATER); SINT8 flip = P_MobjFlip(tails); boolean _2d = (tails->flags2 & MF2_TWOD) || twodlevel; fixed_t scale = tails->scale; + boolean jump_last = (bot->lastbuttons & BT_JUMP); + boolean spin_last = (bot->lastbuttons & BT_SPIN); fixed_t dist = P_AproxDistance(sonic->x - tails->x, sonic->y - tails->y); fixed_t zdist = flip * (sonic->z - tails->z); angle_t ang = sonic->angle; fixed_t pmom = P_AproxDistance(sonic->momx, sonic->momy); fixed_t bmom = P_AproxDistance(tails->momx, tails->momy); - fixed_t followmax = 128 * 8 * scale; // Max follow distance before AI begins to enter "panic" state + fixed_t followmax = 128 * 8 * scale; // Max follow distance before AI begins to enter catchup state fixed_t followthres = 92 * scale; // Distance that AI will try to reach fixed_t followmin = 32 * scale; fixed_t comfortheight = 96 * scale; fixed_t touchdist = 24 * scale; boolean stalled = (bmom < scale >> 1) && dist > followthres; // Helps to see if the AI is having trouble catching up boolean samepos = (sonic->x == tails->x && sonic->y == tails->y); - + boolean blocked = bot->blocked; + if (!samepos) ang = R_PointToAngle2(tails->x, tails->y, sonic->x, sonic->y); - // We can't follow Sonic if he's not around! - if (!sonic || sonic->health <= 0) - return; - // Lua can handle it! if (LUAh_BotAI(sonic, tails, cmd)) return; + // We can't follow Sonic if he's not around! + if (!sonic || sonic->health <= 0) + { + mem->thinkstate = AI_STANDBY; + return; + } + else if (mem->thinkstate == AI_STANDBY) + mem->thinkstate = AI_FOLLOW; + if (tails->player->powers[pw_carry] == CR_MACESPIN || tails->player->powers[pw_carry] == CR_GENERIC) { boolean isrelevant = (sonic->player->powers[pw_carry] == CR_MACESPIN || sonic->player->powers[pw_carry] == CR_GENERIC); - dist = P_AproxDistance(tails->x-sonic->x, tails->y-sonic->y); + //dist = P_AproxDistance(tails->x-sonic->x, tails->y-sonic->y); //! This is totally redundant. if (sonic->player->cmd.buttons & BT_JUMP && (sonic->player->pflags & PF_JUMPED) && isrelevant) cmd->buttons |= BT_JUMP; if (isrelevant) @@ -103,56 +124,57 @@ static void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd) followmin = 0; followthres = 16*scale; followmax >>= 1; - thinkfly = false; + if (mem->thinkstate == AI_THINKFLY) + mem->thinkstate = AI_FOLLOW; } - // Check anxiety - if (spinmode) + // Update catchup_tics + if (mem->thinkstate == AI_SPINFOLLOW) { - anxiety = 0; - panic = false; + mem-> catchup_tics = 0; } else if (dist > followmax || zdist > comfortheight || stalled) { - anxiety = min(anxiety + 2, 70); - if (anxiety >= 70) - panic = true; + mem-> catchup_tics = min(mem-> catchup_tics + 2, 70); + if (mem-> catchup_tics >= 70) + mem->thinkstate = AI_CATCHUP; } else { - anxiety = max(anxiety - 1, 0); - panic = false; + mem-> catchup_tics = max(mem-> catchup_tics - 1, 0); + if (mem->thinkstate == AI_CATCHUP) + mem->thinkstate = AI_FOLLOW; } // Orientation + // cmd->angleturn won't be relative to player angle, since we're not going through G_BuildTiccmd. if (bot->pflags & (PF_SPINNING|PF_STARTDASH)) { - cmd->angleturn = (sonic->angle - tails->angle) >> 16; // NOT FRACBITS DAMNIT + cmd->angleturn = (sonic->angle) >> 16; // NOT FRACBITS DAMNIT } - else if (flymode == 2) + else if (mem->thinkstate == AI_FLYCARRY) { - cmd->angleturn = sonic->player->cmd.angleturn - (tails->angle >> 16); + cmd->angleturn = sonic->player->cmd.angleturn; } else { - cmd->angleturn = (ang - tails->angle) >> 16; // NOT FRACBITS DAMNIT + cmd->angleturn = (ang) >> 16; // NOT FRACBITS DAMNIT } // ******** // FLY MODE - // spinmode check - if (spinmode || player->exiting) - thinkfly = false; + // exiting check + if (player->exiting && mem->thinkstate == AI_THINKFLY) + mem->thinkstate = AI_FOLLOW; else { // Activate co-op flight - if (thinkfly && player->pflags & PF_JUMPED) + if (mem->thinkstate == AI_THINKFLY && player->pflags & PF_JUMPED) { if (!jump_last) { jump = true; - flymode = 1; - thinkfly = false; + mem->thinkstate = AI_FLYSTANDBY; bot->pflags |= PF_CANCARRY; } } @@ -165,20 +187,19 @@ static void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd) && P_IsObjectOnGround(sonic) && P_IsObjectOnGround(tails) && !(player->pflags & PF_STASIS) && bot->charability == CA_FLY) - thinkfly = true; - else - thinkfly = false; + mem->thinkstate = AI_THINKFLY; + else if (mem->thinkstate == AI_THINKFLY) + mem->thinkstate = AI_FOLLOW; // Set carried state if (player->powers[pw_carry] == CR_PLAYER && sonic->tracer == tails) { - flymode = 2; + mem->thinkstate = AI_FLYCARRY; } // Ready for takeoff - if (flymode == 1) + if (mem->thinkstate == AI_FLYSTANDBY) { - thinkfly = false; if (zdist < -64*scale || (flip * tails->momz) > scale) // Make sure we're not too high up spin = true; else if (!jump_last) @@ -186,10 +207,10 @@ static void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd) // Abort if the player moves away or spins if (dist > followthres || player->dashspeed) - flymode = 0; + mem->thinkstate = AI_FOLLOW; } // Read player inputs while carrying - else if (flymode == 2) + else if (mem->thinkstate == AI_FLYCARRY) { cmd->forwardmove = pcmd->forwardmove; cmd->sidemove = pcmd->sidemove; @@ -203,19 +224,19 @@ static void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd) // End flymode if (player->powers[pw_carry] != CR_PLAYER) { - flymode = 0; + mem->thinkstate = AI_FOLLOW; } } } - if (flymode && P_IsObjectOnGround(tails) && !(pcmd->buttons & BT_JUMP)) - flymode = 0; + if (P_IsObjectOnGround(tails) && !(pcmd->buttons & BT_JUMP) && (mem->thinkstate == AI_FLYSTANDBY || mem->thinkstate == AI_FLYCARRY)) + mem->thinkstate = AI_FOLLOW; // ******** // SPINNING - if (panic || flymode || !(player->pflags & PF_SPINNING) || (player->pflags & PF_JUMPED)) - spinmode = false; - else + if (!(player->pflags & (PF_SPINNING|PF_STARTDASH)) && mem->thinkstate == AI_SPINFOLLOW) + mem->thinkstate = AI_FOLLOW; + else if (mem->thinkstate == AI_FOLLOW || mem->thinkstate == AI_SPINFOLLOW) { if (!_2d) { @@ -224,21 +245,21 @@ static void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd) { if (dist < followthres && dist > touchdist) // Do positioning { - cmd->angleturn = (ang - tails->angle) >> 16; // NOT FRACBITS DAMNIT + cmd->angleturn = (ang) >> 16; // NOT FRACBITS DAMNIT cmd->forwardmove = 50; - spinmode = true; + mem->thinkstate = AI_SPINFOLLOW; } else if (dist < touchdist) { if (!bmom && (!(bot->pflags & PF_SPINNING) || (bot->dashspeed && bot->pflags & PF_SPINNING))) { - cmd->angleturn = (sonic->angle - tails->angle) >> 16; // NOT FRACBITS DAMNIT + cmd->angleturn = (sonic->angle) >> 16; // NOT FRACBITS DAMNIT spin = true; } - spinmode = true; + mem->thinkstate = AI_SPINFOLLOW; } else - spinmode = false; + mem->thinkstate = AI_FOLLOW; } // Spin else if (player->dashspeed == bot->dashspeed && player->pflags & PF_SPINNING) @@ -246,12 +267,12 @@ static void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd) if (bot->pflags & PF_SPINNING || !spin_last) { spin = true; - cmd->angleturn = (sonic->angle - tails->angle) >> 16; // NOT FRACBITS DAMNIT + cmd->angleturn = (sonic->angle) >> 16; // NOT FRACBITS DAMNIT cmd->forwardmove = MAXPLMOVE; - spinmode = true; + mem->thinkstate = AI_SPINFOLLOW; } else - spinmode = false; + mem->thinkstate = AI_FOLLOW; } } // 2D mode @@ -261,17 +282,19 @@ static void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd) && ((bot->pflags & PF_SPINNING) || !spin_last)) { spin = true; - spinmode = true; + mem->thinkstate = AI_SPINFOLLOW; } + else + mem->thinkstate = AI_FOLLOW; } } // ******** // FOLLOW - if (!(flymode || spinmode)) + if (mem->thinkstate == AI_FOLLOW || mem->thinkstate == AI_CATCHUP) { // Too far - if (panic || dist > followthres) + if (mem->thinkstate == AI_CATCHUP || dist > followthres) { if (!_2d) cmd->forwardmove = MAXPLMOVE; @@ -281,7 +304,7 @@ static void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd) cmd->sidemove = -MAXPLMOVE; } // Within threshold - else if (!panic && dist > followmin && abs(zdist) < 192*scale) + else if (dist > followmin && abs(zdist) < 192*scale) { if (!_2d) cmd->forwardmove = FixedHypot(pcmd->forwardmove, pcmd->sidemove); @@ -292,7 +315,7 @@ static void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd) else if (dist < followmin) { // Copy inputs - cmd->angleturn = (sonic->angle - tails->angle) >> 16; // NOT FRACBITS DAMNIT + cmd->angleturn = (sonic->angle) >> 16; // NOT FRACBITS DAMNIT bot->drawangle = ang; cmd->forwardmove = 8 * pcmd->forwardmove / 10; cmd->sidemove = 8 * pcmd->sidemove / 10; @@ -301,7 +324,7 @@ static void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd) // ******** // JUMP - if (!(flymode || spinmode)) + if (mem->thinkstate == AI_FOLLOW || mem->thinkstate == AI_CATCHUP || (mem->thinkstate == AI_SPINFOLLOW && player->pflags & PF_JUMPED)) { // Flying catch-up if (bot->pflags & PF_THOKKED) @@ -319,31 +342,30 @@ static void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd) // Start jump else if (!jump_last && !(bot->pflags & PF_JUMPED) //&& !(player->pflags & PF_SPINNING) && ((zdist > 32*scale && player->pflags & PF_JUMPED) // Following - || (zdist > 64*scale && panic) // Vertical catch-up - || (stalled && anxiety > 20 && bot->powers[pw_carry] == CR_NONE) + || (zdist > 64*scale && mem->thinkstate == AI_CATCHUP) // Vertical catch-up + || (stalled && mem-> catchup_tics > 20 && bot->powers[pw_carry] == CR_NONE) //|| (bmom < scale>>3 && dist > followthres && !(bot->powers[pw_carry])) // Stopped & not in carry state || (bot->pflags & PF_SPINNING && !(bot->pflags & PF_JUMPED)))) // Spinning jump = true; // Hold jump - else if (bot->pflags & PF_JUMPED && jump_last && tails->momz*flip > 0 && (zdist > 0 || panic)) + else if (bot->pflags & PF_JUMPED && jump_last && tails->momz*flip > 0 && (zdist > 0 || mem->thinkstate == AI_CATCHUP)) jump = true; // Start flying - else if (bot->pflags & PF_JUMPED && panic && !jump_last && bot->charability == CA_FLY) + else if (bot->pflags & PF_JUMPED && mem->thinkstate == AI_CATCHUP && !jump_last && bot->charability == CA_FLY) jump = true; } // ******** // HISTORY - jump_last = jump; - spin_last = spin; + //jump_last = jump; + //spin_last = spin; // Turn the virtual keypresses into ticcmd_t. B_KeysToTiccmd(tails, cmd, forward, backward, left, right, false, false, jump, spin); // Update our status - lastForward = forward; - lastBlocked = blocked; - blocked = false; + mem->lastForward = forward; + mem->lastBlocked = blocked; } void B_BuildTiccmd(player_t *player, ticcmd_t *cmd) @@ -362,32 +384,31 @@ void B_BuildTiccmd(player_t *player, ticcmd_t *cmd) // Bot AI isn't programmed in analog. CV_SetValue(&cv_analog[1], false); - // Bot cmd functions and hooks are not currently netplay compatible - // Necessary failsafe, as a bot in the P2 position in a netgame can inherit - // the last input from a hook triggered in splitscreen or SP. - if (netgame) - return; - // Let Lua scripts build ticcmds if (LUAh_BotTiccmd(player, cmd)) return; - // We don't have any main character AI, sorry. D: - if (player-players == consoleplayer) + // Make sure we have a valid main character to follow + B_UpdateBotleader(player); + if (!player->botleader) return; - // Basic Tails AI - B_BuildTailsTiccmd(players[consoleplayer].mo, player->mo, cmd); + // Single Player Tails AI + //B_BuildTailsTiccmd(players[consoleplayer].mo, player->mo, cmd); + B_BuildTailsTiccmd(player->botleader->mo, player->mo, cmd); } void B_KeysToTiccmd(mobj_t *mo, ticcmd_t *cmd, boolean forward, boolean backward, boolean left, boolean right, boolean strafeleft, boolean straferight, boolean jump, boolean spin) { + player_t *player = mo->player; // don't try to do stuff if your sonic is in a minecart or something - if (players[consoleplayer].powers[pw_carry] && players[consoleplayer].powers[pw_carry] != CR_PLAYER) + //if (players[consoleplayer].powers[pw_carry] && players[consoleplayer].powers[pw_carry] != CR_PLAYER) + //!!! + if (&player->botleader && player->botleader->powers[pw_carry] && player->botleader->powers[pw_carry] != CR_PLAYER) return; // Turn the virtual keypresses into ticcmd_t. if (twodlevel || mo->flags2 & MF2_TWOD) { - if (players[consoleplayer].climbing + if (player->botleader->climbing || mo->player->pflags & PF_GLIDING) { // Don't mess with bot inputs during these unhandled movement conditions. // The normal AI doesn't use abilities, so custom AI should be sending us exactly what it wants anyway. @@ -426,10 +447,10 @@ void B_KeysToTiccmd(mobj_t *mo, ticcmd_t *cmd, boolean forward, boolean backward cmd->forwardmove += MAXPLMOVE<>16; if (backward) cmd->forwardmove -= MAXPLMOVE<>16; - if (left) + if (left) cmd->angleturn += 1280; if (right) - cmd->angleturn -= 1280; + cmd->angleturn -= 1280; if (strafeleft) cmd->sidemove -= MAXPLMOVE<>16; if (straferight) @@ -453,14 +474,19 @@ void B_KeysToTiccmd(mobj_t *mo, ticcmd_t *cmd, boolean forward, boolean backward void B_MoveBlocked(player_t *player) { (void)player; - blocked = true; + player->blocked = true; } boolean B_CheckRespawn(player_t *player) { - mobj_t *sonic = players[consoleplayer].mo; + mobj_t *sonic; mobj_t *tails = player->mo; + //We don't have a main player to spawn to! + if (!player->botleader) + return false; + + sonic = player->botleader->mo; // We can't follow Sonic if he's not around! if (!sonic || sonic->health <= 0) return false; @@ -511,15 +537,19 @@ void B_RespawnBot(INT32 playernum) { player_t *player = &players[playernum]; fixed_t x,y,z; - mobj_t *sonic = players[consoleplayer].mo; + mobj_t *sonic; mobj_t *tails; + if (!player->botleader) + return; + + sonic = player->botleader->mo; if (!sonic || sonic->health <= 0) return; - B_ResetAI(); + B_ResetAI(&player->botmem); - player->bot = 1; + player->bot = BOT_2PAI; P_SpawnPlayer(playernum); tails = player->mo; @@ -546,10 +576,7 @@ void B_RespawnBot(INT32 playernum) player->powers[pw_spacetime] = sonic->player->powers[pw_spacetime]; player->powers[pw_gravityboots] = sonic->player->powers[pw_gravityboots]; player->powers[pw_nocontrol] = sonic->player->powers[pw_nocontrol]; - player->acceleration = sonic->player->acceleration; - player->accelstart = sonic->player->accelstart; - player->thrustfactor = sonic->player->thrustfactor; - player->normalspeed = sonic->player->normalspeed; + //!!! Nuke the speed equivalencies player->pflags |= PF_AUTOBRAKE|(sonic->player->pflags & PF_DIRECTIONCHAR); P_TeleportMove(tails, x, y, z); @@ -567,11 +594,11 @@ void B_RespawnBot(INT32 playernum) void B_HandleFlightIndicator(player_t *player) { mobj_t *tails = player->mo; - + botmem_t *mem = &player->botmem; if (!tails) return; - if (thinkfly && player->bot == 1 && tails->health) + if (mem->thinkstate == AI_THINKFLY && player->bot == BOT_2PAI && tails->health) { if (!tails->hnext) { From 4e47f240adc21eab710b6c17673d6053539579eb Mon Sep 17 00:00:00 2001 From: Shane Ellis Date: Sat, 23 Jan 2021 10:30:07 -0500 Subject: [PATCH 242/644] Add new botstuffs --- src/d_player.h | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/src/d_player.h b/src/d_player.h index 2e7afed88..bb206c889 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -313,9 +313,43 @@ typedef enum RW_RAIL = 32 } ringweapons_t; +//Bot types +typedef enum +{ + BOT_NONE = 0, + BOT_2PAI, + BOT_2PHUMAN, + BOT_MPAI +} bottype_t; + +//AI states +typedef enum +{ + AI_STANDBY = 0, + AI_FOLLOW, + AI_CATCHUP, + AI_THINKFLY, + AI_FLYSTANDBY, + AI_FLYCARRY, + AI_SPINFOLLOW +} aistatetype_t; + + // ======================================================================== // PLAYER STRUCTURE // ======================================================================== + +//Bot memory struct +typedef struct botmem_s +{ + boolean lastForward; + boolean lastBlocked; + boolean blocked; + UINT8 catchup_tics; + UINT8 thinkstate; +} botmem_t; + +//Main struct typedef struct player_s { mobj_t *mo; @@ -526,7 +560,11 @@ typedef struct player_s boolean spectator; boolean outofcoop; UINT8 bot; - + struct player_s *botleader; + UINT16 lastbuttons; + botmem_t botmem; + boolean blocked; + tic_t jointime; // Timer when player joins game to change skin/color tic_t quittime; // Time elapsed since user disconnected, zero if connected #ifdef HWRENDER From 25bf4b54e2cccb666acb143aecaaa6f26993fc88 Mon Sep 17 00:00:00 2001 From: Shane Ellis Date: Sat, 23 Jan 2021 10:36:44 -0500 Subject: [PATCH 243/644] Restructured botticcmds into G_Ticker --- src/g_game.c | 88 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 54 insertions(+), 34 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 5e2b4e708..3d6fc52b7 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1087,7 +1087,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) boolean turnleft, turnright, strafelkey, straferkey, movefkey, movebkey, mouseaiming, analogjoystickmove, gamepadjoystickmove, thisjoyaiming; boolean strafeisturn; // Simple controls only player_t *player = &players[ssplayer == 2 ? secondarydisplayplayer : consoleplayer]; - camera_t *thiscam = ((ssplayer == 1 || player->bot == 2) ? &camera : &camera2); + camera_t *thiscam = ((ssplayer == 1 || player->bot == BOT_2PHUMAN) ? &camera : &camera2); angle_t *myangle = (ssplayer == 1 ? &localangle : &localangle2); INT32 *myaiming = (ssplayer == 1 ? &localaiming : &localaiming2); @@ -1560,23 +1560,14 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) cmd->forwardmove = (SINT8)(cmd->forwardmove + forward); cmd->sidemove = (SINT8)(cmd->sidemove + side); - if (player->bot == 1) { // Tailsbot for P2 - if (!player->powers[pw_tailsfly] && (cmd->forwardmove || cmd->sidemove || cmd->buttons)) - { - player->bot = 2; // A player-controlled bot. Returns to AI when it respawns. - CV_SetValue(&cv_analog[1], true); - } - else - { - G_CopyTiccmd(cmd, I_BaseTiccmd2(), 1); // empty, or external driver - B_BuildTiccmd(player, cmd); - } - B_HandleFlightIndicator(player); - } - else if (player->bot == 2) + //Note: Majority of botstuffs are handled in G_Ticker now. + if (player->bot == BOT_2PHUMAN) //Player-controlled bot + { + G_CopyTiccmd(cmd, I_BaseTiccmd2(), 1); // empty, or external driver // Fix offset angle for P2-controlled Tailsbot when P2's controls are set to non-Legacy cmd->angleturn = (INT16)((localangle - *myangle) >> 16); - + } + *myangle += (cmd->angleturn<<16); if (controlstyle == CS_LMAOGALOG) { @@ -2290,22 +2281,51 @@ void G_Ticker(boolean run) for (i = 0; i < MAXPLAYERS; i++) { if (playeringame[i]) - { + { //!!! INT16 received; + //Save last frame's button readings + players[i].lastbuttons = players[i].cmd.buttons; G_CopyTiccmd(&players[i].cmd, &netcmds[buf][i], 1); + //Bot ticcmd handling + //Yes, ordinarily this would be handled in G_BuildTiccmd... + //...however, bot players won't have a corresponding consoleplayer or splitscreen player 2 to send that information. + //Therefore, this has to be done after ticcmd sends are received. + if (players[i].bot == BOT_2PAI) { // Tailsbot for P2 + if (!players[i].powers[pw_tailsfly] && (players[i].cmd.forwardmove || players[i].cmd.sidemove || players[i].cmd.buttons)) + { + players[i].bot = BOT_2PHUMAN; // A player-controlled bot. Returns to AI when it respawns. + CV_SetValue(&cv_analog[1], true); + } + else + { + B_BuildTiccmd(&players[i], &players[i].cmd); + } + B_HandleFlightIndicator(&players[i]); + } + else if (players[i].bot == BOT_MPAI) { + B_BuildTiccmd(&players[i], &players[i].cmd); + } + + // Do angle adjustments. + if (players[i].bot == BOT_NONE || players[i].bot == BOT_2PHUMAN) + { + received = (players[i].cmd.angleturn & TICCMD_RECEIVED); + players[i].angleturn += players[i].cmd.angleturn - players[i].oldrelangleturn; + players[i].oldrelangleturn = players[i].cmd.angleturn; + if (P_ControlStyle(&players[i]) == CS_LMAOGALOG) + P_ForceLocalAngle(&players[i], players[i].angleturn << 16); + else + players[i].cmd.angleturn = players[i].angleturn; - received = (players[i].cmd.angleturn & TICCMD_RECEIVED); - - players[i].angleturn += players[i].cmd.angleturn - players[i].oldrelangleturn; - players[i].oldrelangleturn = players[i].cmd.angleturn; - if (P_ControlStyle(&players[i]) == CS_LMAOGALOG) - P_ForceLocalAngle(&players[i], players[i].angleturn << 16); - else - players[i].cmd.angleturn = players[i].angleturn; - - players[i].cmd.angleturn &= ~TICCMD_RECEIVED; - players[i].cmd.angleturn |= received; + players[i].cmd.angleturn &= ~TICCMD_RECEIVED; + players[i].cmd.angleturn |= received; + } + else // Less work is required if we're building a bot ticcmd. + { + players[i].angleturn = players[i].cmd.angleturn; + players[i].oldrelangleturn = players[i].cmd.angleturn; + } } } @@ -2627,8 +2647,8 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) p->totalring = totalring; p->mare = mare; - if (bot == 2) - p->bot = 1; // reset to AI-controlled + if (bot == BOT_2PHUMAN) + p->bot = BOT_2PAI; // reset to AI-controlled else p->bot = bot; p->pity = pity; @@ -2976,8 +2996,8 @@ void G_DoReborn(INT32 playernum) // Make sure objectplace is OFF when you first start the level! OP_ResetObjectplace(); - // Tailsbot - if (player->bot && player->bot != 3 && playernum != consoleplayer) + //! Tailsbot + if (player->bot == BOT_2PAI || player->bot == BOT_2PHUMAN) { // Bots respawn next to their master. mobj_t *oldmo = NULL; @@ -3198,7 +3218,7 @@ void G_AddPlayer(INT32 playernum) if (!playeringame[i]) continue; - if (players[i].bot) // ignore dumb, stupid tails + if (players[i].bot == BOT_2PAI || players[i].bot == BOT_2PHUMAN) // ignore dumb, stupid tails continue; countplayers++; @@ -3239,7 +3259,7 @@ boolean G_EnoughPlayersFinished(void) for (i = 0; i < MAXPLAYERS; i++) { - if (!playeringame[i] || players[i].spectator || players[i].bot) + if (!playeringame[i] || players[i].spectator || players[i].bot == BOT_2PAI || players[i].bot == BOT_2PHUMAN) continue; if (players[i].quittime > 30 * TICRATE) continue; From 1274b4651e6decce71a8b4627bb367377a483465 Mon Sep 17 00:00:00 2001 From: Shane Ellis Date: Sat, 23 Jan 2021 10:39:59 -0500 Subject: [PATCH 244/644] Added botstuffs to savestate --- src/p_saveg.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/p_saveg.c b/src/p_saveg.c index c1364e08f..d80495e5b 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -158,6 +158,18 @@ static void P_NetArchivePlayers(void) WRITEUINT32(save_p, players[i].dashmode); WRITEUINT32(save_p, players[i].skidtime); + ////////// + // Bots // + ////////// + WRITEUINT8(save_p, players[i].bot); + WRITEUINT8(save_p, players[i].botmem.lastForward); + WRITEUINT8(save_p, players[i].botmem.lastBlocked); + WRITEUINT8(save_p, players[i].botmem.catchup_tics); + WRITEUINT8(save_p, players[i].botmem.thinkstate); + + WRITEUINT8(save_p, players[i].blocked); + WRITEUINT16(save_p, players[i].lastbuttons); + //////////////////////////// // Conveyor Belt Movement // //////////////////////////// @@ -372,6 +384,19 @@ static void P_NetUnArchivePlayers(void) players[i].dashmode = READUINT32(save_p); // counter for dashmode ability players[i].skidtime = READUINT32(save_p); // Skid timer + ////////// + // Bots // + ////////// + players[i].bot = READUINT8(save_p); + + players[i].botmem.lastForward = READUINT8(save_p); + players[i].botmem.lastBlocked = READUINT8(save_p); + players[i].botmem.catchup_tics = READUINT8(save_p); + players[i].botmem.thinkstate = READUINT8(save_p); + + players[i].blocked = READUINT8(save_p); + players[i].lastbuttons = READUINT16(save_p); + //////////////////////////// // Conveyor Belt Movement // //////////////////////////// From 135032c2932afa6474b15b0859717fe1771a3dc7 Mon Sep 17 00:00:00 2001 From: Shane Ellis Date: Sat, 23 Jan 2021 10:58:34 -0500 Subject: [PATCH 245/644] Correction to implicit declaration of B_UpdateBotleader() --- src/lua_baselib.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 525ce89ec..b6adc0ccd 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -28,6 +28,7 @@ #include "console.h" #include "d_netcmd.h" // IsPlayerAdmin #include "m_menu.h" // Player Setup menu color stuff +#include "b_bot.h" // B_UpdateBotleader #include "lua_script.h" #include "lua_libs.h" From 0a60fe0b1db198d8ed9ead70bab43a4e7711810b Mon Sep 17 00:00:00 2001 From: CobaltBW Date: Sat, 23 Jan 2021 14:05:36 -0800 Subject: [PATCH 246/644] Almost forgot: player.blocked --- src/lua_playerlib.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 51eb4ac0c..8156c2ac1 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -374,6 +374,8 @@ static int player_get(lua_State *L) LUA_PushUserdata(L, plr->botleader, META_PLAYER); else if (fastcmp(field,"lastbuttons")) lua_pushinteger(L, plr->lastbuttons); + else if (fastcmp(field,"blocked")) + lua_pushboolean(L, plr->blocked); else if (fastcmp(field,"jointime")) lua_pushinteger(L, plr->jointime); else if (fastcmp(field,"quittime")) @@ -732,6 +734,8 @@ static int player_set(lua_State *L) } else if (fastcmp(field,"lastbuttons")) plr->lastbuttons = (UINT16)luaL_checkinteger(L, 3); + else if (fastcmp(field,"blocked")) + plr->blocked = (UINT8)luaL_checkinteger(L, 3); else if (fastcmp(field,"jointime")) plr->jointime = (tic_t)luaL_checkinteger(L, 3); else if (fastcmp(field,"quittime")) From 93ec472c7849fecb0fe53e99e7802904a2b7c1ba Mon Sep 17 00:00:00 2001 From: CobaltBW Date: Sat, 23 Jan 2021 14:49:20 -0800 Subject: [PATCH 247/644] Expose BOT_ to lua --- src/deh_tables.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/deh_tables.c b/src/deh_tables.c index 3039bf7de..cd6ceb3c6 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -5167,6 +5167,12 @@ struct int_const_s const INT_CONST[] = { {"GF_REDFLAG",GF_REDFLAG}, {"GF_BLUEFLAG",GF_BLUEFLAG}, + // Bot types + {"BOT_NONE",BOT_NONE}, + {"BOT_2PAI",BOT_2PAI}, + {"BOT_2PHUMAN",BOT_2PHUMAN}, + {"BOT_MPAI",BOT_MPAI}, + // Customisable sounds for Skins, from sounds.h {"SKSSPIN",SKSSPIN}, {"SKSPUTPUT",SKSPUTPUT}, From a2fce68f14fe8002394639ce1f8facf109f3ea3c Mon Sep 17 00:00:00 2001 From: CobaltBW Date: Sat, 23 Jan 2021 17:01:48 -0800 Subject: [PATCH 248/644] Specialized Lua function for bot removal --- src/d_clisrv.c | 18 +++++++----------- src/d_clisrv.h | 1 + src/lua_baselib.c | 35 ++++++++++++++++++++++++++++++++++- 3 files changed, 42 insertions(+), 12 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 4574e5a1c..691408b54 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2472,7 +2472,7 @@ void CL_ClearPlayer(INT32 playernum) // // Removes a player from the current game // -static void CL_RemovePlayer(INT32 playernum, kickreason_t reason) +void CL_RemovePlayer(INT32 playernum, kickreason_t reason) { // Sanity check: exceptional cases (i.e. c-fails) can cause multiple // kick commands to be issued for the same player. @@ -2815,22 +2815,18 @@ static void Command_Kick(void) return; } + if (!netgame) // Don't kick Tails in splitscreen! + { + CONS_Printf(M_GetText("This only works in a netgame.\n")); + return; + } + if (server || IsPlayerAdmin(consoleplayer)) { UINT8 buf[3 + MAX_REASONLENGTH]; UINT8 *p = buf; const SINT8 pn = nametonum(COM_Argv(1)); - // Unlike bans, kicks are used especially to remove bot players, so we'll - // need to run a more specific check which allows kicking offline, but - // not against splitscreen players. - if (splitscreen && (pn == 0 || pn == 1)) - { - CONS_Printf(M_GetText("Splitscreen players cannot be kicked.\n")); - return; - } - - if (pn == -1 || pn == 0) return; diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 3d67525da..adb611ecf 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -401,6 +401,7 @@ void CL_Reset(void); void CL_ClearPlayer(INT32 playernum); void CL_QueryServerList(msg_server_t *list); void CL_UpdateServerList(boolean internetsearch, INT32 room); +void CL_RemovePlayer(INT32 playernum, kickreason_t reason); // Is there a game running boolean Playing(void); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index b6adc0ccd..9aeabe1fc 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -29,6 +29,7 @@ #include "d_netcmd.h" // IsPlayerAdmin #include "m_menu.h" // Player Setup menu color stuff #include "b_bot.h" // B_UpdateBotleader +#include "d_clisrv.h" // CL_RemovePlayer #include "lua_script.h" #include "lua_libs.h" @@ -3463,7 +3464,7 @@ static int lib_gAddPlayer(lua_State *L) strcpy(player_names[newplayernum], luaL_checkstring(L, 3)); bot = luaL_optinteger(L, 4, 3); - newplayer->bot = (bot >= 0 && bot <= 3) ? bot : 3; + newplayer->bot = (bot >= BOT_NONE && bot <= BOT_MPAI) ? bot : BOT_MPAI; // If our bot is a 2P type, we'll need to set its leader so it can spawn if (newplayer->bot == BOT_2PAI || newplayer->bot == BOT_2PHUMAN) @@ -3487,6 +3488,37 @@ static int lib_gAddPlayer(lua_State *L) } +// Bot removing function +static int lib_gRemovePlayer(lua_State *L) +{ + UINT8 pnum = -1; + //const char *kickreason = luaL_checkstring(L, 2); + + if (!lua_isnoneornil(L, 1)) + pnum = luaL_checkinteger(L, 1); + if (&players[pnum]) + { + if (players[pnum].bot != BOT_NONE) + { +// CL_RemovePlayer(pnum, *kickreason); + CL_RemovePlayer(pnum, pnum); + if (netgame) + { + char kickmsg[256]; + + strcpy(kickmsg, M_GetText("\x82*Bot %s has been removed")); + strcpy(kickmsg, va(kickmsg, player_names[pnum], pnum)); + HU_AddChatText(kickmsg, false); + } + lua_pushboolean(L, true); + return 1; + } + } + lua_pushboolean(L, false); + return 1; +} + + static int Lcheckmapnumber (lua_State *L, int idx, const char *fun) { if (ISINLEVEL) @@ -4068,6 +4100,7 @@ static luaL_Reg lib[] = { // g_game {"G_AddGametype", lib_gAddGametype}, {"G_AddPlayer", lib_gAddPlayer}, + {"G_RemovePlayer", lib_gRemovePlayer}, {"G_BuildMapName",lib_gBuildMapName}, {"G_BuildMapTitle",lib_gBuildMapTitle}, {"G_FindMap",lib_gFindMap}, From ea6879b5c290811395a74c442924f2a200c491ce Mon Sep 17 00:00:00 2001 From: Shane Ellis Date: Sun, 24 Jan 2021 12:43:13 -0500 Subject: [PATCH 249/644] missed a couple spots --- src/p_enemy.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 637eba83f..d0e0cc9ee 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -743,8 +743,8 @@ boolean P_LookForPlayers(mobj_t *actor, boolean allaround, boolean tracer, fixed if (player->mo->health <= 0) continue; // dead - if (player->bot && player->bot != 3) - continue; // ignore bots + if (player->bot == BOT_2PAI || player->bot == BOT_2PHUMAN) + continue; // ignore followbots if (player->quittime) continue; // Ignore uncontrolled bodies @@ -3590,7 +3590,7 @@ void A_1upThinker(mobj_t *actor) for (i = 0; i < MAXPLAYERS; i++) { - if (!playeringame[i] || players[i].bot || players[i].spectator) + if (!playeringame[i] || players[i].bot == BOT_2PAI || players[i].bot == BOT_2PHUMAN || players[i].spectator) continue; if (!players[i].mo) From ca00e2d5086af7f6a5ba63a3caf82b74742680a1 Mon Sep 17 00:00:00 2001 From: Shane Ellis Date: Sun, 24 Jan 2021 12:46:03 -0500 Subject: [PATCH 250/644] correction to nights bot clause --- src/p_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index c631f49b2..f0cbb6f37 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -777,7 +777,7 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) UINT8 oldmare, oldmarelap, oldmarebonuslap; //! Bots can't be NiGHTSerized, silly!1 :P - if (player->bot == BOT_2PAI || player->bot || BOT_2PHUMAN) + if (player->bot == BOT_2PAI || player->bot == BOT_2PHUMAN) return; if (player->powers[pw_carry] != CR_NIGHTSMODE) From 5501d495c72d0cb8f2d82d4424e64d67a6a6a8ea Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Wed, 27 Jan 2021 17:48:57 -0300 Subject: [PATCH 251/644] OpenGL backend: Manage uploaded GPU textures with an internal list Indirectly fixes the game doing whatever after freeing a patch. This commit implements a FTextureInfo struct type, instead of it being a typedef to the GLMipmap_s struct type. --- src/f_finale.c | 44 ++++++++--------- src/hardware/hw_cache.c | 1 - src/hardware/hw_data.h | 19 ++++---- src/hardware/hw_defs.h | 11 ++++- src/hardware/hw_drv.h | 8 ++- src/hardware/r_opengl/r_opengl.c | 84 ++++++++++++++++++++++---------- src/sdl/hwsym_sdl.c | 1 - src/sdl/i_video.c | 1 - src/w_wad.c | 18 +------ src/win32/win_dll.c | 2 - src/z_zone.h | 3 +- 11 files changed, 106 insertions(+), 86 deletions(-) diff --git a/src/f_finale.c b/src/f_finale.c index 2232b669f..fdcfad279 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -2546,28 +2546,28 @@ static void F_UnloadAlacroixGraphics(SINT8 oldttscale) oldttscale--; // zero-based index for (i = 0; i < TTMAX_ALACROIX; i++) { - if(ttembl[oldttscale][i]) { Z_Free(ttembl[oldttscale][i]); ttembl[oldttscale][i] = 0; } - if(ttribb[oldttscale][i]) { Z_Free(ttribb[oldttscale][i]); ttribb[oldttscale][i] = 0; } - if(ttsont[oldttscale][i]) { Z_Free(ttsont[oldttscale][i]); ttsont[oldttscale][i] = 0; } - if(ttrobo[oldttscale][i]) { Z_Free(ttrobo[oldttscale][i]); ttrobo[oldttscale][i] = 0; } - if(tttwot[oldttscale][i]) { Z_Free(tttwot[oldttscale][i]); tttwot[oldttscale][i] = 0; } - if(ttrbtx[oldttscale][i]) { Z_Free(ttrbtx[oldttscale][i]); ttrbtx[oldttscale][i] = 0; } - if(ttsoib[oldttscale][i]) { Z_Free(ttsoib[oldttscale][i]); ttsoib[oldttscale][i] = 0; } - if(ttsoif[oldttscale][i]) { Z_Free(ttsoif[oldttscale][i]); ttsoif[oldttscale][i] = 0; } - if(ttsoba[oldttscale][i]) { Z_Free(ttsoba[oldttscale][i]); ttsoba[oldttscale][i] = 0; } - if(ttsobk[oldttscale][i]) { Z_Free(ttsobk[oldttscale][i]); ttsobk[oldttscale][i] = 0; } - if(ttsodh[oldttscale][i]) { Z_Free(ttsodh[oldttscale][i]); ttsodh[oldttscale][i] = 0; } - if(tttaib[oldttscale][i]) { Z_Free(tttaib[oldttscale][i]); tttaib[oldttscale][i] = 0; } - if(tttaif[oldttscale][i]) { Z_Free(tttaif[oldttscale][i]); tttaif[oldttscale][i] = 0; } - if(tttaba[oldttscale][i]) { Z_Free(tttaba[oldttscale][i]); tttaba[oldttscale][i] = 0; } - if(tttabk[oldttscale][i]) { Z_Free(tttabk[oldttscale][i]); tttabk[oldttscale][i] = 0; } - if(tttabt[oldttscale][i]) { Z_Free(tttabt[oldttscale][i]); tttabt[oldttscale][i] = 0; } - if(tttaft[oldttscale][i]) { Z_Free(tttaft[oldttscale][i]); tttaft[oldttscale][i] = 0; } - if(ttknib[oldttscale][i]) { Z_Free(ttknib[oldttscale][i]); ttknib[oldttscale][i] = 0; } - if(ttknif[oldttscale][i]) { Z_Free(ttknif[oldttscale][i]); ttknif[oldttscale][i] = 0; } - if(ttknba[oldttscale][i]) { Z_Free(ttknba[oldttscale][i]); ttknba[oldttscale][i] = 0; } - if(ttknbk[oldttscale][i]) { Z_Free(ttknbk[oldttscale][i]); ttknbk[oldttscale][i] = 0; } - if(ttkndh[oldttscale][i]) { Z_Free(ttkndh[oldttscale][i]); ttkndh[oldttscale][i] = 0; } + if(ttembl[oldttscale][i]) { Patch_Free(ttembl[oldttscale][i]); ttembl[oldttscale][i] = 0; } + if(ttribb[oldttscale][i]) { Patch_Free(ttribb[oldttscale][i]); ttribb[oldttscale][i] = 0; } + if(ttsont[oldttscale][i]) { Patch_Free(ttsont[oldttscale][i]); ttsont[oldttscale][i] = 0; } + if(ttrobo[oldttscale][i]) { Patch_Free(ttrobo[oldttscale][i]); ttrobo[oldttscale][i] = 0; } + if(tttwot[oldttscale][i]) { Patch_Free(tttwot[oldttscale][i]); tttwot[oldttscale][i] = 0; } + if(ttrbtx[oldttscale][i]) { Patch_Free(ttrbtx[oldttscale][i]); ttrbtx[oldttscale][i] = 0; } + if(ttsoib[oldttscale][i]) { Patch_Free(ttsoib[oldttscale][i]); ttsoib[oldttscale][i] = 0; } + if(ttsoif[oldttscale][i]) { Patch_Free(ttsoif[oldttscale][i]); ttsoif[oldttscale][i] = 0; } + if(ttsoba[oldttscale][i]) { Patch_Free(ttsoba[oldttscale][i]); ttsoba[oldttscale][i] = 0; } + if(ttsobk[oldttscale][i]) { Patch_Free(ttsobk[oldttscale][i]); ttsobk[oldttscale][i] = 0; } + if(ttsodh[oldttscale][i]) { Patch_Free(ttsodh[oldttscale][i]); ttsodh[oldttscale][i] = 0; } + if(tttaib[oldttscale][i]) { Patch_Free(tttaib[oldttscale][i]); tttaib[oldttscale][i] = 0; } + if(tttaif[oldttscale][i]) { Patch_Free(tttaif[oldttscale][i]); tttaif[oldttscale][i] = 0; } + if(tttaba[oldttscale][i]) { Patch_Free(tttaba[oldttscale][i]); tttaba[oldttscale][i] = 0; } + if(tttabk[oldttscale][i]) { Patch_Free(tttabk[oldttscale][i]); tttabk[oldttscale][i] = 0; } + if(tttabt[oldttscale][i]) { Patch_Free(tttabt[oldttscale][i]); tttabt[oldttscale][i] = 0; } + if(tttaft[oldttscale][i]) { Patch_Free(tttaft[oldttscale][i]); tttaft[oldttscale][i] = 0; } + if(ttknib[oldttscale][i]) { Patch_Free(ttknib[oldttscale][i]); ttknib[oldttscale][i] = 0; } + if(ttknif[oldttscale][i]) { Patch_Free(ttknif[oldttscale][i]); ttknif[oldttscale][i] = 0; } + if(ttknba[oldttscale][i]) { Patch_Free(ttknba[oldttscale][i]); ttknba[oldttscale][i] = 0; } + if(ttknbk[oldttscale][i]) { Patch_Free(ttknbk[oldttscale][i]); ttknbk[oldttscale][i] = 0; } + if(ttkndh[oldttscale][i]) { Patch_Free(ttkndh[oldttscale][i]); ttkndh[oldttscale][i] = 0; } } ttloaded[oldttscale] = false; } diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 37e9f690f..83a4e2e03 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -1091,7 +1091,6 @@ void HWR_UnlockCachedPatch(GLPatch_t *gpatch) return; Z_ChangeTag(gpatch->mipmap->data, PU_HWRCACHE_UNLOCKED); - Z_ChangeTag(gpatch, PU_HWRPATCHINFO_UNLOCKED); } static const INT32 picmode2GR[] = diff --git a/src/hardware/hw_data.h b/src/hardware/hw_data.h index 11e41b18a..ce6527666 100644 --- a/src/hardware/hw_data.h +++ b/src/hardware/hw_data.h @@ -48,18 +48,19 @@ struct GLColormap_s typedef struct GLColormap_s GLColormap_t; -// data holds the address of the graphics data cached in heap memory -// NULL if the texture is not in Doom heap cache. +// Texture information (misleadingly named "mipmap" all over the code.) +// The *data pointer holds the address of the graphics data cached in heap memory. +// NULL if the texture is not in SRB2's heap cache. struct GLMipmap_s { - // for TexDownloadMipMap + // for UpdateTexture GLTextureFormat_t format; void *data; UINT32 flags; UINT16 height; UINT16 width; - UINT32 downloaded; // The GPU has this texture. + UINT32 downloaded; // The GPU has this texture. struct GLMipmap_s *nextcolormap; struct GLColormap_s *colormap; @@ -70,22 +71,22 @@ typedef struct GLMipmap_s GLMipmap_t; // -// Doom texture info, as cached for hardware rendering +// Level textures, as cached for hardware rendering. // struct GLMapTexture_s { GLMipmap_t mipmap; - float scaleX; //used for scaling textures on walls + float scaleX; // Used for scaling textures on walls float scaleY; }; typedef struct GLMapTexture_s GLMapTexture_t; -// a cached patch as converted to hardware format +// Patch information for the hardware renderer. struct GLPatch_s { - float max_s,max_t; - GLMipmap_t *mipmap; + GLMipmap_t *mipmap; // Texture data. Allocated whenever the patch is. + float max_s, max_t; }; typedef struct GLPatch_s GLPatch_t; diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index a782762a3..bd6afc74f 100644 --- a/src/hardware/hw_defs.h +++ b/src/hardware/hw_defs.h @@ -255,7 +255,16 @@ enum ETextureFlags TF_TRANSPARENT = 0x00000040, // texture with some alpha == 0 }; -typedef struct GLMipmap_s FTextureInfo; +struct FTextureInfo +{ + UINT32 width, height; + UINT32 downloaded; + UINT32 format; + + struct GLMipmap_s *texture; + struct FTextureInfo *prev, *next; +}; +typedef struct FTextureInfo FTextureInfo; // jimita 14032019 struct FLightInfo diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h index 5a2e0e44e..da4ee8614 100644 --- a/src/hardware/hw_drv.h +++ b/src/hardware/hw_drv.h @@ -40,13 +40,12 @@ EXPORT void HWRAPI(DrawIndexedTriangles) (FSurfaceInfo *pSurf, FOutVector *pOutV EXPORT void HWRAPI(RenderSkyDome) (gl_sky_t *sky); EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags); EXPORT void HWRAPI(ClearBuffer) (FBOOLEAN ColorMask, FBOOLEAN DepthMask, FRGBAFloat *ClearColor); -EXPORT void HWRAPI(SetTexture) (FTextureInfo *TexInfo); -EXPORT void HWRAPI(UpdateTexture) (FTextureInfo *TexInfo); -EXPORT void HWRAPI(DeleteTexture) (FTextureInfo *TexInfo); +EXPORT void HWRAPI(SetTexture) (GLMipmap_t *TexInfo); +EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *TexInfo); +EXPORT void HWRAPI(DeleteTexture) (GLMipmap_t *TexInfo); EXPORT void HWRAPI(ReadRect) (INT32 x, INT32 y, INT32 width, INT32 height, INT32 dst_stride, UINT16 *dst_data); EXPORT void HWRAPI(GClipRect) (INT32 minx, INT32 miny, INT32 maxx, INT32 maxy, float nearclip); EXPORT void HWRAPI(ClearMipMapCache) (void); -EXPORT void HWRAPI(ClearCacheList) (void); //Hurdler: added for backward compatibility EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value); @@ -101,7 +100,6 @@ struct hwdriver_s ReadRect pfnReadRect; GClipRect pfnGClipRect; ClearMipMapCache pfnClearMipMapCache; - ClearCacheList pfnClearCacheList; SetSpecialState pfnSetSpecialState;//Hurdler: added for backward compatibility DrawModel pfnDrawModel; CreateModelVBOs pfnCreateModelVBOs; diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 8cd948eea..2568a7d08 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -58,8 +58,9 @@ static GLuint tex_downloaded = 0; static GLfloat fov = 90.0f; static FBITFIELD CurrentPolyFlags; -static FTextureInfo *gl_cachetail = NULL; -static FTextureInfo *gl_cachehead = NULL; +// Linked list of all textures. +static FTextureInfo *TexCacheTail = NULL; +static FTextureInfo *TexCacheHead = NULL; RGBA_t myPaletteData[256]; GLint screen_width = 0; // used by Draw2DLine() @@ -1287,10 +1288,30 @@ void SetStates(void) // -----------------+ // DeleteTexture : Deletes a texture from the GPU and frees its data // -----------------+ -EXPORT void HWRAPI(DeleteTexture) (FTextureInfo *pTexInfo) +EXPORT void HWRAPI(DeleteTexture) (GLMipmap_t *pTexInfo) { - if (pTexInfo->downloaded) + FTextureInfo *head = TexCacheHead; + + if (!pTexInfo) + return; + else if (pTexInfo->downloaded) pglDeleteTextures(1, (GLuint *)&pTexInfo->downloaded); + + while (head) + { + if (head->downloaded == pTexInfo->downloaded) + { + if (head->next) + head->next->prev = head->prev; + if (head->prev) + head->prev->next = head->next; + free(head); + break; + } + + head = head->next; + } + pTexInfo->downloaded = 0; } @@ -1303,26 +1324,29 @@ void Flush(void) { //GL_DBG_Printf ("HWR_Flush()\n"); - while (gl_cachehead) + while (TexCacheHead) { - DeleteTexture(gl_cachehead); - gl_cachehead = gl_cachehead->nextmipmap; + FTextureInfo *pTexInfo = TexCacheHead; + GLMipmap_t *texture = pTexInfo->texture; + + if (pTexInfo->downloaded) + { + pglDeleteTextures(1, (GLuint *)&pTexInfo->downloaded); + pTexInfo->downloaded = 0; + } + + if (texture) + texture->downloaded = 0; + + TexCacheHead = pTexInfo->next; + free(pTexInfo); } - ClearCacheList(); //Hurdler: well, gl_cachehead is already NULL + TexCacheTail = TexCacheHead = NULL; //Hurdler: well, TexCacheHead is already NULL tex_downloaded = 0; } -// -----------------+ -// ClearCacheList : Clears the texture cache tail and head -// -----------------+ -EXPORT void HWRAPI(ClearCacheList) (void) -{ - gl_cachetail = gl_cachehead = NULL; -} - - // -----------------+ // isExtAvailable : Look if an OpenGL extension is available // Returns : true if extension available @@ -1718,7 +1742,7 @@ EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags) // -----------------+ // UpdateTexture : Updates the texture data. // -----------------+ -EXPORT void HWRAPI(UpdateTexture) (FTextureInfo *pTexInfo) +EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *pTexInfo) { // Download a mipmap boolean updatemipmap = true; @@ -1920,7 +1944,7 @@ EXPORT void HWRAPI(UpdateTexture) (FTextureInfo *pTexInfo) // -----------------+ // SetTexture : The mipmap becomes the current texture source // -----------------+ -EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo) +EXPORT void HWRAPI(SetTexture) (GLMipmap_t *pTexInfo) { if (!pTexInfo) { @@ -1937,17 +1961,25 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo) } else { + FTextureInfo *newTex = calloc(1, sizeof (*newTex)); + UpdateTexture(pTexInfo); - pTexInfo->nextmipmap = NULL; + + newTex->texture = pTexInfo; + newTex->downloaded = (UINT32)pTexInfo->downloaded; + newTex->width = (UINT32)pTexInfo->width; + newTex->height = (UINT32)pTexInfo->height; + newTex->format = (UINT32)pTexInfo->format; // insertion at the tail - if (gl_cachetail) + if (TexCacheTail) { - gl_cachetail->nextmipmap = pTexInfo; - gl_cachetail = pTexInfo; + newTex->prev = TexCacheTail; + TexCacheTail->next = newTex; + TexCacheTail = newTex; } else // initialization of the linked list - gl_cachetail = gl_cachehead = pTexInfo; + TexCacheTail = TexCacheHead = newTex; } } @@ -3011,7 +3043,7 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform) EXPORT INT32 HWRAPI(GetTextureUsed) (void) { - FTextureInfo *tmp = gl_cachehead; + FTextureInfo *tmp = TexCacheHead; INT32 res = 0; while (tmp) @@ -3028,7 +3060,7 @@ EXPORT INT32 HWRAPI(GetTextureUsed) (void) // Add it up! res += tmp->height*tmp->width*bpp; - tmp = tmp->nextmipmap; + tmp = tmp->next; } return res; diff --git a/src/sdl/hwsym_sdl.c b/src/sdl/hwsym_sdl.c index 398508662..96e3d7d69 100644 --- a/src/sdl/hwsym_sdl.c +++ b/src/sdl/hwsym_sdl.c @@ -90,7 +90,6 @@ void *hwSym(const char *funcName,void *handle) GETFUNC(ReadRect); GETFUNC(GClipRect); GETFUNC(ClearMipMapCache); - GETFUNC(ClearCacheList); GETFUNC(SetSpecialState); GETFUNC(GetTextureUsed); GETFUNC(DrawModel); diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 5ebff8700..0ed10463f 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1862,7 +1862,6 @@ void VID_StartupOpenGL(void) HWD.pfnReadRect = hwSym("ReadRect",NULL); HWD.pfnGClipRect = hwSym("GClipRect",NULL); HWD.pfnClearMipMapCache = hwSym("ClearMipMapCache",NULL); - HWD.pfnClearCacheList = hwSym("ClearCacheList",NULL); HWD.pfnSetSpecialState = hwSym("SetSpecialState",NULL); HWD.pfnSetPalette = hwSym("SetPalette",NULL); HWD.pfnGetTextureUsed = hwSym("GetTextureUsed",NULL); diff --git a/src/w_wad.c b/src/w_wad.c index 6566800c0..2cbcdecb5 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -1682,26 +1682,12 @@ void *W_CacheSoftwarePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag) // read the lump in full W_ReadLumpHeaderPwad(wad, lump, lumpdata, 0, 0); + ptr = lumpdata; #ifndef NO_PNG_LUMPS - // lump is a png so convert it if (Picture_IsLumpPNG((UINT8 *)lumpdata, len)) - { - size_t newlen; - void *converted = Picture_PNGConvert((UINT8 *)lumpdata, PICFMT_DOOMPATCH, NULL, NULL, NULL, NULL, len, &newlen, 0); - ptr = Z_Malloc(newlen, PU_STATIC, NULL); - M_Memcpy(ptr, converted, newlen); - Z_Free(converted); - len = newlen; - } - else // just copy it into the patch cache + ptr = Picture_PNGConvert((UINT8 *)lumpdata, PICFMT_DOOMPATCH, NULL, NULL, NULL, NULL, len, &len, 0); #endif - { - ptr = Z_Malloc(len, PU_STATIC, NULL); - M_Memcpy(ptr, lumpdata, len); - } - - Z_Free(lumpdata); dest = Z_Calloc(sizeof(patch_t), tag, &lumpcache[lump]); Patch_Create(ptr, len, dest); diff --git a/src/win32/win_dll.c b/src/win32/win_dll.c index d942d8cd4..4743cec34 100644 --- a/src/win32/win_dll.c +++ b/src/win32/win_dll.c @@ -111,7 +111,6 @@ static loadfunc_t hwdFuncTable[] = { {"ReadRect@24", &hwdriver.pfnReadRect}, {"GClipRect@20", &hwdriver.pfnGClipRect}, {"ClearMipMapCache@0", &hwdriver.pfnClearMipMapCache}, - {"ClearCacheList@0", &hwdriver.pfnClearCacheList}, {"SetSpecialState@8", &hwdriver.pfnSetSpecialState}, {"DrawModel@16", &hwdriver.pfnDrawModel}, {"SetTransform@4", &hwdriver.pfnSetTransform}, @@ -145,7 +144,6 @@ static loadfunc_t hwdFuncTable[] = { {"ReadRect", &hwdriver.pfnReadRect}, {"GClipRect", &hwdriver.pfnGClipRect}, {"ClearMipMapCache", &hwdriver.pfnClearMipMapCache}, - {"ClearCacheList", &hwdriver.pfnClearCacheList}, {"SetSpecialState", &hwdriver.pfnSetSpecialState}, {"DrawModel", &hwdriver.pfnDrawModel}, {"SetTransform", &hwdriver.pfnSetTransform}, diff --git a/src/z_zone.h b/src/z_zone.h index e80a45e7f..7b58be8f3 100644 --- a/src/z_zone.h +++ b/src/z_zone.h @@ -68,8 +68,7 @@ enum PU_HWRCACHE_UNLOCKED = 102, // 'unlocked' PU_HWRCACHE memory: // 'second-level' cache for graphics // stored in hardware format and downloaded as needed - PU_HWRPATCHINFO_UNLOCKED = 103, // 'unlocked' PU_HWRPATCHINFO memory - PU_HWRMODELTEXTURE_UNLOCKED = 104, // 'unlocked' PU_HWRMODELTEXTURE memory + PU_HWRMODELTEXTURE_UNLOCKED = 103, // 'unlocked' PU_HWRMODELTEXTURE memory }; // From d4044a4f82bd9862a848a1e3f49a62f35f8f8b71 Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Wed, 27 Jan 2021 18:54:33 -0300 Subject: [PATCH 252/644] Add PF_ColorMapped Not all surfaces have tint and fade colors. Checking for a specific surface flag, that tells the backend those colors are present, avoids uninitialized reads. --- src/hardware/hw_defs.h | 10 +-- src/hardware/hw_drv.h | 1 - src/hardware/hw_main.c | 129 ++++++++++++++++++++++--------- src/hardware/r_opengl/r_opengl.c | 42 +++++----- 4 files changed, 119 insertions(+), 63 deletions(-) diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index a782762a3..eb4ddf572 100644 --- a/src/hardware/hw_defs.h +++ b/src/hardware/hw_defs.h @@ -230,14 +230,15 @@ enum EPolyFlags PF_NoDepthTest = 0x00000200, // Disables the depth test mode PF_Invisible = 0x00000400, // Disables write to color buffer PF_Decal = 0x00000800, // Enables polygon offset - PF_Modulated = 0x00001000, // Modulation (multiply output with constant ARGB) + PF_Modulated = 0x00001000, // Modulation (multiply output with constant RGBA) // When set, pass the color constant into the FSurfaceInfo -> PolyColor PF_NoTexture = 0x00002000, // Disables texturing PF_Corona = 0x00004000, // Tells the renderer we are drawing a corona - PF_Ripple = 0x00008000, // Water effect shader + PF_ColorMapped = 0x00008000, // Surface has "tint" and "fade" colors, which are sent as uniforms to a shader. PF_RemoveYWrap = 0x00010000, // Forces clamp texture on Y PF_ForceWrapX = 0x00020000, // Forces repeat texture on X - PF_ForceWrapY = 0x00040000 // Forces repeat texture on Y + PF_ForceWrapY = 0x00040000, // Forces repeat texture on Y + PF_Ripple = 0x00100000 // Water ripple effect. The current backend doesn't use it for anything. }; @@ -257,7 +258,6 @@ enum ETextureFlags typedef struct GLMipmap_s FTextureInfo; -// jimita 14032019 struct FLightInfo { FUINT light_level; @@ -273,7 +273,7 @@ struct FSurfaceInfo RGBA_t PolyColor; RGBA_t TintColor; RGBA_t FadeColor; - FLightInfo LightInfo; // jimita 14032019 + FLightInfo LightInfo; }; typedef struct FSurfaceInfo FSurfaceInfo; diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h index 5a2e0e44e..03e664e42 100644 --- a/src/hardware/hw_drv.h +++ b/src/hardware/hw_drv.h @@ -69,7 +69,6 @@ EXPORT void HWRAPI(DrawScreenFinalTexture) (int width, int height); #define SCREENVERTS 10 EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]); -// jimita EXPORT boolean HWRAPI(CompileShaders) (void); EXPORT void HWRAPI(CleanShaders) (void); EXPORT void HWRAPI(SetShader) (int type); diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index a7e37d231..ab5fa0229 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -173,6 +173,11 @@ boolean gl_shadersavailable = true; // Lighting // ========================================================================== +static boolean HWR_UseShader(void) +{ + return (cv_glshaders.value && gl_shadersavailable); +} + void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *colormap) { RGBA_t poly_color, tint_color, fade_color; @@ -182,7 +187,7 @@ void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *col fade_color.rgba = (colormap != NULL) ? (UINT32)colormap->fadergba : GL_DEFAULTFOG; // Crappy backup coloring if you can't do shaders - if (!cv_glshaders.value || !gl_shadersavailable) + if (!HWR_UseShader()) { // be careful, this may get negative for high lightlevel values. float tint_alpha, fade_alpha; @@ -371,7 +376,7 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool static FOutVector *planeVerts = NULL; static UINT16 numAllocedPlaneVerts = 0; - int shader; + INT32 shader = SHADER_DEFAULT; // no convex poly were generated for this subsector if (!xsub->planepoly) @@ -568,12 +573,17 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool else PolyFlags |= PF_Masked|PF_Modulated; - if (PolyFlags & PF_Fog) - shader = SHADER_FOG; // fog shader - else if (PolyFlags & PF_Ripple) - shader = SHADER_WATER; // water shader - else - shader = SHADER_FLOOR; // floor shader + if (HWR_UseShader()) + { + if (PolyFlags & PF_Fog) + shader = SHADER_FOG; + else if (PolyFlags & PF_Ripple) + shader = SHADER_WATER; + else + shader = SHADER_FLOOR; + + PolyFlags |= PF_ColorMapped; + } HWR_ProcessPolygon(&Surf, planeVerts, nrPlaneVerts, PolyFlags, shader, false); @@ -785,8 +795,17 @@ static void HWR_AddTransparentWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, I // static void HWR_ProjectWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blendmode, INT32 lightlevel, extracolormap_t *wallcolormap) { + INT32 shader = SHADER_DEFAULT; + HWR_Lighting(pSurf, lightlevel, wallcolormap); - HWR_ProcessPolygon(pSurf, wallVerts, 4, blendmode|PF_Modulated|PF_Occlude, SHADER_WALL, false); // wall shader + + if (HWR_UseShader()) + { + shader = SHADER_WALL; + blendmode |= PF_ColorMapped; + } + + HWR_ProcessPolygon(pSurf, wallVerts, 4, blendmode|PF_Modulated|PF_Occlude, shader, false); } // ========================================================================== @@ -2659,30 +2678,30 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, FBITFIELD blendmode, UINT8 lightlevel, levelflat_t *levelflat, sector_t *FOFsector, UINT8 alpha, extracolormap_t *planecolormap) { - float height; //constant y for all points on the convex flat polygon - FOutVector *v3d; - INT32 i; - float flatxref,flatyref; + FSurfaceInfo Surf; + FOutVector *v3d; + INT32 shader = SHADER_DEFAULT; + + size_t nrPlaneVerts = polysector->numVertices; + INT32 i; + + float height = FIXED_TO_FLOAT(fixedheight); // constant y for all points on the convex flat polygon + float flatxref, flatyref; float fflatwidth = 64.0f, fflatheight = 64.0f; INT32 flatflag = 63; + boolean texflat = false; + float scrollx = 0.0f, scrolly = 0.0f; angle_t angle = 0; - FSurfaceInfo Surf; fixed_t tempxs, tempyt; - size_t nrPlaneVerts; static FOutVector *planeVerts = NULL; static UINT16 numAllocedPlaneVerts = 0; - nrPlaneVerts = polysector->numVertices; - - height = FIXED_TO_FLOAT(fixedheight); - - if (nrPlaneVerts < 3) //not even a triangle ? + if (nrPlaneVerts < 3) // Not even a triangle? return; - - if (nrPlaneVerts > (size_t)UINT16_MAX) // FIXME: exceeds plVerts size + else if (nrPlaneVerts > (size_t)UINT16_MAX) // FIXME: exceeds plVerts size { CONS_Debug(DBG_RENDER, "polygon size of %s exceeds max value of %d vertices\n", sizeu1(nrPlaneVerts), UINT16_MAX); return; @@ -2834,7 +2853,6 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, v3d->z = FIXED_TO_FLOAT(polysector->vertices[i]->y); } - HWR_Lighting(&Surf, lightlevel, planecolormap); if (blendmode & PF_Translucent) @@ -2845,7 +2863,13 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, else blendmode |= PF_Masked|PF_Modulated; - HWR_ProcessPolygon(&Surf, planeVerts, nrPlaneVerts, blendmode, SHADER_FLOOR, false); // floor shader + if (HWR_UseShader()) + { + shader = SHADER_FLOOR; + blendmode |= PF_ColorMapped; + } + + HWR_ProcessPolygon(&Surf, planeVerts, nrPlaneVerts, blendmode, shader, false); } static void HWR_AddPolyObjectPlanes(void) @@ -3566,6 +3590,8 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale) FSurfaceInfo sSurf; float fscale; float fx; float fy; float offset; extracolormap_t *colormap = NULL; + FBITFIELD blendmode = PF_Translucent|PF_Modulated; + INT32 shader = SHADER_DEFAULT; UINT8 i; SINT8 flip = P_MobjFlip(thing); @@ -3658,7 +3684,13 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale) HWR_Lighting(&sSurf, 0, colormap); sSurf.PolyColor.s.alpha = alpha; - HWR_ProcessPolygon(&sSurf, shadowVerts, 4, PF_Translucent|PF_Modulated, SHADER_SPRITE, false); // sprite shader + if (HWR_UseShader()) + { + shader = SHADER_SPRITE; + blendmode |= PF_ColorMapped; + } + + HWR_ProcessPolygon(&sSurf, shadowVerts, 4, blendmode, shader, false); } // This is expecting a pointer to an array containing 4 wallVerts for a sprite @@ -3706,6 +3738,7 @@ static void HWR_SplitSprite(gl_vissprite_t *spr) boolean lightset = true; FBITFIELD blend = 0; FBITFIELD occlusion; + INT32 shader = SHADER_DEFAULT; boolean use_linkdraw_hack = false; boolean splat = R_ThingIsFloorSprite(spr->mobj); UINT8 alpha; @@ -3832,6 +3865,12 @@ static void HWR_SplitSprite(gl_vissprite_t *spr) if (!occlusion) use_linkdraw_hack = true; } + if (HWR_UseShader()) + { + shader = SHADER_SPRITE; + blend |= PF_ColorMapped; + } + alpha = Surf.PolyColor.s.alpha; // Start with the lightlevel and colormap from the top of the sprite @@ -3940,7 +3979,7 @@ static void HWR_SplitSprite(gl_vissprite_t *spr) Surf.PolyColor.s.alpha = alpha; - HWR_ProcessPolygon(&Surf, wallVerts, 4, blend|PF_Modulated, SHADER_SPRITE, false); // sprite shader + HWR_ProcessPolygon(&Surf, wallVerts, 4, blend|PF_Modulated, shader, false); if (use_linkdraw_hack) HWR_LinkDrawHackAdd(wallVerts, spr); @@ -3969,7 +4008,7 @@ static void HWR_SplitSprite(gl_vissprite_t *spr) Surf.PolyColor.s.alpha = alpha; - HWR_ProcessPolygon(&Surf, wallVerts, 4, blend|PF_Modulated, SHADER_SPRITE, false); // sprite shader + HWR_ProcessPolygon(&Surf, wallVerts, 4, blend|PF_Modulated, shader, false); if (use_linkdraw_hack) HWR_LinkDrawHackAdd(wallVerts, spr); @@ -4219,6 +4258,7 @@ static void HWR_DrawSprite(gl_vissprite_t *spr) } { + INT32 shader = SHADER_DEFAULT; FBITFIELD blend = 0; FBITFIELD occlusion; boolean use_linkdraw_hack = false; @@ -4271,7 +4311,13 @@ static void HWR_DrawSprite(gl_vissprite_t *spr) if (!occlusion) use_linkdraw_hack = true; } - HWR_ProcessPolygon(&Surf, wallVerts, 4, blend|PF_Modulated, SHADER_SPRITE, false); // sprite shader + if (HWR_UseShader()) + { + shader = SHADER_SPRITE; + blend |= PF_ColorMapped; + } + + HWR_ProcessPolygon(&Surf, wallVerts, 4, blend|PF_Modulated, shader, false); if (use_linkdraw_hack) HWR_LinkDrawHackAdd(wallVerts, spr); @@ -4282,6 +4328,7 @@ static void HWR_DrawSprite(gl_vissprite_t *spr) // Sprite drawer for precipitation static inline void HWR_DrawPrecipitationSprite(gl_vissprite_t *spr) { + INT32 shader = SHADER_DEFAULT; FBITFIELD blend = 0; FOutVector wallVerts[4]; patch_t *gpatch; // sprite patch converted to hardware @@ -4372,7 +4419,13 @@ static inline void HWR_DrawPrecipitationSprite(gl_vissprite_t *spr) blend = HWR_GetBlendModeFlag(spr->mobj->blendmode)|PF_Occlude; } - HWR_ProcessPolygon(&Surf, wallVerts, 4, blend|PF_Modulated, SHADER_SPRITE, false); // sprite shader + if (HWR_UseShader()) + { + shader = SHADER_SPRITE; + blend |= PF_ColorMapped; + } + + HWR_ProcessPolygon(&Surf, wallVerts, 4, blend|PF_Modulated, shader, false); } #endif @@ -6454,24 +6507,29 @@ void HWR_RenderWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blend, FBITFIELD blendmode = blend; UINT8 alpha = pSurf->PolyColor.s.alpha; // retain the alpha - int shader; + INT32 shader = SHADER_DEFAULT; // Lighting is done here instead so that fog isn't drawn incorrectly on transparent walls after sorting HWR_Lighting(pSurf, lightlevel, wallcolormap); pSurf->PolyColor.s.alpha = alpha; // put the alpha back after lighting - shader = SHADER_WALL; // wall shader - if (blend & PF_Environment) blendmode |= PF_Occlude; // PF_Occlude must be used for solid objects - if (fogwall) + if (HWR_UseShader()) { - blendmode |= PF_Fog; - shader = SHADER_FOG; // fog shader + if (fogwall) + shader = SHADER_FOG; + else + shader = SHADER_WALL; + + blendmode |= PF_ColorMapped; } + if (fogwall) + blendmode |= PF_Fog; + blendmode |= PF_Modulated; // No PF_Occlude means overlapping (incorrect) transparency HWR_ProcessPolygon(pSurf, wallVerts, 4, blendmode, shader, false); } @@ -6647,7 +6705,6 @@ void HWR_DrawScreenFinalTexture(int width, int height) HWD.pfnDrawScreenFinalTexture(width, height); } -// jimita 18032019 static inline UINT16 HWR_FindShaderDefs(UINT16 wadnum) { UINT16 i; diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 8cd948eea..56e7efc4e 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -909,7 +909,6 @@ void SetupGLFunc4(void) pgluBuild2DMipmaps = GetGLFunc("gluBuild2DMipmaps"); } -// jimita EXPORT boolean HWRAPI(CompileShaders) (void) { #ifdef GL_SHADERS @@ -2144,32 +2143,34 @@ static void PreparePolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FBITFIELD SetBlend(PolyFlags); //TODO: inline (#pragma..) - // PolyColor if (pSurf) { - // If Modulated, mix the surface colour to the texture + // If modulated, mix the surface colour to the texture if (CurrentPolyFlags & PF_Modulated) - { - // Poly color - poly.red = byte2float[pSurf->PolyColor.s.red]; - poly.green = byte2float[pSurf->PolyColor.s.green]; - poly.blue = byte2float[pSurf->PolyColor.s.blue]; - poly.alpha = byte2float[pSurf->PolyColor.s.alpha]; - pglColor4ubv((GLubyte*)&pSurf->PolyColor.s); + + // If the surface is either modulated or colormapped, or both + if (CurrentPolyFlags & (PF_Modulated | PF_ColorMapped)) + { + poly.red = byte2float[pSurf->PolyColor.s.red]; + poly.green = byte2float[pSurf->PolyColor.s.green]; + poly.blue = byte2float[pSurf->PolyColor.s.blue]; + poly.alpha = byte2float[pSurf->PolyColor.s.alpha]; } - // Tint color - tint.red = byte2float[pSurf->TintColor.s.red]; - tint.green = byte2float[pSurf->TintColor.s.green]; - tint.blue = byte2float[pSurf->TintColor.s.blue]; - tint.alpha = byte2float[pSurf->TintColor.s.alpha]; + // Only if the surface is colormapped + if (CurrentPolyFlags & PF_ColorMapped) + { + tint.red = byte2float[pSurf->TintColor.s.red]; + tint.green = byte2float[pSurf->TintColor.s.green]; + tint.blue = byte2float[pSurf->TintColor.s.blue]; + tint.alpha = byte2float[pSurf->TintColor.s.alpha]; - // Fade color - fade.red = byte2float[pSurf->FadeColor.s.red]; - fade.green = byte2float[pSurf->FadeColor.s.green]; - fade.blue = byte2float[pSurf->FadeColor.s.blue]; - fade.alpha = byte2float[pSurf->FadeColor.s.alpha]; + fade.red = byte2float[pSurf->FadeColor.s.red]; + fade.green = byte2float[pSurf->FadeColor.s.green]; + fade.blue = byte2float[pSurf->FadeColor.s.blue]; + fade.alpha = byte2float[pSurf->FadeColor.s.alpha]; + } } // this test is added for new coronas' code (without depth buffer) @@ -2983,7 +2984,6 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform) pglMatrixMode(GL_PROJECTION); pglLoadIdentity(); - // jimita 14042019 // Simulate Software's y-shearing // https://zdoom.org/wiki/Y-shearing if (shearing) From 4891611ab73a7ec60119bfee84d5a164b3127611 Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Wed, 27 Jan 2021 19:23:04 -0300 Subject: [PATCH 253/644] tRNS chunk fix Fixes a faulty check not properly detecting the presence of a tRNS chunk. --- src/r_picformats.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/r_picformats.c b/src/r_picformats.c index f87362c76..ac9747426 100644 --- a/src/r_picformats.c +++ b/src/r_picformats.c @@ -979,8 +979,8 @@ static png_bytep *PNG_Read( for (i = 0; i < 256; i++) { - UINT32 rgb = R_PutRgbaRGBA(pal->red, pal->green, pal->blue, 0xFF); - if (rgb != pMasterPalette[i].rgba) + byteColor_t *curpal = &(pMasterPalette[i].s); + if (pal->red != curpal->red || pal->green != curpal->green || pal->blue != curpal->blue) { usepal = false; break; @@ -996,12 +996,12 @@ static png_bytep *PNG_Read( { png_get_tRNS(png_ptr, png_info_ptr, &trans, &trans_num, &trans_values); - if (trans && trans_num == 256) + if (trans && trans_num > 0) { INT32 i; for (i = 0; i < trans_num; i++) { - // libpng will transform this image into RGB even if + // libpng will transform this image into RGBA even if // the transparent index does not exist in the image, // and there is no way around that. if (trans[i] < 0xFF) From 8318935811aab1bfbf28cc072f302000417e6680 Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Wed, 27 Jan 2021 21:23:20 -0300 Subject: [PATCH 254/644] Remove GLMipmap_t.nextmipmap --- src/hardware/hw_data.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/hardware/hw_data.h b/src/hardware/hw_data.h index ce6527666..7e56a14d0 100644 --- a/src/hardware/hw_data.h +++ b/src/hardware/hw_data.h @@ -64,8 +64,6 @@ struct GLMipmap_s struct GLMipmap_s *nextcolormap; struct GLColormap_s *colormap; - - struct GLMipmap_s *nextmipmap; // Linked list of all textures }; typedef struct GLMipmap_s GLMipmap_t; From 3dff1eb1b71af5c483238d63fcf5c6a5adcbecb8 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Thu, 11 Feb 2021 00:10:15 +0100 Subject: [PATCH 255/644] Fix consoleplayer returning the server player during joining phase --- src/lua_script.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lua_script.c b/src/lua_script.c index bc88928f3..7fd5a98e6 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -333,7 +333,7 @@ int LUA_PushGlobals(lua_State *L, const char *word) return 1; // local player variables, by popular request } else if (fastcmp(word,"consoleplayer")) { // player controlling console (aka local player 1) - if (consoleplayer < 0 || !playeringame[consoleplayer]) + if (!addedtogame || consoleplayer < 0 || !playeringame[consoleplayer]) return 0; LUA_PushUserdata(L, &players[consoleplayer], META_PLAYER); return 1; From dfc1767794c140fc086bcac77c261fcdf39e2270 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Thu, 11 Feb 2021 00:24:42 +0100 Subject: [PATCH 256/644] Only call PlayerCmd hooks if added to game --- src/g_game.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g_game.c b/src/g_game.c index 6b7356c52..10bec888f 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1678,7 +1678,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) // At this point, cmd doesn't contain the final angle yet, // So we need to temporarily transform it so Lua scripters // don't need to handle it differently than in other hooks. - if (gamestate == GS_LEVEL) + if (addedtogame && gamestate == GS_LEVEL) { INT16 extra = ticcmd_oldangleturn[forplayer] - player->oldrelangleturn; INT16 origangle = cmd->angleturn; From 326be012760a1f9e1dff38d3162d8120b620a489 Mon Sep 17 00:00:00 2001 From: namishere <50415197+namishere@users.noreply.github.com> Date: Thu, 11 Feb 2021 04:06:40 -0800 Subject: [PATCH 257/644] Expose P_ButteredSlope to lua --- src/lua_baselib.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index c5f847be6..240591506 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -2494,6 +2494,17 @@ static int lib_pGetZAt(lua_State *L) return 1; } +static int lib_pButteredSlope(lua_State *L) +{ + mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); + NOHUD + INLEVEL + if (!mobj) + return LUA_ErrInvalid(L, "mobj_t"); + P_ButteredSlope(mobj); + return 0; +} + // R_DEFS //////////// @@ -3932,6 +3943,7 @@ static luaL_Reg lib[] = { // p_slopes {"P_GetZAt",lib_pGetZAt}, + {"P_ButteredSlope",lib_pButteredSlope}, // r_defs {"R_PointToAngle",lib_rPointToAngle}, From eda6b0ad8edb2cfda121f8e5058065975a853a1f Mon Sep 17 00:00:00 2001 From: Nev3r Date: Thu, 11 Feb 2021 13:24:20 +0100 Subject: [PATCH 258/644] Remove TAG_ITER_DECLARECOUNTER and the level field on the iterator macros. Declare the position counters inside the for loops instead; RIP C90. --- src/p_ceilng.c | 6 +-- src/p_floor.c | 39 ++++++---------- src/p_lights.c | 3 +- src/p_mobj.c | 6 +-- src/p_setup.c | 8 +--- src/p_slopes.c | 3 +- src/p_spec.c | 122 +++++++++++++++++++++++-------------------------- src/taglist.h | 11 ++--- 8 files changed, 82 insertions(+), 116 deletions(-) diff --git a/src/p_ceilng.c b/src/p_ceilng.c index 2168d1d78..264a6e2c8 100644 --- a/src/p_ceilng.c +++ b/src/p_ceilng.c @@ -395,9 +395,8 @@ INT32 EV_DoCeiling(line_t *line, ceiling_e type) sector_t *sec; ceiling_t *ceiling; mtag_t tag = Tag_FGet(&line->tags); - TAG_ITER_DECLARECOUNTER(0); - TAG_ITER_SECTORS(0, tag, secnum) + TAG_ITER_SECTORS(tag, secnum) { sec = §ors[secnum]; @@ -617,9 +616,8 @@ INT32 EV_DoCrush(line_t *line, ceiling_e type) sector_t *sec; ceiling_t *ceiling; mtag_t tag = Tag_FGet(&line->tags); - TAG_ITER_DECLARECOUNTER(0); - TAG_ITER_SECTORS(0, tag, secnum) + TAG_ITER_SECTORS(tag, secnum) { sec = §ors[secnum]; diff --git a/src/p_floor.c b/src/p_floor.c index de8f5d4e8..86a2a9319 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -635,7 +635,6 @@ void T_BounceCheese(bouncecheese_t *bouncer) boolean remove; INT32 i; mtag_t tag = Tag_FGet(&bouncer->sourceline->tags); - TAG_ITER_DECLARECOUNTER(0); if (bouncer->sector->crumblestate == CRUMBLE_RESTORE || bouncer->sector->crumblestate == CRUMBLE_WAIT || bouncer->sector->crumblestate == CRUMBLE_ACTIVATED) // Oops! Crumbler says to remove yourself! @@ -650,7 +649,7 @@ void T_BounceCheese(bouncecheese_t *bouncer) } // You can use multiple target sectors, but at your own risk!!! - TAG_ITER_SECTORS(0, tag, i) + TAG_ITER_SECTORS(tag, i) { actionsector = §ors[i]; actionsector->moved = true; @@ -775,7 +774,6 @@ void T_StartCrumble(crumble_t *crumble) sector_t *sector; INT32 i; mtag_t tag = Tag_FGet(&crumble->sourceline->tags); - TAG_ITER_DECLARECOUNTER(0); // Once done, the no-return thinker just sits there, // constantly 'returning'... kind of an oxymoron, isn't it? @@ -804,7 +802,7 @@ void T_StartCrumble(crumble_t *crumble) } else if (++crumble->timer == 0) // Reposition back to original spot { - TAG_ITER_SECTORS(0, tag, i) + TAG_ITER_SECTORS(tag, i) { sector = §ors[i]; @@ -840,7 +838,7 @@ void T_StartCrumble(crumble_t *crumble) // Flash to indicate that the platform is about to return. if (crumble->timer > -224 && (leveltime % ((abs(crumble->timer)/8) + 1) == 0)) { - TAG_ITER_SECTORS(0, tag, i) + TAG_ITER_SECTORS(tag, i) { sector = §ors[i]; @@ -932,7 +930,7 @@ void T_StartCrumble(crumble_t *crumble) P_RemoveThinker(&crumble->thinker); } - TAG_ITER_SECTORS(0, tag, i) + TAG_ITER_SECTORS(tag, i) { sector = §ors[i]; sector->moved = true; @@ -948,7 +946,6 @@ void T_StartCrumble(crumble_t *crumble) void T_MarioBlock(mariothink_t *block) { INT32 i; - TAG_ITER_DECLARECOUNTER(0); T_MovePlane ( @@ -983,7 +980,7 @@ void T_MarioBlock(mariothink_t *block) block->sector->ceilspeed = 0; block->direction = 0; } - TAG_ITER_SECTORS(0, (INT16)block->tag, i) + TAG_ITER_SECTORS((INT16)block->tag, i) P_RecalcPrecipInSector(§ors[i]); } @@ -1293,9 +1290,8 @@ void T_NoEnemiesSector(noenemies_t *nobaddies) INT32 secnum = -1; boolean FOFsector = false; mtag_t tag = Tag_FGet(&nobaddies->sourceline->tags); - TAG_ITER_DECLARECOUNTER(0); - TAG_ITER_SECTORS(0, tag, secnum) + TAG_ITER_SECTORS(tag, secnum) { sec = §ors[secnum]; @@ -1306,14 +1302,13 @@ void T_NoEnemiesSector(noenemies_t *nobaddies) { INT32 targetsecnum = -1; mtag_t tag2 = Tag_FGet(&sec->lines[i]->tags); - TAG_ITER_DECLARECOUNTER(1); if (sec->lines[i]->special < 100 || sec->lines[i]->special >= 300) continue; FOFsector = true; - TAG_ITER_SECTORS(1, tag2, targetsecnum) + TAG_ITER_SECTORS(tag2, targetsecnum) { if (T_SectorHasEnemies(§ors[targetsecnum])) return; @@ -1400,7 +1395,6 @@ void T_EachTimeThinker(eachtime_t *eachtime) fixed_t bottomheight, topheight; ffloor_t *rover; mtag_t tag = Tag_FGet(&eachtime->sourceline->tags); - TAG_ITER_DECLARECOUNTER(0); for (i = 0; i < MAXPLAYERS; i++) { @@ -1410,7 +1404,7 @@ void T_EachTimeThinker(eachtime_t *eachtime) eachtime->playersOnArea[i] = false; } - TAG_ITER_SECTORS(0, tag, secnum) + TAG_ITER_SECTORS(tag, secnum) { sec = §ors[secnum]; @@ -1428,14 +1422,13 @@ void T_EachTimeThinker(eachtime_t *eachtime) { INT32 targetsecnum = -1; mtag_t tag2 = Tag_FGet(&sec->lines[i]->tags); - TAG_ITER_DECLARECOUNTER(1); if (sec->lines[i]->special < 100 || sec->lines[i]->special >= 300) continue; FOFsector = true; - TAG_ITER_SECTORS(1, tag2, targetsecnum) + TAG_ITER_SECTORS(tag2, targetsecnum) { targetsec = §ors[targetsecnum]; @@ -1570,12 +1563,11 @@ void T_RaiseSector(raise_t *raise) INT32 direction; result_e res = 0; mtag_t tag = raise->tag; - TAG_ITER_DECLARECOUNTER(0); if (raise->sector->crumblestate >= CRUMBLE_FALL || raise->sector->ceilingdata) return; - TAG_ITER_SECTORS(0, tag, i) + TAG_ITER_SECTORS(tag, i) { sector = §ors[i]; @@ -1702,7 +1694,7 @@ void T_RaiseSector(raise_t *raise) raise->sector->ceilspeed = 42; raise->sector->floorspeed = speed*direction; - TAG_ITER_SECTORS(0, tag, i) + TAG_ITER_SECTORS(tag, i) P_RecalcPrecipInSector(§ors[i]); } @@ -1820,9 +1812,8 @@ void EV_DoFloor(line_t *line, floor_e floortype) sector_t *sec; floormove_t *dofloor; mtag_t tag = Tag_FGet(&line->tags); - TAG_ITER_DECLARECOUNTER(0); - TAG_ITER_SECTORS(0, tag, secnum) + TAG_ITER_SECTORS(tag, secnum) { sec = §ors[secnum]; @@ -2037,10 +2028,9 @@ void EV_DoElevator(line_t *line, elevator_e elevtype, boolean customspeed) sector_t *sec; elevator_t *elevator; mtag_t tag = Tag_FGet(&line->tags); - TAG_ITER_DECLARECOUNTER(0); // act on all sectors with the same tag as the triggering linedef - TAG_ITER_SECTORS(0, tag, secnum) + TAG_ITER_SECTORS(tag, secnum) { sec = §ors[secnum]; @@ -2337,7 +2327,6 @@ INT32 EV_StartCrumble(sector_t *sec, ffloor_t *rover, boolean floating, sector_t *foundsec; INT32 i; mtag_t tag = Tag_FGet(&rover->master->tags); - TAG_ITER_DECLARECOUNTER(0); // If floor is already activated, skip it if (sec->floordata) @@ -2380,7 +2369,7 @@ INT32 EV_StartCrumble(sector_t *sec, ffloor_t *rover, boolean floating, crumble->sector->crumblestate = CRUMBLE_ACTIVATED; - TAG_ITER_SECTORS(0, tag, i) + TAG_ITER_SECTORS(tag, i) { foundsec = §ors[i]; diff --git a/src/p_lights.c b/src/p_lights.c index d396e92d3..3fc8e6c10 100644 --- a/src/p_lights.c +++ b/src/p_lights.c @@ -374,10 +374,9 @@ void P_FadeLightBySector(sector_t *sector, INT32 destvalue, INT32 speed, boolean void P_FadeLight(INT16 tag, INT32 destvalue, INT32 speed, boolean ticbased, boolean force) { INT32 i; - TAG_ITER_DECLARECOUNTER(0); // search all sectors for ones with tag - TAG_ITER_SECTORS(0, tag, i) + TAG_ITER_SECTORS(tag, i) { if (!force && ticbased // always let speed fader execute && sectors[i].lightingdata diff --git a/src/p_mobj.c b/src/p_mobj.c index 69eecd26d..2b408b2fd 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -4607,9 +4607,8 @@ static boolean P_Boss4MoveCage(mobj_t *mobj, fixed_t delta) INT32 snum; sector_t *sector; boolean gotcage = false; - TAG_ITER_DECLARECOUNTER(0); - TAG_ITER_SECTORS(0, tag, snum) + TAG_ITER_SECTORS(tag, snum) { sector = §ors[snum]; sector->floorheight += delta; @@ -4693,9 +4692,8 @@ static void P_Boss4DestroyCage(mobj_t *mobj) size_t a; sector_t *sector, *rsec; ffloor_t *rover; - TAG_ITER_DECLARECOUNTER(0); - TAG_ITER_SECTORS(0, tag, snum) + TAG_ITER_SECTORS(tag, snum) { sector = §ors[snum]; diff --git a/src/p_setup.c b/src/p_setup.c index 2c0b84ba6..e93d930da 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2966,9 +2966,7 @@ static void P_ConvertBinaryMap(void) INT32 check = -1; INT32 paramline = -1; - TAG_ITER_DECLARECOUNTER(0); - - TAG_ITER_LINES(0, tag, check) + TAG_ITER_LINES(tag, check) { if (lines[check].special == 22) { @@ -3183,11 +3181,9 @@ static void P_ConvertBinaryMap(void) INT32 firstline = -1; mtag_t tag = mapthings[i].angle; - TAG_ITER_DECLARECOUNTER(0); - Tag_FSet(&mapthings[i].tags, tag); - TAG_ITER_LINES(0, tag, check) + TAG_ITER_LINES(tag, check) { if (lines[check].special == 20) { diff --git a/src/p_slopes.c b/src/p_slopes.c index d77d0805f..29fbb308f 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -546,11 +546,10 @@ static boolean P_SetSlopeFromTag(sector_t *sec, INT32 tag, boolean ceiling) { INT32 i; pslope_t **secslope = ceiling ? &sec->c_slope : &sec->f_slope; - TAG_ITER_DECLARECOUNTER(0); if (!tag || *secslope) return false; - TAG_ITER_SECTORS(0, tag, i) + TAG_ITER_SECTORS(tag, i) { pslope_t *srcslope = ceiling ? sectors[i].c_slope : sectors[i].f_slope; if (srcslope) diff --git a/src/p_spec.c b/src/p_spec.c index eb14f8dd6..998f8d9e3 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -2223,7 +2223,6 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) INT32 secnum = -1; mobj_t *bot = NULL; mtag_t tag = Tag_FGet(&line->tags); - TAG_ITER_DECLARECOUNTER(0); I_Assert(!mo || !P_MobjWasRemoved(mo)); // If mo is there, mo must be valid! @@ -2251,7 +2250,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) newceilinglightsec = line->frontsector->ceilinglightsec; // act on all sectors with the same tag as the triggering linedef - TAG_ITER_SECTORS(0, tag, secnum) + TAG_ITER_SECTORS(tag, secnum) { if (sectors[secnum].lightingdata) { @@ -2306,7 +2305,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) case 409: // Change tagged sectors' tag // (formerly "Change calling sectors' tag", but behavior was changed) { - TAG_ITER_SECTORS(0, tag, secnum) + TAG_ITER_SECTORS(tag, secnum) Tag_SectorFSet(secnum,(INT16)(sides[line->sidenum[0]].textureoffset>>FRACBITS)); break; } @@ -2316,7 +2315,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) break; case 411: // Stop floor/ceiling movement in tagged sector(s) - TAG_ITER_SECTORS(0, tag, secnum) + TAG_ITER_SECTORS(tag, secnum) { if (sectors[secnum].floordata) { @@ -2501,7 +2500,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) // Additionally play the sound from tagged sectors' soundorgs sector_t *sec; - TAG_ITER_SECTORS(0, tag, secnum) + TAG_ITER_SECTORS(tag, secnum) { sec = §ors[secnum]; S_StartSound(&sec->soundorg, sfxnum); @@ -2616,7 +2615,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) break; case 416: // Spawn adjustable fire flicker - TAG_ITER_SECTORS(0, tag, secnum) + TAG_ITER_SECTORS(tag, secnum) { if (line->flags & ML_NOCLIMB && line->backsector) { @@ -2650,7 +2649,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) break; case 417: // Spawn adjustable glowing light - TAG_ITER_SECTORS(0, tag, secnum) + TAG_ITER_SECTORS(tag, secnum) { if (line->flags & ML_NOCLIMB && line->backsector) { @@ -2684,7 +2683,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) break; case 418: // Spawn adjustable strobe flash (unsynchronized) - TAG_ITER_SECTORS(0, tag, secnum) + TAG_ITER_SECTORS(tag, secnum) { if (line->flags & ML_NOCLIMB && line->backsector) { @@ -2718,7 +2717,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) break; case 419: // Spawn adjustable strobe flash (synchronized) - TAG_ITER_SECTORS(0, tag, secnum) + TAG_ITER_SECTORS(tag, secnum) { if (line->flags & ML_NOCLIMB && line->backsector) { @@ -2766,7 +2765,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) break; case 421: // Stop lighting effect in tagged sectors - TAG_ITER_SECTORS(0, tag, secnum) + TAG_ITER_SECTORS(tag, secnum) if (sectors[secnum].lightingdata) { P_RemoveThinker(&((elevator_t *)sectors[secnum].lightingdata)->thinker); @@ -2980,7 +2979,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) ffloor_t *rover; // FOF that we are going to crumble boolean foundrover = false; // for debug, "Can't find a FOF" message - TAG_ITER_SECTORS(0, sectag, secnum) + TAG_ITER_SECTORS(sectag, secnum) { sec = sectors + secnum; @@ -3105,7 +3104,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) if (line->sidenum[1] != 0xffff) state = (statenum_t)sides[line->sidenum[1]].toptexture; - TAG_ITER_SECTORS(0, tag, secnum) + TAG_ITER_SECTORS(tag, secnum) { boolean tryagain; sec = sectors + secnum; @@ -3165,7 +3164,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) boolean foundrover = false; // for debug, "Can't find a FOF" message ffloortype_e oldflags; // store FOF's old flags - TAG_ITER_SECTORS(0, sectag, secnum) + TAG_ITER_SECTORS(sectag, secnum) { sec = sectors + secnum; @@ -3223,7 +3222,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) if (line->flags & ML_NOCLIMB) // don't respawn! respawn = false; - TAG_ITER_SECTORS(0, sectag, secnum) + TAG_ITER_SECTORS(sectag, secnum) { sec = sectors + secnum; @@ -3279,7 +3278,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) source = sectors[sourcesec].extra_colormap; } } - TAG_ITER_SECTORS(0, line->args[0], secnum) + TAG_ITER_SECTORS(line->args[0], secnum) { if (sectors[secnum].colormap_protected) continue; @@ -3414,7 +3413,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) ffloor_t *rover; // FOF that we are going to operate boolean foundrover = false; // for debug, "Can't find a FOF" message - TAG_ITER_SECTORS(0, sectag, secnum) + TAG_ITER_SECTORS(sectag, secnum) { sec = sectors + secnum; @@ -3478,7 +3477,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) boolean foundrover = false; // for debug, "Can't find a FOF" message size_t j = 0; // sec->ffloors is saved as ffloor #0, ss->ffloors->next is #1, etc - TAG_ITER_SECTORS(0, sectag, secnum) + TAG_ITER_SECTORS(sectag, secnum) { sec = sectors + secnum; @@ -3563,7 +3562,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) ffloor_t *rover; // FOF that we are going to operate boolean foundrover = false; // for debug, "Can't find a FOF" message - TAG_ITER_SECTORS(0, sectag, secnum) + TAG_ITER_SECTORS(sectag, secnum) { sec = sectors + secnum; @@ -3614,7 +3613,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) } } - TAG_ITER_SECTORS(0, line->args[0], secnum) + TAG_ITER_SECTORS(line->args[0], secnum) { extracolormap_t *source_exc, *dest_exc, *exc; @@ -3694,7 +3693,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) break; } case 456: // Stop fade colormap - TAG_ITER_SECTORS(0, line->args[0], secnum) + TAG_ITER_SECTORS(line->args[0], secnum) P_ResetColormapFader(§ors[secnum]); break; @@ -3887,12 +3886,11 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) case 465: // Set linedef executor delay { INT32 linenum; - TAG_ITER_DECLARECOUNTER(1); if (!udmf) break; - TAG_ITER_LINES(1, line->args[0], linenum) + TAG_ITER_LINES(line->args[0], linenum) { if (line->args[2]) lines[linenum].executordelay += line->args[1]; @@ -5928,9 +5926,8 @@ void T_LaserFlash(laserthink_t *flash) sector_t *sector; sector_t *sourcesec = flash->sourceline->frontsector; fixed_t top, bottom; - TAG_ITER_DECLARECOUNTER(0); - TAG_ITER_SECTORS(0, flash->tag, s) + TAG_ITER_SECTORS(flash->tag, s) { sector = §ors[s]; for (fflr = sector->ffloors; fflr; fflr = fflr->next) @@ -6210,11 +6207,10 @@ void P_SpawnSpecials(boolean fromnetsave) INT32 s; size_t sec; ffloortype_e ffloorflags; - TAG_ITER_DECLARECOUNTER(0); case 1: // Definable gravity per sector sec = sides[*lines[i].sidenum].sector - sectors; - TAG_ITER_SECTORS(0, tag, s) + TAG_ITER_SECTORS(tag, s) { sectors[s].gravity = §ors[sec].floorheight; // This allows it to change in realtime! @@ -6238,7 +6234,7 @@ void P_SpawnSpecials(boolean fromnetsave) case 5: // Change camera info sec = sides[*lines[i].sidenum].sector - sectors; - TAG_ITER_SECTORS(0, tag, s) + TAG_ITER_SECTORS(tag, s) P_AddCameraScanner(§ors[sec], §ors[s], R_PointToAngle2(lines[i].v2->x, lines[i].v2->y, lines[i].v1->x, lines[i].v1->y)); break; @@ -6265,7 +6261,7 @@ void P_SpawnSpecials(boolean fromnetsave) P_ApplyFlatAlignment(lines + i, lines[i].frontsector, flatangle, xoffs, yoffs); else { - TAG_ITER_SECTORS(0, tag, s) + TAG_ITER_SECTORS(tag, s) P_ApplyFlatAlignment(lines + i, sectors + s, flatangle, xoffs, yoffs); } } @@ -6276,7 +6272,7 @@ void P_SpawnSpecials(boolean fromnetsave) break; case 8: // Sector Parameters - TAG_ITER_SECTORS(0, tag, s) + TAG_ITER_SECTORS(tag, s) { if (lines[i].flags & ML_NOCLIMB) { @@ -6303,7 +6299,7 @@ void P_SpawnSpecials(boolean fromnetsave) break; case 10: // Vertical culling plane for sprites and FOFs - TAG_ITER_SECTORS(0, tag, s) + TAG_ITER_SECTORS(tag, s) sectors[s].cullheight = &lines[i]; // This allows it to change in realtime! break; @@ -6364,19 +6360,19 @@ void P_SpawnSpecials(boolean fromnetsave) case 63: // support for drawn heights coming from different sector sec = sides[*lines[i].sidenum].sector-sectors; - TAG_ITER_SECTORS(0, tag, s) + TAG_ITER_SECTORS(tag, s) sectors[s].heightsec = (INT32)sec; break; case 64: // Appearing/Disappearing FOF option if (lines[i].flags & ML_BLOCKMONSTERS) { // Find FOFs by control sector tag - TAG_ITER_SECTORS(0, tag, s) + TAG_ITER_SECTORS(tag, s) for (j = 0; (unsigned)j < sectors[s].linecount; j++) if (sectors[s].lines[j]->special >= 100 && sectors[s].lines[j]->special < 300) Add_MasterDisappearer(abs(lines[i].dx>>FRACBITS), abs(lines[i].dy>>FRACBITS), abs(sides[lines[i].sidenum[0]].sector->floorheight>>FRACBITS), (INT32)(sectors[s].lines[j]-lines), (INT32)i); } else // Find FOFs by effect sector tag { - TAG_ITER_LINES(0, tag, s) + TAG_ITER_LINES(tag, s) { if ((size_t)s == i) continue; @@ -6387,15 +6383,15 @@ void P_SpawnSpecials(boolean fromnetsave) break; case 66: // Displace floor by front sector - TAG_ITER_SECTORS(0, tag, s) + TAG_ITER_SECTORS(tag, s) P_AddPlaneDisplaceThinker(pd_floor, FixedHypot(lines[i].dx, lines[i].dy)>>8, sides[lines[i].sidenum[0]].sector-sectors, s, !!(lines[i].flags & ML_NOCLIMB)); break; case 67: // Displace ceiling by front sector - TAG_ITER_SECTORS(0, tag, s) + TAG_ITER_SECTORS(tag, s) P_AddPlaneDisplaceThinker(pd_ceiling, FixedHypot(lines[i].dx, lines[i].dy)>>8, sides[lines[i].sidenum[0]].sector-sectors, s, !!(lines[i].flags & ML_NOCLIMB)); break; case 68: // Displace both floor AND ceiling by front sector - TAG_ITER_SECTORS(0, tag, s) + TAG_ITER_SECTORS(tag, s) P_AddPlaneDisplaceThinker(pd_both, FixedHypot(lines[i].dx, lines[i].dy)>>8, sides[lines[i].sidenum[0]].sector-sectors, s, !!(lines[i].flags & ML_NOCLIMB)); break; @@ -6991,46 +6987,46 @@ void P_SpawnSpecials(boolean fromnetsave) case 600: // floor lighting independently (e.g. lava) sec = sides[*lines[i].sidenum].sector-sectors; - TAG_ITER_SECTORS(0, tag, s) + TAG_ITER_SECTORS(tag, s) sectors[s].floorlightsec = (INT32)sec; break; case 601: // ceiling lighting independently sec = sides[*lines[i].sidenum].sector-sectors; - TAG_ITER_SECTORS(0, tag, s) + TAG_ITER_SECTORS(tag, s) sectors[s].ceilinglightsec = (INT32)sec; break; case 602: // Adjustable pulsating light sec = sides[*lines[i].sidenum].sector - sectors; - TAG_ITER_SECTORS(0, tag, s) + TAG_ITER_SECTORS(tag, s) P_SpawnAdjustableGlowingLight(§ors[sec], §ors[s], FixedHypot(lines[i].dx, lines[i].dy)>>FRACBITS); break; case 603: // Adjustable flickering light sec = sides[*lines[i].sidenum].sector - sectors; - TAG_ITER_SECTORS(0, tag, s) + TAG_ITER_SECTORS(tag, s) P_SpawnAdjustableFireFlicker(§ors[sec], §ors[s], FixedHypot(lines[i].dx, lines[i].dy)>>FRACBITS); break; case 604: // Adjustable Blinking Light (unsynchronized) sec = sides[*lines[i].sidenum].sector - sectors; - TAG_ITER_SECTORS(0, tag, s) + TAG_ITER_SECTORS(tag, s) P_SpawnAdjustableStrobeFlash(§ors[sec], §ors[s], abs(lines[i].dx)>>FRACBITS, abs(lines[i].dy)>>FRACBITS, false); break; case 605: // Adjustable Blinking Light (synchronized) sec = sides[*lines[i].sidenum].sector - sectors; - TAG_ITER_SECTORS(0, tag, s) + TAG_ITER_SECTORS(tag, s) P_SpawnAdjustableStrobeFlash(§ors[sec], §ors[s], abs(lines[i].dx)>>FRACBITS, abs(lines[i].dy)>>FRACBITS, true); break; case 606: // HACK! Copy colormaps. Just plain colormaps. - TAG_ITER_SECTORS(0, lines[i].args[0], s) + TAG_ITER_SECTORS(lines[i].args[0], s) { extracolormap_t *exc; @@ -7104,13 +7100,12 @@ void P_SpawnSpecials(boolean fromnetsave) */ static void P_AddFakeFloorsByLine(size_t line, ffloortype_e ffloorflags, thinkerlist_t *secthinkers) { - TAG_ITER_DECLARECOUNTER(0); INT32 s; mtag_t tag = Tag_FGet(&lines[line].tags); size_t sec = sides[*lines[line].sidenum].sector-sectors; line_t* li = lines + line; - TAG_ITER_SECTORS(0, tag, s) + TAG_ITER_SECTORS(tag, s) P_AddFakeFloor(§ors[s], §ors[sec], li, ffloorflags, secthinkers); } @@ -7220,7 +7215,6 @@ void T_Scroll(scroll_t *s) size_t i; INT32 sect; ffloor_t *rover; - TAG_ITER_DECLARECOUNTER(0); case sc_side: // scroll wall texture side = sides + s->affectee; @@ -7257,7 +7251,7 @@ void T_Scroll(scroll_t *s) if (!is3dblock) continue; - TAG_ITER_SECTORS(0, Tag_FGet(&line->tags), sect) + TAG_ITER_SECTORS(Tag_FGet(&line->tags), sect) { sector_t *psec; psec = sectors + sect; @@ -7332,7 +7326,7 @@ void T_Scroll(scroll_t *s) if (!is3dblock) continue; - TAG_ITER_SECTORS(0, Tag_FGet(&line->tags), sect) + TAG_ITER_SECTORS(Tag_FGet(&line->tags), sect) { sector_t *psec; psec = sectors + sect; @@ -7472,11 +7466,10 @@ static void P_SpawnScrollers(void) switch (special) { register INT32 s; - TAG_ITER_DECLARECOUNTER(0); case 513: // scroll effect ceiling case 533: // scroll and carry objects on ceiling - TAG_ITER_SECTORS(0, tag, s) + TAG_ITER_SECTORS(tag, s) Add_Scroller(sc_ceiling, -dx, dy, control, s, accel, l->flags & ML_NOCLIMB); if (special != 533) break; @@ -7485,13 +7478,13 @@ static void P_SpawnScrollers(void) case 523: // carry objects on ceiling dx = FixedMul(dx, CARRYFACTOR); dy = FixedMul(dy, CARRYFACTOR); - TAG_ITER_SECTORS(0, tag, s) + TAG_ITER_SECTORS(tag, s) Add_Scroller(sc_carry_ceiling, dx, dy, control, s, accel, l->flags & ML_NOCLIMB); break; case 510: // scroll effect floor case 530: // scroll and carry objects on floor - TAG_ITER_SECTORS(0, tag, s) + TAG_ITER_SECTORS(tag, s) Add_Scroller(sc_floor, -dx, dy, control, s, accel, l->flags & ML_NOCLIMB); if (special != 530) break; @@ -7500,7 +7493,7 @@ static void P_SpawnScrollers(void) case 520: // carry objects on floor dx = FixedMul(dx, CARRYFACTOR); dy = FixedMul(dy, CARRYFACTOR); - TAG_ITER_SECTORS(0, tag, s) + TAG_ITER_SECTORS(tag, s) Add_Scroller(sc_carry, dx, dy, control, s, accel, l->flags & ML_NOCLIMB); break; @@ -7508,7 +7501,7 @@ static void P_SpawnScrollers(void) // (same direction and speed as scrolling floors) case 502: { - TAG_ITER_LINES(0, tag, s) + TAG_ITER_LINES(tag, s) if (s != (INT32)i) { if (l->flags & ML_EFFECT2) // use texture offsets instead @@ -7610,9 +7603,8 @@ void T_Disappear(disappear_t *d) ffloor_t *rover; register INT32 s; mtag_t afftag = Tag_FGet(&lines[d->affectee].tags); - TAG_ITER_DECLARECOUNTER(0); - TAG_ITER_SECTORS(0, afftag, s) + TAG_ITER_SECTORS(afftag, s) { for (rover = sectors[s].ffloors; rover; rover = rover->next) { @@ -8343,7 +8335,6 @@ static void P_SpawnFriction(void) fixed_t strength; // frontside texture offset controls magnitude fixed_t friction; // friction value to be applied during movement INT32 movefactor; // applied to each player move to simulate inertia - TAG_ITER_DECLARECOUNTER(0); for (i = 0; i < numlines; i++, l++) if (l->special == 540) @@ -8369,7 +8360,7 @@ static void P_SpawnFriction(void) else movefactor = FRACUNIT; - TAG_ITER_SECTORS(0, tag, s) + TAG_ITER_SECTORS(tag, s) Add_Friction(friction, movefactor, s, -1); } } @@ -8888,7 +8879,6 @@ static void P_SpawnPushers(void) mtag_t tag; register INT32 s; mobj_t *thing; - TAG_ITER_DECLARECOUNTER(0); for (i = 0; i < numlines; i++, l++) { @@ -8896,15 +8886,15 @@ static void P_SpawnPushers(void) switch (l->special) { case 541: // wind - TAG_ITER_SECTORS(0, tag, s) + TAG_ITER_SECTORS(tag, s) Add_Pusher(p_wind, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4); break; case 544: // current - TAG_ITER_SECTORS(0, tag, s) + TAG_ITER_SECTORS(tag, s) Add_Pusher(p_current, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4); break; case 547: // push/pull - TAG_ITER_SECTORS(0, tag, s) + TAG_ITER_SECTORS(tag, s) { thing = P_GetPushThing(s); if (thing) // No MT_P* means no effect @@ -8912,19 +8902,19 @@ static void P_SpawnPushers(void) } break; case 545: // current up - TAG_ITER_SECTORS(0, tag, s) + TAG_ITER_SECTORS(tag, s) Add_Pusher(p_upcurrent, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4); break; case 546: // current down - TAG_ITER_SECTORS(0, tag, s) + TAG_ITER_SECTORS(tag, s) Add_Pusher(p_downcurrent, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4); break; case 542: // wind up - TAG_ITER_SECTORS(0, tag, s) + TAG_ITER_SECTORS(tag, s) Add_Pusher(p_upwind, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4); break; case 543: // wind down - TAG_ITER_SECTORS(0, tag, s) + TAG_ITER_SECTORS(tag, s) Add_Pusher(p_downwind, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4); break; } diff --git a/src/taglist.h b/src/taglist.h index a0529ab6b..df0606a68 100644 --- a/src/taglist.h +++ b/src/taglist.h @@ -71,15 +71,12 @@ INT32 Tag_Iterate_Things (const mtag_t tag, const size_t p); INT32 Tag_FindLineSpecial(const INT16 special, const mtag_t tag); INT32 P_FindSpecialLineFromTag(INT16 special, INT16 tag, INT32 start); -// Use this macro to declare an iterator position variable. -#define TAG_ITER_DECLARECOUNTER(level) size_t ICNT_##level - -#define TAG_ITER(level, fn, tag, return_varname) for(ICNT_##level = 0; (return_varname = fn(tag, ICNT_##level)) >= 0; ICNT_##level++) +#define TAG_ITER(fn, tag, return_varname) for(size_t ICNT_ ## __LINE__ = 0; (return_varname = fn(tag, ICNT_ ## __LINE__)) >= 0; ICNT_ ## __LINE__++) // Use these macros as wrappers for a taglist iteration. -#define TAG_ITER_SECTORS(level, tag, return_varname) TAG_ITER(level, Tag_Iterate_Sectors, tag, return_varname) -#define TAG_ITER_LINES(level, tag, return_varname) TAG_ITER(level, Tag_Iterate_Lines, tag, return_varname) -#define TAG_ITER_THINGS(level, tag, return_varname) TAG_ITER(level, Tag_Iterate_Things, tag, return_varname) +#define TAG_ITER_SECTORS(tag, return_varname) TAG_ITER(Tag_Iterate_Sectors, tag, return_varname) +#define TAG_ITER_LINES(tag, return_varname) TAG_ITER(Tag_Iterate_Lines, tag, return_varname) +#define TAG_ITER_THINGS(tag, return_varname) TAG_ITER(Tag_Iterate_Things, tag, return_varname) /* ITERATION MACROS TAG_ITER_DECLARECOUNTER must be used before using the iterators. From fbe2a19c6037bc141dbe56304164a6a80de23316 Mon Sep 17 00:00:00 2001 From: Nev3r Date: Thu, 11 Feb 2021 14:12:50 +0100 Subject: [PATCH 259/644] Fix __LINE__ macro expansion via recursive macro expansion; C macros sure are something sometimes... --- src/taglist.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/taglist.h b/src/taglist.h index df0606a68..b02fc34dd 100644 --- a/src/taglist.h +++ b/src/taglist.h @@ -71,7 +71,9 @@ INT32 Tag_Iterate_Things (const mtag_t tag, const size_t p); INT32 Tag_FindLineSpecial(const INT16 special, const mtag_t tag); INT32 P_FindSpecialLineFromTag(INT16 special, INT16 tag, INT32 start); -#define TAG_ITER(fn, tag, return_varname) for(size_t ICNT_ ## __LINE__ = 0; (return_varname = fn(tag, ICNT_ ## __LINE__)) >= 0; ICNT_ ## __LINE__++) +#define ICNAME2(id) ICNT_##id +#define ICNAME(id) ICNAME2(id) +#define TAG_ITER(fn, tag, return_varname) for(size_t ICNAME(__LINE__) = 0; (return_varname = fn(tag, ICNAME(__LINE__))) >= 0; ICNAME(__LINE__)++) // Use these macros as wrappers for a taglist iteration. #define TAG_ITER_SECTORS(tag, return_varname) TAG_ITER(Tag_Iterate_Sectors, tag, return_varname) From a57c695f79de5e863e1c708c340fa30c9735e665 Mon Sep 17 00:00:00 2001 From: Nev3r Date: Thu, 11 Feb 2021 14:22:49 +0100 Subject: [PATCH 260/644] Update example comment. --- src/taglist.h | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/src/taglist.h b/src/taglist.h index b02fc34dd..2dd160c9a 100644 --- a/src/taglist.h +++ b/src/taglist.h @@ -81,14 +81,6 @@ INT32 P_FindSpecialLineFromTag(INT16 special, INT16 tag, INT32 start); #define TAG_ITER_THINGS(tag, return_varname) TAG_ITER(Tag_Iterate_Things, tag, return_varname) /* ITERATION MACROS -TAG_ITER_DECLARECOUNTER must be used before using the iterators. - -'level': -For each nested iteration, an additional TAG_ITER_DECLARECOUNTER -must be used with a different level number to avoid conflict with -the outer iterations. -Most cases don't have nested iterations and thus the level is just 0. - 'tag': Pretty much the elements' tag to iterate through. @@ -98,17 +90,12 @@ Target variable's name to return the iteration results to. EXAMPLE: { - TAG_ITER_DECLARECOUNTER(0); - TAG_ITER_DECLARECOUNTER(1); // For the nested iteration. - size_t li; - size_t sec; - INT32 tag1 = 4; ... - TAG_ITER_LINES(0, tag1, li) + TAG_ITER_LINES(tag1, li) { line_t *line = lines + li; @@ -116,11 +103,11 @@ EXAMPLE: if (something) { + size_t sec; mtag_t tag2 = 8; - // Nested iteration; just make sure the level is higher - // and that it has its own counter declared in scope. - TAG_ITER_SECTORS(1, tag2, sec) + // Nested iteration. + TAG_ITER_SECTORS(tag2, sec) { sector_t *sector = sectors + sec; From 09d911a5b607d889ecd7a6ae182f372badb296b7 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sat, 13 Feb 2021 17:45:20 +0100 Subject: [PATCH 261/644] Revert "Replace all instances of P_AproxDistance with FixedHypot" This reverts commit 75633bde5039106c5f916ca2b4d1bde11d274be9. --- src/b_bot.c | 10 +-- src/g_game.c | 2 +- src/p_ceilng.c | 4 +- src/p_enemy.c | 172 ++++++++++++++++++++++++------------------------ src/p_floor.c | 10 +-- src/p_inter.c | 20 +++--- src/p_map.c | 10 +-- src/p_maputl.h | 1 + src/p_mobj.c | 78 +++++++++++----------- src/p_polyobj.c | 2 +- src/p_setup.c | 2 +- src/p_slopes.c | 2 +- src/p_spec.c | 58 ++++++++-------- src/p_user.c | 56 ++++++++-------- src/r_things.c | 4 +- src/s_sound.c | 4 +- src/st_stuff.c | 2 +- 17 files changed, 219 insertions(+), 218 deletions(-) diff --git a/src/b_bot.c b/src/b_bot.c index abe69caeb..d3635f32c 100644 --- a/src/b_bot.c +++ b/src/b_bot.c @@ -54,11 +54,11 @@ static void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd) boolean _2d = (tails->flags2 & MF2_TWOD) || twodlevel; fixed_t scale = tails->scale; - fixed_t dist = FixedHypot(sonic->x - tails->x, sonic->y - tails->y); + fixed_t dist = P_AproxDistance(sonic->x - tails->x, sonic->y - tails->y); fixed_t zdist = flip * (sonic->z - tails->z); angle_t ang = sonic->angle; - fixed_t pmom = FixedHypot(sonic->momx, sonic->momy); - fixed_t bmom = FixedHypot(tails->momx, tails->momy); + fixed_t pmom = P_AproxDistance(sonic->momx, sonic->momy); + fixed_t bmom = P_AproxDistance(tails->momx, tails->momy); fixed_t followmax = 128 * 8 * scale; // Max follow distance before AI begins to enter "panic" state fixed_t followthres = 92 * scale; // Distance that AI will try to reach fixed_t followmin = 32 * scale; @@ -81,7 +81,7 @@ static void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd) if (tails->player->powers[pw_carry] == CR_MACESPIN || tails->player->powers[pw_carry] == CR_GENERIC) { boolean isrelevant = (sonic->player->powers[pw_carry] == CR_MACESPIN || sonic->player->powers[pw_carry] == CR_GENERIC); - dist = FixedHypot(tails->x-sonic->x, tails->y-sonic->y); + dist = P_AproxDistance(tails->x-sonic->x, tails->y-sonic->y); if (sonic->player->cmd.buttons & BT_JUMP && (sonic->player->pflags & PF_JUMPED) && isrelevant) cmd->buttons |= BT_JUMP; if (isrelevant) @@ -496,7 +496,7 @@ boolean B_CheckRespawn(player_t *player) } // If you can't see Sonic, I guess we should? - if (!P_CheckSight(sonic, tails) && FixedHypot(FixedHypot(tails->x-sonic->x, tails->y-sonic->y), tails->z-sonic->z) > FixedMul(1024*FRACUNIT, tails->scale)) + if (!P_CheckSight(sonic, tails) && P_AproxDistance(P_AproxDistance(tails->x-sonic->x, tails->y-sonic->y), tails->z-sonic->z) > FixedMul(1024*FRACUNIT, tails->scale)) return true; return false; } diff --git a/src/g_game.c b/src/g_game.c index 10bec888f..2b304b4fd 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1423,7 +1423,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) newtarget = P_SpawnMobj(ticcmd_ztargetfocus[forplayer]->x, ticcmd_ztargetfocus[forplayer]->y, ticcmd_ztargetfocus[forplayer]->z, MT_LOCKON); // positioning, flip handled in P_SceneryThinker P_SetTarget(&newtarget->target, ticcmd_ztargetfocus[forplayer]); - if (FixedHypot( + if (P_AproxDistance( player->mo->x - ticcmd_ztargetfocus[forplayer]->x, player->mo->y - ticcmd_ztargetfocus[forplayer]->y ) > 50*player->mo->scale) diff --git a/src/p_ceilng.c b/src/p_ceilng.c index 2168d1d78..f12499d5c 100644 --- a/src/p_ceilng.c +++ b/src/p_ceilng.c @@ -468,7 +468,7 @@ INT32 EV_DoCeiling(line_t *line, ceiling_e type) // Linedef executor excellence case moveCeilingByFrontSector: - ceiling->speed = FixedHypot(line->dx, line->dy); + ceiling->speed = P_AproxDistance(line->dx, line->dy); ceiling->speed = FixedDiv(ceiling->speed,8*FRACUNIT); if (line->frontsector->ceilingheight >= sec->ceilingheight) // Move up { @@ -547,7 +547,7 @@ INT32 EV_DoCeiling(line_t *line, ceiling_e type) */ case bounceCeiling: - ceiling->speed = FixedHypot(line->dx, line->dy); // same speed as elevateContinuous + ceiling->speed = P_AproxDistance(line->dx, line->dy); // same speed as elevateContinuous ceiling->speed = FixedDiv(ceiling->speed,4*FRACUNIT); ceiling->origspeed = ceiling->speed; if (line->frontsector->ceilingheight >= sec->ceilingheight) // Move up diff --git a/src/p_enemy.c b/src/p_enemy.c index 0e20aac10..3e7f52a3f 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -334,7 +334,7 @@ boolean P_CheckMeleeRange(mobj_t *actor) return false; pl = actor->target; - dist = FixedHypot(pl->x-actor->x, pl->y-actor->y); + dist = P_AproxDistance(pl->x-actor->x, pl->y-actor->y); if (dist >= FixedMul(MELEERANGE - 20*FRACUNIT, actor->scale) + pl->radius) return false; @@ -360,7 +360,7 @@ boolean P_JetbCheckMeleeRange(mobj_t *actor) return false; pl = actor->target; - dist = FixedHypot(pl->x-actor->x, pl->y-actor->y); + dist = P_AproxDistance(pl->x-actor->x, pl->y-actor->y); if (dist >= (actor->radius + pl->radius)*2) return false; @@ -389,7 +389,7 @@ boolean P_FaceStabCheckMeleeRange(mobj_t *actor) return false; pl = actor->target; - dist = FixedHypot(pl->x-actor->x, pl->y-actor->y); + dist = P_AproxDistance(pl->x-actor->x, pl->y-actor->y); if (dist >= (actor->radius + pl->radius)*4) return false; @@ -413,7 +413,7 @@ boolean P_SkimCheckMeleeRange(mobj_t *actor) return false; pl = actor->target; - dist = FixedHypot(pl->x-actor->x, pl->y-actor->y); + dist = P_AproxDistance(pl->x-actor->x, pl->y-actor->y); if (dist >= FixedMul(MELEERANGE - 20*FRACUNIT, actor->scale) + pl->radius) return false; @@ -449,7 +449,7 @@ boolean P_CheckMissileRange(mobj_t *actor) return false; // OPTIMIZE: get this from a global checksight - dist = FixedHypot(actor->x-actor->target->x, actor->y-actor->target->y) - FixedMul(64*FRACUNIT, actor->scale); + dist = P_AproxDistance(actor->x-actor->target->x, actor->y-actor->target->y) - FixedMul(64*FRACUNIT, actor->scale); if (!actor->info->meleestate) dist -= FixedMul(128*FRACUNIT, actor->scale); // no melee attack, so fire more @@ -750,7 +750,7 @@ boolean P_LookForPlayers(mobj_t *actor, boolean allaround, boolean tracer, fixed continue; // Ignore uncontrolled bodies if (dist > 0 - && FixedHypot(FixedHypot(player->mo->x - actor->x, player->mo->y - actor->y), player->mo->z - actor->z) > dist) + && P_AproxDistance(P_AproxDistance(player->mo->x - actor->x, player->mo->y - actor->y), player->mo->z - actor->z) > dist) continue; // Too far away if (!allaround) @@ -758,7 +758,7 @@ boolean P_LookForPlayers(mobj_t *actor, boolean allaround, boolean tracer, fixed an = R_PointToAngle2(actor->x, actor->y, player->mo->x, player->mo->y) - actor->angle; if (an > ANGLE_90 && an < ANGLE_270) { - dist = FixedHypot(player->mo->x - actor->x, player->mo->y - actor->y); + dist = P_AproxDistance(player->mo->x - actor->x, player->mo->y - actor->y); // if real close, react anyway if (dist > FixedMul(MELEERANGE, actor->scale)) continue; // behind back @@ -821,7 +821,7 @@ static boolean P_LookForShield(mobj_t *actor) continue; if ((player->powers[pw_shield] & SH_PROTECTELECTRIC) - && (FixedHypot(FixedHypot(actor->x-player->mo->x, actor->y-player->mo->y), actor->z-player->mo->z) < FixedMul(RING_DIST, player->mo->scale))) + && (P_AproxDistance(P_AproxDistance(actor->x-player->mo->x, actor->y-player->mo->y), actor->z-player->mo->z) < FixedMul(RING_DIST, player->mo->scale))) { P_SetTarget(&actor->tracer, player->mo); @@ -1548,8 +1548,8 @@ void A_PointyThink(mobj_t *actor) } else { - if (FixedHypot(players[i].mo->x - actor->x, players[i].mo->y - actor->y) < - FixedHypot(player->mo->x - actor->x, player->mo->y - actor->y)) + if (P_AproxDistance(players[i].mo->x - actor->x, players[i].mo->y - actor->y) < + P_AproxDistance(player->mo->x - actor->x, player->mo->y - actor->y)) player = &players[i]; } } @@ -1561,7 +1561,7 @@ void A_PointyThink(mobj_t *actor) P_SetTarget(&actor->target, player->mo); A_FaceTarget(actor); - if (FixedHypot(player->mo->x - actor->x, player->mo->y - actor->y) < FixedHypot(player->mo->x + player->mo->momx - actor->x, player->mo->y + player->mo->momy - actor->y)) + if (P_AproxDistance(player->mo->x - actor->x, player->mo->y - actor->y) < P_AproxDistance(player->mo->x + player->mo->momx - actor->x, player->mo->y + player->mo->momy - actor->y)) sign = -1; // Player is moving away else sign = 1; // Player is moving closer @@ -1638,7 +1638,7 @@ static void P_ParabolicMove(mobj_t *actor, fixed_t x, fixed_t y, fixed_t z, fixe y -= actor->y; z -= actor->z; - dh = FixedHypot(x, y); + dh = P_AproxDistance(x, y); actor->momx = FixedMul(FixedDiv(x, dh), speed); actor->momy = FixedMul(FixedDiv(y, dh), speed); @@ -1706,7 +1706,7 @@ void A_HoodThink(mobj_t *actor) } dx = (actor->target->x - actor->x), dy = (actor->target->y - actor->y), dz = (actor->target->z - actor->z); - dm = FixedHypot(dx, dy); + dm = P_AproxDistance(dx, dy); // Target dangerously close to robohood, retreat then. if ((dm < 256<target || !crab->info->missilestate || (statenum_t)(crab->state-states) == crab->info->missilestate) return; - if (((ang + ANG1) < ANG2) || FixedHypot(crab->x - crab->target->x, crab->y - crab->target->y) < 333*crab->scale) + if (((ang + ANG1) < ANG2) || P_AproxDistance(crab->x - crab->target->x, crab->y - crab->target->y) < 333*crab->scale) P_SetMobjState(crab, crab->info->missilestate); } @@ -2703,7 +2703,7 @@ void A_LobShot(mobj_t *actor) shot->angle = an = actor->angle; an >>= ANGLETOFINESHIFT; - dist = FixedHypot(actor->target->x - shot->x, actor->target->y - shot->y); + dist = P_AproxDistance(actor->target->x - shot->x, actor->target->y - shot->y); horizontal = dist / airtime; vertical = FixedMul((gravity*airtime)/2, shot->scale); @@ -2721,7 +2721,7 @@ void A_LobShot(mobj_t *actor) diff = actor->z - actor->target->z; { - launchhyp = FixedHypot(horizontal, vertical); + launchhyp = P_AproxDistance(horizontal, vertical); orig = FixedMul(FixedDiv(vertical, horizontal), diff); @@ -3325,7 +3325,7 @@ void A_SkullAttack(mobj_t *actor) S_StartSound(actor, actor->info->activesound); A_FaceTarget(actor); - dist = FixedHypot(dest->x - actor->x, dest->y - actor->y); + dist = P_AproxDistance(dest->x - actor->x, dest->y - actor->y); if (locvar1 == 1) actor->angle += ANGLE_180; @@ -3443,7 +3443,7 @@ void A_BossZoom(mobj_t *actor) an = actor->angle >> ANGLETOFINESHIFT; actor->momx = FixedMul(FixedMul(actor->info->speed*5*FRACUNIT, actor->scale), FINECOSINE(an)); actor->momy = FixedMul(FixedMul(actor->info->speed*5*FRACUNIT, actor->scale), FINESINE(an)); - dist = FixedHypot(dest->x - actor->x, dest->y - actor->y); + dist = P_AproxDistance(dest->x - actor->x, dest->y - actor->y); dist = dist / FixedMul(actor->info->speed*5*FRACUNIT, actor->scale); if (dist < 1) @@ -3599,7 +3599,7 @@ void A_1upThinker(mobj_t *actor) if ((netgame || multiplayer) && players[i].playerstate != PST_LIVE) continue; - temp = FixedHypot(players[i].mo->x-actor->x, players[i].mo->y-actor->y); + temp = P_AproxDistance(players[i].mo->x-actor->x, players[i].mo->y-actor->y); if (temp < dist) { @@ -4144,8 +4144,8 @@ bossjustdie: // If this one's further then the last one, don't go for it. if (mo->target && - FixedHypot(FixedHypot(mo->x - mo2->x, mo->y - mo2->y), mo->z - mo2->z) > - FixedHypot(FixedHypot(mo->x - mo->target->x, mo->y - mo->target->y), mo->z - mo->target->z)) + P_AproxDistance(P_AproxDistance(mo->x - mo2->x, mo->y - mo2->y), mo->z - mo2->z) > + P_AproxDistance(P_AproxDistance(mo->x - mo->target->x, mo->y - mo->target->y), mo->z - mo->target->z)) continue; // Otherwise... Do! @@ -4536,7 +4536,7 @@ void A_BubbleSpawn(mobj_t *actor) // Don't spawn bubbles unless a player is relatively close by (var1). for (i = 0; i < MAXPLAYERS; ++i) if (playeringame[i] && players[i].mo - && FixedHypot(actor->x - players[i].mo->x, actor->y - players[i].mo->y) < (locvar1<x - players[i].mo->x, actor->y - players[i].mo->y) < (locvar1<x - players[i].mo->x, actor->y - players[i].mo->y) < (locvar1<x - players[i].mo->x, actor->y - players[i].mo->y) < (locvar1<x-target->x, actor->y-target->y)>>FRACBITS; + dist = P_AproxDistance(actor->x-target->x, actor->y-target->y)>>FRACBITS; if (dist > FixedMul((locvar2 & 65535), actor->scale)) return; @@ -4800,7 +4800,7 @@ void A_FishJump(mobj_t *actor) // Don't spawn trail unless a player is nearby. for (i = 0; i < MAXPLAYERS; ++i) if (playeringame[i] && players[i].mo - && FixedHypot(actor->x - players[i].mo->x, actor->y - players[i].mo->y) < (actor->info->speed)) + && P_AproxDistance(actor->x - players[i].mo->x, actor->y - players[i].mo->y) < (actor->info->speed)) break; // Stop looking. if (i < MAXPLAYERS) { @@ -4905,7 +4905,7 @@ void A_ThrownRing(mobj_t *actor) // magnetic player. If he gets too far away, make // sure to stop the attraction! if ((!actor->tracer->health) || (actor->tracer->player && (actor->tracer->player->powers[pw_shield] & SH_PROTECTELECTRIC) - && FixedHypot(FixedHypot(actor->tracer->x-actor->x, + && P_AproxDistance(P_AproxDistance(actor->tracer->x-actor->x, actor->tracer->y-actor->y), actor->tracer->z-actor->z) > FixedMul(RING_DIST/4, actor->tracer->scale))) { P_SetTarget(&actor->tracer, NULL); @@ -4964,7 +4964,7 @@ void A_ThrownRing(mobj_t *actor) continue; } - dist = FixedHypot(FixedHypot(player->mo->x-actor->x, + dist = P_AproxDistance(P_AproxDistance(player->mo->x-actor->x, player->mo->y-actor->y), player->mo->z-actor->z); // check distance @@ -5345,7 +5345,7 @@ void A_JetChase(mobj_t *actor) return; // got a new target // If the player is over 3072 fracunits away, then look for another player - if (FixedHypot(FixedHypot(actor->target->x - actor->x, actor->target->y - actor->y), + if (P_AproxDistance(P_AproxDistance(actor->target->x - actor->x, actor->target->y - actor->y), actor->target->z - actor->z) > FixedMul(3072*FRACUNIT, actor->scale) && P_LookForPlayers(actor, true, false, FixedMul(3072*FRACUNIT, actor->scale))) { return; // got a new target @@ -5460,7 +5460,7 @@ void A_JetgShoot(mobj_t *actor) if (actor->reactiontime) return; - dist = FixedHypot(actor->target->x - actor->x, actor->target->y - actor->y); + dist = P_AproxDistance(actor->target->x - actor->x, actor->target->y - actor->y); if (dist > FixedMul(actor->info->painchance*FRACUNIT, actor->scale)) return; @@ -5497,7 +5497,7 @@ void A_ShootBullet(mobj_t *actor) if (!actor->target) return; - dist = FixedHypot(FixedHypot(actor->target->x - actor->x, actor->target->y - actor->y), actor->target->z - actor->z); + dist = P_AproxDistance(P_AproxDistance(actor->target->x - actor->x, actor->target->y - actor->y), actor->target->z - actor->z); if (dist > FixedMul(actor->info->painchance*FRACUNIT, actor->scale)) return; @@ -5522,7 +5522,7 @@ static boolean PIT_MinusCarry(mobj_t *thing) if (!(thing->flags & (MF_PUSHABLE|MF_ENEMY))) return true; - if (FixedHypot(minus->x - thing->x, minus->y - thing->y) >= minus->radius*3) + if (P_AproxDistance(minus->x - thing->x, minus->y - thing->y) >= minus->radius*3) return true; if (abs(thing->z - minus->z) > minus->height) @@ -5566,7 +5566,7 @@ void A_MinusDigging(mobj_t *actor) P_TryMove(par, x, y, false); // If close enough, prepare to attack - if (FixedHypot(actor->x - actor->target->x, actor->y - actor->target->y) < actor->radius*2) + if (P_AproxDistance(actor->x - actor->target->x, actor->y - actor->target->y) < actor->radius*2) { P_SetMobjState(actor, actor->info->meleestate); P_TryMove(actor, actor->target->x, actor->target->y, false); @@ -5858,7 +5858,7 @@ void A_DetonChase(mobj_t *actor) } }*/ // movedir is up/down angle: how much it has to go up as it goes over to the player - xydist = FixedHypot(actor->tracer->x - actor->x, actor->tracer->y - actor->y); + xydist = P_AproxDistance(actor->tracer->x - actor->x, actor->tracer->y - actor->y); exact = R_PointToAngle2(0, 0, xydist, actor->tracer->z - actor->z); actor->movedir = exact; /*if (exact != actor->movedir) @@ -5880,7 +5880,7 @@ void A_DetonChase(mobj_t *actor) // check for melee attack if (actor->tracer) { - if (FixedHypot(actor->tracer->x-actor->x, actor->tracer->y-actor->y) < actor->radius+actor->tracer->radius) + if (P_AproxDistance(actor->tracer->x-actor->x, actor->tracer->y-actor->y) < actor->radius+actor->tracer->radius) { if (!((actor->tracer->z > actor->z + actor->height) || (actor->z > actor->tracer->z + actor->tracer->height))) { @@ -5891,7 +5891,7 @@ void A_DetonChase(mobj_t *actor) } // chase towards player - if ((dist = FixedHypot(xydist, actor->tracer->z-actor->z)) + if ((dist = P_AproxDistance(xydist, actor->tracer->z-actor->z)) > FixedMul((actor->info->painchance << FRACBITS), actor->scale)) { P_SetTarget(&actor->tracer, NULL); // Too far away @@ -5938,7 +5938,7 @@ void A_DetonChase(mobj_t *actor) actor->momy = FixedMul(xyspeed, FINESINE(exact)); // Variable re-use - xyspeed = (FixedHypot(actor->tracer->x - actor->x, FixedHypot(actor->tracer->y - actor->y, actor->tracer->z - actor->z))>>(FRACBITS+6)); + xyspeed = (P_AproxDistance(actor->tracer->x - actor->x, P_AproxDistance(actor->tracer->y - actor->y, actor->tracer->z - actor->z))>>(FRACBITS+6)); if (xyspeed < 1) xyspeed = 1; @@ -6086,7 +6086,7 @@ void A_UnidusBall(mobj_t *actor) if (actor->movecount) { - if (FixedHypot(actor->momx, actor->momy) < FixedMul(actor->info->damage/2, actor->scale)) + if (P_AproxDistance(actor->momx, actor->momy) < FixedMul(actor->info->damage/2, actor->scale)) P_ExplodeMissile(actor); return; } @@ -6118,7 +6118,7 @@ void A_UnidusBall(mobj_t *actor) if (locvar1 == 1 && canthrow) { - if (FixedHypot(actor->target->target->x - actor->target->x, actor->target->target->y - actor->target->y) > FixedMul(MISSILERANGE>>1, actor->scale) + if (P_AproxDistance(actor->target->target->x - actor->target->x, actor->target->target->y - actor->target->y) > FixedMul(MISSILERANGE>>1, actor->scale) || !P_CheckSight(actor, actor->target->target)) return; @@ -6193,7 +6193,7 @@ void A_RockSpawn(mobj_t *actor) return; } - dist = FixedHypot(line->dx, line->dy)/16; + dist = P_AproxDistance(line->dx, line->dy)/16; if (dist < 1) dist = 1; @@ -6359,7 +6359,7 @@ void A_CrawlaCommanderThink(mobj_t *actor) return; } - dist = FixedHypot(actor->x - actor->target->x, actor->y - actor->target->y); + dist = P_AproxDistance(actor->x - actor->target->x, actor->y - actor->target->y); if (actor->target->player && (!hovermode || actor->reactiontime <= 2*TICRATE)) { @@ -6396,7 +6396,7 @@ void A_CrawlaCommanderThink(mobj_t *actor) { fixed_t mom; P_Thrust(actor, actor->angle, 2*actor->scale); - mom = FixedHypot(actor->momx, actor->momy); + mom = P_AproxDistance(actor->momx, actor->momy); if (mom > 20*actor->scale) { mom += 20*actor->scale; @@ -6484,7 +6484,7 @@ void A_RingExplode(mobj_t *actor) if (mo2 == actor) // Don't explode yourself! Endless loop! continue; - if (FixedHypot(FixedHypot(mo2->x - actor->x, mo2->y - actor->y), mo2->z - actor->z) > FixedMul(actor->info->painchance, actor->scale)) + if (P_AproxDistance(P_AproxDistance(mo2->x - actor->x, mo2->y - actor->y), mo2->z - actor->z) > FixedMul(actor->info->painchance, actor->scale)) continue; if (mo2->flags & MF_SHOOTABLE) @@ -7083,7 +7083,7 @@ nomissile: } // chase towards player - if (FixedHypot(actor->target->x-actor->x, actor->target->y-actor->y) > actor->radius+actor->target->radius) + if (P_AproxDistance(actor->target->x-actor->x, actor->target->y-actor->y) > actor->radius+actor->target->radius) { if (--actor->movecount < 0 || !P_Move(actor, actor->info->speed)) P_NewChaseDir(actor); @@ -7322,7 +7322,7 @@ void A_Boss7Chase(mobj_t *actor) // Self-adjust if stuck on the edge if (actor->tracer) { - if (FixedHypot(actor->x - actor->tracer->x, actor->y - actor->tracer->y) > 128*FRACUNIT - actor->radius) + if (P_AproxDistance(actor->x - actor->tracer->x, actor->y - actor->tracer->y) > 128*FRACUNIT - actor->radius) P_InstaThrust(actor, R_PointToAngle2(actor->x, actor->y, actor->tracer->x, actor->tracer->y), FRACUNIT); } @@ -7358,7 +7358,7 @@ void A_Boss7Chase(mobj_t *actor) if (players[i].mo->health <= 0) continue; - if (FixedHypot(players[i].mo->x - actor->x, players[i].mo->y - actor->y) > actor->radius) + if (P_AproxDistance(players[i].mo->x - actor->x, players[i].mo->y - actor->y) > actor->radius) continue; if (players[i].mo->z > actor->z + actor->height - 2*FRACUNIT @@ -7481,7 +7481,7 @@ void A_Boss2PogoSFX(mobj_t *actor) } // Boing! - if (FixedHypot(actor->x-actor->target->x, actor->y-actor->target->y) < FixedMul(256*FRACUNIT, actor->scale)) + if (P_AproxDistance(actor->x-actor->target->x, actor->y-actor->target->y) < FixedMul(256*FRACUNIT, actor->scale)) { actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y); P_InstaThrust(actor, actor->angle, FixedMul(actor->info->speed, actor->scale)); @@ -7514,7 +7514,7 @@ void A_Boss2PogoTarget(mobj_t *actor) return; if (!actor->target || !(actor->target->flags & MF_SHOOTABLE) || (actor->target->player && actor->target->player->powers[pw_flashing]) - || FixedHypot(actor->x-actor->target->x, actor->y-actor->target->y) >= FixedMul(512*FRACUNIT, actor->scale)) + || P_AproxDistance(actor->x-actor->target->x, actor->y-actor->target->y) >= FixedMul(512*FRACUNIT, actor->scale)) { // look for a new target if (P_LookForPlayers(actor, true, false, 512*FRACUNIT)) @@ -7535,7 +7535,7 @@ void A_Boss2PogoTarget(mobj_t *actor) P_InstaThrust(actor, actor->angle+ANGLE_180, FixedMul(FixedMul(actor->info->speed,(locvar2)), actor->scale)); // Move at wandering speed } // Try to land on top of the player. - else if (FixedHypot(actor->x-actor->target->x, actor->y-actor->target->y) < FixedMul(512*FRACUNIT, actor->scale)) + else if (P_AproxDistance(actor->x-actor->target->x, actor->y-actor->target->y) < FixedMul(512*FRACUNIT, actor->scale)) { fixed_t airtime, gravityadd, zoffs, height; @@ -7569,7 +7569,7 @@ void A_Boss2PogoTarget(mobj_t *actor) airtime = FixedDiv((-actor->momz - FixedSqrt(FixedMul(actor->momz,actor->momz)+zoffs)), gravityadd)<<1; // to try and land on their head rather than on their feet actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y); - P_InstaThrust(actor, actor->angle, FixedDiv(FixedHypot(actor->x - actor->target->x, actor->y - actor->target->y), airtime)); + P_InstaThrust(actor, actor->angle, FixedDiv(P_AproxDistance(actor->x - actor->target->x, actor->y - actor->target->y), airtime)); } // Wander semi-randomly towards the player to get closer. else @@ -7640,7 +7640,7 @@ void A_TurretFire(mobj_t *actor) while (P_SupermanLook4Players(actor) && count < MAXPLAYERS) { - if (FixedHypot(actor->x - actor->target->x, actor->y - actor->target->y) < dist) + if (P_AproxDistance(actor->x - actor->target->x, actor->y - actor->target->y) < dist) { actor->flags2 |= MF2_FIRING; actor->extravalue1 = locvar1; @@ -7678,7 +7678,7 @@ void A_SuperTurretFire(mobj_t *actor) while (P_SupermanLook4Players(actor) && count < MAXPLAYERS) { - if (FixedHypot(actor->x - actor->target->x, actor->y - actor->target->y) < dist) + if (P_AproxDistance(actor->x - actor->target->x, actor->y - actor->target->y) < dist) { actor->flags2 |= MF2_FIRING; actor->flags2 |= MF2_SUPERFIRE; @@ -7799,7 +7799,7 @@ void A_BuzzFly(mobj_t *actor) } // If the player is over 3072 fracunits away, then look for another player - if (FixedHypot(FixedHypot(actor->target->x - actor->x, actor->target->y - actor->y), + if (P_AproxDistance(P_AproxDistance(actor->target->x - actor->x, actor->target->y - actor->y), actor->target->z - actor->z) > FixedMul(3072*FRACUNIT, actor->scale)) { if (multiplayer || netgame) @@ -7818,7 +7818,7 @@ void A_BuzzFly(mobj_t *actor) else realspeed = FixedMul(actor->info->speed, actor->scale); - dist = FixedHypot(FixedHypot(actor->target->x - actor->x, + dist = P_AproxDistance(P_AproxDistance(actor->target->x - actor->x, actor->target->y - actor->y), actor->target->z - actor->z); if (dist < 1) @@ -8176,7 +8176,7 @@ void A_Boss3Path(mobj_t *actor) if (actor->target->x == actor->x && actor->target->y == actor->y) { - dist = FixedHypot(FixedHypot(actor->target->x - actor->x, actor->target->y - actor->y), actor->target->z + actor->movefactor - actor->z); + dist = P_AproxDistance(P_AproxDistance(actor->target->x - actor->x, actor->target->y - actor->y), actor->target->z + actor->movefactor - actor->z); if (dist < 1) dist = 1; @@ -9586,7 +9586,7 @@ void A_SetObjectTypeState(mobj_t *actor) if (mo2->type == (mobjtype_t)loc2lw) { - dist = FixedHypot(mo2->x - actor->x, mo2->y - actor->y); + dist = P_AproxDistance(mo2->x - actor->x, mo2->y - actor->y); if (mo2->health > 0) { @@ -10092,9 +10092,9 @@ void A_CheckRange(mobj_t *actor) return; if (!(locvar1 >> 16)) //target - dist = FixedHypot(actor->target->x - actor->x, actor->target->y - actor->y); + dist = P_AproxDistance(actor->target->x - actor->x, actor->target->y - actor->y); else //tracer - dist = FixedHypot(actor->tracer->x - actor->x, actor->tracer->y - actor->y); + dist = P_AproxDistance(actor->tracer->x - actor->x, actor->tracer->y - actor->y); if (dist <= FixedMul((locvar1 & 65535)*FRACUNIT, actor->scale)) P_SetMobjState(actor, locvar2); @@ -10156,16 +10156,16 @@ void A_CheckTrueRange(mobj_t *actor) if (!(locvar1 >> 16)) // target { height = actor->target->z - actor->z; - dist = FixedHypot(actor->target->x - actor->x, actor->target->y - actor->y); + dist = P_AproxDistance(actor->target->x - actor->x, actor->target->y - actor->y); } else // tracer { height = actor->tracer->z - actor->z; - dist = FixedHypot(actor->tracer->x - actor->x, actor->tracer->y - actor->y); + dist = P_AproxDistance(actor->tracer->x - actor->x, actor->tracer->y - actor->y); } - l = FixedHypot(dist, height); + l = P_AproxDistance(dist, height); if (l <= FixedMul((locvar1 & 65535)*FRACUNIT, actor->scale)) P_SetMobjState(actor, locvar2); @@ -10210,7 +10210,7 @@ void A_CheckThingCount(mobj_t *actor) if (mo2->type == (mobjtype_t)loc1up) { - dist = FixedHypot(mo2->x - actor->x, mo2->y - actor->y); + dist = P_AproxDistance(mo2->x - actor->x, mo2->y - actor->y); if (loc2up == 0) count++; @@ -10819,7 +10819,7 @@ void A_HomingChase(mobj_t *actor) actor->angle = R_PointToAngle2(actor->x, actor->y, dest->x, dest->y); - dist = FixedHypot(FixedHypot(dest->x - actor->x, dest->y - actor->y), dest->z - actor->z); + dist = P_AproxDistance(P_AproxDistance(dest->x - actor->x, dest->y - actor->y), dest->z - actor->z); if (dist < 1) dist = 1; @@ -11405,14 +11405,14 @@ void A_BrakLobShot(mobj_t *actor) g = gravity; // Look up distance between actor and its target - x = FixedHypot(actor->target->x - actor->x, actor->target->y - actor->y); + x = P_AproxDistance(actor->target->x - actor->x, actor->target->y - actor->y); if (!aimDirect) { // Distance should actually be a third of the way over x = FixedDiv(x, 3<x + P_ReturnThrustX(actor, actor->angle, x); newTargetY = actor->y + P_ReturnThrustY(actor, actor->angle, x); - x = FixedHypot(newTargetX - actor->x, newTargetY - actor->y); + x = P_AproxDistance(newTargetX - actor->x, newTargetY - actor->y); // Look up height difference between actor and the ground 1/3 of the way to its target y = P_FloorzAtPos(newTargetX, newTargetY, actor->target->z, actor->target->height) - (actor->z + FixedMul(locvar2*FRACUNIT, actor->scale)); } @@ -11764,7 +11764,7 @@ void A_FlickyCenter(mobj_t *actor) P_LookForPlayers(actor, true, false, actor->extravalue1); - if (actor->target && FixedHypot(actor->target->x - originx, actor->target->y - originy) < actor->extravalue1) + if (actor->target && P_AproxDistance(actor->target->x - originx, actor->target->y - originy) < actor->extravalue1) { actor->extravalue2 = 1; P_TeleportMove(actor, actor->target->x, actor->target->y, actor->target->z); @@ -11820,7 +11820,7 @@ void A_FlickyAim(mobj_t *actor) if ((actor->momx == actor->momy && actor->momy == 0) || (actor->target && P_IsFlickyCenter(actor->target->type) && actor->target->extravalue1 && (actor->target->flags & MF_SLIDEME) - && FixedHypot(actor->x - actor->target->x, actor->y - actor->target->y) >= actor->target->extravalue1)) + && P_AproxDistance(actor->x - actor->target->x, actor->y - actor->target->y) >= actor->target->extravalue1)) flickyhitwall = true; P_InternalFlickyBubble(actor); @@ -11842,12 +11842,12 @@ void A_FlickyAim(mobj_t *actor) actor->movedir *= -1; posvar = ((R_PointToAngle2(actor->target->x, actor->target->y, actor->x, actor->y) + actor->movedir*locvar1) >> ANGLETOFINESHIFT) & FINEMASK; - chasevar = FixedSqrt(max(FRACUNIT, FixedHypot(actor->target->x - actor->x, actor->target->y - actor->y) - locvar2)) + locvar2; + chasevar = FixedSqrt(max(FRACUNIT, P_AproxDistance(actor->target->x - actor->x, actor->target->y - actor->y) - locvar2)) + locvar2; chasex = actor->target->x + FixedMul(FINECOSINE(posvar), chasevar); chasey = actor->target->y + FixedMul(FINESINE(posvar), chasevar); - if (FixedHypot(chasex - actor->x, chasey - actor->y)) + if (P_AproxDistance(chasex - actor->x, chasey - actor->y)) actor->angle = R_PointToAngle2(actor->x, actor->y, chasex, chasey); } else if (flickyhitwall) @@ -11889,7 +11889,7 @@ void P_InternalFlickyFly(mobj_t *actor, fixed_t flyspeed, fixed_t targetdist, fi targetdist = 16*FRACUNIT; //Default! if (actor->target && abs(chasez - actor->z) > targetdist) - targetdist = FixedHypot(actor->target->x - actor->x, actor->target->y - actor->y); + targetdist = P_AproxDistance(actor->target->x - actor->x, actor->target->y - actor->y); if (actor->target && P_IsFlickyCenter(actor->target->type) @@ -11967,7 +11967,7 @@ void A_FlickyCoast(mobj_t *actor) actor->momy = (11*actor->momy)/12; actor->momz = (11*actor->momz)/12; - if (FixedHypot(FixedHypot(actor->momx, actor->momy), actor->momz) < locvar1) + if (P_AproxDistance(P_AproxDistance(actor->momx, actor->momy), actor->momz) < locvar1) P_SetMobjState(actor, locvar2); return; @@ -12231,7 +12231,7 @@ void A_Boss5Jump(mobj_t *actor) g = gravity; // Look up distance between actor and its tracer - x = FixedHypot(actor->tracer->x - actor->x, actor->tracer->y - actor->y); + x = P_AproxDistance(actor->tracer->x - actor->x, actor->tracer->y - actor->y); // Look up height difference between actor and its tracer y = actor->tracer->z - actor->z; @@ -12352,7 +12352,7 @@ void A_MineExplode(mobj_t *actor) actor->z+P_RandomRange(((actor->eflags & MFE_UNDERWATER) ? -dist : 0), dist)*FRACUNIT, type); fixed_t dx = b->x - actor->x, dy = b->y - actor->y, dz = b->z - actor->z; - fixed_t dm = FixedHypot(dz, FixedHypot(dy, dx)); + fixed_t dm = P_AproxDistance(dz, P_AproxDistance(dy, dx)); b->momx = FixedDiv(dx, dm)*3; b->momy = FixedDiv(dy, dm)*3; b->momz = FixedDiv(dz, dm)*3; @@ -12384,7 +12384,7 @@ void A_MineRange(mobj_t *actor) if (!actor->target) return; - dm = FixedHypot(actor->z - actor->target->z, FixedHypot(actor->y - actor->target->y, actor->x - actor->target->x)); + dm = P_AproxDistance(actor->z - actor->target->z, P_AproxDistance(actor->y - actor->target->y, actor->x - actor->target->x)); if ((dm>>FRACBITS) < locvar1) P_SetMobjState(actor, actor->info->meleestate); } @@ -12510,7 +12510,7 @@ void A_MultiShotDist(mobj_t *actor) // Don't spawn dust unless a player is relatively close by (var1). for (i = 0; i < MAXPLAYERS; ++i) if (playeringame[i] && players[i].mo - && FixedHypot(actor->x - players[i].mo->x, actor->y - players[i].mo->y) < (1600<x - players[i].mo->x, actor->y - players[i].mo->y) < (1600<tracer && - FixedHypot(FixedHypot(actor->x - mo2->x, actor->y - mo2->y), actor->z - mo2->z) > - FixedHypot(FixedHypot(actor->x - actor->tracer->x, actor->y - actor->tracer->y), actor->z - actor->tracer->z)) + P_AproxDistance(P_AproxDistance(actor->x - mo2->x, actor->y - mo2->y), actor->z - mo2->z) > + P_AproxDistance(P_AproxDistance(actor->x - actor->tracer->x, actor->y - actor->tracer->y), actor->z - actor->tracer->z)) continue; // Otherwise... Do! @@ -13058,7 +13058,7 @@ void A_Boss5CheckOnGround(mobj_t *actor) P_SetMobjState(actor, locvar1); } - if (actor->tracer && FixedHypot(actor->tracer->x - actor->x, actor->tracer->y - actor->y) < 2*actor->radius) + if (actor->tracer && P_AproxDistance(actor->tracer->x - actor->x, actor->tracer->y - actor->y) < 2*actor->radius) { actor->momx = (4*actor->momx)/5; actor->momy = (4*actor->momy)/5; @@ -13518,7 +13518,7 @@ static boolean PIT_TNTExplode(mobj_t *nearby) dx = nearby->x - barrel->x; dy = nearby->y - barrel->y; dz = nearby->z - barrel->z + (nearby->height - barrel->height/2)/2; - dm = FixedHypot(FixedHypot(dx, dy), dz); + dm = P_AproxDistance(P_AproxDistance(dx, dy), dz); if (dm >= exploderadius || !P_CheckSight(barrel, nearby)) // out of range or not visible return true; @@ -13921,7 +13921,7 @@ void A_SnapperThinker(mobj_t *actor) // Look for nearby, valid players to chase angrily at. if ((actor->target || P_LookForPlayers(actor, true, false, 1024*FRACUNIT)) - && FixedHypot(actor->target->x - xs, actor->target->y - ys) < 2048*FRACUNIT + && P_AproxDistance(actor->target->x - xs, actor->target->y - ys) < 2048*FRACUNIT && abs(actor->target->z - actor->z) < 80*FRACUNIT && P_CheckSight(actor, actor->target)) { @@ -13936,7 +13936,7 @@ void A_SnapperThinker(mobj_t *actor) y1 = ys; } - dist = FixedHypot(x1 - x0, y1 - y0); + dist = P_AproxDistance(x1 - x0, y1 - y0); // The snapper either chases what it considers to be a nearby player, or instead decides to go back to its spawnpoint. if (chasing || dist > 32*FRACUNIT) @@ -14121,7 +14121,7 @@ void A_LavafallRocks(mobj_t *actor) // Don't spawn rocks unless a player is relatively close by. for (i = 0; i < MAXPLAYERS; ++i) if (playeringame[i] && players[i].mo - && FixedHypot(actor->x - players[i].mo->x, actor->y - players[i].mo->y) < (actor->info->speed >> 1)) + && P_AproxDistance(actor->x - players[i].mo->x, actor->y - players[i].mo->y) < (actor->info->speed >> 1)) break; // Stop looking. if (i < MAXPLAYERS) @@ -14155,7 +14155,7 @@ void A_LavafallLava(mobj_t *actor) // Don't spawn lava unless a player is nearby. for (i = 0; i < MAXPLAYERS; ++i) if (playeringame[i] && players[i].mo - && FixedHypot(actor->x - players[i].mo->x, actor->y - players[i].mo->y) < (actor->info->speed)) + && P_AproxDistance(actor->x - players[i].mo->x, actor->y - players[i].mo->y) < (actor->info->speed)) break; // Stop looking. if (i >= MAXPLAYERS) @@ -14285,7 +14285,7 @@ void A_RolloutSpawn(mobj_t *actor) if (!(actor->target) || P_MobjWasRemoved(actor->target) - || FixedHypot(actor->x - actor->target->x, actor->y - actor->target->y) > locvar1) + || P_AproxDistance(actor->x - actor->target->x, actor->y - actor->target->y) > locvar1) { actor->target = P_SpawnMobj(actor->x, actor->y, actor->z, locvar2); actor->target->flags2 |= (actor->flags2 & (MF2_AMBUSH | MF2_OBJECTFLIP)) | MF2_SLIDEPUSH; @@ -14313,7 +14313,7 @@ void A_RolloutRock(mobj_t *actor) UINT8 maxframes = actor->info->reactiontime; // number of frames the mobj cycles through fixed_t pi = (22*FRACUNIT/7); fixed_t circumference = FixedMul(2 * pi, actor->radius); // used to calculate when to change frame - fixed_t speed = FixedHypot(actor->momx, actor->momy), topspeed = FixedMul(actor->info->speed, actor->scale); + fixed_t speed = P_AproxDistance(actor->momx, actor->momy), topspeed = FixedMul(actor->info->speed, actor->scale); boolean inwater = actor->eflags & (MFE_TOUCHWATER|MFE_UNDERWATER); if (LUA_CallAction(A_ROLLOUTROCK, actor)) @@ -14355,7 +14355,7 @@ void A_RolloutRock(mobj_t *actor) actor->momy = FixedMul(actor->momy, locvar1); } - speed = FixedHypot(actor->momx, actor->momy); // recalculate speed for visual rolling + speed = P_AproxDistance(actor->momx, actor->momy); // recalculate speed for visual rolling if (speed < actor->scale >> 1) // stop moving if speed is insignificant { @@ -14477,7 +14477,7 @@ void A_DragonSegment(mobj_t *actor) return; } - dist = FixedHypot(FixedHypot(actor->x - target->x, actor->y - target->y), actor->z - target->z); + dist = P_AproxDistance(P_AproxDistance(actor->x - target->x, actor->y - target->y), actor->z - target->z); radius = actor->radius + target->radius; hangle = R_PointToAngle2(target->x, target->y, actor->x, actor->y); zangle = R_PointToAngle2(0, target->z, dist, actor->z); diff --git a/src/p_floor.c b/src/p_floor.c index de8f5d4e8..7c26065b5 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -1164,7 +1164,7 @@ void T_ThwompSector(thwomp_t *thwomp) if (players[i].mo->z > thwomp->sector->ceilingheight) continue; - if (FixedHypot(thwompx - players[i].mo->x, thwompy - players[i].mo->y) > 96*FRACUNIT) + if (P_AproxDistance(thwompx - players[i].mo->x, thwompy - players[i].mo->y) > 96*FRACUNIT) continue; thwomp->direction = -1; @@ -1892,7 +1892,7 @@ void EV_DoFloor(line_t *line, floor_e floortype) // Linedef executor command, linetype 106. // Line length = speed, front sector floor = destination height. case moveFloorByFrontSector: - dofloor->speed = FixedHypot(line->dx, line->dy); + dofloor->speed = P_AproxDistance(line->dx, line->dy); dofloor->speed = FixedDiv(dofloor->speed,8*FRACUNIT); dofloor->floordestheight = line->frontsector->floorheight; @@ -1958,7 +1958,7 @@ void EV_DoFloor(line_t *line, floor_e floortype) // Linetypes 2/3. // Move floor up and down indefinitely like the old elevators. case bounceFloor: - dofloor->speed = FixedHypot(line->dx, line->dy); // same speed as elevateContinuous + dofloor->speed = P_AproxDistance(line->dx, line->dy); // same speed as elevateContinuous dofloor->speed = FixedDiv(dofloor->speed,4*FRACUNIT); dofloor->origspeed = dofloor->speed; // it gets slowed down at the top and bottom dofloor->floordestheight = line->frontsector->floorheight; @@ -2104,7 +2104,7 @@ void EV_DoElevator(line_t *line, elevator_e elevtype, boolean customspeed) case elevateContinuous: if (customspeed) { - elevator->origspeed = FixedHypot(line->dx, line->dy); + elevator->origspeed = P_AproxDistance(line->dx, line->dy); elevator->origspeed = FixedDiv(elevator->origspeed,4*FRACUNIT); elevator->speed = elevator->origspeed; } @@ -2266,7 +2266,7 @@ void EV_CrumbleChain(sector_t *sec, ffloor_t *rover) if (flags & ML_EFFECT1) { - P_InstaThrust(spawned, R_PointToAngle2(sec->soundorg.x, sec->soundorg.y, a, b), FixedDiv(FixedHypot(a - sec->soundorg.x, b - sec->soundorg.y), widthfactor)); + P_InstaThrust(spawned, R_PointToAngle2(sec->soundorg.x, sec->soundorg.y, a, b), FixedDiv(P_AproxDistance(a - sec->soundorg.x, b - sec->soundorg.y), widthfactor)); P_SetObjectMomZ(spawned, FixedDiv((c - bottomz), heightfactor), false); } diff --git a/src/p_inter.c b/src/p_inter.c index be4133af5..e9a16a3dd 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1002,7 +1002,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) x = (x/count)<x - x, special->y - y), special->z - z); + gatherradius = P_AproxDistance(P_AproxDistance(special->x - x, special->y - y), special->z - z); P_RemoveMobj(special); if (player->powers[pw_nights_superloop]) @@ -1028,7 +1028,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) mo2 = (mobj_t *)th; - if (FixedHypot(FixedHypot(mo2->x - x, mo2->y - y), mo2->z - z) > gatherradius) + if (P_AproxDistance(P_AproxDistance(mo2->x - x, mo2->y - y), mo2->z - z) > gatherradius) continue; if (mo2->flags & MF_SHOOTABLE) @@ -1450,8 +1450,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) fixed_t touchx, touchy, touchspeed; angle_t angle; - if (FixedHypot(toucher->x-special->x, toucher->y-special->y) > - FixedHypot((toucher->x-toucher->momx)-special->x, (toucher->y-toucher->momy)-special->y)) + if (P_AproxDistance(toucher->x-special->x, toucher->y-special->y) > + P_AproxDistance((toucher->x-toucher->momx)-special->x, (toucher->y-toucher->momy)-special->y)) { touchx = toucher->x + toucher->momx; touchy = toucher->y + toucher->momy; @@ -1463,7 +1463,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) } angle = R_PointToAngle2(special->x, special->y, touchx, touchy); - touchspeed = FixedHypot(toucher->momx, toucher->momy); + touchspeed = P_AproxDistance(toucher->momx, toucher->momy); toucher->momx = P_ReturnThrustX(special, angle, touchspeed); toucher->momy = P_ReturnThrustY(special, angle, touchspeed); @@ -1509,7 +1509,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) case MT_EGGSHIELD: { angle_t angle = R_PointToAngle2(special->x, special->y, toucher->x, toucher->y) - special->angle; - fixed_t touchspeed = FixedHypot(toucher->momx, toucher->momy); + fixed_t touchspeed = P_AproxDistance(toucher->momx, toucher->momy); if (touchspeed < special->scale) touchspeed = special->scale; @@ -1590,7 +1590,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) { special->momx = toucher->momx; special->momy = toucher->momy; - special->momz = FixedHypot(toucher->momx, toucher->momy)/4; + special->momz = P_AproxDistance(toucher->momx, toucher->momy)/4; if (toucher->momz > 0) special->momz += toucher->momz/8; @@ -1762,7 +1762,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) toucher->momx = toucher->tracer->momx/2; toucher->momy = toucher->tracer->momy/2; - toucher->momz = toucher->tracer->momz + FixedHypot(toucher->tracer->momx, toucher->tracer->momy)/2; + toucher->momz = toucher->tracer->momz + P_AproxDistance(toucher->tracer->momx, toucher->tracer->momy)/2; P_ResetPlayer(player); player->pflags &= ~PF_APPLYAUTOBRAKE; P_SetPlayerMobjState(toucher, S_PLAY_FALL); @@ -2666,7 +2666,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget case MT_BUGGLE: if (inflictor && inflictor->player // did a player kill you? Spawn relative to the player so they're bound to get it - && FixedHypot(inflictor->x - target->x, inflictor->y - target->y) <= inflictor->radius + target->radius + FixedMul(8*FRACUNIT, inflictor->scale) // close enough? + && P_AproxDistance(inflictor->x - target->x, inflictor->y - target->y) <= inflictor->radius + target->radius + FixedMul(8*FRACUNIT, inflictor->scale) // close enough? && inflictor->z <= target->z + target->height + FixedMul(8*FRACUNIT, inflictor->scale) && inflictor->z + inflictor->height >= target->z - FixedMul(8*FRACUNIT, inflictor->scale)) mo = P_SpawnMobj(inflictor->x + inflictor->momx, inflictor->y + inflictor->momy, inflictor->z + (inflictor->height / 2) + inflictor->momz, MT_EXTRALARGEBUBBLE); @@ -3305,7 +3305,7 @@ static void P_SuperDamage(player_t *player, mobj_t *inflictor, mobj_t *source, I // to recover if (inflictor->flags2 & MF2_SCATTER && source) { - fixed_t dist = FixedHypot(FixedHypot(source->x-player->mo->x, source->y-player->mo->y), source->z-player->mo->z); + fixed_t dist = P_AproxDistance(P_AproxDistance(source->x-player->mo->x, source->y-player->mo->y), source->z-player->mo->z); dist = FixedMul(128*FRACUNIT, inflictor->scale) - dist/4; diff --git a/src/p_map.c b/src/p_map.c index b4fa2e9e0..a1cad524e 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -776,7 +776,7 @@ static boolean PIT_CheckThing(mobj_t *thing) if (thing->flags & MF_SOLID) S_StartSound(tmthing, thing->info->deathsound); for (iter = thing->subsector->sector->thinglist; iter; iter = iter->snext) - if (iter->type == thing->type && iter->health > 0 && iter->flags & MF_SOLID && (iter == thing || FixedHypot(FixedHypot(thing->x - iter->x, thing->y - iter->y), thing->z - iter->z) < 56*thing->scale))//FixedMul(56*FRACUNIT, thing->scale)) + if (iter->type == thing->type && iter->health > 0 && iter->flags & MF_SOLID && (iter == thing || P_AproxDistance(P_AproxDistance(thing->x - iter->x, thing->y - iter->y), thing->z - iter->z) < 56*thing->scale))//FixedMul(56*FRACUNIT, thing->scale)) P_KillMobj(iter, tmthing, tmthing, 0); } else @@ -815,7 +815,7 @@ static boolean PIT_CheckThing(mobj_t *thing) if (thing->flags & MF_SOLID) S_StartSound(tmthing, thing->info->deathsound); for (iter = thing->subsector->sector->thinglist; iter; iter = iter->snext) - if (iter->type == thing->type && iter->health > 0 && iter->flags & MF_SOLID && (iter == thing || FixedHypot(FixedHypot(thing->x - iter->x, thing->y - iter->y), thing->z - iter->z) < 56*thing->scale))//FixedMul(56*FRACUNIT, thing->scale)) + if (iter->type == thing->type && iter->health > 0 && iter->flags & MF_SOLID && (iter == thing || P_AproxDistance(P_AproxDistance(thing->x - iter->x, thing->y - iter->y), thing->z - iter->z) < 56*thing->scale))//FixedMul(56*FRACUNIT, thing->scale)) P_KillMobj(iter, tmthing, tmthing, 0); return true; } @@ -3063,7 +3063,7 @@ static void P_HitCameraSlideLine(line_t *ld, camera_t *thiscam) lineangle >>= ANGLETOFINESHIFT; deltaangle >>= ANGLETOFINESHIFT; - movelen = FixedHypot(tmxmove, tmymove); + movelen = P_AproxDistance(tmxmove, tmymove); newlen = FixedMul(movelen, FINECOSINE(deltaangle)); tmxmove = FixedMul(newlen, FINECOSINE(lineangle)); @@ -3149,7 +3149,7 @@ static void P_HitBounceLine(line_t *ld) lineangle >>= ANGLETOFINESHIFT; deltaangle >>= ANGLETOFINESHIFT; - movelen = FixedHypot(tmxmove, tmymove); + movelen = P_AproxDistance(tmxmove, tmymove); tmxmove = FixedMul(movelen, FINECOSINE(deltaangle)); tmymove = FixedMul(movelen, FINESINE(deltaangle)); @@ -4076,7 +4076,7 @@ static boolean PIT_RadiusAttack(mobj_t *thing) dy = abs(thing->y - bombspot->y); dz = abs(thing->z + (thing->height>>1) - bombspot->z); - dist = FixedHypot(FixedHypot(dx, dy), dz); + dist = P_AproxDistance(P_AproxDistance(dx, dy), dz); dist -= thing->radius; if (dist < 0) diff --git a/src/p_maputl.h b/src/p_maputl.h index 9bc00fa17..df90ab4b4 100644 --- a/src/p_maputl.h +++ b/src/p_maputl.h @@ -41,6 +41,7 @@ typedef boolean (*traverser_t)(intercept_t *in); boolean P_PathTraverse(fixed_t px1, fixed_t py1, fixed_t px2, fixed_t py2, INT32 pflags, traverser_t ptrav); +#define P_AproxDistance(dx, dy) FixedHypot(dx, dy) void P_ClosestPointOnLine(fixed_t x, fixed_t y, line_t *line, vertex_t *result); void P_ClosestPointOnLine3D(const vector3_t *p, const vector3_t *line, vector3_t *result); INT32 P_PointOnLineSide(fixed_t x, fixed_t y, line_t *line); diff --git a/src/p_mobj.c b/src/p_mobj.c index 69eecd26d..49db6daee 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1736,7 +1736,7 @@ static void P_PushableCheckBustables(mobj_t *mo) // Run a linedef executor?? if (rover->master->flags & ML_EFFECT5) - P_LinedefExecute((INT16)(FixedHypot(rover->master->dx, rover->master->dy)>>FRACBITS), mo, node->m_sector); + P_LinedefExecute((INT16)(P_AproxDistance(rover->master->dx, rover->master->dy)>>FRACBITS), mo, node->m_sector); goto bustupdone; } @@ -2512,7 +2512,7 @@ boolean P_ZMovement(mobj_t *mo) // float down towards target if too close if (!(mo->flags2 & MF2_SKULLFLY) && !(mo->flags2 & MF2_INFLOAT)) { - dist = FixedHypot(mo->x - mo->target->x, mo->y - mo->target->y); + dist = P_AproxDistance(mo->x - mo->target->x, mo->y - mo->target->y); delta = (mo->target->z + (mo->height>>1)) - mo->z; @@ -3665,11 +3665,11 @@ boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled P_ResetCamera(player, thiscam); else { - fixed_t camspeed = FixedHypot(thiscam->momx, thiscam->momy); + fixed_t camspeed = P_AproxDistance(thiscam->momx, thiscam->momy); P_SlideCameraMove(thiscam); - if (!resetcalled && FixedHypot(thiscam->momx, thiscam->momy) == camspeed) + if (!resetcalled && P_AproxDistance(thiscam->momx, thiscam->momy) == camspeed) { P_ResetCamera(player, thiscam); resetcalled = true; @@ -4152,7 +4152,7 @@ boolean P_BossTargetPlayer(mobj_t *actor, boolean closest) if (closest) { - dist = FixedHypot(actor->x - player->mo->x, actor->y - player->mo->y); + dist = P_AproxDistance(actor->x - player->mo->x, actor->y - player->mo->y); if (!lastdist || dist < lastdist) { lastdist = dist+1; @@ -4521,7 +4521,7 @@ static void P_Boss3Thinker(mobj_t *mobj) if (mobj->tracer->x == mobj->x && mobj->tracer->y == mobj->y) { // apply ambush for old routing, otherwise whack a mole only - dist = FixedHypot(FixedHypot(mobj->tracer->x - mobj->x, mobj->tracer->y - mobj->y), mobj->tracer->z + mobj->movefactor - mobj->z); + dist = P_AproxDistance(P_AproxDistance(mobj->tracer->x - mobj->x, mobj->tracer->y - mobj->y), mobj->tracer->z + mobj->movefactor - mobj->z); if (dist < 1) dist = 1; @@ -5045,7 +5045,7 @@ static void P_Boss5Thinker(mobj_t *mobj) } if (mobj->state == &states[mobj->info->xdeathstate]) mobj->momz -= (2*FRACUNIT)/3; - else if (mobj->tracer && FixedHypot(mobj->tracer->x - mobj->x, mobj->tracer->y - mobj->y) < 2*mobj->radius) + else if (mobj->tracer && P_AproxDistance(mobj->tracer->x - mobj->x, mobj->tracer->y - mobj->y) < 2*mobj->radius) mobj->flags &= ~MF_NOCLIP; } else @@ -5171,7 +5171,7 @@ static void P_Boss7Thinker(mobj_t *mobj) if (players[i].mo->health <= 0) continue; - if (FixedHypot(players[i].mo->x - mobj->x, players[i].mo->y - mobj->y) > (mobj->radius + players[i].mo->radius)) + if (P_AproxDistance(players[i].mo->x - mobj->x, players[i].mo->y - mobj->y) > (mobj->radius + players[i].mo->radius)) continue; if (players[i].mo->z > mobj->z + mobj->height - FRACUNIT @@ -5275,7 +5275,7 @@ static void P_Boss7Thinker(mobj_t *mobj) if (mobj->health <= mobj->info->damage && !(mo2->spawnpoint->options & 7)) continue; // don't jump to center - dist = FixedHypot(players[i].mo->x - mo2->x, players[i].mo->y - mo2->y); + dist = P_AproxDistance(players[i].mo->x - mo2->x, players[i].mo->y - mo2->y); if (!(closestNum == -1 || dist < closestdist)) continue; @@ -5348,7 +5348,7 @@ static void P_Boss7Thinker(mobj_t *mobj) an = mobj->angle; an >>= ANGLETOFINESHIFT; - dist = FixedHypot(hitspot->x - mobj->x, hitspot->y - mobj->y); + dist = P_AproxDistance(hitspot->x - mobj->x, hitspot->y - mobj->y); horizontal = dist / airtime; vertical = (gravity*airtime)/2; @@ -5399,7 +5399,7 @@ static void P_Boss7Thinker(mobj_t *mobj) if (players[i].mo->health <= 0) continue; - if (FixedHypot(players[i].mo->x - mobj->x, players[i].mo->y - mobj->y) > mobj->radius*4) + if (P_AproxDistance(players[i].mo->x - mobj->x, players[i].mo->y - mobj->y) > mobj->radius*4) continue; if (players[i].mo->z > mobj->z + 128*FRACUNIT) @@ -5653,14 +5653,14 @@ static void P_Boss9Thinker(mobj_t *mobj) // Spawn energy particles for (spawner = mobj->hnext; spawner; spawner = spawner->hnext) { - dist = FixedHypot(spawner->x - mobj->x, spawner->y - mobj->y); + dist = P_AproxDistance(spawner->x - mobj->x, spawner->y - mobj->y); if (P_RandomRange(1,(dist>>FRACBITS)/16) == 1) break; } if (spawner && dist) { mobj_t *missile = P_SpawnMissile(spawner, mobj, MT_MSGATHER); - missile->fuse = (dist/FixedHypot(missile->momx, missile->momy)); + missile->fuse = (dist/P_AproxDistance(missile->momx, missile->momy)); if (missile->fuse > mobj->fuse) P_RemoveMobj(missile); @@ -6092,7 +6092,7 @@ nodanger: mobj->flags2 |= MF2_INVERTAIMABLE; // Move normally: Approach the player using normal thrust and simulated friction. - dist = FixedHypot(mobj->x-mobj->target->x, mobj->y-mobj->target->y); + dist = P_AproxDistance(mobj->x-mobj->target->x, mobj->y-mobj->target->y); P_Thrust(mobj, R_PointToAngle2(0, 0, mobj->momx, mobj->momy), -3*FRACUNIT/8); if (dist < 64*FRACUNIT && !(mobj->target->player && mobj->target->player->homing)) P_Thrust(mobj, mobj->angle, -4*FRACUNIT); @@ -6100,7 +6100,7 @@ nodanger: P_Thrust(mobj, mobj->angle, FRACUNIT); else P_Thrust(mobj, mobj->angle + ANGLE_90, FINECOSINE((((angle_t)(leveltime*ANG1))>>ANGLETOFINESHIFT) & FINEMASK)>>1); - mobj->momz += FixedHypot(mobj->momx, mobj->momy)/12; // Move up higher the faster you're going. + mobj->momz += P_AproxDistance(mobj->momx, mobj->momy)/12; // Move up higher the faster you're going. } } } @@ -6306,7 +6306,7 @@ void P_SpawnParaloop(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 numb mobj->angle = R_PointToAngle2(mobj->x, mobj->y, x, y); // change slope - dist = FixedHypot(FixedHypot(x - mobj->x, y - mobj->y), z - mobj->z); + dist = P_AproxDistance(P_AproxDistance(x - mobj->x, y - mobj->y), z - mobj->z); if (dist < 1) dist = 1; @@ -6380,7 +6380,7 @@ void P_Attract(mobj_t *source, mobj_t *dest, boolean nightsgrab) // Home in on y fixed_t tx = dest->x; fixed_t ty = dest->y; fixed_t tz = dest->z + (dest->height/2); // Aim for center - fixed_t xydist = FixedHypot(tx - source->x, ty - source->y); + fixed_t xydist = P_AproxDistance(tx - source->x, ty - source->y); if (!dest || dest->health <= 0 || !dest->player || !source->tracer) return; @@ -6389,7 +6389,7 @@ void P_Attract(mobj_t *source, mobj_t *dest, boolean nightsgrab) // Home in on y source->angle = R_PointToAngle2(source->x, source->y, tx, ty); // change slope - dist = FixedHypot(xydist, tz - source->z); + dist = P_AproxDistance(xydist, tz - source->z); if (dist < 1) dist = 1; @@ -6415,9 +6415,9 @@ void P_Attract(mobj_t *source, mobj_t *dest, boolean nightsgrab) // Home in on y else { if (nightsgrab) - speedmul = FixedHypot(dest->momx, dest->momy) + FixedMul(8*FRACUNIT, source->scale); + speedmul = P_AproxDistance(dest->momx, dest->momy) + FixedMul(8*FRACUNIT, source->scale); else - speedmul = FixedHypot(dest->momx, dest->momy) + FixedMul(source->info->speed, source->scale); + speedmul = P_AproxDistance(dest->momx, dest->momy) + FixedMul(source->info->speed, source->scale); source->momx = FixedMul(FixedDiv(tx - source->x, dist), speedmul); source->momy = FixedMul(FixedDiv(ty - source->y, dist), speedmul); @@ -6425,7 +6425,7 @@ void P_Attract(mobj_t *source, mobj_t *dest, boolean nightsgrab) // Home in on y } // Instead of just unsetting NOCLIP like an idiot, let's check the distance to our target. - ndist = FixedHypot(FixedHypot(tx - (source->x+source->momx), + ndist = P_AproxDistance(P_AproxDistance(tx - (source->x+source->momx), ty - (source->y+source->momy)), tz - (source->z+source->momz)); @@ -7076,7 +7076,7 @@ static void P_MaceSceneryThink(mobj_t *mobj) // The below is selected based on CEZ2's first room. I promise you it is a coincidence that it looks like the weed number. for (i = 0; i < MAXPLAYERS; ++i) if (playeringame[i] && players[i].mo - && FixedHypot(FixedHypot(mobj->x - players[i].mo->x, mobj->y - players[i].mo->y), mobj->z - players[i].mo->z) < (4200 << FRACBITS)) + && P_AproxDistance(P_AproxDistance(mobj->x - players[i].mo->x, mobj->y - players[i].mo->y), mobj->z - players[i].mo->z) < (4200 << FRACBITS)) break; // Stop looking. if (i == MAXPLAYERS) { @@ -8052,7 +8052,7 @@ static boolean P_MobjBossThink(mobj_t *mobj) { if (mobj->target) { - mobj->momz = FixedMul(FixedDiv(mobj->target->z - mobj->z, FixedHypot(mobj->x - mobj->target->x, mobj->y - mobj->target->y)), mobj->scale << 1); + mobj->momz = FixedMul(FixedDiv(mobj->target->z - mobj->z, P_AproxDistance(mobj->x - mobj->target->x, mobj->y - mobj->target->y)), mobj->scale << 1); mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x, mobj->target->y); } else @@ -8296,7 +8296,7 @@ static void P_ArrowThink(mobj_t *mobj) 0------dist(momx,momy) */ - fixed_t dist = FixedHypot(mobj->momx, mobj->momy); + fixed_t dist = P_AproxDistance(mobj->momx, mobj->momy); angle_t angle = R_PointToAngle2(0, 0, dist, mobj->momz); if (angle > ANG20 && angle <= ANGLE_180) @@ -8578,7 +8578,7 @@ static boolean P_EggRobo1Think(mobj_t *mobj) continue; if (players[i].mo->z + players[i].mo->height < mobj->z - 8*mobj->scale) continue; - compdist = FixedHypot( + compdist = P_AproxDistance( players[i].mo->x + players[i].mo->momx - basex, players[i].mo->y + players[i].mo->momy - basey); if (compdist >= dist) @@ -8593,7 +8593,7 @@ static boolean P_EggRobo1Think(mobj_t *mobj) mobj->frame = 3 + ((leveltime & 2) >> 1); mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x, mobj->target->y); - if (FixedHypot( + if (P_AproxDistance( mobj->x - basex, mobj->y - basey) < mobj->scale) @@ -8624,7 +8624,7 @@ static boolean P_EggRobo1Think(mobj_t *mobj) if (!didmove) { - if (FixedHypot(mobj->x - basex, mobj->y - basey) < mobj->scale) + if (P_AproxDistance(mobj->x - basex, mobj->y - basey) < mobj->scale) P_TeleportMove(mobj, basex, basey, mobj->z); else P_TeleportMove(mobj, @@ -9014,7 +9014,7 @@ static void P_PyreFlyThink(mobj_t *mobj) { //Aim for player z position. If too close to floor/ceiling, aim just above/below them. fixed_t destz = min(max(mobj->target->z, mobj->target->floorz + 70*FRACUNIT), mobj->target->ceilingz - 80*FRACUNIT - mobj->height); - fixed_t dist = FixedHypot(hdist, destz - mobj->z); + fixed_t dist = P_AproxDistance(hdist, destz - mobj->z); P_InstaThrust(mobj, R_PointToAngle2(mobj->x, mobj->y, mobj->target->x, mobj->target->y), 2*FRACUNIT); mobj->momz = FixedMul(FixedDiv(destz - mobj->z, dist), 2*FRACUNIT); } @@ -9116,7 +9116,7 @@ static void P_PterabyteThink(mobj_t *mobj) var1 = 2*mobj->info->speed; var2 = 1; A_HomingChase(mobj); - if (FixedHypot(mobj->x - mobj->tracer->x, mobj->y - mobj->tracer->y) <= mobj->info->speed) + if (P_AproxDistance(mobj->x - mobj->tracer->x, mobj->y - mobj->tracer->y) <= mobj->info->speed) { mobj->extravalue1 -= 2; mobj->momx = mobj->momy = mobj->momz = 0; @@ -9141,7 +9141,7 @@ static void P_DragonbomberThink(mobj_t *mobj) { mobj_t *mine = P_SpawnMobjFromMobj(segment, 0, 0, 0, segment->info->painchance); mine->angle = segment->angle; - P_InstaThrust(mine, mobj->angle, FixedHypot(mobj->momx, mobj->momy) >> 1); + P_InstaThrust(mine, mobj->angle, P_AproxDistance(mobj->momx, mobj->momy) >> 1); P_SetObjectMomZ(mine, -2*FRACUNIT, true); S_StartSound(mine, mine->info->seesound); P_SetMobjState(segment, segment->info->raisestate); @@ -9151,7 +9151,7 @@ static void P_DragonbomberThink(mobj_t *mobj) } if (mobj->target) // Are we chasing a player? { - fixed_t dist = FixedHypot(mobj->x - mobj->target->x, mobj->y - mobj->target->y); + fixed_t dist = P_AproxDistance(mobj->x - mobj->target->x, mobj->y - mobj->target->y); if (dist > 2000*mobj->scale) // Not anymore! P_SetTarget(&mobj->target, NULL); else @@ -9259,7 +9259,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) mobj->eflags |= MFE_UNDERWATER; //P_MobjCheckWater(mobj); // solely for MFE_UNDERWATER for A_FlickySpawn { if (mobj->tracer && mobj->tracer->player && mobj->tracer->health > 0 - && FixedHypot(FixedHypot(mobj->tracer->x - mobj->x, mobj->tracer->y - mobj->y), mobj->tracer->z - mobj->z) <= mobj->radius*16) + && P_AproxDistance(P_AproxDistance(mobj->tracer->x - mobj->x, mobj->tracer->y - mobj->y), mobj->tracer->z - mobj->z) <= mobj->radius*16) { var1 = mobj->info->speed; var2 = 1; @@ -9394,7 +9394,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) if (playeringame[i] && players[i].mo && players[i].mare == mobj->threshold && players[i].spheres > 0) { - fixed_t dist = FixedHypot(players[i].mo->x - mobj->x, players[i].mo->y - mobj->y); + fixed_t dist = P_AproxDistance(players[i].mo->x - mobj->x, players[i].mo->y - mobj->y); if (dist < shortest) { P_SetTarget(&mobj->target, players[i].mo); @@ -9425,7 +9425,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) P_KoopaThinker(mobj); break; case MT_FIREBALL: - if (FixedHypot(mobj->momx, mobj->momy) <= 16*FRACUNIT) // Once fireballs lose enough speed, kill them + if (P_AproxDistance(mobj->momx, mobj->momy) <= 16*FRACUNIT) // Once fireballs lose enough speed, kill them { P_KillMobj(mobj, NULL, NULL, 0); return false; @@ -13530,7 +13530,7 @@ mobj_t *P_SpawnXYZMissile(mobj_t *source, mobj_t *dest, mobjtype_t type, th->momx = FixedMul(speed, FINECOSINE(an)); th->momy = FixedMul(speed, FINESINE(an)); - dist = FixedHypot(dest->x - x, dest->y - y); + dist = P_AproxDistance(dest->x - x, dest->y - y); dist = dist / speed; if (dist < 1) @@ -13592,7 +13592,7 @@ mobj_t *P_SpawnAlteredDirectionMissile(mobj_t *source, mobjtype_t type, fixed_t th->momx = FixedMul(speed, FINECOSINE(an)); th->momy = FixedMul(speed, FINESINE(an)); - dist = FixedHypot(source->momx*800, source->momy*800); + dist = P_AproxDistance(source->momx*800, source->momy*800); dist = dist / speed; if (dist < 1) @@ -13657,7 +13657,7 @@ mobj_t *P_SpawnPointMissile(mobj_t *source, fixed_t xa, fixed_t ya, fixed_t za, th->momx = FixedMul(speed, FINECOSINE(an)); th->momy = FixedMul(speed, FINESINE(an)); - dist = FixedHypot(xa - x, ya - y); + dist = P_AproxDistance(xa - x, ya - y); dist = dist / speed; if (dist < 1) @@ -13737,9 +13737,9 @@ mobj_t *P_SpawnMissile(mobj_t *source, mobj_t *dest, mobjtype_t type) th->momy = FixedMul(speed, FINESINE(an)); if (type == MT_TURRETLASER || type == MT_ENERGYBALL) // More accurate! - dist = FixedHypot(dest->x+(dest->momx*gsf) - source->x, dest->y+(dest->momy*gsf) - source->y); + dist = P_AproxDistance(dest->x+(dest->momx*gsf) - source->x, dest->y+(dest->momy*gsf) - source->y); else - dist = FixedHypot(dest->x - source->x, dest->y - source->y); + dist = P_AproxDistance(dest->x - source->x, dest->y - source->y); dist = dist / speed; diff --git a/src/p_polyobj.c b/src/p_polyobj.c index 95734ff86..874edbd50 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -1636,7 +1636,7 @@ void T_PolyObjWaypoint(polywaypoint_t *th) distx = target->x - pox; disty = target->y - poy; distz = target->z - poz; - dist = FixedHypot(FixedHypot(distx, disty), distz); + dist = P_AproxDistance(P_AproxDistance(distx, disty), distz); if (dist < 1) dist = 1; diff --git a/src/p_setup.c b/src/p_setup.c index 2c0b84ba6..66243fb0e 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -232,7 +232,7 @@ mobj_t *P_GetClosestWaypoint(UINT8 sequence, mobj_t *mo) if (!mo2) continue; - curdist = FixedHypot(FixedHypot(mo->x - mo2->x, mo->y - mo2->y), mo->z - mo2->z); + curdist = P_AproxDistance(P_AproxDistance(mo->x - mo2->x, mo->y - mo2->y), mo->z - mo2->z); if (result && curdist > bestdist) continue; diff --git a/src/p_slopes.c b/src/p_slopes.c index d77d0805f..aa46a8402 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -885,7 +885,7 @@ void P_ButteredSlope(mobj_t *mo) } if (mo->momx || mo->momy) // Slightly increase thrust based on the object's speed - thrust = FixedMul(thrust, FRACUNIT+FixedHypot(mo->momx, mo->momy)/16); + thrust = FixedMul(thrust, FRACUNIT+P_AproxDistance(mo->momx, mo->momy)/16); // This makes it harder to zigzag up steep slopes, as well as allows greater top speed when rolling down // Let's get the gravity strength for the object... diff --git a/src/p_spec.c b/src/p_spec.c index eb14f8dd6..226e58d15 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1240,7 +1240,7 @@ static boolean PolyFlag(line_t *line) polyflagdata_t pfd; pfd.polyObjNum = Tag_FGet(&line->tags); - pfd.speed = FixedHypot(line->dx, line->dy) >> FRACBITS; + pfd.speed = P_AproxDistance(line->dx, line->dy) >> FRACBITS; pfd.angle = R_PointToAngle2(line->v1->x, line->v1->y, line->v2->x, line->v2->y) >> ANGLETOFINESHIFT; pfd.momx = sides[line->sidenum[0]].textureoffset >> FRACBITS; @@ -1567,7 +1567,7 @@ static boolean P_CheckNightsTriggerLine(line_t *triggerline, mobj_t *actor) boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller) { sector_t *ctlsector; - fixed_t dist = FixedHypot(triggerline->dx, triggerline->dy)>>FRACBITS; + fixed_t dist = P_AproxDistance(triggerline->dx, triggerline->dy)>>FRACBITS; size_t i, linecnt, sectori; INT16 specialtype = triggerline->special; @@ -2629,7 +2629,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) sectors[secnum].lightlevel = line->backsector->lightlevel; flick = P_SpawnAdjustableFireFlicker(line->frontsector, §ors[secnum], - FixedHypot(line->dx, line->dy)>>FRACBITS); + P_AproxDistance(line->dx, line->dy)>>FRACBITS); // Make sure the starting light level is in range. if (reallightlevel < flick->minlight) @@ -2644,7 +2644,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) // Use front sector for min, target sector for max, // the same way linetype 61 does it. P_SpawnAdjustableFireFlicker(line->frontsector, §ors[secnum], - FixedHypot(line->dx, line->dy)>>FRACBITS); + P_AproxDistance(line->dx, line->dy)>>FRACBITS); } } break; @@ -2663,7 +2663,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) sectors[secnum].lightlevel = line->backsector->lightlevel; glow = P_SpawnAdjustableGlowingLight(line->frontsector, §ors[secnum], - FixedHypot(line->dx, line->dy)>>FRACBITS); + P_AproxDistance(line->dx, line->dy)>>FRACBITS); // Make sure the starting light level is in range. if (reallightlevel < glow->minlight) @@ -2678,7 +2678,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) // Use front sector for min, target sector for max, // the same way linetype 602 does it. P_SpawnAdjustableGlowingLight(line->frontsector, §ors[secnum], - FixedHypot(line->dx, line->dy)>>FRACBITS); + P_AproxDistance(line->dx, line->dy)>>FRACBITS); } } break; @@ -2760,7 +2760,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) ((line->sidenum[1] != 0xFFFF && !(sides[line->sidenum[0]].rowoffset>>FRACBITS)) ? max(min(sides[line->sidenum[1]].rowoffset>>FRACBITS, 255), 0) : max(min(sides[line->sidenum[0]].rowoffset>>FRACBITS, 255), 0)) - : abs(FixedHypot(line->dx, line->dy))>>FRACBITS, + : abs(P_AproxDistance(line->dx, line->dy))>>FRACBITS, (line->flags & ML_EFFECT4), (line->flags & ML_EFFECT5)); break; @@ -2795,7 +2795,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) else { P_SetTarget(&mo->player->awayviewmobj, altview); - mo->player->awayviewtics = FixedHypot(line->dx, line->dy)>>FRACBITS; + mo->player->awayviewtics = P_AproxDistance(line->dx, line->dy)>>FRACBITS; } @@ -2840,7 +2840,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) case 425: // Calls P_SetMobjState on calling mobj if (mo && !mo->player) - P_SetMobjState(mo, sides[line->sidenum[0]].toptexture); //FixedHypot(line->dx, line->dy)>>FRACBITS); + P_SetMobjState(mo, sides[line->sidenum[0]].toptexture); //P_AproxDistance(line->dx, line->dy)>>FRACBITS); break; case 426: // Moves the mobj to its sector's soundorg and on the floor, and stops it @@ -3026,7 +3026,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) case 438: // Set player scale if (mo) { - mo->destscale = FixedDiv(FixedHypot(line->dx, line->dy), 100<destscale = FixedDiv(P_AproxDistance(line->dx, line->dy), 100<destscale < FRACUNIT/100) mo->destscale = FRACUNIT/100; if (mo->player && bot) @@ -3144,7 +3144,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) { quake.intensity = sides[line->sidenum[0]].textureoffset; quake.radius = sides[line->sidenum[0]].rowoffset; - quake.time = FixedHypot(line->dx, line->dy)>>FRACBITS; + quake.time = P_AproxDistance(line->dx, line->dy)>>FRACBITS; quake.epicenter = NULL; /// \todo @@ -3407,7 +3407,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) case 452: // Set FOF alpha { INT16 destvalue = line->sidenum[1] != 0xffff ? - (INT16)(sides[line->sidenum[1]].textureoffset>>FRACBITS) : (INT16)(FixedHypot(line->dx, line->dy)>>FRACBITS); + (INT16)(sides[line->sidenum[1]].textureoffset>>FRACBITS) : (INT16)(P_AproxDistance(line->dx, line->dy)>>FRACBITS); INT16 sectag = (INT16)(sides[line->sidenum[0]].textureoffset>>FRACBITS); INT16 foftag = (INT16)(sides[line->sidenum[0]].rowoffset>>FRACBITS); sector_t *sec; // Sector that the FOF is visible in @@ -4997,8 +4997,8 @@ DoneSection2: } else { - if (FixedHypot(FixedHypot(player->mo->x-resultlow.x, player->mo->y-resultlow.y), - player->mo->z-resultlow.z) < FixedHypot(FixedHypot(player->mo->x-resulthigh.x, + if (P_AproxDistance(P_AproxDistance(player->mo->x-resultlow.x, player->mo->y-resultlow.y), + player->mo->z-resultlow.z) < P_AproxDistance(P_AproxDistance(player->mo->x-resulthigh.x, player->mo->y-resulthigh.y), player->mo->z-resulthigh.z)) { // Line between Mid and Low is closer @@ -6316,7 +6316,7 @@ void P_SpawnSpecials(boolean fromnetsave) break; case 52: // Continuously Falling sector - EV_DoContinuousFall(lines[i].frontsector, lines[i].backsector, FixedHypot(lines[i].dx, lines[i].dy), (lines[i].flags & ML_NOCLIMB)); + EV_DoContinuousFall(lines[i].frontsector, lines[i].backsector, P_AproxDistance(lines[i].dx, lines[i].dy), (lines[i].flags & ML_NOCLIMB)); break; case 53: // New super cool and awesome moving floor and ceiling type @@ -6388,15 +6388,15 @@ void P_SpawnSpecials(boolean fromnetsave) case 66: // Displace floor by front sector TAG_ITER_SECTORS(0, tag, s) - P_AddPlaneDisplaceThinker(pd_floor, FixedHypot(lines[i].dx, lines[i].dy)>>8, sides[lines[i].sidenum[0]].sector-sectors, s, !!(lines[i].flags & ML_NOCLIMB)); + P_AddPlaneDisplaceThinker(pd_floor, P_AproxDistance(lines[i].dx, lines[i].dy)>>8, sides[lines[i].sidenum[0]].sector-sectors, s, !!(lines[i].flags & ML_NOCLIMB)); break; case 67: // Displace ceiling by front sector TAG_ITER_SECTORS(0, tag, s) - P_AddPlaneDisplaceThinker(pd_ceiling, FixedHypot(lines[i].dx, lines[i].dy)>>8, sides[lines[i].sidenum[0]].sector-sectors, s, !!(lines[i].flags & ML_NOCLIMB)); + P_AddPlaneDisplaceThinker(pd_ceiling, P_AproxDistance(lines[i].dx, lines[i].dy)>>8, sides[lines[i].sidenum[0]].sector-sectors, s, !!(lines[i].flags & ML_NOCLIMB)); break; case 68: // Displace both floor AND ceiling by front sector TAG_ITER_SECTORS(0, tag, s) - P_AddPlaneDisplaceThinker(pd_both, FixedHypot(lines[i].dx, lines[i].dy)>>8, sides[lines[i].sidenum[0]].sector-sectors, s, !!(lines[i].flags & ML_NOCLIMB)); + P_AddPlaneDisplaceThinker(pd_both, P_AproxDistance(lines[i].dx, lines[i].dy)>>8, sides[lines[i].sidenum[0]].sector-sectors, s, !!(lines[i].flags & ML_NOCLIMB)); break; case 100: // FOF (solid, opaque, shadows) @@ -6590,18 +6590,18 @@ void P_SpawnSpecials(boolean fromnetsave) case 150: // Air bobbing platform case 151: // Adjustable air bobbing platform { - fixed_t dist = (lines[i].special == 150) ? 16*FRACUNIT : FixedHypot(lines[i].dx, lines[i].dy); + fixed_t dist = (lines[i].special == 150) ? 16*FRACUNIT : P_AproxDistance(lines[i].dx, lines[i].dy); P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers); P_AddAirbob(lines[i].frontsector, tag, dist, false, !!(lines[i].flags & ML_NOCLIMB), false); break; } case 152: // Adjustable air bobbing platform in reverse P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers); - P_AddAirbob(lines[i].frontsector, tag, FixedHypot(lines[i].dx, lines[i].dy), true, !!(lines[i].flags & ML_NOCLIMB), false); + P_AddAirbob(lines[i].frontsector, tag, P_AproxDistance(lines[i].dx, lines[i].dy), true, !!(lines[i].flags & ML_NOCLIMB), false); break; case 153: // Dynamic Sinking Platform P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers); - P_AddAirbob(lines[i].frontsector, tag, FixedHypot(lines[i].dx, lines[i].dy), false, !!(lines[i].flags & ML_NOCLIMB), true); + P_AddAirbob(lines[i].frontsector, tag, P_AproxDistance(lines[i].dx, lines[i].dy), false, !!(lines[i].flags & ML_NOCLIMB), true); break; case 160: // Float/bob platform @@ -6680,7 +6680,7 @@ void P_SpawnSpecials(boolean fromnetsave) case 194: // Rising Platform 'Platform' - You can jump up through it case 195: // Rising Platform Translucent "platform" { - fixed_t speed = FixedDiv(FixedHypot(lines[i].dx, lines[i].dy), 4*FRACUNIT); + fixed_t speed = FixedDiv(P_AproxDistance(lines[i].dx, lines[i].dy), 4*FRACUNIT); fixed_t ceilingtop = P_FindHighestCeilingSurrounding(lines[i].frontsector); fixed_t ceilingbottom = P_FindLowestCeilingSurrounding(lines[i].frontsector); @@ -7005,14 +7005,14 @@ void P_SpawnSpecials(boolean fromnetsave) sec = sides[*lines[i].sidenum].sector - sectors; TAG_ITER_SECTORS(0, tag, s) P_SpawnAdjustableGlowingLight(§ors[sec], §ors[s], - FixedHypot(lines[i].dx, lines[i].dy)>>FRACBITS); + P_AproxDistance(lines[i].dx, lines[i].dy)>>FRACBITS); break; case 603: // Adjustable flickering light sec = sides[*lines[i].sidenum].sector - sectors; TAG_ITER_SECTORS(0, tag, s) P_SpawnAdjustableFireFlicker(§ors[sec], §ors[s], - FixedHypot(lines[i].dx, lines[i].dy)>>FRACBITS); + P_AproxDistance(lines[i].dx, lines[i].dy)>>FRACBITS); break; case 604: // Adjustable Blinking Light (unsynchronized) @@ -8418,9 +8418,9 @@ static void Add_Pusher(pushertype_e type, fixed_t x_mag, fixed_t y_mag, mobj_t * // "The right triangle of the square of the length of the hypotenuse is equal to the sum of the squares of the lengths of the other two sides." // "Bah! Stupid brains! Don't you know anything besides the Pythagorean Theorem?" - Earthworm Jim if (type == p_downcurrent || type == p_upcurrent || type == p_upwind || type == p_downwind) - p->magnitude = FixedHypot(p->x_mag,p->y_mag)<<(FRACBITS-PUSH_FACTOR); + p->magnitude = P_AproxDistance(p->x_mag,p->y_mag)<<(FRACBITS-PUSH_FACTOR); else - p->magnitude = FixedHypot(p->x_mag,p->y_mag); + p->magnitude = P_AproxDistance(p->x_mag,p->y_mag); if (source) // point source exist? { // where force goes to zero @@ -8471,14 +8471,14 @@ static inline boolean PIT_PushThing(mobj_t *thing) // don't fade wrt Z if health & 2 (mapthing has multi flag) if (tmpusher->source->health & 2) - dist = FixedHypot(thing->x - sx,thing->y - sy); + dist = P_AproxDistance(thing->x - sx,thing->y - sy); else { // Make sure the Z is in range if (thing->z < sz - tmpusher->radius || thing->z > sz + tmpusher->radius) return false; - dist = FixedHypot(FixedHypot(thing->x - sx, thing->y - sy), + dist = P_AproxDistance(P_AproxDistance(thing->x - sx, thing->y - sy), thing->z - sz); } @@ -8813,7 +8813,7 @@ void T_Pusher(pusher_t *p) // Tumbleweeds bounce a bit... if (thing->type == MT_LITTLETUMBLEWEED || thing->type == MT_BIGTUMBLEWEED) - thing->momz += FixedHypot(xspeed<<(FRACBITS-PUSH_FACTOR), yspeed<<(FRACBITS-PUSH_FACTOR)) >> 2; + thing->momz += P_AproxDistance(xspeed<<(FRACBITS-PUSH_FACTOR), yspeed<<(FRACBITS-PUSH_FACTOR)) >> 2; } if (moved) diff --git a/src/p_user.c b/src/p_user.c index dbf13cefc..a9e1fe9a2 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1018,7 +1018,7 @@ void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor) // to recover if ((inflictor->flags2 & MF2_SCATTER) && source) { - fixed_t dist = FixedHypot(FixedHypot(source->x-player->mo->x, source->y-player->mo->y), source->z-player->mo->z); + fixed_t dist = P_AproxDistance(P_AproxDistance(source->x-player->mo->x, source->y-player->mo->y), source->z-player->mo->z); dist = FixedMul(128*FRACUNIT, inflictor->scale) - dist/4; @@ -2701,7 +2701,7 @@ static void P_CheckBustableBlocks(player_t *player) // Run a linedef executor?? if (rover->master->flags & ML_EFFECT5) - P_LinedefExecute((INT16)(FixedHypot(rover->master->dx, rover->master->dy)>>FRACBITS), player->mo, node->m_sector); + P_LinedefExecute((INT16)(P_AproxDistance(rover->master->dx, rover->master->dy)>>FRACBITS), player->mo, node->m_sector); goto bustupdone; } @@ -2764,7 +2764,7 @@ static void P_CheckBouncySectors(player_t *player) if (player->mo->z + player->mo->height < bottomheight) continue; - bouncestrength = FixedHypot(rover->master->dx, rover->master->dy)/100; + bouncestrength = P_AproxDistance(rover->master->dx, rover->master->dy)/100; if (oldz < P_GetFOFTopZ(player->mo, node->m_sector, rover, oldx, oldy, NULL) && oldz + player->mo->height > P_GetFOFBottomZ(player->mo, node->m_sector, rover, oldx, oldy, NULL)) @@ -4981,7 +4981,7 @@ void P_Telekinesis(player_t *player, fixed_t thrust, fixed_t range) if (!((mo2->flags & MF_SHOOTABLE && mo2->flags & MF_ENEMY) || mo2->type == MT_EGGGUARD || mo2->player)) continue; - dist = FixedHypot(FixedHypot(player->mo->x-mo2->x, player->mo->y-mo2->y), player->mo->z-mo2->z); + dist = P_AproxDistance(P_AproxDistance(player->mo->x-mo2->x, player->mo->y-mo2->y), player->mo->z-mo2->z); if (range < dist) continue; @@ -6464,12 +6464,12 @@ static void P_NightsTransferPoints(player_t *player, fixed_t xspeed, fixed_t rad //CONS_Debug(DBG_NIGHTS, "T1 is at %d, %d\n", transfer1->x>>FRACBITS, transfer1->y>>FRACBITS); //CONS_Debug(DBG_NIGHTS, "T2 is at %d, %d\n", transfer2->x>>FRACBITS, transfer2->y>>FRACBITS); - //CONS_Debug(DBG_NIGHTS, "Distance from T1: %d\n", FixedHypot(transfer1->x - player->mo->x, transfer1->y - player->mo->y)>>FRACBITS); - //CONS_Debug(DBG_NIGHTS, "Distance from T2: %d\n", FixedHypot(transfer2->x - player->mo->x, transfer2->y - player->mo->y)>>FRACBITS); + //CONS_Debug(DBG_NIGHTS, "Distance from T1: %d\n", P_AproxDistance(transfer1->x - player->mo->x, transfer1->y - player->mo->y)>>FRACBITS); + //CONS_Debug(DBG_NIGHTS, "Distance from T2: %d\n", P_AproxDistance(transfer2->x - player->mo->x, transfer2->y - player->mo->y)>>FRACBITS); // Transfer1 is closer to the player than transfer2 - if (FixedHypot(transfer1->x - player->mo->x, transfer1->y - player->mo->y)>>FRACBITS - < FixedHypot(transfer2->x - player->mo->x, transfer2->y - player->mo->y)>>FRACBITS) + if (P_AproxDistance(transfer1->x - player->mo->x, transfer1->y - player->mo->y)>>FRACBITS + < P_AproxDistance(transfer2->x - player->mo->x, transfer2->y - player->mo->y)>>FRACBITS) { //CONS_Debug(DBG_NIGHTS, " must be < 0 to transfer\n"); @@ -7709,7 +7709,7 @@ void P_BlackOw(player_t *player) S_StartSound (player->mo, sfx_bkpoof); // Sound the BANG! for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && FixedHypot(player->mo->x - players[i].mo->x, + if (playeringame[i] && P_AproxDistance(player->mo->x - players[i].mo->x, player->mo->y - players[i].mo->y) < 1536*FRACUNIT) P_FlashPal(&players[i], PAL_NUKE, 10); @@ -7893,7 +7893,7 @@ static void P_SkidStuff(player_t *player) P_SpawnSkidDust(player, 0, false); } } - else if (FixedHypot(pmx, pmy) >= FixedMul(player->runspeed/2, player->mo->scale) // if you were moving faster than half your run speed last frame + else if (P_AproxDistance(pmx, pmy) >= FixedMul(player->runspeed/2, player->mo->scale) // if you were moving faster than half your run speed last frame && (player->mo->momx != pmx || player->mo->momy != pmy) // and you are moving differently this frame && P_GetPlayerControlDirection(player) == 2) // and your controls are pointing in the opposite direction to your movement { // check for skidding @@ -8524,7 +8524,7 @@ void P_MovePlayer(player_t *player) P_ResetScore(player); // Show the "THOK!" graphic when spinning quickly across the ground. (even applies to non-spinners, in the case of zoom tubes) - if (player->pflags & PF_SPINNING && FixedHypot(player->speed, player->mo->momz) > FixedMul(15<mo->scale) && !(player->pflags & PF_JUMPED)) + if (player->pflags & PF_SPINNING && P_AproxDistance(player->speed, player->mo->momz) > FixedMul(15<mo->scale) && !(player->pflags & PF_JUMPED)) { P_SpawnSpinMobj(player, player->spinitem); G_GhostAddSpin(); @@ -8745,7 +8745,7 @@ static void P_DoZoomTube(player_t *player) speed = abs(player->speed); // change slope - dist = FixedHypot(FixedHypot(player->mo->tracer->x - player->mo->x, player->mo->tracer->y - player->mo->y), player->mo->tracer->z - player->mo->z); + dist = P_AproxDistance(P_AproxDistance(player->mo->tracer->x - player->mo->x, player->mo->tracer->y - player->mo->y), player->mo->tracer->z - player->mo->z); if (dist < 1) dist = 1; @@ -8786,7 +8786,7 @@ static void P_DoZoomTube(player_t *player) // calculate MOMX/MOMY/MOMZ for next waypoint // change slope - dist = FixedHypot(FixedHypot(player->mo->tracer->x - player->mo->x, player->mo->tracer->y - player->mo->y), player->mo->tracer->z - player->mo->z); + dist = P_AproxDistance(P_AproxDistance(player->mo->tracer->x - player->mo->x, player->mo->tracer->y - player->mo->y), player->mo->tracer->z - player->mo->z); if (dist < 1) dist = 1; @@ -8839,7 +8839,7 @@ static void P_DoRopeHang(player_t *player) sequence = player->mo->tracer->threshold; // change slope - dist = FixedHypot(FixedHypot(player->mo->tracer->x - player->mo->x, player->mo->tracer->y - player->mo->y), player->mo->tracer->z - playerz); + dist = P_AproxDistance(P_AproxDistance(player->mo->tracer->x - player->mo->x, player->mo->tracer->y - player->mo->y), player->mo->tracer->z - playerz); if (dist < 1) dist = 1; @@ -8902,7 +8902,7 @@ static void P_DoRopeHang(player_t *player) // calculate MOMX/MOMY/MOMZ for next waypoint // change slope - dist = FixedHypot(FixedHypot(player->mo->tracer->x - player->mo->x, player->mo->tracer->y - player->mo->y), player->mo->tracer->z - playerz); + dist = P_AproxDistance(P_AproxDistance(player->mo->tracer->x - player->mo->x, player->mo->tracer->y - player->mo->y), player->mo->tracer->z - playerz); if (dist < 1) dist = 1; @@ -9003,7 +9003,7 @@ void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius) if (abs(inflictor->x - mo->x) > radius || abs(inflictor->y - mo->y) > radius || abs(inflictor->z - mo->z) > radius) continue; // Workaround for possible integer overflow in the below -Red - if (FixedHypot(FixedHypot(inflictor->x - mo->x, inflictor->y - mo->y), inflictor->z - mo->z) > radius) + if (P_AproxDistance(P_AproxDistance(inflictor->x - mo->x, inflictor->y - mo->y), inflictor->z - mo->z) > radius) continue; if (mo->type == MT_MINUS && !(mo->flags & (MF_SPECIAL|MF_SHOOTABLE))) @@ -9139,12 +9139,12 @@ mobj_t *P_LookForFocusTarget(player_t *player, mobj_t *exclude, SINT8 direction, { fixed_t zdist = (player->mo->z + player->mo->height/2) - (mo->z + mo->height/2); - dist = FixedHypot(player->mo->x-mo->x, player->mo->y-mo->y); + dist = P_AproxDistance(player->mo->x-mo->x, player->mo->y-mo->y); if (abs(zdist) > dist) continue; // Don't home outside of desired angle! - dist = FixedHypot(dist, zdist); + dist = P_AproxDistance(dist, zdist); if (dist > maxdist) continue; // out of range } @@ -9236,7 +9236,7 @@ mobj_t *P_LookForEnemies(player_t *player, boolean nonenemies, boolean bullet) { fixed_t zdist = (player->mo->z + player->mo->height/2) - (mo->z + mo->height/2); - dist = FixedHypot(player->mo->x-mo->x, player->mo->y-mo->y); + dist = P_AproxDistance(player->mo->x-mo->x, player->mo->y-mo->y); if (bullet) { if ((R_PointToAngle2(0, 0, dist, zdist) + span) > span*2) @@ -9253,7 +9253,7 @@ mobj_t *P_LookForEnemies(player_t *player, boolean nonenemies, boolean bullet) continue; } - dist = FixedHypot(dist, zdist); + dist = P_AproxDistance(dist, zdist); if (dist > maxdist) continue; // out of range } @@ -9313,7 +9313,7 @@ boolean P_HomingAttack(mobj_t *source, mobj_t *enemy) // Home in on your target // change slope zdist = ((P_MobjFlip(source) == -1) ? (enemy->z + enemy->height) - (source->z + source->height) : (enemy->z - source->z)); - dist = FixedHypot(FixedHypot(enemy->x - source->x, enemy->y - source->y), zdist); + dist = P_AproxDistance(P_AproxDistance(enemy->x - source->x, enemy->y - source->y), zdist); if (dist < 1) dist = 1; @@ -10362,7 +10362,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall // follow the player /*if (player->playerstate != PST_DEAD && (camspeed) != 0) { - if (FixedHypot(mo->x - thiscam->x, mo->y - thiscam->y) > (checkdist + FixedHypot(mo->momx, mo->momy)) * 4 + if (P_AproxDistance(mo->x - thiscam->x, mo->y - thiscam->y) > (checkdist + P_AproxDistance(mo->momx, mo->momy)) * 4 || abs(mo->z - thiscam->z) > checkdist * 3) { if (!resetcalled) @@ -10427,7 +10427,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall } /* check z distance too for orbital camera */ - if (FixedHypot(FixedHypot(vx - mo->x, vy - mo->y), + if (P_AproxDistance(P_AproxDistance(vx - mo->x, vy - mo->y), vz - ( mo->z + mo->height / 2 )) < FixedMul(48*FRACUNIT, mo->scale)) mo->flags2 |= MF2_SHADOW; else @@ -10912,7 +10912,7 @@ static void P_ParabolicMove(mobj_t *mo, fixed_t x, fixed_t y, fixed_t z, fixed_t fixed_t dx = x - mo->x; fixed_t dy = y - mo->y; fixed_t dz = z - mo->z; - fixed_t dh = FixedHypot(dx, dy); + fixed_t dh = P_AproxDistance(dx, dy); fixed_t c = FixedDiv(dx, dh); fixed_t s = FixedDiv(dy, dh); fixed_t fixConst = FixedDiv(speed, g); @@ -11784,7 +11784,7 @@ void P_PlayerThink(player_t *player) if (mo2->flags2 & MF2_NIGHTSPULL) continue; - if (FixedHypot(FixedHypot(mo2->x - x, mo2->y - y), mo2->z - z) > FixedMul(128*FRACUNIT, player->mo->scale)) + if (P_AproxDistance(P_AproxDistance(mo2->x - x, mo2->y - y), mo2->z - z) > FixedMul(128*FRACUNIT, player->mo->scale)) continue; // Yay! The thing's in reach! Pull it in! @@ -12020,7 +12020,7 @@ void P_PlayerThink(player_t *player) if (!currentlyonground) acceleration /= 2; // fake skidding! see P_SkidStuff for reference on conditionals - else if (!player->skidtime && !(player->mo->eflags & MFE_GOOWATER) && !(player->pflags & (PF_JUMPED|PF_SPINNING|PF_SLIDING)) && !(player->charflags & SF_NOSKID) && FixedHypot(player->mo->momx, player->mo->momy) >= FixedMul(player->runspeed, player->mo->scale)) // modified from player->runspeed/2 'cuz the skid was just TOO frequent ngl + else if (!player->skidtime && !(player->mo->eflags & MFE_GOOWATER) && !(player->pflags & (PF_JUMPED|PF_SPINNING|PF_SLIDING)) && !(player->charflags & SF_NOSKID) && P_AproxDistance(player->mo->momx, player->mo->momy) >= FixedMul(player->runspeed, player->mo->scale)) // modified from player->runspeed/2 'cuz the skid was just TOO frequent ngl { if (player->mo->state-states != S_PLAY_SKID) P_SetPlayerMobjState(player->mo, S_PLAY_SKID); @@ -12605,7 +12605,7 @@ void P_PlayerAfterThink(player_t *player) P_SetPlayerAngle(player, player->mo->angle); } - if (FixedHypot(player->mo->x - tails->x, player->mo->y - tails->y) > player->mo->radius) + if (P_AproxDistance(player->mo->x - tails->x, player->mo->y - tails->y) > player->mo->radius) player->powers[pw_carry] = CR_NONE; if (player->powers[pw_carry] != CR_NONE) @@ -12794,7 +12794,7 @@ void P_PlayerAfterThink(player_t *player) player->mo->momy = ptera->momy; player->mo->momz = ptera->momz; - if (FixedHypot(player->mo->x - ptera->x - ptera->watertop, player->mo->y - ptera->y - ptera->waterbottom) > player->mo->radius) + if (P_AproxDistance(player->mo->x - ptera->x - ptera->watertop, player->mo->y - ptera->y - ptera->waterbottom) > player->mo->radius) goto dropoff; ptera->watertop >>= 1; diff --git a/src/r_things.c b/src/r_things.c index 66c292b07..30bf15f85 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -3019,7 +3019,7 @@ boolean R_ThingVisibleWithinDist (mobj_t *thing, if (! R_ThingVisible(thing)) return false; - approx_dist = FixedHypot(viewx-thing->x, viewy-thing->y); + approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y); if (thing->sprite == SPR_HOOP) { @@ -3044,7 +3044,7 @@ boolean R_PrecipThingVisible (precipmobj_t *precipthing, if (( precipthing->precipflags & PCF_INVISIBLE )) return false; - approx_dist = FixedHypot(viewx-precipthing->x, viewy-precipthing->y); + approx_dist = P_AproxDistance(viewx-precipthing->x, viewy-precipthing->y); return ( approx_dist <= limit_dist ); } diff --git a/src/s_sound.c b/src/s_sound.c index 0085dc342..392a5b453 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -943,8 +943,8 @@ void S_UpdateSounds(void) const mobj_t *soundmobj = c->origin; fixed_t dist1, dist2; - dist1 = FixedHypot(listener.x-soundmobj->x, listener.y-soundmobj->y); - dist2 = FixedHypot(listener2.x-soundmobj->x, listener2.y-soundmobj->y); + dist1 = P_AproxDistance(listener.x-soundmobj->x, listener.y-soundmobj->y); + dist2 = P_AproxDistance(listener2.x-soundmobj->x, listener2.y-soundmobj->y); if (dist1 <= dist2) { diff --git a/src/st_stuff.c b/src/st_stuff.c index 15d1af396..649644620 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2458,7 +2458,7 @@ num: static INT32 ST_drawEmeraldHuntIcon(mobj_t *hunt, patch_t **patches, INT32 offset) { INT32 interval, i; - UINT32 dist = ((UINT32)FixedHypot(FixedHypot(stplyr->mo->x - hunt->x, stplyr->mo->y - hunt->y), stplyr->mo->z - hunt->z))>>FRACBITS; + UINT32 dist = ((UINT32)P_AproxDistance(P_AproxDistance(stplyr->mo->x - hunt->x, stplyr->mo->y - hunt->y), stplyr->mo->z - hunt->z))>>FRACBITS; if (dist < 128) { From d2d1f83b62de98a9f08f5197e9bed84306f12741 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sat, 13 Feb 2021 17:45:54 +0100 Subject: [PATCH 262/644] Revert "Use R_PointToDist2 instead" This reverts commit e19196a86e5347edf7f25b335214cede978b91b8. --- src/m_fixed.c | 40 ++++++++++++---------------------------- src/r_main.c | 24 +++++++++++++++++++++++- 2 files changed, 35 insertions(+), 29 deletions(-) diff --git a/src/m_fixed.c b/src/m_fixed.c index 09d6936f2..eb10fd5f8 100644 --- a/src/m_fixed.c +++ b/src/m_fixed.c @@ -18,10 +18,8 @@ #define HAVE_SQRTF #endif #endif - #include "doomdef.h" #include "m_fixed.h" -#include "tables.h" // ANGLETOFINESHIFT #ifdef __USE_C_FIXEDMUL__ @@ -107,34 +105,20 @@ fixed_t FixedSqrt(fixed_t x) fixed_t FixedHypot(fixed_t x, fixed_t y) { - // Moved the code from R_PointToDist2 to here, - // since R_PointToDist2 did the same thing, - // except less prone to overflowing. - - angle_t angle; - fixed_t dist; - - x = abs(x); - y = abs(y); - - if (y > x) + fixed_t ax, yx, yx2, yx1; + if (abs(y) > abs(x)) // |y|>|x| { - fixed_t temp; - - temp = x; - x = y; - y = temp; + ax = abs(y); // |y| => ax + yx = FixedDiv(x, y); // (x/y) } - - if (!y) - return x; - - angle = (tantoangle[FixedDiv(y, x)>>DBITS] + ANGLE_90) >> ANGLETOFINESHIFT; - - // use as cosine - dist = FixedDiv(x, FINESINE(angle)); - - return dist; + else // |x|>|y| + { + ax = abs(x); // |x| => ax + yx = FixedDiv(y, x); // (x/y) + } + yx2 = FixedMul(yx, yx); // (x/y)^2 + yx1 = FixedSqrt(1 * FRACUNIT + yx2); // (1 + (x/y)^2)^1/2 + return FixedMul(ax, yx1); // |x|*((1 + (x/y)^2)^1/2) } vector2_t *FV2_Load(vector2_t *vec, fixed_t x, fixed_t y) diff --git a/src/r_main.c b/src/r_main.c index f6c05e312..f82fb589e 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -357,7 +357,29 @@ angle_t R_PointToAngle2(fixed_t pviewx, fixed_t pviewy, fixed_t x, fixed_t y) fixed_t R_PointToDist2(fixed_t px2, fixed_t py2, fixed_t px1, fixed_t py1) { - return FixedHypot(px1 - px2, py1 - py2); + angle_t angle; + fixed_t dx, dy, dist; + + dx = abs(px1 - px2); + dy = abs(py1 - py2); + + if (dy > dx) + { + fixed_t temp; + + temp = dx; + dx = dy; + dy = temp; + } + if (!dy) + return dx; + + angle = (tantoangle[FixedDiv(dy, dx)>>DBITS] + ANGLE_90) >> ANGLETOFINESHIFT; + + // use as cosine + dist = FixedDiv(dx, FINESINE(angle)); + + return dist; } // Little extra utility. Works in the same way as R_PointToAngle2 From a58df577fe9579bc879de895aea0ef310d8750e1 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sat, 13 Feb 2021 17:46:29 +0100 Subject: [PATCH 263/644] Revert "Use FixedHypot over P_AproxDistance" This reverts commit c5474436af67408342e8dce0ec996d62c9a4c21c. --- src/lua_baselib.c | 3 +-- src/p_maputl.c | 13 +++++++++++++ src/p_maputl.h | 2 +- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 609d9c8b8..c5f847be6 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -432,8 +432,7 @@ static int lib_pAproxDistance(lua_State *L) fixed_t dx = luaL_checkfixed(L, 1); fixed_t dy = luaL_checkfixed(L, 2); //HUDSAFE - LUA_Deprecated(L, "P_AproxDistance", "FixedHypot"); - lua_pushfixed(L, FixedHypot(dx, dy)); + lua_pushfixed(L, P_AproxDistance(dx, dy)); return 1; } diff --git a/src/p_maputl.c b/src/p_maputl.c index 83905a418..90718a41c 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -24,6 +24,19 @@ #include "p_slopes.h" #include "z_zone.h" +// +// P_AproxDistance +// Gives an estimation of distance (not exact) +// +fixed_t P_AproxDistance(fixed_t dx, fixed_t dy) +{ + dx = abs(dx); + dy = abs(dy); + if (dx < dy) + return dx + dy - (dx>>1); + return dx + dy - (dy>>1); +} + // // P_ClosestPointOnLine // Finds the closest point on a given line to the supplied point diff --git a/src/p_maputl.h b/src/p_maputl.h index df90ab4b4..08b606833 100644 --- a/src/p_maputl.h +++ b/src/p_maputl.h @@ -41,7 +41,7 @@ typedef boolean (*traverser_t)(intercept_t *in); boolean P_PathTraverse(fixed_t px1, fixed_t py1, fixed_t px2, fixed_t py2, INT32 pflags, traverser_t ptrav); -#define P_AproxDistance(dx, dy) FixedHypot(dx, dy) +FUNCMATH fixed_t P_AproxDistance(fixed_t dx, fixed_t dy); void P_ClosestPointOnLine(fixed_t x, fixed_t y, line_t *line, vertex_t *result); void P_ClosestPointOnLine3D(const vector3_t *p, const vector3_t *line, vector3_t *result); INT32 P_PointOnLineSide(fixed_t x, fixed_t y, line_t *line); From 758de501da8c458cc3b8f06a376db1b3cb818316 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sat, 13 Feb 2021 18:04:12 +0100 Subject: [PATCH 264/644] Use R_PointToDist2 for the Lua versions of P_AproxDistance and FixedHypot --- src/lua_baselib.c | 2 +- src/lua_mathlib.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index c5f847be6..916fa9254 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -432,7 +432,7 @@ static int lib_pAproxDistance(lua_State *L) fixed_t dx = luaL_checkfixed(L, 1); fixed_t dy = luaL_checkfixed(L, 2); //HUDSAFE - lua_pushfixed(L, P_AproxDistance(dx, dy)); + lua_pushfixed(L, R_PointToDist2(0, 0, dx, dy)); return 1; } diff --git a/src/lua_mathlib.c b/src/lua_mathlib.c index 10ba42ee0..b6046ab53 100644 --- a/src/lua_mathlib.c +++ b/src/lua_mathlib.c @@ -15,6 +15,7 @@ #include "tables.h" #include "p_local.h" #include "doomstat.h" // for ALL7EMERALDS +#include "r_main.h" // for R_PointToDist2 #include "lua_script.h" #include "lua_libs.h" @@ -129,7 +130,7 @@ static int lib_fixedsqrt(lua_State *L) static int lib_fixedhypot(lua_State *L) { - lua_pushfixed(L, FixedHypot(luaL_checkfixed(L, 1), luaL_checkfixed(L, 2))); + lua_pushfixed(L, R_PointToDist2(0, 0, luaL_checkfixed(L, 1), luaL_checkfixed(L, 2))); return 1; } From 70850b083632d9b590cdaaf102be7ecf081be1ca Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sat, 13 Feb 2021 18:04:27 +0100 Subject: [PATCH 265/644] Deprecate P_AproxDistance for Lua scripts --- src/lua_baselib.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 916fa9254..6e0116d12 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -432,6 +432,7 @@ static int lib_pAproxDistance(lua_State *L) fixed_t dx = luaL_checkfixed(L, 1); fixed_t dy = luaL_checkfixed(L, 2); //HUDSAFE + LUA_Deprecated(L, "P_AproxDistance", "FixedHypot"); lua_pushfixed(L, R_PointToDist2(0, 0, dx, dy)); return 1; } From cf389179e85536d05fa4545004477f784181adc1 Mon Sep 17 00:00:00 2001 From: lachwright Date: Mon, 15 Feb 2021 01:11:03 +1100 Subject: [PATCH 266/644] Rollout rock improvements: - No longer struggles to start to accelerating at certain angles - Carrying a player onto a rollout rock no longer leaves them in their ride state - Changed dispoffset might alleviate some sorting issues - Changes the player's camera angle when sprung horizontally - Works better in reverse gravity --- src/info.c | 2 +- src/p_enemy.c | 14 ++++++++++---- src/p_map.c | 7 +++++++ src/p_user.c | 9 ++++++--- 4 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/info.c b/src/info.c index ee836a372..6fbf71432 100644 --- a/src/info.c +++ b/src/info.c @@ -13481,7 +13481,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 32*FRACUNIT, // speed 30*FRACUNIT, // radius 60*FRACUNIT, // height - 0, // display offset + -1, // display offset 100, // mass 0, // damage sfx_None, // activesound diff --git a/src/p_enemy.c b/src/p_enemy.c index 3e7f52a3f..294615b88 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -14319,6 +14319,14 @@ void A_RolloutRock(mobj_t *actor) if (LUA_CallAction(A_ROLLOUTROCK, actor)) return; + if (!actor->tracer || P_MobjWasRemoved(actor->tracer) || !actor->tracer->health) + actor->flags |= MF_PUSHABLE; + else + { + actor->flags2 = (actor->flags2 & ~MF2_OBJECTFLIP) | (actor->tracer->flags2 & MF2_OBJECTFLIP); + actor->eflags = (actor->eflags & ~MFE_VERTICALFLIP) | (actor->tracer->eflags & MFE_VERTICALFLIP); + } + actor->friction = FRACUNIT; // turns out riding on solids sucks, so let's just make it easier on ourselves if (actor->eflags & MFE_JUSTHITFLOOR) @@ -14357,7 +14365,8 @@ void A_RolloutRock(mobj_t *actor) speed = P_AproxDistance(actor->momx, actor->momy); // recalculate speed for visual rolling - if (speed < actor->scale >> 1) // stop moving if speed is insignificant + if (((actor->flags & MF_PUSHABLE) || !(actor->flags2 & MF2_STRONGBOX)) + && speed < actor->scale) // stop moving if speed is insignificant { actor->momx = 0; actor->momy = 0; @@ -14377,9 +14386,6 @@ void A_RolloutRock(mobj_t *actor) actor->frame = actor->reactiontime % maxframes; // set frame - if (!actor->tracer || P_MobjWasRemoved(actor->tracer) || !actor->tracer->health) - actor->flags |= MF_PUSHABLE; - if (!(actor->flags & MF_PUSHABLE) || (actor->movecount != 1)) // if being ridden or haven't moved, don't disappear actor->fuse = actor->info->painchance; else if (actor->fuse < 2*TICRATE) diff --git a/src/p_map.c b/src/p_map.c index a1cad524e..630d28200 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -429,6 +429,13 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) else P_SetPlayerMobjState(object, S_PLAY_FALL); } + else if (horizspeed + && object->tracer + && object->tracer->player + && object->tracer->player->powers[pw_carry] != CR_NONE + && object->tracer->tracer == object + && (!demoplayback || P_ControlStyle(object->tracer->player) == CS_LMAOGALOG)) + P_SetPlayerAngle(object->tracer->player, spring->angle); object->standingslope = NULL; // And again. diff --git a/src/p_user.c b/src/p_user.c index a9e1fe9a2..ca1dfd478 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -12608,14 +12608,14 @@ void P_PlayerAfterThink(player_t *player) if (P_AproxDistance(player->mo->x - tails->x, player->mo->y - tails->y) > player->mo->radius) player->powers[pw_carry] = CR_NONE; - if (player->powers[pw_carry] != CR_NONE) + if (player->powers[pw_carry] == CR_PLAYER) { if (player->mo->state-states != S_PLAY_RIDE) P_SetPlayerMobjState(player->mo, S_PLAY_RIDE); if (tails->player && (tails->skin && ((skin_t *)(tails->skin))->sprites[SPR2_SWIM].numframes) && (tails->eflags & MFE_UNDERWATER)) tails->player->powers[pw_tailsfly] = 0; } - else + else if (player->powers[pw_carry] == CR_NONE) P_SetTarget(&player->mo->tracer, NULL); if (player-players == consoleplayer && botingame) @@ -12718,9 +12718,12 @@ void P_PlayerAfterThink(player_t *player) if (player->cmd.forwardmove || player->cmd.sidemove) { + rock->flags2 |= MF2_STRONGBOX; // signifies the rock should not slow to a halt rock->movedir = (player->cmd.angleturn << FRACBITS) + R_PointToAngle2(0, 0, player->cmd.forwardmove << FRACBITS, -player->cmd.sidemove << FRACBITS); P_Thrust(rock, rock->movedir, rock->scale >> 1); } + else + rock->flags2 &= ~MF2_STRONGBOX; mo->momx = rock->momx; mo->momy = rock->momy; @@ -12736,7 +12739,7 @@ void P_PlayerAfterThink(player_t *player) mo->tics = walktics; } - P_TeleportMove(player->mo, rock->x, rock->y, rock->z + rock->height); + P_TeleportMove(player->mo, rock->x, rock->y, rock->z + ((mo->eflags & MFE_VERTICALFLIP) ? -mo->height : rock->height)); break; } case CR_PTERABYTE: // being carried by a Pterabyte From 4430835a71430c73b5ca3f014babd6ff1778abd1 Mon Sep 17 00:00:00 2001 From: SMS Alfredo <65426124+SMS-Alfredo@users.noreply.github.com> Date: Sun, 14 Feb 2021 20:49:03 -0600 Subject: [PATCH 267/644] This might be dumb, but whatever --- src/lua_baselib.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 6e0116d12..916fa9254 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -432,7 +432,6 @@ static int lib_pAproxDistance(lua_State *L) fixed_t dx = luaL_checkfixed(L, 1); fixed_t dy = luaL_checkfixed(L, 2); //HUDSAFE - LUA_Deprecated(L, "P_AproxDistance", "FixedHypot"); lua_pushfixed(L, R_PointToDist2(0, 0, dx, dy)); return 1; } From b369243bebf5db2d2f1cc270d2716e8a73750073 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Mon, 15 Feb 2021 13:37:25 +0100 Subject: [PATCH 268/644] Use standard Lua naming scheme for polyobject list --- src/lua_polyobjlib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lua_polyobjlib.c b/src/lua_polyobjlib.c index 365d97056..2a5bcfbf1 100644 --- a/src/lua_polyobjlib.c +++ b/src/lua_polyobjlib.c @@ -417,7 +417,7 @@ static int lib_getPolyObject(lua_State *L) { i = luaL_checkinteger(L, 2); if (i < 0 || i >= numPolyObjects) - return luaL_error(L, "PolyObjects[] index %d out of range (0 - %d)", i, numPolyObjects-1); + return luaL_error(L, "polyobjects[] index %d out of range (0 - %d)", i, numPolyObjects-1); LUA_PushUserdata(L, &PolyObjects[i], META_POLYOBJ); return 1; } @@ -481,6 +481,6 @@ int LUA_PolyObjLib(lua_State *L) lua_pushcfunction(L, lib_numPolyObjects); lua_setfield(L, -2, "__len"); lua_setmetatable(L, -2); - lua_setglobal(L, "PolyObjects"); + lua_setglobal(L, "polyobjects"); return 0; } From 0b012d5db0bd5f3d6b904bbed4f585fde61ce582 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Mon, 15 Feb 2021 16:21:26 +0100 Subject: [PATCH 269/644] Make the names of disconnected players flicker in tab HUD --- src/hu_stuff.c | 45 +++++++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 0b24d0690..1e69e6d51 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -2307,10 +2307,11 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I // V_DrawSmallString(x+ 246, y+4, V_YELLOWMAP, "SERVER"); } - V_DrawString(x + 20, y, - ((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0) - | (greycheck ? V_60TRANS : 0) - | V_ALLOWLOWERCASE, tab[i].name); + if (!players[tab[i].num].quittime || (leveltime / (TICRATE/2) & 1)) + V_DrawString(x + 20, y, + ((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0) + | (greycheck ? V_60TRANS : 0) + | V_ALLOWLOWERCASE, tab[i].name); // Draw emeralds if (players[tab[i].num].powers[pw_invulnerability] && (players[tab[i].num].powers[pw_invulnerability] == players[tab[i].num].powers[pw_sneakers]) && ((leveltime/7) & 1)) @@ -2458,10 +2459,11 @@ static void HU_Draw32TeamTabRankings(playersort_t *tab, INT32 whiteplayer) supercheck = supercheckdef; strlcpy(name, tab[i].name, 8); - V_DrawString(x + 10, y, - ((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0) - | (greycheck ? 0 : V_TRANSLUCENT) - | V_ALLOWLOWERCASE, name); + if (!players[tab[i].num].quittime || (leveltime / (TICRATE/2) & 1)) + V_DrawString(x + 10, y, + ((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0) + | (greycheck ? 0 : V_TRANSLUCENT) + | V_ALLOWLOWERCASE, name); if (gametyperules & GTR_TEAMFLAGS) { @@ -2586,10 +2588,11 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer) supercheck = supercheckdef; strlcpy(name, tab[i].name, 7); - V_DrawString(x + 20, y, - ((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0) - | (greycheck ? V_TRANSLUCENT : 0) - | V_ALLOWLOWERCASE, name); + if (!players[tab[i].num].quittime || (leveltime / (TICRATE/2) & 1)) + V_DrawString(x + 20, y, + ((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0) + | (greycheck ? V_TRANSLUCENT : 0) + | V_ALLOWLOWERCASE, name); if (gametyperules & GTR_TEAMFLAGS) { @@ -2660,10 +2663,11 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline //else // V_DrawSmallString(x+ 94, y+4, V_YELLOWMAP, "SERVER"); - V_DrawString(x + 20, y, - ((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0) - | (greycheck ? V_TRANSLUCENT : 0) - | V_ALLOWLOWERCASE, name); + if (!players[tab[i].num].quittime || (leveltime / (TICRATE/2) & 1)) + V_DrawString(x + 20, y, + ((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0) + | (greycheck ? V_TRANSLUCENT : 0) + | V_ALLOWLOWERCASE, name); if (G_GametypeUsesLives() && !(G_GametypeUsesCoopLives() && (cv_cooplives.value == 0 || cv_cooplives.value == 3)) && (players[tab[i].num].lives != INFLIVES)) //show lives V_DrawRightAlignedString(x, y+4, V_ALLOWLOWERCASE, va("%dx", players[tab[i].num].lives)); @@ -2769,10 +2773,11 @@ static void HU_Draw32TabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scor // V_DrawSmallString(x+ 129, y+4, V_YELLOWMAP, "HOST"); } - V_DrawString(x + 10, y, - ((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0) - | (greycheck ? 0 : V_TRANSLUCENT) - | V_ALLOWLOWERCASE, name); + if (!players[tab[i].num].quittime || (leveltime / (TICRATE/2) & 1)) + V_DrawString(x + 10, y, + ((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0) + | (greycheck ? 0 : V_TRANSLUCENT) + | V_ALLOWLOWERCASE, name); if (G_GametypeUsesLives()) //show lives V_DrawRightAlignedThinString(x-1, y, V_ALLOWLOWERCASE, va("%d", players[tab[i].num].lives)); From aa33d90215c058e0f19621661d4ae10391b583eb Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Mon, 15 Feb 2021 16:23:57 +0100 Subject: [PATCH 270/644] Add rejointimeout to the server options --- src/m_menu.c | 69 ++++++++++++++++++++++++++-------------------------- 1 file changed, 35 insertions(+), 34 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 05c819c37..516bd34c1 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1612,53 +1612,54 @@ static menuitem_t OP_ServerOptionsMenu[] = {IT_STRING | IT_CVAR, NULL, "Max Players", &cv_maxplayers, 21}, {IT_STRING | IT_CVAR, NULL, "Allow Add-on Downloading", &cv_downloading, 26}, {IT_STRING | IT_CVAR, NULL, "Allow players to join", &cv_allownewplayer, 31}, + {IT_STRING | IT_CVAR, NULL, "Minutes for reconnecting", &cv_rejointimeout, 36}, #endif - {IT_STRING | IT_CVAR, NULL, "Map progression", &cv_advancemap, 36}, - {IT_STRING | IT_CVAR, NULL, "Intermission Timer", &cv_inttime, 41}, + {IT_STRING | IT_CVAR, NULL, "Map progression", &cv_advancemap, 41}, + {IT_STRING | IT_CVAR, NULL, "Intermission Timer", &cv_inttime, 46}, - {IT_HEADER, NULL, "Characters", NULL, 50}, - {IT_STRING | IT_CVAR, NULL, "Force a character", &cv_forceskin, 56}, - {IT_STRING | IT_CVAR, NULL, "Restrict character changes", &cv_restrictskinchange, 61}, + {IT_HEADER, NULL, "Characters", NULL, 55}, + {IT_STRING | IT_CVAR, NULL, "Force a character", &cv_forceskin, 61}, + {IT_STRING | IT_CVAR, NULL, "Restrict character changes", &cv_restrictskinchange, 66}, - {IT_HEADER, NULL, "Items", NULL, 70}, - {IT_STRING | IT_CVAR, NULL, "Item respawn delay", &cv_itemrespawntime, 76}, - {IT_STRING | IT_SUBMENU, NULL, "Mystery Item Monitor Toggles...", &OP_MonitorToggleDef, 81}, + {IT_HEADER, NULL, "Items", NULL, 75}, + {IT_STRING | IT_CVAR, NULL, "Item respawn delay", &cv_itemrespawntime, 81}, + {IT_STRING | IT_SUBMENU, NULL, "Mystery Item Monitor Toggles...", &OP_MonitorToggleDef, 86}, - {IT_HEADER, NULL, "Cooperative", NULL, 90}, - {IT_STRING | IT_CVAR, NULL, "Players required for exit", &cv_playersforexit, 96}, - {IT_STRING | IT_CVAR, NULL, "Starposts", &cv_coopstarposts, 101}, - {IT_STRING | IT_CVAR, NULL, "Life sharing", &cv_cooplives, 106}, - {IT_STRING | IT_CVAR, NULL, "Post-goal free roaming", &cv_exitmove, 111}, + {IT_HEADER, NULL, "Cooperative", NULL, 95}, + {IT_STRING | IT_CVAR, NULL, "Players required for exit", &cv_playersforexit, 101}, + {IT_STRING | IT_CVAR, NULL, "Starposts", &cv_coopstarposts, 106}, + {IT_STRING | IT_CVAR, NULL, "Life sharing", &cv_cooplives, 111}, + {IT_STRING | IT_CVAR, NULL, "Post-goal free roaming", &cv_exitmove, 116}, - {IT_HEADER, NULL, "Race, Competition", NULL, 120}, - {IT_STRING | IT_CVAR, NULL, "Level completion countdown", &cv_countdowntime, 126}, - {IT_STRING | IT_CVAR, NULL, "Item Monitors", &cv_competitionboxes, 131}, + {IT_HEADER, NULL, "Race, Competition", NULL, 125}, + {IT_STRING | IT_CVAR, NULL, "Level completion countdown", &cv_countdowntime, 131}, + {IT_STRING | IT_CVAR, NULL, "Item Monitors", &cv_competitionboxes, 136}, - {IT_HEADER, NULL, "Ringslinger (Match, CTF, Tag, H&S)", NULL, 140}, - {IT_STRING | IT_CVAR, NULL, "Time Limit", &cv_timelimit, 146}, - {IT_STRING | IT_CVAR, NULL, "Score Limit", &cv_pointlimit, 151}, - {IT_STRING | IT_CVAR, NULL, "Overtime on Tie", &cv_overtime, 156}, - {IT_STRING | IT_CVAR, NULL, "Player respawn delay", &cv_respawntime, 161}, + {IT_HEADER, NULL, "Ringslinger (Match, CTF, Tag, H&S)", NULL, 145}, + {IT_STRING | IT_CVAR, NULL, "Time Limit", &cv_timelimit, 151}, + {IT_STRING | IT_CVAR, NULL, "Score Limit", &cv_pointlimit, 156}, + {IT_STRING | IT_CVAR, NULL, "Overtime on Tie", &cv_overtime, 161}, + {IT_STRING | IT_CVAR, NULL, "Player respawn delay", &cv_respawntime, 166}, - {IT_STRING | IT_CVAR, NULL, "Item Monitors", &cv_matchboxes, 171}, - {IT_STRING | IT_CVAR, NULL, "Weapon Rings", &cv_specialrings, 176}, - {IT_STRING | IT_CVAR, NULL, "Power Stones", &cv_powerstones, 181}, + {IT_STRING | IT_CVAR, NULL, "Item Monitors", &cv_matchboxes, 176}, + {IT_STRING | IT_CVAR, NULL, "Weapon Rings", &cv_specialrings, 181}, + {IT_STRING | IT_CVAR, NULL, "Power Stones", &cv_powerstones, 186}, - {IT_STRING | IT_CVAR, NULL, "Flag respawn delay", &cv_flagtime, 191}, - {IT_STRING | IT_CVAR, NULL, "Hiding time", &cv_hidetime, 196}, + {IT_STRING | IT_CVAR, NULL, "Flag respawn delay", &cv_flagtime, 196}, + {IT_STRING | IT_CVAR, NULL, "Hiding time", &cv_hidetime, 201}, - {IT_HEADER, NULL, "Teams", NULL, 205}, - {IT_STRING | IT_CVAR, NULL, "Autobalance sizes", &cv_autobalance, 211}, - {IT_STRING | IT_CVAR, NULL, "Scramble on Map Change", &cv_scrambleonchange, 216}, + {IT_HEADER, NULL, "Teams", NULL, 210}, + {IT_STRING | IT_CVAR, NULL, "Autobalance sizes", &cv_autobalance, 216}, + {IT_STRING | IT_CVAR, NULL, "Scramble on Map Change", &cv_scrambleonchange, 221}, #ifndef NONET - {IT_HEADER, NULL, "Advanced", NULL, 225}, - {IT_STRING | IT_CVAR | IT_CV_STRING, NULL, "Master server", &cv_masterserver, 231}, + {IT_HEADER, NULL, "Advanced", NULL, 230}, + {IT_STRING | IT_CVAR | IT_CV_STRING, NULL, "Master server", &cv_masterserver, 236}, - {IT_STRING | IT_CVAR, NULL, "Join delay", &cv_joindelay, 246}, - {IT_STRING | IT_CVAR, NULL, "Attempts to resynchronise", &cv_resynchattempts, 251}, + {IT_STRING | IT_CVAR, NULL, "Join delay", &cv_joindelay, 251}, + {IT_STRING | IT_CVAR, NULL, "Attempts to resynchronise", &cv_resynchattempts, 256}, - {IT_STRING | IT_CVAR, NULL, "Show IP Address of Joiners", &cv_showjoinaddress, 256}, + {IT_STRING | IT_CVAR, NULL, "Show IP Address of Joiners", &cv_showjoinaddress, 261}, #endif }; From 97daba68d0beb57622f996c6086d15355175ae22 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Mon, 15 Feb 2021 16:24:30 +0100 Subject: [PATCH 271/644] Enable rejointimeout by default --- src/d_clisrv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 4fdc7e7ee..02577b508 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -3112,7 +3112,7 @@ consvar_t cv_maxplayers = CVAR_INIT ("maxplayers", "8", CV_SAVE|CV_NETVAR, maxpl static CV_PossibleValue_t joindelay_cons_t[] = {{1, "MIN"}, {3600, "MAX"}, {0, "Off"}, {0, NULL}}; consvar_t cv_joindelay = CVAR_INIT ("joindelay", "10", CV_SAVE|CV_NETVAR, joindelay_cons_t, NULL); static CV_PossibleValue_t rejointimeout_cons_t[] = {{1, "MIN"}, {60 * FRACUNIT, "MAX"}, {0, "Off"}, {0, NULL}}; -consvar_t cv_rejointimeout = CVAR_INIT ("rejointimeout", "Off", CV_SAVE|CV_NETVAR|CV_FLOAT, rejointimeout_cons_t, NULL); +consvar_t cv_rejointimeout = CVAR_INIT ("rejointimeout", "2", CV_SAVE|CV_NETVAR|CV_FLOAT, rejointimeout_cons_t, NULL); static CV_PossibleValue_t resynchattempts_cons_t[] = {{1, "MIN"}, {20, "MAX"}, {0, "No"}, {0, NULL}}; consvar_t cv_resynchattempts = CVAR_INIT ("resynchattempts", "10", CV_SAVE|CV_NETVAR, resynchattempts_cons_t, NULL); From 7133c703b4c6a6cada6ee47f8c8fad9ee768f099 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Mon, 15 Feb 2021 22:19:48 +0100 Subject: [PATCH 272/644] Show an alternate ping icon when the player is disconnected --- src/hu_stuff.c | 50 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 1e69e6d51..7c4f1acf1 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -98,6 +98,7 @@ patch_t *emeraldpics[3][8]; // 0 = normal, 1 = tiny, 2 = coinbox static patch_t *emblemicon; patch_t *tokenicon; static patch_t *exiticon; +static patch_t *nopingicon; //------------------------------------------- // misc vars @@ -286,6 +287,7 @@ void HU_LoadGraphics(void) emblemicon = W_CachePatchName("EMBLICON", PU_HUDGFX); tokenicon = W_CachePatchName("TOKNICON", PU_HUDGFX); exiticon = W_CachePatchName("EXITICON", PU_HUDGFX); + nopingicon = W_CachePatchName("NOPINGICON", PU_HUDGFX); emeraldpics[0][0] = W_CachePatchName("CHAOS1", PU_HUDGFX); emeraldpics[0][1] = W_CachePatchName("CHAOS2", PU_HUDGFX); @@ -2246,8 +2248,8 @@ void HU_Erase(void) // void HU_drawPing(INT32 x, INT32 y, UINT32 ping, boolean notext, INT32 flags) { - UINT8 numbars = 1; // how many ping bars do we draw? - UINT8 barcolor = 35; // color we use for the bars (green, yellow or red) + UINT8 numbars = 0; // how many ping bars do we draw? + UINT8 barcolor = 31; // color we use for the bars (green, yellow, red or black) SINT8 i = 0; SINT8 yoffset = 6; INT32 dx = x+1 - (V_SmallStringWidth(va("%dms", ping), @@ -2260,11 +2262,16 @@ void HU_drawPing(INT32 x, INT32 y, UINT32 ping, boolean notext, INT32 flags) } else if (ping < 256) { - numbars = 2; // Apparently ternaries w/ multiple statements don't look good in C so I decided against it. + numbars = 2; barcolor = 73; } + else if (ping < UINT32_MAX) + { + numbars = 1; + barcolor = 35; + } - if (!notext || vid.width >= 640) // how sad, we're using a shit resolution. + if (ping < UINT32_MAX && (!notext || vid.width >= 640)) // how sad, we're using a shit resolution. V_DrawSmallString(dx, y+4, V_ALLOWLOWERCASE|flags, va("%dms", ping)); for (i=0; (i<3); i++) // Draw the ping bar @@ -2275,6 +2282,9 @@ void HU_drawPing(INT32 x, INT32 y, UINT32 ping, boolean notext, INT32 flags) yoffset -= 2; } + + if (ping == UINT32_MAX) + V_DrawSmallScaledPatch(x + 4 - nopingicon->width/2, y + 9 - nopingicon->height/2, 0, nopingicon); } // @@ -2301,8 +2311,8 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I if (!splitscreen) // don't draw it on splitscreen, { - if (!(tab[i].num == serverplayer || players[tab[i].num].quittime)) - HU_drawPing(x+ 253, y, playerpingtable[tab[i].num], false, 0); + if (tab[i].num != serverplayer) + HU_drawPing(x + 253, y, players[tab[i].num].quittime ? UINT32_MAX : playerpingtable[tab[i].num], false, 0); //else // V_DrawSmallString(x+ 246, y+4, V_YELLOWMAP, "SERVER"); } @@ -2502,10 +2512,10 @@ static void HU_Draw32TeamTabRankings(playersort_t *tab, INT32 whiteplayer) V_DrawRightAlignedThinString(x+128, y, ((players[tab[i].num].spectator || players[tab[i].num].playerstate == PST_DEAD) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count)); if (!splitscreen) { - if (!(tab[i].num == serverplayer || players[tab[i].num].quittime)) - HU_drawPing(x+ 135, y+1, playerpingtable[tab[i].num], true, 0); - //else - //V_DrawSmallString(x+ 129, y+4, V_YELLOWMAP, "HOST"); + if (tab[i].num != serverplayer) + HU_drawPing(x + 135, y+1, players[tab[i].num].quittime ? UINT32_MAX : playerpingtable[tab[i].num], true, 0); + //else + //V_DrawSmallString(x+ 129, y+4, V_YELLOWMAP, "HOST"); } } } @@ -2627,10 +2637,10 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer) V_DrawRightAlignedThinString(x+100, y, (greycheck ? V_TRANSLUCENT : 0), va("%u", tab[i].count)); if (!splitscreen) { - if (!(tab[i].num == serverplayer || players[tab[i].num].quittime)) - HU_drawPing(x+ 113, y, playerpingtable[tab[i].num], false, 0); - //else - // V_DrawSmallString(x+ 94, y+4, V_YELLOWMAP, "SERVER"); + if (tab[i].num != serverplayer) + HU_drawPing(x+ 113, y, players[tab[i].num].quittime ? UINT32_MAX : playerpingtable[tab[i].num], false, 0); + //else + // V_DrawSmallString(x+ 94, y+4, V_YELLOWMAP, "SERVER"); } } } @@ -2658,8 +2668,8 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline supercheck = supercheckdef; strlcpy(name, tab[i].name, 7); - if (!(tab[i].num == serverplayer || players[tab[i].num].quittime)) - HU_drawPing(x+ 113, y, playerpingtable[tab[i].num], false, 0); + if (tab[i].num != serverplayer) + HU_drawPing(x+ 113, y, players[tab[i].num].quittime ? UINT32_MAX : playerpingtable[tab[i].num], false, 0); //else // V_DrawSmallString(x+ 94, y+4, V_YELLOWMAP, "SERVER"); @@ -2767,10 +2777,10 @@ static void HU_Draw32TabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scor strlcpy(name, tab[i].name, 7); if (!splitscreen) // don't draw it on splitscreen, { - if (!(tab[i].num == serverplayer || players[tab[i].num].quittime)) - HU_drawPing(x+ 135, y+1, playerpingtable[tab[i].num], true, 0); - //else - // V_DrawSmallString(x+ 129, y+4, V_YELLOWMAP, "HOST"); + if (tab[i].num != serverplayer) + HU_drawPing(x+ 135, y+1, players[tab[i].num].quittime ? UINT32_MAX : playerpingtable[tab[i].num], true, 0); + //else + // V_DrawSmallString(x+ 129, y+4, V_YELLOWMAP, "HOST"); } if (!players[tab[i].num].quittime || (leveltime / (TICRATE/2) & 1)) From 205ccc2727a2c755d9e44dcd662cd8d4d1b6db68 Mon Sep 17 00:00:00 2001 From: "X.organic" Date: Tue, 16 Feb 2021 19:46:31 +0100 Subject: [PATCH 273/644] Move Dehacked table sanity check to deh_tables.c --- src/d_main.c | 2 +- src/deh_tables.c | 24 ++++++++++++++++++++++++ src/deh_tables.h | 3 +++ src/dehacked.c | 22 ---------------------- src/dehacked.h | 2 -- 5 files changed, 28 insertions(+), 25 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index a89f4ed2d..409a66bec 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1072,7 +1072,7 @@ void D_SRB2Main(void) G_LoadGameSettings(); // Test Dehacked lists - DEH_Check(); + DEH_TableCheck(); // Netgame URL special case: change working dir to EXE folder. ChangeDirForUrlHandler(); diff --git a/src/deh_tables.c b/src/deh_tables.c index 3039bf7de..dd6d7d69f 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -5457,3 +5457,27 @@ struct int_const_s const INT_CONST[] = { {NULL,0} }; + +// For this to work compile-time without being in this file, +// this function would need to check sizes at runtime, without sizeof +void DEH_TableCheck(void) +{ +#if defined(_DEBUG) || defined(PARANOIA) + const size_t dehstates = sizeof(STATE_LIST)/sizeof(const char*); + const size_t dehmobjs = sizeof(MOBJTYPE_LIST)/sizeof(const char*); + const size_t dehpowers = sizeof(POWERS_LIST)/sizeof(const char*); + const size_t dehcolors = sizeof(COLOR_ENUMS)/sizeof(const char*); + + if (dehstates != S_FIRSTFREESLOT) + I_Error("You forgot to update the Dehacked states list, you dolt!\n(%d states defined, versus %s in the Dehacked list)\n", S_FIRSTFREESLOT, sizeu1(dehstates)); + + if (dehmobjs != MT_FIRSTFREESLOT) + I_Error("You forgot to update the Dehacked mobjtype list, you dolt!\n(%d mobj types defined, versus %s in the Dehacked list)\n", MT_FIRSTFREESLOT, sizeu1(dehmobjs)); + + if (dehpowers != NUMPOWERS) + I_Error("You forgot to update the Dehacked powers list, you dolt!\n(%d powers defined, versus %s in the Dehacked list)\n", NUMPOWERS, sizeu1(dehpowers)); + + if (dehcolors != SKINCOLOR_FIRSTFREESLOT) + I_Error("You forgot to update the Dehacked colors list, you dolt!\n(%d colors defined, versus %s in the Dehacked list)\n", SKINCOLOR_FIRSTFREESLOT, sizeu1(dehcolors)); +#endif +} diff --git a/src/deh_tables.h b/src/deh_tables.h index 2c6b3e204..d094bcbad 100644 --- a/src/deh_tables.h +++ b/src/deh_tables.h @@ -72,4 +72,7 @@ extern const char *const MENUTYPES_LIST[]; extern struct int_const_s const INT_CONST[]; +// Moved to this file because it can't work compile-time otherwise +void DEH_TableCheck(void); + #endif diff --git a/src/dehacked.c b/src/dehacked.c index b42663267..c2ea28d27 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -645,25 +645,3 @@ void DEH_LoadDehackedLump(lumpnum_t lumpnum) { DEH_LoadDehackedLumpPwad(WADFILENUM(lumpnum),LUMPNUM(lumpnum), false); } - -void DEH_Check(void) -{ -#if defined(_DEBUG) || defined(PARANOIA) - const size_t dehstates = sizeof(STATE_LIST)/sizeof(const char*); - const size_t dehmobjs = sizeof(MOBJTYPE_LIST)/sizeof(const char*); - const size_t dehpowers = sizeof(POWERS_LIST)/sizeof(const char*); - const size_t dehcolors = sizeof(COLOR_ENUMS)/sizeof(const char*); - - if (dehstates != S_FIRSTFREESLOT) - I_Error("You forgot to update the Dehacked states list, you dolt!\n(%d states defined, versus %s in the Dehacked list)\n", S_FIRSTFREESLOT, sizeu1(dehstates)); - - if (dehmobjs != MT_FIRSTFREESLOT) - I_Error("You forgot to update the Dehacked mobjtype list, you dolt!\n(%d mobj types defined, versus %s in the Dehacked list)\n", MT_FIRSTFREESLOT, sizeu1(dehmobjs)); - - if (dehpowers != NUMPOWERS) - I_Error("You forgot to update the Dehacked powers list, you dolt!\n(%d powers defined, versus %s in the Dehacked list)\n", NUMPOWERS, sizeu1(dehpowers)); - - if (dehcolors != SKINCOLOR_FIRSTFREESLOT) - I_Error("You forgot to update the Dehacked colors list, you dolt!\n(%d colors defined, versus %s in the Dehacked list)\n", SKINCOLOR_FIRSTFREESLOT, sizeu1(dehcolors)); -#endif -} diff --git a/src/dehacked.h b/src/dehacked.h index d5256be23..1620314ca 100644 --- a/src/dehacked.h +++ b/src/dehacked.h @@ -30,8 +30,6 @@ typedef enum void DEH_LoadDehackedLump(lumpnum_t lumpnum); void DEH_LoadDehackedLumpPwad(UINT16 wad, UINT16 lump, boolean mainfile); -void DEH_Check(void); - fixed_t get_number(const char *word); FUNCPRINTF void deh_warning(const char *first, ...); void deh_strlcpy(char *dst, const char *src, size_t size, const char *warntext); From 90611ed547044d6902ad61008a8eca2be393074e Mon Sep 17 00:00:00 2001 From: "X.organic" Date: Tue, 16 Feb 2021 21:36:28 +0100 Subject: [PATCH 274/644] Fix MOBJCONSISTANCY and make it optional in DEBUGMODE MOBJCONSISTANCY checks confined to gamestate GS_LEVEL. DEBUGMODE no longer implicitly enables them, making it netgame-compatible. --- src/Makefile | 2 +- src/d_clisrv.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index 1314161bd..67560caf6 100644 --- a/src/Makefile +++ b/src/Makefile @@ -415,7 +415,7 @@ ifdef GCC48 else CFLAGS+=-O0 endif - CFLAGS+= -Wall -DPARANOIA -DRANGECHECK -DPACKETDROP -DMOBJCONSISTANCY + CFLAGS+= -Wall -DPARANOIA -DRANGECHECK -DPACKETDROP else diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 02577b508..1b6b4cd1f 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -4480,6 +4480,7 @@ static INT16 Consistancy(void) ret += P_GetRandSeed(); #ifdef MOBJCONSISTANCY +if (gamestate == GS_LEVEL) { for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) @@ -4546,6 +4547,7 @@ static INT16 Consistancy(void) ret += mo->frame; } } +} #endif DEBFILE(va("Consistancy = %u\n", (ret & 0xFFFF))); From 0cbf9a791b883e7a819aceaa4a0a7e330dccdb15 Mon Sep 17 00:00:00 2001 From: "X.organic" Date: Tue, 16 Feb 2021 23:27:44 +0100 Subject: [PATCH 275/644] Fix indentation in MOBJCONSISTANCY conditional --- src/d_clisrv.c | 125 +++++++++++++++++++++++++------------------------ 1 file changed, 63 insertions(+), 62 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 1b6b4cd1f..7c2dec6a1 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -4480,74 +4480,75 @@ static INT16 Consistancy(void) ret += P_GetRandSeed(); #ifdef MOBJCONSISTANCY -if (gamestate == GS_LEVEL) { - for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) + if (gamestate == GS_LEVEL) { - if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - continue; - - mo = (mobj_t *)th; - - if (mo->flags & (MF_SPECIAL | MF_SOLID | MF_PUSHABLE | MF_BOSS | MF_MISSILE | MF_SPRING | MF_MONITOR | MF_FIRE | MF_ENEMY | MF_PAIN | MF_STICKY)) + for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) { - ret -= mo->type; - ret += mo->x; - ret -= mo->y; - ret += mo->z; - ret -= mo->momx; - ret += mo->momy; - ret -= mo->momz; - ret += mo->angle; - ret -= mo->flags; - ret += mo->flags2; - ret -= mo->eflags; - if (mo->target) + if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + + mo = (mobj_t *)th; + + if (mo->flags & (MF_SPECIAL | MF_SOLID | MF_PUSHABLE | MF_BOSS | MF_MISSILE | MF_SPRING | MF_MONITOR | MF_FIRE | MF_ENEMY | MF_PAIN | MF_STICKY)) { - ret += mo->target->type; - ret -= mo->target->x; - ret += mo->target->y; - ret -= mo->target->z; - ret += mo->target->momx; - ret -= mo->target->momy; - ret += mo->target->momz; - ret -= mo->target->angle; - ret += mo->target->flags; - ret -= mo->target->flags2; - ret += mo->target->eflags; - ret -= mo->target->state - states; - ret += mo->target->tics; - ret -= mo->target->sprite; - ret += mo->target->frame; + ret -= mo->type; + ret += mo->x; + ret -= mo->y; + ret += mo->z; + ret -= mo->momx; + ret += mo->momy; + ret -= mo->momz; + ret += mo->angle; + ret -= mo->flags; + ret += mo->flags2; + ret -= mo->eflags; + if (mo->target) + { + ret += mo->target->type; + ret -= mo->target->x; + ret += mo->target->y; + ret -= mo->target->z; + ret += mo->target->momx; + ret -= mo->target->momy; + ret += mo->target->momz; + ret -= mo->target->angle; + ret += mo->target->flags; + ret -= mo->target->flags2; + ret += mo->target->eflags; + ret -= mo->target->state - states; + ret += mo->target->tics; + ret -= mo->target->sprite; + ret += mo->target->frame; + } + else + ret ^= 0x3333; + if (mo->tracer && mo->tracer->type != MT_OVERLAY) + { + ret += mo->tracer->type; + ret -= mo->tracer->x; + ret += mo->tracer->y; + ret -= mo->tracer->z; + ret += mo->tracer->momx; + ret -= mo->tracer->momy; + ret += mo->tracer->momz; + ret -= mo->tracer->angle; + ret += mo->tracer->flags; + ret -= mo->tracer->flags2; + ret += mo->tracer->eflags; + ret -= mo->tracer->state - states; + ret += mo->tracer->tics; + ret -= mo->tracer->sprite; + ret += mo->tracer->frame; + } + else + ret ^= 0xAAAA; + ret -= mo->state - states; + ret += mo->tics; + ret -= mo->sprite; + ret += mo->frame; } - else - ret ^= 0x3333; - if (mo->tracer && mo->tracer->type != MT_OVERLAY) - { - ret += mo->tracer->type; - ret -= mo->tracer->x; - ret += mo->tracer->y; - ret -= mo->tracer->z; - ret += mo->tracer->momx; - ret -= mo->tracer->momy; - ret += mo->tracer->momz; - ret -= mo->tracer->angle; - ret += mo->tracer->flags; - ret -= mo->tracer->flags2; - ret += mo->tracer->eflags; - ret -= mo->tracer->state - states; - ret += mo->tracer->tics; - ret -= mo->tracer->sprite; - ret += mo->tracer->frame; - } - else - ret ^= 0xAAAA; - ret -= mo->state - states; - ret += mo->tics; - ret -= mo->sprite; - ret += mo->frame; } } -} #endif DEBFILE(va("Consistancy = %u\n", (ret & 0xFFFF))); From 998d06569880aa79e310484d7baa7fdd638d9083 Mon Sep 17 00:00:00 2001 From: sphere Date: Wed, 17 Feb 2021 16:06:02 +0100 Subject: [PATCH 276/644] Add more actions for slope copying & update the ZB config. --- extras/conf/SRB2-22.cfg | 78 +++++++++++++++++++++++++++++++++++++++++ src/p_setup.c | 28 +++++++++++++++ 2 files changed, 106 insertions(+) diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg index a0d40cdf0..b7ba56ba7 100644 --- a/extras/conf/SRB2-22.cfg +++ b/extras/conf/SRB2-22.cfg @@ -3059,6 +3059,84 @@ linedeftypes slopeargs = 3; } + 723 + { + title = "Copy Backside Floor Slope from Line Tag"; + prefix = "(720)"; + slope = "copy"; + slopeargs = 4; + } + + 724 + { + title = "Copy Backside Ceiling Slope from Line Tag"; + prefix = "(721)"; + slope = "copy"; + slopeargs = 8; + } + + 725 + { + title = "Copy Backside Floor and Ceiling Slope from Line Tag"; + prefix = "(722)"; + slope = "copy"; + slopeargs = 12; + } + + 730 + { + title = "Copy Frontside Floor Slope to Backside"; + prefix = "(730)"; + slope = "copy"; + slopeargs = 1; + //copyslopeargs = 1; uncomment when ZB updates + } + + 731 + { + title = "Copy Frontside Ceiling Slope to Backside"; + prefix = "(731)"; + slope = "copy"; + slopeargs = 2; + //copyslopeargs = 4; uncomment when ZB updates + } + + 732 + { + title = "Copy Frontside Floor and Ceiling Slope to Backside"; + prefix = "(732)"; + slope = "copy"; + slopeargs = 3; + //copyslopeargs = 5; uncomment when ZB updates + } + + 733 + { + title = "Copy Backside Floor Slope to Frontside"; + prefix = "(730)"; + slope = "copy"; + slopeargs = 1; + //copyslopeargs = 2; uncomment when ZB updates + } + + 734 + { + title = "Copy Backside Ceiling Slope to Frontside"; + prefix = "(731)"; + slope = "copy"; + slopeargs = 2; + //copyslopeargs = 8; uncomment when ZB updates + } + + 735 + { + title = "Copy Backside Floor and Ceiling Slope to Frontside"; + prefix = "(732)"; + slope = "copy"; + slopeargs = 3; + //copyslopeargs = 10; uncomment when ZB updates + } + 799 { title = "Set Tagged Dynamic Slope Vertex to Front Sector Height"; diff --git a/src/p_setup.c b/src/p_setup.c index 66243fb0e..1c70c01e6 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3141,6 +3141,34 @@ static void P_ConvertBinaryMap(void) lines[i].args[1] = tag; lines[i].special = 720; break; + case 723: //Copy back side floor slope + case 724: //Copy back side ceiling slope + case 725: //Copy back side floor and ceiling slope + if (lines[i].special != 724) + lines[i].args[2] = tag; + if (lines[i].special != 723) + lines[i].args[3] = tag; + lines[i].special = 720; + break; + case 730: //Copy front side floor slope to back side + case 731: //Copy front side ceiling slope to back side + case 732: //Copy front side floor and ceiling slope to back side + if (lines[i].special != 731) + lines[i].args[4] |= TMSC_FRONTTOBACKFLOOR; + if (lines[i].special != 730) + lines[i].args[4] |= TMSC_FRONTTOBACKCEILING; + lines[i].special = 720; + break; + case 733: //Copy back side floor slope to front side + case 734: //Copy back side ceiling slope to front side + case 735: //Copy back side floor and ceiling slope to front side + if (lines[i].special != 734) + lines[i].args[4] |= TMSC_BACKTOFRONTFLOOR; + if (lines[i].special != 733) + lines[i].args[4] |= TMSC_BACKTOFRONTCEILING; + lines[i].special = 720; + break; + case 900: //Translucent wall (10%) case 901: //Translucent wall (20%) case 902: //Translucent wall (30%) From 3003c252d12651111498e47eb9d372c0e8794a75 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 18 Feb 2021 05:16:15 -0800 Subject: [PATCH 277/644] Makfile: don't print some messages twice --- src/Makefile | 10 +++++++--- src/Makefile.cfg | 10 ++++++---- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/Makefile b/src/Makefile index 42b757940..1186fe915 100644 --- a/src/Makefile +++ b/src/Makefile @@ -2,7 +2,7 @@ # GNU Make makefile for SRB2 ############################################################################# # Copyright (C) 1998-2000 by DooM Legacy Team. -# Copyright (C) 2003-2020 by Sonic Team Junior. +# Copyright (C) 2003-2021 by Sonic Team Junior. # # This program is free software distributed under the # terms of the GNU General Public License, version 2. @@ -79,6 +79,10 @@ # ############################################################################# +ifndef MAKE_RESTARTS +print=$(info $(1)) +endif + ALL_SYSTEMS=\ PANDORA\ LINUX64\ @@ -98,7 +102,7 @@ ALL_SYSTEMS=\ ifeq (,$(filter $(ALL_SYSTEMS),$(.VARIABLES))) ifeq ($(OS),Windows_NT) # all windows are Windows_NT... - $(info Detected a Windows system, compiling for 32-bit MinGW SDL2...) + $(call print,Detected a Windows system, compiling for 32-bit MinGW SDL2...) # go for a 32-bit sdl mingw exe by default MINGW=1 @@ -123,7 +127,7 @@ else # if you on the *nix new_system:=$(new_system)64 endif - $(info Detected $(system) ($(new_system))...) + $(call print,Detected $(system) ($(new_system))...) $(new_system)=1 endif diff --git a/src/Makefile.cfg b/src/Makefile.cfg index f081eacdf..c323f4ffd 100644 --- a/src/Makefile.cfg +++ b/src/Makefile.cfg @@ -60,12 +60,14 @@ ifeq (,$(filter GCC%,$(.VARIABLES))) # If this version is not in the list, default to the latest supported ifeq (,$(filter $(v),$(SUPPORTED_GCC_VERSIONS))) - $(info\ - Your compiler version, GCC $(version), is not supported by the Makefile.\ - The Makefile will assume GCC $(LATEST_GCC_VERSION).) + define line = + Your compiler version, GCC $(version), is not supported by the Makefile. + The Makefile will assume GCC $(LATEST_GCC_VERSION).)) + endef + $(call print,$(line)) GCC$(subst .,,$(LATEST_GCC_VERSION))=1 else - $(info Detected GCC $(version) (GCC$(v))) + $(call print,Detected GCC $(version) (GCC$(v))) GCC$(v)=1 endif endif From 3d32f3145cf1bec85f77c33908a8bfc6772bd779 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 18 Feb 2021 06:15:11 -0800 Subject: [PATCH 278/644] Generate individual dependency files This removes Makefile.depends. Instead, '.d' files are included from the 'dep' directory. This speeds up building because dependencies for every file don't need to be regenerated if only one changes. As a bonus, dependencies also won't be generated if only clean type targets are going to be run. Also added a 'distclean' target, which cleans both objects and dependency files. --- src/Makefile | 57 ++++++++++++++++++++++++------------------------ src/Makefile.cfg | 13 +++++++++++ 2 files changed, 41 insertions(+), 29 deletions(-) diff --git a/src/Makefile b/src/Makefile index 1186fe915..3e8c33624 100644 --- a/src/Makefile +++ b/src/Makefile @@ -24,7 +24,9 @@ # clean # Remove all object files # cleandep -# Remove depend.dep +# Remove dependency files +# distclean +# Remove autogenerated files # dll # compile primary HW render DLL/SO # all_dll @@ -459,7 +461,6 @@ DBGNAME?=$(EXENAME).debug # not too sophisticated dependency OBJS:=$(i_main_o) \ - $(OBJDIR)/comptime.o \ $(OBJDIR)/string.o \ $(OBJDIR)/d_main.o \ $(OBJDIR)/d_clisrv.o \ @@ -539,6 +540,8 @@ OBJS:=$(i_main_o) \ $(i_sound_o) \ $(OBJS) +DEPS:=$(patsubst $(OBJDIR)/%.o,$(DEPDIR)/%.d,$(OBJS)) +OBJS+=$(OBJDIR)/comptime.o ifndef ECHO ifndef NOECHOFILENAMES @@ -559,12 +562,12 @@ OPTS+=-DGETTEXT endif ifdef PANDORA -all: pre-build $(BIN)/$(PNDNAME) +all: $(BIN)/$(PNDNAME) endif ifdef SDL -all: pre-build $(BIN)/$(EXENAME) +all: $(BIN)/$(EXENAME) endif ifdef DUMMY @@ -572,20 +575,15 @@ all: $(BIN)/$(EXENAME) endif cleandep: - $(REMOVE) $(OBJDIR)/depend.dep + $(REMOVE) $(DEPS) $(REMOVE) comptime.h -pre-build: -ifdef WINDOWSHELL - -..\comptime.bat . -else - -@../comptime.sh . -endif - clean: $(REMOVE) *~ *.flc $(REMOVE) $(OBJDIR)/*.o +distclean: clean cleandep + ifdef MINGW $(REMOVE) $(OBJDIR)/*.res endif @@ -667,24 +665,21 @@ endif endif #dependecy made by gcc itself ! -$(OBJS): ifndef DUMMY --include $(OBJDIR)/depend.dep +ifneq (,$(filter-out cleandep clean distclean,$(or $(MAKECMDGOALS),all))) +$(call print,Checking dependency files...) +-include $(DEPS) +endif endif -$(OBJDIR)/depend.dep: - @echo "Creating dependency file, depend.dep" - @echo > comptime.h - -$(MKDIR) $(OBJDIR) - $(CC) $(CFLAGS) -MM *.c > $(OBJDIR)/depend.ped - $(CC) $(CFLAGS) -MM $(INTERFACE)/*.c >> $(OBJDIR)/depend.ped -ifndef NOHW - $(CC) $(CFLAGS) -MM hardware/*.c >> $(OBJDIR)/depend.ped +$(DEPDIR)/%.d: %.c +# windows makes it too hard ! +ifndef WINDOWSHELL +ifndef ECHO + @printf "%-20.20s\r" $< endif - $(CC) $(CFLAGS) -MM blua/*.c >> $(OBJDIR)/depend.ped - @sed -e 's,\(.*\)\.o: ,$(subst /,\/,$(OBJDIR))\/&,g' < $(OBJDIR)/depend.ped > $(OBJDIR)/depend.dep - $(REMOVE) $(OBJDIR)/depend.ped - @echo "Created dependency file, depend.dep" +endif + $(CC) $(CFLAGS) -M -MF $@ -MT $(OBJDIR)/$< $< ifdef VALGRIND $(OBJDIR)/z_zone.o: z_zone.c @@ -692,9 +687,13 @@ $(OBJDIR)/z_zone.o: z_zone.c $(CC) $(CFLAGS) $(WFLAGS) -DHAVE_VALGRIND $(VALGRIND_CFLAGS) -c $< -o $@ endif -$(OBJDIR)/comptime.o: comptime.c pre-build - $(echoName) - $(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@ +$(OBJDIR)/comptime.o:: +ifdef WINDOWSHELL + -..\comptime.bat . +else + -../comptime.sh . +endif + $(CC) $(CFLAGS) $(WFLAGS) -c comptime.c -o $@ $(BIN)/%.mo: locale/%.po -$(MKDIR) $(BIN) diff --git a/src/Makefile.cfg b/src/Makefile.cfg index c323f4ffd..ec19e9f85 100644 --- a/src/Makefile.cfg +++ b/src/Makefile.cfg @@ -363,6 +363,7 @@ i_main_o=$(OBJDIR)/i_main.o #set OBJDIR and BIN's starting place OBJDIR=../objs BIN=../bin +DEPDIR=../dep #Nasm ASM and rm ifdef YASM NASM?=yasm @@ -385,6 +386,7 @@ ifdef DUMMY INTERFACE=dummy OBJDIR:=$(OBJDIR)/dummy BIN:=$(BIN)/dummy + DEPDIR:=$(DEPDIR)/dummy else ifdef LINUX NASMFORMAT=elf -DLINUX @@ -392,9 +394,11 @@ ifdef LINUX ifdef LINUX64 OBJDIR:=$(OBJDIR)/Linux64 BIN:=$(BIN)/Linux64 + DEPDIR:=$(DEPDIR)/Linux64 else OBJDIR:=$(OBJDIR)/Linux BIN:=$(BIN)/Linux + DEPDIR:=$(DEPDIR)/Linux endif else ifdef FREEBSD @@ -404,6 +408,7 @@ ifdef FREEBSD OBJDIR:=$(OBJDIR)/FreeBSD BIN:=$(BIN)/FreeBSD + DEPDIR:=$(DEPDIR)/Linux else ifdef SOLARIS INTERFACE=sdl @@ -412,6 +417,7 @@ ifdef SOLARIS OBJDIR:=$(OBJDIR)/Solaris BIN:=$(BIN)/Solaris + DEPDIR:=$(DEPDIR)/Solaris else ifdef CYGWIN32 INTERFACE=sdl @@ -420,18 +426,21 @@ ifdef CYGWIN32 OBJDIR:=$(OBJDIR)/cygwin BIN:=$(BIN)/Cygwin + DEPDIR:=$(DEPDIR)/Cygwin else ifdef MINGW64 #NASMFORMAT=win64 SDL=1 OBJDIR:=$(OBJDIR)/Mingw64 BIN:=$(BIN)/Mingw64 + DEPDIR:=$(DEPDIR)/Mingw64 else ifdef MINGW NASMFORMAT=win32 SDL=1 OBJDIR:=$(OBJDIR)/Mingw BIN:=$(BIN)/Mingw + DEPDIR:=$(DEPDIR)/Mingw endif endif endif @@ -443,6 +452,7 @@ endif ifdef ARCHNAME OBJDIR:=$(OBJDIR)/$(ARCHNAME) BIN:=$(BIN)/$(ARCHNAME) + DEPDIR:=$(DEPDIR)/$(ARCHNAME) endif OBJDUMP_OPTS?=--wide --source --line-numbers @@ -451,14 +461,17 @@ LD=$(CC) ifdef SDL INTERFACE=sdl OBJDIR:=$(OBJDIR)/SDL + DEPDIR:=$(DEPDIR)/SDL endif ifndef DUMMY ifdef DEBUGMODE OBJDIR:=$(OBJDIR)/Debug BIN:=$(BIN)/Debug + DEPDIR:=$(DEPDIR)/Debug else OBJDIR:=$(OBJDIR)/Release BIN:=$(BIN)/Release + DEPDIR:=$(DEPDIR)/Release endif endif From 747c278bc2380d5f48c0c939de1ef3994d44b6c4 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 18 Feb 2021 07:03:25 -0800 Subject: [PATCH 279/644] Makefile: add a SILENT flag This makes it print nothing to stdout. Also fixed some irregularities. --- src/Makefile | 37 ++++++++++++++++++++++++++----------- src/Makefile.cfg | 3 ++- 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/src/Makefile b/src/Makefile index 3e8c33624..260175a69 100644 --- a/src/Makefile +++ b/src/Makefile @@ -81,9 +81,16 @@ # ############################################################################# +,=, + +ifeq (,$(filter-out cleandep clean distclean,$(or $(MAKECMDGOALS),all))) +CLEANONLY=1 +else ifndef SILENT +echo=@echo "$(1)" ifndef MAKE_RESTARTS print=$(info $(1)) endif +endif ALL_SYSTEMS=\ PANDORA\ @@ -104,7 +111,7 @@ ALL_SYSTEMS=\ ifeq (,$(filter $(ALL_SYSTEMS),$(.VARIABLES))) ifeq ($(OS),Windows_NT) # all windows are Windows_NT... - $(call print,Detected a Windows system, compiling for 32-bit MinGW SDL2...) + $(call print,Detected a Windows system$(,) compiling for 32-bit MinGW SDL2...) # go for a 32-bit sdl mingw exe by default MINGW=1 @@ -243,6 +250,12 @@ endif MSGFMT?=msgfmt +ifdef WINDOWSHELL + COMPTIME=-..\comptime.bat +else + COMPTIME=-../comptime.sh +endif + ifndef ECHO NASM:=@$(NASM) REMOVE:=@$(REMOVE) @@ -257,6 +270,7 @@ ifndef ECHO MSGFMT:=@$(MSGFMT) UPX:=@$(UPX) UPX_OPTS+=-q + COMPTIME:=@$(COMPTIME) endif ifdef NONET @@ -543,6 +557,7 @@ OBJS:=$(i_main_o) \ DEPS:=$(patsubst $(OBJDIR)/%.o,$(DEPDIR)/%.d,$(OBJS)) OBJS+=$(OBJDIR)/comptime.o +ifndef SILENT ifndef ECHO ifndef NOECHOFILENAMES define echoName = @@ -550,6 +565,7 @@ define echoName = endef endif endif +endif # List of languages to compile. # For reference, this is the command I use to build a srb2.pot file from the source code. @@ -603,11 +619,11 @@ asm: $(BIN)/$(EXENAME): $(POS) $(OBJS) -$(MKDIR) $(BIN) - @echo Linking $(EXENAME)... + $(call echo,Linking $(EXENAME)...) $(LD) $(LDFLAGS) $(OBJS) -o $(BIN)/$(EXENAME) $(LIBS) ifndef VALGRIND ifndef NOOBJDUMP - @echo Dumping debugging info + $(call echo,Dumping debugging info) $(OBJDUMP) $(OBJDUMP_OPTS) $(BIN)/$(EXENAME) > $(BIN)/$(DBGNAME).txt ifdef WINDOWSHELL -$(GZIP) $(GZIP_OPTS) $(BIN)/$(DBGNAME).txt @@ -626,10 +642,10 @@ ifndef NOUPX -$(UPX) $(UPX_OPTS) $(BIN)/$(EXENAME) endif endif - @echo Build is done, please look for $(EXENAME) in $(BIN), \(checking for post steps\) + $(call echo,Build is done$(,) please look for $(EXENAME) in $(BIN)$(,) (checking for post steps)) reobjdump: - @echo Redumping debugging info + $(call echo,Redumping debugging info) $(OBJDUMP) $(OBJDUMP_OPTS) $(BIN)/$(DBGNAME) > $(BIN)/$(DBGNAME).txt ifdef WINDOWSHELL -$(GZIP) $(GZIP_OPTS) $(BIN)/$(DBGNAME).txt @@ -666,7 +682,7 @@ endif #dependecy made by gcc itself ! ifndef DUMMY -ifneq (,$(filter-out cleandep clean distclean,$(or $(MAKECMDGOALS),all))) +ifndef CLEANONLY $(call print,Checking dependency files...) -include $(DEPS) endif @@ -675,7 +691,7 @@ endif $(DEPDIR)/%.d: %.c # windows makes it too hard ! ifndef WINDOWSHELL -ifndef ECHO +ifdef echoName @printf "%-20.20s\r" $< endif endif @@ -688,11 +704,10 @@ $(OBJDIR)/z_zone.o: z_zone.c endif $(OBJDIR)/comptime.o:: -ifdef WINDOWSHELL - -..\comptime.bat . -else - -../comptime.sh . +ifdef echoName + @echo -- comptime.c ... endif + $(COMPTIME) . $(CC) $(CFLAGS) $(WFLAGS) -c comptime.c -o $@ $(BIN)/%.mo: locale/%.po diff --git a/src/Makefile.cfg b/src/Makefile.cfg index ec19e9f85..075cd2d3a 100644 --- a/src/Makefile.cfg +++ b/src/Makefile.cfg @@ -47,7 +47,8 @@ ifdef MACOSX endif # Automatically set version flag, but not if one was manually set -ifeq (,$(filter GCC%,$(.VARIABLES))) +# And don't bother if this is a clean only run +ifeq (,$(filter GCC% CLEANONLY,$(.VARIABLES))) version:=$(shell $(CC) --version) # check if this is in fact GCC ifneq (,$(or $(findstring gcc,$(version)),$(findstring GCC,$(version)))) From 73758f50ff5586f537a2e414519bc4b8ae8103f4 Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 19 Feb 2021 06:45:28 -0500 Subject: [PATCH 280/644] Fix dropshadows of papersprites drifting depending on angle relative to camera. Discovered in Kart internal for the paper item drops and ported back, hence the branch name. --- src/r_things.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 30bf15f85..bea40c810 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1423,7 +1423,7 @@ static void R_ProjectSprite(mobj_t *thing) fixed_t sheartan = 0; fixed_t shadowscale = FRACUNIT; - fixed_t basetx; // drop shadows + fixed_t basetx, basetz; // drop shadows boolean shadowdraw, shadoweffects, shadowskew; boolean splat = R_ThingIsFloorSprite(thing); @@ -1453,7 +1453,7 @@ static void R_ProjectSprite(mobj_t *thing) tr_x = thing->x - viewx; tr_y = thing->y - viewy; - tz = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin); // near/far distance + basetz = tz = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin); // near/far distance // thing is behind view plane? if (!papersprite && (tz < FixedMul(MINZ, this_scale))) // papersprite clipping is handled later @@ -2052,7 +2052,7 @@ static void R_ProjectSprite(mobj_t *thing) R_SplitSprite(vis); if (oldthing->shadowscale && cv_shadow.value) - R_ProjectDropShadow(oldthing, vis, oldthing->shadowscale, basetx, tz); + R_ProjectDropShadow(oldthing, vis, oldthing->shadowscale, basetx, basetz); // Debug ++objectsdrawn; From 308ab0e0791abe16fd1109c0c48e6a249592cfe9 Mon Sep 17 00:00:00 2001 From: Zwip-Zwap Zapony Date: Sun, 21 Feb 2021 22:16:38 +0100 Subject: [PATCH 281/644] Fix OpenGL V_DrawCroppedPatch --- src/hardware/hw_draw.c | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index 8c92c6709..ba4923d10 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -437,18 +437,9 @@ void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, if (!(option & V_SCALEPATCHMASK)) { - // if it's meant to cover the whole screen, black out the rest (ONLY IF TOP LEFT ISN'T TRANSPARENT) - // cx and cy are possibly *slightly* off from float maths - // This is done before here compared to software because we directly alter cx and cy to centre - if (cx >= -0.1f && cx <= 0.1f && gpatch->width == BASEVIDWIDTH && cy >= -0.1f && cy <= 0.1f && gpatch->height == BASEVIDHEIGHT) - { - const column_t *column = (const column_t *)((const UINT8 *)(gpatch->columns) + (gpatch->columnofs[0])); - if (!column->topdelta) - { - const UINT8 *source = (const UINT8 *)(column) + 3; - HWR_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0])); - } - } + // if it's meant to cover the whole screen, black out the rest + // no the patch is cropped do not do this ever + // centre screen if (fabsf((float)vid.width - (float)BASEVIDWIDTH * dupx) > 1.0E-36f) { @@ -470,11 +461,11 @@ void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, fwidth = w; fheight = h; - if (fwidth > gpatch->width) - fwidth = gpatch->width; + if (sx + w > gpatch->width) + fwidth = gpatch->width - sx; - if (fheight > gpatch->height) - fheight = gpatch->height; + if (sy + h > gpatch->height) + fheight = gpatch->height - sy; if (pscale != FRACUNIT) { @@ -506,13 +497,13 @@ void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, v[0].s = v[3].s = ((sx)/(float)(gpatch->width))*hwrPatch->max_s; if (sx + w > gpatch->width) - v[2].s = v[1].s = hwrPatch->max_s - ((sx+w)/(float)(gpatch->width))*hwrPatch->max_s; + v[2].s = v[1].s = hwrPatch->max_s; else v[2].s = v[1].s = ((sx+w)/(float)(gpatch->width))*hwrPatch->max_s; v[0].t = v[1].t = ((sy)/(float)(gpatch->height))*hwrPatch->max_t; if (sy + h > gpatch->height) - v[2].t = v[3].t = hwrPatch->max_t - ((sy+h)/(float)(gpatch->height))*hwrPatch->max_t; + v[2].t = v[3].t = hwrPatch->max_t; else v[2].t = v[3].t = ((sy+h)/(float)(gpatch->height))*hwrPatch->max_t; From 12205314bcc8e973e22e1bbbfcccb8f34c304629 Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Sun, 21 Feb 2021 19:32:00 -0600 Subject: [PATCH 282/644] Check against null tmpusher source before attempting to push a thing. --- src/p_spec.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/p_spec.c b/src/p_spec.c index 226e58d15..9886495db 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -8458,6 +8458,9 @@ static inline boolean PIT_PushThing(mobj_t *thing) if (thing->player && thing->player->powers[pw_carry] == CR_ROPEHANG) return false; + if (!tmpusher->source) + return false; + // Allow this to affect pushable objects at some point? if (thing->player && (!(thing->flags & (MF_NOGRAVITY | MF_NOCLIP)) || thing->player->powers[pw_carry] == CR_NIGHTSMODE)) { From d305952119aff3f84eee15697c4e2af6b32a1140 Mon Sep 17 00:00:00 2001 From: sphere Date: Wed, 24 Feb 2021 10:30:48 +0100 Subject: [PATCH 283/644] Update ZB config: at this rate, ZB will update before this gets merged. --- extras/conf/SRB2-22.cfg | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg index b7ba56ba7..246ef9b64 100644 --- a/extras/conf/SRB2-22.cfg +++ b/extras/conf/SRB2-22.cfg @@ -3088,8 +3088,7 @@ linedeftypes title = "Copy Frontside Floor Slope to Backside"; prefix = "(730)"; slope = "copy"; - slopeargs = 1; - //copyslopeargs = 1; uncomment when ZB updates + copyslopeargs = 1; } 731 @@ -3097,8 +3096,7 @@ linedeftypes title = "Copy Frontside Ceiling Slope to Backside"; prefix = "(731)"; slope = "copy"; - slopeargs = 2; - //copyslopeargs = 4; uncomment when ZB updates + copyslopeargs = 4; } 732 @@ -3106,8 +3104,7 @@ linedeftypes title = "Copy Frontside Floor and Ceiling Slope to Backside"; prefix = "(732)"; slope = "copy"; - slopeargs = 3; - //copyslopeargs = 5; uncomment when ZB updates + copyslopeargs = 5; } 733 @@ -3115,8 +3112,7 @@ linedeftypes title = "Copy Backside Floor Slope to Frontside"; prefix = "(730)"; slope = "copy"; - slopeargs = 1; - //copyslopeargs = 2; uncomment when ZB updates + copyslopeargs = 2; } 734 @@ -3124,8 +3120,7 @@ linedeftypes title = "Copy Backside Ceiling Slope to Frontside"; prefix = "(731)"; slope = "copy"; - slopeargs = 2; - //copyslopeargs = 8; uncomment when ZB updates + copyslopeargs = 8; } 735 @@ -3133,8 +3128,7 @@ linedeftypes title = "Copy Backside Floor and Ceiling Slope to Frontside"; prefix = "(732)"; slope = "copy"; - slopeargs = 3; - //copyslopeargs = 10; uncomment when ZB updates + copyslopeargs = 10; } 799 From 75d0e702369e80cc93191782bc8dfd4de45fde88 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Thu, 25 Feb 2021 23:41:43 +0100 Subject: [PATCH 284/644] Fix sector tags being signed in Lua --- src/lua_maplib.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 6a9091cc9..9598f7708 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -583,7 +583,18 @@ static int sector_get(lua_State *L) lua_pushinteger(L, sector->special); return 1; case sector_tag: - lua_pushinteger(L, Tag_FGet(§or->tags)); + // HELLO + // THIS IS LJ SONIC + // HOW IS YOUR DAY? + // BY THE WAY WHEN 2.3 OR 3.0 OR 4.0 OR SRB3 OR SRB4 OR WHATEVER IS OUT + // YOU SHOULD REMEMBER TO CHANGE THIS SO IT ALWAYS RETURNS A UNSIGNED VALUE + // HAVE A NICE DAY + // + // + // + // + // you are ugly + lua_pushinteger(L, (UINT16)Tag_FGet(§or->tags)); return 1; case sector_taglist: LUA_PushUserdata(L, §or->tags, META_SECTORTAGLIST); @@ -828,6 +839,17 @@ static int line_get(lua_State *L) lua_pushinteger(L, line->special); return 1; case line_tag: + // HELLO + // THIS IS LJ SONIC + // HOW IS YOUR DAY? + // BY THE WAY WHEN 2.3 OR 3.0 OR 4.0 OR SRB3 OR SRB4 OR WHATEVER IS OUT + // YOU SHOULD REMEMBER TO CHANGE THIS SO IT ALWAYS RETURNS A UNSIGNED VALUE + // HAVE A NICE DAY + // + // + // + // + // you are ugly lua_pushinteger(L, Tag_FGet(&line->tags)); return 1; case line_taglist: From 5b1dc6ba338ac1f1401d38ce1d82aeb082ad3dff Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Wed, 24 Feb 2021 23:45:39 -0300 Subject: [PATCH 285/644] [Meta] Change branding --- src/d_netcmd.c | 4 ++-- src/m_misc.c | 6 +++--- src/sdl/i_system.c | 8 ++++---- src/sdl/i_video.c | 2 +- src/win32/Makefile.cfg | 2 +- src/win32/Srb2win.rc | 6 +++--- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 4208e4c4f..8d42ca4c2 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -3477,9 +3477,9 @@ static void Command_ListWADS_f(void) static void Command_Version_f(void) { #ifdef DEVELOP - CONS_Printf("Sonic Robo Blast 2 %s-%s (%s %s) ", compbranch, comprevision, compdate, comptime); + CONS_Printf("Kitchen Sink Faucet %s-%s (%s %s) ", compbranch, comprevision, compdate, comptime); #else - CONS_Printf("Sonic Robo Blast 2 %s (%s %s %s %s) ", VERSIONSTRING, compdate, comptime, comprevision, compbranch); + CONS_Printf("Kitchen Sink Faucet %s (%s %s %s %s) ", VERSIONSTRING, compdate, comptime, comprevision, compbranch); #endif // Base library diff --git a/src/m_misc.c b/src/m_misc.c index 42890cb08..376e7512f 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -783,10 +783,10 @@ static void M_PNGText(png_structp png_ptr, png_infop png_info_ptr, PNG_CONST png char keytxt[SRB2PNGTXT][12] = { "Title", "Description", "Playername", "Mapnum", "Mapname", "Location", "Interface", "Render Mode", "Revision", "Build Date", "Build Time"}; - char titletxt[] = "Sonic Robo Blast 2 " VERSIONSTRING; + char titletxt[] = "Kitchen Sink Faucet " VERSIONSTRING; png_charp playertxt = cv_playername.zstring; - char desctxt[] = "SRB2 Screenshot"; - char Movietxt[] = "SRB2 Movie"; + char desctxt[] = "Kitchen Sink Faucet Screenshot"; + char Movietxt[] = "Kitchen Sink Faucet Movie"; size_t i; char interfacetxt[] = #ifdef HAVE_SDL diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 10c0747bf..1c47b89c9 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -629,7 +629,7 @@ static void I_StartupConsole(void) if (gotConsole) { - SetConsoleTitleA("SRB2 Console"); + SetConsoleTitleA("Kitchen Sink Faucet Console"); consolevent = SDL_TRUE; } @@ -1622,7 +1622,7 @@ void I_UpdateMumble(const mobj_t *mobj, const listener_t listener) return; if(mumble->uiVersion != 2) { - wcsncpy(mumble->name, L"SRB2 "VERSIONSTRINGW, 256); + wcsncpy(mumble->name, L"Kitchen Sink Faucet "VERSIONSTRINGW, 256); wcsncpy(mumble->description, L"Sonic Robo Blast 2 with integrated Mumble Link support.", 2048); mumble->uiVersion = 2; } @@ -2400,7 +2400,7 @@ void I_Error(const char *error, ...) // which should fail gracefully if it can't put a message box up // on the target system SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, - "SRB2 "VERSIONSTRING" Recursive Error", + "Kitchen Sink Faucet Recursive Error", buffer, NULL); W_Shutdown(); @@ -2444,7 +2444,7 @@ void I_Error(const char *error, ...) // which should fail gracefully if it can't put a message box up // on the target system SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, - "SRB2 "VERSIONSTRING" Error", + "Kitchen Sink Faucet Error", buffer, NULL); // Note that SDL_ShowSimpleMessageBox does *not* require SDL to be // initialized at the time, so calling it after SDL_Quit() is diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index c8f67da77..032521c0a 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1631,7 +1631,7 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen) #endif // Create a window - window = SDL_CreateWindow("SRB2 "VERSIONSTRING, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, + window = SDL_CreateWindow("Kitchen Sink Faucet "VERSIONSTRING, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, realwidth, realheight, flags); diff --git a/src/win32/Makefile.cfg b/src/win32/Makefile.cfg index 702ae3765..0365f617d 100644 --- a/src/win32/Makefile.cfg +++ b/src/win32/Makefile.cfg @@ -68,7 +68,7 @@ endif endif # name of the exefile - EXENAME?=srb2win.exe + EXENAME?=kitchensinkfaucet.exe ifdef SDL i_system_o+=$(OBJDIR)/SRB2.res diff --git a/src/win32/Srb2win.rc b/src/win32/Srb2win.rc index 5ba366bda..98927e2a6 100644 --- a/src/win32/Srb2win.rc +++ b/src/win32/Srb2win.rc @@ -84,14 +84,14 @@ BEGIN BEGIN VALUE "Comments", "Visit our web site at www.srb2.org for news and updates!\0" VALUE "CompanyName", "Sonic Team Junior\0" - VALUE "FileDescription", "Sonic Robo Blast 2\0" + VALUE "FileDescription", "Kitchen Sink Faucet\0" VALUE "FileVersion", VERSIONSTRING_RC VALUE "InternalName", "srb2\0" VALUE "LegalCopyright", "Copyright 1998-2020 by Sonic Team Junior\0" VALUE "LegalTrademarks", "Sonic the Hedgehog and related characters are trademarks of Sega.\0" - VALUE "OriginalFilename", "srb2win.exe\0" + VALUE "OriginalFilename", "kitchensinkfaucet.exe\0" VALUE "PrivateBuild", "\0" - VALUE "ProductName", "Sonic Robo Blast 2\0" + VALUE "ProductName", "Kitchen Sink Faucet\0" VALUE "ProductVersion", VERSIONSTRING_RC VALUE "SpecialBuild", "\0" END From 70ebca2bf602dd69beb1a4c00a9aafe96b8722e0 Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Thu, 25 Feb 2021 00:25:09 -0300 Subject: [PATCH 286/644] Update README --- README.md | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 8a5ca1a1f..98cff8fec 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,7 @@ -# Sonic Robo Blast 2 +# Kitchen Sink Faucet SRB2 -[![Build status](https://ci.appveyor.com/api/projects/status/399d4hcw9yy7hg2y?svg=true)](https://ci.appveyor.com/project/STJr/srb2) -[![Build status](https://travis-ci.org/STJr/SRB2.svg?branch=master)](https://travis-ci.org/STJr/SRB2) -[![CircleCI](https://circleci.com/gh/STJr/SRB2/tree/master.svg?style=svg)](https://circleci.com/gh/STJr/SRB2/tree/master) - -[Sonic Robo Blast 2](https://srb2.org/) is a 3D Sonic the Hedgehog fangame based on a modified version of [Doom Legacy](http://doomlegacy.sourceforge.net/). +[![Build status](https://ci.appveyor.com/api/projects/status/gv49pw5mra2sad1j?svg=true)](https://ci.appveyor.com/project/jimita/kitchensinkfaucetsrb2) +[![CircleCI](https://circleci.com/gh/Jimita/KitchenSinkFaucetSRB2/tree/master.svg?style=svg)](https://app.circleci.com/pipelines/github/Jimita/KitchenSinkFaucetSRB2) ## Dependencies - NASM (x86 builds only) From 2ca8efd7eea4b3d531ac5fca4ef09a5da9f2efd1 Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Thu, 25 Feb 2021 20:17:27 -0300 Subject: [PATCH 287/644] Revert accidental push --- README.md | 9 ++++++--- src/d_netcmd.c | 4 ++-- src/m_misc.c | 6 +++--- src/sdl/i_system.c | 8 ++++---- src/sdl/i_video.c | 2 +- src/win32/Makefile.cfg | 2 +- src/win32/Srb2win.rc | 6 +++--- 7 files changed, 20 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 98cff8fec..8a5ca1a1f 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,10 @@ -# Kitchen Sink Faucet SRB2 +# Sonic Robo Blast 2 -[![Build status](https://ci.appveyor.com/api/projects/status/gv49pw5mra2sad1j?svg=true)](https://ci.appveyor.com/project/jimita/kitchensinkfaucetsrb2) -[![CircleCI](https://circleci.com/gh/Jimita/KitchenSinkFaucetSRB2/tree/master.svg?style=svg)](https://app.circleci.com/pipelines/github/Jimita/KitchenSinkFaucetSRB2) +[![Build status](https://ci.appveyor.com/api/projects/status/399d4hcw9yy7hg2y?svg=true)](https://ci.appveyor.com/project/STJr/srb2) +[![Build status](https://travis-ci.org/STJr/SRB2.svg?branch=master)](https://travis-ci.org/STJr/SRB2) +[![CircleCI](https://circleci.com/gh/STJr/SRB2/tree/master.svg?style=svg)](https://circleci.com/gh/STJr/SRB2/tree/master) + +[Sonic Robo Blast 2](https://srb2.org/) is a 3D Sonic the Hedgehog fangame based on a modified version of [Doom Legacy](http://doomlegacy.sourceforge.net/). ## Dependencies - NASM (x86 builds only) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 8d42ca4c2..4208e4c4f 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -3477,9 +3477,9 @@ static void Command_ListWADS_f(void) static void Command_Version_f(void) { #ifdef DEVELOP - CONS_Printf("Kitchen Sink Faucet %s-%s (%s %s) ", compbranch, comprevision, compdate, comptime); + CONS_Printf("Sonic Robo Blast 2 %s-%s (%s %s) ", compbranch, comprevision, compdate, comptime); #else - CONS_Printf("Kitchen Sink Faucet %s (%s %s %s %s) ", VERSIONSTRING, compdate, comptime, comprevision, compbranch); + CONS_Printf("Sonic Robo Blast 2 %s (%s %s %s %s) ", VERSIONSTRING, compdate, comptime, comprevision, compbranch); #endif // Base library diff --git a/src/m_misc.c b/src/m_misc.c index 376e7512f..42890cb08 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -783,10 +783,10 @@ static void M_PNGText(png_structp png_ptr, png_infop png_info_ptr, PNG_CONST png char keytxt[SRB2PNGTXT][12] = { "Title", "Description", "Playername", "Mapnum", "Mapname", "Location", "Interface", "Render Mode", "Revision", "Build Date", "Build Time"}; - char titletxt[] = "Kitchen Sink Faucet " VERSIONSTRING; + char titletxt[] = "Sonic Robo Blast 2 " VERSIONSTRING; png_charp playertxt = cv_playername.zstring; - char desctxt[] = "Kitchen Sink Faucet Screenshot"; - char Movietxt[] = "Kitchen Sink Faucet Movie"; + char desctxt[] = "SRB2 Screenshot"; + char Movietxt[] = "SRB2 Movie"; size_t i; char interfacetxt[] = #ifdef HAVE_SDL diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 1c47b89c9..10c0747bf 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -629,7 +629,7 @@ static void I_StartupConsole(void) if (gotConsole) { - SetConsoleTitleA("Kitchen Sink Faucet Console"); + SetConsoleTitleA("SRB2 Console"); consolevent = SDL_TRUE; } @@ -1622,7 +1622,7 @@ void I_UpdateMumble(const mobj_t *mobj, const listener_t listener) return; if(mumble->uiVersion != 2) { - wcsncpy(mumble->name, L"Kitchen Sink Faucet "VERSIONSTRINGW, 256); + wcsncpy(mumble->name, L"SRB2 "VERSIONSTRINGW, 256); wcsncpy(mumble->description, L"Sonic Robo Blast 2 with integrated Mumble Link support.", 2048); mumble->uiVersion = 2; } @@ -2400,7 +2400,7 @@ void I_Error(const char *error, ...) // which should fail gracefully if it can't put a message box up // on the target system SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, - "Kitchen Sink Faucet Recursive Error", + "SRB2 "VERSIONSTRING" Recursive Error", buffer, NULL); W_Shutdown(); @@ -2444,7 +2444,7 @@ void I_Error(const char *error, ...) // which should fail gracefully if it can't put a message box up // on the target system SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, - "Kitchen Sink Faucet Error", + "SRB2 "VERSIONSTRING" Error", buffer, NULL); // Note that SDL_ShowSimpleMessageBox does *not* require SDL to be // initialized at the time, so calling it after SDL_Quit() is diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 032521c0a..c8f67da77 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1631,7 +1631,7 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen) #endif // Create a window - window = SDL_CreateWindow("Kitchen Sink Faucet "VERSIONSTRING, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, + window = SDL_CreateWindow("SRB2 "VERSIONSTRING, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, realwidth, realheight, flags); diff --git a/src/win32/Makefile.cfg b/src/win32/Makefile.cfg index 0365f617d..702ae3765 100644 --- a/src/win32/Makefile.cfg +++ b/src/win32/Makefile.cfg @@ -68,7 +68,7 @@ endif endif # name of the exefile - EXENAME?=kitchensinkfaucet.exe + EXENAME?=srb2win.exe ifdef SDL i_system_o+=$(OBJDIR)/SRB2.res diff --git a/src/win32/Srb2win.rc b/src/win32/Srb2win.rc index 98927e2a6..5ba366bda 100644 --- a/src/win32/Srb2win.rc +++ b/src/win32/Srb2win.rc @@ -84,14 +84,14 @@ BEGIN BEGIN VALUE "Comments", "Visit our web site at www.srb2.org for news and updates!\0" VALUE "CompanyName", "Sonic Team Junior\0" - VALUE "FileDescription", "Kitchen Sink Faucet\0" + VALUE "FileDescription", "Sonic Robo Blast 2\0" VALUE "FileVersion", VERSIONSTRING_RC VALUE "InternalName", "srb2\0" VALUE "LegalCopyright", "Copyright 1998-2020 by Sonic Team Junior\0" VALUE "LegalTrademarks", "Sonic the Hedgehog and related characters are trademarks of Sega.\0" - VALUE "OriginalFilename", "kitchensinkfaucet.exe\0" + VALUE "OriginalFilename", "srb2win.exe\0" VALUE "PrivateBuild", "\0" - VALUE "ProductName", "Kitchen Sink Faucet\0" + VALUE "ProductName", "Sonic Robo Blast 2\0" VALUE "ProductVersion", VERSIONSTRING_RC VALUE "SpecialBuild", "\0" END From 8bcc71c6295cd65d3fbb72d9706ef072ff21d4ce Mon Sep 17 00:00:00 2001 From: Riku Salminen <38985578+Riku-S@users.noreply.github.com> Date: Fri, 26 Feb 2021 15:43:53 +0200 Subject: [PATCH 288/644] Disable pausing during score screens in marathon mode --- src/d_netcmd.c | 2 +- src/p_user.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 0acbec928..09f9d4651 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -2130,7 +2130,7 @@ static void Command_Pause(void) if (cv_pause.value || server || (IsPlayerAdmin(consoleplayer))) { - if (modeattacking || !(gamestate == GS_LEVEL || gamestate == GS_INTERMISSION)) + if (modeattacking || !(gamestate == GS_LEVEL || gamestate == GS_INTERMISSION) || (marathonmode && gamestate == GS_INTERMISSION)) { CONS_Printf(M_GetText("You can't pause here.\n")); return; diff --git a/src/p_user.c b/src/p_user.c index a9e1fe9a2..d7ce33177 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -190,7 +190,7 @@ fixed_t P_ReturnThrustY(mobj_t *mo, angle_t angle, fixed_t move) boolean P_AutoPause(void) { // Don't pause even on menu-up or focus-lost in netgames or record attack - if (netgame || modeattacking || gamestate == GS_TITLESCREEN) + if (netgame || modeattacking || gamestate == GS_TITLESCREEN || (marathonmode && gamestate == GS_INTERMISSION)) return false; return (menuactive || ( window_notinfocus && cv_pauseifunfocused.value )); From 77feee73c36085180db713871098f1917fdf1f3d Mon Sep 17 00:00:00 2001 From: Lachlan Wright Date: Sat, 27 Feb 2021 03:38:13 +0000 Subject: [PATCH 289/644] Revert "Merge branch 'player-speed' into 'next'" This reverts merge request !1309 --- src/p_enemy.c | 2 +- src/p_user.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 3e7f52a3f..12bba0b4d 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -1834,7 +1834,7 @@ void A_SnailerThink(mobj_t *actor) fixed_t dist; fixed_t dx, dy; - dist = R_PointToDist2(0, 0, actor->x - actor->target->x, actor->y - actor->target->y); + dist = P_AproxDistance(actor->x - actor->target->x, actor->y - actor->target->y); if (an > ANGLE_45 && an <= ANGLE_90) // fire at 45 degrees to the left { diff --git a/src/p_user.c b/src/p_user.c index a9e1fe9a2..b3b337572 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -5924,7 +5924,7 @@ static void P_3dMovement(player_t *player) player->rmomy = player->mo->momy - player->cmomy; // Calculates player's speed based on distance-of-a-line formula - player->speed = R_PointToDist2(0, 0, player->rmomx, player->rmomy); + player->speed = P_AproxDistance(player->rmomx, player->rmomy); // Monster Iestyn - 04-11-13 // Quadrants are stupid, excessive and broken, let's do this a much simpler way! From a1e0aa18120ad75d25b5aad4373c24e47f9dbb47 Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Sat, 27 Feb 2021 12:04:48 -0300 Subject: [PATCH 290/644] Fix "implicit declaration of function 'DEH_TableCheck'" warning --- src/d_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_main.c b/src/d_main.c index 409a66bec..23a2c0133 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -61,7 +61,7 @@ #include "p_local.h" // chasecam #include "mserv.h" // ms_RoomId #include "m_misc.h" // screenshot functionality -#include "dehacked.h" // Dehacked list test +#include "deh_tables.h" // Dehacked list test #include "m_cond.h" // condition initialization #include "fastcmp.h" #include "keys.h" From 4016a2e0622826f35948da1d357be83946450fcc Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Thu, 3 Dec 2020 17:29:39 -0600 Subject: [PATCH 291/644] Crash backtrace logging for NEWSIGNALHANDLER. --- src/doomdef.h | 1 + src/sdl/i_main.c | 4 ++ src/sdl/i_system.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 103 insertions(+) diff --git a/src/doomdef.h b/src/doomdef.h index 52abc9597..e1cda6f42 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -118,6 +118,7 @@ #ifdef LOGMESSAGES extern FILE *logstream; +extern FILE *crashstream; extern char logfilename[1024]; #endif diff --git a/src/sdl/i_main.c b/src/sdl/i_main.c index 1dee379c0..03783d1ef 100644 --- a/src/sdl/i_main.c +++ b/src/sdl/i_main.c @@ -52,6 +52,7 @@ extern int SDL_main(int argc, char *argv[]); #ifdef LOGMESSAGES FILE *logstream = NULL; +FILE *crashstream = NULL; char logfilename[1024]; #endif @@ -249,6 +250,9 @@ int main(int argc, char **argv) // startup SRB2 CONS_Printf("Setting up SRB2...\n"); D_SRB2Main(); + + crashstream = fopen(va("%s" PATHSEP "%s", srb2home, "crash-log.txt"), "at"); + #ifdef LOGMESSAGES if (!M_CheckParm("-nolog")) CONS_Printf("Logfile: %s\n", logfilename); diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index d2c819c37..528d495c7 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -137,6 +137,11 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); #include #endif +#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) +#include +#include +#endif + // Locations for searching the srb2.pk3 #if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) #define DEFAULTWADLOCATION1 "/usr/local/share/games/SRB2" @@ -238,6 +243,75 @@ SDL_bool framebuffer = SDL_FALSE; UINT8 keyboard_started = false; +#define STDERR_WRITE(string) if (fd != -1) I_OutputMsg("%s", string) +#define CRASHLOG_WRITE(string) if (fd != -1) write(fd, string, strlen(string)) +#define CRASHLOG_STDERR_WRITE(string) \ + if (fd != -1)\ + write(fd, string, strlen(string));\ + I_OutputMsg("%s", string) + +static void write_backtrace(INT32 signal) +{ +#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) + int fd = -1; + size_t size; + time_t rawtime; + struct tm * timeinfo; + + enum { MAX_SIZE = 1024 }; + void *array[MAX_SIZE]; + + const char *error = "An error occurred within SRB2! Send this stack trace to someone who can help!\n"; + const char *error2 = "(Or find crash-log.txt in your SRB2 directory.)\n"; // Shown only to stderr. + + if (!crashstream) + crashstream = fopen(va("%s" PATHSEP "%s", srb2home, "crash-log.txt"), "at"); + + if (!crashstream) + I_OutputMsg("\nWARNING: Couldn't open crash log for writing! Make sure your permissions are correct. Please save the below report!\n"); + else + { + fd = fileno(crashstream); + + if (fd == -1) + fd = open(va("%s" PATHSEP "%s", srb2home, "crash-log.txt"), O_CREAT|O_APPEND); + } + + time(&rawtime); + timeinfo = localtime(&rawtime); + + CRASHLOG_WRITE("------------------------\n"); // Nice looking seperator + + CRASHLOG_STDERR_WRITE("\n"); // Newline to look nice for both outputs. + CRASHLOG_STDERR_WRITE(error); // "Oops, SRB2 crashed" message + STDERR_WRITE(error2); // Tell the user where the crash log is. + + // Tell the log when we crashed. + CRASHLOG_WRITE("Time of crash: "); + CRASHLOG_WRITE(asctime(timeinfo)); + + // Give the crash log the cause and a nice 'Backtrace:' thing + // The signal is given to the user when the parent process sees we crashed. + CRASHLOG_WRITE("Cause: "); + CRASHLOG_WRITE(strsignal(signal)); + CRASHLOG_WRITE("\n"); // Newline for the signal name + + CRASHLOG_STDERR_WRITE("\nBacktrace:\n"); + + // Flood the output and log with the backtrace + size = backtrace(array, MAX_SIZE); + backtrace_symbols_fd(array, size, fd); + backtrace_symbols_fd(array, size, STDERR_FILENO); + + CRASHLOG_WRITE("\n"); // Write another newline to the log so it looks nice :) + + close(fd); +#endif +} +#undef STDERR_WRITE +#undef CRASHLOG_WRITE +#undef CRASHLOG_STDERR_WRITE + static void I_ReportSignal(int num, int coredumped) { //static char msg[] = "oh no! back to reality!\r\n"; @@ -298,6 +372,9 @@ FUNCNORETURN static ATTRNORETURN void signal_handler(INT32 num) D_QuitNetGame(); // Fix server freezes CL_AbortDownloadResume(); I_ReportSignal(num, 0); + + write_backtrace(num); + I_ShutdownSystem(); signal(num, SIG_DFL); //default signal action raise(num); @@ -687,6 +764,26 @@ static void I_RegisterSignals (void) #endif } +#ifdef NEWSIGNALHANDLER +static void signal_handler_child(INT32 num) +{ + write_backtrace(num); + + signal(num, SIG_DFL); //default signal action + raise(num); +} + +static void I_RegisterChildSignals(void) +{ + // If these defines don't exist, + // then compilation would have failed above us... + signal(SIGILL , signal_handler_child); + signal(SIGSEGV , signal_handler_child); + signal(SIGABRT , signal_handler_child); + signal(SIGFPE , signal_handler_child); +} +#endif + // //I_OutputMsg // @@ -2123,6 +2220,7 @@ static void I_Fork(void) newsignalhandler_Warn("fork()"); break; case 0: + I_RegisterChildSignals(); break; default: if (logstream) From 5108f1f57b805f7517e703f8c4b973d8489c3aa7 Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Thu, 3 Dec 2020 17:08:40 -0600 Subject: [PATCH 292/644] Use file descriptors and ditch file streams, for now. --- src/doomdef.h | 1 - src/sdl/i_main.c | 4 ---- src/sdl/i_system.c | 12 ++---------- 3 files changed, 2 insertions(+), 15 deletions(-) diff --git a/src/doomdef.h b/src/doomdef.h index e1cda6f42..52abc9597 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -118,7 +118,6 @@ #ifdef LOGMESSAGES extern FILE *logstream; -extern FILE *crashstream; extern char logfilename[1024]; #endif diff --git a/src/sdl/i_main.c b/src/sdl/i_main.c index 03783d1ef..1dee379c0 100644 --- a/src/sdl/i_main.c +++ b/src/sdl/i_main.c @@ -52,7 +52,6 @@ extern int SDL_main(int argc, char *argv[]); #ifdef LOGMESSAGES FILE *logstream = NULL; -FILE *crashstream = NULL; char logfilename[1024]; #endif @@ -250,9 +249,6 @@ int main(int argc, char **argv) // startup SRB2 CONS_Printf("Setting up SRB2...\n"); D_SRB2Main(); - - crashstream = fopen(va("%s" PATHSEP "%s", srb2home, "crash-log.txt"), "at"); - #ifdef LOGMESSAGES if (!M_CheckParm("-nolog")) CONS_Printf("Logfile: %s\n", logfilename); diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 528d495c7..7c870c0c7 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -264,18 +264,10 @@ static void write_backtrace(INT32 signal) const char *error = "An error occurred within SRB2! Send this stack trace to someone who can help!\n"; const char *error2 = "(Or find crash-log.txt in your SRB2 directory.)\n"; // Shown only to stderr. - if (!crashstream) - crashstream = fopen(va("%s" PATHSEP "%s", srb2home, "crash-log.txt"), "at"); + fd = open(va("%s" PATHSEP "%s", srb2home, "crash-log.txt"), O_CREAT|O_APPEND|O_RDWR, S_IRUSR|S_IWUSR); - if (!crashstream) + if (fd == -1) I_OutputMsg("\nWARNING: Couldn't open crash log for writing! Make sure your permissions are correct. Please save the below report!\n"); - else - { - fd = fileno(crashstream); - - if (fd == -1) - fd = open(va("%s" PATHSEP "%s", srb2home, "crash-log.txt"), O_CREAT|O_APPEND); - } time(&rawtime); timeinfo = localtime(&rawtime); From bdb28a06f4ace02a71375a462696329786dee7e9 Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Thu, 3 Dec 2020 18:23:33 -0600 Subject: [PATCH 293/644] Print the backtrace before showing the signal handler popup. --- src/sdl/i_system.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 7c870c0c7..1d1fc2af2 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -363,10 +363,8 @@ FUNCNORETURN static ATTRNORETURN void signal_handler(INT32 num) { D_QuitNetGame(); // Fix server freezes CL_AbortDownloadResume(); - I_ReportSignal(num, 0); - write_backtrace(num); - + I_ReportSignal(num, 0); I_ShutdownSystem(); signal(num, SIG_DFL); //default signal action raise(num); From a0396d5e437929e525805414cc83d207d7db1331 Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Fri, 4 Dec 2020 12:08:50 -0600 Subject: [PATCH 294/644] Make it more async-signal-safe --- src/sdl/i_system.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 1d1fc2af2..e8c5d59fb 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -256,10 +256,11 @@ static void write_backtrace(INT32 signal) int fd = -1; size_t size; time_t rawtime; - struct tm * timeinfo; + struct tm timeinfo; - enum { MAX_SIZE = 1024 }; - void *array[MAX_SIZE]; + enum { BT_SIZE = 1024, STR_SIZE = 32 }; + void *array[BT_SIZE]; + char timestr[STR_SIZE]; const char *error = "An error occurred within SRB2! Send this stack trace to someone who can help!\n"; const char *error2 = "(Or find crash-log.txt in your SRB2 directory.)\n"; // Shown only to stderr. @@ -269,8 +270,10 @@ static void write_backtrace(INT32 signal) if (fd == -1) I_OutputMsg("\nWARNING: Couldn't open crash log for writing! Make sure your permissions are correct. Please save the below report!\n"); + // Get the current time as a string. time(&rawtime); - timeinfo = localtime(&rawtime); + localtime_r(&rawtime, &timeinfo); + strftime(timestr, STR_SIZE, "%a, %d %b %Y %T %z", &timeinfo); CRASHLOG_WRITE("------------------------\n"); // Nice looking seperator @@ -280,7 +283,8 @@ static void write_backtrace(INT32 signal) // Tell the log when we crashed. CRASHLOG_WRITE("Time of crash: "); - CRASHLOG_WRITE(asctime(timeinfo)); + CRASHLOG_WRITE(timestr); + CRASHLOG_WRITE("\n"); // Give the crash log the cause and a nice 'Backtrace:' thing // The signal is given to the user when the parent process sees we crashed. @@ -290,8 +294,8 @@ static void write_backtrace(INT32 signal) CRASHLOG_STDERR_WRITE("\nBacktrace:\n"); - // Flood the output and log with the backtrace - size = backtrace(array, MAX_SIZE); + // Flood the output and log with the backtrace + size = backtrace(array, BT_SIZE); backtrace_symbols_fd(array, size, fd); backtrace_symbols_fd(array, size, STDERR_FILENO); From 07ffe2599cc25d5fb46f55f9f78f4e6b0dece019 Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Sun, 28 Feb 2021 16:23:40 -0300 Subject: [PATCH 295/644] Fix thing scale mismatch in R_DrawVisSprite --- src/r_things.c | 4 +++- src/r_things.h | 5 ++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 30bf15f85..92340cab3 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -796,7 +796,7 @@ static void R_DrawVisSprite(vissprite_t *vis) INT32 pwidth; fixed_t frac; patch_t *patch = vis->patch; - fixed_t this_scale = vis->mobj->scale; + fixed_t this_scale = vis->thingscale; INT32 x1, x2; INT64 overflow_test; @@ -1332,6 +1332,7 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, shadow->xscale = FixedMul(xscale, shadowxscale); //SoM: 4/17/2000 shadow->scale = FixedMul(yscale, shadowyscale); + shadow->thingscale = thing->scale; shadow->sector = vis->sector; shadow->szt = (INT16)((centeryfrac - FixedMul(shadow->gzt - viewz, yscale))>>FRACBITS); shadow->sz = (INT16)((centeryfrac - FixedMul(shadow->gz - viewz, yscale))>>FRACBITS); @@ -1975,6 +1976,7 @@ static void R_ProjectSprite(mobj_t *thing) vis->xscale = FixedMul(spritexscale, xscale); //SoM: 4/17/2000 vis->scale = FixedMul(spriteyscale, yscale); //<thingscale = oldthing->scale; vis->spritexscale = spritexscale; vis->spriteyscale = spriteyscale; diff --git a/src/r_things.h b/src/r_things.h index f960089a1..708b6c24c 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -155,7 +155,8 @@ typedef struct vissprite_s fixed_t pz, pzt; // physical bottom/top for sorting with 3D floors fixed_t startfrac; // horizontal position of x1 - fixed_t scale; + fixed_t xscale, scale; // projected horizontal and vertical scales + fixed_t thingscale; // the object's scale fixed_t sortscale; // sortscale only differs from scale for paper sprites, floor sprites, and MF2_LINKDRAW fixed_t sortsplat; // the sortscale from behind the floor sprite fixed_t scalestep; // only for paper sprites, 0 otherwise @@ -183,8 +184,6 @@ typedef struct vissprite_s extracolormap_t *extra_colormap; // global colormaps - fixed_t xscale; - // Precalculated top and bottom screen coords for the sprite. fixed_t thingheight; // The actual height of the thing (for 3D floors) sector_t *sector; // The sector containing the thing. From 401271feb7d44bc47b7a4b29aa4de31dbf34b989 Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Sun, 28 Feb 2021 17:05:25 -0300 Subject: [PATCH 296/644] Fix translation colormap cache rebuilding using the old translation enumerations This was causing a buffer underwrite too. Lovely. --- src/r_draw.c | 60 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 18 deletions(-) diff --git a/src/r_draw.c b/src/r_draw.c index d9ea942a2..96554fad3 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -134,9 +134,43 @@ UINT32 nflatxshift, nflatyshift, nflatshiftup, nflatmask; #define DEFAULT_STARTTRANSCOLOR 96 #define NUM_PALETTE_ENTRIES 256 -static UINT8** translationtablecache[MAXSKINS + 7] = {NULL}; +static UINT8 **translationtablecache[MAXSKINS + 7] = {NULL}; UINT8 skincolor_modified[MAXSKINCOLORS]; +static INT32 SkinToCacheIndex(INT32 skinnum) +{ + switch (skinnum) + { + case TC_DEFAULT: return DEFAULT_TT_CACHE_INDEX; + case TC_BOSS: return BOSS_TT_CACHE_INDEX; + case TC_METALSONIC: return METALSONIC_TT_CACHE_INDEX; + case TC_ALLWHITE: return ALLWHITE_TT_CACHE_INDEX; + case TC_RAINBOW: return RAINBOW_TT_CACHE_INDEX; + case TC_BLINK: return BLINK_TT_CACHE_INDEX; + case TC_DASHMODE: return DASHMODE_TT_CACHE_INDEX; + default: break; + } + + return skinnum; +} + +static INT32 CacheIndexToSkin(INT32 ttc) +{ + switch (ttc) + { + case DEFAULT_TT_CACHE_INDEX: return TC_DEFAULT; + case BOSS_TT_CACHE_INDEX: return TC_BOSS; + case METALSONIC_TT_CACHE_INDEX: return TC_METALSONIC; + case ALLWHITE_TT_CACHE_INDEX: return TC_ALLWHITE; + case RAINBOW_TT_CACHE_INDEX: return TC_RAINBOW; + case BLINK_TT_CACHE_INDEX: return TC_BLINK; + case DASHMODE_TT_CACHE_INDEX: return TC_DASHMODE; + default: break; + } + + return ttc; +} + CV_PossibleValue_t Color_cons_t[MAXSKINCOLORS+1]; #define TRANSTAB_AMTMUL10 (256.0f / 10.0f) @@ -308,7 +342,7 @@ static void R_RainbowColormap(UINT8 *dest_colormap, UINT16 skincolor) /** \brief Generates a translation colormap. \param dest_colormap colormap to populate - \param skinnum number of skin, TC_DEFAULT or TC_BOSS + \param skinnum skin number, or a translation mode \param color translation color \return void @@ -412,6 +446,9 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U if (color >= numskincolors) I_Error("Invalid skin color #%hu.", (UINT16)color); + if (skinnum < 0 && skinnum > TC_DEFAULT) + I_Error("Invalid non-translation skin number %d.", skinnum); + starttranscolor = (skinnum != TC_DEFAULT) ? skins[skinnum].starttranscolor : DEFAULT_STARTTRANSCOLOR; if (starttranscolor >= NUM_PALETTE_ENTRIES) @@ -448,25 +485,11 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U UINT8* R_GetTranslationColormap(INT32 skinnum, skincolornum_t color, UINT8 flags) { UINT8* ret; - INT32 skintableindex; + INT32 skintableindex = SkinToCacheIndex(skinnum); // Adjust if we want the default colormap INT32 i; - // Adjust if we want the default colormap - switch (skinnum) - { - case TC_DEFAULT: skintableindex = DEFAULT_TT_CACHE_INDEX; break; - case TC_BOSS: skintableindex = BOSS_TT_CACHE_INDEX; break; - case TC_METALSONIC: skintableindex = METALSONIC_TT_CACHE_INDEX; break; - case TC_ALLWHITE: skintableindex = ALLWHITE_TT_CACHE_INDEX; break; - case TC_RAINBOW: skintableindex = RAINBOW_TT_CACHE_INDEX; break; - case TC_BLINK: skintableindex = BLINK_TT_CACHE_INDEX; break; - case TC_DASHMODE: skintableindex = DASHMODE_TT_CACHE_INDEX; break; - default: skintableindex = skinnum; break; - } - if (flags & GTC_CACHE) { - // Allocate table for skin if necessary if (!translationtablecache[skintableindex]) translationtablecache[skintableindex] = Z_Calloc(MAXSKINCOLORS * sizeof(UINT8**), PU_STATIC, NULL); @@ -479,7 +502,8 @@ UINT8* R_GetTranslationColormap(INT32 skinnum, skincolornum_t color, UINT8 flags { for (i = 0; i < (INT32)(sizeof(translationtablecache) / sizeof(translationtablecache[0])); i++) if (translationtablecache[i] && translationtablecache[i][color]) - R_GenerateTranslationColormap(translationtablecache[i][color], i>=MAXSKINS ? MAXSKINS-i-1 : i, color); + R_GenerateTranslationColormap(translationtablecache[i][color], CacheIndexToSkin(i), color); + skincolor_modified[color] = false; } } From 94fe7a3d8c66d1417dfd0b07d8d5d59962fa8e3b Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Sun, 28 Feb 2021 17:47:12 -0300 Subject: [PATCH 297/644] Change I_Error message --- src/r_draw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_draw.c b/src/r_draw.c index 96554fad3..c3d4efae3 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -447,7 +447,7 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U I_Error("Invalid skin color #%hu.", (UINT16)color); if (skinnum < 0 && skinnum > TC_DEFAULT) - I_Error("Invalid non-translation skin number %d.", skinnum); + I_Error("Invalid translation colormap index %d.", skinnum); starttranscolor = (skinnum != TC_DEFAULT) ? skins[skinnum].starttranscolor : DEFAULT_STARTTRANSCOLOR; From 6d539626c4f6cd2ba7434571daae3878788a50ac Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 28 Feb 2021 16:12:38 -0800 Subject: [PATCH 298/644] I forgot to add the dep directory --- dep/.gitignore | 2 ++ dep/FreeBSD/SDL/Debug/.gitignore | 2 ++ dep/FreeBSD/SDL/Release/.gitignore | 2 ++ dep/Linux/SDL/Debug/.gitignore | 2 ++ dep/Linux/SDL/Release/.gitignore | 2 ++ dep/Linux64/SDL/Debug/.gitignore | 2 ++ dep/Linux64/SDL/Release/.gitignore | 2 ++ dep/MasterClient/.gitignore | 2 ++ dep/MasterServer/.gitignore | 2 ++ dep/Mingw/Debug/.gitignore | 2 ++ dep/Mingw/Release/.gitignore | 2 ++ dep/Mingw/SDL/Debug/.gitignore | 2 ++ dep/Mingw/SDL/Release/.gitignore | 2 ++ dep/Mingw64/Debug/.gitignore | 2 ++ dep/Mingw64/Release/.gitignore | 2 ++ dep/Mingw64/SDL/Debug/.gitignore | 2 ++ dep/Mingw64/SDL/Release/.gitignore | 2 ++ dep/SDL/Release/.gitignore | 2 ++ dep/VC/.gitignore | 2 ++ dep/VC9/.gitignore | 2 ++ dep/cygwin/Debug/.gitignore | 2 ++ dep/cygwin/Release/.gitignore | 2 ++ dep/dummy/.gitignore | 2 ++ 23 files changed, 46 insertions(+) create mode 100644 dep/.gitignore create mode 100644 dep/FreeBSD/SDL/Debug/.gitignore create mode 100644 dep/FreeBSD/SDL/Release/.gitignore create mode 100644 dep/Linux/SDL/Debug/.gitignore create mode 100644 dep/Linux/SDL/Release/.gitignore create mode 100644 dep/Linux64/SDL/Debug/.gitignore create mode 100644 dep/Linux64/SDL/Release/.gitignore create mode 100644 dep/MasterClient/.gitignore create mode 100644 dep/MasterServer/.gitignore create mode 100644 dep/Mingw/Debug/.gitignore create mode 100644 dep/Mingw/Release/.gitignore create mode 100644 dep/Mingw/SDL/Debug/.gitignore create mode 100644 dep/Mingw/SDL/Release/.gitignore create mode 100644 dep/Mingw64/Debug/.gitignore create mode 100644 dep/Mingw64/Release/.gitignore create mode 100644 dep/Mingw64/SDL/Debug/.gitignore create mode 100644 dep/Mingw64/SDL/Release/.gitignore create mode 100644 dep/SDL/Release/.gitignore create mode 100644 dep/VC/.gitignore create mode 100644 dep/VC9/.gitignore create mode 100644 dep/cygwin/Debug/.gitignore create mode 100644 dep/cygwin/Release/.gitignore create mode 100644 dep/dummy/.gitignore diff --git a/dep/.gitignore b/dep/.gitignore new file mode 100644 index 000000000..fb941664f --- /dev/null +++ b/dep/.gitignore @@ -0,0 +1,2 @@ +#All folders +*.d diff --git a/dep/FreeBSD/SDL/Debug/.gitignore b/dep/FreeBSD/SDL/Debug/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/dep/FreeBSD/SDL/Debug/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/dep/FreeBSD/SDL/Release/.gitignore b/dep/FreeBSD/SDL/Release/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/dep/FreeBSD/SDL/Release/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/dep/Linux/SDL/Debug/.gitignore b/dep/Linux/SDL/Debug/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/dep/Linux/SDL/Debug/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/dep/Linux/SDL/Release/.gitignore b/dep/Linux/SDL/Release/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/dep/Linux/SDL/Release/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/dep/Linux64/SDL/Debug/.gitignore b/dep/Linux64/SDL/Debug/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/dep/Linux64/SDL/Debug/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/dep/Linux64/SDL/Release/.gitignore b/dep/Linux64/SDL/Release/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/dep/Linux64/SDL/Release/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/dep/MasterClient/.gitignore b/dep/MasterClient/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/dep/MasterClient/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/dep/MasterServer/.gitignore b/dep/MasterServer/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/dep/MasterServer/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/dep/Mingw/Debug/.gitignore b/dep/Mingw/Debug/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/dep/Mingw/Debug/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/dep/Mingw/Release/.gitignore b/dep/Mingw/Release/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/dep/Mingw/Release/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/dep/Mingw/SDL/Debug/.gitignore b/dep/Mingw/SDL/Debug/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/dep/Mingw/SDL/Debug/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/dep/Mingw/SDL/Release/.gitignore b/dep/Mingw/SDL/Release/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/dep/Mingw/SDL/Release/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/dep/Mingw64/Debug/.gitignore b/dep/Mingw64/Debug/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/dep/Mingw64/Debug/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/dep/Mingw64/Release/.gitignore b/dep/Mingw64/Release/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/dep/Mingw64/Release/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/dep/Mingw64/SDL/Debug/.gitignore b/dep/Mingw64/SDL/Debug/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/dep/Mingw64/SDL/Debug/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/dep/Mingw64/SDL/Release/.gitignore b/dep/Mingw64/SDL/Release/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/dep/Mingw64/SDL/Release/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/dep/SDL/Release/.gitignore b/dep/SDL/Release/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/dep/SDL/Release/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/dep/VC/.gitignore b/dep/VC/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/dep/VC/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/dep/VC9/.gitignore b/dep/VC9/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/dep/VC9/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/dep/cygwin/Debug/.gitignore b/dep/cygwin/Debug/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/dep/cygwin/Debug/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/dep/cygwin/Release/.gitignore b/dep/cygwin/Release/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/dep/cygwin/Release/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/dep/dummy/.gitignore b/dep/dummy/.gitignore new file mode 100644 index 000000000..42c6dc2c6 --- /dev/null +++ b/dep/dummy/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing From 5f4e21ed3a97063c917d7f9ff406548b7e873ddd Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 28 Feb 2021 17:02:08 -0800 Subject: [PATCH 299/644] Fix dependency file trying to be made for SRB2.res and not for interface/blua/hardware files --- src/Makefile | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/Makefile b/src/Makefile index 260175a69..471c55ed3 100644 --- a/src/Makefile +++ b/src/Makefile @@ -554,7 +554,7 @@ OBJS:=$(i_main_o) \ $(i_sound_o) \ $(OBJS) -DEPS:=$(patsubst $(OBJDIR)/%.o,$(DEPDIR)/%.d,$(OBJS)) +DEPS:=$(patsubst $(OBJDIR)/%.o,$(DEPDIR)/%.d,$(filter %.o,$(OBJS))) OBJS+=$(OBJDIR)/comptime.o ifndef SILENT @@ -688,14 +688,33 @@ $(call print,Checking dependency files...) endif endif -$(DEPDIR)/%.d: %.c +undefine deps_rule + # windows makes it too hard ! ifndef WINDOWSHELL ifdef echoName +define deps_rule = @printf "%-20.20s\r" $< + +endef endif endif + +define deps_rule += $(CC) $(CFLAGS) -M -MF $@ -MT $(OBJDIR)/$< $< +endef + +$(DEPDIR)/%.d: %.c + $(deps_rule) + +$(DEPDIR)/%.d: $(INTERFACE)/%.c + $(deps_rule) + +$(DEPDIR)/%.d: hardware/%.c + $(deps_rule) + +$(DEPDIR)/%.d: blua/%.c + $(deps_rule) ifdef VALGRIND $(OBJDIR)/z_zone.o: z_zone.c From f6cb1798ccfc161264c3039bd294c0e061f650a7 Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Tue, 2 Mar 2021 02:27:14 -0300 Subject: [PATCH 300/644] Fix a few renderflags oversights in OpenGL --- src/hardware/hw_main.c | 40 ++++++++++++++++++---------------------- src/hardware/hw_md2.c | 11 +++++------ 2 files changed, 23 insertions(+), 28 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index a7e37d231..c2d617eaf 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -3665,7 +3665,7 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale) static void HWR_RotateSpritePolyToAim(gl_vissprite_t *spr, FOutVector *wallVerts, const boolean precip) { if (cv_glspritebillboarding.value - && spr && spr->mobj && !(spr->mobj->frame & FF_PAPERSPRITE) + && spr && spr->mobj && !R_ThingIsPaperSprite(spr->mobj) && wallVerts) { float basey = FIXED_TO_FLOAT(spr->mobj->z); @@ -3707,7 +3707,6 @@ static void HWR_SplitSprite(gl_vissprite_t *spr) FBITFIELD blend = 0; FBITFIELD occlusion; boolean use_linkdraw_hack = false; - boolean splat = R_ThingIsFloorSprite(spr->mobj); UINT8 alpha; INT32 i; @@ -3766,22 +3765,19 @@ static void HWR_SplitSprite(gl_vissprite_t *spr) baseWallVerts[0].t = baseWallVerts[1].t = ((GLPatch_t *)gpatch->hardware)->max_t; } - if (!splat) - { - // if it has a dispoffset, push it a little towards the camera - if (spr->dispoffset) { - float co = -gl_viewcos*(0.05f*spr->dispoffset); - float si = -gl_viewsin*(0.05f*spr->dispoffset); - baseWallVerts[0].z = baseWallVerts[3].z = baseWallVerts[0].z+si; - baseWallVerts[1].z = baseWallVerts[2].z = baseWallVerts[1].z+si; - baseWallVerts[0].x = baseWallVerts[3].x = baseWallVerts[0].x+co; - baseWallVerts[1].x = baseWallVerts[2].x = baseWallVerts[1].x+co; - } - - // Let dispoffset work first since this adjust each vertex - HWR_RotateSpritePolyToAim(spr, baseWallVerts, false); + // if it has a dispoffset, push it a little towards the camera + if (spr->dispoffset) { + float co = -gl_viewcos*(0.05f*spr->dispoffset); + float si = -gl_viewsin*(0.05f*spr->dispoffset); + baseWallVerts[0].z = baseWallVerts[3].z = baseWallVerts[0].z+si; + baseWallVerts[1].z = baseWallVerts[2].z = baseWallVerts[1].z+si; + baseWallVerts[0].x = baseWallVerts[3].x = baseWallVerts[0].x+co; + baseWallVerts[1].x = baseWallVerts[2].x = baseWallVerts[1].x+co; } + // Let dispoffset work first since this adjust each vertex + HWR_RotateSpritePolyToAim(spr, baseWallVerts, false); + realtop = top = baseWallVerts[3].y; realbot = bot = baseWallVerts[0].y; ttop = baseWallVerts[3].t; @@ -3914,7 +3910,7 @@ static void HWR_SplitSprite(gl_vissprite_t *spr) // The x and y only need to be adjusted in the case that it's not a papersprite if (cv_glspritebillboarding.value - && spr->mobj && !(spr->mobj->frame & FF_PAPERSPRITE)) + && spr->mobj && !R_ThingIsPaperSprite(spr->mobj)) { // Get the x and z of the vertices so billboarding draws correctly realheight = realbot - realtop; @@ -3983,7 +3979,7 @@ static void HWR_SplitSprite(gl_vissprite_t *spr) static void HWR_DrawSprite(gl_vissprite_t *spr) { FOutVector wallVerts[4]; - patch_t *gpatch; // sprite patch converted to hardware + patch_t *gpatch; FSurfaceInfo Surf; const boolean splat = R_ThingIsFloorSprite(spr->mobj); @@ -4284,7 +4280,7 @@ static inline void HWR_DrawPrecipitationSprite(gl_vissprite_t *spr) { FBITFIELD blend = 0; FOutVector wallVerts[4]; - patch_t *gpatch; // sprite patch converted to hardware + patch_t *gpatch; FSurfaceInfo Surf; if (!spr->mobj) @@ -4337,7 +4333,7 @@ static inline void HWR_DrawPrecipitationSprite(gl_vissprite_t *spr) // Always use the light at the top instead of whatever I was doing before INT32 light = R_GetPlaneLight(sector, spr->mobj->z + spr->mobj->height, false); - if (!(spr->mobj->frame & FF_FULLBRIGHT)) + if (!R_ThingIsFullBright(spr->mobj)) lightlevel = *sector->lightlist[light].lightlevel > 255 ? 255 : *sector->lightlist[light].lightlevel; if (*sector->lightlist[light].extra_colormap) @@ -4345,7 +4341,7 @@ static inline void HWR_DrawPrecipitationSprite(gl_vissprite_t *spr) } else { - if (!(spr->mobj->frame & FF_FULLBRIGHT)) + if (!R_ThingIsFullBright(spr->mobj)) lightlevel = sector->lightlevel > 255 ? 255 : sector->lightlevel; if (sector->extra_colormap) @@ -4921,8 +4917,8 @@ static void HWR_ProjectSprite(mobj_t *thing) angle_t ang; INT32 heightsec, phs; - const boolean papersprite = R_ThingIsPaperSprite(thing); const boolean splat = R_ThingIsFloorSprite(thing); + const boolean papersprite = (R_ThingIsPaperSprite(thing) && !splat); angle_t mobjangle = (thing->player ? thing->player->drawangle : thing->angle); float z1, z2; diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 2e944d3e6..3ef746b9f 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1314,7 +1314,7 @@ boolean HWR_DrawModel(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)) + if (!R_ThingIsFullBright(spr->mobj)) lightlevel = *sector->lightlist[light].lightlevel > 255 ? 255 : *sector->lightlist[light].lightlevel; if (*sector->lightlist[light].extra_colormap) @@ -1322,7 +1322,7 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) } else { - if (!(spr->mobj->frame & FF_FULLBRIGHT)) + if (!R_ThingIsFullBright(spr->mobj)) lightlevel = sector->lightlevel > 255 ? 255 : sector->lightlevel; if (sector->extra_colormap) @@ -1340,10 +1340,9 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) GLPatch_t *hwrPatch = NULL, *hwrBlendPatch = NULL; INT32 durs = spr->mobj->state->tics; INT32 tics = spr->mobj->tics; - //mdlframe_t *next = NULL; - const boolean papersprite = (spr->mobj->frame & FF_PAPERSPRITE); - const UINT8 flip = (UINT8)(!(spr->mobj->eflags & MFE_VERTICALFLIP) != !(spr->mobj->frame & FF_VERTICALFLIP)); - const UINT8 hflip = (UINT8)(!(spr->mobj->mirrored) != !(spr->mobj->frame & FF_HORIZONTALFLIP)); + const boolean papersprite = (R_ThingIsPaperSprite(spr->mobj) && !R_ThingIsFloorSprite(spr->mobj)); + const UINT8 flip = (UINT8)(!(spr->mobj->eflags & MFE_VERTICALFLIP) != !R_ThingVerticallyFlipped(spr->mobj)); + const UINT8 hflip = (UINT8)(!(spr->mobj->mirrored) != !R_ThingHorizontallyFlipped(spr->mobj)); spritedef_t *sprdef; spriteframe_t *sprframe; spriteinfo_t *sprinfo; From caab4e96cd5b59b603b77b672ea1edaa1052a095 Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Sat, 6 Mar 2021 19:38:17 +0200 Subject: [PATCH 301/644] Remove misplaced SetShader call in CompileShaders --- src/hardware/r_opengl/r_opengl.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 2568a7d08..6967bab74 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -962,8 +962,6 @@ EXPORT boolean HWRAPI(CompileShaders) (void) } } - SetShader(SHADER_DEFAULT); - return true; #else return false; From 8cc49a0f2e3a658495094c3972f6c69376bd6a26 Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Sat, 6 Mar 2021 19:56:25 +0200 Subject: [PATCH 302/644] Use double precision in R_StoreWallRange sloped seg culling calculations Fixes culling issues in CEZ2 skybox --- src/r_segs.c | 47 +++++++++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/src/r_segs.c b/src/r_segs.c index c79071e9b..a6772f964 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -1649,23 +1649,26 @@ void R_StoreWallRange(INT32 start, INT32 stop) // left temp = xtoviewangle[start]+viewangle; +#define FIXED_TO_DOUBLE(x) (((double)(x)) / ((double)FRACUNIT)) +#define DOUBLE_TO_FIXED(x) (fixed_t)((x) * ((double)FRACUNIT)) + { // Both lines can be written in slope-intercept form, so figure out line intersection - float a1, b1, c1, a2, b2, c2, det; // 1 is the seg, 2 is the view angle vector... - ///TODO: convert to FPU + double a1, b1, c1, a2, b2, c2, det; // 1 is the seg, 2 is the view angle vector... + ///TODO: convert to fixed point - a1 = FIXED_TO_FLOAT(curline->v2->y-curline->v1->y); - b1 = FIXED_TO_FLOAT(curline->v1->x-curline->v2->x); - c1 = a1*FIXED_TO_FLOAT(curline->v1->x) + b1*FIXED_TO_FLOAT(curline->v1->y); + a1 = FIXED_TO_DOUBLE(curline->v2->y-curline->v1->y); + b1 = FIXED_TO_DOUBLE(curline->v1->x-curline->v2->x); + c1 = a1*FIXED_TO_DOUBLE(curline->v1->x) + b1*FIXED_TO_DOUBLE(curline->v1->y); - a2 = -FIXED_TO_FLOAT(FINESINE(temp>>ANGLETOFINESHIFT)); - b2 = FIXED_TO_FLOAT(FINECOSINE(temp>>ANGLETOFINESHIFT)); - c2 = a2*FIXED_TO_FLOAT(viewx) + b2*FIXED_TO_FLOAT(viewy); + a2 = -FIXED_TO_DOUBLE(FINESINE(temp>>ANGLETOFINESHIFT)); + b2 = FIXED_TO_DOUBLE(FINECOSINE(temp>>ANGLETOFINESHIFT)); + c2 = a2*FIXED_TO_DOUBLE(viewx) + b2*FIXED_TO_DOUBLE(viewy); det = a1*b2 - a2*b1; - ds_p->leftpos.x = segleft.x = FLOAT_TO_FIXED((b2*c1 - b1*c2)/det); - ds_p->leftpos.y = segleft.y = FLOAT_TO_FIXED((a1*c2 - a2*c1)/det); + ds_p->leftpos.x = segleft.x = DOUBLE_TO_FIXED((b2*c1 - b1*c2)/det); + ds_p->leftpos.y = segleft.y = DOUBLE_TO_FIXED((a1*c2 - a2*c1)/det); } // right @@ -1673,22 +1676,26 @@ void R_StoreWallRange(INT32 start, INT32 stop) { // Both lines can be written in slope-intercept form, so figure out line intersection - float a1, b1, c1, a2, b2, c2, det; // 1 is the seg, 2 is the view angle vector... - ///TODO: convert to FPU + double a1, b1, c1, a2, b2, c2, det; // 1 is the seg, 2 is the view angle vector... + ///TODO: convert to fixed point - a1 = FIXED_TO_FLOAT(curline->v2->y-curline->v1->y); - b1 = FIXED_TO_FLOAT(curline->v1->x-curline->v2->x); - c1 = a1*FIXED_TO_FLOAT(curline->v1->x) + b1*FIXED_TO_FLOAT(curline->v1->y); + a1 = FIXED_TO_DOUBLE(curline->v2->y-curline->v1->y); + b1 = FIXED_TO_DOUBLE(curline->v1->x-curline->v2->x); + c1 = a1*FIXED_TO_DOUBLE(curline->v1->x) + b1*FIXED_TO_DOUBLE(curline->v1->y); - a2 = -FIXED_TO_FLOAT(FINESINE(temp>>ANGLETOFINESHIFT)); - b2 = FIXED_TO_FLOAT(FINECOSINE(temp>>ANGLETOFINESHIFT)); - c2 = a2*FIXED_TO_FLOAT(viewx) + b2*FIXED_TO_FLOAT(viewy); + a2 = -FIXED_TO_DOUBLE(FINESINE(temp>>ANGLETOFINESHIFT)); + b2 = FIXED_TO_DOUBLE(FINECOSINE(temp>>ANGLETOFINESHIFT)); + c2 = a2*FIXED_TO_DOUBLE(viewx) + b2*FIXED_TO_DOUBLE(viewy); det = a1*b2 - a2*b1; - ds_p->rightpos.x = segright.x = FLOAT_TO_FIXED((b2*c1 - b1*c2)/det); - ds_p->rightpos.y = segright.y = FLOAT_TO_FIXED((a1*c2 - a2*c1)/det); + ds_p->rightpos.x = segright.x = DOUBLE_TO_FIXED((b2*c1 - b1*c2)/det); + ds_p->rightpos.y = segright.y = DOUBLE_TO_FIXED((a1*c2 - a2*c1)/det); } + +#undef FIXED_TO_DOUBLE +#undef DOUBLE_TO_FIXED + } From efdfa55328c68a53c9d821537a2c60f6a68f4f08 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Fri, 12 Mar 2021 19:54:01 +0100 Subject: [PATCH 303/644] Remove misleading comment --- src/lua_maplib.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 9598f7708..016141796 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -583,17 +583,6 @@ static int sector_get(lua_State *L) lua_pushinteger(L, sector->special); return 1; case sector_tag: - // HELLO - // THIS IS LJ SONIC - // HOW IS YOUR DAY? - // BY THE WAY WHEN 2.3 OR 3.0 OR 4.0 OR SRB3 OR SRB4 OR WHATEVER IS OUT - // YOU SHOULD REMEMBER TO CHANGE THIS SO IT ALWAYS RETURNS A UNSIGNED VALUE - // HAVE A NICE DAY - // - // - // - // - // you are ugly lua_pushinteger(L, (UINT16)Tag_FGet(§or->tags)); return 1; case sector_taglist: From 746c84e0b5431c55841d91ac2cbfbd1ef78b0ebf Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Sat, 13 Mar 2021 23:07:51 +0200 Subject: [PATCH 304/644] Fix wrong color on player models' first frame by updating variable after loading blend texture --- src/hardware/hw_md2.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 2e944d3e6..aa005c2fd 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1405,6 +1405,11 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) || ((!hwrBlendPatch->mipmap->format || !hwrBlendPatch->mipmap->downloaded) && !md2->noblendfile))) md2_loadBlendTexture(md2); + // Load it again, because it isn't being loaded into blendgpatch after md2_loadblendtexture... + blendgpatch = md2->blendgrpatch; + if (blendgpatch) + hwrBlendPatch = ((GLPatch_t *)blendgpatch->hardware); + if (md2->error) return false; // we already failed loading this before :( if (!md2->model) From 36c2be283caad32c51093872f73aa5db6dcb9b4c Mon Sep 17 00:00:00 2001 From: lachablock Date: Mon, 15 Mar 2021 15:17:55 +1100 Subject: [PATCH 305/644] Disallow write_backtrace on Windows entirely --- src/sdl/i_system.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index e8c5d59fb..a0dd6e1da 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -140,6 +140,7 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); #if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) #include #include +#define UNIXBACKTRACE #endif // Locations for searching the srb2.pk3 @@ -243,6 +244,7 @@ SDL_bool framebuffer = SDL_FALSE; UINT8 keyboard_started = false; +#ifdef UNIXBACKTRACE #define STDERR_WRITE(string) if (fd != -1) I_OutputMsg("%s", string) #define CRASHLOG_WRITE(string) if (fd != -1) write(fd, string, strlen(string)) #define CRASHLOG_STDERR_WRITE(string) \ @@ -252,7 +254,6 @@ UINT8 keyboard_started = false; static void write_backtrace(INT32 signal) { -#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) int fd = -1; size_t size; time_t rawtime; @@ -302,11 +303,11 @@ static void write_backtrace(INT32 signal) CRASHLOG_WRITE("\n"); // Write another newline to the log so it looks nice :) close(fd); -#endif } #undef STDERR_WRITE #undef CRASHLOG_WRITE #undef CRASHLOG_STDERR_WRITE +#endif // UNIXBACKTRACE static void I_ReportSignal(int num, int coredumped) { @@ -367,7 +368,9 @@ FUNCNORETURN static ATTRNORETURN void signal_handler(INT32 num) { D_QuitNetGame(); // Fix server freezes CL_AbortDownloadResume(); +#ifdef UNIXBACKTRACE write_backtrace(num); +#endif I_ReportSignal(num, 0); I_ShutdownSystem(); signal(num, SIG_DFL); //default signal action @@ -761,7 +764,9 @@ static void I_RegisterSignals (void) #ifdef NEWSIGNALHANDLER static void signal_handler_child(INT32 num) { +#ifdef UNIXBACKTRACE write_backtrace(num); +#endif signal(num, SIG_DFL); //default signal action raise(num); From 95eff8cbc5f4b0be2ae09a83b8fc04e654a81579 Mon Sep 17 00:00:00 2001 From: sphere Date: Mon, 15 Mar 2021 18:11:02 +0100 Subject: [PATCH 306/644] Avoid savemoddata being set in W_InitFile to fix addons with gamedata. --- src/w_wad.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/w_wad.c b/src/w_wad.c index 2cbcdecb5..91c8331f7 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -821,7 +821,8 @@ UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup) } if (important && !mainfile) - G_SetGameModified(true); + //G_SetGameModified(true); + modifiedgame = true; // avoid savemoddata being set to false // // link wad file to search files From 0c22fecafa04ad263cfa411833835ca6415b2c4b Mon Sep 17 00:00:00 2001 From: sphere Date: Wed, 17 Mar 2021 12:42:18 +0100 Subject: [PATCH 307/644] Make horizontal springs above floors put the player in spring state. --- src/p_map.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index a1cad524e..214d2096e 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -419,10 +419,10 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) } else if (object->player->dashmode >= DASHMODE_THRESHOLD) P_SetPlayerMobjState(object, S_PLAY_DASH); - else if (P_IsObjectOnGround(object) && horizspeed >= FixedMul(object->player->runspeed, object->scale)) - P_SetPlayerMobjState(object, S_PLAY_RUN); + else if (P_IsObjectOnGround(object)) + P_SetPlayerMobjState(object, (horizspeed >= FixedMul(object->player->runspeed, object->scale)) ? S_PLAY_RUN : S_PLAY_WALK); else - P_SetPlayerMobjState(object, S_PLAY_WALK); + P_SetPlayerMobjState(object, (object->momz > 0) ? S_PLAY_SPRING : S_PLAY_FALL); } else if (P_MobjFlip(object)*vertispeed > 0) P_SetPlayerMobjState(object, S_PLAY_SPRING); From b882aea2e4286ccdc3f82bf5cc0bdbc51bd4e8fd Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 21 Mar 2021 19:49:32 +0000 Subject: [PATCH 308/644] Fix clobbering error in hw_md2.c by adding "volatile" to png_FILE. (Apparently Kart made this exact fix 2 years ago and it was never backported?) --- src/hardware/hw_md2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index ac637dfb7..5caf344f7 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -158,7 +158,7 @@ static GLTextureFormat_t PNG_Load(const char *filename, int *w, int *h, GLPatch_ jmp_buf jmpbuf; #endif #endif - png_FILE_p png_FILE; + volatile png_FILE_p png_FILE; //Filename checking fixed ~Monster Iestyn and Golden char *pngfilename = va("%s"PATHSEP"models"PATHSEP"%s", srb2home, filename); From 42cfcbf7be35372fb10363858488b6f68e74fa22 Mon Sep 17 00:00:00 2001 From: katsy Date: Sun, 21 Mar 2021 16:09:11 -0500 Subject: [PATCH 309/644] fix sigsegv in A_Custom3DRotate --- src/p_enemy.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 203e04af1..ceacc1962 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -9868,22 +9868,23 @@ void A_Custom3DRotate(mobj_t *actor) if (LUA_CallAction(A_CUSTOM3DROTATE, actor)) return; + if (!actor->target) // Ensure we actually have a target first. + { + CONS_Printf("Error: A_Custom3DRotate: Object has no target.\n"); + P_RemoveMobj(actor); + return; + } + if (actor->target->health == 0) { P_RemoveMobj(actor); return; } - if (!actor->target) // This should NEVER happen. - { - if (cv_debug) - CONS_Printf("Error: Object has no target\n"); - P_RemoveMobj(actor); - return; - } if (hspeed==0 && vspeed==0) { - CONS_Printf("Error: A_Custom3DRotate: Object has no speed.\n"); + if (cv_debug) + CONS_Printf("Error: A_Custom3DRotate: Object has no speed.\n"); return; } From 2aaaddae7c46e8f3ec108841bc1903cd54fd450a Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 22 Mar 2021 14:17:22 +0000 Subject: [PATCH 310/644] Fix mistake I made with my previous commit for r_skins.c --- src/r_skins.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_skins.c b/src/r_skins.c index 228ec46d0..c56f55e01 100644 --- a/src/r_skins.c +++ b/src/r_skins.c @@ -303,7 +303,7 @@ void SetPlayerSkin(INT32 playernum, const char *skinname) if ((i != -1) && R_SkinUsable(playernum, i)) { - SetSkin(playernum, i); + SetSkin(player, i); return; } From ee8acccd3cd54b87d2f9effa3f49aa8a8cbd969f Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 22 Mar 2021 14:43:26 +0000 Subject: [PATCH 311/644] RETURN OF THE PORTS CHOPPING BLOCK: Destroy DOS! Remove all remaining traces of the following macros for the obsolete DOS port, which were missed previously: * `DJGPP` * `__DJGPP__` * `DJGPPDOS` * `PC_DOS` * `WATTCP` May get rid of `MSDOS` later once I get word on whether I should kill it or not --- src/Makefile | 3 -- src/d_main.h | 4 -- src/d_netfil.c | 6 +-- src/doomdef.h | 2 +- src/doomtype.h | 13 +----- src/i_addrinfo.c | 2 +- src/i_tcp.c | 106 ++--------------------------------------------- src/m_fixed.h | 2 +- src/m_misc.c | 2 - src/s_sound.c | 2 - 10 files changed, 8 insertions(+), 134 deletions(-) diff --git a/src/Makefile b/src/Makefile index 9518942b2..929612271 100644 --- a/src/Makefile +++ b/src/Makefile @@ -98,7 +98,6 @@ ALL_SYSTEMS=\ MINGW64\ HAIKU\ DUMMY\ - DJGPPDOS\ MINGW\ UNIX\ LINUX\ @@ -622,8 +621,6 @@ asm: $(REMOVE) $(OBJDIR)/tmp.exe # executable -# NOTE: DJGPP's objcopy do not have --add-gnu-debuglink - $(BIN)/$(EXENAME): $(POS) $(OBJS) -$(MKDIR) $(BIN) $(call echo,Linking $(EXENAME)...) diff --git a/src/d_main.h b/src/d_main.h index 81de0634d..4e5df87e3 100644 --- a/src/d_main.h +++ b/src/d_main.h @@ -40,10 +40,6 @@ void D_SRB2Main(void); // Called by IO functions when input is detected. void D_PostEvent(const event_t *ev); -#if defined (PC_DOS) && !defined (DOXYGEN) -void D_PostEvent_end(void); // delimiter for locking memory -#endif - void D_ProcessEvents(void); const char *D_Home(void); diff --git a/src/d_netfil.c b/src/d_netfil.c index 8f661bb5f..4729eb09d 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -15,7 +15,7 @@ #include -#if defined (_WIN32) || defined (__DJGPP__) +#ifdef _WIN32 #include #include #else @@ -30,10 +30,6 @@ #elif defined (_WIN32) #include #endif -#ifdef __DJGPP__ -#include -#include -#endif #include "doomdef.h" #include "doomstat.h" diff --git a/src/doomdef.h b/src/doomdef.h index 52abc9597..5f36f2d69 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -100,7 +100,7 @@ #include #include -#if defined (_WIN32) || defined (__DJGPP__) +#ifdef _WIN32 #include #endif diff --git a/src/doomtype.h b/src/doomtype.h index 950f50856..ffaa540b1 100644 --- a/src/doomtype.h +++ b/src/doomtype.h @@ -54,17 +54,6 @@ typedef long ssize_t; #define PDWORD_PTR PDWORD #endif #endif -#elif defined (__DJGPP__) -#define UINT8 unsigned char -#define SINT8 signed char - -#define UINT16 unsigned short int -#define INT16 signed short int - -#define INT32 signed long -#define UINT32 unsigned long -#define INT64 signed long long -#define UINT64 unsigned long long #else #define __STDC_LIMIT_MACROS #include @@ -136,7 +125,7 @@ char *strcasestr(const char *in, const char *what); #endif #endif //macintosh -#if defined (PC_DOS) || defined (_WIN32) || defined (__HAIKU__) +#if defined (_WIN32) || defined (__HAIKU__) #define HAVE_DOSSTR_FUNCS #endif diff --git a/src/i_addrinfo.c b/src/i_addrinfo.c index e77774549..ff0dfbd32 100644 --- a/src/i_addrinfo.c +++ b/src/i_addrinfo.c @@ -20,7 +20,7 @@ #else #include #endif -#elif !defined (__DJGPP__) +#else #include #include #include diff --git a/src/i_tcp.c b/src/i_tcp.c index ab8a69a9f..a9f617dc9 100644 --- a/src/i_tcp.c +++ b/src/i_tcp.c @@ -107,15 +107,6 @@ #endif #endif // USE_WINSOCK - #ifdef __DJGPP__ - #ifdef WATTCP // Alam_GBC: Wattcp may need this - #include - #define strerror strerror_s - #else // wattcp - #include - #endif // libsocket - #endif // djgpp - typedef union { struct sockaddr any; @@ -149,25 +140,15 @@ #include "doomstat.h" -// win32 or djgpp -#if defined (USE_WINSOCK) || defined (__DJGPP__) +// win32 +#ifdef USE_WINSOCK // winsock stuff (in winsock a socket is not a file) #define ioctl ioctlsocket #define close closesocket #endif #include "i_addrinfo.h" - -#ifdef __DJGPP__ - -#ifdef WATTCP #define SELECTTEST -#endif - -#else -#define SELECTTEST -#endif - #define DEFAULTPORT "5029" #if defined (USE_WINSOCK) && !defined (NONET) @@ -184,7 +165,7 @@ #ifndef NONET // define socklen_t in DOS/Windows if it is not already defined - #if (defined (WATTCP) && !defined (__libsocket_socklen_t)) || defined (USE_WINSOCK1) + #ifdef USE_WINSOCK1 typedef int socklen_t; #endif static SOCKET_TYPE mysockets[MAXNETNODES+1] = {ERRSOCKET}; @@ -207,19 +188,6 @@ static const char *serverport_name = DEFAULTPORT; static const char *clientport_name;/* any port */ #ifndef NONET - -#ifdef WATTCP -static void wattcp_outch(char s) -{ - static char old = '\0'; - char pr[2] = {s,0}; - if (s == old && old == ' ') return; - else old = s; - if (s == '\r') CONS_Printf("\n"); - else if (s != '\n') CONS_Printf(pr); -} -#endif - #ifdef USE_WINSOCK // stupid microsoft makes things complicated static char *get_WSAErrorStr(int e) @@ -764,11 +732,7 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen int opt; socklen_t opts; #ifdef FIONBIO -#ifdef WATTCP - char trueval = true; -#else unsigned long trueval = true; -#endif #endif mysockaddr_t straddr; struct sockaddr_in sin; @@ -1138,61 +1102,7 @@ boolean I_InitTcpDriver(void) CONS_Debug(DBG_NETPLAY, "WinSock description: %s\n",WSAData.szDescription); CONS_Debug(DBG_NETPLAY, "WinSock System Status: %s\n",WSAData.szSystemStatus); #endif -#ifdef __DJGPP__ -#ifdef WATTCP // Alam_GBC: survive bootp, dhcp, rarp and wattcp/pktdrv from failing to load - survive_eth = 1; // would be needed to not exit if pkt_eth_init() fails - survive_bootp = 1; // ditto for BOOTP - survive_dhcp = 1; // ditto for DHCP/RARP - survive_rarp = 1; - //_watt_do_exit = false; - //_watt_handle_cbreak = false; - //_watt_no_config = true; - _outch = wattcp_outch; - init_misc(); -//#ifdef DEBUGFILE - dbug_init(); -//#endif - switch (sock_init()) - { - case 0: - init_tcp_driver = true; - break; - case 3: - CONS_Debug(DBG_NETPLAY, "No packet driver detected\n"); - break; - case 4: - CONS_Debug(DBG_NETPLAY, "Error while talking to packet driver\n"); - break; - case 5: - CONS_Debug(DBG_NETPLAY, "BOOTP failed\n"); - break; - case 6: - CONS_Debug(DBG_NETPLAY, "DHCP failed\n"); - break; - case 7: - CONS_Debug(DBG_NETPLAY, "RARP failed\n"); - break; - case 8: - CONS_Debug(DBG_NETPLAY, "TCP/IP failed\n"); - break; - case 9: - CONS_Debug(DBG_NETPLAY, "PPPoE login/discovery failed\n"); - break; - default: - CONS_Debug(DBG_NETPLAY, "Unknown error with TCP/IP stack\n"); - break; - } - hires_timer(0); -#else // wattcp - if (__lsck_init()) - init_tcp_driver = true; - else - CONS_Debug(DBG_NETPLAY, "No TCP/IP driver detected\n"); -#endif // libsocket -#endif // __DJGPP__ -#ifndef __DJGPP__ init_tcp_driver = true; -#endif } #endif if (!tcp_was_up && init_tcp_driver) @@ -1217,10 +1127,8 @@ static void SOCK_CloseSocket(void) if (mysockets[i] != (SOCKET_TYPE)ERRSOCKET && FD_ISSET(mysockets[i], &masterset)) { -#if !defined (__DJGPP__) || defined (WATTCP) FD_CLR(mysockets[i], &masterset); close(mysockets[i]); -#endif } mysockets[i] = ERRSOCKET; } @@ -1237,14 +1145,6 @@ void I_ShutdownTcpDriver(void) WS_addrinfocleanup(); WSACleanup(); #endif -#ifdef __DJGPP__ -#ifdef WATTCP // wattcp - //_outch = NULL; - sock_exit(); -#else - __lsck_uninit(); -#endif // libsocket -#endif // __DJGPP__ CONS_Printf("shut down\n"); init_tcp_driver = false; #endif diff --git a/src/m_fixed.h b/src/m_fixed.h index 289ca442a..f634028c7 100644 --- a/src/m_fixed.h +++ b/src/m_fixed.h @@ -71,7 +71,7 @@ FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FloatToFixed(float f) value [eax] \ modify exact [eax edx] #elif defined (__GNUC__) && defined (__i386__) && !defined (NOASM) - // DJGPP, i386 linux, cygwin or mingw + // i386 linux, cygwin or mingw FUNCMATH FUNCINLINE static inline fixed_t FixedMul(fixed_t a, fixed_t b) // asm { fixed_t ret; diff --git a/src/m_misc.c b/src/m_misc.c index ad2d133ab..a9defab3c 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -64,8 +64,6 @@ typedef off_t off64_t; #define PRIdS "u" #elif defined (_WIN32) #define PRIdS "Iu" -#elif defined (DJGPP) -#define PRIdS "u" #else #define PRIdS "zu" #endif diff --git a/src/s_sound.c b/src/s_sound.c index 392a5b453..7f644b12c 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -1033,11 +1033,9 @@ void S_SetSfxVolume(INT32 volume) void S_ClearSfx(void) { -#ifndef DJGPPDOS size_t i; for (i = 1; i < NUMSFX; i++) I_FreeSfx(S_sfx + i); -#endif } static void S_StopChannel(INT32 cnum) From dca158096df47f730e2827736bf650c1ddb8fe3d Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Mon, 22 Mar 2021 23:56:55 -0300 Subject: [PATCH 312/644] Experimental implementation --- src/blua/lbaselib.c | 2 +- src/d_clisrv.c | 4 +- src/d_main.c | 35 ++++- src/d_netcmd.c | 204 +++++++++++++++++++++++- src/d_netcmd.h | 14 +- src/d_netfil.c | 48 +++++- src/d_netfil.h | 6 + src/filesrch.c | 345 +++++++++++++++++++++++++++++++++++++++-- src/filesrch.h | 8 +- src/hardware/hw_main.c | 2 +- src/m_misc.c | 19 +++ src/m_misc.h | 3 + src/p_setup.c | 45 ++++-- src/p_setup.h | 1 + src/r_textures.c | 17 +- src/r_things.c | 1 + src/w_wad.c | 337 ++++++++++++++++++++++++++++++++++++---- src/w_wad.h | 11 +- 18 files changed, 1007 insertions(+), 95 deletions(-) diff --git a/src/blua/lbaselib.c b/src/blua/lbaselib.c index 644565c28..0fc222038 100644 --- a/src/blua/lbaselib.c +++ b/src/blua/lbaselib.c @@ -274,7 +274,7 @@ static int luaB_dofile (lua_State *L) { UINT16 lumpnum; int n = lua_gettop(L); - if (wadfiles[numwadfiles - 1]->type != RET_PK3) + if (!W_FileHasFolders(wadfiles[numwadfiles - 1])) luaL_error(L, "dofile() only works with PK3 files"); snprintf(fullfilename, sizeof(fullfilename), "Lua/%s", filename); diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 7c2dec6a1..3dfb5cea8 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -4486,9 +4486,9 @@ static INT16 Consistancy(void) { if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) continue; - + mo = (mobj_t *)th; - + if (mo->flags & (MF_SPECIAL | MF_SOLID | MF_PUSHABLE | MF_BOSS | MF_MISSILE | MF_SPRING | MF_MONITOR | MF_FIRE | MF_ENEMY | MF_PAIN | MF_STICKY)) { ret -= mo->type; diff --git a/src/d_main.c b/src/d_main.c index 23a2c0133..09f678ba6 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -873,10 +873,26 @@ static void D_AddFile(char **list, const char *file) newfile = malloc(strlen(file) + 1); if (!newfile) - { I_Error("No more free memory to AddFile %s",file); - } + strcpy(newfile, file); + list[pnumwadfiles] = newfile; +} + +static void D_AddFolder(char **list, const char *file) +{ + size_t pnumwadfiles, len = strlen(file); + char *newfile; + + for (pnumwadfiles = 0; list[pnumwadfiles]; pnumwadfiles++) + ; + + newfile = malloc(len + 2); // NULL terminator + path separator + if (!newfile) + I_Error("No more free memory to AddFolder %s",file); + + strcpy(newfile, file); + strcat(newfile, PATHSEP); list[pnumwadfiles] = newfile; } @@ -1180,7 +1196,7 @@ void D_SRB2Main(void) { if (M_CheckParm("-file")) { - // the parms after p are wadfile/lump names, + // the parms after p are wadfile names, // until end of parms or another - preceded parm while (M_IsNextParm()) { @@ -1190,6 +1206,19 @@ void D_SRB2Main(void) D_AddFile(startuppwads, s); } } + + if (M_CheckParm("-folder")) + { + // the parms after p are folder names, + // until end of parms or another - preceded parm + while (M_IsNextParm()) + { + const char *s = M_GetNextParm(); + + if (s) // Check for NULL? + D_AddFolder(startuppwads, s); + } + } } // get map from parms diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 09f9d4651..c177e4a4a 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -63,7 +63,9 @@ static void Got_WeaponPref(UINT8 **cp, INT32 playernum); static void Got_Mapcmd(UINT8 **cp, INT32 playernum); static void Got_ExitLevelcmd(UINT8 **cp, INT32 playernum); static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum); +static void Got_RequestAddfoldercmd(UINT8 **cp, INT32 playernum); static void Got_Addfilecmd(UINT8 **cp, INT32 playernum); +static void Got_Addfoldercmd(UINT8 **cp, INT32 playernum); static void Got_Pause(UINT8 **cp, INT32 playernum); static void Got_Suicide(UINT8 **cp, INT32 playernum); static void Got_RandomSeed(UINT8 **cp, INT32 playernum); @@ -115,6 +117,7 @@ static void Command_Map_f(void); static void Command_ResetCamera_f(void); static void Command_Addfile(void); +static void Command_Addfolder(void); static void Command_ListWADS_f(void); static void Command_RunSOC(void); static void Command_Pause(void); @@ -398,16 +401,16 @@ const char *netxcmdnames[MAXNETXCMD - 1] = "MAP", "EXITLEVEL", "ADDFILE", + "ADDFOLDER", "PAUSE", "ADDPLAYER", "TEAMCHANGE", "CLEARSCORES", - "LOGIN", "VERIFIED", "RANDOMSEED", "RUNSOC", "REQADDFILE", - "DELFILE", // replace next time we add an XD + "REQADDFOLDER", "SETMOTD", "SUICIDE", "LUACMD", @@ -441,7 +444,9 @@ void D_RegisterServerCommands(void) RegisterNetXCmd(XD_MAP, Got_Mapcmd); RegisterNetXCmd(XD_EXITLEVEL, Got_ExitLevelcmd); RegisterNetXCmd(XD_ADDFILE, Got_Addfilecmd); + RegisterNetXCmd(XD_ADDFOLDER, Got_Addfoldercmd); RegisterNetXCmd(XD_REQADDFILE, Got_RequestAddfilecmd); + RegisterNetXCmd(XD_REQADDFOLDER, Got_RequestAddfoldercmd); RegisterNetXCmd(XD_PAUSE, Got_Pause); RegisterNetXCmd(XD_SUICIDE, Got_Suicide); RegisterNetXCmd(XD_RUNSOC, Got_RunSOCcmd); @@ -472,6 +477,7 @@ void D_RegisterServerCommands(void) COM_AddCommand("showmap", Command_Showmap_f); COM_AddCommand("mapmd5", Command_Mapmd5_f); + COM_AddCommand("addfolder", Command_Addfolder); COM_AddCommand("addfile", Command_Addfile); COM_AddCommand("listwad", Command_ListWADS_f); @@ -3323,9 +3329,9 @@ static void Command_Addfile(void) ++p; // check total packet size and no of files currently loaded - // See W_LoadWadFile in w_wad.c + // See W_InitFile in w_wad.c if ((numwadfiles >= MAX_WADFILES) - || ((packetsizetally + nameonlylength(fn) + 22) > MAXFILENEEDED*sizeof(UINT8))) + || ((packetsizetally + nameonlylength(fn) + FILENEEDEDSIZE) > MAXFILENEEDED*sizeof(UINT8))) { CONS_Alert(CONS_ERROR, M_GetText("Too many files loaded to add %s\n"), fn); return; @@ -3373,6 +3379,89 @@ static void Command_Addfile(void) } } +static void Command_Addfolder(void) +{ + size_t argc = COM_Argc(); // amount of arguments total + size_t curarg; // current argument index + + const char *addedfolders[argc]; // list of filenames already processed + size_t numfoldersadded = 0; // the amount of filenames processed + + if (argc < 2) + { + CONS_Printf(M_GetText("addfolder [path2...] [...]: Load add-ons\n")); + return; + } + + // start at one to skip command name + for (curarg = 1; curarg < argc; curarg++) + { + const char *fn, *p; + char buf[256]; + char *buf_p = buf; + INT32 i; + size_t ii; + boolean folderadded = false; + + fn = COM_Argv(curarg); + + // For the amount of filenames previously processed... + for (ii = 0; ii < numfoldersadded; ii++) + { + // If this is one of them, don't try to add it. + if (!strcmp(fn, addedfolders[ii])) + { + folderadded = true; + break; + } + } + + // If we've added this one, skip to the next one. + if (folderadded) + { + CONS_Alert(CONS_WARNING, M_GetText("Already processed %s, skipping\n"), fn); + continue; + } + + // Disallow non-printing characters and semicolons. + for (i = 0; fn[i] != '\0'; i++) + if (!isprint(fn[i]) || fn[i] == ';') + return; + + // Add file on your client directly if you aren't in a netgame. + if (!(netgame || multiplayer)) + { + P_AddFolder(fn); + addedfolders[numfoldersadded++] = fn; + continue; + } + + p = fn+strlen(fn); + while(--p >= fn) + if (*p == '\\' || *p == '/' || *p == ':') + break; + ++p; + + // check total packet size and no of files currently loaded + // See W_InitFile in w_wad.c + if ((numwadfiles >= MAX_WADFILES) + || ((packetsizetally + strlen(fn) + FILENEEDEDSIZE) > MAXFILENEEDED*sizeof(UINT8))) + { + CONS_Alert(CONS_ERROR, M_GetText("Too many files loaded to add %s\n"), fn); + return; + } + + WRITESTRINGN(buf_p,p,240); + + addedfolders[numfoldersadded++] = fn; + + if (IsPlayerAdmin(consoleplayer) && (!server)) // Request to add file + SendNetXCmd(XD_REQADDFOLDER, buf, buf_p - buf); + else + SendNetXCmd(XD_ADDFOLDER, buf, buf_p - buf); + } +} + static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum) { char filename[241]; @@ -3401,9 +3490,9 @@ static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum) return; } - // See W_LoadWadFile in w_wad.c + // See W_InitFile in w_wad.c if ((numwadfiles >= MAX_WADFILES) - || ((packetsizetally + nameonlylength(filename) + 22) > MAXFILENEEDED*sizeof(UINT8))) + || ((packetsizetally + nameonlylength(filename) + FILENEEDEDSIZE) > MAXFILENEEDED*sizeof(UINT8))) toomany = true; else ncs = findfile(filename,md5sum,true); @@ -3433,6 +3522,64 @@ static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum) COM_BufAddText(va("addfile %s\n", filename)); } +static void Got_RequestAddfoldercmd(UINT8 **cp, INT32 playernum) +{ + char path[241]; + filestatus_t ncs = FS_NOTFOUND; + boolean kick = false; + boolean toomany = false; + INT32 i,j; + + READSTRINGN(*cp, path, 240); + + /// \todo Integrity checks. + + // Only the server processes this message. + if (client) + return; + + // Disallow non-printing characters and semicolons. + for (i = 0; path[i] != '\0'; i++) + if (!isprint(path[i]) || path[i] == ';') + kick = true; + + if ((playernum != serverplayer && !IsPlayerAdmin(playernum)) || kick) + { + CONS_Alert(CONS_WARNING, M_GetText("Illegal addfolder command received from %s\n"), player_names[playernum]); + SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY); + return; + } + + // See W_InitFile in w_wad.c + if ((numwadfiles >= MAX_WADFILES) + || ((packetsizetally + strlen(path) + FILENEEDEDSIZE) > MAXFILENEEDED*sizeof(UINT8))) + toomany = true; + else + ncs = findfolder(path); + + if (ncs != FS_FOUND || toomany) + { + char message[256]; + + if (toomany) + sprintf(message, M_GetText("Too many files loaded to add %s\n"), path); + else if (ncs == FS_NOTFOUND) + sprintf(message, M_GetText("The server doesn't have %s\n"), path); + else + sprintf(message, M_GetText("Unknown error finding folder (%s)\n"), path); + + CONS_Printf("%s",message); + + for (j = 0; j < MAXPLAYERS; j++) + if (adminplayers[j]) + COM_BufAddText(va("sayto %d %s", adminplayers[j], message)); + + return; + } + + COM_BufAddText(va("addfolder \"%s\"\n", path)); +} + static void Got_Addfilecmd(UINT8 **cp, INT32 playernum) { char filename[241]; @@ -3481,6 +3628,49 @@ static void Got_Addfilecmd(UINT8 **cp, INT32 playernum) G_SetGameModified(true); } +static void Got_Addfoldercmd(UINT8 **cp, INT32 playernum) +{ + char path[241]; + filestatus_t ncs = FS_NOTFOUND; + + READSTRINGN(*cp, path, 240); + + /// \todo Integrity checks. + + if (playernum != serverplayer) + { + CONS_Alert(CONS_WARNING, M_GetText("Illegal addfolder command received from %s\n"), player_names[playernum]); + if (server) + SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY); + return; + } + + ncs = findfolder(path); + + if (ncs != FS_FOUND || !P_AddFolder(path)) + { + Command_ExitGame_f(); + if (ncs == FS_FOUND) + { + CONS_Printf(M_GetText("The server tried to add %s,\nbut you have too many files added.\nRestart the game to clear loaded files\nand play on this server."), path); + M_StartMessage(va("The server added a folder \n(%s)\nbut you have too many files added.\nRestart the game to clear loaded files.\n\nPress ESC\n",path), NULL, MM_NOTHING); + } + else if (ncs == FS_NOTFOUND) + { + CONS_Printf(M_GetText("The server tried to add %s,\nbut you don't have this file.\nYou need to find it in order\nto play on this server."), path); + M_StartMessage(va("The server added a folder \n(%s)\nthat you do not have.\n\nPress ESC\n",path), NULL, MM_NOTHING); + } + else + { + CONS_Printf(M_GetText("Unknown error finding folder (%s) the server added.\n"), path); + M_StartMessage(va("Unknown error trying to load a folder\nthat the server added \n(%s).\n\nPress ESC\n",path), NULL, MM_NOTHING); + } + return; + } + + G_SetGameModified(true); +} + static void Command_ListWADS_f(void) { INT32 i = numwadfiles; @@ -3495,6 +3685,8 @@ static void Command_ListWADS_f(void) CONS_Printf("\x82 * %.2d\x80: %s\n", i, tempname); else if (!wadfiles[i]->important) CONS_Printf("\x86 %.2d: %s\n", i, tempname); + else if (wadfiles[i]->type == RET_FOLDER) + CONS_Printf("\x82 * %.2d\x84: %s\n", i, tempname); else CONS_Printf(" %.2d: %s\n", i, tempname); } diff --git a/src/d_netcmd.h b/src/d_netcmd.h index ac39626a4..e7076cabf 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -128,16 +128,16 @@ typedef enum XD_MAP, // 6 XD_EXITLEVEL, // 7 XD_ADDFILE, // 8 - XD_PAUSE, // 9 - XD_ADDPLAYER, // 10 - XD_TEAMCHANGE, // 11 - XD_CLEARSCORES, // 12 - // UNUSED 13 (Because I don't want to change these comments) - XD_VERIFIED = 14,//14 + XD_ADDFOLDER, // 9 + XD_PAUSE, // 10 + XD_ADDPLAYER, // 11 + XD_TEAMCHANGE, // 12 + XD_CLEARSCORES, // 13 + XD_VERIFIED, // 14 XD_RANDOMSEED, // 15 XD_RUNSOC, // 16 XD_REQADDFILE, // 17 - XD_DELFILE, // 18 - replace next time we add an XD + XD_REQADDFOLDER,// 18 XD_SETMOTD, // 19 XD_SUICIDE, // 20 XD_DEMOTED, // 21 diff --git a/src/d_netfil.c b/src/d_netfil.c index 8f661bb5f..4e93f6600 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -120,7 +120,7 @@ char luafiledir[256 + 16] = "luafiles"; /** Fills a serverinfo packet with information about wad files loaded. * * \todo Give this function a better name since it is in global scope. - * Used to have size limiting built in - now handled via W_LoadWadFile in w_wad.c + * Used to have size limiting built in - now handled via W_InitFile in w_wad.c * */ UINT8 *PutFileNeeded(void) @@ -128,7 +128,7 @@ UINT8 *PutFileNeeded(void) size_t i, count = 0; UINT8 *p = netbuffer->u.serverinfo.fileneeded; char wadfilename[MAX_WADPATH] = ""; - UINT8 filestatus; + UINT8 filestatus, folder; for (i = 0; i < numwadfiles; i++) { @@ -137,9 +137,10 @@ UINT8 *PutFileNeeded(void) continue; filestatus = 1; // Importance - not really used any more, holds 1 by default for backwards compat with MS + folder = (wadfiles[i]->type == RET_FOLDER); // Store in the upper four bits - if (!cv_downloading.value) + if (!cv_downloading.value || folder) /// \todo Implement folder downloading. filestatus += (2 << 4); // Won't send else if ((wadfiles[i]->filesize <= (UINT32)cv_maxsend.value * 1024)) filestatus += (1 << 4); // Will send if requested @@ -147,6 +148,7 @@ UINT8 *PutFileNeeded(void) // filestatus += (0 << 4); -- Won't send, too big WRITEUINT8(p, filestatus); + WRITEUINT8(p, folder); count++; WRITEUINT32(p, wadfiles[i]->filesize); @@ -178,6 +180,7 @@ void D_ParseFileneeded(INT32 fileneedednum_parm, UINT8 *fileneededstr) fileneeded[i].status = FS_NOTFOUND; // We haven't even started looking for the file yet fileneeded[i].justdownloaded = false; filestatus = READUINT8(p); // The first byte is the file status + fileneeded[i].folder = READUINT8(p); // The second byte is the folder flag fileneeded[i].willsend = (UINT8)(filestatus >> 4); fileneeded[i].totalsize = READUINT32(p); // The four next bytes are the file size fileneeded[i].file = NULL; // The file isn't open yet @@ -420,7 +423,7 @@ INT32 CL_CheckFiles(void) return 1; } - // See W_LoadWadFile in w_wad.c + // See W_InitFile in w_wad.c packetsize = packetsizetally; for (i = 1; i < fileneedednum; i++) @@ -442,7 +445,10 @@ INT32 CL_CheckFiles(void) if (fileneeded[i].status != FS_NOTFOUND) continue; - packetsize += nameonlylength(fileneeded[i].filename) + 22; + if (fileneeded[i].folder) + packetsize += strlen(fileneeded[i].filename) + FILENEEDEDSIZE; + else + packetsize += nameonlylength(fileneeded[i].filename) + FILENEEDEDSIZE; if ((numwadfiles+filestoget >= MAX_WADFILES) || (packetsize > MAXFILENEEDED*sizeof(UINT8))) @@ -450,7 +456,10 @@ INT32 CL_CheckFiles(void) filestoget++; - fileneeded[i].status = findfile(fileneeded[i].filename, fileneeded[i].md5sum, true); + if (fileneeded[i].folder) + fileneeded[i].status = findfolder(fileneeded[i].filename); + else + fileneeded[i].status = findfile(fileneeded[i].filename, fileneeded[i].md5sum, true); CONS_Debug(DBG_NETPLAY, "found %d\n", fileneeded[i].status); if (fileneeded[i].status != FS_FOUND) ret = 0; @@ -472,7 +481,10 @@ void CL_LoadServerFiles(void) continue; // Already loaded else if (fileneeded[i].status == FS_FOUND) { - P_AddWadFile(fileneeded[i].filename); + if (fileneeded[i].folder) + P_AddFolder(fileneeded[i].filename); + else + P_AddWadFile(fileneeded[i].filename); G_SetGameModified(true); fileneeded[i].status = FS_OPEN; } @@ -757,7 +769,7 @@ static boolean AddFileToSendQueue(INT32 node, const char *filename, UINT8 fileid // This formerly checked if (!findfile(p->id.filename, NULL, true)) // Not found - // Don't inform client (probably someone who thought they could leak 2.2 ACZ) + // Don't inform client DEBFILE(va("Client %d request %s: not found\n", node, filename)); free(p->id.filename); free(p); @@ -1556,3 +1568,23 @@ filestatus_t findfile(char *filename, const UINT8 *wantedmd5sum, boolean complet return (badmd5 ? FS_MD5SUMBAD : FS_NOTFOUND); // md5 sum bad or file not found } + +filestatus_t findfolder(const char *path) +{ + // Check the path by itself first. + if (checkfolderpath(path, NULL, true)) + return FS_FOUND; + +#define checkpath(startpath) { \ + if (checkfolderpath(path, startpath, true)) \ + return FS_FOUND; \ + } + + checkpath(srb2home) // Then, look in srb2home. + checkpath(srb2path) // Now, look in srb2path. + checkpath(".") // Finally, look in ".". + +#undef checkpath + + return FS_NOTFOUND; +} diff --git a/src/d_netfil.h b/src/d_netfil.h index 1b399be75..7cd6e06d3 100644 --- a/src/d_netfil.h +++ b/src/d_netfil.h @@ -38,6 +38,7 @@ typedef enum typedef struct { UINT8 willsend; // Is the server willing to send it? + UINT8 folder; // File is a folder char filename[MAX_WADPATH]; UINT8 md5sum[16]; filestatus_t status; // The value returned by recsearch @@ -54,6 +55,8 @@ typedef struct UINT32 ackresendposition; // Used when resuming downloads } fileneeded_t; +#define FILENEEDEDSIZE 23 + extern INT32 fileneedednum; extern fileneeded_t fileneeded[MAX_WADFILES]; extern char downloaddir[512]; @@ -133,6 +136,9 @@ filestatus_t findfile(char *filename, const UINT8 *wantedmd5sum, boolean completepath); filestatus_t checkfilemd5(char *filename, const UINT8 *wantedmd5sum); +// Searches for a folder +filestatus_t findfolder(const char *path); + void nameonly(char *s); size_t nameonlylength(const char *s); diff --git a/src/filesrch.c b/src/filesrch.c index cb53d07be..f01fc0bd2 100644 --- a/src/filesrch.c +++ b/src/filesrch.c @@ -29,6 +29,7 @@ #include "m_misc.h" #include "z_zone.h" #include "m_menu.h" // Addons_option_Onchange +#include "w_wad.h" #if defined (_WIN32) && defined (_MSC_VER) @@ -340,6 +341,11 @@ char *refreshdirname = NULL; size_t packetsizetally = 0; size_t mainwadstally = 0; +#define folderpathlen 1024 +#define maxfolderdepth 48 + +#define isuptree(dirent) ((dirent)[0]=='.' && ((dirent)[1]=='\0' || ((dirent)[1]=='.' && (dirent)[2]=='\0'))) + filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum, boolean completepath, int maxsearchdepth) { filestatus_t retval = FS_NOTFOUND; @@ -387,10 +393,7 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want continue; } - if (dent->d_name[0]=='.' && - (dent->d_name[1]=='\0' || - (dent->d_name[1]=='.' && - dent->d_name[2]=='\0'))) + if (isuptree(dent->d_name)) { // we don't want to scan uptree continue; @@ -445,6 +448,329 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want return retval; } +// Called from findfolder and ResGetLumpsFolder in w_wad.c. +// Call with cleanup true if the path has to be verified. +boolean checkfolderpath(const char *path, const char *startpath, boolean cleanup) +{ + char folderpath[folderpathlen], basepath[folderpathlen], *fn = NULL; + DIR *dirhandle; + + // Remove path separators from the filename, and don't try adding "/". + // See also the same code in W_InitFolder. + if (cleanup) + { + const char *p = path + strlen(path); + size_t len; + + --p; + while (*p == '\\' || *p == '/' || *p == ':') + { + p--; + if (p < path) + return false; + } + ++p; + + // Allocate the new path name. + len = (p - path) + 1; + fn = ZZ_Alloc(len); + strlcpy(fn, path, len); + } + + if (startpath) + { + snprintf(basepath, sizeof basepath, "%s" PATHSEP, startpath); + + if (cleanup) + { + snprintf(folderpath, sizeof folderpath, "%s%s", basepath, fn); + Z_Free(fn); // Don't need this anymore. + } + else + snprintf(folderpath, sizeof folderpath, "%s%s", basepath, path); + + // Home path and folder path are the same? Not valid. + if (!strcmp(basepath, folderpath)) + return false; + } + else if (cleanup) + { + snprintf(folderpath, sizeof folderpath, "%s", fn); + Z_Free(fn); // Don't need this anymore. + } + else + snprintf(folderpath, sizeof folderpath, "%s", path); + + dirhandle = opendir(folderpath); + if (dirhandle == NULL) + return false; + else + closedir(dirhandle); + + return true; +} + +INT32 pathisfolder(const char *path) +{ + struct stat fsstat; + + if (stat(path, &fsstat) < 0) + return -1; + else if (S_ISDIR(fsstat.st_mode)) + return 1; + + return 0; +} + +INT32 samepaths(const char *path1, const char *path2) +{ + struct stat stat1; + struct stat stat2; + + if (stat(path1, &stat1) < 0) + return -1; + if (stat(path2, &stat2) < 0) + return -1; + + if (stat1.st_dev == stat2.st_dev) + { +#if !defined(_WIN32) + return (stat1.st_ino == stat2.st_ino); +#else + HANDLE file1 = CreateFileA(path1, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); + HANDLE file2 = CreateFileA(path2, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); + BY_HANDLE_FILE_INFORMATION file1info, file2info; + boolean ok = false; + + if (file1 != INVALID_HANDLE_VALUE && file2 != INVALID_HANDLE_VALUE) + { + if (GetFileInformationByHandle(file1, &file1info) && GetFileInformationByHandle(file2, &file2info)) + { + if (file1info.dwVolumeSerialNumber == file2info.dwVolumeSerialNumber + && file1info.nFileIndexLow == file2info.nFileIndexLow + && file1info.nFileIndexHigh == file2info.nFileIndexHigh) + ok = true; + } + } + + if (file1 != INVALID_HANDLE_VALUE) + CloseHandle(file1); + if (file2 != INVALID_HANDLE_VALUE) + CloseHandle(file2); + + return ok; +#endif + } + + return false; +} + +// +// Folder loading +// + +static void initfolderpath(char *folderpath, size_t *folderpathindex, int depthleft) +{ + folderpathindex[depthleft] = strlen(folderpath) + 1; + + if (folderpath[folderpathindex[depthleft]-2] != PATHSEP[0]) + { + folderpath[folderpathindex[depthleft]-1] = PATHSEP[0]; + folderpath[folderpathindex[depthleft]] = 0; + } + else + folderpathindex[depthleft]--; +} + +lumpinfo_t *getfolderfiles(const char *path, UINT16 *nlmp, UINT16 *nfiles, UINT16 *nfolders) +{ + DIR **dirhandle; + struct dirent *dent; + struct stat fsstat; + + int rootfolder = (maxfolderdepth - 1); + int depthleft = rootfolder; + + char folderpath[folderpathlen]; + size_t *folderpathindex; + + lumpinfo_t *lumpinfo, *lump_p; + UINT16 i = 0, numlumps = (*nlmp); + + dirhandle = (DIR **)malloc(maxfolderdepth * sizeof (DIR*)); + folderpathindex = (size_t *)malloc(maxfolderdepth * sizeof(size_t)); + + // Open the root directory + strlcpy(folderpath, path, folderpathlen); + dirhandle[depthleft] = opendir(folderpath); + + if (dirhandle[depthleft] == NULL) + { + free(dirhandle); + free(folderpathindex); + return NULL; + } + + initfolderpath(folderpath, folderpathindex, depthleft); + (*nfiles) = 0; + (*nfolders) = 0; + + // Count files and directories + while (depthleft < maxfolderdepth) + { + folderpath[folderpathindex[depthleft]] = 0; + dent = readdir(dirhandle[depthleft]); + + if (!dent) + { + if (depthleft != rootfolder) // Don't close the root directory + closedir(dirhandle[depthleft]); + depthleft++; + continue; + } + else if (isuptree(dent->d_name)) + continue; + + strcpy(&folderpath[folderpathindex[depthleft]], dent->d_name); + + if (stat(folderpath, &fsstat) < 0) + ; + else if (S_ISDIR(fsstat.st_mode) && depthleft) + { + folderpathindex[--depthleft] = strlen(folderpath) + 1; + dirhandle[depthleft] = opendir(folderpath); + + if (dirhandle[depthleft]) + { + numlumps++; + (*nfolders)++; + } + else + depthleft++; + + folderpath[folderpathindex[depthleft]-1] = '/'; + folderpath[folderpathindex[depthleft]] = 0; + } + else + { + numlumps++; + (*nfiles)++; + } + + if (numlumps == (UINT16_MAX-1)) + break; + } + + // Failure: No files have been found. + if (!(*nfiles)) + { + (*nfiles) = UINT16_MAX; + free(folderpathindex); + free(dirhandle); + for (; depthleft < maxfolderdepth; closedir(dirhandle[depthleft++])); // Close any open directories. + return NULL; + } + + // Create the files and directories as lump entries + // It's possible to create lumps and count files at the same time, + // but I didn't to constantly have to reallocate memory for every lump. + rewinddir(dirhandle[rootfolder]); + depthleft = rootfolder; + + strlcpy(folderpath, path, folderpathlen); + initfolderpath(folderpath, folderpathindex, depthleft); + + lump_p = lumpinfo = Z_Calloc(numlumps * sizeof(lumpinfo_t), PU_STATIC, NULL); + + while (depthleft < maxfolderdepth) + { + char *fullname, *trimname; + + folderpath[folderpathindex[depthleft]] = 0; + dent = readdir(dirhandle[depthleft]); + + if (!dent) + { + closedir(dirhandle[depthleft++]); + continue; + } + else if (isuptree(dent->d_name)) + continue; + + strcpy(&folderpath[folderpathindex[depthleft]], dent->d_name); + + if (stat(folderpath, &fsstat) < 0) + continue; + else if (S_ISDIR(fsstat.st_mode) && depthleft) + { + folderpathindex[--depthleft] = strlen(folderpath) + 1; + dirhandle[depthleft] = opendir(folderpath); + + if (!dirhandle[depthleft]) + { + depthleft++; + continue; + } + + folderpath[folderpathindex[depthleft]-1] = '/'; + folderpath[folderpathindex[depthleft]] = 0; + } + + lump_p->diskpath = Z_StrDup(folderpath); // Path in the filesystem to the file + lump_p->compression = CM_NOCOMPRESSION; // Lump is uncompressed + + // Remove the folder path. + fullname = lump_p->diskpath; + if (strstr(fullname, path)) + fullname += strlen(path) + 1; + + // Get the 8-character long lump name. + trimname = strrchr(fullname, '/'); + if (trimname) + trimname++; + else + trimname = fullname; + + if (trimname[0]) + { + char *dotpos = strrchr(trimname, '.'); + if (dotpos == NULL) + dotpos = fullname + strlen(fullname); + + strncpy(lump_p->name, trimname, min(8, dotpos - trimname)); + + // The name of the file, without the extension. + lump_p->longname = Z_Calloc(dotpos - trimname + 1, PU_STATIC, NULL); + strlcpy(lump_p->longname, trimname, dotpos - trimname + 1); + } + else + lump_p->longname = Z_Calloc(1, PU_STATIC, NULL); + + // The complete name of the file, with its extension, + // excluding the path of the folder where it resides. + lump_p->fullname = Z_StrDup(fullname); + + lump_p++; + i++; + + if (i > numlumps || i == (UINT16_MAX-1)) + { + for (; depthleft < maxfolderdepth; closedir(dirhandle[depthleft++])); // Close any open directories. + break; + } + } + + free(folderpathindex); + free(dirhandle); + + (*nlmp) = numlumps; + return lumpinfo; +} + +// +// Addons menu +// + char exttable[NUM_EXT_TABLE][7] = { // maximum extension length (currently 4) plus 3 (null terminator, stop, and length including previous two) "\5.txt", "\5.cfg", // exec "\5.wad", @@ -455,7 +781,6 @@ char exttable[NUM_EXT_TABLE][7] = { // maximum extension length (currently 4) pl char filenamebuf[MAX_WADFILES][MAX_WADPATH]; - static boolean filemenucmp(char *haystack, char *needle) { static char localhaystack[128]; @@ -640,10 +965,7 @@ boolean preparefilemenu(boolean samedepth) if (!dent) break; - else if (dent->d_name[0]=='.' && - (dent->d_name[1]=='\0' || - (dent->d_name[1]=='.' && - dent->d_name[2]=='\0'))) + else if (isuptree(dent->d_name)) continue; // we don't want to scan uptree strcpy(&menupath[menupathindex[menudepthleft]],dent->d_name); @@ -704,10 +1026,7 @@ boolean preparefilemenu(boolean samedepth) if (!dent) break; - else if (dent->d_name[0]=='.' && - (dent->d_name[1]=='\0' || - (dent->d_name[1]=='.' && - dent->d_name[2]=='\0'))) + else if (isuptree(dent->d_name)) continue; // we don't want to scan uptree strcpy(&menupath[menupathindex[menudepthleft]],dent->d_name); diff --git a/src/filesrch.h b/src/filesrch.h index dfea8979e..92e3341f3 100644 --- a/src/filesrch.h +++ b/src/filesrch.h @@ -7,6 +7,7 @@ #include "doomdef.h" #include "d_netfil.h" #include "m_menu.h" // MAXSTRINGLENGTH +#include "w_wad.h" extern consvar_t cv_addons_option, cv_addons_folder, cv_addons_md5, cv_addons_showall, cv_addons_search_case, cv_addons_search_type; @@ -28,6 +29,12 @@ extern consvar_t cv_addons_option, cv_addons_folder, cv_addons_md5, cv_addons_sh filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum, boolean completepath, int maxsearchdepth); +INT32 pathisfolder(const char *path); +boolean checkfolderpath(const char *path, const char *startpath, boolean cleanup); +INT32 samepaths(const char *path1, const char *path2); + +lumpinfo_t *getfolderfiles(const char *path, UINT16 *nlmp, UINT16 *nfiles, UINT16 *nfolders); + #define menudepth 20 extern char menupath[1024]; @@ -94,5 +101,4 @@ typedef enum void closefilemenu(boolean validsize); void searchfilemenu(char *tempname); boolean preparefilemenu(boolean samedepth); - #endif // __FILESRCH_H__ diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index c2d617eaf..8bbe78f00 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -6681,7 +6681,7 @@ void HWR_LoadAllCustomShaders(void) // read every custom shader for (i = 0; i < numwadfiles; i++) - HWR_LoadCustomShadersFromFile(i, (wadfiles[i]->type == RET_PK3)); + HWR_LoadCustomShadersFromFile(i, W_FileHasFolders(wadfiles[i])); } void HWR_LoadCustomShadersFromFile(UINT16 wadnum, boolean PK3) diff --git a/src/m_misc.c b/src/m_misc.c index ad2d133ab..74c30dedd 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -2688,3 +2688,22 @@ const char * M_Ftrim (double f) return &dig[1];/* skip the 0 */ } } + +// Returns true if the string is empty. +boolean M_IsStringEmpty(const char *s) +{ + const char *ch = s; + + if (ch == NULL || (ch && strlen(ch) < 1)) + return true; + + for (;;ch++) + { + if (!(*ch)) + break; + if (!isspace((*ch))) + return false; + } + + return true; +} diff --git a/src/m_misc.h b/src/m_misc.h index c5ef9f9f2..d23c53978 100644 --- a/src/m_misc.h +++ b/src/m_misc.h @@ -117,6 +117,9 @@ trailing zeros, or "" if the fractional part is zero. */ const char * M_Ftrim (double); +// Returns true if the string is empty. +boolean M_IsStringEmpty(const char *s); + // counting bits, for weapon ammo code, usually FUNCMATH UINT8 M_CountBits(UINT32 num, UINT8 size); diff --git a/src/p_setup.c b/src/p_setup.c index 66243fb0e..d1c0f1740 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -4385,10 +4385,9 @@ static lumpinfo_t* FindFolder(const char *folName, UINT16 *start, UINT16 *end, l // Add a wadfile to the active wad files, // replace sounds, musics, patches, textures, sprites and maps // -boolean P_AddWadFile(const char *wadfilename) +static boolean P_LoadAddon(UINT16 wadnum, UINT16 numlumps) { size_t i, j, sreplaces = 0, mreplaces = 0, digmreplaces = 0; - UINT16 numlumps, wadnum; char *name; lumpinfo_t *lumpinfo; @@ -4409,18 +4408,10 @@ boolean P_AddWadFile(const char *wadfilename) // UINT16 flaPos, flaNum = 0; // UINT16 mapPos, mapNum = 0; - // Init file. - if ((numlumps = W_InitFile(wadfilename, false, false)) == INT16_MAX) - { - refreshdirmenu |= REFRESHDIR_NOTLOADED; - return false; - } - else - wadnum = (UINT16)(numwadfiles-1); - switch(wadfiles[wadnum]->type) { case RET_PK3: + case RET_FOLDER: // Look for the lumps that act as resource delimitation markers. lumpinfo = wadfiles[wadnum]->lumpinfo; for (i = 0; i < numlumps; i++, lumpinfo++) @@ -4584,3 +4575,35 @@ boolean P_AddWadFile(const char *wadfilename) return true; } + +boolean P_AddWadFile(const char *wadfilename) +{ + UINT16 numlumps, wadnum; + + // Init file. + if ((numlumps = W_InitFile(wadfilename, false, false)) == INT16_MAX) + { + refreshdirmenu |= REFRESHDIR_NOTLOADED; + return false; + } + else + wadnum = (UINT16)(numwadfiles-1); + + return P_LoadAddon(wadnum, numlumps); +} + +boolean P_AddFolder(const char *folderpath) +{ + UINT16 numlumps, wadnum; + + // Init file. + if ((numlumps = W_InitFolder(folderpath, false, false)) == INT16_MAX) + { + refreshdirmenu |= REFRESHDIR_NOTLOADED; + return false; + } + else + wadnum = (UINT16)(numwadfiles-1); + + return P_LoadAddon(wadnum, numlumps); +} diff --git a/src/p_setup.h b/src/p_setup.h index 5d13ae7d4..ae849acbf 100644 --- a/src/p_setup.h +++ b/src/p_setup.h @@ -103,6 +103,7 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate); void HWR_LoadLevel(void); #endif boolean P_AddWadFile(const char *wadfilename); +boolean P_AddFolder(const char *folderpath); boolean P_RunSOC(const char *socfilename); void P_LoadSoundsRange(UINT16 wadnum, UINT16 first, UINT16 num); void P_LoadMusicsRange(UINT16 wadnum, UINT16 first, UINT16 num); diff --git a/src/r_textures.c b/src/r_textures.c index a006d739f..0a1248100 100644 --- a/src/r_textures.c +++ b/src/r_textures.c @@ -732,7 +732,7 @@ Rloadflats (INT32 i, INT32 w) texpatch_t *patch; // Yes - if (wadfiles[w]->type == RET_PK3) + if (W_FileHasFolders(wadfiles[w])) { texstart = W_CheckNumForFolderStartPK3("flats/", (UINT16)w, 0); texend = W_CheckNumForFolderEndPK3("flats/", (UINT16)w, texstart); @@ -754,7 +754,7 @@ Rloadflats (INT32 i, INT32 w) size_t lumplength; size_t flatsize = 0; - if (wadfiles[w]->type == RET_PK3) + if (W_FileHasFolders(wadfiles[w])) { if (W_IsLumpFolder(wadnum, lumpnum)) // Check if lump is a folder continue; // If it is then SKIP IT @@ -844,7 +844,7 @@ Rloadtextures (INT32 i, INT32 w) texpatch_t *patch; // Get the lump numbers for the markers in the WAD, if they exist. - if (wadfiles[w]->type == RET_PK3) + if (W_FileHasFolders(wadfiles[w])) { texstart = W_CheckNumForFolderStartPK3("textures/", (UINT16)w, 0); texend = W_CheckNumForFolderEndPK3("textures/", (UINT16)w, texstart); @@ -875,7 +875,7 @@ Rloadtextures (INT32 i, INT32 w) size_t lumplength; #endif - if (wadfiles[w]->type == RET_PK3) + if (W_FileHasFolders(wadfiles[w])) { if (W_IsLumpFolder(wadnum, lumpnum)) // Check if lump is a folder continue; // If it is then SKIP IT @@ -964,7 +964,7 @@ void R_LoadTextures(void) { #ifdef WALLFLATS // Count flats - if (wadfiles[w]->type == RET_PK3) + if (W_FileHasFolders(wadfiles[w])) { texstart = W_CheckNumForFolderStartPK3("flats/", (UINT16)w, 0); texend = W_CheckNumForFolderEndPK3("flats/", (UINT16)w, texstart); @@ -978,7 +978,7 @@ void R_LoadTextures(void) if (!( texstart == INT16_MAX || texend == INT16_MAX )) { // PK3s have subfolders, so we can't just make a simple sum - if (wadfiles[w]->type == RET_PK3) + if (W_FileHasFolders(wadfiles[w])) { for (j = texstart; j < texend; j++) { @@ -1002,7 +1002,7 @@ void R_LoadTextures(void) } // Count single-patch textures - if (wadfiles[w]->type == RET_PK3) + if (W_FileHasFolders(wadfiles[w])) { texstart = W_CheckNumForFolderStartPK3("textures/", (UINT16)w, 0); texend = W_CheckNumForFolderEndPK3("textures/", (UINT16)w, texstart); @@ -1017,7 +1017,7 @@ void R_LoadTextures(void) continue; // PK3s have subfolders, so we can't just make a simple sum - if (wadfiles[w]->type == RET_PK3) + if (W_FileHasFolders(wadfiles[w])) { for (j = texstart; j < texend; j++) { @@ -1558,6 +1558,7 @@ lumpnum_t R_GetFlatNumForName(const char *name) continue; break; case RET_PK3: + case RET_FOLDER: if ((start = W_CheckNumForFolderStartPK3("Flats/", i, 0)) == INT16_MAX) continue; if ((end = W_CheckNumForFolderEndPK3("Flats/", i, start)) == INT16_MAX) diff --git a/src/r_things.c b/src/r_things.c index 14eed9cf2..135c4c5bf 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -443,6 +443,7 @@ void R_AddSpriteDefs(UINT16 wadnum) end = W_CheckNumForNamePwad("SS_END",wadnum,start); //deutex compatib. break; case RET_PK3: + case RET_FOLDER: start = W_CheckNumForFolderStartPK3("Sprites/", wadnum, 0); end = W_CheckNumForFolderEndPK3("Sprites/", wadnum, start); break; diff --git a/src/w_wad.c b/src/w_wad.c index 2cbcdecb5..b305d89e9 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -50,16 +50,17 @@ #include "filesrch.h" -#include "i_video.h" // rendermode +#include "d_main.h" #include "d_netfil.h" -#include "dehacked.h" #include "d_clisrv.h" +#include "dehacked.h" #include "r_defs.h" #include "r_data.h" #include "r_textures.h" #include "r_patch.h" #include "r_picformats.h" #include "i_system.h" +#include "i_video.h" // rendermode #include "md5.h" #include "lua_script.h" #ifdef SCANTHINGS @@ -117,10 +118,15 @@ void W_Shutdown(void) { wadfile_t *wad = wadfiles[numwadfiles]; - fclose(wad->handle); + if (wad->handle) + fclose(wad->handle); Z_Free(wad->filename); + if (wad->path) + Z_Free(wad->path); while (wad->numlumps--) { + if (wad->lumpinfo[wad->numlumps].diskpath) + Z_Free(wad->lumpinfo[wad->numlumps].diskpath); Z_Free(wad->lumpinfo[wad->numlumps].longname); Z_Free(wad->lumpinfo[wad->numlumps].fullname); } @@ -421,6 +427,7 @@ static lumpinfo_t* ResGetLumpsWad (FILE* handle, UINT16* nlmp, const char* filen { lump_p->position = LONG(fileinfo->filepos); lump_p->size = lump_p->disksize = LONG(fileinfo->size); + lump_p->diskpath = NULL; if (compressed) // wad is compressed, lump might be { UINT32 realsize = 0; @@ -602,6 +609,7 @@ static lumpinfo_t* ResGetLumpsZip (FILE* handle, UINT16* nlmp) lump_p->position = zentry.offset; // NOT ACCURATE YET: we still need to read the local entry to find our true position lump_p->disksize = zentry.compsize; + lump_p->diskpath = NULL; lump_p->size = zentry.size; fullname = malloc(zentry.namelen + 1); @@ -679,6 +687,58 @@ static lumpinfo_t* ResGetLumpsZip (FILE* handle, UINT16* nlmp) return lumpinfo; } +// Checks if the combination of the first path and the second path are valid. +// If they are, the concatenated path is returned. +static char *W_CheckFolderPath(const char *startpath, const char *path) +{ + if (checkfolderpath(path, startpath, false)) + { + char *fn; + + if (startpath) + { + size_t len = strlen(startpath) + strlen(path) + strlen(PATHSEP) + 1; + fn = ZZ_Alloc(len); + snprintf(fn, len, "%s" PATHSEP "%s", startpath, path); + } + else + fn = Z_StrDup(path); + + return fn; + } + + return NULL; +} + +// Returns the first valid path for a folder. +static char *W_GetFullFolderPath(const char *path) +{ + // Check the path by itself first. + char *fn = W_CheckFolderPath(NULL, path); + if (fn) + return fn; + +#define checkpath(startpath) { \ + fn = W_CheckFolderPath(startpath, path); \ + if (fn) \ + return fn; \ +} \ + + checkpath(srb2home) // Then, look in srb2home. + checkpath(srb2path) // Now, look in srb2path. + checkpath(".") // Finally, look in ".". + +#undef checkpath + + return NULL; +} + +// Loads files from a folder into a lumpinfo structure. +static lumpinfo_t *ResGetLumpsFolder(const char *path, UINT16 *nlmp, UINT16 *nfiles, UINT16 *nfolders) +{ + return getfolderfiles(path, nlmp, nfiles, nfolders); +} + static UINT16 W_InitFileError (const char *filename, boolean exitworthy) { if (exitworthy) @@ -694,6 +754,19 @@ static UINT16 W_InitFileError (const char *filename, boolean exitworthy) return INT16_MAX; } +static void W_ReadFileShaders(wadfile_t *wadfile) +{ +#ifdef HWRENDER + if (rendermode == render_opengl && (vid.glstate == VID_GL_LIBRARY_LOADED)) + { + HWR_LoadCustomShadersFromFile(numwadfiles - 1, W_FileHasFolders(wadfile)); + HWR_CompileShaders(); + } +#else + (void)wadfile; +#endif +} + // Allocate a wadfile, setup the lumpinfo (directory) and // lumpcache, add the wadfile to the current active wadfiles // @@ -760,7 +833,7 @@ UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup) // see PutFileNeeded in d_netfil.c if ((important = !important)) { - packetsize = packetsizetally + nameonlylength(filename) + 22; + packetsize = packetsizetally + nameonlylength(filename) + FILENEEDEDSIZE; if (packetsize > MAXFILENEEDED*sizeof(UINT8)) { @@ -788,7 +861,7 @@ UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup) { CONS_Alert(CONS_ERROR, M_GetText("%s is already loaded\n"), filename); if (important) - packetsizetally -= nameonlylength(filename) + 22; + packetsizetally -= nameonlylength(filename) + FILENEEDEDSIZE; if (handle) fclose(handle); return W_InitFileError(filename, false); @@ -828,9 +901,11 @@ UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup) // wadfile = Z_Malloc(sizeof (*wadfile), PU_STATIC, NULL); wadfile->filename = Z_StrDup(filename); + wadfile->path = NULL; wadfile->type = type; wadfile->handle = handle; - wadfile->numlumps = (UINT16)numlumps; + wadfile->numlumps = numlumps; + wadfile->filecount = wadfile->foldercount = 0; wadfile->lumpinfo = lumpinfo; wadfile->important = important; fseek(handle, 0, SEEK_END); @@ -853,14 +928,8 @@ UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup) wadfiles[numwadfiles] = wadfile; numwadfiles++; // must come BEFORE W_LoadDehackedLumps, so any addfile called by COM_BufInsertText called by Lua doesn't overwrite what we just loaded -#ifdef HWRENDER // Read shaders from file - if (rendermode == render_opengl && (vid.glstate == VID_GL_LIBRARY_LOADED)) - { - HWR_LoadCustomShadersFromFile(numwadfiles - 1, (type == RET_PK3)); - HWR_CompileShaders(); - } -#endif // HWRENDER + W_ReadFileShaders(wadfile); // TODO: HACK ALERT - Load Lua & SOC stuff right here. I feel like this should be out of this place, but... Let's stick with this for now. switch (wadfile->type) @@ -886,6 +955,153 @@ UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup) return wadfile->numlumps; } +// +// Loads a folder as a WAD. +// +UINT16 W_InitFolder(const char *path, boolean mainfile, boolean startup) +{ + lumpinfo_t *lumpinfo = NULL; + wadfile_t *wadfile; + UINT16 numlumps = 0; + UINT16 filecount, foldercount; + size_t i; + char *fn, *fullpath; + const char *p; + int important; + + if (!(refreshdirmenu & REFRESHDIR_ADDFILE)) + refreshdirmenu = REFRESHDIR_NORMAL|REFRESHDIR_ADDFILE; // clean out cons_alerts that happened earlier + + if (refreshdirname) + Z_Free(refreshdirname); + if (dirmenu) + refreshdirname = Z_StrDup(path); + else + refreshdirname = NULL; + + if (numwadfiles >= MAX_WADFILES) + { + CONS_Alert(CONS_ERROR, M_GetText("Maximum wad files reached\n")); + refreshdirmenu |= REFRESHDIR_MAX; + return W_InitFileError(path, startup); + } + + important = 0; // ??? + + /// \todo Implement a W_VerifyFolder. + if ((important = !important)) + { + size_t packetsize = packetsizetally + strlen(path) + FILENEEDEDSIZE; + + if (packetsize > MAXFILENEEDED*sizeof(UINT8)) + { + CONS_Alert(CONS_ERROR, M_GetText("Maximum wad files reached\n")); + refreshdirmenu |= REFRESHDIR_MAX; + return W_InitFileError(path, startup); + } + + packetsizetally = packetsize; + } + + // Remove path separators from the filename, and don't try adding "/". + p = path+strlen(path); + --p; + + while (*p == '\\' || *p == '/' || *p == ':') + { + p--; + if (p < path) + { + CONS_Alert(CONS_ERROR, M_GetText("Path %s is prohibited\n"), path); + return W_InitFileError(path, startup); + } + } + p++; + + // Allocate the new path name. + i = (p - path) + 1; + fn = ZZ_Alloc(i); + strlcpy(fn, path, i); + + if (M_IsStringEmpty(fn)) + { + CONS_Alert(CONS_ERROR, M_GetText("Folder name is empty\n")); + Z_Free(fn); + + if (startup) + return W_InitFileError("A folder", true); + else + return W_InitFileError("a folder", false); + } + + // Get the full path for this filename. + fullpath = W_GetFullFolderPath(fn); + if (fullpath == NULL) + { + Z_Free(fn); + return W_InitFileError(path, false); + } + + for (i = 0; i < numwadfiles; i++) + { + if (wadfiles[i]->type != RET_FOLDER) + continue; + + if (samepaths(wadfiles[i]->path, fullpath) > 0) + { + CONS_Alert(CONS_ERROR, M_GetText("%s is already loaded\n"), path); + if (important) + packetsizetally -= strlen(path) + FILENEEDEDSIZE; + Z_Free(fn); + Z_Free(fullpath); + return W_InitFileError(path, false); + } + } + + lumpinfo = ResGetLumpsFolder(fullpath, &numlumps, &filecount, &foldercount); + if (lumpinfo == NULL) + { + if (filecount == UINT16_MAX) + CONS_Alert(CONS_ERROR, M_GetText("Folder %s is empty\n"), path); + + Z_Free(fn); + Z_Free(fullpath); + + return W_InitFileError(path, startup); + } + + if (important && !mainfile) + G_SetGameModified(true); + + wadfile = Z_Malloc(sizeof (*wadfile), PU_STATIC, NULL); + wadfile->filename = fn; + wadfile->path = fullpath; + wadfile->type = RET_FOLDER; + wadfile->handle = NULL; + wadfile->numlumps = numlumps; + wadfile->filecount = filecount; + wadfile->foldercount = foldercount; + wadfile->lumpinfo = lumpinfo; + wadfile->important = important; + + // Irrelevant. + wadfile->filesize = 0; + memset(wadfile->md5sum, 0x00, 16); + + Z_Calloc(numlumps * sizeof (*wadfile->lumpcache), PU_STATIC, &wadfile->lumpcache); + Z_Calloc(numlumps * sizeof (*wadfile->patchcache), PU_STATIC, &wadfile->patchcache); + + CONS_Printf(M_GetText("Added folder %s (%u files, %u folders)\n"), fn, filecount, foldercount); + wadfiles[numwadfiles] = wadfile; + numwadfiles++; + + W_ReadFileShaders(wadfile); + W_LoadDehackedLumpsPK3(numwadfiles - 1, mainfile); + W_InvalidateLumpnumCache(); + + return wadfile->numlumps; +} + /** Tries to load a series of files. * All files are wads unless they have an extension of ".soc" or ".lua". * @@ -897,11 +1113,18 @@ UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup) */ void W_InitMultipleFiles(char **filenames) { - // will be realloced as lumps are added for (; *filenames; filenames++) { - //CONS_Debug(DBG_SETUP, "Loading %s\n", *filenames); - W_InitFile(*filenames, numwadfiles < mainwads, true); + const char *fn = (*filenames); + char pathsep = fn[strlen(fn) - 1]; + boolean mainfile = (numwadfiles < mainwads); + + //CONS_Debug(DBG_SETUP, "Loading %s\n", fn); + + if (pathsep == '\\' || pathsep == '/') + W_InitFolder(fn, mainfile, true); + else + W_InitFile(fn, mainfile, true); } } @@ -1175,7 +1398,7 @@ lumpnum_t W_CheckNumForMap(const char *name) if (!strncmp(name, (wadfiles[i]->lumpinfo + lumpNum)->name, 8)) return (i<<16) + lumpNum; } - else if (wadfiles[i]->type == RET_PK3) + else if (W_FileHasFolders(wadfiles[i])) { lumpNum = W_CheckNumForFolderStartPK3("maps/", i, 0); if (lumpNum != INT16_MAX) @@ -1273,9 +1496,34 @@ UINT8 W_LumpExists(const char *name) size_t W_LumpLengthPwad(UINT16 wad, UINT16 lump) { + lumpinfo_t *l; + if (!TestValidLump(wad, lump)) return 0; - return wadfiles[wad]->lumpinfo[lump].size; + + l = wadfiles[wad]->lumpinfo + lump; + + if (wadfiles[wad]->type == RET_FOLDER) + { + INT32 stat = pathisfolder(l->diskpath); + + if (stat < 0) + I_Error("W_LumpLengthPwad: could not stat %s", l->diskpath); + else if (stat == 1) // Path is a folder. + return 0; + else + { + FILE *handle = fopen(l->diskpath, "rb"); + if (handle == NULL) + I_Error("W_LumpLengthPwad: could not open file %s", l->diskpath); + + fseek(handle, 0, SEEK_END); + l->size = l->disksize = ftell(handle); + fclose(handle); + } + } + + return l->size; } /** Returns the buffer size needed to load the given lump. @@ -1294,7 +1542,7 @@ size_t W_LumpLength(lumpnum_t lumpnum) // boolean W_IsLumpWad(lumpnum_t lumpnum) { - if (wadfiles[WADFILENUM(lumpnum)]->type == RET_PK3) + if (W_FileHasFolders(wadfiles[WADFILENUM(lumpnum)])) { const char *lumpfullName = (wadfiles[WADFILENUM(lumpnum)]->lumpinfo + LUMPNUM(lumpnum))->fullname; @@ -1312,7 +1560,7 @@ boolean W_IsLumpWad(lumpnum_t lumpnum) // boolean W_IsLumpFolder(UINT16 wad, UINT16 lump) { - if (wadfiles[wad]->type == RET_PK3) + if (W_FileHasFolders(wadfiles[wad])) { const char *name = wadfiles[wad]->lumpinfo[lump].fullname; @@ -1362,17 +1610,44 @@ void zerr(int ret) */ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, size_t offset) { - size_t lumpsize; + size_t lumpsize, bytesread; lumpinfo_t *l; - FILE *handle; + FILE *handle = NULL; if (!TestValidLump(wad,lump)) return 0; + l = wadfiles[wad]->lumpinfo + lump; + + // Open the external file for this lump, if the WAD is a folder. + if (wadfiles[wad]->type == RET_FOLDER) + { + INT32 stat = pathisfolder(l->diskpath); + + if (stat < 0) + I_Error("W_ReadLumpHeaderPwad: could not stat %s", l->diskpath); + else if (stat == 1) // Path is a folder. + return 0; + else + { + handle = fopen(l->diskpath, "rb"); + if (handle == NULL) + I_Error("W_ReadLumpHeaderPwad: could not open file %s", l->diskpath); + + // Find length of file + fseek(handle, 0, SEEK_END); + l->size = l->disksize = ftell(handle); + } + } + lumpsize = wadfiles[wad]->lumpinfo[lump].size; // empty resource (usually markers like S_START, F_END ..) if (!lumpsize || lumpsizetype == RET_FOLDER) + fclose(handle); return 0; + } // zero size means read all the lump if (!size || size+offset > lumpsize) @@ -1380,24 +1655,22 @@ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, si // Let's get the raw lump data. // We setup the desired file handle to read the lump data. - l = wadfiles[wad]->lumpinfo + lump; - handle = wadfiles[wad]->handle; + if (wadfiles[wad]->type != RET_FOLDER) + handle = wadfiles[wad]->handle; fseek(handle, (long)(l->position + offset), SEEK_SET); // But let's not copy it yet. We support different compression formats on lumps, so we need to take that into account. switch(wadfiles[wad]->lumpinfo[lump].compression) { case CM_NOCOMPRESSION: // If it's uncompressed, we directly write the data into our destination, and return the bytes read. + bytesread = fread(dest, 1, size, handle); + if (wadfiles[wad]->type == RET_FOLDER) + fclose(handle); #ifdef NO_PNG_LUMPS - { - size_t bytesread = fread(dest, 1, size, handle); - if (Picture_IsLumpPNG((UINT8 *)dest, bytesread)) - Picture_ThrowPNGError(l->fullname, wadfiles[wad]->filename); - return bytesread; - } -#else - return fread(dest, 1, size, handle); + if (Picture_IsLumpPNG((UINT8 *)dest, bytesread)) + Picture_ThrowPNGError(l->fullname, wadfiles[wad]->filename); #endif + return bytesread; case CM_LZF: // Is it LZF compressed? Used by ZWADs. { #ifdef ZWAD diff --git a/src/w_wad.h b/src/w_wad.h index d0a86bcb4..8b3c3808e 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -69,6 +69,7 @@ typedef struct char name[9]; // filelump_t name[] e.g. "LongEntr" char *longname; // e.g. "LongEntryName" char *fullname; // e.g. "Folder/Subfolder/LongEntryName.extension" + char *diskpath; // path to the file e.g. "/usr/games/srb2/Addon/Folder/Subfolder/LongEntryName.extension" size_t size; // real (uncompressed) size compmethod compression; // lump compression method } lumpinfo_t; @@ -109,17 +110,19 @@ typedef enum restype RET_SOC, RET_LUA, RET_PK3, + RET_FOLDER, RET_UNKNOWN, } restype_t; typedef struct wadfile_s { - char *filename; + char *filename, *path; restype_t type; lumpinfo_t *lumpinfo; lumpcache_t *lumpcache; lumpcache_t *patchcache; UINT16 numlumps; // this wad's number of resources + UINT16 filecount, foldercount; // file and folder count FILE *handle; UINT32 filesize; // for network UINT8 md5sum[16]; @@ -127,7 +130,7 @@ typedef struct wadfile_s boolean important; // also network - !W_VerifyNMUSlumps } wadfile_t; -#define WADFILENUM(lumpnum) (UINT16)((lumpnum)>>16) // wad flumpnum>>16) // wad file number in upper word +#define WADFILENUM(lumpnum) (UINT16)((lumpnum)>>16) // wad file number in upper word #define LUMPNUM(lumpnum) (UINT16)((lumpnum)&0xFFFF) // lump number for this pwad extern UINT16 numwadfiles; @@ -141,10 +144,14 @@ void W_Shutdown(void); FILE *W_OpenWadFile(const char **filename, boolean useerrors); // Load and add a wadfile to the active wad files, returns numbers of lumps, INT16_MAX on error UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup); +// Adds a folder as a file +UINT16 W_InitFolder(const char *path, boolean mainfile, boolean startup); // W_InitMultipleFiles exits if a file was not found, but not if all is okay. void W_InitMultipleFiles(char **filenames); +#define W_FileHasFolders(wadfile) ((wadfile)->type == RET_PK3 || (wadfile)->type == RET_FOLDER) + const char *W_CheckNameForNumPwad(UINT16 wad, UINT16 lump); const char *W_CheckNameForNum(lumpnum_t lumpnum); From 0405b3922c6104a4e1c1eee899e8ebb07209260a Mon Sep 17 00:00:00 2001 From: lachablock Date: Tue, 23 Mar 2021 14:49:22 +1100 Subject: [PATCH 313/644] Do not let nonspin characters enter sectors they could not enter if standing at full height --- src/lua_baselib.c | 22 ++++++++++++++++++++++ src/p_local.h | 2 ++ src/p_map.c | 11 +++++++++++ src/p_user.c | 24 ++++++++++++++++++------ 4 files changed, 53 insertions(+), 6 deletions(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 916fa9254..a59ba546e 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -1671,6 +1671,26 @@ static int lib_pSwitchShield(lua_State *L) return 0; } +static int lib_pPlayerCanEnterSpinGaps(lua_State *L) +{ + player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + INLEVEL + if (!player) + return LUA_ErrInvalid(L, "player_t"); + lua_pushboolean(L, P_PlayerCanEnterSpinGaps(player)); + return 1; +} + +static int lib_pPlayerShouldUseSpinHeight(lua_State *L) +{ + player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + INLEVEL + if (!player) + return LUA_ErrInvalid(L, "player_t"); + lua_pushboolean(L, P_PlayerShouldUseSpinHeight(player)); + return 1; +} + // P_MAP /////////// @@ -3872,6 +3892,8 @@ static luaL_Reg lib[] = { {"P_SpawnSpinMobj",lib_pSpawnSpinMobj}, {"P_Telekinesis",lib_pTelekinesis}, {"P_SwitchShield",lib_pSwitchShield}, + {"P_PlayerCanEnterSpinGaps",lib_pPlayerCanEnterSpinGaps}, + {"P_PlayerShouldUseSpinHeight",lib_pPlayerShouldUseSpinHeight}, // p_map {"P_CheckPosition",lib_pCheckPosition}, diff --git a/src/p_local.h b/src/p_local.h index 8caab0d27..8568dd4f8 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -143,6 +143,8 @@ angle_t P_GetLocalAngle(player_t *player); void P_SetLocalAngle(player_t *player, angle_t angle); void P_ForceLocalAngle(player_t *player, angle_t angle); boolean P_PlayerFullbright(player_t *player); +boolean P_PlayerCanEnterSpinGaps(player_t *player); +boolean P_PlayerShouldUseSpinHeight(player_t *player); boolean P_IsObjectInGoop(mobj_t *mo); boolean P_IsObjectOnGround(mobj_t *mo); diff --git a/src/p_map.c b/src/p_map.c index a1cad524e..7eec0937c 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1955,6 +1955,12 @@ static boolean PIT_CheckLine(line_t *ld) // set openrange, opentop, openbottom P_LineOpening(ld, tmthing); + // players should not always cross into sectors that they could not at full height + if (tmthing->player + && openrange < P_GetPlayerHeight(tmthing->player) + && !P_PlayerCanEnterSpinGaps(tmthing->player)) + return false; + // adjust floor / ceiling heights if (opentop < tmceilingz) { @@ -3331,6 +3337,11 @@ static boolean PTR_LineIsBlocking(line_t *li) if (openbottom - slidemo->z > FixedMul(MAXSTEPMOVE, slidemo->scale)) return true; // too big a step up + if (slidemo->player + && openrange < P_GetPlayerHeight(slidemo->player) + && !P_PlayerCanEnterSpinGaps(slidemo->player)) + return true; // nonspin character should not take this path + return false; } diff --git a/src/p_user.c b/src/p_user.c index 02592053d..38f13f8fd 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8653,12 +8653,7 @@ void P_MovePlayer(player_t *player) fixed_t oldheight = player->mo->height; // Less height while spinning. Good for spinning under things...? - if ((player->mo->state == &states[player->mo->info->painstate]) - || ((player->pflags & PF_JUMPED) && !(player->pflags & PF_NOJUMPDAMAGE)) - || (player->pflags & PF_SPINNING) - || player->powers[pw_tailsfly] || player->pflags & PF_GLIDING - || (player->charability == CA_GLIDEANDCLIMB && player->mo->state-states == S_PLAY_GLIDE_LANDING) - || (player->charability == CA_FLY && player->mo->state-states == S_PLAY_FLY_TIRED)) + if (P_PlayerShouldUseSpinHeight(player)) { player->mo->height = P_GetPlayerSpinHeight(player); atspinheight = true; @@ -12953,3 +12948,20 @@ boolean P_PlayerFullbright(player_t *player) || !(player->mo->state >= &states[S_PLAY_NIGHTS_TRANS1] && player->mo->state < &states[S_PLAY_NIGHTS_TRANS6])))); // Note the < instead of <= } + +// returns true if the player can enter a sector that they could not if standing at their skin's full height +boolean P_PlayerCanEnterSpinGaps(player_t *player) +{ + return ((player->pflags & (PF_SPINNING|PF_GLIDING)) + || (player->charability == CA_GLIDEANDCLIMB && player->mo->state-states == S_PLAY_GLIDE_LANDING)); +} + +// returns true if the player should use their skin's spinheight instead of their skin's height +boolean P_PlayerShouldUseSpinHeight(player_t *player) +{ + return (P_PlayerCanEnterSpinGaps(player) + || (player->mo->state == &states[player->mo->info->painstate]) + || ((player->pflags & PF_JUMPED) && !(player->pflags & PF_NOJUMPDAMAGE)) + || player->powers[pw_tailsfly] + || (player->charability == CA_FLY && player->mo->state-states == S_PLAY_FLY_TIRED)); +} From 08937f892a4eec9c6cdf7c0c3c1ce255941c8ba6 Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Tue, 23 Mar 2021 01:18:28 -0300 Subject: [PATCH 314/644] Allocate a buffer for non-RGBA to RGBA texture conversions. UpdateTexture will I_Error (from AllocTextureBuffer) if the allocation fails. --- src/hardware/r_opengl/r_opengl.c | 124 ++++++++++++++++++++----------- 1 file changed, 82 insertions(+), 42 deletions(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 6967bab74..7c77c27ea 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -131,7 +131,6 @@ static const GLfloat byte2float[256] = { // -----------------+ // GL_DBG_Printf : Output debug messages to debug log if DEBUG_TO_FILE is defined, // : else do nothing -// Returns : // -----------------+ #ifdef DEBUG_TO_FILE @@ -159,8 +158,6 @@ FUNCPRINTF void GL_DBG_Printf(const char *format, ...) // -----------------+ // GL_MSG_Warning : Raises a warning. -// : -// Returns : // -----------------+ static void GL_MSG_Warning(const char *format, ...) @@ -184,8 +181,6 @@ static void GL_MSG_Warning(const char *format, ...) // -----------------+ // GL_MSG_Error : Raises an error. -// : -// Returns : // -----------------+ static void GL_MSG_Error(const char *format, ...) @@ -207,6 +202,32 @@ static void GL_MSG_Error(const char *format, ...) #endif } +// ----------------------+ +// GetTextureFormatName : Returns the corresponding texture format string from the texture format enumeration. +// ----------------------+ +static const char *GetTextureFormatName(INT32 format) +{ + static char num[12]; + + switch (format) + { + case GL_TEXFMT_P_8: return "GL_TEXFMT_P_8"; + case GL_TEXFMT_AP_88: return "GL_TEXFMT_AP_88"; + case GL_TEXFMT_RGBA: return "GL_TEXFMT_RGBA"; + case GL_TEXFMT_ALPHA_8: return "GL_TEXFMT_ALPHA_8"; + case GL_TEXFMT_INTENSITY_8: return "GL_TEXFMT_INTENSITY_8"; + case GL_TEXFMT_ALPHA_INTENSITY_88: return "GL_TEXFMT_ALPHA_INTENSITY_88"; + default: break; + } + + // If the texture format is not known (due to it being invalid), + // return a string containing the format index instead. + format = INT32_MIN; + snprintf(num, sizeof(num), "%d", format); + + return num; +} + #ifdef STATIC_OPENGL /* 1.0 functions */ /* Miscellaneous */ @@ -1375,7 +1396,6 @@ INT32 isExtAvailable(const char *extension, const GLubyte *start) // -----------------+ // Init : Initialise the OpenGL interface API -// Returns : // -----------------+ EXPORT boolean HWRAPI(Init) (void) { @@ -1737,37 +1757,59 @@ EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags) CurrentPolyFlags = PolyFlags; } +// -------------------+ +// AllocTextureBuffer : Allocates memory for converting a non-RGBA texture into an RGBA texture. +// -------------------+ +static RGBA_t *AllocTextureBuffer(GLMipmap_t *pTexInfo) +{ + size_t len = (pTexInfo->width * pTexInfo->height); + RGBA_t *tex = calloc(len, sizeof(RGBA_t)); + + if (tex == NULL) + I_Error("AllocTextureBuffer: out of memory allocating %s bytes for texture %d, format %s", + sizeu1(len * sizeof(RGBA_t)), pTexInfo->downloaded, GetTextureFormatName(pTexInfo->format)); + + return tex; +} + +// ------------------+ +// FreeTextureBuffer : Frees memory allocated by AllocTextureBuffer. +// ------------------+ +static void FreeTextureBuffer(RGBA_t *tex) +{ + if (tex) + free(tex); +} + // -----------------+ -// UpdateTexture : Updates the texture data. +// UpdateTexture : Updates texture data. // -----------------+ EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *pTexInfo) { - // Download a mipmap - boolean updatemipmap = true; - static RGBA_t tex[2048*2048]; - const GLvoid *ptex = tex; - INT32 w, h; - GLuint texnum = 0; + // Upload a texture + GLuint num = pTexInfo->downloaded; + boolean update = true; - if (!pTexInfo->downloaded) + INT32 w = pTexInfo->width, h = pTexInfo->height; + INT32 i, j; + + const GLubyte *pImgData = (const GLubyte *)pTexInfo->data; + const GLvoid *ptex = NULL; + RGBA_t *tex = NULL; + + // Generate a new texture name. + if (!num) { - pglGenTextures(1, &texnum); - pTexInfo->downloaded = texnum; - updatemipmap = false; + pglGenTextures(1, &num); + pTexInfo->downloaded = num; + update = false; } - else - texnum = pTexInfo->downloaded; - //GL_DBG_Printf ("DownloadMipmap %d %x\n",(INT32)texnum,pTexInfo->data); + //GL_DBG_Printf("UpdateTexture %d %x\n", (INT32)num, pImgData); - w = pTexInfo->width; - h = pTexInfo->height; - - if ((pTexInfo->format == GL_TEXFMT_P_8) || - (pTexInfo->format == GL_TEXFMT_AP_88)) + if ((pTexInfo->format == GL_TEXFMT_P_8) || (pTexInfo->format == GL_TEXFMT_AP_88)) { - const GLubyte *pImgData = (const GLubyte *)pTexInfo->data; - INT32 i, j; + ptex = tex = AllocTextureBuffer(pTexInfo); for (j = 0; j < h; j++) { @@ -1798,20 +1840,17 @@ EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *pTexInfo) tex[w*j+i].s.alpha = *pImgData; pImgData++; } - } } } else if (pTexInfo->format == GL_TEXFMT_RGBA) { - // corona test : passed as ARGB 8888, which is not in glide formats - // Hurdler: not used for coronas anymore, just for dynamic lighting - ptex = pTexInfo->data; + // Directly upload the texture data without any kind of conversion. + ptex = pImgData; } else if (pTexInfo->format == GL_TEXFMT_ALPHA_INTENSITY_88) { - const GLubyte *pImgData = (const GLubyte *)pTexInfo->data; - INT32 i, j; + ptex = tex = AllocTextureBuffer(pTexInfo); for (j = 0; j < h; j++) { @@ -1828,8 +1867,7 @@ EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *pTexInfo) } else if (pTexInfo->format == GL_TEXFMT_ALPHA_8) // Used for fade masks { - const GLubyte *pImgData = (const GLubyte *)pTexInfo->data; - INT32 i, j; + ptex = tex = AllocTextureBuffer(pTexInfo); for (j = 0; j < h; j++) { @@ -1844,11 +1882,10 @@ EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *pTexInfo) } } else - GL_MSG_Warning ("SetTexture(bad format) %ld\n", pTexInfo->format); + GL_MSG_Warning("UpdateTexture: bad format %d\n", pTexInfo->format); - // the texture number was already generated by pglGenTextures - pglBindTexture(GL_TEXTURE_2D, texnum); - tex_downloaded = texnum; + pglBindTexture(GL_TEXTURE_2D, num); + tex_downloaded = num; // disable texture filtering on any texture that has holes so there's no dumb borders or blending issues if (pTexInfo->flags & TF_TRANSPARENT) @@ -1877,7 +1914,7 @@ EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *pTexInfo) } else { - if (updatemipmap) + if (update) pglTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex); else pglTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); @@ -1898,7 +1935,7 @@ EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *pTexInfo) } else { - if (updatemipmap) + if (update) pglTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex); else pglTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); @@ -1918,13 +1955,16 @@ EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *pTexInfo) } else { - if (updatemipmap) + if (update) pglTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ptex); else pglTexImage2D(GL_TEXTURE_2D, 0, textureformatGL, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); } } + // Free the texture buffer + FreeTextureBuffer(tex); + if (pTexInfo->flags & TF_WRAPX) pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); else From f99d89742a7c0347bb7e2092fa1ede7a02766abc Mon Sep 17 00:00:00 2001 From: lachablock Date: Thu, 25 Mar 2021 15:09:04 +1100 Subject: [PATCH 315/644] Revise conditions under which players use spinheight and enter gaps: - players with SF_NOJUMPDAMAGE but *not* SF_NOJUMPSPIN now always use spinheight while jumping (i.e. even with PF_NOJUMPDAMAGE), as long as their panim is PA_JUMP or PA_ROLL - players with SF_NOJUMPSPIN no longer use spinheight while jumping (but,) - PA_ROLL is now an acceptable condition for using spinheight (but not for entering gaps, e.g. S3K shields will shrink the hitbox but not allow gap entry on their own) - flying players now only use spinheight if they do not have SF_NOJUMPSPIN (you're welcome, EggpackRE) - players with neither SF_NOJUMPSPIN nor SF_NOJUMPDAMAGE use the same conditions as in 2.2.9 prerelease, i.e. use spinheight and can enter gaps unless they have PF_NOJUMPDAMAGE --- src/p_user.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 38f13f8fd..63942e0be 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -12949,11 +12949,18 @@ boolean P_PlayerFullbright(player_t *player) && player->mo->state < &states[S_PLAY_NIGHTS_TRANS6])))); // Note the < instead of <= } +#define JUMPCURLED(player) ((player->pflags & PF_JUMPED)\ + && (!(player->charflags & SF_NOJUMPSPIN))\ + && (!(player->pflags & PF_NOJUMPDAMAGE)\ + || ((player->charflags & SF_NOJUMPDAMAGE)\ + && (player->panim == PA_JUMP || player->panim == PA_ROLL))))\ + // returns true if the player can enter a sector that they could not if standing at their skin's full height boolean P_PlayerCanEnterSpinGaps(player_t *player) { - return ((player->pflags & (PF_SPINNING|PF_GLIDING)) - || (player->charability == CA_GLIDEANDCLIMB && player->mo->state-states == S_PLAY_GLIDE_LANDING)); + return ((player->pflags & (PF_SPINNING|PF_GLIDING)) // players who are spinning or gliding + || (player->charability == CA_GLIDEANDCLIMB && player->mo->state-states == S_PLAY_GLIDE_LANDING) // players who are landing from a glide + || JUMPCURLED(player)); // players who are jumpcurled, but only if they would normally jump that way } // returns true if the player should use their skin's spinheight instead of their skin's height @@ -12961,7 +12968,7 @@ boolean P_PlayerShouldUseSpinHeight(player_t *player) { return (P_PlayerCanEnterSpinGaps(player) || (player->mo->state == &states[player->mo->info->painstate]) - || ((player->pflags & PF_JUMPED) && !(player->pflags & PF_NOJUMPDAMAGE)) - || player->powers[pw_tailsfly] - || (player->charability == CA_FLY && player->mo->state-states == S_PLAY_FLY_TIRED)); + || (player->panim == PA_ROLL) + || ((player->powers[pw_tailsfly] || (player->charability == CA_FLY && player->mo->state-states == S_PLAY_FLY_TIRED)) + && !(player->charflags & SF_NOJUMPSPIN))); } From b1a926288961fceda7cab4205fed66a706500726 Mon Sep 17 00:00:00 2001 From: lachablock Date: Thu, 25 Mar 2021 15:25:35 +1100 Subject: [PATCH 316/644] Fix P_PlayerCanEnterGaps issues with polyobject collision --- src/p_map.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index 7eec0937c..bf668ba3e 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1955,12 +1955,6 @@ static boolean PIT_CheckLine(line_t *ld) // set openrange, opentop, openbottom P_LineOpening(ld, tmthing); - // players should not always cross into sectors that they could not at full height - if (tmthing->player - && openrange < P_GetPlayerHeight(tmthing->player) - && !P_PlayerCanEnterSpinGaps(tmthing->player)) - return false; - // adjust floor / ceiling heights if (opentop < tmceilingz) { @@ -2729,7 +2723,10 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) if (thing->type == MT_SKIM) maxstep = 0; - if (tmceilingz - tmfloorz < thing->height) + if (tmceilingz - tmfloorz < thing->height + || (thing->player + && tmceilingz - tmfloorz < P_GetPlayerHeight(thing->player) + && !P_PlayerCanEnterSpinGaps(thing->player))) { if (tmfloorthing) tmhitthing = tmfloorthing; From 6ea96536810cc8ad95708436a4f5afd03be3154f Mon Sep 17 00:00:00 2001 From: lachablock Date: Thu, 25 Mar 2021 21:41:09 +1100 Subject: [PATCH 317/644] Add PlayerHeight and PlayerCanEnterSpinGaps Lua hooks --- src/lua_hook.h | 4 +++ src/lua_hooklib.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++ src/p_user.c | 21 +++++++++-- 3 files changed, 112 insertions(+), 3 deletions(-) diff --git a/src/lua_hook.h b/src/lua_hook.h index 5cfcb8360..0d631aa4e 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -61,6 +61,8 @@ enum hook { hook_GameQuit, hook_PlayerCmd, hook_MusicChange, + hook_PlayerHeight, + hook_PlayerCanEnterSpinGaps, hook_MAX // last hook }; @@ -118,3 +120,5 @@ boolean LUAh_ShouldJingleContinue(player_t *player, const char *musname); // Hoo void LUAh_GameQuit(boolean quitting); // Hook for game quitting boolean LUAh_PlayerCmd(player_t *player, ticcmd_t *cmd); // Hook for building player's ticcmd struct (Ported from SRB2Kart) boolean LUAh_MusicChange(const char *oldname, char *newname, UINT16 *mflags, boolean *looping, UINT32 *position, UINT32 *prefadems, UINT32 *fadeinms); // Hook for music changes +fixed_t LUAh_PlayerHeight(player_t *player); +UINT8 LUAh_PlayerCanEnterSpinGaps(player_t *player); diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 29c15a4de..6e9b9d65c 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -77,6 +77,8 @@ const char *const hookNames[hook_MAX+1] = { "GameQuit", "PlayerCmd", "MusicChange", + "PlayerHeight", + "PlayerCanEnterSpinGaps", NULL }; @@ -221,6 +223,8 @@ static int lib_addHook(lua_State *L) case hook_ShieldSpawn: case hook_ShieldSpecial: case hook_PlayerThink: + case hook_PlayerHeight: + case hook_PlayerCanEnterSpinGaps: lastp = &playerhooks; break; case hook_LinedefExecute: @@ -1971,3 +1975,89 @@ boolean LUAh_MusicChange(const char *oldname, char *newname, UINT16 *mflags, boo newname[6] = 0; return hooked; } + +// Hook for determining player height +fixed_t LUAh_PlayerHeight(player_t *player) +{ + hook_p hookp; + fixed_t newheight = -1; + if (!gL || !(hooksAvailable[hook_PlayerHeight/8] & (1<<(hook_PlayerHeight%8)))) + return 0; + + lua_settop(gL, 0); + lua_pushcfunction(gL, LUA_GetErrorMessage); + + for (hookp = playerhooks; hookp; hookp = hookp->next) + { + if (hookp->type != hook_PlayerHeight) + continue; + + ps_lua_mobjhooks++; + if (lua_gettop(gL) == 1) + LUA_PushUserdata(gL, player, META_PLAYER); + PushHook(gL, hookp); + lua_pushvalue(gL, -2); + if (lua_pcall(gL, 1, 1, 1)) { + if (!hookp->error || cv_debug & DBG_LUA) + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + hookp->error = true; + continue; + } + if (!lua_isnil(gL, -1)) + { + fixed_t returnedheight = lua_tonumber(gL, -1); + // 0 height has... strange results, but it's not problematic like negative heights are. + // when an object's height is set to a negative number directly with lua, it's forced to 0 instead. + // here, I think it's better to ignore negatives so that they don't replace any results of previous hooks! + if (returnedheight >= 0) + newheight = returnedheight; + } + lua_pop(gL, 1); + } + + lua_settop(gL, 0); + return newheight; +} + +// Hook for determining whether players are allowed passage through spin gaps +UINT8 LUAh_PlayerCanEnterSpinGaps(player_t *player) +{ + hook_p hookp; + UINT8 canEnter = 0; // 0 = default, 1 = force yes, 2 = force no. + if (!gL || !(hooksAvailable[hook_PlayerCanEnterSpinGaps/8] & (1<<(hook_PlayerCanEnterSpinGaps%8)))) + return 0; + + lua_settop(gL, 0); + lua_pushcfunction(gL, LUA_GetErrorMessage); + + for (hookp = playerhooks; hookp; hookp = hookp->next) + { + if (hookp->type != hook_PlayerCanEnterSpinGaps) + continue; + + ps_lua_mobjhooks++; + if (lua_gettop(gL) == 1) + LUA_PushUserdata(gL, player, META_PLAYER); + PushHook(gL, hookp); + lua_pushvalue(gL, -2); + if (lua_pcall(gL, 1, 1, 1)) { + if (!hookp->error || cv_debug & DBG_LUA) + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + hookp->error = true; + continue; + } + if (!lua_isnil(gL, -1)) + { // if nil, leave canEnter = 0. + if (lua_toboolean(gL, -1)) + canEnter = 1; // Force yes + else + canEnter = 2; // Force no + } + lua_pop(gL, 1); + } + + lua_settop(gL, 0); + return canEnter; +} diff --git a/src/p_user.c b/src/p_user.c index 63942e0be..56767f433 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8651,9 +8651,16 @@ void P_MovePlayer(player_t *player) { boolean atspinheight = false; fixed_t oldheight = player->mo->height; + fixed_t luaheight = LUAh_PlayerHeight(player); + if (luaheight != -1) + { + player->mo->height = luaheight; + if (luaheight <= P_GetPlayerSpinHeight(player)) + atspinheight = true; // spinning will not save you from being crushed + } // Less height while spinning. Good for spinning under things...? - if (P_PlayerShouldUseSpinHeight(player)) + else if (P_PlayerShouldUseSpinHeight(player)) { player->mo->height = P_GetPlayerSpinHeight(player); atspinheight = true; @@ -12958,6 +12965,12 @@ boolean P_PlayerFullbright(player_t *player) // returns true if the player can enter a sector that they could not if standing at their skin's full height boolean P_PlayerCanEnterSpinGaps(player_t *player) { + UINT8 canEnter = LUAh_PlayerCanEnterSpinGaps(player); + if (canEnter == 1) + return true; + else if (canEnter == 2) + return false; + return ((player->pflags & (PF_SPINNING|PF_GLIDING)) // players who are spinning or gliding || (player->charability == CA_GLIDEANDCLIMB && player->mo->state-states == S_PLAY_GLIDE_LANDING) // players who are landing from a glide || JUMPCURLED(player)); // players who are jumpcurled, but only if they would normally jump that way @@ -12966,9 +12979,11 @@ boolean P_PlayerCanEnterSpinGaps(player_t *player) // returns true if the player should use their skin's spinheight instead of their skin's height boolean P_PlayerShouldUseSpinHeight(player_t *player) { - return (P_PlayerCanEnterSpinGaps(player) + return ((player->pflags & (PF_SPINNING|PF_GLIDING)) || (player->mo->state == &states[player->mo->info->painstate]) || (player->panim == PA_ROLL) || ((player->powers[pw_tailsfly] || (player->charability == CA_FLY && player->mo->state-states == S_PLAY_FLY_TIRED)) - && !(player->charflags & SF_NOJUMPSPIN))); + && !(player->charflags & SF_NOJUMPSPIN)) + || (player->charability == CA_GLIDEANDCLIMB && player->mo->state-states == S_PLAY_GLIDE_LANDING) + || JUMPCURLED(player)); } From 000e865f80f3e4f7e77184cc140eaf0dabb1c09b Mon Sep 17 00:00:00 2001 From: lachablock Date: Thu, 25 Mar 2021 21:42:25 +1100 Subject: [PATCH 318/644] Revise spinheight/gap entry conditions (again), let's keep things WAY simpler: - PF_NOJUMPDAMAGE no longer affects height at all (you're welcome katsy). - Characters with SF_NOJUMPSPIN will only use spinheight when panim is PA_ROLL. They cannot enter gaps when jumping with spinheight, unless also spinning or gliding. - All other characters use spinheight when panim is PA_JUMP or PA_ROLL. They can enter gaps when jumping with spinheight. --- src/p_user.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 56767f433..6c7cdb0d0 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -12958,9 +12958,7 @@ boolean P_PlayerFullbright(player_t *player) #define JUMPCURLED(player) ((player->pflags & PF_JUMPED)\ && (!(player->charflags & SF_NOJUMPSPIN))\ - && (!(player->pflags & PF_NOJUMPDAMAGE)\ - || ((player->charflags & SF_NOJUMPDAMAGE)\ - && (player->panim == PA_JUMP || player->panim == PA_ROLL))))\ + && (player->panim == PA_JUMP || player->panim == PA_ROLL))\ // returns true if the player can enter a sector that they could not if standing at their skin's full height boolean P_PlayerCanEnterSpinGaps(player_t *player) From 6267abac8add71a70409fd9987630c44fc56befd Mon Sep 17 00:00:00 2001 From: SwitchKaze Date: Thu, 25 Mar 2021 12:43:30 -0500 Subject: [PATCH 319/644] Fix console text bleeding --- src/console.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/console.c b/src/console.c index f3b0aa603..2d95e10b8 100644 --- a/src/console.c +++ b/src/console.c @@ -1652,6 +1652,7 @@ static void CON_DrawHudlines(void) { charflags = (*p & 0x7f) << V_CHARCOLORSHIFT; p++; + c++; } if (*p < HU_FONTSTART) ;//charwidth = 4 * con_scalefactor; @@ -1774,6 +1775,7 @@ static void CON_DrawConsole(void) { charflags = (*p & 0x7f) << V_CHARCOLORSHIFT; p++; + c++; } V_DrawCharacter(x, y, (INT32)(*p) | charflags | cv_constextsize.value | V_NOSCALESTART, true); } From b6e5837161e29191e9ce16f2f08e760b45030acb Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Thu, 25 Mar 2021 22:28:07 +0100 Subject: [PATCH 320/644] Use a separate transfer status for disconnected nodes --- src/d_netfil.c | 16 +++++++++------- src/d_netfil.h | 5 +++-- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/d_netfil.c b/src/d_netfil.c index 8f661bb5f..e15c15bd5 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -562,7 +562,7 @@ static void SV_PrepareSendLuaFileToNextNode(void) // Find a client to send the file to for (i = 1; i < MAXNETNODES; i++) - if (nodeingame[i] && luafiletransfers->nodestatus[i] == LFTNS_WAITING) // Node waiting + if (luafiletransfers->nodestatus[i] == LFTNS_WAITING) // Node waiting { // Tell the client we're about to send them the file netbuffer->packettype = PT_SENDINGLUAFILE; @@ -588,7 +588,7 @@ void SV_PrepareSendLuaFile(void) // Set status to "waiting" for everyone for (i = 0; i < MAXNETNODES; i++) - luafiletransfers->nodestatus[i] = LFTNS_WAITING; + luafiletransfers->nodestatus[i] = (nodeingame[i] ? LFTNS_WAITING : LFTNS_NONE); if (FIL_ReadFileOK(luafiletransfers->realfilename)) { @@ -649,12 +649,14 @@ void RemoveAllLuaFileTransfers(void) void SV_AbortLuaFileTransfer(INT32 node) { - if (luafiletransfers - && (luafiletransfers->nodestatus[node] == LFTNS_ASKED - || luafiletransfers->nodestatus[node] == LFTNS_SENDING)) + if (luafiletransfers) { - luafiletransfers->nodestatus[node] = LFTNS_WAITING; - SV_PrepareSendLuaFileToNextNode(); + if (luafiletransfers->nodestatus[node] == LFTNS_ASKED + || luafiletransfers->nodestatus[node] == LFTNS_SENDING) + { + SV_PrepareSendLuaFileToNextNode(); + } + luafiletransfers->nodestatus[node] = LFTNS_NONE; } } diff --git a/src/d_netfil.h b/src/d_netfil.h index 1b399be75..2e656e0f6 100644 --- a/src/d_netfil.h +++ b/src/d_netfil.h @@ -85,10 +85,11 @@ boolean PT_RequestFile(INT32 node); typedef enum { + LFTNS_NONE, // This node is not connected LFTNS_WAITING, // This node is waiting for the server to send the file - LFTNS_ASKED, // The server has told the node they're ready to send the file + LFTNS_ASKED, // The server has told the node they're ready to send the file LFTNS_SENDING, // The server is sending the file to this node - LFTNS_SENT // The node already has the file + LFTNS_SENT // The node already has the file } luafiletransfernodestatus_t; typedef struct luafiletransfer_s From 854e43ea7c7cf3b3eb81e7388958f6546ce28ab6 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Thu, 25 Mar 2021 22:28:07 +0100 Subject: [PATCH 321/644] Kick clients if they take too long to download a Lua file --- src/d_netfil.c | 17 +++++++++++++++++ src/d_netfil.h | 1 + 2 files changed, 18 insertions(+) diff --git a/src/d_netfil.c b/src/d_netfil.c index e15c15bd5..50dc2ba60 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -570,6 +570,7 @@ static void SV_PrepareSendLuaFileToNextNode(void) I_Error("Failed to send a PT_SENDINGLUAFILE packet\n"); // !!! Todo: Handle failure a bit better lol luafiletransfers->nodestatus[i] = LFTNS_ASKED; + luafiletransfers->nodetimeouts[i] = I_GetTime() + 30 * TICRATE; return; } @@ -930,6 +931,22 @@ void FileSendTicker(void) filetx_t *f; INT32 packetsent, ram, i, j; + // If someone is taking too long to download, kick them with a timeout + // to prevent blocking the rest of the server... + if (luafiletransfers) + { + for (i = 1; i < MAXNETNODES; i++) + { + luafiletransfernodestatus_t status = luafiletransfers->nodestatus[i]; + + if (status != LFTNS_NONE && status != LFTNS_WAITING && status != LFTNS_SENT + && I_GetTime() > luafiletransfers->nodetimeouts[i]) + { + Net_ConnectionTimeout(i); + } + } + } + if (!filestosend) // No file to send return; diff --git a/src/d_netfil.h b/src/d_netfil.h index 2e656e0f6..158149477 100644 --- a/src/d_netfil.h +++ b/src/d_netfil.h @@ -100,6 +100,7 @@ typedef struct luafiletransfer_s INT32 id; // Callback ID boolean ongoing; luafiletransfernodestatus_t nodestatus[MAXNETNODES]; + tic_t nodetimeouts[MAXNETNODES]; struct luafiletransfer_s *next; } luafiletransfer_t; From 8162d90c9427dea87223133048998d42afc7d032 Mon Sep 17 00:00:00 2001 From: lachablock Date: Fri, 26 Mar 2021 18:01:55 +1100 Subject: [PATCH 322/644] Fix LUAh_PlayerHeight returning wrong default value --- src/lua_hooklib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 6e9b9d65c..637809fd8 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -1982,7 +1982,7 @@ fixed_t LUAh_PlayerHeight(player_t *player) hook_p hookp; fixed_t newheight = -1; if (!gL || !(hooksAvailable[hook_PlayerHeight/8] & (1<<(hook_PlayerHeight%8)))) - return 0; + return newheight; lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); From 55d63000f4eb4de8cfcd533d6e1d3c46f0db5306 Mon Sep 17 00:00:00 2001 From: katsy Date: Sat, 27 Mar 2021 18:30:59 -0500 Subject: [PATCH 323/644] don't HWR_ClearAllTextures() in software --- src/p_setup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 41d8822e2..28ea613d5 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -4135,7 +4135,7 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate) #ifdef HWRENDER // Free GPU textures before freeing patches. - if (vid.glstate == VID_GL_LIBRARY_LOADED) + if (rendermode == render_opengl && (vid.glstate == VID_GL_LIBRARY_LOADED)) HWR_ClearAllTextures(); #endif @@ -4500,7 +4500,7 @@ boolean P_AddWadFile(const char *wadfilename) #ifdef HWRENDER // Free GPU textures before freeing patches. - if (vid.glstate == VID_GL_LIBRARY_LOADED) + if (rendermode == render_opengl && (vid.glstate == VID_GL_LIBRARY_LOADED)) HWR_ClearAllTextures(); #endif From d6eaf7e0ff479a1c6ae907779c47877e3abc88e3 Mon Sep 17 00:00:00 2001 From: katsy Date: Sun, 28 Mar 2021 12:22:04 -0500 Subject: [PATCH 324/644] clear before switching, not after --- src/screen.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/screen.c b/src/screen.c index 9d36eee39..02de884bf 100644 --- a/src/screen.c +++ b/src/screen.c @@ -33,6 +33,11 @@ #include "s_sound.h" // ditto #include "g_game.h" // ditto #include "p_local.h" // P_AutoPause() +#ifdef HWRENDER +#include "hardware/hw_main.h" +#include "hardware/hw_light.h" +#include "hardware/hw_model.h" +#endif #if defined (USEASM) && !defined (NORUSEASM)//&& (!defined (_MSC_VER) || (_MSC_VER <= 1200)) @@ -423,6 +428,10 @@ void SCR_ChangeRenderer(void) CONS_Alert(CONS_ERROR, "OpenGL never loaded\n"); return; } + + if (rendermode == render_opengl && (vid.glstate == VID_GL_LIBRARY_LOADED)) // Clear these out before switching to software + HWR_ClearAllTextures(); + #endif // Set the new render mode From 428ae3127e76753aa47c79b07867560bf9145c60 Mon Sep 17 00:00:00 2001 From: Mari0shi06 Date: Sun, 28 Mar 2021 17:12:58 -0400 Subject: [PATCH 325/644] Change Raspberry's chat colormap to V_ROSYMAP --- src/info.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/info.c b/src/info.c index ee836a372..19a477e5b 100644 --- a/src/info.c +++ b/src/info.c @@ -21761,7 +21761,7 @@ skincolor_t skincolors[MAXSKINCOLORS] = { {"Violet", {0xd0, 0xd1, 0xd2, 0xca, 0xcc, 0xb8, 0xb9, 0xb9, 0xba, 0xa8, 0xa8, 0xa9, 0xa9, 0xfd, 0xfe, 0xfe}, SKINCOLOR_MINT, 6, V_MAGENTAMAP, true}, // SKINCOLOR_VIOLET {"Lilac", {0x00, 0xd0, 0xd1, 0xd2, 0xd3, 0xc1, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc5, 0xc6, 0xc6, 0xfe, 0x1f}, SKINCOLOR_VAPOR, 4, V_ROSYMAP, true}, // SKINCOLOR_LILAC {"Plum", {0xc8, 0xd3, 0xd5, 0xd6, 0xd7, 0xce, 0xcf, 0xb9, 0xb9, 0xba, 0xba, 0xa9, 0xa9, 0xa9, 0xfd, 0xfe}, SKINCOLOR_MINT, 7, V_ROSYMAP, true}, // SKINCOLOR_PLUM - {"Raspberry", {0xc8, 0xc9, 0xca, 0xcb, 0xcb, 0xcc, 0xcd, 0xcd, 0xce, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xfe, 0xfe}, SKINCOLOR_APPLE, 13, V_MAGENTAMAP, true}, // SKINCOLOR_RASPBERRY + {"Raspberry", {0xc8, 0xc9, 0xca, 0xcb, 0xcb, 0xcc, 0xcd, 0xcd, 0xce, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xfe, 0xfe}, SKINCOLOR_APPLE, 13, V_ROSYMAP, true}, // SKINCOLOR_RASPBERRY {"Rosy", {0xfc, 0xc8, 0xc8, 0xc9, 0xc9, 0xca, 0xca, 0xcb, 0xcb, 0xcc, 0xcc, 0xcd, 0xcd, 0xce, 0xce, 0xcf}, SKINCOLOR_AQUA, 1, V_ROSYMAP, true}, // SKINCOLOR_ROSY // super From 424f67a74b5aff5083c174a81a21664a1a63e6dc Mon Sep 17 00:00:00 2001 From: Mari0shi06 Date: Sun, 28 Mar 2021 21:19:26 +0000 Subject: [PATCH 326/644] Revert "Change Raspberry's chat colormap to V_ROSYMAP" This reverts commit 428ae3127e76753aa47c79b07867560bf9145c60 --- src/info.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/info.c b/src/info.c index 19a477e5b..ee836a372 100644 --- a/src/info.c +++ b/src/info.c @@ -21761,7 +21761,7 @@ skincolor_t skincolors[MAXSKINCOLORS] = { {"Violet", {0xd0, 0xd1, 0xd2, 0xca, 0xcc, 0xb8, 0xb9, 0xb9, 0xba, 0xa8, 0xa8, 0xa9, 0xa9, 0xfd, 0xfe, 0xfe}, SKINCOLOR_MINT, 6, V_MAGENTAMAP, true}, // SKINCOLOR_VIOLET {"Lilac", {0x00, 0xd0, 0xd1, 0xd2, 0xd3, 0xc1, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc5, 0xc6, 0xc6, 0xfe, 0x1f}, SKINCOLOR_VAPOR, 4, V_ROSYMAP, true}, // SKINCOLOR_LILAC {"Plum", {0xc8, 0xd3, 0xd5, 0xd6, 0xd7, 0xce, 0xcf, 0xb9, 0xb9, 0xba, 0xba, 0xa9, 0xa9, 0xa9, 0xfd, 0xfe}, SKINCOLOR_MINT, 7, V_ROSYMAP, true}, // SKINCOLOR_PLUM - {"Raspberry", {0xc8, 0xc9, 0xca, 0xcb, 0xcb, 0xcc, 0xcd, 0xcd, 0xce, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xfe, 0xfe}, SKINCOLOR_APPLE, 13, V_ROSYMAP, true}, // SKINCOLOR_RASPBERRY + {"Raspberry", {0xc8, 0xc9, 0xca, 0xcb, 0xcb, 0xcc, 0xcd, 0xcd, 0xce, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xfe, 0xfe}, SKINCOLOR_APPLE, 13, V_MAGENTAMAP, true}, // SKINCOLOR_RASPBERRY {"Rosy", {0xfc, 0xc8, 0xc8, 0xc9, 0xc9, 0xca, 0xca, 0xcb, 0xcb, 0xcc, 0xcc, 0xcd, 0xcd, 0xce, 0xce, 0xcf}, SKINCOLOR_AQUA, 1, V_ROSYMAP, true}, // SKINCOLOR_ROSY // super From 192fa5cb4b2d13ac6e1a026c3a190cece32201fc Mon Sep 17 00:00:00 2001 From: Mari0shi06 Date: Sun, 28 Mar 2021 17:26:41 -0400 Subject: [PATCH 327/644] Change Raspberry's chat color to V_ROSYMAP --- src/info.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/info.c b/src/info.c index ee836a372..2b577c07e 100644 --- a/src/info.c +++ b/src/info.c @@ -21761,7 +21761,7 @@ skincolor_t skincolors[MAXSKINCOLORS] = { {"Violet", {0xd0, 0xd1, 0xd2, 0xca, 0xcc, 0xb8, 0xb9, 0xb9, 0xba, 0xa8, 0xa8, 0xa9, 0xa9, 0xfd, 0xfe, 0xfe}, SKINCOLOR_MINT, 6, V_MAGENTAMAP, true}, // SKINCOLOR_VIOLET {"Lilac", {0x00, 0xd0, 0xd1, 0xd2, 0xd3, 0xc1, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc5, 0xc6, 0xc6, 0xfe, 0x1f}, SKINCOLOR_VAPOR, 4, V_ROSYMAP, true}, // SKINCOLOR_LILAC {"Plum", {0xc8, 0xd3, 0xd5, 0xd6, 0xd7, 0xce, 0xcf, 0xb9, 0xb9, 0xba, 0xba, 0xa9, 0xa9, 0xa9, 0xfd, 0xfe}, SKINCOLOR_MINT, 7, V_ROSYMAP, true}, // SKINCOLOR_PLUM - {"Raspberry", {0xc8, 0xc9, 0xca, 0xcb, 0xcb, 0xcc, 0xcd, 0xcd, 0xce, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xfe, 0xfe}, SKINCOLOR_APPLE, 13, V_MAGENTAMAP, true}, // SKINCOLOR_RASPBERRY + {"Raspberry", {0xc8, 0xc9, 0xca, 0xcb, 0xcb, 0xcc, 0xcd, 0xcd, 0xce, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xfe, 0xfe}, SKINCOLOR_APPLE, 13, V_ROSYMAP, true}, // SKINCOLOR_RASPBERRY {"Rosy", {0xfc, 0xc8, 0xc8, 0xc9, 0xc9, 0xca, 0xca, 0xcb, 0xcb, 0xcc, 0xcc, 0xcd, 0xcd, 0xce, 0xce, 0xcf}, SKINCOLOR_AQUA, 1, V_ROSYMAP, true}, // SKINCOLOR_ROSY // super From 715a3661b5e2cdc8ae3ef8dd5374427031d9da4b Mon Sep 17 00:00:00 2001 From: Mari0shi06 Date: Sun, 28 Mar 2021 21:27:46 +0000 Subject: [PATCH 328/644] Revert "Change Raspberry's chat color to V_ROSYMAP" This reverts commit 192fa5cb4b2d13ac6e1a026c3a190cece32201fc --- src/info.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/info.c b/src/info.c index 2b577c07e..ee836a372 100644 --- a/src/info.c +++ b/src/info.c @@ -21761,7 +21761,7 @@ skincolor_t skincolors[MAXSKINCOLORS] = { {"Violet", {0xd0, 0xd1, 0xd2, 0xca, 0xcc, 0xb8, 0xb9, 0xb9, 0xba, 0xa8, 0xa8, 0xa9, 0xa9, 0xfd, 0xfe, 0xfe}, SKINCOLOR_MINT, 6, V_MAGENTAMAP, true}, // SKINCOLOR_VIOLET {"Lilac", {0x00, 0xd0, 0xd1, 0xd2, 0xd3, 0xc1, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc5, 0xc6, 0xc6, 0xfe, 0x1f}, SKINCOLOR_VAPOR, 4, V_ROSYMAP, true}, // SKINCOLOR_LILAC {"Plum", {0xc8, 0xd3, 0xd5, 0xd6, 0xd7, 0xce, 0xcf, 0xb9, 0xb9, 0xba, 0xba, 0xa9, 0xa9, 0xa9, 0xfd, 0xfe}, SKINCOLOR_MINT, 7, V_ROSYMAP, true}, // SKINCOLOR_PLUM - {"Raspberry", {0xc8, 0xc9, 0xca, 0xcb, 0xcb, 0xcc, 0xcd, 0xcd, 0xce, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xfe, 0xfe}, SKINCOLOR_APPLE, 13, V_ROSYMAP, true}, // SKINCOLOR_RASPBERRY + {"Raspberry", {0xc8, 0xc9, 0xca, 0xcb, 0xcb, 0xcc, 0xcd, 0xcd, 0xce, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xfe, 0xfe}, SKINCOLOR_APPLE, 13, V_MAGENTAMAP, true}, // SKINCOLOR_RASPBERRY {"Rosy", {0xfc, 0xc8, 0xc8, 0xc9, 0xc9, 0xca, 0xca, 0xcb, 0xcb, 0xcc, 0xcc, 0xcd, 0xcd, 0xce, 0xce, 0xcf}, SKINCOLOR_AQUA, 1, V_ROSYMAP, true}, // SKINCOLOR_ROSY // super From 29704e141b9bc2b265a58f41a2ff1c7a293b3ad7 Mon Sep 17 00:00:00 2001 From: Mari0shi06 Date: Sun, 28 Mar 2021 17:29:24 -0400 Subject: [PATCH 329/644] Change Raspberry's chat colormap to V_ROSYMAP --- src/info.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/info.c b/src/info.c index ee836a372..2b577c07e 100644 --- a/src/info.c +++ b/src/info.c @@ -21761,7 +21761,7 @@ skincolor_t skincolors[MAXSKINCOLORS] = { {"Violet", {0xd0, 0xd1, 0xd2, 0xca, 0xcc, 0xb8, 0xb9, 0xb9, 0xba, 0xa8, 0xa8, 0xa9, 0xa9, 0xfd, 0xfe, 0xfe}, SKINCOLOR_MINT, 6, V_MAGENTAMAP, true}, // SKINCOLOR_VIOLET {"Lilac", {0x00, 0xd0, 0xd1, 0xd2, 0xd3, 0xc1, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc5, 0xc6, 0xc6, 0xfe, 0x1f}, SKINCOLOR_VAPOR, 4, V_ROSYMAP, true}, // SKINCOLOR_LILAC {"Plum", {0xc8, 0xd3, 0xd5, 0xd6, 0xd7, 0xce, 0xcf, 0xb9, 0xb9, 0xba, 0xba, 0xa9, 0xa9, 0xa9, 0xfd, 0xfe}, SKINCOLOR_MINT, 7, V_ROSYMAP, true}, // SKINCOLOR_PLUM - {"Raspberry", {0xc8, 0xc9, 0xca, 0xcb, 0xcb, 0xcc, 0xcd, 0xcd, 0xce, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xfe, 0xfe}, SKINCOLOR_APPLE, 13, V_MAGENTAMAP, true}, // SKINCOLOR_RASPBERRY + {"Raspberry", {0xc8, 0xc9, 0xca, 0xcb, 0xcb, 0xcc, 0xcd, 0xcd, 0xce, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xfe, 0xfe}, SKINCOLOR_APPLE, 13, V_ROSYMAP, true}, // SKINCOLOR_RASPBERRY {"Rosy", {0xfc, 0xc8, 0xc8, 0xc9, 0xc9, 0xca, 0xca, 0xcb, 0xcb, 0xcc, 0xcc, 0xcd, 0xcd, 0xce, 0xce, 0xcf}, SKINCOLOR_AQUA, 1, V_ROSYMAP, true}, // SKINCOLOR_ROSY // super From 4025a1d5177b2b9b9d9c535a19d0b2c1324a35de Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Mon, 29 Mar 2021 23:04:13 -0300 Subject: [PATCH 330/644] [Software] A few floorsprite fixes This fixes the texture of the floorsprite sometimes facing the wrong way, since plane rendering can change the view angle. --- src/r_data.c | 6 +----- src/r_draw8.c | 12 +----------- src/r_plane.c | 13 +++---------- src/r_splats.c | 27 +++++++++++---------------- src/r_splats.h | 3 +-- src/r_textures.c | 9 ++------- src/r_things.c | 5 +++-- src/r_things.h | 1 + 8 files changed, 23 insertions(+), 53 deletions(-) diff --git a/src/r_data.c b/src/r_data.c index af672f6dc..2cfe9cb7a 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -30,10 +30,6 @@ #include "byteptr.h" #include "dehacked.h" -#ifdef _WIN32 -#include // alloca(sizeof) -#endif - // // Graphics. // SRB2 graphics for walls and sprites diff --git a/src/r_draw8.c b/src/r_draw8.c index e78ba8a6c..1f451115e 100644 --- a/src/r_draw8.c +++ b/src/r_draw8.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -1447,10 +1447,7 @@ void R_DrawFloorSprite_8 (void) // SoM: Why didn't I see this earlier? the spot variable is a waste now because we don't // have the uber complicated math to calculate it now, so that was a memory write we didn't // need! - // - // 4194303 = (2048x2048)-1 (2048x2048 is maximum flat size) val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); - val &= 4194303; val = source[val]; if (val & 0xFF00) dest[0] = colormap[translation[val & 0xFF]]; @@ -1458,7 +1455,6 @@ void R_DrawFloorSprite_8 (void) yposition += ystep; val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); - val &= 4194303; val = source[val]; if (val & 0xFF00) dest[1] = colormap[translation[val & 0xFF]]; @@ -1466,7 +1462,6 @@ void R_DrawFloorSprite_8 (void) yposition += ystep; val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); - val &= 4194303; val = source[val]; if (val & 0xFF00) dest[2] = colormap[translation[val & 0xFF]]; @@ -1474,7 +1469,6 @@ void R_DrawFloorSprite_8 (void) yposition += ystep; val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); - val &= 4194303; val = source[val]; if (val & 0xFF00) dest[3] = colormap[translation[val & 0xFF]]; @@ -1482,7 +1476,6 @@ void R_DrawFloorSprite_8 (void) yposition += ystep; val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); - val &= 4194303; val = source[val]; if (val & 0xFF00) dest[4] = colormap[translation[val & 0xFF]]; @@ -1490,7 +1483,6 @@ void R_DrawFloorSprite_8 (void) yposition += ystep; val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); - val &= 4194303; val = source[val]; if (val & 0xFF00) dest[5] = colormap[translation[val & 0xFF]]; @@ -1498,7 +1490,6 @@ void R_DrawFloorSprite_8 (void) yposition += ystep; val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); - val &= 4194303; val = source[val]; if (val & 0xFF00) dest[6] = colormap[translation[val & 0xFF]]; @@ -1506,7 +1497,6 @@ void R_DrawFloorSprite_8 (void) yposition += ystep; val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); - val &= 4194303; val = source[val]; if (val & 0xFF00) dest[7] = colormap[translation[val & 0xFF]]; diff --git a/src/r_plane.c b/src/r_plane.c index 45d635213..ea4dfa4e8 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -154,14 +154,10 @@ static void R_UpdatePlaneRipple(void) // R_MapPlane // // Uses global vars: +// planeheight // basexscale // baseyscale // centerx -// viewx -// viewy -// viewsin -// viewcos -// viewheight void R_MapPlane(INT32 y, INT32 x1, INT32 x2) { @@ -580,7 +576,7 @@ void R_ExpandPlane(visplane_t *pl, INT32 start, INT32 stop) // void R_MakeSpans(INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2) { - // Alam: from r_splats's R_RenderFloorSplat + // Alam: from r_splats's R_RasterizeFloorSplat if (t1 >= vid.height) t1 = vid.height-1; if (b1 >= vid.height) b1 = vid.height-1; if (t2 >= vid.height) t2 = vid.height-1; @@ -607,7 +603,6 @@ void R_MakeSpans(INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2) void R_DrawPlanes(void) { visplane_t *pl; - angle_t va = viewangle; INT32 i; R_UpdatePlaneRipple(); @@ -622,8 +617,6 @@ void R_DrawPlanes(void) R_DrawSinglePlane(pl); } } - - viewangle = va; } // R_DrawSkyPlane diff --git a/src/r_splats.c b/src/r_splats.c index a3fad82d8..72cac9fd9 100644 --- a/src/r_splats.c +++ b/src/r_splats.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -28,11 +28,12 @@ static void prepare_rastertab(void); // FLOOR SPLATS // ========================================================================== +static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, vissprite_t *vis); + #ifdef USEASM void ASMCALL rasterize_segment_tex_asm(INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT32 tv1, INT32 tv2, INT32 tc, INT32 dir); #endif -// Lactozilla static void rasterize_segment_tex(INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT32 tv1, INT32 tv2, INT32 tc, INT32 dir) { #ifdef USEASM @@ -137,7 +138,7 @@ static void rasterize_segment_tex(INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT32 } } -void R_DrawFloorSprite(vissprite_t *spr) +void R_DrawFloorSplat(vissprite_t *spr) { floorsplat_t splat; mobj_t *mobj = spr->mobj; @@ -187,7 +188,7 @@ void R_DrawFloorSprite(vissprite_t *spr) if (spr->rotateflags & SRF_3D || renderflags & RF_NOSPLATBILLBOARD) splatangle = mobj->angle; else - splatangle = viewangle; + splatangle = spr->viewangle; if (!(spr->cut & SC_ISROTATED)) splatangle += mobj->rollangle; @@ -265,7 +266,6 @@ void R_DrawFloorSprite(vissprite_t *spr) if (splat.tilted) { - // Lactozilla: Just copy the entire slope LMFAOOOO pslope_t *s = &splat.slope; s->o.x = slope->o.x; @@ -330,7 +330,7 @@ void R_DrawFloorSprite(vissprite_t *spr) v2d[i].y = (centeryfrac + FixedMul(rot_z, yscale))>>FRACBITS; } - R_RenderFloorSplat(&splat, v2d, spr); + R_RasterizeFloorSplat(&splat, v2d, spr); } // -------------------------------------------------------------------------- @@ -338,7 +338,7 @@ void R_DrawFloorSprite(vissprite_t *spr) // fill the polygon with linear interpolation, call span drawer for each // scan line // -------------------------------------------------------------------------- -void R_RenderFloorSplat(floorsplat_t *pSplat, vector2_t *verts, vissprite_t *vis) +static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, vissprite_t *vis) { // rasterizing INT32 miny = viewheight + 1, maxy = 0; @@ -416,11 +416,10 @@ void R_RenderFloorSplat(floorsplat_t *pSplat, vector2_t *verts, vissprite_t *vis if (R_CheckPowersOfTwo()) R_CheckFlatLength(ds_flatwidth * ds_flatheight); - // Lactozilla: I don't know what I'm doing if (pSplat->tilted) { R_SetTiltedSpan(0); - R_CalculateSlopeVectors(&pSplat->slope, viewx, viewy, viewz, pSplat->xscale, pSplat->yscale, -pSplat->verts[0].x, pSplat->verts[0].y, viewangle, pSplat->angle, 1.0f); + R_CalculateSlopeVectors(&pSplat->slope, viewx, viewy, viewz, pSplat->xscale, pSplat->yscale, -pSplat->verts[0].x, pSplat->verts[0].y, vis->viewangle, pSplat->angle, 1.0f); spanfunctype = SPANDRAWFUNC_TILTEDSPRITE; } else @@ -533,7 +532,7 @@ void R_RenderFloorSplat(floorsplat_t *pSplat, vector2_t *verts, vissprite_t *vis fixed_t xstep, ystep; fixed_t distance, span; - angle_t angle = (viewangle + pSplat->angle)>>ANGLETOFINESHIFT; + angle_t angle = (vis->viewangle + pSplat->angle)>>ANGLETOFINESHIFT; angle_t planecos = FINECOSINE(angle); angle_t planesin = FINESINE(angle); @@ -543,17 +542,13 @@ void R_RenderFloorSplat(floorsplat_t *pSplat, vector2_t *verts, vissprite_t *vis distance = cacheddistance[y] = FixedMul(planeheight, yslope[y]); span = abs(centery - y); - if (span) // don't divide by zero + if (span) // Don't divide by zero { xstep = FixedMul(planesin, planeheight) / span; ystep = FixedMul(planecos, planeheight) / span; } else - { - // ah - xstep = FRACUNIT; - ystep = FRACUNIT; - } + xstep = ystep = FRACUNIT; cachedxstep[y] = xstep; cachedystep[y] = ystep; diff --git a/src/r_splats.h b/src/r_splats.h index e1f836f48..05d8b66b0 100644 --- a/src/r_splats.h +++ b/src/r_splats.h @@ -42,7 +42,6 @@ typedef struct floorsplat_s mobj_t *mobj; // Mobj it is tied to } floorsplat_t; -void R_DrawFloorSprite(vissprite_t *spr); -void R_RenderFloorSplat(floorsplat_t *pSplat, vector2_t *verts, vissprite_t *vis); +void R_DrawFloorSplat(vissprite_t *spr); #endif /*__R_SPLATS_H__*/ diff --git a/src/r_textures.c b/src/r_textures.c index a006d739f..d5da69018 100644 --- a/src/r_textures.c +++ b/src/r_textures.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -28,11 +28,6 @@ #include "byteptr.h" #include "dehacked.h" -// I don't know what this is even for, but r_data.c had it. -#ifdef _WIN32 -#include // alloca(sizeof) -#endif - #ifdef HWRENDER #include "hardware/hw_glob.h" // HWR_LoadMapTextures #endif @@ -626,7 +621,7 @@ void *R_GetLevelFlat(levelflat_t *levelflat) // // R_CheckPowersOfTwo // -// Self-explanatory? +// Sets ds_powersoftwo true if the flat's dimensions are powers of two, and returns that. // boolean R_CheckPowersOfTwo(void) { diff --git a/src/r_things.c b/src/r_things.c index 14eed9cf2..98e7d00ca 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -1956,6 +1956,7 @@ static void R_ProjectSprite(mobj_t *thing) vis->paperoffset = paperoffset; vis->paperdistance = paperdistance; vis->centerangle = centerangle; + vis->viewangle = viewangle; vis->shear.tan = sheartan; vis->shear.offset = 0; @@ -2783,7 +2784,7 @@ static void R_DrawSprite(vissprite_t *spr) mceilingclip = spr->cliptop; if (spr->cut & SC_SPLAT) - R_DrawFloorSprite(spr); + R_DrawFloorSplat(spr); else R_DrawVisSprite(spr); } diff --git a/src/r_things.h b/src/r_things.h index 708b6c24c..95b4215af 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -164,6 +164,7 @@ typedef struct vissprite_s fixed_t xiscale; // negative if flipped angle_t centerangle; // for paper sprites + angle_t viewangle; // for floor sprites, the viewpoint's current angle struct { fixed_t tan; // The amount to shear the sprite vertically per row From 0d5284c36c2485d370c7fda604ad458e85cf0ec4 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 30 Mar 2021 19:27:10 +0100 Subject: [PATCH 331/644] Murder `MSDOS`, another of the remaining DOS port related macros I also put in a missing `defined (__APPLE__)` in d_netcmd.h related to cv_mouse2opt Also removed a redundant `!defined (__APPLE__)` in d_main.c --- src/d_main.c | 10 +++++----- src/d_netcmd.c | 6 +++--- src/d_netcmd.h | 2 +- src/doomdef.h | 4 ++-- src/doomtype.h | 2 +- src/i_tcp.c | 4 ++-- src/m_menu.c | 8 ++++---- src/sdl/i_system.c | 2 +- src/v_video.c | 4 ++-- 9 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 23a2c0133..cc02c5398 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -15,7 +15,7 @@ /// plus functions to parse command line parameters, configure game /// parameters, and call the startup functions. -#if (defined (__unix__) && !defined (MSDOS)) || defined(__APPLE__) || defined (UNIXCOMMON) +#if defined (__unix__) || defined (__APPLE__) || defined (UNIXCOMMON) #include #include #endif @@ -934,7 +934,7 @@ static void IdentifyVersion(void) char *srb2wad; const char *srb2waddir = NULL; -#if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL) +#if defined (__unix__) || defined (UNIXCOMMON) || defined (HAVE_SDL) // change to the directory where 'srb2.pk3' is found srb2waddir = I_LocateWad(); #endif @@ -1107,7 +1107,7 @@ void D_SRB2Main(void) if (!userhome) { -#if ((defined (__unix__) && !defined (MSDOS)) || defined(__APPLE__) || defined (UNIXCOMMON)) && !defined (__CYGWIN__) +#if (defined (__unix__) || defined (__APPLE__) || defined (UNIXCOMMON)) && !defined (__CYGWIN__) I_Error("Please set $HOME to your home directory\n"); #else if (dedicated) @@ -1287,7 +1287,7 @@ void D_SRB2Main(void) G_LoadGameData(); -#if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL) +#if defined (__unix__) || defined (UNIXCOMMON) || defined (HAVE_SDL) VID_PrepareModeList(); // Regenerate Modelist according to cv_fullscreen #endif @@ -1553,7 +1553,7 @@ const char *D_Home(void) userhome = M_GetNextParm(); else { -#if !((defined (__unix__) && !defined (MSDOS)) || defined(__APPLE__) || defined (UNIXCOMMON)) && !defined (__APPLE__) +#if !(defined (__unix__) || defined (__APPLE__) || defined (UNIXCOMMON)) if (FIL_FileOK(CONFIGFILENAME)) usehome = false; // Let's NOT use home else diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 09f9d4651..e2ccd0172 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -168,7 +168,7 @@ void SendWeaponPref(void); void SendWeaponPref2(void); static CV_PossibleValue_t usemouse_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Force"}, {0, NULL}}; -#if (defined (__unix__) && !defined (MSDOS)) || defined(__APPLE__) || defined (UNIXCOMMON) +#if defined (__unix__) || defined (__APPLE__) || defined (UNIXCOMMON) static CV_PossibleValue_t mouse2port_cons_t[] = {{0, "/dev/gpmdata"}, {1, "/dev/ttyS0"}, {2, "/dev/ttyS1"}, {3, "/dev/ttyS2"}, {4, "/dev/ttyS3"}, {0, NULL}}; #else @@ -255,7 +255,7 @@ consvar_t cv_joyscale2 = CVAR_INIT ("padscale2", "1", CV_SAVE|CV_CALL, NULL, I_J consvar_t cv_joyscale = CVAR_INIT ("padscale", "1", CV_SAVE|CV_HIDEN, NULL, NULL); //Alam: Dummy for save consvar_t cv_joyscale2 = CVAR_INIT ("padscale2", "1", CV_SAVE|CV_HIDEN, NULL, NULL); //Alam: Dummy for save #endif -#if (defined (__unix__) && !defined (MSDOS)) || defined(__APPLE__) || defined (UNIXCOMMON) +#if defined (__unix__) || defined (__APPLE__) || defined (UNIXCOMMON) consvar_t cv_mouse2port = CVAR_INIT ("mouse2port", "/dev/gpmdata", CV_SAVE, mouse2port_cons_t, NULL); consvar_t cv_mouse2opt = CVAR_INIT ("mouse2opt", "0", CV_SAVE, NULL, NULL); #else @@ -788,7 +788,7 @@ void D_RegisterClientCommands(void) // WARNING: the order is important when initialising mouse2 // we need the mouse2port CV_RegisterVar(&cv_mouse2port); -#if (defined (__unix__) && !defined (MSDOS)) || defined(__APPLE__) || defined (UNIXCOMMON) +#if defined (__unix__) || defined (__APPLE__) || defined (UNIXCOMMON) CV_RegisterVar(&cv_mouse2opt); #endif CV_RegisterVar(&cv_controlperkey); diff --git a/src/d_netcmd.h b/src/d_netcmd.h index ac39626a4..59c231255 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -45,7 +45,7 @@ extern consvar_t cv_joyscale2; // splitscreen with second mouse extern consvar_t cv_mouse2port; extern consvar_t cv_usemouse2; -#if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) +#if defined (__unix__) || defined (__APPLE__) || defined (UNIXCOMMON) extern consvar_t cv_mouse2opt; #endif diff --git a/src/doomdef.h b/src/doomdef.h index 5f36f2d69..0c88d1add 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -112,7 +112,7 @@ //#define PARANOIA // do some tests that never fail but maybe // turn this on by make etc.. DEBUGMODE = 1 or use the Debug profile in the VC++ projects //#endif -#if defined (_WIN32) || (defined (__unix__) && !defined (MSDOS)) || defined(__APPLE__) || defined (UNIXCOMMON) || defined (macintosh) +#if defined (_WIN32) || defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) || defined (macintosh) #define LOGMESSAGES // write message in log.txt #endif @@ -415,7 +415,7 @@ enum { }; // Name of local directory for config files and savegames -#if (((defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON)) && !defined (__CYGWIN__)) && !defined (__APPLE__) +#if (defined (__unix__) || defined (UNIXCOMMON)) && !defined (__CYGWIN__) && !defined (__APPLE__) #define DEFAULTDIR ".srb2" #else #define DEFAULTDIR "srb2" diff --git a/src/doomtype.h b/src/doomtype.h index ffaa540b1..f04314f54 100644 --- a/src/doomtype.h +++ b/src/doomtype.h @@ -97,7 +97,7 @@ typedef long ssize_t; #define strncasecmp strnicmp #define strcasecmp strcmpi #endif -#if (defined (__unix__) && !defined (MSDOS)) || defined(__APPLE__) || defined (UNIXCOMMON) +#if defined (__unix__) || defined (__APPLE__) || defined (UNIXCOMMON) #undef stricmp #define stricmp(x,y) strcasecmp(x,y) #undef strnicmp diff --git a/src/i_tcp.c b/src/i_tcp.c index a9f617dc9..f54dd6878 100644 --- a/src/i_tcp.c +++ b/src/i_tcp.c @@ -64,7 +64,7 @@ #include #include - #if (defined (__unix__) && !defined (MSDOS)) || defined(__APPLE__) || defined (UNIXCOMMON) + #if defined (__unix__) || defined (__APPLE__) || defined (UNIXCOMMON) #include #endif // UNIXCOMMON #endif @@ -155,7 +155,7 @@ typedef SOCKET SOCKET_TYPE; #define ERRSOCKET (SOCKET_ERROR) #else - #if (defined (__unix__) && !defined (MSDOS)) || defined (__APPLE__) || defined (__HAIKU__) + #if defined (__unix__) || defined (__APPLE__) || defined (__HAIKU__) typedef int SOCKET_TYPE; #else typedef unsigned long SOCKET_TYPE; diff --git a/src/m_menu.c b/src/m_menu.c index 516bd34c1..a41c2db26 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1322,7 +1322,7 @@ static menuitem_t OP_Camera2ExtendedOptionsMenu[] = enum { op_video_resolution = 1, -#if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL) +#if defined (__unix__) || defined (UNIXCOMMON) || defined (HAVE_SDL) op_video_fullscreen, #endif op_video_vsync, @@ -1334,7 +1334,7 @@ static menuitem_t OP_VideoOptionsMenu[] = {IT_HEADER, NULL, "Screen", NULL, 0}, {IT_STRING | IT_CALL, NULL, "Set Resolution...", M_VideoModeMenu, 6}, -#if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL) +#if defined (__unix__) || defined (UNIXCOMMON) || defined (HAVE_SDL) {IT_STRING|IT_CVAR, NULL, "Fullscreen", &cv_fullscreen, 11}, #endif {IT_STRING | IT_CVAR, NULL, "Vertical Sync", &cv_vidwait, 16}, @@ -1453,7 +1453,7 @@ static menuitem_t OP_OpenGLOptionsMenu[] = #ifdef ALAM_LIGHTING {IT_SUBMENU|IT_STRING, NULL, "Lighting...", &OP_OpenGLLightingDef, 144}, #endif -#if defined (_WINDOWS) && (!((defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL))) +#if defined (_WINDOWS) && (!(defined (__unix__) || defined (UNIXCOMMON) || defined (HAVE_SDL))) {IT_STRING|IT_CVAR, NULL, "Fullscreen", &cv_fullscreen, 154}, #endif }; @@ -12923,7 +12923,7 @@ static void M_VideoModeMenu(INT32 choice) memset(modedescs, 0, sizeof(modedescs)); -#if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL) +#if defined (__unix__) || defined (UNIXCOMMON) || defined (HAVE_SDL) VID_PrepareModeList(); // FIXME: hack #endif vidm_nummodes = 0; diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index a0dd6e1da..e3a0c2563 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -102,7 +102,7 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); #endif #endif -#if (defined (__unix__) && !defined (_MSDOS)) || (defined (UNIXCOMMON) && !defined(__APPLE__)) +#if defined (__unix__) || (defined (UNIXCOMMON) && !defined (__APPLE__)) #include #include #define NEWSIGNALHANDLER diff --git a/src/v_video.c b/src/v_video.c index 4713db0d8..1c383a2ac 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -418,7 +418,7 @@ void V_SetPalette(INT32 palettenum) #ifdef HWRENDER if (rendermode == render_opengl) HWR_SetPalette(&pLocalPalette[palettenum*256]); -#if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL) +#if defined (__unix__) || defined (UNIXCOMMON) || defined (HAVE_SDL) else #endif #endif @@ -432,7 +432,7 @@ void V_SetPaletteLump(const char *pal) #ifdef HWRENDER if (rendermode == render_opengl) HWR_SetPalette(pLocalPalette); -#if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL) +#if defined (__unix__) || defined (UNIXCOMMON) || defined (HAVE_SDL) else #endif #endif From eece82c481dfa2cc7ab6a3fa1480f2976484b6f4 Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Tue, 30 Mar 2021 17:03:05 -0300 Subject: [PATCH 332/644] Blend modes revision This changes how blend modes render, and includes fixes. --- src/hardware/hw_defs.h | 13 ++- src/hardware/hw_light.c | 8 +- src/hardware/hw_main.c | 32 ++++--- src/hardware/r_opengl/r_opengl.c | 8 +- src/r_draw.c | 148 ++++++++++++++++++++++++------- src/r_draw.h | 5 +- src/r_things.c | 6 +- 7 files changed, 156 insertions(+), 64 deletions(-) diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index bd6afc74f..4bff8fc6a 100644 --- a/src/hardware/hw_defs.h +++ b/src/hardware/hw_defs.h @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -216,14 +216,13 @@ enum EPolyFlags PF_Masked = 0x00000001, // Poly is alpha scaled and 0 alpha pixels are discarded (holes in texture) PF_Translucent = 0x00000002, // Poly is transparent, alpha = level of transparency PF_Environment = 0x00000004, // Poly should be drawn environment mapped. (Hurdler: used for text drawing) - PF_Additive = 0x00000008, // Additive color blending - PF_AdditiveSource = 0x00000010, // Source blending factor is additive. This is the opposite of regular additive blending. - PF_Subtractive = 0x00000020, // Subtractive color blending - PF_ReverseSubtract = 0x00000040, // Reverse subtract, used in wall splats (decals) - PF_Multiplicative = 0x00000080, // Multiplicative color blending + PF_Additive = 0x00000008, // Source blending factor is additive. + PF_Subtractive = 0x00000010, // Subtractive color blending + PF_ReverseSubtract = 0x00000020, // Reverse subtract, used in wall splats (decals) + PF_Multiplicative = 0x00000040, // Multiplicative color blending PF_Fog = 0x20000000, // Fog blocks PF_NoAlphaTest = 0x40000000, // Disables alpha testing - PF_Blending = (PF_Masked|PF_Translucent|PF_Environment|PF_Additive|PF_AdditiveSource|PF_Subtractive|PF_ReverseSubtract|PF_Multiplicative|PF_Fog) & ~PF_NoAlphaTest, + PF_Blending = (PF_Masked|PF_Translucent|PF_Environment|PF_Additive|PF_Subtractive|PF_ReverseSubtract|PF_Multiplicative|PF_Fog) & ~PF_NoAlphaTest, // other flag bits PF_Occlude = 0x00000100, // Updates the depth buffer diff --git a/src/hardware/hw_light.c b/src/hardware/hw_light.c index 93c61f4e7..e83d9a6ec 100644 --- a/src/hardware/hw_light.c +++ b/src/hardware/hw_light.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -35,7 +35,7 @@ #define DL_HIGH_QUALITY //#define STATICLIGHT //Hurdler: TODO! -#define LIGHTMAPFLAGS (PF_Modulated|PF_AdditiveSource) +#define LIGHTMAPFLAGS (PF_Modulated|PF_Additive) #ifdef ALAM_LIGHTING static dynlights_t view_dynlights[2]; // 2 players in splitscreen mode @@ -1056,7 +1056,7 @@ void HWR_DoCoronasLighting(FOutVector *outVerts, gl_vissprite_t *spr) HWR_GetPic(coronalumpnum); /// \todo use different coronas - HWD.pfnDrawPolygon (&Surf, light, 4, PF_Modulated | PF_AdditiveSource | PF_Corona | PF_NoDepthTest); + HWD.pfnDrawPolygon (&Surf, light, 4, PF_Modulated | PF_Additive | PF_Corona | PF_NoDepthTest); } } #endif @@ -1144,7 +1144,7 @@ void HWR_DrawCoronas(void) light[3].y = cy+size*1.33f; light[3].s = 0.0f; light[3].t = 1.0f; - HWD.pfnDrawPolygon (&Surf, light, 4, PF_Modulated | PF_AdditiveSource | PF_NoDepthTest | PF_Corona); + HWD.pfnDrawPolygon (&Surf, light, 4, PF_Modulated | PF_Additive | PF_NoDepthTest | PF_Corona); } } #endif diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index c2d617eaf..0602c5c49 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -706,6 +706,8 @@ FBITFIELD HWR_GetBlendModeFlag(INT32 ast) { switch (ast) { + case AST_COPY: + return PF_Masked; case AST_ADD: return PF_Additive; case AST_SUBTRACT: @@ -744,7 +746,7 @@ UINT8 HWR_GetTranstableAlpha(INT32 transtablenum) FBITFIELD HWR_SurfaceBlend(INT32 style, INT32 transtablenum, FSurfaceInfo *pSurf) { - if (!transtablenum) + if (!transtablenum || style == AST_COPY) { pSurf->PolyColor.s.alpha = 0xff; return PF_Masked; @@ -3813,8 +3815,6 @@ static void HWR_SplitSprite(gl_vissprite_t *spr) else if (spr->mobj->frame & FF_TRANSMASK) { INT32 trans = (spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT; - if (spr->mobj->blendmode == AST_TRANSLUCENT && trans >= NUMTRANSMAPS) - return; blend = HWR_SurfaceBlend(spr->mobj->blendmode, trans, &Surf); } else @@ -4240,8 +4240,6 @@ static void HWR_DrawSprite(gl_vissprite_t *spr) else if (spr->mobj->frame & FF_TRANSMASK) { INT32 trans = (spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT; - if (spr->mobj->blendmode == AST_TRANSLUCENT && trans >= NUMTRANSMAPS) - return; blend = HWR_SurfaceBlend(spr->mobj->blendmode, trans, &Surf); } else @@ -4354,9 +4352,7 @@ static inline void HWR_DrawPrecipitationSprite(gl_vissprite_t *spr) if (spr->mobj->frame & FF_TRANSMASK) { INT32 trans = (spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT; - if (spr->mobj->blendmode == AST_TRANSLUCENT && trans >= NUMTRANSMAPS) - return; - blend = HWR_SurfaceBlend(spr->mobj->blendmode, trans, &Surf); + blend = HWR_SurfaceBlend(AST_TRANSLUCENT, trans, &Surf); } else { @@ -4935,6 +4931,13 @@ static void HWR_ProjectSprite(mobj_t *thing) if (thing->spritexscale < 1 || thing->spriteyscale < 1) return; + // Visibility check by the blend mode. + if (thing->frame & FF_TRANSMASK) + { + if (!R_BlendLevelVisible(thing->blendmode, (thing->frame & FF_TRANSMASK)>>FF_TRANSSHIFT)) + return; + } + dispoffset = thing->info->dispoffset; this_scale = FIXED_TO_FLOAT(thing->scale); @@ -5321,6 +5324,13 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing) unsigned rot = 0; UINT8 flip; + // Visibility check by the blend mode. + if (thing->frame & FF_TRANSMASK) + { + if (!R_BlendLevelVisible(thing->blendmode, (thing->frame & FF_TRANSMASK)>>FF_TRANSSHIFT)) + return; + } + // transform the origin point tr_x = FIXED_TO_FLOAT(thing->x) - gl_viewx; tr_y = FIXED_TO_FLOAT(thing->y) - gl_viewy; @@ -5354,7 +5364,7 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing) return; #endif - sprframe = &sprdef->spriteframes[ thing->frame & FF_FRAMEMASK]; + sprframe = &sprdef->spriteframes[thing->frame & FF_FRAMEMASK]; // use single rotation for all views lumpoff = sprframe->lumpid[0]; @@ -6510,7 +6520,7 @@ void HWR_DoPostProcessor(player_t *player) Surf.PolyColor.s.alpha = 0xc0; // match software mode - HWD.pfnDrawPolygon(&Surf, v, 4, PF_Modulated|PF_AdditiveSource|PF_NoTexture|PF_NoDepthTest); + HWD.pfnDrawPolygon(&Surf, v, 4, PF_Modulated|PF_Additive|PF_NoTexture|PF_NoDepthTest); } // Capture the screen for intermission and screen waving diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 6967bab74..3969f7f35 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -1576,12 +1576,11 @@ static void SetBlendMode(FBITFIELD flags) case PF_Additive & PF_Blending: case PF_Subtractive & PF_Blending: case PF_ReverseSubtract & PF_Blending: + pglBlendFunc(GL_SRC_ALPHA, GL_ONE); // src * alpha + dest + break; case PF_Environment & PF_Blending: pglBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); break; - case PF_AdditiveSource & PF_Blending: - pglBlendFunc(GL_SRC_ALPHA, GL_ONE); // src * alpha + dest - break; case PF_Multiplicative & PF_Blending: pglBlendFunc(GL_DST_COLOR, GL_ZERO); break; @@ -1620,7 +1619,6 @@ static void SetBlendMode(FBITFIELD flags) break; case PF_Translucent & PF_Blending: case PF_Additive & PF_Blending: - case PF_AdditiveSource & PF_Blending: case PF_Subtractive & PF_Blending: case PF_ReverseSubtract & PF_Blending: case PF_Environment & PF_Blending: @@ -2752,7 +2750,7 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 fade.alpha = byte2float[Surface->FadeColor.s.alpha]; flags = (Surface->PolyFlags | PF_Modulated); - if (Surface->PolyFlags & (PF_Additive|PF_AdditiveSource|PF_Subtractive|PF_ReverseSubtract|PF_Multiplicative)) + if (Surface->PolyFlags & (PF_Additive|PF_Subtractive|PF_ReverseSubtract|PF_Multiplicative)) flags |= PF_Occlude; else if (Surface->PolyColor.s.alpha == 0xFF) flags |= (PF_Occlude | PF_Masked); diff --git a/src/r_draw.c b/src/r_draw.c index c3d4efae3..0ebdb4dd8 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -198,43 +198,15 @@ void R_InitTranslucencyTables(void) R_GenerateBlendTables(); } -void R_GenerateBlendTables(void) -{ - INT32 i; - - for (i = 0; i < NUMBLENDMAPS; i++) - { - if (i == blendtab_modulate) - continue; - blendtables[i] = Z_MallocAlign((NUMTRANSTABLES + 1) * 0x10000, PU_STATIC, NULL, 16); - } - - for (i = 0; i <= 9; i++) - { - const size_t offs = (0x10000 * i); - const UINT8 alpha = TRANSTAB_AMTMUL10 * i; - - R_GenerateTranslucencyTable(blendtables[blendtab_add] + offs, AST_ADD, alpha); - R_GenerateTranslucencyTable(blendtables[blendtab_subtract] + offs, AST_SUBTRACT, alpha); - R_GenerateTranslucencyTable(blendtables[blendtab_reversesubtract] + offs, AST_REVERSESUBTRACT, alpha); - } - - // Modulation blending only requires a single table - blendtables[blendtab_modulate] = Z_MallocAlign(0x10000, PU_STATIC, NULL, 16); - R_GenerateTranslucencyTable(blendtables[blendtab_modulate], AST_MODULATE, 0); -} - static colorlookup_t transtab_lut; -void R_GenerateTranslucencyTable(UINT8 *table, int style, UINT8 blendamt) +static void R_GenerateTranslucencyTable(UINT8 *table, int style, UINT8 blendamt) { INT16 bg, fg; if (table == NULL) I_Error("R_GenerateTranslucencyTable: input table was NULL!"); - InitColorLUT(&transtab_lut, pMasterPalette, false); - for (bg = 0; bg < 0xFF; bg++) { for (fg = 0; fg < 0xFF; fg++) @@ -243,12 +215,117 @@ void R_GenerateTranslucencyTable(UINT8 *table, int style, UINT8 blendamt) RGBA_t frontrgba = V_GetMasterColor(fg); RGBA_t result; - result.rgba = ASTBlendPixel(backrgba, frontrgba, style, blendamt); + result.rgba = ASTBlendPixel(backrgba, frontrgba, style, 0xFF); + result.rgba = ASTBlendPixel(result, frontrgba, AST_TRANSLUCENT, blendamt); + table[((bg * 0x100) + fg)] = GetColorLUT(&transtab_lut, result.s.red, result.s.green, result.s.blue); } } } +static void R_GenerateSubtractiveTable(UINT8 *table, int style, UINT8 blendamt) +{ + INT16 bg, fg; + + if (table == NULL) + I_Error("R_GenerateSubtractiveTable: input table was NULL!"); + + blendamt = 0xFF - blendamt; + if (!blendamt) + { + memset(table, GetColorLUT(&transtab_lut, 0, 0, 0), 0x10000); + return; + } + + for (bg = 0; bg < 0xFF; bg++) + { + for (fg = 0; fg < 0xFF; fg++) + { + RGBA_t backrgba = V_GetMasterColor(bg); + RGBA_t frontrgba = V_GetMasterColor(fg); + RGBA_t result; + + result.rgba = ASTBlendPixel(backrgba, frontrgba, style, 0xFF); + result.s.red = (result.s.red * blendamt) / 0xFF; + result.s.green = (result.s.green * blendamt) / 0xFF; + result.s.blue = (result.s.blue * blendamt) / 0xFF; + + table[((bg * 0x100) + fg)] = GetColorLUT(&transtab_lut, result.s.red, result.s.green, result.s.blue); + } + } +} + +static void R_GenerateModulationTable(UINT8 *table) +{ + INT16 bg, fg; + + if (table == NULL) + I_Error("R_GenerateModulationTable: input table was NULL!"); + + for (bg = 0; bg < 0xFF; bg++) + { + for (fg = 0; fg < 0xFF; fg++) + { + RGBA_t backrgba = V_GetMasterColor(bg); + RGBA_t frontrgba = V_GetMasterColor(fg); + RGBA_t result; + result.rgba = ASTBlendPixel(backrgba, frontrgba, AST_MODULATE, 0); + table[((bg * 0x100) + fg)] = GetColorLUT(&transtab_lut, result.s.red, result.s.green, result.s.blue); + } + } +} + +static INT32 R_GetBlendTableCount(INT32 style) +{ + INT32 count = NUMTRANSTABLES; + if (style == blendtab_subtract || style == blendtab_reversesubtract) + count++; + return count; +} + +static void R_GenerateBlendTableMaps(INT32 tab, INT32 style, void (*genfunc)(UINT8 *, int, UINT8)) +{ + INT32 i = 0; + for (; i <= R_GetBlendTableCount(tab); i++) + { + const size_t offs = (0x10000 * i); + const UINT16 alpha = min(TRANSTAB_AMTMUL10 * i, 0xFF); + genfunc(blendtables[tab] + offs, style, alpha); + } +} + +void R_GenerateBlendTables(void) +{ + INT32 i; + + for (i = 0; i < NUMBLENDMAPS; i++) + { + if (i == blendtab_modulate) + continue; + blendtables[i] = Z_MallocAlign((R_GetBlendTableCount(i) + 1) * 0x10000, PU_STATIC, NULL, 16); + } + + InitColorLUT(&transtab_lut, pMasterPalette, false); + + // Additive + R_GenerateBlendTableMaps(blendtab_add, AST_ADD, R_GenerateTranslucencyTable); + + // Subtractive +#if 1 + R_GenerateBlendTableMaps(blendtab_subtract, AST_SUBTRACT, R_GenerateSubtractiveTable); +#else + R_GenerateBlendTableMaps(blendtab_subtract, AST_SUBTRACT, R_GenerateTranslucencyTable); +#endif + + // Reverse subtractive + R_GenerateBlendTableMaps(blendtab_reversesubtract, AST_REVERSESUBTRACT, R_GenerateTranslucencyTable); + + // Modulation blending only requires a single table + blendtables[blendtab_modulate] = Z_MallocAlign(0x10000, PU_STATIC, NULL, 16); + R_GenerateModulationTable(blendtables[blendtab_modulate]); +} + +#define ClipBlendLevel(style, trans) max(min((trans), R_GetBlendTableCount(style)+1), 0) #define ClipTransLevel(trans) max(min((trans), NUMTRANSMAPS-2), 0) UINT8 *R_GetTranslucencyTable(INT32 alphalevel) @@ -258,7 +335,7 @@ UINT8 *R_GetTranslucencyTable(INT32 alphalevel) UINT8 *R_GetBlendTable(int style, INT32 alphalevel) { - size_t offs = (ClipTransLevel(alphalevel) << FF_TRANSSHIFT); + size_t offs = (ClipBlendLevel(style, alphalevel) << FF_TRANSSHIFT); // Lactozilla: Returns the equivalent to AST_TRANSLUCENT // if no alpha style matches any of the blend tables. @@ -283,6 +360,13 @@ UINT8 *R_GetBlendTable(int style, INT32 alphalevel) return NULL; } +boolean R_BlendLevelVisible(INT32 blendmode, INT32 alphalevel) +{ + if (blendmode == AST_COPY || blendmode == AST_SUBTRACT || blendmode == AST_MODULATE) + return true; + return (alphalevel < R_GetBlendTableCount(blendmode)); +} + // Define for getting accurate color brightness readings according to how the human eye sees them. // https://en.wikipedia.org/wiki/Relative_luminance // 0.2126 to red diff --git a/src/r_draw.h b/src/r_draw.h index d1eb83033..caf43fd89 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -140,11 +140,12 @@ extern UINT8 *blendtables[NUMBLENDMAPS]; void R_InitTranslucencyTables(void); void R_GenerateBlendTables(void); -void R_GenerateTranslucencyTable(UINT8 *table, int style, UINT8 blendamt); UINT8 *R_GetTranslucencyTable(INT32 alphalevel); UINT8 *R_GetBlendTable(int style, INT32 alphalevel); +boolean R_BlendLevelVisible(INT32 blendmode, INT32 alphalevel); + // Color ramp modification should force a recache extern UINT8 skincolor_modified[]; diff --git a/src/r_things.c b/src/r_things.c index 14eed9cf2..aa28b7c2b 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -1803,7 +1803,7 @@ static void R_ProjectSprite(mobj_t *thing) else if (oldthing->frame & FF_TRANSMASK) { trans = (oldthing->frame & FF_TRANSMASK) >> FF_TRANSSHIFT; - if (oldthing->blendmode == AST_TRANSLUCENT && trans >= NUMTRANSMAPS) + if (!R_BlendLevelVisible(oldthing->blendmode, trans)) return; } else @@ -2199,7 +2199,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) // specific translucency if (thing->frame & FF_TRANSMASK) - vis->transmap = (thing->frame & FF_TRANSMASK) - 0x10000 + transtables; + vis->transmap = R_GetTranslucencyTable((thing->frame & FF_TRANSMASK) >> FF_TRANSSHIFT); else vis->transmap = NULL; From 59be35e533c420f392da56987f5414cb679e9c25 Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Tue, 30 Mar 2021 22:12:31 -0300 Subject: [PATCH 333/644] Rename functions, make more efficient, fix subtractive in Software --- src/hardware/hw_main.c | 3 +- src/r_draw.c | 92 +++++++++++++++++++++++------------------- 2 files changed, 53 insertions(+), 42 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 0602c5c49..f2af1cc40 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -707,6 +707,7 @@ FBITFIELD HWR_GetBlendModeFlag(INT32 ast) switch (ast) { case AST_COPY: + case AST_OVERLAY: return PF_Masked; case AST_ADD: return PF_Additive; @@ -746,7 +747,7 @@ UINT8 HWR_GetTranstableAlpha(INT32 transtablenum) FBITFIELD HWR_SurfaceBlend(INT32 style, INT32 transtablenum, FSurfaceInfo *pSurf) { - if (!transtablenum || style == AST_COPY) + if (!transtablenum || style == AST_COPY || style == AST_OVERLAY) { pSurf->PolyColor.s.alpha = 0xff; return PF_Masked; diff --git a/src/r_draw.c b/src/r_draw.c index 0ebdb4dd8..8625fbab2 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -173,14 +173,12 @@ static INT32 CacheIndexToSkin(INT32 ttc) CV_PossibleValue_t Color_cons_t[MAXSKINCOLORS+1]; -#define TRANSTAB_AMTMUL10 (256.0f / 10.0f) - /** \brief Initializes the translucency tables used by the Software renderer. */ void R_InitTranslucencyTables(void) { - // Load here the transparency lookup tables 'TINTTAB' - // NOTE: the TINTTAB resource MUST BE aligned on 64k for the asm + // Load here the transparency lookup tables 'TRANSx0' + // NOTE: the TRANSx0 resources MUST BE aligned on 64k for the asm // optimised code (in other words, transtables pointer low word is 0) transtables = Z_MallocAlign(NUMTRANSTABLES*0x10000, PU_STATIC, NULL, 16); @@ -200,12 +198,12 @@ void R_InitTranslucencyTables(void) static colorlookup_t transtab_lut; -static void R_GenerateTranslucencyTable(UINT8 *table, int style, UINT8 blendamt) +static void BlendTab_Translucent(UINT8 *table, int style, UINT8 blendamt) { INT16 bg, fg; if (table == NULL) - I_Error("R_GenerateTranslucencyTable: input table was NULL!"); + I_Error("BlendTab_Translucent: input table was NULL!"); for (bg = 0; bg < 0xFF; bg++) { @@ -223,15 +221,14 @@ static void R_GenerateTranslucencyTable(UINT8 *table, int style, UINT8 blendamt) } } -static void R_GenerateSubtractiveTable(UINT8 *table, int style, UINT8 blendamt) +static void BlendTab_Subtractive(UINT8 *table, int style, UINT8 blendamt) { INT16 bg, fg; if (table == NULL) - I_Error("R_GenerateSubtractiveTable: input table was NULL!"); + I_Error("BlendTab_Subtractive: input table was NULL!"); - blendamt = 0xFF - blendamt; - if (!blendamt) + if (blendamt == 0xFF) { memset(table, GetColorLUT(&transtab_lut, 0, 0, 0), 0x10000); return; @@ -246,21 +243,21 @@ static void R_GenerateSubtractiveTable(UINT8 *table, int style, UINT8 blendamt) RGBA_t result; result.rgba = ASTBlendPixel(backrgba, frontrgba, style, 0xFF); - result.s.red = (result.s.red * blendamt) / 0xFF; - result.s.green = (result.s.green * blendamt) / 0xFF; - result.s.blue = (result.s.blue * blendamt) / 0xFF; + result.s.red = max(0, result.s.red - blendamt); + result.s.green = max(0, result.s.green - blendamt); + result.s.blue = max(0, result.s.blue - blendamt); table[((bg * 0x100) + fg)] = GetColorLUT(&transtab_lut, result.s.red, result.s.green, result.s.blue); } } } -static void R_GenerateModulationTable(UINT8 *table) +static void BlendTab_Modulative(UINT8 *table) { INT16 bg, fg; if (table == NULL) - I_Error("R_GenerateModulationTable: input table was NULL!"); + I_Error("BlendTab_Modulative: input table was NULL!"); for (bg = 0; bg < 0xFF; bg++) { @@ -275,21 +272,33 @@ static void R_GenerateModulationTable(UINT8 *table) } } -static INT32 R_GetBlendTableCount(INT32 style) +static INT32 BlendTab_Count[NUMBLENDMAPS] = { - INT32 count = NUMTRANSTABLES; - if (style == blendtab_subtract || style == blendtab_reversesubtract) - count++; - return count; -} + NUMTRANSTABLES, // blendtab_add + NUMTRANSTABLES+1, // blendtab_subtract + NUMTRANSTABLES+1, // blendtab_reversesubtract + 1 // blendtab_modulate +}; -static void R_GenerateBlendTableMaps(INT32 tab, INT32 style, void (*genfunc)(UINT8 *, int, UINT8)) +static INT32 BlendTab_FromStyle[] = { - INT32 i = 0; - for (; i <= R_GetBlendTableCount(tab); i++) + 0, // AST_COPY + 0, // AST_TRANSLUCENT + blendtab_add, // AST_ADD + blendtab_subtract, // AST_SUBTRACT + blendtab_reversesubtract, // AST_REVERSESUBTRACT + blendtab_modulate, // AST_MODULATE + 0 // AST_OVERLAY +}; + +static void BlendTab_GenerateMaps(INT32 tab, INT32 style, void (*genfunc)(UINT8 *, int, UINT8)) +{ + INT32 i = 0, num = BlendTab_Count[tab]; + const float amtmul = (256.0f / (float)(NUMTRANSTABLES)); + for (; i < num; i++) { const size_t offs = (0x10000 * i); - const UINT16 alpha = min(TRANSTAB_AMTMUL10 * i, 0xFF); + const UINT16 alpha = min(amtmul * i, 0xFF); genfunc(blendtables[tab] + offs, style, alpha); } } @@ -299,33 +308,28 @@ void R_GenerateBlendTables(void) INT32 i; for (i = 0; i < NUMBLENDMAPS; i++) - { - if (i == blendtab_modulate) - continue; - blendtables[i] = Z_MallocAlign((R_GetBlendTableCount(i) + 1) * 0x10000, PU_STATIC, NULL, 16); - } + blendtables[i] = Z_MallocAlign(BlendTab_Count[i] * 0x10000, PU_STATIC, NULL, 16); InitColorLUT(&transtab_lut, pMasterPalette, false); // Additive - R_GenerateBlendTableMaps(blendtab_add, AST_ADD, R_GenerateTranslucencyTable); + BlendTab_GenerateMaps(blendtab_add, AST_ADD, BlendTab_Translucent); // Subtractive #if 1 - R_GenerateBlendTableMaps(blendtab_subtract, AST_SUBTRACT, R_GenerateSubtractiveTable); + BlendTab_GenerateMaps(blendtab_subtract, AST_SUBTRACT, BlendTab_Subtractive); #else - R_GenerateBlendTableMaps(blendtab_subtract, AST_SUBTRACT, R_GenerateTranslucencyTable); + BlendTab_GenerateMaps(blendtab_subtract, AST_SUBTRACT, BlendTab_Translucent); #endif // Reverse subtractive - R_GenerateBlendTableMaps(blendtab_reversesubtract, AST_REVERSESUBTRACT, R_GenerateTranslucencyTable); + BlendTab_GenerateMaps(blendtab_reversesubtract, AST_REVERSESUBTRACT, BlendTab_Translucent); - // Modulation blending only requires a single table - blendtables[blendtab_modulate] = Z_MallocAlign(0x10000, PU_STATIC, NULL, 16); - R_GenerateModulationTable(blendtables[blendtab_modulate]); + // Modulative blending only requires a single table + BlendTab_Modulative(blendtables[blendtab_modulate]); } -#define ClipBlendLevel(style, trans) max(min((trans), R_GetBlendTableCount(style)+1), 0) +#define ClipBlendLevel(style, trans) max(min((trans), BlendTab_Count[BlendTab_FromStyle[style]]-1), 0) #define ClipTransLevel(trans) max(min((trans), NUMTRANSMAPS-2), 0) UINT8 *R_GetTranslucencyTable(INT32 alphalevel) @@ -335,7 +339,12 @@ UINT8 *R_GetTranslucencyTable(INT32 alphalevel) UINT8 *R_GetBlendTable(int style, INT32 alphalevel) { - size_t offs = (ClipBlendLevel(style, alphalevel) << FF_TRANSSHIFT); + size_t offs; + + if (style == AST_COPY || style == AST_OVERLAY) + return NULL; + + offs = (ClipBlendLevel(style, alphalevel) << FF_TRANSSHIFT); // Lactozilla: Returns the equivalent to AST_TRANSLUCENT // if no alpha style matches any of the blend tables. @@ -362,9 +371,10 @@ UINT8 *R_GetBlendTable(int style, INT32 alphalevel) boolean R_BlendLevelVisible(INT32 blendmode, INT32 alphalevel) { - if (blendmode == AST_COPY || blendmode == AST_SUBTRACT || blendmode == AST_MODULATE) + if (blendmode == AST_COPY || blendmode == AST_SUBTRACT || blendmode == AST_MODULATE || blendmode == AST_OVERLAY) return true; - return (alphalevel < R_GetBlendTableCount(blendmode)); + + return (alphalevel < BlendTab_Count[BlendTab_FromStyle[blendmode]]); } // Define for getting accurate color brightness readings according to how the human eye sees them. From 7e6bc9724053dc3af859d0fc02893a8ec5eb6b91 Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Tue, 30 Mar 2021 22:52:50 -0300 Subject: [PATCH 334/644] Smoother freelook in Software Mhm hmm... --- src/r_main.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/r_main.c b/src/r_main.c index f82fb589e..04bdebc58 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1089,8 +1089,6 @@ subsector_t *R_PointInSubsectorOrNull(fixed_t x, fixed_t y) // 18/08/18: (No it's actually 16*viewheight, thanks Jimita for finding this out) static void R_SetupFreelook(player_t *player, boolean skybox) { - INT32 dy = 0; - #ifndef HWRENDER (void)player; (void)skybox; @@ -1109,14 +1107,15 @@ static void R_SetupFreelook(player_t *player, boolean skybox) G_SoftwareClipAimingPitch((INT32 *)&aimingangle); } - if (rendermode == render_soft) - { - dy = (AIMINGTODY(aimingangle)>>FRACBITS) * viewwidth/BASEVIDWIDTH; - yslope = &yslopetab[viewheight*8 - (viewheight/2 + dy)]; - } + centeryfrac = (viewheight/2)< Date: Sat, 13 Feb 2021 20:33:41 +0100 Subject: [PATCH 335/644] Our menu system sucks. That's all I have to say. --- src/m_menu.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 516bd34c1..0fca39801 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -11419,9 +11419,9 @@ static void M_ServerOptions(INT32 choice) OP_ServerOptionsMenu[ 2].status = IT_GRAYEDOUT; // Max players OP_ServerOptionsMenu[ 3].status = IT_GRAYEDOUT; // Allow add-on downloading OP_ServerOptionsMenu[ 4].status = IT_GRAYEDOUT; // Allow players to join - OP_ServerOptionsMenu[35].status = IT_GRAYEDOUT; // Master server - OP_ServerOptionsMenu[36].status = IT_GRAYEDOUT; // Minimum delay between joins - OP_ServerOptionsMenu[37].status = IT_GRAYEDOUT; // Attempts to resynchronise + OP_ServerOptionsMenu[36].status = IT_GRAYEDOUT; // Master server + OP_ServerOptionsMenu[37].status = IT_GRAYEDOUT; // Minimum delay between joins + OP_ServerOptionsMenu[38].status = IT_GRAYEDOUT; // Attempts to resynchronise } else { @@ -11429,11 +11429,11 @@ static void M_ServerOptions(INT32 choice) OP_ServerOptionsMenu[ 2].status = IT_STRING | IT_CVAR; OP_ServerOptionsMenu[ 3].status = IT_STRING | IT_CVAR; OP_ServerOptionsMenu[ 4].status = IT_STRING | IT_CVAR; - OP_ServerOptionsMenu[35].status = (netgame + OP_ServerOptionsMenu[36].status = (netgame ? IT_GRAYEDOUT : (IT_STRING | IT_CVAR | IT_CV_STRING)); - OP_ServerOptionsMenu[36].status = IT_STRING | IT_CVAR; OP_ServerOptionsMenu[37].status = IT_STRING | IT_CVAR; + OP_ServerOptionsMenu[38].status = IT_STRING | IT_CVAR; } #endif From 6bf76602ed442a6a9d3f141896c0f2dd0a0bf2a8 Mon Sep 17 00:00:00 2001 From: SwitchKaze Date: Tue, 23 Mar 2021 00:02:49 -0500 Subject: [PATCH 336/644] Refactor mouse --- src/d_main.c | 9 +++++++++ src/g_game.c | 31 ++++++++++++------------------- src/g_input.c | 34 ++++++++++++++++++++++++---------- src/g_input.h | 17 ++++++++++++++--- 4 files changed, 59 insertions(+), 32 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 23a2c0133..2a4e9ab81 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -175,6 +175,10 @@ void D_ProcessEvents(void) boolean eaten; + // Reset possibly stale mouse info + G_SetMouseData(0, 0, 1); + G_SetMouseData(0, 0, 2); + for (; eventtail != eventhead; eventtail = (eventtail+1) & (MAXEVENTS-1)) { ev = &events[eventtail]; @@ -219,6 +223,11 @@ void D_ProcessEvents(void) G_Responder(ev); } + + if (mouse.rdx || mouse.rdy) + G_SetMouseData(mouse.rdx, mouse.rdy, 1); + if (mouse2.rdx || mouse2.rdy) + G_SetMouseData(mouse2.rdx, mouse2.rdy, 2); } // diff --git a/src/g_game.c b/src/g_game.c index 2b304b4fd..e46a7f816 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1094,7 +1094,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) angle_t drawangleoffset = (player->powers[pw_carry] == CR_ROLLOUT) ? ANGLE_180 : 0; INT32 chasecam, chasefreelook, alwaysfreelook, usejoystick, invertmouse, turnmultiplier, mousemove; controlstyle_e controlstyle = G_ControlStyle(ssplayer); - INT32 *mx; INT32 *my; INT32 *mly; + mouse_t *m = &mouse; static INT32 turnheld[2]; // for accelerative turning static boolean keyboard_look[2]; // true if lookup/down using keyboard @@ -1117,9 +1117,6 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) invertmouse = cv_invertmouse.value; turnmultiplier = cv_cam_turnmultiplier.value; mousemove = cv_mousemove.value; - mx = &mousex; - my = &mousey; - mly = &mlooky; G_CopyTiccmd(cmd, I_BaseTiccmd(), 1); // empty, or external driver } else @@ -1131,9 +1128,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) invertmouse = cv_invertmouse2.value; turnmultiplier = cv_cam2_turnmultiplier.value; mousemove = cv_mousemove2.value; - mx = &mouse2x; - my = &mouse2y; - mly = &mlook2y; + m = &mouse2; G_CopyTiccmd(cmd, I_BaseTiccmd2(), 1); // empty, or external driver } @@ -1476,7 +1471,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) keyboard_look[forplayer] = false; // looking up/down - *myaiming += (*mly<<19)*player_invert*screen_invert; + *myaiming += (m->mlookdy<<19)*player_invert*screen_invert; } if (analogjoystickmove && joyaiming[forplayer] && lookjoystickvector.yaxis != 0 && configlookaxis != 0) @@ -1510,24 +1505,22 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) } if (!mouseaiming && mousemove) - forward += *my; + forward += m->dy; if ((!demoplayback && (player->pflags & PF_SLIDING))) // Analog for mouse - side += *mx*2; + side += m->dx*2; else if (controlstyle == CS_LMAOGALOG) { - if (*mx) + if (m->dx) { - if (*mx > 0) + if (m->dx > 0) cmd->buttons |= BT_CAMRIGHT; else cmd->buttons |= BT_CAMLEFT; } } else - cmd->angleturn = (INT16)(cmd->angleturn - (*mx*8)); - - *mx = *my = *mly = 0; + cmd->angleturn = (INT16)(cmd->angleturn - (m->dx*8)); if (forward > MAXPLMOVE) forward = MAXPLMOVE; @@ -1873,8 +1866,8 @@ void G_DoLoadLevel(boolean resetplayer) joyxmove[i] = joyymove[i] = 0; joy2xmove[i] = joy2ymove[i] = 0; } - mousex = mousey = 0; - mouse2x = mouse2y = 0; + G_SetMouseData(0, 0, 1); + G_SetMouseData(0, 0, 2); // clear hud messages remains (usually from game startup) CON_ClearHUD(); @@ -3095,8 +3088,8 @@ void G_DoReborn(INT32 playernum) joyxmove[i] = joyymove[i] = 0; joy2xmove[i] = joy2ymove[i] = 0; } - mousex = mousey = 0; - mouse2x = mouse2y = 0; + G_SetMouseData(0, 0, 1); + G_SetMouseData(0, 0, 2); // clear hud messages remains (usually from game startup) CON_ClearHUD(); diff --git a/src/g_input.c b/src/g_input.c index d3c21e774..049a4d82c 100644 --- a/src/g_input.c +++ b/src/g_input.c @@ -31,10 +31,8 @@ consvar_t cv_mouseysens = CVAR_INIT ("mouseysens", "20", CV_SAVE, mousesens_cons consvar_t cv_mouseysens2 = CVAR_INIT ("mouseysens2", "20", CV_SAVE, mousesens_cons_t, NULL); consvar_t cv_controlperkey = CVAR_INIT ("controlperkey", "One", CV_SAVE, onecontrolperkey_cons_t, NULL); -INT32 mousex, mousey; -INT32 mlooky; // like mousey but with a custom sensitivity for mlook - -INT32 mouse2x, mouse2y, mlook2y; +mouse_t mouse; +mouse_t mouse2; // joystick values are repeated INT32 joyxmove[JOYAXISSET], joyymove[JOYAXISSET], joy2xmove[JOYAXISSET], joy2ymove[JOYAXISSET]; @@ -142,9 +140,8 @@ void G_MapEventsToControls(event_t *ev) case ev_mouse: // buttons are virtual keys if (menuactive || CON_Ready() || chat_on) break; - mousex = (INT32)(ev->data2*((cv_mousesens.value*cv_mousesens.value)/110.0f + 0.1f)); - mousey = (INT32)(ev->data3*((cv_mousesens.value*cv_mousesens.value)/110.0f + 0.1f)); - mlooky = (INT32)(ev->data3*((cv_mouseysens.value*cv_mousesens.value)/110.0f + 0.1f)); + mouse.rdx = ev->data2; + mouse.rdy = ev->data3; break; case ev_joystick: // buttons are virtual keys @@ -166,9 +163,8 @@ void G_MapEventsToControls(event_t *ev) case ev_mouse2: // buttons are virtual keys if (menuactive || CON_Ready() || chat_on) break; - mouse2x = (INT32)(ev->data2*((cv_mousesens2.value*cv_mousesens2.value)/110.0f + 0.1f)); - mouse2y = (INT32)(ev->data3*((cv_mousesens2.value*cv_mousesens2.value)/110.0f + 0.1f)); - mlook2y = (INT32)(ev->data3*((cv_mouseysens2.value*cv_mousesens2.value)/110.0f + 0.1f)); + mouse2.rdx = ev->data2; + mouse2.rdy = ev->data3; break; default: @@ -1073,3 +1069,21 @@ void Command_Setcontrol2_f(void) setcontrol(gamecontrolbis); } + +void G_SetMouseData(INT32 realdx, INT32 realdy, UINT8 ssplayer) +{ + mouse_t *m = ssplayer == 1 ? &mouse : &mouse2; + consvar_t *cvsens, *cvysens; + + if (!realdx && !realdy) { + memset(m, 0, sizeof(*m)); + return; + } + cvsens = ssplayer == 1 ? &cv_mousesens : &cv_mousesens2; + cvysens = ssplayer == 1 ? &cv_mouseysens : &cv_mouseysens2; + m->rdx = realdx; + m->rdy = realdy; + m->dx = (INT32)(m->rdx*((cvsens->value*cvsens->value)/110.0f + 0.1f)); + m->dy = (INT32)(m->rdy*((cvsens->value*cvsens->value)/110.0f + 0.1f)); + m->mlookdy = (INT32)(m->rdy*((cvysens->value*cvsens->value)/110.0f + 0.1f)); +} diff --git a/src/g_input.h b/src/g_input.h index ce38f6ba9..5912bfdc7 100644 --- a/src/g_input.h +++ b/src/g_input.h @@ -116,9 +116,17 @@ extern consvar_t cv_mousesens, cv_mouseysens; extern consvar_t cv_mousesens2, cv_mouseysens2; extern consvar_t cv_controlperkey; -extern INT32 mousex, mousey; -extern INT32 mlooky; //mousey with mlookSensitivity -extern INT32 mouse2x, mouse2y, mlook2y; +typedef struct +{ + INT32 dx; // deltas with mousemove sensitivity + INT32 dy; + INT32 mlookdy; // dy with mouselook sensitivity + INT32 rdx; // deltas without sensitivity + INT32 rdy; +} mouse_t; + +extern mouse_t mouse; +extern mouse_t mouse2; extern INT32 joyxmove[JOYAXISSET], joyymove[JOYAXISSET], joy2xmove[JOYAXISSET], joy2ymove[JOYAXISSET]; @@ -175,4 +183,7 @@ void G_CopyControls(INT32 (*setupcontrols)[2], INT32 (*fromcontrols)[2], const I void G_SaveKeySetting(FILE *f, INT32 (*fromcontrols)[2], INT32 (*fromcontrolsbis)[2]); INT32 G_CheckDoubleUsage(INT32 keynum, boolean modify); +// sets the members of a mouse_t given position deltas +void G_SetMouseData(INT32 realdx, INT32 realdy, UINT8 ssplayer); + #endif From 3faa98cf4a824ac21a7fa8eae2292f2c6e6d917c Mon Sep 17 00:00:00 2001 From: SwitchKaze Date: Wed, 24 Mar 2021 03:54:11 -0500 Subject: [PATCH 337/644] Expose inputs to Lua --- src/CMakeLists.txt | 1 + src/blua/Makefile.cfg | 3 +- src/console.c | 4 +- src/d_main.c | 17 +++ src/deh_tables.c | 59 ++++++++ src/g_game.c | 84 +++++------ src/g_game.h | 20 +++ src/g_input.c | 16 +- src/g_input.h | 4 +- src/lua_baselib.c | 2 + src/lua_hook.h | 4 + src/lua_hooklib.c | 72 +++++++++ src/lua_inputlib.c | 214 +++++++++++++++++++++++++++ src/lua_libs.h | 3 + src/lua_script.c | 21 ++- src/m_menu.c | 4 +- src/sdl/Srb2SDL-vc10.vcxproj | 1 + src/sdl/Srb2SDL-vc10.vcxproj.filters | 3 + 18 files changed, 471 insertions(+), 61 deletions(-) create mode 100644 src/lua_inputlib.c diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 87a0499b6..77b5a0e4f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -281,6 +281,7 @@ set(SRB2_LUA_SOURCES lua_mobjlib.c lua_playerlib.c lua_polyobjlib.c + lua_inputlib.c lua_script.c lua_skinlib.c lua_thinkerlib.c diff --git a/src/blua/Makefile.cfg b/src/blua/Makefile.cfg index 3a2962e65..4536628ba 100644 --- a/src/blua/Makefile.cfg +++ b/src/blua/Makefile.cfg @@ -50,4 +50,5 @@ OBJS:=$(OBJS) \ $(OBJDIR)/lua_taglib.o \ $(OBJDIR)/lua_polyobjlib.o \ $(OBJDIR)/lua_blockmaplib.o \ - $(OBJDIR)/lua_hudlib.o + $(OBJDIR)/lua_hudlib.o \ + $(OBJDIR)/lua_inputlib.o diff --git a/src/console.c b/src/console.c index 121605b10..3b29e9c4f 100644 --- a/src/console.c +++ b/src/console.c @@ -221,7 +221,7 @@ static void CONS_Bind_f(void) for (key = 0; key < NUMINPUTS; key++) if (bindtable[key]) { - CONS_Printf("%s : \"%s\"\n", G_KeynumToString(key), bindtable[key]); + CONS_Printf("%s : \"%s\"\n", G_KeyNumToString(key), bindtable[key]); na = 1; } if (!na) @@ -229,7 +229,7 @@ static void CONS_Bind_f(void) return; } - key = G_KeyStringtoNum(COM_Argv(1)); + key = G_KeyStringToNum(COM_Argv(1)); if (key <= 0 || key >= NUMINPUTS) { CONS_Alert(CONS_NOTICE, M_GetText("Invalid key name\n")); diff --git a/src/d_main.c b/src/d_main.c index 2a4e9ab81..d60a6cf47 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -181,6 +181,8 @@ void D_ProcessEvents(void) for (; eventtail != eventhead; eventtail = (eventtail+1) & (MAXEVENTS-1)) { + boolean hooked = false; + ev = &events[eventtail]; // Screenshots over everything so that they can be taken anywhere. @@ -193,6 +195,12 @@ void D_ProcessEvents(void) continue; } + if (!CON_Ready() && !menuactive) { + if (G_LuaResponder(ev)) + continue; + hooked = true; + } + // Menu input #ifdef HAVE_THREADS I_lock_mutex(&m_menu_mutex); @@ -207,6 +215,12 @@ void D_ProcessEvents(void) if (eaten) continue; // menu ate the event + if (!hooked && !CON_Ready()) { + if (G_LuaResponder(ev)) + continue; + hooked = true; + } + // console input #ifdef HAVE_THREADS I_lock_mutex(&con_mutex); @@ -221,6 +235,9 @@ void D_ProcessEvents(void) if (eaten) continue; // ate the event + if (!hooked && G_LuaResponder(ev)) + continue; + G_Responder(ev); } diff --git a/src/deh_tables.c b/src/deh_tables.c index dd6d7d69f..7bfe723da 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -22,6 +22,8 @@ #include "v_video.h" // video flags (for lua) #include "i_sound.h" // musictype_t (for lua) #include "g_state.h" // gamestate_t (for lua) +#include "g_game.h" // Joystick axes (for lua) +#include "g_input.h" // Game controls (for lua) #include "deh_tables.h" @@ -5455,6 +5457,63 @@ struct int_const_s const INT_CONST[] = { {"GS_DEDICATEDSERVER",GS_DEDICATEDSERVER}, {"GS_WAITINGPLAYERS",GS_WAITINGPLAYERS}, + // Joystick axes + {"JA_NONE",JA_NONE}, + {"JA_TURN",JA_TURN}, + {"JA_MOVE",JA_MOVE}, + {"JA_LOOK",JA_LOOK}, + {"JA_STRAFE",JA_STRAFE}, + {"JA_DIGITAL",JA_DIGITAL}, + {"JA_JUMP",JA_JUMP}, + {"JA_SPIN",JA_SPIN}, + {"JA_FIRE",JA_FIRE}, + {"JA_FIRENORMAL",JA_FIRENORMAL}, + + // Game controls + {"gc_null",gc_null}, + {"gc_forward",gc_forward}, + {"gc_backward",gc_backward}, + {"gc_strafeleft",gc_strafeleft}, + {"gc_straferight",gc_straferight}, + {"gc_turnleft",gc_turnleft}, + {"gc_turnright",gc_turnright}, + {"gc_weaponnext",gc_weaponnext}, + {"gc_weaponprev",gc_weaponprev}, + {"gc_wepslot1",gc_wepslot1}, + {"gc_wepslot2",gc_wepslot2}, + {"gc_wepslot3",gc_wepslot3}, + {"gc_wepslot4",gc_wepslot4}, + {"gc_wepslot5",gc_wepslot5}, + {"gc_wepslot6",gc_wepslot6}, + {"gc_wepslot7",gc_wepslot7}, + {"gc_wepslot8",gc_wepslot8}, + {"gc_wepslot9",gc_wepslot9}, + {"gc_wepslot10",gc_wepslot10}, + {"gc_fire",gc_fire}, + {"gc_firenormal",gc_firenormal}, + {"gc_tossflag",gc_tossflag}, + {"gc_spin",gc_spin}, + {"gc_camtoggle",gc_camtoggle}, + {"gc_camreset",gc_camreset}, + {"gc_lookup",gc_lookup}, + {"gc_lookdown",gc_lookdown}, + {"gc_centerview",gc_centerview}, + {"gc_mouseaiming",gc_mouseaiming}, + {"gc_talkkey",gc_talkkey}, + {"gc_teamkey",gc_teamkey}, + {"gc_scores",gc_scores}, + {"gc_jump",gc_jump}, + {"gc_console",gc_console}, + {"gc_pause",gc_pause}, + {"gc_systemmenu",gc_systemmenu}, + {"gc_screenshot",gc_screenshot}, + {"gc_recordgif",gc_recordgif}, + {"gc_viewpoint",gc_viewpoint}, + {"gc_custom1",gc_custom1}, + {"gc_custom2",gc_custom2}, + {"gc_custom3",gc_custom3}, + {"num_gamecontrols",num_gamecontrols}, + {NULL,0} }; diff --git a/src/g_game.c b/src/g_game.c index e46a7f816..823ea7c56 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -406,22 +406,6 @@ consvar_t cv_cam_lockonboss[2] = { CVAR_INIT ("cam2_lockaimassist", "Bosses", CV_SAVE, lockedassist_cons_t, NULL), }; -typedef enum -{ - AXISNONE = 0, - AXISTURN, - AXISMOVE, - AXISLOOK, - AXISSTRAFE, - - AXISDIGITAL, // axes below this use digital deadzone - - AXISJUMP, - AXISSPIN, - AXISFIRE, - AXISFIRENORMAL, -} axis_input_e; - consvar_t cv_turnaxis = CVAR_INIT ("joyaxis_turn", "X-Rudder", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_moveaxis = CVAR_INIT ("joyaxis_move", "Y-Axis", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_sideaxis = CVAR_INIT ("joyaxis_side", "X-Axis", CV_SAVE, joyaxis_cons_t, NULL); @@ -841,7 +825,7 @@ INT16 G_SoftwareClipAimingPitch(INT32 *aiming) return (INT16)((*aiming)>>16); } -static INT32 JoyAxis(axis_input_e axissel) +INT32 JoyAxis(joyaxis_e axissel) { INT32 retaxis; INT32 axisval; @@ -850,28 +834,28 @@ static INT32 JoyAxis(axis_input_e axissel) //find what axis to get switch (axissel) { - case AXISTURN: + case JA_TURN: axisval = cv_turnaxis.value; break; - case AXISMOVE: + case JA_MOVE: axisval = cv_moveaxis.value; break; - case AXISLOOK: + case JA_LOOK: axisval = cv_lookaxis.value; break; - case AXISSTRAFE: + case JA_STRAFE: axisval = cv_sideaxis.value; break; - case AXISJUMP: + case JA_JUMP: axisval = cv_jumpaxis.value; break; - case AXISSPIN: + case JA_SPIN: axisval = cv_spinaxis.value; break; - case AXISFIRE: + case JA_FIRE: axisval = cv_fireaxis.value; break; - case AXISFIRENORMAL: + case JA_FIRENORMAL: axisval = cv_firenaxis.value; break; default: @@ -903,7 +887,7 @@ static INT32 JoyAxis(axis_input_e axissel) if (retaxis > (+JOYAXISRANGE)) retaxis = +JOYAXISRANGE; - if (!Joystick.bGamepadStyle && axissel > AXISDIGITAL) + if (!Joystick.bGamepadStyle && axissel > JA_DIGITAL) { const INT32 jdeadzone = ((JOYAXISRANGE-1) * cv_digitaldeadzone.value) >> FRACBITS; if (-jdeadzone < retaxis && retaxis < jdeadzone) @@ -914,7 +898,7 @@ static INT32 JoyAxis(axis_input_e axissel) return retaxis; } -static INT32 Joy2Axis(axis_input_e axissel) +INT32 Joy2Axis(joyaxis_e axissel) { INT32 retaxis; INT32 axisval; @@ -923,28 +907,28 @@ static INT32 Joy2Axis(axis_input_e axissel) //find what axis to get switch (axissel) { - case AXISTURN: + case JA_TURN: axisval = cv_turnaxis2.value; break; - case AXISMOVE: + case JA_MOVE: axisval = cv_moveaxis2.value; break; - case AXISLOOK: + case JA_LOOK: axisval = cv_lookaxis2.value; break; - case AXISSTRAFE: + case JA_STRAFE: axisval = cv_sideaxis2.value; break; - case AXISJUMP: + case JA_JUMP: axisval = cv_jumpaxis2.value; break; - case AXISSPIN: + case JA_SPIN: axisval = cv_spinaxis2.value; break; - case AXISFIRE: + case JA_FIRE: axisval = cv_fireaxis2.value; break; - case AXISFIRENORMAL: + case JA_FIRENORMAL: axisval = cv_firenaxis2.value; break; default: @@ -978,7 +962,7 @@ static INT32 Joy2Axis(axis_input_e axissel) if (retaxis > (+JOYAXISRANGE)) retaxis = +JOYAXISRANGE; - if (!Joystick2.bGamepadStyle && axissel > AXISDIGITAL) + if (!Joystick2.bGamepadStyle && axissel > JA_DIGITAL) { const INT32 jdeadzone = ((JOYAXISRANGE-1) * cv_digitaldeadzone2.value) >> FRACBITS; if (-jdeadzone < retaxis && retaxis < jdeadzone) @@ -1174,10 +1158,10 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) *myaiming = 0; joyaiming[forplayer] = thisjoyaiming; - turnaxis = PlayerJoyAxis(ssplayer, AXISTURN); + turnaxis = PlayerJoyAxis(ssplayer, JA_TURN); if (strafeisturn) - turnaxis += PlayerJoyAxis(ssplayer, AXISSTRAFE); - lookaxis = PlayerJoyAxis(ssplayer, AXISLOOK); + turnaxis += PlayerJoyAxis(ssplayer, JA_STRAFE); + lookaxis = PlayerJoyAxis(ssplayer, JA_LOOK); lookjoystickvector.xaxis = turnaxis; lookjoystickvector.yaxis = lookaxis; G_HandleAxisDeadZone(forplayer, &lookjoystickvector); @@ -1256,8 +1240,8 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) tta_factor[forplayer] = 0; // suspend turn to angle } - strafeaxis = strafeisturn ? 0 : PlayerJoyAxis(ssplayer, AXISSTRAFE); - moveaxis = PlayerJoyAxis(ssplayer, AXISMOVE); + strafeaxis = strafeisturn ? 0 : PlayerJoyAxis(ssplayer, JA_STRAFE); + moveaxis = PlayerJoyAxis(ssplayer, JA_MOVE); movejoystickvector.xaxis = strafeaxis; movejoystickvector.yaxis = moveaxis; G_HandleAxisDeadZone(forplayer, &movejoystickvector); @@ -1313,12 +1297,12 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) } // fire with any button/key - axis = PlayerJoyAxis(ssplayer, AXISFIRE); + axis = PlayerJoyAxis(ssplayer, JA_FIRE); if (PLAYERINPUTDOWN(ssplayer, gc_fire) || (usejoystick && axis > 0)) cmd->buttons |= BT_ATTACK; // fire normal with any button/key - axis = PlayerJoyAxis(ssplayer, AXISFIRENORMAL); + axis = PlayerJoyAxis(ssplayer, JA_FIRENORMAL); if (PLAYERINPUTDOWN(ssplayer, gc_firenormal) || (usejoystick && axis > 0)) cmd->buttons |= BT_FIRENORMAL; @@ -1334,7 +1318,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) cmd->buttons |= BT_CUSTOM3; // use with any button/key - axis = PlayerJoyAxis(ssplayer, AXISSPIN); + axis = PlayerJoyAxis(ssplayer, JA_SPIN); if (PLAYERINPUTDOWN(ssplayer, gc_spin) || (usejoystick && axis > 0)) cmd->buttons |= BT_SPIN; @@ -1452,7 +1436,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) // jump button - axis = PlayerJoyAxis(ssplayer, AXISJUMP); + axis = PlayerJoyAxis(ssplayer, JA_JUMP); if (PLAYERINPUTDOWN(ssplayer, gc_jump) || (usejoystick && axis > 0)) cmd->buttons |= BT_JUMP; @@ -2191,6 +2175,16 @@ boolean G_Responder(event_t *ev) return false; } +// +// G_LuaResponder +// Let Lua handle key events. +// +boolean G_LuaResponder(event_t *ev) +{ + return (ev->type == ev_keydown && LUAh_KeyDown(ev->data1)) || + (ev->type == ev_keyup && LUAh_KeyUp(ev->data1)); +} + // // G_Ticker // Make ticcmd_ts for the players. diff --git a/src/g_game.h b/src/g_game.h index 744d6755a..0cc380294 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -85,6 +85,25 @@ typedef enum } lockassist_e; +typedef enum +{ + JA_NONE = 0, + JA_TURN, + JA_MOVE, + JA_LOOK, + JA_STRAFE, + + JA_DIGITAL, // axes below this use digital deadzone + + JA_JUMP, + JA_SPIN, + JA_FIRE, + JA_FIRENORMAL, +} joyaxis_e; + +INT32 JoyAxis(joyaxis_e axissel); +INT32 Joy2Axis(joyaxis_e axissel); + // mouseaiming (looking up/down with the mouse or keyboard) #define KB_LOOKSPEED (1<<25) #define MAXPLMOVE (50) @@ -204,6 +223,7 @@ void G_EndGame(void); // moved from y_inter.c/h and renamed void G_Ticker(boolean run); boolean G_Responder(event_t *ev); +boolean G_LuaResponder(event_t *ev); void G_AddPlayer(INT32 playernum); diff --git a/src/g_input.c b/src/g_input.c index 049a4d82c..629b389e5 100644 --- a/src/g_input.c +++ b/src/g_input.c @@ -626,7 +626,7 @@ void G_ClearAllControlKeys(void) // Returns the name of a key (or virtual key for mouse and joy) // the input value being an keynum // -const char *G_KeynumToString(INT32 keynum) +const char *G_KeyNumToString(INT32 keynum) { static char keynamestr[8]; @@ -650,7 +650,7 @@ const char *G_KeynumToString(INT32 keynum) return keynamestr; } -INT32 G_KeyStringtoNum(const char *keystr) +INT32 G_KeyStringToNum(const char *keystr) { UINT32 j; @@ -813,10 +813,10 @@ void G_SaveKeySetting(FILE *f, INT32 (*fromcontrols)[2], INT32 (*fromcontrolsbis for (i = 1; i < num_gamecontrols; i++) { fprintf(f, "setcontrol \"%s\" \"%s\"", gamecontrolname[i], - G_KeynumToString(fromcontrols[i][0])); + G_KeyNumToString(fromcontrols[i][0])); if (fromcontrols[i][1]) - fprintf(f, " \"%s\"\n", G_KeynumToString(fromcontrols[i][1])); + fprintf(f, " \"%s\"\n", G_KeyNumToString(fromcontrols[i][1])); else fprintf(f, "\n"); } @@ -824,10 +824,10 @@ void G_SaveKeySetting(FILE *f, INT32 (*fromcontrols)[2], INT32 (*fromcontrolsbis for (i = 1; i < num_gamecontrols; i++) { fprintf(f, "setcontrol2 \"%s\" \"%s\"", gamecontrolname[i], - G_KeynumToString(fromcontrolsbis[i][0])); + G_KeyNumToString(fromcontrolsbis[i][0])); if (fromcontrolsbis[i][1]) - fprintf(f, " \"%s\"\n", G_KeynumToString(fromcontrolsbis[i][1])); + fprintf(f, " \"%s\"\n", G_KeyNumToString(fromcontrolsbis[i][1])); else fprintf(f, "\n"); } @@ -1003,8 +1003,8 @@ static void setcontrol(INT32 (*gc)[2]) CONS_Printf(M_GetText("Control '%s' unknown\n"), namectrl); return; } - keynum1 = G_KeyStringtoNum(COM_Argv(2)); - keynum2 = G_KeyStringtoNum(COM_Argv(3)); + keynum1 = G_KeyStringToNum(COM_Argv(2)); + keynum2 = G_KeyStringToNum(COM_Argv(3)); keynum = G_FilterKeyByVersion(numctrl, 0, player, &keynum1, &keynum2, &nestedoverride); if (keynum >= 0) diff --git a/src/g_input.h b/src/g_input.h index 5912bfdc7..96139e751 100644 --- a/src/g_input.h +++ b/src/g_input.h @@ -169,8 +169,8 @@ extern const INT32 gcl_jump_spin[num_gcl_jump_spin]; void G_MapEventsToControls(event_t *ev); // returns the name of a key -const char *G_KeynumToString(INT32 keynum); -INT32 G_KeyStringtoNum(const char *keystr); +const char *G_KeyNumToString(INT32 keynum); +INT32 G_KeyStringToNum(const char *keystr); // detach any keys associated to the given game control void G_ClearControlKeys(INT32 (*setupcontrols)[2], INT32 control); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index a59ba546e..71282d09c 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -212,6 +212,8 @@ static const struct { {META_ACTION, "action"}, {META_LUABANKS, "luabanks[]"}, + + {META_MOUSE, "mouse_t"}, {NULL, NULL} }; diff --git a/src/lua_hook.h b/src/lua_hook.h index 0d631aa4e..ae1c17a4d 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -63,6 +63,8 @@ enum hook { hook_MusicChange, hook_PlayerHeight, hook_PlayerCanEnterSpinGaps, + hook_KeyDown, + hook_KeyUp, hook_MAX // last hook }; @@ -122,3 +124,5 @@ boolean LUAh_PlayerCmd(player_t *player, ticcmd_t *cmd); // Hook for building pl boolean LUAh_MusicChange(const char *oldname, char *newname, UINT16 *mflags, boolean *looping, UINT32 *position, UINT32 *prefadems, UINT32 *fadeinms); // Hook for music changes fixed_t LUAh_PlayerHeight(player_t *player); UINT8 LUAh_PlayerCanEnterSpinGaps(player_t *player); +boolean LUAh_KeyDown(INT32 keycode); // Hooks for key events +boolean LUAh_KeyUp(INT32 keycode); diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 637809fd8..8a7ce2cb9 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -79,6 +79,8 @@ const char *const hookNames[hook_MAX+1] = { "MusicChange", "PlayerHeight", "PlayerCanEnterSpinGaps", + "KeyDown", + "KeyUp", NULL }; @@ -2061,3 +2063,73 @@ UINT8 LUAh_PlayerCanEnterSpinGaps(player_t *player) lua_settop(gL, 0); return canEnter; } + +// Hook for key press +boolean LUAh_KeyDown(INT32 keycode) +{ + hook_p hookp; + boolean override = false; + if (!gL || !(hooksAvailable[hook_KeyDown/8] & (1<<(hook_KeyDown%8)))) + return false; + + lua_settop(gL, 0); + lua_pushcfunction(gL, LUA_GetErrorMessage); + + for (hookp = roothook; hookp; hookp = hookp->next) + { + if (hookp->type != hook_KeyDown) + continue; + + PushHook(gL, hookp); + lua_pushinteger(gL, keycode); + if (lua_pcall(gL, 1, 1, 1)) { + if (!hookp->error || cv_debug & DBG_LUA) + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + hookp->error = true; + continue; + } + if (lua_toboolean(gL, -1)) + override = true; + lua_pop(gL, 1); + } + + lua_settop(gL, 0); + + return override; +} + +// Hook for key release +boolean LUAh_KeyUp(INT32 keycode) +{ + hook_p hookp; + boolean override = false; + if (!gL || !(hooksAvailable[hook_KeyUp/8] & (1<<(hook_KeyUp%8)))) + return false; + + lua_settop(gL, 0); + lua_pushcfunction(gL, LUA_GetErrorMessage); + + for (hookp = roothook; hookp; hookp = hookp->next) + { + if (hookp->type != hook_KeyUp) + continue; + + PushHook(gL, hookp); + lua_pushinteger(gL, keycode); + if (lua_pcall(gL, 1, 1, 1)) { + if (!hookp->error || cv_debug & DBG_LUA) + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + hookp->error = true; + continue; + } + if (lua_toboolean(gL, -1)) + override = true; + lua_pop(gL, 1); + } + + lua_settop(gL, 0); + + return override; +} diff --git a/src/lua_inputlib.c b/src/lua_inputlib.c new file mode 100644 index 000000000..1b5991e57 --- /dev/null +++ b/src/lua_inputlib.c @@ -0,0 +1,214 @@ +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 2021 by Sonic Team Junior. +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- +/// \file lua_inputlib.c +/// \brief input library for Lua scripting + +#include "doomdef.h" +#include "fastcmp.h" +#include "g_input.h" +#include "g_game.h" +#include "hu_stuff.h" + +#include "lua_script.h" +#include "lua_libs.h" + +/////////////// +// FUNCTIONS // +/////////////// + +static int lib_gameControlDown(lua_State *L) +{ + int i = luaL_checkinteger(L, 1); + if (i < 0 || i >= num_gamecontrols) + return luaL_error(L, "gc_* constant %d out of range (0 - %d)", i, num_gamecontrols-1); + lua_pushinteger(L, PLAYER1INPUTDOWN(i)); + return 1; +} + +static int lib_gameControl2Down(lua_State *L) +{ + int i = luaL_checkinteger(L, 1); + if (i < 0 || i >= num_gamecontrols) + return luaL_error(L, "gc_* constant %d out of range (0 - %d)", i, num_gamecontrols-1); + lua_pushinteger(L, PLAYER2INPUTDOWN(i)); + return 1; +} + +static int lib_gameControlToKeyNum(lua_State *L) +{ + int i = luaL_checkinteger(L, 1); + if (i < 0 || i >= num_gamecontrols) + return luaL_error(L, "gc_* constant %d out of range (0 - %d)", i, num_gamecontrols-1); + lua_pushinteger(L, gamecontrol[i][0]); + lua_pushinteger(L, gamecontrol[i][1]); + return 2; +} + +static int lib_gameControl2ToKeyNum(lua_State *L) +{ + int i = luaL_checkinteger(L, 1); + if (i < 0 || i >= num_gamecontrols) + return luaL_error(L, "gc_* constant %d out of range (0 - %d)", i, num_gamecontrols-1); + lua_pushinteger(L, gamecontrolbis[i][0]); + lua_pushinteger(L, gamecontrolbis[i][1]); + return 2; +} + +static int lib_joyAxis(lua_State *L) +{ + int i = luaL_checkinteger(L, 1); + lua_pushinteger(L, JoyAxis(i)); + return 1; +} + +static int lib_joy2Axis(lua_State *L) +{ + int i = luaL_checkinteger(L, 1); + lua_pushinteger(L, Joy2Axis(i)); + return 1; +} + +static int lib_keyNumToString(lua_State *L) +{ + int i = luaL_checkinteger(L, 1); + lua_pushstring(L, G_KeyNumToString(i)); + return 1; +} + +static int lib_keyStringToNum(lua_State *L) +{ + const char *str = luaL_checkstring(L, 1); + lua_pushinteger(L, G_KeyStringToNum(str)); + return 1; +} + +static int lib_keyNumPrintable(lua_State *L) +{ + int i = luaL_checkinteger(L, 1); + lua_pushboolean(L, i >= 32 && i <= 127); + return 1; +} + +static int lib_shiftKeyNum(lua_State *L) +{ + int i = luaL_checkinteger(L, 1); + if (i >= 32 && i <= 127) + lua_pushinteger(L, shiftxform[i]); + return 1; +} + +static luaL_Reg lib[] = { + {"G_GameControlDown", lib_gameControlDown}, + {"G_GameControl2Down", lib_gameControl2Down}, + {"G_GameControlToKeyNum", lib_gameControlToKeyNum}, + {"G_GameControl2ToKeyNum", lib_gameControl2ToKeyNum}, + {"G_JoyAxis", lib_joyAxis}, + {"G_Joy2Axis", lib_joy2Axis}, + {"G_KeyNumToString", lib_keyNumToString}, + {"G_KeyStringToNum", lib_keyStringToNum}, + {"HU_KeyNumPrintable", lib_keyNumPrintable}, + {"HU_ShiftKeyNum", lib_shiftKeyNum}, + {NULL, NULL} +}; + +/////////////////// +// gamekeydown[] // +/////////////////// + +static int lib_getGameKeyDown(lua_State *L) +{ + int i = luaL_checkinteger(L, 2); + if (i < 0 || i >= NUMINPUTS) + return luaL_error(L, "gamekeydown[] index %d out of range (0 - %d)", i, NUMINPUTS-1); + lua_pushboolean(L, gamekeydown[i]); + return 1; +} + +static int lib_setGameKeyDown(lua_State *L) +{ + int i = luaL_checkinteger(L, 2); + boolean j = luaL_checkboolean(L, 3); + if (i < 0 || i >= NUMINPUTS) + return luaL_error(L, "gamekeydown[] index %d out of range (0 - %d)", i, NUMINPUTS-1); + gamekeydown[i] = j; + return 0; +} + +static int lib_lenGameKeyDown(lua_State *L) +{ + lua_pushinteger(L, NUMINPUTS); + return 1; +} + +/////////// +// MOUSE // +/////////// + +static int mouse_get(lua_State *L) +{ + mouse_t *m = *((mouse_t **)luaL_checkudata(L, 1, META_MOUSE)); + const char *field = luaL_checkstring(L, 2); + + I_Assert(m != NULL); + + if (fastcmp(field,"dx")) + lua_pushinteger(L, m->dx); + else if (fastcmp(field,"dy")) + lua_pushinteger(L, m->dy); + else if (fastcmp(field,"mlookdy")) + lua_pushinteger(L, m->mlookdy); + else if (fastcmp(field,"rdx")) + lua_pushinteger(L, m->rdx); + else if (fastcmp(field,"rdy")) + lua_pushinteger(L, m->rdy); + else + return luaL_error(L, "mouse_t has no field named %s", field); + + return 1; +} + +// #mouse -> 1 or 2 +static int mouse_num(lua_State *L) +{ + mouse_t *m = *((mouse_t **)luaL_checkudata(L, 1, META_MOUSE)); + + I_Assert(m != NULL); + + lua_pushinteger(L, m == &mouse ? 1 : 2); + return 1; +} + +int LUA_InputLib(lua_State *L) +{ + lua_newuserdata(L, 0); + lua_createtable(L, 0, 2); + lua_pushcfunction(L, lib_getGameKeyDown); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, lib_setGameKeyDown); + lua_setfield(L, -2, "__newindex"); + + lua_pushcfunction(L, lib_lenGameKeyDown); + lua_setfield(L, -2, "__len"); + lua_setmetatable(L, -2); + lua_setglobal(L, "gamekeydown"); + + luaL_newmetatable(L, META_MOUSE); + lua_pushcfunction(L, mouse_get); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, mouse_num); + lua_setfield(L, -2, "__len"); + lua_pop(L, 1); + + // Set global functions + lua_pushvalue(L, LUA_GLOBALSINDEX); + luaL_register(L, NULL, lib); + return 0; +} diff --git a/src/lua_libs.h b/src/lua_libs.h index fbe8d4878..d56c45ab4 100644 --- a/src/lua_libs.h +++ b/src/lua_libs.h @@ -88,6 +88,8 @@ extern lua_State *gL; #define META_LUABANKS "LUABANKS[]*" +#define META_MOUSE "MOUSE_T*" + boolean luaL_checkboolean(lua_State *L, int narg); int LUA_EnumLib(lua_State *L); @@ -106,3 +108,4 @@ int LUA_TagLib(lua_State *L); int LUA_PolyObjLib(lua_State *L); int LUA_BlockmapLib(lua_State *L); int LUA_HudLib(lua_State *L); +int LUA_InputLib(lua_State *L); diff --git a/src/lua_script.c b/src/lua_script.c index 7fd5a98e6..45c18178a 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -20,6 +20,7 @@ #include "r_state.h" #include "r_sky.h" #include "g_game.h" +#include "g_input.h" #include "f_finale.h" #include "byteptr.h" #include "p_saveg.h" @@ -57,6 +58,7 @@ static lua_CFunction liblist[] = { LUA_PolyObjLib, // polyobj_t LUA_BlockmapLib, // blockmap stuff LUA_HudLib, // HUD stuff + LUA_InputLib, // inputs NULL }; @@ -380,6 +382,12 @@ int LUA_PushGlobals(lua_State *L, const char *word) } else if (fastcmp(word, "gamestate")) { lua_pushinteger(L, gamestate); return 1; + } else if (fastcmp(word, "mouse")) { + LUA_PushUserdata(L, &mouse, META_MOUSE); + return 1; + } else if (fastcmp(word, "mouse2")) { + LUA_PushUserdata(L, &mouse2, META_MOUSE); + return 1; } return 0; } @@ -934,6 +942,7 @@ enum ARCH_SLOPE, ARCH_MAPHEADER, ARCH_SKINCOLOR, + ARCH_MOUSE, ARCH_TEND=0xFF, }; @@ -961,6 +970,7 @@ static const struct { {META_SLOPE, ARCH_SLOPE}, {META_MAPHEADER, ARCH_MAPHEADER}, {META_SKINCOLOR, ARCH_SKINCOLOR}, + {META_MOUSE, ARCH_MOUSE}, {NULL, ARCH_NULL} }; @@ -1268,7 +1278,6 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex) } break; } - case ARCH_SKINCOLOR: { skincolor_t *info = *((skincolor_t **)lua_touserdata(gL, myindex)); @@ -1276,6 +1285,13 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex) WRITEUINT16(save_p, info - skincolors); break; } + case ARCH_MOUSE: + { + mouse_t *m = *((mouse_t **)lua_touserdata(gL, myindex)); + WRITEUINT8(save_p, ARCH_MOUSE); + WRITEUINT8(save_p, m == &mouse ? 1 : 2); + break; + } default: WRITEUINT8(save_p, ARCH_NULL); return 2; @@ -1527,6 +1543,9 @@ static UINT8 UnArchiveValue(int TABLESINDEX) case ARCH_SKINCOLOR: LUA_PushUserdata(gL, &skincolors[READUINT16(save_p)], META_SKINCOLOR); break; + case ARCH_MOUSE: + LUA_PushUserdata(gL, READUINT16(save_p) == 1 ? &mouse : &mouse2, META_MOUSE); + break; case ARCH_TEND: return 1; } diff --git a/src/m_menu.c b/src/m_menu.c index 0fca39801..fffe08cd2 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -12683,13 +12683,13 @@ static void M_DrawControl(void) else { if (keys[0] != KEY_NULL) - strcat (tmp, G_KeynumToString (keys[0])); + strcat (tmp, G_KeyNumToString (keys[0])); if (keys[0] != KEY_NULL && keys[1] != KEY_NULL) strcat(tmp," or "); if (keys[1] != KEY_NULL) - strcat (tmp, G_KeynumToString (keys[1])); + strcat (tmp, G_KeyNumToString (keys[1])); } diff --git a/src/sdl/Srb2SDL-vc10.vcxproj b/src/sdl/Srb2SDL-vc10.vcxproj index d46a4af2b..707b5c2d8 100644 --- a/src/sdl/Srb2SDL-vc10.vcxproj +++ b/src/sdl/Srb2SDL-vc10.vcxproj @@ -406,6 +406,7 @@ + diff --git a/src/sdl/Srb2SDL-vc10.vcxproj.filters b/src/sdl/Srb2SDL-vc10.vcxproj.filters index adae2f446..dbc32c502 100644 --- a/src/sdl/Srb2SDL-vc10.vcxproj.filters +++ b/src/sdl/Srb2SDL-vc10.vcxproj.filters @@ -720,6 +720,9 @@ LUA + + LUA + LUA From eb2dc9e99bba9b321a0a1cc6c19071fa756a3d62 Mon Sep 17 00:00:00 2001 From: SwitchKaze Date: Thu, 25 Mar 2021 21:14:59 -0500 Subject: [PATCH 338/644] Mouse improvements --- src/d_main.c | 45 +++++++++++++++++++++++++++++++++++++++++---- src/deh_tables.c | 14 ++++++++++++++ src/g_game.c | 32 ++++++++++++++++++++------------ src/g_input.c | 12 +++--------- src/g_input.h | 14 +++++++++++++- src/i_system.h | 12 ++++++++++++ src/lua_inputlib.c | 28 ++++++++++++++++++++++++++++ src/m_menu.c | 2 +- src/sdl/i_system.c | 2 +- src/sdl/i_video.c | 22 ++++++++++++++++++++-- 10 files changed, 153 insertions(+), 30 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index d60a6cf47..0d21d2531 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -176,8 +176,10 @@ void D_ProcessEvents(void) boolean eaten; // Reset possibly stale mouse info - G_SetMouseData(0, 0, 1); - G_SetMouseData(0, 0, 2); + G_SetMouseDeltas(0, 0, 1); + G_SetMouseDeltas(0, 0, 2); + mouse.buttons &= ~(MB_SCROLLUP|MB_SCROLLDOWN); + mouse2.buttons &= ~(MB_SCROLLUP|MB_SCROLLDOWN); for (; eventtail != eventhead; eventtail = (eventtail+1) & (MAXEVENTS-1)) { @@ -185,6 +187,41 @@ void D_ProcessEvents(void) ev = &events[eventtail]; + // Set mouse buttons early in case event is eaten later + if (ev->type == ev_keydown || ev->type == ev_keyup) + { + // Mouse buttons + if ((UINT32)(ev->data1 - KEY_MOUSE1) < MOUSEBUTTONS) + { + if (ev->type == ev_keydown) + mouse.buttons |= 1 << (ev->data1 - KEY_MOUSE1); + else + mouse.buttons &= ~(1 << (ev->data1 - KEY_MOUSE1)); + } + else if ((UINT32)(ev->data1 - KEY_2MOUSE1) < MOUSEBUTTONS) + { + if (ev->type == ev_keydown) + mouse2.buttons |= 1 << (ev->data1 - KEY_2MOUSE1); + else + mouse2.buttons &= ~(1 << (ev->data1 - KEY_2MOUSE1)); + } + // Scroll (has no keyup event) + else switch (ev->data1) { + case KEY_MOUSEWHEELUP: + mouse.buttons |= MB_SCROLLUP; + break; + case KEY_MOUSEWHEELDOWN: + mouse.buttons |= MB_SCROLLDOWN; + break; + case KEY_2MOUSEWHEELUP: + mouse2.buttons |= MB_SCROLLUP; + break; + case KEY_2MOUSEWHEELDOWN: + mouse2.buttons |= MB_SCROLLDOWN; + break; + } + } + // Screenshots over everything so that they can be taken anywhere. if (M_ScreenshotResponder(ev)) continue; // ate the event @@ -242,9 +279,9 @@ void D_ProcessEvents(void) } if (mouse.rdx || mouse.rdy) - G_SetMouseData(mouse.rdx, mouse.rdy, 1); + G_SetMouseDeltas(mouse.rdx, mouse.rdy, 1); if (mouse2.rdx || mouse2.rdy) - G_SetMouseData(mouse2.rdx, mouse2.rdy, 2); + G_SetMouseDeltas(mouse2.rdx, mouse2.rdy, 2); } // diff --git a/src/deh_tables.c b/src/deh_tables.c index 7bfe723da..79f0d1f11 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -23,6 +23,7 @@ #include "i_sound.h" // musictype_t (for lua) #include "g_state.h" // gamestate_t (for lua) #include "g_game.h" // Joystick axes (for lua) +#include "i_joy.h" #include "g_input.h" // Game controls (for lua) #include "deh_tables.h" @@ -5468,6 +5469,7 @@ struct int_const_s const INT_CONST[] = { {"JA_SPIN",JA_SPIN}, {"JA_FIRE",JA_FIRE}, {"JA_FIRENORMAL",JA_FIRENORMAL}, + {"JOYAXISRANGE",JOYAXISRANGE}, // Game controls {"gc_null",gc_null}, @@ -5514,6 +5516,18 @@ struct int_const_s const INT_CONST[] = { {"gc_custom3",gc_custom3}, {"num_gamecontrols",num_gamecontrols}, + // Mouse buttons + {"MB_BUTTON1",MB_BUTTON1}, + {"MB_BUTTON2",MB_BUTTON2}, + {"MB_BUTTON3",MB_BUTTON3}, + {"MB_BUTTON4",MB_BUTTON4}, + {"MB_BUTTON5",MB_BUTTON5}, + {"MB_BUTTON6",MB_BUTTON6}, + {"MB_BUTTON7",MB_BUTTON7}, + {"MB_BUTTON8",MB_BUTTON8}, + {"MB_SCROLLUP",MB_SCROLLUP}, + {"MB_SCROLLDOWN",MB_SCROLLDOWN}, + {NULL,0} }; diff --git a/src/g_game.c b/src/g_game.c index 823ea7c56..a7fbbd92f 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1078,7 +1078,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) angle_t drawangleoffset = (player->powers[pw_carry] == CR_ROLLOUT) ? ANGLE_180 : 0; INT32 chasecam, chasefreelook, alwaysfreelook, usejoystick, invertmouse, turnmultiplier, mousemove; controlstyle_e controlstyle = G_ControlStyle(ssplayer); - mouse_t *m = &mouse; + INT32 mdx, mdy, mldy; static INT32 turnheld[2]; // for accelerative turning static boolean keyboard_look[2]; // true if lookup/down using keyboard @@ -1101,6 +1101,9 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) invertmouse = cv_invertmouse.value; turnmultiplier = cv_cam_turnmultiplier.value; mousemove = cv_mousemove.value; + mdx = mouse.dx; + mdy = -mouse.dy; + mldy = -mouse.mlookdy; G_CopyTiccmd(cmd, I_BaseTiccmd(), 1); // empty, or external driver } else @@ -1112,10 +1115,15 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) invertmouse = cv_invertmouse2.value; turnmultiplier = cv_cam2_turnmultiplier.value; mousemove = cv_mousemove2.value; - m = &mouse2; + mdx = mouse2.dx; + mdy = -mouse2.dy; + mldy = -mouse2.mlookdy; G_CopyTiccmd(cmd, I_BaseTiccmd2(), 1); // empty, or external driver } + if (menuactive || CON_Ready() || chat_on) + mdx = mdy = mldy = 0; + strafeisturn = controlstyle == CS_SIMPLE && ticcmd_centerviewdown[forplayer] && ((cv_cam_lockedinput[forplayer].value && !ticcmd_ztargetfocus[forplayer]) || (player->pflags & PF_STARTDASH)) && !player->climbing && player->powers[pw_carry] != CR_MINECART; @@ -1455,7 +1463,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) keyboard_look[forplayer] = false; // looking up/down - *myaiming += (m->mlookdy<<19)*player_invert*screen_invert; + *myaiming += (mldy<<19)*player_invert*screen_invert; } if (analogjoystickmove && joyaiming[forplayer] && lookjoystickvector.yaxis != 0 && configlookaxis != 0) @@ -1489,22 +1497,22 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) } if (!mouseaiming && mousemove) - forward += m->dy; + forward += mdy; if ((!demoplayback && (player->pflags & PF_SLIDING))) // Analog for mouse - side += m->dx*2; + side += mdx*2; else if (controlstyle == CS_LMAOGALOG) { - if (m->dx) + if (mdx) { - if (m->dx > 0) + if (mdx > 0) cmd->buttons |= BT_CAMRIGHT; else cmd->buttons |= BT_CAMLEFT; } } else - cmd->angleturn = (INT16)(cmd->angleturn - (m->dx*8)); + cmd->angleturn = (INT16)(cmd->angleturn - (mdx*8)); if (forward > MAXPLMOVE) forward = MAXPLMOVE; @@ -1850,8 +1858,8 @@ void G_DoLoadLevel(boolean resetplayer) joyxmove[i] = joyymove[i] = 0; joy2xmove[i] = joy2ymove[i] = 0; } - G_SetMouseData(0, 0, 1); - G_SetMouseData(0, 0, 2); + G_SetMouseDeltas(0, 0, 1); + G_SetMouseDeltas(0, 0, 2); // clear hud messages remains (usually from game startup) CON_ClearHUD(); @@ -3082,8 +3090,8 @@ void G_DoReborn(INT32 playernum) joyxmove[i] = joyymove[i] = 0; joy2xmove[i] = joy2ymove[i] = 0; } - G_SetMouseData(0, 0, 1); - G_SetMouseData(0, 0, 2); + G_SetMouseDeltas(0, 0, 1); + G_SetMouseDeltas(0, 0, 2); // clear hud messages remains (usually from game startup) CON_ClearHUD(); diff --git a/src/g_input.c b/src/g_input.c index 629b389e5..3e8df9eb0 100644 --- a/src/g_input.c +++ b/src/g_input.c @@ -138,8 +138,6 @@ void G_MapEventsToControls(event_t *ev) break; case ev_mouse: // buttons are virtual keys - if (menuactive || CON_Ready() || chat_on) - break; mouse.rdx = ev->data2; mouse.rdy = ev->data3; break; @@ -1070,19 +1068,15 @@ void Command_Setcontrol2_f(void) setcontrol(gamecontrolbis); } -void G_SetMouseData(INT32 realdx, INT32 realdy, UINT8 ssplayer) +void G_SetMouseDeltas(INT32 dx, INT32 dy, UINT8 ssplayer) { mouse_t *m = ssplayer == 1 ? &mouse : &mouse2; consvar_t *cvsens, *cvysens; - if (!realdx && !realdy) { - memset(m, 0, sizeof(*m)); - return; - } cvsens = ssplayer == 1 ? &cv_mousesens : &cv_mousesens2; cvysens = ssplayer == 1 ? &cv_mouseysens : &cv_mouseysens2; - m->rdx = realdx; - m->rdy = realdy; + m->rdx = dx; + m->rdy = dy; m->dx = (INT32)(m->rdx*((cvsens->value*cvsens->value)/110.0f + 0.1f)); m->dy = (INT32)(m->rdy*((cvsens->value*cvsens->value)/110.0f + 0.1f)); m->mlookdy = (INT32)(m->rdy*((cvysens->value*cvsens->value)/110.0f + 0.1f)); diff --git a/src/g_input.h b/src/g_input.h index 96139e751..6127050ed 100644 --- a/src/g_input.h +++ b/src/g_input.h @@ -123,8 +123,20 @@ typedef struct INT32 mlookdy; // dy with mouselook sensitivity INT32 rdx; // deltas without sensitivity INT32 rdy; + UINT16 buttons; } mouse_t; +#define MB_BUTTON1 0x0001 +#define MB_BUTTON2 0x0002 +#define MB_BUTTON3 0x0004 +#define MB_BUTTON4 0x0008 +#define MB_BUTTON5 0x0010 +#define MB_BUTTON6 0x0020 +#define MB_BUTTON7 0x0040 +#define MB_BUTTON8 0x0080 +#define MB_SCROLLUP 0x0100 +#define MB_SCROLLDOWN 0x0200 + extern mouse_t mouse; extern mouse_t mouse2; @@ -184,6 +196,6 @@ void G_SaveKeySetting(FILE *f, INT32 (*fromcontrols)[2], INT32 (*fromcontrolsbis INT32 G_CheckDoubleUsage(INT32 keynum, boolean modify); // sets the members of a mouse_t given position deltas -void G_SetMouseData(INT32 realdx, INT32 realdy, UINT8 ssplayer); +void G_SetMouseDeltas(INT32 dx, INT32 dy, UINT8 ssplayer); #endif diff --git a/src/i_system.h b/src/i_system.h index 12f0d751d..787be88ee 100644 --- a/src/i_system.h +++ b/src/i_system.h @@ -314,4 +314,16 @@ const char *I_ClipboardPaste(void); void I_RegisterSysCommands(void); +/** \brief Return the position of the cursor relative to the top-left window corner. +*/ +void I_GetCursorPosition(INT32 *x, INT32 *y); + +/** \brief Retursn whether the mouse is grabbed +*/ +boolean I_GetMouseGrab(void); + +/** \brief Sets whether the mouse is grabbed +*/ +void I_SetMouseGrab(boolean grab); + #endif diff --git a/src/lua_inputlib.c b/src/lua_inputlib.c index 1b5991e57..217202222 100644 --- a/src/lua_inputlib.c +++ b/src/lua_inputlib.c @@ -14,6 +14,7 @@ #include "g_input.h" #include "g_game.h" #include "hu_stuff.h" +#include "i_system.h" #include "lua_script.h" #include "lua_libs.h" @@ -103,6 +104,28 @@ static int lib_shiftKeyNum(lua_State *L) return 1; } +static int lib_getMouseGrab(lua_State *L) +{ + lua_pushboolean(L, I_GetMouseGrab()); + return 1; +} + +static int lib_setMouseGrab(lua_State *L) +{ + boolean grab = luaL_checkboolean(L, 1); + I_SetMouseGrab(grab); + return 0; +} + +static boolean lib_getCursorPosition(lua_State *L) +{ + int x, y; + I_GetCursorPosition(&x, &y); + lua_pushinteger(L, x); + lua_pushinteger(L, y); + return 2; +} + static luaL_Reg lib[] = { {"G_GameControlDown", lib_gameControlDown}, {"G_GameControl2Down", lib_gameControl2Down}, @@ -114,6 +137,9 @@ static luaL_Reg lib[] = { {"G_KeyStringToNum", lib_keyStringToNum}, {"HU_KeyNumPrintable", lib_keyNumPrintable}, {"HU_ShiftKeyNum", lib_shiftKeyNum}, + {"I_GetMouseGrab", lib_getMouseGrab}, + {"I_SetMouseGrab", lib_setMouseGrab}, + {"I_GetCursorPosition", lib_getCursorPosition}, {NULL, NULL} }; @@ -167,6 +193,8 @@ static int mouse_get(lua_State *L) lua_pushinteger(L, m->rdx); else if (fastcmp(field,"rdy")) lua_pushinteger(L, m->rdy); + else if (fastcmp(field,"buttons")) + lua_pushinteger(L, m->buttons); else return luaL_error(L, "mouse_t has no field named %s", field); diff --git a/src/m_menu.c b/src/m_menu.c index fffe08cd2..cc495c122 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -3305,7 +3305,7 @@ boolean M_Responder(event_t *ev) } else if (ev->type == ev_mouse && mousewait < I_GetTime()) { - pmousey += ev->data3; + pmousey -= ev->data3; if (pmousey < lasty-30) { ch = KEY_DOWNARROW; diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index a0dd6e1da..bd9d3d9a3 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -1969,7 +1969,7 @@ void I_GetMouseEvents(void) event.data1 = 0; // event.data1 = buttons; // not needed event.data2 = handlermouse2x << 1; - event.data3 = -handlermouse2y << 1; + event.data3 = handlermouse2y << 1; handlermouse2x = 0; handlermouse2y = 0; diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 0ed10463f..20f2c8869 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -405,6 +405,19 @@ void I_UpdateMouseGrab(void) SDLdoGrabMouse(); } +boolean I_GetMouseGrab(void) +{ + return SDL_GetWindowGrab(window); +} + +void I_SetMouseGrab(boolean grab) +{ + if (grab) + SDLdoGrabMouse(); + else + SDLdoUngrabMouse(); +} + static void VID_Command_NumModes_f (void) { CONS_Printf(M_GetText("%d video mode(s) available(s)\n"), VID_NumModes()); @@ -673,8 +686,8 @@ static void Impl_HandleMouseMotionEvent(SDL_MouseMotionEvent evt) { if (SDL_GetMouseFocus() == window && SDL_GetKeyboardFocus() == window) { - mousemovex += evt.xrel; - mousemovey += -evt.yrel; + mousemovex += evt.xrel; + mousemovey += evt.yrel; SDL_SetWindowGrab(window, SDL_TRUE); } firstmove = false; @@ -1938,3 +1951,8 @@ void I_ShutdownGraphics(void) framebuffer = SDL_FALSE; } #endif + +void I_GetCursorPosition(INT32 *x, INT32 *y) +{ + SDL_GetMouseState(x, y); +} From cb3a8f7a58d535f17a9b60166fcd2c9ced3a84cf Mon Sep 17 00:00:00 2001 From: SwitchKaze Date: Thu, 25 Mar 2021 22:21:53 -0500 Subject: [PATCH 339/644] Remove key stuff --- src/console.c | 4 +- src/d_main.c | 17 ------- src/deh_tables.c | 46 ------------------ src/g_game.c | 10 ---- src/g_game.h | 1 - src/g_input.c | 16 +++--- src/g_input.h | 4 +- src/lua_baselib.c | 2 +- src/lua_inputlib.c | 118 --------------------------------------------- src/m_menu.c | 4 +- 10 files changed, 15 insertions(+), 207 deletions(-) diff --git a/src/console.c b/src/console.c index 3b29e9c4f..121605b10 100644 --- a/src/console.c +++ b/src/console.c @@ -221,7 +221,7 @@ static void CONS_Bind_f(void) for (key = 0; key < NUMINPUTS; key++) if (bindtable[key]) { - CONS_Printf("%s : \"%s\"\n", G_KeyNumToString(key), bindtable[key]); + CONS_Printf("%s : \"%s\"\n", G_KeynumToString(key), bindtable[key]); na = 1; } if (!na) @@ -229,7 +229,7 @@ static void CONS_Bind_f(void) return; } - key = G_KeyStringToNum(COM_Argv(1)); + key = G_KeyStringtoNum(COM_Argv(1)); if (key <= 0 || key >= NUMINPUTS) { CONS_Alert(CONS_NOTICE, M_GetText("Invalid key name\n")); diff --git a/src/d_main.c b/src/d_main.c index 0d21d2531..9c95a2ac3 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -183,8 +183,6 @@ void D_ProcessEvents(void) for (; eventtail != eventhead; eventtail = (eventtail+1) & (MAXEVENTS-1)) { - boolean hooked = false; - ev = &events[eventtail]; // Set mouse buttons early in case event is eaten later @@ -232,12 +230,6 @@ void D_ProcessEvents(void) continue; } - if (!CON_Ready() && !menuactive) { - if (G_LuaResponder(ev)) - continue; - hooked = true; - } - // Menu input #ifdef HAVE_THREADS I_lock_mutex(&m_menu_mutex); @@ -252,12 +244,6 @@ void D_ProcessEvents(void) if (eaten) continue; // menu ate the event - if (!hooked && !CON_Ready()) { - if (G_LuaResponder(ev)) - continue; - hooked = true; - } - // console input #ifdef HAVE_THREADS I_lock_mutex(&con_mutex); @@ -272,9 +258,6 @@ void D_ProcessEvents(void) if (eaten) continue; // ate the event - if (!hooked && G_LuaResponder(ev)) - continue; - G_Responder(ev); } diff --git a/src/deh_tables.c b/src/deh_tables.c index 79f0d1f11..4ff193dcd 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -24,7 +24,6 @@ #include "g_state.h" // gamestate_t (for lua) #include "g_game.h" // Joystick axes (for lua) #include "i_joy.h" -#include "g_input.h" // Game controls (for lua) #include "deh_tables.h" @@ -5471,51 +5470,6 @@ struct int_const_s const INT_CONST[] = { {"JA_FIRENORMAL",JA_FIRENORMAL}, {"JOYAXISRANGE",JOYAXISRANGE}, - // Game controls - {"gc_null",gc_null}, - {"gc_forward",gc_forward}, - {"gc_backward",gc_backward}, - {"gc_strafeleft",gc_strafeleft}, - {"gc_straferight",gc_straferight}, - {"gc_turnleft",gc_turnleft}, - {"gc_turnright",gc_turnright}, - {"gc_weaponnext",gc_weaponnext}, - {"gc_weaponprev",gc_weaponprev}, - {"gc_wepslot1",gc_wepslot1}, - {"gc_wepslot2",gc_wepslot2}, - {"gc_wepslot3",gc_wepslot3}, - {"gc_wepslot4",gc_wepslot4}, - {"gc_wepslot5",gc_wepslot5}, - {"gc_wepslot6",gc_wepslot6}, - {"gc_wepslot7",gc_wepslot7}, - {"gc_wepslot8",gc_wepslot8}, - {"gc_wepslot9",gc_wepslot9}, - {"gc_wepslot10",gc_wepslot10}, - {"gc_fire",gc_fire}, - {"gc_firenormal",gc_firenormal}, - {"gc_tossflag",gc_tossflag}, - {"gc_spin",gc_spin}, - {"gc_camtoggle",gc_camtoggle}, - {"gc_camreset",gc_camreset}, - {"gc_lookup",gc_lookup}, - {"gc_lookdown",gc_lookdown}, - {"gc_centerview",gc_centerview}, - {"gc_mouseaiming",gc_mouseaiming}, - {"gc_talkkey",gc_talkkey}, - {"gc_teamkey",gc_teamkey}, - {"gc_scores",gc_scores}, - {"gc_jump",gc_jump}, - {"gc_console",gc_console}, - {"gc_pause",gc_pause}, - {"gc_systemmenu",gc_systemmenu}, - {"gc_screenshot",gc_screenshot}, - {"gc_recordgif",gc_recordgif}, - {"gc_viewpoint",gc_viewpoint}, - {"gc_custom1",gc_custom1}, - {"gc_custom2",gc_custom2}, - {"gc_custom3",gc_custom3}, - {"num_gamecontrols",num_gamecontrols}, - // Mouse buttons {"MB_BUTTON1",MB_BUTTON1}, {"MB_BUTTON2",MB_BUTTON2}, diff --git a/src/g_game.c b/src/g_game.c index a7fbbd92f..1d8eed964 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2183,16 +2183,6 @@ boolean G_Responder(event_t *ev) return false; } -// -// G_LuaResponder -// Let Lua handle key events. -// -boolean G_LuaResponder(event_t *ev) -{ - return (ev->type == ev_keydown && LUAh_KeyDown(ev->data1)) || - (ev->type == ev_keyup && LUAh_KeyUp(ev->data1)); -} - // // G_Ticker // Make ticcmd_ts for the players. diff --git a/src/g_game.h b/src/g_game.h index 0cc380294..ae93adf46 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -223,7 +223,6 @@ void G_EndGame(void); // moved from y_inter.c/h and renamed void G_Ticker(boolean run); boolean G_Responder(event_t *ev); -boolean G_LuaResponder(event_t *ev); void G_AddPlayer(INT32 playernum); diff --git a/src/g_input.c b/src/g_input.c index 3e8df9eb0..cc301e8e5 100644 --- a/src/g_input.c +++ b/src/g_input.c @@ -624,7 +624,7 @@ void G_ClearAllControlKeys(void) // Returns the name of a key (or virtual key for mouse and joy) // the input value being an keynum // -const char *G_KeyNumToString(INT32 keynum) +const char *G_KeynumToString(INT32 keynum) { static char keynamestr[8]; @@ -648,7 +648,7 @@ const char *G_KeyNumToString(INT32 keynum) return keynamestr; } -INT32 G_KeyStringToNum(const char *keystr) +INT32 G_KeyStringtoNum(const char *keystr) { UINT32 j; @@ -811,10 +811,10 @@ void G_SaveKeySetting(FILE *f, INT32 (*fromcontrols)[2], INT32 (*fromcontrolsbis for (i = 1; i < num_gamecontrols; i++) { fprintf(f, "setcontrol \"%s\" \"%s\"", gamecontrolname[i], - G_KeyNumToString(fromcontrols[i][0])); + G_KeynumToString(fromcontrols[i][0])); if (fromcontrols[i][1]) - fprintf(f, " \"%s\"\n", G_KeyNumToString(fromcontrols[i][1])); + fprintf(f, " \"%s\"\n", G_KeynumToString(fromcontrols[i][1])); else fprintf(f, "\n"); } @@ -822,10 +822,10 @@ void G_SaveKeySetting(FILE *f, INT32 (*fromcontrols)[2], INT32 (*fromcontrolsbis for (i = 1; i < num_gamecontrols; i++) { fprintf(f, "setcontrol2 \"%s\" \"%s\"", gamecontrolname[i], - G_KeyNumToString(fromcontrolsbis[i][0])); + G_KeynumToString(fromcontrolsbis[i][0])); if (fromcontrolsbis[i][1]) - fprintf(f, " \"%s\"\n", G_KeyNumToString(fromcontrolsbis[i][1])); + fprintf(f, " \"%s\"\n", G_KeynumToString(fromcontrolsbis[i][1])); else fprintf(f, "\n"); } @@ -1001,8 +1001,8 @@ static void setcontrol(INT32 (*gc)[2]) CONS_Printf(M_GetText("Control '%s' unknown\n"), namectrl); return; } - keynum1 = G_KeyStringToNum(COM_Argv(2)); - keynum2 = G_KeyStringToNum(COM_Argv(3)); + keynum1 = G_KeyStringtoNum(COM_Argv(2)); + keynum2 = G_KeyStringtoNum(COM_Argv(3)); keynum = G_FilterKeyByVersion(numctrl, 0, player, &keynum1, &keynum2, &nestedoverride); if (keynum >= 0) diff --git a/src/g_input.h b/src/g_input.h index 6127050ed..798d888cd 100644 --- a/src/g_input.h +++ b/src/g_input.h @@ -181,8 +181,8 @@ extern const INT32 gcl_jump_spin[num_gcl_jump_spin]; void G_MapEventsToControls(event_t *ev); // returns the name of a key -const char *G_KeyNumToString(INT32 keynum); -INT32 G_KeyStringToNum(const char *keystr); +const char *G_KeynumToString(INT32 keynum); +INT32 G_KeyStringtoNum(const char *keystr); // detach any keys associated to the given game control void G_ClearControlKeys(INT32 (*setupcontrols)[2], INT32 control); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 71282d09c..6d4bde18d 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -212,7 +212,7 @@ static const struct { {META_ACTION, "action"}, {META_LUABANKS, "luabanks[]"}, - + {META_MOUSE, "mouse_t"}, {NULL, NULL} }; diff --git a/src/lua_inputlib.c b/src/lua_inputlib.c index 217202222..875c29e70 100644 --- a/src/lua_inputlib.c +++ b/src/lua_inputlib.c @@ -13,7 +13,6 @@ #include "fastcmp.h" #include "g_input.h" #include "g_game.h" -#include "hu_stuff.h" #include "i_system.h" #include "lua_script.h" @@ -23,44 +22,6 @@ // FUNCTIONS // /////////////// -static int lib_gameControlDown(lua_State *L) -{ - int i = luaL_checkinteger(L, 1); - if (i < 0 || i >= num_gamecontrols) - return luaL_error(L, "gc_* constant %d out of range (0 - %d)", i, num_gamecontrols-1); - lua_pushinteger(L, PLAYER1INPUTDOWN(i)); - return 1; -} - -static int lib_gameControl2Down(lua_State *L) -{ - int i = luaL_checkinteger(L, 1); - if (i < 0 || i >= num_gamecontrols) - return luaL_error(L, "gc_* constant %d out of range (0 - %d)", i, num_gamecontrols-1); - lua_pushinteger(L, PLAYER2INPUTDOWN(i)); - return 1; -} - -static int lib_gameControlToKeyNum(lua_State *L) -{ - int i = luaL_checkinteger(L, 1); - if (i < 0 || i >= num_gamecontrols) - return luaL_error(L, "gc_* constant %d out of range (0 - %d)", i, num_gamecontrols-1); - lua_pushinteger(L, gamecontrol[i][0]); - lua_pushinteger(L, gamecontrol[i][1]); - return 2; -} - -static int lib_gameControl2ToKeyNum(lua_State *L) -{ - int i = luaL_checkinteger(L, 1); - if (i < 0 || i >= num_gamecontrols) - return luaL_error(L, "gc_* constant %d out of range (0 - %d)", i, num_gamecontrols-1); - lua_pushinteger(L, gamecontrolbis[i][0]); - lua_pushinteger(L, gamecontrolbis[i][1]); - return 2; -} - static int lib_joyAxis(lua_State *L) { int i = luaL_checkinteger(L, 1); @@ -75,35 +36,6 @@ static int lib_joy2Axis(lua_State *L) return 1; } -static int lib_keyNumToString(lua_State *L) -{ - int i = luaL_checkinteger(L, 1); - lua_pushstring(L, G_KeyNumToString(i)); - return 1; -} - -static int lib_keyStringToNum(lua_State *L) -{ - const char *str = luaL_checkstring(L, 1); - lua_pushinteger(L, G_KeyStringToNum(str)); - return 1; -} - -static int lib_keyNumPrintable(lua_State *L) -{ - int i = luaL_checkinteger(L, 1); - lua_pushboolean(L, i >= 32 && i <= 127); - return 1; -} - -static int lib_shiftKeyNum(lua_State *L) -{ - int i = luaL_checkinteger(L, 1); - if (i >= 32 && i <= 127) - lua_pushinteger(L, shiftxform[i]); - return 1; -} - static int lib_getMouseGrab(lua_State *L) { lua_pushboolean(L, I_GetMouseGrab()); @@ -127,51 +59,14 @@ static boolean lib_getCursorPosition(lua_State *L) } static luaL_Reg lib[] = { - {"G_GameControlDown", lib_gameControlDown}, - {"G_GameControl2Down", lib_gameControl2Down}, - {"G_GameControlToKeyNum", lib_gameControlToKeyNum}, - {"G_GameControl2ToKeyNum", lib_gameControl2ToKeyNum}, {"G_JoyAxis", lib_joyAxis}, {"G_Joy2Axis", lib_joy2Axis}, - {"G_KeyNumToString", lib_keyNumToString}, - {"G_KeyStringToNum", lib_keyStringToNum}, - {"HU_KeyNumPrintable", lib_keyNumPrintable}, - {"HU_ShiftKeyNum", lib_shiftKeyNum}, {"I_GetMouseGrab", lib_getMouseGrab}, {"I_SetMouseGrab", lib_setMouseGrab}, {"I_GetCursorPosition", lib_getCursorPosition}, {NULL, NULL} }; -/////////////////// -// gamekeydown[] // -/////////////////// - -static int lib_getGameKeyDown(lua_State *L) -{ - int i = luaL_checkinteger(L, 2); - if (i < 0 || i >= NUMINPUTS) - return luaL_error(L, "gamekeydown[] index %d out of range (0 - %d)", i, NUMINPUTS-1); - lua_pushboolean(L, gamekeydown[i]); - return 1; -} - -static int lib_setGameKeyDown(lua_State *L) -{ - int i = luaL_checkinteger(L, 2); - boolean j = luaL_checkboolean(L, 3); - if (i < 0 || i >= NUMINPUTS) - return luaL_error(L, "gamekeydown[] index %d out of range (0 - %d)", i, NUMINPUTS-1); - gamekeydown[i] = j; - return 0; -} - -static int lib_lenGameKeyDown(lua_State *L) -{ - lua_pushinteger(L, NUMINPUTS); - return 1; -} - /////////// // MOUSE // /////////// @@ -214,19 +109,6 @@ static int mouse_num(lua_State *L) int LUA_InputLib(lua_State *L) { - lua_newuserdata(L, 0); - lua_createtable(L, 0, 2); - lua_pushcfunction(L, lib_getGameKeyDown); - lua_setfield(L, -2, "__index"); - - lua_pushcfunction(L, lib_setGameKeyDown); - lua_setfield(L, -2, "__newindex"); - - lua_pushcfunction(L, lib_lenGameKeyDown); - lua_setfield(L, -2, "__len"); - lua_setmetatable(L, -2); - lua_setglobal(L, "gamekeydown"); - luaL_newmetatable(L, META_MOUSE); lua_pushcfunction(L, mouse_get); lua_setfield(L, -2, "__index"); diff --git a/src/m_menu.c b/src/m_menu.c index cc495c122..be7fa8a7d 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -12683,13 +12683,13 @@ static void M_DrawControl(void) else { if (keys[0] != KEY_NULL) - strcat (tmp, G_KeyNumToString (keys[0])); + strcat (tmp, G_KeynumToString (keys[0])); if (keys[0] != KEY_NULL && keys[1] != KEY_NULL) strcat(tmp," or "); if (keys[1] != KEY_NULL) - strcat (tmp, G_KeyNumToString (keys[1])); + strcat (tmp, G_KeynumToString (keys[1])); } From 5a247bf375b7b1c973a52d702c37cf48de628fea Mon Sep 17 00:00:00 2001 From: SwitchKaze Date: Thu, 25 Mar 2021 23:29:42 -0500 Subject: [PATCH 340/644] Fix typo in comment of I_GetMouseGrab --- src/i_system.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i_system.h b/src/i_system.h index 787be88ee..3f46eb592 100644 --- a/src/i_system.h +++ b/src/i_system.h @@ -318,7 +318,7 @@ void I_RegisterSysCommands(void); */ void I_GetCursorPosition(INT32 *x, INT32 *y); -/** \brief Retursn whether the mouse is grabbed +/** \brief Returns whether the mouse is grabbed */ boolean I_GetMouseGrab(void); From 0db07cef0ebac2f4d006094fe1b99b061bedfd57 Mon Sep 17 00:00:00 2001 From: SwitchKaze Date: Fri, 26 Mar 2021 02:03:52 -0500 Subject: [PATCH 341/644] Adjust joystick axis enum --- src/g_game.c | 4 ++-- src/g_game.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 1d8eed964..d8b615cbc 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -887,7 +887,7 @@ INT32 JoyAxis(joyaxis_e axissel) if (retaxis > (+JOYAXISRANGE)) retaxis = +JOYAXISRANGE; - if (!Joystick.bGamepadStyle && axissel > JA_DIGITAL) + if (!Joystick.bGamepadStyle && axissel >= JA_DIGITAL) { const INT32 jdeadzone = ((JOYAXISRANGE-1) * cv_digitaldeadzone.value) >> FRACBITS; if (-jdeadzone < retaxis && retaxis < jdeadzone) @@ -962,7 +962,7 @@ INT32 Joy2Axis(joyaxis_e axissel) if (retaxis > (+JOYAXISRANGE)) retaxis = +JOYAXISRANGE; - if (!Joystick2.bGamepadStyle && axissel > JA_DIGITAL) + if (!Joystick2.bGamepadStyle && axissel >= JA_DIGITAL) { const INT32 jdeadzone = ((JOYAXISRANGE-1) * cv_digitaldeadzone2.value) >> FRACBITS; if (-jdeadzone < retaxis && retaxis < jdeadzone) diff --git a/src/g_game.h b/src/g_game.h index ae93adf46..c7fdad3ac 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -93,9 +93,9 @@ typedef enum JA_LOOK, JA_STRAFE, - JA_DIGITAL, // axes below this use digital deadzone + JA_DIGITAL, // axes henceforth use digital deadzone - JA_JUMP, + JA_JUMP = JA_DIGITAL, JA_SPIN, JA_FIRE, JA_FIRENORMAL, From 3895c023308c0ff71194531ce071860ad40764ae Mon Sep 17 00:00:00 2001 From: SwitchKaze Date: Thu, 1 Apr 2021 13:19:50 -0500 Subject: [PATCH 342/644] Revert "Remove key stuff" This reverts commit a439e569 --- src/console.c | 4 +- src/d_main.c | 17 +++++++ src/deh_tables.c | 46 ++++++++++++++++++ src/g_game.c | 10 ++++ src/g_game.h | 1 + src/g_input.c | 16 +++--- src/g_input.h | 4 +- src/lua_hooklib.c | 2 +- src/lua_inputlib.c | 118 +++++++++++++++++++++++++++++++++++++++++++++ src/m_menu.c | 4 +- 10 files changed, 207 insertions(+), 15 deletions(-) diff --git a/src/console.c b/src/console.c index 121605b10..3b29e9c4f 100644 --- a/src/console.c +++ b/src/console.c @@ -221,7 +221,7 @@ static void CONS_Bind_f(void) for (key = 0; key < NUMINPUTS; key++) if (bindtable[key]) { - CONS_Printf("%s : \"%s\"\n", G_KeynumToString(key), bindtable[key]); + CONS_Printf("%s : \"%s\"\n", G_KeyNumToString(key), bindtable[key]); na = 1; } if (!na) @@ -229,7 +229,7 @@ static void CONS_Bind_f(void) return; } - key = G_KeyStringtoNum(COM_Argv(1)); + key = G_KeyStringToNum(COM_Argv(1)); if (key <= 0 || key >= NUMINPUTS) { CONS_Alert(CONS_NOTICE, M_GetText("Invalid key name\n")); diff --git a/src/d_main.c b/src/d_main.c index 9c95a2ac3..0d21d2531 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -183,6 +183,8 @@ void D_ProcessEvents(void) for (; eventtail != eventhead; eventtail = (eventtail+1) & (MAXEVENTS-1)) { + boolean hooked = false; + ev = &events[eventtail]; // Set mouse buttons early in case event is eaten later @@ -230,6 +232,12 @@ void D_ProcessEvents(void) continue; } + if (!CON_Ready() && !menuactive) { + if (G_LuaResponder(ev)) + continue; + hooked = true; + } + // Menu input #ifdef HAVE_THREADS I_lock_mutex(&m_menu_mutex); @@ -244,6 +252,12 @@ void D_ProcessEvents(void) if (eaten) continue; // menu ate the event + if (!hooked && !CON_Ready()) { + if (G_LuaResponder(ev)) + continue; + hooked = true; + } + // console input #ifdef HAVE_THREADS I_lock_mutex(&con_mutex); @@ -258,6 +272,9 @@ void D_ProcessEvents(void) if (eaten) continue; // ate the event + if (!hooked && G_LuaResponder(ev)) + continue; + G_Responder(ev); } diff --git a/src/deh_tables.c b/src/deh_tables.c index 4ff193dcd..79f0d1f11 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -24,6 +24,7 @@ #include "g_state.h" // gamestate_t (for lua) #include "g_game.h" // Joystick axes (for lua) #include "i_joy.h" +#include "g_input.h" // Game controls (for lua) #include "deh_tables.h" @@ -5470,6 +5471,51 @@ struct int_const_s const INT_CONST[] = { {"JA_FIRENORMAL",JA_FIRENORMAL}, {"JOYAXISRANGE",JOYAXISRANGE}, + // Game controls + {"gc_null",gc_null}, + {"gc_forward",gc_forward}, + {"gc_backward",gc_backward}, + {"gc_strafeleft",gc_strafeleft}, + {"gc_straferight",gc_straferight}, + {"gc_turnleft",gc_turnleft}, + {"gc_turnright",gc_turnright}, + {"gc_weaponnext",gc_weaponnext}, + {"gc_weaponprev",gc_weaponprev}, + {"gc_wepslot1",gc_wepslot1}, + {"gc_wepslot2",gc_wepslot2}, + {"gc_wepslot3",gc_wepslot3}, + {"gc_wepslot4",gc_wepslot4}, + {"gc_wepslot5",gc_wepslot5}, + {"gc_wepslot6",gc_wepslot6}, + {"gc_wepslot7",gc_wepslot7}, + {"gc_wepslot8",gc_wepslot8}, + {"gc_wepslot9",gc_wepslot9}, + {"gc_wepslot10",gc_wepslot10}, + {"gc_fire",gc_fire}, + {"gc_firenormal",gc_firenormal}, + {"gc_tossflag",gc_tossflag}, + {"gc_spin",gc_spin}, + {"gc_camtoggle",gc_camtoggle}, + {"gc_camreset",gc_camreset}, + {"gc_lookup",gc_lookup}, + {"gc_lookdown",gc_lookdown}, + {"gc_centerview",gc_centerview}, + {"gc_mouseaiming",gc_mouseaiming}, + {"gc_talkkey",gc_talkkey}, + {"gc_teamkey",gc_teamkey}, + {"gc_scores",gc_scores}, + {"gc_jump",gc_jump}, + {"gc_console",gc_console}, + {"gc_pause",gc_pause}, + {"gc_systemmenu",gc_systemmenu}, + {"gc_screenshot",gc_screenshot}, + {"gc_recordgif",gc_recordgif}, + {"gc_viewpoint",gc_viewpoint}, + {"gc_custom1",gc_custom1}, + {"gc_custom2",gc_custom2}, + {"gc_custom3",gc_custom3}, + {"num_gamecontrols",num_gamecontrols}, + // Mouse buttons {"MB_BUTTON1",MB_BUTTON1}, {"MB_BUTTON2",MB_BUTTON2}, diff --git a/src/g_game.c b/src/g_game.c index d8b615cbc..5939cfe3b 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2183,6 +2183,16 @@ boolean G_Responder(event_t *ev) return false; } +// +// G_LuaResponder +// Let Lua handle key events. +// +boolean G_LuaResponder(event_t *ev) +{ + return (ev->type == ev_keydown && LUAh_KeyDown(ev->data1)) || + (ev->type == ev_keyup && LUAh_KeyUp(ev->data1)); +} + // // G_Ticker // Make ticcmd_ts for the players. diff --git a/src/g_game.h b/src/g_game.h index c7fdad3ac..00958abd0 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -223,6 +223,7 @@ void G_EndGame(void); // moved from y_inter.c/h and renamed void G_Ticker(boolean run); boolean G_Responder(event_t *ev); +boolean G_LuaResponder(event_t *ev); void G_AddPlayer(INT32 playernum); diff --git a/src/g_input.c b/src/g_input.c index cc301e8e5..3e8df9eb0 100644 --- a/src/g_input.c +++ b/src/g_input.c @@ -624,7 +624,7 @@ void G_ClearAllControlKeys(void) // Returns the name of a key (or virtual key for mouse and joy) // the input value being an keynum // -const char *G_KeynumToString(INT32 keynum) +const char *G_KeyNumToString(INT32 keynum) { static char keynamestr[8]; @@ -648,7 +648,7 @@ const char *G_KeynumToString(INT32 keynum) return keynamestr; } -INT32 G_KeyStringtoNum(const char *keystr) +INT32 G_KeyStringToNum(const char *keystr) { UINT32 j; @@ -811,10 +811,10 @@ void G_SaveKeySetting(FILE *f, INT32 (*fromcontrols)[2], INT32 (*fromcontrolsbis for (i = 1; i < num_gamecontrols; i++) { fprintf(f, "setcontrol \"%s\" \"%s\"", gamecontrolname[i], - G_KeynumToString(fromcontrols[i][0])); + G_KeyNumToString(fromcontrols[i][0])); if (fromcontrols[i][1]) - fprintf(f, " \"%s\"\n", G_KeynumToString(fromcontrols[i][1])); + fprintf(f, " \"%s\"\n", G_KeyNumToString(fromcontrols[i][1])); else fprintf(f, "\n"); } @@ -822,10 +822,10 @@ void G_SaveKeySetting(FILE *f, INT32 (*fromcontrols)[2], INT32 (*fromcontrolsbis for (i = 1; i < num_gamecontrols; i++) { fprintf(f, "setcontrol2 \"%s\" \"%s\"", gamecontrolname[i], - G_KeynumToString(fromcontrolsbis[i][0])); + G_KeyNumToString(fromcontrolsbis[i][0])); if (fromcontrolsbis[i][1]) - fprintf(f, " \"%s\"\n", G_KeynumToString(fromcontrolsbis[i][1])); + fprintf(f, " \"%s\"\n", G_KeyNumToString(fromcontrolsbis[i][1])); else fprintf(f, "\n"); } @@ -1001,8 +1001,8 @@ static void setcontrol(INT32 (*gc)[2]) CONS_Printf(M_GetText("Control '%s' unknown\n"), namectrl); return; } - keynum1 = G_KeyStringtoNum(COM_Argv(2)); - keynum2 = G_KeyStringtoNum(COM_Argv(3)); + keynum1 = G_KeyStringToNum(COM_Argv(2)); + keynum2 = G_KeyStringToNum(COM_Argv(3)); keynum = G_FilterKeyByVersion(numctrl, 0, player, &keynum1, &keynum2, &nestedoverride); if (keynum >= 0) diff --git a/src/g_input.h b/src/g_input.h index 798d888cd..6127050ed 100644 --- a/src/g_input.h +++ b/src/g_input.h @@ -181,8 +181,8 @@ extern const INT32 gcl_jump_spin[num_gcl_jump_spin]; void G_MapEventsToControls(event_t *ev); // returns the name of a key -const char *G_KeynumToString(INT32 keynum); -INT32 G_KeyStringtoNum(const char *keystr); +const char *G_KeyNumToString(INT32 keynum); +INT32 G_KeyStringToNum(const char *keystr); // detach any keys associated to the given game control void G_ClearControlKeys(INT32 (*setupcontrols)[2], INT32 control); diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 8a7ce2cb9..28ae487b9 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -1944,7 +1944,7 @@ boolean LUAh_MusicChange(const char *oldname, char *newname, UINT16 *mflags, boo lua_pushinteger(gL, *prefadems); lua_pushinteger(gL, *fadeinms); if (lua_pcall(gL, 7, 6, 1)) { - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1)); + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); continue; } diff --git a/src/lua_inputlib.c b/src/lua_inputlib.c index 875c29e70..217202222 100644 --- a/src/lua_inputlib.c +++ b/src/lua_inputlib.c @@ -13,6 +13,7 @@ #include "fastcmp.h" #include "g_input.h" #include "g_game.h" +#include "hu_stuff.h" #include "i_system.h" #include "lua_script.h" @@ -22,6 +23,44 @@ // FUNCTIONS // /////////////// +static int lib_gameControlDown(lua_State *L) +{ + int i = luaL_checkinteger(L, 1); + if (i < 0 || i >= num_gamecontrols) + return luaL_error(L, "gc_* constant %d out of range (0 - %d)", i, num_gamecontrols-1); + lua_pushinteger(L, PLAYER1INPUTDOWN(i)); + return 1; +} + +static int lib_gameControl2Down(lua_State *L) +{ + int i = luaL_checkinteger(L, 1); + if (i < 0 || i >= num_gamecontrols) + return luaL_error(L, "gc_* constant %d out of range (0 - %d)", i, num_gamecontrols-1); + lua_pushinteger(L, PLAYER2INPUTDOWN(i)); + return 1; +} + +static int lib_gameControlToKeyNum(lua_State *L) +{ + int i = luaL_checkinteger(L, 1); + if (i < 0 || i >= num_gamecontrols) + return luaL_error(L, "gc_* constant %d out of range (0 - %d)", i, num_gamecontrols-1); + lua_pushinteger(L, gamecontrol[i][0]); + lua_pushinteger(L, gamecontrol[i][1]); + return 2; +} + +static int lib_gameControl2ToKeyNum(lua_State *L) +{ + int i = luaL_checkinteger(L, 1); + if (i < 0 || i >= num_gamecontrols) + return luaL_error(L, "gc_* constant %d out of range (0 - %d)", i, num_gamecontrols-1); + lua_pushinteger(L, gamecontrolbis[i][0]); + lua_pushinteger(L, gamecontrolbis[i][1]); + return 2; +} + static int lib_joyAxis(lua_State *L) { int i = luaL_checkinteger(L, 1); @@ -36,6 +75,35 @@ static int lib_joy2Axis(lua_State *L) return 1; } +static int lib_keyNumToString(lua_State *L) +{ + int i = luaL_checkinteger(L, 1); + lua_pushstring(L, G_KeyNumToString(i)); + return 1; +} + +static int lib_keyStringToNum(lua_State *L) +{ + const char *str = luaL_checkstring(L, 1); + lua_pushinteger(L, G_KeyStringToNum(str)); + return 1; +} + +static int lib_keyNumPrintable(lua_State *L) +{ + int i = luaL_checkinteger(L, 1); + lua_pushboolean(L, i >= 32 && i <= 127); + return 1; +} + +static int lib_shiftKeyNum(lua_State *L) +{ + int i = luaL_checkinteger(L, 1); + if (i >= 32 && i <= 127) + lua_pushinteger(L, shiftxform[i]); + return 1; +} + static int lib_getMouseGrab(lua_State *L) { lua_pushboolean(L, I_GetMouseGrab()); @@ -59,14 +127,51 @@ static boolean lib_getCursorPosition(lua_State *L) } static luaL_Reg lib[] = { + {"G_GameControlDown", lib_gameControlDown}, + {"G_GameControl2Down", lib_gameControl2Down}, + {"G_GameControlToKeyNum", lib_gameControlToKeyNum}, + {"G_GameControl2ToKeyNum", lib_gameControl2ToKeyNum}, {"G_JoyAxis", lib_joyAxis}, {"G_Joy2Axis", lib_joy2Axis}, + {"G_KeyNumToString", lib_keyNumToString}, + {"G_KeyStringToNum", lib_keyStringToNum}, + {"HU_KeyNumPrintable", lib_keyNumPrintable}, + {"HU_ShiftKeyNum", lib_shiftKeyNum}, {"I_GetMouseGrab", lib_getMouseGrab}, {"I_SetMouseGrab", lib_setMouseGrab}, {"I_GetCursorPosition", lib_getCursorPosition}, {NULL, NULL} }; +/////////////////// +// gamekeydown[] // +/////////////////// + +static int lib_getGameKeyDown(lua_State *L) +{ + int i = luaL_checkinteger(L, 2); + if (i < 0 || i >= NUMINPUTS) + return luaL_error(L, "gamekeydown[] index %d out of range (0 - %d)", i, NUMINPUTS-1); + lua_pushboolean(L, gamekeydown[i]); + return 1; +} + +static int lib_setGameKeyDown(lua_State *L) +{ + int i = luaL_checkinteger(L, 2); + boolean j = luaL_checkboolean(L, 3); + if (i < 0 || i >= NUMINPUTS) + return luaL_error(L, "gamekeydown[] index %d out of range (0 - %d)", i, NUMINPUTS-1); + gamekeydown[i] = j; + return 0; +} + +static int lib_lenGameKeyDown(lua_State *L) +{ + lua_pushinteger(L, NUMINPUTS); + return 1; +} + /////////// // MOUSE // /////////// @@ -109,6 +214,19 @@ static int mouse_num(lua_State *L) int LUA_InputLib(lua_State *L) { + lua_newuserdata(L, 0); + lua_createtable(L, 0, 2); + lua_pushcfunction(L, lib_getGameKeyDown); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, lib_setGameKeyDown); + lua_setfield(L, -2, "__newindex"); + + lua_pushcfunction(L, lib_lenGameKeyDown); + lua_setfield(L, -2, "__len"); + lua_setmetatable(L, -2); + lua_setglobal(L, "gamekeydown"); + luaL_newmetatable(L, META_MOUSE); lua_pushcfunction(L, mouse_get); lua_setfield(L, -2, "__index"); diff --git a/src/m_menu.c b/src/m_menu.c index be7fa8a7d..cc495c122 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -12683,13 +12683,13 @@ static void M_DrawControl(void) else { if (keys[0] != KEY_NULL) - strcat (tmp, G_KeynumToString (keys[0])); + strcat (tmp, G_KeyNumToString (keys[0])); if (keys[0] != KEY_NULL && keys[1] != KEY_NULL) strcat(tmp," or "); if (keys[1] != KEY_NULL) - strcat (tmp, G_KeynumToString (keys[1])); + strcat (tmp, G_KeyNumToString (keys[1])); } From 57c7a18a20b3049a47bc4bf6a3cc8fc678085e6f Mon Sep 17 00:00:00 2001 From: katsy Date: Fri, 2 Apr 2021 20:50:56 -0400 Subject: [PATCH 343/644] don't say we launched if we didn't actually launch --- src/p_slopes.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/p_slopes.c b/src/p_slopes.c index e93b0f6c9..bd0f15d2e 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -777,13 +777,13 @@ void P_SlopeLaunch(mobj_t *mo) mo->momx = slopemom.x; mo->momy = slopemom.y; mo->momz = slopemom.z/2; + + if (mo->player) + mo->player->powers[pw_justlaunched] = 1; } //CONS_Printf("Launched off of slope.\n"); mo->standingslope = NULL; - - if (mo->player) - mo->player->powers[pw_justlaunched] = 1; } // From e9213b2b41fd60b2331ccad987409786fd337499 Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Sun, 4 Apr 2021 21:29:15 +0300 Subject: [PATCH 344/644] Fix a OpenGL backend DeleteTexture crash --- src/hardware/r_opengl/r_opengl.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 6967bab74..064457c03 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -1301,8 +1301,12 @@ EXPORT void HWRAPI(DeleteTexture) (GLMipmap_t *pTexInfo) { if (head->next) head->next->prev = head->prev; + else // no next -> tail is being deleted -> update TexCacheTail + TexCacheTail = head->prev; if (head->prev) head->prev->next = head->next; + else // no prev -> head is being deleted -> update TexCacheHead + TexCacheHead = head->next; free(head); break; } From 84191252d2c5116b19fc17066e9e313fefa47223 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 4 Apr 2021 17:01:54 -0700 Subject: [PATCH 345/644] Remove code that converts uppercase letters to lower, when coming from dedicated console --- src/console.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/console.c b/src/console.c index 121605b10..1560220f6 100644 --- a/src/console.c +++ b/src/console.c @@ -1303,10 +1303,6 @@ boolean CON_Responder(event_t *ev) if (key < 32 || key > 127) return true; - // add key to cmd line here - if (key >= 'A' && key <= 'Z' && !(shiftdown ^ capslock)) //this is only really necessary for dedicated servers - key = key + 'a' - 'A'; - if (input_sel != input_cur) CON_InputDelSelection(); CON_InputAddChar(key); From 5b2abfa18d672a37320fb3a2cbcb2bba01e5c670 Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Sun, 28 Mar 2021 20:16:17 -0500 Subject: [PATCH 346/644] Replace some decimal constants with more descriptive hex constants. --- src/r_draw8.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/r_draw8.c b/src/r_draw8.c index 1f451115e..4a72dcda4 100644 --- a/src/r_draw8.c +++ b/src/r_draw8.c @@ -1227,8 +1227,9 @@ void R_DrawSplat_8 (void) // need! // // 4194303 = (2048x2048)-1 (2048x2048 is maximum flat size) + // Why decimal? 0x3FFFF == 4194303... ~Golden val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); - val &= 4194303; + val &= 0x3FFFF; val = source[val]; if (val != TRANSPARENTPIXEL) dest[0] = colormap[val]; @@ -1236,7 +1237,7 @@ void R_DrawSplat_8 (void) yposition += ystep; val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); - val &= 4194303; + val &= 0x3FFFF; val = source[val]; if (val != TRANSPARENTPIXEL) dest[1] = colormap[val]; @@ -1244,7 +1245,7 @@ void R_DrawSplat_8 (void) yposition += ystep; val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); - val &= 4194303; + val &= 0x3FFFF; val = source[val]; if (val != TRANSPARENTPIXEL) dest[2] = colormap[val]; @@ -1252,7 +1253,7 @@ void R_DrawSplat_8 (void) yposition += ystep; val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); - val &= 4194303; + val &= 0x3FFFF; val = source[val]; if (val != TRANSPARENTPIXEL) dest[3] = colormap[val]; @@ -1260,7 +1261,7 @@ void R_DrawSplat_8 (void) yposition += ystep; val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); - val &= 4194303; + val &= 0x3FFFF; val = source[val]; if (val != TRANSPARENTPIXEL) dest[4] = colormap[val]; @@ -1268,7 +1269,7 @@ void R_DrawSplat_8 (void) yposition += ystep; val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); - val &= 4194303; + val &= 0x3FFFF; val = source[val]; if (val != TRANSPARENTPIXEL) dest[5] = colormap[val]; @@ -1276,7 +1277,7 @@ void R_DrawSplat_8 (void) yposition += ystep; val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); - val &= 4194303; + val &= 0x3FFFF; val = source[val]; if (val != TRANSPARENTPIXEL) dest[6] = colormap[val]; @@ -1284,7 +1285,7 @@ void R_DrawSplat_8 (void) yposition += ystep; val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); - val &= 4194303; + val &= 0x3FFFF; val = source[val]; if (val != TRANSPARENTPIXEL) dest[7] = colormap[val]; From 776ce2a7506037b528fb7ce4acd81f22f3718582 Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Sun, 28 Mar 2021 20:22:57 -0500 Subject: [PATCH 347/644] bruh i messed up --- src/r_draw8.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/r_draw8.c b/src/r_draw8.c index 4a72dcda4..b4c1491a0 100644 --- a/src/r_draw8.c +++ b/src/r_draw8.c @@ -1227,9 +1227,9 @@ void R_DrawSplat_8 (void) // need! // // 4194303 = (2048x2048)-1 (2048x2048 is maximum flat size) - // Why decimal? 0x3FFFF == 4194303... ~Golden + // Why decimal? 0x3FFFFF == 4194303... ~Golden val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); - val &= 0x3FFFF; + val &= 0x3FFFFF; val = source[val]; if (val != TRANSPARENTPIXEL) dest[0] = colormap[val]; @@ -1237,7 +1237,7 @@ void R_DrawSplat_8 (void) yposition += ystep; val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); - val &= 0x3FFFF; + val &= 0x3FFFFF; val = source[val]; if (val != TRANSPARENTPIXEL) dest[1] = colormap[val]; @@ -1245,7 +1245,7 @@ void R_DrawSplat_8 (void) yposition += ystep; val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); - val &= 0x3FFFF; + val &= 0x3FFFFF; val = source[val]; if (val != TRANSPARENTPIXEL) dest[2] = colormap[val]; @@ -1253,7 +1253,7 @@ void R_DrawSplat_8 (void) yposition += ystep; val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); - val &= 0x3FFFF; + val &= 0x3FFFFF; val = source[val]; if (val != TRANSPARENTPIXEL) dest[3] = colormap[val]; @@ -1261,7 +1261,7 @@ void R_DrawSplat_8 (void) yposition += ystep; val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); - val &= 0x3FFFF; + val &= 0x3FFFFF; val = source[val]; if (val != TRANSPARENTPIXEL) dest[4] = colormap[val]; @@ -1269,7 +1269,7 @@ void R_DrawSplat_8 (void) yposition += ystep; val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); - val &= 0x3FFFF; + val &= 0x3FFFFF; val = source[val]; if (val != TRANSPARENTPIXEL) dest[5] = colormap[val]; @@ -1277,7 +1277,7 @@ void R_DrawSplat_8 (void) yposition += ystep; val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); - val &= 0x3FFFF; + val &= 0x3FFFFF; val = source[val]; if (val != TRANSPARENTPIXEL) dest[6] = colormap[val]; @@ -1285,7 +1285,7 @@ void R_DrawSplat_8 (void) yposition += ystep; val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); - val &= 0x3FFFF; + val &= 0x3FFFFF; val = source[val]; if (val != TRANSPARENTPIXEL) dest[7] = colormap[val]; From 3dd04b90c630574f41ae0f70f03104706ac051dd Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 5 Apr 2021 16:59:02 -0400 Subject: [PATCH 348/644] Fix jet fume crash when dashmode is above DASHMODE_MAX I would like to use higher dashmode values for extra leniency, the jet fume kicks and screams when this happens. --- src/p_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index b8e7d1746..03682b938 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -11310,7 +11310,7 @@ static void P_DoMetalJetFume(player_t *player, mobj_t *fume) angle_t angle = player->drawangle; fixed_t dist; panim_t panim = player->panim; - tic_t dashmode = player->dashmode; + tic_t dashmode = min(player->dashmode, DASHMODE_MAX); boolean underwater = mo->eflags & MFE_UNDERWATER; statenum_t stat = fume->state-states; From a01a420aa06176fce2cc249eacbdfd64ed73d93c Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 5 Apr 2021 18:10:34 -0700 Subject: [PATCH 349/644] Brackets --- src/w_wad.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/w_wad.c b/src/w_wad.c index 91c8331f7..6149aec6e 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -821,8 +821,10 @@ UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup) } if (important && !mainfile) + { //G_SetGameModified(true); modifiedgame = true; // avoid savemoddata being set to false + } // // link wad file to search files From 397fdef034faf90bb89116e7028340f806c81488 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Mon, 5 Apr 2021 22:34:52 -0400 Subject: [PATCH 350/644] Load intermission patches in Y_LoadIntermisionData --- src/g_game.c | 1 + src/y_inter.c | 133 ++++++++++++++++++++++++++++++++------------------ src/y_inter.h | 1 + 3 files changed, 87 insertions(+), 48 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 2b304b4fd..29ad4086e 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3973,6 +3973,7 @@ static void G_DoCompleted(void) { G_SetGamestate(GS_INTERMISSION); Y_StartIntermission(); + Y_LoadIntermisionData(); G_UpdateVisited(); G_HandleSaveLevel(); } diff --git a/src/y_inter.c b/src/y_inter.c index bd3b557d7..629d07426 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -215,6 +215,86 @@ static void Y_IntermissionTokenDrawer(void) V_DrawCroppedPatch(32<width, calc); } + +// +// Y_LoadData +// +// Load patches for drawing the intermission, if acceptable +// +void Y_LoadIntermisionData(void) +{ + INT32 i; + + if (dedicated) + return; + + switch (intertype) + { + case int_coop: + { + for (i = 0; i < 4; ++i) + { + if (strlen(data.coop.bonuses[i].patch)) + data.coop.bonuspatches[i] = W_CachePatchName(data.coop.bonuses[i].patch, PU_PATCH); + } + data.coop.ptotal = W_CachePatchName("YB_TOTAL", PU_PATCH); + + // get background patches + bgpatch = W_CachePatchName("INTERSCR", PU_PATCH); + + // grab an interscreen if appropriate + if (mapheaderinfo[gamemap-1]->interscreen[0] != '#') + interpic = W_CachePatchName(mapheaderinfo[gamemap-1]->interscreen, PU_PATCH); + break; + } + case int_spec: + { + for (i = 0; i < 2; ++i) + data.spec.bonuspatches[i] = W_CachePatchName(data.spec.bonuses[i].patch, PU_PATCH); + + data.spec.pscore = W_CachePatchName("YB_SCORE", PU_PATCH); + data.spec.pcontinues = W_CachePatchName("YB_CONTI", PU_PATCH); + + // get background tile + bgtile = W_CachePatchName("SPECTILE", PU_PATCH); + + // grab an interscreen if appropriate + if (mapheaderinfo[gamemap-1]->interscreen[0] != '#') + interpic = W_CachePatchName(mapheaderinfo[gamemap-1]->interscreen, PU_PATCH); + break; + } + case int_match: + case int_race: + case int_teammatch: + case int_ctf: + { + if (intertype == int_match || intertype == int_race) + { + // get RESULT header + data.match.result = W_CachePatchName("RESULT", PU_PATCH); + } + + if (intertype == int_ctf) + { + data.match.redflag = rflagico; + data.match.blueflag = bflagico; + } + else // team match + { + data.match.redflag = rmatcico; + data.match.blueflag = bmatcico; + } + + // get background tile + bgtile = W_CachePatchName("SRB2BACK", PU_PATCH); + break; + } + case int_none: + default: + break; + } +} + // // Y_ConsiderScreenBuffer // @@ -1176,6 +1256,11 @@ void Y_DetermineIntermissionType(void) intertype = int_ctf; } +// +// Y_StartIntermission +// +// Called by G_DoCompleted. Sets up data for intermission drawer/ticker. +// // // Y_StartIntermission // @@ -1183,8 +1268,6 @@ void Y_DetermineIntermissionType(void) // void Y_StartIntermission(void) { - INT32 i; - intertic = -1; #ifdef PARANOIA @@ -1228,23 +1311,12 @@ void Y_StartIntermission(void) // setup time data data.coop.tics = players[consoleplayer].realtime; - for (i = 0; i < 4; ++i) - { - if (strlen(data.coop.bonuses[i].patch)) - data.coop.bonuspatches[i] = W_CachePatchName(data.coop.bonuses[i].patch, PU_PATCH); - } - data.coop.ptotal = W_CachePatchName("YB_TOTAL", PU_PATCH); - // get act number data.coop.actnum = mapheaderinfo[gamemap-1]->actnum; - // get background patches - bgpatch = W_CachePatchName("INTERSCR", PU_PATCH); - // grab an interscreen if appropriate if (mapheaderinfo[gamemap-1]->interscreen[0] != '#') { - interpic = W_CachePatchName(mapheaderinfo[gamemap-1]->interscreen, PU_PATCH); useinterpic = true; usebuffer = false; } @@ -1301,21 +1373,9 @@ void Y_StartIntermission(void) // give out ring bonuses Y_AwardSpecialStageBonus(); - for (i = 0; i < 2; ++i) - data.spec.bonuspatches[i] = W_CachePatchName(data.spec.bonuses[i].patch, PU_PATCH); - - data.spec.pscore = W_CachePatchName("YB_SCORE", PU_PATCH); - data.spec.pcontinues = W_CachePatchName("YB_CONTI", PU_PATCH); - - // get background tile - bgtile = W_CachePatchName("SPECTILE", PU_PATCH); - // grab an interscreen if appropriate if (mapheaderinfo[gamemap-1]->interscreen[0] != '#') - { - interpic = W_CachePatchName(mapheaderinfo[gamemap-1]->interscreen, PU_PATCH); useinterpic = true; - } else useinterpic = false; @@ -1408,11 +1468,6 @@ void Y_StartIntermission(void) data.match.levelstring[sizeof data.match.levelstring - 1] = '\0'; - // get RESULT header - data.match.result = - W_CachePatchName("RESULT", PU_PATCH); - - bgtile = W_CachePatchName("SRB2BACK", PU_PATCH); usetile = true; useinterpic = false; break; @@ -1437,10 +1492,6 @@ void Y_StartIntermission(void) data.match.levelstring[sizeof data.match.levelstring - 1] = '\0'; - // get RESULT header - data.match.result = W_CachePatchName("RESULT", PU_PATCH); - - bgtile = W_CachePatchName("SRB2BACK", PU_PATCH); usetile = true; useinterpic = false; break; @@ -1466,18 +1517,6 @@ void Y_StartIntermission(void) data.match.levelstring[sizeof data.match.levelstring - 1] = '\0'; - if (intertype == int_ctf) - { - data.match.redflag = rflagico; - data.match.blueflag = bflagico; - } - else // team match - { - data.match.redflag = rmatcico; - data.match.blueflag = bmatcico; - } - - bgtile = W_CachePatchName("SRB2BACK", PU_PATCH); usetile = true; useinterpic = false; break; @@ -1502,8 +1541,6 @@ void Y_StartIntermission(void) data.competition.levelstring[sizeof data.competition.levelstring - 1] = '\0'; - // get background tile - bgtile = W_CachePatchName("SRB2BACK", PU_PATCH); usetile = true; useinterpic = false; break; diff --git a/src/y_inter.h b/src/y_inter.h index 859144b1d..08f7cf9bd 100644 --- a/src/y_inter.h +++ b/src/y_inter.h @@ -14,6 +14,7 @@ extern boolean usebuffer; void Y_IntermissionDrawer(void); void Y_Ticker(void); +void Y_LoadIntermisionData(void); void Y_StartIntermission(void); void Y_EndIntermission(void); From 35c0f8b5cc46ee8addc3cac102daebe7051aef8e Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Mon, 5 Apr 2021 22:44:16 -0400 Subject: [PATCH 351/644] Correct function name comment --- src/y_inter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/y_inter.c b/src/y_inter.c index 629d07426..e1bbd16f6 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -217,7 +217,7 @@ static void Y_IntermissionTokenDrawer(void) // -// Y_LoadData +// Y_LoadIntermisionData // // Load patches for drawing the intermission, if acceptable // From 33b7075d4607a4d68a64d9c7d35f06e99fb22399 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Mon, 5 Apr 2021 22:50:22 -0400 Subject: [PATCH 352/644] bruh --- src/g_game.c | 2 +- src/y_inter.c | 4 ++-- src/y_inter.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 29ad4086e..13423ce77 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3973,7 +3973,7 @@ static void G_DoCompleted(void) { G_SetGamestate(GS_INTERMISSION); Y_StartIntermission(); - Y_LoadIntermisionData(); + Y_LoadIntermissionData(); G_UpdateVisited(); G_HandleSaveLevel(); } diff --git a/src/y_inter.c b/src/y_inter.c index e1bbd16f6..4e10e7398 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -217,11 +217,11 @@ static void Y_IntermissionTokenDrawer(void) // -// Y_LoadIntermisionData +// Y_LoadIntermissionData // // Load patches for drawing the intermission, if acceptable // -void Y_LoadIntermisionData(void) +void Y_LoadIntermissionData(void) { INT32 i; diff --git a/src/y_inter.h b/src/y_inter.h index 08f7cf9bd..7268b1a47 100644 --- a/src/y_inter.h +++ b/src/y_inter.h @@ -14,7 +14,7 @@ extern boolean usebuffer; void Y_IntermissionDrawer(void); void Y_Ticker(void); -void Y_LoadIntermisionData(void); +void Y_LoadIntermissionData(void); void Y_StartIntermission(void); void Y_EndIntermission(void); From 101b6e46d413821f74aa8f10d8e55a4d1959634f Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Mon, 5 Apr 2021 22:56:03 -0400 Subject: [PATCH 353/644] Even more bruhs --- src/y_inter.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/y_inter.c b/src/y_inter.c index 4e10e7398..32dfb52a7 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -1262,10 +1262,6 @@ void Y_DetermineIntermissionType(void) // Called by G_DoCompleted. Sets up data for intermission drawer/ticker. // // -// Y_StartIntermission -// -// Called by G_DoCompleted. Sets up data for intermission drawer/ticker. -// void Y_StartIntermission(void) { intertic = -1; From e39bf7503fe37dfe412ef06b45ef9dba7095b9dc Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 6 Apr 2021 03:55:57 -0700 Subject: [PATCH 354/644] Makefile: fix object file not depending on headers BRUH MOMENT --- src/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index 471c55ed3..cf06ce904 100644 --- a/src/Makefile +++ b/src/Makefile @@ -701,7 +701,7 @@ endif endif define deps_rule += - $(CC) $(CFLAGS) -M -MF $@ -MT $(OBJDIR)/$< $< + $(CC) $(CFLAGS) -M -MF $@ -MT $(OBJDIR)/$(<:.c=.o) $< endef $(DEPDIR)/%.d: %.c From c3d5740e983891b18bd45fccf45ac89cd9345403 Mon Sep 17 00:00:00 2001 From: SwitchKaze Date: Tue, 6 Apr 2021 15:06:44 -0500 Subject: [PATCH 355/644] Fix console text bleeding edge case A single character could prematurely read if there were enough special characters to push 'c' past 'con_width'. --- src/console.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/console.c b/src/console.c index 2d95e10b8..208b55212 100644 --- a/src/console.c +++ b/src/console.c @@ -1654,6 +1654,8 @@ static void CON_DrawHudlines(void) p++; c++; } + if (c >= con_width) + break; if (*p < HU_FONTSTART) ;//charwidth = 4 * con_scalefactor; else @@ -1777,6 +1779,8 @@ static void CON_DrawConsole(void) p++; c++; } + if (c >= con_width) + break; V_DrawCharacter(x, y, (INT32)(*p) | charflags | cv_constextsize.value | V_NOSCALESTART, true); } } From a501b7b00d74bcdce98e2ca0d6b69ddfb0c39ea9 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Wed, 7 Apr 2021 00:55:08 -0400 Subject: [PATCH 356/644] Reorganize the switch block, add missing int_comp case --- src/y_inter.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/src/y_inter.c b/src/y_inter.c index 32dfb52a7..5dd3e845d 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -263,28 +263,23 @@ void Y_LoadIntermissionData(void) interpic = W_CachePatchName(mapheaderinfo[gamemap-1]->interscreen, PU_PATCH); break; } + case int_ctf: + case int_teammatch: + { + data.match.redflag = (intertype == int_ctf) ? rflagico : rmatcico; + data.match.blueflag = (intertype == int_ctf) ? bflagico : bmatcico; + } + /* FALLTHRU */ case int_match: case int_race: - case int_teammatch: - case int_ctf: + case int_comp: { - if (intertype == int_match || intertype == int_race) + if (intertype == int_match || intertype == int_race || intertype == int_comp) { // get RESULT header data.match.result = W_CachePatchName("RESULT", PU_PATCH); } - if (intertype == int_ctf) - { - data.match.redflag = rflagico; - data.match.blueflag = bflagico; - } - else // team match - { - data.match.redflag = rmatcico; - data.match.blueflag = bmatcico; - } - // get background tile bgtile = W_CachePatchName("SRB2BACK", PU_PATCH); break; From 77f2b1f682b1b4112d7f3d74e1f937107479aaef Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Wed, 7 Apr 2021 01:11:39 -0400 Subject: [PATCH 357/644] Prevent redudant result patch caching on competition --- src/y_inter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/y_inter.c b/src/y_inter.c index 5dd3e845d..6833ca2b5 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -274,7 +274,7 @@ void Y_LoadIntermissionData(void) case int_race: case int_comp: { - if (intertype == int_match || intertype == int_race || intertype == int_comp) + if (intertype == int_match || intertype == int_race) { // get RESULT header data.match.result = W_CachePatchName("RESULT", PU_PATCH); From 3f086ff6123341cfe236165908edb779014aa854 Mon Sep 17 00:00:00 2001 From: SMS Alfredo <65426124+SMS-Alfredo@users.noreply.github.com> Date: Wed, 7 Apr 2021 01:14:32 -0500 Subject: [PATCH 358/644] The intial --- src/deh_tables.c | 3 +++ src/p_mobj.c | 41 ++++++++++++++++++++++++++++++++++++----- src/r_defs.h | 4 ++++ 3 files changed, 43 insertions(+), 5 deletions(-) diff --git a/src/deh_tables.c b/src/deh_tables.c index dd6d7d69f..f3a77d528 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -4905,6 +4905,9 @@ struct int_const_s const INT_CONST[] = { {"RF_SHADOWDRAW",RF_SHADOWDRAW}, {"RF_SHADOWEFFECTS",RF_SHADOWEFFECTS}, {"RF_DROPSHADOW",RF_DROPSHADOW}, + {"RF_FORCESUPER",RF_FORCESUPER}, + {"RF_FORCENOSUPER",RF_FORCENOSUPER}, + {"RF_REVERSESUPER",RF_REVERSESUPER}, // Level flags {"LF_SCRIPTISFILE",LF_SCRIPTISFILE}, diff --git a/src/p_mobj.c b/src/p_mobj.c index 49db6daee..3f77f28aa 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -325,9 +325,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) mobj->tics = st->tics; // Adjust the player's animation speed to match their velocity. - if (state == S_PLAY_STND && player->powers[pw_super] && skins[player->skin].sprites[SPR2_WAIT|FF_SPR2SUPER].numframes == 0) // if no super wait, don't wait at all - mobj->tics = -1; - else if (player->panim == PA_EDGE && (player->charflags & SF_FASTEDGE)) + if (player->panim == PA_EDGE && (player->charflags & SF_FASTEDGE)) mobj->tics = 2; else if (!(disableSpeedAdjust || player->charflags & SF_NOSPEEDADJUST)) { @@ -396,8 +394,26 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) if (skin) { - spr2 = P_GetSkinSprite2(skin, (((player->powers[pw_super] && !(player->charflags & SF_NOSUPERSPRITES)) ? FF_SPR2SUPER : 0)|st->frame) & FF_FRAMEMASK, mobj->player); + UINT16 stateframe = st->frame; + + // Add/Remove FF_SPR2SUPER based on certain conditions + if (player->powers[pw_super] && !(player->charflags & SF_NOSUPERSPRITES)) + stateframe = stateframe | FF_SPR2SUPER; + + if (stateframe & FF_SPR2SUPER) + { + if (mobj->renderflags & RF_FORCENOSUPER) + stateframe = stateframe & ~FF_SPR2SUPER; + } + else if (mobj->renderflags & RF_FORCESUPER) + stateframe = stateframe | FF_SPR2SUPER; + + // Get the sprite2 and frame number + spr2 = P_GetSkinSprite2(skin, (stateframe & FF_FRAMEMASK), mobj->player); numframes = skin->sprites[spr2].numframes; + + if (state == S_PLAY_STND && (spr2 & FF_SPR2SUPER) && skin->sprites[SPR2_WAIT|FF_SPR2SUPER].numframes == 0) + mobj->tics = -1; // If no super wait, don't wait at all } else { @@ -522,8 +538,23 @@ boolean P_SetMobjState(mobj_t *mobj, statenum_t state) if (skin) { - spr2 = P_GetSkinSprite2(skin, st->frame & FF_FRAMEMASK, mobj->player); + UINT16 stateframe = st->frame; + + // Add/Remove FF_SPR2SUPER based on certain conditions + if (stateframe & FF_SPR2SUPER) + { + if (mobj->renderflags & RF_FORCENOSUPER) + stateframe = stateframe & ~FF_SPR2SUPER; + } + else if (mobj->renderflags & RF_FORCESUPER) + stateframe = stateframe | FF_SPR2SUPER; + + // Get the sprite2 and frame number + spr2 = P_GetSkinSprite2(skin, (stateframe & FF_FRAMEMASK), NULL); numframes = skin->sprites[spr2].numframes; + + if (state == S_PLAY_STND && (spr2 & FF_SPR2SUPER) && skin->sprites[SPR2_WAIT|FF_SPR2SUPER].numframes == 0) + mobj->tics = -1; // If no super wait, don't wait at all } else { diff --git a/src/r_defs.h b/src/r_defs.h index 9c649fbc4..31f30dd6f 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -738,6 +738,10 @@ typedef enum RF_SHADOWDRAW = 0x10000, // Stretches and skews the sprite like a shadow. RF_SHADOWEFFECTS = 0x20000, // Scales and becomes transparent like a shadow. RF_DROPSHADOW = (RF_SHADOWDRAW | RF_SHADOWEFFECTS | RF_FULLDARK), + + RF_FORCESUPER = 0x40000, // Forces an object to use super sprites with SPR_PLAY. + RF_FORCENOSUPER = 0x80000, // Forces an object to NOT use super sprites with SPR_PLAY. + RF_REVERSESUPER = (RF_FORCESUPER | RF_FORCENOSUPER), //Use normal sprites in place of super sprites and vice-versa } renderflags_t; typedef enum From 876daa7d6ef762312fd4ec990c30fc3b3c499c4d Mon Sep 17 00:00:00 2001 From: katsy Date: Wed, 7 Apr 2021 04:57:18 -0500 Subject: [PATCH 359/644] fix ctf flag garbage --- src/st_stuff.c | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/src/st_stuff.c b/src/st_stuff.c index 649644620..a1fbbec03 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -299,10 +299,6 @@ void ST_LoadGraphics(void) gravboots = W_CachePatchName("TVGVICON", PU_HUDGFX); tagico = W_CachePatchName("TAGICO", PU_HUDGFX); - rflagico = W_CachePatchName("RFLAGICO", PU_HUDGFX); - bflagico = W_CachePatchName("BFLAGICO", PU_HUDGFX); - rmatcico = W_CachePatchName("RMATCICO", PU_HUDGFX); - bmatcico = W_CachePatchName("BMATCICO", PU_HUDGFX); gotrflag = W_CachePatchName("GOTRFLAG", PU_HUDGFX); gotbflag = W_CachePatchName("GOTBFLAG", PU_HUDGFX); fnshico = W_CachePatchName("FNSHICO", PU_HUDGFX); @@ -2363,27 +2359,29 @@ static inline void ST_drawRaceHUD(void) static void ST_drawTeamHUD(void) { - patch_t *p; #define SEP 20 if (F_GetPromptHideHud(0)) // y base is 0 return; - if (gametyperules & GTR_TEAMFLAGS) - p = bflagico; - else - p = bmatcico; + rflagico = W_CachePatchName("RFLAGICO", PU_HUDGFX); + bflagico = W_CachePatchName("BFLAGICO", PU_HUDGFX); + rmatcico = W_CachePatchName("RMATCICO", PU_HUDGFX); + bmatcico = W_CachePatchName("BMATCICO", PU_HUDGFX); if (LUA_HudEnabled(hud_teamscores)) - V_DrawSmallScaledPatch(BASEVIDWIDTH/2 - SEP - (p->width / 4), 4, V_HUDTRANS|V_PERPLAYER|V_SNAPTOTOP, p); - - if (gametyperules & GTR_TEAMFLAGS) - p = rflagico; - else - p = rmatcico; - - if (LUA_HudEnabled(hud_teamscores)) - V_DrawSmallScaledPatch(BASEVIDWIDTH/2 + SEP - (p->width / 4), 4, V_HUDTRANS|V_PERPLAYER|V_SNAPTOTOP, p); + { + if (gametyperules & GTR_TEAMFLAGS) + { + V_DrawSmallScaledPatch(BASEVIDWIDTH/2 - SEP - (bflagico->width / 4), 4, V_HUDTRANS|V_PERPLAYER|V_SNAPTOTOP, bflagico); + V_DrawSmallScaledPatch(BASEVIDWIDTH/2 + SEP - (rflagico->width / 4), 4, V_HUDTRANS|V_PERPLAYER|V_SNAPTOTOP, rflagico); + } + else + { + V_DrawSmallScaledPatch(BASEVIDWIDTH/2 - SEP - (bmatcico->width / 4), 4, V_HUDTRANS|V_PERPLAYER|V_SNAPTOTOP, bmatcico); + V_DrawSmallScaledPatch(BASEVIDWIDTH/2 + SEP - (rmatcico->width / 4), 4, V_HUDTRANS|V_PERPLAYER|V_SNAPTOTOP, rmatcico); + } + } if (!(gametyperules & GTR_TEAMFLAGS)) goto num; From 0d628c351aa57d2dfa95c77fd86c49a3a1a7a3b0 Mon Sep 17 00:00:00 2001 From: sphere Date: Sat, 10 Apr 2021 17:44:42 +0200 Subject: [PATCH 360/644] Update Zone Builder configuration. --- extras/conf/SRB2-22.cfg | 146 ++++++++++++++++++++++++++++------------ 1 file changed, 104 insertions(+), 42 deletions(-) diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg index a0d40cdf0..3fd4b6ccd 100644 --- a/extras/conf/SRB2-22.cfg +++ b/extras/conf/SRB2-22.cfg @@ -746,13 +746,13 @@ linedeftypes 20 { - title = "First Line"; + title = "PolyObject First Line"; prefix = "(20)"; } 22 { - title = "Parameters"; + title = "PolyObject Parameters"; prefix = "(22)"; flags8text = "[3] Set translucency by X offset"; flags32text = "[5] Render outer sides only"; @@ -765,19 +765,19 @@ linedeftypes 30 { - title = "Waving Flag"; + title = "PolyObject Waving Flag"; prefix = "(30)"; } 31 { - title = "Displacement by Front Sector"; + title = "Move PolyObject by Front Sector Displacement"; prefix = "(31)"; } 32 { - title = "Angular Displacement by Front Sector"; + title = "Rotate PolyObject by Front Sector Displacement"; prefix = "(32)"; flags64text = "[6] Don't turn players"; flags512text = "[9] Turn all objects"; @@ -2498,35 +2498,35 @@ linedeftypes 480 { - title = "Door Slide"; + title = "PolyObject Door Slide"; prefix = "(480)"; flags8text = "[3] Set delay by backside sector"; } 481 { - title = "Door Swing"; + title = "PolyObject Door Swing"; prefix = "(481)"; flags8text = "[3] Set delay by backside sector"; } 482 { - title = "Move"; + title = "Move PolyObject"; prefix = "(482)"; flags8text = "[3] Set delay by backside sector"; } 483 { - title = "Move, Override"; + title = "Move PolyObject, Override"; prefix = "(483)"; flags8text = "[3] Set delay by backside sector"; } 484 { - title = "Rotate Right"; + title = "Rotate PolyObject Right"; prefix = "(484)"; flags8text = "[3] Set delay by backside sector"; flags64text = "[6] Don't turn players"; @@ -2535,7 +2535,7 @@ linedeftypes 485 { - title = "Rotate Right, Override"; + title = "Rotate PolyObject Right, Override"; prefix = "(485)"; flags8text = "[3] Set delay by backside sector"; flags64text = "[6] Don't turn players"; @@ -2544,7 +2544,7 @@ linedeftypes 486 { - title = "Rotate Left"; + title = "Rotate PolyObject Left"; prefix = "(486)"; flags8text = "[3] Set delay by backside sector"; flags64text = "[6] Don't turn players"; @@ -2553,7 +2553,7 @@ linedeftypes 487 { - title = "Rotate Left, Override"; + title = "Rotate PolyObject Left, Override"; prefix = "(487)"; flags8text = "[3] Set delay by backside sector"; flags64text = "[6] Don't turn players"; @@ -2562,7 +2562,7 @@ linedeftypes 488 { - title = "Move by Waypoints"; + title = "Move PolyObject by Waypoints"; prefix = "(488)"; flags8text = "[3] Set delay by backside sector"; flags32text = "[5] Reverse order"; @@ -2573,7 +2573,7 @@ linedeftypes 489 { - title = "Turn Invisible, Intangible"; + title = "Turn PolyObject Invisible, Intangible"; prefix = "(489)"; flags8text = "[3] Set delay by backside sector"; flags64text = "[6] Only invisible"; @@ -2581,7 +2581,7 @@ linedeftypes 490 { - title = "Turn Visible, Tangible"; + title = "Turn PolyObject Visible, Tangible"; prefix = "(490)"; flags8text = "[3] Set delay by backside sector"; flags64text = "[6] Only visible"; @@ -2589,7 +2589,7 @@ linedeftypes 491 { - title = "Set Translucency"; + title = "Set PolyObject Translucency"; prefix = "(491)"; flags8text = "[3] Set delay by backside sector"; flags16text = "[4] Set raw alpha by Front X"; @@ -2598,7 +2598,7 @@ linedeftypes 492 { - title = "Fade Translucency"; + title = "Fade PolyObject Translucency"; prefix = "(492)"; flags8text = "[3] Set delay by backside sector"; flags16text = "[4] Set raw alpha by Front X"; @@ -3393,6 +3393,7 @@ thingtypes width = 8; height = 28; angletext = "Jump strength"; + fixedrotation = 1; } 103 { @@ -3431,6 +3432,7 @@ thingtypes width = 12; height = 64; angletext = "Firing delay"; + fixedrotation = 1; } 122 { @@ -3547,9 +3549,10 @@ thingtypes { title = "Pterabyte Spawner"; sprite = "PTERA2A8"; - width = 16; - height = 16; - parametertext = "No. Pterabytes"; + width = 24; + height = 48; + parametertext = "Spawns +1"; + arrow = 0; } 136 { @@ -3771,6 +3774,7 @@ thingtypes height = 16; sprite = "internal:capsule"; angletext = "Tag"; + fixedrotation = 1; } 292 { @@ -3781,11 +3785,13 @@ thingtypes flags8text = "[8] Sea Egg shooting point"; sprite = "internal:eggmanway"; angletext = "No. (Sea Egg)"; + fixedrotation = 1; flagsvaluetext = "No. (Brak)"; parametertext = "Next"; } 293 { + arrow = 0; title = "Metal Sonic Gather Point"; sprite = "internal:metal"; width = 8; @@ -3793,6 +3799,7 @@ thingtypes } 294 { + arrow = 0; title = "Fang Waypoint"; flags8text = "[8] Center waypoint"; sprite = "internal:eggmanway"; @@ -3820,79 +3827,79 @@ thingtypes 301 { title = "Bounce Ring"; - sprite = "internal:RNGBA0"; + sprite = "RNGBA0"; } 302 { title = "Rail Ring"; - sprite = "internal:RNGRA0"; + sprite = "RNGRA0"; } 303 { title = "Infinity Ring"; - sprite = "internal:RNGIA0"; + sprite = "RNGIA0"; } 304 { title = "Automatic Ring"; - sprite = "internal:RNGAA0"; + sprite = "RNGAA0"; } 305 { title = "Explosion Ring"; - sprite = "internal:RNGEA0"; + sprite = "RNGEA0"; } 306 { title = "Scatter Ring"; - sprite = "internal:RNGSA0"; + sprite = "RNGSA0"; } 307 { title = "Grenade Ring"; - sprite = "internal:RNGGA0"; + sprite = "RNGGA0"; } 308 { title = "CTF Team Ring (Red)"; - sprite = "internal:RRNGA0"; + sprite = "internal:TRNGA0r"; width = 16; } 309 { title = "CTF Team Ring (Blue)"; - sprite = "internal:BRNGA0"; + sprite = "internal:TRNGA0b"; width = 16; } 330 { title = "Bounce Ring Panel"; - sprite = "internal:PIKBA0"; + sprite = "PIKBA0"; } 331 { title = "Rail Ring Panel"; - sprite = "internal:PIKRA0"; + sprite = "PIKRA0"; } 332 { title = "Automatic Ring Panel"; - sprite = "internal:PIKAA0"; + sprite = "PIKAA0"; } 333 { title = "Explosion Ring Panel"; - sprite = "internal:PIKEA0"; + sprite = "PIKEA0"; } 334 { title = "Scatter Ring Panel"; - sprite = "internal:PIKSA0"; + sprite = "PIKSA0"; } 335 { title = "Grenade Ring Panel"; - sprite = "internal:PIKGA0"; + sprite = "PIKGA0"; } } @@ -3986,6 +3993,7 @@ thingtypes flags8height = 24; flags8text = "[8] Float"; angletext = "Tag"; + fixedrotation = 1; } } @@ -4000,6 +4008,7 @@ thingtypes flags4text = "[4] Random (Strong)"; flags8text = "[8] Random (Weak)"; angletext = "Tag"; + fixedrotation = 1; 400 { @@ -4131,6 +4140,7 @@ thingtypes height = 44; flags1text = "[1] Run linedef executor on pop"; angletext = "Tag"; + fixedrotation = 1; 431 { @@ -4228,6 +4238,7 @@ thingtypes height = 128; flags4text = "[4] Respawn at center"; angletext = "Angle/Order"; + fixedrotation = 1; parametertext = "Order"; } 520 @@ -4259,7 +4270,7 @@ thingtypes flags1text = "[1] Start retracted"; flags4text = "[4] Retractable"; flags8text = "[8] Intangible"; - parametertext = "Initial delay"; + parametertext = "Start delay"; } 523 { @@ -4271,7 +4282,8 @@ thingtypes flags4text = "[4] Retractable"; flags8text = "[8] Intangible"; angletext = "Retraction interval"; - parametertext = "Initial delay"; + fixedrotation = 1; + parametertext = "Start delay"; } 1130 { @@ -4320,6 +4332,7 @@ thingtypes flags4text = "[4] Invisible"; flags8text = "[8] No distance check"; angletext = "Lift height"; + fixedrotation = 1; } 541 { @@ -4335,6 +4348,7 @@ thingtypes width = 32; height = 64; angletext = "Strength"; + fixedrotation = 1; } 543 { @@ -4344,6 +4358,7 @@ thingtypes height = 64; flags8text = "[8] Respawn"; angletext = "Color"; + fixedrotation = 1; } 550 { @@ -4617,6 +4632,9 @@ thingtypes title = "Slope Vertex"; sprite = "internal:vertexslope"; angletext = "Tag"; + fixedrotation = 1; + parametertext = "Absolute?"; + flagsvaluetext = "Absolute Z"; } 751 @@ -4638,6 +4656,7 @@ thingtypes title = "Zoom Tube Waypoint"; sprite = "internal:zoom"; angletext = "Order"; + fixedrotation = 1; } 754 @@ -4647,6 +4666,7 @@ thingtypes flags8text = "[8] Push using XYZ"; sprite = "GWLGA0"; angletext = "Radius"; + fixedrotation = 1; } 755 { @@ -4655,6 +4675,7 @@ thingtypes flags8text = "[8] Pull using XYZ"; sprite = "GWLRA0"; angletext = "Radius"; + fixedrotation = 1; } 756 { @@ -4663,6 +4684,7 @@ thingtypes width = 32; height = 16; angletext = "Tag"; + fixedrotation = 1; } 757 { @@ -4671,6 +4693,7 @@ thingtypes width = 8; height = 16; angletext = "Tag"; + fixedrotation = 1; } 758 { @@ -4681,21 +4704,24 @@ thingtypes { title = "PolyObject Anchor"; sprite = "internal:polyanchor"; - angletext = "ID"; + angletext = "Tag"; + fixedrotation = 1; } 761 { title = "PolyObject Spawn Point"; sprite = "internal:polycenter"; - angletext = "ID"; + angletext = "Tag"; + fixedrotation = 1; } 762 { title = "PolyObject Spawn Point (Crush)"; sprite = "internal:polycentercrush"; - angletext = "ID"; + angletext = "Tag"; + fixedrotation = 1; } 780 { @@ -4703,6 +4729,7 @@ thingtypes sprite = "internal:skyb"; flags4text = "[4] In-map centerpoint"; parametertext = "ID"; + fixedrotation = 1; } } @@ -4897,6 +4924,7 @@ thingtypes height = 16; hangs = 1; angletext = "Dripping interval"; + fixedrotation = 1; } 1003 { @@ -4953,7 +4981,7 @@ thingtypes 1011 { title = "Stalagmite (DSZ2)"; - sprite = "DSTGA0"; + sprite = "DSTGB0"; width = 8; height = 116; flags4text = "[4] Double size"; @@ -5038,6 +5066,8 @@ thingtypes flags4text = "[4] No sounds"; flags8text = "[8] Double size"; angletext = "Tag"; + parametertext = "Spokes"; + fixedrotation = 1; } 1105 { @@ -5048,6 +5078,8 @@ thingtypes flags4text = "[4] No sounds"; flags8text = "[8] Double size"; angletext = "Tag"; + parametertext = "Spokes"; + fixedrotation = 1; } 1106 { @@ -5058,6 +5090,8 @@ thingtypes flags4text = "[4] No sounds"; flags8text = "[8] Red spring"; angletext = "Tag"; + parametertext = "Spokes"; + fixedrotation = 1; } 1107 { @@ -5067,6 +5101,8 @@ thingtypes height = 34; flags8text = "[8] Double size"; angletext = "Tag"; + parametertext = "Spokes"; + fixedrotation = 1; } 1108 { @@ -5086,6 +5122,8 @@ thingtypes flags4text = "[4] No sounds"; flags8text = "[8] Double size"; angletext = "Tag"; + parametertext = "Spokes"; + fixedrotation = 1; } 1110 { @@ -5095,6 +5133,8 @@ thingtypes height = 34; flags4text = "[4] No sounds"; angletext = "Tag"; + parametertext = "Spokes"; + fixedrotation = 1; } 1111 { @@ -5224,6 +5264,7 @@ thingtypes sprite = "EGR1A1"; width = 20; height = 72; + arrow = 1; } 1128 { @@ -5272,6 +5313,7 @@ thingtypes width = 8; height = 16; angletext = "Tag"; + fixedrotation = 1; } 1203 { @@ -5342,6 +5384,7 @@ thingtypes sprite = "WWSGAR"; width = 22; height = 64; + arrow = 1; } 1213 { @@ -5349,6 +5392,7 @@ thingtypes sprite = "WWS2AR"; width = 22; height = 64; + arrow = 1; } 1214 { @@ -5356,6 +5400,7 @@ thingtypes sprite = "WWS3ALAR"; width = 16; height = 192; + arrow = 1; } 1215 { @@ -5371,6 +5416,7 @@ thingtypes sprite = "BARRA1"; width = 24; height = 63; + arrow = 1; } 1217 { @@ -5392,6 +5438,7 @@ thingtypes sprite = "MCRTCLFR"; width = 22; height = 32; + arrow = 1; } 1220 { @@ -5399,6 +5446,7 @@ thingtypes sprite = "MCRTIR"; width = 32; height = 32; + arrow = 1; } 1221 { @@ -5406,6 +5454,7 @@ thingtypes sprite = "SALDARAL"; width = 96; height = 160; + arrow = 1; flags8text = "[8] Allow non-minecart players"; } 1222 @@ -5467,6 +5516,7 @@ thingtypes height = 40; flags8text = "[8] Waves vertically"; angletext = "On/Off time"; + fixedrotation = 1; parametertext = "Strength"; } 1301 @@ -5477,6 +5527,7 @@ thingtypes height = 40; flags8text = "[8] Shoot downwards"; angletext = "On/Off time"; + fixedrotation = 1; parametertext = "Strength"; } 1302 @@ -5500,6 +5551,7 @@ thingtypes width = 30; height = 32; angletext = "Initial delay"; + fixedrotation = 1; flags8text = "[8] Double size"; } 1305 @@ -5537,6 +5589,7 @@ thingtypes sprite = "WVINALAR"; width = 1; height = 288; + arrow = 1; } 1310 { @@ -5544,6 +5597,7 @@ thingtypes sprite = "WVINBLBR"; width = 1; height = 288; + arrow = 1; } } @@ -5901,6 +5955,7 @@ thingtypes width = 8; height = 4096; sprite = "UNKNA0"; + fixedrotation = 1; 1700 { @@ -5959,6 +6014,7 @@ thingtypes flags4text = "[4] Align player to top"; flags8text = "[8] Die upon time up"; angletext = "Time limit"; + fixedrotation = 1; parametertext = "Height"; } 1704 @@ -5971,6 +6027,7 @@ thingtypes unflippable = true; flagsvaluetext = "Pitch"; angletext = "Yaw"; + fixedrotation = 1; } 1705 { @@ -5983,6 +6040,7 @@ thingtypes centerHitbox = true; flagsvaluetext = "Height"; angletext = "Pitch/Yaw"; + fixedrotation = 1; } 1706 { @@ -6104,6 +6162,7 @@ thingtypes width = 8; height = 16; angletext = "Jump strength"; + fixedrotation = 1; } 1806 { @@ -6336,6 +6395,7 @@ thingtypes width = 18; height = 28; angletext = "Initial delay"; + fixedrotation = 1; } 2001 { @@ -6459,6 +6519,7 @@ thingtypes sprite = "XMS6A0"; width = 52; height = 106; + hangs = 1; } } @@ -6472,6 +6533,7 @@ thingtypes flags4text = "[4] No movement"; flags8text = "[8] Hop"; angletext = "Radius"; + fixedrotation = 1; 2200 { From dbc7f93f15479d7d123b5507b5aaf94e7f952249 Mon Sep 17 00:00:00 2001 From: sphere Date: Sat, 10 Apr 2021 11:52:15 -0400 Subject: [PATCH 361/644] Fix incorrect prefixes in the config --- extras/conf/SRB2-22.cfg | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg index 246ef9b64..a8217754d 100644 --- a/extras/conf/SRB2-22.cfg +++ b/extras/conf/SRB2-22.cfg @@ -3110,7 +3110,7 @@ linedeftypes 733 { title = "Copy Backside Floor Slope to Frontside"; - prefix = "(730)"; + prefix = "(733)"; slope = "copy"; copyslopeargs = 2; } @@ -3118,7 +3118,7 @@ linedeftypes 734 { title = "Copy Backside Ceiling Slope to Frontside"; - prefix = "(731)"; + prefix = "(734)"; slope = "copy"; copyslopeargs = 8; } @@ -3126,7 +3126,7 @@ linedeftypes 735 { title = "Copy Backside Floor and Ceiling Slope to Frontside"; - prefix = "(732)"; + prefix = "(735)"; slope = "copy"; copyslopeargs = 10; } From 4f3802a2cc400a0c93818fce5ac40d60ea2f6424 Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Sun, 11 Apr 2021 18:29:14 -0500 Subject: [PATCH 362/644] acos Lua exposure --- src/lua_mathlib.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/lua_mathlib.c b/src/lua_mathlib.c index b6046ab53..9a288e17b 100644 --- a/src/lua_mathlib.c +++ b/src/lua_mathlib.c @@ -87,6 +87,12 @@ static int lib_finetangent(lua_State *L) return 1; } +static int lib_finearccosine(lua_State *L) +{ + lua_pushangle(L, FixedAcos(luaL_checkfixed(L, 1))); + return 1; +} + // Fixed math //////////////// @@ -192,6 +198,7 @@ static luaL_Reg lib[] = { {"sin", lib_finesine}, {"cos", lib_finecosine}, {"tan", lib_finetangent}, + {"acos", lib_finearccosine}, {"FixedAngle", lib_fixedangle}, {"fixangle" , lib_fixedangle}, {"AngleFixed", lib_anglefixed}, From 8f322fd86fc8b2709c364ef4d2b1e4f363265f78 Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Sun, 11 Apr 2021 18:33:11 -0500 Subject: [PATCH 363/644] name kinda sucked --- src/lua_mathlib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lua_mathlib.c b/src/lua_mathlib.c index 9a288e17b..45168ad79 100644 --- a/src/lua_mathlib.c +++ b/src/lua_mathlib.c @@ -87,7 +87,7 @@ static int lib_finetangent(lua_State *L) return 1; } -static int lib_finearccosine(lua_State *L) +static int lib_fixedacos(lua_State *L) { lua_pushangle(L, FixedAcos(luaL_checkfixed(L, 1))); return 1; @@ -198,7 +198,7 @@ static luaL_Reg lib[] = { {"sin", lib_finesine}, {"cos", lib_finecosine}, {"tan", lib_finetangent}, - {"acos", lib_finearccosine}, + {"acos", lib_fixedacos}, {"FixedAngle", lib_fixedangle}, {"fixangle" , lib_fixedangle}, {"AngleFixed", lib_anglefixed}, From 701c6c8968fea04dc13f02c3cc5e3e7841e48345 Mon Sep 17 00:00:00 2001 From: "X.organic" Date: Tue, 6 Apr 2021 01:01:33 +0200 Subject: [PATCH 364/644] Fix myhashfgets-related buffer overflows in deh_soc.c --- src/deh_soc.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/deh_soc.c b/src/deh_soc.c index 5b12ea1b0..bc7533ee0 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -229,7 +229,10 @@ void readPlayer(MYFILE *f, INT32 num) SLOTFOUND - for (i = 0; i < MAXLINELEN-3; i++) + // A friendly neighborhood alias for brevity's sake + const size_t note_size = sizeof(description[num].notes); + + for (i = 0; i < MAXLINELEN-note_size-3; i++) { if (s[i] == '=') { @@ -239,8 +242,9 @@ void readPlayer(MYFILE *f, INT32 num) } if (playertext) { - strcpy(description[num].notes, playertext); - strcat(description[num].notes, myhashfgets(playertext, sizeof (description[num].notes), f)); + strlcpy(description[num].notes, playertext, note_size); + strlcat(description[num].notes, + myhashfgets(playertext, note_size, f), note_size); } else strcpy(description[num].notes, ""); @@ -249,7 +253,7 @@ void readPlayer(MYFILE *f, INT32 num) // It works down here, though. { INT32 numline = 0; - for (i = 0; (size_t)i < sizeof(description[num].notes)-1; i++) + for (i = 0; (size_t)i < note_size-1; i++) { if (numline < 20 && description[num].notes[i] == '\n') numline++; @@ -1140,8 +1144,10 @@ void readgametype(MYFILE *f, char *gtname) } if (descr) { - strcpy(gtdescription, descr); - strcat(gtdescription, myhashfgets(descr, sizeof (gtdescription), f)); + strlcpy(gtdescription, descr, sizeof (gtdescription)); + strlcat(gtdescription, + myhashfgets(descr, sizeof (gtdescription), f), + sizeof (gtdescription)); } else strcpy(gtdescription, ""); From f0f3b33d71db97ccf4b747f8962022df3104a18c Mon Sep 17 00:00:00 2001 From: "X.organic" Date: Tue, 6 Apr 2021 03:12:46 +0200 Subject: [PATCH 365/644] Edit note_size alias to get rid of warnings --- src/deh_soc.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/deh_soc.c b/src/deh_soc.c index bc7533ee0..72f785eff 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -230,9 +230,9 @@ void readPlayer(MYFILE *f, INT32 num) SLOTFOUND // A friendly neighborhood alias for brevity's sake - const size_t note_size = sizeof(description[num].notes); +#define NOTE_SIZE sizeof(description[num].notes) - for (i = 0; i < MAXLINELEN-note_size-3; i++) + for (i = 0; i < (INT32)(MAXLINELEN-NOTE_SIZE-3); i++) { if (s[i] == '=') { @@ -242,9 +242,9 @@ void readPlayer(MYFILE *f, INT32 num) } if (playertext) { - strlcpy(description[num].notes, playertext, note_size); + strlcpy(description[num].notes, playertext, NOTE_SIZE); strlcat(description[num].notes, - myhashfgets(playertext, note_size, f), note_size); + myhashfgets(playertext, NOTE_SIZE, f), NOTE_SIZE); } else strcpy(description[num].notes, ""); @@ -253,7 +253,7 @@ void readPlayer(MYFILE *f, INT32 num) // It works down here, though. { INT32 numline = 0; - for (i = 0; (size_t)i < note_size-1; i++) + for (i = 0; (size_t)i < NOTE_SIZE-1; i++) { if (numline < 20 && description[num].notes[i] == '\n') numline++; @@ -264,6 +264,7 @@ void readPlayer(MYFILE *f, INT32 num) } description[num].notes[strlen(description[num].notes)-1] = '\0'; description[num].notes[i] = '\0'; +#undef NOTE_SIZE continue; } From 6f0b4a4f6d5f129631f7aed997c332afbfe263e0 Mon Sep 17 00:00:00 2001 From: "X.organic" Date: Tue, 6 Apr 2021 03:13:38 +0200 Subject: [PATCH 366/644] Remove some dead code from DEH_LoadDehackedFile Also fixes a buffer overflow, but said overflow generally got caught by the stack smashing protector. Still, it's better for SOC files not to be able to crash the game that easily. --- src/dehacked.c | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index c2ea28d27..3f066a924 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -188,26 +188,11 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) dbg_line = -1; // start at -1 so the first line is 0. while (!myfeof(f)) { - char origpos[128]; - INT32 size = 0; - char *traverse; - myfgets(s, MAXLINELEN, f); memcpy(textline, s, MAXLINELEN); if (s[0] == '\n' || s[0] == '#') continue; - traverse = s; - - while (traverse[0] != '\n') - { - traverse++; - size++; - } - - strncpy(origpos, s, size); - origpos[size] = '\0'; - if (NULL != (word = strtok(s, " "))) { strupr(word); if (word[strlen(word)-1] == '\n') From 23759c67aa402a1f474edc8a8db25196393397e9 Mon Sep 17 00:00:00 2001 From: katsy Date: Mon, 12 Apr 2021 21:26:29 -0500 Subject: [PATCH 367/644] move HWR_GetMappedPatch earlier --- src/hardware/hw_main.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index c2d617eaf..5772b67d9 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -4137,6 +4137,11 @@ static void HWR_DrawSprite(gl_vissprite_t *spr) wallVerts[1].z = wallVerts[2].z = spr->z2; } + // cache the patch in the graphics card memory + //12/12/99: Hurdler: same comment as above (for md2) + //Hurdler: 25/04/2000: now support colormap in hardware mode + HWR_GetMappedPatch(gpatch, spr->colormap); + if (spr->flip) { wallVerts[0].s = wallVerts[3].s = ((GLPatch_t *)gpatch->hardware)->max_s; @@ -4156,11 +4161,6 @@ static void HWR_DrawSprite(gl_vissprite_t *spr) wallVerts[0].t = wallVerts[1].t = ((GLPatch_t *)gpatch->hardware)->max_t; } - // cache the patch in the graphics card memory - //12/12/99: Hurdler: same comment as above (for md2) - //Hurdler: 25/04/2000: now support colormap in hardware mode - HWR_GetMappedPatch(gpatch, spr->colormap); - if (!splat) { // if it has a dispoffset, push it a little towards the camera From 0d4d2ed6d8cf25398e6286e0982bbc2795cdb121 Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Tue, 13 Apr 2021 12:11:31 -0300 Subject: [PATCH 368/644] Fix blend tables generation --- src/r_draw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/r_draw.c b/src/r_draw.c index 8625fbab2..9a835ee58 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -274,7 +274,7 @@ static void BlendTab_Modulative(UINT8 *table) static INT32 BlendTab_Count[NUMBLENDMAPS] = { - NUMTRANSTABLES, // blendtab_add + NUMTRANSTABLES+1, // blendtab_add NUMTRANSTABLES+1, // blendtab_subtract NUMTRANSTABLES+1, // blendtab_reversesubtract 1 // blendtab_modulate @@ -294,7 +294,7 @@ static INT32 BlendTab_FromStyle[] = static void BlendTab_GenerateMaps(INT32 tab, INT32 style, void (*genfunc)(UINT8 *, int, UINT8)) { INT32 i = 0, num = BlendTab_Count[tab]; - const float amtmul = (256.0f / (float)(NUMTRANSTABLES)); + const float amtmul = (256.0f / (float)(NUMTRANSTABLES + 1)); for (; i < num; i++) { const size_t offs = (0x10000 * i); From b3d7df74c085464cc7f3dd3d78da6f54b8804305 Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Wed, 14 Apr 2021 10:55:52 -0300 Subject: [PATCH 369/644] This is my attempted fix for texture rotation on slopes, in Software. --- src/r_draw8.c | 64 +++++++-------- src/r_draw8_npo2.c | 152 +++++++++++++++++----------------- src/r_plane.c | 197 +++++++++++++++++++++++---------------------- src/r_plane.h | 4 +- src/r_splats.c | 3 +- 5 files changed, 212 insertions(+), 208 deletions(-) diff --git a/src/r_draw8.c b/src/r_draw8.c index 1f451115e..5c62b5595 100644 --- a/src/r_draw8.c +++ b/src/r_draw8.c @@ -693,8 +693,8 @@ void R_DrawTiltedSpan_8(void) do { double z = 1.f/iz; - u = (INT64)(uz*z) + viewx; - v = (INT64)(vz*z) + viewy; + u = (INT64)(uz*z); + v = (INT64)(vz*z); colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); @@ -726,8 +726,8 @@ void R_DrawTiltedSpan_8(void) endv = vz*endz; stepu = (INT64)((endu - startu) * INVSPAN); stepv = (INT64)((endv - startv) * INVSPAN); - u = (INT64)(startu) + viewx; - v = (INT64)(startv) + viewy; + u = (INT64)(startu); + v = (INT64)(startv); for (i = SPANSIZE-1; i >= 0; i--) { @@ -763,8 +763,8 @@ void R_DrawTiltedSpan_8(void) left = 1.f/left; stepu = (INT64)((endu - startu) * left); stepv = (INT64)((endv - startv) * left); - u = (INT64)(startu) + viewx; - v = (INT64)(startv) + viewy; + u = (INT64)(startu); + v = (INT64)(startv); for (; width != 0; width--) { @@ -826,8 +826,8 @@ void R_DrawTiltedTranslucentSpan_8(void) do { double z = 1.f/iz; - u = (INT64)(uz*z) + viewx; - v = (INT64)(vz*z) + viewy; + u = (INT64)(uz*z); + v = (INT64)(vz*z); colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); *dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dest); @@ -858,8 +858,8 @@ void R_DrawTiltedTranslucentSpan_8(void) endv = vz*endz; stepu = (INT64)((endu - startu) * INVSPAN); stepv = (INT64)((endv - startv) * INVSPAN); - u = (INT64)(startu) + viewx; - v = (INT64)(startv) + viewy; + u = (INT64)(startu); + v = (INT64)(startv); for (i = SPANSIZE-1; i >= 0; i--) { @@ -895,8 +895,8 @@ void R_DrawTiltedTranslucentSpan_8(void) left = 1.f/left; stepu = (INT64)((endu - startu) * left); stepv = (INT64)((endv - startv) * left); - u = (INT64)(startu) + viewx; - v = (INT64)(startv) + viewy; + u = (INT64)(startu); + v = (INT64)(startv); for (; width != 0; width--) { @@ -960,8 +960,8 @@ void R_DrawTiltedTranslucentWaterSpan_8(void) do { double z = 1.f/iz; - u = (INT64)(uz*z) + viewx; - v = (INT64)(vz*z) + viewy; + u = (INT64)(uz*z); + v = (INT64)(vz*z); colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); *dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dsrc++); @@ -992,8 +992,8 @@ void R_DrawTiltedTranslucentWaterSpan_8(void) endv = vz*endz; stepu = (INT64)((endu - startu) * INVSPAN); stepv = (INT64)((endv - startv) * INVSPAN); - u = (INT64)(startu) + viewx; - v = (INT64)(startv) + viewy; + u = (INT64)(startu); + v = (INT64)(startv); for (i = SPANSIZE-1; i >= 0; i--) { @@ -1029,8 +1029,8 @@ void R_DrawTiltedTranslucentWaterSpan_8(void) left = 1.f/left; stepu = (INT64)((endu - startu) * left); stepv = (INT64)((endv - startv) * left); - u = (INT64)(startu) + viewx; - v = (INT64)(startv) + viewy; + u = (INT64)(startu); + v = (INT64)(startv); for (; width != 0; width--) { @@ -1091,8 +1091,8 @@ void R_DrawTiltedSplat_8(void) do { double z = 1.f/iz; - u = (INT64)(uz*z) + viewx; - v = (INT64)(vz*z) + viewy; + u = (INT64)(uz*z); + v = (INT64)(vz*z); colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); @@ -1127,8 +1127,8 @@ void R_DrawTiltedSplat_8(void) endv = vz*endz; stepu = (INT64)((endu - startu) * INVSPAN); stepv = (INT64)((endv - startv) * INVSPAN); - u = (INT64)(startu) + viewx; - v = (INT64)(startv) + viewy; + u = (INT64)(startu); + v = (INT64)(startv); for (i = SPANSIZE-1; i >= 0; i--) { @@ -1168,8 +1168,8 @@ void R_DrawTiltedSplat_8(void) left = 1.f/left; stepu = (INT64)((endu - startu) * left); stepv = (INT64)((endv - startv) * left); - u = (INT64)(startu) + viewx; - v = (INT64)(startv) + viewy; + u = (INT64)(startu); + v = (INT64)(startv); for (; width != 0; width--) { @@ -1672,8 +1672,8 @@ void R_DrawTiltedFloorSprite_8(void) endv = vz*endz; stepu = (INT64)((endu - startu) * INVSPAN); stepv = (INT64)((endv - startv) * INVSPAN); - u = (INT64)(startu) + viewx; - v = (INT64)(startv) + viewy; + u = (INT64)(startu); + v = (INT64)(startv); for (i = SPANSIZE-1; i >= 0; i--) { @@ -1712,8 +1712,8 @@ void R_DrawTiltedFloorSprite_8(void) left = 1.f/left; stepu = (INT64)((endu - startu) * left); stepv = (INT64)((endv - startv) * left); - u = (INT64)(startu) + viewx; - v = (INT64)(startv) + viewy; + u = (INT64)(startu); + v = (INT64)(startv); for (; width != 0; width--) { @@ -1781,8 +1781,8 @@ void R_DrawTiltedTranslucentFloorSprite_8(void) endv = vz*endz; stepu = (INT64)((endu - startu) * INVSPAN); stepv = (INT64)((endv - startv) * INVSPAN); - u = (INT64)(startu) + viewx; - v = (INT64)(startv) + viewy; + u = (INT64)(startu); + v = (INT64)(startv); for (i = SPANSIZE-1; i >= 0; i--) { @@ -1821,8 +1821,8 @@ void R_DrawTiltedTranslucentFloorSprite_8(void) left = 1.f/left; stepu = (INT64)((endu - startu) * left); stepv = (INT64)((endv - startv) * left); - u = (INT64)(startu) + viewx; - v = (INT64)(startv) + viewy; + u = (INT64)(startu); + v = (INT64)(startv); for (; width != 0; width--) { diff --git a/src/r_draw8_npo2.c b/src/r_draw8_npo2.c index a34a20e9a..b5614898c 100644 --- a/src/r_draw8_npo2.c +++ b/src/r_draw8_npo2.c @@ -133,15 +133,15 @@ void R_DrawTiltedSpan_NPO2_8(void) do { double z = 1.f/iz; - u = (INT64)(uz*z) + viewx; - v = (INT64)(vz*z) + viewy; + u = (INT64)(uz*z); + v = (INT64)(vz*z); colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); // Lactozilla: Non-powers-of-two { - fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); - fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); + fixed_t x = (((fixed_t)u) >> FRACBITS); + fixed_t y = (((fixed_t)v) >> FRACBITS); // Carefully align all of my Friends. if (x < 0) @@ -181,16 +181,16 @@ void R_DrawTiltedSpan_NPO2_8(void) endv = vz*endz; stepu = (INT64)((endu - startu) * INVSPAN); stepv = (INT64)((endv - startv) * INVSPAN); - u = (INT64)(startu) + viewx; - v = (INT64)(startv) + viewy; + u = (INT64)(startu); + v = (INT64)(startv); for (i = SPANSIZE-1; i >= 0; i--) { colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); // Lactozilla: Non-powers-of-two { - fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); - fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); + fixed_t x = (((fixed_t)u) >> FRACBITS); + fixed_t y = (((fixed_t)v) >> FRACBITS); // Carefully align all of my Friends. if (x < 0) @@ -220,8 +220,8 @@ void R_DrawTiltedSpan_NPO2_8(void) colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); // Lactozilla: Non-powers-of-two { - fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); - fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); + fixed_t x = (((fixed_t)u) >> FRACBITS); + fixed_t y = (((fixed_t)v) >> FRACBITS); // Carefully align all of my Friends. if (x < 0) @@ -248,16 +248,16 @@ void R_DrawTiltedSpan_NPO2_8(void) left = 1.f/left; stepu = (INT64)((endu - startu) * left); stepv = (INT64)((endv - startv) * left); - u = (INT64)(startu) + viewx; - v = (INT64)(startv) + viewy; + u = (INT64)(startu); + v = (INT64)(startv); for (; width != 0; width--) { colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); // Lactozilla: Non-powers-of-two { - fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); - fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); + fixed_t x = (((fixed_t)u) >> FRACBITS); + fixed_t y = (((fixed_t)v) >> FRACBITS); // Carefully align all of my Friends. if (x < 0) @@ -326,14 +326,14 @@ void R_DrawTiltedTranslucentSpan_NPO2_8(void) do { double z = 1.f/iz; - u = (INT64)(uz*z) + viewx; - v = (INT64)(vz*z) + viewy; + u = (INT64)(uz*z); + v = (INT64)(vz*z); colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); // Lactozilla: Non-powers-of-two { - fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); - fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); + fixed_t x = (((fixed_t)u) >> FRACBITS); + fixed_t y = (((fixed_t)v) >> FRACBITS); // Carefully align all of my Friends. if (x < 0) @@ -373,16 +373,16 @@ void R_DrawTiltedTranslucentSpan_NPO2_8(void) endv = vz*endz; stepu = (INT64)((endu - startu) * INVSPAN); stepv = (INT64)((endv - startv) * INVSPAN); - u = (INT64)(startu) + viewx; - v = (INT64)(startv) + viewy; + u = (INT64)(startu); + v = (INT64)(startv); for (i = SPANSIZE-1; i >= 0; i--) { colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); // Lactozilla: Non-powers-of-two { - fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); - fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); + fixed_t x = (((fixed_t)u) >> FRACBITS); + fixed_t y = (((fixed_t)v) >> FRACBITS); // Carefully align all of my Friends. if (x < 0) @@ -412,8 +412,8 @@ void R_DrawTiltedTranslucentSpan_NPO2_8(void) colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); // Lactozilla: Non-powers-of-two { - fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); - fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); + fixed_t x = (((fixed_t)u) >> FRACBITS); + fixed_t y = (((fixed_t)v) >> FRACBITS); // Carefully align all of my Friends. if (x < 0) @@ -440,16 +440,16 @@ void R_DrawTiltedTranslucentSpan_NPO2_8(void) left = 1.f/left; stepu = (INT64)((endu - startu) * left); stepv = (INT64)((endv - startv) * left); - u = (INT64)(startu) + viewx; - v = (INT64)(startv) + viewy; + u = (INT64)(startu); + v = (INT64)(startv); for (; width != 0; width--) { colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); // Lactozilla: Non-powers-of-two { - fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); - fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); + fixed_t x = (((fixed_t)u) >> FRACBITS); + fixed_t y = (((fixed_t)v) >> FRACBITS); // Carefully align all of my Friends. if (x < 0) @@ -517,15 +517,15 @@ void R_DrawTiltedSplat_NPO2_8(void) do { double z = 1.f/iz; - u = (INT64)(uz*z) + viewx; - v = (INT64)(vz*z) + viewy; + u = (INT64)(uz*z); + v = (INT64)(vz*z); colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); // Lactozilla: Non-powers-of-two { - fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); - fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); + fixed_t x = (((fixed_t)u) >> FRACBITS); + fixed_t y = (((fixed_t)v) >> FRACBITS); // Carefully align all of my Friends. if (x < 0) @@ -569,16 +569,16 @@ void R_DrawTiltedSplat_NPO2_8(void) endv = vz*endz; stepu = (INT64)((endu - startu) * INVSPAN); stepv = (INT64)((endv - startv) * INVSPAN); - u = (INT64)(startu) + viewx; - v = (INT64)(startv) + viewy; + u = (INT64)(startu); + v = (INT64)(startv); for (i = SPANSIZE-1; i >= 0; i--) { colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); // Lactozilla: Non-powers-of-two { - fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); - fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); + fixed_t x = (((fixed_t)u) >> FRACBITS); + fixed_t y = (((fixed_t)v) >> FRACBITS); // Carefully align all of my Friends. if (x < 0) @@ -610,8 +610,8 @@ void R_DrawTiltedSplat_NPO2_8(void) colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); // Lactozilla: Non-powers-of-two { - fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); - fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); + fixed_t x = (((fixed_t)u) >> FRACBITS); + fixed_t y = (((fixed_t)v) >> FRACBITS); // Carefully align all of my Friends. if (x < 0) @@ -640,8 +640,8 @@ void R_DrawTiltedSplat_NPO2_8(void) left = 1.f/left; stepu = (INT64)((endu - startu) * left); stepv = (INT64)((endv - startv) * left); - u = (INT64)(startu) + viewx; - v = (INT64)(startv) + viewy; + u = (INT64)(startu); + v = (INT64)(startv); for (; width != 0; width--) { @@ -649,8 +649,8 @@ void R_DrawTiltedSplat_NPO2_8(void) val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]; // Lactozilla: Non-powers-of-two { - fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); - fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); + fixed_t x = (((fixed_t)u) >> FRACBITS); + fixed_t y = (((fixed_t)v) >> FRACBITS); // Carefully align all of my Friends. if (x < 0) @@ -1002,14 +1002,14 @@ void R_DrawTiltedFloorSprite_NPO2_8(void) endv = vz*endz; stepu = (INT64)((endu - startu) * INVSPAN); stepv = (INT64)((endv - startv) * INVSPAN); - u = (INT64)(startu) + viewx; - v = (INT64)(startv) + viewy; + u = (INT64)(startu); + v = (INT64)(startv); for (i = SPANSIZE-1; i >= 0; i--) { // Lactozilla: Non-powers-of-two - fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); - fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); + fixed_t x = (((fixed_t)u) >> FRACBITS); + fixed_t y = (((fixed_t)v) >> FRACBITS); // Carefully align all of my Friends. if (x < 0) @@ -1040,8 +1040,8 @@ void R_DrawTiltedFloorSprite_NPO2_8(void) v = (INT64)(startv); // Lactozilla: Non-powers-of-two { - fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); - fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); + fixed_t x = (((fixed_t)u) >> FRACBITS); + fixed_t y = (((fixed_t)v) >> FRACBITS); // Carefully align all of my Friends. if (x < 0) @@ -1070,14 +1070,14 @@ void R_DrawTiltedFloorSprite_NPO2_8(void) left = 1.f/left; stepu = (INT64)((endu - startu) * left); stepv = (INT64)((endv - startv) * left); - u = (INT64)(startu) + viewx; - v = (INT64)(startv) + viewy; + u = (INT64)(startu); + v = (INT64)(startv); for (; width != 0; width--) { // Lactozilla: Non-powers-of-two - fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); - fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); + fixed_t x = (((fixed_t)u) >> FRACBITS); + fixed_t y = (((fixed_t)v) >> FRACBITS); // Carefully align all of my Friends. if (x < 0) @@ -1152,14 +1152,14 @@ void R_DrawTiltedTranslucentFloorSprite_NPO2_8(void) endv = vz*endz; stepu = (INT64)((endu - startu) * INVSPAN); stepv = (INT64)((endv - startv) * INVSPAN); - u = (INT64)(startu) + viewx; - v = (INT64)(startv) + viewy; + u = (INT64)(startu); + v = (INT64)(startv); for (i = SPANSIZE-1; i >= 0; i--) { // Lactozilla: Non-powers-of-two - fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); - fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); + fixed_t x = (((fixed_t)u) >> FRACBITS); + fixed_t y = (((fixed_t)v) >> FRACBITS); // Carefully align all of my Friends. if (x < 0) @@ -1190,8 +1190,8 @@ void R_DrawTiltedTranslucentFloorSprite_NPO2_8(void) v = (INT64)(startv); // Lactozilla: Non-powers-of-two { - fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); - fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); + fixed_t x = (((fixed_t)u) >> FRACBITS); + fixed_t y = (((fixed_t)v) >> FRACBITS); // Carefully align all of my Friends. if (x < 0) @@ -1220,14 +1220,14 @@ void R_DrawTiltedTranslucentFloorSprite_NPO2_8(void) left = 1.f/left; stepu = (INT64)((endu - startu) * left); stepv = (INT64)((endv - startv) * left); - u = (INT64)(startu) + viewx; - v = (INT64)(startv) + viewy; + u = (INT64)(startu); + v = (INT64)(startv); for (; width != 0; width--) { // Lactozilla: Non-powers-of-two - fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); - fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); + fixed_t x = (((fixed_t)u) >> FRACBITS); + fixed_t y = (((fixed_t)v) >> FRACBITS); // Carefully align all of my Friends. if (x < 0) @@ -1429,14 +1429,14 @@ void R_DrawTiltedTranslucentWaterSpan_NPO2_8(void) do { double z = 1.f/iz; - u = (INT64)(uz*z) + viewx; - v = (INT64)(vz*z) + viewy; + u = (INT64)(uz*z); + v = (INT64)(vz*z); colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); // Lactozilla: Non-powers-of-two { - fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); - fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); + fixed_t x = (((fixed_t)u) >> FRACBITS); + fixed_t y = (((fixed_t)v) >> FRACBITS); // Carefully align all of my Friends. if (x < 0) @@ -1476,16 +1476,16 @@ void R_DrawTiltedTranslucentWaterSpan_NPO2_8(void) endv = vz*endz; stepu = (INT64)((endu - startu) * INVSPAN); stepv = (INT64)((endv - startv) * INVSPAN); - u = (INT64)(startu) + viewx; - v = (INT64)(startv) + viewy; + u = (INT64)(startu); + v = (INT64)(startv); for (i = SPANSIZE-1; i >= 0; i--) { colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); // Lactozilla: Non-powers-of-two { - fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); - fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); + fixed_t x = (((fixed_t)u) >> FRACBITS); + fixed_t y = (((fixed_t)v) >> FRACBITS); // Carefully align all of my Friends. if (x < 0) @@ -1515,8 +1515,8 @@ void R_DrawTiltedTranslucentWaterSpan_NPO2_8(void) colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); // Lactozilla: Non-powers-of-two { - fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); - fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); + fixed_t x = (((fixed_t)u) >> FRACBITS); + fixed_t y = (((fixed_t)v) >> FRACBITS); // Carefully align all of my Friends. if (x < 0) @@ -1543,16 +1543,16 @@ void R_DrawTiltedTranslucentWaterSpan_NPO2_8(void) left = 1.f/left; stepu = (INT64)((endu - startu) * left); stepv = (INT64)((endv - startv) * left); - u = (INT64)(startu) + viewx; - v = (INT64)(startv) + viewy; + u = (INT64)(startu); + v = (INT64)(startv); for (; width != 0; width--) { colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); // Lactozilla: Non-powers-of-two { - fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); - fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); + fixed_t x = (((fixed_t)u) >> FRACBITS); + fixed_t y = (((fixed_t)v) >> FRACBITS); // Carefully align all of my Friends. if (x < 0) diff --git a/src/r_plane.c b/src/r_plane.c index ea4dfa4e8..a936b0911 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -104,6 +104,7 @@ fixed_t cachedxstep[MAXVIDHEIGHT]; fixed_t cachedystep[MAXVIDHEIGHT]; static fixed_t xoffs, yoffs; +static floatv3_t ds_slope_origin, ds_slope_u, ds_slope_v; // // R_InitPlanes @@ -662,69 +663,91 @@ static void R_DrawSkyPlane(visplane_t *pl) } } -// Potentially override other stuff for now cus we're mean. :< But draw a slope plane! -// I copied ZDoom's code and adapted it to SRB2... -Red -void R_CalculateSlopeVectors(pslope_t *slope, fixed_t planeviewx, fixed_t planeviewy, fixed_t planeviewz, fixed_t planexscale, fixed_t planeyscale, fixed_t planexoffset, fixed_t planeyoffset, angle_t planeviewangle, angle_t planeangle, float fudge) +// Sets the origin vector of the sloped plane. +static void R_SetSlopePlaneOrigin(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xoff, fixed_t yoff, fixed_t angle) { - floatv3_t p, m, n; - float ang; - float vx, vy, vz; - float xscale = FIXED_TO_FLOAT(planexscale); - float yscale = FIXED_TO_FLOAT(planeyscale); - // compiler complains when P_GetSlopeZAt is used in FLOAT_TO_FIXED directly - // use this as a temp var to store P_GetSlopeZAt's return value each time - fixed_t temp; + floatv3_t *p = &ds_slope_origin; - vx = FIXED_TO_FLOAT(planeviewx+planexoffset); - vy = FIXED_TO_FLOAT(planeviewy-planeyoffset); - vz = FIXED_TO_FLOAT(planeviewz); + float vx = FixedToFloat(xpos + xoff); + float vy = FixedToFloat(ypos - yoff); + float vz = FixedToFloat(zpos); + float ang = ANG2RAD(ANGLE_270 - angle); - temp = P_GetSlopeZAt(slope, planeviewx, planeviewy); - zeroheight = FIXED_TO_FLOAT(temp); + zeroheight = FixedToFloat(P_GetSlopeZAt(slope, xpos, ypos)); // p is the texture origin in view space // Don't add in the offsets at this stage, because doing so can result in // errors if the flat is rotated. - ang = ANG2RAD(ANGLE_270 - planeviewangle); - p.x = vx * cos(ang) - vy * sin(ang); - p.z = vx * sin(ang) + vy * cos(ang); - temp = P_GetSlopeZAt(slope, -planexoffset, planeyoffset); - p.y = FIXED_TO_FLOAT(temp) - vz; + p->x = vx * cos(ang) - vy * sin(ang); + p->z = vx * sin(ang) + vy * cos(ang); + p->y = FixedToFloat(P_GetSlopeZAt(slope, -xoff, yoff)) - vz; +} + +// This function calculates all of the vectors necessary for drawing a tilted span. +void R_SetSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xoff, fixed_t yoff, angle_t angle, angle_t plangle) +{ + // Potentially override other stuff for now cus we're mean. :< But draw a slope plane! + // I copied ZDoom's code and adapted it to SRB2... -Red + floatv3_t *m = &ds_slope_v, *n = &ds_slope_u; + fixed_t temp; + float ang; + + R_SetSlopePlaneOrigin(slope, xpos, ypos, zpos, xoff, yoff, angle); // m is the v direction vector in view space - ang = ANG2RAD(ANGLE_180 - (planeviewangle + planeangle)); - m.x = yscale * cos(ang); - m.z = yscale * sin(ang); + ang = ANG2RAD(ANGLE_180 - (angle + plangle)); + m->x = cos(ang); + m->z = sin(ang); // n is the u direction vector in view space - n.x = xscale * sin(ang); - n.z = -xscale * cos(ang); + n->x = sin(ang); + n->z = -cos(ang); - ang = ANG2RAD(planeangle); - temp = P_GetSlopeZAt(slope, planeviewx + FLOAT_TO_FIXED(yscale * sin(ang)), planeviewy + FLOAT_TO_FIXED(yscale * cos(ang))); - m.y = FIXED_TO_FLOAT(temp) - zeroheight; - temp = P_GetSlopeZAt(slope, planeviewx + FLOAT_TO_FIXED(xscale * cos(ang)), planeviewy - FLOAT_TO_FIXED(xscale * sin(ang))); - n.y = FIXED_TO_FLOAT(temp) - zeroheight; + ang = ANG2RAD(plangle); + temp = P_GetSlopeZAt(slope, xpos + FloatToFixed(sin(ang)), ypos + FloatToFixed(cos(ang))); + m->y = FixedToFloat(temp) - zeroheight; + temp = P_GetSlopeZAt(slope, xpos + FloatToFixed(cos(ang)), ypos - FloatToFixed(sin(ang))); + n->y = FixedToFloat(temp) - zeroheight; +} - if (ds_powersoftwo) - { - m.x /= fudge; - m.y /= fudge; - m.z /= fudge; +// This function calculates all of the vectors necessary for drawing a scaled, tilted span. +void R_SetSlopePlaneScaled(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xs, fixed_t ys, fixed_t xoff, fixed_t yoff, angle_t angle, angle_t plangle) +{ + floatv3_t *m = &ds_slope_v, *n = &ds_slope_u; + fixed_t temp; - n.x *= fudge; - n.y *= fudge; - n.z *= fudge; - } + float xscale = FixedToFloat(xs); + float yscale = FixedToFloat(ys); + float ang; + R_SetSlopePlaneOrigin(slope, xpos, ypos, zpos, xoff, yoff, angle); + + // m is the v direction vector in view space + ang = ANG2RAD(ANGLE_180 - (angle + plangle)); + m->x = yscale * cos(ang); + m->z = yscale * sin(ang); + + // n is the u direction vector in view space + n->x = xscale * sin(ang); + n->z = -xscale * cos(ang); + + ang = ANG2RAD(plangle); + temp = P_GetSlopeZAt(slope, xpos + FloatToFixed(yscale * sin(ang)), ypos + FloatToFixed(yscale * cos(ang))); + m->y = FixedToFloat(temp) - zeroheight; + temp = P_GetSlopeZAt(slope, xpos + FloatToFixed(xscale * cos(ang)), ypos - FloatToFixed(xscale * sin(ang))); + n->y = FixedToFloat(temp) - zeroheight; +} + +void R_CalculateSlopeVectors(void) +{ // Eh. I tried making this stuff fixed-point and it exploded on me. Here's a macro for the only floating-point vector function I recall using. #define CROSS(d, v1, v2) \ d->x = (v1.y * v2.z) - (v1.z * v2.y);\ d->y = (v1.z * v2.x) - (v1.x * v2.z);\ d->z = (v1.x * v2.y) - (v1.y * v2.x) - CROSS(ds_sup, p, m); - CROSS(ds_svp, p, n); - CROSS(ds_szp, m, n); + CROSS(ds_sup, ds_slope_origin, ds_slope_v); + CROSS(ds_svp, ds_slope_origin, ds_slope_u); + CROSS(ds_szp, ds_slope_v, ds_slope_u); #undef CROSS ds_sup->z *= focallengthf; @@ -769,10 +792,11 @@ void R_SetTiltedSpan(INT32 span) ds_szp = &ds_sz[span]; } -static void R_SetSlopePlaneVectors(visplane_t *pl, INT32 y, fixed_t xoff, fixed_t yoff, float fudge) +static void R_SetSlopePlaneVectors(visplane_t *pl, INT32 y, fixed_t xoff, fixed_t yoff) { R_SetTiltedSpan(y); - R_CalculateSlopeVectors(pl->slope, pl->viewx, pl->viewy, pl->viewz, FRACUNIT, FRACUNIT, xoff, yoff, pl->viewangle, pl->plangle, fudge); + R_SetSlopePlane(pl->slope, pl->viewx, pl->viewy, pl->viewz, xoff, yoff, pl->viewangle, pl->plangle); + R_CalculateSlopeVectors(); } void R_DrawSinglePlane(visplane_t *pl) @@ -782,8 +806,8 @@ void R_DrawSinglePlane(visplane_t *pl) INT32 x; INT32 stop, angle; ffloor_t *rover; - int type; - int spanfunctype = BASEDRAWFUNC; + INT32 type; + INT32 spanfunctype = BASEDRAWFUNC; if (!(pl->minx <= pl->maxx)) return; @@ -953,61 +977,38 @@ void R_DrawSinglePlane(visplane_t *pl) if (pl->slope) { - float fudgecanyon = 0; - angle_t hack = (pl->plangle & (ANGLE_90-1)); + const fixed_t modmaskw = (ds_flatwidth << FRACBITS) - 1; + const fixed_t modmaskh = (ds_flatheight << FRACBITS) - 1; - yoffs *= 1; + /* + Essentially: We can't & the components along the regular axes when the plane is rotated. + This is because the distance on each regular axis in order to loop is different. + We rotate them, & the components, add them together, & them again, and then rotate them back. + These three seperate & operations are done per axis in order to prevent overflows. + toast 10/04/17 + */ + const fixed_t cosinecomponent = FINECOSINE(pl->plangle>>ANGLETOFINESHIFT); + const fixed_t sinecomponent = FINESINE(pl->plangle>>ANGLETOFINESHIFT); - if (ds_powersoftwo) - { - fixed_t temp; - // Okay, look, don't ask me why this works, but without this setup there's a disgusting-looking misalignment with the textures. -Red - fudgecanyon = ((1<>ANGLETOFINESHIFT); - const fixed_t sinecomponent = FINESINE(hack>>ANGLETOFINESHIFT); + fixed_t ox = (FixedMul(pl->slope->o.x,cosinecomponent) & modmaskw) - (FixedMul(pl->slope->o.y,sinecomponent) & modmaskh); + fixed_t oy = (-FixedMul(pl->slope->o.x,sinecomponent) & modmaskw) - (FixedMul(pl->slope->o.y,cosinecomponent) & modmaskh); - const fixed_t modmask = ((1 << (32-nflatshiftup)) - 1); + fixed_t temp = ox & modmaskw; + oy &= modmaskh; + ox = FixedMul(temp,cosinecomponent)+FixedMul(oy,-sinecomponent); // negative sine for opposite direction + oy = -FixedMul(temp,-sinecomponent)+FixedMul(oy,cosinecomponent); - fixed_t ox = (FixedMul(pl->slope->o.x,cosinecomponent) & modmask) - (FixedMul(pl->slope->o.y,sinecomponent) & modmask); - fixed_t oy = (-FixedMul(pl->slope->o.x,sinecomponent) & modmask) - (FixedMul(pl->slope->o.y,cosinecomponent) & modmask); + temp = xoffs; + xoffs = (FixedMul(temp,cosinecomponent) & modmaskw) + (FixedMul(yoffs,sinecomponent) & modmaskh); + yoffs = (-FixedMul(temp,sinecomponent) & modmaskw) + (FixedMul(yoffs,cosinecomponent) & modmaskh); - temp = ox & modmask; - oy &= modmask; - ox = FixedMul(temp,cosinecomponent)+FixedMul(oy,-sinecomponent); // negative sine for opposite direction - oy = -FixedMul(temp,-sinecomponent)+FixedMul(oy,cosinecomponent); + temp = xoffs & modmaskw; + yoffs &= modmaskh; + xoffs = FixedMul(temp,cosinecomponent)+FixedMul(yoffs,-sinecomponent); // ditto + yoffs = -FixedMul(temp,-sinecomponent)+FixedMul(yoffs,cosinecomponent); - temp = xoffs; - xoffs = (FixedMul(temp,cosinecomponent) & modmask) + (FixedMul(yoffs,sinecomponent) & modmask); - yoffs = (-FixedMul(temp,sinecomponent) & modmask) + (FixedMul(yoffs,cosinecomponent) & modmask); - - temp = xoffs & modmask; - yoffs &= modmask; - xoffs = FixedMul(temp,cosinecomponent)+FixedMul(yoffs,-sinecomponent); // ditto - yoffs = -FixedMul(temp,-sinecomponent)+FixedMul(yoffs,cosinecomponent); - - xoffs -= (pl->slope->o.x - ox); - yoffs += (pl->slope->o.y + oy); - } - else - { - xoffs &= ((1 << (32-nflatshiftup))-1); - yoffs &= ((1 << (32-nflatshiftup))-1); - xoffs -= (pl->slope->o.x + (1 << (31-nflatshiftup))) & ~((1 << (32-nflatshiftup))-1); - yoffs += (pl->slope->o.y + (1 << (31-nflatshiftup))) & ~((1 << (32-nflatshiftup))-1); - } - - xoffs = (fixed_t)(xoffs*fudgecanyon); - yoffs = (fixed_t)(yoffs/fudgecanyon); - } + xoffs -= (pl->slope->o.x - ox); + yoffs += (pl->slope->o.y + oy); if (planeripple.active) { @@ -1018,11 +1019,11 @@ void R_DrawSinglePlane(visplane_t *pl) for (x = pl->high; x < pl->low; x++) { R_CalculatePlaneRipple(pl, x, plheight, true); - R_SetSlopePlaneVectors(pl, x, (xoffs + planeripple.xfrac), (yoffs + planeripple.yfrac), fudgecanyon); + R_SetSlopePlaneVectors(pl, x, (xoffs + planeripple.xfrac), (yoffs + planeripple.yfrac)); } } else - R_SetSlopePlaneVectors(pl, 0, xoffs, yoffs, fudgecanyon); + R_SetSlopePlaneVectors(pl, 0, xoffs, yoffs); switch (spanfunctype) { diff --git a/src/r_plane.h b/src/r_plane.h index 0d11c5b72..8f7574744 100644 --- a/src/r_plane.h +++ b/src/r_plane.h @@ -94,7 +94,9 @@ boolean R_CheckPowersOfTwo(void); void R_DrawSinglePlane(visplane_t *pl); // Calculates the slope vectors needed for tilted span drawing. -void R_CalculateSlopeVectors(pslope_t *slope, fixed_t planeviewx, fixed_t planeviewy, fixed_t planeviewz, fixed_t planexscale, fixed_t planeyscale, fixed_t planexoffset, fixed_t planeyoffset, angle_t planeviewangle, angle_t planeangle, float fudge); +void R_SetSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xoff, fixed_t yoff, angle_t angle, angle_t plangle); +void R_SetSlopePlaneScaled(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xs, fixed_t ys, fixed_t xoff, fixed_t yoff, angle_t angle, angle_t plangle); +void R_CalculateSlopeVectors(void); // Sets the slope vector pointers for the current tilted span. void R_SetTiltedSpan(INT32 span); diff --git a/src/r_splats.c b/src/r_splats.c index 72cac9fd9..49b66304b 100644 --- a/src/r_splats.c +++ b/src/r_splats.c @@ -419,7 +419,8 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr if (pSplat->tilted) { R_SetTiltedSpan(0); - R_CalculateSlopeVectors(&pSplat->slope, viewx, viewy, viewz, pSplat->xscale, pSplat->yscale, -pSplat->verts[0].x, pSplat->verts[0].y, vis->viewangle, pSplat->angle, 1.0f); + R_SetSlopePlaneScaled(&pSplat->slope, viewx, viewy, viewz, pSplat->xscale, pSplat->yscale, -pSplat->verts[0].x, pSplat->verts[0].y, vis->viewangle, pSplat->angle); + R_CalculateSlopeVectors(); spanfunctype = SPANDRAWFUNC_TILTEDSPRITE; } else From d5e9005dd0f49b66e7fa384eaaa6360e535638f1 Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Wed, 14 Apr 2021 11:34:36 -0300 Subject: [PATCH 370/644] Fix NPOT flats, other minor changes. --- src/r_plane.c | 42 ++++++++++++++++-------------------------- src/r_plane.h | 2 +- src/r_splats.c | 2 +- 3 files changed, 18 insertions(+), 28 deletions(-) diff --git a/src/r_plane.c b/src/r_plane.c index a936b0911..10d87b9cc 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -663,7 +663,7 @@ static void R_DrawSkyPlane(visplane_t *pl) } } -// Sets the origin vector of the sloped plane. +// Sets the texture origin vector of the sloped plane. static void R_SetSlopePlaneOrigin(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xoff, fixed_t yoff, fixed_t angle) { floatv3_t *p = &ds_slope_origin; @@ -683,7 +683,7 @@ static void R_SetSlopePlaneOrigin(pslope_t *slope, fixed_t xpos, fixed_t ypos, f p->y = FixedToFloat(P_GetSlopeZAt(slope, -xoff, yoff)) - vz; } -// This function calculates all of the vectors necessary for drawing a tilted span. +// This function calculates all of the vectors necessary for drawing a sloped plane. void R_SetSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xoff, fixed_t yoff, angle_t angle, angle_t plangle) { // Potentially override other stuff for now cus we're mean. :< But draw a slope plane! @@ -710,8 +710,8 @@ void R_SetSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, n->y = FixedToFloat(temp) - zeroheight; } -// This function calculates all of the vectors necessary for drawing a scaled, tilted span. -void R_SetSlopePlaneScaled(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xs, fixed_t ys, fixed_t xoff, fixed_t yoff, angle_t angle, angle_t plangle) +// This function calculates all of the vectors necessary for drawing a sloped and scaled plane. +void R_SetScaledSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xs, fixed_t ys, fixed_t xoff, fixed_t yoff, angle_t angle, angle_t plangle) { floatv3_t *m = &ds_slope_v, *n = &ds_slope_u; fixed_t temp; @@ -740,6 +740,8 @@ void R_SetSlopePlaneScaled(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t void R_CalculateSlopeVectors(void) { + float sfmult = 65536.f; + // Eh. I tried making this stuff fixed-point and it exploded on me. Here's a macro for the only floating-point vector function I recall using. #define CROSS(d, v1, v2) \ d->x = (v1.y * v2.z) - (v1.z * v2.y);\ @@ -755,27 +757,15 @@ d->z = (v1.x * v2.y) - (v1.y * v2.x) ds_szp->z *= focallengthf; // Premultiply the texture vectors with the scale factors -#define SFMULT 65536.f if (ds_powersoftwo) - { - ds_sup->x *= (SFMULT * (1<y *= (SFMULT * (1<z *= (SFMULT * (1<x *= (SFMULT * (1<y *= (SFMULT * (1<z *= (SFMULT * (1<x *= SFMULT; - ds_sup->y *= SFMULT; - ds_sup->z *= SFMULT; - ds_svp->x *= SFMULT; - ds_svp->y *= SFMULT; - ds_svp->z *= SFMULT; - } -#undef SFMULT + sfmult *= (1 << nflatshiftup); + + ds_sup->x *= sfmult; + ds_sup->y *= sfmult; + ds_sup->z *= sfmult; + ds_svp->x *= sfmult; + ds_svp->y *= sfmult; + ds_svp->z *= sfmult; } void R_SetTiltedSpan(INT32 span) @@ -977,8 +967,8 @@ void R_DrawSinglePlane(visplane_t *pl) if (pl->slope) { - const fixed_t modmaskw = (ds_flatwidth << FRACBITS) - 1; - const fixed_t modmaskh = (ds_flatheight << FRACBITS) - 1; + const fixed_t modmaskw = (ds_powersoftwo) ? (ds_flatwidth << FRACBITS) - 1 : (signed)(0xFFFFFFFF); + const fixed_t modmaskh = (ds_powersoftwo) ? (ds_flatheight << FRACBITS) - 1 : (signed)(0xFFFFFFFF); /* Essentially: We can't & the components along the regular axes when the plane is rotated. diff --git a/src/r_plane.h b/src/r_plane.h index 8f7574744..9b7e31e3e 100644 --- a/src/r_plane.h +++ b/src/r_plane.h @@ -95,7 +95,7 @@ void R_DrawSinglePlane(visplane_t *pl); // Calculates the slope vectors needed for tilted span drawing. void R_SetSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xoff, fixed_t yoff, angle_t angle, angle_t plangle); -void R_SetSlopePlaneScaled(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xs, fixed_t ys, fixed_t xoff, fixed_t yoff, angle_t angle, angle_t plangle); +void R_SetScaledSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xs, fixed_t ys, fixed_t xoff, fixed_t yoff, angle_t angle, angle_t plangle); void R_CalculateSlopeVectors(void); // Sets the slope vector pointers for the current tilted span. diff --git a/src/r_splats.c b/src/r_splats.c index 49b66304b..4783fb640 100644 --- a/src/r_splats.c +++ b/src/r_splats.c @@ -419,7 +419,7 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr if (pSplat->tilted) { R_SetTiltedSpan(0); - R_SetSlopePlaneScaled(&pSplat->slope, viewx, viewy, viewz, pSplat->xscale, pSplat->yscale, -pSplat->verts[0].x, pSplat->verts[0].y, vis->viewangle, pSplat->angle); + R_SetScaledSlopePlane(&pSplat->slope, viewx, viewy, viewz, pSplat->xscale, pSplat->yscale, -pSplat->verts[0].x, pSplat->verts[0].y, vis->viewangle, pSplat->angle); R_CalculateSlopeVectors(); spanfunctype = SPANDRAWFUNC_TILTEDSPRITE; } From 7b83345c75d8350c1875765d292b588d257a71a2 Mon Sep 17 00:00:00 2001 From: katsy Date: Wed, 14 Apr 2021 19:29:53 -0500 Subject: [PATCH 371/644] need to create the patches here if they don't already exist --- src/y_inter.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/y_inter.c b/src/y_inter.c index 6833ca2b5..dca8cd377 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -266,6 +266,14 @@ void Y_LoadIntermissionData(void) case int_ctf: case int_teammatch: { + if (!rflagico) //prevent a crash if we haven't cached our team graphics yet + { + rflagico = W_CachePatchName("RFLAGICO", PU_HUDGFX); + bflagico = W_CachePatchName("BFLAGICO", PU_HUDGFX); + rmatcico = W_CachePatchName("RMATCICO", PU_HUDGFX); + bmatcico = W_CachePatchName("BMATCICO", PU_HUDGFX); + } + data.match.redflag = (intertype == int_ctf) ? rflagico : rmatcico; data.match.blueflag = (intertype == int_ctf) ? bflagico : bmatcico; } From 3670af5a31b0810cce9a5f1f4c78158b4914e8db Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Fri, 16 Apr 2021 00:38:34 +0300 Subject: [PATCH 372/644] Fix incorrect values caused by outdated use of timing functions in perfstats 3 --- src/lua_hooklib.c | 2 +- src/m_perfstats.c | 4 ++-- src/m_perfstats.h | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 637809fd8..1665e36b0 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -473,7 +473,7 @@ void LUAh_ThinkFrame(void) hook_p hookp; // variables used by perf stats int hook_index = 0; - int time_taken = 0; + precise_t time_taken = 0; if (!gL || !(hooksAvailable[hook_ThinkFrame/8] & (1<<(hook_ThinkFrame%8)))) return; diff --git a/src/m_perfstats.c b/src/m_perfstats.c index 1596a87e5..b58599b6d 100644 --- a/src/m_perfstats.c +++ b/src/m_perfstats.c @@ -62,7 +62,7 @@ int thinkframe_hooks_capacity = 16; static INT32 draw_row; -void PS_SetThinkFrameHookInfo(int index, UINT32 time_taken, char* short_src) +void PS_SetThinkFrameHookInfo(int index, precise_t time_taken, char* short_src) { if (!thinkframe_hooks) { @@ -565,7 +565,7 @@ void M_DrawPerfStats(void) len = (int)strlen(str); if (len > 20) str += len - 20; - snprintf(s, sizeof s - 1, "%20s: %u", str, thinkframe_hooks[i].time_taken); + snprintf(s, sizeof s - 1, "%20s: %d", str, I_PreciseToMicros(thinkframe_hooks[i].time_taken)); V_DrawSmallString(x, y, V_MONOSPACE | V_ALLOWLOWERCASE | text_color, s); y += 4; // repeated code! if (y > 192) diff --git a/src/m_perfstats.h b/src/m_perfstats.h index 132bea38c..1ca71957f 100644 --- a/src/m_perfstats.h +++ b/src/m_perfstats.h @@ -30,11 +30,11 @@ extern int ps_lua_mobjhooks; typedef struct { - UINT32 time_taken; + precise_t time_taken; char short_src[LUA_IDSIZE]; } ps_hookinfo_t; -void PS_SetThinkFrameHookInfo(int index, UINT32 time_taken, char* short_src); +void PS_SetThinkFrameHookInfo(int index, precise_t time_taken, char* short_src); void M_DrawPerfStats(void); From d35a1811d6a0fd94808a4fcb189a0ffe38bc7483 Mon Sep 17 00:00:00 2001 From: katsy Date: Fri, 16 Apr 2021 04:49:33 -0500 Subject: [PATCH 373/644] clean up bouncy fof code --- src/p_user.c | 46 +++++++--------------------------------------- 1 file changed, 7 insertions(+), 39 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 4413cc6cd..c7eecce9b 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2772,16 +2772,9 @@ static void P_CheckBouncySectors(player_t *player) player->mo->momx = -FixedMul(player->mo->momx,bouncestrength); player->mo->momy = -FixedMul(player->mo->momy,bouncestrength); - if (player->pflags & PF_SPINNING) - { - player->pflags &= ~PF_SPINNING; - player->pflags |= P_GetJumpFlags(player); - player->pflags |= PF_THOKKED; - } } else { - fixed_t newmom; pslope_t *slope = (abs(oldz - topheight) < abs(oldz + player->mo->height - bottomheight)) ? *rover->t_slope : *rover->b_slope; momentum.x = player->mo->momx; @@ -2791,53 +2784,28 @@ static void P_CheckBouncySectors(player_t *player) if (slope) P_ReverseQuantizeMomentumToSlope(&momentum, slope); - newmom = momentum.z = -FixedMul(momentum.z,bouncestrength)/2; + momentum.z = -FixedMul(momentum.z,bouncestrength)/2; - if (abs(newmom) < (bouncestrength*2)) + if (abs(momentum.z) < (bouncestrength*2)) goto bouncydone; - if (!(rover->master->flags & ML_BOUNCY)) - { - if (newmom > 0) - { - if (newmom < 8*FRACUNIT) - newmom = 8*FRACUNIT; - } - else if (newmom < 0) - { - if (newmom > -8*FRACUNIT) - newmom = -8*FRACUNIT; - } - } - - if (newmom > P_GetPlayerHeight(player)/2) - newmom = P_GetPlayerHeight(player)/2; - else if (newmom < -P_GetPlayerHeight(player)/2) - newmom = -P_GetPlayerHeight(player)/2; - - momentum.z = newmom*2; + if (momentum.z > FixedMul(24*FRACUNIT, player->mo->scale)) //half of the default player height + momentum.z = FixedMul(24*FRACUNIT, player->mo->scale); + else if (momentum.z < -FixedMul(24*FRACUNIT, player->mo->scale)) + momentum.z = -FixedMul(24*FRACUNIT, player->mo->scale); if (slope) P_QuantizeMomentumToSlope(&momentum, slope); player->mo->momx = momentum.x; player->mo->momy = momentum.y; - player->mo->momz = momentum.z/2; + player->mo->momz = momentum.z; if (player->pflags & PF_SPINNING) { - player->pflags &= ~PF_SPINNING; - player->pflags |= P_GetJumpFlags(player); player->pflags |= PF_THOKKED; } } - - if ((player->pflags & PF_SPINNING) && player->speed < FixedMul(1<mo->scale) && player->mo->momz) - { - player->pflags &= ~PF_SPINNING; - player->pflags |= P_GetJumpFlags(player); - } - goto bouncydone; } } From ee578b68f48c338bebc50ff66beb70bc919ae3a6 Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Sat, 17 Apr 2021 03:11:29 +0300 Subject: [PATCH 374/644] Remove bad pointer arithmetic in polygon comparators, that was causing glitches --- src/hardware/hw_batching.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/hardware/hw_batching.c b/src/hardware/hw_batching.c index fb3417158..b13ad03ea 100644 --- a/src/hardware/hw_batching.c +++ b/src/hardware/hw_batching.c @@ -137,6 +137,8 @@ static int comparePolygons(const void *p1, const void *p2) PolygonArrayEntry* poly2 = &polygonArray[index2]; int diff; INT64 diff64; + UINT32 downloaded1 = 0; + UINT32 downloaded2 = 0; int shader1 = poly1->shader; int shader2 = poly2->shader; @@ -152,7 +154,11 @@ static int comparePolygons(const void *p1, const void *p2) if (shader1 == -1 && shader2 == -1) return index1 - index2; - diff64 = poly1->texture - poly2->texture; + if (poly1->texture) + downloaded1 = poly1->texture->downloaded; // there should be a opengl texture name here, usable for comparisons + if (poly2->texture) + downloaded2 = poly2->texture->downloaded; + diff64 = downloaded1 - downloaded2; if (diff64 != 0) return diff64; diff = poly1->polyFlags - poly2->polyFlags; @@ -184,16 +190,21 @@ static int comparePolygonsNoShaders(const void *p1, const void *p2) GLMipmap_t *texture1 = poly1->texture; GLMipmap_t *texture2 = poly2->texture; + UINT32 downloaded1 = 0; + UINT32 downloaded2 = 0; if (poly1->polyFlags & PF_NoTexture || poly1->horizonSpecial) texture1 = NULL; if (poly2->polyFlags & PF_NoTexture || poly2->horizonSpecial) texture2 = NULL; - diff64 = texture1 - texture2; - if (diff64 != 0) return diff64; - + if (texture1) + downloaded1 = texture1->downloaded; // there should be a opengl texture name here, usable for comparisons + if (texture2) + downloaded2 = texture2->downloaded; // skywalls and horizon lines must retain their order for horizon lines to work - if (texture1 == NULL && texture2 == NULL) + if (!texture1 && !texture2) return index1 - index2; + diff64 = downloaded1 - downloaded2; + if (diff64 != 0) return diff64; diff = poly1->polyFlags - poly2->polyFlags; if (diff != 0) return diff; From d59f25a6cdd16fd1133c089bf6ba740dbc42e657 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 18 Apr 2021 12:59:49 -0400 Subject: [PATCH 375/644] stagefailed is more useful - Can now apply to normal stages, simply defaults to "false" in normal stages. - Post-level cutscenes are now always skipped when the stage was failed. - Exposed the boolean as a Lua read+write global. Desired for SUGOI, as it allows for visited flags not be updated, and level completion emblems to not be awarded. Which means a lot less crappy non-ideal workarounds. Normal stage intermission currently does not reflect failure state at all. Maybe it could always skip, never award score bonuses, have different text... etc. Probably would leave that up to vanilla dev opinion. --- src/doomstat.h | 2 +- src/g_game.c | 15 +++++++++++---- src/lua_script.c | 5 +++++ src/p_setup.c | 6 ++++-- 4 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/doomstat.h b/src/doomstat.h index 2d28b81af..2dbb144e6 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -496,7 +496,7 @@ extern UINT32 lastcustomtol; extern tic_t totalplaytime; -extern UINT8 stagefailed; +extern boolean stagefailed; // Emeralds stored as bits to throw savegame hackers off. extern UINT16 emeralds; diff --git a/src/g_game.c b/src/g_game.c index 2b304b4fd..e6c445d68 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -169,7 +169,7 @@ static boolean exitgame = false; static boolean retrying = false; static boolean retryingmodeattack = false; -UINT8 stagefailed; // Used for GEMS BONUS? Also to see if you beat the stage. +boolean stagefailed = false; // Used for GEMS BONUS? Also to see if you beat the stage. UINT16 emeralds; INT32 luabanks[NUM_LUABANKS]; @@ -3742,7 +3742,7 @@ static void G_UpdateVisited(void) // Update visitation flags? if ((!modifiedgame || savemoddata) // Not modified && !multiplayer && !demoplayback && (gametype == GT_COOP) // SP/RA/NiGHTS mode - && !(spec && stagefailed)) // Not failed the special stage + && !stagefailed) // Did not fail the stage { UINT8 earnedEmblems; @@ -3963,7 +3963,7 @@ static void G_DoCompleted(void) // If the current gametype has no intermission screen set, then don't start it. Y_DetermineIntermissionType(); - if ((skipstats && !modeattacking) || (spec && modeattacking && stagefailed) || (intertype == int_none)) + if ((skipstats && !modeattacking) || (modeattacking && stagefailed) || (intertype == int_none)) { G_UpdateVisited(); G_HandleSaveLevel(); @@ -3994,8 +3994,15 @@ void G_AfterIntermission(void) HU_ClearCEcho(); - if ((gametyperules & GTR_CUTSCENES) && mapheaderinfo[gamemap-1]->cutscenenum && !modeattacking && skipstats <= 1 && (gamecomplete || !(marathonmode & MA_NOCUTSCENES))) // Start a custom cutscene. + if ((gametyperules & GTR_CUTSCENES) && mapheaderinfo[gamemap-1]->cutscenenum + && !modeattacking + && skipstats <= 1 + && (gamecomplete || !(marathonmode & MA_NOCUTSCENES)) + && stagefailed == false) + { + // Start a custom cutscene. F_StartCustomCutscene(mapheaderinfo[gamemap-1]->cutscenenum-1, false, false); + } else { if (nextmap < 1100-1) diff --git a/src/lua_script.c b/src/lua_script.c index 7fd5a98e6..0a7e44422 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -380,6 +380,9 @@ int LUA_PushGlobals(lua_State *L, const char *word) } else if (fastcmp(word, "gamestate")) { lua_pushinteger(L, gamestate); return 1; + } else if (fastcmp(word, "stagefailed")) { + lua_pushboolean(L, stagefailed); + return 1; } return 0; } @@ -429,6 +432,8 @@ int LUA_CheckGlobals(lua_State *L, const char *word) } else if (fastcmp(word, "mapmusflags")) mapmusflags = (UINT16)luaL_checkinteger(L, 2); + else if (fastcmp(word, "stagefailed")) + stagefailed = luaL_checkboolean(L, 2); else return 0; diff --git a/src/p_setup.c b/src/p_setup.c index 40dd1a284..2e7db1055 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3394,8 +3394,10 @@ static void P_InitLevelSettings(void) numstarposts = 0; ssspheres = timeinmap = 0; - // special stage - stagefailed = true; // assume failed unless proven otherwise - P_GiveEmerald or emerald touchspecial + // Assume Special Stages were failed in unless proven otherwise - via P_GiveEmerald or emerald touchspecial + // Normal stages will default to be OK, unless a Lua script sets to false. + stagefailed = G_IsSpecialStage(gamemap); + // Reset temporary record data memset(&ntemprecords, 0, sizeof(nightsdata_t)); From b026a6991cb87b870de07daa191b9fa87a2ac087 Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Mon, 19 Apr 2021 15:52:07 -0300 Subject: [PATCH 376/644] Easing functions --- src/CMakeLists.txt | 2 + src/Makefile | 1 + src/m_easing.c | 399 +++++++++++++++++++++++++++++++++++++++++++++ src/m_easing.h | 95 +++++++++++ 4 files changed, 497 insertions(+) create mode 100644 src/m_easing.c create mode 100644 src/m_easing.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 87a0499b6..cd6e17386 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -32,6 +32,7 @@ set(SRB2_CORE_SOURCES m_bbox.c m_cheat.c m_cond.c + m_easing.c m_fixed.c m_menu.c m_misc.c @@ -101,6 +102,7 @@ set(SRB2_CORE_HEADERS m_cheat.h m_cond.h m_dllist.h + m_easing.h m_fixed.h m_menu.h m_misc.h diff --git a/src/Makefile b/src/Makefile index a4c3c4fdb..bdca6dc08 100644 --- a/src/Makefile +++ b/src/Makefile @@ -503,6 +503,7 @@ OBJS:=$(i_main_o) \ $(OBJDIR)/m_bbox.o \ $(OBJDIR)/m_cheat.o \ $(OBJDIR)/m_cond.o \ + $(OBJDIR)/m_easing.o \ $(OBJDIR)/m_fixed.o \ $(OBJDIR)/m_menu.o \ $(OBJDIR)/m_misc.o \ diff --git a/src/m_easing.c b/src/m_easing.c new file mode 100644 index 000000000..b3ea8842f --- /dev/null +++ b/src/m_easing.c @@ -0,0 +1,399 @@ +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 2020-2021 by Jaime "Lactozilla" Passos. +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- +/// \file m_easing.c +/// \brief Easing functions +/// Referenced from https://easings.net/ + +#include "m_easing.h" +#include "tables.h" +#include "doomdef.h" + +/* + For the computation of the logarithm, we choose, by trial and error, from among + a sequence of particular factors those, that when multiplied with the function + argument, normalize it to unity. For every factor chosen, we add up the + corresponding logarithm value stored in a table. The sum then corresponds to + the logarithm of the function argument. + + For the integer portion, we would want to choose + 2^i, i = 1, 2, 4, 8, ... + and for the factional part we choose + 1+2^-i, i = 1, 2, 3, 4, 5 ... + + The algorithm for the exponential is closely related and quite literally the inverse + of the logarithm algorithm. From among the sequence of tabulated logarithms for our + chosen factors, we pick those that when subtracted from the function argument ultimately + reduce it to zero. Starting with unity, we multiply with all the factors whose logarithms + we have subtracted in the process. The resulting product corresponds to the result of the exponentiation. + + Logarithms of values greater than unity can be computed by applying the algorithm to the reciprocal + of the function argument (with the negation of the result as appropriate), likewise exponentiation with + negative function arguments requires us negate the function argument and compute the reciprocal at the end. +*/ + +static fixed_t logtabdec[FRACBITS] = +{ + 0x95c1, 0x526a, 0x2b80, 0x1663, + 0xb5d, 0x5b9, 0x2e0, 0x170, + 0xb8, 0x5c, 0x2e, 0x17, + 0x0b, 0x06, 0x03, 0x01 +}; + +static fixed_t fixlog2(fixed_t a) +{ + UINT32 x = a, y = 0; + INT32 t, i, shift = 8; + + if (x > FRACUNIT) + x = FixedDiv(FRACUNIT, x); + + // Integer part + // 1<<19 = 0x80000 + // 1<<18 = 0x40000 + // 1<<17 = 0x20000 + // 1<<16 = 0x10000 + +#define dologtab(i) \ + t = (x << shift); \ + if (t < FRACUNIT) \ + { \ + x = t; \ + y += (1 << (19 - i)); \ + } \ + shift /= 2; + + dologtab(0) + dologtab(1) + dologtab(2) + dologtab(3) + +#undef dologtab + + // Decimal part + for (i = 0; i < FRACBITS; i++) + { + t = x + (x >> (i + 1)); + if (t < FRACUNIT) + { + x = t; + y += logtabdec[i]; + } + } + + if (a <= FRACUNIT) + return -y; + + return y; +} + +// Notice how this is symmetric to fixlog2. +static INT32 fixexp(fixed_t a) +{ + UINT32 x, y; + fixed_t t, i, shift = 8; + + // Underflow prevention. + if (a <= -15 * FRACUNIT) + return 0; + + x = (a < 0) ? (-a) : (a); + y = FRACUNIT; + + // Integer part (see fixlog2) +#define dologtab(i) \ + t = x - (1 << (19 - i)); \ + if (t >= 0) \ + { \ + x = t; \ + y <<= shift; \ + } \ + shift /= 2; + + dologtab(0) + dologtab(1) + dologtab(2) + dologtab(3) + +#undef dologtab + + // Decimal part + for (i = 0; i < FRACBITS; i++) + { + t = (x - logtabdec[i]); + if (t >= 0) + { + x = t; + y += (y >> (i + 1)); + } + } + + if (a < 0) + return FixedDiv(FRACUNIT, y); + + return y; +} + +#define fixpow(x, y) fixexp(FixedMul((y), fixlog2(x))) +#define fixintmul(x, y) FixedMul((x) * FRACUNIT, y) +#define fixintdiv(x, y) FixedDiv(x, (y) * FRACUNIT) +#define fixinterp(start, end, t) FixedMul((FRACUNIT - (t)), start) + FixedMul(t, end) + +#define EASINGFUNC(type) fixed_t Easing_ ## type (fixed_t start, fixed_t end, fixed_t t) + +// +// Linear +// + +EASINGFUNC(Linear) +{ + return fixinterp(start, end, t); +} + +// +// Sine +// + +// This is equivalent to calculating (x * pi) and converting the result from radians into degrees. +#define fixang(x) FixedMul((x), 180*FRACUNIT) + +EASINGFUNC(InSine) +{ + fixed_t c = fixang(t / 2); + fixed_t x = FRACUNIT - FINECOSINE(FixedAngle(c)>>ANGLETOFINESHIFT); + return fixinterp(start, end, x); +} + +EASINGFUNC(OutSine) +{ + fixed_t c = fixang(t / 2); + fixed_t x = FINESINE(FixedAngle(c)>>ANGLETOFINESHIFT); + return fixinterp(start, end, x); +} + +EASINGFUNC(InOutSine) +{ + fixed_t c = fixang(t); + fixed_t x = -(FINECOSINE(FixedAngle(c)>>ANGLETOFINESHIFT) - FRACUNIT) / 2; + return fixinterp(start, end, x); +} + +#undef fixang + +// +// Quad +// + +EASINGFUNC(InQuad) +{ + return fixinterp(start, end, FixedMul(t, t)); +} + +EASINGFUNC(OutQuad) +{ + return fixinterp(start, end, FRACUNIT - FixedMul(FRACUNIT - t, FRACUNIT - t)); +} + +EASINGFUNC(InOutQuad) +{ + fixed_t x = t < (FRACUNIT/2) + ? fixintmul(2, FixedMul(t, t)) + : FRACUNIT - fixpow(FixedMul(-2*FRACUNIT, t) + 2*FRACUNIT, 2*FRACUNIT) / 2; + return fixinterp(start, end, x); +} + +// +// Cubic +// + +EASINGFUNC(InCubic) +{ + fixed_t x = FixedMul(t, FixedMul(t, t)); + return fixinterp(start, end, x); +} + +EASINGFUNC(OutCubic) +{ + return fixinterp(start, end, FRACUNIT - fixpow(FRACUNIT - t, 3*FRACUNIT)); +} + +EASINGFUNC(InOutCubic) +{ + fixed_t x = t < (FRACUNIT/2) + ? fixintmul(4, FixedMul(t, FixedMul(t, t))) + : FRACUNIT - fixpow(fixintmul(-2, t) + 2*FRACUNIT, 3*FRACUNIT) / 2; + return fixinterp(start, end, x); +} + +// +// "Quart" +// + +EASINGFUNC(InQuart) +{ + fixed_t x = FixedMul(FixedMul(t, t), FixedMul(t, t)); + return fixinterp(start, end, x); +} + +EASINGFUNC(OutQuart) +{ + fixed_t x = FRACUNIT - fixpow(FRACUNIT - t, 4 * FRACUNIT); + return fixinterp(start, end, x); +} + +EASINGFUNC(InOutQuart) +{ + fixed_t x = t < (FRACUNIT/2) + ? fixintmul(8, FixedMul(FixedMul(t, t), FixedMul(t, t))) + : FRACUNIT - fixpow(fixintmul(-2, t) + 2*FRACUNIT, 4*FRACUNIT) / 2; + return fixinterp(start, end, x); +} + +// +// "Quint" +// + +EASINGFUNC(InQuint) +{ + fixed_t x = FixedMul(t, FixedMul(FixedMul(t, t), FixedMul(t, t))); + return fixinterp(start, end, x); +} + +EASINGFUNC(OutQuint) +{ + fixed_t x = FRACUNIT - fixpow(FRACUNIT - t, 5 * FRACUNIT); + return fixinterp(start, end, x); +} + +EASINGFUNC(InOutQuint) +{ + fixed_t x = t < (FRACUNIT/2) + ? FixedMul(16*FRACUNIT, FixedMul(t, FixedMul(FixedMul(t, t), FixedMul(t, t)))) + : FRACUNIT - fixpow(fixintmul(-2, t) + 2*FRACUNIT, 5*FRACUNIT) / 2; + return fixinterp(start, end, x); +} + +// +// Exponential +// + +EASINGFUNC(InExpo) +{ + fixed_t x = (!t) ? 0 : fixpow(2*FRACUNIT, fixintmul(10, t) - 10*FRACUNIT); + return fixinterp(start, end, x); +} + +EASINGFUNC(OutExpo) +{ + fixed_t x = (t >= FRACUNIT) ? FRACUNIT + : FRACUNIT - fixpow(2*FRACUNIT, fixintmul(-10, t)); + return fixinterp(start, end, x); +} + +EASINGFUNC(InOutExpo) +{ + fixed_t x; + + if (!t) + x = 0; + else if (t >= FRACUNIT) + x = FRACUNIT; + else + { + if (t < FRACUNIT / 2) + { + x = fixpow(2*FRACUNIT, fixintmul(20, t) - 10*FRACUNIT); + x = fixintdiv(x, 2); + } + else + { + x = fixpow(2*FRACUNIT, fixintmul(-20, t) + 10*FRACUNIT); + x = fixintdiv((2*FRACUNIT) - x, 2); + } + } + + return fixinterp(start, end, x); +} + +// +// "Back" +// + +#define EASEBACKCONST1 111514 // 1.70158 +#define EASEBACKCONST2 99942 // 1.525 + +EASINGFUNC(InBack) +{ + const fixed_t c1 = EASEBACKCONST1; + const fixed_t c3 = c1 + FRACUNIT; + fixed_t x = FixedMul(FixedMul(t, t), FixedMul(c3, t) - c1); + return fixinterp(start, end, x); +} + +EASINGFUNC(OutBack) +{ + const fixed_t c1 = EASEBACKCONST1; + const fixed_t c3 = c1 + FRACUNIT; + fixed_t x; + t -= FRACUNIT; + x = FRACUNIT + FixedMul(FixedMul(t, t), FixedMul(c3, t) + c1); + return fixinterp(start, end, x); +} + +static fixed_t DoEaseInOutBack(fixed_t start, fixed_t end, fixed_t t, fixed_t c2) +{ + fixed_t x; + + c2 += FRACUNIT; + + if (t < FRACUNIT / 2) + { + x = fixintmul(7, t) - c2; + x = fixintmul(2, x); + x = FixedMul(FixedMul(t, t), x); + } + else + { + t -= FRACUNIT; + x = fixintmul(2, fixintmul(7, t) + c2); + x = FixedMul(FixedMul(t, t), x); + x = FRACUNIT + x; + } + + return fixinterp(start, end, x); +} + +EASINGFUNC(InOutBack) +{ + return DoEaseInOutBack(start, end, t, EASEBACKCONST2); +} + +#undef EASINGFUNC + +// Function list + +#define EASINGFUNC(type) Easing_ ## type +#define COMMA , + +easingfunc_t easing_funclist[EASE_MAX] = +{ + EASINGFUNCLIST(COMMA) +}; + +// Function names + +#undef EASINGFUNC +#define EASINGFUNC(type) #type + +const char *easing_funcnames[EASE_MAX] = +{ + EASINGFUNCLIST(COMMA) +}; + +#undef COMMA +#undef EASINGFUNC diff --git a/src/m_easing.h b/src/m_easing.h new file mode 100644 index 000000000..e5571ece3 --- /dev/null +++ b/src/m_easing.h @@ -0,0 +1,95 @@ +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 2020-2021 by Jaime "Lactozilla" Passos. +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- +/// \file m_easing.h +/// \brief Easing functions + +#ifndef __M_EASING_H__ +#define __M_EASING_H__ + +#include "doomtype.h" +#include "m_fixed.h" + +typedef enum +{ + EASE_LINEAR = 0, + + EASE_INSINE, + EASE_OUTSINE, + EASE_INOUTSINE, + + EASE_INQUAD, + EASE_OUTQUAD, + EASE_INOUTQUAD, + + EASE_INCUBIC, + EASE_OUTCUBIC, + EASE_INOUTCUBIC, + + EASE_INQUART, + EASE_OUTQUART, + EASE_INOUTQUART, + + EASE_INQUINT, + EASE_OUTQUINT, + EASE_INOUTQUINT, + + EASE_INEXPO, + EASE_OUTEXPO, + EASE_INOUTEXPO, + + EASE_INBACK, + EASE_OUTBACK, + EASE_INOUTBACK, + + EASE_MAX, +} easing_t; + +typedef fixed_t (*easingfunc_t)(fixed_t, fixed_t, fixed_t); + +extern easingfunc_t easing_funclist[EASE_MAX]; +extern const char *easing_funcnames[EASE_MAX]; + +#define EASINGFUNCLIST(sep) \ + EASINGFUNC(Linear) sep \ + \ + EASINGFUNC(InSine) sep \ + EASINGFUNC(OutSine) sep \ + EASINGFUNC(InOutSine) sep \ + \ + EASINGFUNC(InQuad) sep \ + EASINGFUNC(OutQuad) sep \ + EASINGFUNC(InOutQuad) sep \ + \ + EASINGFUNC(InCubic) sep \ + EASINGFUNC(OutCubic) sep \ + EASINGFUNC(InOutCubic) sep \ + \ + EASINGFUNC(InQuart) sep \ + EASINGFUNC(OutQuart) sep \ + EASINGFUNC(InOutQuart) sep \ + \ + EASINGFUNC(InQuint) sep \ + EASINGFUNC(OutQuint) sep \ + EASINGFUNC(InOutQuint) sep \ + \ + EASINGFUNC(InExpo) sep \ + EASINGFUNC(OutExpo) sep \ + EASINGFUNC(InOutExpo) sep \ + \ + EASINGFUNC(InBack) sep \ + EASINGFUNC(OutBack) sep \ + EASINGFUNC(InOutBack) sep + +#define EASINGFUNC(type) fixed_t Easing_ ## type (fixed_t start, fixed_t end, fixed_t t); + +EASINGFUNCLIST() + +#undef EASINGFUNC + +#endif From 228668ce986e2f44fec2e085c9ee7e174ed3f3d3 Mon Sep 17 00:00:00 2001 From: SMS Alfredo <65426124+SMS-Alfredo@users.noreply.github.com> Date: Mon, 19 Apr 2021 14:25:34 -0500 Subject: [PATCH 377/644] Change the render flags to extra flags and improve SF_NOSUPERSPRITES --- src/deh_tables.c | 5 ++--- src/p_mobj.c | 12 +++++++----- src/p_mobj.h | 29 +++++++++++++++++------------ src/r_defs.h | 4 ---- 4 files changed, 26 insertions(+), 24 deletions(-) diff --git a/src/deh_tables.c b/src/deh_tables.c index f3a77d528..621c6aae4 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -4351,6 +4351,8 @@ const char *const MOBJEFLAG_LIST[] = { "SPRUNG", // Mobj was already sprung this tic "APPLYPMOMZ", // Platform movement "TRACERANGLE", // Compute and trigger on mobj angle relative to tracer + "FORCESUPER", // Forces an object to use super sprites with SPR_PLAY. + "FORCENOSUPER", // Forces an object to NOT use super sprites with SPR_PLAY. NULL }; @@ -4905,9 +4907,6 @@ struct int_const_s const INT_CONST[] = { {"RF_SHADOWDRAW",RF_SHADOWDRAW}, {"RF_SHADOWEFFECTS",RF_SHADOWEFFECTS}, {"RF_DROPSHADOW",RF_DROPSHADOW}, - {"RF_FORCESUPER",RF_FORCESUPER}, - {"RF_FORCENOSUPER",RF_FORCENOSUPER}, - {"RF_REVERSESUPER",RF_REVERSESUPER}, // Level flags {"LF_SCRIPTISFILE",LF_SCRIPTISFILE}, diff --git a/src/p_mobj.c b/src/p_mobj.c index 3f77f28aa..4e9015e8a 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -397,15 +397,17 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) UINT16 stateframe = st->frame; // Add/Remove FF_SPR2SUPER based on certain conditions - if (player->powers[pw_super] && !(player->charflags & SF_NOSUPERSPRITES)) + if (player->charflags & SF_NOSUPERSPRITES) + stateframe = stateframe & ~FF_SPR2SUPER; + else if (player->powers[pw_super]) stateframe = stateframe | FF_SPR2SUPER; if (stateframe & FF_SPR2SUPER) { - if (mobj->renderflags & RF_FORCENOSUPER) + if (mobj->eflags & MFE_FORCENOSUPER) stateframe = stateframe & ~FF_SPR2SUPER; } - else if (mobj->renderflags & RF_FORCESUPER) + else if (mobj->eflags & MFE_FORCESUPER) stateframe = stateframe | FF_SPR2SUPER; // Get the sprite2 and frame number @@ -543,10 +545,10 @@ boolean P_SetMobjState(mobj_t *mobj, statenum_t state) // Add/Remove FF_SPR2SUPER based on certain conditions if (stateframe & FF_SPR2SUPER) { - if (mobj->renderflags & RF_FORCENOSUPER) + if (mobj->eflags & MFE_FORCENOSUPER) stateframe = stateframe & ~FF_SPR2SUPER; } - else if (mobj->renderflags & RF_FORCESUPER) + else if (mobj->eflags & MFE_FORCESUPER) stateframe = stateframe | FF_SPR2SUPER; // Get the sprite2 and frame number diff --git a/src/p_mobj.h b/src/p_mobj.h index 5bb7c908e..c4567c27d 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -218,33 +218,38 @@ typedef enum typedef enum { // The mobj stands on solid floor (not on another mobj or in air) - MFE_ONGROUND = 1, + MFE_ONGROUND = 1, // The mobj just hit the floor while falling, this is cleared on next frame // (instant damage in lava/slime sectors to prevent jump cheat..) - MFE_JUSTHITFLOOR = 1<<1, + MFE_JUSTHITFLOOR = 1<<1, // The mobj stands in a sector with water, and touches the surface // this bit is set once and for all at the start of mobjthinker - MFE_TOUCHWATER = 1<<2, + MFE_TOUCHWATER = 1<<2, // The mobj stands in a sector with water, and his waist is BELOW the water surface // (for player, allows swimming up/down) - MFE_UNDERWATER = 1<<3, + MFE_UNDERWATER = 1<<3, // used for ramp sectors - MFE_JUSTSTEPPEDDOWN = 1<<4, + MFE_JUSTSTEPPEDDOWN = 1<<4, // Vertically flip sprite/allow upside-down physics - MFE_VERTICALFLIP = 1<<5, + MFE_VERTICALFLIP = 1<<5, // Goo water - MFE_GOOWATER = 1<<6, + MFE_GOOWATER = 1<<6, // The mobj is touching a lava block - MFE_TOUCHLAVA = 1<<7, + MFE_TOUCHLAVA = 1<<7, // Mobj was already pushed this tic - MFE_PUSHED = 1<<8, + MFE_PUSHED = 1<<8, // Mobj was already sprung this tic - MFE_SPRUNG = 1<<9, + MFE_SPRUNG = 1<<9, // Platform movement - MFE_APPLYPMOMZ = 1<<10, + MFE_APPLYPMOMZ = 1<<10, // Compute and trigger on mobj angle relative to tracer // See Linedef Exec 457 (Track mobj angle to point) - MFE_TRACERANGLE = 1<<11, + MFE_TRACERANGLE = 1<<11, + // Forces an object to use super sprites with SPR_PLAY. + MFE_FORCESUPER = 1<<12, + // Forces an object to NOT use super sprites with SPR_PLAY. + MFE_FORCENOSUPER = 1<<13, + // free: to and including 1<<15 } mobjeflag_t; diff --git a/src/r_defs.h b/src/r_defs.h index 31f30dd6f..9c649fbc4 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -738,10 +738,6 @@ typedef enum RF_SHADOWDRAW = 0x10000, // Stretches and skews the sprite like a shadow. RF_SHADOWEFFECTS = 0x20000, // Scales and becomes transparent like a shadow. RF_DROPSHADOW = (RF_SHADOWDRAW | RF_SHADOWEFFECTS | RF_FULLDARK), - - RF_FORCESUPER = 0x40000, // Forces an object to use super sprites with SPR_PLAY. - RF_FORCENOSUPER = 0x80000, // Forces an object to NOT use super sprites with SPR_PLAY. - RF_REVERSESUPER = (RF_FORCESUPER | RF_FORCENOSUPER), //Use normal sprites in place of super sprites and vice-versa } renderflags_t; typedef enum From d8d3dee46f73d974310a5d18046497087a07a5ad Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 19 Apr 2021 17:20:34 -0400 Subject: [PATCH 378/644] Add linedef executor for toggling stagefailed By default, the executor will fail the stage. If Not Climbable is checked, the stage can be completed normally again. --- src/p_setup.c | 2 +- src/p_spec.c | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/p_setup.c b/src/p_setup.c index 2e7db1055..ec516992e 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3395,7 +3395,7 @@ static void P_InitLevelSettings(void) ssspheres = timeinmap = 0; // Assume Special Stages were failed in unless proven otherwise - via P_GiveEmerald or emerald touchspecial - // Normal stages will default to be OK, unless a Lua script sets to false. + // Normal stages will default to be OK, until a Lua script / linedef executor says otherwise. stagefailed = G_IsSpecialStage(gamemap); // Reset temporary record data diff --git a/src/p_spec.c b/src/p_spec.c index 226e58d15..be120b686 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3902,6 +3902,21 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) } break; + case 466: // Set level failure state + { + if (line->flags & ML_NOCLIMB) + { + stagefailed = false; + CONS_Debug(DBG_GAMELOGIC, "Stage can be completed successfully!\n"); + } + else + { + stagefailed = true; + CONS_Debug(DBG_GAMELOGIC, "Stage will end in failure...\n"); + } + } + break; + case 480: // Polyobj_DoorSlide case 481: // Polyobj_DoorSwing PolyDoor(line); From 30e7455178f43661ad7508ce79fd90bb89020d0d Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 19 Apr 2021 17:50:49 -0400 Subject: [PATCH 379/644] Failing a stage just displays the level title --- src/y_inter.c | 51 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 14 deletions(-) diff --git a/src/y_inter.c b/src/y_inter.c index bd3b557d7..4b37b9f61 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -1259,24 +1259,40 @@ void Y_StartIntermission(void) usetile = false; // set up the "got through act" message according to skin name - // too long so just show "YOU GOT THROUGH THE ACT" - if (strlen(skins[players[consoleplayer].skin].realname) > 13) + if (stagefailed) { - strcpy(data.coop.passed1, "you got"); - strcpy(data.coop.passed2, (mapheaderinfo[gamemap-1]->actnum) ? "through act" : "through the act"); + strcpy(data.coop.passed1, mapheaderinfo[gamemap-1]->lvlttl); + + if (mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE) + { + data.spec.passed2[0] = '\0'; + } + else + { + strcpy(data.coop.passed2, "Zone"); + } } - // long enough that "X GOT" won't fit so use "X PASSED THE ACT" - else if (strlen(skins[players[consoleplayer].skin].realname) > 8) - { - strcpy(data.coop.passed1, skins[players[consoleplayer].skin].realname); - strcpy(data.coop.passed2, (mapheaderinfo[gamemap-1]->actnum) ? "passed act" : "passed the act"); - } - // length is okay for normal use else { - snprintf(data.coop.passed1, sizeof data.coop.passed1, "%s got", - skins[players[consoleplayer].skin].realname); - strcpy(data.coop.passed2, (mapheaderinfo[gamemap-1]->actnum) ? "through act" : "through the act"); + // too long so just show "YOU GOT THROUGH THE ACT" + if (strlen(skins[players[consoleplayer].skin].realname) > 13) + { + strcpy(data.coop.passed1, "you got"); + strcpy(data.coop.passed2, (mapheaderinfo[gamemap-1]->actnum) ? "through act" : "through the act"); + } + // long enough that "X GOT" won't fit so use "X PASSED THE ACT" + else if (strlen(skins[players[consoleplayer].skin].realname) > 8) + { + strcpy(data.coop.passed1, skins[players[consoleplayer].skin].realname); + strcpy(data.coop.passed2, (mapheaderinfo[gamemap-1]->actnum) ? "passed act" : "passed the act"); + } + // length is okay for normal use + else + { + snprintf(data.coop.passed1, sizeof data.coop.passed1, "%s got", + skins[players[consoleplayer].skin].realname); + strcpy(data.coop.passed2, (mapheaderinfo[gamemap-1]->actnum) ? "through act" : "through the act"); + } } // set X positions @@ -1293,6 +1309,13 @@ void Y_StartIntermission(void) // The above value is not precalculated because it needs only be computed once // at the start of intermission, and precalculating it would preclude mods // changing the font to one of a slightly different width. + + if ((stagefailed) && !(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE)) + { + // Bit of a hack, offset so that the "Zone" text is right aligned like title cards. + data.coop.passedx2 = (data.coop.passedx1 + V_LevelNameWidth(data.coop.passed1)) - V_LevelNameWidth(data.coop.passed2); + } + break; } From 41f492f2f90225ed55c82c8bee377d0ae2365a4b Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 19 Apr 2021 17:59:55 -0400 Subject: [PATCH 380/644] Don't award any potentially cheesable bonuses if the stage was failed. Time Bonus is 0'd out if the stage was failed, since you can defeat the whole point of it if the stage lets you fail it immediately. Same with Guard Bonus -- it's not really a no-hit run if you didn't interact with anything. Kept others that are more effort-based like Ring Bonus to give the player a little bit of partial credit, especially since Special Stages do this too. --- src/y_inter.c | 60 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 39 insertions(+), 21 deletions(-) diff --git a/src/y_inter.c b/src/y_inter.c index 4b37b9f61..0627a3aa7 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -1771,21 +1771,30 @@ static void Y_SetTimeBonus(player_t *player, y_bonus_t *bstruct) strncpy(bstruct->patch, "YB_TIME", sizeof(bstruct->patch)); bstruct->display = true; - // calculate time bonus - secs = player->realtime / TICRATE; - if (secs < 30) /* :30 */ bonus = 50000; - else if (secs < 60) /* 1:00 */ bonus = 10000; - else if (secs < 90) /* 1:30 */ bonus = 5000; - else if (secs < 120) /* 2:00 */ bonus = 4000; - else if (secs < 180) /* 3:00 */ bonus = 3000; - else if (secs < 240) /* 4:00 */ bonus = 2000; - else if (secs < 300) /* 5:00 */ bonus = 1000; - else if (secs < 360) /* 6:00 */ bonus = 500; - else if (secs < 420) /* 7:00 */ bonus = 400; - else if (secs < 480) /* 8:00 */ bonus = 300; - else if (secs < 540) /* 9:00 */ bonus = 200; - else if (secs < 600) /* 10:00 */ bonus = 100; - else /* TIME TAKEN: TOO LONG */ bonus = 0; + if (stagefailed == true) + { + // Time Bonus would be very easy to cheese by failing immediately. + bonus = 0; + } + else + { + // calculate time bonus + secs = player->realtime / TICRATE; + if (secs < 30) /* :30 */ bonus = 50000; + else if (secs < 60) /* 1:00 */ bonus = 10000; + else if (secs < 90) /* 1:30 */ bonus = 5000; + else if (secs < 120) /* 2:00 */ bonus = 4000; + else if (secs < 180) /* 3:00 */ bonus = 3000; + else if (secs < 240) /* 4:00 */ bonus = 2000; + else if (secs < 300) /* 5:00 */ bonus = 1000; + else if (secs < 360) /* 6:00 */ bonus = 500; + else if (secs < 420) /* 7:00 */ bonus = 400; + else if (secs < 480) /* 8:00 */ bonus = 300; + else if (secs < 540) /* 9:00 */ bonus = 200; + else if (secs < 600) /* 10:00 */ bonus = 100; + else /* TIME TAKEN: TOO LONG */ bonus = 0; + } + bstruct->points = bonus; } @@ -1838,12 +1847,21 @@ static void Y_SetGuardBonus(player_t *player, y_bonus_t *bstruct) strncpy(bstruct->patch, "YB_GUARD", sizeof(bstruct->patch)); bstruct->display = true; - if (player->timeshit == 0) bonus = 10000; - else if (player->timeshit == 1) bonus = 5000; - else if (player->timeshit == 2) bonus = 1000; - else if (player->timeshit == 3) bonus = 500; - else if (player->timeshit == 4) bonus = 100; - else bonus = 0; + if (stagefailed == true) + { + // "No-hit" runs would be very easy to cheese by failing immediately. + bonus = 0; + } + else + { + if (player->timeshit == 0) bonus = 10000; + else if (player->timeshit == 1) bonus = 5000; + else if (player->timeshit == 2) bonus = 1000; + else if (player->timeshit == 3) bonus = 500; + else if (player->timeshit == 4) bonus = 100; + else bonus = 0; + } + bstruct->points = bonus; } From 77b8578d04763398a60d372afcc834e05bc5fe77 Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Mon, 19 Apr 2021 21:42:00 -0300 Subject: [PATCH 381/644] Add ease Lua library --- src/lua_mathlib.c | 119 +++++++++++++++++++++++++++++++++++++++++++++- src/m_easing.c | 63 +++++++++++++++++------- src/m_easing.h | 52 +++++++++++--------- 3 files changed, 193 insertions(+), 41 deletions(-) diff --git a/src/lua_mathlib.c b/src/lua_mathlib.c index b6046ab53..1b7113b36 100644 --- a/src/lua_mathlib.c +++ b/src/lua_mathlib.c @@ -16,6 +16,7 @@ #include "p_local.h" #include "doomstat.h" // for ALL7EMERALDS #include "r_main.h" // for R_PointToDist2 +#include "m_easing.h" #include "lua_script.h" #include "lua_libs.h" @@ -185,7 +186,7 @@ static int lib_coloropposite(lua_State *L) return 2; } -static luaL_Reg lib[] = { +static luaL_Reg lib_math[] = { {"abs", lib_abs}, {"min", lib_min}, {"max", lib_max}, @@ -223,9 +224,123 @@ static luaL_Reg lib[] = { {NULL, NULL} }; +// +// Easing functions +// + +#define EASINGFUNC(easetype) \ +{ \ + fixed_t start = 0; \ + fixed_t end = FRACUNIT; \ + fixed_t t = luaL_checkfixed(L, 1); \ + int n = lua_gettop(L); \ + if (n == 2) \ + end = luaL_checkfixed(L, 2); \ + else if (n >= 3) \ + { \ + start = luaL_checkfixed(L, 2); \ + end = luaL_checkfixed(L, 3); \ + } \ + lua_pushfixed(L, (Easing_ ## easetype)(t, start, end)); \ + return 1; \ +} \ + +static int lib_easelinear(lua_State *L) { EASINGFUNC(Linear) } + +static int lib_easeinsine(lua_State *L) { EASINGFUNC(InSine) } +static int lib_easeoutsine(lua_State *L) { EASINGFUNC(OutSine) } +static int lib_easeinoutsine(lua_State *L) { EASINGFUNC(InOutSine) } + +static int lib_easeinquad(lua_State *L) { EASINGFUNC(InQuad) } +static int lib_easeoutquad(lua_State *L) { EASINGFUNC(OutQuad) } +static int lib_easeinoutquad(lua_State *L) { EASINGFUNC(InOutQuad) } + +static int lib_easeincubic(lua_State *L) { EASINGFUNC(InCubic) } +static int lib_easeoutcubic(lua_State *L) { EASINGFUNC(OutCubic) } +static int lib_easeinoutcubic(lua_State *L) { EASINGFUNC(InOutCubic) } + +static int lib_easeinquart(lua_State *L) { EASINGFUNC(InQuart) } +static int lib_easeoutquart(lua_State *L) { EASINGFUNC(OutQuart) } +static int lib_easeinoutquart(lua_State *L) { EASINGFUNC(InOutQuart) } + +static int lib_easeinquint(lua_State *L) { EASINGFUNC(InQuint) } +static int lib_easeoutquint(lua_State *L) { EASINGFUNC(OutQuint) } +static int lib_easeinoutquint(lua_State *L) { EASINGFUNC(InOutQuint) } + +static int lib_easeinexpo(lua_State *L) { EASINGFUNC(InExpo) } +static int lib_easeoutexpo(lua_State *L) { EASINGFUNC(OutExpo) } +static int lib_easeinoutexpo(lua_State *L) { EASINGFUNC(InOutExpo) } + +#undef EASINGFUNC + +#define EASINGFUNC(easetype) \ +{ \ + boolean useparam = false; \ + fixed_t param = 0; \ + fixed_t start = 0; \ + fixed_t end = FRACUNIT; \ + fixed_t t = luaL_checkfixed(L, 1); \ + int n = lua_gettop(L); \ + if (n == 2) \ + end = luaL_checkfixed(L, 2); \ + else if (n >= 3) \ + { \ + start = (fixed_t)luaL_optinteger(L, 2, start); \ + end = (fixed_t)luaL_optinteger(L, 3, end); \ + if ((n >= 4) && (useparam = (!lua_isnil(L, 4)))) \ + param = luaL_checkfixed(L, 4); \ + } \ + if (useparam) \ + lua_pushfixed(L, (Easing_ ## easetype ## Parameterized)(t, start, end, param)); \ + else \ + lua_pushfixed(L, (Easing_ ## easetype)(t, start, end)); \ + return 1; \ +} \ + +static int lib_easeinback(lua_State *L) { EASINGFUNC(InBack) } +static int lib_easeoutback(lua_State *L) { EASINGFUNC(OutBack) } +static int lib_easeinoutback(lua_State *L) { EASINGFUNC(InOutBack) } + +#undef EASINGFUNC + +static luaL_Reg lib_ease[] = { + {"linear", lib_easelinear}, + + {"insine", lib_easeinsine}, + {"outsine", lib_easeoutsine}, + {"inoutsine", lib_easeinoutsine}, + + {"inquad", lib_easeinquad}, + {"outquad", lib_easeoutquad}, + {"inoutquad", lib_easeinoutquad}, + + {"incubic", lib_easeincubic}, + {"outcubic", lib_easeoutcubic}, + {"inoutcubic", lib_easeinoutcubic}, + + {"inquart", lib_easeinquart}, + {"outquart", lib_easeoutquart}, + {"inoutquart", lib_easeinoutquart}, + + {"inquint", lib_easeinquint}, + {"outquint", lib_easeoutquint}, + {"inoutquint", lib_easeinoutquint}, + + {"inexpo", lib_easeinexpo}, + {"outexpo", lib_easeoutexpo}, + {"inoutexpo", lib_easeinoutexpo}, + + {"inback", lib_easeinback}, + {"outback", lib_easeoutback}, + {"inoutback", lib_easeinoutback}, + + {NULL, NULL} +}; + int LUA_MathLib(lua_State *L) { lua_pushvalue(L, LUA_GLOBALSINDEX); - luaL_register(L, NULL, lib); + luaL_register(L, NULL, lib_math); + luaL_register(L, "ease", lib_ease); return 0; } diff --git a/src/m_easing.c b/src/m_easing.c index b3ea8842f..c871d3106 100644 --- a/src/m_easing.c +++ b/src/m_easing.c @@ -144,7 +144,11 @@ static INT32 fixexp(fixed_t a) #define fixintdiv(x, y) FixedDiv(x, (y) * FRACUNIT) #define fixinterp(start, end, t) FixedMul((FRACUNIT - (t)), start) + FixedMul(t, end) -#define EASINGFUNC(type) fixed_t Easing_ ## type (fixed_t start, fixed_t end, fixed_t t) +// ================== +// EASING FUNCTIONS +// ================== + +#define EASINGFUNC(type) fixed_t Easing_ ## type (fixed_t t, fixed_t start, fixed_t end) // // Linear @@ -327,17 +331,20 @@ EASINGFUNC(InOutExpo) #define EASEBACKCONST1 111514 // 1.70158 #define EASEBACKCONST2 99942 // 1.525 -EASINGFUNC(InBack) +static fixed_t EaseInBack(fixed_t t, fixed_t start, fixed_t end, fixed_t c1) { - const fixed_t c1 = EASEBACKCONST1; const fixed_t c3 = c1 + FRACUNIT; fixed_t x = FixedMul(FixedMul(t, t), FixedMul(c3, t) - c1); return fixinterp(start, end, x); } -EASINGFUNC(OutBack) +EASINGFUNC(InBack) +{ + return EaseInBack(t, start, end, EASEBACKCONST1); +} + +static fixed_t EaseOutBack(fixed_t t, fixed_t start, fixed_t end, fixed_t c1) { - const fixed_t c1 = EASEBACKCONST1; const fixed_t c3 = c1 + FRACUNIT; fixed_t x; t -= FRACUNIT; @@ -345,32 +352,56 @@ EASINGFUNC(OutBack) return fixinterp(start, end, x); } -static fixed_t DoEaseInOutBack(fixed_t start, fixed_t end, fixed_t t, fixed_t c2) +EASINGFUNC(OutBack) { - fixed_t x; + return EaseOutBack(t, start, end, EASEBACKCONST1); +} - c2 += FRACUNIT; +static fixed_t EaseInOutBack(fixed_t t, fixed_t start, fixed_t end, fixed_t c2) +{ + fixed_t x, y; + const fixed_t f2 = 2*FRACUNIT; if (t < FRACUNIT / 2) { - x = fixintmul(7, t) - c2; - x = fixintmul(2, x); - x = FixedMul(FixedMul(t, t), x); + x = fixpow(FixedMul(t, f2), f2); + y = FixedMul(c2 + FRACUNIT, FixedMul(t, f2)); + x = FixedMul(x, y - c2); } else { - t -= FRACUNIT; - x = fixintmul(2, fixintmul(7, t) + c2); - x = FixedMul(FixedMul(t, t), x); - x = FRACUNIT + x; + x = fixpow(-(FixedMul(t, f2) - f2), f2); + y = FixedMul(c2 + FRACUNIT, FixedMul(t, f2) - f2); + x = FixedMul(x, y + c2); + x += f2; } + x /= 2; + return fixinterp(start, end, x); } EASINGFUNC(InOutBack) { - return DoEaseInOutBack(start, end, t, EASEBACKCONST2); + return EaseInOutBack(t, start, end, EASEBACKCONST2); +} + +#undef EASINGFUNC +#define EASINGFUNC(type) fixed_t Easing_ ## type (fixed_t t, fixed_t start, fixed_t end, fixed_t param) + +EASINGFUNC(InBackParameterized) +{ + return EaseInBack(t, start, end, param); +} + +EASINGFUNC(OutBackParameterized) +{ + return EaseOutBack(t, start, end, param); +} + +EASINGFUNC(InOutBackParameterized) +{ + return EaseInOutBack(t, start, end, param); } #undef EASINGFUNC diff --git a/src/m_easing.h b/src/m_easing.h index e5571ece3..435ad35e7 100644 --- a/src/m_easing.h +++ b/src/m_easing.h @@ -56,40 +56,46 @@ extern easingfunc_t easing_funclist[EASE_MAX]; extern const char *easing_funcnames[EASE_MAX]; #define EASINGFUNCLIST(sep) \ - EASINGFUNC(Linear) sep \ + EASINGFUNC(Linear) sep /* Easing_Linear */ \ \ - EASINGFUNC(InSine) sep \ - EASINGFUNC(OutSine) sep \ - EASINGFUNC(InOutSine) sep \ + EASINGFUNC(InSine) sep /* Easing_InSine */ \ + EASINGFUNC(OutSine) sep /* Easing_OutSine */ \ + EASINGFUNC(InOutSine) sep /* Easing_InOutSine */ \ \ - EASINGFUNC(InQuad) sep \ - EASINGFUNC(OutQuad) sep \ - EASINGFUNC(InOutQuad) sep \ + EASINGFUNC(InQuad) sep /* Easing_InQuad */ \ + EASINGFUNC(OutQuad) sep /* Easing_OutQuad */ \ + EASINGFUNC(InOutQuad) sep /* Easing_InOutQuad */ \ \ - EASINGFUNC(InCubic) sep \ - EASINGFUNC(OutCubic) sep \ - EASINGFUNC(InOutCubic) sep \ + EASINGFUNC(InCubic) sep /* Easing_InCubic */ \ + EASINGFUNC(OutCubic) sep /* Easing_OutCubic */ \ + EASINGFUNC(InOutCubic) sep /* Easing_InOutCubic */ \ \ - EASINGFUNC(InQuart) sep \ - EASINGFUNC(OutQuart) sep \ - EASINGFUNC(InOutQuart) sep \ + EASINGFUNC(InQuart) sep /* Easing_InQuart */ \ + EASINGFUNC(OutQuart) sep /* Easing_OutQuart */ \ + EASINGFUNC(InOutQuart) sep /* Easing_InOutQuart */ \ \ - EASINGFUNC(InQuint) sep \ - EASINGFUNC(OutQuint) sep \ - EASINGFUNC(InOutQuint) sep \ + EASINGFUNC(InQuint) sep /* Easing_InQuint */ \ + EASINGFUNC(OutQuint) sep /* Easing_OutQuint */ \ + EASINGFUNC(InOutQuint) sep /* Easing_InOutQuint */ \ \ - EASINGFUNC(InExpo) sep \ - EASINGFUNC(OutExpo) sep \ - EASINGFUNC(InOutExpo) sep \ + EASINGFUNC(InExpo) sep /* Easing_InExpo */ \ + EASINGFUNC(OutExpo) sep /* Easing_OutExpo */ \ + EASINGFUNC(InOutExpo) sep /* Easing_InOutExpo */ \ \ - EASINGFUNC(InBack) sep \ - EASINGFUNC(OutBack) sep \ - EASINGFUNC(InOutBack) sep + EASINGFUNC(InBack) sep /* Easing_InBack */ \ + EASINGFUNC(OutBack) sep /* Easing_OutBack */ \ + EASINGFUNC(InOutBack) sep /* Easing_InOutBack */ -#define EASINGFUNC(type) fixed_t Easing_ ## type (fixed_t start, fixed_t end, fixed_t t); +#define EASINGFUNC(type) fixed_t Easing_ ## type (fixed_t t, fixed_t start, fixed_t end); EASINGFUNCLIST() #undef EASINGFUNC +#define EASINGFUNC(type) fixed_t Easing_ ## type (fixed_t t, fixed_t start, fixed_t end, fixed_t param); +EASINGFUNC(InBackParameterized) /* Easing_InBackParameterized */ +EASINGFUNC(OutBackParameterized) /* Easing_OutBackParameterized */ +EASINGFUNC(InOutBackParameterized) /* Easing_InOutBackParameterized */ + +#undef EASINGFUNC #endif From 8f01e85adef84af55ed29ce8adbe789d6abec817 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 20 Apr 2021 22:10:11 -0400 Subject: [PATCH 382/644] Allow spaces in captions defined in SOC --- src/deh_soc.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/deh_soc.c b/src/deh_soc.c index 5b12ea1b0..eebaf1316 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -2839,26 +2839,28 @@ void readsound(MYFILE *f, INT32 num) if (s[0] == '\n') break; + // First remove trailing newline, if there is one + tmp = strchr(s, '\n'); + if (tmp) + *tmp = '\0'; + tmp = strchr(s, '#'); if (tmp) *tmp = '\0'; if (s == tmp) continue; // Skip comment lines, but don't break. - word = strtok(s, " "); - if (word) - strupr(word); + // Get the part before the " = " + tmp = strchr(s, '='); + if (tmp) + *(tmp-1) = '\0'; else break; + strupr(word); - word2 = strtok(NULL, " "); - if (word2) - value = atoi(word2); - else - { - deh_warning("No value for token %s", word); - continue; - } + // Now get the part after + word2 = tmp += 2; + value = atoi(word2); // used for numerical settings if (fastcmp(word, "SINGULAR")) { From ce3c5e081e26b601fc7486281df9bd58dc6c51eb Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 20 Apr 2021 22:19:56 -0400 Subject: [PATCH 383/644] Missed a few lines in the prev commit --- src/deh_soc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/deh_soc.c b/src/deh_soc.c index eebaf1316..60aaf1287 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -2850,6 +2850,9 @@ void readsound(MYFILE *f, INT32 num) if (s == tmp) continue; // Skip comment lines, but don't break. + // Set / reset word + word = s; + // Get the part before the " = " tmp = strchr(s, '='); if (tmp) From 6c4e7e13e09e2d0a93c019a0ca93985133afb038 Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Mon, 14 Dec 2020 01:23:57 -0600 Subject: [PATCH 384/644] Allow Lua to disable the emeralds that appear in the Special Stage intermission. --- src/lua_hud.h | 1 + src/lua_hudlib.c | 1 + src/y_inter.c | 1 + 3 files changed, 3 insertions(+) diff --git a/src/lua_hud.h b/src/lua_hud.h index 1e9dca00b..4be20c815 100644 --- a/src/lua_hud.h +++ b/src/lua_hud.h @@ -38,6 +38,7 @@ enum hud { // Intermission hud_intermissiontally, hud_intermissionmessages, + hud_intermissionemeralds, hud_MAX }; diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 8d451e99c..51c7f91ae 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -64,6 +64,7 @@ static const char *const hud_disable_options[] = { "intermissiontally", "intermissionmessages", + "intermissionemeralds", NULL}; enum hudinfo { diff --git a/src/y_inter.c b/src/y_inter.c index dca8cd377..d6baf06c6 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -638,6 +638,7 @@ void Y_IntermissionDrawer(void) // draw the emeralds //if (intertic & 1) + if (LUA_HudEnabled(hud_intermissionemeralds)) { boolean drawthistic = !(ALL7EMERALDS(emeralds) && (intertic & 1)); INT32 emeraldx = 152 - 3*28; From aa54a04c9e38ae0fb4c0b4ed834a32258e1ec409 Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Thu, 17 Dec 2020 02:30:57 -0600 Subject: [PATCH 385/644] Allow Lua to stop the intermission level title strings from drawing --- src/lua_hud.h | 1 + src/lua_hudlib.c | 1 + src/y_inter.c | 72 +++++++++++++++++++++++++++--------------------- 3 files changed, 43 insertions(+), 31 deletions(-) diff --git a/src/lua_hud.h b/src/lua_hud.h index 4be20c815..0a83b6de7 100644 --- a/src/lua_hud.h +++ b/src/lua_hud.h @@ -37,6 +37,7 @@ enum hud { hud_tabemblems, // Intermission hud_intermissiontally, + hud_intermissiontitletext, hud_intermissionmessages, hud_intermissionemeralds, hud_MAX diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 51c7f91ae..862ab4423 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -63,6 +63,7 @@ static const char *const hud_disable_options[] = { "tabemblems", "intermissiontally", + "intermissiontitletext", "intermissionmessages", "intermissionemeralds", NULL}; diff --git a/src/y_inter.c b/src/y_inter.c index d6baf06c6..6240663fa 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -471,14 +471,17 @@ void Y_IntermissionDrawer(void) } } - // draw the "got through act" lines and act number - V_DrawLevelTitle(data.coop.passedx1, 49, 0, data.coop.passed1); + if (LUA_HudEnabled(hud_intermissiontitletext)) { - INT32 h = V_LevelNameHeight(data.coop.passed2); - V_DrawLevelTitle(data.coop.passedx2, 49+h+2, 0, data.coop.passed2); + // draw the "got through act" lines and act number + V_DrawLevelTitle(data.coop.passedx1, 49, 0, data.coop.passed1); + { + INT32 h = V_LevelNameHeight(data.coop.passed2); + V_DrawLevelTitle(data.coop.passedx2, 49+h+2, 0, data.coop.passed2); - if (data.coop.actnum) - V_DrawLevelActNum(244, 42+h, 0, data.coop.actnum); + if (data.coop.actnum) + V_DrawLevelActNum(244, 42+h, 0, data.coop.actnum); + } } bonusy = 150; @@ -562,37 +565,44 @@ void Y_IntermissionDrawer(void) if (drawsection == 1) { - const char *ringtext = "\x82" "50 rings, no shield"; - const char *tut1text = "\x82" "press " "\x80" "spin"; - const char *tut2text = "\x82" "mid-" "\x80" "jump"; - ttheight = 8; - V_DrawLevelTitle(data.spec.passedx1 + xoffset1, ttheight, 0, data.spec.passed1); - ttheight += V_LevelNameHeight(data.spec.passed3) + 2; - V_DrawLevelTitle(data.spec.passedx3 + xoffset2, ttheight, 0, data.spec.passed3); - ttheight += V_LevelNameHeight(data.spec.passed4) + 2; - V_DrawLevelTitle(data.spec.passedx4 + xoffset3, ttheight, 0, data.spec.passed4); + if (LUA_HudEnabled(hud_intermissiontitletext)) + { + const char *ringtext = "\x82" "50 rings, no shield"; + const char *tut1text = "\x82" "press " "\x80" "spin"; + const char *tut2text = "\x82" "mid-" "\x80" "jump"; + ttheight = 8; + V_DrawLevelTitle(data.spec.passedx1 + xoffset1, ttheight, 0, data.spec.passed1); + ttheight += V_LevelNameHeight(data.spec.passed3) + 2; + V_DrawLevelTitle(data.spec.passedx3 + xoffset2, ttheight, 0, data.spec.passed3); + ttheight += V_LevelNameHeight(data.spec.passed4) + 2; + V_DrawLevelTitle(data.spec.passedx4 + xoffset3, ttheight, 0, data.spec.passed4); - ttheight = 108; - V_DrawLevelTitle(BASEVIDWIDTH/2 + xoffset4 - (V_LevelNameWidth(ringtext)/2), ttheight, 0, ringtext); - ttheight += V_LevelNameHeight(tut1text) + 2; - V_DrawLevelTitle(BASEVIDWIDTH/2 + xoffset5 - (V_LevelNameWidth(tut1text)/2), ttheight, 0, tut1text); - ttheight += V_LevelNameHeight(tut2text) + 2; - V_DrawLevelTitle(BASEVIDWIDTH/2 + xoffset6 - (V_LevelNameWidth(tut2text)/2), ttheight, 0, tut2text); + ttheight = 108; + V_DrawLevelTitle(BASEVIDWIDTH/2 + xoffset4 - (V_LevelNameWidth(ringtext)/2), ttheight, 0, ringtext); + ttheight += V_LevelNameHeight(tut1text) + 2; + V_DrawLevelTitle(BASEVIDWIDTH/2 + xoffset5 - (V_LevelNameWidth(tut1text)/2), ttheight, 0, tut1text); + ttheight += V_LevelNameHeight(tut2text) + 2; + V_DrawLevelTitle(BASEVIDWIDTH/2 + xoffset6 - (V_LevelNameWidth(tut2text)/2), ttheight, 0, tut2text); + } } else { INT32 yoffset = 0; - if (data.spec.passed1[0] != '\0') + + if (LUA_HudEnabled(hud_intermissiontitletext)) { - ttheight = 24; - V_DrawLevelTitle(data.spec.passedx1 + xoffset1, ttheight, 0, data.spec.passed1); - ttheight += V_LevelNameHeight(data.spec.passed2) + 2; - V_DrawLevelTitle(data.spec.passedx2 + xoffset2, ttheight, 0, data.spec.passed2); - } - else - { - ttheight = 24 + (V_LevelNameHeight(data.spec.passed2)/2) + 2; - V_DrawLevelTitle(data.spec.passedx2 + xoffset1, ttheight, 0, data.spec.passed2); + if (data.spec.passed1[0] != '\0') + { + ttheight = 24; + V_DrawLevelTitle(data.spec.passedx1 + xoffset1, ttheight, 0, data.spec.passed1); + ttheight += V_LevelNameHeight(data.spec.passed2) + 2; + V_DrawLevelTitle(data.spec.passedx2 + xoffset2, ttheight, 0, data.spec.passed2); + } + else + { + ttheight = 24 + (V_LevelNameHeight(data.spec.passed2)/2) + 2; + V_DrawLevelTitle(data.spec.passedx2 + xoffset1, ttheight, 0, data.spec.passed2); + } } V_DrawScaledPatch(152 + xoffset3, 108, 0, data.spec.bonuspatches[0]); From 43c21edcbd9185dacb3f271a6c7d7733500951eb Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Thu, 17 Dec 2020 03:09:20 -0600 Subject: [PATCH 386/644] Send IntermissionThinker and intermission hud hooks `stagefailed`. --- src/lua_hook.h | 2 +- src/lua_hooklib.c | 7 +++++-- src/lua_hud.h | 2 +- src/lua_hudlib.c | 12 ++++++++---- src/y_inter.c | 4 ++-- 5 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/lua_hook.h b/src/lua_hook.h index 0d631aa4e..fa6df2ee9 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -111,7 +111,7 @@ boolean LUAh_MapThingSpawn(mobj_t *mo, mapthing_t *mthing); // Hook for P_SpawnM boolean LUAh_FollowMobj(player_t *player, mobj_t *mobj); // Hook for P_PlayerAfterThink Smiles mobj-following UINT8 LUAh_PlayerCanDamage(player_t *player, mobj_t *mobj); // Hook for P_PlayerCanDamage void LUAh_PlayerQuit(player_t *plr, kickreason_t reason); // Hook for player quitting -void LUAh_IntermissionThinker(void); // Hook for Y_Ticker +void LUAh_IntermissionThinker(boolean stagefailed); // Hook for Y_Ticker boolean LUAh_TeamSwitch(player_t *player, int newteam, boolean fromspectators, boolean tryingautobalance, boolean tryingscramble); // Hook for team switching in... uh.... UINT8 LUAh_ViewpointSwitch(player_t *player, player_t *newdisplayplayer, boolean forced); // Hook for spy mode boolean LUAh_SeenPlayer(player_t *player, player_t *seenfriend); // Hook for MT_NAMECHECK diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 1665e36b0..130fc0a28 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -1633,7 +1633,7 @@ void LUAh_PlayerQuit(player_t *plr, kickreason_t reason) } // Hook for Y_Ticker -void LUAh_IntermissionThinker(void) +void LUAh_IntermissionThinker(boolean failedstage) { hook_p hookp; if (!gL || !(hooksAvailable[hook_IntermissionThinker/8] & (1<<(hook_IntermissionThinker%8)))) @@ -1646,8 +1646,11 @@ void LUAh_IntermissionThinker(void) if (hookp->type != hook_IntermissionThinker) continue; + lua_pushboolean(gL, failedstage); // stagefailed + PushHook(gL, hookp); - if (lua_pcall(gL, 0, 0, 1)) { + lua_pushvalue(gL, -2); // stagefailed + if (lua_pcall(gL, 1, 0, 1)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); diff --git a/src/lua_hud.h b/src/lua_hud.h index 0a83b6de7..a7f17aab5 100644 --- a/src/lua_hud.h +++ b/src/lua_hud.h @@ -51,4 +51,4 @@ void LUAh_GameHUD(player_t *stplyr); void LUAh_ScoresHUD(void); void LUAh_TitleHUD(void); void LUAh_TitleCardHUD(player_t *stplayr); -void LUAh_IntermissionHUD(void); +void LUAh_IntermissionHUD(boolean failedstage); diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 862ab4423..3dacd121e 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -1386,7 +1386,7 @@ void LUAh_TitleCardHUD(player_t *stplayr) hud_running = false; } -void LUAh_IntermissionHUD(void) +void LUAh_IntermissionHUD(boolean failedstage) { if (!gL || !(hudAvailable & (1< Date: Thu, 17 Dec 2020 12:26:27 -0600 Subject: [PATCH 387/644] Allow Lua to draw level title strings, and get the width and height of what would be drawn --- src/lua_hudlib.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 3dacd121e..951c63e54 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -859,6 +859,26 @@ static int libd_drawScaledNameTag(lua_State *L) return 0; } +static int libd_drawLevelTitle(lua_State *L) +{ + INT32 x; + INT32 y; + const char *str; + INT32 flags; + + HUDONLY + + x = luaL_checkinteger(L, 1); + y = luaL_checkinteger(L, 2); + str = luaL_checkstring(L, 3); + flags = luaL_optinteger(L, 4, 0); + + flags &= ~V_PARAMMASK; // Don't let crashes happen. + + V_DrawLevelTitle(x, y, flags, str); + return 0; +} + static int libd_stringWidth(lua_State *L) { const char *str = luaL_checkstring(L, 1); @@ -888,6 +908,20 @@ static int libd_nameTagWidth(lua_State *L) return 1; } +static int libd_levelTitleWidth(lua_State *L) +{ + HUDONLY + lua_pushinteger(L, V_LevelNameWidth(luaL_checkstring(L, 1))); + return 1; +} + +static int libd_levelTitleHeight(lua_State *L) +{ + HUDONLY + lua_pushinteger(L, V_LevelNameHeight(luaL_checkstring(L, 1))); + return 1; +} + static int libd_getColormap(lua_State *L) { INT32 skinnum = TC_DEFAULT; @@ -1093,10 +1127,13 @@ static luaL_Reg lib_draw[] = { {"drawString", libd_drawString}, {"drawNameTag", libd_drawNameTag}, {"drawScaledNameTag", libd_drawScaledNameTag}, + {"drawLevelTitle", libd_drawLevelTitle}, {"fadeScreen", libd_fadeScreen}, // misc {"stringWidth", libd_stringWidth}, {"nameTagWidth", libd_nameTagWidth}, + {"levelTitleWidth", libd_levelTitleWidth}, + {"levelTitleHeight", libd_levelTitleHeight}, // m_random {"RandomFixed",libd_RandomFixed}, {"RandomByte",libd_RandomByte}, From abc886b9ac25cd5528142b09c62498b335f3c22f Mon Sep 17 00:00:00 2001 From: SMS Alfredo <65426124+SMS-Alfredo@users.noreply.github.com> Date: Wed, 21 Apr 2021 18:20:56 -0500 Subject: [PATCH 388/644] REVERSESUPER rises from the grave --- src/deh_lua.c | 5 +++++ src/p_mobj.h | 2 ++ 2 files changed, 7 insertions(+) diff --git a/src/deh_lua.c b/src/deh_lua.c index e6a436421..e920154cc 100644 --- a/src/deh_lua.c +++ b/src/deh_lua.c @@ -264,6 +264,11 @@ static inline int lib_getenum(lua_State *L) lua_pushinteger(L, ((lua_Integer)1< Date: Wed, 21 Apr 2021 19:58:14 -0400 Subject: [PATCH 389/644] Kart cmd->latency port Nev3r was talking about something that would've been drastically improved with this, and it is really simple, so I ported it :) --- src/d_ticcmd.h | 3 +++ src/g_demo.c | 12 ++++++++++++ src/g_game.c | 8 ++++++++ src/lua_playerlib.c | 6 ++++++ 4 files changed, 29 insertions(+) diff --git a/src/d_ticcmd.h b/src/d_ticcmd.h index 2a5ef0981..04cbeef19 100644 --- a/src/d_ticcmd.h +++ b/src/d_ticcmd.h @@ -21,6 +21,8 @@ #pragma interface #endif +#define MAXPREDICTTICS 12 + // Button/action code definitions. typedef enum { @@ -63,6 +65,7 @@ typedef struct INT16 angleturn; // <<16 for angle delta - saved as 1 byte into demos INT16 aiming; // vertical aiming, see G_BuildTicCmd UINT16 buttons; + UINT8 latency; // Netgames: how many tics ago was this ticcmd generated from this player's end? } ATTRPACK ticcmd_t; #if defined(_MSC_VER) diff --git a/src/g_demo.c b/src/g_demo.c index 593fd7723..16477ab48 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -109,6 +109,7 @@ demoghost *ghosts = NULL; #define ZT_ANGLE 0x04 #define ZT_BUTTONS 0x08 #define ZT_AIMING 0x10 +#define ZT_LATENCY 0x20 #define DEMOMARKER 0x80 // demoend #define METALDEATH 0x44 #define METALSNICE 0x69 @@ -181,6 +182,8 @@ void G_ReadDemoTiccmd(ticcmd_t *cmd, INT32 playernum) oldcmd.buttons = (oldcmd.buttons & (BT_CAMLEFT|BT_CAMRIGHT)) | (READUINT16(demo_p) & ~(BT_CAMLEFT|BT_CAMRIGHT)); if (ziptic & ZT_AIMING) oldcmd.aiming = READINT16(demo_p); + if (ziptic & ZT_LATENCY) + oldcmd.latency = READUINT8(demo_p); G_CopyTiccmd(cmd, &oldcmd, 1); players[playernum].angleturn = cmd->angleturn; @@ -238,6 +241,13 @@ void G_WriteDemoTiccmd(ticcmd_t *cmd, INT32 playernum) ziptic |= ZT_AIMING; } + if (cmd->latency != oldcmd.latency) + { + WRITEUINT8(demo_p,cmd->latency); + oldcmd.latency = cmd->latency; + ziptic |= ZT_LATENCY; + } + *ziptic_p = ziptic; // attention here for the ticcmd size! @@ -679,6 +689,8 @@ void G_GhostTicker(void) g->p += 2; if (ziptic & ZT_AIMING) g->p += 2; + if (ziptic & ZT_LATENCY) + g->p++; // Grab ghost data. ziptic = READUINT8(g->p); diff --git a/src/g_game.c b/src/g_game.c index 13423ce77..c6b3292b0 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1693,6 +1693,10 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) cmd->angleturn = origangle + extra; *myangle += extra << 16; *myaiming += (cmd->aiming - origaiming) << 16; + + // Send leveltime when this tic was generated to the server for control lag calculations. + // Only do this when in a level. Also do this after the hook, so that it can't overwrite this. + cmd->latency = (leveltime & 0xFF); } //Reset away view if a command is given. @@ -1724,6 +1728,7 @@ ticcmd_t *G_MoveTiccmd(ticcmd_t* dest, const ticcmd_t* src, const size_t n) dest[i].angleturn = SHORT(src[i].angleturn); dest[i].aiming = (INT16)SHORT(src[i].aiming); dest[i].buttons = (UINT16)SHORT(src[i].buttons); + dest[i].latency = src[i].latency; } return dest; } @@ -2306,6 +2311,9 @@ void G_Ticker(boolean run) players[i].cmd.angleturn &= ~TICCMD_RECEIVED; players[i].cmd.angleturn |= received; + + // Use the leveltime sent in the player's ticcmd to determine control lag + players[i].cmd.latency = min(((leveltime & 0xFF) - players[i].cmd.latency) & 0xFF, MAXPREDICTTICS-1); } } diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 0eb54808f..d37d46c42 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -795,6 +795,7 @@ static int power_len(lua_State *L) } #define NOFIELD luaL_error(L, LUA_QL("ticcmd_t") " has no field named " LUA_QS, field) +#define NOSET luaL_error(L, LUA_QL("ticcmd_t") " field " LUA_QS " should not be set directly.", field) static int ticcmd_get(lua_State *L) { @@ -813,6 +814,8 @@ static int ticcmd_get(lua_State *L) lua_pushinteger(L, cmd->aiming); else if (fastcmp(field,"buttons")) lua_pushinteger(L, cmd->buttons); + else if (fastcmp(field,"latency")) + lua_pushinteger(L, cmd->latency); else return NOFIELD; @@ -839,6 +842,8 @@ static int ticcmd_set(lua_State *L) cmd->aiming = (INT16)luaL_checkinteger(L, 3); else if (fastcmp(field,"buttons")) cmd->buttons = (UINT16)luaL_checkinteger(L, 3); + else if (fastcmp(field,"latency")) + return NOSET; else return NOFIELD; @@ -846,6 +851,7 @@ static int ticcmd_set(lua_State *L) } #undef NOFIELD +#undef NOSET int LUA_PlayerLib(lua_State *L) { From da56e84d2c1f202789c87afc3aeab6c3b6eb65b1 Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+TatsuruIKR@users.noreply.github.com> Date: Wed, 21 Apr 2021 22:14:37 -0300 Subject: [PATCH 390/644] Change TOL_ERZ3 identifier --- src/g_game.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g_game.c b/src/g_game.c index 13423ce77..bd09e4c79 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3506,7 +3506,7 @@ tolinfo_t TYPEOFLEVEL[NUMTOLNAMES] = { {"2D",TOL_2D}, {"MARIO",TOL_MARIO}, {"NIGHTS",TOL_NIGHTS}, - {"OLDBRAK",TOL_ERZ3}, + {"ERZ3",TOL_ERZ3}, {"XMAS",TOL_XMAS}, {"CHRISTMAS",TOL_XMAS}, From 4f2f94d02d4f982d05900e10b5f00be28b0599ac Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+TatsuruIKR@users.noreply.github.com> Date: Wed, 21 Apr 2021 22:22:37 -0300 Subject: [PATCH 391/644] Compatibility with the current identifier --- src/g_game.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/g_game.c b/src/g_game.c index bd09e4c79..399c4f2bd 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3506,6 +3506,7 @@ tolinfo_t TYPEOFLEVEL[NUMTOLNAMES] = { {"2D",TOL_2D}, {"MARIO",TOL_MARIO}, {"NIGHTS",TOL_NIGHTS}, + {"OLDBRAK",TOL_ERZ3}, {"ERZ3",TOL_ERZ3}, {"XMAS",TOL_XMAS}, From e510e71617a2102001d5038dbc48c7abdf855792 Mon Sep 17 00:00:00 2001 From: Radicalicious Date: Fri, 23 Apr 2021 15:50:48 -0400 Subject: [PATCH 392/644] Remove fire shield flash --- src/p_mobj.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 7ba6d1fad..59f306d1d 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -3283,11 +3283,9 @@ void P_MobjCheckWater(mobj_t *mobj) boolean electric = !!(p->powers[pw_shield] & SH_PROTECTELECTRIC); if (electric || ((p->powers[pw_shield] & SH_PROTECTFIRE) && !(p->powers[pw_shield] & SH_PROTECTWATER) && !(mobj->eflags & MFE_TOUCHLAVA))) { // Water removes electric and non-water fire shields... - P_FlashPal(p, - electric - ? PAL_WHITE - : PAL_NUKE, - 1); + if (electric) + P_FlashPal(p, PAL_WHITE, 1); + p->powers[pw_shield] = p->powers[pw_shield] & SH_STACK; } } From 8278e621fb5cbe685c014c1e72c9145e9c906909 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 25 Apr 2021 07:18:32 -0400 Subject: [PATCH 393/644] Removed skin->availability Locked skins now are a specific unlockable type, instead of being tied to the skin's properties. This has plagued custom gamedata since 2.2 launch. It's extremely obnoxious having to set aside random numbers as dummy unlockables just to ensure that Amy Fang & Metal are unlocked from the start in a custom map pack. Other changes made to accommodate this: - R_GetSkinAvailabilities is now created from the list of unlockables set to skin type. (1st skin unlockable defined is (1), 2nd skin unlockable defined is (1 << 1), etc...) - The "Added skin x" print shows up when loading addons but not at all for the base game, because the previous behavior of hiding based on if the skin was locked would now require iterating unlockables, which felt wrong to do during that stage of the loading process - I noticed in my test wad that Sonic&Tails would give you Sonic&Sonic out if Tails was locked. I fixed that by making both skins required to show the character select option. Mods that reserved empty dummy unlockables for Amy Fang and Metal won't have to do anything. Mods that wanted to re-lock them behind different requirements will have to update, but in the future they will not have to be in specific slots. Additionally, now Sonic Tails and Knuckles can also be locked for mods. --- src/d_netcmd.c | 26 ++++++++-- src/deh_soc.c | 23 ++++++--- src/lua_skinlib.c | 5 -- src/m_cond.h | 1 + src/m_menu.c | 9 +++- src/p_enemy.c | 29 +++++++++-- src/p_setup.c | 4 +- src/r_skins.c | 120 ++++++++++++++++++++++++++++++++++++---------- src/r_skins.h | 6 +-- src/r_things.c | 4 +- 10 files changed, 175 insertions(+), 52 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 09f9d4651..9261770c7 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1475,7 +1475,8 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum) if (server && (p != &players[consoleplayer] && p != &players[secondarydisplayplayer])) { boolean kick = false; - INT32 s; + UINT32 unlockShift = 0; + UINT32 i; // team colors if (G_GametypeHasTeams()) @@ -1491,12 +1492,29 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum) kick = true; // availabilities - for (s = 0; s < MAXSKINS; s++) + for (i = 0; i < MAXUNLOCKABLES; i++) { - if (!skins[s].availability && (p->availabilities & (1 << s))) + if (unlockables[i].type != SECRET_SKIN) + { + continue; + } + + unlockShift++; + } + + // If they set an invalid bit to true, then likely a modified client + if (unlockShift < 32) // 32 is the max the data type allows + { + UINT32 illegalMask = UINT32_MAX; + + for (i = 0; i < unlockShift; i++) + { + illegalMask &= ~(1 << i); + } + + if ((p->availabilities & illegalMask) != 0) { kick = true; - break; } } diff --git a/src/deh_soc.c b/src/deh_soc.c index 5b12ea1b0..e5cba5185 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -3219,19 +3219,30 @@ void readunlockable(MYFILE *f, INT32 num) unlockables[num].type = SECRET_WARP; else if (fastcmp(word2, "SOUNDTEST")) unlockables[num].type = SECRET_SOUNDTEST; + else if (fastcmp(word2, "SKIN")) + unlockables[num].type = SECRET_SKIN; else unlockables[num].type = (INT16)i; } else if (fastcmp(word, "VAR")) { - // Support using the actual map name, - // i.e., Level AB, Level FZ, etc. + INT32 skinnum = R_SkinAvailable(word2); - // Convert to map number - if (word2[0] >= 'A' && word2[0] <= 'Z') - i = M_MapNumber(word2[0], word2[1]); + if (skinnum != -1) + { + unlockables[num].variable = (INT16)skinnum; + } + else + { + // Support using the actual map name, + // i.e., Level AB, Level FZ, etc. - unlockables[num].variable = (INT16)i; + // Convert to map number + if (word2[0] >= 'A' && word2[0] <= 'Z') + i = M_MapNumber(word2[0], word2[1]); + + unlockables[num].variable = (INT16)i; + } } else deh_warning("Unlockable %d: unknown word '%s'", num+1, word); diff --git a/src/lua_skinlib.c b/src/lua_skinlib.c index 56be6bf4f..f6c0879bd 100644 --- a/src/lua_skinlib.c +++ b/src/lua_skinlib.c @@ -53,7 +53,6 @@ enum skin { skin_contspeed, skin_contangle, skin_soundsid, - skin_availability, skin_sprites }; static const char *const skin_opt[] = { @@ -91,7 +90,6 @@ static const char *const skin_opt[] = { "contspeed", "contangle", "soundsid", - "availability", "sprites", NULL}; @@ -209,9 +207,6 @@ static int skin_get(lua_State *L) case skin_soundsid: LUA_PushUserdata(L, skin->soundsid, META_SOUNDSID); break; - case skin_availability: - lua_pushinteger(L, skin->availability); - break; case skin_sprites: LUA_PushLightUserdata(L, skin->sprites, META_SKINSPRITES); break; diff --git a/src/m_cond.h b/src/m_cond.h index 9bb162ff3..08b47c63a 100644 --- a/src/m_cond.h +++ b/src/m_cond.h @@ -132,6 +132,7 @@ typedef struct #define SECRET_WARP 2 // Selectable warp #define SECRET_SOUNDTEST 3 // Sound Test #define SECRET_CREDITS 4 // Enables Credits +#define SECRET_SKIN 5 // Unlocks a skin // If you have more secrets than these variables allow in your game, // you seriously need to get a life. diff --git a/src/m_menu.c b/src/m_menu.c index 0fca39801..651dbecc6 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -8963,7 +8963,7 @@ static void M_CacheCharacterSelectEntry(INT32 i, INT32 skinnum) static UINT8 M_SetupChoosePlayerDirect(INT32 choice) { - INT32 skinnum; + INT32 skinnum, botskin; UINT8 i; UINT8 firstvalid = 255, lastvalid = 255; boolean allowed = false; @@ -8995,6 +8995,13 @@ static UINT8 M_SetupChoosePlayerDirect(INT32 choice) skinnum = description[i].skinnum[0]; if ((skinnum != -1) && (R_SkinUsable(-1, skinnum))) { + botskin = description[i].skinnum[1]; + if ((botskin != -1) && (!R_SkinUsable(-1, botskin))) + { + // Bot skin isn't unlocked + continue; + } + // Handling order. if (firstvalid == 255) firstvalid = i; diff --git a/src/p_enemy.c b/src/p_enemy.c index 59176d6cc..306b8b399 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -25,6 +25,7 @@ #include "i_video.h" #include "z_zone.h" #include "lua_hook.h" +#include "m_cond.h" // SECRET_SKIN #ifdef HW3SOUND #include "hardware/hw3sound.h" @@ -5101,6 +5102,28 @@ void A_SignSpin(mobj_t *actor) } } +static boolean SignSkinCheck(player_t *player, INT32 num) +{ + INT32 i; + + if (player != NULL) + { + // Use player's availabilities + return R_SkinUsable(player - players, num); + } + + // Player invalid, only show characters that are unlocked from the start. + for (i = 0; i < MAXUNLOCKABLES; i++) + { + if (unlockables[i].type == SECRET_SKIN && unlockables[i].variable == num) + { + return false; + } + } + + return true; +} + // Function: A_SignPlayer // // Description: Changes the state of a level end sign to reflect the player that hit it. @@ -5161,23 +5184,21 @@ void A_SignPlayer(mobj_t *actor) // I turned this function into a fucking mess. I'm so sorry. -Lach if (locvar1 == -2) // random skin { -#define skincheck(num) (player ? !R_SkinUsable(player-players, num) : skins[num].availability > 0) player_t *player = actor->target ? actor->target->player : NULL; UINT8 skinnum; UINT8 skincount = 0; for (skinnum = 0; skinnum < numskins; skinnum++) - if (!skincheck(skinnum)) + if (SignSkinCheck(player, skinnum)) skincount++; skinnum = P_RandomKey(skincount); for (skincount = 0; skincount < numskins; skincount++) { if (skincount > skinnum) break; - if (skincheck(skincount)) + if (!SignSkinCheck(player, skincount)) skinnum++; } skin = &skins[skinnum]; -#undef skincheck } else // specific skin skin = &skins[locvar1]; diff --git a/src/p_setup.c b/src/p_setup.c index 40dd1a284..ae68bac80 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -4527,8 +4527,8 @@ boolean P_AddWadFile(const char *wadfilename) // // look for skins // - R_AddSkins(wadnum); // faB: wadfile index in wadfiles[] - R_PatchSkins(wadnum); // toast: PATCH PATCH + R_AddSkins(wadnum, false); // faB: wadfile index in wadfiles[] + R_PatchSkins(wadnum, false); // toast: PATCH PATCH ST_ReloadSkinFaceGraphics(); // diff --git a/src/r_skins.c b/src/r_skins.c index 6f150f234..587259ae0 100644 --- a/src/r_skins.c +++ b/src/r_skins.c @@ -148,8 +148,6 @@ static void Sk_SetDefaultValue(skin_t *skin) skin->contspeed = 17; skin->contangle = 0; - skin->availability = 0; - for (i = 0; i < sfx_skinsoundslot0; i++) if (S_sfx[i].skinsound != -1) skin->soundsid[S_sfx[i].skinsound] = i; @@ -176,14 +174,34 @@ void R_InitSkins(void) UINT32 R_GetSkinAvailabilities(void) { - INT32 s; UINT32 response = 0; + UINT32 unlockShift = 0; + INT32 i; - for (s = 0; s < MAXSKINS; s++) + for (i = 0; i < MAXUNLOCKABLES; i++) { - if (skins[s].availability && unlockables[skins[s].availability - 1].unlocked) - response |= (1 << s); + if (unlockables[i].type != SECRET_SKIN) + { + continue; + } + + if (unlockShift >= 32) + { + // This crash is impossible to trigger as is, + // but it could happen if MAXUNLOCKABLES is ever made higher than 32, + // and someone makes a mod that has 33+ unlockable characters. :V + I_Error("Too many unlockable characters\n"); + return 0; + } + + if (unlockables[i].unlocked) + { + response |= (1 << unlockShift); + } + + unlockShift++; } + return response; } @@ -191,14 +209,74 @@ UINT32 R_GetSkinAvailabilities(void) // warning don't use with an invalid skinnum other than -1 which always returns true boolean R_SkinUsable(INT32 playernum, INT32 skinnum) { - return ((skinnum == -1) // Simplifies things elsewhere, since there's already plenty of checks for less-than-0... - || (!skins[skinnum].availability) - || (((netgame || multiplayer) && playernum != -1) ? (players[playernum].availabilities & (1 << skinnum)) : (unlockables[skins[skinnum].availability - 1].unlocked)) - || (modeattacking) // If you have someone else's run you might as well take a look - || (Playing() && (R_SkinAvailable(mapheaderinfo[gamemap-1]->forcecharacter) == skinnum)) // Force 1. - || (netgame && (cv_forceskin.value == skinnum)) // Force 2. - || (metalrecording && skinnum == 5) // Force 3. - ); + INT32 unlockID = -1; + UINT32 unlockShift = 0; + INT32 i; + + if (skinnum == -1) + { + // Simplifies things elsewhere, since there's already plenty of checks for less-than-0... + return true; + } + + if (modeattacking) + { + // If you have someone else's run you might as well take a look + return true; + } + + if (Playing() && (R_SkinAvailable(mapheaderinfo[gamemap-1]->forcecharacter) == skinnum)) + { + // Force 1. + return true; + } + + if (netgame && (cv_forceskin.value == skinnum)) + { + // Force 2. + return true; + } + + if (metalrecording && skinnum == 5) + { + // Force 3. + return true; + } + + // We will now check if this skin is supposed to be locked or not. + + for (i = 0; i < MAXUNLOCKABLES; i++) + { + if (unlockables[i].type != SECRET_SKIN) + { + continue; + } + + if (unlockables[i].variable == skinnum) + { + unlockID = i; + break; + } + + unlockShift++; + } + + if (unlockID == -1) + { + // This skin isn't locked at all, we're good. + return true; + } + + if ((netgame || multiplayer) && playernum != -1) + { + // We want to check per-player unlockables. + return (players[playernum].availabilities & (1 << unlockShift)); + } + else + { + // We want to check our global unlockables. + return (unlockables[unlockID].unlocked); + } } // returns true if the skin name is found (loaded from pwad) @@ -558,7 +636,7 @@ static boolean R_ProcessPatchableFields(skin_t *skin, char *stoken, char *value) // // Find skin sprites, sounds & optional status bar face, & add them // -void R_AddSkins(UINT16 wadnum) +void R_AddSkins(UINT16 wadnum, boolean mainfile) { UINT16 lump, lastlump = 0; char *buf; @@ -673,12 +751,6 @@ void R_AddSkins(UINT16 wadnum) if (!realname) STRBUFCPY(skin->realname, skin->hudname); } - else if (!stricmp(stoken, "availability")) - { - skin->availability = atoi(value); - if (skin->availability >= MAXUNLOCKABLES) - skin->availability = 0; - } else if (!R_ProcessPatchableFields(skin, stoken, value)) CONS_Debug(DBG_SETUP, "R_AddSkins: Unknown keyword '%s' in S_SKIN lump #%d (WAD %s)\n", stoken, lump, wadfiles[wadnum]->filename); @@ -693,7 +765,7 @@ next_token: R_FlushTranslationColormapCache(); - if (!skin->availability) // Safe to print... + if (mainfile == false) CONS_Printf(M_GetText("Added skin '%s'\n"), skin->name); #ifdef SKINVALUES skin_cons_t[numskins].value = numskins; @@ -713,7 +785,7 @@ next_token: // // Patch skin sprites // -void R_PatchSkins(UINT16 wadnum) +void R_PatchSkins(UINT16 wadnum, boolean mainfile) { UINT16 lump, lastlump = 0; char *buf; @@ -826,7 +898,7 @@ next_token: R_FlushTranslationColormapCache(); - if (!skin->availability) // Safe to print... + if (mainfile == false) CONS_Printf(M_GetText("Patched skin '%s'\n"), skin->name); } return; diff --git a/src/r_skins.h b/src/r_skins.h index fbbb38743..5efd70307 100644 --- a/src/r_skins.h +++ b/src/r_skins.h @@ -80,8 +80,6 @@ typedef struct // contains super versions too spritedef_t sprites[NUMPLAYERSPRITES*2]; spriteinfo_t sprinfo[NUMPLAYERSPRITES*2]; - - UINT8 availability; // lock? } skin_t; /// Externs @@ -96,8 +94,8 @@ void SetPlayerSkinByNum(INT32 playernum,INT32 skinnum); // Tails 03-16-2002 boolean R_SkinUsable(INT32 playernum, INT32 skinnum); UINT32 R_GetSkinAvailabilities(void); INT32 R_SkinAvailable(const char *name); -void R_PatchSkins(UINT16 wadnum); -void R_AddSkins(UINT16 wadnum); +void R_AddSkins(UINT16 wadnum, boolean mainfile); +void R_PatchSkins(UINT16 wadnum, boolean mainfile); UINT8 P_GetSkinSprite2(skin_t *skin, UINT8 spr2, player_t *player); diff --git a/src/r_things.c b/src/r_things.c index a7c44c237..c5cf3aeae 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -547,8 +547,8 @@ void R_InitSprites(void) R_InitSkins(); for (i = 0; i < numwadfiles; i++) { - R_AddSkins((UINT16)i); - R_PatchSkins((UINT16)i); + R_AddSkins((UINT16)i, true); + R_PatchSkins((UINT16)i, true); R_LoadSpriteInfoLumps(i, wadfiles[i]->numlumps); } ST_ReloadSkinFaceGraphics(); From 376d6cd6a200128168f8d6b2c9575257d48aa575 Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+TatsuruIKR@users.noreply.github.com> Date: Sun, 25 Apr 2021 14:26:43 -0300 Subject: [PATCH 394/644] Don't try to free patches in dedicated --- src/y_inter.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/y_inter.c b/src/y_inter.c index dca8cd377..4354a1677 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -2069,7 +2069,8 @@ static void Y_AwardSpecialStageBonus(void) // void Y_EndIntermission(void) { - Y_UnloadData(); + if (!dedicated) + Y_UnloadData(); endtic = -1; intertype = int_none; From 65624bf6c0892b2b8f7579fa8eaf1f5cd66a17ee Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 25 Apr 2021 19:01:51 +0100 Subject: [PATCH 395/644] Change numadded counter to UINT16 instead of UINT8, to allow for more sprites properly --- src/r_things.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_things.c b/src/r_things.c index a7c44c237..5c0e5fda9 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -230,7 +230,7 @@ boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16 UINT8 rotation; lumpinfo_t *lumpinfo; softwarepatch_t patch; - UINT8 numadded = 0; + UINT16 numadded = 0; memset(sprtemp,0xFF, sizeof (sprtemp)); maxframe = (size_t)-1; From 70939a7a3dc75faf77ab0d1d7e3c967d8c1f6927 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 25 Apr 2021 21:08:12 +0100 Subject: [PATCH 396/644] Set "allocated" flag to off if setting a string from PossibleValue afterwards, or if not setting a new value at all. --- src/command.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/command.c b/src/command.c index 58434ef89..f1bf7dfb5 100644 --- a/src/command.c +++ b/src/command.c @@ -1433,6 +1433,7 @@ static void Setvalue(consvar_t *var, const char *valstr, boolean stealth) if (var->revert.allocated) { Z_Free(var->revert.v.string); + var->revert.allocated = false; // the below value is not allocated in zone memory, don't try to free it! } var->revert.v.const_munge = var->PossibleValue[i].strvalue; @@ -1505,6 +1506,7 @@ found: if (var->revert.allocated) { Z_Free(var->revert.v.string); + var->revert.allocated = false; // the below value is not allocated in zone memory, don't try to free it! } var->revert.v.const_munge = var->PossibleValue[i].strvalue; @@ -1523,6 +1525,7 @@ found: if (var->revert.allocated) { Z_Free(var->revert.v.string); + // Z_StrDup creates a new zone memory block, so we can keep the allocated flag on } var->revert.v.string = Z_StrDup(valstr); @@ -1787,6 +1790,7 @@ void CV_RevertNetVars(void) if (cvar->revert.allocated) { Z_Free(cvar->revert.v.string); + cvar->revert.allocated = false; // no value being held now } cvar->revert.v.string = NULL; From 382c0aa7de42b38e647bdfd3b157ff239d1bb5fc Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 25 Apr 2021 16:27:15 -0400 Subject: [PATCH 397/644] Fix overshadowed declaration --- src/m_menu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 651dbecc6..eb330c9e9 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -8963,7 +8963,7 @@ static void M_CacheCharacterSelectEntry(INT32 i, INT32 skinnum) static UINT8 M_SetupChoosePlayerDirect(INT32 choice) { - INT32 skinnum, botskin; + INT32 skinnum, botskinnum; UINT8 i; UINT8 firstvalid = 255, lastvalid = 255; boolean allowed = false; @@ -8995,8 +8995,8 @@ static UINT8 M_SetupChoosePlayerDirect(INT32 choice) skinnum = description[i].skinnum[0]; if ((skinnum != -1) && (R_SkinUsable(-1, skinnum))) { - botskin = description[i].skinnum[1]; - if ((botskin != -1) && (!R_SkinUsable(-1, botskin))) + botskinnum = description[i].skinnum[1]; + if ((botskinnum != -1) && (!R_SkinUsable(-1, botskinnum))) { // Bot skin isn't unlocked continue; From f0b9e0e415982f5dfee3942bb8cbdabc80a2b16f Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 25 Apr 2021 16:38:33 -0400 Subject: [PATCH 398/644] Default to first usable skin instead of 0, I_Error if none are usable --- src/r_skins.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/r_skins.c b/src/r_skins.c index 587259ae0..758d0980d 100644 --- a/src/r_skins.c +++ b/src/r_skins.c @@ -294,6 +294,23 @@ INT32 R_SkinAvailable(const char *name) return -1; } +// Gets the player to the first usuable skin in the game. (If your mod locked them all, then you kinda stupid) +void SetPlayerDefaultSkin(INT32 playernum) +{ + INT32 i; + + for (i = 0; i < numskins; i++) + { + if (R_SkinUsable(playernum, i)) + { + SetPlayerSkinByNum(playernum, i); + return; + } + } + + I_Error("All characters are locked."); +} + // network code calls this when a 'skin change' is received void SetPlayerSkin(INT32 playernum, const char *skinname) { @@ -311,7 +328,7 @@ void SetPlayerSkin(INT32 playernum, const char *skinname) else if(server || IsPlayerAdmin(consoleplayer)) CONS_Alert(CONS_WARNING, M_GetText("Player %d (%s) skin '%s' not found\n"), playernum, player_names[playernum], skinname); - SetPlayerSkinByNum(playernum, 0); + SetPlayerDefaultSkin(playernum); } // Same as SetPlayerSkin, but uses the skin #. @@ -402,7 +419,8 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum) CONS_Alert(CONS_WARNING, M_GetText("Requested skin %d not found\n"), skinnum); else if(server || IsPlayerAdmin(consoleplayer)) CONS_Alert(CONS_WARNING, "Player %d (%s) skin %d not found\n", playernum, player_names[playernum], skinnum); - SetPlayerSkinByNum(playernum, 0); // not found put the sonic skin + + SetPlayerDefaultSkin(playernum); } // From 92107f28d5dc48e7cb01f0c274aef85911f0ebdd Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 25 Apr 2021 17:54:47 -0400 Subject: [PATCH 399/644] Add string variable for unlockables and emblems Skin unlockables / skin emblems are now checked at runtime to see if there's any matches. --- src/d_netcmd.c | 5 +++-- src/deh_soc.c | 54 +++++++++++++++++++++++++++++++++++++------------- src/deh_soc.h | 2 ++ src/dehacked.c | 7 ++----- src/m_cond.c | 48 ++++++++++++++++++++++++++++++++++++++++++++ src/m_cond.h | 5 +++++ src/p_enemy.c | 9 +++++++-- src/p_mobj.c | 16 +++++++++++++-- src/r_skins.c | 25 +++++++++++++++-------- src/r_skins.h | 2 ++ 10 files changed, 140 insertions(+), 33 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 9261770c7..17ab52eb5 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1313,8 +1313,9 @@ static void SendNameAndColor(void) cv_skin.value = R_SkinAvailable(cv_skin.string); if ((cv_skin.value < 0) || !R_SkinUsable(consoleplayer, cv_skin.value)) { - CV_StealthSet(&cv_skin, DEFAULTSKIN); - cv_skin.value = 0; + INT32 defaultSkinNum = GetPlayerDefaultSkin(consoleplayer); + CV_StealthSet(&cv_skin, skins[defaultSkinNum].name); + cv_skin.value = defaultSkinNum; } // Finally write out the complete packet and send it off. diff --git a/src/deh_soc.c b/src/deh_soc.c index e5cba5185..1dde6c9f0 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -127,6 +127,33 @@ static float searchfvalue(const char *s) #endif // These are for clearing all of various things +void clear_emblems(void) +{ + INT32 i; + + for (i = 0; i < MAXEMBLEMS; ++i) + { + Z_Free(emblemlocations[i].stringVar); + emblemlocations[i].stringVar = NULL; + } + + memset(&emblemlocations, 0, sizeof(emblemlocations)); + numemblems = 0; +} + +void clear_unlockables(void) +{ + INT32 i; + + for (i = 0; i < MAXUNLOCKABLES; ++i) + { + Z_Free(unlockables[i].stringVar); + unlockables[i].stringVar = NULL; + } + + memset(&unlockables, 0, sizeof(unlockables)); +} + void clear_conditionsets(void) { UINT8 i; @@ -3017,7 +3044,12 @@ void reademblemdata(MYFILE *f, INT32 num) else if (fastcmp(word, "COLOR")) emblemlocations[num-1].color = get_number(word2); else if (fastcmp(word, "VAR")) + { + Z_Free(emblemlocations[num-1].stringVar); + emblemlocations[num-1].stringVar = Z_StrDup(word2); + emblemlocations[num-1].var = get_number(word2); + } else deh_warning("Emblem %d: unknown word '%s'", num, word); } @@ -3226,23 +3258,17 @@ void readunlockable(MYFILE *f, INT32 num) } else if (fastcmp(word, "VAR")) { - INT32 skinnum = R_SkinAvailable(word2); + Z_Free(unlockables[num].stringVar); + unlockables[num].stringVar = Z_StrDup(word2); - if (skinnum != -1) - { - unlockables[num].variable = (INT16)skinnum; - } - else - { - // Support using the actual map name, - // i.e., Level AB, Level FZ, etc. + // Support using the actual map name, + // i.e., Level AB, Level FZ, etc. - // Convert to map number - if (word2[0] >= 'A' && word2[0] <= 'Z') - i = M_MapNumber(word2[0], word2[1]); + // Convert to map number + if (word2[0] >= 'A' && word2[0] <= 'Z') + i = M_MapNumber(word2[0], word2[1]); - unlockables[num].variable = (INT16)i; - } + unlockables[num].variable = (INT16)i; } else deh_warning("Unlockable %d: unknown word '%s'", num+1, word); diff --git a/src/deh_soc.h b/src/deh_soc.h index 2bcb52e70..9a3b0884d 100644 --- a/src/deh_soc.h +++ b/src/deh_soc.h @@ -84,6 +84,8 @@ void readskincolor(MYFILE *f, INT32 num); void readthing(MYFILE *f, INT32 num); void readfreeslots(MYFILE *f); void readPlayer(MYFILE *f, INT32 num); +void clear_emblems(void); +void clear_unlockables(void); void clear_levels(void); void clear_conditionsets(void); #endif diff --git a/src/dehacked.c b/src/dehacked.c index c2ea28d27..a68537f77 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -562,13 +562,10 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) } if (clearall || fastcmp(word2, "UNLOCKABLES")) - memset(&unlockables, 0, sizeof(unlockables)); + clear_unlockables(); if (clearall || fastcmp(word2, "EMBLEMS")) - { - memset(&emblemlocations, 0, sizeof(emblemlocations)); - numemblems = 0; - } + clear_emblems(); if (clearall || fastcmp(word2, "EXTRAEMBLEMS")) { diff --git a/src/m_cond.c b/src/m_cond.c index 36fcd7cf2..ee8e96d64 100644 --- a/src/m_cond.c +++ b/src/m_cond.c @@ -496,6 +496,54 @@ UINT8 M_GotHighEnoughRings(INT32 trings) return false; } +// Gets the skin number for a SECRET_SKIN unlockable. +INT32 M_UnlockableSkinNum(unlockable_t *unlock) +{ + if (unlock->type != SECRET_SKIN) + { + // This isn't a skin unlockable... + return -1; + } + + if (unlock->stringVar && strcmp(unlock->stringVar, "")) + { + // Get the skin from the string. + return R_SkinAvailable(unlock->stringVar); + } + else if (unlock->variable >= 0 && unlock->variable < numskins) + { + // Use the number directly. + return unlock->variable; + } + + // Invalid skin unlockable. + return -1; +} + +// Gets the skin number for a ET_SKIN emblem. +INT32 M_EmblemSkinNum(emblem_t *emblem) +{ + if (emblem->type != ET_SKIN) + { + // This isn't a skin emblem... + return -1; + } + + if (emblem->stringVar && strcmp(emblem->stringVar, "")) + { + // Get the skin from the string. + return R_SkinAvailable(emblem->stringVar); + } + else if (emblem->var >= 0 && emblem->var < numskins) + { + // Use the number directly. + return emblem->var; + } + + // Invalid skin emblem. + return -1; +} + // ---------------- // Misc Emblem shit // ---------------- diff --git a/src/m_cond.h b/src/m_cond.h index 08b47c63a..8003433a7 100644 --- a/src/m_cond.h +++ b/src/m_cond.h @@ -92,6 +92,7 @@ typedef struct UINT8 sprite; ///< emblem sprite to use, 0 - 25 UINT16 color; ///< skincolor to use INT32 var; ///< If needed, specifies information on the target amount to achieve (or target skin) + char *stringVar; ///< String version char hint[110]; ///< Hint for emblem hints menu UINT8 collected; ///< Do you have this emblem? } emblem_t; @@ -116,6 +117,7 @@ typedef struct UINT8 showconditionset; INT16 type; INT16 variable; + char *stringVar; UINT8 nocecho; UINT8 nochecklist; UINT8 unlocked; @@ -186,4 +188,7 @@ UINT8 M_GotHighEnoughScore(INT32 tscore); UINT8 M_GotLowEnoughTime(INT32 tictime); UINT8 M_GotHighEnoughRings(INT32 trings); +INT32 M_UnlockableSkinNum(unlockable_t *unlock); +INT32 M_EmblemSkinNum(emblem_t *emblem); + #define M_Achieved(a) ((a) >= MAXCONDITIONSETS || conditionSets[a].achieved) diff --git a/src/p_enemy.c b/src/p_enemy.c index 306b8b399..44dace26f 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -5115,9 +5115,14 @@ static boolean SignSkinCheck(player_t *player, INT32 num) // Player invalid, only show characters that are unlocked from the start. for (i = 0; i < MAXUNLOCKABLES; i++) { - if (unlockables[i].type == SECRET_SKIN && unlockables[i].variable == num) + if (unlockables[i].type == SECRET_SKIN) { - return false; + INT32 lockedSkin = M_UnlockableSkinNum(&unlockables[i]); + + if (lockedSkin == num) + { + return false; + } } } diff --git a/src/p_mobj.c b/src/p_mobj.c index 49db6daee..540642134 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11964,6 +11964,7 @@ static boolean P_SetupEmblem(mapthing_t *mthing, mobj_t *mobj) INT32 j; emblem_t* emblem = M_GetLevelEmblems(gamemap); skincolornum_t emcolor; + boolean validEmblem = true; while (emblem) { @@ -11988,8 +11989,19 @@ static boolean P_SetupEmblem(mapthing_t *mthing, mobj_t *mobj) emcolor = M_GetEmblemColor(&emblemlocations[j]); // workaround for compiler complaint about bad function casting mobj->color = (UINT16)emcolor; - if (emblemlocations[j].collected - || (emblemlocations[j].type == ET_SKIN && emblemlocations[j].var != players[0].skin)) + validEmblem = !emblemlocations[j].collected; + + if (emblemlocations[j].type == ET_SKIN) + { + INT32 skinnum = M_EmblemSkinNum(&emblemlocations[j]); + + if (players[0].skin != skinnum) + { + validEmblem = false; + } + } + + if (validEmblem == false) { P_UnsetThingPosition(mobj); mobj->flags |= MF_NOCLIP; diff --git a/src/r_skins.c b/src/r_skins.c index 758d0980d..d6021ebbc 100644 --- a/src/r_skins.c +++ b/src/r_skins.c @@ -247,12 +247,16 @@ boolean R_SkinUsable(INT32 playernum, INT32 skinnum) for (i = 0; i < MAXUNLOCKABLES; i++) { + INT32 unlockSkin = -1; + if (unlockables[i].type != SECRET_SKIN) { continue; } - if (unlockables[i].variable == skinnum) + unlockSkin = M_UnlockableSkinNum(&unlockables[i]); + + if (unlockSkin == skinnum) { unlockID = i; break; @@ -294,8 +298,7 @@ INT32 R_SkinAvailable(const char *name) return -1; } -// Gets the player to the first usuable skin in the game. (If your mod locked them all, then you kinda stupid) -void SetPlayerDefaultSkin(INT32 playernum) +INT32 GetPlayerDefaultSkin(INT32 playernum) { INT32 i; @@ -303,12 +306,18 @@ void SetPlayerDefaultSkin(INT32 playernum) { if (R_SkinUsable(playernum, i)) { - SetPlayerSkinByNum(playernum, i); - return; + return i; } } - I_Error("All characters are locked."); + I_Error("All characters are locked!"); + return 0; +} + +// Gets the player to the first usuable skin in the game. (If your mod locked them all, then you kinda stupid) +void SetPlayerDefaultSkin(INT32 playernum) +{ + SetPlayerSkinByNum(playernum, GetPlayerDefaultSkin(playernum)); } // network code calls this when a 'skin change' is received @@ -325,7 +334,7 @@ void SetPlayerSkin(INT32 playernum, const char *skinname) if (P_IsLocalPlayer(player)) CONS_Alert(CONS_WARNING, M_GetText("Skin '%s' not found.\n"), skinname); - else if(server || IsPlayerAdmin(consoleplayer)) + else if (server || IsPlayerAdmin(consoleplayer)) CONS_Alert(CONS_WARNING, M_GetText("Player %d (%s) skin '%s' not found\n"), playernum, player_names[playernum], skinname); SetPlayerDefaultSkin(playernum); @@ -417,7 +426,7 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum) if (P_IsLocalPlayer(player)) CONS_Alert(CONS_WARNING, M_GetText("Requested skin %d not found\n"), skinnum); - else if(server || IsPlayerAdmin(consoleplayer)) + else if (server || IsPlayerAdmin(consoleplayer)) CONS_Alert(CONS_WARNING, "Player %d (%s) skin %d not found\n", playernum, player_names[playernum], skinnum); SetPlayerDefaultSkin(playernum); diff --git a/src/r_skins.h b/src/r_skins.h index 5efd70307..675eac5cc 100644 --- a/src/r_skins.h +++ b/src/r_skins.h @@ -89,6 +89,8 @@ extern skin_t skins[MAXSKINS]; /// Function prototypes void R_InitSkins(void); +INT32 GetPlayerDefaultSkin(INT32 playernum); +void SetPlayerDefaultSkin(INT32 playernum); void SetPlayerSkin(INT32 playernum,const char *skinname); void SetPlayerSkinByNum(INT32 playernum,INT32 skinnum); // Tails 03-16-2002 boolean R_SkinUsable(INT32 playernum, INT32 skinnum); From 4bafd622716f74df2c5d0b71a317c27257b83b4d Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 25 Apr 2021 18:44:07 -0400 Subject: [PATCH 400/644] Only return skin string number if it existed --- src/m_cond.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/m_cond.c b/src/m_cond.c index ee8e96d64..2fc730d3f 100644 --- a/src/m_cond.c +++ b/src/m_cond.c @@ -508,9 +508,14 @@ INT32 M_UnlockableSkinNum(unlockable_t *unlock) if (unlock->stringVar && strcmp(unlock->stringVar, "")) { // Get the skin from the string. - return R_SkinAvailable(unlock->stringVar); + INT32 skinnum = R_SkinAvailable(unlock->stringVar); + if (skinnum != -1) + { + return skinnum; + } } - else if (unlock->variable >= 0 && unlock->variable < numskins) + + if (unlock->variable >= 0 && unlock->variable < numskins) { // Use the number directly. return unlock->variable; @@ -532,9 +537,14 @@ INT32 M_EmblemSkinNum(emblem_t *emblem) if (emblem->stringVar && strcmp(emblem->stringVar, "")) { // Get the skin from the string. - return R_SkinAvailable(emblem->stringVar); + INT32 skinnum = R_SkinAvailable(emblem->stringVar); + if (skinnum != -1) + { + return skinnum; + } } - else if (emblem->var >= 0 && emblem->var < numskins) + + if (emblem->var >= 0 && emblem->var < numskins) { // Use the number directly. return emblem->var; From c51c478740d1bb22dbe0a28923c433038ec76cfc Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 25 Apr 2021 21:51:24 -0700 Subject: [PATCH 401/644] Lua: ensure order of MIN, MAX possible values Cvars could now have a range (MIN, MAX) plus some preset values, but Lua could not take advantage of this due to table order not being guaranteed. --- src/lua_consolelib.c | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/src/lua_consolelib.c b/src/lua_consolelib.c index 5344fee76..e839d4e15 100644 --- a/src/lua_consolelib.c +++ b/src/lua_consolelib.c @@ -361,6 +361,9 @@ static int lib_cvRegisterVar(lua_State *L) size_t count = 0; CV_PossibleValue_t *cvpv; + const char * const MINMAX[2] = {"MIN", "MAX"}; + int minmax_unset = 3; + lua_pushnil(L); while (lua_next(L, 4)) { count++; @@ -377,16 +380,45 @@ static int lib_cvRegisterVar(lua_State *L) i = 0; lua_pushnil(L); while (lua_next(L, 4)) { + INT32 n; + const char * strval; + // stack: [...] PossibleValue table, index, value // 4 5 6 if (lua_type(L, 5) != LUA_TSTRING || lua_type(L, 6) != LUA_TNUMBER) FIELDERROR("PossibleValue", "custom PossibleValue table requires a format of string=integer, i.e. {MIN=0, MAX=9999}"); - cvpv[i].strvalue = Z_StrDup(lua_tostring(L, 5)); - cvpv[i].value = (INT32)lua_tonumber(L, 6); + + strval = lua_tostring(L, 5); + + if ( + stricmp(strval, MINMAX[n=0]) == 0 || + stricmp(strval, MINMAX[n=1]) == 0 + ){ + /* need to shift forward */ + if (minmax_unset == 3) + { + memmove(&cvpv[2], &cvpv[0], + i * sizeof *cvpv); + } + cvpv[n].strvalue = MINMAX[n]; + minmax_unset &= ~(1 << n); + } + else + { + n = i; + cvpv[n].strvalue = Z_StrDup(strval); + } + + cvpv[n].value = (INT32)lua_tonumber(L, 6); + i++; lua_pop(L, 1); } + + if (minmax_unset) + FIELDERROR("PossibleValue", "custom PossibleValue table requires requires both MIN and MAX keys if one is present"); + cvpv[i].value = 0; cvpv[i].strvalue = NULL; cvar->PossibleValue = cvpv; From 85914cc7cd9143b08353409b1dea2a0d536e31de Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 25 Apr 2021 21:55:04 -0700 Subject: [PATCH 402/644] Free zstring when switching to preset value This is only applicable for bounded cvars (MIN, MAX), since otherwise there's no way to allocate a zstring. --- src/command.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/command.c b/src/command.c index f1bf7dfb5..00116a0cb 100644 --- a/src/command.c +++ b/src/command.c @@ -1441,6 +1441,10 @@ static void Setvalue(consvar_t *var, const char *valstr, boolean stealth) return; } + // free the old value string + Z_Free(var->zstring); + var->zstring = NULL; + var->value = var->PossibleValue[i].value; var->string = var->PossibleValue[i].strvalue; goto finish; From 92aeadc36b8e32e1c18b25eaac03e0eb9b86171b Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 25 Apr 2021 22:01:40 -0700 Subject: [PATCH 403/644] It is impossible for a string to be allocated in this case --- src/command.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/command.c b/src/command.c index 00116a0cb..951e3dd09 100644 --- a/src/command.c +++ b/src/command.c @@ -1507,14 +1507,7 @@ static void Setvalue(consvar_t *var, const char *valstr, boolean stealth) found: if (client && execversion_enabled) { - if (var->revert.allocated) - { - Z_Free(var->revert.v.string); - var->revert.allocated = false; // the below value is not allocated in zone memory, don't try to free it! - } - var->revert.v.const_munge = var->PossibleValue[i].strvalue; - return; } From 7cd41a8eb7ef8285255a65d5c1776608e77a486d Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Mon, 26 Apr 2021 03:48:38 -0400 Subject: [PATCH 404/644] Compile with -rdynamic on UNIXCOMMON platforms --- src/sdl/MakeNIX.cfg | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/sdl/MakeNIX.cfg b/src/sdl/MakeNIX.cfg index 47c944eb5..c2f3ff0b6 100644 --- a/src/sdl/MakeNIX.cfg +++ b/src/sdl/MakeNIX.cfg @@ -18,9 +18,11 @@ endif # #here is GNU/Linux and other # - OPTS=-DUNIXCOMMON +#Use -rdynamic so a backtrace log shows function names instead of addresses + LDFLAGS+=-rdynamic + #LDFLAGS = -L/usr/local/lib LIBS=-lm ifdef LINUX From 34fa9771928961196c46d2e7dbaec46d28bdcfb2 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 26 Apr 2021 19:07:11 +0100 Subject: [PATCH 405/644] move the old "can't load the level" error to its proper place, added specific error messages for all the times that unarchiving Lua banks can fail --- src/d_clisrv.c | 1 - src/p_saveg.c | 18 ++++++++++++++---- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 7c2dec6a1..89077ad6c 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1567,7 +1567,6 @@ static void CL_LoadReceivedSavegame(boolean reloading) } else { - CONS_Alert(CONS_ERROR, M_GetText("Can't load the level!\n")); Z_Free(savebuffer); save_p = NULL; if (unlink(tmpsave) == -1) diff --git a/src/p_saveg.c b/src/p_saveg.c index 03229e740..818596cac 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -4190,7 +4190,10 @@ static inline boolean P_NetUnArchiveMisc(boolean reloading) tokenlist = READUINT32(save_p); if (!P_LoadLevel(true, reloading)) + { + CONS_Alert(CONS_ERROR, M_GetText("Can't load the level!\n")); return false; + } // get the time leveltime = READUINT32(save_p); @@ -4268,19 +4271,26 @@ static inline boolean P_UnArchiveLuabanksAndConsistency(void) { switch (READUINT8(save_p)) { - case 0xb7: + case 0xb7: // luabanks marker { UINT8 i, banksinuse = READUINT8(save_p); if (banksinuse > NUM_LUABANKS) + { + CONS_Alert(CONS_ERROR, M_GetText("Corrupt Luabanks! (Too many banks in use)\n")); return false; + } for (i = 0; i < banksinuse; i++) luabanks[i] = READINT32(save_p); - if (READUINT8(save_p) != 0x1d) + if (READUINT8(save_p) != 0x1d) // consistency marker + { + CONS_Alert(CONS_ERROR, M_GetText("Corrupt Luabanks! (Failed consistency check)\n")); return false; + } } - case 0x1d: + case 0x1d: // consistency marker break; - default: + default: // anything else is nonsense + CONS_Alert(CONS_ERROR, M_GetText("Failed consistency check (???)\n")); return false; } From cd4cfba5000d141e97a9ac6ef0e3204e6cb8f905 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Mon, 26 Apr 2021 21:07:35 +0200 Subject: [PATCH 406/644] Delete faulty return --- src/d_clisrv.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 7c2dec6a1..c4026d52d 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1568,11 +1568,6 @@ static void CL_LoadReceivedSavegame(boolean reloading) else { CONS_Alert(CONS_ERROR, M_GetText("Can't load the level!\n")); - Z_Free(savebuffer); - save_p = NULL; - if (unlink(tmpsave) == -1) - CONS_Alert(CONS_ERROR, M_GetText("Can't delete %s\n"), tmpsave); - return; } // done @@ -4486,9 +4481,9 @@ static INT16 Consistancy(void) { if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) continue; - + mo = (mobj_t *)th; - + if (mo->flags & (MF_SPECIAL | MF_SOLID | MF_PUSHABLE | MF_BOSS | MF_MISSILE | MF_SPRING | MF_MONITOR | MF_FIRE | MF_ENEMY | MF_PAIN | MF_STICKY)) { ret -= mo->type; From 0d4d3a520777bf81609df4c28b144330ab66b640 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Mon, 26 Apr 2021 21:07:35 +0200 Subject: [PATCH 407/644] Revert "Lua: ensure order of MIN, MAX possible values" This reverts commit c51c478740d1bb22dbe0a28923c433038ec76cfc. --- src/lua_consolelib.c | 36 ++---------------------------------- 1 file changed, 2 insertions(+), 34 deletions(-) diff --git a/src/lua_consolelib.c b/src/lua_consolelib.c index e839d4e15..5344fee76 100644 --- a/src/lua_consolelib.c +++ b/src/lua_consolelib.c @@ -361,9 +361,6 @@ static int lib_cvRegisterVar(lua_State *L) size_t count = 0; CV_PossibleValue_t *cvpv; - const char * const MINMAX[2] = {"MIN", "MAX"}; - int minmax_unset = 3; - lua_pushnil(L); while (lua_next(L, 4)) { count++; @@ -380,45 +377,16 @@ static int lib_cvRegisterVar(lua_State *L) i = 0; lua_pushnil(L); while (lua_next(L, 4)) { - INT32 n; - const char * strval; - // stack: [...] PossibleValue table, index, value // 4 5 6 if (lua_type(L, 5) != LUA_TSTRING || lua_type(L, 6) != LUA_TNUMBER) FIELDERROR("PossibleValue", "custom PossibleValue table requires a format of string=integer, i.e. {MIN=0, MAX=9999}"); - - strval = lua_tostring(L, 5); - - if ( - stricmp(strval, MINMAX[n=0]) == 0 || - stricmp(strval, MINMAX[n=1]) == 0 - ){ - /* need to shift forward */ - if (minmax_unset == 3) - { - memmove(&cvpv[2], &cvpv[0], - i * sizeof *cvpv); - } - cvpv[n].strvalue = MINMAX[n]; - minmax_unset &= ~(1 << n); - } - else - { - n = i; - cvpv[n].strvalue = Z_StrDup(strval); - } - - cvpv[n].value = (INT32)lua_tonumber(L, 6); - + cvpv[i].strvalue = Z_StrDup(lua_tostring(L, 5)); + cvpv[i].value = (INT32)lua_tonumber(L, 6); i++; lua_pop(L, 1); } - - if (minmax_unset) - FIELDERROR("PossibleValue", "custom PossibleValue table requires requires both MIN and MAX keys if one is present"); - cvpv[i].value = 0; cvpv[i].strvalue = NULL; cvar->PossibleValue = cvpv; From 34911128187161136db79cbb9df302cb8c8fccc1 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Mon, 26 Apr 2021 21:07:35 +0200 Subject: [PATCH 408/644] Update copyright date --- src/d_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_main.c b/src/d_main.c index 23a2c0133..61510d590 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1045,7 +1045,7 @@ void D_SRB2Main(void) // Print GPL notice for our console users (Linux) CONS_Printf( "\n\nSonic Robo Blast 2\n" - "Copyright (C) 1998-2020 by Sonic Team Junior\n\n" + "Copyright (C) 1998-2021 by Sonic Team Junior\n\n" "This program comes with ABSOLUTELY NO WARRANTY.\n\n" "This is free software, and you are welcome to redistribute it\n" "and/or modify it under the terms of the GNU General Public License\n" From f437d6afec08bebab2d44f0d383c316f11df4934 Mon Sep 17 00:00:00 2001 From: Vincent Robinson Date: Mon, 26 Apr 2021 16:27:39 -0700 Subject: [PATCH 409/644] Add linedef specials for multitagging in binary maps --- extras/conf/SRB2-22.cfg | 18 ++++++++++++++++++ src/p_setup.c | 21 +++++++++++++++++++++ src/taglist.c | 6 ++++-- 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg index 3fd4b6ccd..9a8484df5 100644 --- a/extras/conf/SRB2-22.cfg +++ b/extras/conf/SRB2-22.cfg @@ -640,6 +640,24 @@ linedeftypes prefix = "(63)"; } + 97 + { + title = "Apply Tag to Front Sector"; + prefix = "(97)"; + } + + 98 + { + title = "Apply Tag to Back Sector"; + prefix = "(98)"; + } + + 99 + { + title = "Apply Tag to Front and Back Sectors"; + prefix = "(99)"; + } + 540 { title = "Floor Friction"; diff --git a/src/p_setup.c b/src/p_setup.c index 40dd1a284..1b060660d 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2950,6 +2950,24 @@ static void P_LinkMapData(void) } } +// For maps in binary format, add multi-tags from linedef specials. This must be done +// before any linedef specials have been processed. +static void P_AddBinaryMapTags(void) +{ + size_t i; + + for (i = 0; i < numlines; i++) + { + // 97: Apply Tag to Front Sector + // 98: Apply Tag to Back Sector + // 99: Apply Tag to Front and Back Sectors + if (lines[i].special == 97 || lines[i].special == 99) + Tag_Add(&lines[i].frontsector->tags, Tag_FGet(&lines[i].tags)); + if (lines[i].special == 98 || lines[i].special == 99) + Tag_Add(&lines[i].backsector->tags, Tag_FGet(&lines[i].tags)); + } +} + //For maps in binary format, converts setup of specials to UDMF format. static void P_ConvertBinaryMap(void) { @@ -3287,6 +3305,9 @@ static boolean P_LoadMapFromFile(void) P_LinkMapData(); + if (!udmf) + P_AddBinaryMapTags(); + Taglist_InitGlobalTables(); if (!udmf) diff --git a/src/taglist.c b/src/taglist.c index a759f4d02..e8b64d3f4 100644 --- a/src/taglist.c +++ b/src/taglist.c @@ -27,11 +27,13 @@ taggroup_t* tags_sectors[MAXTAGS + 1]; taggroup_t* tags_lines[MAXTAGS + 1]; taggroup_t* tags_mapthings[MAXTAGS + 1]; -/// Adds a tag to a given element's taglist. +/// Adds a tag to a given element's taglist. It will not add a duplicate. /// \warning This does not rebuild the global taggroups, which are used for iteration. void Tag_Add (taglist_t* list, const mtag_t tag) { - list->tags = Z_Realloc(list->tags, (list->count + 1) * sizeof(list->tags), PU_LEVEL, NULL); + if (Tag_Find(list, tag)) + return; + list->tags = Z_Realloc(list->tags, (list->count + 1) * sizeof(mtag_t), PU_LEVEL, NULL); list->tags[list->count++] = tag; } From 85c53b35cd3a00ddd8d30fbca15499e3b529179b Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Mon, 26 Apr 2021 22:17:03 -0300 Subject: [PATCH 410/644] Use old routine for PO2 spans --- src/r_plane.c | 108 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 76 insertions(+), 32 deletions(-) diff --git a/src/r_plane.c b/src/r_plane.c index 10d87b9cc..ea5a7a3c3 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -789,6 +789,78 @@ static void R_SetSlopePlaneVectors(visplane_t *pl, INT32 y, fixed_t xoff, fixed_ R_CalculateSlopeVectors(); } +/* + Essentially: We can't & the components along the regular axes when the plane is rotated. + This is because the distance on each regular axis in order to loop is different. + We rotate them, & the components, add them together, & them again, and then rotate them back. + These three seperate & operations are done per axis in order to prevent overflows. + toast 10/04/17 +*/ +static inline void R_AdjustSlopeCoordinates(visplane_t *pl) +{ + const fixed_t modmask = ((1 << (32-nflatshiftup)) - 1); + + const fixed_t cosinecomponent = FINECOSINE(pl->plangle>>ANGLETOFINESHIFT); + const fixed_t sinecomponent = FINESINE(pl->plangle>>ANGLETOFINESHIFT); + + fixed_t ox = (FixedMul(pl->slope->o.x,cosinecomponent) & modmask) - (FixedMul(pl->slope->o.y,sinecomponent) & modmask); + fixed_t oy = (-FixedMul(pl->slope->o.x,sinecomponent) & modmask) - (FixedMul(pl->slope->o.y,cosinecomponent) & modmask); + + fixed_t temp = ox & modmask; + oy &= modmask; + + ox = FixedMul(temp,cosinecomponent)+FixedMul(oy,-sinecomponent); // negative sine for opposite direction + oy = -FixedMul(temp,-sinecomponent)+FixedMul(oy,cosinecomponent); + + if (xoffs || yoffs) + { + temp = xoffs; + xoffs = (FixedMul(temp,cosinecomponent) & modmask) + (FixedMul(yoffs,sinecomponent) & modmask); + yoffs = (-FixedMul(temp,sinecomponent) & modmask) + (FixedMul(yoffs,cosinecomponent) & modmask); + + temp = xoffs & modmask; + yoffs &= modmask; + xoffs = FixedMul(temp,cosinecomponent)+FixedMul(yoffs,-sinecomponent); // ditto + yoffs = -FixedMul(temp,-sinecomponent)+FixedMul(yoffs,cosinecomponent); + } + + xoffs -= (pl->slope->o.x - ox); + yoffs += (pl->slope->o.y + oy); +} + +static inline void R_AdjustSlopeCoordinatesNPO2(visplane_t *pl) +{ + const fixed_t modmaskw = (ds_flatwidth << FRACBITS); + const fixed_t modmaskh = (ds_flatheight << FRACBITS); + + const fixed_t cosinecomponent = FINECOSINE(pl->plangle>>ANGLETOFINESHIFT); + const fixed_t sinecomponent = FINESINE(pl->plangle>>ANGLETOFINESHIFT); + + fixed_t ox = (FixedMul(pl->slope->o.x,cosinecomponent) % modmaskw) - (FixedMul(pl->slope->o.y,sinecomponent) % modmaskh); + fixed_t oy = (-FixedMul(pl->slope->o.x,sinecomponent) % modmaskw) - (FixedMul(pl->slope->o.y,cosinecomponent) % modmaskh); + + fixed_t temp = ox % modmaskw; + oy %= modmaskh; + + ox = FixedMul(temp,cosinecomponent)+FixedMul(oy,-sinecomponent); // negative sine for opposite direction + oy = -FixedMul(temp,-sinecomponent)+FixedMul(oy,cosinecomponent); + + if (xoffs || yoffs) + { + temp = xoffs; + xoffs = (FixedMul(temp,cosinecomponent) % modmaskw) + (FixedMul(yoffs,sinecomponent) % modmaskh); + yoffs = (-FixedMul(temp,sinecomponent) % modmaskw) + (FixedMul(yoffs,cosinecomponent) % modmaskh); + + temp = xoffs % modmaskw; + yoffs %= modmaskh; + xoffs = FixedMul(temp,cosinecomponent)+FixedMul(yoffs,-sinecomponent); // ditto + yoffs = -FixedMul(temp,-sinecomponent)+FixedMul(yoffs,cosinecomponent); + } + + xoffs -= (pl->slope->o.x - ox); + yoffs += (pl->slope->o.y + oy); +} + void R_DrawSinglePlane(visplane_t *pl) { levelflat_t *levelflat; @@ -967,38 +1039,10 @@ void R_DrawSinglePlane(visplane_t *pl) if (pl->slope) { - const fixed_t modmaskw = (ds_powersoftwo) ? (ds_flatwidth << FRACBITS) - 1 : (signed)(0xFFFFFFFF); - const fixed_t modmaskh = (ds_powersoftwo) ? (ds_flatheight << FRACBITS) - 1 : (signed)(0xFFFFFFFF); - - /* - Essentially: We can't & the components along the regular axes when the plane is rotated. - This is because the distance on each regular axis in order to loop is different. - We rotate them, & the components, add them together, & them again, and then rotate them back. - These three seperate & operations are done per axis in order to prevent overflows. - toast 10/04/17 - */ - const fixed_t cosinecomponent = FINECOSINE(pl->plangle>>ANGLETOFINESHIFT); - const fixed_t sinecomponent = FINESINE(pl->plangle>>ANGLETOFINESHIFT); - - fixed_t ox = (FixedMul(pl->slope->o.x,cosinecomponent) & modmaskw) - (FixedMul(pl->slope->o.y,sinecomponent) & modmaskh); - fixed_t oy = (-FixedMul(pl->slope->o.x,sinecomponent) & modmaskw) - (FixedMul(pl->slope->o.y,cosinecomponent) & modmaskh); - - fixed_t temp = ox & modmaskw; - oy &= modmaskh; - ox = FixedMul(temp,cosinecomponent)+FixedMul(oy,-sinecomponent); // negative sine for opposite direction - oy = -FixedMul(temp,-sinecomponent)+FixedMul(oy,cosinecomponent); - - temp = xoffs; - xoffs = (FixedMul(temp,cosinecomponent) & modmaskw) + (FixedMul(yoffs,sinecomponent) & modmaskh); - yoffs = (-FixedMul(temp,sinecomponent) & modmaskw) + (FixedMul(yoffs,cosinecomponent) & modmaskh); - - temp = xoffs & modmaskw; - yoffs &= modmaskh; - xoffs = FixedMul(temp,cosinecomponent)+FixedMul(yoffs,-sinecomponent); // ditto - yoffs = -FixedMul(temp,-sinecomponent)+FixedMul(yoffs,cosinecomponent); - - xoffs -= (pl->slope->o.x - ox); - yoffs += (pl->slope->o.y + oy); + if (ds_powersoftwo) + R_AdjustSlopeCoordinates(pl); + else + R_AdjustSlopeCoordinatesNPO2(pl); if (planeripple.active) { From 548554431b945d684725459bab14a6a00951244f Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Tue, 27 Apr 2021 00:20:41 -0300 Subject: [PATCH 411/644] Handle invalid blend modes properly --- src/hardware/hw_main.c | 15 ++++++--------- src/hardware/hw_main.h | 2 +- src/lua_mobjlib.c | 8 +++++++- src/r_draw.c | 4 ++-- 4 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index e94c637e4..41de5ddcf 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -712,13 +712,12 @@ static void HWR_RenderSkyPlane(extrasubsector_t *xsub, fixed_t fixedheight) #endif //doplanes -FBITFIELD HWR_GetBlendModeFlag(INT32 ast) +FBITFIELD HWR_GetBlendModeFlag(INT32 style) { - switch (ast) + switch (style) { - case AST_COPY: - case AST_OVERLAY: - return PF_Masked; + case AST_TRANSLUCENT: + return PF_Translucent; case AST_ADD: return PF_Additive; case AST_SUBTRACT: @@ -728,10 +727,8 @@ FBITFIELD HWR_GetBlendModeFlag(INT32 ast) case AST_MODULATE: return PF_Multiplicative; default: - return PF_Translucent; + return PF_Masked; } - - return 0; } UINT8 HWR_GetTranstableAlpha(INT32 transtablenum) @@ -757,7 +754,7 @@ UINT8 HWR_GetTranstableAlpha(INT32 transtablenum) FBITFIELD HWR_SurfaceBlend(INT32 style, INT32 transtablenum, FSurfaceInfo *pSurf) { - if (!transtablenum || style == AST_COPY || style == AST_OVERLAY) + if (!transtablenum || style <= AST_COPY || style >= AST_OVERLAY) { pSurf->PolyColor.s.alpha = 0xff; return PF_Masked; diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index 4ad09aa3d..2c7d237bf 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -69,7 +69,7 @@ void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *col UINT8 HWR_FogBlockAlpha(INT32 light, extracolormap_t *colormap); // Let's see if this can work UINT8 HWR_GetTranstableAlpha(INT32 transtablenum); -FBITFIELD HWR_GetBlendModeFlag(INT32 ast); +FBITFIELD HWR_GetBlendModeFlag(INT32 style); FBITFIELD HWR_SurfaceBlend(INT32 style, INT32 transtablenum, FSurfaceInfo *pSurf); FBITFIELD HWR_TranstableToAlpha(INT32 transtablenum, FSurfaceInfo *pSurf); diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index 65adceb15..994f6a789 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -12,6 +12,7 @@ #include "doomdef.h" #include "fastcmp.h" +#include "r_data.h" #include "r_skins.h" #include "p_local.h" #include "g_game.h" @@ -654,8 +655,13 @@ static int mobj_set(lua_State *L) break; } case mobj_blendmode: - mo->blendmode = (INT32)luaL_checkinteger(L, 3); + { + INT32 blendmode = (INT32)luaL_checkinteger(L, 3); + if (blendmode < 0 || blendmode > AST_OVERLAY) + return luaL_error(L, "mobj.blendmode %d out of range (0 - %d).", blendmode, AST_OVERLAY); + mo->blendmode = blendmode; break; + } case mobj_bnext: return NOSETPOS; case mobj_bprev: diff --git a/src/r_draw.c b/src/r_draw.c index 9a835ee58..1d2d8352f 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -341,7 +341,7 @@ UINT8 *R_GetBlendTable(int style, INT32 alphalevel) { size_t offs; - if (style == AST_COPY || style == AST_OVERLAY) + if (style <= AST_COPY || style >= AST_OVERLAY) return NULL; offs = (ClipBlendLevel(style, alphalevel) << FF_TRANSSHIFT); @@ -371,7 +371,7 @@ UINT8 *R_GetBlendTable(int style, INT32 alphalevel) boolean R_BlendLevelVisible(INT32 blendmode, INT32 alphalevel) { - if (blendmode == AST_COPY || blendmode == AST_SUBTRACT || blendmode == AST_MODULATE || blendmode == AST_OVERLAY) + if (blendmode <= AST_COPY || blendmode == AST_SUBTRACT || blendmode == AST_MODULATE || blendmode >= AST_OVERLAY) return true; return (alphalevel < BlendTab_Count[BlendTab_FromStyle[blendmode]]); From 21da6ce704c5665a77fcb42e21beb995fce65453 Mon Sep 17 00:00:00 2001 From: Zwip-Zwap Zapony Date: Tue, 27 Apr 2021 21:30:00 +0200 Subject: [PATCH 412/644] Auto-crop at splitscreen borders V_DrawCroppedPatch will no longer go beyond splitscreen borders when V_PERPLAYER is used --- src/hardware/hw_draw.c | 70 ++++++++++++++++++++++++++++++++++++++++++ src/v_video.c | 31 +++++++++++++++++++ 2 files changed, 101 insertions(+) diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index 8722495e4..7deb36b69 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -596,6 +596,76 @@ void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, if (option & V_WRAPY) flags |= PF_ForceWrapY; + // Auto-crop at splitscreen borders! + if (splitscreen && (option & V_PERPLAYER)) + { +#define flerp(a,b,amount) (((a) * (1.0f - (amount))) + ((b) * (amount))) // Float lerp + +#ifdef QUADS + if (splitscreen > 1) // 3 or 4 players + { + #error Auto-cropping doesnt take quadscreen into account! Fix it! + // Hint: For player 1/2, copy player 1's code below. For player 3/4, copy player 2's code below + // For player 1/3 and 2/4, mangle the below code to apply horizontally instead of vertically + } + else +#endif + // 2 players + { + if (stplyr == &players[displayplayer]) // Player 1's screen, crop at the bottom + { + if ((cy - fheight) < 0) // If the bottom is below the border + { + if (cy <= 0) // If the whole patch is beyond the border... + return; // ...crop away the entire patch, don't draw anything + + if (fheight <= 0) // Don't divide by zero + return; + + v[2].y = v[3].y = 0; // Clamp the polygon edge vertex position + // Now for the UV-map... Uh-oh, math time! + + // On second thought, a basic linear interpolation suffices + //float full_height = fheight; + //float cropped_height = fheight - cy; + //float remaining_height = cy; + //float cropped_percentage = (fheight - cy) / fheight; + //float remaining_percentage = cy / fheight; + //v[2].t = v[3].t = lerp(v[2].t, v[0].t, cropped_percentage); + // By swapping v[2] and v[0], we can use remaining_percentage for less operations + //v[2].t = v[3].t = lerp(v[0].t, v[2].t, remaining_percentage); + + v[2].t = v[3].t = flerp(v[0].t, v[2].t, cy/fheight); + } + } + else //if (stplyr == &players[secondarydisplayplayer]) // Player 2's screen, crop at the top + { + if (cy > 0) // If the top is above the border + { + if ((cy - fheight) >= 0) // If the whole patch is beyond the border... + return; // ...crop away the entire patch, don't draw anything + + if (fheight <= 0) // Don't divide by zero + return; + + v[0].y = v[1].y = 0; // Clamp the polygon edge vertex position + // Now for the UV-map... Uh-oh, math time! + + // On second thought, a basic linear interpolation suffices + //float full_height = fheight; + //float cropped_height = cy; + //float remaining_height = fheight - cy; + //float cropped_percentage = cy / fheight; + //float remaining_percentage = (fheight - cy) / fheight; + //v[0].t = v[1].t = lerp(v[0].t, v[2].t, cropped_percentage); + + v[0].t = v[1].t = flerp(v[0].t, v[2].t, cy/fheight); + } + } + } +#undef flerp + } + // clip it since it is used for bunny scroll in doom I if (alphalevel) { diff --git a/src/v_video.c b/src/v_video.c index 4ac8e4d27..bc919af72 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -1019,6 +1019,37 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, IN desttop += (y*vid.width) + x; } + // Auto-crop at splitscreen borders! + if (splitscreen && (scrn & V_PERPLAYER)) + { +#ifdef QUADS + if (splitscreen > 1) // 3 or 4 players + { + #error Auto-cropping doesnt take quadscreen into account! Fix it! + // Hint: For player 1/2, copy player 1's code below. For player 3/4, copy player 2's code below + // For player 1/3 and 2/4, hijack the X wrap prevention lines? That's probably easiest + } + else +#endif + // 2 players + { + if (stplyr == &players[displayplayer]) // Player 1's screen, crop at the bottom + { + // Just put a big old stop sign halfway through the screen + deststop -= vid.rowbytes * (vid.height>>1); + } + else //if (stplyr == &players[secondarydisplayplayer]) // Player 2's screen, crop at the top + { + if (y < (vid.height>>1)) // If the top is above the border + { + sy += ((vid.height>>1) - y) * rowfrac; // Start further down on the patch + h -= ((vid.height>>1) - y) * rowfrac; // Draw less downwards from the start + desttop += ((vid.height>>1) - y) * vid.width; // Start drawing at the border + } + } + } + } + for (col = sx; (col>>FRACBITS) < patch->width && (col - sx) < w; col += colfrac, ++x, desttop++) { INT32 topdelta, prevdelta = -1; From e4b8dc6584de4fed284cb14801b2dbb9b6dcafe6 Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Tue, 27 Apr 2021 19:01:09 -0300 Subject: [PATCH 413/644] Fix sloped plane offsets in Software, and fix rotated flat alignment in OpenGL. + unrelated slope plane optimizations in Software --- src/hardware/hw_main.c | 31 ++-- src/r_draw.h | 2 +- src/r_plane.c | 313 +++++++++++++++++++++-------------------- src/r_plane.h | 4 +- 4 files changed, 170 insertions(+), 180 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index f2af1cc40..b261c6460 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -362,10 +362,10 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool float fflatwidth = 64.0f, fflatheight = 64.0f; INT32 flatflag = 63; boolean texflat = false; - float scrollx = 0.0f, scrolly = 0.0f; + float scrollx = 0.0f, scrolly = 0.0f, anglef = 0.0f; angle_t angle = 0; FSurfaceInfo Surf; - fixed_t tempxsow, tempytow; + float tempxsow, tempytow; pslope_t *slope = NULL; static FOutVector *planeVerts = NULL; @@ -499,24 +499,15 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool } } - if (angle) // Only needs to be done if there's an altered angle { + tempxsow = flatxref; + tempytow = flatyref; - angle = (InvAngle(angle))>>ANGLETOFINESHIFT; + anglef = ANG2RAD(InvAngle(angle)); - // This needs to be done so that it scrolls in a different direction after rotation like software - /*tempxsow = FLOAT_TO_FIXED(scrollx); - tempytow = FLOAT_TO_FIXED(scrolly); - scrollx = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINECOSINE(angle)) - FixedMul(tempytow, FINESINE(angle)))); - scrolly = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINESINE(angle)) + FixedMul(tempytow, FINECOSINE(angle))));*/ - - // This needs to be done so everything aligns after rotation - // It would be done so that rotation is done, THEN the translation, but I couldn't get it to rotate AND scroll like software does - tempxsow = FLOAT_TO_FIXED(flatxref); - tempytow = FLOAT_TO_FIXED(flatyref); - flatxref = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINECOSINE(angle)) - FixedMul(tempytow, FINESINE(angle)))); - flatyref = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINESINE(angle)) + FixedMul(tempytow, FINECOSINE(angle)))); + flatxref = (tempxsow * cos(anglef)) - (tempytow * sin(anglef)); + flatyref = (tempxsow * sin(anglef)) + (tempytow * cos(anglef)); } #define SETUP3DVERT(vert, vx, vy) {\ @@ -535,10 +526,10 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool /* Need to rotate before translate */\ if (angle) /* Only needs to be done if there's an altered angle */\ {\ - tempxsow = FLOAT_TO_FIXED(vert->s);\ - tempytow = FLOAT_TO_FIXED(vert->t);\ - vert->s = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINECOSINE(angle)) - FixedMul(tempytow, FINESINE(angle))));\ - vert->t = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINESINE(angle)) + FixedMul(tempytow, FINECOSINE(angle))));\ + tempxsow = vert->s;\ + tempytow = vert->t;\ + vert->s = (tempxsow * cos(anglef)) - (tempytow * sin(anglef));\ + vert->t = (tempxsow * sin(anglef)) + (tempytow * cos(anglef));\ }\ \ vert->x = (vx);\ diff --git a/src/r_draw.h b/src/r_draw.h index caf43fd89..2173c7a5a 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -177,7 +177,7 @@ void R_Draw2sMultiPatchTranslucentColumn_8(void); void R_DrawFogColumn_8(void); void R_DrawColumnShadowed_8(void); -#define PLANELIGHTFLOAT (BASEVIDWIDTH * BASEVIDWIDTH / vid.width / (zeroheight - FIXED_TO_FLOAT(viewz)) / 21.0f * FIXED_TO_FLOAT(fovtan)) +#define PLANELIGHTFLOAT (BASEVIDWIDTH * BASEVIDWIDTH / vid.width / zeroheight / 21.0f * FIXED_TO_FLOAT(fovtan)) void R_DrawSpan_8(void); void R_DrawTranslucentSpan_8(void); diff --git a/src/r_plane.c b/src/r_plane.c index ea5a7a3c3..ee7b161da 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -31,13 +31,6 @@ #include "z_zone.h" #include "p_tick.h" -#ifdef TIMING -#include "p5prof.h" - INT64 mycount; - INT64 mytotal = 0; - UINT32 nombre = 100000; -#endif - // // opening // @@ -128,21 +121,20 @@ struct boolean active; } planeripple; -static void R_CalculatePlaneRipple(visplane_t *plane, INT32 y, fixed_t plheight, boolean calcfrac) +// ripples da water texture +static fixed_t R_CalculateRippleOffset(INT32 y) { - fixed_t distance = FixedMul(plheight, yslope[y]); + fixed_t distance = FixedMul(planeheight, yslope[y]); const INT32 yay = (planeripple.offset + (distance>>9)) & 8191; + return FixedDiv(FINESINE(yay), (1<<12) + (distance>>11)); +} - // ripples da water texture - ds_bgofs = FixedDiv(FINESINE(yay), (1<<12) + (distance>>11))>>FRACBITS; - - if (calcfrac) - { - angle_t angle = (plane->viewangle + plane->plangle)>>ANGLETOFINESHIFT; - angle = (angle + 2048) & 8191; // 90 degrees - planeripple.xfrac = FixedMul(FINECOSINE(angle), (ds_bgofs<>= ANGLETOFINESHIFT; + angle = (angle + 2048) & 8191; // 90 degrees + planeripple.xfrac = FixedMul(FINECOSINE(angle), ds_bgofs); + planeripple.yfrac = FixedMul(FINESINE(angle), ds_bgofs); } static void R_UpdatePlaneRipple(void) @@ -160,7 +152,7 @@ static void R_UpdatePlaneRipple(void) // baseyscale // centerx -void R_MapPlane(INT32 y, INT32 x1, INT32 x2) +static void R_MapPlane(INT32 y, INT32 x1, INT32 x2) { angle_t angle, planecos, planesin; fixed_t distance = 0, span; @@ -174,60 +166,50 @@ void R_MapPlane(INT32 y, INT32 x1, INT32 x2) if (x1 >= vid.width) x1 = vid.width - 1; - if (!currentplane->slope) + angle = (currentplane->viewangle + currentplane->plangle)>>ANGLETOFINESHIFT; + planecos = FINECOSINE(angle); + planesin = FINESINE(angle); + + if (planeheight != cachedheight[y]) { - angle = (currentplane->viewangle + currentplane->plangle)>>ANGLETOFINESHIFT; - planecos = FINECOSINE(angle); - planesin = FINESINE(angle); + cachedheight[y] = planeheight; + cacheddistance[y] = distance = FixedMul(planeheight, yslope[y]); + span = abs(centery - y); - if (planeheight != cachedheight[y]) + if (span) // don't divide by zero { - cachedheight[y] = planeheight; - cacheddistance[y] = distance = FixedMul(planeheight, yslope[y]); - span = abs(centery - y); - - if (span) // don't divide by zero - { - ds_xstep = FixedMul(planesin, planeheight) / span; - ds_ystep = FixedMul(planecos, planeheight) / span; - } - else - { - ds_xstep = FixedMul(distance, basexscale); - ds_ystep = FixedMul(distance, baseyscale); - } - - cachedxstep[y] = ds_xstep; - cachedystep[y] = ds_ystep; + ds_xstep = FixedMul(planesin, planeheight) / span; + ds_ystep = FixedMul(planecos, planeheight) / span; } else { - distance = cacheddistance[y]; - ds_xstep = cachedxstep[y]; - ds_ystep = cachedystep[y]; + ds_xstep = FixedMul(distance, basexscale); + ds_ystep = FixedMul(distance, baseyscale); } - ds_xfrac = xoffs + FixedMul(planecos, distance) + (x1 - centerx) * ds_xstep; - ds_yfrac = yoffs - FixedMul(planesin, distance) + (x1 - centerx) * ds_ystep; + cachedxstep[y] = ds_xstep; + cachedystep[y] = ds_ystep; } + else + { + distance = cacheddistance[y]; + ds_xstep = cachedxstep[y]; + ds_ystep = cachedystep[y]; + } + + ds_xfrac = xoffs + FixedMul(planecos, distance) + (x1 - centerx) * ds_xstep; + ds_yfrac = yoffs - FixedMul(planesin, distance) + (x1 - centerx) * ds_ystep; // Water ripple effect if (planeripple.active) { - // Needed for ds_bgofs - R_CalculatePlaneRipple(currentplane, y, planeheight, (!currentplane->slope)); + ds_bgofs = R_CalculateRippleOffset(y); - if (currentplane->slope) - { - ds_sup = &ds_su[y]; - ds_svp = &ds_sv[y]; - ds_szp = &ds_sz[y]; - } - else - { - ds_xfrac += planeripple.xfrac; - ds_yfrac += planeripple.yfrac; - } + R_CalculatePlaneRipple(currentplane->viewangle + currentplane->plangle); + + ds_xfrac += planeripple.xfrac; + ds_yfrac += planeripple.yfrac; + ds_bgofs >>= FRACBITS; if ((y + ds_bgofs) >= viewheight) ds_bgofs = viewheight-y-1; @@ -235,16 +217,11 @@ void R_MapPlane(INT32 y, INT32 x1, INT32 x2) ds_bgofs = -y; } - if (currentplane->slope) - ds_colormap = colormaps; - else - { - pindex = distance >> LIGHTZSHIFT; - if (pindex >= MAXLIGHTZ) - pindex = MAXLIGHTZ - 1; - ds_colormap = planezlight[pindex]; - } + pindex = distance >> LIGHTZSHIFT; + if (pindex >= MAXLIGHTZ) + pindex = MAXLIGHTZ - 1; + ds_colormap = planezlight[pindex]; if (currentplane->extra_colormap) ds_colormap = currentplane->extra_colormap->colormap + (ds_colormap - colormaps); @@ -252,19 +229,46 @@ void R_MapPlane(INT32 y, INT32 x1, INT32 x2) ds_x1 = x1; ds_x2 = x2; - // profile drawer -#ifdef TIMING - ProfZeroTimer(); + spanfunc(); +} + +static void R_MapTiltedPlane(INT32 y, INT32 x1, INT32 x2) +{ +#ifdef RANGECHECK + if (x2 < x1 || x1 < 0 || x2 >= viewwidth || y > viewheight) + I_Error("R_MapTiltedPlane: %d, %d at %d", x1, x2, y); #endif + if (x1 >= vid.width) + x1 = vid.width - 1; + + // Water ripple effect + if (planeripple.active) + { + ds_bgofs = R_CalculateRippleOffset(y); + + ds_sup = &ds_su[y]; + ds_svp = &ds_sv[y]; + ds_szp = &ds_sz[y]; + + ds_bgofs >>= FRACBITS; + + if ((y + ds_bgofs) >= viewheight) + ds_bgofs = viewheight-y-1; + if ((y + ds_bgofs) < 0) + ds_bgofs = -y; + } + + if (currentplane->extra_colormap) + ds_colormap = currentplane->extra_colormap->colormap; + else + ds_colormap = colormaps; + + ds_y = y; + ds_x1 = x1; + ds_x2 = x2; + spanfunc(); - -#ifdef TIMING - RDMSR(0x10, &mycount); - mytotal += mycount; // 64bit add - if (!(nombre--)) - I_Error("spanfunc() CPU Spy reports: 0x%d %d\n", *((INT32 *)&mytotal+1), (INT32)mytotal); -#endif } void R_ClearFFloorClips (void) @@ -572,10 +576,7 @@ void R_ExpandPlane(visplane_t *pl, INT32 start, INT32 stop) } -// -// R_MakeSpans -// -void R_MakeSpans(INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2) +static void R_MakeSpans(INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2) { // Alam: from r_splats's R_RasterizeFloorSplat if (t1 >= vid.height) t1 = vid.height-1; @@ -601,6 +602,32 @@ void R_MakeSpans(INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2) spanstart[b2--] = x; } +static void R_MakeTiltedSpans(INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2) +{ + // Alam: from r_splats's R_RasterizeFloorSplat + if (t1 >= vid.height) t1 = vid.height-1; + if (b1 >= vid.height) b1 = vid.height-1; + if (t2 >= vid.height) t2 = vid.height-1; + if (b2 >= vid.height) b2 = vid.height-1; + if (x-1 >= vid.width) x = vid.width; + + while (t1 < t2 && t1 <= b1) + { + R_MapTiltedPlane(t1, spanstart[t1], x - 1); + t1++; + } + while (b1 > b2 && b1 >= t1) + { + R_MapTiltedPlane(b1, spanstart[b1], x - 1); + b1--; + } + + while (t2 < t1 && t2 <= b2) + spanstart[t2++] = x; + while (b2 > b1 && b2 >= t2) + spanstart[b2--] = x; +} + void R_DrawPlanes(void) { visplane_t *pl; @@ -670,17 +697,14 @@ static void R_SetSlopePlaneOrigin(pslope_t *slope, fixed_t xpos, fixed_t ypos, f float vx = FixedToFloat(xpos + xoff); float vy = FixedToFloat(ypos - yoff); - float vz = FixedToFloat(zpos); float ang = ANG2RAD(ANGLE_270 - angle); - zeroheight = FixedToFloat(P_GetSlopeZAt(slope, xpos, ypos)); - // p is the texture origin in view space // Don't add in the offsets at this stage, because doing so can result in // errors if the flat is rotated. p->x = vx * cos(ang) - vy * sin(ang); p->z = vx * sin(ang) + vy * cos(ang); - p->y = FixedToFloat(P_GetSlopeZAt(slope, -xoff, yoff)) - vz; + p->y = FixedToFloat(P_GetSlopeZAt(slope, -xoff, yoff) - zpos); } // This function calculates all of the vectors necessary for drawing a sloped plane. @@ -689,10 +713,12 @@ void R_SetSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, // Potentially override other stuff for now cus we're mean. :< But draw a slope plane! // I copied ZDoom's code and adapted it to SRB2... -Red floatv3_t *m = &ds_slope_v, *n = &ds_slope_u; - fixed_t temp; + fixed_t height, temp; float ang; R_SetSlopePlaneOrigin(slope, xpos, ypos, zpos, xoff, yoff, angle); + height = P_GetSlopeZAt(slope, xpos, ypos); + zeroheight = FixedToFloat(height - zpos); // m is the v direction vector in view space ang = ANG2RAD(ANGLE_180 - (angle + plangle)); @@ -703,24 +729,26 @@ void R_SetSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, n->x = sin(ang); n->z = -cos(ang); - ang = ANG2RAD(plangle); - temp = P_GetSlopeZAt(slope, xpos + FloatToFixed(sin(ang)), ypos + FloatToFixed(cos(ang))); - m->y = FixedToFloat(temp) - zeroheight; - temp = P_GetSlopeZAt(slope, xpos + FloatToFixed(cos(ang)), ypos - FloatToFixed(sin(ang))); - n->y = FixedToFloat(temp) - zeroheight; + plangle >>= ANGLETOFINESHIFT; + temp = P_GetSlopeZAt(slope, xpos + FINESINE(plangle), ypos + FINECOSINE(plangle)); + m->y = FixedToFloat(temp - height); + temp = P_GetSlopeZAt(slope, xpos + FINECOSINE(plangle), ypos - FINESINE(plangle)); + n->y = FixedToFloat(temp - height); } // This function calculates all of the vectors necessary for drawing a sloped and scaled plane. void R_SetScaledSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xs, fixed_t ys, fixed_t xoff, fixed_t yoff, angle_t angle, angle_t plangle) { floatv3_t *m = &ds_slope_v, *n = &ds_slope_u; - fixed_t temp; + fixed_t height, temp; float xscale = FixedToFloat(xs); float yscale = FixedToFloat(ys); float ang; R_SetSlopePlaneOrigin(slope, xpos, ypos, zpos, xoff, yoff, angle); + height = P_GetSlopeZAt(slope, xpos, ypos); + zeroheight = FixedToFloat(height - zpos); // m is the v direction vector in view space ang = ANG2RAD(ANGLE_180 - (angle + plangle)); @@ -733,9 +761,9 @@ void R_SetScaledSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t ang = ANG2RAD(plangle); temp = P_GetSlopeZAt(slope, xpos + FloatToFixed(yscale * sin(ang)), ypos + FloatToFixed(yscale * cos(ang))); - m->y = FixedToFloat(temp) - zeroheight; + m->y = FixedToFloat(temp - height); temp = P_GetSlopeZAt(slope, xpos + FloatToFixed(xscale * cos(ang)), ypos - FloatToFixed(xscale * sin(ang))); - n->y = FixedToFloat(temp) - zeroheight; + n->y = FixedToFloat(temp - height); } void R_CalculateSlopeVectors(void) @@ -803,29 +831,14 @@ static inline void R_AdjustSlopeCoordinates(visplane_t *pl) const fixed_t cosinecomponent = FINECOSINE(pl->plangle>>ANGLETOFINESHIFT); const fixed_t sinecomponent = FINESINE(pl->plangle>>ANGLETOFINESHIFT); - fixed_t ox = (FixedMul(pl->slope->o.x,cosinecomponent) & modmask) - (FixedMul(pl->slope->o.y,sinecomponent) & modmask); - fixed_t oy = (-FixedMul(pl->slope->o.x,sinecomponent) & modmask) - (FixedMul(pl->slope->o.y,cosinecomponent) & modmask); + fixed_t temp = xoffs; + xoffs = (FixedMul(temp,cosinecomponent) & modmask) + (FixedMul(yoffs,sinecomponent) & modmask); + yoffs = (-FixedMul(temp,sinecomponent) & modmask) + (FixedMul(yoffs,cosinecomponent) & modmask); - fixed_t temp = ox & modmask; - oy &= modmask; - - ox = FixedMul(temp,cosinecomponent)+FixedMul(oy,-sinecomponent); // negative sine for opposite direction - oy = -FixedMul(temp,-sinecomponent)+FixedMul(oy,cosinecomponent); - - if (xoffs || yoffs) - { - temp = xoffs; - xoffs = (FixedMul(temp,cosinecomponent) & modmask) + (FixedMul(yoffs,sinecomponent) & modmask); - yoffs = (-FixedMul(temp,sinecomponent) & modmask) + (FixedMul(yoffs,cosinecomponent) & modmask); - - temp = xoffs & modmask; - yoffs &= modmask; - xoffs = FixedMul(temp,cosinecomponent)+FixedMul(yoffs,-sinecomponent); // ditto - yoffs = -FixedMul(temp,-sinecomponent)+FixedMul(yoffs,cosinecomponent); - } - - xoffs -= (pl->slope->o.x - ox); - yoffs += (pl->slope->o.y + oy); + temp = xoffs & modmask; + yoffs &= modmask; + xoffs = FixedMul(temp,cosinecomponent)+FixedMul(yoffs,-sinecomponent); // negative sine for opposite direction + yoffs = -FixedMul(temp,-sinecomponent)+FixedMul(yoffs,cosinecomponent); } static inline void R_AdjustSlopeCoordinatesNPO2(visplane_t *pl) @@ -836,29 +849,14 @@ static inline void R_AdjustSlopeCoordinatesNPO2(visplane_t *pl) const fixed_t cosinecomponent = FINECOSINE(pl->plangle>>ANGLETOFINESHIFT); const fixed_t sinecomponent = FINESINE(pl->plangle>>ANGLETOFINESHIFT); - fixed_t ox = (FixedMul(pl->slope->o.x,cosinecomponent) % modmaskw) - (FixedMul(pl->slope->o.y,sinecomponent) % modmaskh); - fixed_t oy = (-FixedMul(pl->slope->o.x,sinecomponent) % modmaskw) - (FixedMul(pl->slope->o.y,cosinecomponent) % modmaskh); + fixed_t temp = xoffs; + xoffs = (FixedMul(temp,cosinecomponent) % modmaskw) + (FixedMul(yoffs,sinecomponent) % modmaskh); + yoffs = (-FixedMul(temp,sinecomponent) % modmaskw) + (FixedMul(yoffs,cosinecomponent) % modmaskh); - fixed_t temp = ox % modmaskw; - oy %= modmaskh; - - ox = FixedMul(temp,cosinecomponent)+FixedMul(oy,-sinecomponent); // negative sine for opposite direction - oy = -FixedMul(temp,-sinecomponent)+FixedMul(oy,cosinecomponent); - - if (xoffs || yoffs) - { - temp = xoffs; - xoffs = (FixedMul(temp,cosinecomponent) % modmaskw) + (FixedMul(yoffs,sinecomponent) % modmaskh); - yoffs = (-FixedMul(temp,sinecomponent) % modmaskw) + (FixedMul(yoffs,cosinecomponent) % modmaskh); - - temp = xoffs % modmaskw; - yoffs %= modmaskh; - xoffs = FixedMul(temp,cosinecomponent)+FixedMul(yoffs,-sinecomponent); // ditto - yoffs = -FixedMul(temp,-sinecomponent)+FixedMul(yoffs,cosinecomponent); - } - - xoffs -= (pl->slope->o.x - ox); - yoffs += (pl->slope->o.y + oy); + temp = xoffs % modmaskw; + yoffs %= modmaskh; + xoffs = FixedMul(temp,cosinecomponent)+FixedMul(yoffs,-sinecomponent); // ditto + yoffs = -FixedMul(temp,-sinecomponent)+FixedMul(yoffs,cosinecomponent); } void R_DrawSinglePlane(visplane_t *pl) @@ -1029,7 +1027,6 @@ void R_DrawSinglePlane(visplane_t *pl) xoffs = pl->xoffs; yoffs = pl->yoffs; - planeheight = abs(pl->height - pl->viewz); if (light >= LIGHTLEVELS) light = LIGHTLEVELS-1; @@ -1039,20 +1036,24 @@ void R_DrawSinglePlane(visplane_t *pl) if (pl->slope) { - if (ds_powersoftwo) - R_AdjustSlopeCoordinates(pl); - else - R_AdjustSlopeCoordinatesNPO2(pl); + if (xoffs || yoffs) + { + if (ds_powersoftwo) + R_AdjustSlopeCoordinates(pl); + else + R_AdjustSlopeCoordinatesNPO2(pl); + } if (planeripple.active) { - fixed_t plheight = abs(P_GetSlopeZAt(pl->slope, pl->viewx, pl->viewy) - pl->viewz); + planeheight = abs(P_GetSlopeZAt(pl->slope, pl->viewx, pl->viewy) - pl->viewz); R_PlaneBounds(pl); for (x = pl->high; x < pl->low; x++) { - R_CalculatePlaneRipple(pl, x, plheight, true); + ds_bgofs = R_CalculateRippleOffset(x); + R_CalculatePlaneRipple(pl->viewangle + pl->plangle); R_SetSlopePlaneVectors(pl, x, (xoffs + planeripple.xfrac), (yoffs + planeripple.yfrac)); } } @@ -1078,7 +1079,10 @@ void R_DrawSinglePlane(visplane_t *pl) planezlight = scalelight[light]; } else + { + planeheight = abs(pl->height - pl->viewz); planezlight = zlight[light]; + } // Use the correct span drawer depending on the powers-of-twoness if (!ds_powersoftwo) @@ -1099,18 +1103,15 @@ void R_DrawSinglePlane(visplane_t *pl) stop = pl->maxx + 1; - if (viewx != pl->viewx || viewy != pl->viewy) + if (pl->slope) { - viewx = pl->viewx; - viewy = pl->viewy; + for (x = pl->minx; x <= stop; x++) + R_MakeTiltedSpans(x, pl->top[x-1], pl->bottom[x-1], pl->top[x], pl->bottom[x]); } - if (viewz != pl->viewz) - viewz = pl->viewz; - - for (x = pl->minx; x <= stop; x++) + else { - R_MakeSpans(x, pl->top[x-1], pl->bottom[x-1], - pl->top[x], pl->bottom[x]); + for (x = pl->minx; x <= stop; x++) + R_MakeSpans(x, pl->top[x-1], pl->bottom[x-1], pl->top[x], pl->bottom[x]); } /* diff --git a/src/r_plane.h b/src/r_plane.h index 9b7e31e3e..bdad77930 100644 --- a/src/r_plane.h +++ b/src/r_plane.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -78,8 +78,6 @@ void R_InitPlanes(void); void R_ClearPlanes(void); void R_ClearFFloorClips (void); -void R_MapPlane(INT32 y, INT32 x1, INT32 x2); -void R_MakeSpans(INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2); void R_DrawPlanes(void); visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, fixed_t xoff, fixed_t yoff, angle_t plangle, extracolormap_t *planecolormap, ffloor_t *ffloor, polyobj_t *polyobj, pslope_t *slope); From 1c6296653a0e8010642e1acd0e749bb547de79c1 Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Tue, 27 Apr 2021 20:32:41 -0300 Subject: [PATCH 414/644] Use floating point GetSlopeZAt for the texture origin vector --- src/r_plane.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/r_plane.c b/src/r_plane.c index ee7b161da..355260a11 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -690,6 +690,18 @@ static void R_DrawSkyPlane(visplane_t *pl) } } +// Returns the height of the sloped plane at (px, py) as a floating point number +static float R_GetSlopeZAt(const pslope_t *slope, fixed_t px, fixed_t py) +{ + float x = FixedToFloat(px - slope->o.x); + float y = FixedToFloat(py - slope->o.y); + + x = (x * FixedToFloat(slope->d.x)); + y = (y * FixedToFloat(slope->d.y)); + + return FixedToFloat(slope->o.z) + ((x + y) * FixedToFloat(slope->zdelta)); +} + // Sets the texture origin vector of the sloped plane. static void R_SetSlopePlaneOrigin(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xoff, fixed_t yoff, fixed_t angle) { @@ -697,6 +709,7 @@ static void R_SetSlopePlaneOrigin(pslope_t *slope, fixed_t xpos, fixed_t ypos, f float vx = FixedToFloat(xpos + xoff); float vy = FixedToFloat(ypos - yoff); + float vz = FixedToFloat(zpos); float ang = ANG2RAD(ANGLE_270 - angle); // p is the texture origin in view space @@ -704,7 +717,7 @@ static void R_SetSlopePlaneOrigin(pslope_t *slope, fixed_t xpos, fixed_t ypos, f // errors if the flat is rotated. p->x = vx * cos(ang) - vy * sin(ang); p->z = vx * sin(ang) + vy * cos(ang); - p->y = FixedToFloat(P_GetSlopeZAt(slope, -xoff, yoff) - zpos); + p->y = R_GetSlopeZAt(slope, -xoff, yoff) - vz; } // This function calculates all of the vectors necessary for drawing a sloped plane. From 63761a2d07f7b336eb4f7a26778fffd04a38f810 Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Tue, 27 Apr 2021 20:42:59 -0300 Subject: [PATCH 415/644] Use floating point trig in R_SetSlopePlane --- src/r_plane.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/r_plane.c b/src/r_plane.c index 355260a11..3ea046595 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -742,10 +742,10 @@ void R_SetSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, n->x = sin(ang); n->z = -cos(ang); - plangle >>= ANGLETOFINESHIFT; - temp = P_GetSlopeZAt(slope, xpos + FINESINE(plangle), ypos + FINECOSINE(plangle)); + ang = ANG2RAD(plangle); + temp = P_GetSlopeZAt(slope, xpos + FloatToFixed(sin(ang)), ypos + FloatToFixed(cos(ang))); m->y = FixedToFloat(temp - height); - temp = P_GetSlopeZAt(slope, xpos + FINECOSINE(plangle), ypos - FINESINE(plangle)); + temp = P_GetSlopeZAt(slope, xpos + FloatToFixed(cos(ang)), ypos - FloatToFixed(sin(ang))); n->y = FixedToFloat(temp - height); } From 0fba870a3526eb4397f261fe77388095173b82f8 Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Tue, 27 Apr 2021 22:54:56 -0300 Subject: [PATCH 416/644] Revert "Use floating point trig in R_SetSlopePlane" This reverts commit 63761a2d07f7b336eb4f7a26778fffd04a38f810. --- src/r_plane.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/r_plane.c b/src/r_plane.c index 3ea046595..355260a11 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -742,10 +742,10 @@ void R_SetSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, n->x = sin(ang); n->z = -cos(ang); - ang = ANG2RAD(plangle); - temp = P_GetSlopeZAt(slope, xpos + FloatToFixed(sin(ang)), ypos + FloatToFixed(cos(ang))); + plangle >>= ANGLETOFINESHIFT; + temp = P_GetSlopeZAt(slope, xpos + FINESINE(plangle), ypos + FINECOSINE(plangle)); m->y = FixedToFloat(temp - height); - temp = P_GetSlopeZAt(slope, xpos + FloatToFixed(cos(ang)), ypos - FloatToFixed(sin(ang))); + temp = P_GetSlopeZAt(slope, xpos + FINECOSINE(plangle), ypos - FINESINE(plangle)); n->y = FixedToFloat(temp - height); } From 8f47a7e9cc98af4b1631e32e98ff4421f03c49d9 Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Tue, 27 Apr 2021 22:59:06 -0300 Subject: [PATCH 417/644] Prevent texture wobbling on planes with no flat alignment --- src/r_plane.c | 102 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 72 insertions(+), 30 deletions(-) diff --git a/src/r_plane.c b/src/r_plane.c index 355260a11..acbbc8a5c 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -690,16 +690,16 @@ static void R_DrawSkyPlane(visplane_t *pl) } } -// Returns the height of the sloped plane at (px, py) as a floating point number -static float R_GetSlopeZAt(const pslope_t *slope, fixed_t px, fixed_t py) +// Returns the height of the sloped plane at (x, y) as a 32.16 fixed_t +static INT64 R_GetSlopeZAt(const pslope_t *slope, fixed_t x, fixed_t y) { - float x = FixedToFloat(px - slope->o.x); - float y = FixedToFloat(py - slope->o.y); + x = ((INT64)x - (INT64)slope->o.x); + y = ((INT64)y - (INT64)slope->o.y); - x = (x * FixedToFloat(slope->d.x)); - y = (y * FixedToFloat(slope->d.y)); + x = (x * (INT64)slope->d.x) / FRACUNIT; + y = (y * (INT64)slope->d.y) / FRACUNIT; - return FixedToFloat(slope->o.z) + ((x + y) * FixedToFloat(slope->zdelta)); + return (INT64)slope->o.z + ((x + y) * (INT64)slope->zdelta) / FRACUNIT; } // Sets the texture origin vector of the sloped plane. @@ -709,7 +709,6 @@ static void R_SetSlopePlaneOrigin(pslope_t *slope, fixed_t xpos, fixed_t ypos, f float vx = FixedToFloat(xpos + xoff); float vy = FixedToFloat(ypos - yoff); - float vz = FixedToFloat(zpos); float ang = ANG2RAD(ANGLE_270 - angle); // p is the texture origin in view space @@ -717,7 +716,7 @@ static void R_SetSlopePlaneOrigin(pslope_t *slope, fixed_t xpos, fixed_t ypos, f // errors if the flat is rotated. p->x = vx * cos(ang) - vy * sin(ang); p->z = vx * sin(ang) + vy * cos(ang); - p->y = R_GetSlopeZAt(slope, -xoff, yoff) - vz; + p->y = (R_GetSlopeZAt(slope, -xoff, yoff) - zpos) / (float)FRACUNIT; } // This function calculates all of the vectors necessary for drawing a sloped plane. @@ -844,14 +843,37 @@ static inline void R_AdjustSlopeCoordinates(visplane_t *pl) const fixed_t cosinecomponent = FINECOSINE(pl->plangle>>ANGLETOFINESHIFT); const fixed_t sinecomponent = FINESINE(pl->plangle>>ANGLETOFINESHIFT); - fixed_t temp = xoffs; - xoffs = (FixedMul(temp,cosinecomponent) & modmask) + (FixedMul(yoffs,sinecomponent) & modmask); - yoffs = (-FixedMul(temp,sinecomponent) & modmask) + (FixedMul(yoffs,cosinecomponent) & modmask); + fixed_t ox, oy, temp; - temp = xoffs & modmask; - yoffs &= modmask; - xoffs = FixedMul(temp,cosinecomponent)+FixedMul(yoffs,-sinecomponent); // negative sine for opposite direction - yoffs = -FixedMul(temp,-sinecomponent)+FixedMul(yoffs,cosinecomponent); + if (!pl->plangle) + { + ox = (FixedMul(pl->slope->o.x,cosinecomponent) & modmask) - (FixedMul(pl->slope->o.y,sinecomponent) & modmask); + oy = (-FixedMul(pl->slope->o.x,sinecomponent) & modmask) - (FixedMul(pl->slope->o.y,cosinecomponent) & modmask); + + temp = ox & modmask; + oy &= modmask; + + ox = FixedMul(temp,cosinecomponent)+FixedMul(oy,-sinecomponent); // negative sine for opposite direction + oy = -FixedMul(temp,-sinecomponent)+FixedMul(oy,cosinecomponent); + } + + if (xoffs || yoffs) + { + temp = xoffs; + xoffs = (FixedMul(temp,cosinecomponent) & modmask) + (FixedMul(yoffs,sinecomponent) & modmask); + yoffs = (-FixedMul(temp,sinecomponent) & modmask) + (FixedMul(yoffs,cosinecomponent) & modmask); + + temp = xoffs & modmask; + yoffs &= modmask; + xoffs = FixedMul(temp,cosinecomponent)+FixedMul(yoffs,-sinecomponent); // ditto + yoffs = -FixedMul(temp,-sinecomponent)+FixedMul(yoffs,cosinecomponent); + } + + if (!pl->plangle) + { + xoffs -= (pl->slope->o.x - ox); + yoffs += (pl->slope->o.y + oy); + } } static inline void R_AdjustSlopeCoordinatesNPO2(visplane_t *pl) @@ -862,14 +884,37 @@ static inline void R_AdjustSlopeCoordinatesNPO2(visplane_t *pl) const fixed_t cosinecomponent = FINECOSINE(pl->plangle>>ANGLETOFINESHIFT); const fixed_t sinecomponent = FINESINE(pl->plangle>>ANGLETOFINESHIFT); - fixed_t temp = xoffs; - xoffs = (FixedMul(temp,cosinecomponent) % modmaskw) + (FixedMul(yoffs,sinecomponent) % modmaskh); - yoffs = (-FixedMul(temp,sinecomponent) % modmaskw) + (FixedMul(yoffs,cosinecomponent) % modmaskh); + fixed_t ox, oy, temp; - temp = xoffs % modmaskw; - yoffs %= modmaskh; - xoffs = FixedMul(temp,cosinecomponent)+FixedMul(yoffs,-sinecomponent); // ditto - yoffs = -FixedMul(temp,-sinecomponent)+FixedMul(yoffs,cosinecomponent); + if (!pl->plangle) + { + ox = (FixedMul(pl->slope->o.x,cosinecomponent) % modmaskw) - (FixedMul(pl->slope->o.y,sinecomponent) % modmaskh); + oy = (-FixedMul(pl->slope->o.x,sinecomponent) % modmaskw) - (FixedMul(pl->slope->o.y,cosinecomponent) % modmaskh); + + temp = ox % modmaskw; + oy %= modmaskh; + + ox = FixedMul(temp,cosinecomponent)+FixedMul(oy,-sinecomponent); // negative sine for opposite direction + oy = -FixedMul(temp,-sinecomponent)+FixedMul(oy,cosinecomponent); + } + + if (xoffs || yoffs) + { + temp = xoffs; + xoffs = (FixedMul(temp,cosinecomponent) % modmaskw) + (FixedMul(yoffs,sinecomponent) % modmaskh); + yoffs = (-FixedMul(temp,sinecomponent) % modmaskw) + (FixedMul(yoffs,cosinecomponent) % modmaskh); + + temp = xoffs % modmaskw; + yoffs %= modmaskh; + xoffs = FixedMul(temp,cosinecomponent)+FixedMul(yoffs,-sinecomponent); // ditto + yoffs = -FixedMul(temp,-sinecomponent)+FixedMul(yoffs,cosinecomponent); + } + + if (!pl->plangle) + { + xoffs -= (pl->slope->o.x - ox); + yoffs += (pl->slope->o.y + oy); + } } void R_DrawSinglePlane(visplane_t *pl) @@ -1049,13 +1094,10 @@ void R_DrawSinglePlane(visplane_t *pl) if (pl->slope) { - if (xoffs || yoffs) - { - if (ds_powersoftwo) - R_AdjustSlopeCoordinates(pl); - else - R_AdjustSlopeCoordinatesNPO2(pl); - } + if (ds_powersoftwo) + R_AdjustSlopeCoordinates(pl); + else + R_AdjustSlopeCoordinatesNPO2(pl); if (planeripple.active) { From 090f304f3368d96cb02c2ffb89701864d07c2191 Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Wed, 28 Apr 2021 22:00:20 -0300 Subject: [PATCH 418/644] Use 64-bit x/y in R_GetSlopeZAt --- src/r_plane.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/r_plane.c b/src/r_plane.c index acbbc8a5c..8db4801b5 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -693,13 +693,13 @@ static void R_DrawSkyPlane(visplane_t *pl) // Returns the height of the sloped plane at (x, y) as a 32.16 fixed_t static INT64 R_GetSlopeZAt(const pslope_t *slope, fixed_t x, fixed_t y) { - x = ((INT64)x - (INT64)slope->o.x); - y = ((INT64)y - (INT64)slope->o.y); + INT64 x64 = ((INT64)x - (INT64)slope->o.x); + INT64 y64 = ((INT64)y - (INT64)slope->o.y); - x = (x * (INT64)slope->d.x) / FRACUNIT; - y = (y * (INT64)slope->d.y) / FRACUNIT; + x64 = (x64 * (INT64)slope->d.x) / FRACUNIT; + y64 = (y64 * (INT64)slope->d.y) / FRACUNIT; - return (INT64)slope->o.z + ((x + y) * (INT64)slope->zdelta) / FRACUNIT; + return (INT64)slope->o.z + ((x64 + y64) * (INT64)slope->zdelta) / FRACUNIT; } // Sets the texture origin vector of the sloped plane. From 9d41325843d9c63c5e9862034e06863f7be0d65c Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Wed, 28 Apr 2021 22:15:05 -0300 Subject: [PATCH 419/644] Only adjust slope offsets if the plane isn't rotated --- src/r_plane.c | 98 +++++++++++---------------------------------------- 1 file changed, 21 insertions(+), 77 deletions(-) diff --git a/src/r_plane.c b/src/r_plane.c index 8db4801b5..c56a222df 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -829,92 +829,33 @@ static void R_SetSlopePlaneVectors(visplane_t *pl, INT32 y, fixed_t xoff, fixed_ R_CalculateSlopeVectors(); } -/* - Essentially: We can't & the components along the regular axes when the plane is rotated. - This is because the distance on each regular axis in order to loop is different. - We rotate them, & the components, add them together, & them again, and then rotate them back. - These three seperate & operations are done per axis in order to prevent overflows. - toast 10/04/17 -*/ -static inline void R_AdjustSlopeCoordinates(visplane_t *pl) +static inline void R_AdjustSlopeCoordinates(vector3_t *origin) { const fixed_t modmask = ((1 << (32-nflatshiftup)) - 1); - const fixed_t cosinecomponent = FINECOSINE(pl->plangle>>ANGLETOFINESHIFT); - const fixed_t sinecomponent = FINESINE(pl->plangle>>ANGLETOFINESHIFT); + fixed_t ox = (origin->x & modmask); + fixed_t oy = -(origin->y & modmask); - fixed_t ox, oy, temp; + xoffs &= modmask; + yoffs &= modmask; - if (!pl->plangle) - { - ox = (FixedMul(pl->slope->o.x,cosinecomponent) & modmask) - (FixedMul(pl->slope->o.y,sinecomponent) & modmask); - oy = (-FixedMul(pl->slope->o.x,sinecomponent) & modmask) - (FixedMul(pl->slope->o.y,cosinecomponent) & modmask); - - temp = ox & modmask; - oy &= modmask; - - ox = FixedMul(temp,cosinecomponent)+FixedMul(oy,-sinecomponent); // negative sine for opposite direction - oy = -FixedMul(temp,-sinecomponent)+FixedMul(oy,cosinecomponent); - } - - if (xoffs || yoffs) - { - temp = xoffs; - xoffs = (FixedMul(temp,cosinecomponent) & modmask) + (FixedMul(yoffs,sinecomponent) & modmask); - yoffs = (-FixedMul(temp,sinecomponent) & modmask) + (FixedMul(yoffs,cosinecomponent) & modmask); - - temp = xoffs & modmask; - yoffs &= modmask; - xoffs = FixedMul(temp,cosinecomponent)+FixedMul(yoffs,-sinecomponent); // ditto - yoffs = -FixedMul(temp,-sinecomponent)+FixedMul(yoffs,cosinecomponent); - } - - if (!pl->plangle) - { - xoffs -= (pl->slope->o.x - ox); - yoffs += (pl->slope->o.y + oy); - } + xoffs -= (origin->x - ox); + yoffs += (origin->y + oy); } -static inline void R_AdjustSlopeCoordinatesNPO2(visplane_t *pl) +static inline void R_AdjustSlopeCoordinatesNPO2(vector3_t *origin) { const fixed_t modmaskw = (ds_flatwidth << FRACBITS); const fixed_t modmaskh = (ds_flatheight << FRACBITS); - const fixed_t cosinecomponent = FINECOSINE(pl->plangle>>ANGLETOFINESHIFT); - const fixed_t sinecomponent = FINESINE(pl->plangle>>ANGLETOFINESHIFT); + fixed_t ox = (origin->x % modmaskw); + fixed_t oy = -(origin->y % modmaskh); - fixed_t ox, oy, temp; + xoffs %= modmaskw; + yoffs %= modmaskh; - if (!pl->plangle) - { - ox = (FixedMul(pl->slope->o.x,cosinecomponent) % modmaskw) - (FixedMul(pl->slope->o.y,sinecomponent) % modmaskh); - oy = (-FixedMul(pl->slope->o.x,sinecomponent) % modmaskw) - (FixedMul(pl->slope->o.y,cosinecomponent) % modmaskh); - - temp = ox % modmaskw; - oy %= modmaskh; - - ox = FixedMul(temp,cosinecomponent)+FixedMul(oy,-sinecomponent); // negative sine for opposite direction - oy = -FixedMul(temp,-sinecomponent)+FixedMul(oy,cosinecomponent); - } - - if (xoffs || yoffs) - { - temp = xoffs; - xoffs = (FixedMul(temp,cosinecomponent) % modmaskw) + (FixedMul(yoffs,sinecomponent) % modmaskh); - yoffs = (-FixedMul(temp,sinecomponent) % modmaskw) + (FixedMul(yoffs,cosinecomponent) % modmaskh); - - temp = xoffs % modmaskw; - yoffs %= modmaskh; - xoffs = FixedMul(temp,cosinecomponent)+FixedMul(yoffs,-sinecomponent); // ditto - yoffs = -FixedMul(temp,-sinecomponent)+FixedMul(yoffs,cosinecomponent); - } - - if (!pl->plangle) - { - xoffs -= (pl->slope->o.x - ox); - yoffs += (pl->slope->o.y + oy); - } + xoffs -= (origin->x - ox); + yoffs += (origin->y + oy); } void R_DrawSinglePlane(visplane_t *pl) @@ -1094,10 +1035,13 @@ void R_DrawSinglePlane(visplane_t *pl) if (pl->slope) { - if (ds_powersoftwo) - R_AdjustSlopeCoordinates(pl); - else - R_AdjustSlopeCoordinatesNPO2(pl); + if (!pl->plangle) + { + if (ds_powersoftwo) + R_AdjustSlopeCoordinates(&pl->slope->o); + else + R_AdjustSlopeCoordinatesNPO2(&pl->slope->o); + } if (planeripple.active) { From b4a09405a77d5bb5ec1c677a123f763ff2193ebb Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Thu, 29 Apr 2021 19:24:37 -0300 Subject: [PATCH 420/644] Use 64-bit math for calculating the texture origin X/Z --- src/r_plane.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/r_plane.c b/src/r_plane.c index c56a222df..d26c124ef 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -707,15 +707,18 @@ static void R_SetSlopePlaneOrigin(pslope_t *slope, fixed_t xpos, fixed_t ypos, f { floatv3_t *p = &ds_slope_origin; - float vx = FixedToFloat(xpos + xoff); - float vy = FixedToFloat(ypos - yoff); + INT64 vx = (INT64)xpos + (INT64)xoff; + INT64 vy = (INT64)ypos - (INT64)yoff; + + float vxf = vx / (float)FRACUNIT; + float vyf = vy / (float)FRACUNIT; float ang = ANG2RAD(ANGLE_270 - angle); // p is the texture origin in view space // Don't add in the offsets at this stage, because doing so can result in // errors if the flat is rotated. - p->x = vx * cos(ang) - vy * sin(ang); - p->z = vx * sin(ang) + vy * cos(ang); + p->x = vxf * cos(ang) - vyf * sin(ang); + p->z = vxf * sin(ang) + vyf * cos(ang); p->y = (R_GetSlopeZAt(slope, -xoff, yoff) - zpos) / (float)FRACUNIT; } From ea7b332525901bd4bd29eca368fe75ae31e413a4 Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+TatsuruIKR@users.noreply.github.com> Date: Fri, 30 Apr 2021 15:49:09 -0300 Subject: [PATCH 421/644] Visit srb2.org/addons to get & make addons! --- src/m_menu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/m_menu.c b/src/m_menu.c index 0fca39801..562779d39 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -6234,7 +6234,7 @@ static void M_AddonsOptions(INT32 choice) M_SetupNextMenu(&OP_AddonsOptionsDef); } -#define LOCATIONSTRING1 "Visit \x83SRB2.ORG/MODS\x80 to get & make add-ons!" +#define LOCATIONSTRING1 "Visit \x83SRB2.ORG/ADDONS\x80 to get & make addons!" //#define LOCATIONSTRING2 "Visit \x88SRB2.ORG/MODS\x80 to get & make add-ons!" static void M_LoadAddonsPatches(void) From 858cb98e57020be1cf822a114025d79f9d43c57c Mon Sep 17 00:00:00 2001 From: katsy Date: Fri, 30 Apr 2021 17:26:09 -0500 Subject: [PATCH 422/644] attempt to resolve teleportation resync issue --- src/d_clisrv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 7c2dec6a1..62817ea08 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -4268,7 +4268,7 @@ static void HandlePacketFromPlayer(SINT8 node) case PT_RECEIVEDGAMESTATE: sendingsavegame[node] = false; resendingsavegame[node] = false; - savegameresendcooldown[node] = I_GetTime() + 15 * TICRATE; + savegameresendcooldown[node] = I_GetTime() + TICRATE; break; // -------------------------------------------- CLIENT RECEIVE ---------- case PT_SERVERTICS: From bda0ffe94b4491628df2626d4831c98a475a6e1f Mon Sep 17 00:00:00 2001 From: SMS Alfredo <65426124+SMS-Alfredo@users.noreply.github.com> Date: Fri, 30 Apr 2021 18:20:55 -0500 Subject: [PATCH 423/644] You've been blocked --- src/lua_hook.h | 2 +- src/lua_hooklib.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++ src/p_mobj.c | 2 +- 3 files changed, 76 insertions(+), 2 deletions(-) diff --git a/src/lua_hook.h b/src/lua_hook.h index 0d631aa4e..8d80ec8c6 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -106,7 +106,7 @@ boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 #define LUAh_PlayerSpawn(player) LUAh_PlayerHook(player, hook_PlayerSpawn) // Hook for G_SpawnPlayer #define LUAh_ShieldSpawn(player) LUAh_PlayerHook(player, hook_ShieldSpawn) // Hook for P_SpawnShieldOrb #define LUAh_ShieldSpecial(player) LUAh_PlayerHook(player, hook_ShieldSpecial) // Hook for shield abilities -#define LUAh_MobjMoveBlocked(mo) LUAh_MobjHook(mo, hook_MobjMoveBlocked) // Hook for P_XYMovement (when movement is blocked) +boolean LUAh_MobjMoveBlocked(mobj_t *mo, mobj_t *thing, line_t *line); // Hook for P_XYMovement (when movement is blocked) boolean LUAh_MapThingSpawn(mobj_t *mo, mapthing_t *mthing); // Hook for P_SpawnMapThing by mobj type boolean LUAh_FollowMobj(player_t *player, mobj_t *mobj); // Hook for P_PlayerAfterThink Smiles mobj-following UINT8 LUAh_PlayerCanDamage(player_t *player, mobj_t *mobj); // Hook for P_PlayerCanDamage diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 1665e36b0..2b4eda525 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -1414,6 +1414,80 @@ void LUAh_NetArchiveHook(lua_CFunction archFunc) // stack: tables } +boolean LUAh_MobjMoveBlocked(mobj_t *mo, mobj_t *thing, line_t *line) +{ + hook_p hookp; + boolean hooked = false; + if (!gL || !(hooksAvailable[hook_MobjMoveBlocked/8] & (1<<(hook_MobjMoveBlocked%8)))) + return false; + + if (!(mobjhooks[MT_NULL] || mobjhooks[mo->type])) + return false; + + lua_settop(gL, 0); + lua_pushcfunction(gL, LUA_GetErrorMessage); + + // Look for all generic mobj move blocked hooks + for (hookp = mobjhooks[MT_NULL]; hookp; hookp = hookp->next) + { + if (hookp->type != hook_MobjMoveBlocked) + continue; + + ps_lua_mobjhooks++; + if (lua_gettop(gL) == 1) + { + LUA_PushUserdata(gL, mo, META_MOBJ); + LUA_PushUserdata(gL, thing, META_MOBJ); + LUA_PushUserdata(gL, line, META_LINE); + } + PushHook(gL, hookp); + lua_pushvalue(gL, -4); + lua_pushvalue(gL, -4); + lua_pushvalue(gL, -4); + if (lua_pcall(gL, 3, 1, 1)) { + if (!hookp->error || cv_debug & DBG_LUA) + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + hookp->error = true; + continue; + } + if (lua_toboolean(gL, -1)) + hooked = true; + lua_pop(gL, 1); + } + + for (hookp = mobjhooks[mo->type]; hookp; hookp = hookp->next) + { + if (hookp->type != hook_MobjMoveBlocked) + continue; + + ps_lua_mobjhooks++; + if (lua_gettop(gL) == 1) + { + LUA_PushUserdata(gL, mo, META_MOBJ); + LUA_PushUserdata(gL, thing, META_MOBJ); + LUA_PushUserdata(gL, line, META_LINE); + } + PushHook(gL, hookp); + lua_pushvalue(gL, -4); + lua_pushvalue(gL, -4); + lua_pushvalue(gL, -4); + if (lua_pcall(gL, 3, 1, 1)) { + if (!hookp->error || cv_debug & DBG_LUA) + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + hookp->error = true; + continue; + } + if (lua_toboolean(gL, -1)) + hooked = true; + lua_pop(gL, 1); + } + + lua_settop(gL, 0); + return hooked; +} + boolean LUAh_MapThingSpawn(mobj_t *mo, mapthing_t *mthing) { hook_p hookp; diff --git a/src/p_mobj.c b/src/p_mobj.c index 49db6daee..bac3cd2df 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1844,7 +1844,7 @@ void P_XYMovement(mobj_t *mo) B_MoveBlocked(player); } - if (LUAh_MobjMoveBlocked(mo)) + if (LUAh_MobjMoveBlocked(mo, tmhitthing, blockingline)) { if (P_MobjWasRemoved(mo)) return; From 815db014385b59664041927a97ca4c2322abe19c Mon Sep 17 00:00:00 2001 From: katsy Date: Fri, 30 Apr 2021 20:30:35 -0400 Subject: [PATCH 424/644] adjust cooldown to 5 seconds (bandage fix for 2.2.9) --- src/d_clisrv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 62817ea08..04c34e7bc 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -4268,7 +4268,7 @@ static void HandlePacketFromPlayer(SINT8 node) case PT_RECEIVEDGAMESTATE: sendingsavegame[node] = false; resendingsavegame[node] = false; - savegameresendcooldown[node] = I_GetTime() + TICRATE; + savegameresendcooldown[node] = I_GetTime() + 5 * TICRATE; break; // -------------------------------------------- CLIENT RECEIVE ---------- case PT_SERVERTICS: From 381ead4d7e378b557f135a39d582d6a11a8d8af7 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 30 Apr 2021 21:46:09 -0400 Subject: [PATCH 425/644] Level select no longer assumes that games will always be linear - If a level is in-between two with the same header, it would previously create two headers with the same name. Now it groups all levels with the same header together. - Previously, a header would only be visible if its first map was visible. Now it will show the header if you've visited any level under the header. For SUGOI. --- src/m_menu.c | 195 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 148 insertions(+), 47 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 0fca39801..5a5c98241 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -5166,34 +5166,75 @@ static boolean M_GametypeHasLevels(INT32 gt) static INT32 M_CountRowsToShowOnPlatter(INT32 gt) { - INT32 mapnum = 0, prevmapnum = 0, col = 0, rows = 0; + INT32 col = 0, rows = 0; + INT32 mapIterate = 0; + INT32 headingIterate = 0; + boolean mapAddedAlready[NUMMAPS]; - while (mapnum < NUMMAPS) + memset(mapAddedAlready, 0, sizeof mapAddedAlready); + + for (mapIterate = 0; mapIterate < NUMMAPS; mapIterate++) { - if (M_CanShowLevelOnPlatter(mapnum, gt)) + boolean forceNewRow = true; + + if (mapAddedAlready[mapIterate] == true) { - if (rows == 0) + // Already added under another heading + continue; + } + + if (M_CanShowLevelOnPlatter(mapIterate, gt) == false) + { + // Don't show this one + continue; + } + + for (headingIterate = mapIterate; headingIterate < NUMMAPS; headingIterate++) + { + boolean wide = false; + + if (mapAddedAlready[headingIterate] == true) + { + // Already added under another heading + continue; + } + + if (M_CanShowLevelOnPlatter(headingIterate, gt) == false) + { + // Don't show this one + continue; + } + + if (!fastcmp(mapheaderinfo[mapIterate]->selectheading, mapheaderinfo[headingIterate]->selectheading)) + { + // Headers don't match + continue; + } + + wide = (mapheaderinfo[headingIterate]->menuflags & LF2_WIDEICON); + + // preparing next position to drop mapnum into + if (col == 2 // no more space on the row? + || wide || forceNewRow) + { + col = 0; rows++; + } else { - if (col == 2 - || (mapheaderinfo[prevmapnum]->menuflags & LF2_WIDEICON) - || (mapheaderinfo[mapnum]->menuflags & LF2_WIDEICON) - || !(fastcmp(mapheaderinfo[mapnum]->selectheading, mapheaderinfo[prevmapnum]->selectheading))) - { - col = 0; - rows++; - } - else - col++; + col++; } - prevmapnum = mapnum; + + // Done adding this one + mapAddedAlready[headingIterate] = true; + forceNewRow = wide; } - mapnum++; } if (levellistmode == LLM_CREATESERVER) + { rows++; + } return rows; } @@ -5223,7 +5264,10 @@ static void M_CacheLevelPlatter(void) static boolean M_PrepareLevelPlatter(INT32 gt, boolean nextmappick) { INT32 numrows = M_CountRowsToShowOnPlatter(gt); - INT32 mapnum = 0, prevmapnum = 0, col = 0, row = 0, startrow = 0; + INT32 col = 0, row = 0, startrow = 0; + INT32 mapIterate = 0; // First level of map loop -- find starting points for select headings + INT32 headingIterate = 0; // Second level of map loop -- finding maps that match mapIterate's heading. + boolean mapAddedAlready[NUMMAPS]; if (!numrows) return false; @@ -5240,6 +5284,8 @@ static boolean M_PrepareLevelPlatter(INT32 gt, boolean nextmappick) // done here so lsrow and lscol can be set if cv_nextmap is on the platter lsrow = lscol = lshli = lsoffs[0] = lsoffs[1] = 0; + memset(mapAddedAlready, 0, sizeof mapAddedAlready); + if (levellistmode == LLM_CREATESERVER) { sprintf(levelselect.rows[0].header, "Gametype"); @@ -5251,31 +5297,75 @@ static boolean M_PrepareLevelPlatter(INT32 gt, boolean nextmappick) char_notes = NULL; } - while (mapnum < NUMMAPS) + for (mapIterate = 0; mapIterate < NUMMAPS; mapIterate++) { - if (M_CanShowLevelOnPlatter(mapnum, gt)) + INT32 headerRow = -1; + boolean anyAvailable = false; + boolean forceNewRow = true; + + if (mapAddedAlready[mapIterate] == true) { - const UINT8 actnum = mapheaderinfo[mapnum]->actnum; - const boolean headingisname = (fastcmp(mapheaderinfo[mapnum]->selectheading, mapheaderinfo[mapnum]->lvlttl)); - const boolean wide = (mapheaderinfo[mapnum]->menuflags & LF2_WIDEICON); + // Already added under another heading + continue; + } + + if (M_CanShowLevelOnPlatter(mapIterate, gt) == false) + { + // Don't show this one + continue; + } + + for (headingIterate = mapIterate; headingIterate < NUMMAPS; headingIterate++) + { + UINT8 actnum = 0; + boolean headingisname = false; + boolean wide = false; + + if (mapAddedAlready[headingIterate] == true) + { + // Already added under another heading + continue; + } + + if (M_CanShowLevelOnPlatter(headingIterate, gt) == false) + { + // Don't show this one + continue; + } + + if (!fastcmp(mapheaderinfo[mapIterate]->selectheading, mapheaderinfo[headingIterate]->selectheading)) + { + // Headers don't match + continue; + } + + actnum = mapheaderinfo[headingIterate]->actnum; + headingisname = (fastcmp(mapheaderinfo[headingIterate]->selectheading, mapheaderinfo[headingIterate]->lvlttl)); + wide = (mapheaderinfo[headingIterate]->menuflags & LF2_WIDEICON); // preparing next position to drop mapnum into if (levelselect.rows[startrow].maplist[0]) { if (col == 2 // no more space on the row? - || wide - || (mapheaderinfo[prevmapnum]->menuflags & LF2_WIDEICON) - || !(fastcmp(mapheaderinfo[mapnum]->selectheading, mapheaderinfo[prevmapnum]->selectheading))) // a new heading is starting? + || wide || forceNewRow) { col = 0; row++; } else + { col++; + } } - levelselect.rows[row].maplist[col] = mapnum+1; // putting the map on the platter - levelselect.rows[row].mapavailable[col] = M_LevelAvailableOnPlatter(mapnum); + if (headerRow == -1) + { + // Set where the header row is meant to be + headerRow = row; + } + + levelselect.rows[row].maplist[col] = headingIterate+1; // putting the map on the platter + levelselect.rows[row].mapavailable[col] = M_LevelAvailableOnPlatter(headingIterate); if ((lswide(row) = wide)) // intentionally assignment { @@ -5283,7 +5373,7 @@ static boolean M_PrepareLevelPlatter(INT32 gt, boolean nextmappick) levelselect.rows[row].mapavailable[2] = levelselect.rows[row].mapavailable[1] = levelselect.rows[row].mapavailable[0]; } - if (nextmappick && cv_nextmap.value == mapnum+1) // A little quality of life improvement. + if (nextmappick && cv_nextmap.value == headingIterate+1) // A little quality of life improvement. { lsrow = row; lscol = col; @@ -5292,6 +5382,8 @@ static boolean M_PrepareLevelPlatter(INT32 gt, boolean nextmappick) // individual map name if (levelselect.rows[row].mapavailable[col]) { + anyAvailable = true; + if (headingisname) { if (actnum) @@ -5302,7 +5394,7 @@ static boolean M_PrepareLevelPlatter(INT32 gt, boolean nextmappick) else if (wide) { // Yes, with LF2_WIDEICON it'll continue on over into the next 17+1 char block. That's alright; col is always zero, the string is contiguous, and the maximum length is lvlttl[22] + ' ' + ZONE + ' ' + INT32, which is about 39 or so - barely crossing into the third column. - char* mapname = G_BuildMapTitle(mapnum+1); + char* mapname = G_BuildMapTitle(headingIterate+1); strcpy(levelselect.rows[row].mapnames[col], (const char *)mapname); Z_Free(mapname); } @@ -5311,9 +5403,9 @@ static boolean M_PrepareLevelPlatter(INT32 gt, boolean nextmappick) char mapname[22+1+11]; // lvlttl[22] + ' ' + INT32 if (actnum) - sprintf(mapname, "%s %d", mapheaderinfo[mapnum]->lvlttl, actnum); + sprintf(mapname, "%s %d", mapheaderinfo[headingIterate]->lvlttl, actnum); else - strcpy(mapname, mapheaderinfo[mapnum]->lvlttl); + strcpy(mapname, mapheaderinfo[headingIterate]->lvlttl); if (strlen(mapname) >= 17) strcpy(mapname+17-3, "..."); @@ -5322,27 +5414,36 @@ static boolean M_PrepareLevelPlatter(INT32 gt, boolean nextmappick) } } else - sprintf(levelselect.rows[row].mapnames[col], "???"); - - // creating header text - if (!col && ((row == startrow) || !(fastcmp(mapheaderinfo[mapnum]->selectheading, mapheaderinfo[levelselect.rows[row-1].maplist[0]-1]->selectheading)))) { - if (!levelselect.rows[row].mapavailable[col]) - sprintf(levelselect.rows[row].header, "???"); - else - { - sprintf(levelselect.rows[row].header, "%s", mapheaderinfo[mapnum]->selectheading); - if (!(mapheaderinfo[mapnum]->levelflags & LF_NOZONE) && headingisname) - { - sprintf(levelselect.rows[row].header + strlen(levelselect.rows[row].header), " ZONE"); - } - } + sprintf(levelselect.rows[row].mapnames[col], "???"); } - prevmapnum = mapnum; + // Done adding this one + mapAddedAlready[headingIterate] = true; + forceNewRow = wide; } - mapnum++; + if (headerRow == -1) + { + // Shouldn't happen + continue; + } + + // creating header text + if (anyAvailable == false) + { + sprintf(levelselect.rows[headerRow].header, "???"); + } + else + { + sprintf(levelselect.rows[headerRow].header, "%s", mapheaderinfo[mapIterate]->selectheading); + + if (!(mapheaderinfo[mapIterate]->levelflags & LF_NOZONE) + && fastcmp(mapheaderinfo[mapIterate]->selectheading, mapheaderinfo[mapIterate]->lvlttl)) + { + sprintf(levelselect.rows[headerRow].header + strlen(levelselect.rows[headerRow].header), " ZONE"); + } + } } #ifdef SYMMETRICAL_PLATTER From aac3ca320bc1f235e36babdae27b0ba2eb23571c Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+TatsuruIKR@users.noreply.github.com> Date: Sat, 1 May 2021 10:24:28 -0300 Subject: [PATCH 426/644] Update LOCATIONSTRING2 as well --- src/m_menu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/m_menu.c b/src/m_menu.c index 562779d39..13531f1b8 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -6235,7 +6235,7 @@ static void M_AddonsOptions(INT32 choice) } #define LOCATIONSTRING1 "Visit \x83SRB2.ORG/ADDONS\x80 to get & make addons!" -//#define LOCATIONSTRING2 "Visit \x88SRB2.ORG/MODS\x80 to get & make add-ons!" +//#define LOCATIONSTRING2 "Visit \x88SRB2.ORG/ADDONS\x80 to get & make addons!" static void M_LoadAddonsPatches(void) { From ab84bd5370a390fdf048027624c1c2d40a8b2c88 Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Sun, 2 May 2021 00:03:35 -0500 Subject: [PATCH 427/644] Fix the console splitting up halfway through startup. --- src/v_video.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/v_video.c b/src/v_video.c index 4713db0d8..2e7d7e4ea 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -455,7 +455,8 @@ void VID_BlitLinearScreen_ASM(const UINT8 *srcptr, UINT8 *destptr, INT32 width, static void CV_constextsize_OnChange(void) { - con_recalc = true; + if (!con_refresh) + con_recalc = true; } From ed5a7f51e877ce1c125fdcda6412661f7a521ba5 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 2 May 2021 21:32:07 -0700 Subject: [PATCH 428/644] Revert "Merge branch 'lightmemedata' into 'next'" This reverts commit d4c08a84101d6d5cd75e550bacda5d9929413b72, reversing changes made to e100f21ddaa46c8b82393baaa32cf84d222af616. --- src/lua_baselib.c | 12 +++--------- src/lua_consolelib.c | 18 ++++++++++++++++-- src/lua_script.c | 21 --------------------- src/lua_script.h | 1 - 4 files changed, 19 insertions(+), 33 deletions(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index a59ba546e..a265465da 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -242,16 +242,10 @@ static const char *GetUserdataUType(lua_State *L) // or players[0].powers -> "player_t.powers" static int lib_userdataType(lua_State *L) { - int type; lua_settop(L, 1); // pop everything except arg 1 (in case somebody decided to add more) - type = lua_type(L, 1); - if (type == LUA_TLIGHTUSERDATA || type == LUA_TUSERDATA) - { - lua_pushstring(L, GetUserdataUType(L)); - return 1; - } - else - return luaL_typerror(L, 1, "userdata"); + luaL_checktype(L, 1, LUA_TUSERDATA); + lua_pushstring(L, GetUserdataUType(L)); + return 1; } // Takes a metatable as first and only argument diff --git a/src/lua_consolelib.c b/src/lua_consolelib.c index 5344fee76..10959324e 100644 --- a/src/lua_consolelib.c +++ b/src/lua_consolelib.c @@ -440,8 +440,22 @@ static int lib_cvRegisterVar(lua_State *L) static int lib_cvFindVar(lua_State *L) { - LUA_PushLightUserdata(L, CV_FindVar(luaL_checkstring(L,1)), META_CVAR); - return 1; + consvar_t *cv; + if (( cv = CV_FindVar(luaL_checkstring(L,1)) )) + { + lua_settop(L,1);/* We only want one argument in the stack. */ + lua_pushlightuserdata(L, cv);/* Now the second value on stack. */ + luaL_getmetatable(L, META_CVAR); + /* + The metatable is the last value on the stack, so this + applies it to the second value, which is the cvar. + */ + lua_setmetatable(L,2); + lua_pushvalue(L,2); + return 1; + } + else + return 0; } static int CVarSetFunction diff --git a/src/lua_script.c b/src/lua_script.c index 7fd5a98e6..9f8432832 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -714,27 +714,6 @@ fixed_t LUA_EvalMath(const char *word) return res; } -/* -LUA_PushUserdata but no userdata is created. -You can't invalidate it therefore. -*/ - -void LUA_PushLightUserdata (lua_State *L, void *data, const char *meta) -{ - if (data) - { - lua_pushlightuserdata(L, data); - luaL_getmetatable(L, meta); - /* - The metatable is the last value on the stack, so this - applies it to the second value, which is the userdata. - */ - lua_setmetatable(L, -2); - } - else - lua_pushnil(L); -} - // Takes a pointer, any pointer, and a metatable name // Creates a userdata for that pointer with the given metatable // Pushes it to the stack and stores it in the registry. diff --git a/src/lua_script.h b/src/lua_script.h index 77fbb7c1d..9311a727a 100644 --- a/src/lua_script.h +++ b/src/lua_script.h @@ -87,7 +87,6 @@ typedef enum { LPUSHED_EXISTING, } lpushed_t; -void LUA_PushLightUserdata(lua_State *L, void *data, const char *meta); void LUA_PushUserdata(lua_State *L, void *data, const char *meta); lpushed_t LUA_RawPushUserdata(lua_State *L, void *data); From aee963f4e96191c14f7506cc5a7c7e06e7734fa0 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 2 May 2021 21:59:23 -0700 Subject: [PATCH 429/644] Replace LUA_PushLightUserdata with LUA_PushUserdata See 7df6a309 and 83a87042. I didn't realize that light userdata's metatable is shared--like numbers or strings. So it cannot be paired with a metatable. I also made a few minor tweaks to Lua cvars, other than accounting for the double pointer in the userdata. --- src/command.c | 2 +- src/lua_consolelib.c | 68 +++++++++++--------------------------------- src/lua_script.h | 2 +- src/lua_skinlib.c | 8 +++--- 4 files changed, 23 insertions(+), 57 deletions(-) diff --git a/src/command.c b/src/command.c index 951e3dd09..d73cde5c2 100644 --- a/src/command.c +++ b/src/command.c @@ -1577,7 +1577,7 @@ finish: } var->flags |= CV_MODIFIED; // raise 'on change' code - LUA_CVarChanged(var->name); // let consolelib know what cvar this is. + LUA_CVarChanged(var); // let consolelib know what cvar this is. if (var->flags & CV_CALL && !stealth) var->func(); diff --git a/src/lua_consolelib.c b/src/lua_consolelib.c index 10959324e..a8ef6b7c0 100644 --- a/src/lua_consolelib.c +++ b/src/lua_consolelib.c @@ -28,7 +28,7 @@ return luaL_error(L, "HUD rendering code should not call this function!"); #define NOHOOK if (!lua_lumploading)\ return luaL_error(L, "This function cannot be called from within a hook or coroutine!"); -static const char *cvname = NULL; +static consvar_t *this_cvar; void Got_Luacmd(UINT8 **cp, INT32 playernum) { @@ -273,16 +273,13 @@ static int lib_comBufInsertText(lua_State *L) return 0; } -void LUA_CVarChanged(const char *name) +void LUA_CVarChanged(void *cvar) { - cvname = name; + this_cvar = cvar; } static void Lua_OnChange(void) { - I_Assert(gL != NULL); - I_Assert(cvname != NULL); - /// \todo Network this! XD_LUAVAR lua_pushcfunction(gL, LUA_GetErrorMessage); @@ -291,13 +288,10 @@ static void Lua_OnChange(void) // From CV_OnChange registry field, get the function for this cvar by name. lua_getfield(gL, LUA_REGISTRYINDEX, "CV_OnChange"); I_Assert(lua_istable(gL, -1)); - lua_getfield(gL, -1, cvname); // get function + lua_pushlightuserdata(gL, this_cvar); + lua_rawget(gL, -2); // get function - // From the CV_Vars registry field, get the cvar's userdata by name. - lua_getfield(gL, LUA_REGISTRYINDEX, "CV_Vars"); - I_Assert(lua_istable(gL, -1)); - lua_getfield(gL, -1, cvname); // get consvar_t* userdata. - lua_remove(gL, -2); // pop the CV_Vars table. + LUA_RawPushUserdata(gL, this_cvar); LUA_Call(gL, 1, 0, 1); // call function(cvar) lua_pop(gL, 1); // pop CV_OnChange table @@ -312,15 +306,12 @@ static int lib_cvRegisterVar(lua_State *L) luaL_checktype(L, 1, LUA_TTABLE); lua_settop(L, 1); // Clear out all other possible arguments, leaving only the first one. NOHOOK - cvar = lua_newuserdata(L, sizeof(consvar_t)); - luaL_getmetatable(L, META_CVAR); - lua_setmetatable(L, -2); + cvar = ZZ_Calloc(sizeof(consvar_t)); + LUA_PushUserdata(L, cvar, META_CVAR); #define FIELDERROR(f, e) luaL_error(L, "bad value for " LUA_QL(f) " in table passed to " LUA_QL("CV_RegisterVar") " (%s)", e); #define TYPEERROR(f, t) FIELDERROR(f, va("%s expected, got %s", lua_typename(L, t), luaL_typename(L, -1))) - memset(cvar, 0x00, sizeof(consvar_t)); // zero everything by default - lua_pushnil(L); while (lua_next(L, 1)) { // stack: cvar table, cvar userdata, key/index, value @@ -369,7 +360,7 @@ static int lib_cvRegisterVar(lua_State *L) lua_getfield(L, LUA_REGISTRYINDEX, "CV_PossibleValue"); I_Assert(lua_istable(L, 5)); - lua_pushvalue(L, 2); // cvar userdata + lua_pushlightuserdata(L, cvar); cvpv = lua_newuserdata(L, sizeof(CV_PossibleValue_t) * (count+1)); lua_rawset(L, 5); lua_pop(L, 1); // pop CV_PossibleValue registry table @@ -397,8 +388,9 @@ static int lib_cvRegisterVar(lua_State *L) TYPEERROR("func", LUA_TFUNCTION) lua_getfield(L, LUA_REGISTRYINDEX, "CV_OnChange"); I_Assert(lua_istable(L, 5)); + lua_pushlightuserdata(L, cvar); lua_pushvalue(L, 4); - lua_setfield(L, 5, cvar->name); + lua_rawset(L, 5); lua_pop(L, 1); cvar->func = Lua_OnChange; } @@ -415,19 +407,6 @@ static int lib_cvRegisterVar(lua_State *L) if ((cvar->flags & CV_CALL) && !cvar->func) return luaL_error(L, M_GetText("Variable %s has CV_CALL without a function\n"), cvar->name); - // stack: cvar table, cvar userdata - lua_getfield(L, LUA_REGISTRYINDEX, "CV_Vars"); - I_Assert(lua_istable(L, 3)); - - lua_getfield(L, 3, cvar->name); - if (lua_type(L, -1) != LUA_TNIL) - return luaL_error(L, M_GetText("Variable %s is already defined\n"), cvar->name); - lua_pop(L, 1); - - lua_pushvalue(L, 2); - lua_setfield(L, 3, cvar->name); - lua_pop(L, 1); - // actually time to register it to the console now! Finally! cvar->flags |= CV_MODIFIED; CV_RegisterVar(cvar); @@ -440,22 +419,9 @@ static int lib_cvRegisterVar(lua_State *L) static int lib_cvFindVar(lua_State *L) { - consvar_t *cv; - if (( cv = CV_FindVar(luaL_checkstring(L,1)) )) - { - lua_settop(L,1);/* We only want one argument in the stack. */ - lua_pushlightuserdata(L, cv);/* Now the second value on stack. */ - luaL_getmetatable(L, META_CVAR); - /* - The metatable is the last value on the stack, so this - applies it to the second value, which is the cvar. - */ - lua_setmetatable(L,2); - lua_pushvalue(L,2); - return 1; - } - else - return 0; + const char *name = luaL_checkstring(L, 1); + LUA_PushUserdata(L, CV_FindVar(name), META_CVAR); + return 1; } static int CVarSetFunction @@ -464,7 +430,7 @@ static int CVarSetFunction void (*Set)(consvar_t *, const char *), void (*SetValue)(consvar_t *, INT32) ){ - consvar_t *cvar = (consvar_t *)luaL_checkudata(L, 1, META_CVAR); + consvar_t *cvar = *(consvar_t **)luaL_checkudata(L, 1, META_CVAR); if (cvar->flags & CV_NOLUA) return luaL_error(L, "Variable %s cannot be set from Lua.", cvar->name); @@ -496,7 +462,7 @@ static int lib_cvStealthSet(lua_State *L) static int lib_cvAddValue(lua_State *L) { - consvar_t *cvar = (consvar_t *)luaL_checkudata(L, 1, META_CVAR); + consvar_t *cvar = *(consvar_t **)luaL_checkudata(L, 1, META_CVAR); if (cvar->flags & CV_NOLUA) return luaL_error(L, "Variable %s cannot be set from Lua.", cvar->name); @@ -555,7 +521,7 @@ static luaL_Reg lib[] = { static int cvar_get(lua_State *L) { - consvar_t *cvar = (consvar_t *)luaL_checkudata(L, 1, META_CVAR); + consvar_t *cvar = *(consvar_t **)luaL_checkudata(L, 1, META_CVAR); const char *field = luaL_checkstring(L, 2); if(fastcmp(field,"name")) diff --git a/src/lua_script.h b/src/lua_script.h index 9311a727a..89ba7b6ee 100644 --- a/src/lua_script.h +++ b/src/lua_script.h @@ -56,7 +56,7 @@ void LUA_UnArchive(void); int LUA_PushGlobals(lua_State *L, const char *word); int LUA_CheckGlobals(lua_State *L, const char *word); void Got_Luacmd(UINT8 **cp, INT32 playernum); // lua_consolelib.c -void LUA_CVarChanged(const char *name); // lua_consolelib.c +void LUA_CVarChanged(void *cvar); // lua_consolelib.c int Lua_optoption(lua_State *L, int narg, const char *def, const char *const lst[]); void LUAh_NetArchiveHook(lua_CFunction archFunc); diff --git a/src/lua_skinlib.c b/src/lua_skinlib.c index 56be6bf4f..7e7480be3 100644 --- a/src/lua_skinlib.c +++ b/src/lua_skinlib.c @@ -213,7 +213,7 @@ static int skin_get(lua_State *L) lua_pushinteger(L, skin->availability); break; case skin_sprites: - LUA_PushLightUserdata(L, skin->sprites, META_SKINSPRITES); + LUA_PushUserdata(L, skin->sprites, META_SKINSPRITES); break; } return 1; @@ -336,13 +336,13 @@ static const char *const sprites_opt[] = { // skin.sprites[i] -> sprites[i] static int lib_getSkinSprite(lua_State *L) { - spritedef_t *sprites = (spritedef_t *)luaL_checkudata(L, 1, META_SKINSPRITES); + spritedef_t *sprites = *(spritedef_t **)luaL_checkudata(L, 1, META_SKINSPRITES); playersprite_t i = luaL_checkinteger(L, 2); if (i < 0 || i >= NUMPLAYERSPRITES*2) return luaL_error(L, LUA_QL("skin_t") " field 'sprites' index %d out of range (0 - %d)", i, (NUMPLAYERSPRITES*2)-1); - LUA_PushLightUserdata(L, &sprites[i], META_SKINSPRITESLIST); + LUA_PushUserdata(L, &sprites[i], META_SKINSPRITESLIST); return 1; } @@ -355,7 +355,7 @@ static int lib_numSkinsSprites(lua_State *L) static int sprite_get(lua_State *L) { - spritedef_t *sprite = (spritedef_t *)luaL_checkudata(L, 1, META_SKINSPRITESLIST); + spritedef_t *sprite = *(spritedef_t **)luaL_checkudata(L, 1, META_SKINSPRITESLIST); enum spritesopt field = luaL_checkoption(L, 2, NULL, sprites_opt); switch (field) From 80fe39bbd1433c91131d2cdb36ba709f37d3b5f3 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Mon, 3 May 2021 01:40:02 -0400 Subject: [PATCH 430/644] Fix MusicChange hook not returning some values correctly --- src/lua_hooklib.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 1665e36b0..a3f4a95d2 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -1959,13 +1959,13 @@ boolean LUAh_MusicChange(const char *oldname, char *newname, UINT16 *mflags, boo if (lua_isboolean(gL, -4)) *looping = lua_toboolean(gL, -4); // output 4: position override - if (lua_isboolean(gL, -3)) + if (lua_isnumber(gL, -3)) *position = lua_tonumber(gL, -3); // output 5: prefadems override - if (lua_isboolean(gL, -2)) + if (lua_isnumber(gL, -2)) *prefadems = lua_tonumber(gL, -2); // output 6: fadeinms override - if (lua_isboolean(gL, -1)) + if (lua_isnumber(gL, -1)) *fadeinms = lua_tonumber(gL, -1); lua_pop(gL, 7); // Pop returned values and error handler From 44d217807f71d15bd7ca69dad226458e7060ccab Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 1 May 2021 19:07:44 -0700 Subject: [PATCH 431/644] Collect makefiles --- src/{blua/Makefile.cfg => Makefile.d/lua.mk} | 0 src/{sdl/MakeNIX.cfg => Makefile.d/nix.mk} | 0 src/{sdl/Makefile.cfg => Makefile.d/sdl.mk} | 0 src/{Makefile.cfg => Makefile.d/versions.mk} | 0 src/{win32/Makefile.cfg => Makefile.d/win32.mk} | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename src/{blua/Makefile.cfg => Makefile.d/lua.mk} (100%) rename src/{sdl/MakeNIX.cfg => Makefile.d/nix.mk} (100%) rename src/{sdl/Makefile.cfg => Makefile.d/sdl.mk} (100%) rename src/{Makefile.cfg => Makefile.d/versions.mk} (100%) rename src/{win32/Makefile.cfg => Makefile.d/win32.mk} (100%) diff --git a/src/blua/Makefile.cfg b/src/Makefile.d/lua.mk similarity index 100% rename from src/blua/Makefile.cfg rename to src/Makefile.d/lua.mk diff --git a/src/sdl/MakeNIX.cfg b/src/Makefile.d/nix.mk similarity index 100% rename from src/sdl/MakeNIX.cfg rename to src/Makefile.d/nix.mk diff --git a/src/sdl/Makefile.cfg b/src/Makefile.d/sdl.mk similarity index 100% rename from src/sdl/Makefile.cfg rename to src/Makefile.d/sdl.mk diff --git a/src/Makefile.cfg b/src/Makefile.d/versions.mk similarity index 100% rename from src/Makefile.cfg rename to src/Makefile.d/versions.mk diff --git a/src/win32/Makefile.cfg b/src/Makefile.d/win32.mk similarity index 100% rename from src/win32/Makefile.cfg rename to src/Makefile.d/win32.mk From f637e28d0c1877c44acd7b01f7130625d5ea4099 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 4 May 2021 04:14:00 -0700 Subject: [PATCH 432/644] Remove bin, objs and dep directories --- bin/FreeBSD/Debug/.gitignore | 2 -- bin/FreeBSD/Release/.gitignore | 2 -- bin/Linux/Debug/.gitignore | 1 - bin/Linux/Release/.gitignore | 3 --- bin/Linux64/Debug/.gitignore | 1 - bin/Linux64/Release/.gitignore | 1 - bin/Mingw/Debug/.gitignore | 3 --- bin/Mingw/Release/.gitignore | 4 ---- bin/Mingw64/Debug/.gitignore | 3 --- bin/Mingw64/Release/.gitignore | 3 --- bin/SDL/Debug/.gitignore | 2 -- bin/SDL/Release/.gitignore | 2 -- bin/VC/.gitignore | 2 -- bin/VC9/.gitignore | 2 -- bin/dummy/.gitignore | 2 -- dep/.gitignore | 2 -- dep/FreeBSD/SDL/Debug/.gitignore | 2 -- dep/FreeBSD/SDL/Release/.gitignore | 2 -- dep/Linux/SDL/Debug/.gitignore | 2 -- dep/Linux/SDL/Release/.gitignore | 2 -- dep/Linux64/SDL/Debug/.gitignore | 2 -- dep/Linux64/SDL/Release/.gitignore | 2 -- dep/MasterClient/.gitignore | 2 -- dep/MasterServer/.gitignore | 2 -- dep/Mingw/Debug/.gitignore | 2 -- dep/Mingw/Release/.gitignore | 2 -- dep/Mingw/SDL/Debug/.gitignore | 2 -- dep/Mingw/SDL/Release/.gitignore | 2 -- dep/Mingw64/Debug/.gitignore | 2 -- dep/Mingw64/Release/.gitignore | 2 -- dep/Mingw64/SDL/Debug/.gitignore | 2 -- dep/Mingw64/SDL/Release/.gitignore | 2 -- dep/SDL/Release/.gitignore | 2 -- dep/VC/.gitignore | 2 -- dep/VC9/.gitignore | 2 -- dep/cygwin/Debug/.gitignore | 2 -- dep/cygwin/Release/.gitignore | 2 -- dep/dummy/.gitignore | 2 -- objs/.gitignore | 8 -------- objs/FreeBSD/SDL/Debug/.gitignore | 2 -- objs/FreeBSD/SDL/Release/.gitignore | 2 -- objs/Linux/SDL/Debug/.gitignore | 2 -- objs/Linux/SDL/Release/.gitignore | 2 -- objs/Linux64/SDL/Debug/.gitignore | 2 -- objs/Linux64/SDL/Release/.gitignore | 2 -- objs/MasterClient/.gitignore | 2 -- objs/MasterServer/.gitignore | 2 -- objs/Mingw/Debug/.gitignore | 2 -- objs/Mingw/Release/.gitignore | 2 -- objs/Mingw/SDL/Debug/.gitignore | 2 -- objs/Mingw/SDL/Release/.gitignore | 2 -- objs/Mingw64/Debug/.gitignore | 2 -- objs/Mingw64/Release/.gitignore | 2 -- objs/Mingw64/SDL/Debug/.gitignore | 2 -- objs/Mingw64/SDL/Release/.gitignore | 2 -- objs/SDL/Release/.gitignore | 2 -- objs/VC/.gitignore | 2 -- objs/VC9/.gitignore | 2 -- objs/cygwin/Debug/.gitignore | 2 -- objs/cygwin/Release/.gitignore | 2 -- objs/dummy/.gitignore | 2 -- 61 files changed, 131 deletions(-) delete mode 100644 bin/FreeBSD/Debug/.gitignore delete mode 100644 bin/FreeBSD/Release/.gitignore delete mode 100644 bin/Linux/Debug/.gitignore delete mode 100644 bin/Linux/Release/.gitignore delete mode 100644 bin/Linux64/Debug/.gitignore delete mode 100644 bin/Linux64/Release/.gitignore delete mode 100644 bin/Mingw/Debug/.gitignore delete mode 100644 bin/Mingw/Release/.gitignore delete mode 100644 bin/Mingw64/Debug/.gitignore delete mode 100644 bin/Mingw64/Release/.gitignore delete mode 100644 bin/SDL/Debug/.gitignore delete mode 100644 bin/SDL/Release/.gitignore delete mode 100644 bin/VC/.gitignore delete mode 100644 bin/VC9/.gitignore delete mode 100644 bin/dummy/.gitignore delete mode 100644 dep/.gitignore delete mode 100644 dep/FreeBSD/SDL/Debug/.gitignore delete mode 100644 dep/FreeBSD/SDL/Release/.gitignore delete mode 100644 dep/Linux/SDL/Debug/.gitignore delete mode 100644 dep/Linux/SDL/Release/.gitignore delete mode 100644 dep/Linux64/SDL/Debug/.gitignore delete mode 100644 dep/Linux64/SDL/Release/.gitignore delete mode 100644 dep/MasterClient/.gitignore delete mode 100644 dep/MasterServer/.gitignore delete mode 100644 dep/Mingw/Debug/.gitignore delete mode 100644 dep/Mingw/Release/.gitignore delete mode 100644 dep/Mingw/SDL/Debug/.gitignore delete mode 100644 dep/Mingw/SDL/Release/.gitignore delete mode 100644 dep/Mingw64/Debug/.gitignore delete mode 100644 dep/Mingw64/Release/.gitignore delete mode 100644 dep/Mingw64/SDL/Debug/.gitignore delete mode 100644 dep/Mingw64/SDL/Release/.gitignore delete mode 100644 dep/SDL/Release/.gitignore delete mode 100644 dep/VC/.gitignore delete mode 100644 dep/VC9/.gitignore delete mode 100644 dep/cygwin/Debug/.gitignore delete mode 100644 dep/cygwin/Release/.gitignore delete mode 100644 dep/dummy/.gitignore delete mode 100644 objs/.gitignore delete mode 100644 objs/FreeBSD/SDL/Debug/.gitignore delete mode 100644 objs/FreeBSD/SDL/Release/.gitignore delete mode 100644 objs/Linux/SDL/Debug/.gitignore delete mode 100644 objs/Linux/SDL/Release/.gitignore delete mode 100644 objs/Linux64/SDL/Debug/.gitignore delete mode 100644 objs/Linux64/SDL/Release/.gitignore delete mode 100644 objs/MasterClient/.gitignore delete mode 100644 objs/MasterServer/.gitignore delete mode 100644 objs/Mingw/Debug/.gitignore delete mode 100644 objs/Mingw/Release/.gitignore delete mode 100644 objs/Mingw/SDL/Debug/.gitignore delete mode 100644 objs/Mingw/SDL/Release/.gitignore delete mode 100644 objs/Mingw64/Debug/.gitignore delete mode 100644 objs/Mingw64/Release/.gitignore delete mode 100644 objs/Mingw64/SDL/Debug/.gitignore delete mode 100644 objs/Mingw64/SDL/Release/.gitignore delete mode 100644 objs/SDL/Release/.gitignore delete mode 100644 objs/VC/.gitignore delete mode 100644 objs/VC9/.gitignore delete mode 100644 objs/cygwin/Debug/.gitignore delete mode 100644 objs/cygwin/Release/.gitignore delete mode 100644 objs/dummy/.gitignore diff --git a/bin/FreeBSD/Debug/.gitignore b/bin/FreeBSD/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/bin/FreeBSD/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/bin/FreeBSD/Release/.gitignore b/bin/FreeBSD/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/bin/FreeBSD/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/bin/Linux/Debug/.gitignore b/bin/Linux/Debug/.gitignore deleted file mode 100644 index 56dee6f95..000000000 --- a/bin/Linux/Debug/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/lsdlsrb2 diff --git a/bin/Linux/Release/.gitignore b/bin/Linux/Release/.gitignore deleted file mode 100644 index 5b5c54a54..000000000 --- a/bin/Linux/Release/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/lsdlsrb2 -/pnd -/*.mo diff --git a/bin/Linux64/Debug/.gitignore b/bin/Linux64/Debug/.gitignore deleted file mode 100644 index 56dee6f95..000000000 --- a/bin/Linux64/Debug/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/lsdlsrb2 diff --git a/bin/Linux64/Release/.gitignore b/bin/Linux64/Release/.gitignore deleted file mode 100644 index 56dee6f95..000000000 --- a/bin/Linux64/Release/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/lsdlsrb2 diff --git a/bin/Mingw/Debug/.gitignore b/bin/Mingw/Debug/.gitignore deleted file mode 100644 index 834f313e3..000000000 --- a/bin/Mingw/Debug/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -*.exe -*.mo -r_opengl.dll diff --git a/bin/Mingw/Release/.gitignore b/bin/Mingw/Release/.gitignore deleted file mode 100644 index 3458ff764..000000000 --- a/bin/Mingw/Release/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -*.exe -*.mo -r_opengl.dll -*.bat diff --git a/bin/Mingw64/Debug/.gitignore b/bin/Mingw64/Debug/.gitignore deleted file mode 100644 index e431dca5d..000000000 --- a/bin/Mingw64/Debug/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/srb2sdl.exe -/srb2win.exe -/r_opengl.dll diff --git a/bin/Mingw64/Release/.gitignore b/bin/Mingw64/Release/.gitignore deleted file mode 100644 index e431dca5d..000000000 --- a/bin/Mingw64/Release/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/srb2sdl.exe -/srb2win.exe -/r_opengl.dll diff --git a/bin/SDL/Debug/.gitignore b/bin/SDL/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/bin/SDL/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/bin/SDL/Release/.gitignore b/bin/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/bin/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/bin/VC/.gitignore b/bin/VC/.gitignore deleted file mode 100644 index e52f825b2..000000000 --- a/bin/VC/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/Release -/Debug diff --git a/bin/VC9/.gitignore b/bin/VC9/.gitignore deleted file mode 100644 index 205fe45de..000000000 --- a/bin/VC9/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/Win32 -/x64 diff --git a/bin/dummy/.gitignore b/bin/dummy/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/bin/dummy/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/.gitignore b/dep/.gitignore deleted file mode 100644 index fb941664f..000000000 --- a/dep/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -#All folders -*.d diff --git a/dep/FreeBSD/SDL/Debug/.gitignore b/dep/FreeBSD/SDL/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/FreeBSD/SDL/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/FreeBSD/SDL/Release/.gitignore b/dep/FreeBSD/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/FreeBSD/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/Linux/SDL/Debug/.gitignore b/dep/Linux/SDL/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/Linux/SDL/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/Linux/SDL/Release/.gitignore b/dep/Linux/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/Linux/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/Linux64/SDL/Debug/.gitignore b/dep/Linux64/SDL/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/Linux64/SDL/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/Linux64/SDL/Release/.gitignore b/dep/Linux64/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/Linux64/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/MasterClient/.gitignore b/dep/MasterClient/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/MasterClient/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/MasterServer/.gitignore b/dep/MasterServer/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/MasterServer/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/Mingw/Debug/.gitignore b/dep/Mingw/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/Mingw/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/Mingw/Release/.gitignore b/dep/Mingw/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/Mingw/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/Mingw/SDL/Debug/.gitignore b/dep/Mingw/SDL/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/Mingw/SDL/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/Mingw/SDL/Release/.gitignore b/dep/Mingw/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/Mingw/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/Mingw64/Debug/.gitignore b/dep/Mingw64/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/Mingw64/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/Mingw64/Release/.gitignore b/dep/Mingw64/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/Mingw64/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/Mingw64/SDL/Debug/.gitignore b/dep/Mingw64/SDL/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/Mingw64/SDL/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/Mingw64/SDL/Release/.gitignore b/dep/Mingw64/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/Mingw64/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/SDL/Release/.gitignore b/dep/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/VC/.gitignore b/dep/VC/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/VC/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/VC9/.gitignore b/dep/VC9/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/VC9/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/cygwin/Debug/.gitignore b/dep/cygwin/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/cygwin/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/cygwin/Release/.gitignore b/dep/cygwin/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/cygwin/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/dummy/.gitignore b/dep/dummy/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/dummy/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/.gitignore b/objs/.gitignore deleted file mode 100644 index 35ecd6def..000000000 --- a/objs/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -#All folders -SRB2.res -depend.dep -depend.ped -*.o -#VC9 folder only -/VC9/Win32 -/VC9/x64 diff --git a/objs/FreeBSD/SDL/Debug/.gitignore b/objs/FreeBSD/SDL/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/FreeBSD/SDL/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/FreeBSD/SDL/Release/.gitignore b/objs/FreeBSD/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/FreeBSD/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/Linux/SDL/Debug/.gitignore b/objs/Linux/SDL/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/Linux/SDL/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/Linux/SDL/Release/.gitignore b/objs/Linux/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/Linux/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/Linux64/SDL/Debug/.gitignore b/objs/Linux64/SDL/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/Linux64/SDL/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/Linux64/SDL/Release/.gitignore b/objs/Linux64/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/Linux64/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/MasterClient/.gitignore b/objs/MasterClient/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/MasterClient/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/MasterServer/.gitignore b/objs/MasterServer/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/MasterServer/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/Mingw/Debug/.gitignore b/objs/Mingw/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/Mingw/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/Mingw/Release/.gitignore b/objs/Mingw/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/Mingw/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/Mingw/SDL/Debug/.gitignore b/objs/Mingw/SDL/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/Mingw/SDL/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/Mingw/SDL/Release/.gitignore b/objs/Mingw/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/Mingw/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/Mingw64/Debug/.gitignore b/objs/Mingw64/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/Mingw64/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/Mingw64/Release/.gitignore b/objs/Mingw64/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/Mingw64/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/Mingw64/SDL/Debug/.gitignore b/objs/Mingw64/SDL/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/Mingw64/SDL/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/Mingw64/SDL/Release/.gitignore b/objs/Mingw64/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/Mingw64/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/SDL/Release/.gitignore b/objs/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/VC/.gitignore b/objs/VC/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/VC/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/VC9/.gitignore b/objs/VC9/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/VC9/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/cygwin/Debug/.gitignore b/objs/cygwin/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/cygwin/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/cygwin/Release/.gitignore b/objs/cygwin/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/cygwin/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/dummy/.gitignore b/objs/dummy/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/dummy/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing From b31056c7d977fe3c2a5e0637589fd9521f1f6c04 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 2 May 2021 02:54:51 -0700 Subject: [PATCH 433/644] Rewrite Makefile to be modular as well as more automated Some key points for programmers: - Source code files are mostly listed in a 'Sourcefile'. So you no longer directly edit the object list. There can be multiple Sourcefiles and they can even live in subdirectories--the directory name will be prepended to every filename in the list. Of course, the Makefile still needs to be edited to read from each Sourcefile. - Different rules are no longer required for source code files that live in subdirectories (such as sdl/ or hardware/). Subdirectories Just Work so go ham! In addition to those points, another important change is that the bin directory is no longer divided into platform subdirectories (Linux64, Mingw, etc). Executables now go directly into bin. If you use DEBUGMODE or target 64-bit, then subdirectories for 'debug' and '64' will be made though. Oh by the way, I don't think make clean actually removed files before on Windows. It should now. I also fixed as many little inconsistencies like that as I noticed. And now just an overview of the technical aspects that shouldn't affect anyone who doesn't REALLY care about the Makefile... objs and dep directories have been moved to a make directory. Makefile.cfg and its variants have been moved out of their various subdirectories to src/Makefile.d make distclean removes the bin and make directories entirely, but make clean and cleandep still only affect the current build target. When I say automation, I mean that a lot of copy pasting in the Makefile has been reduced. --- .gitignore | 4 +- CMakeLists.txt | 2 +- src/Makefile | 1087 +++++++++++------------------------- src/Makefile.d/detect.mk | 104 ++++ src/Makefile.d/features.mk | 76 +++ src/Makefile.d/lua.mk | 51 -- src/Makefile.d/nix.mk | 94 +--- src/Makefile.d/platform.mk | 67 +++ src/Makefile.d/sdl.mk | 153 +++-- src/Makefile.d/util.mk | 89 +++ src/Makefile.d/versions.mk | 385 ++----------- src/Makefile.d/win32.mk | 187 +++---- src/Sourcefile | 87 +++ src/blua/Sourcefile | 25 + src/hardware/Sourcefile | 13 + src/sdl/Sourcefile | 7 + 16 files changed, 1017 insertions(+), 1414 deletions(-) create mode 100644 src/Makefile.d/detect.mk create mode 100644 src/Makefile.d/features.mk delete mode 100644 src/Makefile.d/lua.mk create mode 100644 src/Makefile.d/platform.mk create mode 100644 src/Makefile.d/util.mk create mode 100644 src/Sourcefile create mode 100644 src/blua/Sourcefile create mode 100644 src/hardware/Sourcefile create mode 100644 src/sdl/Sourcefile diff --git a/.gitignore b/.gitignore index 3090417dd..7023aaa80 100644 --- a/.gitignore +++ b/.gitignore @@ -13,11 +13,11 @@ Win32_LIB_ASM_Release *.dgb *.debug *.debug.txt -/bin/VC10/ -/objs/VC10/ *.user *.db *.opendb /.vs /debian /assets/debian +/make +/bin diff --git a/CMakeLists.txt b/CMakeLists.txt index 5d2d4a7e6..148f17ef0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -119,7 +119,7 @@ set(SRB2_SDL2_EXE_NAME srb2 CACHE STRING "Executable binary output name") include_directories(${CMAKE_CURRENT_BINARY_DIR}/src) add_subdirectory(src) -add_subdirectory(assets) +#add_subdirectory(assets) ## config.h generation diff --git a/src/Makefile b/src/Makefile index cf06ce904..dafec3645 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,817 +1,402 @@ - -# GNU Make makefile for SRB2 -############################################################################# -# Copyright (C) 1998-2000 by DooM Legacy Team. -# Copyright (C) 2003-2021 by Sonic Team Junior. +# GNU Makefile for SRB2 +# the poly3 Makefile adapted over and over... +# +# Copyright 1998-2000 DooM Legacy Team. +# Copyright 2020-2021 James R. +# Copyright 2003-2021 Sonic Team Junior. # # This program is free software distributed under the # terms of the GNU General Public License, version 2. # See the 'LICENSE' file for more details. # -# -DLINUX -> use for the GNU/Linux specific -# -D_WINDOWS -> use for the Win32/DirectX specific -# -DHAVE_SDL -> use for the SDL interface +# Special targets: # -# Sets: -# Compile the SDL/Mingw version with 'make MINGW=1' -# Compile the SDL/Linux version with 'make LINUX=1' -# Compile the SDL/Solaris version with 'make SOLARIS=1' -# Compile the SDL/FreeBSD version with 'gmake FREEBSD=1' -# Compile the SDL/Cygwin version with 'make CYGWIN32=1' -# Compile the SDL/other version try with 'make SDL=1' +# clean - remove executables and objects for this build +# cleandep - remove dependency files for this build +# distclean - remove entire executable, object and +# dependency file directory structure. +# info - print settings # -# 'Targets': -# clean -# Remove all object files -# cleandep -# Remove dependency files -# distclean -# Remove autogenerated files -# dll -# compile primary HW render DLL/SO -# all_dll -# compile all HW render and 3D sound DLLs for the set -# opengl_dll -# Pure Mingw only, compile OpenGL HW render DLL -# ds3d_dll -# Pure Mingw only, compile DirectX DirectSound HW sound DLL -# fmod_dll -# Pure Mingw only, compile FMOD HW sound DLL -# openal_dll -# Pure Mingw only, compile OpenAL HW sound DLL -# fmod_so -# Non-Mingw, compile FMOD HW sound SO -# openal_so -# Non-Mingw, compile OpenAL HW sound SO +# This Makefile can automatically detect the host system +# as well as the compiler version. If system or compiler +# version cannot be detected, you may need to set a flag +# manually. # +# On Windows machines, 32-bit Windows is always targetted. # -# Addon: -# To Cross-Compile, CC=gcc-version make * PREFIX= -# Compile with GCC 2.97 version, add 'GCC29=1' -# Compile with GCC 4.0x version, add 'GCC40=1' -# Compile with GCC 4.1x version, add 'GCC41=1' -# Compile with GCC 4.2x version, add 'GCC42=1' -# Compile with GCC 4.3x version, add 'GCC43=1' -# Compile with GCC 4.4x version, add 'GCC44=1' -# Compile with GCC 4.5x version, add 'GCC45=1' -# Compile with GCC 4.6x version, add 'GCC46=1' -# Compile a profile version, add 'PROFILEMODE=1' -# Compile a debug version, add 'DEBUGMODE=1' -# Compile with less warnings, add 'RELAXWARNINGS=1' -# Generate compiler errors for most compiler warnings, add 'ERRORMODE=1' -# Compile without NASM's tmap.nas, add 'NOASM=1' -# Compile without 3D hardware support, add 'NOHW=1' -# Compile with GDBstubs, add 'RDB=1' -# Compile without PNG, add 'NOPNG=1' -# Compile without zlib, add 'NOZLIB=1' +# Platform/system flags: # -# Addon for SDL: -# To Cross-Compile, add 'SDL_CONFIG=/usr/*/bin/sdl-config' -# Compile without SDL_Mixer, add 'NOMIXER=1' -# Compile without SDL_Mixer_X, add 'NOMIXERX=1' (Win32 only) -# Compile without GME, add 'NOGME=1' -# Compile without BSD API, add 'NONET=1' -# Compile without IPX/SPX, add 'NOIPX=1' -# Compile Mingw/SDL with S_DS3S, add 'DS3D=1' -# Compile without libopenmpt, add 'NOOPENMPT=1' -# Compile with S_FMOD3D, add 'FMOD=1' (WIP) -# Compile with S_OPENAL, add 'OPENAL=1' (WIP) -# To link with the whole SDL_Image lib to load Icons, add 'SDL_IMAGE=1' but it isn't not realy needed -# To link with SDLMain to hide console or make on a console-less binary, add 'SDLMAIN=1' +# LINUX=1, LINUX64=1 +# MINGW=1, MINGW64=1 - Windows (MinGW toolchain) +# UNIX=1 - Generic Unix like system +# FREEBSD=1 +# SDL=1 - Use SDL backend. SDL is the only backend though +# and thus, always enabled. # -############################################################################# +# A list of supported GCC versions can be found in +# Makefile.d/detect.mk -- search 'gcc_versions'. +# +# Feature flags: +# +# Safe to use online +# ------------------ +# NO_IPV6=1 - Disable IPv6 address support. +# NOHW=1 - Disable OpenGL renderer. +# ZDEBUG=1 - Enable more detailed memory debugging +# HAVE_MINIUPNPC=1 - Enable automated port forwarding. +# Already enabled by default for 32-bit +# Windows. +# NOASM=1 - Disable hand optimized assembly code for the +# Software renderer. +# NOPNG=1 - Disable PNG graphics support. (TODO: double +# check netplay compatible.) +# NOCURL=1 - Disable libcurl--HTTP capability. +# NOGME=1 - Disable game music emu, retro VGM support. +# NOOPENMPT=1 - Disable module (tracker) music support. +# NOMIXER=1 - Disable SDL Mixer (audio playback). +# NOMIXERX=1 - Forgo SDL Mixer X--revert to standard SDL +# Mixer. Mixer X is the default for Windows +# builds. +# HAVE_MIXERX=1 - Enable SDL Mixer X. Outside of Windows +# builds, SDL Mixer X is not the default. +# NOTHREADS=1 - Disable multithreading. +# +# Netplay incompatible +# -------------------- +# NONET=1 - Disable online capability. +# NOMD5=1 - Disable MD5 checksum (validation tool). +# NOPOSTPROCESSING=1 - ? +# MOBJCONSISTANCY=1 - ?? +# PACKETDROP=1 - ?? +# DEBUGMODE=1 - Enable various debugging capabilities. +# Also disables optimizations. +# NOZLIB=1 - Disable some compression capability. Implies +# NOPNG=1. +# +# Development flags: +# +# VALGRIND=1 - Enable Valgrind memory debugging support. +# PROFILEMODE=1 - Enable performance profiling (gprof). +# +# General flags for building: +# +# STATIC=1 - Use static linking. +# DISTCC=1 +# CCACHE=1 +# NOOBJDUMP=1 - Don't disassemble executable. +# NOUPX=1 - Don't compress executable. +# WINDOWSHELL=1 - Use Windows commands. +# PREFIX= - Prefix to many commands, for cross compiling. +# YASM=1 - Use Yasm instead of NASM assembler. +# STABS=1 - ? +# ECHO=1 - Print out each command in the build process. +# NOECHOFILENAMES=1 - Don't print out each that is being +# worked on. +# SILENT=1 - Print absolutely nothing except errors. +# RELAXWARNINGS=1 - Use less compiler warnings/errors. +# ERRORMODE=1 - Treat most compiler warnings as errors. +# NOCASTALIGNWARN=1 - ? +# NOLDWARNING=1 - ? +# NOSDLMAIN=1 - ? +# SDLMAIN=1 - ? +# +# Library configuration flags: +# Everything here is an override. +# +# PNG_PKGCONFIG= - libpng-config command. +# PNG_CFLAGS=, PNG_LDFLAGS= +# +# CURLCONFIG= - curl-config command. +# CURL_CFLAGS=, CURL_LDFLAGS= +# +# VALGRIND_PKGCONFIG= - pkg-config package name. +# VALGRIND_CFLAGS=, VALGRIND_LDFLAGS= +# +# LIBGME_PKGCONFIG=, LIBGME_CFLAGS=, LIBGME_LDFLAGS= -,=, +# LIBOPENMPT_PKGCONFIG= +# LIBOPENMPT_CFLAGS=, LIBOPENMPT_LDFLAGS= +# +# ZLIB_PKGCONFIG=, ZLIB_CFLAGS=, ZLIB_LDFLAGS= +# +# SDL_PKGCONFIG= +# SDL_CONFIG= - sdl-config command. +# SDL_CFLAGS=, SDL_LDFLAGS= -ifeq (,$(filter-out cleandep clean distclean,$(or $(MAKECMDGOALS),all))) -CLEANONLY=1 -else ifndef SILENT -echo=@echo "$(1)" -ifndef MAKE_RESTARTS -print=$(info $(1)) -endif -endif +clean_targets=cleandep clean distclean info -ALL_SYSTEMS=\ - PANDORA\ - LINUX64\ - MINGW64\ - HAIKU\ - DUMMY\ - DJGPPDOS\ - MINGW\ - UNIX\ - LINUX\ - SOLARIS\ - FREEBSD\ - MACOSX\ - SDL\ +.PHONY : $(clean_targets) all -# check for user specified system -ifeq (,$(filter $(ALL_SYSTEMS),$(.VARIABLES))) -ifeq ($(OS),Windows_NT) # all windows are Windows_NT... +goals:=$(or $(MAKECMDGOALS),all) +cleanonly:=$(filter $(clean_targets),$(goals)) +destructive:=$(filter-out info,$(cleanonly)) - $(call print,Detected a Windows system$(,) compiling for 32-bit MinGW SDL2...) +include Makefile.d/util.mk - # go for a 32-bit sdl mingw exe by default - MINGW=1 - WINDOWSHELL=1 - -else # if you on the *nix - - system:=$(shell uname -s) - - ifeq ($(system),Linux) - new_system=LINUX - else - - $(error \ - Could not automatically detect your system,\ - try specifying a system manually) - - endif - - ifeq ($(shell getconf LONG_BIT),64) - system+=64-bit - new_system:=$(new_system)64 - endif - - $(call print,Detected $(system) ($(new_system))...) - $(new_system)=1 - -endif -endif - - -# SRB2 data files -D_DIR?=../bin/Resources -D_FILES=$(D_DIR)/srb2.pk3 \ - $(D_DIR)/player.dta \ - $(D_DIR)/zones.pk3 \ - $(D_DIR)/music.dta \ - -PKG_CONFIG?=pkg-config - -ifdef PANDORA -LINUX=1 -endif - -ifdef LINUX64 -LINUX=1 -NONX86=1 -# LINUX64 does not imply X86_64=1; could mean ARM64 or Itanium -endif - -ifdef MINGW64 -MINGW=1 -NONX86=1 -NOASM=1 -# MINGW64 should not necessarily imply X86_64=1, but we make that assumption elsewhere -# Once that changes, remove this -X86_64=1 -endif #ifdef MINGW64 - -ifdef HAIKU -SDL=1 -endif - -include Makefile.cfg - -ifdef DUMMY -NOPNG=1 -NOZLIB=1 -NONET=1 -NOHW=1 -NOASM=1 -NOIPX=1 -EXENAME?=srb2dummy -OBJS=$(OBJDIR)/i_video.o -LIBS=-lm -endif - -ifdef HAIKU -NOIPX=1 -NOASM=1 -ifndef NONET -LIBS=-lnetwork -endif -CFLAGS+=-DUNIXCOMMON -PNG_CFLAGS?= -PNG_LDFLAGS?=-lpng -endif - -ifdef PANDORA -NONX86=1 -NOHW=1 -endif - -ifndef NOOPENMPT -HAVE_OPENMPT=1 -endif - -ifdef MINGW -include win32/Makefile.cfg -endif #ifdef MINGW - -ifdef UNIX -UNIXCOMMON=1 -endif - -ifdef LINUX -UNIXCOMMON=1 -ifndef NOGME -HAVE_LIBGME=1 -endif -endif - -ifdef SOLARIS -UNIXCOMMON=1 -endif - -ifdef FREEBSD -UNIXCOMMON=1 -endif - -ifdef MACOSX -UNIXCOMMON=1 -endif - -ifdef SDL - include sdl/Makefile.cfg -endif #ifdef SDL - -ifdef DISTCC - CC:=distcc $(CC) -endif - -ifdef CCACHE - CC:=ccache $(CC) -endif - -MSGFMT?=msgfmt - -ifdef WINDOWSHELL - COMPTIME=-..\comptime.bat -else - COMPTIME=-../comptime.sh -endif - -ifndef ECHO - NASM:=@$(NASM) - REMOVE:=@$(REMOVE) - CC:=@$(CC) - CXX:=@$(CXX) - OBJCOPY:=@$(OBJCOPY) - OBJDUMP:=@$(OBJDUMP) - STRIP:=@$(STRIP) - WINDRES:=@$(WINDRES) - MKDIR:=@$(MKDIR) - GZIP:=@$(GZIP) - MSGFMT:=@$(MSGFMT) - UPX:=@$(UPX) - UPX_OPTS+=-q - COMPTIME:=@$(COMPTIME) -endif - -ifdef NONET - OPTS+=-DNONET - NOCURL=1 -else -ifdef NO_IPV6 - OPTS+=-DNO_IPV6 -endif -endif - -ifdef NOHW - OPTS+=-DNOHW -else - OPTS+=-DHWRENDER - OBJS+=$(OBJDIR)/hw_bsp.o $(OBJDIR)/hw_draw.o $(OBJDIR)/hw_light.o \ - $(OBJDIR)/hw_main.o $(OBJDIR)/hw_clip.o $(OBJDIR)/hw_md2.o $(OBJDIR)/hw_cache.o \ - $(OBJDIR)/hw_md2load.o $(OBJDIR)/hw_md3load.o $(OBJDIR)/hw_model.o $(OBJDIR)/u_list.o $(OBJDIR)/hw_batching.o -endif - -OPTS += -DCOMPVERSION - -ifndef NONX86 -ifndef GCC29 - ARCHOPTS?=-msse3 -mfpmath=sse -else - ARCHOPTS?=-mpentium -endif -else -ifdef X86_64 - ARCHOPTS?=-march=nocona -endif -endif - -ifndef NOASM -ifndef NONX86 - OBJS+=$(OBJDIR)/tmap.o $(OBJDIR)/tmap_mmx.o - OPTS+=-DUSEASM -endif -endif - -ifndef NOPNG -OPTS+=-DHAVE_PNG - -ifdef PNG_PKGCONFIG -PNG_CFLAGS?=$(shell $(PKG_CONFIG) $(PNG_PKGCONFIG) --cflags) -PNG_LDFLAGS?=$(shell $(PKG_CONFIG) $(PNG_PKGCONFIG) --libs) -else ifdef PREFIX -PNG_CONFIG?=$(PREFIX)-libpng-config +CC:=$(PREFIX)-gcc +endif + +OBJDUMP_OPTS?=--wide --source --line-numbers + +OBJCOPY:=$(call Prefix,objcopy) +OBJDUMP:=$(call Prefix,objdump) $(OBJDUMP_OPTS) +WINDRES:=$(call Prefix,windres) + +ifdef YASM +NASM?=yasm else -PNG_CONFIG?=libpng-config +NASM?=nasm endif -ifdef PNG_STATIC -PNG_CFLAGS?=$(shell $(PNG_CONFIG) --static --cflags) -PNG_LDFLAGS?=$(shell $(PNG_CONFIG) --static --ldflags) -else -PNG_CFLAGS?=$(shell $(PNG_CONFIG) --cflags) -PNG_LDFLAGS?=$(shell $(PNG_CONFIG) --ldflags) -endif -endif - -ifdef LINUX -PNG_CFLAGS+=-D_LARGEFILE64_SOURCE -endif - -LIBS+=$(PNG_LDFLAGS) -CFLAGS+=$(PNG_CFLAGS) - -OBJS+=$(OBJDIR)/apng.o -endif - -ifdef HAVE_LIBGME -OPTS+=-DHAVE_LIBGME - -LIBGME_PKGCONFIG?=libgme -LIBGME_CFLAGS?=$(shell $(PKG_CONFIG) $(LIBGME_PKGCONFIG) --cflags) -LIBGME_LDFLAGS?=$(shell $(PKG_CONFIG) $(LIBGME_PKGCONFIG) --libs) - -LIBS+=$(LIBGME_LDFLAGS) -CFLAGS+=$(LIBGME_CFLAGS) -endif - -ifdef HAVE_OPENMPT -OPTS+=-DHAVE_OPENMPT - -LIBOPENMPT_PKGCONFIG?=libopenmpt -LIBOPENMPT_CFLAGS?=$(shell $(PKG_CONFIG) $(LIBOPENMPT_PKGCONFIG) --cflags) -LIBOPENMPT_LDFLAGS?=$(shell $(PKG_CONFIG) $(LIBOPENMPT_PKGCONFIG) --libs) - -LIBS+=$(LIBOPENMPT_LDFLAGS) -CFLAGS+=$(LIBOPENMPT_CFLAGS) -endif - -ifndef NOZLIB -OPTS+=-DHAVE_ZLIB -ZLIB_PKGCONFIG?=zlib -ZLIB_CFLAGS?=$(shell $(PKG_CONFIG) $(ZLIB_PKGCONFIG) --cflags) -ZLIB_LDFLAGS?=$(shell $(PKG_CONFIG) $(ZLIB_PKGCONFIG) --libs) - -LIBS+=$(ZLIB_LDFLAGS) -CFLAGS+=$(ZLIB_CFLAGS) -else -NOPNG=1 -endif - -ifndef NOCURL -OPTS+=-DHAVE_CURL -CURLCONFIG?=curl-config -CURL_CFLAGS?=$(shell $(CURLCONFIG) --cflags) -CURL_LDFLAGS?=$(shell $(CURLCONFIG) --libs) - -LIBS+=$(CURL_LDFLAGS) -CFLAGS+=$(CURL_CFLAGS) -endif - -ifdef STATIC -LIBS:=-static $(LIBS) -endif - -ifdef HAVE_MINIUPNPC -ifdef NONET -HAVE_MINIUPNPC='' -else -LIBS+=-lminiupnpc -ifdef MINGW -LIBS+=-lws2_32 -liphlpapi -endif -CFLAGS+=-DHAVE_MINIUPNPC -endif -endif - -include blua/Makefile.cfg - -ifdef NOMD5 - OPTS+=-DNOMD5 -else - OBJS:=$(OBJDIR)/md5.o $(OBJS) -endif - -ifdef NOPOSTPROCESSING - OPTS+=-DNOPOSTPROCESSING -endif - - OPTS:=-fno-exceptions $(OPTS) - -ifdef MOBJCONSISTANCY - OPTS+=-DMOBJCONSISTANCY -endif - -ifdef PACKETDROP - OPTS+=-DPACKETDROP -endif - -ifdef DEBUGMODE - - # build with debugging information - WINDRESFLAGS = -D_DEBUG -ifdef GCC48 - CFLAGS+=-Og -else - CFLAGS+=-O0 -endif - CFLAGS+= -Wall -DPARANOIA -DRANGECHECK -DPACKETDROP -DMOBJCONSISTANCY -else - - - # build a normal optimised version - WINDRESFLAGS = -DNDEBUG - CFLAGS+=-O3 -endif - CFLAGS+=-g $(OPTS) $(ARCHOPTS) $(WINDRESFLAGS) - ifdef YASM ifdef STABS - NASMOPTS?= -g stabs +NASMOPTS?=-g stabs else - NASMOPTS?= -g dwarf2 +NASMOPTS?=-g dwarf2 endif else - NASMOPTS?= -g +NASMOPTS?=-g endif -ifdef PROFILEMODE - # build with profiling information - CFLAGS+=-pg - LDFLAGS+=-pg +GZIP?=gzip +GZIP_OPTS?=-9 -f -n +ifdef WINDOWSHELL +GZIP_OPTS+=--rsyncable endif -ifdef ZDEBUG - CPPFLAGS+=-DZDEBUG +UPX?=upx +UPX_OPTS?=--best --preserve-build-id +ifndef ECHO +UPX_OPTS+=-qq endif -OPTS+=$(CPPFLAGS) +include Makefile.d/detect.mk -# default EXENAME if all else fails +# make would try to remove the implicitly made directories +.PRECIOUS : %/ comptime.c + +# very sophisticated dependency +sources:=\ + $(call List,Sourcefile)\ + $(call List,blua/Sourcefile)\ + +makedir:=../make + +# -DCOMPVERSION: flag to use comptime.h +opts:=-DCOMPVERSION -g +libs:= + +nasm_format:= + +# This is a list of variables names, of which if defined, +# also defines the name as a macro to the compiler. +passthru_opts:= + +include Makefile.d/platform.mk +include Makefile.d/features.mk +include Makefile.d/versions.mk + +ifdef DEBUGMODE +makedir:=$(makedir)/debug +endif + +depdir:=$(makedir)/deps +objdir:=$(makedir)/objs + +depends:=$(basename $(filter %.c %.s,$(sources))) +objects:=$(basename $(filter %.c %.s %.nas,$(sources))) + +depends:=$(depends:%=$(depdir)/%.d) + +# comptime.o added directly to objects instead of thru +# sources because comptime.c includes comptime.h, but +# comptime.h may not exist yet. It's a headache so this is +# easier. +objects:=$(objects:=.o) comptime.o + +# windows resource file +rc_file:=$(basename $(filter %.rc,$(sources))) +ifdef rc_file +objects+=$(rc_file:=.res) +endif + +objects:=$(addprefix $(objdir)/,$(objects)) + +ifdef DEBUGMODE +bin:=../bin/debug +else +bin:=../bin +endif + +# default EXENAME (usually set by platform) EXENAME?=srb2 DBGNAME?=$(EXENAME).debug -# $(OBJDIR)/dstrings.o \ +exe:=$(bin)/$(EXENAME) +dbg:=$(bin)/$(DBGNAME) -# not too sophisticated dependency -OBJS:=$(i_main_o) \ - $(OBJDIR)/string.o \ - $(OBJDIR)/d_main.o \ - $(OBJDIR)/d_clisrv.o \ - $(OBJDIR)/d_net.o \ - $(OBJDIR)/d_netfil.o \ - $(OBJDIR)/d_netcmd.o \ - $(OBJDIR)/dehacked.o \ - $(OBJDIR)/z_zone.o \ - $(OBJDIR)/f_finale.o \ - $(OBJDIR)/f_wipe.o \ - $(OBJDIR)/g_demo.o \ - $(OBJDIR)/g_game.o \ - $(OBJDIR)/g_input.o \ - $(OBJDIR)/am_map.o \ - $(OBJDIR)/command.o \ - $(OBJDIR)/console.o \ - $(OBJDIR)/hu_stuff.o \ - $(OBJDIR)/y_inter.o \ - $(OBJDIR)/st_stuff.o \ - $(OBJDIR)/m_aatree.o \ - $(OBJDIR)/m_anigif.o \ - $(OBJDIR)/m_argv.o \ - $(OBJDIR)/m_bbox.o \ - $(OBJDIR)/m_cheat.o \ - $(OBJDIR)/m_cond.o \ - $(OBJDIR)/m_fixed.o \ - $(OBJDIR)/m_menu.o \ - $(OBJDIR)/m_misc.o \ - $(OBJDIR)/m_random.o \ - $(OBJDIR)/m_queue.o \ - $(OBJDIR)/info.o \ - $(OBJDIR)/p_ceilng.o \ - $(OBJDIR)/p_enemy.o \ - $(OBJDIR)/p_floor.o \ - $(OBJDIR)/p_inter.o \ - $(OBJDIR)/p_lights.o \ - $(OBJDIR)/p_map.o \ - $(OBJDIR)/p_maputl.o \ - $(OBJDIR)/p_mobj.o \ - $(OBJDIR)/p_polyobj.o\ - $(OBJDIR)/p_saveg.o \ - $(OBJDIR)/p_setup.o \ - $(OBJDIR)/p_sight.o \ - $(OBJDIR)/p_spec.o \ - $(OBJDIR)/p_telept.o \ - $(OBJDIR)/p_tick.o \ - $(OBJDIR)/p_user.o \ - $(OBJDIR)/p_slopes.o \ - $(OBJDIR)/tables.o \ - $(OBJDIR)/r_bsp.o \ - $(OBJDIR)/r_data.o \ - $(OBJDIR)/r_draw.o \ - $(OBJDIR)/r_main.o \ - $(OBJDIR)/r_plane.o \ - $(OBJDIR)/r_segs.o \ - $(OBJDIR)/r_skins.o \ - $(OBJDIR)/r_sky.o \ - $(OBJDIR)/r_splats.o \ - $(OBJDIR)/r_things.o \ - $(OBJDIR)/r_textures.o \ - $(OBJDIR)/r_picformats.o \ - $(OBJDIR)/r_portal.o \ - $(OBJDIR)/screen.o \ - $(OBJDIR)/v_video.o \ - $(OBJDIR)/s_sound.o \ - $(OBJDIR)/sounds.o \ - $(OBJDIR)/w_wad.o \ - $(OBJDIR)/filesrch.o \ - $(OBJDIR)/mserv.o \ - $(OBJDIR)/http-mserv.o\ - $(OBJDIR)/i_tcp.o \ - $(OBJDIR)/lzf.o \ - $(OBJDIR)/vid_copy.o \ - $(OBJDIR)/b_bot.o \ - $(i_net_o) \ - $(i_system_o) \ - $(i_sound_o) \ - $(OBJS) +build_done=Build is done, please look for $( srb2.s - $(REMOVE) $(OBJDIR)/tmp.exe - -# executable -# NOTE: DJGPP's objcopy do not have --add-gnu-debuglink - -$(BIN)/$(EXENAME): $(POS) $(OBJS) - -$(MKDIR) $(BIN) - $(call echo,Linking $(EXENAME)...) - $(LD) $(LDFLAGS) $(OBJS) -o $(BIN)/$(EXENAME) $(LIBS) ifndef VALGRIND ifndef NOOBJDUMP - $(call echo,Dumping debugging info) - $(OBJDUMP) $(OBJDUMP_OPTS) $(BIN)/$(EXENAME) > $(BIN)/$(DBGNAME).txt -ifdef WINDOWSHELL - -$(GZIP) $(GZIP_OPTS) $(BIN)/$(DBGNAME).txt -else - -$(GZIP) $(GZIP_OPT2) $(BIN)/$(DBGNAME).txt +all : $(dbg).txt endif endif -# mac os x lsdlsrb2 does not like objcopy -ifndef MACOSX - $(OBJCOPY) $(BIN)/$(EXENAME) $(BIN)/$(DBGNAME) - $(OBJCOPY) --strip-debug $(BIN)/$(EXENAME) - -$(OBJCOPY) --add-gnu-debuglink=$(BIN)/$(DBGNAME) $(BIN)/$(EXENAME) +ifdef STATIC +libs+=-static endif + +# build with profiling information +ifdef PROFILEMODE +opts+=-pg +libs+=-pg +endif + +ifdef DEBUGMODE +debug_opts=-D_DEBUG +else # build a normal optimized version +debug_opts=-DNDEBUG +opts+=-O3 +endif + +# debug_opts also get passed to windres +opts+=$(debug_opts) + +opts+=$(foreach v,$(passthru_opts),$(if $($(v)),-D$(v))) + +CFLAGS:=$(opts) $(WFLAGS) $(CPPFLAGS) $(CFLAGS) +LDFLAGS:=$(libs) $(LDFLAGS) +ASFLAGS+=-x assembler-with-cpp + +ifdef DISTCC +CC:=distcc $(CC) +endif + +ifdef CCACHE +CC:=ccache $(CC) +endif + +ifndef SILENT +# makefile will 'restart' when it finishes including the +# dependencies. +ifndef MAKE_RESTARTS +ifndef destrutive +$(shell $(CC) -v) +define flags = + +CC ........ $(CC) + +CFLAGS .... $(CFLAGS) + +LDFLAGS ... $(LDFLAGS) + +endef +$(info $(flags)) +endif +# don't generate dependency files if only cleaning +ifndef cleanonly +$(info Checking dependency files...) +include $(depends) +endif +endif +endif + +LD:=$(CC) +CC:=$(CC) $(CFLAGS) +NASM:=$(NASM) $(NASMOPTS) -f $(nasm_format) +GZIP:=$(GZIP) $(GZIP_OPTS) +UPX:=$(UPX) $(UPX_OPTS) +WINDRES:=$(WINDRES) $(WINDRESFLAGS)\ + $(debug_opts) --include-dir=win32 -O coff + +%/ : + $(.)$(mkdir) $@ + +# this is needed so the target can be referenced in the +# prerequisites +.SECONDEXPANSION : + +# executable stripped of debugging symbols +$(exe) : $(dbg) | $$(@D)/ + $(.)$(OBJCOPY) --strip-debug $< $@ + $(.)-$(OBJCOPY) --add-gnu-debuglink=$< $@ ifndef NOUPX - -$(UPX) $(UPX_OPTS) $(BIN)/$(EXENAME) + $(call Echo,Compressing final executable...) + $(.)-$(UPX) $@ endif -endif - $(call echo,Build is done$(,) please look for $(EXENAME) in $(BIN)$(,) (checking for post steps)) -reobjdump: - $(call echo,Redumping debugging info) - $(OBJDUMP) $(OBJDUMP_OPTS) $(BIN)/$(DBGNAME) > $(BIN)/$(DBGNAME).txt +# original executable with debugging symbols +$(dbg) : $(objects) | $$(@D)/ + $(call Echo,Linking $(@F)...) + $(.)$(LD) -o $@ $^ $(LDFLAGS) + +# disassembly of executable +$(dbg).txt : $(dbg) + $(call Echo,Dumping debugging info...) + $(.)$(OBJDUMP) $< > $@ + $(.)$(GZIP) $@ + +# '::' means run unconditionally +# this really updates comptime.h +comptime.c :: ifdef WINDOWSHELL - -$(GZIP) $(GZIP_OPTS) $(BIN)/$(DBGNAME).txt + $(.)..\comptime.bat . else - -$(GZIP) $(GZIP_OPT2) $(BIN)/$(DBGNAME).txt + $(.)../comptime.sh . endif -$(OBJDIR): - -$(MKDIR) $(OBJDIR) +# I wish I could make dependencies out of rc files :( +$(objdir)/win32/Srb2win.res : \ + win32/afxres.h win32/resource.h -ifdef SDL -ifdef MINGW -$(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \ - doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \ - command.h hardware/hw_data.h hardware/hw_defs.h \ - hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \ - hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \ - am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \ - p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h - $(echoName) - $(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@ -else -$(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \ - doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \ - command.h hardware/hw_data.h hardware/hw_defs.h \ - hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \ - hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \ - am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \ - p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h - $(echoName) - $(CC) $(CFLAGS) $(WFLAGS) -I/usr/X11R6/include -c $< -o $@ -endif -endif - -#dependecy made by gcc itself ! -ifndef DUMMY -ifndef CLEANONLY -$(call print,Checking dependency files...) --include $(DEPS) -endif -endif - -undefine deps_rule - -# windows makes it too hard ! +# dependency recipe template +# 1: source file suffix +# 2: extra flags to gcc +define _recipe = +$(depdir)/%.d : %.$(1) | $$$$(@D)/ ifndef WINDOWSHELL -ifdef echoName -define deps_rule = - @printf "%-20.20s\r" $< - -endef +ifdef Echo_name + @printf '%-20.20s\r' $$< endif endif - -define deps_rule += - $(CC) $(CFLAGS) -M -MF $@ -MT $(OBJDIR)/$(<:.c=.o) $< + $(.)$(CC) -MM -MF $$@ -MT $(objdir)/$$(*F).o $(2) $$< endef -$(DEPDIR)/%.d: %.c - $(deps_rule) +$(eval $(call _recipe,c)) +$(eval $(call _recipe,s,$(ASFLAGS))) -$(DEPDIR)/%.d: $(INTERFACE)/%.c - $(deps_rule) +# compiling recipe template +# 1: target file suffix +# 2: source file suffix +# 3: compile command +define _recipe = +$(objdir)/%.$(1) : %.$(2) | $$$$(@D)/ + $(call Echo_name,$$<) + $(.)$(3) +endef -$(DEPDIR)/%.d: hardware/%.c - $(deps_rule) +$(eval $(call _recipe,o,c,$(CC) -c -o $$@ $$<)) +$(eval $(call _recipe,o,nas,$(NASM) -o $$@ $$<)) +$(eval $(call _recipe,o,s,$(CC) $(ASFLAGS) -c -o $$@ $$<)) +$(eval $(call _recipe,res,rc,$(WINDRES) -i $$< -o $$@)) -$(DEPDIR)/%.d: blua/%.c - $(deps_rule) +cleandep : + $(.)$(rmrf) $(depends) comptime.h -ifdef VALGRIND -$(OBJDIR)/z_zone.o: z_zone.c - $(echoName) - $(CC) $(CFLAGS) $(WFLAGS) -DHAVE_VALGRIND $(VALGRIND_CFLAGS) -c $< -o $@ -endif +clean : + $(.)$(rmrf) $(exe) $(dbg) $(dbg).txt $(objects) -$(OBJDIR)/comptime.o:: -ifdef echoName - @echo -- comptime.c ... -endif - $(COMPTIME) . - $(CC) $(CFLAGS) $(WFLAGS) -c comptime.c -o $@ +distclean : + $(.)$(rmrf) ../bin ../objs ../deps comptime.h -$(BIN)/%.mo: locale/%.po - -$(MKDIR) $(BIN) - $(echoName) - $(MSGFMT) -f -o $@ $< - -$(OBJDIR)/%.o: %.c - $(echoName) - $(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@ - -$(OBJDIR)/%.o: $(INTERFACE)/%.c - $(echoName) - $(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@ - -ifdef MACOSX -$(OBJDIR)/%.o: sdl/macosx/%.c - $(echoName) - $(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@ -endif - -$(OBJDIR)/%.o: hardware/%.c - $(echoName) - $(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@ - -$(OBJDIR)/%.o: blua/%.c - $(echoName) - $(CC) $(CFLAGS) $(LUA_CFLAGS) $(WFLAGS) -c $< -o $@ - -$(OBJDIR)/%.o: %.nas - $(echoName) - $(NASM) $(NASMOPTS) -o $@ -f $(NASMFORMAT) $< - -$(OBJDIR)/vid_copy.o: vid_copy.s asm_defs.inc - $(echoName) - $(CC) $(OPTS) $(ASFLAGS) -x assembler-with-cpp -c $< -o $@ - -$(OBJDIR)/%.o: %.s - $(echoName) - $(CC) $(OPTS) -x assembler-with-cpp -c $< -o $@ - -$(OBJDIR)/SRB2.res: win32/Srb2win.rc win32/afxres.h win32/resource.h - $(echoName) - $(WINDRES) -i $< -O rc $(WINDRESFLAGS) --include-dir=win32 -o $@ -O coff - - -ifdef SDL - -ifdef MINGW -$(OBJDIR)/win_dbg.o: win32/win_dbg.c - $(echoName) - $(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@ -endif - -ifdef STATICHS -$(OBJDIR)/s_openal.o: hardware/s_openal/s_openal.c hardware/hw3dsdrv.h \ - hardware/hw_dll.h - $(echoName) - $(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@ - -$(OBJDIR)/s_fmod.o: hardware/s_fmod/s_fmod.c hardware/hw3dsdrv.h \ - hardware/hw_dll.h - $(echoName) - $(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@ - -ifdef MINGW -$(OBJDIR)/s_ds3d.o: hardware/s_ds3d/s_ds3d.c hardware/hw3dsdrv.h \ - hardware/hw_dll.h - $(echoName) - $(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@ -endif +info: +ifdef WINDOWSHELL + @REM else - -$(OBJDIR)/s_fmod.o: hardware/s_fmod/s_fmod.c hardware/hw3dsdrv.h \ - hardware/hw_dll.h - $(echoName) - $(CC) $(ARCHOPTS) -Os -o $(OBJDIR)/s_fmod.o -DHW3SOUND -DUNIXCOMMON -shared -nostartfiles -c hardware/s_fmod/s_fmod.c - -$(OBJDIR)/s_openal.o: hardware/s_openal/s_openal.c hardware/hw3dsdrv.h \ - hardware/hw_dll.h - $(echoName) - $(CC) $(ARCHOPTS) -Os -o $(OBJDIR)/s_openal.o -DHW3SOUND -DUNIXCOMMON -shared -nostartfiles -c hardware/s_openal/s_openal.c + @: endif -endif - -############################################################# -# -############################################################# diff --git a/src/Makefile.d/detect.mk b/src/Makefile.d/detect.mk new file mode 100644 index 000000000..f576bcf78 --- /dev/null +++ b/src/Makefile.d/detect.mk @@ -0,0 +1,104 @@ +# +# Detect the host system and compiler version. +# + +# Previously featured:\ + PANDORA\ + HAIKU\ + DUMMY\ + DJGPPDOS\ + SOLARIS\ + MACOSX\ + +all_systems:=\ + LINUX64\ + MINGW64\ + MINGW\ + UNIX\ + LINUX\ + FREEBSD\ + SDL\ + +# check for user specified system +ifeq (,$(filter $(all_systems),$(.VARIABLES))) +ifeq ($(OS),Windows_NT) # all windows are Windows_NT... + +_m=Detected a Windows system,\ + compiling for 32-bit MinGW SDL...) +$(call Print,$(_m)) + +# go for a 32-bit sdl mingw exe by default +MINGW:=1 +WINDOWSHELL:=1 + +else # if you on the *nix + +system:=$(shell uname -s) + +ifeq ($(system),Linux) +new_system:=LINUX +else + +$(error \ + Could not automatically detect your system,\ + try specifying a system manually) + +endif + +ifeq ($(shell getconf LONG_BIT),64) +system+=64-bit +new_system:=$(new_system)64 +endif + +$(call Print,Detected $(system) ($(new_system))...) +$(new_system):=1 + +endif +endif + +# This must have high to low order. +gcc_versions:=\ + 102 101\ + 93 92 91\ + 84 83 82 81\ + 75 74 73 72 71\ + 64 63 62 61\ + 55 54 53 52 51\ + 49 48 47 46 45 44 43 42 41 40 + +latest_gcc_version:=10.2 + +# Automatically set version flag, but not if one was +# manually set. And don't bother if this is a clean only +# run. +ifeq (,$(call Wildvar,GCC% destructive)) +version:=$(shell $(CC) --version) + +# check if this is in fact GCC +ifneq (,$(or $(findstring gcc,$(version)),\ + $(findstring GCC,$(version)))) + +version:=$(shell $(CC) -dumpversion) + +# Turn version into words of major, minor +v:=$(subst ., ,$(version)) +# concat. major minor +v:=$(word 1,$(v))$(word 2,$(v)) + +# If this version is not in the list, +# default to the latest supported +ifeq (,$(filter $(v),$(gcc_versions))) +define line = +Your compiler version, GCC $(version), \ +is not supported by the Makefile. +The Makefile will assume GCC $(latest_gcc_version).)) +endef +$(call Print,$(line)) +GCC$(subst .,,$(latest_gcc_version)):=1 +else +$(call Print,Detected GCC $(version) (GCC$(v))) +GCC$(v):=1 +endif + +endif +endif diff --git a/src/Makefile.d/features.mk b/src/Makefile.d/features.mk new file mode 100644 index 000000000..abdc342b7 --- /dev/null +++ b/src/Makefile.d/features.mk @@ -0,0 +1,76 @@ +# +# Makefile for feature flags. +# + +passthru_opts+=\ + NONET NO_IPV6 NOHW NOMD5 NOPOSTPROCESSING\ + MOBJCONSISTANCY PACKETDROP ZDEBUG\ + HAVE_MINIUPNPC\ + +# build with debugging information +ifdef DEBUGMODE +MOBJCONSISTANCY=1 +PACKETDROP=1 +opts+=-DPARANOIA -DRANGECHECK +endif + +ifndef NOHW +opts+=-DHWRENDER +sources+=$(call List,hardware/Sourcefile) +endif + +ifndef NOASM +ifndef NONX86 +sources+=tmap.nas tmap_mmx.nas +opts+=-DUSEASM +endif +endif + +ifndef NOMD5 +sources+=md5.c +endif + +ifndef NOZLIB +ifndef NOPNG +ifdef PNG_PKGCONFIG +$(eval $(call Use_pkg_config,PNG_PKGCONFIG)) +else +PNG_CONFIG?=$(call Prefix,libpng-config) +$(eval $(call Configure,PNG,$(PNG_CONFIG) \ + $(if $(PNG_STATIC),--static),,--ldflags)) +endif +ifdef LINUX +opts+=-D_LARGFILE64_SOURCE +endif +opts+=-DHAVE_PNG +sources+=apng.c +endif +endif + +ifndef NONET +ifndef NOCURL +CURLCONFIG?=curl-config +$(eval $(call Configure,CURL,$(CURLCONFIG))) +opts+=-DHAVE_CURL +endif +endif + +ifdef HAVE_MINIUPNPC +libs+=-lminiupnpc +endif + +# (Valgrind is a memory debugger.) +ifdef VALGRIND +VALGRIND_PKGCONFIG?=valgrind +$(eval $(call Use_pkg_config,VALGRIND)) +ZDEBUG=1 +opts+=-DHAVE_VALGRIND +endif + +default_packages:=\ + GME/libgme/LIBGME\ + OPENMPT/libopenmpt/LIBOPENMPT\ + ZLIB/zlib\ + +$(foreach p,$(default_packages),\ + $(eval $(call Check_pkg_config,$(p)))) diff --git a/src/Makefile.d/lua.mk b/src/Makefile.d/lua.mk deleted file mode 100644 index 12ea064b4..000000000 --- a/src/Makefile.d/lua.mk +++ /dev/null @@ -1,51 +0,0 @@ -ifdef UNIXCOMMON -LUA_CFLAGS+=-DLUA_USE_POSIX -endif -ifdef LINUX -LUA_CFLAGS+=-DLUA_USE_POSIX -endif -ifdef GCC43 -ifndef GCC44 -WFLAGS+=-Wno-logical-op -endif -endif - -OBJS:=$(OBJS) \ - $(OBJDIR)/lapi.o \ - $(OBJDIR)/lbaselib.o \ - $(OBJDIR)/ldo.o \ - $(OBJDIR)/lfunc.o \ - $(OBJDIR)/linit.o \ - $(OBJDIR)/liolib.o \ - $(OBJDIR)/llex.o \ - $(OBJDIR)/lmem.o \ - $(OBJDIR)/lobject.o \ - $(OBJDIR)/lstate.o \ - $(OBJDIR)/lstrlib.o \ - $(OBJDIR)/ltablib.o \ - $(OBJDIR)/lundump.o \ - $(OBJDIR)/lzio.o \ - $(OBJDIR)/lauxlib.o \ - $(OBJDIR)/lcode.o \ - $(OBJDIR)/ldebug.o \ - $(OBJDIR)/ldump.o \ - $(OBJDIR)/lgc.o \ - $(OBJDIR)/lopcodes.o \ - $(OBJDIR)/lparser.o \ - $(OBJDIR)/lstring.o \ - $(OBJDIR)/ltable.o \ - $(OBJDIR)/ltm.o \ - $(OBJDIR)/lvm.o \ - $(OBJDIR)/lua_script.o \ - $(OBJDIR)/lua_baselib.o \ - $(OBJDIR)/lua_mathlib.o \ - $(OBJDIR)/lua_hooklib.o \ - $(OBJDIR)/lua_consolelib.o \ - $(OBJDIR)/lua_infolib.o \ - $(OBJDIR)/lua_mobjlib.o \ - $(OBJDIR)/lua_playerlib.o \ - $(OBJDIR)/lua_skinlib.o \ - $(OBJDIR)/lua_thinkerlib.o \ - $(OBJDIR)/lua_maplib.o \ - $(OBJDIR)/lua_blockmaplib.o \ - $(OBJDIR)/lua_hudlib.o diff --git a/src/Makefile.d/nix.mk b/src/Makefile.d/nix.mk index 47c944eb5..fdcd40d4d 100644 --- a/src/Makefile.d/nix.mk +++ b/src/Makefile.d/nix.mk @@ -1,74 +1,40 @@ # -# sdl/makeNIX.cfg for SRB2/?nix +# Makefile options for unices (linux, bsd...) # -#Valgrind support -ifdef VALGRIND -VALGRIND_PKGCONFIG?=valgrind -VALGRIND_CFLAGS?=$(shell $(PKG_CONFIG) $(VALGRIND_PKGCONFIG) --cflags) -VALGRIND_LDFLAGS?=$(shell $(PKG_CONFIG) $(VALGRIND_PKGCONFIG) --libs) -ZDEBUG=1 -LIBS+=$(VALGRIND_LDFLAGS) -ifdef GCC46 -WFLAGS+=-Wno-error=unused-but-set-variable -WFLAGS+=-Wno-unused-but-set-variable -endif -endif +EXENAME?=lsdl2srb2 -# -#here is GNU/Linux and other -# +opts+=-DUNIXCOMMON -DLUA_USE_POSIX +libs+=-lm - OPTS=-DUNIXCOMMON - - #LDFLAGS = -L/usr/local/lib - LIBS=-lm -ifdef LINUX - LIBS+=-lrt -ifdef NOTERMIOS - OPTS+=-DNOTERMIOS -endif -endif - -ifdef LINUX64 - OPTS+=-DLINUX64 -endif - -# -#here is Solaris -# -ifdef SOLARIS - NOIPX=1 - NOASM=1 - OPTS+=-DSOLARIS -DINADDR_NONE=INADDR_ANY -DBSD_COMP - OPTS+=-I/usr/local/include -I/opt/sfw/include - LDFLAGS+=-L/opt/sfw/lib - LIBS+=-lsocket -lnsl -endif - -# -#here is FreeBSD -# -ifdef FREEBSD - OPTS+=-DLINUX -DFREEBSD -I/usr/X11R6/include - SDL_CONFIG?=sdl11-config - LDFLAGS+=-L/usr/X11R6/lib - LIBS+=-lipx -lkvm -endif - -# -#here is Mac OS X -# -ifdef MACOSX - OBJS+=$(OBJDIR)/mac_resources.o - OBJS+=$(OBJDIR)/mac_alert.o - LIBS+=-framework CoreFoundation +ifndef nasm_format +nasm_format:=elf -DLINUX endif ifndef NOHW - OPTS+=-I/usr/X11R6/include - LDFLAGS+=-L/usr/X11R6/lib +opts+=-I/usr/X11R6/include +libs+=-L/usr/X11R6/lib endif - # name of the exefile - EXENAME?=lsdl2srb2 +SDL=1 + +# In common usage. +ifdef LINUX +libs+=-lrt +passthru_opts+=NOTERMIOS +endif + +# Tested by Steel, as of release 2.2.8. +ifdef FREEBSD +opts+=-I/usr/X11R6/include -DLINUX -DFREEBSD +libs+=-L/usr/X11R6/lib -lipx -lkvm +endif + +# FIXME +#ifdef SOLARIS +#NOIPX=1 +#NOASM=1 +#opts+=-I/usr/local/include -I/opt/sfw/include \ +# -DSOLARIS -DINADDR_NONE=INADDR_ANY -DBSD_COMP +#libs+=-L/opt/sfw/lib -lsocket -lnsl +#endif diff --git a/src/Makefile.d/platform.mk b/src/Makefile.d/platform.mk new file mode 100644 index 000000000..ca00806d9 --- /dev/null +++ b/src/Makefile.d/platform.mk @@ -0,0 +1,67 @@ +# +# Platform specific options. +# + +PKG_CONFIG?=pkg-config + +ifdef WINDOWSHELL +rmrf?=DEL /S /Q +mkdir?=MD +else +rmrf?=rm -rf +mkdir?=mkdir -p +endif + +ifdef LINUX64 +LINUX=1 +endif + +ifdef MINGW64 +MINGW=1 +endif + +ifdef LINUX +UNIX=1 +ifdef LINUX64 +NONX86=1 +# LINUX64 does not imply X86_64=1; +# could mean ARM64 or Itanium +platform=linux/64 +else +platform=linux +endif +else ifdef FREEBSD +UNIX=1 +platform=freebsd +else ifdef SOLARIS # FIXME +UNIX=1 +platform=solaris +else ifdef CYGWIN32 # FIXME +nasm_format=win32 +platform=cygwin +else ifdef MINGW +ifdef MINGW64 +NONX86=1 +NOASM=1 +# MINGW64 should not necessarily imply X86_64=1, +# but we make that assumption elsewhere +# Once that changes, remove this +X86_64=1 +platform=mingw +else +platform=mingw/64 +endif +include Makefile.d/win32.mk +endif + +ifdef platform +makedir:=$(makedir)/$(platform) +endif + +ifdef UNIX +include Makefile.d/nix.mk +endif + +ifdef SDL +include Makefile.d/sdl.mk +endif diff --git a/src/Makefile.d/sdl.mk b/src/Makefile.d/sdl.mk index 45d0d6ba7..43a2ffced 100644 --- a/src/Makefile.d/sdl.mk +++ b/src/Makefile.d/sdl.mk @@ -1,125 +1,98 @@ # -# sdl/makefile.cfg for SRB2/SDL +# Makefile options for SDL2 backend. # # -#SDL...., *looks at Alam*, THIS IS A MESS! +# SDL...., *looks at Alam*, THIS IS A MESS! +# +# ...a little bird flexes its muscles... # -ifdef UNIXCOMMON -include sdl/MakeNIX.cfg -endif +makedir:=$(makedir)/SDL -ifdef PANDORA -include sdl/SRB2Pandora/Makefile.cfg -endif #ifdef PANDORA +sources+=$(call List,sdl/Sourcefile) +opts+=-DDIRECTFULLSCREEN -DHAVE_SDL -ifdef CYGWIN32 -include sdl/MakeCYG.cfg -endif #ifdef CYGWIN32 +# FIXME +#ifdef PANDORA +#include sdl/SRB2Pandora/Makefile.cfg +#endif #ifdef PANDORA -ifdef SDL_PKGCONFIG -SDL_CFLAGS?=$(shell $(PKG_CONFIG) $(SDL_PKGCONFIG) --cflags) -SDL_LDFLAGS?=$(shell $(PKG_CONFIG) $(SDL_PKGCONFIG) --libs) -else -ifdef PREFIX - SDL_CONFIG?=$(PREFIX)-sdl2-config -else - SDL_CONFIG?=sdl2-config -endif - -ifdef STATIC - SDL_CFLAGS?=$(shell $(SDL_CONFIG) --cflags) - SDL_LDFLAGS?=$(shell $(SDL_CONFIG) --static-libs) -else - SDL_CFLAGS?=$(shell $(SDL_CONFIG) --cflags) - SDL_LDFLAGS?=$(shell $(SDL_CONFIG) --libs) -endif -endif - - - #use the x86 asm code -ifndef CYGWIN32 -ifndef NOASM - USEASM=1 -endif -endif - - OBJS+=$(OBJDIR)/i_video.o $(OBJDIR)/dosstr.o $(OBJDIR)/endtxt.o $(OBJDIR)/hwsym_sdl.o - - OPTS+=-DDIRECTFULLSCREEN -DHAVE_SDL +# FIXME +#ifdef CYGWIN32 +#include sdl/MakeCYG.cfg +#endif #ifdef CYGWIN32 ifndef NOHW - OBJS+=$(OBJDIR)/r_opengl.o $(OBJDIR)/ogl_sdl.o +sources+=sdl/ogl_sdl.c endif ifdef NOMIXER - i_sound_o=$(OBJDIR)/sdl_sound.o +sources+=sdl/sdl_sound.c else - i_sound_o=$(OBJDIR)/mixer_sound.o - OPTS+=-DHAVE_MIXER -ifdef HAVE_MIXERX - OPTS+=-DHAVE_MIXERX - SDL_LDFLAGS+=-lSDL2_mixer_ext -else - SDL_LDFLAGS+=-lSDL2_mixer -endif +opts+=-DHAVE_MIXER +sources+=sdl/mixer_sound.c + + ifdef HAVE_MIXERX + opts+=-DHAVE_MIXERX + libs+=-lSDL2_mixer_ext + else + libs+=-lSDL2_mixer + endif endif ifndef NOTHREADS - OPTS+=-DHAVE_THREADS - OBJS+=$(OBJDIR)/i_threads.o +opts+=-DHAVE_THREADS +sources+=sdl/i_threads.c endif -ifdef SDL_TTF - OPTS+=-DHAVE_TTF - SDL_LDFLAGS+=-lSDL2_ttf -lfreetype -lz - OBJS+=$(OBJDIR)/i_ttf.o +ifdef SDL_PKGCONFIG +$(eval $(call Use_pkg_config,SDL)) +else +SDL_CONFIG?=$(call Prefix,sdl2-config) +SDL_CFLAGS?=$(shell $(SDL_CONFIG) --cflags) +SDL_LDFLAGS?=$(shell $(SDL_CONFIG) \ + $(if $(STATIC),--static-libs,--libs)) +$(eval $(call Propogate_flags,SDL)) endif -ifdef SDL_IMAGE - OPTS+=-DHAVE_IMAGE - SDL_LDFLAGS+=-lSDL2_image +# use the x86 asm code +ifndef CYGWIN32 +ifndef NOASM +USEASM=1 +endif endif -ifdef SDL_NET - OPTS+=-DHAVE_SDLNET - SDL_LDFLAGS+=-lSDL2_net -endif +# FIXME +#ifdef SDL_TTF +# OPTS+=-DHAVE_TTF +# SDL_LDFLAGS+=-lSDL2_ttf -lfreetype -lz +# OBJS+=$(OBJDIR)/i_ttf.o +#endif + +# FIXME +#ifdef SDL_IMAGE +# OPTS+=-DHAVE_IMAGE +# SDL_LDFLAGS+=-lSDL2_image +#endif + +# FIXME +#ifdef SDL_NET +# OPTS+=-DHAVE_SDLNET +# SDL_LDFLAGS+=-lSDL2_net +#endif ifdef MINGW ifndef NOSDLMAIN - SDLMAIN=1 +SDLMAIN=1 endif endif ifdef SDLMAIN - OPTS+=-DSDLMAIN +opts+=-DSDLMAIN else ifdef MINGW - SDL_CFLAGS+=-Umain - SDL_LDFLAGS+=-mconsole +opts+=-Umain +libs+=-mconsole endif endif - -ifndef NOHW -ifdef OPENAL -ifdef MINGW - LIBS:=-lopenal32 $(LIBS) -else - LIBS:=-lopenal $(LIBS) -endif -else -ifdef MINGW -ifdef DS3D - LIBS:=-ldsound -luuid $(LIBS) -endif -endif -endif -endif - -CFLAGS+=$(SDL_CFLAGS) -LIBS:=$(SDL_LDFLAGS) $(LIBS) -ifdef STATIC - LIBS+=$(shell $(SDL_CONFIG) --static-libs) -endif diff --git a/src/Makefile.d/util.mk b/src/Makefile.d/util.mk new file mode 100644 index 000000000..88f141bee --- /dev/null +++ b/src/Makefile.d/util.mk @@ -0,0 +1,89 @@ +# +# Utility macros for the rest of the Makefiles. +# + +Ifnot=$(if $(1),$(3),$(2)) +Ifndef=$(call Ifnot,$($(1)),$(2),$(3)) + +# Match and expand a list of variables by pattern. +Wildvar=$(foreach v,$(filter $(1),$(.VARIABLES)),$($(v))) + +# Read a list of words from file and prepend each with the +# directory of the file. +List=$(addprefix $(dir $(1)),$(file < $(1))) + +define Propogate_flags = +opts+=$$($(1)_CFLAGS) +libs+=$$($(1)_LDFLAGS) +endef + +# Set library's _CFLAGS and _LDFLAGS from some command. +# Automatically propogates the flags too. +# 1: variable prefix (e.g. CURL) +# 2: start of command (e.g. curl-config) +# --- optional ---- +# 3: CFLAGS command arguments, default '--cflags' +# 4: LDFLAGS command arguments, default '--libs' +# 5: common command arguments at the end of command +define Configure = +$(1)_CFLAGS?=$$(shell $(2) $(or $(3),--cflags) $(5)) +$(1)_LDFLAGS?=$$(shell $(2) $(or $(4),--libs) $(5)) +$(call Propogate_flags,$(1)) +endef + +# Configure library with pkg-config. The package name is +# taken from a _PKGCONFIG variable. +# 1: variable prefix +# +# LIBGME_PKGCONFIG=libgme +# $(eval $(call Use_pkg_config,LIBGME)) +define Use_pkg_config = +$(call Configure,$(1),$(PKG_CONFIG),,,$($(1)_PKGCONFIG)) +endef + +# Check disabling flag and configure package in one step +# according to delimited argument. +# (There is only one argument, but it split by slash.) +# 1/: short form library name (uppercase). This is +# prefixed with 'NO' and 'HAVE_'. E.g. NOGME, HAVE_GME +# /2: package name (e.g. libgme) +# /3: variable prefix +# +# The following example would check if NOGME is not +# defined before attempting to define LIBGME_CFLAGS and +# LIBGME_LDFLAGS as with Use_pkg_config. +# +# $(eval $(call Check_pkg_config,GME/libgme/LIBGME)) +define Check_pkg_config = +_p:=$(subst /, ,$(1)) +_v1:=$$(word 1,$$(_p)) +_v2:=$$(or $$(word 3,$$(_p)),$$(_v1)) +ifndef NO$$(_v1) +$$(_v2)_PKGCONFIG?=$$(word 2,$$(_p)) +$$(eval $$(call Use_pkg_config,$$(_v2))) +opts+=-DHAVE_$$(_v1) +endif +endef + +# $(call Prefix,gcc) +Prefix=$(if $(PREFIX),$(PREFIX)-)$(1) + +Echo= +Echo_name= +Print= + +ifndef SILENT +Echo=@echo "$(1)" +ifndef ECHO +ifndef NOECHOFILENAMES +Echo_name=$(call Echo,-- $(1) ...) +endif +endif +ifndef MAKE_RESTARTS +ifndef destructive +Print=$(info $(1)) +endif +endif +endif + +.=$(call Ifndef,ECHO,@) diff --git a/src/Makefile.d/versions.mk b/src/Makefile.d/versions.mk index 075cd2d3a..fe2b6b851 100644 --- a/src/Makefile.d/versions.mk +++ b/src/Makefile.d/versions.mk @@ -1,215 +1,23 @@ -# vim: ft=make # -# Makefile.cfg for SRB2 +# Flags to put a sock in GCC! # -# -# GNU compiler & tools' flags -# and other things -# - -# See the following variable don't start with 'GCC'. This is -# to avoid a false positive with the version detection... - -SUPPORTED_GCC_VERSIONS:=\ - 101 102\ - 91 92 93\ - 81 82 83 84\ - 71 72 73 74 75\ - 61 62 63 64\ - 51 52 53 54 55\ - 40 41 42 43 44 45 46 47 48 49 - -LATEST_GCC_VERSION=10.2 - -# gcc or g++ -ifdef PREFIX - CC=$(PREFIX)-gcc - CXX=$(PREFIX)-g++ - OBJCOPY=$(PREFIX)-objcopy - OBJDUMP=$(PREFIX)-objdump - STRIP=$(PREFIX)-strip - WINDRES=$(PREFIX)-windres -else - OBJCOPY=objcopy - OBJDUMP=objdump - STRIP=strip - WINDRES=windres +# See the versions list in detect.mk +# This will define all version flags going backward. +# Yes, it's magic. +define _predecessor = +ifdef GCC$(firstword $(1)) +GCC$(lastword $(1)):=1 endif +endef +_n:=$(words $(gcc_versions)) +$(foreach v,$(join $(wordlist 2,$(_n),- $(gcc_versions)),\ + $(addprefix =,$(wordlist 2,$(_n),$(gcc_versions)))),\ + $(and $(findstring =,$(v)),\ + $(eval $(call _predecessor,$(subst =, ,$(v)))))) -# because Apple screws with us on this -# need to get bintools from homebrew -ifdef MACOSX - CC=clang - CXX=clang - OBJCOPY=gobjcopy - OBJDUMP=gobjdump -endif - -# Automatically set version flag, but not if one was manually set -# And don't bother if this is a clean only run -ifeq (,$(filter GCC% CLEANONLY,$(.VARIABLES))) - version:=$(shell $(CC) --version) - # check if this is in fact GCC - ifneq (,$(or $(findstring gcc,$(version)),$(findstring GCC,$(version)))) - version:=$(shell $(CC) -dumpversion) - - # Turn version into words of major, minor - v:=$(subst ., ,$(version)) - # concat. major minor - v:=$(word 1,$(v))$(word 2,$(v)) - - # If this version is not in the list, default to the latest supported - ifeq (,$(filter $(v),$(SUPPORTED_GCC_VERSIONS))) - define line = - Your compiler version, GCC $(version), is not supported by the Makefile. - The Makefile will assume GCC $(LATEST_GCC_VERSION).)) - endef - $(call print,$(line)) - GCC$(subst .,,$(LATEST_GCC_VERSION))=1 - else - $(call print,Detected GCC $(version) (GCC$(v))) - GCC$(v)=1 - endif - endif -endif - -ifdef GCC102 -GCC101=1 -endif - -ifdef GCC101 -GCC93=1 -endif - -ifdef GCC93 -GCC92=1 -endif - -ifdef GCC92 -GCC91=1 -endif - -ifdef GCC91 -GCC84=1 -endif - -ifdef GCC84 -GCC83=1 -endif - -ifdef GCC83 -GCC82=1 -endif - -ifdef GCC82 -GCC81=1 -endif - -ifdef GCC81 -GCC75=1 -endif - -ifdef GCC75 -GCC74=1 -endif - -ifdef GCC74 -GCC73=1 -endif - -ifdef GCC73 -GCC72=1 -endif - -ifdef GCC72 -GCC71=1 -endif - -ifdef GCC71 -GCC64=1 -endif - -ifdef GCC64 -GCC63=1 -endif - -ifdef GCC63 -GCC62=1 -endif - -ifdef GCC62 -GCC61=1 -endif - -ifdef GCC61 -GCC55=1 -endif - -ifdef GCC55 -GCC54=1 -endif - -ifdef GCC54 -GCC53=1 -endif - -ifdef GCC53 -GCC52=1 -endif - -ifdef GCC52 -GCC51=1 -endif - -ifdef GCC51 -GCC49=1 -endif - -ifdef GCC49 -GCC48=1 -endif - -ifdef GCC48 -GCC47=1 -endif - -ifdef GCC47 -GCC46=1 -endif - -ifdef GCC46 -GCC45=1 -endif - -ifdef GCC45 -GCC44=1 -endif - -ifdef GCC44 -GCC43=1 -endif - -ifdef GCC43 -GCC42=1 -endif - -ifdef GCC42 -GCC41=1 -endif - -ifdef GCC41 -GCC40=1 -VCHELP=1 -endif - -ifdef GCC295 -GCC29=1 -endif - -OLDWFLAGS:=$(WFLAGS) # -W -Wno-unused -WFLAGS=-Wall +WFLAGS:=-Wall ifndef GCC295 #WFLAGS+=-Wno-packed endif @@ -222,15 +30,13 @@ endif #WFLAGS+=-Wsystem-headers WFLAGS+=-Wfloat-equal #WFLAGS+=-Wtraditional -ifdef VCHELP - WFLAGS+=-Wdeclaration-after-statement - WFLAGS+=-Wno-error=declaration-after-statement -endif WFLAGS+=-Wundef ifndef GCC295 WFLAGS+=-Wendif-labels endif ifdef GCC41 + WFLAGS+=-Wdeclaration-after-statement + WFLAGS+=-Wno-error=declaration-after-statement WFLAGS+=-Wshadow endif #WFLAGS+=-Wlarger-than-%len% @@ -308,8 +114,6 @@ ifdef ERRORMODE WFLAGS+=-Werror endif -WFLAGS+=$(OLDWFLAGS) - ifdef GCC43 #WFLAGS+=-Wno-error=clobbered endif @@ -338,141 +142,36 @@ ifdef GCC81 WFLAGS+=-Wno-error=multistatement-macros endif - -#indicate platform and what interface use with -ifndef LINUX -ifndef FREEBSD -ifndef CYGWIN32 -ifndef MINGW -ifndef MINGW64 -ifndef SDL -ifndef DUMMY -$(error No interface or platform flag defined) -endif -endif -endif -endif -endif -endif -endif - -#determine the interface directory (where you put all i_*.c) -i_net_o=$(OBJDIR)/i_net.o -i_system_o=$(OBJDIR)/i_system.o -i_sound_o=$(OBJDIR)/i_sound.o -i_main_o=$(OBJDIR)/i_main.o -#set OBJDIR and BIN's starting place -OBJDIR=../objs -BIN=../bin -DEPDIR=../dep -#Nasm ASM and rm -ifdef YASM -NASM?=yasm +ifdef NONX86 + ifdef X86_64 # yeah that SEEMS contradictory + opts+=-march=nocona + endif else -NASM?=nasm -endif -REMOVE?=rm -f -MKDIR?=mkdir -p -GZIP?=gzip -GZIP_OPTS?=-9 -f -n -GZIP_OPT2=$(GZIP_OPTS) --rsyncable -UPX?=upx -UPX_OPTS?=--best --preserve-build-id -ifndef ECHO -UPX_OPTS+=-q + ifndef GCC29 + opts+=-msse3 -mfpmath=sse + else + opts+=-mpentium + endif endif -#Interface Setup -ifdef DUMMY - INTERFACE=dummy - OBJDIR:=$(OBJDIR)/dummy - BIN:=$(BIN)/dummy - DEPDIR:=$(DEPDIR)/dummy -else -ifdef LINUX - NASMFORMAT=elf -DLINUX - SDL=1 -ifdef LINUX64 - OBJDIR:=$(OBJDIR)/Linux64 - BIN:=$(BIN)/Linux64 - DEPDIR:=$(DEPDIR)/Linux64 -else - OBJDIR:=$(OBJDIR)/Linux - BIN:=$(BIN)/Linux - DEPDIR:=$(DEPDIR)/Linux -endif -else -ifdef FREEBSD - INTERFACE=sdl - NASMFORMAT=elf -DLINUX - SDL=1 - - OBJDIR:=$(OBJDIR)/FreeBSD - BIN:=$(BIN)/FreeBSD - DEPDIR:=$(DEPDIR)/Linux -else -ifdef SOLARIS - INTERFACE=sdl - NASMFORMAT=elf -DLINUX - SDL=1 - - OBJDIR:=$(OBJDIR)/Solaris - BIN:=$(BIN)/Solaris - DEPDIR:=$(DEPDIR)/Solaris -else -ifdef CYGWIN32 - INTERFACE=sdl - NASMFORMAT=win32 - SDL=1 - - OBJDIR:=$(OBJDIR)/cygwin - BIN:=$(BIN)/Cygwin - DEPDIR:=$(DEPDIR)/Cygwin -else -ifdef MINGW64 - #NASMFORMAT=win64 - SDL=1 - OBJDIR:=$(OBJDIR)/Mingw64 - BIN:=$(BIN)/Mingw64 - DEPDIR:=$(DEPDIR)/Mingw64 -else -ifdef MINGW - NASMFORMAT=win32 - SDL=1 - OBJDIR:=$(OBJDIR)/Mingw - BIN:=$(BIN)/Mingw - DEPDIR:=$(DEPDIR)/Mingw -endif -endif -endif -endif -endif -endif -endif - -ifdef ARCHNAME - OBJDIR:=$(OBJDIR)/$(ARCHNAME) - BIN:=$(BIN)/$(ARCHNAME) - DEPDIR:=$(DEPDIR)/$(ARCHNAME) -endif - -OBJDUMP_OPTS?=--wide --source --line-numbers -LD=$(CC) - -ifdef SDL - INTERFACE=sdl - OBJDIR:=$(OBJDIR)/SDL - DEPDIR:=$(DEPDIR)/SDL -endif - -ifndef DUMMY ifdef DEBUGMODE - OBJDIR:=$(OBJDIR)/Debug - BIN:=$(BIN)/Debug - DEPDIR:=$(DEPDIR)/Debug +ifdef GCC48 +opts+=-Og else - OBJDIR:=$(OBJDIR)/Release - BIN:=$(BIN)/Release - DEPDIR:=$(DEPDIR)/Release +opts+=O0 +endif +endif + +ifdef VALGRIND +ifdef GCC46 +WFLAGS+=-Wno-error=unused-but-set-variable +WFLAGS+=-Wno-unused-but-set-variable +endif +endif + +# Lua +ifdef GCC43 +ifndef GCC44 +WFLAGS+=-Wno-logical-op endif endif diff --git a/src/Makefile.d/win32.mk b/src/Makefile.d/win32.mk index 702ae3765..0c671b268 100644 --- a/src/Makefile.d/win32.mk +++ b/src/Makefile.d/win32.mk @@ -1,136 +1,99 @@ # -# win32/Makefile.cfg for SRB2/Minwgw +# Mingw, if you don't know, that's Win32/Win64 # -# -#Mingw, if you don't know, that's Win32/Win64 -# +ifndef MINGW64 +EXENAME?=srb2win.exe +else +EXENAME?=srb2win64.exe +endif + +sources+=win32/Srb2win.rc +opts+=-DSTDC_HEADERS +libs+=-ladvapi32 -lkernel32 -lmsvcrt -luser32 + +nasm_format:=win32 + +SDL=1 + +ifndef NOHW +opts+=-DUSE_WGL_SWAP +endif ifdef MINGW64 - HAVE_LIBGME=1 - LIBGME_CFLAGS=-I../libs/gme/include - LIBGME_LDFLAGS=-L../libs/gme/win64 -lgme -ifdef HAVE_OPENMPT - LIBOPENMPT_CFLAGS?=-I../libs/libopenmpt/inc - LIBOPENMPT_LDFLAGS?=-L../libs/libopenmpt/lib/x86_64/mingw -lopenmpt -endif -ifndef NOMIXERX - HAVE_MIXERX=1 - SDL_CFLAGS?=-I../libs/SDL2/x86_64-w64-mingw32/include/SDL2 -I../libs/SDLMixerX/x86_64-w64-mingw32/include/SDL2 -Dmain=SDL_main - SDL_LDFLAGS?=-L../libs/SDL2/x86_64-w64-mingw32/lib -L../libs/SDLMixerX/x86_64-w64-mingw32/lib -lmingw32 -lSDL2main -lSDL2 -mwindows +libs+=-lws2_32 else - SDL_CFLAGS?=-I../libs/SDL2/x86_64-w64-mingw32/include/SDL2 -I../libs/SDL2_mixer/x86_64-w64-mingw32/include/SDL2 -Dmain=SDL_main - SDL_LDFLAGS?=-L../libs/SDL2/x86_64-w64-mingw32/lib -L../libs/SDL2_mixer/x86_64-w64-mingw32/lib -lmingw32 -lSDL2main -lSDL2 -mwindows -endif +ifdef NO_IPV6 +libs+=-lwsock32 else - HAVE_LIBGME=1 - LIBGME_CFLAGS=-I../libs/gme/include - LIBGME_LDFLAGS=-L../libs/gme/win32 -lgme -ifdef HAVE_OPENMPT - LIBOPENMPT_CFLAGS?=-I../libs/libopenmpt/inc - LIBOPENMPT_LDFLAGS?=-L../libs/libopenmpt/lib/x86/mingw -lopenmpt +libs+=-lws2_32 endif -ifndef NOMIXERX - HAVE_MIXERX=1 - SDL_CFLAGS?=-I../libs/SDL2/i686-w64-mingw32/include/SDL2 -I../libs/SDLMixerX/i686-w64-mingw32/include/SDL2 -Dmain=SDL_main - SDL_LDFLAGS?=-L../libs/SDL2/i686-w64-mingw32/lib -L../libs/SDLMixerX/i686-w64-mingw32/lib -lmingw32 -lSDL2main -lSDL2 -mwindows -else - SDL_CFLAGS?=-I../libs/SDL2/i686-w64-mingw32/include/SDL2 -I../libs/SDL2_mixer/i686-w64-mingw32/include/SDL2 -Dmain=SDL_main - SDL_LDFLAGS?=-L../libs/SDL2/i686-w64-mingw32/lib -L../libs/SDL2_mixer/i686-w64-mingw32/lib -lmingw32 -lSDL2main -lSDL2 -mwindows -endif -endif - -ifndef NOASM - USEASM=1 endif ifndef NONET -ifndef MINGW64 #miniupnc is broken with MINGW64 - HAVE_MINIUPNPC=1 +ifndef MINGW64 # miniupnc is broken with MINGW64 +opts+=-I../libs -DSTATIC_MINIUPNPC +libs+=-L../libs/miniupnpc/mingw$(32) -lws2_32 -liphlpapi endif endif - OPTS=-DSTDC_HEADERS - -ifndef GCC44 - #OPTS+=-mms-bitfields -endif - - LIBS+=-ladvapi32 -lkernel32 -lmsvcrt -luser32 -ifdef MINGW64 - LIBS+=-lws2_32 +ifndef MINGW64 +32=32 +x86=x86 +i686=i686 else -ifdef NO_IPV6 - LIBS+=-lwsock32 +32=64 +x86=x86_64 +i686=x86_64 +endif + +mingw:=$(i686)-w64-mingw32 + +define _set = +$(1)_CFLAGS?=$($(1)_opts) +$(1)_LDFLAGS?=$($(1)_libs) +endef + +lib:=../libs/gme +LIBGME_opts:=-I$(lib)/include +LIBGME_libs:=-L$(lib)/win$(32) -lgme +$(eval $(call _set,LIBGME)) + +lib:=../libs/libopenmpt +LIBOPENMPT_opts:=-I$(lib)/inc +LIBOPENMPT_libs:=-L$(lib)/lib/$(x86)/mingw -lopenmpt +$(eval $(call _set,LIBOPENMPT)) + +ifndef NOMIXERX +HAVE_MIXERX=1 +lib:=../libs/SDLMixerX/$(mingw) else - LIBS+=-lws2_32 -endif +lib:=../libs/SDL2_mixer/$(mingw) endif - # name of the exefile - EXENAME?=srb2win.exe +mixer_opts:=-I$(lib)/include/SDL2 +mixer_libs:=-L$(lib)/lib -ifdef SDL - i_system_o+=$(OBJDIR)/SRB2.res - #i_main_o+=$(OBJDIR)/win_dbg.o -ifndef NOHW - OPTS+=-DUSE_WGL_SWAP -endif -endif +lib:=../libs/SDL2/$(mingw) +SDL_opts:=-I$(lib)/include/SDL2\ + $(mixer_opts) -Dmain=SDL_main +SDL_libs:=-L$(lib)/lib $(mixer_libs)\ + -lmingw32 -lSDL2main -lSDL2 -mwindows +$(eval $(call _set,SDL)) +lib:=../libs/zlib +ZLIB_opts:=-I$(lib) +ZLIB_libs:=-L$(lib)/win32 -lz$(32) +$(eval $(call _set,ZLIB)) -ZLIB_CFLAGS?=-I../libs/zlib -ifdef MINGW64 -ZLIB_LDFLAGS?=-L../libs/zlib/win32 -lz64 -else -ZLIB_LDFLAGS?=-L../libs/zlib/win32 -lz32 -endif - -ifndef NOPNG ifndef PNG_CONFIG - PNG_CFLAGS?=-I../libs/libpng-src -ifdef MINGW64 - PNG_LDFLAGS?=-L../libs/libpng-src/projects -lpng64 -else - PNG_LDFLAGS?=-L../libs/libpng-src/projects -lpng32 -endif #MINGW64 -endif #PNG_CONFIG -endif #NOPNG - -ifdef GETTEXT -ifndef CCBS - MSGFMT?=../libs/gettext/bin32/msgfmt.exe -endif -ifdef MINGW64 - CPPFLAGS+=-I../libs/gettext/include64 - LDFLAGS+=-L../libs/gettext/lib64 - LIBS+=-lmingwex -else - CPPFLAGS+=-I../libs/gettext/include32 - LDFLAGS+=-L../libs/gettext/lib32 - STATIC_GETTEXT=1 -endif #MINGW64 -ifdef STATIC_GETTEXT - LIBS+=-lasprintf -lintl -else - LIBS+=-lintl.dll -endif #STATIC_GETTEXT -endif #GETTEXT - -ifdef HAVE_MINIUPNPC - CPPFLAGS+=-I../libs/ -DSTATIC_MINIUPNPC -ifdef MINGW64 - LDFLAGS+=-L../libs/miniupnpc/mingw64 -else - LDFLAGS+=-L../libs/miniupnpc/mingw32 -endif #MINGW64 +lib:=../libs/libpng-src +PNG_opts:=-I$(lib) +PNG_libs:=-L$(lib)/projects -lpng$(32) +$(eval $(call _set,PNG)) endif -ifndef NOCURL - CURL_CFLAGS+=-I../libs/curl/include -ifdef MINGW64 - CURL_LDFLAGS+=-L../libs/curl/lib64 -lcurl -else - CURL_LDFLAGS+=-L../libs/curl/lib32 -lcurl -endif #MINGW64 -endif +lib:=../libs/curl +CURL_opts:=-I$(lib)/include +CURL_libs:=-L$(lib)/lib$(32) -lcurl +$(eval $(call _set,CURL)) diff --git a/src/Sourcefile b/src/Sourcefile new file mode 100644 index 000000000..9f27f2810 --- /dev/null +++ b/src/Sourcefile @@ -0,0 +1,87 @@ +string.c +d_main.c +d_clisrv.c +d_net.c +d_netfil.c +d_netcmd.c +dehacked.c +z_zone.c +f_finale.c +f_wipe.c +g_demo.c +g_game.c +g_input.c +am_map.c +command.c +console.c +hu_stuff.c +y_inter.c +st_stuff.c +m_aatree.c +m_anigif.c +m_argv.c +m_bbox.c +m_cheat.c +m_cond.c +m_fixed.c +m_menu.c +m_misc.c +m_random.c +m_queue.c +info.c +p_ceilng.c +p_enemy.c +p_floor.c +p_inter.c +p_lights.c +p_map.c +p_maputl.c +p_mobj.c +p_polyobj.c +p_saveg.c +p_setup.c +p_sight.c +p_spec.c +p_telept.c +p_tick.c +p_user.c +p_slopes.c +tables.c +r_bsp.c +r_data.c +r_draw.c +r_main.c +r_plane.c +r_segs.c +r_skins.c +r_sky.c +r_splats.c +r_things.c +r_textures.c +r_picformats.c +r_portal.c +screen.c +v_video.c +s_sound.c +sounds.c +w_wad.c +filesrch.c +mserv.c +http-mserv.c +i_tcp.c +lzf.c +vid_copy.s +b_bot.c +lua_script.c +lua_baselib.c +lua_mathlib.c +lua_hooklib.c +lua_consolelib.c +lua_infolib.c +lua_mobjlib.c +lua_playerlib.c +lua_skinlib.c +lua_thinkerlib.c +lua_maplib.c +lua_blockmaplib.c +lua_hudlib.c diff --git a/src/blua/Sourcefile b/src/blua/Sourcefile new file mode 100644 index 000000000..f99c89c8d --- /dev/null +++ b/src/blua/Sourcefile @@ -0,0 +1,25 @@ +lapi.c +lbaselib.c +ldo.c +lfunc.c +linit.c +liolib.c +llex.c +lmem.c +lobject.c +lstate.c +lstrlib.c +ltablib.c +lundump.c +lzio.c +lauxlib.c +lcode.c +ldebug.c +ldump.c +lgc.c +lopcodes.c +lparser.c +lstring.c +ltable.c +ltm.c +lvm.c diff --git a/src/hardware/Sourcefile b/src/hardware/Sourcefile new file mode 100644 index 000000000..1c05de76c --- /dev/null +++ b/src/hardware/Sourcefile @@ -0,0 +1,13 @@ +hw_bsp.c +hw_draw.c +hw_light.c +hw_main.c +hw_clip.c +hw_md2.c +hw_cache.c +hw_md2load.c +hw_md3load.c +hw_model.c +u_list.c +hw_batching.c +r_opengl/r_opengl.c diff --git a/src/sdl/Sourcefile b/src/sdl/Sourcefile new file mode 100644 index 000000000..82d5ce073 --- /dev/null +++ b/src/sdl/Sourcefile @@ -0,0 +1,7 @@ +i_net.c +i_system.c +i_main.c +i_video.c +dosstr.c +endtxt.c +hwsym_sdl.c From 53d1cbe8264196e46911c86bc4be13d44aa35dfe Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 4 May 2021 16:50:50 -0700 Subject: [PATCH 434/644] Appveyor: update executable directory --- appveyor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 2acc2f712..d9cff5333 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -100,9 +100,9 @@ build_script: after_build: - if [%X86_64%] == [1] ( - set "BUILD_PATH=bin\Mingw64\Release" + set "BUILD_PATH=bin\64" ) else ( - set "BUILD_PATH=bin\Mingw\Release" + set "BUILD_PATH=bin" ) - if [%X86_64%] == [1] ( set "CONFIGURATION=%CONFIGURATION%64" ) - ccache -s From 888073d64d1885cae0ad8b5d54bfec31e9793e0a Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 4 May 2021 16:54:47 -0700 Subject: [PATCH 435/644] Fix make clean printing header --- src/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index dafec3645..8c31b212d 100644 --- a/src/Makefile +++ b/src/Makefile @@ -285,7 +285,7 @@ ifndef SILENT # makefile will 'restart' when it finishes including the # dependencies. ifndef MAKE_RESTARTS -ifndef destrutive +ifndef destructive $(shell $(CC) -v) define flags = From 8840bef2cb7c1913599d4c17b5027988638b50c8 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 4 May 2021 17:05:17 -0700 Subject: [PATCH 436/644] Appveyor: update to correct executable directory this time --- appveyor.yml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index d9cff5333..8a20986cf 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -99,16 +99,11 @@ build_script: - cmd: mingw32-make.exe %SRB2_MFLAGS% ERRORMODE=1 -k after_build: -- if [%X86_64%] == [1] ( - set "BUILD_PATH=bin\64" - ) else ( - set "BUILD_PATH=bin" - ) - if [%X86_64%] == [1] ( set "CONFIGURATION=%CONFIGURATION%64" ) - ccache -s - set BUILD_ARCHIVE=%REPO%-%GITSHORT%-%CONFIGURATION%.7z - set BUILDSARCHIVE=%REPO%-%CONFIGURATION%.7z -- cmd: 7z a %BUILD_ARCHIVE% %BUILD_PATH% -xr!.gitignore +- cmd: 7z a %BUILD_ARCHIVE% bin -xr!.gitignore - appveyor PushArtifact %BUILD_ARCHIVE% #- cmd: copy %BUILD_ARCHIVE% %BUILDSARCHIVE% #- appveyor PushArtifact %BUILDSARCHIVE% From 3d7205d4942d1e1b2627fdf5acf9d9c82437a97b Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 4 May 2021 22:34:20 -0700 Subject: [PATCH 437/644] Fix minor errors with Windows ECHO, DEL, MD - Quotes were not removed by ECHO. - DEL would print an error on nonexistent file. - MD would do this plus return a nonzero exit code. --- src/Makefile | 10 ++++++---- src/Makefile.d/platform.mk | 8 ++++---- src/Makefile.d/util.mk | 5 ++++- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/Makefile b/src/Makefile index 8c31b212d..0c44afe55 100644 --- a/src/Makefile +++ b/src/Makefile @@ -315,7 +315,7 @@ WINDRES:=$(WINDRES) $(WINDRESFLAGS)\ $(debug_opts) --include-dir=win32 -O coff %/ : - $(.)$(mkdir) $@ + $(.)$(mkdir) $(call Windows_path,$@) # this is needed so the target can be referenced in the # prerequisites @@ -385,14 +385,16 @@ $(eval $(call _recipe,o,nas,$(NASM) -o $$@ $$<)) $(eval $(call _recipe,o,s,$(CC) $(ASFLAGS) -c -o $$@ $$<)) $(eval $(call _recipe,res,rc,$(WINDRES) -i $$< -o $$@)) +_rm=$(.)$(rmrf) $(call Windows_path,$(1)) + cleandep : - $(.)$(rmrf) $(depends) comptime.h + $(call _rm,$(depends) comptime.h) clean : - $(.)$(rmrf) $(exe) $(dbg) $(dbg).txt $(objects) + $(call _rm,$(exe) $(dbg) $(dbg).txt $(objects)) distclean : - $(.)$(rmrf) ../bin ../objs ../deps comptime.h + $(call _rm,../bin ../objs ../deps comptime.h) info: ifdef WINDOWSHELL diff --git a/src/Makefile.d/platform.mk b/src/Makefile.d/platform.mk index ca00806d9..4f110594e 100644 --- a/src/Makefile.d/platform.mk +++ b/src/Makefile.d/platform.mk @@ -5,11 +5,11 @@ PKG_CONFIG?=pkg-config ifdef WINDOWSHELL -rmrf?=DEL /S /Q -mkdir?=MD +rmrf=2>NUL DEL /S /Q +mkdir=-2>NUL MD else -rmrf?=rm -rf -mkdir?=mkdir -p +rmrf=rm -rf +mkdir=mkdir -p endif ifdef LINUX64 diff --git a/src/Makefile.d/util.mk b/src/Makefile.d/util.mk index 88f141bee..e76e32422 100644 --- a/src/Makefile.d/util.mk +++ b/src/Makefile.d/util.mk @@ -12,6 +12,9 @@ Wildvar=$(foreach v,$(filter $(1),$(.VARIABLES)),$($(v))) # directory of the file. List=$(addprefix $(dir $(1)),$(file < $(1))) +# Convert path separators to backslash on Windows. +Windows_path=$(if $(WINDOWSHELL),$(subst /,\,$(1)),$(1)) + define Propogate_flags = opts+=$$($(1)_CFLAGS) libs+=$$($(1)_LDFLAGS) @@ -73,7 +76,7 @@ Echo_name= Print= ifndef SILENT -Echo=@echo "$(1)" +Echo=@echo $(1) ifndef ECHO ifndef NOECHOFILENAMES Echo_name=$(call Echo,-- $(1) ...) From f9813844e7f0dfa6229062b1ebd83e4e8150c120 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 5 May 2021 03:56:57 -0700 Subject: [PATCH 438/644] Update CMakeLists.txt to use Sourcefiles This establishes (near) parity of source code file lists between the Makefile and CMakeLists.txt To make that change I messed around CMakeLists.txt a bit. It now uses target_sources and target_compile_definitions. I also removed some MSVC stuff since we don't actually care about MSVC--it made things easier. CMake minimum version 3.0 -> 3.13 for target_sources. --- CMakeLists.txt | 17 +- src/CMakeLists.txt | 383 ++---------------------------------- src/blua/CMakeLists.txt | 1 + src/hardware/CMakeLists.txt | 1 + src/sdl/CMakeLists.txt | 136 ++----------- 5 files changed, 47 insertions(+), 491 deletions(-) create mode 100644 src/blua/CMakeLists.txt create mode 100644 src/hardware/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 148f17ef0..bc764fc87 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.0) +cmake_minimum_required(VERSION 3.13) # Enable CCache early set(SRB2_USE_CCACHE OFF CACHE BOOL "Use CCache") @@ -34,12 +34,11 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/") ### Useful functions -# Prepend sources with current source directory -function(prepend_sources SOURCE_FILES) - foreach(SOURCE_FILE ${${SOURCE_FILES}}) - set(MODIFIED ${MODIFIED} ${CMAKE_CURRENT_SOURCE_DIR}/${SOURCE_FILE}) - endforeach() - set(${SOURCE_FILES} ${MODIFIED} PARENT_SCOPE) +# Add sources from Sourcefile +function(target_sourcefile type) + file(STRINGS Sourcefile list + REGEX "[-0-9A-Za-z_]+\.${type}") + target_sources(SRB2SDL2 PRIVATE ${list}) endfunction() # Macro to add OSX framework @@ -118,8 +117,10 @@ set(SRB2_SDL2_EXE_NAME srb2 CACHE STRING "Executable binary output name") include_directories(${CMAKE_CURRENT_BINARY_DIR}/src) +add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32) + add_subdirectory(src) -#add_subdirectory(assets) +add_subdirectory(assets) ## config.h generation diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 47a790194..0148d605f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,224 +1,12 @@ # SRB2 Core # Core sources -set(SRB2_CORE_SOURCES - am_map.c - b_bot.c - command.c - comptime.c - console.c - d_clisrv.c - d_main.c - d_net.c - d_netcmd.c - d_netfil.c - dehacked.c - f_finale.c - f_wipe.c - filesrch.c - g_demo.c - g_game.c - g_input.c - hu_stuff.c - i_tcp.c - info.c - lzf.c - m_aatree.c - m_anigif.c - m_argv.c - m_bbox.c - m_cheat.c - m_cond.c - m_fixed.c - m_menu.c - m_misc.c - m_queue.c - m_random.c - md5.c - mserv.c - http-mserv.c - s_sound.c - screen.c - sounds.c - st_stuff.c - #string.c - tables.c - v_video.c - w_wad.c - y_inter.c - z_zone.c -) +target_sourcefile(c) +target_sources(SRB2SDL2 PRIVATE comptime.c md5.c config.h) -set(SRB2_CORE_HEADERS - am_map.h - b_bot.h - byteptr.h - command.h - console.h - d_clisrv.h - d_event.h - d_main.h - d_net.h - d_netcmd.h - d_netfil.h - d_player.h - d_think.h - d_ticcmd.h - dehacked.h - doomdata.h - doomdef.h - doomstat.h - doomtype.h - endian.h - f_finale.h - fastcmp.h - filesrch.h - g_demo.h - g_game.h - g_input.h - g_state.h - hu_stuff.h - i_joy.h - i_net.h - i_sound.h - i_system.h - i_tcp.h - i_video.h - info.h - keys.h - lzf.h - m_aatree.h - m_anigif.h - m_argv.h - m_bbox.h - m_cheat.h - m_cond.h - m_dllist.h - m_fixed.h - m_menu.h - m_misc.h - m_queue.h - m_random.h - m_swap.h - md5.h - mserv.h - p5prof.h - s_sound.h - screen.h - sounds.h - st_stuff.h - tables.h - v_video.h - w_wad.h - y_inter.h - z_zone.h - - config.h.in -) - -set(SRB2_CORE_RENDER_SOURCES - r_bsp.c - r_data.c - r_draw.c - r_main.c - r_plane.c - r_segs.c - r_skins.c - r_sky.c - r_splats.c - r_things.c - r_textures.c - r_picformats.c - r_portal.c - - r_bsp.h - r_data.h - r_defs.h - r_draw.h - r_local.h - r_main.h - r_plane.h - r_segs.h - r_skins.h - r_sky.h - r_splats.h - r_state.h - r_things.h - r_textures.h - r_picformats.h - r_portal.h -) - -set(SRB2_CORE_GAME_SOURCES - p_ceilng.c - p_enemy.c - p_floor.c - p_inter.c - p_lights.c - p_map.c - p_maputl.c - p_mobj.c - p_polyobj.c - p_saveg.c - p_setup.c - p_sight.c - p_slopes.c - p_spec.c - p_telept.c - p_tick.c - p_user.c - - p_local.h - p_maputl.h - p_mobj.h - p_polyobj.h - p_pspr.h - p_saveg.h - p_setup.h - p_slopes.h - p_spec.h - p_tick.h -) - -if(NOT (CMAKE_CXX_COMPILER_ID MATCHES "Clang")) - set(SRB2_CORE_SOURCES ${SRB2_CORE_SOURCES} string.c) -endif() - -prepend_sources(SRB2_CORE_SOURCES) -prepend_sources(SRB2_CORE_HEADERS) -prepend_sources(SRB2_CORE_RENDER_SOURCES) -prepend_sources(SRB2_CORE_GAME_SOURCES) - -set(SRB2_CORE_HEADERS ${SRB2_CORE_HEADERS} ${CMAKE_CURRENT_BINARY_DIR}/config.h) -source_group("Main" FILES ${SRB2_CORE_SOURCES} ${SRB2_CORE_HEADERS}) -source_group("Renderer" FILES ${SRB2_CORE_RENDER_SOURCES}) -source_group("Game" FILES ${SRB2_CORE_GAME_SOURCES}) - - -set(SRB2_ASM_SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/vid_copy.s -) - -set(SRB2_NASM_SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/tmap_mmx.nas - ${CMAKE_CURRENT_SOURCE_DIR}/tmap.nas -) - -if(MSVC) - list(APPEND SRB2_NASM_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/tmap_vc.nas) -endif() - -set(SRB2_NASM_OBJECTS - ${CMAKE_CURRENT_BINARY_DIR}/tmap_mmx.obj - ${CMAKE_CURRENT_BINARY_DIR}/tmap.obj -) - -if(MSVC) - list(APPEND SRB2_NASM_OBJECTS ${CMAKE_CURRENT_BINARY_DIR}/tmap_vc.obj) -endif() - -source_group("Assembly" FILES ${SRB2_ASM_SOURCES} ${SRB2_NASM_SOURCES}) +set(SRB2_ASM_SOURCES vid_copy.s) +set(SRB2_NASM_SOURCES tmap_mmx.nas tmap.nas) ### Configuration set(SRB2_CONFIG_HAVE_PNG ON CACHE BOOL @@ -254,90 +42,7 @@ if(${CMAKE_SYSTEM} MATCHES "Windows") ###set on Windows only "Use SRB2's internal copies of required dependencies (SDL2, PNG, zlib, GME, OpenMPT).") endif() -set(SRB2_LUA_SOURCES - lua_baselib.c - lua_blockmaplib.c - lua_consolelib.c - lua_hooklib.c - lua_hudlib.c - lua_infolib.c - lua_maplib.c - lua_mathlib.c - lua_mobjlib.c - lua_playerlib.c - lua_script.c - lua_skinlib.c - lua_thinkerlib.c -) -set(SRB2_LUA_HEADERS - lua_hook.h - lua_hud.h - lua_libs.h - lua_script.h -) - -prepend_sources(SRB2_LUA_SOURCES) -prepend_sources(SRB2_LUA_HEADERS) - -source_group("LUA" FILES ${SRB2_LUA_SOURCES} ${SRB2_LUA_HEADERS}) - -set(SRB2_BLUA_SOURCES - blua/lapi.c - blua/lauxlib.c - blua/lbaselib.c - blua/lcode.c - blua/ldebug.c - blua/ldo.c - blua/ldump.c - blua/lfunc.c - blua/lgc.c - blua/linit.c - blua/liolib.c - blua/llex.c - blua/lmem.c - blua/lobject.c - blua/lopcodes.c - blua/lparser.c - blua/lstate.c - blua/lstring.c - blua/lstrlib.c - blua/ltable.c - blua/ltablib.c - blua/ltm.c - blua/lundump.c - blua/lvm.c - blua/lzio.c -) -set(SRB2_BLUA_HEADERS - blua/lapi.h - blua/lauxlib.h - blua/lcode.h - blua/ldebug.h - blua/ldo.h - blua/lfunc.h - blua/lgc.h - blua/llex.h - blua/llimits.h - blua/lmem.h - blua/lobject.h - blua/lopcodes.h - blua/lparser.h - blua/lstate.h - blua/lstring.h - blua/ltable.h - blua/ltm.h - blua/lua.h - blua/luaconf.h - blua/lualib.h - blua/lundump.h - blua/lvm.h - blua/lzio.h -) - -prepend_sources(SRB2_BLUA_SOURCES) -prepend_sources(SRB2_BLUA_HEADERS) - -source_group("LUA\\Interpreter" FILES ${SRB2_BLUA_SOURCES} ${SRB2_BLUA_HEADERS}) +add_subdirectory(blua) if(${SRB2_CONFIG_HAVE_GME}) if(${SRB2_CONFIG_USE_INTERNAL_LIBRARIES}) @@ -353,7 +58,7 @@ if(${SRB2_CONFIG_HAVE_GME}) endif() if(${GME_FOUND}) set(SRB2_HAVE_GME ON) - add_definitions(-DHAVE_LIBGME) + target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_LIBGME) else() message(WARNING "You have specified that GME is available but it was not found.") endif() @@ -373,7 +78,7 @@ if(${SRB2_CONFIG_HAVE_OPENMPT}) endif() if(${OPENMPT_FOUND}) set(SRB2_HAVE_OPENMPT ON) - add_definitions(-DHAVE_OPENMPT) + target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_OPENMPT) else() message(WARNING "You have specified that OpenMPT is available but it was not found.") endif() @@ -396,8 +101,7 @@ if(${SRB2_CONFIG_HAVE_MIXERX}) endif() if(${MIXERX_FOUND}) set(SRB2_HAVE_MIXERX ON) - set(SRB2_SDL2_SOUNDIMPL mixer_sound.c) - add_definitions(-DHAVE_MIXERX) + target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_MIXERX) else() message(WARNING "You have specified that SDL Mixer X is available but it was not found.") endif() @@ -417,7 +121,7 @@ if(${SRB2_CONFIG_HAVE_ZLIB}) endif() if(${ZLIB_FOUND}) set(SRB2_HAVE_ZLIB ON) - add_definitions(-DHAVE_ZLIB) + target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_ZLIB) else() message(WARNING "You have specified that ZLIB is available but it was not found. SRB2 may not compile correctly.") endif() @@ -438,14 +142,9 @@ if(${SRB2_CONFIG_HAVE_PNG} AND ${SRB2_CONFIG_HAVE_ZLIB}) endif() if(${PNG_FOUND}) set(SRB2_HAVE_PNG ON) - add_definitions(-DHAVE_PNG) - add_definitions(-D_LARGEFILE64_SOURCE) - set(SRB2_PNG_SOURCES apng.c) - set(SRB2_PNG_HEADERS apng.h) - prepend_sources(SRB2_PNG_SOURCES) - prepend_sources(SRB2_PNG_HEADERS) - source_group("Main" FILES ${SRB2_CORE_SOURCES} ${SRB2_CORE_HEADERS} - ${SRB2_PNG_SOURCES} ${SRB2_PNG_HEADERS}) + target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_PNG) + target_compile_definitions(SRB2SDL2 PRIVATE -D_LARGEFILE64_SOURCE) + target_sources(SRB2SDL2 PRIVATE apng.c) else() message(WARNING "You have specified that PNG is available but it was not found. SRB2 may not compile correctly.") endif() @@ -466,7 +165,7 @@ if(${SRB2_CONFIG_HAVE_CURL}) endif() if(${CURL_FOUND}) set(SRB2_HAVE_CURL ON) - add_definitions(-DHAVE_CURL) + target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_CURL) else() message(WARNING "You have specified that CURL is available but it was not found. SRB2 may not compile correctly.") endif() @@ -474,59 +173,19 @@ endif() if(${SRB2_CONFIG_HAVE_THREADS}) set(SRB2_HAVE_THREADS ON) - set(SRB2_CORE_HEADERS ${SRB2_CORE_HEADERS} ${CMAKE_CURRENT_SOURCE_DIR}/i_threads.h) - add_definitions(-DHAVE_THREADS) + target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_THREADS) endif() if(${SRB2_CONFIG_HWRENDER}) - add_definitions(-DHWRENDER) - set(SRB2_HWRENDER_SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_batching.c - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_bsp.c - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_cache.c - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_clip.c - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_draw.c - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_light.c - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_main.c - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md2.c - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md2load.c - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md3load.c - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_model.c - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/u_list.c - ) - - set (SRB2_HWRENDER_HEADERS - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_batching.h - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_clip.h - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_data.h - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_defs.h - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_dll.h - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_drv.h - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_glob.h - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_light.h - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_main.h - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md2.h - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md2load.h - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md3load.h - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_model.h - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/u_list.h - ) - - set(SRB2_R_OPENGL_SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/r_opengl/r_opengl.c - ) - - set(SRB2_R_OPENGL_HEADERS - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/r_opengl/r_opengl.h - ) - + target_compile_definitions(SRB2SDL2 PRIVATE -DHWRENDER) + add_subdirectory(hardware) endif() if(${SRB2_CONFIG_HWRENDER} AND ${SRB2_CONFIG_STATIC_OPENGL}) find_package(OpenGL) if(${OPENGL_FOUND}) - add_definitions(-DHWRENDER) - add_definitions(-DSTATIC_OPENGL) + target_compile_definitions(SRB2SDL2 PRIVATE -DHWRENDER) + target_compile_definitions(SRB2SDL2 PRIVATE -DSTATIC_OPENGL) else() message(WARNING "You have specified static opengl but opengl was not found. Not setting HWRENDER.") endif() @@ -548,11 +207,11 @@ if(${SRB2_CONFIG_USEASM}) enable_language(ASM_NASM) endif() set(SRB2_USEASM ON) - add_definitions(-DUSEASM) + target_compile_definitions(SRB2SDL2 PRIVATE -DUSEASM) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -msse3 -mfpmath=sse") else() set(SRB2_USEASM OFF) - add_definitions(-DNONX86 -DNORUSEASM) + target_compile_definitions(SRB2SDL2 PRIVATE -DNONX86 -DNORUSEASM) endif() # Targets @@ -588,7 +247,7 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} -Wno-absolute-value) endif() -add_definitions(-DCMAKECONFIG) +target_compile_definitions(SRB2SDL2 PRIVATE -DCMAKECONFIG) #add_library(SRB2Core STATIC # ${SRB2_CORE_SOURCES} diff --git a/src/blua/CMakeLists.txt b/src/blua/CMakeLists.txt new file mode 100644 index 000000000..4e9c67d2f --- /dev/null +++ b/src/blua/CMakeLists.txt @@ -0,0 +1 @@ +target_sourcefile(c) diff --git a/src/hardware/CMakeLists.txt b/src/hardware/CMakeLists.txt new file mode 100644 index 000000000..4e9c67d2f --- /dev/null +++ b/src/hardware/CMakeLists.txt @@ -0,0 +1 @@ +target_sourcefile(c) diff --git a/src/sdl/CMakeLists.txt b/src/sdl/CMakeLists.txt index a7f015c86..a1d55ad4d 100644 --- a/src/sdl/CMakeLists.txt +++ b/src/sdl/CMakeLists.txt @@ -21,46 +21,25 @@ if(${SRB2_CONFIG_SDL2_USEMIXER}) endif() if(${SDL2_MIXER_FOUND}) set(SRB2_HAVE_MIXER ON) - set(SRB2_SDL2_SOUNDIMPL mixer_sound.c) + target_sources(SRB2SDL2 PRIVATE mixer_sound.c) else() message(WARNING "You specified that SDL2_mixer is available, but it was not found. Falling back to sdl sound.") - set(SRB2_SDL2_SOUNDIMPL sdl_sound.c) + target_sources(SRB2SDL2 PRIVATE sdl_sound.c) endif() elseif(${MIXERX_FOUND}) - set(SRB2_SDL2_SOUNDIMPL mixer_sound.c) + target_sources(SRB2SDL2 PRIVATE mixer_sound.c) else() - set(SRB2_SDL2_SOUNDIMPL sdl_sound.c) + target_sources(SRB2SDL2 PRIVATE sdl_sound.c) endif() -set(SRB2_SDL2_SOURCES - dosstr.c - endtxt.c - hwsym_sdl.c - i_main.c - i_net.c - i_system.c - i_ttf.c - i_video.c - #IMG_xpm.c - ogl_sdl.c +target_sourcefile(c) - ${SRB2_SDL2_SOUNDIMPL} -) - -set(SRB2_SDL2_HEADERS - endtxt.h - hwsym_sdl.h - i_ttf.h - ogl_sdl.h - sdlmain.h -) +target_sources(SRB2SDL2 PRIVATE ogl_sdl.c) if(${SRB2_CONFIG_HAVE_THREADS}) - set(SRB2_SDL2_SOURCES ${SRB2_SDL2_SOURCES} i_threads.c) + target_sources(SRB2SDL2 PRIVATE i_threads.c) endif() -source_group("Interface Code" FILES ${SRB2_SDL2_SOURCES} ${SRB2_SDL2_HEADERS}) - # Dependency if(${SRB2_CONFIG_USE_INTERNAL_LIBRARIES}) set(SDL2_FOUND ON) @@ -76,79 +55,31 @@ else() endif() if(${SDL2_FOUND}) - set(SRB2_SDL2_TOTAL_SOURCES - ${SRB2_CORE_SOURCES} - ${SRB2_CORE_HEADERS} - ${SRB2_PNG_SOURCES} - ${SRB2_PNG_HEADERS} - ${SRB2_CORE_RENDER_SOURCES} - ${SRB2_CORE_GAME_SOURCES} - ${SRB2_LUA_SOURCES} - ${SRB2_LUA_HEADERS} - ${SRB2_BLUA_SOURCES} - ${SRB2_BLUA_HEADERS} - ${SRB2_SDL2_SOURCES} - ${SRB2_SDL2_HEADERS} - ) - - source_group("Main" FILES ${SRB2_CORE_SOURCES} ${SRB2_CORE_HEADERS} - ${SRB2_PNG_SOURCES} ${SRB2_PNG_HEADERS}) - source_group("Renderer" FILES ${SRB2_CORE_RENDER_SOURCES}) - source_group("Game" FILES ${SRB2_CORE_GAME_SOURCES}) - source_group("Assembly" FILES ${SRB2_ASM_SOURCES} ${SRB2_NASM_SOURCES}) - source_group("LUA" FILES ${SRB2_LUA_SOURCES} ${SRB2_LUA_HEADERS}) - source_group("LUA\\Interpreter" FILES ${SRB2_BLUA_SOURCES} ${SRB2_BLUA_HEADERS}) - - if(${SRB2_CONFIG_HWRENDER}) - set(SRB2_SDL2_TOTAL_SOURCES ${SRB2_SDL2_TOTAL_SOURCES} - ${SRB2_HWRENDER_SOURCES} - ${SRB2_HWRENDER_HEADERS} - ${SRB2_R_OPENGL_SOURCES} - ${SRB2_R_OPENGL_HEADERS} - ) - - source_group("Hardware" FILES ${SRB2_HWRENDER_SOURCES} ${SRB2_HWRENDER_HEADERS}) - source_group("Hardware\\OpenGL Renderer" FILES ${SRB2_R_OPENGL_SOURCES} ${SRB2_R_OPENGL_HEADERS}) - endif() - if(${SRB2_USEASM}) - set(SRB2_SDL2_TOTAL_SOURCES ${SRB2_SDL2_TOTAL_SOURCES} - ${SRB2_NASM_SOURCES} - ) - if(MSVC) - set(SRB2_SDL2_TOTAL_SOURCES ${SRB2_SDL2_TOTAL_SOURCES} - ${SRB2_NASM_OBJECTS} - ) - set_source_files_properties(${SRB2_NASM_OBJECTS} PROPERTIES GENERATED ON) - else() - list(APPEND SRB2_SDL2_TOTAL_SOURCES ${SRB2_ASM_SOURCES}) - set_source_files_properties(${SRB2_ASM_SOURCES} PROPERTIES LANGUAGE C) - set_source_files_properties(${SRB2_ASM_SOURCES} PROPERTIES COMPILE_FLAGS "-x assembler-with-cpp") - endif() + target_sources(SRB2SDL2 PRIVATE ${SRB2_ASM_SOURCES} + ${SRB2_NASM_SOURCES}) + set_source_files_properties(${SRB2_ASM_SOURCES} PROPERTIES LANGUAGE C) + set_source_files_properties(${SRB2_ASM_SOURCES} PROPERTIES COMPILE_FLAGS "-x assembler-with-cpp") endif() if(${CMAKE_SYSTEM} MATCHES Windows) - set(SRB2_SDL2_TOTAL_SOURCES ${SRB2_SDL2_TOTAL_SOURCES} - ${CMAKE_SOURCE_DIR}/src/win32/win_dbg.c - ${CMAKE_SOURCE_DIR}/src/win32/Srb2win.rc - ) + target_sources(SRB2SDL2 PRIVATE + ../win32/win_dbg.c + ../win32/Srb2win.rc) endif() if(${CMAKE_SYSTEM} MATCHES Darwin) set(MACOSX_BUNDLE_ICON_FILE Srb2mac.icns) set_source_files_properties(macosx/Srb2mac.icns PROPERTIES MACOSX_PACKAGE_LOCATION "Resources") - set(SRB2_SDL2_MAC_SOURCES + target_sources(SRB2SDL2 PRIVATE macosx/mac_alert.c macosx/mac_alert.h macosx/mac_resources.c macosx/mac_resources.h macosx/Srb2mac.icns ) - source_group("Interface Code\\OSX Compatibility" FILES ${SRB2_SDL2_MAC_SOURCES}) - set(SRB2_SDL2_TOTAL_SOURCES ${SRB2_SDL2_TOTAL_SOURCES} ${SRB2_SDL2_MAC_SOURCES}) endif() - add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32 ${SRB2_SDL2_TOTAL_SOURCES}) if(${CMAKE_SYSTEM} MATCHES Windows) set_target_properties(SRB2SDL2 PROPERTIES OUTPUT_NAME srb2win) elseif(${CMAKE_SYSTEM} MATCHES Linux) @@ -205,18 +136,6 @@ if(${SDL2_FOUND}) set(ASM_ASSEMBLER_OBJFORMAT ${CMAKE_ASM_NASM_OBJECT_FORMAT}) set_source_files_properties(${SRB2_NASM_SOURCES} LANGUAGE ASM_NASM) endif() - - if(MSVC) - # using assembler with msvc doesn't work, must do it manually - foreach(ASMFILE ${SRB2_NASM_SOURCES}) - get_filename_component(ASMFILE_NAME ${ASMFILE} NAME_WE) - set(ASMFILE_NAME ${ASMFILE_NAME}.obj) - add_custom_command(TARGET SRB2SDL2 PRE_LINK - COMMAND ${ASM_ASSEMBLER_TEMP} ARGS -f ${ASM_ASSEMBLER_OBJFORMAT} -o ${CMAKE_CURRENT_BINARY_DIR}/${ASMFILE_NAME} ${ASMFILE} - COMMENT "assemble ${ASMFILE_NAME}." - ) - endforeach() - endif() endif() set_target_properties(SRB2SDL2 PROPERTIES VERSION ${SRB2_VERSION}) @@ -230,31 +149,6 @@ if(${SDL2_FOUND}) ) endif() - if(MSVC) - if(${SRB2_CONFIG_USE_INTERNAL_LIBRARIES}) - set(SDL2_MAIN_FOUND ON) - if(${SRB2_SYSTEM_BITS} EQUAL 64) - set(SDL2_MAIN_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/libs/SDL2/x86_64-w64-mingw32/include/SDL2) - set(SDL2_MAIN_LIBRARIES "-L${CMAKE_SOURCE_DIR}/libs/SDL2/x86_64-w64-mingw32/lib -lSDL2main") - else() # 32-bit - set(SDL2_MAIN_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/libs/SDL2/i686-w64-mingw32/include/SDL2) - set(SDL2_MAIN_LIBRARIES "-L${CMAKE_SOURCE_DIR}/libs/SDL2/i686-w64-mingw32/lib -lSDL2main") - endif() - else() - find_package(SDL2_MAIN REQUIRED) - endif() - target_link_libraries(SRB2SDL2 PRIVATE - ${SDL2_MAIN_LIBRARIES} - ) - target_compile_options(SRB2SDL2 PRIVATE - /Umain - /D_CRT_SECURE_NO_WARNINGS # something about string functions. - /D_CRT_NONSTDC_NO_DEPRECATE - /DSDLMAIN - /D_WINSOCK_DEPRECATED_NO_WARNINGS # Don't care - ) - endif() - target_include_directories(SRB2SDL2 PRIVATE ${SDL2_INCLUDE_DIRS} ${SDL2_MIXER_INCLUDE_DIRS} From ec8b63d6759f0c124693ea6d5a521e8d82efd566 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 5 May 2021 21:21:55 -0700 Subject: [PATCH 439/644] Makefile: remove last of unused flags --- src/Makefile.d/nix.mk | 2 +- src/Makefile.d/platform.mk | 4 ++-- src/Makefile.d/sdl.mk | 23 ++--------------------- 3 files changed, 5 insertions(+), 24 deletions(-) diff --git a/src/Makefile.d/nix.mk b/src/Makefile.d/nix.mk index fdcd40d4d..f1645e1e4 100644 --- a/src/Makefile.d/nix.mk +++ b/src/Makefile.d/nix.mk @@ -30,7 +30,7 @@ opts+=-I/usr/X11R6/include -DLINUX -DFREEBSD libs+=-L/usr/X11R6/lib -lipx -lkvm endif -# FIXME +# FIXME: UNTESTED #ifdef SOLARIS #NOIPX=1 #NOASM=1 diff --git a/src/Makefile.d/platform.mk b/src/Makefile.d/platform.mk index 4f110594e..be8d35830 100644 --- a/src/Makefile.d/platform.mk +++ b/src/Makefile.d/platform.mk @@ -33,10 +33,10 @@ endif else ifdef FREEBSD UNIX=1 platform=freebsd -else ifdef SOLARIS # FIXME +else ifdef SOLARIS # FIXME: UNTESTED UNIX=1 platform=solaris -else ifdef CYGWIN32 # FIXME +else ifdef CYGWIN32 # FIXME: UNTESTED nasm_format=win32 platform=cygwin else ifdef MINGW diff --git a/src/Makefile.d/sdl.mk b/src/Makefile.d/sdl.mk index 43a2ffced..99ca624e6 100644 --- a/src/Makefile.d/sdl.mk +++ b/src/Makefile.d/sdl.mk @@ -13,12 +13,12 @@ makedir:=$(makedir)/SDL sources+=$(call List,sdl/Sourcefile) opts+=-DDIRECTFULLSCREEN -DHAVE_SDL -# FIXME +# FIXME: UNTESTED #ifdef PANDORA #include sdl/SRB2Pandora/Makefile.cfg #endif #ifdef PANDORA -# FIXME +# FIXME: UNTESTED #ifdef CYGWIN32 #include sdl/MakeCYG.cfg #endif #ifdef CYGWIN32 @@ -63,25 +63,6 @@ USEASM=1 endif endif -# FIXME -#ifdef SDL_TTF -# OPTS+=-DHAVE_TTF -# SDL_LDFLAGS+=-lSDL2_ttf -lfreetype -lz -# OBJS+=$(OBJDIR)/i_ttf.o -#endif - -# FIXME -#ifdef SDL_IMAGE -# OPTS+=-DHAVE_IMAGE -# SDL_LDFLAGS+=-lSDL2_image -#endif - -# FIXME -#ifdef SDL_NET -# OPTS+=-DHAVE_SDLNET -# SDL_LDFLAGS+=-lSDL2_net -#endif - ifdef MINGW ifndef NOSDLMAIN SDLMAIN=1 From 3159d5a6e490666324278c3b283c1bf8b02b79bb Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+TatsuruIKR@users.noreply.github.com> Date: Thu, 6 May 2021 21:58:21 -0300 Subject: [PATCH 440/644] 2.2.9 prep --- appveyor.yml | 2 +- src/config.h.in | 5 +++-- src/p_enemy.c | 2 +- src/version.h | 4 ++-- src/win32/Srb2win.rc | 4 ++-- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 2acc2f712..e94a709cd 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 2.2.8.{branch}-{build} +version: 2.2.9.{branch}-{build} os: MinGW environment: diff --git a/src/config.h.in b/src/config.h.in index a6f43a7d7..6bdb00bab 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -34,12 +34,13 @@ * Last updated 2020 / 07 / 10 - v2.2.6 - player.dta & patch.pk3 * Last updated 2020 / 09 / 27 - v2.2.7 - patch.pk3 * Last updated 2020 / 10 / 02 - v2.2.8 - patch.pk3 + * Last updated 2020 / 05 / 06 - v2.2.9 - patch.pk3 & zones.pk3 */ #define ASSET_HASH_SRB2_PK3 "0277c9416756627004e83cbb5b2e3e28" -#define ASSET_HASH_ZONES_PK3 "f7e88afb6af7996a834c7d663144bead" +#define ASSET_HASH_ZONES_PK3 "f8f3e2b5deacf40f14e36686a07d44bb" #define ASSET_HASH_PLAYER_DTA "49dad7b24634c89728cc3e0b689e12bb" #ifdef USE_PATCH_DTA -#define ASSET_HASH_PATCH_PK3 "466cdf60075262b3f5baa5e07f0999e8" +#define ASSET_HASH_PATCH_PK3 "7d467a883f7887b3c311798ee2f56b6a" #endif #endif diff --git a/src/p_enemy.c b/src/p_enemy.c index 59176d6cc..51f18f596 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -4201,7 +4201,7 @@ void A_CustomPower(mobj_t *actor) return; } - if (locvar1 >= NUMPOWERS) + if (locvar1 >= NUMPOWERS || locvar1 < 0) { CONS_Debug(DBG_GAMELOGIC, "Power #%d out of range!\n", locvar1); return; diff --git a/src/version.h b/src/version.h index ece084beb..4470fbd6e 100644 --- a/src/version.h +++ b/src/version.h @@ -1,4 +1,4 @@ -#define SRB2VERSION "2.2.8"/* this must be the first line, for cmake !! */ +#define SRB2VERSION "2.2.9"/* this must be the first line, for cmake !! */ // The Modification ID; must be obtained from a Master Server Admin ( https://mb.srb2.org/showgroups.php ). // DO NOT try to set this otherwise, or your modification will be unplayable through the Master Server. @@ -9,7 +9,7 @@ // it's only for detection of the version the player is using so the MS can alert them of an update. // Only set it higher, not lower, obviously. // Note that we use this to help keep internal testing in check; this is why v2.2.0 is not version "1". -#define MODVERSION 49 +#define MODVERSION 50 // Define this as a prerelease version suffix // #define BETAVERSION "RC1" diff --git a/src/win32/Srb2win.rc b/src/win32/Srb2win.rc index d5d59922c..b0eb2532e 100644 --- a/src/win32/Srb2win.rc +++ b/src/win32/Srb2win.rc @@ -76,8 +76,8 @@ END #include "../doomdef.h" // Needed for version string VS_VERSION_INFO VERSIONINFO - FILEVERSION 2,2,8,0 - PRODUCTVERSION 2,2,8,0 + FILEVERSION 2,2,9,0 + PRODUCTVERSION 2,2,9,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L From 8b021ec16bcd78c566995ca65f5da920cbdd6315 Mon Sep 17 00:00:00 2001 From: lachablock Date: Fri, 7 May 2021 12:38:24 +1000 Subject: [PATCH 441/644] but if you close your eyes EH OH, EH OH --- src/config.h.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config.h.in b/src/config.h.in index 6bdb00bab..db794cccc 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -34,7 +34,7 @@ * Last updated 2020 / 07 / 10 - v2.2.6 - player.dta & patch.pk3 * Last updated 2020 / 09 / 27 - v2.2.7 - patch.pk3 * Last updated 2020 / 10 / 02 - v2.2.8 - patch.pk3 - * Last updated 2020 / 05 / 06 - v2.2.9 - patch.pk3 & zones.pk3 + * Last updated 2021 / 05 / 06 - v2.2.9 - patch.pk3 & zones.pk3 */ #define ASSET_HASH_SRB2_PK3 "0277c9416756627004e83cbb5b2e3e28" #define ASSET_HASH_ZONES_PK3 "f8f3e2b5deacf40f14e36686a07d44bb" From d325c7e6d314562f79f1890f7d0c5bf5e1496c93 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Fri, 7 May 2021 17:45:56 +0200 Subject: [PATCH 442/644] The year is 2021 --- src/am_map.c | 2 +- src/am_map.h | 2 +- src/apng.c | 2 +- src/apng.h | 2 +- src/asm_defs.inc | 2 +- src/b_bot.c | 2 +- src/b_bot.h | 2 +- src/byteptr.h | 2 +- src/command.c | 2 +- src/command.h | 2 +- src/console.c | 2 +- src/console.h | 2 +- src/d_clisrv.c | 2 +- src/d_clisrv.h | 2 +- src/d_event.h | 2 +- src/d_main.c | 2 +- src/d_main.h | 2 +- src/d_net.c | 2 +- src/d_net.h | 2 +- src/d_netcmd.c | 2 +- src/d_netcmd.h | 2 +- src/d_netfil.c | 2 +- src/d_netfil.h | 2 +- src/d_player.h | 2 +- src/d_think.h | 2 +- src/d_ticcmd.h | 2 +- src/deh_lua.c | 2 +- src/deh_lua.h | 2 +- src/deh_soc.c | 2 +- src/deh_soc.h | 2 +- src/deh_tables.c | 2 +- src/deh_tables.h | 2 +- src/dehacked.c | 2 +- src/dehacked.h | 2 +- src/doomdata.h | 2 +- src/doomdef.h | 2 +- src/doomstat.h | 2 +- src/doomtype.h | 2 +- src/endian.h | 2 +- src/f_finale.c | 2 +- src/f_finale.h | 2 +- src/f_wipe.c | 2 +- src/g_demo.c | 2 +- src/g_demo.h | 2 +- src/g_game.c | 2 +- src/g_game.h | 2 +- src/g_input.c | 2 +- src/g_input.h | 2 +- src/g_state.h | 2 +- src/hardware/hw_batching.c | 2 +- src/hardware/hw_batching.h | 2 +- src/hardware/hw_cache.c | 2 +- src/hardware/hw_data.h | 2 +- src/hardware/hw_draw.c | 2 +- src/hardware/hw_drv.h | 2 +- src/hardware/hw_glob.h | 2 +- src/hardware/hw_light.h | 2 +- src/hardware/hw_main.h | 2 +- src/hardware/hw_md2.c | 2 +- src/hardware/hw_md2.h | 2 +- src/hardware/r_opengl/r_opengl.c | 2 +- src/http-mserv.c | 2 +- src/hu_stuff.c | 2 +- src/hu_stuff.h | 2 +- src/i_addrinfo.c | 2 +- src/i_addrinfo.h | 2 +- src/i_joy.h | 2 +- src/i_net.h | 2 +- src/i_sound.h | 2 +- src/i_system.h | 2 +- src/i_tcp.c | 2 +- src/i_tcp.h | 2 +- src/i_threads.h | 2 +- src/i_video.h | 2 +- src/info.c | 2 +- src/info.h | 2 +- src/keys.h | 2 +- src/lua_baselib.c | 2 +- src/lua_blockmaplib.c | 4 ++-- src/lua_consolelib.c | 2 +- src/lua_hook.h | 2 +- src/lua_hooklib.c | 2 +- src/lua_hud.h | 2 +- src/lua_hudlib.c | 2 +- src/lua_infolib.c | 2 +- src/lua_libs.h | 2 +- src/lua_maplib.c | 2 +- src/lua_mathlib.c | 2 +- src/lua_mobjlib.c | 2 +- src/lua_playerlib.c | 2 +- src/lua_polyobjlib.c | 4 ++-- src/lua_script.c | 2 +- src/lua_script.h | 2 +- src/lua_skinlib.c | 2 +- src/lua_taglib.c | 4 ++-- src/lua_thinkerlib.c | 2 +- src/m_aatree.c | 2 +- src/m_aatree.h | 2 +- src/m_anigif.c | 2 +- src/m_anigif.h | 2 +- src/m_argv.c | 2 +- src/m_argv.h | 2 +- src/m_bbox.c | 2 +- src/m_bbox.h | 2 +- src/m_cheat.c | 2 +- src/m_cheat.h | 2 +- src/m_cond.c | 2 +- src/m_cond.h | 2 +- src/m_dllist.h | 2 +- src/m_fixed.c | 2 +- src/m_fixed.h | 2 +- src/m_menu.c | 2 +- src/m_menu.h | 2 +- src/m_misc.c | 2 +- src/m_misc.h | 2 +- src/m_perfstats.c | 2 +- src/m_perfstats.h | 2 +- src/m_queue.c | 2 +- src/m_queue.h | 2 +- src/m_random.c | 2 +- src/m_random.h | 2 +- src/m_swap.h | 2 +- src/mserv.c | 4 ++-- src/mserv.h | 4 ++-- src/p_ceilng.c | 2 +- src/p_enemy.c | 2 +- src/p_floor.c | 2 +- src/p_inter.c | 2 +- src/p_lights.c | 2 +- src/p_local.h | 2 +- src/p_map.c | 2 +- src/p_maputl.c | 2 +- src/p_maputl.h | 2 +- src/p_mobj.c | 2 +- src/p_mobj.h | 2 +- src/p_polyobj.c | 2 +- src/p_polyobj.h | 2 +- src/p_pspr.h | 2 +- src/p_saveg.c | 2 +- src/p_saveg.h | 2 +- src/p_setup.c | 2 +- src/p_setup.h | 2 +- src/p_sight.c | 2 +- src/p_slopes.c | 2 +- src/p_slopes.h | 2 +- src/p_spec.c | 2 +- src/p_spec.h | 2 +- src/p_telept.c | 2 +- src/p_tick.c | 2 +- src/p_tick.h | 2 +- src/p_user.c | 2 +- src/r_bsp.c | 2 +- src/r_bsp.h | 2 +- src/r_data.h | 2 +- src/r_defs.h | 2 +- src/r_draw16.c | 2 +- src/r_draw8_npo2.c | 2 +- src/r_local.h | 2 +- src/r_main.c | 2 +- src/r_main.h | 2 +- src/r_patch.c | 2 +- src/r_patch.h | 2 +- src/r_patchrotation.c | 2 +- src/r_patchrotation.h | 2 +- src/r_picformats.c | 4 ++-- src/r_picformats.h | 4 ++-- src/r_plane.h | 2 +- src/r_portal.c | 2 +- src/r_portal.h | 2 +- src/r_segs.c | 2 +- src/r_segs.h | 2 +- src/r_skins.c | 2 +- src/r_skins.h | 2 +- src/r_sky.c | 2 +- src/r_sky.h | 2 +- src/r_splats.h | 2 +- src/r_state.h | 2 +- src/r_textures.h | 2 +- src/r_things.h | 2 +- src/s_sound.c | 2 +- src/s_sound.h | 2 +- src/screen.c | 2 +- src/screen.h | 2 +- src/sdl/i_system.c | 2 +- src/sdl/i_threads.c | 2 +- src/sdl/i_video.c | 2 +- src/sdl/mixer_sound.c | 4 ++-- src/sdl/ogl_sdl.c | 2 +- src/sdl/ogl_sdl.h | 2 +- src/sdl/sdl_sound.c | 2 +- src/sdl/sdlmain.h | 2 +- src/sounds.c | 2 +- src/sounds.h | 2 +- src/st_stuff.c | 2 +- src/st_stuff.h | 2 +- src/strcasestr.c | 2 +- src/string.c | 2 +- src/tables.c | 2 +- src/tables.h | 2 +- src/taglist.c | 4 ++-- src/taglist.h | 4 ++-- src/tmap.nas | 2 +- src/tmap.s | 2 +- src/tmap_asm.s | 2 +- src/tmap_mmx.nas | 2 +- src/tmap_vc.nas | 2 +- src/v_video.c | 2 +- src/v_video.h | 2 +- src/vid_copy.s | 2 +- src/w_wad.c | 2 +- src/w_wad.h | 2 +- src/win32/Srb2win.rc | 2 +- src/y_inter.c | 2 +- src/y_inter.h | 2 +- src/z_zone.c | 2 +- src/z_zone.h | 2 +- 216 files changed, 226 insertions(+), 226 deletions(-) diff --git a/src/am_map.c b/src/am_map.c index 53a7480a5..ef0ebb88c 100644 --- a/src/am_map.c +++ b/src/am_map.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/am_map.h b/src/am_map.h index 1c8fa70e4..022a7208b 100644 --- a/src/am_map.h +++ b/src/am_map.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/apng.c b/src/apng.c index 0abbe541d..36b205c60 100644 --- a/src/apng.c +++ b/src/apng.c @@ -1,5 +1,5 @@ /* -Copyright 2019-2020, James R. +Copyright 2019-2021, James R. All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/src/apng.h b/src/apng.h index a8b5c8f24..893b523cb 100644 --- a/src/apng.h +++ b/src/apng.h @@ -1,5 +1,5 @@ /* -Copyright 2019-2020, James R. +Copyright 2019-2021, James R. All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/src/asm_defs.inc b/src/asm_defs.inc index ec286b0bd..9074f20f8 100644 --- a/src/asm_defs.inc +++ b/src/asm_defs.inc @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/b_bot.c b/src/b_bot.c index d3635f32c..5b4124627 100644 --- a/src/b_bot.c +++ b/src/b_bot.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 2007-2016 by John "JTE" Muniz. -// Copyright (C) 2011-2020 by Sonic Team Junior. +// Copyright (C) 2011-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/b_bot.h b/src/b_bot.h index 2806bd68f..9f55637d1 100644 --- a/src/b_bot.h +++ b/src/b_bot.h @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 2007-2016 by John "JTE" Muniz. -// Copyright (C) 2012-2020 by Sonic Team Junior. +// Copyright (C) 2012-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/byteptr.h b/src/byteptr.h index 01a6293b4..4c8414fae 100644 --- a/src/byteptr.h +++ b/src/byteptr.h @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/command.c b/src/command.c index d73cde5c2..95b1fd67d 100644 --- a/src/command.c +++ b/src/command.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/command.h b/src/command.h index d4033e6ef..34fd15963 100644 --- a/src/command.h +++ b/src/command.h @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/console.c b/src/console.c index 1560220f6..8c3703dd8 100644 --- a/src/console.c +++ b/src/console.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/console.h b/src/console.h index 0296f4f6e..28f40d308 100644 --- a/src/console.h +++ b/src/console.h @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 911a91355..4176b8a11 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 3d67525da..f3eb52423 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/d_event.h b/src/d_event.h index 3cce8fad1..1fd2e3824 100644 --- a/src/d_event.h +++ b/src/d_event.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/d_main.c b/src/d_main.c index 61510d590..2a608cfc8 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/d_main.h b/src/d_main.h index 81de0634d..943da8418 100644 --- a/src/d_main.h +++ b/src/d_main.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/d_net.c b/src/d_net.c index d534b1b08..9e5abe24a 100644 --- a/src/d_net.c +++ b/src/d_net.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/d_net.h b/src/d_net.h index ea6b5d4d9..dbc6d8ba5 100644 --- a/src/d_net.h +++ b/src/d_net.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 09f9d4651..97a2921a2 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/d_netcmd.h b/src/d_netcmd.h index ac39626a4..fcdd1d4bb 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/d_netfil.c b/src/d_netfil.c index 50dc2ba60..9618c8073 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/d_netfil.h b/src/d_netfil.h index 158149477..ddcbcfec3 100644 --- a/src/d_netfil.h +++ b/src/d_netfil.h @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/d_player.h b/src/d_player.h index 2e7afed88..54ab34288 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/d_think.h b/src/d_think.h index 4bdac4627..c3f91edc4 100644 --- a/src/d_think.h +++ b/src/d_think.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/d_ticcmd.h b/src/d_ticcmd.h index 2a5ef0981..374585edf 100644 --- a/src/d_ticcmd.h +++ b/src/d_ticcmd.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/deh_lua.c b/src/deh_lua.c index e6a436421..3af97999c 100644 --- a/src/deh_lua.c +++ b/src/deh_lua.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/deh_lua.h b/src/deh_lua.h index cd927b9fd..9df4028bd 100644 --- a/src/deh_lua.h +++ b/src/deh_lua.h @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/deh_soc.c b/src/deh_soc.c index 5b12ea1b0..fc764b411 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/deh_soc.h b/src/deh_soc.h index 2bcb52e70..4064deb3f 100644 --- a/src/deh_soc.h +++ b/src/deh_soc.h @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/deh_tables.c b/src/deh_tables.c index dd6d7d69f..23faf0092 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/deh_tables.h b/src/deh_tables.h index d094bcbad..1f265cc99 100644 --- a/src/deh_tables.h +++ b/src/deh_tables.h @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/dehacked.c b/src/dehacked.c index c2ea28d27..7d8629567 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/dehacked.h b/src/dehacked.h index 1620314ca..1b200e246 100644 --- a/src/dehacked.h +++ b/src/dehacked.h @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/doomdata.h b/src/doomdata.h index b3f7f5c4d..e317fec1b 100644 --- a/src/doomdata.h +++ b/src/doomdata.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/doomdef.h b/src/doomdef.h index 52abc9597..9dc44d3bb 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/doomstat.h b/src/doomstat.h index 2d28b81af..843202395 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/doomtype.h b/src/doomtype.h index 950f50856..a094cbb08 100644 --- a/src/doomtype.h +++ b/src/doomtype.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/endian.h b/src/endian.h index 24d8e35cd..e78204e72 100644 --- a/src/endian.h +++ b/src/endian.h @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2014-2020 by Sonic Team Junior. +// Copyright (C) 2014-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/f_finale.c b/src/f_finale.c index fdcfad279..bfba7cf96 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/f_finale.h b/src/f_finale.h index b3abf1778..4aa2c3f05 100644 --- a/src/f_finale.h +++ b/src/f_finale.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/f_wipe.c b/src/f_wipe.c index 6afb8a6a7..7526aeca3 100644 --- a/src/f_wipe.c +++ b/src/f_wipe.c @@ -3,7 +3,7 @@ // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. // Copyright (C) 2013-2016 by Matthew "Kaito Sinclaire" Walsh. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/g_demo.c b/src/g_demo.c index 593fd7723..ea71c9bd4 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/g_demo.h b/src/g_demo.h index df25042c4..73cf27358 100644 --- a/src/g_demo.h +++ b/src/g_demo.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/g_game.c b/src/g_game.c index 399c4f2bd..9911baab6 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/g_game.h b/src/g_game.h index 744d6755a..98336ad44 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/g_input.c b/src/g_input.c index d3c21e774..357081e1d 100644 --- a/src/g_input.c +++ b/src/g_input.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/g_input.h b/src/g_input.h index ce38f6ba9..609141825 100644 --- a/src/g_input.h +++ b/src/g_input.h @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/g_state.h b/src/g_state.h index e364c5a35..589dc6361 100644 --- a/src/g_state.h +++ b/src/g_state.h @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/hardware/hw_batching.c b/src/hardware/hw_batching.c index b13ad03ea..3a8eef55e 100644 --- a/src/hardware/hw_batching.c +++ b/src/hardware/hw_batching.c @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2020 by Sonic Team Junior. +// Copyright (C) 2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/hardware/hw_batching.h b/src/hardware/hw_batching.h index 42291a0df..d886dcf2a 100644 --- a/src/hardware/hw_batching.h +++ b/src/hardware/hw_batching.h @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2020 by Sonic Team Junior. +// Copyright (C) 2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 83a4e2e03..317efd320 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/hardware/hw_data.h b/src/hardware/hw_data.h index 7e56a14d0..5aba6a2a9 100644 --- a/src/hardware/hw_data.h +++ b/src/hardware/hw_data.h @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index ba4923d10..e83aff0d7 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h index 8cae144ff..d4a586d41 100644 --- a/src/hardware/hw_drv.h +++ b/src/hardware/hw_drv.h @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/hardware/hw_glob.h b/src/hardware/hw_glob.h index 2aba62248..37d77b467 100644 --- a/src/hardware/hw_glob.h +++ b/src/hardware/hw_glob.h @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/hardware/hw_light.h b/src/hardware/hw_light.h index fed7db47f..244cc921f 100644 --- a/src/hardware/hw_light.h +++ b/src/hardware/hw_light.h @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index 4ad09aa3d..ba6532c38 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 5caf344f7..9c3aa9e58 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/hardware/hw_md2.h b/src/hardware/hw_md2.h index 0f4d2c7bc..9249c034c 100644 --- a/src/hardware/hw_md2.h +++ b/src/hardware/hw_md2.h @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index af06a198f..645a3bbae 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 1998-2020 by Sonic Team Junior. +// Copyright (C) 1998-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/http-mserv.c b/src/http-mserv.c index 7c7d04495..0b9eb2f92 100644 --- a/src/http-mserv.c +++ b/src/http-mserv.c @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2020 by James R. +// Copyright (C) 2021 by James R. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 7c4f1acf1..0c073866e 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/hu_stuff.h b/src/hu_stuff.h index 63d85f1b8..9b7cee2d3 100644 --- a/src/hu_stuff.h +++ b/src/hu_stuff.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/i_addrinfo.c b/src/i_addrinfo.c index e77774549..79709899e 100644 --- a/src/i_addrinfo.c +++ b/src/i_addrinfo.c @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2011-2020 by Sonic Team Junior. +// Copyright (C) 2011-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/i_addrinfo.h b/src/i_addrinfo.h index 7ae006719..397a1969d 100644 --- a/src/i_addrinfo.h +++ b/src/i_addrinfo.h @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2011-2020 by Sonic Team Junior. +// Copyright (C) 2011-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/i_joy.h b/src/i_joy.h index 2a2797fc4..0c7c8dd3f 100644 --- a/src/i_joy.h +++ b/src/i_joy.h @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/i_net.h b/src/i_net.h index 5d93f191e..dbc82db65 100644 --- a/src/i_net.h +++ b/src/i_net.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/i_sound.h b/src/i_sound.h index d45c0b323..e38a17626 100644 --- a/src/i_sound.h +++ b/src/i_sound.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/i_system.h b/src/i_system.h index 12f0d751d..b88ea3177 100644 --- a/src/i_system.h +++ b/src/i_system.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/i_tcp.c b/src/i_tcp.c index ab8a69a9f..679553039 100644 --- a/src/i_tcp.c +++ b/src/i_tcp.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/i_tcp.h b/src/i_tcp.h index 738b8b4d1..785734415 100644 --- a/src/i_tcp.h +++ b/src/i_tcp.h @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/i_threads.h b/src/i_threads.h index ecb9fce67..924d283c4 100644 --- a/src/i_threads.h +++ b/src/i_threads.h @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2020 by James R. +// Copyright (C) 2021 by James R. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/i_video.h b/src/i_video.h index ab48881d4..2d07fcf10 100644 --- a/src/i_video.h +++ b/src/i_video.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/info.c b/src/info.c index ee836a372..bb1279b6b 100644 --- a/src/info.c +++ b/src/info.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/info.h b/src/info.h index 60e970246..031a08b43 100644 --- a/src/info.h +++ b/src/info.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/keys.h b/src/keys.h index 6cdd7956c..b19259320 100644 --- a/src/keys.h +++ b/src/keys.h @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/lua_baselib.c b/src/lua_baselib.c index a265465da..a0c99411b 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 2012-2016 by John "JTE" Muniz. -// Copyright (C) 2012-2020 by Sonic Team Junior. +// Copyright (C) 2012-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/lua_blockmaplib.c b/src/lua_blockmaplib.c index 1949d56bb..9089d19b6 100644 --- a/src/lua_blockmaplib.c +++ b/src/lua_blockmaplib.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2016-2020 by Iestyn "Monster Iestyn" Jealous. -// Copyright (C) 2016-2020 by Sonic Team Junior. +// Copyright (C) 2016-2021 by Iestyn "Monster Iestyn" Jealous. +// Copyright (C) 2016-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/lua_consolelib.c b/src/lua_consolelib.c index a8ef6b7c0..414d9692a 100644 --- a/src/lua_consolelib.c +++ b/src/lua_consolelib.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 2012-2016 by John "JTE" Muniz. -// Copyright (C) 2012-2020 by Sonic Team Junior. +// Copyright (C) 2012-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/lua_hook.h b/src/lua_hook.h index 0d631aa4e..c22309eaa 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 2012-2016 by John "JTE" Muniz. -// Copyright (C) 2012-2020 by Sonic Team Junior. +// Copyright (C) 2012-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index a3f4a95d2..3715aae04 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 2012-2016 by John "JTE" Muniz. -// Copyright (C) 2012-2020 by Sonic Team Junior. +// Copyright (C) 2012-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/lua_hud.h b/src/lua_hud.h index 1e9dca00b..a7b1a4cf5 100644 --- a/src/lua_hud.h +++ b/src/lua_hud.h @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 2014-2016 by John "JTE" Muniz. -// Copyright (C) 2014-2020 by Sonic Team Junior. +// Copyright (C) 2014-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 8d451e99c..b0548c321 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 2014-2016 by John "JTE" Muniz. -// Copyright (C) 2014-2020 by Sonic Team Junior. +// Copyright (C) 2014-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/lua_infolib.c b/src/lua_infolib.c index 6e86f47b7..af2d99a0c 100644 --- a/src/lua_infolib.c +++ b/src/lua_infolib.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 2012-2016 by John "JTE" Muniz. -// Copyright (C) 2012-2020 by Sonic Team Junior. +// Copyright (C) 2012-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/lua_libs.h b/src/lua_libs.h index fbe8d4878..05061f118 100644 --- a/src/lua_libs.h +++ b/src/lua_libs.h @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 2012-2016 by John "JTE" Muniz. -// Copyright (C) 2012-2020 by Sonic Team Junior. +// Copyright (C) 2012-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 016141796..9031c99f1 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 2012-2016 by John "JTE" Muniz. -// Copyright (C) 2012-2020 by Sonic Team Junior. +// Copyright (C) 2012-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/lua_mathlib.c b/src/lua_mathlib.c index b6046ab53..a1dca9e15 100644 --- a/src/lua_mathlib.c +++ b/src/lua_mathlib.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 2012-2016 by John "JTE" Muniz. -// Copyright (C) 2012-2020 by Sonic Team Junior. +// Copyright (C) 2012-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index 65adceb15..5d5f0e85b 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 2012-2016 by John "JTE" Muniz. -// Copyright (C) 2012-2020 by Sonic Team Junior. +// Copyright (C) 2012-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 0eb54808f..687cee2eb 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 2012-2016 by John "JTE" Muniz. -// Copyright (C) 2012-2020 by Sonic Team Junior. +// Copyright (C) 2012-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/lua_polyobjlib.c b/src/lua_polyobjlib.c index 2a5bcfbf1..cfd6b67d4 100644 --- a/src/lua_polyobjlib.c +++ b/src/lua_polyobjlib.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2020 by Iestyn "Monster Iestyn" Jealous. -// Copyright (C) 2020 by Sonic Team Junior. +// Copyright (C) 2021 by Iestyn "Monster Iestyn" Jealous. +// Copyright (C) 2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/lua_script.c b/src/lua_script.c index 9f8432832..aa1db3aeb 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 2012-2016 by John "JTE" Muniz. -// Copyright (C) 2012-2020 by Sonic Team Junior. +// Copyright (C) 2012-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/lua_script.h b/src/lua_script.h index 89ba7b6ee..a9c8762ad 100644 --- a/src/lua_script.h +++ b/src/lua_script.h @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 2012-2016 by John "JTE" Muniz. -// Copyright (C) 2012-2020 by Sonic Team Junior. +// Copyright (C) 2012-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/lua_skinlib.c b/src/lua_skinlib.c index 7e7480be3..3370f8f72 100644 --- a/src/lua_skinlib.c +++ b/src/lua_skinlib.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 2014-2016 by John "JTE" Muniz. -// Copyright (C) 2014-2020 by Sonic Team Junior. +// Copyright (C) 2014-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/lua_taglib.c b/src/lua_taglib.c index c9f320fe8..55abb09cd 100644 --- a/src/lua_taglib.c +++ b/src/lua_taglib.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2020 by James R. -// Copyright (C) 2020 by Sonic Team Junior. +// Copyright (C) 2021 by James R. +// Copyright (C) 2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/lua_thinkerlib.c b/src/lua_thinkerlib.c index 82baa6469..65bf8c313 100644 --- a/src/lua_thinkerlib.c +++ b/src/lua_thinkerlib.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 2012-2016 by John "JTE" Muniz. -// Copyright (C) 2012-2020 by Sonic Team Junior. +// Copyright (C) 2012-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/m_aatree.c b/src/m_aatree.c index c0bb739f8..b228ed63d 100644 --- a/src/m_aatree.c +++ b/src/m_aatree.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/m_aatree.h b/src/m_aatree.h index b784eb17a..5a240394f 100644 --- a/src/m_aatree.h +++ b/src/m_aatree.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/m_anigif.c b/src/m_anigif.c index 41f99254e..fe04a5cb4 100644 --- a/src/m_anigif.c +++ b/src/m_anigif.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 2013-2016 by Matthew "Kaito Sinclaire" Walsh. // Copyright (C) 2013 by "Ninji". -// Copyright (C) 2013-2020 by Sonic Team Junior. +// Copyright (C) 2013-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/m_anigif.h b/src/m_anigif.h index abe05dd96..ca7563b1e 100644 --- a/src/m_anigif.h +++ b/src/m_anigif.h @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 2013-2016 by Matthew "Kaito Sinclaire" Walsh. -// Copyright (C) 2013-2020 by Sonic Team Junior. +// Copyright (C) 2013-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/m_argv.c b/src/m_argv.c index 7d43d96bc..453d6e45c 100644 --- a/src/m_argv.c +++ b/src/m_argv.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/m_argv.h b/src/m_argv.h index 92770f4e9..f39db513f 100644 --- a/src/m_argv.h +++ b/src/m_argv.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/m_bbox.c b/src/m_bbox.c index 02d534164..e0505fd95 100644 --- a/src/m_bbox.c +++ b/src/m_bbox.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/m_bbox.h b/src/m_bbox.h index 9b63c61b6..c56bd22c0 100644 --- a/src/m_bbox.h +++ b/src/m_bbox.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/m_cheat.c b/src/m_cheat.c index 6e0fb8c5c..c958bb4a4 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/m_cheat.h b/src/m_cheat.h index ac2540408..ee4ba5f55 100644 --- a/src/m_cheat.h +++ b/src/m_cheat.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/m_cond.c b/src/m_cond.c index 36fcd7cf2..a54238ab2 100644 --- a/src/m_cond.c +++ b/src/m_cond.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 2012-2016 by Matthew "Kaito Sinclaire" Walsh. -// Copyright (C) 2012-2020 by Sonic Team Junior. +// Copyright (C) 2012-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/m_cond.h b/src/m_cond.h index 9bb162ff3..690b6fb26 100644 --- a/src/m_cond.h +++ b/src/m_cond.h @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 2012-2016 by Matthew "Kaito Sinclaire" Walsh. -// Copyright (C) 2012-2020 by Sonic Team Junior. +// Copyright (C) 2012-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/m_dllist.h b/src/m_dllist.h index 680c2cd80..65303b4a3 100644 --- a/src/m_dllist.h +++ b/src/m_dllist.h @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 2005 by James Haley -// Copyright (C) 2005-2020 by Sonic Team Junior. +// Copyright (C) 2005-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/m_fixed.c b/src/m_fixed.c index eb10fd5f8..d40ccd98e 100644 --- a/src/m_fixed.c +++ b/src/m_fixed.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/m_fixed.h b/src/m_fixed.h index 289ca442a..73adf52f6 100644 --- a/src/m_fixed.h +++ b/src/m_fixed.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/m_menu.c b/src/m_menu.c index 13531f1b8..496ce6b4c 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -3,7 +3,7 @@ // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. // Copyright (C) 2011-2016 by Matthew "Kaito Sinclaire" Walsh. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/m_menu.h b/src/m_menu.h index 0465128ef..ba9c326a0 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -3,7 +3,7 @@ // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. // Copyright (C) 2011-2016 by Matthew "Kaito Sinclaire" Walsh. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/m_misc.c b/src/m_misc.c index 17a398b83..999ee0961 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/m_misc.h b/src/m_misc.h index c5ef9f9f2..fc5430f01 100644 --- a/src/m_misc.h +++ b/src/m_misc.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/m_perfstats.c b/src/m_perfstats.c index b58599b6d..c4b2044b3 100644 --- a/src/m_perfstats.c +++ b/src/m_perfstats.c @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2020 by Sonic Team Junior. +// Copyright (C) 2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/m_perfstats.h b/src/m_perfstats.h index 1ca71957f..8f87146f2 100644 --- a/src/m_perfstats.h +++ b/src/m_perfstats.h @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2020 by Sonic Team Junior. +// Copyright (C) 2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/m_queue.c b/src/m_queue.c index 8603ab202..a337ca4ce 100644 --- a/src/m_queue.c +++ b/src/m_queue.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 2003 by James Haley -// Copyright (C) 2003-2020 by Sonic Team Junior. +// Copyright (C) 2003-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/m_queue.h b/src/m_queue.h index 3e9579e11..cc64b8dd7 100644 --- a/src/m_queue.h +++ b/src/m_queue.h @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 2003 by James Haley -// Copyright (C) 2003-2020 by Sonic Team Junior. +// Copyright (C) 2003-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/m_random.c b/src/m_random.c index 481fdb72b..6b281fc24 100644 --- a/src/m_random.c +++ b/src/m_random.c @@ -3,7 +3,7 @@ // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. // Copyright (C) 2012-2016 by Matthew "Kaito Sinclaire" Walsh. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/m_random.h b/src/m_random.h index 01190e046..df10b4bb3 100644 --- a/src/m_random.h +++ b/src/m_random.h @@ -3,7 +3,7 @@ // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. // Copyright (C) 2012-2016 by Matthew "Kaito Sinclaire" Walsh. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/m_swap.h b/src/m_swap.h index b44d6de8c..6aa347d97 100644 --- a/src/m_swap.h +++ b/src/m_swap.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/mserv.c b/src/mserv.c index dfb417415..f46a3d444 100644 --- a/src/mserv.c +++ b/src/mserv.c @@ -1,8 +1,8 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. -// Copyright (C) 2020 by James R. +// Copyright (C) 1999-2021 by Sonic Team Junior. +// Copyright (C) 2021 by James R. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/mserv.h b/src/mserv.h index d0d5e49df..ff12fa1f8 100644 --- a/src/mserv.h +++ b/src/mserv.h @@ -1,8 +1,8 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. -// Copyright (C) 2020 by James R. +// Copyright (C) 1999-2021 by Sonic Team Junior. +// Copyright (C) 2021 by James R. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/p_ceilng.c b/src/p_ceilng.c index f12499d5c..ac93e8e2e 100644 --- a/src/p_ceilng.c +++ b/src/p_ceilng.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/p_enemy.c b/src/p_enemy.c index 51f18f596..ca88b7831 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/p_floor.c b/src/p_floor.c index 7c26065b5..d7e417f5c 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/p_inter.c b/src/p_inter.c index e9a16a3dd..380040bc8 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/p_lights.c b/src/p_lights.c index d396e92d3..937808ef1 100644 --- a/src/p_lights.c +++ b/src/p_lights.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/p_local.h b/src/p_local.h index 8568dd4f8..1fcd3050d 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/p_map.c b/src/p_map.c index bf668ba3e..19b999c43 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/p_maputl.c b/src/p_maputl.c index 90718a41c..efcebe736 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/p_maputl.h b/src/p_maputl.h index 08b606833..cec344d03 100644 --- a/src/p_maputl.h +++ b/src/p_maputl.h @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/p_mobj.c b/src/p_mobj.c index 49db6daee..690842270 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/p_mobj.h b/src/p_mobj.h index 5bb7c908e..82cd056a8 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/p_polyobj.c b/src/p_polyobj.c index 874edbd50..6431e4624 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 2006 by James Haley -// Copyright (C) 2006-2020 by Sonic Team Junior. +// Copyright (C) 2006-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/p_polyobj.h b/src/p_polyobj.h index 8c2946965..7c814e0bf 100644 --- a/src/p_polyobj.h +++ b/src/p_polyobj.h @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 2006 by James Haley -// Copyright (C) 2006-2020 by Sonic Team Junior. +// Copyright (C) 2006-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/p_pspr.h b/src/p_pspr.h index 231262beb..4525ba14c 100644 --- a/src/p_pspr.h +++ b/src/p_pspr.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/p_saveg.c b/src/p_saveg.c index 03229e740..ba4d8a32e 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/p_saveg.h b/src/p_saveg.h index be98953eb..ed9297a4d 100644 --- a/src/p_saveg.h +++ b/src/p_saveg.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/p_setup.c b/src/p_setup.c index 40dd1a284..5a8248a28 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/p_setup.h b/src/p_setup.h index 5d13ae7d4..9fa70d516 100644 --- a/src/p_setup.h +++ b/src/p_setup.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/p_sight.c b/src/p_sight.c index 2e1e49997..e4a37a718 100644 --- a/src/p_sight.c +++ b/src/p_sight.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/p_slopes.c b/src/p_slopes.c index aa46a8402..05955c5d6 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 2004 by Stephen McGranahan -// Copyright (C) 2015-2020 by Sonic Team Junior. +// Copyright (C) 2015-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/p_slopes.h b/src/p_slopes.h index 46e8dc1e7..ae040ae56 100644 --- a/src/p_slopes.h +++ b/src/p_slopes.h @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 2004 by Stephen McGranahan -// Copyright (C) 2015-2020 by Sonic Team Junior. +// Copyright (C) 2015-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/p_spec.c b/src/p_spec.c index 226e58d15..0bb12cf58 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/p_spec.h b/src/p_spec.h index bba7c4a40..3b8abfcf8 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/p_telept.c b/src/p_telept.c index f6feddf4b..6bac5ad20 100644 --- a/src/p_telept.c +++ b/src/p_telept.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/p_tick.c b/src/p_tick.c index c0a1c5700..9f00ef8dc 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/p_tick.h b/src/p_tick.h index 1fb88f3f2..ae481c6a2 100644 --- a/src/p_tick.h +++ b/src/p_tick.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/p_user.c b/src/p_user.c index 4413cc6cd..29770ccb5 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/r_bsp.c b/src/r_bsp.c index 6f2a90d2d..5acd4e70c 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/r_bsp.h b/src/r_bsp.h index e2da8ebaf..40d24ffec 100644 --- a/src/r_bsp.h +++ b/src/r_bsp.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/r_data.h b/src/r_data.h index aec52b54b..571fdc54f 100644 --- a/src/r_data.h +++ b/src/r_data.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/r_defs.h b/src/r_defs.h index 9c649fbc4..1be3a1b8c 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/r_draw16.c b/src/r_draw16.c index 8b1d29e8d..1a2fed773 100644 --- a/src/r_draw16.c +++ b/src/r_draw16.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/r_draw8_npo2.c b/src/r_draw8_npo2.c index a34a20e9a..6bb2880b2 100644 --- a/src/r_draw8_npo2.c +++ b/src/r_draw8_npo2.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/r_local.h b/src/r_local.h index 4ccb766cf..ba78ea87d 100644 --- a/src/r_local.h +++ b/src/r_local.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/r_main.c b/src/r_main.c index 04bdebc58..be9bbd7d0 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/r_main.h b/src/r_main.h index 2ac6abf5a..f81447c45 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/r_patch.c b/src/r_patch.c index 1a08d1892..ef41aa574 100644 --- a/src/r_patch.c +++ b/src/r_patch.c @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2020 by Jaime "Lactozilla" Passos. +// Copyright (C) 2021 by Jaime "Lactozilla" Passos. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/r_patch.h b/src/r_patch.h index 32bcb3909..d4ca8e6ee 100644 --- a/src/r_patch.h +++ b/src/r_patch.h @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2020 by Jaime "Lactozilla" Passos. +// Copyright (C) 2021 by Jaime "Lactozilla" Passos. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/r_patchrotation.c b/src/r_patchrotation.c index 123c4eef2..a6c2b41ce 100644 --- a/src/r_patchrotation.c +++ b/src/r_patchrotation.c @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2020 by Jaime "Lactozilla" Passos. +// Copyright (C) 2021 by Jaime "Lactozilla" Passos. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/r_patchrotation.h b/src/r_patchrotation.h index 2744f71d2..c64a08366 100644 --- a/src/r_patchrotation.h +++ b/src/r_patchrotation.h @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2020 by Jaime "Lactozilla" Passos. +// Copyright (C) 2021 by Jaime "Lactozilla" Passos. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/r_picformats.c b/src/r_picformats.c index f87362c76..3bbbf82ec 100644 --- a/src/r_picformats.c +++ b/src/r_picformats.c @@ -2,8 +2,8 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 2005-2009 by Andrey "entryway" Budko. -// Copyright (C) 2018-2020 by Jaime "Lactozilla" Passos. -// Copyright (C) 2019-2020 by Sonic Team Junior. +// Copyright (C) 2018-2021 by Jaime "Lactozilla" Passos. +// Copyright (C) 2019-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/r_picformats.h b/src/r_picformats.h index 8d3999013..b1bb35edd 100644 --- a/src/r_picformats.h +++ b/src/r_picformats.h @@ -1,8 +1,8 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. -// Copyright (C) 2018-2020 by Jaime "Lactozilla" Passos. -// Copyright (C) 2019-2020 by Sonic Team Junior. +// Copyright (C) 2018-2021 by Jaime "Lactozilla" Passos. +// Copyright (C) 2019-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/r_plane.h b/src/r_plane.h index 0d11c5b72..748a7f007 100644 --- a/src/r_plane.h +++ b/src/r_plane.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/r_portal.c b/src/r_portal.c index 1aca145ec..3026f4e4c 100644 --- a/src/r_portal.c +++ b/src/r_portal.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/r_portal.h b/src/r_portal.h index e665a26e6..0effd07b5 100644 --- a/src/r_portal.h +++ b/src/r_portal.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/r_segs.c b/src/r_segs.c index a6772f964..c9f9bbfe6 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/r_segs.h b/src/r_segs.h index ace5711d4..da7d44ad4 100644 --- a/src/r_segs.h +++ b/src/r_segs.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/r_skins.c b/src/r_skins.c index 6f150f234..7b6c4517b 100644 --- a/src/r_skins.c +++ b/src/r_skins.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/r_skins.h b/src/r_skins.h index fbbb38743..3f67bfdab 100644 --- a/src/r_skins.h +++ b/src/r_skins.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/r_sky.c b/src/r_sky.c index 7cdcfa44d..041cccfc5 100644 --- a/src/r_sky.c +++ b/src/r_sky.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/r_sky.h b/src/r_sky.h index 55d866b86..f4356dcfa 100644 --- a/src/r_sky.h +++ b/src/r_sky.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/r_splats.h b/src/r_splats.h index 05d8b66b0..cab3d63b6 100644 --- a/src/r_splats.h +++ b/src/r_splats.h @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/r_state.h b/src/r_state.h index 25aa69702..5a606ed8c 100644 --- a/src/r_state.h +++ b/src/r_state.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/r_textures.h b/src/r_textures.h index 74a94a9ed..dd286b6ac 100644 --- a/src/r_textures.h +++ b/src/r_textures.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/r_things.h b/src/r_things.h index 95b4215af..9315b36e9 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/s_sound.c b/src/s_sound.c index 392a5b453..ea1479cae 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/s_sound.h b/src/s_sound.h index 4ac3c70bf..f736833f9 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/screen.c b/src/screen.c index d37724390..770f1c802 100644 --- a/src/screen.c +++ b/src/screen.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/screen.h b/src/screen.h index e4944775d..67880e2b9 100644 --- a/src/screen.h +++ b/src/screen.h @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index a0dd6e1da..df29e348b 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -5,7 +5,7 @@ // // Copyright (C) 1993-1996 by id Software, Inc. // Portions Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 2014-2020 by Sonic Team Junior. +// Copyright (C) 2014-2021 by Sonic Team Junior. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License diff --git a/src/sdl/i_threads.c b/src/sdl/i_threads.c index 3b1c20b9a..bf9668584 100644 --- a/src/sdl/i_threads.c +++ b/src/sdl/i_threads.c @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2020 by James R. +// Copyright (C) 2021 by James R. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 0ed10463f..5f18720f8 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -4,7 +4,7 @@ // // Copyright (C) 1993-1996 by id Software, Inc. // Portions Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 2014-2020 by Sonic Team Junior. +// Copyright (C) 2014-2021 by Sonic Team Junior. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index 412a21ea0..2f1a87266 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2014-2020 by Sonic Team Junior. +// Copyright (C) 2014-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -1301,7 +1301,7 @@ boolean I_PlaySong(boolean looping) #if defined (GME_VERSION) && GME_VERSION >= 0x000603 if (looping) gme_set_autoload_playback_limit(gme, 0); -#endif +#endif gme_set_equalizer(gme, &eq); gme_start_track(gme, 0); current_track = 0; diff --git a/src/sdl/ogl_sdl.c b/src/sdl/ogl_sdl.c index 52727c056..c426e6792 100644 --- a/src/sdl/ogl_sdl.c +++ b/src/sdl/ogl_sdl.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 2014-2020 by Sonic Team Junior. +// Copyright (C) 2014-2021 by Sonic Team Junior. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License diff --git a/src/sdl/ogl_sdl.h b/src/sdl/ogl_sdl.h index 748e30bae..8f87f688e 100644 --- a/src/sdl/ogl_sdl.h +++ b/src/sdl/ogl_sdl.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 2014-2020 by Sonic Team Junior. +// Copyright (C) 2014-2021 by Sonic Team Junior. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License diff --git a/src/sdl/sdl_sound.c b/src/sdl/sdl_sound.c index 86e294fb5..058b601c3 100644 --- a/src/sdl/sdl_sound.c +++ b/src/sdl/sdl_sound.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // // Copyright (C) 1993-1996 by id Software, Inc. -// Copyright (C) 2014-2020 by Sonic Team Junior. +// Copyright (C) 2014-2021 by Sonic Team Junior. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License diff --git a/src/sdl/sdlmain.h b/src/sdl/sdlmain.h index e35506114..a9676b5c2 100644 --- a/src/sdl/sdlmain.h +++ b/src/sdl/sdlmain.h @@ -1,7 +1,7 @@ // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // -// Copyright (C) 2006-2020 by Sonic Team Junior. +// Copyright (C) 2006-2021 by Sonic Team Junior. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License diff --git a/src/sounds.c b/src/sounds.c index 092bda21f..4c5b11ee9 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/sounds.h b/src/sounds.h index e49dd2f3e..2dd37953c 100644 --- a/src/sounds.h +++ b/src/sounds.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/st_stuff.c b/src/st_stuff.c index a1fbbec03..a0457ba53 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/st_stuff.h b/src/st_stuff.h index 4ea307d2b..b1ea2942d 100644 --- a/src/st_stuff.h +++ b/src/st_stuff.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/strcasestr.c b/src/strcasestr.c index b266278ed..1cbee286a 100644 --- a/src/strcasestr.c +++ b/src/strcasestr.c @@ -2,7 +2,7 @@ strcasestr -- case insensitive substring searching function. */ /* -Copyright 2019-2020 James R. +Copyright 2019-2021 James R. All rights reserved. Redistribution and use in source forms, with or without modification, is diff --git a/src/string.c b/src/string.c index e430c5cc3..f32025612 100644 --- a/src/string.c +++ b/src/string.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 2006 by Graue. -// Copyright (C) 2006-2020 by Sonic Team Junior. +// Copyright (C) 2006-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/tables.c b/src/tables.c index 70a1ecd0a..9263f42d3 100644 --- a/src/tables.c +++ b/src/tables.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/tables.h b/src/tables.h index 953d891ce..baa3adf36 100644 --- a/src/tables.h +++ b/src/tables.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/taglist.c b/src/taglist.c index a759f4d02..1b4a64ecd 100644 --- a/src/taglist.c +++ b/src/taglist.c @@ -1,8 +1,8 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. -// Copyright (C) 2020 by Nev3r. +// Copyright (C) 1999-2021 by Sonic Team Junior. +// Copyright (C) 2021 by Nev3r. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/taglist.h b/src/taglist.h index a0529ab6b..80100f80a 100644 --- a/src/taglist.h +++ b/src/taglist.h @@ -1,8 +1,8 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. -// Copyright (C) 2020 by Nev3r. +// Copyright (C) 1999-2021 by Sonic Team Junior. +// Copyright (C) 2021 by Nev3r. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/tmap.nas b/src/tmap.nas index 69282d0b4..5bf28359e 100644 --- a/src/tmap.nas +++ b/src/tmap.nas @@ -1,7 +1,7 @@ ;; SONIC ROBO BLAST 2 ;;----------------------------------------------------------------------------- ;; Copyright (C) 1998-2000 by DooM Legacy Team. -;; Copyright (C) 1999-2020 by Sonic Team Junior. +;; Copyright (C) 1999-2021 by Sonic Team Junior. ;; ;; This program is free software distributed under the ;; terms of the GNU General Public License, version 2. diff --git a/src/tmap.s b/src/tmap.s index 3a4cf2e1a..62dcf85dc 100644 --- a/src/tmap.s +++ b/src/tmap.s @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/tmap_asm.s b/src/tmap_asm.s index 3cd0f87cc..b5a0a51e9 100644 --- a/src/tmap_asm.s +++ b/src/tmap_asm.s @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/tmap_mmx.nas b/src/tmap_mmx.nas index 15b97499d..8b6ef91a6 100644 --- a/src/tmap_mmx.nas +++ b/src/tmap_mmx.nas @@ -1,7 +1,7 @@ ;; SONIC ROBO BLAST 2 ;;----------------------------------------------------------------------------- ;; Copyright (C) 1998-2000 by DOSDOOM. -;; Copyright (C) 2010-2020 by Sonic Team Junior. +;; Copyright (C) 2010-2021 by Sonic Team Junior. ;; ;; This program is free software distributed under the ;; terms of the GNU General Public License, version 2. diff --git a/src/tmap_vc.nas b/src/tmap_vc.nas index 49eb21a6d..b6ee26e6b 100644 --- a/src/tmap_vc.nas +++ b/src/tmap_vc.nas @@ -1,7 +1,7 @@ ;; SONIC ROBO BLAST 2 ;;----------------------------------------------------------------------------- ;; Copyright (C) 1998-2000 by DooM Legacy Team. -;; Copyright (C) 1999-2020 by Sonic Team Junior. +;; Copyright (C) 1999-2021 by Sonic Team Junior. ;; ;; This program is free software distributed under the ;; terms of the GNU General Public License, version 2. diff --git a/src/v_video.c b/src/v_video.c index 4713db0d8..9cbf6d792 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/v_video.h b/src/v_video.h index 8a18f82ad..7184e799e 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/vid_copy.s b/src/vid_copy.s index eae435ea4..6a3788356 100644 --- a/src/vid_copy.s +++ b/src/vid_copy.s @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/w_wad.c b/src/w_wad.c index 6149aec6e..cbff5c67b 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/w_wad.h b/src/w_wad.h index d0a86bcb4..130967712 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/win32/Srb2win.rc b/src/win32/Srb2win.rc index b0eb2532e..0a280448b 100644 --- a/src/win32/Srb2win.rc +++ b/src/win32/Srb2win.rc @@ -97,7 +97,7 @@ BEGIN VALUE "FileDescription", "Sonic Robo Blast 2\0" VALUE "FileVersion", VERSIONSTRING_RC VALUE "InternalName", "srb2\0" - VALUE "LegalCopyright", "Copyright 1998-2020 by Sonic Team Junior\0" + VALUE "LegalCopyright", "Copyright 1998-2021 by Sonic Team Junior\0" VALUE "LegalTrademarks", "Sonic the Hedgehog and related characters are trademarks of Sega.\0" VALUE "OriginalFilename", "srb2win.exe\0" VALUE "PrivateBuild", "\0" diff --git a/src/y_inter.c b/src/y_inter.c index 4354a1677..dc78a1983 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2004-2020 by Sonic Team Junior. +// Copyright (C) 2004-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/y_inter.h b/src/y_inter.h index 7268b1a47..871142858 100644 --- a/src/y_inter.h +++ b/src/y_inter.h @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2004-2020 by Sonic Team Junior. +// Copyright (C) 2004-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/z_zone.c b/src/z_zone.c index d7da17e51..34ff3d37e 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 2006 by Graue. -// Copyright (C) 2006-2020 by Sonic Team Junior. +// Copyright (C) 2006-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/z_zone.h b/src/z_zone.h index 7b58be8f3..be55bf994 100644 --- a/src/z_zone.h +++ b/src/z_zone.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2020 by Sonic Team Junior. +// Copyright (C) 1999-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. From 07e69c5eb30d83f229e42db460dd180c3188f9dd Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Fri, 7 May 2021 18:04:30 +0200 Subject: [PATCH 443/644] Add copyright date ranges for files created in 2020 --- src/hardware/hw_batching.c | 2 +- src/hardware/hw_batching.h | 2 +- src/http-mserv.c | 2 +- src/i_threads.h | 2 +- src/lua_polyobjlib.c | 4 ++-- src/lua_taglib.c | 4 ++-- src/m_perfstats.c | 2 +- src/m_perfstats.h | 2 +- src/mserv.c | 2 +- src/mserv.h | 2 +- src/r_patch.c | 2 +- src/r_patch.h | 2 +- src/r_patchrotation.c | 2 +- src/r_patchrotation.h | 2 +- src/sdl/i_threads.c | 2 +- src/taglist.c | 2 +- src/taglist.h | 2 +- 17 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/hardware/hw_batching.c b/src/hardware/hw_batching.c index 3a8eef55e..0ac33d136 100644 --- a/src/hardware/hw_batching.c +++ b/src/hardware/hw_batching.c @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2021 by Sonic Team Junior. +// Copyright (C) 2020-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/hardware/hw_batching.h b/src/hardware/hw_batching.h index d886dcf2a..9ccc7de3d 100644 --- a/src/hardware/hw_batching.h +++ b/src/hardware/hw_batching.h @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2021 by Sonic Team Junior. +// Copyright (C) 2020-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/http-mserv.c b/src/http-mserv.c index 0b9eb2f92..f9134ba50 100644 --- a/src/http-mserv.c +++ b/src/http-mserv.c @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2021 by James R. +// Copyright (C) 2020-2021 by James R. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/i_threads.h b/src/i_threads.h index 924d283c4..bc752181f 100644 --- a/src/i_threads.h +++ b/src/i_threads.h @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2021 by James R. +// Copyright (C) 2020-2021 by James R. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/lua_polyobjlib.c b/src/lua_polyobjlib.c index cfd6b67d4..5d76a912d 100644 --- a/src/lua_polyobjlib.c +++ b/src/lua_polyobjlib.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2021 by Iestyn "Monster Iestyn" Jealous. -// Copyright (C) 2021 by Sonic Team Junior. +// Copyright (C) 2020-2021 by Iestyn "Monster Iestyn" Jealous. +// Copyright (C) 2020-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/lua_taglib.c b/src/lua_taglib.c index 55abb09cd..d0cf385a9 100644 --- a/src/lua_taglib.c +++ b/src/lua_taglib.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2021 by James R. -// Copyright (C) 2021 by Sonic Team Junior. +// Copyright (C) 2020-2021 by James R. +// Copyright (C) 2020-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/m_perfstats.c b/src/m_perfstats.c index c4b2044b3..8a99312e6 100644 --- a/src/m_perfstats.c +++ b/src/m_perfstats.c @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2021 by Sonic Team Junior. +// Copyright (C) 2020-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/m_perfstats.h b/src/m_perfstats.h index 8f87146f2..71208fbc1 100644 --- a/src/m_perfstats.h +++ b/src/m_perfstats.h @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2021 by Sonic Team Junior. +// Copyright (C) 2020-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/mserv.c b/src/mserv.c index f46a3d444..f64c7bea9 100644 --- a/src/mserv.c +++ b/src/mserv.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. // Copyright (C) 1999-2021 by Sonic Team Junior. -// Copyright (C) 2021 by James R. +// Copyright (C) 2020-2021 by James R. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/mserv.h b/src/mserv.h index ff12fa1f8..7a3b3d8ec 100644 --- a/src/mserv.h +++ b/src/mserv.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. // Copyright (C) 1999-2021 by Sonic Team Junior. -// Copyright (C) 2021 by James R. +// Copyright (C) 2020-2021 by James R. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/r_patch.c b/src/r_patch.c index ef41aa574..6827cd12c 100644 --- a/src/r_patch.c +++ b/src/r_patch.c @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2021 by Jaime "Lactozilla" Passos. +// Copyright (C) 2020-2021 by Jaime "Lactozilla" Passos. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/r_patch.h b/src/r_patch.h index d4ca8e6ee..96fbb0e28 100644 --- a/src/r_patch.h +++ b/src/r_patch.h @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2021 by Jaime "Lactozilla" Passos. +// Copyright (C) 2020-2021 by Jaime "Lactozilla" Passos. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/r_patchrotation.c b/src/r_patchrotation.c index a6c2b41ce..a9b4a2b8f 100644 --- a/src/r_patchrotation.c +++ b/src/r_patchrotation.c @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2021 by Jaime "Lactozilla" Passos. +// Copyright (C) 2020-2021 by Jaime "Lactozilla" Passos. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/r_patchrotation.h b/src/r_patchrotation.h index c64a08366..689b7d411 100644 --- a/src/r_patchrotation.h +++ b/src/r_patchrotation.h @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2021 by Jaime "Lactozilla" Passos. +// Copyright (C) 2020-2021 by Jaime "Lactozilla" Passos. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/sdl/i_threads.c b/src/sdl/i_threads.c index bf9668584..f73d00bcf 100644 --- a/src/sdl/i_threads.c +++ b/src/sdl/i_threads.c @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2021 by James R. +// Copyright (C) 2020-2021 by James R. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/taglist.c b/src/taglist.c index 1b4a64ecd..28fa48c25 100644 --- a/src/taglist.c +++ b/src/taglist.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. // Copyright (C) 1999-2021 by Sonic Team Junior. -// Copyright (C) 2021 by Nev3r. +// Copyright (C) 2020-2021 by Nev3r. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. diff --git a/src/taglist.h b/src/taglist.h index 80100f80a..146d76131 100644 --- a/src/taglist.h +++ b/src/taglist.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. // Copyright (C) 1999-2021 by Sonic Team Junior. -// Copyright (C) 2021 by Nev3r. +// Copyright (C) 2020-2021 by Nev3r. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. From 8e8881b534e5844e45a06f9bdbfb3f6728a8f9cd Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 7 May 2021 14:14:31 -0400 Subject: [PATCH 444/644] Fix custom title card text not looping properly --- src/st_stuff.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/st_stuff.c b/src/st_stuff.c index a1fbbec03..5f7307b58 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1367,7 +1367,7 @@ void ST_drawTitleCard(void) zzticker = lt_ticker; V_DrawMappedPatch(FixedInt(lt_zigzag), (-zzticker) % zigzag->height, V_SNAPTOTOP|V_SNAPTOLEFT, zigzag, colormap); V_DrawMappedPatch(FixedInt(lt_zigzag), (zigzag->height-zzticker) % zigzag->height, V_SNAPTOTOP|V_SNAPTOLEFT, zigzag, colormap); - V_DrawMappedPatch(FixedInt(lt_zigzag), (-zigzag->height+zzticker) % zztext->height, V_SNAPTOTOP|V_SNAPTOLEFT, zztext, colormap); + V_DrawMappedPatch(FixedInt(lt_zigzag), (-zztext->height+zzticker) % zztext->height, V_SNAPTOTOP|V_SNAPTOLEFT, zztext, colormap); V_DrawMappedPatch(FixedInt(lt_zigzag), (zzticker) % zztext->height, V_SNAPTOTOP|V_SNAPTOLEFT, zztext, colormap); } From 44782654001339da3ec60e3b31772b198cd11d03 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 7 May 2021 14:15:37 -0400 Subject: [PATCH 445/644] Fix title card patches not actually having enough room for an entire lump name --- src/doomstat.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/doomstat.h b/src/doomstat.h index 2d28b81af..ee6756759 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -337,9 +337,9 @@ typedef struct fixed_t gravity; ///< Map-wide gravity. // Title card. - char ltzzpatch[8]; ///< Zig zag patch. - char ltzztext[8]; ///< Zig zag text. - char ltactdiamond[8]; ///< Act diamond. + char ltzzpatch[9]; ///< Zig zag patch. + char ltzztext[9]; ///< Zig zag text. + char ltactdiamond[9]; ///< Act diamond. // Freed animals stuff. UINT8 numFlickies; ///< Internal. For freed flicky support. From c06817d0085ee77b0027917bca91a24e60c7deba Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 7 May 2021 15:30:46 -0700 Subject: [PATCH 446/644] Makefile: fix mingw/64 swapped with 32-bit --- src/Makefile.d/platform.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Makefile.d/platform.mk b/src/Makefile.d/platform.mk index be8d35830..f13488823 100644 --- a/src/Makefile.d/platform.mk +++ b/src/Makefile.d/platform.mk @@ -47,9 +47,9 @@ NOASM=1 # but we make that assumption elsewhere # Once that changes, remove this X86_64=1 -platform=mingw -else platform=mingw/64 +else +platform=mingw endif include Makefile.d/win32.mk endif From 9e7d80c2c44199126fa451c59fca0f98d23ad14d Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 7 May 2021 16:08:24 -0700 Subject: [PATCH 447/644] Makefile: suppress DEL error --- src/Makefile.d/platform.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile.d/platform.mk b/src/Makefile.d/platform.mk index f13488823..531d073e9 100644 --- a/src/Makefile.d/platform.mk +++ b/src/Makefile.d/platform.mk @@ -5,7 +5,7 @@ PKG_CONFIG?=pkg-config ifdef WINDOWSHELL -rmrf=2>NUL DEL /S /Q +rmrf=-2>NUL DEL /S /Q mkdir=-2>NUL MD else rmrf=rm -rf From dc6851dabc376a939673fadac8bacc903e74127e Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Thu, 6 May 2021 17:41:43 -0400 Subject: [PATCH 448/644] Save skin name instead of skin number into save files Allows you to save a game as any character, and you don't have to load the files in a specific order to access the save file. --- src/g_game.c | 25 +++++++++++- src/m_menu.c | 105 ++++++++++++++++++++++++++++++++++++++------------ src/p_saveg.c | 49 ++++++++++++++++++++--- src/p_saveg.h | 2 + 4 files changed, 150 insertions(+), 31 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 399c4f2bd..08d07dbbb 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -4619,6 +4619,9 @@ void G_SaveGameOver(UINT32 slot, boolean modifylives) UINT8 *end_p = savebuffer + length; UINT8 *lives_p; SINT8 pllives; +#ifdef NEWSKINSAVES + INT16 backwardsCompat = 0; +#endif save_p = savebuffer; // Version check @@ -4637,9 +4640,29 @@ void G_SaveGameOver(UINT32 slot, boolean modifylives) // P_UnArchivePlayer() CHECKPOS - (void)READUINT16(save_p); +#ifdef NEWSKINSAVES + backwardsCompat = READUINT16(save_p); CHECKPOS + if (backwardsCompat == NEWSKINSAVES) // New save, read skin names +#endif + { + boolean haveBot = false; + char ourSkinName[SKINNAMESIZE+1]; + + READSTRINGN(save_p, ourSkinName, SKINNAMESIZE); + CHECKPOS + haveBot = (boolean)READUINT8(save_p); + CHECKPOS + + if (haveBot == true) + { + char botSkinName[SKINNAMESIZE+1]; + READSTRINGN(save_p, botSkinName, SKINNAMESIZE); + CHECKPOS + } + } + WRITEUINT8(save_p, numgameovers); CHECKPOS diff --git a/src/m_menu.c b/src/m_menu.c index 40215090c..03487e2fa 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -62,6 +62,8 @@ #include "i_joy.h" // for joystick menu controls +#include "p_saveg.h" // Only for NEWSKINSAVES + // Condition Sets #include "m_cond.h" @@ -8580,7 +8582,7 @@ static void M_LoadSelect(INT32 choice) #define VERSIONSIZE 16 #define BADSAVE { savegameinfo[slot].lives = -666; Z_Free(savebuffer); return; } -#define CHECKPOS if (save_p >= end_p) BADSAVE +#define CHECKPOS if (sav_p >= end_p) BADSAVE // Reads the save file to list lives, level, player, etc. // Tails 05-29-2003 static void M_ReadSavegameInfo(UINT32 slot) @@ -8589,10 +8591,13 @@ static void M_ReadSavegameInfo(UINT32 slot) char savename[255]; UINT8 *savebuffer; UINT8 *end_p; // buffer end point, don't read past here - UINT8 *save_p; + UINT8 *sav_p; INT32 fake; // Dummy variable char temp[sizeof(timeattackfolder)]; char vcheck[VERSIONSIZE]; +#ifdef NEWSKINSAVES + INT16 backwardsCompat = 0; +#endif sprintf(savename, savegamename, slot); @@ -8608,19 +8613,19 @@ static void M_ReadSavegameInfo(UINT32 slot) end_p = savebuffer + length; // skip the description field - save_p = savebuffer; + sav_p = savebuffer; // Version check memset(vcheck, 0, sizeof (vcheck)); sprintf(vcheck, "version %d", VERSION); - if (strcmp((const char *)save_p, (const char *)vcheck)) BADSAVE - save_p += VERSIONSIZE; + if (strcmp((const char *)sav_p, (const char *)vcheck)) BADSAVE + sav_p += VERSIONSIZE; // dearchive all the modifications // P_UnArchiveMisc() CHECKPOS - fake = READINT16(save_p); + fake = READINT16(sav_p); if (((fake-1) & 8191) >= NUMMAPS) BADSAVE @@ -8637,54 +8642,104 @@ static void M_ReadSavegameInfo(UINT32 slot) savegameinfo[slot].gamemap = fake; CHECKPOS - savegameinfo[slot].numemeralds = READUINT16(save_p)-357; // emeralds + savegameinfo[slot].numemeralds = READUINT16(sav_p)-357; // emeralds CHECKPOS - READSTRINGN(save_p, temp, sizeof(temp)); // mod it belongs to + READSTRINGN(sav_p, temp, sizeof(temp)); // mod it belongs to if (strcmp(temp, timeattackfolder)) BADSAVE // P_UnArchivePlayer() +#ifdef NEWSKINSAVES CHECKPOS - fake = READUINT16(save_p); - savegameinfo[slot].skinnum = fake & ((1<<5) - 1); - if (savegameinfo[slot].skinnum >= numskins - || !R_SkinUsable(-1, savegameinfo[slot].skinnum)) - BADSAVE - savegameinfo[slot].botskin = fake >> 5; - if (savegameinfo[slot].botskin-1 >= numskins - || !R_SkinUsable(-1, savegameinfo[slot].botskin-1)) - BADSAVE + backwardsCompat = READUINT16(sav_p); + + if (backwardsCompat != NEWSKINSAVES) + { + CONS_Printf("Old behavior for %d\n", slot); + + // Backwards compat + savegameinfo[slot].skinnum = backwardsCompat & ((1<<5) - 1); + + if (savegameinfo[slot].skinnum >= numskins + || !R_SkinUsable(-1, savegameinfo[slot].skinnum)) + BADSAVE + + CONS_Printf("Read skinnum successfully\n"); + + savegameinfo[slot].botskin = backwardsCompat >> 5; + if (savegameinfo[slot].botskin-1 >= numskins + || !R_SkinUsable(-1, savegameinfo[slot].botskin-1)) + BADSAVE + + CONS_Printf("Read botskin successfully\n"); + } + else +#endif + { + boolean haveBot = false; + char ourSkinName[SKINNAMESIZE+1]; + + CONS_Printf("New behavior for %d\n", slot); + + CHECKPOS + READSTRINGN(sav_p, ourSkinName, SKINNAMESIZE); + savegameinfo[slot].skinnum = R_SkinAvailable(ourSkinName); + + if (savegameinfo[slot].skinnum >= numskins + || !R_SkinUsable(-1, savegameinfo[slot].skinnum)) + BADSAVE + + CONS_Printf("Read skinnum successfully\n"); + + CHECKPOS + haveBot = (boolean)READUINT8(sav_p); + + if (haveBot == true) + { + char botSkinName[SKINNAMESIZE+1]; + + CHECKPOS + READSTRINGN(sav_p, botSkinName, SKINNAMESIZE); + savegameinfo[slot].botskin = (R_SkinAvailable(botSkinName) + 1); + + if (savegameinfo[slot].botskin-1 >= numskins + || !R_SkinUsable(-1, savegameinfo[slot].botskin-1)) + BADSAVE + } + + CONS_Printf("Read botskin successfully\n"); + } CHECKPOS - savegameinfo[slot].numgameovers = READUINT8(save_p); // numgameovers + savegameinfo[slot].numgameovers = READUINT8(sav_p); // numgameovers CHECKPOS - savegameinfo[slot].lives = READSINT8(save_p); // lives + savegameinfo[slot].lives = READSINT8(sav_p); // lives CHECKPOS - savegameinfo[slot].continuescore = READINT32(save_p); // score + savegameinfo[slot].continuescore = READINT32(sav_p); // score CHECKPOS - fake = READINT32(save_p); // continues + fake = READINT32(sav_p); // continues if (useContinues) savegameinfo[slot].continuescore = fake; // File end marker check CHECKPOS - switch (READUINT8(save_p)) + switch (READUINT8(sav_p)) { case 0xb7: { UINT8 i, banksinuse; CHECKPOS - banksinuse = READUINT8(save_p); + banksinuse = READUINT8(sav_p); CHECKPOS if (banksinuse > NUM_LUABANKS) BADSAVE for (i = 0; i < banksinuse; i++) { - (void)READINT32(save_p); + (void)READINT32(sav_p); CHECKPOS } - if (READUINT8(save_p) != 0x1d) + if (READUINT8(sav_p) != 0x1d) BADSAVE } case 0x1d: diff --git a/src/p_saveg.c b/src/p_saveg.c index 818596cac..cd9235e05 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -64,12 +64,26 @@ typedef enum static inline void P_ArchivePlayer(void) { const player_t *player = &players[consoleplayer]; - INT16 skininfo = player->skin + (botskin<<5); SINT8 pllives = player->lives; if (pllives < startinglivesbalance[numgameovers]) // Bump up to 3 lives if the player pllives = startinglivesbalance[numgameovers]; // has less than that. - WRITEUINT16(save_p, skininfo); +#ifdef NEWSKINSAVES + WRITEUINT16(save_p, NEWSKINSAVES); +#endif + + WRITESTRINGN(save_p, skins[player->skin].name, SKINNAMESIZE); + + if (botskin != 0) + { + WRITEUINT8(save_p, 1); + WRITESTRINGN(save_p, skins[botskin-1].name, SKINNAMESIZE); + } + else + { + WRITEUINT8(save_p, 0); + } + WRITEUINT8(save_p, numgameovers); WRITESINT8(save_p, pllives); WRITEUINT32(save_p, player->score); @@ -78,9 +92,34 @@ static inline void P_ArchivePlayer(void) static inline void P_UnArchivePlayer(void) { - INT16 skininfo = READUINT16(save_p); - savedata.skin = skininfo & ((1<<5) - 1); - savedata.botskin = skininfo >> 5; +#ifdef NEWSKINSAVES + INT16 backwardsCompat = READUINT16(save_p); + + if (backwardsCompat != NEWSKINSAVES) + { + // Backwards compat + savedata.skin = backwardsCompat & ((1<<5) - 1); + savedata.botskin = backwardsCompat >> 5; + } + else +#endif + { + boolean haveBot = false; + char ourSkinName[SKINNAMESIZE+1]; + + READSTRINGN(save_p, ourSkinName, SKINNAMESIZE); + savedata.skin = R_SkinAvailable(ourSkinName); + + haveBot = (boolean)READUINT8(save_p); + + if (haveBot == true) + { + char botSkinName[SKINNAMESIZE+1]; + + READSTRINGN(save_p, botSkinName, SKINNAMESIZE); + savedata.botskin = R_SkinAvailable(botSkinName) + 1; + } + } savedata.numgameovers = READUINT8(save_p); savedata.lives = READSINT8(save_p); diff --git a/src/p_saveg.h b/src/p_saveg.h index be98953eb..1649d32d7 100644 --- a/src/p_saveg.h +++ b/src/p_saveg.h @@ -18,6 +18,8 @@ #pragma interface #endif +#define NEWSKINSAVES (INT16_MAX) // Purely for backwards compatibility, remove this for 2.3 + // Persistent storage/archiving. // These are the load / save game routines. From a5830270062f6a2e34c041eed2ba096546dafc33 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 7 May 2021 19:52:29 -0400 Subject: [PATCH 449/644] Remove prints --- src/m_menu.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 03487e2fa..b72ba0be4 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -8656,8 +8656,6 @@ static void M_ReadSavegameInfo(UINT32 slot) if (backwardsCompat != NEWSKINSAVES) { - CONS_Printf("Old behavior for %d\n", slot); - // Backwards compat savegameinfo[slot].skinnum = backwardsCompat & ((1<<5) - 1); @@ -8665,14 +8663,10 @@ static void M_ReadSavegameInfo(UINT32 slot) || !R_SkinUsable(-1, savegameinfo[slot].skinnum)) BADSAVE - CONS_Printf("Read skinnum successfully\n"); - savegameinfo[slot].botskin = backwardsCompat >> 5; if (savegameinfo[slot].botskin-1 >= numskins || !R_SkinUsable(-1, savegameinfo[slot].botskin-1)) BADSAVE - - CONS_Printf("Read botskin successfully\n"); } else #endif @@ -8680,8 +8674,6 @@ static void M_ReadSavegameInfo(UINT32 slot) boolean haveBot = false; char ourSkinName[SKINNAMESIZE+1]; - CONS_Printf("New behavior for %d\n", slot); - CHECKPOS READSTRINGN(sav_p, ourSkinName, SKINNAMESIZE); savegameinfo[slot].skinnum = R_SkinAvailable(ourSkinName); @@ -8690,8 +8682,6 @@ static void M_ReadSavegameInfo(UINT32 slot) || !R_SkinUsable(-1, savegameinfo[slot].skinnum)) BADSAVE - CONS_Printf("Read skinnum successfully\n"); - CHECKPOS haveBot = (boolean)READUINT8(sav_p); @@ -8707,8 +8697,6 @@ static void M_ReadSavegameInfo(UINT32 slot) || !R_SkinUsable(-1, savegameinfo[slot].botskin-1)) BADSAVE } - - CONS_Printf("Read botskin successfully\n"); } CHECKPOS From d136c60a3fa9f73a7ae0f26d0552f67b4d5f0d8e Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 7 May 2021 20:13:16 -0400 Subject: [PATCH 450/644] Add some comments, write an empty string instead of a boolean determining if the bot skin exists or not. I was a little scared of doing this at first, but after a bit of thought & some testing that it'll be fine. --- src/g_game.c | 12 +++--------- src/m_menu.c | 20 ++++++-------------- src/p_saveg.c | 22 +++++++++------------- 3 files changed, 18 insertions(+), 36 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 08d07dbbb..ad60fe47a 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -4647,20 +4647,14 @@ void G_SaveGameOver(UINT32 slot, boolean modifylives) if (backwardsCompat == NEWSKINSAVES) // New save, read skin names #endif { - boolean haveBot = false; char ourSkinName[SKINNAMESIZE+1]; + char botSkinName[SKINNAMESIZE+1]; READSTRINGN(save_p, ourSkinName, SKINNAMESIZE); CHECKPOS - haveBot = (boolean)READUINT8(save_p); - CHECKPOS - if (haveBot == true) - { - char botSkinName[SKINNAMESIZE+1]; - READSTRINGN(save_p, botSkinName, SKINNAMESIZE); - CHECKPOS - } + READSTRINGN(save_p, botSkinName, SKINNAMESIZE); + CHECKPOS } WRITEUINT8(save_p, numgameovers); diff --git a/src/m_menu.c b/src/m_menu.c index b72ba0be4..2cbbe400f 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -8671,8 +8671,8 @@ static void M_ReadSavegameInfo(UINT32 slot) else #endif { - boolean haveBot = false; char ourSkinName[SKINNAMESIZE+1]; + char botSkinName[SKINNAMESIZE+1]; CHECKPOS READSTRINGN(sav_p, ourSkinName, SKINNAMESIZE); @@ -8683,20 +8683,12 @@ static void M_ReadSavegameInfo(UINT32 slot) BADSAVE CHECKPOS - haveBot = (boolean)READUINT8(sav_p); + READSTRINGN(sav_p, botSkinName, SKINNAMESIZE); + savegameinfo[slot].botskin = (R_SkinAvailable(botSkinName) + 1); - if (haveBot == true) - { - char botSkinName[SKINNAMESIZE+1]; - - CHECKPOS - READSTRINGN(sav_p, botSkinName, SKINNAMESIZE); - savegameinfo[slot].botskin = (R_SkinAvailable(botSkinName) + 1); - - if (savegameinfo[slot].botskin-1 >= numskins - || !R_SkinUsable(-1, savegameinfo[slot].botskin-1)) - BADSAVE - } + if (savegameinfo[slot].botskin-1 >= numskins + || !R_SkinUsable(-1, savegameinfo[slot].botskin-1)) + BADSAVE } CHECKPOS diff --git a/src/p_saveg.c b/src/p_saveg.c index cd9235e05..abfd4b905 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -69,19 +69,22 @@ static inline void P_ArchivePlayer(void) pllives = startinglivesbalance[numgameovers]; // has less than that. #ifdef NEWSKINSAVES + // Write a specific value into the old skininfo location. + // If we read something other than this, it's an older save file that used skin numbers. WRITEUINT16(save_p, NEWSKINSAVES); #endif + // Write skin names, so that loading skins in different orders + // doesn't change who the save file is for! WRITESTRINGN(save_p, skins[player->skin].name, SKINNAMESIZE); if (botskin != 0) { - WRITEUINT8(save_p, 1); WRITESTRINGN(save_p, skins[botskin-1].name, SKINNAMESIZE); } else { - WRITEUINT8(save_p, 0); + WRITESTRINGN(save_p, "\0", SKINNAMESIZE); } WRITEUINT8(save_p, numgameovers); @@ -97,28 +100,21 @@ static inline void P_UnArchivePlayer(void) if (backwardsCompat != NEWSKINSAVES) { - // Backwards compat + // This is an older save file, which used direct skin numbers. savedata.skin = backwardsCompat & ((1<<5) - 1); savedata.botskin = backwardsCompat >> 5; } else #endif { - boolean haveBot = false; char ourSkinName[SKINNAMESIZE+1]; + char botSkinName[SKINNAMESIZE+1]; READSTRINGN(save_p, ourSkinName, SKINNAMESIZE); savedata.skin = R_SkinAvailable(ourSkinName); - haveBot = (boolean)READUINT8(save_p); - - if (haveBot == true) - { - char botSkinName[SKINNAMESIZE+1]; - - READSTRINGN(save_p, botSkinName, SKINNAMESIZE); - savedata.botskin = R_SkinAvailable(botSkinName) + 1; - } + READSTRINGN(save_p, botSkinName, SKINNAMESIZE); + savedata.botskin = R_SkinAvailable(botSkinName) + 1; } savedata.numgameovers = READUINT8(save_p); From 87afa7655a71539c7cbc7db12df18c4253187fbc Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 7 May 2021 18:57:46 -0700 Subject: [PATCH 451/644] CMake: fix ASM compile - target_sources from correct directory - enable_language must be used in add_executable directory --- CMakeLists.txt | 2 -- src/CMakeLists.txt | 6 ++++++ src/sdl/CMakeLists.txt | 2 -- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bc764fc87..6f901d3d7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -117,8 +117,6 @@ set(SRB2_SDL2_EXE_NAME srb2 CACHE STRING "Executable binary output name") include_directories(${CMAKE_CURRENT_BINARY_DIR}/src) -add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32) - add_subdirectory(src) add_subdirectory(assets) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0148d605f..3b690a20a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,5 +1,7 @@ # SRB2 Core +add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32) + # Core sources target_sourcefile(c) target_sources(SRB2SDL2 PRIVATE comptime.c md5.c config.h) @@ -206,9 +208,13 @@ if(${SRB2_CONFIG_USEASM}) set(CMAKE_ASM_NASM_FLAGS "${SRB2_ASM_FLAGS}" CACHE STRING "Flags used by the assembler during all build types.") enable_language(ASM_NASM) endif() + set(SRB2_USEASM ON) target_compile_definitions(SRB2SDL2 PRIVATE -DUSEASM) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -msse3 -mfpmath=sse") + + target_sources(SRB2SDL2 PRIVATE ${SRB2_ASM_SOURCES} + ${SRB2_NASM_SOURCES}) else() set(SRB2_USEASM OFF) target_compile_definitions(SRB2SDL2 PRIVATE -DNONX86 -DNORUSEASM) diff --git a/src/sdl/CMakeLists.txt b/src/sdl/CMakeLists.txt index a1d55ad4d..4f19d93df 100644 --- a/src/sdl/CMakeLists.txt +++ b/src/sdl/CMakeLists.txt @@ -56,8 +56,6 @@ endif() if(${SDL2_FOUND}) if(${SRB2_USEASM}) - target_sources(SRB2SDL2 PRIVATE ${SRB2_ASM_SOURCES} - ${SRB2_NASM_SOURCES}) set_source_files_properties(${SRB2_ASM_SOURCES} PROPERTIES LANGUAGE C) set_source_files_properties(${SRB2_ASM_SOURCES} PROPERTIES COMPILE_FLAGS "-x assembler-with-cpp") endif() From 3880263f1fb9e206f94a5b170a6c3775efbe5313 Mon Sep 17 00:00:00 2001 From: lachablock Date: Sat, 8 May 2021 12:27:29 +1000 Subject: [PATCH 452/644] Add machine dashmode as a condition for gap passage. (Also remove the sprite2 check, we don't need to be that stingy since PlayerHeight hooks allow greater control over that now!) --- src/p_user.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/p_user.c b/src/p_user.c index 4dbbcc04f..dc7209763 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -12972,6 +12972,8 @@ boolean P_PlayerCanEnterSpinGaps(player_t *player) return ((player->pflags & (PF_SPINNING|PF_GLIDING)) // players who are spinning or gliding || (player->charability == CA_GLIDEANDCLIMB && player->mo->state-states == S_PLAY_GLIDE_LANDING) // players who are landing from a glide + || ((player->charflags & (SF_DASHMODE|SF_MACHINE)) == (SF_DASHMODE|SF_MACHINE) + && player->dashmode >= DASHMODE_THRESHOLD && player->mo->state-states == S_PLAY_DASH) // machine players in dashmode || JUMPCURLED(player)); // players who are jumpcurled, but only if they would normally jump that way } From d2db204058a6f7dac39a68704c93a11e63a1d0de Mon Sep 17 00:00:00 2001 From: lachablock Date: Sat, 8 May 2021 18:34:32 +1000 Subject: [PATCH 453/644] Fix rollout rock controls in 2D mode --- src/p_user.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index b3bfb763c..57cb056fd 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -12727,7 +12727,10 @@ void P_PlayerAfterThink(player_t *player) if (player->cmd.forwardmove || player->cmd.sidemove) { rock->flags2 |= MF2_STRONGBOX; // signifies the rock should not slow to a halt - rock->movedir = (player->cmd.angleturn << FRACBITS) + R_PointToAngle2(0, 0, player->cmd.forwardmove << FRACBITS, -player->cmd.sidemove << FRACBITS); + if (twodlevel || (mo->flags2 & MF2_TWOD)) + rock->movedir = mo->angle; + else + rock->movedir = (player->cmd.angleturn << FRACBITS) + R_PointToAngle2(0, 0, player->cmd.forwardmove << FRACBITS, -player->cmd.sidemove << FRACBITS); P_Thrust(rock, rock->movedir, rock->scale >> 1); } else From ec8e884a310fe7978bba4d720ce1259d918a5c8b Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 8 May 2021 12:56:33 -0400 Subject: [PATCH 454/644] Removed this function --- src/r_skins.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/r_skins.h b/src/r_skins.h index 675eac5cc..70e9b49c0 100644 --- a/src/r_skins.h +++ b/src/r_skins.h @@ -90,7 +90,6 @@ extern skin_t skins[MAXSKINS]; void R_InitSkins(void); INT32 GetPlayerDefaultSkin(INT32 playernum); -void SetPlayerDefaultSkin(INT32 playernum); void SetPlayerSkin(INT32 playernum,const char *skinname); void SetPlayerSkinByNum(INT32 playernum,INT32 skinnum); // Tails 03-16-2002 boolean R_SkinUsable(INT32 playernum, INT32 skinnum); From 210c9419e4bddd1fe8e9be7cb66de31119fa0d68 Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 8 May 2021 16:48:40 -0700 Subject: [PATCH 455/644] Ignore -Wtrigraphs --- src/CMakeLists.txt | 2 ++ src/Makefile.cfg | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 87a0499b6..88ab1cdcb 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -604,6 +604,8 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} -Wno-absolute-value) endif() +set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} -Wno-trigraphs) + add_definitions(-DCMAKECONFIG) #add_library(SRB2Core STATIC diff --git a/src/Makefile.cfg b/src/Makefile.cfg index 075cd2d3a..79d332f85 100644 --- a/src/Makefile.cfg +++ b/src/Makefile.cfg @@ -209,7 +209,7 @@ endif OLDWFLAGS:=$(WFLAGS) # -W -Wno-unused -WFLAGS=-Wall +WFLAGS=-Wall -Wno-trigraphs ifndef GCC295 #WFLAGS+=-Wno-packed endif From 35244fa736cd2b5d1a35b471ef75cfaaba6a3a2a Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 8 May 2021 16:49:23 -0700 Subject: [PATCH 456/644] Clang: fix -Wimplicit-const-int-float-conversion Some of these integers exceed the precision of float. In that case the number is rounded. The rounding shouldn't matter too much anyway, so just shut the compiler up. --- src/hardware/hw_main.c | 2 +- src/m_random.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index e94c637e4..dd633d6fc 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5715,7 +5715,7 @@ static void HWR_DrawSkyBackground(player_t *player) dimensionmultiply = ((float)textures[texturetranslation[skytexture]]->width/256.0f); - v[0].s = v[3].s = (-1.0f * angle) / ((ANGLE_90-1)*dimensionmultiply); // left + v[0].s = v[3].s = (-1.0f * angle) / (((float)ANGLE_90-1.0f)*dimensionmultiply); // left v[2].s = v[1].s = v[0].s + (1.0f/dimensionmultiply); // right (or left + 1.0f) // use +angle and -1.0f above instead if you wanted old backwards behavior diff --git a/src/m_random.c b/src/m_random.c index 481fdb72b..b00eff60f 100644 --- a/src/m_random.c +++ b/src/m_random.c @@ -60,7 +60,7 @@ UINT8 M_RandomByte(void) */ INT32 M_RandomKey(INT32 a) { - return (INT32)((rand()/((unsigned)RAND_MAX+1.0f))*a); + return (INT32)((rand()/((float)RAND_MAX+1.0f))*a); } /** Provides a random integer in a given range. @@ -73,7 +73,7 @@ INT32 M_RandomKey(INT32 a) */ INT32 M_RandomRange(INT32 a, INT32 b) { - return (INT32)((rand()/((unsigned)RAND_MAX+1.0f))*(b-a+1))+a; + return (INT32)((rand()/((float)RAND_MAX+1.0f))*(b-a+1))+a; } From 69647eb78d36c0b2f5febecd2c4e55f622325217 Mon Sep 17 00:00:00 2001 From: RJPFonseca Date: Sun, 9 May 2021 19:10:53 +0100 Subject: [PATCH 457/644] Used spaces instead of tabs in Makefile.cfg --- src/Makefile.cfg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Makefile.cfg b/src/Makefile.cfg index 075cd2d3a..e6821a4c9 100644 --- a/src/Makefile.cfg +++ b/src/Makefile.cfg @@ -61,10 +61,10 @@ ifeq (,$(filter GCC% CLEANONLY,$(.VARIABLES))) # If this version is not in the list, default to the latest supported ifeq (,$(filter $(v),$(SUPPORTED_GCC_VERSIONS))) - define line = + define line = Your compiler version, GCC $(version), is not supported by the Makefile. The Makefile will assume GCC $(LATEST_GCC_VERSION).)) - endef + endef $(call print,$(line)) GCC$(subst .,,$(LATEST_GCC_VERSION))=1 else From 0edbca5e02dfc0ffa23696e4c1d86cd12f8e516b Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 10 May 2021 16:51:18 -0700 Subject: [PATCH 458/644] Actually report server version mismatches Incompatible servers get dropped from the server list. It turns out the server list is also used when connecting directly to a server. This meant that if you tried connecting to a server that was incompatible, you'd just get an infinite connection screen, as if the server was completely unreachable. Now it won't drop the server if you are directly connecting to it. I also copied some incompatibility messages from HandleConnect. --- src/d_clisrv.c | 113 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 88 insertions(+), 25 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 7fa6d8d59..8b80e58f5 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1667,20 +1667,24 @@ static void SL_InsertServer(serverinfo_pak* info, SINT8 node) if (serverlistcount >= MAXSERVERLIST) return; // list full - if (info->_255 != 255) - return;/* old packet format */ + /* check it later if connecting to this one */ + if (node != servernode) + { + if (info->_255 != 255) + return;/* old packet format */ - if (info->packetversion != PACKETVERSION) - return;/* old new packet format */ + if (info->packetversion != PACKETVERSION) + return;/* old new packet format */ - if (info->version != VERSION) - return; // Not same version. + if (info->version != VERSION) + return; // Not same version. - if (info->subversion != SUBVERSION) - return; // Close, but no cigar. + if (info->subversion != SUBVERSION) + return; // Close, but no cigar. - if (strcmp(info->application, SRB2APPLICATION)) - return;/* that's a different mod */ + if (strcmp(info->application, SRB2APPLICATION)) + return;/* that's a different mod */ + } i = serverlistcount++; } @@ -1829,6 +1833,65 @@ void CL_UpdateServerList(boolean internetsearch, INT32 room) #endif // ifndef NONET +static const char * InvalidServerReason (INT32 i) +{ +#define EOT "\nPress ESC\n" + + serverinfo_pak *info = &serverlist[i].info; + + /* magic number for new packet format */ + if (info->_255 != 255) + { + return + "Outdated server (version unknown).\n" EOT; + } + + if (strncmp(info->application, SRB2APPLICATION, sizeof + info->application)) + { + return va( + "%s cannot connect\n" + "to %s servers.\n" EOT, + SRB2APPLICATION, + info->application); + } + + if ( + info->packetversion != PACKETVERSION || + info->version != VERSION || + info->subversion != SUBVERSION + ){ + return va( + "Incompatible %s versions.\n" + "(server version %d.%d.%d)\n" EOT, + SRB2APPLICATION, + info->version / 100, + info->version % 100, + info->subversion); + } + + if (info->refusereason) + { + if (serverlist[i].info.refusereason == 1) + return + "The server is not accepting\n" + "joins for the moment.\n" EOT; + else if (serverlist[i].info.refusereason == 2) + return va( + "Maximum players reached: %d\n" EOT, + info->maxplayer); + else + return + "You can't join.\n" + "I don't know why,\n" + "but you can't join.\n" EOT; + } + + return NULL; + +#undef EOT +} + /** Called by CL_ServerConnectionTicker * * \param asksent The last time we asked the server to join. We re-ask every second in case our request got lost in transmit. @@ -1859,23 +1922,23 @@ static boolean CL_ServerConnectionSearchTicker(tic_t *asksent) return true; } - // Quit here rather than downloading files and being refused later. - if (serverlist[i].info.refusereason) - { - D_QuitNetGame(); - CL_Reset(); - D_StartTitle(); - if (serverlist[i].info.refusereason == 1) - M_StartMessage(M_GetText("The server is not accepting\njoins for the moment.\n\nPress ESC\n"), NULL, MM_NOTHING); - else if (serverlist[i].info.refusereason == 2) - M_StartMessage(va(M_GetText("Maximum players reached: %d\n\nPress ESC\n"), serverlist[i].info.maxplayer), NULL, MM_NOTHING); - else - M_StartMessage(M_GetText("You can't join.\nI don't know why,\nbut you can't join.\n\nPress ESC\n"), NULL, MM_NOTHING); - return false; - } - if (client) { + const char *reason = InvalidServerReason(i); + + // Quit here rather than downloading files + // and being refused later. + if (reason) + { + char *message = Z_StrDup(reason); + D_QuitNetGame(); + CL_Reset(); + D_StartTitle(); + M_StartMessage(message, NULL, MM_NOTHING); + Z_Free(message); + return false; + } + D_ParseFileneeded(serverlist[i].info.fileneedednum, serverlist[i].info.fileneeded); CONS_Printf(M_GetText("Checking files...\n")); From 22bfc2db78e2c0afbe839681310a7470b17a9325 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 10 May 2021 17:50:01 -0700 Subject: [PATCH 459/644] Refactor HandleConnect refusals Also removed some version fields from serverconfig_pak and clientconfig_pak. Client version will be checked with SRB2APPLICATION and MODVERSION. Not updating PACKETVERSION because those packets shouldn't have been packetversion'd in the first place. --- src/d_clisrv.c | 115 +++++++++++++++++++++++++++++++++++-------------- src/d_clisrv.h | 8 +--- 2 files changed, 83 insertions(+), 40 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 8b80e58f5..27e104596 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1150,15 +1150,14 @@ static boolean CL_SendJoin(void) CONS_Printf(M_GetText("Sending join request...\n")); netbuffer->packettype = PT_CLIENTJOIN; + netbuffer->u.clientcfg.modversion = MODVERSION; + strncpy(netbuffer->u.clientcfg.application, + SRB2APPLICATION, + sizeof netbuffer->u.clientcfg.application); + if (splitscreen || botingame) localplayers++; netbuffer->u.clientcfg.localplayers = localplayers; - netbuffer->u.clientcfg._255 = 255; - netbuffer->u.clientcfg.packetversion = PACKETVERSION; - netbuffer->u.clientcfg.version = VERSION; - netbuffer->u.clientcfg.subversion = SUBVERSION; - strncpy(netbuffer->u.clientcfg.application, SRB2APPLICATION, - sizeof netbuffer->u.clientcfg.application); CleanupPlayerName(consoleplayer, cv_playername.zstring); if (splitscreen) @@ -1344,9 +1343,6 @@ static boolean SV_SendServerConfig(INT32 node) netbuffer->packettype = PT_SERVERCFG; - netbuffer->u.servercfg.version = VERSION; - netbuffer->u.servercfg.subversion = SUBVERSION; - netbuffer->u.servercfg.serverplayer = (UINT8)serverplayer; netbuffer->u.servercfg.totalslotnum = (UINT8)(doomcom->numslots); netbuffer->u.servercfg.gametic = (tic_t)LONG(gametic); @@ -3683,6 +3679,78 @@ static size_t TotalTextCmdPerTic(tic_t tic) return total; } +static const char * +ConnectionRefused (SINT8 node, INT32 rejoinernum) +{ + clientconfig_pak *cc = &netbuffer->u.clientcfg; + + boolean rejoining = (rejoinernum != -1); + + if (!node)/* server connecting to itself */ + return NULL; + + if ( + cc->modversion != MODVERSION || + strncmp(cc->application, SRB2APPLICATION, + sizeof cc->application) + ){ + return/* this is probably client's fault */ + "Incompatible."; + } + else if (bannednode && bannednode[node]) + { + return + "You have been banned\n" + "from the server."; + } + else if (cc->localplayers != 1) + { + return + "Wrong player count."; + } + + if (!rejoining) + { + if (!cv_allownewplayer.value) + { + return + "The server is not accepting\n" + "joins for the moment."; + } + else if (D_NumPlayers() >= cv_maxplayers.value) + { + return va( + "Maximum players reached: %d", + cv_maxplayers.value); + } + } + + if (luafiletransfers) + { + return + "The serveris broadcasting a file\n" + "requested by a Lua script.\n" + "Please wait a bit and then\n" + "try rejoining."; + } + + if (netgame) + { + const tic_t th = 2 * cv_joindelay.value * TICRATE; + + if (joindelay > th) + { + return va( + "Too many people are connecting.\n" + "Please wait %d seconds and then\n" + "try rejoining.", + (joindelay - th) / TICRATE); + } + } + + return NULL; +} + /** Called when a PT_CLIENTJOIN packet is received * * \param node The packet sender @@ -3693,33 +3761,14 @@ static void HandleConnect(SINT8 node) char names[MAXSPLITSCREENPLAYERS][MAXPLAYERNAME + 1]; INT32 rejoinernum; INT32 i; + const char *refuse; rejoinernum = FindRejoinerNum(node); - if (bannednode && bannednode[node]) - SV_SendRefuse(node, M_GetText("You have been banned\nfrom the server.")); - else if (netbuffer->u.clientcfg._255 != 255 || - netbuffer->u.clientcfg.packetversion != PACKETVERSION) - SV_SendRefuse(node, "Incompatible packet formats."); - else if (strncmp(netbuffer->u.clientcfg.application, SRB2APPLICATION, - sizeof netbuffer->u.clientcfg.application)) - SV_SendRefuse(node, "Different SRB2 modifications\nare not compatible."); - else if (netbuffer->u.clientcfg.version != VERSION - || netbuffer->u.clientcfg.subversion != SUBVERSION) - SV_SendRefuse(node, va(M_GetText("Different SRB2 versions cannot\nplay a netgame!\n(server version %d.%d.%d)"), VERSION/100, VERSION%100, SUBVERSION)); - else if (!cv_allownewplayer.value && node && rejoinernum == -1) - SV_SendRefuse(node, M_GetText("The server is not accepting\njoins for the moment.")); - else if (D_NumPlayers() >= cv_maxplayers.value && rejoinernum == -1) - SV_SendRefuse(node, va(M_GetText("Maximum players reached: %d"), cv_maxplayers.value)); - else if (netgame && netbuffer->u.clientcfg.localplayers > 1) // Hacked client? - SV_SendRefuse(node, M_GetText("Too many players from\nthis node.")); - else if (netgame && !netbuffer->u.clientcfg.localplayers) // Stealth join? - SV_SendRefuse(node, M_GetText("No players from\nthis node.")); - else if (luafiletransfers) - SV_SendRefuse(node, M_GetText("The server is broadcasting a file\nrequested by a Lua script.\nPlease wait a bit and then\ntry rejoining.")); - else if (netgame && joindelay > 2 * (tic_t)cv_joindelay.value * TICRATE) - SV_SendRefuse(node, va(M_GetText("Too many people are connecting.\nPlease wait %d seconds and then\ntry rejoining."), - (joindelay - 2 * cv_joindelay.value * TICRATE) / TICRATE)); + refuse = ConnectionRefused(node, rejoinernum); + + if (refuse) + SV_SendRefuse(node, refuse); else { #ifndef NONET diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 3d67525da..9b690da84 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -141,9 +141,6 @@ typedef struct typedef struct { - UINT8 version; // Different versions don't work - UINT8 subversion; // Contains build version - // Server launch stuffs UINT8 serverplayer; UINT8 totalslotnum; // "Slots": highest player number in use plus one. @@ -190,11 +187,8 @@ typedef struct typedef struct { - UINT8 _255;/* see serverinfo_pak */ - UINT8 packetversion; + UINT8 modversion; char application[MAXAPPLICATION]; - UINT8 version; // Different versions don't work - UINT8 subversion; // Contains build version UINT8 localplayers; UINT8 mode; char names[MAXSPLITSCREENPLAYERS][MAXPLAYERNAME]; From 8486a9386d84293375465420fa80cfeed9859cd1 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 10 May 2021 18:10:16 -0700 Subject: [PATCH 460/644] serverinfo: enumerate refusereason --- src/d_clisrv.c | 41 +++++++++++++++++++++++++---------------- src/d_clisrv.h | 7 ++++++- 2 files changed, 31 insertions(+), 17 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 27e104596..a06a935a7 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1200,6 +1200,19 @@ static INT32 FindRejoinerNum(SINT8 node) return -1; } +static UINT8 +GetRefuseReason (INT32 node) +{ + if (!node || FindRejoinerNum(node) != -1) + return 0; + else if (!cv_allownewplayer.value) + return REFUSE_JOINS_DISABLED; + else if (D_NumPlayers() >= cv_maxplayers.value) + return REFUSE_SLOTS_FULL; + else + return 0; +} + static void SV_SendServerInfo(INT32 node, tic_t servertime) { UINT8 *p; @@ -1218,14 +1231,7 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime) netbuffer->u.serverinfo.numberofplayer = (UINT8)D_NumPlayers(); netbuffer->u.serverinfo.maxplayer = (UINT8)cv_maxplayers.value; - if (!node || FindRejoinerNum(node) != -1) - netbuffer->u.serverinfo.refusereason = 0; - else if (!cv_allownewplayer.value) - netbuffer->u.serverinfo.refusereason = 1; - else if (D_NumPlayers() >= cv_maxplayers.value) - netbuffer->u.serverinfo.refusereason = 2; - else - netbuffer->u.serverinfo.refusereason = 0; + netbuffer->u.serverinfo.refusereason = GetRefuseReason(node); strncpy(netbuffer->u.serverinfo.gametypename, Gametype_Names[gametype], sizeof netbuffer->u.serverinfo.gametypename); @@ -1866,21 +1872,24 @@ static const char * InvalidServerReason (INT32 i) info->subversion); } - if (info->refusereason) + switch (info->refusereason) { - if (serverlist[i].info.refusereason == 1) + case REFUSE_JOINS_DISABLED: return "The server is not accepting\n" "joins for the moment.\n" EOT; - else if (serverlist[i].info.refusereason == 2) + case REFUSE_SLOTS_FULL: return va( "Maximum players reached: %d\n" EOT, info->maxplayer); - else - return - "You can't join.\n" - "I don't know why,\n" - "but you can't join.\n" EOT; + default: + if (info->refusereason) + { + return + "You can't join.\n" + "I don't know why,\n" + "but you can't join.\n" EOT; + } } return NULL; diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 9b690da84..0e8e4c2b8 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -194,6 +194,11 @@ typedef struct char names[MAXSPLITSCREENPLAYERS][MAXPLAYERNAME]; } ATTRPACK clientconfig_pak; +enum { + REFUSE_JOINS_DISABLED = 1, + REFUSE_SLOTS_FULL, +}; + #define MAXSERVERNAME 32 #define MAXFILENEEDED 915 // This packet is too large @@ -211,7 +216,7 @@ typedef struct UINT8 subversion; UINT8 numberofplayer; UINT8 maxplayer; - UINT8 refusereason; // 0: joinable, 1: joins disabled, 2: full + UINT8 refusereason; // 0: joinable, REFUSE enum char gametypename[24]; UINT8 modifiedgame; UINT8 cheatsenabled; From c13e1a74ddb5fba981d801d1137c11537d4505f7 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 10 May 2021 18:10:53 -0700 Subject: [PATCH 461/644] Reject banned players with refusereason --- src/d_clisrv.c | 6 ++++++ src/d_clisrv.h | 13 +++++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index a06a935a7..e87edf43d 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1205,6 +1205,8 @@ GetRefuseReason (INT32 node) { if (!node || FindRejoinerNum(node) != -1) return 0; + else if (bannednode && bannednode[node]) + return REFUSE_BANNED; else if (!cv_allownewplayer.value) return REFUSE_JOINS_DISABLED; else if (D_NumPlayers() >= cv_maxplayers.value) @@ -1874,6 +1876,10 @@ static const char * InvalidServerReason (INT32 i) switch (info->refusereason) { + case REFUSE_BANNED: + return + "You have been banned\n" + "from the server.\n" EOT; case REFUSE_JOINS_DISABLED: return "The server is not accepting\n" diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 0e8e4c2b8..99274b5de 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -22,11 +22,15 @@ #include "mserv.h" /* -The 'packet version' is used to distinguish packet formats. -This version is independent of VERSION and SUBVERSION. Different -applications may follow different packet versions. +The 'packet version' is used to distinguish packet +formats. This version is independent of VERSION and +SUBVERSION. Different applications may follow different +packet versions. + +If you change the struct or the meaning of a field +therein, increment this number. */ -#define PACKETVERSION 3 +#define PACKETVERSION 4 // Network play related stuff. // There is a data struct that stores network @@ -197,6 +201,7 @@ typedef struct enum { REFUSE_JOINS_DISABLED = 1, REFUSE_SLOTS_FULL, + REFUSE_BANNED, }; #define MAXSERVERNAME 32 From f55a5b3b0b964ccf77279bab9136ee7ce883a2e1 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Tue, 11 May 2021 20:02:12 -0400 Subject: [PATCH 462/644] Add badge to readme showing latest stable release --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 8a5ca1a1f..49a3cc36d 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ # Sonic Robo Blast 2 +[![latest release](https://badgen.net/github/release/STJr/SRB2/stable)](https://github.com/STJr/SRB2/releases/latest) [![Build status](https://ci.appveyor.com/api/projects/status/399d4hcw9yy7hg2y?svg=true)](https://ci.appveyor.com/project/STJr/srb2) [![Build status](https://travis-ci.org/STJr/SRB2.svg?branch=master)](https://travis-ci.org/STJr/SRB2) From 5b86b8991c7408ba7ebb78d0d6ff4438d447936e Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Sun, 16 May 2021 21:43:52 -0300 Subject: [PATCH 463/644] Use floating point trigonometry --- src/r_plane.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/r_plane.c b/src/r_plane.c index d26c124ef..4c757d8ca 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -368,11 +368,11 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, if (plangle != 0) { // Add the view offset, rotated by the plane angle. - fixed_t cosinecomponent = FINECOSINE(plangle>>ANGLETOFINESHIFT); - fixed_t sinecomponent = FINESINE(plangle>>ANGLETOFINESHIFT); - fixed_t oldxoff = xoff; - xoff = FixedMul(xoff,cosinecomponent)+FixedMul(yoff,sinecomponent); - yoff = -FixedMul(oldxoff,sinecomponent)+FixedMul(yoff,cosinecomponent); + float ang = ANG2RAD(plangle); + float x = FixedToFloat(xoff); + float y = FixedToFloat(yoff); + xoff = FloatToFixed(x * cos(ang) + y * sin(ang)); + yoff = FloatToFixed(-x * sin(ang) + y * cos(ang)); } } From 7c11bc8ac5807414fee671df0b6d82c040a067bc Mon Sep 17 00:00:00 2001 From: lachablock Date: Fri, 21 May 2021 20:28:50 +1000 Subject: [PATCH 464/644] Remove camera dependency from P_GetPlayerControlDirection --- src/p_user.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 6ebee5afc..3b8248e97 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -5624,16 +5624,10 @@ INT32 P_GetPlayerControlDirection(player_t *player) { ticcmd_t *cmd = &player->cmd; angle_t controllerdirection, controlplayerdirection; - camera_t *thiscam; angle_t dangle; fixed_t tempx = 0, tempy = 0; angle_t tempangle, origtempangle; - if (splitscreen && player == &players[secondarydisplayplayer]) - thiscam = &camera2; - else - thiscam = &camera; - if (!cmd->forwardmove && !cmd->sidemove) return 0; @@ -5649,17 +5643,15 @@ INT32 P_GetPlayerControlDirection(player_t *player) origtempangle = tempangle = 0; // relative to the axis rather than the player! controlplayerdirection = R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy); } - else if ((P_ControlStyle(player) & CS_LMAOGALOG) && thiscam->chase) + else { if (player->awayviewtics) origtempangle = tempangle = player->awayviewmobj->angle; + else if (P_ControlStyle(player) & CS_LMAOGALOG) + origtempangle = tempangle = (cmd->angleturn << 16); else - origtempangle = tempangle = thiscam->angle; - controlplayerdirection = player->mo->angle; - } - else - { - origtempangle = tempangle = player->mo->angle; + origtempangle = tempangle = player->mo->angle; + controlplayerdirection = R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy); } From 4e5c3566c95cd9526d42629837f779c041fe0a92 Mon Sep 17 00:00:00 2001 From: lachablock Date: Sat, 22 May 2021 16:52:01 +1000 Subject: [PATCH 465/644] Respect mobj->color while enemies & bosses flash --- src/r_draw.c | 4 ++++ src/r_things.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/r_draw.c b/src/r_draw.c index 9a835ee58..c7bf36e64 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -481,8 +481,12 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U // White! if (skinnum == TC_BOSS) { + UINT8 *originalColormap = R_GetTranslationColormap(TC_DEFAULT, (skincolornum_t)color, GTC_CACHE); for (i = 0; i < 16; i++) + { + dest_colormap[DEFAULT_STARTTRANSCOLOR + i] = originalColormap[DEFAULT_STARTTRANSCOLOR + i]; dest_colormap[31-i] = i; + } } else if (skinnum == TC_METALSONIC) { diff --git a/src/r_things.c b/src/r_things.c index 5c0e5fda9..bbae345db 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -753,7 +753,7 @@ UINT8 *R_GetSpriteTranslation(vissprite_t *vis) else if (vis->mobj->type == MT_METALSONIC_BATTLE) return R_GetTranslationColormap(TC_METALSONIC, 0, GTC_CACHE); else - return R_GetTranslationColormap(TC_BOSS, 0, GTC_CACHE); + return R_GetTranslationColormap(TC_BOSS, vis->mobj->color, GTC_CACHE); } else if (vis->mobj->color) { From 99ad18826332cb95798d17b658ccb4fa9c83b3f6 Mon Sep 17 00:00:00 2001 From: lachablock Date: Sat, 22 May 2021 18:17:48 +1000 Subject: [PATCH 466/644] Fix models interpolating to frame 0 from a same-sprite2 FF_SPR2ENDSTATE state --- src/hardware/hw_md2.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 9c3aa9e58..e3b612678 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1533,7 +1533,12 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) { nextFrame = (spr->mobj->frame & FF_FRAMEMASK) + 1; if (nextFrame >= mod) - nextFrame = 0; + { + if (spr->mobj->state->frame & FF_SPR2ENDSTATE) + nextFrame--; + else + nextFrame = 0; + } if (frame || !(spr->mobj->state->frame & FF_SPR2ENDSTATE)) nextFrame = md2->model->spr2frames[spr2].frames[nextFrame]; else From 750bdd9d607f1a078d16b88a87d59b12bf0992a7 Mon Sep 17 00:00:00 2001 From: lachablock Date: Sat, 22 May 2021 23:25:36 +1000 Subject: [PATCH 467/644] Respect mobj->color while enemies & bosses flash, but in OpenGL --- src/hardware/hw_main.c | 2 +- src/hardware/hw_md2.c | 28 ++++++++++------------------ 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index dd633d6fc..cec55e601 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5327,7 +5327,7 @@ static void HWR_ProjectSprite(mobj_t *thing) else if (vis->mobj->type == MT_METALSONIC_BATTLE) vis->colormap = R_GetTranslationColormap(TC_METALSONIC, 0, GTC_CACHE); else - vis->colormap = R_GetTranslationColormap(TC_BOSS, 0, GTC_CACHE); + vis->colormap = R_GetTranslationColormap(TC_BOSS, vis->mobj->color, GTC_CACHE); } else if (thing->color) { diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 9c3aa9e58..fd7b67aad 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -777,24 +777,7 @@ static void HWR_CreateBlendedTexture(patch_t *gpatch, patch_t *blendgpatch, GLMi while (size--) { - if (skinnum == TC_BOSS) - { - // Turn everything below a certain threshold white - if ((image->s.red == image->s.green) && (image->s.green == image->s.blue) && image->s.blue < 127) - { - // Lactozilla: Invert the colors - cur->s.red = cur->s.green = cur->s.blue = (255 - image->s.blue); - } - else - { - cur->s.red = image->s.red; - cur->s.green = image->s.green; - cur->s.blue = image->s.blue; - } - - cur->s.alpha = image->s.alpha; - } - else if (skinnum == TC_ALLWHITE) + if (skinnum == TC_ALLWHITE) { // Turn everything white cur->s.red = cur->s.green = cur->s.blue = 255; @@ -1065,6 +1048,15 @@ skippixel: cur->s.alpha = image->s.alpha; } + else if (skinnum == TC_BOSS) + { + // Turn everything below a certain threshold white + if ((image->s.red == image->s.green) && (image->s.green == image->s.blue) && image->s.blue < 127) + { + // Lactozilla: Invert the colors + cur->s.red = cur->s.green = cur->s.blue = (255 - image->s.blue); + } + } } } From a1553c46232f6a4df12b71af9ff7f29bf36b9607 Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Sat, 22 May 2021 20:08:11 -0300 Subject: [PATCH 468/644] Update r_opengl.c --- src/hardware/r_opengl/r_opengl.c | 75 ++++++++++---------------------- 1 file changed, 22 insertions(+), 53 deletions(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 003a1b3ca..de0e8c6a6 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -62,6 +62,9 @@ static FBITFIELD CurrentPolyFlags; static FTextureInfo *TexCacheTail = NULL; static FTextureInfo *TexCacheHead = NULL; +static RGBA_t *textureBuffer = NULL; +static size_t textureBufferSize = 0; + RGBA_t myPaletteData[256]; GLint screen_width = 0; // used by Draw2DLine() GLint screen_height = 0; @@ -202,32 +205,6 @@ static void GL_MSG_Error(const char *format, ...) #endif } -// ----------------------+ -// GetTextureFormatName : Returns the corresponding texture format string from the texture format enumeration. -// ----------------------+ -static const char *GetTextureFormatName(INT32 format) -{ - static char num[12]; - - switch (format) - { - case GL_TEXFMT_P_8: return "GL_TEXFMT_P_8"; - case GL_TEXFMT_AP_88: return "GL_TEXFMT_AP_88"; - case GL_TEXFMT_RGBA: return "GL_TEXFMT_RGBA"; - case GL_TEXFMT_ALPHA_8: return "GL_TEXFMT_ALPHA_8"; - case GL_TEXFMT_INTENSITY_8: return "GL_TEXFMT_INTENSITY_8"; - case GL_TEXFMT_ALPHA_INTENSITY_88: return "GL_TEXFMT_ALPHA_INTENSITY_88"; - default: break; - } - - // If the texture format is not known (due to it being invalid), - // return a string containing the format index instead. - format = INT32_MIN; - snprintf(num, sizeof(num), "%d", format); - - return num; -} - #ifdef STATIC_OPENGL /* 1.0 functions */ /* Miscellaneous */ @@ -1366,6 +1343,10 @@ void Flush(void) TexCacheTail = TexCacheHead = NULL; //Hurdler: well, TexCacheHead is already NULL tex_downloaded = 0; + + free(textureBuffer); + textureBuffer = NULL; + textureBufferSize = 0; } @@ -1758,28 +1739,16 @@ EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags) CurrentPolyFlags = PolyFlags; } -// -------------------+ -// AllocTextureBuffer : Allocates memory for converting a non-RGBA texture into an RGBA texture. -// -------------------+ -static RGBA_t *AllocTextureBuffer(GLMipmap_t *pTexInfo) +static void AllocTextureBuffer(GLMipmap_t *pTexInfo) { - size_t len = (pTexInfo->width * pTexInfo->height); - RGBA_t *tex = calloc(len, sizeof(RGBA_t)); - - if (tex == NULL) - I_Error("AllocTextureBuffer: out of memory allocating %s bytes for texture %d, format %s", - sizeu1(len * sizeof(RGBA_t)), pTexInfo->downloaded, GetTextureFormatName(pTexInfo->format)); - - return tex; -} - -// ------------------+ -// FreeTextureBuffer : Frees memory allocated by AllocTextureBuffer. -// ------------------+ -static void FreeTextureBuffer(RGBA_t *tex) -{ - if (tex) - free(tex); + size_t size = pTexInfo->width * pTexInfo->height; + if (size > textureBufferSize) + { + textureBuffer = realloc(textureBuffer, size * sizeof(RGBA_t)); + if (textureBuffer == NULL) + I_Error("AllocTextureBuffer: out of memory allocating %s bytes", sizeu1(size * sizeof(RGBA_t))); + textureBufferSize = size; + } } // -----------------+ @@ -1810,7 +1779,8 @@ EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *pTexInfo) if ((pTexInfo->format == GL_TEXFMT_P_8) || (pTexInfo->format == GL_TEXFMT_AP_88)) { - ptex = tex = AllocTextureBuffer(pTexInfo); + AllocTextureBuffer(pTexInfo); + ptex = tex = textureBuffer; for (j = 0; j < h; j++) { @@ -1851,7 +1821,8 @@ EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *pTexInfo) } else if (pTexInfo->format == GL_TEXFMT_ALPHA_INTENSITY_88) { - ptex = tex = AllocTextureBuffer(pTexInfo); + AllocTextureBuffer(pTexInfo); + ptex = tex = textureBuffer; for (j = 0; j < h; j++) { @@ -1868,7 +1839,8 @@ EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *pTexInfo) } else if (pTexInfo->format == GL_TEXFMT_ALPHA_8) // Used for fade masks { - ptex = tex = AllocTextureBuffer(pTexInfo); + AllocTextureBuffer(pTexInfo); + ptex = tex = textureBuffer; for (j = 0; j < h; j++) { @@ -1963,9 +1935,6 @@ EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *pTexInfo) } } - // Free the texture buffer - FreeTextureBuffer(tex); - if (pTexInfo->flags & TF_WRAPX) pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); else From 75397c347db01720f32547ca02c8c7b9486a727c Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Sat, 22 May 2021 21:09:06 -0300 Subject: [PATCH 469/644] Remove FRACUNIT/2 --- src/r_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_main.c b/src/r_main.c index be9bbd7d0..17e124cb9 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -955,7 +955,7 @@ void R_ExecuteSetViewSize(void) j = viewheight*16; for (i = 0; i < j; i++) { - dy = ((i - viewheight*8)< Date: Mon, 24 May 2021 00:00:01 -0500 Subject: [PATCH 470/644] make a few messages more helpful --- src/d_clisrv.c | 6 +++--- src/locale/en.po | 6 +++--- src/locale/srb2.pot | 6 +++--- src/p_setup.c | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 3a0e64c56..64efd3b60 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2952,7 +2952,7 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum) { case KICK_MSG_GO_AWAY: if (!players[pnum].quittime) - HU_AddChatText(va("\x82*%s has been kicked (Go away)", player_names[pnum]), false); + HU_AddChatText(va("\x82*%s has been kicked (No reason given)", player_names[pnum]), false); kickreason = KR_KICK; break; case KICK_MSG_PING_HIGH: @@ -2960,7 +2960,7 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum) kickreason = KR_PINGLIMIT; break; case KICK_MSG_CON_FAIL: - HU_AddChatText(va("\x82*%s left the game (Synch Failure)", player_names[pnum]), false); + HU_AddChatText(va("\x82*%s left the game (Synch failure)", player_names[pnum]), false); kickreason = KR_SYNCH; if (M_CheckParm("-consisdump")) // Helps debugging some problems @@ -3006,7 +3006,7 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum) kickreason = KR_LEAVE; break; case KICK_MSG_BANNED: - HU_AddChatText(va("\x82*%s has been banned (Don't come back)", player_names[pnum]), false); + HU_AddChatText(va("\x82*%s has been banned (No reason given)", player_names[pnum]), false); kickreason = KR_BAN; break; case KICK_MSG_CUSTOM_KICK: diff --git a/src/locale/en.po b/src/locale/en.po index 30ebe4368..8dd08173d 100644 --- a/src/locale/en.po +++ b/src/locale/en.po @@ -466,7 +466,7 @@ msgid "" msgstr "" #: d_clisrv.c:1764 -msgid "has been kicked (Go away)\n" +msgid "has been kicked (No reason given)\n" msgstr "" #: d_clisrv.c:1768 @@ -474,7 +474,7 @@ msgid "left the game (Broke ping limit)\n" msgstr "" #: d_clisrv.c:1772 -msgid "left the game (Consistency failure)\n" +msgid "left the game (Synch failure)\n" msgstr "" #: d_clisrv.c:1778 @@ -501,7 +501,7 @@ msgid "left the game\n" msgstr "" #: d_clisrv.c:1798 -msgid "has been banned (Don't come back)\n" +msgid "has been banned (No reason given)\n" msgstr "" #: d_clisrv.c:1802 diff --git a/src/locale/srb2.pot b/src/locale/srb2.pot index 960c36dbe..cd2db750d 100644 --- a/src/locale/srb2.pot +++ b/src/locale/srb2.pot @@ -459,7 +459,7 @@ msgid "" msgstr "" #: d_clisrv.c:1889 -msgid "has been kicked (Go away)\n" +msgid "has been kicked (No reason given)\n" msgstr "" #: d_clisrv.c:1893 @@ -467,7 +467,7 @@ msgid "left the game (Broke ping limit)\n" msgstr "" #: d_clisrv.c:1897 -msgid "left the game (Consistency failure)\n" +msgid "left the game (Synch failure)\n" msgstr "" #: d_clisrv.c:1903 @@ -494,7 +494,7 @@ msgid "left the game\n" msgstr "" #: d_clisrv.c:1923 -msgid "has been banned (Don't come back)\n" +msgid "has been banned (No reason given)\n" msgstr "" #: d_clisrv.c:1927 diff --git a/src/p_setup.c b/src/p_setup.c index 16c080248..231e5ed57 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2486,7 +2486,7 @@ static void P_LoadMapBSP(const virtres_t *virt) if (numsubsectors <= 0) I_Error("Level has no subsectors (did you forget to run it through a nodesbuilder?)"); if (numnodes <= 0) - I_Error("Level has no nodes"); + I_Error("Level has no nodes (does your map have at least 2 sectors?)"); if (numsegs <= 0) I_Error("Level has no segs"); From a1235e144dfddd2151471071c8cdd713ae46d89b Mon Sep 17 00:00:00 2001 From: katsy Date: Wed, 26 May 2021 01:09:56 -0500 Subject: [PATCH 471/644] allow sliders passage through spin gaps --- src/p_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index 6ebee5afc..45867ee5b 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -12971,7 +12971,7 @@ boolean P_PlayerCanEnterSpinGaps(player_t *player) else if (canEnter == 2) return false; - return ((player->pflags & (PF_SPINNING|PF_GLIDING)) // players who are spinning or gliding + return ((player->pflags & (PF_SPINNING|PF_SLIDING|PF_GLIDING)) // players who are spinning, sliding, or gliding || (player->charability == CA_GLIDEANDCLIMB && player->mo->state-states == S_PLAY_GLIDE_LANDING) // players who are landing from a glide || JUMPCURLED(player)); // players who are jumpcurled, but only if they would normally jump that way } From 6286fc8b05909e332dac676de5c7fe01d33266c0 Mon Sep 17 00:00:00 2001 From: katsy Date: Wed, 26 May 2021 02:37:46 -0400 Subject: [PATCH 472/644] add sliding flag to spinheight conditions --- src/p_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index 45867ee5b..9cb00967a 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -12979,7 +12979,7 @@ boolean P_PlayerCanEnterSpinGaps(player_t *player) // returns true if the player should use their skin's spinheight instead of their skin's height boolean P_PlayerShouldUseSpinHeight(player_t *player) { - return ((player->pflags & (PF_SPINNING|PF_GLIDING)) + return ((player->pflags & (PF_SPINNING|PF_SLIDING|PF_GLIDING)) || (player->mo->state == &states[player->mo->info->painstate]) || (player->panim == PA_ROLL) || ((player->powers[pw_tailsfly] || (player->charability == CA_FLY && player->mo->state-states == S_PLAY_FLY_TIRED)) From fd82357d4f72d2f8b7922551a98c3688bca77d5b Mon Sep 17 00:00:00 2001 From: flarn2006 Date: Thu, 27 May 2021 18:35:15 -0400 Subject: [PATCH 473/644] Expose M_MapNumber to Lua --- src/lua_baselib.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index a0c99411b..2a8c62a37 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -28,6 +28,7 @@ #include "console.h" #include "d_netcmd.h" // IsPlayerAdmin #include "m_menu.h" // Player Setup menu color stuff +#include "m_misc.h" // M_MapNumber #include "lua_script.h" #include "lua_libs.h" @@ -357,6 +358,23 @@ static int lib_pGetColorAfter(lua_State *L) return 1; } +// M_MISC +////////////// + +static int lib_mMapNumber(lua_State *L) +{ + const char *arg = luaL_checkstring(L, 1); + size_t len = strlen(arg); + if (len == 2 || len == 5) { + char first = arg[len-2]; + char second = arg[len-1]; + lua_pushinteger(L, M_MapNumber(first, second)); + } else { + lua_pushinteger(L, 0); + } + return 1; +} + // M_RANDOM ////////////// @@ -3778,6 +3796,9 @@ static luaL_Reg lib[] = { {"M_GetColorAfter",lib_pGetColorAfter}, {"M_GetColorBefore",lib_pGetColorBefore}, + // m_misc + {"M_MapNumber",lib_mMapNumber}, + // m_random {"P_RandomFixed",lib_pRandomFixed}, {"P_RandomByte",lib_pRandomByte}, From 07801a2a184b2120608759f80889a3a6113a02d3 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 28 May 2021 18:42:19 +0100 Subject: [PATCH 474/644] move P_MapEnd call in P_LoadLevel further down, so that the P_MapStart/End pair also encloses cached actions and the MapLoad Lua hook --- src/p_setup.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 16c080248..1abdccc21 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -4223,7 +4223,7 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate) P_ResetWaypoints(); - P_MapStart(); + P_MapStart(); // tmthing can be used starting from this point if (!P_LoadMapFromFile()) return false; @@ -4276,8 +4276,6 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate) // clear special respawning que iquehead = iquetail = 0; - P_MapEnd(); - // Remove the loading shit from the screen if (rendermode != render_none && !(titlemapinaction || reloadinggamestate)) F_WipeColorFill(levelfadecol); @@ -4323,6 +4321,8 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate) LUAh_MapLoad(); } + P_MapEnd(); // tmthing is no longer needed from this point onwards + // No render mode or reloading gamestate, stop here. if (rendermode == render_none || reloadinggamestate) return true; From ada6ec07dbc76d0d6e732e3b761ef79819c38412 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 28 May 2021 18:47:09 +0100 Subject: [PATCH 475/644] Fix Lua versions of P_ZMovement and its clones as well as P_MovePlayer so tmthing changes don't linger afterwards --- src/lua_baselib.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index df370a431..daf1ee6b0 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -1044,48 +1044,56 @@ static int lib_pSceneryXYMovement(lua_State *L) static int lib_pZMovement(lua_State *L) { mobj_t *actor = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); + mobj_t *ptmthing = tmthing; NOHUD INLEVEL if (!actor) return LUA_ErrInvalid(L, "mobj_t"); lua_pushboolean(L, P_ZMovement(actor)); P_CheckPosition(actor, actor->x, actor->y); + P_SetTarget(&tmthing, ptmthing); return 1; } static int lib_pRingZMovement(lua_State *L) { mobj_t *actor = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); + mobj_t *ptmthing = tmthing; NOHUD INLEVEL if (!actor) return LUA_ErrInvalid(L, "mobj_t"); P_RingZMovement(actor); P_CheckPosition(actor, actor->x, actor->y); + P_SetTarget(&tmthing, ptmthing); return 0; } static int lib_pSceneryZMovement(lua_State *L) { mobj_t *actor = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); + mobj_t *ptmthing = tmthing; NOHUD INLEVEL if (!actor) return LUA_ErrInvalid(L, "mobj_t"); lua_pushboolean(L, P_SceneryZMovement(actor)); P_CheckPosition(actor, actor->x, actor->y); + P_SetTarget(&tmthing, ptmthing); return 1; } static int lib_pPlayerZMovement(lua_State *L) { mobj_t *actor = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); + mobj_t *ptmthing = tmthing; NOHUD INLEVEL if (!actor) return LUA_ErrInvalid(L, "mobj_t"); P_PlayerZMovement(actor); P_CheckPosition(actor, actor->x, actor->y); + P_SetTarget(&tmthing, ptmthing); return 0; } @@ -1472,11 +1480,13 @@ static int lib_pSpawnSkidDust(lua_State *L) static int lib_pMovePlayer(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + mobj_t *ptmthing = tmthing; NOHUD INLEVEL if (!player) return LUA_ErrInvalid(L, "player_t"); P_MovePlayer(player); + P_SetTarget(&tmthing, ptmthing); return 0; } From 45b1223f3e356544ef8968c1d7054727e261cd1e Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 28 May 2021 18:56:32 +0100 Subject: [PATCH 476/644] My mistake, `P_PreTicker` calls `P_MapStart` and `P_MapEnd` too, so rework my earlier fix a bit --- src/p_setup.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 1abdccc21..913dfe403 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -4295,6 +4295,8 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate) P_RunCachedActions(); + P_MapEnd(); // tmthing is no longer needed from this point onwards + // Took me 3 hours to figure out why my progression kept on getting overwritten with the titlemap... if (!titlemapinaction) { @@ -4318,11 +4320,11 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate) G_CopyTiccmd(&players[i].cmd, &netcmds[buf][i], 1); } P_PreTicker(2); + P_MapStart(); // just in case MapLoad modifies tmthing LUAh_MapLoad(); + P_MapEnd(); // just in case MapLoad modifies tmthing } - P_MapEnd(); // tmthing is no longer needed from this point onwards - // No render mode or reloading gamestate, stop here. if (rendermode == render_none || reloadinggamestate) return true; From 21dab7bd6652688930879af9e42c2ec54dd46859 Mon Sep 17 00:00:00 2001 From: Riku Salminen <38985578+Riku-S@users.noreply.github.com> Date: Fri, 28 May 2021 22:30:43 +0300 Subject: [PATCH 477/644] Add previous demo version to acceptable demo versions for demo comparison --- src/g_demo.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/g_demo.c b/src/g_demo.c index ea71c9bd4..635b42b13 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -1668,6 +1668,7 @@ UINT8 G_CmpDemoTime(char *oldname, char *newname) switch(oldversion) // demoversion { case DEMOVERSION: // latest always supported + case 0x000d: // latest always supported case 0x000c: // all that changed between then and now was longer color name break; // too old, cannot support. From 22aaffa35d3bf2abb73a16b27f887162722ca0f4 Mon Sep 17 00:00:00 2001 From: Riku Salminen <38985578+Riku-S@users.noreply.github.com> Date: Fri, 28 May 2021 22:32:11 +0300 Subject: [PATCH 478/644] non-misleading comment --- src/g_demo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g_demo.c b/src/g_demo.c index 635b42b13..16d29fb88 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -1668,7 +1668,7 @@ UINT8 G_CmpDemoTime(char *oldname, char *newname) switch(oldversion) // demoversion { case DEMOVERSION: // latest always supported - case 0x000d: // latest always supported + case 0x000d: // The previous demoversion also supported case 0x000c: // all that changed between then and now was longer color name break; // too old, cannot support. From 8d8f62baefdcbb1b71d75d505b95e3cc4a675056 Mon Sep 17 00:00:00 2001 From: flarn2006 Date: Fri, 28 May 2021 23:59:39 -0400 Subject: [PATCH 479/644] Add additional multitagging functionality --- extras/conf/SRB2-22.cfg | 14 ++++++++++++++ src/p_setup.c | 33 +++++++++++++++++++++++++++++---- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg index d36c16b75..ad930a485 100644 --- a/extras/conf/SRB2-22.cfg +++ b/extras/conf/SRB2-22.cfg @@ -640,22 +640,36 @@ linedeftypes prefix = "(63)"; } + 96 + { + title = "Apply Tag to Tagged Sectors"; + prefix = "(96)"; + flags8192text = "[13] Use Front Side Offsets"; + flags32768text = "[15] Use Back Side Offsets"; + } + 97 { title = "Apply Tag to Front Sector"; prefix = "(97)"; + flags8192text = "[13] Use Front Side Offsets"; + flags32768text = "[15] Use Back Side Offsets"; } 98 { title = "Apply Tag to Back Sector"; prefix = "(98)"; + flags8192text = "[13] Use Front Side Offsets"; + flags32768text = "[15] Use Back Side Offsets"; } 99 { title = "Apply Tag to Front and Back Sectors"; prefix = "(99)"; + flags8192text = "[13] Use Front Side Offsets"; + flags32768text = "[15] Use Back Side Offsets"; } 540 diff --git a/src/p_setup.c b/src/p_setup.c index 16c080248..6375decac 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2952,19 +2952,44 @@ static void P_LinkMapData(void) // For maps in binary format, add multi-tags from linedef specials. This must be done // before any linedef specials have been processed. +static void P_AddBinaryMapTagsFromLine(sector_t *sector, line_t *line) +{ + Tag_Add(§or->tags, Tag_FGet(&line->tags)); + if (line->flags & ML_EFFECT6) { + if (sides[line->sidenum[0]].textureoffset) + Tag_Add(§or->tags, (INT32)sides[line->sidenum[0]].textureoffset); + if (sides[line->sidenum[0]].rowoffset) + Tag_Add(§or->tags, (INT32)sides[line->sidenum[0]].rowoffset); + } + if (line->flags & ML_TFERLINE) { + if (sides[line->sidenum[1]].textureoffset) + Tag_Add(§or->tags, (INT32)sides[line->sidenum[1]].textureoffset); + if (sides[line->sidenum[1]].rowoffset) + Tag_Add(§or->tags, (INT32)sides[line->sidenum[1]].rowoffset); + } +} + static void P_AddBinaryMapTags(void) { size_t i; for (i = 0; i < numlines; i++) { + // 96: Apply Tag to Tagged Sectors // 97: Apply Tag to Front Sector // 98: Apply Tag to Back Sector // 99: Apply Tag to Front and Back Sectors - if (lines[i].special == 97 || lines[i].special == 99) - Tag_Add(&lines[i].frontsector->tags, Tag_FGet(&lines[i].tags)); - if (lines[i].special == 98 || lines[i].special == 99) - Tag_Add(&lines[i].backsector->tags, Tag_FGet(&lines[i].tags)); + if (lines[i].special == 96) { + mtag_t tag = Tag_FGet(&lines[i].frontsector->tags); + INT32 s; + TAG_ITER_DECLARECOUNTER(0); + TAG_ITER_SECTORS(0, tag, s) + P_AddBinaryMapTagsFromLine(§ors[s], &lines[i]); + } else if (lines[i].special == 97 || lines[i].special == 99) { + P_AddBinaryMapTagsFromLine(lines[i].frontsector, &lines[i]); + } else if (lines[i].special == 98 || lines[i].special == 99) { + P_AddBinaryMapTagsFromLine(lines[i].backsector, &lines[i]); + } } } From 7d71d534d47941faaa5dbe962a20b52ab850a8b8 Mon Sep 17 00:00:00 2001 From: flarn2006 Date: Sat, 29 May 2021 00:40:06 -0400 Subject: [PATCH 480/644] Add missing "/ FRACUNIT" to texture offset code --- src/p_setup.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 6375decac..4bb47c943 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2957,15 +2957,15 @@ static void P_AddBinaryMapTagsFromLine(sector_t *sector, line_t *line) Tag_Add(§or->tags, Tag_FGet(&line->tags)); if (line->flags & ML_EFFECT6) { if (sides[line->sidenum[0]].textureoffset) - Tag_Add(§or->tags, (INT32)sides[line->sidenum[0]].textureoffset); + Tag_Add(§or->tags, (INT32)sides[line->sidenum[0]].textureoffset / FRACUNIT); if (sides[line->sidenum[0]].rowoffset) - Tag_Add(§or->tags, (INT32)sides[line->sidenum[0]].rowoffset); + Tag_Add(§or->tags, (INT32)sides[line->sidenum[0]].rowoffset / FRACUNIT); } if (line->flags & ML_TFERLINE) { if (sides[line->sidenum[1]].textureoffset) - Tag_Add(§or->tags, (INT32)sides[line->sidenum[1]].textureoffset); + Tag_Add(§or->tags, (INT32)sides[line->sidenum[1]].textureoffset / FRACUNIT); if (sides[line->sidenum[1]].rowoffset) - Tag_Add(§or->tags, (INT32)sides[line->sidenum[1]].rowoffset); + Tag_Add(§or->tags, (INT32)sides[line->sidenum[1]].rowoffset / FRACUNIT); } } From eee894581aecc4575baf0edb4cb46941806efbf8 Mon Sep 17 00:00:00 2001 From: flarn2006 Date: Sat, 29 May 2021 00:54:31 -0400 Subject: [PATCH 481/644] Make linedef 96 skip the control sector --- src/p_setup.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 4bb47c943..336cf9886 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2983,8 +2983,10 @@ static void P_AddBinaryMapTags(void) mtag_t tag = Tag_FGet(&lines[i].frontsector->tags); INT32 s; TAG_ITER_DECLARECOUNTER(0); - TAG_ITER_SECTORS(0, tag, s) - P_AddBinaryMapTagsFromLine(§ors[s], &lines[i]); + TAG_ITER_SECTORS(0, tag, s) { + if (s != lines[i].frontsector - sectors) // Skip the control sector + P_AddBinaryMapTagsFromLine(§ors[s], &lines[i]); + } } else if (lines[i].special == 97 || lines[i].special == 99) { P_AddBinaryMapTagsFromLine(lines[i].frontsector, &lines[i]); } else if (lines[i].special == 98 || lines[i].special == 99) { From 93de054786147c7f64360177cd271ed70eedb2fb Mon Sep 17 00:00:00 2001 From: flarn2006 Date: Sat, 29 May 2021 11:08:46 -0400 Subject: [PATCH 482/644] Fix linedef type 96 (I had it all wrong) --- src/p_setup.c | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 336cf9886..0d061aaab 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2980,12 +2980,36 @@ static void P_AddBinaryMapTags(void) // 98: Apply Tag to Back Sector // 99: Apply Tag to Front and Back Sectors if (lines[i].special == 96) { + size_t j; mtag_t tag = Tag_FGet(&lines[i].frontsector->tags); - INT32 s; - TAG_ITER_DECLARECOUNTER(0); - TAG_ITER_SECTORS(0, tag, s) { - if (s != lines[i].frontsector - sectors) // Skip the control sector - P_AddBinaryMapTagsFromLine(§ors[s], &lines[i]); + mtag_t target_tags[5]; + target_tags[0] = Tag_FGet(&lines[i].tags); + if (lines[i].flags & ML_EFFECT6) { + target_tags[1] = (INT32)sides[lines[i].sidenum[0]].textureoffset / FRACUNIT; + target_tags[2] = (INT32)sides[lines[i].sidenum[0]].rowoffset / FRACUNIT; + } else { + target_tags[1] = target_tags[2] = 0; + } + if (lines[i].flags & ML_TFERLINE) { + target_tags[3] = (INT32)sides[lines[i].sidenum[1]].textureoffset / FRACUNIT; + target_tags[4] = (INT32)sides[lines[i].sidenum[1]].rowoffset / FRACUNIT; + } else { + target_tags[3] = target_tags[4] = 0; + } + + for (j = 0; j < numsectors; j++) { + CONS_Printf("Sector %zu (tag %d):\n", j, Tag_FGet(§ors[j].tags)); + size_t k; for (k = 0; k < 5; k++) { + if (k > 0 && !target_tags[k]) + continue; + if (Tag_Find(§ors[j].tags, target_tags[k])) { + Tag_Add(§ors[j].tags, tag); + CONS_Printf(" Tag %d found, added tag %d\n", target_tags[k], tag); + break; + } else { + CONS_Printf(" Tag %d not found\n", target_tags[k]); + } + } } } else if (lines[i].special == 97 || lines[i].special == 99) { P_AddBinaryMapTagsFromLine(lines[i].frontsector, &lines[i]); From 5090de58097eed382a58402af0f3217eb3493381 Mon Sep 17 00:00:00 2001 From: flarn2006 Date: Sat, 29 May 2021 12:09:30 -0400 Subject: [PATCH 483/644] Remove leftover debug printfs --- src/p_setup.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 0d061aaab..ea655f5f9 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2998,16 +2998,13 @@ static void P_AddBinaryMapTags(void) } for (j = 0; j < numsectors; j++) { - CONS_Printf("Sector %zu (tag %d):\n", j, Tag_FGet(§ors[j].tags)); size_t k; for (k = 0; k < 5; k++) { if (k > 0 && !target_tags[k]) continue; if (Tag_Find(§ors[j].tags, target_tags[k])) { Tag_Add(§ors[j].tags, tag); - CONS_Printf(" Tag %d found, added tag %d\n", target_tags[k], tag); break; } else { - CONS_Printf(" Tag %d not found\n", target_tags[k]); } } } From 2d4411d077a0d36a78707e655863b94afd127ec4 Mon Sep 17 00:00:00 2001 From: flarn2006 Date: Sat, 29 May 2021 12:23:35 -0400 Subject: [PATCH 484/644] Remove empty 'else' block (also leftover) --- src/p_setup.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/p_setup.c b/src/p_setup.c index ea655f5f9..095524203 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3004,7 +3004,6 @@ static void P_AddBinaryMapTags(void) if (Tag_Find(§ors[j].tags, target_tags[k])) { Tag_Add(§ors[j].tags, tag); break; - } else { } } } From f8fe763df22285af086f51389186ebf8ab15b2b8 Mon Sep 17 00:00:00 2001 From: flarn2006 Date: Sat, 29 May 2021 12:28:06 -0400 Subject: [PATCH 485/644] Fix linedef type 99 --- src/p_setup.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 095524203..f60af94ed 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3007,10 +3007,11 @@ static void P_AddBinaryMapTags(void) } } } - } else if (lines[i].special == 97 || lines[i].special == 99) { - P_AddBinaryMapTagsFromLine(lines[i].frontsector, &lines[i]); - } else if (lines[i].special == 98 || lines[i].special == 99) { - P_AddBinaryMapTagsFromLine(lines[i].backsector, &lines[i]); + } else { + if (lines[i].special == 97 || lines[i].special == 99) + P_AddBinaryMapTagsFromLine(lines[i].frontsector, &lines[i]); + if (lines[i].special == 98 || lines[i].special == 99) + P_AddBinaryMapTagsFromLine(lines[i].backsector, &lines[i]); } } } From d10cf4faf52734dc48b7fe7d4865610bce018e0a Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 29 May 2021 22:54:58 +0100 Subject: [PATCH 486/644] A_Custom3DRotate: don't scale hspeed and vspeed - they are angular speeds, not linear! (I added the scaling to this action somewhere between 7-9 years ago, and somehow never knew I made this mistake until now, welp.) --- src/p_enemy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 3b13fe295..b90a87cc0 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -9899,8 +9899,8 @@ void A_Custom3DRotate(mobj_t *actor) const fixed_t radius = FixedMul(loc1lw*FRACUNIT, actor->scale); const fixed_t hOff = FixedMul(loc1up*FRACUNIT, actor->scale); - const fixed_t hspeed = FixedMul(loc2up*FRACUNIT/10, actor->scale); - const fixed_t vspeed = FixedMul(loc2lw*FRACUNIT/10, actor->scale); + const fixed_t hspeed = loc2up*FRACUNIT/10; // Monster's note (29/05/21): DO NOT SCALE, this is an angular speed! + const fixed_t vspeed = loc2lw*FRACUNIT/10; // ditto if (LUA_CallAction(A_CUSTOM3DROTATE, actor)) return; From 0b51b391f1a7e61f1e64992c92cd96e483b1ed08 Mon Sep 17 00:00:00 2001 From: flarn2006 Date: Sun, 30 May 2021 12:16:15 -0400 Subject: [PATCH 487/644] Make 96's flags consistent with 97-99 by default --- extras/conf/SRB2-22.cfg | 17 +++++++++-------- src/p_setup.c | 35 +++++++++++++++++++---------------- 2 files changed, 28 insertions(+), 24 deletions(-) diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg index ad930a485..5a464eb5d 100644 --- a/extras/conf/SRB2-22.cfg +++ b/extras/conf/SRB2-22.cfg @@ -644,32 +644,33 @@ linedeftypes { title = "Apply Tag to Tagged Sectors"; prefix = "(96)"; - flags8192text = "[13] Use Front Side Offsets"; - flags32768text = "[15] Use Back Side Offsets"; + flags1024text = "[10] Offsets are target tags"; + flags8192text = "[13] Use front side offsets"; + flags32768text = "[15] Use back side offsets"; } 97 { title = "Apply Tag to Front Sector"; prefix = "(97)"; - flags8192text = "[13] Use Front Side Offsets"; - flags32768text = "[15] Use Back Side Offsets"; + flags8192text = "[13] Use front side offsets"; + flags32768text = "[15] Use back side offsets"; } 98 { title = "Apply Tag to Back Sector"; prefix = "(98)"; - flags8192text = "[13] Use Front Side Offsets"; - flags32768text = "[15] Use Back Side Offsets"; + flags8192text = "[13] Use front side offsets"; + flags32768text = "[15] Use back side offsets"; } 99 { title = "Apply Tag to Front and Back Sectors"; prefix = "(99)"; - flags8192text = "[13] Use Front Side Offsets"; - flags32768text = "[15] Use Back Side Offsets"; + flags8192text = "[13] Use front side offsets"; + flags32768text = "[15] Use back side offsets"; } 540 diff --git a/src/p_setup.c b/src/p_setup.c index f60af94ed..7ecaf2ff4 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2982,28 +2982,31 @@ static void P_AddBinaryMapTags(void) if (lines[i].special == 96) { size_t j; mtag_t tag = Tag_FGet(&lines[i].frontsector->tags); - mtag_t target_tags[5]; - target_tags[0] = Tag_FGet(&lines[i].tags); + mtag_t target_tag = Tag_FGet(&lines[i].tags); + mtag_t offset_tags[4]; + memset(offset_tags, 0, sizeof(mtag_t)*4); if (lines[i].flags & ML_EFFECT6) { - target_tags[1] = (INT32)sides[lines[i].sidenum[0]].textureoffset / FRACUNIT; - target_tags[2] = (INT32)sides[lines[i].sidenum[0]].rowoffset / FRACUNIT; - } else { - target_tags[1] = target_tags[2] = 0; + offset_tags[1] = (INT32)sides[lines[i].sidenum[0]].textureoffset / FRACUNIT; + offset_tags[2] = (INT32)sides[lines[i].sidenum[0]].rowoffset / FRACUNIT; } if (lines[i].flags & ML_TFERLINE) { - target_tags[3] = (INT32)sides[lines[i].sidenum[1]].textureoffset / FRACUNIT; - target_tags[4] = (INT32)sides[lines[i].sidenum[1]].rowoffset / FRACUNIT; - } else { - target_tags[3] = target_tags[4] = 0; + offset_tags[3] = (INT32)sides[lines[i].sidenum[1]].textureoffset / FRACUNIT; + offset_tags[4] = (INT32)sides[lines[i].sidenum[1]].rowoffset / FRACUNIT; } for (j = 0; j < numsectors; j++) { - size_t k; for (k = 0; k < 5; k++) { - if (k > 0 && !target_tags[k]) - continue; - if (Tag_Find(§ors[j].tags, target_tags[k])) { - Tag_Add(§ors[j].tags, tag); - break; + boolean matches_target_tag = Tag_Find(§ors[j].tags, target_tag); + size_t k; for (k = 0; k < 4; k++) { + if (lines[i].flags & ML_EFFECT5) { + if (matches_target_tag || offset_tags[k] && Tag_Find(§ors[j].tags, offset_tags[k])) { + Tag_Add(§ors[j].tags, tag); + break; + } + } else if (matches_target_tag) { + if (k == 0) + Tag_Add(§ors[j].tags, tag); + if (offset_tags[k]) + Tag_Add(§ors[j].tags, offset_tags[k]); } } } From 92209bf246068c10b1ac318faecc85313dd85e8a Mon Sep 17 00:00:00 2001 From: Radicalicious Date: Mon, 31 May 2021 15:09:54 -0400 Subject: [PATCH 488/644] Update p_user.c --- src/p_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index c5f919c78..6b3a8f585 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2992,7 +2992,7 @@ static void P_CheckUnderwaterAndSpaceTimer(player_t *player) player->powers[pw_spacetime] = 0; // Underwater audio cues - if (P_IsLocalPlayer(player) && !player->bot) + if (P_IsLocalPlayer(player) && !player->bot && !(player->mo->eflags & MFE_COLDWATER)) { if ((player->powers[pw_underwater] == 25*TICRATE + 1) || (player->powers[pw_underwater] == 20*TICRATE + 1) From 3e91a8b2d4ce08cdcda59fd37db8b2c986397c6e Mon Sep 17 00:00:00 2001 From: Radicalicious Date: Mon, 31 May 2021 19:23:37 +0000 Subject: [PATCH 489/644] Revert "Update p_user.c" This reverts commit 92209bf246068c10b1ac318faecc85313dd85e8a --- src/p_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index 6b3a8f585..c5f919c78 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2992,7 +2992,7 @@ static void P_CheckUnderwaterAndSpaceTimer(player_t *player) player->powers[pw_spacetime] = 0; // Underwater audio cues - if (P_IsLocalPlayer(player) && !player->bot && !(player->mo->eflags & MFE_COLDWATER)) + if (P_IsLocalPlayer(player) && !player->bot) { if ((player->powers[pw_underwater] == 25*TICRATE + 1) || (player->powers[pw_underwater] == 20*TICRATE + 1) From 172454f108ea17ee4c0b289df4924fc4dd8b1b02 Mon Sep 17 00:00:00 2001 From: flarn2006 Date: Tue, 1 Jun 2021 10:09:57 -0400 Subject: [PATCH 490/644] Fix offset_tags array indices --- src/p_setup.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 7ecaf2ff4..50b073a21 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2986,12 +2986,12 @@ static void P_AddBinaryMapTags(void) mtag_t offset_tags[4]; memset(offset_tags, 0, sizeof(mtag_t)*4); if (lines[i].flags & ML_EFFECT6) { - offset_tags[1] = (INT32)sides[lines[i].sidenum[0]].textureoffset / FRACUNIT; - offset_tags[2] = (INT32)sides[lines[i].sidenum[0]].rowoffset / FRACUNIT; + offset_tags[0] = (INT32)sides[lines[i].sidenum[0]].textureoffset / FRACUNIT; + offset_tags[1] = (INT32)sides[lines[i].sidenum[0]].rowoffset / FRACUNIT; } if (lines[i].flags & ML_TFERLINE) { - offset_tags[3] = (INT32)sides[lines[i].sidenum[1]].textureoffset / FRACUNIT; - offset_tags[4] = (INT32)sides[lines[i].sidenum[1]].rowoffset / FRACUNIT; + offset_tags[2] = (INT32)sides[lines[i].sidenum[1]].textureoffset / FRACUNIT; + offset_tags[3] = (INT32)sides[lines[i].sidenum[1]].rowoffset / FRACUNIT; } for (j = 0; j < numsectors; j++) { From 115254efc9e2b42c15c93d478611d0a64f4a27bd Mon Sep 17 00:00:00 2001 From: flarn2006 Date: Tue, 1 Jun 2021 17:10:29 -0400 Subject: [PATCH 491/644] Fix compiler warning related to precedence --- src/p_setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_setup.c b/src/p_setup.c index 50b073a21..61d1a5e46 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2998,7 +2998,7 @@ static void P_AddBinaryMapTags(void) boolean matches_target_tag = Tag_Find(§ors[j].tags, target_tag); size_t k; for (k = 0; k < 4; k++) { if (lines[i].flags & ML_EFFECT5) { - if (matches_target_tag || offset_tags[k] && Tag_Find(§ors[j].tags, offset_tags[k])) { + if (matches_target_tag || (offset_tags[k] && Tag_Find(§ors[j].tags, offset_tags[k]))) { Tag_Add(§ors[j].tags, tag); break; } From 8cb62eeca5515552d8d9745ea9356291697792a0 Mon Sep 17 00:00:00 2001 From: Nev3r Date: Wed, 2 Jun 2021 10:57:57 +0200 Subject: [PATCH 492/644] Initialize slopes before the map loads. --- src/p_setup.c | 2 ++ src/p_slopes.c | 10 +++++++--- src/p_slopes.h | 1 + 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 51d2f474d..aa22fed86 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -4274,6 +4274,8 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate) P_MapStart(); // tmthing can be used starting from this point + P_InitSlopes(); + if (!P_LoadMapFromFile()) return false; diff --git a/src/p_slopes.c b/src/p_slopes.c index 4e93e4a45..9ce5af838 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -635,9 +635,6 @@ pslope_t *P_SlopeById(UINT16 id) void P_SpawnSlopes(const boolean fromsave) { size_t i; - slopelist = NULL; - slopecount = 0; - /// Generates vertex slopes. SpawnVertexSlopes(); @@ -671,6 +668,13 @@ void P_SpawnSlopes(const boolean fromsave) { } } +/// Initializes slopes. +void P_InitSlopes(void) +{ + slopelist = NULL; + slopecount = 0; +} + // ============================================================================ // // Various utilities related to slopes diff --git a/src/p_slopes.h b/src/p_slopes.h index ae040ae56..f627cae70 100644 --- a/src/p_slopes.h +++ b/src/p_slopes.h @@ -50,6 +50,7 @@ typedef enum void P_LinkSlopeThinkers (void); void P_CalculateSlopeNormal(pslope_t *slope); +void P_InitSlopes(void); void P_SpawnSlopes(const boolean fromsave); // From 36ce44e0a37b3f8deac01f109f5eb3f83ed9972a Mon Sep 17 00:00:00 2001 From: Nev3r Date: Wed, 2 Jun 2021 10:58:36 +0200 Subject: [PATCH 493/644] Add slope equation constant parsing functionality. --- src/p_slopes.c | 40 ++++++++++++++++++++++++++++++++++++++++ src/p_slopes.h | 1 + 2 files changed, 41 insertions(+) diff --git a/src/p_slopes.c b/src/p_slopes.c index 9ce5af838..09094a32a 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -90,6 +90,36 @@ static void ReconfigureViaVertexes (pslope_t *slope, const vector3_t v1, const v } } +/// Setup slope via constants. +static void ReconfigureViaConstants (pslope_t *slope, const fixed_t a, const fixed_t b, const fixed_t c, const fixed_t d) +{ + fixed_t m; + vector3_t *normal = &slope->normal; + + // Set origin. + FV3_Load(&slope->o, 0, 0, c ? -FixedDiv(d, c) : 0); + + // Get slope's normal. + FV3_Load(normal, a, b, c); + FV3_Normalize(normal); + + // Invert normal if it's facing down. + if (normal->z < 0) + FV3_Negate(normal); + + // Get direction vector + m = FixedHypot(normal->x, normal->y); + slope->d.x = -FixedDiv(normal->x, m); + slope->d.y = -FixedDiv(normal->y, m); + + // Z delta + slope->zdelta = FixedDiv(m, normal->z); + + // Get angles + slope->xydirection = R_PointToAngle2(0, 0, slope->d.x, slope->d.y)+ANGLE_180; + slope->zangle = InvAngle(R_PointToAngle2(0, 0, FRACUNIT, slope->zdelta)); +} + /// Recalculate dynamic slopes. void T_DynamicSlopeLine (dynplanethink_t* th) { @@ -631,6 +661,16 @@ pslope_t *P_SlopeById(UINT16 id) return ret; } +/// Creates a new slope from equation constants. +pslope_t *MakeViaEquationConstants(const fixed_t a, const fixed_t b, const fixed_t c, const fixed_t d) +{ + pslope_t* ret = Slope_Add(0); + + ReconfigureViaConstants(ret, a, b, c, d); + + return ret; +} + /// Initializes and reads the slopes from the map data. void P_SpawnSlopes(const boolean fromsave) { size_t i; diff --git a/src/p_slopes.h b/src/p_slopes.h index f627cae70..43cd3edb0 100644 --- a/src/p_slopes.h +++ b/src/p_slopes.h @@ -87,6 +87,7 @@ fixed_t P_GetWallTransferMomZ(mobj_t *mo, pslope_t *slope); void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope); void P_ButteredSlope(mobj_t *mo); +pslope_t *MakeViaEquationConstants(const fixed_t a, const fixed_t b, const fixed_t c, const fixed_t d); /// Dynamic plane type enum for the thinker. Will have a different functionality depending on this. typedef enum { From aec1ab304a154deb156a8c8e13fe39f6e74b8714 Mon Sep 17 00:00:00 2001 From: Nev3r Date: Wed, 2 Jun 2021 10:59:05 +0200 Subject: [PATCH 494/644] Let equation slopes be read from textmaps. --- src/p_setup.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/src/p_setup.c b/src/p_setup.c index aa22fed86..330b3e1fc 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1501,6 +1501,22 @@ typedef struct textmap_colormap_s { textmap_colormap_t textmap_colormap = { false, 0, 25, 0, 25, 0, 31, 0 }; +typedef enum +{ + PD_A = 1, + PD_B = 1<<1, + PD_C = 1<<2, + PD_D = 1<<3, +} planedef_t; + +typedef struct textmap_plane_s { + UINT8 defined; + fixed_t a, b, c, d; +} textmap_plane_t; + +textmap_plane_t textmap_planefloor = {0, 0, 0, 0, 0}; +textmap_plane_t textmap_planeceiling = {0, 0, 0, 0, 0}; + static void ParseTextmapSectorParameter(UINT32 i, char *param, char *val) { if (fastcmp(param, "heightfloor")) @@ -1539,6 +1555,46 @@ static void ParseTextmapSectorParameter(UINT32 i, char *param, char *val) sectors[i].floorpic_angle = FixedAngle(FLOAT_TO_FIXED(atof(val))); else if (fastcmp(param, "rotationceiling")) sectors[i].ceilingpic_angle = FixedAngle(FLOAT_TO_FIXED(atof(val))); + else if (fastcmp(param, "floorplane_a")) + { + textmap_planefloor.defined |= PD_A; + textmap_planefloor.a = FLOAT_TO_FIXED(atof(val)); + } + else if (fastcmp(param, "floorplane_b")) + { + textmap_planefloor.defined |= PD_B; + textmap_planefloor.a = FLOAT_TO_FIXED(atof(val)); + } + else if (fastcmp(param, "floorplane_c")) + { + textmap_planefloor.defined |= PD_C; + textmap_planefloor.a = FLOAT_TO_FIXED(atof(val)); + } + else if (fastcmp(param, "floorplane_d")) + { + textmap_planefloor.defined |= PD_D; + textmap_planefloor.a = FLOAT_TO_FIXED(atof(val)); + } + else if (fastcmp(param, "ceilingplane_a")) + { + textmap_planeceiling.defined |= PD_A; + textmap_planeceiling.a = FLOAT_TO_FIXED(atof(val)); + } + else if (fastcmp(param, "ceilingplane_b")) + { + textmap_planeceiling.defined |= PD_B; + textmap_planeceiling.a = FLOAT_TO_FIXED(atof(val)); + } + else if (fastcmp(param, "ceilingplane_c")) + { + textmap_planeceiling.defined |= PD_C; + textmap_planeceiling.a = FLOAT_TO_FIXED(atof(val)); + } + else if (fastcmp(param, "ceilingplane_d")) + { + textmap_planeceiling.defined |= PD_D; + textmap_planeceiling.a = FLOAT_TO_FIXED(atof(val)); + } else if (fastcmp(param, "lightcolor")) { textmap_colormap.used = true; @@ -1868,6 +1924,10 @@ static void P_LoadTextmap(void) textmap_colormap.fadestart = 0; textmap_colormap.fadeend = 31; textmap_colormap.flags = 0; + + textmap_planefloor.defined = 0; + textmap_planeceiling.defined = 0; + TextmapParse(sectorsPos[i], i, ParseTextmapSectorParameter); P_InitializeSector(sc); @@ -1877,6 +1937,19 @@ static void P_LoadTextmap(void) INT32 fadergba = P_ColorToRGBA(textmap_colormap.fadecolor, textmap_colormap.fadealpha); sc->extra_colormap = sc->spawn_extra_colormap = R_CreateColormap(rgba, fadergba, textmap_colormap.fadestart, textmap_colormap.fadeend, textmap_colormap.flags); } + + if (textmap_planefloor.defined == (PD_A|PD_B|PD_C|PD_D)) + { + sc->f_slope = MakeViaEquationConstants(textmap_planefloor.a, textmap_planefloor.b, textmap_planefloor.c, textmap_planefloor.d); + sc->hasslope = true; + } + + if (textmap_planeceiling.defined == (PD_A|PD_B|PD_C|PD_D)) + { + sc->c_slope = MakeViaEquationConstants(textmap_planeceiling.a, textmap_planeceiling.b, textmap_planeceiling.c, textmap_planeceiling.d); + sc->hasslope = true; + } + TextmapFixFlatOffsets(sc); } From 9c68f8cbb0982a09eeeff4ec8df2486ac38f200f Mon Sep 17 00:00:00 2001 From: Nev3r Date: Wed, 2 Jun 2021 11:21:37 +0200 Subject: [PATCH 495/644] Fix the equation constant fields not being filled properly. --- src/p_setup.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 330b3e1fc..c198d0c08 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1563,17 +1563,17 @@ static void ParseTextmapSectorParameter(UINT32 i, char *param, char *val) else if (fastcmp(param, "floorplane_b")) { textmap_planefloor.defined |= PD_B; - textmap_planefloor.a = FLOAT_TO_FIXED(atof(val)); + textmap_planefloor.b = FLOAT_TO_FIXED(atof(val)); } else if (fastcmp(param, "floorplane_c")) { textmap_planefloor.defined |= PD_C; - textmap_planefloor.a = FLOAT_TO_FIXED(atof(val)); + textmap_planefloor.c = FLOAT_TO_FIXED(atof(val)); } else if (fastcmp(param, "floorplane_d")) { textmap_planefloor.defined |= PD_D; - textmap_planefloor.a = FLOAT_TO_FIXED(atof(val)); + textmap_planefloor.d = FLOAT_TO_FIXED(atof(val)); } else if (fastcmp(param, "ceilingplane_a")) { @@ -1583,17 +1583,17 @@ static void ParseTextmapSectorParameter(UINT32 i, char *param, char *val) else if (fastcmp(param, "ceilingplane_b")) { textmap_planeceiling.defined |= PD_B; - textmap_planeceiling.a = FLOAT_TO_FIXED(atof(val)); + textmap_planeceiling.b = FLOAT_TO_FIXED(atof(val)); } else if (fastcmp(param, "ceilingplane_c")) { textmap_planeceiling.defined |= PD_C; - textmap_planeceiling.a = FLOAT_TO_FIXED(atof(val)); + textmap_planeceiling.c = FLOAT_TO_FIXED(atof(val)); } else if (fastcmp(param, "ceilingplane_d")) { textmap_planeceiling.defined |= PD_D; - textmap_planeceiling.a = FLOAT_TO_FIXED(atof(val)); + textmap_planeceiling.d = FLOAT_TO_FIXED(atof(val)); } else if (fastcmp(param, "lightcolor")) { @@ -3308,7 +3308,7 @@ static void P_ConvertBinaryMap(void) lines[i].args[4] |= TMSC_BACKTOFRONTCEILING; lines[i].special = 720; break; - + case 900: //Translucent wall (10%) case 901: //Translucent wall (20%) case 902: //Translucent wall (30%) From a4300220e94d924d49a4a3067de0a348e16a3705 Mon Sep 17 00:00:00 2001 From: Nev3r Date: Wed, 2 Jun 2021 11:36:52 +0200 Subject: [PATCH 496/644] whitespace --- src/p_slopes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_slopes.c b/src/p_slopes.c index 09094a32a..41cfbf337 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -817,7 +817,7 @@ void P_SlopeLaunch(mobj_t *mo) mo->momx = slopemom.x; mo->momy = slopemom.y; mo->momz = slopemom.z/2; - + if (mo->player) mo->player->powers[pw_justlaunched] = 1; } From 476dcc861be0c82e4a99f9379970588c95cbcefa Mon Sep 17 00:00:00 2001 From: lachablock Date: Thu, 3 Jun 2021 14:36:29 +1000 Subject: [PATCH 497/644] Restore P_AproxDistance Lua parity --- src/lua_baselib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 1a0b53920..594ac6af2 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -444,7 +444,7 @@ static int lib_pAproxDistance(lua_State *L) fixed_t dx = luaL_checkfixed(L, 1); fixed_t dy = luaL_checkfixed(L, 2); //HUDSAFE - lua_pushfixed(L, R_PointToDist2(0, 0, dx, dy)); + lua_pushfixed(L, P_AproxDistance(dx, dy)); return 1; } From cb5e433a49c61fda688de6d5dd5910c106df34e3 Mon Sep 17 00:00:00 2001 From: Radicalicious Date: Thu, 3 Jun 2021 09:34:18 -0400 Subject: [PATCH 498/644] Update lua_hudlib.c --- src/lua_hudlib.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 684e47c38..14d7d7f3c 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -794,6 +794,27 @@ static int libd_drawString(lua_State *L) return 0; } +static int libd_drawLevelActNum(lua_State *L) +{ + INT32 x; + INT32 y; + INT32 flags; + UINT8 num; + + HUDONLY + + x = luaL_checkinteger(L, 1); + y = luaL_checkinteger(L, 2); + flags = luaL_optinteger(L, 3, 0); + num = luaL_checkinteger(L, 4); + + flags &= ~V_PARAMMASK; // Don't let crashes happen. + + V_DrawLevelActNum(x, y, flags, num); + return 0; +} + + static int libd_drawNameTag(lua_State *L) { INT32 x; @@ -878,6 +899,20 @@ static int libd_stringWidth(lua_State *L) return 1; } +static int libd_levelActNumWidth(lua_State *L) +{ + HUDONLY + lua_pushinteger(L, V_LevelActNumWidth(luaL_checkinteger(L, 1))); + return 1; +} + +static int libd_levelActNumHeight(lua_State *L) +{ + HUDONLY + lua_pushinteger(L, V_LevelActNumHeight(luaL_checkinteger(L, 1))); + return 1; +} + static int libd_nameTagWidth(lua_State *L) { HUDONLY @@ -1086,11 +1121,14 @@ static luaL_Reg lib_draw[] = { {"drawPaddedNum", libd_drawPaddedNum}, {"drawFill", libd_drawFill}, {"drawString", libd_drawString}, + {"drawLevelActNum", libd_drawLevelActNum}, {"drawNameTag", libd_drawNameTag}, {"drawScaledNameTag", libd_drawScaledNameTag}, {"fadeScreen", libd_fadeScreen}, // misc {"stringWidth", libd_stringWidth}, + {"levelActNumWidth", libd_levelActNumWidth}, + {"levelActNumHeight", libd_levelActNumHeight}, {"nameTagWidth", libd_nameTagWidth}, // m_random {"RandomFixed",libd_RandomFixed}, From 6ff212b79f4bc97b2f34edf2ebc62e79e64ca519 Mon Sep 17 00:00:00 2001 From: sphere Date: Thu, 3 Jun 2021 16:01:09 +0200 Subject: [PATCH 499/644] Use floating-point math for polyobject planes as well. --- src/r_plane.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/r_plane.c b/src/r_plane.c index 4c757d8ca..818770906 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -380,9 +380,11 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, { if (polyobj->angle != 0) { - angle_t fineshift = polyobj->angle >> ANGLETOFINESHIFT; - xoff -= FixedMul(FINECOSINE(fineshift), polyobj->centerPt.x)+FixedMul(FINESINE(fineshift), polyobj->centerPt.y); - yoff -= FixedMul(FINESINE(fineshift), polyobj->centerPt.x)-FixedMul(FINECOSINE(fineshift), polyobj->centerPt.y); + float ang = ANG2RAD(polyobj->angle); + float x = FixedToFloat(polyobj->centerPt.x); + float y = FixedToFloat(polyobj->centerPt.y); + xoff -= FloatToFixed(x * cos(ang) + y * sin(ang)); + yoff -= FloatToFixed(x * sin(ang) - y * cos(ang)); } else { From 7483a9d049230e983e5fd8b44dd733c7bf26bb16 Mon Sep 17 00:00:00 2001 From: Radicalicious Date: Thu, 3 Jun 2021 10:55:42 -0400 Subject: [PATCH 500/644] Switch num and flags so flags is optional --- src/lua_hudlib.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 14d7d7f3c..5e974675f 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -798,15 +798,15 @@ static int libd_drawLevelActNum(lua_State *L) { INT32 x; INT32 y; - INT32 flags; UINT8 num; + INT32 flags; HUDONLY x = luaL_checkinteger(L, 1); y = luaL_checkinteger(L, 2); - flags = luaL_optinteger(L, 3, 0); - num = luaL_checkinteger(L, 4); + num = luaL_checkinteger(L, 3); + flags = luaL_optinteger(L, 4, 0); flags &= ~V_PARAMMASK; // Don't let crashes happen. From 409cba678dcabcc7cb2960cf3d444a45b064a47b Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Sat, 5 Jun 2021 18:35:44 -0500 Subject: [PATCH 501/644] metalrecording --- src/lua_script.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/lua_script.c b/src/lua_script.c index 6b8613812..4e04c2ee0 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -184,6 +184,9 @@ int LUA_PushGlobals(lua_State *L, const char *word) } else if (fastcmp(word,"modeattacking")) { lua_pushboolean(L, modeattacking); return 1; + } else if (fastcmp(word,"metalrecording")) { + lua_pushboolean(L, metalrecording); + return 1; } else if (fastcmp(word,"splitscreen")) { lua_pushboolean(L, splitscreen); return 1; From 0f4eb4fab949976276c4a8e9426d45bbfc275eec Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 7 Jun 2021 18:13:22 -0700 Subject: [PATCH 502/644] Merge conflicts 4d22b9f17 --- src/lua_hook.h | 6 +++++- src/lua_hooklib.c | 45 ++++++++++++++++++++++++++++++++++++++++----- src/p_user.c | 46 +++++++++++++++++++++++----------------------- 3 files changed, 68 insertions(+), 29 deletions(-) diff --git a/src/lua_hook.h b/src/lua_hook.h index 0f8482794..b44233734 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 2012-2016 by John "JTE" Muniz. -// Copyright (C) 2012-2020 by Sonic Team Junior. +// Copyright (C) 2012-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -68,6 +68,8 @@ automatically. X (GameQuit),\ X (PlayerCmd),/* building the player's ticcmd struct (Ported from SRB2Kart) */\ X (MusicChange),\ + X (PlayerHeight),/* override player height */\ + X (PlayerCanEnterSpinGaps),\ #define STRING_HOOK_LIST(X) \ X (BotAI),/* B_BuildTailsTiccmd by skin name */\ @@ -124,3 +126,5 @@ int LUA_HookSeenPlayer(player_t *player, player_t *seenfriend); int LUA_HookShouldJingleContinue(player_t *, const char *musname); int LUA_HookPlayerCmd(player_t *, ticcmd_t *); int LUA_HookMusicChange(const char *oldname, struct MusicChange *); +fixed_t LUA_HookPlayerHeight(player_t *player); +int LUA_HookPlayerCanEnterSpinGaps(player_t *player); diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 7f5e3dc96..9f4fa4c88 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 2012-2016 by John "JTE" Muniz. -// Copyright (C) 2012-2020 by Sonic Team Junior. +// Copyright (C) 2012-2021 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -231,7 +231,7 @@ typedef struct Hook_State Hook_State; typedef void (*Hook_Callback)(Hook_State *); struct Hook_State { - int status;/* return status to calling function */ + INT32 status;/* return status to calling function */ void * userdata; int hook_type; mobjtype_t mobj_type;/* >0 if mobj hook */ @@ -1005,13 +1005,13 @@ static void res_musicchange(Hook_State *hook) if (lua_isboolean(gL, -4)) *musicchange->looping = lua_toboolean(gL, -4); // output 4: position override - if (lua_isboolean(gL, -3)) + if (lua_isnumber(gL, -3)) *musicchange->position = lua_tonumber(gL, -3); // output 5: prefadems override - if (lua_isboolean(gL, -2)) + if (lua_isnumber(gL, -2)) *musicchange->prefadems = lua_tonumber(gL, -2); // output 6: fadeinms override - if (lua_isboolean(gL, -1)) + if (lua_isnumber(gL, -1)) *musicchange->fadeinms = lua_tonumber(gL, -1); } @@ -1052,3 +1052,38 @@ int LUA_HookMusicChange(const char *oldname, struct MusicChange *param) return hook.status; } + +static void res_playerheight(Hook_State *hook) +{ + if (!lua_isnil(gL, -1)) + { + fixed_t returnedheight = lua_tonumber(gL, -1); + // 0 height has... strange results, but it's not problematic like negative heights are. + // when an object's height is set to a negative number directly with lua, it's forced to 0 instead. + // here, I think it's better to ignore negatives so that they don't replace any results of previous hooks! + if (returnedheight >= 0) + hook->status = returnedheight; + } +} + +fixed_t LUA_HookPlayerHeight(player_t *player) +{ + Hook_State hook; + if (prepare_hook(&hook, -1, HOOK(PlayerHeight))) + { + LUA_PushUserdata(gL, player, META_PLAYER); + call_hooks(&hook, 1, 1, res_playerheight); + } + return hook.status; +} + +int LUA_HookPlayerCanEnterSpinGaps(player_t *player) +{ + Hook_State hook; + if (prepare_hook(&hook, 0, HOOK(PlayerCanEnterSpinGaps))) + { + LUA_PushUserdata(gL, player, META_PLAYER); + call_hooks(&hook, 1, 1, res_force); + } + return hook.status; +} diff --git a/src/p_user.c b/src/p_user.c index 2b773c84a..c3184b52f 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1111,7 +1111,7 @@ boolean P_PlayerCanDamage(player_t *player, mobj_t *thing) return false; { - UINT8 shouldCollide = LUAh_PlayerCanDamage(player, thing); + UINT8 shouldCollide = LUA_HookPlayerCanDamage(player, thing); if (P_MobjWasRemoved(thing)) return false; // removed??? if (shouldCollide == 1) @@ -1594,7 +1594,7 @@ boolean P_EvaluateMusicStatus(UINT16 status, const char *musname) break; case JT_OTHER: // Other state - result = LUAh_ShouldJingleContinue(&players[i], musname); + result = LUA_HookShouldJingleContinue(&players[i], musname); break; case JT_NONE: // Null state @@ -1860,7 +1860,7 @@ void P_SpawnShieldOrb(player_t *player) I_Error("P_SpawnShieldOrb: player->mo is NULL!\n"); #endif - if (LUAh_ShieldSpawn(player)) + if (LUA_HookPlayer(player, HOOK(ShieldSpawn))) return; if (player->powers[pw_shield] & SH_FORCE) @@ -4583,7 +4583,7 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) if (cmd->buttons & BT_SPIN) { - if (LUAh_SpinSpecial(player)) + if (LUA_HookPlayer(player, HOOK(SpinSpecial))) return; } @@ -5055,7 +5055,7 @@ static boolean P_PlayerShieldThink(player_t *player, ticcmd_t *cmd, mobj_t *lock } } } - if ((!(player->charflags & SF_NOSHIELDABILITY)) && (cmd->buttons & BT_SPIN && !LUAh_ShieldSpecial(player))) // Spin button effects + if ((!(player->charflags & SF_NOSHIELDABILITY)) && (cmd->buttons & BT_SPIN && !LUA_HookPlayer(player, HOOK(ShieldSpecial)))) // Spin button effects { // Force stop if ((player->powers[pw_shield] & ~(SH_FORCEHP|SH_STACK)) == SH_FORCE) @@ -5179,7 +5179,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) // and you don't have a shield, do it! P_DoSuperTransformation(player, false); } - else if (!LUAh_JumpSpinSpecial(player)) + else if (!LUA_HookPlayer(player, HOOK(JumpSpinSpecial))) switch (player->charability) { case CA_THOK: @@ -5252,7 +5252,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) if (cmd->buttons & BT_JUMP && !player->exiting && !P_PlayerInPain(player)) { - if (LUAh_JumpSpecial(player)) + if (LUA_HookPlayer(player, HOOK(JumpSpecial))) ; // all situations below this require jump button not to be pressed already else if (player->pflags & PF_JUMPDOWN) @@ -5287,7 +5287,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) }*/ else if (player->pflags & PF_JUMPED) { - if (!LUAh_AbilitySpecial(player)) + if (!LUA_HookPlayer(player, HOOK(AbilitySpecial))) switch (player->charability) { case CA_THOK: @@ -5480,7 +5480,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) } else if (player->pflags & PF_THOKKED) { - if (!LUAh_AbilitySpecial(player)) + if (!LUA_HookPlayer(player, HOOK(AbilitySpecial))) switch (player->charability) { case CA_FLY: @@ -5503,7 +5503,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) break; } } - else if ((!(player->charflags & SF_NOSHIELDABILITY)) && ((player->powers[pw_shield] & SH_NOSTACK) == SH_WHIRLWIND && !player->powers[pw_super] && !LUAh_ShieldSpecial(player))) + else if ((!(player->charflags & SF_NOSHIELDABILITY)) && ((player->powers[pw_shield] & SH_NOSTACK) == SH_WHIRLWIND && !player->powers[pw_super] && !LUA_HookPlayer(player, HOOK(ShieldSpecial)))) P_DoJumpShield(player); } @@ -8653,7 +8653,7 @@ void P_MovePlayer(player_t *player) { boolean atspinheight = false; fixed_t oldheight = player->mo->height; - fixed_t luaheight = LUAh_PlayerHeight(player); + fixed_t luaheight = LUA_HookPlayerHeight(player); if (luaheight != -1) { @@ -10515,7 +10515,7 @@ boolean P_SpectatorJoinGame(player_t *player) else changeto = (P_RandomFixed() & 1) + 1; - if (!LUAh_TeamSwitch(player, changeto, true, false, false)) + if (!LUA_HookTeamSwitch(player, changeto, true, false, false)) return false; if (player->mo) @@ -10532,7 +10532,7 @@ boolean P_SpectatorJoinGame(player_t *player) { // Call ViewpointSwitch hooks here. // The viewpoint was forcibly changed. - LUAh_ViewpointSwitch(player, &players[consoleplayer], true); + LUA_HookViewpointSwitch(player, &players[consoleplayer], true); displayplayer = consoleplayer; } @@ -10550,7 +10550,7 @@ boolean P_SpectatorJoinGame(player_t *player) // respawn in place and sit there for the rest of the round. if (!((gametyperules & GTR_HIDEFROZEN) && leveltime > (hidetime * TICRATE))) { - if (!LUAh_TeamSwitch(player, 3, true, false, false)) + if (!LUA_HookTeamSwitch(player, 3, true, false, false)) return false; if (player->mo) { @@ -10577,7 +10577,7 @@ boolean P_SpectatorJoinGame(player_t *player) { // Call ViewpointSwitch hooks here. // The viewpoint was forcibly changed. - LUAh_ViewpointSwitch(player, &players[consoleplayer], true); + LUA_HookViewpointSwitch(player, &players[consoleplayer], true); displayplayer = consoleplayer; } @@ -11503,7 +11503,7 @@ void P_PlayerThink(player_t *player) } if (player->playerstate == PST_REBORN) { - LUAh_PlayerThink(player); + LUA_HookPlayer(player, HOOK(PlayerThink)); return; } } @@ -11605,7 +11605,7 @@ void P_PlayerThink(player_t *player) if (player->playerstate == PST_DEAD) { - LUAh_PlayerThink(player); + LUA_HookPlayer(player, HOOK(PlayerThink)); return; } } @@ -11726,7 +11726,7 @@ void P_PlayerThink(player_t *player) { player->mo->flags2 &= ~MF2_SHADOW; P_DeathThink(player); - LUAh_PlayerThink(player); + LUA_HookPlayer(player, HOOK(PlayerThink)); return; } @@ -11768,7 +11768,7 @@ void P_PlayerThink(player_t *player) { if (P_SpectatorJoinGame(player)) { - LUAh_PlayerThink(player); + LUA_HookPlayer(player, HOOK(PlayerThink)); return; // player->mo was removed. } } @@ -11873,7 +11873,7 @@ void P_PlayerThink(player_t *player) if (!player->mo) { - LUAh_PlayerThink(player); + LUA_HookPlayer(player, HOOK(PlayerThink)); return; // P_MovePlayer removed player->mo. } @@ -12327,7 +12327,7 @@ void P_PlayerThink(player_t *player) } #undef dashmode - LUAh_PlayerThink(player); + LUA_HookPlayer(player, HOOK(PlayerThink)); /* // Colormap verification @@ -12896,7 +12896,7 @@ void P_PlayerAfterThink(player_t *player) if (player->followmobj) { - if (LUAh_FollowMobj(player, player->followmobj) || P_MobjWasRemoved(player->followmobj)) + if (LUA_HookFollowMobj(player, player->followmobj) || P_MobjWasRemoved(player->followmobj)) {;} else { @@ -12975,7 +12975,7 @@ boolean P_PlayerFullbright(player_t *player) // returns true if the player can enter a sector that they could not if standing at their skin's full height boolean P_PlayerCanEnterSpinGaps(player_t *player) { - UINT8 canEnter = LUAh_PlayerCanEnterSpinGaps(player); + UINT8 canEnter = LUA_HookPlayerCanEnterSpinGaps(player); if (canEnter == 1) return true; else if (canEnter == 2) From 4d1b3edb035b362cf6c3e37f78ea755f4e61cf1b Mon Sep 17 00:00:00 2001 From: lachablock Date: Tue, 8 Jun 2021 17:21:54 +1000 Subject: [PATCH 503/644] Split up x/y/z averages in A_Boss3ShockThink --- src/p_enemy.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 9a9edb5e3..eb4b0c080 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -8272,7 +8272,7 @@ void A_Boss3ShockThink(mobj_t *actor) fixed_t x0, y0, x1, y1; // Break the link if movements are too different - if (FixedHypot(snext->momx - actor->momx, snext->momy - actor->momy) > 12*actor->scale) + if (R_PointToDist2(0, 0, snext->momx - actor->momx, snext->momy - actor->momy) > 12*actor->scale) { P_SetTarget(&actor->hnext, NULL); return; @@ -8283,9 +8283,11 @@ void A_Boss3ShockThink(mobj_t *actor) y0 = actor->y; x1 = snext->x; y1 = snext->y; - if (FixedHypot(x1 - x0, y1 - y0) > 2*actor->radius) + if (R_PointToDist2(0, 0, x1 - x0, y1 - y0) > 2*actor->radius) { - snew = P_SpawnMobj((x0 + x1) >> 1, (y0 + y1) >> 1, (actor->z + snext->z) >> 1, actor->type); + snew = P_SpawnMobj((x0 >> 1) + (x1 >> 1), + (y0 >> 1) + (y1 >> 1), + (actor->z >> 1) + (snext->z >> 1), actor->type); snew->momx = (actor->momx + snext->momx) >> 1; snew->momy = (actor->momy + snext->momy) >> 1; snew->momz = (actor->momz + snext->momz) >> 1; // is this really needed? From fbeabad7972c966776a3d86617caefc799a1e440 Mon Sep 17 00:00:00 2001 From: Riku Salminen <38985578+Riku-S@users.noreply.github.com> Date: Wed, 9 Jun 2021 19:28:14 +0300 Subject: [PATCH 504/644] Revert "Made height/spinheight and height change values in replays more accurate" This reverts commit 3daee0ebf882d795ec0aef7fb54d48b74f940c59. --- src/g_demo.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/g_demo.c b/src/g_demo.c index 7793e0272..80968cd1c 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -463,7 +463,8 @@ void G_WriteGhostTic(mobj_t *ghost) WRITEUINT16(demo_p,oldghost.sprite); if (ghostext.flags & EZT_HEIGHT) { - WRITEFIXED(demo_p, height); + height >>= FRACBITS; + WRITEINT16(demo_p, height); } ghostext.flags = 0; } @@ -619,7 +620,7 @@ void G_ConsGhostTic(void) if (xziptic & EZT_SPRITE) demo_p += sizeof(UINT16); if (xziptic & EZT_HEIGHT) - demo_p += (demoversion < 0x000e) ? sizeof(INT16) : sizeof(fixed_t); + demo_p += sizeof(INT16); } if (ziptic & GZT_FOLLOW) @@ -853,7 +854,7 @@ void G_GhostTicker(void) g->mo->sprite = READUINT16(g->p); if (xziptic & EZT_HEIGHT) { - fixed_t temp = (g->version < 0x000e) ? READINT16(g->p)<p); + fixed_t temp = READINT16(g->p)<mo->height = FixedMul(temp, g->mo->scale); } } @@ -1117,7 +1118,7 @@ void G_ReadMetalTic(mobj_t *metal) metal->sprite = READUINT16(metal_p); if (xziptic & EZT_HEIGHT) { - fixed_t temp = (metalversion < 0x000e) ? READINT16(metal_p)<height = FixedMul(temp, metal->scale); } } @@ -1304,7 +1305,8 @@ void G_WriteMetalTic(mobj_t *metal) WRITEUINT16(demo_p,oldmetal.sprite); if (ghostext.flags & EZT_HEIGHT) { - WRITEFIXED(demo_p, height); + height >>= FRACBITS; + WRITEINT16(demo_p, height); } ghostext.flags = 0; } @@ -1484,8 +1486,8 @@ void G_BeginRecording(void) WRITEUINT8(demo_p,player->thrustfactor); WRITEUINT8(demo_p,player->accelstart); WRITEUINT8(demo_p,player->acceleration); - WRITEFIXED(demo_p,player->height); - WRITEFIXED(demo_p,player->spinheight); + WRITEUINT8(demo_p,player->height>>FRACBITS); + WRITEUINT8(demo_p,player->spinheight>>FRACBITS); WRITEUINT8(demo_p,player->camerascale>>FRACBITS); WRITEUINT8(demo_p,player->shieldscale>>FRACBITS); @@ -1911,8 +1913,8 @@ void G_DoPlayDemo(char *defdemoname) thrustfactor = READUINT8(demo_p); accelstart = READUINT8(demo_p); acceleration = READUINT8(demo_p); - height = (demoversion < 0x000e) ? (fixed_t)READUINT8(demo_p)< Date: Wed, 9 Jun 2021 19:40:59 +0300 Subject: [PATCH 505/644] Revert "Revert "Made height/spinheight and height change values in replays more accurate"" This reverts commit fbeabad7972c966776a3d86617caefc799a1e440. --- src/g_demo.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/src/g_demo.c b/src/g_demo.c index 80968cd1c..7793e0272 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -463,8 +463,7 @@ void G_WriteGhostTic(mobj_t *ghost) WRITEUINT16(demo_p,oldghost.sprite); if (ghostext.flags & EZT_HEIGHT) { - height >>= FRACBITS; - WRITEINT16(demo_p, height); + WRITEFIXED(demo_p, height); } ghostext.flags = 0; } @@ -620,7 +619,7 @@ void G_ConsGhostTic(void) if (xziptic & EZT_SPRITE) demo_p += sizeof(UINT16); if (xziptic & EZT_HEIGHT) - demo_p += sizeof(INT16); + demo_p += (demoversion < 0x000e) ? sizeof(INT16) : sizeof(fixed_t); } if (ziptic & GZT_FOLLOW) @@ -854,7 +853,7 @@ void G_GhostTicker(void) g->mo->sprite = READUINT16(g->p); if (xziptic & EZT_HEIGHT) { - fixed_t temp = READINT16(g->p)<version < 0x000e) ? READINT16(g->p)<p); g->mo->height = FixedMul(temp, g->mo->scale); } } @@ -1118,7 +1117,7 @@ void G_ReadMetalTic(mobj_t *metal) metal->sprite = READUINT16(metal_p); if (xziptic & EZT_HEIGHT) { - fixed_t temp = READINT16(metal_p)<height = FixedMul(temp, metal->scale); } } @@ -1305,8 +1304,7 @@ void G_WriteMetalTic(mobj_t *metal) WRITEUINT16(demo_p,oldmetal.sprite); if (ghostext.flags & EZT_HEIGHT) { - height >>= FRACBITS; - WRITEINT16(demo_p, height); + WRITEFIXED(demo_p, height); } ghostext.flags = 0; } @@ -1486,8 +1484,8 @@ void G_BeginRecording(void) WRITEUINT8(demo_p,player->thrustfactor); WRITEUINT8(demo_p,player->accelstart); WRITEUINT8(demo_p,player->acceleration); - WRITEUINT8(demo_p,player->height>>FRACBITS); - WRITEUINT8(demo_p,player->spinheight>>FRACBITS); + WRITEFIXED(demo_p,player->height); + WRITEFIXED(demo_p,player->spinheight); WRITEUINT8(demo_p,player->camerascale>>FRACBITS); WRITEUINT8(demo_p,player->shieldscale>>FRACBITS); @@ -1913,8 +1911,8 @@ void G_DoPlayDemo(char *defdemoname) thrustfactor = READUINT8(demo_p); accelstart = READUINT8(demo_p); acceleration = READUINT8(demo_p); - height = (fixed_t)READUINT8(demo_p)< Date: Thu, 10 Jun 2021 17:49:33 +0200 Subject: [PATCH 506/644] Ignore a linedef tag of 0 when using linedef action 96. --- src/p_setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_setup.c b/src/p_setup.c index 51d2f474d..db44e4be0 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2995,7 +2995,7 @@ static void P_AddBinaryMapTags(void) } for (j = 0; j < numsectors; j++) { - boolean matches_target_tag = Tag_Find(§ors[j].tags, target_tag); + boolean matches_target_tag = target_tag && Tag_Find(§ors[j].tags, target_tag); size_t k; for (k = 0; k < 4; k++) { if (lines[i].flags & ML_EFFECT5) { if (matches_target_tag || (offset_tags[k] && Tag_Find(§ors[j].tags, offset_tags[k]))) { From 9210923b86ead23f81f16f1153f9b8d046431faa Mon Sep 17 00:00:00 2001 From: Radicalicious Date: Thu, 10 Jun 2021 12:59:54 -0400 Subject: [PATCH 507/644] Cut cv_hidetime's minimum value to 5 seconds --- src/d_netcmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 31c10f58a..78fc83474 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -286,7 +286,7 @@ consvar_t cv_gravity = CVAR_INIT ("gravity", "0.5", CV_RESTRICT|CV_FLOAT|CV_CALL consvar_t cv_soundtest = CVAR_INIT ("soundtest", "0", CV_CALL, NULL, SoundTest_OnChange); -static CV_PossibleValue_t minitimelimit_cons_t[] = {{15, "MIN"}, {9999, "MAX"}, {0, NULL}}; +static CV_PossibleValue_t minitimelimit_cons_t[] = {{5, "MIN"}, {9999, "MAX"}, {0, NULL}}; consvar_t cv_countdowntime = CVAR_INIT ("countdowntime", "60", CV_SAVE|CV_NETVAR|CV_CHEAT, minitimelimit_cons_t, NULL); consvar_t cv_touchtag = CVAR_INIT ("touchtag", "Off", CV_SAVE|CV_NETVAR, CV_OnOff, NULL); From f1a96bd7ee1df2e3cf0c2ab7b6b6f9ce4841778b Mon Sep 17 00:00:00 2001 From: Riku Salminen <38985578+Riku-S@users.noreply.github.com> Date: Thu, 10 Jun 2021 21:18:45 +0300 Subject: [PATCH 508/644] Add support for ghosts with netvars in 2.2.6 and before --- src/g_demo.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/g_demo.c b/src/g_demo.c index 7793e0272..45d09fdbd 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -726,6 +726,7 @@ void G_GhostTicker(void) g->mo->y = g->oldmo.y; g->mo->z = g->oldmo.z; P_SetThingPosition(g->mo); + g->mo->frame = g->oldmo.frame | tr_trans30<fadein) { @@ -2023,7 +2024,7 @@ void G_AddGhost(char *defdemoname) char name[17],skin[17],color[MAXCOLORNAME+1],*n,*pdemoname,md5[16]; UINT8 cnamelen; demoghost *gh; - UINT8 flags; + UINT8 flags, subversion; UINT8 *buffer,*p; mapthing_t *mthing; UINT16 count, ghostversion; @@ -2071,7 +2072,7 @@ void G_AddGhost(char *defdemoname) return; } p += 12; // DEMOHEADER p++; // VERSION - p++; // SUBVERSION + subversion = READUINT8(p); // SUBVERSION ghostversion = READUINT16(p); switch(ghostversion) { @@ -2170,9 +2171,19 @@ void G_AddGhost(char *defdemoname) count = READUINT16(p); while (count--) { - SKIPSTRING(p); - SKIPSTRING(p); - p++; + // In 2.2.7 netvar saving was updated + if (subversion < 7) + { + p += 2; + SKIPSTRING(p); + p++; + } + else + { + SKIPSTRING(p); + SKIPSTRING(p); + p++; + } } if (*p == DEMOMARKER) From 2a891546672cedc06174ab753c92d26316eb0240 Mon Sep 17 00:00:00 2001 From: Ors Date: Thu, 10 Jun 2021 14:23:51 -0400 Subject: [PATCH 509/644] Revert an accidental whitespace change --- src/g_demo.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/g_demo.c b/src/g_demo.c index 45d09fdbd..bf2013107 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -726,7 +726,6 @@ void G_GhostTicker(void) g->mo->y = g->oldmo.y; g->mo->z = g->oldmo.z; P_SetThingPosition(g->mo); - g->mo->frame = g->oldmo.frame | tr_trans30<fadein) { From 4c9b83b6bdd8cd3e2626505940de75668e3db0c2 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 10 Jun 2021 21:20:42 +0100 Subject: [PATCH 510/644] Allow P_CheckSight to see through FF_FOG FOFs --- src/p_sight.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/p_sight.c b/src/p_sight.c index e4a37a718..706745f35 100644 --- a/src/p_sight.c +++ b/src/p_sight.c @@ -307,7 +307,7 @@ static boolean P_CrossSubsector(size_t num, register los_t *los) for (rover = front->ffloors; rover; rover = rover->next) { if (!(rover->flags & FF_EXISTS) - || !(rover->flags & FF_RENDERSIDES) || rover->flags & FF_TRANSLUCENT) + || !(rover->flags & FF_RENDERSIDES) || (rover->flags & (FF_TRANSLUCENT|FF_FOG))) { continue; } @@ -323,7 +323,7 @@ static boolean P_CrossSubsector(size_t num, register los_t *los) for (rover = back->ffloors; rover; rover = rover->next) { if (!(rover->flags & FF_EXISTS) - || !(rover->flags & FF_RENDERSIDES) || rover->flags & FF_TRANSLUCENT) + || !(rover->flags & FF_RENDERSIDES) || (rover->flags & (FF_TRANSLUCENT|FF_FOG))) { continue; } @@ -452,7 +452,7 @@ boolean P_CheckSight(mobj_t *t1, mobj_t *t2) /// \todo Improve by checking fog density/translucency /// and setting a sight limit. if (!(rover->flags & FF_EXISTS) - || !(rover->flags & FF_RENDERPLANES) || rover->flags & FF_TRANSLUCENT) + || !(rover->flags & FF_RENDERPLANES) || (rover->flags & (FF_TRANSLUCENT|FF_FOG))) { continue; } From c9417f26e59bffcf2b0f2f5452d8ce5e98e2da55 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 10 Jun 2021 17:47:03 -0700 Subject: [PATCH 511/644] Fix pop original table in lua net archive --- src/lua_hooklib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 9f4fa4c88..a8d49db7e 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -851,7 +851,7 @@ void LUA_HookNetArchive(lua_CFunction archFunc) init_hook_call(&hook, 1, 0, res_none); call_mapped(&hook, map); - lua_pop(gL, 2); // pop hook table and archFunc + lua_pop(gL, 1); // pop archFunc lua_remove(gL, EINDEX); // pop error handler // stack: tables } From 46ca9613c68422a26910cbb034a9f3e004a967c3 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 10 Jun 2021 18:09:39 -0700 Subject: [PATCH 512/644] Pop hook id fetched from table --- src/lua_hooklib.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index a8d49db7e..63a1b111d 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -352,6 +352,7 @@ static void get_hook_from_table(Hook_State *hook, int n) { lua_rawgeti(gL, -1, n); hook->id = lua_tonumber(gL, -1); + lua_pop(gL, 1); lua_getref(gL, hookRefs[hook->id]); } From 460d46bbc9095820c9a3c84bf716079735977fea Mon Sep 17 00:00:00 2001 From: Radicalicious Date: Fri, 11 Jun 2021 10:52:31 -0400 Subject: [PATCH 513/644] Cut cv_hidetime's minimum value all the way down to 1 --- src/d_netcmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 78fc83474..c6091d9e0 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -286,7 +286,7 @@ consvar_t cv_gravity = CVAR_INIT ("gravity", "0.5", CV_RESTRICT|CV_FLOAT|CV_CALL consvar_t cv_soundtest = CVAR_INIT ("soundtest", "0", CV_CALL, NULL, SoundTest_OnChange); -static CV_PossibleValue_t minitimelimit_cons_t[] = {{5, "MIN"}, {9999, "MAX"}, {0, NULL}}; +static CV_PossibleValue_t minitimelimit_cons_t[] = {{1, "MIN"}, {9999, "MAX"}, {0, NULL}}; consvar_t cv_countdowntime = CVAR_INIT ("countdowntime", "60", CV_SAVE|CV_NETVAR|CV_CHEAT, minitimelimit_cons_t, NULL); consvar_t cv_touchtag = CVAR_INIT ("touchtag", "Off", CV_SAVE|CV_NETVAR, CV_OnOff, NULL); From 8be7c1a03d8a4c011b777eb41d8e906e4539e7bc Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 11 Jun 2021 18:31:38 -0700 Subject: [PATCH 514/644] Fix double micros conv. blame e0a307da15 --- src/lua_hooklib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 63a1b111d..2ecd12589 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -624,7 +624,7 @@ void LUA_HookThinkFrame(void) if (cv_perfstats.value == 3) { lua_Debug ar; - time_taken = I_PreciseToMicros(I_GetPreciseTime() - time_taken); + time_taken = I_GetPreciseTime() - time_taken; lua_getinfo(gL, ">S", &ar); PS_SetThinkFrameHookInfo(hook_index, time_taken, ar.short_src); hook_index++; From 781678389f8c591c5f201b2c789e5d92b90788c8 Mon Sep 17 00:00:00 2001 From: Radicalicious Date: Sat, 12 Jun 2021 20:36:57 -0400 Subject: [PATCH 515/644] Replace "II" with "2" for consistency --- src/f_finale.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/f_finale.c b/src/f_finale.c index 688cd4fc7..bfea57a60 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1063,7 +1063,7 @@ boolean F_IntroResponder(event_t *event) // CREDITS // ========= static const char *credits[] = { - "\1Sonic Robo Blast II", + "\1Sonic Robo Blast 2", "\1Credits", "", "\1Game Design", From df5c9933ec355b2924c0dc8d10cf6044ec7fd4fd Mon Sep 17 00:00:00 2001 From: sphere Date: Wed, 16 Jun 2021 16:12:38 +0200 Subject: [PATCH 516/644] Restore toggle for Robo-Hood to not jump away from nearby players. --- extras/conf/SRB2-22.cfg | 1 + src/p_enemy.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg index 5a464eb5d..f457fe972 100644 --- a/extras/conf/SRB2-22.cfg +++ b/extras/conf/SRB2-22.cfg @@ -3589,6 +3589,7 @@ thingtypes sprite = "ARCHA1"; width = 24; height = 32; + flags8text = "[8] Don't jump away"; } 118 { diff --git a/src/p_enemy.c b/src/p_enemy.c index 9a9edb5e3..def3a87f5 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -1709,7 +1709,7 @@ void A_HoodThink(mobj_t *actor) dx = (actor->target->x - actor->x), dy = (actor->target->y - actor->y), dz = (actor->target->z - actor->z); dm = P_AproxDistance(dx, dy); // Target dangerously close to robohood, retreat then. - if ((dm < 256<flags2 & MF2_AMBUSH)) { S_StartSound(actor, actor->info->attacksound); P_SetMobjState(actor, actor->info->raisestate); From 3a044e71cc7cf6c80d9836189511c1a58c108370 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 16 Jun 2021 15:34:58 -0700 Subject: [PATCH 517/644] Disable EXE disassembly and compression by default NOOBJDUMP=1 and NOUPX=1 have been removed. Make 'dump' target to disassemble. UPX=upx to compress executable. Setting UPX used to cause it to fail. That has been fixed. --- src/Makefile | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/Makefile b/src/Makefile index 0c44afe55..6ec009044 100644 --- a/src/Makefile +++ b/src/Makefile @@ -15,6 +15,7 @@ # cleandep - remove dependency files for this build # distclean - remove entire executable, object and # dependency file directory structure. +# dump - disassemble executable # info - print settings # # This Makefile can automatically detect the host system @@ -83,8 +84,8 @@ # STATIC=1 - Use static linking. # DISTCC=1 # CCACHE=1 -# NOOBJDUMP=1 - Don't disassemble executable. -# NOUPX=1 - Don't compress executable. +# UPX= - UPX command to use for compressing final +# executable. # WINDOWSHELL=1 - Use Windows commands. # PREFIX= - Prefix to many commands, for cross compiling. # YASM=1 - Use Yasm instead of NASM assembler. @@ -165,7 +166,6 @@ ifdef WINDOWSHELL GZIP_OPTS+=--rsyncable endif -UPX?=upx UPX_OPTS?=--best --preserve-build-id ifndef ECHO UPX_OPTS+=-qq @@ -242,9 +242,7 @@ all : $(exe) $(call Echo,$(build_done)) ifndef VALGRIND -ifndef NOOBJDUMP -all : $(dbg).txt -endif +dump : $(dbg).txt endif ifdef STATIC @@ -310,7 +308,9 @@ LD:=$(CC) CC:=$(CC) $(CFLAGS) NASM:=$(NASM) $(NASMOPTS) -f $(nasm_format) GZIP:=$(GZIP) $(GZIP_OPTS) +ifdef UPX UPX:=$(UPX) $(UPX_OPTS) +endif WINDRES:=$(WINDRES) $(WINDRESFLAGS)\ $(debug_opts) --include-dir=win32 -O coff @@ -321,11 +321,14 @@ WINDRES:=$(WINDRES) $(WINDRESFLAGS)\ # prerequisites .SECONDEXPANSION : +# 'UPX' is also recognized in the enviornment by upx +unexport UPX + # executable stripped of debugging symbols $(exe) : $(dbg) | $$(@D)/ $(.)$(OBJCOPY) --strip-debug $< $@ $(.)-$(OBJCOPY) --add-gnu-debuglink=$< $@ -ifndef NOUPX +ifdef UPX $(call Echo,Compressing final executable...) $(.)-$(UPX) $@ endif From c142b3241ddb8f1ea9b5090d20dffa43a17129ab Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 16 Jun 2021 15:48:16 -0700 Subject: [PATCH 518/644] Makefile: alert full path of final executable With added textual contrast. --- src/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index 6ec009044..6d2d68477 100644 --- a/src/Makefile +++ b/src/Makefile @@ -236,7 +236,8 @@ DBGNAME?=$(EXENAME).debug exe:=$(bin)/$(EXENAME) dbg:=$(bin)/$(DBGNAME) -build_done=Build is done, please look for $( Date: Wed, 16 Jun 2021 15:57:08 -0700 Subject: [PATCH 519/644] Add a proxy Makefile at top level --- Makefile | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 Makefile diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..7ee12d837 --- /dev/null +++ b/Makefile @@ -0,0 +1,8 @@ +ifdef SILENT +MAKEFLAGS+=--no-print-directory +endif + +all : + +% :: + @$(MAKE) -C src $(MAKECMDGOALS) From b04c79d8a7ba4ae8f888ab94d394b6714699e107 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 16 Jun 2021 16:58:47 -0700 Subject: [PATCH 520/644] Say 'at' --- src/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index 6d2d68477..18ab524b8 100644 --- a/src/Makefile +++ b/src/Makefile @@ -237,7 +237,7 @@ exe:=$(bin)/$(EXENAME) dbg:=$(bin)/$(DBGNAME) build_done==== Build is done, look for \ - $( Date: Thu, 17 Jun 2021 13:23:27 +0200 Subject: [PATCH 521/644] Add flag to line slopes for copying their slopes to the other side. --- extras/conf/SRB2-22.cfg | 16 ++++++++++++++++ src/p_setup.c | 6 ++++++ src/p_slopes.c | 3 +++ 3 files changed, 25 insertions(+) diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg index 5a464eb5d..a9027f14a 100644 --- a/extras/conf/SRB2-22.cfg +++ b/extras/conf/SRB2-22.cfg @@ -2950,8 +2950,10 @@ linedeftypes prefix = "(700)"; flags2048text = "[11] No physics"; flags4096text = "[12] Dynamic"; + flags32768text = "[15] Copy to other side"; slope = "regular"; slopeargs = 1; + copyslopeargs = 1; } 701 @@ -2960,8 +2962,10 @@ linedeftypes prefix = "(701)"; flags2048text = "[11] No physics"; flags4096text = "[12] Dynamic"; + flags32768text = "[15] Copy to other side"; slope = "regular"; slopeargs = 2; + copyslopeargs = 4; } 702 @@ -2970,8 +2974,10 @@ linedeftypes prefix = "(702)"; flags2048text = "[11] No physics"; flags4096text = "[12] Dynamic"; + flags32768text = "[15] Copy to other side"; slope = "regular"; slopeargs = 3; + copyslopeargs = 5; } 703 @@ -2980,8 +2986,10 @@ linedeftypes prefix = "(703)"; flags2048text = "[11] No physics"; flags4096text = "[12] Dynamic"; + flags32768text = "[15] Copy to other side"; slope = "regular"; slopeargs = 9; + copyslopeargs = 8; } 704 @@ -3012,8 +3020,10 @@ linedeftypes prefix = "(710)"; flags2048text = "[11] No physics"; flags4096text = "[12] Dynamic"; + flags32768text = "[15] Copy to other side"; slope = "regular"; slopeargs = 4; + copyslopeargs = 2; } 711 @@ -3022,8 +3032,10 @@ linedeftypes prefix = "(711)"; flags2048text = "[11] No physics"; flags4096text = "[12] Dynamic"; + flags32768text = "[15] Copy to other side"; slope = "regular"; slopeargs = 8; + copyslopeargs = 8; } 712 @@ -3032,8 +3044,10 @@ linedeftypes prefix = "(712)"; flags2048text = "[11] No physics"; flags4096text = "[12] Dynamic"; + flags32768text = "[15] Copy to other side"; slope = "regular"; slopeargs = 12; + copyslopeargs = 10; } 713 @@ -3042,8 +3056,10 @@ linedeftypes prefix = "(713)"; flags2048text = "[11] No physics"; flags4096text = "[12] Dynamic"; + flags32768text = "[15] Copy to other side"; slope = "regular"; slopeargs = 6; + copyslopeargs = 6; } 714 diff --git a/src/p_setup.c b/src/p_setup.c index 51d2f474d..8d2ba4b01 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3154,6 +3154,12 @@ static void P_ConvertBinaryMap(void) if (lines[i].flags & ML_NONET) lines[i].args[2] |= TMSL_DYNAMIC; + if (lines[i].flags & ML_TFERLINE) + { + lines[i].args[4] |= backfloor ? TMSC_BACKTOFRONTFLOOR : (frontfloor ? TMSC_FRONTTOBACKFLOOR : 0); + lines[i].args[4] |= backceil ? TMSC_BACKTOFRONTCEILING : (frontceil ? TMSC_FRONTTOBACKCEILING : 0); + } + lines[i].special = 700; break; } diff --git a/src/p_slopes.c b/src/p_slopes.c index 4e93e4a45..e99ecc64c 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -664,6 +664,9 @@ void P_SpawnSlopes(const boolean fromsave) { for (i = 0; i < numlines; i++) switch (lines[i].special) { + case 700: + if (lines[i].flags & ML_TFERLINE) P_CopySectorSlope(&lines[i]); + break; case 720: P_CopySectorSlope(&lines[i]); default: From e46afda89620a85fbfcf47afeaac5b436a4e587c Mon Sep 17 00:00:00 2001 From: Radicalicious Date: Fri, 18 Jun 2021 01:04:49 -0400 Subject: [PATCH 522/644] Hopefully fix ghosts --- src/g_demo.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/g_demo.c b/src/g_demo.c index 9d3b86015..1367c87b9 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -784,6 +784,18 @@ void G_GhostTicker(void) mobj = P_SpawnGhostMobj(g->mo); // does a large portion of the work for us mobj->frame = (mobj->frame & ~FF_FRAMEMASK)|tr_trans60<mo, 0, 0, g->mo->scale * 24, type); + mobj->angle = g->mo->angle + ANGLE_90; + mobj->fuse = 7; + mobj->scale = FRACUNIT / 3; + mobj->destscale = 10*FRACUNIT; + mobj->colorized = true; + mobj->color = g->mo->color; + mobj->momx = -g->mo->momx / 2; + mobj->momy = -g->mo->momy / 2; + } else { mobj = P_SpawnMobjFromMobj(g->mo, 0, 0, -FixedDiv(FixedMul(g->mo->info->height, g->mo->scale) - g->mo->height,3*FRACUNIT), MT_THOK); @@ -1074,6 +1086,18 @@ void G_ReadMetalTic(mobj_t *metal) { mobj = P_SpawnGhostMobj(metal); // does a large portion of the work for us } + else if (type == MT_THOKEFFECT) + { + mobj = P_SpawnMobjFromMobj(metal, 0, 0, metal->scale * 24, type); + mobj->angle = metal->angle + ANGLE_90; + mobj->fuse = 7; + mobj->scale = FRACUNIT / 3; + mobj->destscale = 10*FRACUNIT; + mobj->colorized = true; + mobj->color = metal->color; + mobj->momx = -metal->momx / 2; + mobj->momy = -metal->momy / 2; + } else { mobj = P_SpawnMobjFromMobj(metal, 0, 0, -FixedDiv(FixedMul(metal->info->height, metal->scale) - metal->height,3*FRACUNIT), MT_THOK); From 63d217b689ee4d39fc906a77e5b93b3557898fca Mon Sep 17 00:00:00 2001 From: Radicalicious Date: Fri, 18 Jun 2021 05:06:52 +0000 Subject: [PATCH 523/644] Revert "Hopefully fix ghosts" This reverts commit e46afda89620a85fbfcf47afeaac5b436a4e587c --- src/g_demo.c | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/src/g_demo.c b/src/g_demo.c index 1367c87b9..9d3b86015 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -784,18 +784,6 @@ void G_GhostTicker(void) mobj = P_SpawnGhostMobj(g->mo); // does a large portion of the work for us mobj->frame = (mobj->frame & ~FF_FRAMEMASK)|tr_trans60<mo, 0, 0, g->mo->scale * 24, type); - mobj->angle = g->mo->angle + ANGLE_90; - mobj->fuse = 7; - mobj->scale = FRACUNIT / 3; - mobj->destscale = 10*FRACUNIT; - mobj->colorized = true; - mobj->color = g->mo->color; - mobj->momx = -g->mo->momx / 2; - mobj->momy = -g->mo->momy / 2; - } else { mobj = P_SpawnMobjFromMobj(g->mo, 0, 0, -FixedDiv(FixedMul(g->mo->info->height, g->mo->scale) - g->mo->height,3*FRACUNIT), MT_THOK); @@ -1086,18 +1074,6 @@ void G_ReadMetalTic(mobj_t *metal) { mobj = P_SpawnGhostMobj(metal); // does a large portion of the work for us } - else if (type == MT_THOKEFFECT) - { - mobj = P_SpawnMobjFromMobj(metal, 0, 0, metal->scale * 24, type); - mobj->angle = metal->angle + ANGLE_90; - mobj->fuse = 7; - mobj->scale = FRACUNIT / 3; - mobj->destscale = 10*FRACUNIT; - mobj->colorized = true; - mobj->color = metal->color; - mobj->momx = -metal->momx / 2; - mobj->momy = -metal->momy / 2; - } else { mobj = P_SpawnMobjFromMobj(metal, 0, 0, -FixedDiv(FixedMul(metal->info->height, metal->scale) - metal->height,3*FRACUNIT), MT_THOK); From c1aca51fc3815de8262381cd2235b1b4e1349841 Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 19 Jun 2021 18:32:56 -0700 Subject: [PATCH 524/644] Fix basic warnings --- src/lua_inputlib.c | 2 +- src/sdl/i_video.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lua_inputlib.c b/src/lua_inputlib.c index 217202222..71eb1033f 100644 --- a/src/lua_inputlib.c +++ b/src/lua_inputlib.c @@ -117,7 +117,7 @@ static int lib_setMouseGrab(lua_State *L) return 0; } -static boolean lib_getCursorPosition(lua_State *L) +static int lib_getCursorPosition(lua_State *L) { int x, y; I_GetCursorPosition(&x, &y); diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index c387e5a18..234585cf3 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -407,7 +407,7 @@ void I_UpdateMouseGrab(void) boolean I_GetMouseGrab(void) { - return SDL_GetWindowGrab(window); + return (boolean)SDL_GetWindowGrab(window); } void I_SetMouseGrab(boolean grab) From 2d7a8c3c571bcc5335437e9db074c75af00408ce Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 21 Jun 2021 14:47:42 -0700 Subject: [PATCH 525/644] Makefile: use shell commands to read in Sourcefile File function is not supported < Make 4.2. --- src/Makefile | 11 ++++++----- src/Makefile.d/platform.mk | 2 ++ src/Makefile.d/util.mk | 3 ++- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/Makefile b/src/Makefile index 18ab524b8..7104a91cf 100644 --- a/src/Makefile +++ b/src/Makefile @@ -176,11 +176,7 @@ include Makefile.d/detect.mk # make would try to remove the implicitly made directories .PRECIOUS : %/ comptime.c -# very sophisticated dependency -sources:=\ - $(call List,Sourcefile)\ - $(call List,blua/Sourcefile)\ - +sources:= makedir:=../make # -DCOMPVERSION: flag to use comptime.h @@ -204,6 +200,11 @@ endif depdir:=$(makedir)/deps objdir:=$(makedir)/objs +# very sophisticated dependency +sources+=\ + $(call List,Sourcefile)\ + $(call List,blua/Sourcefile)\ + depends:=$(basename $(filter %.c %.s,$(sources))) objects:=$(basename $(filter %.c %.s %.nas,$(sources))) diff --git a/src/Makefile.d/platform.mk b/src/Makefile.d/platform.mk index 531d073e9..fad4be191 100644 --- a/src/Makefile.d/platform.mk +++ b/src/Makefile.d/platform.mk @@ -7,9 +7,11 @@ PKG_CONFIG?=pkg-config ifdef WINDOWSHELL rmrf=-2>NUL DEL /S /Q mkdir=-2>NUL MD +cat=TYPE else rmrf=rm -rf mkdir=mkdir -p +cat=cat endif ifdef LINUX64 diff --git a/src/Makefile.d/util.mk b/src/Makefile.d/util.mk index e76e32422..bda68df13 100644 --- a/src/Makefile.d/util.mk +++ b/src/Makefile.d/util.mk @@ -10,7 +10,8 @@ Wildvar=$(foreach v,$(filter $(1),$(.VARIABLES)),$($(v))) # Read a list of words from file and prepend each with the # directory of the file. -List=$(addprefix $(dir $(1)),$(file < $(1))) +_cat=$(shell $(cat) $(call Windows_path,$(1))) +List=$(addprefix $(dir $(1)),$(call _cat,$(1))) # Convert path separators to backslash on Windows. Windows_path=$(if $(WINDOWSHELL),$(subst /,\,$(1)),$(1)) From d5146945a69ebf30e6fc1fbb64558e456e0b7459 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 21 Jun 2021 16:10:13 -0700 Subject: [PATCH 526/644] Makefile: don't automatically set WINDOWSHELL unless PATH matches Windows norms This is for MSYS2, which requires unix shell commands. --- src/Makefile.d/detect.mk | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Makefile.d/detect.mk b/src/Makefile.d/detect.mk index f576bcf78..89c193a32 100644 --- a/src/Makefile.d/detect.mk +++ b/src/Makefile.d/detect.mk @@ -29,7 +29,10 @@ $(call Print,$(_m)) # go for a 32-bit sdl mingw exe by default MINGW:=1 +# cmd.exe uses native Windows semicolon delimited PATH +ifneq (,$(findstring ;,$(PATH))) WINDOWSHELL:=1 +endif else # if you on the *nix From 5f4d7e3c5b013afe03ae2a441c82ad79bae7c66c Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 22 Jun 2021 15:14:42 -0700 Subject: [PATCH 527/644] Makefile: fail if old build directories exist After a checkout from before revision, old directories such as bin/Linux64 only remain if untracked files exist within. This may be confusing to the user. They may even use an outdated executable if it is one of those untracked files. --- src/Makefile | 6 +++++- src/Makefile.d/old.mk | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 src/Makefile.d/old.mk diff --git a/src/Makefile b/src/Makefile index 7104a91cf..61a4c5e34 100644 --- a/src/Makefile +++ b/src/Makefile @@ -132,6 +132,10 @@ goals:=$(or $(MAKECMDGOALS),all) cleanonly:=$(filter $(clean_targets),$(goals)) destructive:=$(filter-out info,$(cleanonly)) +ifndef cleanonly +include Makefile.d/old.mk +endif + include Makefile.d/util.mk ifdef PREFIX @@ -399,7 +403,7 @@ clean : $(call _rm,$(exe) $(dbg) $(dbg).txt $(objects)) distclean : - $(call _rm,../bin ../objs ../deps comptime.h) + $(call _rm,../bin ../objs ../deps ../make comptime.h) info: ifdef WINDOWSHELL diff --git a/src/Makefile.d/old.mk b/src/Makefile.d/old.mk new file mode 100644 index 000000000..e5890eedd --- /dev/null +++ b/src/Makefile.d/old.mk @@ -0,0 +1,16 @@ +# +# Warn about old build directories and offer to purge. +# + +_old:=$(wildcard $(addprefix ../bin/,FreeBSD Linux \ + Linux64 Mingw Mingw64 SDL dummy) ../objs ../deps) + +ifdef _old +$(foreach v,$(_old),$(info $(abspath $(v)))) +$(info ) +$(info These directories are no longer\ + required and should be removed.) +$(info You may remove them manually or\ + by using 'make distclean') +$(error ) +endif From c3ad5de912fccfdd64c510f5684883afceaa7d36 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 22 Jun 2021 15:47:48 -0700 Subject: [PATCH 528/644] Makefile: let variables be defined on Make line If a variable is defined as in 'make CC=gcc-10', then that definition overrides anything other definition in the Makefile. --- src/Makefile | 51 ++++++++++++++++++++++++++------------------------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/src/Makefile b/src/Makefile index 61a4c5e34..90776b812 100644 --- a/src/Makefile +++ b/src/Makefile @@ -145,7 +145,7 @@ endif OBJDUMP_OPTS?=--wide --source --line-numbers OBJCOPY:=$(call Prefix,objcopy) -OBJDUMP:=$(call Prefix,objdump) $(OBJDUMP_OPTS) +OBJDUMP:=$(call Prefix,objdump) WINDRES:=$(call Prefix,windres) ifdef YASM @@ -273,16 +273,18 @@ opts+=$(debug_opts) opts+=$(foreach v,$(passthru_opts),$(if $($(v)),-D$(v))) -CFLAGS:=$(opts) $(WFLAGS) $(CPPFLAGS) $(CFLAGS) -LDFLAGS:=$(libs) $(LDFLAGS) -ASFLAGS+=-x assembler-with-cpp +opts+=$(WFLAGS) $(CPPFLAGS) $(CFLAGS) +libs+=$(LDFLAGS) +asflags:=$(ASFLAGS) -x assembler-with-cpp + +cc=$(CC) ifdef DISTCC -CC:=distcc $(CC) +cc=distcc $(CC) endif ifdef CCACHE -CC:=ccache $(CC) +cc=ccache $(CC) endif ifndef SILENT @@ -293,11 +295,11 @@ ifndef destructive $(shell $(CC) -v) define flags = -CC ........ $(CC) +CC ........ $(cc) -CFLAGS .... $(CFLAGS) +CFLAGS .... $(opts) -LDFLAGS ... $(LDFLAGS) +LDFLAGS ... $(libs) endef $(info $(flags)) @@ -311,13 +313,12 @@ endif endif LD:=$(CC) -CC:=$(CC) $(CFLAGS) -NASM:=$(NASM) $(NASMOPTS) -f $(nasm_format) -GZIP:=$(GZIP) $(GZIP_OPTS) +cc:=$(cc) $(opts) +nasm=$(NASM) $(NASMOPTS) -f $(nasm_format) ifdef UPX -UPX:=$(UPX) $(UPX_OPTS) +upx=$(UPX) $(UPX_OPTS) endif -WINDRES:=$(WINDRES) $(WINDRESFLAGS)\ +windres=$(WINDRES) $(WINDRESFLAGS)\ $(debug_opts) --include-dir=win32 -O coff %/ : @@ -327,7 +328,7 @@ WINDRES:=$(WINDRES) $(WINDRESFLAGS)\ # prerequisites .SECONDEXPANSION : -# 'UPX' is also recognized in the enviornment by upx +# 'UPX' is also recognized in the environment by upx unexport UPX # executable stripped of debugging symbols @@ -336,19 +337,19 @@ $(exe) : $(dbg) | $$(@D)/ $(.)-$(OBJCOPY) --add-gnu-debuglink=$< $@ ifdef UPX $(call Echo,Compressing final executable...) - $(.)-$(UPX) $@ + $(.)-$(upx) $@ endif # original executable with debugging symbols $(dbg) : $(objects) | $$(@D)/ $(call Echo,Linking $(@F)...) - $(.)$(LD) -o $@ $^ $(LDFLAGS) + $(.)$(LD) -o $@ $^ $(libs) # disassembly of executable $(dbg).txt : $(dbg) $(call Echo,Dumping debugging info...) - $(.)$(OBJDUMP) $< > $@ - $(.)$(GZIP) $@ + $(.)$(OBJDUMP) $(OBJDUMP_OPTS) $< > $@ + $(.)$(GZIP) $(GZIP_OPTS) $@ # '::' means run unconditionally # this really updates comptime.h @@ -373,11 +374,11 @@ ifdef Echo_name @printf '%-20.20s\r' $$< endif endif - $(.)$(CC) -MM -MF $$@ -MT $(objdir)/$$(*F).o $(2) $$< + $(.)$(cc) -MM -MF $$@ -MT $(objdir)/$$(*F).o $(2) $$< endef $(eval $(call _recipe,c)) -$(eval $(call _recipe,s,$(ASFLAGS))) +$(eval $(call _recipe,s,$(asflags))) # compiling recipe template # 1: target file suffix @@ -389,10 +390,10 @@ $(objdir)/%.$(1) : %.$(2) | $$$$(@D)/ $(.)$(3) endef -$(eval $(call _recipe,o,c,$(CC) -c -o $$@ $$<)) -$(eval $(call _recipe,o,nas,$(NASM) -o $$@ $$<)) -$(eval $(call _recipe,o,s,$(CC) $(ASFLAGS) -c -o $$@ $$<)) -$(eval $(call _recipe,res,rc,$(WINDRES) -i $$< -o $$@)) +$(eval $(call _recipe,o,c,$(cc) -c -o $$@ $$<)) +$(eval $(call _recipe,o,nas,$(nasm) -o $$@ $$<)) +$(eval $(call _recipe,o,s,$(cc) $(asflags) -c -o $$@ $$<)) +$(eval $(call _recipe,res,rc,$(windres) -i $$< -o $$@)) _rm=$(.)$(rmrf) $(call Windows_path,$(1)) From ed85e994a46ace07cf022b38a9abac1698a8667e Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 22 Jun 2021 15:49:59 -0700 Subject: [PATCH 529/644] Remove misplaced parentheses --- src/Makefile.d/detect.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile.d/detect.mk b/src/Makefile.d/detect.mk index 89c193a32..3edf0dad4 100644 --- a/src/Makefile.d/detect.mk +++ b/src/Makefile.d/detect.mk @@ -94,7 +94,7 @@ ifeq (,$(filter $(v),$(gcc_versions))) define line = Your compiler version, GCC $(version), \ is not supported by the Makefile. -The Makefile will assume GCC $(latest_gcc_version).)) +The Makefile will assume GCC $(latest_gcc_version). endef $(call Print,$(line)) GCC$(subst .,,$(latest_gcc_version)):=1 From 22272732f0e45d9cfa637880f8eb36b00bf838b3 Mon Sep 17 00:00:00 2001 From: flarn2006 Date: Sat, 26 Jun 2021 14:59:56 -0400 Subject: [PATCH 530/644] Exclude MT_BOXSPARKLE from Mario blocks --- src/p_floor.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/p_floor.c b/src/p_floor.c index d81a022e5..e98670f17 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -1062,6 +1062,7 @@ static mobj_t *SearchMarioNode(msecnode_t *node) case MT_HOOPCOLLIDE: case MT_NIGHTSCORE: case MT_NAMECHECK: // DEFINITELY not this, because it is client-side. + case MT_BOXSPARKLE: continue; default: break; From a5cd764772760583d55d4d116b3cbfdf09cafeaa Mon Sep 17 00:00:00 2001 From: flarn2006 Date: Sat, 26 Jun 2021 15:42:41 -0400 Subject: [PATCH 531/644] move MT_BOXSPARKLE in the list --- src/p_floor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_floor.c b/src/p_floor.c index e98670f17..263644f70 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -1042,6 +1042,7 @@ static mobj_t *SearchMarioNode(msecnode_t *node) case MT_THUNDERCOIN_ORB: case MT_IVSP: case MT_SUPERSPARK: + case MT_BOXSPARKLE: case MT_RAIN: case MT_SNOWFLAKE: case MT_SPLISH: @@ -1062,7 +1063,6 @@ static mobj_t *SearchMarioNode(msecnode_t *node) case MT_HOOPCOLLIDE: case MT_NIGHTSCORE: case MT_NAMECHECK: // DEFINITELY not this, because it is client-side. - case MT_BOXSPARKLE: continue; default: break; From 90763d42e1352efb03a81fee3c53de7fcd9d0d3e Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 29 Jun 2021 01:49:09 -0700 Subject: [PATCH 532/644] Shuffle LUA_HookKey --- src/lua_hook.h | 2 +- src/lua_hooklib.c | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/lua_hook.h b/src/lua_hook.h index e3af951f5..223b83c61 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -107,6 +107,7 @@ void LUA_HookInt(INT32 integer, int hook); void LUA_HookBool(boolean value, int hook); int LUA_HookPlayer(player_t *, int hook); int LUA_HookTiccmd(player_t *, ticcmd_t *, int hook); +int LUA_HookKey(INT32 keycode, int hook); // Hooks for key events void LUA_HookThinkFrame(void); int LUA_HookMobjLineCollide(mobj_t *, line_t *); @@ -130,4 +131,3 @@ int LUA_HookPlayerCmd(player_t *, ticcmd_t *); int LUA_HookMusicChange(const char *oldname, struct MusicChange *); fixed_t LUA_HookPlayerHeight(player_t *player); int LUA_HookPlayerCanEnterSpinGaps(player_t *player); -int LUA_HookKey(INT32 keycode, int hooktype); // Hooks for key events diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 39aa5ea18..6c709bf48 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -588,6 +588,17 @@ int LUA_HookTiccmd(player_t *player, ticcmd_t *cmd, int hook_type) return hook.status; } +int LUA_HookKey(INT32 keycode, int hook_type) +{ + Hook_State hook; + if (prepare_hook(&hook, false, hook_type)) + { + lua_pushinteger(gL, keycode); + call_hooks(&hook, 1, 0, res_true); + } + return hook.status; +} + /* ========================================================================= SPECIALIZED HOOKS ========================================================================= */ @@ -1088,14 +1099,3 @@ int LUA_HookPlayerCanEnterSpinGaps(player_t *player) } return hook.status; } - -int LUA_HookKey(INT32 keycode, int hooktype) -{ - Hook_State hook; - if (prepare_hook(&hook, 0, hooktype)) - { - lua_pushinteger(gL, keycode); - call_hooks(&hook, 1, 0, res_true); - } - return hook.status; -} From 7d01bd38d8dc7fc6744d20c3376e38ccdf480d9a Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 29 Jun 2021 01:49:53 -0700 Subject: [PATCH 533/644] Fix return value of Lua key hooks not being used --- src/lua_hooklib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 6c709bf48..d1b0d3bdd 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -594,7 +594,7 @@ int LUA_HookKey(INT32 keycode, int hook_type) if (prepare_hook(&hook, false, hook_type)) { lua_pushinteger(gL, keycode); - call_hooks(&hook, 1, 0, res_true); + call_hooks(&hook, 1, 1, res_true); } return hook.status; } From c1ecfa306f6a0b168d4f6cbc3224ebebd4deec51 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 29 Jun 2021 13:58:38 -0700 Subject: [PATCH 534/644] Makefile: 'dep' not 'deps' --- src/Makefile.d/old.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile.d/old.mk b/src/Makefile.d/old.mk index e5890eedd..ec9b6d776 100644 --- a/src/Makefile.d/old.mk +++ b/src/Makefile.d/old.mk @@ -3,7 +3,7 @@ # _old:=$(wildcard $(addprefix ../bin/,FreeBSD Linux \ - Linux64 Mingw Mingw64 SDL dummy) ../objs ../deps) + Linux64 Mingw Mingw64 SDL dummy) ../objs ../dep) ifdef _old $(foreach v,$(_old),$(info $(abspath $(v)))) From c3fa9bea0fd6a426e448d4ecb8240a75593ecd50 Mon Sep 17 00:00:00 2001 From: CobaltBW Date: Tue, 29 Jun 2021 13:30:10 -0700 Subject: [PATCH 535/644] ri# mified: src/tazx# mofied: src/tazx# modified: src/tazx# modified: src/tazxc --- src/g_game.c | 5 +---- src/r_skins.c | 1 - 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 83531bb35..9f2d05ff0 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2317,16 +2317,13 @@ void G_Ticker(boolean run) P_ForceLocalAngle(&players[i], players[i].angleturn << 16); else players[i].cmd.angleturn = players[i].angleturn; - players[i].angleturn += players[i].cmd.angleturn - players[i].oldrelangleturn; - players[i].oldrelangleturn = players[i].cmd.angleturn; if (P_ControlStyle(&players[i]) == CS_LMAOGALOG) P_ForceLocalAngle(&players[i], players[i].angleturn << 16); else players[i].cmd.angleturn = players[i].angleturn; players[i].cmd.angleturn &= ~TICCMD_RECEIVED; - - // Use the leveltime sent in the player's ticcmd to determine control lag + // Use the leveltime sent in the player's ticcmd to determine control lag players[i].cmd.latency = min(((leveltime & 0xFF) - players[i].cmd.latency) & 0xFF, MAXPREDICTTICS-1); } else // Less work is required if we're building a bot ticcmd. diff --git a/src/r_skins.c b/src/r_skins.c index f67f2afd4..c734b6001 100644 --- a/src/r_skins.c +++ b/src/r_skins.c @@ -286,7 +286,6 @@ boolean R_SkinUsable(INT32 playernum, INT32 skinnum) // We want to check our global unlockables. return (unlockables[unlockID].unlocked); } ->>>>>>> src/r_skins.c } // returns true if the skin name is found (loaded from pwad) From 6c03f9b5b3590e01773f05bc1c31cc67a2d88fc2 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 29 Jun 2021 14:42:40 -0700 Subject: [PATCH 536/644] fuck --- src/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index 90776b812..8bb7b54ef 100644 --- a/src/Makefile +++ b/src/Makefile @@ -404,7 +404,7 @@ clean : $(call _rm,$(exe) $(dbg) $(dbg).txt $(objects)) distclean : - $(call _rm,../bin ../objs ../deps ../make comptime.h) + $(call _rm,../bin ../objs ../dep ../make comptime.h) info: ifdef WINDOWSHELL From abdf5c101cbe80657f210c0b90800e2c4c6f0c05 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 29 Jun 2021 16:22:46 -0700 Subject: [PATCH 537/644] Makefile: report SHELL --- src/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Makefile b/src/Makefile index 8bb7b54ef..ce0e84987 100644 --- a/src/Makefile +++ b/src/Makefile @@ -295,6 +295,8 @@ ifndef destructive $(shell $(CC) -v) define flags = +SHELL ..... $(SHELL) + CC ........ $(cc) CFLAGS .... $(opts) From 22ab611daa17bd23225f3afeeba39147c0d0fe17 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 29 Jun 2021 16:23:27 -0700 Subject: [PATCH 538/644] Makefile: do not automatically set WINDOWSHELL According to this answer-- https://stackoverflow.com/a/45952425 --Make will always prefer a unix shell, even on Windows, if one can be found in Path. So we can't check PATH to determine if it's a Windows shell... this is just too much bother. --- src/Makefile.d/detect.mk | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Makefile.d/detect.mk b/src/Makefile.d/detect.mk index 3edf0dad4..9c8a0a227 100644 --- a/src/Makefile.d/detect.mk +++ b/src/Makefile.d/detect.mk @@ -29,10 +29,6 @@ $(call Print,$(_m)) # go for a 32-bit sdl mingw exe by default MINGW:=1 -# cmd.exe uses native Windows semicolon delimited PATH -ifneq (,$(findstring ;,$(PATH))) -WINDOWSHELL:=1 -endif else # if you on the *nix From f79e0ee540564fcec5da7c0dc4006906492a7f30 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 29 Jun 2021 14:33:55 -0700 Subject: [PATCH 539/644] Appveyor: remove 64-bit target --- appveyor.yml | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index d5f76c344..a74d3c415 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -4,12 +4,9 @@ os: MinGW environment: CC: ccache CCACHE_CC: i686-w64-mingw32-gcc - CCACHE_CC_64: x86_64-w64-mingw32-gcc WINDRES: windres # c:\mingw-w64 i686 has gcc 6.3.0, so use c:\msys64 7.3.0 instead MINGW_SDK: c:\msys64\mingw32 - # c:\msys64 x86_64 has gcc 8.2.0, so use c:\mingw-w64 7.3.0 instead - MINGW_SDK_64: C:\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64 CFLAGS: -Wall -W -Werror -Wno-error=implicit-fallthrough -Wimplicit-fallthrough=3 -Wno-tautological-compare -Wno-error=suggest-attribute=noreturn NASM_ZIP: nasm-2.12.01 NASM_URL: http://www.nasm.us/pub/nasm/releasebuilds/2.12.01/win64/nasm-2.12.01-win64.zip @@ -53,11 +50,6 @@ cache: - C:\Users\appveyor\srb2_cache install: -- if [%CONFIGURATION%] == [SDL64] ( set "X86_64=1" ) -- if [%CONFIGURATION%] == [SDL64] ( set "CONFIGURATION=SDL" ) -- if [%X86_64%] == [1] ( set "MINGW_SDK=%MINGW_SDK_64%" ) -- if [%X86_64%] == [1] ( set "CCACHE_CC=%CCACHE_CC_64%" ) - - if not exist "%NASM_ZIP%.zip" appveyor DownloadFile "%NASM_URL%" -FileName "%NASM_ZIP%.zip" - 7z x -y "%NASM_ZIP%.zip" -o%TMP% >null - robocopy /S /xx /ns /nc /nfl /ndl /np /njh /njs "%TMP%\%NASM_ZIP%" "%MINGW_SDK%\bin" nasm.exe || exit 0 @@ -72,13 +64,12 @@ install: configuration: - SDL -- SDL64 before_build: - set "Path=%MINGW_SDK%\bin;%Path%" -- if [%X86_64%] == [1] ( x86_64-w64-mingw32-gcc --version ) else ( i686-w64-mingw32-gcc --version ) +- i686-w64-mingw32-gcc --version - mingw32-make --version -- if not [%X86_64%] == [1] ( nasm -v ) +- nasm -v - if not [%NOUPX%] == [1] ( upx -V ) - ccache -V - ccache -s @@ -91,7 +82,7 @@ before_build: - if not [%APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME%] == [] ( if not [%APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME%] == [%APPVEYOR_REPO_NAME%] ( for /f "delims=/" %%a in ("%APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME%") do set "REPO=%%a-%APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH%" ) ) - set "EXENAME=EXENAME=srb2win-%REPO%-%GITSHORT%.exe" - set "SRB2_MFLAGS=-C src WARNINGMODE=1 CCACHE=1 NOOBJDUMP=1 %NOUPX% %EXENAME%" -- if [%X86_64%] == [1] ( set "MINGW_FLAGS=MINGW64=1 X86_64=1 GCC81=1" ) else ( set "MINGW_FLAGS=MINGW=1 GCC91=1" ) +- set "MINGW_FLAGS=MINGW=1 GCC91=1" - set "SRB2_MFLAGS=%SRB2_MFLAGS% %MINGW_FLAGS% %CONFIGURATION%=1" build_script: @@ -99,7 +90,6 @@ build_script: - cmd: mingw32-make.exe %SRB2_MFLAGS% ERRORMODE=1 -k after_build: -- if [%X86_64%] == [1] ( set "CONFIGURATION=%CONFIGURATION%64" ) - ccache -s - set BUILD_ARCHIVE=%REPO%-%GITSHORT%-%CONFIGURATION%.7z - set BUILDSARCHIVE=%REPO%-%CONFIGURATION%.7z @@ -134,3 +124,4 @@ test: off on_finish: #- cmd: echo xfreerdp /u:appveyor /cert-ignore +clipboard /v:: #- ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) +# vim: et ts=1 From faee657572f23cd6f8b68c077873e01c4278414e Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 29 Jun 2021 14:55:06 -0700 Subject: [PATCH 540/644] Appveyor: update for new Makefile --- appveyor.yml | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index a74d3c415..26a1e2a9b 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -2,8 +2,7 @@ version: 2.2.9.{branch}-{build} os: MinGW environment: - CC: ccache - CCACHE_CC: i686-w64-mingw32-gcc + CC: i686-w64-mingw32-gcc WINDRES: windres # c:\mingw-w64 i686 has gcc 6.3.0, so use c:\msys64 7.3.0 instead MINGW_SDK: c:\msys64\mingw32 @@ -16,8 +15,6 @@ environment: CCACHE_URL: http://alam.srb2.org/ccache.exe CCACHE_COMPRESS: true CCACHE_DIR: C:\Users\appveyor\.ccache - # Disable UPX by default. The user can override this in their Appveyor project settings - NOUPX: 1 ############################## # DEPLOYER VARIABLES # DPL_ENABLED=1 builds installers for branch names starting with `deployer`. @@ -67,23 +64,18 @@ configuration: before_build: - set "Path=%MINGW_SDK%\bin;%Path%" -- i686-w64-mingw32-gcc --version - mingw32-make --version - nasm -v - if not [%NOUPX%] == [1] ( upx -V ) - ccache -V - ccache -s -- if [%NOUPX%] == [1] ( set "NOUPX=NOUPX=1" ) else ( set "NOUPX=" ) - if defined [%APPVEYOR_PULL_REQUEST_HEAD_COMMIT%] ( set "COMMIT=%APPVEYOR_PULL_REQUEST_HEAD_COMMIT%" ) else ( set "COMMIT=%APPVEYOR_REPO_COMMIT%" ) - cmd: git rev-parse --short %COMMIT%>%TMP%/gitshort.txt - cmd: set /P GITSHORT=<%TMP%/gitshort.txt # for pull requests, take the owner's name only, if this isn't the same repo of course - set "REPO=%APPVEYOR_REPO_BRANCH%" - if not [%APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME%] == [] ( if not [%APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME%] == [%APPVEYOR_REPO_NAME%] ( for /f "delims=/" %%a in ("%APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME%") do set "REPO=%%a-%APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH%" ) ) -- set "EXENAME=EXENAME=srb2win-%REPO%-%GITSHORT%.exe" -- set "SRB2_MFLAGS=-C src WARNINGMODE=1 CCACHE=1 NOOBJDUMP=1 %NOUPX% %EXENAME%" -- set "MINGW_FLAGS=MINGW=1 GCC91=1" -- set "SRB2_MFLAGS=%SRB2_MFLAGS% %MINGW_FLAGS% %CONFIGURATION%=1" +- set "SRB2_MFLAGS=-C src CCACHE=1 EXENAME=srb2win-%REPO%-%GITSHORT%.exe" build_script: - cmd: mingw32-make.exe %SRB2_MFLAGS% clean From 44b82dea58612e6f07830647e2b08555f54a7caa Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 29 Jun 2021 19:55:14 -0700 Subject: [PATCH 541/644] Appveyor: remove redundant CFLAGS Also changed -Wno-error=implicit-fallthrough to -Wno-implicit-fallthrough. For some reason Appveyor's version of GCC is triggering these warnings despite the comments, so just shut it up. --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 26a1e2a9b..962444a18 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -6,7 +6,7 @@ environment: WINDRES: windres # c:\mingw-w64 i686 has gcc 6.3.0, so use c:\msys64 7.3.0 instead MINGW_SDK: c:\msys64\mingw32 - CFLAGS: -Wall -W -Werror -Wno-error=implicit-fallthrough -Wimplicit-fallthrough=3 -Wno-tautological-compare -Wno-error=suggest-attribute=noreturn + CFLAGS: -Wno-implicit-fallthrough NASM_ZIP: nasm-2.12.01 NASM_URL: http://www.nasm.us/pub/nasm/releasebuilds/2.12.01/win64/nasm-2.12.01-win64.zip UPX_ZIP: upx391w From db919accd22350c087c1fd0e5122d8e490e2f171 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 29 Jun 2021 20:01:14 -0700 Subject: [PATCH 542/644] Appveyor: suppress real time file names --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 962444a18..b9f84f395 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -75,7 +75,7 @@ before_build: # for pull requests, take the owner's name only, if this isn't the same repo of course - set "REPO=%APPVEYOR_REPO_BRANCH%" - if not [%APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME%] == [] ( if not [%APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME%] == [%APPVEYOR_REPO_NAME%] ( for /f "delims=/" %%a in ("%APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME%") do set "REPO=%%a-%APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH%" ) ) -- set "SRB2_MFLAGS=-C src CCACHE=1 EXENAME=srb2win-%REPO%-%GITSHORT%.exe" +- set "SRB2_MFLAGS=-C src NOECHOFILENAMES=1 CCACHE=1 EXENAME=srb2win-%REPO%-%GITSHORT%.exe" build_script: - cmd: mingw32-make.exe %SRB2_MFLAGS% clean From dad361721fa3c1f572ba5d40ae5af0884258fb17 Mon Sep 17 00:00:00 2001 From: Shane Ellis Date: Wed, 30 Jun 2021 01:32:24 -0400 Subject: [PATCH 543/644] comment cleanup --- src/p_user.c | 27 ++++----------------------- 1 file changed, 4 insertions(+), 23 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index dadc23193..7ab7d8105 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -776,7 +776,7 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) { UINT8 oldmare, oldmarelap, oldmarebonuslap; - //! Bots can't be NiGHTSerized, silly!1 :P + // Bots can't be NiGHTSerized, silly!1 :P if (player->bot == BOT_2PAI || player->bot == BOT_2PHUMAN) return; @@ -1188,7 +1188,6 @@ void P_GivePlayerRings(player_t *player, INT32 num_rings) { if (!player) return; - //! if ((player->bot == BOT_2PAI || player->bot == BOT_2PHUMAN) && player->botleader) player = player->botleader; @@ -5965,23 +5964,6 @@ static void P_3dMovement(player_t *player) acceleration = 96 + (FixedDiv(player->speed, player->mo->scale)>>FRACBITS) * 40; topspeed = normalspd; } - //! Kill this! - /* else if (player->bot == BOT_2PAI || player->bot == BOT_2PHUMAN) - { // Bot steals player 1's stats - normalspd = FixedMul(players[consoleplayer].normalspeed, player->mo->scale); - thrustfactor = players[consoleplayer].thrustfactor; - acceleration = players[consoleplayer].accelstart + (FixedDiv(player->speed, player->mo->scale)>>FRACBITS) * players[consoleplayer].acceleration; - - if (player->powers[pw_tailsfly]) - topspeed = normalspd/2; - else if (player->mo->eflags & (MFE_UNDERWATER|MFE_GOOWATER)) - { - topspeed = normalspd/2; - acceleration = 2*acceleration/3; - } - else - topspeed = normalspd; - } */ else { if (player->powers[pw_super] || player->powers[pw_sneakers]) @@ -11488,7 +11470,7 @@ void P_PlayerThink(player_t *player) I_Error("p_playerthink: players[%s].mo == NULL", sizeu1(playeri)); #endif - //! Reset terrain blocked status for this frame + // Reset terrain blocked status for this frame player->blocked = false; // todo: Figure out what is actually causing these problems in the first place... @@ -11641,7 +11623,7 @@ void P_PlayerThink(player_t *player) INT32 i; for (i = 0; i < MAXPLAYERS; i++) - { //! + { if (!playeringame[i] || players[i].spectator || players[i].bot == BOT_2PAI || players[i].bot == BOT_2PHUMAN) continue; if (players[i].lives <= 0) @@ -11673,7 +11655,7 @@ void P_PlayerThink(player_t *player) INT32 i, total = 0, exiting = 0; for (i = 0; i < MAXPLAYERS; i++) - { //! + { if (!playeringame[i] || players[i].spectator || players[i].bot == BOT_2PAI || players[i].bot == BOT_2PHUMAN) continue; if (players[i].quittime > 30 * TICRATE) @@ -12614,7 +12596,6 @@ void P_PlayerAfterThink(player_t *player) player->mo->momy = tails->momy; player->mo->momz = tails->momz; } - //! if (G_CoopGametype() && tails->player && tails->player->bot != BOT_2PAI) { player->mo->angle = tails->angle; From ee765d1043893bb798cdd84cf22d3383812812e6 Mon Sep 17 00:00:00 2001 From: Shane Ellis Date: Wed, 30 Jun 2021 01:34:21 -0400 Subject: [PATCH 544/644] comment cleanup --- src/g_game.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g_game.c b/src/g_game.c index 0643350b6..6e900d026 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3005,7 +3005,7 @@ void G_DoReborn(INT32 playernum) // Make sure objectplace is OFF when you first start the level! OP_ResetObjectplace(); - //! Tailsbot + // Tailsbot if (player->bot == BOT_2PAI || player->bot == BOT_2PHUMAN) { // Bots respawn next to their master. mobj_t *oldmo = NULL; From 94441d6eee252c3ebc7cd438c32d3d15dbb3c012 Mon Sep 17 00:00:00 2001 From: Shane Ellis Date: Wed, 30 Jun 2021 01:36:28 -0400 Subject: [PATCH 545/644] comment cleanup --- src/b_bot.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/b_bot.c b/src/b_bot.c index c61e56f5f..cdd74fc07 100644 --- a/src/b_bot.c +++ b/src/b_bot.c @@ -25,8 +25,6 @@ void B_UpdateBotleader(player_t *player) fixed_t neardist = INT32_MAX; player_t *nearplayer = NULL; //Find new botleader - //if (!player->botleader) - //{ for (i = 0; i < MAXPLAYERS; i++) { if (players[i].bot || players[i].playerstate != PST_LIVE || players[i].spectator || !players[i].mo) @@ -46,7 +44,6 @@ void B_UpdateBotleader(player_t *player) } //Set botleader to best candidate (or null if none available) player->botleader = nearplayer; - //} } static inline void B_ResetAI(botmem_t *mem) @@ -102,7 +99,6 @@ static void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd) if (tails->player->powers[pw_carry] == CR_MACESPIN || tails->player->powers[pw_carry] == CR_GENERIC) { boolean isrelevant = (sonic->player->powers[pw_carry] == CR_MACESPIN || sonic->player->powers[pw_carry] == CR_GENERIC); - //dist = P_AproxDistance(tails->x-sonic->x, tails->y-sonic->y); //! This is totally redundant. if (sonic->player->cmd.buttons & BT_JUMP && (sonic->player->pflags & PF_JUMPED) && isrelevant) cmd->buttons |= BT_JUMP; if (isrelevant) @@ -402,8 +398,6 @@ void B_KeysToTiccmd(mobj_t *mo, ticcmd_t *cmd, boolean forward, boolean backward { player_t *player = mo->player; // don't try to do stuff if your sonic is in a minecart or something - //if (players[consoleplayer].powers[pw_carry] && players[consoleplayer].powers[pw_carry] != CR_PLAYER) - //!!! if (&player->botleader && player->botleader->powers[pw_carry] && player->botleader->powers[pw_carry] != CR_PLAYER) return; // Turn the virtual keypresses into ticcmd_t. @@ -576,7 +570,6 @@ void B_RespawnBot(INT32 playernum) player->powers[pw_spacetime] = sonic->player->powers[pw_spacetime]; player->powers[pw_gravityboots] = sonic->player->powers[pw_gravityboots]; player->powers[pw_nocontrol] = sonic->player->powers[pw_nocontrol]; - //!!! Nuke the speed equivalencies player->pflags |= PF_AUTOBRAKE|(sonic->player->pflags & PF_DIRECTIONCHAR); P_TeleportMove(tails, x, y, z); From afa8466b304207f15367c30352da5af7e1ede59f Mon Sep 17 00:00:00 2001 From: Shane Ellis Date: Wed, 30 Jun 2021 01:38:04 -0400 Subject: [PATCH 546/644] comment cleanup --- src/p_mobj.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 4924ec053..8af7ab0d0 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1839,7 +1839,6 @@ void P_XYMovement(mobj_t *mo) // blocked move moved = false; - //!!! if (player) B_MoveBlocked(player); From 0482eacb7c9a625c47a19c017304a3f4af2bd24c Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sat, 3 Jul 2021 19:58:59 +0200 Subject: [PATCH 547/644] Load add-ons in the order in which the -file and -folder arguments are specified --- src/d_main.c | 41 ++++++++++++++++------------------------- 1 file changed, 16 insertions(+), 25 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 0d0e2434a..7866ccbed 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1253,34 +1253,25 @@ void D_SRB2Main(void) // Do this up here so that WADs loaded through the command line can use ExecCfg COM_Init(); - // add any files specified on the command line with -file wadfile - // to the wad list + // Add any files specified on the command line with + // "-file " or "-folder " to the add-on list if (!((M_GetUrlProtocolArg() || M_CheckParm("-connect")) && !M_CheckParm("-server"))) { - if (M_CheckParm("-file")) + INT32 addontype = 0; + INT32 i; + + for (i = 1; i < myargc; i++) { - // the parms after p are wadfile names, - // until end of parms or another - preceded parm - while (M_IsNextParm()) - { - const char *s = M_GetNextParm(); - - if (s) // Check for NULL? - D_AddFile(startuppwads, s); - } - } - - if (M_CheckParm("-folder")) - { - // the parms after p are folder names, - // until end of parms or another - preceded parm - while (M_IsNextParm()) - { - const char *s = M_GetNextParm(); - - if (s) // Check for NULL? - D_AddFolder(startuppwads, s); - } + if (!strcasecmp(myargv[i], "-file")) + addontype = 1; + else if (!strcasecmp(myargv[i], "-folder")) + addontype = 2; + else if (myargv[i][0] == '-' || myargv[i][0] == '+') + addontype = 0; + else if (addontype == 1) + D_AddFile(startuppwads, myargv[i]); + else if (addontype == 2) + D_AddFolder(startuppwads, myargv[i]); } } From 18cbc1e37047f2fabf61e32a4bc2997125ad21b4 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 5 Jul 2021 18:31:04 -0700 Subject: [PATCH 548/644] Fix aliases bypass COM_SAFE --- src/command.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/command.c b/src/command.c index 95b1fd67d..0e0b1a685 100644 --- a/src/command.c +++ b/src/command.c @@ -650,7 +650,7 @@ static void COM_ExecuteString(char *ptext) else { // Monster Iestyn: keep track of how many levels of recursion we're in recursion++; - COM_BufInsertText(a->value); + COM_BufInsertTextEx(a->value, com_flags); recursion--; } return; From 14c5d2c916e42c926dcf8267df3b49bd3dcab31d Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 5 Jul 2021 18:39:12 -0700 Subject: [PATCH 549/644] Warn if Lua attempted access NOLUA consvar And quote variable name. --- src/command.c | 5 ++++- src/lua_consolelib.c | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/command.c b/src/command.c index 0e0b1a685..e6c6587e8 100644 --- a/src/command.c +++ b/src/command.c @@ -2364,7 +2364,10 @@ static boolean CV_Command(void) return false; if (( com_flags & COM_SAFE ) && ( v->flags & CV_NOLUA )) - return false; + { + CONS_Alert(CONS_WARNING, "Variable '%s' cannot be changed from Lua.\n", v->name); + return true; + } // perform a variable print or set if (COM_Argc() == 1) diff --git a/src/lua_consolelib.c b/src/lua_consolelib.c index 414d9692a..2b8cad69b 100644 --- a/src/lua_consolelib.c +++ b/src/lua_consolelib.c @@ -433,7 +433,7 @@ static int CVarSetFunction consvar_t *cvar = *(consvar_t **)luaL_checkudata(L, 1, META_CVAR); if (cvar->flags & CV_NOLUA) - return luaL_error(L, "Variable %s cannot be set from Lua.", cvar->name); + return luaL_error(L, "Variable '%s' cannot be set from Lua.", cvar->name); switch (lua_type(L, 2)) { From a75d4a1c360874a3c301a494e38ea49cd89b6616 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 6 Jul 2021 18:42:08 -0700 Subject: [PATCH 550/644] Automatically count hook values --- src/lua_hooklib.c | 91 +++++++++++++++++++++++++---------------------- 1 file changed, 49 insertions(+), 42 deletions(-) diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index d1b0d3bdd..5f733c3ef 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -259,11 +259,16 @@ static void push_string(void) lua_pushvalue(gL, SINDEX); } -static boolean start_hook_stack(void) +static boolean begin_hook_values(Hook_State *hook) +{ + hook->top = lua_gettop(gL); + return true; +} + +static void start_hook_stack(void) { lua_settop(gL, 0); push_error_handler(); - return true; } static boolean init_hook_type @@ -279,10 +284,11 @@ static boolean init_hook_type if (nonzero) { + start_hook_stack(); hook->hook_type = hook_type; hook->mobj_type = mobj_type; hook->string = string; - return start_hook_stack(); + return begin_hook_values(hook); } else return false; @@ -323,7 +329,7 @@ static boolean prepare_string_hook stringHooks[hook_type].ref)) { lua_pushstring(gL, string); - return true; + return begin_hook_values(hook); } else return false; @@ -332,12 +338,12 @@ static boolean prepare_string_hook static void init_hook_call ( Hook_State * hook, - int values, int results, Hook_Callback results_handler ){ - hook->top = lua_gettop(gL); - hook->values = values; + const int top = lua_gettop(gL); + hook->values = (top - hook->top); + hook->top = top; hook->results = results; hook->results_handler = results_handler; } @@ -447,13 +453,12 @@ static int call_mobj_type_hooks(Hook_State *hook, mobjtype_t mobj_type) static int call_hooks ( Hook_State * hook, - int values, int results, Hook_Callback results_handler ){ int calls = 0; - init_hook_call(hook, values, results, results_handler); + init_hook_call(hook, results, results_handler); if (hook->string) { @@ -514,7 +519,7 @@ int LUA_HookMobj(mobj_t *mobj, int hook_type) if (prepare_mobj_hook(&hook, false, hook_type, mobj->type)) { LUA_PushUserdata(gL, mobj, META_MOBJ); - call_hooks(&hook, 1, 1, res_true); + call_hooks(&hook, 1, res_true); } return hook.status; } @@ -526,7 +531,7 @@ int LUA_Hook2Mobj(mobj_t *t1, mobj_t *t2, int hook_type) { LUA_PushUserdata(gL, t1, META_MOBJ); LUA_PushUserdata(gL, t2, META_MOBJ); - call_hooks(&hook, 2, 1, res_force); + call_hooks(&hook, 1, res_force); } return hook.status; } @@ -535,7 +540,7 @@ void LUA_HookVoid(int type) { Hook_State hook; if (prepare_hook(&hook, 0, type)) - call_hooks(&hook, 0, 0, res_none); + call_hooks(&hook, 0, res_none); } void LUA_HookInt(INT32 number, int hook_type) @@ -544,7 +549,7 @@ void LUA_HookInt(INT32 number, int hook_type) if (prepare_hook(&hook, 0, hook_type)) { lua_pushinteger(gL, number); - call_hooks(&hook, 1, 0, res_none); + call_hooks(&hook, 0, res_none); } } @@ -554,7 +559,7 @@ void LUA_HookBool(boolean value, int hook_type) if (prepare_hook(&hook, 0, hook_type)) { lua_pushboolean(gL, value); - call_hooks(&hook, 1, 0, res_none); + call_hooks(&hook, 0, res_none); } } @@ -564,7 +569,7 @@ int LUA_HookPlayer(player_t *player, int hook_type) if (prepare_hook(&hook, false, hook_type)) { LUA_PushUserdata(gL, player, META_PLAYER); - call_hooks(&hook, 1, 1, res_true); + call_hooks(&hook, 1, res_true); } return hook.status; } @@ -580,7 +585,7 @@ int LUA_HookTiccmd(player_t *player, ticcmd_t *cmd, int hook_type) if (hook_type == HOOK(PlayerCmd)) hook_cmd_running = true; - call_hooks(&hook, 2, 1, res_true); + call_hooks(&hook, 1, res_true); if (hook_type == HOOK(PlayerCmd)) hook_cmd_running = false; @@ -594,7 +599,7 @@ int LUA_HookKey(INT32 keycode, int hook_type) if (prepare_hook(&hook, false, hook_type)) { lua_pushinteger(gL, keycode); - call_hooks(&hook, 1, 1, res_true); + call_hooks(&hook, 1, res_true); } return hook.status; } @@ -618,7 +623,7 @@ void LUA_HookThinkFrame(void) if (prepare_hook(&hook, 0, type)) { - init_hook_call(&hook, 0, 0, res_none); + init_hook_call(&hook, 0, res_none); for (k = 0; k < map->numHooks; ++k) { @@ -653,7 +658,7 @@ int LUA_HookMobjLineCollide(mobj_t *mobj, line_t *line) { LUA_PushUserdata(gL, mobj, META_MOBJ); LUA_PushUserdata(gL, line, META_LINE); - call_hooks(&hook, 2, 1, res_force); + call_hooks(&hook, 1, res_force); } return hook.status; } @@ -665,7 +670,7 @@ int LUA_HookTouchSpecial(mobj_t *special, mobj_t *toucher) { LUA_PushUserdata(gL, special, META_MOBJ); LUA_PushUserdata(gL, toucher, META_MOBJ); - call_hooks(&hook, 2, 1, res_true); + call_hooks(&hook, 1, res_true); } return hook.status; } @@ -678,7 +683,6 @@ static int damage_hook INT32 damage, UINT8 damagetype, int hook_type, - int values, Hook_Callback results_handler ){ Hook_State hook; @@ -687,10 +691,10 @@ static int damage_hook LUA_PushUserdata(gL, target, META_MOBJ); LUA_PushUserdata(gL, inflictor, META_MOBJ); LUA_PushUserdata(gL, source, META_MOBJ); - if (values == 5) + if (hook_type != MOBJ_HOOK(MobjDeath)) lua_pushinteger(gL, damage); lua_pushinteger(gL, damagetype); - call_hooks(&hook, values, 1, results_handler); + call_hooks(&hook, 1, results_handler); } return hook.status; } @@ -698,19 +702,19 @@ static int damage_hook int LUA_HookShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype) { return damage_hook(target, inflictor, source, damage, damagetype, - MOBJ_HOOK(ShouldDamage), 5, res_force); + MOBJ_HOOK(ShouldDamage), res_force); } int LUA_HookMobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype) { return damage_hook(target, inflictor, source, damage, damagetype, - MOBJ_HOOK(MobjDamage), 5, res_true); + MOBJ_HOOK(MobjDamage), res_true); } int LUA_HookMobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damagetype) { return damage_hook(target, inflictor, source, 0, damagetype, - MOBJ_HOOK(MobjDeath), 4, res_true); + MOBJ_HOOK(MobjDeath), res_true); } typedef struct { @@ -783,7 +787,7 @@ int LUA_HookBotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd) hook.userdata = &botai; - call_hooks(&hook, 2, 8, res_botai); + call_hooks(&hook, 8, res_botai); } return hook.status; @@ -798,7 +802,7 @@ void LUA_HookLinedefExecute(line_t *line, mobj_t *mo, sector_t *sector) LUA_PushUserdata(gL, line, META_LINE); LUA_PushUserdata(gL, mo, META_MOBJ); LUA_PushUserdata(gL, sector, META_SECTOR); - ps_lua_mobjhooks += call_hooks(&hook, 3, 0, res_none); + ps_lua_mobjhooks += call_hooks(&hook, 0, res_none); } } @@ -822,7 +826,7 @@ int LUA_HookPlayerMsg(int source, int target, int flags, char *msg) LUA_PushUserdata(gL, &players[target-1], META_PLAYER); // target } lua_pushstring(gL, msg); // msg - call_hooks(&hook, 4, 1, res_true); + call_hooks(&hook, 1, res_true); } return hook.status; } @@ -836,7 +840,7 @@ int LUA_HookHurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 d LUA_PushUserdata(gL, inflictor, META_MOBJ); LUA_PushUserdata(gL, source, META_MOBJ); lua_pushinteger(gL, damagetype); - call_hooks(&hook, 4, 1, res_true); + call_hooks(&hook, 1, res_true); } return hook.status; } @@ -855,12 +859,14 @@ void LUA_HookNetArchive(lua_CFunction archFunc) push_error_handler(); lua_insert(gL, EINDEX); + begin_hook_values(&hook); + // tables becomes an upvalue of archFunc lua_pushvalue(gL, -1); lua_pushcclosure(gL, archFunc, 1); // stack: tables, archFunc - init_hook_call(&hook, 1, 0, res_none); + init_hook_call(&hook, 0, res_none); call_mapped(&hook, map); lua_pop(gL, 1); // pop archFunc @@ -876,7 +882,7 @@ int LUA_HookMapThingSpawn(mobj_t *mobj, mapthing_t *mthing) { LUA_PushUserdata(gL, mobj, META_MOBJ); LUA_PushUserdata(gL, mthing, META_MAPTHING); - call_hooks(&hook, 2, 1, res_true); + call_hooks(&hook, 1, res_true); } return hook.status; } @@ -888,7 +894,7 @@ int LUA_HookFollowMobj(player_t *player, mobj_t *mobj) { LUA_PushUserdata(gL, player, META_PLAYER); LUA_PushUserdata(gL, mobj, META_MOBJ); - call_hooks(&hook, 2, 1, res_true); + call_hooks(&hook, 1, res_true); } return hook.status; } @@ -900,7 +906,7 @@ int LUA_HookPlayerCanDamage(player_t *player, mobj_t *mobj) { LUA_PushUserdata(gL, player, META_PLAYER); LUA_PushUserdata(gL, mobj, META_MOBJ); - call_hooks(&hook, 2, 1, res_force); + call_hooks(&hook, 1, res_force); } return hook.status; } @@ -912,7 +918,7 @@ void LUA_HookPlayerQuit(player_t *plr, kickreason_t reason) { LUA_PushUserdata(gL, plr, META_PLAYER); // Player that quit lua_pushinteger(gL, reason); // Reason for quitting - call_hooks(&hook, 2, 0, res_none); + call_hooks(&hook, 0, res_none); } } @@ -926,7 +932,7 @@ int LUA_HookTeamSwitch(player_t *player, int newteam, boolean fromspectators, bo lua_pushboolean(gL, fromspectators); lua_pushboolean(gL, tryingautobalance); lua_pushboolean(gL, tryingscramble); - call_hooks(&hook, 5, 1, res_false); + call_hooks(&hook, 1, res_false); } return hook.status; } @@ -941,7 +947,7 @@ int LUA_HookViewpointSwitch(player_t *player, player_t *newdisplayplayer, boolea lua_pushboolean(gL, forced); hud_running = true; // local hook - call_hooks(&hook, 3, 1, res_force); + call_hooks(&hook, 1, res_force); hud_running = false; } return hook.status; @@ -956,7 +962,7 @@ int LUA_HookSeenPlayer(player_t *player, player_t *seenfriend) LUA_PushUserdata(gL, seenfriend, META_PLAYER); hud_running = true; // local hook - call_hooks(&hook, 2, 1, res_false); + call_hooks(&hook, 1, res_false); hud_running = false; } return hook.status; @@ -972,7 +978,7 @@ int LUA_HookShouldJingleContinue(player_t *player, const char *musname) push_string(); hud_running = true; // local hook - call_hooks(&hook, 2, 1, res_true); + call_hooks(&hook, 1, res_true); hud_running = false; } return hook.status; @@ -1038,7 +1044,8 @@ int LUA_HookMusicChange(const char *oldname, struct MusicChange *param) if (prepare_hook(&hook, false, type)) { - init_hook_call(&hook, 7, 6, res_musicchange); + init_hook_call(&hook, 6, res_musicchange); + hook.values = 7;/* values pushed later */ hook.userdata = param; lua_pushstring(gL, oldname);/* the only constant value */ @@ -1084,7 +1091,7 @@ fixed_t LUA_HookPlayerHeight(player_t *player) if (prepare_hook(&hook, -1, HOOK(PlayerHeight))) { LUA_PushUserdata(gL, player, META_PLAYER); - call_hooks(&hook, 1, 1, res_playerheight); + call_hooks(&hook, 1, res_playerheight); } return hook.status; } @@ -1095,7 +1102,7 @@ int LUA_HookPlayerCanEnterSpinGaps(player_t *player) if (prepare_hook(&hook, 0, HOOK(PlayerCanEnterSpinGaps))) { LUA_PushUserdata(gL, player, META_PLAYER); - call_hooks(&hook, 1, 1, res_force); + call_hooks(&hook, 1, res_force); } return hook.status; } From 331329306cad257d52f84e47a92d9214d9eaa8d3 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 6 Jul 2021 19:12:47 -0700 Subject: [PATCH 551/644] Refactor hook ref allocation --- src/lua_hooklib.c | 58 +++++++++++++++++++++++++---------------------- 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 5f733c3ef..ce1b16f75 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -56,6 +56,7 @@ static stringhook_t stringHooks[STRING_HOOK(MAX)]; // This will be indexed by hook id, the value of which fetches the registry. static int * hookRefs; +static int nextid; // After a hook errors once, don't print the error again. static UINT8 * hooksErrored; @@ -104,13 +105,13 @@ static void get_table(lua_State *L) lua_remove(L, -2); } -static void add_hook_to_table(lua_State *L, int id, int n) +static void add_hook_to_table(lua_State *L, int n) { - lua_pushnumber(L, id); + lua_pushnumber(L, nextid); lua_rawseti(L, -2, n); } -static void add_string_hook(lua_State *L, int type, int id) +static void add_string_hook(lua_State *L, int type) { stringhook_t * hook = &stringHooks[type]; @@ -146,33 +147,48 @@ static void add_string_hook(lua_State *L, int type, int id) { lua_pushstring(L, string); get_table(L); - add_hook_to_table(L, id, 1 + lua_objlen(L, -1)); + add_hook_to_table(L, 1 + lua_objlen(L, -1)); } else - add_hook_to_table(L, id, ++hook->numGeneric); + add_hook_to_table(L, ++hook->numGeneric); } -static void add_hook(hook_t *map, int id) +static void add_hook(hook_t *map) { Z_Realloc(map->ids, (map->numHooks + 1) * sizeof *map->ids, PU_STATIC, &map->ids); - map->ids[map->numHooks++] = id; + map->ids[map->numHooks++] = nextid; } -static void add_mobj_hook(lua_State *L, int hook_type, int id) +static void add_mobj_hook(lua_State *L, int hook_type) { mobjtype_t mobj_type = luaL_optnumber(L, 3, MT_NULL); luaL_argcheck(L, mobj_type < NUMMOBJTYPES, 3, "invalid mobjtype_t"); - add_hook(&mobjHookIds[mobj_type][hook_type], id); + add_hook(&mobjHookIds[mobj_type][hook_type]); +} + +static void add_hook_ref(lua_State *L, int idx) +{ + if (!(nextid & 7)) + { + Z_Realloc(hooksErrored, + BIT_ARRAY_SIZE (nextid + 1) * sizeof *hooksErrored, + PU_STATIC, &hooksErrored); + hooksErrored[nextid >> 3] = 0; + } + + Z_Realloc(hookRefs, (nextid + 1) * sizeof *hookRefs, PU_STATIC, &hookRefs); + + // set the hook function in the registry. + lua_pushvalue(L, idx); + hookRefs[nextid++] = luaL_ref(L, LUA_REGISTRYINDEX); } // Takes hook, function, and additional arguments (mobj type to act on, etc.) static int lib_addHook(lua_State *L) { - static int nextid; - const char * name; int type; @@ -185,34 +201,22 @@ static int lib_addHook(lua_State *L) /* this is a very special case */ if (( type = hook_in_list(name, stringHookNames) ) < STRING_HOOK(MAX)) { - add_string_hook(L, type, nextid); + add_string_hook(L, type); } else if (( type = hook_in_list(name, mobjHookNames) ) < MOBJ_HOOK(MAX)) { - add_mobj_hook(L, type, nextid); + add_mobj_hook(L, type); } else if (( type = hook_in_list(name, hookNames) ) < HOOK(MAX)) { - add_hook(&hookIds[type], nextid); + add_hook(&hookIds[type]); } else { return luaL_argerror(L, 1, lua_pushfstring(L, "invalid hook " LUA_QS, name)); } - if (!(nextid & 7)) - { - Z_Realloc(hooksErrored, - BIT_ARRAY_SIZE (nextid + 1) * sizeof *hooksErrored, - PU_STATIC, &hooksErrored); - hooksErrored[nextid >> 3] = 0; - } - - Z_Realloc(hookRefs, (nextid + 1) * sizeof *hookRefs, PU_STATIC, &hookRefs); - - // set the hook function in the registry. - lua_pushvalue(L, 2);/* the function */ - hookRefs[nextid++] = luaL_ref(L, LUA_REGISTRYINDEX); + add_hook_ref(L, 2);/* the function */ return 0; } From ae57b6ca8664e00ff4d9544339dbf29a41138040 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 6 Jul 2021 20:23:38 -0700 Subject: [PATCH 552/644] MORE MACROS I just can't stop myself! --- src/lua_hook.h | 10 +++++++--- src/lua_hooklib.c | 12 +++++++----- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/lua_hook.h b/src/lua_hook.h index 223b83c61..1af1697a7 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -90,9 +90,13 @@ grepped and found in the lists above. #define HOOK(name) hook_ ## name #define STRING_HOOK(name) stringhook_ ## name -enum { MOBJ_HOOK_LIST (MOBJ_HOOK) MOBJ_HOOK(MAX) }; -enum { HOOK_LIST (HOOK) HOOK(MAX) }; -enum { STRING_HOOK_LIST (STRING_HOOK) STRING_HOOK(MAX) }; +#define ENUM(X) enum { X ## _LIST (X) X(MAX) } + +ENUM (MOBJ_HOOK); +ENUM (HOOK); +ENUM (STRING_HOOK); + +#undef ENUM /* dead simple, LUA_HOOK(GameQuit) */ #define LUA_HOOK(type) LUA_HookVoid(HOOK(type)) diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index ce1b16f75..5815f17b3 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -31,12 +31,14 @@ ABSTRACTION ========================================================================= */ -static const char * const mobjHookNames[] = { MOBJ_HOOK_LIST (TOSTR) NULL }; -static const char * const hookNames[] = { HOOK_LIST (TOSTR) NULL }; +#define LIST(id, M) \ + static const char * const id [] = { M (TOSTR) NULL } -static const char * const stringHookNames[] = { - STRING_HOOK_LIST (TOSTR) NULL -}; +LIST (mobjHookNames, MOBJ_HOOK_LIST); +LIST (hookNames, HOOK_LIST); +LIST (stringHookNames, STRING_HOOK_LIST); + +#undef LIST typedef struct { int numHooks; From b4fa98d2fbab180f487ce3efedb8ab715e5f3390 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 7 Jul 2021 00:23:51 -0700 Subject: [PATCH 553/644] Refactor hudlib hooks to hooklib HUD hooks now meet the standard of hooklib. HUD registry magic numbers are gone. HUD hooks may also be added using addHook. addHook('HUD', fn[, type]) hud.add still exists, but the intention is to remove it eventually. --- src/f_finale.c | 3 +- src/hu_stuff.c | 2 +- src/lua_hook.h | 11 +++ src/lua_hooklib.c | 47 +++++++++ src/lua_hud.h | 6 +- src/lua_hudlib.c | 236 ++++++---------------------------------------- src/st_stuff.c | 5 +- src/y_inter.c | 2 +- 8 files changed, 93 insertions(+), 219 deletions(-) diff --git a/src/f_finale.c b/src/f_finale.c index e8757c18a..401ab45b1 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -41,6 +41,7 @@ #include "console.h" #include "lua_hud.h" +#include "lua_hook.h" // Stage of animation: // 0 = text, 1 = art screen @@ -3423,7 +3424,7 @@ void F_TitleScreenDrawer(void) } luahook: - LUAh_TitleHUD(); + LUA_HUDHOOK(title); } // separate animation timer for backgrounds, since we also count diff --git a/src/hu_stuff.c b/src/hu_stuff.c index e0eaf8fb1..be215ff21 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -2104,7 +2104,7 @@ void HU_Drawer(void) } else HU_DrawCoopOverlay(); - LUAh_ScoresHUD(); + LUA_HUDHOOK(scores); } if (gamestate != GS_LEVEL) diff --git a/src/lua_hook.h b/src/lua_hook.h index 1af1697a7..1c01d1d66 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -78,6 +78,13 @@ automatically. X (LinedefExecute),\ X (ShouldJingleContinue),/* should jingle of the given music continue playing */\ +#define HUD_HOOK_LIST(X) \ + X (game),\ + X (scores),/* emblems/multiplayer list */\ + X (title),/* titlescreen */\ + X (titlecard),\ + X (intermission),\ + /* I chose to access the hook enums through a macro as well. This could provide a hint to lookup the macro's definition instead of the enum's definition. @@ -88,22 +95,26 @@ grepped and found in the lists above. #define MOBJ_HOOK(name) mobjhook_ ## name #define HOOK(name) hook_ ## name +#define HUD_HOOK(name) hudhook_ ## name #define STRING_HOOK(name) stringhook_ ## name #define ENUM(X) enum { X ## _LIST (X) X(MAX) } ENUM (MOBJ_HOOK); ENUM (HOOK); +ENUM (HUD_HOOK); ENUM (STRING_HOOK); #undef ENUM /* dead simple, LUA_HOOK(GameQuit) */ #define LUA_HOOK(type) LUA_HookVoid(HOOK(type)) +#define LUA_HUDHOOK(type) LUA_HookHUD(HUD_HOOK(type)) extern boolean hook_cmd_running; void LUA_HookVoid(int hook); +void LUA_HookHUD(int hook); int LUA_HookMobj(mobj_t *, int hook); int LUA_Hook2Mobj(mobj_t *, mobj_t *, int hook); diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 5815f17b3..96cb04543 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -36,6 +36,7 @@ LIST (mobjHookNames, MOBJ_HOOK_LIST); LIST (hookNames, HOOK_LIST); +LIST (hudHookNames, HUD_HOOK_LIST); LIST (stringHookNames, STRING_HOOK_LIST); #undef LIST @@ -51,6 +52,7 @@ typedef struct { } stringhook_t; static hook_t hookIds[HOOK(MAX)]; +static hook_t hudHookIds[HUD_HOOK(MAX)]; static hook_t mobjHookIds[NUMMOBJTYPES][MOBJ_HOOK(MAX)]; // Lua tables are used to lookup string hook ids. @@ -171,6 +173,12 @@ static void add_mobj_hook(lua_State *L, int hook_type) add_hook(&mobjHookIds[mobj_type][hook_type]); } +static void add_hud_hook(lua_State *L, int idx) +{ + add_hook(&hudHookIds[luaL_checkoption(L, + idx, "game", hudHookNames)]); +} + static void add_hook_ref(lua_State *L, int idx) { if (!(nextid & 7)) @@ -213,6 +221,10 @@ static int lib_addHook(lua_State *L) { add_hook(&hookIds[type]); } + else if (strcmp(name, "HUD") == 0) + { + add_hud_hook(L, 3); + } else { return luaL_argerror(L, 1, lua_pushfstring(L, "invalid hook " LUA_QS, name)); @@ -233,6 +245,23 @@ int LUA_HookLib(lua_State *L) return 0; } +/* TODO: remove in next backwards incompatible release */ +#if MODID == 18 +int lib_hudadd(lua_State *L);/* yeah compiler */ +int lib_hudadd(lua_State *L) +{ + if (!lua_lumploading) + return luaL_error(L, "This function cannot be called from within a hook or coroutine!"); + + luaL_checktype(L, 1, LUA_TFUNCTION); + + add_hud_hook(L, 2); + add_hook_ref(L, 1); + + return 0; +} +#endif + typedef struct Hook_State Hook_State; typedef void (*Hook_Callback)(Hook_State *); @@ -610,6 +639,24 @@ int LUA_HookKey(INT32 keycode, int hook_type) return hook.status; } +void LUA_HookHUD(int hook_type) +{ + const hook_t * map = &hudHookIds[hook_type]; + Hook_State hook; + if (map->numHooks > 0) + { + start_hook_stack(); + begin_hook_values(&hook); + + LUA_SetHudHook(hook_type); + + hud_running = true; // local hook + init_hook_call(&hook, 0, res_none); + call_mapped(&hook, map); + hud_running = false; + } +} + /* ========================================================================= SPECIALIZED HOOKS ========================================================================= */ diff --git a/src/lua_hud.h b/src/lua_hud.h index d2f5bceca..c1d2d164b 100644 --- a/src/lua_hud.h +++ b/src/lua_hud.h @@ -47,8 +47,4 @@ extern boolean hud_running; boolean LUA_HudEnabled(enum hud option); -void LUAh_GameHUD(player_t *stplyr); -void LUAh_ScoresHUD(void); -void LUAh_TitleHUD(void); -void LUAh_TitleCardHUD(player_t *stplayr); -void LUAh_IntermissionHUD(boolean failedstage); +void LUA_SetHudHook(int hook); diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 9a3e676d5..b60cdcde0 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -23,18 +23,18 @@ #include "v_video.h" #include "w_wad.h" #include "z_zone.h" +#include "y_inter.h" #include "lua_script.h" #include "lua_libs.h" #include "lua_hud.h" +#include "lua_hook.h" #define HUDONLY if (!hud_running) return luaL_error(L, "HUD rendering code should not be called outside of rendering hooks!"); boolean hud_running = false; static UINT8 hud_enabled[(hud_MAX/8)+1]; -static UINT8 hudAvailable; // hud hooks field - // must match enum hud in lua_hud.h static const char *const hud_disable_options[] = { "stagetitle", @@ -95,21 +95,6 @@ static const char *const patch_opt[] = { "topoffset", NULL}; -enum hudhook { - hudhook_game = 0, - hudhook_scores, - hudhook_intermission, - hudhook_title, - hudhook_titlecard -}; -static const char *const hudhook_opt[] = { - "game", - "scores", - "intermission", - "title", - "titlecard", - NULL}; - // alignment types for v.drawString enum align { align_left = 0, @@ -1152,6 +1137,8 @@ static luaL_Reg lib_draw[] = { {NULL, NULL} }; +static int lib_draw_ref; + // // lib_hud // @@ -1186,28 +1173,7 @@ static int lib_hudenabled(lua_State *L) // add a HUD element for rendering -static int lib_hudadd(lua_State *L) -{ - enum hudhook field; - - luaL_checktype(L, 1, LUA_TFUNCTION); - field = luaL_checkoption(L, 2, "game", hudhook_opt); - - if (!lua_lumploading) - return luaL_error(L, "This function cannot be called from within a hook or coroutine!"); - - lua_getfield(L, LUA_REGISTRYINDEX, "HUD"); - I_Assert(lua_istable(L, -1)); - lua_rawgeti(L, -1, field+2); // HUD[2+] - I_Assert(lua_istable(L, -1)); - lua_remove(L, -2); - - lua_pushvalue(L, 1); - lua_rawseti(L, -2, (int)(lua_objlen(L, -2) + 1)); - - hudAvailable |= 1< Date: Wed, 7 Jul 2021 19:57:28 -0500 Subject: [PATCH 554/644] Rebase on !1307 --- src/lua_hook.h | 1 + src/lua_hooklib.c | 13 +++++++++++++ src/p_mobj.c | 2 +- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/lua_hook.h b/src/lua_hook.h index 223b83c61..1af28aac5 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -115,6 +115,7 @@ int LUA_HookTouchSpecial(mobj_t *special, mobj_t *toucher); int LUA_HookShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype); int LUA_HookMobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype); int LUA_HookMobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damagetype); +int LUA_HookMobjMoveBlocked(mobj_t *, mobj_t *, line_t *); int LUA_HookBotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd); void LUA_HookLinedefExecute(line_t *, mobj_t *, sector_t *); int LUA_HookPlayerMsg(int source, int target, int flags, char *msg); diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index d1b0d3bdd..f2e9b5233 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -713,6 +713,19 @@ int LUA_HookMobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 d MOBJ_HOOK(MobjDeath), 4, res_true); } +int LUA_HookMobjMoveBlocked(mobj_t *t1, mobj_t *t2, line_t *line) +{ + Hook_State hook; + if (prepare_mobj_hook(&hook, 0, MOBJ_HOOK(MobjMoveBlocked), t1->type)) + { + LUA_PushUserdata(gL, t1, META_MOBJ); + LUA_PushUserdata(gL, t2, META_MOBJ); + LUA_PushUserdata(gL, line, META_LINE); + call_hooks(&hook, 3, 1, res_true); + } + return hook.status; +} + typedef struct { mobj_t * tails; ticcmd_t * cmd; diff --git a/src/p_mobj.c b/src/p_mobj.c index 10220fff6..f2fae6cc6 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1844,7 +1844,7 @@ void P_XYMovement(mobj_t *mo) B_MoveBlocked(player); } - if (LUA_HookMobj(mo, MOBJ_HOOK(MobjMoveBlocked))) + if (LUA_HookMobjMoveBlocked(mo, tmhitthing, blockingline)) { if (P_MobjWasRemoved(mo)) return; From e30d4f954b9ec90632484b31673b7fe6185481a5 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 8 Jul 2021 14:37:03 -0700 Subject: [PATCH 555/644] Revert netvars after demo finishes playback (Demos do not call CL_Reset BTW.) --- src/command.c | 4 +++- src/d_clisrv.c | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/command.c b/src/command.c index 95b1fd67d..da777310a 100644 --- a/src/command.c +++ b/src/command.c @@ -1738,6 +1738,8 @@ void CV_SaveVars(UINT8 **p, boolean in_demo) static void CV_LoadVars(UINT8 **p, consvar_t *(*got)(UINT8 **p, char **ret_value, boolean *ret_stealth)) { + const boolean store = (client || demoplayback); + consvar_t *cvar; UINT16 count; @@ -1751,7 +1753,7 @@ static void CV_LoadVars(UINT8 **p, { if (cvar->flags & CV_NETVAR) { - if (client && cvar->revert.v.string == NULL) + if (store && cvar->revert.v.string == NULL) { cvar->revert.v.const_munge = cvar->string; cvar->revert.allocated = ( cvar->zstring != NULL ); diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 1549811c1..1d895c0e1 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2599,7 +2599,6 @@ void CL_Reset(void) doomcom->numslots = 1; SV_StopServer(); SV_ResetServer(); - CV_RevertNetVars(); // make sure we don't leave any fileneeded gunk over from a failed join fileneedednum = 0; @@ -3231,6 +3230,8 @@ void SV_ResetServer(void) // clear server_context memset(server_context, '-', 8); + CV_RevertNetVars(); + DEBFILE("\n-=-=-=-=-=-=-= Server Reset =-=-=-=-=-=-=-\n\n"); } From 366b1f65a18a89b26afcd30c71255bcd9d1995be Mon Sep 17 00:00:00 2001 From: lachablock Date: Sat, 10 Jul 2021 18:22:07 +1000 Subject: [PATCH 556/644] Allow Lua write access to camera_t variables & expose the cameras globally --- src/lua_hudlib.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++ src/lua_script.c | 8 +++++++ 2 files changed, 64 insertions(+) diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 9a3e676d5..306ffaf94 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -384,6 +384,59 @@ static int camera_get(lua_State *L) return 1; } +static int camera_set(lua_State *L) +{ + camera_t *cam = *((camera_t **)luaL_checkudata(L, 1, META_CAMERA)); + enum cameraf field = luaL_checkoption(L, 2, NULL, camera_opt); + + I_Assert(cam != NULL); + + switch(field) + { + case camera_subsector: + case camera_floorz: + case camera_ceilingz: + case camera_height: + case camera_radius: + return luaL_error(L, LUA_QL("camera_t") " field " LUA_QS " should not be set directly.", camera_opt[field]); + case camera_chase: + if (cam == &camera) + CV_SetValue(&cv_chasecam, (INT32)luaL_checkboolean(L, 3)); + else if (cam == &camera2) + CV_SetValue(&cv_chasecam2, (INT32)luaL_checkboolean(L, 3)); + else // ??? this should never happen, but ok + cam->chase = luaL_checkboolean(L, 3); + break; + case camera_aiming: + cam->aiming = luaL_checkangle(L, 3); + break; + case camera_x: + cam->x = luaL_checkfixed(L, 3); + break; + case camera_y: + cam->y = luaL_checkfixed(L, 3); + break; + case camera_z: + cam->z = luaL_checkfixed(L, 3); + break; + case camera_angle: + cam->angle = luaL_checkangle(L, 3); + break; + case camera_momx: + cam->momx = luaL_checkfixed(L, 3); + break; + case camera_momy: + cam->momy = luaL_checkfixed(L, 3); + break; + case camera_momz: + cam->momz = luaL_checkfixed(L, 3); + break; + default: + return luaL_error(L, LUA_QL("camera_t") " has no field named " LUA_QS, camera_opt[field]); + } + return 0; +} + // // lib_draw // @@ -1283,6 +1336,9 @@ int LUA_HudLib(lua_State *L) luaL_newmetatable(L, META_CAMERA); lua_pushcfunction(L, camera_get); lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, camera_set); + lua_setfield(L, -2, "__newindex"); lua_pop(L,1); luaL_register(L, "hud", lib_hud); diff --git a/src/lua_script.c b/src/lua_script.c index 6faff8729..54ab124fc 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -393,6 +393,14 @@ int LUA_PushGlobals(lua_State *L, const char *word) } else if (fastcmp(word, "mouse2")) { LUA_PushUserdata(L, &mouse2, META_MOUSE); return 1; + } else if (fastcmp(word, "camera")) { + LUA_PushUserdata(L, &camera, META_CAMERA); + return 1; + } else if (fastcmp(word, "camera2")) { + if (!splitscreen) + return 0; + LUA_PushUserdata(L, &camera2, META_CAMERA); + return 1; } return 0; } From 117e3e267087d8c13914037f14b282d47177d474 Mon Sep 17 00:00:00 2001 From: lachablock Date: Sun, 11 Jul 2021 16:23:50 +1000 Subject: [PATCH 557/644] Expose P_TryCameraMove and P_TeleportCameraMove, disallow write access to camera.x and camera.y, allow write access to camera.height and camera.radius --- src/lua_baselib.c | 33 +++++++++++++++++++++++++++++++++ src/lua_hudlib.c | 31 ++++++++++++++++++++++--------- 2 files changed, 55 insertions(+), 9 deletions(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index d6f40846c..a3f1d9811 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -1883,6 +1883,37 @@ static int lib_pDoSpring(lua_State *L) return 1; } +static int lib_pTryCameraMove(lua_State *L) +{ + camera_t *cam = *((camera_t **)luaL_checkudata(L, 1, META_CAMERA)); + fixed_t x = luaL_checkfixed(L, 2); + fixed_t y = luaL_checkfixed(L, 3); + + if (!cam) + return LUA_ErrInvalid(L, "camera_t"); + lua_pushboolean(L, P_TryCameraMove(x, y, cam)); + return 1; +} + +static int lib_pTeleportCameraMove(lua_State *L) +{ + camera_t *cam = *((camera_t **)luaL_checkudata(L, 1, META_CAMERA)); + fixed_t x = luaL_checkfixed(L, 2); + fixed_t y = luaL_checkfixed(L, 3); + fixed_t z = luaL_checkfixed(L, 4); + + if (!cam) + return LUA_ErrInvalid(L, "camera_t"); + cam->x = x; + cam->y = y; + cam->z = z; + P_CheckCameraPosition(x, y, cam); + cam->subsector = R_PointInSubsector(x, y); + cam->floorz = tmfloorz; + cam->ceilingz = tmceilingz; + return 0; +} + // P_INTER //////////// @@ -3881,6 +3912,8 @@ static luaL_Reg lib[] = { {"P_FloorzAtPos",lib_pFloorzAtPos}, {"P_CeilingzAtPos",lib_pCeilingzAtPos}, {"P_DoSpring",lib_pDoSpring}, + {"P_TryCameraMove", lib_pTryCameraMove}, + {"P_TeleportCameraMove", lib_pTeleportCameraMove}, // p_inter {"P_RemoveShield",lib_pRemoveShield}, diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 306ffaf94..0f8ccb089 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -396,9 +396,9 @@ static int camera_set(lua_State *L) case camera_subsector: case camera_floorz: case camera_ceilingz: - case camera_height: - case camera_radius: - return luaL_error(L, LUA_QL("camera_t") " field " LUA_QS " should not be set directly.", camera_opt[field]); + case camera_x: + case camera_y: + return luaL_error(L, LUA_QL("camera_t") " field " LUA_QS " should not be set directly. Use " LUA_QL("P_TryCameraMove") " or " LUA_QL("P_TeleportCameraMove") " instead.", camera_opt[field]); case camera_chase: if (cam == &camera) CV_SetValue(&cv_chasecam, (INT32)luaL_checkboolean(L, 3)); @@ -410,18 +410,31 @@ static int camera_set(lua_State *L) case camera_aiming: cam->aiming = luaL_checkangle(L, 3); break; - case camera_x: - cam->x = luaL_checkfixed(L, 3); - break; - case camera_y: - cam->y = luaL_checkfixed(L, 3); - break; case camera_z: cam->z = luaL_checkfixed(L, 3); + P_CheckCameraPosition(cam->x, cam->y, cam); + cam->floorz = tmfloorz; + cam->ceilingz = tmceilingz; break; case camera_angle: cam->angle = luaL_checkangle(L, 3); break; + case camera_radius: + cam->radius = luaL_checkfixed(L, 3); + if (cam->radius < 0) + cam->radius = 0; + P_CheckCameraPosition(cam->x, cam->y, cam); + cam->floorz = tmfloorz; + cam->ceilingz = tmceilingz; + break; + case camera_height: + cam->height = luaL_checkfixed(L, 3); + if (cam->height < 0) + cam->height = 0; + P_CheckCameraPosition(cam->x, cam->y, cam); + cam->floorz = tmfloorz; + cam->ceilingz = tmceilingz; + break; case camera_momx: cam->momx = luaL_checkfixed(L, 3); break; From c337709d105696f91ed923371346326e11dd93ee Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 11 Jul 2021 16:32:36 -0400 Subject: [PATCH 558/644] Update f_finale.c --- src/f_finale.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/f_finale.c b/src/f_finale.c index e8757c18a..4d9a8f825 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1166,7 +1166,6 @@ static const char *credits[] = { "Alexander \"DrTapeworm\" Moench-Ford", "Stefan \"Stuf\" Rimalia", "Shane Mychal Sexton", - "\"Spazzo\"", "David \"Big Wave Dave\" Spencer Sr.", "David \"Instant Sonic\" Spencer Jr.", "\"SSNTails\"", @@ -1191,7 +1190,6 @@ static const char *credits[] = { "\"Revan\"", "Anna \"QueenDelta\" Sandlin", "Wessel \"sphere\" Smit", - "\"Spazzo\"", "\"SSNTails\"", "Rob Tisdell", "\"Torgo\"", From 0faecf095987e4df5333a9d4fed6f06cd75bd9f0 Mon Sep 17 00:00:00 2001 From: SteelT Date: Sun, 11 Jul 2021 20:51:06 -0400 Subject: [PATCH 559/644] version.h: Update comment about contacting an MS admin --- src/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h b/src/version.h index 4470fbd6e..28fc71c36 100644 --- a/src/version.h +++ b/src/version.h @@ -1,6 +1,6 @@ #define SRB2VERSION "2.2.9"/* this must be the first line, for cmake !! */ -// The Modification ID; must be obtained from a Master Server Admin ( https://mb.srb2.org/showgroups.php ). +// The Modification ID; must be obtained from a Master Server Admin ( https://mb.srb2.org/members/?key=ms_admin ). // DO NOT try to set this otherwise, or your modification will be unplayable through the Master Server. // "18" is the default mod ID for version 2.2 #define MODID 18 From 58fa44e8dc0444eecbe701f31872fad9fa563a6a Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 12 Jul 2021 03:50:44 -0700 Subject: [PATCH 560/644] CMP0115 --- src/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4c125c4b8..721cd6dca 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -4,7 +4,7 @@ add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32) # Core sources target_sourcefile(c) -target_sources(SRB2SDL2 PRIVATE comptime.c md5.c config.h) +target_sources(SRB2SDL2 PRIVATE comptime.c md5.c config.h.in) set(SRB2_ASM_SOURCES vid_copy.s) From 33ae95bf134571967f3f9875e5b3efeb2a352127 Mon Sep 17 00:00:00 2001 From: Shane Ellis Date: Mon, 12 Jul 2021 23:38:52 -0400 Subject: [PATCH 561/644] G_RemovePlayer error handling --- src/lua_baselib.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 9946a9fd3..34d1b1a94 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -3482,15 +3482,16 @@ static int lib_gAddPlayer(lua_State *L) static int lib_gRemovePlayer(lua_State *L) { UINT8 pnum = -1; - //const char *kickreason = luaL_checkstring(L, 2); - if (!lua_isnoneornil(L, 1)) pnum = luaL_checkinteger(L, 1); - if (&players[pnum]) + else // No argument + return luaL_error(L, "argument #1 not given (expected number)"); + if (pnum >= MAXPLAYERS) // Out of range + return luaL_error(L, "playernum %d out of range (0 - %d)", pnum, MAXPLAYERS-1); + if (playeringame[pnum]) // Found player { - if (players[pnum].bot != BOT_NONE) + if (players[pnum].bot != BOT_NONE) // Can't remove clients. { -// CL_RemovePlayer(pnum, *kickreason); CL_RemovePlayer(pnum, pnum); if (netgame) { @@ -3503,9 +3504,11 @@ static int lib_gRemovePlayer(lua_State *L) lua_pushboolean(L, true); return 1; } + else + return luaL_error(L, "G_RemovePlayer can only be used on players with a bot value other than BOT_NONE."); } - lua_pushboolean(L, false); - return 1; + // Fell through. Invalid player + return LUA_ErrInvalid(L, "player_t"); } From aed86781fc2794bb50a8245cbd0f2e5ea455d5c4 Mon Sep 17 00:00:00 2001 From: Nev3r Date: Tue, 13 Jul 2021 17:41:38 +0200 Subject: [PATCH 562/644] Bugfix - Fix sporadically occurring incorrect userdata types in Lua, caused by previously loaded userdata which didn't get invalidated in previous sessions. Invalidate userdata for line and mapthing args. Invalidate userdata for slopes and their normal, origin and direction vectors. --- src/lua_script.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/lua_script.c b/src/lua_script.c index 6faff8729..506a888ea 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -25,7 +25,7 @@ #include "byteptr.h" #include "p_saveg.h" #include "p_local.h" -#include "p_slopes.h" // for P_SlopeById +#include "p_slopes.h" // for P_SlopeById and slopelist #include "p_polyobj.h" // polyobj_t, PolyObjects #ifdef LUA_ALLOW_BYTECODE #include "d_netfil.h" // for LUA_DumpFile @@ -851,6 +851,7 @@ void LUA_InvalidateLevel(void) { LUA_InvalidateUserdata(&lines[i]); LUA_InvalidateUserdata(&lines[i].tags); + LUA_InvalidateUserdata(&lines[i].args); LUA_InvalidateUserdata(lines[i].sidenum); } for (i = 0; i < numsides; i++) @@ -863,6 +864,13 @@ void LUA_InvalidateLevel(void) LUA_InvalidateUserdata(&PolyObjects[i].vertices); LUA_InvalidateUserdata(&PolyObjects[i].lines); } + for (pslope_t *slope = slopelist; slope; slope = slope->next) + { + LUA_InvalidateUserdata(slope); + LUA_InvalidateUserdata(&slope->normal); + LUA_InvalidateUserdata(&slope->o); + LUA_InvalidateUserdata(&slope->d); + } #ifdef HAVE_LUA_SEGS for (i = 0; i < numsegs; i++) LUA_InvalidateUserdata(&segs[i]); @@ -885,6 +893,7 @@ void LUA_InvalidateMapthings(void) { LUA_InvalidateUserdata(&mapthings[i]); LUA_InvalidateUserdata(&mapthings[i].tags); + LUA_InvalidateUserdata(&mapthings[i].args); } } From 22dfa05c318b02bd77b9ee75990482b2d1378ad9 Mon Sep 17 00:00:00 2001 From: Nev3r Date: Tue, 13 Jul 2021 17:44:28 +0200 Subject: [PATCH 563/644] Forgot the stringargs. --- src/lua_script.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lua_script.c b/src/lua_script.c index 506a888ea..a7bd67456 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -852,6 +852,7 @@ void LUA_InvalidateLevel(void) LUA_InvalidateUserdata(&lines[i]); LUA_InvalidateUserdata(&lines[i].tags); LUA_InvalidateUserdata(&lines[i].args); + LUA_InvalidateUserdata(&lines[i].stringargs); LUA_InvalidateUserdata(lines[i].sidenum); } for (i = 0; i < numsides; i++) @@ -894,6 +895,7 @@ void LUA_InvalidateMapthings(void) LUA_InvalidateUserdata(&mapthings[i]); LUA_InvalidateUserdata(&mapthings[i].tags); LUA_InvalidateUserdata(&mapthings[i].args); + LUA_InvalidateUserdata(&mapthings[i].stringargs); } } From 3a49b9519dc0faefa8f6f88d1354ac235b29c6c1 Mon Sep 17 00:00:00 2001 From: Nev3r Date: Tue, 13 Jul 2021 17:55:06 +0200 Subject: [PATCH 564/644] Remove &, since args and stringargs are arrays --- src/lua_script.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lua_script.c b/src/lua_script.c index a7bd67456..9eb1912b3 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -851,8 +851,8 @@ void LUA_InvalidateLevel(void) { LUA_InvalidateUserdata(&lines[i]); LUA_InvalidateUserdata(&lines[i].tags); - LUA_InvalidateUserdata(&lines[i].args); - LUA_InvalidateUserdata(&lines[i].stringargs); + LUA_InvalidateUserdata(lines[i].args); + LUA_InvalidateUserdata(lines[i].stringargs); LUA_InvalidateUserdata(lines[i].sidenum); } for (i = 0; i < numsides; i++) @@ -894,8 +894,8 @@ void LUA_InvalidateMapthings(void) { LUA_InvalidateUserdata(&mapthings[i]); LUA_InvalidateUserdata(&mapthings[i].tags); - LUA_InvalidateUserdata(&mapthings[i].args); - LUA_InvalidateUserdata(&mapthings[i].stringargs); + LUA_InvalidateUserdata(mapthings[i].args); + LUA_InvalidateUserdata(mapthings[i].stringargs); } } From 1c3a898bbbd5539f666b08d085692a356501f219 Mon Sep 17 00:00:00 2001 From: CobaltBW Date: Thu, 15 Jul 2021 12:53:13 -0700 Subject: [PATCH 565/644] Fixed locked characters being visible in multiplayer select screen --- src/r_skins.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_skins.c b/src/r_skins.c index c734b6001..86c0bbc54 100644 --- a/src/r_skins.c +++ b/src/r_skins.c @@ -242,7 +242,7 @@ boolean R_SkinUsable(INT32 playernum, INT32 skinnum) // Force 3. return true; } - if (players[playernum].bot) + if (playernum != -1 && players[playernum].bot) { //Force 4. return true; From 4486ff065af8d6ad3567043af16a58a300aff041 Mon Sep 17 00:00:00 2001 From: CobaltBW Date: Thu, 15 Jul 2021 13:03:26 -0700 Subject: [PATCH 566/644] All remaining player->bot checks modified to rely on BOT_ constants --- src/p_inter.c | 54 +++++++++++++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 7e43c46a8..21e3bfa3d 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -151,7 +151,7 @@ boolean P_CanPickupItem(player_t *player, boolean weapon) if (!player->mo || player->mo->health <= 0) return false; - if (player->bot && player->bot != 3) + if (player->bot && player->bot != BOT_MPAI) { if (weapon) return false; @@ -178,7 +178,7 @@ void P_DoNightsScore(player_t *player) return; // Don't do any fancy shit for failures. dummymo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z+player->mo->height/2, MT_NIGHTSCORE); - if (player->bot && player->bot != 3) + if (player->bot && player->bot != BOT_MPAI) player = &players[consoleplayer]; if (G_IsSpecialStage(gamemap)) // Global link count? Maybe not a good idea... @@ -630,7 +630,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) // ***************************** // // Special Stage Token case MT_TOKEN: - if (player->bot && player->bot != 3) + if (player->bot && player->bot != BOT_MPAI) return; P_AddPlayerScore(player, 1000); @@ -670,7 +670,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) // Emerald Hunt case MT_EMERHUNT: - if (player->bot && player->bot != 3) + if (player->bot && player->bot != BOT_MPAI) return; if (hunt1 == special) @@ -701,7 +701,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) case MT_EMERALD5: case MT_EMERALD6: case MT_EMERALD7: - if (player->bot && player->bot != 3) + if (player->bot && player->bot != BOT_MPAI) return; if (special->threshold) @@ -738,7 +738,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) // Secret emblem thingy case MT_EMBLEM: { - if (demoplayback || (player->bot && player->bot != 3)) + if (demoplayback || (player->bot && player->bot != BOT_MPAI)) return; emblemlocations[special->health-1].collected = true; @@ -751,7 +751,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) // CTF Flags case MT_REDFLAG: case MT_BLUEFLAG: - if (player->bot && player->bot != 3) + if (player->bot && player->bot != BOT_MPAI) return; if (player->powers[pw_flashing] || player->tossdelay) return; @@ -826,7 +826,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) { boolean spec = G_IsSpecialStage(gamemap); boolean cangiveemmy = false; - if (player->bot && player->bot != 3) + if (player->bot && player->bot != BOT_MPAI) return; if (player->exiting) return; @@ -1072,7 +1072,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) } return; case MT_EGGCAPSULE: - if (player->bot && player->bot != 3) + if (player->bot && player->bot != BOT_MPAI) return; // make sure everything is as it should be, THEN take rings from players in special stages @@ -1164,7 +1164,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) } return; case MT_NIGHTSSUPERLOOP: - if ((player->bot && player->bot != 3) || !(player->powers[pw_carry] == CR_NIGHTSMODE)) + if ((player->bot && player->bot != BOT_MPAI) || !(player->powers[pw_carry] == CR_NIGHTSMODE)) return; if (!G_IsSpecialStage(gamemap)) player->powers[pw_nights_superloop] = (UINT16)special->info->speed; @@ -1186,7 +1186,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) } break; case MT_NIGHTSDRILLREFILL: - if ((player->bot && player->bot != 3) || !(player->powers[pw_carry] == CR_NIGHTSMODE)) + if ((player->bot && player->bot != BOT_MPAI) || !(player->powers[pw_carry] == CR_NIGHTSMODE)) return; if (!G_IsSpecialStage(gamemap)) player->drillmeter = special->info->speed; @@ -1208,7 +1208,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) } break; case MT_NIGHTSHELPER: - if ((player->bot && player->bot != 3) || !(player->powers[pw_carry] == CR_NIGHTSMODE)) + if ((player->bot && player->bot != BOT_MPAI) || !(player->powers[pw_carry] == CR_NIGHTSMODE)) return; if (!G_IsSpecialStage(gamemap)) { @@ -1240,7 +1240,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) } break; case MT_NIGHTSEXTRATIME: - if ((player->bot && player->bot != 3) || !(player->powers[pw_carry] == CR_NIGHTSMODE)) + if ((player->bot && player->bot != BOT_MPAI) || !(player->powers[pw_carry] == CR_NIGHTSMODE)) return; if (!G_IsSpecialStage(gamemap)) { @@ -1272,7 +1272,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) } break; case MT_NIGHTSLINKFREEZE: - if ((player->bot && player->bot != 3) || !(player->powers[pw_carry] == CR_NIGHTSMODE)) + if ((player->bot && player->bot != BOT_MPAI) || !(player->powers[pw_carry] == CR_NIGHTSMODE)) return; if (!G_IsSpecialStage(gamemap)) { @@ -1332,7 +1332,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (playeringame[i] && players[i].powers[pw_carry] == CR_NIGHTSMODE) players[i].drillmeter += TICRATE/2; } - else if (player->bot && player->bot != 3) + else if (player->bot && player->bot != BOT_MPAI) players[consoleplayer].drillmeter += TICRATE/2; else player->drillmeter += TICRATE/2; @@ -1385,7 +1385,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) thinker_t *th; mobj_t *mo2; - if (player->bot && player->bot != 3) + if (player->bot && player->bot != BOT_MPAI) return; // Initialize my junk @@ -1423,7 +1423,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; } case MT_FIREFLOWER: - if (player->bot && player->bot != 3) + if (player->bot && player->bot != BOT_MPAI) return; S_StartSound(toucher, sfx_mario3); @@ -1685,7 +1685,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; // Only go in the mouth // Eaten by player! - if ((!player->bot || player->bot == 3) && (player->powers[pw_underwater] && player->powers[pw_underwater] <= 12*TICRATE + 1)) + if ((!player->bot || player->bot == BOT_MPAI) && (player->powers[pw_underwater] && player->powers[pw_underwater] <= 12*TICRATE + 1)) { player->powers[pw_underwater] = underwatertics + 1; P_RestoreMusic(player); @@ -1696,7 +1696,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (!player->climbing) { - if (player->bot && player->bot != 3 && toucher->state-states != S_PLAY_GASP) + if (player->bot && player->bot != BOT_MPAI && toucher->state-states != S_PLAY_GASP) S_StartSound(toucher, special->info->deathsound); // Force it to play a sound for bots P_SetPlayerMobjState(toucher, S_PLAY_GASP); P_ResetPlayer(player); @@ -1704,7 +1704,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) toucher->momx = toucher->momy = toucher->momz = 0; - if (player->bot && player->bot != 3) + if (player->bot && player->bot != BOT_MPAI) return; else break; @@ -1736,7 +1736,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; case MT_MINECARTSPAWNER: - if (!player->bot && player->bot != 3 && special->fuse <= TICRATE && player->powers[pw_carry] != CR_MINECART && !(player->powers[pw_ignorelatch] & (1<<15))) + if (!player->bot && player->bot != BOT_MPAI && special->fuse <= TICRATE && player->powers[pw_carry] != CR_MINECART && !(player->powers[pw_ignorelatch] & (1<<15))) { mobj_t *mcart = P_SpawnMobj(special->x, special->y, special->z, MT_MINECART); P_SetTarget(&mcart->target, toucher); @@ -1789,7 +1789,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) } return; default: // SOC or script pickup - if (player->bot && player->bot != 3) + if (player->bot && player->bot != BOT_MPAI) return; P_SetTarget(&special->target, toucher); break; @@ -1813,7 +1813,7 @@ void P_TouchStarPost(mobj_t *post, player_t *player, boolean snaptopost) mobj_t *toucher = player->mo; mobj_t *checkbase = snaptopost ? post : toucher; - if (player->bot && player->bot != 3) + if (player->bot && player->bot != BOT_MPAI) return; // In circuit, player must have touched all previous starposts if (circuitmap @@ -2555,7 +2555,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget if ((target->player->lives <= 1) && (netgame || multiplayer) && G_GametypeUsesCoopLives() && (cv_cooplives.value == 0)) ; - else if ((!target->player->bot || target->player->bot == 3) && !target->player->spectator && (target->player->lives != INFLIVES) + else if ((!target->player->bot || target->player->bot == BOT_MPAI) && !target->player->spectator && (target->player->lives != INFLIVES) && G_GametypeUsesLives()) { if (!(target->player->pflags & PF_FINISHED)) @@ -3475,7 +3475,7 @@ void P_SpecialStageDamage(player_t *player, mobj_t *inflictor, mobj_t *source) if (inflictor && inflictor->type == MT_LHRT) return; - if (player->powers[pw_shield] || (player->bot && player->bot != 3)) //If One-Hit Shield + if (player->powers[pw_shield] || (player->bot && player->bot != BOT_MPAI)) //If One-Hit Shield { P_RemoveShield(player); S_StartSound(player->mo, sfx_shldls); // Ba-Dum! Shield loss. @@ -3566,7 +3566,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da return false; // Make sure that boxes cannot be popped by enemies, red rings, etc. - if (target->flags & MF_MONITOR && ((!source || !source->player || (source->player->bot && source->player->bot != 3)) + if (target->flags & MF_MONITOR && ((!source || !source->player || (source->player->bot && source->player->bot != BOT_MPAI)) || (inflictor && (inflictor->type == MT_REDRING || (inflictor->type >= MT_THROWNBOUNCE && inflictor->type <= MT_THROWNGRENADE))))) return false; } @@ -3701,7 +3701,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da } else if (LUA_HookMobjDamage(target, inflictor, source, damage, damagetype)) return true; - else if (player->powers[pw_shield] || (player->bot && player->bot != 3 && !ultimatemode)) //If One-Hit Shield + else if (player->powers[pw_shield] || (player->bot && player->bot != BOT_MPAI && !ultimatemode)) //If One-Hit Shield { P_ShieldDamage(player, inflictor, source, damage, damagetype); damage = 0; From 48514ee88d54a5d36a92c2af0fdd1feb587acf2d Mon Sep 17 00:00:00 2001 From: CobaltBW Date: Thu, 15 Jul 2021 15:04:24 -0700 Subject: [PATCH 567/644] Fixed G_RemovePlayer crash in players.iterate This was done by storing flag-for-removal status as a boolean inside the player struct. Bot players are instead removed at the start of G_Ticker, rather than being removed immediately by G_RemovePlayer. --- src/d_player.h | 1 + src/g_game.c | 22 +++++++++++++++++++++- src/lua_baselib.c | 14 ++------------ src/p_saveg.c | 2 ++ 4 files changed, 26 insertions(+), 13 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index 89776fe5e..a0db1402d 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -559,6 +559,7 @@ typedef struct player_s boolean spectator; boolean outofcoop; + boolean removing; UINT8 bot; struct player_s *botleader; UINT16 lastbuttons; diff --git a/src/g_game.c b/src/g_game.c index 0643350b6..4d501f526 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1545,7 +1545,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) cmd->forwardmove = (SINT8)(cmd->forwardmove + forward); cmd->sidemove = (SINT8)(cmd->sidemove + side); - //Note: Majority of botstuffs are handled in G_Ticker now. + // Note: Majority of botstuffs are handled in G_Ticker now. if (player->bot == BOT_2PHUMAN) //Player-controlled bot { G_CopyTiccmd(cmd, I_BaseTiccmd2(), 1); // empty, or external driver @@ -2198,6 +2198,23 @@ void G_Ticker(boolean run) UINT32 i; INT32 buf; + // Bot players queued for removal + for (i = MAXPLAYERS-1; i != UINT32_MAX; i--) + { + if (playeringame[i] && players[i].removing) + { + CL_RemovePlayer(i, i); + if (netgame) + { + char kickmsg[256]; + + strcpy(kickmsg, M_GetText("\x82*Bot %s has been removed")); + strcpy(kickmsg, va(kickmsg, player_names[i], i)); + HU_AddChatText(kickmsg, false); + } + } + } + // see also SCR_DisplayMarathonInfo if ((marathonmode & (MA_INIT|MA_INGAME)) == MA_INGAME && gamestate == GS_LEVEL) marathontime++; @@ -2520,6 +2537,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) tic_t quittime; boolean spectator; boolean outofcoop; + boolean removing; INT16 bot; SINT8 pity; INT16 rings; @@ -2536,6 +2554,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) quittime = players[player].quittime; spectator = players[player].spectator; outofcoop = players[player].outofcoop; + removing = players[player].removing; pflags = (players[player].pflags & (PF_FLIPCAM|PF_ANALOGMODE|PF_DIRECTIONCHAR|PF_AUTOBRAKE|PF_TAGIT|PF_GAMETYPEOVER)); playerangleturn = players[player].angleturn; oldrelangleturn = players[player].oldrelangleturn; @@ -2612,6 +2631,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) p->quittime = quittime; p->spectator = spectator; p->outofcoop = outofcoop; + p->removing = removing; p->angleturn = playerangleturn; p->oldrelangleturn = oldrelangleturn; diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 9946a9fd3..9e01a98c0 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -3482,24 +3482,14 @@ static int lib_gAddPlayer(lua_State *L) static int lib_gRemovePlayer(lua_State *L) { UINT8 pnum = -1; - //const char *kickreason = luaL_checkstring(L, 2); if (!lua_isnoneornil(L, 1)) pnum = luaL_checkinteger(L, 1); if (&players[pnum]) { - if (players[pnum].bot != BOT_NONE) + if (players[pnum].bot != BOT_NONE && players[pnum].removing == false) { -// CL_RemovePlayer(pnum, *kickreason); - CL_RemovePlayer(pnum, pnum); - if (netgame) - { - char kickmsg[256]; - - strcpy(kickmsg, M_GetText("\x82*Bot %s has been removed")); - strcpy(kickmsg, va(kickmsg, player_names[pnum], pnum)); - HU_AddChatText(kickmsg, false); - } + players[pnum].removing = true; // This function can be run in players.iterate(), which isn't equipped to deal with players being removed mid-process. Instead we'll remove the player at the beginning of the next ticframe. lua_pushboolean(L, true); return 1; } diff --git a/src/p_saveg.c b/src/p_saveg.c index 7e9d7b6d4..1270064c0 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -201,6 +201,7 @@ static void P_NetArchivePlayers(void) WRITEUINT8(save_p, players[i].botmem.lastBlocked); WRITEUINT8(save_p, players[i].botmem.catchup_tics); WRITEUINT8(save_p, players[i].botmem.thinkstate); + WRITEUINT8(save_p, players[i].removing); WRITEUINT8(save_p, players[i].blocked); WRITEUINT16(save_p, players[i].lastbuttons); @@ -428,6 +429,7 @@ static void P_NetUnArchivePlayers(void) players[i].botmem.lastBlocked = READUINT8(save_p); players[i].botmem.catchup_tics = READUINT8(save_p); players[i].botmem.thinkstate = READUINT8(save_p); + players[i].removing = READUINT8(save_p); players[i].blocked = READUINT8(save_p); players[i].lastbuttons = READUINT16(save_p); From 22f42efb61e242a75a017712d6b753149c3a91ce Mon Sep 17 00:00:00 2001 From: CobaltBW Date: Thu, 15 Jul 2021 15:09:02 -0700 Subject: [PATCH 568/644] Cleaned up leftover comments --- src/b_bot.c | 4 ---- src/g_game.c | 2 +- src/p_mobj.c | 1 - src/p_user.c | 29 ++++++----------------------- 4 files changed, 7 insertions(+), 29 deletions(-) diff --git a/src/b_bot.c b/src/b_bot.c index c61e56f5f..6f4b0ce15 100644 --- a/src/b_bot.c +++ b/src/b_bot.c @@ -102,7 +102,6 @@ static void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd) if (tails->player->powers[pw_carry] == CR_MACESPIN || tails->player->powers[pw_carry] == CR_GENERIC) { boolean isrelevant = (sonic->player->powers[pw_carry] == CR_MACESPIN || sonic->player->powers[pw_carry] == CR_GENERIC); - //dist = P_AproxDistance(tails->x-sonic->x, tails->y-sonic->y); //! This is totally redundant. if (sonic->player->cmd.buttons & BT_JUMP && (sonic->player->pflags & PF_JUMPED) && isrelevant) cmd->buttons |= BT_JUMP; if (isrelevant) @@ -402,8 +401,6 @@ void B_KeysToTiccmd(mobj_t *mo, ticcmd_t *cmd, boolean forward, boolean backward { player_t *player = mo->player; // don't try to do stuff if your sonic is in a minecart or something - //if (players[consoleplayer].powers[pw_carry] && players[consoleplayer].powers[pw_carry] != CR_PLAYER) - //!!! if (&player->botleader && player->botleader->powers[pw_carry] && player->botleader->powers[pw_carry] != CR_PLAYER) return; // Turn the virtual keypresses into ticcmd_t. @@ -576,7 +573,6 @@ void B_RespawnBot(INT32 playernum) player->powers[pw_spacetime] = sonic->player->powers[pw_spacetime]; player->powers[pw_gravityboots] = sonic->player->powers[pw_gravityboots]; player->powers[pw_nocontrol] = sonic->player->powers[pw_nocontrol]; - //!!! Nuke the speed equivalencies player->pflags |= PF_AUTOBRAKE|(sonic->player->pflags & PF_DIRECTIONCHAR); P_TeleportMove(tails, x, y, z); diff --git a/src/g_game.c b/src/g_game.c index 4d501f526..8cdeaf079 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3025,7 +3025,7 @@ void G_DoReborn(INT32 playernum) // Make sure objectplace is OFF when you first start the level! OP_ResetObjectplace(); - //! Tailsbot + // Tailsbot if (player->bot == BOT_2PAI || player->bot == BOT_2PHUMAN) { // Bots respawn next to their master. mobj_t *oldmo = NULL; diff --git a/src/p_mobj.c b/src/p_mobj.c index 4924ec053..8af7ab0d0 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1839,7 +1839,6 @@ void P_XYMovement(mobj_t *mo) // blocked move moved = false; - //!!! if (player) B_MoveBlocked(player); diff --git a/src/p_user.c b/src/p_user.c index dadc23193..b3535623c 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -776,7 +776,7 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) { UINT8 oldmare, oldmarelap, oldmarebonuslap; - //! Bots can't be NiGHTSerized, silly!1 :P + // Bots can't be NiGHTSerized, silly!1 :P if (player->bot == BOT_2PAI || player->bot == BOT_2PHUMAN) return; @@ -1188,7 +1188,7 @@ void P_GivePlayerRings(player_t *player, INT32 num_rings) { if (!player) return; - //! + if ((player->bot == BOT_2PAI || player->bot == BOT_2PHUMAN) && player->botleader) player = player->botleader; @@ -5965,23 +5965,6 @@ static void P_3dMovement(player_t *player) acceleration = 96 + (FixedDiv(player->speed, player->mo->scale)>>FRACBITS) * 40; topspeed = normalspd; } - //! Kill this! - /* else if (player->bot == BOT_2PAI || player->bot == BOT_2PHUMAN) - { // Bot steals player 1's stats - normalspd = FixedMul(players[consoleplayer].normalspeed, player->mo->scale); - thrustfactor = players[consoleplayer].thrustfactor; - acceleration = players[consoleplayer].accelstart + (FixedDiv(player->speed, player->mo->scale)>>FRACBITS) * players[consoleplayer].acceleration; - - if (player->powers[pw_tailsfly]) - topspeed = normalspd/2; - else if (player->mo->eflags & (MFE_UNDERWATER|MFE_GOOWATER)) - { - topspeed = normalspd/2; - acceleration = 2*acceleration/3; - } - else - topspeed = normalspd; - } */ else { if (player->powers[pw_super] || player->powers[pw_sneakers]) @@ -11488,7 +11471,7 @@ void P_PlayerThink(player_t *player) I_Error("p_playerthink: players[%s].mo == NULL", sizeu1(playeri)); #endif - //! Reset terrain blocked status for this frame + // Reset terrain blocked status for this frame player->blocked = false; // todo: Figure out what is actually causing these problems in the first place... @@ -11641,7 +11624,7 @@ void P_PlayerThink(player_t *player) INT32 i; for (i = 0; i < MAXPLAYERS; i++) - { //! + { if (!playeringame[i] || players[i].spectator || players[i].bot == BOT_2PAI || players[i].bot == BOT_2PHUMAN) continue; if (players[i].lives <= 0) @@ -11673,7 +11656,7 @@ void P_PlayerThink(player_t *player) INT32 i, total = 0, exiting = 0; for (i = 0; i < MAXPLAYERS; i++) - { //! + { if (!playeringame[i] || players[i].spectator || players[i].bot == BOT_2PAI || players[i].bot == BOT_2PHUMAN) continue; if (players[i].quittime > 30 * TICRATE) @@ -12614,7 +12597,7 @@ void P_PlayerAfterThink(player_t *player) player->mo->momy = tails->momy; player->mo->momz = tails->momz; } - //! + if (G_CoopGametype() && tails->player && tails->player->bot != BOT_2PAI) { player->mo->angle = tails->angle; From 95359fef5142d1dce33ebce35b18d13846e2ca56 Mon Sep 17 00:00:00 2001 From: CobaltBW Date: Thu, 15 Jul 2021 15:19:47 -0700 Subject: [PATCH 569/644] Amendment to G_RemovePlayer to preserve lua error handlers --- src/lua_baselib.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 9e01a98c0..f287fb78c 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -3482,20 +3482,25 @@ static int lib_gAddPlayer(lua_State *L) static int lib_gRemovePlayer(lua_State *L) { UINT8 pnum = -1; - if (!lua_isnoneornil(L, 1)) pnum = luaL_checkinteger(L, 1); - if (&players[pnum]) + else // No argument + return luaL_error(L, "argument #1 not given (expected number)"); + if (pnum >= MAXPLAYERS) // Out of range + return luaL_error(L, "playernum %d out of range (0 - %d)", pnum, MAXPLAYERS-1); + if (playeringame[pnum]) // Found player { - if (players[pnum].bot != BOT_NONE && players[pnum].removing == false) + if (players[pnum].bot == BOT_NONE) // Can't remove clients. + return luaL_error(L, "G_RemovePlayer can only be used on players with a bot value other than BOT_NONE."); + else { - players[pnum].removing = true; // This function can be run in players.iterate(), which isn't equipped to deal with players being removed mid-process. Instead we'll remove the player at the beginning of the next ticframe. + players[pnum].removing = true; lua_pushboolean(L, true); return 1; } } - lua_pushboolean(L, false); - return 1; + // Fell through. Invalid player + return LUA_ErrInvalid(L, "player_t"); } From 71f905f95bd4fe62dbca87208cf71b7309f12de1 Mon Sep 17 00:00:00 2001 From: SteelT Date: Fri, 16 Jul 2021 15:26:09 -0400 Subject: [PATCH 570/644] Fix gme support being effectively disabled I found this easier than trying to adjust the makefile, as it uses the same thing to automatically generate the various NO* compile options. --- src/CMakeLists.txt | 2 +- src/sdl/mixer_sound.c | 46 +++++++++++++++++++++---------------------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 721cd6dca..ae93aac37 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -60,7 +60,7 @@ if(${SRB2_CONFIG_HAVE_GME}) endif() if(${GME_FOUND}) set(SRB2_HAVE_GME ON) - target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_LIBGME) + target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_GME) else() message(WARNING "You have specified that GME is available but it was not found.") endif() diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index 2f1a87266..35a79acc0 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -9,7 +9,7 @@ /// \file /// \brief SDL Mixer interface for sound -#ifdef HAVE_LIBGME +#ifdef HAVE_GME #ifdef HAVE_ZLIB #ifndef _MSC_VER #ifndef _LARGEFILE64_SOURCE @@ -27,7 +27,7 @@ #include #endif // HAVE_ZLIB -#endif // HAVE_LIBGME +#endif // HAVE_GME #include "../doomdef.h" #include "../doomstat.h" // menuactive @@ -73,11 +73,11 @@ #define MUS_MODPLUG MUS_MODPLUG_UNUSED #endif -#ifdef HAVE_LIBGME +#ifdef HAVE_GME #include "gme/gme.h" #define GME_TREBLE 5.0f #define GME_BASS 1.0f -#endif // HAVE_LIBGME +#endif // HAVE_GME static UINT16 BUFFERSIZE = 2048; static UINT16 SAMPLERATE = 44100; @@ -110,7 +110,7 @@ static INT32 fading_id; static void (*fading_callback)(void); static boolean fading_nocleanup; -#ifdef HAVE_LIBGME +#ifdef HAVE_GME static Music_Emu *gme; static UINT16 current_track; #endif @@ -220,7 +220,7 @@ static void var_cleanup(void) internal_volume = 100; } -#if defined (HAVE_LIBGME) && defined (HAVE_ZLIB) +#if defined (HAVE_GME) && defined (HAVE_ZLIB) static const char* get_zlib_error(int zErr) { switch (zErr) @@ -318,7 +318,7 @@ void I_ShutdownSound(void) SDL_QuitSubSystem(SDL_INIT_AUDIO); -#ifdef HAVE_LIBGME +#ifdef HAVE_GME if (gme) gme_delete(gme); #endif @@ -453,7 +453,7 @@ void *I_GetSfx(sfxinfo_t *sfx) void *lump; Mix_Chunk *chunk; SDL_RWops *rw; -#ifdef HAVE_LIBGME +#ifdef HAVE_GME Music_Emu *emu; gme_info_t *info; #endif @@ -473,7 +473,7 @@ void *I_GetSfx(sfxinfo_t *sfx) } // Not a doom sound? Try something else. -#ifdef HAVE_LIBGME +#ifdef HAVE_GME // VGZ format if (((UINT8 *)lump)[0] == 0x1F && ((UINT8 *)lump)[1] == 0x8B) @@ -729,7 +729,7 @@ static UINT32 music_fade(UINT32 interval, void *param) } } -#ifdef HAVE_LIBGME +#ifdef HAVE_GME static void mix_gme(void *udata, Uint8 *stream, int len) { int i; @@ -797,7 +797,7 @@ void I_ShutdownMusic(void) musictype_t I_SongType(void) { -#ifdef HAVE_LIBGME +#ifdef HAVE_GME if (gme) return MU_GME; else @@ -828,7 +828,7 @@ musictype_t I_SongType(void) boolean I_SongPlaying(void) { return ( -#ifdef HAVE_LIBGME +#ifdef HAVE_GME (I_SongType() == MU_GME && gme) || #endif #ifdef HAVE_OPENMPT @@ -851,7 +851,7 @@ boolean I_SetSongSpeed(float speed) { if (speed > 250.0f) speed = 250.0f; //limit speed up to 250x -#ifdef HAVE_LIBGME +#ifdef HAVE_GME if (gme) { SDL_LockAudio(); @@ -893,7 +893,7 @@ UINT32 I_GetSongLength(void) { INT32 length; -#ifdef HAVE_LIBGME +#ifdef HAVE_GME if (gme) { gme_info_t *info; @@ -963,7 +963,7 @@ boolean I_SetSongLoopPoint(UINT32 looppoint) UINT32 I_GetSongLoopPoint(void) { -#ifdef HAVE_LIBGME +#ifdef HAVE_GME if (gme) { INT32 looppoint; @@ -992,7 +992,7 @@ UINT32 I_GetSongLoopPoint(void) boolean I_SetSongPosition(UINT32 position) { UINT32 length; -#ifdef HAVE_LIBGME +#ifdef HAVE_GME if (gme) { // this is unstable, so fail silently @@ -1055,7 +1055,7 @@ boolean I_SetSongPosition(UINT32 position) UINT32 I_GetSongPosition(void) { -#ifdef HAVE_LIBGME +#ifdef HAVE_GME if (gme) { INT32 position = gme_tell(gme); @@ -1124,7 +1124,7 @@ boolean I_LoadSong(char *data, size_t len) SDL_RWops *rw; if (music -#ifdef HAVE_LIBGME +#ifdef HAVE_GME || gme #endif #ifdef HAVE_OPENMPT @@ -1136,7 +1136,7 @@ boolean I_LoadSong(char *data, size_t len) // always do this whether or not a music already exists var_cleanup(); -#ifdef HAVE_LIBGME +#ifdef HAVE_GME if ((UINT8)data[0] == 0x1F && (UINT8)data[1] == 0x8B) { @@ -1271,7 +1271,7 @@ void I_UnloadSong(void) { I_StopSong(); -#ifdef HAVE_LIBGME +#ifdef HAVE_GME if (gme) { gme_delete(gme); @@ -1294,7 +1294,7 @@ void I_UnloadSong(void) boolean I_PlaySong(boolean looping) { -#ifdef HAVE_LIBGME +#ifdef HAVE_GME if (gme) { gme_equalizer_t eq = {GME_TREBLE, GME_BASS, 0,0,0,0,0,0,0,0}; @@ -1360,7 +1360,7 @@ void I_StopSong(void) if (!fading_nocleanup) I_StopFadingSong(); -#ifdef HAVE_LIBGME +#ifdef HAVE_GME if (gme) { Mix_HookMusic(NULL, NULL); @@ -1433,7 +1433,7 @@ void I_SetMusicVolume(UINT8 volume) boolean I_SetSongTrack(int track) { -#ifdef HAVE_LIBGME +#ifdef HAVE_GME // If the specified track is within the number of tracks playing, then change it if (gme) { From 58db5a6904943ef944f76ca45d260a1bc123463f Mon Sep 17 00:00:00 2001 From: Radicalicious Date: Wed, 28 Jul 2021 15:42:44 +0000 Subject: [PATCH 571/644] Fix P_PlayerInPain crash. --- src/p_user.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/p_user.c b/src/p_user.c index c5f919c78..f3ebc7dff 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -969,6 +969,9 @@ pflags_t P_GetJumpFlags(player_t *player) // boolean P_PlayerInPain(player_t *player) { + // If the player doesn't have a mobj, it can't be in pain. + if !(player->mo) + return false; // no silly, sliding isn't pain if (!(player->pflags & PF_SLIDING) && player->mo->state == &states[player->mo->info->painstate] && player->powers[pw_flashing]) return true; From d50e3bff70f1ac28fc74e85f8e93642a979f0b52 Mon Sep 17 00:00:00 2001 From: Radicalicious Date: Thu, 29 Jul 2021 15:55:19 +0000 Subject: [PATCH 572/644] ACTUALLY fix the issue. --- src/p_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index f3ebc7dff..740688b45 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -970,7 +970,7 @@ pflags_t P_GetJumpFlags(player_t *player) boolean P_PlayerInPain(player_t *player) { // If the player doesn't have a mobj, it can't be in pain. - if !(player->mo) + if (!player->mo) return false; // no silly, sliding isn't pain if (!(player->pflags & PF_SLIDING) && player->mo->state == &states[player->mo->info->painstate] && player->powers[pw_flashing]) From 7dddc631d798469725e40bd3fbc1a2617f4982ee Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 31 Jul 2021 21:14:48 +0100 Subject: [PATCH 573/644] P_ZMovement: add a P_MobjWasRemoved check after P_CheckPosition, so we can bail out if the mobj was removed (by Lua most likely) --- src/p_mobj.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/p_mobj.c b/src/p_mobj.c index 10220fff6..3bb7ac58d 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -2549,6 +2549,10 @@ boolean P_ZMovement(mobj_t *mo) } P_CheckPosition(mo, mo->x, mo->y); // Sets mo->standingslope correctly + + if (P_MobjWasRemoved(mobj)) // mobjs can be removed by P_CheckPosition -- Monster Iestyn 31/07/21 + return false; + if (((mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope) && (mo->type != MT_STEAM)) { mo->standingslope = (mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope; From df99cde40ffd1163cfec164e72f7b5d3b31261cb Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 31 Jul 2021 22:11:44 +0100 Subject: [PATCH 574/644] mo not mobj! --- src/p_mobj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 3bb7ac58d..da7385be5 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -2550,7 +2550,7 @@ boolean P_ZMovement(mobj_t *mo) P_CheckPosition(mo, mo->x, mo->y); // Sets mo->standingslope correctly - if (P_MobjWasRemoved(mobj)) // mobjs can be removed by P_CheckPosition -- Monster Iestyn 31/07/21 + if (P_MobjWasRemoved(mo)) // mobjs can be removed by P_CheckPosition -- Monster Iestyn 31/07/21 return false; if (((mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope) && (mo->type != MT_STEAM)) From 2d218859ff4f879ee13fbf3e45d6dc890be9012a Mon Sep 17 00:00:00 2001 From: SMS Alfredo <65426124+SMS-Alfredo@users.noreply.github.com> Date: Fri, 6 Aug 2021 23:25:19 -0500 Subject: [PATCH 575/644] Give coins a drop shadow --- src/p_mobj.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/p_mobj.c b/src/p_mobj.c index da7385be5..c7e0a7909 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10391,6 +10391,9 @@ static fixed_t P_DefaultMobjShadowScale (mobj_t *thing) case MT_RING: case MT_FLINGRING: + + case MT_COIN: + case MT_FLINGCOIN: case MT_BLUESPHERE: case MT_FLINGBLUESPHERE: From d1e8b05749447da3c7944d852b0484c6c9dc3842 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sun, 8 Aug 2021 19:43:42 +0200 Subject: [PATCH 576/644] Don't call map load trigger linedefs when joining or reloading gamestate --- src/p_spec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/p_spec.c b/src/p_spec.c index 4b566acfb..e5e546b7a 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -7102,7 +7102,8 @@ void P_SpawnSpecials(boolean fromnetsave) } } - P_RunLevelLoadExecutors(); + if (!fromnetsave) + P_RunLevelLoadExecutors(); } /** Adds 3Dfloors as appropriate based on a common control linedef. From a9b35a6f7a68d7dfd2e0df907b628f8bc3135a1f Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Tue, 10 Aug 2021 00:15:44 +0200 Subject: [PATCH 577/644] Fix incorrect error message during Lua archiving --- src/lua_script.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/lua_script.c b/src/lua_script.c index 9eb1912b3..25e0a8f37 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -1384,21 +1384,13 @@ static void ArchiveTables(void) // Write key e = ArchiveValue(TABLESINDEX, -2); // key should be either a number or a string, ArchiveValue can handle this. if (e == 2) // invalid key type (function, thread, lightuserdata, or anything we don't recognise) - { - lua_pushvalue(gL, -2); - CONS_Alert(CONS_ERROR, "Index '%s' (%s) of table %d could not be archived!\n", lua_tostring(gL, -1), luaL_typename(gL, -1), i); - lua_pop(gL, 1); - } + CONS_Alert(CONS_ERROR, "Index '%s' (%s) of table %d could not be archived!\n", lua_tostring(gL, -2), luaL_typename(gL, -2), i); // Write value e = ArchiveValue(TABLESINDEX, -1); if (e == 1) n++; // the table contained a new table we'll have to archive. :( else if (e == 2) // invalid value type - { - lua_pushvalue(gL, -2); CONS_Alert(CONS_ERROR, "Type of value for table %d entry '%s' (%s) could not be archived!\n", i, lua_tostring(gL, -1), luaL_typename(gL, -1)); - lua_pop(gL, 1); - } lua_pop(gL, 1); } From 6403a38c72cfdb57a25ccd380037034eb831fcff Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Tue, 10 Aug 2021 01:48:26 +0200 Subject: [PATCH 578/644] Fix again --- src/lua_script.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lua_script.c b/src/lua_script.c index 25e0a8f37..bf262c065 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -1390,7 +1390,7 @@ static void ArchiveTables(void) if (e == 1) n++; // the table contained a new table we'll have to archive. :( else if (e == 2) // invalid value type - CONS_Alert(CONS_ERROR, "Type of value for table %d entry '%s' (%s) could not be archived!\n", i, lua_tostring(gL, -1), luaL_typename(gL, -1)); + CONS_Alert(CONS_ERROR, "Type of value for table %d entry '%s' (%s) could not be archived!\n", i, lua_tostring(gL, -2), luaL_typename(gL, -1)); lua_pop(gL, 1); } From 15b7221c7895d05103239a08c34ac1ff890ad000 Mon Sep 17 00:00:00 2001 From: litten Date: Thu, 12 Aug 2021 12:39:28 -0500 Subject: [PATCH 579/644] modified: debian-template/rules --- debian-template/rules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian-template/rules b/debian-template/rules index 0a77624cb..12ceaf98b 100644 --- a/debian-template/rules +++ b/debian-template/rules @@ -78,7 +78,7 @@ NONX86 = $(shell test "`echo $(CROSS_COMPILE_HOST) | grep 'i[3-6]86'`" || echo " MAKEARGS = $(OS) $(NONX86) $(PREFIX) EXENAME=$(EXENAME) DBGNAME=$(DBGNAME) NOOBJDUMP=1 # SDL_PKGCONFIG=sdl2 PNG_PKGCONFIG=libpng MENUFILE1 = ?package($(PACKAGE)):needs="X11" section="$(SECTION)" MENUFILE2 = title="$(TITLE)" command="/$(PKGDIR)/$(PACKAGE)" -BINDIR := $(DIR)/bin/Linux/Release +BINDIR := $(DIR)/bin/ # FIXME pkg-config dir hacks # Launchpad doesn't need this; it actually makes i386 builds fail due to cross-compile From 8adf4b672acc12b6726192be980f18e30e70624f Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Fri, 13 Aug 2021 21:58:34 +0200 Subject: [PATCH 580/644] Put Lua input library in its own namespace --- src/lua_inputlib.c | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/src/lua_inputlib.c b/src/lua_inputlib.c index 71eb1033f..7ad265eff 100644 --- a/src/lua_inputlib.c +++ b/src/lua_inputlib.c @@ -127,19 +127,19 @@ static int lib_getCursorPosition(lua_State *L) } static luaL_Reg lib[] = { - {"G_GameControlDown", lib_gameControlDown}, - {"G_GameControl2Down", lib_gameControl2Down}, - {"G_GameControlToKeyNum", lib_gameControlToKeyNum}, - {"G_GameControl2ToKeyNum", lib_gameControl2ToKeyNum}, - {"G_JoyAxis", lib_joyAxis}, - {"G_Joy2Axis", lib_joy2Axis}, - {"G_KeyNumToString", lib_keyNumToString}, - {"G_KeyStringToNum", lib_keyStringToNum}, - {"HU_KeyNumPrintable", lib_keyNumPrintable}, - {"HU_ShiftKeyNum", lib_shiftKeyNum}, - {"I_GetMouseGrab", lib_getMouseGrab}, - {"I_SetMouseGrab", lib_setMouseGrab}, - {"I_GetCursorPosition", lib_getCursorPosition}, + {"gameControlDown", lib_gameControlDown}, + {"gameControl2Down", lib_gameControl2Down}, + {"gameControlToKeyNum", lib_gameControlToKeyNum}, + {"gameControl2ToKeyNum", lib_gameControl2ToKeyNum}, + {"joyAxis", lib_joyAxis}, + {"joy2Axis", lib_joy2Axis}, + {"keyNumToString", lib_keyNumToString}, + {"keyStringToNum", lib_keyStringToNum}, + {"keyNumPrintable", lib_keyNumPrintable}, + {"shiftKeyNum", lib_shiftKeyNum}, + {"getMouseGrab", lib_getMouseGrab}, + {"setMouseGrab", lib_setMouseGrab}, + {"getCursorPosition", lib_getCursorPosition}, {NULL, NULL} }; @@ -235,8 +235,6 @@ int LUA_InputLib(lua_State *L) lua_setfield(L, -2, "__len"); lua_pop(L, 1); - // Set global functions - lua_pushvalue(L, LUA_GLOBALSINDEX); - luaL_register(L, NULL, lib); + luaL_register(L, "input", lib); return 0; } From 38e82e55fcf39ccd0e4d2316839e502958ba76cf Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sat, 14 Aug 2021 20:33:20 +0200 Subject: [PATCH 581/644] Add a "repeated" field to event_t --- src/d_event.h | 1 + src/sdl/i_system.c | 4 ++-- src/sdl/i_video.c | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/d_event.h b/src/d_event.h index 1fd2e3824..70b55c328 100644 --- a/src/d_event.h +++ b/src/d_event.h @@ -36,6 +36,7 @@ typedef struct INT32 data1; // keys / mouse/joystick buttons INT32 data2; // mouse/joystick x move INT32 data3; // mouse/joystick y move + boolean repeated; // key repeat } event_t; // diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index d68e3e435..1594c8d61 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -1012,7 +1012,7 @@ void I_ShutdownJoystick(void) void I_GetJoystickEvents(void) { - static event_t event = {0,0,0,0}; + static event_t event = {0,0,0,0,false}; INT32 i = 0; UINT64 joyhats = 0; #if 0 @@ -1282,7 +1282,7 @@ void I_ShutdownJoystick2(void) void I_GetJoystick2Events(void) { - static event_t event = {0,0,0,0}; + static event_t event = {0,0,0,0,false}; INT32 i = 0; UINT64 joyhats = 0; #if 0 diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 819589eaf..1f4b866c1 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -664,6 +664,7 @@ static void Impl_HandleKeyboardEvent(SDL_KeyboardEvent evt, Uint32 type) return; } event.data1 = Impl_SDL_Scancode_To_Keycode(evt.keysym.scancode); + event.repeated = (evt.repeat != 0); if (event.data1) D_PostEvent(&event); } From 5b949a6751c34a939a3aa6cef3cdb7d0dfc2f181 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sat, 14 Aug 2021 20:33:42 +0200 Subject: [PATCH 582/644] Expose keyevent_t to Lua --- src/lua_inputlib.c | 28 ++++++++++++++++++++++++++++ src/lua_libs.h | 1 + 2 files changed, 29 insertions(+) diff --git a/src/lua_inputlib.c b/src/lua_inputlib.c index 7ad265eff..01ad9af3c 100644 --- a/src/lua_inputlib.c +++ b/src/lua_inputlib.c @@ -172,6 +172,29 @@ static int lib_lenGameKeyDown(lua_State *L) return 1; } +/////////////// +// KEY EVENT // +/////////////// + +static int keyevent_get(lua_State *L) +{ + event_t *event = *((event_t **)luaL_checkudata(L, 1, META_KEYEVENT)); + const char *field = luaL_checkstring(L, 2); + + I_Assert(event != NULL); + + if (fastcmp(field,"name")) + lua_pushstring(L, G_KeyNumToString(event->data1)); + else if (fastcmp(field,"num")) + lua_pushinteger(L, event->data1); + else if (fastcmp(field,"repeated")) + lua_pushboolean(L, event->repeated); + else + return luaL_error(L, "keyevent_t has no field named %s", field); + + return 1; +} + /////////// // MOUSE // /////////// @@ -227,6 +250,11 @@ int LUA_InputLib(lua_State *L) lua_setmetatable(L, -2); lua_setglobal(L, "gamekeydown"); + luaL_newmetatable(L, META_KEYEVENT); + lua_pushcfunction(L, keyevent_get); + lua_setfield(L, -2, "__index"); + lua_pop(L, 1); + luaL_newmetatable(L, META_MOUSE); lua_pushcfunction(L, mouse_get); lua_setfield(L, -2, "__index"); diff --git a/src/lua_libs.h b/src/lua_libs.h index 668eb99b0..de174283c 100644 --- a/src/lua_libs.h +++ b/src/lua_libs.h @@ -88,6 +88,7 @@ extern lua_State *gL; #define META_LUABANKS "LUABANKS[]*" +#define META_KEYEVENT "KEYEVENT_T*" #define META_MOUSE "MOUSE_T*" boolean luaL_checkboolean(lua_State *L, int narg); From c2907b89f703a4e09cf236907b9be28c28242b54 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sat, 14 Aug 2021 20:34:59 +0200 Subject: [PATCH 583/644] Pass a keyevent_t userdatum to key hooks --- src/g_game.c | 18 +++++++++++++++--- src/lua_hook.h | 3 ++- src/lua_hooklib.c | 4 ++-- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 13fdab877..a35d89aa1 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -45,6 +45,7 @@ #include "lua_hook.h" #include "b_bot.h" #include "m_cond.h" // condition sets +#include "lua_script.h" #include "lua_hud.h" @@ -2194,8 +2195,20 @@ boolean G_Responder(event_t *ev) // boolean G_LuaResponder(event_t *ev) { - return (ev->type == ev_keydown && LUA_HookKey(ev->data1, HOOK(KeyDown))) || - (ev->type == ev_keyup && LUA_HookKey(ev->data1, HOOK(KeyUp))); + boolean cancelled = false; + + if (ev->type == ev_keydown) + { + cancelled = LUA_HookKey(ev, HOOK(KeyDown)); + LUA_InvalidateUserdata(ev); + } + else if (ev->type == ev_keyup) + { + cancelled = LUA_HookKey(ev, HOOK(KeyUp)); + LUA_InvalidateUserdata(ev); + } + + return cancelled; } // @@ -5240,4 +5253,3 @@ INT32 G_TicsToMilliseconds(tic_t tics) { return (INT32)((tics%TICRATE) * (1000.00f/TICRATE)); } - diff --git a/src/lua_hook.h b/src/lua_hook.h index 223b83c61..55f3bb817 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -13,6 +13,7 @@ #include "r_defs.h" #include "d_player.h" #include "s_sound.h" +#include "d_event.h" /* Do you know what an 'X Macro' is? Such a macro is called over each element of @@ -107,7 +108,7 @@ void LUA_HookInt(INT32 integer, int hook); void LUA_HookBool(boolean value, int hook); int LUA_HookPlayer(player_t *, int hook); int LUA_HookTiccmd(player_t *, ticcmd_t *, int hook); -int LUA_HookKey(INT32 keycode, int hook); // Hooks for key events +int LUA_HookKey(event_t *event, int hook); // Hooks for key events void LUA_HookThinkFrame(void); int LUA_HookMobjLineCollide(mobj_t *, line_t *); diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index d1b0d3bdd..1e0462126 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -588,12 +588,12 @@ int LUA_HookTiccmd(player_t *player, ticcmd_t *cmd, int hook_type) return hook.status; } -int LUA_HookKey(INT32 keycode, int hook_type) +int LUA_HookKey(event_t *event, int hook_type) { Hook_State hook; if (prepare_hook(&hook, false, hook_type)) { - lua_pushinteger(gL, keycode); + LUA_PushUserdata(gL, event, META_KEYEVENT); call_hooks(&hook, 1, 1, res_true); } return hook.status; From 5bc0ce7a62c816e33e6d2a7ddc4b4b1360fd9df4 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sat, 14 Aug 2021 23:42:39 +0200 Subject: [PATCH 584/644] Give fields in event_t better names --- src/am_map.c | 6 +- src/console.c | 4 +- src/d_event.h | 6 +- src/d_main.c | 14 +-- src/f_finale.c | 6 +- src/g_game.c | 20 ++--- src/g_input.c | 32 +++---- src/hu_stuff.c | 18 ++-- src/lua_inputlib.c | 4 +- src/m_cheat.c | 6 +- src/m_menu.c | 34 ++++---- src/m_misc.c | 2 +- src/sdl/i_system.c | 108 +++++++++++------------ src/sdl/i_video.c | 46 +++++----- src/win32/win_main.c | 24 ++--- src/win32/win_sys.c | 202 +++++++++++++++++++++---------------------- 16 files changed, 266 insertions(+), 266 deletions(-) diff --git a/src/am_map.c b/src/am_map.c index ef0ebb88c..24379e2f1 100644 --- a/src/am_map.c +++ b/src/am_map.c @@ -458,7 +458,7 @@ boolean AM_Responder(event_t *ev) { if (!automapactive) { - if (ev->type == ev_keydown && ev->data1 == AM_TOGGLEKEY) + if (ev->type == ev_keydown && ev->key == AM_TOGGLEKEY) { //faB: prevent alt-tab in win32 version to activate automap just before // minimizing the app; doesn't do any harm to the DOS version @@ -473,7 +473,7 @@ boolean AM_Responder(event_t *ev) else if (ev->type == ev_keydown) { rc = true; - switch (ev->data1) + switch (ev->key) { case AM_PANRIGHTKEY: // pan right if (!followplayer) @@ -550,7 +550,7 @@ boolean AM_Responder(event_t *ev) else if (ev->type == ev_keyup) { rc = false; - switch (ev->data1) + switch (ev->key) { case AM_PANRIGHTKEY: if (!followplayer) diff --git a/src/console.c b/src/console.c index b3c413840..7941e1dbb 100644 --- a/src/console.c +++ b/src/console.c @@ -913,12 +913,12 @@ boolean CON_Responder(event_t *ev) // let go keyup events, don't eat them if (ev->type != ev_keydown && ev->type != ev_console) { - if (ev->data1 == gamecontrol[gc_console][0] || ev->data1 == gamecontrol[gc_console][1]) + if (ev->key == gamecontrol[gc_console][0] || ev->key == gamecontrol[gc_console][1]) consdown = false; return false; } - key = ev->data1; + key = ev->key; // check for console toggle key if (ev->type != ev_console) diff --git a/src/d_event.h b/src/d_event.h index 70b55c328..c30a8ced2 100644 --- a/src/d_event.h +++ b/src/d_event.h @@ -33,9 +33,9 @@ typedef enum typedef struct { evtype_t type; - INT32 data1; // keys / mouse/joystick buttons - INT32 data2; // mouse/joystick x move - INT32 data3; // mouse/joystick y move + INT32 key; // keys/mouse/joystick buttons + INT32 x; // mouse/joystick x move + INT32 y; // mouse/joystick y move boolean repeated; // key repeat } event_t; diff --git a/src/d_main.c b/src/d_main.c index 1b3449ec1..5acb9073f 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -191,22 +191,22 @@ void D_ProcessEvents(void) if (ev->type == ev_keydown || ev->type == ev_keyup) { // Mouse buttons - if ((UINT32)(ev->data1 - KEY_MOUSE1) < MOUSEBUTTONS) + if ((UINT32)(ev->key - KEY_MOUSE1) < MOUSEBUTTONS) { if (ev->type == ev_keydown) - mouse.buttons |= 1 << (ev->data1 - KEY_MOUSE1); + mouse.buttons |= 1 << (ev->key - KEY_MOUSE1); else - mouse.buttons &= ~(1 << (ev->data1 - KEY_MOUSE1)); + mouse.buttons &= ~(1 << (ev->key - KEY_MOUSE1)); } - else if ((UINT32)(ev->data1 - KEY_2MOUSE1) < MOUSEBUTTONS) + else if ((UINT32)(ev->key - KEY_2MOUSE1) < MOUSEBUTTONS) { if (ev->type == ev_keydown) - mouse2.buttons |= 1 << (ev->data1 - KEY_2MOUSE1); + mouse2.buttons |= 1 << (ev->key - KEY_2MOUSE1); else - mouse2.buttons &= ~(1 << (ev->data1 - KEY_2MOUSE1)); + mouse2.buttons &= ~(1 << (ev->key - KEY_2MOUSE1)); } // Scroll (has no keyup event) - else switch (ev->data1) { + else switch (ev->key) { case KEY_MOUSEWHEELUP: mouse.buttons |= MB_SCROLLUP; break; diff --git a/src/f_finale.c b/src/f_finale.c index 4d9a8f825..4887b11a4 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1011,7 +1011,7 @@ void F_IntroTicker(void) // boolean F_IntroResponder(event_t *event) { - INT32 key = event->data1; + INT32 key = event->key; // remap virtual keys (mouse & joystick buttons) switch (key) @@ -1397,7 +1397,7 @@ void F_CreditTicker(void) boolean F_CreditResponder(event_t *event) { - INT32 key = event->data1; + INT32 key = event->key; // remap virtual keys (mouse & joystick buttons) switch (key) @@ -3821,7 +3821,7 @@ void F_ContinueTicker(void) boolean F_ContinueResponder(event_t *event) { - INT32 key = event->data1; + INT32 key = event->key; if (keypressed) return true; diff --git a/src/g_game.c b/src/g_game.c index a35d89aa1..5c89bcae8 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1969,7 +1969,7 @@ boolean G_Responder(event_t *ev) if (gameaction == ga_nothing && !singledemo && ((demoplayback && !modeattacking && !titledemo) || gamestate == GS_TITLESCREEN)) { - if (ev->type == ev_keydown && ev->data1 != 301 && !(gamestate == GS_TITLESCREEN && finalecount < TICRATE)) + if (ev->type == ev_keydown && ev->key != 301 && !(gamestate == GS_TITLESCREEN && finalecount < TICRATE)) { M_StartControlPanel(); return true; @@ -2045,7 +2045,7 @@ boolean G_Responder(event_t *ev) // allow spy mode changes even during the demo if (gamestate == GS_LEVEL && ev->type == ev_keydown - && (ev->data1 == KEY_F12 || ev->data1 == gamecontrol[gc_viewpoint][0] || ev->data1 == gamecontrol[gc_viewpoint][1])) + && (ev->key == KEY_F12 || ev->key == gamecontrol[gc_viewpoint][0] || ev->key == gamecontrol[gc_viewpoint][1])) { // ViewpointSwitch Lua hook. UINT8 canSwitchView = 0; @@ -2118,13 +2118,13 @@ boolean G_Responder(event_t *ev) switch (ev->type) { case ev_keydown: - if (ev->data1 == gamecontrol[gc_pause][0] - || ev->data1 == gamecontrol[gc_pause][1] - || ev->data1 == KEY_PAUSE) + if (ev->key == gamecontrol[gc_pause][0] + || ev->key == gamecontrol[gc_pause][1] + || ev->key == KEY_PAUSE) { if (modeattacking && !demoplayback && (gamestate == GS_LEVEL)) { - pausebreakkey = (ev->data1 == KEY_PAUSE); + pausebreakkey = (ev->key == KEY_PAUSE); if (menuactive || pausedelay < 0 || leveltime < 2) return true; @@ -2149,8 +2149,8 @@ boolean G_Responder(event_t *ev) } } } - if (ev->data1 == gamecontrol[gc_camtoggle][0] - || ev->data1 == gamecontrol[gc_camtoggle][1]) + if (ev->key == gamecontrol[gc_camtoggle][0] + || ev->key == gamecontrol[gc_camtoggle][1]) { if (!camtoggledelay) { @@ -2158,8 +2158,8 @@ boolean G_Responder(event_t *ev) CV_SetValue(&cv_chasecam, cv_chasecam.value ? 0 : 1); } } - if (ev->data1 == gamecontrolbis[gc_camtoggle][0] - || ev->data1 == gamecontrolbis[gc_camtoggle][1]) + if (ev->key == gamecontrolbis[gc_camtoggle][0] + || ev->key == gamecontrolbis[gc_camtoggle][1]) { if (!camtoggledelay2) { diff --git a/src/g_input.c b/src/g_input.c index 2f7980c64..e0a27d1ca 100644 --- a/src/g_input.c +++ b/src/g_input.c @@ -115,54 +115,54 @@ void G_MapEventsToControls(event_t *ev) switch (ev->type) { case ev_keydown: - if (ev->data1 < NUMINPUTS) - gamekeydown[ev->data1] = 1; + if (ev->key < NUMINPUTS) + gamekeydown[ev->key] = 1; #ifdef PARANOIA else { - CONS_Debug(DBG_GAMELOGIC, "Bad downkey input %d\n",ev->data1); + CONS_Debug(DBG_GAMELOGIC, "Bad downkey input %d\n",ev->key); } #endif break; case ev_keyup: - if (ev->data1 < NUMINPUTS) - gamekeydown[ev->data1] = 0; + if (ev->key < NUMINPUTS) + gamekeydown[ev->key] = 0; #ifdef PARANOIA else { - CONS_Debug(DBG_GAMELOGIC, "Bad upkey input %d\n",ev->data1); + CONS_Debug(DBG_GAMELOGIC, "Bad upkey input %d\n",ev->key); } #endif break; case ev_mouse: // buttons are virtual keys - mouse.rdx = ev->data2; - mouse.rdy = ev->data3; + mouse.rdx = ev->x; + mouse.rdy = ev->y; break; case ev_joystick: // buttons are virtual keys - i = ev->data1; + i = ev->key; if (i >= JOYAXISSET || menuactive || CON_Ready() || chat_on) break; - if (ev->data2 != INT32_MAX) joyxmove[i] = ev->data2; - if (ev->data3 != INT32_MAX) joyymove[i] = ev->data3; + if (ev->x != INT32_MAX) joyxmove[i] = ev->x; + if (ev->y != INT32_MAX) joyymove[i] = ev->y; break; case ev_joystick2: // buttons are virtual keys - i = ev->data1; + i = ev->key; if (i >= JOYAXISSET || menuactive || CON_Ready() || chat_on) break; - if (ev->data2 != INT32_MAX) joy2xmove[i] = ev->data2; - if (ev->data3 != INT32_MAX) joy2ymove[i] = ev->data3; + if (ev->x != INT32_MAX) joy2xmove[i] = ev->x; + if (ev->y != INT32_MAX) joy2ymove[i] = ev->y; break; case ev_mouse2: // buttons are virtual keys if (menuactive || CON_Ready() || chat_on) break; - mouse2.rdx = ev->data2; - mouse2.rdy = ev->data3; + mouse2.rdx = ev->x; + mouse2.rdy = ev->y; break; default: diff --git a/src/hu_stuff.c b/src/hu_stuff.c index e0eaf8fb1..3bd263210 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -1111,12 +1111,12 @@ boolean HU_Responder(event_t *ev) // (Unless if you're sharing a keyboard, since you probably establish when you start chatting that you have dibs on it...) // (Ahhh, the good ol days when I was a kid who couldn't afford an extra USB controller...) - if (ev->data1 >= KEY_MOUSE1) + if (ev->key >= KEY_MOUSE1) { INT32 i; for (i = 0; i < num_gamecontrols; i++) { - if (gamecontrol[i][0] == ev->data1 || gamecontrol[i][1] == ev->data1) + if (gamecontrol[i][0] == ev->key || gamecontrol[i][1] == ev->key) break; } @@ -1125,12 +1125,12 @@ boolean HU_Responder(event_t *ev) }*/ //We don't actually care about that unless we get splitscreen netgames. :V #ifndef NONET - c = (INT32)ev->data1; + c = (INT32)ev->key; if (!chat_on) { // enter chat mode - if ((ev->data1 == gamecontrol[gc_talkkey][0] || ev->data1 == gamecontrol[gc_talkkey][1]) + if ((ev->key == gamecontrol[gc_talkkey][0] || ev->key == gamecontrol[gc_talkkey][1]) && netgame && !OLD_MUTE) // check for old chat mute, still let the players open the chat incase they want to scroll otherwise. { chat_on = true; @@ -1140,7 +1140,7 @@ boolean HU_Responder(event_t *ev) typelines = 1; return true; } - if ((ev->data1 == gamecontrol[gc_teamkey][0] || ev->data1 == gamecontrol[gc_teamkey][1]) + if ((ev->key == gamecontrol[gc_teamkey][0] || ev->key == gamecontrol[gc_teamkey][1]) && netgame && !OLD_MUTE) { chat_on = true; @@ -1157,12 +1157,12 @@ boolean HU_Responder(event_t *ev) // Ignore modifier keys // Note that we do this here so users can still set // their chat keys to one of these, if they so desire. - if (ev->data1 == KEY_LSHIFT || ev->data1 == KEY_RSHIFT - || ev->data1 == KEY_LCTRL || ev->data1 == KEY_RCTRL - || ev->data1 == KEY_LALT || ev->data1 == KEY_RALT) + if (ev->key == KEY_LSHIFT || ev->key == KEY_RSHIFT + || ev->key == KEY_LCTRL || ev->key == KEY_RCTRL + || ev->key == KEY_LALT || ev->key == KEY_RALT) return true; - c = (INT32)ev->data1; + c = (INT32)ev->key; // I know this looks very messy but this works. If it ain't broke, don't fix it! // shift LETTERS to uppercase if we have capslock or are holding shift diff --git a/src/lua_inputlib.c b/src/lua_inputlib.c index 01ad9af3c..01383a57b 100644 --- a/src/lua_inputlib.c +++ b/src/lua_inputlib.c @@ -184,9 +184,9 @@ static int keyevent_get(lua_State *L) I_Assert(event != NULL); if (fastcmp(field,"name")) - lua_pushstring(L, G_KeyNumToString(event->data1)); + lua_pushstring(L, G_KeyNumToString(event->key)); else if (fastcmp(field,"num")) - lua_pushinteger(L, event->data1); + lua_pushinteger(L, event->key); else if (fastcmp(field,"repeated")) lua_pushboolean(L, event->repeated); else diff --git a/src/m_cheat.c b/src/m_cheat.c index c958bb4a4..ef896c991 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -203,11 +203,11 @@ boolean cht_Responder(event_t *ev) if (ev->type != ev_keydown) return false; - if (ev->data1 > 0xFF) + if (ev->key > 0xFF) { // map some fake (joy) inputs into keys // map joy inputs into keys - switch (ev->data1) + switch (ev->key) { case KEY_JOY1: case KEY_JOY1 + 2: @@ -231,7 +231,7 @@ boolean cht_Responder(event_t *ev) } } else - ch = (UINT8)ev->data1; + ch = (UINT8)ev->key; ret += cht_CheckCheat(&cheat_ultimate, (char)ch); ret += cht_CheckCheat(&cheat_ultimate_joy, (char)ch); diff --git a/src/m_menu.c b/src/m_menu.c index db2aa09c6..92754705b 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -3229,7 +3229,7 @@ boolean M_Responder(event_t *ev) if (ev->type == ev_keydown) { keydown++; - ch = ev->data1; + ch = ev->key; // added 5-2-98 remap virtual keys (mouse & joystick buttons) switch (ch) @@ -3262,44 +3262,44 @@ boolean M_Responder(event_t *ev) break; } } - else if (ev->type == ev_joystick && ev->data1 == 0 && joywait < I_GetTime()) + else if (ev->type == ev_joystick && ev->key == 0 && joywait < I_GetTime()) { const INT32 jdeadzone = (JOYAXISRANGE * cv_digitaldeadzone.value) / FRACUNIT; - if (ev->data3 != INT32_MAX) + if (ev->y != INT32_MAX) { - if (Joystick.bGamepadStyle || abs(ev->data3) > jdeadzone) + if (Joystick.bGamepadStyle || abs(ev->y) > jdeadzone) { - if (ev->data3 < 0 && pjoyy >= 0) + if (ev->y < 0 && pjoyy >= 0) { ch = KEY_UPARROW; joywait = I_GetTime() + NEWTICRATE/7; } - else if (ev->data3 > 0 && pjoyy <= 0) + else if (ev->y > 0 && pjoyy <= 0) { ch = KEY_DOWNARROW; joywait = I_GetTime() + NEWTICRATE/7; } - pjoyy = ev->data3; + pjoyy = ev->y; } else pjoyy = 0; } - if (ev->data2 != INT32_MAX) + if (ev->x != INT32_MAX) { - if (Joystick.bGamepadStyle || abs(ev->data2) > jdeadzone) + if (Joystick.bGamepadStyle || abs(ev->x) > jdeadzone) { - if (ev->data2 < 0 && pjoyx >= 0) + if (ev->x < 0 && pjoyx >= 0) { ch = KEY_LEFTARROW; joywait = I_GetTime() + NEWTICRATE/17; } - else if (ev->data2 > 0 && pjoyx <= 0) + else if (ev->x > 0 && pjoyx <= 0) { ch = KEY_RIGHTARROW; joywait = I_GetTime() + NEWTICRATE/17; } - pjoyx = ev->data2; + pjoyx = ev->x; } else pjoyx = 0; @@ -3307,7 +3307,7 @@ boolean M_Responder(event_t *ev) } else if (ev->type == ev_mouse && mousewait < I_GetTime()) { - pmousey -= ev->data3; + pmousey -= ev->y; if (pmousey < lasty-30) { ch = KEY_DOWNARROW; @@ -3321,7 +3321,7 @@ boolean M_Responder(event_t *ev) pmousey = lasty += 30; } - pmousex += ev->data2; + pmousex += ev->x; if (pmousex < lastx - 30) { ch = KEY_LEFTARROW; @@ -3339,7 +3339,7 @@ boolean M_Responder(event_t *ev) keydown = 0; } else if (ev->type == ev_keydown) // Preserve event for other responders - ch = ev->data1; + ch = ev->key; if (ch == -1) return false; @@ -12859,7 +12859,7 @@ static void M_ChangecontrolResponse(event_t *ev) { INT32 control; INT32 found; - INT32 ch = ev->data1; + INT32 ch = ev->key; // ESCAPE cancels; dummy out PAUSE if (ch != KEY_ESCAPE && ch != KEY_PAUSE) @@ -12878,7 +12878,7 @@ static void M_ChangecontrolResponse(event_t *ev) // keypad arrows are converted for the menu in cursor arrows // so use the event instead of ch case ev_keydown: - ch = ev->data1; + ch = ev->key; break; default: diff --git a/src/m_misc.c b/src/m_misc.c index ac60d49c7..f9a23ad44 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -1631,7 +1631,7 @@ boolean M_ScreenshotResponder(event_t *ev) if (dedicated || ev->type != ev_keydown) return false; - ch = ev->data1; + ch = ev->key; if (ch >= KEY_MOUSE1 && menuactive) // If it's not a keyboard key, then don't allow it in the menus! return false; diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 1594c8d61..a3908c570 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -572,7 +572,7 @@ void I_GetConsoleEvents(void) tty_con.buffer[tty_con.cursor] = '\0'; tty_Back(); } - ev.data1 = KEY_BACKSPACE; + ev.key = KEY_BACKSPACE; } else if (key < ' ') // check if this is a control char { @@ -580,19 +580,19 @@ void I_GetConsoleEvents(void) { tty_Clear(); tty_con.cursor = 0; - ev.data1 = KEY_ENTER; + ev.key = KEY_ENTER; } else return; } else { // push regular character - ev.data1 = tty_con.buffer[tty_con.cursor] = key; + ev.key = tty_con.buffer[tty_con.cursor] = key; tty_con.cursor++; // print the current line (this is differential) d = write(STDOUT_FILENO, &key, 1); } - if (ev.data1) D_PostEvent(&ev); + if (ev.key) D_PostEvent(&ev); //tty_FlushIn(); (void)d; } @@ -626,18 +626,18 @@ static void Impl_HandleKeyboardConsoleEvent(KEY_EVENT_RECORD evt, HANDLE co) { case VK_ESCAPE: case VK_TAB: - event.data1 = KEY_NULL; + event.key = KEY_NULL; break; case VK_RETURN: entering_con_command = false; /* FALLTHRU */ default: - //event.data1 = MapVirtualKey(evt.wVirtualKeyCode,2); // convert in to char - event.data1 = evt.uChar.AsciiChar; + //event.key = MapVirtualKey(evt.wVirtualKeyCode,2); // convert in to char + event.key = evt.uChar.AsciiChar; } if (co != INVALID_HANDLE_VALUE && GetFileType(co) == FILE_TYPE_CHAR && GetConsoleMode(co, &t)) { - if (event.data1 && event.data1 != KEY_LSHIFT && event.data1 != KEY_RSHIFT) + if (event.key && event.key != KEY_LSHIFT && event.key != KEY_RSHIFT) { #ifdef _UNICODE WriteConsole(co, &evt.uChar.UnicodeChar, 1, &t, NULL); @@ -652,7 +652,7 @@ static void Impl_HandleKeyboardConsoleEvent(KEY_EVENT_RECORD evt, HANDLE co) } } } - if (event.data1) D_PostEvent(&event); + if (event.key) D_PostEvent(&event); } void I_GetConsoleEvents(void) @@ -917,7 +917,7 @@ INT32 I_GetKey (void) ev = &events[eventtail]; if (ev->type == ev_keydown || ev->type == ev_console) { - rc = ev->data1; + rc = ev->key; continue; } } @@ -977,22 +977,22 @@ void I_ShutdownJoystick(void) INT32 i; event_t event; event.type=ev_keyup; - event.data2 = 0; - event.data3 = 0; + event.x = 0; + event.y = 0; lastjoybuttons = lastjoyhats = 0; // emulate the up of all joystick buttons for (i=0;i= 0; i--) { - event.data1 = i; + event.key = i; if (i*2 + 1 <= JoyInfo.axises) axisx = SDL_JoystickGetAxis(JoyInfo.dev, i*2 + 0); else axisx = 0; @@ -1110,15 +1110,15 @@ void I_GetJoystickEvents(void) { // gamepad control type, on or off, live or die if (axisx < -(JOYAXISRANGE/2)) - event.data2 = -1; + event.x = -1; else if (axisx > (JOYAXISRANGE/2)) - event.data2 = 1; - else event.data2 = 0; + event.x = 1; + else event.x = 0; if (axisy < -(JOYAXISRANGE/2)) - event.data3 = -1; + event.y = -1; else if (axisy > (JOYAXISRANGE/2)) - event.data3 = 1; - else event.data3 = 0; + event.y = 1; + else event.y = 0; } else { @@ -1132,8 +1132,8 @@ void I_GetJoystickEvents(void) #endif // analog control style , just send the raw data - event.data2 = axisx; // x axis - event.data3 = axisy; // y axis + event.x = axisx; // x axis + event.y = axisy; // y axis } D_PostEvent(&event); } @@ -1247,22 +1247,22 @@ void I_ShutdownJoystick2(void) INT32 i; event_t event; event.type = ev_keyup; - event.data2 = 0; - event.data3 = 0; + event.x = 0; + event.y = 0; lastjoy2buttons = lastjoy2hats = 0; // emulate the up of all joystick buttons for (i = 0; i < JOYBUTTONS; i++) { - event.data1 = KEY_2JOY1 + i; + event.key = KEY_2JOY1 + i; D_PostEvent(&event); } // emulate the up of all joystick hats for (i = 0; i < JOYHATS*4; i++) { - event.data1 = KEY_2HAT1 + i; + event.key = KEY_2HAT1 + i; D_PostEvent(&event); } @@ -1270,7 +1270,7 @@ void I_ShutdownJoystick2(void) event.type = ev_joystick2; for (i = 0; i < JOYAXISSET; i++) { - event.data1 = i; + event.key = i; D_PostEvent(&event); } @@ -1321,7 +1321,7 @@ void I_GetJoystick2Events(void) event.type = ev_keydown; else event.type = ev_keyup; - event.data1 = KEY_2JOY1 + i; + event.key = KEY_2JOY1 + i; D_PostEvent(&event); } } @@ -1352,7 +1352,7 @@ void I_GetJoystick2Events(void) event.type = ev_keydown; else event.type = ev_keyup; - event.data1 = KEY_2HAT1 + i; + event.key = KEY_2HAT1 + i; D_PostEvent(&event); } } @@ -1364,7 +1364,7 @@ void I_GetJoystick2Events(void) for (i = JOYAXISSET - 1; i >= 0; i--) { - event.data1 = i; + event.key = i; if (i*2 + 1 <= JoyInfo2.axises) axisx = SDL_JoystickGetAxis(JoyInfo2.dev, i*2 + 0); else axisx = 0; @@ -1380,17 +1380,17 @@ void I_GetJoystick2Events(void) { // gamepad control type, on or off, live or die if (axisx < -(JOYAXISRANGE/2)) - event.data2 = -1; + event.x = -1; else if (axisx > (JOYAXISRANGE/2)) - event.data2 = 1; + event.x = 1; else - event.data2 = 0; + event.x = 0; if (axisy < -(JOYAXISRANGE/2)) - event.data3 = -1; + event.y = -1; else if (axisy > (JOYAXISRANGE/2)) - event.data3 = 1; + event.y = 1; else - event.data3 = 0; + event.y = 0; } else { @@ -1404,8 +1404,8 @@ void I_GetJoystick2Events(void) #endif // analog control style , just send the raw data - event.data2 = axisx; // x axis - event.data3 = axisy; // y axis + event.x = axisx; // x axis + event.y = axisy; // y axis } D_PostEvent(&event); } @@ -1804,7 +1804,7 @@ void I_GetMouseEvents(void) if (!(button & (1< 0) { - event.data1 = KEY_MOUSEWHEELUP; + event.key = KEY_MOUSEWHEELUP; event.type = ev_keydown; } if (evt.y < 0) { - event.data1 = KEY_MOUSEWHEELDOWN; + event.key = KEY_MOUSEWHEELDOWN; event.type = ev_keydown; } if (evt.y == 0) { - event.data1 = 0; + event.key = 0; event.type = ev_keyup; } if (event.type == ev_keyup || event.type == ev_keydown) @@ -796,7 +796,7 @@ static void Impl_HandleJoystickAxisEvent(SDL_JoyAxisEvent evt) joyid[1] = SDL_JoystickInstanceID(JoyInfo2.dev); evt.axis++; - event.data1 = event.data2 = event.data3 = INT32_MAX; + event.key = event.x = event.y = INT32_MAX; if (evt.which == joyid[0]) { @@ -813,14 +813,14 @@ static void Impl_HandleJoystickAxisEvent(SDL_JoyAxisEvent evt) //vaule if (evt.axis%2) { - event.data1 = evt.axis / 2; - event.data2 = SDLJoyAxis(evt.value, event.type); + event.key = evt.axis / 2; + event.x = SDLJoyAxis(evt.value, event.type); } else { evt.axis--; - event.data1 = evt.axis / 2; - event.data3 = SDLJoyAxis(evt.value, event.type); + event.key = evt.axis / 2; + event.y = SDLJoyAxis(evt.value, event.type); } D_PostEvent(&event); } @@ -840,11 +840,11 @@ static void Impl_HandleJoystickHatEvent(SDL_JoyHatEvent evt) if (evt.which == joyid[0]) { - event.data1 = KEY_HAT1 + (evt.hat*4); + event.key = KEY_HAT1 + (evt.hat*4); } else if (evt.which == joyid[1]) { - event.data1 = KEY_2HAT1 + (evt.hat*4); + event.key = KEY_2HAT1 + (evt.hat*4); } else return; @@ -863,11 +863,11 @@ static void Impl_HandleJoystickButtonEvent(SDL_JoyButtonEvent evt, Uint32 type) if (evt.which == joyid[0]) { - event.data1 = KEY_JOY1; + event.key = KEY_JOY1; } else if (evt.which == joyid[1]) { - event.data1 = KEY_2JOY1; + event.key = KEY_2JOY1; } else return; if (type == SDL_JOYBUTTONUP) @@ -881,7 +881,7 @@ static void Impl_HandleJoystickButtonEvent(SDL_JoyButtonEvent evt, Uint32 type) else return; if (evt.button < JOYBUTTONS) { - event.data1 += evt.button; + event.key += evt.button; } else return; @@ -1085,9 +1085,9 @@ void I_GetEvent(void) SDL_GetWindowSize(window, &wwidth, &wheight); //SDL_memset(&event, 0, sizeof(event_t)); event.type = ev_mouse; - event.data1 = 0; - event.data2 = (INT32)lround(mousemovex * ((float)wwidth / (float)realwidth)); - event.data3 = (INT32)lround(mousemovey * ((float)wheight / (float)realheight)); + event.key = 0; + event.x = (INT32)lround(mousemovex * ((float)wwidth / (float)realwidth)); + event.y = (INT32)lround(mousemovey * ((float)wheight / (float)realheight)); D_PostEvent(&event); } diff --git a/src/win32/win_main.c b/src/win32/win_main.c index e1d90881b..a5ebf3211 100644 --- a/src/win32/win_main.c +++ b/src/win32/win_main.c @@ -188,11 +188,11 @@ static LRESULT CALLBACK MainWndproc(HWND hWnd, UINT message, WPARAM wParam, LPAR ev.type = ev_keydown; handleKeyDoom: - ev.data1 = 0; + ev.key = 0; if (wParam == VK_PAUSE) // intercept PAUSE key { - ev.data1 = KEY_PAUSE; + ev.key = KEY_PAUSE; } else if (!keyboard_started) // post some keys during the game startup @@ -201,14 +201,14 @@ static LRESULT CALLBACK MainWndproc(HWND hWnd, UINT message, WPARAM wParam, LPAR { switch (wParam) { - case VK_ESCAPE: ev.data1 = KEY_ESCAPE; break; - case VK_RETURN: ev.data1 = KEY_ENTER; break; - case VK_SHIFT: ev.data1 = KEY_LSHIFT; break; - default: ev.data1 = MapVirtualKey((DWORD)wParam,2); // convert in to char + case VK_ESCAPE: ev.key = KEY_ESCAPE; break; + case VK_RETURN: ev.key = KEY_ENTER; break; + case VK_SHIFT: ev.key = KEY_LSHIFT; break; + default: ev.key = MapVirtualKey((DWORD)wParam,2); // convert in to char } } - if (ev.data1) + if (ev.key) D_PostEvent (&ev); return 0; @@ -240,7 +240,7 @@ static LRESULT CALLBACK MainWndproc(HWND hWnd, UINT message, WPARAM wParam, LPAR if (nodinput) { ev.type = ev_keyup; - ev.data1 = KEY_MOUSE1 + 3 + HIWORD(wParam); + ev.key = KEY_MOUSE1 + 3 + HIWORD(wParam); D_PostEvent(&ev); return TRUE; } @@ -249,7 +249,7 @@ static LRESULT CALLBACK MainWndproc(HWND hWnd, UINT message, WPARAM wParam, LPAR if (nodinput) { ev.type = ev_keydown; - ev.data1 = KEY_MOUSE1 + 3 + HIWORD(wParam); + ev.key = KEY_MOUSE1 + 3 + HIWORD(wParam); D_PostEvent(&ev); return TRUE; } @@ -258,9 +258,9 @@ static LRESULT CALLBACK MainWndproc(HWND hWnd, UINT message, WPARAM wParam, LPAR //I_OutputMsg("MW_WHEEL dispatched.\n"); ev.type = ev_keydown; if ((INT16)HIWORD(wParam) > 0) - ev.data1 = KEY_MOUSEWHEELUP; + ev.key = KEY_MOUSEWHEELUP; else - ev.data1 = KEY_MOUSEWHEELDOWN; + ev.key = KEY_MOUSEWHEELDOWN; D_PostEvent(&ev); break; @@ -271,7 +271,7 @@ static LRESULT CALLBACK MainWndproc(HWND hWnd, UINT message, WPARAM wParam, LPAR case WM_CLOSE: PostQuitMessage(0); //to quit while in-game - ev.data1 = KEY_ESCAPE; //to exit network synchronization + ev.key = KEY_ESCAPE; //to exit network synchronization ev.type = ev_keydown; D_PostEvent (&ev); return 0; diff --git a/src/win32/win_sys.c b/src/win32/win_sys.c index da0d5b47e..ff443935f 100644 --- a/src/win32/win_sys.c +++ b/src/win32/win_sys.c @@ -322,20 +322,20 @@ static inline VOID I_GetConsoleEvents(VOID) { case VK_ESCAPE: case VK_TAB: - ev.data1 = KEY_NULL; + ev.key = KEY_NULL; break; case VK_SHIFT: - ev.data1 = KEY_LSHIFT; + ev.key = KEY_LSHIFT; break; case VK_RETURN: entering_con_command = false; /* FALLTHRU */ default: - ev.data1 = MapVirtualKey(input.Event.KeyEvent.wVirtualKeyCode,2); // convert in to char + ev.key = MapVirtualKey(input.Event.KeyEvent.wVirtualKeyCode,2); // convert in to char } if (co != INVALID_HANDLE_VALUE && GetFileType(co) == FILE_TYPE_CHAR && GetConsoleMode(co, &t)) { - if (ev.data1 && ev.data1 != KEY_LSHIFT && ev.data1 != KEY_RSHIFT) + if (ev.key && ev.key != KEY_LSHIFT && ev.key != KEY_RSHIFT) { #ifdef UNICODE WriteConsole(co, &input.Event.KeyEvent.uChar.UnicodeChar, 1, &t, NULL); @@ -356,13 +356,13 @@ static inline VOID I_GetConsoleEvents(VOID) switch (input.Event.KeyEvent.wVirtualKeyCode) { case VK_SHIFT: - ev.data1 = KEY_LSHIFT; + ev.key = KEY_LSHIFT; break; default: break; } } - if (ev.data1) D_PostEvent(&ev); + if (ev.key) D_PostEvent(&ev); break; case MOUSE_EVENT: case WINDOW_BUFFER_SIZE_EVENT: @@ -945,7 +945,7 @@ static void I_ShutdownMouse2(VOID) for (i = 0; i < MOUSEBUTTONS; i++) { event.type = ev_keyup; - event.data1 = KEY_2MOUSE1 + i; + event.key = KEY_2MOUSE1 + i; D_PostEvent(&event); } @@ -1135,14 +1135,14 @@ VOID I_GetSysMouseEvents(INT mouse_state) if ((mouse_state & (1 << i)) && !(old_mouse_state & (1 << i))) { event.type = ev_keydown; - event.data1 = KEY_MOUSE1 + i; + event.key = KEY_MOUSE1 + i; D_PostEvent(&event); } // check if button released if (!(mouse_state & (1 << i)) && (old_mouse_state & (1 << i))) { event.type = ev_keyup; - event.data1 = KEY_MOUSE1 + i; + event.key = KEY_MOUSE1 + i; D_PostEvent(&event); } } @@ -1156,9 +1156,9 @@ VOID I_GetSysMouseEvents(INT mouse_state) if (xmickeys || ymickeys) { event.type = ev_mouse; - event.data1 = 0; - event.data2 = xmickeys; - event.data3 = -ymickeys; + event.key = 0; + event.x = xmickeys; + event.y = -ymickeys; D_PostEvent(&event); SetCursorPos(center_x, center_y); } @@ -1240,7 +1240,7 @@ static void I_ShutdownMouse(void) for (i = 0; i < MOUSEBUTTONS; i++) { event.type = ev_keyup; - event.data1 = KEY_MOUSE1 + i; + event.key = KEY_MOUSE1 + i; D_PostEvent(&event); } if (nodinput) @@ -1281,7 +1281,7 @@ void I_GetMouseEvents(void) event.type = ev_keydown; else event.type = ev_keyup; - event.data1 = KEY_2MOUSE1 + i; + event.key = KEY_2MOUSE1 + i; D_PostEvent(&event); } } @@ -1289,9 +1289,9 @@ void I_GetMouseEvents(void) if (handlermouse2x || handlermouse2y) { event.type = ev_mouse2; - event.data1 = 0; - event.data2 = handlermouse2x<<1; - event.data3 = -handlermouse2y<<1; + event.key = 0; + event.x = handlermouse2x<<1; + event.y = -handlermouse2y<<1; handlermouse2x = 0; handlermouse2y = 0; @@ -1330,7 +1330,7 @@ getBufferedData: else event.type = ev_keyup; // Button up - event.data1 = rgdod[d].dwOfs - DIMOFS_BUTTON0 + KEY_MOUSE1; + event.key = rgdod[d].dwOfs - DIMOFS_BUTTON0 + KEY_MOUSE1; D_PostEvent(&event); } else if (rgdod[d].dwOfs == DIMOFS_X) @@ -1342,9 +1342,9 @@ getBufferedData: { // z-axes the wheel if ((int)rgdod[d].dwData > 0) - event.data1 = KEY_MOUSEWHEELUP; + event.key = KEY_MOUSEWHEELUP; else - event.data1 = KEY_MOUSEWHEELDOWN; + event.key = KEY_MOUSEWHEELDOWN; event.type = ev_keydown; D_PostEvent(&event); } @@ -1354,9 +1354,9 @@ getBufferedData: if (xmickeys || ymickeys) { event.type = ev_mouse; - event.data1 = 0; - event.data2 = xmickeys; - event.data3 = -ymickeys; + event.key = 0; + event.x = xmickeys; + event.y = -ymickeys; D_PostEvent(&event); } } @@ -2395,14 +2395,14 @@ static VOID I_ShutdownJoystick(VOID) // emulate the up of all joystick buttons for (i = 0;i < JOYBUTTONS;i++) { - event.data1 = KEY_JOY1+i; + event.key = KEY_JOY1+i; D_PostEvent(&event); } // emulate the up of all joystick hats for (i = 0;i < JOYHATS*4;i++) { - event.data1 = KEY_HAT1+i; + event.key = KEY_HAT1+i; D_PostEvent(&event); } @@ -2410,7 +2410,7 @@ static VOID I_ShutdownJoystick(VOID) event.type = ev_joystick; for (i = 0;i < JOYAXISSET; i++) { - event.data1 = i; + event.key = i; D_PostEvent(&event); } @@ -2460,14 +2460,14 @@ static VOID I_ShutdownJoystick2(VOID) // emulate the up of all joystick buttons for (i = 0;i < JOYBUTTONS;i++) { - event.data1 = KEY_2JOY1+i; + event.key = KEY_2JOY1+i; D_PostEvent(&event); } // emulate the up of all joystick hats for (i = 0;i < JOYHATS*4;i++) { - event.data1 = KEY_2HAT1+i; + event.key = KEY_2HAT1+i; D_PostEvent(&event); } @@ -2475,7 +2475,7 @@ static VOID I_ShutdownJoystick2(VOID) event.type = ev_joystick2; for (i = 0;i < JOYAXISSET; i++) { - event.data1 = i; + event.key = i; D_PostEvent(&event); } @@ -2598,7 +2598,7 @@ acquire: event.type = ev_keydown; else event.type = ev_keyup; - event.data1 = KEY_JOY1 + i; + event.key = KEY_JOY1 + i; D_PostEvent(&event); } } @@ -2618,7 +2618,7 @@ acquire: event.type = ev_keydown; else event.type = ev_keyup; - event.data1 = KEY_HAT1 + i; + event.key = KEY_HAT1 + i; D_PostEvent(&event); } } @@ -2627,7 +2627,7 @@ acquire: // send joystick axis positions event.type = ev_joystick; - event.data1 = event.data2 = event.data3 = 0; + event.key = event.x = event.y = 0; if (Joystick.bGamepadStyle) { @@ -2635,29 +2635,29 @@ acquire: if (JoyInfo.X) { if (js.lX < -(JOYAXISRANGE/2)) - event.data2 = -1; + event.x = -1; else if (js.lX > JOYAXISRANGE/2) - event.data2 = 1; + event.x = 1; } if (JoyInfo.Y) { if (js.lY < -(JOYAXISRANGE/2)) - event.data3 = -1; + event.y = -1; else if (js.lY > JOYAXISRANGE/2) - event.data3 = 1; + event.y = 1; } } else { // analog control style, just send the raw data - if (JoyInfo.X) event.data2 = js.lX; // x axis - if (JoyInfo.Y) event.data3 = js.lY; // y axis + if (JoyInfo.X) event.x = js.lX; // x axis + if (JoyInfo.Y) event.y = js.lY; // y axis } D_PostEvent(&event); #if JOYAXISSET > 1 - event.data1 = 1; - event.data2 = event.data3 = 0; + event.key = 1; + event.x = event.y = 0; if (Joystick.bGamepadStyle) { @@ -2665,30 +2665,30 @@ acquire: if (JoyInfo.Z) { if (js.lZ < -(JOYAXISRANGE/2)) - event.data2 = -1; + event.x = -1; else if (js.lZ > JOYAXISRANGE/2) - event.data2 = 1; + event.x = 1; } if (JoyInfo.Rx) { if (js.lRx < -(JOYAXISRANGE/2)) - event.data3 = -1; + event.y = -1; else if (js.lRx > JOYAXISRANGE/2) - event.data3 = 1; + event.y = 1; } } else { // analog control style, just send the raw data - if (JoyInfo.Z) event.data2 = js.lZ; // z axis - if (JoyInfo.Rx) event.data3 = js.lRx; // rx axis + if (JoyInfo.Z) event.x = js.lZ; // z axis + if (JoyInfo.Rx) event.y = js.lRx; // rx axis } D_PostEvent(&event); #endif #if JOYAXISSET > 2 - event.data1 = 2; - event.data2 = event.data3 = 0; + event.key = 2; + event.x = event.y = 0; if (Joystick.bGamepadStyle) { @@ -2696,53 +2696,53 @@ acquire: if (JoyInfo.Rx) { if (js.lRy < -(JOYAXISRANGE/2)) - event.data2 = -1; + event.x = -1; else if (js.lRy > JOYAXISRANGE/2) - event.data2 = 1; + event.x = 1; } if (JoyInfo.Rz) { if (js.lRz < -(JOYAXISRANGE/2)) - event.data3 = -1; + event.y = -1; else if (js.lRz > JOYAXISRANGE/2) - event.data3 = 1; + event.y = 1; } } else { // analog control style, just send the raw data - if (JoyInfo.Ry) event.data2 = js.lRy; // ry axis - if (JoyInfo.Rz) event.data3 = js.lRz; // rz axis + if (JoyInfo.Ry) event.x = js.lRy; // ry axis + if (JoyInfo.Rz) event.y = js.lRz; // rz axis } D_PostEvent(&event); #endif #if JOYAXISSET > 3 - event.data1 = 3; - event.data2 = event.data3 = 0; + event.key = 3; + event.x = event.y = 0; if (Joystick.bGamepadStyle) { // gamepad control type, on or off, live or die if (JoyInfo.U) { if (js.rglSlider[0] < -(JOYAXISRANGE/2)) - event.data2 = -1; + event.x = -1; else if (js.rglSlider[0] > JOYAXISRANGE/2) - event.data2 = 1; + event.x = 1; } if (JoyInfo.V) { if (js.rglSlider[1] < -(JOYAXISRANGE/2)) - event.data3 = -1; + event.y = -1; else if (js.rglSlider[1] > JOYAXISRANGE/2) - event.data3 = 1; + event.y = 1; } } else { // analog control style, just send the raw data - if (JoyInfo.U) event.data2 = js.rglSlider[0]; // U axis - if (JoyInfo.V) event.data3 = js.rglSlider[1]; // V axis + if (JoyInfo.U) event.x = js.rglSlider[0]; // U axis + if (JoyInfo.V) event.y = js.rglSlider[1]; // V axis } D_PostEvent(&event); #endif @@ -2842,7 +2842,7 @@ acquire: event.type = ev_keydown; else event.type = ev_keyup; - event.data1 = KEY_2JOY1 + i; + event.key = KEY_2JOY1 + i; D_PostEvent(&event); } } @@ -2862,7 +2862,7 @@ acquire: event.type = ev_keydown; else event.type = ev_keyup; - event.data1 = KEY_2HAT1 + i; + event.key = KEY_2HAT1 + i; D_PostEvent(&event); } } @@ -2871,7 +2871,7 @@ acquire: // send joystick axis positions event.type = ev_joystick2; - event.data1 = event.data2 = event.data3 = 0; + event.key = event.x = event.y = 0; if (Joystick2.bGamepadStyle) { @@ -2879,29 +2879,29 @@ acquire: if (JoyInfo2.X) { if (js.lX < -(JOYAXISRANGE/2)) - event.data2 = -1; + event.x = -1; else if (js.lX > JOYAXISRANGE/2) - event.data2 = 1; + event.x = 1; } if (JoyInfo2.Y) { if (js.lY < -(JOYAXISRANGE/2)) - event.data3 = -1; + event.y = -1; else if (js.lY > JOYAXISRANGE/2) - event.data3 = 1; + event.y = 1; } } else { // analog control style, just send the raw data - if (JoyInfo2.X) event.data2 = js.lX; // x axis - if (JoyInfo2.Y) event.data3 = js.lY; // y axis + if (JoyInfo2.X) event.x = js.lX; // x axis + if (JoyInfo2.Y) event.y = js.lY; // y axis } D_PostEvent(&event); #if JOYAXISSET > 1 - event.data1 = 1; - event.data2 = event.data3 = 0; + event.key = 1; + event.x = event.y = 0; if (Joystick2.bGamepadStyle) { @@ -2909,30 +2909,30 @@ acquire: if (JoyInfo2.Z) { if (js.lZ < -(JOYAXISRANGE/2)) - event.data2 = -1; + event.x = -1; else if (js.lZ > JOYAXISRANGE/2) - event.data2 = 1; + event.x = 1; } if (JoyInfo2.Rx) { if (js.lRx < -(JOYAXISRANGE/2)) - event.data3 = -1; + event.y = -1; else if (js.lRx > JOYAXISRANGE/2) - event.data3 = 1; + event.y = 1; } } else { // analog control style, just send the raw data - if (JoyInfo2.Z) event.data2 = js.lZ; // z axis - if (JoyInfo2.Rx) event.data3 = js.lRx; // rx axis + if (JoyInfo2.Z) event.x = js.lZ; // z axis + if (JoyInfo2.Rx) event.y = js.lRx; // rx axis } D_PostEvent(&event); #endif #if JOYAXISSET > 2 - event.data1 = 2; - event.data2 = event.data3 = 0; + event.key = 2; + event.x = event.y = 0; if (Joystick2.bGamepadStyle) { @@ -2940,53 +2940,53 @@ acquire: if (JoyInfo2.Rx) { if (js.lRy < -(JOYAXISRANGE/2)) - event.data2 = -1; + event.x = -1; else if (js.lRy > JOYAXISRANGE/2) - event.data2 = 1; + event.x = 1; } if (JoyInfo2.Rz) { if (js.lRz < -(JOYAXISRANGE/2)) - event.data3 = -1; + event.y = -1; else if (js.lRz > JOYAXISRANGE/2) - event.data3 = 1; + event.y = 1; } } else { // analog control style, just send the raw data - if (JoyInfo2.Ry) event.data2 = js.lRy; // ry axis - if (JoyInfo2.Rz) event.data3 = js.lRz; // rz axis + if (JoyInfo2.Ry) event.x = js.lRy; // ry axis + if (JoyInfo2.Rz) event.y = js.lRz; // rz axis } D_PostEvent(&event); #endif #if JOYAXISSET > 3 - event.data1 = 3; - event.data2 = event.data3 = 0; + event.key = 3; + event.x = event.y = 0; if (Joystick2.bGamepadStyle) { // gamepad control type, on or off, live or die if (JoyInfo2.U) { if (js.rglSlider[0] < -(JOYAXISRANGE/2)) - event.data2 = -1; + event.x = -1; else if (js.rglSlider[0] > JOYAXISRANGE/2) - event.data2 = 1; + event.x = 1; } if (JoyInfo2.V) { if (js.rglSlider[1] < -(JOYAXISRANGE/2)) - event.data3 = -1; + event.y = -1; else if (js.rglSlider[1] > JOYAXISRANGE/2) - event.data3 = 1; + event.y = 1; } } else { // analog control style, just send the raw data - if (JoyInfo2.U) event.data2 = js.rglSlider[0]; // U axis - if (JoyInfo2.V) event.data3 = js.rglSlider[1]; // V axis + if (JoyInfo2.U) event.x = js.rglSlider[0]; // U axis + if (JoyInfo2.V) event.y = js.rglSlider[1]; // V axis } D_PostEvent(&event); #endif @@ -3194,7 +3194,7 @@ INT32 I_GetKey(void) ev = &events[eventtail]; eventtail = (eventtail+1) & (MAXEVENTS-1); if (ev->type == ev_keydown || ev->type == ev_console) - return ev->data1; + return ev->key; else return 0; } @@ -3308,7 +3308,7 @@ static VOID I_GetKeyboardEvents(VOID) if (!appActive && RepeatKeyCode) // Stop when lost focus { event.type = ev_keyup; - event.data1 = RepeatKeyCode; + event.key = RepeatKeyCode; D_PostEvent(&event); RepeatKeyCode = 0; } @@ -3363,9 +3363,9 @@ getBufferedData: ch = rgdod[d].dwOfs & 0xFF; if (ASCIINames[ch]) - event.data1 = ASCIINames[ch]; + event.key = ASCIINames[ch]; else - event.data1 = 0x80; + event.key = 0x80; D_PostEvent(&event); } @@ -3378,7 +3378,7 @@ getBufferedData: // delay is tripled for first repeating key RepeatKeyTics = hacktics + (KEY_REPEAT_DELAY*3); if (event.type == ev_keydown) // use the last event! - RepeatKeyCode = event.data1; + RepeatKeyCode = event.key; } else { @@ -3386,7 +3386,7 @@ getBufferedData: if (RepeatKeyCode && hacktics - RepeatKeyTics > KEY_REPEAT_DELAY) { event.type = ev_keydown; - event.data1 = RepeatKeyCode; + event.key = RepeatKeyCode; D_PostEvent(&event); RepeatKeyTics = hacktics; From 824b1ab28cdddfd1c018454a9af14dabaab49fcd Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 14 Aug 2021 15:29:21 -0700 Subject: [PATCH 585/644] Makefile: use full stem in dependency generation Previously took only the filename, so the directory component was stripped. This broke dependencies for basically every file. --- src/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index ce0e84987..9659a4994 100644 --- a/src/Makefile +++ b/src/Makefile @@ -376,7 +376,7 @@ ifdef Echo_name @printf '%-20.20s\r' $$< endif endif - $(.)$(cc) -MM -MF $$@ -MT $(objdir)/$$(*F).o $(2) $$< + $(.)$(cc) -MM -MF $$@ -MT $(objdir)/$$*.o $(2) $$< endef $(eval $(call _recipe,c)) From 772695741c7935a3798d3e48d0d5c9151df7ae28 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sun, 15 Aug 2021 15:24:23 +0200 Subject: [PATCH 586/644] Rename KeyNumToString to KeyNumToName and vice-versa --- src/console.c | 4 ++-- src/g_input.c | 16 ++++++++-------- src/g_input.h | 4 ++-- src/lua_inputlib.c | 14 +++++++------- src/m_menu.c | 4 ++-- 5 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/console.c b/src/console.c index 7941e1dbb..d615f3e6b 100644 --- a/src/console.c +++ b/src/console.c @@ -221,7 +221,7 @@ static void CONS_Bind_f(void) for (key = 0; key < NUMINPUTS; key++) if (bindtable[key]) { - CONS_Printf("%s : \"%s\"\n", G_KeyNumToString(key), bindtable[key]); + CONS_Printf("%s : \"%s\"\n", G_KeyNumToName(key), bindtable[key]); na = 1; } if (!na) @@ -229,7 +229,7 @@ static void CONS_Bind_f(void) return; } - key = G_KeyStringToNum(COM_Argv(1)); + key = G_KeyNameToNum(COM_Argv(1)); if (key <= 0 || key >= NUMINPUTS) { CONS_Alert(CONS_NOTICE, M_GetText("Invalid key name\n")); diff --git a/src/g_input.c b/src/g_input.c index e0a27d1ca..494edbd56 100644 --- a/src/g_input.c +++ b/src/g_input.c @@ -624,7 +624,7 @@ void G_ClearAllControlKeys(void) // Returns the name of a key (or virtual key for mouse and joy) // the input value being an keynum // -const char *G_KeyNumToString(INT32 keynum) +const char *G_KeyNumToName(INT32 keynum) { static char keynamestr[8]; @@ -648,7 +648,7 @@ const char *G_KeyNumToString(INT32 keynum) return keynamestr; } -INT32 G_KeyStringToNum(const char *keystr) +INT32 G_KeyNameToNum(const char *keystr) { UINT32 j; @@ -811,10 +811,10 @@ void G_SaveKeySetting(FILE *f, INT32 (*fromcontrols)[2], INT32 (*fromcontrolsbis for (i = 1; i < num_gamecontrols; i++) { fprintf(f, "setcontrol \"%s\" \"%s\"", gamecontrolname[i], - G_KeyNumToString(fromcontrols[i][0])); + G_KeyNumToName(fromcontrols[i][0])); if (fromcontrols[i][1]) - fprintf(f, " \"%s\"\n", G_KeyNumToString(fromcontrols[i][1])); + fprintf(f, " \"%s\"\n", G_KeyNumToName(fromcontrols[i][1])); else fprintf(f, "\n"); } @@ -822,10 +822,10 @@ void G_SaveKeySetting(FILE *f, INT32 (*fromcontrols)[2], INT32 (*fromcontrolsbis for (i = 1; i < num_gamecontrols; i++) { fprintf(f, "setcontrol2 \"%s\" \"%s\"", gamecontrolname[i], - G_KeyNumToString(fromcontrolsbis[i][0])); + G_KeyNumToName(fromcontrolsbis[i][0])); if (fromcontrolsbis[i][1]) - fprintf(f, " \"%s\"\n", G_KeyNumToString(fromcontrolsbis[i][1])); + fprintf(f, " \"%s\"\n", G_KeyNumToName(fromcontrolsbis[i][1])); else fprintf(f, "\n"); } @@ -1001,8 +1001,8 @@ static void setcontrol(INT32 (*gc)[2]) CONS_Printf(M_GetText("Control '%s' unknown\n"), namectrl); return; } - keynum1 = G_KeyStringToNum(COM_Argv(2)); - keynum2 = G_KeyStringToNum(COM_Argv(3)); + keynum1 = G_KeyNameToNum(COM_Argv(2)); + keynum2 = G_KeyNameToNum(COM_Argv(3)); keynum = G_FilterKeyByVersion(numctrl, 0, player, &keynum1, &keynum2, &nestedoverride); if (keynum >= 0) diff --git a/src/g_input.h b/src/g_input.h index ffd0cb560..39c0180e7 100644 --- a/src/g_input.h +++ b/src/g_input.h @@ -181,8 +181,8 @@ extern const INT32 gcl_jump_spin[num_gcl_jump_spin]; void G_MapEventsToControls(event_t *ev); // returns the name of a key -const char *G_KeyNumToString(INT32 keynum); -INT32 G_KeyStringToNum(const char *keystr); +const char *G_KeyNumToName(INT32 keynum); +INT32 G_KeyNameToNum(const char *keystr); // detach any keys associated to the given game control void G_ClearControlKeys(INT32 (*setupcontrols)[2], INT32 control); diff --git a/src/lua_inputlib.c b/src/lua_inputlib.c index 01383a57b..3affeea7b 100644 --- a/src/lua_inputlib.c +++ b/src/lua_inputlib.c @@ -75,17 +75,17 @@ static int lib_joy2Axis(lua_State *L) return 1; } -static int lib_keyNumToString(lua_State *L) +static int lib_keyNumToName(lua_State *L) { int i = luaL_checkinteger(L, 1); - lua_pushstring(L, G_KeyNumToString(i)); + lua_pushstring(L, G_KeyNumToName(i)); return 1; } -static int lib_keyStringToNum(lua_State *L) +static int lib_keyNameToNum(lua_State *L) { const char *str = luaL_checkstring(L, 1); - lua_pushinteger(L, G_KeyStringToNum(str)); + lua_pushinteger(L, G_KeyNameToNum(str)); return 1; } @@ -133,8 +133,8 @@ static luaL_Reg lib[] = { {"gameControl2ToKeyNum", lib_gameControl2ToKeyNum}, {"joyAxis", lib_joyAxis}, {"joy2Axis", lib_joy2Axis}, - {"keyNumToString", lib_keyNumToString}, - {"keyStringToNum", lib_keyStringToNum}, + {"keyNumToName", lib_keyNumToName}, + {"keyNameToNum", lib_keyNameToNum}, {"keyNumPrintable", lib_keyNumPrintable}, {"shiftKeyNum", lib_shiftKeyNum}, {"getMouseGrab", lib_getMouseGrab}, @@ -184,7 +184,7 @@ static int keyevent_get(lua_State *L) I_Assert(event != NULL); if (fastcmp(field,"name")) - lua_pushstring(L, G_KeyNumToString(event->key)); + lua_pushstring(L, G_KeyNumToName(event->key)); else if (fastcmp(field,"num")) lua_pushinteger(L, event->key); else if (fastcmp(field,"repeated")) diff --git a/src/m_menu.c b/src/m_menu.c index 92754705b..4a0fefb1b 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -12826,13 +12826,13 @@ static void M_DrawControl(void) else { if (keys[0] != KEY_NULL) - strcat (tmp, G_KeyNumToString (keys[0])); + strcat (tmp, G_KeyNumToName (keys[0])); if (keys[0] != KEY_NULL && keys[1] != KEY_NULL) strcat(tmp," or "); if (keys[1] != KEY_NULL) - strcat (tmp, G_KeyNumToString (keys[1])); + strcat (tmp, G_KeyNumToName (keys[1])); } From 5340db5f6755fb927b36c33aacd845c11ea5cca4 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sun, 15 Aug 2021 16:15:28 +0200 Subject: [PATCH 587/644] Make gc_ constants uppercase --- src/console.c | 4 +- src/d_clisrv.c | 4 +- src/deh_tables.c | 86 ++++++++--------- src/g_game.c | 62 ++++++------ src/g_input.c | 228 ++++++++++++++++++++++----------------------- src/g_input.h | 94 +++++++++---------- src/hu_stuff.c | 14 +-- src/lua_inputlib.c | 16 ++-- src/m_menu.c | 80 ++++++++-------- src/m_misc.c | 4 +- src/p_user.c | 4 +- 11 files changed, 298 insertions(+), 298 deletions(-) diff --git a/src/console.c b/src/console.c index d615f3e6b..b9348d10e 100644 --- a/src/console.c +++ b/src/console.c @@ -913,7 +913,7 @@ boolean CON_Responder(event_t *ev) // let go keyup events, don't eat them if (ev->type != ev_keydown && ev->type != ev_console) { - if (ev->key == gamecontrol[gc_console][0] || ev->key == gamecontrol[gc_console][1]) + if (ev->key == gamecontrol[GC_CONSOLE][0] || ev->key == gamecontrol[GC_CONSOLE][1]) consdown = false; return false; } @@ -926,7 +926,7 @@ boolean CON_Responder(event_t *ev) if (modeattacking || metalrecording || marathonmode) return false; - if (key == gamecontrol[gc_console][0] || key == gamecontrol[gc_console][1]) + if (key == gamecontrol[GC_CONSOLE][0] || key == gamecontrol[GC_CONSOLE][1]) { if (consdown) // ignore repeat return true; diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 36a0d7df7..326105a3b 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -663,14 +663,14 @@ static void Snake_Handle(void) UINT16 i; // Handle retry - if (snake->gameover && (PLAYER1INPUTDOWN(gc_jump) || gamekeydown[KEY_ENTER])) + if (snake->gameover && (PLAYER1INPUTDOWN(GC_JUMP) || gamekeydown[KEY_ENTER])) { Snake_Initialise(); snake->pausepressed = true; // Avoid accidental pause on respawn } // Handle pause - if (PLAYER1INPUTDOWN(gc_pause) || gamekeydown[KEY_ENTER]) + if (PLAYER1INPUTDOWN(GC_PAUSE) || gamekeydown[KEY_ENTER]) { if (!snake->pausepressed) snake->paused = !snake->paused; diff --git a/src/deh_tables.c b/src/deh_tables.c index 677b23214..088bc26c0 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -5472,49 +5472,49 @@ struct int_const_s const INT_CONST[] = { {"JOYAXISRANGE",JOYAXISRANGE}, // Game controls - {"gc_null",gc_null}, - {"gc_forward",gc_forward}, - {"gc_backward",gc_backward}, - {"gc_strafeleft",gc_strafeleft}, - {"gc_straferight",gc_straferight}, - {"gc_turnleft",gc_turnleft}, - {"gc_turnright",gc_turnright}, - {"gc_weaponnext",gc_weaponnext}, - {"gc_weaponprev",gc_weaponprev}, - {"gc_wepslot1",gc_wepslot1}, - {"gc_wepslot2",gc_wepslot2}, - {"gc_wepslot3",gc_wepslot3}, - {"gc_wepslot4",gc_wepslot4}, - {"gc_wepslot5",gc_wepslot5}, - {"gc_wepslot6",gc_wepslot6}, - {"gc_wepslot7",gc_wepslot7}, - {"gc_wepslot8",gc_wepslot8}, - {"gc_wepslot9",gc_wepslot9}, - {"gc_wepslot10",gc_wepslot10}, - {"gc_fire",gc_fire}, - {"gc_firenormal",gc_firenormal}, - {"gc_tossflag",gc_tossflag}, - {"gc_spin",gc_spin}, - {"gc_camtoggle",gc_camtoggle}, - {"gc_camreset",gc_camreset}, - {"gc_lookup",gc_lookup}, - {"gc_lookdown",gc_lookdown}, - {"gc_centerview",gc_centerview}, - {"gc_mouseaiming",gc_mouseaiming}, - {"gc_talkkey",gc_talkkey}, - {"gc_teamkey",gc_teamkey}, - {"gc_scores",gc_scores}, - {"gc_jump",gc_jump}, - {"gc_console",gc_console}, - {"gc_pause",gc_pause}, - {"gc_systemmenu",gc_systemmenu}, - {"gc_screenshot",gc_screenshot}, - {"gc_recordgif",gc_recordgif}, - {"gc_viewpoint",gc_viewpoint}, - {"gc_custom1",gc_custom1}, - {"gc_custom2",gc_custom2}, - {"gc_custom3",gc_custom3}, - {"num_gamecontrols",num_gamecontrols}, + {"GC_NULL",GC_NULL}, + {"GC_FORWARD",GC_FORWARD}, + {"GC_BACKWARD",GC_BACKWARD}, + {"GC_STRAFELEFT",GC_STRAFELEFT}, + {"GC_STRAFERIGHT",GC_STRAFERIGHT}, + {"GC_TURNLEFT",GC_TURNLEFT}, + {"GC_TURNRIGHT",GC_TURNRIGHT}, + {"GC_WEAPONNEXT",GC_WEAPONNEXT}, + {"GC_WEAPONPREV",GC_WEAPONPREV}, + {"GC_WEPSLOT1",GC_WEPSLOT1}, + {"GC_WEPSLOT2",GC_WEPSLOT2}, + {"GC_WEPSLOT3",GC_WEPSLOT3}, + {"GC_WEPSLOT4",GC_WEPSLOT4}, + {"GC_WEPSLOT5",GC_WEPSLOT5}, + {"GC_WEPSLOT6",GC_WEPSLOT6}, + {"GC_WEPSLOT7",GC_WEPSLOT7}, + {"GC_WEPSLOT8",GC_WEPSLOT8}, + {"GC_WEPSLOT9",GC_WEPSLOT9}, + {"GC_WEPSLOT10",GC_WEPSLOT10}, + {"GC_FIRE",GC_FIRE}, + {"GC_FIRENORMAL",GC_FIRENORMAL}, + {"GC_TOSSFLAG",GC_TOSSFLAG}, + {"GC_SPIN",GC_SPIN}, + {"GC_CAMTOGGLE",GC_CAMTOGGLE}, + {"GC_CAMRESET",GC_CAMRESET}, + {"GC_LOOKUP",GC_LOOKUP}, + {"GC_LOOKDOWN",GC_LOOKDOWN}, + {"GC_CENTERVIEW",GC_CENTERVIEW}, + {"GC_MOUSEAIMING",GC_MOUSEAIMING}, + {"GC_TALKKEY",GC_TALKKEY}, + {"GC_TEAMKEY",GC_TEAMKEY}, + {"GC_SCORES",GC_SCORES}, + {"GC_JUMP",GC_JUMP}, + {"GC_CONSOLE",GC_CONSOLE}, + {"GC_PAUSE",GC_PAUSE}, + {"GC_SYSTEMMENU",GC_SYSTEMMENU}, + {"GC_SCREENSHOT",GC_SCREENSHOT}, + {"GC_RECORDGIF",GC_RECORDGIF}, + {"GC_VIEWPOINT",GC_VIEWPOINT}, + {"GC_CUSTOM1",GC_CUSTOM1}, + {"GC_CUSTOM2",GC_CUSTOM2}, + {"GC_CUSTOM3",GC_CUSTOM3}, + {"NUM_GAMECONTROLS",NUM_GAMECONTROLS}, // Mouse buttons {"MB_BUTTON1",MB_BUTTON1}, diff --git a/src/g_game.c b/src/g_game.c index 5c89bcae8..bc86e255a 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1140,13 +1140,13 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) return; } - turnright = PLAYERINPUTDOWN(ssplayer, gc_turnright); - turnleft = PLAYERINPUTDOWN(ssplayer, gc_turnleft); + turnright = PLAYERINPUTDOWN(ssplayer, GC_TURNRIGHT); + turnleft = PLAYERINPUTDOWN(ssplayer, GC_TURNLEFT); - straferkey = PLAYERINPUTDOWN(ssplayer, gc_straferight); - strafelkey = PLAYERINPUTDOWN(ssplayer, gc_strafeleft); - movefkey = PLAYERINPUTDOWN(ssplayer, gc_forward); - movebkey = PLAYERINPUTDOWN(ssplayer, gc_backward); + straferkey = PLAYERINPUTDOWN(ssplayer, GC_STRAFERIGHT); + strafelkey = PLAYERINPUTDOWN(ssplayer, GC_STRAFELEFT); + movefkey = PLAYERINPUTDOWN(ssplayer, GC_FORWARD); + movebkey = PLAYERINPUTDOWN(ssplayer, GC_BACKWARD); if (strafeisturn) { @@ -1155,7 +1155,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) straferkey = strafelkey = false; } - mouseaiming = (PLAYERINPUTDOWN(ssplayer, gc_mouseaiming)) ^ + mouseaiming = (PLAYERINPUTDOWN(ssplayer, GC_MOUSEAIMING)) ^ ((chasecam && !player->spectator) ? chasefreelook : alwaysfreelook); analogjoystickmove = usejoystick && !Joystick.bGamepadStyle; gamepadjoystickmove = usejoystick && Joystick.bGamepadStyle; @@ -1271,11 +1271,11 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) // forward with key or button if (movefkey || (gamepadjoystickmove && movejoystickvector.yaxis < 0) || ((player->powers[pw_carry] == CR_NIGHTSMODE) - && (PLAYERINPUTDOWN(ssplayer, gc_lookup) || (gamepadjoystickmove && lookjoystickvector.yaxis > 0)))) + && (PLAYERINPUTDOWN(ssplayer, GC_LOOKUP) || (gamepadjoystickmove && lookjoystickvector.yaxis > 0)))) forward = forwardmove[speed]; if (movebkey || (gamepadjoystickmove && movejoystickvector.yaxis > 0) || ((player->powers[pw_carry] == CR_NIGHTSMODE) - && (PLAYERINPUTDOWN(ssplayer, gc_lookdown) || (gamepadjoystickmove && lookjoystickvector.yaxis < 0)))) + && (PLAYERINPUTDOWN(ssplayer, GC_LOOKDOWN) || (gamepadjoystickmove && lookjoystickvector.yaxis < 0)))) forward -= forwardmove[speed]; if (analogjoystickmove && movejoystickvector.yaxis != 0) @@ -1288,9 +1288,9 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) if (strafelkey) side -= sidemove[speed]; - if (PLAYERINPUTDOWN(ssplayer, gc_weaponnext)) + if (PLAYERINPUTDOWN(ssplayer, GC_WEAPONNEXT)) cmd->buttons |= BT_WEAPONNEXT; // Next Weapon - if (PLAYERINPUTDOWN(ssplayer, gc_weaponprev)) + if (PLAYERINPUTDOWN(ssplayer, GC_WEAPONPREV)) cmd->buttons |= BT_WEAPONPREV; // Previous Weapon #if NUM_WEAPONS > 10 @@ -1299,7 +1299,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) //use the four avaliable bits to determine the weapon. cmd->buttons &= ~BT_WEAPONMASK; for (i = 0; i < NUM_WEAPONS; ++i) - if (PLAYERINPUTDOWN(ssplayer, gc_wepslot1 + i)) + if (PLAYERINPUTDOWN(ssplayer, GC_WEPSLOT1 + i)) { cmd->buttons |= (UINT16)(i + 1); break; @@ -1307,34 +1307,34 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) // fire with any button/key axis = PlayerJoyAxis(ssplayer, JA_FIRE); - if (PLAYERINPUTDOWN(ssplayer, gc_fire) || (usejoystick && axis > 0)) + if (PLAYERINPUTDOWN(ssplayer, GC_FIRE) || (usejoystick && axis > 0)) cmd->buttons |= BT_ATTACK; // fire normal with any button/key axis = PlayerJoyAxis(ssplayer, JA_FIRENORMAL); - if (PLAYERINPUTDOWN(ssplayer, gc_firenormal) || (usejoystick && axis > 0)) + if (PLAYERINPUTDOWN(ssplayer, GC_FIRENORMAL) || (usejoystick && axis > 0)) cmd->buttons |= BT_FIRENORMAL; - if (PLAYERINPUTDOWN(ssplayer, gc_tossflag)) + if (PLAYERINPUTDOWN(ssplayer, GC_TOSSFLAG)) cmd->buttons |= BT_TOSSFLAG; // Lua scriptable buttons - if (PLAYERINPUTDOWN(ssplayer, gc_custom1)) + if (PLAYERINPUTDOWN(ssplayer, GC_CUSTOM1)) cmd->buttons |= BT_CUSTOM1; - if (PLAYERINPUTDOWN(ssplayer, gc_custom2)) + if (PLAYERINPUTDOWN(ssplayer, GC_CUSTOM2)) cmd->buttons |= BT_CUSTOM2; - if (PLAYERINPUTDOWN(ssplayer, gc_custom3)) + if (PLAYERINPUTDOWN(ssplayer, GC_CUSTOM3)) cmd->buttons |= BT_CUSTOM3; // use with any button/key axis = PlayerJoyAxis(ssplayer, JA_SPIN); - if (PLAYERINPUTDOWN(ssplayer, gc_spin) || (usejoystick && axis > 0)) + if (PLAYERINPUTDOWN(ssplayer, GC_SPIN) || (usejoystick && axis > 0)) cmd->buttons |= BT_SPIN; // Centerview can be a toggle in simple mode! { static boolean last_centerviewdown[2], centerviewhold[2]; // detect taps for toggle behavior - boolean down = PLAYERINPUTDOWN(ssplayer, gc_centerview); + boolean down = PLAYERINPUTDOWN(ssplayer, GC_CENTERVIEW); if (!(controlstyle == CS_SIMPLE && cv_cam_centertoggle[forplayer].value)) centerviewdown = down; @@ -1433,7 +1433,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) if (ticcmd_centerviewdown[forplayer] && controlstyle == CS_SIMPLE) controlstyle = CS_LEGACY; - if (PLAYERINPUTDOWN(ssplayer, gc_camreset)) + if (PLAYERINPUTDOWN(ssplayer, GC_CAMRESET)) { if (thiscam->chase && !resetdown[forplayer]) P_ResetCamera(&players[ssplayer == 1 ? displayplayer : secondarydisplayplayer], thiscam); @@ -1446,7 +1446,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) // jump button axis = PlayerJoyAxis(ssplayer, JA_JUMP); - if (PLAYERINPUTDOWN(ssplayer, gc_jump) || (usejoystick && axis > 0)) + if (PLAYERINPUTDOWN(ssplayer, GC_JUMP) || (usejoystick && axis > 0)) cmd->buttons |= BT_JUMP; // player aiming shit, ahhhh... @@ -1476,12 +1476,12 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) if (!(player->powers[pw_carry] == CR_NIGHTSMODE)) { - if (PLAYERINPUTDOWN(ssplayer, gc_lookup) || (gamepadjoystickmove && lookjoystickvector.yaxis < 0)) + if (PLAYERINPUTDOWN(ssplayer, GC_LOOKUP) || (gamepadjoystickmove && lookjoystickvector.yaxis < 0)) { *myaiming += KB_LOOKSPEED * screen_invert; keyboard_look[forplayer] = true; } - else if (PLAYERINPUTDOWN(ssplayer, gc_lookdown) || (gamepadjoystickmove && lookjoystickvector.yaxis > 0)) + else if (PLAYERINPUTDOWN(ssplayer, GC_LOOKDOWN) || (gamepadjoystickmove && lookjoystickvector.yaxis > 0)) { *myaiming -= KB_LOOKSPEED * screen_invert; keyboard_look[forplayer] = true; @@ -2045,7 +2045,7 @@ boolean G_Responder(event_t *ev) // allow spy mode changes even during the demo if (gamestate == GS_LEVEL && ev->type == ev_keydown - && (ev->key == KEY_F12 || ev->key == gamecontrol[gc_viewpoint][0] || ev->key == gamecontrol[gc_viewpoint][1])) + && (ev->key == KEY_F12 || ev->key == gamecontrol[GC_VIEWPOINT][0] || ev->key == gamecontrol[GC_VIEWPOINT][1])) { // ViewpointSwitch Lua hook. UINT8 canSwitchView = 0; @@ -2118,8 +2118,8 @@ boolean G_Responder(event_t *ev) switch (ev->type) { case ev_keydown: - if (ev->key == gamecontrol[gc_pause][0] - || ev->key == gamecontrol[gc_pause][1] + if (ev->key == gamecontrol[GC_PAUSE][0] + || ev->key == gamecontrol[GC_PAUSE][1] || ev->key == KEY_PAUSE) { if (modeattacking && !demoplayback && (gamestate == GS_LEVEL)) @@ -2149,8 +2149,8 @@ boolean G_Responder(event_t *ev) } } } - if (ev->key == gamecontrol[gc_camtoggle][0] - || ev->key == gamecontrol[gc_camtoggle][1]) + if (ev->key == gamecontrol[GC_CAMTOGGLE][0] + || ev->key == gamecontrol[GC_CAMTOGGLE][1]) { if (!camtoggledelay) { @@ -2158,8 +2158,8 @@ boolean G_Responder(event_t *ev) CV_SetValue(&cv_chasecam, cv_chasecam.value ? 0 : 1); } } - if (ev->key == gamecontrolbis[gc_camtoggle][0] - || ev->key == gamecontrolbis[gc_camtoggle][1]) + if (ev->key == gamecontrolbis[GC_CAMTOGGLE][0] + || ev->key == gamecontrolbis[GC_CAMTOGGLE][1]) { if (!camtoggledelay2) { diff --git a/src/g_input.c b/src/g_input.c index 494edbd56..cd4536bba 100644 --- a/src/g_input.c +++ b/src/g_input.c @@ -41,49 +41,49 @@ INT32 joyxmove[JOYAXISSET], joyymove[JOYAXISSET], joy2xmove[JOYAXISSET], joy2ymo UINT8 gamekeydown[NUMINPUTS]; // two key codes (or virtual key) per game control -INT32 gamecontrol[num_gamecontrols][2]; -INT32 gamecontrolbis[num_gamecontrols][2]; // secondary splitscreen player -INT32 gamecontroldefault[num_gamecontrolschemes][num_gamecontrols][2]; // default control storage, use 0 (gcs_custom) for memory retention -INT32 gamecontrolbisdefault[num_gamecontrolschemes][num_gamecontrols][2]; +INT32 gamecontrol[NUM_GAMECONTROLS][2]; +INT32 gamecontrolbis[NUM_GAMECONTROLS][2]; // secondary splitscreen player +INT32 gamecontroldefault[num_gamecontrolschemes][NUM_GAMECONTROLS][2]; // default control storage, use 0 (gcs_custom) for memory retention +INT32 gamecontrolbisdefault[num_gamecontrolschemes][NUM_GAMECONTROLS][2]; // lists of GC codes for selective operation const INT32 gcl_tutorial_check[num_gcl_tutorial_check] = { - gc_forward, gc_backward, gc_strafeleft, gc_straferight, - gc_turnleft, gc_turnright + GC_FORWARD, GC_BACKWARD, GC_STRAFELEFT, GC_STRAFERIGHT, + GC_TURNLEFT, GC_TURNRIGHT }; const INT32 gcl_tutorial_used[num_gcl_tutorial_used] = { - gc_forward, gc_backward, gc_strafeleft, gc_straferight, - gc_turnleft, gc_turnright, - gc_jump, gc_spin + GC_FORWARD, GC_BACKWARD, GC_STRAFELEFT, GC_STRAFERIGHT, + GC_TURNLEFT, GC_TURNRIGHT, + GC_JUMP, GC_SPIN }; const INT32 gcl_tutorial_full[num_gcl_tutorial_full] = { - gc_forward, gc_backward, gc_strafeleft, gc_straferight, - gc_lookup, gc_lookdown, gc_turnleft, gc_turnright, gc_centerview, - gc_jump, gc_spin, - gc_fire, gc_firenormal + GC_FORWARD, GC_BACKWARD, GC_STRAFELEFT, GC_STRAFERIGHT, + GC_LOOKUP, GC_LOOKDOWN, GC_TURNLEFT, GC_TURNRIGHT, GC_CENTERVIEW, + GC_JUMP, GC_SPIN, + GC_FIRE, GC_FIRENORMAL }; const INT32 gcl_movement[num_gcl_movement] = { - gc_forward, gc_backward, gc_strafeleft, gc_straferight + GC_FORWARD, GC_BACKWARD, GC_STRAFELEFT, GC_STRAFERIGHT }; const INT32 gcl_camera[num_gcl_camera] = { - gc_turnleft, gc_turnright + GC_TURNLEFT, GC_TURNRIGHT }; const INT32 gcl_movement_camera[num_gcl_movement_camera] = { - gc_forward, gc_backward, gc_strafeleft, gc_straferight, - gc_turnleft, gc_turnright + GC_FORWARD, GC_BACKWARD, GC_STRAFELEFT, GC_STRAFERIGHT, + GC_TURNLEFT, GC_TURNRIGHT }; -const INT32 gcl_jump[num_gcl_jump] = { gc_jump }; +const INT32 gcl_jump[num_gcl_jump] = { GC_JUMP }; -const INT32 gcl_spin[num_gcl_spin] = { gc_spin }; +const INT32 gcl_spin[num_gcl_spin] = { GC_SPIN }; const INT32 gcl_jump_spin[num_gcl_jump_spin] = { - gc_jump, gc_spin + GC_JUMP, GC_SPIN }; typedef struct @@ -553,9 +553,9 @@ static keyname_t keynames[] = }; -static const char *gamecontrolname[num_gamecontrols] = +static const char *gamecontrolname[NUM_GAMECONTROLS] = { - "nothing", // a key/button mapped to gc_null has no effect + "nothing", // a key/button mapped to GC_NULL has no effect "forward", "backward", "strafeleft", @@ -613,7 +613,7 @@ void G_ClearControlKeys(INT32 (*setupcontrols)[2], INT32 control) void G_ClearAllControlKeys(void) { INT32 i; - for (i = 0; i < num_gamecontrols; i++) + for (i = 0; i < NUM_GAMECONTROLS; i++) { G_ClearControlKeys(gamecontrol, i); G_ClearControlKeys(gamecontrolbis, i); @@ -676,92 +676,92 @@ void G_DefineDefaultControls(void) INT32 i; // FPS game controls (WASD) - gamecontroldefault[gcs_fps][gc_forward ][0] = 'w'; - gamecontroldefault[gcs_fps][gc_backward ][0] = 's'; - gamecontroldefault[gcs_fps][gc_strafeleft ][0] = 'a'; - gamecontroldefault[gcs_fps][gc_straferight][0] = 'd'; - gamecontroldefault[gcs_fps][gc_lookup ][0] = KEY_UPARROW; - gamecontroldefault[gcs_fps][gc_lookdown ][0] = KEY_DOWNARROW; - gamecontroldefault[gcs_fps][gc_turnleft ][0] = KEY_LEFTARROW; - gamecontroldefault[gcs_fps][gc_turnright ][0] = KEY_RIGHTARROW; - gamecontroldefault[gcs_fps][gc_centerview ][0] = KEY_END; - gamecontroldefault[gcs_fps][gc_jump ][0] = KEY_SPACE; - gamecontroldefault[gcs_fps][gc_spin ][0] = KEY_LSHIFT; - gamecontroldefault[gcs_fps][gc_fire ][0] = KEY_RCTRL; - gamecontroldefault[gcs_fps][gc_fire ][1] = KEY_MOUSE1+0; - gamecontroldefault[gcs_fps][gc_firenormal ][0] = 'c'; + gamecontroldefault[gcs_fps][GC_FORWARD ][0] = 'w'; + gamecontroldefault[gcs_fps][GC_BACKWARD ][0] = 's'; + gamecontroldefault[gcs_fps][GC_STRAFELEFT ][0] = 'a'; + gamecontroldefault[gcs_fps][GC_STRAFERIGHT][0] = 'd'; + gamecontroldefault[gcs_fps][GC_LOOKUP ][0] = KEY_UPARROW; + gamecontroldefault[gcs_fps][GC_LOOKDOWN ][0] = KEY_DOWNARROW; + gamecontroldefault[gcs_fps][GC_TURNLEFT ][0] = KEY_LEFTARROW; + gamecontroldefault[gcs_fps][GC_TURNRIGHT ][0] = KEY_RIGHTARROW; + gamecontroldefault[gcs_fps][GC_CENTERVIEW ][0] = KEY_END; + gamecontroldefault[gcs_fps][GC_JUMP ][0] = KEY_SPACE; + gamecontroldefault[gcs_fps][GC_SPIN ][0] = KEY_LSHIFT; + gamecontroldefault[gcs_fps][GC_FIRE ][0] = KEY_RCTRL; + gamecontroldefault[gcs_fps][GC_FIRE ][1] = KEY_MOUSE1+0; + gamecontroldefault[gcs_fps][GC_FIRENORMAL ][0] = 'c'; // Platform game controls (arrow keys) - gamecontroldefault[gcs_platform][gc_forward ][0] = KEY_UPARROW; - gamecontroldefault[gcs_platform][gc_backward ][0] = KEY_DOWNARROW; - gamecontroldefault[gcs_platform][gc_strafeleft ][0] = 'a'; - gamecontroldefault[gcs_platform][gc_straferight][0] = 'd'; - gamecontroldefault[gcs_platform][gc_lookup ][0] = KEY_PGUP; - gamecontroldefault[gcs_platform][gc_lookdown ][0] = KEY_PGDN; - gamecontroldefault[gcs_platform][gc_turnleft ][0] = KEY_LEFTARROW; - gamecontroldefault[gcs_platform][gc_turnright ][0] = KEY_RIGHTARROW; - gamecontroldefault[gcs_platform][gc_centerview ][0] = KEY_END; - gamecontroldefault[gcs_platform][gc_jump ][0] = KEY_SPACE; - gamecontroldefault[gcs_platform][gc_spin ][0] = KEY_LSHIFT; - gamecontroldefault[gcs_platform][gc_fire ][0] = 's'; - gamecontroldefault[gcs_platform][gc_fire ][1] = KEY_MOUSE1+0; - gamecontroldefault[gcs_platform][gc_firenormal ][0] = 'w'; + gamecontroldefault[gcs_platform][GC_FORWARD ][0] = KEY_UPARROW; + gamecontroldefault[gcs_platform][GC_BACKWARD ][0] = KEY_DOWNARROW; + gamecontroldefault[gcs_platform][GC_STRAFELEFT ][0] = 'a'; + gamecontroldefault[gcs_platform][GC_STRAFERIGHT][0] = 'd'; + gamecontroldefault[gcs_platform][GC_LOOKUP ][0] = KEY_PGUP; + gamecontroldefault[gcs_platform][GC_LOOKDOWN ][0] = KEY_PGDN; + gamecontroldefault[gcs_platform][GC_TURNLEFT ][0] = KEY_LEFTARROW; + gamecontroldefault[gcs_platform][GC_TURNRIGHT ][0] = KEY_RIGHTARROW; + gamecontroldefault[gcs_platform][GC_CENTERVIEW ][0] = KEY_END; + gamecontroldefault[gcs_platform][GC_JUMP ][0] = KEY_SPACE; + gamecontroldefault[gcs_platform][GC_SPIN ][0] = KEY_LSHIFT; + gamecontroldefault[gcs_platform][GC_FIRE ][0] = 's'; + gamecontroldefault[gcs_platform][GC_FIRE ][1] = KEY_MOUSE1+0; + gamecontroldefault[gcs_platform][GC_FIRENORMAL ][0] = 'w'; for (i = 1; i < num_gamecontrolschemes; i++) // skip gcs_custom (0) { - gamecontroldefault[i][gc_weaponnext ][0] = KEY_MOUSEWHEELUP+0; - gamecontroldefault[i][gc_weaponprev ][0] = KEY_MOUSEWHEELDOWN+0; - gamecontroldefault[i][gc_wepslot1 ][0] = '1'; - gamecontroldefault[i][gc_wepslot2 ][0] = '2'; - gamecontroldefault[i][gc_wepslot3 ][0] = '3'; - gamecontroldefault[i][gc_wepslot4 ][0] = '4'; - gamecontroldefault[i][gc_wepslot5 ][0] = '5'; - gamecontroldefault[i][gc_wepslot6 ][0] = '6'; - gamecontroldefault[i][gc_wepslot7 ][0] = '7'; - gamecontroldefault[i][gc_wepslot8 ][0] = '8'; - gamecontroldefault[i][gc_wepslot9 ][0] = '9'; - gamecontroldefault[i][gc_wepslot10 ][0] = '0'; - gamecontroldefault[i][gc_tossflag ][0] = '\''; - gamecontroldefault[i][gc_camtoggle ][0] = 'v'; - gamecontroldefault[i][gc_camreset ][0] = 'r'; - gamecontroldefault[i][gc_talkkey ][0] = 't'; - gamecontroldefault[i][gc_teamkey ][0] = 'y'; - gamecontroldefault[i][gc_scores ][0] = KEY_TAB; - gamecontroldefault[i][gc_console ][0] = KEY_CONSOLE; - gamecontroldefault[i][gc_pause ][0] = 'p'; - gamecontroldefault[i][gc_screenshot ][0] = KEY_F8; - gamecontroldefault[i][gc_recordgif ][0] = KEY_F9; - gamecontroldefault[i][gc_viewpoint ][0] = KEY_F12; + gamecontroldefault[i][GC_WEAPONNEXT ][0] = KEY_MOUSEWHEELUP+0; + gamecontroldefault[i][GC_WEAPONPREV ][0] = KEY_MOUSEWHEELDOWN+0; + gamecontroldefault[i][GC_WEPSLOT1 ][0] = '1'; + gamecontroldefault[i][GC_WEPSLOT2 ][0] = '2'; + gamecontroldefault[i][GC_WEPSLOT3 ][0] = '3'; + gamecontroldefault[i][GC_WEPSLOT4 ][0] = '4'; + gamecontroldefault[i][GC_WEPSLOT5 ][0] = '5'; + gamecontroldefault[i][GC_WEPSLOT6 ][0] = '6'; + gamecontroldefault[i][GC_WEPSLOT7 ][0] = '7'; + gamecontroldefault[i][GC_WEPSLOT8 ][0] = '8'; + gamecontroldefault[i][GC_WEPSLOT9 ][0] = '9'; + gamecontroldefault[i][GC_WEPSLOT10 ][0] = '0'; + gamecontroldefault[i][GC_TOSSFLAG ][0] = '\''; + gamecontroldefault[i][GC_CAMTOGGLE ][0] = 'v'; + gamecontroldefault[i][GC_CAMRESET ][0] = 'r'; + gamecontroldefault[i][GC_TALKKEY ][0] = 't'; + gamecontroldefault[i][GC_TEAMKEY ][0] = 'y'; + gamecontroldefault[i][GC_SCORES ][0] = KEY_TAB; + gamecontroldefault[i][GC_CONSOLE ][0] = KEY_CONSOLE; + gamecontroldefault[i][GC_PAUSE ][0] = 'p'; + gamecontroldefault[i][GC_SCREENSHOT ][0] = KEY_F8; + gamecontroldefault[i][GC_RECORDGIF ][0] = KEY_F9; + gamecontroldefault[i][GC_VIEWPOINT ][0] = KEY_F12; // Gamepad controls -- same for both schemes - gamecontroldefault[i][gc_weaponnext ][1] = KEY_JOY1+1; // B - gamecontroldefault[i][gc_weaponprev ][1] = KEY_JOY1+2; // X - gamecontroldefault[i][gc_tossflag ][1] = KEY_JOY1+0; // A - gamecontroldefault[i][gc_spin ][1] = KEY_JOY1+4; // LB - gamecontroldefault[i][gc_camtoggle ][1] = KEY_HAT1+0; // D-Pad Up - gamecontroldefault[i][gc_camreset ][1] = KEY_JOY1+3; // Y - gamecontroldefault[i][gc_centerview ][1] = KEY_JOY1+9; // Right Stick - gamecontroldefault[i][gc_talkkey ][1] = KEY_HAT1+2; // D-Pad Left - gamecontroldefault[i][gc_scores ][1] = KEY_HAT1+3; // D-Pad Right - gamecontroldefault[i][gc_jump ][1] = KEY_JOY1+5; // RB - gamecontroldefault[i][gc_pause ][1] = KEY_JOY1+6; // Back - gamecontroldefault[i][gc_screenshot ][1] = KEY_HAT1+1; // D-Pad Down - gamecontroldefault[i][gc_systemmenu ][0] = KEY_JOY1+7; // Start + gamecontroldefault[i][GC_WEAPONNEXT ][1] = KEY_JOY1+1; // B + gamecontroldefault[i][GC_WEAPONPREV ][1] = KEY_JOY1+2; // X + gamecontroldefault[i][GC_TOSSFLAG ][1] = KEY_JOY1+0; // A + gamecontroldefault[i][GC_SPIN ][1] = KEY_JOY1+4; // LB + gamecontroldefault[i][GC_CAMTOGGLE ][1] = KEY_HAT1+0; // D-Pad Up + gamecontroldefault[i][GC_CAMRESET ][1] = KEY_JOY1+3; // Y + gamecontroldefault[i][GC_CENTERVIEW ][1] = KEY_JOY1+9; // Right Stick + gamecontroldefault[i][GC_TALKKEY ][1] = KEY_HAT1+2; // D-Pad Left + gamecontroldefault[i][GC_SCORES ][1] = KEY_HAT1+3; // D-Pad Right + gamecontroldefault[i][GC_JUMP ][1] = KEY_JOY1+5; // RB + gamecontroldefault[i][GC_PAUSE ][1] = KEY_JOY1+6; // Back + gamecontroldefault[i][GC_SCREENSHOT ][1] = KEY_HAT1+1; // D-Pad Down + gamecontroldefault[i][GC_SYSTEMMENU ][0] = KEY_JOY1+7; // Start // Second player controls only have joypad defaults - gamecontrolbisdefault[i][gc_weaponnext][0] = KEY_2JOY1+1; // B - gamecontrolbisdefault[i][gc_weaponprev][0] = KEY_2JOY1+2; // X - gamecontrolbisdefault[i][gc_tossflag ][0] = KEY_2JOY1+0; // A - gamecontrolbisdefault[i][gc_spin ][0] = KEY_2JOY1+4; // LB - gamecontrolbisdefault[i][gc_camreset ][0] = KEY_2JOY1+3; // Y - gamecontrolbisdefault[i][gc_centerview][0] = KEY_2JOY1+9; // Right Stick - gamecontrolbisdefault[i][gc_jump ][0] = KEY_2JOY1+5; // RB - //gamecontrolbisdefault[i][gc_pause ][0] = KEY_2JOY1+6; // Back - //gamecontrolbisdefault[i][gc_systemmenu][0] = KEY_2JOY1+7; // Start - gamecontrolbisdefault[i][gc_camtoggle ][0] = KEY_2HAT1+0; // D-Pad Up - gamecontrolbisdefault[i][gc_screenshot][0] = KEY_2HAT1+1; // D-Pad Down - //gamecontrolbisdefault[i][gc_talkkey ][0] = KEY_2HAT1+2; // D-Pad Left - //gamecontrolbisdefault[i][gc_scores ][0] = KEY_2HAT1+3; // D-Pad Right + gamecontrolbisdefault[i][GC_WEAPONNEXT][0] = KEY_2JOY1+1; // B + gamecontrolbisdefault[i][GC_WEAPONPREV][0] = KEY_2JOY1+2; // X + gamecontrolbisdefault[i][GC_TOSSFLAG ][0] = KEY_2JOY1+0; // A + gamecontrolbisdefault[i][GC_SPIN ][0] = KEY_2JOY1+4; // LB + gamecontrolbisdefault[i][GC_CAMRESET ][0] = KEY_2JOY1+3; // Y + gamecontrolbisdefault[i][GC_CENTERVIEW][0] = KEY_2JOY1+9; // Right Stick + gamecontrolbisdefault[i][GC_JUMP ][0] = KEY_2JOY1+5; // RB + //gamecontrolbisdefault[i][GC_PAUSE ][0] = KEY_2JOY1+6; // Back + //gamecontrolbisdefault[i][GC_SYSTEMMENU][0] = KEY_2JOY1+7; // Start + gamecontrolbisdefault[i][GC_CAMTOGGLE ][0] = KEY_2HAT1+0; // D-Pad Up + gamecontrolbisdefault[i][GC_SCREENSHOT][0] = KEY_2HAT1+1; // D-Pad Down + //gamecontrolbisdefault[i][GC_TALKKEY ][0] = KEY_2HAT1+2; // D-Pad Left + //gamecontrolbisdefault[i][GC_SCORES ][0] = KEY_2HAT1+3; // D-Pad Right } } @@ -773,7 +773,7 @@ INT32 G_GetControlScheme(INT32 (*fromcontrols)[2], const INT32 *gclist, INT32 gc for (i = 1; i < num_gamecontrolschemes; i++) // skip gcs_custom (0) { skipscheme = false; - for (j = 0; j < (gclist && gclen ? gclen : num_gamecontrols); j++) + for (j = 0; j < (gclist && gclen ? gclen : NUM_GAMECONTROLS); j++) { gc = (gclist && gclen) ? gclist[j] : j; if (((fromcontrols[gc][0] && gamecontroldefault[i][gc][0]) ? fromcontrols[gc][0] != gamecontroldefault[i][gc][0] : true) && @@ -796,7 +796,7 @@ void G_CopyControls(INT32 (*setupcontrols)[2], INT32 (*fromcontrols)[2], const I { INT32 i, gc; - for (i = 0; i < (gclist && gclen ? gclen : num_gamecontrols); i++) + for (i = 0; i < (gclist && gclen ? gclen : NUM_GAMECONTROLS); i++) { gc = (gclist && gclen) ? gclist[i] : i; setupcontrols[gc][0] = fromcontrols[gc][0]; @@ -808,7 +808,7 @@ void G_SaveKeySetting(FILE *f, INT32 (*fromcontrols)[2], INT32 (*fromcontrolsbis { INT32 i; - for (i = 1; i < num_gamecontrols; i++) + for (i = 1; i < NUM_GAMECONTROLS; i++) { fprintf(f, "setcontrol \"%s\" \"%s\"", gamecontrolname[i], G_KeyNumToName(fromcontrols[i][0])); @@ -819,7 +819,7 @@ void G_SaveKeySetting(FILE *f, INT32 (*fromcontrols)[2], INT32 (*fromcontrolsbis fprintf(f, "\n"); } - for (i = 1; i < num_gamecontrols; i++) + for (i = 1; i < NUM_GAMECONTROLS; i++) { fprintf(f, "setcontrol2 \"%s\" \"%s\"", gamecontrolname[i], G_KeyNumToName(fromcontrolsbis[i][0])); @@ -833,11 +833,11 @@ void G_SaveKeySetting(FILE *f, INT32 (*fromcontrols)[2], INT32 (*fromcontrolsbis INT32 G_CheckDoubleUsage(INT32 keynum, boolean modify) { - INT32 result = gc_null; + INT32 result = GC_NULL; if (cv_controlperkey.value == 1) { INT32 i; - for (i = 0; i < num_gamecontrols; i++) + for (i = 0; i < NUM_GAMECONTROLS; i++) { if (gamecontrol[i][0] == keynum) { @@ -883,11 +883,11 @@ static INT32 G_FilterKeyByVersion(INT32 numctrl, INT32 keyidx, INT32 player, INT return -1; // skip setting control if (GETMAJOREXECVERSION(cv_execversion.value) < 27 && ( // v2.1.22 - numctrl == gc_weaponnext || numctrl == gc_weaponprev || numctrl == gc_tossflag || - numctrl == gc_spin || numctrl == gc_camreset || numctrl == gc_jump || - numctrl == gc_pause || numctrl == gc_systemmenu || numctrl == gc_camtoggle || - numctrl == gc_screenshot || numctrl == gc_talkkey || numctrl == gc_scores || - numctrl == gc_centerview + numctrl == GC_WEAPONNEXT || numctrl == GC_WEAPONPREV || numctrl == GC_TOSSFLAG || + numctrl == GC_SPIN || numctrl == GC_CAMRESET || numctrl == GC_JUMP || + numctrl == GC_PAUSE || numctrl == GC_SYSTEMMENU || numctrl == GC_CAMTOGGLE || + numctrl == GC_SCREENSHOT || numctrl == GC_TALKKEY || numctrl == GC_SCORES || + numctrl == GC_CENTERVIEW )) { INT32 keynum = 0, existingctrl = 0; @@ -895,7 +895,7 @@ static INT32 G_FilterKeyByVersion(INT32 numctrl, INT32 keyidx, INT32 player, INT boolean defaultoverride = false; // get the default gamecontrol - if (player == 0 && numctrl == gc_systemmenu) + if (player == 0 && numctrl == GC_SYSTEMMENU) defaultkey = gamecontrol[numctrl][0]; else defaultkey = (player == 1 ? gamecontrolbis[numctrl][0] : gamecontrol[numctrl][1]); @@ -993,10 +993,10 @@ static void setcontrol(INT32 (*gc)[2]) // Update me for 2.3 namectrl = (stricmp(COM_Argv(1), "use")) ? COM_Argv(1) : "spin"; - for (numctrl = 0; numctrl < num_gamecontrols && stricmp(namectrl, gamecontrolname[numctrl]); + for (numctrl = 0; numctrl < NUM_GAMECONTROLS && stricmp(namectrl, gamecontrolname[numctrl]); numctrl++) ; - if (numctrl == num_gamecontrols) + if (numctrl == NUM_GAMECONTROLS) { CONS_Printf(M_GetText("Control '%s' unknown\n"), namectrl); return; diff --git a/src/g_input.h b/src/g_input.h index 39c0180e7..2e9f53dcf 100644 --- a/src/g_input.h +++ b/src/g_input.h @@ -58,49 +58,49 @@ typedef enum typedef enum { - gc_null = 0, // a key/button mapped to gc_null has no effect - gc_forward, - gc_backward, - gc_strafeleft, - gc_straferight, - gc_turnleft, - gc_turnright, - gc_weaponnext, - gc_weaponprev, - gc_wepslot1, - gc_wepslot2, - gc_wepslot3, - gc_wepslot4, - gc_wepslot5, - gc_wepslot6, - gc_wepslot7, - gc_wepslot8, - gc_wepslot9, - gc_wepslot10, - gc_fire, - gc_firenormal, - gc_tossflag, - gc_spin, - gc_camtoggle, - gc_camreset, - gc_lookup, - gc_lookdown, - gc_centerview, - gc_mouseaiming, // mouse aiming is momentary (toggleable in the menu) - gc_talkkey, - gc_teamkey, - gc_scores, - gc_jump, - gc_console, - gc_pause, - gc_systemmenu, - gc_screenshot, - gc_recordgif, - gc_viewpoint, - gc_custom1, // Lua scriptable - gc_custom2, // Lua scriptable - gc_custom3, // Lua scriptable - num_gamecontrols + GC_NULL = 0, // a key/button mapped to GC_NULL has no effect + GC_FORWARD, + GC_BACKWARD, + GC_STRAFELEFT, + GC_STRAFERIGHT, + GC_TURNLEFT, + GC_TURNRIGHT, + GC_WEAPONNEXT, + GC_WEAPONPREV, + GC_WEPSLOT1, + GC_WEPSLOT2, + GC_WEPSLOT3, + GC_WEPSLOT4, + GC_WEPSLOT5, + GC_WEPSLOT6, + GC_WEPSLOT7, + GC_WEPSLOT8, + GC_WEPSLOT9, + GC_WEPSLOT10, + GC_FIRE, + GC_FIRENORMAL, + GC_TOSSFLAG, + GC_SPIN, + GC_CAMTOGGLE, + GC_CAMRESET, + GC_LOOKUP, + GC_LOOKDOWN, + GC_CENTERVIEW, + GC_MOUSEAIMING, // mouse aiming is momentary (toggleable in the menu) + GC_TALKKEY, + GC_TEAMKEY, + GC_SCORES, + GC_JUMP, + GC_CONSOLE, + GC_PAUSE, + GC_SYSTEMMENU, + GC_SCREENSHOT, + GC_RECORDGIF, + GC_VIEWPOINT, + GC_CUSTOM1, // Lua scriptable + GC_CUSTOM2, // Lua scriptable + GC_CUSTOM3, // Lua scriptable + NUM_GAMECONTROLS } gamecontrols_e; typedef enum @@ -146,10 +146,10 @@ extern INT32 joyxmove[JOYAXISSET], joyymove[JOYAXISSET], joy2xmove[JOYAXISSET], extern UINT8 gamekeydown[NUMINPUTS]; // two key codes (or virtual key) per game control -extern INT32 gamecontrol[num_gamecontrols][2]; -extern INT32 gamecontrolbis[num_gamecontrols][2]; // secondary splitscreen player -extern INT32 gamecontroldefault[num_gamecontrolschemes][num_gamecontrols][2]; // default control storage, use 0 (gcs_custom) for memory retention -extern INT32 gamecontrolbisdefault[num_gamecontrolschemes][num_gamecontrols][2]; +extern INT32 gamecontrol[NUM_GAMECONTROLS][2]; +extern INT32 gamecontrolbis[NUM_GAMECONTROLS][2]; // secondary splitscreen player +extern INT32 gamecontroldefault[num_gamecontrolschemes][NUM_GAMECONTROLS][2]; // default control storage, use 0 (gcs_custom) for memory retention +extern INT32 gamecontrolbisdefault[num_gamecontrolschemes][NUM_GAMECONTROLS][2]; #define PLAYER1INPUTDOWN(gc) (gamekeydown[gamecontrol[gc][0]] || gamekeydown[gamecontrol[gc][1]]) #define PLAYER2INPUTDOWN(gc) (gamekeydown[gamecontrolbis[gc][0]] || gamekeydown[gamecontrolbis[gc][1]]) #define PLAYERINPUTDOWN(p, gc) ((p) == 2 ? PLAYER2INPUTDOWN(gc) : PLAYER1INPUTDOWN(gc)) diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 3bd263210..d8891d508 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -936,7 +936,7 @@ void HU_Ticker(void) hu_tick++; hu_tick &= 7; // currently only to blink chat input cursor - if (PLAYER1INPUTDOWN(gc_scores)) + if (PLAYER1INPUTDOWN(GC_SCORES)) hu_showscores = !chat_on; else hu_showscores = false; @@ -1114,13 +1114,13 @@ boolean HU_Responder(event_t *ev) if (ev->key >= KEY_MOUSE1) { INT32 i; - for (i = 0; i < num_gamecontrols; i++) + for (i = 0; i < NUM_GAMECONTROLS; i++) { if (gamecontrol[i][0] == ev->key || gamecontrol[i][1] == ev->key) break; } - if (i == num_gamecontrols) + if (i == NUM_GAMECONTROLS) return false; }*/ //We don't actually care about that unless we get splitscreen netgames. :V @@ -1130,7 +1130,7 @@ boolean HU_Responder(event_t *ev) if (!chat_on) { // enter chat mode - if ((ev->key == gamecontrol[gc_talkkey][0] || ev->key == gamecontrol[gc_talkkey][1]) + if ((ev->key == gamecontrol[GC_TALKKEY][0] || ev->key == gamecontrol[GC_TALKKEY][1]) && netgame && !OLD_MUTE) // check for old chat mute, still let the players open the chat incase they want to scroll otherwise. { chat_on = true; @@ -1140,7 +1140,7 @@ boolean HU_Responder(event_t *ev) typelines = 1; return true; } - if ((ev->key == gamecontrol[gc_teamkey][0] || ev->key == gamecontrol[gc_teamkey][1]) + if ((ev->key == gamecontrol[GC_TEAMKEY][0] || ev->key == gamecontrol[GC_TEAMKEY][1]) && netgame && !OLD_MUTE) { chat_on = true; @@ -1234,8 +1234,8 @@ boolean HU_Responder(event_t *ev) I_UpdateMouseGrab(); } else if (c == KEY_ESCAPE - || ((c == gamecontrol[gc_talkkey][0] || c == gamecontrol[gc_talkkey][1] - || c == gamecontrol[gc_teamkey][0] || c == gamecontrol[gc_teamkey][1]) + || ((c == gamecontrol[GC_TALKKEY][0] || c == gamecontrol[GC_TALKKEY][1] + || c == gamecontrol[GC_TEAMKEY][0] || c == gamecontrol[GC_TEAMKEY][1]) && c >= KEY_MOUSE1)) // If it's not a keyboard key, then the chat button is used as a toggle. { chat_on = false; diff --git a/src/lua_inputlib.c b/src/lua_inputlib.c index 3affeea7b..6e3085e94 100644 --- a/src/lua_inputlib.c +++ b/src/lua_inputlib.c @@ -26,8 +26,8 @@ static int lib_gameControlDown(lua_State *L) { int i = luaL_checkinteger(L, 1); - if (i < 0 || i >= num_gamecontrols) - return luaL_error(L, "gc_* constant %d out of range (0 - %d)", i, num_gamecontrols-1); + if (i < 0 || i >= NUM_GAMECONTROLS) + return luaL_error(L, "GC_* constant %d out of range (0 - %d)", i, NUM_GAMECONTROLS-1); lua_pushinteger(L, PLAYER1INPUTDOWN(i)); return 1; } @@ -35,8 +35,8 @@ static int lib_gameControlDown(lua_State *L) static int lib_gameControl2Down(lua_State *L) { int i = luaL_checkinteger(L, 1); - if (i < 0 || i >= num_gamecontrols) - return luaL_error(L, "gc_* constant %d out of range (0 - %d)", i, num_gamecontrols-1); + if (i < 0 || i >= NUM_GAMECONTROLS) + return luaL_error(L, "GC_* constant %d out of range (0 - %d)", i, NUM_GAMECONTROLS-1); lua_pushinteger(L, PLAYER2INPUTDOWN(i)); return 1; } @@ -44,8 +44,8 @@ static int lib_gameControl2Down(lua_State *L) static int lib_gameControlToKeyNum(lua_State *L) { int i = luaL_checkinteger(L, 1); - if (i < 0 || i >= num_gamecontrols) - return luaL_error(L, "gc_* constant %d out of range (0 - %d)", i, num_gamecontrols-1); + if (i < 0 || i >= NUM_GAMECONTROLS) + return luaL_error(L, "GC_* constant %d out of range (0 - %d)", i, NUM_GAMECONTROLS-1); lua_pushinteger(L, gamecontrol[i][0]); lua_pushinteger(L, gamecontrol[i][1]); return 2; @@ -54,8 +54,8 @@ static int lib_gameControlToKeyNum(lua_State *L) static int lib_gameControl2ToKeyNum(lua_State *L) { int i = luaL_checkinteger(L, 1); - if (i < 0 || i >= num_gamecontrols) - return luaL_error(L, "gc_* constant %d out of range (0 - %d)", i, num_gamecontrols-1); + if (i < 0 || i >= NUM_GAMECONTROLS) + return luaL_error(L, "GC_* constant %d out of range (0 - %d)", i, NUM_GAMECONTROLS-1); lua_pushinteger(L, gamecontrolbis[i][0]); lua_pushinteger(L, gamecontrolbis[i][1]); return 2; diff --git a/src/m_menu.c b/src/m_menu.c index 4a0fefb1b..56d7e889e 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1106,55 +1106,55 @@ static menuitem_t OP_ChangeControlsMenu[] = { {IT_HEADER, NULL, "Movement", NULL, 0}, {IT_SPACE, NULL, NULL, NULL, 0}, // padding - {IT_CALL | IT_STRING2, NULL, "Move Forward", M_ChangeControl, gc_forward }, - {IT_CALL | IT_STRING2, NULL, "Move Backward", M_ChangeControl, gc_backward }, - {IT_CALL | IT_STRING2, NULL, "Move Left", M_ChangeControl, gc_strafeleft }, - {IT_CALL | IT_STRING2, NULL, "Move Right", M_ChangeControl, gc_straferight }, - {IT_CALL | IT_STRING2, NULL, "Jump", M_ChangeControl, gc_jump }, - {IT_CALL | IT_STRING2, NULL, "Spin", M_ChangeControl, gc_spin }, + {IT_CALL | IT_STRING2, NULL, "Move Forward", M_ChangeControl, GC_FORWARD }, + {IT_CALL | IT_STRING2, NULL, "Move Backward", M_ChangeControl, GC_BACKWARD }, + {IT_CALL | IT_STRING2, NULL, "Move Left", M_ChangeControl, GC_STRAFELEFT }, + {IT_CALL | IT_STRING2, NULL, "Move Right", M_ChangeControl, GC_STRAFERIGHT }, + {IT_CALL | IT_STRING2, NULL, "Jump", M_ChangeControl, GC_JUMP }, + {IT_CALL | IT_STRING2, NULL, "Spin", M_ChangeControl, GC_SPIN }, {IT_HEADER, NULL, "Camera", NULL, 0}, {IT_SPACE, NULL, NULL, NULL, 0}, // padding - {IT_CALL | IT_STRING2, NULL, "Look Up", M_ChangeControl, gc_lookup }, - {IT_CALL | IT_STRING2, NULL, "Look Down", M_ChangeControl, gc_lookdown }, - {IT_CALL | IT_STRING2, NULL, "Look Left", M_ChangeControl, gc_turnleft }, - {IT_CALL | IT_STRING2, NULL, "Look Right", M_ChangeControl, gc_turnright }, - {IT_CALL | IT_STRING2, NULL, "Center View", M_ChangeControl, gc_centerview }, - {IT_CALL | IT_STRING2, NULL, "Toggle Mouselook", M_ChangeControl, gc_mouseaiming }, - {IT_CALL | IT_STRING2, NULL, "Toggle Third-Person", M_ChangeControl, gc_camtoggle}, - {IT_CALL | IT_STRING2, NULL, "Reset Camera", M_ChangeControl, gc_camreset }, + {IT_CALL | IT_STRING2, NULL, "Look Up", M_ChangeControl, GC_LOOKUP }, + {IT_CALL | IT_STRING2, NULL, "Look Down", M_ChangeControl, GC_LOOKDOWN }, + {IT_CALL | IT_STRING2, NULL, "Look Left", M_ChangeControl, GC_TURNLEFT }, + {IT_CALL | IT_STRING2, NULL, "Look Right", M_ChangeControl, GC_TURNRIGHT }, + {IT_CALL | IT_STRING2, NULL, "Center View", M_ChangeControl, GC_CENTERVIEW }, + {IT_CALL | IT_STRING2, NULL, "Toggle Mouselook", M_ChangeControl, GC_MOUSEAIMING }, + {IT_CALL | IT_STRING2, NULL, "Toggle Third-Person", M_ChangeControl, GC_CAMTOGGLE}, + {IT_CALL | IT_STRING2, NULL, "Reset Camera", M_ChangeControl, GC_CAMRESET }, {IT_HEADER, NULL, "Meta", NULL, 0}, {IT_SPACE, NULL, NULL, NULL, 0}, // padding {IT_CALL | IT_STRING2, NULL, "Game Status", - M_ChangeControl, gc_scores }, - {IT_CALL | IT_STRING2, NULL, "Pause / Run Retry", M_ChangeControl, gc_pause }, - {IT_CALL | IT_STRING2, NULL, "Screenshot", M_ChangeControl, gc_screenshot }, - {IT_CALL | IT_STRING2, NULL, "Toggle GIF Recording", M_ChangeControl, gc_recordgif }, - {IT_CALL | IT_STRING2, NULL, "Open/Close Menu (ESC)", M_ChangeControl, gc_systemmenu }, - {IT_CALL | IT_STRING2, NULL, "Change Viewpoint", M_ChangeControl, gc_viewpoint }, - {IT_CALL | IT_STRING2, NULL, "Console", M_ChangeControl, gc_console }, + M_ChangeControl, GC_SCORES }, + {IT_CALL | IT_STRING2, NULL, "Pause / Run Retry", M_ChangeControl, GC_PAUSE }, + {IT_CALL | IT_STRING2, NULL, "Screenshot", M_ChangeControl, GC_SCREENSHOT }, + {IT_CALL | IT_STRING2, NULL, "Toggle GIF Recording", M_ChangeControl, GC_RECORDGIF }, + {IT_CALL | IT_STRING2, NULL, "Open/Close Menu (ESC)", M_ChangeControl, GC_SYSTEMMENU }, + {IT_CALL | IT_STRING2, NULL, "Change Viewpoint", M_ChangeControl, GC_VIEWPOINT }, + {IT_CALL | IT_STRING2, NULL, "Console", M_ChangeControl, GC_CONSOLE }, {IT_HEADER, NULL, "Multiplayer", NULL, 0}, {IT_SPACE, NULL, NULL, NULL, 0}, // padding - {IT_CALL | IT_STRING2, NULL, "Talk", M_ChangeControl, gc_talkkey }, - {IT_CALL | IT_STRING2, NULL, "Talk (Team only)", M_ChangeControl, gc_teamkey }, + {IT_CALL | IT_STRING2, NULL, "Talk", M_ChangeControl, GC_TALKKEY }, + {IT_CALL | IT_STRING2, NULL, "Talk (Team only)", M_ChangeControl, GC_TEAMKEY }, {IT_HEADER, NULL, "Ringslinger (Match, CTF, Tag, H&S)", NULL, 0}, {IT_SPACE, NULL, NULL, NULL, 0}, // padding - {IT_CALL | IT_STRING2, NULL, "Fire", M_ChangeControl, gc_fire }, - {IT_CALL | IT_STRING2, NULL, "Fire Normal", M_ChangeControl, gc_firenormal }, - {IT_CALL | IT_STRING2, NULL, "Toss Flag", M_ChangeControl, gc_tossflag }, - {IT_CALL | IT_STRING2, NULL, "Next Weapon", M_ChangeControl, gc_weaponnext }, - {IT_CALL | IT_STRING2, NULL, "Prev Weapon", M_ChangeControl, gc_weaponprev }, - {IT_CALL | IT_STRING2, NULL, "Normal / Infinity", M_ChangeControl, gc_wepslot1 }, - {IT_CALL | IT_STRING2, NULL, "Automatic", M_ChangeControl, gc_wepslot2 }, - {IT_CALL | IT_STRING2, NULL, "Bounce", M_ChangeControl, gc_wepslot3 }, - {IT_CALL | IT_STRING2, NULL, "Scatter", M_ChangeControl, gc_wepslot4 }, - {IT_CALL | IT_STRING2, NULL, "Grenade", M_ChangeControl, gc_wepslot5 }, - {IT_CALL | IT_STRING2, NULL, "Explosion", M_ChangeControl, gc_wepslot6 }, - {IT_CALL | IT_STRING2, NULL, "Rail", M_ChangeControl, gc_wepslot7 }, + {IT_CALL | IT_STRING2, NULL, "Fire", M_ChangeControl, GC_FIRE }, + {IT_CALL | IT_STRING2, NULL, "Fire Normal", M_ChangeControl, GC_FIRENORMAL }, + {IT_CALL | IT_STRING2, NULL, "Toss Flag", M_ChangeControl, GC_TOSSFLAG }, + {IT_CALL | IT_STRING2, NULL, "Next Weapon", M_ChangeControl, GC_WEAPONNEXT }, + {IT_CALL | IT_STRING2, NULL, "Prev Weapon", M_ChangeControl, GC_WEAPONPREV }, + {IT_CALL | IT_STRING2, NULL, "Normal / Infinity", M_ChangeControl, GC_WEPSLOT1 }, + {IT_CALL | IT_STRING2, NULL, "Automatic", M_ChangeControl, GC_WEPSLOT2 }, + {IT_CALL | IT_STRING2, NULL, "Bounce", M_ChangeControl, GC_WEPSLOT3 }, + {IT_CALL | IT_STRING2, NULL, "Scatter", M_ChangeControl, GC_WEPSLOT4 }, + {IT_CALL | IT_STRING2, NULL, "Grenade", M_ChangeControl, GC_WEPSLOT5 }, + {IT_CALL | IT_STRING2, NULL, "Explosion", M_ChangeControl, GC_WEPSLOT6 }, + {IT_CALL | IT_STRING2, NULL, "Rail", M_ChangeControl, GC_WEPSLOT7 }, {IT_HEADER, NULL, "Add-ons", NULL, 0}, {IT_SPACE, NULL, NULL, NULL, 0}, // padding - {IT_CALL | IT_STRING2, NULL, "Custom Action 1", M_ChangeControl, gc_custom1 }, - {IT_CALL | IT_STRING2, NULL, "Custom Action 2", M_ChangeControl, gc_custom2 }, - {IT_CALL | IT_STRING2, NULL, "Custom Action 3", M_ChangeControl, gc_custom3 }, + {IT_CALL | IT_STRING2, NULL, "Custom Action 1", M_ChangeControl, GC_CUSTOM1 }, + {IT_CALL | IT_STRING2, NULL, "Custom Action 2", M_ChangeControl, GC_CUSTOM2 }, + {IT_CALL | IT_STRING2, NULL, "Custom Action 3", M_ChangeControl, GC_CUSTOM3 }, }; static menuitem_t OP_Joystick1Menu[] = @@ -3343,7 +3343,7 @@ boolean M_Responder(event_t *ev) if (ch == -1) return false; - else if (ch == gamecontrol[gc_systemmenu][0] || ch == gamecontrol[gc_systemmenu][1]) // allow remappable ESC key + else if (ch == gamecontrol[GC_SYSTEMMENU][0] || ch == gamecontrol[GC_SYSTEMMENU][1]) // allow remappable ESC key ch = KEY_ESCAPE; // F-Keys @@ -12929,7 +12929,7 @@ static void M_ChangecontrolResponse(event_t *ev) static char tmp[158]; menu_t *prev = currentMenu->prevMenu; - if (controltochange == gc_pause) + if (controltochange == GC_PAUSE) sprintf(tmp, M_GetText("The \x82Pause Key \x80is enabled, but \nit cannot be used to retry runs \nduring Record Attack. \n\nHit another key for\n%s\nESC for Cancel"), controltochangetext); else diff --git a/src/m_misc.c b/src/m_misc.c index f9a23ad44..dcdddf9d5 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -1636,9 +1636,9 @@ boolean M_ScreenshotResponder(event_t *ev) if (ch >= KEY_MOUSE1 && menuactive) // If it's not a keyboard key, then don't allow it in the menus! return false; - if (ch == KEY_F8 || ch == gamecontrol[gc_screenshot][0] || ch == gamecontrol[gc_screenshot][1]) // remappable F8 + if (ch == KEY_F8 || ch == gamecontrol[GC_SCREENSHOT][0] || ch == gamecontrol[GC_SCREENSHOT][1]) // remappable F8 M_ScreenShot(); - else if (ch == KEY_F9 || ch == gamecontrol[gc_recordgif][0] || ch == gamecontrol[gc_recordgif][1]) // remappable F9 + else if (ch == KEY_F9 || ch == gamecontrol[GC_RECORDGIF][0] || ch == gamecontrol[GC_RECORDGIF][1]) // remappable F9 ((moviemode) ? M_StopMovie : M_StartMovie)(); else return false; diff --git a/src/p_user.c b/src/p_user.c index c3184b52f..d12affd1d 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -5357,9 +5357,9 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) // disabled because it seemed to disorient people and Z-targeting exists now /*if (!demoplayback) { - if (player == &players[consoleplayer] && cv_cam_turnfacingability[0].value > 0 && !(PLAYER1INPUTDOWN(gc_turnleft) || PLAYER1INPUTDOWN(gc_turnright))) + if (player == &players[consoleplayer] && cv_cam_turnfacingability[0].value > 0 && !(PLAYER1INPUTDOWN(GC_TURNLEFT) || PLAYER1INPUTDOWN(GC_TURNRIGHT))) P_SetPlayerAngle(player, player->mo->angle);; - else if (player == &players[secondarydisplayplayer] && cv_cam_turnfacingability[1].value > 0 && !(PLAYER2INPUTDOWN(gc_turnleft) || PLAYER2INPUTDOWN(gc_turnright))) + else if (player == &players[secondarydisplayplayer] && cv_cam_turnfacingability[1].value > 0 && !(PLAYER2INPUTDOWN(GC_TURNLEFT) || PLAYER2INPUTDOWN(GC_TURNRIGHT))) P_SetPlayerAngle(player, player->mo->angle); }*/ } From 9b7263855e573747cc396c6af6f789fdb95ac5aa Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Wed, 18 Aug 2021 20:58:13 +0200 Subject: [PATCH 588/644] Prevent input.setMouseGrab from interfering with window focus --- src/d_clisrv.c | 4 ++++ src/lua_inputlib.c | 8 +++++--- src/lua_libs.h | 2 ++ src/sdl/i_video.c | 4 ++++ 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 326105a3b..4cf7259bf 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -43,6 +43,7 @@ #include "lzf.h" #include "lua_script.h" #include "lua_hook.h" +#include "lua_libs.h" #include "md5.h" #include "m_perfstats.h" @@ -3331,6 +3332,9 @@ static inline void SV_GenContext(void) // void D_QuitNetGame(void) { + mousegrabbedbylua = true; + I_UpdateMouseGrab(); + if (!netgame || !netbuffer) return; diff --git a/src/lua_inputlib.c b/src/lua_inputlib.c index 6e3085e94..661d93641 100644 --- a/src/lua_inputlib.c +++ b/src/lua_inputlib.c @@ -19,6 +19,8 @@ #include "lua_script.h" #include "lua_libs.h" +boolean mousegrabbedbylua = true; + /////////////// // FUNCTIONS // /////////////// @@ -106,14 +108,14 @@ static int lib_shiftKeyNum(lua_State *L) static int lib_getMouseGrab(lua_State *L) { - lua_pushboolean(L, I_GetMouseGrab()); + lua_pushboolean(L, mousegrabbedbylua); return 1; } static int lib_setMouseGrab(lua_State *L) { - boolean grab = luaL_checkboolean(L, 1); - I_SetMouseGrab(grab); + mousegrabbedbylua = luaL_checkboolean(L, 1); + I_UpdateMouseGrab(); return 0; } diff --git a/src/lua_libs.h b/src/lua_libs.h index de174283c..8903834e8 100644 --- a/src/lua_libs.h +++ b/src/lua_libs.h @@ -12,6 +12,8 @@ extern lua_State *gL; +extern boolean mousegrabbedbylua; + #define MUTABLE_TAGS #define LREG_VALID "VALID_USERDATA" diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index a18ea32ba..97e4a7214 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -73,6 +73,8 @@ #include "../console.h" #include "../command.h" #include "../r_main.h" +#include "../lua_script.h" +#include "../lua_libs.h" #include "../lua_hook.h" #include "sdlmain.h" #ifdef HWRENDER @@ -372,6 +374,8 @@ static boolean IgnoreMouse(void) if (gamestate != GS_LEVEL && gamestate != GS_INTERMISSION && gamestate != GS_CONTINUING && gamestate != GS_CUTSCENE) return true; + if (!mousegrabbedbylua) + return true; return false; } From 4a6acc2c8dcd7cd94305da19f15ff790fae277de Mon Sep 17 00:00:00 2001 From: SteelT Date: Sun, 22 Aug 2021 16:13:40 -0400 Subject: [PATCH 589/644] Fix metal recordings not being saved in srb2home --- src/g_demo.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/g_demo.c b/src/g_demo.c index 701f930e5..e75c6a738 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -2422,12 +2422,13 @@ ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(boolean kill) { WRITEUINT8(demo_p, (kill) ? METALDEATH : DEMOMARKER); // add the demo end (or metal death) marker WriteDemoChecksum(); - saved = FIL_WriteFile(va("%sMS.LMP", G_BuildMapName(gamemap)), demobuffer, demo_p - demobuffer); // finally output the file. + sprintf(demoname, "%sMS.LMP", G_BuildMapName(gamemap)); + saved = FIL_WriteFile(va(pandf, srb2home, demoname), demobuffer, demo_p - demobuffer); // finally output the file. } free(demobuffer); metalrecording = false; if (saved) - I_Error("Saved to %sMS.LMP", G_BuildMapName(gamemap)); + I_Error("Saved to %s", demoname); I_Error("Failed to save demo!"); } From 450955cba264ea3dde9eb3f745ff9816307635ce Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Thu, 26 Aug 2021 13:22:32 -0300 Subject: [PATCH 590/644] Fix floor sprite projection --- src/r_plane.c | 124 ++++++++----------------------------------------- src/r_plane.h | 1 - src/r_splats.c | 91 ++++++++++++++---------------------- src/r_splats.h | 3 +- src/r_things.c | 5 +- src/r_things.h | 10 +++- 6 files changed, 68 insertions(+), 166 deletions(-) diff --git a/src/r_plane.c b/src/r_plane.c index 818770906..d844048ae 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -89,8 +89,6 @@ static fixed_t planeheight; fixed_t yslopetab[MAXVIDHEIGHT*16]; fixed_t *yslope; -fixed_t basexscale, baseyscale; - fixed_t cachedheight[MAXVIDHEIGHT]; fixed_t cacheddistance[MAXVIDHEIGHT]; fixed_t cachedxstep[MAXVIDHEIGHT]; @@ -114,7 +112,7 @@ void R_InitPlanes(void) // Sets planeripple.xfrac and planeripple.yfrac, added to ds_xfrac and ds_yfrac, if the span is not tilted. // -struct +static struct { INT32 offset; fixed_t xfrac, yfrac; @@ -143,15 +141,6 @@ static void R_UpdatePlaneRipple(void) planeripple.offset = (leveltime * 140); } -// -// R_MapPlane -// -// Uses global vars: -// planeheight -// basexscale -// baseyscale -// centerx - static void R_MapPlane(INT32 y, INT32 x1, INT32 x2) { angle_t angle, planecos, planesin; @@ -176,16 +165,13 @@ static void R_MapPlane(INT32 y, INT32 x1, INT32 x2) cacheddistance[y] = distance = FixedMul(planeheight, yslope[y]); span = abs(centery - y); - if (span) // don't divide by zero + if (span) // Don't divide by zero { ds_xstep = FixedMul(planesin, planeheight) / span; ds_ystep = FixedMul(planecos, planeheight) / span; } else - { - ds_xstep = FixedMul(distance, basexscale); - ds_ystep = FixedMul(distance, baseyscale); - } + ds_xstep = ds_ystep = FRACUNIT; cachedxstep[y] = ds_xstep; cachedystep[y] = ds_ystep; @@ -197,6 +183,11 @@ static void R_MapPlane(INT32 y, INT32 x1, INT32 x2) ds_ystep = cachedystep[y]; } + // [RH] Instead of using the xtoviewangle array, I calculated the fractional values + // at the middle of the screen, then used the calculated ds_xstep and ds_ystep + // to step from those to the proper texture coordinate to start drawing at. + // That way, the texture coordinate is always calculated by its position + // on the screen and not by its position relative to the edge of the visplane. ds_xfrac = xoffs + FixedMul(planecos, distance) + (x1 - centerx) * ds_xstep; ds_yfrac = yoffs - FixedMul(planesin, distance) + (x1 - centerx) * ds_ystep; @@ -295,7 +286,6 @@ void R_ClearFFloorClips (void) void R_ClearPlanes(void) { INT32 i, p; - angle_t angle; // opening / clipping determination for (i = 0; i < viewwidth; i++) @@ -321,13 +311,6 @@ void R_ClearPlanes(void) // texture calculation memset(cachedheight, 0, sizeof (cachedheight)); - - // left to right mapping - angle = (viewangle-ANGLE_90)>>ANGLETOFINESHIFT; - - // scale will be unit scale at SCREENWIDTH/2 distance - basexscale = FixedDiv (FINECOSINE(angle),centerxfrac); - baseyscale = -FixedDiv (FINESINE(angle),centerxfrac); } static visplane_t *new_visplane(unsigned hash) @@ -532,53 +515,22 @@ visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop) // // R_ExpandPlane // -// This function basically expands the visplane or I_Errors. +// This function basically expands the visplane. // The reason for this is that when creating 3D floor planes, there is no // need to create new ones with R_CheckPlane, because 3D floor planes // are created by subsector and there is no way a subsector can graphically // overlap. void R_ExpandPlane(visplane_t *pl, INT32 start, INT32 stop) { -// INT32 unionl, unionh; -// INT32 x; - // Don't expand polyobject planes here - we do that on our own. if (pl->polyobj) return; if (pl->minx > start) pl->minx = start; if (pl->maxx < stop) pl->maxx = stop; -/* - if (start < pl->minx) - { - unionl = start; - } - else - { - unionl = pl->minx; - } - - if (stop > pl->maxx) - { - unionh = stop; - } - else - { - unionh = pl->maxx; - } - for (x = start; x <= stop; x++) - if (pl->top[x] != 0xffff || pl->bottom[x] != 0x0000) - break; - - if (x <= stop) - I_Error("R_ExpandPlane: planes in same subsector overlap?!\nminx: %d, maxx: %d, start: %d, stop: %d\n", pl->minx, pl->maxx, start, stop); - - pl->minx = unionl, pl->maxx = unionh; -*/ - } -static void R_MakeSpans(INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2) +static void R_MakeSpans(void (*mapfunc)(INT32, INT32, INT32), INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2) { // Alam: from r_splats's R_RasterizeFloorSplat if (t1 >= vid.height) t1 = vid.height-1; @@ -589,38 +541,12 @@ static void R_MakeSpans(INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2) while (t1 < t2 && t1 <= b1) { - R_MapPlane(t1, spanstart[t1], x - 1); + mapfunc(t1, spanstart[t1], x - 1); t1++; } while (b1 > b2 && b1 >= t1) { - R_MapPlane(b1, spanstart[b1], x - 1); - b1--; - } - - while (t2 < t1 && t2 <= b2) - spanstart[t2++] = x; - while (b2 > b1 && b2 >= t2) - spanstart[b2--] = x; -} - -static void R_MakeTiltedSpans(INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2) -{ - // Alam: from r_splats's R_RasterizeFloorSplat - if (t1 >= vid.height) t1 = vid.height-1; - if (b1 >= vid.height) b1 = vid.height-1; - if (t2 >= vid.height) t2 = vid.height-1; - if (b2 >= vid.height) b2 = vid.height-1; - if (x-1 >= vid.width) x = vid.width; - - while (t1 < t2 && t1 <= b1) - { - R_MapTiltedPlane(t1, spanstart[t1], x - 1); - t1++; - } - while (b1 > b2 && b1 >= t1) - { - R_MapTiltedPlane(b1, spanstart[b1], x - 1); + mapfunc(b1, spanstart[b1], x - 1); b1--; } @@ -867,11 +793,10 @@ void R_DrawSinglePlane(visplane_t *pl) { levelflat_t *levelflat; INT32 light = 0; - INT32 x; - INT32 stop, angle; + INT32 x, stop; ffloor_t *rover; - INT32 type; - INT32 spanfunctype = BASEDRAWFUNC; + INT32 type, spanfunctype = BASEDRAWFUNC; + void (*mapfunc)(INT32, INT32, INT32) = R_MapPlane; if (!(pl->minx <= pl->maxx)) return; @@ -1023,9 +948,6 @@ void R_DrawSinglePlane(visplane_t *pl) && viewangle != pl->viewangle+pl->plangle) { memset(cachedheight, 0, sizeof (cachedheight)); - angle = (pl->viewangle+pl->plangle-ANGLE_90)>>ANGLETOFINESHIFT; - basexscale = FixedDiv(FINECOSINE(angle),centerxfrac); - baseyscale = -FixedDiv(FINESINE(angle),centerxfrac); viewangle = pl->viewangle+pl->plangle; } @@ -1040,6 +962,8 @@ void R_DrawSinglePlane(visplane_t *pl) if (pl->slope) { + mapfunc = R_MapTiltedPlane; + if (!pl->plangle) { if (ds_powersoftwo) @@ -1107,16 +1031,8 @@ void R_DrawSinglePlane(visplane_t *pl) stop = pl->maxx + 1; - if (pl->slope) - { - for (x = pl->minx; x <= stop; x++) - R_MakeTiltedSpans(x, pl->top[x-1], pl->bottom[x-1], pl->top[x], pl->bottom[x]); - } - else - { - for (x = pl->minx; x <= stop; x++) - R_MakeSpans(x, pl->top[x-1], pl->bottom[x-1], pl->top[x], pl->bottom[x]); - } + for (x = pl->minx; x <= stop; x++) + R_MakeSpans(mapfunc, x, pl->top[x-1], pl->bottom[x-1], pl->top[x], pl->bottom[x]); /* QUINCUNX anti-aliasing technique (sort of) @@ -1183,7 +1099,7 @@ using the palette colors. stop = pl->maxx + 1; for (x = pl->minx; x <= stop; x++) - R_MakeSpans(x, pl->top[x-1], pl->bottom[x-1], + R_MakeSpans(mapfunc, x, pl->top[x-1], pl->bottom[x-1], pl->top[x], pl->bottom[x]); } } diff --git a/src/r_plane.h b/src/r_plane.h index bdad77930..862b95069 100644 --- a/src/r_plane.h +++ b/src/r_plane.h @@ -69,7 +69,6 @@ extern fixed_t cachedheight[MAXVIDHEIGHT]; extern fixed_t cacheddistance[MAXVIDHEIGHT]; extern fixed_t cachedxstep[MAXVIDHEIGHT]; extern fixed_t cachedystep[MAXVIDHEIGHT]; -extern fixed_t basexscale, baseyscale; extern fixed_t *yslope; extern lighttable_t **planezlight; diff --git a/src/r_splats.c b/src/r_splats.c index 4783fb640..c554e9b1f 100644 --- a/src/r_splats.c +++ b/src/r_splats.c @@ -155,7 +155,6 @@ void R_DrawFloorSplat(vissprite_t *spr) fixed_t xscale, yscale; fixed_t xoffset, yoffset; fixed_t leftoffset, topoffset; - pslope_t *slope = NULL; INT32 i; boolean hflip = (spr->xiscale < 0); @@ -188,7 +187,7 @@ void R_DrawFloorSplat(vissprite_t *spr) if (spr->rotateflags & SRF_3D || renderflags & RF_NOSPLATBILLBOARD) splatangle = mobj->angle; else - splatangle = spr->viewangle; + splatangle = spr->viewpoint.angle; if (!(spr->cut & SC_ISROTATED)) splatangle += mobj->rollangle; @@ -218,7 +217,7 @@ void R_DrawFloorSplat(vissprite_t *spr) splat.x = x; splat.y = y; splat.z = mobj->z; - splat.tilted = false; + splat.slope = NULL; // Set positions @@ -238,9 +237,9 @@ void R_DrawFloorSplat(vissprite_t *spr) splat.verts[3].x = w - xoffset; splat.verts[3].y = -h + yoffset; - angle = -splat.angle; - ca = FINECOSINE(angle>>ANGLETOFINESHIFT); - sa = FINESINE(angle>>ANGLETOFINESHIFT); + angle = -splat.angle>>ANGLETOFINESHIFT; + ca = FINECOSINE(angle); + sa = FINESINE(angle); // Rotate for (i = 0; i < 4; i++) @@ -255,36 +254,10 @@ void R_DrawFloorSplat(vissprite_t *spr) // The slope that was defined for the sprite. if (renderflags & RF_SLOPESPLAT) - slope = mobj->floorspriteslope; + splat.slope = mobj->floorspriteslope; if (standingslope && (renderflags & RF_OBJECTSLOPESPLAT)) - slope = standingslope; - - // Set splat as tilted - splat.tilted = (slope != NULL); - } - - if (splat.tilted) - { - pslope_t *s = &splat.slope; - - s->o.x = slope->o.x; - s->o.y = slope->o.y; - s->o.z = slope->o.z; - - s->d.x = slope->d.x; - s->d.y = slope->d.y; - - s->normal.x = slope->normal.x; - s->normal.y = slope->normal.y; - s->normal.z = slope->normal.z; - - s->zdelta = slope->zdelta; - s->zangle = slope->zangle; - s->xydirection = slope->xydirection; - - s->next = NULL; - s->flags = 0; + splat.slope = standingslope; } // Translate @@ -293,9 +266,9 @@ void R_DrawFloorSplat(vissprite_t *spr) tr_x = rotated[i].x + x; tr_y = rotated[i].y + y; - if (slope) + if (splat.slope) { - rot_z = P_GetSlopeZAt(slope, tr_x, tr_y); + rot_z = P_GetSlopeZAt(splat.slope, tr_x, tr_y); splat.verts[i].z = rot_z; } else @@ -305,18 +278,23 @@ void R_DrawFloorSplat(vissprite_t *spr) splat.verts[i].y = tr_y; } + angle = spr->viewpoint.angle >> ANGLETOFINESHIFT; + ca = FINECOSINE(angle); + sa = FINESINE(angle); + + // Project for (i = 0; i < 4; i++) { v3d = &splat.verts[i]; // transform the origin point - tr_x = v3d->x - viewx; - tr_y = v3d->y - viewy; + tr_x = v3d->x - spr->viewpoint.x; + tr_y = v3d->y - spr->viewpoint.y; // rotation around vertical y axis - rot_x = FixedMul(tr_x, viewsin) - FixedMul(tr_y, viewcos); - rot_y = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin); - rot_z = v3d->z - viewz; + rot_x = FixedMul(tr_x, sa) - FixedMul(tr_y, ca); + rot_y = FixedMul(tr_x, ca) + FixedMul(tr_y, sa); + rot_z = v3d->z - spr->viewpoint.z; if (rot_y < FRACUNIT) return; @@ -416,31 +394,32 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr if (R_CheckPowersOfTwo()) R_CheckFlatLength(ds_flatwidth * ds_flatheight); - if (pSplat->tilted) + if (pSplat->slope) { R_SetTiltedSpan(0); - R_SetScaledSlopePlane(&pSplat->slope, viewx, viewy, viewz, pSplat->xscale, pSplat->yscale, -pSplat->verts[0].x, pSplat->verts[0].y, vis->viewangle, pSplat->angle); + R_SetScaledSlopePlane(pSplat->slope, vis->viewpoint.x, vis->viewpoint.y, vis->viewpoint.z, pSplat->xscale, pSplat->yscale, -pSplat->verts[0].x, pSplat->verts[0].y, vis->viewpoint.angle, pSplat->angle); R_CalculateSlopeVectors(); spanfunctype = SPANDRAWFUNC_TILTEDSPRITE; } else { - planeheight = abs(pSplat->z - viewz); + planeheight = abs(pSplat->z - vis->viewpoint.z); if (pSplat->angle) { - // Add the view offset, rotated by the plane angle. - fixed_t a = -pSplat->verts[0].x + viewx; - fixed_t b = -pSplat->verts[0].y + viewy; - angle_t angle = (pSplat->angle >> ANGLETOFINESHIFT); - offsetx = FixedMul(a, FINECOSINE(angle)) - FixedMul(b,FINESINE(angle)); - offsety = -FixedMul(a, FINESINE(angle)) - FixedMul(b,FINECOSINE(angle)); memset(cachedheight, 0, sizeof(cachedheight)); + + // Add the view offset, rotated by the plane angle. + fixed_t a = -pSplat->verts[0].x + vis->viewpoint.x; + fixed_t b = -pSplat->verts[0].y + vis->viewpoint.y; + angle_t angle = (pSplat->angle >> ANGLETOFINESHIFT); + offsetx = FixedMul(a, FINECOSINE(angle)) - FixedMul(b, FINESINE(angle)); + offsety = -FixedMul(a, FINESINE(angle)) - FixedMul(b, FINECOSINE(angle)); } else { - offsetx = viewx - pSplat->verts[0].x; - offsety = pSplat->verts[0].y - viewy; + offsetx = vis->viewpoint.x - pSplat->verts[0].x; + offsety = pSplat->verts[0].y - vis->viewpoint.y; } } @@ -461,7 +440,7 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr { ds_transmap = vis->transmap; - if (pSplat->tilted) + if (pSplat->slope) spanfunctype = SPANDRAWFUNC_TILTEDTRANSSPRITE; else spanfunctype = SPANDRAWFUNC_TRANSSPRITE; @@ -528,12 +507,12 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr if (x2 < x1) continue; - if (!pSplat->tilted) + if (!pSplat->slope) { fixed_t xstep, ystep; fixed_t distance, span; - angle_t angle = (vis->viewangle + pSplat->angle)>>ANGLETOFINESHIFT; + angle_t angle = (vis->viewpoint.angle + pSplat->angle)>>ANGLETOFINESHIFT; angle_t planecos = FINECOSINE(angle); angle_t planesin = FINESINE(angle); @@ -577,7 +556,7 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr rastertab[y].maxx = INT32_MIN; } - if (pSplat->angle && !pSplat->tilted) + if (pSplat->angle && !pSplat->slope) memset(cachedheight, 0, sizeof(cachedheight)); } diff --git a/src/r_splats.h b/src/r_splats.h index cab3d63b6..7e31406d1 100644 --- a/src/r_splats.h +++ b/src/r_splats.h @@ -34,8 +34,7 @@ typedef struct floorsplat_s INT32 width, height; fixed_t scale, xscale, yscale; angle_t angle; - boolean tilted; // Uses the tilted drawer - pslope_t slope; + pslope_t *slope; vector3_t verts[4]; // (x,y,z) as viewed from above on map fixed_t x, y, z; // position diff --git a/src/r_things.c b/src/r_things.c index 0283712b8..f1996d743 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1956,9 +1956,12 @@ static void R_ProjectSprite(mobj_t *thing) vis->paperoffset = paperoffset; vis->paperdistance = paperdistance; vis->centerangle = centerangle; - vis->viewangle = viewangle; vis->shear.tan = sheartan; vis->shear.offset = 0; + vis->viewpoint.x = viewx; + vis->viewpoint.y = viewy; + vis->viewpoint.z = viewz; + vis->viewpoint.angle = viewangle; vis->mobj = thing; // Easy access! Tails 06-07-2002 diff --git a/src/r_things.h b/src/r_things.h index 9315b36e9..79dc80d94 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -164,7 +164,12 @@ typedef struct vissprite_s fixed_t xiscale; // negative if flipped angle_t centerangle; // for paper sprites - angle_t viewangle; // for floor sprites, the viewpoint's current angle + + // for floor sprites + struct { + fixed_t x, y, z; // the viewpoint's current position + angle_t angle; // the viewpoint's current angle + } viewpoint; struct { fixed_t tan; // The amount to shear the sprite vertically per row @@ -185,9 +190,10 @@ typedef struct vissprite_s extracolormap_t *extra_colormap; // global colormaps - // Precalculated top and bottom screen coords for the sprite. fixed_t thingheight; // The actual height of the thing (for 3D floors) sector_t *sector; // The sector containing the thing. + + // Precalculated top and bottom screen coords for the sprite. INT16 sz, szt; spritecut_e cut; From 3ff8d9d3b1d3fec83cb4ba20ff40fefb97ec2dde Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Thu, 26 Aug 2021 13:37:52 -0300 Subject: [PATCH 591/644] Fix issue with png_get_tRNS This fixes an oversight where the return value of png_get_tRNS was being ignored. --- src/r_picformats.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/r_picformats.c b/src/r_picformats.c index 59b1d16c5..5c81d1e02 100644 --- a/src/r_picformats.c +++ b/src/r_picformats.c @@ -901,9 +901,8 @@ static png_bytep *PNG_Read( png_colorp palette; int palette_size; - png_bytep trans; - int trans_num; - png_color_16p trans_values; + png_bytep trans = NULL; + int num_trans = 0; #ifdef PNG_SETJMP_SUPPORTED #ifdef USE_FAR_KEYWORD @@ -998,12 +997,12 @@ static png_bytep *PNG_Read( // color is present on the image, the palette flag is disabled. if (usepal) { - png_get_tRNS(png_ptr, png_info_ptr, &trans, &trans_num, &trans_values); + png_uint_32 result = png_get_tRNS(png_ptr, png_info_ptr, &trans, &num_trans, NULL); - if (trans && trans_num > 0) + if ((result & PNG_INFO_tRNS) && num_trans > 0 && trans != NULL) { INT32 i; - for (i = 0; i < trans_num; i++) + for (i = 0; i < num_trans; i++) { // libpng will transform this image into RGBA even if // the transparent index does not exist in the image, From b73c24a0c5a0a01078c27242ec72d98a31f8b524 Mon Sep 17 00:00:00 2001 From: Shane Ellis Date: Sat, 28 Aug 2021 17:14:36 +0000 Subject: [PATCH 592/644] Add VERSIONSTRING_RC to DEVELOP builds for compiler compatibility --- src/doomdef.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/doomdef.h b/src/doomdef.h index 11ca80538..37edca896 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -127,6 +127,7 @@ extern char logfilename[1024]; //#define DEVELOP // Disable this for release builds to remove excessive cheat commands and enable MD5 checking and stuff, all in one go. :3 #ifdef DEVELOP #define VERSIONSTRING "Development EXE" +#define VERSIONSTRING_RC "Development EXE" "\0" // most interface strings are ignored in development mode. // we use comprevision and compbranch instead. // VERSIONSTRING_RC is for the resource-definition script used by windows builds From 1a8ec7975c20e1d652cbbdb7a9e366192e41c05f Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Sat, 28 Aug 2021 15:39:34 -0500 Subject: [PATCH 593/644] Makefile: Improve gcc detection Wasn't working for me until I fixed it. Turns out gcc really doesn't like giving its name out. Most of the time it reads argv[0]. --- src/Makefile.d/detect.mk | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/Makefile.d/detect.mk b/src/Makefile.d/detect.mk index 9c8a0a227..f458b044c 100644 --- a/src/Makefile.d/detect.mk +++ b/src/Makefile.d/detect.mk @@ -71,13 +71,17 @@ latest_gcc_version:=10.2 # manually set. And don't bother if this is a clean only # run. ifeq (,$(call Wildvar,GCC% destructive)) -version:=$(shell $(CC) --version) + +# can't use $(CC) --version here since that uses argv[0] to display the name +# also gcc outputs the information to stderr, so I had to do 2>&1 +# this program really doesn't like identifying itself +version:=$(shell $(CC) -v 2>&1) # check if this is in fact GCC -ifneq (,$(or $(findstring gcc,$(version)),\ - $(findstring GCC,$(version)))) +ifneq (,$(findstring gcc version,$(version))) -version:=$(shell $(CC) -dumpversion) +# in stark contrast to the name, gcc will give me a nicely formatted version number for free +version:=$(shell $(CC) -dumpfullversion) # Turn version into words of major, minor v:=$(subst ., ,$(version)) From f4f7af6f6d87451c3271606c965762755617cdc1 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 30 Aug 2021 18:40:36 -0700 Subject: [PATCH 594/644] Add my full name --- src/f_finale.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/f_finale.c b/src/f_finale.c index 4d9a8f825..acad7b248 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1089,7 +1089,6 @@ static const char *credits[] = { "\"Hannu_Hanhi\"", // For many OpenGL performance improvements! "Kepa \"Nev3r\" Iceta", "Thomas \"Shadow Hog\" Igoe", - "\"james\"", "Iestyn \"Monster Iestyn\" Jealous", "\"Jimita\"", "\"Kaito Sinclaire\"", @@ -1102,6 +1101,7 @@ static const char *credits[] = { "Louis-Antoine \"LJ Sonic\" de Moulins", // de Rochefort doesn't quite fit on the screen sorry lol "John \"JTE\" Muniz", "Colin \"Sonict\" Pfaff", + "James \"james\" Robert Roman", "Sean \"Sryder13\" Ryder", "Ehab \"Wolfy\" Saeed", "Tasos \"tatokis\" Sahanidis", // Corrected C FixedMul, making 64-bit builds netplay compatible From 39bd9c6da8dbcb47660cc41ac53bbbacb4c020ab Mon Sep 17 00:00:00 2001 From: namishere Date: Mon, 30 Aug 2021 23:18:25 -0700 Subject: [PATCH 595/644] Make next compile again --- src/lua_baselib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index f287fb78c..1c3b483fa 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -3405,7 +3405,7 @@ static int lib_gAddPlayer(lua_State *L) { INT16 i, newplayernum, botcount = 1; player_t *newplayer; - INT8 skinnum = 0, bot; + SINT8 skinnum = 0, bot; for (i = 0; i < MAXPLAYERS; i++) { From 8e0831a183dbcd3dad5696c6f6514c95df861417 Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 3 Sep 2021 17:13:12 -0700 Subject: [PATCH 596/644] Fix unused variable warning under NOPNG --- src/r_picformats.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_picformats.h b/src/r_picformats.h index b1bb35edd..c74f8a13a 100644 --- a/src/r_picformats.h +++ b/src/r_picformats.h @@ -116,9 +116,9 @@ void *Picture_PNGConvert( size_t insize, size_t *outsize, pictureflags_t flags); boolean Picture_PNGDimensions(UINT8 *png, INT32 *width, INT32 *height, INT16 *topoffset, INT16 *leftoffset, size_t size); -#endif #define PICTURE_PNG_USELOOKUP +#endif // SpriteInfo extern spriteinfo_t spriteinfo[NUMSPRITES]; From cbc5cc3b2acd0f8f87a4616b8fadf57400dffbcb Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 3 Sep 2021 17:18:00 -0700 Subject: [PATCH 597/644] Fix GCC 11 array-bounds warning in P_SetupStateAnimation Removing inline here silences the warning somehow, it could be a GCC bug? --- src/p_mobj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 690842270..b77dbc42a 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -78,7 +78,7 @@ void P_AddCachedAction(mobj_t *mobj, INT32 statenum) // // P_SetupStateAnimation // -FUNCINLINE static ATTRINLINE void P_SetupStateAnimation(mobj_t *mobj, state_t *st) +static void P_SetupStateAnimation(mobj_t *mobj, state_t *st) { INT32 animlength = (mobj->sprite == SPR_PLAY && mobj->skin) ? (INT32)(((skin_t *)mobj->skin)->sprites[mobj->sprite2].numframes) - 1 From 50fe45efe68f01dc8dd79d4f040a776d5d043857 Mon Sep 17 00:00:00 2001 From: katsy <205-katsy@users.noreply.git.do.srb2.org> Date: Fri, 10 Sep 2021 17:00:43 +0000 Subject: [PATCH 598/644] Refactor weather switching (fixes #541) --- src/p_mobj.c | 14 ++------ src/p_spec.c | 93 ++++++++++------------------------------------------ 2 files changed, 21 insertions(+), 86 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 10220fff6..c32371888 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11051,7 +11051,7 @@ void P_SpawnPrecipitation(void) subsector_t *precipsector = NULL; precipmobj_t *rainmo = NULL; - if (dedicated || !(cv_drawdist_precip.value) || curWeather == PRECIP_NONE) + if (dedicated || !(cv_drawdist_precip.value) || curWeather == PRECIP_NONE || curWeather == PRECIP_STORM_NORAIN) return; // Use the blockmap to narrow down our placing patterns @@ -11097,22 +11097,14 @@ void P_SpawnPrecipitation(void) continue; rainmo = P_SpawnRainMobj(x, y, height, MT_RAIN); + if (curWeather == PRECIP_BLANK) + rainmo->precipflags |= PCF_INVISIBLE; } // Randomly assign a height, now that floorz is set. rainmo->z = M_RandomRange(rainmo->floorz>>FRACBITS, rainmo->ceilingz>>FRACBITS)<flags = mobjinfo[MT_RAIN].flags; st = &states[mobjinfo[MT_RAIN].spawnstate]; @@ -2078,7 +2039,7 @@ void P_SwitchWeather(INT32 weathernum) precipmobj->precipflags |= PCF_RAIN; //think->function.acp1 = (actionf_p1)P_RainThinker; } - else if (swap == PRECIP_SNOW) // Rain To Snow + else if (weathernum == PRECIP_SNOW) // Rain To Snow { INT32 z; @@ -2103,7 +2064,7 @@ void P_SwitchWeather(INT32 weathernum) //think->function.acp1 = (actionf_p1)P_SnowThinker; } - else if (swap == PRECIP_BLANK || swap == PRECIP_STORM_NORAIN) // Remove precip, but keep it around for reuse. + else // Remove precip, but keep it around for reuse. { //think->function.acp1 = (actionf_p1)P_NullPrecipThinker; @@ -2116,49 +2077,34 @@ void P_SwitchWeather(INT32 weathernum) { case PRECIP_SNOW: // snow curWeather = PRECIP_SNOW; - - if (!swap) + + if (purge) P_SpawnPrecipitation(); break; case PRECIP_RAIN: // rain { - boolean dontspawn = false; - - if (curWeather == PRECIP_RAIN || curWeather == PRECIP_STORM || curWeather == PRECIP_STORM_NOSTRIKES) - dontspawn = true; - curWeather = PRECIP_RAIN; - if (!dontspawn && !swap) + if (purge) P_SpawnPrecipitation(); break; } case PRECIP_STORM: // storm { - boolean dontspawn = false; - - if (curWeather == PRECIP_RAIN || curWeather == PRECIP_STORM || curWeather == PRECIP_STORM_NOSTRIKES) - dontspawn = true; - curWeather = PRECIP_STORM; - if (!dontspawn && !swap) + if (purge) P_SpawnPrecipitation(); break; } case PRECIP_STORM_NOSTRIKES: // storm w/o lightning { - boolean dontspawn = false; - - if (curWeather == PRECIP_RAIN || curWeather == PRECIP_STORM || curWeather == PRECIP_STORM_NOSTRIKES) - dontspawn = true; - curWeather = PRECIP_STORM_NOSTRIKES; - if (!dontspawn && !swap) + if (purge) P_SpawnPrecipitation(); break; @@ -2166,14 +2112,11 @@ void P_SwitchWeather(INT32 weathernum) case PRECIP_STORM_NORAIN: // storm w/o rain curWeather = PRECIP_STORM_NORAIN; - if (!swap) - P_SpawnPrecipitation(); - break; - case PRECIP_BLANK: + case PRECIP_BLANK: //preloaded curWeather = PRECIP_BLANK; - if (!swap) + if (purge) P_SpawnPrecipitation(); break; From aaf4653f1e111edfd5efe1f2004f1f48e34883ad Mon Sep 17 00:00:00 2001 From: LZA <73-LZA@users.noreply.git.do.srb2.org> Date: Sun, 12 Sep 2021 21:08:06 +0000 Subject: [PATCH 599/644] Fix minor issues with folder addons --- src/d_main.c | 4 +- src/d_netcmd.c | 56 ++++++++- src/d_netfil.c | 19 +-- src/filesrch.c | 329 ++++++++++++++++++++++++++++--------------------- src/filesrch.h | 10 +- src/m_misc.c | 2 +- src/w_wad.c | 168 ++++++++++++++++++++----- src/w_wad.h | 5 +- 8 files changed, 405 insertions(+), 188 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 7866ccbed..36f41e0a4 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -944,13 +944,13 @@ static void D_AddFile(char **list, const char *file) static void D_AddFolder(char **list, const char *file) { - size_t pnumwadfiles, len = strlen(file); + size_t pnumwadfiles; char *newfile; for (pnumwadfiles = 0; list[pnumwadfiles]; pnumwadfiles++) ; - newfile = malloc(len + 2); // NULL terminator + path separator + newfile = malloc(strlen(file) + 2); // Path delimiter + NULL terminator if (!newfile) I_Error("No more free memory to AddFolder %s",file); diff --git a/src/d_netcmd.c b/src/d_netcmd.c index ea0d9ca80..1e4e2b464 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1518,7 +1518,7 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum) { illegalMask &= ~(1 << i); } - + if ((p->availabilities & illegalMask) != 0) { kick = true; @@ -3416,9 +3416,10 @@ static void Command_Addfolder(void) for (curarg = 1; curarg < argc; curarg++) { const char *fn, *p; + char *fullpath; char buf[256]; char *buf_p = buf; - INT32 i; + INT32 i, stat; size_t ii; boolean folderadded = false; @@ -3461,6 +3462,13 @@ static void Command_Addfolder(void) break; ++p; + // Don't add an empty path. + if (M_IsStringEmpty(fn)) + { + CONS_Alert(CONS_WARNING, M_GetText("Folder name is empty, skipping\n")); + continue; + } + // check total packet size and no of files currently loaded // See W_InitFile in w_wad.c if ((numwadfiles >= MAX_WADFILES) @@ -3470,10 +3478,52 @@ static void Command_Addfolder(void) return; } - WRITESTRINGN(buf_p,p,240); + // Check if the path is valid. + stat = W_IsPathToFolderValid(fn); + + if (stat == 0) + { + CONS_Alert(CONS_WARNING, M_GetText("Path %s is invalid, skipping\n"), fn); + continue; + } + else if (stat < 0) + { +#ifndef AVOID_ERRNO + CONS_Alert(CONS_WARNING, M_GetText("Error accessing %s (%s), skipping\n"), fn, strerror(direrror)); +#else + CONS_Alert(CONS_WARNING, M_GetText("Error accessing %s, skipping\n"), fn); +#endif + continue; + } + + // Get the full path for this folder. + fullpath = W_GetFullFolderPath(fn); + + if (fullpath == NULL) + { + CONS_Alert(CONS_WARNING, M_GetText("Path %s is invalid, skipping\n"), fn); + continue; + } + + // Check if the folder is already added. + for (i = 0; i < numwadfiles; i++) + { + if (wadfiles[i]->type != RET_FOLDER) + continue; + + if (samepaths(wadfiles[i]->path, fullpath) > 0) + { + CONS_Alert(CONS_ERROR, M_GetText("%s is already loaded\n"), fn); + continue; + } + } + + Z_Free(fullpath); addedfolders[numfoldersadded++] = fn; + WRITESTRINGN(buf_p,p,240); + if (IsPlayerAdmin(consoleplayer) && (!server)) // Request to add file SendNetXCmd(XD_REQADDFOLDER, buf, buf_p - buf); else diff --git a/src/d_netfil.c b/src/d_netfil.c index 15f9f1ff5..12c5ee6a2 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -1584,20 +1584,23 @@ filestatus_t findfile(char *filename, const UINT8 *wantedmd5sum, boolean complet return (badmd5 ? FS_MD5SUMBAD : FS_NOTFOUND); // md5 sum bad or file not found } +// Searches for a folder. +// This can be used with a full path, or an incomplete path. +// In the latter case, the function will try to find folders in +// srb2home, srb2path, and the current directory. filestatus_t findfolder(const char *path) { // Check the path by itself first. - if (checkfolderpath(path, NULL, true)) + if (concatpaths(path, NULL) == 1) return FS_FOUND; -#define checkpath(startpath) { \ - if (checkfolderpath(path, startpath, true)) \ - return FS_FOUND; \ - } +#define checkpath(startpath) \ + if (concatpaths(path, startpath) == 1) \ + return FS_FOUND - checkpath(srb2home) // Then, look in srb2home. - checkpath(srb2path) // Now, look in srb2path. - checkpath(".") // Finally, look in ".". + checkpath(srb2home); // Then, look in srb2home. + checkpath(srb2path); // Now, look in srb2path. + checkpath("."); // Finally, look in the current directory. #undef checkpath diff --git a/src/filesrch.c b/src/filesrch.c index f01fc0bd2..e5c9b2158 100644 --- a/src/filesrch.c +++ b/src/filesrch.c @@ -341,8 +341,8 @@ char *refreshdirname = NULL; size_t packetsizetally = 0; size_t mainwadstally = 0; -#define folderpathlen 1024 -#define maxfolderdepth 48 +#define dirpathlen 1024 +#define maxdirdepth 48 #define isuptree(dirent) ((dirent)[0]=='.' && ((dirent)[1]=='\0' || ((dirent)[1]=='.' && (dirent)[2]=='\0'))) @@ -448,182 +448,227 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want return retval; } -// Called from findfolder and ResGetLumpsFolder in w_wad.c. -// Call with cleanup true if the path has to be verified. -boolean checkfolderpath(const char *path, const char *startpath, boolean cleanup) -{ - char folderpath[folderpathlen], basepath[folderpathlen], *fn = NULL; - DIR *dirhandle; +#ifndef AVOID_ERRNO +int direrror = 0; +#endif - // Remove path separators from the filename, and don't try adding "/". - // See also the same code in W_InitFolder. - if (cleanup) - { - const char *p = path + strlen(path); - size_t len; - - --p; - while (*p == '\\' || *p == '/' || *p == ':') - { - p--; - if (p < path) - return false; - } - ++p; - - // Allocate the new path name. - len = (p - path) + 1; - fn = ZZ_Alloc(len); - strlcpy(fn, path, len); - } - - if (startpath) - { - snprintf(basepath, sizeof basepath, "%s" PATHSEP, startpath); - - if (cleanup) - { - snprintf(folderpath, sizeof folderpath, "%s%s", basepath, fn); - Z_Free(fn); // Don't need this anymore. - } - else - snprintf(folderpath, sizeof folderpath, "%s%s", basepath, path); - - // Home path and folder path are the same? Not valid. - if (!strcmp(basepath, folderpath)) - return false; - } - else if (cleanup) - { - snprintf(folderpath, sizeof folderpath, "%s", fn); - Z_Free(fn); // Don't need this anymore. - } - else - snprintf(folderpath, sizeof folderpath, "%s", path); - - dirhandle = opendir(folderpath); - if (dirhandle == NULL) - return false; - else - closedir(dirhandle); - - return true; -} - -INT32 pathisfolder(const char *path) +// Checks if the specified path is a directory. +// Returns 1 if so, 0 if not, and -1 if an error occurred. +// direrror is set if there was an error. +INT32 pathisdirectory(const char *path) { struct stat fsstat; if (stat(path, &fsstat) < 0) + { +#ifndef AVOID_ERRNO + direrror = errno; +#endif return -1; + } else if (S_ISDIR(fsstat.st_mode)) return 1; return 0; } +// Concatenates two paths, and checks if it is a directory that can be opened. +// Returns 1 if so, 0 if not, and -1 if an error occurred. +INT32 concatpaths(const char *path, const char *startpath) +{ + char dirpath[dirpathlen]; + DIR *dirhandle; + INT32 stat; + + if (startpath) + { + char basepath[dirpathlen]; + + snprintf(basepath, sizeof basepath, "%s" PATHSEP, startpath); + snprintf(dirpath, sizeof dirpath, "%s%s", basepath, path); + + // Base path and directory path are the same? Not valid. + stat = samepaths(basepath, dirpath); + + if (stat == 1) + return 0; + else if (stat < 0) + return -1; + } + else + snprintf(dirpath, sizeof dirpath, "%s", path); + + // Check if the path is a directory. + // Will return -1 if there was an error. + stat = pathisdirectory(dirpath); + if (stat == 0) + return 0; + else if (stat < 0) + { + // The path doesn't exist, so it can't be a directory. + if (direrror == ENOENT) + return 0; + + return -1; + } + + // Open the directory. + // Will return 0 if it couldn't be opened. + dirhandle = opendir(dirpath); + if (dirhandle == NULL) + return 0; + else + closedir(dirhandle); + + return 1; +} + +// Checks if two paths are the same. Returns 1 if so, and 0 if not. +// Returns -1 if an error occurred with the first path, +// and returns -2 if an error occurred with the second path. +// direrror is set if there was an error. INT32 samepaths(const char *path1, const char *path2) { struct stat stat1; struct stat stat2; if (stat(path1, &stat1) < 0) + { +#ifndef AVOID_ERRNO + direrror = errno; +#endif return -1; + } if (stat(path2, &stat2) < 0) - return -1; + { +#ifndef AVOID_ERRNO + direrror = errno; +#endif + return -2; + } if (stat1.st_dev == stat2.st_dev) { #if !defined(_WIN32) return (stat1.st_ino == stat2.st_ino); #else + // The above doesn't work on NTFS or FAT. HANDLE file1 = CreateFileA(path1, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); HANDLE file2 = CreateFileA(path2, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); BY_HANDLE_FILE_INFORMATION file1info, file2info; - boolean ok = false; - if (file1 != INVALID_HANDLE_VALUE && file2 != INVALID_HANDLE_VALUE) + if (file1 == INVALID_HANDLE_VALUE) { - if (GetFileInformationByHandle(file1, &file1info) && GetFileInformationByHandle(file2, &file2info)) - { - if (file1info.dwVolumeSerialNumber == file2info.dwVolumeSerialNumber - && file1info.nFileIndexLow == file2info.nFileIndexLow - && file1info.nFileIndexHigh == file2info.nFileIndexHigh) - ok = true; - } +#ifndef AVOID_ERRNO + direrror = ENOENT; +#endif + return -1; + } + else if (file2 == INVALID_HANDLE_VALUE) + { + CloseHandle(file1); +#ifndef AVOID_ERRNO + direrror = ENOENT; +#endif + return -2; } - if (file1 != INVALID_HANDLE_VALUE) + // I have no idea why GetFileInformationByHandle would fail. + // Microsoft's documentation doesn't tell me. + // I'll just use EIO... + if (!GetFileInformationByHandle(file1, &file1info)) + { +#ifndef AVOID_ERRNO + direrror = EIO; +#endif + return -1; + } + else if (!GetFileInformationByHandle(file2, &file2info)) + { CloseHandle(file1); - if (file2 != INVALID_HANDLE_VALUE) CloseHandle(file2); +#ifndef AVOID_ERRNO + direrror = EIO; +#endif + return -2; + } - return ok; + if (file1info.dwVolumeSerialNumber == file2info.dwVolumeSerialNumber + && file1info.nFileIndexLow == file2info.nFileIndexLow + && file1info.nFileIndexHigh == file2info.nFileIndexHigh) + { + CloseHandle(file1); + CloseHandle(file2); + return 1; + } + + return 0; #endif } - return false; + return 0; } // -// Folder loading +// Directory loading // -static void initfolderpath(char *folderpath, size_t *folderpathindex, int depthleft) +static void initdirpath(char *dirpath, size_t *dirpathindex, int depthleft) { - folderpathindex[depthleft] = strlen(folderpath) + 1; + dirpathindex[depthleft] = strlen(dirpath) + 1; - if (folderpath[folderpathindex[depthleft]-2] != PATHSEP[0]) + if (dirpath[dirpathindex[depthleft]-2] != PATHSEP[0]) { - folderpath[folderpathindex[depthleft]-1] = PATHSEP[0]; - folderpath[folderpathindex[depthleft]] = 0; + dirpath[dirpathindex[depthleft]-1] = PATHSEP[0]; + dirpath[dirpathindex[depthleft]] = 0; } else - folderpathindex[depthleft]--; + dirpathindex[depthleft]--; } -lumpinfo_t *getfolderfiles(const char *path, UINT16 *nlmp, UINT16 *nfiles, UINT16 *nfolders) +lumpinfo_t *getdirectoryfiles(const char *path, UINT16 *nlmp, UINT16 *nfolders) { DIR **dirhandle; struct dirent *dent; struct stat fsstat; - int rootfolder = (maxfolderdepth - 1); - int depthleft = rootfolder; + int rootdir = (maxdirdepth - 1); + int depthleft = rootdir; - char folderpath[folderpathlen]; - size_t *folderpathindex; + char dirpath[dirpathlen]; + size_t *dirpathindex; lumpinfo_t *lumpinfo, *lump_p; - UINT16 i = 0, numlumps = (*nlmp); + UINT16 i = 0, numlumps = 0; - dirhandle = (DIR **)malloc(maxfolderdepth * sizeof (DIR*)); - folderpathindex = (size_t *)malloc(maxfolderdepth * sizeof(size_t)); + boolean failure = false; + + dirhandle = (DIR **)malloc(maxdirdepth * sizeof (DIR*)); + dirpathindex = (size_t *)malloc(maxdirdepth * sizeof(size_t)); // Open the root directory - strlcpy(folderpath, path, folderpathlen); - dirhandle[depthleft] = opendir(folderpath); + strlcpy(dirpath, path, dirpathlen); + dirhandle[depthleft] = opendir(dirpath); if (dirhandle[depthleft] == NULL) { free(dirhandle); - free(folderpathindex); + free(dirpathindex); return NULL; } - initfolderpath(folderpath, folderpathindex, depthleft); - (*nfiles) = 0; + initdirpath(dirpath, dirpathindex, depthleft); (*nfolders) = 0; // Count files and directories - while (depthleft < maxfolderdepth) + while (depthleft < maxdirdepth) { - folderpath[folderpathindex[depthleft]] = 0; + dirpath[dirpathindex[depthleft]] = 0; dent = readdir(dirhandle[depthleft]); if (!dent) { - if (depthleft != rootfolder) // Don't close the root directory + if (depthleft != rootdir) // Don't close the root directory closedir(dirhandle[depthleft]); depthleft++; continue; @@ -631,62 +676,67 @@ lumpinfo_t *getfolderfiles(const char *path, UINT16 *nlmp, UINT16 *nfiles, UINT1 else if (isuptree(dent->d_name)) continue; - strcpy(&folderpath[folderpathindex[depthleft]], dent->d_name); + strcpy(&dirpath[dirpathindex[depthleft]], dent->d_name); - if (stat(folderpath, &fsstat) < 0) + if (stat(dirpath, &fsstat) < 0) ; else if (S_ISDIR(fsstat.st_mode) && depthleft) { - folderpathindex[--depthleft] = strlen(folderpath) + 1; - dirhandle[depthleft] = opendir(folderpath); + dirpathindex[--depthleft] = strlen(dirpath) + 1; + dirhandle[depthleft] = opendir(dirpath); if (dirhandle[depthleft]) - { - numlumps++; (*nfolders)++; - } else depthleft++; - folderpath[folderpathindex[depthleft]-1] = '/'; - folderpath[folderpathindex[depthleft]] = 0; + dirpath[dirpathindex[depthleft]-1] = '/'; + dirpath[dirpathindex[depthleft]] = 0; } else - { numlumps++; - (*nfiles)++; - } - if (numlumps == (UINT16_MAX-1)) + // Failure: Too many files. + if (numlumps == UINT16_MAX) + { + (*nlmp) = UINT16_MAX; + failure = true; break; + } } // Failure: No files have been found. - if (!(*nfiles)) + if (!numlumps) { - (*nfiles) = UINT16_MAX; - free(folderpathindex); + (*nlmp) = 0; + failure = true; + } + + // Close any open directories and return if something went wrong. + if (failure) + { + free(dirpathindex); free(dirhandle); - for (; depthleft < maxfolderdepth; closedir(dirhandle[depthleft++])); // Close any open directories. + for (; depthleft < maxdirdepth; closedir(dirhandle[depthleft++])); return NULL; } // Create the files and directories as lump entries // It's possible to create lumps and count files at the same time, - // but I didn't to constantly have to reallocate memory for every lump. - rewinddir(dirhandle[rootfolder]); - depthleft = rootfolder; + // but I didn't want to have to reallocate memory for every lump. + rewinddir(dirhandle[rootdir]); + depthleft = rootdir; - strlcpy(folderpath, path, folderpathlen); - initfolderpath(folderpath, folderpathindex, depthleft); + strlcpy(dirpath, path, dirpathlen); + initdirpath(dirpath, dirpathindex, depthleft); lump_p = lumpinfo = Z_Calloc(numlumps * sizeof(lumpinfo_t), PU_STATIC, NULL); - while (depthleft < maxfolderdepth) + while (depthleft < maxdirdepth) { char *fullname, *trimname; - folderpath[folderpathindex[depthleft]] = 0; + dirpath[dirpathindex[depthleft]] = 0; dent = readdir(dirhandle[depthleft]); if (!dent) @@ -697,29 +747,30 @@ lumpinfo_t *getfolderfiles(const char *path, UINT16 *nlmp, UINT16 *nfiles, UINT1 else if (isuptree(dent->d_name)) continue; - strcpy(&folderpath[folderpathindex[depthleft]], dent->d_name); + strcpy(&dirpath[dirpathindex[depthleft]], dent->d_name); - if (stat(folderpath, &fsstat) < 0) + if (stat(dirpath, &fsstat) < 0) continue; else if (S_ISDIR(fsstat.st_mode) && depthleft) { - folderpathindex[--depthleft] = strlen(folderpath) + 1; - dirhandle[depthleft] = opendir(folderpath); + dirpathindex[--depthleft] = strlen(dirpath) + 1; + dirhandle[depthleft] = opendir(dirpath); - if (!dirhandle[depthleft]) + if (dirhandle[depthleft]) { - depthleft++; - continue; + dirpath[dirpathindex[depthleft]-1] = '/'; + dirpath[dirpathindex[depthleft]] = 0; } + else + depthleft++; - folderpath[folderpathindex[depthleft]-1] = '/'; - folderpath[folderpathindex[depthleft]] = 0; + continue; } - lump_p->diskpath = Z_StrDup(folderpath); // Path in the filesystem to the file + lump_p->diskpath = Z_StrDup(dirpath); // Path in the filesystem to the file lump_p->compression = CM_NOCOMPRESSION; // Lump is uncompressed - // Remove the folder path. + // Remove the directory's path. fullname = lump_p->diskpath; if (strstr(fullname, path)) fullname += strlen(path) + 1; @@ -747,7 +798,7 @@ lumpinfo_t *getfolderfiles(const char *path, UINT16 *nlmp, UINT16 *nfiles, UINT1 lump_p->longname = Z_Calloc(1, PU_STATIC, NULL); // The complete name of the file, with its extension, - // excluding the path of the folder where it resides. + // excluding the path of the directory where it resides. lump_p->fullname = Z_StrDup(fullname); lump_p++; @@ -755,12 +806,12 @@ lumpinfo_t *getfolderfiles(const char *path, UINT16 *nlmp, UINT16 *nfiles, UINT1 if (i > numlumps || i == (UINT16_MAX-1)) { - for (; depthleft < maxfolderdepth; closedir(dirhandle[depthleft++])); // Close any open directories. + for (; depthleft < maxdirdepth; closedir(dirhandle[depthleft++])); // Close any open directories. break; } } - free(folderpathindex); + free(dirpathindex); free(dirhandle); (*nlmp) = numlumps; diff --git a/src/filesrch.h b/src/filesrch.h index 92e3341f3..e358d7993 100644 --- a/src/filesrch.h +++ b/src/filesrch.h @@ -29,11 +29,15 @@ extern consvar_t cv_addons_option, cv_addons_folder, cv_addons_md5, cv_addons_sh filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum, boolean completepath, int maxsearchdepth); -INT32 pathisfolder(const char *path); -boolean checkfolderpath(const char *path, const char *startpath, boolean cleanup); +INT32 pathisdirectory(const char *path); INT32 samepaths(const char *path1, const char *path2); +boolean concatpaths(const char *path, const char *startpath); -lumpinfo_t *getfolderfiles(const char *path, UINT16 *nlmp, UINT16 *nfiles, UINT16 *nfolders); +#ifndef AVOID_ERRNO +extern int direrror; +#endif + +lumpinfo_t *getdirectoryfiles(const char *path, UINT16 *nlmp, UINT16 *nfolders); #define menudepth 20 diff --git a/src/m_misc.c b/src/m_misc.c index 4100a8f17..17d6d738b 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -2694,7 +2694,7 @@ boolean M_IsStringEmpty(const char *s) { const char *ch = s; - if (ch == NULL || (ch && strlen(ch) < 1)) + if (s == NULL || s[0] == '\0') return true; for (;;ch++) diff --git a/src/w_wad.c b/src/w_wad.c index e37c86bac..3ff301117 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -687,11 +687,67 @@ static lumpinfo_t* ResGetLumpsZip (FILE* handle, UINT16* nlmp) return lumpinfo; } +static INT32 CheckPathsNotEqual(const char *path1, const char *path2) +{ + INT32 stat = samepaths(path1, path2); + + if (stat == 1) + return 0; + else if (stat < 0) + return -1; + + return 1; +} + +// Returns 1 if the path is valid, 0 if not, and -1 if there was an error. +INT32 W_IsPathToFolderValid(const char *path) +{ + INT32 stat; + + // Remove path delimiters. + const char *p = path + (strlen(path) - 1); + while (*p == '\\' || *p == '/' || *p == ':') + { + p--; + if (p < path) + return 0; + } + + // Check if the path is a directory. + stat = pathisdirectory(path); + if (stat == 0) + return 0; + else if (stat < 0) + { + // The path doesn't exist, so it can't be a directory. + if (direrror == ENOENT) + return 0; + + return -1; + } + + // Don't add your home, you sodding tic tac. + stat = CheckPathsNotEqual(path, srb2home); + if (stat != 1) + return stat; + + // Do the same checks for SRB2's path, and the current directory. + stat = CheckPathsNotEqual(path, srb2path); + if (stat != 1) + return stat; + + stat = CheckPathsNotEqual(path, "."); + if (stat != 1) + return stat; + + return 1; +} + // Checks if the combination of the first path and the second path are valid. // If they are, the concatenated path is returned. -static char *W_CheckFolderPath(const char *startpath, const char *path) +static char *CheckConcatFolderPath(const char *startpath, const char *path) { - if (checkfolderpath(path, startpath, false)) + if (concatpaths(path, startpath) == 1) { char *fn; @@ -710,23 +766,23 @@ static char *W_CheckFolderPath(const char *startpath, const char *path) return NULL; } -// Returns the first valid path for a folder. -static char *W_GetFullFolderPath(const char *path) +// Looks for the first valid full path for a folder. +// Returns NULL if the folder doesn't exist, or it isn't valid. +char *W_GetFullFolderPath(const char *path) { // Check the path by itself first. - char *fn = W_CheckFolderPath(NULL, path); + char *fn = CheckConcatFolderPath(NULL, path); if (fn) return fn; -#define checkpath(startpath) { \ - fn = W_CheckFolderPath(startpath, path); \ +#define checkpath(startpath) \ + fn = CheckConcatFolderPath(startpath, path); \ if (fn) \ - return fn; \ -} \ + return fn - checkpath(srb2home) // Then, look in srb2home. - checkpath(srb2path) // Now, look in srb2path. - checkpath(".") // Finally, look in ".". + checkpath(srb2home); // Then, look in srb2home. + checkpath(srb2path); // Now, look in srb2path. + checkpath("."); // Finally, look in the current directory. #undef checkpath @@ -734,9 +790,9 @@ static char *W_GetFullFolderPath(const char *path) } // Loads files from a folder into a lumpinfo structure. -static lumpinfo_t *ResGetLumpsFolder(const char *path, UINT16 *nlmp, UINT16 *nfiles, UINT16 *nfolders) +static lumpinfo_t *ResGetLumpsFolder(const char *path, UINT16 *nlmp, UINT16 *nfolders) { - return getfolderfiles(path, nlmp, nfiles, nfolders); + return getdirectoryfiles(path, nlmp, nfolders); } static UINT16 W_InitFileError (const char *filename, boolean exitworthy) @@ -908,7 +964,7 @@ UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup) wadfile->type = type; wadfile->handle = handle; wadfile->numlumps = numlumps; - wadfile->filecount = wadfile->foldercount = 0; + wadfile->foldercount = 0; wadfile->lumpinfo = lumpinfo; wadfile->important = important; fseek(handle, 0, SEEK_END); @@ -966,11 +1022,12 @@ UINT16 W_InitFolder(const char *path, boolean mainfile, boolean startup) lumpinfo_t *lumpinfo = NULL; wadfile_t *wadfile; UINT16 numlumps = 0; - UINT16 filecount, foldercount; + UINT16 foldercount; size_t i; char *fn, *fullpath; const char *p; int important; + INT32 stat; if (!(refreshdirmenu & REFRESHDIR_ADDFILE)) refreshdirmenu = REFRESHDIR_NORMAL|REFRESHDIR_ADDFILE; // clean out cons_alerts that happened earlier @@ -1006,16 +1063,15 @@ UINT16 W_InitFolder(const char *path, boolean mainfile, boolean startup) packetsizetally = packetsize; } - // Remove path separators from the filename, and don't try adding "/". - p = path+strlen(path); - --p; + // Remove path delimiters. + p = path + (strlen(path) - 1); while (*p == '\\' || *p == '/' || *p == ':') { p--; if (p < path) { - CONS_Alert(CONS_ERROR, M_GetText("Path %s is prohibited\n"), path); + CONS_Alert(CONS_ERROR, M_GetText("Path %s is invalid\n"), path); return W_InitFileError(path, startup); } } @@ -1026,6 +1082,7 @@ UINT16 W_InitFolder(const char *path, boolean mainfile, boolean startup) fn = ZZ_Alloc(i); strlcpy(fn, path, i); + // Don't add an empty path. if (M_IsStringEmpty(fn)) { CONS_Alert(CONS_ERROR, M_GetText("Folder name is empty\n")); @@ -1037,14 +1094,36 @@ UINT16 W_InitFolder(const char *path, boolean mainfile, boolean startup) return W_InitFileError("a folder", false); } - // Get the full path for this filename. + // Check if the path is valid. + stat = W_IsPathToFolderValid(fn); + + if (stat != 1) + { + if (stat == 0) + CONS_Alert(CONS_ERROR, M_GetText("Path %s is invalid\n"), fn); + else if (stat < 0) + { +#ifndef AVOID_ERRNO + CONS_Alert(CONS_ERROR, M_GetText("Could not stat %s: %s\n"), fn, strerror(direrror)); +#else + CONS_Alert(CONS_ERROR, M_GetText("Could not stat %s\n"), fn); +#endif + } + + Z_Free(fn); + return W_InitFileError(path, startup); + } + + // Get the full path for this folder. fullpath = W_GetFullFolderPath(fn); if (fullpath == NULL) { + CONS_Alert(CONS_ERROR, M_GetText("Path %s is invalid\n"), fn); Z_Free(fn); - return W_InitFileError(path, false); + return W_InitFileError(path, startup); } + // Check if the folder is already added. for (i = 0; i < numwadfiles; i++) { if (wadfiles[i]->type != RET_FOLDER) @@ -1061,11 +1140,16 @@ UINT16 W_InitFolder(const char *path, boolean mainfile, boolean startup) } } - lumpinfo = ResGetLumpsFolder(fullpath, &numlumps, &filecount, &foldercount); + lumpinfo = ResGetLumpsFolder(fullpath, &numlumps, &foldercount); + if (lumpinfo == NULL) { - if (filecount == UINT16_MAX) + if (!numlumps) CONS_Alert(CONS_ERROR, M_GetText("Folder %s is empty\n"), path); + else if (numlumps == UINT16_MAX) + CONS_Alert(CONS_ERROR, M_GetText("Folder %s contains too many files\n"), path); + else + CONS_Alert(CONS_ERROR, M_GetText("Unknown error enumerating files from folder %s\n"), path); Z_Free(fn); Z_Free(fullpath); @@ -1082,7 +1166,6 @@ UINT16 W_InitFolder(const char *path, boolean mainfile, boolean startup) wadfile->type = RET_FOLDER; wadfile->handle = NULL; wadfile->numlumps = numlumps; - wadfile->filecount = filecount; wadfile->foldercount = foldercount; wadfile->lumpinfo = lumpinfo; wadfile->important = important; @@ -1094,7 +1177,7 @@ UINT16 W_InitFolder(const char *path, boolean mainfile, boolean startup) Z_Calloc(numlumps * sizeof (*wadfile->lumpcache), PU_STATIC, &wadfile->lumpcache); Z_Calloc(numlumps * sizeof (*wadfile->patchcache), PU_STATIC, &wadfile->patchcache); - CONS_Printf(M_GetText("Added folder %s (%u files, %u folders)\n"), fn, filecount, foldercount); + CONS_Printf(M_GetText("Added folder %s (%u files, %u folders)\n"), fn, numlumps, foldercount); wadfiles[numwadfiles] = wadfile; numwadfiles++; @@ -1506,12 +1589,24 @@ size_t W_LumpLengthPwad(UINT16 wad, UINT16 lump) l = wadfiles[wad]->lumpinfo + lump; + // Open the external file for this lump, if the WAD is a folder. if (wadfiles[wad]->type == RET_FOLDER) { - INT32 stat = pathisfolder(l->diskpath); + // pathisdirectory calls stat, so if anything wrong has happened, + // this is the time to be aware of it. + INT32 stat = pathisdirectory(l->diskpath); if (stat < 0) - I_Error("W_LumpLengthPwad: could not stat %s", l->diskpath); + { +#ifndef AVOID_ERRNO + if (direrror == ENOENT) + I_Error("W_LumpLengthPwad: file %s doesn't exist", l->diskpath); + else + I_Error("W_LumpLengthPwad: could not stat %s: %s", l->diskpath, strerror(direrror)); +#else + I_Error("W_LumpLengthPwad: could not access %s", l->diskpath); +#endif + } else if (stat == 1) // Path is a folder. return 0; else @@ -1617,7 +1712,7 @@ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, si lumpinfo_t *l; FILE *handle = NULL; - if (!TestValidLump(wad,lump)) + if (!TestValidLump(wad, lump)) return 0; l = wadfiles[wad]->lumpinfo + lump; @@ -1625,10 +1720,21 @@ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, si // Open the external file for this lump, if the WAD is a folder. if (wadfiles[wad]->type == RET_FOLDER) { - INT32 stat = pathisfolder(l->diskpath); + // pathisdirectory calls stat, so if anything wrong has happened, + // this is the time to be aware of it. + INT32 stat = pathisdirectory(l->diskpath); if (stat < 0) - I_Error("W_ReadLumpHeaderPwad: could not stat %s", l->diskpath); + { +#ifndef AVOID_ERRNO + if (direrror == ENOENT) + I_Error("W_ReadLumpHeaderPwad: file %s doesn't exist", l->diskpath); + else + I_Error("W_ReadLumpHeaderPwad: could not stat %s: %s", l->diskpath, strerror(direrror)); +#else + I_Error("W_ReadLumpHeaderPwad: could not access %s", l->diskpath); +#endif + } else if (stat == 1) // Path is a folder. return 0; else diff --git a/src/w_wad.h b/src/w_wad.h index 25b4bffa8..3958f7faf 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -122,7 +122,7 @@ typedef struct wadfile_s lumpcache_t *lumpcache; lumpcache_t *patchcache; UINT16 numlumps; // this wad's number of resources - UINT16 filecount, foldercount; // file and folder count + UINT16 foldercount; // folder count FILE *handle; UINT32 filesize; // for network UINT8 md5sum[16]; @@ -152,6 +152,9 @@ void W_InitMultipleFiles(char **filenames); #define W_FileHasFolders(wadfile) ((wadfile)->type == RET_PK3 || (wadfile)->type == RET_FOLDER) +boolean W_IsPathToFolderValid(const char *path); +char *W_GetFullFolderPath(const char *path); + const char *W_CheckNameForNumPwad(UINT16 wad, UINT16 lump); const char *W_CheckNameForNum(lumpnum_t lumpnum); From d5cdb2dc789530ab00a874a56e37f31d7ec4b3f8 Mon Sep 17 00:00:00 2001 From: SMS Alfredo Date: Sun, 12 Sep 2021 22:04:28 +0000 Subject: [PATCH 600/644] Add a missing scale assignment to A_Boss3ShockThink --- src/p_enemy.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/p_enemy.c b/src/p_enemy.c index 6a92c5d33..d148b11e0 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -8292,6 +8292,10 @@ void A_Boss3ShockThink(mobj_t *actor) snew->angle = (actor->angle + snext->angle) >> 1; P_SetTarget(&snew->target, actor->target); snew->fuse = actor->fuse; + + P_SetScale(snew, actor->scale); + snew->destscale = actor->destscale; + snew->scalespeed = actor->scalespeed; P_SetTarget(&actor->hnext, snew); P_SetTarget(&snew->hnext, snext); From db92f31f7d41ddd4356acdbf3cd7f4f420d7d34f Mon Sep 17 00:00:00 2001 From: Tatsuru Date: Sun, 12 Sep 2021 18:41:36 -0400 Subject: [PATCH 601/644] Revert "Merge branch 'draw-act-num' into 'next'" This reverts merge request !1532 --- src/lua_hudlib.c | 38 -------------------------------------- 1 file changed, 38 deletions(-) diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 0bfcfd9ea..3ce36f4f1 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -919,27 +919,6 @@ static int libd_drawString(lua_State *L) return 0; } -static int libd_drawLevelActNum(lua_State *L) -{ - INT32 x; - INT32 y; - UINT8 num; - INT32 flags; - - HUDONLY - - x = luaL_checkinteger(L, 1); - y = luaL_checkinteger(L, 2); - num = luaL_checkinteger(L, 3); - flags = luaL_optinteger(L, 4, 0); - - flags &= ~V_PARAMMASK; // Don't let crashes happen. - - V_DrawLevelActNum(x, y, flags, num); - return 0; -} - - static int libd_drawNameTag(lua_State *L) { INT32 x; @@ -1044,20 +1023,6 @@ static int libd_stringWidth(lua_State *L) return 1; } -static int libd_levelActNumWidth(lua_State *L) -{ - HUDONLY - lua_pushinteger(L, V_LevelActNumWidth(luaL_checkinteger(L, 1))); - return 1; -} - -static int libd_levelActNumHeight(lua_State *L) -{ - HUDONLY - lua_pushinteger(L, V_LevelActNumHeight(luaL_checkinteger(L, 1))); - return 1; -} - static int libd_nameTagWidth(lua_State *L) { HUDONLY @@ -1287,15 +1252,12 @@ static luaL_Reg lib_draw[] = { {"drawPaddedNum", libd_drawPaddedNum}, {"drawFill", libd_drawFill}, {"drawString", libd_drawString}, - {"drawLevelActNum", libd_drawLevelActNum}, {"drawNameTag", libd_drawNameTag}, {"drawScaledNameTag", libd_drawScaledNameTag}, {"drawLevelTitle", libd_drawLevelTitle}, {"fadeScreen", libd_fadeScreen}, // misc {"stringWidth", libd_stringWidth}, - {"levelActNumWidth", libd_levelActNumWidth}, - {"levelActNumHeight", libd_levelActNumHeight}, {"nameTagWidth", libd_nameTagWidth}, {"levelTitleWidth", libd_levelTitleWidth}, {"levelTitleHeight", libd_levelTitleHeight}, From fec5f2778e6ec27dc6c4272a720e744fc5c902ec Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 12 Sep 2021 18:53:51 -0700 Subject: [PATCH 602/644] Fix compiler warnings --- src/filesrch.c | 2 +- src/filesrch.h | 2 +- src/lua_hudlib.c | 10 ++++++---- src/sdl/i_system.c | 2 +- src/w_wad.h | 2 +- 5 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/filesrch.c b/src/filesrch.c index e5c9b2158..b4039e526 100644 --- a/src/filesrch.c +++ b/src/filesrch.c @@ -13,6 +13,7 @@ /// FS_FOUND #include +#include #ifdef __GNUC__ #include #endif @@ -33,7 +34,6 @@ #if defined (_WIN32) && defined (_MSC_VER) -#include #include #include diff --git a/src/filesrch.h b/src/filesrch.h index e358d7993..9d5f31bbb 100644 --- a/src/filesrch.h +++ b/src/filesrch.h @@ -31,7 +31,7 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want INT32 pathisdirectory(const char *path); INT32 samepaths(const char *path1, const char *path2); -boolean concatpaths(const char *path, const char *startpath); +INT32 concatpaths(const char *path, const char *startpath); #ifndef AVOID_ERRNO extern int direrror; diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 25f513e65..fca832053 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -401,14 +401,16 @@ static int camera_set(lua_State *L) case camera_x: case camera_y: return luaL_error(L, LUA_QL("camera_t") " field " LUA_QS " should not be set directly. Use " LUA_QL("P_TryCameraMove") " or " LUA_QL("P_TeleportCameraMove") " instead.", camera_opt[field]); - case camera_chase: + case camera_chase: { + INT32 chase = luaL_checkboolean(L, 3); if (cam == &camera) - CV_SetValue(&cv_chasecam, (INT32)luaL_checkboolean(L, 3)); + CV_SetValue(&cv_chasecam, chase); else if (cam == &camera2) - CV_SetValue(&cv_chasecam2, (INT32)luaL_checkboolean(L, 3)); + CV_SetValue(&cv_chasecam2, chase); else // ??? this should never happen, but ok - cam->chase = luaL_checkboolean(L, 3); + cam->chase = chase; break; + } case camera_aiming: cam->aiming = luaL_checkangle(L, 3); break; diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index a3908c570..2ec28ebc8 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -550,7 +550,7 @@ static void I_StartupConsole(void) void I_GetConsoleEvents(void) { // we use this when sending back commands - event_t ev = {0,0,0,0}; + event_t ev = {0}; char key = 0; ssize_t d; diff --git a/src/w_wad.h b/src/w_wad.h index 3958f7faf..949bab9fe 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -152,7 +152,7 @@ void W_InitMultipleFiles(char **filenames); #define W_FileHasFolders(wadfile) ((wadfile)->type == RET_PK3 || (wadfile)->type == RET_FOLDER) -boolean W_IsPathToFolderValid(const char *path); +INT32 W_IsPathToFolderValid(const char *path); char *W_GetFullFolderPath(const char *path); const char *W_CheckNameForNumPwad(UINT16 wad, UINT16 lump); From 923e6f31aa1737183f03e61dcddcd6cc3f27b5b6 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 12 Sep 2021 19:01:30 -0700 Subject: [PATCH 603/644] Fix faulty comparison Logical comparisons evaluate to a boolean value... --- src/p_spec.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index 8e51f788c..8ae0ec125 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1981,6 +1981,22 @@ void P_LinedefExecute(INT16 tag, mobj_t *actor, sector_t *caller) } } +static boolean is_rain_type (INT32 weathernum) +{ + switch (weathernum) + { + case PRECIP_SNOW: + case PRECIP_RAIN: + case PRECIP_STORM: + case PRECIP_STORM_NOSTRIKES: + case PRECIP_BLANK: + return true; + + default: + return false; + } +} + // // P_SwitchWeather // @@ -1989,12 +2005,12 @@ void P_LinedefExecute(INT16 tag, mobj_t *actor, sector_t *caller) void P_SwitchWeather(INT32 weathernum) { boolean purge = true; - boolean raintype = (PRECIP_SNOW || PRECIP_RAIN || PRECIP_STORM || PRECIP_STORM_NOSTRIKES || PRECIP_BLANK); if (weathernum == curWeather) return; - if (weathernum == raintype && curWeather == raintype) + if (is_rain_type(weathernum) && + is_rain_type(curWeather)) purge = false; if (purge) From 0ac36b7ce1cc28af073fb157af4ab139571746e4 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 12 Sep 2021 19:07:40 -0700 Subject: [PATCH 604/644] Remove mixed code and declarations warning --- src/Makefile.d/versions.mk | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Makefile.d/versions.mk b/src/Makefile.d/versions.mk index d7d0c3dd1..f0b59658e 100644 --- a/src/Makefile.d/versions.mk +++ b/src/Makefile.d/versions.mk @@ -35,8 +35,6 @@ ifndef GCC295 WFLAGS+=-Wendif-labels endif ifdef GCC41 - WFLAGS+=-Wdeclaration-after-statement - WFLAGS+=-Wno-error=declaration-after-statement WFLAGS+=-Wshadow endif #WFLAGS+=-Wlarger-than-%len% From 3d2f9e6150ab7216d8beea232262850d9e669125 Mon Sep 17 00:00:00 2001 From: katsy Date: Mon, 13 Sep 2021 17:20:20 -0500 Subject: [PATCH 605/644] don't create the default patches if we have an interscreen --- src/y_inter.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/y_inter.c b/src/y_inter.c index 6e1bc2e61..1abe01792 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -239,12 +239,12 @@ void Y_LoadIntermissionData(void) } data.coop.ptotal = W_CachePatchName("YB_TOTAL", PU_PATCH); - // get background patches - bgpatch = W_CachePatchName("INTERSCR", PU_PATCH); // grab an interscreen if appropriate if (mapheaderinfo[gamemap-1]->interscreen[0] != '#') interpic = W_CachePatchName(mapheaderinfo[gamemap-1]->interscreen, PU_PATCH); + else // no interscreen? use default background + bgpatch = W_CachePatchName("INTERSCR", PU_PATCH); break; } case int_spec: @@ -255,12 +255,11 @@ void Y_LoadIntermissionData(void) data.spec.pscore = W_CachePatchName("YB_SCORE", PU_PATCH); data.spec.pcontinues = W_CachePatchName("YB_CONTI", PU_PATCH); - // get background tile - bgtile = W_CachePatchName("SPECTILE", PU_PATCH); - // grab an interscreen if appropriate if (mapheaderinfo[gamemap-1]->interscreen[0] != '#') interpic = W_CachePatchName(mapheaderinfo[gamemap-1]->interscreen, PU_PATCH); + else // no interscreen? use default background + bgtile = W_CachePatchName("SPECTILE", PU_PATCH); break; } case int_ctf: From 143a515445f1307b98dbd79a458f966f71601185 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 21 Sep 2021 02:15:11 -0700 Subject: [PATCH 606/644] Correct Big Wave Dave/InstantSonic credits --- src/f_finale.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/f_finale.c b/src/f_finale.c index aecf79fc2..dc736a720 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1167,8 +1167,8 @@ static const char *credits[] = { "Alexander \"DrTapeworm\" Moench-Ford", "Stefan \"Stuf\" Rimalia", "Shane Mychal Sexton", - "David \"Big Wave Dave\" Spencer Sr.", - "David \"Instant Sonic\" Spencer Jr.", + "Dave \"Big Wave Dave\" Spencer", + "David \"InstantSonic\" Spencer", "\"SSNTails\"", "", "\1Level Design", From d88eb7cc14c239dfb30fbfae3dc00ebdd1a8b388 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 21 Sep 2021 02:17:44 -0700 Subject: [PATCH 607/644] Missed the 'i' --- src/f_finale.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/f_finale.c b/src/f_finale.c index dc736a720..47786bb60 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1168,7 +1168,7 @@ static const char *credits[] = { "Stefan \"Stuf\" Rimalia", "Shane Mychal Sexton", "Dave \"Big Wave Dave\" Spencer", - "David \"InstantSonic\" Spencer", + "David \"instantSonic\" Spencer", "\"SSNTails\"", "", "\1Level Design", From 791b981fd80cb23cee19d27170b347e10ce96ef1 Mon Sep 17 00:00:00 2001 From: katsy Date: Wed, 22 Sep 2021 16:22:47 -0500 Subject: [PATCH 608/644] null gamestate during pre-intermission to prevent unwanted interaction --- src/g_game.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/g_game.c b/src/g_game.c index de1a774f4..e497aa13f 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3927,6 +3927,9 @@ static void G_DoCompleted(void) if (metalrecording) G_StopMetalRecording(false); + G_SetGamestate(GS_NULL); + wipegamestate = GS_NULL; + for (i = 0; i < MAXPLAYERS; i++) if (playeringame[i]) G_PlayerFinishLevel(i); // take away cards and stuff From ed5942a0b6fb05c861384786f389f63d1fc528dc Mon Sep 17 00:00:00 2001 From: katsy Date: Wed, 22 Sep 2021 23:18:54 -0500 Subject: [PATCH 609/644] fix tailsbot controls --- src/g_game.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index de1a774f4..ce2aa41f5 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1549,8 +1549,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) // Note: Majority of botstuffs are handled in G_Ticker now. if (player->bot == BOT_2PHUMAN) //Player-controlled bot { - G_CopyTiccmd(cmd, I_BaseTiccmd2(), 1); // empty, or external driver - // Fix offset angle for P2-controlled Tailsbot when P2's controls are set to non-Legacy + // Fix offset angle for P2-controlled Tailsbot when P2's controls are set to non-Strafe cmd->angleturn = (INT16)((localangle - *myangle) >> 16); } From 0f4074f22d6e1bab37fa6c4e138270ec95e72a04 Mon Sep 17 00:00:00 2001 From: SteelT Date: Thu, 23 Sep 2021 13:45:42 -0400 Subject: [PATCH 610/644] Remove unused I_GetMouseGrab function --- src/i_system.h | 4 ---- src/sdl/i_video.c | 5 ----- 2 files changed, 9 deletions(-) diff --git a/src/i_system.h b/src/i_system.h index e046fd620..a3790dca3 100644 --- a/src/i_system.h +++ b/src/i_system.h @@ -318,10 +318,6 @@ void I_RegisterSysCommands(void); */ void I_GetCursorPosition(INT32 *x, INT32 *y); -/** \brief Returns whether the mouse is grabbed -*/ -boolean I_GetMouseGrab(void); - /** \brief Sets whether the mouse is grabbed */ void I_SetMouseGrab(boolean grab); diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 97e4a7214..ed766ff23 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -409,11 +409,6 @@ void I_UpdateMouseGrab(void) SDLdoGrabMouse(); } -boolean I_GetMouseGrab(void) -{ - return (boolean)SDL_GetWindowGrab(window); -} - void I_SetMouseGrab(boolean grab) { if (grab) From a8c6a652605b921d2accbf256c2ebbd27c9dd596 Mon Sep 17 00:00:00 2001 From: FlykeSpice Date: Mon, 11 Oct 2021 00:20:11 -0400 Subject: [PATCH 611/644] Fix visplanes getting allocated twice I guess that is legacy remnant stuff --- src/r_plane.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_plane.c b/src/r_plane.c index d844048ae..45719ce58 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -318,7 +318,7 @@ static visplane_t *new_visplane(unsigned hash) visplane_t *check = freetail; if (!check) { - check = calloc(2, sizeof (*check)); + check = malloc(sizeof (*check)); if (check == NULL) I_Error("%s: Out of memory", "new_visplane"); // FIXME: ugly } else From 8110473643e6b6e541a7f8e8217bed45dd64d671 Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Fri, 22 Oct 2021 18:31:37 -0500 Subject: [PATCH 612/644] Give userdata that needed names some names. --- src/lua_baselib.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 350c1585f..a0b5ff873 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -187,6 +187,8 @@ static const struct { {META_MAPHEADER, "mapheader_t"}, {META_POLYOBJ, "polyobj_t"}, + {META_POLYOBJVERTICES, "polyobj_t.vertices"}, + {META_POLYOBJLINES, "polyobj_t.lines"}, {META_CVAR, "consvar_t"}, @@ -216,6 +218,7 @@ static const struct { {META_LUABANKS, "luabanks[]"}, + {META_KEYEVENT, "keyevent_t"}, {META_MOUSE, "mouse_t"}, {NULL, NULL} }; From e10eddd11da065f0cb0955700055d09509bfd11a Mon Sep 17 00:00:00 2001 From: katsy <205-katsy@users.noreply.git.do.srb2.org> Date: Wed, 27 Oct 2021 17:52:29 +0000 Subject: [PATCH 613/644] Fix broken rain to rain weather switching --- src/p_spec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_spec.c b/src/p_spec.c index 8ae0ec125..07410efa2 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -2040,7 +2040,7 @@ void P_SwitchWeather(INT32 weathernum) continue; // not a precipmobj thinker precipmobj = (precipmobj_t *)think; - if (weathernum == (PRECIP_RAIN || PRECIP_STORM || PRECIP_STORM_NOSTRIKES)) // Snow To Rain + if (weathernum == PRECIP_RAIN || weathernum == PRECIP_STORM || weathernum == PRECIP_STORM_NOSTRIKES) // Snow To Rain { precipmobj->flags = mobjinfo[MT_RAIN].flags; st = &states[mobjinfo[MT_RAIN].spawnstate]; From 77ecfb9cdc92faea474cb91b65edd45c32a4ff40 Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Mon, 25 Oct 2021 20:49:15 +0300 Subject: [PATCH 614/644] Perfstats averaging and refactor --- src/d_clisrv.c | 11 +- src/d_main.c | 14 +- src/d_netcmd.c | 12 +- src/d_netcmd.h | 2 + src/hardware/hw_batching.c | 31 +- src/hardware/hw_main.c | 70 +-- src/hardware/hw_main.h | 30 +- src/lua_hooklib.c | 4 +- src/m_perfstats.c | 1074 ++++++++++++++++++++++-------------- src/m_perfstats.h | 43 +- src/p_map.c | 2 +- src/p_tick.c | 20 +- src/r_bsp.c | 4 +- src/r_main.c | 49 +- src/r_main.h | 26 +- src/r_things.c | 2 +- src/z_zone.h | 1 + 17 files changed, 840 insertions(+), 555 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index b7071320c..61b855319 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -4974,16 +4974,23 @@ void TryRunTics(tic_t realtics) // run the count * tics while (neededtic > gametic) { + boolean update_stats = !(paused || P_AutoPause()); + DEBFILE(va("============ Running tic %d (local %d)\n", gametic, localgametic)); - ps_tictime = I_GetPreciseTime(); + if (update_stats) + PS_START_TIMING(ps_tictime); G_Ticker((gametic % NEWTICRATERATIO) == 0); ExtraDataTicker(); gametic++; consistancy[gametic%BACKUPTICS] = Consistancy(); - ps_tictime = I_GetPreciseTime() - ps_tictime; + if (update_stats) + { + PS_STOP_TIMING(ps_tictime); + PS_UpdateTickStats(); + } // Leave a certain amount of tics present in the net buffer as long as we've ran at least one tic this frame. if (client && gamestate == GS_LEVEL && leveltime > 3 && neededtic <= gametic + cv_netticbuffer.value) diff --git a/src/d_main.c b/src/d_main.c index b4b668f4b..3845f08bd 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -476,7 +476,7 @@ static void D_Display(void) if (!automapactive && !dedicated && cv_renderview.value) { - ps_rendercalltime = I_GetPreciseTime(); + PS_START_TIMING(ps_rendercalltime); if (players[displayplayer].mo || players[displayplayer].playerstate == PST_DEAD) { topleft = screens[0] + viewwindowy*vid.width + viewwindowx; @@ -523,7 +523,7 @@ static void D_Display(void) if (postimgtype2) V_DoPostProcessor(1, postimgtype2, postimgparam2); } - ps_rendercalltime = I_GetPreciseTime() - ps_rendercalltime; + PS_STOP_TIMING(ps_rendercalltime); } if (lastdraw) @@ -537,7 +537,7 @@ static void D_Display(void) lastdraw = false; } - ps_uitime = I_GetPreciseTime(); + PS_START_TIMING(ps_uitime); if (gamestate == GS_LEVEL) { @@ -550,7 +550,7 @@ static void D_Display(void) } else { - ps_uitime = I_GetPreciseTime(); + PS_START_TIMING(ps_uitime); } } @@ -592,7 +592,7 @@ static void D_Display(void) CON_Drawer(); - ps_uitime = I_GetPreciseTime() - ps_uitime; + PS_STOP_TIMING(ps_uitime); // // wipe update @@ -678,9 +678,9 @@ static void D_Display(void) M_DrawPerfStats(); } - ps_swaptime = I_GetPreciseTime(); + PS_START_TIMING(ps_swaptime); I_FinishUpdate(); // page flip or blit buffer - ps_swaptime = I_GetPreciseTime() - ps_swaptime; + PS_STOP_TIMING(ps_swaptime); } } diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 5eb360bef..9d32f1bb1 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -47,6 +47,7 @@ #include "m_cond.h" #include "m_anigif.h" #include "md5.h" +#include "m_perfstats.h" #ifdef NETGAME_DEVMODE #define CV_RESTRICT CV_NETVAR @@ -374,7 +375,14 @@ consvar_t cv_sleep = CVAR_INIT ("cpusleep", "1", CV_SAVE, sleeping_cons_t, NULL) static CV_PossibleValue_t perfstats_cons_t[] = { {0, "Off"}, {1, "Rendering"}, {2, "Logic"}, {3, "ThinkFrame"}, {0, NULL}}; -consvar_t cv_perfstats = CVAR_INIT ("perfstats", "Off", 0, perfstats_cons_t, NULL); +consvar_t cv_perfstats = CVAR_INIT ("perfstats", "Off", CV_CALL, perfstats_cons_t, PS_PerfStats_OnChange); +static CV_PossibleValue_t ps_samplesize_cons_t[] = { + {1, "MIN"}, {1000, "MAX"}, {0, NULL}}; +consvar_t cv_ps_samplesize = CVAR_INIT ("ps_samplesize", "1", CV_CALL, ps_samplesize_cons_t, PS_SampleSize_OnChange); +static CV_PossibleValue_t ps_descriptor_cons_t[] = { + {1, "Average"}, {2, "SD"}, {3, "Minimum"}, {4, "Maximum"}, {0, NULL}}; +consvar_t cv_ps_descriptor = CVAR_INIT ("ps_descriptor", "Average", 0, ps_descriptor_cons_t, NULL); + consvar_t cv_freedemocamera = CVAR_INIT("freedemocamera", "Off", CV_SAVE, CV_OnOff, NULL); char timedemo_name[256]; @@ -867,6 +875,8 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_soundtest); CV_RegisterVar(&cv_perfstats); + CV_RegisterVar(&cv_ps_samplesize); + CV_RegisterVar(&cv_ps_descriptor); // ingame object placing COM_AddCommand("objectplace", Command_ObjectPlace_f); diff --git a/src/d_netcmd.h b/src/d_netcmd.h index cae32643e..30b39c0eb 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -110,6 +110,8 @@ extern consvar_t cv_skipmapcheck; extern consvar_t cv_sleep; extern consvar_t cv_perfstats; +extern consvar_t cv_ps_samplesize; +extern consvar_t cv_ps_descriptor; extern char timedemo_name[256]; extern boolean timedemo_csv; diff --git a/src/hardware/hw_batching.c b/src/hardware/hw_batching.c index 0ac33d136..da0319bcc 100644 --- a/src/hardware/hw_batching.c +++ b/src/hardware/hw_batching.c @@ -245,13 +245,16 @@ void HWR_RenderBatches(void) currently_batching = false;// no longer collecting batches if (!polygonArraySize) { - ps_hw_numpolys = ps_hw_numcalls = ps_hw_numshaders = ps_hw_numtextures = ps_hw_numpolyflags = ps_hw_numcolors = 0; + ps_hw_numpolys.value.i = ps_hw_numcalls.value.i = ps_hw_numshaders.value.i + = ps_hw_numtextures.value.i = ps_hw_numpolyflags.value.i + = ps_hw_numcolors.value.i = 0; return;// nothing to draw } // init stats vars - ps_hw_numpolys = polygonArraySize; - ps_hw_numcalls = ps_hw_numverts = 0; - ps_hw_numshaders = ps_hw_numtextures = ps_hw_numpolyflags = ps_hw_numcolors = 1; + ps_hw_numpolys.value.i = polygonArraySize; + ps_hw_numcalls.value.i = ps_hw_numverts.value.i = 0; + ps_hw_numshaders.value.i = ps_hw_numtextures.value.i + = ps_hw_numpolyflags.value.i = ps_hw_numcolors.value.i = 1; // init polygonIndexArray for (i = 0; i < polygonArraySize; i++) { @@ -259,12 +262,12 @@ void HWR_RenderBatches(void) } // sort polygons - ps_hw_batchsorttime = I_GetPreciseTime(); + PS_START_TIMING(ps_hw_batchsorttime); if (cv_glshaders.value && gl_shadersavailable) qsort(polygonIndexArray, polygonArraySize, sizeof(unsigned int), comparePolygons); else qsort(polygonIndexArray, polygonArraySize, sizeof(unsigned int), comparePolygonsNoShaders); - ps_hw_batchsorttime = I_GetPreciseTime() - ps_hw_batchsorttime; + PS_STOP_TIMING(ps_hw_batchsorttime); // sort order // 1. shader // 2. texture @@ -272,7 +275,7 @@ void HWR_RenderBatches(void) // 4. colors + light level // not sure about what order of the last 2 should be, or if it even matters - ps_hw_batchdrawtime = I_GetPreciseTime(); + PS_START_TIMING(ps_hw_batchdrawtime); currentShader = polygonArray[polygonIndexArray[0]].shader; currentTexture = polygonArray[polygonIndexArray[0]].texture; @@ -408,8 +411,8 @@ void HWR_RenderBatches(void) // execute draw call HWD.pfnDrawIndexedTriangles(¤tSurfaceInfo, finalVertexArray, finalIndexWritePos, currentPolyFlags, finalVertexIndexArray); // update stats - ps_hw_numcalls++; - ps_hw_numverts += finalIndexWritePos; + ps_hw_numcalls.value.i++; + ps_hw_numverts.value.i += finalIndexWritePos; // reset write positions finalVertexWritePos = 0; finalIndexWritePos = 0; @@ -426,7 +429,7 @@ void HWR_RenderBatches(void) currentShader = nextShader; changeShader = false; - ps_hw_numshaders++; + ps_hw_numshaders.value.i++; } if (changeTexture) { @@ -435,21 +438,21 @@ void HWR_RenderBatches(void) currentTexture = nextTexture; changeTexture = false; - ps_hw_numtextures++; + ps_hw_numtextures.value.i++; } if (changePolyFlags) { currentPolyFlags = nextPolyFlags; changePolyFlags = false; - ps_hw_numpolyflags++; + ps_hw_numpolyflags.value.i++; } if (changeSurfaceInfo) { currentSurfaceInfo = nextSurfaceInfo; changeSurfaceInfo = false; - ps_hw_numcolors++; + ps_hw_numcolors.value.i++; } // and that should be it? } @@ -457,7 +460,7 @@ void HWR_RenderBatches(void) polygonArraySize = 0; unsortedVertexArraySize = 0; - ps_hw_batchdrawtime = I_GetPreciseTime() - ps_hw_batchdrawtime; + PS_STOP_TIMING(ps_hw_batchdrawtime); } diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index e0851af85..9bade3d6f 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -147,22 +147,22 @@ static angle_t gl_aimingangle; static void HWR_SetTransformAiming(FTransform *trans, player_t *player, boolean skybox); // Render stats -precise_t ps_hw_skyboxtime = 0; -precise_t ps_hw_nodesorttime = 0; -precise_t ps_hw_nodedrawtime = 0; -precise_t ps_hw_spritesorttime = 0; -precise_t ps_hw_spritedrawtime = 0; +ps_metric_t ps_hw_skyboxtime = {0}; +ps_metric_t ps_hw_nodesorttime = {0}; +ps_metric_t ps_hw_nodedrawtime = {0}; +ps_metric_t ps_hw_spritesorttime = {0}; +ps_metric_t ps_hw_spritedrawtime = {0}; // Render stats for batching -int ps_hw_numpolys = 0; -int ps_hw_numverts = 0; -int ps_hw_numcalls = 0; -int ps_hw_numshaders = 0; -int ps_hw_numtextures = 0; -int ps_hw_numpolyflags = 0; -int ps_hw_numcolors = 0; -precise_t ps_hw_batchsorttime = 0; -precise_t ps_hw_batchdrawtime = 0; +ps_metric_t ps_hw_numpolys = {0}; +ps_metric_t ps_hw_numverts = {0}; +ps_metric_t ps_hw_numcalls = {0}; +ps_metric_t ps_hw_numshaders = {0}; +ps_metric_t ps_hw_numtextures = {0}; +ps_metric_t ps_hw_numpolyflags = {0}; +ps_metric_t ps_hw_numcolors = {0}; +ps_metric_t ps_hw_batchsorttime = {0}; +ps_metric_t ps_hw_batchdrawtime = {0}; boolean gl_init = false; boolean gl_maploaded = false; @@ -3235,7 +3235,7 @@ static void HWR_Subsector(size_t num) } // for render stats - ps_numpolyobjects += numpolys; + ps_numpolyobjects.value.i += numpolys; // Sort polyobjects R_SortPolyObjects(sub); @@ -3343,7 +3343,7 @@ static void HWR_RenderBSPNode(INT32 bspnum) // Decide which side the view point is on INT32 side; - ps_numbspcalls++; + ps_numbspcalls.value.i++; // Found a subsector? if (bspnum & NF_SUBSECTOR) @@ -4718,7 +4718,7 @@ static void HWR_CreateDrawNodes(void) // that is already lying around. This should all be in some sort of linked list or lists. sortindex = Z_Calloc(sizeof(size_t) * (numplanes + numpolyplanes + numwalls), PU_STATIC, NULL); - ps_hw_nodesorttime = I_GetPreciseTime(); + PS_START_TIMING(ps_hw_nodesorttime); for (i = 0; i < numplanes; i++, p++) { @@ -4738,7 +4738,7 @@ static void HWR_CreateDrawNodes(void) sortindex[p] = p; } - ps_numdrawnodes = p; + ps_numdrawnodes.value.i = p; // p is the number of stuff to sort @@ -4773,9 +4773,9 @@ static void HWR_CreateDrawNodes(void) } } - ps_hw_nodesorttime = I_GetPreciseTime() - ps_hw_nodesorttime; + PS_STOP_TIMING(ps_hw_nodesorttime); - ps_hw_nodedrawtime = I_GetPreciseTime(); + PS_START_TIMING(ps_hw_nodedrawtime); // Okay! Let's draw it all! Woo! HWD.pfnSetTransform(&atransform); @@ -4812,7 +4812,7 @@ static void HWR_CreateDrawNodes(void) } } - ps_hw_nodedrawtime = I_GetPreciseTime() - ps_hw_nodedrawtime; + PS_STOP_TIMING(ps_hw_nodedrawtime); numwalls = 0; numplanes = 0; @@ -6095,10 +6095,10 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) if (viewnumber == 0) // Only do it if it's the first screen being rendered HWD.pfnClearBuffer(true, false, &ClearColor); // Clear the Color Buffer, stops HOMs. Also seems to fix the skybox issue on Intel GPUs. - ps_hw_skyboxtime = I_GetPreciseTime(); + PS_START_TIMING(ps_hw_skyboxtime); if (skybox && drawsky) // If there's a skybox and we should be drawing the sky, draw the skybox HWR_RenderSkyboxView(viewnumber, player); // This is drawn before everything else so it is placed behind - ps_hw_skyboxtime = I_GetPreciseTime() - ps_hw_skyboxtime; + PS_STOP_TIMING(ps_hw_skyboxtime); { // do we really need to save player (is it not the same)? @@ -6208,9 +6208,9 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) // Reset the shader state. HWR_SetShaderState(); - ps_numbspcalls = 0; - ps_numpolyobjects = 0; - ps_bsptime = I_GetPreciseTime(); + ps_numbspcalls.value.i = 0; + ps_numpolyobjects.value.i = 0; + PS_START_TIMING(ps_bsptime); validcount++; @@ -6248,7 +6248,7 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) } #endif - ps_bsptime = I_GetPreciseTime() - ps_bsptime; + PS_STOP_TIMING(ps_bsptime); if (cv_glbatching.value) HWR_RenderBatches(); @@ -6263,22 +6263,22 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) #endif // Draw MD2 and sprites - ps_numsprites = gl_visspritecount; - ps_hw_spritesorttime = I_GetPreciseTime(); + ps_numsprites.value.i = gl_visspritecount; + PS_START_TIMING(ps_hw_spritesorttime); HWR_SortVisSprites(); - ps_hw_spritesorttime = I_GetPreciseTime() - ps_hw_spritesorttime; - ps_hw_spritedrawtime = I_GetPreciseTime(); + PS_STOP_TIMING(ps_hw_spritesorttime); + PS_START_TIMING(ps_hw_spritedrawtime); HWR_DrawSprites(); - ps_hw_spritedrawtime = I_GetPreciseTime() - ps_hw_spritedrawtime; + PS_STOP_TIMING(ps_hw_spritedrawtime); #ifdef NEWCORONAS //Hurdler: they must be drawn before translucent planes, what about gl fog? HWR_DrawCoronas(); #endif - ps_numdrawnodes = 0; - ps_hw_nodesorttime = 0; - ps_hw_nodedrawtime = 0; + ps_numdrawnodes.value.i = 0; + ps_hw_nodesorttime.value.p = 0; + ps_hw_nodedrawtime.value.p = 0; if (numplanes || numpolyplanes || numwalls) //Hurdler: render 3D water and transparent walls after everything { HWR_CreateDrawNodes(); diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index b751b2a6e..3f90f0ae1 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -20,6 +20,8 @@ #include "../d_player.h" #include "../r_defs.h" +#include "../m_perfstats.h" + // Startup & Shutdown the hardware mode renderer void HWR_Startup(void); void HWR_Switch(void); @@ -116,22 +118,22 @@ extern FTransform atransform; // Render stats -extern precise_t ps_hw_skyboxtime; -extern precise_t ps_hw_nodesorttime; -extern precise_t ps_hw_nodedrawtime; -extern precise_t ps_hw_spritesorttime; -extern precise_t ps_hw_spritedrawtime; +extern ps_metric_t ps_hw_skyboxtime; +extern ps_metric_t ps_hw_nodesorttime; +extern ps_metric_t ps_hw_nodedrawtime; +extern ps_metric_t ps_hw_spritesorttime; +extern ps_metric_t ps_hw_spritedrawtime; // Render stats for batching -extern int ps_hw_numpolys; -extern int ps_hw_numverts; -extern int ps_hw_numcalls; -extern int ps_hw_numshaders; -extern int ps_hw_numtextures; -extern int ps_hw_numpolyflags; -extern int ps_hw_numcolors; -extern precise_t ps_hw_batchsorttime; -extern precise_t ps_hw_batchdrawtime; +extern ps_metric_t ps_hw_numpolys; +extern ps_metric_t ps_hw_numverts; +extern ps_metric_t ps_hw_numcalls; +extern ps_metric_t ps_hw_numshaders; +extern ps_metric_t ps_hw_numtextures; +extern ps_metric_t ps_hw_numpolyflags; +extern ps_metric_t ps_hw_numcolors; +extern ps_metric_t ps_hw_batchsorttime; +extern ps_metric_t ps_hw_batchdrawtime; extern boolean gl_init; extern boolean gl_maploaded; diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 32b5e52fb..a72b22b5a 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -505,7 +505,7 @@ static int call_hooks calls += call_mobj_type_hooks(hook, MT_NULL); calls += call_mobj_type_hooks(hook, hook->mobj_type); - ps_lua_mobjhooks += calls; + ps_lua_mobjhooks.value.i += calls; } else calls += call_mapped(hook, &hookIds[hook->hook_type]); @@ -868,7 +868,7 @@ void LUA_HookLinedefExecute(line_t *line, mobj_t *mo, sector_t *sector) LUA_PushUserdata(gL, line, META_LINE); LUA_PushUserdata(gL, mo, META_MOBJ); LUA_PushUserdata(gL, sector, META_SECTOR); - ps_lua_mobjhooks += call_hooks(&hook, 0, res_none); + ps_lua_mobjhooks.value.i += call_hooks(&hook, 0, res_none); } } diff --git a/src/m_perfstats.c b/src/m_perfstats.c index 8a99312e6..9285b31be 100644 --- a/src/m_perfstats.c +++ b/src/m_perfstats.c @@ -22,46 +22,173 @@ #include "hardware/hw_main.h" #endif -struct perfstatcol; struct perfstatrow; -typedef struct perfstatcol perfstatcol_t; typedef struct perfstatrow perfstatrow_t; -struct perfstatcol { - INT32 lores_x; - INT32 hires_x; - INT32 color; - perfstatrow_t * rows; -}; - struct perfstatrow { - const char * lores_label; - const char * hires_label; - void * value; + const char * lores_label; + const char * hires_label; + ps_metric_t * metric; + UINT8 flags; }; -static precise_t ps_frametime = 0; +// perfstatrow_t flags -precise_t ps_tictime = 0; +#define PS_TIME 1 // metric measures time (uses precise_t instead of INT32) +#define PS_LEVEL 2 // metric is valid only when a level is active +#define PS_SW 4 // metric is valid only in software mode +#define PS_HW 8 // metric is valid only in opengl mode +#define PS_BATCHING 16 // metric is valid only when opengl batching is active +#define PS_HIDE_ZERO 32 // hide metric if its value is zero -precise_t ps_playerthink_time = 0; -precise_t ps_thinkertime = 0; +static ps_metric_t ps_frametime = {0}; -precise_t ps_thlist_times[NUM_THINKERLISTS]; +ps_metric_t ps_tictime = {0}; -int ps_checkposition_calls = 0; +ps_metric_t ps_playerthink_time = {0}; +ps_metric_t ps_thinkertime = {0}; -precise_t ps_lua_thinkframe_time = 0; -int ps_lua_mobjhooks = 0; +ps_metric_t ps_thlist_times[NUM_THINKERLISTS]; + +static ps_metric_t ps_thinkercount = {0}; +static ps_metric_t ps_polythcount = {0}; +static ps_metric_t ps_mainthcount = {0}; +static ps_metric_t ps_mobjcount = {0}; +static ps_metric_t ps_regularcount = {0}; +static ps_metric_t ps_scenerycount = {0}; +static ps_metric_t ps_nothinkcount = {0}; +static ps_metric_t ps_dynslopethcount = {0}; +static ps_metric_t ps_precipcount = {0}; +static ps_metric_t ps_removecount = {0}; + +ps_metric_t ps_checkposition_calls = {0}; + +ps_metric_t ps_lua_thinkframe_time = {0}; +ps_metric_t ps_lua_mobjhooks = {0}; + +ps_metric_t ps_otherlogictime = {0}; + +// Columns for perfstats pages. + +// Position on screen is determined separately in the drawing functions. + +// New columns must also be added to the drawing and update functions. +// Drawing functions: PS_DrawRenderStats, PS_DrawGameLogicStats, etc. +// Update functions: +// - PS_UpdateFrameStats for frame-dependent values +// - PS_UpdateTickStats for tick-dependent values + +// Rendering stats columns + +perfstatrow_t rendertime_rows[] = { + {"frmtime", "Frame time: ", &ps_frametime, PS_TIME}, + {"drwtime", "3d rendering: ", &ps_rendercalltime, PS_TIME|PS_LEVEL}, + +#ifdef HWRENDER + {" skybox ", " Skybox render: ", &ps_hw_skyboxtime, PS_TIME|PS_LEVEL|PS_HW}, + {" bsptime", " RenderBSPNode: ", &ps_bsptime, PS_TIME|PS_LEVEL|PS_HW}, + {" batsort", " Batch sort: ", &ps_hw_batchsorttime, PS_TIME|PS_LEVEL|PS_HW|PS_BATCHING}, + {" batdraw", " Batch render: ", &ps_hw_batchdrawtime, PS_TIME|PS_LEVEL|PS_HW|PS_BATCHING}, + {" sprsort", " Sprite sort: ", &ps_hw_spritesorttime, PS_TIME|PS_LEVEL|PS_HW}, + {" sprdraw", " Sprite render: ", &ps_hw_spritedrawtime, PS_TIME|PS_LEVEL|PS_HW}, + {" nodesrt", " Drwnode sort: ", &ps_hw_nodesorttime, PS_TIME|PS_LEVEL|PS_HW}, + {" nodedrw", " Drwnode render:", &ps_hw_nodedrawtime, PS_TIME|PS_LEVEL|PS_HW}, + {" other ", " Other: ", &ps_otherrendertime, PS_TIME|PS_LEVEL|PS_HW}, +#endif + + {" bsptime", " RenderBSPNode: ", &ps_bsptime, PS_TIME|PS_LEVEL|PS_SW}, + {" sprclip", " R_ClipSprites: ", &ps_sw_spritecliptime, PS_TIME|PS_LEVEL|PS_SW}, + {" portals", " Portals+Skybox:", &ps_sw_portaltime, PS_TIME|PS_LEVEL|PS_SW}, + {" planes ", " R_DrawPlanes: ", &ps_sw_planetime, PS_TIME|PS_LEVEL|PS_SW}, + {" masked ", " R_DrawMasked: ", &ps_sw_maskedtime, PS_TIME|PS_LEVEL|PS_SW}, + {" other ", " Other: ", &ps_otherrendertime, PS_TIME|PS_LEVEL|PS_SW}, + + {"ui ", "UI render: ", &ps_uitime, PS_TIME}, + {"finupdt", "I_FinishUpdate:", &ps_swaptime, PS_TIME}, + {0} +}; + +perfstatrow_t gamelogicbrief_row[] = { + {"logic ", "Game logic: ", &ps_tictime, PS_TIME}, + {0} +}; + +perfstatrow_t commoncounter_rows[] = { + {"bspcall", "BSP calls: ", &ps_numbspcalls, 0}, + {"sprites", "Sprites: ", &ps_numsprites, 0}, + {"drwnode", "Drawnodes: ", &ps_numdrawnodes, 0}, + {"plyobjs", "Polyobjects: ", &ps_numpolyobjects, 0}, + {0} +}; + +#ifdef HWRENDER +perfstatrow_t batchcount_rows[] = { + {"polygon", "Polygons: ", &ps_hw_numpolys, 0}, + {"vertex ", "Vertices: ", &ps_hw_numverts, 0}, + {0} +}; + +perfstatrow_t batchcalls_rows[] = { + {"drwcall", "Draw calls:", &ps_hw_numcalls, 0}, + {"shaders", "Shaders: ", &ps_hw_numshaders, 0}, + {"texture", "Textures: ", &ps_hw_numtextures, 0}, + {"polyflg", "Polyflags: ", &ps_hw_numpolyflags, 0}, + {"colors ", "Colors: ", &ps_hw_numcolors, 0}, + {0} +}; +#endif + +// Game logic stats columns + +perfstatrow_t gamelogic_rows[] = { + {"logic ", "Game logic: ", &ps_tictime, PS_TIME}, + {" plrthnk", " P_PlayerThink: ", &ps_playerthink_time, PS_TIME|PS_LEVEL}, + {" thnkers", " P_RunThinkers: ", &ps_thinkertime, PS_TIME|PS_LEVEL}, + {" plyobjs", " Polyobjects: ", &ps_thlist_times[THINK_POLYOBJ], PS_TIME|PS_LEVEL}, + {" main ", " Main: ", &ps_thlist_times[THINK_MAIN], PS_TIME|PS_LEVEL}, + {" mobjs ", " Mobjs: ", &ps_thlist_times[THINK_MOBJ], PS_TIME|PS_LEVEL}, + {" dynslop", " Dynamic slopes: ", &ps_thlist_times[THINK_DYNSLOPE], PS_TIME|PS_LEVEL}, + {" precip ", " Precipitation: ", &ps_thlist_times[THINK_PRECIP], PS_TIME|PS_LEVEL}, + {" lthinkf", " LUAh_ThinkFrame:", &ps_lua_thinkframe_time, PS_TIME|PS_LEVEL}, + {" other ", " Other: ", &ps_otherlogictime, PS_TIME|PS_LEVEL}, + {0} +}; + +perfstatrow_t thinkercount_rows[] = { + {"thnkers", "Thinkers: ", &ps_thinkercount, PS_LEVEL}, + {" plyobjs", " Polyobjects: ", &ps_polythcount, PS_LEVEL}, + {" main ", " Main: ", &ps_mainthcount, PS_LEVEL}, + {" mobjs ", " Mobjs: ", &ps_mobjcount, PS_LEVEL}, + {" regular", " Regular: ", &ps_regularcount, PS_LEVEL}, + {" scenery", " Scenery: ", &ps_scenerycount, PS_LEVEL}, + {" nothink", " Nothink: ", &ps_nothinkcount, PS_HIDE_ZERO|PS_LEVEL}, + {" dynslop", " Dynamic slopes: ", &ps_dynslopethcount, PS_LEVEL}, + {" precip ", " Precipitation: ", &ps_precipcount, PS_LEVEL}, + {" remove ", " Pending removal:", &ps_removecount, PS_LEVEL}, + {0} +}; + +perfstatrow_t misc_calls_rows[] = { + {"lmhook", "Lua mobj hooks: ", &ps_lua_mobjhooks, PS_LEVEL}, + {"chkpos", "P_CheckPosition:", &ps_checkposition_calls, PS_LEVEL}, + {0} +}; + +// Sample collection status for averaging. +// Maximum of these two is shown to user if nonzero to tell that +// the reported averages are not correct yet. +int ps_frame_samples_left = 0; +int ps_tick_samples_left = 0; +// History writing positions for frame and tick based metrics +int ps_frame_index = 0; +int ps_tick_index = 0; // dynamically allocated resizeable array for thinkframe hook stats ps_hookinfo_t *thinkframe_hooks = NULL; int thinkframe_hooks_length = 0; int thinkframe_hooks_capacity = 16; -static INT32 draw_row; - void PS_SetThinkFrameHookInfo(int index, precise_t time_taken, char* short_src) { if (!thinkframe_hooks) @@ -76,506 +203,617 @@ void PS_SetThinkFrameHookInfo(int index, precise_t time_taken, char* short_src) thinkframe_hooks = Z_Realloc(thinkframe_hooks, sizeof(ps_hookinfo_t) * thinkframe_hooks_capacity, PU_STATIC, NULL); } - thinkframe_hooks[index].time_taken = time_taken; + thinkframe_hooks[index].time_taken.value.p = time_taken; memcpy(thinkframe_hooks[index].short_src, short_src, LUA_IDSIZE * sizeof(char)); // since the values are set sequentially from begin to end, the last call should leave // the correct value to this variable thinkframe_hooks_length = index + 1; } -static void PS_SetFrameTime(void) -{ - precise_t currenttime = I_GetPreciseTime(); - ps_frametime = currenttime - ps_prevframetime; - ps_prevframetime = currenttime; -} - -static boolean M_HighResolution(void) +static boolean PS_HighResolution(void) { return (vid.width >= 640 && vid.height >= 400); } -enum { - PERF_TIME, - PERF_COUNT, -}; - -static void M_DrawPerfString(perfstatcol_t *col, int type) +static boolean PS_IsLevelActive(void) { - const boolean hires = M_HighResolution(); + return gamestate == GS_LEVEL || + (gamestate == GS_TITLESCREEN && titlemapinaction); +} - INT32 draw_flags = V_MONOSPACE | col->color; +// Is the row valid in the current context? +static boolean PS_IsRowValid(perfstatrow_t *row) +{ + return !((row->flags & PS_LEVEL && !PS_IsLevelActive()) || + (row->flags & PS_SW && rendermode != render_soft) || + (row->flags & PS_HW && rendermode != render_opengl) || + (row->flags & PS_BATCHING && !cv_glbatching.value)); +} +// Should the row be visible on the screen? +static boolean PS_IsRowVisible(perfstatrow_t *row) +{ + boolean value_is_zero; + + if (row->flags & PS_TIME) + value_is_zero = row->metric->value.p == 0; + else + value_is_zero = row->metric->value.i == 0; + + return !(!PS_IsRowValid(row) || + (row->flags & PS_HIDE_ZERO && value_is_zero)); +} + +static INT32 PS_GetMetricAverage(ps_metric_t *metric, boolean time_metric) +{ + char* history_read_pos = metric->history; // char* used for pointer arithmetic + INT64 sum = 0; + int i; + int value_size = time_metric ? sizeof(precise_t) : sizeof(INT32); + + for (i = 0; i < cv_ps_samplesize.value; i++) + { + if (time_metric) + sum += I_PreciseToMicros(*((precise_t*)history_read_pos)); + else + sum += *((INT32*)history_read_pos); + history_read_pos += value_size; + } + + return sum / cv_ps_samplesize.value; +} + +static INT32 PS_GetMetricMinOrMax(ps_metric_t *metric, boolean time_metric, boolean get_max) +{ + char* history_read_pos = metric->history; // char* used for pointer arithmetic + INT32 found_value = get_max ? INT32_MIN : INT32_MAX; + int i; + int value_size = time_metric ? sizeof(precise_t) : sizeof(INT32); + + for (i = 0; i < cv_ps_samplesize.value; i++) + { + INT32 value; + if (time_metric) + value = I_PreciseToMicros(*((precise_t*)history_read_pos)); + else + value = *((INT32*)history_read_pos); + + if ((get_max && value > found_value) || + (!get_max && value < found_value)) + { + found_value = value; + } + history_read_pos += value_size; + } + + return found_value; +} + +// Calculates the standard deviation for metric. +static INT32 PS_GetMetricSD(ps_metric_t *metric, boolean time_metric) +{ + char* history_read_pos = metric->history; // char* used for pointer arithmetic + INT64 sum = 0; + int i; + int value_size = time_metric ? sizeof(precise_t) : sizeof(INT32); + INT32 avg = PS_GetMetricAverage(metric, time_metric); + + for (i = 0; i < cv_ps_samplesize.value; i++) + { + INT64 value; + if (time_metric) + value = I_PreciseToMicros(*((precise_t*)history_read_pos)); + else + value = *((INT32*)history_read_pos); + + value -= avg; + sum += value * value; + + history_read_pos += value_size; + } + + return round(sqrt(sum / cv_ps_samplesize.value)); +} + +// Returns the value to show on screen for metric. +static INT32 PS_GetMetricScreenValue(ps_metric_t *metric, boolean time_metric) +{ + if (cv_ps_samplesize.value > 1 && metric->history) + { + if (cv_ps_descriptor.value == 1) + return PS_GetMetricAverage(metric, time_metric); + else if (cv_ps_descriptor.value == 2) + return PS_GetMetricSD(metric, time_metric); + else if (cv_ps_descriptor.value == 3) + return PS_GetMetricMinOrMax(metric, time_metric, false); + else + return PS_GetMetricMinOrMax(metric, time_metric, true); + } + else + { + if (time_metric) + return I_PreciseToMicros(metric->value.p); + else + return metric->value.i; + } +} + +static int PS_DrawPerfRows(int x, int y, int color, perfstatrow_t *rows) +{ + const boolean hires = PS_HighResolution(); + INT32 draw_flags = V_MONOSPACE | color; perfstatrow_t * row; - - int value; + int draw_y = y; if (hires) draw_flags |= V_ALLOWLOWERCASE; - for (row = col->rows; row->lores_label; ++row) + for (row = rows; row->lores_label; ++row) { - if (type == PERF_TIME) - value = I_PreciseToMicros(*(precise_t *)row->value); - else - value = *(int *)row->value; + const char *label; + INT32 value; + char *final_str; + + if (!PS_IsRowVisible(row)) + continue; + + label = hires ? row->hires_label : row->lores_label; + value = PS_GetMetricScreenValue(row->metric, !!(row->flags & PS_TIME)); + final_str = va("%s %d", label, value); if (hires) { - V_DrawSmallString(col->hires_x, draw_row, draw_flags, - va("%s %d", row->hires_label, value)); - - draw_row += 5; + V_DrawSmallString(x, draw_y, draw_flags, final_str); + draw_y += 5; } else { - V_DrawThinString(col->lores_x, draw_row, draw_flags, - va("%s %d", row->lores_label, value)); - - draw_row += 8; + V_DrawThinString(x, draw_y, draw_flags, final_str); + draw_y += 8; } } + + return draw_y; +} + +static void PS_UpdateMetricHistory(ps_metric_t *metric, boolean time_metric, boolean frame_metric, boolean set_user) +{ + int index = frame_metric ? ps_frame_index : ps_tick_index; + + if (!metric->history) + { + // allocate history table + int value_size = time_metric ? sizeof(precise_t) : sizeof(INT32); + void** memory_user = set_user ? &metric->history : NULL; + + metric->history = Z_Calloc(value_size * cv_ps_samplesize.value, PU_PERFSTATS, + memory_user); + + // reset "samples left" counter since this history table needs to be filled + if (frame_metric) + ps_frame_samples_left = cv_ps_samplesize.value; + else + ps_tick_samples_left = cv_ps_samplesize.value; + } + + if (time_metric) + { + precise_t *history = (precise_t*)metric->history; + history[index] = metric->value.p; + } + else + { + INT32 *history = (INT32*)metric->history; + history[index] = metric->value.i; + } } -static void M_DrawPerfTiming(perfstatcol_t *col) +static void PS_UpdateRowHistories(perfstatrow_t *rows, boolean frame_metric) { - M_DrawPerfString(col, PERF_TIME); -} - -static void M_DrawPerfCount(perfstatcol_t *col) -{ - M_DrawPerfString(col, PERF_COUNT); -} - -static void M_DrawRenderStats(void) -{ - const boolean hires = M_HighResolution(); - - const int half_row = hires ? 5 : 4; - - precise_t extrarendertime; - - perfstatrow_t frametime_row[] = { - {"frmtime", "Frame time: ", &ps_frametime}, - {0} - }; - - perfstatrow_t rendercalltime_row[] = { - {"drwtime", "3d rendering: ", &ps_rendercalltime}, - {0} - }; - - perfstatrow_t opengltime_row[] = { - {"skybox ", "Skybox render: ", &ps_hw_skyboxtime}, - {"bsptime", "RenderBSPNode: ", &ps_bsptime}, - {"nodesrt", "Drwnode sort: ", &ps_hw_nodesorttime}, - {"nodedrw", "Drwnode render:", &ps_hw_nodedrawtime}, - {"sprsort", "Sprite sort: ", &ps_hw_spritesorttime}, - {"sprdraw", "Sprite render: ", &ps_hw_spritedrawtime}, - {"other ", "Other: ", &extrarendertime}, - {0} - }; - - perfstatrow_t softwaretime_row[] = { - {"bsptime", "RenderBSPNode: ", &ps_bsptime}, - {"sprclip", "R_ClipSprites: ", &ps_sw_spritecliptime}, - {"portals", "Portals+Skybox:", &ps_sw_portaltime}, - {"planes ", "R_DrawPlanes: ", &ps_sw_planetime}, - {"masked ", "R_DrawMasked: ", &ps_sw_maskedtime}, - {"other ", "Other: ", &extrarendertime}, - {0} - }; - - perfstatrow_t uiswaptime_row[] = { - {"ui ", "UI render: ", &ps_uitime}, - {"finupdt", "I_FinishUpdate:", &ps_swaptime}, - {0} - }; - - perfstatrow_t tictime_row[] = { - {"logic ", "Game logic: ", &ps_tictime}, - {0} - }; - - perfstatrow_t rendercalls_row[] = { - {"bspcall", "BSP calls: ", &ps_numbspcalls}, - {"sprites", "Sprites: ", &ps_numsprites}, - {"drwnode", "Drawnodes: ", &ps_numdrawnodes}, - {"plyobjs", "Polyobjects: ", &ps_numpolyobjects}, - {0} - }; - - perfstatrow_t batchtime_row[] = { - {"batsort", "Batch sort: ", &ps_hw_batchsorttime}, - {"batdraw", "Batch render:", &ps_hw_batchdrawtime}, - {0} - }; - - perfstatrow_t batchcount_row[] = { - {"polygon", "Polygons: ", &ps_hw_numpolys}, - {"vertex ", "Vertices: ", &ps_hw_numverts}, - {0} - }; - - perfstatrow_t batchcalls_row[] = { - {"drwcall", "Draw calls:", &ps_hw_numcalls}, - {"shaders", "Shaders: ", &ps_hw_numshaders}, - {"texture", "Textures: ", &ps_hw_numtextures}, - {"polyflg", "Polyflags: ", &ps_hw_numpolyflags}, - {"colors ", "Colors: ", &ps_hw_numcolors}, - {0} - }; - - perfstatcol_t frametime_col = {20, 20, V_YELLOWMAP, frametime_row}; - perfstatcol_t rendercalltime_col = {20, 20, V_YELLOWMAP, rendercalltime_row}; - - perfstatcol_t opengltime_col = {24, 24, V_YELLOWMAP, opengltime_row}; - perfstatcol_t softwaretime_col = {24, 24, V_YELLOWMAP, softwaretime_row}; - - perfstatcol_t uiswaptime_col = {20, 20, V_YELLOWMAP, uiswaptime_row}; - perfstatcol_t tictime_col = {20, 20, V_GRAYMAP, tictime_row}; - - perfstatcol_t rendercalls_col = {90, 115, V_BLUEMAP, rendercalls_row}; - - perfstatcol_t batchtime_col = {90, 115, V_REDMAP, batchtime_row}; - - perfstatcol_t batchcount_col = {155, 200, V_PURPLEMAP, batchcount_row}; - perfstatcol_t batchcalls_col = {220, 200, V_PURPLEMAP, batchcalls_row}; - - - boolean rendering = ( - gamestate == GS_LEVEL || - (gamestate == GS_TITLESCREEN && titlemapinaction) - ); - - draw_row = 10; - M_DrawPerfTiming(&frametime_col); - - if (rendering) + perfstatrow_t *row; + for (row = rows; row->lores_label; row++) { - M_DrawPerfTiming(&rendercalltime_col); + if (PS_IsRowValid(row)) + PS_UpdateMetricHistory(row->metric, !!(row->flags & PS_TIME), frame_metric, true); + } +} +// Update all metrics that are calculated on every frame. +static void PS_UpdateFrameStats(void) +{ + // update frame time + precise_t currenttime = I_GetPreciseTime(); + ps_frametime.value.p = currenttime - ps_prevframetime; + ps_prevframetime = currenttime; + + // update 3d rendering stats + if (PS_IsLevelActive()) + { // Remember to update this calculation when adding more 3d rendering stats! - extrarendertime = ps_rendercalltime - ps_bsptime; + ps_otherrendertime.value.p = ps_rendercalltime.value.p - ps_bsptime.value.p; #ifdef HWRENDER if (rendermode == render_opengl) { - extrarendertime -= - ps_hw_skyboxtime + - ps_hw_nodesorttime + - ps_hw_nodedrawtime + - ps_hw_spritesorttime + - ps_hw_spritedrawtime; + ps_otherrendertime.value.p -= + ps_hw_skyboxtime.value.p + + ps_hw_nodesorttime.value.p + + ps_hw_nodedrawtime.value.p + + ps_hw_spritesorttime.value.p + + ps_hw_spritedrawtime.value.p; if (cv_glbatching.value) { - extrarendertime -= - ps_hw_batchsorttime + - ps_hw_batchdrawtime; + ps_otherrendertime.value.p -= + ps_hw_batchsorttime.value.p + + ps_hw_batchdrawtime.value.p; } - - M_DrawPerfTiming(&opengltime_col); } else #endif { - extrarendertime -= - ps_sw_spritecliptime + - ps_sw_portaltime + - ps_sw_planetime + - ps_sw_maskedtime; - - M_DrawPerfTiming(&softwaretime_col); + ps_otherrendertime.value.p -= + ps_sw_spritecliptime.value.p + + ps_sw_portaltime.value.p + + ps_sw_planetime.value.p + + ps_sw_maskedtime.value.p; } } - M_DrawPerfTiming(&uiswaptime_col); - - draw_row += half_row; - M_DrawPerfTiming(&tictime_col); - - if (rendering) + if (cv_ps_samplesize.value > 1) { - draw_row = 10; - M_DrawPerfCount(&rendercalls_col); + PS_UpdateRowHistories(rendertime_rows, true); + if (PS_IsLevelActive()) + PS_UpdateRowHistories(commoncounter_rows, true); #ifdef HWRENDER if (rendermode == render_opengl && cv_glbatching.value) { - draw_row += half_row; - M_DrawPerfTiming(&batchtime_col); - - draw_row = 10; - M_DrawPerfCount(&batchcount_col); - - if (hires) - draw_row += half_row; - else - draw_row = 10; - - M_DrawPerfCount(&batchcalls_col); + PS_UpdateRowHistories(batchcount_rows, true); + PS_UpdateRowHistories(batchcalls_rows, true); } #endif + + ps_frame_index++; + if (ps_frame_index >= cv_ps_samplesize.value) + ps_frame_index = 0; + if (ps_frame_samples_left) + ps_frame_samples_left--; } } -static void M_DrawTickStats(void) +// Update thinker counters by iterating the thinker lists. +static void PS_CountThinkers(void) { - int i = 0; + int i; thinker_t *thinker; - int thinkercount = 0; - int polythcount = 0; - int mainthcount = 0; - int mobjcount = 0; - int nothinkcount = 0; - int scenerycount = 0; - int regularcount = 0; - int dynslopethcount = 0; - int precipcount = 0; - int removecount = 0; - precise_t extratime = - ps_tictime - - ps_playerthink_time - - ps_thinkertime - - ps_lua_thinkframe_time; - - perfstatrow_t tictime_row[] = { - {"logic ", "Game logic: ", &ps_tictime}, - {0} - }; - - perfstatrow_t thinker_time_row[] = { - {"plrthnk", "P_PlayerThink: ", &ps_playerthink_time}, - {"thnkers", "P_RunThinkers: ", &ps_thinkertime}, - {0} - }; - - perfstatrow_t detailed_thinker_time_row[] = { - {"plyobjs", "Polyobjects: ", &ps_thlist_times[THINK_POLYOBJ]}, - {"main ", "Main: ", &ps_thlist_times[THINK_MAIN]}, - {"mobjs ", "Mobjs: ", &ps_thlist_times[THINK_MOBJ]}, - {"dynslop", "Dynamic slopes: ", &ps_thlist_times[THINK_DYNSLOPE]}, - {"precip ", "Precipitation: ", &ps_thlist_times[THINK_PRECIP]}, - {0} - }; - - perfstatrow_t extra_thinker_time_row[] = { - {"lthinkf", "LUAh_ThinkFrame:", &ps_lua_thinkframe_time}, - {"other ", "Other: ", &extratime}, - {0} - }; - - perfstatrow_t thinkercount_row[] = { - {"thnkers", "Thinkers: ", &thinkercount}, - {0} - }; - - perfstatrow_t detailed_thinkercount_row[] = { - {"plyobjs", "Polyobjects: ", &polythcount}, - {"main ", "Main: ", &mainthcount}, - {"mobjs ", "Mobjs: ", &mobjcount}, - {0} - }; - - perfstatrow_t mobjthinkercount_row[] = { - {"regular", "Regular: ", ®ularcount}, - {"scenery", "Scenery: ", &scenerycount}, - {0} - }; - - perfstatrow_t nothinkcount_row[] = { - {"nothink", "Nothink: ", ¬hinkcount}, - {0} - }; - - perfstatrow_t detailed_thinkercount_row2[] = { - {"dynslop", "Dynamic slopes: ", &dynslopethcount}, - {"precip ", "Precipitation: ", &precipcount}, - {"remove ", "Pending removal:", &removecount}, - {0} - }; - - perfstatrow_t misc_calls_row[] = { - {"lmhook", "Lua mobj hooks: ", &ps_lua_mobjhooks}, - {"chkpos", "P_CheckPosition:", &ps_checkposition_calls}, - {0} - }; - - perfstatcol_t tictime_col = {20, 20, V_YELLOWMAP, tictime_row}; - perfstatcol_t thinker_time_col = {24, 24, V_YELLOWMAP, thinker_time_row}; - perfstatcol_t detailed_thinker_time_col = {28, 28, V_YELLOWMAP, detailed_thinker_time_row}; - perfstatcol_t extra_thinker_time_col = {24, 24, V_YELLOWMAP, extra_thinker_time_row}; - - perfstatcol_t thinkercount_col = {90, 115, V_BLUEMAP, thinkercount_row}; - perfstatcol_t detailed_thinkercount_col = {94, 119, V_BLUEMAP, detailed_thinkercount_row}; - perfstatcol_t mobjthinkercount_col = {98, 123, V_BLUEMAP, mobjthinkercount_row}; - perfstatcol_t nothinkcount_col = {98, 123, V_BLUEMAP, nothinkcount_row}; - perfstatcol_t detailed_thinkercount_col2 = {94, 119, V_BLUEMAP, detailed_thinkercount_row2}; - perfstatcol_t misc_calls_col = {170, 216, V_PURPLEMAP, misc_calls_row}; + ps_thinkercount.value.i = 0; + ps_polythcount.value.i = 0; + ps_mainthcount.value.i = 0; + ps_mobjcount.value.i = 0; + ps_regularcount.value.i = 0; + ps_scenerycount.value.i = 0; + ps_nothinkcount.value.i = 0; + ps_dynslopethcount.value.i = 0; + ps_precipcount.value.i = 0; + ps_removecount.value.i = 0; for (i = 0; i < NUM_THINKERLISTS; i++) { for (thinker = thlist[i].next; thinker != &thlist[i]; thinker = thinker->next) { - thinkercount++; + ps_thinkercount.value.i++; if (thinker->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) - removecount++; + ps_removecount.value.i++; else if (i == THINK_POLYOBJ) - polythcount++; + ps_polythcount.value.i++; else if (i == THINK_MAIN) - mainthcount++; + ps_mainthcount.value.i++; else if (i == THINK_MOBJ) { if (thinker->function.acp1 == (actionf_p1)P_MobjThinker) { mobj_t *mobj = (mobj_t*)thinker; - mobjcount++; + ps_mobjcount.value.i++; if (mobj->flags & MF_NOTHINK) - nothinkcount++; + ps_nothinkcount.value.i++; else if (mobj->flags & MF_SCENERY) - scenerycount++; + ps_scenerycount.value.i++; else - regularcount++; + ps_regularcount.value.i++; } } else if (i == THINK_DYNSLOPE) - dynslopethcount++; + ps_dynslopethcount.value.i++; else if (i == THINK_PRECIP) - precipcount++; + ps_precipcount.value.i++; } } +} - draw_row = 10; - M_DrawPerfTiming(&tictime_col); - M_DrawPerfTiming(&thinker_time_col); - M_DrawPerfTiming(&detailed_thinker_time_col); - M_DrawPerfTiming(&extra_thinker_time_col); - - draw_row = 10; - M_DrawPerfCount(&thinkercount_col); - M_DrawPerfCount(&detailed_thinkercount_col); - M_DrawPerfCount(&mobjthinkercount_col); - - if (nothinkcount) - M_DrawPerfCount(¬hinkcount_col); - - M_DrawPerfCount(&detailed_thinkercount_col2); - - if (M_HighResolution()) +// Update all metrics that are calculated on every tick. +void PS_UpdateTickStats(void) +{ + if (cv_perfstats.value == 1 && cv_ps_samplesize.value > 1) { + PS_UpdateRowHistories(gamelogicbrief_row, false); + } + if (cv_perfstats.value == 2) + { + if (PS_IsLevelActive()) + { + ps_otherlogictime.value.p = + ps_tictime.value.p - + ps_playerthink_time.value.p - + ps_thinkertime.value.p - + ps_lua_thinkframe_time.value.p; + + PS_CountThinkers(); + } + + if (cv_ps_samplesize.value > 1) + { + PS_UpdateRowHistories(gamelogic_rows, false); + PS_UpdateRowHistories(thinkercount_rows, false); + PS_UpdateRowHistories(misc_calls_rows, false); + } + } + if (cv_perfstats.value == 3 && cv_ps_samplesize.value > 1 && PS_IsLevelActive()) + { + int i; + for (i = 0; i < thinkframe_hooks_length; i++) + { + PS_UpdateMetricHistory(&thinkframe_hooks[i].time_taken, true, false, false); + } + } + if (cv_perfstats.value && cv_ps_samplesize.value > 1) + { + ps_tick_index++; + if (ps_tick_index >= cv_ps_samplesize.value) + ps_tick_index = 0; + if (ps_tick_samples_left) + ps_tick_samples_left--; + } +} + +static void PS_DrawDescriptorHeader(void) +{ + if (cv_ps_samplesize.value > 1) + { + const char* descriptor_names[] = { + "average", + "standard deviation", + "minimum", + "maximum" + }; + const boolean hires = PS_HighResolution(); + char* str; + INT32 flags = V_MONOSPACE | V_ALLOWLOWERCASE; + int samples_left = max(ps_frame_samples_left, ps_tick_samples_left); + int x, y; + + if (cv_perfstats.value == 3) + { + x = 2; + y = 0; + } + else + { + x = 20; + y = hires ? 5 : 2; + } + + if (samples_left) + { + str = va("Samples needed for correct results: %d", samples_left); + flags |= V_REDMAP; + } + else + { + str = va("Showing the %s of %d samples.", + descriptor_names[cv_ps_descriptor.value - 1], cv_ps_samplesize.value); + flags |= V_GREENMAP; + } + + if (hires) + V_DrawSmallString(x, y, flags, str); + else + V_DrawThinString(x, y, flags, str); + } +} + +static void PS_DrawRenderStats(void) +{ + const boolean hires = PS_HighResolution(); + const int half_row = hires ? 5 : 4; + int x, y; + + PS_DrawDescriptorHeader(); + + y = PS_DrawPerfRows(20, 10, V_YELLOWMAP, rendertime_rows); + + PS_DrawPerfRows(20, y + half_row, V_GRAYMAP, gamelogicbrief_row); + + if (PS_IsLevelActive()) + { + x = hires ? 115 : 90; + PS_DrawPerfRows(x, 10, V_BLUEMAP, commoncounter_rows); + +#ifdef HWRENDER + if (rendermode == render_opengl && cv_glbatching.value) + { + x = hires ? 200 : 155; + y = PS_DrawPerfRows(x, 10, V_PURPLEMAP, batchcount_rows); + + x = hires ? 200 : 220; + y = hires ? y + half_row : 10; + PS_DrawPerfRows(x, y, V_PURPLEMAP, batchcalls_rows); + } +#endif + } +} + +static void PS_DrawGameLogicStats(void) +{ + const boolean hires = PS_HighResolution(); + int x, y; + + PS_DrawDescriptorHeader(); + + PS_DrawPerfRows(20, 10, V_YELLOWMAP, gamelogic_rows); + + x = hires ? 115 : 90; + PS_DrawPerfRows(x, 10, V_BLUEMAP, thinkercount_rows); + + if (hires) V_DrawSmallString(212, 10, V_MONOSPACE | V_ALLOWLOWERCASE | V_PURPLEMAP, "Calls:"); - draw_row = 15; - } - else - { - draw_row = 10; - } + x = hires ? 216 : 170; + y = hires ? 15 : 10; + PS_DrawPerfRows(x, y, V_PURPLEMAP, misc_calls_rows); +} - M_DrawPerfCount(&misc_calls_col); +static void PS_DrawThinkFrameStats(void) +{ + char s[100]; + int i; + // text writing position + int x = 2; + int y = 4; + UINT32 text_color; + char tempbuffer[LUA_IDSIZE]; + char last_mod_name[LUA_IDSIZE]; + last_mod_name[0] = '\0'; + + PS_DrawDescriptorHeader(); + + for (i = 0; i < thinkframe_hooks_length; i++) + { + +#define NEXT_ROW() \ +y += 4; \ +if (y > 192) \ +{ \ + y = 4; \ + x += 106; \ + if (x > 214) \ + break; \ +} + + char* str = thinkframe_hooks[i].short_src; + char* tempstr = tempbuffer; + int len = (int)strlen(str); + char* str_ptr; + if (strcmp(".lua", str + len - 4) == 0) + { + str[len-4] = '\0'; // remove .lua at end + len -= 4; + } + // we locate the wad/pk3 name in the string and compare it to + // what we found on the previous iteration. + // if the name has changed, print it out on the screen + strcpy(tempstr, str); + str_ptr = strrchr(tempstr, '|'); + if (str_ptr) + { + *str_ptr = '\0'; + str = str_ptr + 1; // this is the name of the hook without the mod file name + str_ptr = strrchr(tempstr, PATHSEP[0]); + if (str_ptr) + tempstr = str_ptr + 1; + // tempstr should now point to the mod name, (wad/pk3) possibly truncated + if (strcmp(tempstr, last_mod_name) != 0) + { + strcpy(last_mod_name, tempstr); + len = (int)strlen(tempstr); + if (len > 25) + tempstr += len - 25; + snprintf(s, sizeof s - 1, "%s", tempstr); + V_DrawSmallString(x, y, V_MONOSPACE | V_ALLOWLOWERCASE | V_GRAYMAP, s); + NEXT_ROW() + } + text_color = V_YELLOWMAP; + } + else + { + // probably a standalone lua file + // cut off the folder if it's there + str_ptr = strrchr(tempstr, PATHSEP[0]); + if (str_ptr) + str = str_ptr + 1; + text_color = 0; // white + } + len = (int)strlen(str); + if (len > 20) + str += len - 20; + snprintf(s, sizeof s - 1, "%20s: %d", str, + PS_GetMetricScreenValue(&thinkframe_hooks[i].time_taken, true)); + V_DrawSmallString(x, y, V_MONOSPACE | V_ALLOWLOWERCASE | text_color, s); + NEXT_ROW() + +#undef NEXT_ROW + + } } void M_DrawPerfStats(void) { - char s[100]; - - PS_SetFrameTime(); - if (cv_perfstats.value == 1) // rendering { - M_DrawRenderStats(); + PS_UpdateFrameStats(); + PS_DrawRenderStats(); } else if (cv_perfstats.value == 2) // logic { - M_DrawTickStats(); + // PS_UpdateTickStats is called in TryRunTics, since otherwise it would miss + // tics when frame skips happen + PS_DrawGameLogicStats(); } else if (cv_perfstats.value == 3) // lua thinkframe { - if (!(gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction))) + if (!PS_IsLevelActive()) return; - if (vid.width < 640 || vid.height < 400) // low resolution + if (!PS_HighResolution()) { - // it's not gonna fit very well.. - V_DrawThinString(30, 30, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, "Not available for resolutions below 640x400"); + // Low resolutions can't really use V_DrawSmallString that is used by thinkframe stats. + // A low-res version using V_DrawThinString could be implemented, + // but it would have much less space for information. + V_DrawThinString(80, 92, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, "Perfstats 3 is not available"); + V_DrawThinString(80, 100, V_MONOSPACE | V_ALLOWLOWERCASE | V_YELLOWMAP, "for resolutions below 640x400."); } - else // high resolution + else { - int i; - // text writing position - int x = 2; - int y = 4; - UINT32 text_color; - char tempbuffer[LUA_IDSIZE]; - char last_mod_name[LUA_IDSIZE]; - last_mod_name[0] = '\0'; - for (i = 0; i < thinkframe_hooks_length; i++) - { - char* str = thinkframe_hooks[i].short_src; - char* tempstr = tempbuffer; - int len = (int)strlen(str); - char* str_ptr; - if (strcmp(".lua", str + len - 4) == 0) - { - str[len-4] = '\0'; // remove .lua at end - len -= 4; - } - // we locate the wad/pk3 name in the string and compare it to - // what we found on the previous iteration. - // if the name has changed, print it out on the screen - strcpy(tempstr, str); - str_ptr = strrchr(tempstr, '|'); - if (str_ptr) - { - *str_ptr = '\0'; - str = str_ptr + 1; // this is the name of the hook without the mod file name - str_ptr = strrchr(tempstr, PATHSEP[0]); - if (str_ptr) - tempstr = str_ptr + 1; - // tempstr should now point to the mod name, (wad/pk3) possibly truncated - if (strcmp(tempstr, last_mod_name) != 0) - { - strcpy(last_mod_name, tempstr); - len = (int)strlen(tempstr); - if (len > 25) - tempstr += len - 25; - snprintf(s, sizeof s - 1, "%s", tempstr); - V_DrawSmallString(x, y, V_MONOSPACE | V_ALLOWLOWERCASE | V_GRAYMAP, s); - y += 4; // repeated code! - if (y > 192) - { - y = 4; - x += 106; - if (x > 214) - break; - } - } - text_color = V_YELLOWMAP; - } - else - { - // probably a standalone lua file - // cut off the folder if it's there - str_ptr = strrchr(tempstr, PATHSEP[0]); - if (str_ptr) - str = str_ptr + 1; - text_color = 0; // white - } - len = (int)strlen(str); - if (len > 20) - str += len - 20; - snprintf(s, sizeof s - 1, "%20s: %d", str, I_PreciseToMicros(thinkframe_hooks[i].time_taken)); - V_DrawSmallString(x, y, V_MONOSPACE | V_ALLOWLOWERCASE | text_color, s); - y += 4; // repeated code! - if (y > 192) - { - y = 4; - x += 106; - if (x > 214) - break; - } - } + PS_DrawThinkFrameStats(); } } } + +// remove and unallocate history from all metrics +static void PS_ClearHistory(void) +{ + int i; + + Z_FreeTag(PU_PERFSTATS); + // thinkframe hook metric history pointers need to be cleared manually + for (i = 0; i < thinkframe_hooks_length; i++) + { + thinkframe_hooks[i].time_taken.history = NULL; + } + + ps_frame_index = ps_tick_index = 0; + // PS_UpdateMetricHistory will set these correctly when it runs + ps_frame_samples_left = ps_tick_samples_left = 0; +} + +void PS_PerfStats_OnChange(void) +{ + if (cv_perfstats.value && cv_ps_samplesize.value > 1) + PS_ClearHistory(); +} + +void PS_SampleSize_OnChange(void) +{ + if (cv_ps_samplesize.value > 1) + PS_ClearHistory(); +} diff --git a/src/m_perfstats.h b/src/m_perfstats.h index 71208fbc1..3ff0e6c6b 100644 --- a/src/m_perfstats.h +++ b/src/m_perfstats.h @@ -16,26 +16,45 @@ #include "lua_script.h" #include "p_local.h" -extern precise_t ps_tictime; - -extern precise_t ps_playerthink_time; -extern precise_t ps_thinkertime; - -extern precise_t ps_thlist_times[]; - -extern int ps_checkposition_calls; - -extern precise_t ps_lua_thinkframe_time; -extern int ps_lua_mobjhooks; +typedef struct +{ + union { + precise_t p; + INT32 i; + } value; + void *history; +} ps_metric_t; typedef struct { - precise_t time_taken; + ps_metric_t time_taken; char short_src[LUA_IDSIZE]; } ps_hookinfo_t; +#define PS_START_TIMING(metric) metric.value.p = I_GetPreciseTime() +#define PS_STOP_TIMING(metric) metric.value.p = I_GetPreciseTime() - metric.value.p + +extern ps_metric_t ps_tictime; + +extern ps_metric_t ps_playerthink_time; +extern ps_metric_t ps_thinkertime; + +extern ps_metric_t ps_thlist_times[]; + +extern ps_metric_t ps_checkposition_calls; + +extern ps_metric_t ps_lua_thinkframe_time; +extern ps_metric_t ps_lua_mobjhooks; + +extern ps_metric_t ps_otherlogictime; + void PS_SetThinkFrameHookInfo(int index, precise_t time_taken, char* short_src); +void PS_UpdateTickStats(void); + void M_DrawPerfStats(void); +void PS_PerfStats_OnChange(void); +void PS_SampleSize_OnChange(void); + #endif diff --git a/src/p_map.c b/src/p_map.c index e55bebb9a..1d3197fab 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -2029,7 +2029,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) subsector_t *newsubsec; boolean blockval = true; - ps_checkposition_calls++; + ps_checkposition_calls.value.i++; I_Assert(thing != NULL); #ifdef PARANOIA diff --git a/src/p_tick.c b/src/p_tick.c index d7357eb82..1cdea9ac6 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -323,7 +323,7 @@ static inline void P_RunThinkers(void) size_t i; for (i = 0; i < NUM_THINKERLISTS; i++) { - ps_thlist_times[i] = I_GetPreciseTime(); + PS_START_TIMING(ps_thlist_times[i]); for (currentthinker = thlist[i].next; currentthinker != &thlist[i]; currentthinker = currentthinker->next) { #ifdef PARANOIA @@ -331,7 +331,7 @@ static inline void P_RunThinkers(void) #endif currentthinker->function.acp1(currentthinker); } - ps_thlist_times[i] = I_GetPreciseTime() - ps_thlist_times[i]; + PS_STOP_TIMING(ps_thlist_times[i]); } } @@ -653,16 +653,16 @@ void P_Ticker(boolean run) } } - ps_lua_mobjhooks = 0; - ps_checkposition_calls = 0; + ps_lua_mobjhooks.value.i = 0; + ps_checkposition_calls.value.i = 0; LUA_HOOK(PreThinkFrame); - ps_playerthink_time = I_GetPreciseTime(); + PS_START_TIMING(ps_playerthink_time); for (i = 0; i < MAXPLAYERS; i++) if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo)) P_PlayerThink(&players[i]); - ps_playerthink_time = I_GetPreciseTime() - ps_playerthink_time; + PS_STOP_TIMING(ps_playerthink_time); } // Keep track of how long they've been playing! @@ -677,18 +677,18 @@ void P_Ticker(boolean run) if (run) { - ps_thinkertime = I_GetPreciseTime(); + PS_START_TIMING(ps_thinkertime); P_RunThinkers(); - ps_thinkertime = I_GetPreciseTime() - ps_thinkertime; + PS_STOP_TIMING(ps_thinkertime); // Run any "after all the other thinkers" stuff for (i = 0; i < MAXPLAYERS; i++) if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo)) P_PlayerAfterThink(&players[i]); - ps_lua_thinkframe_time = I_GetPreciseTime(); + PS_START_TIMING(ps_lua_thinkframe_time); LUA_HookThinkFrame(); - ps_lua_thinkframe_time = I_GetPreciseTime() - ps_lua_thinkframe_time; + PS_STOP_TIMING(ps_lua_thinkframe_time); } // Run shield positioning diff --git a/src/r_bsp.c b/src/r_bsp.c index 5acd4e70c..b8559d39e 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -804,7 +804,7 @@ static void R_AddPolyObjects(subsector_t *sub) } // for render stats - ps_numpolyobjects += numpolys; + ps_numpolyobjects.value.i += numpolys; // sort polyobjects R_SortPolyObjects(sub); @@ -1239,7 +1239,7 @@ void R_RenderBSPNode(INT32 bspnum) node_t *bsp; INT32 side; - ps_numbspcalls++; + ps_numbspcalls.value.i++; while (!(bspnum & NF_SUBSECTOR)) // Found a subsector? { diff --git a/src/r_main.c b/src/r_main.c index 17e124cb9..8729b5dcb 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -101,21 +101,22 @@ extracolormap_t *extra_colormaps = NULL; // Render stats precise_t ps_prevframetime = 0; -precise_t ps_rendercalltime = 0; -precise_t ps_uitime = 0; -precise_t ps_swaptime = 0; +ps_metric_t ps_rendercalltime = {0}; +ps_metric_t ps_otherrendertime = {0}; +ps_metric_t ps_uitime = {0}; +ps_metric_t ps_swaptime = {0}; -precise_t ps_bsptime = 0; +ps_metric_t ps_bsptime = {0}; -precise_t ps_sw_spritecliptime = 0; -precise_t ps_sw_portaltime = 0; -precise_t ps_sw_planetime = 0; -precise_t ps_sw_maskedtime = 0; +ps_metric_t ps_sw_spritecliptime = {0}; +ps_metric_t ps_sw_portaltime = {0}; +ps_metric_t ps_sw_planetime = {0}; +ps_metric_t ps_sw_maskedtime = {0}; -int ps_numbspcalls = 0; -int ps_numsprites = 0; -int ps_numdrawnodes = 0; -int ps_numpolyobjects = 0; +ps_metric_t ps_numbspcalls = {0}; +ps_metric_t ps_numsprites = {0}; +ps_metric_t ps_numdrawnodes = {0}; +ps_metric_t ps_numpolyobjects = {0}; static CV_PossibleValue_t drawdist_cons_t[] = { {256, "256"}, {512, "512"}, {768, "768"}, @@ -1496,11 +1497,11 @@ void R_RenderPlayerView(player_t *player) mytotal = 0; ProfZeroTimer(); #endif - ps_numbspcalls = ps_numpolyobjects = ps_numdrawnodes = 0; - ps_bsptime = I_GetPreciseTime(); + ps_numbspcalls.value.i = ps_numpolyobjects.value.i = ps_numdrawnodes.value.i = 0; + PS_START_TIMING(ps_bsptime); R_RenderBSPNode((INT32)numnodes - 1); - ps_bsptime = I_GetPreciseTime() - ps_bsptime; - ps_numsprites = visspritecount; + PS_STOP_TIMING(ps_bsptime); + ps_numsprites.value.i = visspritecount; #ifdef TIMING RDMSR(0x10, &mycount); mytotal += mycount; // 64bit add @@ -1510,9 +1511,9 @@ void R_RenderPlayerView(player_t *player) //profile stuff --------------------------------------------------------- Mask_Post(&masks[nummasks - 1]); - ps_sw_spritecliptime = I_GetPreciseTime(); + PS_START_TIMING(ps_sw_spritecliptime); R_ClipSprites(drawsegs, NULL); - ps_sw_spritecliptime = I_GetPreciseTime() - ps_sw_spritecliptime; + PS_STOP_TIMING(ps_sw_spritecliptime); // Add skybox portals caused by sky visplanes. @@ -1520,7 +1521,7 @@ void R_RenderPlayerView(player_t *player) Portal_AddSkyboxPortals(); // Portal rendering. Hijacks the BSP traversal. - ps_sw_portaltime = I_GetPreciseTime(); + PS_START_TIMING(ps_sw_portaltime); if (portal_base) { portal_t *portal; @@ -1560,17 +1561,17 @@ void R_RenderPlayerView(player_t *player) Portal_Remove(portal); } } - ps_sw_portaltime = I_GetPreciseTime() - ps_sw_portaltime; + PS_STOP_TIMING(ps_sw_portaltime); - ps_sw_planetime = I_GetPreciseTime(); + PS_START_TIMING(ps_sw_planetime); R_DrawPlanes(); - ps_sw_planetime = I_GetPreciseTime() - ps_sw_planetime; + PS_STOP_TIMING(ps_sw_planetime); // draw mid texture and sprite // And now 3D floors/sides! - ps_sw_maskedtime = I_GetPreciseTime(); + PS_START_TIMING(ps_sw_maskedtime); R_DrawMasked(masks, nummasks); - ps_sw_maskedtime = I_GetPreciseTime() - ps_sw_maskedtime; + PS_STOP_TIMING(ps_sw_maskedtime); free(masks); } diff --git a/src/r_main.h b/src/r_main.h index f81447c45..5f3bed980 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -17,6 +17,7 @@ #include "d_player.h" #include "r_data.h" #include "r_textures.h" +#include "m_perfstats.h" // ps_metric_t // // POV related. @@ -79,21 +80,22 @@ boolean R_DoCulling(line_t *cullheight, line_t *viewcullheight, fixed_t vz, fixe // Render stats extern precise_t ps_prevframetime;// time when previous frame was rendered -extern precise_t ps_rendercalltime; -extern precise_t ps_uitime; -extern precise_t ps_swaptime; +extern ps_metric_t ps_rendercalltime; +extern ps_metric_t ps_otherrendertime; +extern ps_metric_t ps_uitime; +extern ps_metric_t ps_swaptime; -extern precise_t ps_bsptime; +extern ps_metric_t ps_bsptime; -extern precise_t ps_sw_spritecliptime; -extern precise_t ps_sw_portaltime; -extern precise_t ps_sw_planetime; -extern precise_t ps_sw_maskedtime; +extern ps_metric_t ps_sw_spritecliptime; +extern ps_metric_t ps_sw_portaltime; +extern ps_metric_t ps_sw_planetime; +extern ps_metric_t ps_sw_maskedtime; -extern int ps_numbspcalls; -extern int ps_numsprites; -extern int ps_numdrawnodes; -extern int ps_numpolyobjects; +extern ps_metric_t ps_numbspcalls; +extern ps_metric_t ps_numsprites; +extern ps_metric_t ps_numdrawnodes; +extern ps_metric_t ps_numpolyobjects; // // REFRESH - the actual rendering functions. diff --git a/src/r_things.c b/src/r_things.c index ea57e4086..bed71a6d7 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2745,7 +2745,7 @@ static drawnode_t *R_CreateDrawNode(drawnode_t *link) node->ffloor = NULL; node->sprite = NULL; - ps_numdrawnodes++; + ps_numdrawnodes.value.i++; return node; } diff --git a/src/z_zone.h b/src/z_zone.h index be55bf994..17f572a90 100644 --- a/src/z_zone.h +++ b/src/z_zone.h @@ -39,6 +39,7 @@ enum // Tags < PU_LEVEL are not purged until freed explicitly. PU_STATIC = 1, // static entire execution time PU_LUA = 2, // static entire execution time -- used by lua so it doesn't get caught in loops forever + PU_PERFSTATS = 3, // static between changes to ps_samplesize cvar PU_SOUND = 11, // static while playing PU_MUSIC = 12, // static while playing From 865c0a081da3292f9923216f0b31a3128b462c81 Mon Sep 17 00:00:00 2001 From: SMS Alfredo Date: Fri, 29 Oct 2021 10:40:25 +0000 Subject: [PATCH 615/644] Make Overlay objects account for player->drawangle --- src/p_enemy.c | 2 +- src/p_mobj.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 49907bdcc..0cada7f9f 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -5297,7 +5297,7 @@ void A_OverlayThink(mobj_t *actor) actor->z = actor->target->z + actor->target->height - mobjinfo[actor->type].height - ((var2>>16) ? -1 : 1)*(var2&0xFFFF)*FRACUNIT; else actor->z = actor->target->z + ((var2>>16) ? -1 : 1)*(var2&0xFFFF)*FRACUNIT; - actor->angle = actor->target->angle + actor->movedir; + actor->angle = (actor->target->player ? actor->target->player->drawangle : actor->target->angle) + actor->movedir; actor->eflags = actor->target->eflags; actor->momx = actor->target->momx; diff --git a/src/p_mobj.c b/src/p_mobj.c index a1bb2d6ff..41377373d 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6837,7 +6837,7 @@ void P_RunOverlays(void) mo->eflags = (mo->eflags & ~MFE_VERTICALFLIP) | (mo->target->eflags & MFE_VERTICALFLIP); mo->scale = mo->destscale = mo->target->scale; - mo->angle = mo->target->angle + mo->movedir; + mo->angle = (mo->target->player ? mo->target->player->drawangle : mo->target->angle) + mo->movedir; if (!(mo->state->frame & FF_ANIMATE)) zoffs = FixedMul(((signed)mo->state->var2)*FRACUNIT, mo->scale); From c55e973364ab990afbd29f081c94aad245a13809 Mon Sep 17 00:00:00 2001 From: SteelT Date: Wed, 3 Nov 2021 17:13:34 -0400 Subject: [PATCH 616/644] MSYS2: Don't compile with dynamic base Resolves #671 --- src/Makefile.d/win32.mk | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Makefile.d/win32.mk b/src/Makefile.d/win32.mk index 0c671b268..768133c15 100644 --- a/src/Makefile.d/win32.mk +++ b/src/Makefile.d/win32.mk @@ -8,6 +8,11 @@ else EXENAME?=srb2win64.exe endif +# disable dynamicbase if under msys2 +ifdef MSYSTEM +libs+=-Wl,--disable-dynamicbase +endif + sources+=win32/Srb2win.rc opts+=-DSTDC_HEADERS libs+=-ladvapi32 -lkernel32 -lmsvcrt -luser32 From da33cb674e419eba5b4870c134f8dacab86ffb6f Mon Sep 17 00:00:00 2001 From: katsy Date: Fri, 5 Nov 2021 16:51:44 -0500 Subject: [PATCH 617/644] fix water fof height calculation on slopes --- src/p_mobj.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index a1bb2d6ff..c5a84f333 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -3236,8 +3236,8 @@ void P_MobjCheckWater(mobj_t *mobj) || ((rover->flags & FF_BLOCKOTHERS) && !mobj->player))) continue; - topheight = P_GetFFloorTopZAt (rover, mobj->x, mobj->y); - bottomheight = P_GetFFloorBottomZAt(rover, mobj->x, mobj->y); + topheight = P_GetSpecialTopZ(mobj, sectors + rover->secnum, sector); + bottomheight = P_GetSpecialBottomZ(mobj, sectors + rover->secnum, sector); if (mobj->eflags & MFE_VERTICALFLIP) { From 0ecfc38c468944b4de997199c0ece750cb39750f Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Sat, 6 Nov 2021 01:49:29 -0300 Subject: [PATCH 618/644] Remove misplaced line from R_DrawTiltedSplat_NPO2_8 --- src/r_draw8_npo2.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/r_draw8_npo2.c b/src/r_draw8_npo2.c index 71ec99948..2433cb402 100644 --- a/src/r_draw8_npo2.c +++ b/src/r_draw8_npo2.c @@ -666,7 +666,6 @@ void R_DrawTiltedSplat_NPO2_8(void) for (; width != 0; width--) { colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]; // Lactozilla: Non-powers-of-two { fixed_t x = (((fixed_t)u) >> FRACBITS); From 9a5bb5980107050c1203276a72fcc4f23fd22e60 Mon Sep 17 00:00:00 2001 From: sphere Date: Sun, 7 Nov 2021 12:51:21 +0100 Subject: [PATCH 619/644] https://mb.srb2.org/threads/the-most-utterly-unimportant-typo-ever.27152 --- src/f_finale.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/f_finale.c b/src/f_finale.c index 47786bb60..0b2fe9741 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1219,7 +1219,7 @@ static const char *credits[] = { "Bill \"Tets\" Reed", "", "\1Special Thanks", - "iD Software", + "id Software", "Doom Legacy Project", "FreeDoom Project", // Used some of the mancubus and rocket launcher sprites for Brak "Kart Krew", From 270c7701b4c43faa59b642be5774a0a867a0f1ed Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Mon, 8 Nov 2021 01:17:30 +0200 Subject: [PATCH 620/644] Timestamp function for Lua --- src/i_system.h | 2 +- src/lua_baselib.c | 9 +++++++++ src/sdl/i_system.c | 8 +++++++- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/i_system.h b/src/i_system.h index a3790dca3..a2dd81cca 100644 --- a/src/i_system.h +++ b/src/i_system.h @@ -50,7 +50,7 @@ tic_t I_GetTime(void); */ precise_t I_GetPreciseTime(void); -/** \brief Returns the difference between precise times as microseconds. +/** \brief Converts a precise_t to microseconds and casts it to a 32 bit integer. */ int I_PreciseToMicros(precise_t); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 350c1585f..61f0e43cb 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -31,6 +31,7 @@ #include "m_misc.h" // M_MapNumber #include "b_bot.h" // B_UpdateBotleader #include "d_clisrv.h" // CL_RemovePlayer +#include "i_system.h" // I_GetPreciseTime, I_PreciseToMicros #include "lua_script.h" #include "lua_libs.h" @@ -3876,6 +3877,12 @@ static int lib_gTicsToMilliseconds(lua_State *L) return 1; } +static int lib_iGetTimestamp(lua_State *L) +{ + lua_pushinteger(L, I_PreciseToMicros(I_GetPreciseTime())); + return 1; +} + static luaL_Reg lib[] = { {"print", lib_print}, {"chatprint", lib_chatprint}, @@ -4150,6 +4157,8 @@ static luaL_Reg lib[] = { {"G_TicsToCentiseconds",lib_gTicsToCentiseconds}, {"G_TicsToMilliseconds",lib_gTicsToMilliseconds}, + {"I_GetTimestamp",lib_iGetTimestamp}, + {NULL, NULL} }; diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 2ec28ebc8..ccec37093 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -2163,7 +2163,13 @@ precise_t I_GetPreciseTime(void) int I_PreciseToMicros(precise_t d) { - return (int)(d / (timer_frequency / 1000000.0)); + // d is going to be converted into a double. So remove the highest bits + // to avoid loss of precision in the lower bits, for the (probably rare) case + // that the higher bits are actually used. + d &= ((precise_t)1 << 53) - 1; // The mantissa of a double can handle 53 bits at most. + // The resulting double from the calculation is converted first to UINT64 to avoid overflow, + // which is undefined behaviour when converting floating point values to integers. + return (int)(UINT64)(d / (timer_frequency / 1000000.0)); } // From a14c008dee4e4841e5eb78df57429e59136027b7 Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Mon, 8 Nov 2021 00:38:24 -0300 Subject: [PATCH 621/644] Fix #555 --- src/r_patchrotation.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/r_patchrotation.c b/src/r_patchrotation.c index a9b4a2b8f..dae3a7b53 100644 --- a/src/r_patchrotation.c +++ b/src/r_patchrotation.c @@ -227,8 +227,8 @@ void RotatedPatch_DoRotation(rotsprite_t *rotsprite, patch_t *patch, INT32 angle ox = (newwidth / 2) + (leftoffset - xpivot); oy = (newheight / 2) + (patch->topoffset - ypivot); - width = (maxx - minx); - height = (maxy - miny); + width = (maxx+1 - minx); + height = (maxy+1 - miny); if ((unsigned)(width * height) != size) { From 34b05efdf1fe548763901a49b0e20b80cc25d95c Mon Sep 17 00:00:00 2001 From: LZA <73-LZA@users.noreply.git.do.srb2.org> Date: Mon, 8 Nov 2021 03:40:53 +0000 Subject: [PATCH 622/644] Revert "Merge branch 'writable-colormaps' into 'next'" This reverts merge request !959 --- src/lua_hudlib.c | 33 +++------------------------------ 1 file changed, 3 insertions(+), 30 deletions(-) diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index fca832053..0dd951efd 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -265,7 +265,7 @@ static int hudinfo_num(lua_State *L) static int colormap_get(lua_State *L) { - UINT8 *colormap = *((UINT8 **)luaL_checkudata(L, 1, META_COLORMAP)); + const UINT8 *colormap = *((UINT8 **)luaL_checkudata(L, 1, META_COLORMAP)); UINT32 i = luaL_checkinteger(L, 2); if (i >= 256) return luaL_error(L, "colormap index %d out of range (0 - %d)", i, 255); @@ -273,23 +273,6 @@ static int colormap_get(lua_State *L) return 1; } -static int colormap_set(lua_State *L) -{ - UINT8 *colormap = *((UINT8 **)luaL_checkudata(L, 1, META_COLORMAP)); - UINT32 i = luaL_checkinteger(L, 2); - if (i >= 256) - return luaL_error(L, "colormap index %d out of range (0 - %d)", i, 255); - colormap[i] = (UINT8)luaL_checkinteger(L, 3); - return 0; -} - -static int colormap_free(lua_State *L) -{ - UINT8 *colormap = *((UINT8 **)luaL_checkudata(L, 1, META_COLORMAP)); - Z_Free(colormap); - return 0; -} - static int patch_get(lua_State *L) { patch_t *patch = *((patch_t **)luaL_checkudata(L, 1, META_PATCH)); @@ -1057,7 +1040,7 @@ static int libd_getColormap(lua_State *L) // all was successful above, now we generate the colormap at last! - colormap = R_GetTranslationColormap(skinnum, color, 0); + colormap = R_GetTranslationColormap(skinnum, color, GTC_CACHE); LUA_PushUserdata(L, colormap, META_COLORMAP); // push as META_COLORMAP userdata, specifically for patches to use! return 1; } @@ -1066,14 +1049,10 @@ static int libd_getStringColormap(lua_State *L) { INT32 flags = luaL_checkinteger(L, 1); UINT8* colormap = NULL; - UINT8* lua_colormap = NULL; HUDONLY colormap = V_GetStringColormap(flags & V_CHARCOLORMASK); if (colormap) { - lua_colormap = Z_Malloc(256 * sizeof(UINT8), PU_LUA, NULL); - memcpy(lua_colormap, colormap, 256 * sizeof(UINT8)); - - LUA_PushUserdata(L, lua_colormap, META_COLORMAP); // push as META_COLORMAP userdata, specifically for patches to use! + LUA_PushUserdata(L, colormap, META_COLORMAP); // push as META_COLORMAP userdata, specifically for patches to use! return 1; } return 0; @@ -1348,12 +1327,6 @@ int LUA_HudLib(lua_State *L) luaL_newmetatable(L, META_COLORMAP); lua_pushcfunction(L, colormap_get); lua_setfield(L, -2, "__index"); - - lua_pushcfunction(L, colormap_set); - lua_setfield(L, -2, "__newindex"); - - lua_pushcfunction(L, colormap_free); - lua_setfield(L, -2, "__gc"); lua_pop(L,1); luaL_newmetatable(L, META_PATCH); From 32a68f35c95d46f6bb2090d309a400814754476f Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Mon, 8 Nov 2021 01:11:51 -0300 Subject: [PATCH 623/644] Change my name --- src/f_finale.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/f_finale.c b/src/f_finale.c index 0b2fe9741..8dd03d44f 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1091,11 +1091,11 @@ static const char *credits[] = { "Kepa \"Nev3r\" Iceta", "Thomas \"Shadow Hog\" Igoe", "Iestyn \"Monster Iestyn\" Jealous", - "\"Jimita\"", "\"Kaito Sinclaire\"", "\"Kalaron\"", // Coded some of Sryder13's collection of OpenGL fixes, especially fog "Ronald \"Furyhunter\" Kinard", // The SDL2 port "\"Lat'\"", // SRB2-CHAT, the chat window from Kart + "\"LZA\"", "Matthew \"Shuffle\" Marsalko", "Steven \"StroggOnMeth\" McGranahan", "\"Morph\"", // For SRB2Morphed stuff From 1d7061b8921e348502a8b8569a0361a97a8fc76d Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Mon, 8 Nov 2021 01:34:03 -0300 Subject: [PATCH 624/644] Fix NONET compiling --- src/d_clisrv.c | 74 ++++++++++++++++++++++++++++---------------------- 1 file changed, 42 insertions(+), 32 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index b7071320c..efe6473d4 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1836,8 +1836,6 @@ void CL_UpdateServerList(boolean internetsearch, INT32 room) #endif/*MASTERSERVER*/ } -#endif // ifndef NONET - static const char * InvalidServerReason (INT32 i) { #define EOT "\nPress ESC\n" @@ -1904,6 +1902,8 @@ static const char * InvalidServerReason (INT32 i) #undef EOT } +#endif // ifndef NONET + /** Called by CL_ServerConnectionTicker * * \param asksent The last time we asked the server to join. We re-ask every second in case our request got lost in transmit. @@ -2932,6 +2932,34 @@ static void Command_Kick(void) else CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n")); } + +static void Command_ResendGamestate(void) +{ + SINT8 playernum; + + if (COM_Argc() == 1) + { + CONS_Printf(M_GetText("resendgamestate : resend the game state to a player\n")); + return; + } + else if (client) + { + CONS_Printf(M_GetText("Only the server can use this.\n")); + return; + } + + playernum = nametonum(COM_Argv(1)); + if (playernum == -1 || playernum == 0) + return; + + // Send a PT_WILLRESENDGAMESTATE packet to the client so they know what's going on + netbuffer->packettype = PT_WILLRESENDGAMESTATE; + if (!HSendPacket(playernode[playernum], true, 0, 0)) + { + CONS_Alert(CONS_ERROR, M_GetText("A problem occured, please try again.\n")); + return; + } +} #endif static void Got_KickCmd(UINT8 **p, INT32 playernum) @@ -3139,34 +3167,6 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum) CL_RemovePlayer(pnum, kickreason); } -static void Command_ResendGamestate(void) -{ - SINT8 playernum; - - if (COM_Argc() == 1) - { - CONS_Printf(M_GetText("resendgamestate : resend the game state to a player\n")); - return; - } - else if (client) - { - CONS_Printf(M_GetText("Only the server can use this.\n")); - return; - } - - playernum = nametonum(COM_Argv(1)); - if (playernum == -1 || playernum == 0) - return; - - // Send a PT_WILLRESENDGAMESTATE packet to the client so they know what's going on - netbuffer->packettype = PT_WILLRESENDGAMESTATE; - if (!HSendPacket(playernode[playernum], true, 0, 0)) - { - CONS_Alert(CONS_ERROR, M_GetText("A problem occured, please try again.\n")); - return; - } -} - static CV_PossibleValue_t netticbuffer_cons_t[] = {{0, "MIN"}, {3, "MAX"}, {0, NULL}}; consvar_t cv_netticbuffer = CVAR_INIT ("netticbuffer", "1", CV_SAVE, netticbuffer_cons_t, NULL); @@ -3903,6 +3903,7 @@ static void HandleServerInfo(SINT8 node) static void PT_WillResendGamestate(void) { +#ifndef NONET char tmpsave[256]; if (server || cl_redownloadinggamestate) @@ -3925,10 +3926,12 @@ static void PT_WillResendGamestate(void) CL_PrepareDownloadSaveGame(tmpsave); cl_redownloadinggamestate = true; +#endif } static void PT_CanReceiveGamestate(SINT8 node) { +#ifndef NONET if (client || sendingsavegame[node]) return; @@ -3936,6 +3939,9 @@ static void PT_CanReceiveGamestate(SINT8 node) SV_SendSaveGame(node, true); // Resend a complete game state resendingsavegame[node] = true; +#else + (void)node; +#endif } /** Handles a packet received from a node that isn't in game @@ -4222,8 +4228,10 @@ static void HandlePacketFromPlayer(SINT8 node) // Check player consistancy during the level if (realstart <= gametic && realstart + BACKUPTICS - 1 > gametic && gamestate == GS_LEVEL && consistancy[realstart%BACKUPTICS] != SHORT(netbuffer->u.clientpak.consistancy) - && !resendingsavegame[node] && savegameresendcooldown[node] <= I_GetTime() - && !SV_ResendingSavegameToAnyone()) +#ifndef NONET + && !SV_ResendingSavegameToAnyone() +#endif + && !resendingsavegame[node] && savegameresendcooldown[node] <= I_GetTime()) { if (cv_resynchattempts.value) { @@ -5127,9 +5135,11 @@ void NetUpdate(void) if (client) { +#ifndef NONET // If the client just finished redownloading the game state, load it if (cl_redownloadinggamestate && fileneeded[0].status == FS_FOUND) CL_ReloadReceivedSavegame(); +#endif CL_SendClientCmd(); // Send tic cmd hu_redownloadinggamestate = cl_redownloadinggamestate; From 56c5a887c858aaf9e1def23327e56d09c546f333 Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Mon, 8 Nov 2021 20:28:35 +0200 Subject: [PATCH 625/644] Call the Lua timestamp function getTimeMicros --- src/lua_baselib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 61f0e43cb..29de7a05f 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -3877,7 +3877,7 @@ static int lib_gTicsToMilliseconds(lua_State *L) return 1; } -static int lib_iGetTimestamp(lua_State *L) +static int lib_getTimeMicros(lua_State *L) { lua_pushinteger(L, I_PreciseToMicros(I_GetPreciseTime())); return 1; @@ -4157,7 +4157,7 @@ static luaL_Reg lib[] = { {"G_TicsToCentiseconds",lib_gTicsToCentiseconds}, {"G_TicsToMilliseconds",lib_gTicsToMilliseconds}, - {"I_GetTimestamp",lib_iGetTimestamp}, + {"getTimeMicros",lib_getTimeMicros}, {NULL, NULL} }; From cade6f3cf69cb3e4f3cbf7e4952706b317e7ea88 Mon Sep 17 00:00:00 2001 From: Zwip-Zwap Zapony Date: Tue, 9 Nov 2021 16:59:49 +0100 Subject: [PATCH 626/644] Fix Ringslinger weapon ring penalty missplitment --- src/st_stuff.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/st_stuff.c b/src/st_stuff.c index 784666ad4..a1b9206b0 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2188,7 +2188,7 @@ static void ST_drawMatchHUD(void) { sprintf(penaltystr, "-%d", stplyr->ammoremoval); V_DrawString(offset + 8 + stplyr->ammoremovalweapon * 20, y, - V_REDMAP|V_SNAPTOBOTTOM, penaltystr); + V_REDMAP|V_SNAPTOBOTTOM|V_PERPLAYER, penaltystr); } } From 8136f5522b83d7328b20def28433ee274bd913cb Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Wed, 10 Nov 2021 01:55:31 +0200 Subject: [PATCH 627/644] Fix uninitialized history pointers in thinkframe_hooks array --- src/m_perfstats.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/m_perfstats.c b/src/m_perfstats.c index 9285b31be..439a9da1c 100644 --- a/src/m_perfstats.c +++ b/src/m_perfstats.c @@ -194,14 +194,18 @@ void PS_SetThinkFrameHookInfo(int index, precise_t time_taken, char* short_src) if (!thinkframe_hooks) { // array needs to be initialized - thinkframe_hooks = Z_Malloc(sizeof(ps_hookinfo_t) * thinkframe_hooks_capacity, PU_STATIC, NULL); + thinkframe_hooks = Z_Calloc(sizeof(ps_hookinfo_t) * thinkframe_hooks_capacity, PU_STATIC, NULL); } if (index >= thinkframe_hooks_capacity) { // array needs more space, realloc with double size - thinkframe_hooks_capacity *= 2; + int new_capacity = thinkframe_hooks_capacity * 2; thinkframe_hooks = Z_Realloc(thinkframe_hooks, - sizeof(ps_hookinfo_t) * thinkframe_hooks_capacity, PU_STATIC, NULL); + sizeof(ps_hookinfo_t) * new_capacity, PU_STATIC, NULL); + // initialize new memory with zeros so the pointers in the structs are null + memset(&thinkframe_hooks[thinkframe_hooks_capacity], 0, + sizeof(ps_hookinfo_t) * thinkframe_hooks_capacity); + thinkframe_hooks_capacity = new_capacity; } thinkframe_hooks[index].time_taken.value.p = time_taken; memcpy(thinkframe_hooks[index].short_src, short_src, LUA_IDSIZE * sizeof(char)); From a48c8826a1c5b1a8514632b9a3433161b3a35ebd Mon Sep 17 00:00:00 2001 From: sphere Date: Sat, 8 May 2021 18:13:35 +0200 Subject: [PATCH 628/644] Add modifiedgame warning to save select menu. --- src/m_menu.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/m_menu.c b/src/m_menu.c index 7a82fd8fb..271936b0e 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -8652,6 +8652,12 @@ static void M_DrawLoad(void) loadgameoffset = 0; M_DrawLoadGameData(); + + if (modifiedgame && !savemoddata) + { + V_DrawCenteredThinString(BASEVIDWIDTH/2, 184, 0, "\x85WARNING: \x80The game is modified."); + V_DrawCenteredThinString(BASEVIDWIDTH/2, 192, 0, "Progress will not be saved."); + } } // From d9fde5c39558248e43d8ec6f32a12c2a4c5d7cd3 Mon Sep 17 00:00:00 2001 From: sphere Date: Sun, 9 May 2021 16:47:52 +0200 Subject: [PATCH 629/644] Add emblem counter to the Extras checklist. --- src/m_menu.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/m_menu.c b/src/m_menu.c index 271936b0e..8f956e9a7 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -7187,13 +7187,20 @@ static void M_HandleChecklist(INT32 choice) static void M_DrawChecklist(void) { - INT32 i = check_on, j = 0, y = currentMenu->y; + INT32 i = check_on, j = 0, y = currentMenu->y, emblems = numemblems+numextraemblems; UINT32 condnum, previd, maxcond; condition_t *cond; // draw title (or big pic) M_DrawMenuTitle(); + // draw emblem counter + if (emblems > 0) + { + V_DrawString(42, 20, (emblems == M_CountEmblems()) ? V_GREENMAP : 0, va("%d/%d", M_CountEmblems(), emblems)); + V_DrawSmallScaledPatch(28, 20, 0, W_CachePatchName("EMBLICON", PU_PATCH)); + } + if (check_on) V_DrawString(10, y-(skullAnimCounter/5), V_YELLOWMAP, "\x1A"); From 08e63fc822005bf061c004c8f6aaea37f56c4702 Mon Sep 17 00:00:00 2001 From: sphere Date: Fri, 8 Oct 2021 18:00:08 +0200 Subject: [PATCH 630/644] Show values on (float) sliders in the options menu. --- src/m_menu.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 8f956e9a7..eeb51d0da 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4062,14 +4062,6 @@ static void M_DrawSlider(INT32 x, INT32 y, const consvar_t *cv, boolean ontop) for (i = 1; i < SLIDER_RANGE; i++) V_DrawScaledPatch (x+i*8, y, 0,p); - if (ontop) - { - V_DrawCharacter(x - 6 - (skullAnimCounter/5), y, - '\x1C' | V_YELLOWMAP, false); - V_DrawCharacter(x+i*8 + 8 + (skullAnimCounter/5), y, - '\x1D' | V_YELLOWMAP, false); - } - p = W_CachePatchName("M_SLIDER", PU_PATCH); V_DrawScaledPatch(x+i*8, y, 0, p); @@ -4105,6 +4097,16 @@ static void M_DrawSlider(INT32 x, INT32 y, const consvar_t *cv, boolean ontop) range = 100; V_DrawMappedPatch(x + 2 + (SLIDER_RANGE*8*range)/100, y, 0, p, yellowmap); + + if (ontop) + { + V_DrawCharacter(x - 6 - (skullAnimCounter/5), y, + '\x1C' | V_YELLOWMAP, false); + V_DrawCharacter(x + 80 + (skullAnimCounter/5), y, + '\x1D' | V_YELLOWMAP, false); + V_DrawCenteredString(x + 40, y, V_30TRANS, + (cv->flags & CV_FLOAT) ? va("%.2f", FIXED_TO_FLOAT(cv->value)) : va("%d", cv->value)); + } } // From 4480af69c7dde61cb3d0a3e82dd9e1587e133157 Mon Sep 17 00:00:00 2001 From: spherallic Date: Fri, 26 Nov 2021 14:09:10 +0100 Subject: [PATCH 631/644] Only show Ultimate mode warning in unmodified vanilla gameplay. --- src/m_menu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/m_menu.c b/src/m_menu.c index eeb51d0da..b99ec186b 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -8968,7 +8968,7 @@ static void M_HandleLoadSave(INT32 choice) break; case KEY_ENTER: - if (ultimate_selectable && saveSlotSelected == NOSAVESLOT) + if (ultimate_selectable && saveSlotSelected == NOSAVESLOT && !savemoddata && !modifiedgame) { loadgamescroll = 0; S_StartSound(NULL, sfx_skid); From cf79bc8382c414ae6973636b92cecb1403cd36c9 Mon Sep 17 00:00:00 2001 From: SMS Alfredo Date: Fri, 26 Nov 2021 14:11:09 +0000 Subject: [PATCH 632/644] Fix #214 (Crushstacean + Fireball Player Removal) --- src/p_enemy.c | 4 +--- src/p_inter.c | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 49907bdcc..8329b4f57 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -3518,9 +3518,7 @@ void A_Scream(mobj_t *actor) if (LUA_CallAction(A_SCREAM, actor)) return; - if (actor->tracer && (actor->tracer->type == MT_SHELL || actor->tracer->type == MT_FIREBALL)) - S_StartScreamSound(actor, sfx_mario2); - else if (actor->info->deathsound) + if (actor->info->deathsound && !S_SoundPlaying(actor, sfx_mario2)) S_StartScreamSound(actor, actor->info->deathsound); } diff --git a/src/p_inter.c b/src/p_inter.c index 21e3bfa3d..4b958fb89 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2391,7 +2391,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget mobj_t *mo; if (inflictor && (inflictor->type == MT_SHELL || inflictor->type == MT_FIREBALL)) - P_SetTarget(&target->tracer, inflictor); + S_StartScreamSound(target, sfx_mario2); if (!(maptol & TOL_NIGHTS) && G_IsSpecialStage(gamemap) && target->player && target->player->nightstime > 6) target->player->nightstime = 6; // Just let P_Ticker take care of the rest. From 6a6b292c730be21e492735ed8366a4c9f2ba5cb4 Mon Sep 17 00:00:00 2001 From: spherallic Date: Sat, 27 Nov 2021 14:22:21 +0100 Subject: [PATCH 633/644] Fix Flame Shield interactions in old-style special stages. --- src/p_tick.c | 2 +- src/st_stuff.c | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/p_tick.c b/src/p_tick.c index d7357eb82..cee658953 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -487,7 +487,7 @@ static inline void P_DoSpecialStageStuff(void) continue; // If in water, deplete timer 6x as fast. - if (players[i].mo->eflags & (MFE_TOUCHWATER|MFE_UNDERWATER) && !(players[i].powers[pw_shield] & SH_PROTECTWATER)) + if (players[i].mo->eflags & (MFE_TOUCHWATER|MFE_UNDERWATER) && !(players[i].powers[pw_shield] & ((players[i].mo->eflags & MFE_TOUCHLAVA) ? SH_PROTECTFIRE : SH_PROTECTWATER))) players[i].nightstime -= 5; if (--players[i].nightstime > 6) { diff --git a/src/st_stuff.c b/src/st_stuff.c index a1b9206b0..a328d669e 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2037,9 +2037,8 @@ static void ST_drawNiGHTSHUD(void) else numbersize = 48/2; - if ((oldspecialstage && leveltime & 2) - && (stplyr->mo->eflags & (MFE_TOUCHWATER|MFE_UNDERWATER)) - && !(stplyr->powers[pw_shield] & SH_PROTECTWATER)) + if ((oldspecialstage && leveltime & 2) && + (stplyr->mo->eflags & (MFE_TOUCHWATER|MFE_UNDERWATER) && !(stplyr->powers[pw_shield] & ((stplyr->mo->eflags & MFE_TOUCHLAVA) ? SH_PROTECTFIRE : SH_PROTECTWATER)))) col = SKINCOLOR_ORANGE; ST_DrawNightsOverlayNum((160 + numbersize)< Date: Sat, 27 Nov 2021 14:23:02 +0100 Subject: [PATCH 634/644] Make Brak's electric barrier damage Elemental and Flame Shields. --- src/p_inter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_inter.c b/src/p_inter.c index 4b958fb89..b37689fd8 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -3651,7 +3651,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da return true; } - if (!force && inflictor && inflictor->flags & MF_FIRE) + if (!force && inflictor && inflictor->flags & MF_FIRE && !(damagetype && damagetype != DMG_FIRE)) { if (player->powers[pw_shield] & SH_PROTECTFIRE) return false; // Invincible to fire objects From 49e6e7a80f40b25e18faa99c54c121e0b2ac3b14 Mon Sep 17 00:00:00 2001 From: spherallic Date: Sat, 27 Nov 2021 16:19:04 +0100 Subject: [PATCH 635/644] Fix retracting spikes dealing typeless damage instead of spike damage. --- src/info.c | 4 ++-- src/p_map.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/info.c b/src/info.c index efcf1c044..b9d088662 100644 --- a/src/info.c +++ b/src/info.c @@ -7974,7 +7974,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 8*FRACUNIT, // radius 32*FRACUNIT, // height 0, // display offset - 4, // mass + DMG_SPIKE, // mass 0, // damage sfx_None, // activesound MF_NOBLOCKMAP|MF_SCENERY|MF_NOCLIPHEIGHT, // flags @@ -8001,7 +8001,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 16*FRACUNIT, // radius 14*FRACUNIT, // height 0, // display offset - 4, // mass + DMG_SPIKE, // mass 0, // damage sfx_None, // activesound MF_NOBLOCKMAP|MF_NOGRAVITY|MF_SCENERY|MF_NOCLIPHEIGHT|MF_PAPERCOLLISION, // flags diff --git a/src/p_map.c b/src/p_map.c index e55bebb9a..c01c91e3c 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1156,7 +1156,7 @@ static boolean PIT_CheckThing(mobj_t *thing) else thing->z = tmthing->z + tmthing->height + FixedMul(FRACUNIT, tmthing->scale); if (thing->flags & MF_SHOOTABLE) - P_DamageMobj(thing, tmthing, tmthing, 1, 0); + P_DamageMobj(thing, tmthing, tmthing, 1, DMG_SPIKE); return true; } From 9bdfafc9dd3b274243c429a60ee7c14cceeeae2f Mon Sep 17 00:00:00 2001 From: spherallic Date: Mon, 29 Nov 2021 19:25:30 +0100 Subject: [PATCH 636/644] Add DMG_FIRE to Pyrefly fire and lavafall objects. --- src/info.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/info.c b/src/info.c index b9d088662..24c8f7bf7 100644 --- a/src/info.c +++ b/src/info.c @@ -5199,7 +5199,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 24*FRACUNIT, // radius 34*FRACUNIT, // height 0, // display offset - 100, // mass + DMG_FIRE, // mass 0, // damage sfx_None, // activesound MF_NOGRAVITY|MF_NOBLOCKMAP|MF_FIRE|MF_PAIN, // flags @@ -13401,7 +13401,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 30*FRACUNIT, // radius 48*FRACUNIT, // height 0, // display offset - 100, // mass + DMG_FIRE, // mass 0, // damage sfx_None, // activesound MF_SPECIAL|MF_PAIN|MF_NOGRAVITY|MF_FIRE, // flags @@ -13806,7 +13806,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 8*FRACUNIT, // radius 32*FRACUNIT, // height 0, // display offset - 0, // mass + 0, // mass 0, // damage sfx_None, // activesound MF_NOGRAVITY|MF_PAIN, // flags From a5e1167ad2181a3b6278f6aeaa9e2cbb7d4dff97 Mon Sep 17 00:00:00 2001 From: SMS Alfredo <65426124+SMS-Alfredo@users.noreply.github.com> Date: Tue, 30 Nov 2021 20:51:15 -0600 Subject: [PATCH 637/644] balls --- src/info.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/info.c b/src/info.c index efcf1c044..1cd80f383 100644 --- a/src/info.c +++ b/src/info.c @@ -11430,7 +11430,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 17*FRACUNIT, // radius 34*FRACUNIT, // height 1, // display offset - 0, // mass + DMG_SPIKE, // mass 1, // damage sfx_s3kc9s, //sfx_mswing, -- activesound MF_SCENERY|MF_PAIN|MF_NOGRAVITY, // flags @@ -11457,7 +11457,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 34*FRACUNIT, // radius 68*FRACUNIT, // height 1, // display offset - 0, // mass + DMG_SPIKE, // mass 1, // damage sfx_s3kc9s, //sfx_mswing, -- activesound MF_SCENERY|MF_PAIN|MF_NOGRAVITY, // flags @@ -20380,7 +20380,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 18*FRACUNIT, // radius 28*FRACUNIT, // height 0, // display offset - 0, // mass + DMG_SPIKE, // mass 0, // damage sfx_None, // activesound MF_NOGRAVITY|MF_PAIN, // flags From aca0ba0f4b0175072dbd71f4b9cca4c2cbf17982 Mon Sep 17 00:00:00 2001 From: SMS Alfredo <65426124+SMS-Alfredo@users.noreply.github.com> Date: Tue, 30 Nov 2021 22:46:51 -0600 Subject: [PATCH 638/644] wow --- src/info.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/info.c b/src/info.c index efcf1c044..4e991e81c 100644 --- a/src/info.c +++ b/src/info.c @@ -2069,7 +2069,7 @@ state_t states[NUMSTATES] = {SPR_TVFL, 2, 18, {A_GiveShield}, SH_FLAMEAURA, 0, S_NULL}, // S_FLAMEAURA_ICON2 {SPR_TVBB, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_BUBBLEWRAP_ICON2}, // S_BUBBLEWRAP_ICON1 - {SPR_TVBB, 2, 18, {A_GiveShield}, SH_BUBBLEWRAP, 0, S_NULL}, // S_BUBBLERWAP_ICON2 + {SPR_TVBB, 2, 18, {A_GiveShield}, SH_BUBBLEWRAP, 0, S_NULL}, // S_BUBBLEWRAP_ICON2 {SPR_TVZP, FF_ANIMATE|2, 18, {NULL}, 3, 4, S_THUNDERCOIN_ICON2}, // S_THUNDERCOIN_ICON1 {SPR_TVZP, 2, 18, {A_GiveShield}, SH_THUNDERCOIN, 0, S_NULL}, // S_THUNDERCOIN_ICON2 From c1c7607cb0a1e359cdce4db3cd252c1004e100ee Mon Sep 17 00:00:00 2001 From: spherallic Date: Thu, 2 Dec 2021 01:52:45 +0100 Subject: [PATCH 639/644] Add toggle for linedef action 401 to not change the ceiling texture. --- extras/conf/SRB2-22.cfg | 7 ++++--- src/p_ceilng.c | 11 ++++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg index 0ca8a6715..4ed68e1ca 100644 --- a/extras/conf/SRB2-22.cfg +++ b/extras/conf/SRB2-22.cfg @@ -1992,7 +1992,7 @@ linedeftypes title = "Set Tagged Sector's Floor Height/Texture"; prefix = "(400)"; flags8text = "[3] Set delay by backside sector"; - flags64text = "[6] Keep floor flat"; + flags64text = "[6] Don't change floor texture"; } 401 @@ -2000,6 +2000,7 @@ linedeftypes title = "Set Tagged Sector's Ceiling Height/Texture"; prefix = "(401)"; flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Don't change ceiling texture"; } 402 @@ -2090,7 +2091,7 @@ linedeftypes prefix = "(403)"; flags2text = "[1] Trigger linedef executor"; flags8text = "[3] Set delay by backside sector"; - flags64text = "[6] Change floor flat"; + flags64text = "[6] Change floor texture"; } 404 @@ -2099,7 +2100,7 @@ linedeftypes prefix = "(404)"; flags2text = "[1] Trigger linedef executor"; flags8text = "[3] Set delay by backside sector"; - flags64text = "[6] Change ceiling flat"; + flags64text = "[6] Change ceiling texture"; } 405 diff --git a/src/p_ceilng.c b/src/p_ceilng.c index 43f3cc1d5..e28f9b5b1 100644 --- a/src/p_ceilng.c +++ b/src/p_ceilng.c @@ -67,7 +67,8 @@ void T_MoveCeiling(ceiling_t *ceiling) switch (ceiling->type) { case instantMoveCeilingByFrontSector: - ceiling->sector->ceilingpic = ceiling->texture; + if (ceiling->texture > -1) + ceiling->sector->ceilingpic = ceiling->texture; ceiling->sector->ceilingdata = NULL; ceiling->sector->ceilspeed = 0; P_RemoveThinker(&ceiling->thinker); @@ -186,7 +187,8 @@ void T_MoveCeiling(ceiling_t *ceiling) break; case instantMoveCeilingByFrontSector: - ceiling->sector->ceilingpic = ceiling->texture; + if (ceiling->texture > -1) + ceiling->sector->ceilingpic = ceiling->texture; ceiling->sector->ceilingdata = NULL; ceiling->sector->ceilspeed = 0; P_RemoveThinker(&ceiling->thinker); @@ -512,7 +514,10 @@ INT32 EV_DoCeiling(line_t *line, ceiling_e type) ceiling->direction = -1; ceiling->bottomheight = line->frontsector->ceilingheight; } - ceiling->texture = line->frontsector->ceilingpic; + if (line->flags & ML_NOCLIMB) + ceiling->texture = -1; + else + ceiling->texture = line->frontsector->ceilingpic; break; case moveCeilingByFrontTexture: From 443c51714a3e78eb47a1b10091f5852d86521b99 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Thu, 2 Dec 2021 21:02:54 +0100 Subject: [PATCH 640/644] Fix KeyUp hook being called when the console is open --- src/d_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_main.c b/src/d_main.c index 679a596b3..99b3c3ebd 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -272,7 +272,7 @@ void D_ProcessEvents(void) if (eaten) continue; // ate the event - if (!hooked && G_LuaResponder(ev)) + if (!hooked && !CON_Ready() && G_LuaResponder(ev)) continue; G_Responder(ev); From 425d1f1b536dc634f81dd9d0a2473f03ab82a0a7 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Thu, 2 Dec 2021 21:03:16 +0100 Subject: [PATCH 641/644] Make all key identifiers lowercase --- src/g_input.c | 570 +++++++++++++++++++++++++------------------------- 1 file changed, 285 insertions(+), 285 deletions(-) diff --git a/src/g_input.c b/src/g_input.c index cd4536bba..6383c3f00 100644 --- a/src/g_input.c +++ b/src/g_input.c @@ -233,323 +233,323 @@ typedef struct static keyname_t keynames[] = { - {KEY_SPACE, "SPACE"}, - {KEY_CAPSLOCK, "CAPS LOCK"}, - {KEY_ENTER, "ENTER"}, - {KEY_TAB, "TAB"}, - {KEY_ESCAPE, "ESCAPE"}, - {KEY_BACKSPACE, "BACKSPACE"}, + {KEY_SPACE, "space"}, + {KEY_CAPSLOCK, "caps lock"}, + {KEY_ENTER, "enter"}, + {KEY_TAB, "tab"}, + {KEY_ESCAPE, "escape"}, + {KEY_BACKSPACE, "backspace"}, - {KEY_NUMLOCK, "NUMLOCK"}, - {KEY_SCROLLLOCK, "SCROLLLOCK"}, + {KEY_NUMLOCK, "numlock"}, + {KEY_SCROLLLOCK, "scrolllock"}, // bill gates keys - {KEY_LEFTWIN, "LEFTWIN"}, - {KEY_RIGHTWIN, "RIGHTWIN"}, - {KEY_MENU, "MENU"}, + {KEY_LEFTWIN, "leftwin"}, + {KEY_RIGHTWIN, "rightwin"}, + {KEY_MENU, "menu"}, - {KEY_LSHIFT, "LSHIFT"}, - {KEY_RSHIFT, "RSHIFT"}, - {KEY_LSHIFT, "SHIFT"}, - {KEY_LCTRL, "LCTRL"}, - {KEY_RCTRL, "RCTRL"}, - {KEY_LCTRL, "CTRL"}, - {KEY_LALT, "LALT"}, - {KEY_RALT, "RALT"}, - {KEY_LALT, "ALT"}, + {KEY_LSHIFT, "lshift"}, + {KEY_RSHIFT, "rshift"}, + {KEY_LSHIFT, "shift"}, + {KEY_LCTRL, "lctrl"}, + {KEY_RCTRL, "rctrl"}, + {KEY_LCTRL, "ctrl"}, + {KEY_LALT, "lalt"}, + {KEY_RALT, "ralt"}, + {KEY_LALT, "alt"}, // keypad keys - {KEY_KPADSLASH, "KEYPAD /"}, - {KEY_KEYPAD7, "KEYPAD 7"}, - {KEY_KEYPAD8, "KEYPAD 8"}, - {KEY_KEYPAD9, "KEYPAD 9"}, - {KEY_MINUSPAD, "KEYPAD -"}, - {KEY_KEYPAD4, "KEYPAD 4"}, - {KEY_KEYPAD5, "KEYPAD 5"}, - {KEY_KEYPAD6, "KEYPAD 6"}, - {KEY_PLUSPAD, "KEYPAD +"}, - {KEY_KEYPAD1, "KEYPAD 1"}, - {KEY_KEYPAD2, "KEYPAD 2"}, - {KEY_KEYPAD3, "KEYPAD 3"}, - {KEY_KEYPAD0, "KEYPAD 0"}, - {KEY_KPADDEL, "KEYPAD ."}, + {KEY_KPADSLASH, "keypad /"}, + {KEY_KEYPAD7, "keypad 7"}, + {KEY_KEYPAD8, "keypad 8"}, + {KEY_KEYPAD9, "keypad 9"}, + {KEY_MINUSPAD, "keypad -"}, + {KEY_KEYPAD4, "keypad 4"}, + {KEY_KEYPAD5, "keypad 5"}, + {KEY_KEYPAD6, "keypad 6"}, + {KEY_PLUSPAD, "keypad +"}, + {KEY_KEYPAD1, "keypad 1"}, + {KEY_KEYPAD2, "keypad 2"}, + {KEY_KEYPAD3, "keypad 3"}, + {KEY_KEYPAD0, "keypad 0"}, + {KEY_KPADDEL, "keypad ."}, // extended keys (not keypad) - {KEY_HOME, "HOME"}, - {KEY_UPARROW, "UP ARROW"}, - {KEY_PGUP, "PGUP"}, - {KEY_LEFTARROW, "LEFT ARROW"}, - {KEY_RIGHTARROW, "RIGHT ARROW"}, - {KEY_END, "END"}, - {KEY_DOWNARROW, "DOWN ARROW"}, - {KEY_PGDN, "PGDN"}, - {KEY_INS, "INS"}, - {KEY_DEL, "DEL"}, + {KEY_HOME, "home"}, + {KEY_UPARROW, "up arrow"}, + {KEY_PGUP, "pgup"}, + {KEY_LEFTARROW, "left arrow"}, + {KEY_RIGHTARROW, "right arrow"}, + {KEY_END, "end"}, + {KEY_DOWNARROW, "down arrow"}, + {KEY_PGDN, "pgdn"}, + {KEY_INS, "ins"}, + {KEY_DEL, "del"}, // other keys - {KEY_F1, "F1"}, - {KEY_F2, "F2"}, - {KEY_F3, "F3"}, - {KEY_F4, "F4"}, - {KEY_F5, "F5"}, - {KEY_F6, "F6"}, - {KEY_F7, "F7"}, - {KEY_F8, "F8"}, - {KEY_F9, "F9"}, - {KEY_F10, "F10"}, - {KEY_F11, "F11"}, - {KEY_F12, "F12"}, + {KEY_F1, "f1"}, + {KEY_F2, "f2"}, + {KEY_F3, "f3"}, + {KEY_F4, "f4"}, + {KEY_F5, "f5"}, + {KEY_F6, "f6"}, + {KEY_F7, "f7"}, + {KEY_F8, "f8"}, + {KEY_F9, "f9"}, + {KEY_F10, "f10"}, + {KEY_F11, "f11"}, + {KEY_F12, "f12"}, // KEY_CONSOLE has an exception in the keyname code {'`', "TILDE"}, - {KEY_PAUSE, "PAUSE/BREAK"}, + {KEY_PAUSE, "pause/break"}, // virtual keys for mouse buttons and joystick buttons - {KEY_MOUSE1+0,"MOUSE1"}, - {KEY_MOUSE1+1,"MOUSE2"}, - {KEY_MOUSE1+2,"MOUSE3"}, - {KEY_MOUSE1+3,"MOUSE4"}, - {KEY_MOUSE1+4,"MOUSE5"}, - {KEY_MOUSE1+5,"MOUSE6"}, - {KEY_MOUSE1+6,"MOUSE7"}, - {KEY_MOUSE1+7,"MOUSE8"}, - {KEY_2MOUSE1+0,"SEC_MOUSE2"}, // BP: sorry my mouse handler swap button 1 and 2 - {KEY_2MOUSE1+1,"SEC_MOUSE1"}, - {KEY_2MOUSE1+2,"SEC_MOUSE3"}, - {KEY_2MOUSE1+3,"SEC_MOUSE4"}, - {KEY_2MOUSE1+4,"SEC_MOUSE5"}, - {KEY_2MOUSE1+5,"SEC_MOUSE6"}, - {KEY_2MOUSE1+6,"SEC_MOUSE7"}, - {KEY_2MOUSE1+7,"SEC_MOUSE8"}, - {KEY_MOUSEWHEELUP, "Wheel 1 UP"}, - {KEY_MOUSEWHEELDOWN, "Wheel 1 Down"}, - {KEY_2MOUSEWHEELUP, "Wheel 2 UP"}, - {KEY_2MOUSEWHEELDOWN, "Wheel 2 Down"}, + {KEY_MOUSE1+0,"mouse1"}, + {KEY_MOUSE1+1,"mouse2"}, + {KEY_MOUSE1+2,"mouse3"}, + {KEY_MOUSE1+3,"mouse4"}, + {KEY_MOUSE1+4,"mouse5"}, + {KEY_MOUSE1+5,"mouse6"}, + {KEY_MOUSE1+6,"mouse7"}, + {KEY_MOUSE1+7,"mouse8"}, + {KEY_2MOUSE1+0,"sec_mouse2"}, // BP: sorry my mouse handler swap button 1 and 2 + {KEY_2MOUSE1+1,"sec_mouse1"}, + {KEY_2MOUSE1+2,"sec_mouse3"}, + {KEY_2MOUSE1+3,"sec_mouse4"}, + {KEY_2MOUSE1+4,"sec_mouse5"}, + {KEY_2MOUSE1+5,"sec_mouse6"}, + {KEY_2MOUSE1+6,"sec_mouse7"}, + {KEY_2MOUSE1+7,"sec_mouse8"}, + {KEY_MOUSEWHEELUP, "wheel 1 up"}, + {KEY_MOUSEWHEELDOWN, "wheel 1 down"}, + {KEY_2MOUSEWHEELUP, "wheel 2 up"}, + {KEY_2MOUSEWHEELDOWN, "wheel 2 down"}, - {KEY_JOY1+0, "JOY1"}, - {KEY_JOY1+1, "JOY2"}, - {KEY_JOY1+2, "JOY3"}, - {KEY_JOY1+3, "JOY4"}, - {KEY_JOY1+4, "JOY5"}, - {KEY_JOY1+5, "JOY6"}, - {KEY_JOY1+6, "JOY7"}, - {KEY_JOY1+7, "JOY8"}, - {KEY_JOY1+8, "JOY9"}, + {KEY_JOY1+0, "joy1"}, + {KEY_JOY1+1, "joy2"}, + {KEY_JOY1+2, "joy3"}, + {KEY_JOY1+3, "joy4"}, + {KEY_JOY1+4, "joy5"}, + {KEY_JOY1+5, "joy6"}, + {KEY_JOY1+6, "joy7"}, + {KEY_JOY1+7, "joy8"}, + {KEY_JOY1+8, "joy9"}, #if !defined (NOMOREJOYBTN_1S) // we use up to 32 buttons in DirectInput - {KEY_JOY1+9, "JOY10"}, - {KEY_JOY1+10, "JOY11"}, - {KEY_JOY1+11, "JOY12"}, - {KEY_JOY1+12, "JOY13"}, - {KEY_JOY1+13, "JOY14"}, - {KEY_JOY1+14, "JOY15"}, - {KEY_JOY1+15, "JOY16"}, - {KEY_JOY1+16, "JOY17"}, - {KEY_JOY1+17, "JOY18"}, - {KEY_JOY1+18, "JOY19"}, - {KEY_JOY1+19, "JOY20"}, - {KEY_JOY1+20, "JOY21"}, - {KEY_JOY1+21, "JOY22"}, - {KEY_JOY1+22, "JOY23"}, - {KEY_JOY1+23, "JOY24"}, - {KEY_JOY1+24, "JOY25"}, - {KEY_JOY1+25, "JOY26"}, - {KEY_JOY1+26, "JOY27"}, - {KEY_JOY1+27, "JOY28"}, - {KEY_JOY1+28, "JOY29"}, - {KEY_JOY1+29, "JOY30"}, - {KEY_JOY1+30, "JOY31"}, - {KEY_JOY1+31, "JOY32"}, + {KEY_JOY1+9, "joy10"}, + {KEY_JOY1+10, "joy11"}, + {KEY_JOY1+11, "joy12"}, + {KEY_JOY1+12, "joy13"}, + {KEY_JOY1+13, "joy14"}, + {KEY_JOY1+14, "joy15"}, + {KEY_JOY1+15, "joy16"}, + {KEY_JOY1+16, "joy17"}, + {KEY_JOY1+17, "joy18"}, + {KEY_JOY1+18, "joy19"}, + {KEY_JOY1+19, "joy20"}, + {KEY_JOY1+20, "joy21"}, + {KEY_JOY1+21, "joy22"}, + {KEY_JOY1+22, "joy23"}, + {KEY_JOY1+23, "joy24"}, + {KEY_JOY1+24, "joy25"}, + {KEY_JOY1+25, "joy26"}, + {KEY_JOY1+26, "joy27"}, + {KEY_JOY1+27, "joy28"}, + {KEY_JOY1+28, "joy29"}, + {KEY_JOY1+29, "joy30"}, + {KEY_JOY1+30, "joy31"}, + {KEY_JOY1+31, "joy32"}, #endif // the DOS version uses Allegro's joystick support - {KEY_HAT1+0, "HATUP"}, - {KEY_HAT1+1, "HATDOWN"}, - {KEY_HAT1+2, "HATLEFT"}, - {KEY_HAT1+3, "HATRIGHT"}, - {KEY_HAT1+4, "HATUP2"}, - {KEY_HAT1+5, "HATDOWN2"}, - {KEY_HAT1+6, "HATLEFT2"}, - {KEY_HAT1+7, "HATRIGHT2"}, - {KEY_HAT1+8, "HATUP3"}, - {KEY_HAT1+9, "HATDOWN3"}, - {KEY_HAT1+10, "HATLEFT3"}, - {KEY_HAT1+11, "HATRIGHT3"}, - {KEY_HAT1+12, "HATUP4"}, - {KEY_HAT1+13, "HATDOWN4"}, - {KEY_HAT1+14, "HATLEFT4"}, - {KEY_HAT1+15, "HATRIGHT4"}, + {KEY_HAT1+0, "hatup"}, + {KEY_HAT1+1, "hatdown"}, + {KEY_HAT1+2, "hatleft"}, + {KEY_HAT1+3, "hatright"}, + {KEY_HAT1+4, "hatup2"}, + {KEY_HAT1+5, "hatdown2"}, + {KEY_HAT1+6, "hatleft2"}, + {KEY_HAT1+7, "hatright2"}, + {KEY_HAT1+8, "hatup3"}, + {KEY_HAT1+9, "hatdown3"}, + {KEY_HAT1+10, "hatleft3"}, + {KEY_HAT1+11, "hatright3"}, + {KEY_HAT1+12, "hatup4"}, + {KEY_HAT1+13, "hatdown4"}, + {KEY_HAT1+14, "hatleft4"}, + {KEY_HAT1+15, "hatright4"}, - {KEY_DBLMOUSE1+0, "DBLMOUSE1"}, - {KEY_DBLMOUSE1+1, "DBLMOUSE2"}, - {KEY_DBLMOUSE1+2, "DBLMOUSE3"}, - {KEY_DBLMOUSE1+3, "DBLMOUSE4"}, - {KEY_DBLMOUSE1+4, "DBLMOUSE5"}, - {KEY_DBLMOUSE1+5, "DBLMOUSE6"}, - {KEY_DBLMOUSE1+6, "DBLMOUSE7"}, - {KEY_DBLMOUSE1+7, "DBLMOUSE8"}, - {KEY_DBL2MOUSE1+0, "DBLSEC_MOUSE2"}, // BP: sorry my mouse handler swap button 1 and 2 - {KEY_DBL2MOUSE1+1, "DBLSEC_MOUSE1"}, - {KEY_DBL2MOUSE1+2, "DBLSEC_MOUSE3"}, - {KEY_DBL2MOUSE1+3, "DBLSEC_MOUSE4"}, - {KEY_DBL2MOUSE1+4, "DBLSEC_MOUSE5"}, - {KEY_DBL2MOUSE1+5, "DBLSEC_MOUSE6"}, - {KEY_DBL2MOUSE1+6, "DBLSEC_MOUSE7"}, - {KEY_DBL2MOUSE1+7, "DBLSEC_MOUSE8"}, + {KEY_DBLMOUSE1+0, "dblmouse1"}, + {KEY_DBLMOUSE1+1, "dblmouse2"}, + {KEY_DBLMOUSE1+2, "dblmouse3"}, + {KEY_DBLMOUSE1+3, "dblmouse4"}, + {KEY_DBLMOUSE1+4, "dblmouse5"}, + {KEY_DBLMOUSE1+5, "dblmouse6"}, + {KEY_DBLMOUSE1+6, "dblmouse7"}, + {KEY_DBLMOUSE1+7, "dblmouse8"}, + {KEY_DBL2MOUSE1+0, "dblsec_mouse2"}, // BP: sorry my mouse handler swap button 1 and 2 + {KEY_DBL2MOUSE1+1, "dblsec_mouse1"}, + {KEY_DBL2MOUSE1+2, "dblsec_mouse3"}, + {KEY_DBL2MOUSE1+3, "dblsec_mouse4"}, + {KEY_DBL2MOUSE1+4, "dblsec_mouse5"}, + {KEY_DBL2MOUSE1+5, "dblsec_mouse6"}, + {KEY_DBL2MOUSE1+6, "dblsec_mouse7"}, + {KEY_DBL2MOUSE1+7, "dblsec_mouse8"}, - {KEY_DBLJOY1+0, "DBLJOY1"}, - {KEY_DBLJOY1+1, "DBLJOY2"}, - {KEY_DBLJOY1+2, "DBLJOY3"}, - {KEY_DBLJOY1+3, "DBLJOY4"}, - {KEY_DBLJOY1+4, "DBLJOY5"}, - {KEY_DBLJOY1+5, "DBLJOY6"}, - {KEY_DBLJOY1+6, "DBLJOY7"}, - {KEY_DBLJOY1+7, "DBLJOY8"}, + {KEY_DBLJOY1+0, "dbljoy1"}, + {KEY_DBLJOY1+1, "dbljoy2"}, + {KEY_DBLJOY1+2, "dbljoy3"}, + {KEY_DBLJOY1+3, "dbljoy4"}, + {KEY_DBLJOY1+4, "dbljoy5"}, + {KEY_DBLJOY1+5, "dbljoy6"}, + {KEY_DBLJOY1+6, "dbljoy7"}, + {KEY_DBLJOY1+7, "dbljoy8"}, #if !defined (NOMOREJOYBTN_1DBL) - {KEY_DBLJOY1+8, "DBLJOY9"}, - {KEY_DBLJOY1+9, "DBLJOY10"}, - {KEY_DBLJOY1+10, "DBLJOY11"}, - {KEY_DBLJOY1+11, "DBLJOY12"}, - {KEY_DBLJOY1+12, "DBLJOY13"}, - {KEY_DBLJOY1+13, "DBLJOY14"}, - {KEY_DBLJOY1+14, "DBLJOY15"}, - {KEY_DBLJOY1+15, "DBLJOY16"}, - {KEY_DBLJOY1+16, "DBLJOY17"}, - {KEY_DBLJOY1+17, "DBLJOY18"}, - {KEY_DBLJOY1+18, "DBLJOY19"}, - {KEY_DBLJOY1+19, "DBLJOY20"}, - {KEY_DBLJOY1+20, "DBLJOY21"}, - {KEY_DBLJOY1+21, "DBLJOY22"}, - {KEY_DBLJOY1+22, "DBLJOY23"}, - {KEY_DBLJOY1+23, "DBLJOY24"}, - {KEY_DBLJOY1+24, "DBLJOY25"}, - {KEY_DBLJOY1+25, "DBLJOY26"}, - {KEY_DBLJOY1+26, "DBLJOY27"}, - {KEY_DBLJOY1+27, "DBLJOY28"}, - {KEY_DBLJOY1+28, "DBLJOY29"}, - {KEY_DBLJOY1+29, "DBLJOY30"}, - {KEY_DBLJOY1+30, "DBLJOY31"}, - {KEY_DBLJOY1+31, "DBLJOY32"}, + {KEY_DBLJOY1+8, "dbljoy9"}, + {KEY_DBLJOY1+9, "dbljoy10"}, + {KEY_DBLJOY1+10, "dbljoy11"}, + {KEY_DBLJOY1+11, "dbljoy12"}, + {KEY_DBLJOY1+12, "dbljoy13"}, + {KEY_DBLJOY1+13, "dbljoy14"}, + {KEY_DBLJOY1+14, "dbljoy15"}, + {KEY_DBLJOY1+15, "dbljoy16"}, + {KEY_DBLJOY1+16, "dbljoy17"}, + {KEY_DBLJOY1+17, "dbljoy18"}, + {KEY_DBLJOY1+18, "dbljoy19"}, + {KEY_DBLJOY1+19, "dbljoy20"}, + {KEY_DBLJOY1+20, "dbljoy21"}, + {KEY_DBLJOY1+21, "dbljoy22"}, + {KEY_DBLJOY1+22, "dbljoy23"}, + {KEY_DBLJOY1+23, "dbljoy24"}, + {KEY_DBLJOY1+24, "dbljoy25"}, + {KEY_DBLJOY1+25, "dbljoy26"}, + {KEY_DBLJOY1+26, "dbljoy27"}, + {KEY_DBLJOY1+27, "dbljoy28"}, + {KEY_DBLJOY1+28, "dbljoy29"}, + {KEY_DBLJOY1+29, "dbljoy30"}, + {KEY_DBLJOY1+30, "dbljoy31"}, + {KEY_DBLJOY1+31, "dbljoy32"}, #endif - {KEY_DBLHAT1+0, "DBLHATUP"}, - {KEY_DBLHAT1+1, "DBLHATDOWN"}, - {KEY_DBLHAT1+2, "DBLHATLEFT"}, - {KEY_DBLHAT1+3, "DBLHATRIGHT"}, - {KEY_DBLHAT1+4, "DBLHATUP2"}, - {KEY_DBLHAT1+5, "DBLHATDOWN2"}, - {KEY_DBLHAT1+6, "DBLHATLEFT2"}, - {KEY_DBLHAT1+7, "DBLHATRIGHT2"}, - {KEY_DBLHAT1+8, "DBLHATUP3"}, - {KEY_DBLHAT1+9, "DBLHATDOWN3"}, - {KEY_DBLHAT1+10, "DBLHATLEFT3"}, - {KEY_DBLHAT1+11, "DBLHATRIGHT3"}, - {KEY_DBLHAT1+12, "DBLHATUP4"}, - {KEY_DBLHAT1+13, "DBLHATDOWN4"}, - {KEY_DBLHAT1+14, "DBLHATLEFT4"}, - {KEY_DBLHAT1+15, "DBLHATRIGHT4"}, + {KEY_DBLHAT1+0, "dblhatup"}, + {KEY_DBLHAT1+1, "dblhatdown"}, + {KEY_DBLHAT1+2, "dblhatleft"}, + {KEY_DBLHAT1+3, "dblhatright"}, + {KEY_DBLHAT1+4, "dblhatup2"}, + {KEY_DBLHAT1+5, "dblhatdown2"}, + {KEY_DBLHAT1+6, "dblhatleft2"}, + {KEY_DBLHAT1+7, "dblhatright2"}, + {KEY_DBLHAT1+8, "dblhatup3"}, + {KEY_DBLHAT1+9, "dblhatdown3"}, + {KEY_DBLHAT1+10, "dblhatleft3"}, + {KEY_DBLHAT1+11, "dblhatright3"}, + {KEY_DBLHAT1+12, "dblhatup4"}, + {KEY_DBLHAT1+13, "dblhatdown4"}, + {KEY_DBLHAT1+14, "dblhatleft4"}, + {KEY_DBLHAT1+15, "dblhatright4"}, - {KEY_2JOY1+0, "SEC_JOY1"}, - {KEY_2JOY1+1, "SEC_JOY2"}, - {KEY_2JOY1+2, "SEC_JOY3"}, - {KEY_2JOY1+3, "SEC_JOY4"}, - {KEY_2JOY1+4, "SEC_JOY5"}, - {KEY_2JOY1+5, "SEC_JOY6"}, - {KEY_2JOY1+6, "SEC_JOY7"}, - {KEY_2JOY1+7, "SEC_JOY8"}, + {KEY_2JOY1+0, "sec_joy1"}, + {KEY_2JOY1+1, "sec_joy2"}, + {KEY_2JOY1+2, "sec_joy3"}, + {KEY_2JOY1+3, "sec_joy4"}, + {KEY_2JOY1+4, "sec_joy5"}, + {KEY_2JOY1+5, "sec_joy6"}, + {KEY_2JOY1+6, "sec_joy7"}, + {KEY_2JOY1+7, "sec_joy8"}, #if !defined (NOMOREJOYBTN_2S) // we use up to 32 buttons in DirectInput - {KEY_2JOY1+8, "SEC_JOY9"}, - {KEY_2JOY1+9, "SEC_JOY10"}, - {KEY_2JOY1+10, "SEC_JOY11"}, - {KEY_2JOY1+11, "SEC_JOY12"}, - {KEY_2JOY1+12, "SEC_JOY13"}, - {KEY_2JOY1+13, "SEC_JOY14"}, - {KEY_2JOY1+14, "SEC_JOY15"}, - {KEY_2JOY1+15, "SEC_JOY16"}, - {KEY_2JOY1+16, "SEC_JOY17"}, - {KEY_2JOY1+17, "SEC_JOY18"}, - {KEY_2JOY1+18, "SEC_JOY19"}, - {KEY_2JOY1+19, "SEC_JOY20"}, - {KEY_2JOY1+20, "SEC_JOY21"}, - {KEY_2JOY1+21, "SEC_JOY22"}, - {KEY_2JOY1+22, "SEC_JOY23"}, - {KEY_2JOY1+23, "SEC_JOY24"}, - {KEY_2JOY1+24, "SEC_JOY25"}, - {KEY_2JOY1+25, "SEC_JOY26"}, - {KEY_2JOY1+26, "SEC_JOY27"}, - {KEY_2JOY1+27, "SEC_JOY28"}, - {KEY_2JOY1+28, "SEC_JOY29"}, - {KEY_2JOY1+29, "SEC_JOY30"}, - {KEY_2JOY1+30, "SEC_JOY31"}, - {KEY_2JOY1+31, "SEC_JOY32"}, + {KEY_2JOY1+8, "sec_joy9"}, + {KEY_2JOY1+9, "sec_joy10"}, + {KEY_2JOY1+10, "sec_joy11"}, + {KEY_2JOY1+11, "sec_joy12"}, + {KEY_2JOY1+12, "sec_joy13"}, + {KEY_2JOY1+13, "sec_joy14"}, + {KEY_2JOY1+14, "sec_joy15"}, + {KEY_2JOY1+15, "sec_joy16"}, + {KEY_2JOY1+16, "sec_joy17"}, + {KEY_2JOY1+17, "sec_joy18"}, + {KEY_2JOY1+18, "sec_joy19"}, + {KEY_2JOY1+19, "sec_joy20"}, + {KEY_2JOY1+20, "sec_joy21"}, + {KEY_2JOY1+21, "sec_joy22"}, + {KEY_2JOY1+22, "sec_joy23"}, + {KEY_2JOY1+23, "sec_joy24"}, + {KEY_2JOY1+24, "sec_joy25"}, + {KEY_2JOY1+25, "sec_joy26"}, + {KEY_2JOY1+26, "sec_joy27"}, + {KEY_2JOY1+27, "sec_joy28"}, + {KEY_2JOY1+28, "sec_joy29"}, + {KEY_2JOY1+29, "sec_joy30"}, + {KEY_2JOY1+30, "sec_joy31"}, + {KEY_2JOY1+31, "sec_joy32"}, #endif // the DOS version uses Allegro's joystick support - {KEY_2HAT1+0, "SEC_HATUP"}, - {KEY_2HAT1+1, "SEC_HATDOWN"}, - {KEY_2HAT1+2, "SEC_HATLEFT"}, - {KEY_2HAT1+3, "SEC_HATRIGHT"}, - {KEY_2HAT1+4, "SEC_HATUP2"}, - {KEY_2HAT1+5, "SEC_HATDOWN2"}, - {KEY_2HAT1+6, "SEC_HATLEFT2"}, - {KEY_2HAT1+7, "SEC_HATRIGHT2"}, - {KEY_2HAT1+8, "SEC_HATUP3"}, - {KEY_2HAT1+9, "SEC_HATDOWN3"}, - {KEY_2HAT1+10, "SEC_HATLEFT3"}, - {KEY_2HAT1+11, "SEC_HATRIGHT3"}, - {KEY_2HAT1+12, "SEC_HATUP4"}, - {KEY_2HAT1+13, "SEC_HATDOWN4"}, - {KEY_2HAT1+14, "SEC_HATLEFT4"}, - {KEY_2HAT1+15, "SEC_HATRIGHT4"}, + {KEY_2HAT1+0, "sec_hatup"}, + {KEY_2HAT1+1, "sec_hatdown"}, + {KEY_2HAT1+2, "sec_hatleft"}, + {KEY_2HAT1+3, "sec_hatright"}, + {KEY_2HAT1+4, "sec_hatup2"}, + {KEY_2HAT1+5, "sec_hatdown2"}, + {KEY_2HAT1+6, "sec_hatleft2"}, + {KEY_2HAT1+7, "sec_hatright2"}, + {KEY_2HAT1+8, "sec_hatup3"}, + {KEY_2HAT1+9, "sec_hatdown3"}, + {KEY_2HAT1+10, "sec_hatleft3"}, + {KEY_2HAT1+11, "sec_hatright3"}, + {KEY_2HAT1+12, "sec_hatup4"}, + {KEY_2HAT1+13, "sec_hatdown4"}, + {KEY_2HAT1+14, "sec_hatleft4"}, + {KEY_2HAT1+15, "sec_hatright4"}, - {KEY_DBL2JOY1+0, "DBLSEC_JOY1"}, - {KEY_DBL2JOY1+1, "DBLSEC_JOY2"}, - {KEY_DBL2JOY1+2, "DBLSEC_JOY3"}, - {KEY_DBL2JOY1+3, "DBLSEC_JOY4"}, - {KEY_DBL2JOY1+4, "DBLSEC_JOY5"}, - {KEY_DBL2JOY1+5, "DBLSEC_JOY6"}, - {KEY_DBL2JOY1+6, "DBLSEC_JOY7"}, - {KEY_DBL2JOY1+7, "DBLSEC_JOY8"}, + {KEY_DBL2JOY1+0, "dblsec_joy1"}, + {KEY_DBL2JOY1+1, "dblsec_joy2"}, + {KEY_DBL2JOY1+2, "dblsec_joy3"}, + {KEY_DBL2JOY1+3, "dblsec_joy4"}, + {KEY_DBL2JOY1+4, "dblsec_joy5"}, + {KEY_DBL2JOY1+5, "dblsec_joy6"}, + {KEY_DBL2JOY1+6, "dblsec_joy7"}, + {KEY_DBL2JOY1+7, "dblsec_joy8"}, #if !defined (NOMOREJOYBTN_2DBL) - {KEY_DBL2JOY1+8, "DBLSEC_JOY9"}, - {KEY_DBL2JOY1+9, "DBLSEC_JOY10"}, - {KEY_DBL2JOY1+10, "DBLSEC_JOY11"}, - {KEY_DBL2JOY1+11, "DBLSEC_JOY12"}, - {KEY_DBL2JOY1+12, "DBLSEC_JOY13"}, - {KEY_DBL2JOY1+13, "DBLSEC_JOY14"}, - {KEY_DBL2JOY1+14, "DBLSEC_JOY15"}, - {KEY_DBL2JOY1+15, "DBLSEC_JOY16"}, - {KEY_DBL2JOY1+16, "DBLSEC_JOY17"}, - {KEY_DBL2JOY1+17, "DBLSEC_JOY18"}, - {KEY_DBL2JOY1+18, "DBLSEC_JOY19"}, - {KEY_DBL2JOY1+19, "DBLSEC_JOY20"}, - {KEY_DBL2JOY1+20, "DBLSEC_JOY21"}, - {KEY_DBL2JOY1+21, "DBLSEC_JOY22"}, - {KEY_DBL2JOY1+22, "DBLSEC_JOY23"}, - {KEY_DBL2JOY1+23, "DBLSEC_JOY24"}, - {KEY_DBL2JOY1+24, "DBLSEC_JOY25"}, - {KEY_DBL2JOY1+25, "DBLSEC_JOY26"}, - {KEY_DBL2JOY1+26, "DBLSEC_JOY27"}, - {KEY_DBL2JOY1+27, "DBLSEC_JOY28"}, - {KEY_DBL2JOY1+28, "DBLSEC_JOY29"}, - {KEY_DBL2JOY1+29, "DBLSEC_JOY30"}, - {KEY_DBL2JOY1+30, "DBLSEC_JOY31"}, - {KEY_DBL2JOY1+31, "DBLSEC_JOY32"}, + {KEY_DBL2JOY1+8, "dblsec_joy9"}, + {KEY_DBL2JOY1+9, "dblsec_joy10"}, + {KEY_DBL2JOY1+10, "dblsec_joy11"}, + {KEY_DBL2JOY1+11, "dblsec_joy12"}, + {KEY_DBL2JOY1+12, "dblsec_joy13"}, + {KEY_DBL2JOY1+13, "dblsec_joy14"}, + {KEY_DBL2JOY1+14, "dblsec_joy15"}, + {KEY_DBL2JOY1+15, "dblsec_joy16"}, + {KEY_DBL2JOY1+16, "dblsec_joy17"}, + {KEY_DBL2JOY1+17, "dblsec_joy18"}, + {KEY_DBL2JOY1+18, "dblsec_joy19"}, + {KEY_DBL2JOY1+19, "dblsec_joy20"}, + {KEY_DBL2JOY1+20, "dblsec_joy21"}, + {KEY_DBL2JOY1+21, "dblsec_joy22"}, + {KEY_DBL2JOY1+22, "dblsec_joy23"}, + {KEY_DBL2JOY1+23, "dblsec_joy24"}, + {KEY_DBL2JOY1+24, "dblsec_joy25"}, + {KEY_DBL2JOY1+25, "dblsec_joy26"}, + {KEY_DBL2JOY1+26, "dblsec_joy27"}, + {KEY_DBL2JOY1+27, "dblsec_joy28"}, + {KEY_DBL2JOY1+28, "dblsec_joy29"}, + {KEY_DBL2JOY1+29, "dblsec_joy30"}, + {KEY_DBL2JOY1+30, "dblsec_joy31"}, + {KEY_DBL2JOY1+31, "dblsec_joy32"}, #endif - {KEY_DBL2HAT1+0, "DBLSEC_HATUP"}, - {KEY_DBL2HAT1+1, "DBLSEC_HATDOWN"}, - {KEY_DBL2HAT1+2, "DBLSEC_HATLEFT"}, - {KEY_DBL2HAT1+3, "DBLSEC_HATRIGHT"}, - {KEY_DBL2HAT1+4, "DBLSEC_HATUP2"}, - {KEY_DBL2HAT1+5, "DBLSEC_HATDOWN2"}, - {KEY_DBL2HAT1+6, "DBLSEC_HATLEFT2"}, - {KEY_DBL2HAT1+7, "DBLSEC_HATRIGHT2"}, - {KEY_DBL2HAT1+8, "DBLSEC_HATUP3"}, - {KEY_DBL2HAT1+9, "DBLSEC_HATDOWN3"}, - {KEY_DBL2HAT1+10, "DBLSEC_HATLEFT3"}, - {KEY_DBL2HAT1+11, "DBLSEC_HATRIGHT3"}, - {KEY_DBL2HAT1+12, "DBLSEC_HATUP4"}, - {KEY_DBL2HAT1+13, "DBLSEC_HATDOWN4"}, - {KEY_DBL2HAT1+14, "DBLSEC_HATLEFT4"}, - {KEY_DBL2HAT1+15, "DBLSEC_HATRIGHT4"}, + {KEY_DBL2HAT1+0, "dblsec_hatup"}, + {KEY_DBL2HAT1+1, "dblsec_hatdown"}, + {KEY_DBL2HAT1+2, "dblsec_hatleft"}, + {KEY_DBL2HAT1+3, "dblsec_hatright"}, + {KEY_DBL2HAT1+4, "dblsec_hatup2"}, + {KEY_DBL2HAT1+5, "dblsec_hatdown2"}, + {KEY_DBL2HAT1+6, "dblsec_hatleft2"}, + {KEY_DBL2HAT1+7, "dblsec_hatright2"}, + {KEY_DBL2HAT1+8, "dblsec_hatup3"}, + {KEY_DBL2HAT1+9, "dblsec_hatdown3"}, + {KEY_DBL2HAT1+10, "dblsec_hatleft3"}, + {KEY_DBL2HAT1+11, "dblsec_hatright3"}, + {KEY_DBL2HAT1+12, "dblsec_hatup4"}, + {KEY_DBL2HAT1+13, "dblsec_hatdown4"}, + {KEY_DBL2HAT1+14, "dblsec_hatleft4"}, + {KEY_DBL2HAT1+15, "dblsec_hatright4"}, }; From 14403737efa4715ce49effd15a48fcb8c7384eb0 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Thu, 2 Dec 2021 23:15:55 +0100 Subject: [PATCH 642/644] Raise the file upload speed drastically --- src/d_clisrv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index efe6473d4..5aab9c3cf 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -3189,7 +3189,7 @@ consvar_t cv_maxsend = CVAR_INIT ("maxsend", "4096", CV_SAVE|CV_NETVAR, maxsend_ consvar_t cv_noticedownload = CVAR_INIT ("noticedownload", "Off", CV_SAVE|CV_NETVAR, CV_OnOff, NULL); // Speed of file downloading (in packets per tic) -static CV_PossibleValue_t downloadspeed_cons_t[] = {{0, "MIN"}, {32, "MAX"}, {0, NULL}}; +static CV_PossibleValue_t downloadspeed_cons_t[] = {{0, "MIN"}, {300, "MAX"}, {0, NULL}}; consvar_t cv_downloadspeed = CVAR_INIT ("downloadspeed", "16", CV_SAVE|CV_NETVAR, downloadspeed_cons_t, NULL); static void Got_AddPlayer(UINT8 **p, INT32 playernum); From ff037a81608eead67faa44fa4ea1bbbbeb46989c Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Thu, 2 Dec 2021 23:34:28 +0100 Subject: [PATCH 643/644] Remove downloadspeed cruft --- src/d_clisrv.c | 2 +- src/d_netfil.c | 10 +--------- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 5aab9c3cf..47733a3ee 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -3189,7 +3189,7 @@ consvar_t cv_maxsend = CVAR_INIT ("maxsend", "4096", CV_SAVE|CV_NETVAR, maxsend_ consvar_t cv_noticedownload = CVAR_INIT ("noticedownload", "Off", CV_SAVE|CV_NETVAR, CV_OnOff, NULL); // Speed of file downloading (in packets per tic) -static CV_PossibleValue_t downloadspeed_cons_t[] = {{0, "MIN"}, {300, "MAX"}, {0, NULL}}; +static CV_PossibleValue_t downloadspeed_cons_t[] = {{1, "MIN"}, {300, "MAX"}, {0, NULL}}; consvar_t cv_downloadspeed = CVAR_INIT ("downloadspeed", "16", CV_SAVE|CV_NETVAR, downloadspeed_cons_t, NULL); static void Got_AddPlayer(UINT8 **p, INT32 playernum); diff --git a/src/d_netfil.c b/src/d_netfil.c index 12c5ee6a2..daf6271bf 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -925,7 +925,6 @@ static void SV_EndFileSend(INT32 node) filestosend--; } -#define PACKETPERTIC net_bandwidth/(TICRATE*software_MAXPACKETLENGTH) #define FILEFRAGMENTSIZE (software_MAXPACKETLENGTH - (FILETXHEADER + BASEPACKETSIZE)) /** Handles file transmission @@ -958,14 +957,7 @@ void FileSendTicker(void) if (!filestosend) // No file to send return; - if (cv_downloadspeed.value) // New behavior - packetsent = cv_downloadspeed.value; - else // Old behavior - { - packetsent = PACKETPERTIC; - if (!packetsent) - packetsent = 1; - } + packetsent = cv_downloadspeed.value; netbuffer->packettype = PT_FILEFRAGMENT; From a3353be0dce216dd7945a3c2f6af6ac24092e820 Mon Sep 17 00:00:00 2001 From: LZA <73-LZA@users.noreply.git.do.srb2.org> Date: Thu, 2 Dec 2021 22:50:44 +0000 Subject: [PATCH 644/644] Raise addon limit --- src/d_clisrv.c | 547 +++++++++++++++++++++++++++++++++++++------------ src/d_clisrv.h | 18 +- src/d_main.c | 102 +++++---- src/d_net.c | 2 + src/d_netcmd.c | 43 ++-- src/d_netcmd.h | 1 + src/d_netfil.c | 278 +++++++++++++++---------- src/d_netfil.h | 27 ++- src/doomdef.h | 3 + src/filesrch.c | 15 +- src/filesrch.h | 3 - src/m_menu.c | 11 +- src/w_wad.c | 74 ++----- src/w_wad.h | 20 +- 14 files changed, 768 insertions(+), 376 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index efe6473d4..36ced7f64 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -128,10 +128,14 @@ static UINT8 localtextcmd[MAXTEXTCMD]; static UINT8 localtextcmd2[MAXTEXTCMD]; // splitscreen static tic_t neededtic; SINT8 servernode = 0; // the number of the server node + /// \brief do we accept new players? /// \todo WORK! boolean acceptnewnode = true; +static boolean serverisfull = false; //lets us be aware if the server was full after we check files, but before downloading, so we can ask if the user still wants to download or not +static tic_t firstconnectattempttime = 0; + // engine // Must be a power of two @@ -511,18 +515,24 @@ static INT16 Consistancy(void); typedef enum { CL_SEARCHING, + CL_CHECKFILES, CL_DOWNLOADFILES, CL_ASKJOIN, + CL_LOADFILES, CL_WAITJOINRESPONSE, CL_DOWNLOADSAVEGAME, CL_CONNECTED, - CL_ABORTED + CL_ABORTED, + CL_ASKFULLFILELIST, + CL_CONFIRMCONNECT } cl_mode_t; static void GetPackets(void); static cl_mode_t cl_mode = CL_SEARCHING; +static UINT16 cl_lastcheckedfilecount = 0; // used for full file list + #ifndef NONET #define SNAKE_SPEED 5 @@ -920,6 +930,8 @@ static void Snake_Draw(void) INT16 i; // Background + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); + V_DrawFlatFill( SNAKE_LEFT_X + SNAKE_BORDER_SIZE, SNAKE_TOP_Y + SNAKE_BORDER_SIZE, @@ -1021,6 +1033,13 @@ static void Snake_Draw(void) ); } +static void CL_DrawConnectionStatusBox(void) +{ + M_DrawTextBox(BASEVIDWIDTH/2-128-8, BASEVIDHEIGHT-16-8, 32, 1); + if (cl_mode != CL_CONFIRMCONNECT) + V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-16-16, V_YELLOWMAP, "Press ESC to abort"); +} + // // CL_DrawConnectionStatus // @@ -1031,28 +1050,32 @@ static inline void CL_DrawConnectionStatus(void) INT32 ccstime = I_GetTime(); // Draw background fade - if (!menuactive) // menu already draws its own fade - V_DrawFadeScreen(0xFF00, 16); // force default + V_DrawFadeScreen(0xFF00, 16); // force default - // Draw the bottom box. - M_DrawTextBox(BASEVIDWIDTH/2-128-8, BASEVIDHEIGHT-16-8, 32, 1); - V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-16-16, V_YELLOWMAP, "Press ESC to abort"); - - if (cl_mode != CL_DOWNLOADFILES) + if (cl_mode != CL_DOWNLOADFILES && cl_mode != CL_LOADFILES) { INT32 i, animtime = ((ccstime / 4) & 15) + 16; - UINT8 palstart = (cl_mode == CL_SEARCHING) ? 32 : 96; - // 15 pal entries total. + UINT8 palstart; const char *cltext; + // Draw the bottom box. + CL_DrawConnectionStatusBox(); + + if (cl_mode == CL_SEARCHING) + palstart = 32; // Red + else if (cl_mode == CL_CONFIRMCONNECT) + palstart = 48; // Orange + else + palstart = 96; // Green + if (!(cl_mode == CL_DOWNLOADSAVEGAME && lastfilenum != -1)) - for (i = 0; i < 16; ++i) + for (i = 0; i < 16; ++i) // 15 pal entries total. V_DrawFill((BASEVIDWIDTH/2-128) + (i * 16), BASEVIDHEIGHT-16, 16, 8, palstart + ((animtime - i) & 15)); switch (cl_mode) { case CL_DOWNLOADSAVEGAME: - if (lastfilenum != -1) + if (fileneeded && lastfilenum != -1) { UINT32 currentsize = fileneeded[lastfilenum].currentsize; UINT32 totalsize = fileneeded[lastfilenum].totalsize; @@ -1076,9 +1099,22 @@ static inline void CL_DrawConnectionStatus(void) else cltext = M_GetText("Waiting to download game state..."); break; + case CL_ASKFULLFILELIST: + case CL_CHECKFILES: + cltext = M_GetText("Checking server addon list..."); + break; + case CL_CONFIRMCONNECT: + cltext = ""; + break; + case CL_LOADFILES: + cltext = M_GetText("Loading server addons..."); + break; case CL_ASKJOIN: case CL_WAITJOINRESPONSE: - cltext = M_GetText("Requesting to join..."); + if (serverisfull) + cltext = M_GetText("Server full, waiting for a slot..."); + else + cltext = M_GetText("Requesting to join..."); break; default: cltext = M_GetText("Connecting to server..."); @@ -1088,14 +1124,51 @@ static inline void CL_DrawConnectionStatus(void) } else { - if (lastfilenum != -1) + if (cl_mode == CL_LOADFILES) + { + INT32 totalfileslength; + INT32 loadcompletednum = 0; + INT32 i; + + V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-16-16, V_YELLOWMAP, "Press ESC to abort"); + + //ima just count files here + if (fileneeded) + { + for (i = 0; i < fileneedednum; i++) + if (fileneeded[i].status == FS_OPEN) + loadcompletednum++; + } + + // Loading progress + V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-16-24, V_YELLOWMAP, "Loading server addons..."); + totalfileslength = (INT32)((loadcompletednum/(double)(fileneedednum)) * 256); + M_DrawTextBox(BASEVIDWIDTH/2-128-8, BASEVIDHEIGHT-16-8, 32, 1); + V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-16, 256, 8, 111); + V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-16, totalfileslength, 8, 96); + V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-16, V_20TRANS|V_MONOSPACE, + va(" %2u/%2u Files",loadcompletednum,fileneedednum)); + } + else if (lastfilenum != -1) { INT32 dldlength; static char tempname[28]; - fileneeded_t *file = &fileneeded[lastfilenum]; - char *filename = file->filename; + fileneeded_t *file; + char *filename; - Snake_Draw(); + if (snake) + Snake_Draw(); + + // Draw the bottom box. + CL_DrawConnectionStatusBox(); + + if (fileneeded) + { + file = &fileneeded[lastfilenum]; + filename = file->filename; + } + else + return; Net_GetNetStat(); dldlength = (INT32)((file->currentsize/(double)file->totalsize) * 256); @@ -1128,20 +1201,32 @@ static inline void CL_DrawConnectionStatus(void) va("%3.1fK/s ", ((double)getbps)/1024)); } else + { + if (snake) + Snake_Draw(); + + CL_DrawConnectionStatusBox(); V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-16-24, V_YELLOWMAP, M_GetText("Waiting to download files...")); + } } } #endif +static boolean CL_AskFileList(INT32 firstfile) +{ + netbuffer->packettype = PT_TELLFILESNEEDED; + netbuffer->u.filesneedednum = firstfile; + + return HSendPacket(servernode, false, 0, sizeof (INT32)); +} + /** Sends a special packet to declare how many players in local * Used only in arbitratrenetstart() * Sends a PT_CLIENTJOIN packet to the server * * \return True if the packet was successfully sent * \todo Improve the description... - * Because to be honest, I have no idea what arbitratrenetstart is... - * Is it even used...? * */ static boolean CL_SendJoin(void) @@ -1240,7 +1325,7 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime) sizeof netbuffer->u.serverinfo.gametypename); netbuffer->u.serverinfo.modifiedgame = (UINT8)modifiedgame; netbuffer->u.serverinfo.cheatsenabled = CV_CheatsEnabled(); - netbuffer->u.serverinfo.isdedicated = (UINT8)dedicated; + netbuffer->u.serverinfo.flags = (dedicated ? SV_DEDICATED : 0); strncpy(netbuffer->u.serverinfo.servername, cv_servername.string, MAXSERVERNAME); strncpy(netbuffer->u.serverinfo.mapname, G_BuildMapName(gamemap), 7); @@ -1275,7 +1360,7 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime) if (mapheaderinfo[gamemap-1]) netbuffer->u.serverinfo.actnum = mapheaderinfo[gamemap-1]->actnum; - p = PutFileNeeded(); + p = PutFileNeeded(0); HSendPacket(node, false, 0, p - ((UINT8 *)&netbuffer->u)); } @@ -1526,6 +1611,8 @@ static void CL_LoadReceivedSavegame(boolean reloading) size_t length, decompressedlen; char tmpsave[256]; + FreeFileNeeded(); + sprintf(tmpsave, "%s" PATHSEP TMPSAVENAME, srb2home); length = FIL_ReadFile(tmpsave, &savebuffer); @@ -1836,12 +1923,164 @@ void CL_UpdateServerList(boolean internetsearch, INT32 room) #endif/*MASTERSERVER*/ } -static const char * InvalidServerReason (INT32 i) +#endif // ifndef NONET + +static void M_ConfirmConnect(event_t *ev) +{ +#ifndef NONET + if (ev->type == ev_keydown) + { + if (ev->key == ' ' || ev->key == 'y' || ev->key == KEY_ENTER) + { + if (totalfilesrequestednum > 0) + { + if (CL_SendFileRequest()) + { + cl_mode = CL_DOWNLOADFILES; + Snake_Initialise(); + } + } + else + cl_mode = CL_LOADFILES; + + M_ClearMenus(true); + } + else if (ev->key == 'n' || ev->key == KEY_ESCAPE) + { + cl_mode = CL_ABORTED; + M_ClearMenus(true); + } + } +#else + (void)ev; +#endif +} + +static boolean CL_FinishedFileList(void) +{ + INT32 i; + char *downloadsize = NULL; + //CONS_Printf(M_GetText("Checking files...\n")); + i = CL_CheckFiles(); + if (i == 4) // still checking ... + { + return true; + } + else if (i == 3) // too many files + { + D_QuitNetGame(); + CL_Reset(); + D_StartTitle(); + M_StartMessage(M_GetText( + "You have too many WAD files loaded\n" + "to add ones the server is using.\n" + "Please restart SRB2 before connecting.\n\n" + "Press ESC\n" + ), NULL, MM_NOTHING); + return false; + } + else if (i == 2) // cannot join for some reason + { + D_QuitNetGame(); + CL_Reset(); + D_StartTitle(); + M_StartMessage(M_GetText( + "You have the wrong addons loaded.\n\n" + "To play on this server, restart\n" + "the game and don't load any addons.\n" + "SRB2 will automatically add\n" + "everything you need when you join.\n\n" + "Press ESC\n" + ), NULL, MM_NOTHING); + return false; + } + else if (i == 1) + { + if (serverisfull) + { + M_StartMessage(M_GetText( + "This server is full!\n" + "\n" + "You may load server addons (if any), and wait for a slot.\n" + "\n" + "Press ENTER to continue\nor ESC to cancel.\n\n" + ), M_ConfirmConnect, MM_EVENTHANDLER); + cl_mode = CL_CONFIRMCONNECT; + curfadevalue = 0; + } + else + cl_mode = CL_LOADFILES; + } + else + { + // must download something + // can we, though? + if (!CL_CheckDownloadable()) // nope! + { + D_QuitNetGame(); + CL_Reset(); + D_StartTitle(); + M_StartMessage(M_GetText( + "An error occured when trying to\n" + "download missing addons.\n" + "(This is almost always a problem\n" + "with the server, not your game.)\n\n" + "See the console or log file\n" + "for additional details.\n\n" + "Press ESC\n" + ), NULL, MM_NOTHING); + return false; + } + +#ifndef NONET + downloadcompletednum = 0; + downloadcompletedsize = 0; + totalfilesrequestednum = 0; + totalfilesrequestedsize = 0; + + if (fileneeded == NULL) + I_Error("CL_FinishedFileList: fileneeded == NULL"); + + for (i = 0; i < fileneedednum; i++) + if (fileneeded[i].status == FS_NOTFOUND || fileneeded[i].status == FS_MD5SUMBAD) + { + totalfilesrequestednum++; + totalfilesrequestedsize += fileneeded[i].totalsize; + } + + if (totalfilesrequestedsize>>20 >= 100) + downloadsize = Z_StrDup(va("%uM",totalfilesrequestedsize>>20)); + else + downloadsize = Z_StrDup(va("%uK",totalfilesrequestedsize>>10)); +#endif + + if (serverisfull) + M_StartMessage(va(M_GetText( + "This server is full!\n" + "Download of %s additional content\nis required to join.\n" + "\n" + "You may download, load server addons,\nand wait for a slot.\n" + "\n" + "Press ENTER to continue\nor ESC to cancel.\n" + ), downloadsize), M_ConfirmConnect, MM_EVENTHANDLER); + else + M_StartMessage(va(M_GetText( + "Download of %s additional content\nis required to join.\n" + "\n" + "Press ENTER to continue\nor ESC to cancel.\n" + ), downloadsize), M_ConfirmConnect, MM_EVENTHANDLER); + + Z_Free(downloadsize); + cl_mode = CL_CONFIRMCONNECT; + curfadevalue = 0; + } + return true; +} + +static const char * InvalidServerReason (serverinfo_pak *info) { #define EOT "\nPress ESC\n" - serverinfo_pak *info = &serverlist[i].info; - /* magic number for new packet format */ if (info->_255 != 255) { @@ -1902,8 +2141,6 @@ static const char * InvalidServerReason (INT32 i) #undef EOT } -#endif // ifndef NONET - /** Called by CL_ServerConnectionTicker * * \param asksent The last time we asked the server to join. We re-ask every second in case our request got lost in transmit. @@ -1936,86 +2173,44 @@ static boolean CL_ServerConnectionSearchTicker(tic_t *asksent) if (client) { - const char *reason = InvalidServerReason(i); + serverinfo_pak *info = &serverlist[i].info; - // Quit here rather than downloading files - // and being refused later. - if (reason) - { - char *message = Z_StrDup(reason); - D_QuitNetGame(); - CL_Reset(); - D_StartTitle(); - M_StartMessage(message, NULL, MM_NOTHING); - Z_Free(message); - return false; - } - - D_ParseFileneeded(serverlist[i].info.fileneedednum, - serverlist[i].info.fileneeded); - CONS_Printf(M_GetText("Checking files...\n")); - i = CL_CheckFiles(); - if (i == 3) // too many files - { - D_QuitNetGame(); - CL_Reset(); - D_StartTitle(); - M_StartMessage(M_GetText( - "You have too many WAD files loaded\n" - "to add ones the server is using.\n" - "Please restart SRB2 before connecting.\n\n" - "Press ESC\n" - ), NULL, MM_NOTHING); - return false; - } - else if (i == 2) // cannot join for some reason - { - D_QuitNetGame(); - CL_Reset(); - D_StartTitle(); - M_StartMessage(M_GetText( - "You have the wrong addons loaded.\n\n" - "To play on this server, restart\n" - "the game and don't load any addons.\n" - "SRB2 will automatically add\n" - "everything you need when you join.\n\n" - "Press ESC\n" - ), NULL, MM_NOTHING); - return false; - } - else if (i == 1) - cl_mode = CL_ASKJOIN; + if (info->refusereason == REFUSE_SLOTS_FULL) + serverisfull = true; else { - // must download something - // can we, though? - if (!CL_CheckDownloadable()) // nope! + const char *reason = InvalidServerReason(info); + + // Quit here rather than downloading files + // and being refused later. + if (reason) { + char *message = Z_StrDup(reason); D_QuitNetGame(); CL_Reset(); D_StartTitle(); - M_StartMessage(M_GetText( - "You cannot connect to this server\n" - "because you cannot download the files\n" - "that you are missing from the server.\n\n" - "See the console or log file for\n" - "more details.\n\n" - "Press ESC\n" - ), NULL, MM_NOTHING); + M_StartMessage(message, NULL, MM_NOTHING); + Z_Free(message); return false; } - // no problem if can't send packet, we will retry later - if (CL_SendFileRequest()) - { - cl_mode = CL_DOWNLOADFILES; -#ifndef NONET - Snake_Initialise(); -#endif - } } + + D_ParseFileneeded(info->fileneedednum, info->fileneeded, 0); + + if (info->flags & SV_LOTSOFADDONS) + { + cl_mode = CL_ASKFULLFILELIST; + cl_lastcheckedfilecount = 0; + return true; + } + + cl_mode = CL_CHECKFILES; } else + { cl_mode = CL_ASKJOIN; // files need not be checked for the server. + *asksent = 0; + } return true; } @@ -2061,6 +2256,22 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic return false; break; + case CL_ASKFULLFILELIST: + if (cl_lastcheckedfilecount == UINT16_MAX) // All files retrieved + cl_mode = CL_CHECKFILES; + else if (fileneedednum != cl_lastcheckedfilecount || I_GetTime() >= *asksent) + { + if (CL_AskFileList(fileneedednum)) + { + cl_lastcheckedfilecount = fileneedednum; + *asksent = I_GetTime() + NEWTICRATE; + } + } + break; + case CL_CHECKFILES: + if (!CL_FinishedFileList()) + return false; + break; case CL_DOWNLOADFILES: waitmore = false; for (i = 0; i < fileneedednum; i++) @@ -2081,21 +2292,51 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic } #endif - cl_mode = CL_ASKJOIN; // don't break case continue to cljoin request now - /* FALLTHRU */ - + cl_mode = CL_LOADFILES; + break; + case CL_LOADFILES: + if (CL_LoadServerFiles()) + { + FreeFileNeeded(); + *asksent = 0; //This ensure the first join ask is right away + firstconnectattempttime = I_GetTime(); + cl_mode = CL_ASKJOIN; + } + break; case CL_ASKJOIN: - CL_LoadServerFiles(); + if (firstconnectattempttime + NEWTICRATE*300 < I_GetTime() && !server) + { + CONS_Printf(M_GetText("5 minute wait time exceeded.\n")); + CONS_Printf(M_GetText("Network game synchronization aborted.\n")); + D_QuitNetGame(); + CL_Reset(); + D_StartTitle(); + M_StartMessage(M_GetText( + "5 minute wait time exceeded.\n" + "You may retry connection.\n" + "\n" + "Press ESC\n" + ), NULL, MM_NOTHING); + return false; + } #ifndef NONET // prepare structures to save the file // WARNING: this can be useless in case of server not in GS_LEVEL // but since the network layer doesn't provide ordered packets... CL_PrepareDownloadSaveGame(tmpsave); #endif - if (CL_SendJoin()) + if (I_GetTime() >= *asksent && CL_SendJoin()) + { + *asksent = I_GetTime() + NEWTICRATE*3; cl_mode = CL_WAITJOINRESPONSE; + } + break; + case CL_WAITJOINRESPONSE: + if (I_GetTime() >= *asksent) + { + cl_mode = CL_ASKJOIN; + } break; - #ifndef NONET case CL_DOWNLOADSAVEGAME: // At this state, the first (and only) needed file is the gamestate @@ -2109,8 +2350,8 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic break; #endif - case CL_WAITJOINRESPONSE: case CL_CONNECTED: + case CL_CONFIRMCONNECT: //logic is handled by M_ConfirmConnect default: break; @@ -2118,7 +2359,6 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic case CL_ABORTED: cl_mode = CL_SEARCHING; return false; - } GetPackets(); @@ -2128,13 +2368,19 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic if (*oldtic != I_GetTime()) { I_OsPolling(); - for (; eventtail != eventhead; eventtail = (eventtail+1) & (MAXEVENTS-1)) - G_MapEventsToControls(&events[eventtail]); - if (gamekeydown[KEY_ESCAPE] || gamekeydown[KEY_JOY1+1]) + if (cl_mode == CL_CONFIRMCONNECT) + D_ProcessEvents(); //needed for menu system to receive inputs + else + { + for (; eventtail != eventhead; eventtail = (eventtail+1) & (MAXEVENTS-1)) + G_MapEventsToControls(&events[eventtail]); + } + + if (gamekeydown[KEY_ESCAPE] || gamekeydown[KEY_JOY1+1] || cl_mode == CL_ABORTED) { CONS_Printf(M_GetText("Network game synchronization aborted.\n")); -// M_StartMessage(M_GetText("Network game synchronization aborted.\n\nPress ESC\n"), NULL, MM_NOTHING); + M_StartMessage(M_GetText("Network game synchronization aborted.\n\nPress ESC\n"), NULL, MM_NOTHING); #ifndef NONET if (snake) @@ -2167,13 +2413,20 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic #ifndef NONET if (client && cl_mode != CL_CONNECTED && cl_mode != CL_ABORTED) { - if (cl_mode != CL_DOWNLOADFILES && cl_mode != CL_DOWNLOADSAVEGAME) + if (!snake) { F_MenuPresTicker(true); // title sky F_TitleScreenTicker(true); F_TitleScreenDrawer(); } CL_DrawConnectionStatus(); +#ifdef HAVE_THREADS + I_lock_mutex(&m_menu_mutex); +#endif + M_Drawer(); //Needed for drawing messageboxes on the connection screen +#ifdef HAVE_THREADS + I_unlock_mutex(m_menu_mutex); +#endif I_UpdateNoVsync(); // page flip or blit buffer if (moviemode) M_SaveFrame(); @@ -2235,8 +2488,10 @@ static void CL_ConnectToServer(void) ClearAdminPlayers(); pnumnodes = 1; oldtic = I_GetTime() - 1; + #ifndef NONET asksent = (tic_t) - TICRATE; + firstconnectattempttime = I_GetTime(); i = SL_SearchServer(servernode); @@ -2676,8 +2931,16 @@ void CL_Reset(void) SV_ResetServer(); // make sure we don't leave any fileneeded gunk over from a failed join + FreeFileNeeded(); fileneedednum = 0; - memset(fileneeded, 0, sizeof(fileneeded)); + +#ifndef NONET + totalfilesrequestednum = 0; + totalfilesrequestedsize = 0; +#endif + firstconnectattempttime = 0; + serverisfull = false; + connectiontimeout = (tic_t)cv_nettimeout.value; //reset this temporary hack // D_StartTitle should get done now, but the calling function will handle it } @@ -3968,31 +4231,40 @@ static void HandlePacketFromAwayNode(SINT8 node) switch (netbuffer->packettype) { case PT_ASKINFOVIAMS: -#if 0 + Net_CloseConnection(node); + break; + + case PT_TELLFILESNEEDED: if (server && serverrunning) { - INT32 clientnode; - if (ms_RoomId < 0) // ignore if we're not actually on the MS right now - { - Net_CloseConnection(node); // and yes, close connection - return; - } - clientnode = I_NetMakeNode(netbuffer->u.msaskinfo.clientaddr); - if (clientnode != -1) - { - SV_SendServerInfo(clientnode, (tic_t)LONG(netbuffer->u.msaskinfo.time)); - SV_SendPlayerInfo(clientnode); // Send extra info - Net_CloseConnection(clientnode); - // Don't close connection to MS... - } - else - Net_CloseConnection(node); // ...unless the IP address is not valid + UINT8 *p; + INT32 firstfile = netbuffer->u.filesneedednum; + + netbuffer->packettype = PT_MOREFILESNEEDED; + netbuffer->u.filesneededcfg.first = firstfile; + netbuffer->u.filesneededcfg.more = 0; + + p = PutFileNeeded(firstfile); + + HSendPacket(node, false, 0, p - ((UINT8 *)&netbuffer->u)); + } + else // Shouldn't get this if you aren't the server...? + Net_CloseConnection(node); + break; + + case PT_MOREFILESNEEDED: + if (server && serverrunning) + { // But wait I thought I'm the server? + Net_CloseConnection(node); + break; + } + SERVERONLY + if (cl_mode == CL_ASKFULLFILELIST && netbuffer->u.filesneededcfg.first == fileneedednum) + { + D_ParseFileneeded(netbuffer->u.filesneededcfg.num, netbuffer->u.filesneededcfg.files, netbuffer->u.filesneededcfg.first); + if (!netbuffer->u.filesneededcfg.more) + cl_lastcheckedfilecount = UINT16_MAX; // Got the whole file list } - else - Net_CloseConnection(node); // you're not supposed to get it, so ignore it -#else - Net_CloseConnection(node); -#endif break; case PT_ASKINFO: @@ -4018,13 +4290,24 @@ static void HandlePacketFromAwayNode(SINT8 node) if (!reason) I_Error("Out of memory!\n"); - D_QuitNetGame(); - CL_Reset(); - D_StartTitle(); + if (strstr(reason, "Maximum players reached")) + { + serverisfull = true; + //Special timeout for when refusing due to player cap. The client will wait 3 seconds between join requests when waiting for a slot, so we need this to be much longer + //We set it back to the value of cv_nettimeout.value in CL_Reset + connectiontimeout = NEWTICRATE*7; + cl_mode = CL_ASKJOIN; + free(reason); + break; + } M_StartMessage(va(M_GetText("Server refuses connection\n\nReason:\n%s"), reason), NULL, MM_NOTHING); + D_QuitNetGame(); + CL_Reset(); + D_StartTitle(); + free(reason); // Will be reset by caller. Signals refusal. diff --git a/src/d_clisrv.h b/src/d_clisrv.h index a89c054e1..8e75fb963 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -94,6 +94,9 @@ typedef enum PT_LOGIN, // Login attempt from the client. + PT_TELLFILESNEEDED, // Client, to server: "what other files do I need starting from this number?" + PT_MOREFILESNEEDED, // Server, to client: "you need these (+ more on top of those)" + PT_PING, // Packet sent to tell clients the other client's latency to server. NUMPACKETTYPE } packettype_t; @@ -198,6 +201,9 @@ typedef struct char names[MAXSPLITSCREENPLAYERS][MAXPLAYERNAME]; } ATTRPACK clientconfig_pak; +#define SV_DEDICATED 0x40 // server is dedicated +#define SV_LOTSOFADDONS 0x20 // flag used to ask for full file list in d_netfil + enum { REFUSE_JOINS_DISABLED = 1, REFUSE_SLOTS_FULL, @@ -225,7 +231,7 @@ typedef struct char gametypename[24]; UINT8 modifiedgame; UINT8 cheatsenabled; - UINT8 isdedicated; + UINT8 flags; UINT8 fileneedednum; tic_t time; tic_t leveltime; @@ -279,6 +285,14 @@ typedef struct UINT8 ctfteam; } ATTRPACK plrconfig; +typedef struct +{ + INT32 first; + UINT8 num; + UINT8 more; + UINT8 files[MAXFILENEEDED]; // is filled with writexxx (byteptr.h) +} ATTRPACK filesneededconfig_pak; + // // Network packet data // @@ -308,6 +322,8 @@ typedef struct msaskinfo_pak msaskinfo; // 22 bytes plrinfo playerinfo[MAXPLAYERS]; // 576 bytes(?) plrconfig playerconfig[MAXPLAYERS]; // (up to) 528 bytes(?) + INT32 filesneedednum; // 4 bytes + filesneededconfig_pak filesneededcfg; // ??? bytes UINT32 pingtable[MAXPLAYERS+1]; // 68 bytes } u; // This is needed to pack diff packet types data together } ATTRPACK doomdata_t; diff --git a/src/d_main.c b/src/d_main.c index 679a596b3..15f85f2e8 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -65,7 +65,7 @@ #include "m_cond.h" // condition initialization #include "fastcmp.h" #include "keys.h" -#include "filesrch.h" // refreshdirmenu, mainwadstally +#include "filesrch.h" // refreshdirmenu #include "g_input.h" // tutorial mode control scheming #include "m_perfstats.h" @@ -96,11 +96,8 @@ int SUBVERSION; // platform independant focus loss UINT8 window_notinfocus = false; -// -// DEMO LOOP -// -static char *startupwadfiles[MAX_WADFILES]; -static char *startuppwads[MAX_WADFILES]; +static addfilelist_t startupwadfiles; +static addfilelist_t startuppwads; boolean devparm = false; // started game with -devparm @@ -119,6 +116,9 @@ boolean midi_disabled = false; boolean sound_disabled = false; boolean digital_disabled = false; +// +// DEMO LOOP +// boolean advancedemo; #ifdef DEBUGFILE INT32 debugload = 0; @@ -923,51 +923,68 @@ void D_StartTitle(void) tutorialmode = false; } -// -// D_AddFile -// -static void D_AddFile(char **list, const char *file) -{ - size_t pnumwadfiles; - char *newfile; +#define REALLOC_FILE_LIST \ + if (list->files == NULL) \ + { \ + list->files = calloc(sizeof(list->files), 2); \ + list->numfiles = 1; \ + } \ + else \ + { \ + index = list->numfiles; \ + list->files = realloc(list->files, sizeof(list->files) * ((++list->numfiles) + 1)); \ + if (list->files == NULL) \ + I_Error("%s: No more free memory to add file %s", __FUNCTION__, file); \ + } - for (pnumwadfiles = 0; list[pnumwadfiles]; pnumwadfiles++) - ; +static void D_AddFile(addfilelist_t *list, const char *file) +{ + char *newfile; + size_t index = 0; + + REALLOC_FILE_LIST newfile = malloc(strlen(file) + 1); if (!newfile) - I_Error("No more free memory to AddFile %s",file); + I_Error("D_AddFile: No more free memory to add file %s", file); strcpy(newfile, file); - list[pnumwadfiles] = newfile; + list->files[index] = newfile; } -static void D_AddFolder(char **list, const char *file) +static void D_AddFolder(addfilelist_t *list, const char *file) { - size_t pnumwadfiles; char *newfile; + size_t index = 0; - for (pnumwadfiles = 0; list[pnumwadfiles]; pnumwadfiles++) - ; + REALLOC_FILE_LIST newfile = malloc(strlen(file) + 2); // Path delimiter + NULL terminator if (!newfile) - I_Error("No more free memory to AddFolder %s",file); + I_Error("D_AddFolder: No more free memory to add folder %s", file); strcpy(newfile, file); strcat(newfile, PATHSEP); - list[pnumwadfiles] = newfile; + list->files[index] = newfile; } -static inline void D_CleanFile(char **list) +#undef REALLOC_FILE_LIST + +static inline void D_CleanFile(addfilelist_t *list) { - size_t pnumwadfiles; - for (pnumwadfiles = 0; list[pnumwadfiles]; pnumwadfiles++) + if (list->files) { - free(list[pnumwadfiles]); - list[pnumwadfiles] = NULL; + size_t pnumwadfiles = 0; + + for (; pnumwadfiles < list->numfiles; pnumwadfiles++) + free(list->files[pnumwadfiles]); + + free(list->files); + list->files = NULL; } + + list->numfiles = 0; } ///\brief Checks if a netgame URL is being handled, and changes working directory to the EXE's if so. @@ -1051,7 +1068,7 @@ static void IdentifyVersion(void) // Load the IWAD if (srb2wad != NULL && FIL_ReadFileOK(srb2wad)) - D_AddFile(startupwadfiles, srb2wad); + D_AddFile(&startupwadfiles, srb2wad); else I_Error("srb2.pk3 not found! Expected in %s, ss file: %s\n", srb2waddir, srb2wad); @@ -1062,14 +1079,14 @@ static void IdentifyVersion(void) // checking in D_SRB2Main // Add the maps - D_AddFile(startupwadfiles, va(pandf,srb2waddir,"zones.pk3")); + D_AddFile(&startupwadfiles, va(pandf,srb2waddir, "zones.pk3")); // Add the players - D_AddFile(startupwadfiles, va(pandf,srb2waddir, "player.dta")); + D_AddFile(&startupwadfiles, va(pandf,srb2waddir, "player.dta")); #ifdef USE_PATCH_DTA // Add our crappy patches to fix our bugs - D_AddFile(startupwadfiles, va(pandf,srb2waddir,"patch.pk3")); + D_AddFile(&startupwadfiles, va(pandf,srb2waddir, "patch.pk3")); #endif #if !defined (HAVE_SDL) || defined (HAVE_MIXER) @@ -1079,7 +1096,7 @@ static void IdentifyVersion(void) const char *musicpath = va(pandf,srb2waddir,str);\ int ms = W_VerifyNMUSlumps(musicpath, false); \ if (ms == 1) \ - D_AddFile(startupwadfiles, musicpath); \ + D_AddFile(&startupwadfiles, musicpath); \ else if (ms == 0) \ I_Error("File "str" has been modified with non-music/sound lumps"); \ } @@ -1269,9 +1286,9 @@ void D_SRB2Main(void) else if (myargv[i][0] == '-' || myargv[i][0] == '+') addontype = 0; else if (addontype == 1) - D_AddFile(startuppwads, myargv[i]); + D_AddFile(&startuppwads, myargv[i]); else if (addontype == 2) - D_AddFolder(startuppwads, myargv[i]); + D_AddFolder(&startuppwads, myargv[i]); } } @@ -1310,8 +1327,8 @@ void D_SRB2Main(void) // load wad, including the main wad file CONS_Printf("W_InitMultipleFiles(): Adding IWAD and main PWADs.\n"); - W_InitMultipleFiles(startupwadfiles); - D_CleanFile(startupwadfiles); + W_InitMultipleFiles(&startupwadfiles); + D_CleanFile(&startupwadfiles); #ifndef DEVELOP // md5s last updated 22/02/20 (ddmmyy) @@ -1326,8 +1343,6 @@ void D_SRB2Main(void) // ...except it does if they slip maps in there, and that's what W_VerifyNMUSlumps is for. #endif //ifndef DEVELOP - mainwadstally = packetsizetally; // technically not accurate atm, remember to port the two-stage -file process from kart in 2.2.x - cht_Init(); //---------------------------------------------------- READY SCREEN @@ -1360,9 +1375,12 @@ void D_SRB2Main(void) CON_StopRefresh(); // Temporarily stop refreshing the screen for wad loading - CONS_Printf("W_InitMultipleFiles(): Adding extra PWADs.\n"); - W_InitMultipleFiles(startuppwads); - D_CleanFile(startuppwads); + if (startuppwads.numfiles) + { + CONS_Printf("W_InitMultipleFiles(): Adding extra PWADs.\n"); + W_InitMultipleFiles(&startuppwads); + D_CleanFile(&startuppwads); + } CON_StartRefresh(); // Restart the refresh! diff --git a/src/d_net.c b/src/d_net.c index 9e5abe24a..3a4746002 100644 --- a/src/d_net.c +++ b/src/d_net.c @@ -815,6 +815,8 @@ static const char *packettypename[NUMPACKETTYPE] = "CLIENTJOIN", "NODETIMEOUT", "LOGIN", + "TELLFILESNEEDED", + "MOREFILESNEEDED", "PING" }; diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 5eb360bef..7024e64fb 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -3223,7 +3223,7 @@ static void Command_RunSOC(void) static void Got_RunSOCcmd(UINT8 **cp, INT32 playernum) { char filename[256]; - filestatus_t ncs = FS_NOTFOUND; + filestatus_t ncs = FS_NOTCHECKED; if (playernum != serverplayer && !IsPlayerAdmin(playernum)) { @@ -3347,10 +3347,9 @@ static void Command_Addfile(void) break; ++p; - // check total packet size and no of files currently loaded - // See W_InitFile in w_wad.c - if ((numwadfiles >= MAX_WADFILES) - || ((packetsizetally + nameonlylength(fn) + FILENEEDEDSIZE) > MAXFILENEEDED*sizeof(UINT8))) + // check no of files currently loaded + // See W_LoadWadFile in w_wad.c + if (numwadfiles >= MAX_WADFILES) { CONS_Alert(CONS_ERROR, M_GetText("Too many files loaded to add %s\n"), fn); return; @@ -3379,6 +3378,9 @@ static void Command_Addfile(void) for (i = 0; i < numwadfiles; i++) { + if (wadfiles[i]->type == RET_FOLDER) + continue; + if (!memcmp(wadfiles[i]->md5sum, md5sum, 16)) { CONS_Alert(CONS_ERROR, M_GetText("%s is already loaded\n"), fn); @@ -3469,10 +3471,9 @@ static void Command_Addfolder(void) continue; } - // check total packet size and no of files currently loaded - // See W_InitFile in w_wad.c - if ((numwadfiles >= MAX_WADFILES) - || ((packetsizetally + strlen(fn) + FILENEEDEDSIZE) > MAXFILENEEDED*sizeof(UINT8))) + // check no of files currently loaded + // See W_LoadWadFile in w_wad.c + if (numwadfiles >= MAX_WADFILES) { CONS_Alert(CONS_ERROR, M_GetText("Too many files loaded to add %s\n"), fn); return; @@ -3534,7 +3535,7 @@ static void Command_Addfolder(void) static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum) { char filename[241]; - filestatus_t ncs = FS_NOTFOUND; + filestatus_t ncs = FS_NOTCHECKED; UINT8 md5sum[16]; boolean kick = false; boolean toomany = false; @@ -3559,9 +3560,7 @@ static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum) return; } - // See W_InitFile in w_wad.c - if ((numwadfiles >= MAX_WADFILES) - || ((packetsizetally + nameonlylength(filename) + FILENEEDEDSIZE) > MAXFILENEEDED*sizeof(UINT8))) + if (numwadfiles >= MAX_WADFILES) toomany = true; else ncs = findfile(filename,md5sum,true); @@ -3594,7 +3593,7 @@ static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum) static void Got_RequestAddfoldercmd(UINT8 **cp, INT32 playernum) { char path[241]; - filestatus_t ncs = FS_NOTFOUND; + filestatus_t ncs = FS_NOTCHECKED; boolean kick = false; boolean toomany = false; INT32 i,j; @@ -3619,9 +3618,7 @@ static void Got_RequestAddfoldercmd(UINT8 **cp, INT32 playernum) return; } - // See W_InitFile in w_wad.c - if ((numwadfiles >= MAX_WADFILES) - || ((packetsizetally + strlen(path) + FILENEEDEDSIZE) > MAXFILENEEDED*sizeof(UINT8))) + if (numwadfiles >= MAX_WADFILES) toomany = true; else ncs = findfolder(path); @@ -3652,7 +3649,7 @@ static void Got_RequestAddfoldercmd(UINT8 **cp, INT32 playernum) static void Got_Addfilecmd(UINT8 **cp, INT32 playernum) { char filename[241]; - filestatus_t ncs = FS_NOTFOUND; + filestatus_t ncs = FS_NOTCHECKED; UINT8 md5sum[16]; READSTRINGN(*cp, filename, 240); @@ -3700,7 +3697,7 @@ static void Got_Addfilecmd(UINT8 **cp, INT32 playernum) static void Got_Addfoldercmd(UINT8 **cp, INT32 playernum) { char path[241]; - filestatus_t ncs = FS_NOTFOUND; + filestatus_t ncs = FS_NOTCHECKED; READSTRINGN(*cp, path, 240); @@ -3744,7 +3741,13 @@ static void Command_ListWADS_f(void) { INT32 i = numwadfiles; char *tempname; - CONS_Printf(M_GetText("There are %d wads loaded:\n"),numwadfiles); + +#ifdef ENFORCE_WAD_LIMIT + CONS_Printf(M_GetText("There are %d/%d files loaded:\n"),numwadfiles,MAX_WADFILES); +#else + CONS_Printf(M_GetText("There are %d files loaded:\n"),numwadfiles); +#endif + for (i--; i >= 0; i--) { nameonly(tempname = va("%s", wadfiles[i]->filename)); diff --git a/src/d_netcmd.h b/src/d_netcmd.h index cae32643e..efe00552a 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -73,6 +73,7 @@ extern consvar_t cv_teamscramble; extern consvar_t cv_scrambleonchange; extern consvar_t cv_netstat; +extern consvar_t cv_nettimeout; extern consvar_t cv_countdowntime; extern consvar_t cv_runscripts; diff --git a/src/d_netfil.c b/src/d_netfil.c index 12c5ee6a2..a1dd02eeb 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -52,7 +52,7 @@ #include // Prototypes -static boolean AddFileToSendQueue(INT32 node, const char *filename, UINT8 fileid); +static boolean AddFileToSendQueue(INT32 node, UINT8 fileid); // Sender structure typedef struct filetx_s @@ -87,7 +87,7 @@ static filetran_t transfer[MAXNETNODES]; // Receiver structure INT32 fileneedednum; // Number of files needed to join the server -fileneeded_t fileneeded[MAX_WADFILES]; // List of needed files +fileneeded_t *fileneeded; // List of needed files static tic_t lasttimeackpacketsent = 0; char downloaddir[512] = "DOWNLOAD"; @@ -105,6 +105,10 @@ static pauseddownload_t *pauseddownload = NULL; #ifndef NONET // for cl loading screen INT32 lastfilenum = -1; +INT32 downloadcompletednum = 0; +UINT32 downloadcompletedsize = 0; +INT32 totalfilesrequestednum = 0; +UINT32 totalfilesrequestedsize = 0; #endif luafiletransfer_t *luafiletransfers = NULL; @@ -113,25 +117,62 @@ boolean waitingforluafilecommand = false; char luafiledir[256 + 16] = "luafiles"; +static UINT16 GetWadNumFromFileNeededId(UINT8 id) +{ + UINT16 wadnum; + + for (wadnum = mainwads; wadnum < numwadfiles; wadnum++) + { + if (!wadfiles[wadnum]->important) + continue; + if (id == 0) + return wadnum; + id--; + } + + return UINT16_MAX; +} + /** Fills a serverinfo packet with information about wad files loaded. * * \todo Give this function a better name since it is in global scope. * Used to have size limiting built in - now handled via W_InitFile in w_wad.c * */ -UINT8 *PutFileNeeded(void) +UINT8 *PutFileNeeded(UINT16 firstfile) { - size_t i, count = 0; - UINT8 *p = netbuffer->u.serverinfo.fileneeded; + size_t i; + UINT8 count = 0; + UINT8 *p_start = netbuffer->packettype == PT_MOREFILESNEEDED ? netbuffer->u.filesneededcfg.files : netbuffer->u.serverinfo.fileneeded; + UINT8 *p = p_start; char wadfilename[MAX_WADPATH] = ""; UINT8 filestatus, folder; - for (i = 0; i < numwadfiles; i++) + for (i = mainwads; i < numwadfiles; i++) //mainwads, otherwise we start on the first mainwad { // If it has only music/sound lumps, don't put it in the list if (!wadfiles[i]->important) continue; + if (firstfile) + { // Skip files until we reach the first file. + firstfile--; + continue; + } + + nameonly(strcpy(wadfilename, wadfiles[i]->filename)); + + // Look below at the WRITE macros to understand what these numbers mean. + if (p + 1 + 4 + min(strlen(wadfilename) + 1, MAX_WADPATH) + 16 > p_start + MAXFILENEEDED) + { + // Too many files to send all at once + if (netbuffer->packettype == PT_MOREFILESNEEDED) + netbuffer->u.filesneededcfg.more = 1; + else + netbuffer->u.serverinfo.flags |= SV_LOTSOFADDONS; + break; + } + filestatus = 1; // Importance - not really used any more, holds 1 by default for backwards compat with MS folder = (wadfiles[i]->type == RET_FOLDER); @@ -148,32 +189,53 @@ UINT8 *PutFileNeeded(void) count++; WRITEUINT32(p, wadfiles[i]->filesize); - nameonly(strcpy(wadfilename, wadfiles[i]->filename)); WRITESTRINGN(p, wadfilename, MAX_WADPATH); WRITEMEM(p, wadfiles[i]->md5sum, 16); } - netbuffer->u.serverinfo.fileneedednum = (UINT8)count; + + if (netbuffer->packettype == PT_MOREFILESNEEDED) + netbuffer->u.filesneededcfg.num = count; + else + netbuffer->u.serverinfo.fileneedednum = count; return p; } +void AllocFileNeeded(INT32 size) +{ + if (fileneeded == NULL) + fileneeded = Z_Calloc(sizeof(fileneeded_t) * size, PU_STATIC, NULL); + else + fileneeded = Z_Realloc(fileneeded, sizeof(fileneeded_t) * size, PU_STATIC, NULL); +} + +void FreeFileNeeded(void) +{ + Z_Free(fileneeded); + fileneeded = NULL; +} + /** Parses the serverinfo packet and fills the fileneeded table on client * * \param fileneedednum_parm The number of files needed to join the server * \param fileneededstr The memory block containing the list of needed files * */ -void D_ParseFileneeded(INT32 fileneedednum_parm, UINT8 *fileneededstr) +void D_ParseFileneeded(INT32 fileneedednum_parm, UINT8 *fileneededstr, UINT16 firstfile) { INT32 i; UINT8 *p; UINT8 filestatus; - fileneedednum = fileneedednum_parm; + fileneedednum = firstfile + fileneedednum_parm; p = (UINT8 *)fileneededstr; - for (i = 0; i < fileneedednum; i++) + + AllocFileNeeded(fileneedednum); + + for (i = firstfile; i < fileneedednum; i++) { - fileneeded[i].status = FS_NOTFOUND; // We haven't even started looking for the file yet + fileneeded[i].type = FILENEEDED_WAD; + fileneeded[i].status = FS_NOTCHECKED; // We haven't even started looking for the file yet fileneeded[i].justdownloaded = false; filestatus = READUINT8(p); // The first byte is the file status fileneeded[i].folder = READUINT8(p); // The second byte is the folder flag @@ -191,7 +253,11 @@ void CL_PrepareDownloadSaveGame(const char *tmpsave) lastfilenum = -1; #endif + FreeFileNeeded(); + AllocFileNeeded(1); + fileneedednum = 1; + fileneeded[0].type = FILENEEDED_SAVEGAME; fileneeded[0].status = FS_REQUESTED; fileneeded[0].justdownloaded = false; fileneeded[0].totalsize = UINT32_MAX; @@ -322,14 +388,18 @@ boolean CL_SendFileRequest(void) if ((fileneeded[i].status == FS_NOTFOUND || fileneeded[i].status == FS_MD5SUMBAD)) { totalfreespaceneeded += fileneeded[i].totalsize; - nameonly(fileneeded[i].filename); + WRITEUINT8(p, i); // fileid - WRITESTRINGN(p, fileneeded[i].filename, MAX_WADPATH); + // put it in download dir + nameonly(fileneeded[i].filename); strcatbf(fileneeded[i].filename, downloaddir, "/"); + fileneeded[i].status = FS_REQUESTED; } + WRITEUINT8(p, 0xFF); + I_GetDiskFreeSpace(&availablefreespace); if (totalfreespaceneeded > availablefreespace) I_Error("To play on this server you must download %s KB,\n" @@ -345,21 +415,22 @@ boolean CL_SendFileRequest(void) // returns false if a requested file was not found or cannot be sent boolean PT_RequestFile(INT32 node) { - char wad[MAX_WADPATH+1]; UINT8 *p = netbuffer->u.textcmd; UINT8 id; + while (p < netbuffer->u.textcmd + MAXTEXTCMD-1) // Don't allow hacked client to overflow { id = READUINT8(p); if (id == 0xFF) break; - READSTRINGN(p, wad, MAX_WADPATH); - if (!AddFileToSendQueue(node, wad, id)) + + if (!AddFileToSendQueue(node, id)) { SV_AbortSendFiles(node); return false; // don't read the rest of the files } } + return true; // no problems with any files } @@ -368,23 +439,16 @@ boolean PT_RequestFile(INT32 node) * \return 0 if some files are missing * 1 if all files exist * 2 if some already loaded files are not requested or are in a different order + * 3 too many files, over WADLIMIT + * 4 still checking, continuing next tic * */ INT32 CL_CheckFiles(void) { INT32 i, j; char wadfilename[MAX_WADPATH]; - INT32 ret = 1; - size_t packetsize = 0; - size_t filestoget = 0; - -// if (M_CheckParm("-nofiles")) -// return 1; - - // the first is the iwad (the main wad file) - // we don't care if it's called srb2.pk3 or not. - // Never download the IWAD, just assume it's there and identical - fileneeded[0].status = FS_OPEN; + size_t filestoload = 0; + boolean downloadrequired = false; // Modified game handling -- check for an identical file list // must be identical in files loaded AND in order @@ -392,7 +456,7 @@ INT32 CL_CheckFiles(void) if (modifiedgame) { CONS_Debug(DBG_NETPLAY, "game is modified; only doing basic checks\n"); - for (i = 1, j = 1; i < fileneedednum || j < numwadfiles;) + for (i = 0, j = mainwads; i < fileneedednum || j < numwadfiles;) { if (j < numwadfiles && !wadfiles[j]->important) { @@ -419,15 +483,21 @@ INT32 CL_CheckFiles(void) return 1; } - // See W_InitFile in w_wad.c - packetsize = packetsizetally; - - for (i = 1; i < fileneedednum; i++) + for (i = 0; i < fileneedednum; i++) { + if (fileneeded[i].status == FS_NOTFOUND || fileneeded[i].status == FS_MD5SUMBAD) + downloadrequired = true; + + if (fileneeded[i].status != FS_OPEN) + filestoload++; + + if (fileneeded[i].status != FS_NOTCHECKED) //since we're running this over multiple tics now, its possible for us to come across files checked in previous tics + continue; + CONS_Debug(DBG_NETPLAY, "searching for '%s' ", fileneeded[i].filename); // Check in already loaded files - for (j = 1; wadfiles[j]; j++) + for (j = mainwads; wadfiles[j]; j++) { nameonly(strcpy(wadfilename, wadfiles[j]->filename)); if (!stricmp(wadfilename, fileneeded[i].filename) && @@ -435,43 +505,34 @@ INT32 CL_CheckFiles(void) { CONS_Debug(DBG_NETPLAY, "already loaded\n"); fileneeded[i].status = FS_OPEN; - break; + return 4; } } - if (fileneeded[i].status != FS_NOTFOUND) - continue; - - if (fileneeded[i].folder) - packetsize += strlen(fileneeded[i].filename) + FILENEEDEDSIZE; - else - packetsize += nameonlylength(fileneeded[i].filename) + FILENEEDEDSIZE; - - if ((numwadfiles+filestoget >= MAX_WADFILES) - || (packetsize > MAXFILENEEDED*sizeof(UINT8))) - return 3; - - filestoget++; if (fileneeded[i].folder) fileneeded[i].status = findfolder(fileneeded[i].filename); else fileneeded[i].status = findfile(fileneeded[i].filename, fileneeded[i].md5sum, true); + CONS_Debug(DBG_NETPLAY, "found %d\n", fileneeded[i].status); - if (fileneeded[i].status != FS_FOUND) - ret = 0; + return 4; } - return ret; + + //now making it here means we've checked the entire list and no FS_NOTCHECKED files remain + if (numwadfiles+filestoload > MAX_WADFILES) + return 3; + else if (downloadrequired) + return 0; //some stuff is FS_NOTFOUND, needs download + else + return 1; //everything is FS_OPEN or FS_FOUND, proceed to loading } // Load it now -void CL_LoadServerFiles(void) +boolean CL_LoadServerFiles(void) { INT32 i; -// if (M_CheckParm("-nofiles")) -// return; - - for (i = 1; i < fileneedednum; i++) + for (i = 0; i < fileneedednum; i++) { if (fileneeded[i].status == FS_OPEN) continue; // Already loaded @@ -483,6 +544,7 @@ void CL_LoadServerFiles(void) P_AddWadFile(fileneeded[i].filename); G_SetGameModified(true); fileneeded[i].status = FS_OPEN; + return false; } else if (fileneeded[i].status == FS_MD5SUMBAD) I_Error("Wrong version of file %s", fileneeded[i].filename); @@ -508,6 +570,7 @@ void CL_LoadServerFiles(void) fileneeded[i].status, s); } } + return true; } void AddLuaFileTransfer(const char *filename, const char *mode) @@ -689,7 +752,11 @@ void CL_PrepareDownloadLuaFile(void) netbuffer->packettype = PT_ASKLUAFILE; HSendPacket(servernode, true, 0, 0); + FreeFileNeeded(); + AllocFileNeeded(1); + fileneedednum = 1; + fileneeded[0].type = FILENEEDED_LUAFILE; fileneeded[0].status = FS_REQUESTED; fileneeded[0].justdownloaded = false; fileneeded[0].totalsize = UINT32_MAX; @@ -716,15 +783,11 @@ static INT32 filestosend = 0; * \sa AddLuaFileToSendQueue * */ -static boolean AddFileToSendQueue(INT32 node, const char *filename, UINT8 fileid) +static boolean AddFileToSendQueue(INT32 node, UINT8 fileid) { filetx_t **q; // A pointer to the "next" field of the last file in the list filetx_t *p; // The new file request - INT32 i; - char wadfilename[MAX_WADPATH]; - - if (cv_noticedownload.value) - CONS_Printf("Sending file \"%s\" to node %d (%s)\n", filename, node, I_GetNodeAddress(node)); + UINT16 wadnum; // Find the last file in the list and set a pointer to its "next" field q = &transfer[node].txlist; @@ -744,51 +807,43 @@ static boolean AddFileToSendQueue(INT32 node, const char *filename, UINT8 fileid if (!p->id.filename) I_Error("AddFileToSendQueue: No more memory\n"); - // Set the file name and get rid of the path - strlcpy(p->id.filename, filename, MAX_WADPATH); - nameonly(p->id.filename); - - // Look for the requested file through all loaded files - for (i = 0; wadfiles[i]; i++) - { - strlcpy(wadfilename, wadfiles[i]->filename, MAX_WADPATH); - nameonly(wadfilename); - if (!stricmp(wadfilename, p->id.filename)) - { - // Copy file name with full path - strlcpy(p->id.filename, wadfiles[i]->filename, MAX_WADPATH); - break; - } - } + // Find the wad the ID refers to + wadnum = GetWadNumFromFileNeededId(fileid); // Handle non-loaded file requests - if (!wadfiles[i]) + if (wadnum == UINT16_MAX) { - DEBFILE(va("%s not found in wadfiles\n", filename)); + DEBFILE(va("fileneeded %d not found in wadfiles\n", fileid)); // This formerly checked if (!findfile(p->id.filename, NULL, true)) // Not found // Don't inform client - DEBFILE(va("Client %d request %s: not found\n", node, filename)); + DEBFILE(va("Client %d request fileneeded %d: not found\n", node, fileid)); free(p->id.filename); free(p); *q = NULL; return false; // cancel the rest of the requests } + // Set the file name and get rid of the path + strlcpy(p->id.filename, wadfiles[wadnum]->filename, MAX_WADPATH); + // Handle huge file requests (i.e. bigger than cv_maxsend.value KB) - if (wadfiles[i]->filesize > (UINT32)cv_maxsend.value * 1024) + if (wadfiles[wadnum]->filesize > (UINT32)cv_maxsend.value * 1024) { // Too big // Don't inform client (client sucks, man) - DEBFILE(va("Client %d request %s: file too big, not sending\n", node, filename)); + DEBFILE(va("Client %d request %s: file too big, not sending\n", node, p->id.filename)); free(p->id.filename); free(p); *q = NULL; return false; // cancel the rest of the requests } - DEBFILE(va("Sending file %s (id=%d) to %d\n", filename, fileid, node)); + if (cv_noticedownload.value) + CONS_Printf("Sending file \"%s\" to node %d (%s)\n", p->id.filename, node, I_GetNodeAddress(node)); + + DEBFILE(va("Sending file %s (id=%d) to %d\n", p->id.filename, fileid, node)); p->ram = SF_FILE; // It's a file, we need to close it and free its name once we're done sending it p->fileid = fileid; p->next = NULL; // End of list @@ -1242,6 +1297,9 @@ void PT_FileFragment(void) UINT16 boundedfragmentsize = doomcom->datalength - BASEPACKETSIZE - sizeof(netbuffer->u.filetxpak); char *filename; + if (!file) + return; + filename = va("%s", file->filename); nameonly(filename); @@ -1353,6 +1411,7 @@ void PT_FileFragment(void) // Tell the server we have received the file netbuffer->packettype = PT_HASLUAFILE; HSendPacket(servernode, true, 0, 0); + FreeFileNeeded(); } } } @@ -1423,32 +1482,37 @@ void CloseNetFile(void) SV_AbortSendFiles(i); // Receiving a file? - for (i = 0; i < MAX_WADFILES; i++) - if (fileneeded[i].status == FS_DOWNLOADING && fileneeded[i].file) - { - fclose(fileneeded[i].file); - free(fileneeded[i].ackpacket); - - if (!pauseddownload && i != 0) // 0 is either srb2.srb or the gamestate... + if (fileneeded) + { + for (i = 0; i < fileneedednum; i++) + if (fileneeded[i].status == FS_DOWNLOADING && fileneeded[i].file) { - // Don't remove the file, save it for later in case we resume the download - pauseddownload = malloc(sizeof(*pauseddownload)); - if (!pauseddownload) - I_Error("CloseNetFile: No more memory\n"); + fclose(fileneeded[i].file); + free(fileneeded[i].ackpacket); - strcpy(pauseddownload->filename, fileneeded[i].filename); - memcpy(pauseddownload->md5sum, fileneeded[i].md5sum, 16); - pauseddownload->currentsize = fileneeded[i].currentsize; - pauseddownload->receivedfragments = fileneeded[i].receivedfragments; - pauseddownload->fragmentsize = fileneeded[i].fragmentsize; + if (!pauseddownload && (fileneeded[i].type == FILENEEDED_WAD || i != 0)) // 0 is the gamestate... + { + // Don't remove the file, save it for later in case we resume the download + pauseddownload = malloc(sizeof(*pauseddownload)); + if (!pauseddownload) + I_Error("CloseNetFile: No more memory\n"); + + strcpy(pauseddownload->filename, fileneeded[i].filename); + memcpy(pauseddownload->md5sum, fileneeded[i].md5sum, 16); + pauseddownload->currentsize = fileneeded[i].currentsize; + pauseddownload->receivedfragments = fileneeded[i].receivedfragments; + pauseddownload->fragmentsize = fileneeded[i].fragmentsize; + } + else + { + // File is not complete, delete it. + free(fileneeded[i].receivedfragments); + remove(fileneeded[i].filename); + } } - else - { - free(fileneeded[i].receivedfragments); - // File is not complete delete it - remove(fileneeded[i].filename); - } - } + } + + FreeFileNeeded(); } void Command_Downloads_f(void) diff --git a/src/d_netfil.h b/src/d_netfil.h index 70b721bf7..3d713c150 100644 --- a/src/d_netfil.h +++ b/src/d_netfil.h @@ -27,6 +27,7 @@ typedef enum typedef enum { + FS_NOTCHECKED, FS_NOTFOUND, FS_FOUND, FS_REQUESTED, @@ -35,13 +36,21 @@ typedef enum FS_MD5SUMBAD } filestatus_t; +typedef enum +{ + FILENEEDED_WAD, + FILENEEDED_SAVEGAME, + FILENEEDED_LUAFILE +} fileneededtype_t; + typedef struct { - UINT8 willsend; // Is the server willing to send it? - UINT8 folder; // File is a folder char filename[MAX_WADPATH]; UINT8 md5sum[16]; filestatus_t status; // The value returned by recsearch + UINT8 willsend; // Is the server willing to send it? + UINT8 folder; // File is a folder + fileneededtype_t type; boolean justdownloaded; // To prevent late fragments from causing an I_Error // Used only for download @@ -58,19 +67,25 @@ typedef struct #define FILENEEDEDSIZE 23 extern INT32 fileneedednum; -extern fileneeded_t fileneeded[MAX_WADFILES]; +extern fileneeded_t *fileneeded; extern char downloaddir[512]; #ifndef NONET extern INT32 lastfilenum; +extern INT32 downloadcompletednum; +extern UINT32 downloadcompletedsize; +extern INT32 totalfilesrequestednum; +extern UINT32 totalfilesrequestedsize; #endif -UINT8 *PutFileNeeded(void); -void D_ParseFileneeded(INT32 fileneedednum_parm, UINT8 *fileneededstr); +void AllocFileNeeded(INT32 size); +void FreeFileNeeded(void); +UINT8 *PutFileNeeded(UINT16 firstfile); +void D_ParseFileneeded(INT32 fileneedednum_parm, UINT8 *fileneededstr, UINT16 firstfile); void CL_PrepareDownloadSaveGame(const char *tmpsave); INT32 CL_CheckFiles(void); -void CL_LoadServerFiles(void); +boolean CL_LoadServerFiles(void); void AddRamToSendQueue(INT32 node, void *data, size_t size, freemethod_t freemethod, UINT8 fileid); diff --git a/src/doomdef.h b/src/doomdef.h index 37edca896..7e7e35599 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -152,6 +152,9 @@ extern char logfilename[1024]; // Comment or uncomment this as necessary. #define USE_PATCH_DTA +// Enforce a limit of loaded WAD files. +//#define ENFORCE_WAD_LIMIT + // Use .kart extension addons //#define USE_KART diff --git a/src/filesrch.c b/src/filesrch.c index b4039e526..ec095518e 100644 --- a/src/filesrch.c +++ b/src/filesrch.c @@ -338,9 +338,6 @@ size_t dir_on[menudepth]; UINT8 refreshdirmenu = 0; char *refreshdirname = NULL; -size_t packetsizetally = 0; -size_t mainwadstally = 0; - #define dirpathlen 1024 #define maxdirdepth 48 @@ -830,7 +827,7 @@ char exttable[NUM_EXT_TABLE][7] = { // maximum extension length (currently 4) pl #endif "\5.pk3", "\5.soc", "\5.lua"}; // addfile -char filenamebuf[MAX_WADFILES][MAX_WADPATH]; +static char (*filenamebuf)[MAX_WADPATH]; static boolean filemenucmp(char *haystack, char *needle) { @@ -1102,6 +1099,10 @@ boolean preparefilemenu(boolean samedepth) if (ext >= EXT_LOADSTART) { size_t i; + + if (filenamebuf == NULL) + filenamebuf = calloc(sizeof(char) * MAX_WADPATH, numwadfiles); + for (i = 0; i < numwadfiles; i++) { if (!filenamebuf[i][0]) @@ -1151,6 +1152,12 @@ boolean preparefilemenu(boolean samedepth) } } + if (filenamebuf) + { + free(filenamebuf); + filenamebuf = NULL; + } + closedir(dirhandle); if ((menudepthleft != menudepth-1) // now for UP... entry diff --git a/src/filesrch.h b/src/filesrch.h index 9d5f31bbb..59ef5269b 100644 --- a/src/filesrch.h +++ b/src/filesrch.h @@ -53,9 +53,6 @@ extern size_t dir_on[menudepth]; extern UINT8 refreshdirmenu; extern char *refreshdirname; -extern size_t packetsizetally; -extern size_t mainwadstally; - typedef enum { EXT_FOLDER = 0, diff --git a/src/m_menu.c b/src/m_menu.c index 7a82fd8fb..d5fa5e95b 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -3215,7 +3215,7 @@ boolean M_Responder(event_t *ev) if (gamestate == GS_TITLESCREEN && finalecount < TICRATE) return false; - if (CON_Ready()) + if (CON_Ready() && gamestate != GS_WAITINGPLAYERS) return false; if (noFurtherInput) @@ -6410,6 +6410,7 @@ static void M_Addons(INT32 choice) M_SetupNextMenu(&MISC_AddonsDef); } +#ifdef ENFORCE_WAD_LIMIT #define width 4 #define vpadding 27 #define h (BASEVIDHEIGHT-(2*vpadding)) @@ -6457,6 +6458,7 @@ static void M_DrawTemperature(INT32 x, fixed_t t) #undef vpadding #undef h #undef NUMCOLOURS +#endif static char *M_AddonsHeaderPath(void) { @@ -6550,21 +6552,20 @@ static void M_DrawAddons(void) V_DrawCenteredString(BASEVIDWIDTH/2, 5, 0, LOCATIONSTRING1); // (recommendedflags == V_SKYMAP ? LOCATIONSTRING2 : LOCATIONSTRING1) +#ifdef ENFORCE_WAD_LIMIT if (numwadfiles <= mainwads+1) y = 0; else if (numwadfiles >= MAX_WADFILES) y = FRACUNIT; else { - x = FixedDiv(((ssize_t)(numwadfiles) - (ssize_t)(mainwads+1))< y) - y = x; + y = FixedDiv(((ssize_t)(numwadfiles) - (ssize_t)(mainwads+1))< FRACUNIT) // happens because of how we're shrinkin' it a little y = FRACUNIT; } M_DrawTemperature(BASEVIDWIDTH - 19 - 5, y); +#endif // DRAW MENU x = currentMenu->x; diff --git a/src/w_wad.c b/src/w_wad.c index 3ff301117..e49e0ce82 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -105,7 +105,7 @@ static UINT16 lumpnumcacheindex = 0; // GLOBALS //=========================================================================== UINT16 numwadfiles; // number of active wadfiles -wadfile_t *wadfiles[MAX_WADFILES]; // 0 to numwadfiles-1 are valid +wadfile_t **wadfiles; // 0 to numwadfiles-1 are valid // W_Shutdown // Closes all of the WAD files before quitting @@ -134,6 +134,8 @@ void W_Shutdown(void) Z_Free(wad->lumpinfo); Z_Free(wad); } + + Z_Free(wadfiles); } //=========================================================================== @@ -844,7 +846,6 @@ UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup) #ifndef NOMD5 size_t i; #endif - size_t packetsize; UINT8 md5sum[16]; int important; @@ -862,9 +863,8 @@ UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup) refreshdirname = NULL; //CONS_Debug(DBG_SETUP, "Loading %s\n", filename); - // - // check if limit of active wadfiles - // + + // Check if the game reached the limit of active wadfiles. if (numwadfiles >= MAX_WADFILES) { CONS_Alert(CONS_ERROR, M_GetText("Maximum wad files reached\n")); @@ -884,24 +884,7 @@ UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup) return INT16_MAX; } - // Check if wad files will overflow fileneededbuffer. Only the filename part - // is send in the packet; cf. - // see PutFileNeeded in d_netfil.c - if ((important = !important)) - { - packetsize = packetsizetally + nameonlylength(filename) + FILENEEDEDSIZE; - - if (packetsize > MAXFILENEEDED*sizeof(UINT8)) - { - CONS_Alert(CONS_ERROR, M_GetText("Maximum wad files reached\n")); - refreshdirmenu |= REFRESHDIR_MAX; - if (handle) - fclose(handle); - return W_InitFileError(filename, startup); - } - - packetsizetally = packetsize; - } + important = !important; #ifndef NOMD5 // @@ -913,11 +896,12 @@ UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup) for (i = 0; i < numwadfiles; i++) { + if (wadfiles[i]->type == RET_FOLDER) + continue; + if (!memcmp(wadfiles[i]->md5sum, md5sum, 16)) { CONS_Alert(CONS_ERROR, M_GetText("%s is already loaded\n"), filename); - if (important) - packetsizetally -= nameonlylength(filename) + FILENEEDEDSIZE; if (handle) fclose(handle); return W_InitFileError(filename, false); @@ -984,6 +968,7 @@ UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup) // add the wadfile // CONS_Printf(M_GetText("Added file %s (%u lumps)\n"), filename, numlumps); + wadfiles = Z_Realloc(wadfiles, sizeof(wadfile_t) * (numwadfiles + 1), PU_STATIC, NULL); wadfiles[numwadfiles] = wadfile; numwadfiles++; // must come BEFORE W_LoadDehackedLumps, so any addfile called by COM_BufInsertText called by Lua doesn't overwrite what we just loaded @@ -1046,22 +1031,7 @@ UINT16 W_InitFolder(const char *path, boolean mainfile, boolean startup) return W_InitFileError(path, startup); } - important = 0; // ??? - - /// \todo Implement a W_VerifyFolder. - if ((important = !important)) - { - size_t packetsize = packetsizetally + strlen(path) + FILENEEDEDSIZE; - - if (packetsize > MAXFILENEEDED*sizeof(UINT8)) - { - CONS_Alert(CONS_ERROR, M_GetText("Maximum wad files reached\n")); - refreshdirmenu |= REFRESHDIR_MAX; - return W_InitFileError(path, startup); - } - - packetsizetally = packetsize; - } + important = 0; /// \todo Implement a W_VerifyFolder. // Remove path delimiters. p = path + (strlen(path) - 1); @@ -1132,8 +1102,6 @@ UINT16 W_InitFolder(const char *path, boolean mainfile, boolean startup) if (samepaths(wadfiles[i]->path, fullpath) > 0) { CONS_Alert(CONS_ERROR, M_GetText("%s is already loaded\n"), path); - if (important) - packetsizetally -= strlen(path) + FILENEEDEDSIZE; Z_Free(fn); Z_Free(fullpath); return W_InitFileError(path, false); @@ -1197,11 +1165,13 @@ UINT16 W_InitFolder(const char *path, boolean mainfile, boolean startup) * * \param filenames A null-terminated list of files to use. */ -void W_InitMultipleFiles(char **filenames) +void W_InitMultipleFiles(addfilelist_t *list) { - for (; *filenames; filenames++) + size_t i = 0; + + for (; i < list->numfiles; i++) { - const char *fn = (*filenames); + const char *fn = list->files[i]; char pathsep = fn[strlen(fn) - 1]; boolean mainfile = (numwadfiles < mainwads); @@ -1219,7 +1189,7 @@ void W_InitMultipleFiles(char **filenames) */ static boolean TestValidLump(UINT16 wad, UINT16 lump) { - I_Assert(wad < MAX_WADFILES); + I_Assert(wad < numwadfiles); if (!wadfiles[wad]) // make sure the wad file exists return false; @@ -1636,7 +1606,7 @@ size_t W_LumpLength(lumpnum_t lumpnum) // // W_IsLumpWad -// Is the lump a WAD? (presumably in a PK3) +// Is the lump a WAD? (presumably not in a WAD) // boolean W_IsLumpWad(lumpnum_t lumpnum) { @@ -1649,12 +1619,12 @@ boolean W_IsLumpWad(lumpnum_t lumpnum) return !strnicmp(lumpfullName + strlen(lumpfullName) - 4, ".wad", 4); } - return false; // WADs should never be inside non-PK3s as far as SRB2 is concerned + return false; // WADs should never be inside WADs as far as SRB2 is concerned } // // W_IsLumpFolder -// Is the lump a folder? (in a PK3 obviously) +// Is the lump a folder? (not in a WAD obviously) // boolean W_IsLumpFolder(UINT16 wad, UINT16 lump) { @@ -1665,7 +1635,7 @@ boolean W_IsLumpFolder(UINT16 wad, UINT16 lump) return (name[strlen(name)-1] == '/'); // folders end in '/' } - return false; // non-PK3s don't have folders + return false; // WADs don't have folders } #ifdef HAVE_ZLIB @@ -2217,7 +2187,7 @@ void W_VerifyFileMD5(UINT16 wadfilenum, const char *matchmd5) #else I_Error #endif - (M_GetText("File is old, is corrupt or has been modified: %s (found md5: %s, wanted: %s)\n"), wadfiles[wadfilenum]->filename, actualmd5text, matchmd5); + (M_GetText("File is old, is corrupt or has been modified:\n%s\nFound MD5: %s\nWanted MD5: %s\n"), wadfiles[wadfilenum]->filename, actualmd5text, matchmd5); } #endif } diff --git a/src/w_wad.h b/src/w_wad.h index 949bab9fe..a41ba1724 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -97,9 +97,15 @@ virtlump_t* vres_Find(const virtres_t*, const char*); // DYNAMIC WAD LOADING // ========================================================================= +// Maximum of files that can be loaded +// (there is a max of simultaneous open files anyway) +#ifdef ENFORCE_WAD_LIMIT +#define MAX_WADFILES 2048 // This cannot be any higher than UINT16_MAX. +#else +#define MAX_WADFILES UINT16_MAX +#endif + #define MAX_WADPATH 512 -#define MAX_WADFILES 48 // maximum of wad files used at the same time -// (there is a max of simultaneous open files anyway, and this should be plenty) #define lumpcache_t void * @@ -134,7 +140,13 @@ typedef struct wadfile_s #define LUMPNUM(lumpnum) (UINT16)((lumpnum)&0xFFFF) // lump number for this pwad extern UINT16 numwadfiles; -extern wadfile_t *wadfiles[MAX_WADFILES]; +extern wadfile_t **wadfiles; + +typedef struct +{ + char **files; + size_t numfiles; +} addfilelist_t; // ========================================================================= @@ -148,7 +160,7 @@ UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup); UINT16 W_InitFolder(const char *path, boolean mainfile, boolean startup); // W_InitMultipleFiles exits if a file was not found, but not if all is okay. -void W_InitMultipleFiles(char **filenames); +void W_InitMultipleFiles(addfilelist_t *list); #define W_FileHasFolders(wadfile) ((wadfile)->type == RET_PK3 || (wadfile)->type == RET_FOLDER)