From 8f02e3e462dc7d4bd3ba781592a1a5fa7c3152cf Mon Sep 17 00:00:00 2001 From: Zwip-Zwap Zapony Date: Sat, 2 Jan 2021 12:40:59 +0100 Subject: [PATCH 001/586] Fix PRIdS define for Windows MINGW64 and DJGPP Make the PRIdS define into "zu" instead of "Iu" for MINGW64 Fix checking for "DJGPP" instead of "__DJGPP__" --- src/m_misc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/m_misc.c b/src/m_misc.c index 42890cb08..ef48dde00 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -62,9 +62,9 @@ typedef off_t off64_t; #if defined(__MINGW32__) && ((__GNUC__ > 7) || (__GNUC__ == 6 && __GNUC_MINOR__ >= 3)) && (__GNUC__ < 8) #define PRIdS "u" -#elif defined (_WIN32) +#elif defined(_WIN32) && !defined(__MINGW64__) #define PRIdS "Iu" -#elif defined (DJGPP) +#elif defined(__DJGPP__) #define PRIdS "u" #else #define PRIdS "zu" From a1a58143ec3e39b9cf76cdaeb84c6a07646a73e4 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 31 Aug 2021 19:00:05 -0700 Subject: [PATCH 002/586] Fix IPv6 address checks - SOCK_cmpaddr returned inverted truth for IPv6 addresses. This would prevent making a connection. - Account for IPv6 address resolution. (bug: 5a627482) --- src/i_tcp.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/i_tcp.c b/src/i_tcp.c index cae97a7d1..3d5d302f8 100644 --- a/src/i_tcp.c +++ b/src/i_tcp.c @@ -427,7 +427,7 @@ static boolean SOCK_cmpaddr(mysockaddr_t *a, mysockaddr_t *b, UINT8 mask) && (b->ip4.sin_port == 0 || (a->ip4.sin_port == b->ip4.sin_port)); #ifdef HAVE_IPV6 else if (b->any.sa_family == AF_INET6) - return memcmp(&a->ip6.sin6_addr, &b->ip6.sin6_addr, sizeof(b->ip6.sin6_addr)) + return !memcmp(&a->ip6.sin6_addr, &b->ip6.sin6_addr, sizeof(b->ip6.sin6_addr)) && (b->ip6.sin6_port == 0 || (a->ip6.sin6_port == b->ip6.sin6_port)); #endif else @@ -1156,6 +1156,7 @@ static SINT8 SOCK_NetMakeNodewPort(const char *address, const char *port) SINT8 newnode = -1; struct my_addrinfo *ai = NULL, *runp, hints; int gaie; + size_t i; if (!port || !port[0]) port = DEFAULTPORT; @@ -1183,13 +1184,20 @@ static SINT8 SOCK_NetMakeNodewPort(const char *address, const char *port) while (runp != NULL) { - // find ip of the server - if (sendto(mysockets[0], NULL, 0, 0, runp->ai_addr, runp->ai_addrlen) == 0) + // test ip address of server + for (i = 0; i < mysocketses; ++i) { - memcpy(&clientaddress[newnode], runp->ai_addr, runp->ai_addrlen); - break; + if (runp->ai_addr->sa_family == myfamily[i]) + { + memcpy(&clientaddress[newnode], runp->ai_addr, runp->ai_addrlen); + break; + } } - runp = runp->ai_next; + + if (i < mysocketses) + runp = runp->ai_next; + else + break; } I_freeaddrinfo(ai); return newnode; From f8a749be091176d1548fd2dc09eda4901d152d29 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 31 Aug 2021 19:03:23 -0700 Subject: [PATCH 003/586] Correctly set IPV6_V6ONLY setsockopt level for v6 options is IPPROTO_IPV6. --- src/i_tcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i_tcp.c b/src/i_tcp.c index 3d5d302f8..50d1a57fa 100644 --- a/src/i_tcp.c +++ b/src/i_tcp.c @@ -788,7 +788,7 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen // make it IPv6 ony opt = true; opts = (socklen_t)sizeof(opt); - if (setsockopt(s, SOL_SOCKET, IPV6_V6ONLY, (char *)&opt, opts)) + if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&opt, opts)) { CONS_Alert(CONS_WARNING, M_GetText("Could not limit IPv6 bind\n")); // I do not care anymore } From 0422870df85932748d8166b3ce46dde3f87f0417 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 31 Aug 2021 19:54:27 -0700 Subject: [PATCH 004/586] Use RFC2732 notation for IPv6 addresses This fixes keepbody and the connect command (also '-connect' parameter). connect ::1 connect [::1]:5029 --- src/d_clisrv.c | 19 ++++++++----------- src/d_net.c | 26 +++++++++++++++++--------- src/i_net.h | 11 +++++++++++ src/i_tcp.c | 21 +++++++++++++++++---- 4 files changed, 53 insertions(+), 24 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index aa7bc8a6c..e9a70c8ec 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1171,9 +1171,9 @@ static boolean CL_SendJoin(void) static INT32 FindRejoinerNum(SINT8 node) { - char strippednodeaddress[64]; + char addressbuffer[64]; const char *nodeaddress; - char *port; + const char *strippednodeaddress; INT32 i; // Make sure there is no dead dress before proceeding to the stripping @@ -1184,10 +1184,8 @@ static INT32 FindRejoinerNum(SINT8 node) return -1; // Strip the address of its port - strcpy(strippednodeaddress, nodeaddress); - port = strchr(strippednodeaddress, ':'); - if (port) - *port = '\0'; + strcpy(addressbuffer, nodeaddress); + strippednodeaddress = I_NetSplitAddress(addressbuffer, NULL); // Check if any player matches the stripped address for (i = 0; i < MAXPLAYERS; i++) @@ -3426,14 +3424,13 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum) if (server && I_GetNodeAddress) { + char addressbuffer[64]; 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'; + strcpy(addressbuffer, address); + strcpy(playeraddress[newplayernum], + I_NetSplitAddress(addressbuffer, NULL)); } } } diff --git a/src/d_net.c b/src/d_net.c index 9e5abe24a..6906ac123 100644 --- a/src/d_net.c +++ b/src/d_net.c @@ -1200,26 +1200,34 @@ static void Internal_FreeNodenum(INT32 nodenum) (void)nodenum; } +char *I_NetSplitAddress(char *host, char **port) +{ + boolean v4 = (strchr(host, '.') != NULL); + + host = strtok(host, v4 ? ":" : "[]"); + + if (port) + *port = strtok(NULL, ":"); + + return host; +} + SINT8 I_NetMakeNode(const char *hostname) { SINT8 newnode = -1; if (I_NetMakeNodewPort) { char *localhostname = strdup(hostname); - char *t = localhostname; - const char *port; + char *port; if (!localhostname) return newnode; + // retrieve portnum from address! - strtok(localhostname, ":"); - port = strtok(NULL, ":"); + hostname = I_NetSplitAddress(localhostname, &port); - // remove the port in the hostname as we've it already - while ((*t != ':') && (*t != '\0')) - t++; - *t = '\0'; + CONS_Printf("%s %s\n", hostname, port); - newnode = I_NetMakeNodewPort(localhostname, port); + newnode = I_NetMakeNodewPort(hostname, port); free(localhostname); } return newnode; diff --git a/src/i_net.h b/src/i_net.h index dbc82db65..2d09af750 100644 --- a/src/i_net.h +++ b/src/i_net.h @@ -109,6 +109,17 @@ extern boolean (*I_NetCanSend)(void); */ extern void (*I_NetFreeNodenum)(INT32 nodenum); +/** + \brief split a string into address and port + + \param address string to split + + \param port double pointer to hold port component (optional) + + \return address component +*/ +extern char *I_NetSplitAddress(char *address, char **port); + /** \brief open a connection with specified address \param address address to connect to diff --git a/src/i_tcp.c b/src/i_tcp.c index 50d1a57fa..ca55515ab 100644 --- a/src/i_tcp.c +++ b/src/i_tcp.c @@ -340,8 +340,14 @@ static inline void I_UPnP_rem(const char *port, const char * servicetype) static const char *SOCK_AddrToStr(mysockaddr_t *sk) { - static char s[64]; // 255.255.255.255:65535 or IPv6:65535 + static char s[64]; // 255.255.255.255:65535 or + // [ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]:65535 #ifdef HAVE_NTOP +#ifdef HAVE_IPV6 + int v6 = (sk->any.sa_family == AF_INET6); +#else + int v6 = 0; +#endif void *addr; if(sk->any.sa_family == AF_INET) @@ -355,14 +361,21 @@ static const char *SOCK_AddrToStr(mysockaddr_t *sk) if(addr == NULL) sprintf(s, "No address"); - else if(inet_ntop(sk->any.sa_family, addr, s, sizeof (s)) == NULL) + else if(inet_ntop(sk->any.sa_family, addr, &s[v6], sizeof (s) - v6) == NULL) sprintf(s, "Unknown family type, error #%u", errno); #ifdef HAVE_IPV6 - else if(sk->any.sa_family == AF_INET6 && sk->ip6.sin6_port != 0) - strcat(s, va(":%d", ntohs(sk->ip6.sin6_port))); + else if(sk->any.sa_family == AF_INET6) + { + s[0] = '['; + strcat(s, "]"); + + if (sk->ip6.sin6_port != 0) + strcat(s, va(":%d", ntohs(sk->ip6.sin6_port))); + } #endif else if(sk->any.sa_family == AF_INET && sk->ip4.sin_port != 0) strcat(s, va(":%d", ntohs(sk->ip4.sin_port))); + #else if (sk->any.sa_family == AF_INET) { From 44bafe0a325768e8cf8cf04e7802804961751865 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 31 Aug 2021 20:00:20 -0700 Subject: [PATCH 005/586] Remove debug print --- src/d_net.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/d_net.c b/src/d_net.c index 6906ac123..ecf446529 100644 --- a/src/d_net.c +++ b/src/d_net.c @@ -1225,8 +1225,6 @@ SINT8 I_NetMakeNode(const char *hostname) // retrieve portnum from address! hostname = I_NetSplitAddress(localhostname, &port); - CONS_Printf("%s %s\n", hostname, port); - newnode = I_NetMakeNodewPort(hostname, port); free(localhostname); } From 32ad1f2067d05d2e82a233b67c68d649e4ceaabe Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 31 Aug 2021 20:02:09 -0700 Subject: [PATCH 006/586] Make IPv6 default An IPv4 socket is still made. The '-ipv6' parameter is replaced with '-noipv6', self explanatory. --- src/i_tcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i_tcp.c b/src/i_tcp.c index ca55515ab..7878d1fbb 100644 --- a/src/i_tcp.c +++ b/src/i_tcp.c @@ -857,7 +857,7 @@ static boolean UDP_Socket(void) struct my_addrinfo *ai, *runp, hints; int gaie; #ifdef HAVE_IPV6 - const INT32 b_ipv6 = M_CheckParm("-ipv6"); + const INT32 b_ipv6 = !M_CheckParm("-noipv6"); #endif const char *serv; From c9631565d62f6899b8f052bba698ebe13e4db69e Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 1 Sep 2021 17:35:41 -0700 Subject: [PATCH 007/586] Fix address structure handling in UDP_Bind Fixed instances of copying only sizeof (struct sockaddr) bytes (not enough for struct sockaddr_in6), as well as trying to getsockname into an insufficient buffer. --- src/i_tcp.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/i_tcp.c b/src/i_tcp.c index 7878d1fbb..9cdcc6ec4 100644 --- a/src/i_tcp.c +++ b/src/i_tcp.c @@ -748,8 +748,7 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen unsigned long trueval = true; #endif mysockaddr_t straddr; - struct sockaddr_in sin; - socklen_t len = sizeof(sin); + socklen_t len = sizeof(straddr); if (s == (SOCKET_TYPE)ERRSOCKET) return (SOCKET_TYPE)ERRSOCKET; @@ -767,14 +766,12 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen } #endif - straddr.any = *addr; + memcpy(&straddr, addr, addrlen); I_OutputMsg("Binding to %s\n", SOCK_AddrToStr(&straddr)); if (family == AF_INET) { - mysockaddr_t tmpaddr; - tmpaddr.any = *addr ; - if (tmpaddr.ip4.sin_addr.s_addr == htonl(INADDR_ANY)) + if (straddr.ip4.sin_addr.s_addr == htonl(INADDR_ANY)) { opt = true; opts = (socklen_t)sizeof(opt); @@ -791,7 +788,7 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen #ifdef HAVE_IPV6 else if (family == AF_INET6) { - if (memcmp(addr, &in6addr_any, sizeof(in6addr_any)) == 0) //IN6_ARE_ADDR_EQUAL + if (memcmp(&straddr.ip6.sin6_addr, &in6addr_any, sizeof(in6addr_any)) == 0) //IN6_ARE_ADDR_EQUAL { opt = true; opts = (socklen_t)sizeof(opt); @@ -843,10 +840,17 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen CONS_Printf(M_GetText("Network system buffer set to: %dKb\n"), opt>>10); } - if (getsockname(s, (struct sockaddr *)&sin, &len) == -1) + if (getsockname(s, &straddr.any, &len) == -1) CONS_Alert(CONS_WARNING, M_GetText("Failed to get port number\n")); else - current_port = (UINT16)ntohs(sin.sin_port); + { + if (family == AF_INET) + current_port = (UINT16)ntohs(straddr.ip4.sin_port); +#ifdef HAVE_IPV6 + else if (family == AF_INET6) + current_port = (UINT16)ntohs(straddr.ip6.sin6_port); +#endif + } return s; } From 7976d0476d9ab3148c1e4dd24c477c686aa35b14 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 1 Sep 2021 18:02:39 -0700 Subject: [PATCH 008/586] Enbiglarge ip field of server list to fit IPv6 addresses --- src/mserv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mserv.h b/src/mserv.h index 7a3b3d8ec..b97abb634 100644 --- a/src/mserv.h +++ b/src/mserv.h @@ -33,7 +33,7 @@ typedef union typedef struct { msg_header_t header; - char ip[16]; + char ip[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"]; char port[8]; char name[32]; INT32 room; From 31943f30a1829a51620f8d7d3437634105185cde Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 1 Sep 2021 18:32:18 -0700 Subject: [PATCH 009/586] Support connecting by IPv6 address in the menu Font will shrink once exceeding a certain number of characters. --- src/m_menu.c | 56 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 17 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index db2aa09c6..35dae1d03 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -968,7 +968,7 @@ static menuitem_t MP_MainMenu[] = { {IT_HEADER, NULL, "Join a game", NULL, 0}, {IT_STRING|IT_CALL, NULL, "Server browser...", M_ConnectMenuModChecks, 12}, - {IT_STRING|IT_KEYHANDLER, NULL, "Specify IPv4 address:", M_HandleConnectIP, 22}, + {IT_STRING|IT_KEYHANDLER, NULL, "Specify server address:", M_HandleConnectIP, 22}, {IT_HEADER, NULL, "Host a game", NULL, 54}, {IT_STRING|IT_CALL, NULL, "Internet/LAN...", M_StartServerMenu, 66}, {IT_STRING|IT_CALL, NULL, "Splitscreen...", M_StartSplitServerMenu, 76}, @@ -11605,7 +11605,35 @@ static void M_StartServerMenu(INT32 choice) // CONNECT VIA IP // ============== -static char setupm_ip[28]; +static char setupm_ip[sizeof "[ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]:65535"]; + +static void M_DrawConnectIP(void) +{ + INT32 x = currentMenu->x; + INT32 y = currentMenu->y + 22; + + INT32 opt = V_ALLOWLOWERCASE; + INT32 width; + + V_DrawFill(x+5, y+4+5, /*16*8 + 6,*/ BASEVIDWIDTH - 2*(x+5), 8+6, 159); + + // draw name string + if (strlen(setupm_ip) > 30)/* w stands for wide boi */ + { + V_DrawThinString(x+8,y+12, opt, setupm_ip); + width = V_ThinStringWidth(setupm_ip, opt); + } + else + { + V_DrawString(x+8,y+12, opt, setupm_ip); + width = V_StringWidth(setupm_ip, opt); + } + + // draw text cursor for name + if (itemOn == 2 //0 + && skullAnimCounter < 4) //blink cursor + V_DrawCharacter(x+8+width,y+12,'_',false); +} // Draw the funky Connect IP menu. Tails 11-19-2002 // So much work for such a little thing! @@ -11626,17 +11654,7 @@ static void M_DrawMPMainMenu(void) V_DrawRightAlignedString(BASEVIDWIDTH-x, y+116, ((itemOn == 8) ? V_YELLOWMAP : 0), "(splitscreen)"); - y += 22; - - V_DrawFill(x+5, y+4+5, /*16*8 + 6,*/ BASEVIDWIDTH - 2*(x+5), 8+6, 159); - - // draw name string - V_DrawString(x+8,y+12, V_ALLOWLOWERCASE, setupm_ip); - - // draw text cursor for name - if (itemOn == 2 //0 - && skullAnimCounter < 4) //blink cursor - V_DrawCharacter(x+8+V_StringWidth(setupm_ip, V_ALLOWLOWERCASE),y+12,'_',false); + M_DrawConnectIP(); } // Tails 11-19-2002 @@ -11719,7 +11737,7 @@ static void M_HandleConnectIP(INT32 choice) const char *paste = I_ClipboardPaste(); if (paste != NULL) { - strncat(setupm_ip, paste, 28-1 - l); // Concat the ip field with clipboard + strncat(setupm_ip, paste, (sizeof setupm_ip)-1 - l); // Concat the ip field with clipboard if (strlen(paste) != 0) // Don't play sound if nothing was pasted S_StartSound(NULL,sfx_menu1); // Tails } @@ -11753,7 +11771,7 @@ static void M_HandleConnectIP(INT32 choice) const char *paste = I_ClipboardPaste(); if (paste != NULL) { - strncat(setupm_ip, paste, 28-1 - l); // Concat the ip field with clipboard + strncat(setupm_ip, paste, (sizeof setupm_ip)-1 - l); // Concat the ip field with clipboard if (strlen(paste) != 0) // Don't play sound if nothing was pasted S_StartSound(NULL,sfx_menu1); // Tails } @@ -11770,11 +11788,15 @@ static void M_HandleConnectIP(INT32 choice) } } - if (l >= 28-1) + if (l >= (sizeof setupm_ip)-1) break; // Rudimentary number and period enforcing - also allows letters so hostnames can be used instead - if ((choice >= '-' && choice <= ':') || (choice >= 'A' && choice <= 'Z') || (choice >= 'a' && choice <= 'z')) + // and square brackets for RFC 2732 IPv6 addresses + if ((choice >= '-' && choice <= ':') || + (choice == '[' || choice == ']') || + (choice >= 'A' && choice <= 'Z') || + (choice >= 'a' && choice <= 'z')) { S_StartSound(NULL,sfx_menu1); // Tails setupm_ip[l] = (char)choice; From 46a5ce4325fbe23234a8167bd16bc4ef6bf7ceee Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 1 Sep 2021 18:41:41 -0700 Subject: [PATCH 010/586] Only restrict master server connection to IPv4 if -noipv6 --- src/http-mserv.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/http-mserv.c b/src/http-mserv.c index f9134ba50..a0912a81e 100644 --- a/src/http-mserv.c +++ b/src/http-mserv.c @@ -196,7 +196,9 @@ HMS_connect (const char *format, ...) curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); - curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); + + if (M_CheckParm("-noipv6")) + curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); curl_easy_setopt(curl, CURLOPT_TIMEOUT, cv_masterserver_timeout.value); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, HMS_on_read); From 39fdbac2ace76cc1ead1b92b4f32d2aa17ad99d2 Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 3 Sep 2021 16:41:08 -0700 Subject: [PATCH 011/586] Only test -noipv6 if enabled at compile time --- src/http-mserv.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/http-mserv.c b/src/http-mserv.c index a0912a81e..0ab16f989 100644 --- a/src/http-mserv.c +++ b/src/http-mserv.c @@ -197,7 +197,9 @@ HMS_connect (const char *format, ...) curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); +#ifndef NO_IPV6 if (M_CheckParm("-noipv6")) +#endif curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); curl_easy_setopt(curl, CURLOPT_TIMEOUT, cv_masterserver_timeout.value); From b2fe36fe5b504ae2221a4306f76e663fff38090f Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 3 Sep 2021 16:48:29 -0700 Subject: [PATCH 012/586] Add back address resolution test Mistakenly removed by a1a58143e --- src/i_tcp.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/i_tcp.c b/src/i_tcp.c index 9cdcc6ec4..48a65faae 100644 --- a/src/i_tcp.c +++ b/src/i_tcp.c @@ -1204,7 +1204,11 @@ static SINT8 SOCK_NetMakeNodewPort(const char *address, const char *port) // test ip address of server for (i = 0; i < mysocketses; ++i) { - if (runp->ai_addr->sa_family == myfamily[i]) + /* sendto tests that there is a network to this + address */ + if (runp->ai_addr->sa_family == myfamily[i] && + sendto(mysockets[i], NULL, 0, 0, + runp->ai_addr, runp->ai_addrlen) == 0) { memcpy(&clientaddress[newnode], runp->ai_addr, runp->ai_addrlen); break; From 4424f6ba9a59b06c10d0bb683c8e00cded1d90db Mon Sep 17 00:00:00 2001 From: tertu marybig Date: Tue, 28 Sep 2021 08:31:14 -0500 Subject: [PATCH 013/586] Remove FixedMul and FixedDiv2 asm implementations Actually works this time --- src/m_fixed.c | 44 ---------------- src/m_fixed.h | 136 ++++++++------------------------------------------ 2 files changed, 22 insertions(+), 158 deletions(-) diff --git a/src/m_fixed.c b/src/m_fixed.c index d40ccd98e..315ac0bde 100644 --- a/src/m_fixed.c +++ b/src/m_fixed.c @@ -21,50 +21,6 @@ #include "doomdef.h" #include "m_fixed.h" -#ifdef __USE_C_FIXEDMUL__ - -/** \brief The FixedMul function - - \param a fixed_t number - \param b fixed_t number - - \return a*b>>FRACBITS - -*/ -fixed_t FixedMul(fixed_t a, fixed_t b) -{ - // Need to cast to unsigned before shifting to avoid undefined behaviour - // for negative integers - return (fixed_t)(((UINT64)((INT64)a * b)) >> FRACBITS); -} - -#endif //__USE_C_FIXEDMUL__ - -#ifdef __USE_C_FIXEDDIV__ -/** \brief The FixedDiv2 function - - \param a fixed_t number - \param b fixed_t number - - \return a/b * FRACUNIT - -*/ -fixed_t FixedDiv2(fixed_t a, fixed_t b) -{ - INT64 ret; - - if (b == 0) - I_Error("FixedDiv: divide by zero"); - - ret = (((INT64)a * FRACUNIT)) / b; - - if ((ret > INT32_MAX) || (ret < INT32_MIN)) - I_Error("FixedDiv: divide by zero"); - return (fixed_t)ret; -} - -#endif // __USE_C_FIXEDDIV__ - fixed_t FixedSqrt(fixed_t x) { #ifdef HAVE_SQRT diff --git a/src/m_fixed.h b/src/m_fixed.h index 1cf2f00d1..83b1710f7 100644 --- a/src/m_fixed.h +++ b/src/m_fixed.h @@ -53,127 +53,35 @@ FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FloatToFixed(float f) #define FIXED_TO_FLOAT(x) FixedToFloat(x) // (((float)(x)) / ((float)FRACUNIT)) #define FLOAT_TO_FIXED(f) FloatToFixed(f) // (fixed_t)((f) * ((float)FRACUNIT)) +/** \brief The FixedMul function -#if defined (__WATCOMC__) && FRACBITS == 16 - #pragma aux FixedMul = \ - "imul ebx", \ - "shrd eax,edx,16" \ - parm [eax] [ebx] \ - value [eax] \ - modify exact [eax edx] + \param a fixed_t number + \param b fixed_t number - #pragma aux FixedDiv2 = \ - "cdq", \ - "shld edx,eax,16", \ - "sal eax,16", \ - "idiv ebx" \ - parm [eax] [ebx] \ - value [eax] \ - modify exact [eax edx] -#elif defined (__GNUC__) && defined (__i386__) && !defined (NOASM) - // i386 linux, cygwin or mingw - FUNCMATH FUNCINLINE static inline fixed_t FixedMul(fixed_t a, fixed_t b) // asm - { - fixed_t ret; - asm - ( - "imull %2;" // a*b - "shrdl %3,%%edx,%0;" // shift logical right FRACBITS bits - :"=a" (ret) // eax is always the result and the first operand (%0,%1) - :"0" (a), "r" (b) // and %2 is what we use imull on with what in %1 - , "I" (FRACBITS) // %3 holds FRACBITS (normally 16) - :"cc", "%edx" // edx and condition codes clobbered - ); - return ret; - } + \return a*b>>FRACBITS - FUNCMATH FUNCINLINE static inline fixed_t FixedDiv2(fixed_t a, fixed_t b) - { - fixed_t ret; - asm - ( - "movl %1,%%edx;" // these two instructions allow the next two to pair, on the Pentium processor. - "sarl $31,%%edx;" // shift arithmetic right 31 on EDX - "shldl %3,%1,%%edx;" // DP shift logical left FRACBITS on EDX - "sall %3,%0;" // shift arithmetic left FRACBITS on EAX - "idivl %2;" // EDX/b = EAX - : "=a" (ret) - : "0" (a), "r" (b) - , "I" (FRACBITS) - : "%edx" - ); - return ret; - } -#elif defined (__GNUC__) && defined (__arm__) && !defined(__thumb__) && !defined(NOASM) //ARMv4 ASM - FUNCMATH FUNCINLINE static inline fixed_t FixedMul(fixed_t a, fixed_t b) // let abuse smull - { - fixed_t ret; - asm - ( - "smull %[lo], r1, %[a], %[b];" - "mov %[lo], %[lo], lsr %3;" - "orr %[lo], %[lo], r1, lsl %3;" - : [lo] "=&r" (ret) // rhi, rlo and rm must be distinct registers - : [a] "r" (a), [b] "r" (b) - , "i" (FRACBITS) - : "r1" - ); - return ret; - } +*/ +FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FixedMul(fixed_t a, fixed_t b) +{ + // Need to cast to unsigned before shifting to avoid undefined behaviour + // for negative integers + return (fixed_t)(((UINT64)((INT64)a * b)) >> FRACBITS); +} - #define __USE_C_FIXEDDIV__ // no double or asm div in ARM land -#elif defined (__GNUC__) && defined (__ppc__) && !defined(NOASM) && 0 // WII: PPC CPU - FUNCMATH FUNCINLINE static inline fixed_t FixedMul(fixed_t a, fixed_t b) // asm - { - fixed_t ret, hi, lo; - asm - ( - "mullw %0, %2, %3;" - "mulhw %1, %2, %3" - : "=r" (hi), "=r" (lo) - : "r" (a), "r" (b) - , "I" (FRACBITS) - ); - ret = (INT64)((hi>>FRACBITS)+lo)<>FRACBITS)+b)< Date: Tue, 7 Dec 2021 17:10:38 -0600 Subject: [PATCH 014/586] fix spike ring catapult --- src/p_map.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_map.c b/src/p_map.c index 836e75c4e..7e754bed9 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1144,7 +1144,7 @@ static boolean PIT_CheckThing(mobj_t *thing) } // When solid spikes move, assume they just popped up and teleport things on top of them to hurt. - if (tmthing->type == MT_SPIKE && tmthing->flags & MF_SOLID) + if (tmthing->type == MT_SPIKE && (thing->flags & MF_SOLID) && (tmthing->flags & MF_SOLID)) { if (thing->z > tmthing->z + tmthing->height) return true; // overhead From d764d68d02c1f7609c65534f7cfa07da724c42cd Mon Sep 17 00:00:00 2001 From: lachablock Date: Thu, 13 Jan 2022 18:53:26 +1100 Subject: [PATCH 015/586] Turn dispoffset into a mobj field --- src/hardware/hw_glob.h | 2 +- src/hardware/hw_main.c | 2 +- src/lua_mobjlib.c | 10 +++++++++- src/p_mobj.c | 2 ++ src/p_mobj.h | 1 + src/p_saveg.c | 9 +++++++++ src/r_things.c | 2 +- src/r_things.h | 2 +- 8 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/hardware/hw_glob.h b/src/hardware/hw_glob.h index 37d77b467..68c5dd14d 100644 --- a/src/hardware/hw_glob.h +++ b/src/hardware/hw_glob.h @@ -84,7 +84,7 @@ typedef struct gl_vissprite_s //Hurdler: 25/04/2000: now support colormap in hardware mode UINT8 *colormap; - INT32 dispoffset; // copy of info->dispoffset, affects ordering but not drawing + INT32 dispoffset; // copy of mobj->dispoffset, affects ordering but not drawing patch_t *gpatch; mobj_t *mobj; // NOTE: This is a precipmobj_t if precip is true !!! Watch out. diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index d2982afe4..ab2b7cae2 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5052,7 +5052,7 @@ static void HWR_ProjectSprite(mobj_t *thing) return; } - dispoffset = thing->info->dispoffset; + dispoffset = thing->dispoffset; this_scale = FIXED_TO_FLOAT(thing->scale); spritexscale = FIXED_TO_FLOAT(thing->spritexscale); diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index cf8ccab2c..ffdfe999d 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -96,7 +96,8 @@ enum mobj_e { mobj_standingslope, mobj_colorized, mobj_mirrored, - mobj_shadowscale + mobj_shadowscale, + mobj_dispoffset }; static const char *const mobj_opt[] = { @@ -173,6 +174,7 @@ static const char *const mobj_opt[] = { "colorized", "mirrored", "shadowscale", + "dispoffset", NULL}; #define UNIMPLEMENTED luaL_error(L, LUA_QL("mobj_t") " field " LUA_QS " is not implemented for Lua and cannot be accessed.", mobj_opt[field]) @@ -439,6 +441,9 @@ static int mobj_get(lua_State *L) case mobj_shadowscale: lua_pushfixed(L, mo->shadowscale); break; + case mobj_dispoffset: + lua_pushinteger(L, mo->dispoffset); + break; default: // extra custom variables in Lua memory lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS); I_Assert(lua_istable(L, -1)); @@ -803,6 +808,9 @@ static int mobj_set(lua_State *L) case mobj_shadowscale: mo->shadowscale = luaL_checkfixed(L, 3); break; + case mobj_dispoffset: + mo->dispoffset = luaL_checkinteger(L, 3); + break; default: lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS); I_Assert(lua_istable(L, -1)); diff --git a/src/p_mobj.c b/src/p_mobj.c index 87e20fd4a..10a01dbaa 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10499,6 +10499,8 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) mobj->reactiontime = info->reactiontime; + mobj->dispoffset = info->dispoffset; + mobj->lastlook = -1; // stuff moved in P_enemy.P_LookForPlayer // do not set the state with P_SetMobjState, diff --git a/src/p_mobj.h b/src/p_mobj.h index 2d096385b..d078137d8 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -390,6 +390,7 @@ typedef struct mobj_s boolean colorized; // Whether the mobj uses the rainbow colormap boolean mirrored; // The object's rotations will be mirrored left to right, e.g., see frame AL from the right and AR from the left fixed_t shadowscale; // If this object casts a shadow, and the size relative to radius + INT32 dispoffset; // copy of info->dispoffset, so mobjs can be sorted independently of their type // WARNING: New fields must be added separately to savegame and Lua. } mobj_t; diff --git a/src/p_saveg.c b/src/p_saveg.c index 722340f41..17c47c7a1 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1486,6 +1486,7 @@ typedef enum MD2_SPRITEXOFFSET = 1<<20, MD2_SPRITEYOFFSET = 1<<21, MD2_FLOORSPRITESLOPE = 1<<22, + MD2_DISPOFFSET = 1<<23 } mobj_diff2_t; typedef enum @@ -1720,6 +1721,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) || (slope->normal.z != FRACUNIT)) diff2 |= MD2_FLOORSPRITESLOPE; } + if (mobj->dispoffset != mobj->info->dispoffset) + diff2 |= MD2_DISPOFFSET; if (diff2 != 0) diff |= MD_MORE; @@ -1895,6 +1898,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) WRITEFIXED(save_p, slope->normal.y); WRITEFIXED(save_p, slope->normal.z); } + if (diff2 & MD2_DISPOFFSET) + WRITEINT32(save_p, mobj->dispoffset); WRITEUINT32(save_p, mobj->mobjnum); } @@ -2942,6 +2947,10 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) slope->normal.y = READFIXED(save_p); slope->normal.z = READFIXED(save_p); } + if (diff2 & MD2_DISPOFFSET) + mobj->dispoffset = READINT32(save_p); + else + mobj->dispoffset = mobj->info->dispoffset; if (diff & MD_REDFLAG) { diff --git a/src/r_things.c b/src/r_things.c index accd1e2b3..1dee17356 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1437,7 +1437,7 @@ static void R_ProjectSprite(mobj_t *thing) fixed_t paperoffset = 0, paperdistance = 0; angle_t centerangle = 0; - INT32 dispoffset = thing->info->dispoffset; + INT32 dispoffset = thing->dispoffset; //SoM: 3/17/2000 fixed_t gz = 0, gzt = 0; diff --git a/src/r_things.h b/src/r_things.h index b1ff32b1e..6a6ff3042 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -209,7 +209,7 @@ typedef struct vissprite_s INT16 clipbot[MAXVIDWIDTH], cliptop[MAXVIDWIDTH]; - INT32 dispoffset; // copy of info->dispoffset, affects ordering but not drawing + INT32 dispoffset; // copy of mobj->dispoffset, affects ordering but not drawing } vissprite_t; extern UINT32 visspritecount; From 3bff9011d8a7baed3281a3be3c664fc7d0bdc41c Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Fri, 21 Jan 2022 16:16:13 +0200 Subject: [PATCH 016/586] LUA_EnumLib optimizations for constant value access - constants are stored into _G after first use - made LUA_EvalMath's dedicated Lua state permanent so it can also benefit from these optimizations --- src/deh_lua.c | 169 +++++++++++++++++++++++++++++------------------ src/deh_lua.h | 15 +++++ src/deh_soc.c | 3 + src/lua_script.c | 23 ++++--- 4 files changed, 134 insertions(+), 76 deletions(-) diff --git a/src/deh_lua.c b/src/deh_lua.c index a2ffca95b..0bd906c13 100644 --- a/src/deh_lua.c +++ b/src/deh_lua.c @@ -10,20 +10,7 @@ /// \file deh_lua.c /// \brief Lua SOC library -#include "g_game.h" -#include "s_sound.h" -#include "z_zone.h" -#include "m_menu.h" -#include "m_misc.h" -#include "p_local.h" -#include "st_stuff.h" -#include "fastcmp.h" -#include "lua_script.h" -#include "lua_libs.h" - -#include "dehacked.h" #include "deh_lua.h" -#include "deh_tables.h" // freeslot takes a name (string only!) // and allocates it to the appropriate free slot. @@ -89,6 +76,8 @@ static inline int lib_freeslot(lua_State *L) strncpy(sprnames[j],word,4); //sprnames[j][4] = 0; used_spr[(j-SPR_FIRSTFREESLOT)/8] |= 1<<(j%8); // Okay, this sprite slot has been named now. + // Lua needs to update the value in _G if it exists + LUA_UpdateSprName(word, j); lua_pushinteger(L, j); r++; break; @@ -216,18 +205,27 @@ static int lib_dummysuper(lua_State *L) return luaL_error(L, "Can't call super() outside of hardcode-replacing A_Action functions being called by state changes!"); // convoluted, I know. @_@;; } -static inline int lib_getenum(lua_State *L) +static void CacheAndPushConstant(lua_State *L, const char *name, lua_Integer value) { - const char *word, *p; + // "cache" into _G + lua_pushstring(L, name); + lua_pushinteger(L, value); + lua_rawset(L, LUA_GLOBALSINDEX); + // push + lua_pushinteger(L, value); +} + +// Search for a matching constant variable. +// Result is stored into _G for faster subsequent use. (Except for SPR_ in the SOC parser) +static int ScanConstants(lua_State *L, boolean mathlib, const char *word) +{ + const char *p; fixed_t i; - boolean mathlib = lua_toboolean(L, lua_upvalueindex(1)); - if (lua_type(L,2) != LUA_TSTRING) - return 0; - word = lua_tostring(L,2); + if (strlen(word) == 1) { // Assume sprite frame if length 1. if (*word >= 'A' && *word <= '~') { - lua_pushinteger(L, *word-'A'); + CacheAndPushConstant(L, word, *word-'A'); return 1; } if (mathlib) return luaL_error(L, "constant '%s' could not be parsed.\n", word); @@ -237,7 +235,7 @@ static inline int lib_getenum(lua_State *L) p = word+3; for (i = 0; MOBJFLAG_LIST[i]; i++) if (fastcmp(p, MOBJFLAG_LIST[i])) { - lua_pushinteger(L, ((lua_Integer)1< Date: Tue, 25 Jan 2022 00:43:38 +0200 Subject: [PATCH 017/586] Fix Lua stack overflow in LUA_UpdateSprName --- src/deh_lua.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/deh_lua.c b/src/deh_lua.c index 0bd906c13..1f6a0659c 100644 --- a/src/deh_lua.c +++ b/src/deh_lua.c @@ -590,11 +590,12 @@ void LUA_UpdateSprName(const char *name, lua_Integer value) if (!lua_isnil(gL, -1)) { - lua_pop(gL, 1); lua_pushstring(gL, name); lua_pushinteger(gL, value); lua_rawset(gL, LUA_GLOBALSINDEX); } + + lua_pop(gL, 1); // pop the rawget result } int LUA_EnumLib(lua_State *L) From f5d4eb3e7aa6de763c2dda58800a2702a5da36e4 Mon Sep 17 00:00:00 2001 From: spherallic Date: Mon, 31 Jan 2022 14:39:51 +0100 Subject: [PATCH 018/586] Turn F11 into a fullscreen toggle, and process it inside menus as well. --- src/m_menu.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 3c1d8d7ca..7d4e4b8ae 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1347,7 +1347,7 @@ static menuitem_t OP_VideoOptionsMenu[] = #endif {IT_HEADER, NULL, "Color Profile", NULL, 30}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Brightness (F11)", &cv_globalgamma,36}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Brightness", &cv_globalgamma,36}, {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Saturation", &cv_globalsaturation, 41}, {IT_SUBMENU|IT_STRING, NULL, "Advanced Settings...", &OP_ColorOptionsDef, 46}, @@ -3399,8 +3399,8 @@ boolean M_Responder(event_t *ev) M_QuitSRB2(0); return true; - case KEY_F11: // Gamma Level - CV_AddValue(&cv_globalgamma, 1); + case KEY_F11: // Fullscreen toggle, also processed inside menus + CV_SetValue(&cv_fullscreen, !cv_fullscreen.value); return true; // Spymode on F12 handled in game logic @@ -3579,6 +3579,10 @@ boolean M_Responder(event_t *ev) // M_SetupNextMenu(currentMenu->prevMenu); return false; + case KEY_F11: // Fullscreen toggle, also processed outside menus + CV_SetValue(&cv_fullscreen, !cv_fullscreen.value); + return true; + default: CON_Responder(ev); break; From 020ce6a1ddda6d185ade732197c165f99a2c4931 Mon Sep 17 00:00:00 2001 From: spherallic Date: Mon, 31 Jan 2022 14:40:41 +0100 Subject: [PATCH 019/586] Rudimentary support for separate fullscreen/windowed resolutions. --- src/d_netcmd.c | 4 ++++ src/screen.c | 9 ++++++++- src/screen.h | 1 + 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index fe7e7678f..4ad6c8c51 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -872,6 +872,10 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_scr_width); CV_RegisterVar(&cv_scr_height); + CV_RegisterVar(&cv_usewindowedres); + CV_RegisterVar(&cv_scr_width_w); + CV_RegisterVar(&cv_scr_height_w); + CV_RegisterVar(&cv_soundtest); CV_RegisterVar(&cv_perfstats); diff --git a/src/screen.c b/src/screen.c index 770f1c802..19e6bf1bd 100644 --- a/src/screen.c +++ b/src/screen.c @@ -69,6 +69,10 @@ consvar_t cv_scr_height = CVAR_INIT ("scr_height", "800", CV_SAVE, CV_Unsigned, consvar_t cv_scr_depth = CVAR_INIT ("scr_depth", "16 bits", CV_SAVE, scr_depth_cons_t, NULL); consvar_t cv_renderview = CVAR_INIT ("renderview", "On", 0, CV_OnOff, NULL); +consvar_t cv_usewindowedres = CVAR_INIT ("usewindowedres", "No", CV_SAVE, CV_YesNo, NULL); +consvar_t cv_scr_width_w = CVAR_INIT ("scr_width_w", "640", CV_SAVE, CV_Unsigned, NULL); +consvar_t cv_scr_height_w = CVAR_INIT ("scr_height_w", "400", CV_SAVE, CV_Unsigned, NULL); + CV_PossibleValue_t cv_renderer_t[] = { {1, "Software"}, #ifdef HWRENDER @@ -405,7 +409,10 @@ void SCR_ChangeFullscreen(void) if (graphics_started) { VID_PrepareModeList(); - setmodeneeded = VID_GetModeForSize(vid.width, vid.height) + 1; + if (cv_usewindowedres.value == 1 && cv_fullscreen.value == 0) + setmodeneeded = VID_GetModeForSize(cv_scr_width_w.value, cv_scr_height_w.value) + 1; + else + setmodeneeded = VID_GetModeForSize(cv_scr_width.value, cv_scr_height.value) + 1; } return; #endif diff --git a/src/screen.h b/src/screen.h index 67880e2b9..3077973d2 100644 --- a/src/screen.h +++ b/src/screen.h @@ -190,6 +190,7 @@ extern INT32 scr_bpp; extern UINT8 *scr_borderpatch; // patch used to fill the view borders extern consvar_t cv_scr_width, cv_scr_height, cv_scr_depth, cv_renderview, cv_renderer, cv_fullscreen; +extern consvar_t cv_scr_width_w, cv_scr_height_w, cv_usewindowedres; // wait for page flipping to end or not extern consvar_t cv_vidwait; From 0cfc75070d92fa9e636a0e970c813d7d25bf1e11 Mon Sep 17 00:00:00 2001 From: spherallic Date: Fri, 4 Feb 2022 14:42:10 +0100 Subject: [PATCH 020/586] Improved support for separate resolutions: - Windowed mode resolution can now be changed via the resolutions menu. - F11 can also be used while in this menu. - Removed usewindowedres cvar for ease of use. - When starting in windowed mode, use the correct resolution. --- src/d_netcmd.c | 2 -- src/m_menu.c | 16 ++++++++++++---- src/screen.c | 35 +++++++++++++++++++++++------------ src/screen.h | 4 ++-- 4 files changed, 37 insertions(+), 20 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 4ad6c8c51..eda70a170 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -871,8 +871,6 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_scr_depth); CV_RegisterVar(&cv_scr_width); CV_RegisterVar(&cv_scr_height); - - CV_RegisterVar(&cv_usewindowedres); CV_RegisterVar(&cv_scr_width_w); CV_RegisterVar(&cv_scr_height_w); diff --git a/src/m_menu.c b/src/m_menu.c index 7d4e4b8ae..f07dffe5c 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1337,13 +1337,13 @@ static menuitem_t OP_VideoOptionsMenu[] = {IT_STRING | IT_CALL, NULL, "Set Resolution...", M_VideoModeMenu, 6}, #if defined (__unix__) || defined (UNIXCOMMON) || defined (HAVE_SDL) - {IT_STRING|IT_CVAR, NULL, "Fullscreen", &cv_fullscreen, 11}, + {IT_STRING|IT_CVAR, NULL, "Fullscreen (F11)", &cv_fullscreen, 11}, #endif {IT_STRING | IT_CVAR, NULL, "Vertical Sync", &cv_vidwait, 16}, #ifdef HWRENDER {IT_STRING | IT_CVAR, NULL, "Renderer", &cv_renderer, 21}, #else - {IT_TRANSTEXT | IT_PAIR, "Renderer", "Software", &cv_renderer, 21}, + {IT_TRANSTEXT | IT_PAIR, "Renderer", "Software", &cv_renderer, 21}, #endif {IT_HEADER, NULL, "Color Profile", NULL, 30}, @@ -13217,14 +13217,18 @@ static void M_DrawVideoMode(void) } else { - M_CentreText(OP_VideoModeDef.y + 116, + M_CentreText(OP_VideoModeDef.y + 100, va("Current mode is %c%dx%d", (SCR_IsAspectCorrect(vid.width, vid.height)) ? 0x83 : 0x80, vid.width, vid.height)); - M_CentreText(OP_VideoModeDef.y + 124, + M_CentreText(OP_VideoModeDef.y + 116, va("Default mode is %c%dx%d", (SCR_IsAspectCorrect(cv_scr_width.value, cv_scr_height.value)) ? 0x83 : 0x80, cv_scr_width.value, cv_scr_height.value)); + M_CentreText(OP_VideoModeDef.y + 124, + va("Windowed mode is %c%dx%d", + (SCR_IsAspectCorrect(cv_scr_width_w.value, cv_scr_height_w.value)) ? 0x83 : 0x80, + cv_scr_width_w.value, cv_scr_height_w.value)); V_DrawCenteredString(BASEVIDWIDTH/2, OP_VideoModeDef.y + 138, V_GREENMAP, "Green modes are recommended."); @@ -13438,6 +13442,10 @@ static void M_HandleVideoMode(INT32 ch) M_ClearMenus(true); break; + case KEY_F11: + CV_SetValue(&cv_fullscreen, !cv_fullscreen.value); + break; + default: break; } diff --git a/src/screen.c b/src/screen.c index 19e6bf1bd..96e436193 100644 --- a/src/screen.c +++ b/src/screen.c @@ -66,12 +66,10 @@ static CV_PossibleValue_t scr_depth_cons_t[] = {{8, "8 bits"}, {16, "16 bits"}, //added : 03-02-98: default screen mode, as loaded/saved in config consvar_t cv_scr_width = CVAR_INIT ("scr_width", "1280", CV_SAVE, CV_Unsigned, NULL); consvar_t cv_scr_height = CVAR_INIT ("scr_height", "800", CV_SAVE, CV_Unsigned, NULL); -consvar_t cv_scr_depth = CVAR_INIT ("scr_depth", "16 bits", CV_SAVE, scr_depth_cons_t, NULL); -consvar_t cv_renderview = CVAR_INIT ("renderview", "On", 0, CV_OnOff, NULL); - -consvar_t cv_usewindowedres = CVAR_INIT ("usewindowedres", "No", CV_SAVE, CV_YesNo, NULL); consvar_t cv_scr_width_w = CVAR_INIT ("scr_width_w", "640", CV_SAVE, CV_Unsigned, NULL); consvar_t cv_scr_height_w = CVAR_INIT ("scr_height_w", "400", CV_SAVE, CV_Unsigned, NULL); +consvar_t cv_scr_depth = CVAR_INIT ("scr_depth", "16 bits", CV_SAVE, scr_depth_cons_t, NULL); +consvar_t cv_renderview = CVAR_INIT ("renderview", "On", 0, CV_OnOff, NULL); CV_PossibleValue_t cv_renderer_t[] = { {1, "Software"}, @@ -370,10 +368,16 @@ void SCR_CheckDefaultMode(void) } else { - CONS_Printf(M_GetText("Default resolution: %d x %d (%d bits)\n"), cv_scr_width.value, - cv_scr_height.value, cv_scr_depth.value); - // see note above - setmodeneeded = VID_GetModeForSize(cv_scr_width.value, cv_scr_height.value) + 1; + if (cv_fullscreen.value == 0) + { + CONS_Printf(M_GetText("Default windowed resolution: %d x %d (%d bits)\n"), cv_scr_width_w.value, cv_scr_height_w.value, cv_scr_depth.value); + setmodeneeded = VID_GetModeForSize(cv_scr_width_w.value, cv_scr_height_w.value) + 1; // see note above + } + else + { + CONS_Printf(M_GetText("Default resolution: %d x %d (%d bits)\n"), cv_scr_width.value, cv_scr_height.value, cv_scr_depth.value); + setmodeneeded = VID_GetModeForSize(cv_scr_width.value, cv_scr_height.value) + 1; // see note above + } } if (cv_renderer.value != (signed)rendermode) @@ -392,9 +396,16 @@ void SCR_CheckDefaultMode(void) void SCR_SetDefaultMode(void) { // remember the default screen size - CV_SetValue(&cv_scr_width, vid.width); - CV_SetValue(&cv_scr_height, vid.height); - CV_SetValue(&cv_scr_depth, vid.bpp*8); + if (cv_fullscreen.value == 0) + { + CV_SetValue(&cv_scr_width_w, vid.width); + CV_SetValue(&cv_scr_height_w, vid.height); + } + else + { + CV_SetValue(&cv_scr_width, vid.width); + CV_SetValue(&cv_scr_height, vid.height); + } } // Change fullscreen on/off according to cv_fullscreen @@ -409,7 +420,7 @@ void SCR_ChangeFullscreen(void) if (graphics_started) { VID_PrepareModeList(); - if (cv_usewindowedres.value == 1 && cv_fullscreen.value == 0) + if (cv_fullscreen.value == 0) setmodeneeded = VID_GetModeForSize(cv_scr_width_w.value, cv_scr_height_w.value) + 1; else setmodeneeded = VID_GetModeForSize(cv_scr_width.value, cv_scr_height.value) + 1; diff --git a/src/screen.h b/src/screen.h index 3077973d2..30582793f 100644 --- a/src/screen.h +++ b/src/screen.h @@ -189,8 +189,8 @@ extern CV_PossibleValue_t cv_renderer_t[]; extern INT32 scr_bpp; extern UINT8 *scr_borderpatch; // patch used to fill the view borders -extern consvar_t cv_scr_width, cv_scr_height, cv_scr_depth, cv_renderview, cv_renderer, cv_fullscreen; -extern consvar_t cv_scr_width_w, cv_scr_height_w, cv_usewindowedres; +extern consvar_t cv_scr_width, cv_scr_height, cv_scr_width_w, cv_scr_height_w, cv_scr_depth, cv_fullscreen; +extern consvar_t cv_renderview, cv_renderer; // wait for page flipping to end or not extern consvar_t cv_vidwait; From 5fdc0b889bfc5c9429911c5c42d6a1209fc637ec Mon Sep 17 00:00:00 2001 From: spherallic Date: Fri, 4 Feb 2022 14:50:45 +0100 Subject: [PATCH 021/586] Replace F10's near-useless game quit option with a renderer toggle. --- src/m_menu.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index f07dffe5c..b54baa9dd 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1341,7 +1341,7 @@ static menuitem_t OP_VideoOptionsMenu[] = #endif {IT_STRING | IT_CVAR, NULL, "Vertical Sync", &cv_vidwait, 16}, #ifdef HWRENDER - {IT_STRING | IT_CVAR, NULL, "Renderer", &cv_renderer, 21}, + {IT_STRING | IT_CVAR, NULL, "Renderer (F10)", &cv_renderer, 21}, #else {IT_TRANSTEXT | IT_PAIR, "Renderer", "Software", &cv_renderer, 21}, #endif @@ -3395,8 +3395,11 @@ boolean M_Responder(event_t *ev) // Screenshots on F8 now handled elsewhere // Same with Moviemode on F9 - case KEY_F10: // Quit SRB2 - M_QuitSRB2(0); + case KEY_F10: // Renderer toggle, also processed inside menus + if (cv_renderer.value == render_soft) + CV_SetValue(&cv_renderer, render_opengl); + else if (cv_renderer.value == render_opengl) + CV_SetValue(&cv_renderer, render_soft); return true; case KEY_F11: // Fullscreen toggle, also processed inside menus @@ -3579,6 +3582,13 @@ boolean M_Responder(event_t *ev) // M_SetupNextMenu(currentMenu->prevMenu); return false; + case KEY_F10: // Renderer toggle, also processed outside menus + if (cv_renderer.value == render_soft) + CV_SetValue(&cv_renderer, render_opengl); + else if (cv_renderer.value == render_opengl) + CV_SetValue(&cv_renderer, render_soft); + return true; + case KEY_F11: // Fullscreen toggle, also processed outside menus CV_SetValue(&cv_fullscreen, !cv_fullscreen.value); return true; From 599644e885b9624eb72aecfe67b11939a8f4af46 Mon Sep 17 00:00:00 2001 From: spherallic Date: Sat, 5 Feb 2022 11:32:48 +0100 Subject: [PATCH 022/586] Update resolutions menu, remove M_CentreText. --- src/m_menu.c | 49 +++++++++++++++++++++++-------------------------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index b54baa9dd..c034aee48 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4228,15 +4228,6 @@ static void M_DrawSaveLoadBorder(INT32 x,INT32 y) } #endif -// horizontally centered text -static void M_CentreText(INT32 y, const char *string) -{ - INT32 x; - //added : 02-02-98 : centre on 320, because V_DrawString centers on vid.width... - x = (BASEVIDWIDTH - V_StringWidth(string, V_OLDSPACING))>>1; - V_DrawString(x,y,V_OLDSPACING,string); -} - // // M_DrawMapEmblems // @@ -12818,12 +12809,12 @@ static void M_DrawControl(void) if (tutorialmode && tutorialgcs) { if ((gametic / TICRATE) % 2) - M_CentreText(30, "\202EXIT THE TUTORIAL TO CHANGE THE CONTROLS"); + V_DrawCenteredString(BASEVIDWIDTH/2, 30, 0, "\202EXIT THE TUTORIAL TO CHANGE THE CONTROLS"); else - M_CentreText(30, "EXIT THE TUTORIAL TO CHANGE THE CONTROLS"); + V_DrawCenteredString(BASEVIDWIDTH/2, 30, 0, "EXIT THE TUTORIAL TO CHANGE THE CONTROLS"); } else - M_CentreText(30, + V_DrawCenteredString(BASEVIDWIDTH/2, 30, 0, (setupcontrols_secondaryplayer ? "SET CONTROLS FOR SECONDARY PLAYER" : "PRESS ENTER TO CHANGE, BACKSPACE TO CLEAR")); @@ -13188,11 +13179,11 @@ static void M_DrawVideoMode(void) // draw title M_DrawMenuTitle(); - V_DrawCenteredString(BASEVIDWIDTH/2, OP_VideoModeDef.y, - V_YELLOWMAP, "Choose mode, reselect to change default"); + V_DrawCenteredString(BASEVIDWIDTH/2, OP_VideoModeDef.y, V_YELLOWMAP, "Choose mode, reselect to change default"); + V_DrawCenteredString(BASEVIDWIDTH/2, OP_VideoModeDef.y+8, V_YELLOWMAP, "Press F11 to toggle fullscreen"); row = 41; - col = OP_VideoModeDef.y + 14; + col = OP_VideoModeDef.y + 24; for (i = 0; i < vidm_nummodes; i++) { if (i == vidm_selected) @@ -13205,7 +13196,7 @@ static void M_DrawVideoMode(void) if ((i % vidm_column_size) == (vidm_column_size-1)) { row += 7*13; - col = OP_VideoModeDef.y + 14; + col = OP_VideoModeDef.y + 24; } } @@ -13213,29 +13204,31 @@ static void M_DrawVideoMode(void) { INT32 testtime = (vidm_testingmode/TICRATE) + 1; - M_CentreText(OP_VideoModeDef.y + 116, + V_DrawCenteredString(BASEVIDWIDTH/2, OP_VideoModeDef.y + 116, 0, va("Previewing mode %c%dx%d", (SCR_IsAspectCorrect(vid.width, vid.height)) ? 0x83 : 0x80, vid.width, vid.height)); - M_CentreText(OP_VideoModeDef.y + 138, + V_DrawCenteredString(BASEVIDWIDTH/2, OP_VideoModeDef.y + 138, 0, "Press ENTER again to keep this mode"); - M_CentreText(OP_VideoModeDef.y + 150, + V_DrawCenteredString(BASEVIDWIDTH/2, OP_VideoModeDef.y + 150, 0, va("Wait %d second%s", testtime, (testtime > 1) ? "s" : "")); - M_CentreText(OP_VideoModeDef.y + 158, + V_DrawCenteredString(BASEVIDWIDTH/2, OP_VideoModeDef.y + 158, 0, "or press ESC to return"); - } else { - M_CentreText(OP_VideoModeDef.y + 100, + V_DrawFill(60, OP_VideoModeDef.y + 98, 200, 12, 159); + V_DrawFill(60, OP_VideoModeDef.y + 114, 200, 20, 159); + + V_DrawCenteredString(BASEVIDWIDTH/2, OP_VideoModeDef.y + 100, 0, va("Current mode is %c%dx%d", (SCR_IsAspectCorrect(vid.width, vid.height)) ? 0x83 : 0x80, vid.width, vid.height)); - M_CentreText(OP_VideoModeDef.y + 116, + V_DrawCenteredString(BASEVIDWIDTH/2, OP_VideoModeDef.y + 116, (cv_fullscreen.value ? 0 : V_TRANSLUCENT), va("Default mode is %c%dx%d", (SCR_IsAspectCorrect(cv_scr_width.value, cv_scr_height.value)) ? 0x83 : 0x80, cv_scr_width.value, cv_scr_height.value)); - M_CentreText(OP_VideoModeDef.y + 124, + V_DrawCenteredString(BASEVIDWIDTH/2, OP_VideoModeDef.y + 124, (cv_fullscreen.value ? V_TRANSLUCENT : 0), va("Windowed mode is %c%dx%d", (SCR_IsAspectCorrect(cv_scr_width_w.value, cv_scr_height_w.value)) ? 0x83 : 0x80, cv_scr_width_w.value, cv_scr_height_w.value)); @@ -13250,7 +13243,7 @@ static void M_DrawVideoMode(void) // Draw the cursor for the VidMode menu i = 41 - 10 + ((vidm_selected / vidm_column_size)*7*13); - j = OP_VideoModeDef.y + 14 + ((vidm_selected % vidm_column_size)*8); + j = OP_VideoModeDef.y + 24 + ((vidm_selected % vidm_column_size)*8); V_DrawScaledPatch(i - 8, j, 0, W_CachePatchName("M_CURSOR", PU_PATCH)); @@ -13433,11 +13426,14 @@ static void M_HandleVideoMode(INT32 ch) break; case KEY_ENTER: - S_StartSound(NULL, sfx_menu1); if (vid.modenum == modedescs[vidm_selected].modenum) + { + S_StartSound(NULL, sfx_strpst); SCR_SetDefaultMode(); + } else { + S_StartSound(NULL, sfx_menu1); vidm_testingmode = 15*TICRATE; vidm_previousmode = vid.modenum; if (!setmodeneeded) // in case the previous setmode was not finished @@ -13453,6 +13449,7 @@ static void M_HandleVideoMode(INT32 ch) break; case KEY_F11: + S_StartSound(NULL, sfx_menu1); CV_SetValue(&cv_fullscreen, !cv_fullscreen.value); break; From 35f2937fd114d16cf3e5374fa80c1dcca1220fb4 Mon Sep 17 00:00:00 2001 From: spherallic Date: Sun, 6 Feb 2022 16:13:45 +0100 Subject: [PATCH 023/586] Minor code cleanup & remove some unneeded resolution info from logs. --- src/screen.c | 34 +++++++++++----------------------- src/sdl/i_video.c | 4 ++-- 2 files changed, 13 insertions(+), 25 deletions(-) diff --git a/src/screen.c b/src/screen.c index 96e436193..f21ea2a93 100644 --- a/src/screen.c +++ b/src/screen.c @@ -368,16 +368,13 @@ void SCR_CheckDefaultMode(void) } else { - if (cv_fullscreen.value == 0) - { - CONS_Printf(M_GetText("Default windowed resolution: %d x %d (%d bits)\n"), cv_scr_width_w.value, cv_scr_height_w.value, cv_scr_depth.value); - setmodeneeded = VID_GetModeForSize(cv_scr_width_w.value, cv_scr_height_w.value) + 1; // see note above - } - else - { - CONS_Printf(M_GetText("Default resolution: %d x %d (%d bits)\n"), cv_scr_width.value, cv_scr_height.value, cv_scr_depth.value); + CONS_Printf(M_GetText("Default resolution: %d x %d\n"), cv_scr_width.value, cv_scr_height.value); + CONS_Printf(M_GetText("Windowed resolution: %d x %d\n"), cv_scr_width_w.value, cv_scr_height_w.value); + CONS_Printf(M_GetText("Default bit depth: %d bits\n"), cv_scr_depth.value); + if (cv_fullscreen.value) setmodeneeded = VID_GetModeForSize(cv_scr_width.value, cv_scr_height.value) + 1; // see note above - } + else + setmodeneeded = VID_GetModeForSize(cv_scr_width_w.value, cv_scr_height_w.value) + 1; // see note above } if (cv_renderer.value != (signed)rendermode) @@ -395,17 +392,8 @@ void SCR_CheckDefaultMode(void) // sets the modenum as the new default video mode to be saved in the config file void SCR_SetDefaultMode(void) { - // remember the default screen size - if (cv_fullscreen.value == 0) - { - CV_SetValue(&cv_scr_width_w, vid.width); - CV_SetValue(&cv_scr_height_w, vid.height); - } - else - { - CV_SetValue(&cv_scr_width, vid.width); - CV_SetValue(&cv_scr_height, vid.height); - } + CV_SetValue(cv_fullscreen.value ? &cv_scr_width : &cv_scr_width_w, vid.width); + CV_SetValue(cv_fullscreen.value ? &cv_scr_height : &cv_scr_height_w, vid.height); } // Change fullscreen on/off according to cv_fullscreen @@ -420,10 +408,10 @@ void SCR_ChangeFullscreen(void) if (graphics_started) { VID_PrepareModeList(); - if (cv_fullscreen.value == 0) - setmodeneeded = VID_GetModeForSize(cv_scr_width_w.value, cv_scr_height_w.value) + 1; - else + if (cv_fullscreen.value) setmodeneeded = VID_GetModeForSize(cv_scr_width.value, cv_scr_height.value) + 1; + else + setmodeneeded = VID_GetModeForSize(cv_scr_width_w.value, cv_scr_height_w.value) + 1; } return; #endif diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index ed766ff23..1642695d0 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1795,7 +1795,7 @@ void I_StartupGraphics(void) borderlesswindow = M_CheckParm("-borderless"); //SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY>>1,SDL_DEFAULT_REPEAT_INTERVAL<<2); - VID_Command_ModeList_f(); + //VID_Command_ModeList_f(); #ifdef HWRENDER if (rendermode == render_opengl) @@ -1843,7 +1843,7 @@ void I_StartupGraphics(void) realwidth = (Uint16)vid.width; realheight = (Uint16)vid.height; - VID_Command_Info_f(); + //VID_Command_Info_f(); SDLdoUngrabMouse(); SDL_RaiseWindow(window); From dcdbdec2bf8fffbc4b2d99ac89612cb9516cfcb9 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 6 Feb 2022 15:16:30 -0500 Subject: [PATCH 024/586] Make super for A_Actions act as described --- src/deh_lua.c | 61 +++++++++++++++++++++++++++++++------------- src/deh_tables.h | 1 + src/dehacked.h | 5 ++-- src/info.h | 3 ++- src/lua_infolib.c | 64 ++++++++++++++++++++++++++++++++++------------- src/lua_script.c | 14 ++++++++++- 6 files changed, 109 insertions(+), 39 deletions(-) diff --git a/src/deh_lua.c b/src/deh_lua.c index a2ffca95b..43e25a49d 100644 --- a/src/deh_lua.c +++ b/src/deh_lua.c @@ -195,25 +195,32 @@ static inline int lib_freeslot(lua_State *L) // Arguments: mobj_t actor, int var1, int var2 static int action_call(lua_State *L) { - //actionf_t *action = lua_touserdata(L,lua_upvalueindex(1)); actionf_t *action = *((actionf_t **)luaL_checkudata(L, 1, META_ACTION)); mobj_t *actor = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ)); + var1 = (INT32)luaL_optinteger(L, 3, 0); var2 = (INT32)luaL_optinteger(L, 4, 0); + if (!actor) + { return LUA_ErrInvalid(L, "mobj_t"); + } + action->acp1(actor); return 0; } // Hardcoded A_Action name to call for super() or NULL if super() would be invalid. // Set in lua_infolib. -const char *superactions[MAXRECURSION]; +const char *luaactions[MAX_ACTION_RECURSION]; +UINT8 luaactionstack = 0; UINT8 superstack = 0; static int lib_dummysuper(lua_State *L) { - return luaL_error(L, "Can't call super() outside of hardcode-replacing A_Action functions being called by state changes!"); // convoluted, I know. @_@;; + // TODO: Now that the restriction on only being allowed in state changes was lifted, + // it'd be nice to have super extend to Lua A_ functions too :) + return luaL_error(L, "Can't call super() outside of hardcode-replacing A_Action functions!"); } static inline int lib_getenum(lua_State *L) @@ -500,42 +507,62 @@ static inline int lib_getenum(lua_State *L) } else if (!mathlib && fastncmp("A_",word,2)) { char *caps; - // Try to get a Lua action first. - /// \todo Push a closure that sets superactions[] and superstack. + + // Hardcoded actions come first. + // Trying to call them will invoke LUA_CallAction, which will handle super properly. + // Retrieving them from this metatable allows them to be case-insensitive! + for (i = 0; actionpointers[i].name; i++) + { + if (fasticmp(word, actionpointers[i].name)) + { + // We push the actionf_t* itself as userdata! + LUA_PushUserdata(L, &actionpointers[i].action, META_ACTION); + return 1; + } + } + + // Now try to get Lua actions. + /// \todo Push a closure that sets luaactions[] and luaactionstack. + /// This would be part one of a step to get super functions working for custom A_ functions. + /// Custom functions. lua_getfield(L, LUA_REGISTRYINDEX, LREG_ACTIONS); + // actions are stored in all uppercase. caps = Z_StrDup(word); strupr(caps); lua_getfield(L, -1, caps); Z_Free(caps); + if (!lua_isnil(L, -1)) + { return 1; // Success! :D That was easy. + } + // Welp, that failed. lua_pop(L, 2); // pop nil and LREG_ACTIONS - - // Hardcoded actions as callable Lua functions! - // Retrieving them from this metatable allows them to be case-insensitive! - for (i = 0; actionpointers[i].name; i++) - if (fasticmp(word, actionpointers[i].name)) { - // We push the actionf_t* itself as userdata! - LUA_PushUserdata(L, &actionpointers[i].action, META_ACTION); - return 1; - } return 0; } else if (!mathlib && fastcmp("super",word)) { - if (!superstack) + if (!luaactionstack) { + // Not in A_ action routine lua_pushcfunction(L, lib_dummysuper); return 1; } + for (i = 0; actionpointers[i].name; i++) - if (fasticmp(superactions[superstack-1], actionpointers[i].name)) { + { + if (fasticmp(luaactions[luaactionstack-1], actionpointers[i].name)) + { LUA_PushUserdata(L, &actionpointers[i].action, META_ACTION); return 1; } - return 0; + } + + // Not a hardcoded A_ action. + lua_pushcfunction(L, lib_dummysuper); + return 1; } if (fastcmp(word, "BT_USE")) // Remove case when 2.3 nears release... diff --git a/src/deh_tables.h b/src/deh_tables.h index 1f265cc99..70347f7dd 100644 --- a/src/deh_tables.h +++ b/src/deh_tables.h @@ -30,6 +30,7 @@ extern UINT8 used_spr[(NUMSPRITEFREESLOTS / 8) + 1]; // Bitwise flag for sprite memset(FREE_MOBJS,0,sizeof(char *) * NUMMOBJFREESLOTS);\ memset(FREE_SKINCOLORS,0,sizeof(char *) * NUMCOLORFREESLOTS);\ memset(used_spr,0,sizeof(UINT8) * ((NUMSPRITEFREESLOTS / 8) + 1));\ + memset(actionsoverridden, LUA_REFNIL, sizeof(actionsoverridden));\ } struct flickytypes_s { diff --git a/src/dehacked.h b/src/dehacked.h index 1b200e246..e29aef6ff 100644 --- a/src/dehacked.h +++ b/src/dehacked.h @@ -40,8 +40,9 @@ extern boolean gamedataadded; extern boolean titlechanged; extern boolean introchanged; -#define MAXRECURSION 30 -extern const char *superactions[MAXRECURSION]; +#define MAX_ACTION_RECURSION 30 +extern const char *luaactions[MAX_ACTION_RECURSION]; +extern UINT8 luaactionstack; extern UINT8 superstack; // If the dehacked patch does not match this version, we throw a warning diff --git a/src/info.h b/src/info.h index 031a08b43..6e9460bec 100644 --- a/src/info.h +++ b/src/info.h @@ -18,6 +18,7 @@ #include "d_think.h" #include "sounds.h" #include "m_fixed.h" +#include "dehacked.h" // MAX_ACTION_RECURSION // deh_tables.c now has lists for the more named enums! PLEASE keep them up to date! // For great modding!! @@ -554,7 +555,7 @@ void A_DragonWing(); void A_DragonSegment(); void A_ChangeHeight(); -extern boolean actionsoverridden[NUMACTIONS]; +extern int actionsoverridden[NUMACTIONS][MAX_ACTION_RECURSION]; // ratio of states to sprites to mobj types is roughly 6 : 1 : 1 #define NUMMOBJFREESLOTS 512 diff --git a/src/lua_infolib.c b/src/lua_infolib.c index af2d99a0c..e20202495 100644 --- a/src/lua_infolib.c +++ b/src/lua_infolib.c @@ -66,7 +66,7 @@ const char *const sfxinfo_wopt[] = { "caption", NULL}; -boolean actionsoverridden[NUMACTIONS] = {false}; +int actionsoverridden[NUMACTIONS][MAX_ACTION_RECURSION]; // // Sprite Names @@ -645,8 +645,8 @@ static void A_Lua(mobj_t *actor) if (lua_rawequal(gL, -1, -4)) { found = true; - superactions[superstack] = lua_tostring(gL, -2); // "A_ACTION" - ++superstack; + luaactions[luaactionstack] = lua_tostring(gL, -2); // "A_ACTION" + ++luaactionstack; lua_pop(gL, 2); // pop the name and function break; } @@ -661,8 +661,8 @@ static void A_Lua(mobj_t *actor) if (found) { - --superstack; - superactions[superstack] = NULL; + --luaactionstack; + luaactions[luaactionstack] = NULL; } } @@ -816,18 +816,46 @@ boolean LUA_CallAction(enum actionnum actionnum, mobj_t *actor) { I_Assert(actor != NULL); - if (!actionsoverridden[actionnum]) // The action is not overriden, - return false; // action not called. + if (actionsoverridden[actionnum][0] == LUA_REFNIL) + { + // The action was not overridden at all, + // so call the hardcoded version. + return false; + } - if (superstack && fasticmp(actionpointers[actionnum].name, superactions[superstack-1])) // the action is calling itself, - return false; // let it call the hardcoded function instead. + if (luaactionstack && fasticmp(actionpointers[actionnum].name, luaactions[luaactionstack-1])) + { + // The action is calling itself, + // so look up the next Lua reference in its stack. + // 0 is just the reference to the one we're calling, + // so we increment here. + superstack++; + + if (superstack >= MAX_ACTION_RECURSION) + { + CONS_Alert(CONS_WARNING, "Max Lua super recursion reached! Cool it on calling super!\n"); + return false; + } + } + else + { + // Not calling itself, reset the super counter. + superstack = 0; + } + + if (actionsoverridden[actionnum][superstack] == LUA_REFNIL) + { + // No Lua reference beyond this point. + // Let it call the hardcoded function instead. + return false; + } + + // Push error function lua_pushcfunction(gL, LUA_GetErrorMessage); - // grab function by uppercase name. - lua_getfield(gL, LUA_REGISTRYINDEX, LREG_ACTIONS); - lua_getfield(gL, -1, actionpointers[actionnum].name); - lua_remove(gL, -2); // pop LREG_ACTIONS + // Push function by reference. + lua_getref(gL, actionsoverridden[actionnum][superstack]); if (lua_isnil(gL, -1)) // no match { @@ -835,7 +863,7 @@ boolean LUA_CallAction(enum actionnum actionnum, mobj_t *actor) return false; // action not called. } - if (superstack == MAXRECURSION) + if (luaactionstack >= MAX_ACTION_RECURSION) { CONS_Alert(CONS_WARNING, "Max Lua Action recursion reached! Cool it on the calling A_Action functions from inside A_Action functions!\n"); lua_pop(gL, 2); // pop function and error handler @@ -849,14 +877,14 @@ boolean LUA_CallAction(enum actionnum actionnum, mobj_t *actor) lua_pushinteger(gL, var1); lua_pushinteger(gL, var2); - superactions[superstack] = actionpointers[actionnum].name; - ++superstack; + luaactions[luaactionstack] = actionpointers[actionnum].name; + ++luaactionstack; LUA_Call(gL, 3, 0, -(2 + 3)); lua_pop(gL, -1); // Error handler - --superstack; - superactions[superstack] = NULL; + --luaactionstack; + luaactions[luaactionstack] = NULL; return true; // action successfully called. } diff --git a/src/lua_script.c b/src/lua_script.c index a1376ca2e..5441d315e 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -485,7 +485,19 @@ static int setglobals(lua_State *L) actionnum = LUA_GetActionNumByName(name); if (actionnum < NUMACTIONS) - actionsoverridden[actionnum] = true; + { + int i; + + for (i = MAX_ACTION_RECURSION-1; i > 0; i--) + { + // Move other references deeper. + actionsoverridden[actionnum][i] = actionsoverridden[actionnum][i - 1]; + } + + // Add the new reference. + lua_pushvalue(L, 2); + actionsoverridden[actionnum][0] = luaL_ref(L, LUA_REGISTRYINDEX); + } Z_Free(name); return 0; From c53f57a22fcf5e26164c41b29ba5be8e675d82a9 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 6 Feb 2022 18:31:10 -0500 Subject: [PATCH 025/586] Handle super stack more intelligently Counted per action type, and it is decremented after the function is called instead of keeping its old value or even resetting completely when using multiple actions together. --- src/deh_lua.c | 1 - src/dehacked.h | 1 - src/lua_infolib.c | 30 ++++++++++++++++++++---------- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/deh_lua.c b/src/deh_lua.c index 43e25a49d..62a1717a8 100644 --- a/src/deh_lua.c +++ b/src/deh_lua.c @@ -214,7 +214,6 @@ static int action_call(lua_State *L) // Set in lua_infolib. const char *luaactions[MAX_ACTION_RECURSION]; UINT8 luaactionstack = 0; -UINT8 superstack = 0; static int lib_dummysuper(lua_State *L) { diff --git a/src/dehacked.h b/src/dehacked.h index e29aef6ff..bf4d5c121 100644 --- a/src/dehacked.h +++ b/src/dehacked.h @@ -43,7 +43,6 @@ extern boolean introchanged; #define MAX_ACTION_RECURSION 30 extern const char *luaactions[MAX_ACTION_RECURSION]; extern UINT8 luaactionstack; -extern UINT8 superstack; // If the dehacked patch does not match this version, we throw a warning #define PATCHVERSION 220 diff --git a/src/lua_infolib.c b/src/lua_infolib.c index e20202495..ad7bc7b6f 100644 --- a/src/lua_infolib.c +++ b/src/lua_infolib.c @@ -812,6 +812,7 @@ boolean LUA_SetLuaAction(void *stv, const char *action) return true; // action successfully set. } +static UINT8 superstack[NUMACTIONS]; boolean LUA_CallAction(enum actionnum actionnum, mobj_t *actor) { I_Assert(actor != NULL); @@ -819,7 +820,7 @@ boolean LUA_CallAction(enum actionnum actionnum, mobj_t *actor) if (actionsoverridden[actionnum][0] == LUA_REFNIL) { // The action was not overridden at all, - // so call the hardcoded version. + // so just call the hardcoded version. return false; } @@ -830,24 +831,27 @@ boolean LUA_CallAction(enum actionnum actionnum, mobj_t *actor) // 0 is just the reference to the one we're calling, // so we increment here. - superstack++; + superstack[actionnum]++; - if (superstack >= MAX_ACTION_RECURSION) + if (superstack[actionnum] >= MAX_ACTION_RECURSION) { CONS_Alert(CONS_WARNING, "Max Lua super recursion reached! Cool it on calling super!\n"); + superstack[actionnum] = 0; return false; } } - else - { - // Not calling itself, reset the super counter. - superstack = 0; - } - if (actionsoverridden[actionnum][superstack] == LUA_REFNIL) + if (actionsoverridden[actionnum][superstack[actionnum]] == LUA_REFNIL) { // No Lua reference beyond this point. // Let it call the hardcoded function instead. + + if (superstack[actionnum]) + { + // Decrement super stack + superstack[actionnum]--; + } + return false; } @@ -855,7 +859,7 @@ boolean LUA_CallAction(enum actionnum actionnum, mobj_t *actor) lua_pushcfunction(gL, LUA_GetErrorMessage); // Push function by reference. - lua_getref(gL, actionsoverridden[actionnum][superstack]); + lua_getref(gL, actionsoverridden[actionnum][superstack[actionnum]]); if (lua_isnil(gL, -1)) // no match { @@ -883,6 +887,12 @@ boolean LUA_CallAction(enum actionnum actionnum, mobj_t *actor) LUA_Call(gL, 3, 0, -(2 + 3)); lua_pop(gL, -1); // Error handler + if (superstack[actionnum]) + { + // Decrement super stack + superstack[actionnum]--; + } + --luaactionstack; luaactions[luaactionstack] = NULL; return true; // action successfully called. From 7d1faf7e2c0f4db8c4d953dd40f7b899b4bfadef Mon Sep 17 00:00:00 2001 From: spherallic Date: Sat, 19 Feb 2022 12:12:04 +0100 Subject: [PATCH 026/586] Handle invalid resolutions, make Backspace work in resolution menu. --- src/m_menu.c | 16 ++++++++++++++-- src/screen.c | 9 +++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index c034aee48..220d67a3f 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -13226,11 +13226,11 @@ static void M_DrawVideoMode(void) vid.width, vid.height)); V_DrawCenteredString(BASEVIDWIDTH/2, OP_VideoModeDef.y + 116, (cv_fullscreen.value ? 0 : V_TRANSLUCENT), va("Default mode is %c%dx%d", - (SCR_IsAspectCorrect(cv_scr_width.value, cv_scr_height.value)) ? 0x83 : 0x80, + (SCR_IsAspectCorrect(cv_scr_width.value, cv_scr_height.value)) ? 0x83 : (!(VID_GetModeForSize(cv_scr_width.value, cv_scr_height.value)+1) ? 0x85 : 0x80), cv_scr_width.value, cv_scr_height.value)); V_DrawCenteredString(BASEVIDWIDTH/2, OP_VideoModeDef.y + 124, (cv_fullscreen.value ? V_TRANSLUCENT : 0), va("Windowed mode is %c%dx%d", - (SCR_IsAspectCorrect(cv_scr_width_w.value, cv_scr_height_w.value)) ? 0x83 : 0x80, + (SCR_IsAspectCorrect(cv_scr_width_w.value, cv_scr_height_w.value)) ? 0x83 : (!(VID_GetModeForSize(cv_scr_width_w.value, cv_scr_height_w.value)+1) ? 0x85 : 0x80), cv_scr_width_w.value, cv_scr_height_w.value)); V_DrawCenteredString(BASEVIDWIDTH/2, OP_VideoModeDef.y + 138, @@ -13448,6 +13448,18 @@ static void M_HandleVideoMode(INT32 ch) M_ClearMenus(true); break; + case KEY_BACKSPACE: + S_StartSound(NULL, sfx_menu1); + CV_Set(&cv_scr_width, cv_scr_width.defaultvalue); + CV_Set(&cv_scr_height, cv_scr_height.defaultvalue); + CV_Set(&cv_scr_width_w, cv_scr_width_w.defaultvalue); + CV_Set(&cv_scr_height_w, cv_scr_height_w.defaultvalue); + if (cv_fullscreen.value) + setmodeneeded = VID_GetModeForSize(cv_scr_width.value, cv_scr_height.value)+1; + else + setmodeneeded = VID_GetModeForSize(cv_scr_width_w.value, cv_scr_height_w.value)+1; + break; + case KEY_F11: S_StartSound(NULL, sfx_menu1); CV_SetValue(&cv_fullscreen, !cv_fullscreen.value); diff --git a/src/screen.c b/src/screen.c index f21ea2a93..3a548bece 100644 --- a/src/screen.c +++ b/src/screen.c @@ -375,6 +375,9 @@ void SCR_CheckDefaultMode(void) setmodeneeded = VID_GetModeForSize(cv_scr_width.value, cv_scr_height.value) + 1; // see note above else setmodeneeded = VID_GetModeForSize(cv_scr_width_w.value, cv_scr_height_w.value) + 1; // see note above + + if (setmodeneeded <= 0) + CONS_Alert(CONS_WARNING, "Invalid resolution given, defaulting to base resolution\n"); } if (cv_renderer.value != (signed)rendermode) @@ -412,6 +415,12 @@ void SCR_ChangeFullscreen(void) setmodeneeded = VID_GetModeForSize(cv_scr_width.value, cv_scr_height.value) + 1; else setmodeneeded = VID_GetModeForSize(cv_scr_width_w.value, cv_scr_height_w.value) + 1; + + if (setmodeneeded <= 0) // hacky safeguard + { + CONS_Alert(CONS_WARNING, "Invalid resolution given, defaulting to base resolution.\n"); + setmodeneeded = VID_GetModeForSize(BASEVIDWIDTH, BASEVIDHEIGHT) + 1; + } } return; #endif From f077021591132c3e9c565169e70e030bd378bbf0 Mon Sep 17 00:00:00 2001 From: spherallic Date: Sat, 19 Feb 2022 15:15:06 +0100 Subject: [PATCH 027/586] Clean up renderer toggle at SteelT's suggestion. --- src/m_menu.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 220d67a3f..c3c7db923 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -3396,10 +3396,7 @@ boolean M_Responder(event_t *ev) // Same with Moviemode on F9 case KEY_F10: // Renderer toggle, also processed inside menus - if (cv_renderer.value == render_soft) - CV_SetValue(&cv_renderer, render_opengl); - else if (cv_renderer.value == render_opengl) - CV_SetValue(&cv_renderer, render_soft); + CV_AddValue(&cv_renderer, 1); return true; case KEY_F11: // Fullscreen toggle, also processed inside menus @@ -3583,10 +3580,7 @@ boolean M_Responder(event_t *ev) return false; case KEY_F10: // Renderer toggle, also processed outside menus - if (cv_renderer.value == render_soft) - CV_SetValue(&cv_renderer, render_opengl); - else if (cv_renderer.value == render_opengl) - CV_SetValue(&cv_renderer, render_soft); + CV_AddValue(&cv_renderer, 1); return true; case KEY_F11: // Fullscreen toggle, also processed outside menus From f7b166da07d821c655cc804111d419ab3c14c694 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 27 Feb 2022 07:56:45 -0500 Subject: [PATCH 028/586] Refresh sprite2s Allows for custom characters to be loaded first, then a wad that adds a custom sprite2, and the custom character's sprite2s won't be discarded. --- src/deh_lua.c | 3 + src/deh_soc.c | 2 + src/r_skins.c | 156 ++++++++++++++++++++++++++++++++++++++++++++++++-- src/r_skins.h | 2 + 4 files changed, 158 insertions(+), 5 deletions(-) diff --git a/src/deh_lua.c b/src/deh_lua.c index a2ffca95b..7984a38c8 100644 --- a/src/deh_lua.c +++ b/src/deh_lua.c @@ -188,6 +188,9 @@ static inline int lib_freeslot(lua_State *L) lua_remove(L, 1); continue; } + + R_RefreshSprite2(); + return r; } diff --git a/src/deh_soc.c b/src/deh_soc.c index 3a611f3ba..dd33594ea 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -513,6 +513,8 @@ void readfreeslots(MYFILE *f) } while (!myfeof(f)); // finish when the line is empty Z_Free(s); + + R_RefreshSprite2(); } void readthing(MYFILE *f, INT32 num) diff --git a/src/r_skins.c b/src/r_skins.c index 86c0bbc54..010280403 100644 --- a/src/r_skins.c +++ b/src/r_skins.c @@ -499,7 +499,7 @@ static UINT16 W_CheckForPatchSkinMarkerInPwad(UINT16 wadid, UINT16 startlump) return INT16_MAX; // not found } -static void R_LoadSkinSprites(UINT16 wadnum, UINT16 *lump, UINT16 *lastlump, skin_t *skin) +static void R_LoadSkinSprites(UINT16 wadnum, UINT16 *lump, UINT16 *lastlump, skin_t *skin, UINT8 start_spr2) { UINT16 newlastlump; UINT8 sprite2; @@ -521,7 +521,7 @@ static void R_LoadSkinSprites(UINT16 wadnum, UINT16 *lump, UINT16 *lastlump, ski { newlastlump++; // load all sprite sets we are aware of... for super! - for (sprite2 = 0; sprite2 < free_spr2; sprite2++) + for (sprite2 = start_spr2; sprite2 < free_spr2; sprite2++) R_AddSingleSpriteDef(spr2names[sprite2], &skin->sprites[FF_SPR2SUPER|sprite2], wadnum, newlastlump, *lastlump); newlastlump--; @@ -529,7 +529,7 @@ static void R_LoadSkinSprites(UINT16 wadnum, UINT16 *lump, UINT16 *lastlump, ski } // load all sprite sets we are aware of... for normal stuff. - for (sprite2 = 0; sprite2 < free_spr2; sprite2++) + for (sprite2 = start_spr2; sprite2 < free_spr2; sprite2++) R_AddSingleSpriteDef(spr2names[sprite2], &skin->sprites[sprite2], wadnum, *lump, *lastlump); if (skin->sprites[0].numframes == 0) @@ -795,7 +795,7 @@ next_token: free(buf2); // Add sprites - R_LoadSkinSprites(wadnum, &lump, &lastlump, skin); + R_LoadSkinSprites(wadnum, &lump, &lastlump, skin, 0); //ST_LoadFaceGraphics(numskins); -- nah let's do this elsewhere R_FlushTranslationColormapCache(); @@ -928,7 +928,7 @@ next_token: } // Patch sprites - R_LoadSkinSprites(wadnum, &lump, &lastlump, skin); + R_LoadSkinSprites(wadnum, &lump, &lastlump, skin, 0); //ST_LoadFaceGraphics(skinnum); -- nah let's do this elsewhere R_FlushTranslationColormapCache(); @@ -941,3 +941,149 @@ next_token: #undef HUDNAMEWRITE #undef SYMBOLCONVERT + +static UINT16 W_CheckForEitherSkinMarkerInPwad(UINT16 wadid, UINT16 startlump) +{ + UINT16 i; + const char *S_SKIN = "S_SKIN"; + 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,S_SKIN,6)==0 || memcmp(lump_p->name,P_SKIN,6)==0) + return i; + } + return INT16_MAX; // not found +} + +static void R_RefreshSprite2ForWad(UINT16 wadnum, UINT8 start_spr2) +{ + UINT16 lump, lastlump = 0; + char *buf; + char *buf2; + char *stoken; + char *value; + size_t size; + skin_t *skin; + boolean noskincomplain; + + // + // search for all skin patch markers in pwad + // + + while ((lump = W_CheckForEitherSkinMarkerInPwad(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_RefreshSprite2ForWad: No more free memory\n"); + M_Memcpy(buf2,buf,size); + buf2[size] = '\0'; + + skin = NULL; + noskincomplain = 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_RefreshSprite2ForWad: syntax error in P_SKIN lump# %d(%s) in WAD %s\n", lump, W_CheckNameForNumPwad(wadnum,lump), wadfiles[wadnum]->filename); + + if (!stricmp(stoken, "name")) + { + strlwr(value); + skinnum = R_SkinAvailable(value); + if (skinnum != -1) + skin = &skins[skinnum]; + else + { + CONS_Debug(DBG_SETUP, "R_RefreshSprite2ForWad: unknown skin name in P_SKIN lump# %d(%s) in WAD %s\n", lump, W_CheckNameForNumPwad(wadnum,lump), wadfiles[wadnum]->filename); + noskincomplain = true; + } + } + + if (!skin) + break; + +next_token: + stoken = strtok(NULL, "\r\n= "); + } + free(buf2); + + if (!skin) // Didn't include a name parameter? What a waste. + { + if (!noskincomplain) + CONS_Debug(DBG_SETUP, "R_RefreshSprite2ForWad: no skin name given in P_SKIN lump #%d (WAD %s)\n", lump, wadfiles[wadnum]->filename); + continue; + } + + // Update sprites, in the range of (start_spr2 - free_spr2-1) + R_LoadSkinSprites(wadnum, &lump, &lastlump, skin, start_spr2); + //R_FlushTranslationColormapCache(); // I don't think this is needed for what we're doing? + } +} + +static playersprite_t old_spr2 = SPR2_FIRSTFREESLOT; +void R_RefreshSprite2(void) +{ + // Sprite2s being defined by custom wads can create situations where + // a custom character might want to add support, but due to load order, + // might not be defined in time. + + // The trick where you load characters then level packs to keep savedata + // in particular will practically garantuee a level pack can NEVER add custom animations, + // because custom character's Sprite2s will not be added. + + // So, go through every file, and reload the sprite2s that were added. + + INT32 i; + + if (old_spr2 > free_spr2) + { +#ifdef PARANOIA + I_Error("R_RefreshSprite2: old_spr2 is too high?! (old_spr2: %d, free_spr2: %d)\n", old_spr2, free_spr2); +#else + // Just silently fix + old_spr2 = free_spr2; +#endif + } + + if (old_spr2 == free_spr2) + { + // No sprite2s were added since the last time we did freeslots. + return; + } + + for (i = 0; i < numwadfiles; i++) + { + R_RefreshSprite2ForWad(i, old_spr2); + } + + // Update previous value. + old_spr2 = free_spr2; +} diff --git a/src/r_skins.h b/src/r_skins.h index a38997f4d..2ef1bdd65 100644 --- a/src/r_skins.h +++ b/src/r_skins.h @@ -100,4 +100,6 @@ void R_PatchSkins(UINT16 wadnum, boolean mainfile); UINT8 P_GetSkinSprite2(skin_t *skin, UINT8 spr2, player_t *player); +void R_RefreshSprite2(void); + #endif //__R_SKINS__ From 6a969c163b4f72b98c5d24d1eafe30e02045c044 Mon Sep 17 00:00:00 2001 From: spherallic Date: Wed, 6 Apr 2022 15:31:25 +0200 Subject: [PATCH 029/586] Make boss 3's shockwave into a customizable action. --- src/deh_tables.c | 1 + src/info.h | 2 ++ src/p_enemy.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+) diff --git a/src/deh_tables.c b/src/deh_tables.c index 8dbe314cc..bed81e60c 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -198,6 +198,7 @@ actionpointer_t actionpointers[] = {{A_Boss3TakeDamage}, "A_BOSS3TAKEDAMAGE"}, {{A_Boss3Path}, "A_BOSS3PATH"}, {{A_Boss3ShockThink}, "A_BOSS3SHOCKTHINK"}, + {{A_Shockwave}, "A_SHOCKWAVE"}, {{A_LinedefExecute}, "A_LINEDEFEXECUTE"}, {{A_PlaySeeSound}, "A_PLAYSEESOUND"}, {{A_PlayAttackSound}, "A_PLAYATTACKSOUND"}, diff --git a/src/info.h b/src/info.h index 1b7a201ce..04c048dd8 100644 --- a/src/info.h +++ b/src/info.h @@ -151,6 +151,7 @@ enum actionnum A_BOSS3TAKEDAMAGE, A_BOSS3PATH, A_BOSS3SHOCKTHINK, + A_SHOCKWAVE, A_LINEDEFEXECUTE, A_PLAYSEESOUND, A_PLAYATTACKSOUND, @@ -414,6 +415,7 @@ void A_Boss1Spikeballs(); void A_Boss3TakeDamage(); void A_Boss3Path(); void A_Boss3ShockThink(); +void A_Shockwave(); void A_LinedefExecute(); void A_PlaySeeSound(); void A_PlayAttackSound(); diff --git a/src/p_enemy.c b/src/p_enemy.c index 87aa5ff2f..efa413a44 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -173,6 +173,7 @@ void A_Boss1Spikeballs(mobj_t *actor); void A_Boss3TakeDamage(mobj_t *actor); void A_Boss3Path(mobj_t *actor); void A_Boss3ShockThink(mobj_t *actor); +void A_Shockwave(mobj_t *actor); void A_LinedefExecute(mobj_t *actor); void A_PlaySeeSound(mobj_t *actor); void A_PlayAttackSound(mobj_t *actor); @@ -8326,6 +8327,56 @@ void A_Boss3ShockThink(mobj_t *actor) } } +// Function: A_Shockwave +// +// Description: Spawns a shockwave of objects. Best used to spawn objects that call A_Boss3ShockThink. +// +// var1 = object spawned +// var2 = amount of objects spawned +// +void A_Shockwave(mobj_t *actor) +{ + INT32 locvar1 = var1; + INT32 locvar2 = var2; + INT32 i; + + angle_t ang = 0, interval; + mobj_t *shock = NULL, *sfirst = NULL, *sprev = NULL; + + if (LUA_CallAction(A_SHOCKWAVE, actor)) + return; + + if (locvar2 == 0) + locvar2 = 24; // a sensible default, just in case + + interval = FixedAngle((360 << FRACBITS) / locvar2); + + for (i = 0; i < locvar2; i++) + { + shock = P_SpawnMobj(actor->x, actor->y, actor->z, locvar1); + P_SetTarget(&shock->target, actor); + shock->fuse = shock->info->painchance; + + if (i % 2 == 0) + P_SetMobjState(shock, shock->state->nextstate); + + if (!sprev) + sfirst = shock; + else + { + if (i == locvar2 - 1) + P_SetTarget(&shock->hnext, sfirst); + P_SetTarget(&sprev->hnext, shock); + } + + P_Thrust(shock, ang, shock->info->speed); + ang += interval; + sprev = shock; + } + + S_StartSound(actor, shock->info->seesound); +} + // Function: A_LinedefExecute // // Description: Object's location is used to set the calling sector. The tag used is var1. Optionally, if var2 is set, the actor's angle (multiplied by var2) is added to the tag number as well. From f564090c80c1ea54ebfebcdac0ea64618c5d0c6b Mon Sep 17 00:00:00 2001 From: spherallic Date: Wed, 7 Sep 2022 14:00:56 +0200 Subject: [PATCH 030/586] Two small renderer switching changes: - Allow renderer switching in resolution menu - Fix "(F10)" suffix not being shown on the renderer option --- src/m_menu.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/m_menu.c b/src/m_menu.c index b527c4c1a..19c5eaeaf 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -2157,7 +2157,7 @@ static void M_VideoOptions(INT32 choice) { OP_VideoOptionsMenu[op_video_renderer].status = (IT_STRING | IT_CVAR); OP_VideoOptionsMenu[op_video_renderer].patch = NULL; - OP_VideoOptionsMenu[op_video_renderer].text = "Renderer"; + OP_VideoOptionsMenu[op_video_renderer].text = "Renderer (F10)"; } #endif @@ -13456,6 +13456,10 @@ static void M_HandleVideoMode(INT32 ch) setmodeneeded = VID_GetModeForSize(cv_scr_width_w.value, cv_scr_height_w.value)+1; break; + case KEY_F10: // Renderer toggle, also processed inside menus + CV_AddValue(&cv_renderer, 1); + break; + case KEY_F11: S_StartSound(NULL, sfx_menu1); CV_SetValue(&cv_fullscreen, !cv_fullscreen.value); From 3da9fb636aebd8311e4119f7f6af65a924a0e0df Mon Sep 17 00:00:00 2001 From: spherallic Date: Sat, 17 Sep 2022 10:51:16 +0200 Subject: [PATCH 031/586] Add plane scroller features to binary map format: - Added actions for scrolling floor + ceiling simultaneously - Added flag to use X offset for speed, instead of line length --- extras/conf/SRB2-22.cfg | 89 +++++++++++++++++++- extras/conf/udb/Includes/SRB222_linedefs.cfg | 47 ++++++++++- src/p_setup.c | 13 ++- 3 files changed, 146 insertions(+), 3 deletions(-) diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg index 969f645f3..0bf009f79 100644 --- a/extras/conf/SRB2-22.cfg +++ b/extras/conf/SRB2-22.cfg @@ -2824,36 +2824,63 @@ linedeftypes { title = "Scroll Floor Texture"; prefix = "(510)"; + flags8192text = "[13] Use angle and X offset"; } 511 { title = "Scroll Floor Texture (Accelerative)"; prefix = "(511)"; + flags8192text = "[13] Use angle and X offset"; } 512 { title = "Scroll Floor Texture (Displacement)"; prefix = "(512)"; + flags8192text = "[13] Use angle and X offset"; } 513 { title = "Scroll Ceiling Texture"; prefix = "(513)"; + flags8192text = "[13] Use angle and X offset"; } 514 { title = "Scroll Ceiling Texture (Accelerative)"; prefix = "(514)"; + flags8192text = "[13] Use angle and X offset"; } 515 { title = "Scroll Ceiling Texture (Displacement)"; prefix = "(515)"; + flags8192text = "[13] Use angle and X offset"; + } + + 516 + { + title = "Scroll Floor and Ceiling Texture"; + prefix = "(516)"; + flags8192text = "[13] Use angle and X offset"; + } + + 517 + { + title = "Scroll Floor and Ceiling Texture (Accelerative)"; + prefix = "(517)"; + flags8192text = "[13] Use angle and X offset"; + } + + 518 + { + title = "Scroll Floor and Ceiling Texture (Displacement)"; + prefix = "(518)"; + flags8192text = "[13] Use angle and X offset"; } 520 @@ -2861,6 +2888,7 @@ linedeftypes title = "Carry Objects on Floor"; prefix = "(520)"; flags64text = "[6] Exclusive"; + flags8192text = "[13] Use angle and X offset"; } 521 @@ -2868,6 +2896,7 @@ linedeftypes title = "Carry Objects on Floor (Accelerative)"; prefix = "(521)"; flags64text = "[6] Exclusive"; + flags8192text = "[13] Use angle and X offset"; } 522 @@ -2875,6 +2904,7 @@ linedeftypes title = "Carry Objects on Floor (Displacement)"; prefix = "(522)"; flags64text = "[6] Exclusive"; + flags8192text = "[13] Use angle and X offset"; } 523 @@ -2882,6 +2912,7 @@ linedeftypes title = "Carry Objects on Ceiling"; prefix = "(523)"; flags64text = "[6] Exclusive"; + flags8192text = "[13] Use angle and X offset"; } 524 @@ -2889,6 +2920,7 @@ linedeftypes title = "Carry Objects on Ceiling (Accelerative)"; prefix = "(524)"; flags64text = "[6] Exclusive"; + flags8192text = "[13] Use angle and X offset"; } 525 @@ -2896,6 +2928,31 @@ linedeftypes title = "Carry Objects on Ceiling (Displacement)"; prefix = "(525)"; flags64text = "[6] Exclusive"; + flags8192text = "[13] Use angle and X offset"; + } + + 526 + { + title = "Carry Objects on Floor and Ceiling"; + prefix = "(526)"; + flags64text = "[6] Exclusive"; + flags8192text = "[13] Use angle and X offset"; + } + + 527 + { + title = "Carry Objects on Floor and Ceiling (Accelerative)"; + prefix = "(527)"; + flags64text = "[6] Exclusive"; + flags8192text = "[13] Use angle and X offset"; + } + + 528 + { + title = "Carry Objects on Floor and Ceiling (Displacement)"; + prefix = "(528)"; + flags64text = "[6] Exclusive"; + flags8192text = "[13] Use angle and X offset"; } 530 @@ -2903,6 +2960,7 @@ linedeftypes title = "Scroll Floor Texture and Carry Objects"; prefix = "(530)"; flags64text = "[6] Exclusive"; + flags8192text = "[13] Use angle and X offset"; } 531 @@ -2910,6 +2968,7 @@ linedeftypes title = "Scroll Floor Texture and Carry Objects (Accelerative)"; prefix = "(531)"; flags64text = "[6] Exclusive"; + flags8192text = "[13] Use angle and X offset"; } 532 @@ -2917,6 +2976,7 @@ linedeftypes title = "Scroll Floor Texture and Carry Objects (Displacement)"; prefix = "(532)"; flags64text = "[6] Exclusive"; + flags8192text = "[13] Use angle and X offset"; } 533 @@ -2924,6 +2984,7 @@ linedeftypes title = "Scroll Ceiling Texture and Carry Objects"; prefix = "(533)"; flags64text = "[6] Exclusive"; + flags8192text = "[13] Use angle and X offset"; } 534 @@ -2931,6 +2992,7 @@ linedeftypes title = "Scroll Ceiling Texture and Carry Objects (Accelerative)"; prefix = "(534)"; flags64text = "[6] Exclusive"; + flags8192text = "[13] Use angle and X offset"; } 535 @@ -2938,6 +3000,31 @@ linedeftypes title = "Scroll Ceiling Texture and Carry Objects (Displacement)"; prefix = "(535)"; flags64text = "[6] Exclusive"; + flags8192text = "[13] Use angle and X offset"; + } + + 536 + { + title = "Scroll Floor and Ceiling Texture and Carry Objects"; + prefix = "(536)"; + flags64text = "[6] Exclusive"; + flags8192text = "[13] Use angle and X offset"; + } + + 537 + { + title = "Scroll Floor and Ceiling Texture and Carry Objects (Accelerative)"; + prefix = "(537)"; + flags64text = "[6] Exclusive"; + flags8192text = "[13] Use angle and X offset"; + } + + 538 + { + title = "Scroll Floor and Ceiling Texture and Carry Objects (Displacement)"; + prefix = "(538)"; + flags64text = "[6] Exclusive"; + flags8192text = "[13] Use angle and X offset"; } } @@ -6949,7 +7036,7 @@ thingtypes { color = 10; // Green title = "Tutorial"; - + 799 { title = "Tutorial Plant"; diff --git a/extras/conf/udb/Includes/SRB222_linedefs.cfg b/extras/conf/udb/Includes/SRB222_linedefs.cfg index fff9edf10..4b9e5fd97 100644 --- a/extras/conf/udb/Includes/SRB222_linedefs.cfg +++ b/extras/conf/udb/Includes/SRB222_linedefs.cfg @@ -1286,6 +1286,21 @@ doom title = "Scroll Ceiling Texture (Displacement)"; prefix = "(515)"; } + 516 + { + title = "Scroll Floor and Ceiling Texture"; + prefix = "(516)"; + } + 517 + { + title = "Scroll Floor and Ceiling Texture (Accelerative)"; + prefix = "(517)"; + } + 518 + { + title = "Scroll Floor and Ceiling Texture (Displacement)"; + prefix = "(518)"; + } 520 { title = "Carry Objects on Floor"; @@ -1316,6 +1331,21 @@ doom title = "Carry Objects on Ceiling (Displacement)"; prefix = "(525)"; } + 526 + { + title = "Carry Objects on Floor and Ceiling"; + prefix = "(526)"; + } + 527 + { + title = "Carry Objects on Floor and Ceiling (Accelerative)"; + prefix = "(527)"; + } + 528 + { + title = "Carry Objects on Floor and Ceiling (Displacement)"; + prefix = "(528)"; + } 530 { title = "Scroll Floor Texture and Carry Objects"; @@ -1346,6 +1376,21 @@ doom title = "Scroll Ceiling Texture and Carry Objects (Displacement)"; prefix = "(535)"; } + 536 + { + title = "Scroll Floor and Ceiling Texture and Carry Objects"; + prefix = "(536)"; + } + 537 + { + title = "Scroll Floor and Ceiling Texture and Carry Objects (Accelerative)"; + prefix = "(537)"; + } + 538 + { + title = "Scroll Floor and Ceiling Texture and Carry Objects (Displacement)"; + prefix = "(538)"; + } } pusher @@ -2593,7 +2638,7 @@ udmf } } } - + 190 { title = "Rising"; diff --git a/src/p_setup.c b/src/p_setup.c index 146d5d302..9712528ef 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -5594,25 +5594,36 @@ static void P_ConvertBinaryLinedefTypes(void) case 513: //Scroll ceiling texture case 514: //Scroll ceiling texture (accelerative) case 515: //Scroll ceiling texture (displacement) + case 516: //Scroll floor and ceiling texture + case 517: //Scroll floor and ceiling texture (accelerative) + case 518: //Scroll floor and ceiling texture (displacement) case 520: //Carry objects on floor case 521: //Carry objects on floor (accelerative) case 522: //Carry objects on floor (displacement) case 523: //Carry objects on ceiling case 524: //Carry objects on ceiling (accelerative) case 525: //Carry objects on ceiling (displacement) + case 526: //Carry objects on floor and ceiling + case 527: //Carry objects on floor and ceiling (accelerative) + case 528: //Carry objects on floor and ceiling (displacement) case 530: //Scroll floor texture and carry objects case 531: //Scroll floor texture and carry objects (accelerative) case 532: //Scroll floor texture and carry objects (displacement) case 533: //Scroll ceiling texture and carry objects case 534: //Scroll ceiling texture and carry objects (accelerative) case 535: //Scroll ceiling texture and carry objects (displacement) + case 536: //Scroll floor and ceiling texture and carry objects + case 537: //Scroll floor and ceiling texture and carry objects (accelerative) + case 538: //Scroll floor and ceiling texture and carry objects (displacement) lines[i].args[0] = tag; - lines[i].args[1] = ((lines[i].special % 10) < 3) ? TMP_FLOOR : TMP_CEILING; + lines[i].args[1] = ((lines[i].special % 10) < 6) ? (((lines[i].special % 10) < 3) ? TMP_FLOOR : TMP_CEILING) : TMP_BOTH; lines[i].args[2] = ((lines[i].special - 510)/10 + 1) % 3; lines[i].args[3] = R_PointToDist2(lines[i].v2->x, lines[i].v2->y, lines[i].v1->x, lines[i].v1->y) >> FRACBITS; lines[i].args[4] = (lines[i].special % 10) % 3; if (lines[i].args[2] != TMS_SCROLLONLY && !(lines[i].flags & ML_NOCLIMB)) lines[i].args[4] |= TMST_NONEXCLUSIVE; + if (lines[i].flags & ML_EFFECT6) + lines[i].args[3] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; lines[i].special = 510; break; case 540: //Floor friction From fe8485cc2ffd6ca761e8423f08039ba5672bce29 Mon Sep 17 00:00:00 2001 From: spherallic Date: Sat, 17 Sep 2022 11:20:51 +0200 Subject: [PATCH 032/586] Add flag to set wind/current/push/pull strength using X offset --- extras/conf/SRB2-22.cfg | 19 +++++++++++++------ src/p_setup.c | 9 +++++---- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg index 0bf009f79..6cd2f0d04 100644 --- a/extras/conf/SRB2-22.cfg +++ b/extras/conf/SRB2-22.cfg @@ -3036,48 +3036,54 @@ linedeftypes { title = "Wind"; prefix = "(541)"; - flags512text = "[9] Player slides"; flags64text = "[6] Exclusive"; + flags512text = "[9] Player slides"; + flags8192text = "[13] Use angle and X offset"; } 542 { title = "Upwards Wind"; prefix = "(542)"; - flags512text = "[9] Player slides"; flags64text = "[6] Exclusive"; + flags512text = "[9] Player slides"; + flags8192text = "[13] Use X offset"; } 543 { title = "Downwards Wind"; prefix = "(543)"; - flags512text = "[9] Player slides"; flags64text = "[6] Exclusive"; + flags512text = "[9] Player slides"; + flags8192text = "[13] Use X offset"; } 544 { title = "Current"; prefix = "(544)"; - flags512text = "[9] Player slides"; flags64text = "[6] Exclusive"; + flags512text = "[9] Player slides"; + flags8192text = "[13] Use angle and X offset"; } 545 { title = "Upwards Current"; prefix = "(545)"; - flags512text = "[9] Player slides"; flags64text = "[6] Exclusive"; + flags512text = "[9] Player slides"; + flags8192text = "[13] Use X offset"; } 546 { title = "Downwards Current"; prefix = "(546)"; - flags512text = "[9] Player slides"; flags64text = "[6] Exclusive"; + flags512text = "[9] Player slides"; + flags8192text = "[13] Use X offset"; } 547 @@ -3085,6 +3091,7 @@ linedeftypes title = "Push/Pull"; prefix = "(547)"; flags64text = "[6] Exclusive"; + flags8192text = "[13] Use X offset"; } } diff --git a/src/p_setup.c b/src/p_setup.c index 9712528ef..acee2bb69 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -5651,17 +5651,18 @@ static void P_ConvertBinaryLinedefTypes(void) case 544: //Current case 545: //Upwards current case 546: //Downwards current + fixed_t speed = (lines[i].flags & ML_EFFECT6) ? sides[lines[i].sidenum[0]].textureoffset : R_PointToDist2(lines[i].v2->x, lines[i].v2->y, lines[i].v1->x, lines[i].v1->y); lines[i].args[0] = tag; switch ((lines[i].special - 541) % 3) { case 0: - lines[i].args[1] = R_PointToDist2(lines[i].v2->x, lines[i].v2->y, lines[i].v1->x, lines[i].v1->y) >> FRACBITS; + lines[i].args[1] = speed >> FRACBITS; break; case 1: - lines[i].args[2] = R_PointToDist2(lines[i].v2->x, lines[i].v2->y, lines[i].v1->x, lines[i].v1->y) >> FRACBITS; + lines[i].args[2] = speed >> FRACBITS; break; case 2: - lines[i].args[2] = -R_PointToDist2(lines[i].v2->x, lines[i].v2->y, lines[i].v1->x, lines[i].v1->y) >> FRACBITS; + lines[i].args[2] = -speed >> FRACBITS; break; } lines[i].args[3] = (lines[i].special >= 544) ? p_current : p_wind; @@ -6308,7 +6309,7 @@ static void P_ConvertBinaryThingTypes(void) } mapthings[i].args[0] = mapthings[i].angle; - mapthings[i].args[1] = P_AproxDistance(line->dx >> FRACBITS, line->dy >> FRACBITS); + mapthings[i].args[1] = (line->flags & ML_EFFECT6) ? sides[line->sidenum[0]].textureoffset >> FRACBITS : P_AproxDistance(line->dx >> FRACBITS, line->dy >> FRACBITS); if (mapthings[i].type == 755) mapthings[i].args[1] *= -1; if (mapthings[i].options & MTF_OBJECTSPECIAL) From cc3d4acdcdd18d97140b40824c2f46ee71476d4a Mon Sep 17 00:00:00 2001 From: spherallic Date: Tue, 20 Sep 2022 20:42:19 +0200 Subject: [PATCH 033/586] Fix AppVeyor build failure --- src/p_setup.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index acee2bb69..a85e27e99 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -5651,18 +5651,19 @@ static void P_ConvertBinaryLinedefTypes(void) case 544: //Current case 545: //Upwards current case 546: //Downwards current - fixed_t speed = (lines[i].flags & ML_EFFECT6) ? sides[lines[i].sidenum[0]].textureoffset : R_PointToDist2(lines[i].v2->x, lines[i].v2->y, lines[i].v1->x, lines[i].v1->y); + { + fixed_t strength = (lines[i].flags & ML_EFFECT6) ? sides[lines[i].sidenum[0]].textureoffset : R_PointToDist2(lines[i].v2->x, lines[i].v2->y, lines[i].v1->x, lines[i].v1->y); lines[i].args[0] = tag; switch ((lines[i].special - 541) % 3) { case 0: - lines[i].args[1] = speed >> FRACBITS; + lines[i].args[1] = strength >> FRACBITS; break; case 1: - lines[i].args[2] = speed >> FRACBITS; + lines[i].args[2] = strength >> FRACBITS; break; case 2: - lines[i].args[2] = -speed >> FRACBITS; + lines[i].args[2] = -strength >> FRACBITS; break; } lines[i].args[3] = (lines[i].special >= 544) ? p_current : p_wind; @@ -5672,6 +5673,7 @@ static void P_ConvertBinaryLinedefTypes(void) lines[i].args[4] |= TMPF_NONEXCLUSIVE; lines[i].special = 541; break; + } case 600: //Floor lighting case 601: //Ceiling lighting lines[i].args[0] = tag; From 049bfd7bd4c0b3ba27cfcf3f38fb7653ebeaaf76 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 9 Oct 2022 17:17:16 +0200 Subject: [PATCH 034/586] Minor code cleanup in P_ConvertBinaryLinedefTypes --- src/p_setup.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index a85e27e99..1f8d316a7 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -5618,12 +5618,10 @@ static void P_ConvertBinaryLinedefTypes(void) lines[i].args[0] = tag; lines[i].args[1] = ((lines[i].special % 10) < 6) ? (((lines[i].special % 10) < 3) ? TMP_FLOOR : TMP_CEILING) : TMP_BOTH; lines[i].args[2] = ((lines[i].special - 510)/10 + 1) % 3; - lines[i].args[3] = R_PointToDist2(lines[i].v2->x, lines[i].v2->y, lines[i].v1->x, lines[i].v1->y) >> FRACBITS; + lines[i].args[3] = ((lines[i].flags & ML_EFFECT6) ? sides[lines[i].sidenum[0]].textureoffset : R_PointToDist2(lines[i].v2->x, lines[i].v2->y, lines[i].v1->x, lines[i].v1->y)) >> FRACBITS; lines[i].args[4] = (lines[i].special % 10) % 3; if (lines[i].args[2] != TMS_SCROLLONLY && !(lines[i].flags & ML_NOCLIMB)) lines[i].args[4] |= TMST_NONEXCLUSIVE; - if (lines[i].flags & ML_EFFECT6) - lines[i].args[3] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; lines[i].special = 510; break; case 540: //Floor friction From 2714ac44b47af785e3e4d7532731192911ae0879 Mon Sep 17 00:00:00 2001 From: katsy Date: Wed, 12 Oct 2022 20:38:29 -0500 Subject: [PATCH 035/586] reallow score chains from rolling --- 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 2f522ad4b..bcc9cb20b 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8412,12 +8412,12 @@ void P_MovePlayer(player_t *player) } } - // End your chain if you're on the ground or climbing a wall. + // End your chain if you're on the ground while not rolling, or climbing a wall. // But not if invincible! Allow for some crazy long chains with it. // Also keep in mind the PF_JUMPED check. // If we lacked this, stepping up while jumping up would reset score. // (for instance, when climbing up off a wall.) - if ((onground || player->climbing) && !(player->pflags & PF_JUMPED) && player->powers[pw_invulnerability] <= 1) + if ((onground || player->climbing) && ((player->pflags & (PF_STARTDASH|PF_SPINNING)) != PF_SPINNING) && !(player->pflags & PF_JUMPED) && player->powers[pw_invulnerability] <= 1) P_ResetScore(player); // Show the "THOK!" graphic when spinning quickly across the ground. (even applies to non-spinners, in the case of zoom tubes) From 373af010920537ba949c113163ddf0537cb30078 Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 14 Oct 2022 18:20:52 -0700 Subject: [PATCH 036/586] Add startswith and endswith, functions that compare the beginning or ending of a string --- src/doomtype.h | 3 +++ src/string.c | 16 ++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/doomtype.h b/src/doomtype.h index 5ddd9ae44..95871e98c 100644 --- a/src/doomtype.h +++ b/src/doomtype.h @@ -107,6 +107,9 @@ typedef long ssize_t; char *strcasestr(const char *in, const char *what); #define stristr strcasestr +int startswith (const char *base, const char *tag); +int endswith (const char *base, const char *tag); + #if defined (macintosh) //|| defined (__APPLE__) //skip all boolean/Boolean crap #define true 1 #define false 0 diff --git a/src/string.c b/src/string.c index 5534a3f0c..f48788e35 100644 --- a/src/string.c +++ b/src/string.c @@ -52,3 +52,19 @@ size_t strlcpy(char *dst, const char *src, size_t siz) #endif #include "strcasestr.c" + +int startswith(const char *path, const char *tag) +{ + return !strncmp(path, tag, strlen(tag)); +} + +int endswith(const char *base, const char *tag) +{ + const size_t base_length = strlen(base); + const size_t tag_length = strlen(tag); + + if (tag_length > base_length) + return false; + + return !memcmp(&base[base_length - tag_length], tag, tag_length); +} From b1a86b0b340fce3d0b92493bca6db55878f2eafa Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 14 Oct 2022 17:40:13 -0700 Subject: [PATCH 037/586] Disallow adding files with absolute path or traversing upward (Except as part of srb2home, srb2path or addons_folder -- this lets addons menu work, primarily.) - disallowed when using addfile or addfolder - security check for xcmd receive --- src/d_main.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/d_main.h | 2 ++ src/p_setup.c | 43 +++++++++++++++---------------- 3 files changed, 94 insertions(+), 22 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index fa9e21337..6e76672e0 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1689,3 +1689,74 @@ const char *D_Home(void) if (usehome) return userhome; else return NULL; } + +static boolean check_top_dir(const char **path, const char *top) +{ + // empty string does NOT match + if (!strcmp(top, "")) + return false; + + if (!startswith(*path, top)) + return false; + + *path += strlen(top); + + // if it doesn't already end with a path separator, + // check if a separator follows + if (!endswith(top, PATHSEP)) + { + if (startswith(*path, PATHSEP)) + *path += strlen(PATHSEP); + else + return false; + } + + return true; +} + +static int cmp_strlen_desc(const void *a, const void *b) +{ + return ((int)strlen(*(const char*const*)b) - (int)strlen(*(const char*const*)a)); +} + +boolean D_IsPathAllowed(const char *path) +{ + const char *paths[] = { + srb2home, + srb2path, + cv_addons_folder.string + }; + + const size_t n_paths = sizeof paths / sizeof *paths; + + size_t i; + + // Sort folder paths by longest to shortest so + // overlapping paths work. E.g.: + // Path 1: /home/james/.srb2/addons + // Path 2: /home/james/.srb2 + qsort(paths, n_paths, sizeof *paths, cmp_strlen_desc); + + // These paths are allowed to be absolute + // path is offset so ".." can be checked only in the + // rest of the path + for (i = 0; i < n_paths; ++i) + { + if (check_top_dir(&path, paths[i])) + break; + } + + // Only if none of the presets matched + if (i == n_paths) + { + // Cannot be an absolute path + if (M_IsPathAbsolute(path)) + return false; + } + + // Cannot traverse upwards + if (strstr(path, "..")) + return false; + + return true; +} diff --git a/src/d_main.h b/src/d_main.h index 8189a9f2b..7760351f3 100644 --- a/src/d_main.h +++ b/src/d_main.h @@ -44,6 +44,8 @@ void D_ProcessEvents(void); const char *D_Home(void); +boolean D_IsPathAllowed(const char *path); + // // BASE LEVEL // diff --git a/src/p_setup.c b/src/p_setup.c index 03a702b30..132dc4259 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -7860,8 +7860,10 @@ 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 // -static boolean P_LoadAddon(UINT16 wadnum, UINT16 numlumps) +static boolean P_LoadAddon(UINT16 numlumps) { + const UINT16 wadnum = (UINT16)(numwadfiles-1); + size_t i, j, sreplaces = 0, mreplaces = 0, digmreplaces = 0; char *name; lumpinfo_t *lumpinfo; @@ -7883,6 +7885,12 @@ static boolean P_LoadAddon(UINT16 wadnum, UINT16 numlumps) // UINT16 flaPos, flaNum = 0; // UINT16 mapPos, mapNum = 0; + if (numlumps == INT16_MAX) + { + refreshdirmenu |= REFRESHDIR_NOTLOADED; + return false; + } + switch(wadfiles[wadnum]->type) { case RET_PK3: @@ -8051,34 +8059,25 @@ static boolean P_LoadAddon(UINT16 wadnum, UINT16 numlumps) return true; } -boolean P_AddWadFile(const char *wadfilename) +static boolean P_CheckAddonPath(const char *path) { - UINT16 numlumps, wadnum; - - // Init file. - if ((numlumps = W_InitFile(wadfilename, false, false)) == INT16_MAX) + if (!D_IsPathAllowed(path)) { - refreshdirmenu |= REFRESHDIR_NOTLOADED; + CONS_Alert(CONS_WARNING, "%s: tried to add file, location is not allowed\n", path); return false; } - else - wadnum = (UINT16)(numwadfiles-1); - return P_LoadAddon(wadnum, numlumps); + return true; +} + +boolean P_AddWadFile(const char *wadfilename) +{ + return P_CheckAddonPath(wadfilename) && + P_LoadAddon(W_InitFile(wadfilename, false, false)); } 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); + return P_CheckAddonPath(folderpath) && + P_LoadAddon(W_InitFolder(folderpath, false, false)); } From 3bd3369fdc8b133d2a6a537160cb438749af3349 Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 14 Oct 2022 21:56:01 -0700 Subject: [PATCH 038/586] Add fopenfile, alternative to fopen that does not ever open directories --- src/doomdef.h | 2 ++ src/filesrch.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/src/doomdef.h b/src/doomdef.h index 2b62bcd6e..62afcc6c7 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -104,6 +104,8 @@ #include #endif +FILE *fopenfile(const char*, const char*); + //#define NOMD5 // Uncheck this to compile debugging code diff --git a/src/filesrch.c b/src/filesrch.c index 3f901b695..33d5bc65f 100644 --- a/src/filesrch.c +++ b/src/filesrch.c @@ -39,6 +39,7 @@ #define SUFFIX "*" #define SLASH "\\" +#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) #ifndef INVALID_FILE_ATTRIBUTES @@ -307,6 +308,39 @@ closedir (DIR * dirp) } #endif +// fopen but it REALLY only works on regular files +// Turns out, on linux, anyway, you can fopen directories +// in read mode. (It's supposed to fail in write mode +// though!!) +FILE *fopenfile(const char *path, const char *mode) +{ + FILE *h = fopen(path, mode); + + if (h != NULL) + { + struct stat st; + int eno; + + if (fstat(fileno(h), &st) == -1) + { + eno = errno; + } + else if (!S_ISREG(st.st_mode)) + { + eno = EACCES; // set some kinda error + } + else + { + return h; // ok + } + + fclose(h); + errno = eno; + } + + return NULL; +} + static CV_PossibleValue_t addons_cons_t[] = {{0, "Default"}, #if 1 {1, "HOME"}, {2, "SRB2"}, From 9761ab52d9d4193aa9fde4c072aa86572d79bccb Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 14 Oct 2022 21:57:14 -0700 Subject: [PATCH 039/586] FIL_ReadFileTag: use fopenfile Fixes exec, for example, crashing the game if given a directory. Test: `exec .` --- src/m_misc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/m_misc.c b/src/m_misc.c index 6c346e5a1..495c40e8b 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -273,8 +273,8 @@ size_t FIL_ReadFileTag(char const *name, UINT8 **buffer, INT32 tag) size_t count, length; UINT8 *buf; - if (FIL_ReadFileOK(name)) - handle = fopen(name, "rb"); + //if (FIL_ReadFileOK(name)) + handle = fopenfile(name, "rb"); if (!handle) return 0; From 76879299f98b2b91f9a7df661e17c137ff2f6598 Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 14 Oct 2022 22:10:24 -0700 Subject: [PATCH 040/586] Restrict exec path to srb2 directories --- src/command.c | 4 ++++ src/d_main.c | 11 +++++++++++ src/d_main.h | 1 + src/m_misc.c | 1 + src/p_setup.c | 15 ++------------- 5 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/command.c b/src/command.c index dae4dc7b1..f8b587328 100644 --- a/src/command.c +++ b/src/command.c @@ -34,6 +34,7 @@ #include "lua_script.h" #include "d_netfil.h" // findfile #include "r_data.h" // Color_cons_t +#include "d_main.h" // D_IsPathAllowed //======== // protos. @@ -770,6 +771,9 @@ static void COM_Exec_f(void) return; } + if (!D_CheckPathAllowed(COM_Argv(1), "tried to exec")) + return; + // load file // Try with Argv passed verbatim first, for back compat FIL_ReadFile(COM_Argv(1), &buf); diff --git a/src/d_main.c b/src/d_main.c index 6e76672e0..5b102d623 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1760,3 +1760,14 @@ boolean D_IsPathAllowed(const char *path) return true; } + +boolean D_CheckPathAllowed(const char *path, const char *why) +{ + if (!D_IsPathAllowed(path)) + { + CONS_Alert(CONS_WARNING, "%s: %s, location is not allowed\n", why, path); + return false; + } + + return true; +} diff --git a/src/d_main.h b/src/d_main.h index 7760351f3..cc06f5f61 100644 --- a/src/d_main.h +++ b/src/d_main.h @@ -45,6 +45,7 @@ void D_ProcessEvents(void); const char *D_Home(void); boolean D_IsPathAllowed(const char *path); +boolean D_CheckPathAllowed(const char *path, const char *why); // // BASE LEVEL diff --git a/src/m_misc.c b/src/m_misc.c index 6c346e5a1..fca0474eb 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -467,6 +467,7 @@ void Command_SaveConfig_f(void) CONS_Printf(M_GetText("saveconfig [-silent] : save config to a file\n")); return; } + strcpy(tmpstr, COM_Argv(1)); FIL_ForceExtension(tmpstr, ".cfg"); diff --git a/src/p_setup.c b/src/p_setup.c index 132dc4259..45813e04d 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -8059,25 +8059,14 @@ static boolean P_LoadAddon(UINT16 numlumps) return true; } -static boolean P_CheckAddonPath(const char *path) -{ - if (!D_IsPathAllowed(path)) - { - CONS_Alert(CONS_WARNING, "%s: tried to add file, location is not allowed\n", path); - return false; - } - - return true; -} - boolean P_AddWadFile(const char *wadfilename) { - return P_CheckAddonPath(wadfilename) && + return D_CheckPathAllowed(wadfilename, "tried to add file") && P_LoadAddon(W_InitFile(wadfilename, false, false)); } boolean P_AddFolder(const char *folderpath) { - return P_CheckAddonPath(folderpath) && + return D_CheckPathAllowed(folderpath, "tried to add folder") && P_LoadAddon(W_InitFolder(folderpath, false, false)); } From 1b43cdddd59ebeb6ea76721ba953370476478f0f Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 27 Feb 2022 10:11:55 -0500 Subject: [PATCH 041/586] Allow saving in modified games. --- src/d_main.c | 6 ++++ src/d_netcmd.c | 6 ++-- src/f_finale.c | 17 +++------ src/g_game.c | 97 +++++++++++++++++++++++++++++++++----------------- src/hu_stuff.c | 2 +- src/m_cond.c | 3 -- src/m_menu.c | 30 ++++++---------- src/p_inter.c | 2 +- src/p_mobj.c | 6 +--- src/p_setup.c | 6 ++-- src/p_spec.c | 2 +- src/y_inter.c | 4 +-- 12 files changed, 97 insertions(+), 84 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 3566e7f3d..b1f09aaa8 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1473,6 +1473,12 @@ void D_SRB2Main(void) //--------------------------------------------------------- CONFIG.CFG M_FirstLoadConfig(); // WARNING : this do a "COM_BufExecute()" + if (M_CheckParm("-gamedata") && M_IsNextParm()) + { + // Moved from G_LoadGameData itself, as it would cause some crazy + // confusion issues when loading mods. + strlcpy(gamedatafilename, M_GetNextParm(), sizeof gamedatafilename); + } G_LoadGameData(); #if defined (__unix__) || defined (UNIXCOMMON) || defined (HAVE_SDL) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 4e90db0dc..73bfe9e17 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -4613,11 +4613,11 @@ static void Fishcake_OnChange(void) static void Command_Isgamemodified_f(void) { if (savemoddata) - CONS_Printf(M_GetText("modifiedgame is true, but you can save emblem and time data in this mod.\n")); + CONS_Printf(M_GetText("modifiedgame is true, but you can save time data in this mod.\n")); else if (modifiedgame) - CONS_Printf(M_GetText("modifiedgame is true, extras will not be unlocked\n")); + CONS_Printf(M_GetText("modifiedgame is true, time data can't be saved\n")); else - CONS_Printf(M_GetText("modifiedgame is false, you can unlock extras\n")); + CONS_Printf(M_GetText("modifiedgame is false, you can save time data\n")); } static void Command_Cheats_f(void) diff --git a/src/f_finale.c b/src/f_finale.c index bca8e3ba6..73f6281a1 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1575,7 +1575,9 @@ void F_GameEvaluationDrawer(void) { V_DrawString(8, 16, V_YELLOWMAP, "Unlocked:"); - if (!(netgame) && (!modifiedgame || savemoddata)) + if (netgame) + V_DrawString(8, 96, V_YELLOWMAP, "Multiplayer games\ncan't unlock\nextras!"); + else { INT32 startcoord = 32; @@ -1590,10 +1592,6 @@ void F_GameEvaluationDrawer(void) } } } - else if (netgame) - V_DrawString(8, 96, V_YELLOWMAP, "Multiplayer games\ncan't unlock\nextras!"); - else - V_DrawString(8, 96, V_YELLOWMAP, "Modified games\ncan't unlock\nextras!"); } #endif @@ -1657,7 +1655,7 @@ void F_GameEvaluationTicker(void) HU_DoCEcho("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\Multiplayer games can't unlock extras!"); S_StartSound(NULL, sfx_s3k68); } - else if (!modifiedgame || savemoddata) + else { ++timesBeaten; @@ -1672,13 +1670,6 @@ void F_GameEvaluationTicker(void) G_SaveGameData(); } - else - { - HU_SetCEchoFlags(V_YELLOWMAP|V_RETURN8); - HU_SetCEchoDuration(6); - HU_DoCEcho("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\Modified games can't unlock extras!"); - S_StartSound(NULL, sfx_s3k68); - } } } diff --git a/src/g_game.c b/src/g_game.c index 349d90558..edddcc050 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -755,7 +755,7 @@ void G_SetGameModified(boolean silent) savemoddata = false; if (!silent) - CONS_Alert(CONS_NOTICE, M_GetText("Game must be restarted to record statistics.\n")); + CONS_Alert(CONS_NOTICE, M_GetText("Game must be restarted to play Record Attack.\n")); // If in record attack recording, cancel it. if (modeattacking) @@ -3826,8 +3826,7 @@ static void G_UpdateVisited(void) { boolean spec = G_IsSpecialStage(gamemap); // Update visitation flags? - if ((!modifiedgame || savemoddata) // Not modified - && !multiplayer && !demoplayback && (gametype == GT_COOP) // SP/RA/NiGHTS mode + if (!multiplayer && !demoplayback && (gametype == GT_COOP) // SP/RA/NiGHTS mode && !stagefailed) // Did not fail the stage { UINT8 earnedEmblems; @@ -3895,14 +3894,18 @@ static void G_HandleSaveLevel(void) remove(liveeventbackup); cursaveslot = 0; } - else if ((!modifiedgame || savemoddata) && !(netgame || multiplayer || ultimatemode || demorecording || metalrecording || modeattacking)) + else if (!(netgame || multiplayer || ultimatemode || demorecording || metalrecording || modeattacking)) + { G_SaveGame((UINT32)cursaveslot, spstage_start); + } } } // and doing THIS here means you don't lose your progress if you close the game mid-intermission else if (!(ultimatemode || netgame || multiplayer || demoplayback || demorecording || metalrecording || modeattacking) - && (!modifiedgame || savemoddata) && cursaveslot > 0 && CanSaveLevel(lastmap+1)) + && cursaveslot > 0 && CanSaveLevel(lastmap+1)) + { G_SaveGame((UINT32)cursaveslot, lastmap+1); // not nextmap+1 to route around special stages + } } // @@ -4178,8 +4181,10 @@ static void G_DoContinued(void) tokenlist = 0; token = 0; - if (!(netgame || multiplayer || demoplayback || demorecording || metalrecording || modeattacking) && (!modifiedgame || savemoddata) && cursaveslot > 0) + if (!(netgame || multiplayer || demoplayback || demorecording || metalrecording || modeattacking) && cursaveslot > 0) + { G_SaveGameOver((UINT32)cursaveslot, true); + } // Reset # of lives pl->lives = (ultimatemode) ? 1 : startinglivesbalance[numgameovers]; @@ -4244,13 +4249,17 @@ void G_LoadGameSettings(void) S_InitRuntimeSounds(); } +#define GAMEDATA_ID 0x86E4A27C // Change every major version, as usual +#define COMPAT_GAMEDATA_ID 0xFCAFE211 // Can be removed entirely for 2.3 + // G_LoadGameData // Loads the main data file, which stores information such as emblems found, etc. void G_LoadGameData(void) { size_t length; INT32 i, j; - UINT8 modded = false; + + UINT32 versionID; UINT8 rtemp; //For records @@ -4261,6 +4270,9 @@ void G_LoadGameData(void) UINT8 recmares; INT32 curmare; + // Stop saving, until we successfully load it again. + gamedataloaded = false; + // Clear things so previously read gamedata doesn't transfer // to new gamedata G_ClearRecords(); // main and nights records @@ -4268,27 +4280,35 @@ void G_LoadGameData(void) totalplaytime = 0; // total play time (separate from all) if (M_CheckParm("-nodata")) - return; // Don't load. - - // Allow saving of gamedata beyond this point - gamedataloaded = true; - - if (M_CheckParm("-gamedata") && M_IsNextParm()) { - strlcpy(gamedatafilename, M_GetNextParm(), sizeof gamedatafilename); + // Don't load at all. + return; } if (M_CheckParm("-resetdata")) - return; // Don't load (essentially, reset). + { + // Don't load, but do save. (essentially, reset) + gamedataloaded = true; + return; + } length = FIL_ReadFile(va(pandf, srb2home, gamedatafilename), &savebuffer); - if (!length) // Aw, no game data. Their loss! + if (!length) + { + // No gamedata. We can save a new one. + gamedataloaded = true; return; + } save_p = savebuffer; // Version check - if (READUINT32(save_p) != 0xFCAFE211) + versionID = READUINT32(save_p); + if (versionID != GAMEDATA_ID +#ifdef COMPAT_GAMEDATA_ID // backwards compat behavior + && versionID != COMPAT_GAMEDATA_ID +#endif + ) { const char *gdfolder = "the SRB2 folder"; if (strcmp(srb2home,".")) @@ -4301,13 +4321,26 @@ void G_LoadGameData(void) totalplaytime = READUINT32(save_p); - modded = READUINT8(save_p); +#ifdef COMPAT_GAMEDATA_ID + // Ignore for backwards compat, it'll get fixed when saving. + if (versionID == COMPAT_GAMEDATA_ID) + { + // Old files use a UINT8 here. + READUINT8(save_p); + } + else +#endif + { + // Quick & dirty hash for what mod this save file is for. + UINT32 modID = READUINT32(save_p); + UINT32 expectedID = quickncasehash(timeattackfolder, sizeof timeattackfolder); - // Aha! Someone's been screwing with the save file! - if ((modded && !savemoddata)) - goto datacorrupt; - else if (modded != true && modded != false) - goto datacorrupt; + if (modID != expectedID) + { + // Aha! Someone's been screwing with the save file! + goto datacorrupt; + } + } // TODO put another cipher on these things? meh, I don't care... for (i = 0; i < NUMMAPS; i++) @@ -4393,6 +4426,12 @@ void G_LoadGameData(void) Z_Free(savebuffer); save_p = NULL; + // Don't consider loaded until it's a success! + // It used to do this much earlier, but this would cause the gamedata to + // save over itself when it I_Errors from the corruption landing point below, + // which can accidentally delete players' legitimate data if the code ever has any tiny mistakes! + gamedataloaded = true; + // Silent update unlockables in case they're out of sync with conditions M_SilentUpdateUnlockablesAndEmblems(); @@ -4432,20 +4471,12 @@ void G_SaveGameData(void) return; } - if (modifiedgame && !savemoddata) - { - free(savebuffer); - save_p = savebuffer = NULL; - return; - } - // Version test - WRITEUINT32(save_p, 0xFCAFE211); + WRITEUINT32(save_p, GAMEDATA_ID); WRITEUINT32(save_p, totalplaytime); - btemp = (UINT8)(savemoddata || modifiedgame); - WRITEUINT8(save_p, btemp); + WRITEUINT32(save_p, quickncasehash(timeattackfolder, sizeof timeattackfolder)); // TODO put another cipher on these things? meh, I don't care... for (i = 0; i < NUMMAPS; i++) diff --git a/src/hu_stuff.c b/src/hu_stuff.c index c037abcd7..ebef02319 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -2994,7 +2994,7 @@ static void HU_DrawCoopOverlay(void) V_DrawSmallScaledPatch(148, 172, 0, tokenicon); } - if (LUA_HudEnabled(hud_tabemblems) && (!modifiedgame || savemoddata)) + if (LUA_HudEnabled(hud_tabemblems)) { V_DrawString(160, 144, 0, va("- %d/%d", M_CountEmblems(), numemblems+numextraemblems)); V_DrawScaledPatch(128, 144 - emblemicon->height/4, 0, emblemicon); diff --git a/src/m_cond.c b/src/m_cond.c index 1406317c5..58ee71fec 100644 --- a/src/m_cond.c +++ b/src/m_cond.c @@ -200,9 +200,6 @@ UINT8 M_UpdateUnlockablesAndExtraEmblems(void) char cechoText[992] = ""; UINT8 cechoLines = 0; - if (modifiedgame && !savemoddata) - return false; - M_CheckUnlockConditions(); // Go through extra emblems diff --git a/src/m_menu.c b/src/m_menu.c index 83b788fd5..55733e552 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -757,12 +757,12 @@ static menuitem_t SR_EmblemHintMenu[] = static menuitem_t SP_MainMenu[] = { // Note: If changing the positions here, also change them in M_SinglePlayerMenu() - {IT_CALL | IT_STRING, NULL, "Start Game", M_LoadGame, 76}, - {IT_SECRET, NULL, "Record Attack", M_TimeAttack, 84}, - {IT_SECRET, NULL, "NiGHTS Mode", M_NightsAttack, 92}, - {IT_SECRET, NULL, "Marathon Run", M_Marathon, 100}, - {IT_CALL | IT_STRING, NULL, "Tutorial", M_StartTutorial, 108}, - {IT_CALL | IT_STRING | IT_CALL_NOTMODIFIED, NULL, "Statistics", M_Statistics, 116} + {IT_CALL | IT_STRING, NULL, "Start Game", M_LoadGame, 76}, + {IT_SECRET, NULL, "Record Attack", M_TimeAttack, 84}, + {IT_SECRET, NULL, "NiGHTS Mode", M_NightsAttack, 92}, + {IT_SECRET, NULL, "Marathon Run", M_Marathon, 100}, + {IT_CALL | IT_STRING, NULL, "Tutorial", M_StartTutorial, 108}, + {IT_CALL | IT_STRING, NULL, "Statistics", M_Statistics, 116} }; enum @@ -3514,9 +3514,11 @@ boolean M_Responder(event_t *ev) { if (((currentMenu->menuitems[itemOn].status & IT_TYPE)==IT_CALL || (currentMenu->menuitems[itemOn].status & IT_TYPE)==IT_SUBMENU) - && (currentMenu->menuitems[itemOn].status & IT_CALLTYPE)) + && (currentMenu->menuitems[itemOn].status & IT_CALLTYPE)) { #ifndef DEVELOP + // TODO: Replays are scary, so I left the remaining instances of this alone. + // It'd be nice to get rid of this once and for all though! if (((currentMenu->menuitems[itemOn].status & IT_CALLTYPE) & IT_CALL_NOTMODIFIED) && modifiedgame && !savemoddata) { S_StartSound(NULL, sfx_skid); @@ -8701,12 +8703,6 @@ 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."); - } } // @@ -9008,18 +9004,12 @@ static void M_HandleLoadSave(INT32 choice) break; case KEY_ENTER: - if (ultimate_selectable && saveSlotSelected == NOSAVESLOT && !savemoddata && !modifiedgame) + if (ultimate_selectable && saveSlotSelected == NOSAVESLOT) { loadgamescroll = 0; S_StartSound(NULL, sfx_skid); M_StartMessage("Are you sure you want to play\n\x85ultimate mode\x80? It isn't remotely fair,\nand you don't even get an emblem for it.\n\n(Press 'Y' to confirm)\n",M_SaveGameUltimateResponse,MM_YESNO); } - else if (saveSlotSelected != NOSAVESLOT && savegameinfo[saveSlotSelected-1].lives == -42 && !(!modifiedgame || savemoddata)) - { - loadgamescroll = 0; - S_StartSound(NULL, sfx_skid); - M_StartMessage(M_GetText("This cannot be done in a modified game.\n\n(Press a key)\n"), NULL, MM_NOTHING); - } else if (saveSlotSelected == NOSAVESLOT || savegameinfo[saveSlotSelected-1].lives != -666) // don't allow loading of "bad saves" { loadgamescroll = 0; diff --git a/src/p_inter.c b/src/p_inter.c index dd3e0f9c2..1094c3045 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2583,7 +2583,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget if (!(netgame || multiplayer || demoplayback || demorecording || metalrecording || modeattacking) && numgameovers < maxgameovers) { numgameovers++; - if ((!modifiedgame || savemoddata) && cursaveslot > 0) + if (cursaveslot > 0) G_SaveGameOver((UINT32)cursaveslot, (target->player->continues <= 0)); } } diff --git a/src/p_mobj.c b/src/p_mobj.c index 4533a2ce8..ac91e0f7f 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11972,11 +11972,7 @@ static boolean P_AllowMobjSpawn(mapthing_t* mthing, mobjtype_t i) break; case MT_EMBLEM: if (netgame || multiplayer) - return false; // Single player - - if (modifiedgame && !savemoddata) - return false; // No cheating!! - + return false; // Single player (You're next on my shit list) break; default: break; diff --git a/src/p_setup.c b/src/p_setup.c index deb308da2..c41a5d94e 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -7746,7 +7746,7 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate) nextmapoverride = 0; skipstats = 0; - if (!(netgame || multiplayer || demoplayback) && (!modifiedgame || savemoddata)) + if (!(netgame || multiplayer || demoplayback)) mapvisited[gamemap-1] |= MV_VISITED; else if (netgame || multiplayer) mapvisited[gamemap-1] |= MV_MP; // you want to record that you've been there this session, but not permanently @@ -7764,8 +7764,10 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate) { // I'd love to do this in the menu code instead of here, but everything's a mess and I can't guarantee saving proper player struct info before the first act's started. You could probably refactor it, but it'd be a lot of effort. Easier to just work off known good code. ~toast 22/06/2020 if (!(ultimatemode || netgame || multiplayer || demoplayback || demorecording || metalrecording || modeattacking || marathonmode) - && (!modifiedgame || savemoddata) && cursaveslot > 0) + && cursaveslot > 0) + { G_SaveGame((UINT32)cursaveslot, gamemap); + } // If you're looking for saving sp file progression (distinct from G_SaveGameOver), check G_DoCompleted. } lastmaploaded = gamemap; // HAS to be set after saving!! diff --git a/src/p_spec.c b/src/p_spec.c index 82337d2f6..94659e0d7 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -2937,7 +2937,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) break; case 441: // Trigger unlockable - if ((!modifiedgame || savemoddata) && !(netgame || multiplayer)) + if (!(netgame || multiplayer)) { INT32 trigid = line->args[0]; diff --git a/src/y_inter.c b/src/y_inter.c index 7faceff50..e0f246eee 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -1092,7 +1092,7 @@ void Y_Ticker(void) S_StartSound(NULL, (gottoken ? sfx_token : sfx_chchng)); // cha-ching! // Update when done with tally - if ((!modifiedgame || savemoddata) && !(netgame || multiplayer) && !demoplayback) + if (!(netgame || multiplayer) && !demoplayback) { if (M_UpdateUnlockablesAndExtraEmblems()) S_StartSound(NULL, sfx_s3k68); @@ -1223,7 +1223,7 @@ void Y_Ticker(void) S_StartSound(NULL, (gottoken ? sfx_token : sfx_chchng)); // cha-ching! // Update when done with tally - if ((!modifiedgame || savemoddata) && !(netgame || multiplayer) && !demoplayback) + if (!(netgame || multiplayer) && !demoplayback) { if (M_UpdateUnlockablesAndExtraEmblems()) S_StartSound(NULL, sfx_s3k68); From bcfe0da8fc10ed8b3417a11e2dcdb26aeda9bd1f Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 27 Feb 2022 10:22:44 -0500 Subject: [PATCH 042/586] Use old modded behavior when loading old files, instead of ignoring Let's not pretend script-kiddie edited old files are now perfectly A-OK :p --- src/g_game.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index edddcc050..892802d91 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -4322,11 +4322,20 @@ void G_LoadGameData(void) totalplaytime = READUINT32(save_p); #ifdef COMPAT_GAMEDATA_ID - // Ignore for backwards compat, it'll get fixed when saving. if (versionID == COMPAT_GAMEDATA_ID) { - // Old files use a UINT8 here. - READUINT8(save_p); + // We'll temporarily use the old condition when loading an older file. + // The proper mod-specific hash will get saved in afterwards. + boolean modded = READUINT8(save_p); + + if (modded && !savemoddata) + { + goto datacorrupt; + } + else if (modded != true && modded != false) + { + goto datacorrupt; + } } else #endif From 4a520e63c67bfe8d9a8320553d1fd71908df3243 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 27 Feb 2022 10:33:58 -0500 Subject: [PATCH 043/586] Don't allow a gamedata named the same as the default time attack folder That'd be kinda scary! --- src/deh_soc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/deh_soc.c b/src/deh_soc.c index 583776ee7..db427b349 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -2901,7 +2901,9 @@ static boolean GoodDataFileName(const char *s) p = s + strlen(s) - strlen(tail); if (p <= s) return false; // too short if (!fasticmp(p, tail)) return false; // doesn't end in .dat - if (fasticmp(s, "gamedata.dat")) return false; + + if (fasticmp(s, "gamedata.dat")) return false; // Don't overwrite default gamedata + if (fasticmp(s, "main.dat")) return false; // Don't overwrite default time attack replays return true; } From a22fa1c455cea774946f7032fd74e2e8155c9d9d Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 28 Feb 2022 12:43:00 -0500 Subject: [PATCH 044/586] Compromise on cheats setting modified game Instead of modifying the game, cheats now set a separate "cheats were used in this session" variable, which returns some of the old behavior. HOWEVER, cheats will STILL allow spawning / collecting emblems & unlocking unlockables. Cheats will purely prevent saving progress. (It was always frustrating that devmode would make debugging unlockable features harder...) Lastly, the function to set no-saving was exposed to Lua (`G_SetUsedCheats(silent)`). Just thought it'd be useful for large-scale gamedata-using mods that want to add their own cheat commands. --- src/d_clisrv.c | 3 +++ src/d_clisrv.h | 1 + src/d_main.c | 2 +- src/d_netcmd.c | 20 ++++++++++---------- src/doomstat.h | 1 + src/g_game.c | 31 ++++++++++++++++++++++++++++--- src/g_game.h | 1 + src/lua_baselib.c | 11 +++++++++++ src/lua_script.c | 3 +++ src/m_cheat.c | 20 ++++++++++---------- src/m_menu.c | 20 ++++++++++++++++---- src/p_inter.c | 2 +- src/p_setup.c | 2 +- 13 files changed, 87 insertions(+), 30 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 4cd6333c5..f95b952f3 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1448,6 +1448,7 @@ static boolean SV_SendServerConfig(INT32 node) netbuffer->u.servercfg.gamestate = (UINT8)gamestate; netbuffer->u.servercfg.gametype = (UINT8)gametype; netbuffer->u.servercfg.modifiedgame = (UINT8)modifiedgame; + netbuffer->u.servercfg.usedCheats = (UINT8)usedCheats; memcpy(netbuffer->u.servercfg.server_context, server_context, 8); @@ -4341,6 +4342,8 @@ static void HandlePacketFromAwayNode(SINT8 node) maketic = gametic = neededtic = (tic_t)LONG(netbuffer->u.servercfg.gametic); G_SetGametype(netbuffer->u.servercfg.gametype); modifiedgame = netbuffer->u.servercfg.modifiedgame; + if (netbuffer->u.servercfg.usedCheats) + G_SetUsedCheats(true); memcpy(server_context, netbuffer->u.servercfg.server_context, 8); } diff --git a/src/d_clisrv.h b/src/d_clisrv.h index e07864122..f3896c7ea 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -158,6 +158,7 @@ typedef struct UINT8 gametype; UINT8 modifiedgame; + UINT8 usedCheats; char server_context[8]; // Unique context id, generated at server startup. } ATTRPACK serverconfig_pak; diff --git a/src/d_main.c b/src/d_main.c index b1f09aaa8..9df1d8fab 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1506,7 +1506,7 @@ void D_SRB2Main(void) else { if (!M_CheckParm("-server")) - G_SetGameModified(true); + G_SetUsedCheats(true); autostart = true; } } diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 73bfe9e17..847f97341 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1877,7 +1877,7 @@ static void Command_Map_f(void) const char *gametypename; boolean newresetplayers; - boolean mustmodifygame; + boolean wouldSetCheats; INT32 newmapnum; @@ -1898,11 +1898,11 @@ static void Command_Map_f(void) option_gametype = COM_CheckPartialParm("-g"); newresetplayers = ! COM_CheckParm("-noresetplayers"); - mustmodifygame = - !( netgame || multiplayer ) && - (!modifiedgame || savemoddata ); + wouldSetCheats = + !( netgame || multiplayer ) && + !( usedCheats ); - if (mustmodifygame && !option_force) + if (wouldSetCheats && !option_force) { /* May want to be more descriptive? */ CONS_Printf(M_GetText("Sorry, level change disabled in single player.\n")); @@ -1956,9 +1956,9 @@ static void Command_Map_f(void) return; } - if (mustmodifygame && option_force) + if (wouldSetCheats && option_force) { - G_SetGameModified(false); + G_SetUsedCheats(false); } // new gametype value @@ -4259,7 +4259,7 @@ static void Ringslinger_OnChange(void) } if (cv_ringslinger.value) // Only if it's been turned on - G_SetGameModified(multiplayer); + G_SetUsedCheats(false); } static void Gravity_OnChange(void) @@ -4280,7 +4280,7 @@ static void Gravity_OnChange(void) #endif if (!CV_IsSetToDefault(&cv_gravity)) - G_SetGameModified(multiplayer); + G_SetUsedCheats(false); gravity = cv_gravity.value; } @@ -4596,7 +4596,7 @@ static void Fishcake_OnChange(void) // so don't make modifiedgame always on! if (cv_debug) { - G_SetGameModified(multiplayer); + G_SetUsedCheats(false); } else if (cv_debug != cv_fishcake.value) diff --git a/src/doomstat.h b/src/doomstat.h index bce43416b..490054cf9 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -75,6 +75,7 @@ extern SINT8 startinglivesbalance[maxgameovers+1]; extern boolean modifiedgame; extern UINT16 mainwads; extern boolean savemoddata; // This mod saves time/emblem data. +extern boolean usedCheats; extern boolean disableSpeedAdjust; // Don't alter the duration of player states if true extern boolean imcontinuing; // Temporary flag while continuing extern boolean metalrecording; diff --git a/src/g_game.c b/src/g_game.c index 892802d91..e75bb433e 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -96,6 +96,7 @@ SINT8 startinglivesbalance[maxgameovers+1] = {3, 5, 7, 9, 12, 15, 20, 25, 30, 40 UINT16 mainwads = 0; boolean modifiedgame; // Set if homebrew PWAD stuff has been added. boolean savemoddata = false; +boolean usedCheats = false; // Set when a gamedata-preventing cheat command is used. UINT8 paused; UINT8 modeattacking = ATTACKING_NONE; boolean disableSpeedAdjust = false; @@ -764,6 +765,23 @@ void G_SetGameModified(boolean silent) Command_ExitGame_f(); } +void G_SetUsedCheats(boolean silent) +{ + if (usedCheats) + return; + + usedCheats = true; + + if (!silent) + CONS_Alert(CONS_NOTICE, M_GetText("Game must be restarted to save progress.\n")); + + // If in record attack recording, cancel it. + if (modeattacking) + M_EndModeAttackRun(); + else if (marathonmode) + Command_ExitGame_f(); +} + /** Builds an original game map name from a map number. * The complexity is due to MAPA0-MAPZZ. * @@ -3894,7 +3912,7 @@ static void G_HandleSaveLevel(void) remove(liveeventbackup); cursaveslot = 0; } - else if (!(netgame || multiplayer || ultimatemode || demorecording || metalrecording || modeattacking)) + else if (!usedCheats && !(netgame || multiplayer || ultimatemode || demorecording || metalrecording || modeattacking)) { G_SaveGame((UINT32)cursaveslot, spstage_start); } @@ -3902,7 +3920,7 @@ static void G_HandleSaveLevel(void) } // and doing THIS here means you don't lose your progress if you close the game mid-intermission else if (!(ultimatemode || netgame || multiplayer || demoplayback || demorecording || metalrecording || modeattacking) - && cursaveslot > 0 && CanSaveLevel(lastmap+1)) + && !usedCheats && cursaveslot > 0 && CanSaveLevel(lastmap+1)) { G_SaveGame((UINT32)cursaveslot, lastmap+1); // not nextmap+1 to route around special stages } @@ -4181,7 +4199,7 @@ static void G_DoContinued(void) tokenlist = 0; token = 0; - if (!(netgame || multiplayer || demoplayback || demorecording || metalrecording || modeattacking) && cursaveslot > 0) + if (!(netgame || multiplayer || demoplayback || demorecording || metalrecording || modeattacking) && !usedCheats && cursaveslot > 0) { G_SaveGameOver((UINT32)cursaveslot, true); } @@ -4480,6 +4498,13 @@ void G_SaveGameData(void) return; } + if (usedCheats) + { + free(savebuffer); + save_p = savebuffer = NULL; + return; + } + // Version test WRITEUINT32(save_p, GAMEDATA_ID); diff --git a/src/g_game.h b/src/g_game.h index dca043f2e..a781e23f9 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -243,6 +243,7 @@ void G_LoadGameData(void); void G_LoadGameSettings(void); void G_SetGameModified(boolean silent); +void G_SetUsedCheats(boolean silent); void G_SetGamestate(gamestate_t newstate); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 29adb478a..031a155d2 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -3612,6 +3612,16 @@ static int lib_gRemovePlayer(lua_State *L) } +static int lib_gSetUsedCheats(lua_State *L) +{ + // Let large-scale level packs using Lua be able to add cheat commands. + boolean silent = lua_optboolean(L, 1); + //NOHUD + //INLEVEL + G_SetUsedCheats(silent); + return 0; +} + static int Lcheckmapnumber (lua_State *L, int idx, const char *fun) { if (ISINLEVEL) @@ -4213,6 +4223,7 @@ static luaL_Reg lib[] = { {"G_AddGametype", lib_gAddGametype}, {"G_AddPlayer", lib_gAddPlayer}, {"G_RemovePlayer", lib_gRemovePlayer}, + {"G_SetUsedCheats", lib_gSetUsedCheats}, {"G_BuildMapName",lib_gBuildMapName}, {"G_BuildMapTitle",lib_gBuildMapTitle}, {"G_FindMap",lib_gFindMap}, diff --git a/src/lua_script.c b/src/lua_script.c index 4d4071545..5f16bca8a 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -204,6 +204,9 @@ int LUA_PushGlobals(lua_State *L, const char *word) } else if (fastcmp(word,"modifiedgame")) { lua_pushboolean(L, modifiedgame && !savemoddata); return 1; + } else if (fastcmp(word,"usedCheats")) { + lua_pushboolean(L, usedCheats); + return 1; } else if (fastcmp(word,"menuactive")) { lua_pushboolean(L, menuactive); return 1; diff --git a/src/m_cheat.c b/src/m_cheat.c index 89c8009ae..78fb3a505 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -81,7 +81,7 @@ static UINT8 cheatf_warp(void) S_StartSound(0, sfx_itemup); // Temporarily unlock stuff. - G_SetGameModified(false); + G_SetUsedCheats(false); unlockables[31].unlocked = true; // credits unlockables[30].unlocked = true; // sound test unlockables[28].unlocked = true; // level select @@ -106,7 +106,7 @@ static UINT8 cheatf_devmode(void) S_StartSound(0, sfx_itemup); // Just unlock all the things and turn on -debug and console devmode. - G_SetGameModified(false); + G_SetUsedCheats(false); for (i = 0; i < MAXUNLOCKABLES; i++) unlockables[i].unlocked = true; devparm = true; @@ -275,7 +275,7 @@ void Command_CheatNoClip_f(void) plyr->pflags ^= PF_NOCLIP; CONS_Printf(M_GetText("No Clipping %s\n"), plyr->pflags & PF_NOCLIP ? M_GetText("On") : M_GetText("Off")); - G_SetGameModified(multiplayer); + G_SetUsedCheats(false); } void Command_CheatGod_f(void) @@ -290,7 +290,7 @@ void Command_CheatGod_f(void) plyr->pflags ^= PF_GODMODE; CONS_Printf(M_GetText("Cheese Mode %s\n"), plyr->pflags & PF_GODMODE ? M_GetText("On") : M_GetText("Off")); - G_SetGameModified(multiplayer); + G_SetUsedCheats(false); } void Command_CheatNoTarget_f(void) @@ -305,7 +305,7 @@ void Command_CheatNoTarget_f(void) plyr->pflags ^= PF_INVIS; CONS_Printf(M_GetText("SEP Field %s\n"), plyr->pflags & PF_INVIS ? M_GetText("On") : M_GetText("Off")); - G_SetGameModified(multiplayer); + G_SetUsedCheats(false); } void Command_Scale_f(void) @@ -879,7 +879,7 @@ void Command_Devmode_f(void) return; } - G_SetGameModified(multiplayer); + G_SetUsedCheats(false); } void Command_Setrings_f(void) @@ -905,7 +905,7 @@ void Command_Setrings_f(void) // no totalsphere addition to revert } - G_SetGameModified(multiplayer); + G_SetUsedCheats(false); } } @@ -928,7 +928,7 @@ void Command_Setlives_f(void) P_GivePlayerLives(&players[consoleplayer], atoi(COM_Argv(1))); } - G_SetGameModified(multiplayer); + G_SetUsedCheats(false); } } @@ -955,7 +955,7 @@ void Command_Setcontinues_f(void) players[consoleplayer].continues = numcontinues; - G_SetGameModified(multiplayer); + G_SetUsedCheats(false); } } @@ -1446,7 +1446,7 @@ void Command_ObjectPlace_f(void) REQUIRE_SINGLEPLAYER; REQUIRE_NOULTIMATE; - G_SetGameModified(multiplayer); + G_SetUsedCheats(false); silent = COM_CheckParm("-silent"); diff --git a/src/m_menu.c b/src/m_menu.c index 55733e552..81567662a 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -7082,7 +7082,7 @@ static void M_AllowSuper(INT32 choice) M_StartMessage(M_GetText("You are now capable of turning super.\nRemember to get all the emeralds!\n"),NULL,MM_NOTHING); SR_PandorasBox[6].status = IT_GRAYEDOUT; - G_SetGameModified(multiplayer); + G_SetUsedCheats(false); } static void M_GetAllEmeralds(INT32 choice) @@ -7093,7 +7093,7 @@ static void M_GetAllEmeralds(INT32 choice) M_StartMessage(M_GetText("You now have all 7 emeralds.\nUse them wisely.\nWith great power comes great ring drain.\n"),NULL,MM_NOTHING); SR_PandorasBox[7].status = IT_GRAYEDOUT; - G_SetGameModified(multiplayer); + G_SetUsedCheats(false); } static void M_DestroyRobotsResponse(INT32 ch) @@ -7104,7 +7104,7 @@ static void M_DestroyRobotsResponse(INT32 ch) // Destroy all robots P_DestroyRobots(); - G_SetGameModified(multiplayer); + G_SetUsedCheats(false); } static void M_DestroyRobots(INT32 choice) @@ -8703,6 +8703,12 @@ static void M_DrawLoad(void) loadgameoffset = 0; M_DrawLoadGameData(); + + if (usedCheats) + { + V_DrawCenteredThinString(BASEVIDWIDTH/2, 184, 0, "\x85WARNING:\x80 Cheats have been activated."); + V_DrawCenteredThinString(BASEVIDWIDTH/2, 192, 0, "Progress will not be saved."); + } } // @@ -9004,12 +9010,18 @@ static void M_HandleLoadSave(INT32 choice) break; case KEY_ENTER: - if (ultimate_selectable && saveSlotSelected == NOSAVESLOT) + if (ultimate_selectable && saveSlotSelected == NOSAVESLOT && !usedCheats) { loadgamescroll = 0; S_StartSound(NULL, sfx_skid); M_StartMessage("Are you sure you want to play\n\x85ultimate mode\x80? It isn't remotely fair,\nand you don't even get an emblem for it.\n\n(Press 'Y' to confirm)\n",M_SaveGameUltimateResponse,MM_YESNO); } + else if (saveSlotSelected != NOSAVESLOT && savegameinfo[saveSlotSelected-1].lives == -42 && usedCheats) + { + loadgamescroll = 0; + S_StartSound(NULL, sfx_skid); + M_StartMessage(M_GetText("This cannot be done in a cheated game.\n\n(Press a key)\n"), NULL, MM_NOTHING); + } else if (saveSlotSelected == NOSAVESLOT || savegameinfo[saveSlotSelected-1].lives != -666) // don't allow loading of "bad saves" { loadgamescroll = 0; diff --git a/src/p_inter.c b/src/p_inter.c index 1094c3045..b86bb39a6 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2583,7 +2583,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget if (!(netgame || multiplayer || demoplayback || demorecording || metalrecording || modeattacking) && numgameovers < maxgameovers) { numgameovers++; - if (cursaveslot > 0) + if (!usedCheats && cursaveslot > 0) G_SaveGameOver((UINT32)cursaveslot, (target->player->continues <= 0)); } } diff --git a/src/p_setup.c b/src/p_setup.c index c41a5d94e..a965c5142 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -7764,7 +7764,7 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate) { // I'd love to do this in the menu code instead of here, but everything's a mess and I can't guarantee saving proper player struct info before the first act's started. You could probably refactor it, but it'd be a lot of effort. Easier to just work off known good code. ~toast 22/06/2020 if (!(ultimatemode || netgame || multiplayer || demoplayback || demorecording || metalrecording || modeattacking || marathonmode) - && cursaveslot > 0) + && !usedCheats && cursaveslot > 0) { G_SaveGame((UINT32)cursaveslot, gamemap); } From f082acbbdbc6dcb535804c4c050f0a95ea3fb773 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 28 Feb 2022 12:48:18 -0500 Subject: [PATCH 045/586] Don't allow Record Attack in cheated games --- 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 81567662a..6d1dec19e 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -3519,7 +3519,7 @@ boolean M_Responder(event_t *ev) #ifndef DEVELOP // TODO: Replays are scary, so I left the remaining instances of this alone. // It'd be nice to get rid of this once and for all though! - if (((currentMenu->menuitems[itemOn].status & IT_CALLTYPE) & IT_CALL_NOTMODIFIED) && modifiedgame && !savemoddata) + if (((currentMenu->menuitems[itemOn].status & IT_CALLTYPE) & IT_CALL_NOTMODIFIED) && (modifiedgame && !savemoddata) && !usedCheats) { S_StartSound(NULL, sfx_skid); M_StartMessage(M_GetText("This cannot be done in a modified game.\n\n(Press a key)\n"), NULL, MM_NOTHING); From 947dbda045929e0577a52a898bd40e71a6066ac1 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Thu, 3 Mar 2022 10:48:44 -0500 Subject: [PATCH 046/586] Use savemoddata for ultimate file check --- 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 6d1dec19e..c5c49a7b8 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -9010,7 +9010,7 @@ static void M_HandleLoadSave(INT32 choice) break; case KEY_ENTER: - if (ultimate_selectable && saveSlotSelected == NOSAVESLOT && !usedCheats) + if (ultimate_selectable && saveSlotSelected == NOSAVESLOT && !savemoddata) { loadgamescroll = 0; S_StartSound(NULL, sfx_skid); From d3ff5342dd4cec3583523a8d53e6d1d6f7b7b591 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 1 May 2022 19:34:18 -0400 Subject: [PATCH 047/586] Minor adjustments --- src/m_cheat.c | 6 ------ src/m_menu.c | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/src/m_cheat.c b/src/m_cheat.c index 78fb3a505..18a5a8609 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -72,9 +72,6 @@ static UINT8 cheatf_ultimate(void) static UINT8 cheatf_warp(void) { - if (modifiedgame) - return 0; - if (menuactive && currentMenu != &MainDef) return 0; // Only on the main menu! @@ -97,9 +94,6 @@ static UINT8 cheatf_devmode(void) { UINT8 i; - if (modifiedgame) - return 0; - if (menuactive && currentMenu != &MainDef) return 0; // Only on the main menu! diff --git a/src/m_menu.c b/src/m_menu.c index c5c49a7b8..d26712f1e 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -6711,7 +6711,7 @@ static void M_DrawAddons(void) // draw save icon x = BASEVIDWIDTH - x - 16; - V_DrawSmallScaledPatch(x, y + 4, ((!modifiedgame || savemoddata) ? 0 : V_TRANSLUCENT), addonsp[NUM_EXT+4]); + V_DrawSmallScaledPatch(x, y + 4, (!usedCheats ? 0 : V_TRANSLUCENT), addonsp[NUM_EXT+4]); if (modifiedgame) V_DrawSmallScaledPatch(x, y + 4, 0, addonsp[NUM_EXT+2]); From 5103253e0b3828db68e1d58a6d3d0749d90ba8e2 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Wed, 12 Oct 2022 00:57:15 -0400 Subject: [PATCH 048/586] Allow unlockable executors again --- 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 94659e0d7..810a7cd3f 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1797,7 +1797,7 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller { // Unlockable triggers required INT32 trigid = triggerline->args[1]; - if ((modifiedgame && !savemoddata) || (netgame || multiplayer)) + if (netgame || multiplayer) return false; else if (trigid < 0 || trigid > 31) // limited by 32 bit variable { @@ -1812,7 +1812,7 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller { // An unlockable itself must be unlocked! INT32 unlockid = triggerline->args[1]; - if ((modifiedgame && !savemoddata) || (netgame || multiplayer)) + if (netgame || multiplayer) return false; else if (unlockid < 0 || unlockid >= MAXUNLOCKABLES) // limited by unlockable count { From 969dc4813a4ebd41e1710e941bbd36f002c1796f Mon Sep 17 00:00:00 2001 From: Zwip-Zwap Zapony Date: Sat, 19 Nov 2022 19:57:08 +0100 Subject: [PATCH 049/586] Allow cosmetic add-ons mid-save --- 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 deb308da2..d5e6100b7 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -8074,7 +8074,7 @@ static boolean P_LoadAddon(UINT16 wadnum, UINT16 numlumps) ST_Start(); // Prevent savefile cheating - if (cursaveslot > 0) + if (modifiedgame && (cursaveslot > 0)) cursaveslot = 0; if (replacedcurrentmap && gamestate == GS_LEVEL && (netgame || multiplayer)) From 256d9b5fdb3411a79278e3ba2ec5000bc889770f Mon Sep 17 00:00:00 2001 From: Zwip-Zwap Zapony Date: Sun, 20 Nov 2022 11:50:01 +0100 Subject: [PATCH 050/586] Uncap console opening/closing animation --- src/console.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/src/console.c b/src/console.c index 40fb43121..9af9eb9a8 100644 --- a/src/console.c +++ b/src/console.c @@ -643,33 +643,39 @@ static void CON_ChangeHeight(void) // static void CON_MoveConsole(void) { - fixed_t conspeed; + static fixed_t fracmovement = 0; Lock_state(); - conspeed = FixedDiv(cons_speed.value*vid.fdupy, FRACUNIT); - // instant if (!cons_speed.value) { con_curlines = con_destlines; + Unlock_state(); return; } - // up/down move to dest - if (con_curlines < con_destlines) + // Not instant - Increment fracmovement fractionally + fracmovement += FixedMul(cons_speed.value*vid.fdupy, renderdeltatics); + + if (con_curlines < con_destlines) // Move the console downwards { - con_curlines += FixedInt(conspeed); - if (con_curlines > con_destlines) - con_curlines = con_destlines; + con_curlines += FixedInt(fracmovement); // Move by fracmovement's integer value + if (con_curlines > con_destlines) // If we surpassed the destination... + con_curlines = con_destlines; // ...clamp to it! } - else if (con_curlines > con_destlines) + else // Move the console upwards { - con_curlines -= FixedInt(conspeed); + con_curlines -= FixedInt(fracmovement); if (con_curlines < con_destlines) con_curlines = con_destlines; + + if (con_destlines == 0) // If the console is being closed, not just moved up... + con_tick = 0; // ...don't show the blinking cursor } + fracmovement %= FRACUNIT; // Reset fracmovement's integer value, but keep the fraction + Unlock_state(); } @@ -752,10 +758,6 @@ void CON_Ticker(void) CON_ChangeHeight(); } - // console movement - if (con_destlines != con_curlines) - CON_MoveConsole(); - // clip the view, so that the part under the console is not drawn con_clipviewtop = -1; if (cons_backpic.value) // clip only when using an opaque background @@ -1866,6 +1868,10 @@ void CON_Drawer(void) CON_ClearHUD(); } + // console movement + if (con_curlines != con_destlines) + CON_MoveConsole(); + if (con_curlines > 0) CON_DrawConsole(); else if (gamestate == GS_LEVEL From 435e1f6e7e1fab7e47dfc2df2ab60660583fe53d Mon Sep 17 00:00:00 2001 From: Zwip-Zwap Zapony Date: Sun, 20 Nov 2022 11:50:57 +0100 Subject: [PATCH 051/586] Make con_height adjustable on the fly --- src/console.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/console.c b/src/console.c index 9af9eb9a8..fb023c67e 100644 --- a/src/console.c +++ b/src/console.c @@ -110,6 +110,7 @@ static void CON_RecalcSize(void); static void CON_ChangeHeight(void); static void CON_DrawBackpic(void); +static void CONS_height_Change(void); static void CONS_hudlines_Change(void); static void CONS_backcolor_Change(void); @@ -136,7 +137,7 @@ static CV_PossibleValue_t speed_cons_t[] = {{0, "MIN"}, {64, "MAX"}, {0, NULL}}; static consvar_t cons_speed = CVAR_INIT ("con_speed", "8", CV_SAVE, speed_cons_t, NULL); // percentage of screen height to use for console -static consvar_t cons_height = CVAR_INIT ("con_height", "50", CV_SAVE, CV_Unsigned, NULL); +static consvar_t cons_height = CVAR_INIT ("con_height", "50", CV_CALL|CV_SAVE, CV_Unsigned, CONS_height_Change); static CV_PossibleValue_t backpic_cons_t[] = {{0, "translucent"}, {1, "picture"}, {0, NULL}}; // whether to use console background picture, or translucent mode @@ -156,6 +157,18 @@ consvar_t cons_backcolor = CVAR_INIT ("con_backcolor", "Green", CV_CALL|CV_SAVE, static void CON_Print(char *msg); +// Change the console height on demand +// +static void CONS_height_Change(void) +{ + Lock_state(); + + if (con_destlines > 0 && !con_startup) // If the console is open (as in, not using "bind")... + CON_ChangeHeight(); // ...update its height now, not only when it's closed and re-opened + + Unlock_state(); +} + // // static void CONS_hudlines_Change(void) From 396db189e7cf541f325d653ef5be7fa5ed1b2037 Mon Sep 17 00:00:00 2001 From: Zwip-Zwap Zapony Date: Sun, 20 Nov 2022 11:51:40 +0100 Subject: [PATCH 052/586] Draw the input prompt while the console is moving --- src/console.c | 52 +++++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/src/console.c b/src/console.c index fb023c67e..6f85dbf1c 100644 --- a/src/console.c +++ b/src/console.c @@ -61,7 +61,7 @@ static boolean con_started = false; // console has been initialised static boolean con_forcepic = true; // at startup toggle console translucency when first off boolean con_recalc; // set true when screen size has changed -static tic_t con_tick; // console ticker for anim or blinking prompt cursor +static tic_t con_tick; // console ticker for blinking prompt cursor // con_scrollup should use time (currenttime - lasttime).. static boolean consoletoggle; // true when console key pushed, ticker will handle @@ -1824,41 +1824,41 @@ static void CON_DrawConsole(void) } // draw console text lines from top to bottom - if (con_curlines < minheight) - return; - - i = con_cy - con_scrollup; - - // skip the last empty line due to the cursor being at the start of a new line - i--; - - i -= (con_curlines - minheight) / charheight; - - if (rendermode == render_none) return; - - for (y = (con_curlines-minheight) % charheight; y <= con_curlines-minheight; y += charheight, i++) + if (con_curlines >= minheight) { - INT32 x; - size_t c; + i = con_cy - con_scrollup; - p = (UINT8 *)&con_buffer[((i > 0 ? i : 0)%con_totallines)*con_width]; + // skip the last empty line due to the cursor being at the start of a new line + i--; - for (c = 0, x = charwidth; c < con_width; c++, x += charwidth, p++) + i -= (con_curlines - minheight) / charheight; + + if (rendermode == render_none) return; + + for (y = (con_curlines-minheight) % charheight; y <= con_curlines-minheight; y += charheight, i++) { - while (*p & 0x80) + INT32 x; + size_t c; + + p = (UINT8 *)&con_buffer[((i > 0 ? i : 0)%con_totallines)*con_width]; + + for (c = 0, x = charwidth; c < con_width; c++, x += charwidth, p++) { - charflags = (*p & 0x7f) << V_CHARCOLORSHIFT; - p++; - c++; + while (*p & 0x80) + { + charflags = (*p & 0x7f) << V_CHARCOLORSHIFT; + p++; + c++; + } + if (c >= con_width) + break; + V_DrawCharacter(x, y, (INT32)(*p) | charflags | cv_constextsize.value | V_NOSCALESTART, true); } - if (c >= con_width) - break; - V_DrawCharacter(x, y, (INT32)(*p) | charflags | cv_constextsize.value | V_NOSCALESTART, true); } } // draw prompt if enough place (not while game startup) - if ((con_curlines == con_destlines) && (con_curlines >= minheight) && !con_startup) + if ((con_curlines >= (minheight-charheight)) && !con_startup) CON_DrawInput(); } From 3a2834e781f42137bd17376e3e78da3d479ffbf9 Mon Sep 17 00:00:00 2001 From: ashifolfi Date: Sun, 20 Nov 2022 15:25:53 -0500 Subject: [PATCH 053/586] add R_TextureNameForNum and expose to lua --- src/lua_baselib.c | 18 ++++++++++++++++++ src/r_textures.c | 20 ++++++++++++++++++++ src/r_textures.h | 4 ++++ 3 files changed, 42 insertions(+) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 29adb478a..9cfde9706 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -2832,6 +2832,22 @@ static int lib_rTextureNumForName(lua_State *L) return 1; } +static int lib_rCheckTextureNameForNum(lua_State *L) +{ + INT32 num = luaL_checkstring(L, 1); + //HUDSAFE + lua_pushstring(L, R_CheckTextureNameForNum(num)); + return 1; +} + +static int lib_rTextureNameForNum(lua_State *L) +{ + INT32 num = luaL_checkstring(L, 1); + //HUDSAFE + lua_pushstring(L, R_TextureNameForNum(num)); + return 1; +} + // R_DRAW //////////// static int lib_rGetColorByName(lua_State *L) @@ -4174,6 +4190,8 @@ static luaL_Reg lib[] = { // r_data {"R_CheckTextureNumForName",lib_rCheckTextureNumForName}, {"R_TextureNumForName",lib_rTextureNumForName}, + {"R_CheckTextureNameForNum", lib_rCheckTextureNameForNum}, + {"R_TextureNameForNum", lib_rTextureNameForNum}, // r_draw {"R_GetColorByName", lib_rGetColorByName}, diff --git a/src/r_textures.c b/src/r_textures.c index 98c2788a2..2a9fc9953 100644 --- a/src/r_textures.c +++ b/src/r_textures.c @@ -1662,6 +1662,26 @@ INT32 R_CheckTextureNumForName(const char *name) return -1; } +// i was fully expecting this to take like an hour to figure out not 2 mintues and 5 lines of c - ashi +const char *R_CheckTextureNameForNum(INT32 num) +{ + if (textures[num] && textures[num]->name) + { + return textures[num]->name; + } + return "-"; +} + +const char *R_TextureNameForNum(INT32 num) +{ + const char *result = R_CheckTextureNameForNum(num); + + if (strcmp(result, "-")) + return "REDWALL"; + + return result; +} + // // R_TextureNumForName // diff --git a/src/r_textures.h b/src/r_textures.h index b9b48da8c..64be59ee3 100644 --- a/src/r_textures.h +++ b/src/r_textures.h @@ -104,6 +104,10 @@ INT32 R_TextureNumForName(const char *name); INT32 R_CheckTextureNumForName(const char *name); lumpnum_t R_GetFlatNumForName(const char *name); +// Returns the texture name for the texture number (in case you ever needed it) +const char *R_TextureNumForName(INT32 num); +const char *R_CheckTextureNumForName(INT32 num); + extern INT32 numtextures; #endif From e48f7d15381753e6ac49ea8c8607cc1a957617f0 Mon Sep 17 00:00:00 2001 From: ashifolfi Date: Sun, 20 Nov 2022 16:06:43 -0500 Subject: [PATCH 054/586] actually use correct names in the header --- src/r_textures.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/r_textures.h b/src/r_textures.h index 64be59ee3..4fb65f7e5 100644 --- a/src/r_textures.h +++ b/src/r_textures.h @@ -105,8 +105,8 @@ INT32 R_CheckTextureNumForName(const char *name); lumpnum_t R_GetFlatNumForName(const char *name); // Returns the texture name for the texture number (in case you ever needed it) -const char *R_TextureNumForName(INT32 num); -const char *R_CheckTextureNumForName(INT32 num); +const char *R_CheckTextureNameForNum(INT32 num); +const char *R_TextureNameForNum(INT32 num); extern INT32 numtextures; From 1b14dff0e9cb7cea73866a4a6abf51927d507606 Mon Sep 17 00:00:00 2001 From: ashifolfi Date: Sun, 20 Nov 2022 16:06:47 -0500 Subject: [PATCH 055/586] add comments + better checktexturename if statement --- src/r_textures.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/r_textures.c b/src/r_textures.c index 2a9fc9953..34b2f0637 100644 --- a/src/r_textures.c +++ b/src/r_textures.c @@ -1662,21 +1662,30 @@ INT32 R_CheckTextureNumForName(const char *name) return -1; } -// i was fully expecting this to take like an hour to figure out not 2 mintues and 5 lines of c - ashi +// +// R_CheckTextureNameForNum +// +// because sidedefs use numbers and sometimes you want names +// returns no texture marker if no texture was found +// const char *R_CheckTextureNameForNum(INT32 num) { - if (textures[num] && textures[num]->name) - { + if (num > 0 && num < numtextures) return textures[num]->name; - } + return "-"; } +// +// R_TextureNameForNum +// +// calls R_CheckTextureNameForNum and returns REDWALL if result is a no texture marker +// const char *R_TextureNameForNum(INT32 num) { const char *result = R_CheckTextureNameForNum(num); - if (strcmp(result, "-")) + if (strcmp(result, "-") == 0) return "REDWALL"; return result; From 47e981d2a876940f581332afd379caca6568f87e Mon Sep 17 00:00:00 2001 From: ashifolfi Date: Sun, 20 Nov 2022 16:07:14 -0500 Subject: [PATCH 056/586] actually check the right type in lua --- 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 9cfde9706..efbc80472 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -2834,7 +2834,7 @@ static int lib_rTextureNumForName(lua_State *L) static int lib_rCheckTextureNameForNum(lua_State *L) { - INT32 num = luaL_checkstring(L, 1); + INT32 num = (INT32)luaL_checkinteger(L, 1); //HUDSAFE lua_pushstring(L, R_CheckTextureNameForNum(num)); return 1; @@ -2842,7 +2842,7 @@ static int lib_rCheckTextureNameForNum(lua_State *L) static int lib_rTextureNameForNum(lua_State *L) { - INT32 num = luaL_checkstring(L, 1); + INT32 num = (INT32)luaL_checkinteger(L, 1); //HUDSAFE lua_pushstring(L, R_TextureNameForNum(num)); return 1; From 356bdb25a1b4d36db3fe4c3a385a14f34e5e687a Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 6 Sep 2022 12:36:59 -0700 Subject: [PATCH 057/586] Add a hitbox renderer to Software mode renderhitbox - Tangible - collision activating objects, minus rings - All - every object - Intangible - the opposite of Tangible, also no rings - Rings - rings --- src/Sourcefile | 1 + src/d_netcmd.c | 1 + src/p_mobj.h | 2 +- src/r_bbox.c | 290 +++++++++++++++++++++++++++++++++++++++++++++++++ src/r_things.c | 8 ++ src/r_things.h | 3 + src/screen.h | 2 +- 7 files changed, 305 insertions(+), 2 deletions(-) create mode 100644 src/r_bbox.c diff --git a/src/Sourcefile b/src/Sourcefile index de90bb609..fb08c2171 100644 --- a/src/Sourcefile +++ b/src/Sourcefile @@ -64,6 +64,7 @@ r_skins.c r_sky.c r_splats.c r_things.c +r_bbox.c r_textures.c r_patch.c r_patchrotation.c diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 4e90db0dc..ceb94fb1f 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -868,6 +868,7 @@ void D_RegisterClientCommands(void) // screen.c CV_RegisterVar(&cv_fullscreen); CV_RegisterVar(&cv_renderview); + CV_RegisterVar(&cv_renderhitbox); CV_RegisterVar(&cv_renderer); CV_RegisterVar(&cv_scr_depth); CV_RegisterVar(&cv_scr_width); diff --git a/src/p_mobj.h b/src/p_mobj.h index 60601692c..a7e25f461 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -122,7 +122,7 @@ typedef enum MF_AMBIENT = 1<<10, // Slide this object when it hits a wall. MF_SLIDEME = 1<<11, - // Player cheat. + // Don't collide with walls or solid objects. Two MF_NOCLIP objects can't touch each other at all! MF_NOCLIP = 1<<12, // Allow moves to any height, no gravity. For active floaters. MF_FLOAT = 1<<13, diff --git a/src/r_bbox.c b/src/r_bbox.c new file mode 100644 index 000000000..e3b5216bf --- /dev/null +++ b/src/r_bbox.c @@ -0,0 +1,290 @@ +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 1993-1996 by id Software, Inc. +// Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2021 by Sonic Team Junior. +// Copyright (C) 2022 by Kart Krew. +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- +/// \file r_bbox.c +/// \brief Boundary box (cube) renderer + +#include "doomdef.h" +#include "command.h" +#include "r_local.h" +#include "screen.h" // cv_renderhitbox +#include "v_video.h" // V_DrawFill + +enum { + RENDERHITBOX_OFF, + RENDERHITBOX_TANGIBLE, + RENDERHITBOX_ALL, + RENDERHITBOX_INTANGIBLE, + RENDERHITBOX_RINGS, +}; + +static CV_PossibleValue_t renderhitbox_cons_t[] = { + {RENDERHITBOX_OFF, "Off"}, + {RENDERHITBOX_TANGIBLE, "Tangible"}, + {RENDERHITBOX_ALL, "All"}, + {RENDERHITBOX_INTANGIBLE, "Intangible"}, + {RENDERHITBOX_RINGS, "Rings"}, + {0}}; + +consvar_t cv_renderhitbox = CVAR_INIT ("renderhitbox", "Off", 0, renderhitbox_cons_t, NULL); + +struct bbox_col { + INT32 x; + INT32 y; + INT32 h; +}; + +struct bbox_config { + fixed_t height; + fixed_t tz; + struct bbox_col col[4]; + UINT8 color; +}; + +static inline void +raster_bbox_seg +( INT32 x, + fixed_t y, + fixed_t h, + UINT8 pixel) +{ + y /= FRACUNIT; + + if (y < 0) + y = 0; + + h = y + (FixedCeil(abs(h)) / FRACUNIT); + + if (h >= viewheight) + h = viewheight; + + while (y < h) + { + topleft[x + y * vid.width] = pixel; + y++; + } +} + +static void +draw_bbox_col +( struct bbox_config * bb, + int p, + fixed_t tx, + fixed_t ty) +{ + struct bbox_col *col = &bb->col[p]; + + fixed_t xscale = FixedDiv(projection, ty); + fixed_t yscale = FixedDiv(projectiony, ty); + + col->x = (centerxfrac + FixedMul(tx, xscale)) / FRACUNIT; + col->y = (centeryfrac - FixedMul(bb->tz, yscale)); + col->h = FixedMul(bb->height, yscale); + + // Using this function is TOO EASY! + V_DrawFill( + viewwindowx + col->x, + viewwindowy + col->y / FRACUNIT, 1, + col->h / FRACUNIT, V_NOSCALESTART | bb->color); +} + +static void +draw_bbox_row +( struct bbox_config * bb, + int p1, + int p2) +{ + struct bbox_col + *a = &bb->col[p1], + *b = &bb->col[p2]; + + INT32 x1, x2; // left, right + INT32 dx; // width + + fixed_t y1, y2; // top, bottom + fixed_t s1, s2; // top and bottom increment + + if (a->x > b->x) + { + struct bbox_col *c = a; + a = b; + b = c; + } + + x1 = a->x; + x2 = b->x; + + if (x2 >= viewwidth) + x2 = viewwidth - 1; + + if (x1 == x2 || x1 >= viewwidth || x2 < 0) + return; + + dx = x2 - x1; + + y1 = a->y; + y2 = b->y; + s1 = (y2 - y1) / dx; + + y2 = y1 + a->h; + s2 = ((b->y + b->h) - y2) / dx; + + // FixedCeil needs a minimum!!! :D :D + + if (s1 == 0) + s1 = 1; + + if (s2 == 0) + s2 = 1; + + if (x1 < 0) + { + y1 -= x1 * s1; + y2 -= x1 * s2; + x1 = 0; + } + + while (x1 < x2) + { + raster_bbox_seg(x1, y1, s1, bb->color); + raster_bbox_seg(x1, y2, s2, bb->color); + + y1 += s1; + y2 += s2; + + x1++; + } +} + +static UINT8 +get_bbox_color (mobj_t *thing) +{ + UINT32 flags = thing->flags; + + if (thing->player) + return 255; // 0FF + + if (flags & (MF_NOCLIPTHING)) + return 7; // BFBFBF + + if (flags & (MF_BOSS|MF_MISSILE|MF_ENEMY|MF_PAIN)) + return 35; // F00 + + if (flags & (MF_SPECIAL|MF_MONITOR)) + return 73; // FF0 + + if (flags & (MF_NOCLIP)) + return 152; // 00F + + return 0; // FFF +} + +void R_DrawThingBoundingBox(mobj_t *thing) +{ + fixed_t rs, rc; // radius offsets + fixed_t gx, gy; // origin + fixed_t tx, ty; // translated coordinates + + struct bbox_config bb = {0}; + + rs = FixedMul(thing->radius, viewsin); + rc = FixedMul(thing->radius, viewcos); + + gx = thing->x - viewx; + gy = thing->y - viewy; + + tx = FixedMul(gx, viewsin) - FixedMul(gy, viewcos); + ty = FixedMul(gx, viewcos) + FixedMul(gy, viewsin); + + bb.height = thing->height; + bb.tz = (thing->z + bb.height) - viewz; + bb.color = get_bbox_color(thing); + + // 1--3 + // | | + // 0--2 + + // left + + tx -= rs; + ty -= rc; + + draw_bbox_col(&bb, 0, tx + rc, ty - rs); // bottom + draw_bbox_col(&bb, 1, tx - rc, ty + rs); // top + + // right + + tx += rs + rs; + ty += rc + rc; + + draw_bbox_col(&bb, 2, tx + rc, ty - rs); // bottom + draw_bbox_col(&bb, 3, tx - rc, ty + rs); // top + + // connect all four columns + + draw_bbox_row(&bb, 0, 1); + draw_bbox_row(&bb, 1, 3); + draw_bbox_row(&bb, 3, 2); + draw_bbox_row(&bb, 2, 0); +} + +static boolean is_tangible (mobj_t *thing) +{ + // These objects can never touch another + if (thing->flags & (MF_NOCLIPTHING)) + { + return false; + } + + // These objects probably do nothing! :D + if ((thing->flags & (MF_SPECIAL|MF_SOLID|MF_SHOOTABLE + |MF_PUSHABLE|MF_BOSS|MF_MISSILE|MF_SPRING + |MF_BOUNCE|MF_MONITOR|MF_FIRE|MF_ENEMY + |MF_PAIN|MF_STICKY + |MF_GRENADEBOUNCE)) == 0U) + { + return false; + } + + return true; +} + +boolean R_ThingBoundingBoxVisible(mobj_t *thing) +{ + INT32 cvmode = cv_renderhitbox.value; + + switch (cvmode) + { + case RENDERHITBOX_OFF: + return false; + + case RENDERHITBOX_ALL: + return true; + + case RENDERHITBOX_INTANGIBLE: + return !is_tangible(thing); + + case RENDERHITBOX_TANGIBLE: + // Exclude rings from here, lots of them! + if (thing->type == MT_RING) + { + return false; + } + + return is_tangible(thing); + + case RENDERHITBOX_RINGS: + return (thing->type == MT_RING); + + default: + return false; + } +} diff --git a/src/r_things.c b/src/r_things.c index fed873fd6..65047176d 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2939,6 +2939,14 @@ static void R_DrawSprite(vissprite_t *spr) R_DrawFloorSplat(spr); else R_DrawVisSprite(spr); + + if (R_ThingBoundingBoxVisible(spr->mobj)) + { + // fuck you fuck you fuck you FUCK YOU + // (shadows are linked to their mobj) + if (!(spr->cut & SC_SHADOW)) + R_DrawThingBoundingBox(spr->mobj); + } } // Special drawer for precipitation sprites Tails 08-18-2002 diff --git a/src/r_things.h b/src/r_things.h index 35eeb9ce1..4ba649c30 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -66,6 +66,9 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel); void R_InitSprites(void); void R_ClearSprites(void); +boolean R_ThingBoundingBoxVisible(mobj_t *thing); +void R_DrawThingBoundingBox(mobj_t *thing); + boolean R_ThingVisible (mobj_t *thing); boolean R_ThingVisibleWithinDist (mobj_t *thing, diff --git a/src/screen.h b/src/screen.h index add048b25..5a69be659 100644 --- a/src/screen.h +++ b/src/screen.h @@ -199,7 +199,7 @@ extern CV_PossibleValue_t cv_renderer_t[]; extern INT32 scr_bpp; extern UINT8 *scr_borderpatch; // patch used to fill the view borders -extern consvar_t cv_scr_width, cv_scr_height, cv_scr_depth, cv_renderview, cv_renderer, cv_fullscreen; +extern consvar_t cv_scr_width, cv_scr_height, cv_scr_depth, cv_renderview, cv_renderer, cv_renderhitbox, cv_fullscreen; // wait for page flipping to end or not extern consvar_t cv_vidwait; extern consvar_t cv_timescale; From 694804cd96cafb1bfb146406f775e2bd23b1fb7a Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 10 Sep 2022 21:27:37 -0700 Subject: [PATCH 058/586] Refactor hitbox renderer to project vissprites Properly accounts for portals (skyboxes). --- src/r_bbox.c | 46 ++++++--------- src/r_things.c | 155 ++++++++++++++++++++++++++++++++++++++++++------- src/r_things.h | 9 ++- 3 files changed, 161 insertions(+), 49 deletions(-) diff --git a/src/r_bbox.c b/src/r_bbox.c index e3b5216bf..bbac0f56b 100644 --- a/src/r_bbox.c +++ b/src/r_bbox.c @@ -165,11 +165,11 @@ draw_bbox_row } static UINT8 -get_bbox_color (mobj_t *thing) +get_bbox_color (vissprite_t *vis) { - UINT32 flags = thing->flags; + UINT32 flags = vis->mobjflags; - if (thing->player) + if (vis->mobj->player) return 255; // 0FF if (flags & (MF_NOCLIPTHING)) @@ -187,26 +187,21 @@ get_bbox_color (mobj_t *thing) return 0; // FFF } -void R_DrawThingBoundingBox(mobj_t *thing) +void R_DrawThingBoundingBox(vissprite_t *vis) { - fixed_t rs, rc; // radius offsets - fixed_t gx, gy; // origin - fixed_t tx, ty; // translated coordinates + // radius offsets + fixed_t rs = vis->scale; + fixed_t rc = vis->xscale; - struct bbox_config bb = {0}; + // translated coordinates + fixed_t tx = vis->gx; + fixed_t ty = vis->gy; - rs = FixedMul(thing->radius, viewsin); - rc = FixedMul(thing->radius, viewcos); - - gx = thing->x - viewx; - gy = thing->y - viewy; - - tx = FixedMul(gx, viewsin) - FixedMul(gy, viewcos); - ty = FixedMul(gx, viewcos) + FixedMul(gy, viewsin); - - bb.height = thing->height; - bb.tz = (thing->z + bb.height) - viewz; - bb.color = get_bbox_color(thing); + struct bbox_config bb = { + .height = vis->thingheight, + .tz = vis->texturemid, + .color = get_bbox_color(vis), + }; // 1--3 // | | @@ -214,18 +209,15 @@ void R_DrawThingBoundingBox(mobj_t *thing) // left - tx -= rs; - ty -= rc; - - draw_bbox_col(&bb, 0, tx + rc, ty - rs); // bottom + draw_bbox_col(&bb, 0, tx, ty); // bottom draw_bbox_col(&bb, 1, tx - rc, ty + rs); // top // right - tx += rs + rs; - ty += rc + rc; + tx += rs; + ty += rc; - draw_bbox_col(&bb, 2, tx + rc, ty - rs); // bottom + draw_bbox_col(&bb, 2, tx, ty); // bottom draw_bbox_col(&bb, 3, tx - rc, ty + rs); // top // connect all four columns diff --git a/src/r_things.c b/src/r_things.c index 65047176d..6e4062219 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1424,6 +1424,91 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, objectsdrawn++; } +static void R_ProjectBoundingBox(mobj_t *thing, vissprite_t *vis) +{ + fixed_t gx, gy; + fixed_t tx, tz; + + vissprite_t *box; + + if (!R_ThingBoundingBoxVisible(thing)) + { + return; + } + + // 1--3 + // | | + // 0--2 + + // start in the (0) corner + gx = thing->x - thing->radius - viewx; + gy = thing->y - thing->radius - viewy; + + tz = FixedMul(gx, viewcos) + FixedMul(gy, viewsin); + + // thing is behind view plane? + // if parent vis is visible, ignore this + if (!vis && (tz < FixedMul(MINZ, thing->scale))) + { + return; + } + + tx = FixedMul(gx, viewsin) - FixedMul(gy, viewcos); + + // too far off the side? + if (!vis && abs(tx) > FixedMul(tz, fovtan)<<2) + { + return; + } + + box = R_NewVisSprite(); + box->mobj = thing; + box->mobjflags = thing->flags; + box->thingheight = thing->height; + box->cut = SC_BBOX; + + box->gx = tx; + box->gy = tz; + + box->scale = 2 * FixedMul(thing->radius, viewsin); + box->xscale = 2 * FixedMul(thing->radius, viewcos); + + box->pz = thing->z; + box->pzt = box->pz + box->thingheight; + + box->gzt = box->pzt; + box->gz = box->pz; + box->texturemid = box->gzt - viewz; + + if (vis) + { + box->x1 = vis->x1; + box->x2 = vis->x2; + box->szt = vis->szt; + box->sz = vis->sz; + + box->sortscale = vis->sortscale; // link sorting to sprite + box->dispoffset = vis->dispoffset + 5; + + box->cut |= SC_LINKDRAW; + } + else + { + fixed_t xscale = FixedDiv(projection, tz); + fixed_t yscale = FixedDiv(projectiony, tz); + fixed_t top = (centeryfrac - FixedMul(box->texturemid, yscale)); + + box->x1 = (centerxfrac + FixedMul(box->gx, xscale)) / FRACUNIT; + box->x2 = box->x1; + + box->szt = top / FRACUNIT; + box->sz = (top + FixedMul(box->thingheight, yscale)) / FRACUNIT; + + box->sortscale = yscale; + box->dispoffset = 0; + } +} + // // R_ProjectSprite // Generates a vissprite for a thing @@ -2181,6 +2266,8 @@ static void R_ProjectSprite(mobj_t *thing) if (oldthing->shadowscale && cv_shadow.value) R_ProjectDropShadow(oldthing, vis, oldthing->shadowscale, basetx, basetz); + R_ProjectBoundingBox(oldthing, vis); + // Debug ++objectsdrawn; } @@ -2406,8 +2493,26 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel) hoop_limit_dist = (fixed_t)(cv_drawdist_nights.value) << FRACBITS; for (thing = sec->thinglist; thing; thing = thing->snext) { - if (R_ThingVisibleWithinDist(thing, limit_dist, hoop_limit_dist)) - R_ProjectSprite(thing); + if (R_ThingWithinDist(thing, limit_dist, hoop_limit_dist)) + { + const INT32 oldobjectsdrawn = objectsdrawn; + + if (R_ThingVisible(thing)) + { + R_ProjectSprite(thing); + } + + // I'm so smart :^) + if (objectsdrawn == oldobjectsdrawn) + { + /* + Object is invisible OR is off screen but + render its bbox even if the latter because + radius could be bigger than sprite. + */ + R_ProjectBoundingBox(thing, NULL); + } + } } // no, no infinite draw distance for precipitation. this option at zero is supposed to turn it off @@ -2495,6 +2600,10 @@ static void R_SortVisSprites(vissprite_t* vsprsortedhead, UINT32 start, UINT32 e if (dsfirst->cut & SC_SHADOW) continue; + // don't connect to your bounding box! + if (dsfirst->cut & SC_BBOX) + continue; + // don't connect if it's not the tracer if (dsfirst->mobj != ds->mobj) continue; @@ -2935,18 +3044,12 @@ static void R_DrawSprite(vissprite_t *spr) mfloorclip = spr->clipbot; mceilingclip = spr->cliptop; - if (spr->cut & SC_SPLAT) + if (spr->cut & SC_BBOX) + R_DrawThingBoundingBox(spr); + else if (spr->cut & SC_SPLAT) R_DrawFloorSplat(spr); else R_DrawVisSprite(spr); - - if (R_ThingBoundingBoxVisible(spr->mobj)) - { - // fuck you fuck you fuck you FUCK YOU - // (shadows are linked to their mobj) - if (!(spr->cut & SC_SHADOW)) - R_DrawThingBoundingBox(spr->mobj); - } } // Special drawer for precipitation sprites Tails 08-18-2002 @@ -3182,9 +3285,13 @@ void R_ClipSprites(drawseg_t* dsstart, portal_t* portal) for (; clippedvissprites < visspritecount; clippedvissprites++) { vissprite_t *spr = R_GetVisSprite(clippedvissprites); - INT32 x1 = (spr->cut & SC_SPLAT) ? 0 : spr->x1; - INT32 x2 = (spr->cut & SC_SPLAT) ? viewwidth : spr->x2; - R_ClipVisSprite(spr, x1, x2, dsstart, portal); + + if (!(spr->cut & SC_BBOX)) // Do not clip bounding boxes + { + INT32 x1 = (spr->cut & SC_SPLAT) ? 0 : spr->x1; + INT32 x2 = (spr->cut & SC_SPLAT) ? viewwidth : spr->x2; + R_ClipVisSprite(spr, x1, x2, dsstart, portal); + } } } @@ -3198,16 +3305,11 @@ boolean R_ThingVisible (mobj_t *thing) )); } -boolean R_ThingVisibleWithinDist (mobj_t *thing, +boolean R_ThingWithinDist (mobj_t *thing, fixed_t limit_dist, fixed_t hoop_limit_dist) { - fixed_t approx_dist; - - if (! R_ThingVisible(thing)) - return false; - - approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y); + const fixed_t approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y); if (thing->sprite == SPR_HOOP) { @@ -3223,6 +3325,17 @@ boolean R_ThingVisibleWithinDist (mobj_t *thing, return true; } +// For OpenGL, TODO: REMOVE!! +boolean R_ThingVisibleWithinDist (mobj_t *thing, + fixed_t limit_dist, + fixed_t hoop_limit_dist) +{ + if (! R_ThingVisible(thing)) + return false; + + return R_ThingWithinDist(thing, limit_dist, hoop_limit_dist); +} + /* Check if precipitation may be drawn from our current view. */ boolean R_PrecipThingVisible (precipmobj_t *precipthing, fixed_t limit_dist) diff --git a/src/r_things.h b/src/r_things.h index 4ba649c30..f1855dfd8 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -67,10 +67,13 @@ void R_InitSprites(void); void R_ClearSprites(void); boolean R_ThingBoundingBoxVisible(mobj_t *thing); -void R_DrawThingBoundingBox(mobj_t *thing); boolean R_ThingVisible (mobj_t *thing); +boolean R_ThingWithinDist (mobj_t *thing, + fixed_t draw_dist, + fixed_t nights_draw_dist); + boolean R_ThingVisibleWithinDist (mobj_t *thing, fixed_t draw_dist, fixed_t nights_draw_dist); @@ -135,6 +138,7 @@ typedef enum SC_SHADOW = 1<<10, SC_SHEAR = 1<<11, SC_SPLAT = 1<<12, + SC_BBOX = 1<<13, // masks SC_CUTMASK = SC_TOP|SC_BOTTOM, SC_FLAGMASK = ~SC_CUTMASK @@ -224,6 +228,9 @@ void R_ClipSprites(drawseg_t* dsstart, portal_t* portal); void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2, drawseg_t* dsstart, portal_t* portal); boolean R_SpriteIsFlashing(vissprite_t *vis); + +void R_DrawThingBoundingBox(vissprite_t *spr); + UINT8 *R_GetSpriteTranslation(vissprite_t *vis); // ---------- From 99653de13431d91ae9259dfd6c002861ea396156 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 11 Sep 2022 06:25:08 -0700 Subject: [PATCH 059/586] Do not render viewmobj or skybox viewpoint hitbox If you are a spectator (or in first person), the hitbox exists right ontop of you and hitboxes don't render correctly if they are too close to the viewpoint. --- src/r_bbox.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/r_bbox.c b/src/r_bbox.c index bbac0f56b..3d46aa566 100644 --- a/src/r_bbox.c +++ b/src/r_bbox.c @@ -253,6 +253,27 @@ boolean R_ThingBoundingBoxVisible(mobj_t *thing) { INT32 cvmode = cv_renderhitbox.value; + // Do not render bbox for these + switch (thing->type) + { + default: + // First person / awayviewmobj -- rendering + // a bbox too close to the viewpoint causes + // anomalies and these are exactly on the + // viewpoint! + if (thing != r_viewmobj) + { + break; + } + // FALLTHRU + + case MT_SKYBOX: + // Ditto for skybox viewpoint but because they + // are rendered using portals in Software, + // r_viewmobj does not point here. + return false; + } + switch (cvmode) { case RENDERHITBOX_OFF: From 7527fdbb568358bc56755220945255c8adaefeae Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 11 Sep 2022 07:08:10 -0700 Subject: [PATCH 060/586] Remedy some quirky rendering of hitboxes if your viewpoint is too close It's not correct but it's better than before. --- src/r_bbox.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/r_bbox.c b/src/r_bbox.c index 3d46aa566..e1749225c 100644 --- a/src/r_bbox.c +++ b/src/r_bbox.c @@ -82,8 +82,13 @@ draw_bbox_col { struct bbox_col *col = &bb->col[p]; - fixed_t xscale = FixedDiv(projection, ty); - fixed_t yscale = FixedDiv(projectiony, ty); + fixed_t xscale, yscale; + + if (ty < FRACUNIT) // projection breaks down here + ty = FRACUNIT; + + xscale = FixedDiv(projection, ty); + yscale = FixedDiv(projectiony, ty); col->x = (centerxfrac + FixedMul(tx, xscale)) / FRACUNIT; col->y = (centeryfrac - FixedMul(bb->tz, yscale)); From 5b53017a09eb70c94ffaae259350d765de901988 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 11 Sep 2022 16:54:15 -0700 Subject: [PATCH 061/586] r_opengl: add PF_WireFrame and SHADER_NONE Draw lines instead of tris and disable shader entirely. --- src/hardware/hw_defs.h | 4 +++- src/hardware/r_opengl/r_opengl.c | 8 +++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index fca9b80a3..bb27c34fa 100644 --- a/src/hardware/hw_defs.h +++ b/src/hardware/hw_defs.h @@ -136,6 +136,7 @@ typedef struct // Predefined shader types enum { + SHADER_NONE = -1, SHADER_DEFAULT = 0, SHADER_FLOOR, @@ -237,7 +238,8 @@ enum EPolyFlags 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_Ripple = 0x00100000 // Water ripple effect. The current backend doesn't use it for anything. + PF_Ripple = 0x00100000, // Water ripple effect. The current backend doesn't use it for anything. + PF_WireFrame = 0x00200000, // Draws vertices as lines instead of triangles }; diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 9d1630abb..3a97f9315 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -1030,6 +1030,12 @@ EXPORT void HWRAPI(LoadCustomShader) (int number, char *code, size_t size, boole EXPORT void HWRAPI(SetShader) (int type) { #ifdef GL_SHADERS + if (type == SHADER_NONE) + { + HWRAPI(UnSetShader)(); + return; + } + if (gl_allowshaders != HWD_SHADEROPTION_OFF) { gl_shader_t *shader = gl_shaderstate.current; @@ -2290,7 +2296,7 @@ EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUI pglVertexPointer(3, GL_FLOAT, sizeof(FOutVector), &pOutVerts[0].x); pglTexCoordPointer(2, GL_FLOAT, sizeof(FOutVector), &pOutVerts[0].s); - pglDrawArrays(GL_TRIANGLE_FAN, 0, iNumPts); + pglDrawArrays(PolyFlags & PF_WireFrame ? GL_LINES : GL_TRIANGLE_FAN, 0, iNumPts); if (PolyFlags & PF_RemoveYWrap) pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); From bfaf2bc6f3635f3e95b8bf6172d9a2f6d3e22edf Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 11 Sep 2022 16:57:58 -0700 Subject: [PATCH 062/586] OpenGL hitbox renderer I apologize for that vertex array. --- src/hardware/hw_glob.h | 1 + src/hardware/hw_main.c | 118 +++++++++++++++++++++++++++++++++++++++-- src/r_bbox.c | 9 ++-- src/r_things.h | 1 + 4 files changed, 120 insertions(+), 9 deletions(-) diff --git a/src/hardware/hw_glob.h b/src/hardware/hw_glob.h index 1ec9101c3..504cdf148 100644 --- a/src/hardware/hw_glob.h +++ b/src/hardware/hw_glob.h @@ -81,6 +81,7 @@ typedef struct gl_vissprite_s boolean flip, vflip; boolean precip; // Tails 08-25-2002 + boolean bbox; boolean rotated; UINT8 translucency; //alpha level 0-255 diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 3cb7275a0..24d5925bd 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -66,6 +66,7 @@ static void HWR_ProjectSprite(mobj_t *thing); #ifdef HWPRECIP static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing); #endif +static void HWR_ProjectBoundingBox(mobj_t *thing); void HWR_AddTransparentFloor(levelflat_t *levelflat, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, extracolormap_t *planecolormap); void HWR_AddTransparentPolyobjectFloor(levelflat_t *levelflat, polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, @@ -4036,6 +4037,54 @@ static void HWR_SplitSprite(gl_vissprite_t *spr) HWR_LinkDrawHackAdd(wallVerts, spr); } +static void HWR_DrawBoundingBox(gl_vissprite_t *vis) +{ + FOutVector v[24]; + FSurfaceInfo Surf = {0}; + + // + // create a cube (side view) + // + // 5--4 3 + // | + // | + // 0--1 2 + // + // repeat this 4 times (overhead) + // + // + // 17 20 21 11 + // 16 15 14 10 + // 27 22 *--* 07 12 + // | | + // 26 23 *--* 06 13 + // 24 00 01 02 + // 25 05 04 03 + // + + v[000].x = v[005].x = v[015].x = v[016].x = v[017].x = v[020].x = + v[022].x = v[023].x = v[024].x = v[025].x = v[026].x = v[027].x = vis->x1; // west + + v[001].x = v[002].x = v[003].x = v[004].x = v[006].x = v[007].x = + v[010].x = v[011].x = v[012].x = v[013].x = v[014].x = v[021].x = vis->x2; // east + + v[000].z = v[001].z = v[002].z = v[003].z = v[004].z = v[005].z = + v[006].z = v[013].z = v[023].z = v[024].z = v[025].z = v[026].z = vis->z1; // south + + v[007].z = v[010].z = v[011].z = v[012].z = v[014].z = v[015].z = + v[016].z = v[017].z = v[020].z = v[021].z = v[022].z = v[027].z = vis->z2; // north + + v[000].y = v[001].y = v[002].y = v[006].y = v[007].y = v[010].y = + v[014].y = v[015].y = v[016].y = v[022].y = v[023].y = v[024].y = vis->gz; // bottom + + v[003].y = v[004].y = v[005].y = v[011].y = v[012].y = v[013].y = + v[017].y = v[020].y = v[021].y = v[025].y = v[026].y = v[027].y = vis->gzt; // top + + Surf.PolyColor = V_GetColor(R_GetBoundingBoxColor(vis->mobj)); + + HWR_ProcessPolygon(&Surf, v, 24, PF_Modulated|PF_NoTexture|PF_WireFrame, SHADER_NONE, false); +} + // -----------------+ // HWR_DrawSprite : Draw flat sprites // : (monsters, bonuses, weapons, lights, ...) @@ -4480,9 +4529,16 @@ static int CompareVisSprites(const void *p1, const void *p2) int transparency1; int transparency2; + int linkdraw1; + int linkdraw2; + + // bbox doesn't need to be sorted + if (spr1->bbox || spr2->bbox) + return 0; + // check for precip first, because then sprX->mobj is actually a precipmobj_t and does not have flags2 or tracer - int linkdraw1 = !spr1->precip && (spr1->mobj->flags2 & MF2_LINKDRAW) && spr1->mobj->tracer; - int linkdraw2 = !spr2->precip && (spr2->mobj->flags2 & MF2_LINKDRAW) && spr2->mobj->tracer; + linkdraw1 = !spr1->precip && (spr1->mobj->flags2 & MF2_LINKDRAW) && spr1->mobj->tracer; + linkdraw2 = !spr2->precip && (spr2->mobj->flags2 & MF2_LINKDRAW) && spr2->mobj->tracer; // ^ is the XOR operation // if comparing a linkdraw and non-linkdraw sprite or 2 linkdraw sprites with different tracers, then use @@ -4852,6 +4908,9 @@ static void HWR_DrawSprites(void) for (i = 0; i < gl_visspritecount; i++) { gl_vissprite_t *spr = gl_vsprorder[i]; + if (spr->bbox) + HWR_DrawBoundingBox(spr); + else #ifdef HWPRECIP if (spr->precip) HWR_DrawPrecipitationSprite(spr); @@ -4951,8 +5010,15 @@ static void HWR_AddSprites(sector_t *sec) hoop_limit_dist = (fixed_t)(cv_drawdist_nights.value) << FRACBITS; for (thing = sec->thinglist; thing; thing = thing->snext) { - if (R_ThingVisibleWithinDist(thing, limit_dist, hoop_limit_dist)) - HWR_ProjectSprite(thing); + if (R_ThingWithinDist(thing, limit_dist, hoop_limit_dist)) + { + if (R_ThingVisible(thing)) + { + HWR_ProjectSprite(thing); + } + + HWR_ProjectBoundingBox(thing); + } } #ifdef HWPRECIP @@ -5462,6 +5528,7 @@ static void HWR_ProjectSprite(mobj_t *thing) vis->vflip = vflip; vis->precip = false; + vis->bbox = false; vis->angle = interp.angle; } @@ -5584,6 +5651,7 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing) vis->gz = vis->gzt - FIXED_TO_FLOAT(spritecachedinfo[lumpoff].height); vis->precip = true; + vis->bbox = false; // okay... this is a hack, but weather isn't networked, so it should be ok if (!(thing->precipflags & PCF_THUNK)) @@ -5597,6 +5665,48 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing) } #endif +static void HWR_ProjectBoundingBox(mobj_t *thing) +{ + gl_vissprite_t *vis; + float tr_x, tr_y; + float tz; + float rad; + + if (!thing) + return; + + if (!R_ThingBoundingBoxVisible(thing)) + return; + + // transform the origin point + tr_x = FIXED_TO_FLOAT(thing->x) - gl_viewx; + tr_y = FIXED_TO_FLOAT(thing->y) - gl_viewy; + + // rotation around vertical axis + tz = (tr_x * gl_viewcos) + (tr_y * gl_viewsin); + + // thing is behind view plane? + if (tz < ZCLIP_PLANE) + return; + + tr_x += gl_viewx; + tr_y += gl_viewy; + + rad = FIXED_TO_FLOAT(thing->radius); + + vis = HWR_NewVisSprite(); + vis->x1 = tr_x - rad; + vis->x2 = tr_x + rad; + vis->z1 = tr_y - rad; + vis->z2 = tr_y + rad; + vis->gz = FIXED_TO_FLOAT(thing->z); + vis->gzt = vis->gz + FIXED_TO_FLOAT(thing->height); + vis->mobj = thing; + + vis->precip = false; + vis->bbox = true; +} + // ========================================================================== // Sky dome rendering, ported from PrBoom+ // ========================================================================== diff --git a/src/r_bbox.c b/src/r_bbox.c index e1749225c..9108ec0c0 100644 --- a/src/r_bbox.c +++ b/src/r_bbox.c @@ -169,12 +169,11 @@ draw_bbox_row } } -static UINT8 -get_bbox_color (vissprite_t *vis) +UINT8 R_GetBoundingBoxColor(mobj_t *thing) { - UINT32 flags = vis->mobjflags; + UINT32 flags = thing->flags; - if (vis->mobj->player) + if (thing->player) return 255; // 0FF if (flags & (MF_NOCLIPTHING)) @@ -205,7 +204,7 @@ void R_DrawThingBoundingBox(vissprite_t *vis) struct bbox_config bb = { .height = vis->thingheight, .tz = vis->texturemid, - .color = get_bbox_color(vis), + .color = R_GetBoundingBoxColor(vis->mobj), }; // 1--3 diff --git a/src/r_things.h b/src/r_things.h index f1855dfd8..9aa1003da 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -66,6 +66,7 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel); void R_InitSprites(void); void R_ClearSprites(void); +UINT8 R_GetBoundingBoxColor(mobj_t *thing); boolean R_ThingBoundingBoxVisible(mobj_t *thing); boolean R_ThingVisible (mobj_t *thing); From 7855bae8a13f4787ecc6badb11fbf2c96e582515 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 11 Sep 2022 16:59:25 -0700 Subject: [PATCH 063/586] Remove R_ThingVisibleWithinDist It's no longer used! --- src/r_things.c | 11 ----------- src/r_things.h | 4 ---- 2 files changed, 15 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 6e4062219..953f12ea6 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -3325,17 +3325,6 @@ boolean R_ThingWithinDist (mobj_t *thing, return true; } -// For OpenGL, TODO: REMOVE!! -boolean R_ThingVisibleWithinDist (mobj_t *thing, - fixed_t limit_dist, - fixed_t hoop_limit_dist) -{ - if (! R_ThingVisible(thing)) - return false; - - return R_ThingWithinDist(thing, limit_dist, hoop_limit_dist); -} - /* Check if precipitation may be drawn from our current view. */ boolean R_PrecipThingVisible (precipmobj_t *precipthing, fixed_t limit_dist) diff --git a/src/r_things.h b/src/r_things.h index 9aa1003da..84d5967ab 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -75,10 +75,6 @@ boolean R_ThingWithinDist (mobj_t *thing, fixed_t draw_dist, fixed_t nights_draw_dist); -boolean R_ThingVisibleWithinDist (mobj_t *thing, - fixed_t draw_dist, - fixed_t nights_draw_dist); - boolean R_PrecipThingVisible (precipmobj_t *precipthing, fixed_t precip_draw_dist); From f7fa9fcc190f0ba4fb8ad3ef15465f6c37ea9443 Mon Sep 17 00:00:00 2001 From: toaster Date: Mon, 12 Sep 2022 12:58:39 +0100 Subject: [PATCH 064/586] Fix compilation issue with nested defines for r_opengl.c UnSetShader --- src/hardware/r_opengl/r_opengl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 3a97f9315..98929f030 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -1032,7 +1032,7 @@ EXPORT void HWRAPI(SetShader) (int type) #ifdef GL_SHADERS if (type == SHADER_NONE) { - HWRAPI(UnSetShader)(); + UnSetShader(); return; } From 8430dfa0639c06b0d48b34a76e1abe14af4885ce Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 25 Oct 2022 12:03:18 -0700 Subject: [PATCH 065/586] Fix copyright year in r_bbox.c --- src/r_bbox.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_bbox.c b/src/r_bbox.c index 9108ec0c0..cc225eaec 100644 --- a/src/r_bbox.c +++ b/src/r_bbox.c @@ -2,8 +2,8 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2021 by Sonic Team Junior. // Copyright (C) 2022 by Kart Krew. +// Copyright (C) 1999-2022 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. From 5411d522e5143caed15d23693bba175f0b1d19f3 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 26 Oct 2022 13:53:35 -0700 Subject: [PATCH 066/586] r_bbox.c: use size_t to access column array --- src/r_bbox.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/r_bbox.c b/src/r_bbox.c index cc225eaec..b45007bb2 100644 --- a/src/r_bbox.c +++ b/src/r_bbox.c @@ -76,7 +76,7 @@ raster_bbox_seg static void draw_bbox_col ( struct bbox_config * bb, - int p, + size_t p, fixed_t tx, fixed_t ty) { @@ -104,8 +104,8 @@ draw_bbox_col static void draw_bbox_row ( struct bbox_config * bb, - int p1, - int p2) + size_t p1, + size_t p2) { struct bbox_col *a = &bb->col[p1], From 34cc1d1cc4a8c27c86b71ee7c94d0c1fc177f187 Mon Sep 17 00:00:00 2001 From: Ace Lite Date: Wed, 23 Nov 2022 17:09:54 +0000 Subject: [PATCH 067/586] Exposed floor/ceiling pic x/y offsets to Lua. --- src/lua_maplib.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/src/lua_maplib.c b/src/lua_maplib.c index b4565121d..4b90bc013 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -33,7 +33,13 @@ enum sector_e { sector_floorheight, sector_ceilingheight, sector_floorpic, + sector_floorxoffs, + sector_flooryoffs, + sector_floorpicangle, sector_ceilingpic, + sector_ceilingxoffs, + sector_ceilingyoffs, + sector_ceilingpicangle, sector_lightlevel, sector_floorlightlevel, sector_floorlightabsolute, @@ -63,7 +69,13 @@ static const char *const sector_opt[] = { "floorheight", "ceilingheight", "floorpic", + "floorxoffs", + "flooryoffs", + "floorpicangle", "ceilingpic", + "ceilingxoffs", + "ceilingyoffs", + "ceilingpicangle", "lightlevel", "floorlightlevel", "floorlightabsolute", @@ -607,6 +619,21 @@ static int sector_get(lua_State *L) lua_pushlstring(L, levelflat->name, i); return 1; } + case sector_floorxoffs: + { + lua_pushfixed(L, sector->floor_xoffs); + return 1; + } + case sector_flooryoffs: + { + lua_pushfixed(L, sector->floor_yoffs); + return 1; + } + case sector_floorpicangle: + { + lua_pushangle(L, sector->floorpic_angle); + return 1; + } case sector_ceilingpic: // ceilingpic { levelflat_t *levelflat = &levelflats[sector->ceilingpic]; @@ -616,6 +643,21 @@ static int sector_get(lua_State *L) lua_pushlstring(L, levelflat->name, i); return 1; } + case sector_ceilingxoffs: + { + lua_pushfixed(L, sector->ceiling_xoffs); + return 1; + } + case sector_ceilingyoffs: + { + lua_pushfixed(L, sector->ceiling_yoffs); + return 1; + } + case sector_ceilingpicangle: + { + lua_pushangle(L, sector->ceilingpic_angle); + return 1; + } case sector_lightlevel: lua_pushinteger(L, sector->lightlevel); return 1; @@ -751,9 +793,27 @@ static int sector_set(lua_State *L) case sector_floorpic: sector->floorpic = P_AddLevelFlatRuntime(luaL_checkstring(L, 3)); break; + case sector_floorxoffs: + sector->floor_xoffs = luaL_checkfixed(L, 3); + break; + case sector_flooryoffs: + sector->floor_yoffs = luaL_checkfixed(L, 3); + break; + case sector_floorpicangle: + sector->floorpic_angle = luaL_checkangle(L, 3); + break; case sector_ceilingpic: sector->ceilingpic = P_AddLevelFlatRuntime(luaL_checkstring(L, 3)); break; + case sector_ceilingxoffs: + sector->ceiling_xoffs = luaL_checkfixed(L, 3); + break; + case sector_ceilingyoffs: + sector->ceiling_yoffs = luaL_checkfixed(L, 3); + break; + case sector_ceilingpicangle: + sector->ceilingpic_angle = luaL_checkangle(L, 3); + break; case sector_lightlevel: sector->lightlevel = (INT16)luaL_checkinteger(L, 3); break; From e789bf1fb241148d6dbd54c2e0efc7059b032b44 Mon Sep 17 00:00:00 2001 From: Ace Lite Date: Wed, 23 Nov 2022 17:29:44 +0000 Subject: [PATCH 068/586] Fix for consistency just *angle for *_angle --- src/lua_maplib.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 4b90bc013..ff732af29 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -35,11 +35,11 @@ enum sector_e { sector_floorpic, sector_floorxoffs, sector_flooryoffs, - sector_floorpicangle, + sector_floorpic_angle, sector_ceilingpic, sector_ceilingxoffs, sector_ceilingyoffs, - sector_ceilingpicangle, + sector_ceilingpic_angle, sector_lightlevel, sector_floorlightlevel, sector_floorlightabsolute, @@ -71,11 +71,11 @@ static const char *const sector_opt[] = { "floorpic", "floorxoffs", "flooryoffs", - "floorpicangle", + "floorpic_angle", "ceilingpic", "ceilingxoffs", "ceilingyoffs", - "ceilingpicangle", + "ceilingpic_angle", "lightlevel", "floorlightlevel", "floorlightabsolute", @@ -629,7 +629,7 @@ static int sector_get(lua_State *L) lua_pushfixed(L, sector->floor_yoffs); return 1; } - case sector_floorpicangle: + case sector_floorpic_angle: { lua_pushangle(L, sector->floorpic_angle); return 1; @@ -653,7 +653,7 @@ static int sector_get(lua_State *L) lua_pushfixed(L, sector->ceiling_yoffs); return 1; } - case sector_ceilingpicangle: + case sector_ceilingpic_angle: { lua_pushangle(L, sector->ceilingpic_angle); return 1; @@ -799,7 +799,7 @@ static int sector_set(lua_State *L) case sector_flooryoffs: sector->floor_yoffs = luaL_checkfixed(L, 3); break; - case sector_floorpicangle: + case sector_floorpic_angle: sector->floorpic_angle = luaL_checkangle(L, 3); break; case sector_ceilingpic: @@ -811,7 +811,7 @@ static int sector_set(lua_State *L) case sector_ceilingyoffs: sector->ceiling_yoffs = luaL_checkfixed(L, 3); break; - case sector_ceilingpicangle: + case sector_ceilingpic_angle: sector->ceilingpic_angle = luaL_checkangle(L, 3); break; case sector_lightlevel: From 27c6afb80b2a67ec1197dca5d9a96e9fec6de512 Mon Sep 17 00:00:00 2001 From: Ace Lite Date: Thu, 24 Nov 2022 18:51:53 +0000 Subject: [PATCH 069/586] Yikes. how did I miss "_" on every single variable --- src/lua_maplib.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/lua_maplib.c b/src/lua_maplib.c index ff732af29..0def825e1 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -33,12 +33,12 @@ enum sector_e { sector_floorheight, sector_ceilingheight, sector_floorpic, - sector_floorxoffs, - sector_flooryoffs, + sector_floor_xoffs, + sector_floor_yoffs, sector_floorpic_angle, sector_ceilingpic, - sector_ceilingxoffs, - sector_ceilingyoffs, + sector_ceiling_xoffs, + sector_ceiling_yoffs, sector_ceilingpic_angle, sector_lightlevel, sector_floorlightlevel, @@ -69,12 +69,12 @@ static const char *const sector_opt[] = { "floorheight", "ceilingheight", "floorpic", - "floorxoffs", - "flooryoffs", + "floor_xoffs", + "floor_yoffs", "floorpic_angle", "ceilingpic", - "ceilingxoffs", - "ceilingyoffs", + "ceiling_xoffs", + "ceiling_yoffs", "ceilingpic_angle", "lightlevel", "floorlightlevel", @@ -619,12 +619,12 @@ static int sector_get(lua_State *L) lua_pushlstring(L, levelflat->name, i); return 1; } - case sector_floorxoffs: + case sector_floor_xoffs: { lua_pushfixed(L, sector->floor_xoffs); return 1; } - case sector_flooryoffs: + case sector_floor_yoffs: { lua_pushfixed(L, sector->floor_yoffs); return 1; @@ -643,12 +643,12 @@ static int sector_get(lua_State *L) lua_pushlstring(L, levelflat->name, i); return 1; } - case sector_ceilingxoffs: + case sector_ceiling_xoffs: { lua_pushfixed(L, sector->ceiling_xoffs); return 1; } - case sector_ceilingyoffs: + case sector_ceiling_yoffs: { lua_pushfixed(L, sector->ceiling_yoffs); return 1; @@ -793,10 +793,10 @@ static int sector_set(lua_State *L) case sector_floorpic: sector->floorpic = P_AddLevelFlatRuntime(luaL_checkstring(L, 3)); break; - case sector_floorxoffs: + case sector_floor_xoffs: sector->floor_xoffs = luaL_checkfixed(L, 3); break; - case sector_flooryoffs: + case sector_floor_yoffs: sector->floor_yoffs = luaL_checkfixed(L, 3); break; case sector_floorpic_angle: @@ -805,10 +805,10 @@ static int sector_set(lua_State *L) case sector_ceilingpic: sector->ceilingpic = P_AddLevelFlatRuntime(luaL_checkstring(L, 3)); break; - case sector_ceilingxoffs: + case sector_ceiling_xoffs: sector->ceiling_xoffs = luaL_checkfixed(L, 3); break; - case sector_ceilingyoffs: + case sector_ceiling_yoffs: sector->ceiling_yoffs = luaL_checkfixed(L, 3); break; case sector_ceilingpic_angle: From 9d4a3b91c3c33d8e8945d90a61584336c41e461f Mon Sep 17 00:00:00 2001 From: Ace Lite Date: Fri, 25 Nov 2022 22:27:41 +0000 Subject: [PATCH 070/586] change names of Lua variables for last time. --- src/lua_maplib.c | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 0def825e1..7908a1d72 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -33,13 +33,13 @@ enum sector_e { sector_floorheight, sector_ceilingheight, sector_floorpic, - sector_floor_xoffs, - sector_floor_yoffs, - sector_floorpic_angle, + sector_floorxoffset, + sector_flooryoffset, + sector_floorangle, sector_ceilingpic, - sector_ceiling_xoffs, - sector_ceiling_yoffs, - sector_ceilingpic_angle, + sector_ceilingxoffset, + sector_ceilingyoffset, + sector_ceilingangle, sector_lightlevel, sector_floorlightlevel, sector_floorlightabsolute, @@ -69,13 +69,13 @@ static const char *const sector_opt[] = { "floorheight", "ceilingheight", "floorpic", - "floor_xoffs", - "floor_yoffs", - "floorpic_angle", + "floorxoffset", + "flooryoffset", + "floorangle", "ceilingpic", - "ceiling_xoffs", - "ceiling_yoffs", - "ceilingpic_angle", + "ceilingxoffset", + "ceilingyoffset", + "ceilingangle", "lightlevel", "floorlightlevel", "floorlightabsolute", @@ -619,17 +619,17 @@ static int sector_get(lua_State *L) lua_pushlstring(L, levelflat->name, i); return 1; } - case sector_floor_xoffs: + case sector_floorxoffset: { lua_pushfixed(L, sector->floor_xoffs); return 1; } - case sector_floor_yoffs: + case sector_flooryoffset: { lua_pushfixed(L, sector->floor_yoffs); return 1; } - case sector_floorpic_angle: + case sector_floorangle: { lua_pushangle(L, sector->floorpic_angle); return 1; @@ -643,17 +643,17 @@ static int sector_get(lua_State *L) lua_pushlstring(L, levelflat->name, i); return 1; } - case sector_ceiling_xoffs: + case sector_ceilingxoffset: { lua_pushfixed(L, sector->ceiling_xoffs); return 1; } - case sector_ceiling_yoffs: + case sector_ceilingyoffset: { lua_pushfixed(L, sector->ceiling_yoffs); return 1; } - case sector_ceilingpic_angle: + case sector_ceilingangle: { lua_pushangle(L, sector->ceilingpic_angle); return 1; @@ -793,25 +793,25 @@ static int sector_set(lua_State *L) case sector_floorpic: sector->floorpic = P_AddLevelFlatRuntime(luaL_checkstring(L, 3)); break; - case sector_floor_xoffs: + case sector_floorxoffset: sector->floor_xoffs = luaL_checkfixed(L, 3); break; - case sector_floor_yoffs: + case sector_flooryoffset: sector->floor_yoffs = luaL_checkfixed(L, 3); break; - case sector_floorpic_angle: + case sector_floorangle: sector->floorpic_angle = luaL_checkangle(L, 3); break; case sector_ceilingpic: sector->ceilingpic = P_AddLevelFlatRuntime(luaL_checkstring(L, 3)); break; - case sector_ceiling_xoffs: + case sector_ceilingxoffset: sector->ceiling_xoffs = luaL_checkfixed(L, 3); break; - case sector_ceiling_yoffs: + case sector_ceilingyoffset: sector->ceiling_yoffs = luaL_checkfixed(L, 3); break; - case sector_ceilingpic_angle: + case sector_ceilingangle: sector->ceilingpic_angle = luaL_checkangle(L, 3); break; case sector_lightlevel: From 3217984f55720b30a5f43df32cacdb6f89466ccf Mon Sep 17 00:00:00 2001 From: Ace Lite Date: Fri, 25 Nov 2022 23:01:27 +0000 Subject: [PATCH 071/586] c-side offset/angle variable renamed --- src/hardware/hw_main.c | 32 ++++++------- src/lua_maplib.c | 24 +++++----- src/p_saveg.c | 36 +++++++------- src/p_setup.c | 106 ++++++++++++++++++++--------------------- src/p_spec.c | 32 ++++++------- src/r_bsp.c | 58 +++++++++++----------- src/r_defs.h | 8 ++-- src/r_fps.c | 16 +++---- src/r_segs.c | 12 ++--- 9 files changed, 162 insertions(+), 162 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 3cb7275a0..2b376544a 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -459,30 +459,30 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool { if (!isceiling) // it's a floor { - scrollx = FIXED_TO_FLOAT(FOFsector->floor_xoffs)/fflatwidth; - scrolly = FIXED_TO_FLOAT(FOFsector->floor_yoffs)/fflatheight; - angle = FOFsector->floorpic_angle; + scrollx = FIXED_TO_FLOAT(FOFsector->floorxoffset)/fflatwidth; + scrolly = FIXED_TO_FLOAT(FOFsector->flooryoffset)/fflatheight; + angle = FOFsector->floorangle; } else // it's a ceiling { scrollx = FIXED_TO_FLOAT(FOFsector->ceiling_xoffs)/fflatwidth; scrolly = FIXED_TO_FLOAT(FOFsector->ceiling_yoffs)/fflatheight; - angle = FOFsector->ceilingpic_angle; + angle = FOFsector->ceilingangle; } } else if (gl_frontsector) { if (!isceiling) // it's a floor { - scrollx = FIXED_TO_FLOAT(gl_frontsector->floor_xoffs)/fflatwidth; - scrolly = FIXED_TO_FLOAT(gl_frontsector->floor_yoffs)/fflatheight; - angle = gl_frontsector->floorpic_angle; + scrollx = FIXED_TO_FLOAT(gl_frontsector->floorxoffset)/fflatwidth; + scrolly = FIXED_TO_FLOAT(gl_frontsector->flooryoffset)/fflatheight; + angle = gl_frontsector->floorangle; } else // it's a ceiling { scrollx = FIXED_TO_FLOAT(gl_frontsector->ceiling_xoffs)/fflatwidth; scrolly = FIXED_TO_FLOAT(gl_frontsector->ceiling_yoffs)/fflatheight; - angle = gl_frontsector->ceilingpic_angle; + angle = gl_frontsector->ceilingangle; } } @@ -2719,30 +2719,30 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, { if (!isceiling) // it's a floor { - scrollx = FIXED_TO_FLOAT(FOFsector->floor_xoffs)/fflatwidth; - scrolly = FIXED_TO_FLOAT(FOFsector->floor_yoffs)/fflatheight; - angle = FOFsector->floorpic_angle; + scrollx = FIXED_TO_FLOAT(FOFsector->floorxoffset)/fflatwidth; + scrolly = FIXED_TO_FLOAT(FOFsector->flooryoffset)/fflatheight; + angle = FOFsector->floorangle; } else // it's a ceiling { scrollx = FIXED_TO_FLOAT(FOFsector->ceiling_xoffs)/fflatwidth; scrolly = FIXED_TO_FLOAT(FOFsector->ceiling_yoffs)/fflatheight; - angle = FOFsector->ceilingpic_angle; + angle = FOFsector->ceilingangle; } } else if (gl_frontsector) { if (!isceiling) // it's a floor { - scrollx = FIXED_TO_FLOAT(gl_frontsector->floor_xoffs)/fflatwidth; - scrolly = FIXED_TO_FLOAT(gl_frontsector->floor_yoffs)/fflatheight; - angle = gl_frontsector->floorpic_angle; + scrollx = FIXED_TO_FLOAT(gl_frontsector->floorxoffset)/fflatwidth; + scrolly = FIXED_TO_FLOAT(gl_frontsector->flooryoffset)/fflatheight; + angle = gl_frontsector->floorangle; } else // it's a ceiling { scrollx = FIXED_TO_FLOAT(gl_frontsector->ceiling_xoffs)/fflatwidth; scrolly = FIXED_TO_FLOAT(gl_frontsector->ceiling_yoffs)/fflatheight; - angle = gl_frontsector->ceilingpic_angle; + angle = gl_frontsector->ceilingangle; } } diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 7908a1d72..79909a6be 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -621,17 +621,17 @@ static int sector_get(lua_State *L) } case sector_floorxoffset: { - lua_pushfixed(L, sector->floor_xoffs); + lua_pushfixed(L, sector->floorxoffset); return 1; } case sector_flooryoffset: { - lua_pushfixed(L, sector->floor_yoffs); + lua_pushfixed(L, sector->flooryoffset); return 1; } case sector_floorangle: { - lua_pushangle(L, sector->floorpic_angle); + lua_pushangle(L, sector->floorangle); return 1; } case sector_ceilingpic: // ceilingpic @@ -645,17 +645,17 @@ static int sector_get(lua_State *L) } case sector_ceilingxoffset: { - lua_pushfixed(L, sector->ceiling_xoffs); + lua_pushfixed(L, sector->ceilingxoffset); return 1; } case sector_ceilingyoffset: { - lua_pushfixed(L, sector->ceiling_yoffs); + lua_pushfixed(L, sector->ceilingyoffset); return 1; } case sector_ceilingangle: { - lua_pushangle(L, sector->ceilingpic_angle); + lua_pushangle(L, sector->ceilingangle); return 1; } case sector_lightlevel: @@ -794,25 +794,25 @@ static int sector_set(lua_State *L) sector->floorpic = P_AddLevelFlatRuntime(luaL_checkstring(L, 3)); break; case sector_floorxoffset: - sector->floor_xoffs = luaL_checkfixed(L, 3); + sector->floorxoffset = luaL_checkfixed(L, 3); break; case sector_flooryoffset: - sector->floor_yoffs = luaL_checkfixed(L, 3); + sector->flooryoffset = luaL_checkfixed(L, 3); break; case sector_floorangle: - sector->floorpic_angle = luaL_checkangle(L, 3); + sector->floorangle = luaL_checkangle(L, 3); break; case sector_ceilingpic: sector->ceilingpic = P_AddLevelFlatRuntime(luaL_checkstring(L, 3)); break; case sector_ceilingxoffset: - sector->ceiling_xoffs = luaL_checkfixed(L, 3); + sector->ceilingxoffset = luaL_checkfixed(L, 3); break; case sector_ceilingyoffset: - sector->ceiling_yoffs = luaL_checkfixed(L, 3); + sector->ceilingyoffset = luaL_checkfixed(L, 3); break; case sector_ceilingangle: - sector->ceilingpic_angle = luaL_checkangle(L, 3); + sector->ceilingangle = luaL_checkangle(L, 3); break; case sector_lightlevel: sector->lightlevel = (INT16)luaL_checkinteger(L, 3); diff --git a/src/p_saveg.c b/src/p_saveg.c index ce7353b95..464372d68 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1022,17 +1022,17 @@ static void ArchiveSectors(void) if (ss->special != spawnss->special) diff |= SD_SPECIAL; - if (ss->floor_xoffs != spawnss->floor_xoffs) + if (ss->floorxoffset != spawnss->floorxoffset) diff2 |= SD_FXOFFS; - if (ss->floor_yoffs != spawnss->floor_yoffs) + if (ss->flooryoffset != spawnss->flooryoffset) diff2 |= SD_FYOFFS; - if (ss->ceiling_xoffs != spawnss->ceiling_xoffs) + if (ss->ceilingxoffset != spawnss->ceilingxoffset) diff2 |= SD_CXOFFS; - if (ss->ceiling_yoffs != spawnss->ceiling_yoffs) + if (ss->ceilingyoffset != spawnss->ceilingyoffset) diff2 |= SD_CYOFFS; - if (ss->floorpic_angle != spawnss->floorpic_angle) + if (ss->floorangle != spawnss->floorangle) diff2 |= SD_FLOORANG; - if (ss->ceilingpic_angle != spawnss->ceilingpic_angle) + if (ss->ceilingangle != spawnss->ceilingangle) diff2 |= SD_CEILANG; if (!Tag_Compare(&ss->tags, &spawnss->tags)) @@ -1095,17 +1095,17 @@ static void ArchiveSectors(void) if (diff & SD_SPECIAL) WRITEINT16(save_p, ss->special); if (diff2 & SD_FXOFFS) - WRITEFIXED(save_p, ss->floor_xoffs); + WRITEFIXED(save_p, ss->floorxoffset); if (diff2 & SD_FYOFFS) - WRITEFIXED(save_p, ss->floor_yoffs); + WRITEFIXED(save_p, ss->flooryoffset); if (diff2 & SD_CXOFFS) - WRITEFIXED(save_p, ss->ceiling_xoffs); + WRITEFIXED(save_p, ss->ceilingxoffset); if (diff2 & SD_CYOFFS) - WRITEFIXED(save_p, ss->ceiling_yoffs); + WRITEFIXED(save_p, ss->ceilingyoffset); if (diff2 & SD_FLOORANG) - WRITEANGLE(save_p, ss->floorpic_angle); + WRITEANGLE(save_p, ss->floorangle); if (diff2 & SD_CEILANG) - WRITEANGLE(save_p, ss->ceilingpic_angle); + WRITEANGLE(save_p, ss->ceilingangle); if (diff2 & SD_TAG) { WRITEUINT32(save_p, ss->tags.count); @@ -1196,17 +1196,17 @@ static void UnArchiveSectors(void) sectors[i].special = READINT16(save_p); if (diff2 & SD_FXOFFS) - sectors[i].floor_xoffs = READFIXED(save_p); + sectors[i].floorxoffset = READFIXED(save_p); if (diff2 & SD_FYOFFS) - sectors[i].floor_yoffs = READFIXED(save_p); + sectors[i].flooryoffset = READFIXED(save_p); if (diff2 & SD_CXOFFS) - sectors[i].ceiling_xoffs = READFIXED(save_p); + sectors[i].ceilingxoffset = READFIXED(save_p); if (diff2 & SD_CYOFFS) - sectors[i].ceiling_yoffs = READFIXED(save_p); + sectors[i].ceilingyoffset = READFIXED(save_p); if (diff2 & SD_FLOORANG) - sectors[i].floorpic_angle = READANGLE(save_p); + sectors[i].floorangle = READANGLE(save_p); if (diff2 & SD_CEILANG) - sectors[i].ceilingpic_angle = READANGLE(save_p); + sectors[i].ceilingangle = READANGLE(save_p); if (diff2 & SD_TAG) { size_t ncount = READUINT32(save_p); diff --git a/src/p_setup.c b/src/p_setup.c index deb308da2..20790a48b 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1049,10 +1049,10 @@ static void P_LoadSectors(UINT8 *data) ss->special = SHORT(ms->special); Tag_FSet(&ss->tags, SHORT(ms->tag)); - ss->floor_xoffs = ss->floor_yoffs = 0; - ss->ceiling_xoffs = ss->ceiling_yoffs = 0; + ss->floorxoffset = ss->flooryoffset = 0; + ss->ceilingxoffset = ss->ceilingyoffset = 0; - ss->floorpic_angle = ss->ceilingpic_angle = 0; + ss->floorangle = ss->ceilingangle = 0; ss->floorlightlevel = ss->ceilinglightlevel = 0; ss->floorlightabsolute = ss->ceilinglightabsolute = false; @@ -1578,19 +1578,19 @@ static void ParseTextmapSectorParameter(UINT32 i, const char *param, const char if ((id = strchr(id, ' '))) id++; } - } + } else if (fastcmp(param, "xpanningfloor")) - sectors[i].floor_xoffs = FLOAT_TO_FIXED(atof(val)); + sectors[i].floorxoffset = FLOAT_TO_FIXED(atof(val)); else if (fastcmp(param, "ypanningfloor")) - sectors[i].floor_yoffs = FLOAT_TO_FIXED(atof(val)); + sectors[i].flooryoffset = FLOAT_TO_FIXED(atof(val)); else if (fastcmp(param, "xpanningceiling")) - sectors[i].ceiling_xoffs = FLOAT_TO_FIXED(atof(val)); + sectors[i].ceilingxoffset = FLOAT_TO_FIXED(atof(val)); else if (fastcmp(param, "ypanningceiling")) - sectors[i].ceiling_yoffs = FLOAT_TO_FIXED(atof(val)); + sectors[i].ceilingyoffset = FLOAT_TO_FIXED(atof(val)); else if (fastcmp(param, "rotationfloor")) - sectors[i].floorpic_angle = FixedAngle(FLOAT_TO_FIXED(atof(val))); + sectors[i].floorangle = FixedAngle(FLOAT_TO_FIXED(atof(val))); else if (fastcmp(param, "rotationceiling")) - sectors[i].ceilingpic_angle = FixedAngle(FLOAT_TO_FIXED(atof(val))); + sectors[i].ceilingangle = FixedAngle(FLOAT_TO_FIXED(atof(val))); else if (fastcmp(param, "floorplane_a")) { textmap_planefloor.defined |= PD_A; @@ -1959,47 +1959,47 @@ static void TextmapParse(UINT32 dataPos, size_t num, void (*parser)(UINT32, cons */ static void TextmapFixFlatOffsets(sector_t *sec) { - if (sec->floorpic_angle) + if (sec->floorangle) { - fixed_t pc = FINECOSINE(sec->floorpic_angle>>ANGLETOFINESHIFT); - fixed_t ps = FINESINE (sec->floorpic_angle>>ANGLETOFINESHIFT); - fixed_t xoffs = sec->floor_xoffs; - fixed_t yoffs = sec->floor_yoffs; - sec->floor_xoffs = (FixedMul(xoffs, pc) % MAXFLATSIZE) - (FixedMul(yoffs, ps) % MAXFLATSIZE); - sec->floor_yoffs = (FixedMul(xoffs, ps) % MAXFLATSIZE) + (FixedMul(yoffs, pc) % MAXFLATSIZE); + fixed_t pc = FINECOSINE(sec->floorangle>>ANGLETOFINESHIFT); + fixed_t ps = FINESINE (sec->floorangle>>ANGLETOFINESHIFT); + fixed_t xoffs = sec->floorxoffset; + fixed_t yoffs = sec->flooryoffset; + sec->floorxoffset = (FixedMul(xoffs, pc) % MAXFLATSIZE) - (FixedMul(yoffs, ps) % MAXFLATSIZE); + sec->flooryoffset = (FixedMul(xoffs, ps) % MAXFLATSIZE) + (FixedMul(yoffs, pc) % MAXFLATSIZE); } - if (sec->ceilingpic_angle) + if (sec->ceilingangle) { - fixed_t pc = FINECOSINE(sec->ceilingpic_angle>>ANGLETOFINESHIFT); - fixed_t ps = FINESINE (sec->ceilingpic_angle>>ANGLETOFINESHIFT); - fixed_t xoffs = sec->ceiling_xoffs; - fixed_t yoffs = sec->ceiling_yoffs; - sec->ceiling_xoffs = (FixedMul(xoffs, pc) % MAXFLATSIZE) - (FixedMul(yoffs, ps) % MAXFLATSIZE); - sec->ceiling_yoffs = (FixedMul(xoffs, ps) % MAXFLATSIZE) + (FixedMul(yoffs, pc) % MAXFLATSIZE); + fixed_t pc = FINECOSINE(sec->ceilingangle>>ANGLETOFINESHIFT); + fixed_t ps = FINESINE (sec->ceilingangle>>ANGLETOFINESHIFT); + fixed_t xoffs = sec->ceilingxoffset; + fixed_t yoffs = sec->ceilingyoffset; + sec->ceilingxoffset = (FixedMul(xoffs, pc) % MAXFLATSIZE) - (FixedMul(yoffs, ps) % MAXFLATSIZE); + sec->ceilingyoffset = (FixedMul(xoffs, ps) % MAXFLATSIZE) + (FixedMul(yoffs, pc) % MAXFLATSIZE); } } static void TextmapUnfixFlatOffsets(sector_t *sec) { - if (sec->floorpic_angle) + if (sec->floorangle) { - fixed_t pc = FINECOSINE(sec->floorpic_angle >> ANGLETOFINESHIFT); - fixed_t ps = FINESINE(sec->floorpic_angle >> ANGLETOFINESHIFT); - fixed_t xoffs = sec->floor_xoffs; - fixed_t yoffs = sec->floor_yoffs; - sec->floor_xoffs = (FixedMul(xoffs, ps) % MAXFLATSIZE) + (FixedMul(yoffs, pc) % MAXFLATSIZE); - sec->floor_yoffs = (FixedMul(xoffs, pc) % MAXFLATSIZE) - (FixedMul(yoffs, ps) % MAXFLATSIZE); + fixed_t pc = FINECOSINE(sec->floorangle >> ANGLETOFINESHIFT); + fixed_t ps = FINESINE(sec->floorangle >> ANGLETOFINESHIFT); + fixed_t xoffs = sec->floorxoffset; + fixed_t yoffs = sec->flooryoffset; + sec->floorxoffset = (FixedMul(xoffs, ps) % MAXFLATSIZE) + (FixedMul(yoffs, pc) % MAXFLATSIZE); + sec->flooryoffset = (FixedMul(xoffs, pc) % MAXFLATSIZE) - (FixedMul(yoffs, ps) % MAXFLATSIZE); } - if (sec->ceilingpic_angle) + if (sec->ceilingangle) { - fixed_t pc = FINECOSINE(sec->ceilingpic_angle >> ANGLETOFINESHIFT); - fixed_t ps = FINESINE(sec->ceilingpic_angle >> ANGLETOFINESHIFT); - fixed_t xoffs = sec->ceiling_xoffs; - fixed_t yoffs = sec->ceiling_yoffs; - sec->ceiling_xoffs = (FixedMul(xoffs, ps) % MAXFLATSIZE) + (FixedMul(yoffs, pc) % MAXFLATSIZE); - sec->ceiling_yoffs = (FixedMul(xoffs, pc) % MAXFLATSIZE) - (FixedMul(yoffs, ps) % MAXFLATSIZE); + fixed_t pc = FINECOSINE(sec->ceilingangle >> ANGLETOFINESHIFT); + fixed_t ps = FINESINE(sec->ceilingangle >> ANGLETOFINESHIFT); + fixed_t xoffs = sec->ceilingxoffset; + fixed_t yoffs = sec->ceilingyoffset; + sec->ceilingxoffset = (FixedMul(xoffs, ps) % MAXFLATSIZE) + (FixedMul(yoffs, pc) % MAXFLATSIZE); + sec->ceilingyoffset = (FixedMul(xoffs, pc) % MAXFLATSIZE) - (FixedMul(yoffs, ps) % MAXFLATSIZE); } } @@ -2492,18 +2492,18 @@ static void P_WriteTextmap(void) } sector_t tempsec = wsectors[i]; TextmapUnfixFlatOffsets(&tempsec); - if (tempsec.floor_xoffs != 0) - fprintf(f, "xpanningfloor = %f;\n", FIXED_TO_FLOAT(tempsec.floor_xoffs)); - if (tempsec.floor_yoffs != 0) - fprintf(f, "ypanningfloor = %f;\n", FIXED_TO_FLOAT(tempsec.floor_yoffs)); - if (tempsec.ceiling_xoffs != 0) - fprintf(f, "xpanningceiling = %f;\n", FIXED_TO_FLOAT(tempsec.ceiling_xoffs)); - if (tempsec.ceiling_yoffs != 0) - fprintf(f, "ypanningceiling = %f;\n", FIXED_TO_FLOAT(tempsec.ceiling_yoffs)); - if (wsectors[i].floorpic_angle != 0) - fprintf(f, "rotationfloor = %f;\n", FIXED_TO_FLOAT(AngleFixed(wsectors[i].floorpic_angle))); - if (wsectors[i].ceilingpic_angle != 0) - fprintf(f, "rotationceiling = %f;\n", FIXED_TO_FLOAT(AngleFixed(wsectors[i].ceilingpic_angle))); + if (tempsec.floorxoffset != 0) + fprintf(f, "xpanningfloor = %f;\n", FIXED_TO_FLOAT(tempsec.floorxoffset)); + if (tempsec.flooryoffset != 0) + fprintf(f, "ypanningfloor = %f;\n", FIXED_TO_FLOAT(tempsec.flooryoffset)); + if (tempsec.ceilingxoffset != 0) + fprintf(f, "xpanningceiling = %f;\n", FIXED_TO_FLOAT(tempsec.ceilingxoffset)); + if (tempsec.ceilingyoffset != 0) + fprintf(f, "ypanningceiling = %f;\n", FIXED_TO_FLOAT(tempsec.ceilingyoffset)); + if (wsectors[i].floorangle != 0) + fprintf(f, "rotationfloor = %f;\n", FIXED_TO_FLOAT(AngleFixed(wsectors[i].floorangle))); + if (wsectors[i].ceilingangle != 0) + fprintf(f, "rotationceiling = %f;\n", FIXED_TO_FLOAT(AngleFixed(wsectors[i].ceilingangle))); if (wsectors[i].extra_colormap) { INT32 lightcolor = P_RGBAToColor(wsectors[i].extra_colormap->rgba); @@ -2708,10 +2708,10 @@ static void P_LoadTextmap(void) sc->special = 0; Tag_FSet(&sc->tags, 0); - sc->floor_xoffs = sc->floor_yoffs = 0; - sc->ceiling_xoffs = sc->ceiling_yoffs = 0; + sc->floorxoffset = sc->flooryoffset = 0; + sc->ceilingxoffset = sc->ceilingyoffset = 0; - sc->floorpic_angle = sc->ceilingpic_angle = 0; + sc->floorangle = sc->ceilingangle = 0; sc->floorlightlevel = sc->ceilinglightlevel = 0; sc->floorlightabsolute = sc->ceilinglightabsolute = false; diff --git a/src/p_spec.c b/src/p_spec.c index 82337d2f6..d781ea7d7 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -5570,17 +5570,17 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, I fflr->target = sec; fflr->bottomheight = &sec2->floorheight; fflr->bottompic = &sec2->floorpic; - fflr->bottomxoffs = &sec2->floor_xoffs; - fflr->bottomyoffs = &sec2->floor_yoffs; - fflr->bottomangle = &sec2->floorpic_angle; + fflr->bottomxoffs = &sec2->floorxoffset; + fflr->bottomyoffs = &sec2->flooryoffset; + fflr->bottomangle = &sec2->floorangle; // Add the ceiling fflr->topheight = &sec2->ceilingheight; fflr->toppic = &sec2->ceilingpic; fflr->toplightlevel = &sec2->lightlevel; - fflr->topxoffs = &sec2->ceiling_xoffs; - fflr->topyoffs = &sec2->ceiling_yoffs; - fflr->topangle = &sec2->ceilingpic_angle; + fflr->topxoffs = &sec2->ceilingxoffset; + fflr->topyoffs = &sec2->ceilingyoffset; + fflr->topangle = &sec2->ceilingangle; // Add slopes fflr->t_slope = &sec2->c_slope; @@ -6098,16 +6098,16 @@ void P_ApplyFlatAlignment(sector_t *sector, angle_t flatangle, fixed_t xoffs, fi { if (floor) { - sector->floorpic_angle = flatangle; - sector->floor_xoffs += xoffs; - sector->floor_yoffs += yoffs; + sector->floorangle = flatangle; + sector->floorxoffset += xoffs; + sector->flooryoffset += yoffs; } if (ceiling) { - sector->ceilingpic_angle = flatangle; - sector->ceiling_xoffs += xoffs; - sector->ceiling_yoffs += yoffs; + sector->ceilingangle = flatangle; + sector->ceilingxoffset += xoffs; + sector->ceilingyoffset += yoffs; } } @@ -7349,14 +7349,14 @@ void T_Scroll(scroll_t *s) case sc_floor: // scroll floor texture sec = sectors + s->affectee; - sec->floor_xoffs += dx; - sec->floor_yoffs += dy; + sec->floorxoffset += dx; + sec->flooryoffset += dy; break; case sc_ceiling: // scroll ceiling texture sec = sectors + s->affectee; - sec->ceiling_xoffs += dx; - sec->ceiling_yoffs += dy; + sec->ceilingxoffset += dx; + sec->ceilingyoffset += dy; break; case sc_carry: diff --git a/src/r_bsp.c b/src/r_bsp.c index bf238a435..129c6ba00 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -275,9 +275,9 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel, tempsec->ceilingheight = s->floorheight - 1, !back)) || viewz <= s->floorheight) { // head-below-floor hack tempsec->floorpic = s->floorpic; - tempsec->floor_xoffs = s->floor_xoffs; - tempsec->floor_yoffs = s->floor_yoffs; - tempsec->floorpic_angle = s->floorpic_angle; + tempsec->floorxoffset = s->floorxoffset; + tempsec->flooryoffset = s->flooryoffset; + tempsec->floorangle = s->floorangle; if (underwater) { @@ -285,16 +285,16 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel, { tempsec->floorheight = tempsec->ceilingheight+1; tempsec->ceilingpic = tempsec->floorpic; - tempsec->ceiling_xoffs = tempsec->floor_xoffs; - tempsec->ceiling_yoffs = tempsec->floor_yoffs; - tempsec->ceilingpic_angle = tempsec->floorpic_angle; + tempsec->ceilingxoffset = tempsec->floorxoffset; + tempsec->ceilingyoffset = tempsec->flooryoffset; + tempsec->ceilingangle = tempsec->floorangle; } else { tempsec->ceilingpic = s->ceilingpic; - tempsec->ceiling_xoffs = s->ceiling_xoffs; - tempsec->ceiling_yoffs = s->ceiling_yoffs; - tempsec->ceilingpic_angle = s->ceilingpic_angle; + tempsec->ceilingxoffset = s->ceilingxoffset; + tempsec->ceilingyoffset = s->ceilingyoffset; + tempsec->ceilingangle = s->ceilingangle; } } @@ -315,25 +315,25 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel, tempsec->floorheight = s->ceilingheight + 1; tempsec->floorpic = tempsec->ceilingpic = s->ceilingpic; - tempsec->floor_xoffs = tempsec->ceiling_xoffs = s->ceiling_xoffs; - tempsec->floor_yoffs = tempsec->ceiling_yoffs = s->ceiling_yoffs; - tempsec->floorpic_angle = tempsec->ceilingpic_angle = s->ceilingpic_angle; + tempsec->floorxoffset = tempsec->ceilingxoffset = s->ceilingxoffset; + tempsec->flooryoffset = tempsec->ceilingyoffset = s->ceilingyoffset; + tempsec->floorangle = tempsec->ceilingangle = s->ceilingangle; if (s->floorpic == skyflatnum) // SKYFIX? { tempsec->ceilingheight = tempsec->floorheight-1; tempsec->floorpic = tempsec->ceilingpic; - tempsec->floor_xoffs = tempsec->ceiling_xoffs; - tempsec->floor_yoffs = tempsec->ceiling_yoffs; - tempsec->floorpic_angle = tempsec->ceilingpic_angle; + tempsec->floorxoffset = tempsec->ceilingxoffset; + tempsec->flooryoffset = tempsec->ceilingyoffset; + tempsec->floorangle = tempsec->ceilingangle; } else { tempsec->ceilingheight = sec->ceilingheight; tempsec->floorpic = s->floorpic; - tempsec->floor_xoffs = s->floor_xoffs; - tempsec->floor_yoffs = s->floor_yoffs; - tempsec->floorpic_angle = s->floorpic_angle; + tempsec->floorxoffset = s->floorxoffset; + tempsec->flooryoffset = s->flooryoffset; + tempsec->floorangle = s->floorangle; } tempsec->lightlevel = s->lightlevel; @@ -363,12 +363,12 @@ boolean R_IsEmptyLine(seg_t *line, sector_t *front, sector_t *back) && back->lightlevel == front->lightlevel && !line->sidedef->midtexture // Check offsets too! - && back->floor_xoffs == front->floor_xoffs - && back->floor_yoffs == front->floor_yoffs - && back->floorpic_angle == front->floorpic_angle - && back->ceiling_xoffs == front->ceiling_xoffs - && back->ceiling_yoffs == front->ceiling_yoffs - && back->ceilingpic_angle == front->ceilingpic_angle + && back->floorxoffset == front->floorxoffset + && back->flooryoffset == front->flooryoffset + && back->floorangle == front->floorangle + && back->ceilingxoffset == front->ceilingxoffset + && back->ceilingyoffset == front->ceilingyoffset + && back->ceilingangle == front->ceilingangle // Consider altered lighting. && back->floorlightlevel == front->floorlightlevel && back->floorlightabsolute == front->floorlightabsolute @@ -909,7 +909,7 @@ static void R_Subsector(size_t num) || (frontsector->heightsec != -1 && sectors[frontsector->heightsec].ceilingpic == skyflatnum)) { floorplane = R_FindPlane(frontsector->floorheight, frontsector->floorpic, floorlightlevel, - frontsector->floor_xoffs, frontsector->floor_yoffs, frontsector->floorpic_angle, floorcolormap, NULL, NULL, frontsector->f_slope); + frontsector->floorxoffset, frontsector->flooryoffset, frontsector->floorangle, floorcolormap, NULL, NULL, frontsector->f_slope); } else floorplane = NULL; @@ -919,7 +919,7 @@ static void R_Subsector(size_t num) || (frontsector->heightsec != -1 && sectors[frontsector->heightsec].floorpic == skyflatnum)) { ceilingplane = R_FindPlane(frontsector->ceilingheight, frontsector->ceilingpic, - ceilinglightlevel, frontsector->ceiling_xoffs, frontsector->ceiling_yoffs, frontsector->ceilingpic_angle, + ceilinglightlevel, frontsector->ceilingxoffset, frontsector->ceilingyoffset, frontsector->ceilingangle, ceilingcolormap, NULL, NULL, frontsector->c_slope); } else @@ -1033,8 +1033,8 @@ static void R_Subsector(size_t num) { light = R_GetPlaneLight(frontsector, polysec->floorheight, viewz < polysec->floorheight); ffloor[numffloors].plane = R_FindPlane(polysec->floorheight, polysec->floorpic, - (light == -1 ? frontsector->lightlevel : *frontsector->lightlist[light].lightlevel), polysec->floor_xoffs, polysec->floor_yoffs, - polysec->floorpic_angle-po->angle, + (light == -1 ? frontsector->lightlevel : *frontsector->lightlist[light].lightlevel), polysec->floorxoffset, polysec->flooryoffset, + polysec->floorangle-po->angle, (light == -1 ? frontsector->extra_colormap : *frontsector->lightlist[light].extra_colormap), NULL, po, NULL); // will ffloors be slopable eventually? @@ -1057,7 +1057,7 @@ static void R_Subsector(size_t num) { light = R_GetPlaneLight(frontsector, polysec->floorheight, viewz < polysec->floorheight); ffloor[numffloors].plane = R_FindPlane(polysec->ceilingheight, polysec->ceilingpic, - (light == -1 ? frontsector->lightlevel : *frontsector->lightlist[light].lightlevel), polysec->ceiling_xoffs, polysec->ceiling_yoffs, polysec->ceilingpic_angle-po->angle, + (light == -1 ? frontsector->lightlevel : *frontsector->lightlist[light].lightlevel), polysec->ceilingxoffset, polysec->ceilingyoffset, polysec->ceilingangle-po->angle, (light == -1 ? frontsector->extra_colormap : *frontsector->lightlist[light].extra_colormap), NULL, po, NULL); // will ffloors be slopable eventually? diff --git a/src/r_defs.h b/src/r_defs.h index dbede806e..7da162de7 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -423,12 +423,12 @@ typedef struct sector_s void *fadecolormapdata; // fade colormap thinker // floor and ceiling texture offsets - fixed_t floor_xoffs, floor_yoffs; - fixed_t ceiling_xoffs, ceiling_yoffs; + fixed_t floorxoffset, flooryoffset; + fixed_t ceilingxoffset, ceilingyoffset; // flat angle - angle_t floorpic_angle; - angle_t ceilingpic_angle; + angle_t floorangle; + angle_t ceilingangle; INT32 heightsec; // other sector, or -1 if no other sector INT32 camsec; // used for camera clipping diff --git a/src/r_fps.c b/src/r_fps.c index 2d30c9f01..3d7d3f7ae 100644 --- a/src/r_fps.c +++ b/src/r_fps.c @@ -426,8 +426,8 @@ void R_CreateInterpolator_SectorScroll(thinker_t *thinker, sector_t *sector, boo } else { - interp->sectorscroll.oldxoffs = interp->sectorscroll.bakxoffs = sector->floor_xoffs; - interp->sectorscroll.oldyoffs = interp->sectorscroll.bakyoffs = sector->floor_yoffs; + interp->sectorscroll.oldxoffs = interp->sectorscroll.bakxoffs = sector->floorxoffset; + interp->sectorscroll.oldyoffs = interp->sectorscroll.bakyoffs = sector->flooryoffset; } } @@ -490,9 +490,9 @@ static void UpdateLevelInterpolatorState(levelinterpolator_t *interp) break; case LVLINTERP_SectorScroll: interp->sectorscroll.oldxoffs = interp->sectorscroll.bakxoffs; - interp->sectorscroll.bakxoffs = interp->sectorscroll.ceiling ? interp->sectorscroll.sector->ceiling_xoffs : interp->sectorscroll.sector->floor_xoffs; + interp->sectorscroll.bakxoffs = interp->sectorscroll.ceiling ? interp->sectorscroll.sector->ceiling_xoffs : interp->sectorscroll.sector->floorxoffset; interp->sectorscroll.oldyoffs = interp->sectorscroll.bakyoffs; - interp->sectorscroll.bakyoffs = interp->sectorscroll.ceiling ? interp->sectorscroll.sector->ceiling_yoffs : interp->sectorscroll.sector->floor_yoffs; + interp->sectorscroll.bakyoffs = interp->sectorscroll.ceiling ? interp->sectorscroll.sector->ceiling_yoffs : interp->sectorscroll.sector->flooryoffset; break; case LVLINTERP_SideScroll: interp->sidescroll.oldtextureoffset = interp->sidescroll.baktextureoffset; @@ -583,8 +583,8 @@ void R_ApplyLevelInterpolators(fixed_t frac) } else { - interp->sectorscroll.sector->floor_xoffs = R_LerpFixed(interp->sectorscroll.oldxoffs, interp->sectorscroll.bakxoffs, frac); - interp->sectorscroll.sector->floor_yoffs = R_LerpFixed(interp->sectorscroll.oldyoffs, interp->sectorscroll.bakyoffs, frac); + interp->sectorscroll.sector->floorxoffset = R_LerpFixed(interp->sectorscroll.oldxoffs, interp->sectorscroll.bakxoffs, frac); + interp->sectorscroll.sector->flooryoffset = R_LerpFixed(interp->sectorscroll.oldyoffs, interp->sectorscroll.bakyoffs, frac); } break; case LVLINTERP_SideScroll: @@ -638,8 +638,8 @@ void R_RestoreLevelInterpolators(void) } else { - interp->sectorscroll.sector->floor_xoffs = interp->sectorscroll.bakxoffs; - interp->sectorscroll.sector->floor_yoffs = interp->sectorscroll.bakyoffs; + interp->sectorscroll.sector->floorxoffset = interp->sectorscroll.bakxoffs; + interp->sectorscroll.sector->flooryoffset = interp->sectorscroll.bakyoffs; } break; case LVLINTERP_SideScroll: diff --git a/src/r_segs.c b/src/r_segs.c index 43a7f945f..681524054 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -1906,9 +1906,9 @@ void R_StoreWallRange(INT32 start, INT32 stop) || backsector->floorpic != frontsector->floorpic || backsector->lightlevel != frontsector->lightlevel //SoM: 3/22/2000: Check floor x and y offsets. - || backsector->floor_xoffs != frontsector->floor_xoffs - || backsector->floor_yoffs != frontsector->floor_yoffs - || backsector->floorpic_angle != frontsector->floorpic_angle + || backsector->floorxoffset != frontsector->floorxoffset + || backsector->flooryoffset != frontsector->flooryoffset + || backsector->floorangle != frontsector->floorangle //SoM: 3/22/2000: Prevents bleeding. || (frontsector->heightsec != -1 && frontsector->floorpic != skyflatnum) || backsector->floorlightlevel != frontsector->floorlightlevel @@ -1939,9 +1939,9 @@ void R_StoreWallRange(INT32 start, INT32 stop) || backsector->ceilingpic != frontsector->ceilingpic || backsector->lightlevel != frontsector->lightlevel //SoM: 3/22/2000: Check floor x and y offsets. - || backsector->ceiling_xoffs != frontsector->ceiling_xoffs - || backsector->ceiling_yoffs != frontsector->ceiling_yoffs - || backsector->ceilingpic_angle != frontsector->ceilingpic_angle + || backsector->ceilingxoffset != frontsector->ceilingxoffset + || backsector->ceilingyoffset != frontsector->ceilingyoffset + || backsector->ceilingangle != frontsector->ceilingangle //SoM: 3/22/2000: Prevents bleeding. || (frontsector->heightsec != -1 && frontsector->ceilingpic != skyflatnum) || backsector->ceilinglightlevel != frontsector->ceilinglightlevel From c5daa248d16f803cf16b0836980cadf973e758e9 Mon Sep 17 00:00:00 2001 From: Ace Lite Date: Fri, 25 Nov 2022 23:06:07 +0000 Subject: [PATCH 072/586] r_fps.c ceiling_y/xoffs renamed --- src/r_fps.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/r_fps.c b/src/r_fps.c index 3d7d3f7ae..661da8ba2 100644 --- a/src/r_fps.c +++ b/src/r_fps.c @@ -421,8 +421,8 @@ void R_CreateInterpolator_SectorScroll(thinker_t *thinker, sector_t *sector, boo interp->sectorscroll.ceiling = ceiling; if (ceiling) { - interp->sectorscroll.oldxoffs = interp->sectorscroll.bakxoffs = sector->ceiling_xoffs; - interp->sectorscroll.oldyoffs = interp->sectorscroll.bakyoffs = sector->ceiling_yoffs; + interp->sectorscroll.oldxoffs = interp->sectorscroll.bakxoffs = sector->ceilingxoffset; + interp->sectorscroll.oldyoffs = interp->sectorscroll.bakyoffs = sector->ceilingyoffset; } else { @@ -490,9 +490,9 @@ static void UpdateLevelInterpolatorState(levelinterpolator_t *interp) break; case LVLINTERP_SectorScroll: interp->sectorscroll.oldxoffs = interp->sectorscroll.bakxoffs; - interp->sectorscroll.bakxoffs = interp->sectorscroll.ceiling ? interp->sectorscroll.sector->ceiling_xoffs : interp->sectorscroll.sector->floorxoffset; + interp->sectorscroll.bakxoffs = interp->sectorscroll.ceiling ? interp->sectorscroll.sector->ceilingxoffset : interp->sectorscroll.sector->floorxoffset; interp->sectorscroll.oldyoffs = interp->sectorscroll.bakyoffs; - interp->sectorscroll.bakyoffs = interp->sectorscroll.ceiling ? interp->sectorscroll.sector->ceiling_yoffs : interp->sectorscroll.sector->flooryoffset; + interp->sectorscroll.bakyoffs = interp->sectorscroll.ceiling ? interp->sectorscroll.sector->ceilingyoffset : interp->sectorscroll.sector->flooryoffset; break; case LVLINTERP_SideScroll: interp->sidescroll.oldtextureoffset = interp->sidescroll.baktextureoffset; @@ -578,8 +578,8 @@ void R_ApplyLevelInterpolators(fixed_t frac) case LVLINTERP_SectorScroll: if (interp->sectorscroll.ceiling) { - interp->sectorscroll.sector->ceiling_xoffs = R_LerpFixed(interp->sectorscroll.oldxoffs, interp->sectorscroll.bakxoffs, frac); - interp->sectorscroll.sector->ceiling_yoffs = R_LerpFixed(interp->sectorscroll.oldyoffs, interp->sectorscroll.bakyoffs, frac); + interp->sectorscroll.sector->ceilingxoffset = R_LerpFixed(interp->sectorscroll.oldxoffs, interp->sectorscroll.bakxoffs, frac); + interp->sectorscroll.sector->ceilingyoffset = R_LerpFixed(interp->sectorscroll.oldyoffs, interp->sectorscroll.bakyoffs, frac); } else { @@ -633,8 +633,8 @@ void R_RestoreLevelInterpolators(void) case LVLINTERP_SectorScroll: if (interp->sectorscroll.ceiling) { - interp->sectorscroll.sector->ceiling_xoffs = interp->sectorscroll.bakxoffs; - interp->sectorscroll.sector->ceiling_yoffs = interp->sectorscroll.bakyoffs; + interp->sectorscroll.sector->ceilingxoffset = interp->sectorscroll.bakxoffs; + interp->sectorscroll.sector->ceilingyoffset = interp->sectorscroll.bakyoffs; } else { From 656f7f94acf7390a17aff9b4a4fd92771ea5953b Mon Sep 17 00:00:00 2001 From: Ace Lite Date: Fri, 25 Nov 2022 23:06:22 +0000 Subject: [PATCH 073/586] hw_main.c ceiling_y/xoffs renamed --- src/hardware/hw_main.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 2b376544a..c1043f8bb 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -465,8 +465,8 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool } else // it's a ceiling { - scrollx = FIXED_TO_FLOAT(FOFsector->ceiling_xoffs)/fflatwidth; - scrolly = FIXED_TO_FLOAT(FOFsector->ceiling_yoffs)/fflatheight; + scrollx = FIXED_TO_FLOAT(FOFsector->ceilingxoffset)/fflatwidth; + scrolly = FIXED_TO_FLOAT(FOFsector->ceilingyoffset)/fflatheight; angle = FOFsector->ceilingangle; } } @@ -480,8 +480,8 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool } else // it's a ceiling { - scrollx = FIXED_TO_FLOAT(gl_frontsector->ceiling_xoffs)/fflatwidth; - scrolly = FIXED_TO_FLOAT(gl_frontsector->ceiling_yoffs)/fflatheight; + scrollx = FIXED_TO_FLOAT(gl_frontsector->ceilingxoffset)/fflatwidth; + scrolly = FIXED_TO_FLOAT(gl_frontsector->ceilingyoffset)/fflatheight; angle = gl_frontsector->ceilingangle; } } @@ -2725,8 +2725,8 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, } else // it's a ceiling { - scrollx = FIXED_TO_FLOAT(FOFsector->ceiling_xoffs)/fflatwidth; - scrolly = FIXED_TO_FLOAT(FOFsector->ceiling_yoffs)/fflatheight; + scrollx = FIXED_TO_FLOAT(FOFsector->ceilingxoffset)/fflatwidth; + scrolly = FIXED_TO_FLOAT(FOFsector->ceilingyoffset)/fflatheight; angle = FOFsector->ceilingangle; } } @@ -2740,8 +2740,8 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, } else // it's a ceiling { - scrollx = FIXED_TO_FLOAT(gl_frontsector->ceiling_xoffs)/fflatwidth; - scrolly = FIXED_TO_FLOAT(gl_frontsector->ceiling_yoffs)/fflatheight; + scrollx = FIXED_TO_FLOAT(gl_frontsector->ceilingxoffset)/fflatwidth; + scrolly = FIXED_TO_FLOAT(gl_frontsector->ceilingyoffset)/fflatheight; angle = gl_frontsector->ceilingangle; } } From da9786b593040200fe56f6771e58ed6a16a01ed2 Mon Sep 17 00:00:00 2001 From: Ace Lite Date: Fri, 25 Nov 2022 23:16:11 +0000 Subject: [PATCH 074/586] exposed floorlightsec, ceilinglightsec variables. --- src/lua_maplib.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 79909a6be..d3a00782b 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -43,8 +43,10 @@ enum sector_e { sector_lightlevel, sector_floorlightlevel, sector_floorlightabsolute, + sector_floorlightsec, sector_ceilinglightlevel, sector_ceilinglightabsolute, + sector_ceilinglightsec, sector_special, sector_tag, sector_taglist, @@ -79,8 +81,10 @@ static const char *const sector_opt[] = { "lightlevel", "floorlightlevel", "floorlightabsolute", + "floorlightsec", "ceilinglightlevel", "ceilinglightabsolute", + "ceilinglightsec", "special", "tag", "taglist", @@ -667,12 +671,18 @@ static int sector_get(lua_State *L) case sector_floorlightabsolute: lua_pushboolean(L, sector->floorlightabsolute); return 1; + case sector_floorlightsec: + lua_pushinteger(L, sector->floorlightsec); + return 1; case sector_ceilinglightlevel: lua_pushinteger(L, sector->ceilinglightlevel); return 1; case sector_ceilinglightabsolute: lua_pushboolean(L, sector->ceilinglightabsolute); return 1; + case sector_ceilinglightsec: + lua_pushinteger(L, sector->ceilinglightsec); + return 1; case sector_special: lua_pushinteger(L, sector->special); return 1; @@ -801,7 +811,7 @@ static int sector_set(lua_State *L) break; case sector_floorangle: sector->floorangle = luaL_checkangle(L, 3); - break; + break; case sector_ceilingpic: sector->ceilingpic = P_AddLevelFlatRuntime(luaL_checkstring(L, 3)); break; @@ -823,12 +833,18 @@ static int sector_set(lua_State *L) case sector_floorlightabsolute: sector->floorlightabsolute = luaL_checkboolean(L, 3); break; + case sector_floorlightsec: + sector->floorlightsec = (INT32)luaL_checkinteger(L, 3); + break; case sector_ceilinglightlevel: sector->ceilinglightlevel = (INT16)luaL_checkinteger(L, 3); break; case sector_ceilinglightabsolute: sector->ceilinglightabsolute = luaL_checkboolean(L, 3); break; + case sector_ceilinglightsec: + sector->ceilinglightsec = (INT32)luaL_checkinteger(L, 3); + break; case sector_special: sector->special = (INT16)luaL_checkinteger(L, 3); break; From 5cb13f9d1c1a28575cd5fad4160407269e552d8c Mon Sep 17 00:00:00 2001 From: Eidolon Date: Thu, 17 Nov 2022 18:39:39 -0600 Subject: [PATCH 075/586] Bump SRB2VERSION and MODVERSION for 2.2.11 pre1 --- src/version.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/version.h b/src/version.h index 7a12fbbbe..5e4c85be4 100644 --- a/src/version.h +++ b/src/version.h @@ -1,4 +1,4 @@ -#define SRB2VERSION "2.2.10"/* this must be the first line, for cmake !! */ +#define SRB2VERSION "2.2.11"/* this must be the first line, for cmake !! */ // 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. @@ -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 51 +#define MODVERSION 52 // Define this as a prerelease version suffix (pre#, RC#) -// #define BETAVERSION "pre1" +#define BETAVERSION "pre1" From df131ef131c5146b8f9a99af182849a2ed19f2e4 Mon Sep 17 00:00:00 2001 From: Eidolon Date: Tue, 6 Dec 2022 18:43:59 -0600 Subject: [PATCH 076/586] Bump SRB2VERSION and MODVERSION for 2.2.11 pre2 --- src/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h b/src/version.h index 5e4c85be4..5314314bf 100644 --- a/src/version.h +++ b/src/version.h @@ -12,4 +12,4 @@ #define MODVERSION 52 // Define this as a prerelease version suffix (pre#, RC#) -#define BETAVERSION "pre1" +#define BETAVERSION "pre2" From 9e191d0748df60eb7d11ef7beaaba038e1da6180 Mon Sep 17 00:00:00 2001 From: Eidolon Date: Thu, 8 Dec 2022 21:27:24 -0600 Subject: [PATCH 077/586] Bump SRB2VERSION and MODVERSION for 2.2.11 pre3 --- src/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h b/src/version.h index 5314314bf..f8b09ada6 100644 --- a/src/version.h +++ b/src/version.h @@ -12,4 +12,4 @@ #define MODVERSION 52 // Define this as a prerelease version suffix (pre#, RC#) -#define BETAVERSION "pre2" +#define BETAVERSION "pre3" From 30df486dacb53132d0045b0190a22a4468ca14ef Mon Sep 17 00:00:00 2001 From: Eidolon Date: Sat, 10 Dec 2022 15:32:06 -0600 Subject: [PATCH 078/586] Update zones.pk3 hash for pre3 (oops) --- 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 928705b30..22cfd6481 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -29,7 +29,7 @@ * Last updated 2022 / 03 / 06 - v2.2.10 - main assets */ #define ASSET_HASH_SRB2_PK3 "ad911f29a28a18968ee5b2d11c2acb39" -#define ASSET_HASH_ZONES_PK3 "86ae55cae4e0a93ceda868635706a093" +#define ASSET_HASH_ZONES_PK3 "188a2bfd552196609323fc91ec1cdb22" #define ASSET_HASH_PLAYER_DTA "2e7aaae8a6b1b77d90ffe7606ceadb6c" #ifdef USE_PATCH_DTA #define ASSET_HASH_PATCH_PK3 "7d467a883f7887b3c311798ee2f56b6a" From 449d27749f6c245653db7d2846f12ab2dca34a40 Mon Sep 17 00:00:00 2001 From: Arthur Date: Sat, 31 Dec 2022 20:30:39 -0500 Subject: [PATCH 079/586] Fixes Issue #912 --- src/p_user.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/p_user.c b/src/p_user.c index 4ca4e6c8a..0ef787641 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -11266,6 +11266,11 @@ static void P_DoTailsOverlay(player_t *player, mobj_t *tails) tails->y = player->mo->y + P_ReturnThrustY(tails, tails->angle, FixedMul(backwards, tails->scale)); tails->z = player->mo->z + zoffs; P_SetThingPosition(tails); + + if (player->mo->flags2 & MF2_SHADOW) + tails->flags2 |= MF2_SHADOW; + else + tails->flags2 &= ~MF2_SHADOW; } // Metal Sonic's jet fume From e909f8ec12a707e90d83f380e60a8e6c46a2f4e3 Mon Sep 17 00:00:00 2001 From: Arthur Date: Sat, 31 Dec 2022 21:06:39 -0500 Subject: [PATCH 080/586] Fixes Issue #711 --- src/p_map.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/p_map.c b/src/p_map.c index 5c8ccbb19..f738cb97d 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -264,11 +264,13 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) { INT32 pflags = object->player->pflags & (PF_JUMPED|PF_NOJUMPDAMAGE|PF_SPINNING|PF_THOKKED|PF_BOUNCING); // Not identical to below... UINT8 secondjump = object->player->secondjump; + UINT16 tailsfly = object->player->powers[pw_tailsfly]; if (object->player->pflags & PF_GLIDING) P_SetPlayerMobjState(object, S_PLAY_FALL); P_ResetPlayer(object->player); object->player->pflags |= pflags; object->player->secondjump = secondjump; + object->player->powers[pw_tailsfly] = tailsfly; } } From bc519ad132334b1e764884a468de490c007e4a35 Mon Sep 17 00:00:00 2001 From: Arthur Date: Sat, 31 Dec 2022 22:07:22 -0500 Subject: [PATCH 081/586] Fix for issue #933 - special stage tokens should divert player until after the special stage with a custom exit map --- 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 b4a127a73..ab399cfa2 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -4161,7 +4161,7 @@ static void G_DoCompleted(void) { token--; - if (!nextmapoverride) +// if (!nextmapoverride) // Having a token should pull the player into the special stage before going to the overridden map (Issue #933) for (i = 0; i < 7; i++) if (!(emeralds & (1< Date: Sat, 31 Dec 2022 22:46:08 -0500 Subject: [PATCH 082/586] When attaching to a wall to do a climb, the second sidedef wasn't be handled properly. --- src/p_map.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index 5c8ccbb19..232bf3a50 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -3506,11 +3506,9 @@ static void PTR_GlideClimbTraverse(line_t *li) if (fofline) whichside = 0; - if (!whichside) - { - slidemo->player->lastsidehit = checkline->sidenum[whichside]; - slidemo->player->lastlinehit = (INT16)(checkline - lines); - } + // Even if you attach to the second side of a linedef, we want to know the last hit. + slidemo->player->lastsidehit = checkline->sidenum[whichside]; + slidemo->player->lastlinehit = (INT16)(checkline - lines); P_Thrust(slidemo, slidemo->angle, FixedMul(5*FRACUNIT, slidemo->scale)); } From bd89b97e0a770944452da5829c27b78524a58e6b Mon Sep 17 00:00:00 2001 From: Arthur Date: Sun, 1 Jan 2023 20:59:11 -0500 Subject: [PATCH 083/586] Fixes issue #704 --- src/p_map.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/p_map.c b/src/p_map.c index 5c8ccbb19..911d7927c 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -418,7 +418,12 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) P_SetPlayerMobjState(object, S_PLAY_ROLL); } else - pflags = object->player->pflags & (PF_STARTJUMP|PF_JUMPED|PF_NOJUMPDAMAGE|PF_SPINNING|PF_THOKKED|PF_BOUNCING); // I still need these. + { + pflags = object->player->pflags & (PF_STARTJUMP | PF_JUMPED | PF_NOJUMPDAMAGE | PF_SPINNING | PF_THOKKED | PF_BOUNCING); // I still need these. + + if (pflags & PF_SPINNING) // Ensure we're in the rolling state, and not something like spindash. + P_SetPlayerMobjState(object, S_PLAY_ROLL); + } secondjump = object->player->secondjump; washoming = object->player->homing; P_ResetPlayer(object->player); From 7d53e4647b7317cb90708e86b7f8794241a307e1 Mon Sep 17 00:00:00 2001 From: Arthur Date: Sun, 1 Jan 2023 21:07:15 -0500 Subject: [PATCH 084/586] Fixes issue #568 --- src/p_enemy.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/p_enemy.c b/src/p_enemy.c index ece4f3814..3053e1fb8 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -13460,6 +13460,9 @@ static boolean PIT_DustDevilLaunch(mobj_t *thing) if (!player) return true; + if (player->spectator) + return true; + if (player->powers[pw_carry] != CR_DUSTDEVIL && (player->powers[pw_ignorelatch] & (1<<15))) return true; From af146071d87c588e140b3aa52995d1268f0cd928 Mon Sep 17 00:00:00 2001 From: Arthur Date: Mon, 2 Jan 2023 07:34:33 -0500 Subject: [PATCH 085/586] Check for spindash ability and dashspeed being > 0 before indiscriminately setting roll animation. --- src/p_map.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/p_map.c b/src/p_map.c index 911d7927c..cb4309f80 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -419,9 +419,11 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) } else { + boolean wasSpindashing = object->player->dashspeed > 0 && (object->player->charability2 == CA2_SPINDASH); + pflags = object->player->pflags & (PF_STARTJUMP | PF_JUMPED | PF_NOJUMPDAMAGE | PF_SPINNING | PF_THOKKED | PF_BOUNCING); // I still need these. - if (pflags & PF_SPINNING) // Ensure we're in the rolling state, and not something like spindash. + if (wasSpindashing) // Ensure we're in the rolling state, and not spindash. P_SetPlayerMobjState(object, S_PLAY_ROLL); } secondjump = object->player->secondjump; From 28f97dcd0bd716a3f6773030efbc66640a319d6b Mon Sep 17 00:00:00 2001 From: Arthur Date: Mon, 2 Jan 2023 08:07:13 -0500 Subject: [PATCH 086/586] Also fix STJr/SRB2#618 since it is highly related. --- src/p_map.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/p_map.c b/src/p_map.c index cb4309f80..98a5360f6 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -425,6 +425,12 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) if (wasSpindashing) // Ensure we're in the rolling state, and not spindash. P_SetPlayerMobjState(object, S_PLAY_ROLL); + + if (object->player->charability == CA_GLIDEANDCLIMB && object->player->skidtime && (pflags & PF_JUMPED)) + { + object->player->skidtime = 0; // No skidding should be happening, either. + pflags &= ~PF_JUMPED; + } } secondjump = object->player->secondjump; washoming = object->player->homing; From 3a04e1174372fd2b605b99220d127a6cc1291ecc Mon Sep 17 00:00:00 2001 From: katsy Date: Thu, 5 Jan 2023 14:11:54 -0600 Subject: [PATCH 087/586] allow targeting invulnerable bosses --- src/g_game.c | 1 - src/p_user.c | 12 ++---------- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index b4a127a73..cd29a08f8 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1453,7 +1453,6 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) if ( P_MobjWasRemoved(ticcmd_ztargetfocus[forplayer]) || !ticcmd_ztargetfocus[forplayer]->health || - (ticcmd_ztargetfocus[forplayer]->flags2 & MF2_FRET) || (ticcmd_ztargetfocus[forplayer]->type == MT_EGGMOBILE3 && !ticcmd_ztargetfocus[forplayer]->movecount) // Sea Egg is moving around underground and shouldn't be tracked ) P_SetTarget(&ticcmd_ztargetfocus[forplayer], NULL); diff --git a/src/p_user.c b/src/p_user.c index 4ca4e6c8a..0ca49ded0 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9059,10 +9059,6 @@ mobj_t *P_LookForFocusTarget(player_t *player, mobj_t *exclude, SINT8 direction, switch (mo->type) { - case MT_TNTBARREL: - if (lockonflags & LOCK_INTERESTS) - break; - /*FALLTHRU*/ case MT_PLAYER: // Don't chase other players! case MT_DETON: continue; // Don't be STUPID, Sonic! @@ -9083,17 +9079,13 @@ mobj_t *P_LookForFocusTarget(player_t *player, mobj_t *exclude, SINT8 direction, /*FALLTHRU*/ default: - if ((lockonflags & LOCK_BOSS) && ((mo->flags & (MF_BOSS|MF_SHOOTABLE)) == (MF_BOSS|MF_SHOOTABLE))) // allows if it has the flags desired XOR it has the invert aimable flag - { - if (mo->flags2 & MF2_FRET) - continue; + if ((lockonflags & LOCK_BOSS) && (mo->flags & MF_BOSS)) // always allow targeting bosses break; - } if ((lockonflags & LOCK_ENEMY) && (!((mo->flags & (MF_ENEMY|MF_SHOOTABLE)) == (MF_ENEMY|MF_SHOOTABLE)) != !(mo->flags2 & MF2_INVERTAIMABLE))) // allows if it has the flags desired XOR it has the invert aimable flag break; - if ((lockonflags & LOCK_INTERESTS) && (mo->flags & (MF_PUSHABLE|MF_MONITOR))) // allows if it has the flags desired XOR it has the invert aimable flag + if ((lockonflags & LOCK_INTERESTS) && (mo->flags & (MF_PUSHABLE|MF_MONITOR))) // allows if it has the flags desired break; continue; // not a valid object From 20724ad70bc44eee8d8c10c32cfbf88be94ef2f9 Mon Sep 17 00:00:00 2001 From: Arthur Date: Fri, 27 Jan 2023 09:46:02 -0500 Subject: [PATCH 088/586] Also retain PF_CANCARRY --- src/p_map.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_map.c b/src/p_map.c index f738cb97d..54e2003ba 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -262,7 +262,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) } else { - INT32 pflags = object->player->pflags & (PF_JUMPED|PF_NOJUMPDAMAGE|PF_SPINNING|PF_THOKKED|PF_BOUNCING); // Not identical to below... + INT32 pflags = object->player->pflags & (PF_JUMPED|PF_NOJUMPDAMAGE|PF_SPINNING|PF_THOKKED|PF_BOUNCING|PF_CANCARRY); // Not identical to below... UINT8 secondjump = object->player->secondjump; UINT16 tailsfly = object->player->powers[pw_tailsfly]; if (object->player->pflags & PF_GLIDING) From b64dac714f39dadf9f44e474558c81d6420032d0 Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Sat, 28 Jan 2023 00:12:29 -0300 Subject: [PATCH 089/586] Fix -Wnon-literal-null-conversion and -Wconstant-conversion warnings --- src/p_spec.c | 2 +- src/taglist.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index 5c9caa82f..c104ce6c5 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4375,7 +4375,7 @@ sector_t *P_FindPlayerTrigger(player_t *player, line_t *sourceline) return loopsector; } - return false; + return NULL; } boolean P_IsPlayerValid(size_t playernum) diff --git a/src/taglist.c b/src/taglist.c index 305b05f04..405007614 100644 --- a/src/taglist.c +++ b/src/taglist.c @@ -472,5 +472,5 @@ mtag_t Tag_NextUnused(mtag_t start) start++; } - return MAXTAGS; + return (mtag_t)MAXTAGS; } From cc6eac0886317f4dab85743ae20f23c5f03004cc Mon Sep 17 00:00:00 2001 From: Zwip-Zwap Zapony Date: Sat, 4 Feb 2023 17:34:43 +0100 Subject: [PATCH 090/586] Fix con_hudlines being off by one --- src/console.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/console.c b/src/console.c index 40fb43121..0f3105caa 100644 --- a/src/console.c +++ b/src/console.c @@ -72,8 +72,8 @@ static INT32 con_curlines; // vid lines currently used by console INT32 con_clipviewtop; // (useless) -static INT32 con_hudlines; // number of console heads up message lines -static INT32 con_hudtime[MAXHUDLINES]; // remaining time of display for hud msg lines +static UINT8 con_hudlines; // number of console heads up message lines +static INT32 con_hudtime[MAXHUDLINES]; // remaining time of display for hud msg lines INT32 con_clearlines; // top screen lines to refresh when view reduced boolean con_hudupdate; // when messages scroll, we need a backgrnd refresh @@ -128,7 +128,8 @@ static char con_buffer[CON_BUFFERSIZE]; static consvar_t cons_msgtimeout = CVAR_INIT ("con_hudtime", "5", CV_SAVE, CV_Unsigned, NULL); // number of lines displayed on the HUD -static consvar_t cons_hudlines = CVAR_INIT ("con_hudlines", "5", CV_CALL|CV_SAVE, CV_Unsigned, CONS_hudlines_Change); +static CV_PossibleValue_t hudlines_cons_t[] = {{1, "MIN"}, {MAXHUDLINES, "MAX"}, {0, "None"}, {0, NULL}}; +static consvar_t cons_hudlines = CVAR_INIT ("con_hudlines", "5", CV_CALL|CV_SAVE, hudlines_cons_t, CONS_hudlines_Change); // number of lines console move per frame // (con_speed needs a limit, apparently) @@ -168,11 +169,6 @@ static void CONS_hudlines_Change(void) for (i = 0; i < con_hudlines; i++) con_hudtime[i] = 0; - if (cons_hudlines.value < 1) - cons_hudlines.value = 1; - else if (cons_hudlines.value > MAXHUDLINES) - cons_hudlines.value = MAXHUDLINES; - con_hudlines = cons_hudlines.value; Unlock_state(); @@ -1328,7 +1324,8 @@ boolean CON_Responder(event_t *ev) static void CON_Linefeed(void) { // set time for heads up messages - con_hudtime[con_cy%con_hudlines] = cons_msgtimeout.value*TICRATE; + if (con_hudlines) + con_hudtime[con_cy%con_hudlines] = cons_msgtimeout.value*TICRATE; con_cy++; con_cx = 0; @@ -1684,7 +1681,7 @@ static void CON_DrawHudlines(void) INT32 charwidth = 8 * con_scalefactor; INT32 charheight = 8 * con_scalefactor; - if (con_hudlines <= 0) + if (!con_hudlines) return; if (chat_on && OLDCHAT) @@ -1692,7 +1689,7 @@ static void CON_DrawHudlines(void) else y = 0; - for (i = con_cy - con_hudlines+1; i <= con_cy; i++) + for (i = con_cy - con_hudlines; i <= con_cy; i++) { size_t c; INT32 x; From 702b2acfd39d8665ce3290eecb2abd84460198aa Mon Sep 17 00:00:00 2001 From: Zwip-Zwap Zapony Date: Sat, 4 Feb 2023 17:35:44 +0100 Subject: [PATCH 091/586] Limit con_hudtime to 24 hours Also rename cons_msgtimeout to cons_hudtime for consistency --- src/console.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/console.c b/src/console.c index 0f3105caa..b99b13720 100644 --- a/src/console.c +++ b/src/console.c @@ -72,8 +72,8 @@ static INT32 con_curlines; // vid lines currently used by console INT32 con_clipviewtop; // (useless) -static UINT8 con_hudlines; // number of console heads up message lines -static INT32 con_hudtime[MAXHUDLINES]; // remaining time of display for hud msg lines +static UINT8 con_hudlines; // number of console heads up message lines +static UINT32 con_hudtime[MAXHUDLINES]; // remaining time of display for hud msg lines INT32 con_clearlines; // top screen lines to refresh when view reduced boolean con_hudupdate; // when messages scroll, we need a backgrnd refresh @@ -125,7 +125,9 @@ static void CONS_backcolor_Change(void); static char con_buffer[CON_BUFFERSIZE]; // how many seconds the hud messages lasts on the screen -static consvar_t cons_msgtimeout = CVAR_INIT ("con_hudtime", "5", CV_SAVE, CV_Unsigned, NULL); +// CV_Unsigned can overflow when multiplied by TICRATE later, so let's use a 24-hour limit instead +static CV_PossibleValue_t hudtime_cons_t[] = {{0, "MIN"}, {86400, "MAX"}, {0, NULL}}; +static consvar_t cons_hudtime = CVAR_INIT ("con_hudtime", "5", CV_SAVE, hudtime_cons_t, NULL); // number of lines displayed on the HUD static CV_PossibleValue_t hudlines_cons_t[] = {{1, "MIN"}, {MAXHUDLINES, "MAX"}, {0, "None"}, {0, NULL}}; @@ -460,7 +462,7 @@ void CON_Init(void) Unlock_state(); - CV_RegisterVar(&cons_msgtimeout); + CV_RegisterVar(&cons_hudtime); CV_RegisterVar(&cons_hudlines); CV_RegisterVar(&cons_speed); CV_RegisterVar(&cons_height); @@ -773,9 +775,8 @@ void CON_Ticker(void) // make overlay messages disappear after a while for (i = 0; i < con_hudlines; i++) { - con_hudtime[i]--; - if (con_hudtime[i] < 0) - con_hudtime[i] = 0; + if (con_hudtime[i]) + con_hudtime[i]--; } Unlock_state(); @@ -1325,7 +1326,7 @@ static void CON_Linefeed(void) { // set time for heads up messages if (con_hudlines) - con_hudtime[con_cy%con_hudlines] = cons_msgtimeout.value*TICRATE; + con_hudtime[con_cy%con_hudlines] = cons_hudtime.value*TICRATE; con_cy++; con_cx = 0; From aba57612d57de590b1b9db8891d1332fb1857460 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 19 Feb 2023 07:27:16 +0100 Subject: [PATCH 092/586] -Only print deprecated map effect warnings once on map load -Add missing unsupported effect warnings to P_WriteTextmap -Apply spikes MSF_TRIGGERSPECIAL_TOUCH hack in UDMF too --- src/p_setup.c | 20 ++++++++++++++++++++ src/p_spec.c | 29 +++++++++-------------------- 2 files changed, 29 insertions(+), 20 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index b0054119b..0330ea1e5 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2270,6 +2270,9 @@ static void P_WriteTextmap(void) case 10: CONS_Alert(CONS_WARNING, M_GetText("Sector %s has ring drainer effect, which is not supported in UDMF. Use linedef type 462 instead.\n"), sizeu1(i)); break; + case 15: + CONS_Alert(CONS_WARNING, M_GetText("Sector %s has bouncy FOF effect, which is not supported in UDMF. Use linedef type 76 instead.\n"), sizeu1(i)); + break; default: break; } @@ -2285,6 +2288,12 @@ static void P_WriteTextmap(void) case 9: CONS_Alert(CONS_WARNING, M_GetText("Sector %s has Egg Capsule type, which is not supported in UDMF. Use linedef type 464 instead.\n"), sizeu1(i)); break; + case 10: + CONS_Alert(CONS_WARNING, M_GetText("Sector %s has special stage time/spheres requirements effect, which is not supported in UDMF. Use the SpecialStageTime and SpecialStageSpheres level header options instead.\n"), sizeu1(i)); + break; + case 11: + CONS_Alert(CONS_WARNING, M_GetText("Sector %s has custom global gravity effect, which is not supported in UDMF. Use the Gravity level header option instead.\n"), sizeu1(i)); + break; default: break; } @@ -6008,6 +6017,9 @@ static void P_ConvertBinarySectorTypes(void) case 14: //Non-ramp sector sectors[i].specialflags |= SSF_NOSTEPDOWN; break; + case 15: //Bouncy FOF + CONS_Alert(CONS_WARNING, M_GetText("Deprecated bouncy FOF sector type detected. Please use linedef type 76 instead.\n")); + break; default: break; } @@ -6040,11 +6052,13 @@ static void P_ConvertBinarySectorTypes(void) sectors[i].triggerer = TO_PLAYER; break; case 6: //Trigger linedef executor (Emerald check) + CONS_Alert(CONS_WARNING, M_GetText("Deprecated emerald check sector type detected. Please use linedef types 337-339 instead.\n")); sectors[i].triggertag = tag; sectors[i].flags &= ~MSF_TRIGGERLINE_PLANE; sectors[i].triggerer = TO_PLAYEREMERALDS; break; case 7: //Trigger linedef executor (NiGHTS mare) + CONS_Alert(CONS_WARNING, M_GetText("Deprecated NiGHTS mare sector type detected. Please use linedef types 340-342 instead.\n")); sectors[i].triggertag = tag; sectors[i].flags &= ~MSF_TRIGGERLINE_PLANE; sectors[i].triggerer = TO_PLAYERNIGHTS; @@ -6052,6 +6066,12 @@ static void P_ConvertBinarySectorTypes(void) case 8: //Check for linedef executor on FOFs sectors[i].flags |= MSF_TRIGGERLINE_MOBJ; break; + case 10: //Special stage time/spheres requirements + CONS_Alert(CONS_WARNING, M_GetText("Deprecated sector type for special stage requirements detected. Please use the SpecialStageTime and SpecialStageSpheres level header options instead.\n")); + break; + case 11: //Custom global gravity + CONS_Alert(CONS_WARNING, M_GetText("Deprecated sector type for global gravity detected. Please use the Gravity level header option instead.\n")); + break; default: break; } diff --git a/src/p_spec.c b/src/p_spec.c index 6a52f19e8..2aec1ae36 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1760,13 +1760,11 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller { if (caller->triggerer == TO_PLAYEREMERALDS) { - CONS_Alert(CONS_WARNING, M_GetText("Deprecated emerald check sector type detected. Please use linedef types 337-339 instead.\n")); if (!(ALL7EMERALDS(emeralds))) return false; } else if (caller->triggerer == TO_PLAYERNIGHTS) { - CONS_Alert(CONS_WARNING, M_GetText("Deprecated NiGHTS mare sector type detected. Please use linedef types 340-342 instead.\n")); if (!P_CheckPlayerMareOld(triggerline)) return false; } @@ -5970,8 +5968,6 @@ static inline void P_AddCameraScanner(sector_t *sourcesec, sector_t *actionsecto { elevator_t *elevator; // Why not? LOL - CONS_Alert(CONS_WARNING, M_GetText("Detected a camera scanner effect (linedef type 5). This effect is deprecated and will be removed in the future!\n")); - // create and initialize new elevator thinker elevator = Z_Calloc(sizeof (*elevator), PU_LEVSPEC, NULL); P_AddThinker(THINK_MAIN, &elevator->thinker); @@ -6226,22 +6222,21 @@ void P_SpawnSpecials(boolean fromnetsave) circuitmap = true; } - if (!sector->special) + if (sector->damagetype == SD_SPIKE) { + //Terrible hack to replace an even worse hack: + //Spike damage automatically sets MSF_TRIGGERSPECIAL_TOUCH. + //Yes, this also affects other specials on the same sector. Sorry. + sector->flags |= MSF_TRIGGERSPECIAL_TOUCH; + } + + // Process deprecated binary sector specials + if (udmf || !sector->special) continue; // Process Section 1 switch(GETSECSPECIAL(sector->special, 1)) { - case 5: // Spikes - //Terrible hack to replace an even worse hack: - //Spike damage automatically sets MSF_TRIGGERSPECIAL_TOUCH. - //Yes, this also affects other specials on the same sector. Sorry. - sector->flags |= MSF_TRIGGERSPECIAL_TOUCH; - break; case 15: // Bouncy FOF - if (udmf) - break; - CONS_Alert(CONS_WARNING, M_GetText("Deprecated bouncy FOF sector type detected. Please use linedef type 76 instead.\n")); CheckForBouncySector = true; break; } @@ -6250,17 +6245,11 @@ void P_SpawnSpecials(boolean fromnetsave) switch(GETSECSPECIAL(sector->special, 2)) { case 10: // Time for special stage - if (udmf) - break; - CONS_Alert(CONS_WARNING, M_GetText("Deprecated sector type for special stage requirements detected. Please use the SpecialStageTime and SpecialStageSpheres level header options instead.\n")); sstimer = (sector->floorheight>>FRACBITS) * TICRATE + 6; // Time to finish ssspheres = sector->ceilingheight>>FRACBITS; // Ring count for special stage break; case 11: // Custom global gravity! - if (udmf) - break; - CONS_Alert(CONS_WARNING, M_GetText("Deprecated sector type for global gravity detected. Please use the Gravity level header option instead.\n")); gravity = sector->floorheight/1000; break; } From 9a9a16183f02b3570faa24c949c4fc68eda9d48f Mon Sep 17 00:00:00 2001 From: Eidolon Date: Fri, 24 Feb 2023 18:48:10 -0600 Subject: [PATCH 093/586] Disable floor splat slope interpolation Getting these to interpolate correctly is proving to be an absolute ordeal and I would rather have them look correct-but-not-interpolated than completely broken. --- src/hardware/hw_main.c | 6 +++--- src/r_splats.c | 15 ++++++++------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 05d1be28f..321ed215f 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -4102,7 +4102,7 @@ static void HWR_DrawSprite(gl_vissprite_t *spr) scale *= spr->shadowscale; if (spr->rotateflags & SRF_3D || renderflags & RF_NOSPLATBILLBOARD) - angle = spr->angle; + angle = spr->mobj->angle; else angle = viewangle; @@ -4157,8 +4157,8 @@ static void HWR_DrawSprite(gl_vissprite_t *spr) // Translate for (i = 0; i < 4; i++) { - wallVerts[i].x = rotated[i].x + spr->x1; - wallVerts[i].z = rotated[i].y + spr->z1; + wallVerts[i].x = rotated[i].x + FIXED_TO_FLOAT(spr->mobj->x); + wallVerts[i].z = rotated[i].y + FIXED_TO_FLOAT(spr->mobj->y); } if (renderflags & (RF_SLOPESPLAT | RF_OBJECTSLOPESPLAT)) diff --git a/src/r_splats.c b/src/r_splats.c index a58cfe536..bab89c89e 100644 --- a/src/r_splats.c +++ b/src/r_splats.c @@ -11,6 +11,7 @@ /// \brief Floor splats #include "r_draw.h" +#include "r_fps.h" #include "r_main.h" #include "r_splats.h" #include "r_bsp.h" @@ -185,7 +186,7 @@ void R_DrawFloorSplat(vissprite_t *spr) splat.scale = FixedMul(splat.scale, ((skin_t *)mobj->skin)->highresscale); if (spr->rotateflags & SRF_3D || renderflags & RF_NOSPLATBILLBOARD) - splatangle = spr->centerangle; + splatangle = mobj->angle; else splatangle = spr->viewpoint.angle; @@ -209,8 +210,8 @@ void R_DrawFloorSplat(vissprite_t *spr) xoffset = FixedMul(leftoffset, splat.xscale); yoffset = FixedMul(topoffset, splat.yscale); - x = spr->gx; - y = spr->gy; + x = mobj->x; + y = mobj->y; w = (splat.width * splat.xscale); h = (splat.height * splat.yscale); @@ -263,8 +264,8 @@ void R_DrawFloorSplat(vissprite_t *spr) // Translate for (i = 0; i < 4; i++) { - tr_x = rotated[i].x + x; - tr_y = rotated[i].y + y; + tr_x = rotated[i].x + mobj->x; + tr_y = rotated[i].y + mobj->y; if (splat.slope) { @@ -292,8 +293,8 @@ void R_DrawFloorSplat(vissprite_t *spr) tr_y = v3d->y - spr->viewpoint.y; // rotation around vertical y axis - rot_x = FixedMul(tr_x, sa) - FixedMul(tr_y, ca); - rot_y = FixedMul(tr_x, ca) + FixedMul(tr_y, sa); + rot_x = FixedMul(tr_x - (mobj->x - x), sa) - FixedMul(tr_y - (mobj->y - y), ca); + rot_y = FixedMul(tr_x - (mobj->x - x), ca) + FixedMul(tr_y - (mobj->y - y), sa); rot_z = v3d->z - spr->viewpoint.z; if (rot_y < FRACUNIT) From d58dad7f982e9486afd6945df2f223ed79abf721 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 25 Feb 2023 11:58:12 +0100 Subject: [PATCH 094/586] Move emblem float option to args[1], since args[0] is already occupied for NiGHTS emblems --- extras/conf/udb/Includes/SRB222_things.cfg | 2 +- src/p_mobj.c | 5 ++++- src/p_setup.c | 4 +++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/extras/conf/udb/Includes/SRB222_things.cfg b/extras/conf/udb/Includes/SRB222_things.cfg index 1de661e29..b4508c91e 100644 --- a/extras/conf/udb/Includes/SRB222_things.cfg +++ b/extras/conf/udb/Includes/SRB222_things.cfg @@ -4546,7 +4546,7 @@ udmf sprite = "EMBMA0"; width = 16; height = 30; - arg0 + arg1 { title = "Float?"; type = 11; diff --git a/src/p_mobj.c b/src/p_mobj.c index 635d4f42b..412ef7ddb 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11849,7 +11849,6 @@ fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mt case MT_EMERHUNT: case MT_EMERALDSPAWN: case MT_TOKEN: - case MT_EMBLEM: case MT_RING: case MT_REDTEAMRING: case MT_BLUETEAMRING: @@ -11861,6 +11860,10 @@ fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mt offset += mthing->args[0] ? 0 : 24*FRACUNIT; break; + case MT_EMBLEM: + offset += mthing->args[1] ? 0 : 24 * FRACUNIT; + break; + // Remaining objects. default: if (P_WeaponOrPanel(mobjtype)) diff --git a/src/p_setup.c b/src/p_setup.c index b0054119b..1c052a148 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -6288,7 +6288,6 @@ static void P_ConvertBinaryThingTypes(void) case 312: //Emerald token case 320: //Emerald hunt location case 321: //Match chaos emerald spawn - case 322: //Emblem case 330: //Bounce ring panel case 331: //Rail ring panel case 332: //Automatic ring panel @@ -6301,6 +6300,9 @@ static void P_ConvertBinaryThingTypes(void) case 1800: //Coin mapthings[i].args[0] = !(mapthings[i].options & MTF_AMBUSH); break; + case 322: //Emblem + mapthings[i].args[1] = !(mapthings[i].options & MTF_AMBUSH); + break; case 409: //Extra life monitor mapthings[i].args[2] = !(mapthings[i].options & (MTF_AMBUSH|MTF_OBJECTSPECIAL)); break; From 283f7e8919ca62ef9d6d6d1d885858f6332aaf48 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 25 Feb 2023 13:24:14 +0100 Subject: [PATCH 095/586] Linedef type 14 UDMF conversion: Don't fill stringargs[0] if toptexture is empty --- src/p_setup.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/p_setup.c b/src/p_setup.c index b0054119b..c9e578922 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -4209,7 +4209,8 @@ static void P_ConvertBinaryLinedefTypes(void) lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; lines[i].args[1] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS; lines[i].args[2] = !!(lines[i].flags & ML_SKEWTD); - P_WriteConstant(sides[lines[i].sidenum[0]].toptexture, &lines[i].stringargs[0]); + if (sides[lines[i].sidenum[0]].toptexture) + P_WriteConstant(sides[lines[i].sidenum[0]].toptexture, &lines[i].stringargs[0]); break; case 16: //Minecart parameters lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; From 6e7ff6972096f37ce618507ec0cdc60d272c5dee Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 25 Feb 2023 15:03:52 +0100 Subject: [PATCH 096/586] Re-add code that sets MF2_AMBUSH if MTF_AMBUSH is set, but only for binary maps --- src/p_mobj.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/p_mobj.c b/src/p_mobj.c index 635d4f42b..f8f4ee2a6 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -13277,6 +13277,23 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean return true; } +// Pre-UDMF backwards compatibility stuff. Remove for 2.3 +static void P_SetAmbush(mapthing_t *mthing, mobj_t *mobj) +{ + if (mobj->type == MT_NIGHTSBUMPER + || mobj->type == MT_AXIS + || mobj->type == MT_AXISTRANSFER + || mobj->type == MT_AXISTRANSFERLINE + || mobj->type == MT_NIGHTSBUMPER + || mobj->type == MT_STARPOST) + return; + + if ((mthing->options & MTF_OBJECTSPECIAL) && (mobj->flags & MF_PUSHABLE)) + return; + + mobj->flags2 |= MF2_AMBUSH; +} + static mobj_t *P_SpawnMobjFromMapThing(mapthing_t *mthing, fixed_t x, fixed_t y, fixed_t z, mobjtype_t i) { mobj_t *mobj = NULL; @@ -13299,6 +13316,9 @@ static mobj_t *P_SpawnMobjFromMapThing(mapthing_t *mthing, fixed_t x, fixed_t y, mthing->mobj = mobj; + if (!udmf && (mthing->options & MTF_AMBUSH)) + P_SetAmbush(mthing, mobj); + // Generic reverse gravity for individual objects flag. if (mthing->options & MTF_OBJECTFLIP) { From bb9e7045c5c3f5f433e7d9fb2be5ce9046f9298f Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 25 Feb 2023 15:43:51 +0100 Subject: [PATCH 097/586] Fix wrong flag being checked in P_ProcessTeamBase --- 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 6a52f19e8..b0840b30c 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4653,7 +4653,7 @@ static void P_ProcessTeamBase(player_t *player, boolean redteam) // Make sure the team still has their own // flag at their base so they can score. - if (!P_IsFlagAtBase(redteam ? MT_BLUEFLAG : MT_REDFLAG)) + if (!P_IsFlagAtBase(redteam ? MT_REDFLAG : MT_BLUEFLAG)) return; HU_SetCEchoFlags(V_AUTOFADEOUT|V_ALLOWLOWERCASE); From a32dc3daa0ce4f3f16674021198f194386212543 Mon Sep 17 00:00:00 2001 From: Eidolon Date: Sun, 26 Feb 2023 17:57:44 -0600 Subject: [PATCH 098/586] Fix software vsync This pre-SDL 2.0.18 hack from the interp branch is no longer needed when building with a new enough SDL version. This makes vid_wait toggleable at all times if SDL is at least 2.0.18. --- src/sdl/i_video.c | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 6e971a5d8..47d41ede5 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -102,8 +102,10 @@ rendermode_t chosenrendermode = render_none; // set by command line arguments boolean highcolor = false; +static void VidWaitChanged(void); + // synchronize page flipping with screen refresh -consvar_t cv_vidwait = CVAR_INIT ("vid_wait", "On", CV_SAVE, CV_OnOff, NULL); +consvar_t cv_vidwait = CVAR_INIT ("vid_wait", "On", CV_SAVE | CV_CALL, CV_OnOff, VidWaitChanged); static consvar_t cv_stretch = CVAR_INIT ("stretch", "Off", CV_SAVE|CV_NOSHOWHELP, CV_OnOff, NULL); static consvar_t cv_alwaysgrabmouse = CVAR_INIT ("alwaysgrabmouse", "Off", CV_SAVE, CV_OnOff, NULL); @@ -274,6 +276,22 @@ static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen, SDL_bool } } +static void VidWaitChanged(void) +{ + if (renderer && rendermode == render_soft) + { +#if SDL_VERSION_ATLEAST(2, 0, 18) + SDL_RenderSetVSync(renderer, cv_vidwait.value ? 1 : 0); +#endif + } +#ifdef HWRENDER + else if (rendermode == render_opengl && sdlglcontext != NULL && SDL_GL_GetCurrentContext() == sdlglcontext) + { + SDL_GL_SetSwapInterval(cv_vidwait.value ? 1 : 0); + } +#endif +} + static INT32 Impl_SDL_Scancode_To_Keycode(SDL_Scancode code) { if (code >= SDL_SCANCODE_A && code <= SDL_SCANCODE_Z) @@ -1476,15 +1494,19 @@ static SDL_bool Impl_CreateContext(void) int flags = 0; // Use this to set SDL_RENDERER_* flags now if (usesdl2soft) flags |= SDL_RENDERER_SOFTWARE; -#if 0 - // This shit is BROKEN. - // - The version of SDL we're using cannot toggle VSync at runtime. We'll need a new SDL version implemented to have this work properly. - // - cv_vidwait is initialized before config is loaded, so it's forced to default value at runtime, and forced off when switching. The config loading code would need restructured. - // - With both this & frame interpolation on, I_FinishUpdate takes x10 longer. At this point, it is simpler to use a standard FPS cap. - // So you can probably guess why I'm kinda over this, I'm just disabling it. else if (cv_vidwait.value) + { +#if SDL_VERSION_ATLEAST(2, 0, 18) + // If SDL is new enough, we can turn off vsync later. flags |= SDL_RENDERER_PRESENTVSYNC; +#else + // However, if it isn't, we should just silently turn vid_wait off + // This is because the renderer will be created before the config + // is read and vid_wait is set from the user's preferences, and thus + // vid_wait will have no effect. + CV_StealthSetValue(cv_vidwait, 0); #endif + } if (!renderer) renderer = SDL_CreateRenderer(window, -1, flags); @@ -1571,6 +1593,7 @@ boolean VID_CheckRenderer(void) else if (vid.glstate == VID_GL_LIBRARY_ERROR) rendererchanged = false; } + else #endif if (!contextcreated) From c42ef9f1be3157f468f0ae881a855538c6fa540d Mon Sep 17 00:00:00 2001 From: Eidolon Date: Sun, 26 Feb 2023 16:47:00 -0600 Subject: [PATCH 099/586] Fix IT and ctf flag sign interpolation --- src/info.c | 4 ++-- src/p_user.c | 57 +++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 45 insertions(+), 16 deletions(-) diff --git a/src/info.c b/src/info.c index 174eb5cc4..b55302170 100644 --- a/src/info.c +++ b/src/info.c @@ -3429,10 +3429,10 @@ state_t states[NUMSTATES] = {SPR_LCKN, 2|FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_LOCKONINF3 {SPR_LCKN, 3|FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_LOCKONINF4 - {SPR_TTAG, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_TTAG + {SPR_TTAG, FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_NULL}, // S_TTAG // CTF Sign - {SPR_GFLG, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_GOTFLAG + {SPR_GFLG, FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_NULL}, // S_GOTFLAG // Finish flag {SPR_FNSF, FF_TRANS30, -1, {NULL}, 0, 0, S_NULL}, // S_FINISHFLAG diff --git a/src/p_user.c b/src/p_user.c index bdb164484..9d16bdda2 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -3108,14 +3108,25 @@ static void P_DoPlayerHeadSigns(player_t *player) if (G_TagGametype()) { // If you're "IT", show a big "IT" over your head for others to see. - if (player->pflags & PF_TAGIT) + if (player->pflags & PF_TAGIT && P_IsLocalPlayer(player)) { - if (!P_IsLocalPlayer(player)) // Don't display it on your own view. + mobj_t* it = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_TAG); + it->x = player->mo->x; + it->y = player->mo->y; + it->z = player->mo->z; + it->old_x = player->mo->old_x; + it->old_y = player->mo->old_y; + it->old_z = player->mo->old_z; + + if (!(player->mo->eflags & MFE_VERTICALFLIP)) { - if (!(player->mo->eflags & MFE_VERTICALFLIP)) - P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z + player->mo->height, MT_TAG); - else - P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z - mobjinfo[MT_TAG].height, MT_TAG)->eflags |= MFE_VERTICALFLIP; + it->z += player->mo->height; + it->old_z += player->mo->height; + } + else + { + it->z -= mobjinfo[MT_TAG].height; + it->old_z -= mobjinfo[MT_TAG].height; } } } @@ -3123,17 +3134,34 @@ static void P_DoPlayerHeadSigns(player_t *player) { // Spawn a got-flag message over the head of the player that // has it (but not on your own screen if you have the flag). - if (splitscreen || player != &players[consoleplayer]) + if (splitscreen || player != &players[consoleplayer] || true) { - mobj_t *sign = P_SpawnMobj(player->mo->x+player->mo->momx, player->mo->y+player->mo->momy, - player->mo->z+player->mo->momz, MT_GOTFLAG); - if (player->mo->eflags & MFE_VERTICALFLIP) + fixed_t zofs; + mobj_t *sign; + boolean player_is_flipped = (player->mo->eflags & MFE_VERTICALFLIP) > 0; + + zofs = player->mo->momz; + if (player_is_flipped) { - sign->z += player->mo->height-P_GetPlayerHeight(player)-mobjinfo[MT_GOTFLAG].height-FixedMul(16*FRACUNIT, player->mo->scale); - sign->eflags |= MFE_VERTICALFLIP; + zofs += player->mo->height - P_GetPlayerHeight(player) - mobjinfo[MT_GOTFLAG].height - FixedMul(16 * FRACUNIT, player->mo->scale); } else - sign->z += P_GetPlayerHeight(player)+FixedMul(16*FRACUNIT, player->mo->scale); + { + zofs += P_GetPlayerHeight(player) + FixedMul(16 * FRACUNIT, player->mo->scale); + } + + sign = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_GOTFLAG); + sign->x = player->mo->x; + sign->y = player->mo->y; + sign->z = player->mo->z + zofs; + sign->old_x = player->mo->old_x; + sign->old_y = player->mo->old_y; + sign->old_z = player->mo->old_z + zofs; + + if (player_is_flipped) + { + sign->eflags |= MFE_VERTICALFLIP; + } if (player->gotflag & GF_REDFLAG) sign->frame = 1|FF_FULLBRIGHT; @@ -12028,7 +12056,6 @@ void P_PlayerThink(player_t *player) P_DoBubbleBreath(player); // Spawn Sonic's bubbles P_CheckUnderwaterAndSpaceTimer(player); // Display the countdown drown numbers! P_CheckInvincibilityTimer(player); // Spawn Invincibility Sparkles - P_DoPlayerHeadSigns(player); // Spawn Tag/CTF signs over player's head #if 1 // "Blur" a bit when you have speed shoes and are going fast enough @@ -12893,6 +12920,8 @@ void P_PlayerAfterThink(player_t *player) } } } + + P_DoPlayerHeadSigns(player); // Spawn Tag/CTF signs over player's head } void P_SetPlayerAngle(player_t *player, angle_t angle) From 851ca92aaaefc576d3be0fcca9a844bc6447a0fd Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 28 Feb 2023 17:51:26 +0000 Subject: [PATCH 100/586] revert Eidolon's edits for testing the IT/CTF flag sign fixes, they were left in by mistake --- src/p_user.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 26abc0220..60a0f5106 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1,4 +1,3 @@ - // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. @@ -3108,7 +3107,7 @@ static void P_DoPlayerHeadSigns(player_t *player) if (G_TagGametype()) { // If you're "IT", show a big "IT" over your head for others to see. - if (player->pflags & PF_TAGIT && P_IsLocalPlayer(player)) + if (player->pflags & PF_TAGIT && !P_IsLocalPlayer(player)) { mobj_t* it = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_TAG); it->x = player->mo->x; @@ -3134,7 +3133,7 @@ static void P_DoPlayerHeadSigns(player_t *player) { // Spawn a got-flag message over the head of the player that // has it (but not on your own screen if you have the flag). - if (splitscreen || player != &players[consoleplayer] || true) + if (splitscreen || player != &players[consoleplayer]) { fixed_t zofs; mobj_t *sign; From 57148ef9c28d78897852608e642c9028807a79c7 Mon Sep 17 00:00:00 2001 From: spherallic Date: Thu, 2 Mar 2023 18:10:47 +0100 Subject: [PATCH 101/586] Fix Explosion Ring explosion interpolation --- src/p_mobj.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index b279a8a88..30e0183de 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6334,11 +6334,7 @@ void P_SpawnParaloop(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 numb mobj->fuse = (radius>>(FRACBITS+2)) + 1; if (spawncenter) - { - mobj->x = x; - mobj->y = y; - mobj->z = z; - } + P_SetOrigin(mobj, x, y, z); if (mobj->fuse <= 1) mobj->fuse = 2; From b184067048b4c5548d152c2481db9baa0d2866bd Mon Sep 17 00:00:00 2001 From: spherallic Date: Tue, 14 Mar 2023 14:19:53 +0100 Subject: [PATCH 102/586] Add HUD icons for timed NiGHTS powerups --- src/st_stuff.c | 89 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 61 insertions(+), 28 deletions(-) diff --git a/src/st_stuff.c b/src/st_stuff.c index 3e75750a8..65e4c5e03 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -108,6 +108,9 @@ static patch_t *sneakers; static patch_t *gravboots; static patch_t *nonicon; static patch_t *nonicon2; +static patch_t *nightopianhelper; +static patch_t *linkfreeze; +static patch_t *superparaloop; static patch_t *bluestat; static patch_t *byelstat; static patch_t *orngstat; @@ -313,6 +316,10 @@ void ST_LoadGraphics(void) nonicon2 = W_CachePatchName("NONICON2", PU_HUDGFX); // NiGHTS HUD things + nightopianhelper = W_CachePatchName("NHLPICON", PU_HUDGFX); + linkfreeze = W_CachePatchName("NLFZICON", PU_HUDGFX); + superparaloop = W_CachePatchName("NSPRICON", PU_HUDGFX); + bluestat = W_CachePatchName("BLUESTAT", PU_HUDGFX); byelstat = W_CachePatchName("BYELSTAT", PU_HUDGFX); orngstat = W_CachePatchName("ORNGSTAT", PU_HUDGFX); @@ -1448,6 +1455,21 @@ void ST_drawWipeTitleCard(void) } } +#define ICONSEP (16+4) // matches weapon rings HUD + +static INT32 ST_powerupHUDoffset(UINT16 timer) +{ + if (timer > 7) + return ICONSEP; + else + { + UINT8 a = ICONSEP, b = 7-timer; + while (b--) + a = 2*a/3; + return a; + } +} + static void ST_drawPowerupHUD(void) { patch_t *p = NULL; @@ -1455,7 +1477,6 @@ static void ST_drawPowerupHUD(void) INT32 offs = hudinfo[HUD_POWERUPS].x; const UINT8 q = ((splitscreen && stplyr == &players[secondarydisplayplayer]) ? 1 : 0); static INT32 flagoffs[2] = {0, 0}, shieldoffs[2] = {0, 0}, finishoffs[2] = {0, 0}; -#define ICONSEP (16+4) // matches weapon rings HUD if (F_GetPromptHideHud(hudinfo[HUD_POWERUPS].y)) return; @@ -1567,15 +1588,7 @@ static void ST_drawPowerupHUD(void) DRAWTIMERICON(invincibility, invulntime) } - if (invulntime > 7) - offs -= ICONSEP; - else - { - UINT8 a = ICONSEP, b = 7-invulntime; - while (b--) - a = 2*a/3; - offs -= a; - } + offs -= ST_powerupHUDoffset(invulntime); // Super Sneakers if (stplyr->powers[pw_sneakers] > 3*TICRATE || (stplyr->powers[pw_sneakers] && leveltime & 1)) @@ -1583,15 +1596,7 @@ static void ST_drawPowerupHUD(void) DRAWTIMERICON(sneakers, stplyr->powers[pw_sneakers]) } - if (stplyr->powers[pw_sneakers] > 7) - offs -= ICONSEP; - else - { - UINT8 a = ICONSEP, b = 7-stplyr->powers[pw_sneakers]; - while (b--) - a = 2*a/3; - offs -= a; - } + offs -= ST_powerupHUDoffset(stplyr->powers[pw_sneakers]); // Gravity Boots if (stplyr->powers[pw_gravityboots] > 3*TICRATE || (stplyr->powers[pw_gravityboots] && leveltime & 1)) @@ -1599,6 +1604,36 @@ static void ST_drawPowerupHUD(void) DRAWTIMERICON(gravboots, stplyr->powers[pw_gravityboots]) } + offs -= ST_powerupHUDoffset(stplyr->powers[pw_gravityboots]); + +// -------------------- +// NiGHTS timer-based powerups +// -------------------- + + // Nightopian Helper + if (stplyr->powers[pw_nights_helper] > 3*TICRATE || (stplyr->powers[pw_nights_helper] && leveltime & 1)) + { + DRAWTIMERICON(nightopianhelper, stplyr->powers[pw_nights_helper]) + } + + offs -= ST_powerupHUDoffset(stplyr->powers[pw_nights_helper]); + + // Link Freeze + if (stplyr->powers[pw_nights_linkfreeze] > 3*TICRATE || (stplyr->powers[pw_nights_linkfreeze] && leveltime & 1)) + { + DRAWTIMERICON(linkfreeze, stplyr->powers[pw_nights_linkfreeze]) + } + + offs -= ST_powerupHUDoffset(stplyr->powers[pw_nights_linkfreeze]); + + // Super Paraloop + if (stplyr->powers[pw_nights_superloop] > 3*TICRATE || (stplyr->powers[pw_nights_superloop] && leveltime & 1)) + { + DRAWTIMERICON(superparaloop, stplyr->powers[pw_nights_superloop]) + } + + //offs -= ST_powerupHUDoffset(stplyr->powers[pw_nights_superloop]); + #undef DRAWTIMERICON #undef ICONSEP } @@ -2740,18 +2775,16 @@ static void ST_overlayDrawer(void) } // This is where we draw all the fun cheese if you have the chasecam off! - if (!(maptol & TOL_NIGHTS)) + if ((stplyr == &players[displayplayer] && !camera.chase) + || ((splitscreen && stplyr == &players[secondarydisplayplayer]) && !camera2.chase)) { - if ((stplyr == &players[displayplayer] && !camera.chase) - || ((splitscreen && stplyr == &players[secondarydisplayplayer]) && !camera2.chase)) - { - ST_drawFirstPersonHUD(); - if (cv_powerupdisplay.value) - ST_drawPowerupHUD(); // same as it ever was... - } - else if (cv_powerupdisplay.value == 2) + ST_drawFirstPersonHUD(); + if (cv_powerupdisplay.value) ST_drawPowerupHUD(); // same as it ever was... } + else if (cv_powerupdisplay.value == 2) + ST_drawPowerupHUD(); // same as it ever was... + } else if (!(netgame || multiplayer) && cv_powerupdisplay.value == 2) ST_drawPowerupHUD(); // same as it ever was... From 2a50626b004110ec27d2d6259653d513f8546df7 Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+TatsuruIKR@users.noreply.github.com> Date: Wed, 15 Mar 2023 17:50:13 -0300 Subject: [PATCH 103/586] Initial commit --- src/d_clisrv.c | 20 +++++++++++++++++--- src/d_clisrv.h | 1 + src/lua_baselib.c | 16 ++++++++++------ 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 1ff053e5c..d3426ef14 100755 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1377,8 +1377,9 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime) 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; + // Exclude bots from both counts + netbuffer->u.serverinfo.numberofplayer = (UINT8)(D_NumPlayers() - D_NumBots()); + netbuffer->u.serverinfo.maxplayer = (UINT8)(cv_maxplayers.value - D_NumBots()); netbuffer->u.serverinfo.refusereason = GetRefuseReason(node); @@ -4077,7 +4078,7 @@ ConnectionRefused (SINT8 node, INT32 rejoinernum) { return va( "Maximum players reached: %d", - cv_maxplayers.value); + cv_maxplayers.value - D_NumBots()); } } @@ -5609,6 +5610,19 @@ INT32 D_NumPlayers(void) return num; } +/** Similar to the above, but counts only bots. + * Purpose is to remove bots from both the player count and the + * max player count on the server view +*/ +INT32 D_NumBots(void) +{ + INT32 num = 0, ix; + for (ix = 0; ix < MAXPLAYERS; ix++) + if (playeringame[ix] && players[ix].bot) + num++; + return num; +} + tic_t GetLag(INT32 node) { return gametic - nettics[node]; diff --git a/src/d_clisrv.h b/src/d_clisrv.h index e07864122..48480cfe5 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -447,6 +447,7 @@ extern char motd[254], server_context[8]; extern UINT8 playernode[MAXPLAYERS]; INT32 D_NumPlayers(void); +INT32 D_NumBots(void); void D_ResetTiccmds(void); tic_t GetLag(INT32 node); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index a4ad81358..04a9607a8 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -3541,7 +3541,6 @@ static int lib_gAddPlayer(lua_State *L) return 1; } - newplayernum = i; CL_ClearPlayer(newplayernum); @@ -3553,9 +3552,6 @@ static int lib_gAddPlayer(lua_State *L) newplayer->jointime = 0; newplayer->quittime = 0; - // Set the bot name (defaults to Bot #) - strcpy(player_names[newplayernum], va("Bot %d", botcount)); - // Read the skin argument (defaults to Sonic) if (!lua_isnoneornil(L, 1)) { @@ -3567,7 +3563,10 @@ static int lib_gAddPlayer(lua_State *L) if (!lua_isnoneornil(L, 2)) newplayer->skincolor = R_GetColorByName(luaL_checkstring(L, 2)); else - newplayer->skincolor = skins[newplayer->skin].prefcolor; + newplayer->skincolor = skins[skinnum].prefcolor; + + // Set the bot default name as the skin + strcpy(player_names[newplayernum], skins[skinnum].realname); // Read the bot name, if given if (!lua_isnoneornil(L, 3)) @@ -3583,14 +3582,19 @@ static int lib_gAddPlayer(lua_State *L) // Set the skin (can't do this until AFTER bot type is set!) SetPlayerSkinByNum(newplayernum, skinnum); - if (netgame) { char joinmsg[256]; + // Truncate bot name + player_names[newplayernum][sizeof(*player_names) - 7] = '\0'; // The length of colored [BOT] + 1 + 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); + + // Append blue [BOT] tag at the end + strlcat(player_names[newplayernum], "\x84[BOT]", sizeof(*player_names)); } LUA_PushUserdata(L, newplayer, META_PLAYER); From db4de0f50e527f1a22e2418921aa0f6116c77c48 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 15 Mar 2023 16:39:53 -0700 Subject: [PATCH 104/586] sdl/i_video.c: fix compile prior to SDL 2.0.18 --- src/sdl/i_video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 47d41ede5..02f0e462e 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1504,7 +1504,7 @@ static SDL_bool Impl_CreateContext(void) // This is because the renderer will be created before the config // is read and vid_wait is set from the user's preferences, and thus // vid_wait will have no effect. - CV_StealthSetValue(cv_vidwait, 0); + CV_StealthSetValue(&cv_vidwait, 0); #endif } From e48786961a865289b3cf4b9f86ba014a250bf14e Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 15 Mar 2023 11:33:37 -0700 Subject: [PATCH 105/586] exec: pass on com_flags --- src/command.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/command.c b/src/command.c index b22f03d1a..f73bb3b26 100644 --- a/src/command.c +++ b/src/command.c @@ -794,8 +794,8 @@ static void COM_Exec_f(void) CONS_Printf(M_GetText("executing %s\n"), COM_Argv(1)); // insert text file into the command buffer - COM_BufAddText((char *)buf); - COM_BufAddText("\n"); + COM_BufAddTextEx((char *)buf, com_flags); + COM_BufAddTextEx("\n", com_flags); // free buffer Z_Free(buf); From a39f69c9c7ebe35beb38132afbc232f25db17252 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 15 Mar 2023 11:39:25 -0700 Subject: [PATCH 106/586] Reset com_flags at end of COM_BufExecute Fixes com_flags being discarded after the first command in a chain (semicolon list). --- src/command.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/command.c b/src/command.c index f73bb3b26..de9da232e 100644 --- a/src/command.c +++ b/src/command.c @@ -264,6 +264,8 @@ void COM_BufExecute(void) break; } } + + com_flags = 0; } /** Executes a string immediately. Used for skirting around WAIT commands. @@ -440,7 +442,6 @@ static void COM_TokenizeString(char *ptext) com_argc = 0; com_args = NULL; - com_flags = 0; while (com_argc < MAX_ARGS) { From 5d08bfd7068997edbc435d1e50dfd3ae8a402bc8 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 15 Mar 2023 11:43:53 -0700 Subject: [PATCH 107/586] Rename CV_NOLUA to CV_ALLOWLUA, opt IN to Lua mutability --- src/command.c | 19 ++++++++++++++++++- src/command.h | 2 +- src/deh_tables.c | 2 +- src/lua_consolelib.c | 5 +++-- src/screen.c | 2 +- 5 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/command.c b/src/command.c index de9da232e..e027b45f3 100644 --- a/src/command.c +++ b/src/command.c @@ -57,6 +57,7 @@ static boolean CV_FilterVarByVersion(consvar_t *v, const char *valstr); static boolean CV_Command(void); consvar_t *CV_FindVar(const char *name); static const char *CV_StringValue(const char *var_name); +static boolean CV_Immutable(const consvar_t *var); static consvar_t *consvar_vars; // list of registered console variables static UINT16 consvar_number_of_netids = 0; @@ -2371,7 +2372,7 @@ static boolean CV_Command(void) if (!v) return false; - if (( com_flags & COM_SAFE ) && ( v->flags & CV_NOLUA )) + if (CV_Immutable(v)) { CONS_Alert(CONS_WARNING, "Variable '%s' cannot be changed from Lua.\n", v->name); return true; @@ -2460,6 +2461,22 @@ void CV_SaveVariables(FILE *f) } } +// Returns true if this cvar cannot be modified in current context. +// Such as if the cvar does not have CV_ALLOWLUA. +static boolean CV_Immutable(const consvar_t *var) +{ + // Currently operating from Lua + if (com_flags & COM_SAFE) + { + if (!(var->flags & CV_ALLOWLUA)) + { + return true; + } + } + + return false; +} + //============================================================================ // SCRIPT PARSE //============================================================================ diff --git a/src/command.h b/src/command.h index 30d7e5bbe..48827f99f 100644 --- a/src/command.h +++ b/src/command.h @@ -120,7 +120,7 @@ typedef enum // can only be set when we have the pointer to it // used on menus CV_CHEAT = 2048, // Don't let this be used in multiplayer unless cheats are on. - CV_NOLUA = 4096,/* don't let this be called from Lua */ + CV_ALLOWLUA = 4096,/* Let this be called from Lua */ } cvflags_t; typedef struct CV_PossibleValue_s diff --git a/src/deh_tables.c b/src/deh_tables.c index 4a3467f78..1031f44fa 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -5525,7 +5525,7 @@ struct int_const_s const INT_CONST[] = { {"CV_HIDEN",CV_HIDEN}, {"CV_HIDDEN",CV_HIDEN}, {"CV_CHEAT",CV_CHEAT}, - {"CV_NOLUA",CV_NOLUA}, + {"CV_ALLOWLUA",CV_ALLOWLUA}, // v_video flags {"V_NOSCALEPATCH",V_NOSCALEPATCH}, diff --git a/src/lua_consolelib.c b/src/lua_consolelib.c index 816051199..f5e98e920 100644 --- a/src/lua_consolelib.c +++ b/src/lua_consolelib.c @@ -450,6 +450,7 @@ static int lib_cvRegisterVar(lua_State *L) return luaL_error(L, M_GetText("Variable %s has CV_CALL without a function"), cvar->name); } + cvar->flags |= CV_ALLOWLUA; // actually time to register it to the console now! Finally! cvar->flags |= CV_MODIFIED; CV_RegisterVar(cvar); @@ -478,7 +479,7 @@ static int CVarSetFunction ){ consvar_t *cvar = *(consvar_t **)luaL_checkudata(L, 1, META_CVAR); - if (cvar->flags & CV_NOLUA) + if (!(cvar->flags & CV_ALLOWLUA)) return luaL_error(L, "Variable '%s' cannot be set from Lua.", cvar->name); switch (lua_type(L, 2)) @@ -510,7 +511,7 @@ static int lib_cvAddValue(lua_State *L) { consvar_t *cvar = *(consvar_t **)luaL_checkudata(L, 1, META_CVAR); - if (cvar->flags & CV_NOLUA) + if (!(cvar->flags & CV_ALLOWLUA)) return luaL_error(L, "Variable %s cannot be set from Lua.", cvar->name); CV_AddValue(cvar, (INT32)luaL_checknumber(L, 2)); diff --git a/src/screen.c b/src/screen.c index 3842a365d..501ee358d 100644 --- a/src/screen.c +++ b/src/screen.c @@ -82,7 +82,7 @@ CV_PossibleValue_t cv_renderer_t[] = { {0, NULL} }; -consvar_t cv_renderer = CVAR_INIT ("renderer", "Software", CV_SAVE|CV_NOLUA|CV_CALL, cv_renderer_t, SCR_ChangeRenderer); +consvar_t cv_renderer = CVAR_INIT ("renderer", "Software", CV_SAVE|CV_CALL, cv_renderer_t, SCR_ChangeRenderer); static void SCR_ChangeFullscreen(void); From 15e3d0e667f97dad191260d3b699e9d60a9f7174 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 15 Mar 2023 11:45:14 -0700 Subject: [PATCH 108/586] Fix toggle command and add command being able to bypass Lua restriction --- src/command.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/command.c b/src/command.c index e027b45f3..7ffa300b1 100644 --- a/src/command.c +++ b/src/command.c @@ -1000,6 +1000,9 @@ static void COM_Toggle_f(void) return; } + if (CV_Immutable(cvar)) + return; + if (!(cvar->PossibleValue == CV_YesNo || cvar->PossibleValue == CV_OnOff)) { CONS_Alert(CONS_NOTICE, M_GetText("%s is not a boolean value\n"), COM_Argv(1)); @@ -1029,6 +1032,9 @@ static void COM_Add_f(void) return; } + if (CV_Immutable(cvar)) + return; + if (( cvar->flags & CV_FLOAT )) { float n =FIXED_TO_FLOAT (cvar->value) + atof(COM_Argv(2)); From ff0f6e9b74020bc587ba54906dbf1362362af577 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 15 Mar 2023 12:35:10 -0700 Subject: [PATCH 109/586] Add CV_ALLOWLUA to a bunch of cvars These cvars can be modified by Lua. - advancemap - allowexitlevel - allowjoin - allowmlook - allowseenames - allowteamchange - autobalance - basenumlaps - cam2_adjust - cam2_centertoggle - cam2_curdist - cam2_curheight - cam2_dist - cam2_height - cam2_lockaimassist - cam2_lockedinput - cam2_orbit - cam2_rotate - cam2_rotspeed - cam2_shiftfacingchar - cam2_simpledist - cam2_simpleheight - cam2_speed - cam2_still - cam2_turnfacingability - cam2_turnfacingchar - cam2_turnfacinginput - cam2_turnfacingspindash - cam2_turnmultiplier - cam_adjust - cam_centertoggle - cam_curdist - cam_curheight - cam_dist - cam_height - cam_lockaimassist - cam_lockedinput - cam_orbit - cam_rotate - cam_rotspeed - cam_shiftfacingchar - cam_simpledist - cam_simpleheight - cam_speed - cam_still - cam_turnfacingability - cam_turnfacingchar - cam_turnfacinginput - cam_turnfacingspindash - cam_turnmultiplier - color - color2 - competitionboxes - cooplives - coopstarposts - countdowntime - exitmove - flagtime - forceskin - friendlyfire - gravity - hidetime - inttime - itemfinder - killingdead - matchboxes - maxplayers - mute - numlaps - overtime - pausepermission - playersforexit - pointlimit - powerstones - respawndelay - respawnitem - respawnitemtime - restrictskinchange - ringslinger - runscripts - scrambleonchange - seenames - servername - showhud - showinputjoy - skin - skin2 - specialrings - startinglives - tailspickup - teamscramble - timelimit - touchtag - tv_1up - tv_bombshield - tv_eggman - tv_forceshield - tv_invincibility - tv_jumpshield - tv_recycler - tv_ringshield - tv_superring - tv_supersneaker - tv_teleporter - tv_watershield --- src/d_clisrv.c | 4 +- src/d_netcmd.c | 108 ++++++++++++++++++++++++------------------------- src/g_game.c | 32 +++++++-------- src/mserv.c | 2 +- src/p_mobj.c | 6 +-- src/p_user.c | 52 ++++++++++++------------ src/r_main.c | 6 +-- 7 files changed, 105 insertions(+), 105 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 1ff053e5c..19e6bf0f7 100755 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -3506,10 +3506,10 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum) 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_allownewplayer = CVAR_INIT ("allowjoin", "On", CV_SAVE|CV_NETVAR|CV_ALLOWLUA, 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); +consvar_t cv_maxplayers = CVAR_INIT ("maxplayers", "8", CV_SAVE|CV_NETVAR|CV_ALLOWLUA, 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}}; diff --git a/src/d_netcmd.c b/src/d_netcmd.c index f63f38a74..67099e848 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -203,37 +203,37 @@ static CV_PossibleValue_t matchboxes_cons_t[] = {{0, "Normal"}, {1, "Mystery"}, static CV_PossibleValue_t chances_cons_t[] = {{0, "MIN"}, {9, "MAX"}, {0, NULL}}; static CV_PossibleValue_t pause_cons_t[] = {{0, "Server"}, {1, "All"}, {0, NULL}}; -consvar_t cv_showinputjoy = CVAR_INIT ("showinputjoy", "Off", 0, CV_OnOff, NULL); +consvar_t cv_showinputjoy = CVAR_INIT ("showinputjoy", "Off", CV_ALLOWLUA, CV_OnOff, NULL); #ifdef NETGAME_DEVMODE static consvar_t cv_fishcake = CVAR_INIT ("fishcake", "Off", CV_CALL|CV_NOSHOWHELP|CV_RESTRICT, CV_OnOff, Fishcake_OnChange); #endif static consvar_t cv_dummyconsvar = CVAR_INIT ("dummyconsvar", "Off", CV_CALL|CV_NOSHOWHELP, CV_OnOff, DummyConsvar_OnChange); -consvar_t cv_restrictskinchange = CVAR_INIT ("restrictskinchange", "Yes", CV_SAVE|CV_NETVAR|CV_CHEAT, CV_YesNo, NULL); -consvar_t cv_allowteamchange = CVAR_INIT ("allowteamchange", "Yes", CV_SAVE|CV_NETVAR, CV_YesNo, NULL); +consvar_t cv_restrictskinchange = CVAR_INIT ("restrictskinchange", "Yes", CV_SAVE|CV_NETVAR|CV_CHEAT|CV_ALLOWLUA, CV_YesNo, NULL); +consvar_t cv_allowteamchange = CVAR_INIT ("allowteamchange", "Yes", CV_SAVE|CV_NETVAR|CV_ALLOWLUA, CV_YesNo, NULL); -consvar_t cv_startinglives = CVAR_INIT ("startinglives", "3", CV_SAVE|CV_NETVAR|CV_CHEAT, startingliveslimit_cons_t, NULL); +consvar_t cv_startinglives = CVAR_INIT ("startinglives", "3", CV_SAVE|CV_NETVAR|CV_CHEAT|CV_ALLOWLUA, startingliveslimit_cons_t, NULL); static CV_PossibleValue_t respawntime_cons_t[] = {{1, "MIN"}, {30, "MAX"}, {0, "Off"}, {0, NULL}}; -consvar_t cv_respawntime = CVAR_INIT ("respawndelay", "3", CV_SAVE|CV_NETVAR|CV_CHEAT, respawntime_cons_t, NULL); +consvar_t cv_respawntime = CVAR_INIT ("respawndelay", "3", CV_SAVE|CV_NETVAR|CV_CHEAT|CV_ALLOWLUA, respawntime_cons_t, NULL); -consvar_t cv_competitionboxes = CVAR_INIT ("competitionboxes", "Mystery", CV_SAVE|CV_NETVAR|CV_CHEAT, competitionboxes_cons_t, NULL); +consvar_t cv_competitionboxes = CVAR_INIT ("competitionboxes", "Mystery", CV_SAVE|CV_NETVAR|CV_CHEAT|CV_ALLOWLUA, competitionboxes_cons_t, NULL); 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); +consvar_t cv_seenames = CVAR_INIT ("seenames", "Ally/Foe", CV_SAVE|CV_ALLOWLUA, seenames_cons_t, 0); +consvar_t cv_allowseenames = CVAR_INIT ("allowseenames", "Yes", CV_SAVE|CV_NETVAR|CV_ALLOWLUA, CV_YesNo, NULL); // names consvar_t cv_playername = CVAR_INIT ("name", "Sonic", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Name_OnChange); consvar_t cv_playername2 = CVAR_INIT ("name2", "Tails", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Name2_OnChange); // player colors UINT16 lastgoodcolor = SKINCOLOR_BLUE, lastgoodcolor2 = SKINCOLOR_BLUE; -consvar_t cv_playercolor = CVAR_INIT ("color", "Blue", CV_CALL|CV_NOINIT, Color_cons_t, Color_OnChange); -consvar_t cv_playercolor2 = CVAR_INIT ("color2", "Orange", CV_CALL|CV_NOINIT, Color_cons_t, Color2_OnChange); +consvar_t cv_playercolor = CVAR_INIT ("color", "Blue", CV_CALL|CV_NOINIT|CV_ALLOWLUA, Color_cons_t, Color_OnChange); +consvar_t cv_playercolor2 = CVAR_INIT ("color2", "Orange", CV_CALL|CV_NOINIT|CV_ALLOWLUA, Color_cons_t, Color2_OnChange); // player's skin, saved for commodity, when using a favorite skins wad.. -consvar_t cv_skin = CVAR_INIT ("skin", DEFAULTSKIN, CV_CALL|CV_NOINIT, NULL, Skin_OnChange); -consvar_t cv_skin2 = CVAR_INIT ("skin2", DEFAULTSKIN2, CV_CALL|CV_NOINIT, NULL, Skin2_OnChange); +consvar_t cv_skin = CVAR_INIT ("skin", DEFAULTSKIN, CV_CALL|CV_NOINIT|CV_ALLOWLUA, NULL, Skin_OnChange); +consvar_t cv_skin2 = CVAR_INIT ("skin2", DEFAULTSKIN2, CV_CALL|CV_NOINIT|CV_ALLOWLUA, NULL, Skin2_OnChange); // saved versions of the above six consvar_t cv_defaultplayercolor = CVAR_INIT ("defaultcolor", "Blue", CV_SAVE, Color_cons_t, NULL); @@ -268,43 +268,43 @@ consvar_t cv_mouse2opt = CVAR_INIT ("mouse2opt", "0", CV_SAVE, NULL, NULL); consvar_t cv_mouse2port = CVAR_INIT ("mouse2port", "COM2", CV_SAVE, mouse2port_cons_t, NULL); #endif -consvar_t cv_matchboxes = CVAR_INIT ("matchboxes", "Normal", CV_SAVE|CV_NETVAR|CV_CHEAT, matchboxes_cons_t, NULL); -consvar_t cv_specialrings = CVAR_INIT ("specialrings", "On", CV_SAVE|CV_NETVAR, CV_OnOff, NULL); -consvar_t cv_powerstones = CVAR_INIT ("powerstones", "On", CV_SAVE|CV_NETVAR, CV_OnOff, NULL); +consvar_t cv_matchboxes = CVAR_INIT ("matchboxes", "Normal", CV_SAVE|CV_NETVAR|CV_CHEAT|CV_ALLOWLUA, matchboxes_cons_t, NULL); +consvar_t cv_specialrings = CVAR_INIT ("specialrings", "On", CV_SAVE|CV_NETVAR|CV_ALLOWLUA, CV_OnOff, NULL); +consvar_t cv_powerstones = CVAR_INIT ("powerstones", "On", CV_SAVE|CV_NETVAR|CV_ALLOWLUA, CV_OnOff, NULL); -consvar_t cv_recycler = CVAR_INIT ("tv_recycler", "5", CV_SAVE|CV_NETVAR|CV_CHEAT, chances_cons_t, NULL); -consvar_t cv_teleporters = CVAR_INIT ("tv_teleporter", "5", CV_SAVE|CV_NETVAR|CV_CHEAT, chances_cons_t, NULL); -consvar_t cv_superring = CVAR_INIT ("tv_superring", "5", CV_SAVE|CV_NETVAR|CV_CHEAT, chances_cons_t, NULL); -consvar_t cv_supersneakers = CVAR_INIT ("tv_supersneaker", "5", CV_SAVE|CV_NETVAR|CV_CHEAT, chances_cons_t, NULL); -consvar_t cv_invincibility = CVAR_INIT ("tv_invincibility", "5", CV_SAVE|CV_NETVAR|CV_CHEAT, chances_cons_t, NULL); -consvar_t cv_jumpshield = CVAR_INIT ("tv_jumpshield", "5", CV_SAVE|CV_NETVAR|CV_CHEAT, chances_cons_t, NULL); -consvar_t cv_watershield = CVAR_INIT ("tv_watershield", "5", CV_SAVE|CV_NETVAR|CV_CHEAT, chances_cons_t, NULL); -consvar_t cv_ringshield = CVAR_INIT ("tv_ringshield", "5", CV_SAVE|CV_NETVAR|CV_CHEAT, chances_cons_t, NULL); -consvar_t cv_forceshield = CVAR_INIT ("tv_forceshield", "5", CV_SAVE|CV_NETVAR|CV_CHEAT, chances_cons_t, NULL); -consvar_t cv_bombshield = CVAR_INIT ("tv_bombshield", "5", CV_SAVE|CV_NETVAR|CV_CHEAT, chances_cons_t, NULL); -consvar_t cv_1up = CVAR_INIT ("tv_1up", "5", CV_SAVE|CV_NETVAR|CV_CHEAT, chances_cons_t, NULL); -consvar_t cv_eggmanbox = CVAR_INIT ("tv_eggman", "5", CV_SAVE|CV_NETVAR|CV_CHEAT, chances_cons_t, NULL); +consvar_t cv_recycler = CVAR_INIT ("tv_recycler", "5", CV_SAVE|CV_NETVAR|CV_CHEAT|CV_ALLOWLUA, chances_cons_t, NULL); +consvar_t cv_teleporters = CVAR_INIT ("tv_teleporter", "5", CV_SAVE|CV_NETVAR|CV_CHEAT|CV_ALLOWLUA, chances_cons_t, NULL); +consvar_t cv_superring = CVAR_INIT ("tv_superring", "5", CV_SAVE|CV_NETVAR|CV_CHEAT|CV_ALLOWLUA, chances_cons_t, NULL); +consvar_t cv_supersneakers = CVAR_INIT ("tv_supersneaker", "5", CV_SAVE|CV_NETVAR|CV_CHEAT|CV_ALLOWLUA, chances_cons_t, NULL); +consvar_t cv_invincibility = CVAR_INIT ("tv_invincibility", "5", CV_SAVE|CV_NETVAR|CV_CHEAT|CV_ALLOWLUA, chances_cons_t, NULL); +consvar_t cv_jumpshield = CVAR_INIT ("tv_jumpshield", "5", CV_SAVE|CV_NETVAR|CV_CHEAT|CV_ALLOWLUA, chances_cons_t, NULL); +consvar_t cv_watershield = CVAR_INIT ("tv_watershield", "5", CV_SAVE|CV_NETVAR|CV_CHEAT|CV_ALLOWLUA, chances_cons_t, NULL); +consvar_t cv_ringshield = CVAR_INIT ("tv_ringshield", "5", CV_SAVE|CV_NETVAR|CV_CHEAT|CV_ALLOWLUA, chances_cons_t, NULL); +consvar_t cv_forceshield = CVAR_INIT ("tv_forceshield", "5", CV_SAVE|CV_NETVAR|CV_CHEAT|CV_ALLOWLUA, chances_cons_t, NULL); +consvar_t cv_bombshield = CVAR_INIT ("tv_bombshield", "5", CV_SAVE|CV_NETVAR|CV_CHEAT|CV_ALLOWLUA, chances_cons_t, NULL); +consvar_t cv_1up = CVAR_INIT ("tv_1up", "5", CV_SAVE|CV_NETVAR|CV_CHEAT|CV_ALLOWLUA, chances_cons_t, NULL); +consvar_t cv_eggmanbox = CVAR_INIT ("tv_eggman", "5", CV_SAVE|CV_NETVAR|CV_CHEAT|CV_ALLOWLUA, chances_cons_t, NULL); -consvar_t cv_ringslinger = CVAR_INIT ("ringslinger", "No", CV_NETVAR|CV_NOSHOWHELP|CV_CALL|CV_CHEAT, CV_YesNo, Ringslinger_OnChange); -consvar_t cv_gravity = CVAR_INIT ("gravity", "0.5", CV_RESTRICT|CV_FLOAT|CV_CALL, NULL, Gravity_OnChange); +consvar_t cv_ringslinger = CVAR_INIT ("ringslinger", "No", CV_NETVAR|CV_NOSHOWHELP|CV_CALL|CV_CHEAT|CV_ALLOWLUA, CV_YesNo, Ringslinger_OnChange); +consvar_t cv_gravity = CVAR_INIT ("gravity", "0.5", CV_RESTRICT|CV_FLOAT|CV_CALL|CV_ALLOWLUA, NULL, Gravity_OnChange); consvar_t cv_soundtest = CVAR_INIT ("soundtest", "0", CV_CALL, NULL, SoundTest_OnChange); 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_countdowntime = CVAR_INIT ("countdowntime", "60", CV_SAVE|CV_NETVAR|CV_CHEAT|CV_ALLOWLUA, minitimelimit_cons_t, NULL); -consvar_t cv_touchtag = CVAR_INIT ("touchtag", "Off", CV_SAVE|CV_NETVAR, CV_OnOff, NULL); -consvar_t cv_hidetime = CVAR_INIT ("hidetime", "30", CV_SAVE|CV_NETVAR|CV_CALL, minitimelimit_cons_t, Hidetime_OnChange); +consvar_t cv_touchtag = CVAR_INIT ("touchtag", "Off", CV_SAVE|CV_NETVAR|CV_ALLOWLUA, CV_OnOff, NULL); +consvar_t cv_hidetime = CVAR_INIT ("hidetime", "30", CV_SAVE|CV_NETVAR|CV_CALL|CV_ALLOWLUA, minitimelimit_cons_t, Hidetime_OnChange); -consvar_t cv_autobalance = CVAR_INIT ("autobalance", "Off", CV_SAVE|CV_NETVAR|CV_CALL, CV_OnOff, AutoBalance_OnChange); -consvar_t cv_teamscramble = CVAR_INIT ("teamscramble", "Off", CV_SAVE|CV_NETVAR|CV_CALL|CV_NOINIT, teamscramble_cons_t, TeamScramble_OnChange); -consvar_t cv_scrambleonchange = CVAR_INIT ("scrambleonchange", "Off", CV_SAVE|CV_NETVAR, teamscramble_cons_t, NULL); +consvar_t cv_autobalance = CVAR_INIT ("autobalance", "Off", CV_SAVE|CV_NETVAR|CV_CALL|CV_ALLOWLUA, CV_OnOff, AutoBalance_OnChange); +consvar_t cv_teamscramble = CVAR_INIT ("teamscramble", "Off", CV_SAVE|CV_NETVAR|CV_CALL|CV_NOINIT|CV_ALLOWLUA, teamscramble_cons_t, TeamScramble_OnChange); +consvar_t cv_scrambleonchange = CVAR_INIT ("scrambleonchange", "Off", CV_SAVE|CV_NETVAR|CV_ALLOWLUA, teamscramble_cons_t, NULL); -consvar_t cv_friendlyfire = CVAR_INIT ("friendlyfire", "Off", CV_SAVE|CV_NETVAR, CV_OnOff, NULL); -consvar_t cv_itemfinder = CVAR_INIT ("itemfinder", "Off", CV_CALL, CV_OnOff, ItemFinder_OnChange); +consvar_t cv_friendlyfire = CVAR_INIT ("friendlyfire", "Off", CV_SAVE|CV_NETVAR|CV_ALLOWLUA, CV_OnOff, NULL); +consvar_t cv_itemfinder = CVAR_INIT ("itemfinder", "Off", CV_CALL|CV_ALLOWLUA, CV_OnOff, ItemFinder_OnChange); // Scoring type options -consvar_t cv_overtime = CVAR_INIT ("overtime", "Yes", CV_SAVE|CV_NETVAR, CV_YesNo, NULL); +consvar_t cv_overtime = CVAR_INIT ("overtime", "Yes", CV_SAVE|CV_NETVAR|CV_ALLOWLUA, CV_YesNo, NULL); consvar_t cv_rollingdemos = CVAR_INIT ("rollingdemos", "On", CV_SAVE, CV_OnOff, NULL); @@ -315,13 +315,13 @@ static CV_PossibleValue_t powerupdisplay_cons_t[] = {{0, "Never"}, {1, "First-pe consvar_t cv_powerupdisplay = CVAR_INIT ("powerupdisplay", "First-person only", CV_SAVE, powerupdisplay_cons_t, NULL); static CV_PossibleValue_t pointlimit_cons_t[] = {{1, "MIN"}, {MAXSCORE, "MAX"}, {0, "None"}, {0, NULL}}; -consvar_t cv_pointlimit = CVAR_INIT ("pointlimit", "None", CV_SAVE|CV_NETVAR|CV_CALL|CV_NOINIT, pointlimit_cons_t, PointLimit_OnChange); +consvar_t cv_pointlimit = CVAR_INIT ("pointlimit", "None", CV_SAVE|CV_NETVAR|CV_CALL|CV_NOINIT|CV_ALLOWLUA, pointlimit_cons_t, PointLimit_OnChange); static CV_PossibleValue_t timelimit_cons_t[] = {{1, "MIN"}, {30, "MAX"}, {0, "None"}, {0, NULL}}; -consvar_t cv_timelimit = CVAR_INIT ("timelimit", "None", CV_SAVE|CV_NETVAR|CV_CALL|CV_NOINIT, timelimit_cons_t, TimeLimit_OnChange); +consvar_t cv_timelimit = CVAR_INIT ("timelimit", "None", CV_SAVE|CV_NETVAR|CV_CALL|CV_NOINIT|CV_ALLOWLUA, timelimit_cons_t, TimeLimit_OnChange); static CV_PossibleValue_t numlaps_cons_t[] = {{1, "MIN"}, {50, "MAX"}, {0, NULL}}; -consvar_t cv_numlaps = CVAR_INIT ("numlaps", "4", CV_NETVAR|CV_CALL|CV_NOINIT, numlaps_cons_t, NumLaps_OnChange); +consvar_t cv_numlaps = CVAR_INIT ("numlaps", "4", CV_NETVAR|CV_CALL|CV_NOINIT|CV_ALLOWLUA, numlaps_cons_t, NumLaps_OnChange); static CV_PossibleValue_t basenumlaps_cons_t[] = {{1, "MIN"}, {50, "MAX"}, {0, "Map default"}, {0, NULL}}; -consvar_t cv_basenumlaps = CVAR_INIT ("basenumlaps", "Map default", CV_SAVE|CV_NETVAR|CV_CALL|CV_CHEAT, basenumlaps_cons_t, BaseNumLaps_OnChange); +consvar_t cv_basenumlaps = CVAR_INIT ("basenumlaps", "Map default", CV_SAVE|CV_NETVAR|CV_CALL|CV_CHEAT|CV_ALLOWLUA, basenumlaps_cons_t, BaseNumLaps_OnChange); // Point and time limits for every gametype INT32 pointlimits[NUMGAMETYPES]; @@ -330,11 +330,11 @@ INT32 timelimits[NUMGAMETYPES]; // log elemental hazards -- not a netvar, is local to current player consvar_t cv_hazardlog = CVAR_INIT ("hazardlog", "Yes", 0, CV_YesNo, NULL); -consvar_t cv_forceskin = CVAR_INIT ("forceskin", "None", CV_NETVAR|CV_CALL|CV_CHEAT, NULL, ForceSkin_OnChange); +consvar_t cv_forceskin = CVAR_INIT ("forceskin", "None", CV_NETVAR|CV_CALL|CV_CHEAT|CV_ALLOWLUA, NULL, ForceSkin_OnChange); consvar_t cv_downloading = CVAR_INIT ("downloading", "On", 0, CV_OnOff, NULL); -consvar_t cv_allowexitlevel = CVAR_INIT ("allowexitlevel", "No", CV_SAVE|CV_NETVAR, CV_YesNo, NULL); +consvar_t cv_allowexitlevel = CVAR_INIT ("allowexitlevel", "No", CV_SAVE|CV_NETVAR|CV_ALLOWLUA, CV_YesNo, NULL); -consvar_t cv_killingdead = CVAR_INIT ("killingdead", "Off", CV_NETVAR, CV_OnOff, NULL); +consvar_t cv_killingdead = CVAR_INIT ("killingdead", "Off", CV_NETVAR|CV_ALLOWLUA, CV_OnOff, NULL); consvar_t cv_netstat = CVAR_INIT ("netstat", "Off", 0, CV_OnOff, NULL); // show bandwidth statistics static CV_PossibleValue_t nettimeout_cons_t[] = {{TICRATE/7, "MIN"}, {60*TICRATE, "MAX"}, {0, NULL}}; @@ -352,26 +352,26 @@ consvar_t cv_showping = CVAR_INIT ("showping", "Warning", CV_SAVE, showping_cons // Intermission time Tails 04-19-2002 static CV_PossibleValue_t inttime_cons_t[] = {{0, "MIN"}, {3600, "MAX"}, {0, NULL}}; -consvar_t cv_inttime = CVAR_INIT ("inttime", "10", CV_SAVE|CV_NETVAR, inttime_cons_t, NULL); +consvar_t cv_inttime = CVAR_INIT ("inttime", "10", CV_SAVE|CV_NETVAR|CV_ALLOWLUA, inttime_cons_t, NULL); static CV_PossibleValue_t coopstarposts_cons_t[] = {{0, "Per-player"}, {1, "Shared"}, {2, "Teamwork"}, {0, NULL}}; -consvar_t cv_coopstarposts = CVAR_INIT ("coopstarposts", "Per-player", CV_SAVE|CV_NETVAR|CV_CALL, coopstarposts_cons_t, CoopStarposts_OnChange); +consvar_t cv_coopstarposts = CVAR_INIT ("coopstarposts", "Per-player", CV_SAVE|CV_NETVAR|CV_CALL|CV_ALLOWLUA, coopstarposts_cons_t, CoopStarposts_OnChange); static CV_PossibleValue_t cooplives_cons_t[] = {{0, "Infinite"}, {1, "Per-player"}, {2, "Avoid Game Over"}, {3, "Single pool"}, {0, NULL}}; -consvar_t cv_cooplives = CVAR_INIT ("cooplives", "Avoid Game Over", CV_SAVE|CV_NETVAR|CV_CALL|CV_CHEAT, cooplives_cons_t, CoopLives_OnChange); +consvar_t cv_cooplives = CVAR_INIT ("cooplives", "Avoid Game Over", CV_SAVE|CV_NETVAR|CV_CALL|CV_CHEAT|CV_ALLOWLUA, cooplives_cons_t, CoopLives_OnChange); static CV_PossibleValue_t advancemap_cons_t[] = {{0, "Off"}, {1, "Next"}, {2, "Random"}, {0, NULL}}; -consvar_t cv_advancemap = CVAR_INIT ("advancemap", "Next", CV_SAVE|CV_NETVAR, advancemap_cons_t, NULL); +consvar_t cv_advancemap = CVAR_INIT ("advancemap", "Next", CV_SAVE|CV_NETVAR|CV_ALLOWLUA, advancemap_cons_t, NULL); static CV_PossibleValue_t playersforexit_cons_t[] = {{0, "One"}, {1, "1/4"}, {2, "Half"}, {3, "3/4"}, {4, "All"}, {0, NULL}}; -consvar_t cv_playersforexit = CVAR_INIT ("playersforexit", "All", CV_SAVE|CV_NETVAR, playersforexit_cons_t, NULL); +consvar_t cv_playersforexit = CVAR_INIT ("playersforexit", "All", CV_SAVE|CV_NETVAR|CV_ALLOWLUA, playersforexit_cons_t, NULL); -consvar_t cv_exitmove = CVAR_INIT ("exitmove", "On", CV_SAVE|CV_NETVAR|CV_CALL, CV_OnOff, ExitMove_OnChange); +consvar_t cv_exitmove = CVAR_INIT ("exitmove", "On", CV_SAVE|CV_NETVAR|CV_CALL|CV_ALLOWLUA, CV_OnOff, ExitMove_OnChange); -consvar_t cv_runscripts = CVAR_INIT ("runscripts", "Yes", 0, CV_YesNo, NULL); +consvar_t cv_runscripts = CVAR_INIT ("runscripts", "Yes", CV_ALLOWLUA, CV_YesNo, NULL); -consvar_t cv_pause = CVAR_INIT ("pausepermission", "Server", CV_SAVE|CV_NETVAR, pause_cons_t, NULL); -consvar_t cv_mute = CVAR_INIT ("mute", "Off", CV_NETVAR|CV_CALL, CV_OnOff, Mute_OnChange); +consvar_t cv_pause = CVAR_INIT ("pausepermission", "Server", CV_SAVE|CV_NETVAR|CV_ALLOWLUA, pause_cons_t, NULL); +consvar_t cv_mute = CVAR_INIT ("mute", "Off", CV_NETVAR|CV_CALL|CV_ALLOWLUA, CV_OnOff, Mute_OnChange); consvar_t cv_sleep = CVAR_INIT ("cpusleep", "1", CV_SAVE, sleeping_cons_t, NULL); diff --git a/src/g_game.c b/src/g_game.c index 74bc42711..d9a043482 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -364,36 +364,36 @@ consvar_t cv_autobrake2 = CVAR_INIT ("autobrake2", "On", CV_SAVE|CV_CALL, CV_OnO // hi here's some new controls static CV_PossibleValue_t zerotoone_cons_t[] = {{0, "MIN"}, {FRACUNIT, "MAX"}, {0, NULL}}; consvar_t cv_cam_shiftfacing[2] = { - CVAR_INIT ("cam_shiftfacingchar", "0.375", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL), - CVAR_INIT ("cam2_shiftfacingchar", "0.375", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL), + CVAR_INIT ("cam_shiftfacingchar", "0.375", CV_FLOAT|CV_SAVE|CV_ALLOWLUA, zerotoone_cons_t, NULL), + CVAR_INIT ("cam2_shiftfacingchar", "0.375", CV_FLOAT|CV_SAVE|CV_ALLOWLUA, zerotoone_cons_t, NULL), }; consvar_t cv_cam_turnfacing[2] = { - CVAR_INIT ("cam_turnfacingchar", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL), - CVAR_INIT ("cam2_turnfacingchar", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL), + CVAR_INIT ("cam_turnfacingchar", "0.25", CV_FLOAT|CV_SAVE|CV_ALLOWLUA, zerotoone_cons_t, NULL), + CVAR_INIT ("cam2_turnfacingchar", "0.25", CV_FLOAT|CV_SAVE|CV_ALLOWLUA, zerotoone_cons_t, NULL), }; consvar_t cv_cam_turnfacingability[2] = { - CVAR_INIT ("cam_turnfacingability", "0.125", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL), - CVAR_INIT ("cam2_turnfacingability", "0.125", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL), + CVAR_INIT ("cam_turnfacingability", "0.125", CV_FLOAT|CV_SAVE|CV_ALLOWLUA, zerotoone_cons_t, NULL), + CVAR_INIT ("cam2_turnfacingability", "0.125", CV_FLOAT|CV_SAVE|CV_ALLOWLUA, zerotoone_cons_t, NULL), }; consvar_t cv_cam_turnfacingspindash[2] = { - CVAR_INIT ("cam_turnfacingspindash", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL), - CVAR_INIT ("cam2_turnfacingspindash", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL), + CVAR_INIT ("cam_turnfacingspindash", "0.25", CV_FLOAT|CV_SAVE|CV_ALLOWLUA, zerotoone_cons_t, NULL), + CVAR_INIT ("cam2_turnfacingspindash", "0.25", CV_FLOAT|CV_SAVE|CV_ALLOWLUA, zerotoone_cons_t, NULL), }; consvar_t cv_cam_turnfacinginput[2] = { - CVAR_INIT ("cam_turnfacinginput", "0.375", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL), - CVAR_INIT ("cam2_turnfacinginput", "0.375", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL), + CVAR_INIT ("cam_turnfacinginput", "0.375", CV_FLOAT|CV_SAVE|CV_ALLOWLUA, zerotoone_cons_t, NULL), + CVAR_INIT ("cam2_turnfacinginput", "0.375", CV_FLOAT|CV_SAVE|CV_ALLOWLUA, zerotoone_cons_t, NULL), }; static CV_PossibleValue_t centertoggle_cons_t[] = {{0, "Hold"}, {1, "Toggle"}, {2, "Sticky Hold"}, {0, NULL}}; consvar_t cv_cam_centertoggle[2] = { - CVAR_INIT ("cam_centertoggle", "Hold", CV_SAVE, centertoggle_cons_t, NULL), - CVAR_INIT ("cam2_centertoggle", "Hold", CV_SAVE, centertoggle_cons_t, NULL), + CVAR_INIT ("cam_centertoggle", "Hold", CV_SAVE|CV_ALLOWLUA, centertoggle_cons_t, NULL), + CVAR_INIT ("cam2_centertoggle", "Hold", CV_SAVE|CV_ALLOWLUA, centertoggle_cons_t, NULL), }; static CV_PossibleValue_t lockedinput_cons_t[] = {{0, "Strafe"}, {1, "Turn"}, {0, NULL}}; consvar_t cv_cam_lockedinput[2] = { - CVAR_INIT ("cam_lockedinput", "Strafe", CV_SAVE, lockedinput_cons_t, NULL), - CVAR_INIT ("cam2_lockedinput", "Strafe", CV_SAVE, lockedinput_cons_t, NULL), + CVAR_INIT ("cam_lockedinput", "Strafe", CV_SAVE|CV_ALLOWLUA, lockedinput_cons_t, NULL), + CVAR_INIT ("cam2_lockedinput", "Strafe", CV_SAVE|CV_ALLOWLUA, lockedinput_cons_t, NULL), }; static CV_PossibleValue_t lockedassist_cons_t[] = { @@ -405,8 +405,8 @@ static CV_PossibleValue_t lockedassist_cons_t[] = { {0, NULL} }; consvar_t cv_cam_lockonboss[2] = { - CVAR_INIT ("cam_lockaimassist", "Full", CV_SAVE, lockedassist_cons_t, NULL), - CVAR_INIT ("cam2_lockaimassist", "Full", CV_SAVE, lockedassist_cons_t, NULL), + CVAR_INIT ("cam_lockaimassist", "Full", CV_SAVE|CV_ALLOWLUA, lockedassist_cons_t, NULL), + CVAR_INIT ("cam2_lockaimassist", "Full", CV_SAVE|CV_ALLOWLUA, lockedassist_cons_t, NULL), }; consvar_t cv_moveaxis = CVAR_INIT ("joyaxis_move", "Y-Axis", CV_SAVE, joyaxis_cons_t, NULL); diff --git a/src/mserv.c b/src/mserv.c index bff562c95..5e198c9fd 100644 --- a/src/mserv.c +++ b/src/mserv.c @@ -62,7 +62,7 @@ static CV_PossibleValue_t masterserver_update_rate_cons_t[] = { }; consvar_t cv_masterserver = CVAR_INIT ("masterserver", "https://mb.srb2.org/MS/0", CV_SAVE|CV_CALL, NULL, MasterServer_OnChange); -consvar_t cv_servername = CVAR_INIT ("servername", "SRB2 server", CV_SAVE|CV_NETVAR|CV_CALL|CV_NOINIT, NULL, Update_parameters); +consvar_t cv_servername = CVAR_INIT ("servername", "SRB2 server", CV_SAVE|CV_NETVAR|CV_CALL|CV_NOINIT|CV_ALLOWLUA, NULL, Update_parameters); consvar_t cv_masterserver_update_rate = CVAR_INIT ("masterserver_update_rate", "15", CV_SAVE|CV_CALL|CV_NOINIT, masterserver_update_rate_cons_t, Update_parameters); diff --git a/src/p_mobj.c b/src/p_mobj.c index 30e0183de..8646d13bf 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11228,10 +11228,10 @@ void P_RemoveSavegameMobj(mobj_t *mobj) } static CV_PossibleValue_t respawnitemtime_cons_t[] = {{1, "MIN"}, {300, "MAX"}, {0, NULL}}; -consvar_t cv_itemrespawntime = CVAR_INIT ("respawnitemtime", "30", CV_SAVE|CV_NETVAR|CV_CHEAT, respawnitemtime_cons_t, NULL); -consvar_t cv_itemrespawn = CVAR_INIT ("respawnitem", "On", CV_SAVE|CV_NETVAR, CV_OnOff, NULL); +consvar_t cv_itemrespawntime = CVAR_INIT ("respawnitemtime", "30", CV_SAVE|CV_NETVAR|CV_CHEAT|CV_ALLOWLUA, respawnitemtime_cons_t, NULL); +consvar_t cv_itemrespawn = CVAR_INIT ("respawnitem", "On", CV_SAVE|CV_NETVAR|CV_ALLOWLUA, CV_OnOff, NULL); static CV_PossibleValue_t flagtime_cons_t[] = {{0, "MIN"}, {300, "MAX"}, {0, NULL}}; -consvar_t cv_flagtime = CVAR_INIT ("flagtime", "30", CV_SAVE|CV_NETVAR|CV_CHEAT, flagtime_cons_t, NULL); +consvar_t cv_flagtime = CVAR_INIT ("flagtime", "30", CV_SAVE|CV_NETVAR|CV_CHEAT|CV_ALLOWLUA, flagtime_cons_t, NULL); void P_SpawnPrecipitation(void) { diff --git a/src/p_user.c b/src/p_user.c index 60a0f5106..11f5efe10 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9647,45 +9647,45 @@ static CV_PossibleValue_t rotation_cons_t[] = {{1, "MIN"}, {25, "MAX"}, {0, NULL static CV_PossibleValue_t CV_CamRotate[] = {{-720, "MIN"}, {720, "MAX"}, {0, NULL}}; static CV_PossibleValue_t multiplier_cons_t[] = {{0, "MIN"}, {3*FRACUNIT, "MAX"}, {0, NULL}}; -consvar_t cv_cam_dist = CVAR_INIT ("cam_curdist", "160", CV_FLOAT, NULL, NULL); -consvar_t cv_cam_height = CVAR_INIT ("cam_curheight", "25", CV_FLOAT, NULL, NULL); -consvar_t cv_cam_still = CVAR_INIT ("cam_still", "Off", 0, CV_OnOff, NULL); -consvar_t cv_cam_speed = CVAR_INIT ("cam_speed", "0.3", CV_FLOAT|CV_SAVE, CV_CamSpeed, NULL); -consvar_t cv_cam_rotate = CVAR_INIT ("cam_rotate", "0", CV_CALL|CV_NOINIT, CV_CamRotate, CV_CamRotate_OnChange); -consvar_t cv_cam_rotspeed = CVAR_INIT ("cam_rotspeed", "10", CV_SAVE, rotation_cons_t, NULL); -consvar_t cv_cam_turnmultiplier = CVAR_INIT ("cam_turnmultiplier", "0.75", CV_FLOAT|CV_SAVE, multiplier_cons_t, NULL); -consvar_t cv_cam_orbit = CVAR_INIT ("cam_orbit", "Off", CV_SAVE, CV_OnOff, NULL); -consvar_t cv_cam_adjust = CVAR_INIT ("cam_adjust", "On", CV_SAVE, CV_OnOff, NULL); -consvar_t cv_cam2_dist = CVAR_INIT ("cam2_curdist", "160", CV_FLOAT, NULL, NULL); -consvar_t cv_cam2_height = CVAR_INIT ("cam2_curheight", "25", CV_FLOAT, NULL, NULL); -consvar_t cv_cam2_still = CVAR_INIT ("cam2_still", "Off", 0, CV_OnOff, NULL); -consvar_t cv_cam2_speed = CVAR_INIT ("cam2_speed", "0.3", CV_FLOAT|CV_SAVE, CV_CamSpeed, NULL); -consvar_t cv_cam2_rotate = CVAR_INIT ("cam2_rotate", "0", CV_CALL|CV_NOINIT, CV_CamRotate, CV_CamRotate2_OnChange); -consvar_t cv_cam2_rotspeed = CVAR_INIT ("cam2_rotspeed", "10", CV_SAVE, rotation_cons_t, NULL); -consvar_t cv_cam2_turnmultiplier = CVAR_INIT ("cam2_turnmultiplier", "0.75", CV_FLOAT|CV_SAVE, multiplier_cons_t, NULL); -consvar_t cv_cam2_orbit = CVAR_INIT ("cam2_orbit", "Off", CV_SAVE, CV_OnOff, NULL); -consvar_t cv_cam2_adjust = CVAR_INIT ("cam2_adjust", "On", CV_SAVE, CV_OnOff, NULL); +consvar_t cv_cam_dist = CVAR_INIT ("cam_curdist", "160", CV_FLOAT|CV_ALLOWLUA, NULL, NULL); +consvar_t cv_cam_height = CVAR_INIT ("cam_curheight", "25", CV_FLOAT|CV_ALLOWLUA, NULL, NULL); +consvar_t cv_cam_still = CVAR_INIT ("cam_still", "Off", CV_ALLOWLUA, CV_OnOff, NULL); +consvar_t cv_cam_speed = CVAR_INIT ("cam_speed", "0.3", CV_FLOAT|CV_SAVE|CV_ALLOWLUA, CV_CamSpeed, NULL); +consvar_t cv_cam_rotate = CVAR_INIT ("cam_rotate", "0", CV_CALL|CV_NOINIT|CV_ALLOWLUA, CV_CamRotate, CV_CamRotate_OnChange); +consvar_t cv_cam_rotspeed = CVAR_INIT ("cam_rotspeed", "10", CV_SAVE|CV_ALLOWLUA, rotation_cons_t, NULL); +consvar_t cv_cam_turnmultiplier = CVAR_INIT ("cam_turnmultiplier", "0.75", CV_FLOAT|CV_SAVE|CV_ALLOWLUA, multiplier_cons_t, NULL); +consvar_t cv_cam_orbit = CVAR_INIT ("cam_orbit", "Off", CV_SAVE|CV_ALLOWLUA, CV_OnOff, NULL); +consvar_t cv_cam_adjust = CVAR_INIT ("cam_adjust", "On", CV_SAVE|CV_ALLOWLUA, CV_OnOff, NULL); +consvar_t cv_cam2_dist = CVAR_INIT ("cam2_curdist", "160", CV_FLOAT|CV_ALLOWLUA, NULL, NULL); +consvar_t cv_cam2_height = CVAR_INIT ("cam2_curheight", "25", CV_FLOAT|CV_ALLOWLUA, NULL, NULL); +consvar_t cv_cam2_still = CVAR_INIT ("cam2_still", "Off", CV_ALLOWLUA, CV_OnOff, NULL); +consvar_t cv_cam2_speed = CVAR_INIT ("cam2_speed", "0.3", CV_FLOAT|CV_SAVE|CV_ALLOWLUA, CV_CamSpeed, NULL); +consvar_t cv_cam2_rotate = CVAR_INIT ("cam2_rotate", "0", CV_CALL|CV_NOINIT|CV_ALLOWLUA, CV_CamRotate, CV_CamRotate2_OnChange); +consvar_t cv_cam2_rotspeed = CVAR_INIT ("cam2_rotspeed", "10", CV_SAVE|CV_ALLOWLUA, rotation_cons_t, NULL); +consvar_t cv_cam2_turnmultiplier = CVAR_INIT ("cam2_turnmultiplier", "0.75", CV_FLOAT|CV_SAVE|CV_ALLOWLUA, multiplier_cons_t, NULL); +consvar_t cv_cam2_orbit = CVAR_INIT ("cam2_orbit", "Off", CV_SAVE|CV_ALLOWLUA, CV_OnOff, NULL); +consvar_t cv_cam2_adjust = CVAR_INIT ("cam2_adjust", "On", CV_SAVE|CV_ALLOWLUA, CV_OnOff, NULL); // [standard vs simple][p1 or p2] consvar_t cv_cam_savedist[2][2] = { { // standard - CVAR_INIT ("cam_dist", "192", CV_FLOAT|CV_SAVE|CV_CALL, NULL, CV_UpdateCamDist), - CVAR_INIT ("cam2_dist", "192", CV_FLOAT|CV_SAVE|CV_CALL, NULL, CV_UpdateCam2Dist), + CVAR_INIT ("cam_dist", "192", CV_FLOAT|CV_SAVE|CV_CALL|CV_ALLOWLUA, NULL, CV_UpdateCamDist), + CVAR_INIT ("cam2_dist", "192", CV_FLOAT|CV_SAVE|CV_CALL|CV_ALLOWLUA, NULL, CV_UpdateCam2Dist), }, { // simple - CVAR_INIT ("cam_simpledist", "256", CV_FLOAT|CV_SAVE|CV_CALL, NULL, CV_UpdateCamDist), - CVAR_INIT ("cam2_simpledist", "256", CV_FLOAT|CV_SAVE|CV_CALL, NULL, CV_UpdateCam2Dist), + CVAR_INIT ("cam_simpledist", "256", CV_FLOAT|CV_SAVE|CV_CALL|CV_ALLOWLUA, NULL, CV_UpdateCamDist), + CVAR_INIT ("cam2_simpledist", "256", CV_FLOAT|CV_SAVE|CV_CALL|CV_ALLOWLUA, NULL, CV_UpdateCam2Dist), } }; consvar_t cv_cam_saveheight[2][2] = { { // standard - CVAR_INIT ("cam_height", "40", CV_FLOAT|CV_SAVE|CV_CALL, NULL, CV_UpdateCamDist), - CVAR_INIT ("cam2_height", "40", CV_FLOAT|CV_SAVE|CV_CALL, NULL, CV_UpdateCam2Dist), + CVAR_INIT ("cam_height", "40", CV_FLOAT|CV_SAVE|CV_CALL|CV_ALLOWLUA, NULL, CV_UpdateCamDist), + CVAR_INIT ("cam2_height", "40", CV_FLOAT|CV_SAVE|CV_CALL|CV_ALLOWLUA, NULL, CV_UpdateCam2Dist), }, { // simple - CVAR_INIT ("cam_simpleheight", "60", CV_FLOAT|CV_SAVE|CV_CALL, NULL, CV_UpdateCamDist), - CVAR_INIT ("cam2_simpleheight", "60", CV_FLOAT|CV_SAVE|CV_CALL, NULL, CV_UpdateCam2Dist), + CVAR_INIT ("cam_simpleheight", "60", CV_FLOAT|CV_SAVE|CV_CALL|CV_ALLOWLUA, NULL, CV_UpdateCamDist), + CVAR_INIT ("cam2_simpleheight", "60", CV_FLOAT|CV_SAVE|CV_CALL|CV_ALLOWLUA, NULL, CV_UpdateCam2Dist), } }; diff --git a/src/r_main.c b/src/r_main.c index 187925408..19477103f 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -149,7 +149,7 @@ static void FlipCam2_OnChange(void); void SendWeaponPref(void); void SendWeaponPref2(void); -consvar_t cv_tailspickup = CVAR_INIT ("tailspickup", "On", CV_NETVAR, CV_OnOff, NULL); +consvar_t cv_tailspickup = CVAR_INIT ("tailspickup", "On", CV_NETVAR|CV_ALLOWLUA, CV_OnOff, NULL); consvar_t cv_chasecam = CVAR_INIT ("chasecam", "On", CV_CALL, CV_OnOff, ChaseCam_OnChange); consvar_t cv_chasecam2 = CVAR_INIT ("chasecam2", "On", CV_CALL, CV_OnOff, ChaseCam2_OnChange); consvar_t cv_flipcam = CVAR_INIT ("flipcam", "No", CV_SAVE|CV_CALL|CV_NOINIT, CV_YesNo, FlipCam_OnChange); @@ -158,8 +158,8 @@ consvar_t cv_flipcam2 = CVAR_INIT ("flipcam2", "No", CV_SAVE|CV_CALL|CV_NOINIT, consvar_t cv_shadow = CVAR_INIT ("shadow", "On", CV_SAVE, CV_OnOff, NULL); consvar_t cv_skybox = CVAR_INIT ("skybox", "On", CV_SAVE, CV_OnOff, NULL); consvar_t cv_ffloorclip = CVAR_INIT ("ffloorclip", "On", CV_SAVE, CV_OnOff, NULL); -consvar_t cv_allowmlook = CVAR_INIT ("allowmlook", "Yes", CV_NETVAR, CV_YesNo, NULL); -consvar_t cv_showhud = CVAR_INIT ("showhud", "Yes", CV_CALL, CV_YesNo, R_SetViewSize); +consvar_t cv_allowmlook = CVAR_INIT ("allowmlook", "Yes", CV_NETVAR|CV_ALLOWLUA, CV_YesNo, NULL); +consvar_t cv_showhud = CVAR_INIT ("showhud", "Yes", CV_CALL|CV_ALLOWLUA, CV_YesNo, R_SetViewSize); consvar_t cv_translucenthud = CVAR_INIT ("translucenthud", "10", CV_SAVE, translucenthud_cons_t, NULL); consvar_t cv_translucency = CVAR_INIT ("translucency", "On", CV_SAVE, CV_OnOff, NULL); From 0405df1a47aece4aa1b8c904cdd1d8b7f51ccf96 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 15 Mar 2023 11:57:39 -0700 Subject: [PATCH 110/586] Merge COM_SAFE with other COM flags Renames COM_SAFE to COM_LUA. --- src/command.c | 10 +++++----- src/command.h | 20 +++++++++----------- src/lua_consolelib.c | 4 ++-- 3 files changed, 16 insertions(+), 18 deletions(-) diff --git a/src/command.c b/src/command.c index 7ffa300b1..8659ce3a4 100644 --- a/src/command.c +++ b/src/command.c @@ -109,6 +109,7 @@ static cmdalias_t *com_alias; // aliases list // ========================================================================= static vsbuf_t com_text; // variable sized buffer +static com_flags_t com_flags = 0; /** Purges control characters out of some text. * @@ -141,7 +142,7 @@ COM_Purge (char *s, int *np) * \param ptext The text to add. * \sa COM_BufInsertTextEx */ -void COM_BufAddTextEx(const char *ptext, int flags) +void COM_BufAddTextEx(const char *ptext, com_flags_t flags) { int l; char *text; @@ -164,7 +165,7 @@ void COM_BufAddTextEx(const char *ptext, int flags) * \param ptext The text to execute. A newline is automatically added. * \sa COM_BufAddTextEx */ -void COM_BufInsertTextEx(const char *ptext, int flags) +void COM_BufInsertTextEx(const char *ptext, com_flags_t flags) { const INT32 old_wait = com_wait; @@ -320,7 +321,6 @@ static size_t com_argc; static char *com_argv[MAX_ARGS]; static const char *com_null_string = ""; static char *com_args = NULL; // current command args or NULL -static int com_flags; static void Got_NetVar(UINT8 **p, INT32 playernum); @@ -1124,7 +1124,7 @@ void VS_Write(vsbuf_t *buf, const void *data, size_t length) M_Memcpy(VS_GetSpace(buf, length), data, length); } -void VS_WriteEx(vsbuf_t *buf, const void *data, size_t length, int flags) +void VS_WriteEx(vsbuf_t *buf, const void *data, size_t length, com_flags_t flags) { char *p; p = VS_GetSpace(buf, 2 + length); @@ -2472,7 +2472,7 @@ void CV_SaveVariables(FILE *f) static boolean CV_Immutable(const consvar_t *var) { // Currently operating from Lua - if (com_flags & COM_SAFE) + if (com_flags & COM_LUA) { if (!(var->flags & CV_ALLOWLUA)) { diff --git a/src/command.h b/src/command.h index 48827f99f..ea5d525a7 100644 --- a/src/command.h +++ b/src/command.h @@ -20,19 +20,17 @@ // Command buffer & command execution //=================================== -/* Lua command registration flags. */ -enum +/* Command registration flags. */ +typedef enum { COM_ADMIN = 1, COM_SPLITSCREEN = 2, COM_LOCAL = 4, -}; -/* Command buffer flags. */ -enum -{ - COM_SAFE = 1, -}; + // COM_BufInsertText etc: can only access cvars + // with CV_ALLOWLUA set. + COM_LUA = 8, +} com_flags_t; typedef void (*com_func_t)(void); @@ -53,11 +51,11 @@ const char *COM_CompleteAlias(const char *partial, INT32 skips); // insert at queu (at end of other command) #define COM_BufAddText(s) COM_BufAddTextEx(s, 0) -void COM_BufAddTextEx(const char *btext, int flags); +void COM_BufAddTextEx(const char *btext, com_flags_t flags); // insert in head (before other command) #define COM_BufInsertText(s) COM_BufInsertTextEx(s, 0) -void COM_BufInsertTextEx(const char *btext, int flags); +void COM_BufInsertTextEx(const char *btext, com_flags_t flags); // don't bother inserting, just do immediately void COM_ImmedExecute(const char *ptext); @@ -89,7 +87,7 @@ void VS_Free(vsbuf_t *buf); void VS_Clear(vsbuf_t *buf); void *VS_GetSpace(vsbuf_t *buf, size_t length); void VS_Write(vsbuf_t *buf, const void *data, size_t length); -void VS_WriteEx(vsbuf_t *buf, const void *data, size_t length, int flags); +void VS_WriteEx(vsbuf_t *buf, const void *data, size_t length, com_flags_t flags); void VS_Print(vsbuf_t *buf, const char *data); // strcats onto the sizebuf //================== diff --git a/src/lua_consolelib.c b/src/lua_consolelib.c index f5e98e920..43dde280d 100644 --- a/src/lua_consolelib.c +++ b/src/lua_consolelib.c @@ -253,7 +253,7 @@ static int lib_comBufAddText(lua_State *L) plr = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); if (plr && plr != &players[consoleplayer]) return 0; - COM_BufAddTextEx(va("%s\n", luaL_checkstring(L, 2)), COM_SAFE); + COM_BufAddTextEx(va("%s\n", luaL_checkstring(L, 2)), COM_LUA); return 0; } @@ -269,7 +269,7 @@ static int lib_comBufInsertText(lua_State *L) plr = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); if (plr && plr != &players[consoleplayer]) return 0; - COM_BufInsertTextEx(va("%s\n", luaL_checkstring(L, 2)), COM_SAFE); + COM_BufInsertTextEx(va("%s\n", luaL_checkstring(L, 2)), COM_LUA); return 0; } From 8a6f2e568bf28a3732b631886fb04daf438ba2d8 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 15 Mar 2023 15:53:40 -0700 Subject: [PATCH 111/586] Add a flags parameter to COM_AddCommand --- src/command.c | 25 ++++---- src/command.h | 2 +- src/console.c | 4 +- src/d_clisrv.c | 26 ++++----- src/d_netcmd.c | 146 +++++++++++++++++++++++----------------------- src/hu_stuff.c | 8 +-- src/m_menu.c | 2 +- src/mserv.c | 4 +- src/s_sound.c | 4 +- src/sdl/i_video.c | 8 +-- src/z_zone.c | 4 +- 11 files changed, 118 insertions(+), 115 deletions(-) diff --git a/src/command.c b/src/command.c index 8659ce3a4..3d3271ddb 100644 --- a/src/command.c +++ b/src/command.c @@ -312,6 +312,7 @@ typedef struct xcommand_s const char *name; struct xcommand_s *next; com_func_t function; + com_flags_t flags; } xcommand_t; static xcommand_t *com_commands = NULL; // current commands @@ -332,16 +333,16 @@ void COM_Init(void) VS_Alloc(&com_text, COM_BUF_SIZE); // add standard commands - COM_AddCommand("alias", COM_Alias_f); - COM_AddCommand("echo", COM_Echo_f); - COM_AddCommand("cecho", COM_CEcho_f); - COM_AddCommand("cechoflags", COM_CEchoFlags_f); - COM_AddCommand("cechoduration", COM_CEchoDuration_f); - COM_AddCommand("exec", COM_Exec_f); - COM_AddCommand("wait", COM_Wait_f); - COM_AddCommand("help", COM_Help_f); - COM_AddCommand("toggle", COM_Toggle_f); - COM_AddCommand("add", COM_Add_f); + COM_AddCommand("alias", COM_Alias_f, 0); + COM_AddCommand("echo", COM_Echo_f, 0); + COM_AddCommand("cecho", COM_CEcho_f, 0); + COM_AddCommand("cechoflags", COM_CEchoFlags_f, 0); + COM_AddCommand("cechoduration", COM_CEchoDuration_f, 0); + COM_AddCommand("exec", COM_Exec_f, 0); + COM_AddCommand("wait", COM_Wait_f, 0); + COM_AddCommand("help", COM_Help_f, 0); + COM_AddCommand("toggle", COM_Toggle_f, 0); + COM_AddCommand("add", COM_Add_f, 0); RegisterNetXCmd(XD_NETVAR, Got_NetVar); } @@ -480,7 +481,7 @@ static void COM_TokenizeString(char *ptext) * \param name Name of the command. * \param func Function called when the command is run. */ -void COM_AddCommand(const char *name, com_func_t func) +void COM_AddCommand(const char *name, com_func_t func, com_flags_t flags) { xcommand_t *cmd; @@ -510,6 +511,7 @@ void COM_AddCommand(const char *name, com_func_t func) cmd = ZZ_Alloc(sizeof *cmd); cmd->name = name; cmd->function = func; + cmd->flags = flags; cmd->next = com_commands; com_commands = cmd; } @@ -542,6 +544,7 @@ int COM_AddLuaCommand(const char *name) cmd = ZZ_Alloc(sizeof *cmd); cmd->name = name; cmd->function = COM_Lua_f; + cmd->flags = 0; cmd->next = com_commands; com_commands = cmd; return 0; diff --git a/src/command.h b/src/command.h index ea5d525a7..93adfd418 100644 --- a/src/command.h +++ b/src/command.h @@ -34,7 +34,7 @@ typedef enum typedef void (*com_func_t)(void); -void COM_AddCommand(const char *name, com_func_t func); +void COM_AddCommand(const char *name, com_func_t func, com_flags_t flags); int COM_AddLuaCommand(const char *name); size_t COM_Argc(void); diff --git a/src/console.c b/src/console.c index 40fb43121..9b464e31b 100644 --- a/src/console.c +++ b/src/console.c @@ -443,7 +443,7 @@ void CON_Init(void) // register our commands // - COM_AddCommand("cls", CONS_Clear_f); + COM_AddCommand("cls", CONS_Clear_f, 0); //COM_AddCommand("english", CONS_English_f); // set console full screen for game startup MAKE SURE VID_Init() done !!! Lock_state(); @@ -470,7 +470,7 @@ void CON_Init(void) CV_RegisterVar(&cons_height); CV_RegisterVar(&cons_backpic); CV_RegisterVar(&cons_backcolor); - COM_AddCommand("bind", CONS_Bind_f); + COM_AddCommand("bind", CONS_Bind_f, 0); } else { diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 19e6bf0f7..232b41bd0 100755 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -3537,22 +3537,22 @@ void D_ClientServerInit(void) 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); + COM_AddCommand("getplayernum", Command_GetPlayerNum, 0); + COM_AddCommand("kick", Command_Kick, 0); + COM_AddCommand("ban", Command_Ban, 0); + COM_AddCommand("banip", Command_BanIP, 0); + COM_AddCommand("clearbans", Command_ClearBans, 0); + COM_AddCommand("showbanlist", Command_ShowBan, 0); + COM_AddCommand("reloadbans", Command_ReloadBan, 0); + COM_AddCommand("connect", Command_connect, 0); + COM_AddCommand("nodes", Command_Nodes, 0); + COM_AddCommand("resendgamestate", Command_ResendGamestate, 0); #ifdef PACKETDROP - COM_AddCommand("drop", Command_Drop); - COM_AddCommand("droprate", Command_Droprate); + COM_AddCommand("drop", Command_Drop, 0); + COM_AddCommand("droprate", Command_Droprate, 0); #endif #ifdef _DEBUG - COM_AddCommand("numnodes", Command_Numnodes); + COM_AddCommand("numnodes", Command_Numnodes, 0); #endif #endif diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 67099e848..ef00ec431 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -464,57 +464,57 @@ void D_RegisterServerCommands(void) RegisterNetXCmd(XD_LUAFILE, Got_LuaFile); // Remote Administration - COM_AddCommand("password", Command_Changepassword_f); - COM_AddCommand("login", Command_Login_f); // useful in dedicated to kick off remote admin - COM_AddCommand("promote", Command_Verify_f); + COM_AddCommand("password", Command_Changepassword_f, 0); + COM_AddCommand("login", Command_Login_f, 0); // useful in dedicated to kick off remote admin + COM_AddCommand("promote", Command_Verify_f, 0); RegisterNetXCmd(XD_VERIFIED, Got_Verification); - COM_AddCommand("demote", Command_RemoveAdmin_f); + COM_AddCommand("demote", Command_RemoveAdmin_f, 0); RegisterNetXCmd(XD_DEMOTED, Got_Removal); - COM_AddCommand("motd", Command_MotD_f); + COM_AddCommand("motd", Command_MotD_f, 0); RegisterNetXCmd(XD_SETMOTD, Got_MotD_f); // For remote admin RegisterNetXCmd(XD_TEAMCHANGE, Got_Teamchange); - COM_AddCommand("serverchangeteam", Command_ServerTeamChange_f); + COM_AddCommand("serverchangeteam", Command_ServerTeamChange_f, 0); RegisterNetXCmd(XD_CLEARSCORES, Got_Clearscores); - COM_AddCommand("clearscores", Command_Clearscores_f); - COM_AddCommand("map", Command_Map_f); + COM_AddCommand("clearscores", Command_Clearscores_f, 0); + COM_AddCommand("map", Command_Map_f, 0); - COM_AddCommand("exitgame", Command_ExitGame_f); - COM_AddCommand("retry", Command_Retry_f); - COM_AddCommand("exitlevel", Command_ExitLevel_f); - COM_AddCommand("showmap", Command_Showmap_f); - COM_AddCommand("mapmd5", Command_Mapmd5_f); + COM_AddCommand("exitgame", Command_ExitGame_f, 0); + COM_AddCommand("retry", Command_Retry_f, 0); + COM_AddCommand("exitlevel", Command_ExitLevel_f, 0); + COM_AddCommand("showmap", Command_Showmap_f, 0); + COM_AddCommand("mapmd5", Command_Mapmd5_f, 0); - COM_AddCommand("addfolder", Command_Addfolder); - COM_AddCommand("addfile", Command_Addfile); - COM_AddCommand("listwad", Command_ListWADS_f); + COM_AddCommand("addfolder", Command_Addfolder, 0); + COM_AddCommand("addfile", Command_Addfile, 0); + COM_AddCommand("listwad", Command_ListWADS_f, 0); - COM_AddCommand("runsoc", Command_RunSOC); - COM_AddCommand("pause", Command_Pause); - COM_AddCommand("suicide", Command_Suicide); + COM_AddCommand("runsoc", Command_RunSOC, 0); + COM_AddCommand("pause", Command_Pause, 0); + COM_AddCommand("suicide", Command_Suicide, 0); - COM_AddCommand("gametype", Command_ShowGametype_f); - COM_AddCommand("version", Command_Version_f); + COM_AddCommand("gametype", Command_ShowGametype_f, 0); + COM_AddCommand("version", Command_Version_f, 0); #ifdef UPDATE_ALERT - COM_AddCommand("mod_details", Command_ModDetails_f); + COM_AddCommand("mod_details", Command_ModDetails_f, 0); #endif - COM_AddCommand("quit", Command_Quit_f); + COM_AddCommand("quit", Command_Quit_f, 0); - COM_AddCommand("saveconfig", Command_SaveConfig_f); - COM_AddCommand("loadconfig", Command_LoadConfig_f); - COM_AddCommand("changeconfig", Command_ChangeConfig_f); - COM_AddCommand("isgamemodified", Command_Isgamemodified_f); // test - COM_AddCommand("showscores", Command_ShowScores_f); - COM_AddCommand("showtime", Command_ShowTime_f); - COM_AddCommand("cheats", Command_Cheats_f); // test + COM_AddCommand("saveconfig", Command_SaveConfig_f, 0); + COM_AddCommand("loadconfig", Command_LoadConfig_f, 0); + COM_AddCommand("changeconfig", Command_ChangeConfig_f, 0); + COM_AddCommand("isgamemodified", Command_Isgamemodified_f, 0); // test + COM_AddCommand("showscores", Command_ShowScores_f, 0); + COM_AddCommand("showtime", Command_ShowTime_f, 0); + COM_AddCommand("cheats", Command_Cheats_f, 0); // test #ifdef _DEBUG - COM_AddCommand("togglemodified", Command_Togglemodified_f); - COM_AddCommand("archivetest", Command_Archivetest_f); + COM_AddCommand("togglemodified", Command_Togglemodified_f, 0); + COM_AddCommand("archivetest", Command_Archivetest_f, 0); #endif - COM_AddCommand("downloads", Command_Downloads_f); + COM_AddCommand("downloads", Command_Downloads_f, 0); // for master server connection AddMServCommands(); @@ -601,7 +601,7 @@ void D_RegisterServerCommands(void) CV_RegisterVar(&cv_blamecfail); #endif - COM_AddCommand("ping", Command_Ping_f); + COM_AddCommand("ping", Command_Ping_f, 0); CV_RegisterVar(&cv_nettimeout); CV_RegisterVar(&cv_jointimeout); @@ -645,25 +645,25 @@ void D_RegisterClientCommands(void) if (dedicated) return; - COM_AddCommand("numthinkers", Command_Numthinkers_f); - COM_AddCommand("countmobjs", Command_CountMobjs_f); + COM_AddCommand("numthinkers", Command_Numthinkers_f, 0); + COM_AddCommand("countmobjs", Command_CountMobjs_f, 0); - COM_AddCommand("changeteam", Command_Teamchange_f); - COM_AddCommand("changeteam2", Command_Teamchange2_f); + COM_AddCommand("changeteam", Command_Teamchange_f, 0); + COM_AddCommand("changeteam2", Command_Teamchange2_f, 0); - COM_AddCommand("playdemo", Command_Playdemo_f); - COM_AddCommand("timedemo", Command_Timedemo_f); - COM_AddCommand("stopdemo", Command_Stopdemo_f); - COM_AddCommand("playintro", Command_Playintro_f); + COM_AddCommand("playdemo", Command_Playdemo_f, 0); + COM_AddCommand("timedemo", Command_Timedemo_f, 0); + COM_AddCommand("stopdemo", Command_Stopdemo_f, 0); + COM_AddCommand("playintro", Command_Playintro_f, 0); - COM_AddCommand("resetcamera", Command_ResetCamera_f); + COM_AddCommand("resetcamera", Command_ResetCamera_f, 0); - COM_AddCommand("setcontrol", Command_Setcontrol_f); - COM_AddCommand("setcontrol2", Command_Setcontrol2_f); + COM_AddCommand("setcontrol", Command_Setcontrol_f, 0); + COM_AddCommand("setcontrol2", Command_Setcontrol2_f, 0); - COM_AddCommand("screenshot", M_ScreenShot); - COM_AddCommand("startmovie", Command_StartMovie_f); - COM_AddCommand("stopmovie", Command_StopMovie_f); + COM_AddCommand("screenshot", M_ScreenShot, 0); + COM_AddCommand("startmovie", Command_StartMovie_f, 0); + COM_AddCommand("stopmovie", Command_StopMovie_f, 0); CV_RegisterVar(&cv_screenshot_option); CV_RegisterVar(&cv_screenshot_folder); @@ -725,7 +725,7 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_ghost_last); CV_RegisterVar(&cv_ghost_guest); - COM_AddCommand("displayplayer", Command_Displayplayer_f); + COM_AddCommand("displayplayer", Command_Displayplayer_f, 0); // FIXME: not to be here.. but needs be done for config loading CV_RegisterVar(&cv_globalgamma); @@ -881,7 +881,7 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_ps_descriptor); // ingame object placing - COM_AddCommand("objectplace", Command_ObjectPlace_f); + COM_AddCommand("objectplace", Command_ObjectPlace_f, 0); //COM_AddCommand("writethings", Command_Writethings_f); CV_RegisterVar(&cv_speed); CV_RegisterVar(&cv_opflags); @@ -893,32 +893,32 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_freedemocamera); // add cheat commands - COM_AddCommand("noclip", Command_CheatNoClip_f); - COM_AddCommand("god", Command_CheatGod_f); - COM_AddCommand("notarget", Command_CheatNoTarget_f); - COM_AddCommand("getallemeralds", Command_Getallemeralds_f); - COM_AddCommand("resetemeralds", Command_Resetemeralds_f); - COM_AddCommand("setrings", Command_Setrings_f); - COM_AddCommand("setlives", Command_Setlives_f); - COM_AddCommand("setcontinues", Command_Setcontinues_f); - COM_AddCommand("devmode", Command_Devmode_f); - COM_AddCommand("savecheckpoint", Command_Savecheckpoint_f); - COM_AddCommand("scale", Command_Scale_f); - COM_AddCommand("gravflip", Command_Gravflip_f); - COM_AddCommand("hurtme", Command_Hurtme_f); - COM_AddCommand("jumptoaxis", Command_JumpToAxis_f); - COM_AddCommand("charability", Command_Charability_f); - COM_AddCommand("charspeed", Command_Charspeed_f); - COM_AddCommand("teleport", Command_Teleport_f); - COM_AddCommand("rteleport", Command_RTeleport_f); - COM_AddCommand("skynum", Command_Skynum_f); - COM_AddCommand("weather", Command_Weather_f); - COM_AddCommand("toggletwod", Command_Toggletwod_f); + COM_AddCommand("noclip", Command_CheatNoClip_f, 0); + COM_AddCommand("god", Command_CheatGod_f, 0); + COM_AddCommand("notarget", Command_CheatNoTarget_f, 0); + COM_AddCommand("getallemeralds", Command_Getallemeralds_f, 0); + COM_AddCommand("resetemeralds", Command_Resetemeralds_f, 0); + COM_AddCommand("setrings", Command_Setrings_f, 0); + COM_AddCommand("setlives", Command_Setlives_f, 0); + COM_AddCommand("setcontinues", Command_Setcontinues_f, 0); + COM_AddCommand("devmode", Command_Devmode_f, 0); + COM_AddCommand("savecheckpoint", Command_Savecheckpoint_f, 0); + COM_AddCommand("scale", Command_Scale_f, 0); + COM_AddCommand("gravflip", Command_Gravflip_f, 0); + COM_AddCommand("hurtme", Command_Hurtme_f, 0); + COM_AddCommand("jumptoaxis", Command_JumpToAxis_f, 0); + COM_AddCommand("charability", Command_Charability_f, 0); + COM_AddCommand("charspeed", Command_Charspeed_f, 0); + COM_AddCommand("teleport", Command_Teleport_f, 0); + COM_AddCommand("rteleport", Command_RTeleport_f, 0); + COM_AddCommand("skynum", Command_Skynum_f, 0); + COM_AddCommand("weather", Command_Weather_f, 0); + COM_AddCommand("toggletwod", Command_Toggletwod_f, 0); #ifdef _DEBUG - COM_AddCommand("causecfail", Command_CauseCfail_f); + COM_AddCommand("causecfail", Command_CauseCfail_f, 0); #endif #ifdef LUA_ALLOW_BYTECODE - COM_AddCommand("dumplua", Command_Dumplua_f); + COM_AddCommand("dumplua", Command_Dumplua_f, 0); #endif } diff --git a/src/hu_stuff.c b/src/hu_stuff.c index c037abcd7..2b1cbfcaf 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -328,10 +328,10 @@ void HU_LoadGraphics(void) void HU_Init(void) { #ifndef NONET - COM_AddCommand("say", Command_Say_f); - COM_AddCommand("sayto", Command_Sayto_f); - COM_AddCommand("sayteam", Command_Sayteam_f); - COM_AddCommand("csay", Command_CSay_f); + COM_AddCommand("say", Command_Say_f, 0); + COM_AddCommand("sayto", Command_Sayto_f, 0); + COM_AddCommand("sayteam", Command_Sayteam_f, 0); + COM_AddCommand("csay", Command_CSay_f, 0); RegisterNetXCmd(XD_SAY, Got_Saycmd); #endif diff --git a/src/m_menu.c b/src/m_menu.c index 82d078062..9ca21841b 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -3909,7 +3909,7 @@ void M_Init(void) { int i; - COM_AddCommand("manual", Command_Manual_f); + COM_AddCommand("manual", Command_Manual_f, 0); CV_RegisterVar(&cv_nextmap); CV_RegisterVar(&cv_newgametype); diff --git a/src/mserv.c b/src/mserv.c index 5e198c9fd..376774b23 100644 --- a/src/mserv.c +++ b/src/mserv.c @@ -97,8 +97,8 @@ void AddMServCommands(void) CV_RegisterVar(&cv_masterserver_token); CV_RegisterVar(&cv_servername); #ifdef MASTERSERVER - COM_AddCommand("listserv", Command_Listserv_f); - COM_AddCommand("masterserver_update", Update_parameters); // allows people to updates manually in case you were delisted by accident + COM_AddCommand("listserv", Command_Listserv_f, 0); + COM_AddCommand("masterserver_update", Update_parameters, 0); // allows people to updates manually in case you were delisted by accident #endif #endif } diff --git a/src/s_sound.c b/src/s_sound.c index f28a77a80..c230ea3c4 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -289,8 +289,8 @@ void S_RegisterSoundStuff(void) CV_RegisterVar(&cv_miditimiditypath); #endif - COM_AddCommand("tunes", Command_Tunes_f); - COM_AddCommand("restartaudio", Command_RestartAudio_f); + COM_AddCommand("tunes", Command_Tunes_f, 0); + COM_AddCommand("restartaudio", Command_RestartAudio_f, 0); } static void SetChannelsNum(void) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 02f0e462e..2ad97108c 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1784,10 +1784,10 @@ void I_StartupGraphics(void) if (graphics_started) return; - COM_AddCommand ("vid_nummodes", VID_Command_NumModes_f); - COM_AddCommand ("vid_info", VID_Command_Info_f); - COM_AddCommand ("vid_modelist", VID_Command_ModeList_f); - COM_AddCommand ("vid_mode", VID_Command_Mode_f); + COM_AddCommand ("vid_nummodes", VID_Command_NumModes_f, 0); + COM_AddCommand ("vid_info", VID_Command_Info_f, 0); + COM_AddCommand ("vid_modelist", VID_Command_ModeList_f, 0); + COM_AddCommand ("vid_mode", VID_Command_Mode_f, 0); CV_RegisterVar (&cv_vidwait); CV_RegisterVar (&cv_stretch); CV_RegisterVar (&cv_alwaysgrabmouse); diff --git a/src/z_zone.c b/src/z_zone.c index b949730e3..d0722b84c 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -116,10 +116,10 @@ void Z_Init(void) CONS_Printf("System memory: %uMB - Free: %uMB\n", total>>20, memfree); // Note: This allocates memory. Watch out. - COM_AddCommand("memfree", Command_Memfree_f); + COM_AddCommand("memfree", Command_Memfree_f, 0); #ifdef ZDEBUG - COM_AddCommand("memdump", Command_Memdump_f); + COM_AddCommand("memdump", Command_Memdump_f, 0); #endif } From 49f1462f751e9681ccf4cde44c18cc7040fb094d Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 15 Mar 2023 16:32:28 -0700 Subject: [PATCH 112/586] Only let Lua run commands registered with COM_LUA --- src/command.c | 8 +++++++- src/command.h | 2 ++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/command.c b/src/command.c index 3d3271ddb..c2926c473 100644 --- a/src/command.c +++ b/src/command.c @@ -544,7 +544,7 @@ int COM_AddLuaCommand(const char *name) cmd = ZZ_Alloc(sizeof *cmd); cmd->name = name; cmd->function = COM_Lua_f; - cmd->flags = 0; + cmd->flags = COM_LUA; cmd->next = com_commands; com_commands = cmd; return 0; @@ -640,6 +640,12 @@ static void COM_ExecuteString(char *ptext) { if (!stricmp(com_argv[0], cmd->name)) //case insensitive now that we have lower and uppercase! { + if ((com_flags & COM_LUA) && !(cmd->flags & COM_LUA)) + { + CONS_Alert(CONS_WARNING, "Command '%s' cannot be run from Lua.\n", cmd->name); + return; + } + cmd->function(); return; } diff --git a/src/command.h b/src/command.h index 93adfd418..55b5ed8c6 100644 --- a/src/command.h +++ b/src/command.h @@ -29,6 +29,8 @@ typedef enum // COM_BufInsertText etc: can only access cvars // with CV_ALLOWLUA set. + // COM_AddCommand: without this flag, the command + // CANNOT be run from Lua. COM_LUA = 8, } com_flags_t; From 07e4497320512d0fd6c14f32c2e04b0405bb0487 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 15 Mar 2023 17:21:13 -0700 Subject: [PATCH 113/586] Add COM_LUA to a bunch of commands These commands be run from Lua: - add - addfile - addfolder - archivetest - ban - banip - causecfail - cecho - cechoduration - cechoflags - changeteam - changeteam2 - charability - charspeed - cheats - clearbans - clearscores - connect - countmobjs - csay - demote - devmode - displayplayer - downloads - drop - droprate - dumplua - echo - exitgame - exitlevel - gametype - getallemeralds - getplayernum - god - gravflip - help - hurtme - isgamemodified - jumptoaxis - kick - listwad - login - manual - map - mapmd5 - masterserver_update - memdump - memfree - mod_details - motd - noclip - nodes - notarget - numnodes - numthinkers - objectplace - password - pause - ping - playintro - promote - quit - reloadbans - resendgamestate - resetcamera - resetemeralds - restartaudio - retry - rteleport - runsoc - savecheckpoint - say - sayteam - sayto - scale - screenshot - serverchangeteam - setcontinues - setlives - setrings - showbanlist - showmap - showscores - showtime - skynum - startmovie - stopdemo - stopmovie - suicide - teleport - toggle - togglemodified - toggletwod - tunes - version - vid_info - vid_modelist - vid_nummodes - weather --- src/command.c | 14 ++--- src/d_clisrv.c | 26 ++++----- src/d_netcmd.c | 132 +++++++++++++++++++++++----------------------- src/hu_stuff.c | 8 +-- src/m_menu.c | 2 +- src/mserv.c | 2 +- src/s_sound.c | 4 +- src/sdl/i_video.c | 6 +-- src/z_zone.c | 4 +- 9 files changed, 99 insertions(+), 99 deletions(-) diff --git a/src/command.c b/src/command.c index c2926c473..bef6e2cdd 100644 --- a/src/command.c +++ b/src/command.c @@ -334,15 +334,15 @@ void COM_Init(void) // add standard commands COM_AddCommand("alias", COM_Alias_f, 0); - COM_AddCommand("echo", COM_Echo_f, 0); - COM_AddCommand("cecho", COM_CEcho_f, 0); - COM_AddCommand("cechoflags", COM_CEchoFlags_f, 0); - COM_AddCommand("cechoduration", COM_CEchoDuration_f, 0); + COM_AddCommand("echo", COM_Echo_f, COM_LUA); + COM_AddCommand("cecho", COM_CEcho_f, COM_LUA); + COM_AddCommand("cechoflags", COM_CEchoFlags_f, COM_LUA); + COM_AddCommand("cechoduration", COM_CEchoDuration_f, COM_LUA); COM_AddCommand("exec", COM_Exec_f, 0); COM_AddCommand("wait", COM_Wait_f, 0); - COM_AddCommand("help", COM_Help_f, 0); - COM_AddCommand("toggle", COM_Toggle_f, 0); - COM_AddCommand("add", COM_Add_f, 0); + COM_AddCommand("help", COM_Help_f, COM_LUA); + COM_AddCommand("toggle", COM_Toggle_f, COM_LUA); + COM_AddCommand("add", COM_Add_f, COM_LUA); RegisterNetXCmd(XD_NETVAR, Got_NetVar); } diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 232b41bd0..9740c7f22 100755 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -3537,22 +3537,22 @@ void D_ClientServerInit(void) VERSION/100, VERSION%100, SUBVERSION)); #ifndef NONET - COM_AddCommand("getplayernum", Command_GetPlayerNum, 0); - COM_AddCommand("kick", Command_Kick, 0); - COM_AddCommand("ban", Command_Ban, 0); - COM_AddCommand("banip", Command_BanIP, 0); - COM_AddCommand("clearbans", Command_ClearBans, 0); - COM_AddCommand("showbanlist", Command_ShowBan, 0); - COM_AddCommand("reloadbans", Command_ReloadBan, 0); - COM_AddCommand("connect", Command_connect, 0); - COM_AddCommand("nodes", Command_Nodes, 0); - COM_AddCommand("resendgamestate", Command_ResendGamestate, 0); + COM_AddCommand("getplayernum", Command_GetPlayerNum, COM_LUA); + COM_AddCommand("kick", Command_Kick, COM_LUA); + COM_AddCommand("ban", Command_Ban, COM_LUA); + COM_AddCommand("banip", Command_BanIP, COM_LUA); + COM_AddCommand("clearbans", Command_ClearBans, COM_LUA); + COM_AddCommand("showbanlist", Command_ShowBan, COM_LUA); + COM_AddCommand("reloadbans", Command_ReloadBan, COM_LUA); + COM_AddCommand("connect", Command_connect, COM_LUA); + COM_AddCommand("nodes", Command_Nodes, COM_LUA); + COM_AddCommand("resendgamestate", Command_ResendGamestate, COM_LUA); #ifdef PACKETDROP - COM_AddCommand("drop", Command_Drop, 0); - COM_AddCommand("droprate", Command_Droprate, 0); + COM_AddCommand("drop", Command_Drop, COM_LUA); + COM_AddCommand("droprate", Command_Droprate, COM_LUA); #endif #ifdef _DEBUG - COM_AddCommand("numnodes", Command_Numnodes, 0); + COM_AddCommand("numnodes", Command_Numnodes, COM_LUA); #endif #endif diff --git a/src/d_netcmd.c b/src/d_netcmd.c index ef00ec431..676b6e7a0 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -464,57 +464,57 @@ void D_RegisterServerCommands(void) RegisterNetXCmd(XD_LUAFILE, Got_LuaFile); // Remote Administration - COM_AddCommand("password", Command_Changepassword_f, 0); - COM_AddCommand("login", Command_Login_f, 0); // useful in dedicated to kick off remote admin - COM_AddCommand("promote", Command_Verify_f, 0); + COM_AddCommand("password", Command_Changepassword_f, COM_LUA); + COM_AddCommand("login", Command_Login_f, COM_LUA); // useful in dedicated to kick off remote admin + COM_AddCommand("promote", Command_Verify_f, COM_LUA); RegisterNetXCmd(XD_VERIFIED, Got_Verification); - COM_AddCommand("demote", Command_RemoveAdmin_f, 0); + COM_AddCommand("demote", Command_RemoveAdmin_f, COM_LUA); RegisterNetXCmd(XD_DEMOTED, Got_Removal); - COM_AddCommand("motd", Command_MotD_f, 0); + COM_AddCommand("motd", Command_MotD_f, COM_LUA); RegisterNetXCmd(XD_SETMOTD, Got_MotD_f); // For remote admin RegisterNetXCmd(XD_TEAMCHANGE, Got_Teamchange); - COM_AddCommand("serverchangeteam", Command_ServerTeamChange_f, 0); + COM_AddCommand("serverchangeteam", Command_ServerTeamChange_f, COM_LUA); RegisterNetXCmd(XD_CLEARSCORES, Got_Clearscores); - COM_AddCommand("clearscores", Command_Clearscores_f, 0); - COM_AddCommand("map", Command_Map_f, 0); + COM_AddCommand("clearscores", Command_Clearscores_f, COM_LUA); + COM_AddCommand("map", Command_Map_f, COM_LUA); - COM_AddCommand("exitgame", Command_ExitGame_f, 0); - COM_AddCommand("retry", Command_Retry_f, 0); - COM_AddCommand("exitlevel", Command_ExitLevel_f, 0); - COM_AddCommand("showmap", Command_Showmap_f, 0); - COM_AddCommand("mapmd5", Command_Mapmd5_f, 0); + COM_AddCommand("exitgame", Command_ExitGame_f, COM_LUA); + COM_AddCommand("retry", Command_Retry_f, COM_LUA); + COM_AddCommand("exitlevel", Command_ExitLevel_f, COM_LUA); + COM_AddCommand("showmap", Command_Showmap_f, COM_LUA); + COM_AddCommand("mapmd5", Command_Mapmd5_f, COM_LUA); - COM_AddCommand("addfolder", Command_Addfolder, 0); - COM_AddCommand("addfile", Command_Addfile, 0); - COM_AddCommand("listwad", Command_ListWADS_f, 0); + COM_AddCommand("addfolder", Command_Addfolder, COM_LUA); + COM_AddCommand("addfile", Command_Addfile, COM_LUA); + COM_AddCommand("listwad", Command_ListWADS_f, COM_LUA); - COM_AddCommand("runsoc", Command_RunSOC, 0); - COM_AddCommand("pause", Command_Pause, 0); - COM_AddCommand("suicide", Command_Suicide, 0); + COM_AddCommand("runsoc", Command_RunSOC, COM_LUA); + COM_AddCommand("pause", Command_Pause, COM_LUA); + COM_AddCommand("suicide", Command_Suicide, COM_LUA); - COM_AddCommand("gametype", Command_ShowGametype_f, 0); - COM_AddCommand("version", Command_Version_f, 0); + COM_AddCommand("gametype", Command_ShowGametype_f, COM_LUA); + COM_AddCommand("version", Command_Version_f, COM_LUA); #ifdef UPDATE_ALERT - COM_AddCommand("mod_details", Command_ModDetails_f, 0); + COM_AddCommand("mod_details", Command_ModDetails_f, COM_LUA); #endif - COM_AddCommand("quit", Command_Quit_f, 0); + COM_AddCommand("quit", Command_Quit_f, COM_LUA); COM_AddCommand("saveconfig", Command_SaveConfig_f, 0); COM_AddCommand("loadconfig", Command_LoadConfig_f, 0); COM_AddCommand("changeconfig", Command_ChangeConfig_f, 0); - COM_AddCommand("isgamemodified", Command_Isgamemodified_f, 0); // test - COM_AddCommand("showscores", Command_ShowScores_f, 0); - COM_AddCommand("showtime", Command_ShowTime_f, 0); - COM_AddCommand("cheats", Command_Cheats_f, 0); // test + COM_AddCommand("isgamemodified", Command_Isgamemodified_f, COM_LUA); // test + COM_AddCommand("showscores", Command_ShowScores_f, COM_LUA); + COM_AddCommand("showtime", Command_ShowTime_f, COM_LUA); + COM_AddCommand("cheats", Command_Cheats_f, COM_LUA); // test #ifdef _DEBUG - COM_AddCommand("togglemodified", Command_Togglemodified_f, 0); - COM_AddCommand("archivetest", Command_Archivetest_f, 0); + COM_AddCommand("togglemodified", Command_Togglemodified_f, COM_LUA); + COM_AddCommand("archivetest", Command_Archivetest_f, COM_LUA); #endif - COM_AddCommand("downloads", Command_Downloads_f, 0); + COM_AddCommand("downloads", Command_Downloads_f, COM_LUA); // for master server connection AddMServCommands(); @@ -601,7 +601,7 @@ void D_RegisterServerCommands(void) CV_RegisterVar(&cv_blamecfail); #endif - COM_AddCommand("ping", Command_Ping_f, 0); + COM_AddCommand("ping", Command_Ping_f, COM_LUA); CV_RegisterVar(&cv_nettimeout); CV_RegisterVar(&cv_jointimeout); @@ -645,25 +645,25 @@ void D_RegisterClientCommands(void) if (dedicated) return; - COM_AddCommand("numthinkers", Command_Numthinkers_f, 0); - COM_AddCommand("countmobjs", Command_CountMobjs_f, 0); + COM_AddCommand("numthinkers", Command_Numthinkers_f, COM_LUA); + COM_AddCommand("countmobjs", Command_CountMobjs_f, COM_LUA); - COM_AddCommand("changeteam", Command_Teamchange_f, 0); - COM_AddCommand("changeteam2", Command_Teamchange2_f, 0); + COM_AddCommand("changeteam", Command_Teamchange_f, COM_LUA); + COM_AddCommand("changeteam2", Command_Teamchange2_f, COM_LUA); COM_AddCommand("playdemo", Command_Playdemo_f, 0); COM_AddCommand("timedemo", Command_Timedemo_f, 0); - COM_AddCommand("stopdemo", Command_Stopdemo_f, 0); - COM_AddCommand("playintro", Command_Playintro_f, 0); + COM_AddCommand("stopdemo", Command_Stopdemo_f, COM_LUA); + COM_AddCommand("playintro", Command_Playintro_f, COM_LUA); - COM_AddCommand("resetcamera", Command_ResetCamera_f, 0); + COM_AddCommand("resetcamera", Command_ResetCamera_f, COM_LUA); COM_AddCommand("setcontrol", Command_Setcontrol_f, 0); COM_AddCommand("setcontrol2", Command_Setcontrol2_f, 0); - COM_AddCommand("screenshot", M_ScreenShot, 0); - COM_AddCommand("startmovie", Command_StartMovie_f, 0); - COM_AddCommand("stopmovie", Command_StopMovie_f, 0); + COM_AddCommand("screenshot", M_ScreenShot, COM_LUA); + COM_AddCommand("startmovie", Command_StartMovie_f, COM_LUA); + COM_AddCommand("stopmovie", Command_StopMovie_f, COM_LUA); CV_RegisterVar(&cv_screenshot_option); CV_RegisterVar(&cv_screenshot_folder); @@ -725,7 +725,7 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_ghost_last); CV_RegisterVar(&cv_ghost_guest); - COM_AddCommand("displayplayer", Command_Displayplayer_f, 0); + COM_AddCommand("displayplayer", Command_Displayplayer_f, COM_LUA); // FIXME: not to be here.. but needs be done for config loading CV_RegisterVar(&cv_globalgamma); @@ -881,7 +881,7 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_ps_descriptor); // ingame object placing - COM_AddCommand("objectplace", Command_ObjectPlace_f, 0); + COM_AddCommand("objectplace", Command_ObjectPlace_f, COM_LUA); //COM_AddCommand("writethings", Command_Writethings_f); CV_RegisterVar(&cv_speed); CV_RegisterVar(&cv_opflags); @@ -893,32 +893,32 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_freedemocamera); // add cheat commands - COM_AddCommand("noclip", Command_CheatNoClip_f, 0); - COM_AddCommand("god", Command_CheatGod_f, 0); - COM_AddCommand("notarget", Command_CheatNoTarget_f, 0); - COM_AddCommand("getallemeralds", Command_Getallemeralds_f, 0); - COM_AddCommand("resetemeralds", Command_Resetemeralds_f, 0); - COM_AddCommand("setrings", Command_Setrings_f, 0); - COM_AddCommand("setlives", Command_Setlives_f, 0); - COM_AddCommand("setcontinues", Command_Setcontinues_f, 0); - COM_AddCommand("devmode", Command_Devmode_f, 0); - COM_AddCommand("savecheckpoint", Command_Savecheckpoint_f, 0); - COM_AddCommand("scale", Command_Scale_f, 0); - COM_AddCommand("gravflip", Command_Gravflip_f, 0); - COM_AddCommand("hurtme", Command_Hurtme_f, 0); - COM_AddCommand("jumptoaxis", Command_JumpToAxis_f, 0); - COM_AddCommand("charability", Command_Charability_f, 0); - COM_AddCommand("charspeed", Command_Charspeed_f, 0); - COM_AddCommand("teleport", Command_Teleport_f, 0); - COM_AddCommand("rteleport", Command_RTeleport_f, 0); - COM_AddCommand("skynum", Command_Skynum_f, 0); - COM_AddCommand("weather", Command_Weather_f, 0); - COM_AddCommand("toggletwod", Command_Toggletwod_f, 0); + COM_AddCommand("noclip", Command_CheatNoClip_f, COM_LUA); + COM_AddCommand("god", Command_CheatGod_f, COM_LUA); + COM_AddCommand("notarget", Command_CheatNoTarget_f, COM_LUA); + COM_AddCommand("getallemeralds", Command_Getallemeralds_f, COM_LUA); + COM_AddCommand("resetemeralds", Command_Resetemeralds_f, COM_LUA); + COM_AddCommand("setrings", Command_Setrings_f, COM_LUA); + COM_AddCommand("setlives", Command_Setlives_f, COM_LUA); + COM_AddCommand("setcontinues", Command_Setcontinues_f, COM_LUA); + COM_AddCommand("devmode", Command_Devmode_f, COM_LUA); + COM_AddCommand("savecheckpoint", Command_Savecheckpoint_f, COM_LUA); + COM_AddCommand("scale", Command_Scale_f, COM_LUA); + COM_AddCommand("gravflip", Command_Gravflip_f, COM_LUA); + COM_AddCommand("hurtme", Command_Hurtme_f, COM_LUA); + COM_AddCommand("jumptoaxis", Command_JumpToAxis_f, COM_LUA); + COM_AddCommand("charability", Command_Charability_f, COM_LUA); + COM_AddCommand("charspeed", Command_Charspeed_f, COM_LUA); + COM_AddCommand("teleport", Command_Teleport_f, COM_LUA); + COM_AddCommand("rteleport", Command_RTeleport_f, COM_LUA); + COM_AddCommand("skynum", Command_Skynum_f, COM_LUA); + COM_AddCommand("weather", Command_Weather_f, COM_LUA); + COM_AddCommand("toggletwod", Command_Toggletwod_f, COM_LUA); #ifdef _DEBUG - COM_AddCommand("causecfail", Command_CauseCfail_f, 0); + COM_AddCommand("causecfail", Command_CauseCfail_f, COM_LUA); #endif #ifdef LUA_ALLOW_BYTECODE - COM_AddCommand("dumplua", Command_Dumplua_f, 0); + COM_AddCommand("dumplua", Command_Dumplua_f, COM_LUA); #endif } diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 2b1cbfcaf..9322770fa 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -328,10 +328,10 @@ void HU_LoadGraphics(void) void HU_Init(void) { #ifndef NONET - COM_AddCommand("say", Command_Say_f, 0); - COM_AddCommand("sayto", Command_Sayto_f, 0); - COM_AddCommand("sayteam", Command_Sayteam_f, 0); - COM_AddCommand("csay", Command_CSay_f, 0); + COM_AddCommand("say", Command_Say_f, COM_LUA); + COM_AddCommand("sayto", Command_Sayto_f, COM_LUA); + COM_AddCommand("sayteam", Command_Sayteam_f, COM_LUA); + COM_AddCommand("csay", Command_CSay_f, COM_LUA); RegisterNetXCmd(XD_SAY, Got_Saycmd); #endif diff --git a/src/m_menu.c b/src/m_menu.c index 9ca21841b..82d21bc55 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -3909,7 +3909,7 @@ void M_Init(void) { int i; - COM_AddCommand("manual", Command_Manual_f, 0); + COM_AddCommand("manual", Command_Manual_f, COM_LUA); CV_RegisterVar(&cv_nextmap); CV_RegisterVar(&cv_newgametype); diff --git a/src/mserv.c b/src/mserv.c index 376774b23..64632016e 100644 --- a/src/mserv.c +++ b/src/mserv.c @@ -98,7 +98,7 @@ void AddMServCommands(void) CV_RegisterVar(&cv_servername); #ifdef MASTERSERVER COM_AddCommand("listserv", Command_Listserv_f, 0); - COM_AddCommand("masterserver_update", Update_parameters, 0); // allows people to updates manually in case you were delisted by accident + COM_AddCommand("masterserver_update", Update_parameters, COM_LUA); // allows people to updates manually in case you were delisted by accident #endif #endif } diff --git a/src/s_sound.c b/src/s_sound.c index c230ea3c4..c3e5626fa 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -289,8 +289,8 @@ void S_RegisterSoundStuff(void) CV_RegisterVar(&cv_miditimiditypath); #endif - COM_AddCommand("tunes", Command_Tunes_f, 0); - COM_AddCommand("restartaudio", Command_RestartAudio_f, 0); + COM_AddCommand("tunes", Command_Tunes_f, COM_LUA); + COM_AddCommand("restartaudio", Command_RestartAudio_f, COM_LUA); } static void SetChannelsNum(void) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 2ad97108c..57c6e48e9 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1784,9 +1784,9 @@ void I_StartupGraphics(void) if (graphics_started) return; - COM_AddCommand ("vid_nummodes", VID_Command_NumModes_f, 0); - COM_AddCommand ("vid_info", VID_Command_Info_f, 0); - COM_AddCommand ("vid_modelist", VID_Command_ModeList_f, 0); + COM_AddCommand ("vid_nummodes", VID_Command_NumModes_f, COM_LUA); + COM_AddCommand ("vid_info", VID_Command_Info_f, COM_LUA); + COM_AddCommand ("vid_modelist", VID_Command_ModeList_f, COM_LUA); COM_AddCommand ("vid_mode", VID_Command_Mode_f, 0); CV_RegisterVar (&cv_vidwait); CV_RegisterVar (&cv_stretch); diff --git a/src/z_zone.c b/src/z_zone.c index d0722b84c..6ffe9aedd 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -116,10 +116,10 @@ void Z_Init(void) CONS_Printf("System memory: %uMB - Free: %uMB\n", total>>20, memfree); // Note: This allocates memory. Watch out. - COM_AddCommand("memfree", Command_Memfree_f, 0); + COM_AddCommand("memfree", Command_Memfree_f, COM_LUA); #ifdef ZDEBUG - COM_AddCommand("memdump", Command_Memdump_f, 0); + COM_AddCommand("memdump", Command_Memdump_f, COM_LUA); #endif } From 1304874a8f4e92e0507505e7ace02861c5ece0d1 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Thu, 16 Mar 2023 19:17:42 +0100 Subject: [PATCH 114/586] Remove incorrect early returns in P_CheckSector --- src/p_map.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index 54e2003ba..1cdccbbcc 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -4509,7 +4509,6 @@ boolean P_CheckSector(sector_t *sector, boolean crunch) continue; PIT_ChangeSector(mo, true); - return nofit; } } } @@ -4539,10 +4538,7 @@ boolean P_CheckSector(sector_t *sector, boolean crunch) { n->visited = true; if (!(n->m_thing->flags & MF_NOBLOCKMAP)) - { PIT_ChangeSector(n->m_thing, true); - return nofit; - } break; } } while (n); @@ -4562,10 +4558,7 @@ boolean P_CheckSector(sector_t *sector, boolean crunch) { n->visited = true; // mark thing as processed if (!(n->m_thing->flags & MF_NOBLOCKMAP)) //jff 4/7/98 don't do these - { PIT_ChangeSector(n->m_thing, true); // process it - return nofit; - } break; // exit and start over } } while (n); // repeat from scratch until all things left are marked valid From 0667bf74feb7f1bf46304d04046608cbae27cba0 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Thu, 16 Mar 2023 19:30:21 +0100 Subject: [PATCH 115/586] Remove duplicated code in P_CheckSector --- src/p_map.c | 312 +++++++++++++++++++--------------------------------- 1 file changed, 111 insertions(+), 201 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index 1cdccbbcc..d5f6ce1c1 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -4340,14 +4340,118 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush) return true; } +static boolean P_CheckSectorHelper(sector_t *sector, boolean realcrush) +{ + msecnode_t *n; + size_t i; + + // Sal: This stupid function chain is required to fix polyobjects not being able to crush. + // Monster Iestyn: don't use P_CheckSector actually just look for objects in the blockmap instead + validcount++; + + for (i = 0; i < sector->linecount; i++) + { + if (sector->lines[i]->polyobj) + { + polyobj_t *po = sector->lines[i]->polyobj; + if (po->validcount == validcount) + continue; // skip if already checked + if (!(po->flags & POF_SOLID)) + continue; + if (po->lines[0]->backsector == sector) // Make sure you're currently checking the control sector + { + INT32 x, y; + po->validcount = validcount; + + for (y = po->blockbox[BOXBOTTOM]; y <= po->blockbox[BOXTOP]; ++y) + { + for (x = po->blockbox[BOXLEFT]; x <= po->blockbox[BOXRIGHT]; ++x) + { + mobj_t *mo; + + if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight) + continue; + + mo = blocklinks[y * bmapwidth + x]; + + for (; mo; mo = mo->bnext) + { + // Monster Iestyn: do we need to check if a mobj has already been checked? ...probably not I suspect + + if (!P_MobjInsidePolyobj(po, mo)) + continue; + + if (!PIT_ChangeSector(mo, realcrush) && !realcrush) + return false; + } + } + } + } + } + } + + if (sector->numattached) + { + sector_t *sec; + for (i = 0; i < sector->numattached; i++) + { + sec = §ors[sector->attached[i]]; + for (n = sec->touching_thinglist; n; n = n->m_thinglist_next) + n->visited = false; + + sec->moved = true; + + P_RecalcPrecipInSector(sec); + + if (!sector->attachedsolid[i]) + continue; + + do + { + for (n = sec->touching_thinglist; n; n = n->m_thinglist_next) + if (!n->visited) + { + n->visited = true; + if (!(n->m_thing->flags & MF_NOBLOCKMAP)) + { + if (!PIT_ChangeSector(n->m_thing, realcrush) && !realcrush) + return false; + } + break; + } + } while (n); + } + } + + // Mark all things invalid + sector->moved = true; + + for (n = sector->touching_thinglist; n; n = n->m_thinglist_next) + n->visited = false; + + do + { + for (n = sector->touching_thinglist; n; n = n->m_thinglist_next) // go through list + if (!n->visited) // unprocessed thing found + { + n->visited = true; // mark thing as processed + if (!(n->m_thing->flags & MF_NOBLOCKMAP)) //jff 4/7/98 don't do these + { + if (!PIT_ChangeSector(n->m_thing, realcrush) && !realcrush) // process it + return false; + } + break; // exit and start over + } + } while (n); // repeat from scratch until all things left are marked valid + + return true; +} + // // P_CheckSector // boolean P_CheckSector(sector_t *sector, boolean crunch) { - msecnode_t *n; - size_t i; - nofit = false; crushchange = crunch; @@ -4359,209 +4463,15 @@ boolean P_CheckSector(sector_t *sector, boolean crunch) // // killough 4/7/98: simplified to avoid using complicated counter - // First, let's see if anything will keep it from crushing. - - // Sal: This stupid function chain is required to fix polyobjects not being able to crush. - // Monster Iestyn: don't use P_CheckSector actually just look for objects in the blockmap instead - validcount++; - - for (i = 0; i < sector->linecount; i++) + if (!P_CheckSectorHelper(sector, false)) { - if (sector->lines[i]->polyobj) - { - polyobj_t *po = sector->lines[i]->polyobj; - if (po->validcount == validcount) - continue; // skip if already checked - if (!(po->flags & POF_SOLID)) - continue; - if (po->lines[0]->backsector == sector) // Make sure you're currently checking the control sector - { - INT32 x, y; - po->validcount = validcount; - - for (y = po->blockbox[BOXBOTTOM]; y <= po->blockbox[BOXTOP]; ++y) - { - for (x = po->blockbox[BOXLEFT]; x <= po->blockbox[BOXRIGHT]; ++x) - { - mobj_t *mo; - - if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight) - continue; - - mo = blocklinks[y * bmapwidth + x]; - - for (; mo; mo = mo->bnext) - { - // Monster Iestyn: do we need to check if a mobj has already been checked? ...probably not I suspect - - if (!P_MobjInsidePolyobj(po, mo)) - continue; - - if (!PIT_ChangeSector(mo, false)) - { - nofit = true; - return nofit; - } - } - } - } - } - } + nofit = true; + return nofit; } - if (sector->numattached) - { - sector_t *sec; - for (i = 0; i < sector->numattached; i++) - { - sec = §ors[sector->attached[i]]; - for (n = sec->touching_thinglist; n; n = n->m_thinglist_next) - n->visited = false; - - sec->moved = true; - - P_RecalcPrecipInSector(sec); - - if (!sector->attachedsolid[i]) - continue; - - do - { - for (n = sec->touching_thinglist; n; n = n->m_thinglist_next) - if (!n->visited) - { - n->visited = true; - if (!(n->m_thing->flags & MF_NOBLOCKMAP)) - { - if (!PIT_ChangeSector(n->m_thing, false)) - { - nofit = true; - return nofit; - } - } - break; - } - } while (n); - } - } - - // Mark all things invalid - sector->moved = true; - - for (n = sector->touching_thinglist; n; n = n->m_thinglist_next) - n->visited = false; - - do - { - for (n = sector->touching_thinglist; n; n = n->m_thinglist_next) // go through list - if (!n->visited) // unprocessed thing found - { - n->visited = true; // mark thing as processed - if (!(n->m_thing->flags & MF_NOBLOCKMAP)) //jff 4/7/98 don't do these - { - if (!PIT_ChangeSector(n->m_thing, false)) // process it - { - nofit = true; - return nofit; - } - } - break; // exit and start over - } - } while (n); // repeat from scratch until all things left are marked valid - // Nothing blocked us, so lets crush for real! - - // Sal: This stupid function chain is required to fix polyobjects not being able to crush. - // Monster Iestyn: don't use P_CheckSector actually just look for objects in the blockmap instead - validcount++; - - for (i = 0; i < sector->linecount; i++) - { - if (sector->lines[i]->polyobj) - { - polyobj_t *po = sector->lines[i]->polyobj; - if (po->validcount == validcount) - continue; // skip if already checked - if (!(po->flags & POF_SOLID)) - continue; - if (po->lines[0]->backsector == sector) // Make sure you're currently checking the control sector - { - INT32 x, y; - po->validcount = validcount; - - for (y = po->blockbox[BOXBOTTOM]; y <= po->blockbox[BOXTOP]; ++y) - { - for (x = po->blockbox[BOXLEFT]; x <= po->blockbox[BOXRIGHT]; ++x) - { - mobj_t *mo; - - if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight) - continue; - - mo = blocklinks[y * bmapwidth + x]; - - for (; mo; mo = mo->bnext) - { - // Monster Iestyn: do we need to check if a mobj has already been checked? ...probably not I suspect - - if (!P_MobjInsidePolyobj(po, mo)) - continue; - - PIT_ChangeSector(mo, true); - } - } - } - } - } - } - if (sector->numattached) - { - sector_t *sec; - for (i = 0; i < sector->numattached; i++) - { - sec = §ors[sector->attached[i]]; - for (n = sec->touching_thinglist; n; n = n->m_thinglist_next) - n->visited = false; - - sec->moved = true; - - P_RecalcPrecipInSector(sec); - - if (!sector->attachedsolid[i]) - continue; - - do - { - for (n = sec->touching_thinglist; n; n = n->m_thinglist_next) - if (!n->visited) - { - n->visited = true; - if (!(n->m_thing->flags & MF_NOBLOCKMAP)) - PIT_ChangeSector(n->m_thing, true); - break; - } - } while (n); - } - } - - // Mark all things invalid - sector->moved = true; - - for (n = sector->touching_thinglist; n; n = n->m_thinglist_next) - n->visited = false; - - do - { - for (n = sector->touching_thinglist; n; n = n->m_thinglist_next) // go through list - if (!n->visited) // unprocessed thing found - { - n->visited = true; // mark thing as processed - if (!(n->m_thing->flags & MF_NOBLOCKMAP)) //jff 4/7/98 don't do these - PIT_ChangeSector(n->m_thing, true); // process it - break; // exit and start over - } - } while (n); // repeat from scratch until all things left are marked valid + P_CheckSectorHelper(sector, true); return nofit; } From 411b79e4564a35dc946944c714da98c7a56ba628 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Thu, 16 Mar 2023 19:38:30 +0100 Subject: [PATCH 116/586] P_CheckSector: Remove unnecessary static variables --- src/p_map.c | 40 ++++++++++++---------------------------- 1 file changed, 12 insertions(+), 28 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index d5f6ce1c1..3172f57ed 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -4231,13 +4231,11 @@ void P_RadiusAttack(mobj_t *spot, mobj_t *source, fixed_t damagedist, UINT8 dama // the way it was and call P_CheckSector (? was P_ChangeSector - Graue) again // to undo the changes. // -static boolean crushchange; -static boolean nofit; // // PIT_ChangeSector // -static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush) +static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush, boolean crunch) { mobj_t *killer = NULL; //If a thing is both pushable and vulnerable, it doesn't block the crusher because it gets killed. @@ -4261,11 +4259,7 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush) if (thing->z + thing->height > thing->ceilingz && thing->z <= thing->ceilingz) { if (immunepushable && thing->z + thing->height > thing->subsector->sector->ceilingheight) - { - //Thing is a pushable and blocks the moving ceiling - nofit = true; - return false; - } + return false; //Thing is a pushable and blocks the moving ceiling //Check FOFs in the sector if (thing->subsector->sector->ffloors && (realcrush || immunepushable)) @@ -4291,11 +4285,7 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush) if (bottomheight <= thing->ceilingz && abs(delta1) >= abs(delta2)) { if (immunepushable) - { - //FOF is blocked by pushable - nofit = true; - return false; - } + return false; //FOF is blocked by pushable else { //If the thing was crushed by a crumbling FOF, reward the player who made it crumble! @@ -4333,14 +4323,14 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush) } } - if (realcrush && crushchange) + if (realcrush && crunch) P_DamageMobj(thing, NULL, NULL, 1, 0); // keep checking (crush other things) return true; } -static boolean P_CheckSectorHelper(sector_t *sector, boolean realcrush) +static boolean P_CheckSectorHelper(sector_t *sector, boolean realcrush, boolean crunch) { msecnode_t *n; size_t i; @@ -4381,7 +4371,7 @@ static boolean P_CheckSectorHelper(sector_t *sector, boolean realcrush) if (!P_MobjInsidePolyobj(po, mo)) continue; - if (!PIT_ChangeSector(mo, realcrush) && !realcrush) + if (!PIT_ChangeSector(mo, realcrush, crunch) && !realcrush) return false; } } @@ -4414,7 +4404,7 @@ static boolean P_CheckSectorHelper(sector_t *sector, boolean realcrush) n->visited = true; if (!(n->m_thing->flags & MF_NOBLOCKMAP)) { - if (!PIT_ChangeSector(n->m_thing, realcrush) && !realcrush) + if (!PIT_ChangeSector(n->m_thing, realcrush, crunch) && !realcrush) return false; } break; @@ -4437,7 +4427,7 @@ static boolean P_CheckSectorHelper(sector_t *sector, boolean realcrush) n->visited = true; // mark thing as processed if (!(n->m_thing->flags & MF_NOBLOCKMAP)) //jff 4/7/98 don't do these { - if (!PIT_ChangeSector(n->m_thing, realcrush) && !realcrush) // process it + if (!PIT_ChangeSector(n->m_thing, realcrush, crunch) && !realcrush) // process it return false; } break; // exit and start over @@ -4452,9 +4442,6 @@ static boolean P_CheckSectorHelper(sector_t *sector, boolean realcrush) // boolean P_CheckSector(sector_t *sector, boolean crunch) { - nofit = false; - crushchange = crunch; - // killough 4/4/98: scan list front-to-back until empty or exhausted, // restarting from beginning after each thing is processed. Avoids // crashes, and is sure to examine all things in the sector, and only @@ -4464,16 +4451,13 @@ boolean P_CheckSector(sector_t *sector, boolean crunch) // killough 4/7/98: simplified to avoid using complicated counter // First, let's see if anything will keep it from crushing. - if (!P_CheckSectorHelper(sector, false)) - { - nofit = true; - return nofit; - } + if (!P_CheckSectorHelper(sector, false, crunch)) + return true; // Nothing blocked us, so lets crush for real! - P_CheckSectorHelper(sector, true); + P_CheckSectorHelper(sector, true, crunch); - return nofit; + return false; } /* From afa1a9ab6a0cf917ed41cf3ba6227a03f90f127a Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Thu, 16 Mar 2023 20:03:42 +0100 Subject: [PATCH 117/586] Split P_CheckSector further --- src/p_map.c | 162 ++++++++++++++++++++++++++++------------------------ 1 file changed, 88 insertions(+), 74 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index 3172f57ed..e1ebe6ae9 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -4330,9 +4330,8 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush, boolean crunch return true; } -static boolean P_CheckSectorHelper(sector_t *sector, boolean realcrush, boolean crunch) +static boolean P_CheckSectorPolyObjects(sector_t *sector, boolean realcrush, boolean crunch) { - msecnode_t *n; size_t i; // Sal: This stupid function chain is required to fix polyobjects not being able to crush. @@ -4341,80 +4340,51 @@ static boolean P_CheckSectorHelper(sector_t *sector, boolean realcrush, boolean for (i = 0; i < sector->linecount; i++) { - if (sector->lines[i]->polyobj) + INT32 x, y; + polyobj_t *po = sector->lines[i]->polyobj; + + if (!po) + continue; + if (po->validcount == validcount) + continue; // skip if already checked + if (!(po->flags & POF_SOLID)) + continue; + if (po->lines[0]->backsector != sector) // Make sure you're currently checking the control sector + continue; + + po->validcount = validcount; + + for (y = po->blockbox[BOXBOTTOM]; y <= po->blockbox[BOXTOP]; ++y) { - polyobj_t *po = sector->lines[i]->polyobj; - if (po->validcount == validcount) - continue; // skip if already checked - if (!(po->flags & POF_SOLID)) - continue; - if (po->lines[0]->backsector == sector) // Make sure you're currently checking the control sector + for (x = po->blockbox[BOXLEFT]; x <= po->blockbox[BOXRIGHT]; ++x) { - INT32 x, y; - po->validcount = validcount; + mobj_t *mo; - for (y = po->blockbox[BOXBOTTOM]; y <= po->blockbox[BOXTOP]; ++y) + if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight) + continue; + + mo = blocklinks[y * bmapwidth + x]; + + for (; mo; mo = mo->bnext) { - for (x = po->blockbox[BOXLEFT]; x <= po->blockbox[BOXRIGHT]; ++x) - { - mobj_t *mo; + // Monster Iestyn: do we need to check if a mobj has already been checked? ...probably not I suspect - if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight) - continue; + if (!P_MobjInsidePolyobj(po, mo)) + continue; - mo = blocklinks[y * bmapwidth + x]; - - for (; mo; mo = mo->bnext) - { - // Monster Iestyn: do we need to check if a mobj has already been checked? ...probably not I suspect - - if (!P_MobjInsidePolyobj(po, mo)) - continue; - - if (!PIT_ChangeSector(mo, realcrush, crunch) && !realcrush) - return false; - } - } + if (!PIT_ChangeSector(mo, realcrush, crunch) && !realcrush) + return false; } } } } - if (sector->numattached) - { - sector_t *sec; - for (i = 0; i < sector->numattached; i++) - { - sec = §ors[sector->attached[i]]; - for (n = sec->touching_thinglist; n; n = n->m_thinglist_next) - n->visited = false; + return true; +} - sec->moved = true; - - P_RecalcPrecipInSector(sec); - - if (!sector->attachedsolid[i]) - continue; - - do - { - for (n = sec->touching_thinglist; n; n = n->m_thinglist_next) - if (!n->visited) - { - n->visited = true; - if (!(n->m_thing->flags & MF_NOBLOCKMAP)) - { - if (!PIT_ChangeSector(n->m_thing, realcrush, crunch) && !realcrush) - return false; - } - break; - } - } while (n); - } - } - - // Mark all things invalid - sector->moved = true; +static boolean P_CheckTouchingThinglist(sector_t *sector, boolean realcrush, boolean crunch) +{ + msecnode_t *n; for (n = sector->touching_thinglist; n; n = n->m_thinglist_next) n->visited = false; @@ -4422,21 +4392,65 @@ static boolean P_CheckSectorHelper(sector_t *sector, boolean realcrush, boolean do { for (n = sector->touching_thinglist; n; n = n->m_thinglist_next) // go through list - if (!n->visited) // unprocessed thing found - { - n->visited = true; // mark thing as processed - if (!(n->m_thing->flags & MF_NOBLOCKMAP)) //jff 4/7/98 don't do these - { - if (!PIT_ChangeSector(n->m_thing, realcrush, crunch) && !realcrush) // process it - return false; - } - break; // exit and start over - } + { + if (n->visited) + continue; + + n->visited = true; // mark thing as processed + + if (n->m_thing->flags & MF_NOBLOCKMAP) //jff 4/7/98 don't do these + continue; + + if (!PIT_ChangeSector(n->m_thing, realcrush, crunch) && !realcrush) // process it + return false; + + break; // exit and start over + } } while (n); // repeat from scratch until all things left are marked valid return true; } +static boolean P_CheckSectorFFloors(sector_t *sector, boolean realcrush, boolean crunch) +{ + sector_t *sec; + size_t i; + + if (!sector->numattached) + return true; + + for (i = 0; i < sector->numattached; i++) + { + sec = §ors[sector->attached[i]]; + + sec->moved = true; + + P_RecalcPrecipInSector(sec); + + if (!sector->attachedsolid[i]) + continue; + + if (!P_CheckTouchingThinglist(sec, realcrush, crunch)) + return false; + } + + return true; +} + +static boolean P_CheckSectorHelper(sector_t *sector, boolean realcrush, boolean crunch) +{ + if (!P_CheckSectorPolyObjects(sector, realcrush, crunch)) + return false; + + if (!P_CheckSectorFFloors(sector, realcrush, crunch)) + return false; + + // Mark all things invalid + sector->moved = true; + + return P_CheckTouchingThinglist(sector, realcrush, crunch); +} + // // P_CheckSector // From fff6683173e0a2ec61a5a2a8ab7e33f85ad714c3 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Thu, 16 Mar 2023 20:38:28 +0100 Subject: [PATCH 118/586] Clean up PIT_ChangeSector --- src/p_map.c | 63 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 26 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index e1ebe6ae9..8ea1a6392 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -4271,43 +4271,54 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush, boolean crunch for (rover = thing->subsector->sector->ffloors; rover; rover = rover->next) { - if (!(((rover->fofflags & FOF_BLOCKPLAYER) && thing->player) - || ((rover->fofflags & FOF_BLOCKOTHERS) && !thing->player)) || !(rover->fofflags & FOF_EXISTS)) + thinker_t *think; + + if (!(rover->fofflags & FOF_EXISTS)) + continue; + if (thing->player && !(rover->fofflags & FOF_BLOCKPLAYER)) + continue; + if (!thing->player && !(rover->fofflags & FOF_BLOCKOTHERS)) continue; topheight = *rover->topheight; bottomheight = *rover->bottomheight; - //topheight = P_GetFFloorTopZAt (rover, thing->x, thing->y); - //bottomheight = P_GetFFloorBottomZAt(rover, thing->x, thing->y); + + if (bottomheight > thing->ceilingz) + continue; delta1 = thing->z - (bottomheight + topheight)/2; delta2 = thingtop - (bottomheight + topheight)/2; - if (bottomheight <= thing->ceilingz && abs(delta1) >= abs(delta2)) + if (abs(delta1) < abs(delta2)) + continue; + + if (immunepushable) + return false; //FOF is blocked by pushable + + if (!realcrush) + continue; + + //If the thing was crushed by a crumbling FOF, reward the player who made it crumble! + for (think = thlist[THINK_MAIN].next; think != &thlist[THINK_MAIN]; think = think->next) { - if (immunepushable) - return false; //FOF is blocked by pushable - else - { - //If the thing was crushed by a crumbling FOF, reward the player who made it crumble! - thinker_t *think; - crumble_t *crumbler; + crumble_t *crumbler; - for (think = thlist[THINK_MAIN].next; think != &thlist[THINK_MAIN]; think = think->next) - { - if (think->function.acp1 != (actionf_p1)T_StartCrumble) - continue; + if (think->function.acp1 != (actionf_p1)T_StartCrumble) + continue; - crumbler = (crumble_t *)think; + crumbler = (crumble_t *)think; - if (crumbler->player && crumbler->player->mo - && crumbler->player->mo != thing - && crumbler->actionsector == thing->subsector->sector - && crumbler->sector == rover->master->frontsector) - { - killer = crumbler->player->mo; - } - } - } + if (!crumbler->player) + continue; + if (!crumbler->player->mo) + continue; + if (crumbler->player->mo == thing) + continue; + if (crumbler->actionsector != thing->subsector->sector) + continue; + if (crumbler->sector != rover->master->frontsector) + continue; + + killer = crumbler->player->mo; } } } From 62aef145f5c8f922b7a730eaf9227c0119b10f2f Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sun, 19 Mar 2023 14:44:18 +0100 Subject: [PATCH 119/586] Fix time functions not starting from zero --- src/i_time.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/i_time.c b/src/i_time.c index c1cc9dfd4..b302c6025 100644 --- a/src/i_time.c +++ b/src/i_time.c @@ -43,18 +43,20 @@ tic_t I_GetTime(void) void I_InitializeTime(void) { - g_time.time = 0; - g_time.timefrac = 0; - - enterprecise = 0; - oldenterprecise = 0; - tictimer = 0.0; - CV_RegisterVar(&cv_timescale); // I_StartupTimer is preserved for potential subsystems that need to setup // timing information for I_GetPreciseTime and sleeping I_StartupTimer(); + + g_time.time = 0; + g_time.timefrac = 0; + + enterprecise = I_GetPreciseTime(); + oldenterprecise = enterprecise; + entertic = 0; + oldentertics = 0; + tictimer = 0.0; } void I_UpdateTime(fixed_t timescale) From 0f9c5582a397c531d421ebcc24abb7df969fae6b Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sun, 19 Mar 2023 14:52:12 +0100 Subject: [PATCH 120/586] Add basic rate limitation for Lua file access --- src/blua/liolib.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/src/blua/liolib.c b/src/blua/liolib.c index e029650c0..545f9c144 100644 --- a/src/blua/liolib.c +++ b/src/blua/liolib.c @@ -24,12 +24,14 @@ #include "../byteptr.h" #include "../lua_script.h" #include "../m_misc.h" +#include "../i_time.h" #define IO_INPUT 1 #define IO_OUTPUT 2 -#define FILELIMIT (1024 * 1024) // Size limit for reading/writing files +#define MAXBYTESPERMINUTE (10 * 1024 * 1024) // Rate limit for writing files +#define MAXOPENSPERMINUTE 50 // Rate limit for opening new files #define FMT_FILECALLBACKID "file_callback_%d" @@ -46,6 +48,10 @@ static const char *whitelist[] = { }; +static INT64 numwrittenbytes = 0; +static INT64 numopenedfiles = 0; + + static int pushresult (lua_State *L, int i, const char *filename) { int en = errno; /* calls to Lua API may change this value */ if (i) { @@ -252,6 +258,17 @@ static int io_openlocal (lua_State *L) { "Files can't be opened while being downloaded\n", filename); + // Reading not restricted + if (client && (strchr(mode, 'w') || strchr(mode, 'a') || strchr(mode, '+'))) + { + if (numopenedfiles >= (I_GetTime() / (60*TICRATE) + 1) * MAXOPENSPERMINUTE) + I_Error("Access denied to %s\n" + "File opening rate exceeded\n", + filename); + + numopenedfiles++; + } + MakePathDirs(realfilename); // Open and return the file @@ -527,9 +544,12 @@ static int g_write (lua_State *L, FILE *f, int arg) { else { size_t l; const char *s = luaL_checklstring(L, arg, &l); - if (ftell(f) + l > FILELIMIT) { - luaL_error(L,"write limit bypassed in file. Changes have been discarded."); - break; + if (client) { + if (numwrittenbytes + l > (I_GetTime() / (60*TICRATE) + 1) * MAXBYTESPERMINUTE) { + luaL_error(L,"file write rate limit exceeded; changes have been discarded"); + break; + } + numwrittenbytes += l; } status = status && (fwrite(s, sizeof(char), l, f) == l); } From 540c5d6cc0271a255a89566f06247f034d0978d1 Mon Sep 17 00:00:00 2001 From: spherallic Date: Mon, 20 Mar 2023 15:46:15 +0100 Subject: [PATCH 121/586] Add flag to action 433 to force MFE_VERTICALFLIP --- extras/conf/SRB2-22.cfg | 1 + extras/conf/udb/Includes/SRB222_linedefs.cfg | 10 ++++++++++ src/p_setup.c | 1 + src/p_spec.c | 2 ++ 4 files changed, 14 insertions(+) diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg index 952ce6969..ae905b637 100644 --- a/extras/conf/SRB2-22.cfg +++ b/extras/conf/SRB2-22.cfg @@ -2341,6 +2341,7 @@ linedeftypes { title = "Enable/Disable Gravity Flip"; prefix = "(433)"; + flags2text = "[1] Force MFE_VERTICALFLIP"; flags8text = "[3] Set delay by backside sector"; flags32text = "[5] Invert current gravity"; flags64text = "[6] Return to normal"; diff --git a/extras/conf/udb/Includes/SRB222_linedefs.cfg b/extras/conf/udb/Includes/SRB222_linedefs.cfg index 99c305659..3a3bd80cc 100644 --- a/extras/conf/udb/Includes/SRB222_linedefs.cfg +++ b/extras/conf/udb/Includes/SRB222_linedefs.cfg @@ -4223,6 +4223,16 @@ udmf 1 = "Yes"; } } + arg2 + { + title = "Force MFE_VERTICALFLIP"; + type = 11; + enum + { + 0 = "No"; + 1 = "Yes"; + } + } } 434 diff --git a/src/p_setup.c b/src/p_setup.c index d6cda7d4f..dc1111531 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -5299,6 +5299,7 @@ static void P_ConvertBinaryLinedefTypes(void) case 433: //Enable/disable gravity flip lines[i].args[0] = !!(lines[i].flags & ML_NOCLIMB); lines[i].args[1] = !!(lines[i].flags & ML_SKEWTD); + lines[i].args[2] = !!(lines[i].flags & ML_BLOCKMONSTERS); break; case 434: //Award power-up if (sides[lines[i].sidenum[0]].text) diff --git a/src/p_spec.c b/src/p_spec.c index 4e6ef531f..6f798421a 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -2786,6 +2786,8 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) mo->flags2 &= ~MF2_OBJECTFLIP; else mo->flags2 |= MF2_OBJECTFLIP; + if (line->args[2]) + mo->eflags |= MFE_VERTICALFLIP; if (bot) bot->flags2 = (bot->flags2 & ~MF2_OBJECTFLIP) | (mo->flags2 & MF2_OBJECTFLIP); break; From 498c9da85943886fda0538e1689fc66dbfebe64d Mon Sep 17 00:00:00 2001 From: spherallic Date: Wed, 29 Mar 2023 16:41:45 +0200 Subject: [PATCH 122/586] Don't attract bomb spheres with Attraction shield --- 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 30e0183de..f5a951d65 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9686,7 +9686,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) P_RingThinker(mobj); if (mobj->flags2 & MF2_NIGHTSPULL) P_NightsItemChase(mobj); - else + else if (mobj->type != MT_BOMBSPHERE) // prevent shields from attracting bomb spheres A_AttractChase(mobj); return false; // Flung items From 91ef59f76b19f72eaf134a3274e96d14314aa31f Mon Sep 17 00:00:00 2001 From: spherallic Date: Fri, 31 Mar 2023 13:36:54 +0200 Subject: [PATCH 123/586] Fix tiny regression with special stage tally --- 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 7faceff50..1e070260e 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -1139,7 +1139,7 @@ void Y_Ticker(void) data.spec.emeraldmomy = 20; data.spec.emeraldy = -40; } - else + else if (P_GetNextEmerald() < 7) { if (!stagefailed) { From 1470d099e338aff3aad25178894e15bb6d1e8232 Mon Sep 17 00:00:00 2001 From: spherallic Date: Fri, 31 Mar 2023 14:53:31 +0200 Subject: [PATCH 124/586] Update copyright year & credits --- assets/README.txt | 2 +- src/Makefile | 4 ++-- 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 | 4 ++-- 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 | 4 ++-- 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 | 4 ++-- 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_defs.h | 2 +- src/hardware/hw_draw.c | 2 +- src/hardware/hw_drv.h | 2 +- src/hardware/hw_glob.h | 2 +- src/hardware/hw_light.c | 2 +- src/hardware/hw_light.h | 2 +- src/hardware/hw_main.c | 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_time.c | 2 +- src/i_time.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_hudlib_drawlist.c | 2 +- src/lua_hudlib_drawlist.h | 2 +- src/lua_infolib.c | 2 +- src/lua_inputlib.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_easing.c | 2 +- src/m_easing.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.c | 2 +- src/r_data.h | 2 +- src/r_defs.h | 2 +- src/r_draw.c | 2 +- src/r_draw.h | 2 +- src/r_draw16.c | 2 +- src/r_draw8.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.c | 2 +- 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.c | 2 +- src/r_splats.h | 2 +- src/r_state.h | 2 +- src/r_textures.c | 2 +- src/r_textures.h | 2 +- src/r_things.c | 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 | 2 +- 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 +- 236 files changed, 249 insertions(+), 249 deletions(-) diff --git a/assets/README.txt b/assets/README.txt index 5480cb7b0..e384333ed 100644 --- a/assets/README.txt +++ b/assets/README.txt @@ -39,7 +39,7 @@ https://facebook.com/SonicRoboBlast2 COPYRIGHT AND DISCLAIMER -Design and content in Sonic Robo Blast 2 is copyright 1998-2022 by Sonic Team Jr. +Design and content in Sonic Robo Blast 2 is copyright 1998-2023 by Sonic Team Jr. All original material in this game is copyrighted by their respective owners, and no copyright infringement is intended. Sonic Team Jr. is in no way affiliated with SEGA or Sonic Team, and we do not claim ownership of any of SEGA's intellectual property used in SRB2. diff --git a/src/Makefile b/src/Makefile index 7571c8089..36b1a7efa 100644 --- a/src/Makefile +++ b/src/Makefile @@ -2,8 +2,8 @@ # the poly3 Makefile adapted over and over... # # Copyright 1998-2000 DooM Legacy Team. -# Copyright 2020-2022 James R. -# Copyright 2003-2022 Sonic Team Junior. +# Copyright 2020-2023 James R. +# Copyright 2003-2023 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.c b/src/am_map.c index 65a57c09e..331d1a5e0 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 89c4ad9fa..a202bece1 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 f4c08d979..11d3ab9f5 100644 --- a/src/apng.c +++ b/src/apng.c @@ -1,5 +1,5 @@ /* -Copyright 2019-2022, James R. +Copyright 2019-2023, 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 6b9347424..ed30549e2 100644 --- a/src/apng.h +++ b/src/apng.h @@ -1,5 +1,5 @@ /* -Copyright 2019-2022, James R. +Copyright 2019-2023, 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 a8c60f19e..48f8da0d8 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 2774337cc..d1465f891 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-2022 by Sonic Team Junior. +// Copyright (C) 2011-2023 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -118,7 +118,7 @@ static void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd) return; } - // Adapted from CobaltBW's tails_AI.wad + // Adapted from clairebun's tails_AI.wad // Check water if (water) diff --git a/src/b_bot.h b/src/b_bot.h index c29974c50..bbe0829be 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-2022 by Sonic Team Junior. +// Copyright (C) 2012-2023 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 3aa2aa508..8ab359c4c 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 b22f03d1a..3340641e8 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 30d7e5bbe..c60bf33a1 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 40fb43121..0a910858b 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 1cd032ac1..f22f8dcbc 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 1ff053e5c..aa2b2fd6b 100755 --- 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 e07864122..8767445d4 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 c0b9cef77..5aa435060 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 3566e7f3d..6903369e4 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -1224,7 +1224,7 @@ void D_SRB2Main(void) // Print GPL notice for our console users (Linux) CONS_Printf( "\n\nSonic Robo Blast 2\n" - "Copyright (C) 1998-2022 by Sonic Team Junior\n\n" + "Copyright (C) 1998-2023 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" diff --git a/src/d_main.h b/src/d_main.h index 8189a9f2b..197423fb3 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 a7e1eb16d..7de3dba56 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 5baa593a0..ddedbef4a 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 f63f38a74..1fbdfdce2 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 0beeae154..26bf4d5c6 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 edbef30bb..e60af2c2c 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 f778a518f..ecec976be 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 42e9c3a82..756c7141e 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 90a58ab68..bdb5db3f5 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 e632a74a8..2481ed738 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 09dc155cf..1a87e38a5 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 657e66b6e..c400351b8 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 cbc7940f7..2af7b65bf 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 f972ec26e..0cab545f6 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 4a3467f78..00dd7525e 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 850194a96..8943ab71a 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 3f339e477..17768eb7f 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 b4651c66a..902404df7 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 56fb5e9e9..4c5bdefaf 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 2b62bcd6e..2bab63829 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 bce43416b..632381b1c 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 456f56380..d29bd35f2 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 86297f0cb..87f752471 100644 --- a/src/endian.h +++ b/src/endian.h @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2014-2022 by Sonic Team Junior. +// Copyright (C) 2014-2023 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 bca8e3ba6..ea5ce62bd 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -1138,7 +1138,7 @@ static const char *credits[] = { "Dave \"DemonTomatoDave\" Bulmer", "Paul \"Boinciel\" Clempson", "\"Cyan Helkaraxe\"", - "Shane \"CobaltBW\" Ellis", + "Claire \"clairebun\" Ellis", "James \"SeventhSentinel\" Hall", "Kepa \"Nev3r\" Iceta", "Iestyn \"Monster Iestyn\" Jealous", diff --git a/src/f_finale.h b/src/f_finale.h index efdc9d4ad..e37b45253 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 ab869ca60..6014fb7f9 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 2da5a76ab..0403da16d 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 37664dc71..f25315a58 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 74bc42711..e49308c5f 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 dca043f2e..55b771274 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 262e68c6a..9d5656253 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 400e3fd12..e9c909e6e 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 a6ac1970d..8f97930bb 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 f9c6542ae..d1b84a5ee 100644 --- a/src/hardware/hw_batching.c +++ b/src/hardware/hw_batching.c @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2020-2022 by Sonic Team Junior. +// Copyright (C) 2020-2023 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 df5c478a3..c7fd7afe3 100644 --- a/src/hardware/hw_batching.h +++ b/src/hardware/hw_batching.h @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2020-2022 by Sonic Team Junior. +// Copyright (C) 2020-2023 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 3e207025c..d6245df64 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 ceefe9abd..af65a4e65 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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_defs.h b/src/hardware/hw_defs.h index fca9b80a3..b0859f478 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 ada2a6bf8..eb0b9e332 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 3b9b8681c..426d2f283 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 1ec9101c3..4c7c56d17 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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.c b/src/hardware/hw_light.c index eb3c9bbbb..c1f0b3407 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 a0a9e93ad..e9d87933d 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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.c b/src/hardware/hw_main.c index 321ed215f..343fa43bf 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 cd822c0c1..4a1b412fc 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 f33d67bbb..6b1d0c6fc 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 966ed016b..f1cca763c 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 0b51fa05c..569ddfee8 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-2022 by Sonic Team Junior. +// Copyright (C) 1998-2023 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 6e3de4535..b4dba0db9 100644 --- a/src/http-mserv.c +++ b/src/http-mserv.c @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2020-2022 by James R. +// Copyright (C) 2020-2023 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 c037abcd7..c5a32dbd2 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 110486378..8647e4500 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 49aadf27d..9efaff4da 100644 --- a/src/i_addrinfo.c +++ b/src/i_addrinfo.c @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2011-2022 by Sonic Team Junior. +// Copyright (C) 2011-2023 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 592e693f4..79cfb05b2 100644 --- a/src/i_addrinfo.h +++ b/src/i_addrinfo.h @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2011-2022 by Sonic Team Junior. +// Copyright (C) 2011-2023 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 27584cea6..95caed4fd 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 62b7528d5..9f2c38c7b 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 6358fbefb..c51d8e4f4 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 7153aa735..957150fe6 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 8838ba725..3820155b8 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 b6e5b9235..ae9983bf1 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 c7b71d26c..fe6ab4fb0 100644 --- a/src/i_threads.h +++ b/src/i_threads.h @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2020-2022 by James R. +// Copyright (C) 2020-2023 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_time.c b/src/i_time.c index c1cc9dfd4..55d1557bd 100644 --- a/src/i_time.c +++ b/src/i_time.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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_time.h b/src/i_time.h index cab36133b..997ba7ef2 100644 --- a/src/i_time.h +++ b/src/i_time.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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_video.h b/src/i_video.h index d66b2d95f..8efca5f9a 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 b55302170..09452a74f 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 a9f68721f..502ecd726 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 df12c95ae..689f15fef 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 a4ad81358..8fec7bd63 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-2022 by Sonic Team Junior. +// Copyright (C) 2012-2023 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 8c63a9d6d..8d47f3dc1 100644 --- a/src/lua_blockmaplib.c +++ b/src/lua_blockmaplib.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2016-2022 by Iestyn "Monster Iestyn" Jealous. -// Copyright (C) 2016-2022 by Sonic Team Junior. +// Copyright (C) 2016-2023 by Iestyn "Monster Iestyn" Jealous. +// Copyright (C) 2016-2023 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 816051199..da4094732 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-2022 by Sonic Team Junior. +// Copyright (C) 2012-2023 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 4fa3a1a17..cb0e30d87 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-2022 by Sonic Team Junior. +// Copyright (C) 2012-2023 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 c4083c9ad..039a9677f 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-2022 by Sonic Team Junior. +// Copyright (C) 2012-2023 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 0d629d233..ba102f2f4 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-2022 by Sonic Team Junior. +// Copyright (C) 2014-2023 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 785124fec..1a0599757 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-2022 by Sonic Team Junior. +// Copyright (C) 2014-2023 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_drawlist.c b/src/lua_hudlib_drawlist.c index bcf132ec6..f46f207c1 100644 --- a/src/lua_hudlib_drawlist.c +++ b/src/lua_hudlib_drawlist.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 2014-2016 by John "JTE" Muniz. -// Copyright (C) 2014-2022 by Sonic Team Junior. +// Copyright (C) 2014-2023 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_drawlist.h b/src/lua_hudlib_drawlist.h index 57d3de3c3..b2df39747 100644 --- a/src/lua_hudlib_drawlist.h +++ b/src/lua_hudlib_drawlist.h @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2022-2022 by Sonic Team Junior. +// Copyright (C) 2022-2023 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 ac41de419..7388632d3 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-2022 by Sonic Team Junior. +// Copyright (C) 2012-2023 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_inputlib.c b/src/lua_inputlib.c index 1710b0355..1f75ee6fe 100644 --- a/src/lua_inputlib.c +++ b/src/lua_inputlib.c @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2021-2022 by Sonic Team Junior. +// Copyright (C) 2021-2023 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 b4a891edb..7f8d21f38 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-2022 by Sonic Team Junior. +// Copyright (C) 2012-2023 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 b4565121d..7abe820a5 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-2022 by Sonic Team Junior. +// Copyright (C) 2012-2023 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 c7501da60..d0fe6863f 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-2022 by Sonic Team Junior. +// Copyright (C) 2012-2023 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 2aec48c90..7d2c77595 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-2022 by Sonic Team Junior. +// Copyright (C) 2012-2023 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 58cfab76c..f7e14e78f 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-2022 by Sonic Team Junior. +// Copyright (C) 2012-2023 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 a91c354f4..c3d9d9d1a 100644 --- a/src/lua_polyobjlib.c +++ b/src/lua_polyobjlib.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2020-2022 by Iestyn "Monster Iestyn" Jealous. -// Copyright (C) 2020-2022 by Sonic Team Junior. +// Copyright (C) 2020-2023 by Iestyn "Monster Iestyn" Jealous. +// Copyright (C) 2020-2023 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 f166fb4e6..8f7b04430 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-2022 by Sonic Team Junior. +// Copyright (C) 2012-2023 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 e586b04a8..fe04e5e60 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-2022 by Sonic Team Junior. +// Copyright (C) 2012-2023 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 9c7c4ad03..5c21b04c3 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-2022 by Sonic Team Junior. +// Copyright (C) 2014-2023 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 b69416362..2ba60df99 100644 --- a/src/lua_taglib.c +++ b/src/lua_taglib.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2020-2022 by James R. -// Copyright (C) 2020-2022 by Sonic Team Junior. +// Copyright (C) 2020-2023 by James R. +// Copyright (C) 2020-2023 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 963fdbd5a..cff92f34d 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-2022 by Sonic Team Junior. +// Copyright (C) 2012-2023 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 522e38a53..a530395f6 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 ed011644e..91716f346 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 41765e6e1..90e4c69ce 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-2022 by Sonic Team Junior. +// Copyright (C) 2013-2023 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 ad64dff7b..060c5f585 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-2022 by Sonic Team Junior. +// Copyright (C) 2013-2023 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 1444f0c38..475be23a3 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 cdb6aa246..2d74ca150 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 7fde0c171..75c84385a 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 588000fae..046e325a9 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 89c8009ae..1056ecb02 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 086117579..f4ac01d84 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 1406317c5..769ff90be 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-2022 by Sonic Team Junior. +// Copyright (C) 2012-2023 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 f36c80009..d49dc920b 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-2022 by Sonic Team Junior. +// Copyright (C) 2012-2023 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 d8ca6648a..06a479422 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-2022 by Sonic Team Junior. +// Copyright (C) 2005-2023 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_easing.c b/src/m_easing.c index 0f1cc1d02..48fe1efbc 100644 --- a/src/m_easing.c +++ b/src/m_easing.c @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2020-2022 by Jaime "Lactozilla" Passos. +// Copyright (C) 2020-2023 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/m_easing.h b/src/m_easing.h index 229222a15..eaa5d6773 100644 --- a/src/m_easing.h +++ b/src/m_easing.h @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2020-2022 by Jaime "Lactozilla" Passos. +// Copyright (C) 2020-2023 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/m_fixed.c b/src/m_fixed.c index ded294b0a..ad2831196 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 73e629f44..4a5b7ce2a 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 82d078062..4451af4fd 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 a7072b0c1..35c77cc43 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 d98c949cf..49eb7f1ef 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 2959ba44e..8cad7ba9a 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 9f65a7616..17e026b3e 100644 --- a/src/m_perfstats.c +++ b/src/m_perfstats.c @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2020-2022 by Sonic Team Junior. +// Copyright (C) 2020-2023 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 f6a7c1f74..db250be2a 100644 --- a/src/m_perfstats.h +++ b/src/m_perfstats.h @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2020-2022 by Sonic Team Junior. +// Copyright (C) 2020-2023 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 2cc3f7cb8..1c10a6692 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-2022 by Sonic Team Junior. +// Copyright (C) 2003-2023 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 071f9d8fa..b1ad22bf5 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-2022 by Sonic Team Junior. +// Copyright (C) 2003-2023 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 112795500..3d0774a60 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 aa5ffb0bb..824287e27 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 df5f3e907..b63089bcb 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 bff562c95..dc0cc136a 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-2022 by Sonic Team Junior. -// Copyright (C) 2020-2022 by James R. +// Copyright (C) 1999-2023 by Sonic Team Junior. +// Copyright (C) 2020-2023 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 23b26fbc5..1c8d742d8 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-2022 by Sonic Team Junior. -// Copyright (C) 2020-2022 by James R. +// Copyright (C) 1999-2023 by Sonic Team Junior. +// Copyright (C) 2020-2023 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 66f2dd58e..98e931362 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 c376c2db4..63d430eb6 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 869384b53..9c24f5851 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 dd3e0f9c2..8bc5c95e4 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 4c783f884..75455da73 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 2b3020997..cc060e4ee 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 54e2003ba..a7d1f4abd 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 260bcc074..b6a320730 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 b7779d88a..08de0cb0b 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 30e0183de..c8adb6f1d 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 60601692c..2cf177d23 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 7ef956ff1..b207bb740 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-2022 by Sonic Team Junior. +// Copyright (C) 2006-2023 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 7e7b70c17..0573f6350 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-2022 by Sonic Team Junior. +// Copyright (C) 2006-2023 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 4136c2118..69e5eeeb3 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 42125dae7..880466d37 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 9f4a2633f..73fcfd583 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 d6cda7d4f..a125760cf 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 36d19f66d..c6f4f741c 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 4023744dc..3e92bec86 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 2c0e3d88b..cf7807d4e 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-2022 by Sonic Team Junior. +// Copyright (C) 2015-2023 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 f4b0535e7..096bf8f82 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-2022 by Sonic Team Junior. +// Copyright (C) 2015-2023 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 4e6ef531f..5a262e87a 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 779afdd05..91dfccb70 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 4d10f1df3..66b05ff01 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 fe6a4d33f..0357258e8 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 d355bc6d7..594bbc7af 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 60a0f5106..d5fb17364 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 c9c169a51..121ddaae5 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 88757cf4b..55199405a 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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.c b/src/r_data.c index 51ed15dd6..4b7492f90 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 63772e7b0..ef5c967e5 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 3746643c6..6d2b7d3d8 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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_draw.c b/src/r_draw.c index 601fb4bb2..b0467e4f7 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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_draw.h b/src/r_draw.h index cb4e4482a..ea03a8e3d 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 763fd1631..2ed5a2a8e 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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.c b/src/r_draw8.c index 31abe70b8..b80a47984 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 8b02fb90d..faf1cdba8 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 a5b590e5c..65fad64d0 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 187925408..4d801dc80 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 94103ceed..f08070d0f 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 e771e5c94..7c561e959 100644 --- a/src/r_patch.c +++ b/src/r_patch.c @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2020-2022 by Jaime "Lactozilla" Passos. +// Copyright (C) 2020-2023 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 26c28e1f9..d2106a390 100644 --- a/src/r_patch.h +++ b/src/r_patch.h @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2020-2022 by Jaime "Lactozilla" Passos. +// Copyright (C) 2020-2023 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 b24e065ba..3d3c6c512 100644 --- a/src/r_patchrotation.c +++ b/src/r_patchrotation.c @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2020-2022 by Jaime "Lactozilla" Passos. +// Copyright (C) 2020-2023 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 e6bee80ed..a239ac5fa 100644 --- a/src/r_patchrotation.h +++ b/src/r_patchrotation.h @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2020-2022 by Jaime "Lactozilla" Passos. +// Copyright (C) 2020-2023 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 5a7aebcf7..9aea8c6c1 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-2022 by Jaime "Lactozilla" Passos. -// Copyright (C) 2019-2022 by Sonic Team Junior. +// Copyright (C) 2018-2023 by Jaime "Lactozilla" Passos. +// Copyright (C) 2019-2023 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 f3080479f..4f9637460 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-2022 by Jaime "Lactozilla" Passos. -// Copyright (C) 2019-2022 by Sonic Team Junior. +// Copyright (C) 2018-2023 by Jaime "Lactozilla" Passos. +// Copyright (C) 2019-2023 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.c b/src/r_plane.c index 56cf869ef..c568484b6 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 ea793fce2..9870a43e2 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 4d4132133..e594f960a 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 687ee058f..f90f05fbc 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 43a7f945f..71fc9f9b2 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 4075cc0bb..09c68b27e 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 92fd6cfae..56e322e87 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 aeaa9f3e0..361ebb102 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 e21b7cbf1..c47029f0b 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 31c821d22..012f47d23 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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.c b/src/r_splats.c index bab89c89e..72bfe74b3 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 ec6885e26..dcae2789c 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 69989e7ac..b36697f73 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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.c b/src/r_textures.c index 98c2788a2..69e64074d 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 b9b48da8c..4a3c10b9e 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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.c b/src/r_things.c index 461761977..2916482fb 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 35eeb9ce1..de9ea5dfd 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 f28a77a80..3bbbad479 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 6223c4fdb..288859c8d 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 3842a365d..ab04f68bf 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 add048b25..19103b0df 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 818d0f0c4..e328bedc2 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-2022 by Sonic Team Junior. +// Copyright (C) 2014-2023 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 a182ae197..c05936072 100644 --- a/src/sdl/i_threads.c +++ b/src/sdl/i_threads.c @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2020-2022 by James R. +// Copyright (C) 2020-2023 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 02f0e462e..5ebd276ef 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.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-2022 by Sonic Team Junior. +// Copyright (C) 2014-2023 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 e56a5bc1b..f13aaef5d 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2014-2022 by Sonic Team Junior. +// Copyright (C) 2014-2023 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/ogl_sdl.c b/src/sdl/ogl_sdl.c index 67e98d4f5..db0538195 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-2022 by Sonic Team Junior. +// Copyright (C) 2014-2023 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 9744bc6f1..bd1d699ff 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-2022 by Sonic Team Junior. +// Copyright (C) 2014-2023 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 0de3788fe..2ca35b954 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-2022 by Sonic Team Junior. +// Copyright (C) 2014-2023 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 6b6e79d97..db736880d 100644 --- a/src/sdl/sdlmain.h +++ b/src/sdl/sdlmain.h @@ -1,7 +1,7 @@ // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // -// Copyright (C) 2006-2022 by Sonic Team Junior. +// Copyright (C) 2006-2023 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 43525d568..19b69dd28 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 eec518689..102881e99 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 3e75750a8..cce8ea9f2 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 c59bc2ac6..68ac900f7 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 6affde364..2796f11d5 100644 --- a/src/strcasestr.c +++ b/src/strcasestr.c @@ -2,7 +2,7 @@ strcasestr -- case insensitive substring searching function. */ /* -Copyright 2019-2022 James R. +Copyright 2019-2023 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 5534a3f0c..28bb7d2d1 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-2022 by Sonic Team Junior. +// Copyright (C) 2006-2023 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 f8b8030c9..315fe1d7a 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 172ade378..2736f03e8 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 405007614..e4e385b9e 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-2022 by Sonic Team Junior. -// Copyright (C) 2020-2022 by Nev3r. +// Copyright (C) 1999-2023 by Sonic Team Junior. +// Copyright (C) 2020-2023 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 de6e9abd5..d42a48f05 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-2022 by Sonic Team Junior. -// Copyright (C) 2020-2022 by Nev3r. +// Copyright (C) 1999-2023 by Sonic Team Junior. +// Copyright (C) 2020-2023 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 f096c8141..85091cbd5 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-2022 by Sonic Team Junior. +;; Copyright (C) 1999-2023 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 5bb2dea12..d98d82e25 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 8e307f42b..d8967178c 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 5312f3c76..a45667e23 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-2022 by Sonic Team Junior. +;; Copyright (C) 2010-2023 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 44b2d2e7b..c85cf7003 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-2022 by Sonic Team Junior. +;; Copyright (C) 1999-2023 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 84d7978cb..461a5e3bc 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 2831230a3..ff03836b5 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 8e43e23c1..1473a3856 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 42c6bf83b..40073fc55 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 c4de55d77..ffb9095ba 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 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 2236beca1..07898dbc1 100644 --- a/src/win32/Srb2win.rc +++ b/src/win32/Srb2win.rc @@ -98,7 +98,7 @@ BEGIN VALUE "FileDescription", "Sonic Robo Blast 2\0" VALUE "FileVersion", VERSIONSTRING_RC VALUE "InternalName", "srb2\0" - VALUE "LegalCopyright", "Copyright 1998-2022 by Sonic Team Junior\0" + VALUE "LegalCopyright", "Copyright 1998-2023 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 1e070260e..7b4b6f5cf 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2004-2022 by Sonic Team Junior. +// Copyright (C) 2004-2023 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 74183066e..6b249ca0d 100644 --- a/src/y_inter.h +++ b/src/y_inter.h @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2004-2022 by Sonic Team Junior. +// Copyright (C) 2004-2023 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 b949730e3..ec2b70815 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-2022 by Sonic Team Junior. +// Copyright (C) 2006-2023 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 d7e1ed528..c3cd4f011 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-2022 by Sonic Team Junior. +// Copyright (C) 1999-2023 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. From 2e3963fd16f1cfe435ef1eb3d4a57ccce53021e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Sun, 2 Apr 2023 21:58:42 +0200 Subject: [PATCH 125/586] Fix buffer overflow for setcontrol with 2 arguments --- src/g_input.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/g_input.c b/src/g_input.c index 9d5656253..826dcecbd 100644 --- a/src/g_input.c +++ b/src/g_input.c @@ -993,7 +993,7 @@ static void setcontrol(INT32 (*gc)[2]) { INT32 numctrl; const char *namectrl; - INT32 keynum, keynum1, keynum2; + INT32 keynum, keynum1, keynum2 = 0; INT32 player = ((void*)gc == (void*)&gamecontrolbis ? 1 : 0); boolean nestedoverride = false; @@ -1009,7 +1009,8 @@ static void setcontrol(INT32 (*gc)[2]) return; } keynum1 = G_KeyNameToNum(COM_Argv(2)); - keynum2 = G_KeyNameToNum(COM_Argv(3)); + if (COM_Argc() > 3) + keynum2 = G_KeyNameToNum(COM_Argv(3)); keynum = G_FilterKeyByVersion(numctrl, 0, player, &keynum1, &keynum2, &nestedoverride); if (keynum >= 0) From 8218ce0fe290f7047999328304ea69cfb4c39934 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Fri, 7 Apr 2023 14:49:31 +0200 Subject: [PATCH 126/586] Fix use-after-free when Metal Sonic charges energy balls --- src/p_mobj.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index c8adb6f1d..4281d6e76 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -5665,21 +5665,25 @@ static void P_Boss9Thinker(mobj_t *mobj) missile->fuse = 1; if (missile->fuse > mobj->fuse) - P_RemoveMobj(missile); - - if (mobj->health > mobj->info->damage) { - P_SetScale(missile, FRACUNIT/3); - missile->color = SKINCOLOR_MAGENTA; // sonic OVA/4 purple power + P_RemoveMobj(missile); } else { - P_SetScale(missile, FRACUNIT/5); - missile->color = SKINCOLOR_SUNSET; // sonic cd electric power + if (mobj->health > mobj->info->damage) + { + P_SetScale(missile, FRACUNIT/3); + missile->color = SKINCOLOR_MAGENTA; // sonic OVA/4 purple power + } + else + { + P_SetScale(missile, FRACUNIT/5); + missile->color = SKINCOLOR_SUNSET; // sonic cd electric power + } + missile->destscale = missile->scale*2; + missile->scalespeed = abs(missile->scale - missile->destscale)/missile->fuse; + missile->colorized = true; } - missile->destscale = missile->scale*2; - missile->scalespeed = abs(missile->scale - missile->destscale)/missile->fuse; - missile->colorized = true; } // ...then down. easier than changing the missile's momz after-the-fact From 16ad23f06de09fd00800c055e6da5b78ab3875f6 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Mon, 10 Apr 2023 14:08:53 +0200 Subject: [PATCH 127/586] Fix flag mixup in P_GetOldFOFFlags() --- src/lua_maplib.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 7abe820a5..898651520 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -1910,10 +1910,10 @@ static INT32 P_GetOldFOFFlags(ffloor_t *fflr) result |= FF_OLD_SPINBUST; if (fflr->busttype == BT_STRONG) result |= FF_OLD_STRONGBUST; - if (fflr->fofflags & FF_OLD_RIPPLE) - result |= FOF_RIPPLE; - if (fflr->fofflags & FF_OLD_COLORMAPONLY) - result |= FOF_COLORMAPONLY; + if (fflr->fofflags & FOF_RIPPLE) + result |= FF_OLD_RIPPLE; + if (fflr->fofflags & FOF_COLORMAPONLY) + result |= FF_OLD_COLORMAPONLY; return result; } From 8b77af73780f72bfc128f4e960e4c6a8f07df5f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Mon, 10 Apr 2023 14:55:19 +0200 Subject: [PATCH 128/586] Fix segfault when killing wall spike while it moves --- src/p_mobj.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/p_mobj.c b/src/p_mobj.c index c8adb6f1d..a290bd074 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10061,6 +10061,8 @@ static boolean P_FuseThink(mobj_t *mobj) case MT_SPIKE: case MT_WALLSPIKE: P_SetMobjState(mobj, mobj->state->nextstate); + if (P_MobjWasRemoved(mobj)) + return false; mobj->fuse = mobj->spawnpoint ? mobj->spawnpoint->args[0] : mobj->info->speed; break; case MT_NIGHTSCORE: @@ -10222,6 +10224,9 @@ void P_MobjThinker(mobj_t *mobj) if (mobj->flags2 & MF2_FIRING) P_FiringThink(mobj); + if (P_MobjWasRemoved(mobj)) + return; + if (mobj->type == MT_AMBIENT) { if (leveltime % mobj->health) From 4c02bde4e9771281e96352a0c87222dedb61f0b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Mon, 10 Apr 2023 18:31:12 +0200 Subject: [PATCH 129/586] Fix crash during debug when escaping pterabyte --- 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 d5fb17364..f8df5a023 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -12808,7 +12808,7 @@ void P_PlayerAfterThink(player_t *player) P_KillMobj(ptera, player->mo, player->mo, 0); P_SetObjectMomZ(player->mo, 12*FRACUNIT, false); player->pflags |= PF_APPLYAUTOBRAKE|PF_JUMPED|PF_THOKKED; - P_SetMobjState(player->mo, S_PLAY_ROLL); + P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); break; } From 1cd5e10ab084b2df0649ad3f89e6900c7e852ed4 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Tue, 11 Apr 2023 16:19:27 +0200 Subject: [PATCH 130/586] Fix custom ambient sound mobjs not working --- src/m_cheat.c | 2 +- src/p_mobj.c | 8 +++++++- src/p_mobj.h | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/m_cheat.c b/src/m_cheat.c index 1056ecb02..4ea8d13b4 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -1004,7 +1004,7 @@ static void OP_CycleThings(INT32 amt) } while (mobjinfo[op_currentthing].doomednum == -1 || op_currentthing == MT_NIGHTSDRONE - || mobjinfo[op_currentthing].flags & MF_NOSECTOR + || mobjinfo[op_currentthing].flags & (MF_AMBIENT|MF_NOSECTOR) || (states[mobjinfo[op_currentthing].spawnstate].sprite == SPR_NULL && states[mobjinfo[op_currentthing].seestate].sprite == SPR_NULL) ); diff --git a/src/p_mobj.c b/src/p_mobj.c index c8adb6f1d..0776e4484 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10222,7 +10222,7 @@ void P_MobjThinker(mobj_t *mobj) if (mobj->flags2 & MF2_FIRING) P_FiringThink(mobj); - if (mobj->type == MT_AMBIENT) + if (mobj->flags & MF_AMBIENT) { if (leveltime % mobj->health) return; @@ -13272,6 +13272,12 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean mobj->flags2 |= MF2_STRONGBOX; } } + // Custom ambient sounds + if ((mobj->flags & MF_AMBIENT) && mobj->type != MT_AMBIENT) + { + mobj->threshold = mobj->info->seesound; + mobj->health = mobj->info->spawnhealth; + } return true; } diff --git a/src/p_mobj.h b/src/p_mobj.h index 2cf177d23..a839eaba6 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -118,7 +118,7 @@ typedef enum // Don't apply gravity (every tic); object will float, keeping current height // or changing it actively. MF_NOGRAVITY = 1<<9, - // This object is an ambient sound. Obsolete, but keep this around for backwards compatibility. + // This object is an ambient sound. MF_AMBIENT = 1<<10, // Slide this object when it hits a wall. MF_SLIDEME = 1<<11, From 846cf71e6a0ce18cb806e74669265d81654163ec Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Tue, 11 Apr 2023 18:48:23 +0200 Subject: [PATCH 131/586] F_StartTitleScreen: Make sure the level header for gamemap always exists --- src/f_finale.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/f_finale.c b/src/f_finale.c index ea5ce62bd..fe94b924c 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -2503,6 +2503,8 @@ void F_StartTitleScreen(void) { titlemapinaction = TITLEMAP_OFF; gamemap = 1; // g_game.c + if (!mapheaderinfo[gamemap-1]) + P_AllocMapHeader(gamemap-1); CON_ClearHUD(); } From 8486bd083a0eb96bd801dec5f6d86ee1295714b6 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Tue, 11 Apr 2023 19:13:30 +0200 Subject: [PATCH 132/586] R_SkinUsable: Only check header of current map if one exists --- 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 56e322e87..b10a78c18 100644 --- a/src/r_skins.c +++ b/src/r_skins.c @@ -225,7 +225,7 @@ boolean R_SkinUsable(INT32 playernum, INT32 skinnum) return true; } - if (Playing() && (R_SkinAvailable(mapheaderinfo[gamemap-1]->forcecharacter) == skinnum)) + if (Playing() && mapheaderinfo[gamemap-1] && (R_SkinAvailable(mapheaderinfo[gamemap-1]->forcecharacter) == skinnum)) { // Force 1. return true; From cb849ca4f03a6d209cdfb972ec88ecbfd941d6ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Tue, 11 Apr 2023 22:13:29 +0200 Subject: [PATCH 133/586] Fix segfault when first mobj in overlaycap is removed --- src/p_mobj.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/p_mobj.c b/src/p_mobj.c index c8adb6f1d..d6352bc2a 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6900,6 +6900,13 @@ static void P_AddOverlay(mobj_t *thing) static void P_RemoveOverlay(mobj_t *thing) { mobj_t *mo; + if (overlaycap == thing) + { + P_SetTarget(&overlaycap, thing->hnext); + P_SetTarget(&thing->hnext, NULL); + return; + } + for (mo = overlaycap; mo; mo = mo->hnext) { if (mo->hnext != thing) From cf67ba1d0113cea9105a81b19083d0ed93d2fb71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Tue, 11 Apr 2023 22:51:18 +0200 Subject: [PATCH 134/586] fixup! Fix segfault when killing wall spike while it moves --- src/p_mobj.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index a290bd074..6a089074c 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10224,9 +10224,6 @@ void P_MobjThinker(mobj_t *mobj) if (mobj->flags2 & MF2_FIRING) P_FiringThink(mobj); - if (P_MobjWasRemoved(mobj)) - return; - if (mobj->type == MT_AMBIENT) { if (leveltime % mobj->health) From 4b6de096e516bf4579d2367639ae71d12ea865d2 Mon Sep 17 00:00:00 2001 From: spherallic Date: Wed, 12 Apr 2023 00:59:08 +0200 Subject: [PATCH 135/586] Define cv_addons_folder in dedicated --- src/d_netcmd.c | 4 ++-- src/r_main.c | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 1fbdfdce2..28e7727e1 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -794,8 +794,8 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_digitaldeadzone2); // filesrch.c - CV_RegisterVar(&cv_addons_option); - CV_RegisterVar(&cv_addons_folder); + //CV_RegisterVar(&cv_addons_option); // These two are now defined + //CV_RegisterVar(&cv_addons_folder); // in R_RegisterEngineStuff CV_RegisterVar(&cv_addons_md5); CV_RegisterVar(&cv_addons_showall); CV_RegisterVar(&cv_addons_search_type); diff --git a/src/r_main.c b/src/r_main.c index 4d801dc80..53f6ee2f9 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -36,6 +36,7 @@ #include "r_main.h" #include "i_system.h" // I_GetPreciseTime #include "r_fps.h" // Frame interpolation/uncapped +#include "filesrch.c" // cv_addons_folder #ifdef HWRENDER #include "hardware/hw_main.h" @@ -1589,6 +1590,10 @@ void R_RegisterEngineStuff(void) CV_RegisterVar(&cv_flipcam); CV_RegisterVar(&cv_flipcam2); + // Other filesrch.c consvars are defined in D_RegisterClientCommands + CV_RegisterVar(&cv_addons_option); + CV_RegisterVar(&cv_addons_folder); + // Enough for dedicated server if (dedicated) return; From 488f0fdfab57e30478dcb87032ac0368cd064c5c Mon Sep 17 00:00:00 2001 From: spherallic Date: Wed, 12 Apr 2023 20:06:02 +0200 Subject: [PATCH 136/586] bruh --- src/d_netcmd.c | 6 +++++- src/r_main.c | 5 ----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 64a61d701..0eedd4542 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -613,6 +613,10 @@ void D_RegisterServerCommands(void) CV_RegisterVar(&cv_allowseenames); + // Other filesrch.c consvars are defined in D_RegisterClientCommands + CV_RegisterVar(&cv_addons_option); + CV_RegisterVar(&cv_addons_folder); + CV_RegisterVar(&cv_dummyconsvar); } @@ -795,7 +799,7 @@ void D_RegisterClientCommands(void) // filesrch.c //CV_RegisterVar(&cv_addons_option); // These two are now defined - //CV_RegisterVar(&cv_addons_folder); // in R_RegisterEngineStuff + //CV_RegisterVar(&cv_addons_folder); // in D_RegisterServerCommands CV_RegisterVar(&cv_addons_md5); CV_RegisterVar(&cv_addons_showall); CV_RegisterVar(&cv_addons_search_type); diff --git a/src/r_main.c b/src/r_main.c index 2a31227d1..ebf7a28bf 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -36,7 +36,6 @@ #include "r_main.h" #include "i_system.h" // I_GetPreciseTime #include "r_fps.h" // Frame interpolation/uncapped -#include "filesrch.c" // cv_addons_folder #ifdef HWRENDER #include "hardware/hw_main.h" @@ -1590,10 +1589,6 @@ void R_RegisterEngineStuff(void) CV_RegisterVar(&cv_flipcam); CV_RegisterVar(&cv_flipcam2); - // Other filesrch.c consvars are defined in D_RegisterClientCommands - CV_RegisterVar(&cv_addons_option); - CV_RegisterVar(&cv_addons_folder); - // Enough for dedicated server if (dedicated) return; From c61594931debe50e520b1737810331c39f7d776c Mon Sep 17 00:00:00 2001 From: spherallic Date: Fri, 14 Apr 2023 00:28:14 +0200 Subject: [PATCH 137/586] Fix titlecard hook being inconsistent on map load --- 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 cce8ea9f2..206c93273 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1412,7 +1412,7 @@ void ST_drawTitleCard(void) lt_lasttic = lt_ticker; luahook: - if (renderisnewtic) + //if (renderisnewtic) { LUA_HUD_ClearDrawList(luahuddrawlist_titlecard); LUA_HUDHOOK(titlecard, luahuddrawlist_titlecard); From 930b1355ed5634110dfa6895b14d0f510c4a70f6 Mon Sep 17 00:00:00 2001 From: spherallic Date: Fri, 14 Apr 2023 12:03:21 +0200 Subject: [PATCH 138/586] Don't call P_ResetCamera when spawning a bot --- src/g_game.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/g_game.c b/src/g_game.c index 8c497a72d..a0ea9ae88 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2825,6 +2825,9 @@ void G_MovePlayerToSpawnOrStarpost(INT32 playernum) R_ResetMobjInterpolationState(players[playernum].mo); + if (players[playernum].bot) // don't reset the camera for bots + return; + if (playernum == consoleplayer) P_ResetCamera(&players[playernum], &camera); else if (playernum == secondarydisplayplayer) From e4f92cc6676afe8af23c01b1d1be6cc1dd3f4dc2 Mon Sep 17 00:00:00 2001 From: spherallic Date: Tue, 18 Apr 2023 02:04:23 +0200 Subject: [PATCH 139/586] Always important --- src/w_wad.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/w_wad.c b/src/w_wad.c index 40073fc55..456afef7b 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -1035,7 +1035,7 @@ UINT16 W_InitFolder(const char *path, boolean mainfile, boolean startup) return W_InitFileError(path, startup); } - important = 0; /// \todo Implement a W_VerifyFolder. + important = 1; /// \todo Implement a W_VerifyFolder. // Remove path delimiters. p = path + (strlen(path) - 1); From 072dd2eda761981df5dbd4165d4ec6638d599cc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Tue, 18 Apr 2023 20:46:13 +0200 Subject: [PATCH 140/586] Fix segfault when removing source from ShouldDamage --- src/p_inter.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/p_inter.c b/src/p_inter.c index 8bc5c95e4..de13202ab 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -3546,6 +3546,8 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da UINT8 shouldForce = LUA_HookShouldDamage(target, inflictor, source, damage, damagetype); if (P_MobjWasRemoved(target)) return (shouldForce == 1); // mobj was removed + if (P_MobjWasRemoved(source)) + source = NULL; if (shouldForce == 1) force = true; else if (shouldForce == 2) From ad412c9700cb19dec4ad795857796f8bb5900ec9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Tue, 18 Apr 2023 22:08:26 +0200 Subject: [PATCH 141/586] Fix segfault when damaging mobj with no painstate --- src/p_inter.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/p_inter.c b/src/p_inter.c index 8bc5c95e4..fc193ac94 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -3763,6 +3763,9 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da else P_SetMobjState(target, target->info->painstate); + if (P_MobjWasRemoved(target)) + return false; + if (target->type == MT_HIVEELEMENTAL) target->extravalue1 += 3; From e5a1fee7596a5ed15034f5604693a22c9635d739 Mon Sep 17 00:00:00 2001 From: spherallic Date: Wed, 19 Apr 2023 00:21:10 +0200 Subject: [PATCH 142/586] Adjust default look/turn axis for new SDL2 version --- src/g_game.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index a0ea9ae88..b7f3eb24a 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -411,8 +411,8 @@ consvar_t cv_cam_lockonboss[2] = { 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); -consvar_t cv_lookaxis = CVAR_INIT ("joyaxis_look", "Y-Rudder-", CV_SAVE, joyaxis_cons_t, NULL); -consvar_t cv_turnaxis = CVAR_INIT ("joyaxis_turn", "X-Rudder", CV_SAVE, joyaxis_cons_t, NULL); +consvar_t cv_lookaxis = CVAR_INIT ("joyaxis_look", "X-Rudder-", CV_SAVE, joyaxis_cons_t, NULL); +consvar_t cv_turnaxis = CVAR_INIT ("joyaxis_turn", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_jumpaxis = CVAR_INIT ("joyaxis_jump", "None", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_spinaxis = CVAR_INIT ("joyaxis_spin", "None", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_fireaxis = CVAR_INIT ("joyaxis_fire", "Z-Rudder", CV_SAVE, joyaxis_cons_t, NULL); @@ -422,8 +422,8 @@ consvar_t cv_digitaldeadzone = CVAR_INIT ("joy_digdeadzone", "0.25", CV_FLOAT|CV consvar_t cv_moveaxis2 = CVAR_INIT ("joyaxis2_move", "Y-Axis", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_sideaxis2 = CVAR_INIT ("joyaxis2_side", "X-Axis", CV_SAVE, joyaxis_cons_t, NULL); -consvar_t cv_lookaxis2 = CVAR_INIT ("joyaxis2_look", "Y-Rudder-", CV_SAVE, joyaxis_cons_t, NULL); -consvar_t cv_turnaxis2 = CVAR_INIT ("joyaxis2_turn", "X-Rudder", CV_SAVE, joyaxis_cons_t, NULL); +consvar_t cv_lookaxis2 = CVAR_INIT ("joyaxis2_look", "X-Rudder-", CV_SAVE, joyaxis_cons_t, NULL); +consvar_t cv_turnaxis2 = CVAR_INIT ("joyaxis2_turn", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_jumpaxis2 = CVAR_INIT ("joyaxis2_jump", "None", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_spinaxis2 = CVAR_INIT ("joyaxis2_spin", "None", CV_SAVE, joyaxis_cons_t, NULL); consvar_t cv_fireaxis2 = CVAR_INIT ("joyaxis2_fire", "Z-Rudder", CV_SAVE, joyaxis_cons_t, NULL); From 6ff37b47d9b60b8c71768ba3ca2cb9d1d8aae333 Mon Sep 17 00:00:00 2001 From: spherallic Date: Wed, 19 Apr 2023 12:13:29 +0200 Subject: [PATCH 143/586] Skip emerald bounce logic in Y_Ticker on dedicated --- src/y_inter.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/y_inter.c b/src/y_inter.c index 7b4b6f5cf..cfd1e106e 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -1133,7 +1133,11 @@ void Y_Ticker(void) } // emerald bounce - if (intertic <= 1) + if (dedicated) + { + // dedicated servers don't need this, especially since it crashes when stagefailed + } + else if (intertic <= 1) { data.spec.emeraldbounces = 0; data.spec.emeraldmomy = 20; From c2c430853ccb47174281908f131f87a0059ac560 Mon Sep 17 00:00:00 2001 From: spherallic Date: Wed, 19 Apr 2023 20:17:50 +0200 Subject: [PATCH 144/586] If Lua disabled intermission emeralds, skip sounds --- 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 cfd1e106e..f0777add7 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -1133,9 +1133,10 @@ void Y_Ticker(void) } // emerald bounce - if (dedicated) + if (dedicated || !LUA_HudEnabled(hud_intermissionemeralds)) { // dedicated servers don't need this, especially since it crashes when stagefailed + // also skip this if Lua disabled intermission emeralds, so it doesn't play sounds } else if (intertic <= 1) { From 2d3153079b046ae9c5f585e77d677022aabf957b Mon Sep 17 00:00:00 2001 From: SteelT Date: Fri, 21 Apr 2023 12:57:37 -0400 Subject: [PATCH 145/586] A_PointyThink crash fix (patch from #827) Fixes A_PointyThink crashing in certain scenarios --- src/p_enemy.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/p_enemy.c b/src/p_enemy.c index 63d430eb6..ca947fc20 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -1589,6 +1589,10 @@ void A_PointyThink(mobj_t *actor) if (!actor->tracer) // For some reason we do not have spike balls... return; + // Catch case where actor lastlook is -1 (which segfaults the following blocks) + if (actor->lastlook < 0) + return; + // Position spike balls relative to the value of 'lastlook'. ball = actor->tracer; From 98dcf2d228141015c6fcdc2a054454357037dec6 Mon Sep 17 00:00:00 2001 From: spherallic Date: Mon, 24 Apr 2023 23:23:47 +0200 Subject: [PATCH 146/586] Tweak yellow/green/blue/red/peridot text colors --- src/console.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/console.c b/src/console.c index 33d59046e..5ada6dd94 100644 --- a/src/console.c +++ b/src/console.c @@ -382,16 +382,16 @@ static void CON_SetupColormaps(void) // 0x1 0x3 0x9 0xF 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, 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(yellowmap, 82, 82, 73, 73, 73, 74, 74, 74, 66, 66, 66, 66, 67, 67, 67, 68); + colset(lgreenmap, 96, 96, 98, 98, 98, 100, 100, 100, 103, 103, 103, 103, 105, 105, 105, 107); + colset(bluemap, 146, 146, 147, 147, 147, 148, 148, 148, 149, 149, 149, 149, 150, 150, 150, 151); + colset(redmap, 32, 32, 33, 33, 33, 34, 34, 34, 35, 35, 35, 35, 37, 37, 37, 39); 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(peridotmap, 73, 73, 188, 188, 188, 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); From d6cafea571cab556c89ff31343af0242a797378b Mon Sep 17 00:00:00 2001 From: spherallic Date: Fri, 28 Apr 2023 15:30:02 +0200 Subject: [PATCH 147/586] Don't force FLS to false after a pre-map cutscene --- src/f_finale.c | 13 +++++++------ src/f_finale.h | 2 +- src/g_game.c | 4 ++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/f_finale.c b/src/f_finale.c index fe94b924c..6560c24f1 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -337,7 +337,7 @@ static tic_t introscenetime[NUMINTROSCENES] = }; // custom intros -void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean resetplayer); +void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean resetplayer, boolean FLS); void F_StartIntro(void) { @@ -349,7 +349,7 @@ void F_StartIntro(void) if (!cutscenes[introtoplay - 1]) D_StartTitle(); else - F_StartCustomCutscene(introtoplay - 1, false, false); + F_StartCustomCutscene(introtoplay - 1, false, false, false); return; } @@ -1257,7 +1257,7 @@ void F_StartCredits(void) if (creditscutscene) { - F_StartCustomCutscene(creditscutscene - 1, false, false); + F_StartCustomCutscene(creditscutscene - 1, false, false, false); return; } @@ -3859,7 +3859,7 @@ static INT32 scenenum, cutnum; static INT32 picxpos, picypos, picnum, pictime, picmode, numpics, pictoloop; static INT32 textxpos, textypos; static boolean cutsceneover = false; -static boolean runningprecutscene = false, precutresetplayer = false; +static boolean runningprecutscene = false, precutresetplayer = false, precutFLS = false; static void F_AdvanceToNextScene(void) { @@ -3928,7 +3928,7 @@ void F_EndCutScene(void) if (runningprecutscene) { if (server) - D_MapChange(gamemap, gametype, ultimatemode, precutresetplayer, 0, true, false); + D_MapChange(gamemap, gametype, ultimatemode, precutresetplayer, 0, true, precutFLS); } else { @@ -3943,7 +3943,7 @@ void F_EndCutScene(void) } } -void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean resetplayer) +void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean resetplayer, boolean FLS) { if (!cutscenes[cutscenenum]) return; @@ -3962,6 +3962,7 @@ void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean reset cutsceneover = false; runningprecutscene = precutscene; precutresetplayer = resetplayer; + precutFLS = FLS; scenenum = picnum = 0; cutnum = cutscenenum; diff --git a/src/f_finale.h b/src/f_finale.h index e37b45253..6ea1b5537 100644 --- a/src/f_finale.h +++ b/src/f_finale.h @@ -52,7 +52,7 @@ void F_EndingDrawer(void); void F_CreditTicker(void); void F_CreditDrawer(void); -void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean resetplayer); +void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean resetplayer, boolean FLS); void F_CutsceneDrawer(void); void F_EndCutScene(void); diff --git a/src/g_game.c b/src/g_game.c index b7f3eb24a..0d5181b07 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -4108,7 +4108,7 @@ void G_AfterIntermission(void) && stagefailed == false) { // Start a custom cutscene. - F_StartCustomCutscene(mapheaderinfo[gamemap-1]->cutscenenum-1, false, false); + F_StartCustomCutscene(mapheaderinfo[gamemap-1]->cutscenenum-1, false, false, false); } else { @@ -4958,7 +4958,7 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean imcontinuing = false; if ((gametyperules & GTR_CUTSCENES) && !skipprecutscene && mapheaderinfo[gamemap-1]->precutscenenum && !modeattacking && !(marathonmode & MA_NOCUTSCENES)) // Start a custom cutscene. - F_StartCustomCutscene(mapheaderinfo[gamemap-1]->precutscenenum-1, true, resetplayer); + F_StartCustomCutscene(mapheaderinfo[gamemap-1]->precutscenenum-1, true, resetplayer, FLS); else G_DoLoadLevel(resetplayer); From 901c7362ed65434ad83c623506d8a00fc4b9099d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Sun, 30 Apr 2023 14:05:10 +0200 Subject: [PATCH 148/586] Fix segfault when P_RemoveMobj is called within A_FaceTarget action --- src/p_enemy.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/src/p_enemy.c b/src/p_enemy.c index 63d430eb6..af629a299 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -1571,6 +1571,8 @@ void A_PointyThink(mobj_t *actor) // Okay, we found the closest player. Let's move based on his movement. P_SetTarget(&actor->target, player->mo); A_FaceTarget(actor); + if (P_MobjWasRemoved(actor)) + return; 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 @@ -1686,6 +1688,8 @@ void A_HoodFire(mobj_t *actor) } A_FaceTarget(actor); + if (P_MobjWasRemoved(actor)) + return; if (!(arrow = P_SpawnMissile(actor, actor->target, (mobjtype_t)locvar1))) return; @@ -2266,6 +2270,8 @@ void A_VultureVtol(mobj_t *actor) actor->flags |= MF_FLOAT; A_FaceTarget(actor); + if (P_MobjWasRemoved(actor)) + return; S_StopSound(actor); @@ -2364,6 +2370,9 @@ void A_VultureHover(mobj_t *actor) P_VultureHoverParticle(actor); A_FaceTarget(actor); + if (P_MobjWasRemoved(actor)) + return; + targetz = actor->target->z + actor->target->height / 2; for (i = -1; i <= 1; i++) { @@ -2680,6 +2689,8 @@ void A_LobShot(mobj_t *actor) return; A_FaceTarget(actor); + if (P_MobjWasRemoved(actor)) + return; if (actor->eflags & MFE_VERTICALFLIP) { @@ -2775,6 +2786,8 @@ void A_FireShot(mobj_t *actor) return; A_FaceTarget(actor); + if (P_MobjWasRemoved(actor)) + return; if (actor->eflags & MFE_VERTICALFLIP) z = actor->z + actor->height - FixedMul(48*FRACUNIT + locvar2*FRACUNIT, actor->scale); @@ -2813,6 +2826,8 @@ void A_SuperFireShot(mobj_t *actor) return; A_FaceTarget(actor); + if (P_MobjWasRemoved(actor)) + return; if (actor->eflags & MFE_VERTICALFLIP) z = actor->z + actor->height - FixedMul(48*FRACUNIT + locvar2*FRACUNIT, actor->scale); @@ -2860,6 +2875,8 @@ void A_BossFireShot(mobj_t *actor) return; A_FaceTarget(actor); + if (P_MobjWasRemoved(actor)) + return; switch (locvar2) { @@ -2947,6 +2964,8 @@ void A_Boss7FireMissiles(mobj_t *actor) } A_FaceTarget(actor); + if (P_MobjWasRemoved(actor)) + return; S_StartSound(NULL, locvar2); @@ -3331,6 +3350,8 @@ void A_SkullAttack(mobj_t *actor) if (actor->info->activesound) S_StartSound(actor, actor->info->activesound); A_FaceTarget(actor); + if (P_MobjWasRemoved(actor)) + return; dist = P_AproxDistance(dest->x - actor->x, dest->y - actor->y); @@ -3442,6 +3463,9 @@ void A_BossZoom(mobj_t *actor) if (actor->info->attacksound) S_StartAttackSound(actor, actor->info->attacksound); A_FaceTarget(actor); + if (P_MobjWasRemoved(actor)) + return; + 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)); @@ -5539,6 +5563,9 @@ void A_JetgShoot(mobj_t *actor) return; A_FaceTarget(actor); + if (P_MobjWasRemoved(actor)) + return; + P_SpawnMissile(actor, actor->target, (mobjtype_t)actor->info->raisestate); if (ultimatemode) @@ -5573,6 +5600,9 @@ void A_ShootBullet(mobj_t *actor) return; A_FaceTarget(actor); + if (P_MobjWasRemoved(actor)) + return; + P_SpawnMissile(actor, actor->target, (mobjtype_t)actor->info->raisestate); if (actor->info->attacksound) @@ -7431,6 +7461,8 @@ void A_Boss7Chase(mobj_t *actor) && (actor->target->player->powers[pw_carry] == CR_GENERIC)) { A_FaceTarget(actor); + if (P_MobjWasRemoved(actor)) + return; P_SetMobjState(actor, S_BLACKEGG_SHOOT1); actor->movecount = TICRATE + P_RandomByte()/2; return; @@ -7448,6 +7480,8 @@ void A_Boss7Chase(mobj_t *actor) if (actor->z < 1056*FRACUNIT) { A_FaceTarget(actor); + if (P_MobjWasRemoved(actor)) + return; P_SetMobjState(actor, actor->info->xdeathstate); actor->movecount = 7*TICRATE + P_RandomByte(); break; @@ -7456,6 +7490,8 @@ void A_Boss7Chase(mobj_t *actor) /* FALLTHRU */ case 1: // Chaingun Goop A_FaceTarget(actor); + if (P_MobjWasRemoved(actor)) + return; P_SetMobjState(actor, S_BLACKEGG_SHOOT1); if (actor->health > actor->info->damage) @@ -7465,6 +7501,8 @@ void A_Boss7Chase(mobj_t *actor) break; case 2: // Homing Missile A_FaceTarget(actor); + if (P_MobjWasRemoved(actor)) + return; P_SetMobjState(actor, actor->info->missilestate); S_StartSound(0, sfx_beflap); break; @@ -8182,6 +8220,9 @@ void A_Boss3Path(mobj_t *actor) P_SetTarget(&actor->target, actor->tracer->target); var1 = 0, var2 = 0; A_FaceTarget(actor); + if (P_MobjWasRemoved(actor)) + return; + if (actor->tracer->state == &states[actor->tracer->info->missilestate]) P_SetMobjState(actor, actor->info->missilestate); return; @@ -9856,6 +9897,8 @@ void A_SplitShot(mobj_t *actor) return; A_FaceTarget(actor); + if (P_MobjWasRemoved(actor)) + return; { const angle_t an = (actor->angle + ANGLE_90) >> ANGLETOFINESHIFT; const fixed_t fasin = FINESINE(an); @@ -9920,6 +9963,9 @@ void A_MultiShot(mobj_t *actor) if (actor->target) A_FaceTarget(actor); + if (P_MobjWasRemoved(actor)) + return; + if(loc1lw > 90) ad = FixedMul(90*FRACUNIT, actor->scale); else @@ -11064,6 +11110,8 @@ void A_VileTarget(mobj_t *actor) return; A_FaceTarget(actor); + if (P_MobjWasRemoved(actor)) + return; // Determine object to spawn if (locvar1 <= 0 || locvar1 >= NUMMOBJTYPES) @@ -11151,6 +11199,8 @@ void A_VileAttack(mobj_t *actor) return; A_FaceTarget(actor); + if (P_MobjWasRemoved(actor)) + return; if (locvar1 <= 0 || locvar1 >= NUMSFX) soundtoplay = sfx_brakrx; @@ -11469,6 +11519,8 @@ void A_BrakFireShot(mobj_t *actor) return; A_FaceTarget(actor); + if (P_MobjWasRemoved(actor)) + return; x = actor->x + P_ReturnThrustX(actor, actor->angle, FixedMul(64*FRACUNIT, actor->scale)) @@ -11586,6 +11638,9 @@ void A_BrakLobShot(mobj_t *actor) // Okay, complicated math done. Let's fire our object already, sheesh. A_FaceTarget(actor); + if (P_MobjWasRemoved(actor)) + return; + if (locvar1 <= 0 || locvar1 >= NUMMOBJTYPES) typeOfShot = MT_CANNONBALL; else typeOfShot = (mobjtype_t)locvar1; @@ -12670,6 +12725,8 @@ void A_WhoCaresIfYourSonIsABee(mobj_t *actor) return; A_FaceTarget(actor); + if (P_MobjWasRemoved(actor)) + return; if (actor->extravalue1) actor->extravalue1--; From 03971f58a924e41c0f794a9dcbe459052835a381 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Thu, 4 May 2023 22:42:51 +0200 Subject: [PATCH 149/586] Fix segfault when shields are removed after thinking --- src/p_mobj.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index ee4440b73..0704c15a7 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6765,7 +6765,8 @@ void P_RunShields(void) // run shields for (i = 0; i < numshields; i++) { - P_ShieldLook(shields[i], shields[i]->threshold); + if (!P_MobjWasRemoved(shields[i])) + P_ShieldLook(shields[i], shields[i]->threshold); P_SetTarget(&shields[i], NULL); } numshields = 0; From ed46dd08a6a2ae85f7eebc9d15cb5c2c024e0e96 Mon Sep 17 00:00:00 2001 From: spherallic Date: Sun, 7 May 2023 17:33:12 +0200 Subject: [PATCH 150/586] Prevent tmthing crash with P_SpawnParaloop in Lua --- src/lua_baselib.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 6e258c82a..db06d53dd 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -874,6 +874,7 @@ static int lib_pGetClosestAxis(lua_State *L) static int lib_pSpawnParaloop(lua_State *L) { + mobj_t *ptmthing = tmthing; fixed_t x = luaL_checkfixed(L, 1); fixed_t y = luaL_checkfixed(L, 2); fixed_t z = luaL_checkfixed(L, 3); @@ -890,6 +891,7 @@ static int lib_pSpawnParaloop(lua_State *L) if (nstate >= NUMSTATES) return luaL_error(L, "state %d out of range (0 - %d)", nstate, NUMSTATES-1); P_SpawnParaloop(x, y, z, radius, number, type, nstate, rotangle, spawncenter); + P_SetTarget(&tmthing, ptmthing); return 0; } From b99ecde7b85ae78482762f0e73162b817e7edcfd Mon Sep 17 00:00:00 2001 From: spherallic Date: Sun, 7 May 2023 17:42:39 +0200 Subject: [PATCH 151/586] Fix [BOT] indicator color not being cleared --- 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 db06d53dd..6f5b46e30 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -3589,14 +3589,14 @@ static int lib_gAddPlayer(lua_State *L) char joinmsg[256]; // Truncate bot name - player_names[newplayernum][sizeof(*player_names) - 7] = '\0'; // The length of colored [BOT] + 1 + player_names[newplayernum][sizeof(*player_names) - 8] = '\0'; // The length of colored [BOT] + 1 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); // Append blue [BOT] tag at the end - strlcat(player_names[newplayernum], "\x84[BOT]", sizeof(*player_names)); + strlcat(player_names[newplayernum], "\x84[BOT]\x80", sizeof(*player_names)); } LUA_PushUserdata(L, newplayer, META_PLAYER); From b487a71533e4d3058b703362b6a828d51069c6cc Mon Sep 17 00:00:00 2001 From: spherallic Date: Sun, 14 May 2023 16:26:34 +0200 Subject: [PATCH 152/586] Fix light fades being unable to lower light levels --- src/p_lights.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_lights.c b/src/p_lights.c index 75455da73..4b6a3673b 100644 --- a/src/p_lights.c +++ b/src/p_lights.c @@ -353,8 +353,8 @@ void P_FadeLightBySector(sector_t *sector, INT32 destvalue, INT32 speed, boolean else { // Speed means increment per tic (literally speed). - ll->timer = FixedDiv((destvalue<fixedcurlevel, speed<>FRACBITS; - ll->fixedpertic = speed<timer = abs(FixedDiv((destvalue<fixedcurlevel, speed<>FRACBITS); + ll->fixedpertic = ll->destlevel < ll->sourcelevel ? -speed< Date: Thu, 4 May 2023 16:17:10 +0200 Subject: [PATCH 153/586] 2.2.11 --- appveyor.yml | 2 +- assets/CMakeLists.txt | 1 + src/config.h.in | 5 +++-- src/doomdef.h | 2 +- src/version.h | 2 +- src/win32/Srb2win.rc | 4 ++-- 6 files changed, 9 insertions(+), 7 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 348b727b1..e3348d35c 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 2.2.10.{branch}-{build} +version: 2.2.11.{branch}-{build} os: MinGW environment: diff --git a/assets/CMakeLists.txt b/assets/CMakeLists.txt index de164b23f..dfb2f4180 100644 --- a/assets/CMakeLists.txt +++ b/assets/CMakeLists.txt @@ -29,6 +29,7 @@ set(SRB2_ASSETS_GAME "srb2.pk3" "player.dta" "zones.pk3" + "patch.pk3" "music.dta" "models.dat" ) diff --git a/src/config.h.in b/src/config.h.in index 22cfd6481..3d6d98375 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -27,12 +27,13 @@ * Last updated 2020 / 10 / 02 - v2.2.8 - patch.pk3 * Last updated 2021 / 05 / 06 - v2.2.9 - patch.pk3 & zones.pk3 * Last updated 2022 / 03 / 06 - v2.2.10 - main assets + * Last updated 2023 / 05 / 02 - v2.2.11 - patch.pk3 & zones.pk3 */ #define ASSET_HASH_SRB2_PK3 "ad911f29a28a18968ee5b2d11c2acb39" -#define ASSET_HASH_ZONES_PK3 "188a2bfd552196609323fc91ec1cdb22" +#define ASSET_HASH_ZONES_PK3 "1c8adf8d079ecb87d00081f158acf3c7" #define ASSET_HASH_PLAYER_DTA "2e7aaae8a6b1b77d90ffe7606ceadb6c" #ifdef USE_PATCH_DTA -#define ASSET_HASH_PATCH_PK3 "7d467a883f7887b3c311798ee2f56b6a" +#define ASSET_HASH_PATCH_PK3 "2e69558bce3b9610624549a75e29e19b" #endif #endif diff --git a/src/doomdef.h b/src/doomdef.h index 3abe27112..d521d4fbb 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -152,7 +152,7 @@ extern char logfilename[1024]; // Does this version require an added patch file? // Comment or uncomment this as necessary. -// #define USE_PATCH_DTA +#define USE_PATCH_DTA // Enforce a limit of loaded WAD files. //#define ENFORCE_WAD_LIMIT diff --git a/src/version.h b/src/version.h index f8b09ada6..083c53134 100644 --- a/src/version.h +++ b/src/version.h @@ -12,4 +12,4 @@ #define MODVERSION 52 // Define this as a prerelease version suffix (pre#, RC#) -#define BETAVERSION "pre3" +//#define BETAVERSION "pre1" diff --git a/src/win32/Srb2win.rc b/src/win32/Srb2win.rc index 07898dbc1..869c0e7d3 100644 --- a/src/win32/Srb2win.rc +++ b/src/win32/Srb2win.rc @@ -77,8 +77,8 @@ END #include "../doomdef.h" // Needed for version string VS_VERSION_INFO VERSIONINFO - FILEVERSION 2,2,10,0 - PRODUCTVERSION 2,2,10,0 + FILEVERSION 2,2,11,0 + PRODUCTVERSION 2,2,11,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L From 6bb3ee226f825a013bd17b200d4d491e3170d780 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Tue, 16 May 2023 19:16:14 +0200 Subject: [PATCH 154/586] Fix segfault when going up steep slopes in rare cases --- 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 cf7807d4e..48a13a07d 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -869,7 +869,7 @@ fixed_t P_GetWallTransferMomZ(mobj_t *mo, pslope_t *slope) vector3_t slopemom, axis; angle_t ang; - if (mo->standingslope->flags & SL_NOPHYSICS) + if (slope->flags & SL_NOPHYSICS) return 0; // If there's physics, time for launching. From d4951f7cdd804a237ded2ed66711d69901673636 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Tue, 16 May 2023 22:18:11 +0200 Subject: [PATCH 155/586] Fix segfault when Crushstaceans hit a player with Armageddon shield --- 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 ca947fc20..618665c97 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -2231,7 +2231,7 @@ void A_CrushclawLaunch(mobj_t *actor) } } - if (!actor->target) + if (P_MobjWasRemoved(actor->target)) return; { From 2f98cd3b972b35427ef42978af46bade61874f5e Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Fri, 19 May 2023 14:26:30 -0300 Subject: [PATCH 156/586] Fix I_GetFreeMem --- src/android/i_system.c | 2 +- src/dummy/i_system.c | 2 +- src/i_system.h | 2 +- src/sdl/i_system.c | 13 ++++++------- src/z_zone.c | 10 +++++----- 5 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/android/i_system.c b/src/android/i_system.c index f0edcc17e..ff8b88de5 100644 --- a/src/android/i_system.c +++ b/src/android/i_system.c @@ -24,7 +24,7 @@ static INT64 start_time; // as microseconds since the epoch // I should probably return how much memory is remaining // for this process, considering Android's process memory limit. -UINT32 I_GetFreeMem(UINT32 *total) +size_t I_GetFreeMem(size_t *total) { // what the heck? sysinfo() is partially missing in bionic? /* struct sysinfo si; */ diff --git a/src/dummy/i_system.c b/src/dummy/i_system.c index 997115ad0..00550c410 100644 --- a/src/dummy/i_system.c +++ b/src/dummy/i_system.c @@ -8,7 +8,7 @@ UINT8 graphics_started = 0; UINT8 keyboard_started = 0; -UINT32 I_GetFreeMem(UINT32 *total) +size_t I_GetFreeMem(UINT32 *total) { *total = 0; return 0; diff --git a/src/i_system.h b/src/i_system.h index 957150fe6..deea9f8a8 100644 --- a/src/i_system.h +++ b/src/i_system.h @@ -40,7 +40,7 @@ extern UINT8 keyboard_started; \return free memory in the system */ -UINT32 I_GetFreeMem(UINT32 *total); +size_t I_GetFreeMem(size_t *total); /** \brief Returns precise time value for performance measurement. The precise time should be a monotonically increasing counter, and will wrap. diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index e328bedc2..67ee8d668 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -2962,8 +2962,7 @@ static long get_entry(const char* name, const char* buf) } #endif -// quick fix for compil -UINT32 I_GetFreeMem(UINT32 *total) +size_t I_GetFreeMem(size_t *total) { #ifdef FREEBSD struct vmmeter sum; @@ -3011,14 +3010,14 @@ UINT32 I_GetFreeMem(UINT32 *total) info.dwLength = sizeof (MEMORYSTATUS); GlobalMemoryStatus( &info ); if (total) - *total = (UINT32)info.dwTotalPhys; - return (UINT32)info.dwAvailPhys; + *total = (size_t)info.dwTotalPhys; + return (size_t)info.dwAvailPhys; #elif defined (__linux__) /* Linux */ char buf[1024]; char *memTag; - UINT32 freeKBytes; - UINT32 totalKBytes; + size_t freeKBytes; + size_t totalKBytes; INT32 n; INT32 meminfo_fd = -1; long Cached; @@ -3049,7 +3048,7 @@ UINT32 I_GetFreeMem(UINT32 *total) } memTag += sizeof (MEMTOTAL); - totalKBytes = atoi(memTag); + totalKBytes = (size_t)atoi(memTag); if ((memTag = strstr(buf, MEMAVAILABLE)) == NULL) { diff --git a/src/z_zone.c b/src/z_zone.c index c012816ff..11c4bcb2c 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -106,14 +106,14 @@ static void Command_Memdump_f(void); */ void Z_Init(void) { - UINT32 total, memfree; + size_t total, memfree; memset(&head, 0x00, sizeof(head)); head.next = head.prev = &head; memfree = I_GetFreeMem(&total)>>20; - CONS_Printf("System memory: %uMB - Free: %uMB\n", total>>20, memfree); + CONS_Printf("System memory: %sMB - Free: %sMB\n", sizeu1(total>>20), sizeu2(memfree)); // Note: This allocates memory. Watch out. COM_AddCommand("memfree", Command_Memfree_f, COM_LUA); @@ -791,7 +791,7 @@ size_t Z_TagsUsage(INT32 lowtag, INT32 hightag) */ static void Command_Memfree_f(void) { - UINT32 freebytes, totalbytes; + size_t freebytes, totalbytes; Z_CheckHeap(-1); CONS_Printf("\x82%s", M_GetText("Memory Info\n")); @@ -824,8 +824,8 @@ static void Command_Memfree_f(void) CONS_Printf("\x82%s", M_GetText("System Memory Info\n")); freebytes = I_GetFreeMem(&totalbytes); - CONS_Printf(M_GetText(" Total physical memory: %7u KB\n"), totalbytes>>10); - CONS_Printf(M_GetText("Available physical memory: %7u KB\n"), freebytes>>10); + CONS_Printf(M_GetText(" Total physical memory: %s KB\n"), sizeu1(totalbytes>>10)); + CONS_Printf(M_GetText("Available physical memory: %s KB\n"), sizeu1(freebytes>>10)); } #ifdef ZDEBUG From 7dc74fc364b688a44279a7d29322798fb838fd99 Mon Sep 17 00:00:00 2001 From: Jaime Ita Passos Date: Fri, 19 May 2023 15:12:20 -0300 Subject: [PATCH 157/586] Fix declaration of I_GetFreeMem in src/dummy/i_system.c --- src/dummy/i_system.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dummy/i_system.c b/src/dummy/i_system.c index 00550c410..8556c0248 100644 --- a/src/dummy/i_system.c +++ b/src/dummy/i_system.c @@ -8,7 +8,7 @@ UINT8 graphics_started = 0; UINT8 keyboard_started = 0; -size_t I_GetFreeMem(UINT32 *total) +size_t I_GetFreeMem(size_t *total) { *total = 0; return 0; From eb1492fe6e501001a2271fa133bd76c0b0612715 Mon Sep 17 00:00:00 2001 From: spherallic Date: Tue, 23 May 2023 17:51:56 +0200 Subject: [PATCH 158/586] Zone Builder config updates --- extras/conf/SRB2-22.cfg | 299 ++++++++++++++++++++++------------------ 1 file changed, 163 insertions(+), 136 deletions(-) diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg index ae905b637..b5078cd0c 100644 --- a/extras/conf/SRB2-22.cfg +++ b/extras/conf/SRB2-22.cfg @@ -41,6 +41,9 @@ linetagindicatesectors = true; // The format interface handles the map data format - DoomMapSetIO for SRB2DB2, SRB2MapSetIO for Zone Builder formatinterface = "SRB2MapSetIO"; + +//Maximum safe map size check (0 means skip check) +safeboundary = 0; //Sky textures for vanilla maps defaultskytextures @@ -77,7 +80,7 @@ defaultskytextures defaultlumpname = "MAP01"; // Default testing parameters -testparameters = "-file \"%AP\" \"%F\" -warp %L"; +testparameters = "-folder \"%AF\" -file \"%AA\" \"%F\" -warp %L"; testshortpaths = true; // Default nodebuilder configurations @@ -437,6 +440,8 @@ sectortypes 144 = "Egg Capsule"; 160 = "Special Stage Time/Spheres Parameters "; 176 = "Custom Global Gravity "; + 512 = "Wind/Current "; + 1024 = "Conveyor Belt "; 1280 = "Speed Pad"; 1536 = "Flip Gravity on Jump"; 4096 = "Star Post Activator"; @@ -496,6 +501,8 @@ gen_sectortypes third { 0 = "Normal"; + 512 = "Wind/Current "; + 1024 = "Conveyor Belt "; 1280 = "Speed Pad"; 1536 = "Flip Gravity on Jump"; } @@ -578,7 +585,7 @@ linedeftypes title = "Per-Sector Gravity"; prefix = "(1)"; flags64text = "[6] Flip in reverse gravity"; - flags8192text = "[13] Reverse while inside"; + flags8192text = "[13] Cancel MF2_OBJECTFLIP"; } 5 @@ -641,35 +648,35 @@ linedeftypes 96 { - title = "Apply Tag to Tagged Sectors"; + title = "Add Front Sector Tag to Tagged Sectors"; prefix = "(96)"; flags1024text = "[10] Offsets are target tags"; - flags8192text = "[13] Use front side offsets"; - flags32768text = "[15] Use back side offsets"; + flags8192text = "[13] Add front side offsets"; + flags32768text = "[15] Add back side offsets"; } 97 { - title = "Apply Tag to Front Sector"; + title = "Add Tag to Front Sector"; prefix = "(97)"; - flags8192text = "[13] Use front side offsets"; - flags32768text = "[15] Use back side offsets"; + flags8192text = "[13] Add front side offsets"; + flags32768text = "[15] Add back side offsets"; } 98 { - title = "Apply Tag to Back Sector"; + title = "Add Tag to Back Sector"; prefix = "(98)"; - flags8192text = "[13] Use front side offsets"; - flags32768text = "[15] Use back side offsets"; + flags8192text = "[13] Add front side offsets"; + flags32768text = "[15] Add back side offsets"; } 99 { - title = "Apply Tag to Front and Back Sectors"; + title = "Add Tag to Front and Back Sectors"; prefix = "(99)"; - flags8192text = "[13] Use front side offsets"; - flags32768text = "[15] Use back side offsets"; + flags8192text = "[13] Add front side offsets"; + flags32768text = "[15] Add back side offsets"; } 540 @@ -990,6 +997,7 @@ linedeftypes flags128text = "[7] Only block non-players"; 3dfloor = true; 3dfloorflags = "47"; + invisiblefof = true; } 140 @@ -1227,6 +1235,7 @@ linedeftypes prefix = "(223)"; 3dfloor = true; 3dfloorflags = "41"; + invisiblefof = true; } } @@ -1524,6 +1533,7 @@ linedeftypes prefix = "(200)"; 3dfloor = true; 3dfloorflags = "20201"; + invisiblefof = true; } 201 @@ -1532,6 +1542,7 @@ linedeftypes prefix = "(201)"; 3dfloor = true; 3dfloorflags = "201"; + invisiblefof = true; } 202 @@ -1539,7 +1550,8 @@ linedeftypes title = "Fog Block"; prefix = "(202)"; 3dfloor = true; - 3dfloorflags = "3EF19"; + 3dfloorflags = "3EF01"; + invisiblefof = true; } 250 @@ -3624,7 +3636,7 @@ thingtypes 3328 = "3D Mode Start"; } - + starts { color = 1; // Blue @@ -3814,7 +3826,7 @@ thingtypes enemies { - color = 9; // Light_Blue + color = 9; // Light Blue arrow = 1; title = "Enemies"; @@ -4124,7 +4136,7 @@ thingtypes bosses { - color = 8; // Dark_Gray + color = 4; // Dark Red arrow = 1; title = "Bosses"; @@ -4223,6 +4235,7 @@ thingtypes sprite = "internal:capsule"; angletext = "Tag"; fixedrotation = 1; + tagthing = true; } 292 { @@ -4310,13 +4323,13 @@ thingtypes 308 { title = "CTF Team Ring (Red)"; - sprite = "internal:TRNGA0r"; + sprite = "internal:TRNGA0R"; width = 16; } 309 { title = "CTF Team Ring (Blue)"; - sprite = "internal:TRNGA0b"; + sprite = "internal:TRNGA0B"; width = 16; } 330 @@ -4353,7 +4366,7 @@ thingtypes collectibles { - color = 10; // Light_Green + color = 10; // Light Green title = "Other Collectibles"; width = 16; height = 32; @@ -4457,6 +4470,7 @@ thingtypes flags8text = "[8] Random (Weak)"; angletext = "Tag"; fixedrotation = 1; + tagthing = true; 400 { @@ -4589,6 +4603,7 @@ thingtypes flags1text = "[1] Run linedef executor on pop"; angletext = "Tag"; fixedrotation = 1; + tagthing = true; 431 { @@ -4659,7 +4674,7 @@ thingtypes generic { - color = 11; // Light_Cyan + color = 11; // Light Cyan title = "Generic Items & Hazards"; 500 @@ -4765,7 +4780,7 @@ thingtypes springs { - color = 12; // Light_Red + color = 12; // Light Red title = "Springs and Fans"; width = 20; height = 16; @@ -4927,13 +4942,13 @@ thingtypes { arrow = 0; title = "5 Vertical Rings (Yellow Spring)"; - sprite = "RINGA0"; + sprite = "internal:ringverticalyellow"; } 601 { arrow = 0; title = "5 Vertical Rings (Red Spring)"; - sprite = "RINGA0"; + sprite = "internal:ringverticalred"; height = 1024; } 602 @@ -4951,7 +4966,7 @@ thingtypes 604 { title = "Circle of Rings"; - sprite = "RINGA0"; + sprite = "internal:circlering"; width = 96; height = 192; unflippable = true; @@ -4960,7 +4975,7 @@ thingtypes 605 { title = "Circle of Rings (Big)"; - sprite = "RINGA0"; + sprite = "internal:circlebigring"; width = 192; unflippable = true; centerHitbox = true; @@ -4968,7 +4983,7 @@ thingtypes 606 { title = "Circle of Blue Spheres"; - sprite = "SPHRA0"; + sprite = "internal:circlesphere"; width = 96; height = 192; unflippable = true; @@ -4977,7 +4992,7 @@ thingtypes 607 { title = "Circle of Blue Spheres (Big)"; - sprite = "SPHRA0"; + sprite = "internal:circlebigsphere"; width = 192; unflippable = true; centerHitbox = true; @@ -4985,7 +5000,7 @@ thingtypes 608 { title = "Circle of Rings and Spheres"; - sprite = "SPHRA0"; + sprite = "internal:circleringsphere"; width = 96; height = 192; unflippable = true; @@ -4994,13 +5009,77 @@ thingtypes 609 { title = "Circle of Rings and Spheres (Big)"; - sprite = "SPHRA0"; + sprite = "internal:circlebigringsphere"; width = 192; unflippable = true; centerHitbox = true; } } + ambience + { + color = 8; // Dark Gray + title = "Ambience"; + width = 8; + height = 16; + sprite = "internal:ambiance"; + + 700 + { + title = "Water Ambience A (Large)"; + } + + 701 + { + title = "Water Ambience B (Large)"; + } + + 702 + { + title = "Water Ambience C (Medium)"; + } + + 703 + { + title = "Water Ambience D (Medium)"; + } + + 704 + { + title = "Water Ambience E (Small)"; + } + + 705 + { + title = "Water Ambience F (Small)"; + } + + 706 + { + title = "Water Ambience G (Extra Large)"; + } + + 707 + { + title = "Water Ambience H (Extra Large)"; + } + + 708 + { + title = "Disco Ambience"; + } + + 709 + { + title = "Volcano Ambience"; + } + + 710 + { + title = "Machine Ambience"; + } + } + invisible { color = 15; // White @@ -5009,72 +5088,6 @@ thingtypes height = 16; sprite = "UNKNA0"; - 700 - { - title = "Water Ambience A (Large)"; - sprite = "internal:ambiance"; - } - - 701 - { - title = "Water Ambience B (Large)"; - sprite = "internal:ambiance"; - } - - 702 - { - title = "Water Ambience C (Medium)"; - sprite = "internal:ambiance"; - } - - 703 - { - title = "Water Ambience D (Medium)"; - sprite = "internal:ambiance"; - } - - 704 - { - title = "Water Ambience E (Small)"; - sprite = "internal:ambiance"; - } - - 705 - { - title = "Water Ambience F (Small)"; - sprite = "internal:ambiance"; - } - - 706 - { - title = "Water Ambience G (Extra Large)"; - sprite = "internal:ambiance"; - } - - 707 - { - title = "Water Ambience H (Extra Large)"; - sprite = "internal:ambiance"; - } - - 708 - { - title = "Disco Ambience"; - sprite = "internal:ambiance"; - } - - 709 - { - title = "Volcano Ambience"; - sprite = "internal:ambiance"; - } - - 710 - { - title = "Machine Ambience"; - sprite = "internal:ambiance"; - } - 750 { title = "Slope Vertex"; @@ -5083,6 +5096,7 @@ thingtypes fixedrotation = 1; parametertext = "Absolute?"; flagsvaluetext = "Absolute Z"; + tagthing = true; } 751 @@ -5128,20 +5142,22 @@ thingtypes 756 { title = "Blast Linedef Executor"; - sprite = "TOADA0"; + sprite = "internal:blastexec"; width = 32; height = 16; angletext = "Tag"; fixedrotation = 1; + tagthing = true; } 757 { title = "Fan Particle Generator"; - sprite = "PRTLA0"; + sprite = "internal:fanparticles"; width = 8; height = 16; angletext = "Tag"; fixedrotation = 1; + tagthing = true; } 758 { @@ -5154,6 +5170,8 @@ thingtypes sprite = "internal:polyanchor"; angletext = "Tag"; fixedrotation = 1; + tagthing = true; + unflippable = true; } 761 @@ -5162,6 +5180,8 @@ thingtypes sprite = "internal:polycenter"; angletext = "Tag"; fixedrotation = 1; + tagthing = true; + unflippable = true; } 762 @@ -5170,6 +5190,8 @@ thingtypes sprite = "internal:polycentercrush"; angletext = "Tag"; fixedrotation = 1; + tagthing = true; + unflippable = true; } 780 { @@ -5183,7 +5205,7 @@ thingtypes greenflower { - color = 10; // Green + color = 2; // Green title = "Greenflower"; 800 @@ -5288,7 +5310,7 @@ thingtypes technohill { - color = 10; // Green + color = 2; // Green title = "Techno Hill"; 900 @@ -5332,7 +5354,7 @@ thingtypes deepsea { - color = 10; // Green + color = 2; // Green title = "Deep Sea"; 1000 @@ -5467,7 +5489,7 @@ thingtypes castleeggman { - color = 10; // Green + color = 2; // Green title = "Castle Eggman"; 1100 @@ -5516,6 +5538,7 @@ thingtypes angletext = "Tag"; parametertext = "Spokes"; fixedrotation = 1; + tagthing = true; } 1105 { @@ -5528,6 +5551,7 @@ thingtypes angletext = "Tag"; parametertext = "Spokes"; fixedrotation = 1; + tagthing = true; } 1106 { @@ -5540,23 +5564,25 @@ thingtypes angletext = "Tag"; parametertext = "Spokes"; fixedrotation = 1; + tagthing = true; } 1107 { title = "Chain Spawnpoint"; - sprite = "BMCHA0"; + sprite = "BMCHB0"; width = 17; height = 34; flags8text = "[8] Double size"; angletext = "Tag"; parametertext = "Spokes"; fixedrotation = 1; + tagthing = true; } 1108 { arrow = 1; title = "Hidden Chain Spawnpoint"; - sprite = "internal:chain3"; + sprite = "SMCHA0"; width = 17; height = 34; flags8text = "[8] Double size"; @@ -5572,6 +5598,7 @@ thingtypes angletext = "Tag"; parametertext = "Spokes"; fixedrotation = 1; + tagthing = true; } 1110 { @@ -5583,6 +5610,7 @@ thingtypes angletext = "Tag"; parametertext = "Spokes"; fixedrotation = 1; + tagthing = true; } 1111 { @@ -5736,7 +5764,7 @@ thingtypes aridcanyon { - color = 10; // Green + color = 2; // Green title = "Arid Canyon"; 1200 @@ -5764,6 +5792,7 @@ thingtypes height = 16; angletext = "Tag"; fixedrotation = 1; + tagthing = true; } 1203 { @@ -5955,7 +5984,7 @@ thingtypes redvolcano { - color = 10; // Green + color = 2; // Green title = "Red Volcano"; 1300 @@ -6055,7 +6084,7 @@ thingtypes botanicserenity { - color = 10; // Green + color = 2; // Green title = "Botanic Serenity"; width = 16; height = 32; @@ -6298,7 +6327,7 @@ thingtypes azuretemple { - color = 10; // Green + color = 2; // Green title = "Azure Temple"; 1500 @@ -6374,7 +6403,7 @@ thingtypes dreamhill { - color = 10; // Green + color = 2; // Green title = "Dream Hill"; 1600 @@ -6402,8 +6431,8 @@ thingtypes nightstrk { - color = 13; // Pink - title = "NiGHTS Track"; + color = 16; // Light Pink + title = "NiGHTS Track & Basics"; width = 8; height = 4096; sprite = "UNKNA0"; @@ -6438,6 +6467,19 @@ thingtypes flagsvaluetext = "Order"; parametertext = "Mare"; } + 1703 + { + title = "Ideya Drone"; + sprite = "NDRNA1"; + width = 16; + height = 56; + flags1text = "[1] Align player to middle"; + flags4text = "[4] Align player to top"; + flags8text = "[8] Die upon time up"; + angletext = "Time limit"; + fixedrotation = 1; + parametertext = "Height"; + } 1710 { title = "Ideya Capture"; @@ -6455,20 +6497,6 @@ thingtypes title = "NiGHTS Items"; width = 16; height = 32; - - 1703 - { - title = "Ideya Drone"; - sprite = "NDRNA1"; - width = 16; - height = 56; - flags1text = "[1] Align player to middle"; - flags4text = "[4] Align player to top"; - flags8text = "[8] Die upon time up"; - angletext = "Time limit"; - fixedrotation = 1; - parametertext = "Height"; - } 1704 { arrow = 1; @@ -6479,13 +6507,12 @@ thingtypes unflippable = true; flagsvaluetext = "Pitch"; angletext = "Yaw"; - fixedrotation = 1; } 1705 { arrow = 1; title = "Hoop (Generic)"; - sprite = "HOOPA0"; + sprite = "internal:nightshoop"; width = 80; height = 160; unflippable = true; @@ -6502,7 +6529,6 @@ thingtypes height = 24; flags8height = 24; flags8text = "[8] Float"; - unflippable = true; } 1707 { @@ -6547,7 +6573,7 @@ thingtypes flags2text = "[2] Radius +32"; flags4text = "[4] Radius +64"; flags8text = "[8] Radius +128"; - sprite = "HOOPA0"; + sprite = "internal:nightshoop"; width = 80; height = 160; unflippable = true; @@ -6657,7 +6683,7 @@ thingtypes christmasdisco { - color = 10; // Green + color = 2; // Green title = "Christmas & Disco"; 1850 @@ -6760,7 +6786,7 @@ thingtypes stalagmites { - color = 10; // Green + color = 2; // Green title = "Stalagmites"; width = 16; height = 40; @@ -6839,7 +6865,7 @@ thingtypes hauntedheights { - color = 10; // Green + color = 2; // Green title = "Haunted Heights"; 2000 @@ -6928,7 +6954,7 @@ thingtypes frozenhillside { - color = 10; // Green + color = 2; // Green title = "Frozen Hillside"; 2100 @@ -6979,7 +7005,7 @@ thingtypes tutorial { - color = 10; // Green + color = 2; // Green title = "Tutorial"; 799 @@ -6990,10 +7016,11 @@ thingtypes height = 144; parametertext = "Start frame"; } + } flickies { - color = 10; // Green + color = 3; // Teal title = "Flickies"; width = 8; height = 20; From b9c86a0f7f579253f622fc00ca8e5ac9b513f89d Mon Sep 17 00:00:00 2001 From: spherallic Date: Tue, 23 May 2023 17:51:56 +0200 Subject: [PATCH 159/586] Zone Builder config updates --- extras/conf/SRB2-22.cfg | 299 ++++++++++++++++++++++------------------ 1 file changed, 163 insertions(+), 136 deletions(-) diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg index ae905b637..b5078cd0c 100644 --- a/extras/conf/SRB2-22.cfg +++ b/extras/conf/SRB2-22.cfg @@ -41,6 +41,9 @@ linetagindicatesectors = true; // The format interface handles the map data format - DoomMapSetIO for SRB2DB2, SRB2MapSetIO for Zone Builder formatinterface = "SRB2MapSetIO"; + +//Maximum safe map size check (0 means skip check) +safeboundary = 0; //Sky textures for vanilla maps defaultskytextures @@ -77,7 +80,7 @@ defaultskytextures defaultlumpname = "MAP01"; // Default testing parameters -testparameters = "-file \"%AP\" \"%F\" -warp %L"; +testparameters = "-folder \"%AF\" -file \"%AA\" \"%F\" -warp %L"; testshortpaths = true; // Default nodebuilder configurations @@ -437,6 +440,8 @@ sectortypes 144 = "Egg Capsule"; 160 = "Special Stage Time/Spheres Parameters "; 176 = "Custom Global Gravity "; + 512 = "Wind/Current "; + 1024 = "Conveyor Belt "; 1280 = "Speed Pad"; 1536 = "Flip Gravity on Jump"; 4096 = "Star Post Activator"; @@ -496,6 +501,8 @@ gen_sectortypes third { 0 = "Normal"; + 512 = "Wind/Current "; + 1024 = "Conveyor Belt "; 1280 = "Speed Pad"; 1536 = "Flip Gravity on Jump"; } @@ -578,7 +585,7 @@ linedeftypes title = "Per-Sector Gravity"; prefix = "(1)"; flags64text = "[6] Flip in reverse gravity"; - flags8192text = "[13] Reverse while inside"; + flags8192text = "[13] Cancel MF2_OBJECTFLIP"; } 5 @@ -641,35 +648,35 @@ linedeftypes 96 { - title = "Apply Tag to Tagged Sectors"; + title = "Add Front Sector Tag to Tagged Sectors"; prefix = "(96)"; flags1024text = "[10] Offsets are target tags"; - flags8192text = "[13] Use front side offsets"; - flags32768text = "[15] Use back side offsets"; + flags8192text = "[13] Add front side offsets"; + flags32768text = "[15] Add back side offsets"; } 97 { - title = "Apply Tag to Front Sector"; + title = "Add Tag to Front Sector"; prefix = "(97)"; - flags8192text = "[13] Use front side offsets"; - flags32768text = "[15] Use back side offsets"; + flags8192text = "[13] Add front side offsets"; + flags32768text = "[15] Add back side offsets"; } 98 { - title = "Apply Tag to Back Sector"; + title = "Add Tag to Back Sector"; prefix = "(98)"; - flags8192text = "[13] Use front side offsets"; - flags32768text = "[15] Use back side offsets"; + flags8192text = "[13] Add front side offsets"; + flags32768text = "[15] Add back side offsets"; } 99 { - title = "Apply Tag to Front and Back Sectors"; + title = "Add Tag to Front and Back Sectors"; prefix = "(99)"; - flags8192text = "[13] Use front side offsets"; - flags32768text = "[15] Use back side offsets"; + flags8192text = "[13] Add front side offsets"; + flags32768text = "[15] Add back side offsets"; } 540 @@ -990,6 +997,7 @@ linedeftypes flags128text = "[7] Only block non-players"; 3dfloor = true; 3dfloorflags = "47"; + invisiblefof = true; } 140 @@ -1227,6 +1235,7 @@ linedeftypes prefix = "(223)"; 3dfloor = true; 3dfloorflags = "41"; + invisiblefof = true; } } @@ -1524,6 +1533,7 @@ linedeftypes prefix = "(200)"; 3dfloor = true; 3dfloorflags = "20201"; + invisiblefof = true; } 201 @@ -1532,6 +1542,7 @@ linedeftypes prefix = "(201)"; 3dfloor = true; 3dfloorflags = "201"; + invisiblefof = true; } 202 @@ -1539,7 +1550,8 @@ linedeftypes title = "Fog Block"; prefix = "(202)"; 3dfloor = true; - 3dfloorflags = "3EF19"; + 3dfloorflags = "3EF01"; + invisiblefof = true; } 250 @@ -3624,7 +3636,7 @@ thingtypes 3328 = "3D Mode Start"; } - + starts { color = 1; // Blue @@ -3814,7 +3826,7 @@ thingtypes enemies { - color = 9; // Light_Blue + color = 9; // Light Blue arrow = 1; title = "Enemies"; @@ -4124,7 +4136,7 @@ thingtypes bosses { - color = 8; // Dark_Gray + color = 4; // Dark Red arrow = 1; title = "Bosses"; @@ -4223,6 +4235,7 @@ thingtypes sprite = "internal:capsule"; angletext = "Tag"; fixedrotation = 1; + tagthing = true; } 292 { @@ -4310,13 +4323,13 @@ thingtypes 308 { title = "CTF Team Ring (Red)"; - sprite = "internal:TRNGA0r"; + sprite = "internal:TRNGA0R"; width = 16; } 309 { title = "CTF Team Ring (Blue)"; - sprite = "internal:TRNGA0b"; + sprite = "internal:TRNGA0B"; width = 16; } 330 @@ -4353,7 +4366,7 @@ thingtypes collectibles { - color = 10; // Light_Green + color = 10; // Light Green title = "Other Collectibles"; width = 16; height = 32; @@ -4457,6 +4470,7 @@ thingtypes flags8text = "[8] Random (Weak)"; angletext = "Tag"; fixedrotation = 1; + tagthing = true; 400 { @@ -4589,6 +4603,7 @@ thingtypes flags1text = "[1] Run linedef executor on pop"; angletext = "Tag"; fixedrotation = 1; + tagthing = true; 431 { @@ -4659,7 +4674,7 @@ thingtypes generic { - color = 11; // Light_Cyan + color = 11; // Light Cyan title = "Generic Items & Hazards"; 500 @@ -4765,7 +4780,7 @@ thingtypes springs { - color = 12; // Light_Red + color = 12; // Light Red title = "Springs and Fans"; width = 20; height = 16; @@ -4927,13 +4942,13 @@ thingtypes { arrow = 0; title = "5 Vertical Rings (Yellow Spring)"; - sprite = "RINGA0"; + sprite = "internal:ringverticalyellow"; } 601 { arrow = 0; title = "5 Vertical Rings (Red Spring)"; - sprite = "RINGA0"; + sprite = "internal:ringverticalred"; height = 1024; } 602 @@ -4951,7 +4966,7 @@ thingtypes 604 { title = "Circle of Rings"; - sprite = "RINGA0"; + sprite = "internal:circlering"; width = 96; height = 192; unflippable = true; @@ -4960,7 +4975,7 @@ thingtypes 605 { title = "Circle of Rings (Big)"; - sprite = "RINGA0"; + sprite = "internal:circlebigring"; width = 192; unflippable = true; centerHitbox = true; @@ -4968,7 +4983,7 @@ thingtypes 606 { title = "Circle of Blue Spheres"; - sprite = "SPHRA0"; + sprite = "internal:circlesphere"; width = 96; height = 192; unflippable = true; @@ -4977,7 +4992,7 @@ thingtypes 607 { title = "Circle of Blue Spheres (Big)"; - sprite = "SPHRA0"; + sprite = "internal:circlebigsphere"; width = 192; unflippable = true; centerHitbox = true; @@ -4985,7 +5000,7 @@ thingtypes 608 { title = "Circle of Rings and Spheres"; - sprite = "SPHRA0"; + sprite = "internal:circleringsphere"; width = 96; height = 192; unflippable = true; @@ -4994,13 +5009,77 @@ thingtypes 609 { title = "Circle of Rings and Spheres (Big)"; - sprite = "SPHRA0"; + sprite = "internal:circlebigringsphere"; width = 192; unflippable = true; centerHitbox = true; } } + ambience + { + color = 8; // Dark Gray + title = "Ambience"; + width = 8; + height = 16; + sprite = "internal:ambiance"; + + 700 + { + title = "Water Ambience A (Large)"; + } + + 701 + { + title = "Water Ambience B (Large)"; + } + + 702 + { + title = "Water Ambience C (Medium)"; + } + + 703 + { + title = "Water Ambience D (Medium)"; + } + + 704 + { + title = "Water Ambience E (Small)"; + } + + 705 + { + title = "Water Ambience F (Small)"; + } + + 706 + { + title = "Water Ambience G (Extra Large)"; + } + + 707 + { + title = "Water Ambience H (Extra Large)"; + } + + 708 + { + title = "Disco Ambience"; + } + + 709 + { + title = "Volcano Ambience"; + } + + 710 + { + title = "Machine Ambience"; + } + } + invisible { color = 15; // White @@ -5009,72 +5088,6 @@ thingtypes height = 16; sprite = "UNKNA0"; - 700 - { - title = "Water Ambience A (Large)"; - sprite = "internal:ambiance"; - } - - 701 - { - title = "Water Ambience B (Large)"; - sprite = "internal:ambiance"; - } - - 702 - { - title = "Water Ambience C (Medium)"; - sprite = "internal:ambiance"; - } - - 703 - { - title = "Water Ambience D (Medium)"; - sprite = "internal:ambiance"; - } - - 704 - { - title = "Water Ambience E (Small)"; - sprite = "internal:ambiance"; - } - - 705 - { - title = "Water Ambience F (Small)"; - sprite = "internal:ambiance"; - } - - 706 - { - title = "Water Ambience G (Extra Large)"; - sprite = "internal:ambiance"; - } - - 707 - { - title = "Water Ambience H (Extra Large)"; - sprite = "internal:ambiance"; - } - - 708 - { - title = "Disco Ambience"; - sprite = "internal:ambiance"; - } - - 709 - { - title = "Volcano Ambience"; - sprite = "internal:ambiance"; - } - - 710 - { - title = "Machine Ambience"; - sprite = "internal:ambiance"; - } - 750 { title = "Slope Vertex"; @@ -5083,6 +5096,7 @@ thingtypes fixedrotation = 1; parametertext = "Absolute?"; flagsvaluetext = "Absolute Z"; + tagthing = true; } 751 @@ -5128,20 +5142,22 @@ thingtypes 756 { title = "Blast Linedef Executor"; - sprite = "TOADA0"; + sprite = "internal:blastexec"; width = 32; height = 16; angletext = "Tag"; fixedrotation = 1; + tagthing = true; } 757 { title = "Fan Particle Generator"; - sprite = "PRTLA0"; + sprite = "internal:fanparticles"; width = 8; height = 16; angletext = "Tag"; fixedrotation = 1; + tagthing = true; } 758 { @@ -5154,6 +5170,8 @@ thingtypes sprite = "internal:polyanchor"; angletext = "Tag"; fixedrotation = 1; + tagthing = true; + unflippable = true; } 761 @@ -5162,6 +5180,8 @@ thingtypes sprite = "internal:polycenter"; angletext = "Tag"; fixedrotation = 1; + tagthing = true; + unflippable = true; } 762 @@ -5170,6 +5190,8 @@ thingtypes sprite = "internal:polycentercrush"; angletext = "Tag"; fixedrotation = 1; + tagthing = true; + unflippable = true; } 780 { @@ -5183,7 +5205,7 @@ thingtypes greenflower { - color = 10; // Green + color = 2; // Green title = "Greenflower"; 800 @@ -5288,7 +5310,7 @@ thingtypes technohill { - color = 10; // Green + color = 2; // Green title = "Techno Hill"; 900 @@ -5332,7 +5354,7 @@ thingtypes deepsea { - color = 10; // Green + color = 2; // Green title = "Deep Sea"; 1000 @@ -5467,7 +5489,7 @@ thingtypes castleeggman { - color = 10; // Green + color = 2; // Green title = "Castle Eggman"; 1100 @@ -5516,6 +5538,7 @@ thingtypes angletext = "Tag"; parametertext = "Spokes"; fixedrotation = 1; + tagthing = true; } 1105 { @@ -5528,6 +5551,7 @@ thingtypes angletext = "Tag"; parametertext = "Spokes"; fixedrotation = 1; + tagthing = true; } 1106 { @@ -5540,23 +5564,25 @@ thingtypes angletext = "Tag"; parametertext = "Spokes"; fixedrotation = 1; + tagthing = true; } 1107 { title = "Chain Spawnpoint"; - sprite = "BMCHA0"; + sprite = "BMCHB0"; width = 17; height = 34; flags8text = "[8] Double size"; angletext = "Tag"; parametertext = "Spokes"; fixedrotation = 1; + tagthing = true; } 1108 { arrow = 1; title = "Hidden Chain Spawnpoint"; - sprite = "internal:chain3"; + sprite = "SMCHA0"; width = 17; height = 34; flags8text = "[8] Double size"; @@ -5572,6 +5598,7 @@ thingtypes angletext = "Tag"; parametertext = "Spokes"; fixedrotation = 1; + tagthing = true; } 1110 { @@ -5583,6 +5610,7 @@ thingtypes angletext = "Tag"; parametertext = "Spokes"; fixedrotation = 1; + tagthing = true; } 1111 { @@ -5736,7 +5764,7 @@ thingtypes aridcanyon { - color = 10; // Green + color = 2; // Green title = "Arid Canyon"; 1200 @@ -5764,6 +5792,7 @@ thingtypes height = 16; angletext = "Tag"; fixedrotation = 1; + tagthing = true; } 1203 { @@ -5955,7 +5984,7 @@ thingtypes redvolcano { - color = 10; // Green + color = 2; // Green title = "Red Volcano"; 1300 @@ -6055,7 +6084,7 @@ thingtypes botanicserenity { - color = 10; // Green + color = 2; // Green title = "Botanic Serenity"; width = 16; height = 32; @@ -6298,7 +6327,7 @@ thingtypes azuretemple { - color = 10; // Green + color = 2; // Green title = "Azure Temple"; 1500 @@ -6374,7 +6403,7 @@ thingtypes dreamhill { - color = 10; // Green + color = 2; // Green title = "Dream Hill"; 1600 @@ -6402,8 +6431,8 @@ thingtypes nightstrk { - color = 13; // Pink - title = "NiGHTS Track"; + color = 16; // Light Pink + title = "NiGHTS Track & Basics"; width = 8; height = 4096; sprite = "UNKNA0"; @@ -6438,6 +6467,19 @@ thingtypes flagsvaluetext = "Order"; parametertext = "Mare"; } + 1703 + { + title = "Ideya Drone"; + sprite = "NDRNA1"; + width = 16; + height = 56; + flags1text = "[1] Align player to middle"; + flags4text = "[4] Align player to top"; + flags8text = "[8] Die upon time up"; + angletext = "Time limit"; + fixedrotation = 1; + parametertext = "Height"; + } 1710 { title = "Ideya Capture"; @@ -6455,20 +6497,6 @@ thingtypes title = "NiGHTS Items"; width = 16; height = 32; - - 1703 - { - title = "Ideya Drone"; - sprite = "NDRNA1"; - width = 16; - height = 56; - flags1text = "[1] Align player to middle"; - flags4text = "[4] Align player to top"; - flags8text = "[8] Die upon time up"; - angletext = "Time limit"; - fixedrotation = 1; - parametertext = "Height"; - } 1704 { arrow = 1; @@ -6479,13 +6507,12 @@ thingtypes unflippable = true; flagsvaluetext = "Pitch"; angletext = "Yaw"; - fixedrotation = 1; } 1705 { arrow = 1; title = "Hoop (Generic)"; - sprite = "HOOPA0"; + sprite = "internal:nightshoop"; width = 80; height = 160; unflippable = true; @@ -6502,7 +6529,6 @@ thingtypes height = 24; flags8height = 24; flags8text = "[8] Float"; - unflippable = true; } 1707 { @@ -6547,7 +6573,7 @@ thingtypes flags2text = "[2] Radius +32"; flags4text = "[4] Radius +64"; flags8text = "[8] Radius +128"; - sprite = "HOOPA0"; + sprite = "internal:nightshoop"; width = 80; height = 160; unflippable = true; @@ -6657,7 +6683,7 @@ thingtypes christmasdisco { - color = 10; // Green + color = 2; // Green title = "Christmas & Disco"; 1850 @@ -6760,7 +6786,7 @@ thingtypes stalagmites { - color = 10; // Green + color = 2; // Green title = "Stalagmites"; width = 16; height = 40; @@ -6839,7 +6865,7 @@ thingtypes hauntedheights { - color = 10; // Green + color = 2; // Green title = "Haunted Heights"; 2000 @@ -6928,7 +6954,7 @@ thingtypes frozenhillside { - color = 10; // Green + color = 2; // Green title = "Frozen Hillside"; 2100 @@ -6979,7 +7005,7 @@ thingtypes tutorial { - color = 10; // Green + color = 2; // Green title = "Tutorial"; 799 @@ -6990,10 +7016,11 @@ thingtypes height = 144; parametertext = "Start frame"; } + } flickies { - color = 10; // Green + color = 3; // Teal title = "Flickies"; width = 8; height = 20; From b2313aa4bda91da0bf4575c67bb5eeac4647f0c7 Mon Sep 17 00:00:00 2001 From: Zwip-Zwap Zapony Date: Mon, 22 May 2023 17:55:04 +0200 Subject: [PATCH 160/586] Rewrite F_SkyScroll to fix overflows --- src/d_clisrv.c | 2 +- src/f_finale.c | 73 +++++++++++++++++++++----------------------------- src/f_finale.h | 4 +-- src/g_game.c | 6 +++-- src/m_menu.c | 6 ++--- 5 files changed, 40 insertions(+), 51 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 94384e46a..839f70f7e 100755 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2486,7 +2486,7 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic { if (!snake) { - F_MenuPresTicker(true); // title sky + F_MenuPresTicker(); // title sky F_TitleScreenTicker(true); F_TitleScreenDrawer(); } diff --git a/src/f_finale.c b/src/f_finale.c index 6560c24f1..47d4627ec 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -63,7 +63,6 @@ static tic_t stoptimer; static boolean keypressed = false; // (no longer) De-Demo'd Title Screen -static INT32 menuanimtimer; // Title screen: background animation timing mobj_t *titlemapcameraref = NULL; // menu presentation state @@ -75,6 +74,8 @@ INT32 curbgyspeed; boolean curbghide; boolean hidetitlemap; // WARNING: set to false by M_SetupNextMenu and M_ClearMenus +static fixed_t curbgx = 0; +static fixed_t curbgy = 0; static UINT8 curDemo = 0; static UINT32 demoDelayLeft; static UINT32 demoIdleLeft; @@ -2258,7 +2259,8 @@ void F_GameEndTicker(void) void F_InitMenuPresValues(void) { - menuanimtimer = 0; + curbgx = 0; + curbgy = 0; prevMenuId = 0; activeMenuId = MainDef.menuid; @@ -2291,17 +2293,11 @@ void F_InitMenuPresValues(void) // // F_SkyScroll // -void F_SkyScroll(INT32 scrollxspeed, INT32 scrollyspeed, const char *patchname) +void F_SkyScroll(const char *patchname) { - INT32 xscrolled, x, xneg = (scrollxspeed > 0) - (scrollxspeed < 0), tilex; - INT32 yscrolled, y, yneg = (scrollyspeed > 0) - (scrollyspeed < 0), tiley; - boolean xispos = (scrollxspeed >= 0), yispos = (scrollyspeed >= 0); + INT32 x, basey = 0; INT32 dupz = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy); - INT16 patwidth, patheight; - INT32 pw, ph; // scaled by dupz patch_t *pat; - INT32 i, j; - fixed_t fracmenuanimtimer, xscrolltimer, yscrolltimer; if (rendermode == render_none) return; @@ -2312,43 +2308,34 @@ void F_SkyScroll(INT32 scrollxspeed, INT32 scrollyspeed, const char *patchname) return; } - if (!scrollxspeed && !scrollyspeed) + pat = W_CachePatchName(patchname, PU_PATCH_LOWPRIORITY); + + if (!curbgxspeed && !curbgyspeed) { - V_DrawPatchFill(W_CachePatchName(patchname, PU_PATCH_LOWPRIORITY)); + V_DrawPatchFill(pat); + W_UnlockCachedPatch(pat); return; } - pat = W_CachePatchName(patchname, PU_PATCH_LOWPRIORITY); + // Modulo the background scrolling to prevent jumps from integer overflows + // We already load the background patch here, so we can modulo it here + // to avoid also having to load the patch in F_MenuPresTicker + curbgx %= pat->width * 16; + curbgy %= pat->height * 16; - patwidth = pat->width; - patheight = pat->height; - pw = patwidth * dupz; - ph = patheight * dupz; + // Ooh, fancy frame interpolation + x = ((curbgx*dupz) + FixedInt((rendertimefrac-FRACUNIT) * curbgxspeed*dupz)) / 16; + basey = ((curbgy*dupz) + FixedInt((rendertimefrac-FRACUNIT) * curbgyspeed*dupz)) / 16; - tilex = max(FixedCeil(FixedDiv(vid.width, pw)) >> FRACBITS, 1)+2; // one tile on both sides of center - tiley = max(FixedCeil(FixedDiv(vid.height, ph)) >> FRACBITS, 1)+2; + if (x > 0) // Make sure that we don't leave the left or top sides empty + x -= pat->width * dupz; + if (basey > 0) + basey -= pat->height * dupz; - fracmenuanimtimer = (menuanimtimer * FRACUNIT) - (FRACUNIT - rendertimefrac); - xscrolltimer = ((fracmenuanimtimer*scrollxspeed)/16 + patwidth*xneg*FRACUNIT) % (patwidth * FRACUNIT); - yscrolltimer = ((fracmenuanimtimer*scrollyspeed)/16 + patheight*yneg*FRACUNIT) % (patheight * FRACUNIT); - - // coordinate offsets - xscrolled = FixedInt(xscrolltimer * dupz); - yscrolled = FixedInt(yscrolltimer * dupz); - - for (x = (xispos) ? -pw*(tilex-1)+pw : 0, i = 0; - i < tilex; - x += pw, i++) + for (; x < vid.width; x += pat->width * dupz) { - for (y = (yispos) ? -ph*(tiley-1)+ph : 0, j = 0; - j < tiley; - y += ph, j++) - { - V_DrawScaledPatch( - (xispos) ? xscrolled - x : x + xscrolled, - (yispos) ? yscrolled - y : y + yscrolled, - V_NOSCALESTART, pat); - } + for (INT32 y = basey; y < vid.height; y += pat->height * dupz) + V_DrawScaledPatch(x, y, V_NOSCALESTART, pat); } W_UnlockCachedPatch(pat); @@ -2671,7 +2658,7 @@ void F_TitleScreenDrawer(void) if (curbgcolor >= 0) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, curbgcolor); else if (!curbghide || !titlemapinaction || gamestate == GS_WAITINGPLAYERS) - F_SkyScroll(curbgxspeed, curbgyspeed, curbgname); + F_SkyScroll(curbgname); // Don't draw outside of the title screen, or if the patch isn't there. if (gamestate != GS_TITLESCREEN && gamestate != GS_WAITINGPLAYERS) @@ -3426,10 +3413,10 @@ luahook: // separate animation timer for backgrounds, since we also count // during GS_TIMEATTACK -void F_MenuPresTicker(boolean run) +void F_MenuPresTicker(void) { - if (run) - menuanimtimer++; + curbgx += curbgxspeed; + curbgy += curbgyspeed; } // (no longer) De-Demo'd Title Screen diff --git a/src/f_finale.h b/src/f_finale.h index 6ea1b5537..7f53bfbad 100644 --- a/src/f_finale.h +++ b/src/f_finale.h @@ -40,7 +40,7 @@ void F_TextPromptTicker(void); void F_GameEndDrawer(void); void F_IntroDrawer(void); void F_TitleScreenDrawer(void); -void F_SkyScroll(INT32 scrollxspeed, INT32 scrollyspeed, const char *patchname); +void F_SkyScroll(const char *patchname); void F_GameEvaluationDrawer(void); void F_StartGameEvaluation(void); @@ -131,7 +131,7 @@ extern UINT16 curtttics; #define TITLEBACKGROUNDACTIVE (curfadevalue >= 0 || curbgname[0]) void F_InitMenuPresValues(void); -void F_MenuPresTicker(boolean run); +void F_MenuPresTicker(void); // // WIPE diff --git a/src/g_game.c b/src/g_game.c index 0d5181b07..2935daa55 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2390,7 +2390,8 @@ void G_Ticker(boolean run) break; case GS_TIMEATTACK: - F_MenuPresTicker(run); + if (run) + F_MenuPresTicker(); break; case GS_INTRO: @@ -2438,7 +2439,8 @@ void G_Ticker(boolean run) // then intentionally fall through /* FALLTHRU */ case GS_WAITINGPLAYERS: - F_MenuPresTicker(run); + if (run) + F_MenuPresTicker(); F_TitleScreenTicker(run); break; diff --git a/src/m_menu.c b/src/m_menu.c index e879e9c14..7efe81f43 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -5964,7 +5964,7 @@ static void M_DrawLevelPlatterMenu(void) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, curbgcolor); else if (!curbghide || !titlemapinaction) { - F_SkyScroll(curbgxspeed, curbgyspeed, curbgname); + F_SkyScroll(curbgname); // Draw and animate foreground if (!strncmp("RECATKBG", curbgname, 8)) M_DrawRecordAttackForeground(); @@ -6226,7 +6226,7 @@ static void M_DrawMessageMenu(void) } else { - F_SkyScroll(curbgxspeed, curbgyspeed, curbgname); + F_SkyScroll(curbgname); if (!strncmp("RECATKBG", curbgname, 8)) M_DrawRecordAttackForeground(); } @@ -9873,7 +9873,7 @@ void M_DrawTimeAttackMenu(void) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, curbgcolor); else if (!curbghide || !titlemapinaction) { - F_SkyScroll(curbgxspeed, curbgyspeed, curbgname); + F_SkyScroll(curbgname); // Draw and animate foreground if (!strncmp("RECATKBG", curbgname, 8)) M_DrawRecordAttackForeground(); From 3f5e7ff0d06b2a0aa7fdb1c42e9ebdc34b13129c Mon Sep 17 00:00:00 2001 From: Zwip-Zwap Zapony Date: Mon, 22 May 2023 20:53:17 +0200 Subject: [PATCH 161/586] Interpolate shadows when scaling mobjs --- src/hardware/hw_main.c | 2 ++ src/r_things.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 343fa43bf..6e7214571 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -3606,6 +3606,8 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale) scalemul = FixedMul(FRACUNIT - floordiff/640, scale); scalemul = FixedMul(scalemul, (thing->radius*2) / gpatch->height); + if ((thing->scale != thing->old_scale) && (thing->scale >= FRACUNIT/1024)) // Interpolate shadows when scaling mobjs + scalemul = FixedMul(scalemul, FixedDiv(interp.scale, thing->scale)); fscale = FIXED_TO_FLOAT(scalemul); fx = FIXED_TO_FLOAT(interp.x); diff --git a/src/r_things.c b/src/r_things.c index 2916482fb..62d97ff33 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1324,6 +1324,8 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, if (trans >= 9) return; scalemul = FixedMul(FRACUNIT - floordiff/640, scale); + if ((thing->scale != thing->old_scale) && (thing->scale >= FRACUNIT/1024)) // Interpolate shadows when scaling mobjs + scalemul = FixedMul(scalemul, FixedDiv(interp.scale, thing->scale)); patch = W_CachePatchName("DSHADOW", PU_SPRITE); xscale = FixedDiv(projection, tz); From 05f1a9a2c8a0da9ed4ab00a0abac3d439b3ec08c Mon Sep 17 00:00:00 2001 From: Zwip-Zwap Zapony Date: Mon, 29 May 2023 14:38:22 +0200 Subject: [PATCH 162/586] Suppress libdivide warnings in GCC/Clang --- src/libdivide.h | 9 +++++++++ src/r_draw8_npo2.c | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/src/libdivide.h b/src/libdivide.h index 1a589c7e5..71a5ae6be 100644 --- a/src/libdivide.h +++ b/src/libdivide.h @@ -581,6 +581,11 @@ static inline void libdivide_u128_shift(uint64_t *u1, uint64_t *u0, int32_t sign ////////// UINT32 +#if defined(__GNUC__) || defined(__clang__) // Suppress intentional compiler warnings + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Waggregate-return" +#endif + 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; @@ -647,6 +652,10 @@ struct libdivide_u32_t libdivide_u32_gen(uint32_t d) { return ret; }*/ +#if defined(__GNUC__) || defined(__clang__) // Stop suppressing intentional compiler warnings + #pragma GCC diagnostic pop +#endif + uint32_t libdivide_u32_do(uint32_t numer, const struct libdivide_u32_t *denom) { uint8_t more = denom->more; if (!denom->magic) { diff --git a/src/r_draw8_npo2.c b/src/r_draw8_npo2.c index faf1cdba8..91f3b06c4 100644 --- a/src/r_draw8_npo2.c +++ b/src/r_draw8_npo2.c @@ -18,6 +18,11 @@ #define SPANSIZE 16 #define INVSPAN 0.0625f +#if defined(__GNUC__) || defined(__clang__) // Suppress intentional libdivide compiler warnings - Also added to libdivide.h + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Waggregate-return" +#endif + /** \brief The R_DrawSpan_NPO2_8 function Draws the actual span. */ @@ -1572,3 +1577,7 @@ void R_DrawTiltedWaterSpan_NPO2_8(void) } #endif } + +#if defined(__GNUC__) || defined(__clang__) // Stop suppressing intentional libdivide compiler warnings + #pragma GCC diagnostic pop +#endif From 58b3b8e0750effcc1da5149305c8781003289366 Mon Sep 17 00:00:00 2001 From: SMS Alfredo <65426124+SMS-Alfredo@users.noreply.github.com> Date: Wed, 31 May 2023 22:33:16 -0500 Subject: [PATCH 163/586] Fix Flung Spheres not using the Blue Sphere collection effect --- 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 873448dcd..86fc2a6ae 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -563,7 +563,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) special->momx = special->momy = special->momz = 0; P_GivePlayerSpheres(player, 1); - if (special->type == MT_BLUESPHERE) + if (special->type == MT_BLUESPHERE || special->type == MT_FLINGBLUESPHERE) { special->destscale = ((player->powers[pw_carry] == CR_NIGHTSMODE) ? 4 : 2)*special->scale; if (states[special->info->deathstate].tics > 0) From 49fa46d80efd95047f05834bde41dbbd7311d418 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 27 Feb 2022 16:52:05 -0500 Subject: [PATCH 164/586] Online emblems Currently, emblems share with everyone. Will add an option to toggle this. --- src/d_clisrv.c | 3 + src/d_main.c | 9 +- src/d_netcmd.c | 14 +-- src/deh_soc.c | 2 +- src/dehacked.c | 2 +- src/doomstat.h | 54 ---------- src/f_finale.c | 43 ++++---- src/g_game.c | 251 ++++++++++++++++++++++----------------------- src/g_game.h | 25 ++--- src/hu_stuff.c | 2 +- src/m_cheat.c | 4 +- src/m_cond.c | 248 +++++++++++++++++++++++++++++--------------- src/m_cond.h | 123 ++++++++++++++++++---- src/m_menu.c | 155 +++++++++++++++------------- src/m_random.c | 5 +- src/p_inter.c | 18 +++- src/p_mobj.c | 19 ++-- src/p_saveg.c | 225 ++++++++++++++++++++++++++++++++++++++++ src/p_setup.c | 11 +- src/p_spec.c | 7 +- src/p_tick.c | 5 +- src/r_skins.c | 13 +-- src/s_sound.c | 5 +- src/sdl/i_system.c | 6 +- src/st_stuff.c | 9 +- src/y_inter.c | 16 +-- 26 files changed, 824 insertions(+), 450 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 64e5aff6b..18f0179f8 100755 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -3645,6 +3645,9 @@ void SV_ResetServer(void) CV_RevertNetVars(); + // Ensure synched when creating a new server + M_CopyGameData(serverGamedata, clientGamedata); + DEBFILE("\n-=-=-=-=-=-=-= Server Reset =-=-=-=-=-=-=-\n\n"); } diff --git a/src/d_main.c b/src/d_main.c index 6506c9d4e..5861f9886 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1350,6 +1350,9 @@ void D_SRB2Main(void) CONS_Printf("Z_Init(): Init zone memory allocation daemon. \n"); Z_Init(); + clientGamedata = M_NewGameDataStruct(); + serverGamedata = M_NewGameDataStruct(); + // Do this up here so that WADs loaded through the command line can use ExecCfg COM_Init(); @@ -1479,7 +1482,9 @@ void D_SRB2Main(void) // confusion issues when loading mods. strlcpy(gamedatafilename, M_GetNextParm(), sizeof gamedatafilename); } - G_LoadGameData(); + + G_LoadGameData(clientGamedata); + M_CopyGameData(serverGamedata, clientGamedata); #if defined (__unix__) || defined (UNIXCOMMON) || defined (HAVE_SDL) VID_PrepareModeList(); // Regenerate Modelist according to cv_fullscreen @@ -1710,7 +1715,7 @@ void D_SRB2Main(void) // ... unless you're in a dedicated server. Yes, technically this means you can view any level by // running a dedicated server and joining it yourself, but that's better than making dedicated server's // lives hell. - else if (!dedicated && M_MapLocked(pstartmap)) + else if (!dedicated && M_MapLocked(pstartmap, serverGamedata)) I_Error("You need to unlock this level before you can warp to it!\n"); else { diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 80a084e16..af44e53d6 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -2036,7 +2036,7 @@ static void Command_Map_f(void) // ... unless you're in a dedicated server. Yes, technically this means you can view any level by // running a dedicated server and joining it yourself, but that's better than making dedicated server's // lives hell. - if (!dedicated && M_MapLocked(newmapnum)) + if (!dedicated && M_MapLocked(newmapnum, serverGamedata)) { CONS_Alert(CONS_NOTICE, M_GetText("You need to unlock this level before you can warp to it!\n")); Z_Free(realmapname); @@ -3945,18 +3945,12 @@ void ItemFinder_OnChange(void) if (!cv_itemfinder.value) return; // it's fine. - if (!M_SecretUnlocked(SECRET_ITEMFINDER)) + if (!M_SecretUnlocked(SECRET_ITEMFINDER, clientGamedata)) { CONS_Printf(M_GetText("You haven't earned this yet.\n")); CV_StealthSetValue(&cv_itemfinder, 0); return; } - else if (netgame || multiplayer) - { - CONS_Printf(M_GetText("This only works in single player.\n")); - CV_StealthSetValue(&cv_itemfinder, 0); - return; - } } /** Deals with a pointlimit change by printing the change to the console. @@ -4305,7 +4299,7 @@ void D_GameTypeChanged(INT32 lastgametype) static void Ringslinger_OnChange(void) { - if (!M_SecretUnlocked(SECRET_PANDORA) && !netgame && cv_ringslinger.value && !cv_debug) + if (!M_SecretUnlocked(SECRET_PANDORA, serverGamedata) && !netgame && cv_ringslinger.value && !cv_debug) { CONS_Printf(M_GetText("You haven't earned this yet.\n")); CV_StealthSetValue(&cv_ringslinger, 0); @@ -4318,7 +4312,7 @@ static void Ringslinger_OnChange(void) static void Gravity_OnChange(void) { - if (!M_SecretUnlocked(SECRET_PANDORA) && !netgame && !cv_debug + if (!M_SecretUnlocked(SECRET_PANDORA, serverGamedata) && !netgame && !cv_debug && strcmp(cv_gravity.string, cv_gravity.defaultvalue)) { CONS_Printf(M_GetText("You haven't earned this yet.\n")); diff --git a/src/deh_soc.c b/src/deh_soc.c index 3a3942c14..81adbc9d2 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -3849,7 +3849,7 @@ void readmaincfg(MYFILE *f) if (!GoodDataFileName(word2)) I_Error("Maincfg: bad data file name '%s'\n", word2); - G_SaveGameData(); + G_SaveGameData(clientGamedata); strlcpy(gamedatafilename, word2, sizeof (gamedatafilename)); strlwr(gamedatafilename); savemoddata = true; diff --git a/src/dehacked.c b/src/dehacked.c index 17768eb7f..fd2a70171 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -575,7 +575,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) } // end while if (gamedataadded) - G_LoadGameData(); + G_LoadGameData(clientGamedata); if (gamestate == GS_TITLESCREEN) { diff --git a/src/doomstat.h b/src/doomstat.h index 847c10b8c..5875bd01f 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -132,8 +132,6 @@ extern INT32 postimgparam2; extern INT32 viewwindowx, viewwindowy; extern INT32 viewwidth, scaledviewwidth; -extern boolean gamedataloaded; - // Player taking events, and displaying. extern INT32 consoleplayer; extern INT32 displayplayer; @@ -495,8 +493,6 @@ typedef struct extern tolinfo_t TYPEOFLEVEL[NUMTOLNAMES]; extern UINT32 lastcustomtol; -extern tic_t totalplaytime; - extern boolean stagefailed; // Emeralds stored as bits to throw savegame hackers off. @@ -515,52 +511,6 @@ extern INT32 luabanks[NUM_LUABANKS]; extern INT32 nummaprings; //keep track of spawned rings/coins -/** Time attack information, currently a very small structure. - */ -typedef struct -{ - tic_t time; ///< Time in which the level was finished. - UINT32 score; ///< Score when the level was finished. - UINT16 rings; ///< Rings when the level was finished. -} recorddata_t; - -/** Setup for one NiGHTS map. - * These are dynamically allocated because I am insane - */ -#define GRADE_F 0 -#define GRADE_E 1 -#define GRADE_D 2 -#define GRADE_C 3 -#define GRADE_B 4 -#define GRADE_A 5 -#define GRADE_S 6 - -typedef struct -{ - // 8 mares, 1 overall (0) - UINT8 nummares; - UINT32 score[9]; - UINT8 grade[9]; - tic_t time[9]; -} nightsdata_t; - -extern nightsdata_t *nightsrecords[NUMMAPS]; -extern recorddata_t *mainrecords[NUMMAPS]; - -// mapvisited is now a set of flags that says what we've done in the map. -#define MV_VISITED 1 -#define MV_BEATEN 2 -#define MV_ALLEMERALDS 4 -#define MV_ULTIMATE 8 -#define MV_PERFECT 16 -#define MV_PERFECTRA 32 -#define MV_MAX 63 // used in gamedata check, update whenever MV's are added -#define MV_MP 128 -extern UINT8 mapvisited[NUMMAPS]; - -// Temporary holding place for nights data for the current map -extern nightsdata_t ntemprecords; - extern UINT32 token; ///< Number of tokens collected in a level extern UINT32 tokenlist; ///< List of tokens collected extern boolean gottoken; ///< Did you get a token? Used for end of act @@ -616,10 +566,6 @@ extern INT32 cheats; extern tic_t hidetime; -extern UINT32 timesBeaten; // # of times the game has been beaten. -extern UINT32 timesBeatenWithEmeralds; -extern UINT32 timesBeatenUltimate; - // =========================== // Internal parameters, fixed. // =========================== diff --git a/src/f_finale.c b/src/f_finale.c index 68b2641a1..4bb640d50 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1411,7 +1411,7 @@ boolean F_CreditResponder(event_t *event) break; } - if (!(timesBeaten) && !(netgame || multiplayer) && !cv_debug) + if (!(serverGamedata->timesBeaten) && !(netgame || multiplayer) && !cv_debug) return false; if (event->type != ev_keydown) @@ -1573,23 +1573,17 @@ void F_GameEvaluationDrawer(void) #if 0 // the following looks like hot garbage the more unlockables we add, and we now have a lot of unlockables if (finalecount >= 5*TICRATE) { + INT32 startcoord = 32; V_DrawString(8, 16, V_YELLOWMAP, "Unlocked:"); - if (netgame) - V_DrawString(8, 96, V_YELLOWMAP, "Multiplayer games\ncan't unlock\nextras!"); - else + for (i = 0; i < MAXUNLOCKABLES; i++) { - INT32 startcoord = 32; - - for (i = 0; i < MAXUNLOCKABLES; i++) + if (unlockables[i].conditionset && unlockables[i].conditionset < MAXCONDITIONSETS + && unlockables[i].type && !unlockables[i].nocecho) { - if (unlockables[i].conditionset && unlockables[i].conditionset < MAXCONDITIONSETS - && unlockables[i].type && !unlockables[i].nocecho) - { - if (unlockables[i].unlocked) - V_DrawString(8, startcoord, 0, unlockables[i].name); - startcoord += 8; - } + if (clientGamedata->unlocked[i]) + V_DrawString(8, startcoord, 0, unlockables[i].name); + startcoord += 8; } } } @@ -1657,18 +1651,27 @@ void F_GameEvaluationTicker(void) } else { - ++timesBeaten; + serverGamedata->timesBeaten++; + clientGamedata->timesBeaten++; if (ALL7EMERALDS(emeralds)) - ++timesBeatenWithEmeralds; + { + serverGamedata->timesBeatenWithEmeralds++; + clientGamedata->timesBeatenWithEmeralds++; + } if (ultimatemode) - ++timesBeatenUltimate; + { + serverGamedata->timesBeatenUltimate++; + clientGamedata->timesBeatenUltimate++; + } - if (M_UpdateUnlockablesAndExtraEmblems()) + M_SilentUpdateUnlockablesAndEmblems(serverGamedata); + + if (M_UpdateUnlockablesAndExtraEmblems(clientGamedata)) S_StartSound(NULL, sfx_s3k68); - G_SaveGameData(); + G_SaveGameData(clientGamedata); } } } @@ -2183,7 +2186,7 @@ void F_EndingDrawer(void) //colset(linkmap, 164, 165, 169); -- the ideal purple colour to represent a clicked in-game link, but not worth it just for a soundtest-controlled secret V_DrawCenteredString(BASEVIDWIDTH/2, 8, V_ALLOWLOWERCASE|(trans<'|(trans<= STOPPINGPOINT-TICRATE) ? V_PURPLEMAP : V_BLUEMAP)|(trans<"); + V_DrawString(40, ((finalecount == STOPPINGPOINT-(20+TICRATE)) ? 1 : 0)+BASEVIDHEIGHT-16, ((serverGamedata->timesBeaten || finalecount >= STOPPINGPOINT-TICRATE) ? V_PURPLEMAP : V_BLUEMAP)|(trans<"); } if (finalecount > STOPPINGPOINT-(20+(2*TICRATE))) diff --git a/src/g_game.c b/src/g_game.c index 7386b2a84..854bf9bbb 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -185,18 +185,6 @@ INT32 tokenbits; // Used for setting token bits // Old Special Stage INT32 sstimer; // Time allotted in the special stage -tic_t totalplaytime; -boolean gamedataloaded = false; - -// Time attack data for levels -// These are dynamically allocated for space reasons now -recorddata_t *mainrecords[NUMMAPS] = {NULL}; -nightsdata_t *nightsrecords[NUMMAPS] = {NULL}; -UINT8 mapvisited[NUMMAPS]; - -// Temporary holding place for nights data for the current map -nightsdata_t ntemprecords; - UINT32 bluescore, redscore; // CTF and Team Match team scores // ring count... for PERFECT! @@ -252,11 +240,6 @@ INT32 cheats; //for multiplayer cheat commands tic_t hidetime; -// Grading -UINT32 timesBeaten; -UINT32 timesBeatenWithEmeralds; -UINT32 timesBeatenUltimate; - typedef struct joystickvector2_s { INT32 xaxis; @@ -452,86 +435,86 @@ INT16 rw_maximums[NUM_WEAPONS] = }; // Allocation for time and nights data -void G_AllocMainRecordData(INT16 i) +void G_AllocMainRecordData(INT16 i, gamedata_t *data) { - if (!mainrecords[i]) - mainrecords[i] = Z_Malloc(sizeof(recorddata_t), PU_STATIC, NULL); - memset(mainrecords[i], 0, sizeof(recorddata_t)); + if (!data->mainrecords[i]) + data->mainrecords[i] = Z_Malloc(sizeof(recorddata_t), PU_STATIC, NULL); + memset(data->mainrecords[i], 0, sizeof(recorddata_t)); } -void G_AllocNightsRecordData(INT16 i) +void G_AllocNightsRecordData(INT16 i, gamedata_t *data) { - if (!nightsrecords[i]) - nightsrecords[i] = Z_Malloc(sizeof(nightsdata_t), PU_STATIC, NULL); - memset(nightsrecords[i], 0, sizeof(nightsdata_t)); + if (!data->nightsrecords[i]) + data->nightsrecords[i] = Z_Malloc(sizeof(nightsdata_t), PU_STATIC, NULL); + memset(data->nightsrecords[i], 0, sizeof(nightsdata_t)); } // MAKE SURE YOU SAVE DATA BEFORE CALLING THIS -void G_ClearRecords(void) +void G_ClearRecords(gamedata_t *data) { INT16 i; for (i = 0; i < NUMMAPS; ++i) { - if (mainrecords[i]) + if (data->mainrecords[i]) { - Z_Free(mainrecords[i]); - mainrecords[i] = NULL; + Z_Free(data->mainrecords[i]); + data->mainrecords[i] = NULL; } - if (nightsrecords[i]) + if (data->nightsrecords[i]) { - Z_Free(nightsrecords[i]); - nightsrecords[i] = NULL; + Z_Free(data->nightsrecords[i]); + data->nightsrecords[i] = NULL; } } } // For easy retrieval of records -UINT32 G_GetBestScore(INT16 map) +UINT32 G_GetBestScore(INT16 map, gamedata_t *data) { - if (!mainrecords[map-1]) + if (!data->mainrecords[map-1]) return 0; - return mainrecords[map-1]->score; + return data->mainrecords[map-1]->score; } -tic_t G_GetBestTime(INT16 map) +tic_t G_GetBestTime(INT16 map, gamedata_t *data) { - if (!mainrecords[map-1] || mainrecords[map-1]->time <= 0) + if (!data->mainrecords[map-1] || data->mainrecords[map-1]->time <= 0) return (tic_t)UINT32_MAX; - return mainrecords[map-1]->time; + return data->mainrecords[map-1]->time; } -UINT16 G_GetBestRings(INT16 map) +UINT16 G_GetBestRings(INT16 map, gamedata_t *data) { - if (!mainrecords[map-1]) + if (!data->mainrecords[map-1]) return 0; - return mainrecords[map-1]->rings; + return data->mainrecords[map-1]->rings; } -UINT32 G_GetBestNightsScore(INT16 map, UINT8 mare) +UINT32 G_GetBestNightsScore(INT16 map, UINT8 mare, gamedata_t *data) { - if (!nightsrecords[map-1]) + if (!data->nightsrecords[map-1]) return 0; - return nightsrecords[map-1]->score[mare]; + return data->nightsrecords[map-1]->score[mare]; } -tic_t G_GetBestNightsTime(INT16 map, UINT8 mare) +tic_t G_GetBestNightsTime(INT16 map, UINT8 mare, gamedata_t *data) { - if (!nightsrecords[map-1] || nightsrecords[map-1]->time[mare] <= 0) + if (!data->nightsrecords[map-1] || data->nightsrecords[map-1]->time[mare] <= 0) return (tic_t)UINT32_MAX; - return nightsrecords[map-1]->time[mare]; + return data->nightsrecords[map-1]->time[mare]; } -UINT8 G_GetBestNightsGrade(INT16 map, UINT8 mare) +UINT8 G_GetBestNightsGrade(INT16 map, UINT8 mare, gamedata_t *data) { - if (!nightsrecords[map-1]) + if (!data->nightsrecords[map-1]) return 0; - return nightsrecords[map-1]->grade[mare]; + return data->nightsrecords[map-1]->grade[mare]; } // For easy adding of NiGHTS records @@ -553,7 +536,7 @@ void G_AddTempNightsRecords(UINT32 pscore, tic_t ptime, UINT8 mare) // Update replay files/data, etc. for Record Attack // See G_SetNightsRecords for NiGHTS Attack. // -static void G_UpdateRecordReplays(void) +static void G_UpdateRecordReplays(gamedata_t *data) { const size_t glen = strlen(srb2home)+1+strlen("replay")+1+strlen(timeattackfolder)+1+strlen("MAPXX")+1; char *gpath; @@ -561,17 +544,17 @@ static void G_UpdateRecordReplays(void) UINT8 earnedEmblems; // Record new best time - if (!mainrecords[gamemap-1]) - G_AllocMainRecordData(gamemap-1); + if (!data->mainrecords[gamemap-1]) + G_AllocMainRecordData(gamemap-1, data); - if (players[consoleplayer].score > mainrecords[gamemap-1]->score) - mainrecords[gamemap-1]->score = players[consoleplayer].score; + if (players[consoleplayer].score > data->mainrecords[gamemap-1]->score) + data->mainrecords[gamemap-1]->score = players[consoleplayer].score; - if ((mainrecords[gamemap-1]->time == 0) || (players[consoleplayer].realtime < mainrecords[gamemap-1]->time)) - mainrecords[gamemap-1]->time = players[consoleplayer].realtime; + if ((data->mainrecords[gamemap-1]->time == 0) || (players[consoleplayer].realtime < data->mainrecords[gamemap-1]->time)) + data->mainrecords[gamemap-1]->time = players[consoleplayer].realtime; - if ((UINT16)(players[consoleplayer].rings) > mainrecords[gamemap-1]->rings) - mainrecords[gamemap-1]->rings = (UINT16)(players[consoleplayer].rings); + if ((UINT16)(players[consoleplayer].rings) > data->mainrecords[gamemap-1]->rings) + data->mainrecords[gamemap-1]->rings = (UINT16)(players[consoleplayer].rings); // Save demo! bestdemo[255] = '\0'; @@ -627,14 +610,14 @@ static void G_UpdateRecordReplays(void) free(gpath); // Check emblems when level data is updated - if ((earnedEmblems = M_CheckLevelEmblems())) + if ((earnedEmblems = M_CheckLevelEmblems(data))) CONS_Printf(M_GetText("\x82" "Earned %hu emblem%s for Record Attack records.\n"), (UINT16)earnedEmblems, earnedEmblems > 1 ? "s" : ""); // Update timeattack menu's replay availability. Nextmap_OnChange(); } -void G_SetNightsRecords(void) +void G_SetNightsRecords(gamedata_t *data) { INT32 i; UINT32 totalscore = 0; @@ -675,9 +658,9 @@ void G_SetNightsRecords(void) { nightsdata_t *maprecords; - if (!nightsrecords[gamemap-1]) - G_AllocNightsRecordData(gamemap-1); - maprecords = nightsrecords[gamemap-1]; + if (!data->nightsrecords[gamemap-1]) + G_AllocNightsRecordData(gamemap-1, data); + maprecords = data->nightsrecords[gamemap-1]; if (maprecords->nummares != ntemprecords.nummares) maprecords->nummares = ntemprecords.nummares; @@ -739,7 +722,7 @@ void G_SetNightsRecords(void) } free(gpath); - if ((earnedEmblems = M_CheckLevelEmblems())) + if ((earnedEmblems = M_CheckLevelEmblems(data))) CONS_Printf(M_GetText("\x82" "Earned %hu emblem%s for NiGHTS records.\n"), (UINT16)earnedEmblems, earnedEmblems > 1 ? "s" : ""); // If the mare count changed, this will update the score display @@ -3838,7 +3821,7 @@ static INT16 RandMap(UINT32 tolflags, INT16 pprevmap) for (ix = 0; ix < NUMMAPS; ix++) if (mapheaderinfo[ix] && (mapheaderinfo[ix]->typeoflevel & tolflags) == tolflags && ix != pprevmap // Don't pick the same map. - && (dedicated || !M_MapLocked(ix+1)) // Don't pick locked maps. + && (dedicated || !M_MapLocked(ix+1, serverGamedata)) // Don't pick locked maps. ) okmaps[numokmaps++] = ix; @@ -3855,7 +3838,7 @@ static INT16 RandMap(UINT32 tolflags, INT16 pprevmap) // // G_UpdateVisited // -static void G_UpdateVisited(void) +static void G_UpdateVisited(gamedata_t *data, boolean silent) { boolean spec = G_IsSpecialStage(gamemap); // Update visitation flags? @@ -3865,30 +3848,37 @@ static void G_UpdateVisited(void) UINT8 earnedEmblems; // Update visitation flags - mapvisited[gamemap-1] |= MV_BEATEN; + data->mapvisited[gamemap-1] |= MV_BEATEN; // eh, what the hell if (ultimatemode) - mapvisited[gamemap-1] |= MV_ULTIMATE; + data->mapvisited[gamemap-1] |= MV_ULTIMATE; // may seem incorrect but IS possible in what the main game uses as mp special stages, and nummaprings will be -1 in NiGHTS if (nummaprings > 0 && players[consoleplayer].rings >= nummaprings) { - mapvisited[gamemap-1] |= MV_PERFECT; + data->mapvisited[gamemap-1] |= MV_PERFECT; if (modeattacking) - mapvisited[gamemap-1] |= MV_PERFECTRA; + data->mapvisited[gamemap-1] |= MV_PERFECTRA; } if (!spec) { // not available to special stages because they can only really be done in one order in an unmodified game, so impossible for first six and trivial for seventh if (ALL7EMERALDS(emeralds)) - mapvisited[gamemap-1] |= MV_ALLEMERALDS; + data->mapvisited[gamemap-1] |= MV_ALLEMERALDS; } - if (modeattacking == ATTACKING_RECORD) - G_UpdateRecordReplays(); - else if (modeattacking == ATTACKING_NIGHTS) - G_SetNightsRecords(); + if (silent) + { + M_CheckLevelEmblems(data); + } + else + { + if (modeattacking == ATTACKING_RECORD) + G_UpdateRecordReplays(data); + else if (modeattacking == ATTACKING_NIGHTS) + G_SetNightsRecords(data); + } - if ((earnedEmblems = M_CompletionEmblems())) + if ((earnedEmblems = M_CompletionEmblems(data)) && !silent) CONS_Printf(M_GetText("\x82" "Earned %hu emblem%s for level completion.\n"), (UINT16)earnedEmblems, earnedEmblems > 1 ? "s" : ""); } } @@ -4091,7 +4081,8 @@ static void G_DoCompleted(void) if ((skipstats && !modeattacking) || (modeattacking && stagefailed) || (intertype == int_none)) { - G_UpdateVisited(); + G_UpdateVisited(serverGamedata, true); + G_UpdateVisited(clientGamedata, false); G_HandleSaveLevel(); G_AfterIntermission(); } @@ -4100,7 +4091,8 @@ static void G_DoCompleted(void) G_SetGamestate(GS_INTERMISSION); Y_StartIntermission(); Y_LoadIntermissionData(); - G_UpdateVisited(); + G_UpdateVisited(serverGamedata, true); + G_UpdateVisited(clientGamedata, false); G_HandleSaveLevel(); } } @@ -4287,7 +4279,7 @@ void G_LoadGameSettings(void) // G_LoadGameData // Loads the main data file, which stores information such as emblems found, etc. -void G_LoadGameData(void) +void G_LoadGameData(gamedata_t *data) { size_t length; INT32 i, j; @@ -4304,13 +4296,13 @@ void G_LoadGameData(void) INT32 curmare; // Stop saving, until we successfully load it again. - gamedataloaded = false; + data->loaded = false; // Clear things so previously read gamedata doesn't transfer // to new gamedata - G_ClearRecords(); // main and nights records - M_ClearSecrets(); // emblems, unlocks, maps visited, etc - totalplaytime = 0; // total play time (separate from all) + G_ClearRecords(data); // main and nights records + M_ClearSecrets(data); // emblems, unlocks, maps visited, etc + data->totalplaytime = 0; // total play time (separate from all) if (M_CheckParm("-nodata")) { @@ -4321,7 +4313,7 @@ void G_LoadGameData(void) if (M_CheckParm("-resetdata")) { // Don't load, but do save. (essentially, reset) - gamedataloaded = true; + data->loaded = true; return; } @@ -4329,7 +4321,7 @@ void G_LoadGameData(void) if (!length) { // No gamedata. We can save a new one. - gamedataloaded = true; + data->loaded = true; return; } @@ -4352,7 +4344,7 @@ void G_LoadGameData(void) I_Error("Game data is from another version of SRB2.\nDelete %s(maybe in %s) and try again.", gamedatafilename, gdfolder); } - totalplaytime = READUINT32(save_p); + data->totalplaytime = READUINT32(save_p); #ifdef COMPAT_GAMEDATA_ID if (versionID == COMPAT_GAMEDATA_ID) @@ -4386,7 +4378,7 @@ void G_LoadGameData(void) // TODO put another cipher on these things? meh, I don't care... for (i = 0; i < NUMMAPS; i++) - if ((mapvisited[i] = READUINT8(save_p)) > MV_MAX) + if ((data->mapvisited[i] = READUINT8(save_p)) > MV_MAX) goto datacorrupt; // To save space, use one bit per collected/achieved/unlocked flag @@ -4394,34 +4386,34 @@ void G_LoadGameData(void) { rtemp = READUINT8(save_p); for (j = 0; j < 8 && j+i < MAXEMBLEMS; ++j) - emblemlocations[j+i].collected = ((rtemp >> j) & 1); + data->collected[j+i] = ((rtemp >> j) & 1); i += j; } for (i = 0; i < MAXEXTRAEMBLEMS;) { rtemp = READUINT8(save_p); for (j = 0; j < 8 && j+i < MAXEXTRAEMBLEMS; ++j) - extraemblems[j+i].collected = ((rtemp >> j) & 1); + data->extraCollected[j+i] = ((rtemp >> j) & 1); i += j; } for (i = 0; i < MAXUNLOCKABLES;) { rtemp = READUINT8(save_p); for (j = 0; j < 8 && j+i < MAXUNLOCKABLES; ++j) - unlockables[j+i].unlocked = ((rtemp >> j) & 1); + data->unlocked[j+i] = ((rtemp >> j) & 1); i += j; } for (i = 0; i < MAXCONDITIONSETS;) { rtemp = READUINT8(save_p); for (j = 0; j < 8 && j+i < MAXCONDITIONSETS; ++j) - conditionSets[j+i].achieved = ((rtemp >> j) & 1); + data->achieved[j+i] = ((rtemp >> j) & 1); i += j; } - timesBeaten = READUINT32(save_p); - timesBeatenWithEmeralds = READUINT32(save_p); - timesBeatenUltimate = READUINT32(save_p); + data->timesBeaten = READUINT32(save_p); + data->timesBeatenWithEmeralds = READUINT32(save_p); + data->timesBeatenUltimate = READUINT32(save_p); // Main records for (i = 0; i < NUMMAPS; ++i) @@ -4436,10 +4428,10 @@ void G_LoadGameData(void) if (recscore || rectime || recrings) { - G_AllocMainRecordData((INT16)i); - mainrecords[i]->score = recscore; - mainrecords[i]->time = rectime; - mainrecords[i]->rings = recrings; + G_AllocMainRecordData((INT16)i, data); + data->mainrecords[i]->score = recscore; + data->mainrecords[i]->time = rectime; + data->mainrecords[i]->rings = recrings; } } @@ -4449,19 +4441,21 @@ void G_LoadGameData(void) if ((recmares = READUINT8(save_p)) == 0) continue; - G_AllocNightsRecordData((INT16)i); + G_AllocNightsRecordData((INT16)i, data); for (curmare = 0; curmare < (recmares+1); ++curmare) { - nightsrecords[i]->score[curmare] = READUINT32(save_p); - nightsrecords[i]->grade[curmare] = READUINT8(save_p); - nightsrecords[i]->time[curmare] = (tic_t)READUINT32(save_p); + data->nightsrecords[i]->score[curmare] = READUINT32(save_p); + data->nightsrecords[i]->grade[curmare] = READUINT8(save_p); + data->nightsrecords[i]->time[curmare] = (tic_t)READUINT32(save_p); - if (nightsrecords[i]->grade[curmare] > GRADE_S) + if (data->nightsrecords[i]->grade[curmare] > GRADE_S) + { goto datacorrupt; + } } - nightsrecords[i]->nummares = recmares; + data->nightsrecords[i]->nummares = recmares; } // done @@ -4472,10 +4466,11 @@ void G_LoadGameData(void) // It used to do this much earlier, but this would cause the gamedata to // save over itself when it I_Errors from the corruption landing point below, // which can accidentally delete players' legitimate data if the code ever has any tiny mistakes! - gamedataloaded = true; + data->loaded = true; // Silent update unlockables in case they're out of sync with conditions - M_SilentUpdateUnlockablesAndEmblems(); + M_SilentUpdateUnlockablesAndEmblems(data); + M_SilentUpdateSkinAvailabilites(); return; @@ -4495,7 +4490,7 @@ void G_LoadGameData(void) // G_SaveGameData // Saves the main data file, which stores information such as emblems found, etc. -void G_SaveGameData(void) +void G_SaveGameData(gamedata_t *data) { size_t length; INT32 i, j; @@ -4503,7 +4498,7 @@ void G_SaveGameData(void) INT32 curmare; - if (!gamedataloaded) + if (!data->loaded) return; // If never loaded (-nodata), don't save save_p = savebuffer = (UINT8 *)malloc(GAMEDATASIZE); @@ -4523,20 +4518,20 @@ void G_SaveGameData(void) // Version test WRITEUINT32(save_p, GAMEDATA_ID); - WRITEUINT32(save_p, totalplaytime); + WRITEUINT32(save_p, data->totalplaytime); WRITEUINT32(save_p, quickncasehash(timeattackfolder, sizeof timeattackfolder)); // TODO put another cipher on these things? meh, I don't care... for (i = 0; i < NUMMAPS; i++) - WRITEUINT8(save_p, (mapvisited[i] & MV_MAX)); + WRITEUINT8(save_p, (data->mapvisited[i] & MV_MAX)); // To save space, use one bit per collected/achieved/unlocked flag for (i = 0; i < MAXEMBLEMS;) { btemp = 0; for (j = 0; j < 8 && j+i < MAXEMBLEMS; ++j) - btemp |= (emblemlocations[j+i].collected << j); + btemp |= (data->collected[j+i] << j); WRITEUINT8(save_p, btemp); i += j; } @@ -4544,7 +4539,7 @@ void G_SaveGameData(void) { btemp = 0; for (j = 0; j < 8 && j+i < MAXEXTRAEMBLEMS; ++j) - btemp |= (extraemblems[j+i].collected << j); + btemp |= (data->extraCollected[j+i] << j); WRITEUINT8(save_p, btemp); i += j; } @@ -4552,7 +4547,7 @@ void G_SaveGameData(void) { btemp = 0; for (j = 0; j < 8 && j+i < MAXUNLOCKABLES; ++j) - btemp |= (unlockables[j+i].unlocked << j); + btemp |= (data->unlocked[j+i] << j); WRITEUINT8(save_p, btemp); i += j; } @@ -4560,23 +4555,23 @@ void G_SaveGameData(void) { btemp = 0; for (j = 0; j < 8 && j+i < MAXCONDITIONSETS; ++j) - btemp |= (conditionSets[j+i].achieved << j); + btemp |= (data->achieved[j+i] << j); WRITEUINT8(save_p, btemp); i += j; } - WRITEUINT32(save_p, timesBeaten); - WRITEUINT32(save_p, timesBeatenWithEmeralds); - WRITEUINT32(save_p, timesBeatenUltimate); + WRITEUINT32(save_p, data->timesBeaten); + WRITEUINT32(save_p, data->timesBeatenWithEmeralds); + WRITEUINT32(save_p, data->timesBeatenUltimate); // Main records for (i = 0; i < NUMMAPS; i++) { - if (mainrecords[i]) + if (data->mainrecords[i]) { - WRITEUINT32(save_p, mainrecords[i]->score); - WRITEUINT32(save_p, mainrecords[i]->time); - WRITEUINT16(save_p, mainrecords[i]->rings); + WRITEUINT32(save_p, data->mainrecords[i]->score); + WRITEUINT32(save_p, data->mainrecords[i]->time); + WRITEUINT16(save_p, data->mainrecords[i]->rings); } else { @@ -4590,19 +4585,19 @@ void G_SaveGameData(void) // NiGHTS records for (i = 0; i < NUMMAPS; i++) { - if (!nightsrecords[i] || !nightsrecords[i]->nummares) + if (!data->nightsrecords[i] || !data->nightsrecords[i]->nummares) { WRITEUINT8(save_p, 0); continue; } - WRITEUINT8(save_p, nightsrecords[i]->nummares); + WRITEUINT8(save_p, data->nightsrecords[i]->nummares); - for (curmare = 0; curmare < (nightsrecords[i]->nummares + 1); ++curmare) + for (curmare = 0; curmare < (data->nightsrecords[i]->nummares + 1); ++curmare) { - WRITEUINT32(save_p, nightsrecords[i]->score[curmare]); - WRITEUINT8(save_p, nightsrecords[i]->grade[curmare]); - WRITEUINT32(save_p, nightsrecords[i]->time[curmare]); + WRITEUINT32(save_p, data->nightsrecords[i]->score[curmare]); + WRITEUINT8(save_p, data->nightsrecords[i]->grade[curmare]); + WRITEUINT32(save_p, data->nightsrecords[i]->time[curmare]); } } diff --git a/src/g_game.h b/src/g_game.h index 144360db4..6cda7ca9c 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -19,6 +19,7 @@ #include "d_event.h" #include "g_demo.h" #include "m_cheat.h" // objectplacing +#include "m_cond.h" extern char gamedatafilename[64]; extern char timeattackfolder[64]; @@ -183,7 +184,7 @@ boolean G_IsTitleCardAvailable(void); // Can be called by the startup code or M_Responder, calls P_SetupLevel. void G_LoadGame(UINT32 slot, INT16 mapoverride); -void G_SaveGameData(void); +void G_SaveGameData(gamedata_t *data); void G_SaveGame(UINT32 slot, INT16 mapnum); @@ -239,7 +240,7 @@ void G_SetModeAttackRetryFlag(void); void G_ClearModeAttackRetryFlag(void); boolean G_GetModeAttackRetryFlag(void); -void G_LoadGameData(void); +void G_LoadGameData(gamedata_t *data); void G_LoadGameSettings(void); void G_SetGameModified(boolean silent); @@ -248,19 +249,19 @@ void G_SetUsedCheats(boolean silent); void G_SetGamestate(gamestate_t newstate); // Gamedata record shit -void G_AllocMainRecordData(INT16 i); -void G_AllocNightsRecordData(INT16 i); -void G_ClearRecords(void); +void G_AllocMainRecordData(INT16 i, gamedata_t *data); +void G_AllocNightsRecordData(INT16 i, gamedata_t *data); +void G_ClearRecords(gamedata_t *data); -UINT32 G_GetBestScore(INT16 map); -tic_t G_GetBestTime(INT16 map); -UINT16 G_GetBestRings(INT16 map); -UINT32 G_GetBestNightsScore(INT16 map, UINT8 mare); -tic_t G_GetBestNightsTime(INT16 map, UINT8 mare); -UINT8 G_GetBestNightsGrade(INT16 map, UINT8 mare); +UINT32 G_GetBestScore(INT16 map, gamedata_t *data); +tic_t G_GetBestTime(INT16 map, gamedata_t *data); +UINT16 G_GetBestRings(INT16 map, gamedata_t *data); +UINT32 G_GetBestNightsScore(INT16 map, UINT8 mare, gamedata_t *data); +tic_t G_GetBestNightsTime(INT16 map, UINT8 mare, gamedata_t *data); +UINT8 G_GetBestNightsGrade(INT16 map, UINT8 mare, gamedata_t *data); void G_AddTempNightsRecords(UINT32 pscore, tic_t ptime, UINT8 mare); -void G_SetNightsRecords(void); +void G_SetNightsRecords(gamedata_t *data); FUNCMATH INT32 G_TicsToHours(tic_t tics); FUNCMATH INT32 G_TicsToMinutes(tic_t tics, boolean full); diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 55ebe0d4d..eceb6bbaf 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -2996,7 +2996,7 @@ static void HU_DrawCoopOverlay(void) if (LUA_HudEnabled(hud_tabemblems)) { - V_DrawString(160, 144, 0, va("- %d/%d", M_CountEmblems(), numemblems+numextraemblems)); + V_DrawString(160, 144, 0, va("- %d/%d", M_CountEmblems(clientGamedata), numemblems+numextraemblems)); V_DrawScaledPatch(128, 144 - emblemicon->height/4, 0, emblemicon); } diff --git a/src/m_cheat.c b/src/m_cheat.c index 9d257b48b..934779982 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -102,7 +102,7 @@ static UINT8 cheatf_devmode(void) // Just unlock all the things and turn on -debug and console devmode. G_SetUsedCheats(false); for (i = 0; i < MAXUNLOCKABLES; i++) - unlockables[i].unlocked = true; + clientGamedata->unlocked[i] = true; devparm = true; cv_debug |= 0x8000; @@ -238,7 +238,7 @@ boolean cht_Responder(event_t *ev) } // Console cheat commands rely on these a lot... -#define REQUIRE_PANDORA if (!M_SecretUnlocked(SECRET_PANDORA) && !cv_debug)\ +#define REQUIRE_PANDORA if (!M_SecretUnlocked(SECRET_PANDORA, serverGamedata) && !cv_debug)\ { CONS_Printf(M_GetText("You haven't earned this yet.\n")); return; } #define REQUIRE_DEVMODE if (!cv_debug)\ diff --git a/src/m_cond.c b/src/m_cond.c index bd6faadfd..55f35830a 100644 --- a/src/m_cond.c +++ b/src/m_cond.c @@ -21,6 +21,9 @@ #include "r_skins.h" // numskins #include "r_draw.h" // R_GetColorByName +gamedata_t *clientGamedata; // Our gamedata +gamedata_t *serverGamedata; // Server's gamedata + // Map triggers for linedef executors // 32 triggers, one bit each UINT32 unlocktriggers; @@ -41,6 +44,70 @@ unlockable_t unlockables[MAXUNLOCKABLES]; INT32 numemblems = 0; INT32 numextraemblems = 0; +// Temporary holding place for nights data for the current map +nightsdata_t ntemprecords; + +// Create a new gamedata_t, for start-up +gamedata_t *M_NewGameDataStruct(void) +{ + gamedata_t *data = Z_Calloc(sizeof (*data), PU_STATIC, NULL); + M_ClearSecrets(data); + G_ClearRecords(data); + return data; +} + +void M_CopyGameData(gamedata_t *dest, gamedata_t *src) +{ + INT32 i, j; + + M_ClearSecrets(dest); + G_ClearRecords(dest); + + dest->loaded = src->loaded; + dest->totalplaytime = src->totalplaytime; + + dest->timesBeaten = src->timesBeaten; + dest->timesBeatenWithEmeralds = src->timesBeatenWithEmeralds; + dest->timesBeatenUltimate = src->timesBeatenUltimate; + + memcpy(dest->achieved, src->achieved, sizeof(dest->achieved)); + memcpy(dest->collected, src->collected, sizeof(dest->collected)); + memcpy(dest->extraCollected, src->extraCollected, sizeof(dest->extraCollected)); + memcpy(dest->unlocked, src->unlocked, sizeof(dest->unlocked)); + + memcpy(dest->mapvisited, src->mapvisited, sizeof(dest->mapvisited)); + + // Main records + for (i = 0; i < NUMMAPS; ++i) + { + if (!src->mainrecords[i]) + continue; + + G_AllocMainRecordData((INT16)i, dest); + dest->mainrecords[i]->score = src->mainrecords[i]->score; + dest->mainrecords[i]->time = src->mainrecords[i]->time; + dest->mainrecords[i]->rings = src->mainrecords[i]->rings; + } + + // Nights records + for (i = 0; i < NUMMAPS; ++i) + { + if (!src->nightsrecords[i] || !src->nightsrecords[i]->nummares) + continue; + + G_AllocNightsRecordData((INT16)i, dest); + + for (j = 0; j < (src->nightsrecords[i]->nummares + 1); j++) + { + dest->nightsrecords[i]->score[j] = src->nightsrecords[i]->score[j]; + dest->nightsrecords[i]->grade[j] = src->nightsrecords[i]->grade[j]; + dest->nightsrecords[i]->time[j] = src->nightsrecords[i]->time[j]; + } + + dest->nightsrecords[i]->nummares = src->nightsrecords[i]->nummares; + } +} + void M_AddRawCondition(UINT8 set, UINT8 id, conditiontype_t c, INT32 r, INT16 x1, INT16 x2) { condition_t *cond; @@ -70,89 +137,90 @@ void M_ClearConditionSet(UINT8 set) conditionSets[set - 1].condition = NULL; conditionSets[set - 1].numconditions = 0; } - conditionSets[set - 1].achieved = false; + clientGamedata->achieved[set - 1] = serverGamedata->achieved[set - 1] = false; } // Clear ALL secrets. -void M_ClearSecrets(void) +void M_ClearSecrets(gamedata_t *data) { INT32 i; - memset(mapvisited, 0, sizeof(mapvisited)); + memset(data->mapvisited, 0, sizeof(data->mapvisited)); for (i = 0; i < MAXEMBLEMS; ++i) - emblemlocations[i].collected = false; + data->collected[i] = false; for (i = 0; i < MAXEXTRAEMBLEMS; ++i) - extraemblems[i].collected = false; + data->extraCollected[i] = false; for (i = 0; i < MAXUNLOCKABLES; ++i) - unlockables[i].unlocked = false; + data->unlocked[i] = false; for (i = 0; i < MAXCONDITIONSETS; ++i) - conditionSets[i].achieved = false; + data->achieved[i] = false; - timesBeaten = timesBeatenWithEmeralds = timesBeatenUltimate = 0; + data->timesBeaten = data->timesBeatenWithEmeralds = data->timesBeatenUltimate = 0; // Re-unlock any always unlocked things - M_SilentUpdateUnlockablesAndEmblems(); + M_SilentUpdateUnlockablesAndEmblems(data); + M_SilentUpdateSkinAvailabilites(); } // ---------------------- // Condition set checking // ---------------------- -static UINT8 M_CheckCondition(condition_t *cn) +static UINT8 M_CheckCondition(condition_t *cn, gamedata_t *data) { switch (cn->type) { case UC_PLAYTIME: // Requires total playing time >= x - return (totalplaytime >= (unsigned)cn->requirement); + return (data->totalplaytime >= (unsigned)cn->requirement); case UC_GAMECLEAR: // Requires game beaten >= x times - return (timesBeaten >= (unsigned)cn->requirement); + return (data->timesBeaten >= (unsigned)cn->requirement); case UC_ALLEMERALDS: // Requires game beaten with all 7 emeralds >= x times - return (timesBeatenWithEmeralds >= (unsigned)cn->requirement); + return (data->timesBeatenWithEmeralds >= (unsigned)cn->requirement); case UC_ULTIMATECLEAR: // Requires game beaten on ultimate >= x times (in other words, never) - return (timesBeatenUltimate >= (unsigned)cn->requirement); + return (data->timesBeatenUltimate >= (unsigned)cn->requirement); case UC_OVERALLSCORE: // Requires overall score >= x - return (M_GotHighEnoughScore(cn->requirement)); + return (M_GotHighEnoughScore(cn->requirement, data)); case UC_OVERALLTIME: // Requires overall time <= x - return (M_GotLowEnoughTime(cn->requirement)); + return (M_GotLowEnoughTime(cn->requirement, data)); case UC_OVERALLRINGS: // Requires overall rings >= x - return (M_GotHighEnoughRings(cn->requirement)); + return (M_GotHighEnoughRings(cn->requirement, data)); case UC_MAPVISITED: // Requires map x to be visited - return ((mapvisited[cn->requirement - 1] & MV_VISITED) == MV_VISITED); + return ((data->mapvisited[cn->requirement - 1] & MV_VISITED) == MV_VISITED); case UC_MAPBEATEN: // Requires map x to be beaten - return ((mapvisited[cn->requirement - 1] & MV_BEATEN) == MV_BEATEN); + return ((data->mapvisited[cn->requirement - 1] & MV_BEATEN) == MV_BEATEN); case UC_MAPALLEMERALDS: // Requires map x to be beaten with all emeralds in possession - return ((mapvisited[cn->requirement - 1] & MV_ALLEMERALDS) == MV_ALLEMERALDS); + return ((data->mapvisited[cn->requirement - 1] & MV_ALLEMERALDS) == MV_ALLEMERALDS); case UC_MAPULTIMATE: // Requires map x to be beaten on ultimate - return ((mapvisited[cn->requirement - 1] & MV_ULTIMATE) == MV_ULTIMATE); + return ((data->mapvisited[cn->requirement - 1] & MV_ULTIMATE) == MV_ULTIMATE); case UC_MAPPERFECT: // Requires map x to be beaten with a perfect bonus - return ((mapvisited[cn->requirement - 1] & MV_PERFECT) == MV_PERFECT); + return ((data->mapvisited[cn->requirement - 1] & MV_PERFECT) == MV_PERFECT); case UC_MAPSCORE: // Requires score on map >= x - return (G_GetBestScore(cn->extrainfo1) >= (unsigned)cn->requirement); + return (G_GetBestScore(cn->extrainfo1, data) >= (unsigned)cn->requirement); case UC_MAPTIME: // Requires time on map <= x - return (G_GetBestTime(cn->extrainfo1) <= (unsigned)cn->requirement); + return (G_GetBestTime(cn->extrainfo1, data) <= (unsigned)cn->requirement); case UC_MAPRINGS: // Requires rings on map >= x - return (G_GetBestRings(cn->extrainfo1) >= cn->requirement); + return (G_GetBestRings(cn->extrainfo1, data) >= cn->requirement); case UC_NIGHTSSCORE: - return (G_GetBestNightsScore(cn->extrainfo1, (UINT8)cn->extrainfo2) >= (unsigned)cn->requirement); + return (G_GetBestNightsScore(cn->extrainfo1, (UINT8)cn->extrainfo2, data) >= (unsigned)cn->requirement); case UC_NIGHTSTIME: - return (G_GetBestNightsTime(cn->extrainfo1, (UINT8)cn->extrainfo2) <= (unsigned)cn->requirement); + return (G_GetBestNightsTime(cn->extrainfo1, (UINT8)cn->extrainfo2, data) <= (unsigned)cn->requirement); case UC_NIGHTSGRADE: - return (G_GetBestNightsGrade(cn->extrainfo1, (UINT8)cn->extrainfo2) >= cn->requirement); + return (G_GetBestNightsGrade(cn->extrainfo1, (UINT8)cn->extrainfo2, data) >= cn->requirement); case UC_TRIGGER: // requires map trigger set return !!(unlocktriggers & (1 << cn->requirement)); case UC_TOTALEMBLEMS: // Requires number of emblems >= x - return (M_GotEnoughEmblems(cn->requirement)); + return (M_GotEnoughEmblems(cn->requirement, data)); case UC_EMBLEM: // Requires emblem x to be obtained - return emblemlocations[cn->requirement-1].collected; + return data->collected[cn->requirement-1]; case UC_EXTRAEMBLEM: // Requires extra emblem x to be obtained - return extraemblems[cn->requirement-1].collected; + return data->extraCollected[cn->requirement-1]; case UC_CONDITIONSET: // requires condition set x to already be achieved - return M_Achieved(cn->requirement-1); + return M_Achieved(cn->requirement-1, data); } return false; } -static UINT8 M_CheckConditionSet(conditionset_t *c) +static UINT8 M_CheckConditionSet(conditionset_t *c, gamedata_t *data) { UINT32 i; UINT32 lastID = 0; @@ -173,13 +241,13 @@ static UINT8 M_CheckConditionSet(conditionset_t *c) continue; lastID = cn->id; - achievedSoFar = M_CheckCondition(cn); + achievedSoFar = M_CheckCondition(cn, data); } return achievedSoFar; } -void M_CheckUnlockConditions(void) +void M_CheckUnlockConditions(gamedata_t *data) { INT32 i; conditionset_t *c; @@ -187,27 +255,27 @@ void M_CheckUnlockConditions(void) for (i = 0; i < MAXCONDITIONSETS; ++i) { c = &conditionSets[i]; - if (!c->numconditions || c->achieved) + if (!c->numconditions || data->achieved[i]) continue; - c->achieved = (M_CheckConditionSet(c)); + data->achieved[i] = (M_CheckConditionSet(c, data)); } } -UINT8 M_UpdateUnlockablesAndExtraEmblems(void) +UINT8 M_UpdateUnlockablesAndExtraEmblems(gamedata_t *data) { INT32 i; char cechoText[992] = ""; UINT8 cechoLines = 0; - M_CheckUnlockConditions(); + M_CheckUnlockConditions(data); // Go through extra emblems for (i = 0; i < numextraemblems; ++i) { - if (extraemblems[i].collected || !extraemblems[i].conditionset) + if (data->extraCollected[i] || !extraemblems[i].conditionset) continue; - if ((extraemblems[i].collected = M_Achieved(extraemblems[i].conditionset - 1)) != false) + if ((data->extraCollected[i] = M_Achieved(extraemblems[i].conditionset - 1, data)) != false) { strcat(cechoText, va(M_GetText("Got \"%s\" emblem!\\"), extraemblems[i].name)); ++cechoLines; @@ -217,14 +285,14 @@ UINT8 M_UpdateUnlockablesAndExtraEmblems(void) // Fun part: if any of those unlocked we need to go through the // unlock conditions AGAIN just in case an emblem reward was reached if (cechoLines) - M_CheckUnlockConditions(); + M_CheckUnlockConditions(data); // Go through unlockables for (i = 0; i < MAXUNLOCKABLES; ++i) { - if (unlockables[i].unlocked || !unlockables[i].conditionset) + if (data->unlocked[i] || !unlockables[i].conditionset) continue; - if ((unlockables[i].unlocked = M_Achieved(unlockables[i].conditionset - 1)) != false) + if ((data->unlocked[i] = M_Achieved(unlockables[i].conditionset - 1, data)) != false) { if (unlockables[i].nocecho) continue; @@ -248,45 +316,49 @@ UINT8 M_UpdateUnlockablesAndExtraEmblems(void) HU_DoCEcho(slashed); return true; } + return false; } // Used when loading gamedata to make sure all unlocks are synched with conditions -void M_SilentUpdateUnlockablesAndEmblems(void) +void M_SilentUpdateUnlockablesAndEmblems(gamedata_t *data) { INT32 i; boolean checkAgain = false; // Just in case they aren't to sync - M_CheckUnlockConditions(); - M_CheckLevelEmblems(); + M_CheckUnlockConditions(data); + M_CheckLevelEmblems(data); // Go through extra emblems for (i = 0; i < numextraemblems; ++i) { - if (extraemblems[i].collected || !extraemblems[i].conditionset) + if (data->extraCollected[i] || !extraemblems[i].conditionset) continue; - if ((extraemblems[i].collected = M_Achieved(extraemblems[i].conditionset - 1)) != false) + if ((data->extraCollected[i] = M_Achieved(extraemblems[i].conditionset - 1, data)) != false) checkAgain = true; } // check again if extra emblems unlocked, blah blah, etc if (checkAgain) - M_CheckUnlockConditions(); + M_CheckUnlockConditions(data); // Go through unlockables for (i = 0; i < MAXUNLOCKABLES; ++i) { - if (unlockables[i].unlocked || !unlockables[i].conditionset) + if (data->unlocked[i] || !unlockables[i].conditionset) continue; - unlockables[i].unlocked = M_Achieved(unlockables[i].conditionset - 1); + data->unlocked[i] = M_Achieved(unlockables[i].conditionset - 1, data); } +} +void M_SilentUpdateSkinAvailabilites(void) +{ players[consoleplayer].availabilities = players[1].availabilities = R_GetSkinAvailabilities(); // players[1] is supposed to be for 2p } // Emblem unlocking shit -UINT8 M_CheckLevelEmblems(void) +UINT8 M_CheckLevelEmblems(gamedata_t *data) { INT32 i; INT32 valToReach; @@ -297,7 +369,7 @@ UINT8 M_CheckLevelEmblems(void) // Update Score, Time, Rings emblems for (i = 0; i < numemblems; ++i) { - if (emblemlocations[i].type <= ET_SKIN || emblemlocations[i].type == ET_MAP || emblemlocations[i].collected) + if (emblemlocations[i].type <= ET_SKIN || emblemlocations[i].type == ET_MAP || data->collected[i]) continue; levelnum = emblemlocations[i].level; @@ -306,32 +378,32 @@ UINT8 M_CheckLevelEmblems(void) switch (emblemlocations[i].type) { case ET_SCORE: // Requires score on map >= x - res = (G_GetBestScore(levelnum) >= (unsigned)valToReach); + res = (G_GetBestScore(levelnum, data) >= (unsigned)valToReach); break; case ET_TIME: // Requires time on map <= x - res = (G_GetBestTime(levelnum) <= (unsigned)valToReach); + res = (G_GetBestTime(levelnum, data) <= (unsigned)valToReach); break; case ET_RINGS: // Requires rings on map >= x - res = (G_GetBestRings(levelnum) >= valToReach); + res = (G_GetBestRings(levelnum, data) >= valToReach); break; case ET_NGRADE: // Requires NiGHTS grade on map >= x - res = (G_GetBestNightsGrade(levelnum, 0) >= valToReach); + res = (G_GetBestNightsGrade(levelnum, 0, data) >= valToReach); break; case ET_NTIME: // Requires NiGHTS time on map <= x - res = (G_GetBestNightsTime(levelnum, 0) <= (unsigned)valToReach); + res = (G_GetBestNightsTime(levelnum, 0, data) <= (unsigned)valToReach); break; default: // unreachable but shuts the compiler up. continue; } - emblemlocations[i].collected = res; + data->collected[i] = res; if (res) ++somethingUnlocked; } return somethingUnlocked; } -UINT8 M_CompletionEmblems(void) // Bah! Duplication sucks, but it's for a separate print when awarding emblems and it's sorta different enough. +UINT8 M_CompletionEmblems(gamedata_t *data) // Bah! Duplication sucks, but it's for a separate print when awarding emblems and it's sorta different enough. { INT32 i; INT32 embtype; @@ -342,7 +414,7 @@ UINT8 M_CompletionEmblems(void) // Bah! Duplication sucks, but it's for a separa for (i = 0; i < numemblems; ++i) { - if (emblemlocations[i].type != ET_MAP || emblemlocations[i].collected) + if (emblemlocations[i].type != ET_MAP || data->collected[i]) continue; levelnum = emblemlocations[i].level; @@ -358,9 +430,9 @@ UINT8 M_CompletionEmblems(void) // Bah! Duplication sucks, but it's for a separa if (embtype & ME_PERFECT) flags |= MV_PERFECT; - res = ((mapvisited[levelnum - 1] & flags) == flags); + res = ((data->mapvisited[levelnum - 1] & flags) == flags); - emblemlocations[i].collected = res; + data->collected[i] = res; if (res) ++somethingUnlocked; } @@ -370,48 +442,54 @@ UINT8 M_CompletionEmblems(void) // Bah! Duplication sucks, but it's for a separa // ------------------- // Quick unlock checks // ------------------- -UINT8 M_AnySecretUnlocked(void) +UINT8 M_AnySecretUnlocked(gamedata_t *data) { INT32 i; for (i = 0; i < MAXUNLOCKABLES; ++i) { - if (!unlockables[i].nocecho && unlockables[i].unlocked) + if (!unlockables[i].nocecho && data->unlocked[i]) return true; } return false; } -UINT8 M_SecretUnlocked(INT32 type) +UINT8 M_SecretUnlocked(INT32 type, gamedata_t *data) { INT32 i; for (i = 0; i < MAXUNLOCKABLES; ++i) { - if (unlockables[i].type == type && unlockables[i].unlocked) + if (unlockables[i].type == type && data->unlocked[i]) return true; } return false; } -UINT8 M_MapLocked(INT32 mapnum) +UINT8 M_MapLocked(INT32 mapnum, gamedata_t *data) { if (!mapheaderinfo[mapnum-1] || mapheaderinfo[mapnum-1]->unlockrequired < 0) + { return false; - if (!unlockables[mapheaderinfo[mapnum-1]->unlockrequired].unlocked) + } + + if (!data->unlocked[mapheaderinfo[mapnum-1]->unlockrequired]) + { return true; + } + return false; } -INT32 M_CountEmblems(void) +INT32 M_CountEmblems(gamedata_t *data) { INT32 found = 0, i; for (i = 0; i < numemblems; ++i) { - if (emblemlocations[i].collected) + if (data->collected[i]) found++; } for (i = 0; i < numextraemblems; ++i) { - if (extraemblems[i].collected) + if (data->extraCollected[i]) found++; } return found; @@ -423,23 +501,23 @@ INT32 M_CountEmblems(void) // Theoretically faster than using M_CountEmblems() // Stops when it reaches the target number of emblems. -UINT8 M_GotEnoughEmblems(INT32 number) +UINT8 M_GotEnoughEmblems(INT32 number, gamedata_t *data) { INT32 i, gottenemblems = 0; for (i = 0; i < numemblems; ++i) { - if (emblemlocations[i].collected) + if (data->collected[i]) if (++gottenemblems >= number) return true; } for (i = 0; i < numextraemblems; ++i) { - if (extraemblems[i].collected) + if (data->extraCollected[i]) if (++gottenemblems >= number) return true; } return false; } -UINT8 M_GotHighEnoughScore(INT32 tscore) +UINT8 M_GotHighEnoughScore(INT32 tscore, gamedata_t *data) { INT32 mscore = 0; INT32 i; @@ -448,16 +526,16 @@ UINT8 M_GotHighEnoughScore(INT32 tscore) { if (!mapheaderinfo[i] || !(mapheaderinfo[i]->menuflags & LF2_RECORDATTACK)) continue; - if (!mainrecords[i]) + if (!data->mainrecords[i]) continue; - if ((mscore += mainrecords[i]->score) > tscore) + if ((mscore += data->mainrecords[i]->score) > tscore) return true; } return false; } -UINT8 M_GotLowEnoughTime(INT32 tictime) +UINT8 M_GotLowEnoughTime(INT32 tictime, gamedata_t *data) { INT32 curtics = 0; INT32 i; @@ -467,15 +545,15 @@ UINT8 M_GotLowEnoughTime(INT32 tictime) if (!mapheaderinfo[i] || !(mapheaderinfo[i]->menuflags & LF2_RECORDATTACK)) continue; - if (!mainrecords[i] || !mainrecords[i]->time) + if (!data->mainrecords[i] || !data->mainrecords[i]->time) return false; - else if ((curtics += mainrecords[i]->time) > tictime) + else if ((curtics += data->mainrecords[i]->time) > tictime) return false; } return true; } -UINT8 M_GotHighEnoughRings(INT32 trings) +UINT8 M_GotHighEnoughRings(INT32 trings, gamedata_t *data) { INT32 mrings = 0; INT32 i; @@ -484,10 +562,10 @@ UINT8 M_GotHighEnoughRings(INT32 trings) { if (!mapheaderinfo[i] || !(mapheaderinfo[i]->menuflags & LF2_RECORDATTACK)) continue; - if (!mainrecords[i]) + if (!data->mainrecords[i]) continue; - if ((mrings += mainrecords[i]->rings) > trings) + if ((mrings += data->mainrecords[i]->rings) > trings) return true; } return false; diff --git a/src/m_cond.h b/src/m_cond.h index d49dc920b..6a3da79ec 100644 --- a/src/m_cond.h +++ b/src/m_cond.h @@ -10,7 +10,11 @@ /// \file m_cond.h /// \brief Unlockable condition system for SRB2 version 2.1 +#ifndef __M_COND__ +#define __M_COND__ + #include "doomdef.h" +#include "doomdata.h" // -------- // Typedefs @@ -61,8 +65,6 @@ typedef struct { UINT32 numconditions; /// <- number of conditions. condition_t *condition; /// <- All conditionals to be checked. - UINT8 achieved; /// <- Whether this conditional has been achieved already or not. - /// (Conditional checking is skipped if true -- it's assumed you can't relock an unlockable) } conditionset_t; // Emblem information @@ -94,7 +96,6 @@ typedef struct 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; typedef struct { @@ -104,7 +105,6 @@ typedef struct UINT8 showconditionset; ///< Condition set that shows this emblem. UINT8 sprite; ///< emblem sprite to use, 0 - 25 UINT16 color; ///< skincolor to use - UINT8 collected; ///< Do you have this emblem? } extraemblem_t; // Unlockable information @@ -120,7 +120,6 @@ typedef struct char *stringVar; UINT8 nocecho; UINT8 nochecklist; - UINT8 unlocked; } unlockable_t; #define SECRET_NONE -6 // Does nil. Use with levels locked by UnlockRequired @@ -143,6 +142,83 @@ typedef struct #define MAXEXTRAEMBLEMS 16 #define MAXUNLOCKABLES 32 +/** Time attack information, currently a very small structure. + */ +typedef struct +{ + tic_t time; ///< Time in which the level was finished. + UINT32 score; ///< Score when the level was finished. + UINT16 rings; ///< Rings when the level was finished. +} recorddata_t; + +/** Setup for one NiGHTS map. + * These are dynamically allocated because I am insane + */ +#define GRADE_F 0 +#define GRADE_E 1 +#define GRADE_D 2 +#define GRADE_C 3 +#define GRADE_B 4 +#define GRADE_A 5 +#define GRADE_S 6 + +typedef struct +{ + // 8 mares, 1 overall (0) + UINT8 nummares; + UINT32 score[9]; + UINT8 grade[9]; + tic_t time[9]; +} nightsdata_t; + +// mapvisited is now a set of flags that says what we've done in the map. +#define MV_VISITED 1 +#define MV_BEATEN 2 +#define MV_ALLEMERALDS 4 +#define MV_ULTIMATE 8 +#define MV_PERFECT 16 +#define MV_PERFECTRA 32 +#define MV_MAX 63 // used in gamedata check, update whenever MV's are added + +// Temporary holding place for nights data for the current map +extern nightsdata_t ntemprecords; + +// GAMEDATA STRUCTURE +// Everything that would get saved in gamedata.dat +typedef struct +{ + // WHENEVER OR NOT WE'RE READY TO SAVE + boolean loaded; + + // CONDITION SETS ACHIEVED + boolean achieved[MAXCONDITIONSETS]; + + // EMBLEMS COLLECTED + boolean collected[MAXEMBLEMS]; + + // EXTRA EMBLEMS COLLECTED + boolean extraCollected[MAXEXTRAEMBLEMS]; + + // UNLOCKABLES UNLOCKED + boolean unlocked[MAXUNLOCKABLES]; + + // TIME ATTACK DATA + recorddata_t *mainrecords[NUMMAPS]; + nightsdata_t *nightsrecords[NUMMAPS]; + UINT8 mapvisited[NUMMAPS]; + + // # OF TIMES THE GAME HAS BEEN BEATEN + UINT32 timesBeaten; + UINT32 timesBeatenWithEmeralds; + UINT32 timesBeatenUltimate; + + // PLAY TIME + UINT32 totalplaytime; +} gamedata_t; + +extern gamedata_t *clientGamedata; +extern gamedata_t *serverGamedata; + extern conditionset_t conditionSets[MAXCONDITIONSETS]; extern emblem_t emblemlocations[MAXEMBLEMS]; extern extraemblem_t extraemblems[MAXEXTRAEMBLEMS]; @@ -153,25 +229,30 @@ extern INT32 numextraemblems; extern UINT32 unlocktriggers; +gamedata_t *M_NewGameDataStruct(void); +void M_CopyGameData(gamedata_t *dest, gamedata_t *src); + // Condition set setup void M_AddRawCondition(UINT8 set, UINT8 id, conditiontype_t c, INT32 r, INT16 x1, INT16 x2); // Clearing secrets void M_ClearConditionSet(UINT8 set); -void M_ClearSecrets(void); +void M_ClearSecrets(gamedata_t *data); // Updating conditions and unlockables -void M_CheckUnlockConditions(void); -UINT8 M_UpdateUnlockablesAndExtraEmblems(void); -void M_SilentUpdateUnlockablesAndEmblems(void); -UINT8 M_CheckLevelEmblems(void); -UINT8 M_CompletionEmblems(void); +void M_CheckUnlockConditions(gamedata_t *data); +UINT8 M_UpdateUnlockablesAndExtraEmblems(gamedata_t *data); +void M_SilentUpdateUnlockablesAndEmblems(gamedata_t *data); +UINT8 M_CheckLevelEmblems(gamedata_t *data); +UINT8 M_CompletionEmblems(gamedata_t *data); + +void M_SilentUpdateSkinAvailabilites(void); // Checking unlockable status -UINT8 M_AnySecretUnlocked(void); -UINT8 M_SecretUnlocked(INT32 type); -UINT8 M_MapLocked(INT32 mapnum); -INT32 M_CountEmblems(void); +UINT8 M_AnySecretUnlocked(gamedata_t *data); +UINT8 M_SecretUnlocked(INT32 type, gamedata_t *data); +UINT8 M_MapLocked(INT32 mapnum, gamedata_t *data); +INT32 M_CountEmblems(gamedata_t *data); // Emblem shit emblem_t *M_GetLevelEmblems(INT32 mapnum); @@ -183,12 +264,14 @@ const char *M_GetExtraEmblemPatch(extraemblem_t *em, boolean big); // If you're looking to compare stats for unlocks or what not, use these // They stop checking upon reaching the target number so they // should be (theoretically?) slightly faster. -UINT8 M_GotEnoughEmblems(INT32 number); -UINT8 M_GotHighEnoughScore(INT32 tscore); -UINT8 M_GotLowEnoughTime(INT32 tictime); -UINT8 M_GotHighEnoughRings(INT32 trings); +UINT8 M_GotEnoughEmblems(INT32 number, gamedata_t *data); +UINT8 M_GotHighEnoughScore(INT32 tscore, gamedata_t *data); +UINT8 M_GotLowEnoughTime(INT32 tictime, gamedata_t *data); +UINT8 M_GotHighEnoughRings(INT32 trings, gamedata_t *data); INT32 M_UnlockableSkinNum(unlockable_t *unlock); INT32 M_EmblemSkinNum(emblem_t *emblem); -#define M_Achieved(a) ((a) >= MAXCONDITIONSETS || conditionSets[a].achieved) +#define M_Achieved(a, data) ((a) >= MAXCONDITIONSETS || data->achieved[a]) + +#endif diff --git a/src/m_menu.c b/src/m_menu.c index 64a1c9404..2214e6a6a 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -2284,6 +2284,7 @@ static boolean M_CanShowLevelOnPlatter(INT32 mapnum, INT32 gt); // Nextmap. Used for Level select. void Nextmap_OnChange(void) { + gamedata_t *data = clientGamedata; char *leveltitle; char tabase[256]; #ifdef OLDNREPLAYNAME @@ -2301,7 +2302,7 @@ void Nextmap_OnChange(void) { CV_StealthSetValue(&cv_dummymares, 0); // Hide the record changing CVAR if only one mare is available. - if (!nightsrecords[cv_nextmap.value-1] || nightsrecords[cv_nextmap.value-1]->nummares < 2) + if (!data->nightsrecords[cv_nextmap.value-1] || data->nightsrecords[cv_nextmap.value-1]->nummares < 2) SP_NightsAttackMenu[narecords].status = IT_DISABLED; else SP_NightsAttackMenu[narecords].status = IT_STRING|IT_CVAR; @@ -2432,14 +2433,15 @@ void Nextmap_OnChange(void) static void Dummymares_OnChange(void) { - if (!nightsrecords[cv_nextmap.value-1]) + gamedata_t *data = clientGamedata; + if (!data->nightsrecords[cv_nextmap.value-1]) { CV_StealthSetValue(&cv_dummymares, 0); return; } else { - UINT8 mares = nightsrecords[cv_nextmap.value-1]->nummares; + UINT8 mares = data->nightsrecords[cv_nextmap.value-1]->nummares; if (cv_dummymares.value < 0) CV_StealthSetValue(&cv_dummymares, mares); @@ -3670,9 +3672,9 @@ void M_StartControlPanel(void) if (!Playing()) { // Secret menu! - MainMenu[singleplr].alphaKey = (M_AnySecretUnlocked()) ? 76 : 84; - MainMenu[multiplr].alphaKey = (M_AnySecretUnlocked()) ? 84 : 92; - MainMenu[secrets].status = (M_AnySecretUnlocked()) ? (IT_STRING | IT_CALL) : (IT_DISABLED); + MainMenu[singleplr].alphaKey = (M_AnySecretUnlocked(clientGamedata)) ? 76 : 84; + MainMenu[multiplr].alphaKey = (M_AnySecretUnlocked(clientGamedata)) ? 84 : 92; + MainMenu[secrets].status = (M_AnySecretUnlocked(clientGamedata)) ? (IT_STRING | IT_CALL) : (IT_DISABLED); currentMenu = &MainDef; itemOn = singleplr; @@ -3680,14 +3682,14 @@ void M_StartControlPanel(void) else if (modeattacking) { currentMenu = &MAPauseDef; - MAPauseMenu[mapause_hints].status = (M_SecretUnlocked(SECRET_EMBLEMHINTS)) ? (IT_STRING | IT_CALL) : (IT_DISABLED); + MAPauseMenu[mapause_hints].status = (M_SecretUnlocked(SECRET_EMBLEMHINTS, clientGamedata)) ? (IT_STRING | IT_CALL) : (IT_DISABLED); itemOn = mapause_continue; } else if (!(netgame || multiplayer)) // Single Player { if (gamestate != GS_LEVEL || ultimatemode) // intermission, so gray out stuff. { - SPauseMenu[spause_pandora].status = (M_SecretUnlocked(SECRET_PANDORA)) ? (IT_GRAYEDOUT) : (IT_DISABLED); + SPauseMenu[spause_pandora].status = (M_SecretUnlocked(SECRET_PANDORA, serverGamedata)) ? (IT_GRAYEDOUT) : (IT_DISABLED); SPauseMenu[spause_retry].status = IT_GRAYEDOUT; } else @@ -3696,7 +3698,7 @@ void M_StartControlPanel(void) if (players[consoleplayer].playerstate != PST_LIVE) ++numlives; - SPauseMenu[spause_pandora].status = (M_SecretUnlocked(SECRET_PANDORA) && !marathonmode) ? (IT_STRING | IT_CALL) : (IT_DISABLED); + SPauseMenu[spause_pandora].status = (M_SecretUnlocked(SECRET_PANDORA, serverGamedata) && !marathonmode) ? (IT_STRING | IT_CALL) : (IT_DISABLED); // The list of things that can disable retrying is (was?) a little too complex // for me to want to use the short if statement syntax @@ -3710,7 +3712,7 @@ void M_StartControlPanel(void) SPauseMenu[spause_levelselect].status = (gamecomplete == 1) ? (IT_STRING | IT_CALL) : (IT_DISABLED); // And emblem hints. - SPauseMenu[spause_hints].status = (M_SecretUnlocked(SECRET_EMBLEMHINTS) && !marathonmode) ? (IT_STRING | IT_CALL) : (IT_DISABLED); + SPauseMenu[spause_hints].status = (M_SecretUnlocked(SECRET_EMBLEMHINTS, clientGamedata) && !marathonmode) ? (IT_STRING | IT_CALL) : (IT_DISABLED); // Shift up Pandora's Box if both pandora and levelselect are active /*if (SPauseMenu[spause_pandora].status != (IT_DISABLED) @@ -4259,7 +4261,7 @@ static void M_DrawMapEmblems(INT32 mapnum, INT32 x, INT32 y, boolean norecordatt x -= 4; lasttype = curtype; - if (emblem->collected) + if (clientGamedata->collected[emblem - emblemlocations]) V_DrawSmallMappedPatch(x, y, 0, W_CachePatchName(M_GetEmblemPatch(emblem, false), PU_PATCH), R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(emblem), GTC_CACHE)); else @@ -4692,6 +4694,8 @@ static void M_DrawGenericScrollMenu(void) static void M_DrawPauseMenu(void) { + gamedata_t *data = clientGamedata; + if (!netgame && !multiplayer && (gamestate == GS_LEVEL || gamestate == GS_INTERMISSION)) { emblem_t *emblem_detail[3] = {NULL, NULL, NULL}; @@ -4720,7 +4724,7 @@ static void M_DrawPauseMenu(void) { case ET_SCORE: snprintf(targettext, 9, "%d", emblem->var); - snprintf(currenttext, 9, "%u", G_GetBestScore(gamemap)); + snprintf(currenttext, 9, "%u", G_GetBestScore(gamemap, data)); targettext[8] = 0; currenttext[8] = 0; @@ -4734,7 +4738,7 @@ static void M_DrawPauseMenu(void) G_TicsToSeconds((tic_t)emblemslot), G_TicsToCentiseconds((tic_t)emblemslot)); - emblemslot = (INT32)G_GetBestTime(gamemap); // dumb hack pt ii + emblemslot = (INT32)G_GetBestTime(gamemap, data); // dumb hack pt ii if ((tic_t)emblemslot == UINT32_MAX) snprintf(currenttext, 9, "-:--.--"); else @@ -4750,7 +4754,7 @@ static void M_DrawPauseMenu(void) break; case ET_RINGS: snprintf(targettext, 9, "%d", emblem->var); - snprintf(currenttext, 9, "%u", G_GetBestRings(gamemap)); + snprintf(currenttext, 9, "%u", G_GetBestRings(gamemap, data)); targettext[8] = 0; currenttext[8] = 0; @@ -4758,8 +4762,8 @@ static void M_DrawPauseMenu(void) emblemslot = 2; break; case ET_NGRADE: - snprintf(targettext, 9, "%u", P_GetScoreForGradeOverall(gamemap, emblem->var)); - snprintf(currenttext, 9, "%u", G_GetBestNightsScore(gamemap, 0)); + snprintf(targettext, 9, "%u", P_GetScoreForGrade(gamemap, 0, emblem->var)); + snprintf(currenttext, 9, "%u", G_GetBestNightsScore(gamemap, 0, data)); targettext[8] = 0; currenttext[8] = 0; @@ -4773,7 +4777,7 @@ static void M_DrawPauseMenu(void) G_TicsToSeconds((tic_t)emblemslot), G_TicsToCentiseconds((tic_t)emblemslot)); - emblemslot = (INT32)G_GetBestNightsTime(gamemap, 0); // dumb hack pt iv + emblemslot = (INT32)G_GetBestNightsTime(gamemap, 0, data); // dumb hack pt iv if ((tic_t)emblemslot == UINT32_MAX) snprintf(currenttext, 9, "-:--.--"); else @@ -4807,7 +4811,7 @@ static void M_DrawPauseMenu(void) if (!emblem) continue; - if (emblem->collected) + if (data->collected[emblem - emblemlocations]) V_DrawSmallMappedPatch(40, 44 + (i*8), 0, W_CachePatchName(M_GetEmblemPatch(emblem, false), PU_PATCH), R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(emblem), GTC_CACHE)); else @@ -5019,7 +5023,9 @@ static void M_PatchSkinNameTable(void) // static boolean M_LevelAvailableOnPlatter(INT32 mapnum) { - if (M_MapLocked(mapnum+1)) + gamedata_t *data = serverGamedata; + + if (M_MapLocked(mapnum+1, data)) return false; // not unlocked switch (levellistmode) @@ -5032,7 +5038,7 @@ static boolean M_LevelAvailableOnPlatter(INT32 mapnum) return true; #ifndef DEVELOP - if (mapvisited[mapnum]) // MV_MP + if (data->mapvisited[mapnum]) #endif return true; @@ -5040,7 +5046,7 @@ static boolean M_LevelAvailableOnPlatter(INT32 mapnum) case LLM_RECORDATTACK: case LLM_NIGHTSATTACK: #ifndef DEVELOP - if (mapvisited[mapnum] & MV_MAX) + if (data->mapvisited[mapnum]) return true; if (mapheaderinfo[mapnum]->menuflags & LF2_NOVISITNEEDED) @@ -5071,7 +5077,7 @@ static boolean M_CanShowLevelOnPlatter(INT32 mapnum, INT32 gt) if (!mapheaderinfo[mapnum]->lvlttl[0]) return false; - /*if (M_MapLocked(mapnum+1)) + /*if (M_MapLocked(mapnum+1, serverGamedata)) return false; // not unlocked*/ switch (levellistmode) @@ -6904,7 +6910,7 @@ static void M_HandleAddons(INT32 choice) closefilemenu(true); // secrets disabled by addfile... - MainMenu[secrets].status = (M_AnySecretUnlocked()) ? (IT_STRING | IT_CALL) : (IT_DISABLED); + MainMenu[secrets].status = (M_AnySecretUnlocked(clientGamedata)) ? (IT_STRING | IT_CALL) : (IT_DISABLED); if (currentMenu->prevMenu) M_SetupNextMenu(currentMenu->prevMenu); @@ -7150,7 +7156,9 @@ static boolean checklist_cangodown; // uuuueeerggghhhh HACK static void M_HandleChecklist(INT32 choice) { + gamedata_t *data = clientGamedata; INT32 j; + switch (choice) { case KEY_DOWNARROW: @@ -7167,7 +7175,7 @@ static void M_HandleChecklist(INT32 choice) continue; if (unlockables[j].conditionset > MAXCONDITIONSETS) continue; - if (!unlockables[j].unlocked && unlockables[j].showconditionset && !M_Achieved(unlockables[j].showconditionset)) + if (!data->unlocked[j] && unlockables[j].showconditionset && !M_Achieved(unlockables[j].showconditionset, data)) continue; if (unlockables[j].conditionset == unlockables[check_on].conditionset) continue; @@ -7192,7 +7200,7 @@ static void M_HandleChecklist(INT32 choice) continue; if (unlockables[j].conditionset > MAXCONDITIONSETS) continue; - if (!unlockables[j].unlocked && unlockables[j].showconditionset && !M_Achieved(unlockables[j].showconditionset)) + if (!data->unlocked[j] && unlockables[j].showconditionset && !M_Achieved(unlockables[j].showconditionset, data)) continue; if (j && unlockables[j].conditionset == unlockables[j-1].conditionset) continue; @@ -7218,6 +7226,9 @@ static void M_HandleChecklist(INT32 choice) static void M_DrawChecklist(void) { + gamedata_t *data = clientGamedata; + INT32 emblemCount = M_CountEmblems(data); + INT32 i = check_on, j = 0, y = currentMenu->y, emblems = numemblems+numextraemblems; UINT32 condnum, previd, maxcond; condition_t *cond; @@ -7228,7 +7239,7 @@ static void M_DrawChecklist(void) // draw emblem counter if (emblems > 0) { - V_DrawString(42, 20, (emblems == M_CountEmblems()) ? V_GREENMAP : 0, va("%d/%d", M_CountEmblems(), emblems)); + V_DrawString(42, 20, (emblems == emblemCount) ? V_GREENMAP : 0, va("%d/%d", emblemCount, emblems)); V_DrawSmallScaledPatch(28, 20, 0, W_CachePatchName("EMBLICON", PU_PATCH)); } @@ -7239,13 +7250,13 @@ static void M_DrawChecklist(void) { if (unlockables[i].name[0] == 0 //|| unlockables[i].nochecklist || !unlockables[i].conditionset || unlockables[i].conditionset > MAXCONDITIONSETS - || (!unlockables[i].unlocked && unlockables[i].showconditionset && !M_Achieved(unlockables[i].showconditionset))) + || (!data->unlocked[i] && unlockables[i].showconditionset && !M_Achieved(unlockables[i].showconditionset, data))) { i += 1; continue; } - V_DrawString(currentMenu->x, y, ((unlockables[i].unlocked) ? V_GREENMAP : V_TRANSLUCENT)|V_ALLOWLOWERCASE, ((unlockables[i].unlocked || !unlockables[i].nochecklist) ? unlockables[i].name : M_CreateSecretMenuOption(unlockables[i].name))); + V_DrawString(currentMenu->x, y, ((data->unlocked[i]) ? V_GREENMAP : V_TRANSLUCENT)|V_ALLOWLOWERCASE, ((data->unlocked[i] || !unlockables[i].nochecklist) ? unlockables[i].name : M_CreateSecretMenuOption(unlockables[i].name))); for (j = i+1; j < MAXUNLOCKABLES; j++) { @@ -7323,7 +7334,7 @@ static void M_DrawChecklist(void) if (title) { - const char *level = ((M_MapLocked(cond[condnum].requirement) || !((mapheaderinfo[cond[condnum].requirement-1]->menuflags & LF2_NOVISITNEEDED) || (mapvisited[cond[condnum].requirement-1] & MV_MAX))) ? M_CreateSecretMenuOption(title) : title); + const char *level = ((M_MapLocked(cond[condnum].requirement, data) || !((mapheaderinfo[cond[condnum].requirement-1]->menuflags & LF2_NOVISITNEEDED) || (data->mapvisited[cond[condnum].requirement-1] & MV_MAX))) ? M_CreateSecretMenuOption(title) : title); switch (cond[condnum].type) { @@ -7356,7 +7367,7 @@ static void M_DrawChecklist(void) if (title) { - const char *level = ((M_MapLocked(cond[condnum].extrainfo1) || !((mapheaderinfo[cond[condnum].extrainfo1-1]->menuflags & LF2_NOVISITNEEDED) || (mapvisited[cond[condnum].extrainfo1-1] & MV_MAX))) ? M_CreateSecretMenuOption(title) : title); + const char *level = ((M_MapLocked(cond[condnum].extrainfo1, data) || !((mapheaderinfo[cond[condnum].extrainfo1-1]->menuflags & LF2_NOVISITNEEDED) || (data->mapvisited[cond[condnum].extrainfo1-1] & MV_MAX))) ? M_CreateSecretMenuOption(title) : title); switch (cond[condnum].type) { @@ -7425,7 +7436,7 @@ static void M_DrawChecklist(void) if (title) { - const char *level = ((M_MapLocked(cond[condnum].extrainfo1) || !((mapheaderinfo[cond[condnum].extrainfo1-1]->menuflags & LF2_NOVISITNEEDED) || (mapvisited[cond[condnum].extrainfo1-1] & MV_MAX))) ? M_CreateSecretMenuOption(title) : title); + const char *level = ((M_MapLocked(cond[condnum].extrainfo1, data) || !((mapheaderinfo[cond[condnum].extrainfo1-1]->menuflags & LF2_NOVISITNEEDED) || (data->mapvisited[cond[condnum].extrainfo1-1] & MV_MAX))) ? M_CreateSecretMenuOption(title) : title); switch (cond[condnum].type) { @@ -7488,7 +7499,7 @@ static void M_DrawChecklist(void) /*V_DrawString(160, 8+(24*j), V_RETURN8, V_WordWrap(160, 292, 0, unlockables[i].objective)); - if (unlockables[i].unlocked) + if (data->unlocked[i]) V_DrawString(308, 8+(24*j), V_YELLOWMAP, "Y"); else V_DrawString(308, 8+(24*j), V_YELLOWMAP, "N");*/ @@ -7517,7 +7528,7 @@ static void M_EmblemHints(INT32 choice) (void)choice; SR_EmblemHintMenu[0].status = (local > NUMHINTS*2) ? (IT_STRING | IT_ARROWS) : (IT_DISABLED); - SR_EmblemHintMenu[1].status = (M_SecretUnlocked(SECRET_ITEMFINDER)) ? (IT_CVAR|IT_STRING) : (IT_SECRET); + SR_EmblemHintMenu[1].status = (M_SecretUnlocked(SECRET_ITEMFINDER, clientGamedata)) ? (IT_CVAR|IT_STRING) : (IT_SECRET); hintpage = 1; SR_EmblemHintDef.prevMenu = currentMenu; M_SetupNextMenu(&SR_EmblemHintDef); @@ -7577,7 +7588,7 @@ static void M_DrawEmblemHints(void) if (totalemblems >= ((hintpage-1)*(NUMHINTS*2) + 1) && totalemblems < (hintpage*NUMHINTS*2)+1){ - if (emblem->collected) + if (clientGamedata->collected[i]) { collected = V_GREENMAP; V_DrawMappedPatch(x, y+4, 0, W_CachePatchName(M_GetEmblemPatch(emblem, false), PU_PATCH), @@ -8117,7 +8128,7 @@ static void M_SecretsMenu(INT32 choice) SR_MainMenu[i].status = IT_SECRET; - if (unlockables[ul].unlocked) + if (clientGamedata->unlocked[ul]) { switch (unlockables[ul].type) { @@ -8216,7 +8227,7 @@ static void M_SinglePlayerMenu(INT32 choice) levellistmode = LLM_RECORDATTACK; if (M_GametypeHasLevels(-1)) - SP_MainMenu[sprecordattack].status = (M_SecretUnlocked(SECRET_RECORDATTACK)) ? IT_CALL|IT_STRING : IT_SECRET; + SP_MainMenu[sprecordattack].status = (M_SecretUnlocked(SECRET_RECORDATTACK, clientGamedata)) ? IT_CALL|IT_STRING : IT_SECRET; else // If Record Attack is nonexistent in the current add-on... { SP_MainMenu[sprecordattack].status = IT_NOTHING|IT_DISABLED; // ...hide and disable the Record Attack option... @@ -8226,7 +8237,7 @@ static void M_SinglePlayerMenu(INT32 choice) levellistmode = LLM_NIGHTSATTACK; if (M_GametypeHasLevels(-1)) - SP_MainMenu[spnightsmode].status = (M_SecretUnlocked(SECRET_NIGHTSMODE)) ? IT_CALL|IT_STRING : IT_SECRET; + SP_MainMenu[spnightsmode].status = (M_SecretUnlocked(SECRET_NIGHTSMODE, clientGamedata)) ? IT_CALL|IT_STRING : IT_SECRET; else // If NiGHTS Mode is nonexistent in the current add-on... { SP_MainMenu[spnightsmode].status = IT_NOTHING|IT_DISABLED; // ...hide and disable the NiGHTS Mode option... @@ -8249,7 +8260,7 @@ static void M_SinglePlayerMenu(INT32 choice) SP_MainMenu[spnightsmode] .alphaKey += 8; } else // Otherwise, if Marathon Run is allowed and Record Attack is unlocked, unlock Marathon Run! - SP_MainMenu[spmarathon].status = (M_SecretUnlocked(SECRET_RECORDATTACK)) ? IT_CALL|IT_STRING|IT_CALL_NOTMODIFIED : IT_SECRET; + SP_MainMenu[spmarathon].status = (M_SecretUnlocked(SECRET_RECORDATTACK, clientGamedata)) ? IT_CALL|IT_STRING|IT_CALL_NOTMODIFIED : IT_SECRET; if (tutorialmap) // If there's a tutorial available in the current add-on... @@ -9626,7 +9637,7 @@ static void M_Statistics(INT32 choice) if (!(mapheaderinfo[i]->typeoflevel & TOL_SP) || (mapheaderinfo[i]->menuflags & LF2_HIDEINSTATS)) continue; - if (!(mapvisited[i] & MV_MAX)) + if (!(clientGamedata->mapvisited[i] & MV_MAX)) continue; statsMapList[j++] = i; @@ -9643,6 +9654,7 @@ static void M_Statistics(INT32 choice) static void M_DrawStatsMaps(int location) { + gamedata_t *data = clientGamedata; INT32 y = 80, i = -1; INT16 mnum; extraemblem_t *exemblem; @@ -9710,14 +9722,14 @@ static void M_DrawStatsMaps(int location) { exemblem = &extraemblems[i]; - if (exemblem->collected) + if (data->extraCollected[i]) V_DrawSmallMappedPatch(292, y, 0, W_CachePatchName(M_GetExtraEmblemPatch(exemblem, false), PU_PATCH), R_GetTranslationColormap(TC_DEFAULT, M_GetExtraEmblemColor(exemblem), GTC_CACHE)); else V_DrawSmallScaledPatch(292, y, 0, W_CachePatchName("NEEDIT", PU_PATCH)); V_DrawString(20, y, V_YELLOWMAP|V_ALLOWLOWERCASE, - (!exemblem->collected && exemblem->showconditionset && !M_Achieved(exemblem->showconditionset)) + (!data->extraCollected[i] && exemblem->showconditionset && !M_Achieved(exemblem->showconditionset, data)) ? M_CreateSecretMenuOption(exemblem->description) : exemblem->description); } @@ -9734,6 +9746,7 @@ bottomarrow: static void M_DrawLevelStats(void) { + gamedata_t *data = clientGamedata; char beststr[40]; tic_t besttime = 0; @@ -9748,9 +9761,9 @@ static void M_DrawLevelStats(void) V_DrawString(20, 24, V_YELLOWMAP, "Total Play Time:"); V_DrawCenteredString(BASEVIDWIDTH/2, 32, 0, va("%i hours, %i minutes, %i seconds", - G_TicsToHours(totalplaytime), - G_TicsToMinutes(totalplaytime, false), - G_TicsToSeconds(totalplaytime))); + G_TicsToHours(data->totalplaytime), + G_TicsToMinutes(data->totalplaytime, false), + G_TicsToSeconds(data->totalplaytime))); for (i = 0; i < NUMMAPS; i++) { @@ -9759,25 +9772,25 @@ static void M_DrawLevelStats(void) if (!mapheaderinfo[i] || !(mapheaderinfo[i]->menuflags & LF2_RECORDATTACK)) continue; - if (!mainrecords[i]) + if (!data->mainrecords[i]) { mapsunfinished++; bestunfinished[0] = bestunfinished[1] = bestunfinished[2] = true; continue; } - if (mainrecords[i]->score > 0) - bestscore += mainrecords[i]->score; + if (data->mainrecords[i]->score > 0) + bestscore += data->mainrecords[i]->score; else mapunfinished = bestunfinished[0] = true; - if (mainrecords[i]->time > 0) - besttime += mainrecords[i]->time; + if (data->mainrecords[i]->time > 0) + besttime += data->mainrecords[i]->time; else mapunfinished = bestunfinished[1] = true; - if (mainrecords[i]->rings > 0) - bestrings += mainrecords[i]->rings; + if (data->mainrecords[i]->rings > 0) + bestrings += data->mainrecords[i]->rings; else mapunfinished = bestunfinished[2] = true; @@ -9792,7 +9805,7 @@ static void M_DrawLevelStats(void) else V_DrawString(20, 56, V_GREENMAP, "(complete)"); - V_DrawString(36, 64, 0, va("x %d/%d", M_CountEmblems(), numemblems+numextraemblems)); + V_DrawString(36, 64, 0, va("x %d/%d", M_CountEmblems(data), numemblems+numextraemblems)); V_DrawSmallScaledPatch(20, 64, 0, W_CachePatchName("EMBLICON", PU_PATCH)); sprintf(beststr, "%u", bestscore); @@ -9859,6 +9872,7 @@ static void M_HandleLevelStats(INT32 choice) // Drawing function for Time Attack void M_DrawTimeAttackMenu(void) { + gamedata_t *data = clientGamedata; INT32 i, x, y, empatx, empaty, cursory = 0; UINT16 dispstatus; patch_t *PictureOfUrFace; // my WHAT @@ -10017,7 +10031,7 @@ void M_DrawTimeAttackMenu(void) empatx = empatch->leftoffset / 2; empaty = empatch->topoffset / 2; - if (em->collected) + if (data->collected[em - emblemlocations]) V_DrawSmallMappedPatch(104+76+empatx, yHeight+lsheadingheight/2+empaty, 0, empatch, R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(em), GTC_CACHE)); else @@ -10030,34 +10044,34 @@ void M_DrawTimeAttackMenu(void) // Draw in-level emblems. M_DrawMapEmblems(cv_nextmap.value, 288, 28, true); - if (!mainrecords[cv_nextmap.value-1] || !mainrecords[cv_nextmap.value-1]->score) + if (!data->mainrecords[cv_nextmap.value-1] || !data->mainrecords[cv_nextmap.value-1]->score) sprintf(beststr, "(none)"); else - sprintf(beststr, "%u", mainrecords[cv_nextmap.value-1]->score); + sprintf(beststr, "%u", data->mainrecords[cv_nextmap.value-1]->score); V_DrawString(104-72, 33+lsheadingheight/2, V_YELLOWMAP, "SCORE:"); V_DrawRightAlignedString(104+64, 33+lsheadingheight/2, V_ALLOWLOWERCASE, beststr); V_DrawRightAlignedString(104+72, 43+lsheadingheight/2, V_ALLOWLOWERCASE, reqscore); - if (!mainrecords[cv_nextmap.value-1] || !mainrecords[cv_nextmap.value-1]->time) + if (!data->mainrecords[cv_nextmap.value-1] || !data->mainrecords[cv_nextmap.value-1]->time) sprintf(beststr, "(none)"); else - sprintf(beststr, "%i:%02i.%02i", G_TicsToMinutes(mainrecords[cv_nextmap.value-1]->time, true), - G_TicsToSeconds(mainrecords[cv_nextmap.value-1]->time), - G_TicsToCentiseconds(mainrecords[cv_nextmap.value-1]->time)); + sprintf(beststr, "%i:%02i.%02i", G_TicsToMinutes(data->mainrecords[cv_nextmap.value-1]->time, true), + G_TicsToSeconds(data->mainrecords[cv_nextmap.value-1]->time), + G_TicsToCentiseconds(data->mainrecords[cv_nextmap.value-1]->time)); V_DrawString(104-72, 53+lsheadingheight/2, V_YELLOWMAP, "TIME:"); V_DrawRightAlignedString(104+64, 53+lsheadingheight/2, V_ALLOWLOWERCASE, beststr); V_DrawRightAlignedString(104+72, 63+lsheadingheight/2, V_ALLOWLOWERCASE, reqtime); - if (!mainrecords[cv_nextmap.value-1] || !mainrecords[cv_nextmap.value-1]->rings) + if (!data->mainrecords[cv_nextmap.value-1] || !data->mainrecords[cv_nextmap.value-1]->rings) sprintf(beststr, "(none)"); else - sprintf(beststr, "%hu", mainrecords[cv_nextmap.value-1]->rings); + sprintf(beststr, "%hu", data->mainrecords[cv_nextmap.value-1]->rings); V_DrawString(104-72, 73+lsheadingheight/2, V_YELLOWMAP, "RINGS:"); - V_DrawRightAlignedString(104+64, 73+lsheadingheight/2, V_ALLOWLOWERCASE|((mapvisited[cv_nextmap.value-1] & MV_PERFECTRA) ? V_YELLOWMAP : 0), beststr); + V_DrawRightAlignedString(104+64, 73+lsheadingheight/2, V_ALLOWLOWERCASE|((data->mapvisited[cv_nextmap.value-1] & MV_PERFECTRA) ? V_YELLOWMAP : 0), beststr); V_DrawRightAlignedString(104+72, 83+lsheadingheight/2, V_ALLOWLOWERCASE, reqrings); } @@ -10151,6 +10165,7 @@ static void M_TimeAttack(INT32 choice) // Drawing function for Nights Attack void M_DrawNightsAttackMenu(void) { + gamedata_t *data = clientGamedata; INT32 i, x, y, cursory = 0; UINT16 dispstatus; @@ -10217,10 +10232,10 @@ void M_DrawNightsAttackMenu(void) lumpnum_t lumpnum; char beststr[40]; - //UINT8 bestoverall = G_GetBestNightsGrade(cv_nextmap.value, 0); - UINT8 bestgrade = G_GetBestNightsGrade(cv_nextmap.value, cv_dummymares.value); - UINT32 bestscore = G_GetBestNightsScore(cv_nextmap.value, cv_dummymares.value); - tic_t besttime = G_GetBestNightsTime(cv_nextmap.value, cv_dummymares.value); + //UINT8 bestoverall = G_GetBestNightsGrade(cv_nextmap.value, 0, data); + UINT8 bestgrade = G_GetBestNightsGrade(cv_nextmap.value, cv_dummymares.value, data); + UINT32 bestscore = G_GetBestNightsScore(cv_nextmap.value, cv_dummymares.value, data); + tic_t besttime = G_GetBestNightsTime(cv_nextmap.value, cv_dummymares.value, data); M_DrawLevelPlatterHeader(32-lsheadingheight/2, cv_nextmap.string, true, false); @@ -10301,7 +10316,7 @@ void M_DrawNightsAttackMenu(void) goto skipThisOne; } - if (em->collected) + if (data->collected[em - emblemlocations]) V_DrawSmallMappedPatch(xpos, yHeight+lsheadingheight/2, 0, W_CachePatchName(M_GetEmblemPatch(em, false), PU_PATCH), R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(em), GTC_CACHE)); else @@ -12544,12 +12559,12 @@ static void M_EraseDataResponse(INT32 ch) // Delete the data if (erasecontext != 1) - G_ClearRecords(); + G_ClearRecords(clientGamedata); if (erasecontext != 0) - M_ClearSecrets(); + M_ClearSecrets(clientGamedata); if (erasecontext == 2) { - totalplaytime = 0; + clientGamedata->totalplaytime = 0; F_StartIntro(); } BwehHehHe(); diff --git a/src/m_random.c b/src/m_random.c index 3d0774a60..8b5138b9c 100644 --- a/src/m_random.c +++ b/src/m_random.c @@ -14,12 +14,11 @@ #include "doomdef.h" #include "doomtype.h" -#include "doomstat.h" // totalplaytime #include "m_random.h" #include "m_fixed.h" - +#include "m_cond.h" // totalplaytime // --------------------------- // RNG functions (not synched) @@ -252,5 +251,5 @@ void P_SetRandSeedD(const char *rfile, INT32 rline, UINT32 seed) */ UINT32 M_RandomizedSeed(void) { - return ((totalplaytime & 0xFFFF) << 16)|M_RandomFixed(); + return ((serverGamedata->totalplaytime & 0xFFFF) << 16) | M_RandomFixed(); } diff --git a/src/p_inter.c b/src/p_inter.c index 873448dcd..f2d20912f 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -740,10 +740,22 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) { if (demoplayback || (player->bot && player->bot != BOT_MPAI) || special->health <= 0 || special->health > MAXEMBLEMS) return; - emblemlocations[special->health-1].collected = true; - M_UpdateUnlockablesAndExtraEmblems(); - G_SaveGameData(); + if (emblemlocations[special->health-1].type == ET_SKIN) + { + INT32 skinnum = M_EmblemSkinNum(&emblemlocations[special->health-1]); + + if (player->skin != skinnum) + { + return; + } + } + + clientGamedata->collected[special->health-1] = serverGamedata->collected[special->health-1] = true; + + M_SilentUpdateUnlockablesAndEmblems(serverGamedata); + M_UpdateUnlockablesAndExtraEmblems(clientGamedata); + G_SaveGameData(clientGamedata); break; } diff --git a/src/p_mobj.c b/src/p_mobj.c index eeaf54776..6563e6f0a 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -12004,10 +12004,6 @@ static boolean P_AllowMobjSpawn(mapthing_t* mthing, mobjtype_t i) return false; // You already got this token break; - case MT_EMBLEM: - if (netgame || multiplayer) - return false; // Single player (You're next on my shit list) - break; default: break; } @@ -12175,15 +12171,20 @@ 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; - validEmblem = !emblemlocations[j].collected; + validEmblem = true; - if (emblemlocations[j].type == ET_SKIN) + if (!netgame) { - INT32 skinnum = M_EmblemSkinNum(&emblemlocations[j]); + validEmblem = !serverGamedata->collected[j]; - if (players[0].skin != skinnum) + if (emblemlocations[j].type == ET_SKIN && !multiplayer) { - validEmblem = false; + INT32 skinnum = M_EmblemSkinNum(&emblemlocations[j]); + + if (players[0].skin != skinnum) + { + validEmblem = false; + } } } diff --git a/src/p_saveg.c b/src/p_saveg.c index 8c8a78322..c18319c69 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -47,6 +47,7 @@ UINT8 *save_p; #define ARCHIVEBLOCK_POBJS 0x7F928546 #define ARCHIVEBLOCK_THINKERS 0x7F37037C #define ARCHIVEBLOCK_SPECIALS 0x7F228378 +#define ARCHIVEBLOCK_EMBLEMS 0x7F4A5445 // Note: This cannot be bigger // than an UINT16 @@ -4339,6 +4340,8 @@ static void P_NetArchiveMisc(boolean resending) WRITEUINT32(save_p, hidetime); + WRITEUINT32(save_p, unlocktriggers); + // Is it paused? if (paused) WRITEUINT8(save_p, 0x2f); @@ -4437,6 +4440,8 @@ static inline boolean P_NetUnArchiveMisc(boolean reloading) hidetime = READUINT32(save_p); + unlocktriggers = READUINT32(save_p); + // Is it paused? if (READUINT8(save_p) == 0x2f) paused = true; @@ -4444,6 +4449,224 @@ static inline boolean P_NetUnArchiveMisc(boolean reloading) return true; } + +static inline void P_NetArchiveEmblems(void) +{ + gamedata_t *data = serverGamedata; + INT32 i, j; + UINT8 btemp; + INT32 curmare; + + WRITEUINT32(save_p, ARCHIVEBLOCK_EMBLEMS); + + // These should be synchronized before savegame loading by the wad files being the same anyway, + // but just in case, for now, we'll leave them here for testing. It would be very bad if they mismatch. + WRITEUINT8(save_p, (UINT8)savemoddata); + WRITEINT32(save_p, numemblems); + WRITEINT32(save_p, numextraemblems); + + // The rest of this is lifted straight from G_SaveGameData in g_game.c + // TODO: Optimize this to only send information about emblems, unlocks, etc. which actually exist + // There is no need to go all the way up to MAXEMBLEMS when wads are guaranteed to be the same. + + WRITEUINT32(save_p, data->totalplaytime); + + // TODO put another cipher on these things? meh, I don't care... + for (i = 0; i < NUMMAPS; i++) + WRITEUINT8(save_p, (data->mapvisited[i] & MV_MAX)); + + // To save space, use one bit per collected/achieved/unlocked flag + for (i = 0; i < MAXEMBLEMS;) + { + btemp = 0; + for (j = 0; j < 8 && j+i < MAXEMBLEMS; ++j) + btemp |= (data->collected[j+i] << j); + WRITEUINT8(save_p, btemp); + i += j; + } + for (i = 0; i < MAXEXTRAEMBLEMS;) + { + btemp = 0; + for (j = 0; j < 8 && j+i < MAXEXTRAEMBLEMS; ++j) + btemp |= (data->extraCollected[j+i] << j); + WRITEUINT8(save_p, btemp); + i += j; + } + for (i = 0; i < MAXUNLOCKABLES;) + { + btemp = 0; + for (j = 0; j < 8 && j+i < MAXUNLOCKABLES; ++j) + btemp |= (data->unlocked[j+i] << j); + WRITEUINT8(save_p, btemp); + i += j; + } + for (i = 0; i < MAXCONDITIONSETS;) + { + btemp = 0; + for (j = 0; j < 8 && j+i < MAXCONDITIONSETS; ++j) + btemp |= (data->achieved[j+i] << j); + WRITEUINT8(save_p, btemp); + i += j; + } + + WRITEUINT32(save_p, data->timesBeaten); + WRITEUINT32(save_p, data->timesBeatenWithEmeralds); + WRITEUINT32(save_p, data->timesBeatenUltimate); + + // Main records + for (i = 0; i < NUMMAPS; i++) + { + if (data->mainrecords[i]) + { + WRITEUINT32(save_p, data->mainrecords[i]->score); + WRITEUINT32(save_p, data->mainrecords[i]->time); + WRITEUINT16(save_p, data->mainrecords[i]->rings); + } + else + { + WRITEUINT32(save_p, 0); + WRITEUINT32(save_p, 0); + WRITEUINT16(save_p, 0); + } + } + + // NiGHTS records + for (i = 0; i < NUMMAPS; i++) + { + if (!data->nightsrecords[i] || !data->nightsrecords[i]->nummares) + { + WRITEUINT8(save_p, 0); + continue; + } + + WRITEUINT8(save_p, data->nightsrecords[i]->nummares); + + for (curmare = 0; curmare < (data->nightsrecords[i]->nummares + 1); ++curmare) + { + WRITEUINT32(save_p, data->nightsrecords[i]->score[curmare]); + WRITEUINT8(save_p, data->nightsrecords[i]->grade[curmare]); + WRITEUINT32(save_p, data->nightsrecords[i]->time[curmare]); + } + } +} + +static inline void P_NetUnArchiveEmblems(void) +{ + gamedata_t *data = serverGamedata; + INT32 i, j; + UINT8 rtemp; + UINT32 recscore; + tic_t rectime; + UINT16 recrings; + UINT8 recmares; + INT32 curmare; + + if (READUINT32(save_p) != ARCHIVEBLOCK_EMBLEMS) + I_Error("Bad $$$.sav at archive block Emblems"); + + savemoddata = (boolean)READUINT8(save_p); // this one is actually necessary because savemoddata stays false otherwise for some reason. + + if (numemblems != READINT32(save_p)) + I_Error("numemblems mismatch"); + if (numextraemblems != READINT32(save_p)) + I_Error("numextraemblems mismatch"); + + // This shouldn't happen, but if something really fucked up happens and you transfer + // the SERVER player's gamedata over your own CLIENT gamedata, + // then this prevents it from being saved over yours. + data->loaded = false; + + M_ClearSecrets(data); + G_ClearRecords(data); + + // The rest of this is lifted straight from G_LoadGameData in g_game.c + // TODO: Optimize this to only read information about emblems, unlocks, etc. which actually exist + // There is no need to go all the way up to MAXEMBLEMS when wads are guaranteed to be the same. + + data->totalplaytime = READUINT32(save_p); + + // TODO put another cipher on these things? meh, I don't care... + for (i = 0; i < NUMMAPS; i++) + if ((data->mapvisited[i] = READUINT8(save_p)) > MV_MAX) + I_Error("Bad $$$.sav dearchiving Emblems"); + + // To save space, use one bit per collected/achieved/unlocked flag + for (i = 0; i < MAXEMBLEMS;) + { + rtemp = READUINT8(save_p); + for (j = 0; j < 8 && j+i < MAXEMBLEMS; ++j) + data->collected[j+i] = ((rtemp >> j) & 1); + i += j; + } + for (i = 0; i < MAXEXTRAEMBLEMS;) + { + rtemp = READUINT8(save_p); + for (j = 0; j < 8 && j+i < MAXEXTRAEMBLEMS; ++j) + data->extraCollected[j+i] = ((rtemp >> j) & 1); + i += j; + } + for (i = 0; i < MAXUNLOCKABLES;) + { + rtemp = READUINT8(save_p); + for (j = 0; j < 8 && j+i < MAXUNLOCKABLES; ++j) + data->unlocked[j+i] = ((rtemp >> j) & 1); + i += j; + } + for (i = 0; i < MAXCONDITIONSETS;) + { + rtemp = READUINT8(save_p); + for (j = 0; j < 8 && j+i < MAXCONDITIONSETS; ++j) + data->achieved[j+i] = ((rtemp >> j) & 1); + i += j; + } + + data->timesBeaten = READUINT32(save_p); + data->timesBeatenWithEmeralds = READUINT32(save_p); + data->timesBeatenUltimate = READUINT32(save_p); + + // Main records + for (i = 0; i < NUMMAPS; ++i) + { + recscore = READUINT32(save_p); + rectime = (tic_t)READUINT32(save_p); + recrings = READUINT16(save_p); + + if (recrings > 10000 || recscore > MAXSCORE) + I_Error("Bad $$$.sav dearchiving Emblems"); + + if (recscore || rectime || recrings) + { + G_AllocMainRecordData((INT16)i, data); + data->mainrecords[i]->score = recscore; + data->mainrecords[i]->time = rectime; + data->mainrecords[i]->rings = recrings; + } + } + + // Nights records + for (i = 0; i < NUMMAPS; ++i) + { + if ((recmares = READUINT8(save_p)) == 0) + continue; + + G_AllocNightsRecordData((INT16)i, data); + + for (curmare = 0; curmare < (recmares+1); ++curmare) + { + data->nightsrecords[i]->score[curmare] = READUINT32(save_p); + data->nightsrecords[i]->grade[curmare] = READUINT8(save_p); + data->nightsrecords[i]->time[curmare] = (tic_t)READUINT32(save_p); + + if (data->nightsrecords[i]->grade[curmare] > GRADE_S) + { + I_Error("Bad $$$.sav dearchiving Emblems"); + } + } + + data->nightsrecords[i]->nummares = recmares; + } +} + static inline void P_ArchiveLuabanksAndConsistency(void) { UINT8 i, banksinuse = NUM_LUABANKS; @@ -4507,6 +4730,7 @@ void P_SaveNetGame(boolean resending) CV_SaveNetVars(&save_p); P_NetArchiveMisc(resending); + P_NetArchiveEmblems(); // Assign the mobjnumber for pointer tracking for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) @@ -4559,6 +4783,7 @@ boolean P_LoadNetGame(boolean reloading) CV_LoadNetVars(&save_p); if (!P_NetUnArchiveMisc(reloading)) return false; + P_NetUnArchiveEmblems(); P_NetUnArchivePlayers(); if (gamestate == GS_LEVEL) { diff --git a/src/p_setup.c b/src/p_setup.c index c8b0936b8..70a2c0a8b 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -7460,7 +7460,7 @@ static void P_WriteLetter(void) { char *buf, *b; - if (!unlockables[28].unlocked) // pandora's box + if (!serverGamedata->unlocked[28]) // pandora's box return; if (modeattacking) @@ -7804,10 +7804,11 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate) nextmapoverride = 0; skipstats = 0; - if (!(netgame || multiplayer || demoplayback)) - mapvisited[gamemap-1] |= MV_VISITED; - else if (netgame || multiplayer) - mapvisited[gamemap-1] |= MV_MP; // you want to record that you've been there this session, but not permanently + if (!demoplayback) + { + clientGamedata->mapvisited[gamemap-1] |= MV_VISITED; + serverGamedata->mapvisited[gamemap-1] |= MV_VISITED; + } levelloading = false; diff --git a/src/p_spec.c b/src/p_spec.c index aa04a723e..48185e908 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -2937,7 +2937,6 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) break; case 441: // Trigger unlockable - if (!(netgame || multiplayer)) { INT32 trigid = line->args[0]; @@ -2948,10 +2947,12 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) unlocktriggers |= 1 << trigid; // Unlocked something? - if (M_UpdateUnlockablesAndExtraEmblems()) + M_SilentUpdateUnlockablesAndEmblems(serverGamedata); + + if (M_UpdateUnlockablesAndExtraEmblems(clientGamedata)) { S_StartSound(NULL, sfx_s3k68); - G_SaveGameData(); // only save if unlocked something + G_SaveGameData(clientGamedata); // only save if unlocked something } } } diff --git a/src/p_tick.c b/src/p_tick.c index 0357258e8..b1fd367ed 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -675,7 +675,10 @@ void P_Ticker(boolean run) // Keep track of how long they've been playing! if (!demoplayback) // Don't increment if a demo is playing. - totalplaytime++; + { + clientGamedata->totalplaytime++; + serverGamedata->totalplaytime++; + } if (!(maptol & TOL_NIGHTS) && G_IsSpecialStage(gamemap)) P_DoSpecialStageStuff(); diff --git a/src/r_skins.c b/src/r_skins.c index e59e085b8..2c031ee85 100644 --- a/src/r_skins.c +++ b/src/r_skins.c @@ -194,7 +194,7 @@ UINT32 R_GetSkinAvailabilities(void) return 0; } - if (unlockables[i].unlocked) + if (clientGamedata->unlocked[i]) { response |= (1 << unlockShift); } @@ -242,11 +242,12 @@ boolean R_SkinUsable(INT32 playernum, INT32 skinnum) // Force 3. return true; } + if (playernum != -1 && players[playernum].bot) - { - //Force 4. - return true; - } + { + // Force 4. + return true; + } // We will now check if this skin is supposed to be locked or not. @@ -284,7 +285,7 @@ boolean R_SkinUsable(INT32 playernum, INT32 skinnum) else { // We want to check our global unlockables. - return (unlockables[unlockID].unlocked); + return (clientGamedata->unlocked[unlockID]); } } diff --git a/src/s_sound.c b/src/s_sound.c index 111b6ce25..ada1a0fd2 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -1692,6 +1692,7 @@ UINT8 soundtestpage = 1; // boolean S_PrepareSoundTest(void) { + gamedata_t *data = clientGamedata; musicdef_t *def; INT32 pos = numsoundtestdefs = 0; @@ -1717,9 +1718,9 @@ boolean S_PrepareSoundTest(void) if (!(def->soundtestpage & soundtestpage)) continue; soundtestdefs[pos++] = def; - if (def->soundtestcond > 0 && !(mapvisited[def->soundtestcond-1] & MV_BEATEN)) + if (def->soundtestcond > 0 && !(data->mapvisited[def->soundtestcond-1] & MV_BEATEN)) continue; - if (def->soundtestcond < 0 && !M_Achieved(-1-def->soundtestcond)) + if (def->soundtestcond < 0 && !M_Achieved(-1-def->soundtestcond, data)) continue; def->allowed = true; } diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 67ee8d668..66eeffa30 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -2352,7 +2352,7 @@ void I_Quit(void) #ifndef NONET D_SaveBan(); // save the ban list #endif - G_SaveGameData(); // Tails 12-08-2002 + G_SaveGameData(clientGamedata); // Tails 12-08-2002 //added:16-02-98: when recording a demo, should exit using 'q' key, // but sometimes we forget and use 'F10'.. so save here too. @@ -2436,7 +2436,7 @@ void I_Error(const char *error, ...) if (errorcount == 8) { M_SaveConfig(NULL); - G_SaveGameData(); + G_SaveGameData(clientGamedata); } if (errorcount > 20) { @@ -2469,7 +2469,7 @@ void I_Error(const char *error, ...) #ifndef NONET D_SaveBan(); // save the ban list #endif - G_SaveGameData(); // Tails 12-08-2002 + G_SaveGameData(clientGamedata); // Tails 12-08-2002 // Shutdown. Here might be other errors. if (demorecording) diff --git a/src/st_stuff.c b/src/st_stuff.c index 206c93273..1f0ca277f 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1697,7 +1697,7 @@ static void ST_drawNightsRecords(void) ST_DrawNightsOverlayNum((BASEVIDWIDTH/2 + 56)<lastmarescore, nightsnum, SKINCOLOR_AZURE); // If new record, say so! - if (!(netgame || multiplayer) && G_GetBestNightsScore(gamemap, stplyr->lastmare + 1) <= stplyr->lastmarescore) + if (!(netgame || multiplayer) && G_GetBestNightsScore(gamemap, stplyr->lastmare + 1, clientGamedata) <= stplyr->lastmarescore) { if (stplyr->texttimer & 16) V_DrawCenteredString(BASEVIDWIDTH/2, 184, V_YELLOWMAP|aflag, "* NEW RECORD *"); @@ -2563,8 +2563,11 @@ static void ST_doItemFinderIconsAndSound(void) emblems[stemblems++] = i; - if (!emblemlocations[i].collected) + if (!(clientGamedata->collected[i] && serverGamedata->collected[i])) + { + // It can be worth collecting again if the server doesn't have it. ++stunfound; + } if (stemblems >= 16) break; @@ -2723,7 +2726,7 @@ static void ST_overlayDrawer(void) ST_drawRaceHUD(); // Emerald Hunt Indicators - if (cv_itemfinder.value && M_SecretUnlocked(SECRET_ITEMFINDER)) + if (cv_itemfinder.value && M_SecretUnlocked(SECRET_ITEMFINDER, clientGamedata)) ST_doItemFinderIconsAndSound(); else ST_doHuntIconsAndSound(); diff --git a/src/y_inter.c b/src/y_inter.c index 02d01233e..6e7d362a7 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -1092,12 +1092,14 @@ void Y_Ticker(void) S_StartSound(NULL, (gottoken ? sfx_token : sfx_chchng)); // cha-ching! // Update when done with tally - if (!(netgame || multiplayer) && !demoplayback) + if (!demoplayback) { - if (M_UpdateUnlockablesAndExtraEmblems()) + M_SilentUpdateUnlockablesAndEmblems(serverGamedata); + + if (M_UpdateUnlockablesAndExtraEmblems(clientGamedata)) S_StartSound(NULL, sfx_s3k68); - G_SaveGameData(); + G_SaveGameData(clientGamedata); } } else if (!(intertic & 1)) @@ -1228,12 +1230,14 @@ void Y_Ticker(void) S_StartSound(NULL, (gottoken ? sfx_token : sfx_chchng)); // cha-ching! // Update when done with tally - if (!(netgame || multiplayer) && !demoplayback) + if (!demoplayback) { - if (M_UpdateUnlockablesAndExtraEmblems()) + M_SilentUpdateUnlockablesAndEmblems(serverGamedata); + + if (M_UpdateUnlockablesAndExtraEmblems(clientGamedata)) S_StartSound(NULL, sfx_s3k68); - G_SaveGameData(); + G_SaveGameData(clientGamedata); } } else if (!(intertic & 1)) From 303d636f8e31358f63bb9b31ffef290fb74144b5 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 28 Feb 2022 10:58:18 -0500 Subject: [PATCH 165/586] Individual emblems mode --- src/deh_soc.c | 4 ++ src/doomstat.h | 3 ++ src/g_game.c | 1 + src/p_inter.c | 100 ++++++++++++++++++++++++++++++++++++++++++------- src/p_local.h | 2 + src/p_mobj.c | 48 ++++++------------------ src/p_setup.c | 2 +- src/st_stuff.c | 3 +- 8 files changed, 110 insertions(+), 53 deletions(-) diff --git a/src/deh_soc.c b/src/deh_soc.c index 81adbc9d2..f2f3e04b8 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -3839,6 +3839,10 @@ void readmaincfg(MYFILE *f) { useContinues = (UINT8)(value || word2[0] == 'T' || word2[0] == 'Y'); } + else if (fastcmp(word, "SHAREEMBLEMS")) + { + shareEmblems = (UINT8)(value || word2[0] == 'T' || word2[0] == 'Y'); + } else if (fastcmp(word, "GAMEDATA")) { diff --git a/src/doomstat.h b/src/doomstat.h index 5875bd01f..a812cc304 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -543,9 +543,12 @@ extern UINT8 useBlackRock; extern UINT8 use1upSound; extern UINT8 maxXtraLife; // Max extra lives from rings + extern UINT8 useContinues; #define continuesInSession (!multiplayer && (ultimatemode || (useContinues && !marathonmode) || (!modeattacking && !(cursaveslot > 0)))) +extern UINT8 shareEmblems; + extern mobj_t *hunt1, *hunt2, *hunt3; // Emerald hunt locations // For racing diff --git a/src/g_game.c b/src/g_game.c index 854bf9bbb..066b43cad 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -215,6 +215,7 @@ UINT8 ammoremovaltics = 2*TICRATE; UINT8 use1upSound = 0; UINT8 maxXtraLife = 2; // Max extra lives from rings UINT8 useContinues = 0; // Set to 1 to enable continues outside of no-save scenarioes +UINT8 shareEmblems = 0; // Set to 1 to share all picked up emblems in multiplayer UINT8 introtoplay; UINT8 creditscutscene; diff --git a/src/p_inter.c b/src/p_inter.c index f2d20912f..02ae222e3 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -164,6 +164,62 @@ boolean P_CanPickupItem(player_t *player, boolean weapon) return true; } +boolean P_CanPickupEmblem(player_t *player, INT32 emblemID) +{ + emblem_t *emblem = NULL; + + if (emblemID < 0 || emblemID >= numemblems) + { + // Invalid emblem ID, can't pickup. + return false; + } + + emblem = &emblemlocations[emblemID]; + + if (demoplayback) + { + // Never collect emblems in replays. + return false; + } + + if (player->bot && player->bot != BOT_MPAI) + { + // Your little lap-dog can't grab these for you. + return false; + } + + if (emblem->type == ET_SKIN) + { + INT32 skinnum = M_EmblemSkinNum(emblem); + + if (player->skin != skinnum) + { + // Incorrect skin to pick up this emblem. + return false; + } + } + + return true; +} + +boolean P_EmblemWasCollected(INT32 emblemID) +{ + if (emblemID < 0 || emblemID >= numemblems) + { + // Invalid emblem ID, can't pickup. + return true; + } + + if (shareEmblems && !serverGamedata->collected[emblemID]) + { + // It can be worth collecting again if we're sharing emblems + // and the server doesn't have it. + return false; + } + + return clientGamedata->collected[emblemID]; +} + // // P_DoNightsScore // @@ -738,25 +794,41 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) // Secret emblem thingy case MT_EMBLEM: { - if (demoplayback || (player->bot && player->bot != BOT_MPAI) || special->health <= 0 || special->health > MAXEMBLEMS) - return; + mobj_t *spark = NULL; + boolean prevCollected; - if (emblemlocations[special->health-1].type == ET_SKIN) + if (!P_CanPickupEmblem(player, special->health - 1)) { - INT32 skinnum = M_EmblemSkinNum(&emblemlocations[special->health-1]); - - if (player->skin != skinnum) - { - return; - } + return; } - clientGamedata->collected[special->health-1] = serverGamedata->collected[special->health-1] = true; + prevCollected = P_EmblemWasCollected(special->health - 1); - M_SilentUpdateUnlockablesAndEmblems(serverGamedata); - M_UpdateUnlockablesAndExtraEmblems(clientGamedata); - G_SaveGameData(clientGamedata); - break; + if (((player - players) == serverplayer) || shareEmblems) + { + serverGamedata->collected[special->health-1] = true; + M_SilentUpdateUnlockablesAndEmblems(serverGamedata); + } + + if (P_IsLocalPlayer(player) || shareEmblems) + { + clientGamedata->collected[special->health-1] = true; + M_UpdateUnlockablesAndExtraEmblems(clientGamedata); + G_SaveGameData(clientGamedata); + } + + // This always spawns the object to prevent mobjnum issues, + // but makes the effect invisible to whoever it doesn't matter to. + spark = P_SpawnMobjFromMobj(special, 0, 0, 0, MT_SPARK); + if (prevCollected == false && P_EmblemWasCollected(special->health - 1) == true) + { + S_StartSound(special, special->info->deathsound); + } + else + { + spark->flags2 |= MF2_DONTDRAW; + } + return; } // CTF Flags diff --git a/src/p_local.h b/src/p_local.h index cc060e4ee..3c84d6fe2 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -510,6 +510,8 @@ void P_ClearStarPost(INT32 postnum); void P_ResetStarposts(void); boolean P_CanPickupItem(player_t *player, boolean weapon); +boolean P_CanPickupEmblem(player_t *player, INT32 emblemID); +boolean P_EmblemWasCollected(INT32 emblemID); void P_DoNightsScore(player_t *player); void P_DoMatchSuper(player_t *player); diff --git a/src/p_mobj.c b/src/p_mobj.c index 6563e6f0a..f198a1a69 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9716,6 +9716,11 @@ static boolean P_MobjRegularThink(mobj_t *mobj) A_AttractChase(mobj); break; case MT_EMBLEM: + if (P_EmblemWasCollected(mobj->health - 1) || !P_CanPickupEmblem(&players[consoleplayer], mobj->health - 1)) + mobj->frame |= (tr_trans50 << FF_TRANSSHIFT); + else + mobj->frame &= ~FF_TRANSMASK; + if (mobj->flags2 & MF2_NIGHTSPULL) P_NightsItemChase(mobj); break; @@ -12146,7 +12151,6 @@ 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) { @@ -12171,47 +12175,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; - validEmblem = true; + mobj->frame &= ~FF_TRANSMASK; - if (!netgame) + if (emblemlocations[j].type == ET_GLOBAL) { - validEmblem = !serverGamedata->collected[j]; - - if (emblemlocations[j].type == ET_SKIN && !multiplayer) + mobj->reactiontime = emblemlocations[j].var; + if (emblemlocations[j].var & GE_NIGHTSITEM) { - INT32 skinnum = M_EmblemSkinNum(&emblemlocations[j]); - - if (players[0].skin != skinnum) - { - validEmblem = false; - } + mobj->flags |= MF_NIGHTSITEM; + mobj->flags &= ~MF_SPECIAL; + mobj->flags2 |= MF2_DONTDRAW; } } - if (validEmblem == false) - { - P_UnsetThingPosition(mobj); - mobj->flags |= MF_NOCLIP; - mobj->flags &= ~MF_SPECIAL; - mobj->flags |= MF_NOBLOCKMAP; - mobj->frame |= (tr_trans50 << FF_TRANSSHIFT); - P_SetThingPosition(mobj); - } - else - { - mobj->frame &= ~FF_TRANSMASK; - - if (emblemlocations[j].type == ET_GLOBAL) - { - mobj->reactiontime = emblemlocations[j].var; - if (emblemlocations[j].var & GE_NIGHTSITEM) - { - mobj->flags |= MF_NIGHTSITEM; - mobj->flags &= ~MF_SPECIAL; - mobj->flags2 |= MF2_DONTDRAW; - } - } - } return true; } diff --git a/src/p_setup.c b/src/p_setup.c index 70a2c0a8b..74645e877 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -876,7 +876,7 @@ static void P_SpawnMapThings(boolean spawnemblems) size_t i; mapthing_t *mt; - // Spawn axis points first so they are at the front of the list for fast searching. + // Spawn axis points first so they are at the front of the list for fast searching. for (i = 0, mt = mapthings; i < nummapthings; i++, mt++) { switch (mt->type) diff --git a/src/st_stuff.c b/src/st_stuff.c index 1f0ca277f..986b71219 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2563,9 +2563,8 @@ static void ST_doItemFinderIconsAndSound(void) emblems[stemblems++] = i; - if (!(clientGamedata->collected[i] && serverGamedata->collected[i])) + if (!P_EmblemWasCollected(i)) { - // It can be worth collecting again if the server doesn't have it. ++stunfound; } From 29c61fac88f88aa63474444f8fad73a3f9a49e13 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 28 Feb 2022 10:58:34 -0500 Subject: [PATCH 166/586] Allow completion emblems in multiplayer --- 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 066b43cad..c26968ac0 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3843,7 +3843,7 @@ static void G_UpdateVisited(gamedata_t *data, boolean silent) { boolean spec = G_IsSpecialStage(gamemap); // Update visitation flags? - if (!multiplayer && !demoplayback && (gametype == GT_COOP) // SP/RA/NiGHTS mode + if (!demoplayback && (gametype == GT_COOP) // SP/RA/NiGHTS mode && !stagefailed) // Did not fail the stage { UINT8 earnedEmblems; From d7c5e16f6c0c82a9d8ca214b010094f65b5e61f3 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 28 Feb 2022 11:50:12 -0500 Subject: [PATCH 167/586] Play sound globally if emblems are shared --- 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 02ae222e3..b5266e09f 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -822,7 +822,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) spark = P_SpawnMobjFromMobj(special, 0, 0, 0, MT_SPARK); if (prevCollected == false && P_EmblemWasCollected(special->health - 1) == true) { - S_StartSound(special, special->info->deathsound); + S_StartSound((shareEmblems ? NULL : special), special->info->deathsound); } else { From 30f6ae6e5606bbdb6564558fef18918a127ac0f3 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 28 Feb 2022 13:48:59 -0500 Subject: [PATCH 168/586] Add read access to shareEmblems (as well as a few other MAINCFG variables that weren't) --- src/lua_script.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/lua_script.c b/src/lua_script.c index 9c7636ebe..75e9c29a0 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -306,6 +306,18 @@ int LUA_PushGlobals(lua_State *L, const char *word) lua_pushinteger(L, ammoremovaltics); return 1; // end timers + } else if (fastcmp(word,"use1upSound")) { + lua_pushinteger(L, use1upSound); + return 1; + } else if (fastcmp(word,"maxXtraLife")) { + lua_pushinteger(L, maxXtraLife); + return 1; + } else if (fastcmp(word,"useContinues")) { + lua_pushinteger(L, useContinues); + return 1; + } else if (fastcmp(word,"shareEmblems")) { + lua_pushinteger(L, shareEmblems); + return 1; } else if (fastcmp(word,"gametype")) { lua_pushinteger(L, gametype); return 1; From ffb76334ff37a0c5b2064450d0b895773515a4fe Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 28 Feb 2022 13:58:23 -0500 Subject: [PATCH 169/586] Don't check time attack emblems in multiplayer (Maybe some day...) --- src/g_game.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/g_game.c b/src/g_game.c index c26968ac0..b3dffd0e6 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3869,7 +3869,8 @@ static void G_UpdateVisited(gamedata_t *data, boolean silent) if (silent) { - M_CheckLevelEmblems(data); + if (modeattacking) + M_CheckLevelEmblems(data); } else { From ffe591afeee2b48875235e86bc3480ce99850cb3 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 28 Feb 2022 17:36:02 -0500 Subject: [PATCH 170/586] Tie emblem spawning to Coop gametypes --- src/g_game.c | 6 +++++- src/p_mobj.c | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/g_game.c b/src/g_game.c index b3dffd0e6..106682aee 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3843,16 +3843,19 @@ static void G_UpdateVisited(gamedata_t *data, boolean silent) { boolean spec = G_IsSpecialStage(gamemap); // Update visitation flags? - if (!demoplayback && (gametype == GT_COOP) // SP/RA/NiGHTS mode + if (!demoplayback + && G_CoopGametype() // Campaign mode && !stagefailed) // Did not fail the stage { UINT8 earnedEmblems; // Update visitation flags data->mapvisited[gamemap-1] |= MV_BEATEN; + // eh, what the hell if (ultimatemode) data->mapvisited[gamemap-1] |= MV_ULTIMATE; + // may seem incorrect but IS possible in what the main game uses as mp special stages, and nummaprings will be -1 in NiGHTS if (nummaprings > 0 && players[consoleplayer].rings >= nummaprings) { @@ -3860,6 +3863,7 @@ static void G_UpdateVisited(gamedata_t *data, boolean silent) if (modeattacking) data->mapvisited[gamemap-1] |= MV_PERFECTRA; } + if (!spec) { // not available to special stages because they can only really be done in one order in an unmodified game, so impossible for first six and trivial for seventh diff --git a/src/p_mobj.c b/src/p_mobj.c index f198a1a69..e79977c48 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -12009,6 +12009,10 @@ static boolean P_AllowMobjSpawn(mapthing_t* mthing, mobjtype_t i) return false; // You already got this token break; + case MT_EMBLEM: + if (!G_CoopGametype()) + return false; // Gametype's not right + break; default: break; } From 122ddade61d60259f8b7d66fd27cb2c60ed44452 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 28 Feb 2022 18:52:38 -0500 Subject: [PATCH 171/586] Draw level stats on pause & emblem hints menus in multiplayer --- src/m_menu.c | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 2214e6a6a..2d8db8b24 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -555,19 +555,22 @@ static menuitem_t MPauseMenu[] = {IT_STRING | IT_CALL, NULL, "Add-ons...", M_Addons, 8}, {IT_STRING | IT_SUBMENU, NULL, "Scramble Teams...", &MISC_ScrambleTeamDef, 16}, {IT_STRING | IT_CALL, NULL, "Switch Gametype/Level...", M_MapChange, 24}, + {IT_STRING | IT_CALL, NULL, "Emblem Hints...", M_EmblemHints, 32}, - {IT_STRING | IT_CALL, NULL, "Continue", M_SelectableClearMenus,40}, - {IT_STRING | IT_CALL, NULL, "Player 1 Setup", M_SetupMultiPlayer, 48}, // splitscreen - {IT_STRING | IT_CALL, NULL, "Player 2 Setup", M_SetupMultiPlayer2, 56}, // splitscreen + {IT_STRING | IT_CALL, NULL, "Continue", M_SelectableClearMenus,48}, - {IT_STRING | IT_CALL, NULL, "Spectate", M_ConfirmSpectate, 48}, - {IT_STRING | IT_CALL, NULL, "Enter Game", M_ConfirmEnterGame, 48}, - {IT_STRING | IT_SUBMENU, NULL, "Switch Team...", &MISC_ChangeTeamDef, 48}, - {IT_STRING | IT_CALL, NULL, "Player Setup", M_SetupMultiPlayer, 56}, // alone - {IT_STRING | IT_CALL, NULL, "Options", M_Options, 64}, + {IT_STRING | IT_CALL, NULL, "Player 1 Setup", M_SetupMultiPlayer, 56}, // splitscreen + {IT_STRING | IT_CALL, NULL, "Player 2 Setup", M_SetupMultiPlayer2, 64}, - {IT_STRING | IT_CALL, NULL, "Return to Title", M_EndGame, 80}, - {IT_STRING | IT_CALL, NULL, "Quit Game", M_QuitSRB2, 88}, + {IT_STRING | IT_CALL, NULL, "Spectate", M_ConfirmSpectate, 56}, // alone + {IT_STRING | IT_CALL, NULL, "Enter Game", M_ConfirmEnterGame, 56}, + {IT_STRING | IT_SUBMENU, NULL, "Switch Team...", &MISC_ChangeTeamDef, 56}, + {IT_STRING | IT_CALL, NULL, "Player Setup", M_SetupMultiPlayer, 64}, + + {IT_STRING | IT_CALL, NULL, "Options", M_Options, 72}, + + {IT_STRING | IT_CALL, NULL, "Return to Title", M_EndGame, 88}, + {IT_STRING | IT_CALL, NULL, "Quit Game", M_QuitSRB2, 96}, }; typedef enum @@ -575,6 +578,7 @@ typedef enum mpause_addons = 0, mpause_scramble, mpause_switchmap, + mpause_hints, mpause_continue, mpause_psetupsplit, @@ -3747,12 +3751,10 @@ void M_StartControlPanel(void) if (splitscreen) { MPauseMenu[mpause_psetupsplit].status = MPauseMenu[mpause_psetupsplit2].status = IT_STRING | IT_CALL; - MPauseMenu[mpause_psetup].text = "Player 1 Setup"; } else { MPauseMenu[mpause_psetup].status = IT_STRING | IT_CALL; - MPauseMenu[mpause_psetup].text = "Player Setup"; if (G_GametypeHasTeams()) MPauseMenu[mpause_switchteam].status = IT_STRING | IT_SUBMENU; @@ -3762,6 +3764,8 @@ void M_StartControlPanel(void) MPauseMenu[mpause_spectate].status = IT_GRAYEDOUT; } + MPauseMenu[mpause_hints].status = (M_SecretUnlocked(SECRET_EMBLEMHINTS, clientGamedata) && G_CoopGametype()) ? (IT_STRING | IT_CALL) : (IT_DISABLED); + currentMenu = &MPauseDef; itemOn = mpause_continue; } @@ -4696,7 +4700,7 @@ static void M_DrawPauseMenu(void) { gamedata_t *data = clientGamedata; - if (!netgame && !multiplayer && (gamestate == GS_LEVEL || gamestate == GS_INTERMISSION)) + if (gamestate == GS_LEVEL || gamestate == GS_INTERMISSION) { emblem_t *emblem_detail[3] = {NULL, NULL, NULL}; char emblem_text[3][20]; From fb5b8ce1be2a88c7afae55816c62e1928a5b88f5 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 28 Feb 2022 19:14:02 -0500 Subject: [PATCH 172/586] Show tab emblems in Coop --- src/hu_stuff.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/hu_stuff.c b/src/hu_stuff.c index eceb6bbaf..091e2b2fb 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -2862,18 +2862,6 @@ static void HU_DrawRankings(void) V_DrawCenteredString(256, 16, 0, va("%d", cv_pointlimit.value)); } } - else if (gametyperankings[gametype] == GT_COOP) - { - INT32 totalscore = 0; - for (i = 0; i < MAXPLAYERS; i++) - { - if (playeringame[i]) - totalscore += players[i].score; - } - - V_DrawCenteredString(256, 8, 0, "TOTAL SCORE"); - V_DrawCenteredString(256, 16, 0, va("%u", totalscore)); - } else { if (circuitmap) @@ -3029,6 +3017,15 @@ static void HU_DrawNetplayCoopOverlay(void) V_DrawSmallScaledPatch(148, 6, 0, tokenicon); } + if (G_CoopGametype() && LUA_HudEnabled(hud_tabemblems)) + { + V_DrawCenteredString(256, 14, 0, "/"); + V_DrawString(256 + 4, 14, 0, va("%d", numemblems + numextraemblems)); + V_DrawRightAlignedString(256 - 4, 14, 0, va("%d", M_CountEmblems(clientGamedata))); + + V_DrawSmallScaledPatch(256 - (emblemicon->width / 4), 6, 0, emblemicon); + } + if (!LUA_HudEnabled(hud_coopemeralds)) return; From 87e468f365d58f012b62a3a0a7851d4bf26a9872 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Thu, 3 Mar 2022 10:26:04 -0500 Subject: [PATCH 173/586] Allow emerald hunt radar to function if emblem radar is on but all emblems have been collected. --- src/st_stuff.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/st_stuff.c b/src/st_stuff.c index 986b71219..7eab0442f 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2545,7 +2545,7 @@ static void ST_doHuntIconsAndSound(void) S_StartSound(NULL, sfx_emfind); } -static void ST_doItemFinderIconsAndSound(void) +static boolean ST_doItemFinderIconsAndSound(void) { INT32 emblems[16]; thinker_t *th; @@ -2556,6 +2556,12 @@ static void ST_doItemFinderIconsAndSound(void) INT32 interval = 0, newinterval = 0; INT32 soffset; + if (!(cv_itemfinder.value && M_SecretUnlocked(SECRET_ITEMFINDER, clientGamedata))) + { + // Not unlocked, or not enabled. Use emerald hunt radar. + return false; + } + for (i = 0; i < numemblems; ++i) { if (emblemlocations[i].type > ET_SKIN || emblemlocations[i].level != gamemap) @@ -2573,7 +2579,10 @@ static void ST_doItemFinderIconsAndSound(void) } // Found all/none exist? Don't waste our time if (!stunfound) - return; + { + // Allow emerald hunt radar to function after they're all collected. + return false; + } // Scan thinkers to find emblem mobj with these ids for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) @@ -2607,6 +2616,8 @@ static void ST_doItemFinderIconsAndSound(void) if (!(P_AutoPause() || paused) && interval > 0 && leveltime && leveltime % interval == 0 && renderisnewtic) S_StartSound(NULL, sfx_emfind); + + return true; } // @@ -2725,9 +2736,7 @@ static void ST_overlayDrawer(void) ST_drawRaceHUD(); // Emerald Hunt Indicators - if (cv_itemfinder.value && M_SecretUnlocked(SECRET_ITEMFINDER, clientGamedata)) - ST_doItemFinderIconsAndSound(); - else + if (!ST_doItemFinderIconsAndSound()); ST_doHuntIconsAndSound(); if(!P_IsLocalPlayer(stplyr)) From cb54b1e5ce1daee0cd5e20bb507eeb375cb6ff5e Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Thu, 3 Mar 2022 10:26:36 -0500 Subject: [PATCH 174/586] Fix check that does LevelEmblems but not CompletionEmblems on startup --- src/m_cond.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/m_cond.c b/src/m_cond.c index 55f35830a..a54988f67 100644 --- a/src/m_cond.c +++ b/src/m_cond.c @@ -329,6 +329,7 @@ void M_SilentUpdateUnlockablesAndEmblems(gamedata_t *data) // Just in case they aren't to sync M_CheckUnlockConditions(data); M_CheckLevelEmblems(data); + M_CompletionEmblems(data); // Go through extra emblems for (i = 0; i < numextraemblems; ++i) From bc00b1335848e9827f492161baa14e2401dc45af Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 4 Mar 2022 11:29:02 -0500 Subject: [PATCH 175/586] Fix Emblem Radar detecting already collected emblems --- src/st_stuff.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/st_stuff.c b/src/st_stuff.c index 7eab0442f..42f1f89ec 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2577,6 +2577,7 @@ static boolean ST_doItemFinderIconsAndSound(void) if (stemblems >= 16) break; } + // Found all/none exist? Don't waste our time if (!stunfound) { @@ -2602,6 +2603,9 @@ static boolean ST_doItemFinderIconsAndSound(void) { if (mo2->health == emblems[i] + 1) { + if (P_EmblemWasCollected(emblems[i])) + break; + soffset = (i * 20) - ((stemblems - 1) * 10); newinterval = ST_drawEmeraldHuntIcon(mo2, itemhoming, soffset); @@ -2736,7 +2740,7 @@ static void ST_overlayDrawer(void) ST_drawRaceHUD(); // Emerald Hunt Indicators - if (!ST_doItemFinderIconsAndSound()); + if (!ST_doItemFinderIconsAndSound()) ST_doHuntIconsAndSound(); if(!P_IsLocalPlayer(stplyr)) From 903a47966d62df8571250646bc11858fc1c222bd Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 4 Mar 2022 11:31:41 -0500 Subject: [PATCH 176/586] Swap hints & level select on multiplayer pause menu This makes it consistent with SP's pause menu order. (Although admittedly I prefer how the other order looks.) --- 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 2d8db8b24..0ad9183c7 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -554,8 +554,8 @@ static menuitem_t MPauseMenu[] = { {IT_STRING | IT_CALL, NULL, "Add-ons...", M_Addons, 8}, {IT_STRING | IT_SUBMENU, NULL, "Scramble Teams...", &MISC_ScrambleTeamDef, 16}, - {IT_STRING | IT_CALL, NULL, "Switch Gametype/Level...", M_MapChange, 24}, - {IT_STRING | IT_CALL, NULL, "Emblem Hints...", M_EmblemHints, 32}, + {IT_STRING | IT_CALL, NULL, "Emblem Hints...", M_EmblemHints, 24}, + {IT_STRING | IT_CALL, NULL, "Switch Gametype/Level...", M_MapChange, 32}, {IT_STRING | IT_CALL, NULL, "Continue", M_SelectableClearMenus,48}, @@ -577,8 +577,8 @@ typedef enum { mpause_addons = 0, mpause_scramble, - mpause_switchmap, mpause_hints, + mpause_switchmap, mpause_continue, mpause_psetupsplit, From 9b6a47783dbfbc32998e1a30ca5e9717b1fc2552 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 4 Mar 2022 12:32:23 -0500 Subject: [PATCH 177/586] Show the level select option used to start the level in the pause menu. Previously, level select only appeared in the SP pause menu if you load a complete save file. Now, entering the game through an Extras menu level select shows that level select. Simply makes it more convenient, as you don't need to exit to the main menu again whenever you want to get to another level from an unlocked level select. Tested all ways you can start a new map from the menu that I can think of (New Save File, Complete Save File, Mid-game Save File, several different Level Select types, custom Warp, Record Attack, Marathon, Tutorial), and could not smuggle wrong level selects into any. --- src/m_menu.c | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 0ad9183c7..a40eddae9 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -241,6 +241,7 @@ static void M_EmblemHints(INT32 choice); static void M_HandleEmblemHints(INT32 choice); UINT32 hintpage = 1; static void M_HandleChecklist(INT32 choice); +static void M_PauseLevelSelect(INT32 choice); menu_t SR_MainDef, SR_UnlockChecklistDef; static UINT8 check_on; @@ -601,7 +602,7 @@ static menuitem_t SPauseMenu[] = // Pandora's Box will be shifted up if both options are available {IT_CALL | IT_STRING, NULL, "Pandora's Box...", M_PandorasBox, 16}, {IT_CALL | IT_STRING, NULL, "Emblem Hints...", M_EmblemHints, 24}, - {IT_CALL | IT_STRING, NULL, "Level Select...", M_LoadGameLevelSelect, 32}, + {IT_CALL | IT_STRING, NULL, "Level Select...", M_PauseLevelSelect, 32}, {IT_CALL | IT_STRING, NULL, "Continue", M_SelectableClearMenus,48}, {IT_CALL | IT_STRING, NULL, "Retry", M_Retry, 56}, @@ -3713,7 +3714,7 @@ void M_StartControlPanel(void) } // We can always use level select though. :33 - SPauseMenu[spause_levelselect].status = (gamecomplete == 1) ? (IT_STRING | IT_CALL) : (IT_DISABLED); + SPauseMenu[spause_levelselect].status = (maplistoption != 0) ? (IT_STRING | IT_CALL) : (IT_DISABLED); // And emblem hints. SPauseMenu[spause_hints].status = (M_SecretUnlocked(SECRET_EMBLEMHINTS, clientGamedata) && !marathonmode) ? (IT_STRING | IT_CALL) : (IT_DISABLED); @@ -7138,7 +7139,6 @@ static void M_LevelSelectWarp(INT32 choice) } startmap = (INT16)(cv_nextmap.value); - fromlevelselect = true; if (fromloadgame) @@ -7662,6 +7662,26 @@ static void M_HandleEmblemHints(INT32 choice) } +static void M_PauseLevelSelect(INT32 choice) +{ + (void)choice; + + SP_LevelSelectDef.prevMenu = currentMenu; + levellistmode = LLM_LEVELSELECT; + + // maplistoption is NOT specified, so that this + // transfers the level select list from the menu + // used to enter the game to the pause menu. + + if (!M_PrepareLevelPlatter(-1, true)) + { + M_StartMessage(M_GetText("No selectable levels found.\n"),NULL,MM_NOTHING); + return; + } + + M_SetupNextMenu(&SP_LevelSelectDef); +} + /*static void M_DrawSkyRoom(void) { INT32 i, y = 0; @@ -8169,6 +8189,7 @@ INT32 ultimate_selectable = false; static void M_NewGame(void) { fromlevelselect = false; + maplistoption = 0; startmap = spstage_start; CV_SetValue(&cv_newgametype, GT_COOP); // Graue 09-08-2004 @@ -8180,6 +8201,7 @@ static void M_CustomWarp(INT32 choice) { INT32 ul = skyRoomMenuTranslations[choice-1]; + maplistoption = 0; startmap = (INT16)(unlockables[ul].variable); M_SetupChoosePlayer(0); @@ -8372,6 +8394,7 @@ static void M_StartTutorial(INT32 choice) M_ClearMenus(true); gamecomplete = 0; cursaveslot = 0; + maplistoption = 0; G_DeferedInitNew(false, G_BuildMapName(tutorialmap), 0, false, false); } @@ -8734,6 +8757,10 @@ static void M_LoadSelect(INT32 choice) { (void)choice; + // Reset here, if we want a level select + // M_LoadGameLevelSelect will set it for us. + maplistoption = 0; + if (saveSlotSelected == NOSAVESLOT) //last slot is play without saving { M_NewGame(); @@ -10674,6 +10701,7 @@ static void M_Marathon(INT32 choice) } fromlevelselect = false; + maplistoption = 0; startmap = spmarathon_start; CV_SetValue(&cv_newgametype, GT_COOP); // Graue 09-08-2004 From 897b81b8400522ec0d6a761d19bc2eb49c3e74f4 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 4 Mar 2022 15:28:11 -0500 Subject: [PATCH 178/586] Don't load game from pause level select without save slot --- src/m_menu.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index a40eddae9..ef149cec5 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1829,6 +1829,10 @@ menu_t SP_LevelSelectDef = MAPPLATTERMENUSTYLE( MTREE4(MN_SP_MAIN, MN_SP_LOAD, MN_SP_PLAYER, MN_SP_LEVELSELECT), NULL, SP_LevelSelectMenu); +menu_t SP_PauseLevelSelectDef = MAPPLATTERMENUSTYLE( + MTREE4(MN_SP_MAIN, MN_SP_LOAD, MN_SP_PLAYER, MN_SP_LEVELSELECT), + NULL, SP_LevelSelectMenu); + menu_t SP_LevelStatsDef = { MTREE2(MN_SP_MAIN, MN_SP_LEVELSTATS), @@ -7129,6 +7133,7 @@ static void M_DestroyRobots(INT32 choice) static void M_LevelSelectWarp(INT32 choice) { boolean fromloadgame = (currentMenu == &SP_LevelSelectDef); + boolean frompause = (currentMenu == &SP_PauseLevelSelectDef); (void)choice; @@ -7146,7 +7151,20 @@ static void M_LevelSelectWarp(INT32 choice) else { cursaveslot = 0; - M_SetupChoosePlayer(0); + + if (frompause) + { + M_ClearMenus(true); + + D_MapChange(startmap, gametype, false, false, 1, false, fromlevelselect); + COM_BufAddText("dummyconsvar 1\n"); + + if (levelselect.rows) + Z_Free(levelselect.rows); + levelselect.rows = NULL; + } + else + M_SetupChoosePlayer(0); } } @@ -7666,7 +7684,7 @@ static void M_PauseLevelSelect(INT32 choice) { (void)choice; - SP_LevelSelectDef.prevMenu = currentMenu; + SP_PauseLevelSelectDef.prevMenu = currentMenu; levellistmode = LLM_LEVELSELECT; // maplistoption is NOT specified, so that this @@ -7679,7 +7697,7 @@ static void M_PauseLevelSelect(INT32 choice) return; } - M_SetupNextMenu(&SP_LevelSelectDef); + M_SetupNextMenu(&SP_PauseLevelSelectDef); } /*static void M_DrawSkyRoom(void) From d8f6ad217c02ab04d1dceb3e084ce2857a8ad886 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 5 Mar 2022 01:41:24 -0500 Subject: [PATCH 179/586] Don't give completion emblems when getting a game over in multiplayer (or any other kind of level reset) --- src/g_game.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/g_game.c b/src/g_game.c index 106682aee..aafbdea76 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3153,6 +3153,9 @@ void G_DoReborn(INT32 playernum) if (resetlevel) { + // Don't give completion emblems for reloading the level... + stagefailed = true; + // reload the level from scratch if (countdowntimeup) { From 3b15d9b4fe0c3f9b3a0fc1b6d3d947f39ac65e5a Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 6 Mar 2022 22:52:20 -0500 Subject: [PATCH 180/586] Make the level select behave more identically to G_LoadGame Noticed some oddities with D_MapChange here with very rarely not changing player position when the map is loaded. --- 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 ef149cec5..c025ae286 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -7156,8 +7156,8 @@ static void M_LevelSelectWarp(INT32 choice) { M_ClearMenus(true); - D_MapChange(startmap, gametype, false, false, 1, false, fromlevelselect); - COM_BufAddText("dummyconsvar 1\n"); + G_DeferedInitNew(false, G_BuildMapName(startmap), cv_skin.value, false, fromlevelselect); // Not sure about using cv_skin here, but it seems fine in testing. + COM_BufAddText("dummyconsvar 1\n"); // G_DeferedInitNew doesn't do this if (levelselect.rows) Z_Free(levelselect.rows); From 9cce2195d4e41f537a911a1de9aa17a0caba0b91 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 7 Mar 2022 16:31:10 -0500 Subject: [PATCH 181/586] Make ShareEmblems more Top Down style --- 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 b5266e09f..750e9cc34 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -810,7 +810,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) M_SilentUpdateUnlockablesAndEmblems(serverGamedata); } - if (P_IsLocalPlayer(player) || shareEmblems) + if (P_IsLocalPlayer(player) /*|| shareEmblems*/) { clientGamedata->collected[special->health-1] = true; M_UpdateUnlockablesAndExtraEmblems(clientGamedata); From d751ad5cf262b0557a86a2e5d028cabce0c06909 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Wed, 9 Mar 2022 03:28:38 -0500 Subject: [PATCH 182/586] Remove "Multiplayer games can't unlock extras!" --- src/f_finale.c | 46 ++++++++++++++++++---------------------------- 1 file changed, 18 insertions(+), 28 deletions(-) diff --git a/src/f_finale.c b/src/f_finale.c index 4bb640d50..929a08eaf 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1642,37 +1642,27 @@ void F_GameEvaluationTicker(void) if (finalecount == 5*TICRATE) { - if (netgame || multiplayer) // modify this when we finally allow unlocking stuff in 2P + serverGamedata->timesBeaten++; + clientGamedata->timesBeaten++; + + if (ALL7EMERALDS(emeralds)) { - HU_SetCEchoFlags(V_YELLOWMAP|V_RETURN8); - HU_SetCEchoDuration(6); - HU_DoCEcho("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\Multiplayer games can't unlock extras!"); + serverGamedata->timesBeatenWithEmeralds++; + clientGamedata->timesBeatenWithEmeralds++; + } + + if (ultimatemode) + { + serverGamedata->timesBeatenUltimate++; + clientGamedata->timesBeatenUltimate++; + } + + M_SilentUpdateUnlockablesAndEmblems(serverGamedata); + + if (M_UpdateUnlockablesAndExtraEmblems(clientGamedata)) S_StartSound(NULL, sfx_s3k68); - } - else - { - serverGamedata->timesBeaten++; - clientGamedata->timesBeaten++; - if (ALL7EMERALDS(emeralds)) - { - serverGamedata->timesBeatenWithEmeralds++; - clientGamedata->timesBeatenWithEmeralds++; - } - - if (ultimatemode) - { - serverGamedata->timesBeatenUltimate++; - clientGamedata->timesBeatenUltimate++; - } - - M_SilentUpdateUnlockablesAndEmblems(serverGamedata); - - if (M_UpdateUnlockablesAndExtraEmblems(clientGamedata)) - S_StartSound(NULL, sfx_s3k68); - - G_SaveGameData(clientGamedata); - } + G_SaveGameData(clientGamedata); } } From 29f55471ddc163bddaa8bf5fba75ef4aec2fef63 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Wed, 12 Oct 2022 01:18:02 -0400 Subject: [PATCH 183/586] Fix instances reverted to old unlocked variable --- src/m_cheat.c | 6 +++--- src/p_spec.c | 10 +++------- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/src/m_cheat.c b/src/m_cheat.c index 934779982..e370335f8 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -79,9 +79,9 @@ static UINT8 cheatf_warp(void) // Temporarily unlock stuff. G_SetUsedCheats(false); - unlockables[31].unlocked = true; // credits - unlockables[30].unlocked = true; // sound test - unlockables[28].unlocked = true; // level select + clientGamedata->unlocked[31] = true; // credits + clientGamedata->unlocked[30] = true; // sound test + clientGamedata->unlocked[28] = true; // level select // Refresh secrets menu existing. M_ClearMenus(true); diff --git a/src/p_spec.c b/src/p_spec.c index 48185e908..71ea145b9 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1795,9 +1795,7 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller { // Unlockable triggers required INT32 trigid = triggerline->args[1]; - if (netgame || multiplayer) - return false; - else if (trigid < 0 || trigid > 31) // limited by 32 bit variable + if (trigid < 0 || trigid > 31) // limited by 32 bit variable { CONS_Debug(DBG_GAMELOGIC, "Unlockable trigger (sidedef %hu): bad trigger ID %d\n", triggerline->sidenum[0], trigid); return false; @@ -1810,14 +1808,12 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller { // An unlockable itself must be unlocked! INT32 unlockid = triggerline->args[1]; - if (netgame || multiplayer) - return false; - else if (unlockid < 0 || unlockid >= MAXUNLOCKABLES) // limited by unlockable count + if (unlockid < 0 || unlockid >= MAXUNLOCKABLES) // limited by unlockable count { CONS_Debug(DBG_GAMELOGIC, "Unlockable check (sidedef %hu): bad unlockable ID %d\n", triggerline->sidenum[0], unlockid); return false; } - else if (!(unlockables[unlockid-1].unlocked)) + else if (!(serverGamedata->unlocked[unlockid-1])) return false; } break; From c1e641be437ae0e3e037f1f518466734ff47a8ab Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 31 Oct 2022 18:09:18 -0400 Subject: [PATCH 184/586] Improve emblem sharing conditions --- src/p_inter.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 750e9cc34..bd3c15a45 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -796,6 +796,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) { mobj_t *spark = NULL; boolean prevCollected; + const boolean isServer = ((player - players) == serverplayer); if (!P_CanPickupEmblem(player, special->health - 1)) { @@ -804,13 +805,13 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) prevCollected = P_EmblemWasCollected(special->health - 1); - if (((player - players) == serverplayer) || shareEmblems) + if (isServer || shareEmblems) { serverGamedata->collected[special->health-1] = true; M_SilentUpdateUnlockablesAndEmblems(serverGamedata); } - if (P_IsLocalPlayer(player) /*|| shareEmblems*/) + if (P_IsLocalPlayer(player) || (isServer && shareEmblems)) { clientGamedata->collected[special->health-1] = true; M_UpdateUnlockablesAndExtraEmblems(clientGamedata); From 645dd7d66278372c8fd9ec3357286887683c8f0b Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 31 Oct 2022 18:26:41 -0400 Subject: [PATCH 185/586] Stop endlessly chasing NIGHTSPULL emblems --- src/p_inter.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/p_inter.c b/src/p_inter.c index bd3c15a45..907388a8c 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -798,6 +798,17 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) boolean prevCollected; const boolean isServer = ((player - players) == serverplayer); + if ((special->flags2 & MF2_NIGHTSPULL) + && (toucher == special->tracer)) + { + // Since collecting may not remove the object, + // we need to manually stop it from chasing. + P_SetTarget(&special->tracer, NULL); + special->flags2 &= ~MF2_NIGHTSPULL; + special->movefactor = 0; + special->momx = special->momy = special->momz = 0; + } + if (!P_CanPickupEmblem(player, special->health - 1)) { return; From cf228757a1c310cf0ba22452f2b5967f54a9583f Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 31 Oct 2022 18:46:47 -0400 Subject: [PATCH 186/586] Emblems disappear on collection again, only for SP --- src/p_inter.c | 41 +++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 907388a8c..5adfdb852 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -794,9 +794,9 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) // Secret emblem thingy case MT_EMBLEM: { - mobj_t *spark = NULL; - boolean prevCollected; - const boolean isServer = ((player - players) == serverplayer); + const boolean toucherIsServer = ((player - players) == serverplayer); + const boolean consoleIsServer = (consoleplayer == serverplayer); + boolean prevCollected = false; if ((special->flags2 & MF2_NIGHTSPULL) && (toucher == special->tracer)) @@ -816,31 +816,48 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) prevCollected = P_EmblemWasCollected(special->health - 1); - if (isServer || shareEmblems) + if (toucherIsServer || shareEmblems) { serverGamedata->collected[special->health-1] = true; M_SilentUpdateUnlockablesAndEmblems(serverGamedata); } - if (P_IsLocalPlayer(player) || (isServer && shareEmblems)) + if (P_IsLocalPlayer(player) || (consoleIsServer && shareEmblems)) { clientGamedata->collected[special->health-1] = true; M_UpdateUnlockablesAndExtraEmblems(clientGamedata); G_SaveGameData(clientGamedata); } - // This always spawns the object to prevent mobjnum issues, - // but makes the effect invisible to whoever it doesn't matter to. - spark = P_SpawnMobjFromMobj(special, 0, 0, 0, MT_SPARK); - if (prevCollected == false && P_EmblemWasCollected(special->health - 1) == true) + if (netgame) { - S_StartSound((shareEmblems ? NULL : special), special->info->deathsound); + // This always spawns the object to prevent mobjnum issues, + // but makes the effect invisible to whoever it doesn't matter to. + mobj_t *spark = P_SpawnMobjFromMobj(special, 0, 0, 0, MT_SPARK); + + if (prevCollected == false && P_EmblemWasCollected(special->health - 1) == true) + { + // Play the sound if it was collected. + S_StartSound((shareEmblems ? NULL : special), special->info->deathsound); + } + else + { + // We didn't collect it, make it invisible to us. + spark->flags2 |= MF2_DONTDRAW; + } + + return; } else { - spark->flags2 |= MF2_DONTDRAW; + if (prevCollected == false && P_EmblemWasCollected(special->health - 1) == true) + { + // Disappear when collecting for local games. + break; + } + + return; } - return; } // CTF Flags From e06956a53b06872b4eb2c9bd184177c3b1322b77 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Wed, 16 Nov 2022 12:40:46 -0500 Subject: [PATCH 187/586] Fix skin-only emblems on emblem radar --- src/st_stuff.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/st_stuff.c b/src/st_stuff.c index 42f1f89ec..59c50b168 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2569,7 +2569,7 @@ static boolean ST_doItemFinderIconsAndSound(void) emblems[stemblems++] = i; - if (!P_EmblemWasCollected(i)) + if (!P_EmblemWasCollected(i) && P_CanPickupEmblem(stplyr, i)) { ++stunfound; } @@ -2603,7 +2603,7 @@ static boolean ST_doItemFinderIconsAndSound(void) { if (mo2->health == emblems[i] + 1) { - if (P_EmblemWasCollected(emblems[i])) + if (P_EmblemWasCollected(emblems[i]) || !P_CanPickupEmblem(stplyr, emblems[i])) break; soffset = (i * 20) - ((stemblems - 1) * 10); From 35b676e313378a08d9369a503612ddd0d795832a Mon Sep 17 00:00:00 2001 From: SMS Alfredo <65426124+SMS-Alfredo@users.noreply.github.com> Date: Fri, 2 Jun 2023 19:52:03 -0500 Subject: [PATCH 188/586] Fix Camera Interpolation Not Being Reset --- src/r_main.c | 63 +++++++++++++++++++++++++--------------------------- 1 file changed, 30 insertions(+), 33 deletions(-) diff --git a/src/r_main.c b/src/r_main.c index ebf7a28bf..55bb9c4ff 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1092,34 +1092,12 @@ subsector_t *R_PointInSubsectorOrNull(fixed_t x, fixed_t y) void R_SetupFrame(player_t *player) { camera_t *thiscam; - boolean chasecam = false; - - if (splitscreen && player == &players[secondarydisplayplayer] - && player != &players[consoleplayer]) - { + boolean chasecam = R_ViewpointHasChasecam(player); + + if (splitscreen && player == &players[secondarydisplayplayer] && player != &players[consoleplayer]) thiscam = &camera2; - chasecam = (cv_chasecam2.value != 0); - R_SetViewContext(VIEWCONTEXT_PLAYER2); - } else - { thiscam = &camera; - chasecam = (cv_chasecam.value != 0); - R_SetViewContext(VIEWCONTEXT_PLAYER1); - } - - if (player->climbing || (player->powers[pw_carry] == CR_NIGHTSMODE) || player->playerstate == PST_DEAD || gamestate == GS_TITLESCREEN || tutorialmode) - chasecam = true; // force chasecam on - else if (player->spectator) // no spectator chasecam - chasecam = false; // force chasecam off - - if (chasecam && !thiscam->chase) - { - P_ResetCamera(player, thiscam); - thiscam->chase = true; - } - else if (!chasecam) - thiscam->chase = false; newview->sky = false; @@ -1348,11 +1326,37 @@ boolean R_ViewpointHasChasecam(player_t *player) { camera_t *thiscam; boolean chasecam = false; + boolean isplayer2 = (splitscreen && player == &players[secondarydisplayplayer] && player != &players[consoleplayer]); - if (splitscreen && player == &players[secondarydisplayplayer] && player != &players[consoleplayer]) + if (isplayer2) { thiscam = &camera2; chasecam = (cv_chasecam2.value != 0); + } + else + { + thiscam = &camera; + chasecam = (cv_chasecam.value != 0); + } + + if (player->climbing || (player->powers[pw_carry] == CR_NIGHTSMODE) || player->playerstate == PST_DEAD || gamestate == GS_TITLESCREEN || tutorialmode) + chasecam = true; // force chasecam on + else if (player->spectator) // no spectator chasecam + chasecam = false; // force chasecam off + + if (chasecam && !thiscam->chase) + { + P_ResetCamera(player, thiscam); + thiscam->chase = true; + } + else if (!chasecam && thiscam->chase) + { + P_ResetCamera(player, thiscam); + thiscam->chase = false; + } + + if (isplayer2) + { R_SetViewContext(VIEWCONTEXT_PLAYER2); if (thiscam->reset) { @@ -1362,8 +1366,6 @@ boolean R_ViewpointHasChasecam(player_t *player) } else { - thiscam = &camera; - chasecam = (cv_chasecam.value != 0); R_SetViewContext(VIEWCONTEXT_PLAYER1); if (thiscam->reset) { @@ -1372,11 +1374,6 @@ boolean R_ViewpointHasChasecam(player_t *player) } } - if (player->climbing || (player->powers[pw_carry] == CR_NIGHTSMODE) || player->playerstate == PST_DEAD || gamestate == GS_TITLESCREEN || tutorialmode) - chasecam = true; // force chasecam on - else if (player->spectator) // no spectator chasecam - chasecam = false; // force chasecam off - return chasecam; } From 7c75f61be74a6a152640df01bcb60d4c07fd7e03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Sat, 3 Jun 2023 13:05:33 +0200 Subject: [PATCH 189/586] Fix buffer overflow when displaying a scrolling background --- src/m_menu.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/m_menu.c b/src/m_menu.c index 64a1c9404..2fc0b889f 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -2807,6 +2807,7 @@ void M_SetMenuCurBackground(const char *defaultname) { char name[9]; strncpy(name, defaultname, 8); + name[8] = '\0'; M_IterateMenuTree(MIT_SetCurBackground, &name); } From aa43aa7c8c0a1c17174b7b84ffa9e9a282f4264c Mon Sep 17 00:00:00 2001 From: SMS Alfredo <65426124+SMS-Alfredo@users.noreply.github.com> Date: Sat, 3 Jun 2023 15:43:58 -0500 Subject: [PATCH 190/586] Call P_ResetCamera Upon Switching To/From an Away View Camera --- src/lua_playerlib.c | 4 ++++ src/p_spec.c | 5 +++++ src/p_user.c | 17 +++++++++++++---- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index f7e14e78f..f79b1e45e 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -710,6 +710,10 @@ static int player_set(lua_State *L) if (!lua_isnil(L, 3)) mo = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); P_SetTarget(&plr->awayviewmobj, mo); + if (plr == &players[displayplayer]) + P_ResetCamera(plr, &camera); // reset p1 camera on p1 getting an awayviewmobj + else if (splitscreen && plr == &players[secondarydisplayplayer]) + P_ResetCamera(plr, &camera2); // reset p2 camera on p2 getting an awayviewmobj } else if (fastcmp(field,"awayviewtics")) { diff --git a/src/p_spec.c b/src/p_spec.c index aa04a723e..8489a227f 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -2669,6 +2669,11 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) { P_SetTarget(&mo->player->awayviewmobj, altview); mo->player->awayviewtics = line->args[1]; + + if (mo->player == &players[displayplayer]) + P_ResetCamera(mo->player, &camera); // reset p1 camera on p1 getting an awayviewmobj + else if (splitscreen && mo->player == &players[secondarydisplayplayer]) + P_ResetCamera(mo->player, &camera2); // reset p2 camera on p2 getting an awayviewmobj } aim = udmf ? altview->spawnpoint->pitch : line->args[2]; diff --git a/src/p_user.c b/src/p_user.c index 0f3282da5..42fd0c310 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -11507,15 +11507,24 @@ void P_PlayerThink(player_t *player) if (player->awayviewmobj && P_MobjWasRemoved(player->awayviewmobj)) { P_SetTarget(&player->awayviewmobj, NULL); // remove awayviewmobj asap if invalid - player->awayviewtics = 0; // reset to zero + player->awayviewtics = 1; // reset to one, the below code will immediately set it to zero + } + + if (player->awayviewtics && player->awayviewtics != -1) + { + player->awayviewtics--; + if (!(player->awayviewtics)) + { + if (player == &players[displayplayer]) + P_ResetCamera(player, &camera); // reset p1 camera on p1 running out of awayviewtics + else if (splitscreen && player == &players[secondarydisplayplayer]) + P_ResetCamera(player, &camera2); // reset p2 camera on p2 running out of awayviewtics + } } if (player->flashcount) player->flashcount--; - if (player->awayviewtics && player->awayviewtics != -1) - player->awayviewtics--; - /// \note do this in the cheat code if (player->pflags & PF_NOCLIP) player->mo->flags |= MF_NOCLIP; From 7fa7653494dace135afd2fb84184c73bd51c1609 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 5 Jun 2023 13:54:09 -0400 Subject: [PATCH 191/586] Port increment_move radius clamps from Ring Racers Fixes inconsistencies with thin players, like with Liftoff Gantry's scale section, and with large characters colliding with steep slopes instead of going up them. --- src/p_map.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index 27d5ea781..107048957 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -2728,8 +2728,22 @@ increment_move fixed_t thingtop; floatok = false; - if (radius < MAXRADIUS/2) - radius = MAXRADIUS/2; + // This makes sure that there are no freezes from computing extremely small movements. + // Originally was MAXRADIUS/2, but that can cause some bad inconsistencies for small players. + radius = max(radius, thing->scale); + + // And we also have to prevent Big Large (tm) movements, as those can skip too far + // across slopes and cause us to fail step up checks on them when we otherwise shouldn't. + radius = min(radius, 16 * thing->scale); + + // (This whole "step" system is flawed; it was OK before, but the addition of slopes has + // exposed the problems with doing it like this. The right thing to do would be to use + // raycasting for physics to fix colliding in weird order, double-checking collisions, + // randomly colliding with slopes instead of going up them, etc. I don't feel like porting + // that from RR, as its both a huge sweeping change and still incomplete at the time of + // writing. Clamping radius to make our steps more precise will work just fine as long + // as you keep all of your crazy intentions to poke any of the other deep-rooted movement + // code to yourself. -- Sal 6/5/2023) do { if (thing->flags & MF_NOCLIP) { From 1cc870485dd93445bb4933be98dc58b1cdafee5b Mon Sep 17 00:00:00 2001 From: spherallic Date: Tue, 15 Mar 2022 20:35:06 +0100 Subject: [PATCH 192/586] Increase unlockable limits: - MAXUNLOCKABLES from 32 to 80 - MAXEXTRAEMBLEMS from 16 to 48 - COMPAT_GAMEDATA_ID is used to account for the old values to prevent losing records. - Also fixes linedef actions 319/320. --- src/g_game.c | 32 +++++++++++++++++++++++--------- src/m_cond.h | 4 ++-- src/m_menu.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ src/r_skins.c | 3 ++- 4 files changed, 75 insertions(+), 12 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index b23980044..47e670bfe 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -4309,6 +4309,12 @@ void G_LoadGameData(gamedata_t *data) // Stop saving, until we successfully load it again. data->loaded = false; + // Backwards compat stuff + INT32 max_emblems = MAXEMBLEMS; + INT32 max_extraemblems = MAXEXTRAEMBLEMS; + INT32 max_unlockables = MAXUNLOCKABLES; + INT32 max_conditionsets = MAXCONDITIONSETS; + // Clear things so previously read gamedata doesn't transfer // to new gamedata G_ClearRecords(data); // main and nights records @@ -4325,7 +4331,7 @@ void G_LoadGameData(gamedata_t *data) { // Don't load, but do save. (essentially, reset) data->loaded = true; - return; + return; } length = FIL_ReadFile(va(pandf, srb2home, gamedatafilename), &savebuffer); @@ -4355,6 +4361,14 @@ void G_LoadGameData(gamedata_t *data) I_Error("Game data is from another version of SRB2.\nDelete %s(maybe in %s) and try again.", gamedatafilename, gdfolder); } +#ifdef COMPAT_GAMEDATA_ID // Account for lower MAXUNLOCKABLES and MAXEXTRAEMBLEMS from older versions + if (versionID == COMPAT_GAMEDATA_ID) + { + max_extraemblems = 16; + max_unlockables = 32; + } +#endif + data->totalplaytime = READUINT32(save_p); #ifdef COMPAT_GAMEDATA_ID @@ -4393,31 +4407,31 @@ void G_LoadGameData(gamedata_t *data) goto datacorrupt; // To save space, use one bit per collected/achieved/unlocked flag - for (i = 0; i < MAXEMBLEMS;) + for (i = 0; i < max_emblems;) { rtemp = READUINT8(save_p); - for (j = 0; j < 8 && j+i < MAXEMBLEMS; ++j) + for (j = 0; j < 8 && j+i < max_emblems; ++j) data->collected[j+i] = ((rtemp >> j) & 1); i += j; } - for (i = 0; i < MAXEXTRAEMBLEMS;) + for (i = 0; i < max_extraemblems;) { rtemp = READUINT8(save_p); - for (j = 0; j < 8 && j+i < MAXEXTRAEMBLEMS; ++j) + for (j = 0; j < 8 && j+i < max_extraemblems; ++j) data->extraCollected[j+i] = ((rtemp >> j) & 1); i += j; } - for (i = 0; i < MAXUNLOCKABLES;) + for (i = 0; i < max_unlockables;) { rtemp = READUINT8(save_p); - for (j = 0; j < 8 && j+i < MAXUNLOCKABLES; ++j) + for (j = 0; j < 8 && j+i < max_unlockables; ++j) data->unlocked[j+i] = ((rtemp >> j) & 1); i += j; } - for (i = 0; i < MAXCONDITIONSETS;) + for (i = 0; i < max_conditionsets;) { rtemp = READUINT8(save_p); - for (j = 0; j < 8 && j+i < MAXCONDITIONSETS; ++j) + for (j = 0; j < 8 && j+i < max_conditionsets; ++j) data->achieved[j+i] = ((rtemp >> j) & 1); i += j; } diff --git a/src/m_cond.h b/src/m_cond.h index 6a3da79ec..95c3e1ebe 100644 --- a/src/m_cond.h +++ b/src/m_cond.h @@ -139,8 +139,8 @@ typedef struct // you seriously need to get a life. #define MAXCONDITIONSETS 128 #define MAXEMBLEMS 512 -#define MAXEXTRAEMBLEMS 16 -#define MAXUNLOCKABLES 32 +#define MAXEXTRAEMBLEMS 48 +#define MAXUNLOCKABLES 80 /** Time attack information, currently a very small structure. */ diff --git a/src/m_menu.c b/src/m_menu.c index f9f52335d..1c064d228 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -728,6 +728,54 @@ static menuitem_t SR_MainMenu[] = {IT_DISABLED, NULL, "", NULL, 0}, // Custom30 {IT_DISABLED, NULL, "", NULL, 0}, // Custom31 {IT_DISABLED, NULL, "", NULL, 0}, // Custom32 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom33 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom34 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom35 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom36 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom37 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom38 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom39 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom40 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom41 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom42 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom43 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom44 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom45 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom46 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom47 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom48 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom49 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom50 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom51 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom52 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom53 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom54 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom55 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom56 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom57 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom58 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom59 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom60 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom61 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom62 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom63 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom64 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom65 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom66 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom67 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom68 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom69 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom70 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom71 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom72 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom73 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom74 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom75 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom76 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom77 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom78 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom79 + {IT_DISABLED, NULL, "", NULL, 0}, // Custom80 }; diff --git a/src/r_skins.c b/src/r_skins.c index 2c031ee85..5bcde27b1 100644 --- a/src/r_skins.c +++ b/src/r_skins.c @@ -190,7 +190,8 @@ UINT32 R_GetSkinAvailabilities(void) // 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"); + // 2022/03/15: MAXUNLOCKABLES is now higher than 32 + I_Error("Too many unlockable characters! (maximum is 32)\n"); return 0; } From 99f09339866e3fc30d100d7353d0866a41ed0981 Mon Sep 17 00:00:00 2001 From: spherallic Date: Sun, 20 Mar 2022 14:10:18 +0100 Subject: [PATCH 193/586] Change how SR_MainMenu is initialized. --- src/m_menu.c | 93 ++++------------------------------------------------ 1 file changed, 7 insertions(+), 86 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 1c064d228..51f5b7173 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -693,90 +693,10 @@ static menuitem_t SR_PandorasBox[] = }; // Sky Room Custom Unlocks -static menuitem_t SR_MainMenu[] = +static menuitem_t SR_MainMenu[MAXUNLOCKABLES+1] = { {IT_STRING|IT_SUBMENU,NULL, "Extras Checklist", &SR_UnlockChecklistDef, 0}, - {IT_DISABLED, NULL, "", NULL, 0}, // Custom1 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom2 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom3 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom4 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom5 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom6 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom7 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom8 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom9 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom10 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom11 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom12 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom13 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom14 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom15 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom16 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom17 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom18 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom19 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom20 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom21 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom22 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom23 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom24 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom25 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom26 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom27 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom28 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom29 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom30 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom31 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom32 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom33 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom34 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom35 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom36 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom37 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom38 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom39 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom40 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom41 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom42 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom43 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom44 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom45 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom46 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom47 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom48 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom49 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom50 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom51 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom52 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom53 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom54 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom55 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom56 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom57 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom58 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom59 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom60 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom61 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom62 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom63 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom64 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom65 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom66 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom67 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom68 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom69 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom70 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom71 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom72 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom73 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom74 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom75 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom76 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom77 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom78 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom79 - {IT_DISABLED, NULL, "", NULL, 0}, // Custom80 - + // The remaining (MAXUNLOCKABLES) items are now initialized in M_SecretsMenu }; static menuitem_t SR_LevelSelectMenu[] = @@ -8177,14 +8097,15 @@ static void M_SecretsMenu(INT32 choice) (void)choice; - // Clear all before starting - for (i = 1; i < MAXUNLOCKABLES+1; ++i) - SR_MainMenu[i].status = IT_DISABLED; + // Initialize array with placeholder entries + menuitem_t placeholder = {IT_DISABLED, NULL, "", NULL, 0}; + for (i = 1; i <= MAXUNLOCKABLES; ++i) + SR_MainMenu[i] = placeholder; memset(skyRoomMenuTranslations, 0, sizeof(skyRoomMenuTranslations)); memset(done, 0, sizeof(done)); - for (i = 1; i < MAXUNLOCKABLES+1; ++i) + for (i = 1; i <= MAXUNLOCKABLES; ++i) { curheight = UINT16_MAX; ul = -1; From d9937953ad1d1e57c08da5f684c7021dcd5a5663 Mon Sep 17 00:00:00 2001 From: spherallic Date: Wed, 24 May 2023 12:54:19 +0200 Subject: [PATCH 194/586] Fix linedef type 319/320 again --- 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 71ea145b9..d1973d951 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1808,7 +1808,7 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller { // An unlockable itself must be unlocked! INT32 unlockid = triggerline->args[1]; - if (unlockid < 0 || unlockid >= MAXUNLOCKABLES) // limited by unlockable count + if (unlockid <= 0 || unlockid > MAXUNLOCKABLES) // limited by unlockable count { CONS_Debug(DBG_GAMELOGIC, "Unlockable check (sidedef %hu): bad unlockable ID %d\n", triggerline->sidenum[0], unlockid); return false; From d8dd9884511b9be445dbd4211fbe94747d5cf9ff Mon Sep 17 00:00:00 2001 From: spherallic Date: Thu, 16 Mar 2023 11:47:21 +0100 Subject: [PATCH 195/586] Don't cancel P_LinedefExecute early --- src/p_spec.c | 52 ++++++++++++++++++++++++---------------------------- src/p_spec.h | 2 +- 2 files changed, 25 insertions(+), 29 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index 71ea145b9..2f6e89c28 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1741,14 +1741,13 @@ static boolean P_ActivateLinedefExecutorsInSector(line_t *triggerline, mobj_t *a /** Used by P_LinedefExecute to check a trigger linedef's conditions * The linedef executor specials in the trigger linedef's sector are run if all conditions are met. - * Return false cancels P_LinedefExecute, this happens if a condition is not met. * * \param triggerline Trigger linedef to check conditions for; should NEVER be NULL. * \param actor Object initiating the action; should not be NULL. * \param caller Sector in which the action was started. May be NULL. * \sa P_ProcessLineSpecial, P_LinedefExecute */ -boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller) +void P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller) { INT16 specialtype = triggerline->special; @@ -1761,12 +1760,12 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller if (caller->triggerer == TO_PLAYEREMERALDS) { if (!(ALL7EMERALDS(emeralds))) - return false; + return; } else if (caller->triggerer == TO_PLAYERNIGHTS) { if (!P_CheckPlayerMareOld(triggerline)) - return false; + return; } } @@ -1774,22 +1773,22 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller { case 303: if (!P_CheckPlayerRings(triggerline, actor)) - return false; + return; break; case 305: if (!(actor && actor->player && actor->player->charability == triggerline->args[1])) - return false; + return; break; case 309: // Only red/blue team members can activate this. if (!(actor && actor->player)) - return false; + return; if (actor->player->ctfteam != ((triggerline->args[1] == TMT_RED) ? 1 : 2)) - return false; + return; break; case 314: if (!P_CheckPushables(triggerline, caller)) - return false; + return; break; case 317: { // Unlockable triggers required @@ -1798,10 +1797,10 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller if (trigid < 0 || trigid > 31) // limited by 32 bit variable { CONS_Debug(DBG_GAMELOGIC, "Unlockable trigger (sidedef %hu): bad trigger ID %d\n", triggerline->sidenum[0], trigid); - return false; + return; } else if (!(unlocktriggers & (1 << trigid))) - return false; + return; } break; case 319: @@ -1811,10 +1810,10 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller if (unlockid < 0 || unlockid >= MAXUNLOCKABLES) // limited by unlockable count { CONS_Debug(DBG_GAMELOGIC, "Unlockable check (sidedef %hu): bad unlockable ID %d\n", triggerline->sidenum[0], unlockid); - return false; + return; } else if (!(serverGamedata->unlocked[unlockid-1])) - return false; + return; } break; case 321: @@ -1822,7 +1821,7 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller if (triggerline->callcount > 0) { if (--triggerline->callcount > 0) - return false; + return; } break; case 323: // nightserize @@ -1830,15 +1829,15 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller case 327: // nights lap case 329: // nights egg capsule touch if (!P_CheckNightsTriggerLine(triggerline, actor)) - return false; + return; break; case 331: if (!(actor && actor->player)) - return false; + return; if (!triggerline->stringargs[0]) - return false; + return; if (!(stricmp(triggerline->stringargs[0], skins[actor->player->skin].name) == 0) ^ !!(triggerline->args[1])) - return false; + return; break; case 334: // object dye { @@ -1846,22 +1845,22 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller UINT16 color = (actor->player ? actor->player->powers[pw_dye] : actor->color); if (!!(triggerline->args[1]) ^ (triggercolor != color)) - return false; + return; } break; case 337: // emerald check if (!P_CheckEmeralds(triggerline->args[2], (UINT16)triggerline->args[1])) - return false; + return; break; case 340: // NiGHTS mare if (!P_CheckPlayerMare(triggerline)) - return false; + return; break; case 343: // gravity check if (triggerline->args[1] == TMG_TEMPREVERSE && (!(actor->flags2 & MF2_OBJECTFLIP) != !(actor->player->powers[pw_gravityboots]))) - return false; + return; if ((triggerline->args[1] == TMG_NORMAL) != !(actor->eflags & MFE_VERTICALFLIP)) - return false; + return; break; default: break; @@ -1872,7 +1871,7 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller ///////////////////////////////// if (!P_ActivateLinedefExecutorsInSector(triggerline, actor, caller)) - return false; + return; // "Trigger on X calls" linedefs reset if args[2] is set if (specialtype == 321 && triggerline->args[2]) @@ -1905,8 +1904,6 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller && triggerline->args[0] == TMT_ONCE) triggerline->special = 0; } - - return true; } /** Runs a linedef executor. @@ -1959,8 +1956,7 @@ void P_LinedefExecute(INT16 tag, mobj_t *actor, sector_t *caller) if (lines[masterline].special == 321 && lines[masterline].args[0] > TMXT_EACHTIMEMASK) // Trigger after X calls continue; - if (!P_RunTriggerLinedef(&lines[masterline], actor, caller)) - return; // cancel P_LinedefExecute if function returns false + P_RunTriggerLinedef(&lines[masterline], actor, caller); // Even if it fails, there might be more linedefs to trigger } } diff --git a/src/p_spec.h b/src/p_spec.h index 91dfccb70..c8701749f 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -527,7 +527,7 @@ boolean P_IsMobjTouchingPolyobj(mobj_t *mo, polyobj_t *po, sector_t *polysec); void P_SwitchWeather(INT32 weathernum); -boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller); +void P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller); void P_LinedefExecute(INT16 tag, mobj_t *actor, sector_t *caller); void P_RunNightserizeExecutors(mobj_t *actor); void P_RunDeNightserizeExecutors(mobj_t *actor); From b8a25ae53c5db7017adf2411ebae254ac2ed85c1 Mon Sep 17 00:00:00 2001 From: sphere Date: Tue, 13 Jun 2023 00:05:58 +0000 Subject: [PATCH 196/586] Add interpolation to hitbox viewer, tweak hitbox colors --- src/d_netcmd.c | 1 + src/hardware/hw_main.c | 19 ++++++++++++++++--- src/r_bbox.c | 14 ++++++++++++-- src/r_things.c | 22 ++++++++++++++++++---- src/screen.h | 2 +- 5 files changed, 48 insertions(+), 10 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 420621a77..0f859a569 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -873,6 +873,7 @@ void D_RegisterClientCommands(void) // screen.c CV_RegisterVar(&cv_fullscreen); CV_RegisterVar(&cv_renderview); + CV_RegisterVar(&cv_renderhitboxinterpolation); CV_RegisterVar(&cv_renderhitbox); CV_RegisterVar(&cv_renderer); CV_RegisterVar(&cv_scr_depth); diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 09235ce62..e7550fd6e 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5686,9 +5686,22 @@ static void HWR_ProjectBoundingBox(mobj_t *thing) if (!R_ThingBoundingBoxVisible(thing)) return; + // uncapped/interpolation + boolean interpolate = cv_renderhitboxinterpolation.value; + interpmobjstate_t interp = {0}; + + if (R_UsingFrameInterpolation() && !paused && interpolate) + { + R_InterpolateMobjState(thing, rendertimefrac, &interp); + } + else + { + R_InterpolateMobjState(thing, FRACUNIT, &interp); + } + // transform the origin point - tr_x = FIXED_TO_FLOAT(thing->x) - gl_viewx; - tr_y = FIXED_TO_FLOAT(thing->y) - gl_viewy; + tr_x = FIXED_TO_FLOAT(interp.x) - gl_viewx; + tr_y = FIXED_TO_FLOAT(interp.y) - gl_viewy; // rotation around vertical axis tz = (tr_x * gl_viewcos) + (tr_y * gl_viewsin); @@ -5707,7 +5720,7 @@ static void HWR_ProjectBoundingBox(mobj_t *thing) vis->x2 = tr_x + rad; vis->z1 = tr_y - rad; vis->z2 = tr_y + rad; - vis->gz = FIXED_TO_FLOAT(thing->z); + vis->gz = FIXED_TO_FLOAT(interp.z); vis->gzt = vis->gz + FIXED_TO_FLOAT(thing->height); vis->mobj = thing; diff --git a/src/r_bbox.c b/src/r_bbox.c index b45007bb2..7ed693fd0 100644 --- a/src/r_bbox.c +++ b/src/r_bbox.c @@ -35,6 +35,7 @@ static CV_PossibleValue_t renderhitbox_cons_t[] = { {0}}; consvar_t cv_renderhitbox = CVAR_INIT ("renderhitbox", "Off", 0, renderhitbox_cons_t, NULL); +consvar_t cv_renderhitboxinterpolation = CVAR_INIT ("renderhitbox_interpolation", "On", CV_SAVE, CV_OnOff, NULL); struct bbox_col { INT32 x; @@ -179,12 +180,21 @@ UINT8 R_GetBoundingBoxColor(mobj_t *thing) if (flags & (MF_NOCLIPTHING)) return 7; // BFBFBF - if (flags & (MF_BOSS|MF_MISSILE|MF_ENEMY|MF_PAIN)) + if (flags & (MF_BOSS|MF_ENEMY)) return 35; // F00 + if (flags & (MF_MISSILE|MF_PAIN)) + return 54; // F70 + if (flags & (MF_SPECIAL|MF_MONITOR)) return 73; // FF0 + if (flags & MF_PUSHABLE) + return 112; // 0F0 + + if (flags & (MF_SPRING)) + return 181; // F0F + if (flags & (MF_NOCLIP)) return 152; // 00F @@ -299,7 +309,7 @@ boolean R_ThingBoundingBoxVisible(mobj_t *thing) return is_tangible(thing); case RENDERHITBOX_RINGS: - return (thing->type == MT_RING); + return (thing->type == MT_RING || thing->type == MT_BLUESPHERE); default: return false; diff --git a/src/r_things.c b/src/r_things.c index 7eecb041e..38237e5b3 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1436,19 +1436,33 @@ static void R_ProjectBoundingBox(mobj_t *thing, vissprite_t *vis) return; } + // uncapped/interpolation + boolean interpolate = cv_renderhitboxinterpolation.value; + interpmobjstate_t interp = {0}; + + // do interpolation + if (R_UsingFrameInterpolation() && !paused && interpolate) + { + R_InterpolateMobjState(thing, rendertimefrac, &interp); + } + else + { + R_InterpolateMobjState(thing, FRACUNIT, &interp); + } + // 1--3 // | | // 0--2 // start in the (0) corner - gx = thing->x - thing->radius - viewx; - gy = thing->y - thing->radius - viewy; + gx = interp.x - thing->radius - viewx; + gy = interp.y - thing->radius - viewy; tz = FixedMul(gx, viewcos) + FixedMul(gy, viewsin); // thing is behind view plane? // if parent vis is visible, ignore this - if (!vis && (tz < FixedMul(MINZ, thing->scale))) + if (!vis && (tz < FixedMul(MINZ, interp.scale))) { return; } @@ -1473,7 +1487,7 @@ static void R_ProjectBoundingBox(mobj_t *thing, vissprite_t *vis) box->scale = 2 * FixedMul(thing->radius, viewsin); box->xscale = 2 * FixedMul(thing->radius, viewcos); - box->pz = thing->z; + box->pz = interp.z; box->pzt = box->pz + box->thingheight; box->gzt = box->pzt; diff --git a/src/screen.h b/src/screen.h index a0e04f85e..b021a419d 100644 --- a/src/screen.h +++ b/src/screen.h @@ -199,7 +199,7 @@ extern CV_PossibleValue_t cv_renderer_t[]; extern INT32 scr_bpp; extern UINT8 *scr_borderpatch; // patch used to fill the view borders -extern consvar_t cv_scr_width, cv_scr_height, cv_scr_depth, cv_renderview, cv_renderer, cv_renderhitbox, cv_fullscreen; +extern consvar_t cv_scr_width, cv_scr_height, cv_scr_depth, cv_renderview, cv_renderer, cv_renderhitbox, cv_renderhitboxinterpolation, cv_fullscreen; // wait for page flipping to end or not extern consvar_t cv_vidwait; extern consvar_t cv_timescale; From 37223f13f1319df814d683f86b3a61ff83b1b123 Mon Sep 17 00:00:00 2001 From: spherallic Date: Tue, 13 Jun 2023 10:38:44 +0200 Subject: [PATCH 197/586] Remove debug print on generic item circle spawn --- src/p_mobj.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index e79977c48..a04351ae7 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -13687,7 +13687,6 @@ void P_SpawnItemPattern(mapthing_t *mthing, boolean bonustime) UINT8 numitemtypes; if (!udmf) return; - CONS_Printf("Itemstring: %s\n", mthing->stringargs[0]); P_ParseItemTypes(mthing->stringargs[0], itemtypes, &numitemtypes); P_SpawnItemCircle(mthing, itemtypes, numitemtypes, mthing->args[0], mthing->args[1] << FRACBITS, bonustime); return; From 4d4910c918fde1a45bec771c84f688d8ef28cfc9 Mon Sep 17 00:00:00 2001 From: Zwip-Zwap Zapony Date: Tue, 13 Jun 2023 14:02:19 +0200 Subject: [PATCH 198/586] Use 99999999 instead of 86400, make "MIN" 0 Nines might be more pleasing than an exact number for con_hudtime It'd be bad to make "MIN" in an old config suddenly start displaying lines for con_hudlines --- src/console.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/console.c b/src/console.c index b99b13720..d432bba72 100644 --- a/src/console.c +++ b/src/console.c @@ -125,12 +125,12 @@ static void CONS_backcolor_Change(void); static char con_buffer[CON_BUFFERSIZE]; // how many seconds the hud messages lasts on the screen -// CV_Unsigned can overflow when multiplied by TICRATE later, so let's use a 24-hour limit instead -static CV_PossibleValue_t hudtime_cons_t[] = {{0, "MIN"}, {86400, "MAX"}, {0, NULL}}; +// CV_Unsigned can overflow when multiplied by TICRATE later, so let's use a 3-year limit instead +static CV_PossibleValue_t hudtime_cons_t[] = {{0, "MIN"}, {99999999, "MAX"}, {0, NULL}}; static consvar_t cons_hudtime = CVAR_INIT ("con_hudtime", "5", CV_SAVE, hudtime_cons_t, NULL); // number of lines displayed on the HUD -static CV_PossibleValue_t hudlines_cons_t[] = {{1, "MIN"}, {MAXHUDLINES, "MAX"}, {0, "None"}, {0, NULL}}; +static CV_PossibleValue_t hudlines_cons_t[] = {{0, "MIN"}, {MAXHUDLINES, "MAX"}, {0, NULL}}; static consvar_t cons_hudlines = CVAR_INIT ("con_hudlines", "5", CV_CALL|CV_SAVE, hudlines_cons_t, CONS_hudlines_Change); // number of lines console move per frame From f921a9987d11dc805aaca944577ce982ed800068 Mon Sep 17 00:00:00 2001 From: Zwip-Zwap Zapony Date: Tue, 13 Jun 2023 19:06:12 +0200 Subject: [PATCH 199/586] Interpolate models when scaling mobjs --- 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 6b1d0c6fc..38e8e8fc4 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1660,7 +1660,7 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) #endif // SRB2CBTODO: MD2 scaling support - finalscale *= FIXED_TO_FLOAT(spr->mobj->scale); + finalscale *= FIXED_TO_FLOAT(interp.scale); p.flip = atransform.flip; #ifdef USE_FTRANSFORM_MIRROR From 5c3f66dc36371beb02f4e7a74ecca79fc7c5beed Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 13 Jun 2023 21:26:40 -0400 Subject: [PATCH 200/586] Remove "singletics" code in F_WriteText This was added in 2.1 for whatever reason. All instances of F_WriteText are already capped to the framerate properly by other means; so this code being present just makes timing differences between different netgame clients / other inaccuracies cause the text speed to slow down more than intended. --- src/f_finale.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/f_finale.c b/src/f_finale.c index f529b4564..299a6a054 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -224,7 +224,6 @@ static INT32 cutscene_writeptr = 0; static INT32 cutscene_textcount = 0; static INT32 cutscene_textspeed = 0; static UINT8 cutscene_boostspeed = 0; -static tic_t cutscene_lasttextwrite = 0; // STJR Intro char stjrintro[9] = "STJRI000"; @@ -240,11 +239,6 @@ static UINT8 F_WriteText(void) { INT32 numtowrite = 1; const char *c; - tic_t ltw = I_GetTime(); - - if (cutscene_lasttextwrite == ltw) - return 1; // singletics prevention - cutscene_lasttextwrite = ltw; if (cutscene_boostspeed) { From bed7e434e7fbc340fa36424a4f1eb67848e8b164 Mon Sep 17 00:00:00 2001 From: spherallic Date: Sat, 10 Jun 2023 12:12:41 +0200 Subject: [PATCH 201/586] Add absolute z height flag for mapthings in UDMF --- src/doomdata.h | 4 ++++ src/p_mobj.c | 17 +++++++++-------- src/p_mobj.h | 2 +- src/p_setup.c | 2 ++ 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/doomdata.h b/src/doomdata.h index 4c5bdefaf..45cbb2557 100644 --- a/src/doomdata.h +++ b/src/doomdata.h @@ -62,6 +62,10 @@ enum #define MTF_AMBUSH 8 // Do not use bit five or after, as they are used for object z-offsets. +// Unless it's exclusive to UDMF. + +// Flag to use Z as absolute spawn height, ignoring the floor and ceiling. +#define MTF_ABSOLUTEZ 16 #if defined(_MSC_VER) #pragma pack(1) diff --git a/src/p_mobj.c b/src/p_mobj.c index a04351ae7..0622ff601 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11812,7 +11812,7 @@ void P_MovePlayerToStarpost(INT32 playernum) mapthing_t *huntemeralds[MAXHUNTEMERALDS]; INT32 numhuntemeralds; -fixed_t P_GetMobjSpawnHeight(const mobjtype_t mobjtype, const fixed_t x, const fixed_t y, const fixed_t dz, const fixed_t offset, const boolean flip, const fixed_t scale) +fixed_t P_GetMobjSpawnHeight(const mobjtype_t mobjtype, const fixed_t x, const fixed_t y, const fixed_t dz, const fixed_t offset, const boolean flip, const fixed_t scale, const boolean absolutez) { const subsector_t *ss = R_PointInSubsector(x, y); @@ -11822,9 +11822,9 @@ fixed_t P_GetMobjSpawnHeight(const mobjtype_t mobjtype, const fixed_t x, const f // Establish height. if (flip) - return P_GetSectorCeilingZAt(ss->sector, x, y) - dz - FixedMul(scale, offset + mobjinfo[mobjtype].height); + return (absolutez ? dz : P_GetSectorCeilingZAt(ss->sector, x, y) - dz) - FixedMul(scale, offset + mobjinfo[mobjtype].height); else - return P_GetSectorFloorZAt(ss->sector, x, y) + dz + FixedMul(scale, offset); + return (absolutez ? dz : P_GetSectorFloorZAt(ss->sector, x, y) + dz) + FixedMul(scale, offset); } fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mthing, const fixed_t x, const fixed_t y) @@ -11832,6 +11832,7 @@ fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mt fixed_t dz = mthing->z << FRACBITS; // Base offset from the floor. fixed_t offset = 0; // Specific scaling object offset. boolean flip = (!!(mobjinfo[mobjtype].flags & MF_SPAWNCEILING) ^ !!(mthing->options & MTF_OBJECTFLIP)); + boolean absolutez = !!(mthing->options & MTF_ABSOLUTEZ); switch (mobjtype) { @@ -11887,7 +11888,7 @@ fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mt offset += mthing->args[0] ? 0 : 24*FRACUNIT; } - if (!(dz + offset)) // Snap to the surfaces when there's no offset set. + if (!(dz + offset) && !absolutez) // Snap to the surfaces when there's no offset set. { if (flip) return ONCEILINGZ; @@ -11895,7 +11896,7 @@ fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mt return ONFLOORZ; } - return P_GetMobjSpawnHeight(mobjtype, x, y, dz, offset, flip, mthing->scale); + return P_GetMobjSpawnHeight(mobjtype, x, y, dz, offset, flip, mthing->scale, absolutez); } static boolean P_SpawnNonMobjMapThing(mapthing_t *mthing) @@ -13389,7 +13390,7 @@ void P_SpawnHoop(mapthing_t *mthing) vector4_t v, res; fixed_t x = mthing->x << FRACBITS; fixed_t y = mthing->y << FRACBITS; - fixed_t z = P_GetMobjSpawnHeight(MT_HOOP, x, y, mthing->z << FRACBITS, 0, false, mthing->scale); + fixed_t z = P_GetMobjSpawnHeight(MT_HOOP, x, y, mthing->z << FRACBITS, 0, false, mthing->scale, !!(mthing->options & MTF_ABSOLUTEZ)); hoopcenter = P_SpawnMobj(x, y, z, MT_HOOPCENTER); hoopcenter->spawnpoint = mthing; @@ -13516,7 +13517,7 @@ static void P_SpawnItemRow(mapthing_t *mthing, mobjtype_t *itemtypes, UINT8 numi itemtypes[r] = P_GetMobjtypeSubstitute(&dummything, itemtypes[r]); } } - z = P_GetMobjSpawnHeight(itemtypes[0], x, y, z, 0, mthing->options & MTF_OBJECTFLIP, mthing->scale); + z = P_GetMobjSpawnHeight(itemtypes[0], x, y, z, 0, mthing->options & MTF_OBJECTFLIP, mthing->scale, !!(mthing->options & MTF_ABSOLUTEZ)); for (r = 0; r < numitems; r++) { @@ -13575,7 +13576,7 @@ static void P_SpawnItemCircle(mapthing_t *mthing, mobjtype_t *itemtypes, UINT8 n itemtypes[i] = P_GetMobjtypeSubstitute(&dummything, itemtypes[i]); } } - z = P_GetMobjSpawnHeight(itemtypes[0], x, y, z, 0, false, mthing->scale); + z = P_GetMobjSpawnHeight(itemtypes[0], x, y, z, 0, false, mthing->scale, !!(mthing->options & MTF_ABSOLUTEZ)); for (i = 0; i < numitems; i++) { diff --git a/src/p_mobj.h b/src/p_mobj.h index 6717c4add..d7d660078 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -489,7 +489,7 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing); void P_MovePlayerToStarpost(INT32 playernum); void P_AfterPlayerSpawn(INT32 playernum); -fixed_t P_GetMobjSpawnHeight(const mobjtype_t mobjtype, const fixed_t x, const fixed_t y, const fixed_t dz, const fixed_t offset, const boolean flip, const fixed_t scale); +fixed_t P_GetMobjSpawnHeight(const mobjtype_t mobjtype, const fixed_t x, const fixed_t y, const fixed_t dz, const fixed_t offset, const boolean flip, const fixed_t scale, const boolean absolutez); fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mthing, const fixed_t x, const fixed_t y); mobj_t *P_SpawnMapThing(mapthing_t *mthing); diff --git a/src/p_setup.c b/src/p_setup.c index 74645e877..167e1baac 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1916,6 +1916,8 @@ static void ParseTextmapThingParameter(UINT32 i, const char *param, const char * // Flags else if (fastcmp(param, "flip") && fastcmp("true", val)) mapthings[i].options |= MTF_OBJECTFLIP; + else if (fastcmp(param, "absolutez") && fastcmp("true", val)) + mapthings[i].options |= MTF_ABSOLUTEZ; else if (fastncmp(param, "stringarg", 9) && strlen(param) > 9) { From f416c6a98d78cefc6acd9d94396ce9e438f784c3 Mon Sep 17 00:00:00 2001 From: spherallic Date: Sun, 11 Jun 2023 12:42:10 +0200 Subject: [PATCH 202/586] Add absolute Z flag to MAPTHINGFLAG_LIST --- src/deh_lua.c | 4 ++-- src/deh_tables.c | 5 +++-- src/deh_tables.h | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/deh_lua.c b/src/deh_lua.c index 6dabb7e2d..a8bc63377 100644 --- a/src/deh_lua.c +++ b/src/deh_lua.c @@ -271,8 +271,8 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *word) } else if (fastncmp("MTF_", word, 4)) { p = word+4; - for (i = 0; i < 4; i++) - if (MAPTHINGFLAG_LIST[i] && fastcmp(p, MAPTHINGFLAG_LIST[i])) { + for (i = 0; MAPTHINGFLAG_LIST[i]; i++) + if (fastcmp(p, MAPTHINGFLAG_LIST[i])) { CacheAndPushConstant(L, word, ((lua_Integer)1< \t"\1", // \2 extern const char *const MOBJEFLAG_LIST[]; -extern const char *const MAPTHINGFLAG_LIST[4]; +extern const char *const MAPTHINGFLAG_LIST[]; extern const char *const PLAYERFLAG_LIST[]; extern const char *const GAMETYPERULE_LIST[]; extern const char *const ML_LIST[]; // Linedef flags From 90d95d13057a24b1556dd43fa02dd8b78a8a0b7f Mon Sep 17 00:00:00 2001 From: spherallic Date: Sun, 11 Jun 2023 13:40:18 +0200 Subject: [PATCH 203/586] Clean options field of binary-converted things --- src/p_mobj.c | 6 +++--- src/p_setup.c | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 0622ff601..b7295da4c 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -13390,7 +13390,7 @@ void P_SpawnHoop(mapthing_t *mthing) vector4_t v, res; fixed_t x = mthing->x << FRACBITS; fixed_t y = mthing->y << FRACBITS; - fixed_t z = P_GetMobjSpawnHeight(MT_HOOP, x, y, mthing->z << FRACBITS, 0, false, mthing->scale, !!(mthing->options & MTF_ABSOLUTEZ)); + fixed_t z = P_GetMobjSpawnHeight(MT_HOOP, x, y, mthing->z << FRACBITS, 0, false, mthing->scale, mthing->options & MTF_ABSOLUTEZ); hoopcenter = P_SpawnMobj(x, y, z, MT_HOOPCENTER); hoopcenter->spawnpoint = mthing; @@ -13517,7 +13517,7 @@ static void P_SpawnItemRow(mapthing_t *mthing, mobjtype_t *itemtypes, UINT8 numi itemtypes[r] = P_GetMobjtypeSubstitute(&dummything, itemtypes[r]); } } - z = P_GetMobjSpawnHeight(itemtypes[0], x, y, z, 0, mthing->options & MTF_OBJECTFLIP, mthing->scale, !!(mthing->options & MTF_ABSOLUTEZ)); + z = P_GetMobjSpawnHeight(itemtypes[0], x, y, z, 0, mthing->options & MTF_OBJECTFLIP, mthing->scale, mthing->options & MTF_ABSOLUTEZ); for (r = 0; r < numitems; r++) { @@ -13576,7 +13576,7 @@ static void P_SpawnItemCircle(mapthing_t *mthing, mobjtype_t *itemtypes, UINT8 n itemtypes[i] = P_GetMobjtypeSubstitute(&dummything, itemtypes[i]); } } - z = P_GetMobjSpawnHeight(itemtypes[0], x, y, z, 0, false, mthing->scale, !!(mthing->options & MTF_ABSOLUTEZ)); + z = P_GetMobjSpawnHeight(itemtypes[0], x, y, z, 0, false, mthing->scale, mthing->options & MTF_ABSOLUTEZ); for (i = 0; i < numitems; i++) { diff --git a/src/p_setup.c b/src/p_setup.c index 167e1baac..482330599 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -6681,7 +6681,6 @@ static void P_ConvertBinaryThingTypes(void) break; case 1704: //NiGHTS bumper mapthings[i].pitch = 30 * (((mapthings[i].options & 15) + 9) % 12); - mapthings[i].options &= ~0xF; break; case 1705: //Hoop case 1713: //Hoop (Customizable) @@ -6690,7 +6689,6 @@ static void P_ConvertBinaryThingTypes(void) mapthings[i].angle = (mapthings[i].extrainfo == 1) ? oldangle - 90 : ((oldangle >> 8)*360)/256; mapthings[i].pitch = (mapthings[i].extrainfo == 1) ? oldangle / 360 : ((oldangle & 255)*360)/256; mapthings[i].args[0] = (mapthings[i].type == 1705) ? 96 : (mapthings[i].options & 0xF)*16 + 32; - mapthings[i].options &= ~0xF; mapthings[i].type = 1713; break; } @@ -6718,6 +6716,9 @@ static void P_ConvertBinaryThingTypes(void) default: break; } + + // Clear binary thing height hacks, to prevent interfering with UDMF-only flags + mapthings[i].options &= 8; } } From 056d3dcf31ea2c7443b27eaf6982eda9f63d243f Mon Sep 17 00:00:00 2001 From: spherallic Date: Sun, 11 Jun 2023 17:15:36 +0200 Subject: [PATCH 204/586] Actually clear options field properly --- 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 482330599..66d7bff42 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -6718,7 +6718,7 @@ static void P_ConvertBinaryThingTypes(void) } // Clear binary thing height hacks, to prevent interfering with UDMF-only flags - mapthings[i].options &= 8; + mapthings[i].options &= 0xF; } } From 2f2de7d3d357e6e27369cb2fb51fceadefb1899b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Sun, 18 Jun 2023 18:05:16 +0200 Subject: [PATCH 205/586] Optimize field lookups in Lua metatables --- src/lua_consolelib.c | 56 +- src/lua_hudlib.c | 14 +- src/lua_infolib.c | 231 ++++++-- src/lua_maplib.c | 308 ++++++++--- src/lua_mobjlib.c | 235 +++++--- src/lua_playerlib.c | 1243 +++++++++++++++++++++++++++++++----------- src/lua_script.c | 36 +- src/lua_script.h | 4 +- src/lua_skinlib.c | 7 +- 9 files changed, 1597 insertions(+), 537 deletions(-) diff --git a/src/lua_consolelib.c b/src/lua_consolelib.c index dcaad1416..1d15b3b14 100644 --- a/src/lua_consolelib.c +++ b/src/lua_consolelib.c @@ -566,27 +566,59 @@ static luaL_Reg lib[] = { {NULL, NULL} }; +enum cvar_e +{ + cvar_name, + cvar_defaultvalue, + cvar_flags, + cvar_value, + cvar_string, + cvar_changed, +}; + +static const char *const cvar_opt[] = { + "name", + "defaultvalue", + "flags", + "value", + "string", + "changed", + NULL, +}; + +static int cvar_fields_ref = LUA_NOREF; + static int cvar_get(lua_State *L) { consvar_t *cvar = *(consvar_t **)luaL_checkudata(L, 1, META_CVAR); - const char *field = luaL_checkstring(L, 2); + enum cvar_e field = Lua_optoption(L, 2, -1, cvar_fields_ref); - if(fastcmp(field,"name")) + switch (field) + { + case cvar_name: lua_pushstring(L, cvar->name); - else if(fastcmp(field,"defaultvalue")) + break; + case cvar_defaultvalue: lua_pushstring(L, cvar->defaultvalue); - else if(fastcmp(field,"flags")) + break; + case cvar_flags: lua_pushinteger(L, cvar->flags); - else if(fastcmp(field,"value")) + break; + case cvar_value: lua_pushinteger(L, cvar->value); - else if(fastcmp(field,"string")) + break; + case cvar_string: lua_pushstring(L, cvar->string); - else if(fastcmp(field,"changed")) + break; + case cvar_changed: lua_pushboolean(L, cvar->changed); - else if (devparm) - return luaL_error(L, LUA_QL("consvar_t") " has no field named " LUA_QS, field); - else - return 0; + break; + default: + if (devparm) + return luaL_error(L, LUA_QL("consvar_t") " has no field named " LUA_QS, field); + else + return 0; + } return 1; } @@ -598,6 +630,8 @@ int LUA_ConsoleLib(lua_State *L) lua_setfield(L, -2, "__index"); lua_pop(L,1); + cvar_fields_ref = Lua_CreateFieldTable(L, cvar_opt); + // Set empty registry tables lua_newtable(L); lua_setfield(L, LUA_REGISTRYINDEX, "COM_Command"); diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 1a0599757..c7f67e93a 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -95,6 +95,8 @@ static const char *const patch_opt[] = { "topoffset", NULL}; +static int patch_fields_ref = LUA_NOREF; + // alignment types for v.drawString enum align { align_left = 0, @@ -196,6 +198,8 @@ static const char *const camera_opt[] = { "momz", NULL}; +static int camera_fields_ref = LUA_NOREF; + static int lib_getHudInfo(lua_State *L) { UINT32 i; @@ -276,7 +280,7 @@ static int colormap_get(lua_State *L) static int patch_get(lua_State *L) { patch_t *patch = *((patch_t **)luaL_checkudata(L, 1, META_PATCH)); - enum patch field = luaL_checkoption(L, 2, NULL, patch_opt); + enum patch field = Lua_optoption(L, 2, -1, patch_fields_ref); // patches are invalidated when switching renderers if (!patch) { @@ -316,7 +320,7 @@ static int patch_set(lua_State *L) static int camera_get(lua_State *L) { camera_t *cam = *((camera_t **)luaL_checkudata(L, 1, META_CAMERA)); - enum cameraf field = luaL_checkoption(L, 2, NULL, camera_opt); + enum cameraf field = Lua_optoption(L, 2, -1, camera_fields_ref); // cameras should always be valid unless I'm a nutter I_Assert(cam != NULL); @@ -372,7 +376,7 @@ static int camera_get(lua_State *L) 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); + enum cameraf field = Lua_optoption(L, 2, -1, camera_fields_ref); I_Assert(cam != NULL); @@ -1444,6 +1448,8 @@ int LUA_HudLib(lua_State *L) lua_setfield(L, -2, "__newindex"); lua_pop(L,1); + patch_fields_ref = Lua_CreateFieldTable(L, patch_opt); + luaL_newmetatable(L, META_CAMERA); lua_pushcfunction(L, camera_get); lua_setfield(L, -2, "__index"); @@ -1452,6 +1458,8 @@ int LUA_HudLib(lua_State *L) lua_setfield(L, -2, "__newindex"); lua_pop(L,1); + camera_fields_ref = Lua_CreateFieldTable(L, camera_opt); + luaL_register(L, "hud", lib_hud); return 0; } diff --git a/src/lua_infolib.c b/src/lua_infolib.c index 7388632d3..fb07ccebb 100644 --- a/src/lua_infolib.c +++ b/src/lua_infolib.c @@ -1106,75 +1106,161 @@ static int lib_mobjinfolen(lua_State *L) return 1; } +enum mobjinfo_e +{ + mobjinfo_doomednum, + mobjinfo_spawnstate, + mobjinfo_spawnhealth, + mobjinfo_seestate, + mobjinfo_seesound, + mobjinfo_reactiontime, + mobjinfo_attacksound, + mobjinfo_painstate, + mobjinfo_painchance, + mobjinfo_painsound, + mobjinfo_meleestate, + mobjinfo_missilestate, + mobjinfo_deathstate, + mobjinfo_xdeathstate, + mobjinfo_deathsound, + mobjinfo_speed, + mobjinfo_radius, + mobjinfo_height, + mobjinfo_dispoffset, + mobjinfo_mass, + mobjinfo_damage, + mobjinfo_activesound, + mobjinfo_flags, + mobjinfo_raisestate, +}; + +const char *const mobjinfo_opt[] = { + "doomednum", + "spawnstate", + "spawnhealth", + "seestate", + "seesound", + "reactiontime", + "attacksound", + "painstate", + "painchance", + "painsound", + "meleestate", + "missilestate", + "deathstate", + "xdeathstate", + "deathsound", + "speed", + "radius", + "height", + "dispoffset", + "mass", + "damage", + "activesound", + "flags", + "raisestate", + NULL, +}; + +static int mobjinfo_fields_ref = LUA_NOREF; + // mobjinfo_t *, field -> number static int mobjinfo_get(lua_State *L) { mobjinfo_t *info = *((mobjinfo_t **)luaL_checkudata(L, 1, META_MOBJINFO)); - const char *field = luaL_checkstring(L, 2); + enum mobjinfo_e field = luaL_checkoption(L, 2, mobjinfo_opt[0], mobjinfo_opt); I_Assert(info != NULL); I_Assert(info >= mobjinfo); - if (fastcmp(field,"doomednum")) + switch (field) + { + case mobjinfo_doomednum: lua_pushinteger(L, info->doomednum); - else if (fastcmp(field,"spawnstate")) + break; + case mobjinfo_spawnstate: lua_pushinteger(L, info->spawnstate); - else if (fastcmp(field,"spawnhealth")) + break; + case mobjinfo_spawnhealth: lua_pushinteger(L, info->spawnhealth); - else if (fastcmp(field,"seestate")) + break; + case mobjinfo_seestate: lua_pushinteger(L, info->seestate); - else if (fastcmp(field,"seesound")) + break; + case mobjinfo_seesound: lua_pushinteger(L, info->seesound); - else if (fastcmp(field,"reactiontime")) + break; + case mobjinfo_reactiontime: lua_pushinteger(L, info->reactiontime); - else if (fastcmp(field,"attacksound")) + break; + case mobjinfo_attacksound: lua_pushinteger(L, info->attacksound); - else if (fastcmp(field,"painstate")) + break; + case mobjinfo_painstate: lua_pushinteger(L, info->painstate); - else if (fastcmp(field,"painchance")) + break; + case mobjinfo_painchance: lua_pushinteger(L, info->painchance); - else if (fastcmp(field,"painsound")) + break; + case mobjinfo_painsound: lua_pushinteger(L, info->painsound); - else if (fastcmp(field,"meleestate")) + break; + case mobjinfo_meleestate: lua_pushinteger(L, info->meleestate); - else if (fastcmp(field,"missilestate")) + break; + case mobjinfo_missilestate: lua_pushinteger(L, info->missilestate); - else if (fastcmp(field,"deathstate")) + break; + case mobjinfo_deathstate: lua_pushinteger(L, info->deathstate); - else if (fastcmp(field,"xdeathstate")) + break; + case mobjinfo_xdeathstate: lua_pushinteger(L, info->xdeathstate); - else if (fastcmp(field,"deathsound")) + break; + case mobjinfo_deathsound: lua_pushinteger(L, info->deathsound); - else if (fastcmp(field,"speed")) + break; + case mobjinfo_speed: lua_pushinteger(L, info->speed); // sometimes it's fixed_t, sometimes it's not... - else if (fastcmp(field,"radius")) + break; + case mobjinfo_radius: lua_pushfixed(L, info->radius); - else if (fastcmp(field,"height")) + break; + case mobjinfo_height: lua_pushfixed(L, info->height); - else if (fastcmp(field,"dispoffset")) + break; + case mobjinfo_dispoffset: lua_pushinteger(L, info->dispoffset); - else if (fastcmp(field,"mass")) + break; + case mobjinfo_mass: lua_pushinteger(L, info->mass); - else if (fastcmp(field,"damage")) + break; + case mobjinfo_damage: lua_pushinteger(L, info->damage); - else if (fastcmp(field,"activesound")) + break; + case mobjinfo_activesound: lua_pushinteger(L, info->activesound); - else if (fastcmp(field,"flags")) + break; + case mobjinfo_flags: lua_pushinteger(L, info->flags); - else if (fastcmp(field,"raisestate")) + break; + case mobjinfo_raisestate: lua_pushinteger(L, info->raisestate); - else { + break; + default: lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS); I_Assert(lua_istable(L, -1)); lua_pushlightuserdata(L, info); lua_rawget(L, -2); if (!lua_istable(L, -1)) { // no extra values table - CONS_Debug(DBG_LUA, M_GetText("'%s' has no field named '%s'; returning nil.\n"), "mobjinfo_t", field); + CONS_Debug(DBG_LUA, M_GetText("'%s' has no field named '%s'; returning nil.\n"), "mobjinfo_t", lua_tostring(L, 2)); return 0; } - lua_getfield(L, -1, field); + lua_pushvalue(L, 2); // field name + lua_gettable(L, -2); if (lua_isnil(L, -1)) // no value for this field - CONS_Debug(DBG_LUA, M_GetText("'%s' has no field named '%s'; returning nil.\n"), "mobjinfo_t", field); + CONS_Debug(DBG_LUA, M_GetText("'%s' has no field named '%s'; returning nil.\n"), "mobjinfo_t", lua_tostring(L, 2)); + break; } return 1; } @@ -1183,7 +1269,7 @@ static int mobjinfo_get(lua_State *L) static int mobjinfo_set(lua_State *L) { mobjinfo_t *info = *((mobjinfo_t **)luaL_checkudata(L, 1, META_MOBJINFO)); - const char *field = luaL_checkstring(L, 2); + enum mobjinfo_e field = Lua_optoption(L, 2, -1, mobjinfo_fields_ref); if (hud_running) return luaL_error(L, "Do not alter mobjinfo in HUD rendering code!"); @@ -1193,55 +1279,81 @@ static int mobjinfo_set(lua_State *L) I_Assert(info != NULL); I_Assert(info >= mobjinfo); - if (fastcmp(field,"doomednum")) + switch (field) + { + case mobjinfo_doomednum: info->doomednum = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"spawnstate")) + break; + case mobjinfo_spawnstate: info->spawnstate = luaL_checkinteger(L, 3); - else if (fastcmp(field,"spawnhealth")) + break; + case mobjinfo_spawnhealth: info->spawnhealth = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"seestate")) + break; + case mobjinfo_seestate: info->seestate = luaL_checkinteger(L, 3); - else if (fastcmp(field,"seesound")) + break; + case mobjinfo_seesound: info->seesound = luaL_checkinteger(L, 3); - else if (fastcmp(field,"reactiontime")) + break; + case mobjinfo_reactiontime: info->reactiontime = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"attacksound")) + break; + case mobjinfo_attacksound: info->attacksound = luaL_checkinteger(L, 3); - else if (fastcmp(field,"painstate")) + break; + case mobjinfo_painstate: info->painstate = luaL_checkinteger(L, 3); - else if (fastcmp(field,"painchance")) + break; + case mobjinfo_painchance: info->painchance = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"painsound")) + break; + case mobjinfo_painsound: info->painsound = luaL_checkinteger(L, 3); - else if (fastcmp(field,"meleestate")) + break; + case mobjinfo_meleestate: info->meleestate = luaL_checkinteger(L, 3); - else if (fastcmp(field,"missilestate")) + break; + case mobjinfo_missilestate: info->missilestate = luaL_checkinteger(L, 3); - else if (fastcmp(field,"deathstate")) + break; + case mobjinfo_deathstate: info->deathstate = luaL_checkinteger(L, 3); - else if (fastcmp(field,"xdeathstate")) + break; + case mobjinfo_xdeathstate: info->xdeathstate = luaL_checkinteger(L, 3); - else if (fastcmp(field,"deathsound")) + break; + case mobjinfo_deathsound: info->deathsound = luaL_checkinteger(L, 3); - else if (fastcmp(field,"speed")) + break; + case mobjinfo_speed: info->speed = luaL_checkfixed(L, 3); - else if (fastcmp(field,"radius")) + break; + case mobjinfo_radius: info->radius = luaL_checkfixed(L, 3); - else if (fastcmp(field,"height")) + break; + case mobjinfo_height: info->height = luaL_checkfixed(L, 3); - else if (fastcmp(field,"dispoffset")) + break; + case mobjinfo_dispoffset: info->dispoffset = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"mass")) + break; + case mobjinfo_mass: info->mass = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"damage")) + break; + case mobjinfo_damage: info->damage = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"activesound")) + break; + case mobjinfo_activesound: info->activesound = luaL_checkinteger(L, 3); - else if (fastcmp(field,"flags")) + break; + case mobjinfo_flags: info->flags = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"raisestate")) + break; + case mobjinfo_raisestate: info->raisestate = luaL_checkinteger(L, 3); - else { + break; + default: lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS); I_Assert(lua_istable(L, -1)); lua_pushlightuserdata(L, info); @@ -1249,18 +1361,17 @@ static int mobjinfo_set(lua_State *L) if (lua_isnil(L, -1)) { // This index doesn't have a table for extra values yet, let's make one. lua_pop(L, 1); - CONS_Debug(DBG_LUA, M_GetText("'%s' has no field named '%s'; adding it as Lua data.\n"), "mobjinfo_t", field); + CONS_Debug(DBG_LUA, M_GetText("'%s' has no field named '%s'; adding it as Lua data.\n"), "mobjinfo_t", lua_tostring(L, 2)); lua_newtable(L); lua_pushlightuserdata(L, info); lua_pushvalue(L, -2); // ext value table lua_rawset(L, -4); // LREG_EXTVARS table } + lua_pushvalue(L, 2); // key lua_pushvalue(L, 3); // value to store - lua_setfield(L, -2, field); + lua_settable(L, -3); lua_pop(L, 2); } - //else - //return luaL_error(L, LUA_QL("mobjinfo_t") " has no field named " LUA_QS, field); return 0; } @@ -1788,6 +1899,8 @@ int LUA_InfoLib(lua_State *L) lua_setfield(L, -2, "__len"); lua_pop(L, 1); + mobjinfo_fields_ref = Lua_CreateFieldTable(L, mobjinfo_opt); + luaL_newmetatable(L, META_SKINCOLOR); lua_pushcfunction(L, skincolor_get); lua_setfield(L, -2, "__index"); diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 898651520..dc477c81f 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -88,6 +88,8 @@ static const char *const sector_opt[] = { "gravity", NULL}; +static int sector_fields_ref = LUA_NOREF; + enum subsector_e { subsector_valid = 0, subsector_sector, @@ -104,6 +106,8 @@ static const char *const subsector_opt[] = { "polyList", NULL}; +static int subsector_fields_ref = LUA_NOREF; + enum line_e { line_valid = 0, line_v1, @@ -156,6 +160,8 @@ static const char *const line_opt[] = { "callcount", NULL}; +static int line_fields_ref = LUA_NOREF; + enum side_e { side_valid = 0, side_textureoffset, @@ -184,6 +190,8 @@ static const char *const side_opt[] = { "text", NULL}; +static int side_fields_ref = LUA_NOREF; + enum vertex_e { vertex_valid = 0, vertex_x, @@ -204,6 +212,8 @@ static const char *const vertex_opt[] = { "ceilingzset", NULL}; +static int vertex_fields_ref = LUA_NOREF; + enum ffloor_e { ffloor_valid = 0, ffloor_topheight, @@ -256,6 +266,8 @@ static const char *const ffloor_opt[] = { "bouncestrength", NULL}; +static int ffloor_fields_ref = LUA_NOREF; + #ifdef HAVE_LUA_SEGS enum seg_e { seg_valid = 0, @@ -285,6 +297,8 @@ static const char *const seg_opt[] = { "polyseg", NULL}; +static int seg_fields_ref = LUA_NOREF; + enum node_e { node_valid = 0, node_x, @@ -305,6 +319,8 @@ static const char *const node_opt[] = { "children", NULL}; +static int node_fields_ref = LUA_NOREF; + enum nodechild_e { nodechild_valid = 0, nodechild_right, @@ -356,6 +372,8 @@ static const char *const slope_opt[] = { "flags", NULL}; +static int slope_fields_ref = LUA_NOREF; + // shared by both vector2_t and vector3_t enum vector_e { vector_x = 0, @@ -575,7 +593,7 @@ static int sectorlines_num(lua_State *L) static int sector_get(lua_State *L) { sector_t *sector = *((sector_t **)luaL_checkudata(L, 1, META_SECTOR)); - enum sector_e field = luaL_checkoption(L, 2, sector_opt[0], sector_opt); + enum sector_e field = Lua_optoption(L, 2, sector_valid, sector_fields_ref); INT16 i; if (!sector) @@ -697,7 +715,7 @@ static int sector_get(lua_State *L) static int sector_set(lua_State *L) { sector_t *sector = *((sector_t **)luaL_checkudata(L, 1, META_SECTOR)); - enum sector_e field = luaL_checkoption(L, 2, sector_opt[0], sector_opt); + enum sector_e field = Lua_optoption(L, 2, sector_valid, sector_fields_ref); if (!sector) return luaL_error(L, "accessed sector_t doesn't exist anymore."); @@ -814,7 +832,7 @@ static int sector_num(lua_State *L) static int subsector_get(lua_State *L) { subsector_t *subsector = *((subsector_t **)luaL_checkudata(L, 1, META_SUBSECTOR)); - enum subsector_e field = luaL_checkoption(L, 2, subsector_opt[0], subsector_opt); + enum subsector_e field = Lua_optoption(L, 2, subsector_valid, subsector_fields_ref); if (!subsector) { @@ -898,7 +916,7 @@ static int linestringargs_len(lua_State *L) static int line_get(lua_State *L) { line_t *line = *((line_t **)luaL_checkudata(L, 1, META_LINE)); - enum line_e field = luaL_checkoption(L, 2, line_opt[0], line_opt); + enum line_e field = Lua_optoption(L, 2, line_valid, line_fields_ref); if (!line) { @@ -1057,7 +1075,7 @@ static int sidenum_get(lua_State *L) static int side_get(lua_State *L) { side_t *side = *((side_t **)luaL_checkudata(L, 1, META_SIDE)); - enum side_e field = luaL_checkoption(L, 2, side_opt[0], side_opt); + enum side_e field = Lua_optoption(L, 2, side_valid, side_fields_ref); if (!side) { @@ -1110,7 +1128,7 @@ static int side_get(lua_State *L) static int side_set(lua_State *L) { side_t *side = *((side_t **)luaL_checkudata(L, 1, META_SIDE)); - enum side_e field = luaL_checkoption(L, 2, side_opt[0], side_opt); + enum side_e field = Lua_optoption(L, 2, side_valid, side_fields_ref); if (!side) { @@ -1166,7 +1184,7 @@ static int side_num(lua_State *L) static int vertex_get(lua_State *L) { vertex_t *vertex = *((vertex_t **)luaL_checkudata(L, 1, META_VERTEX)); - enum vertex_e field = luaL_checkoption(L, 2, vertex_opt[0], vertex_opt); + enum vertex_e field = Lua_optoption(L, 2, vertex_valid, vertex_fields_ref); if (!vertex) { @@ -1220,7 +1238,7 @@ static int vertex_num(lua_State *L) static int seg_get(lua_State *L) { seg_t *seg = *((seg_t **)luaL_checkudata(L, 1, META_SEG)); - enum seg_e field = luaL_checkoption(L, 2, seg_opt[0], seg_opt); + enum seg_e field = Lua_optoption(L, 2, seg_valid, seg_fields_ref); if (!seg) { @@ -1284,7 +1302,7 @@ static int seg_num(lua_State *L) static int node_get(lua_State *L) { node_t *node = *((node_t **)luaL_checkudata(L, 1, META_NODE)); - enum node_e field = luaL_checkoption(L, 2, node_opt[0], node_opt); + enum node_e field = Lua_optoption(L, 2, node_valid, node_fields_ref); if (!node) { @@ -1920,7 +1938,7 @@ static INT32 P_GetOldFOFFlags(ffloor_t *fflr) static int ffloor_get(lua_State *L) { ffloor_t *ffloor = *((ffloor_t **)luaL_checkudata(L, 1, META_FFLOOR)); - enum ffloor_e field = luaL_checkoption(L, 2, ffloor_opt[0], ffloor_opt); + enum ffloor_e field = Lua_optoption(L, 2, ffloor_valid, ffloor_fields_ref); INT16 i; if (!ffloor) @@ -2102,7 +2120,7 @@ static void P_SetOldFOFFlags(ffloor_t *fflr, oldffloortype_e oldflags) static int ffloor_set(lua_State *L) { ffloor_t *ffloor = *((ffloor_t **)luaL_checkudata(L, 1, META_FFLOOR)); - enum ffloor_e field = luaL_checkoption(L, 2, ffloor_opt[0], ffloor_opt); + enum ffloor_e field = Lua_optoption(L, 2, ffloor_valid, ffloor_fields_ref); if (!ffloor) return luaL_error(L, "accessed ffloor_t doesn't exist anymore."); @@ -2197,7 +2215,7 @@ static int ffloor_set(lua_State *L) static int slope_get(lua_State *L) { pslope_t *slope = *((pslope_t **)luaL_checkudata(L, 1, META_SLOPE)); - enum slope_e field = luaL_checkoption(L, 2, slope_opt[0], slope_opt); + enum slope_e field = Lua_optoption(L, 2, slope_valid, slope_fields_ref); if (!slope) { @@ -2241,7 +2259,7 @@ static int slope_get(lua_State *L) static int slope_set(lua_State *L) { pslope_t *slope = *((pslope_t **)luaL_checkudata(L, 1, META_SLOPE)); - enum slope_e field = luaL_checkoption(L, 2, slope_opt[0], slope_opt); + enum slope_e field = Lua_optoption(L, 2, slope_valid, slope_fields_ref); if (!slope) return luaL_error(L, "accessed pslope_t doesn't exist anymore."); @@ -2405,110 +2423,258 @@ static int lib_nummapheaders(lua_State *L) // mapheader_t // ///////////////// +enum mapheaderinfo_e +{ + mapheaderinfo_lvlttl, + mapheaderinfo_subttl, + mapheaderinfo_actnum, + mapheaderinfo_typeoflevel, + mapheaderinfo_nextlevel, + mapheaderinfo_marathonnext, + mapheaderinfo_keywords, + mapheaderinfo_musname, + mapheaderinfo_mustrack, + mapheaderinfo_muspos, + mapheaderinfo_musinterfadeout, + mapheaderinfo_musintername, + mapheaderinfo_muspostbossname, + mapheaderinfo_muspostbosstrack, + mapheaderinfo_muspostbosspos, + mapheaderinfo_muspostbossfadein, + mapheaderinfo_musforcereset, + mapheaderinfo_forcecharacter, + mapheaderinfo_weather, + mapheaderinfo_skynum, + mapheaderinfo_skybox_scalex, + mapheaderinfo_skybox_scaley, + mapheaderinfo_skybox_scalez, + mapheaderinfo_interscreen, + mapheaderinfo_runsoc, + mapheaderinfo_scriptname, + mapheaderinfo_precutscenenum, + mapheaderinfo_cutscenenum, + mapheaderinfo_countdown, + mapheaderinfo_palette, + mapheaderinfo_numlaps, + mapheaderinfo_unlockrequired, + mapheaderinfo_levelselect, + mapheaderinfo_bonustype, + mapheaderinfo_ltzzpatch, + mapheaderinfo_ltzztext, + mapheaderinfo_ltactdiamond, + mapheaderinfo_maxbonuslives, + mapheaderinfo_levelflags, + mapheaderinfo_menuflags, + mapheaderinfo_selectheading, + mapheaderinfo_startrings, + mapheaderinfo_sstimer, + mapheaderinfo_ssspheres, + mapheaderinfo_gravity, +}; + +static const char *const mapheaderinfo_opt[] = { + "lvlttl", + "subttl", + "actnum", + "typeoflevel", + "nextlevel", + "marathonnext", + "keywords", + "musname", + "mustrack", + "muspos", + "musinterfadeout", + "musintername", + "muspostbossname", + "muspostbosstrack", + "muspostbosspos", + "muspostbossfadein", + "musforcereset", + "forcecharacter", + "weather", + "skynum", + "skybox_scalex", + "skybox_scaley", + "skybox_scalez", + "interscreen", + "runsoc", + "scriptname", + "precutscenenum", + "cutscenenum", + "countdown", + "palette", + "numlaps", + "unlockrequired", + "levelselect", + "bonustype", + "ltzzpatch", + "ltzztext", + "ltactdiamond", + "maxbonuslives", + "levelflags", + "menuflags", + "selectheading", + "startrings", + "sstimer", + "ssspheres", + "gravity", + NULL, +}; + +static int mapheaderinfo_fields_ref = LUA_NOREF; + static int mapheaderinfo_get(lua_State *L) { mapheader_t *header = *((mapheader_t **)luaL_checkudata(L, 1, META_MAPHEADER)); - const char *field = luaL_checkstring(L, 2); + enum mapheaderinfo_e field = Lua_optoption(L, 2, -1, mapheaderinfo_fields_ref); INT16 i; - if (fastcmp(field,"lvlttl")) + + switch (field) + { + case mapheaderinfo_lvlttl: lua_pushstring(L, header->lvlttl); - else if (fastcmp(field,"subttl")) + break; + case mapheaderinfo_subttl: lua_pushstring(L, header->subttl); - else if (fastcmp(field,"actnum")) + break; + case mapheaderinfo_actnum: lua_pushinteger(L, header->actnum); - else if (fastcmp(field,"typeoflevel")) + break; + case mapheaderinfo_typeoflevel: lua_pushinteger(L, header->typeoflevel); - else if (fastcmp(field,"nextlevel")) + break; + case mapheaderinfo_nextlevel: lua_pushinteger(L, header->nextlevel); - else if (fastcmp(field,"marathonnext")) + break; + case mapheaderinfo_marathonnext: lua_pushinteger(L, header->marathonnext); - else if (fastcmp(field,"keywords")) + break; + case mapheaderinfo_keywords: lua_pushstring(L, header->keywords); - else if (fastcmp(field,"musname")) + break; + case mapheaderinfo_musname: lua_pushstring(L, header->musname); - else if (fastcmp(field,"mustrack")) + break; + case mapheaderinfo_mustrack: lua_pushinteger(L, header->mustrack); - else if (fastcmp(field,"muspos")) + break; + case mapheaderinfo_muspos: lua_pushinteger(L, header->muspos); - else if (fastcmp(field,"musinterfadeout")) + break; + case mapheaderinfo_musinterfadeout: lua_pushinteger(L, header->musinterfadeout); - else if (fastcmp(field,"musintername")) + break; + case mapheaderinfo_musintername: lua_pushstring(L, header->musintername); - else if (fastcmp(field,"muspostbossname")) + break; + case mapheaderinfo_muspostbossname: lua_pushstring(L, header->muspostbossname); - else if (fastcmp(field,"muspostbosstrack")) + break; + case mapheaderinfo_muspostbosstrack: lua_pushinteger(L, header->muspostbosstrack); - else if (fastcmp(field,"muspostbosspos")) + break; + case mapheaderinfo_muspostbosspos: lua_pushinteger(L, header->muspostbosspos); - else if (fastcmp(field,"muspostbossfadein")) + break; + case mapheaderinfo_muspostbossfadein: lua_pushinteger(L, header->muspostbossfadein); - else if (fastcmp(field,"musforcereset")) + break; + case mapheaderinfo_musforcereset: lua_pushinteger(L, header->musforcereset); - else if (fastcmp(field,"forcecharacter")) + break; + case mapheaderinfo_forcecharacter: lua_pushstring(L, header->forcecharacter); - else if (fastcmp(field,"weather")) + break; + case mapheaderinfo_weather: lua_pushinteger(L, header->weather); - else if (fastcmp(field,"skynum")) + break; + case mapheaderinfo_skynum: lua_pushinteger(L, header->skynum); - else if (fastcmp(field,"skybox_scalex")) + break; + case mapheaderinfo_skybox_scalex: lua_pushinteger(L, header->skybox_scalex); - else if (fastcmp(field,"skybox_scaley")) + break; + case mapheaderinfo_skybox_scaley: lua_pushinteger(L, header->skybox_scaley); - else if (fastcmp(field,"skybox_scalez")) + break; + case mapheaderinfo_skybox_scalez: lua_pushinteger(L, header->skybox_scalez); - else if (fastcmp(field,"interscreen")) { + break; + case mapheaderinfo_interscreen: for (i = 0; i < 8; i++) if (!header->interscreen[i]) break; lua_pushlstring(L, header->interscreen, i); - } else if (fastcmp(field,"runsoc")) + break; + case mapheaderinfo_runsoc: lua_pushstring(L, header->runsoc); - else if (fastcmp(field,"scriptname")) + break; + case mapheaderinfo_scriptname: lua_pushstring(L, header->scriptname); - else if (fastcmp(field,"precutscenenum")) + break; + case mapheaderinfo_precutscenenum: lua_pushinteger(L, header->precutscenenum); - else if (fastcmp(field,"cutscenenum")) + break; + case mapheaderinfo_cutscenenum: lua_pushinteger(L, header->cutscenenum); - else if (fastcmp(field,"countdown")) + break; + case mapheaderinfo_countdown: lua_pushinteger(L, header->countdown); - else if (fastcmp(field,"palette")) + break; + case mapheaderinfo_palette: lua_pushinteger(L, header->palette); - else if (fastcmp(field,"numlaps")) + break; + case mapheaderinfo_numlaps: lua_pushinteger(L, header->numlaps); - else if (fastcmp(field,"unlockrequired")) + break; + case mapheaderinfo_unlockrequired: lua_pushinteger(L, header->unlockrequired); - else if (fastcmp(field,"levelselect")) + break; + case mapheaderinfo_levelselect: lua_pushinteger(L, header->levelselect); - else if (fastcmp(field,"bonustype")) + break; + case mapheaderinfo_bonustype: lua_pushinteger(L, header->bonustype); - else if (fastcmp(field,"ltzzpatch")) + break; + case mapheaderinfo_ltzzpatch: lua_pushstring(L, header->ltzzpatch); - else if (fastcmp(field,"ltzztext")) + break; + case mapheaderinfo_ltzztext: lua_pushstring(L, header->ltzztext); - else if (fastcmp(field,"ltactdiamond")) + break; + case mapheaderinfo_ltactdiamond: lua_pushstring(L, header->ltactdiamond); - else if (fastcmp(field,"maxbonuslives")) + break; + case mapheaderinfo_maxbonuslives: lua_pushinteger(L, header->maxbonuslives); - else if (fastcmp(field,"levelflags")) + break; + case mapheaderinfo_levelflags: lua_pushinteger(L, header->levelflags); - else if (fastcmp(field,"menuflags")) + break; + case mapheaderinfo_menuflags: lua_pushinteger(L, header->menuflags); - else if (fastcmp(field,"selectheading")) + break; + case mapheaderinfo_selectheading: lua_pushstring(L, header->selectheading); - else if (fastcmp(field,"startrings")) + break; + case mapheaderinfo_startrings: lua_pushinteger(L, header->startrings); - else if (fastcmp(field, "sstimer")) + break; + case mapheaderinfo_sstimer: lua_pushinteger(L, header->sstimer); - else if (fastcmp(field, "ssspheres")) + break; + case mapheaderinfo_ssspheres: lua_pushinteger(L, header->ssspheres); - else if (fastcmp(field, "gravity")) + break; + case mapheaderinfo_gravity: lua_pushfixed(L, header->gravity); + break; // TODO add support for reading numGradedMares and grades - else { + default: // Read custom vars now // (note: don't include the "LUA." in your lua scripts!) UINT8 j = 0; - for (;j < header->numCustomOptions && !fastcmp(field, header->customopts[j].option); ++j); + for (;j < header->numCustomOptions && !fastcmp(lua_tostring(L, 2), header->customopts[j].option); ++j); if(j < header->numCustomOptions) lua_pushstring(L, header->customopts[j].value); @@ -2539,6 +2705,8 @@ int LUA_MapLib(lua_State *L) lua_setfield(L, -2, "__len"); lua_pop(L, 1); + sector_fields_ref = Lua_CreateFieldTable(L, sector_opt); + luaL_newmetatable(L, META_SUBSECTOR); lua_pushcfunction(L, subsector_get); lua_setfield(L, -2, "__index"); @@ -2547,6 +2715,8 @@ int LUA_MapLib(lua_State *L) lua_setfield(L, -2, "__len"); lua_pop(L, 1); + subsector_fields_ref = Lua_CreateFieldTable(L, subsector_opt); + luaL_newmetatable(L, META_LINE); lua_pushcfunction(L, line_get); lua_setfield(L, -2, "__index"); @@ -2555,6 +2725,8 @@ int LUA_MapLib(lua_State *L) lua_setfield(L, -2, "__len"); lua_pop(L, 1); + line_fields_ref = Lua_CreateFieldTable(L, line_opt); + luaL_newmetatable(L, META_LINEARGS); lua_pushcfunction(L, lineargs_get); lua_setfield(L, -2, "__index"); @@ -2587,6 +2759,8 @@ int LUA_MapLib(lua_State *L) lua_setfield(L, -2, "__len"); lua_pop(L, 1); + side_fields_ref = Lua_CreateFieldTable(L, side_opt); + luaL_newmetatable(L, META_VERTEX); lua_pushcfunction(L, vertex_get); lua_setfield(L, -2, "__index"); @@ -2595,6 +2769,8 @@ int LUA_MapLib(lua_State *L) lua_setfield(L, -2, "__len"); lua_pop(L, 1); + vertex_fields_ref = Lua_CreateFieldTable(L, vertex_opt); + luaL_newmetatable(L, META_FFLOOR); lua_pushcfunction(L, ffloor_get); lua_setfield(L, -2, "__index"); @@ -2603,6 +2779,8 @@ int LUA_MapLib(lua_State *L) lua_setfield(L, -2, "__newindex"); lua_pop(L, 1); + ffloor_fields_ref = Lua_CreateFieldTable(L, ffloor_opt); + #ifdef HAVE_LUA_SEGS luaL_newmetatable(L, META_SEG); lua_pushcfunction(L, seg_get); @@ -2612,6 +2790,8 @@ int LUA_MapLib(lua_State *L) lua_setfield(L, -2, "__len"); lua_pop(L, 1); + seg_fields_ref = Lua_CreateFieldTable(L, seg_opt); + luaL_newmetatable(L, META_NODE); lua_pushcfunction(L, node_get); lua_setfield(L, -2, "__index"); @@ -2620,6 +2800,8 @@ int LUA_MapLib(lua_State *L) lua_setfield(L, -2, "__len"); lua_pop(L, 1); + node_fields_ref = Lua_CreateFieldTable(L, node_opt); + luaL_newmetatable(L, META_NODEBBOX); //lua_pushcfunction(L, nodebbox_get); //lua_setfield(L, -2, "__index"); @@ -2646,6 +2828,8 @@ int LUA_MapLib(lua_State *L) lua_setfield(L, -2, "__newindex"); lua_pop(L, 1); + slope_fields_ref = Lua_CreateFieldTable(L, slope_opt); + luaL_newmetatable(L, META_VECTOR2); lua_pushcfunction(L, vector2_get); lua_setfield(L, -2, "__index"); @@ -2664,6 +2848,8 @@ int LUA_MapLib(lua_State *L) //lua_setfield(L, -2, "__len"); lua_pop(L, 1); + mapheaderinfo_fields_ref = Lua_CreateFieldTable(L, mapheaderinfo_opt); + LUA_PushTaggableObjectArray(L, "sectors", lib_iterateSectors, lib_getSector, diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index 5c2b8b4d3..09d244c91 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -179,10 +179,12 @@ static const char *const mobj_opt[] = { #define UNIMPLEMENTED luaL_error(L, LUA_QL("mobj_t") " field " LUA_QS " is not implemented for Lua and cannot be accessed.", mobj_opt[field]) +static int mobj_fields_ref = LUA_NOREF; + static int mobj_get(lua_State *L) { mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); - enum mobj_e field = Lua_optoption(L, 2, NULL, mobj_opt); + enum mobj_e field = Lua_optoption(L, 2, -1, mobj_fields_ref); lua_settop(L, 2); if (!mo || !ISINLEVEL) { @@ -467,7 +469,7 @@ static int mobj_get(lua_State *L) static int mobj_set(lua_State *L) { mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); - enum mobj_e field = Lua_optoption(L, 2, mobj_opt[0], mobj_opt); + enum mobj_e field = Lua_optoption(L, 2, mobj_valid, mobj_fields_ref); lua_settop(L, 3); INLEVEL @@ -876,14 +878,55 @@ static int thingstringargs_len(lua_State *L) return 1; } +enum mapthing_e { + mapthing_valid = 0, + mapthing_x, + mapthing_y, + mapthing_angle, + mapthing_pitch, + mapthing_roll, + mapthing_type, + mapthing_options, + mapthing_scale, + mapthing_z, + mapthing_extrainfo, + mapthing_tag, + mapthing_taglist, + mapthing_args, + mapthing_stringargs, + mapthing_mobj, +}; + +const char *const mapthing_opt[] = { + "valid", + "x", + "y", + "angle", + "pitch", + "roll", + "type", + "options", + "scale", + "z", + "extrainfo", + "tag", + "taglist", + "args", + "stringargs", + "mobj", + NULL, +}; + +static int mapthing_fields_ref = LUA_NOREF; + static int mapthing_get(lua_State *L) { mapthing_t *mt = *((mapthing_t **)luaL_checkudata(L, 1, META_MAPTHING)); - const char *field = luaL_checkstring(L, 2); - lua_Integer number; + enum mapthing_e field = Lua_optoption(L, 2, -1, mapthing_fields_ref); + lua_settop(L, 2); if (!mt) { - if (fastcmp(field,"valid")) { + if (field == mapthing_valid) { lua_pushboolean(L, false); return 1; } @@ -892,62 +935,71 @@ static int mapthing_get(lua_State *L) return 0; } - if (fastcmp(field,"valid")) { - lua_pushboolean(L, true); - return 1; - } else if(fastcmp(field,"x")) - number = mt->x; - else if(fastcmp(field,"y")) - number = mt->y; - else if(fastcmp(field,"angle")) - number = mt->angle; - else if(fastcmp(field,"pitch")) - number = mt->pitch; - else if(fastcmp(field,"roll")) - number = mt->roll; - else if(fastcmp(field,"type")) - number = mt->type; - else if(fastcmp(field,"options")) - number = mt->options; - else if(fastcmp(field,"scale")) - number = mt->scale; - else if(fastcmp(field,"z")) - number = mt->z; - else if(fastcmp(field,"extrainfo")) - number = mt->extrainfo; - else if(fastcmp(field,"tag")) - number = Tag_FGet(&mt->tags); - else if(fastcmp(field,"taglist")) + switch (field) { - LUA_PushUserdata(L, &mt->tags, META_TAGLIST); - return 1; + case mapthing_valid: + lua_pushboolean(L, true); + break; + case mapthing_x: + lua_pushinteger(L, mt->x); + break; + case mapthing_y: + lua_pushinteger(L, mt->y); + break; + case mapthing_angle: + lua_pushinteger(L, mt->angle); + break; + case mapthing_pitch: + lua_pushinteger(L, mt->pitch); + break; + case mapthing_roll: + lua_pushinteger(L, mt->roll); + break; + case mapthing_type: + lua_pushinteger(L, mt->type); + break; + case mapthing_options: + lua_pushinteger(L, mt->options); + break; + case mapthing_scale: + lua_pushinteger(L, mt->scale); + break; + case mapthing_z: + lua_pushinteger(L, mt->z); + break; + case mapthing_extrainfo: + lua_pushinteger(L, mt->extrainfo); + break; + case mapthing_tag: + lua_pushinteger(L, Tag_FGet(&mt->tags)); + break; + case mapthing_taglist: + LUA_PushUserdata(L, &mt->tags, META_TAGLIST); + break; + case mapthing_args: + LUA_PushUserdata(L, mt->args, META_THINGARGS); + break; + case mapthing_stringargs: + LUA_PushUserdata(L, mt->stringargs, META_THINGSTRINGARGS); + break; + case mapthing_mobj: + LUA_PushUserdata(L, mt->mobj, META_MOBJ); + break; + default: + if (devparm) + return luaL_error(L, LUA_QL("mapthing_t") " has no field named " LUA_QS, field); + else + return 0; } - else if(fastcmp(field,"args")) - { - LUA_PushUserdata(L, mt->args, META_THINGARGS); - return 1; - } - else if(fastcmp(field,"stringargs")) - { - LUA_PushUserdata(L, mt->stringargs, META_THINGSTRINGARGS); - return 1; - } - else if(fastcmp(field,"mobj")) { - LUA_PushUserdata(L, mt->mobj, META_MOBJ); - return 1; - } else if (devparm) - return luaL_error(L, LUA_QL("mapthing_t") " has no field named " LUA_QS, field); - else - return 0; - lua_pushinteger(L, number); return 1; } static int mapthing_set(lua_State *L) { mapthing_t *mt = *((mapthing_t **)luaL_checkudata(L, 1, META_MAPTHING)); - const char *field = luaL_checkstring(L, 2); + enum mapthing_e field = Lua_optoption(L, 2, -1, mapthing_fields_ref); + lua_settop(L, 3); if (!mt) return luaL_error(L, "accessed mapthing_t doesn't exist anymore."); @@ -957,39 +1009,52 @@ static int mapthing_set(lua_State *L) if (hook_cmd_running) return luaL_error(L, "Do not alter mapthing_t in CMD building code!"); - if(fastcmp(field,"x")) - mt->x = (INT16)luaL_checkinteger(L, 3); - else if(fastcmp(field,"y")) - mt->y = (INT16)luaL_checkinteger(L, 3); - else if(fastcmp(field,"angle")) - mt->angle = (INT16)luaL_checkinteger(L, 3); - else if(fastcmp(field,"pitch")) - mt->pitch = (INT16)luaL_checkinteger(L, 3); - else if(fastcmp(field,"roll")) - mt->roll = (INT16)luaL_checkinteger(L, 3); - else if(fastcmp(field,"type")) - mt->type = (UINT16)luaL_checkinteger(L, 3); - else if(fastcmp(field,"options")) - mt->options = (UINT16)luaL_checkinteger(L, 3); - else if(fastcmp(field,"scale")) - mt->scale = luaL_checkfixed(L, 3); - else if(fastcmp(field,"z")) - mt->z = (INT16)luaL_checkinteger(L, 3); - else if(fastcmp(field,"extrainfo")) + switch (field) { - INT32 extrainfo = luaL_checkinteger(L, 3); - if (extrainfo & ~15) - return luaL_error(L, "mapthing_t extrainfo set %d out of range (%d - %d)", extrainfo, 0, 15); - mt->extrainfo = (UINT8)extrainfo; + case mapthing_x: + mt->x = (INT16)luaL_checkinteger(L, 3); + break; + case mapthing_y: + mt->y = (INT16)luaL_checkinteger(L, 3); + break; + case mapthing_angle: + mt->angle = (INT16)luaL_checkinteger(L, 3); + break; + case mapthing_pitch: + mt->pitch = (INT16)luaL_checkinteger(L, 3); + break; + case mapthing_roll: + mt->roll = (INT16)luaL_checkinteger(L, 3); + break; + case mapthing_type: + mt->type = (UINT16)luaL_checkinteger(L, 3); + break; + case mapthing_options: + mt->options = (UINT16)luaL_checkinteger(L, 3); + break; + case mapthing_scale: + mt->scale = luaL_checkfixed(L, 3); + break; + case mapthing_z: + mt->z = (INT16)luaL_checkinteger(L, 3); + break; + case mapthing_extrainfo: + INT32 extrainfo = luaL_checkinteger(L, 3); + if (extrainfo & ~15) + return luaL_error(L, "mapthing_t extrainfo set %d out of range (%d - %d)", extrainfo, 0, 15); + mt->extrainfo = (UINT8)extrainfo; + break; + case mapthing_tag: + Tag_FSet(&mt->tags, (INT16)luaL_checkinteger(L, 3)); + break; + case mapthing_taglist: + return LUA_ErrSetDirectly(L, "mapthing_t", "taglist"); + case mapthing_mobj: + mt->mobj = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); + break; + default: + return luaL_error(L, LUA_QL("mapthing_t") " has no field named " LUA_QS, field); } - 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 - return luaL_error(L, LUA_QL("mapthing_t") " has no field named " LUA_QS, field); return 0; } @@ -1051,6 +1116,8 @@ int LUA_MobjLib(lua_State *L) lua_setfield(L, -2, "__newindex"); lua_pop(L,1); + mobj_fields_ref = Lua_CreateFieldTable(L, mobj_opt); + luaL_newmetatable(L, META_THINGARGS); lua_pushcfunction(L, thingargs_get); lua_setfield(L, -2, "__index"); @@ -1078,6 +1145,8 @@ int LUA_MobjLib(lua_State *L) lua_setfield(L, -2, "__len"); lua_pop(L,1); + mapthing_fields_ref = Lua_CreateFieldTable(L, mapthing_opt); + LUA_PushTaggableObjectArray(L, "mapthings", lib_iterateMapthings, lib_getMapthing, diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index f7e14e78f..1d06e081b 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -80,322 +80,764 @@ static int lib_lenPlayer(lua_State *L) return 1; } +enum player_e +{ + player_valid, + player_name, + player_realmo, + player_mo, + player_cmd, + player_playerstate, + player_camerascale, + player_shieldscale, + player_viewz, + player_viewheight, + player_deltaviewheight, + player_bob, + player_viewrollangle, + player_aiming, + player_drawangle, + player_rings, + player_spheres, + player_pity, + player_currentweapon, + player_ringweapons, + player_ammoremoval, + player_ammoremovaltimer, + player_ammoremovalweapon, + player_powers, + player_pflags, + player_panim, + player_flashcount, + player_flashpal, + player_skincolor, + player_skin, + player_availabilities, + player_score, + player_dashspeed, + player_normalspeed, + player_runspeed, + player_thrustfactor, + player_accelstart, + player_acceleration, + player_charability, + player_charability2, + player_charflags, + player_thokitem, + player_spinitem, + player_revitem, + player_followitem, + player_followmobj, + player_actionspd, + player_mindash, + player_maxdash, + player_jumpfactor, + player_height, + player_spinheight, + player_lives, + player_continues, + player_xtralife, + player_gotcontinue, + player_speed, + player_secondjump, + player_fly1, + player_scoreadd, + player_glidetime, + player_climbing, + player_deadtimer, + player_exiting, + player_homing, + player_dashmode, + player_skidtime, + player_cmomx, + player_cmomy, + player_rmomx, + player_rmomy, + player_numboxes, + player_totalring, + player_realtime, + player_laps, + player_ctfteam, + player_gotflag, + player_weapondelay, + player_tossdelay, + player_starpostx, + player_starposty, + player_starpostz, + player_starpostnum, + player_starposttime, + player_starpostangle, + player_starpostscale, + player_angle_pos, + player_old_angle_pos, + player_axis1, + player_axis2, + player_bumpertime, + player_flyangle, + player_drilltimer, + player_linkcount, + player_linktimer, + player_anotherflyangle, + player_nightstime, + player_drillmeter, + player_drilldelay, + player_bonustime, + player_capsule, + player_drone, + player_oldscale, + player_mare, + player_marelap, + player_marebonuslap, + player_marebegunat, + player_startedtime, + player_finishedtime, + player_lapbegunat, + player_lapstartedtime, + player_finishedspheres, + player_finishedrings, + player_marescore, + player_lastmarescore, + player_totalmarescore, + player_lastmare, + player_lastmarelap, + player_lastmarebonuslap, + player_totalmarelap, + player_totalmarebonuslap, + player_maxlink, + player_texttimer, + player_textvar, + player_lastsidehit, + player_lastlinehit, + player_losstime, + player_timeshit, + player_onconveyor, + player_awayviewmobj, + player_awayviewtics, + player_awayviewaiming, + player_spectator, + player_outofcoop, + player_bot, + player_botleader, + player_lastbuttons, + player_blocked, + player_jointime, + player_quittime, +#ifdef HWRENDER + player_fovadd, +#endif +}; + +static const char *const player_opt[] = { + "valid", + "name", + "realmo", + "mo", + "cmd", + "playerstate", + "camerascale", + "shieldscale", + "viewz", + "viewheight", + "deltaviewheight", + "bob", + "viewrollangle", + "aiming", + "drawangle", + "rings", + "spheres", + "pity", + "currentweapon", + "ringweapons", + "ammoremoval", + "ammoremovaltimer", + "ammoremovalweapon", + "powers", + "pflags", + "panim", + "flashcount", + "flashpal", + "skincolor", + "skin", + "availabilities", + "score", + "dashspeed", + "normalspeed", + "runspeed", + "thrustfactor", + "accelstart", + "acceleration", + "charability", + "charability2", + "charflags", + "thokitem", + "spinitem", + "revitem", + "followitem", + "followmobj", + "actionspd", + "mindash", + "maxdash", + "jumpfactor", + "height", + "spinheight", + "lives", + "continues", + "xtralife", + "gotcontinue", + "speed", + "secondjump", + "fly1", + "scoreadd", + "glidetime", + "climbing", + "deadtimer", + "exiting", + "homing", + "dashmode", + "skidtime", + "cmomx", + "cmomy", + "rmomx", + "rmomy", + "numboxes", + "totalring", + "realtime", + "laps", + "ctfteam", + "gotflag", + "weapondelay", + "tossdelay", + "starpostx", + "starposty", + "starpostz", + "starpostnum", + "starposttime", + "starpostangle", + "starpostscale", + "angle_pos", + "old_angle_pos", + "axis1", + "axis2", + "bumpertime", + "flyangle", + "drilltimer", + "linkcount", + "linktimer", + "anotherflyangle", + "nightstime", + "drillmeter", + "drilldelay", + "bonustime", + "capsule", + "drone", + "oldscale", + "mare", + "marelap", + "marebonuslap", + "marebegunat", + "startedtime", + "finishedtime", + "lapbegunat", + "lapstartedtime", + "finishedspheres", + "finishedrings", + "marescore", + "lastmarescore", + "totalmarescore", + "lastmare", + "lastmarelap", + "lastmarebonuslap", + "totalmarelap", + "totalmarebonuslap", + "maxlink", + "texttimer", + "textvar", + "lastsidehit", + "lastlinehit", + "losstime", + "timeshit", + "onconveyor", + "awayviewmobj", + "awayviewtics", + "awayviewaiming", + "spectator", + "outofcoop", + "bot", + "botleader", + "lastbuttons", + "blocked", + "jointime", + "quittime", +#ifdef HWRENDER + "fovadd", +#endif + NULL, +}; + +static int player_fields_ref = LUA_NOREF; + static int player_get(lua_State *L) { player_t *plr = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); - const char *field = luaL_checkstring(L, 2); + enum player_e field = Lua_optoption(L, 2, -1, player_fields_ref); + lua_settop(L, 2); - if (!plr) { - if (fastcmp(field,"valid")) { + if (!plr) + { + if (field == player_valid) + { lua_pushboolean(L, false); return 1; } return LUA_ErrInvalid(L, "player_t"); } - if (fastcmp(field,"valid")) + switch (field) + { + case player_valid: lua_pushboolean(L, true); - else if (fastcmp(field,"name")) + break; + case player_name: lua_pushstring(L, player_names[plr-players]); - else if (fastcmp(field,"realmo")) + break; + case player_realmo: LUA_PushUserdata(L, plr->mo, META_MOBJ); + break; // Kept for backward-compatibility // Should be fixed to work like "realmo" later - else if (fastcmp(field,"mo")) - { + case player_mo: if (plr->spectator) lua_pushnil(L); else LUA_PushUserdata(L, plr->mo, META_MOBJ); - } - else if (fastcmp(field,"cmd")) + break; + case player_cmd: LUA_PushUserdata(L, &plr->cmd, META_TICCMD); - else if (fastcmp(field,"playerstate")) + break; + case player_playerstate: lua_pushinteger(L, plr->playerstate); - else if (fastcmp(field,"camerascale")) + break; + case player_camerascale: lua_pushfixed(L, plr->camerascale); - else if (fastcmp(field,"shieldscale")) + break; + case player_shieldscale: lua_pushfixed(L, plr->shieldscale); - else if (fastcmp(field,"viewz")) + break; + case player_viewz: lua_pushfixed(L, plr->viewz); - else if (fastcmp(field,"viewheight")) + break; + case player_viewheight: lua_pushfixed(L, plr->viewheight); - else if (fastcmp(field,"deltaviewheight")) + break; + case player_deltaviewheight: lua_pushfixed(L, plr->deltaviewheight); - else if (fastcmp(field,"bob")) + break; + case player_bob: lua_pushfixed(L, plr->bob); - else if (fastcmp(field,"viewrollangle")) + break; + case player_viewrollangle: lua_pushangle(L, plr->viewrollangle); - else if (fastcmp(field,"aiming")) + break; + case player_aiming: lua_pushangle(L, plr->aiming); - else if (fastcmp(field,"drawangle")) + break; + case player_drawangle: lua_pushangle(L, plr->drawangle); - else if (fastcmp(field,"rings")) + break; + case player_rings: lua_pushinteger(L, plr->rings); - else if (fastcmp(field,"spheres")) + break; + case player_spheres: lua_pushinteger(L, plr->spheres); - else if (fastcmp(field,"pity")) + break; + case player_pity: lua_pushinteger(L, plr->pity); - else if (fastcmp(field,"currentweapon")) + break; + case player_currentweapon: lua_pushinteger(L, plr->currentweapon); - else if (fastcmp(field,"ringweapons")) + break; + case player_ringweapons: lua_pushinteger(L, plr->ringweapons); - else if (fastcmp(field,"ammoremoval")) + break; + case player_ammoremoval: lua_pushinteger(L, plr->ammoremoval); - else if (fastcmp(field,"ammoremovaltimer")) + break; + case player_ammoremovaltimer: lua_pushinteger(L, plr->ammoremovaltimer); - else if (fastcmp(field,"ammoremovalweapon")) + break; + case player_ammoremovalweapon: lua_pushinteger(L, plr->ammoremovalweapon); - else if (fastcmp(field,"powers")) + break; + case player_powers: LUA_PushUserdata(L, plr->powers, META_POWERS); - else if (fastcmp(field,"pflags")) + break; + case player_pflags: lua_pushinteger(L, plr->pflags); - else if (fastcmp(field,"panim")) + break; + case player_panim: lua_pushinteger(L, plr->panim); - else if (fastcmp(field,"flashcount")) + break; + case player_flashcount: lua_pushinteger(L, plr->flashcount); - else if (fastcmp(field,"flashpal")) + break; + case player_flashpal: lua_pushinteger(L, plr->flashpal); - else if (fastcmp(field,"skincolor")) + break; + case player_skincolor: lua_pushinteger(L, plr->skincolor); - else if (fastcmp(field,"skin")) + break; + case player_skin: lua_pushinteger(L, plr->skin); - else if (fastcmp(field,"availabilities")) + break; + case player_availabilities: lua_pushinteger(L, plr->availabilities); - else if (fastcmp(field,"score")) + break; + case player_score: lua_pushinteger(L, plr->score); - else if (fastcmp(field,"dashspeed")) + break; + case player_dashspeed: lua_pushfixed(L, plr->dashspeed); - else if (fastcmp(field,"normalspeed")) + break; + case player_normalspeed: lua_pushfixed(L, plr->normalspeed); - else if (fastcmp(field,"runspeed")) + break; + case player_runspeed: lua_pushfixed(L, plr->runspeed); - else if (fastcmp(field,"thrustfactor")) + break; + case player_thrustfactor: lua_pushinteger(L, plr->thrustfactor); - else if (fastcmp(field,"accelstart")) + break; + case player_accelstart: lua_pushinteger(L, plr->accelstart); - else if (fastcmp(field,"acceleration")) + break; + case player_acceleration: lua_pushinteger(L, plr->acceleration); - else if (fastcmp(field,"charability")) + break; + case player_charability: lua_pushinteger(L, plr->charability); - else if (fastcmp(field,"charability2")) + break; + case player_charability2: lua_pushinteger(L, plr->charability2); - else if (fastcmp(field,"charflags")) + break; + case player_charflags: lua_pushinteger(L, plr->charflags); - else if (fastcmp(field,"thokitem")) + break; + case player_thokitem: lua_pushinteger(L, plr->thokitem); - else if (fastcmp(field,"spinitem")) + break; + case player_spinitem: lua_pushinteger(L, plr->spinitem); - else if (fastcmp(field,"revitem")) + break; + case player_revitem: lua_pushinteger(L, plr->revitem); - else if (fastcmp(field,"followitem")) + break; + case player_followitem: lua_pushinteger(L, plr->followitem); - else if (fastcmp(field,"followmobj")) + break; + case player_followmobj: LUA_PushUserdata(L, plr->followmobj, META_MOBJ); - else if (fastcmp(field,"actionspd")) + break; + case player_actionspd: lua_pushfixed(L, plr->actionspd); - else if (fastcmp(field,"mindash")) + break; + case player_mindash: lua_pushfixed(L, plr->mindash); - else if (fastcmp(field,"maxdash")) + break; + case player_maxdash: lua_pushfixed(L, plr->maxdash); - else if (fastcmp(field,"jumpfactor")) + break; + case player_jumpfactor: lua_pushfixed(L, plr->jumpfactor); - else if (fastcmp(field,"height")) + break; + case player_height: lua_pushfixed(L, plr->height); - else if (fastcmp(field,"spinheight")) + break; + case player_spinheight: lua_pushfixed(L, plr->spinheight); - else if (fastcmp(field,"lives")) + break; + case player_lives: lua_pushinteger(L, plr->lives); - else if (fastcmp(field,"continues")) + break; + case player_continues: lua_pushinteger(L, plr->continues); - else if (fastcmp(field,"xtralife")) + break; + case player_xtralife: lua_pushinteger(L, plr->xtralife); - else if (fastcmp(field,"gotcontinue")) + break; + case player_gotcontinue: lua_pushinteger(L, plr->gotcontinue); - else if (fastcmp(field,"speed")) + break; + case player_speed: lua_pushfixed(L, plr->speed); - else if (fastcmp(field,"secondjump")) + break; + case player_secondjump: lua_pushinteger(L, plr->secondjump); - else if (fastcmp(field,"fly1")) + break; + case player_fly1: lua_pushinteger(L, plr->fly1); - else if (fastcmp(field,"scoreadd")) + break; + case player_scoreadd: lua_pushinteger(L, plr->scoreadd); - else if (fastcmp(field,"glidetime")) + break; + case player_glidetime: lua_pushinteger(L, plr->glidetime); - else if (fastcmp(field,"climbing")) + break; + case player_climbing: lua_pushinteger(L, plr->climbing); - else if (fastcmp(field,"deadtimer")) + break; + case player_deadtimer: lua_pushinteger(L, plr->deadtimer); - else if (fastcmp(field,"exiting")) + break; + case player_exiting: lua_pushinteger(L, plr->exiting); - else if (fastcmp(field,"homing")) + break; + case player_homing: lua_pushinteger(L, plr->homing); - else if (fastcmp(field,"dashmode")) + break; + case player_dashmode: lua_pushinteger(L, plr->dashmode); - else if (fastcmp(field,"skidtime")) + break; + case player_skidtime: lua_pushinteger(L, plr->skidtime); - else if (fastcmp(field,"cmomx")) + break; + case player_cmomx: lua_pushfixed(L, plr->cmomx); - else if (fastcmp(field,"cmomy")) + break; + case player_cmomy: lua_pushfixed(L, plr->cmomy); - else if (fastcmp(field,"rmomx")) + break; + case player_rmomx: lua_pushfixed(L, plr->rmomx); - else if (fastcmp(field,"rmomy")) + break; + case player_rmomy: lua_pushfixed(L, plr->rmomy); - else if (fastcmp(field,"numboxes")) + break; + case player_numboxes: lua_pushinteger(L, plr->numboxes); - else if (fastcmp(field,"totalring")) + break; + case player_totalring: lua_pushinteger(L, plr->totalring); - else if (fastcmp(field,"realtime")) + break; + case player_realtime: lua_pushinteger(L, plr->realtime); - else if (fastcmp(field,"laps")) + break; + case player_laps: lua_pushinteger(L, plr->laps); - else if (fastcmp(field,"ctfteam")) + break; + case player_ctfteam: lua_pushinteger(L, plr->ctfteam); - else if (fastcmp(field,"gotflag")) + break; + case player_gotflag: lua_pushinteger(L, plr->gotflag); - else if (fastcmp(field,"weapondelay")) + break; + case player_weapondelay: lua_pushinteger(L, plr->weapondelay); - else if (fastcmp(field,"tossdelay")) + break; + case player_tossdelay: lua_pushinteger(L, plr->tossdelay); - else if (fastcmp(field,"starpostx")) + break; + case player_starpostx: lua_pushinteger(L, plr->starpostx); - else if (fastcmp(field,"starposty")) + break; + case player_starposty: lua_pushinteger(L, plr->starposty); - else if (fastcmp(field,"starpostz")) + break; + case player_starpostz: lua_pushinteger(L, plr->starpostz); - else if (fastcmp(field,"starpostnum")) + break; + case player_starpostnum: lua_pushinteger(L, plr->starpostnum); - else if (fastcmp(field,"starposttime")) + break; + case player_starposttime: lua_pushinteger(L, plr->starposttime); - else if (fastcmp(field,"starpostangle")) + break; + case player_starpostangle: lua_pushangle(L, plr->starpostangle); - else if (fastcmp(field,"starpostscale")) + break; + case player_starpostscale: lua_pushfixed(L, plr->starpostscale); - else if (fastcmp(field,"angle_pos")) + break; + case player_angle_pos: lua_pushangle(L, plr->angle_pos); - else if (fastcmp(field,"old_angle_pos")) + break; + case player_old_angle_pos: lua_pushangle(L, plr->old_angle_pos); - else if (fastcmp(field,"axis1")) + break; + case player_axis1: LUA_PushUserdata(L, plr->axis1, META_MOBJ); - else if (fastcmp(field,"axis2")) + break; + case player_axis2: LUA_PushUserdata(L, plr->axis2, META_MOBJ); - else if (fastcmp(field,"bumpertime")) + break; + case player_bumpertime: lua_pushinteger(L, plr->bumpertime); - else if (fastcmp(field,"flyangle")) + break; + case player_flyangle: lua_pushinteger(L, plr->flyangle); - else if (fastcmp(field,"drilltimer")) + break; + case player_drilltimer: lua_pushinteger(L, plr->drilltimer); - else if (fastcmp(field,"linkcount")) + break; + case player_linkcount: lua_pushinteger(L, plr->linkcount); - else if (fastcmp(field,"linktimer")) + break; + case player_linktimer: lua_pushinteger(L, plr->linktimer); - else if (fastcmp(field,"anotherflyangle")) + break; + case player_anotherflyangle: lua_pushinteger(L, plr->anotherflyangle); - else if (fastcmp(field,"nightstime")) + break; + case player_nightstime: lua_pushinteger(L, plr->nightstime); - else if (fastcmp(field,"drillmeter")) + break; + case player_drillmeter: lua_pushinteger(L, plr->drillmeter); - else if (fastcmp(field,"drilldelay")) + break; + case player_drilldelay: lua_pushinteger(L, plr->drilldelay); - else if (fastcmp(field,"bonustime")) + break; + case player_bonustime: lua_pushboolean(L, plr->bonustime); - else if (fastcmp(field,"capsule")) + break; + case player_capsule: LUA_PushUserdata(L, plr->capsule, META_MOBJ); - else if (fastcmp(field,"drone")) + break; + case player_drone: LUA_PushUserdata(L, plr->drone, META_MOBJ); - else if (fastcmp(field,"oldscale")) + break; + case player_oldscale: lua_pushfixed(L, plr->oldscale); - else if (fastcmp(field,"mare")) + break; + case player_mare: lua_pushinteger(L, plr->mare); - else if (fastcmp(field,"marelap")) + break; + case player_marelap: lua_pushinteger(L, plr->marelap); - else if (fastcmp(field,"marebonuslap")) + break; + case player_marebonuslap: lua_pushinteger(L, plr->marebonuslap); - else if (fastcmp(field,"marebegunat")) + break; + case player_marebegunat: lua_pushinteger(L, plr->marebegunat); - else if (fastcmp(field,"startedtime")) + break; + case player_startedtime: lua_pushinteger(L, plr->startedtime); - else if (fastcmp(field,"finishedtime")) + break; + case player_finishedtime: lua_pushinteger(L, plr->finishedtime); - else if (fastcmp(field,"lapbegunat")) + break; + case player_lapbegunat: lua_pushinteger(L, plr->lapbegunat); - else if (fastcmp(field,"lapstartedtime")) + break; + case player_lapstartedtime: lua_pushinteger(L, plr->lapstartedtime); - else if (fastcmp(field,"finishedspheres")) + break; + case player_finishedspheres: lua_pushinteger(L, plr->finishedspheres); - else if (fastcmp(field,"finishedrings")) + break; + case player_finishedrings: lua_pushinteger(L, plr->finishedrings); - else if (fastcmp(field,"marescore")) + break; + case player_marescore: lua_pushinteger(L, plr->marescore); - else if (fastcmp(field,"lastmarescore")) + break; + case player_lastmarescore: lua_pushinteger(L, plr->lastmarescore); - else if (fastcmp(field,"totalmarescore")) + break; + case player_totalmarescore: lua_pushinteger(L, plr->totalmarescore); - else if (fastcmp(field,"lastmare")) + break; + case player_lastmare: lua_pushinteger(L, plr->lastmare); - else if (fastcmp(field,"lastmarelap")) + break; + case player_lastmarelap: lua_pushinteger(L, plr->lastmarelap); - else if (fastcmp(field,"lastmarebonuslap")) + break; + case player_lastmarebonuslap: lua_pushinteger(L, plr->lastmarebonuslap); - else if (fastcmp(field,"totalmarelap")) + break; + case player_totalmarelap: lua_pushinteger(L, plr->totalmarelap); - else if (fastcmp(field,"totalmarebonuslap")) + break; + case player_totalmarebonuslap: lua_pushinteger(L, plr->totalmarebonuslap); - else if (fastcmp(field,"maxlink")) + break; + case player_maxlink: lua_pushinteger(L, plr->maxlink); - else if (fastcmp(field,"texttimer")) + break; + case player_texttimer: lua_pushinteger(L, plr->texttimer); - else if (fastcmp(field,"textvar")) + break; + case player_textvar: lua_pushinteger(L, plr->textvar); - else if (fastcmp(field,"lastsidehit")) + break; + case player_lastsidehit: lua_pushinteger(L, plr->lastsidehit); - else if (fastcmp(field,"lastlinehit")) + break; + case player_lastlinehit: lua_pushinteger(L, plr->lastlinehit); - else if (fastcmp(field,"losstime")) + break; + case player_losstime: lua_pushinteger(L, plr->losstime); - else if (fastcmp(field,"timeshit")) + break; + case player_timeshit: lua_pushinteger(L, plr->timeshit); - else if (fastcmp(field,"onconveyor")) + break; + case player_onconveyor: lua_pushinteger(L, plr->onconveyor); - else if (fastcmp(field,"awayviewmobj")) + break; + case player_awayviewmobj: LUA_PushUserdata(L, plr->awayviewmobj, META_MOBJ); - else if (fastcmp(field,"awayviewtics")) + break; + case player_awayviewtics: lua_pushinteger(L, plr->awayviewtics); - else if (fastcmp(field,"awayviewaiming")) + break; + case player_awayviewaiming: lua_pushangle(L, plr->awayviewaiming); - else if (fastcmp(field,"spectator")) + break; + case player_spectator: lua_pushboolean(L, plr->spectator); - else if (fastcmp(field,"outofcoop")) + break; + case player_outofcoop: lua_pushboolean(L, plr->outofcoop); - else if (fastcmp(field,"bot")) + break; + case player_bot: lua_pushinteger(L, plr->bot); - else if (fastcmp(field,"botleader")) + break; + case player_botleader: LUA_PushUserdata(L, plr->botleader, META_PLAYER); - else if (fastcmp(field,"lastbuttons")) + break; + case player_lastbuttons: lua_pushinteger(L, plr->lastbuttons); - else if (fastcmp(field,"blocked")) + break; + case player_blocked: lua_pushboolean(L, plr->blocked); - else if (fastcmp(field,"jointime")) + break; + case player_jointime: lua_pushinteger(L, plr->jointime); - else if (fastcmp(field,"quittime")) + break; + case player_quittime: lua_pushinteger(L, plr->quittime); + break; #ifdef HWRENDER - else if (fastcmp(field,"fovadd")) + case player_fovadd: lua_pushfixed(L, plr->fovadd); + break; #endif - else { + default: lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS); I_Assert(lua_istable(L, -1)); lua_pushlightuserdata(L, plr); lua_rawget(L, -2); if (!lua_istable(L, -1)) { // no extra values table - CONS_Debug(DBG_LUA, M_GetText("'%s' has no extvars table or field named '%s'; returning nil.\n"), "player_t", field); + CONS_Debug(DBG_LUA, M_GetText("'%s' has no extvars table or field named '%s'; returning nil.\n"), "player_t", lua_tostring(L, 2)); return 0; } - lua_getfield(L, -1, field); + lua_pushvalue(L, 2); // field name + lua_gettable(L, -2); if (lua_isnil(L, -1)) // no value for this field - CONS_Debug(DBG_LUA, M_GetText("'%s' has no field named '%s'; returning nil.\n"), "player_t", field); + CONS_Debug(DBG_LUA, M_GetText("'%s' has no field named '%s'; returning nil.\n"), "player_t", lua_tostring(L, 2)); + break; } return 1; @@ -405,7 +847,7 @@ static int player_get(lua_State *L) static int player_set(lua_State *L) { player_t *plr = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); - const char *field = luaL_checkstring(L, 2); + enum player_e field = Lua_optoption(L, 2, player_cmd, player_fields_ref); if (!plr) return LUA_ErrInvalid(L, "player_t"); @@ -414,337 +856,473 @@ static int player_set(lua_State *L) if (hook_cmd_running) return luaL_error(L, "Do not alter player_t in CMD building code!"); - if (fastcmp(field,"mo") || fastcmp(field,"realmo")) { + switch (field) + { + case player_mo: + case player_realmo: + { mobj_t *newmo = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); plr->mo->player = NULL; // remove player pointer from old mobj (newmo->player = plr)->mo = newmo; // set player pointer for new mobj, and set new mobj as the player's mobj + break; } - else if (fastcmp(field,"cmd")) + case player_cmd: return NOSET; - else if (fastcmp(field,"playerstate")) + case player_playerstate: plr->playerstate = luaL_checkinteger(L, 3); - else if (fastcmp(field,"camerascale")) + break; + case player_camerascale: plr->camerascale = luaL_checkfixed(L, 3); - else if (fastcmp(field,"shieldscale")) + break; + case player_shieldscale: plr->shieldscale = luaL_checkfixed(L, 3); - else if (fastcmp(field,"viewz")) + break; + case player_viewz: plr->viewz = luaL_checkfixed(L, 3); - else if (fastcmp(field,"viewheight")) + break; + case player_viewheight: plr->viewheight = luaL_checkfixed(L, 3); - else if (fastcmp(field,"deltaviewheight")) + break; + case player_deltaviewheight: plr->deltaviewheight = luaL_checkfixed(L, 3); - else if (fastcmp(field,"bob")) + break; + case player_bob: plr->bob = luaL_checkfixed(L, 3); - else if (fastcmp(field,"viewrollangle")) + break; + case player_viewrollangle: plr->viewrollangle = luaL_checkangle(L, 3); - else if (fastcmp(field,"aiming")) { + break; + case player_aiming: + { plr->aiming = luaL_checkangle(L, 3); if (plr == &players[consoleplayer]) localaiming = plr->aiming; else if (plr == &players[secondarydisplayplayer]) localaiming2 = plr->aiming; + break; } - else if (fastcmp(field,"drawangle")) + case player_drawangle: plr->drawangle = luaL_checkangle(L, 3); - else if (fastcmp(field,"rings")) + break; + case player_rings: plr->rings = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"spheres")) + break; + case player_spheres: plr->spheres = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"pity")) + break; + case player_pity: plr->pity = (SINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"currentweapon")) + break; + case player_currentweapon: plr->currentweapon = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"ringweapons")) + break; + case player_ringweapons: plr->ringweapons = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"ammoremoval")) + break; + case player_ammoremoval: plr->ammoremoval = (UINT16)luaL_checkinteger(L, 3); - else if (fastcmp(field,"ammoremovaltimer")) + break; + case player_ammoremovaltimer: plr->ammoremovaltimer = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"ammoremovalweapon")) + break; + case player_ammoremovalweapon: plr->ammoremovalweapon = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"powers")) + break; + case player_powers: return NOSET; - else if (fastcmp(field,"pflags")) + case player_pflags: plr->pflags = luaL_checkinteger(L, 3); - else if (fastcmp(field,"panim")) + break; + case player_panim: plr->panim = luaL_checkinteger(L, 3); - else if (fastcmp(field,"flashcount")) + break; + case player_flashcount: plr->flashcount = (UINT16)luaL_checkinteger(L, 3); - else if (fastcmp(field,"flashpal")) + break; + case player_flashpal: plr->flashpal = (UINT16)luaL_checkinteger(L, 3); - else if (fastcmp(field,"skincolor")) + break; + case player_skincolor: { UINT16 newcolor = (UINT16)luaL_checkinteger(L,3); if (newcolor >= numskincolors) return luaL_error(L, "player.skincolor %d out of range (0 - %d).", newcolor, numskincolors-1); plr->skincolor = newcolor; + break; } - else if (fastcmp(field,"skin")) + case player_skin: return NOSET; - else if (fastcmp(field,"availabilities")) + case player_availabilities: return NOSET; - else if (fastcmp(field,"score")) + case player_score: plr->score = (UINT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"dashspeed")) + break; + case player_dashspeed: plr->dashspeed = luaL_checkfixed(L, 3); - else if (fastcmp(field,"normalspeed")) + break; + case player_normalspeed: plr->normalspeed = luaL_checkfixed(L, 3); - else if (fastcmp(field,"runspeed")) + break; + case player_runspeed: plr->runspeed = luaL_checkfixed(L, 3); - else if (fastcmp(field,"thrustfactor")) + break; + case player_thrustfactor: plr->thrustfactor = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"accelstart")) + break; + case player_accelstart: plr->accelstart = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"acceleration")) + break; + case player_acceleration: plr->acceleration = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"charability")) + break; + case player_charability: plr->charability = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"charability2")) + break; + case player_charability2: plr->charability2 = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"charflags")) + break; + case player_charflags: plr->charflags = (UINT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"thokitem")) + break; + case player_thokitem: plr->thokitem = luaL_checkinteger(L, 3); - else if (fastcmp(field,"spinitem")) + break; + case player_spinitem: plr->spinitem = luaL_checkinteger(L, 3); - else if (fastcmp(field,"revitem")) + break; + case player_revitem: plr->revitem = luaL_checkinteger(L, 3); - else if (fastcmp(field,"followitem")) + break; + case player_followitem: plr->followitem = luaL_checkinteger(L, 3); - else if (fastcmp(field,"followmobj")) + break; + case player_followmobj: { mobj_t *mo = NULL; if (!lua_isnil(L, 3)) mo = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); P_SetTarget(&plr->followmobj, mo); + break; } - else if (fastcmp(field,"actionspd")) + case player_actionspd: plr->actionspd = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"mindash")) + break; + case player_mindash: plr->mindash = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"maxdash")) + break; + case player_maxdash: plr->maxdash = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"jumpfactor")) + break; + case player_jumpfactor: plr->jumpfactor = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"height")) + break; + case player_height: plr->height = luaL_checkfixed(L, 3); - else if (fastcmp(field,"spinheight")) + break; + case player_spinheight: plr->spinheight = luaL_checkfixed(L, 3); - else if (fastcmp(field,"lives")) + break; + case player_lives: plr->lives = (SINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"continues")) + break; + case player_continues: plr->continues = (SINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"xtralife")) + break; + case player_xtralife: plr->xtralife = (SINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"gotcontinue")) + break; + case player_gotcontinue: plr->gotcontinue = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"speed")) + break; + case player_speed: plr->speed = luaL_checkfixed(L, 3); - else if (fastcmp(field,"secondjump")) + break; + case player_secondjump: plr->secondjump = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"fly1")) + break; + case player_fly1: plr->fly1 = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"scoreadd")) + break; + case player_scoreadd: plr->scoreadd = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"glidetime")) + break; + case player_glidetime: plr->glidetime = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"climbing")) + break; + case player_climbing: plr->climbing = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"deadtimer")) + break; + case player_deadtimer: plr->deadtimer = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"exiting")) + break; + case player_exiting: plr->exiting = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"homing")) + break; + case player_homing: plr->homing = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"dashmode")) + break; + case player_dashmode: plr->dashmode = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"skidtime")) + break; + case player_skidtime: plr->skidtime = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"cmomx")) + break; + case player_cmomx: plr->cmomx = luaL_checkfixed(L, 3); - else if (fastcmp(field,"cmomy")) + break; + case player_cmomy: plr->cmomy = luaL_checkfixed(L, 3); - else if (fastcmp(field,"rmomx")) + break; + case player_rmomx: plr->rmomx = luaL_checkfixed(L, 3); - else if (fastcmp(field,"rmomy")) + break; + case player_rmomy: plr->rmomy = luaL_checkfixed(L, 3); - else if (fastcmp(field,"numboxes")) + break; + case player_numboxes: plr->numboxes = (INT16)luaL_checkinteger(L, 3); - else if (fastcmp(field,"totalring")) + break; + case player_totalring: plr->totalring = (INT16)luaL_checkinteger(L, 3); - else if (fastcmp(field,"realtime")) + break; + case player_realtime: plr->realtime = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"laps")) + break; + case player_laps: plr->laps = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"ctfteam")) + break; + case player_ctfteam: plr->ctfteam = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"gotflag")) + break; + case player_gotflag: plr->gotflag = (UINT16)luaL_checkinteger(L, 3); - else if (fastcmp(field,"weapondelay")) + break; + case player_weapondelay: plr->weapondelay = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"tossdelay")) + break; + case player_tossdelay: plr->tossdelay = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"starpostx")) + break; + case player_starpostx: plr->starpostx = (INT16)luaL_checkinteger(L, 3); - else if (fastcmp(field,"starposty")) + break; + case player_starposty: plr->starposty = (INT16)luaL_checkinteger(L, 3); - else if (fastcmp(field,"starpostz")) + break; + case player_starpostz: plr->starpostz = (INT16)luaL_checkinteger(L, 3); - else if (fastcmp(field,"starpostnum")) + break; + case player_starpostnum: plr->starpostnum = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"starposttime")) + break; + case player_starposttime: plr->starposttime = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"starpostangle")) + break; + case player_starpostangle: plr->starpostangle = luaL_checkangle(L, 3); - else if (fastcmp(field,"starpostscale")) + break; + case player_starpostscale: plr->starpostscale = luaL_checkfixed(L, 3); - else if (fastcmp(field,"angle_pos")) + break; + case player_angle_pos: plr->angle_pos = luaL_checkangle(L, 3); - else if (fastcmp(field,"old_angle_pos")) + break; + case player_old_angle_pos: plr->old_angle_pos = luaL_checkangle(L, 3); - else if (fastcmp(field,"axis1")) + break; + case player_axis1: { mobj_t *mo = NULL; if (!lua_isnil(L, 3)) mo = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); P_SetTarget(&plr->axis1, mo); + break; } - else if (fastcmp(field,"axis2")) + case player_axis2: { mobj_t *mo = NULL; if (!lua_isnil(L, 3)) mo = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); P_SetTarget(&plr->axis2, mo); + break; } - else if (fastcmp(field,"bumpertime")) + case player_bumpertime: plr->bumpertime = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"flyangle")) + break; + case player_flyangle: plr->flyangle = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"drilltimer")) + break; + case player_drilltimer: plr->drilltimer = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"linkcount")) + break; + case player_linkcount: plr->linkcount = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"linktimer")) + break; + case player_linktimer: plr->linktimer = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"anotherflyangle")) + break; + case player_anotherflyangle: plr->anotherflyangle = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"nightstime")) + break; + case player_nightstime: plr->nightstime = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"drillmeter")) + break; + case player_drillmeter: plr->drillmeter = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"drilldelay")) + break; + case player_drilldelay: plr->drilldelay = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"bonustime")) + break; + case player_bonustime: plr->bonustime = luaL_checkboolean(L, 3); - else if (fastcmp(field,"capsule")) + break; + case player_capsule: { mobj_t *mo = NULL; if (!lua_isnil(L, 3)) mo = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); P_SetTarget(&plr->capsule, mo); + break; } - else if (fastcmp(field,"drone")) + case player_drone: { mobj_t *mo = NULL; if (!lua_isnil(L, 3)) mo = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); P_SetTarget(&plr->drone, mo); + break; } - else if (fastcmp(field,"oldscale")) + case player_oldscale: plr->oldscale = luaL_checkfixed(L, 3); - else if (fastcmp(field,"mare")) + break; + case player_mare: plr->mare = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"marelap")) + break; + case player_marelap: plr->marelap = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"marebonuslap")) + break; + case player_marebonuslap: plr->marebonuslap = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"marebegunat")) + break; + case player_marebegunat: plr->marebegunat = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"startedtime")) + break; + case player_startedtime: plr->startedtime = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"finishedtime")) + break; + case player_finishedtime: plr->finishedtime = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"lapbegunat")) + break; + case player_lapbegunat: plr->lapbegunat = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"lapstartedtime")) + break; + case player_lapstartedtime: plr->lapstartedtime = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"finishedspheres")) + break; + case player_finishedspheres: plr->finishedspheres = (INT16)luaL_checkinteger(L, 3); - else if (fastcmp(field,"finishedrings")) + break; + case player_finishedrings: plr->finishedrings = (INT16)luaL_checkinteger(L, 3); - else if (fastcmp(field,"marescore")) + break; + case player_marescore: plr->marescore = (UINT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"lastmarescore")) + break; + case player_lastmarescore: plr->lastmarescore = (UINT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"totalmarescore")) + break; + case player_totalmarescore: plr->totalmarescore = (UINT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"lastmare")) + break; + case player_lastmare: plr->lastmare = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"lastmarelap")) + break; + case player_lastmarelap: plr->lastmarelap = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"lastmarebonuslap")) + break; + case player_lastmarebonuslap: plr->lastmarebonuslap = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"totalmarelap")) + break; + case player_totalmarelap: plr->totalmarelap = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"totalmarebonuslap")) + break; + case player_totalmarebonuslap: plr->totalmarebonuslap = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"maxlink")) + break; + case player_maxlink: plr->maxlink = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"texttimer")) + break; + case player_texttimer: plr->texttimer = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"textvar")) + break; + case player_textvar: plr->textvar = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"lastsidehit")) + break; + case player_lastsidehit: plr->lastsidehit = (INT16)luaL_checkinteger(L, 3); - else if (fastcmp(field,"lastlinehit")) + break; + case player_lastlinehit: plr->lastlinehit = (INT16)luaL_checkinteger(L, 3); - else if (fastcmp(field,"losstime")) + break; + case player_losstime: plr->losstime = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"timeshit")) + break; + case player_timeshit: plr->timeshit = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"onconveyor")) + break; + case player_onconveyor: plr->onconveyor = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"awayviewmobj")) + break; + case player_awayviewmobj: { mobj_t *mo = NULL; if (!lua_isnil(L, 3)) mo = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); P_SetTarget(&plr->awayviewmobj, mo); + break; } - else if (fastcmp(field,"awayviewtics")) - { + case player_awayviewtics: plr->awayviewtics = (INT32)luaL_checkinteger(L, 3); if (plr->awayviewtics && !plr->awayviewmobj) // awayviewtics must ALWAYS have an awayviewmobj set!! P_SetTarget(&plr->awayviewmobj, plr->mo); // but since the script might set awayviewmobj immediately AFTER setting awayviewtics, use player mobj as filler for now. - } - else if (fastcmp(field,"awayviewaiming")) + break; + case player_awayviewaiming: plr->awayviewaiming = luaL_checkangle(L, 3); - else if (fastcmp(field,"spectator")) + break; + case player_spectator: plr->spectator = lua_toboolean(L, 3); - else if (fastcmp(field,"outofcoop")) + break; + case player_outofcoop: plr->outofcoop = lua_toboolean(L, 3); - else if (fastcmp(field,"bot")) + break; + case player_bot: return NOSET; - else if (fastcmp(field,"botleader")) + case player_botleader: { player_t *player = NULL; if (!lua_isnil(L, 3)) player = *((player_t **)luaL_checkudata(L, 3, META_PLAYER)); plr->botleader = player; + break; } - else if (fastcmp(field,"lastbuttons")) + case player_lastbuttons: plr->lastbuttons = (UINT16)luaL_checkinteger(L, 3); - else if (fastcmp(field,"blocked")) + break; + case player_blocked: plr->blocked = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"jointime")) + break; + case player_jointime: plr->jointime = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"quittime")) + break; + case player_quittime: plr->quittime = (tic_t)luaL_checkinteger(L, 3); + break; #ifdef HWRENDER - else if (fastcmp(field,"fovadd")) + case player_fovadd: plr->fovadd = luaL_checkfixed(L, 3); + break; #endif - else { + default: lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS); I_Assert(lua_istable(L, -1)); lua_pushlightuserdata(L, plr); @@ -752,15 +1330,17 @@ static int player_set(lua_State *L) if (lua_isnil(L, -1)) { // This index doesn't have a table for extra values yet, let's make one. lua_pop(L, 1); - CONS_Debug(DBG_LUA, M_GetText("'%s' has no field named '%s'; adding it as Lua data.\n"), "player_t", field); + CONS_Debug(DBG_LUA, M_GetText("'%s' has no field named '%s'; adding it as Lua data.\n"), "player_t", lua_tostring(L, 2)); lua_newtable(L); lua_pushlightuserdata(L, plr); lua_pushvalue(L, -2); // ext value table lua_rawset(L, -4); // LREG_EXTVARS table } + lua_pushvalue(L, 2); // key lua_pushvalue(L, 3); // value to store - lua_setfield(L, -2, field); + lua_settable(L, -3); lua_pop(L, 2); + break; } return 0; @@ -814,27 +1394,58 @@ 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) +enum ticcmd_e +{ + ticcmd_forwardmove, + ticcmd_sidemove, + ticcmd_angleturn, + ticcmd_aiming, + ticcmd_buttons, + ticcmd_latency, +}; + +static const char *const ticcmd_opt[] = { + "forwardmove", + "sidemove", + "angleturn", + "aiming", + "buttons", + "latency", + NULL, +}; + +static int ticcmd_fields_ref = LUA_NOREF; + static int ticcmd_get(lua_State *L) { ticcmd_t *cmd = *((ticcmd_t **)luaL_checkudata(L, 1, META_TICCMD)); - const char *field = luaL_checkstring(L, 2); + enum ticcmd_e field = Lua_optoption(L, 2, -1, ticcmd_fields_ref); if (!cmd) return LUA_ErrInvalid(L, "player_t"); - if (fastcmp(field,"forwardmove")) + switch (field) + { + case ticcmd_forwardmove: lua_pushinteger(L, cmd->forwardmove); - else if (fastcmp(field,"sidemove")) + break; + case ticcmd_sidemove: lua_pushinteger(L, cmd->sidemove); - else if (fastcmp(field,"angleturn")) + break; + case ticcmd_angleturn: lua_pushinteger(L, cmd->angleturn); - else if (fastcmp(field,"aiming")) + break; + case ticcmd_aiming: lua_pushinteger(L, cmd->aiming); - else if (fastcmp(field,"buttons")) + break; + case ticcmd_buttons: lua_pushinteger(L, cmd->buttons); - else if (fastcmp(field,"latency")) + break; + case ticcmd_latency: lua_pushinteger(L, cmd->latency); - else + break; + default: return NOFIELD; + } return 1; } @@ -842,27 +1453,35 @@ static int ticcmd_get(lua_State *L) static int ticcmd_set(lua_State *L) { ticcmd_t *cmd = *((ticcmd_t **)luaL_checkudata(L, 1, META_TICCMD)); - const char *field = luaL_checkstring(L, 2); + enum ticcmd_e field = Lua_optoption(L, 2, -1, ticcmd_fields_ref); if (!cmd) return LUA_ErrInvalid(L, "ticcmd_t"); if (hud_running) return luaL_error(L, "Do not alter player_t in HUD rendering code!"); - if (fastcmp(field,"forwardmove")) + switch (field) + { + case ticcmd_forwardmove: cmd->forwardmove = (SINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"sidemove")) + break; + case ticcmd_sidemove: cmd->sidemove = (SINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"angleturn")) + break; + case ticcmd_angleturn: cmd->angleturn = (INT16)luaL_checkinteger(L, 3); - else if (fastcmp(field,"aiming")) + break; + case ticcmd_aiming: cmd->aiming = (INT16)luaL_checkinteger(L, 3); - else if (fastcmp(field,"buttons")) + break; + case ticcmd_buttons: cmd->buttons = (UINT16)luaL_checkinteger(L, 3); - else if (fastcmp(field,"latency")) + break; + case ticcmd_latency: return NOSET; - else + default: return NOFIELD; + } return 0; } @@ -883,6 +1502,8 @@ int LUA_PlayerLib(lua_State *L) lua_setfield(L, -2, "__len"); lua_pop(L,1); + player_fields_ref = Lua_CreateFieldTable(L, player_opt); + luaL_newmetatable(L, META_POWERS); lua_pushcfunction(L, power_get); lua_setfield(L, -2, "__index"); @@ -902,6 +1523,8 @@ int LUA_PlayerLib(lua_State *L) lua_setfield(L, -2, "__newindex"); lua_pop(L,1); + ticcmd_fields_ref = Lua_CreateFieldTable(L, ticcmd_opt); + lua_newuserdata(L, 0); lua_createtable(L, 0, 2); lua_pushcfunction(L, lib_getPlayer); diff --git a/src/lua_script.c b/src/lua_script.c index 9cb146c12..6893265d5 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -1729,17 +1729,39 @@ void LUA_UnArchive(void) } // For mobj_t, player_t, etc. to take custom variables. -int Lua_optoption(lua_State *L, int narg, - const char *def, const char *const lst[]) +int Lua_optoption(lua_State *L, int narg, int def, int list_ref) { - const char *name = (def) ? luaL_optstring(L, narg, def) : luaL_checkstring(L, narg); - int i; - for (i=0; lst[i]; i++) - if (fastcmp(lst[i], name)) - return i; + if (lua_isnoneornil(L, narg)) + return def; + + I_Assert(lua_checkstack(L, 2)); + luaL_checkstring(L, narg); + + lua_rawgeti(L, LUA_REGISTRYINDEX, list_ref); + I_Assert(lua_istable(L, -1)); + lua_pushvalue(L, narg); + lua_rawget(L, -2); + + if (lua_isnumber(L, -1)) + return lua_tointeger(L, -1); return -1; } +int Lua_CreateFieldTable(lua_State *L, const char *const lst[]) +{ + int i; + + lua_newtable(L); + for (i = 0; lst[i] != NULL; i++) + { + lua_pushstring(L, lst[i]); + lua_pushinteger(L, i); + lua_settable(L, -3); + } + + return luaL_ref(L, LUA_REGISTRYINDEX); +} + void LUA_PushTaggableObjectArray ( lua_State *L, const char *field, diff --git a/src/lua_script.h b/src/lua_script.h index fe04e5e60..d0b06a719 100644 --- a/src/lua_script.h +++ b/src/lua_script.h @@ -57,8 +57,8 @@ 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(void *cvar); // lua_consolelib.c -int Lua_optoption(lua_State *L, int narg, - const char *def, const char *const lst[]); +int Lua_optoption(lua_State *L, int narg, int def, int list_ref); +int Lua_CreateFieldTable(lua_State *L, const char *const lst[]); void LUA_HookNetArchive(lua_CFunction archFunc); void LUA_PushTaggableObjectArray diff --git a/src/lua_skinlib.c b/src/lua_skinlib.c index 5c21b04c3..b7890a6c7 100644 --- a/src/lua_skinlib.c +++ b/src/lua_skinlib.c @@ -55,6 +55,7 @@ enum skin { skin_soundsid, skin_sprites }; + static const char *const skin_opt[] = { "valid", "name", @@ -95,10 +96,12 @@ static const char *const skin_opt[] = { #define UNIMPLEMENTED luaL_error(L, LUA_QL("skin_t") " field " LUA_QS " is not implemented for Lua and cannot be accessed.", skin_opt[field]) +static int skin_fields_ref = LUA_NOREF; + static int skin_get(lua_State *L) { skin_t *skin = *((skin_t **)luaL_checkudata(L, 1, META_SKIN)); - enum skin field = luaL_checkoption(L, 2, NULL, skin_opt); + enum skin field = Lua_optoption(L, 2, -1, skin_fields_ref); // skins are always valid, only added, never removed I_Assert(skin != NULL); @@ -376,6 +379,8 @@ int LUA_SkinLib(lua_State *L) lua_setfield(L, -2, "__len"); lua_pop(L,1); + skin_fields_ref = Lua_CreateFieldTable(L, skin_opt); + luaL_newmetatable(L, META_SOUNDSID); lua_pushcfunction(L, soundsid_get); lua_setfield(L, -2, "__index"); From 17356f93bf1f77f582f68494d4ee2b1574ff36cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Mon, 19 Jun 2023 22:19:39 +0200 Subject: [PATCH 206/586] Fix segfault when ghost dies from a death pit --- src/p_mobj.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index a04351ae7..3eab29c09 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -3139,7 +3139,8 @@ boolean P_SceneryZMovement(mobj_t *mo) if (P_CheckDeathPitCollide(mo)) { - P_RemoveMobj(mo); + if (mo->type != MT_GHOST) // ghosts play death animations instead, so don't remove them + P_RemoveMobj(mo); return false; } From bbe6c12323703736722dc9b1813fe79f1be3eb0d Mon Sep 17 00:00:00 2001 From: Lach <54614944+lachablock@users.noreply.github.com> Date: Wed, 26 Oct 2022 22:44:25 +1100 Subject: [PATCH 207/586] Skincolor changes: - Tweaked Orange and Cobalt - Added Pepper, Jade, Headlight, Master, Mauve, and Taffy - Fixed Mario mode invincibility color cycle (Opposite color shades are placeholder for now) --- src/deh_tables.c | 6 ++++++ src/doomdef.h | 6 ++++++ src/info.c | 10 ++++++++-- src/p_user.c | 2 +- 4 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/deh_tables.c b/src/deh_tables.c index c3b2cfccd..79e01ef75 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -4623,6 +4623,7 @@ const char *COLOR_ENUMS[] = { // Viv's vivid colours (toast 21/07/17) "RUBY", // SKINCOLOR_RUBY, "SALMON", // SKINCOLOR_SALMON, + "PEPPER", // SKINCOLOR_PEPPER, "RED", // SKINCOLOR_RED, "CRIMSON", // SKINCOLOR_CRIMSON, "FLAME", // SKINCOLOR_FLAME, @@ -4644,7 +4645,10 @@ const char *COLOR_ENUMS[] = { "GREEN", // SKINCOLOR_GREEN, "FOREST", // SKINCOLOR_FOREST, "EMERALD", // SKINCOLOR_EMERALD, + "JADE", // SKINCOLOR_JADE, + "HEADLIGHT", // SKINCOLOR_HEADLIGHT, "MINT", // SKINCOLOR_MINT, + "MASTER", // SKINCOLOR_MASTER, "SEAFOAM", // SKINCOLOR_SEAFOAM, "AQUA", // SKINCOLOR_AQUA, "TEAL", // SKINCOLOR_TEAL, @@ -4666,8 +4670,10 @@ const char *COLOR_ENUMS[] = { "NEON", // SKINCOLOR_NEON, "VIOLET", // SKINCOLOR_VIOLET, "LILAC", // SKINCOLOR_LILAC, + "MAUVE", // SKINCOLOR_MAUVE, "PLUM", // SKINCOLOR_PLUM, "RASPBERRY", // SKINCOLOR_RASPBERRY, + "TAFFY", // SKINCOLOR_TAFFY, "ROSY", // SKINCOLOR_ROSY, // Super special awesome Super flashing colors! diff --git a/src/doomdef.h b/src/doomdef.h index d521d4fbb..a2243f5f3 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -275,6 +275,7 @@ typedef enum // Viv's vivid colours (toast 21/07/17) SKINCOLOR_RUBY, SKINCOLOR_SALMON, + SKINCOLOR_PEPPER, SKINCOLOR_RED, SKINCOLOR_CRIMSON, SKINCOLOR_FLAME, @@ -296,7 +297,10 @@ typedef enum SKINCOLOR_GREEN, SKINCOLOR_FOREST, SKINCOLOR_EMERALD, + SKINCOLOR_JADE, + SKINCOLOR_HEADLIGHT, SKINCOLOR_MINT, + SKINCOLOR_MASTER, SKINCOLOR_SEAFOAM, SKINCOLOR_AQUA, SKINCOLOR_TEAL, @@ -318,8 +322,10 @@ typedef enum SKINCOLOR_NEON, SKINCOLOR_VIOLET, SKINCOLOR_LILAC, + SKINCOLOR_MAUVE, SKINCOLOR_PLUM, SKINCOLOR_RASPBERRY, + SKINCOLOR_TAFFY, SKINCOLOR_ROSY, FIRSTSUPERCOLOR, diff --git a/src/info.c b/src/info.c index 09452a74f..fbcdcfc80 100644 --- a/src/info.c +++ b/src/info.c @@ -21600,6 +21600,7 @@ skincolor_t skincolors[MAXSKINCOLORS] = { // Viv's vivid colours (toast 21/07/17) {"Ruby", {0xb0, 0xb0, 0xc9, 0xca, 0xcc, 0x26, 0x27, 0x28, 0x29, 0x2a, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xfd}, SKINCOLOR_EMERALD, 10, V_REDMAP, true}, // SKINCOLOR_RUBY {"Salmon", {0xd0, 0xd0, 0xd1, 0xd2, 0x20, 0x21, 0x24, 0x25, 0x26, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e}, SKINCOLOR_FOREST, 6, V_REDMAP, true}, // SKINCOLOR_SALMON + {"Pepper", { 210, 32, 33, 34, 35, 35, 36, 37, 38, 39, 41, 43, 45, 45, 46, 47}, SKINCOLOR_MASTER, 8, V_REDMAP, true}, // SKINCOLOR_PEPPER {"Red", {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x47, 0x2e, 0x2f}, SKINCOLOR_GREEN, 10, V_REDMAP, true}, // SKINCOLOR_RED {"Crimson", {0x27, 0x27, 0x28, 0x28, 0x29, 0x2a, 0x2b, 0x2b, 0x2c, 0x2d, 0x2e, 0x2e, 0x2e, 0x2f, 0x2f, 0x1f}, SKINCOLOR_ICY, 10, V_REDMAP, true}, // SKINCOLOR_CRIMSON {"Flame", {0x31, 0x32, 0x33, 0x36, 0x22, 0x22, 0x25, 0x25, 0x25, 0xcd, 0xcf, 0xcf, 0xc5, 0xc5, 0xc7, 0xc7}, SKINCOLOR_PURPLE, 8, V_REDMAP, true}, // SKINCOLOR_FLAME @@ -21609,7 +21610,7 @@ skincolor_t skincolors[MAXSKINCOLORS] = { {"Sunset", {0x51, 0x52, 0x40, 0x40, 0x34, 0x36, 0xd5, 0xd5, 0xd6, 0xd7, 0xcf, 0xcf, 0xc6, 0xc6, 0xc7, 0xfe}, SKINCOLOR_SAPPHIRE, 5, V_ORANGEMAP, true}, // SKINCOLOR_SUNSET {"Copper", {0x58, 0x54, 0x40, 0x34, 0x35, 0x38, 0x3a, 0x3c, 0x3d, 0x2a, 0x2b, 0x2c, 0x2c, 0xba, 0xba, 0xbb}, SKINCOLOR_BLUEBELL, 5, V_ORANGEMAP, true}, // SKINCOLOR_COPPER {"Apricot", {0x00, 0xd8, 0xd9, 0xda, 0xdb, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e}, SKINCOLOR_CYAN, 4, V_ORANGEMAP, true}, // SKINCOLOR_APRICOT - {"Orange", {0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x2c}, SKINCOLOR_BLUE, 4, V_ORANGEMAP, true}, // SKINCOLOR_ORANGE + {"Orange", { 49, 50, 51, 52, 53, 54, 55, 57, 58, 59, 60, 42, 44, 45, 46, 46}, SKINCOLOR_BLUE, 4, V_ORANGEMAP, true}, // SKINCOLOR_ORANGE {"Rust", {0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3c, 0x3d, 0x3d, 0x3d, 0x3f, 0x2c, 0x2d, 0x47, 0x2e, 0x2f, 0x2f}, SKINCOLOR_YOGURT, 8, V_ORANGEMAP, true}, // SKINCOLOR_RUST {"Gold", {0x51, 0x51, 0x54, 0x54, 0x41, 0x42, 0x43, 0x43, 0x44, 0x45, 0x46, 0x3f, 0x2d, 0x2e, 0x2f, 0x2f}, SKINCOLOR_LAVENDER, 10, V_YELLOWMAP, true}, // SKINCOLOR_GOLD {"Sandy", {0x53, 0x40, 0x41, 0x42, 0x43, 0xe6, 0xe9, 0xe9, 0xea, 0xec, 0xec, 0xc6, 0xc6, 0xc7, 0xc7, 0xfe}, SKINCOLOR_SKY, 8, V_YELLOWMAP, true}, // SKINCOLOR_SANDY @@ -21621,7 +21622,10 @@ skincolor_t skincolors[MAXSKINCOLORS] = { {"Green", {0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f}, SKINCOLOR_RED, 6, V_GREENMAP, true}, // SKINCOLOR_GREEN {"Forest", {0x65, 0x66, 0x67, 0x68, 0x69, 0x69, 0x6a, 0x6b, 0x6b, 0x6c, 0x6d, 0x6d, 0x6e, 0x6e, 0x6e, 0x6f}, SKINCOLOR_SALMON, 9, V_GREENMAP, true}, // SKINCOLOR_FOREST {"Emerald", {0x70, 0x70, 0x71, 0x71, 0x72, 0x72, 0x73, 0x73, 0x73, 0x74, 0x75, 0x75, 0x76, 0x76, 0x77, 0x77}, SKINCOLOR_RUBY, 4, V_GREENMAP, true}, // SKINCOLOR_EMERALD + {"Jade", { 128, 120, 121, 122, 122, 113, 114, 114, 115, 116, 117, 118, 119, 110, 111, 30}, SKINCOLOR_TAFFY, 8, V_GREENMAP, true}, // SKINCOLOR_JADE + {"Headlight", { 0, 80, 81, 82, 73, 84, 64, 65, 91, 91, 124, 125, 126, 137, 138, 139}, SKINCOLOR_MAUVE, 8, V_YELLOWMAP, true}, // SKINCOLOR_HEADLIGHT {"Mint", {0x00, 0x00, 0x58, 0x58, 0x59, 0x62, 0x62, 0x62, 0x64, 0x67, 0x7e, 0x7e, 0x8f, 0x8f, 0x8a, 0x8a}, SKINCOLOR_VIOLET, 5, V_GREENMAP, true}, // SKINCOLOR_MINT + {"Master", { 0, 80, 88, 96, 112, 113, 99, 100, 124, 125, 126, 117, 107, 118, 119, 111}, SKINCOLOR_PEPPER, 8, V_GREENMAP, true}, // SKINCOLOR_MASTER {"Seafoam", {0x01, 0x58, 0x59, 0x5a, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x8f, 0x8f, 0x8a, 0x8a, 0x8a, 0xfd, 0xfd}, SKINCOLOR_PLUM, 6, V_AQUAMAP, true}, // SKINCOLOR_SEAFOAM {"Aqua", {0x78, 0x79, 0x7a, 0x7a, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7d, 0x7e, 0x7e, 0x7f, 0x7f, 0x76, 0x77}, SKINCOLOR_ROSY, 7, V_AQUAMAP, true}, // SKINCOLOR_AQUA {"Teal", {0x78, 0x78, 0x8c, 0x8c, 0x8d, 0x8d, 0x8d, 0x8e, 0x8e, 0x8f, 0x8f, 0x8f, 0x8a, 0x8a, 0x8a, 0x8a}, SKINCOLOR_PEACHY, 7, V_SKYMAP, true}, // SKINCOLOR_TEAL @@ -21633,7 +21637,7 @@ skincolor_t skincolors[MAXSKINCOLORS] = { {"Sapphire", {0x80, 0x83, 0x86, 0x87, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xfd, 0xfe}, SKINCOLOR_SUNSET, 5, V_SKYMAP, true}, // SKINCOLOR_SAPPHIRE {"Cornflower", {0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x9a, 0x9c, 0x9d, 0x9d, 0x9e, 0x9e, 0x9e}, SKINCOLOR_YELLOW, 4, V_BLUEMAP, true}, // SKINCOLOR_CORNFLOWER {"Blue", {0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xfd, 0xfe}, SKINCOLOR_ORANGE, 5, V_BLUEMAP, true}, // SKINCOLOR_BLUE - {"Cobalt", {0x93, 0x94, 0x95, 0x96, 0x98, 0x9a, 0x9b, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xfd, 0xfd, 0xfe, 0xfe}, SKINCOLOR_PERIDOT, 5, V_BLUEMAP, true}, // SKINCOLOR_COBALT + {"Cobalt", { 145, 147, 149, 150, 151, 153, 154, 155, 156, 157, 158, 159, 253, 253, 254, 254}, SKINCOLOR_PERIDOT, 5, V_BLUEMAP, true}, // SKINCOLOR_COBALT {"Vapor", {0x80, 0x81, 0x83, 0x86, 0x94, 0x94, 0xa3, 0xa3, 0xa4, 0xa6, 0xa6, 0xa6, 0xa8, 0xa8, 0xa9, 0xa9}, SKINCOLOR_LILAC, 4, V_SKYMAP, true}, // SKINCOLOR_VAPOR {"Dusk", {0x92, 0x93, 0x94, 0x94, 0xac, 0xad, 0xad, 0xad, 0xae, 0xae, 0xaf, 0xaf, 0xa9, 0xa9, 0xfd, 0xfd}, SKINCOLOR_OLIVE, 0, V_BLUEMAP, true}, // SKINCOLOR_DUSK {"Pastel", {0x90, 0x90, 0xa0, 0xa0, 0xa1, 0xa1, 0xa2, 0xa2, 0xa2, 0xa3, 0xa4, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8}, SKINCOLOR_BUBBLEGUM, 9, V_PURPLEMAP, true}, // SKINCOLOR_PASTEL @@ -21643,8 +21647,10 @@ skincolor_t skincolors[MAXSKINCOLORS] = { {"Neon", {0xb3, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xbb, 0xc7, 0xc7, 0x1d, 0x1d, 0x1e}, SKINCOLOR_CERULEAN, 2, V_MAGENTAMAP, true}, // SKINCOLOR_NEON {"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 + {"Mauve", { 176, 177, 178, 192, 193, 194, 195, 195, 196, 185, 185, 186, 186, 187, 187, 253}, SKINCOLOR_HEADLIGHT, 8, V_PURPLEMAP, true}, // SKINCOLOR_MAUVE {"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 + {"Taffy", { 1, 176, 176, 177, 178, 179, 202, 203, 204, 204, 206, 207, 44, 44, 46, 47}, SKINCOLOR_JADE, 8, V_ROSYMAP, true}, // SKINCOLOR_TAFFY {"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 diff --git a/src/p_user.c b/src/p_user.c index 0f3282da5..38af2843b 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2984,7 +2984,7 @@ static void P_CheckInvincibilityTimer(player_t *player) return; if (mariomode && !player->powers[pw_super]) - player->mo->color = (UINT16)(SKINCOLOR_RUBY + (leveltime % (numskincolors - SKINCOLOR_RUBY))); // Passes through all saturated colours + player->mo->color = (UINT16)(SKINCOLOR_RUBY + (leveltime % (FIRSTSUPERCOLOR - SKINCOLOR_RUBY))); // Passes through all saturated colours else if (leveltime % (TICRATE/7) == 0) { mobj_t *sparkle = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_IVSP); From 222e409cde6e212b2eec61268b78ac83a7cf1051 Mon Sep 17 00:00:00 2001 From: spherallic Date: Thu, 27 Oct 2022 00:24:12 +0200 Subject: [PATCH 208/586] More skincolor changes: - Tweaked Bubblegum - Added 8 new colors by Alice - Added 22 new colors by sphere --- src/deh_tables.c | 31 +++++++++++++++++++++++++++++++ src/doomdef.h | 31 +++++++++++++++++++++++++++++++ src/info.c | 33 ++++++++++++++++++++++++++++++++- 3 files changed, 94 insertions(+), 1 deletion(-) diff --git a/src/deh_tables.c b/src/deh_tables.c index 79e01ef75..7ee78218b 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -4609,19 +4609,28 @@ const char *COLOR_ENUMS[] = { // Desaturated "AETHER", // SKINCOLOR_AETHER, "SLATE", // SKINCOLOR_SLATE, + "MERCURY", // SKINCOLOR_MERCURY, "BLUEBELL", // SKINCOLOR_BLUEBELL, "PINK", // SKINCOLOR_PINK, + "ROSEWOOD", // SKINCOLOR_ROSEWOOD, "YOGURT", // SKINCOLOR_YOGURT, + "LATTE", // SKINCOLOR_LATTE, "BROWN", // SKINCOLOR_BROWN, "BRONZE", // SKINCOLOR_BRONZE, + "SEPIA", // SKINCOLOR_SEPIA, + "ECRU", // SKINCOLOR_ECRU, "TAN", // SKINCOLOR_TAN, "BEIGE", // SKINCOLOR_BEIGE, + "ROSEBUSH", // SKINCOLOR_ROSEBUSH, "MOSS", // SKINCOLOR_MOSS, "AZURE", // SKINCOLOR_AZURE, + "EGGPLANT", // SKINCOLOR_EGGPLANT, "LAVENDER", // SKINCOLOR_LAVENDER, // Viv's vivid colours (toast 21/07/17) + // Tweaks & additions (Lach, sphere, Alice, MotorRoach 26/10/22) "RUBY", // SKINCOLOR_RUBY, + "CHERRY", // SKINCOLOR_CHERRY, "SALMON", // SKINCOLOR_SALMON, "PEPPER", // SKINCOLOR_PEPPER, "RED", // SKINCOLOR_RED, @@ -4630,18 +4639,24 @@ const char *COLOR_ENUMS[] = { "KETCHUP", // SKINCOLOR_KETCHUP, "PEACHY", // SKINCOLOR_PEACHY, "QUAIL", // SKINCOLOR_QUAIL, + "FOUNDATION", // SKINCOLOR_FOUNDATION, "SUNSET", // SKINCOLOR_SUNSET, "COPPER", // SKINCOLOR_COPPER, "APRICOT", // SKINCOLOR_APRICOT, "ORANGE", // SKINCOLOR_ORANGE, + "PUMPKIN", // SKINCOLOR_PUMPKIN, "RUST", // SKINCOLOR_RUST, "GOLD", // SKINCOLOR_GOLD, "SANDY", // SKINCOLOR_SANDY, "YELLOW", // SKINCOLOR_YELLOW, "OLIVE", // SKINCOLOR_OLIVE, + "KIWI", // SKINCOLOR_KIWI, + "LEMON", // SKINCOLOR_LEMON, "LIME", // SKINCOLOR_LIME, + "MINDARO", // SKINCOLOR_MINDARO, "PERIDOT", // SKINCOLOR_PERIDOT, "APPLE", // SKINCOLOR_APPLE, + "CHARTREUSE", // SKINCOLOR_CHARTREUSE, "GREEN", // SKINCOLOR_GREEN, "FOREST", // SKINCOLOR_FOREST, "EMERALD", // SKINCOLOR_EMERALD, @@ -4649,32 +4664,48 @@ const char *COLOR_ENUMS[] = { "HEADLIGHT", // SKINCOLOR_HEADLIGHT, "MINT", // SKINCOLOR_MINT, "MASTER", // SKINCOLOR_MASTER, + "BOTTLE", // SKINCOLOR_BOTTLE, "SEAFOAM", // SKINCOLOR_SEAFOAM, + "ISLAND", // SKINCOLOR_ISLAND, "AQUA", // SKINCOLOR_AQUA, "TEAL", // SKINCOLOR_TEAL, "WAVE", // SKINCOLOR_WAVE, "CYAN", // SKINCOLOR_CYAN, + "TURQUOISE", // SKINCOLOR_TURQUOISE, "SKY", // SKINCOLOR_SKY, + "MARINE", // SKINCOLOR_MARINE, "CERULEAN", // SKINCOLOR_CERULEAN, + "DREAM", // SKINCOLOR_DREAM, "ICY", // SKINCOLOR_ICY, + "DAYBREAK", // SKINCOLOR_DAYBREAK, "SAPPHIRE", // SKINCOLOR_SAPPHIRE, + "ARCTIC", // SKINCOLOR_ARCTIC, "CORNFLOWER", // SKINCOLOR_CORNFLOWER, "BLUE", // SKINCOLOR_BLUE, "COBALT", // SKINCOLOR_COBALT, + "MIDNIGHT", // SKINCOLOR_MIDNIGHT, + "GALAXY", // SKINCOLOR_GALAXY, "VAPOR", // SKINCOLOR_VAPOR, "DUSK", // SKINCOLOR_DUSK, + "MAJESTY", // SKINCOLOR_MAJESTY, "PASTEL", // SKINCOLOR_PASTEL, "PURPLE", // SKINCOLOR_PURPLE, + "NOBLE", // SKINCOLOR_NOBLE, + "FUCHSIA", // SKINCOLOR_FUCHSIA, "BUBBLEGUM", // SKINCOLOR_BUBBLEGUM, "MAGENTA", // SKINCOLOR_MAGENTA, "NEON", // SKINCOLOR_NEON, "VIOLET", // SKINCOLOR_VIOLET, + "ROYAL", // SKINCOLOR_ROYAL, "LILAC", // SKINCOLOR_LILAC, "MAUVE", // SKINCOLOR_MAUVE, + "EVENTIDE", // SKINCOLOR_EVENTIDE, "PLUM", // SKINCOLOR_PLUM, "RASPBERRY", // SKINCOLOR_RASPBERRY, "TAFFY", // SKINCOLOR_TAFFY, "ROSY", // SKINCOLOR_ROSY, + "FANCY", // SKINCOLOR_FANCY, + "SANGRIA", // SKINCOLOR_SANGRIA, // Super special awesome Super flashing colors! "SUPERSILVER1", // SKINCOLOR_SUPERSILVER1 diff --git a/src/doomdef.h b/src/doomdef.h index a2243f5f3..f21000cda 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -261,19 +261,28 @@ typedef enum // Desaturated SKINCOLOR_AETHER, SKINCOLOR_SLATE, + SKINCOLOR_MERCURY, SKINCOLOR_BLUEBELL, SKINCOLOR_PINK, + SKINCOLOR_ROSEWOOD, SKINCOLOR_YOGURT, + SKINCOLOR_LATTE, SKINCOLOR_BROWN, SKINCOLOR_BRONZE, + SKINCOLOR_SEPIA, + SKINCOLOR_ECRU, SKINCOLOR_TAN, SKINCOLOR_BEIGE, + SKINCOLOR_ROSEBUSH, SKINCOLOR_MOSS, SKINCOLOR_AZURE, + SKINCOLOR_EGGPLANT, SKINCOLOR_LAVENDER, // Viv's vivid colours (toast 21/07/17) + // Tweaks & additions (Lach, sphere, Alice, MotorRoach 26/10/22) SKINCOLOR_RUBY, + SKINCOLOR_CHERRY, SKINCOLOR_SALMON, SKINCOLOR_PEPPER, SKINCOLOR_RED, @@ -282,18 +291,24 @@ typedef enum SKINCOLOR_KETCHUP, SKINCOLOR_PEACHY, SKINCOLOR_QUAIL, + SKINCOLOR_FOUNDATION, SKINCOLOR_SUNSET, SKINCOLOR_COPPER, SKINCOLOR_APRICOT, SKINCOLOR_ORANGE, + SKINCOLOR_PUMPKIN, SKINCOLOR_RUST, SKINCOLOR_GOLD, SKINCOLOR_SANDY, SKINCOLOR_YELLOW, SKINCOLOR_OLIVE, + SKINCOLOR_KIWI, + SKINCOLOR_LEMON, SKINCOLOR_LIME, + SKINCOLOR_MINDARO, SKINCOLOR_PERIDOT, SKINCOLOR_APPLE, + SKINCOLOR_CHARTREUSE, SKINCOLOR_GREEN, SKINCOLOR_FOREST, SKINCOLOR_EMERALD, @@ -301,32 +316,48 @@ typedef enum SKINCOLOR_HEADLIGHT, SKINCOLOR_MINT, SKINCOLOR_MASTER, + SKINCOLOR_BOTTLE, SKINCOLOR_SEAFOAM, + SKINCOLOR_ISLAND, SKINCOLOR_AQUA, SKINCOLOR_TEAL, SKINCOLOR_WAVE, SKINCOLOR_CYAN, + SKINCOLOR_TURQUOISE, SKINCOLOR_SKY, + SKINCOLOR_MARINE, SKINCOLOR_CERULEAN, + SKINCOLOR_DREAM, SKINCOLOR_ICY, + SKINCOLOR_DAYBREAK, SKINCOLOR_SAPPHIRE, // sweet mother, i cannot weave – slender aphrodite has overcome me with longing for a girl + SKINCOLOR_ARCTIC, SKINCOLOR_CORNFLOWER, SKINCOLOR_BLUE, SKINCOLOR_COBALT, + SKINCOLOR_MIDNIGHT, + SKINCOLOR_GALAXY, SKINCOLOR_VAPOR, SKINCOLOR_DUSK, + SKINCOLOR_MAJESTY, SKINCOLOR_PASTEL, SKINCOLOR_PURPLE, + SKINCOLOR_NOBLE, + SKINCOLOR_FUCHSIA, SKINCOLOR_BUBBLEGUM, SKINCOLOR_MAGENTA, SKINCOLOR_NEON, SKINCOLOR_VIOLET, + SKINCOLOR_ROYAL, SKINCOLOR_LILAC, SKINCOLOR_MAUVE, + SKINCOLOR_EVENTIDE, SKINCOLOR_PLUM, SKINCOLOR_RASPBERRY, SKINCOLOR_TAFFY, SKINCOLOR_ROSY, + SKINCOLOR_FANCY, + SKINCOLOR_SANGRIA, FIRSTSUPERCOLOR, diff --git a/src/info.c b/src/info.c index fbcdcfc80..10b05dee4 100644 --- a/src/info.c +++ b/src/info.c @@ -21586,19 +21586,28 @@ skincolor_t skincolors[MAXSKINCOLORS] = { // Desaturated {"Aether", {0x00, 0x00, 0x01, 0x02, 0x02, 0x03, 0x91, 0x91, 0x91, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xaf}, SKINCOLOR_GREY, 15, 0, true}, // SKINCOLOR_AETHER {"Slate", {0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0xaa, 0xaa, 0xaa, 0xab, 0xac, 0xac, 0xad, 0xad, 0xae, 0xaf}, SKINCOLOR_SILVER, 12, 0, true}, // SKINCOLOR_SLATE + {"Mercury", { 0, 3, 4, 7, 11, 12, 14, 15, 171, 172, 173, 155, 157, 159, 253, 254}, SKINCOLOR_ECRU, 15, V_AZUREMAP, true}, // SKINCOLOR_MERCURY {"Bluebell", {0x90, 0x91, 0x92, 0x93, 0x94, 0x94, 0x95, 0xac, 0xac, 0xad, 0xad, 0xa8, 0xa8, 0xa9, 0xfd, 0xfe}, SKINCOLOR_COPPER, 4, V_BLUEMAP, true}, // SKINCOLOR_BLUEBELL {"Pink", {0xd0, 0xd0, 0xd1, 0xd1, 0xd2, 0xd2, 0xd3, 0xd3, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0x2b, 0x2c, 0x2e}, SKINCOLOR_AZURE, 9, V_REDMAP, true}, // SKINCOLOR_PINK + {"Rosewood", { 209, 210, 211, 212, 213, 214, 228, 230, 232, 234, 235, 237, 26, 27, 28, 29}, SKINCOLOR_SEPIA, 5, V_BROWNMAP, true}, // SKINCOLOR_ROSEWOOD {"Yogurt", {0xd0, 0x30, 0xd8, 0xd9, 0xda, 0xdb, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe3, 0xe6, 0xe8, 0xe9}, SKINCOLOR_RUST, 7, V_BROWNMAP, true}, // SKINCOLOR_YOGURT + {"Latte", { 48, 217, 219, 221, 223, 224, 226, 228, 68, 69, 70, 70, 44, 45, 46, 47}, SKINCOLOR_BOTTLE, 14, V_BROWNMAP, true}, // SKINCOLOR_LATTE {"Brown", {0xdf, 0xe0, 0xe1, 0xe2, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef}, SKINCOLOR_TAN, 2, V_BROWNMAP, true}, // SKINCOLOR_BROWN {"Bronze", {0xde, 0xe0, 0xe1, 0xe4, 0xe7, 0xe9, 0xeb, 0xec, 0xed, 0xed, 0xed, 0x19, 0x19, 0x1b, 0x1d, 0x1e}, SKINCOLOR_KETCHUP, 0, V_BROWNMAP, true}, // SKINCOLOR_BRONZE + {"Sepia", { 88, 84, 85, 86, 224, 226, 228, 230, 232, 235, 236, 237, 238, 239, 28, 28}, SKINCOLOR_ROSEWOOD,5, V_BROWNMAP, true}, // SKINCOLOR_SEPIA + {"Ecru", { 80, 83, 84, 85, 86, 242, 243, 245, 230, 232, 234, 236, 238, 239, 47, 47}, SKINCOLOR_MERCURY, 15, V_BROWNMAP, true}, // SKINCOLOR_ECRU {"Tan", {0x51, 0x51, 0x54, 0x54, 0x55, 0x55, 0x56, 0x56, 0x56, 0x57, 0xf5, 0xf5, 0xf9, 0xf9, 0xed, 0xed}, SKINCOLOR_BROWN, 12, V_BROWNMAP, true}, // SKINCOLOR_TAN {"Beige", {0x54, 0x55, 0x56, 0x56, 0xf2, 0xf3, 0xf3, 0xf4, 0xf5, 0xf6, 0xf8, 0xf9, 0xfa, 0xfb, 0xed, 0xed}, SKINCOLOR_MOSS, 5, V_BROWNMAP, true}, // SKINCOLOR_BEIGE + {"Rosebush", { 208, 216, 209, 85, 90, 91, 91, 92, 191, 93, 94, 107, 109, 110, 111, 111}, SKINCOLOR_EGGPLANT,5, V_GREENMAP, true}, // SKINCOLOR_ROSEBUSH {"Moss", {0x58, 0x58, 0x59, 0x59, 0x5a, 0x5a, 0x5b, 0x5b, 0x5b, 0x5c, 0x5d, 0x5d, 0x5e, 0x5e, 0x5f, 0x5f}, SKINCOLOR_BEIGE, 13, V_GREENMAP, true}, // SKINCOLOR_MOSS {"Azure", {0x90, 0x90, 0x91, 0x91, 0xaa, 0xaa, 0xab, 0xab, 0xab, 0xac, 0xad, 0xad, 0xae, 0xae, 0xaf, 0xaf}, SKINCOLOR_PINK, 5, V_AZUREMAP, true}, // SKINCOLOR_AZURE + {"Eggplant", { 4, 8, 11, 11, 16, 195, 195, 195, 196, 186, 187, 187, 254, 254, 30, 31}, SKINCOLOR_ROSEBUSH,5, V_PURPLEMAP, true}, // SKINCOLOR_EGGPLANT {"Lavender", {0xc0, 0xc0, 0xc1, 0xc1, 0xc2, 0xc2, 0xc3, 0xc3, 0xc3, 0xc4, 0xc5, 0xc5, 0xc6, 0xc6, 0xc7, 0xc7}, SKINCOLOR_GOLD, 4, V_PURPLEMAP, true}, // SKINCOLOR_LAVENDER // Viv's vivid colours (toast 21/07/17) + // Tweaks & additions (Lach, sphere, Alice, MotorRoach 26/10/22) {"Ruby", {0xb0, 0xb0, 0xc9, 0xca, 0xcc, 0x26, 0x27, 0x28, 0x29, 0x2a, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xfd}, SKINCOLOR_EMERALD, 10, V_REDMAP, true}, // SKINCOLOR_RUBY + {"Cherry", { 202, 203, 204, 205, 206, 40, 41, 42, 43, 44, 186, 187, 28, 29, 30, 31}, SKINCOLOR_MIDNIGHT, 10, V_REDMAP, true}, // SKINCOLOR_CHERRY {"Salmon", {0xd0, 0xd0, 0xd1, 0xd2, 0x20, 0x21, 0x24, 0x25, 0x26, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e}, SKINCOLOR_FOREST, 6, V_REDMAP, true}, // SKINCOLOR_SALMON {"Pepper", { 210, 32, 33, 34, 35, 35, 36, 37, 38, 39, 41, 43, 45, 45, 46, 47}, SKINCOLOR_MASTER, 8, V_REDMAP, true}, // SKINCOLOR_PEPPER {"Red", {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x47, 0x2e, 0x2f}, SKINCOLOR_GREEN, 10, V_REDMAP, true}, // SKINCOLOR_RED @@ -21607,18 +21616,24 @@ skincolor_t skincolors[MAXSKINCOLORS] = { {"Ketchup", {0x48, 0x49, 0x40, 0x33, 0x34, 0x36, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2b, 0x2c, 0x47, 0x2e, 0x2f}, SKINCOLOR_BRONZE, 8, V_REDMAP, true}, // SKINCOLOR_KETCHUP {"Peachy", {0xd0, 0x30, 0x31, 0x31, 0x32, 0x32, 0xdc, 0xdc, 0xdc, 0xd3, 0xd4, 0xd4, 0xcc, 0xcd, 0xce, 0xcf}, SKINCOLOR_TEAL, 7, V_ROSYMAP, true}, // SKINCOLOR_PEACHY {"Quail", {0xd8, 0xd9, 0xdb, 0xdc, 0xde, 0xdf, 0xd5, 0xd5, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0x1d, 0x1f}, SKINCOLOR_WAVE, 5, V_BROWNMAP, true}, // SKINCOLOR_QUAIL + {"Foundation", { 80, 81, 82, 84, 219, 221, 221, 212, 213, 214, 215, 195, 196, 186, 187, 30}, SKINCOLOR_DREAM, 9, V_ORANGEMAP, true}, // SKINCOLOR_FOUNDATION {"Sunset", {0x51, 0x52, 0x40, 0x40, 0x34, 0x36, 0xd5, 0xd5, 0xd6, 0xd7, 0xcf, 0xcf, 0xc6, 0xc6, 0xc7, 0xfe}, SKINCOLOR_SAPPHIRE, 5, V_ORANGEMAP, true}, // SKINCOLOR_SUNSET {"Copper", {0x58, 0x54, 0x40, 0x34, 0x35, 0x38, 0x3a, 0x3c, 0x3d, 0x2a, 0x2b, 0x2c, 0x2c, 0xba, 0xba, 0xbb}, SKINCOLOR_BLUEBELL, 5, V_ORANGEMAP, true}, // SKINCOLOR_COPPER {"Apricot", {0x00, 0xd8, 0xd9, 0xda, 0xdb, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e}, SKINCOLOR_CYAN, 4, V_ORANGEMAP, true}, // SKINCOLOR_APRICOT {"Orange", { 49, 50, 51, 52, 53, 54, 55, 57, 58, 59, 60, 42, 44, 45, 46, 46}, SKINCOLOR_BLUE, 4, V_ORANGEMAP, true}, // SKINCOLOR_ORANGE + {"Pumpkin", { 51, 52, 53, 54, 56, 58, 59, 59, 61, 61, 63, 45, 46, 47, 47, 31}, SKINCOLOR_ARCTIC, 10, V_ORANGEMAP, true}, // SKINCOLOR_PUMPKIN {"Rust", {0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3c, 0x3d, 0x3d, 0x3d, 0x3f, 0x2c, 0x2d, 0x47, 0x2e, 0x2f, 0x2f}, SKINCOLOR_YOGURT, 8, V_ORANGEMAP, true}, // SKINCOLOR_RUST {"Gold", {0x51, 0x51, 0x54, 0x54, 0x41, 0x42, 0x43, 0x43, 0x44, 0x45, 0x46, 0x3f, 0x2d, 0x2e, 0x2f, 0x2f}, SKINCOLOR_LAVENDER, 10, V_YELLOWMAP, true}, // SKINCOLOR_GOLD {"Sandy", {0x53, 0x40, 0x41, 0x42, 0x43, 0xe6, 0xe9, 0xe9, 0xea, 0xec, 0xec, 0xc6, 0xc6, 0xc7, 0xc7, 0xfe}, SKINCOLOR_SKY, 8, V_YELLOWMAP, true}, // SKINCOLOR_SANDY {"Yellow", {0x52, 0x53, 0x49, 0x49, 0x4a, 0x4a, 0x4b, 0x4b, 0x4b, 0x4c, 0x4d, 0x4d, 0x4e, 0x4e, 0x4f, 0xed}, SKINCOLOR_CORNFLOWER, 8, V_YELLOWMAP, true}, // SKINCOLOR_YELLOW {"Olive", {0x4b, 0x4b, 0x4c, 0x4c, 0x4d, 0x4e, 0xe7, 0xe7, 0xe9, 0xc5, 0xc5, 0xc6, 0xc6, 0xc7, 0xc7, 0xfd}, SKINCOLOR_DUSK, 3, V_YELLOWMAP, true}, // SKINCOLOR_OLIVE + {"Kiwi", { 88, 64, 188, 189, 189, 76, 76, 67, 67, 68, 69, 70, 45, 46, 47, 47}, SKINCOLOR_MARINE, 7, V_PERIDOTMAP, true}, // SKINCOLOR_KIWI + {"Lemon", { 0, 80, 81, 83, 73, 73, 74, 74, 76, 76, 191, 191, 79, 79, 110, 111}, SKINCOLOR_FUCHSIA, 6, V_YELLOWMAP, true}, // SKINCOLOR_LEMON {"Lime", {0x50, 0x51, 0x52, 0x53, 0x48, 0xbc, 0xbd, 0xbe, 0xbe, 0xbf, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f}, SKINCOLOR_MAGENTA, 9, V_PERIDOTMAP, true}, // SKINCOLOR_LIME + {"Mindaro", { 0, 80, 81, 82, 83, 64, 188, 189, 189, 190, 115, 116, 117, 118, 119, 111}, SKINCOLOR_MAJESTY, 11, V_PERIDOTMAP, true}, // SKINCOLOR_MINDARO {"Peridot", {0x58, 0x58, 0xbc, 0xbc, 0xbd, 0xbd, 0xbe, 0xbe, 0xbe, 0xbf, 0x5e, 0x5e, 0x5f, 0x5f, 0x77, 0x77}, SKINCOLOR_COBALT, 2, V_PERIDOTMAP, true}, // SKINCOLOR_PERIDOT {"Apple", {0x49, 0x49, 0xbc, 0xbd, 0xbe, 0xbe, 0xbe, 0x67, 0x69, 0x6a, 0x6b, 0x6b, 0x6c, 0x6d, 0x6d, 0x6d}, SKINCOLOR_RASPBERRY, 13, V_PERIDOTMAP, true}, // SKINCOLOR_APPLE + {"Chartreuse", { 80, 82, 72, 73, 188, 188, 113, 114, 114, 125, 126, 137, 138, 139, 253, 254}, SKINCOLOR_NOBLE, 12, V_PERIDOTMAP, true}, // SKINCOLOR_CHARTREUSE {"Green", {0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f}, SKINCOLOR_RED, 6, V_GREENMAP, true}, // SKINCOLOR_GREEN {"Forest", {0x65, 0x66, 0x67, 0x68, 0x69, 0x69, 0x6a, 0x6b, 0x6b, 0x6c, 0x6d, 0x6d, 0x6e, 0x6e, 0x6e, 0x6f}, SKINCOLOR_SALMON, 9, V_GREENMAP, true}, // SKINCOLOR_FOREST {"Emerald", {0x70, 0x70, 0x71, 0x71, 0x72, 0x72, 0x73, 0x73, 0x73, 0x74, 0x75, 0x75, 0x76, 0x76, 0x77, 0x77}, SKINCOLOR_RUBY, 4, V_GREENMAP, true}, // SKINCOLOR_EMERALD @@ -21626,32 +21641,48 @@ skincolor_t skincolors[MAXSKINCOLORS] = { {"Headlight", { 0, 80, 81, 82, 73, 84, 64, 65, 91, 91, 124, 125, 126, 137, 138, 139}, SKINCOLOR_MAUVE, 8, V_YELLOWMAP, true}, // SKINCOLOR_HEADLIGHT {"Mint", {0x00, 0x00, 0x58, 0x58, 0x59, 0x62, 0x62, 0x62, 0x64, 0x67, 0x7e, 0x7e, 0x8f, 0x8f, 0x8a, 0x8a}, SKINCOLOR_VIOLET, 5, V_GREENMAP, true}, // SKINCOLOR_MINT {"Master", { 0, 80, 88, 96, 112, 113, 99, 100, 124, 125, 126, 117, 107, 118, 119, 111}, SKINCOLOR_PEPPER, 8, V_GREENMAP, true}, // SKINCOLOR_MASTER + {"Bottle", { 0, 1, 3, 4, 5, 140, 141, 141, 124, 125, 126, 127, 118, 119, 111, 111}, SKINCOLOR_LATTE, 14, V_AQUAMAP, true}, // SKINCOLOR_BOTTLE {"Seafoam", {0x01, 0x58, 0x59, 0x5a, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x8f, 0x8f, 0x8a, 0x8a, 0x8a, 0xfd, 0xfd}, SKINCOLOR_PLUM, 6, V_AQUAMAP, true}, // SKINCOLOR_SEAFOAM + {"Island", { 96, 97, 113, 113, 114, 124, 142, 136, 136, 150, 151, 153, 168, 168, 169, 169}, SKINCOLOR_GALAXY, 7, V_AQUAMAP, true}, // SKINCOLOR_ISLAND {"Aqua", {0x78, 0x79, 0x7a, 0x7a, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7d, 0x7e, 0x7e, 0x7f, 0x7f, 0x76, 0x77}, SKINCOLOR_ROSY, 7, V_AQUAMAP, true}, // SKINCOLOR_AQUA {"Teal", {0x78, 0x78, 0x8c, 0x8c, 0x8d, 0x8d, 0x8d, 0x8e, 0x8e, 0x8f, 0x8f, 0x8f, 0x8a, 0x8a, 0x8a, 0x8a}, SKINCOLOR_PEACHY, 7, V_SKYMAP, true}, // SKINCOLOR_TEAL {"Wave", {0x00, 0x78, 0x78, 0x79, 0x8d, 0x87, 0x88, 0x89, 0x89, 0xae, 0xa8, 0xa8, 0xa9, 0xa9, 0xfd, 0xfd}, SKINCOLOR_QUAIL, 5, V_SKYMAP, true}, // SKINCOLOR_WAVE {"Cyan", {0x80, 0x81, 0xff, 0xff, 0x83, 0x83, 0x8d, 0x8d, 0x8d, 0x8e, 0x7e, 0x7f, 0x76, 0x76, 0x77, 0x6e}, SKINCOLOR_APRICOT, 6, V_SKYMAP, true}, // SKINCOLOR_CYAN + {"Turquoise", { 0, 120, 121, 122, 123, 141, 141, 135, 136, 136, 150, 153, 155, 157, 159, 253}, SKINCOLOR_SANGRIA, 7, V_SKYMAP, true}, // SKINCOLOR_TURQUOISE {"Sky", {0x80, 0x80, 0x81, 0x82, 0x83, 0x83, 0x84, 0x85, 0x85, 0x86, 0x87, 0x88, 0x89, 0x89, 0x8a, 0x8b}, SKINCOLOR_SANDY, 1, V_SKYMAP, true}, // SKINCOLOR_SKY + {"Marine", { 144, 146, 147, 147, 148, 135, 136, 136, 137, 137, 127, 118, 119, 111, 111, 111}, SKINCOLOR_KIWI, 10, V_SKYMAP, true}, // SKINCOLOR_MARINE {"Cerulean", {0x85, 0x86, 0x87, 0x88, 0x88, 0x89, 0x89, 0x89, 0x8a, 0x8a, 0xfd, 0xfd, 0xfd, 0x1f, 0x1f, 0x1f}, SKINCOLOR_NEON, 4, V_SKYMAP, true}, // SKINCOLOR_CERULEAN + {"Dream", { 80, 208, 200, 200, 146, 146, 133, 134, 135, 136, 137, 138, 139, 139, 254, 254}, SKINCOLOR_FOUNDATION, 9, V_SKYMAP, true}, // SKINCOLOR_DREAM {"Icy", {0x00, 0x00, 0x00, 0x00, 0x80, 0x81, 0x83, 0x83, 0x86, 0x87, 0x95, 0x95, 0xad, 0xad, 0xae, 0xaf}, SKINCOLOR_CRIMSON, 0, V_SKYMAP, true}, // SKINCOLOR_ICY + {"Daybreak", { 80, 81, 82, 72, 64, 9, 11, 171, 149, 150, 151, 153, 156, 157, 159, 253}, SKINCOLOR_EVENTIDE, 12, V_BLUEMAP, true}, // SKINCOLOR_DAYBREAK {"Sapphire", {0x80, 0x83, 0x86, 0x87, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xfd, 0xfe}, SKINCOLOR_SUNSET, 5, V_SKYMAP, true}, // SKINCOLOR_SAPPHIRE + {"Arctic", { 0, 1, 3, 4, 146, 146, 147, 148, 148, 149, 150, 153, 156, 159, 253, 254}, SKINCOLOR_PUMPKIN, 10, V_BLUEMAP, true}, // SKINCOLOR_ARCTIC {"Cornflower", {0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x9a, 0x9c, 0x9d, 0x9d, 0x9e, 0x9e, 0x9e}, SKINCOLOR_YELLOW, 4, V_BLUEMAP, true}, // SKINCOLOR_CORNFLOWER {"Blue", {0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xfd, 0xfe}, SKINCOLOR_ORANGE, 5, V_BLUEMAP, true}, // SKINCOLOR_BLUE {"Cobalt", { 145, 147, 149, 150, 151, 153, 154, 155, 156, 157, 158, 159, 253, 253, 254, 254}, SKINCOLOR_PERIDOT, 5, V_BLUEMAP, true}, // SKINCOLOR_COBALT + {"Midnight", { 171, 171, 172, 173, 173, 174, 155, 156, 157, 159, 253, 253, 254, 254, 31, 31}, SKINCOLOR_CHERRY, 10, V_GRAYMAP, true}, // SKINCOLOR_MIDNIGHT + {"Galaxy", { 160, 161, 162, 163, 164, 165, 166, 167, 154, 155, 156, 157, 159, 253, 254, 31}, SKINCOLOR_ISLAND, 7, V_PURPLEMAP, true}, // SKINCOLOR_GALAXY {"Vapor", {0x80, 0x81, 0x83, 0x86, 0x94, 0x94, 0xa3, 0xa3, 0xa4, 0xa6, 0xa6, 0xa6, 0xa8, 0xa8, 0xa9, 0xa9}, SKINCOLOR_LILAC, 4, V_SKYMAP, true}, // SKINCOLOR_VAPOR {"Dusk", {0x92, 0x93, 0x94, 0x94, 0xac, 0xad, 0xad, 0xad, 0xae, 0xae, 0xaf, 0xaf, 0xa9, 0xa9, 0xfd, 0xfd}, SKINCOLOR_OLIVE, 0, V_BLUEMAP, true}, // SKINCOLOR_DUSK + {"Majesty", { 0, 1, 176, 160, 160, 161, 162, 162, 163, 172, 173, 174, 174, 175, 139, 139}, SKINCOLOR_MINDARO, 11, V_PURPLEMAP, true}, // SKINCOLOR_MAJESTY {"Pastel", {0x90, 0x90, 0xa0, 0xa0, 0xa1, 0xa1, 0xa2, 0xa2, 0xa2, 0xa3, 0xa4, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8}, SKINCOLOR_BUBBLEGUM, 9, V_PURPLEMAP, true}, // SKINCOLOR_PASTEL {"Purple", {0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa4, 0xa5, 0xa5, 0xa5, 0xa6, 0xa7, 0xa7, 0xa8, 0xa8, 0xa9, 0xa9}, SKINCOLOR_FLAME, 7, V_PURPLEMAP, true}, // SKINCOLOR_PURPLE - {"Bubblegum", {0x00, 0xd0, 0xd0, 0xc8, 0xc8, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8}, SKINCOLOR_PASTEL, 8, V_MAGENTAMAP, true}, // SKINCOLOR_BUBBLEGUM + {"Noble", { 144, 146, 147, 148, 148, 164, 164, 165, 165, 185, 186, 186, 187, 187, 28, 29}, SKINCOLOR_CHARTREUSE, 12, V_PURPLEMAP, true}, // SKINCOLOR_NOBLE + {"Fuchsia", { 200, 201, 203, 204, 204, 183, 184, 184, 165, 166, 167, 168, 169, 159, 253, 254}, SKINCOLOR_LEMON, 6, V_PURPLEMAP, true}, // SKINCOLOR_FUCHSIA + {"Bubblegum", { 0, 208, 208, 176, 177, 178, 179, 180, 181, 183, 165, 166, 167, 168, 169, 253}, SKINCOLOR_PASTEL, 8, V_MAGENTAMAP, true}, // SKINCOLOR_BUBBLEGUM {"Magenta", {0xb3, 0xb3, 0xb4, 0xb5, 0xb6, 0xb6, 0xb7, 0xb7, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xbb}, SKINCOLOR_LIME, 6, V_MAGENTAMAP, true}, // SKINCOLOR_MAGENTA {"Neon", {0xb3, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xbb, 0xc7, 0xc7, 0x1d, 0x1d, 0x1e}, SKINCOLOR_CERULEAN, 2, V_MAGENTAMAP, true}, // SKINCOLOR_NEON {"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 + {"Royal", { 208, 209, 192, 192, 192, 193, 193, 194, 194, 172, 173, 174, 175, 175, 139, 139}, SKINCOLOR_FANCY, 9, V_PURPLEMAP, true}, // SKINCOLOR_ROYAL {"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 {"Mauve", { 176, 177, 178, 192, 193, 194, 195, 195, 196, 185, 185, 186, 186, 187, 187, 253}, SKINCOLOR_HEADLIGHT, 8, V_PURPLEMAP, true}, // SKINCOLOR_MAUVE + {"Eventide", { 51, 52, 53, 33, 34, 204, 183, 183, 184, 184, 166, 167, 168, 169, 253, 254}, SKINCOLOR_DAYBREAK, 12, V_REDMAP, true}, // SKINCOLOR_EVENTIDE {"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 {"Taffy", { 1, 176, 176, 177, 178, 179, 202, 203, 204, 204, 206, 207, 44, 44, 46, 47}, SKINCOLOR_JADE, 8, V_ROSYMAP, true}, // SKINCOLOR_TAFFY {"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 + {"Fancy", { 0, 208, 49, 210, 210, 202, 202, 203, 204, 204, 205, 206, 207, 207, 186, 186}, SKINCOLOR_ROYAL, 9, V_ROSYMAP, true}, // SKINCOLOR_FANCY + {"Sangria", { 210, 32, 33, 34, 35, 215, 215, 207, 207, 185, 186, 186, 186, 169, 169, 253}, SKINCOLOR_TURQUOISE, 7, V_ROSYMAP, true}, // SKINCOLOR_SANGRIA // super {"Super Silver 1", {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x03}, SKINCOLOR_BLACK, 15, 0, false}, // SKINCOLOR_SUPERSILVER1 From edbfb92b1128d628177a80c201ecde5a09df267f Mon Sep 17 00:00:00 2001 From: spherallic Date: Thu, 27 Oct 2022 00:37:15 +0200 Subject: [PATCH 209/586] Correct tabs & spacing --- src/deh_tables.c | 24 ++++++++++++------------ src/doomdef.h | 8 ++++---- src/info.c | 38 +++++++++++++++++++------------------- 3 files changed, 35 insertions(+), 35 deletions(-) diff --git a/src/deh_tables.c b/src/deh_tables.c index 7ee78218b..d349e35d0 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -4612,20 +4612,20 @@ const char *COLOR_ENUMS[] = { "MERCURY", // SKINCOLOR_MERCURY, "BLUEBELL", // SKINCOLOR_BLUEBELL, "PINK", // SKINCOLOR_PINK, - "ROSEWOOD", // SKINCOLOR_ROSEWOOD, + "ROSEWOOD", // SKINCOLOR_ROSEWOOD, "YOGURT", // SKINCOLOR_YOGURT, "LATTE", // SKINCOLOR_LATTE, "BROWN", // SKINCOLOR_BROWN, "BRONZE", // SKINCOLOR_BRONZE, "SEPIA", // SKINCOLOR_SEPIA, "ECRU", // SKINCOLOR_ECRU, - "TAN", // SKINCOLOR_TAN, + "TAN", // SKINCOLOR_TAN, "BEIGE", // SKINCOLOR_BEIGE, - "ROSEBUSH", // SKINCOLOR_ROSEBUSH, + "ROSEBUSH", // SKINCOLOR_ROSEBUSH, "MOSS", // SKINCOLOR_MOSS, "AZURE", // SKINCOLOR_AZURE, - "EGGPLANT", // SKINCOLOR_EGGPLANT, - "LAVENDER", // SKINCOLOR_LAVENDER, + "EGGPLANT", // SKINCOLOR_EGGPLANT, + "LAVENDER", // SKINCOLOR_LAVENDER, // Viv's vivid colours (toast 21/07/17) // Tweaks & additions (Lach, sphere, Alice, MotorRoach 26/10/22) @@ -4639,7 +4639,7 @@ const char *COLOR_ENUMS[] = { "KETCHUP", // SKINCOLOR_KETCHUP, "PEACHY", // SKINCOLOR_PEACHY, "QUAIL", // SKINCOLOR_QUAIL, - "FOUNDATION", // SKINCOLOR_FOUNDATION, + "FOUNDATION", // SKINCOLOR_FOUNDATION, "SUNSET", // SKINCOLOR_SUNSET, "COPPER", // SKINCOLOR_COPPER, "APRICOT", // SKINCOLOR_APRICOT, @@ -4656,7 +4656,7 @@ const char *COLOR_ENUMS[] = { "MINDARO", // SKINCOLOR_MINDARO, "PERIDOT", // SKINCOLOR_PERIDOT, "APPLE", // SKINCOLOR_APPLE, - "CHARTREUSE", // SKINCOLOR_CHARTREUSE, + "CHARTREUSE", // SKINCOLOR_CHARTREUSE, "GREEN", // SKINCOLOR_GREEN, "FOREST", // SKINCOLOR_FOREST, "EMERALD", // SKINCOLOR_EMERALD, @@ -4673,17 +4673,17 @@ const char *COLOR_ENUMS[] = { "CYAN", // SKINCOLOR_CYAN, "TURQUOISE", // SKINCOLOR_TURQUOISE, "SKY", // SKINCOLOR_SKY, - "MARINE", // SKINCOLOR_MARINE, + "MARINE", // SKINCOLOR_MARINE, "CERULEAN", // SKINCOLOR_CERULEAN, - "DREAM", // SKINCOLOR_DREAM, + "DREAM", // SKINCOLOR_DREAM, "ICY", // SKINCOLOR_ICY, - "DAYBREAK", // SKINCOLOR_DAYBREAK, + "DAYBREAK", // SKINCOLOR_DAYBREAK, "SAPPHIRE", // SKINCOLOR_SAPPHIRE, - "ARCTIC", // SKINCOLOR_ARCTIC, + "ARCTIC", // SKINCOLOR_ARCTIC, "CORNFLOWER", // SKINCOLOR_CORNFLOWER, "BLUE", // SKINCOLOR_BLUE, "COBALT", // SKINCOLOR_COBALT, - "MIDNIGHT", // SKINCOLOR_MIDNIGHT, + "MIDNIGHT", // SKINCOLOR_MIDNIGHT, "GALAXY", // SKINCOLOR_GALAXY, "VAPOR", // SKINCOLOR_VAPOR, "DUSK", // SKINCOLOR_DUSK, diff --git a/src/doomdef.h b/src/doomdef.h index f21000cda..171c4b69c 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -264,16 +264,16 @@ typedef enum SKINCOLOR_MERCURY, SKINCOLOR_BLUEBELL, SKINCOLOR_PINK, - SKINCOLOR_ROSEWOOD, + SKINCOLOR_ROSEWOOD, SKINCOLOR_YOGURT, - SKINCOLOR_LATTE, + SKINCOLOR_LATTE, SKINCOLOR_BROWN, SKINCOLOR_BRONZE, - SKINCOLOR_SEPIA, + SKINCOLOR_SEPIA, SKINCOLOR_ECRU, SKINCOLOR_TAN, SKINCOLOR_BEIGE, - SKINCOLOR_ROSEBUSH, + SKINCOLOR_ROSEBUSH, SKINCOLOR_MOSS, SKINCOLOR_AZURE, SKINCOLOR_EGGPLANT, diff --git a/src/info.c b/src/info.c index 10b05dee4..ab5a0e254 100644 --- a/src/info.c +++ b/src/info.c @@ -21584,25 +21584,25 @@ skincolor_t skincolors[MAXSKINCOLORS] = { {"Black", {0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1b, 0x1b, 0x1c, 0x1d, 0x1d, 0x1e, 0x1e, 0x1f, 0x1f}, SKINCOLOR_WHITE, 7, V_GRAYMAP, true}, // SKINCOLOR_BLACK // Desaturated - {"Aether", {0x00, 0x00, 0x01, 0x02, 0x02, 0x03, 0x91, 0x91, 0x91, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xaf}, SKINCOLOR_GREY, 15, 0, true}, // SKINCOLOR_AETHER - {"Slate", {0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0xaa, 0xaa, 0xaa, 0xab, 0xac, 0xac, 0xad, 0xad, 0xae, 0xaf}, SKINCOLOR_SILVER, 12, 0, true}, // SKINCOLOR_SLATE - {"Mercury", { 0, 3, 4, 7, 11, 12, 14, 15, 171, 172, 173, 155, 157, 159, 253, 254}, SKINCOLOR_ECRU, 15, V_AZUREMAP, true}, // SKINCOLOR_MERCURY - {"Bluebell", {0x90, 0x91, 0x92, 0x93, 0x94, 0x94, 0x95, 0xac, 0xac, 0xad, 0xad, 0xa8, 0xa8, 0xa9, 0xfd, 0xfe}, SKINCOLOR_COPPER, 4, V_BLUEMAP, true}, // SKINCOLOR_BLUEBELL - {"Pink", {0xd0, 0xd0, 0xd1, 0xd1, 0xd2, 0xd2, 0xd3, 0xd3, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0x2b, 0x2c, 0x2e}, SKINCOLOR_AZURE, 9, V_REDMAP, true}, // SKINCOLOR_PINK - {"Rosewood", { 209, 210, 211, 212, 213, 214, 228, 230, 232, 234, 235, 237, 26, 27, 28, 29}, SKINCOLOR_SEPIA, 5, V_BROWNMAP, true}, // SKINCOLOR_ROSEWOOD - {"Yogurt", {0xd0, 0x30, 0xd8, 0xd9, 0xda, 0xdb, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe3, 0xe6, 0xe8, 0xe9}, SKINCOLOR_RUST, 7, V_BROWNMAP, true}, // SKINCOLOR_YOGURT - {"Latte", { 48, 217, 219, 221, 223, 224, 226, 228, 68, 69, 70, 70, 44, 45, 46, 47}, SKINCOLOR_BOTTLE, 14, V_BROWNMAP, true}, // SKINCOLOR_LATTE - {"Brown", {0xdf, 0xe0, 0xe1, 0xe2, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef}, SKINCOLOR_TAN, 2, V_BROWNMAP, true}, // SKINCOLOR_BROWN - {"Bronze", {0xde, 0xe0, 0xe1, 0xe4, 0xe7, 0xe9, 0xeb, 0xec, 0xed, 0xed, 0xed, 0x19, 0x19, 0x1b, 0x1d, 0x1e}, SKINCOLOR_KETCHUP, 0, V_BROWNMAP, true}, // SKINCOLOR_BRONZE - {"Sepia", { 88, 84, 85, 86, 224, 226, 228, 230, 232, 235, 236, 237, 238, 239, 28, 28}, SKINCOLOR_ROSEWOOD,5, V_BROWNMAP, true}, // SKINCOLOR_SEPIA - {"Ecru", { 80, 83, 84, 85, 86, 242, 243, 245, 230, 232, 234, 236, 238, 239, 47, 47}, SKINCOLOR_MERCURY, 15, V_BROWNMAP, true}, // SKINCOLOR_ECRU - {"Tan", {0x51, 0x51, 0x54, 0x54, 0x55, 0x55, 0x56, 0x56, 0x56, 0x57, 0xf5, 0xf5, 0xf9, 0xf9, 0xed, 0xed}, SKINCOLOR_BROWN, 12, V_BROWNMAP, true}, // SKINCOLOR_TAN - {"Beige", {0x54, 0x55, 0x56, 0x56, 0xf2, 0xf3, 0xf3, 0xf4, 0xf5, 0xf6, 0xf8, 0xf9, 0xfa, 0xfb, 0xed, 0xed}, SKINCOLOR_MOSS, 5, V_BROWNMAP, true}, // SKINCOLOR_BEIGE - {"Rosebush", { 208, 216, 209, 85, 90, 91, 91, 92, 191, 93, 94, 107, 109, 110, 111, 111}, SKINCOLOR_EGGPLANT,5, V_GREENMAP, true}, // SKINCOLOR_ROSEBUSH - {"Moss", {0x58, 0x58, 0x59, 0x59, 0x5a, 0x5a, 0x5b, 0x5b, 0x5b, 0x5c, 0x5d, 0x5d, 0x5e, 0x5e, 0x5f, 0x5f}, SKINCOLOR_BEIGE, 13, V_GREENMAP, true}, // SKINCOLOR_MOSS - {"Azure", {0x90, 0x90, 0x91, 0x91, 0xaa, 0xaa, 0xab, 0xab, 0xab, 0xac, 0xad, 0xad, 0xae, 0xae, 0xaf, 0xaf}, SKINCOLOR_PINK, 5, V_AZUREMAP, true}, // SKINCOLOR_AZURE - {"Eggplant", { 4, 8, 11, 11, 16, 195, 195, 195, 196, 186, 187, 187, 254, 254, 30, 31}, SKINCOLOR_ROSEBUSH,5, V_PURPLEMAP, true}, // SKINCOLOR_EGGPLANT - {"Lavender", {0xc0, 0xc0, 0xc1, 0xc1, 0xc2, 0xc2, 0xc3, 0xc3, 0xc3, 0xc4, 0xc5, 0xc5, 0xc6, 0xc6, 0xc7, 0xc7}, SKINCOLOR_GOLD, 4, V_PURPLEMAP, true}, // SKINCOLOR_LAVENDER + {"Aether", {0x00, 0x00, 0x01, 0x02, 0x02, 0x03, 0x91, 0x91, 0x91, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xaf}, SKINCOLOR_GREY, 15, 0, true}, // SKINCOLOR_AETHER + {"Slate", {0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0xaa, 0xaa, 0xaa, 0xab, 0xac, 0xac, 0xad, 0xad, 0xae, 0xaf}, SKINCOLOR_SILVER, 12, 0, true}, // SKINCOLOR_SLATE + {"Mercury", { 0, 3, 4, 7, 11, 12, 14, 15, 171, 172, 173, 155, 157, 159, 253, 254}, SKINCOLOR_ECRU, 15, V_AZUREMAP, true}, // SKINCOLOR_MERCURY + {"Bluebell", {0x90, 0x91, 0x92, 0x93, 0x94, 0x94, 0x95, 0xac, 0xac, 0xad, 0xad, 0xa8, 0xa8, 0xa9, 0xfd, 0xfe}, SKINCOLOR_COPPER, 4, V_BLUEMAP, true}, // SKINCOLOR_BLUEBELL + {"Pink", {0xd0, 0xd0, 0xd1, 0xd1, 0xd2, 0xd2, 0xd3, 0xd3, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0x2b, 0x2c, 0x2e}, SKINCOLOR_AZURE, 9, V_REDMAP, true}, // SKINCOLOR_PINK + {"Rosewood", { 209, 210, 211, 212, 213, 214, 228, 230, 232, 234, 235, 237, 26, 27, 28, 29}, SKINCOLOR_SEPIA, 5, V_BROWNMAP, true}, // SKINCOLOR_ROSEWOOD + {"Yogurt", {0xd0, 0x30, 0xd8, 0xd9, 0xda, 0xdb, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe3, 0xe6, 0xe8, 0xe9}, SKINCOLOR_RUST, 7, V_BROWNMAP, true}, // SKINCOLOR_YOGURT + {"Latte", { 48, 217, 219, 221, 223, 224, 226, 228, 68, 69, 70, 70, 44, 45, 46, 47}, SKINCOLOR_BOTTLE, 14, V_BROWNMAP, true}, // SKINCOLOR_LATTE + {"Brown", {0xdf, 0xe0, 0xe1, 0xe2, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef}, SKINCOLOR_TAN, 2, V_BROWNMAP, true}, // SKINCOLOR_BROWN + {"Bronze", {0xde, 0xe0, 0xe1, 0xe4, 0xe7, 0xe9, 0xeb, 0xec, 0xed, 0xed, 0xed, 0x19, 0x19, 0x1b, 0x1d, 0x1e}, SKINCOLOR_KETCHUP, 0, V_BROWNMAP, true}, // SKINCOLOR_BRONZE + {"Sepia", { 88, 84, 85, 86, 224, 226, 228, 230, 232, 235, 236, 237, 238, 239, 28, 28}, SKINCOLOR_ROSEWOOD, 5, V_BROWNMAP, true}, // SKINCOLOR_SEPIA + {"Ecru", { 80, 83, 84, 85, 86, 242, 243, 245, 230, 232, 234, 236, 238, 239, 47, 47}, SKINCOLOR_MERCURY, 15, V_BROWNMAP, true}, // SKINCOLOR_ECRU + {"Tan", {0x51, 0x51, 0x54, 0x54, 0x55, 0x55, 0x56, 0x56, 0x56, 0x57, 0xf5, 0xf5, 0xf9, 0xf9, 0xed, 0xed}, SKINCOLOR_BROWN, 12, V_BROWNMAP, true}, // SKINCOLOR_TAN + {"Beige", {0x54, 0x55, 0x56, 0x56, 0xf2, 0xf3, 0xf3, 0xf4, 0xf5, 0xf6, 0xf8, 0xf9, 0xfa, 0xfb, 0xed, 0xed}, SKINCOLOR_MOSS, 5, V_BROWNMAP, true}, // SKINCOLOR_BEIGE + {"Rosebush", { 208, 216, 209, 85, 90, 91, 91, 92, 191, 93, 94, 107, 109, 110, 111, 111}, SKINCOLOR_EGGPLANT, 5, V_GREENMAP, true}, // SKINCOLOR_ROSEBUSH + {"Moss", {0x58, 0x58, 0x59, 0x59, 0x5a, 0x5a, 0x5b, 0x5b, 0x5b, 0x5c, 0x5d, 0x5d, 0x5e, 0x5e, 0x5f, 0x5f}, SKINCOLOR_BEIGE, 13, V_GREENMAP, true}, // SKINCOLOR_MOSS + {"Azure", {0x90, 0x90, 0x91, 0x91, 0xaa, 0xaa, 0xab, 0xab, 0xab, 0xac, 0xad, 0xad, 0xae, 0xae, 0xaf, 0xaf}, SKINCOLOR_PINK, 5, V_AZUREMAP, true}, // SKINCOLOR_AZURE + {"Eggplant", { 4, 8, 11, 11, 16, 195, 195, 195, 196, 186, 187, 187, 254, 254, 30, 31}, SKINCOLOR_ROSEBUSH, 5, V_PURPLEMAP, true}, // SKINCOLOR_EGGPLANT + {"Lavender", {0xc0, 0xc0, 0xc1, 0xc1, 0xc2, 0xc2, 0xc3, 0xc3, 0xc3, 0xc4, 0xc5, 0xc5, 0xc6, 0xc6, 0xc7, 0xc7}, SKINCOLOR_GOLD, 4, V_PURPLEMAP, true}, // SKINCOLOR_LAVENDER // Viv's vivid colours (toast 21/07/17) // Tweaks & additions (Lach, sphere, Alice, MotorRoach 26/10/22) From 647e6aac12d215e2263543172dbae3619f1fb9ef Mon Sep 17 00:00:00 2001 From: Lach <54614944+lachablock@users.noreply.github.com> Date: Thu, 27 Oct 2022 20:06:26 +1100 Subject: [PATCH 210/586] Simplify the way skincolors' invshades are used --- src/m_menu.c | 2 +- src/p_enemy.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index f9f52335d..c09e12998 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -8520,7 +8520,7 @@ static void M_DrawLoadGameData(void) if (charskin->prefoppositecolor) { col = charskin->prefoppositecolor; - col = skincolors[col].ramp[skincolors[skincolors[col].invcolor].invshade]; + col = skincolors[col].ramp[skincolors[charskin->prefcolor].invshade]; } else { diff --git a/src/p_enemy.c b/src/p_enemy.c index c7d87b88a..fe062cffc 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -5321,7 +5321,7 @@ void A_SignPlayer(mobj_t *actor) actor->tracer->color = signcolor; if (signcolor && signcolor < numskincolors) - signframe += (15 - skincolors[skincolors[signcolor].invcolor].invshade); + signframe += (15 - skincolors[facecolor].invshade); actor->tracer->frame = signframe; } From 458b47464577cd23b5d1f5c3a9f88599598b1531 Mon Sep 17 00:00:00 2001 From: spherallic Date: Thu, 27 Oct 2022 11:22:33 +0200 Subject: [PATCH 211/586] Even more skincolor changes: - Changed Bronze - Added Boulder & Volcanic - Tweaked Galaxy --- src/deh_tables.c | 2 ++ src/doomdef.h | 2 ++ src/info.c | 8 +++++--- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/deh_tables.c b/src/deh_tables.c index d349e35d0..ec60d7311 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -4616,6 +4616,7 @@ const char *COLOR_ENUMS[] = { "YOGURT", // SKINCOLOR_YOGURT, "LATTE", // SKINCOLOR_LATTE, "BROWN", // SKINCOLOR_BROWN, + "BOULDER", // SKINCOLOR_BOULDER "BRONZE", // SKINCOLOR_BRONZE, "SEPIA", // SKINCOLOR_SEPIA, "ECRU", // SKINCOLOR_ECRU, @@ -4706,6 +4707,7 @@ const char *COLOR_ENUMS[] = { "ROSY", // SKINCOLOR_ROSY, "FANCY", // SKINCOLOR_FANCY, "SANGRIA", // SKINCOLOR_SANGRIA, + "VOLCANIC", // SKINCOLOR_VOLCANIC, // Super special awesome Super flashing colors! "SUPERSILVER1", // SKINCOLOR_SUPERSILVER1 diff --git a/src/doomdef.h b/src/doomdef.h index 171c4b69c..aa200274a 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -268,6 +268,7 @@ typedef enum SKINCOLOR_YOGURT, SKINCOLOR_LATTE, SKINCOLOR_BROWN, + SKINCOLOR_BOULDER, SKINCOLOR_BRONZE, SKINCOLOR_SEPIA, SKINCOLOR_ECRU, @@ -358,6 +359,7 @@ typedef enum SKINCOLOR_ROSY, SKINCOLOR_FANCY, SKINCOLOR_SANGRIA, + SKINCOLOR_VOLCANIC, FIRSTSUPERCOLOR, diff --git a/src/info.c b/src/info.c index ab5a0e254..ec5a6c72d 100644 --- a/src/info.c +++ b/src/info.c @@ -21593,7 +21593,8 @@ skincolor_t skincolors[MAXSKINCOLORS] = { {"Yogurt", {0xd0, 0x30, 0xd8, 0xd9, 0xda, 0xdb, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe3, 0xe6, 0xe8, 0xe9}, SKINCOLOR_RUST, 7, V_BROWNMAP, true}, // SKINCOLOR_YOGURT {"Latte", { 48, 217, 219, 221, 223, 224, 226, 228, 68, 69, 70, 70, 44, 45, 46, 47}, SKINCOLOR_BOTTLE, 14, V_BROWNMAP, true}, // SKINCOLOR_LATTE {"Brown", {0xdf, 0xe0, 0xe1, 0xe2, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef}, SKINCOLOR_TAN, 2, V_BROWNMAP, true}, // SKINCOLOR_BROWN - {"Bronze", {0xde, 0xe0, 0xe1, 0xe4, 0xe7, 0xe9, 0xeb, 0xec, 0xed, 0xed, 0xed, 0x19, 0x19, 0x1b, 0x1d, 0x1e}, SKINCOLOR_KETCHUP, 0, V_BROWNMAP, true}, // SKINCOLOR_BRONZE + {"Boulder", {0xde, 0xe0, 0xe1, 0xe4, 0xe7, 0xe9, 0xeb, 0xec, 0xed, 0xed, 0xed, 0x19, 0x19, 0x1b, 0x1d, 0x1e}, SKINCOLOR_KETCHUP, 0, V_BROWNMAP, true}, // SKINCOLOR_BOULDER + {"Bronze", { 82, 84, 50, 51, 223, 228, 230, 232, 234, 236, 237, 238, 239, 239, 30, 31}, SKINCOLOR_VOLCANIC, 9, V_BROWNMAP, true}, // SKINCOLOR_BRONZE {"Sepia", { 88, 84, 85, 86, 224, 226, 228, 230, 232, 235, 236, 237, 238, 239, 28, 28}, SKINCOLOR_ROSEWOOD, 5, V_BROWNMAP, true}, // SKINCOLOR_SEPIA {"Ecru", { 80, 83, 84, 85, 86, 242, 243, 245, 230, 232, 234, 236, 238, 239, 47, 47}, SKINCOLOR_MERCURY, 15, V_BROWNMAP, true}, // SKINCOLOR_ECRU {"Tan", {0x51, 0x51, 0x54, 0x54, 0x55, 0x55, 0x56, 0x56, 0x56, 0x57, 0xf5, 0xf5, 0xf9, 0xf9, 0xed, 0xed}, SKINCOLOR_BROWN, 12, V_BROWNMAP, true}, // SKINCOLOR_TAN @@ -21613,7 +21614,7 @@ skincolor_t skincolors[MAXSKINCOLORS] = { {"Red", {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x47, 0x2e, 0x2f}, SKINCOLOR_GREEN, 10, V_REDMAP, true}, // SKINCOLOR_RED {"Crimson", {0x27, 0x27, 0x28, 0x28, 0x29, 0x2a, 0x2b, 0x2b, 0x2c, 0x2d, 0x2e, 0x2e, 0x2e, 0x2f, 0x2f, 0x1f}, SKINCOLOR_ICY, 10, V_REDMAP, true}, // SKINCOLOR_CRIMSON {"Flame", {0x31, 0x32, 0x33, 0x36, 0x22, 0x22, 0x25, 0x25, 0x25, 0xcd, 0xcf, 0xcf, 0xc5, 0xc5, 0xc7, 0xc7}, SKINCOLOR_PURPLE, 8, V_REDMAP, true}, // SKINCOLOR_FLAME - {"Ketchup", {0x48, 0x49, 0x40, 0x33, 0x34, 0x36, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2b, 0x2c, 0x47, 0x2e, 0x2f}, SKINCOLOR_BRONZE, 8, V_REDMAP, true}, // SKINCOLOR_KETCHUP + {"Ketchup", {0x48, 0x49, 0x40, 0x33, 0x34, 0x36, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2b, 0x2c, 0x47, 0x2e, 0x2f}, SKINCOLOR_BOULDER, 8, V_REDMAP, true}, // SKINCOLOR_KETCHUP {"Peachy", {0xd0, 0x30, 0x31, 0x31, 0x32, 0x32, 0xdc, 0xdc, 0xdc, 0xd3, 0xd4, 0xd4, 0xcc, 0xcd, 0xce, 0xcf}, SKINCOLOR_TEAL, 7, V_ROSYMAP, true}, // SKINCOLOR_PEACHY {"Quail", {0xd8, 0xd9, 0xdb, 0xdc, 0xde, 0xdf, 0xd5, 0xd5, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0x1d, 0x1f}, SKINCOLOR_WAVE, 5, V_BROWNMAP, true}, // SKINCOLOR_QUAIL {"Foundation", { 80, 81, 82, 84, 219, 221, 221, 212, 213, 214, 215, 195, 196, 186, 187, 30}, SKINCOLOR_DREAM, 9, V_ORANGEMAP, true}, // SKINCOLOR_FOUNDATION @@ -21661,7 +21662,7 @@ skincolor_t skincolors[MAXSKINCOLORS] = { {"Blue", {0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xfd, 0xfe}, SKINCOLOR_ORANGE, 5, V_BLUEMAP, true}, // SKINCOLOR_BLUE {"Cobalt", { 145, 147, 149, 150, 151, 153, 154, 155, 156, 157, 158, 159, 253, 253, 254, 254}, SKINCOLOR_PERIDOT, 5, V_BLUEMAP, true}, // SKINCOLOR_COBALT {"Midnight", { 171, 171, 172, 173, 173, 174, 155, 156, 157, 159, 253, 253, 254, 254, 31, 31}, SKINCOLOR_CHERRY, 10, V_GRAYMAP, true}, // SKINCOLOR_MIDNIGHT - {"Galaxy", { 160, 161, 162, 163, 164, 165, 166, 167, 154, 155, 156, 157, 159, 253, 254, 31}, SKINCOLOR_ISLAND, 7, V_PURPLEMAP, true}, // SKINCOLOR_GALAXY + {"Galaxy", { 160, 161, 162, 163, 164, 165, 166, 166, 154, 155, 156, 157, 159, 253, 254, 31}, SKINCOLOR_ISLAND, 7, V_PURPLEMAP, true}, // SKINCOLOR_GALAXY {"Vapor", {0x80, 0x81, 0x83, 0x86, 0x94, 0x94, 0xa3, 0xa3, 0xa4, 0xa6, 0xa6, 0xa6, 0xa8, 0xa8, 0xa9, 0xa9}, SKINCOLOR_LILAC, 4, V_SKYMAP, true}, // SKINCOLOR_VAPOR {"Dusk", {0x92, 0x93, 0x94, 0x94, 0xac, 0xad, 0xad, 0xad, 0xae, 0xae, 0xaf, 0xaf, 0xa9, 0xa9, 0xfd, 0xfd}, SKINCOLOR_OLIVE, 0, V_BLUEMAP, true}, // SKINCOLOR_DUSK {"Majesty", { 0, 1, 176, 160, 160, 161, 162, 162, 163, 172, 173, 174, 174, 175, 139, 139}, SKINCOLOR_MINDARO, 11, V_PURPLEMAP, true}, // SKINCOLOR_MAJESTY @@ -21683,6 +21684,7 @@ skincolor_t skincolors[MAXSKINCOLORS] = { {"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 {"Fancy", { 0, 208, 49, 210, 210, 202, 202, 203, 204, 204, 205, 206, 207, 207, 186, 186}, SKINCOLOR_ROYAL, 9, V_ROSYMAP, true}, // SKINCOLOR_FANCY {"Sangria", { 210, 32, 33, 34, 35, 215, 215, 207, 207, 185, 186, 186, 186, 169, 169, 253}, SKINCOLOR_TURQUOISE, 7, V_ROSYMAP, true}, // SKINCOLOR_SANGRIA + {"Volcanic", { 35, 38, 41, 42, 44, 46, 46, 169, 169, 159, 253, 254, 30, 30, 31, 31}, SKINCOLOR_BRONZE, 9, V_REDMAP, true}, // SKINCOLOR_VOLCANIC // super {"Super Silver 1", {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x03}, SKINCOLOR_BLACK, 15, 0, false}, // SKINCOLOR_SUPERSILVER1 From 4cd85b522838403cf98e91ef1de988dcdf471144 Mon Sep 17 00:00:00 2001 From: spherallic Date: Thu, 27 Oct 2022 13:22:43 +0200 Subject: [PATCH 212/586] Support PgUp/PgDn for color select, similar to sound test & addons menu --- src/m_menu.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/m_menu.c b/src/m_menu.c index c09e12998..d07bf62e1 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -12268,6 +12268,23 @@ static void M_HandleSetupMultiPlayer(INT32 choice) } break; + case KEY_PGUP: + case KEY_PGDN: + { + UINT8 i; + if (itemOn == 2) // player color + { + S_StartSound(NULL,sfx_menu1); + for (i = 0; i < 13; i++) // or (282-charw)/(2*indexwidth) + { + setupm_fakecolor = (choice == KEY_PGUP) ? setupm_fakecolor->prev : setupm_fakecolor->next; + while (!skincolors[setupm_fakecolor->color].accessible) // skip inaccessible colors + setupm_fakecolor = (choice == KEY_PGUP) ? setupm_fakecolor->prev : setupm_fakecolor->next; + } + } + } + break; + case KEY_ESCAPE: exitmenu = true; break; From 766c346df59f6cc8383e159458db463a9bf42895 Mon Sep 17 00:00:00 2001 From: spherallic Date: Sat, 29 Oct 2022 00:07:40 +0200 Subject: [PATCH 213/586] Add grid view for skincolors --- src/m_menu.c | 215 ++++++++++++++++++++++++++++++++++++++++----------- src/m_menu.h | 2 + 2 files changed, 173 insertions(+), 44 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index d07bf62e1..63b345692 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -389,6 +389,7 @@ static void M_DrawRoomMenu(void); #endif static void M_DrawJoystick(void); static void M_DrawSetupMultiPlayerMenu(void); +static void M_DrawColorRamp(INT32 x, INT32 y, INT32 w, INT32 h, skincolor_t color); // Handling functions static boolean M_ExitPandorasBox(void); @@ -12010,6 +12011,7 @@ static consvar_t *setupm_cvdefaultskin; static consvar_t *setupm_cvdefaultcolor; static INT32 setupm_fakeskin; static menucolor_t *setupm_fakecolor; +static boolean colorgrid; static void M_DrawSetupMultiPlayerMenu(void) { @@ -12059,7 +12061,7 @@ static void M_DrawSetupMultiPlayerMenu(void) '\x1D' | V_YELLOWMAP, false); } - x = BASEVIDWIDTH/2; + x = colorgrid ? 92 : BASEVIDWIDTH/2; y += 11; // anim the player in the box @@ -12116,61 +12118,121 @@ faildraw: #undef chary colordraw: - x = MP_PlayerSetupDef.x; - y += 75; - - M_DrawLevelPlatterHeader(y - (lsheadingheight - 12), "Color", true, false); - if (itemOn == 2) - cursory = y; - - // draw color string - V_DrawRightAlignedString(BASEVIDWIDTH - x, y, - ((MP_PlayerSetupMenu[2].status & IT_TYPE) == IT_SPACE ? V_TRANSLUCENT : 0)|(itemOn == 2 ? V_YELLOWMAP : 0)|V_ALLOWLOWERCASE, - skincolors[setupm_fakecolor->color].name); - - if (itemOn == 2 && (MP_PlayerSetupMenu[2].status & IT_TYPE) != IT_SPACE) - { - V_DrawCharacter(BASEVIDWIDTH - x - 10 - V_StringWidth(skincolors[setupm_fakecolor->color].name, V_ALLOWLOWERCASE) - (skullAnimCounter/5), y, - '\x1C' | V_YELLOWMAP, false); - V_DrawCharacter(BASEVIDWIDTH - x + 2 + (skullAnimCounter/5), y, - '\x1D' | V_YELLOWMAP, false); - } - - y += 11; #define indexwidth 8 + + if (colorgrid) // Draw color grid & skip the later options + { + UINT16 pos; + INT16 cx = 96, cy = 66; + INT16 i, j; + INT32 w = indexwidth; // Width of a singular color block + boolean stoprow = false; + menucolor_t *mc; // Last accessed color + + x = 132; + y = 66; + pos = min(max(0, 16*((M_GetColorIndex(setupm_fakecolor->color)-1)/16) - 64), 16*(M_GetColorIndex(menucolortail->color)/16-1) - 128); + mc = M_GetColorFromIndex(pos); + + // Draw grid + V_DrawFill(x-2, y-2, 132, 132, 159); + for (j = 0; j < 8; j++) + { + for (i = 0; i < 16; i++) + { + if (skincolors[mc->color].accessible && !stoprow) + { + M_DrawColorRamp(x + i*w, y + j*16, w, 1, skincolors[mc->color]); + if (mc->color == setupm_fakecolor->color) // store current color position + { + cx = x + i*w; + cy = y + j*16; + } + } + mc = mc->next; + while (!skincolors[mc->color].accessible && !stoprow) // Find accessible color after this one + { + mc = mc->next; + if (mc == menucolortail) stoprow = true; + } + } + } + + // Draw arrows, if needed + if (pos > 0) + V_DrawCharacter(264, y - (skullAnimCounter/5), '\x1A' | V_YELLOWMAP, false); + if (!stoprow) + V_DrawCharacter(264, y+120 + (skullAnimCounter/5), '\x1B' | V_YELLOWMAP, false); + + // Draw cursor & current skincolor + V_DrawFill(cx - 2, cy - 2, 12, 20, 0); + V_DrawFill(cx - 1, cy - 1, 11, 19, 31); + V_DrawFill( cx, cy, 9, 17, 0); + M_DrawColorRamp(cx, cy, w, 1, skincolors[setupm_fakecolor->color]); + + // Draw color string (with background) + V_DrawFill(55, 148, 74, 1, 73); + V_DrawFill(55, 149, 74, 1, 26); + M_DrawColorRamp(55, 150, 74, 1, skincolors[setupm_fakecolor->color]); + V_DrawRightAlignedString(x-2,166, + ((MP_PlayerSetupMenu[2].status & IT_TYPE) == IT_SPACE ? V_TRANSLUCENT : 0)|(itemOn == 2 ? V_YELLOWMAP : 0)|V_ALLOWLOWERCASE, + skincolors[setupm_fakecolor->color].name); + + return; // Don't draw anything after this + } + else // Draw color strip & the rest of the menu options { const INT32 numcolors = (282-charw)/(2*indexwidth); // Number of colors per side INT32 w = indexwidth; // Width of a singular color block menucolor_t *mc = setupm_fakecolor->prev; // Last accessed color - UINT8 h; INT16 i; + x = MP_PlayerSetupDef.x; + y += 75; + + // Draw color header & string + M_DrawLevelPlatterHeader(y - (lsheadingheight - 12), "Color...", true, false); + V_DrawRightAlignedString(BASEVIDWIDTH - x, y, + ((MP_PlayerSetupMenu[2].status & IT_TYPE) == IT_SPACE ? V_TRANSLUCENT : 0)|(itemOn == 2 ? V_YELLOWMAP : 0)|V_ALLOWLOWERCASE, + skincolors[setupm_fakecolor->color].name); + + // Draw horizontal arrows + if (itemOn == 2) + { + cursory = y; + if ((MP_PlayerSetupMenu[2].status & IT_TYPE) != IT_SPACE) + { + V_DrawCharacter(BASEVIDWIDTH - x - 10 - V_StringWidth(skincolors[setupm_fakecolor->color].name, V_ALLOWLOWERCASE) - (skullAnimCounter/5), y, + '\x1C' | V_YELLOWMAP, false); + V_DrawCharacter(BASEVIDWIDTH - x + 2 + (skullAnimCounter/5), y, + '\x1D' | V_YELLOWMAP, false); + } + } + // Draw color in the middle x += numcolors*w; - for (h = 0; h < 16; h++) - V_DrawFill(x, y+h, charw, 1, skincolors[setupm_fakecolor->color].ramp[h]); + y += 11; + M_DrawColorRamp(x, y, charw, 1, skincolors[setupm_fakecolor->color]); - //Draw colors from middle to left - for (i=0; icolor].accessible) + while (!skincolors[mc->color].accessible) // Find accessible color before this one mc = mc->prev; - for (h = 0; h < 16; h++) - V_DrawFill(x, y+h, w, 1, skincolors[mc->color].ramp[h]); + M_DrawColorRamp(x, y, w, 1, skincolors[mc->color]); mc = mc->prev; } // Draw colors from middle to right mc = setupm_fakecolor->next; x += numcolors*w + charw; - for (i=0; icolor].accessible) + for (i = 0; i < numcolors; i++) + { + while (!skincolors[mc->color].accessible) // Find accessible color after this one mc = mc->next; - for (h = 0; h < 16; h++) - V_DrawFill(x, y+h, w, 1, skincolors[mc->color].ramp[h]); + M_DrawColorRamp(x, y, w, 1, skincolors[mc->color]); x += w; mc = mc->next; } @@ -12195,6 +12257,13 @@ colordraw: W_CachePatchName("M_CURSOR", PU_PATCH)); } +static void M_DrawColorRamp(INT32 x, INT32 y, INT32 w, INT32 h, skincolor_t color) +{ + UINT8 i; + for (i = 0; i < 16; i++) + V_DrawFill(x, y+(i*h), w, h, color.ramp[i]); +} + // Handle 1P/2P MP Setup static void M_HandleSetupMultiPlayer(INT32 choice) { @@ -12205,13 +12274,25 @@ static void M_HandleSetupMultiPlayer(INT32 choice) switch (choice) { case KEY_DOWNARROW: - M_NextOpt(); - S_StartSound(NULL,sfx_menu1); // Tails - break; - case KEY_UPARROW: - M_PrevOpt(); - S_StartSound(NULL,sfx_menu1); // Tails + { + UINT8 i; + if (itemOn == 2 && colorgrid) + { + for (i = 0; i < 16; i++) + { + setupm_fakecolor = (choice == KEY_UPARROW) ? setupm_fakecolor->prev : setupm_fakecolor->next; + while (!skincolors[setupm_fakecolor->color].accessible) // skip inaccessible colors + setupm_fakecolor = (choice == KEY_UPARROW) ? setupm_fakecolor->prev : setupm_fakecolor->next; + } + } + else if (choice == KEY_UPARROW) + M_PrevOpt(); + else + M_NextOpt(); + + S_StartSound(NULL,sfx_menu1); + } break; case KEY_LEFTARROW: @@ -12246,6 +12327,13 @@ static void M_HandleSetupMultiPlayer(INT32 choice) COM_BufAddText (va("%s %d\n",setupm_cvdefaultcolor->name,setupm_fakecolor->color)); break; } + else if (itemOn == 2) + { + if (!colorgrid) + S_StartSound(NULL,sfx_menu1); + colorgrid = !colorgrid; + break; + } /* FALLTHRU */ case KEY_RIGHTARROW: if (itemOn == 1) //player skin @@ -12275,7 +12363,7 @@ static void M_HandleSetupMultiPlayer(INT32 choice) if (itemOn == 2) // player color { S_StartSound(NULL,sfx_menu1); - for (i = 0; i < 13; i++) // or (282-charw)/(2*indexwidth) + for (i = 0; i < (colorgrid ? 64 : 13); i++) // or (282-charw)/(2*indexwidth) { setupm_fakecolor = (choice == KEY_PGUP) ? setupm_fakecolor->prev : setupm_fakecolor->next; while (!skincolors[setupm_fakecolor->color].accessible) // skip inaccessible colors @@ -12286,7 +12374,10 @@ static void M_HandleSetupMultiPlayer(INT32 choice) break; case KEY_ESCAPE: - exitmenu = true; + if (itemOn == 2 && colorgrid) + colorgrid = false; + else + exitmenu = true; break; case KEY_BACKSPACE: @@ -12596,6 +12687,42 @@ UINT16 M_GetColorAfter(UINT16 color) { } } +UINT16 M_GetColorIndex(UINT16 color) { + menucolor_t *look; + UINT16 i = 0; + + if (color >= numskincolors) { + CONS_Printf("M_GetColorIndex: color %d does not exist.\n",color); + return 0; + } + + for (look=menucolorhead;;look=look->next) { + if (look->color == color) + return i; + if (look==menucolortail) + return 0; + i++; + } +} + +menucolor_t* M_GetColorFromIndex(UINT16 index) { + menucolor_t *look = menucolorhead; + UINT16 i = 0; + + if (index >= numskincolors) { + CONS_Printf("M_GetColorIndex: index %d does not exist.\n",index); + return 0; + } + + for (i = 0; i <= index; i++) { + if (look==menucolortail) + return menucolorhead; + look=look->next; + } + + return look; +} + void M_InitPlayerSetupColors(void) { UINT8 i; numskincolors = SKINCOLOR_FIRSTFREESLOT; diff --git a/src/m_menu.h b/src/m_menu.h index 35c77cc43..c925c7f49 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -482,6 +482,8 @@ void M_MoveColorBefore(UINT16 color, UINT16 targ); void M_MoveColorAfter(UINT16 color, UINT16 targ); UINT16 M_GetColorBefore(UINT16 color); UINT16 M_GetColorAfter(UINT16 color); +UINT16 M_GetColorIndex(UINT16 color); +menucolor_t* M_GetColorFromIndex(UINT16 index); void M_InitPlayerSetupColors(void); void M_FreePlayerSetupColors(void); From c9b6693c765fcabf1523d58ca6e6197dd0609b5b Mon Sep 17 00:00:00 2001 From: spherallic Date: Sat, 29 Oct 2022 00:08:32 +0200 Subject: [PATCH 214/586] Allow pausing & rotation of player sprites in player setup --- src/m_menu.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 63b345692..b4b5409b0 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -11999,6 +11999,8 @@ static void M_HandleConnectIP(INT32 choice) static fixed_t multi_tics; static UINT8 multi_frame; static UINT8 multi_spr2; +static UINT8 multi_angle; +static boolean multi_paused; // this is set before entering the MultiPlayer setup menu, // for either player 1 or 2 @@ -12066,7 +12068,7 @@ static void M_DrawSetupMultiPlayerMenu(void) // anim the player in the box multi_tics -= renderdeltatics; - while (multi_tics <= 0) + while (!multi_paused && multi_tics <= 0) { multi_frame++; multi_tics += 4*FRACUNIT; @@ -12089,8 +12091,8 @@ static void M_DrawSetupMultiPlayerMenu(void) multi_frame = 0; sprframe = &sprdef->spriteframes[multi_frame]; - patch = W_CachePatchNum(sprframe->lumppat[0], PU_PATCH); - if (sprframe->flip & 1) // Only for first sprite + patch = W_CachePatchNum(sprframe->lumppat[multi_angle], PU_PATCH); + if (sprframe->flip & 1 || multi_angle >= 5) // Only for first sprite flags |= V_FLIP; // This sprite is left/right flipped! #define chary (y+64) @@ -12408,6 +12410,20 @@ static void M_HandleSetupMultiPlayer(INT32 choice) } break; + case KEY_KEYPAD5: + multi_paused = !multi_paused; + break; + + case KEY_KEYPAD4: + if (multi_angle <= 0) multi_angle = 7; + else multi_angle--; + break; + + case KEY_KEYPAD6: + if (multi_angle >= 7) multi_angle = 0; + else multi_angle++; + break; + default: if (itemOn != 0 || choice < 32 || choice > 127) break; @@ -12447,6 +12463,7 @@ static void M_SetupMultiPlayer(INT32 choice) multi_frame = 0; multi_tics = 4*FRACUNIT; + multi_angle = 0; strcpy(setupm_name, cv_playername.string); // set for player 1 @@ -12491,6 +12508,7 @@ static void M_SetupMultiPlayer2(INT32 choice) multi_frame = 0; multi_tics = 4*FRACUNIT; + multi_angle = 0; strcpy (setupm_name, cv_playername2.string); // set for splitscreen secondary player From 853c9958d7c044629608d5316715333016c207b5 Mon Sep 17 00:00:00 2001 From: spherallic Date: Sat, 31 Dec 2022 02:40:44 +0100 Subject: [PATCH 215/586] Remove unfinished sprite rotation --- src/m_menu.c | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index b4b5409b0..a1c22bb3e 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -11999,7 +11999,6 @@ static void M_HandleConnectIP(INT32 choice) static fixed_t multi_tics; static UINT8 multi_frame; static UINT8 multi_spr2; -static UINT8 multi_angle; static boolean multi_paused; // this is set before entering the MultiPlayer setup menu, @@ -12091,8 +12090,8 @@ static void M_DrawSetupMultiPlayerMenu(void) multi_frame = 0; sprframe = &sprdef->spriteframes[multi_frame]; - patch = W_CachePatchNum(sprframe->lumppat[multi_angle], PU_PATCH); - if (sprframe->flip & 1 || multi_angle >= 5) // Only for first sprite + patch = W_CachePatchNum(sprframe->lumppat[0], PU_PATCH); + if (sprframe->flip & 1) // Only for first sprite flags |= V_FLIP; // This sprite is left/right flipped! #define chary (y+64) @@ -12410,20 +12409,10 @@ static void M_HandleSetupMultiPlayer(INT32 choice) } break; - case KEY_KEYPAD5: + case KEY_PAUSE: multi_paused = !multi_paused; break; - case KEY_KEYPAD4: - if (multi_angle <= 0) multi_angle = 7; - else multi_angle--; - break; - - case KEY_KEYPAD6: - if (multi_angle >= 7) multi_angle = 0; - else multi_angle++; - break; - default: if (itemOn != 0 || choice < 32 || choice > 127) break; @@ -12463,7 +12452,7 @@ static void M_SetupMultiPlayer(INT32 choice) multi_frame = 0; multi_tics = 4*FRACUNIT; - multi_angle = 0; + strcpy(setupm_name, cv_playername.string); // set for player 1 @@ -12508,7 +12497,7 @@ static void M_SetupMultiPlayer2(INT32 choice) multi_frame = 0; multi_tics = 4*FRACUNIT; - multi_angle = 0; + strcpy (setupm_name, cv_playername2.string); // set for splitscreen secondary player From 5e6850a7f78ddbef1414a82b9e0395ffddfd66b4 Mon Sep 17 00:00:00 2001 From: spherallic Date: Sat, 31 Dec 2022 03:18:26 +0100 Subject: [PATCH 216/586] Some more color tweaks: - Added 6 new colors to match Chaos Emeralds - Changed Taffy & Sapphire (3rd emerald) - Renamed old Emerald to Shamrock --- src/deh_tables.c | 10 ++++++++-- src/doomdef.h | 8 +++++++- src/info.c | 12 +++++++++--- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/deh_tables.c b/src/deh_tables.c index ec60d7311..1344fb400 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -4609,6 +4609,7 @@ const char *COLOR_ENUMS[] = { // Desaturated "AETHER", // SKINCOLOR_AETHER, "SLATE", // SKINCOLOR_SLATE, + "STONE", // SKINCOLOR_STONE, "MERCURY", // SKINCOLOR_MERCURY, "BLUEBELL", // SKINCOLOR_BLUEBELL, "PINK", // SKINCOLOR_PINK, @@ -4637,6 +4638,7 @@ const char *COLOR_ENUMS[] = { "RED", // SKINCOLOR_RED, "CRIMSON", // SKINCOLOR_CRIMSON, "FLAME", // SKINCOLOR_FLAME, + "GARNET", // SKINCOLOR_GARNET, "KETCHUP", // SKINCOLOR_KETCHUP, "PEACHY", // SKINCOLOR_PEACHY, "QUAIL", // SKINCOLOR_QUAIL, @@ -4649,6 +4651,7 @@ const char *COLOR_ENUMS[] = { "RUST", // SKINCOLOR_RUST, "GOLD", // SKINCOLOR_GOLD, "SANDY", // SKINCOLOR_SANDY, + "TOPAZ", // SKINCOLOR_TOPAZ, "YELLOW", // SKINCOLOR_YELLOW, "OLIVE", // SKINCOLOR_OLIVE, "KIWI", // SKINCOLOR_KIWI, @@ -4660,11 +4663,12 @@ const char *COLOR_ENUMS[] = { "CHARTREUSE", // SKINCOLOR_CHARTREUSE, "GREEN", // SKINCOLOR_GREEN, "FOREST", // SKINCOLOR_FOREST, - "EMERALD", // SKINCOLOR_EMERALD, + "SHAMROCK", // SKINCOLOR_SHAMROCK, "JADE", // SKINCOLOR_JADE, "HEADLIGHT", // SKINCOLOR_HEADLIGHT, "MINT", // SKINCOLOR_MINT, "MASTER", // SKINCOLOR_MASTER, + "EMERALD", // SKINCOLOR_EMERALD, "BOTTLE", // SKINCOLOR_BOTTLE, "SEAFOAM", // SKINCOLOR_SEAFOAM, "ISLAND", // SKINCOLOR_ISLAND, @@ -4678,6 +4682,7 @@ const char *COLOR_ENUMS[] = { "CERULEAN", // SKINCOLOR_CERULEAN, "DREAM", // SKINCOLOR_DREAM, "ICY", // SKINCOLOR_ICY, + "AQUAMARINE", // SKINCOLOR_AQUAMARINE, "DAYBREAK", // SKINCOLOR_DAYBREAK, "SAPPHIRE", // SKINCOLOR_SAPPHIRE, "ARCTIC", // SKINCOLOR_ARCTIC, @@ -4693,7 +4698,8 @@ const char *COLOR_ENUMS[] = { "PURPLE", // SKINCOLOR_PURPLE, "NOBLE", // SKINCOLOR_NOBLE, "FUCHSIA", // SKINCOLOR_FUCHSIA, - "BUBBLEGUM", // SKINCOLOR_BUBBLEGUM, + "BUBBLEGUM", // SKINCOLOR_BUBBLEGUM, + "AMETHYST", // SKINCOLOR_AMETHYST, "MAGENTA", // SKINCOLOR_MAGENTA, "NEON", // SKINCOLOR_NEON, "VIOLET", // SKINCOLOR_VIOLET, diff --git a/src/doomdef.h b/src/doomdef.h index aa200274a..8bd311e6a 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -261,6 +261,7 @@ typedef enum // Desaturated SKINCOLOR_AETHER, SKINCOLOR_SLATE, + SKINCOLOR_STONE, SKINCOLOR_MERCURY, SKINCOLOR_BLUEBELL, SKINCOLOR_PINK, @@ -289,6 +290,7 @@ typedef enum SKINCOLOR_RED, SKINCOLOR_CRIMSON, SKINCOLOR_FLAME, + SKINCOLOR_GARNET, SKINCOLOR_KETCHUP, SKINCOLOR_PEACHY, SKINCOLOR_QUAIL, @@ -301,6 +303,7 @@ typedef enum SKINCOLOR_RUST, SKINCOLOR_GOLD, SKINCOLOR_SANDY, + SKINCOLOR_TOPAZ, SKINCOLOR_YELLOW, SKINCOLOR_OLIVE, SKINCOLOR_KIWI, @@ -312,11 +315,12 @@ typedef enum SKINCOLOR_CHARTREUSE, SKINCOLOR_GREEN, SKINCOLOR_FOREST, - SKINCOLOR_EMERALD, + SKINCOLOR_SHAMROCK, SKINCOLOR_JADE, SKINCOLOR_HEADLIGHT, SKINCOLOR_MINT, SKINCOLOR_MASTER, + SKINCOLOR_EMERALD, SKINCOLOR_BOTTLE, SKINCOLOR_SEAFOAM, SKINCOLOR_ISLAND, @@ -330,6 +334,7 @@ typedef enum SKINCOLOR_CERULEAN, SKINCOLOR_DREAM, SKINCOLOR_ICY, + SKINCOLOR_AQUAMARINE, SKINCOLOR_DAYBREAK, SKINCOLOR_SAPPHIRE, // sweet mother, i cannot weave – slender aphrodite has overcome me with longing for a girl SKINCOLOR_ARCTIC, @@ -346,6 +351,7 @@ typedef enum SKINCOLOR_NOBLE, SKINCOLOR_FUCHSIA, SKINCOLOR_BUBBLEGUM, + SKINCOLOR_AMETHYST, SKINCOLOR_MAGENTA, SKINCOLOR_NEON, SKINCOLOR_VIOLET, diff --git a/src/info.c b/src/info.c index ec5a6c72d..052be8c87 100644 --- a/src/info.c +++ b/src/info.c @@ -21586,6 +21586,7 @@ skincolor_t skincolors[MAXSKINCOLORS] = { // Desaturated {"Aether", {0x00, 0x00, 0x01, 0x02, 0x02, 0x03, 0x91, 0x91, 0x91, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xaf}, SKINCOLOR_GREY, 15, 0, true}, // SKINCOLOR_AETHER {"Slate", {0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0xaa, 0xaa, 0xaa, 0xab, 0xac, 0xac, 0xad, 0xad, 0xae, 0xaf}, SKINCOLOR_SILVER, 12, 0, true}, // SKINCOLOR_SLATE + {"Stone", { 0, 4, 8, 9, 11, 12, 14, 15, 171, 172, 173, 174, 175, 27, 29, 31}, SKINCOLOR_TOPAZ, 15, 0, true}, // SKINCOLOR_STONE {"Mercury", { 0, 3, 4, 7, 11, 12, 14, 15, 171, 172, 173, 155, 157, 159, 253, 254}, SKINCOLOR_ECRU, 15, V_AZUREMAP, true}, // SKINCOLOR_MERCURY {"Bluebell", {0x90, 0x91, 0x92, 0x93, 0x94, 0x94, 0x95, 0xac, 0xac, 0xad, 0xad, 0xa8, 0xa8, 0xa9, 0xfd, 0xfe}, SKINCOLOR_COPPER, 4, V_BLUEMAP, true}, // SKINCOLOR_BLUEBELL {"Pink", {0xd0, 0xd0, 0xd1, 0xd1, 0xd2, 0xd2, 0xd3, 0xd3, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0x2b, 0x2c, 0x2e}, SKINCOLOR_AZURE, 9, V_REDMAP, true}, // SKINCOLOR_PINK @@ -21614,6 +21615,7 @@ skincolor_t skincolors[MAXSKINCOLORS] = { {"Red", {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x47, 0x2e, 0x2f}, SKINCOLOR_GREEN, 10, V_REDMAP, true}, // SKINCOLOR_RED {"Crimson", {0x27, 0x27, 0x28, 0x28, 0x29, 0x2a, 0x2b, 0x2b, 0x2c, 0x2d, 0x2e, 0x2e, 0x2e, 0x2f, 0x2f, 0x1f}, SKINCOLOR_ICY, 10, V_REDMAP, true}, // SKINCOLOR_CRIMSON {"Flame", {0x31, 0x32, 0x33, 0x36, 0x22, 0x22, 0x25, 0x25, 0x25, 0xcd, 0xcf, 0xcf, 0xc5, 0xc5, 0xc7, 0xc7}, SKINCOLOR_PURPLE, 8, V_REDMAP, true}, // SKINCOLOR_FLAME + {"Garnet", { 0, 83, 50, 53, 34, 35, 37, 38, 39, 40, 42, 44, 45, 46, 47, 47}, SKINCOLOR_AQUAMARINE, 8, V_REDMAP, true}, // SKINCOLOR_GARNET {"Ketchup", {0x48, 0x49, 0x40, 0x33, 0x34, 0x36, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2b, 0x2c, 0x47, 0x2e, 0x2f}, SKINCOLOR_BOULDER, 8, V_REDMAP, true}, // SKINCOLOR_KETCHUP {"Peachy", {0xd0, 0x30, 0x31, 0x31, 0x32, 0x32, 0xdc, 0xdc, 0xdc, 0xd3, 0xd4, 0xd4, 0xcc, 0xcd, 0xce, 0xcf}, SKINCOLOR_TEAL, 7, V_ROSYMAP, true}, // SKINCOLOR_PEACHY {"Quail", {0xd8, 0xd9, 0xdb, 0xdc, 0xde, 0xdf, 0xd5, 0xd5, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0x1d, 0x1f}, SKINCOLOR_WAVE, 5, V_BROWNMAP, true}, // SKINCOLOR_QUAIL @@ -21626,6 +21628,7 @@ skincolor_t skincolors[MAXSKINCOLORS] = { {"Rust", {0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3c, 0x3d, 0x3d, 0x3d, 0x3f, 0x2c, 0x2d, 0x47, 0x2e, 0x2f, 0x2f}, SKINCOLOR_YOGURT, 8, V_ORANGEMAP, true}, // SKINCOLOR_RUST {"Gold", {0x51, 0x51, 0x54, 0x54, 0x41, 0x42, 0x43, 0x43, 0x44, 0x45, 0x46, 0x3f, 0x2d, 0x2e, 0x2f, 0x2f}, SKINCOLOR_LAVENDER, 10, V_YELLOWMAP, true}, // SKINCOLOR_GOLD {"Sandy", {0x53, 0x40, 0x41, 0x42, 0x43, 0xe6, 0xe9, 0xe9, 0xea, 0xec, 0xec, 0xc6, 0xc6, 0xc7, 0xc7, 0xfe}, SKINCOLOR_SKY, 8, V_YELLOWMAP, true}, // SKINCOLOR_SANDY + {"Topaz", { 0, 81, 72, 73, 64, 65, 66, 66, 54, 55, 57, 59, 60, 42, 43, 45}, SKINCOLOR_STONE , 8, V_YELLOWMAP, true}, // SKINCOLOR_TOPAZ {"Yellow", {0x52, 0x53, 0x49, 0x49, 0x4a, 0x4a, 0x4b, 0x4b, 0x4b, 0x4c, 0x4d, 0x4d, 0x4e, 0x4e, 0x4f, 0xed}, SKINCOLOR_CORNFLOWER, 8, V_YELLOWMAP, true}, // SKINCOLOR_YELLOW {"Olive", {0x4b, 0x4b, 0x4c, 0x4c, 0x4d, 0x4e, 0xe7, 0xe7, 0xe9, 0xc5, 0xc5, 0xc6, 0xc6, 0xc7, 0xc7, 0xfd}, SKINCOLOR_DUSK, 3, V_YELLOWMAP, true}, // SKINCOLOR_OLIVE {"Kiwi", { 88, 64, 188, 189, 189, 76, 76, 67, 67, 68, 69, 70, 45, 46, 47, 47}, SKINCOLOR_MARINE, 7, V_PERIDOTMAP, true}, // SKINCOLOR_KIWI @@ -21637,11 +21640,12 @@ skincolor_t skincolors[MAXSKINCOLORS] = { {"Chartreuse", { 80, 82, 72, 73, 188, 188, 113, 114, 114, 125, 126, 137, 138, 139, 253, 254}, SKINCOLOR_NOBLE, 12, V_PERIDOTMAP, true}, // SKINCOLOR_CHARTREUSE {"Green", {0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f}, SKINCOLOR_RED, 6, V_GREENMAP, true}, // SKINCOLOR_GREEN {"Forest", {0x65, 0x66, 0x67, 0x68, 0x69, 0x69, 0x6a, 0x6b, 0x6b, 0x6c, 0x6d, 0x6d, 0x6e, 0x6e, 0x6e, 0x6f}, SKINCOLOR_SALMON, 9, V_GREENMAP, true}, // SKINCOLOR_FOREST - {"Emerald", {0x70, 0x70, 0x71, 0x71, 0x72, 0x72, 0x73, 0x73, 0x73, 0x74, 0x75, 0x75, 0x76, 0x76, 0x77, 0x77}, SKINCOLOR_RUBY, 4, V_GREENMAP, true}, // SKINCOLOR_EMERALD + {"Shamrock", {0x70, 0x70, 0x71, 0x71, 0x72, 0x72, 0x73, 0x73, 0x73, 0x74, 0x75, 0x75, 0x76, 0x76, 0x77, 0x77}, SKINCOLOR_AMETHYST, 4, V_GREENMAP, true}, // SKINCOLOR_SHAMROCK {"Jade", { 128, 120, 121, 122, 122, 113, 114, 114, 115, 116, 117, 118, 119, 110, 111, 30}, SKINCOLOR_TAFFY, 8, V_GREENMAP, true}, // SKINCOLOR_JADE {"Headlight", { 0, 80, 81, 82, 73, 84, 64, 65, 91, 91, 124, 125, 126, 137, 138, 139}, SKINCOLOR_MAUVE, 8, V_YELLOWMAP, true}, // SKINCOLOR_HEADLIGHT {"Mint", {0x00, 0x00, 0x58, 0x58, 0x59, 0x62, 0x62, 0x62, 0x64, 0x67, 0x7e, 0x7e, 0x8f, 0x8f, 0x8a, 0x8a}, SKINCOLOR_VIOLET, 5, V_GREENMAP, true}, // SKINCOLOR_MINT {"Master", { 0, 80, 88, 96, 112, 113, 99, 100, 124, 125, 126, 117, 107, 118, 119, 111}, SKINCOLOR_PEPPER, 8, V_GREENMAP, true}, // SKINCOLOR_MASTER + {"Emerald", { 80, 96, 112, 113, 114, 114, 125, 125, 126, 126, 137, 137, 138, 138, 139, 139}, SKINCOLOR_RUBY, 4, V_GREENMAP, true}, // SKINCOLOR_EMERALD {"Bottle", { 0, 1, 3, 4, 5, 140, 141, 141, 124, 125, 126, 127, 118, 119, 111, 111}, SKINCOLOR_LATTE, 14, V_AQUAMAP, true}, // SKINCOLOR_BOTTLE {"Seafoam", {0x01, 0x58, 0x59, 0x5a, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x8f, 0x8f, 0x8a, 0x8a, 0x8a, 0xfd, 0xfd}, SKINCOLOR_PLUM, 6, V_AQUAMAP, true}, // SKINCOLOR_SEAFOAM {"Island", { 96, 97, 113, 113, 114, 124, 142, 136, 136, 150, 151, 153, 168, 168, 169, 169}, SKINCOLOR_GALAXY, 7, V_AQUAMAP, true}, // SKINCOLOR_ISLAND @@ -21655,8 +21659,9 @@ skincolor_t skincolors[MAXSKINCOLORS] = { {"Cerulean", {0x85, 0x86, 0x87, 0x88, 0x88, 0x89, 0x89, 0x89, 0x8a, 0x8a, 0xfd, 0xfd, 0xfd, 0x1f, 0x1f, 0x1f}, SKINCOLOR_NEON, 4, V_SKYMAP, true}, // SKINCOLOR_CERULEAN {"Dream", { 80, 208, 200, 200, 146, 146, 133, 134, 135, 136, 137, 138, 139, 139, 254, 254}, SKINCOLOR_FOUNDATION, 9, V_SKYMAP, true}, // SKINCOLOR_DREAM {"Icy", {0x00, 0x00, 0x00, 0x00, 0x80, 0x81, 0x83, 0x83, 0x86, 0x87, 0x95, 0x95, 0xad, 0xad, 0xae, 0xaf}, SKINCOLOR_CRIMSON, 0, V_SKYMAP, true}, // SKINCOLOR_ICY + {"Aquamarine", { 0, 120, 121, 131, 132, 133, 134, 134, 135, 135, 149, 149, 172, 173, 174, 175}, SKINCOLOR_GARNET, 0, V_SKYMAP, true}, // SKINCOLOR_AQUAMARINE {"Daybreak", { 80, 81, 82, 72, 64, 9, 11, 171, 149, 150, 151, 153, 156, 157, 159, 253}, SKINCOLOR_EVENTIDE, 12, V_BLUEMAP, true}, // SKINCOLOR_DAYBREAK - {"Sapphire", {0x80, 0x83, 0x86, 0x87, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xfd, 0xfe}, SKINCOLOR_SUNSET, 5, V_SKYMAP, true}, // SKINCOLOR_SAPPHIRE + {"Sapphire", {0x80, 0x82, 0x86, 0x87, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xfd, 0xfe}, SKINCOLOR_SUNSET, 5, V_SKYMAP, true}, // SKINCOLOR_SAPPHIRE {"Arctic", { 0, 1, 3, 4, 146, 146, 147, 148, 148, 149, 150, 153, 156, 159, 253, 254}, SKINCOLOR_PUMPKIN, 10, V_BLUEMAP, true}, // SKINCOLOR_ARCTIC {"Cornflower", {0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x9a, 0x9c, 0x9d, 0x9d, 0x9e, 0x9e, 0x9e}, SKINCOLOR_YELLOW, 4, V_BLUEMAP, true}, // SKINCOLOR_CORNFLOWER {"Blue", {0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xfd, 0xfe}, SKINCOLOR_ORANGE, 5, V_BLUEMAP, true}, // SKINCOLOR_BLUE @@ -21671,6 +21676,7 @@ skincolor_t skincolors[MAXSKINCOLORS] = { {"Noble", { 144, 146, 147, 148, 148, 164, 164, 165, 165, 185, 186, 186, 187, 187, 28, 29}, SKINCOLOR_CHARTREUSE, 12, V_PURPLEMAP, true}, // SKINCOLOR_NOBLE {"Fuchsia", { 200, 201, 203, 204, 204, 183, 184, 184, 165, 166, 167, 168, 169, 159, 253, 254}, SKINCOLOR_LEMON, 6, V_PURPLEMAP, true}, // SKINCOLOR_FUCHSIA {"Bubblegum", { 0, 208, 208, 176, 177, 178, 179, 180, 181, 183, 165, 166, 167, 168, 169, 253}, SKINCOLOR_PASTEL, 8, V_MAGENTAMAP, true}, // SKINCOLOR_BUBBLEGUM + {"Amethyst", { 252, 177, 179, 180, 181, 181, 182, 182, 183, 164, 166, 167, 167, 168, 169, 159}, SKINCOLOR_EMERALD, 8, V_MAGENTAMAP, true}, // SKINCOLOR_AMETHYST {"Magenta", {0xb3, 0xb3, 0xb4, 0xb5, 0xb6, 0xb6, 0xb7, 0xb7, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xbb}, SKINCOLOR_LIME, 6, V_MAGENTAMAP, true}, // SKINCOLOR_MAGENTA {"Neon", {0xb3, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xbb, 0xc7, 0xc7, 0x1d, 0x1d, 0x1e}, SKINCOLOR_CERULEAN, 2, V_MAGENTAMAP, true}, // SKINCOLOR_NEON {"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 @@ -21680,7 +21686,7 @@ skincolor_t skincolors[MAXSKINCOLORS] = { {"Eventide", { 51, 52, 53, 33, 34, 204, 183, 183, 184, 184, 166, 167, 168, 169, 253, 254}, SKINCOLOR_DAYBREAK, 12, V_REDMAP, true}, // SKINCOLOR_EVENTIDE {"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 - {"Taffy", { 1, 176, 176, 177, 178, 179, 202, 203, 204, 204, 206, 207, 44, 44, 46, 47}, SKINCOLOR_JADE, 8, V_ROSYMAP, true}, // SKINCOLOR_TAFFY + {"Taffy", { 1, 176, 176, 177, 178, 179, 202, 203, 204, 204, 205, 206, 207, 44, 45, 46}, SKINCOLOR_JADE, 8, V_ROSYMAP, true}, // SKINCOLOR_TAFFY {"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 {"Fancy", { 0, 208, 49, 210, 210, 202, 202, 203, 204, 204, 205, 206, 207, 207, 186, 186}, SKINCOLOR_ROYAL, 9, V_ROSYMAP, true}, // SKINCOLOR_FANCY {"Sangria", { 210, 32, 33, 34, 35, 215, 215, 207, 207, 185, 186, 186, 186, 169, 169, 253}, SKINCOLOR_TURQUOISE, 7, V_ROSYMAP, true}, // SKINCOLOR_SANGRIA From 70b69552f9f42ee1a94b29583f75ebc50ddb2f56 Mon Sep 17 00:00:00 2001 From: spherallic Date: Sat, 31 Dec 2022 14:30:47 +0100 Subject: [PATCH 217/586] Add toggle for invcolor background, plus: - Renamed Amethyst to Crystal - Moved some of the new colors - Tweaked a couple of invshades --- src/deh_tables.c | 6 +++--- src/doomdef.h | 6 +++--- src/info.c | 22 +++++++++++----------- src/m_menu.c | 8 +++++++- 4 files changed, 24 insertions(+), 18 deletions(-) diff --git a/src/deh_tables.c b/src/deh_tables.c index 1344fb400..d174afb12 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -4649,9 +4649,9 @@ const char *COLOR_ENUMS[] = { "ORANGE", // SKINCOLOR_ORANGE, "PUMPKIN", // SKINCOLOR_PUMPKIN, "RUST", // SKINCOLOR_RUST, + "TOPAZ", // SKINCOLOR_TOPAZ, "GOLD", // SKINCOLOR_GOLD, "SANDY", // SKINCOLOR_SANDY, - "TOPAZ", // SKINCOLOR_TOPAZ, "YELLOW", // SKINCOLOR_YELLOW, "OLIVE", // SKINCOLOR_OLIVE, "KIWI", // SKINCOLOR_KIWI, @@ -4677,12 +4677,12 @@ const char *COLOR_ENUMS[] = { "WAVE", // SKINCOLOR_WAVE, "CYAN", // SKINCOLOR_CYAN, "TURQUOISE", // SKINCOLOR_TURQUOISE, + "AQUAMARINE", // SKINCOLOR_AQUAMARINE, "SKY", // SKINCOLOR_SKY, "MARINE", // SKINCOLOR_MARINE, "CERULEAN", // SKINCOLOR_CERULEAN, "DREAM", // SKINCOLOR_DREAM, "ICY", // SKINCOLOR_ICY, - "AQUAMARINE", // SKINCOLOR_AQUAMARINE, "DAYBREAK", // SKINCOLOR_DAYBREAK, "SAPPHIRE", // SKINCOLOR_SAPPHIRE, "ARCTIC", // SKINCOLOR_ARCTIC, @@ -4699,7 +4699,7 @@ const char *COLOR_ENUMS[] = { "NOBLE", // SKINCOLOR_NOBLE, "FUCHSIA", // SKINCOLOR_FUCHSIA, "BUBBLEGUM", // SKINCOLOR_BUBBLEGUM, - "AMETHYST", // SKINCOLOR_AMETHYST, + "CRYSTAL", // SKINCOLOR_CRYSTAL, "MAGENTA", // SKINCOLOR_MAGENTA, "NEON", // SKINCOLOR_NEON, "VIOLET", // SKINCOLOR_VIOLET, diff --git a/src/doomdef.h b/src/doomdef.h index 8bd311e6a..d19543e23 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -301,9 +301,9 @@ typedef enum SKINCOLOR_ORANGE, SKINCOLOR_PUMPKIN, SKINCOLOR_RUST, + SKINCOLOR_TOPAZ, SKINCOLOR_GOLD, SKINCOLOR_SANDY, - SKINCOLOR_TOPAZ, SKINCOLOR_YELLOW, SKINCOLOR_OLIVE, SKINCOLOR_KIWI, @@ -329,12 +329,12 @@ typedef enum SKINCOLOR_WAVE, SKINCOLOR_CYAN, SKINCOLOR_TURQUOISE, + SKINCOLOR_AQUAMARINE, SKINCOLOR_SKY, SKINCOLOR_MARINE, SKINCOLOR_CERULEAN, SKINCOLOR_DREAM, SKINCOLOR_ICY, - SKINCOLOR_AQUAMARINE, SKINCOLOR_DAYBREAK, SKINCOLOR_SAPPHIRE, // sweet mother, i cannot weave – slender aphrodite has overcome me with longing for a girl SKINCOLOR_ARCTIC, @@ -351,7 +351,7 @@ typedef enum SKINCOLOR_NOBLE, SKINCOLOR_FUCHSIA, SKINCOLOR_BUBBLEGUM, - SKINCOLOR_AMETHYST, + SKINCOLOR_CRYSTAL, SKINCOLOR_MAGENTA, SKINCOLOR_NEON, SKINCOLOR_VIOLET, diff --git a/src/info.c b/src/info.c index 052be8c87..2b6d6affb 100644 --- a/src/info.c +++ b/src/info.c @@ -21592,7 +21592,7 @@ skincolor_t skincolors[MAXSKINCOLORS] = { {"Pink", {0xd0, 0xd0, 0xd1, 0xd1, 0xd2, 0xd2, 0xd3, 0xd3, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0x2b, 0x2c, 0x2e}, SKINCOLOR_AZURE, 9, V_REDMAP, true}, // SKINCOLOR_PINK {"Rosewood", { 209, 210, 211, 212, 213, 214, 228, 230, 232, 234, 235, 237, 26, 27, 28, 29}, SKINCOLOR_SEPIA, 5, V_BROWNMAP, true}, // SKINCOLOR_ROSEWOOD {"Yogurt", {0xd0, 0x30, 0xd8, 0xd9, 0xda, 0xdb, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe3, 0xe6, 0xe8, 0xe9}, SKINCOLOR_RUST, 7, V_BROWNMAP, true}, // SKINCOLOR_YOGURT - {"Latte", { 48, 217, 219, 221, 223, 224, 226, 228, 68, 69, 70, 70, 44, 45, 46, 47}, SKINCOLOR_BOTTLE, 14, V_BROWNMAP, true}, // SKINCOLOR_LATTE + {"Latte", { 48, 217, 219, 221, 223, 224, 226, 228, 68, 69, 70, 70, 44, 45, 46, 47}, SKINCOLOR_BOTTLE, 12, V_BROWNMAP, true}, // SKINCOLOR_LATTE {"Brown", {0xdf, 0xe0, 0xe1, 0xe2, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef}, SKINCOLOR_TAN, 2, V_BROWNMAP, true}, // SKINCOLOR_BROWN {"Boulder", {0xde, 0xe0, 0xe1, 0xe4, 0xe7, 0xe9, 0xeb, 0xec, 0xed, 0xed, 0xed, 0x19, 0x19, 0x1b, 0x1d, 0x1e}, SKINCOLOR_KETCHUP, 0, V_BROWNMAP, true}, // SKINCOLOR_BOULDER {"Bronze", { 82, 84, 50, 51, 223, 228, 230, 232, 234, 236, 237, 238, 239, 239, 30, 31}, SKINCOLOR_VOLCANIC, 9, V_BROWNMAP, true}, // SKINCOLOR_BRONZE @@ -21627,11 +21627,11 @@ skincolor_t skincolors[MAXSKINCOLORS] = { {"Pumpkin", { 51, 52, 53, 54, 56, 58, 59, 59, 61, 61, 63, 45, 46, 47, 47, 31}, SKINCOLOR_ARCTIC, 10, V_ORANGEMAP, true}, // SKINCOLOR_PUMPKIN {"Rust", {0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3c, 0x3d, 0x3d, 0x3d, 0x3f, 0x2c, 0x2d, 0x47, 0x2e, 0x2f, 0x2f}, SKINCOLOR_YOGURT, 8, V_ORANGEMAP, true}, // SKINCOLOR_RUST {"Gold", {0x51, 0x51, 0x54, 0x54, 0x41, 0x42, 0x43, 0x43, 0x44, 0x45, 0x46, 0x3f, 0x2d, 0x2e, 0x2f, 0x2f}, SKINCOLOR_LAVENDER, 10, V_YELLOWMAP, true}, // SKINCOLOR_GOLD + {"Topaz", { 0, 81, 72, 73, 64, 65, 66, 66, 54, 55, 57, 59, 60, 42, 43, 45}, SKINCOLOR_STONE , 10, V_YELLOWMAP, true}, // SKINCOLOR_TOPAZ {"Sandy", {0x53, 0x40, 0x41, 0x42, 0x43, 0xe6, 0xe9, 0xe9, 0xea, 0xec, 0xec, 0xc6, 0xc6, 0xc7, 0xc7, 0xfe}, SKINCOLOR_SKY, 8, V_YELLOWMAP, true}, // SKINCOLOR_SANDY - {"Topaz", { 0, 81, 72, 73, 64, 65, 66, 66, 54, 55, 57, 59, 60, 42, 43, 45}, SKINCOLOR_STONE , 8, V_YELLOWMAP, true}, // SKINCOLOR_TOPAZ {"Yellow", {0x52, 0x53, 0x49, 0x49, 0x4a, 0x4a, 0x4b, 0x4b, 0x4b, 0x4c, 0x4d, 0x4d, 0x4e, 0x4e, 0x4f, 0xed}, SKINCOLOR_CORNFLOWER, 8, V_YELLOWMAP, true}, // SKINCOLOR_YELLOW {"Olive", {0x4b, 0x4b, 0x4c, 0x4c, 0x4d, 0x4e, 0xe7, 0xe7, 0xe9, 0xc5, 0xc5, 0xc6, 0xc6, 0xc7, 0xc7, 0xfd}, SKINCOLOR_DUSK, 3, V_YELLOWMAP, true}, // SKINCOLOR_OLIVE - {"Kiwi", { 88, 64, 188, 189, 189, 76, 76, 67, 67, 68, 69, 70, 45, 46, 47, 47}, SKINCOLOR_MARINE, 7, V_PERIDOTMAP, true}, // SKINCOLOR_KIWI + {"Kiwi", { 88, 64, 188, 189, 189, 76, 76, 67, 67, 68, 69, 70, 45, 46, 47, 47}, SKINCOLOR_MARINE, 9, V_PERIDOTMAP, true}, // SKINCOLOR_KIWI {"Lemon", { 0, 80, 81, 83, 73, 73, 74, 74, 76, 76, 191, 191, 79, 79, 110, 111}, SKINCOLOR_FUCHSIA, 6, V_YELLOWMAP, true}, // SKINCOLOR_LEMON {"Lime", {0x50, 0x51, 0x52, 0x53, 0x48, 0xbc, 0xbd, 0xbe, 0xbe, 0xbf, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f}, SKINCOLOR_MAGENTA, 9, V_PERIDOTMAP, true}, // SKINCOLOR_LIME {"Mindaro", { 0, 80, 81, 82, 83, 64, 188, 189, 189, 190, 115, 116, 117, 118, 119, 111}, SKINCOLOR_MAJESTY, 11, V_PERIDOTMAP, true}, // SKINCOLOR_MINDARO @@ -21640,13 +21640,13 @@ skincolor_t skincolors[MAXSKINCOLORS] = { {"Chartreuse", { 80, 82, 72, 73, 188, 188, 113, 114, 114, 125, 126, 137, 138, 139, 253, 254}, SKINCOLOR_NOBLE, 12, V_PERIDOTMAP, true}, // SKINCOLOR_CHARTREUSE {"Green", {0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f}, SKINCOLOR_RED, 6, V_GREENMAP, true}, // SKINCOLOR_GREEN {"Forest", {0x65, 0x66, 0x67, 0x68, 0x69, 0x69, 0x6a, 0x6b, 0x6b, 0x6c, 0x6d, 0x6d, 0x6e, 0x6e, 0x6e, 0x6f}, SKINCOLOR_SALMON, 9, V_GREENMAP, true}, // SKINCOLOR_FOREST - {"Shamrock", {0x70, 0x70, 0x71, 0x71, 0x72, 0x72, 0x73, 0x73, 0x73, 0x74, 0x75, 0x75, 0x76, 0x76, 0x77, 0x77}, SKINCOLOR_AMETHYST, 4, V_GREENMAP, true}, // SKINCOLOR_SHAMROCK - {"Jade", { 128, 120, 121, 122, 122, 113, 114, 114, 115, 116, 117, 118, 119, 110, 111, 30}, SKINCOLOR_TAFFY, 8, V_GREENMAP, true}, // SKINCOLOR_JADE + {"Shamrock", {0x70, 0x70, 0x71, 0x71, 0x72, 0x72, 0x73, 0x73, 0x73, 0x74, 0x75, 0x75, 0x76, 0x76, 0x77, 0x77}, SKINCOLOR_CRYSTAL, 10, V_GREENMAP, true}, // SKINCOLOR_SHAMROCK + {"Jade", { 128, 120, 121, 122, 122, 113, 114, 114, 115, 116, 117, 118, 119, 110, 111, 30}, SKINCOLOR_TAFFY, 10, V_GREENMAP, true}, // SKINCOLOR_JADE {"Headlight", { 0, 80, 81, 82, 73, 84, 64, 65, 91, 91, 124, 125, 126, 137, 138, 139}, SKINCOLOR_MAUVE, 8, V_YELLOWMAP, true}, // SKINCOLOR_HEADLIGHT {"Mint", {0x00, 0x00, 0x58, 0x58, 0x59, 0x62, 0x62, 0x62, 0x64, 0x67, 0x7e, 0x7e, 0x8f, 0x8f, 0x8a, 0x8a}, SKINCOLOR_VIOLET, 5, V_GREENMAP, true}, // SKINCOLOR_MINT {"Master", { 0, 80, 88, 96, 112, 113, 99, 100, 124, 125, 126, 117, 107, 118, 119, 111}, SKINCOLOR_PEPPER, 8, V_GREENMAP, true}, // SKINCOLOR_MASTER - {"Emerald", { 80, 96, 112, 113, 114, 114, 125, 125, 126, 126, 137, 137, 138, 138, 139, 139}, SKINCOLOR_RUBY, 4, V_GREENMAP, true}, // SKINCOLOR_EMERALD - {"Bottle", { 0, 1, 3, 4, 5, 140, 141, 141, 124, 125, 126, 127, 118, 119, 111, 111}, SKINCOLOR_LATTE, 14, V_AQUAMAP, true}, // SKINCOLOR_BOTTLE + {"Emerald", { 80, 96, 112, 113, 114, 114, 125, 125, 126, 126, 137, 137, 138, 138, 139, 139}, SKINCOLOR_RUBY, 7, V_GREENMAP, true}, // SKINCOLOR_EMERALD + {"Bottle", { 0, 1, 3, 4, 5, 140, 141, 141, 124, 125, 126, 127, 118, 119, 111, 111}, SKINCOLOR_LATTE, 12, V_AQUAMAP, true}, // SKINCOLOR_BOTTLE {"Seafoam", {0x01, 0x58, 0x59, 0x5a, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x8f, 0x8f, 0x8a, 0x8a, 0x8a, 0xfd, 0xfd}, SKINCOLOR_PLUM, 6, V_AQUAMAP, true}, // SKINCOLOR_SEAFOAM {"Island", { 96, 97, 113, 113, 114, 124, 142, 136, 136, 150, 151, 153, 168, 168, 169, 169}, SKINCOLOR_GALAXY, 7, V_AQUAMAP, true}, // SKINCOLOR_ISLAND {"Aqua", {0x78, 0x79, 0x7a, 0x7a, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7d, 0x7e, 0x7e, 0x7f, 0x7f, 0x76, 0x77}, SKINCOLOR_ROSY, 7, V_AQUAMAP, true}, // SKINCOLOR_AQUA @@ -21654,12 +21654,12 @@ skincolor_t skincolors[MAXSKINCOLORS] = { {"Wave", {0x00, 0x78, 0x78, 0x79, 0x8d, 0x87, 0x88, 0x89, 0x89, 0xae, 0xa8, 0xa8, 0xa9, 0xa9, 0xfd, 0xfd}, SKINCOLOR_QUAIL, 5, V_SKYMAP, true}, // SKINCOLOR_WAVE {"Cyan", {0x80, 0x81, 0xff, 0xff, 0x83, 0x83, 0x8d, 0x8d, 0x8d, 0x8e, 0x7e, 0x7f, 0x76, 0x76, 0x77, 0x6e}, SKINCOLOR_APRICOT, 6, V_SKYMAP, true}, // SKINCOLOR_CYAN {"Turquoise", { 0, 120, 121, 122, 123, 141, 141, 135, 136, 136, 150, 153, 155, 157, 159, 253}, SKINCOLOR_SANGRIA, 7, V_SKYMAP, true}, // SKINCOLOR_TURQUOISE + {"Aquamarine", { 0, 120, 121, 131, 132, 133, 134, 134, 135, 135, 149, 149, 172, 173, 174, 175}, SKINCOLOR_GARNET, 8, V_SKYMAP, true}, // SKINCOLOR_AQUAMARINE {"Sky", {0x80, 0x80, 0x81, 0x82, 0x83, 0x83, 0x84, 0x85, 0x85, 0x86, 0x87, 0x88, 0x89, 0x89, 0x8a, 0x8b}, SKINCOLOR_SANDY, 1, V_SKYMAP, true}, // SKINCOLOR_SKY - {"Marine", { 144, 146, 147, 147, 148, 135, 136, 136, 137, 137, 127, 118, 119, 111, 111, 111}, SKINCOLOR_KIWI, 10, V_SKYMAP, true}, // SKINCOLOR_MARINE + {"Marine", { 144, 146, 147, 147, 148, 135, 136, 136, 137, 137, 127, 118, 119, 111, 111, 111}, SKINCOLOR_KIWI, 13, V_SKYMAP, true}, // SKINCOLOR_MARINE {"Cerulean", {0x85, 0x86, 0x87, 0x88, 0x88, 0x89, 0x89, 0x89, 0x8a, 0x8a, 0xfd, 0xfd, 0xfd, 0x1f, 0x1f, 0x1f}, SKINCOLOR_NEON, 4, V_SKYMAP, true}, // SKINCOLOR_CERULEAN {"Dream", { 80, 208, 200, 200, 146, 146, 133, 134, 135, 136, 137, 138, 139, 139, 254, 254}, SKINCOLOR_FOUNDATION, 9, V_SKYMAP, true}, // SKINCOLOR_DREAM {"Icy", {0x00, 0x00, 0x00, 0x00, 0x80, 0x81, 0x83, 0x83, 0x86, 0x87, 0x95, 0x95, 0xad, 0xad, 0xae, 0xaf}, SKINCOLOR_CRIMSON, 0, V_SKYMAP, true}, // SKINCOLOR_ICY - {"Aquamarine", { 0, 120, 121, 131, 132, 133, 134, 134, 135, 135, 149, 149, 172, 173, 174, 175}, SKINCOLOR_GARNET, 0, V_SKYMAP, true}, // SKINCOLOR_AQUAMARINE {"Daybreak", { 80, 81, 82, 72, 64, 9, 11, 171, 149, 150, 151, 153, 156, 157, 159, 253}, SKINCOLOR_EVENTIDE, 12, V_BLUEMAP, true}, // SKINCOLOR_DAYBREAK {"Sapphire", {0x80, 0x82, 0x86, 0x87, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xfd, 0xfe}, SKINCOLOR_SUNSET, 5, V_SKYMAP, true}, // SKINCOLOR_SAPPHIRE {"Arctic", { 0, 1, 3, 4, 146, 146, 147, 148, 148, 149, 150, 153, 156, 159, 253, 254}, SKINCOLOR_PUMPKIN, 10, V_BLUEMAP, true}, // SKINCOLOR_ARCTIC @@ -21676,14 +21676,14 @@ skincolor_t skincolors[MAXSKINCOLORS] = { {"Noble", { 144, 146, 147, 148, 148, 164, 164, 165, 165, 185, 186, 186, 187, 187, 28, 29}, SKINCOLOR_CHARTREUSE, 12, V_PURPLEMAP, true}, // SKINCOLOR_NOBLE {"Fuchsia", { 200, 201, 203, 204, 204, 183, 184, 184, 165, 166, 167, 168, 169, 159, 253, 254}, SKINCOLOR_LEMON, 6, V_PURPLEMAP, true}, // SKINCOLOR_FUCHSIA {"Bubblegum", { 0, 208, 208, 176, 177, 178, 179, 180, 181, 183, 165, 166, 167, 168, 169, 253}, SKINCOLOR_PASTEL, 8, V_MAGENTAMAP, true}, // SKINCOLOR_BUBBLEGUM - {"Amethyst", { 252, 177, 179, 180, 181, 181, 182, 182, 183, 164, 166, 167, 167, 168, 169, 159}, SKINCOLOR_EMERALD, 8, V_MAGENTAMAP, true}, // SKINCOLOR_AMETHYST + {"Crystal", { 252, 177, 179, 180, 181, 181, 182, 182, 183, 164, 166, 167, 167, 168, 169, 159}, SKINCOLOR_EMERALD, 8, V_MAGENTAMAP, true}, // SKINCOLOR_CRYSTAL {"Magenta", {0xb3, 0xb3, 0xb4, 0xb5, 0xb6, 0xb6, 0xb7, 0xb7, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xbb}, SKINCOLOR_LIME, 6, V_MAGENTAMAP, true}, // SKINCOLOR_MAGENTA {"Neon", {0xb3, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xbb, 0xc7, 0xc7, 0x1d, 0x1d, 0x1e}, SKINCOLOR_CERULEAN, 2, V_MAGENTAMAP, true}, // SKINCOLOR_NEON {"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 {"Royal", { 208, 209, 192, 192, 192, 193, 193, 194, 194, 172, 173, 174, 175, 175, 139, 139}, SKINCOLOR_FANCY, 9, V_PURPLEMAP, true}, // SKINCOLOR_ROYAL {"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 {"Mauve", { 176, 177, 178, 192, 193, 194, 195, 195, 196, 185, 185, 186, 186, 187, 187, 253}, SKINCOLOR_HEADLIGHT, 8, V_PURPLEMAP, true}, // SKINCOLOR_MAUVE - {"Eventide", { 51, 52, 53, 33, 34, 204, 183, 183, 184, 184, 166, 167, 168, 169, 253, 254}, SKINCOLOR_DAYBREAK, 12, V_REDMAP, true}, // SKINCOLOR_EVENTIDE + {"Eventide", { 51, 52, 53, 33, 34, 204, 183, 183, 184, 184, 166, 167, 168, 169, 253, 254}, SKINCOLOR_DAYBREAK, 13, V_MAGENTAMAP, true}, // SKINCOLOR_EVENTIDE {"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 {"Taffy", { 1, 176, 176, 177, 178, 179, 202, 203, 204, 204, 205, 206, 207, 44, 45, 46}, SKINCOLOR_JADE, 8, V_ROSYMAP, true}, // SKINCOLOR_TAFFY diff --git a/src/m_menu.c b/src/m_menu.c index a1c22bb3e..cf61e7fb1 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -12000,6 +12000,7 @@ static fixed_t multi_tics; static UINT8 multi_frame; static UINT8 multi_spr2; static boolean multi_paused; +static boolean multi_invcolor; // this is set before entering the MultiPlayer setup menu, // for either player 1 or 2 @@ -12076,7 +12077,8 @@ static void M_DrawSetupMultiPlayerMenu(void) #define charw 74 // draw box around character - V_DrawFill(x-(charw/2), y, charw, 84, 159); + V_DrawFill(x-(charw/2), y, charw, 84, + multi_invcolor ?skincolors[skincolors[setupm_fakecolor->color].invcolor].ramp[skincolors[setupm_fakecolor->color].invshade] : 159); sprdef = &skins[setupm_fakeskin].sprites[multi_spr2]; @@ -12413,6 +12415,10 @@ static void M_HandleSetupMultiPlayer(INT32 choice) multi_paused = !multi_paused; break; + case KEY_INS: + multi_invcolor = !multi_invcolor; + break; + default: if (itemOn != 0 || choice < 32 || choice > 127) break; From 1bd593d17337a2664c58c46c316613cde8e48781 Mon Sep 17 00:00:00 2001 From: spherallic Date: Tue, 3 Jan 2023 23:08:39 +0100 Subject: [PATCH 218/586] Use extra colors for very high NiGHTS links, plus: - Replaced Mindaro with Goldenrod - Changed Topaz, and fixed inconsistency with its placement - Small tweaks to Kiwi, Seafoam, Noble and Sangria - Changed other NiGHTS link colors a little (& removed old iterations) --- src/deh_tables.c | 4 ++-- src/doomdef.h | 4 ++-- src/info.c | 14 +++++++------- src/st_stuff.c | 38 ++++++++------------------------------ 4 files changed, 19 insertions(+), 41 deletions(-) diff --git a/src/deh_tables.c b/src/deh_tables.c index d174afb12..268a18ad4 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -4649,15 +4649,15 @@ const char *COLOR_ENUMS[] = { "ORANGE", // SKINCOLOR_ORANGE, "PUMPKIN", // SKINCOLOR_PUMPKIN, "RUST", // SKINCOLOR_RUST, - "TOPAZ", // SKINCOLOR_TOPAZ, "GOLD", // SKINCOLOR_GOLD, + "TOPAZ", // SKINCOLOR_TOPAZ, "SANDY", // SKINCOLOR_SANDY, + "GOLDENROD", // SKINCOLOR_GOLDENROD, "YELLOW", // SKINCOLOR_YELLOW, "OLIVE", // SKINCOLOR_OLIVE, "KIWI", // SKINCOLOR_KIWI, "LEMON", // SKINCOLOR_LEMON, "LIME", // SKINCOLOR_LIME, - "MINDARO", // SKINCOLOR_MINDARO, "PERIDOT", // SKINCOLOR_PERIDOT, "APPLE", // SKINCOLOR_APPLE, "CHARTREUSE", // SKINCOLOR_CHARTREUSE, diff --git a/src/doomdef.h b/src/doomdef.h index d19543e23..31cdac9c4 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -301,15 +301,15 @@ typedef enum SKINCOLOR_ORANGE, SKINCOLOR_PUMPKIN, SKINCOLOR_RUST, - SKINCOLOR_TOPAZ, SKINCOLOR_GOLD, + SKINCOLOR_TOPAZ, SKINCOLOR_SANDY, + SKINCOLOR_GOLDENROD, SKINCOLOR_YELLOW, SKINCOLOR_OLIVE, SKINCOLOR_KIWI, SKINCOLOR_LEMON, SKINCOLOR_LIME, - SKINCOLOR_MINDARO, SKINCOLOR_PERIDOT, SKINCOLOR_APPLE, SKINCOLOR_CHARTREUSE, diff --git a/src/info.c b/src/info.c index 2b6d6affb..085966b9c 100644 --- a/src/info.c +++ b/src/info.c @@ -21627,14 +21627,14 @@ skincolor_t skincolors[MAXSKINCOLORS] = { {"Pumpkin", { 51, 52, 53, 54, 56, 58, 59, 59, 61, 61, 63, 45, 46, 47, 47, 31}, SKINCOLOR_ARCTIC, 10, V_ORANGEMAP, true}, // SKINCOLOR_PUMPKIN {"Rust", {0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3c, 0x3d, 0x3d, 0x3d, 0x3f, 0x2c, 0x2d, 0x47, 0x2e, 0x2f, 0x2f}, SKINCOLOR_YOGURT, 8, V_ORANGEMAP, true}, // SKINCOLOR_RUST {"Gold", {0x51, 0x51, 0x54, 0x54, 0x41, 0x42, 0x43, 0x43, 0x44, 0x45, 0x46, 0x3f, 0x2d, 0x2e, 0x2f, 0x2f}, SKINCOLOR_LAVENDER, 10, V_YELLOWMAP, true}, // SKINCOLOR_GOLD - {"Topaz", { 0, 81, 72, 73, 64, 65, 66, 66, 54, 55, 57, 59, 60, 42, 43, 45}, SKINCOLOR_STONE , 10, V_YELLOWMAP, true}, // SKINCOLOR_TOPAZ + {"Topaz", { 0, 81, 83, 73, 74, 74, 65, 52, 53, 54, 56, 58, 60, 42, 43, 45}, SKINCOLOR_STONE , 10, V_YELLOWMAP, true}, // SKINCOLOR_TOPAZ {"Sandy", {0x53, 0x40, 0x41, 0x42, 0x43, 0xe6, 0xe9, 0xe9, 0xea, 0xec, 0xec, 0xc6, 0xc6, 0xc7, 0xc7, 0xfe}, SKINCOLOR_SKY, 8, V_YELLOWMAP, true}, // SKINCOLOR_SANDY + {"Goldenrod", { 0, 80, 81, 81, 83, 73, 73, 64, 65, 66, 67, 68, 69, 62, 44, 45}, SKINCOLOR_MAJESTY, 11, V_YELLOWMAP, true}, // SKINCOLOR_GOLDENROD {"Yellow", {0x52, 0x53, 0x49, 0x49, 0x4a, 0x4a, 0x4b, 0x4b, 0x4b, 0x4c, 0x4d, 0x4d, 0x4e, 0x4e, 0x4f, 0xed}, SKINCOLOR_CORNFLOWER, 8, V_YELLOWMAP, true}, // SKINCOLOR_YELLOW {"Olive", {0x4b, 0x4b, 0x4c, 0x4c, 0x4d, 0x4e, 0xe7, 0xe7, 0xe9, 0xc5, 0xc5, 0xc6, 0xc6, 0xc7, 0xc7, 0xfd}, SKINCOLOR_DUSK, 3, V_YELLOWMAP, true}, // SKINCOLOR_OLIVE - {"Kiwi", { 88, 64, 188, 189, 189, 76, 76, 67, 67, 68, 69, 70, 45, 46, 47, 47}, SKINCOLOR_MARINE, 9, V_PERIDOTMAP, true}, // SKINCOLOR_KIWI + {"Kiwi", { 88, 89, 188, 189, 189, 76, 76, 67, 67, 68, 69, 70, 45, 46, 47, 47}, SKINCOLOR_MARINE, 9, V_PERIDOTMAP, true}, // SKINCOLOR_KIWI {"Lemon", { 0, 80, 81, 83, 73, 73, 74, 74, 76, 76, 191, 191, 79, 79, 110, 111}, SKINCOLOR_FUCHSIA, 6, V_YELLOWMAP, true}, // SKINCOLOR_LEMON {"Lime", {0x50, 0x51, 0x52, 0x53, 0x48, 0xbc, 0xbd, 0xbe, 0xbe, 0xbf, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f}, SKINCOLOR_MAGENTA, 9, V_PERIDOTMAP, true}, // SKINCOLOR_LIME - {"Mindaro", { 0, 80, 81, 82, 83, 64, 188, 189, 189, 190, 115, 116, 117, 118, 119, 111}, SKINCOLOR_MAJESTY, 11, V_PERIDOTMAP, true}, // SKINCOLOR_MINDARO {"Peridot", {0x58, 0x58, 0xbc, 0xbc, 0xbd, 0xbd, 0xbe, 0xbe, 0xbe, 0xbf, 0x5e, 0x5e, 0x5f, 0x5f, 0x77, 0x77}, SKINCOLOR_COBALT, 2, V_PERIDOTMAP, true}, // SKINCOLOR_PERIDOT {"Apple", {0x49, 0x49, 0xbc, 0xbd, 0xbe, 0xbe, 0xbe, 0x67, 0x69, 0x6a, 0x6b, 0x6b, 0x6c, 0x6d, 0x6d, 0x6d}, SKINCOLOR_RASPBERRY, 13, V_PERIDOTMAP, true}, // SKINCOLOR_APPLE {"Chartreuse", { 80, 82, 72, 73, 188, 188, 113, 114, 114, 125, 126, 137, 138, 139, 253, 254}, SKINCOLOR_NOBLE, 12, V_PERIDOTMAP, true}, // SKINCOLOR_CHARTREUSE @@ -21647,7 +21647,7 @@ skincolor_t skincolors[MAXSKINCOLORS] = { {"Master", { 0, 80, 88, 96, 112, 113, 99, 100, 124, 125, 126, 117, 107, 118, 119, 111}, SKINCOLOR_PEPPER, 8, V_GREENMAP, true}, // SKINCOLOR_MASTER {"Emerald", { 80, 96, 112, 113, 114, 114, 125, 125, 126, 126, 137, 137, 138, 138, 139, 139}, SKINCOLOR_RUBY, 7, V_GREENMAP, true}, // SKINCOLOR_EMERALD {"Bottle", { 0, 1, 3, 4, 5, 140, 141, 141, 124, 125, 126, 127, 118, 119, 111, 111}, SKINCOLOR_LATTE, 12, V_AQUAMAP, true}, // SKINCOLOR_BOTTLE - {"Seafoam", {0x01, 0x58, 0x59, 0x5a, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x8f, 0x8f, 0x8a, 0x8a, 0x8a, 0xfd, 0xfd}, SKINCOLOR_PLUM, 6, V_AQUAMAP, true}, // SKINCOLOR_SEAFOAM + {"Seafoam", {0x01, 0x58, 0x59, 0x5a, 0x7c, 0x7d, 0x7d, 0x7e, 0x7e, 0x8f, 0x8f, 0x8a, 0x8a, 0x8b, 0xfd, 0xfd}, SKINCOLOR_PLUM, 6, V_AQUAMAP, true}, // SKINCOLOR_SEAFOAM {"Island", { 96, 97, 113, 113, 114, 124, 142, 136, 136, 150, 151, 153, 168, 168, 169, 169}, SKINCOLOR_GALAXY, 7, V_AQUAMAP, true}, // SKINCOLOR_ISLAND {"Aqua", {0x78, 0x79, 0x7a, 0x7a, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7d, 0x7e, 0x7e, 0x7f, 0x7f, 0x76, 0x77}, SKINCOLOR_ROSY, 7, V_AQUAMAP, true}, // SKINCOLOR_AQUA {"Teal", {0x78, 0x78, 0x8c, 0x8c, 0x8d, 0x8d, 0x8d, 0x8e, 0x8e, 0x8f, 0x8f, 0x8f, 0x8a, 0x8a, 0x8a, 0x8a}, SKINCOLOR_PEACHY, 7, V_SKYMAP, true}, // SKINCOLOR_TEAL @@ -21670,10 +21670,10 @@ skincolor_t skincolors[MAXSKINCOLORS] = { {"Galaxy", { 160, 161, 162, 163, 164, 165, 166, 166, 154, 155, 156, 157, 159, 253, 254, 31}, SKINCOLOR_ISLAND, 7, V_PURPLEMAP, true}, // SKINCOLOR_GALAXY {"Vapor", {0x80, 0x81, 0x83, 0x86, 0x94, 0x94, 0xa3, 0xa3, 0xa4, 0xa6, 0xa6, 0xa6, 0xa8, 0xa8, 0xa9, 0xa9}, SKINCOLOR_LILAC, 4, V_SKYMAP, true}, // SKINCOLOR_VAPOR {"Dusk", {0x92, 0x93, 0x94, 0x94, 0xac, 0xad, 0xad, 0xad, 0xae, 0xae, 0xaf, 0xaf, 0xa9, 0xa9, 0xfd, 0xfd}, SKINCOLOR_OLIVE, 0, V_BLUEMAP, true}, // SKINCOLOR_DUSK - {"Majesty", { 0, 1, 176, 160, 160, 161, 162, 162, 163, 172, 173, 174, 174, 175, 139, 139}, SKINCOLOR_MINDARO, 11, V_PURPLEMAP, true}, // SKINCOLOR_MAJESTY + {"Majesty", { 0, 1, 176, 160, 160, 161, 162, 162, 163, 172, 173, 174, 174, 175, 139, 139}, SKINCOLOR_GOLDENROD, 11, V_PURPLEMAP, true}, // SKINCOLOR_MAJESTY {"Pastel", {0x90, 0x90, 0xa0, 0xa0, 0xa1, 0xa1, 0xa2, 0xa2, 0xa2, 0xa3, 0xa4, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8}, SKINCOLOR_BUBBLEGUM, 9, V_PURPLEMAP, true}, // SKINCOLOR_PASTEL {"Purple", {0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa4, 0xa5, 0xa5, 0xa5, 0xa6, 0xa7, 0xa7, 0xa8, 0xa8, 0xa9, 0xa9}, SKINCOLOR_FLAME, 7, V_PURPLEMAP, true}, // SKINCOLOR_PURPLE - {"Noble", { 144, 146, 147, 148, 148, 164, 164, 165, 165, 185, 186, 186, 187, 187, 28, 29}, SKINCOLOR_CHARTREUSE, 12, V_PURPLEMAP, true}, // SKINCOLOR_NOBLE + {"Noble", { 144, 146, 147, 148, 149, 164, 164, 165, 166, 185, 186, 186, 187, 187, 28, 29}, SKINCOLOR_CHARTREUSE, 12, V_PURPLEMAP, true}, // SKINCOLOR_NOBLE {"Fuchsia", { 200, 201, 203, 204, 204, 183, 184, 184, 165, 166, 167, 168, 169, 159, 253, 254}, SKINCOLOR_LEMON, 6, V_PURPLEMAP, true}, // SKINCOLOR_FUCHSIA {"Bubblegum", { 0, 208, 208, 176, 177, 178, 179, 180, 181, 183, 165, 166, 167, 168, 169, 253}, SKINCOLOR_PASTEL, 8, V_MAGENTAMAP, true}, // SKINCOLOR_BUBBLEGUM {"Crystal", { 252, 177, 179, 180, 181, 181, 182, 182, 183, 164, 166, 167, 167, 168, 169, 159}, SKINCOLOR_EMERALD, 8, V_MAGENTAMAP, true}, // SKINCOLOR_CRYSTAL @@ -21689,7 +21689,7 @@ skincolor_t skincolors[MAXSKINCOLORS] = { {"Taffy", { 1, 176, 176, 177, 178, 179, 202, 203, 204, 204, 205, 206, 207, 44, 45, 46}, SKINCOLOR_JADE, 8, V_ROSYMAP, true}, // SKINCOLOR_TAFFY {"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 {"Fancy", { 0, 208, 49, 210, 210, 202, 202, 203, 204, 204, 205, 206, 207, 207, 186, 186}, SKINCOLOR_ROYAL, 9, V_ROSYMAP, true}, // SKINCOLOR_FANCY - {"Sangria", { 210, 32, 33, 34, 35, 215, 215, 207, 207, 185, 186, 186, 186, 169, 169, 253}, SKINCOLOR_TURQUOISE, 7, V_ROSYMAP, true}, // SKINCOLOR_SANGRIA + {"Sangria", { 210, 32, 33, 34, 34, 215, 215, 207, 207, 185, 186, 186, 186, 169, 169, 253}, SKINCOLOR_TURQUOISE, 7, V_ROSYMAP, true}, // SKINCOLOR_SANGRIA {"Volcanic", { 35, 38, 41, 42, 44, 46, 46, 169, 169, 159, 253, 254, 30, 30, 31, 31}, SKINCOLOR_BRONZE, 9, V_REDMAP, true}, // SKINCOLOR_VOLCANIC // super diff --git a/src/st_stuff.c b/src/st_stuff.c index dcab2bb9c..484216e30 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1751,43 +1751,21 @@ static void ST_drawNightsRecords(void) } } -// 2.0-1: [21:42] <+Rob> Beige - Lavender - Steel Blue - Peach - Orange - Purple - Silver - Yellow - Pink - Red - Blue - Green - Cyan - Gold -/*#define NUMLINKCOLORS 14 -static skincolornum_t linkColor[NUMLINKCOLORS] = -{SKINCOLOR_BEIGE, SKINCOLOR_LAVENDER, SKINCOLOR_AZURE, SKINCOLOR_PEACH, SKINCOLOR_ORANGE, - SKINCOLOR_MAGENTA, SKINCOLOR_SILVER, SKINCOLOR_SUPERGOLD4, SKINCOLOR_PINK, SKINCOLOR_RED, - SKINCOLOR_BLUE, SKINCOLOR_GREEN, SKINCOLOR_CYAN, SKINCOLOR_GOLD};*/ - -// 2.2 indev list: (unix time 1470866042) Emerald, Aqua, Cyan, Blue, Pastel, Purple, Magenta, Rosy, Red, Orange, Gold, Yellow, Peridot -/*#define NUMLINKCOLORS 13 -static skincolornum_t linkColor[NUMLINKCOLORS] = -{SKINCOLOR_EMERALD, SKINCOLOR_AQUA, SKINCOLOR_CYAN, SKINCOLOR_BLUE, SKINCOLOR_PASTEL, - SKINCOLOR_PURPLE, SKINCOLOR_MAGENTA, SKINCOLOR_ROSY, SKINCOLOR_RED, SKINCOLOR_ORANGE, - SKINCOLOR_GOLD, SKINCOLOR_YELLOW, SKINCOLOR_PERIDOT};*/ - -// 2.2 indev list again: [19:59:52] Ruby > Red > Flame > Sunset > Orange > Gold > Yellow > Lime > Green > Aqua > cyan > Sky > Blue > Pastel > Purple > Bubblegum > Magenta > Rosy > repeat -// [20:00:25] Also Icy for the link freeze text color -// [20:04:03] I would start it on lime -/*#define NUMLINKCOLORS 18 -static skincolornum_t linkColor[NUMLINKCOLORS] = -{SKINCOLOR_LIME, SKINCOLOR_EMERALD, SKINCOLOR_AQUA, SKINCOLOR_CYAN, SKINCOLOR_SKY, - SKINCOLOR_SAPPHIRE, SKINCOLOR_PASTEL, SKINCOLOR_PURPLE, SKINCOLOR_BUBBLEGUM, SKINCOLOR_MAGENTA, - SKINCOLOR_ROSY, SKINCOLOR_RUBY, SKINCOLOR_RED, SKINCOLOR_FLAME, SKINCOLOR_SUNSET, - SKINCOLOR_ORANGE, SKINCOLOR_GOLD, SKINCOLOR_YELLOW};*/ - -// 2.2+ list for real this time: https://wiki.srb2.org/wiki/User:Rob/Sandbox (check history around 31/10/17, spoopy) +// NiGHTS link colors; 3 sets with increasingly fancy colors (1 to 299, 300 to 599, 600 and above) #define NUMLINKCOLORS 12 -static skincolornum_t linkColor[2][NUMLINKCOLORS] = { -{SKINCOLOR_EMERALD, SKINCOLOR_AQUA, SKINCOLOR_SKY, SKINCOLOR_BLUE, SKINCOLOR_PURPLE, SKINCOLOR_MAGENTA, +static skincolornum_t linkColor[3][NUMLINKCOLORS] = { +{SKINCOLOR_SHAMROCK, SKINCOLOR_AQUA, SKINCOLOR_SKY, SKINCOLOR_BLUE, SKINCOLOR_PURPLE, SKINCOLOR_MAGENTA, SKINCOLOR_ROSY, SKINCOLOR_RED, SKINCOLOR_ORANGE, SKINCOLOR_GOLD, SKINCOLOR_YELLOW, SKINCOLOR_PERIDOT}, -{SKINCOLOR_SEAFOAM, SKINCOLOR_CYAN, SKINCOLOR_WAVE, SKINCOLOR_SAPPHIRE, SKINCOLOR_VAPOR, SKINCOLOR_BUBBLEGUM, - SKINCOLOR_VIOLET, SKINCOLOR_RUBY, SKINCOLOR_FLAME, SKINCOLOR_SUNSET, SKINCOLOR_SANDY, SKINCOLOR_LIME}}; +{SKINCOLOR_EMERALD, SKINCOLOR_AQUAMARINE, SKINCOLOR_WAVE, SKINCOLOR_SAPPHIRE, SKINCOLOR_GALAXY, SKINCOLOR_CRYSTAL, + SKINCOLOR_TAFFY, SKINCOLOR_RUBY, SKINCOLOR_GARNET, SKINCOLOR_TOPAZ, SKINCOLOR_LEMON, SKINCOLOR_LIME}, +{SKINCOLOR_ISLAND, SKINCOLOR_TURQUOISE, SKINCOLOR_DREAM, SKINCOLOR_DAYBREAK, SKINCOLOR_VAPOR, SKINCOLOR_FUCHSIA, + SKINCOLOR_VIOLET, SKINCOLOR_EVENTIDE, SKINCOLOR_KETCHUP, SKINCOLOR_FOUNDATION, SKINCOLOR_HEADLIGHT, SKINCOLOR_CHARTREUSE}}; static void ST_drawNiGHTSLink(void) { static INT32 prevsel[2] = {0, 0}, prevtime[2] = {0, 0}; const UINT8 q = ((splitscreen && stplyr == &players[secondarydisplayplayer]) ? 1 : 0); - INT32 sel = ((stplyr->linkcount-1) / 5) % NUMLINKCOLORS, aflag = V_PERPLAYER, mag = ((stplyr->linkcount-1 >= 300) ? 1 : 0); + INT32 sel = ((stplyr->linkcount-1) / 5) % NUMLINKCOLORS, aflag = V_PERPLAYER, mag = ((stplyr->linkcount-1 >= 300) ? (stplyr->linkcount-1 >= 600) ? 2 : 1 : 0); skincolornum_t colornum; fixed_t x, y, scale; From 73eb8fc358bc0d474b28369d5d48b7953e1111d5 Mon Sep 17 00:00:00 2001 From: spherallic Date: Mon, 13 Mar 2023 19:52:41 +0100 Subject: [PATCH 219/586] A couple more changes: - Swapped invcolors of new character skincolors - Renamed Stone to Meteorite & changed text color to gray - Tweaked some colors' invshades --- src/deh_tables.c | 2 +- src/doomdef.h | 2 +- src/info.c | 92 ++++++++++++++++++++++++------------------------ 3 files changed, 48 insertions(+), 48 deletions(-) diff --git a/src/deh_tables.c b/src/deh_tables.c index 268a18ad4..d53680c19 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -4609,7 +4609,7 @@ const char *COLOR_ENUMS[] = { // Desaturated "AETHER", // SKINCOLOR_AETHER, "SLATE", // SKINCOLOR_SLATE, - "STONE", // SKINCOLOR_STONE, + "METEORITE", // SKINCOLOR_METEORITE, "MERCURY", // SKINCOLOR_MERCURY, "BLUEBELL", // SKINCOLOR_BLUEBELL, "PINK", // SKINCOLOR_PINK, diff --git a/src/doomdef.h b/src/doomdef.h index 31cdac9c4..20b87f230 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -261,7 +261,7 @@ typedef enum // Desaturated SKINCOLOR_AETHER, SKINCOLOR_SLATE, - SKINCOLOR_STONE, + SKINCOLOR_METEORITE, SKINCOLOR_MERCURY, SKINCOLOR_BLUEBELL, SKINCOLOR_PINK, diff --git a/src/info.c b/src/info.c index 085966b9c..5a304240d 100644 --- a/src/info.c +++ b/src/info.c @@ -21584,76 +21584,76 @@ skincolor_t skincolors[MAXSKINCOLORS] = { {"Black", {0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1b, 0x1b, 0x1c, 0x1d, 0x1d, 0x1e, 0x1e, 0x1f, 0x1f}, SKINCOLOR_WHITE, 7, V_GRAYMAP, true}, // SKINCOLOR_BLACK // Desaturated - {"Aether", {0x00, 0x00, 0x01, 0x02, 0x02, 0x03, 0x91, 0x91, 0x91, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xaf}, SKINCOLOR_GREY, 15, 0, true}, // SKINCOLOR_AETHER - {"Slate", {0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0xaa, 0xaa, 0xaa, 0xab, 0xac, 0xac, 0xad, 0xad, 0xae, 0xaf}, SKINCOLOR_SILVER, 12, 0, true}, // SKINCOLOR_SLATE - {"Stone", { 0, 4, 8, 9, 11, 12, 14, 15, 171, 172, 173, 174, 175, 27, 29, 31}, SKINCOLOR_TOPAZ, 15, 0, true}, // SKINCOLOR_STONE - {"Mercury", { 0, 3, 4, 7, 11, 12, 14, 15, 171, 172, 173, 155, 157, 159, 253, 254}, SKINCOLOR_ECRU, 15, V_AZUREMAP, true}, // SKINCOLOR_MERCURY - {"Bluebell", {0x90, 0x91, 0x92, 0x93, 0x94, 0x94, 0x95, 0xac, 0xac, 0xad, 0xad, 0xa8, 0xa8, 0xa9, 0xfd, 0xfe}, SKINCOLOR_COPPER, 4, V_BLUEMAP, true}, // SKINCOLOR_BLUEBELL - {"Pink", {0xd0, 0xd0, 0xd1, 0xd1, 0xd2, 0xd2, 0xd3, 0xd3, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0x2b, 0x2c, 0x2e}, SKINCOLOR_AZURE, 9, V_REDMAP, true}, // SKINCOLOR_PINK - {"Rosewood", { 209, 210, 211, 212, 213, 214, 228, 230, 232, 234, 235, 237, 26, 27, 28, 29}, SKINCOLOR_SEPIA, 5, V_BROWNMAP, true}, // SKINCOLOR_ROSEWOOD - {"Yogurt", {0xd0, 0x30, 0xd8, 0xd9, 0xda, 0xdb, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe3, 0xe6, 0xe8, 0xe9}, SKINCOLOR_RUST, 7, V_BROWNMAP, true}, // SKINCOLOR_YOGURT - {"Latte", { 48, 217, 219, 221, 223, 224, 226, 228, 68, 69, 70, 70, 44, 45, 46, 47}, SKINCOLOR_BOTTLE, 12, V_BROWNMAP, true}, // SKINCOLOR_LATTE - {"Brown", {0xdf, 0xe0, 0xe1, 0xe2, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef}, SKINCOLOR_TAN, 2, V_BROWNMAP, true}, // SKINCOLOR_BROWN - {"Boulder", {0xde, 0xe0, 0xe1, 0xe4, 0xe7, 0xe9, 0xeb, 0xec, 0xed, 0xed, 0xed, 0x19, 0x19, 0x1b, 0x1d, 0x1e}, SKINCOLOR_KETCHUP, 0, V_BROWNMAP, true}, // SKINCOLOR_BOULDER - {"Bronze", { 82, 84, 50, 51, 223, 228, 230, 232, 234, 236, 237, 238, 239, 239, 30, 31}, SKINCOLOR_VOLCANIC, 9, V_BROWNMAP, true}, // SKINCOLOR_BRONZE - {"Sepia", { 88, 84, 85, 86, 224, 226, 228, 230, 232, 235, 236, 237, 238, 239, 28, 28}, SKINCOLOR_ROSEWOOD, 5, V_BROWNMAP, true}, // SKINCOLOR_SEPIA - {"Ecru", { 80, 83, 84, 85, 86, 242, 243, 245, 230, 232, 234, 236, 238, 239, 47, 47}, SKINCOLOR_MERCURY, 15, V_BROWNMAP, true}, // SKINCOLOR_ECRU - {"Tan", {0x51, 0x51, 0x54, 0x54, 0x55, 0x55, 0x56, 0x56, 0x56, 0x57, 0xf5, 0xf5, 0xf9, 0xf9, 0xed, 0xed}, SKINCOLOR_BROWN, 12, V_BROWNMAP, true}, // SKINCOLOR_TAN - {"Beige", {0x54, 0x55, 0x56, 0x56, 0xf2, 0xf3, 0xf3, 0xf4, 0xf5, 0xf6, 0xf8, 0xf9, 0xfa, 0xfb, 0xed, 0xed}, SKINCOLOR_MOSS, 5, V_BROWNMAP, true}, // SKINCOLOR_BEIGE - {"Rosebush", { 208, 216, 209, 85, 90, 91, 91, 92, 191, 93, 94, 107, 109, 110, 111, 111}, SKINCOLOR_EGGPLANT, 5, V_GREENMAP, true}, // SKINCOLOR_ROSEBUSH - {"Moss", {0x58, 0x58, 0x59, 0x59, 0x5a, 0x5a, 0x5b, 0x5b, 0x5b, 0x5c, 0x5d, 0x5d, 0x5e, 0x5e, 0x5f, 0x5f}, SKINCOLOR_BEIGE, 13, V_GREENMAP, true}, // SKINCOLOR_MOSS - {"Azure", {0x90, 0x90, 0x91, 0x91, 0xaa, 0xaa, 0xab, 0xab, 0xab, 0xac, 0xad, 0xad, 0xae, 0xae, 0xaf, 0xaf}, SKINCOLOR_PINK, 5, V_AZUREMAP, true}, // SKINCOLOR_AZURE - {"Eggplant", { 4, 8, 11, 11, 16, 195, 195, 195, 196, 186, 187, 187, 254, 254, 30, 31}, SKINCOLOR_ROSEBUSH, 5, V_PURPLEMAP, true}, // SKINCOLOR_EGGPLANT - {"Lavender", {0xc0, 0xc0, 0xc1, 0xc1, 0xc2, 0xc2, 0xc3, 0xc3, 0xc3, 0xc4, 0xc5, 0xc5, 0xc6, 0xc6, 0xc7, 0xc7}, SKINCOLOR_GOLD, 4, V_PURPLEMAP, true}, // SKINCOLOR_LAVENDER + {"Aether", {0x00, 0x00, 0x01, 0x02, 0x02, 0x03, 0x91, 0x91, 0x91, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xaf}, SKINCOLOR_GREY, 15, 0, true}, // SKINCOLOR_AETHER + {"Slate", {0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0xaa, 0xaa, 0xaa, 0xab, 0xac, 0xac, 0xad, 0xad, 0xae, 0xaf}, SKINCOLOR_SILVER, 12, 0, true}, // SKINCOLOR_SLATE + {"Meteorite", { 0, 4, 8, 9, 11, 12, 14, 15, 171, 172, 173, 174, 175, 27, 29, 31}, SKINCOLOR_TOPAZ, 15, V_GRAYMAP, true}, // SKINCOLOR_METEORITE + {"Mercury", { 0, 3, 4, 7, 11, 12, 14, 15, 171, 172, 173, 155, 157, 159, 253, 254}, SKINCOLOR_ECRU, 15, V_AZUREMAP, true}, // SKINCOLOR_MERCURY + {"Bluebell", {0x90, 0x91, 0x92, 0x93, 0x94, 0x94, 0x95, 0xac, 0xac, 0xad, 0xad, 0xa8, 0xa8, 0xa9, 0xfd, 0xfe}, SKINCOLOR_COPPER, 4, V_BLUEMAP, true}, // SKINCOLOR_BLUEBELL + {"Pink", {0xd0, 0xd0, 0xd1, 0xd1, 0xd2, 0xd2, 0xd3, 0xd3, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0x2b, 0x2c, 0x2e}, SKINCOLOR_AZURE, 9, V_REDMAP, true}, // SKINCOLOR_PINK + {"Rosewood", { 209, 210, 211, 212, 213, 214, 228, 230, 232, 234, 235, 237, 26, 27, 28, 29}, SKINCOLOR_SEPIA, 5, V_BROWNMAP, true}, // SKINCOLOR_ROSEWOOD + {"Yogurt", {0xd0, 0x30, 0xd8, 0xd9, 0xda, 0xdb, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe3, 0xe6, 0xe8, 0xe9}, SKINCOLOR_RUST, 7, V_BROWNMAP, true}, // SKINCOLOR_YOGURT + {"Latte", { 48, 217, 219, 221, 223, 224, 226, 228, 68, 69, 70, 70, 44, 45, 46, 47}, SKINCOLOR_BOTTLE, 12, V_BROWNMAP, true}, // SKINCOLOR_LATTE + {"Brown", {0xdf, 0xe0, 0xe1, 0xe2, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef}, SKINCOLOR_TAN, 2, V_BROWNMAP, true}, // SKINCOLOR_BROWN + {"Boulder", {0xde, 0xe0, 0xe1, 0xe4, 0xe7, 0xe9, 0xeb, 0xec, 0xed, 0xed, 0xed, 0x19, 0x19, 0x1b, 0x1d, 0x1e}, SKINCOLOR_KETCHUP, 0, V_BROWNMAP, true}, // SKINCOLOR_BOULDER + {"Bronze", { 82, 84, 50, 51, 223, 228, 230, 232, 234, 236, 237, 238, 239, 239, 30, 31}, SKINCOLOR_VOLCANIC, 9, V_BROWNMAP, true}, // SKINCOLOR_BRONZE + {"Sepia", { 88, 84, 85, 86, 224, 226, 228, 230, 232, 235, 236, 237, 238, 239, 28, 28}, SKINCOLOR_ROSEWOOD, 5, V_BROWNMAP, true}, // SKINCOLOR_SEPIA + {"Ecru", { 80, 83, 84, 85, 86, 242, 243, 245, 230, 232, 234, 236, 238, 239, 47, 47}, SKINCOLOR_MERCURY, 15, V_BROWNMAP, true}, // SKINCOLOR_ECRU + {"Tan", {0x51, 0x51, 0x54, 0x54, 0x55, 0x55, 0x56, 0x56, 0x56, 0x57, 0xf5, 0xf5, 0xf9, 0xf9, 0xed, 0xed}, SKINCOLOR_BROWN, 12, V_BROWNMAP, true}, // SKINCOLOR_TAN + {"Beige", {0x54, 0x55, 0x56, 0x56, 0xf2, 0xf3, 0xf3, 0xf4, 0xf5, 0xf6, 0xf8, 0xf9, 0xfa, 0xfb, 0xed, 0xed}, SKINCOLOR_MOSS, 5, V_BROWNMAP, true}, // SKINCOLOR_BEIGE + {"Rosebush", { 208, 216, 209, 85, 90, 91, 91, 92, 191, 93, 94, 107, 109, 110, 111, 111}, SKINCOLOR_EGGPLANT, 5, V_GREENMAP, true}, // SKINCOLOR_ROSEBUSH + {"Moss", {0x58, 0x58, 0x59, 0x59, 0x5a, 0x5a, 0x5b, 0x5b, 0x5b, 0x5c, 0x5d, 0x5d, 0x5e, 0x5e, 0x5f, 0x5f}, SKINCOLOR_BEIGE, 13, V_GREENMAP, true}, // SKINCOLOR_MOSS + {"Azure", {0x90, 0x90, 0x91, 0x91, 0xaa, 0xaa, 0xab, 0xab, 0xab, 0xac, 0xad, 0xad, 0xae, 0xae, 0xaf, 0xaf}, SKINCOLOR_PINK, 5, V_AZUREMAP, true}, // SKINCOLOR_AZURE + {"Eggplant", { 4, 8, 11, 11, 16, 195, 195, 195, 196, 186, 187, 187, 254, 254, 30, 31}, SKINCOLOR_ROSEBUSH, 5, V_PURPLEMAP, true}, // SKINCOLOR_EGGPLANT + {"Lavender", {0xc0, 0xc0, 0xc1, 0xc1, 0xc2, 0xc2, 0xc3, 0xc3, 0xc3, 0xc4, 0xc5, 0xc5, 0xc6, 0xc6, 0xc7, 0xc7}, SKINCOLOR_HEADLIGHT, 8, V_PURPLEMAP, true}, // SKINCOLOR_LAVENDER // Viv's vivid colours (toast 21/07/17) // Tweaks & additions (Lach, sphere, Alice, MotorRoach 26/10/22) {"Ruby", {0xb0, 0xb0, 0xc9, 0xca, 0xcc, 0x26, 0x27, 0x28, 0x29, 0x2a, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xfd}, SKINCOLOR_EMERALD, 10, V_REDMAP, true}, // SKINCOLOR_RUBY {"Cherry", { 202, 203, 204, 205, 206, 40, 41, 42, 43, 44, 186, 187, 28, 29, 30, 31}, SKINCOLOR_MIDNIGHT, 10, V_REDMAP, true}, // SKINCOLOR_CHERRY {"Salmon", {0xd0, 0xd0, 0xd1, 0xd2, 0x20, 0x21, 0x24, 0x25, 0x26, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e}, SKINCOLOR_FOREST, 6, V_REDMAP, true}, // SKINCOLOR_SALMON - {"Pepper", { 210, 32, 33, 34, 35, 35, 36, 37, 38, 39, 41, 43, 45, 45, 46, 47}, SKINCOLOR_MASTER, 8, V_REDMAP, true}, // SKINCOLOR_PEPPER - {"Red", {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x47, 0x2e, 0x2f}, SKINCOLOR_GREEN, 10, V_REDMAP, true}, // SKINCOLOR_RED + {"Pepper", { 210, 32, 33, 34, 35, 35, 36, 37, 38, 39, 41, 43, 45, 45, 46, 47}, SKINCOLOR_GREEN, 10, V_REDMAP, true}, // SKINCOLOR_PEPPER + {"Red", {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x47, 0x2e, 0x2f}, SKINCOLOR_MASTER, 8, V_REDMAP, true}, // SKINCOLOR_RED {"Crimson", {0x27, 0x27, 0x28, 0x28, 0x29, 0x2a, 0x2b, 0x2b, 0x2c, 0x2d, 0x2e, 0x2e, 0x2e, 0x2f, 0x2f, 0x1f}, SKINCOLOR_ICY, 10, V_REDMAP, true}, // SKINCOLOR_CRIMSON {"Flame", {0x31, 0x32, 0x33, 0x36, 0x22, 0x22, 0x25, 0x25, 0x25, 0xcd, 0xcf, 0xcf, 0xc5, 0xc5, 0xc7, 0xc7}, SKINCOLOR_PURPLE, 8, V_REDMAP, true}, // SKINCOLOR_FLAME - {"Garnet", { 0, 83, 50, 53, 34, 35, 37, 38, 39, 40, 42, 44, 45, 46, 47, 47}, SKINCOLOR_AQUAMARINE, 8, V_REDMAP, true}, // SKINCOLOR_GARNET + {"Garnet", { 0, 83, 50, 53, 34, 35, 37, 38, 39, 40, 42, 44, 45, 46, 47, 47}, SKINCOLOR_AQUAMARINE, 6, V_REDMAP, true}, // SKINCOLOR_GARNET {"Ketchup", {0x48, 0x49, 0x40, 0x33, 0x34, 0x36, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2b, 0x2c, 0x47, 0x2e, 0x2f}, SKINCOLOR_BOULDER, 8, V_REDMAP, true}, // SKINCOLOR_KETCHUP {"Peachy", {0xd0, 0x30, 0x31, 0x31, 0x32, 0x32, 0xdc, 0xdc, 0xdc, 0xd3, 0xd4, 0xd4, 0xcc, 0xcd, 0xce, 0xcf}, SKINCOLOR_TEAL, 7, V_ROSYMAP, true}, // SKINCOLOR_PEACHY {"Quail", {0xd8, 0xd9, 0xdb, 0xdc, 0xde, 0xdf, 0xd5, 0xd5, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0x1d, 0x1f}, SKINCOLOR_WAVE, 5, V_BROWNMAP, true}, // SKINCOLOR_QUAIL - {"Foundation", { 80, 81, 82, 84, 219, 221, 221, 212, 213, 214, 215, 195, 196, 186, 187, 30}, SKINCOLOR_DREAM, 9, V_ORANGEMAP, true}, // SKINCOLOR_FOUNDATION + {"Foundation", { 80, 81, 82, 84, 219, 221, 221, 212, 213, 214, 215, 195, 196, 186, 187, 30}, SKINCOLOR_DREAM, 6, V_ORANGEMAP, true}, // SKINCOLOR_FOUNDATION {"Sunset", {0x51, 0x52, 0x40, 0x40, 0x34, 0x36, 0xd5, 0xd5, 0xd6, 0xd7, 0xcf, 0xcf, 0xc6, 0xc6, 0xc7, 0xfe}, SKINCOLOR_SAPPHIRE, 5, V_ORANGEMAP, true}, // SKINCOLOR_SUNSET {"Copper", {0x58, 0x54, 0x40, 0x34, 0x35, 0x38, 0x3a, 0x3c, 0x3d, 0x2a, 0x2b, 0x2c, 0x2c, 0xba, 0xba, 0xbb}, SKINCOLOR_BLUEBELL, 5, V_ORANGEMAP, true}, // SKINCOLOR_COPPER {"Apricot", {0x00, 0xd8, 0xd9, 0xda, 0xdb, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e}, SKINCOLOR_CYAN, 4, V_ORANGEMAP, true}, // SKINCOLOR_APRICOT {"Orange", { 49, 50, 51, 52, 53, 54, 55, 57, 58, 59, 60, 42, 44, 45, 46, 46}, SKINCOLOR_BLUE, 4, V_ORANGEMAP, true}, // SKINCOLOR_ORANGE - {"Pumpkin", { 51, 52, 53, 54, 56, 58, 59, 59, 61, 61, 63, 45, 46, 47, 47, 31}, SKINCOLOR_ARCTIC, 10, V_ORANGEMAP, true}, // SKINCOLOR_PUMPKIN + {"Pumpkin", { 51, 52, 53, 54, 56, 58, 59, 59, 61, 61, 63, 45, 46, 47, 47, 31}, SKINCOLOR_ARCTIC, 12, V_ORANGEMAP, true}, // SKINCOLOR_PUMPKIN {"Rust", {0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3c, 0x3d, 0x3d, 0x3d, 0x3f, 0x2c, 0x2d, 0x47, 0x2e, 0x2f, 0x2f}, SKINCOLOR_YOGURT, 8, V_ORANGEMAP, true}, // SKINCOLOR_RUST - {"Gold", {0x51, 0x51, 0x54, 0x54, 0x41, 0x42, 0x43, 0x43, 0x44, 0x45, 0x46, 0x3f, 0x2d, 0x2e, 0x2f, 0x2f}, SKINCOLOR_LAVENDER, 10, V_YELLOWMAP, true}, // SKINCOLOR_GOLD - {"Topaz", { 0, 81, 83, 73, 74, 74, 65, 52, 53, 54, 56, 58, 60, 42, 43, 45}, SKINCOLOR_STONE , 10, V_YELLOWMAP, true}, // SKINCOLOR_TOPAZ + {"Gold", {0x51, 0x51, 0x54, 0x54, 0x41, 0x42, 0x43, 0x43, 0x44, 0x45, 0x46, 0x3f, 0x2d, 0x2e, 0x2f, 0x2f}, SKINCOLOR_MAUVE, 8, V_YELLOWMAP, true}, // SKINCOLOR_GOLD + {"Topaz", { 0, 81, 83, 73, 74, 74, 65, 52, 53, 54, 56, 58, 60, 42, 43, 45}, SKINCOLOR_METEORITE, 10, V_YELLOWMAP, true}, // SKINCOLOR_TOPAZ {"Sandy", {0x53, 0x40, 0x41, 0x42, 0x43, 0xe6, 0xe9, 0xe9, 0xea, 0xec, 0xec, 0xc6, 0xc6, 0xc7, 0xc7, 0xfe}, SKINCOLOR_SKY, 8, V_YELLOWMAP, true}, // SKINCOLOR_SANDY - {"Goldenrod", { 0, 80, 81, 81, 83, 73, 73, 64, 65, 66, 67, 68, 69, 62, 44, 45}, SKINCOLOR_MAJESTY, 11, V_YELLOWMAP, true}, // SKINCOLOR_GOLDENROD + {"Goldenrod", { 0, 80, 81, 81, 83, 73, 73, 64, 65, 66, 67, 68, 69, 62, 44, 45}, SKINCOLOR_MAJESTY, 8, V_YELLOWMAP, true}, // SKINCOLOR_GOLDENROD {"Yellow", {0x52, 0x53, 0x49, 0x49, 0x4a, 0x4a, 0x4b, 0x4b, 0x4b, 0x4c, 0x4d, 0x4d, 0x4e, 0x4e, 0x4f, 0xed}, SKINCOLOR_CORNFLOWER, 8, V_YELLOWMAP, true}, // SKINCOLOR_YELLOW {"Olive", {0x4b, 0x4b, 0x4c, 0x4c, 0x4d, 0x4e, 0xe7, 0xe7, 0xe9, 0xc5, 0xc5, 0xc6, 0xc6, 0xc7, 0xc7, 0xfd}, SKINCOLOR_DUSK, 3, V_YELLOWMAP, true}, // SKINCOLOR_OLIVE {"Kiwi", { 88, 89, 188, 189, 189, 76, 76, 67, 67, 68, 69, 70, 45, 46, 47, 47}, SKINCOLOR_MARINE, 9, V_PERIDOTMAP, true}, // SKINCOLOR_KIWI - {"Lemon", { 0, 80, 81, 83, 73, 73, 74, 74, 76, 76, 191, 191, 79, 79, 110, 111}, SKINCOLOR_FUCHSIA, 6, V_YELLOWMAP, true}, // SKINCOLOR_LEMON + {"Lemon", { 0, 80, 81, 83, 73, 73, 74, 74, 76, 76, 191, 191, 79, 79, 110, 111}, SKINCOLOR_FUCHSIA, 8, V_YELLOWMAP, true}, // SKINCOLOR_LEMON {"Lime", {0x50, 0x51, 0x52, 0x53, 0x48, 0xbc, 0xbd, 0xbe, 0xbe, 0xbf, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f}, SKINCOLOR_MAGENTA, 9, V_PERIDOTMAP, true}, // SKINCOLOR_LIME {"Peridot", {0x58, 0x58, 0xbc, 0xbc, 0xbd, 0xbd, 0xbe, 0xbe, 0xbe, 0xbf, 0x5e, 0x5e, 0x5f, 0x5f, 0x77, 0x77}, SKINCOLOR_COBALT, 2, V_PERIDOTMAP, true}, // SKINCOLOR_PERIDOT {"Apple", {0x49, 0x49, 0xbc, 0xbd, 0xbe, 0xbe, 0xbe, 0x67, 0x69, 0x6a, 0x6b, 0x6b, 0x6c, 0x6d, 0x6d, 0x6d}, SKINCOLOR_RASPBERRY, 13, V_PERIDOTMAP, true}, // SKINCOLOR_APPLE - {"Chartreuse", { 80, 82, 72, 73, 188, 188, 113, 114, 114, 125, 126, 137, 138, 139, 253, 254}, SKINCOLOR_NOBLE, 12, V_PERIDOTMAP, true}, // SKINCOLOR_CHARTREUSE - {"Green", {0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f}, SKINCOLOR_RED, 6, V_GREENMAP, true}, // SKINCOLOR_GREEN + {"Chartreuse", { 80, 82, 72, 73, 188, 188, 113, 114, 114, 125, 126, 137, 138, 139, 253, 254}, SKINCOLOR_NOBLE, 9, V_PERIDOTMAP, true}, // SKINCOLOR_CHARTREUSE + {"Green", {0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f}, SKINCOLOR_PEPPER, 8, V_GREENMAP, true}, // SKINCOLOR_GREEN {"Forest", {0x65, 0x66, 0x67, 0x68, 0x69, 0x69, 0x6a, 0x6b, 0x6b, 0x6c, 0x6d, 0x6d, 0x6e, 0x6e, 0x6e, 0x6f}, SKINCOLOR_SALMON, 9, V_GREENMAP, true}, // SKINCOLOR_FOREST {"Shamrock", {0x70, 0x70, 0x71, 0x71, 0x72, 0x72, 0x73, 0x73, 0x73, 0x74, 0x75, 0x75, 0x76, 0x76, 0x77, 0x77}, SKINCOLOR_CRYSTAL, 10, V_GREENMAP, true}, // SKINCOLOR_SHAMROCK - {"Jade", { 128, 120, 121, 122, 122, 113, 114, 114, 115, 116, 117, 118, 119, 110, 111, 30}, SKINCOLOR_TAFFY, 10, V_GREENMAP, true}, // SKINCOLOR_JADE - {"Headlight", { 0, 80, 81, 82, 73, 84, 64, 65, 91, 91, 124, 125, 126, 137, 138, 139}, SKINCOLOR_MAUVE, 8, V_YELLOWMAP, true}, // SKINCOLOR_HEADLIGHT + {"Jade", { 128, 120, 121, 122, 122, 113, 114, 114, 115, 116, 117, 118, 119, 110, 111, 30}, SKINCOLOR_ROSY, 7, V_GREENMAP, true}, // SKINCOLOR_JADE + {"Headlight", { 0, 80, 81, 82, 73, 84, 64, 65, 91, 91, 124, 125, 126, 137, 138, 139}, SKINCOLOR_LAVENDER, 10, V_YELLOWMAP, true}, // SKINCOLOR_HEADLIGHT {"Mint", {0x00, 0x00, 0x58, 0x58, 0x59, 0x62, 0x62, 0x62, 0x64, 0x67, 0x7e, 0x7e, 0x8f, 0x8f, 0x8a, 0x8a}, SKINCOLOR_VIOLET, 5, V_GREENMAP, true}, // SKINCOLOR_MINT - {"Master", { 0, 80, 88, 96, 112, 113, 99, 100, 124, 125, 126, 117, 107, 118, 119, 111}, SKINCOLOR_PEPPER, 8, V_GREENMAP, true}, // SKINCOLOR_MASTER - {"Emerald", { 80, 96, 112, 113, 114, 114, 125, 125, 126, 126, 137, 137, 138, 138, 139, 139}, SKINCOLOR_RUBY, 7, V_GREENMAP, true}, // SKINCOLOR_EMERALD - {"Bottle", { 0, 1, 3, 4, 5, 140, 141, 141, 124, 125, 126, 127, 118, 119, 111, 111}, SKINCOLOR_LATTE, 12, V_AQUAMAP, true}, // SKINCOLOR_BOTTLE + {"Master", { 0, 80, 88, 96, 112, 113, 99, 100, 124, 125, 126, 117, 107, 118, 119, 111}, SKINCOLOR_RED, 6, V_GREENMAP, true}, // SKINCOLOR_MASTER + {"Emerald", { 80, 96, 112, 113, 114, 114, 125, 125, 126, 126, 137, 137, 138, 138, 139, 139}, SKINCOLOR_RUBY, 9, V_GREENMAP, true}, // SKINCOLOR_EMERALD + {"Bottle", { 0, 1, 3, 4, 5, 140, 141, 141, 124, 125, 126, 127, 118, 119, 111, 111}, SKINCOLOR_LATTE, 14, V_AQUAMAP, true}, // SKINCOLOR_BOTTLE {"Seafoam", {0x01, 0x58, 0x59, 0x5a, 0x7c, 0x7d, 0x7d, 0x7e, 0x7e, 0x8f, 0x8f, 0x8a, 0x8a, 0x8b, 0xfd, 0xfd}, SKINCOLOR_PLUM, 6, V_AQUAMAP, true}, // SKINCOLOR_SEAFOAM {"Island", { 96, 97, 113, 113, 114, 124, 142, 136, 136, 150, 151, 153, 168, 168, 169, 169}, SKINCOLOR_GALAXY, 7, V_AQUAMAP, true}, // SKINCOLOR_ISLAND - {"Aqua", {0x78, 0x79, 0x7a, 0x7a, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7d, 0x7e, 0x7e, 0x7f, 0x7f, 0x76, 0x77}, SKINCOLOR_ROSY, 7, V_AQUAMAP, true}, // SKINCOLOR_AQUA + {"Aqua", {0x78, 0x79, 0x7a, 0x7a, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7d, 0x7e, 0x7e, 0x7f, 0x7f, 0x76, 0x77}, SKINCOLOR_TAFFY, 10, V_AQUAMAP, true}, // SKINCOLOR_AQUA {"Teal", {0x78, 0x78, 0x8c, 0x8c, 0x8d, 0x8d, 0x8d, 0x8e, 0x8e, 0x8f, 0x8f, 0x8f, 0x8a, 0x8a, 0x8a, 0x8a}, SKINCOLOR_PEACHY, 7, V_SKYMAP, true}, // SKINCOLOR_TEAL {"Wave", {0x00, 0x78, 0x78, 0x79, 0x8d, 0x87, 0x88, 0x89, 0x89, 0xae, 0xa8, 0xa8, 0xa9, 0xa9, 0xfd, 0xfd}, SKINCOLOR_QUAIL, 5, V_SKYMAP, true}, // SKINCOLOR_WAVE {"Cyan", {0x80, 0x81, 0xff, 0xff, 0x83, 0x83, 0x8d, 0x8d, 0x8d, 0x8e, 0x7e, 0x7f, 0x76, 0x76, 0x77, 0x6e}, SKINCOLOR_APRICOT, 6, V_SKYMAP, true}, // SKINCOLOR_CYAN - {"Turquoise", { 0, 120, 121, 122, 123, 141, 141, 135, 136, 136, 150, 153, 155, 157, 159, 253}, SKINCOLOR_SANGRIA, 7, V_SKYMAP, true}, // SKINCOLOR_TURQUOISE + {"Turquoise", { 0, 120, 121, 122, 123, 141, 141, 135, 136, 136, 150, 153, 155, 157, 159, 253}, SKINCOLOR_SANGRIA, 12, V_SKYMAP, true}, // SKINCOLOR_TURQUOISE {"Aquamarine", { 0, 120, 121, 131, 132, 133, 134, 134, 135, 135, 149, 149, 172, 173, 174, 175}, SKINCOLOR_GARNET, 8, V_SKYMAP, true}, // SKINCOLOR_AQUAMARINE {"Sky", {0x80, 0x80, 0x81, 0x82, 0x83, 0x83, 0x84, 0x85, 0x85, 0x86, 0x87, 0x88, 0x89, 0x89, 0x8a, 0x8b}, SKINCOLOR_SANDY, 1, V_SKYMAP, true}, // SKINCOLOR_SKY {"Marine", { 144, 146, 147, 147, 148, 135, 136, 136, 137, 137, 127, 118, 119, 111, 111, 111}, SKINCOLOR_KIWI, 13, V_SKYMAP, true}, // SKINCOLOR_MARINE @@ -21662,7 +21662,7 @@ skincolor_t skincolors[MAXSKINCOLORS] = { {"Icy", {0x00, 0x00, 0x00, 0x00, 0x80, 0x81, 0x83, 0x83, 0x86, 0x87, 0x95, 0x95, 0xad, 0xad, 0xae, 0xaf}, SKINCOLOR_CRIMSON, 0, V_SKYMAP, true}, // SKINCOLOR_ICY {"Daybreak", { 80, 81, 82, 72, 64, 9, 11, 171, 149, 150, 151, 153, 156, 157, 159, 253}, SKINCOLOR_EVENTIDE, 12, V_BLUEMAP, true}, // SKINCOLOR_DAYBREAK {"Sapphire", {0x80, 0x82, 0x86, 0x87, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xfd, 0xfe}, SKINCOLOR_SUNSET, 5, V_SKYMAP, true}, // SKINCOLOR_SAPPHIRE - {"Arctic", { 0, 1, 3, 4, 146, 146, 147, 148, 148, 149, 150, 153, 156, 159, 253, 254}, SKINCOLOR_PUMPKIN, 10, V_BLUEMAP, true}, // SKINCOLOR_ARCTIC + {"Arctic", { 0, 1, 3, 4, 146, 146, 147, 148, 148, 149, 150, 153, 156, 159, 253, 254}, SKINCOLOR_PUMPKIN, 6, V_BLUEMAP, true}, // SKINCOLOR_ARCTIC {"Cornflower", {0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x9a, 0x9c, 0x9d, 0x9d, 0x9e, 0x9e, 0x9e}, SKINCOLOR_YELLOW, 4, V_BLUEMAP, true}, // SKINCOLOR_CORNFLOWER {"Blue", {0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xfd, 0xfe}, SKINCOLOR_ORANGE, 5, V_BLUEMAP, true}, // SKINCOLOR_BLUE {"Cobalt", { 145, 147, 149, 150, 151, 153, 154, 155, 156, 157, 158, 159, 253, 253, 254, 254}, SKINCOLOR_PERIDOT, 5, V_BLUEMAP, true}, // SKINCOLOR_COBALT @@ -21670,11 +21670,11 @@ skincolor_t skincolors[MAXSKINCOLORS] = { {"Galaxy", { 160, 161, 162, 163, 164, 165, 166, 166, 154, 155, 156, 157, 159, 253, 254, 31}, SKINCOLOR_ISLAND, 7, V_PURPLEMAP, true}, // SKINCOLOR_GALAXY {"Vapor", {0x80, 0x81, 0x83, 0x86, 0x94, 0x94, 0xa3, 0xa3, 0xa4, 0xa6, 0xa6, 0xa6, 0xa8, 0xa8, 0xa9, 0xa9}, SKINCOLOR_LILAC, 4, V_SKYMAP, true}, // SKINCOLOR_VAPOR {"Dusk", {0x92, 0x93, 0x94, 0x94, 0xac, 0xad, 0xad, 0xad, 0xae, 0xae, 0xaf, 0xaf, 0xa9, 0xa9, 0xfd, 0xfd}, SKINCOLOR_OLIVE, 0, V_BLUEMAP, true}, // SKINCOLOR_DUSK - {"Majesty", { 0, 1, 176, 160, 160, 161, 162, 162, 163, 172, 173, 174, 174, 175, 139, 139}, SKINCOLOR_GOLDENROD, 11, V_PURPLEMAP, true}, // SKINCOLOR_MAJESTY + {"Majesty", { 0, 1, 176, 160, 160, 161, 162, 162, 163, 172, 173, 174, 174, 175, 139, 139}, SKINCOLOR_GOLDENROD, 9, V_PURPLEMAP, true}, // SKINCOLOR_MAJESTY {"Pastel", {0x90, 0x90, 0xa0, 0xa0, 0xa1, 0xa1, 0xa2, 0xa2, 0xa2, 0xa3, 0xa4, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8}, SKINCOLOR_BUBBLEGUM, 9, V_PURPLEMAP, true}, // SKINCOLOR_PASTEL {"Purple", {0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa4, 0xa5, 0xa5, 0xa5, 0xa6, 0xa7, 0xa7, 0xa8, 0xa8, 0xa9, 0xa9}, SKINCOLOR_FLAME, 7, V_PURPLEMAP, true}, // SKINCOLOR_PURPLE {"Noble", { 144, 146, 147, 148, 149, 164, 164, 165, 166, 185, 186, 186, 187, 187, 28, 29}, SKINCOLOR_CHARTREUSE, 12, V_PURPLEMAP, true}, // SKINCOLOR_NOBLE - {"Fuchsia", { 200, 201, 203, 204, 204, 183, 184, 184, 165, 166, 167, 168, 169, 159, 253, 254}, SKINCOLOR_LEMON, 6, V_PURPLEMAP, true}, // SKINCOLOR_FUCHSIA + {"Fuchsia", { 200, 201, 203, 204, 204, 183, 184, 184, 165, 166, 167, 168, 169, 159, 253, 254}, SKINCOLOR_LEMON, 10, V_PURPLEMAP, true}, // SKINCOLOR_FUCHSIA {"Bubblegum", { 0, 208, 208, 176, 177, 178, 179, 180, 181, 183, 165, 166, 167, 168, 169, 253}, SKINCOLOR_PASTEL, 8, V_MAGENTAMAP, true}, // SKINCOLOR_BUBBLEGUM {"Crystal", { 252, 177, 179, 180, 181, 181, 182, 182, 183, 164, 166, 167, 167, 168, 169, 159}, SKINCOLOR_EMERALD, 8, V_MAGENTAMAP, true}, // SKINCOLOR_CRYSTAL {"Magenta", {0xb3, 0xb3, 0xb4, 0xb5, 0xb6, 0xb6, 0xb7, 0xb7, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xbb}, SKINCOLOR_LIME, 6, V_MAGENTAMAP, true}, // SKINCOLOR_MAGENTA @@ -21682,14 +21682,14 @@ 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 {"Royal", { 208, 209, 192, 192, 192, 193, 193, 194, 194, 172, 173, 174, 175, 175, 139, 139}, SKINCOLOR_FANCY, 9, V_PURPLEMAP, true}, // SKINCOLOR_ROYAL {"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 - {"Mauve", { 176, 177, 178, 192, 193, 194, 195, 195, 196, 185, 185, 186, 186, 187, 187, 253}, SKINCOLOR_HEADLIGHT, 8, V_PURPLEMAP, true}, // SKINCOLOR_MAUVE + {"Mauve", { 176, 177, 178, 192, 193, 194, 195, 195, 196, 185, 185, 186, 186, 187, 187, 253}, SKINCOLOR_GOLD, 4, V_PURPLEMAP, true}, // SKINCOLOR_MAUVE {"Eventide", { 51, 52, 53, 33, 34, 204, 183, 183, 184, 184, 166, 167, 168, 169, 253, 254}, SKINCOLOR_DAYBREAK, 13, V_MAGENTAMAP, true}, // SKINCOLOR_EVENTIDE {"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 - {"Taffy", { 1, 176, 176, 177, 178, 179, 202, 203, 204, 204, 205, 206, 207, 44, 45, 46}, SKINCOLOR_JADE, 8, V_ROSYMAP, true}, // SKINCOLOR_TAFFY - {"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 + {"Taffy", { 1, 176, 176, 177, 178, 179, 202, 203, 204, 204, 205, 206, 207, 44, 45, 46}, SKINCOLOR_AQUA, 1, V_ROSYMAP, true}, // SKINCOLOR_TAFFY + {"Rosy", {0xfc, 0xc8, 0xc8, 0xc9, 0xc9, 0xca, 0xca, 0xcb, 0xcb, 0xcc, 0xcc, 0xcd, 0xcd, 0xce, 0xce, 0xcf}, SKINCOLOR_JADE, 8, V_ROSYMAP, true}, // SKINCOLOR_ROSY {"Fancy", { 0, 208, 49, 210, 210, 202, 202, 203, 204, 204, 205, 206, 207, 207, 186, 186}, SKINCOLOR_ROYAL, 9, V_ROSYMAP, true}, // SKINCOLOR_FANCY - {"Sangria", { 210, 32, 33, 34, 34, 215, 215, 207, 207, 185, 186, 186, 186, 169, 169, 253}, SKINCOLOR_TURQUOISE, 7, V_ROSYMAP, true}, // SKINCOLOR_SANGRIA + {"Sangria", { 210, 32, 33, 34, 34, 215, 215, 207, 207, 185, 186, 186, 186, 169, 169, 253}, SKINCOLOR_TURQUOISE, 12, V_ROSYMAP, true}, // SKINCOLOR_SANGRIA {"Volcanic", { 35, 38, 41, 42, 44, 46, 46, 169, 169, 159, 253, 254, 30, 30, 31, 31}, SKINCOLOR_BRONZE, 9, V_REDMAP, true}, // SKINCOLOR_VOLCANIC // super From b97f0a8643dc59e9ffd78d73c848138d8882c06d Mon Sep 17 00:00:00 2001 From: spherallic Date: Tue, 28 Mar 2023 20:10:53 +0200 Subject: [PATCH 220/586] Fix MT_NIGHTSCORE color cycling, using link colors --- src/p_inter.c | 39 ++++++++------------------------------- src/p_mobj.c | 2 +- src/st_stuff.c | 16 ++++++++-------- src/st_stuff.h | 3 +++ 4 files changed, 20 insertions(+), 40 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 046a0a198..c66c4e10e 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -255,42 +255,19 @@ void P_DoNightsScore(player_t *player) player->linktimer = nightslinktics; } - if (player->linkcount < 10) - { - if (player->bonustime) - { - P_AddPlayerScore(player, player->linkcount*20); - P_SetMobjState(dummymo, dummymo->info->xdeathstate+player->linkcount-1); - } - else - { - P_AddPlayerScore(player, player->linkcount*10); - P_SetMobjState(dummymo, dummymo->info->spawnstate+player->linkcount-1); - } - } - else - { - if (player->bonustime) - { - P_AddPlayerScore(player, 200); - P_SetMobjState(dummymo, dummymo->info->xdeathstate+9); - } - else - { - P_AddPlayerScore(player, 100); - P_SetMobjState(dummymo, dummymo->info->spawnstate+9); - } - } + // Award 10-100 score, doubled if bonus time is active + P_AddPlayerScore(player, min(player->linkcount,10)*(player->bonustime ? 20 : 10)); + P_SetMobjState(dummymo, (player->bonustime ? dummymo->info->xdeathstate : dummymo->info->spawnstate) + min(player->linkcount,10)-1); - // Hoops are the only things that should add to your drill meter - //player->drillmeter += TICRATE; + // Make objects slowly rise & scale up dummymo->momz = FRACUNIT; dummymo->fuse = 3*TICRATE; - - // What?! NO, don't use the camera! Scale up instead! - //P_InstaThrust(dummymo, R_PointToAngle2(dummymo->x, dummymo->y, camera.x, camera.y), 3*FRACUNIT); dummymo->scalespeed = FRACUNIT/25; dummymo->destscale = 2*FRACUNIT; + + // Add extra values used for color variety + dummymo->extravalue1 = player->linkcount-1; + dummymo->extravalue2 = ((player->linkcount-1 >= 300) ? (player->linkcount-1 >= 600) ? 2 : 1 : 0); } // diff --git a/src/p_mobj.c b/src/p_mobj.c index 3eab29c09..a43afc9b1 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9603,7 +9603,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) case MT_BOSSFLYPOINT: return false; case MT_NIGHTSCORE: - mobj->color = (UINT16)(leveltime % SKINCOLOR_WHITE); + mobj->color = linkColor[mobj->extravalue2][(leveltime + mobj->extravalue1) % NUMLINKCOLORS]; break; case MT_JETFUME1: if (!P_JetFume1Think(mobj)) diff --git a/src/st_stuff.c b/src/st_stuff.c index 484216e30..3ce1cbfd8 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -170,6 +170,14 @@ hudinfo_t hudinfo[NUMHUDITEMS] = static huddrawlist_h luahuddrawlist_game[2]; static huddrawlist_h luahuddrawlist_titlecard; +skincolornum_t linkColor[3][NUMLINKCOLORS] = { +{SKINCOLOR_SHAMROCK, SKINCOLOR_AQUA, SKINCOLOR_SKY, SKINCOLOR_BLUE, SKINCOLOR_PURPLE, SKINCOLOR_MAGENTA, + SKINCOLOR_ROSY, SKINCOLOR_RED, SKINCOLOR_ORANGE, SKINCOLOR_GOLD, SKINCOLOR_YELLOW, SKINCOLOR_PERIDOT}, +{SKINCOLOR_EMERALD, SKINCOLOR_AQUAMARINE, SKINCOLOR_WAVE, SKINCOLOR_SAPPHIRE, SKINCOLOR_GALAXY, SKINCOLOR_CRYSTAL, + SKINCOLOR_TAFFY, SKINCOLOR_RUBY, SKINCOLOR_GARNET, SKINCOLOR_TOPAZ, SKINCOLOR_LEMON, SKINCOLOR_LIME}, +{SKINCOLOR_ISLAND, SKINCOLOR_TURQUOISE, SKINCOLOR_DREAM, SKINCOLOR_DAYBREAK, SKINCOLOR_VAPOR, SKINCOLOR_FUCHSIA, + SKINCOLOR_VIOLET, SKINCOLOR_EVENTIDE, SKINCOLOR_KETCHUP, SKINCOLOR_FOUNDATION, SKINCOLOR_HEADLIGHT, SKINCOLOR_CHARTREUSE}}; + // // STATUS BAR CODE // @@ -1752,14 +1760,6 @@ static void ST_drawNightsRecords(void) } // NiGHTS link colors; 3 sets with increasingly fancy colors (1 to 299, 300 to 599, 600 and above) -#define NUMLINKCOLORS 12 -static skincolornum_t linkColor[3][NUMLINKCOLORS] = { -{SKINCOLOR_SHAMROCK, SKINCOLOR_AQUA, SKINCOLOR_SKY, SKINCOLOR_BLUE, SKINCOLOR_PURPLE, SKINCOLOR_MAGENTA, - SKINCOLOR_ROSY, SKINCOLOR_RED, SKINCOLOR_ORANGE, SKINCOLOR_GOLD, SKINCOLOR_YELLOW, SKINCOLOR_PERIDOT}, -{SKINCOLOR_EMERALD, SKINCOLOR_AQUAMARINE, SKINCOLOR_WAVE, SKINCOLOR_SAPPHIRE, SKINCOLOR_GALAXY, SKINCOLOR_CRYSTAL, - SKINCOLOR_TAFFY, SKINCOLOR_RUBY, SKINCOLOR_GARNET, SKINCOLOR_TOPAZ, SKINCOLOR_LEMON, SKINCOLOR_LIME}, -{SKINCOLOR_ISLAND, SKINCOLOR_TURQUOISE, SKINCOLOR_DREAM, SKINCOLOR_DAYBREAK, SKINCOLOR_VAPOR, SKINCOLOR_FUCHSIA, - SKINCOLOR_VIOLET, SKINCOLOR_EVENTIDE, SKINCOLOR_KETCHUP, SKINCOLOR_FOUNDATION, SKINCOLOR_HEADLIGHT, SKINCOLOR_CHARTREUSE}}; static void ST_drawNiGHTSLink(void) { diff --git a/src/st_stuff.h b/src/st_stuff.h index 68ac900f7..603be3c30 100644 --- a/src/st_stuff.h +++ b/src/st_stuff.h @@ -124,4 +124,7 @@ extern hudinfo_t hudinfo[NUMHUDITEMS]; extern UINT16 objectsdrawn; +#define NUMLINKCOLORS 12 +extern skincolornum_t linkColor[3][NUMLINKCOLORS]; + #endif From 1a956667a74c8619333076d68c94f177b5f5082f Mon Sep 17 00:00:00 2001 From: spherallic Date: Wed, 29 Mar 2023 15:50:03 +0200 Subject: [PATCH 221/586] Small tweak to Bubblegum --- src/info.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/info.c b/src/info.c index 5a304240d..32b21b702 100644 --- a/src/info.c +++ b/src/info.c @@ -21675,7 +21675,7 @@ skincolor_t skincolors[MAXSKINCOLORS] = { {"Purple", {0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa4, 0xa5, 0xa5, 0xa5, 0xa6, 0xa7, 0xa7, 0xa8, 0xa8, 0xa9, 0xa9}, SKINCOLOR_FLAME, 7, V_PURPLEMAP, true}, // SKINCOLOR_PURPLE {"Noble", { 144, 146, 147, 148, 149, 164, 164, 165, 166, 185, 186, 186, 187, 187, 28, 29}, SKINCOLOR_CHARTREUSE, 12, V_PURPLEMAP, true}, // SKINCOLOR_NOBLE {"Fuchsia", { 200, 201, 203, 204, 204, 183, 184, 184, 165, 166, 167, 168, 169, 159, 253, 254}, SKINCOLOR_LEMON, 10, V_PURPLEMAP, true}, // SKINCOLOR_FUCHSIA - {"Bubblegum", { 0, 208, 208, 176, 177, 178, 179, 180, 181, 183, 165, 166, 167, 168, 169, 253}, SKINCOLOR_PASTEL, 8, V_MAGENTAMAP, true}, // SKINCOLOR_BUBBLEGUM + {"Bubblegum", { 0, 208, 208, 176, 177, 178, 179, 180, 181, 182, 164, 166, 167, 168, 169, 253}, SKINCOLOR_PASTEL, 8, V_MAGENTAMAP, true}, // SKINCOLOR_BUBBLEGUM {"Crystal", { 252, 177, 179, 180, 181, 181, 182, 182, 183, 164, 166, 167, 167, 168, 169, 159}, SKINCOLOR_EMERALD, 8, V_MAGENTAMAP, true}, // SKINCOLOR_CRYSTAL {"Magenta", {0xb3, 0xb3, 0xb4, 0xb5, 0xb6, 0xb6, 0xb7, 0xb7, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xbb}, SKINCOLOR_LIME, 6, V_MAGENTAMAP, true}, // SKINCOLOR_MAGENTA {"Neon", {0xb3, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xbb, 0xc7, 0xc7, 0x1d, 0x1d, 0x1e}, SKINCOLOR_CERULEAN, 2, V_MAGENTAMAP, true}, // SKINCOLOR_NEON From 867a5e0d47180c068a5819e0b3e6d054e999d000 Mon Sep 17 00:00:00 2001 From: spherallic Date: Tue, 20 Jun 2023 21:48:26 +0200 Subject: [PATCH 222/586] Correct misplaced comment on NiGHTS link colors --- src/st_stuff.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/st_stuff.c b/src/st_stuff.c index 3ce1cbfd8..9cac145a7 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -170,6 +170,7 @@ hudinfo_t hudinfo[NUMHUDITEMS] = static huddrawlist_h luahuddrawlist_game[2]; static huddrawlist_h luahuddrawlist_titlecard; +// NiGHTS link colors; 3 sets with increasingly fancy colors (1 to 299, 300 to 599, 600 and above) skincolornum_t linkColor[3][NUMLINKCOLORS] = { {SKINCOLOR_SHAMROCK, SKINCOLOR_AQUA, SKINCOLOR_SKY, SKINCOLOR_BLUE, SKINCOLOR_PURPLE, SKINCOLOR_MAGENTA, SKINCOLOR_ROSY, SKINCOLOR_RED, SKINCOLOR_ORANGE, SKINCOLOR_GOLD, SKINCOLOR_YELLOW, SKINCOLOR_PERIDOT}, @@ -1759,8 +1760,6 @@ static void ST_drawNightsRecords(void) } } -// NiGHTS link colors; 3 sets with increasingly fancy colors (1 to 299, 300 to 599, 600 and above) - static void ST_drawNiGHTSLink(void) { static INT32 prevsel[2] = {0, 0}, prevtime[2] = {0, 0}; From e88b3542c72516c94d9257c4c79852dca58e8791 Mon Sep 17 00:00:00 2001 From: spherallic Date: Thu, 22 Jun 2023 14:02:31 +0200 Subject: [PATCH 223/586] Update UZB/UDMF configuration files --- extras/conf/udb/Includes/SRB222_common.cfg | 152 +- extras/conf/udb/Includes/SRB222_linedefs.cfg | 1810 +------- extras/conf/udb/Includes/SRB222_misc.cfg | 356 +- extras/conf/udb/Includes/SRB222_sectors.cfg | 107 - extras/conf/udb/Includes/SRB222_things.cfg | 3927 +++--------------- extras/conf/udb/SRB2_22Doom.cfg | 32 - 6 files changed, 751 insertions(+), 5633 deletions(-) delete mode 100644 extras/conf/udb/Includes/SRB222_sectors.cfg delete mode 100644 extras/conf/udb/SRB2_22Doom.cfg diff --git a/extras/conf/udb/Includes/SRB222_common.cfg b/extras/conf/udb/Includes/SRB222_common.cfg index 0ff044a6d..9a574d6f2 100644 --- a/extras/conf/udb/Includes/SRB222_common.cfg +++ b/extras/conf/udb/Includes/SRB222_common.cfg @@ -15,7 +15,7 @@ common ignoredextensions = "wad pk3 pk7 bak backup1 backup2 backup3 zip rar 7z"; // Default testing parameters - testparameters = "-file \"%AP\" \"%F\" -warp %L"; + testparameters = "-folder \"%AF\" -file \"%AA\" \"%F\" -warp %L"; testshortpaths = true; // Action special help @@ -26,7 +26,7 @@ common generalizedsectors = true; // Maximum safe map size check (0 means skip check) - safeboundary = 1; + safeboundary = 0; // Map boundaries. Map objects can only be placed within these boundaries leftboundary = -32768; @@ -40,6 +40,8 @@ common defaultflatscale = 1.0f; scaledtextureoffsets = true; + maxcolormapalpha = 25; + // Thing number for start position in 3D Mode start3dmode = 3328; @@ -68,137 +70,6 @@ common } } -mapformat_doom -{ - // The format interface handles the map data format - formatinterface = "DoomMapSetIO"; - - // Default nodebuilder configurations - defaultsavecompiler = "zennode_normal"; - defaulttestcompiler = "zennode_fast"; - - /* - GAME DETECT PATTERN - Used to guess the game for which a WAD file is made. - - 1 = One of these lumps must exist - 2 = None of these lumps must exist - 3 = All of these lumps must exist - */ - - gamedetect - { - EXTENDED = 2; - - - BEHAVIOR = 2; - - E#M# = 2; - - MAP?? = 1; - } - - /* - MAP LUMP NAMES - Map lumps are loaded with the map as long as they are right after each other. When the editor - meets a lump which is not defined in this list it will ignore the map if not satisfied. - The order of items defines the order in which lumps will be written to WAD file on save. - To indicate the map header lump, use ~MAP - - Legenda: - required = Lump is required to exist. - blindcopy = Lump will be copied along with the map blindly. (usefull for lumps Doom Builder doesn't use) - nodebuild = The nodebuilder generates this lump. - allowempty = The nodebuilder is allowed to leave this lump empty. - script = This lump is a text-based script. Specify the filename of the script configuration to use. - */ - - maplumpnames - { - include("SRB222_misc.cfg", "doommaplumpnames"); - } - - // When this is set to true, sectors with the same tag will light up when a line is highlighted - linetagindicatesectors = true; - - // Special linedefs - include("SRB222_misc.cfg", "speciallinedefs"); - - // Default flags for first new thing - defaultthingflags - { - } - - // DEFAULT SECTOR BRIGHTNESS LEVELS - sectorbrightness - { - include("SRB222_misc.cfg", "sectorbrightness"); - } - - // SECTOR TYPES - sectortypes - { - include("SRB222_sectors.cfg", "sectortypes"); - } - - // GENERALISED SECTOR TYPES - gen_sectortypes - { - include("SRB222_sectors.cfg", "gen_sectortypes"); - } - - // LINEDEF FLAGS - linedefflags - { - include("SRB222_misc.cfg", "linedefflags"); - } - - // Linedef flags UDMF translation table - // This is needed for copy/paste and prefabs to work properly - // When the UDMF field name is prefixed with ! it is inverted - linedefflagstranslation - { - include("SRB222_misc.cfg", "linedefflagstranslation"); - } - - // LINEDEF ACTIVATIONS - linedefactivations - { - } - - // LINEDEF TYPES - linedeftypes - { - include("SRB222_linedefs.cfg", "doom"); - } - - // THING FLAGS - thingflags - { - include("SRB222_misc.cfg", "thingflags"); - } - - // Thing flags UDMF translation table - // This is needed for copy/paste and prefabs to work properly - // When the UDMF field name is prefixed with ! it is inverted - thingflagstranslation - { - include("SRB222_misc.cfg", "thingflagstranslation"); - } - - // THING FLAGS ERROR MASK - // Mask for the thing flags which indicates the options - // that make the same thing appear in the same modes - thingflagsmask1 = 7; // 1 + 2 + 4 - thingflagsmask2 = 0; - - // THING TYPES - thingtypes - { - include("SRB222_things.cfg", "doom"); - } -} - mapformat_udmf { // The format interface handles the map data format @@ -222,9 +93,17 @@ mapformat_udmf { include("SRB222_misc.cfg", "universalfields"); } + + // Disable Doom-related modes that don't make sense for SRB2 + soundsupport = false; + automapsupport = false; // When this is set to true, sectors with the same tag will light up when a line is highlighted linetagindicatesectors = false; + localsidedeftextureoffsets = false; + distinctfloorandceilingbrightness = true; + + planeequationsupport = true; // Special linedefs include("SRB222_misc.cfg", "speciallinedefs_udmf"); @@ -240,6 +119,11 @@ mapformat_udmf include("SRB222_misc.cfg", "sectorflags"); } + sectorflagscategories + { + include("SRB222_misc.cfg", "sectorflagscategories"); + } + // DEFAULT SECTOR BRIGHTNESS LEVELS sectorbrightness { @@ -247,6 +131,7 @@ mapformat_udmf } damagetypes = "Generic Water Fire Lava Electric Spike DeathPitTilt DeathPitNoTilt Instakill SpecialStage"; + triggerertypes = "Player AllPlayers Mobj"; // LINEDEF FLAGS linedefflags @@ -282,7 +167,6 @@ mapformat_udmf // How to compare thing flags (for the stuck things error checker) thingflagscompare { - include("UDMF_misc.cfg", "thingflagscompare"); } // THING TYPES diff --git a/extras/conf/udb/Includes/SRB222_linedefs.cfg b/extras/conf/udb/Includes/SRB222_linedefs.cfg index b526e84e7..621b4abd5 100644 --- a/extras/conf/udb/Includes/SRB222_linedefs.cfg +++ b/extras/conf/udb/Includes/SRB222_linedefs.cfg @@ -1,1793 +1,3 @@ -doom -{ - misc - { - title = "Miscellaneous"; - - 0 - { - title = "None"; - prefix = "(0)"; - } - 1 - { - title = "Per-Sector Gravity"; - prefix = "(1)"; - } - 5 - { - title = "Camera Scanner "; - prefix = "(5)"; - } - 7 - { - title = "Sector Flat Alignment"; - prefix = "(7)"; - } - 10 - { - title = "Culling Plane"; - prefix = "(10)"; - } - 13 - { - title = "Heat Wave Effect"; - prefix = "(13)"; - } - 40 - { - title = "Visual Portal Between Tagged Linedefs"; - prefix = "(40)"; - } - 41 - { - title = "Horizon Effect"; - prefix = "(41)"; - } - 50 - { - title = "Instantly Lower Floor on Level Load"; - prefix = "(50)"; - } - 51 - { - title = "Instantly Raise Ceiling on Level Load"; - prefix = "(51)"; - } - 63 - { - title = "Fake Floor/Ceiling Planes"; - prefix = "(63)"; - } - 540 - { - title = "Floor Friction"; - prefix = "(540)"; - } - } - - parameters - { - title = "Parameters"; - - 2 - { - title = "Custom Exit"; - prefix = "(2)"; - } - 3 - { - title = "Zoom Tube Parameters"; - prefix = "(3)"; - } - 4 - { - title = "Speed Pad Parameters"; - prefix = "(4)"; - } - 8 - { - title = "Special Sector Properties"; - prefix = "(8)"; - } - 9 - { - title = "Chain Parameters"; - prefix = "(9)"; - } - 11 - { - title = "Rope Hang Parameters"; - prefix = "(11)"; - } - 12 - { - title = "Rock Spawner Parameters"; - prefix = "(12)"; - } - 14 - { - title = "Bustable Block Parameters"; - prefix = "(14)"; - } - 15 - { - title = "Fan Particle Spawner Parameters"; - prefix = "(15)"; - } - 16 - { - title = "Minecart Parameters"; - prefix = "(16)"; - } - 64 - { - title = "Continuously Appearing/Disappearing FOF"; - prefix = "(64)"; - } - 76 - { - title = "Make FOF Bouncy"; - prefix = "(76)"; - } - } - - polyobject - { - title = "PolyObject"; - - 20 - { - title = "First Line"; - prefix = "(20)"; - } - 21 - { - title = "Explicitly Include Line "; - prefix = "(21)"; - } - 22 - { - title = "Parameters"; - prefix = "(22)"; - } - 30 - { - title = "Waving Flag"; - prefix = "(30)"; - } - 31 - { - title = "Displacement by Front Sector"; - prefix = "(31)"; - } - 32 - { - title = "Angular Displacement by Front Sector"; - prefix = "(32)"; - } - } - - planemove - { - title = "Plane Movement"; - - 52 - { - title = "Continuously Falling Sector"; - prefix = "(52)"; - } - 53 - { - title = "Continuous Floor/Ceiling Mover"; - prefix = "(53)"; - } - 54 - { - title = "Continuous Floor Mover"; - prefix = "(54)"; - } - 55 - { - title = "Continuous Ceiling Mover"; - prefix = "(55)"; - } - 56 - { - title = "Continuous Two-Speed Floor/Ceiling Mover"; - prefix = "(56)"; - } - 57 - { - title = "Continuous Two-Speed Floor Mover"; - prefix = "(57)"; - } - 58 - { - title = "Continuous Two-Speed Ceiling Mover"; - prefix = "(58)"; - } - 59 - { - title = "Activate Moving Platform"; - prefix = "(59)"; - } - 60 - { - title = "Activate Moving Platform (Adjustable Speed)"; - prefix = "(60)"; - } - 61 - { - title = "Crusher (Ceiling to Floor)"; - prefix = "(61)"; - } - 62 - { - title = "Crusher (Floor to Ceiling)"; - prefix = "(62)"; - } - 66 - { - title = "Move Floor by Displacement"; - prefix = "(66)"; - } - 67 - { - title = "Move Ceiling by Displacement"; - prefix = "(67)"; - } - 68 - { - title = "Move Floor and Ceiling by Displacement"; - prefix = "(68)"; - } - } - - fofsolid - { - title = "FOF (solid)"; - - 100 - { - title = "Solid, Opaque"; - prefix = "(100)"; - } - 101 - { - title = "Solid, Opaque, No Shadow"; - prefix = "(101)"; - } - 102 - { - title = "Solid, Translucent"; - prefix = "(102)"; - } - 103 - { - title = "Solid, Sides Only"; - prefix = "(103)"; - } - 104 - { - title = "Solid, No Sides"; - prefix = "(104)"; - } - 105 - { - title = "Solid, Invisible"; - prefix = "(105)"; - } - 140 - { - title = "Intangible from Bottom, Opaque"; - prefix = "(140)"; - } - 141 - { - title = "Intangible from Bottom, Translucent"; - prefix = "(141)"; - } - 142 - { - title = "Intangible from Bottom, Translucent, No Sides"; - prefix = "(142)"; - } - 143 - { - title = "Intangible from Top, Opaque"; - prefix = "(143)"; - } - 144 - { - title = "Intangible from Top, Translucent"; - prefix = "(144)"; - } - 145 - { - title = "Intangible from Top, Translucent, No Sides"; - prefix = "(145)"; - } - 146 - { - title = "Only Tangible from Sides"; - prefix = "(146)"; - } - } - - fofintangible - { - title = "FOF (intangible)"; - - 120 - { - title = "Water, Opaque"; - prefix = "(120)"; - } - 121 - { - title = "Water, Translucent"; - prefix = "(121)"; - } - 122 - { - title = "Water, Opaque, No Sides"; - prefix = "(122)"; - } - 123 - { - title = "Water, Translucent, No Sides"; - prefix = "(123)"; - } - 124 - { - title = "Goo Water, Translucent"; - prefix = "(124)"; - } - 125 - { - title = "Goo Water, Translucent, No Sides"; - prefix = "(125)"; - } - 220 - { - title = "Intangible, Opaque"; - prefix = "(220)"; - } - 221 - { - title = "Intangible, Translucent"; - prefix = "(221)"; - } - 222 - { - title = "Intangible, Sides Only"; - prefix = "(222)"; - } - 223 - { - title = "Intangible, Invisible"; - prefix = "(223)"; - } - } - - fofmoving - { - title = "FOF (moving)"; - - 150 - { - title = "Air Bobbing"; - prefix = "(150)"; - } - 151 - { - title = "Air Bobbing (Adjustable)"; - prefix = "(151)"; - } - 152 - { - title = "Reverse Air Bobbing (Adjustable)"; - prefix = "(152)"; - } - 153 - { - title = "Dynamically Sinking Platform"; - prefix = "(153)"; - } - 160 - { - title = "Water Bobbing"; - prefix = "(160)"; - } - 190 - { - title = "Rising Platform, Solid, Opaque"; - prefix = "(190)"; - } - 191 - { - title = "Rising Platform, Solid, Opaque, No Shadow"; - prefix = "(191)"; - } - 192 - { - title = "Rising Platform, Solid, Translucent"; - prefix = "(192)"; - } - 193 - { - title = "Rising Platform, Solid, Invisible"; - prefix = "(193)"; - } - 194 - { - title = "Rising Platform, Intangible from Bottom, Opaque"; - prefix = "(194)"; - } - 195 - { - title = "Rising Platform, Intangible from Bottom, Translucent"; - prefix = "(195)"; - } - } - - fofcrumbling - { - title = "FOF (crumbling)"; - - 170 - { - title = "Crumbling, Respawn"; - prefix = "(170)"; - } - 171 - { - title = "Crumbling, No Respawn"; - prefix = "(171)"; - } - 172 - { - title = "Crumbling, Respawn, Intangible from Bottom"; - prefix = "(172)"; - } - 173 - { - title = "Crumbling, No Respawn, Intangible from Bottom"; - prefix = "(173)"; - } - 174 - { - title = "Crumbling, Respawn, Int. from Bottom, Translucent"; - prefix = "(174)"; - } - 175 - { - title = "Crumbling, No Respawn, Int. from Bottom, Translucent"; - prefix = "(175)"; - } - 176 - { - title = "Crumbling, Respawn, Floating, Bobbing"; - prefix = "(176)"; - } - 177 - { - title = "Crumbling, No Respawn, Floating, Bobbing"; - prefix = "(177)"; - } - 178 - { - title = "Crumbling, Respawn, Floating"; - prefix = "(178)"; - } - 179 - { - title = "Crumbling, No Respawn, Floating"; - prefix = "(179)"; - } - 180 - { - title = "Crumbling, Respawn, Air Bobbing"; - prefix = "(180)"; - } - } - - fofspecial - { - title = "FOF (special)"; - - 200 - { - title = "Light Block"; - prefix = "(200)"; - } - 201 - { - title = "Half Light Block"; - prefix = "(201)"; - } - 202 - { - title = "Fog Block"; - prefix = "(202)"; - } - 250 - { - title = "Mario Block"; - prefix = "(250)"; - } - 251 - { - title = "Thwomp Block"; - prefix = "(251)"; - } - 252 - { - title = "Shatter Block"; - prefix = "(252)"; - } - 253 - { - title = "Shatter Block, Translucent"; - prefix = "(253)"; - } - 254 - { - title = "Bustable Block"; - prefix = "(254)"; - } - 255 - { - title = "Spin-Bustable Block"; - prefix = "(255)"; - } - 256 - { - title = "Spin-Bustable Block, Translucent"; - prefix = "(256)"; - } - 257 - { - title = "Quicksand"; - prefix = "(257)"; - } - 258 - { - title = "Laser"; - prefix = "(258)"; - } - 259 - { - title = "Custom FOF"; - prefix = "(259)"; - } - } - - linedeftrigger - { - title = "Linedef Executor Trigger"; - - 300 - { - title = "Continuous"; - prefix = "(300)"; - } - 301 - { - title = "Each Time"; - prefix = "(301)"; - } - 302 - { - title = "Once"; - prefix = "(302)"; - } - 303 - { - title = "Ring Count - Continuous"; - prefix = "(303)"; - } - 304 - { - title = "Ring Count - Once"; - prefix = "(304)"; - } - 305 - { - title = "Character Ability - Continuous"; - prefix = "(305)"; - } - 306 - { - title = "Character Ability - Each Time"; - prefix = "(306)"; - } - 307 - { - title = "Character Ability - Once"; - prefix = "(307)"; - } - 308 - { - title = "Race Only - Once"; - prefix = "(308)"; - } - 309 - { - title = "CTF Red Team - Continuous"; - prefix = "(309)"; - } - 310 - { - title = "CTF Red Team - Each Time"; - prefix = "(310)"; - } - 311 - { - title = "CTF Blue Team - Continuous"; - prefix = "(311)"; - } - 312 - { - title = "CTF Blue Team - Each Time"; - prefix = "(312)"; - } - 313 - { - title = "No More Enemies - Once"; - prefix = "(313)"; - } - 314 - { - title = "Number of Pushables - Continuous"; - prefix = "(314)"; - } - 315 - { - title = "Number of Pushables - Once"; - prefix = "(315)"; - } - 317 - { - title = "Condition Set Trigger - Continuous"; - prefix = "(317)"; - } - 318 - { - title = "Condition Set Trigger - Once"; - prefix = "(318)"; - } - 319 - { - title = "Unlockable - Continuous"; - prefix = "(319)"; - } - 320 - { - title = "Unlockable - Once"; - prefix = "(320)"; - } - 321 - { - title = "Trigger After X Calls - Continuous"; - prefix = "(321)"; - } - 322 - { - title = "Trigger After X Calls - Each Time"; - prefix = "(322)"; - } - 323 - { - title = "NiGHTSerize - Each Time"; - prefix = "(323)"; - } - 324 - { - title = "NiGHTSerize - Once"; - prefix = "(324)"; - } - 325 - { - title = "De-NiGHTSerize - Each Time"; - prefix = "(325)"; - } - 326 - { - title = "De-NiGHTSerize - Once"; - prefix = "(326)"; - } - 327 - { - title = "NiGHTS Lap - Each Time"; - prefix = "(327)"; - } - 328 - { - title = "NiGHTS Lap - Once"; - prefix = "(328)"; - } - 329 - { - title = "Ideya Capture Touch - Each Time"; - prefix = "(329)"; - } - 330 - { - title = "Ideya Capture Touch - Once"; - prefix = "(330)"; - } - 331 - { - title = "Player Skin - Continuous"; - flags64text = "[6] Disable for this skin"; - prefix = "(331)"; - } - 332 - { - title = "Player Skin - Each Time"; - prefix = "(332)"; - } - 333 - { - title = "Player Skin - Once"; - prefix = "(333)"; - } - 334 - { - title = "Object Dye - Continuous"; - prefix = "(334)"; - } - 335 - { - title = "Object Dye - Each Time"; - prefix = "(335)"; - } - 336 - { - title = "Object Dye - Once"; - prefix = "(336)"; - } - 337 - { - title = "Emerald Check - Continuous"; - prefix = "(337)"; - } - 338 - { - title = "Emerald Check - Each Time"; - prefix = "(338)"; - } - 339 - { - title = "Emerald Check - Once"; - prefix = "(339)"; - } - 340 - { - title = "NiGHTS Mare - Continuous"; - prefix = "(340)"; - } - 341 - { - title = "NiGHTS Mare - Each Time"; - prefix = "(341)"; - } - 342 - { - title = "NiGHTS Mare - Once"; - prefix = "(342)"; - } - 343 - { - title = "Gravity Check - Continuous"; - prefix = "(343)"; - } - 344 - { - title = "Gravity Check - Each Time"; - prefix = "(344)"; - } - 345 - { - title = "Gravity Check - Once"; - prefix = "(345)"; - } - 399 - { - title = "Level Load"; - prefix = "(399)"; - } - } - - linedefexecsector - { - title = "Linedef Executor (sector)"; - - 400 - { - title = "Set Tagged Sector's Floor Height/Texture"; - prefix = "(400)"; - } - 401 - { - title = "Set Tagged Sector's Ceiling Height/Texture"; - prefix = "(401)"; - } - 402 - { - title = "Copy Light Level to Tagged Sectors"; - prefix = "(402)"; - } - 408 - { - title = "Set Tagged Sector's Flats"; - prefix = "(408)"; - } - 409 - { - title = "Change Tagged Sector's Tag"; - prefix = "(409)"; - } - 410 - { - title = "Change Front Sector's Tag"; - prefix = "(410)"; - } - 416 - { - title = "Start Adjustable Flickering Light"; - prefix = "(416)"; - } - 417 - { - title = "Start Adjustable Pulsating Light"; - prefix = "(417)"; - } - 418 - { - title = "Start Adjustable Blinking Light (unsynchronized)"; - prefix = "(418)"; - } - 419 - { - title = "Start Adjustable Blinking Light (synchronized)"; - prefix = "(419)"; - } - 420 - { - title = "Fade Light Level"; - prefix = "(420)"; - } - 421 - { - title = "Stop Lighting Effect"; - prefix = "(421)"; - } - 435 - { - title = "Change Plane Scroller Direction"; - prefix = "(435)"; - } - 467 - { - title = "Set Tagged Sector's Light Level"; - prefix = "(467)"; - } - } - - linedefexecplane - { - title = "Linedef Executor (plane movement)"; - - 403 - { - title = "Move Tagged Sector's Floor"; - prefix = "(403)"; - } - 404 - { - title = "Move Tagged Sector's Ceiling"; - prefix = "(404)"; - } - 405 - { - title = "Move Floor According to Front Texture Offsets"; - prefix = "(405)"; - } - 407 - { - title = "Move Ceiling According to Front Texture Offsets"; - prefix = "(407)"; - } - 411 - { - title = "Stop Plane Movement"; - prefix = "(411)"; - } - 428 - { - title = "Start Platform Movement"; - prefix = "(428)"; - } - 429 - { - title = "Crush Ceiling Once"; - prefix = "(429)"; - } - 430 - { - title = "Crush Floor Once"; - prefix = "(430)"; - } - 431 - { - title = "Crush Floor and Ceiling Once"; - prefix = "(431)"; - } - } - - linedefexecplayer - { - title = "Linedef Executor (player/object)"; - - 412 - { - title = "Teleporter"; - prefix = "(412)"; - } - 425 - { - title = "Change Object State"; - prefix = "(425)"; - } - 426 - { - title = "Stop Object"; - prefix = "(426)"; - } - 427 - { - title = "Award Score"; - prefix = "(427)"; - } - 432 - { - title = "Enable/Disable 2D Mode"; - prefix = "(432)"; - } - 433 - { - title = "Enable/Disable Gravity Flip"; - prefix = "(433)"; - } - 434 - { - title = "Award Power-Up"; - prefix = "(434)"; - } - 437 - { - title = "Disable Player Control"; - prefix = "(437)"; - } - 438 - { - title = "Change Object Size"; - prefix = "(438)"; - } - 442 - { - title = "Change Object Type State"; - prefix = "(442)"; - } - 457 - { - title = "Track Object's Angle"; - prefix = "(457)"; - } - 458 - { - title = "Stop Tracking Object's Angle"; - prefix = "(458)"; - } - 460 - { - title = "Award Rings"; - prefix = "(460)"; - } - 461 - { - title = "Spawn Object"; - prefix = "(461)"; - } - 462 - { - title = "Stop Timer/Exit Stage in Record Attack"; - prefix = "(462)"; - } - 463 - { - title = "Dye Object"; - prefix = "(463)"; - } - 464 - { - title = "Trigger Egg Capsule"; - prefix = "(464)"; - } - 466 - { - title = "Set Level Failure State"; - prefix = "(466)"; - } - } - - linedefexecmisc - { - title = "Linedef Executor (misc.)"; - - 413 - { - title = "Change Music"; - prefix = "(413)"; - } - 414 - { - title = "Play Sound Effect"; - prefix = "(414)"; - } - 415 - { - title = "Run Script"; - prefix = "(415)"; - } - 422 - { - title = "Switch to Cut-Away View"; - prefix = "(422)"; - } - 423 - { - title = "Change Sky"; - prefix = "(423)"; - } - 424 - { - title = "Change Weather"; - prefix = "(424)"; - } - 436 - { - title = "Shatter FOF"; - prefix = "(436)"; - } - 439 - { - title = "Change Tagged Linedef's Textures"; - prefix = "(439)"; - } - 440 - { - title = "Start Metal Sonic Race"; - prefix = "(440)"; - } - 441 - { - title = "Condition Set Trigger"; - prefix = "(441)"; - } - 443 - { - title = "Call Lua Function"; - prefix = "(443)"; - } - 444 - { - title = "Earthquake"; - prefix = "(444)"; - } - 445 - { - title = "Make FOF Disappear/Reappear"; - prefix = "(445)"; - } - 446 - { - title = "Make FOF Crumble"; - prefix = "(446)"; - } - 447 - { - title = "Change Tagged Sector's Colormap"; - prefix = "(447)"; - } - 448 - { - title = "Change Skybox"; - prefix = "(448)"; - } - 449 - { - title = "Enable Bosses with Parameter"; - prefix = "(449)"; - } - 450 - { - title = "Execute Linedef Executor (specific tag)"; - prefix = "(450)"; - } - 451 - { - title = "Execute Linedef Executor (random tag in range)"; - prefix = "(451)"; - } - 452 - { - title = "Set FOF Translucency"; - prefix = "(452)"; - } - 453 - { - title = "Fade FOF"; - prefix = "(453)"; - } - 454 - { - title = "Stop Fading FOF"; - prefix = "(454)"; - } - 455 - { - title = "Fade Tagged Sector's Colormap"; - prefix = "(455)"; - } - 456 - { - title = "Stop Fading Tagged Sector's Colormap"; - prefix = "(456)"; - } - 459 - { - title = "Control Text Prompt"; - prefix = "(459)"; - } - } - - linedefexecpoly - { - title = "Linedef Executor (polyobject)"; - - 480 - { - title = "Door Slide"; - prefix = "(480)"; - } - 481 - { - title = "Door Swing"; - prefix = "(481)"; - } - 482 - { - title = "Move"; - prefix = "(482)"; - } - 483 - { - title = "Move, Override"; - prefix = "(483)"; - } - 484 - { - title = "Rotate Right"; - prefix = "(484)"; - } - 485 - { - title = "Rotate Right, Override"; - prefix = "(485)"; - } - 486 - { - title = "Rotate Left"; - prefix = "(486)"; - } - 487 - { - title = "Rotate Left, Override"; - prefix = "(487)"; - } - 488 - { - title = "Move by Waypoints"; - prefix = "(488)"; - } - 489 - { - title = "Turn Invisible, Intangible"; - prefix = "(489)"; - } - 490 - { - title = "Turn Visible, Tangible"; - prefix = "(490)"; - } - 491 - { - title = "Set Translucency"; - prefix = "(491)"; - } - 492 - { - title = "Fade Translucency"; - prefix = "(492)"; - } - } - - wallscroll - { - title = "Wall Scrolling"; - - 500 - { - title = "Scroll Wall Front Side Left"; - prefix = "(500)"; - } - 501 - { - title = "Scroll Wall Front Side Right"; - prefix = "(501)"; - } - 502 - { - title = "Scroll Wall According to Linedef"; - prefix = "(502)"; - } - 503 - { - title = "Scroll Wall According to Linedef (Accelerative)"; - prefix = "(503)"; - } - 504 - { - title = "Scroll Wall According to Linedef (Displacement)"; - prefix = "(504)"; - } - 505 - { - title = "Scroll Texture by Front Side Offsets"; - prefix = "(505)"; - } - 506 - { - title = "Scroll Texture by Back Side Offsets"; - prefix = "(506)"; - } - } - - planescroll - { - title = "Plane Scrolling"; - - 510 - { - title = "Scroll Floor Texture"; - prefix = "(510)"; - } - 511 - { - title = "Scroll Floor Texture (Accelerative)"; - prefix = "(511)"; - } - 512 - { - title = "Scroll Floor Texture (Displacement)"; - prefix = "(512)"; - } - 513 - { - title = "Scroll Ceiling Texture"; - prefix = "(513)"; - } - 514 - { - title = "Scroll Ceiling Texture (Accelerative)"; - prefix = "(514)"; - } - 515 - { - title = "Scroll Ceiling Texture (Displacement)"; - prefix = "(515)"; - } - 516 - { - title = "Scroll Floor and Ceiling Texture"; - prefix = "(516)"; - } - 517 - { - title = "Scroll Floor and Ceiling Texture (Accelerative)"; - prefix = "(517)"; - } - 518 - { - title = "Scroll Floor and Ceiling Texture (Displacement)"; - prefix = "(518)"; - } - 520 - { - title = "Carry Objects on Floor"; - prefix = "(520)"; - } - 521 - { - title = "Carry Objects on Floor (Accelerative)"; - prefix = "(521)"; - } - 522 - { - title = "Carry Objects on Floor (Displacement)"; - prefix = "(522)"; - } - 523 - { - title = "Carry Objects on Ceiling"; - prefix = "(523)"; - } - 524 - { - title = "Carry Objects on Ceiling (Accelerative)"; - prefix = "(524)"; - } - 525 - { - title = "Carry Objects on Ceiling (Displacement)"; - prefix = "(525)"; - } - 526 - { - title = "Carry Objects on Floor and Ceiling"; - prefix = "(526)"; - } - 527 - { - title = "Carry Objects on Floor and Ceiling (Accelerative)"; - prefix = "(527)"; - } - 528 - { - title = "Carry Objects on Floor and Ceiling (Displacement)"; - prefix = "(528)"; - } - 530 - { - title = "Scroll Floor Texture and Carry Objects"; - prefix = "(530)"; - } - 531 - { - title = "Scroll Floor Texture and Carry Objects (Accelerative)"; - prefix = "(531)"; - } - 532 - { - title = "Scroll Floor Texture and Carry Objects (Displacement)"; - prefix = "(532)"; - } - 533 - { - title = "Scroll Ceiling Texture and Carry Objects"; - prefix = "(533)"; - } - 534 - { - title = "Scroll Ceiling Texture and Carry Objects (Accelerative)"; - prefix = "(534)"; - } - 535 - { - title = "Scroll Ceiling Texture and Carry Objects (Displacement)"; - prefix = "(535)"; - } - 536 - { - title = "Scroll Floor and Ceiling Texture and Carry Objects"; - prefix = "(536)"; - } - 537 - { - title = "Scroll Floor and Ceiling Texture and Carry Objects (Accelerative)"; - prefix = "(537)"; - } - 538 - { - title = "Scroll Floor and Ceiling Texture and Carry Objects (Displacement)"; - prefix = "(538)"; - } - } - - pusher - { - title = "Pusher"; - - 541 - { - title = "Wind"; - prefix = "(541)"; - } - 542 - { - title = "Upwards Wind"; - prefix = "(542)"; - } - 543 - { - title = "Downwards Wind"; - prefix = "(543)"; - } - 544 - { - title = "Current"; - prefix = "(544)"; - } - 545 - { - title = "Upwards Current"; - prefix = "(545)"; - } - 546 - { - title = "Downwards Current"; - prefix = "(546)"; - } - 547 - { - title = "Push/Pull"; - prefix = "(547)"; - } - } - - light - { - title = "Lighting"; - - 600 - { - title = "Floor Lighting"; - prefix = "(600)"; - } - 601 - { - title = "Ceiling Lighting"; - prefix = "(601)"; - } - 602 - { - title = "Adjustable Pulsating Light"; - prefix = "(602)"; - } - 603 - { - title = "Adjustable Flickering Light"; - prefix = "(603)"; - } - 604 - { - title = "Adjustable Blinking Light (unsynchronized)"; - prefix = "(604)"; - } - 605 - { - title = "Adjustable Blinking Light (synchronized)"; - prefix = "(605)"; - } - 606 - { - title = "Colormap"; - prefix = "(606)"; - } - } - - slope - { - title = "Slope"; - - 700 - { - title = "Slope Frontside Floor"; - prefix = "(700)"; - } - 701 - { - title = "Slope Frontside Ceiling"; - prefix = "(701)"; - } - 702 - { - title = "Slope Frontside Floor and Ceiling"; - prefix = "(702)"; - } - 703 - { - title = "Slope Frontside Floor and Backside Ceiling"; - prefix = "(703)"; -´ } - 704 - { - title = "Slope Frontside Floor by 3 Tagged Vertex Things"; - prefix = "(704)"; - } - 705 - { - title = "Slope Frontside Ceiling by 3 Tagged Vertex Things"; - prefix = "(705)"; - } - 710 - { - title = "Slope Backside Floor"; - prefix = "(710)"; - } - 711 - { - title = "Slope Backside Ceiling"; - prefix = "(711)"; - } - 712 - { - title = "Slope Backside Floor and Ceiling"; - prefix = "(712)"; - } - 713 - { - title = "Slope Backside Floor and Frontside Ceiling"; - prefix = "(713)"; - } - 714 - { - title = "Slope Backside Floor by 3 Tagged Vertex Things"; - prefix = "(714)"; - } - 715 - { - title = "Slope Backside Ceiling by 3 Tagged Vertex Things"; - prefix = "(715)"; - } - 720 - { - title = "Copy Frontside Floor Slope from Line Tag"; - prefix = "(720)"; - } - 721 - { - title = "Copy Frontside Ceiling Slope from Line Tag"; - prefix = "(721)"; - } - 722 - { - title = "Copy Frontside Floor and Ceiling Slope from Line Tag"; - prefix = "(722)"; - } - 799 - { - title = "Set Tagged Dynamic Slope Vertex to Front Sector Height"; - prefix = "(799)"; - } - } - - transwall - { - title = "Translucent Wall"; - - 900 - { - title = "90% Opaque"; - prefix = "(900)"; - } - 901 - { - title = "80% Opaque"; - prefix = "(901)"; - } - 902 - { - title = "70% Opaque"; - prefix = "(902)"; - } - 903 - { - title = "60% Opaque"; - prefix = "(903)"; - } - 904 - { - title = "50% Opaque"; - prefix = "(904)"; - } - 905 - { - title = "40% Opaque"; - prefix = "(905)"; - } - 906 - { - title = "30% Opaque"; - prefix = "(906)"; - } - 907 - { - title = "20% Opaque"; - prefix = "(907)"; - } - 908 - { - title = "10% Opaque"; - prefix = "(908)"; - } - 909 - { - title = "Fog Wall"; - prefix = "(909)"; - } - 910 - { - title = "100% Additive"; - prefix = "(910)"; - } - 911 - { - title = "90% Additive"; - prefix = "(911)"; - } - 912 - { - title = "80% Additive"; - prefix = "(912)"; - } - 913 - { - title = "70% Additive"; - prefix = "(913)"; - } - 914 - { - title = "60% Additive"; - prefix = "(914)"; - } - 915 - { - title = "50% Additive"; - prefix = "(915)"; - } - 916 - { - title = "40% Additive"; - prefix = "(916)"; - } - 917 - { - title = "30% Additive"; - prefix = "(917)"; - } - 918 - { - title = "20% Additive"; - prefix = "(918)"; - } - 919 - { - title = "10% Additive"; - prefix = "(919)"; - } - 920 - { - title = "100% Subtractive"; - prefix = "(920)"; - } - 921 - { - title = "90% Subtractive"; - prefix = "(921)"; - } - 922 - { - title = "80% Subtractive"; - prefix = "(922)"; - } - 923 - { - title = "70% Subtractive"; - prefix = "(923)"; - } - 924 - { - title = "60% Subtractive"; - prefix = "(924)"; - } - 925 - { - title = "50% Subtractive"; - prefix = "(925)"; - } - 926 - { - title = "40% Subtractive"; - prefix = "(926)"; - } - 927 - { - title = "30% Subtractive"; - prefix = "(927)"; - } - 928 - { - title = "20% Subtractive"; - prefix = "(928)"; - } - 929 - { - title = "10% Subtractive"; - prefix = "(929)"; - } - 930 - { - title = "100% Reverse Subtractive"; - prefix = "(930)"; - } - 931 - { - title = "90% Reverse Subtractive"; - prefix = "(931)"; - } - 932 - { - title = "80% Reverse Subtractive"; - prefix = "(932)"; - } - 933 - { - title = "70% Reverse Subtractive"; - prefix = "(933)"; - } - 934 - { - title = "60% Reverse Subtractive"; - prefix = "(934)"; - } - 935 - { - title = "50% Reverse Subtractive"; - prefix = "(935)"; - } - 936 - { - title = "40% Reverse Subtractive"; - prefix = "(936)"; - } - 937 - { - title = "30% Reverse Subtractive"; - prefix = "(937)"; - } - 938 - { - title = "20% Reverse Subtractive"; - prefix = "(938)"; - } - 939 - { - title = "10% Reverse Subtractive"; - prefix = "(939)"; - } - 940 - { - title = "Modulate"; - prefix = "(940)"; - } - } -} - udmf { misc @@ -2502,6 +712,7 @@ udmf { title = "Solid"; prefix = "(100)"; + id = "srb2_fofsolid"; arg0 { title = "Target sector tag"; @@ -2544,6 +755,7 @@ udmf { title = "Water"; prefix = "(120)"; + id = "srb2_fofwater"; arg0 { title = "Target sector tag"; @@ -2580,6 +792,7 @@ udmf { title = "Air Bobbing"; prefix = "(150)"; + id = "srb2_fofsolidopaque"; arg0 { title = "Target sector tag"; @@ -2606,6 +819,7 @@ udmf { title = "Water Bobbing"; prefix = "(160)"; + id = "srb2_fofsolidopaque"; arg0 { title = "Target sector tag"; @@ -2617,6 +831,7 @@ udmf { title = "Crumbling"; prefix = "(170)"; + id = "srb2_fofcrumbling"; arg0 { title = "Target sector tag"; @@ -2653,11 +868,12 @@ udmf } } } - + 190 { title = "Rising"; prefix = "(190)"; + id = "srb2_fofsolid"; arg0 { title = "Target sector tag"; @@ -2714,6 +930,7 @@ udmf { title = "Light Block"; prefix = "(200)"; + id = "srb2_foflight"; arg0 { title = "Target sector tag"; @@ -2731,6 +948,7 @@ udmf { title = "Fog Block"; prefix = "(202)"; + id = "srb2_foffog"; arg0 { title = "Target sector tag"; @@ -2742,6 +960,7 @@ udmf { title = "Intangible"; prefix = "(220)"; + id = "srb2_fofintangible"; arg0 { title = "Target sector tag"; @@ -2778,6 +997,7 @@ udmf { title = "Intangible, Invisible"; prefix = "(223)"; + id = "srb2_fofintangibleinvisible"; arg0 { title = "Target sector tag"; @@ -2789,6 +1009,7 @@ udmf { title = "Mario Block"; prefix = "(250)"; + id = "srb2_fofsolidopaque"; arg0 { title = "Target sector tag"; @@ -2810,6 +1031,7 @@ udmf { title = "Thwomp Block"; prefix = "(251)"; + id = "srb2_fofsolidopaque"; arg0 { title = "Target sector tag"; @@ -2834,6 +1056,7 @@ udmf { title = "Bustable Block"; prefix = "(254)"; + id = "srb2_fofbustable"; arg0 { title = "Target sector tag"; @@ -2885,6 +1108,7 @@ udmf { title = "Quicksand"; prefix = "(257)"; + id = "srb2_fofsolidopaque"; arg0 { title = "Target sector tag"; @@ -2910,6 +1134,7 @@ udmf { title = "Laser"; prefix = "(258)"; + id = "srb2_foflaser"; arg0 { title = "Target sector tag"; @@ -2942,6 +1167,7 @@ udmf { title = "Custom"; prefix = "(259)"; + id = "srb2_fofcustom"; arg0 { title = "Target sector tag"; @@ -5686,6 +3912,7 @@ udmf { title = "Create Vertex-Based Slope"; prefix = "(704)"; + id = "srb2_vertexslope"; arg0 { title = "Plane"; @@ -5729,6 +3956,7 @@ udmf { title = "Copy Slope"; prefix = "(720)"; + id = "plane_copy"; arg0 { title = "Front floor tag"; diff --git a/extras/conf/udb/Includes/SRB222_misc.cfg b/extras/conf/udb/Includes/SRB222_misc.cfg index ed0488a3f..e274fece6 100644 --- a/extras/conf/udb/Includes/SRB222_misc.cfg +++ b/extras/conf/udb/Includes/SRB222_misc.cfg @@ -1,24 +1,3 @@ -linedefflags -{ - 1 = "[0] Impassable"; - 2 = "[1] Block Enemies"; - 4 = "[2] Double-Sided"; - 8 = "[3] Upper Unpegged"; - 16 = "[4] Lower Unpegged"; - 32 = "[5] Slope Skew (E1)"; - 64 = "[6] Not Climbable"; - 128 = "[7] No Midtexture Skew (E2)"; - 256 = "[8] Peg Midtexture (E3)"; - 512 = "[9] Solid Midtexture (E4)"; - 1024 = "[10] Repeat Midtexture (E5)"; - 2048 = "[11] Netgame Only"; - 4096 = "[12] No Netgame"; - 8192 = "[13] Effect 6"; - 16384 = "[14] Bouncy Wall"; - 32768 = "[15] Transfer Line"; -} - - // Linedef flags UDMF translation table // This is needed for copy/paste and prefabs to work properly // When the UDMF field name is prefixed with ! it is inverted @@ -42,7 +21,6 @@ linedefflagstranslation 32768 = "transfer"; } - linedefflags_udmf { blocking = "Impassable"; @@ -74,19 +52,13 @@ linedefrenderstyles sectorflags { - colormapfog = "Fog Planes in Colormap"; - colormapfadesprites = "Fade Fullbright in Colormap"; - colormapprotected = "Protected Colormap"; - flipspecial_nofloor = "No Trigger on Floor Touch"; - flipspecial_ceiling = "Trigger on Ceiling Touch"; - triggerspecial_touch = "Trigger on Edge Touch"; - triggerspecial_headbump = "Trigger on Headbump"; - triggerline_plane = "Linedef Trigger Requires Plane Touch"; - triggerline_mobj = "Non-Pushables Can Trigger Linedef"; invertprecip = "Invert Precipitation"; gravityflip = "Flip Objects in Reverse Gravity"; heatwave = "Heat Wave"; noclipcamera = "Intangible to the Camera"; + colormapfog = "Fog Planes"; + colormapfadesprites = "Fade Fullbright"; + colormapprotected = "Protected from Tagging"; outerspace = "Space Countdown"; doublestepup = "Ramp Sector (double step-up/down)"; nostepdown = "Non-Ramp Sector (No step-down)"; @@ -104,23 +76,59 @@ sectorflags zoomtubeend = "Zoom Tube End"; finishline = "Circuit Finish Line"; ropehang = "Rope Hang"; + jumpflip = "Flip Gravity on Jump"; + gravityoverride = "Make Reverse Gravity Temporary"; + flipspecial_nofloor = "No Trigger on Floor Touch"; + flipspecial_ceiling = "Trigger on Ceiling Touch"; + triggerspecial_touch = "Trigger on Edge Touch"; + triggerspecial_headbump = "Trigger on Headbump"; + triggerline_plane = "Linedef Trigger Requires Plane Touch"; + triggerline_mobj = "Non-Pushables Can Trigger Linedef"; } -thingflags +sectorflagscategories { - 1 = "[1] Extra"; - 2 = "[2] Flip"; - 4 = "[4] Special"; - 8 = "[8] Ambush"; + invertprecip = "regular"; + gravityflip = "regular"; + heatwave = "regular"; + noclipcamera = "regular"; + colormapfog = "colormap"; + colormapfadesprites = "colormap"; + colormapprotected = "colormap"; + outerspace = "special"; + doublestepup = "special"; + nostepdown = "special"; + speedpad = "special"; + starpostactivator = "special"; + exit = "special"; + specialstagepit = "special"; + returnflag = "special"; + redteambase = "special"; + blueteambase = "special"; + fan = "special"; + supertransform = "special"; + forcespin = "special"; + zoomtubestart = "special"; + zoomtubeend = "special"; + finishline = "special"; + ropehang = "special"; + jumpflip = "special"; + gravityoverride = "special"; + flipspecial_nofloor = "trigger"; + flipspecial_ceiling = "trigger"; + triggerspecial_touch = "trigger"; + triggerspecial_headbump = "trigger"; + triggerline_plane = "trigger"; + triggerline_mobj = "trigger"; } // THING FLAGS thingflags_udmf { flip = "Flip"; + absolutez = "Absolute Z height"; } - // Thing flags UDMF translation table // This is needed for copy/paste and prefabs to work properly // When the UDMF field name is prefixed with ! it is inverted @@ -130,9 +138,9 @@ thingflagstranslation 2 = "flip"; 4 = "special"; 8 = "ambush"; + 16 = "absolutez"; } - // DEFAULT SECTOR BRIGHTNESS LEVELS sectorbrightness { @@ -171,6 +179,8 @@ sectorbrightness 0; } +numbrightnesslevels = 32; + /* TEXTURES AND FLAT SOURCES This tells Doom Builder where to find the information for textures @@ -221,145 +231,18 @@ universalfields { sector { - lightalpha - { - type = 0; - default = 25; - } - - fadealpha - { - type = 0; - default = 25; - } - - fadestart - { - type = 0; - default = 0; - } - - fadeend - { - type = 0; - default = 33; - } - - foglighting - { - type = 3; - default = false; - } - - friction - { - type = 1; - default = 0.90625; - } - - triggertag - { - type = 15; - default = 0; - } - - triggerer - { - type = 2; - default = "Player"; - } } linedef { - arg5 - { - type = 0; - default = 0; - } - arg6 - { - type = 0; - default = 0; - } - arg7 - { - type = 0; - default = 0; - } - arg8 - { - type = 0; - default = 0; - } - arg9 - { - type = 0; - default = 0; - } - stringarg0 - { - type = 2; - default = ""; - } - stringarg1 - { - type = 2; - default = ""; - } - executordelay - { - type = 0; - default = 0; - } } sidedef { - repeatcnt - { - type = 0; - default = 0; - } } thing { - arg5 - { - type = 0; - default = 0; - } - arg6 - { - type = 0; - default = 0; - } - arg7 - { - type = 0; - default = 0; - } - arg8 - { - type = 0; - default = 0; - } - arg9 - { - type = 0; - default = 0; - } - stringarg0 - { - type = 2; - default = ""; - } - stringarg1 - { - type = 2; - default = ""; - } } } @@ -378,87 +261,6 @@ allowempty = The nodebuilder is allowed to leave this lump empty. scriptbuild = This lump is a text-based script, which should be compiled using current script compiler; script = This lump is a text-based script. Specify the filename of the script configuration to use. */ - -doommaplumpnames -{ - ~MAP - { - required = true; - blindcopy = true; - nodebuild = false; - } - - THINGS - { - required = true; - nodebuild = true; - allowempty = true; - } - - LINEDEFS - { - required = true; - nodebuild = true; - allowempty = false; - } - - SIDEDEFS - { - required = true; - nodebuild = true; - allowempty = false; - } - - VERTEXES - { - required = true; - nodebuild = true; - allowempty = false; - } - - SEGS - { - required = false; - nodebuild = true; - allowempty = false; - } - - SSECTORS - { - required = false; - nodebuild = true; - allowempty = false; - } - - NODES - { - required = false; - nodebuild = true; - allowempty = false; - } - - SECTORS - { - required = true; - nodebuild = true; - allowempty = false; - } - - REJECT - { - required = false; - nodebuild = true; - allowempty = false; - } - - BLOCKMAP - { - required = false; - nodebuild = true; - allowempty = true; - } -} - udmfmaplumpnames { ZNODES @@ -682,48 +484,32 @@ thingsfilters } + //filter3 + //{ + // name = "Normal Gravity"; + // category = ""; + // type = -1; + // + // fields + // { + // 2 = false; + // } + //} - filter3 - { - name = "Normal Gravity"; - category = ""; - type = -1; - - fields - { - 2 = false; - } - - } - - - filter4 - { - name = "Reverse Gravity"; - category = ""; - type = -1; - - fields - { - 2 = true; - } - - } + //filter4 + //{ + // name = "Reverse Gravity"; + // category = ""; + // type = -1; + // + // fields + // { + // 2 = true; + // } + //} } // Special linedefs -speciallinedefs -{ - soundlinedefflag = 64; // See linedefflags - singlesidedflag = 1; // See linedefflags - doublesidedflag = 4; // See linedefflags - impassableflag = 1; - upperunpeggedflag = 8; - lowerunpeggedflag = 16; - repeatmidtextureflag = 1024; - pegmidtextureflag = 256; -} - speciallinedefs_udmf { soundlinedefflag = "noclimb"; @@ -734,6 +520,8 @@ speciallinedefs_udmf lowerunpeggedflag = "dontpegbottom"; repeatmidtextureflag = "wrapmidtex"; pegmidtextureflag = "midpeg"; + slopeskewflag = "skewtd"; + nomidtextureskewflag = "noskew"; } scriptlumpnames diff --git a/extras/conf/udb/Includes/SRB222_sectors.cfg b/extras/conf/udb/Includes/SRB222_sectors.cfg deleted file mode 100644 index 5b3ad4155..000000000 --- a/extras/conf/udb/Includes/SRB222_sectors.cfg +++ /dev/null @@ -1,107 +0,0 @@ -sectortypes -{ - 0 = "Normal"; - 1 = "Damage"; - 2 = "Damage (Water)"; - 3 = "Damage (Fire)"; - 4 = "Damage (Electrical)"; - 5 = "Spikes"; - 6 = "Death Pit (Camera Tilt)"; - 7 = "Death Pit (No Camera Tilt)"; - 8 = "Instant Kill"; - 9 = "Ring Drainer (Floor Touch)"; - 10 = "Ring Drainer (Anywhere in Sector)"; - 11 = "Special Stage Damage"; - 12 = "Space Countdown"; - 13 = "Ramp Sector (double step-up/down)"; - 14 = "Non-Ramp Sector (no step-down)"; - 15 = "Bouncy FOF "; - 16 = "Trigger Line Ex. (Pushable Objects)"; - 32 = "Trigger Line Ex. (Anywhere, All Players)"; - 48 = "Trigger Line Ex. (Floor Touch, All Players)"; - 64 = "Trigger Line Ex. (Anywhere in Sector)"; - 80 = "Trigger Line Ex. (Floor Touch)"; - 96 = "Trigger Line Ex. (Emerald Check) "; - 112 = "Trigger Line Ex. (NiGHTS Mare) "; - 128 = "Check for Linedef Executor on FOFs"; - 144 = "Egg Capsule"; - 160 = "Special Stage Time/Spheres Parameters "; - 176 = "Custom Global Gravity "; - 1280 = "Speed Pad"; - 1536 = "Flip Gravity on Jump"; - 4096 = "Star Post Activator"; - 8192 = "Exit/Special Stage Pit/Return Flag"; - 12288 = "CTF Red Team Base"; - 16384 = "CTF Blue Team Base"; - 20480 = "Fan Sector"; - 24576 = "Super Sonic Transform"; - 28672 = "Force Spin"; - 32768 = "Zoom Tube Start"; - 36864 = "Zoom Tube End"; - 40960 = "Circuit Finish Line"; - 45056 = "Rope Hang"; - 49152 = "Intangible to the Camera"; -} - -gen_sectortypes -{ - first - { - 0 = "Normal"; - 1 = "Damage"; - 2 = "Damage (Water)"; - 3 = "Damage (Fire)"; - 4 = "Damage (Electrical)"; - 5 = "Spikes"; - 6 = "Death Pit (Camera Tilt)"; - 7 = "Death Pit (No Camera Tilt)"; - 8 = "Instant Kill"; - 9 = "Ring Drainer (Floor Touch)"; - 10 = "Ring Drainer (Anywhere in Sector)"; - 11 = "Special Stage Damage"; - 12 = "Space Countdown"; - 13 = "Ramp Sector (double step-up/down)"; - 14 = "Non-Ramp Sector (no step-down)"; - 15 = "Bouncy FOF "; - } - - second - { - 0 = "Normal"; - 16 = "Trigger Line Ex. (Pushable Objects)"; - 32 = "Trigger Line Ex. (Anywhere, All Players)"; - 48 = "Trigger Line Ex. (Floor Touch, All Players)"; - 64 = "Trigger Line Ex. (Anywhere in Sector)"; - 80 = "Trigger Line Ex. (Floor Touch)"; - 96 = "Trigger Line Ex. (Emerald Check) "; - 112 = "Trigger Line Ex. (NiGHTS Mare) "; - 128 = "Check for Linedef Executor on FOFs"; - 144 = "Egg Capsule"; - 160 = "Special Stage Time/Spheres Parameters "; - 176 = "Custom Global Gravity "; - } - - third - { - 0 = "Normal"; - 1280 = "Speed Pad"; - 1536 = "Flip Gravity on Jump"; - } - - fourth - { - 0 = "Normal"; - 4096 = "Star Post Activator"; - 8192 = "Exit/Special Stage Pit/Return Flag"; - 12288 = "CTF Red Team Base"; - 16384 = "CTF Blue Team Base"; - 20480 = "Fan Sector"; - 24576 = "Super Sonic Transform"; - 28672 = "Force Spin"; - 32768 = "Zoom Tube Start"; - 36864 = "Zoom Tube End"; - 40960 = "Circuit Finish Line"; - 45056 = "Rope Hang"; - 49152 = "Intangible to the Camera"; - } -} diff --git a/extras/conf/udb/Includes/SRB222_things.cfg b/extras/conf/udb/Includes/SRB222_things.cfg index b4508c91e..df08e3ac5 100644 --- a/extras/conf/udb/Includes/SRB222_things.cfg +++ b/extras/conf/udb/Includes/SRB222_things.cfg @@ -3,3175 +3,8 @@ // 8-Dark_Gray 9-Blue 10-Green 11-Cyan 12-Red 13-Magenta // 14-Yellow 15-White 16-Pink 17-Orange 18-Gold 19-Cream -doom -{ - editor - { - color = 15; // White - arrow = 1; - title = ""; - error = -1; - width = 8; - height = 16; - sort = 1; - - 3328 = "3D Mode Start"; - } - - starts - { - color = 1; // Blue - arrow = 1; - title = "Player Starts"; - width = 16; - height = 48; - sprite = "PLAYA0"; - - 1 - { - title = "Player 01 Start"; - sprite = "PLAYA0"; - } - 2 - { - title = "Player 02 Start"; - sprite = "PLAYA0"; - } - 3 - { - title = "Player 03 Start"; - sprite = "PLAYA0"; - } - 4 - { - title = "Player 04 Start"; - sprite = "PLAYA0"; - } - 5 - { - title = "Player 05 Start"; - sprite = "PLAYA0"; - } - 6 - { - title = "Player 06 Start"; - sprite = "PLAYA0"; - } - 7 - { - title = "Player 07 Start"; - sprite = "PLAYA0"; - } - 8 - { - title = "Player 08 Start"; - sprite = "PLAYA0"; - } - 9 - { - title = "Player 09 Start"; - sprite = "PLAYA0"; - } - 10 - { - title = "Player 10 Start"; - sprite = "PLAYA0"; - } - 11 - { - title = "Player 11 Start"; - sprite = "PLAYA0"; - } - 12 - { - title = "Player 12 Start"; - sprite = "PLAYA0"; - } - 13 - { - title = "Player 13 Start"; - sprite = "PLAYA0"; - } - 14 - { - title = "Player 14 Start"; - sprite = "PLAYA0"; - } - 15 - { - title = "Player 15 Start"; - sprite = "PLAYA0"; - } - 16 - { - title = "Player 16 Start"; - sprite = "PLAYA0"; - } - 17 - { - title = "Player 17 Start"; - sprite = "PLAYA0"; - } - 18 - { - title = "Player 18 Start"; - sprite = "PLAYA0"; - } - 19 - { - title = "Player 19 Start"; - sprite = "PLAYA0"; - } - 20 - { - title = "Player 20 Start"; - sprite = "PLAYA0"; - } - 21 - { - title = "Player 21 Start"; - sprite = "PLAYA0"; - } - 22 - { - title = "Player 22 Start"; - sprite = "PLAYA0"; - } - 23 - { - title = "Player 23 Start"; - sprite = "PLAYA0"; - } - 24 - { - title = "Player 24 Start"; - sprite = "PLAYA0"; - } - 25 - { - title = "Player 25 Start"; - sprite = "PLAYA0"; - } - 26 - { - title = "Player 26 Start"; - sprite = "PLAYA0"; - } - 27 - { - title = "Player 27 Start"; - sprite = "PLAYA0"; - } - 28 - { - title = "Player 28 Start"; - sprite = "PLAYA0"; - } - 29 - { - title = "Player 29 Start"; - sprite = "PLAYA0"; - } - 30 - { - title = "Player 30 Start"; - sprite = "PLAYA0"; - } - 31 - { - title = "Player 31 Start"; - sprite = "PLAYA0"; - } - 32 - { - title = "Player 32 Start"; - sprite = "PLAYA0"; - } - 33 - { - title = "Match Start"; - sprite = "NDRNA2A8"; - } - 34 - { - title = "CTF Red Team Start"; - sprite = "SIGNG0"; - } - 35 - { - title = "CTF Blue Team Start"; - sprite = "SIGNE0"; - } - } - - enemies - { - color = 9; // Light_Blue - arrow = 1; - title = "Enemies"; - - 100 - { - title = "Crawla (Blue)"; - sprite = "POSSA1"; - width = 24; - height = 32; - } - 101 - { - title = "Crawla (Red)"; - sprite = "SPOSA1"; - width = 24; - height = 32; - } - 102 - { - title = "Stupid Dumb Unnamed RoboFish"; - sprite = "FISHA0"; - width = 8; - height = 28; - } - 103 - { - title = "Buzz (Gold)"; - sprite = "BUZZA1"; - width = 28; - height = 40; - } - 104 - { - title = "Buzz (Red)"; - sprite = "RBUZA1"; - width = 28; - height = 40; - } - 108 - { - title = "Deton"; - sprite = "DETNA1"; - width = 20; - height = 32; - } - 110 - { - title = "Turret"; - sprite = "TRETA1"; - width = 16; - height = 32; - } - 111 - { - title = "Pop-up Turret"; - sprite = "TURRI1"; - width = 12; - height = 64; - } - 122 - { - title = "Spring Shell (Green)"; - sprite = "SSHLA1"; - width = 24; - height = 40; - } - 125 - { - title = "Spring Shell (Yellow)"; - sprite = "SSHLI1"; - width = 24; - height = 40; - } - 109 - { - title = "Skim"; - sprite = "SKIMA1"; - width = 16; - height = 24; - } - 113 - { - title = "Jet Jaw"; - sprite = "JJAWA3A7"; - width = 12; - height = 20; - } - 126 - { - title = "Crushstacean"; - sprite = "CRABA0"; - width = 24; - height = 32; - } - 138 - { - title = "Banpyura"; - sprite = "CR2BA0"; - width = 24; - height = 32; - } - 117 - { - title = "Robo-Hood"; - sprite = "ARCHA1"; - width = 24; - height = 32; - } - 118 - { - title = "Lance-a-Bot"; - sprite = "CBFSA1"; - width = 32; - height = 72; - } - 1113 - { - title = "Suspicious Lance-a-Bot Statue"; - sprite = "CBBSA1"; - width = 32; - height = 72; - } - 119 - { - title = "Egg Guard"; - sprite = "ESHIA1"; - width = 16; - height = 48; - } - 115 - { - title = "Bird Aircraft Strike Hazard"; - sprite = "VLTRF1"; - width = 12; - height = 24; - } - 120 - { - title = "Green Snapper"; - sprite = "GSNPA1"; - width = 24; - height = 24; - } - 121 - { - title = "Minus"; - sprite = "MNUSA0"; - width = 24; - height = 32; - } - 134 - { - title = "Canarivore"; - sprite = "CANAA0"; - width = 12; - height = 80; - hangs = 1; - } - 123 - { - title = "Unidus"; - sprite = "UNIDA1"; - width = 18; - height = 36; - } - 135 - { - title = "Pterabyte Spawner"; - sprite = "PTERA2A8"; - width = 16; - height = 16; - } - 136 - { - title = "Pyre Fly"; - sprite = "PYREA0"; - width = 24; - height = 34; - } - 137 - { - title = "Dragonbomber"; - sprite = "DRABA1"; - width = 28; - height = 48; - } - 105 - { - title = "Jetty-Syn Bomber"; - sprite = "JETBB1"; - width = 20; - height = 50; - } - 106 - { - title = "Jetty-Syn Gunner"; - sprite = "JETGB1"; - width = 20; - height = 48; - } - 112 - { - title = "Spincushion"; - sprite = "SHRPA1"; - width = 16; - height = 24; - } - 114 - { - title = "Snailer"; - sprite = "SNLRA3A7"; - width = 24; - height = 48; - } - 129 - { - title = "Penguinator"; - sprite = "PENGA1"; - width = 24; - height = 32; - } - 130 - { - title = "Pophat"; - sprite = "POPHA1"; - width = 24; - height = 32; - } - 107 - { - title = "Crawla Commander"; - sprite = "CCOMA1"; - width = 16; - height = 32; - } - 131 - { - title = "Spinbobert"; - sprite = "SBOBB0"; - width = 32; - height = 32; - } - 132 - { - title = "Cacolantern"; - sprite = "CACOA0"; - width = 32; - height = 32; - } - 133 - { - title = "Hangster"; - sprite = "HBATC1"; - width = 24; - height = 24; - hangs = 1; - } - 127 - { - title = "Hive Elemental"; - sprite = "HIVEA0"; - width = 32; - height = 80; - } - 128 - { - title = "Bumblebore"; - sprite = "BUMBA1"; - width = 16; - height = 32; - } - 124 - { - title = "Buggle"; - sprite = "BBUZA1"; - width = 20; - height = 24; - } - 116 - { - title = "Pointy"; - sprite = "PNTYA1"; - width = 8; - height = 16; - } - } - - bosses - { - color = 8; // Dark_Gray - arrow = 1; - title = "Bosses"; - - 200 - { - title = "Egg Mobile"; - sprite = "EGGMA1"; - width = 24; - height = 76; - } - 201 - { - title = "Egg Slimer"; - sprite = "EGGNA1"; - width = 24; - height = 76; - } - 202 - { - title = "Sea Egg"; - sprite = "EGGOA1"; - width = 32; - height = 116; - } - 203 - { - title = "Egg Colosseum"; - sprite = "EGGPA1"; - width = 24; - height = 76; - } - 204 - { - title = "Fang"; - sprite = "FANGA1"; - width = 24; - height = 60; - } - 206 - { - title = "Brak Eggman (Old)"; - sprite = "BRAKB1"; - width = 48; - height = 160; - } - 207 - { - title = "Metal Sonic (Race)"; - sprite = "METLI1"; - width = 16; - height = 48; - } - 208 - { - title = "Metal Sonic (Battle)"; - sprite = "METLC1"; - width = 16; - height = 48; - } - 209 - { - title = "Brak Eggman"; - sprite = "BRAK01"; - width = 48; - height = 160; - } - 290 - { - arrow = 0; - title = "Boss Escape Point"; - width = 8; - height = 16; - sprite = "internal:eggmanend"; - } - 291 - { - arrow = 0; - title = "Egg Capsule Center"; - width = 8; - height = 16; - sprite = "internal:capsule"; - } - 292 - { - arrow = 0; - title = "Boss Waypoint"; - width = 8; - height = 16; - sprite = "internal:eggmanway"; - } - 293 - { - title = "Metal Sonic Gather Point"; - sprite = "internal:metal"; - width = 8; - height = 16; - } - 294 - { - title = "Fang Waypoint"; - sprite = "internal:eggmanway"; - width = 8; - height = 16; - } - } - - rings - { - color = 14; // Yellow - title = "Rings and Weapon Panels"; - width = 24; - height = 24; - sprite = "RINGA0"; - - 300 - { - title = "Ring"; - sprite = "RINGA0"; - width = 16; - } - 301 - { - title = "Bounce Ring"; - sprite = "internal:RNGBA0"; - } - 302 - { - title = "Rail Ring"; - sprite = "internal:RNGRA0"; - } - 303 - { - title = "Infinity Ring"; - sprite = "internal:RNGIA0"; - } - 304 - { - title = "Automatic Ring"; - sprite = "internal:RNGAA0"; - } - 305 - { - title = "Explosion Ring"; - sprite = "internal:RNGEA0"; - } - 306 - { - title = "Scatter Ring"; - sprite = "internal:RNGSA0"; - } - 307 - { - title = "Grenade Ring"; - sprite = "internal:RNGGA0"; - } - 308 - { - title = "CTF Team Ring (Red)"; - sprite = "internal:RRNGA0"; - width = 16; - } - 309 - { - title = "CTF Team Ring (Blue)"; - sprite = "internal:BRNGA0"; - width = 16; - } - 330 - { - title = "Bounce Ring Panel"; - sprite = "internal:PIKBA0"; - } - 331 - { - title = "Rail Ring Panel"; - sprite = "internal:PIKRA0"; - } - 332 - { - title = "Automatic Ring Panel"; - sprite = "internal:PIKAA0"; - } - 333 - { - title = "Explosion Ring Panel"; - sprite = "internal:PIKEA0"; - } - 334 - { - title = "Scatter Ring Panel"; - sprite = "internal:PIKSA0"; - } - 335 - { - title = "Grenade Ring Panel"; - sprite = "internal:PIKGA0"; - } - } - - collectibles - { - color = 10; // Light_Green - title = "Other Collectibles"; - width = 16; - height = 32; - sort = 1; - sprite = "CEMGA0"; - - 310 - { - title = "CTF Red Flag"; - sprite = "RFLGA0"; - width = 24; - height = 64; - } - 311 - { - title = "CTF Blue Flag"; - sprite = "BFLGA0"; - width = 24; - height = 64; - } - 312 - { - title = "Emerald Token"; - sprite = "TOKEA0"; - width = 16; - height = 32; - } - 313 - { - title = "Chaos Emerald 1 (Green)"; - sprite = "CEMGA0"; - } - 314 - { - title = "Chaos Emerald 2 (Purple)"; - sprite = "CEMGB0"; - } - 315 - { - title = "Chaos Emerald 3 (Blue)"; - sprite = "CEMGC0"; - } - 316 - { - title = "Chaos Emerald 4 (Cyan)"; - sprite = "CEMGD0"; - } - 317 - { - title = "Chaos Emerald 5 (Orange)"; - sprite = "CEMGE0"; - } - 318 - { - title = "Chaos Emerald 6 (Red)"; - sprite = "CEMGF0"; - } - 319 - { - title = "Chaos Emerald 7 (Gray)"; - sprite = "CEMGG0"; - } - 320 - { - title = "Emerald Hunt Location"; - sprite = "SHRDA0"; - } - 321 - { - title = "Match Chaos Emerald Spawn"; - sprite = "CEMGA0"; - } - 322 - { - title = "Emblem"; - sprite = "EMBMA0"; - width = 16; - height = 30; - } - } - - boxes - { - color = 7; // Gray - blocking = 2; - title = "Monitors"; - width = 18; - height = 40; - - 400 - { - title = "Super Ring (10 Rings)"; - sprite = "TVRIA0"; - } - 401 - { - title = "Pity Shield"; - sprite = "TVPIA0"; - } - 402 - { - title = "Attraction Shield"; - sprite = "TVATA0"; - } - 403 - { - title = "Force Shield"; - sprite = "TVFOA0"; - } - 404 - { - title = "Armageddon Shield"; - sprite = "TVARA0"; - } - 405 - { - title = "Whirlwind Shield"; - sprite = "TVWWA0"; - } - 406 - { - title = "Elemental Shield"; - sprite = "TVELA0"; - } - 407 - { - title = "Super Sneakers"; - sprite = "TVSSA0"; - } - 408 - { - title = "Invincibility"; - sprite = "TVIVA0"; - } - 409 - { - title = "Extra Life"; - sprite = "TV1UA0"; - } - 410 - { - title = "Eggman"; - sprite = "TVEGA0"; - } - 411 - { - title = "Teleporter"; - sprite = "TVMXA0"; - } - 413 - { - title = "Gravity Boots"; - sprite = "TVGVA0"; - } - 414 - { - title = "CTF Team Ring Monitor (Red)"; - sprite = "TRRIA0"; - } - 415 - { - title = "CTF Team Ring Monitor (Blue)"; - sprite = "TBRIA0"; - } - 416 - { - title = "Recycler"; - sprite = "TVRCA0"; - } - 418 - { - title = "Score (1,000 Points)"; - sprite = "TV1KA0"; - } - 419 - { - title = "Score (10,000 Points)"; - sprite = "TVTKA0"; - } - 420 - { - title = "Flame Shield"; - sprite = "TVFLA0"; - } - 421 - { - title = "Water Shield"; - sprite = "TVBBA0"; - } - 422 - { - title = "Lightning Shield"; - sprite = "TVZPA0"; - } - } - - boxes2 - { - color = 18; // Gold - blocking = 2; - title = "Monitors (Respawning)"; - width = 20; - height = 44; - - 431 - { - title = "Pity Shield (Respawn)"; - sprite = "TVPIB0"; - } - 432 - { - title = "Attraction Shield (Respawn)"; - sprite = "TVATB0"; - } - 433 - { - title = "Force Shield (Respawn)"; - sprite = "TVFOB0"; - } - 434 - { - title = "Armageddon Shield (Respawn)"; - sprite = "TVARB0"; - } - 435 - { - title = "Whirlwind Shield (Respawn)"; - sprite = "TVWWB0"; - } - 436 - { - title = "Elemental Shield (Respawn)"; - sprite = "TVELB0"; - } - 437 - { - title = "Super Sneakers (Respawn)"; - sprite = "TVSSB0"; - } - 438 - { - title = "Invincibility (Respawn)"; - sprite = "TVIVB0"; - } - 440 - { - title = "Eggman (Respawn)"; - sprite = "TVEGB0"; - } - 443 - { - title = "Gravity Boots (Respawn)"; - sprite = "TVGVB0"; - } - 450 - { - title = "Flame Shield (Respawn)"; - sprite = "TVFLB0"; - } - 451 - { - title = "Water Shield (Respawn)"; - sprite = "TVBBB0"; - } - 452 - { - title = "Lightning Shield (Respawn)"; - sprite = "TVZPB0"; - } - } - - generic - { - color = 11; // Light_Cyan - title = "Generic Items & Hazards"; - - 500 - { - title = "Air Bubble Patch"; - sprite = "BUBLE0"; - width = 8; - height = 16; - } - 501 - { - title = "Signpost"; - sprite = "SIGND0"; - width = 8; - height = 32; - } - 502 - { - arrow = 1; - title = "Star Post"; - sprite = "STPTA0M0"; - width = 64; - height = 128; - } - 520 - { - title = "Bomb Sphere"; - sprite = "SPHRD0"; - width = 16; - height = 24; - } - 521 - { - title = "Spikeball"; - sprite = "SPIKA0"; - width = 12; - height = 8; - } - 522 - { - title = "Wall Spike"; - sprite = "WSPKALAR"; - width = 16; - height = 14; - arrow = 1; - } - 523 - { - title = "Spike"; - sprite = "USPKA0"; - width = 8; - height = 32; - } - 1130 - { - title = "Small Mace"; - sprite = "SMCEA0"; - width = 17; - height = 34; - } - 1131 - { - title = "Big Mace"; - sprite = "BMCEA0"; - width = 34; - height = 68; - } - 1136 - { - title = "Small Fireball"; - sprite = "SFBRA0"; - width = 17; - height = 34; - } - 1137 - { - title = "Large Fireball"; - sprite = "BFBRA0"; - width = 34; - height = 68; - } - } - - springs - { - color = 12; // Light_Red - title = "Springs and Fans"; - width = 20; - height = 16; - sprite = "RSPRD2"; - - 540 - { - title = "Fan"; - sprite = "FANSA0D0"; - width = 16; - height = 8; - } - 541 - { - title = "Gas Jet"; - sprite = "STEMD0"; - width = 32; - } - 542 - { - title = "Bumper"; - sprite = "BUMPA0"; - width = 32; - height = 64; - } - 543 - { - title = "Balloon"; - sprite = "BLONA0"; - width = 32; - height = 64; - } - 550 - { - title = "Yellow Spring"; - sprite = "SPRYA0"; - } - 551 - { - title = "Red Spring"; - sprite = "SPRRA0"; - } - 552 - { - title = "Blue Spring"; - sprite = "SPRBA0"; - } - 555 - { - arrow = 1; - title = "Diagonal Yellow Spring"; - sprite = "YSPRD2"; - width = 16; - } - 556 - { - arrow = 1; - title = "Diagonal Red Spring"; - sprite = "RSPRD2"; - width = 16; - } - 557 - { - arrow = 1; - title = "Diagonal Blue Spring"; - sprite = "BSPRD2"; - width = 16; - } - 558 - { - arrow = 1; - title = "Horizontal Yellow Spring"; - sprite = "SSWYD2D8"; - width = 16; - height = 32; - } - 559 - { - arrow = 1; - title = "Horizontal Red Spring"; - sprite = "SSWRD2D8"; - width = 16; - height = 32; - } - 560 - { - arrow = 1; - title = "Horizontal Blue Spring"; - sprite = "SSWBD2D8"; - width = 16; - height = 32; - } - 1134 - { - title = "Yellow Spring Ball"; - sprite = "YSPBA0"; - width = 17; - height = 34; - } - 1135 - { - title = "Red Spring Ball"; - sprite = "RSPBA0"; - width = 17; - height = 34; - } - 544 - { - arrow = 1; - title = "Yellow Boost Panel"; - sprite = "BSTYA0"; - width = 28; - height = 2; - } - 545 - { - arrow = 1; - title = "Red Boost Panel"; - sprite = "BSTRA0"; - width = 28; - height = 2; - } - } - - patterns - { - color = 5; // Magenta - arrow = 1; - title = "Special Placement Patterns"; - width = 16; - height = 384; - sprite = "RINGA0"; - - 600 - { - arrow = 0; - title = "5 Vertical Rings (Yellow Spring)"; - sprite = "RINGA0"; - } - 601 - { - arrow = 0; - title = "5 Vertical Rings (Red Spring)"; - sprite = "RINGA0"; - height = 1024; - } - 602 - { - title = "5 Diagonal Rings (Yellow Spring)"; - sprite = "RINGA0"; - height = 32; - } - 603 - { - title = "10 Diagonal Rings (Red Spring)"; - sprite = "RINGA0"; - height = 32; - } - 604 - { - title = "Circle of Rings"; - sprite = "RINGA0"; - width = 96; - height = 192; - } - 605 - { - title = "Circle of Rings (Big)"; - sprite = "RINGA0"; - width = 192; - } - 606 - { - title = "Circle of Blue Spheres"; - sprite = "SPHRA0"; - width = 96; - height = 192; - } - 607 - { - title = "Circle of Blue Spheres (Big)"; - sprite = "SPHRA0"; - width = 192; - } - 608 - { - title = "Circle of Rings and Spheres"; - sprite = "SPHRA0"; - width = 96; - height = 192; - } - 609 - { - title = "Circle of Rings and Spheres (Big)"; - sprite = "SPHRA0"; - width = 192; - } - } - - invisible - { - color = 15; // White - title = "Misc. Invisible"; - width = 0; - height = 0; - sprite = "UNKNA0"; - sort = 1; - fixedsize = true; - blocking = 0; - - 700 - { - title = "Water Ambience A (Large)"; - sprite = "internal:ambiance"; - } - - 701 - { - title = "Water Ambience B (Large)"; - sprite = "internal:ambiance"; - } - - 702 - { - title = "Water Ambience C (Medium)"; - sprite = "internal:ambiance"; - } - - 703 - { - title = "Water Ambience D (Medium)"; - sprite = "internal:ambiance"; - } - - 704 - { - title = "Water Ambience E (Small)"; - sprite = "internal:ambiance"; - } - - 705 - { - title = "Water Ambience F (Small)"; - sprite = "internal:ambiance"; - } - - 706 - { - title = "Water Ambience G (Extra Large)"; - sprite = "internal:ambiance"; - } - - 707 - { - title = "Water Ambience H (Extra Large)"; - sprite = "internal:ambiance"; - } - - 708 - { - title = "Disco Ambience"; - sprite = "internal:ambiance"; - } - - 709 - { - title = "Volcano Ambience"; - sprite = "internal:ambiance"; - } - - 710 - { - title = "Machine Ambience"; - sprite = "internal:ambiance"; - } - - 750 - { - title = "Slope Vertex"; - sprite = "internal:vertexslope"; - } - - 751 - { - arrow = 1; - title = "Teleport Destination"; - sprite = "internal:tele"; - } - - 752 - { - arrow = 1; - title = "Alternate View Point"; - sprite = "internal:view"; - } - - 753 - { - title = "Zoom Tube Waypoint"; - sprite = "internal:zoom"; - } - - 754 - { - title = "Push Point"; - sprite = "GWLGA0"; - } - 755 - { - title = "Pull Point"; - sprite = "GWLRA0"; - } - 756 - { - title = "Blast Linedef Executor"; - sprite = "TOADA0"; - width = 32; - height = 16; - } - 757 - { - title = "Fan Particle Generator"; - sprite = "PRTLA0"; - width = 8; - height = 16; - } - 758 - { - title = "Object Angle Anchor"; - sprite = "internal:view"; - } - 760 - { - title = "PolyObject Anchor"; - sprite = "internal:polyanchor"; - } - 761 - { - title = "PolyObject Spawn Point"; - sprite = "internal:polycenter"; - } - 762 - { - title = "PolyObject Spawn Point (Crush)"; - sprite = "internal:polycentercrush"; - } - 780 - { - title = "Skybox View Point"; - sprite = "internal:skyb"; - } - } - - greenflower - { - color = 10; // Green - title = "Greenflower"; - - 800 - { - title = "GFZ Flower"; - sprite = "FWR1A0"; - width = 16; - height = 40; - } - 801 - { - title = "Sunflower"; - sprite = "FWR2A0"; - width = 16; - height = 96; - } - 802 - { - title = "Budding Flower"; - sprite = "FWR3A0"; - width = 8; - height = 32; - } - 803 - { - title = "Blueberry Bush"; - sprite = "BUS3A0"; - width = 16; - height = 32; - } - 804 - { - title = "Berry Bush"; - sprite = "BUS1A0"; - width = 16; - height = 32; - } - 805 - { - title = "Bush"; - sprite = "BUS2A0"; - width = 16; - height = 32; - } - 806 - { - title = "GFZ Tree"; - sprite = "TRE1A0"; - width = 20; - height = 128; - } - 807 - { - title = "GFZ Berry Tree"; - sprite = "TRE1B0"; - width = 20; - height = 128; - } - 808 - { - title = "GFZ Cherry Tree"; - sprite = "TRE1C0"; - width = 20; - height = 128; - } - 809 - { - title = "Checkered Tree"; - sprite = "TRE2A0"; - width = 20; - height = 200; - } - 810 - { - title = "Checkered Tree (Sunset)"; - sprite = "TRE2B0"; - width = 20; - height = 200; - } - 811 - { - title = "Polygon Tree"; - sprite = "TRE4A0"; - width = 20; - height = 200; - } - 812 - { - title = "Bush Tree"; - sprite = "TRE5A0"; - width = 20; - height = 200; - } - 813 - { - title = "Red Bush Tree"; - sprite = "TRE5B0"; - width = 20; - height = 200; - } - } - - technohill - { - color = 10; // Green - title = "Techno Hill"; - - 900 - { - title = "THZ Steam Flower"; - sprite = "THZPA0"; - width = 8; - height = 32; - } - 901 - { - title = "Alarm"; - sprite = "ALRMA0"; - width = 8; - height = 16; - hangs = 1; - } - 902 - { - title = "THZ Spin Flower (Red)"; - sprite = "FWR5A0"; - width = 16; - height = 64; - } - 903 - { - title = "THZ Spin Flower (Yellow)"; - sprite = "FWR6A0"; - width = 16; - height = 64; - } - 904 - { - arrow = 1; - title = "Whistlebush"; - sprite = "THZTA0"; - width = 16; - height = 64; - } - } - - deepsea - { - color = 10; // Green - title = "Deep Sea"; - - 1000 - { - arrow = 1; - blocking = 2; - title = "Gargoyle"; - sprite = "GARGA1"; - width = 16; - height = 40; - } - 1009 - { - arrow = 1; - blocking = 2; - title = "Gargoyle (Big)"; - sprite = "GARGB1"; - width = 32; - height = 80; - } - 1001 - { - title = "Seaweed"; - sprite = "SEWEA0"; - width = 24; - height = 56; - } - 1002 - { - title = "Dripping Water"; - sprite = "DRIPD0"; - width = 8; - height = 16; - hangs = 1; - } - 1003 - { - title = "Coral (Green)"; - sprite = "CORLA0"; - width = 29; - height = 40; - } - 1004 - { - title = "Coral (Red)"; - sprite = "CORLB0"; - width = 30; - height = 53; - } - 1005 - { - title = "Coral (Orange)"; - sprite = "CORLC0"; - width = 28; - height = 41; - } - 1006 - { - title = "Blue Crystal"; - sprite = "BCRYA1"; - width = 8; - height = 16; - } - 1007 - { - title = "Kelp"; - sprite = "KELPA0"; - width = 16; - height = 292; - } - 1008 - { - title = "Stalagmite (DSZ1)"; - sprite = "DSTGA0"; - width = 8; - height = 116; - } - 1010 - { - arrow = 1; - title = "Light Beam"; - sprite = "LIBEARAL"; - width = 16; - height = 16; - } - 1011 - { - title = "Stalagmite (DSZ2)"; - sprite = "DSTGA0"; - width = 8; - height = 116; - } - 1012 - { - arrow = 1; - title = "Big Floating Mine"; - width = 28; - height = 56; - sprite = "BMNEA1"; - } - 1013 - { - title = "Animated Kelp"; - sprite = "ALGAA0"; - width = 48; - height = 120; - } - 1014 - { - title = "Large Coral (Brown)"; - sprite = "CORLD0"; - width = 56; - height = 112; - } - 1015 - { - title = "Large Coral (Beige)"; - sprite = "CORLE0"; - width = 56; - height = 112; - } - } - - castleeggman - { - color = 10; // Green - title = "Castle Eggman"; - - 1100 - { - title = "Chain (Decorative)"; - sprite = "CHANA0"; - width = 4; - height = 128; - hangs = 1; - } - 1101 - { - title = "Torch"; - sprite = "FLAMA0E0"; - width = 8; - height = 32; - } - 1102 - { - arrow = 1; - blocking = 2; - title = "Eggman Statue"; - sprite = "ESTAA1"; - width = 32; - height = 240; - } - 1103 - { - title = "CEZ Flower"; - sprite = "FWR4A0"; - width = 16; - height = 40; - } - 1104 - { - title = "Mace Spawnpoint"; - sprite = "SMCEA0"; - width = 17; - height = 34; - } - 1105 - { - title = "Chain with Maces Spawnpoint"; - sprite = "SMCEA0"; - width = 17; - height = 34; - } - 1106 - { - title = "Chained Spring Spawnpoint"; - sprite = "YSPBA0"; - width = 17; - height = 34; - } - 1107 - { - title = "Chain Spawnpoint"; - sprite = "BMCHA0"; - width = 17; - height = 34; - } - 1108 - { - arrow = 1; - title = "Hidden Chain Spawnpoint"; - sprite = "internal:chain3"; - width = 17; - height = 34; - } - 1109 - { - title = "Firebar Spawnpoint"; - sprite = "BFBRA0"; - width = 17; - height = 34; - } - 1110 - { - title = "Custom Mace Spawnpoint"; - sprite = "SMCEA0"; - width = 17; - height = 34; - } - 1111 - { - arrow = 1; - blocking = 2; - title = "Crawla Statue"; - sprite = "CSTAA1"; - width = 16; - height = 40; - } - 1112 - { - arrow = 1; - blocking = 2; - title = "Lance-a-Bot Statue"; - sprite = "CBBSA1"; - width = 32; - height = 72; - } - 1114 - { - title = "Pine Tree"; - sprite = "PINEA0"; - width = 16; - height = 628; - } - 1115 - { - title = "CEZ Shrub (Small)"; - sprite = "CEZBA0"; - width = 16; - height = 24; - } - 1116 - { - title = "CEZ Shrub (Large)"; - sprite = "CEZBB0"; - width = 32; - height = 48; - } - 1117 - { - arrow = 1; - title = "Pole Banner (Red)"; - sprite = "BANRA0"; - width = 40; - height = 224; - } - 1118 - { - arrow = 1; - title = "Pole Banner (Blue)"; - sprite = "BANRA0"; - width = 40; - height = 224; - } - 1119 - { - title = "Candle"; - sprite = "CNDLA0"; - width = 8; - height = 48; - } - 1120 - { - title = "Candle Pricket"; - sprite = "CNDLB0"; - width = 8; - height = 176; - } - 1121 - { - title = "Flame Holder"; - sprite = "FLMHA0"; - width = 24; - height = 80; - } - 1122 - { - title = "Fire Torch"; - sprite = "CTRCA0"; - width = 16; - height = 80; - } - 1123 - { - title = "Cannonball Launcher"; - sprite = "internal:cannonball"; - width = 8; - height = 16; - } - 1124 - { - blocking = 2; - title = "Cannonball"; - sprite = "CBLLA0"; - width = 20; - height = 40; - } - 1125 - { - title = "Brambles"; - sprite = "CABRALAR"; - width = 48; - height = 32; - } - 1126 - { - title = "Invisible Lockon Object"; - sprite = "LCKNC0"; - width = 16; - height = 32; - } - 1127 - { - title = "Spectator Eggrobo"; - sprite = "EGR1A1"; - width = 20; - height = 72; - } - 1128 - { - arrow = 1; - title = "Waving Flag (Red)"; - sprite = "CFLGA0"; - width = 8; - height = 208; - } - 1129 - { - arrow = 1; - title = "Waving Flag (Blue)"; - sprite = "CFLGA0"; - width = 8; - height = 208; - } - } - - aridcanyon - { - color = 10; // Green - title = "Arid Canyon"; - - 1200 - { - title = "Tumbleweed (Big)"; - sprite = "BTBLA0"; - width = 24; - height = 48; - } - 1201 - { - title = "Tumbleweed (Small)"; - sprite = "STBLA0"; - width = 12; - height = 24; - } - 1202 - { - arrow = 1; - title = "Rock Spawner"; - sprite = "ROIAA0"; - width = 8; - height = 16; - } - 1203 - { - title = "Tiny Red Flower Cactus"; - sprite = "CACTA0"; - width = 13; - height = 24; - } - 1204 - { - title = "Small Red Flower Cactus"; - sprite = "CACTB0"; - width = 15; - height = 52; - } - 1205 - { - title = "Tiny Blue Flower Cactus"; - sprite = "CACTC0"; - width = 13; - height = 24; - } - 1206 - { - title = "Small Blue Flower Cactus"; - sprite = "CACTD0"; - width = 15; - height = 52; - } - 1207 - { - title = "Prickly Pear"; - sprite = "CACTE0"; - width = 32; - height = 96; - } - 1208 - { - title = "Barrel Cactus"; - sprite = "CACTF0"; - width = 20; - height = 128; - } - 1209 - { - title = "Tall Barrel Cactus"; - sprite = "CACTG0"; - width = 24; - height = 224; - } - 1210 - { - title = "Armed Cactus"; - sprite = "CACTH0"; - width = 24; - height = 256; - } - 1211 - { - title = "Ball Cactus"; - sprite = "CACTI0"; - width = 48; - height = 96; - } - 1212 - { - title = "Caution Sign"; - sprite = "WWSGAR"; - width = 22; - height = 64; - } - 1213 - { - title = "Cacti Sign"; - sprite = "WWS2AR"; - width = 22; - height = 64; - } - 1214 - { - title = "Sharp Turn Sign"; - sprite = "WWS3ALAR"; - width = 16; - height = 192; - } - 1215 - { - title = "Mine Oil Lamp"; - sprite = "OILLA0"; - width = 22; - height = 64; - hangs = 1; - } - 1216 - { - title = "TNT Barrel"; - sprite = "BARRA1"; - width = 24; - height = 63; - } - 1217 - { - title = "TNT Proximity Shell"; - sprite = "REMTA0"; - width = 64; - height = 40; - } - 1218 - { - title = "Dust Devil"; - sprite = "TAZDCR"; - width = 80; - height = 416; - } - 1219 - { - title = "Minecart Spawner"; - sprite = "MCRTCLFR"; - width = 22; - height = 32; - } - 1220 - { - title = "Minecart Stopper"; - sprite = "MCRTIR"; - width = 32; - height = 32; - } - 1221 - { - title = "Minecart Saloon Door"; - sprite = "SALDARAL"; - width = 96; - height = 160; - } - 1222 - { - title = "Train Cameo Spawner"; - sprite = "TRAEBRBL"; - width = 28; - height = 32; - } - 1223 - { - title = "Train Dust Spawner"; - sprite = "ADSTA0"; - width = 4; - height = 4; - } - 1224 - { - title = "Train Steam Spawner"; - sprite = "STEAA0"; - width = 4; - height = 4; - } - 1229 - { - title = "Minecart Switch Point"; - sprite = "internal:zoom"; - width = 8; - height = 16; - } - 1230 - { - title = "Tiny Cactus"; - sprite = "CACTJ0"; - width = 13; - height = 28; - } - 1231 - { - title = "Small Cactus"; - sprite = "CACTK0"; - width = 15; - height = 60; - } - } - - redvolcano - { - color = 10; // Green - title = "Red Volcano"; - - 1300 - { - arrow = 1; - title = "Flame Jet (Horizontal)"; - sprite = "internal:flameh"; - width = 16; - height = 40; - } - 1301 - { - title = "Flame Jet (Vertical)"; - sprite = "internal:flamev"; - width = 16; - height = 40; - } - 1302 - { - title = "Spinning Flame Jet (Counter-Clockwise)"; - sprite = "internal:flame2"; - width = 16; - height = 24; - } - 1303 - { - title = "Spinning Flame Jet (Clockwise)"; - sprite = "internal:flame1"; - width = 16; - height = 24; - } - 1304 - { - title = "Lavafall"; - sprite = "LFALF0"; - width = 30; - height = 32; - } - 1305 - { - title = "Rollout Rock"; - sprite = "PUMIA1A5"; - width = 30; - height = 60; - } - 1306 - { - title = "Big Fern"; - sprite = "JPLAB0"; - width = 32; - height = 48; - } - 1307 - { - title = "Jungle Palm"; - sprite = "JPLAC0"; - width = 32; - height = 48; - } - 1308 - { - title = "Torch Flower"; - sprite = "TFLOA0"; - width = 14; - height = 110; - } - 1309 - { - title = "RVZ1 Wall Vine (Long)"; - sprite = "WVINALAR"; - width = 1; - height = 288; - } - 1310 - { - title = "RVZ1 Wall Vine (Short)"; - sprite = "WVINBLBR"; - width = 1; - height = 288; - } - } - - botanicserenity - { - color = 10; // Green - title = "Botanic Serenity"; - width = 16; - height = 32; - sprite = "BSZ1A0"; - 1400 - { - title = "Tall Flower (Red)"; - sprite = "BSZ1A0"; - } - 1401 - { - title = "Tall Flower (Purple)"; - sprite = "BSZ1B0"; - } - 1402 - { - title = "Tall Flower (Blue)"; - sprite = "BSZ1C0"; - } - 1403 - { - title = "Tall Flower (Cyan)"; - sprite = "BSZ1D0"; - } - 1404 - { - title = "Tall Flower (Yellow)"; - sprite = "BSZ1E0"; - } - 1405 - { - title = "Tall Flower (Orange)"; - sprite = "BSZ1F0"; - } - 1410 - { - title = "Medium Flower (Red)"; - sprite = "BSZ2A0"; - } - 1411 - { - title = "Medium Flower (Purple)"; - sprite = "BSZ2B0"; - } - 1412 - { - title = "Medium Flower (Blue)"; - sprite = "BSZ2C0"; - } - 1413 - { - title = "Medium Flower (Cyan)"; - sprite = "BSZ2D0"; - } - 1414 - { - title = "Medium Flower (Yellow)"; - sprite = "BSZ2E0"; - } - 1415 - { - title = "Medium Flower (Orange)"; - sprite = "BSZ2F0"; - } - 1420 - { - title = "Short Flower (Red)"; - sprite = "BSZ3A0"; - } - 1421 - { - title = "Short Flower (Purple)"; - sprite = "BSZ3B0"; - } - 1422 - { - title = "Short Flower (Blue)"; - sprite = "BSZ3C0"; - } - 1423 - { - title = "Short Flower (Cyan)"; - sprite = "BSZ3D0"; - } - 1424 - { - title = "Short Flower (Yellow)"; - sprite = "BSZ3E0"; - } - 1425 - { - title = "Short Flower (Orange)"; - sprite = "BSZ3F0"; - } - 1430 - { - title = "Tulip (Red)"; - sprite = "BST1A0"; - } - 1431 - { - title = "Tulip (Purple)"; - sprite = "BST2A0"; - } - 1432 - { - title = "Tulip (Blue)"; - sprite = "BST3A0"; - } - 1433 - { - title = "Tulip (Cyan)"; - sprite = "BST4A0"; - } - 1434 - { - title = "Tulip (Yellow)"; - sprite = "BST5A0"; - } - 1435 - { - title = "Tulip (Orange)"; - sprite = "BST6A0"; - } - 1440 - { - title = "Cluster (Red)"; - sprite = "BSZ5A0"; - } - 1441 - { - title = "Cluster (Purple)"; - sprite = "BSZ5B0"; - } - 1442 - { - title = "Cluster (Blue)"; - sprite = "BSZ5C0"; - } - 1443 - { - title = "Cluster (Cyan)"; - sprite = "BSZ5D0"; - } - 1444 - { - title = "Cluster (Yellow)"; - sprite = "BSZ5E0"; - } - 1445 - { - title = "Cluster (Orange)"; - sprite = "BSZ5F0"; - } - 1450 - { - title = "Bush (Red)"; - sprite = "BSZ6A0"; - } - 1451 - { - title = "Bush (Purple)"; - sprite = "BSZ6B0"; - } - 1452 - { - title = "Bush (Blue)"; - sprite = "BSZ6C0"; - } - 1453 - { - title = "Bush (Cyan)"; - sprite = "BSZ6D0"; - } - 1454 - { - title = "Bush (Yellow)"; - sprite = "BSZ6E0"; - } - 1455 - { - title = "Bush (Orange)"; - sprite = "BSZ6F0"; - } - 1460 - { - title = "Vine (Red)"; - sprite = "BSZ7A0"; - } - 1461 - { - title = "Vine (Purple)"; - sprite = "BSZ7B0"; - } - 1462 - { - title = "Vine (Blue)"; - sprite = "BSZ7C0"; - } - 1463 - { - title = "Vine (Cyan)"; - sprite = "BSZ7D0"; - } - 1464 - { - title = "Vine (Yellow)"; - sprite = "BSZ7E0"; - } - 1465 - { - title = "Vine (Orange)"; - sprite = "BSZ7F0"; - } - 1470 - { - title = "BSZ Shrub"; - sprite = "BSZ8A0"; - } - 1471 - { - title = "BSZ Clover"; - sprite = "BSZ8B0"; - } - 1473 - { - title = "Palm Tree (Big)"; - width = 16; - height = 160; - sprite = "BSZ8D0"; - } - 1475 - { - title = "Palm Tree (Small)"; - width = 16; - height = 80; - sprite = "BSZ8F0"; - } - } - - azuretemple - { - color = 10; // Green - title = "Azure Temple"; - - 1500 - { - arrow = 1; - blocking = 2; - title = "Glaregoyle"; - sprite = "BGARA1"; - width = 16; - height = 40; - } - 1501 - { - arrow = 1; - blocking = 2; - title = "Glaregoyle (Up)"; - sprite = "BGARA1"; - width = 16; - height = 40; - } - 1502 - { - arrow = 1; - blocking = 2; - title = "Glaregoyle (Down)"; - sprite = "BGARA1"; - width = 16; - height = 40; - } - 1503 - { - arrow = 1; - blocking = 2; - title = "Glaregoyle (Long)"; - sprite = "BGARA1"; - width = 16; - height = 40; - } - 1504 - { - title = "ATZ Target"; - sprite = "RCRYB0"; - width = 24; - height = 32; - } - 1505 - { - title = "Green Flame"; - sprite = "CFLMA0E0"; - width = 8; - height = 32; - } - 1506 - { - arrow = 1; - blocking = 2; - title = "Blue Gargoyle"; - sprite = "BGARD1"; - width = 16; - height = 40; - } - } - - dreamhill - { - color = 10; // Green - title = "Dream Hill"; - - 1600 - { - title = "Spring Tree"; - sprite = "TRE6A0"; - width = 16; - height = 32; - } - 1601 - { - title = "Shleep"; - sprite = "SHLPA0"; - width = 24; - height = 32; - } - 1602 - { - title = "Nightopian"; - sprite = "NTPNA1"; - width = 16; - height = 40; - } - } - - nightstrk - { - color = 13; // Pink - title = "NiGHTS Track"; - width = 8; - height = 4096; - sprite = "UNKNA0"; - - 1700 - { - title = "Axis"; - sprite = "internal:axis1"; - circle = 1; - } - 1701 - { - title = "Axis Transfer"; - sprite = "internal:axis2"; - } - 1702 - { - title = "Axis Transfer Line"; - sprite = "internal:axis3"; - } - 1710 - { - title = "Ideya Capture"; - sprite = "CAPSA0"; - width = 72; - height = 144; - } - } - - nights - { - color = 13; // Pink - title = "NiGHTS Items"; - width = 16; - height = 32; - - 1703 - { - title = "Ideya Drone"; - sprite = "NDRNA1"; - width = 16; - height = 56; - } - 1704 - { - arrow = 1; - title = "NiGHTS Bumper"; - sprite = "NBMPG3G7"; - width = 32; - height = 64; - } - 1705 - { - arrow = 1; - title = "Hoop (Generic)"; - sprite = "HOOPA0"; - width = 80; - height = 160; - } - 1706 - { - title = "Blue Sphere"; - sprite = "SPHRA0"; - width = 16; - height = 24; - } - 1707 - { - title = "Super Paraloop"; - sprite = "NPRUA0"; - } - 1708 - { - title = "Drill Refill"; - sprite = "NPRUB0"; - } - 1709 - { - title = "Nightopian Helper"; - sprite = "NPRUC0"; - } - 1711 - { - title = "Extra Time"; - sprite = "NPRUD0"; - } - 1712 - { - title = "Link Freeze"; - sprite = "NPRUE0"; - } - 1713 - { - arrow = 1; - title = "Hoop (Customizable)"; - sprite = "HOOPA0"; - width = 80; - height = 160; - } - 1714 - { - title = "Ideya Anchor Point"; - sprite = "internal:axis1"; - width = 8; - height = 16; - } - } - - mario - { - color = 6; // Brown - title = "Mario"; - - 1800 - { - title = "Coin"; - sprite = "COINA0"; - width = 16; - height = 24; - } - 1801 - { - arrow = 1; - title = "Goomba"; - sprite = "GOOMA0"; - width = 24; - height = 32; - } - 1802 - { - arrow = 1; - title = "Goomba (Blue)"; - sprite = "BGOMA0"; - width = 24; - height = 32; - } - 1803 - { - title = "Fire Flower"; - sprite = "FFWRB0"; - width = 16; - height = 32; - } - 1804 - { - title = "Koopa Shell"; - sprite = "SHLLA1"; - width = 16; - height = 20; - } - 1805 - { - title = "Puma (Jumping Fireball)"; - sprite = "PUMAA0"; - width = 8; - height = 16; - } - 1806 - { - title = "King Bowser"; - sprite = "KOOPA0"; - width = 16; - height = 48; - } - 1807 - { - title = "Axe"; - sprite = "MAXEA0"; - width = 8; - height = 16; - } - 1808 - { - title = "Bush (Short)"; - sprite = "MUS1A0"; - width = 16; - height = 32; - } - 1809 - { - title = "Bush (Tall)"; - sprite = "MUS2A0"; - width = 16; - height = 32; - } - 1810 - { - title = "Toad"; - sprite = "TOADA0"; - width = 8; - height = 32; - } - } - - christmasdisco - { - color = 10; // Green - title = "Christmas & Disco"; - - 1850 - { - title = "Christmas Pole"; - sprite = "XMS1A0"; - width = 16; - height = 40; - } - 1851 - { - title = "Candy Cane"; - sprite = "XMS2A0"; - width = 8; - height = 32; - } - 1852 - { - blocking = 2; - title = "Snowman"; - sprite = "XMS3A0"; - width = 16; - height = 64; - } - 1853 - { - blocking = 2; - title = "Snowman (With Hat)"; - sprite = "XMS3B0"; - width = 16; - height = 80; - } - 1854 - { - title = "Lamp Post"; - sprite = "XMS4A0"; - width = 8; - height = 120; - } - 1855 - { - title = "Lamp Post (Snow)"; - sprite = "XMS4B0"; - width = 8; - height = 120; - } - 1856 - { - title = "Hanging Star"; - sprite = "XMS5A0"; - width = 4; - height = 80; - hangs = 1; - } - 1857 - { - title = "Berry Bush (Snow)"; - sprite = "BUS1B0"; - width = 16; - height = 32; - } - 1858 - { - title = "Bush (Snow)"; - sprite = "BUS2B0"; - width = 16; - height = 32; - } - 1859 - { - title = "Blueberry Bush (Snow)"; - sprite = "BUS3B0"; - width = 16; - height = 32; - } - 1875 - { - title = "Disco Ball"; - sprite = "DBALA0"; - width = 16; - height = 54; - hangs = 1; - } - 1876 - { - arrow = 1; - blocking = 2; - title = "Eggman Disco Statue"; - sprite = "ESTAB1"; - width = 20; - height = 96; - } - } - - stalagmites - { - color = 10; // Green - title = "Stalagmites"; - width = 16; - height = 40; - - 1900 - { - title = "Brown Stalagmite (Tall)"; - sprite = "STLGA0"; - width = 16; - height = 40; - } - 1901 - { - title = "Brown Stalagmite"; - sprite = "STLGB0"; - width = 16; - height = 40; - } - 1902 - { - title = "Orange Stalagmite (Tall)"; - sprite = "STLGC0"; - width = 16; - height = 40; - } - 1903 - { - title = "Orange Stalagmite"; - sprite = "STLGD0"; - width = 16; - height = 40; - } - 1904 - { - title = "Red Stalagmite (Tall)"; - sprite = "STLGE0"; - width = 16; - height = 40; - } - 1905 - { - title = "Red Stalagmite"; - sprite = "STLGF0"; - width = 16; - height = 40; - } - 1906 - { - title = "Gray Stalagmite (Tall)"; - sprite = "STLGG0"; - width = 24; - height = 96; - } - 1907 - { - title = "Gray Stalagmite"; - sprite = "STLGH0"; - width = 16; - height = 40; - } - 1908 - { - title = "Blue Stalagmite (Tall)"; - sprite = "STLGI0"; - width = 16; - height = 40; - } - 1909 - { - title = "Blue Stalagmite"; - sprite = "STLGJ0"; - width = 16; - height = 40; - } - } - - hauntedheights - { - color = 10; // Green - title = "Haunted Heights"; - - 2000 - { - title = "Smashing Spikeball"; - sprite = "FMCEA0"; - width = 18; - height = 28; - } - 2001 - { - title = "HHZ Grass"; - sprite = "HHZMA0"; - width = 16; - height = 40; - } - 2002 - { - title = "HHZ Tentacle 1"; - sprite = "HHZMB0"; - width = 16; - height = 40; - } - 2003 - { - title = "HHZ Tentacle 2"; - sprite = "HHZMC0"; - width = 16; - height = 40; - } - 2004 - { - title = "HHZ Stalagmite (Tall)"; - sprite = "HHZME0"; - width = 16; - height = 40; - } - 2005 - { - title = "HHZ Stalagmite (Short)"; - sprite = "HHZMF0"; - width = 16; - height = 40; - } - 2006 - { - title = "Jack-o'-lantern 1"; - sprite = "PUMKA0"; - width = 16; - height = 40; - } - 2007 - { - title = "Jack-o'-lantern 2"; - sprite = "PUMKB0"; - width = 16; - height = 40; - } - 2008 - { - title = "Jack-o'-lantern 3"; - sprite = "PUMKC0"; - width = 16; - height = 40; - } - 2009 - { - title = "Purple Mushroom"; - sprite = "SHRMD0"; - width = 16; - height = 48; - } - 2010 - { - title = "HHZ Tree"; - sprite = "HHPLC0"; - width = 12; - height = 40; - } - } - - frozenhillside - { - color = 10; // Green - title = "Frozen Hillside"; - - 2100 - { - title = "Ice Shard (Small)"; - sprite = "FHZIA0"; - width = 8; - height = 32; - } - 2101 - { - title = "Ice Shard (Large)"; - sprite = "FHZIB0"; - width = 8; - height = 32; - } - 2102 - { - title = "Crystal Tree (Aqua)"; - sprite = "TRE3A0"; - width = 20; - height = 200; - } - 2103 - { - title = "Crystal Tree (Pink)"; - sprite = "TRE3B0"; - width = 20; - height = 200; - } - 2104 - { - title = "Amy Cameo"; - sprite = "ROSYA1"; - width = 16; - height = 48; - } - 2105 - { - title = "Mistletoe"; - sprite = "XMS6A0"; - width = 52; - height = 106; - } - } - - tutorial - { - color = 10; // Green - title = "Tutorial"; - - 799 - { - title = "Tutorial Plant"; - sprite = "TUPFH0"; - width = 40; - height = 144; - } - } - - flickies - { - color = 10; // Green - title = "Flickies"; - width = 8; - height = 20; - - 2200 - { - title = "Bluebird"; - sprite = "FL01A1"; - } - 2201 - { - title = "Rabbit"; - sprite = "FL02A1"; - } - 2202 - { - title = "Chicken"; - sprite = "FL03A1"; - } - 2203 - { - title = "Seal"; - sprite = "FL04A1"; - } - 2204 - { - title = "Pig"; - sprite = "FL05A1"; - } - 2205 - { - title = "Chipmunk"; - sprite = "FL06A1"; - } - 2206 - { - title = "Penguin"; - sprite = "FL07A1"; - } - 2207 - { - title = "Fish"; - sprite = "FL08A1"; - } - 2208 - { - title = "Ram"; - sprite = "FL09A1"; - } - 2209 - { - title = "Puffin"; - sprite = "FL10A1"; - } - 2210 - { - title = "Cow"; - sprite = "FL11A1"; - } - 2211 - { - title = "Rat"; - sprite = "FL12A1"; - } - 2212 - { - title = "Bear"; - sprite = "FL13A1"; - } - 2213 - { - title = "Dove"; - sprite = "FL14A1"; - } - 2214 - { - title = "Cat"; - sprite = "FL15A1"; - } - 2215 - { - title = "Canary"; - sprite = "FL16A1"; - } - 2216 - { - title = "Spider"; - sprite = "FS01A1"; - } - 2217 - { - title = "Bat"; - sprite = "FS02A0"; - } - } -} - udmf { - editor - { - color = 15; // White - arrow = 1; - title = ""; - error = -1; - width = 8; - height = 16; - sort = 1; - - 3328 = "3D Mode Start"; - } starts { @@ -3974,7 +807,7 @@ udmf bosses { - color = 8; // Dark_Gray + color = 4; // Dark Red arrow = 1; title = "Bosses"; @@ -4355,95 +1188,185 @@ udmf width = 24; height = 24; sprite = "RINGA0"; - arg0 - { - title = "Float?"; - type = 11; - enum = "yesno"; - } 300 { title = "Ring"; sprite = "RINGA0"; width = 16; + arg0 + { + title = "Float?"; + type = 11; + enum = "yesno"; + } } 301 { title = "Bounce Ring"; - sprite = "internal:RNGBA0"; + sprite = "RNGBA0"; + arg0 + { + title = "Float?"; + type = 11; + enum = "yesno"; + } } 302 { title = "Rail Ring"; - sprite = "internal:RNGRA0"; + sprite = "RNGRA0"; + arg0 + { + title = "Float?"; + type = 11; + enum = "yesno"; + } } 303 { title = "Infinity Ring"; - sprite = "internal:RNGIA0"; + sprite = "RNGIA0"; + arg0 + { + title = "Float?"; + type = 11; + enum = "yesno"; + } } 304 { title = "Automatic Ring"; - sprite = "internal:RNGAA0"; + sprite = "RNGAA0"; + arg0 + { + title = "Float?"; + type = 11; + enum = "yesno"; + } } 305 { title = "Explosion Ring"; - sprite = "internal:RNGEA0"; + sprite = "RNGEA0"; + arg0 + { + title = "Float?"; + type = 11; + enum = "yesno"; + } } 306 { title = "Scatter Ring"; - sprite = "internal:RNGSA0"; + sprite = "RNGSA0"; + arg0 + { + title = "Float?"; + type = 11; + enum = "yesno"; + } } 307 { title = "Grenade Ring"; - sprite = "internal:RNGGA0"; + sprite = "RNGGA0"; + arg0 + { + title = "Float?"; + type = 11; + enum = "yesno"; + } } 308 { title = "CTF Team Ring (Red)"; - sprite = "internal:RRNGA0"; + sprite = "internal:TRNGA0R"; width = 16; + arg0 + { + title = "Float?"; + type = 11; + enum = "yesno"; + } } 309 { title = "CTF Team Ring (Blue)"; - sprite = "internal:BRNGA0"; + sprite = "internal:TRNGA0B"; width = 16; + arg0 + { + title = "Float?"; + type = 11; + enum = "yesno"; + } } 330 { title = "Bounce Ring Panel"; - sprite = "internal:PIKBA0"; + sprite = "PIKBA0"; + arg0 + { + title = "Float?"; + type = 11; + enum = "yesno"; + } } 331 { title = "Rail Ring Panel"; - sprite = "internal:PIKRA0"; + sprite = "PIKRA0"; + arg0 + { + title = "Float?"; + type = 11; + enum = "yesno"; + } } 332 { title = "Automatic Ring Panel"; - sprite = "internal:PIKAA0"; + sprite = "PIKAA0"; + arg0 + { + title = "Float?"; + type = 11; + enum = "yesno"; + } } 333 { title = "Explosion Ring Panel"; - sprite = "internal:PIKEA0"; + sprite = "PIKEA0"; + arg0 + { + title = "Float?"; + type = 11; + enum = "yesno"; + } } 334 { title = "Scatter Ring Panel"; - sprite = "internal:PIKSA0"; + sprite = "PIKSA0"; + arg0 + { + title = "Float?"; + type = 11; + enum = "yesno"; + } } 335 { title = "Grenade Ring Panel"; - sprite = "internal:PIKGA0"; + sprite = "PIKGA0"; + arg0 + { + title = "Float?"; + type = 11; + enum = "yesno"; + } } } @@ -4562,16 +1485,16 @@ udmf title = "Monitors"; width = 18; height = 40; - arg0 - { - title = "Death trigger tag"; - type = 15; - } 400 { title = "Super Ring (10 Rings)"; sprite = "TVRIA0"; + arg0 + { + title = "Death trigger tag"; + type = 15; + } arg1 { title = "Respawn behavior"; @@ -4583,6 +1506,11 @@ udmf { title = "Pity Shield"; sprite = "TVPIA0"; + arg0 + { + title = "Death trigger tag"; + type = 15; + } arg1 { title = "Respawn behavior"; @@ -4594,6 +1522,11 @@ udmf { title = "Attraction Shield"; sprite = "TVATA0"; + arg0 + { + title = "Death trigger tag"; + type = 15; + } arg1 { title = "Respawn behavior"; @@ -4605,6 +1538,11 @@ udmf { title = "Force Shield"; sprite = "TVFOA0"; + arg0 + { + title = "Death trigger tag"; + type = 15; + } arg1 { title = "Respawn behavior"; @@ -4616,6 +1554,11 @@ udmf { title = "Armageddon Shield"; sprite = "TVARA0"; + arg0 + { + title = "Death trigger tag"; + type = 15; + } arg1 { title = "Respawn behavior"; @@ -4627,6 +1570,11 @@ udmf { title = "Whirlwind Shield"; sprite = "TVWWA0"; + arg0 + { + title = "Death trigger tag"; + type = 15; + } arg1 { title = "Respawn behavior"; @@ -4638,6 +1586,11 @@ udmf { title = "Elemental Shield"; sprite = "TVELA0"; + arg0 + { + title = "Death trigger tag"; + type = 15; + } arg1 { title = "Respawn behavior"; @@ -4649,6 +1602,11 @@ udmf { title = "Super Sneakers"; sprite = "TVSSA0"; + arg0 + { + title = "Death trigger tag"; + type = 15; + } arg1 { title = "Respawn behavior"; @@ -4660,6 +1618,11 @@ udmf { title = "Invincibility"; sprite = "TVIVA0"; + arg0 + { + title = "Death trigger tag"; + type = 15; + } arg1 { title = "Respawn behavior"; @@ -4671,6 +1634,11 @@ udmf { title = "Extra Life"; sprite = "TV1UA0"; + arg0 + { + title = "Death trigger tag"; + type = 15; + } arg1 { title = "Respawn behavior"; @@ -4692,11 +1660,21 @@ udmf { title = "Eggman"; sprite = "TVEGA0"; + arg0 + { + title = "Death trigger tag"; + type = 15; + } } 411 { title = "Teleporter"; sprite = "TVMXA0"; + arg0 + { + title = "Death trigger tag"; + type = 15; + } arg1 { title = "Respawn behavior"; @@ -4708,21 +1686,41 @@ udmf { title = "Gravity Boots"; sprite = "TVGVA0"; + arg0 + { + title = "Death trigger tag"; + type = 15; + } } 414 { title = "CTF Team Ring Monitor (Red)"; sprite = "TRRIA0"; + arg0 + { + title = "Death trigger tag"; + type = 15; + } } 415 { title = "CTF Team Ring Monitor (Blue)"; sprite = "TBRIA0"; + arg0 + { + title = "Death trigger tag"; + type = 15; + } } 416 { title = "Recycler"; sprite = "TVRCA0"; + arg0 + { + title = "Death trigger tag"; + type = 15; + } arg1 { title = "Respawn behavior"; @@ -4734,16 +1732,31 @@ udmf { title = "Score (1,000 Points)"; sprite = "TV1KA0"; + arg0 + { + title = "Death trigger tag"; + type = 15; + } } 419 { title = "Score (10,000 Points)"; sprite = "TVTKA0"; + arg0 + { + title = "Death trigger tag"; + type = 15; + } } 420 { title = "Flame Shield"; sprite = "TVFLA0"; + arg0 + { + title = "Death trigger tag"; + type = 15; + } arg1 { title = "Respawn behavior"; @@ -4755,6 +1768,11 @@ udmf { title = "Water Shield"; sprite = "TVBBA0"; + arg0 + { + title = "Death trigger tag"; + type = 15; + } arg1 { title = "Respawn behavior"; @@ -4766,6 +1784,11 @@ udmf { title = "Lightning Shield"; sprite = "TVZPA0"; + arg0 + { + title = "Death trigger tag"; + type = 15; + } arg1 { title = "Respawn behavior"; @@ -4782,76 +1805,136 @@ udmf title = "Monitors (Respawning)"; width = 20; height = 44; - arg0 - { - title = "Death trigger tag"; - type = 15; - } 431 { title = "Pity Shield (Respawn)"; sprite = "TVPIB0"; + arg0 + { + title = "Death trigger tag"; + type = 15; + } } 432 { title = "Attraction Shield (Respawn)"; sprite = "TVATB0"; + arg0 + { + title = "Death trigger tag"; + type = 15; + } } 433 { title = "Force Shield (Respawn)"; sprite = "TVFOB0"; + arg0 + { + title = "Death trigger tag"; + type = 15; + } } 434 { title = "Armageddon Shield (Respawn)"; sprite = "TVARB0"; + arg0 + { + title = "Death trigger tag"; + type = 15; + } } 435 { title = "Whirlwind Shield (Respawn)"; sprite = "TVWWB0"; + arg0 + { + title = "Death trigger tag"; + type = 15; + } } 436 { title = "Elemental Shield (Respawn)"; sprite = "TVELB0"; + arg0 + { + title = "Death trigger tag"; + type = 15; + } } 437 { title = "Super Sneakers (Respawn)"; sprite = "TVSSB0"; + arg0 + { + title = "Death trigger tag"; + type = 15; + } } 438 { title = "Invincibility (Respawn)"; sprite = "TVIVB0"; + arg0 + { + title = "Death trigger tag"; + type = 15; + } } 440 { title = "Eggman (Respawn)"; sprite = "TVEGB0"; + arg0 + { + title = "Death trigger tag"; + type = 15; + } } 443 { title = "Gravity Boots (Respawn)"; sprite = "TVGVB0"; + arg0 + { + title = "Death trigger tag"; + type = 15; + } } 450 { title = "Flame Shield (Respawn)"; sprite = "TVFLB0"; + arg0 + { + title = "Death trigger tag"; + type = 15; + } } 451 { title = "Water Shield (Respawn)"; sprite = "TVBBB0"; + arg0 + { + title = "Death trigger tag"; + type = 15; + } } 452 { title = "Lightning Shield (Respawn)"; sprite = "TVZPB0"; + arg0 + { + title = "Death trigger tag"; + type = 15; + } } } @@ -5235,13 +2318,13 @@ udmf { arrow = 0; title = "5 Vertical Rings (Yellow Spring)"; - sprite = "RINGA0"; + sprite = "internal:ringverticalyellow"; } 601 { arrow = 0; title = "5 Vertical Rings (Red Spring)"; - sprite = "RINGA0"; + sprite = "internal:ringverticalred"; height = 1024; } 602 @@ -5259,41 +2342,47 @@ udmf 604 { title = "Circle of Rings"; - sprite = "RINGA0"; + sprite = "internal:circlering"; width = 96; height = 192; + centerhitbox = true; } 605 { title = "Circle of Rings (Big)"; - sprite = "RINGA0"; + sprite = "internal:circlebigring"; width = 192; + centerhitbox = true; } 606 { title = "Circle of Blue Spheres"; - sprite = "SPHRA0"; + sprite = "internal:circlesphere"; width = 96; height = 192; + centerhitbox = true; } 607 { title = "Circle of Blue Spheres (Big)"; - sprite = "SPHRA0"; + sprite = "internal:circlebigsphere"; width = 192; + centerhitbox = true; } 608 { title = "Circle of Rings and Spheres"; - sprite = "SPHRA0"; + sprite = "internal:circleringsphere"; width = 96; height = 192; + centerhitbox = true; } 609 { title = "Circle of Rings and Spheres (Big)"; - sprite = "SPHRA0"; + sprite = "internal:circlebigringsphere"; width = 192; + centerhitbox = true; } 610 { @@ -5322,6 +2411,7 @@ udmf sprite = "RINGA0"; width = 96; height = 192; + centerhitbox = true; arg0 { title = "Number of items"; @@ -5429,7 +2519,7 @@ udmf 756 { title = "Blast Linedef Executor"; - sprite = "TOADA0"; + sprite = "internal:blastexec"; width = 32; height = 16; arg0 @@ -5441,7 +2531,7 @@ udmf 757 { title = "Fan Particle Generator"; - sprite = "PRTLA0"; + sprite = "internal:fanparticles"; width = 8; height = 16; arg0 @@ -5490,11 +2580,6 @@ udmf title = "PolyObject Spawn Point"; sprite = "internal:polycenter"; } - 762 - { - title = "PolyObject Spawn Point (Crush)"; - sprite = "internal:polycentercrush"; - } 780 { title = "Skybox View Point"; @@ -5514,7 +2599,7 @@ udmf greenflower { - color = 10; // Green + color = 2; // Green title = "Greenflower"; 800 @@ -5619,7 +2704,7 @@ udmf technohill { - color = 10; // Green + color = 2; // Green title = "Techno Hill"; 900 @@ -5663,7 +2748,7 @@ udmf deepsea { - color = 10; // Green + color = 2; // Green title = "Deep Sea"; 1000 @@ -5823,7 +2908,7 @@ udmf castleeggman { - color = 10; // Green + color = 2; // Green title = "Castle Eggman"; 1100 @@ -6386,7 +3471,7 @@ udmf aridcanyon { - color = 10; // Green + color = 2; // Green title = "Arid Canyon"; 1200 @@ -6511,6 +3596,7 @@ udmf sprite = "WWSGAR"; width = 22; height = 64; + wallsprite = true; } 1213 { @@ -6518,6 +3604,7 @@ udmf sprite = "WWS2AR"; width = 22; height = 64; + wallsprite = true; } 1214 { @@ -6525,6 +3612,7 @@ udmf sprite = "WWS3ALAR"; width = 16; height = 192; + wallsprite = true; } 1215 { @@ -6644,7 +3732,7 @@ udmf redvolcano { - color = 10; // Green + color = 2; // Green title = "Red Volcano"; 1300 @@ -6789,7 +3877,7 @@ udmf botanicserenity { - color = 10; // Green + color = 2; // Green title = "Botanic Serenity"; width = 16; height = 32; @@ -7032,7 +4120,7 @@ udmf azuretemple { - color = 10; // Green + color = 2; // Green title = "Azure Temple"; 1500 @@ -7144,7 +4232,7 @@ udmf dreamhill { - color = 10; // Green + color = 2; // Green title = "Dream Hill"; 1600 @@ -7178,8 +4266,8 @@ udmf nightstrk { - color = 13; // Pink - title = "NiGHTS Track"; + color = 16; // Light Pink + title = "NiGHTS Track & Misc."; width = 8; height = 4096; sprite = "UNKNA0"; @@ -7207,8 +4295,8 @@ udmf type = 11; enum { - 0 = "Clockwise"; - 1 = "Counterclockwise"; + 0 = "Counterclockwise"; + 1 = "Clockwise"; } } } @@ -7238,30 +4326,6 @@ udmf title = "Order"; } } - 1710 - { - title = "Ideya Capture"; - sprite = "CAPSA0"; - width = 72; - height = 144; - arg0 - { - title = "Mare"; - } - arg1 - { - title = "Required spheres"; - } - } - } - - nights - { - color = 13; // Pink - title = "NiGHTS Items"; - width = 16; - height = 32; - 1703 { title = "Ideya Drone"; @@ -7299,6 +4363,41 @@ udmf enum = "noyes"; } } + 1710 + { + title = "Ideya Capture"; + sprite = "CAPSA0"; + width = 72; + height = 144; + arg0 + { + title = "Mare"; + } + arg1 + { + title = "Required spheres"; + } + } + 1714 + { + title = "Ideya Anchor Point"; + sprite = "internal:ideya"; + width = 8; + height = 16; + arg0 + { + title = "Mare"; + } + } + } + + nights + { + color = 13; // Pink + title = "NiGHTS Items"; + width = 16; + height = 32; + 1704 { arrow = 1; @@ -7399,25 +4498,15 @@ udmf { arrow = 1; title = "Hoop"; - sprite = "HOOPA0"; + sprite = "internal:nightshoop"; width = 80; height = 160; + centerhitbox = true; arg0 { title = "Radius"; } } - 1714 - { - title = "Ideya Anchor Point"; - sprite = "internal:axis1"; - width = 8; - height = 16; - arg0 - { - title = "Mare"; - } - } } mario @@ -7528,7 +4617,7 @@ udmf christmasdisco { - color = 10; // Green + color = 2; // Green title = "Christmas & Disco"; 1850 @@ -7643,7 +4732,7 @@ udmf stalagmites { - color = 10; // Green + color = 2; // Green title = "Stalagmites"; width = 16; height = 40; @@ -7722,7 +4811,7 @@ udmf hauntedheights { - color = 10; // Green + color = 2; // Green title = "Haunted Heights"; 2000 @@ -7828,7 +4917,7 @@ udmf frozenhillside { - color = 10; // Green + color = 2; // Green title = "Frozen Hillside"; 2100 @@ -7883,7 +4972,7 @@ udmf tutorial { - color = 10; // Green + color = 2; // Green title = "Tutorial"; 799 @@ -7901,65 +4990,170 @@ udmf flickies { - color = 10; // Green + color = 2; // Green title = "Flickies"; width = 8; height = 20; - arg0 - { - title = "Radius"; - } - arg1 - { - title = "Flags"; - type = 12; - enum - { - 1 = "Move aimlessly"; - 2 = "No movement"; - 4 = "Hop"; - } - } 2200 { title = "Bluebird"; sprite = "FL01A1"; + arg0 + { + title = "Radius"; + } + arg1 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Move aimlessly"; + 2 = "No movement"; + 4 = "Hop"; + } + } } 2201 { title = "Rabbit"; sprite = "FL02A1"; + arg0 + { + title = "Radius"; + } + arg1 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Move aimlessly"; + 2 = "No movement"; + 4 = "Hop"; + } + } } 2202 { title = "Chicken"; sprite = "FL03A1"; + arg0 + { + title = "Radius"; + } + arg1 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Move aimlessly"; + 2 = "No movement"; + 4 = "Hop"; + } + } } 2203 { title = "Seal"; sprite = "FL04A1"; + arg0 + { + title = "Radius"; + } + arg1 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Move aimlessly"; + 2 = "No movement"; + 4 = "Hop"; + } + } } 2204 { title = "Pig"; sprite = "FL05A1"; + arg0 + { + title = "Radius"; + } + arg1 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Move aimlessly"; + 2 = "No movement"; + 4 = "Hop"; + } + } } 2205 { title = "Chipmunk"; sprite = "FL06A1"; + arg0 + { + title = "Radius"; + } + arg1 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Move aimlessly"; + 2 = "No movement"; + 4 = "Hop"; + } + } } 2206 { title = "Penguin"; sprite = "FL07A1"; + arg0 + { + title = "Radius"; + } + arg1 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Move aimlessly"; + 2 = "No movement"; + 4 = "Hop"; + } + } } 2207 { title = "Fish"; sprite = "FL08A1"; + arg0 + { + title = "Radius"; + } + arg1 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Move aimlessly"; + 2 = "No movement"; + 4 = "Hop"; + } + } arg2 { title = "Color"; @@ -7989,51 +5183,214 @@ udmf { title = "Ram"; sprite = "FL09A1"; + arg0 + { + title = "Radius"; + } + arg1 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Move aimlessly"; + 2 = "No movement"; + 4 = "Hop"; + } + } } 2209 { title = "Puffin"; sprite = "FL10A1"; + arg0 + { + title = "Radius"; + } + arg1 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Move aimlessly"; + 2 = "No movement"; + 4 = "Hop"; + } + } } 2210 { title = "Cow"; sprite = "FL11A1"; + arg0 + { + title = "Radius"; + } + arg1 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Move aimlessly"; + 2 = "No movement"; + 4 = "Hop"; + } + } } 2211 { title = "Rat"; sprite = "FL12A1"; + arg0 + { + title = "Radius"; + } + arg1 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Move aimlessly"; + 2 = "No movement"; + 4 = "Hop"; + } + } } 2212 { title = "Bear"; sprite = "FL13A1"; + arg0 + { + title = "Radius"; + } + arg1 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Move aimlessly"; + 2 = "No movement"; + 4 = "Hop"; + } + } } 2213 { title = "Dove"; sprite = "FL14A1"; + arg0 + { + title = "Radius"; + } + arg1 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Move aimlessly"; + 2 = "No movement"; + 4 = "Hop"; + } + } } 2214 { title = "Cat"; sprite = "FL15A1"; + arg0 + { + title = "Radius"; + } + arg1 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Move aimlessly"; + 2 = "No movement"; + 4 = "Hop"; + } + } } 2215 { title = "Canary"; sprite = "FL16A1"; + arg0 + { + title = "Radius"; + } + arg1 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Move aimlessly"; + 2 = "No movement"; + 4 = "Hop"; + } + } } 2216 { title = "Spider"; sprite = "FS01A1"; + arg0 + { + title = "Radius"; + } + arg1 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Move aimlessly"; + 2 = "No movement"; + 4 = "Hop"; + } + } } 2217 { title = "Bat"; sprite = "FS02A0"; + arg0 + { + title = "Radius"; + } + arg1 + { + title = "Flags"; + type = 12; + enum + { + 1 = "Move aimlessly"; + 2 = "No movement"; + 4 = "Hop"; + } + } } } -} + + editor + { + color = 15; // White + arrow = 1; + title = "3D Mode Start"; + error = -1; + width = 8; + height = 16; + sort = 1; + + 3328 = "3D Mode Start"; + } +} \ No newline at end of file diff --git a/extras/conf/udb/SRB2_22Doom.cfg b/extras/conf/udb/SRB2_22Doom.cfg deleted file mode 100644 index 9e733aa39..000000000 --- a/extras/conf/udb/SRB2_22Doom.cfg +++ /dev/null @@ -1,32 +0,0 @@ -/************************************************************************\ - Ultimate Doom Builder Game Configuration for Sonic Robo Blast 2 Version 2.2 -\************************************************************************/ - -// This is required to prevent accidental use of a different configuration -type = "Doom Builder 2 Game Configuration"; - -// This is the title to show for this game -game = "Sonic Robo Blast 2 - 2.2 (Doom format)"; - -// This is the simplified game engine/sourceport name -engine = "zdoom"; - -// Settings common to all games and all map formats -include("Includes\\SRB222_common.cfg", "common"); - -// Settings common to Doom map format -include("Includes\\SRB222_common.cfg", "mapformat_doom"); - -include("Includes\\Game_SRB222.cfg"); - -// Script lumps detection -scriptlumpnames -{ - include("Includes\\SRB222_misc.cfg", "scriptlumpnames"); -} - -//Default things filters -thingsfilters -{ - include("Includes\\SRB222_misc.cfg", "thingsfilters"); -} \ No newline at end of file From b405f50caaa93dc0cfeb9de821cba003bda0a8a6 Mon Sep 17 00:00:00 2001 From: Zwip-Zwap Zapony Date: Sat, 24 Jun 2023 19:35:57 +0200 Subject: [PATCH 224/586] Fix A_ConnectToGround's handling of scaled mobjs --- src/p_enemy.c | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index c7d87b88a..87c2d7b9e 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -12583,8 +12583,7 @@ void A_MineRange(mobj_t *actor) void A_ConnectToGround(mobj_t *actor) { mobj_t *work; - fixed_t workz; - fixed_t workh; + fixed_t endz; angle_t ang; INT32 locvar1 = var1; INT32 locvar2 = var2; @@ -12595,38 +12594,42 @@ void A_ConnectToGround(mobj_t *actor) if (actor->subsector->sector->ffloors) P_AdjustMobjFloorZ_FFloors(actor, actor->subsector->sector, 2); + endz = actor->z; if (actor->flags2 & MF2_OBJECTFLIP) - workz = (actor->z + actor->height) - actor->ceilingz; + actor->z = actor->ceilingz - actor->height; // Ensures perfect ceiling connection else - workz = actor->floorz - actor->z; + actor->z = actor->floorz; // Ensures perfect floor connection if (locvar2) { - workh = FixedMul(mobjinfo[locvar2].height, actor->scale); - if (actor->flags2 & MF2_OBJECTFLIP) - workz += workh; - work = P_SpawnMobjFromMobj(actor, 0, 0, workz, locvar2); - workz += workh; + work = P_SpawnMobjFromMobj(actor, 0, 0, 0, locvar2); + if (work) + work->old_z = work->z; // Don't copy old_z from the actor + + actor->z += P_MobjFlip(actor) * FixedMul(mobjinfo[locvar2].height, actor->scale); } - if (!locvar1) - return; - - if (!(workh = FixedMul(mobjinfo[locvar1].height, actor->scale))) + if (!locvar1 || !mobjinfo[locvar1].height) // Can't tile the middle object? + { + actor->z = endz; return; + } ang = actor->angle + ANGLE_45; - while (workz < 0) + while ((actor->flags2 & MF2_OBJECTFLIP) ? (actor->z > endz) : (actor->z < endz)) { - work = P_SpawnMobjFromMobj(actor, 0, 0, workz, locvar1); + work = P_SpawnMobjFromMobj(actor, 0, 0, 0, locvar1); if (work) - work->angle = ang; + { + work->angle = work->old_angle = ang; + work->old_z = work->z; // Don't copy old_z from the actor + } + ang += ANGLE_90; - workz += workh; + actor->z += P_MobjFlip(actor) * FixedMul(mobjinfo[locvar1].height, actor->scale); } - if (workz != 0) - actor->z += P_MobjFlip(actor)*workz; + actor->old_z = actor->z; // Reset Z interpolation - the spawned objects intentionally don't have any Z interpolation either, after all } // Function: A_SpawnParticleRelative From 8c31d279cffd1f750ee8d3c082e72cd5be29baf9 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 11 Jun 2023 19:55:43 +0200 Subject: [PATCH 225/586] Implement per-texture offsets in UDMF --- extras/conf/udb/Includes/SRB222_common.cfg | 2 +- src/hardware/hw_main.c | 54 +++++++++++----------- src/lua_maplib.c | 48 +++++++++++++++++++ src/p_maputl.c | 16 +++---- src/p_setup.c | 29 ++++++++++++ src/r_defs.h | 4 ++ src/r_segs.c | 26 ++++++----- 7 files changed, 132 insertions(+), 47 deletions(-) diff --git a/extras/conf/udb/Includes/SRB222_common.cfg b/extras/conf/udb/Includes/SRB222_common.cfg index 9a574d6f2..8f37aabaa 100644 --- a/extras/conf/udb/Includes/SRB222_common.cfg +++ b/extras/conf/udb/Includes/SRB222_common.cfg @@ -100,7 +100,7 @@ mapformat_udmf // When this is set to true, sectors with the same tag will light up when a line is highlighted linetagindicatesectors = false; - localsidedeftextureoffsets = false; + localsidedeftextureoffsets = true; distinctfloorandceilingbrightness = true; planeequationsupport = true; diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 897288da2..c2390519e 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -1153,7 +1153,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom else texturevpeg = gl_backsector->ceilingheight + textureheight[gl_toptexture] - gl_frontsector->ceilingheight; - texturevpeg += gl_sidedef->rowoffset; + texturevpeg += gl_sidedef->rowoffset + gl_sidedef->offsety_top; // This is so that it doesn't overflow and screw up the wall, it doesn't need to go higher than the texture's height anyway texturevpeg %= textureheight[gl_toptexture]; @@ -1162,8 +1162,8 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY; wallVerts[0].t = wallVerts[1].t = (texturevpeg + gl_frontsector->ceilingheight - gl_backsector->ceilingheight) * grTex->scaleY; - wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX; - wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX; + wallVerts[0].s = wallVerts[3].s = (cliplow + gl_sidedef->offsetx_top) * grTex->scaleX; + wallVerts[2].s = wallVerts[1].s = (cliphigh + gl_sidedef->offsetx_top) * grTex->scaleX; // Adjust t value for sloped walls if (!(gl_linedef->flags & ML_SKEWTD)) @@ -1213,7 +1213,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom else texturevpeg = gl_frontsector->floorheight - gl_backsector->floorheight; - texturevpeg += gl_sidedef->rowoffset; + texturevpeg += gl_sidedef->rowoffset + gl_sidedef->offsety_bot; // This is so that it doesn't overflow and screw up the wall, it doesn't need to go higher than the texture's height anyway texturevpeg %= textureheight[gl_bottomtexture]; @@ -1222,8 +1222,8 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY; wallVerts[0].t = wallVerts[1].t = (texturevpeg + gl_backsector->floorheight - gl_frontsector->floorheight) * grTex->scaleY; - wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX; - wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX; + wallVerts[0].s = wallVerts[3].s = (cliplow + gl_sidedef->offsetx_bot) * grTex->scaleX; + wallVerts[2].s = wallVerts[1].s = (cliphigh + gl_sidedef->offsetx_bot) * grTex->scaleX; // Adjust t value for sloped walls if (!(gl_linedef->flags & ML_SKEWTD)) @@ -1333,13 +1333,13 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom // Peg it to the floor if (gl_linedef->flags & ML_MIDPEG) { - polybottom = max(front->floorheight, back->floorheight) + gl_sidedef->rowoffset; + polybottom = max(front->floorheight, back->floorheight) + gl_sidedef->rowoffset + gl_sidedef->offsety_mid; polytop = polybottom + midtexheight; } // Peg it to the ceiling else { - polytop = min(front->ceilingheight, back->ceilingheight) + gl_sidedef->rowoffset; + polytop = min(front->ceilingheight, back->ceilingheight) + gl_sidedef->rowoffset + gl_sidedef->offsety_mid; polybottom = polytop - midtexheight; } @@ -1350,9 +1350,9 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom // Skew the texture, but peg it to the floor else if (gl_linedef->flags & ML_MIDPEG) { - polybottom = popenbottom + gl_sidedef->rowoffset; + polybottom = popenbottom + gl_sidedef->rowoffset + gl_sidedef->offsety_mid; polytop = polybottom + midtexheight; - polybottomslope = popenbottomslope + gl_sidedef->rowoffset; + polybottomslope = popenbottomslope + gl_sidedef->rowoffset + gl_sidedef->offsety_mid; polytopslope = polybottomslope + midtexheight; } // Skew it according to the ceiling's slope @@ -1407,12 +1407,12 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom // Left side wallVerts[3].t = texturevpeg * grTex->scaleY; wallVerts[0].t = (h - l + texturevpeg) * grTex->scaleY; - wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX; + wallVerts[0].s = wallVerts[3].s = (cliplow + gl_sidedef->offsetx_mid) * grTex->scaleX; // Right side wallVerts[2].t = texturevpegslope * grTex->scaleY; wallVerts[1].t = (hS - lS + texturevpegslope) * grTex->scaleY; - wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX; + wallVerts[2].s = wallVerts[1].s = (cliphigh + gl_sidedef->offsetx_mid) * grTex->scaleX; // set top/bottom coords // Take the texture peg into account, rather than changing the offsets past @@ -1474,19 +1474,19 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom // PEGGING if ((gl_linedef->flags & (ML_DONTPEGBOTTOM|ML_NOSKEW)) == (ML_DONTPEGBOTTOM|ML_NOSKEW)) - texturevpeg = gl_frontsector->floorheight + textureheight[gl_sidedef->midtexture] - gl_frontsector->ceilingheight + gl_sidedef->rowoffset; + texturevpeg = gl_frontsector->floorheight + textureheight[gl_sidedef->midtexture] - gl_frontsector->ceilingheight + gl_sidedef->rowoffset + gl_sidedef->offsety_mid; else if (gl_linedef->flags & ML_DONTPEGBOTTOM) - texturevpeg = worldbottom + textureheight[gl_sidedef->midtexture] - worldtop + gl_sidedef->rowoffset; + texturevpeg = worldbottom + textureheight[gl_sidedef->midtexture] - worldtop + gl_sidedef->rowoffset + gl_sidedef->offsety_mid; else // top of texture at top - texturevpeg = gl_sidedef->rowoffset; + texturevpeg = gl_sidedef->rowoffset + gl_sidedef->offsety_mid; grTex = HWR_GetTexture(gl_midtexture); wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY; wallVerts[0].t = wallVerts[1].t = (texturevpeg + gl_frontsector->ceilingheight - gl_frontsector->floorheight) * grTex->scaleY; - wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX; - wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX; + wallVerts[0].s = wallVerts[3].s = (cliplow + gl_sidedef->offsetx_mid) * grTex->scaleX; + wallVerts[2].s = wallVerts[1].s = (cliphigh + gl_sidedef->offsetx_mid) * grTex->scaleX; // Texture correction for slopes if (gl_linedef->flags & ML_NOSKEW) { @@ -1634,13 +1634,13 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom // -- Monster Iestyn 26/06/18 if (newline) { - texturevpeg = sides[newline->sidenum[0]].rowoffset; + texturevpeg = sides[newline->sidenum[0]].rowoffset + sides[newline->sidenum[0]].offsety_mid; attachtobottom = !!(newline->flags & ML_DONTPEGBOTTOM); slopeskew = !!(newline->flags & ML_SKEWTD); } else { - texturevpeg = sides[rover->master->sidenum[0]].rowoffset; + texturevpeg = sides[rover->master->sidenum[0]].rowoffset + sides[rover->master->sidenum[0]].offsety_mid; attachtobottom = !!(gl_linedef->flags & ML_DONTPEGBOTTOM); slopeskew = !!(rover->master->flags & ML_SKEWTD); } @@ -1672,8 +1672,8 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom } } - wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX; - wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX; + wallVerts[0].s = wallVerts[3].s = (cliplow + gl_sidedef->offsetx_mid) * grTex->scaleX; + wallVerts[2].s = wallVerts[1].s = (cliphigh + gl_sidedef->offsetx_mid) * grTex->scaleX; } if (rover->fofflags & FOF_FOG) { @@ -1785,17 +1785,17 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom if (newline) { - wallVerts[3].t = wallVerts[2].t = (*rover->topheight - h + sides[newline->sidenum[0]].rowoffset) * grTex->scaleY; - wallVerts[0].t = wallVerts[1].t = (h - l + (*rover->topheight - h + sides[newline->sidenum[0]].rowoffset)) * grTex->scaleY; + wallVerts[3].t = wallVerts[2].t = (*rover->topheight - h + sides[newline->sidenum[0]].rowoffset + sides[newline->sidenum[0]].offsety_mid) * grTex->scaleY; + wallVerts[0].t = wallVerts[1].t = (h - l + (*rover->topheight - h + sides[newline->sidenum[0]].rowoffset) + sides[newline->sidenum[0]].offsety_mid) * grTex->scaleY; } else { - wallVerts[3].t = wallVerts[2].t = (*rover->topheight - h + sides[rover->master->sidenum[0]].rowoffset) * grTex->scaleY; - wallVerts[0].t = wallVerts[1].t = (h - l + (*rover->topheight - h + sides[rover->master->sidenum[0]].rowoffset)) * grTex->scaleY; + wallVerts[3].t = wallVerts[2].t = (*rover->topheight - h + sides[rover->master->sidenum[0]].rowoffset + sides[rover->master->sidenum[0]].offsety_mid) * grTex->scaleY; + wallVerts[0].t = wallVerts[1].t = (h - l + (*rover->topheight - h + sides[rover->master->sidenum[0]].rowoffset + sides[rover->master->sidenum[0]].offsety_mid)) * grTex->scaleY; } - wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX; - wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX; + wallVerts[0].s = wallVerts[3].s = (cliplow + gl_sidedef->offsetx_mid) * grTex->scaleX; + wallVerts[2].s = wallVerts[1].s = (cliphigh + gl_sidedef->offsetx_mid) * grTex->scaleX; } if (rover->fofflags & FOF_FOG) diff --git a/src/lua_maplib.c b/src/lua_maplib.c index dc477c81f..f73b3c7d2 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -166,6 +166,12 @@ enum side_e { side_valid = 0, side_textureoffset, side_rowoffset, + side_offsetx_top, + side_offsety_top, + side_offsetx_mid, + side_offsety_mid, + side_offsetx_bot, + side_offsety_bot, side_toptexture, side_bottomtexture, side_midtexture, @@ -180,6 +186,12 @@ static const char *const side_opt[] = { "valid", "textureoffset", "rowoffset", + "offsetx_top", + "offsety_top", + "offsetx_mid", + "offsety_mid", + "offsetx_bot", + "offsety_bot", "toptexture", "bottomtexture", "midtexture", @@ -1097,6 +1109,24 @@ static int side_get(lua_State *L) case side_rowoffset: lua_pushfixed(L, side->rowoffset); return 1; + case side_offsetx_top: + lua_pushfixed(L, side->offsetx_top); + return 1; + case side_offsety_top: + lua_pushfixed(L, side->offsety_top); + return 1; + case side_offsetx_mid: + lua_pushfixed(L, side->offsetx_mid); + return 1; + case side_offsety_mid: + lua_pushfixed(L, side->offsety_mid); + return 1; + case side_offsetx_bot: + lua_pushfixed(L, side->offsetx_bot); + return 1; + case side_offsety_bot: + lua_pushfixed(L, side->offsety_bot); + return 1; case side_toptexture: lua_pushinteger(L, side->toptexture); return 1; @@ -1154,6 +1184,24 @@ static int side_set(lua_State *L) case side_rowoffset: side->rowoffset = luaL_checkfixed(L, 3); break; + case side_offsetx_top: + side->offsetx_top = luaL_checkfixed(L, 3); + break; + case side_offsety_top: + side->offsety_top = luaL_checkfixed(L, 3); + break; + case side_offsetx_mid: + side->offsetx_mid = luaL_checkfixed(L, 3); + break; + case side_offsety_mid: + side->offsety_mid = luaL_checkfixed(L, 3); + break; + case side_offsetx_bot: + side->offsetx_bot = luaL_checkfixed(L, 3); + break; + case side_offsety_bot: + side->offsety_bot = luaL_checkfixed(L, 3); + break; case side_toptexture: side->toptexture = luaL_checkinteger(L, 3); break; diff --git a/src/p_maputl.c b/src/p_maputl.c index b6a320730..e36d5fd72 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -509,26 +509,26 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) // on non-solid polyobjects should NEVER happen in the future if (linedef->polyobj && (linedef->polyobj->flags & POF_TESTHEIGHT)) { if (linedef->flags & ML_WRAPMIDTEX && !side->repeatcnt) { // "infinite" repeat - texbottom = back->floorheight + side->rowoffset; - textop = back->ceilingheight + side->rowoffset; + texbottom = back->floorheight + side->rowoffset + side->offsety_mid; + textop = back->ceilingheight + side->rowoffset + side->offsety_mid; } else if (linedef->flags & ML_MIDTEX) { - texbottom = back->floorheight + side->rowoffset; + texbottom = back->floorheight + side->rowoffset + side->offsety_mid; textop = texbottom + texheight*(side->repeatcnt+1); } else { - textop = back->ceilingheight + side->rowoffset; + textop = back->ceilingheight + side->rowoffset + side->offsety_mid; texbottom = textop - texheight*(side->repeatcnt+1); } } else #endif { if (linedef->flags & ML_WRAPMIDTEX && !side->repeatcnt) { // "infinite" repeat - texbottom = openbottom + side->rowoffset; - textop = opentop + side->rowoffset; + texbottom = openbottom + side->rowoffset + side->offsety_mid; + textop = opentop + side->rowoffset + side->offsety_mid; } else if (linedef->flags & ML_MIDPEG) { - texbottom = openbottom + side->rowoffset; + texbottom = openbottom + side->rowoffset + side->offsety_mid; textop = texbottom + texheight*(side->repeatcnt+1); } else { - textop = opentop + side->rowoffset; + textop = opentop + side->rowoffset + side->offsety_mid; texbottom = textop - texheight*(side->repeatcnt+1); } } diff --git a/src/p_setup.c b/src/p_setup.c index 74645e877..a10326986 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1240,6 +1240,9 @@ static void P_LoadSidedefs(UINT8 *data) } sd->rowoffset = SHORT(msd->rowoffset)<offsetx_top = sd->offsetx_mid = sd->offsetx_bot = 0; + sd->offsety_top = sd->offsety_mid = sd->offsety_bot = 0; + P_SetSidedefSector(i, SHORT(msd->sector)); // Special info stored in texture fields! @@ -1777,6 +1780,18 @@ static void ParseTextmapSidedefParameter(UINT32 i, const char *param, const char sides[i].textureoffset = atol(val)<> FRACBITS); if (wsides[i].rowoffset != 0) fprintf(f, "offsety = %d;\n", wsides[i].rowoffset >> FRACBITS); + if (wsides[i].offsetx_top != 0) + fprintf(f, "offsetx_top = %d;\n", wsides[i].offsetx_top >> FRACBITS); + if (wsides[i].offsety_top != 0) + fprintf(f, "offsety_top = %d;\n", wsides[i].offsety_top >> FRACBITS); + if (wsides[i].offsetx_mid != 0) + fprintf(f, "offsetx_mid = %d;\n", wsides[i].offsetx_mid >> FRACBITS); + if (wsides[i].offsety_mid != 0) + fprintf(f, "offsety_mid = %d;\n", wsides[i].offsety_mid >> FRACBITS); + if (wsides[i].offsetx_bot != 0) + fprintf(f, "offsetx_bottom = %d;\n", wsides[i].offsetx_bot >> FRACBITS); + if (wsides[i].offsety_bot != 0) + fprintf(f, "offsety_bottom = %d;\n", wsides[i].offsety_bot >> FRACBITS); if (wsides[i].toptexture > 0 && wsides[i].toptexture < numtextures) fprintf(f, "texturetop = \"%.*s\";\n", 8, textures[wsides[i].toptexture]->name); if (wsides[i].bottomtexture > 0 && wsides[i].bottomtexture < numtextures) @@ -2828,6 +2855,8 @@ static void P_LoadTextmap(void) // Defaults. sd->textureoffset = 0; sd->rowoffset = 0; + sd->offsetx_top = sd->offsetx_mid = sd->offsetx_bot = 0; + sd->offsety_top = sd->offsety_mid = sd->offsety_bot = 0; sd->toptexture = R_TextureNumForName("-"); sd->midtexture = R_TextureNumForName("-"); sd->bottomtexture = R_TextureNumForName("-"); diff --git a/src/r_defs.h b/src/r_defs.h index 6d2b7d3d8..963d655b1 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -559,6 +559,10 @@ typedef struct // add this to the calculated texture top fixed_t rowoffset; + // per-texture offsets for UDMF + fixed_t offsetx_top, offsetx_mid, offsetx_bot; + fixed_t offsety_top, offsety_mid, offsety_bot; + // Texture indices. // We do not maintain names here. INT32 toptexture, bottomtexture, midtexture; diff --git a/src/r_segs.c b/src/r_segs.c index 71fc9f9b2..5acca9b17 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -49,6 +49,7 @@ fixed_t rw_distance; static INT32 rw_x, rw_stopx; static angle_t rw_centerangle; static fixed_t rw_offset; +static fixed_t rw_offset_top, rw_offset_mid, rw_offset_bot; static fixed_t rw_offset2; // for splats static fixed_t rw_scale, rw_scalestep; static fixed_t rw_midtexturemid, rw_toptexturemid, rw_bottomtexturemid; @@ -778,7 +779,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) if (newline) { - offsetvalue = sides[newline->sidenum[0]].rowoffset; + offsetvalue = sides[newline->sidenum[0]].rowoffset + sides[newline->sidenum[0]].offsety_mid; if (newline->flags & ML_DONTPEGBOTTOM) { skewslope = *pfloor->b_slope; // skew using bottom slope @@ -790,7 +791,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) } else { - offsetvalue = sides[pfloor->master->sidenum[0]].rowoffset; + offsetvalue = sides[pfloor->master->sidenum[0]].rowoffset + sides[pfloor->master->sidenum[0]].offsety_mid; if (curline->linedef->flags & ML_DONTPEGBOTTOM) { skewslope = *pfloor->b_slope; // skew using bottom slope @@ -1335,7 +1336,7 @@ static void R_RenderSegLoop (void) dc_yl = yl; dc_yh = yh; dc_texturemid = rw_midtexturemid; - dc_source = R_GetColumn(midtexture,texturecolumn); + dc_source = R_GetColumn(midtexture,texturecolumn + (rw_offset_mid>>FRACBITS)); dc_texheight = textureheight[midtexture]>>FRACBITS; //profile stuff --------------------------------------------------------- @@ -1396,7 +1397,7 @@ static void R_RenderSegLoop (void) dc_yl = yl; dc_yh = mid; dc_texturemid = rw_toptexturemid; - dc_source = R_GetColumn(toptexture,texturecolumn); + dc_source = R_GetColumn(toptexture,texturecolumn + (rw_offset_top>>FRACBITS)); dc_texheight = textureheight[toptexture]>>FRACBITS; colfunc(); ceilingclip[rw_x] = (INT16)mid; @@ -1433,7 +1434,7 @@ static void R_RenderSegLoop (void) dc_yh = yh; dc_texturemid = rw_bottomtexturemid; dc_source = R_GetColumn(bottomtexture, - texturecolumn); + texturecolumn + (rw_offset_bot>>FRACBITS)); dc_texheight = textureheight[bottomtexture]>>FRACBITS; colfunc(); floorclip[rw_x] = (INT16)mid; @@ -1452,7 +1453,7 @@ static void R_RenderSegLoop (void) { // save texturecol // for backdrawing of masked mid texture - maskedtexturecol[rw_x] = (INT16)texturecolumn; + maskedtexturecol[rw_x] = (INT16)(texturecolumn + (rw_offset_mid>>FRACBITS)); if (maskedtextureheight != NULL) { maskedtextureheight[rw_x] = (curline->linedef->flags & ML_MIDPEG) ? @@ -1783,7 +1784,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) rw_midtexturemid = worldtop; rw_midtextureslide = ceilingfrontslide; } - rw_midtexturemid += sidedef->rowoffset; + rw_midtexturemid += sidedef->rowoffset + sidedef->offsety_mid; ds_p->silhouette = SIL_BOTH; ds_p->sprtopclip = screenheightarray; @@ -2022,8 +2023,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) } } - rw_toptexturemid += sidedef->rowoffset; - rw_bottomtexturemid += sidedef->rowoffset; + rw_toptexturemid += sidedef->rowoffset + sidedef->offsety_top; + rw_bottomtexturemid += sidedef->rowoffset + sidedef->offsety_bot; // allocate space for masked texture tables if (frontsector && backsector && !Tag_Compare(&frontsector->tags, &backsector->tags) && (backsector->ffloors || frontsector->ffloors)) @@ -2266,8 +2267,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) rw_midtexturebackslide = ceilingbackslide; } } - rw_midtexturemid += sidedef->rowoffset; - rw_midtextureback += sidedef->rowoffset; + rw_midtexturemid += sidedef->rowoffset + sidedef->offsety_mid; + rw_midtextureback += sidedef->rowoffset + sidedef->offsety_mid; maskedtexture = true; } @@ -2305,6 +2306,9 @@ void R_StoreWallRange(INT32 start, INT32 stop) /// don't use texture offset for splats rw_offset2 = rw_offset + curline->offset; rw_offset += sidedef->textureoffset + curline->offset; + rw_offset_top = sidedef->offsetx_top; + rw_offset_mid = sidedef->offsetx_mid; + rw_offset_bot = sidedef->offsetx_bot; rw_centerangle = ANGLE_90 + viewangle - rw_normalangle; // calculate light table From 2c66f2ce27fa097992fbc1e224eb7cfd2da4af69 Mon Sep 17 00:00:00 2001 From: katsy Date: Mon, 3 Jul 2023 16:27:07 -0500 Subject: [PATCH 226/586] Fix homing attack and ring attraction math dumbs --- src/p_enemy.c | 2 +- src/p_user.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index fe062cffc..df2b27af2 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -828,7 +828,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))) + && (R_PointToDist2(0, 0, R_PointToDist2(0, 0, 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); diff --git a/src/p_user.c b/src/p_user.c index 38af2843b..8bb5fb2e4 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9217,7 +9217,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 = R_PointToDist2(0, 0, player->mo->x-mo->x, player->mo->y-mo->y); if (bullet) { if ((R_PointToAngle2(0, 0, dist, zdist) + span) > span*2) @@ -9234,7 +9234,7 @@ mobj_t *P_LookForEnemies(player_t *player, boolean nonenemies, boolean bullet) continue; } - dist = P_AproxDistance(dist, zdist); + dist = R_PointToDist2(0, 0, dist, zdist); if (dist > maxdist) continue; // out of range } From beda6109b2cc4d903c7c4fbc4cdad8e9879cef76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Mon, 3 Jul 2023 23:30:49 +0200 Subject: [PATCH 227/586] Fix segfault when trying to set a read-only field on player_t --- src/lua_playerlib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 1d06e081b..f76ec1689 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -843,7 +843,7 @@ static int player_get(lua_State *L) return 1; } -#define NOSET luaL_error(L, LUA_QL("player_t") " field " LUA_QS " should not be set directly.", field) +#define NOSET luaL_error(L, LUA_QL("player_t") " field " LUA_QS " should not be set directly.", player_opt[field]) static int player_set(lua_State *L) { player_t *plr = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); @@ -1392,7 +1392,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) +#define NOSET luaL_error(L, LUA_QL("ticcmd_t") " field " LUA_QS " should not be set directly.", ticcmd_opt[field]) enum ticcmd_e { From 09b9adc8066a31926d9fdbad0e672bbb89e20435 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Tue, 4 Jul 2023 18:46:49 +0200 Subject: [PATCH 228/586] Fix Lua warning when accessing custom field on mobjinfo --- src/lua_infolib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lua_infolib.c b/src/lua_infolib.c index fb07ccebb..4d150347d 100644 --- a/src/lua_infolib.c +++ b/src/lua_infolib.c @@ -1168,7 +1168,7 @@ static int mobjinfo_fields_ref = LUA_NOREF; static int mobjinfo_get(lua_State *L) { mobjinfo_t *info = *((mobjinfo_t **)luaL_checkudata(L, 1, META_MOBJINFO)); - enum mobjinfo_e field = luaL_checkoption(L, 2, mobjinfo_opt[0], mobjinfo_opt); + enum mobjinfo_e field = Lua_optoption(L, 2, mobjinfo_doomednum, mobjinfo_fields_ref); I_Assert(info != NULL); I_Assert(info >= mobjinfo); From ff7a24df09ac9517be430ea984104ce61242511b Mon Sep 17 00:00:00 2001 From: spherallic Date: Wed, 5 Jul 2023 12:10:30 +0200 Subject: [PATCH 229/586] Rename Kiwi skincolor to Pear --- src/deh_tables.c | 2 +- src/doomdef.h | 2 +- src/info.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/deh_tables.c b/src/deh_tables.c index d53680c19..1614fbecb 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -4655,7 +4655,7 @@ const char *COLOR_ENUMS[] = { "GOLDENROD", // SKINCOLOR_GOLDENROD, "YELLOW", // SKINCOLOR_YELLOW, "OLIVE", // SKINCOLOR_OLIVE, - "KIWI", // SKINCOLOR_KIWI, + "PEAR", // SKINCOLOR_PEAR, "LEMON", // SKINCOLOR_LEMON, "LIME", // SKINCOLOR_LIME, "PERIDOT", // SKINCOLOR_PERIDOT, diff --git a/src/doomdef.h b/src/doomdef.h index 20b87f230..84404d6ed 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -307,7 +307,7 @@ typedef enum SKINCOLOR_GOLDENROD, SKINCOLOR_YELLOW, SKINCOLOR_OLIVE, - SKINCOLOR_KIWI, + SKINCOLOR_PEAR, SKINCOLOR_LEMON, SKINCOLOR_LIME, SKINCOLOR_PERIDOT, diff --git a/src/info.c b/src/info.c index 32b21b702..abcf4b499 100644 --- a/src/info.c +++ b/src/info.c @@ -21632,7 +21632,7 @@ skincolor_t skincolors[MAXSKINCOLORS] = { {"Goldenrod", { 0, 80, 81, 81, 83, 73, 73, 64, 65, 66, 67, 68, 69, 62, 44, 45}, SKINCOLOR_MAJESTY, 8, V_YELLOWMAP, true}, // SKINCOLOR_GOLDENROD {"Yellow", {0x52, 0x53, 0x49, 0x49, 0x4a, 0x4a, 0x4b, 0x4b, 0x4b, 0x4c, 0x4d, 0x4d, 0x4e, 0x4e, 0x4f, 0xed}, SKINCOLOR_CORNFLOWER, 8, V_YELLOWMAP, true}, // SKINCOLOR_YELLOW {"Olive", {0x4b, 0x4b, 0x4c, 0x4c, 0x4d, 0x4e, 0xe7, 0xe7, 0xe9, 0xc5, 0xc5, 0xc6, 0xc6, 0xc7, 0xc7, 0xfd}, SKINCOLOR_DUSK, 3, V_YELLOWMAP, true}, // SKINCOLOR_OLIVE - {"Kiwi", { 88, 89, 188, 189, 189, 76, 76, 67, 67, 68, 69, 70, 45, 46, 47, 47}, SKINCOLOR_MARINE, 9, V_PERIDOTMAP, true}, // SKINCOLOR_KIWI + {"Pear", { 88, 89, 188, 189, 189, 76, 76, 67, 67, 68, 69, 70, 45, 46, 47, 47}, SKINCOLOR_MARINE, 9, V_PERIDOTMAP, true}, // SKINCOLOR_PEAR {"Lemon", { 0, 80, 81, 83, 73, 73, 74, 74, 76, 76, 191, 191, 79, 79, 110, 111}, SKINCOLOR_FUCHSIA, 8, V_YELLOWMAP, true}, // SKINCOLOR_LEMON {"Lime", {0x50, 0x51, 0x52, 0x53, 0x48, 0xbc, 0xbd, 0xbe, 0xbe, 0xbf, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f}, SKINCOLOR_MAGENTA, 9, V_PERIDOTMAP, true}, // SKINCOLOR_LIME {"Peridot", {0x58, 0x58, 0xbc, 0xbc, 0xbd, 0xbd, 0xbe, 0xbe, 0xbe, 0xbf, 0x5e, 0x5e, 0x5f, 0x5f, 0x77, 0x77}, SKINCOLOR_COBALT, 2, V_PERIDOTMAP, true}, // SKINCOLOR_PERIDOT @@ -21656,7 +21656,7 @@ skincolor_t skincolors[MAXSKINCOLORS] = { {"Turquoise", { 0, 120, 121, 122, 123, 141, 141, 135, 136, 136, 150, 153, 155, 157, 159, 253}, SKINCOLOR_SANGRIA, 12, V_SKYMAP, true}, // SKINCOLOR_TURQUOISE {"Aquamarine", { 0, 120, 121, 131, 132, 133, 134, 134, 135, 135, 149, 149, 172, 173, 174, 175}, SKINCOLOR_GARNET, 8, V_SKYMAP, true}, // SKINCOLOR_AQUAMARINE {"Sky", {0x80, 0x80, 0x81, 0x82, 0x83, 0x83, 0x84, 0x85, 0x85, 0x86, 0x87, 0x88, 0x89, 0x89, 0x8a, 0x8b}, SKINCOLOR_SANDY, 1, V_SKYMAP, true}, // SKINCOLOR_SKY - {"Marine", { 144, 146, 147, 147, 148, 135, 136, 136, 137, 137, 127, 118, 119, 111, 111, 111}, SKINCOLOR_KIWI, 13, V_SKYMAP, true}, // SKINCOLOR_MARINE + {"Marine", { 144, 146, 147, 147, 148, 135, 136, 136, 137, 137, 127, 118, 119, 111, 111, 111}, SKINCOLOR_PEAR, 13, V_SKYMAP, true}, // SKINCOLOR_MARINE {"Cerulean", {0x85, 0x86, 0x87, 0x88, 0x88, 0x89, 0x89, 0x89, 0x8a, 0x8a, 0xfd, 0xfd, 0xfd, 0x1f, 0x1f, 0x1f}, SKINCOLOR_NEON, 4, V_SKYMAP, true}, // SKINCOLOR_CERULEAN {"Dream", { 80, 208, 200, 200, 146, 146, 133, 134, 135, 136, 137, 138, 139, 139, 254, 254}, SKINCOLOR_FOUNDATION, 9, V_SKYMAP, true}, // SKINCOLOR_DREAM {"Icy", {0x00, 0x00, 0x00, 0x00, 0x80, 0x81, 0x83, 0x83, 0x86, 0x87, 0x95, 0x95, 0xad, 0xad, 0xae, 0xaf}, SKINCOLOR_CRIMSON, 0, V_SKYMAP, true}, // SKINCOLOR_ICY From f261b9f0e118d6b6ac7216514423b06e888ab0e1 Mon Sep 17 00:00:00 2001 From: katsy <205-katsy@users.noreply.git.do.srb2.org> Date: Wed, 5 Jul 2023 17:05:47 +0000 Subject: [PATCH 230/586] Add player->powers[pw_strong], refactor attacks and busting conditions, and allow breaking floors and ceilings separately --- src/d_player.h | 35 +++++++++++++++++ src/deh_tables.c | 28 +++++++++++++- src/p_inter.c | 34 ++++++++--------- src/p_map.c | 90 +++++++++++++++++--------------------------- src/p_saveg.c | 2 + src/p_user.c | 97 ++++++++++++++++++++++++++++++++---------------- 6 files changed, 179 insertions(+), 107 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index 6df6689c5..1b2c99743 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -249,6 +249,38 @@ typedef enum CR_FAN } carrytype_t; // pw_carry +typedef enum +{ + STR_NONE = 0, // All strong powers can stack onto each other + + // Attack powers + STR_ANIM = 0x1, // remove powers when leaving current animation + STR_PUNCH = 0x2, // frontal attack (knuckles glide) + STR_TAIL = 0x4, // rear attack + STR_STOMP = 0x8, // falling onto object (fang bounce) + STR_UPPER = 0x10, // moving upwards into object (tails fly) + STR_GUARD = 0x20, //protect against damage + STR_HEAVY = 0x40, // ignore vertical rebound + STR_DASH = 0x80, // special type for machine dashmode, automatically removes your powers when leaving dashmode + + // Environment powers + STR_WALL = 0x100, // fof busting + STR_FLOOR = 0x200, + STR_CEILING = 0x400, + STR_SPRING = 0x800, // power up hit springs + STR_SPIKE = 0x1000, // break spikes + + // Shortcuts + STR_ATTACK = STR_PUNCH|STR_TAIL|STR_STOMP|STR_UPPER, + STR_BUST = STR_WALL|STR_FLOOR|STR_CEILING, + STR_FLY = STR_ANIM|STR_UPPER, + STR_GLIDE = STR_ANIM|STR_PUNCH, + STR_TWINSPIN = STR_ANIM|STR_ATTACK|STR_BUST|STR_SPRING|STR_SPIKE, + STR_MELEE = STR_ANIM|STR_PUNCH|STR_HEAVY|STR_WALL|STR_FLOOR|STR_SPRING|STR_SPIKE, + STR_BOUNCE = STR_ANIM|STR_STOMP|STR_FLOOR, + STR_METAL = STR_DASH|STR_SPIKE +} strongtype_t; // pw_strong + // Player powers. (don't edit this comment) typedef enum { @@ -293,6 +325,8 @@ typedef enum pw_ignorelatch, // Don't grab onto CR_GENERIC, add 32768 (powers[pw_ignorelatch] & 1<<15) to avoid ALL not-NiGHTS CR_ types + pw_strong, // Additional properties for powerful attacks + NUMPOWERS } powertype_t; @@ -405,6 +439,7 @@ typedef struct player_s // playing animation. panim_t panim; + UINT8 stronganim; // For screen flashing (bright). UINT16 flashcount; diff --git a/src/deh_tables.c b/src/deh_tables.c index 11d8b1a01..c7c53f650 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -4768,7 +4768,9 @@ const char *const POWERS_LIST[] = { "JUSTLAUNCHED", - "IGNORELATCH" + "IGNORELATCH", + + "STRONG" }; const char *const HUDITEMS_LIST[] = { @@ -5121,6 +5123,30 @@ struct int_const_s const INT_CONST[] = { {"CR_DUSTDEVIL",CR_DUSTDEVIL}, {"CR_FAN",CR_FAN}, + // Strong powers + {"STR_NONE",STR_NONE}, + {"STR_ANIM",STR_ANIM}, + {"STR_PUNCH",STR_PUNCH}, + {"STR_TAIL",STR_TAIL}, + {"STR_STOMP",STR_STOMP}, + {"STR_UPPER",STR_UPPER}, + {"STR_GUARD",STR_GUARD}, + {"STR_HEAVY",STR_HEAVY}, + {"STR_DASH",STR_DASH}, + {"STR_WALL",STR_WALL}, + {"STR_FLOOR",STR_FLOOR}, + {"STR_CEILING",STR_CEILING}, + {"STR_SPRING",STR_SPRING}, + {"STR_SPIKE",STR_SPIKE}, + {"STR_ATTACK",STR_ATTACK}, + {"STR_BUST",STR_BUST}, + {"STR_FLY",STR_FLY}, + {"STR_GLIDE",STR_GLIDE}, + {"STR_TWINSPIN",STR_TWINSPIN}, + {"STR_MELEE",STR_MELEE}, + {"STR_BOUNCE",STR_BOUNCE}, + {"STR_METAL",STR_METAL}, + // Ring weapons (ringweapons_t) // Useful for A_GiveWeapon {"RW_AUTO",RW_AUTO}, diff --git a/src/p_inter.c b/src/p_inter.c index c230ce178..cc8a1d2b9 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -465,23 +465,20 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (special->type == MT_PTERABYTE && special->target == player->mo && special->extravalue1 == 1) return; // Can't hurt a Pterabyte if it's trying to pick you up - if ((P_MobjFlip(toucher)*toucher->momz < 0) && (elementalpierce != 1)) + if ((P_MobjFlip(toucher)*toucher->momz < 0) && (elementalpierce != 1) && (!(player->powers[pw_strong] & STR_HEAVY))) { - 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 { - 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! - } + boolean underwater = toucher->eflags & MFE_UNDERWATER; + + if (underwater) + toucher->momz /= 2; + toucher->momz -= (toucher->momz/(underwater ? 8 : 4)); // Cap the height! } } if (player->pflags & PF_BOUNCING) @@ -500,8 +497,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) toucher->momx = 7*toucher->momx>>3; toucher->momy = 7*toucher->momy>>3; } - else if (player->dashmode >= DASHMODE_THRESHOLD && (player->charflags & (SF_DASHMODE|SF_MACHINE)) == (SF_DASHMODE|SF_MACHINE) - && player->panim == PA_DASH) + else if ((player->powers[pw_strong] & STR_DASH) && player->panim == PA_DASH) P_DoPlayerPain(player, special, special); } P_DamageMobj(special, toucher, toucher, 1, 0); @@ -3213,7 +3209,7 @@ static boolean P_PlayerHitsPlayer(mobj_t *target, mobj_t *inflictor, mobj_t *sou return false; // Add pity. - if (!player->powers[pw_flashing] && !player->powers[pw_invulnerability] && !player->powers[pw_super] + if (!player->powers[pw_flashing] && !player->powers[pw_invulnerability] && !player->powers[pw_super] && !(player->powers[pw_strong] & STR_GUARD) && source->player->score > player->score) player->pity++; @@ -3683,7 +3679,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da } return false; } - else if (player->powers[pw_invulnerability] || player->powers[pw_flashing] || player->powers[pw_super]) // ignore bouncing & such in invulnerability + else if (player->powers[pw_invulnerability] || player->powers[pw_flashing] || player->powers[pw_super] || (player->powers[pw_strong] & STR_GUARD)) // ignore bouncing & such in invulnerability { if (force || (inflictor && inflictor->flags & MF_MISSILE && inflictor->flags2 & MF2_SUPERFIRE)) // Super Sonic is stunned! diff --git a/src/p_map.c b/src/p_map.c index 2bb02503f..3dc913435 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -152,10 +152,8 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) { if (spring->info->painchance == 3) ; - else if (object->player->charability == CA_TWINSPIN && object->player->panim == PA_ABILITY) + else if (object->player->powers[pw_strong] & STR_SPRING) strong = 1; - else if (object->player->charability2 == CA2_MELEE && object->player->panim == PA_ABILITY2) - strong = 2; } if (spring->info->painchance == -1) // Pinball bumper mode. @@ -455,7 +453,8 @@ springstate: if (strong) { - P_TwinSpinRejuvenate(object->player, (strong == 1 ? object->player->thokitem : object->player->revitem)); + if (object->player->charability == CA_TWINSPIN || object->player->charability2 == CA2_MELEE) + P_TwinSpinRejuvenate(object->player, (object->player->charability == CA_TWINSPIN ? object->player->thokitem : object->player->revitem)); S_StartSound(object, sfx_sprong); // strong spring. sprong. } } @@ -796,43 +795,25 @@ static boolean PIT_CheckThing(mobj_t *thing) return true; } - // SF_DASHMODE users destroy spikes and monitors, CA_TWINSPIN users and CA2_MELEE users destroy spikes. - if ((tmthing->player) - && ((((tmthing->player->charflags & (SF_DASHMODE|SF_MACHINE)) == (SF_DASHMODE|SF_MACHINE)) && (tmthing->player->dashmode >= DASHMODE_THRESHOLD) - && (thing->flags & (MF_MONITOR) - || (thing->type == MT_SPIKE - || thing->type == MT_WALLSPIKE))) - || ((((tmthing->player->charability == CA_TWINSPIN) && (tmthing->player->panim == PA_ABILITY)) - || (tmthing->player->charability2 == CA2_MELEE && tmthing->player->panim == PA_ABILITY2)) - && (thing->type == MT_SPIKE - || thing->type == MT_WALLSPIKE)))) + // STR_SPIKE users destroy spikes + if ((tmthing->player) && ((tmthing->player->powers[pw_strong] & STR_SPIKE) && (thing->type == MT_SPIKE || thing->type == MT_WALLSPIKE))) { - if ((thing->flags & (MF_MONITOR)) && (thing->health <= 0 || !(thing->flags & MF_SHOOTABLE))) - return true; - blockdist = thing->radius + tmthing->radius; - if (abs(thing->x - tmx) >= blockdist || abs(thing->y - tmy) >= blockdist) - return true; // didn't hit it - // see if it went over / under - if (tmthing->z > thing->z + thing->height) - return true; // overhead - if (tmthing->z + tmthing->height < thing->z) - return true; // underneath - if (thing->type == MT_SPIKE - || thing->type == MT_WALLSPIKE) - { - mobj_t *iter; - 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)) - P_KillMobj(iter, tmthing, tmthing, 0); - return true; - } - else - { - if (P_DamageMobj(thing, tmthing, tmthing, 1, 0)) - return true; - } + mobj_t *iter; + blockdist = thing->radius + tmthing->radius; + if (abs(thing->x - tmx) >= blockdist || abs(thing->y - tmy) >= blockdist) + return true; // didn't hit it + // see if it went over / under + if (tmthing->z > thing->z + thing->height) + return true; // overhead + if (tmthing->z + tmthing->height < thing->z) + return true; // underneath + + 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)) + P_KillMobj(iter, tmthing, tmthing, 0); + return true; } // vectorise metal - done in a special case as at this point neither has the right flags for touching @@ -1687,25 +1668,22 @@ static boolean PIT_CheckThing(mobj_t *thing) // Going down? Then bounce back up. if (P_DamageMobj(thing, tmthing, tmthing, 1, 0) // break the monitor && (flipval*(*momz) < 0) // monitor is on the floor and you're going down, or on the ceiling and you're going up - && (elementalpierce != 1)) // you're not piercing through the monitor... + && (elementalpierce != 1) && (!(player->powers[pw_strong] & STR_HEAVY))) // you're not piercing through the monitor... { - 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. + if (player->charability == CA_TWINSPIN && player->panim == PA_ABILITY) + P_TwinSpinRejuvenate(player, player->thokitem); + if (elementalpierce == 2) // Reset bubblewrap, part 2 { - fixed_t setmomz = -*momz; // Store this, momz get changed by P_DoJump within P_DoBubbleBounce + boolean underwater = tmthing->eflags & MFE_UNDERWATER; - if (elementalpierce == 2) // Reset bubblewrap, part 1 - P_DoBubbleBounce(player); - *momz = setmomz; // Therefore, you should be thrust in the opposite direction, vertically. - if (player->charability == CA_TWINSPIN && player->panim == PA_ABILITY) - P_TwinSpinRejuvenate(player, player->thokitem); - 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! - } + if (underwater) + *momz /= 2; + *momz -= (*momz/(underwater ? 8 : 4)); // Cap the height! } } if (!(elementalpierce == 1 && thing->flags & MF_GRENADEBOUNCE)) // prevent gold monitor clipthrough. diff --git a/src/p_saveg.c b/src/p_saveg.c index 07b3d8640..b5907cfb8 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -167,6 +167,7 @@ static void P_NetArchivePlayers(void) WRITEUINT8(save_p, players[i].playerstate); WRITEUINT32(save_p, players[i].pflags); WRITEUINT8(save_p, players[i].panim); + WRITEUINT8(save_p, players[i].stronganim); WRITEUINT8(save_p, players[i].spectator); WRITEUINT16(save_p, players[i].flashpal); @@ -394,6 +395,7 @@ static void P_NetUnArchivePlayers(void) players[i].playerstate = READUINT8(save_p); players[i].pflags = READUINT32(save_p); players[i].panim = READUINT8(save_p); + players[i].stronganim = READUINT8(save_p); players[i].spectator = READUINT8(save_p); players[i].flashpal = READUINT16(save_p); diff --git a/src/p_user.c b/src/p_user.c index 2f522ad4b..464cc521d 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -988,6 +988,8 @@ void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor) if (player->powers[pw_carry] == CR_ROPEHANG) P_SetTarget(&player->mo->tracer, NULL); + player->powers[pw_strong] = STR_NONE; + { angle_t ang; fixed_t fallbackspeed; @@ -1105,6 +1107,7 @@ void P_ResetPlayer(player_t *player) boolean P_PlayerCanDamage(player_t *player, mobj_t *thing) { fixed_t bottomheight, topheight; + boolean allatk = ((player->powers[pw_strong] & STR_PUNCH) && (player->powers[pw_strong] & STR_TAIL) && (player->powers[pw_strong] & STR_STOMP) && (player->powers[pw_strong] & STR_UPPER)); if (!player->mo || player->spectator || !thing || P_MobjWasRemoved(thing)) return false; @@ -1129,22 +1132,33 @@ boolean P_PlayerCanDamage(player_t *player, mobj_t *thing) // Jumping. if ((player->pflags & PF_JUMPED) - && (!(player->pflags & PF_NOJUMPDAMAGE) - || (player->charability == CA_TWINSPIN && player->panim == PA_ABILITY))) + && (!(player->pflags & PF_NOJUMPDAMAGE))) return true; // Spinning. if (player->pflags & PF_SPINNING) return true; - if (player->dashmode >= DASHMODE_THRESHOLD && (player->charflags & (SF_DASHMODE|SF_MACHINE)) == (SF_DASHMODE|SF_MACHINE)) + // Shield stomp. + if (((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL || (player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP) && (player->pflags & PF_SHIELDABILITY)) + return true; + + // pw_strong checks below here + + // Omnidirectional attacks. + if (allatk || (player->powers[pw_strong] & STR_DASH)) return true; // From the front. - if (((player->pflags & PF_GLIDING) || (player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2)) + if ((player->powers[pw_strong] & STR_PUNCH) && (player->drawangle - R_PointToAngle2(player->mo->x - player->mo->momx, player->mo->y - player->mo->momy, thing->x, thing->y) + + ANGLE_90) < ANGLE_180) return true; + // From the back. + if ((player->powers[pw_strong] & STR_TAIL) + && (player->drawangle - R_PointToAngle2(player->mo->x - player->mo->momx, player->mo->y - player->mo->momy, thing->x, thing->y) + + ANGLE_90) >= ANGLE_180) + return true; + // From the top/bottom. bottomheight = player->mo->z; topheight = player->mo->z + player->mo->height; @@ -1158,19 +1172,15 @@ boolean P_PlayerCanDamage(player_t *player, mobj_t *thing) if (P_MobjFlip(player->mo)*(bottomheight - (thing->z + thing->height/2)) > 0) { - if ((player->charflags & SF_STOMPDAMAGE || player->pflags & PF_BOUNCING) && (P_MobjFlip(player->mo)*(player->mo->momz - thing->momz) < 0)) + if ((player->charflags & SF_STOMPDAMAGE || player->powers[pw_strong] & STR_STOMP) && (P_MobjFlip(player->mo)*(player->mo->momz - thing->momz) < 0)) return true; } else if (P_MobjFlip(player->mo)*(topheight - (thing->z + thing->height/2)) < 0) { - if (player->charability == CA_FLY && player->panim == PA_ABILITY && !(player->mo->eflags & MFE_UNDERWATER) && (P_MobjFlip(player->mo)*(player->mo->momz - thing->momz) > 0)) + if ((player->powers[pw_strong] & STR_UPPER) && (player->mo->sprite2 != SPR2_SWIM) && (P_MobjFlip(player->mo)*(player->mo->momz - thing->momz) > 0)) return true; } - // Shield stomp. - if (((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL || (player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP) && (player->pflags & PF_SHIELDABILITY)) - return true; - return false; } @@ -2324,6 +2334,7 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff) player->mo->tics = (player->mo->movefactor == FRACUNIT) ? TICRATE/2 : (FixedDiv(35<<(FRACBITS-1), FixedSqrt(player->mo->movefactor)))>>FRACBITS; S_StartSound(player->mo, sfx_s3k8b); player->pflags |= PF_FULLSTASIS; + player->powers[pw_strong] = STR_MELEE; // hearticles if (type) @@ -2513,17 +2524,13 @@ static boolean P_PlayerCanBust(player_t *player, ffloor_t *rover) return true; // Passive wall breaking - if (player->charflags & SF_CANBUSTWALLS) + if (player->charflags & SF_CANBUSTWALLS || player->powers[pw_strong] & (STR_WALL|STR_FLOOR|STR_CEILING|STR_DASH)) return true; // Super if (player->powers[pw_super]) return true; - // Dashmode - if ((player->charflags & (SF_DASHMODE|SF_MACHINE)) == (SF_DASHMODE|SF_MACHINE) && player->dashmode >= DASHMODE_THRESHOLD) - return true; - // NiGHTS drill if (player->pflags & PF_DRILLING) return true; @@ -2534,21 +2541,11 @@ static boolean P_PlayerCanBust(player_t *player, ffloor_t *rover) /* FALLTHRU */ case BT_STRONG: // Requires a "strong ability" - if (player->charflags & SF_CANBUSTWALLS) - return true; - - if (player->pflags & PF_BOUNCING) - return true; - - if (player->charability == CA_TWINSPIN && player->panim == PA_ABILITY) - return true; - - if (player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2) + if (player->charflags & SF_CANBUSTWALLS || player->powers[pw_strong] & (STR_WALL|STR_FLOOR|STR_CEILING)) return true; break; } - return false; } @@ -2564,7 +2561,7 @@ static void P_CheckBustableBlocks(player_t *player) oldx = player->mo->x; oldy = player->mo->y; - if (!(player->pflags & PF_BOUNCING)) // Bouncers only get to break downwards, not sideways + if (!((player->powers[pw_strong] & (STR_FLOOR|STR_CEILING)) && (!(player->powers[pw_strong] & STR_WALL)) && (!(player->charflags & SF_CANBUSTWALLS)))) // Don't break sideways without wall powers { P_UnsetThingPosition(player->mo); player->mo->x += player->mo->momx; @@ -2591,8 +2588,24 @@ static void P_CheckBustableBlocks(player_t *player) topheight = P_GetFOFTopZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL); bottomheight = P_GetFOFBottomZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL); - if (((player->charability == CA_TWINSPIN) && (player->panim == PA_ABILITY)) - || ((P_MobjFlip(player->mo)*player->mo->momz < 0) && (player->pflags & PF_BOUNCING || ((player->charability2 == CA2_MELEE) && (player->panim == PA_ABILITY2))))) + // Height checks + if (player->mo->eflags & MFE_VERTICALFLIP) + { + if ((player->powers[pw_strong] & STR_FLOOR) && (!(player->powers[pw_strong] & STR_CEILING)) && player->mo->z > topheight) + continue; + + if ((player->powers[pw_strong] & STR_CEILING) && (!(player->powers[pw_strong] & STR_FLOOR)) && player->mo->z + player->mo->height < bottomheight) + continue; + } + else + { + if ((player->powers[pw_strong] & STR_FLOOR) && (!(player->powers[pw_strong] & STR_CEILING)) && player->mo->z < bottomheight) + continue; + + if ((player->powers[pw_strong] & STR_CEILING) && (!(player->powers[pw_strong] & STR_FLOOR)) && player->mo->z + player->mo->height > topheight) + continue; + } + if (player->powers[pw_strong] & (STR_FLOOR|STR_CEILING)) { topheight -= player->mo->momz; bottomheight -= player->mo->momz; @@ -2660,7 +2673,7 @@ static void P_CheckBustableBlocks(player_t *player) } } bustupdone: - if (!(player->pflags & PF_BOUNCING)) + if (!((player->powers[pw_strong] & (STR_FLOOR|STR_CEILING)) && (!(player->powers[pw_strong] & STR_WALL)) && (!(player->charflags & SF_CANBUSTWALLS)))) { P_UnsetThingPosition(player->mo); player->mo->x = oldx; @@ -4690,6 +4703,7 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) player->mo->momx += player->cmomx; player->mo->momy += player->cmomy; P_SetPlayerMobjState(player->mo, S_PLAY_MELEE); + player->powers[pw_strong] = STR_MELEE; S_StartSound(player->mo, sfx_s3k42); } player->pflags |= PF_SPINDOWN; @@ -4937,6 +4951,7 @@ static void P_DoTwinSpin(player_t *player) S_StartSound(player->mo, sfx_s3k42); player->mo->frame = 0; P_SetPlayerMobjState(player->mo, S_PLAY_TWINSPIN); + player->powers[pw_strong] = STR_TWINSPIN; } // @@ -5300,6 +5315,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) player->pflags |= PF_THOKKED; else player->pflags |= (PF_THOKKED|PF_CANCARRY); + player->powers[pw_strong] = STR_FLY; } break; case CA_GLIDEANDCLIMB: @@ -5326,7 +5342,8 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) P_SetPlayerMobjState(player->mo, S_PLAY_GLIDE); if (playerspeed < glidespeed) P_Thrust(player->mo, player->mo->angle, glidespeed - playerspeed); - player->pflags &= ~(PF_SPINNING|PF_STARTDASH); + player->pflags &= ~(PF_JUMPED|PF_SPINNING|PF_STARTDASH); + player->powers[pw_strong] = STR_GLIDE; } break; case CA_DOUBLEJUMP: // Double-Jump @@ -5383,6 +5400,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) P_SetPlayerMobjState(player->mo, S_PLAY_BOUNCE); player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE); player->pflags |= PF_THOKKED|PF_BOUNCING; + player->powers[pw_strong] = STR_BOUNCE; player->mo->momx >>= 1; player->mo->momy >>= 1; player->mo->momz >>= 1; @@ -12070,6 +12088,16 @@ void P_PlayerThink(player_t *player) else player->powers[pw_ignorelatch] = 0; + if (player->powers[pw_strong] & STR_ANIM) + { + if (!(player->stronganim)) + player->stronganim = player->panim; + else if (player->panim != player->stronganim) + player->powers[pw_strong] = STR_NONE; + } + else if (player->stronganim) + player->stronganim = 0; + //pw_super acts as a timer now if (player->powers[pw_super] && (player->mo->state < &states[S_PLAY_SUPER_TRANS1] @@ -12164,6 +12192,8 @@ void P_PlayerThink(player_t *player) { player->normalspeed = skins[player->skin].normalspeed; // Reset to default if not capable of entering dash mode. player->jumpfactor = skins[player->skin].jumpfactor; + if (player->powers[pw_strong] & STR_DASH) + player->powers[pw_strong] = STR_NONE; } } else if (P_IsObjectOnGround(player->mo)) // Activate dash mode if we're on the ground. @@ -12173,6 +12203,9 @@ void P_PlayerThink(player_t *player) if (player->jumpfactor < FixedMul(skins[player->skin].jumpfactor, 5*FRACUNIT/4)) // Boost jump height. player->jumpfactor += FRACUNIT/300; + + if ((player->charflags & SF_MACHINE) && (!(player->powers[pw_strong] == STR_METAL))) + player->powers[pw_strong] = STR_METAL; } if (player->normalspeed >= skins[player->skin].normalspeed*2) @@ -12190,6 +12223,8 @@ void P_PlayerThink(player_t *player) player->normalspeed = skins[player->skin].normalspeed; player->jumpfactor = skins[player->skin].jumpfactor; S_StartSound(player->mo, sfx_kc65); + if (player->powers[pw_strong] & STR_DASH) + player->powers[pw_strong] = STR_NONE; } dashmode = 0; } From 4342dacbdff30383d7e804cb2bb46d20045852c1 Mon Sep 17 00:00:00 2001 From: MIDIMan Date: Wed, 5 Jul 2023 14:21:53 -0400 Subject: [PATCH 231/586] Fix A_FishJump for custom objects in binary maps --- src/p_enemy.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index fe062cffc..5e52993cc 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -4886,7 +4886,9 @@ void A_FishJump(mobj_t *actor) jumpval = locvar1; else { - if (actor->spawnpoint && actor->spawnpoint->args[0]) + if (!udmf && actor->angle) + jumpval = AngleFixed(actor->angle)>>2; + else if (actor->spawnpoint && actor->spawnpoint->args[0]) jumpval = actor->spawnpoint->args[0] << (FRACBITS - 2); else jumpval = 44 << (FRACBITS - 2); From 8f75141c0779c6ec6e8ee91dc796341029f691e8 Mon Sep 17 00:00:00 2001 From: spherallic Date: Thu, 6 Jul 2023 12:38:02 +0200 Subject: [PATCH 232/586] Give drop shadows to weapon rings & panels --- src/p_mobj.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/p_mobj.c b/src/p_mobj.c index a43afc9b1..44140042e 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10581,6 +10581,8 @@ static fixed_t P_DefaultMobjShadowScale (mobj_t *thing) if (thing->flags & (MF_ENEMY|MF_BOSS)) return FRACUNIT; + else if (P_WeaponOrPanel(thing->type)) + return 2*FRACUNIT/3; else return 0; } From a4bcf4e2cefa850fa0996e19e0fdb6d502cbafad Mon Sep 17 00:00:00 2001 From: spherallic Date: Thu, 6 Jul 2023 18:06:23 +0200 Subject: [PATCH 233/586] Do not consider 0 a valid executor tag for bosses --- 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 fe062cffc..e00a1a882 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -3938,7 +3938,7 @@ static void P_DoBossVictory(mobj_t *mo) } // victory! - if (mo->spawnpoint) + if (mo->spawnpoint && mo->spawnpoint->args[3]) P_LinedefExecute(mo->spawnpoint->args[3], mo, NULL); if (stoppedclock && modeattacking) // if you're just time attacking, skip making the capsule appear since you don't need to step on it anyways. @@ -4157,7 +4157,7 @@ void A_BossDeath(mobj_t *mo) if (LUA_CallAction(A_BOSSDEATH, mo)) return; - if (mo->spawnpoint) + if (mo->spawnpoint && mo->spawnpoint->args[2]) P_LinedefExecute(mo->spawnpoint->args[2], mo, NULL); mo->health = 0; @@ -7136,7 +7136,7 @@ void A_Boss1Chase(mobj_t *actor) } else { - if (actor->spawnpoint) + if (actor->spawnpoint && actor->spawnpoint->args[4]) P_LinedefExecute(actor->spawnpoint->args[4], actor, NULL); P_SetMobjState(actor, actor->info->raisestate); } From 49528c15580f6c710ca8fd222d413fdb2caa13a6 Mon Sep 17 00:00:00 2001 From: spherallic Date: Thu, 6 Jul 2023 18:11:52 +0200 Subject: [PATCH 234/586] Remove generalized FOF type (linedef action 260) --- src/p_spec.c | 65 ---------------------------------------------------- 1 file changed, 65 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index 71ea145b9..9195ef019 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -6880,71 +6880,6 @@ void P_SpawnSpecials(boolean fromnetsave) } break; - case 260: // GZDoom-like 3D Floor. - { - UINT8 dtype = lines[i].args[1] & 3; - UINT8 dflags1 = lines[i].args[1] - dtype; - UINT8 dflags2 = lines[i].args[2]; - UINT8 dopacity = lines[i].args[3]; - boolean isfog = false; - - if (dtype == 0) - dtype = 1; - - ffloorflags = FOF_EXISTS; - - if (dflags2 & 1) ffloorflags |= FOF_NOSHADE; // Disable light effects (Means no shadowcast) - if (dflags2 & 2) ffloorflags |= FOF_DOUBLESHADOW; // Restrict light inside (Means doubleshadow) - if (dflags2 & 4) isfog = true; // Fog effect (Explicitly render like a fog block) - - if (dflags1 & 4) ffloorflags |= FOF_BOTHPLANES|FOF_ALLSIDES; // Render-inside - if (dflags1 & 16) ffloorflags |= FOF_INVERTSIDES|FOF_INVERTPLANES; // Invert visibility rules - - // Fog block - if (isfog) - ffloorflags |= FOF_RENDERALL|FOF_CUTEXTRA|FOF_CUTSPRITES|FOF_BOTHPLANES|FOF_EXTRA|FOF_FOG|FOF_INVERTPLANES|FOF_ALLSIDES|FOF_INVERTSIDES; - else - { - ffloorflags |= FOF_RENDERALL; - - // Solid - if (dtype == 1) - ffloorflags |= FOF_SOLID|FOF_CUTLEVEL; - // Water - else if (dtype == 2) - ffloorflags |= FOF_SWIMMABLE|FOF_CUTEXTRA|FOF_CUTSPRITES|FOF_EXTRA|FOF_RIPPLE; - // Intangible - else if (dtype == 3) - ffloorflags |= FOF_CUTEXTRA|FOF_CUTSPRITES|FOF_EXTRA; - } - - // Non-opaque - if (dopacity < 255) - { - // Invisible - if (dopacity == 0) - { - // True invisible - if (ffloorflags & FOF_NOSHADE) - ffloorflags &= ~(FOF_RENDERALL|FOF_CUTEXTRA|FOF_CUTSPRITES|FOF_EXTRA|FOF_BOTHPLANES|FOF_ALLSIDES|FOF_CUTLEVEL); - // Shadow block - else - { - ffloorflags |= FOF_CUTSPRITES; - ffloorflags &= ~(FOF_RENDERALL|FOF_CUTEXTRA|FOF_EXTRA|FOF_BOTHPLANES|FOF_ALLSIDES|FOF_CUTLEVEL); - } - } - else - { - ffloorflags |= FOF_TRANSLUCENT|FOF_CUTEXTRA|FOF_EXTRA; - ffloorflags &= ~FOF_CUTLEVEL; - } - } - - P_AddFakeFloorsByLine(i, dopacity, TMB_TRANSLUCENT, ffloorflags, secthinkers); - } - break; - case 300: // Trigger linedef executor case 303: // Count rings case 305: // Character ability From 29703f8d6ad7c4923bd088416b874373f2d74d1a Mon Sep 17 00:00:00 2001 From: spherallic Date: Thu, 6 Jul 2023 18:26:30 +0200 Subject: [PATCH 235/586] Remove action 260 from the UDMF config --- extras/conf/udb/Includes/SRB222_linedefs.cfg | 46 -------------------- 1 file changed, 46 deletions(-) diff --git a/extras/conf/udb/Includes/SRB222_linedefs.cfg b/extras/conf/udb/Includes/SRB222_linedefs.cfg index 621b4abd5..680778623 100644 --- a/extras/conf/udb/Includes/SRB222_linedefs.cfg +++ b/extras/conf/udb/Includes/SRB222_linedefs.cfg @@ -1221,52 +1221,6 @@ udmf } } } - 260 - { - title = "Generalized 3D Floor"; - prefix = "(260)"; - id = "Sector_Set3dFloor"; - requiresactivation = false; - - arg0 - { - title = "Target sector tag"; - type = 13; - } - arg1 - { - title = "Type"; - type = 26; - default = 1; - enum - { - 1 = "Solid"; - 2 = "Water"; - 3 = "Intangible"; - } - flags - { - 4 = "Render insides"; - 16 = "Only render insides"; - } - } - arg2 - { - title = "Flags"; - type = 12; - enum - { - 1 = "No shadow"; - 2 = "Double shadow"; - 4 = "Fog"; - } - } - arg3 - { - title = "Alpha"; - default = 255; - } - } } linedeftrigger From 8d8257b4a642cda4061c50e4afca2b62f5490af0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Thu, 6 Jul 2023 19:12:29 +0200 Subject: [PATCH 236/586] Handle missing frames for sprite gracefully --- 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 2c031ee85..db3227307 100644 --- a/src/r_skins.c +++ b/src/r_skins.c @@ -534,7 +534,7 @@ static void R_LoadSkinSprites(UINT16 wadnum, UINT16 *lump, UINT16 *lastlump, ski 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]); + CONS_Alert(CONS_ERROR, M_GetText("No frames found for sprite SPR2_%s\n"), spr2names[0]); } // returns whether found appropriate property From 372bb8b8fc10e2eee4f1ede2e6460c3cda6521c9 Mon Sep 17 00:00:00 2001 From: Ace Lite Date: Thu, 6 Jul 2023 19:27:32 +0000 Subject: [PATCH 237/586] [UDMF] Updated line sloping warning message --- 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 48a13a07d..1f07b8f37 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -328,7 +328,7 @@ static void line_SpawnViaLine(const int linenum, const boolean spawnthinker) if(!frontfloor && !backfloor && !frontceil && !backceil) { - CONS_Printf("line_SpawnViaLine: Slope special with nothing to do.\n"); + CONS_Printf("line_SpawnViaLine: Unused slope special with nothing to do on line number %i\n", linenum); return; } From ecf0c4b45a756039ccde6ffd1845c0232220952d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Fri, 7 Jul 2023 21:35:41 +0200 Subject: [PATCH 238/586] Fix segfault when calling P_RemoveMobj from MobjCollide hook --- src/p_map.c | 240 ++++++++++++++++++++++++++-------------------------- 1 file changed, 122 insertions(+), 118 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index 0021fe450..0221fbc11 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -4005,131 +4005,135 @@ void P_BounceMove(mobj_t *mo) slidemo = mo; hitcount = 0; -retry: - if (++hitcount == 3) - goto bounceback; // don't loop forever + do + { + if (++hitcount == 3) + goto bounceback; // don't loop forever - if (mo->player) - { - mmomx = mo->player->rmomx; - mmomy = mo->player->rmomy; - } - else - { - mmomx = mo->momx; - mmomy = mo->momy; - } - - // trace along the three leading corners - if (mo->momx > 0) - { - leadx = mo->x + mo->radius; - trailx = mo->x - mo->radius; - } - else - { - leadx = mo->x - mo->radius; - trailx = mo->x + mo->radius; - } - - if (mo->momy > 0) - { - leady = mo->y + mo->radius; - traily = mo->y - mo->radius; - } - else - { - leady = mo->y - mo->radius; - traily = mo->y + mo->radius; - } - - bestslidefrac = FRACUNIT + 1; - - P_PathTraverse(leadx, leady, leadx + mmomx, leady + mmomy, PT_ADDLINES, PTR_SlideTraverse); - P_PathTraverse(trailx, leady, trailx + mmomx, leady + mmomy, PT_ADDLINES, PTR_SlideTraverse); - P_PathTraverse(leadx, traily, leadx + mmomx, traily + mmomy, PT_ADDLINES, PTR_SlideTraverse); - - // move up to the wall - if (bestslidefrac == FRACUNIT + 1) - { - // the move must have hit the middle, so bounce straight back -bounceback: - if (P_TryMove(mo, mo->x - mmomx, mo->y - mmomy, true)) + if (mo->player) { - mo->momx *= -1; - mo->momy *= -1; - mo->momx = FixedMul(mo->momx, (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3))); - mo->momy = FixedMul(mo->momy, (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3))); + mmomx = mo->player->rmomx; + mmomy = mo->player->rmomy; + } + else + { + mmomx = mo->momx; + mmomy = mo->momy; + } - if (mo->player) + // trace along the three leading corners + if (mo->momx > 0) + { + leadx = mo->x + mo->radius; + trailx = mo->x - mo->radius; + } + else + { + leadx = mo->x - mo->radius; + trailx = mo->x + mo->radius; + } + + if (mo->momy > 0) + { + leady = mo->y + mo->radius; + traily = mo->y - mo->radius; + } + else + { + leady = mo->y - mo->radius; + traily = mo->y + mo->radius; + } + + bestslidefrac = FRACUNIT + 1; + + P_PathTraverse(leadx, leady, leadx + mmomx, leady + mmomy, PT_ADDLINES, PTR_SlideTraverse); + P_PathTraverse(trailx, leady, trailx + mmomx, leady + mmomy, PT_ADDLINES, PTR_SlideTraverse); + P_PathTraverse(leadx, traily, leadx + mmomx, traily + mmomy, PT_ADDLINES, PTR_SlideTraverse); + + // move up to the wall + if (bestslidefrac == FRACUNIT + 1) + { + // the move must have hit the middle, so bounce straight back +bounceback: + if (P_TryMove(mo, mo->x - mmomx, mo->y - mmomy, true)) { - mo->player->cmomx *= -1; - mo->player->cmomy *= -1; - mo->player->cmomx = FixedMul(mo->player->cmomx, - (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3))); - mo->player->cmomy = FixedMul(mo->player->cmomy, - (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3))); + mo->momx *= -1; + mo->momy *= -1; + mo->momx = FixedMul(mo->momx, (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3))); + mo->momy = FixedMul(mo->momy, (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3))); + + if (mo->player) + { + mo->player->cmomx *= -1; + mo->player->cmomy *= -1; + mo->player->cmomx = FixedMul(mo->player->cmomx, + (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3))); + mo->player->cmomy = FixedMul(mo->player->cmomy, + (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3))); + } + } + return; + } + + // fudge a bit to make sure it doesn't hit + bestslidefrac -= 0x800; + if (bestslidefrac > 0) + { + newx = FixedMul(mmomx, bestslidefrac); + newy = FixedMul(mmomy, bestslidefrac); + + if (!P_TryMove(mo, mo->x + newx, mo->y + newy, true)) + { + if (P_MobjWasRemoved(mo)) + return; + goto bounceback; } } - return; + + // Now continue along the wall. + // First calculate remainder. + bestslidefrac = FRACUNIT - bestslidefrac; + + if (bestslidefrac > FRACUNIT) + bestslidefrac = FRACUNIT; + + if (bestslidefrac <= 0) + return; + + if (mo->type == MT_SHELL) + { + tmxmove = mmomx; + tmymove = mmomy; + } + else if (mo->type == MT_THROWNBOUNCE) + { + tmxmove = FixedMul(mmomx, (FRACUNIT - (FRACUNIT>>6) - (FRACUNIT>>5))); + tmymove = FixedMul(mmomy, (FRACUNIT - (FRACUNIT>>6) - (FRACUNIT>>5))); + } + else if (mo->type == MT_THROWNGRENADE || mo->type == MT_CYBRAKDEMON_NAPALM_BOMB_LARGE) + { + // Quickly decay speed as it bounces + tmxmove = FixedDiv(mmomx, 2*FRACUNIT); + tmymove = FixedDiv(mmomy, 2*FRACUNIT); + } + else + { + tmxmove = FixedMul(mmomx, (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3))); + tmymove = FixedMul(mmomy, (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3))); + } + + P_HitBounceLine(bestslideline); // clip the moves + + mo->momx = tmxmove; + mo->momy = tmymove; + + if (mo->player) + { + mo->player->cmomx = tmxmove; + mo->player->cmomy = tmymove; + } } - - // fudge a bit to make sure it doesn't hit - bestslidefrac -= 0x800; - if (bestslidefrac > 0) - { - newx = FixedMul(mmomx, bestslidefrac); - newy = FixedMul(mmomy, bestslidefrac); - - if (!P_TryMove(mo, mo->x + newx, mo->y + newy, true)) - goto bounceback; - } - - // Now continue along the wall. - // First calculate remainder. - bestslidefrac = FRACUNIT - bestslidefrac; - - if (bestslidefrac > FRACUNIT) - bestslidefrac = FRACUNIT; - - if (bestslidefrac <= 0) - return; - - if (mo->type == MT_SHELL) - { - tmxmove = mmomx; - tmymove = mmomy; - } - else if (mo->type == MT_THROWNBOUNCE) - { - tmxmove = FixedMul(mmomx, (FRACUNIT - (FRACUNIT>>6) - (FRACUNIT>>5))); - tmymove = FixedMul(mmomy, (FRACUNIT - (FRACUNIT>>6) - (FRACUNIT>>5))); - } - else if (mo->type == MT_THROWNGRENADE || mo->type == MT_CYBRAKDEMON_NAPALM_BOMB_LARGE) - { - // Quickly decay speed as it bounces - tmxmove = FixedDiv(mmomx, 2*FRACUNIT); - tmymove = FixedDiv(mmomy, 2*FRACUNIT); - } - else - { - tmxmove = FixedMul(mmomx, (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3))); - tmymove = FixedMul(mmomy, (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3))); - } - - P_HitBounceLine(bestslideline); // clip the moves - - mo->momx = tmxmove; - mo->momy = tmymove; - - if (mo->player) - { - mo->player->cmomx = tmxmove; - mo->player->cmomy = tmymove; - } - - if (!P_TryMove(mo, mo->x + tmxmove, mo->y + tmymove, true)) - goto retry; + while (!P_TryMove(mo, mo->x + tmxmove, mo->y + tmymove, true) && !P_MobjWasRemoved(mo)); } // From 3ff9e908feac1349fefccf11a171f3e1c21d6a09 Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+TatsuruIKR@users.noreply.github.com> Date: Fri, 7 Jul 2023 18:13:44 -0300 Subject: [PATCH 239/586] Signal handler minor refactor --- src/sdl/i_system.c | 76 +++++++++++++++++++++++++++++++++------------- 1 file changed, 55 insertions(+), 21 deletions(-) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 66eeffa30..847ab2646 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -325,56 +325,90 @@ static void write_backtrace(INT32 signal) static void I_ReportSignal(int num, int coredumped) { //static char msg[] = "oh no! back to reality!\r\n"; - const char * sigmsg; - char msg[128]; + const char *sigmsg, *sigttl; + char ttl[128]; switch (num) { // case SIGINT: -// sigmsg = "SIGINT - interrupted"; +// sigttl = "SIGINT" +// sigmsg = "SRB2 was interrupted prematurely by the user."; // break; case SIGILL: - sigmsg = "SIGILL - illegal instruction - invalid function image"; + sigmsg = "SRB2 has attempted to execute an illegal instruction and needs to close. %s"; + sigttl = "SIGILL"; // illegal instruction - invalid function image break; case SIGFPE: - sigmsg = "SIGFPE - mathematical exception"; + sigmsg = "SRB2 has encountered a mathematical exception and needs to close. %s"; + sigttl = "SIGFPE"; // mathematical exception break; case SIGSEGV: - sigmsg = "SIGSEGV - segment violation"; + sigmsg = "SRB2 has attempted to access a memory location that it shouldn't and needs to close. %s"; + sigttl = "SIGSEGV"; // segment violation break; // case SIGTERM: -// sigmsg = "SIGTERM - Software termination signal from kill"; +// sigmsg = "SRB2 was terminated by a kill signal."; +// sigttl = "SIGTERM"; // Software termination signal from kill // break; // case SIGBREAK: -// sigmsg = "SIGBREAK - Ctrl-Break sequence"; +// sigmsg = "SRB2 was terminated by a Ctrl-Break sequence."; +// sigttl = "SIGBREAK" // Ctrl-Break sequence // break; case SIGABRT: - sigmsg = "SIGABRT - abnormal termination triggered by abort call"; + sigmsg = "SRB2 was terminated by an abort signal. %s"; + sigttl = "SIGABRT"; // abnormal termination triggered by abort call break; default: - sprintf(msg,"signal number %d", num); + sigmsg = "SRB2 was terminated by an unknown signal. %s"; + + sprintf(ttl, "number %d", num); if (coredumped) - sigmsg = 0; + sigttl = 0; else - sigmsg = msg; + sigttl = ttl; } if (coredumped) { - if (sigmsg) - sprintf(msg, "%s (core dumped)", sigmsg); + if (sigttl) + sprintf(ttl, "%s (core dumped)", sigttl); else - strcat(msg, " (core dumped)"); + strcat(ttl, " (core dumped)"); - sigmsg = msg; + sigttl = ttl; } - I_OutputMsg("\nProcess killed by signal: %s\n\n", sigmsg); + sprintf(ttl, "Process killed by signal: %s", sigttl); - if (!M_CheckParm("-dedicated")) - SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, - "Process killed by signal", - sigmsg, NULL); + sigttl = ttl; + + I_OutputMsg("\n%s\n\n", sigttl); + + if (M_CheckParm("-dedicated")) + return; + + const SDL_MessageBoxButtonData buttons[] = { + { SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, 0, "OK" }, + { 0, 1, "Discord" }, + }; + + const SDL_MessageBoxData messageboxdata = { + SDL_MESSAGEBOX_ERROR, /* .flags */ + NULL, /* .window */ + sigttl, /* .title */ + va(sigmsg, + "\n\nTo help us figure out the cause, you can visit our official Discord server\nwhere you will find more instructions on how to submit a crash report.\n\nSorry for the inconvenience!"), /* .message */ + SDL_arraysize(buttons), /* .numbuttons */ + buttons, /* .buttons */ + NULL /* .colorScheme */ + }; + + int buttonid; + + SDL_ShowMessageBox(&messageboxdata, &buttonid); + + if (buttonid == 1) + SDL_OpenURL("https://www.srb2.org/discord"); } #ifndef NEWSIGNALHANDLER From 0aa763df8543cf98eb2ca8da1d3a77e80f3a3119 Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Sat, 8 Jul 2023 00:53:28 -0300 Subject: [PATCH 240/586] Do music fade callback on main thread --- src/sdl/mixer_sound.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index f13aaef5d..0a39c7f28 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -108,6 +108,7 @@ static UINT32 fading_timer; static UINT32 fading_duration; static INT32 fading_id; static void (*fading_callback)(void); +static boolean fading_do_callback; static boolean fading_nocleanup; #ifdef HAVE_GME @@ -213,7 +214,10 @@ static void var_cleanup(void) // HACK: See music_loop, where we want the fade timing to proceed after a non-looping // song has stopped playing if (!fading_nocleanup) + { fading_callback = NULL; + fading_do_callback = false; + } else fading_nocleanup = false; // use it once, set it back immediately @@ -330,6 +334,13 @@ void I_ShutdownSound(void) void I_UpdateSound(void) { + if (fading_do_callback) + { + if (fading_callback) + (*fading_callback)(); + fading_callback = NULL; + fading_do_callback = false; + } } /// ------------------------ @@ -654,9 +665,8 @@ static UINT32 get_adjusted_position(UINT32 position) static void do_fading_callback(void) { - if (fading_callback) - (*fading_callback)(); - fading_callback = NULL; + // TODO: Should I use a mutex here or something? + fading_do_callback = true; } /// ------------------------ From 281e6012f3cf5b27dde2816ad1bacb4fe50c8634 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Sat, 8 Jul 2023 14:02:32 +0200 Subject: [PATCH 241/586] Fix segfault when exiting game with automap open --- src/d_netcmd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index af44e53d6..361d32008 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -4609,6 +4609,7 @@ void Command_ExitGame_f(void) botskin = 0; cv_debug = 0; emeralds = 0; + automapactive = false; memset(&luabanks, 0, sizeof(luabanks)); if (dirmenu) From 8cc0feb21d41adebe9faef6cd5484d912e0c8e08 Mon Sep 17 00:00:00 2001 From: katsy Date: Sat, 8 Jul 2023 15:17:53 -0500 Subject: [PATCH 242/586] fix reading and writing of shieldscale and camerascale to record attack demos --- src/g_demo.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/g_demo.c b/src/g_demo.c index 0403da16d..51001c6d0 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -1493,8 +1493,8 @@ void G_BeginRecording(void) WRITEUINT8(demo_p,player->acceleration); WRITEFIXED(demo_p,player->height); WRITEFIXED(demo_p,player->spinheight); - WRITEUINT8(demo_p,player->camerascale>>FRACBITS); - WRITEUINT8(demo_p,player->shieldscale>>FRACBITS); + WRITEFIXED(demo_p,player->camerascale); + WRITEFIXED(demo_p,player->shieldscale); // Trying to convert it back to % causes demo desync due to precision loss. // Don't do it. @@ -1923,8 +1923,8 @@ void G_DoPlayDemo(char *defdemoname) acceleration = READUINT8(demo_p); height = (demoversion < 0x000e) ? (fixed_t)READUINT8(demo_p)< Date: Sat, 8 Jul 2023 16:14:37 -0500 Subject: [PATCH 243/586] actually, make all player stats precise --- src/g_demo.c | 41 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/src/g_demo.c b/src/g_demo.c index 51001c6d0..3dbbe6c47 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -95,7 +95,7 @@ demoghost *ghosts = NULL; // DEMO RECORDING // -#define DEMOVERSION 0x000f +#define DEMOVERSION 0x0010 #define DEMOHEADER "\xF0" "SRB2Replay" "\x0F" #define DF_GHOST 0x01 // This demo contains ghost data too! @@ -1483,11 +1483,11 @@ void G_BeginRecording(void) // Stats WRITEUINT8(demo_p,player->charability); WRITEUINT8(demo_p,player->charability2); - WRITEUINT8(demo_p,player->actionspd>>FRACBITS); - WRITEUINT8(demo_p,player->mindash>>FRACBITS); - WRITEUINT8(demo_p,player->maxdash>>FRACBITS); - WRITEUINT8(demo_p,player->normalspeed>>FRACBITS); - WRITEUINT8(demo_p,player->runspeed>>FRACBITS); + WRITEFIXED(demo_p,player->actionspd); + WRITEFIXED(demo_p,player->mindash); + WRITEFIXED(demo_p,player->maxdash); + WRITEFIXED(demo_p,player->normalspeed); + WRITEFIXED(demo_p,player->runspeed); WRITEUINT8(demo_p,player->thrustfactor); WRITEUINT8(demo_p,player->accelstart); WRITEUINT8(demo_p,player->acceleration); @@ -1687,7 +1687,8 @@ UINT8 G_CmpDemoTime(char *oldname, char *newname) switch(oldversion) // demoversion { case DEMOVERSION: // latest always supported - case 0x000e: // The previous demoversions also supported + case 0x000f: // The previous demoversions also supported + case 0x000e: case 0x000d: // all that changed between then and now was longer color name case 0x000c: break; @@ -1831,6 +1832,7 @@ void G_DoPlayDemo(char *defdemoname) demoversion = READUINT16(demo_p); switch(demoversion) { + case 0x000f: case 0x000d: case 0x000e: case DEMOVERSION: // latest always supported @@ -1913,18 +1915,18 @@ void G_DoPlayDemo(char *defdemoname) charability = READUINT8(demo_p); charability2 = READUINT8(demo_p); - actionspd = (fixed_t)READUINT8(demo_p)< Date: Mon, 10 Jul 2023 15:40:20 -0700 Subject: [PATCH 244/586] Buffer ticcmds when receiving two on same tic --- src/d_clisrv.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index ca9f4a24e..7d62272ff 100755 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -4565,12 +4565,17 @@ static void HandlePacketFromPlayer(SINT8 node) /// \todo Use a separate cvar for that kind of timeout? freezetimeout[node] = I_GetTime() + connectiontimeout; + // If we've alredy received a ticcmd for this tic, just submit it for the next one. + tic_t faketic = maketic; + if (!!(netcmds[maketic % BACKUPTICS][netconsole].angleturn & TICCMD_RECEIVED)) + faketic++; + // Copy ticcmd - G_MoveTiccmd(&netcmds[maketic%BACKUPTICS][netconsole], &netbuffer->u.clientpak.cmd, 1); + G_MoveTiccmd(&netcmds[faketic%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) + if (netcmds[faketic%BACKUPTICS][netconsole].forwardmove > MAXPLMOVE || netcmds[faketic%BACKUPTICS][netconsole].forwardmove < -MAXPLMOVE + || netcmds[faketic%BACKUPTICS][netconsole].sidemove > MAXPLMOVE || netcmds[faketic%BACKUPTICS][netconsole].sidemove < -MAXPLMOVE) { CONS_Alert(CONS_WARNING, M_GetText("Illegal movement value received from node %d\n"), netconsole); //D_Clearticcmd(k); @@ -4582,9 +4587,10 @@ static void HandlePacketFromPlayer(SINT8 node) // Splitscreen cmd if ((netbuffer->packettype == PT_CLIENT2CMD || netbuffer->packettype == PT_CLIENT2MIS) && nodetoplayer2[node] >= 0) - G_MoveTiccmd(&netcmds[maketic%BACKUPTICS][(UINT8)nodetoplayer2[node]], + G_MoveTiccmd(&netcmds[faketic%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) From 576262f6c59d000efc7c9f48e860d3b74a2b1da9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Tue, 11 Jul 2023 16:37:45 +0200 Subject: [PATCH 245/586] Fix inaccuracies in FPS counter --- src/screen.c | 40 +++++++++------------------------------- 1 file changed, 9 insertions(+), 31 deletions(-) diff --git a/src/screen.c b/src/screen.c index f8af4c504..f4982111d 100644 --- a/src/screen.c +++ b/src/screen.c @@ -462,11 +462,10 @@ double averageFPS = 0.0f; #define USE_FPS_SAMPLES #ifdef USE_FPS_SAMPLES -#define FPS_SAMPLE_RATE (0.05) // How often to update FPS samples, in seconds -#define NUM_FPS_SAMPLES (16) // Number of samples to store +#define NUM_FPS_SAMPLES (32) // Number of samples to store static double fps_samples[NUM_FPS_SAMPLES]; -static double updateElapsed = 0.0; +static int fps_index; #endif static boolean fps_init = false; @@ -475,6 +474,7 @@ static precise_t fps_enter = 0; void SCR_CalculateFPS(void) { precise_t fps_finish = 0; + int i; double frameElapsed = 0.0; @@ -489,35 +489,13 @@ void SCR_CalculateFPS(void) fps_enter = fps_finish; #ifdef USE_FPS_SAMPLES - updateElapsed += frameElapsed; + fps_samples[fps_index] = frameElapsed / NUM_FPS_SAMPLES; + fps_index = (fps_index + 1) % NUM_FPS_SAMPLES; - if (updateElapsed >= FPS_SAMPLE_RATE) - { - static int sampleIndex = 0; - int i; - - fps_samples[sampleIndex] = frameElapsed; - - sampleIndex++; - if (sampleIndex >= NUM_FPS_SAMPLES) - sampleIndex = 0; - - averageFPS = 0.0; - for (i = 0; i < NUM_FPS_SAMPLES; i++) - { - averageFPS += fps_samples[i]; - } - - if (averageFPS > 0.0) - { - averageFPS = 1.0 / (averageFPS / NUM_FPS_SAMPLES); - } - } - - while (updateElapsed >= FPS_SAMPLE_RATE) - { - updateElapsed -= FPS_SAMPLE_RATE; - } + averageFPS = 0.0; + for (i = 0; i < NUM_FPS_SAMPLES; i++) + averageFPS += fps_samples[i]; + averageFPS = 1.0 / averageFPS; #else // Direct, unsampled counter. averageFPS = 1.0 / frameElapsed; From 73ded4787c9c2c5d529917ab456510e9f32fa6a6 Mon Sep 17 00:00:00 2001 From: spherallic Date: Tue, 11 Jul 2023 19:00:47 +0200 Subject: [PATCH 246/586] Fix ammo/panel/emerald hitboxes, add shadows to thrown rings --- src/info.c | 38 +++++++++++++++++++------------------- src/p_mobj.c | 25 +++++++++++++++++++++++-- 2 files changed, 42 insertions(+), 21 deletions(-) diff --git a/src/info.c b/src/info.c index abcf4b499..eab6ac82a 100644 --- a/src/info.c +++ b/src/info.c @@ -7194,7 +7194,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_cgot, // deathsound EMERALD1, // speed 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 24*FRACUNIT, // height 0, // display offset 16, // mass 0, // damage @@ -7220,7 +7220,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_cgot, // deathsound EMERALD2, // speed 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 24*FRACUNIT, // height 0, // display offset 16, // mass 0, // damage @@ -7246,7 +7246,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_cgot, // deathsound EMERALD3, // speed 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 24*FRACUNIT, // height 0, // display offset 16, // mass 0, // damage @@ -7272,7 +7272,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_cgot, // deathsound EMERALD4, // speed 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 24*FRACUNIT, // height 0, // display offset 16, // mass 0, // damage @@ -7298,7 +7298,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_cgot, // deathsound EMERALD5, // speed 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 24*FRACUNIT, // height 0, // display offset 16, // mass 0, // damage @@ -7324,7 +7324,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_cgot, // deathsound EMERALD6, // speed 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 24*FRACUNIT, // height 0, // display offset 16, // mass 0, // damage @@ -7350,7 +7350,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_cgot, // deathsound EMERALD7, // speed 16*FRACUNIT, // radius - 32*FRACUNIT, // height + 24*FRACUNIT, // height 0, // display offset 16, // mass 0, // damage @@ -18344,7 +18344,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_itemup, // deathsound 60*FRACUNIT, // speed - 24*FRACUNIT, // radius + 16*FRACUNIT, // radius 24*FRACUNIT, // height 0, // display offset pw_bouncering, // mass @@ -18371,7 +18371,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_itemup, // deathsound 60*FRACUNIT, // speed - 24*FRACUNIT, // radius + 16*FRACUNIT, // radius 24*FRACUNIT, // height 0, // display offset pw_railring, // mass @@ -18425,7 +18425,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_itemup, // deathsound 60*FRACUNIT, // speed - 24*FRACUNIT, // radius + 16*FRACUNIT, // radius 24*FRACUNIT, // height 0, // display offset pw_automaticring, // mass @@ -18452,7 +18452,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_itemup, // deathsound 60*FRACUNIT, // speed - 24*FRACUNIT, // radius + 16*FRACUNIT, // radius 24*FRACUNIT, // height 0, // display offset pw_explosionring, // mass @@ -18479,7 +18479,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_itemup, // deathsound 60*FRACUNIT, // speed - 24*FRACUNIT, // radius + 16*FRACUNIT, // radius 24*FRACUNIT, // height 0, // display offset pw_scatterring, // mass @@ -18506,7 +18506,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_itemup, // deathsound 60*FRACUNIT, // speed - 24*FRACUNIT, // radius + 16*FRACUNIT, // radius 24*FRACUNIT, // height 0, // display offset pw_grenadering, // mass @@ -18535,7 +18535,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_ncitem, // deathsound 60*FRACUNIT, // speed 24*FRACUNIT, // radius - 24*FRACUNIT, // height + 40*FRACUNIT, // height 0, // display offset pw_bouncering, // mass 2*TICRATE, // damage @@ -18562,7 +18562,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_ncitem, // deathsound 60*FRACUNIT, // speed 24*FRACUNIT, // radius - 24*FRACUNIT, // height + 40*FRACUNIT, // height 0, // display offset pw_railring, // mass 2*TICRATE, // damage @@ -18589,7 +18589,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_ncitem, // deathsound 60*FRACUNIT, // speed 24*FRACUNIT, // radius - 24*FRACUNIT, // height + 40*FRACUNIT, // height 0, // display offset pw_automaticring, // mass 2*TICRATE, // damage @@ -18616,7 +18616,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_ncitem, // deathsound 60*FRACUNIT, // speed 24*FRACUNIT, // radius - 24*FRACUNIT, // height + 40*FRACUNIT, // height 0, // display offset pw_explosionring, // mass 2*TICRATE, // damage @@ -18643,7 +18643,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_ncitem, // deathsound 60*FRACUNIT, // speed 24*FRACUNIT, // radius - 24*FRACUNIT, // height + 40*FRACUNIT, // height 0, // display offset pw_scatterring, // mass 2*TICRATE, // damage @@ -18670,7 +18670,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_ncitem, // deathsound 60*FRACUNIT, // speed 24*FRACUNIT, // radius - 24*FRACUNIT, // height + 40*FRACUNIT, // height 0, // display offset pw_grenadering, // mass 2*TICRATE, // damage diff --git a/src/p_mobj.c b/src/p_mobj.c index 44140042e..152513d1b 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10541,6 +10541,29 @@ static fixed_t P_DefaultMobjShadowScale (mobj_t *thing) case MT_REDFLAG: case MT_BLUEFLAG: + case MT_BOUNCERING: + case MT_AUTOMATICRING: + case MT_INFINITYRING: + case MT_RAILRING: + case MT_EXPLOSIONRING: + case MT_SCATTERRING: + case MT_GRENADERING: + + case MT_BOUNCEPICKUP: + case MT_RAILPICKUP: + case MT_AUTOPICKUP: + case MT_EXPLODEPICKUP: + case MT_SCATTERPICKUP: + case MT_GRENADEPICKUP: + + case MT_REDRING: + case MT_THROWNBOUNCE: + case MT_THROWNINFINITY: + case MT_THROWNAUTOMATIC: + case MT_THROWNSCATTER: + case MT_THROWNEXPLOSION: + case MT_THROWNGRENADE: + case MT_EMBLEM: case MT_TOKEN: @@ -10581,8 +10604,6 @@ static fixed_t P_DefaultMobjShadowScale (mobj_t *thing) if (thing->flags & (MF_ENEMY|MF_BOSS)) return FRACUNIT; - else if (P_WeaponOrPanel(thing->type)) - return 2*FRACUNIT/3; else return 0; } From 464110ed814a4ed1f8a7b1d4ac7c3c4815728fe7 Mon Sep 17 00:00:00 2001 From: SteelT Date: Thu, 13 Jul 2023 01:02:15 -0400 Subject: [PATCH 247/586] Add CV_TrueFalse as possible value types for console variables This also adds support for using true/false as value aliases for On/Off, Yes/No or 1/0 --- src/command.c | 15 +++++++++------ src/command.h | 1 + src/lua_consolelib.c | 4 +++- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/command.c b/src/command.c index a34d9694a..b03d2d8c1 100644 --- a/src/command.c +++ b/src/command.c @@ -76,6 +76,7 @@ CV_PossibleValue_t CV_OnOff[] = {{0, "Off"}, {1, "On"}, {0, NULL}}; CV_PossibleValue_t CV_YesNo[] = {{0, "No"}, {1, "Yes"}, {0, NULL}}; CV_PossibleValue_t CV_Unsigned[] = {{0, "MIN"}, {999999999, "MAX"}, {0, NULL}}; CV_PossibleValue_t CV_Natural[] = {{1, "MIN"}, {999999999, "MAX"}, {0, NULL}}; +CV_PossibleValue_t CV_TrueFalse[] = {{0, "False"}, {1, "True"}, {0, NULL}}; // Filter consvars by EXECVERSION // First implementation is 26 (2.1.21), so earlier configs default at 25 (2.1.20) @@ -863,9 +864,11 @@ static void COM_Help_f(void) { CONS_Printf(" Possible values:\n"); if (cvar->PossibleValue == CV_YesNo) - CONS_Printf(" Yes or No (On or Off, 1 or 0)\n"); + CONS_Printf(" Yes or No (On or Off, True or False, 1 or 0)\n"); else if (cvar->PossibleValue == CV_OnOff) - CONS_Printf(" On or Off (Yes or No, 1 or 0)\n"); + CONS_Printf(" On or Off (Yes or No, True or False, 1 or 0)\n"); + else if (cvar->PossibleValue == CV_TrueFalse) + CONS_Printf(" True or False (On or Off, Yes or No, 1 or 0)\n"); else if (cvar->PossibleValue == Color_cons_t) { for (i = 1; i < numskincolors; ++i) @@ -1016,7 +1019,7 @@ static void COM_Toggle_f(void) if (CV_Immutable(cvar)) return; - if (!(cvar->PossibleValue == CV_YesNo || cvar->PossibleValue == CV_OnOff)) + if (!(cvar->PossibleValue == CV_YesNo || cvar->PossibleValue == CV_OnOff || cvar->PossibleValue == CV_TrueFalse)) { CONS_Alert(CONS_NOTICE, M_GetText("%s is not a boolean value\n"), COM_Argv(1)); return; @@ -1507,12 +1510,12 @@ static void Setvalue(consvar_t *var, const char *valstr, boolean stealth) goto found; } // Not found ... but wait, there's hope! - if (var->PossibleValue == CV_OnOff || var->PossibleValue == CV_YesNo) + if (var->PossibleValue == CV_OnOff || var->PossibleValue == CV_YesNo || var->PossibleValue == CV_TrueFalse) { overrideval = -1; - if (!stricmp(valstr, "on") || !stricmp(valstr, "yes")) + if (!stricmp(valstr, "on") || !stricmp(valstr, "yes") || !stricmp(valstr, "true")) overrideval = 1; - else if (!stricmp(valstr, "off") || !stricmp(valstr, "no")) + else if (!stricmp(valstr, "off") || !stricmp(valstr, "no") || !stricmp(valstr, "false")) overrideval = 0; if (overrideval != -1) diff --git a/src/command.h b/src/command.h index 69d1890d3..619d8c1dc 100644 --- a/src/command.h +++ b/src/command.h @@ -177,6 +177,7 @@ extern CV_PossibleValue_t CV_OnOff[]; extern CV_PossibleValue_t CV_YesNo[]; extern CV_PossibleValue_t CV_Unsigned[]; extern CV_PossibleValue_t CV_Natural[]; +extern CV_PossibleValue_t CV_TrueFalse[]; // Filter consvars by version extern consvar_t cv_execversion; diff --git a/src/lua_consolelib.c b/src/lua_consolelib.c index 1d15b3b14..9e5d1e2ee 100644 --- a/src/lua_consolelib.c +++ b/src/lua_consolelib.c @@ -357,7 +357,7 @@ static int lib_cvRegisterVar(lua_State *L) if (lua_islightuserdata(L, 4)) { CV_PossibleValue_t *pv = lua_touserdata(L, 4); - if (pv == CV_OnOff || pv == CV_YesNo || pv == CV_Unsigned || pv == CV_Natural) + if (pv == CV_OnOff || pv == CV_YesNo || pv == CV_Unsigned || pv == CV_Natural || pv == CV_TrueFalse) cvar->PossibleValue = pv; else FIELDERROR("PossibleValue", "CV_PossibleValue_t expected, got unrecognised pointer") @@ -652,6 +652,8 @@ int LUA_ConsoleLib(lua_State *L) lua_setglobal(L, "CV_Unsigned"); lua_pushlightuserdata(L, CV_Natural); lua_setglobal(L, "CV_Natural"); + lua_pushlightuserdata(L, CV_TrueFalse); + lua_setglobal(L, "CV_TrueFalse"); // Set global functions lua_pushvalue(L, LUA_GLOBALSINDEX); From 8755582901c70a8eff73084690d50da29d9c93cd Mon Sep 17 00:00:00 2001 From: AJ Martinez Date: Fri, 14 Jul 2023 02:33:33 -0700 Subject: [PATCH 248/586] Don't submit future ticcmds if they could overwrite a needed ticcmd --- src/d_clisrv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 7d62272ff..210619164 100755 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -4567,7 +4567,8 @@ static void HandlePacketFromPlayer(SINT8 node) // If we've alredy received a ticcmd for this tic, just submit it for the next one. tic_t faketic = maketic; - if (!!(netcmds[maketic % BACKUPTICS][netconsole].angleturn & TICCMD_RECEIVED)) + if ((!!(netcmds[maketic % BACKUPTICS][netconsole].angleturn & TICCMD_RECEIVED)) + && (maketic - firstticstosend < BACKUPTICS)) faketic++; // Copy ticcmd From bfbbaf9f56a3622d9748251f09e8cd8d56ab3966 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Fri, 14 Jul 2023 13:25:09 +0200 Subject: [PATCH 249/586] Make sure all allocations are properly aligned --- src/d_netfil.c | 2 +- src/lua_hudlib_drawlist.c | 6 +++--- src/r_fps.c | 17 ++++++----------- src/w_wad.c | 2 +- src/z_zone.c | 3 ++- src/z_zone.h | 8 ++++---- 6 files changed, 17 insertions(+), 21 deletions(-) diff --git a/src/d_netfil.c b/src/d_netfil.c index e60af2c2c..3fef75681 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -498,7 +498,7 @@ INT32 CL_CheckFiles(void) CONS_Debug(DBG_NETPLAY, "searching for '%s' ", fileneeded[i].filename); // Check in already loaded files - for (j = mainwads; wadfiles[j]; j++) + for (j = mainwads; j < numwadfiles; j++) { nameonly(strcpy(wadfilename, wadfiles[j]->filename)); if (!stricmp(wadfilename, fileneeded[i].filename) && diff --git a/src/lua_hudlib_drawlist.c b/src/lua_hudlib_drawlist.c index f46f207c1..6f83094ac 100644 --- a/src/lua_hudlib_drawlist.c +++ b/src/lua_hudlib_drawlist.c @@ -103,7 +103,7 @@ huddrawlist_h LUA_HUD_CreateDrawList(void) { huddrawlist_h drawlist; - drawlist = (huddrawlist_h) Z_CallocAlign(sizeof(struct huddrawlist_s), PU_STATIC, NULL, 64); + drawlist = (huddrawlist_h) Z_Calloc(sizeof(struct huddrawlist_s), PU_STATIC, NULL); drawlist->items = NULL; drawlist->items_capacity = 0; drawlist->items_len = 0; @@ -160,7 +160,7 @@ static size_t AllocateDrawItem(huddrawlist_h list) { if (list->items_capacity == 0) list->items_capacity = 128; else list->items_capacity *= 2; - list->items = (drawitem_t *) Z_ReallocAlign(list->items, sizeof(struct drawitem_s) * list->items_capacity, PU_STATIC, NULL, 64); + list->items = (drawitem_t *) Z_Realloc(list->items, sizeof(struct drawitem_s) * list->items_capacity, PU_STATIC, NULL); } return list->items_len++; @@ -179,7 +179,7 @@ static const char *CopyString(huddrawlist_h list, const char* str) { if (list->strbuf_capacity == 0) list->strbuf_capacity = 256; else list->strbuf_capacity *= 2; - list->strbuf = (char*) Z_ReallocAlign(list->strbuf, sizeof(char) * list->strbuf_capacity, PU_STATIC, NULL, 8); + list->strbuf = (char*) Z_Realloc(list->strbuf, sizeof(char) * list->strbuf_capacity, PU_STATIC, NULL); } const char *result = (const char *) &list->strbuf[list->strbuf_len]; strncpy(&list->strbuf[list->strbuf_len], str, lenstr + 1); diff --git a/src/r_fps.c b/src/r_fps.c index 2d30c9f01..6166f0408 100644 --- a/src/r_fps.c +++ b/src/r_fps.c @@ -369,12 +369,11 @@ static void AddInterpolator(levelinterpolator_t* interpolator) levelinterpolators_size *= 2; } - levelinterpolators = Z_ReallocAlign( + levelinterpolators = Z_Realloc( (void*) levelinterpolators, sizeof(levelinterpolator_t*) * levelinterpolators_size, PU_LEVEL, - NULL, - sizeof(levelinterpolator_t*) * 8 + NULL ); } @@ -384,11 +383,8 @@ static void AddInterpolator(levelinterpolator_t* interpolator) static levelinterpolator_t *CreateInterpolator(levelinterpolator_type_e type, thinker_t *thinker) { - levelinterpolator_t *ret = (levelinterpolator_t*) Z_CallocAlign( - sizeof(levelinterpolator_t), - PU_LEVEL, - NULL, - sizeof(levelinterpolator_t) * 8 + levelinterpolator_t *ret = (levelinterpolator_t*) Z_Calloc( + sizeof(levelinterpolator_t), PU_LEVEL, NULL ); ret->type = type; @@ -703,12 +699,11 @@ void R_AddMobjInterpolator(mobj_t *mobj) interpolated_mobjs_capacity *= 2; } - interpolated_mobjs = Z_ReallocAlign( + interpolated_mobjs = Z_Realloc( interpolated_mobjs, sizeof(mobj_t *) * interpolated_mobjs_capacity, PU_LEVEL, - NULL, - 64 + NULL ); } diff --git a/src/w_wad.c b/src/w_wad.c index 456afef7b..b13dc8cc1 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -972,7 +972,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 = 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 diff --git a/src/z_zone.c b/src/z_zone.c index 11c4bcb2c..d23c43b7b 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -287,7 +287,8 @@ void *Z_Malloc2(size_t size, INT32 tag, void *user, INT32 alignbits, void *Z_MallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits) #endif { - size_t extrabytes = (1<= 0 && alignbits < (INT32)(sizeof(size_t) * 8)); + size_t extrabytes = ((size_t)1< Date: Fri, 14 Jul 2023 12:51:16 +0000 Subject: [PATCH 250/586] Draw hitboxes last in OpenGL --- src/hardware/hw_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index e7550fd6e..bb05f2a6d 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -4532,9 +4532,9 @@ static int CompareVisSprites(const void *p1, const void *p2) int linkdraw1; int linkdraw2; - // bbox doesn't need to be sorted + // draw bbox after everything else if (spr1->bbox || spr2->bbox) - return 0; + return (spr1->bbox - spr2->bbox); // check for precip first, because then sprX->mobj is actually a precipmobj_t and does not have flags2 or tracer linkdraw1 = !spr1->precip && (spr1->mobj->flags2 & MF2_LINKDRAW) && spr1->mobj->tracer; From 34ce172a907778bc4c220dba02cd5ab3761ae761 Mon Sep 17 00:00:00 2001 From: spherallic Date: Fri, 14 Jul 2023 15:03:43 +0200 Subject: [PATCH 251/586] Allow toggling PF_NoDepthTest for OpenGL hitboxes --- src/d_netcmd.c | 1 + src/hardware/hw_main.c | 4 ++-- src/r_bbox.c | 3 ++- src/screen.h | 3 ++- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 0f859a569..c3cd7daa8 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -874,6 +874,7 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_fullscreen); CV_RegisterVar(&cv_renderview); CV_RegisterVar(&cv_renderhitboxinterpolation); + CV_RegisterVar(&cv_renderhitboxgldepth); CV_RegisterVar(&cv_renderhitbox); CV_RegisterVar(&cv_renderer); CV_RegisterVar(&cv_scr_depth); diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index bb05f2a6d..194d68c54 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -4081,8 +4081,8 @@ static void HWR_DrawBoundingBox(gl_vissprite_t *vis) v[017].y = v[020].y = v[021].y = v[025].y = v[026].y = v[027].y = vis->gzt; // top Surf.PolyColor = V_GetColor(R_GetBoundingBoxColor(vis->mobj)); - - HWR_ProcessPolygon(&Surf, v, 24, PF_Modulated|PF_NoTexture|PF_WireFrame, SHADER_NONE, false); + + HWR_ProcessPolygon(&Surf, v, 24, (cv_renderhitboxgldepth.value ? 0 : PF_NoDepthTest)|PF_Modulated|PF_NoTexture|PF_WireFrame, SHADER_NONE, false); } // -----------------+ diff --git a/src/r_bbox.c b/src/r_bbox.c index 7ed693fd0..59d0893c4 100644 --- a/src/r_bbox.c +++ b/src/r_bbox.c @@ -34,8 +34,9 @@ static CV_PossibleValue_t renderhitbox_cons_t[] = { {RENDERHITBOX_RINGS, "Rings"}, {0}}; -consvar_t cv_renderhitbox = CVAR_INIT ("renderhitbox", "Off", 0, renderhitbox_cons_t, NULL); +consvar_t cv_renderhitbox = CVAR_INIT ("renderhitbox", "Off", CV_CHEAT, renderhitbox_cons_t, NULL); consvar_t cv_renderhitboxinterpolation = CVAR_INIT ("renderhitbox_interpolation", "On", CV_SAVE, CV_OnOff, NULL); +consvar_t cv_renderhitboxgldepth = CVAR_INIT ("renderhitbox_gldepth", "Off", CV_SAVE, CV_OnOff, NULL); struct bbox_col { INT32 x; diff --git a/src/screen.h b/src/screen.h index b021a419d..9222805fb 100644 --- a/src/screen.h +++ b/src/screen.h @@ -199,7 +199,8 @@ extern CV_PossibleValue_t cv_renderer_t[]; extern INT32 scr_bpp; extern UINT8 *scr_borderpatch; // patch used to fill the view borders -extern consvar_t cv_scr_width, cv_scr_height, cv_scr_depth, cv_renderview, cv_renderer, cv_renderhitbox, cv_renderhitboxinterpolation, cv_fullscreen; +extern consvar_t cv_scr_width, cv_scr_height, cv_scr_depth, cv_renderview, cv_renderer, cv_fullscreen; +extern consvar_t cv_renderhitbox, cv_renderhitboxinterpolation, cv_renderhitboxgldepth; // wait for page flipping to end or not extern consvar_t cv_vidwait; extern consvar_t cv_timescale; From 28849c31a8bed7854f1f28cdd37cb3fad0623287 Mon Sep 17 00:00:00 2001 From: spherallic Date: Sat, 15 Jul 2023 11:26:13 +0200 Subject: [PATCH 252/586] Update (U)ZB config with hitbox tweaks --- extras/conf/SRB2-22.cfg | 15 ++++++++++----- extras/conf/udb/Includes/SRB222_things.cfg | 21 ++++++++++++++++----- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg index dd5cdb46b..bcb6e6241 100644 --- a/extras/conf/SRB2-22.cfg +++ b/extras/conf/SRB2-22.cfg @@ -4367,7 +4367,6 @@ thingtypes { color = 14; // Yellow title = "Rings and Weapon Panels"; - width = 24; height = 24; flags8height = 24; flags8text = "[8] Float"; @@ -4377,7 +4376,6 @@ thingtypes { title = "Ring"; sprite = "RINGA0"; - width = 16; } 301 { @@ -4393,6 +4391,7 @@ thingtypes { title = "Infinity Ring"; sprite = "RNGIA0"; + width = 24; } 304 { @@ -4418,43 +4417,48 @@ thingtypes { title = "CTF Team Ring (Red)"; sprite = "internal:TRNGA0R"; - width = 16; } 309 { title = "CTF Team Ring (Blue)"; sprite = "internal:TRNGA0B"; - width = 16; } 330 { title = "Bounce Ring Panel"; sprite = "PIKBA0"; + width = 24; + height = 40; } 331 { title = "Rail Ring Panel"; sprite = "PIKRA0"; + width = 24; } 332 { title = "Automatic Ring Panel"; sprite = "PIKAA0"; + width = 24; } 333 { title = "Explosion Ring Panel"; sprite = "PIKEA0"; + width = 24; } 334 { title = "Scatter Ring Panel"; sprite = "PIKSA0"; + width = 24; } 335 { title = "Grenade Ring Panel"; sprite = "PIKGA0"; + width = 24; } } @@ -4463,7 +4467,7 @@ thingtypes color = 10; // Light Green title = "Other Collectibles"; width = 16; - height = 32; + height = 24; sort = 1; sprite = "CEMGA0"; @@ -4529,6 +4533,7 @@ thingtypes { title = "Emerald Hunt Location"; sprite = "SHRDA0"; + height = 32; flags8height = 24; flags8text = "[8] Float"; } diff --git a/extras/conf/udb/Includes/SRB222_things.cfg b/extras/conf/udb/Includes/SRB222_things.cfg index df08e3ac5..9eb227974 100644 --- a/extras/conf/udb/Includes/SRB222_things.cfg +++ b/extras/conf/udb/Includes/SRB222_things.cfg @@ -1185,7 +1185,7 @@ udmf { color = 14; // Yellow title = "Rings and Weapon Panels"; - width = 24; + width = 16; height = 24; sprite = "RINGA0"; @@ -1193,7 +1193,6 @@ udmf { title = "Ring"; sprite = "RINGA0"; - width = 16; arg0 { title = "Float?"; @@ -1227,6 +1226,7 @@ udmf { title = "Infinity Ring"; sprite = "RNGIA0"; + width = 24; arg0 { title = "Float?"; @@ -1282,7 +1282,6 @@ udmf { title = "CTF Team Ring (Red)"; sprite = "internal:TRNGA0R"; - width = 16; arg0 { title = "Float?"; @@ -1294,7 +1293,6 @@ udmf { title = "CTF Team Ring (Blue)"; sprite = "internal:TRNGA0B"; - width = 16; arg0 { title = "Float?"; @@ -1306,6 +1304,8 @@ udmf { title = "Bounce Ring Panel"; sprite = "PIKBA0"; + width = 24; + height = 40; arg0 { title = "Float?"; @@ -1317,6 +1317,8 @@ udmf { title = "Rail Ring Panel"; sprite = "PIKRA0"; + width = 24; + height = 40; arg0 { title = "Float?"; @@ -1328,6 +1330,8 @@ udmf { title = "Automatic Ring Panel"; sprite = "PIKAA0"; + width = 24; + height = 40; arg0 { title = "Float?"; @@ -1339,6 +1343,8 @@ udmf { title = "Explosion Ring Panel"; sprite = "PIKEA0"; + width = 24; + height = 40; arg0 { title = "Float?"; @@ -1350,6 +1356,8 @@ udmf { title = "Scatter Ring Panel"; sprite = "PIKSA0"; + width = 24; + height = 40; arg0 { title = "Float?"; @@ -1361,6 +1369,8 @@ udmf { title = "Grenade Ring Panel"; sprite = "PIKGA0"; + width = 24; + height = 40; arg0 { title = "Float?"; @@ -1375,7 +1385,7 @@ udmf color = 10; // Light_Green title = "Other Collectibles"; width = 16; - height = 32; + height = 24; sort = 1; sprite = "CEMGA0"; @@ -1445,6 +1455,7 @@ udmf { title = "Emerald Hunt Location"; sprite = "SHRDA0"; + height = 32; arg0 { title = "Float?"; From e3824b9f1b759c319df85d7c710bf76a70573c38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Sat, 15 Jul 2023 12:51:07 +0200 Subject: [PATCH 253/586] fixup! Fix inaccuracies in FPS counter --- src/screen.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/screen.c b/src/screen.c index f4982111d..b09ee81d2 100644 --- a/src/screen.c +++ b/src/screen.c @@ -462,10 +462,11 @@ double averageFPS = 0.0f; #define USE_FPS_SAMPLES #ifdef USE_FPS_SAMPLES -#define NUM_FPS_SAMPLES (32) // Number of samples to store +#define MAX_FRAME_TIME 0.05 +#define NUM_FPS_SAMPLES (16) // Number of samples to store -static double fps_samples[NUM_FPS_SAMPLES]; -static int fps_index; +static double total_frame_time = 0.0; +static int frame_index; #endif static boolean fps_init = false; @@ -474,7 +475,6 @@ static precise_t fps_enter = 0; void SCR_CalculateFPS(void) { precise_t fps_finish = 0; - int i; double frameElapsed = 0.0; @@ -489,13 +489,13 @@ void SCR_CalculateFPS(void) fps_enter = fps_finish; #ifdef USE_FPS_SAMPLES - fps_samples[fps_index] = frameElapsed / NUM_FPS_SAMPLES; - fps_index = (fps_index + 1) % NUM_FPS_SAMPLES; - - averageFPS = 0.0; - for (i = 0; i < NUM_FPS_SAMPLES; i++) - averageFPS += fps_samples[i]; - averageFPS = 1.0 / averageFPS; + total_frame_time += frameElapsed; + if (frame_index++ >= NUM_FPS_SAMPLES || total_frame_time >= MAX_FRAME_TIME) + { + averageFPS = 1.0 / (total_frame_time / frame_index); + total_frame_time = 0.0; + frame_index = 0; + } #else // Direct, unsampled counter. averageFPS = 1.0 / frameElapsed; From c64b242f012adbaa6d3e77070baebbf190313247 Mon Sep 17 00:00:00 2001 From: spherallic Date: Sat, 15 Jul 2023 13:07:55 +0200 Subject: [PATCH 254/586] Note to self: don't do busywork right after waking up from a short night of sleep --- extras/conf/SRB2-22.cfg | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg index bcb6e6241..41ad99889 100644 --- a/extras/conf/SRB2-22.cfg +++ b/extras/conf/SRB2-22.cfg @@ -4435,30 +4435,35 @@ thingtypes title = "Rail Ring Panel"; sprite = "PIKRA0"; width = 24; + height = 40; } 332 { title = "Automatic Ring Panel"; sprite = "PIKAA0"; width = 24; + height = 40; } 333 { title = "Explosion Ring Panel"; sprite = "PIKEA0"; width = 24; + height = 40; } 334 { title = "Scatter Ring Panel"; sprite = "PIKSA0"; width = 24; + height = 40; } 335 { title = "Grenade Ring Panel"; sprite = "PIKGA0"; width = 24; + height = 40; } } From 9a386111e285af2e9eea0293ff484f0375fd61a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Sun, 16 Jul 2023 14:19:19 +0200 Subject: [PATCH 255/586] Fix crash when P_ZMovement calls from Lua removes the object --- src/lua_baselib.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 25fa38769..0b0c93be4 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -1078,7 +1078,8 @@ static int lib_pZMovement(lua_State *L) if (!actor) return LUA_ErrInvalid(L, "mobj_t"); lua_pushboolean(L, P_ZMovement(actor)); - P_CheckPosition(actor, actor->x, actor->y); + if (!P_MobjWasRemoved(actor)) + P_CheckPosition(actor, actor->x, actor->y); P_SetTarget(&tmthing, ptmthing); return 1; } @@ -1106,7 +1107,8 @@ static int lib_pSceneryZMovement(lua_State *L) if (!actor) return LUA_ErrInvalid(L, "mobj_t"); lua_pushboolean(L, P_SceneryZMovement(actor)); - P_CheckPosition(actor, actor->x, actor->y); + if (!P_MobjWasRemoved(actor)) + P_CheckPosition(actor, actor->x, actor->y); P_SetTarget(&tmthing, ptmthing); return 1; } From c55b2f29434ab6959873f5e455040d17d65838ba Mon Sep 17 00:00:00 2001 From: SteelT Date: Sun, 16 Jul 2023 13:56:42 -0400 Subject: [PATCH 256/586] Print list of existing alias commands --- src/command.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/command.c b/src/command.c index b03d2d8c1..2cb3d821c 100644 --- a/src/command.c +++ b/src/command.c @@ -681,6 +681,17 @@ static void COM_ExecuteString(char *ptext) // SCRIPT COMMANDS // ========================================================================= +static void print_alias(void) +{ + cmdalias_t *a; + + CONS_Printf("\x82""Current alias commands:\n"); + for (a = com_alias; a; a = a->next) + { + CONS_Printf("%s : %s", a->name, a->value); + } +} + /** Creates a command name that replaces another command. */ static void COM_Alias_f(void) @@ -692,6 +703,7 @@ static void COM_Alias_f(void) if (COM_Argc() < 3) { CONS_Printf(M_GetText("alias : create a shortcut command that executes other command(s)\n")); + print_alias(); return; } From a90151570f3db849d93a41dd6812f2f42e9d1a67 Mon Sep 17 00:00:00 2001 From: SteelT Date: Sun, 16 Jul 2023 15:44:48 -0400 Subject: [PATCH 257/586] Replace the alias if an alias already exists Reduces wasting memory by having multiple aliases with the same name --- src/command.c | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/src/command.c b/src/command.c index 2cb3d821c..e1a43522d 100644 --- a/src/command.c +++ b/src/command.c @@ -692,11 +692,36 @@ static void print_alias(void) } } +static void add_alias(char *newname, char *newcmd) +{ + cmdalias_t *a; + + // Check for existing aliases first + for (a = com_alias; a; a = a->next) + { + if (!stricmp(newname, a->name)) + { + Z_Free(a->value); // Free old cmd + a->value = newcmd; + return; + } + } + + // No alias found, add it instead + a = ZZ_Alloc(sizeof *a); + a->next = com_alias; + com_alias = a; + + a->name = newname; + a->value = newcmd; +} + /** Creates a command name that replaces another command. */ static void COM_Alias_f(void) { - cmdalias_t *a; + char *name; + char *zcmd; char cmd[1024]; size_t i, c; @@ -707,11 +732,7 @@ static void COM_Alias_f(void) return; } - a = ZZ_Alloc(sizeof *a); - a->next = com_alias; - com_alias = a; - - a->name = Z_StrDup(COM_Argv(1)); + name = Z_StrDup(COM_Argv(1)); // copy the rest of the command line cmd[0] = 0; // start out with a null string @@ -723,8 +744,8 @@ static void COM_Alias_f(void) strcat(cmd, " "); } strcat(cmd, "\n"); - - a->value = Z_StrDup(cmd); + zcmd = Z_StrDup(cmd); + add_alias(name, zcmd); } /** Prints a line of text to the console. From 1ced8acc6a3c301f638753cf404a29cdfecb4d54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Sun, 16 Jul 2023 23:25:22 +0200 Subject: [PATCH 258/586] Fix softlocking as Sonic & Tails when Player 2 has no name --- src/d_clisrv.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 210619164..05af083bd 100755 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1293,6 +1293,7 @@ static boolean CL_AskFileList(INT32 firstfile) static boolean CL_SendJoin(void) { UINT8 localplayers = 1; + char const *player2name; if (netgame) CONS_Printf(M_GetText("Sending join request...\n")); netbuffer->packettype = PT_CLIENTJOIN; @@ -1309,9 +1310,11 @@ static boolean CL_SendJoin(void) CleanupPlayerName(consoleplayer, cv_playername.zstring); if (splitscreen) CleanupPlayerName(1, cv_playername2.zstring);/* 1 is a HACK? oh no */ + // Avoid empty string on bots to avoid softlocking in singleplayer + player2name = botingame ? "a" : cv_playername2.zstring; strncpy(netbuffer->u.clientcfg.names[0], cv_playername.zstring, MAXPLAYERNAME); - strncpy(netbuffer->u.clientcfg.names[1], cv_playername2.zstring, MAXPLAYERNAME); + strncpy(netbuffer->u.clientcfg.names[1], player2name, MAXPLAYERNAME); return HSendPacket(servernode, true, 0, sizeof (clientconfig_pak)); } From 80bf4d6c2d1cc413c41b0df69e2cf9334675377b Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 12 Jun 2023 22:34:42 -0400 Subject: [PATCH 259/586] Port SRB2Kart join on intermission fix All gamestates besides GS_LEVEL are unsupported by the save game functions. This commit forces players joining during these gamestates into GS_WAITINGPLAYERS, which is a basic gamestate that just maintains the connection until we can enter the start of a new one. Also provides an extremely simple drawer for GS_WAITINGPLAYERS so the joining player knows what's going on. --- src/console.c | 2 +- src/d_clisrv.c | 2 ++ src/d_main.c | 7 +++++++ src/d_netcmd.c | 2 +- src/f_finale.c | 33 +++++++++++++++++++++++++++++++++ src/f_finale.h | 4 ++++ src/g_game.c | 9 ++++++--- src/p_saveg.c | 6 +++++- 8 files changed, 59 insertions(+), 6 deletions(-) diff --git a/src/console.c b/src/console.c index 6d273f620..119079464 100644 --- a/src/console.c +++ b/src/console.c @@ -1889,7 +1889,7 @@ void CON_Drawer(void) CON_DrawConsole(); else if (gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_ENDING || gamestate == GS_CUTSCENE - || gamestate == GS_CREDITS || gamestate == GS_EVALUATION) + || gamestate == GS_CREDITS || gamestate == GS_EVALUATION || gamestate == GS_WAITINGPLAYERS) CON_DrawHudlines(); Unlock_state(); diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 210619164..9b3187cbb 100755 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2600,6 +2600,8 @@ static void CL_ConnectToServer(void) } while (!(cl_mode == CL_CONNECTED && (client || (server && nodewaited <= pnumnodes)))); + if (netgame) + F_StartWaitingPlayers(); DEBFILE(va("Synchronisation Finished\n")); displayplayer = consoleplayer; diff --git a/src/d_main.c b/src/d_main.c index 5861f9886..2db400258 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -458,6 +458,13 @@ static void D_Display(void) case GS_WAITINGPLAYERS: // The clientconnect drawer is independent... + if (netgame) + { + // I don't think HOM from nothing drawing is independent... + F_WaitingPlayersDrawer(); + HU_Erase(); + HU_Drawer(); + } case GS_DEDICATEDSERVER: case GS_NULL: break; diff --git a/src/d_netcmd.c b/src/d_netcmd.c index b23aaa5a0..2cdf70843 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -2174,7 +2174,7 @@ static void Command_Pause(void) if (cv_pause.value || server || (IsPlayerAdmin(consoleplayer))) { - if (modeattacking || !(gamestate == GS_LEVEL || gamestate == GS_INTERMISSION) || (marathonmode && gamestate == GS_INTERMISSION)) + if (modeattacking || !(gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_WAITINGPLAYERS) || (marathonmode && gamestate == GS_INTERMISSION)) { CONS_Printf(M_GetText("You can't pause here.\n")); return; diff --git a/src/f_finale.c b/src/f_finale.c index 299a6a054..529244b5a 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -4660,3 +4660,36 @@ void F_TextPromptTicker(void) animtimer--; } } + +// ================ +// WAITINGPLAYERS +// ================ + +void F_StartWaitingPlayers(void) +{ + wipegamestate = GS_TITLESCREEN; // technically wiping from title screen + finalecount = 0; +} + +void F_WaitingPlayersTicker(void) +{ + if (paused) + return; + + finalecount++; + + // dumb hack, only start the music on the 1st tick so if you instantly go into the map you aren't hearing a tic of music + if (finalecount == 2) + S_ChangeMusicInternal("_CHSEL", true); +} + +void F_WaitingPlayersDrawer(void) +{ + const char *waittext1 = "You will join"; + const char *waittext2 = "next level..."; + + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); + + V_DrawCreditString((160 - (V_CreditStringWidth(waittext1)>>1))<>1))< Date: Mon, 17 Jul 2023 00:44:34 -0400 Subject: [PATCH 260/586] Even more SRB2Kart netcode improvement ports - Prevent connection timeout during the waiting gamestate from the last commit. - Keep client connections alive during fades / other internal loops. - More consistently timeout clients when they reach the end of BACKUPTICS. - Dedicated servers will not run any game logic if no nodes are sending packets to it, to reduce CPU usage when there is no one interacting with your server. - Unlike SRB2Kart, the amount of time is configurable with the "dedicatedidletime" console variable. Setting this to 0 will disable this feature. - CL_SendClientCmd uses exact packet types instead of magic number offsets. --- src/d_clisrv.c | 274 +++++++++++++++++++++++++++++++++++++++---------- src/d_clisrv.h | 6 ++ src/d_net.c | 3 + src/d_netcmd.c | 1 + src/f_wipe.c | 2 + src/g_game.c | 1 + src/p_setup.c | 1 + 7 files changed, 235 insertions(+), 53 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 9b3187cbb..13dab4539 100755 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -120,6 +120,8 @@ UINT8 hu_redownloadinggamestate = 0; // true when a player is connecting or disconnecting so that the gameplay has stopped in its tracks boolean hu_stopped = false; +consvar_t cv_dedicatedidletime = CVAR_INIT ("dedicatedidletime", "10", CV_SAVE, CV_Unsigned, NULL); + UINT8 adminpassmd5[16]; boolean adminpasswordset = false; @@ -4520,6 +4522,7 @@ static void HandlePacketFromPlayer(SINT8 node) netconsole = 0; else netconsole = nodetoplayer[node]; + #ifdef PARANOIA if (netconsole >= MAXPLAYERS) I_Error("bad table nodetoplayer: node %d player %d", doomcom->remotenode, netconsole); @@ -4558,15 +4561,20 @@ static void HandlePacketFromPlayer(SINT8 node) // 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) + // This should probably still timeout though, as the node should always have a player 1 number + if (netconsole == -1) 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; + // Don't do anything for packets of type NODEKEEPALIVE? + // Sryder 2018/07/01: Update the freezetimeout still! + if (netbuffer->packettype == PT_NODEKEEPALIVE + || netbuffer->packettype == PT_NODEKEEPALIVEMIS) + break; + // If we've alredy received a ticcmd for this tic, just submit it for the next one. tic_t faketic = maketic; if ((!!(netcmds[maketic % BACKUPTICS][netconsole].angleturn & TICCMD_RECEIVED)) @@ -4630,6 +4638,21 @@ static void HandlePacketFromPlayer(SINT8 node) } } break; + case PT_BASICKEEPALIVE: + if (client) + break; + + // This should probably still timeout though, as the node should always have a player 1 number + if (netconsole == -1) + break; + + // If a client sends this it should mean they are done receiving the savegame + sendingsavegame[node] = false; + + // As long as clients send keep alives, the server can keep running, so reset the timeout + /// \todo Use a separate cvar for that kind of timeout? + freezetimeout[node] = I_GetTime() + connectiontimeout; + break; case PT_TEXTCMD2: // splitscreen special netconsole = nodetoplayer2[node]; /* FALLTHRU */ @@ -5056,39 +5079,66 @@ static INT16 Consistancy(void) return (INT16)(ret & 0xFFFF); } +// confusing, but this DOESN'T send PT_NODEKEEPALIVE, it sends PT_BASICKEEPALIVE +// used during wipes to tell the server that a node is still connected +static void CL_SendClientKeepAlive(void) +{ + netbuffer->packettype = PT_BASICKEEPALIVE; + + HSendPacket(servernode, false, 0, 0); +} + +static void SV_SendServerKeepAlive(void) +{ + INT32 n; + + for (n = 1; n < MAXNETNODES; n++) + { + if (nodeingame[n]) + { + netbuffer->packettype = PT_BASICKEEPALIVE; + HSendPacket(n, false, 0, 0); + } + } +} + // send the client packet to the server static void CL_SendClientCmd(void) { size_t packetsize = 0; + boolean mis = false; netbuffer->packettype = PT_CLIENTCMD; if (cl_packetmissed) - netbuffer->packettype++; + { + netbuffer->packettype = PT_CLIENTMIS; + mis = true; + } + 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; + netbuffer->packettype = (mis ? PT_NODEKEEPALIVEMIS : PT_NODEKEEPALIVE); packetsize = sizeof (clientcmd_pak) - sizeof (ticcmd_t) - sizeof (INT16); HSendPacket(servernode, false, 0, packetsize); } else if (gamestate != GS_NULL && (addedtogame || dedicated)) { + packetsize = sizeof (clientcmd_pak); 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); + netbuffer->packettype = (mis ? PT_CLIENT2MIS : PT_CLIENT2CMD); packetsize = sizeof (client2cmd_pak); + G_MoveTiccmd(&netbuffer->u.client2pak.cmd2, &localcmds2, 1); } - else - packetsize = sizeof (clientcmd_pak); HSendPacket(servernode, false, 0, packetsize); } @@ -5099,7 +5149,7 @@ static void CL_SendClientCmd(void) if (localtextcmd[0]) { netbuffer->packettype = PT_TEXTCMD; - M_Memcpy(netbuffer->u.textcmd,localtextcmd, localtextcmd[0]+1); + 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; @@ -5479,28 +5529,11 @@ static inline void PingUpdate(void) pingmeasurecount = 1; //Reset count } -void NetUpdate(void) +static tic_t gametime = 0; + +static void UpdatePingTable(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) { @@ -5512,6 +5545,150 @@ void NetUpdate(void) realpingtable[i] += G_TicsToMilliseconds(GetLag(playernode[i])); pingmeasurecount++; } +} + +// Handle timeouts to prevent definitive freezes from happenning +static void HandleNodeTimeouts(void) +{ + INT32 i; + + 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); + } +} + +// Keep the network alive while not advancing tics! +void NetKeepAlive(void) +{ + tic_t nowtime; + INT32 realtics; + + nowtime = I_GetTime(); + realtics = nowtime - gametime; + + // return if there's no time passed since the last call + if (realtics <= 0) // nothing new to update + return; + + UpdatePingTable(); + + GetPackets(); + +#ifdef MASTERSERVER + MasterClient_Ticker(); +#endif + + if (client) + { + // send keep alive + CL_SendClientKeepAlive(); + // No need to check for resynch because we aren't running any tics + } + else + { + SV_SendServerKeepAlive(); + } + + // No else because no tics are being run and we can't resynch during this + + Net_AckTicker(); + HandleNodeTimeouts(); + FileSendTicker(); +} + +void NetUpdate(void) +{ + 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; + } + + if (server && dedicated && gamestate == GS_LEVEL) + { + const tic_t dedicatedidletime = cv_dedicatedidletime.value * TICRATE; + static tic_t dedicatedidletimeprev = 0; + static tic_t dedicatedidle = 0; + + if (dedicatedidletime > 0) + { + for (i = 1; i < MAXNETNODES; ++i) + if (nodeingame[i]) + { + if (dedicatedidle >= dedicatedidletime) + { + CONS_Printf("DEDICATED: Awakening from idle (Node %d detected...)\n", i); + dedicatedidle = 0; + } + break; + } + + if (i == MAXNETNODES) + { + if (leveltime == 2) + { + // On next tick... + dedicatedidle = dedicatedidletime-1; + } + else if (dedicatedidle >= dedicatedidletime) + { + if (D_GetExistingTextcmd(gametic, 0) || D_GetExistingTextcmd(gametic+1, 0)) + { + CONS_Printf("DEDICATED: Awakening from idle (Netxcmd detected...)\n"); + dedicatedidle = 0; + } + else + { + realtics = 0; + } + } + else if ((dedicatedidle += realtics) >= dedicatedidletime) + { + const char *idlereason = "at round start"; + if (leveltime > 3) + idlereason = va("for %d seconds", dedicatedidle/TICRATE); + + CONS_Printf("DEDICATED: No nodes %s, idling...\n", idlereason); + realtics = 0; + dedicatedidle = dedicatedidletime; + } + } + } + else + { + if (dedicatedidletimeprev > 0 && dedicatedidle >= dedicatedidletimeprev) + { + CONS_Printf("DEDICATED: Awakening from idle (Idle disabled...)\n"); + } + dedicatedidle = 0; + } + + dedicatedidletimeprev = dedicatedidletime; + } + + gametime = nowtime; + + UpdatePingTable(); if (client) maketic = neededtic; @@ -5543,25 +5720,26 @@ void NetUpdate(void) } else { - if (!demoplayback) + if (!demoplayback && realtics > 0) { 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; + firstticstosend = gametic; + for (i = 0; i < MAXNETNODES; i++) + { + if (!nodeingame[i]) + continue; + if (nettics[i] < firstticstosend) + firstticstosend = nettics[i]; + if (maketic + counts >= nettics[i] + (BACKUPTICS - TICRATE)) + Net_ConnectionTimeout(i); + } + if (maketic + counts >= firstticstosend + BACKUPTICS) counts = firstticstosend+BACKUPTICS-maketic-1; @@ -5578,20 +5756,10 @@ void NetUpdate(void) } 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); - } + HandleNodeTimeouts(); nowtime /= NEWTICRATERATIO; + if (nowtime > resptime) { resptime = nowtime; diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 04a7b5ba2..49fb5fc1d 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -77,6 +77,8 @@ typedef enum PT_ASKLUAFILE, // Client telling the server they don't have the file PT_HASLUAFILE, // Client telling the server they have the file + PT_BASICKEEPALIVE,// Keep the network alive during wipes, as tics aren't advanced and NetUpdate isn't called + // Add non-PT_CANFAIL packet types here to avoid breaking MS compatibility. PT_CANFAIL, // This is kind of a priority. Anything bigger than CANFAIL @@ -398,6 +400,7 @@ extern tic_t servermaxping; extern consvar_t cv_netticbuffer, cv_allownewplayer, cv_joinnextround, cv_maxplayers, cv_joindelay, cv_rejointimeout; extern consvar_t cv_resynchattempts, cv_blamecfail; extern consvar_t cv_maxsend, cv_noticedownload, cv_downloadspeed; +extern consvar_t cv_dedicatedidletime; // Used in d_net, the only dependence tic_t ExpandTics(INT32 low, INT32 node); @@ -412,6 +415,9 @@ void SendKick(UINT8 playernum, UINT8 msg); // Create any new ticcmds and broadcast to other players. void NetUpdate(void); +// Maintain connections to nodes without timing them all out. +void NetKeepAlive(void); + void SV_StartSinglePlayerServer(void); boolean SV_SpawnServer(void); void SV_StopServer(void); diff --git a/src/d_net.c b/src/d_net.c index 768c9ac7e..6d8c72942 100644 --- a/src/d_net.c +++ b/src/d_net.c @@ -869,6 +869,9 @@ static void DebugPrintpacket(const char *header) (UINT32)ExpandTics(netbuffer->u.clientpak.client_tic, doomcom->remotenode), (UINT32)ExpandTics (netbuffer->u.clientpak.resendfrom, doomcom->remotenode)); break; + case PT_BASICKEEPALIVE: + fprintf(debugfile, " wipetime\n"); + break; case PT_TEXTCMD: case PT_TEXTCMD2: fprintf(debugfile, " length %d\n ", netbuffer->u.textcmd[0]); diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 2cdf70843..8fd207037 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -599,6 +599,7 @@ void D_RegisterServerCommands(void) CV_RegisterVar(&cv_joinnextround); CV_RegisterVar(&cv_showjoinaddress); CV_RegisterVar(&cv_blamecfail); + CV_RegisterVar(&cv_dedicatedidletime); #endif COM_AddCommand("ping", Command_Ping_f, COM_LUA); diff --git a/src/f_wipe.c b/src/f_wipe.c index 6014fb7f9..4bcfb029b 100644 --- a/src/f_wipe.c +++ b/src/f_wipe.c @@ -614,6 +614,8 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu) if (moviemode) M_SaveFrame(); + + NetKeepAlive(); // Update the network so we don't cause timeouts } WipeInAction = false; diff --git a/src/g_game.c b/src/g_game.c index bcfe69105..eea804c83 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1915,6 +1915,7 @@ void G_PreLevelTitleCard(void) ST_runTitleCard(); ST_preLevelTitleCardDrawer(); I_FinishUpdate(); // page flip or blit buffer + NetKeepAlive(); // Prevent timeouts if (moviemode) M_SaveFrame(); diff --git a/src/p_setup.c b/src/p_setup.c index a10326986..e4a46c0f4 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -7436,6 +7436,7 @@ static void P_RunSpecialStageWipe(void) lastwipetic = nowtime; if (moviemode) // make sure we save frames for the white hold too M_SaveFrame(); + NetKeepAlive(); // Prevent timeout } } From ff56d46827e9ff9ba71222248eda3483ac106cd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Mon, 17 Jul 2023 16:41:22 +0200 Subject: [PATCH 261/586] fixup! Fix softlocking as Sonic & Tails when Player 2 has no name --- src/d_clisrv.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 05af083bd..9a8aedefa 100755 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1311,7 +1311,10 @@ static boolean CL_SendJoin(void) if (splitscreen) CleanupPlayerName(1, cv_playername2.zstring);/* 1 is a HACK? oh no */ // Avoid empty string on bots to avoid softlocking in singleplayer - player2name = botingame ? "a" : cv_playername2.zstring; + if (botingame) + player2name = strcmp(cv_playername.zstring, "Tails") == 0 ? "Tail" : "Tails"; + else + player2name = cv_playername2.zstring; strncpy(netbuffer->u.clientcfg.names[0], cv_playername.zstring, MAXPLAYERNAME); strncpy(netbuffer->u.clientcfg.names[1], player2name, MAXPLAYERNAME); From 8cf65e83018e02e4bcdea186082a9fc82f23e50c Mon Sep 17 00:00:00 2001 From: katsy <205-katsy@users.noreply.git.do.srb2.org> Date: Wed, 19 Jul 2023 19:43:15 +0000 Subject: [PATCH 262/586] Fix inconsistency with title card patch coloring (color the title card patch used in the credits to skin) --- src/f_finale.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/f_finale.c b/src/f_finale.c index 8dd03d44f..2a551da7e 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1301,14 +1301,23 @@ void F_CreditDrawer(void) UINT16 i; INT16 zagpos = (timetonext - finalecount - animtimer) % 32; fixed_t y = (80<>1); + UINT8 colornum; + const UINT8 *colormap; + + if (players[consoleplayer].skincolor) + colornum = players[consoleplayer].skincolor; + else + colornum = cv_playercolor.value; + + colormap = R_GetTranslationColormap(TC_DEFAULT, colornum, GTC_CACHE); V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); // Zig Zagz - V_DrawScaledPatch(-16, zagpos, V_SNAPTOLEFT, W_CachePatchName("LTZIGZAG", PU_PATCH_LOWPRIORITY)); - V_DrawScaledPatch(-16, zagpos - 320, V_SNAPTOLEFT, W_CachePatchName("LTZIGZAG", PU_PATCH_LOWPRIORITY)); - V_DrawScaledPatch(BASEVIDWIDTH + 16, zagpos, V_SNAPTORIGHT|V_FLIP, W_CachePatchName("LTZIGZAG", PU_PATCH_LOWPRIORITY)); - V_DrawScaledPatch(BASEVIDWIDTH + 16, zagpos - 320, V_SNAPTORIGHT|V_FLIP, W_CachePatchName("LTZIGZAG", PU_PATCH_LOWPRIORITY)); + V_DrawFixedPatch(-16*FRACUNIT, zagpos< Date: Wed, 19 Jul 2023 23:17:21 +0200 Subject: [PATCH 263/586] Clean up and simplify zone memory allocation --- src/z_zone.c | 225 +++++++++------------------------------------------ 1 file changed, 39 insertions(+), 186 deletions(-) diff --git a/src/z_zone.c b/src/z_zone.c index d23c43b7b..5750f8ae0 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -51,27 +51,11 @@ static boolean Z_calloc = false; //#define ZDEBUG2 #endif -struct memblock_s; - -typedef struct -{ - struct memblock_s *block; // Describing this memory - UINT32 id; // Should be ZONEID -} ATTRPACK memhdr_t; - -// Some code might want aligned memory. Assume it wants memory n bytes -// aligned -- then we allocate n-1 extra bytes and return a pointer to -// the first byte aligned as requested. -// Thus, "real" is the pointer we get from malloc() and will free() -// later, but "hdr" is where the memhdr_t starts. -// For non-aligned allocations they will be the same. typedef struct memblock_s { - void *real; - memhdr_t *hdr; - void **user; INT32 tag; // purgelevel + UINT32 id; // Should be ZONEID size_t size; // including the header and blocks size_t realsize; // size of real data only @@ -82,7 +66,10 @@ typedef struct memblock_s #endif struct memblock_s *next, *prev; -} ATTRPACK memblock_t; +} memblock_t; + +#define MEMORY(x) (void *)((uintptr_t)(x) + sizeof(memblock_t)) +#define MEMBLOCK(x) (memblock_t *)((uintptr_t)(x) - sizeof(memblock_t)) // both the head and tail of the zone memory block list static memblock_t head; @@ -128,64 +115,6 @@ void Z_Init(void) // Zone memory allocation // ---------------------- -/** Returns the corresponding memblock_t for a given memory block. - * - * \param ptr A pointer to allocated memory, - * assumed to have been allocated with Z_Malloc/Z_Calloc. - * \param func A string containing the name of the function that called this, - * to be printed if the function I_Errors - * \return A pointer to the memblock_t for the given memory. - * \sa Z_Free, Z_ReallocAlign - */ -#ifdef ZDEBUG -#define Ptr2Memblock(s, f) Ptr2Memblock2(s, f, __FILE__, __LINE__) -static memblock_t *Ptr2Memblock2(void *ptr, const char* func, const char *file, INT32 line) -#else -static memblock_t *Ptr2Memblock(void *ptr, const char* func) -#endif -{ - memhdr_t *hdr; - memblock_t *block; - - if (ptr == NULL) - return NULL; - -#ifdef ZDEBUG2 - CONS_Printf("%s %s:%d\n", func, file, line); -#endif - - hdr = (memhdr_t *)((UINT8 *)ptr - sizeof *hdr); - -#ifdef VALGRIND_MAKE_MEM_DEFINED - VALGRIND_MAKE_MEM_DEFINED(hdr, sizeof *hdr); -#endif - -#ifdef VALGRIND_MEMPOOL_EXISTS - if (!VALGRIND_MEMPOOL_EXISTS(hdr->block)) - { -#ifdef ZDEBUG - I_Error("%s: bad memblock from %s:%d", func, file, line); -#else - I_Error("%s: bad memblock", func); -#endif - } -#endif - if (hdr->id != ZONEID) - { -#ifdef ZDEBUG - I_Error("%s: wrong id from %s:%d", func, file, line); -#else - I_Error("%s: wrong id", func); -#endif - } - block = hdr->block; -#ifdef VALGRIND_MAKE_MEM_NOACCESS - VALGRIND_MAKE_MEM_NOACCESS(hdr, sizeof *hdr); -#endif - return block; - -} - /** Frees allocated memory. * * \param ptr A pointer to allocated memory, @@ -207,10 +136,14 @@ void Z_Free(void *ptr) CONS_Debug(DBG_MEMORY, "Z_Free %s:%d\n", file, line); #endif + block = MEMBLOCK(ptr); +#ifdef PARANOIA + if (block->id != ZONEID) #ifdef ZDEBUG - block = Ptr2Memblock2(ptr, "Z_Free", file, line); + I_Error("Z_Free at %s:%d: wrong id", file, line); #else - block = Ptr2Memblock(ptr, "Z_Free"); + I_Error("Z_Free: wrong id"); +#endif #endif #ifdef ZDEBUG @@ -229,8 +162,6 @@ void Z_Free(void *ptr) if (block->user != NULL) *block->user = NULL; - // Free the memory and get rid of the block. - free(block->real); #ifdef VALGRIND_DESTROY_MEMPOOL VALGRIND_DESTROY_MEMPOOL(block); #endif @@ -287,35 +218,17 @@ void *Z_Malloc2(size_t size, INT32 tag, void *user, INT32 alignbits, void *Z_MallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits) #endif { - I_Assert(alignbits >= 0 && alignbits < (INT32)(sizeof(size_t) * 8)); - size_t extrabytes = ((size_t)1<next->prev = block; - block->real = ptr; - block->hdr = hdr; block->tag = tag; block->user = NULL; #ifdef ZDEBUG block->ownerline = line; block->ownerfile = file; #endif - block->size = blocksize; + block->size = sizeof (memblock_t) + size; block->realsize = size; #ifdef VALGRIND_CREATE_MEMPOOL - VALGRIND_CREATE_MEMPOOL(block, padsize, Z_calloc); + VALGRIND_CREATE_MEMPOOL(block, size, Z_calloc); #endif -//#ifdef VALGRIND_MEMPOOL_ALLOC -// VALGRIND_MEMPOOL_ALLOC(block, hdr, size + sizeof *hdr); -//#endif - hdr->id = ZONEID; - hdr->block = block; - -#ifdef VALGRIND_MAKE_MEM_NOACCESS - VALGRIND_MAKE_MEM_NOACCESS(hdr, sizeof *hdr); -#endif + block->id = ZONEID; if (user != NULL) { block->user = user; - *(void **)user = given; + *(void **)user = ptr; } else if (tag >= PU_PURGELEVEL) I_Error("Z_Malloc: attempted to allocate purgable block " "(size %s) with no user", sizeu1(size)); - return given; + return ptr; } /** The Z_CallocAlign function. @@ -437,10 +340,14 @@ void *Z_ReallocAlign(void *ptr, size_t size, INT32 tag, void *user, INT32 alignb #endif } + block = MEMBLOCK(ptr); +#ifdef PARANOIA + if (block->id != ZONEID) #ifdef ZDEBUG - block = Ptr2Memblock2(ptr, "Z_Realloc", file, line); + I_Error("Z_ReallocAlign at %s:%d: wrong id", file, line); #else - block = Ptr2Memblock(ptr, "Z_Realloc"); + I_Error("Z_ReallocAlign: wrong id"); +#endif #endif if (block == NULL) @@ -491,9 +398,8 @@ void Z_FreeTags(INT32 lowtag, INT32 hightag) for (block = head.next; block != &head; block = next) { next = block->next; // get link before freeing - if (block->tag >= lowtag && block->tag <= hightag) - Z_Free((UINT8 *)block->hdr + sizeof *block->hdr); + Z_Free(MEMORY(block)); } } @@ -516,7 +422,7 @@ void Z_IterateTags(INT32 lowtag, INT32 hightag, boolean (*iterfunc)(void *)) if (block->tag >= lowtag && block->tag <= hightag) { - void *mem = (UINT8 *)block->hdr + sizeof *block->hdr; + void *mem = MEMORY(block); boolean free = iterfunc(mem); if (free) Z_Free(mem); @@ -561,15 +467,13 @@ void Z_CheckMemCleanup(void) void Z_CheckHeap(INT32 i) { memblock_t *block; - memhdr_t *hdr; UINT32 blocknumon = 0; void *given; for (block = head.next; block != &head; block = block->next) { blocknumon++; - hdr = block->hdr; - given = (UINT8 *)hdr + sizeof *hdr; + given = MEMORY(block); #ifdef ZDEBUG2 CONS_Debug(DBG_MEMORY, "block %u owned by %s:%d\n", blocknumon, block->ownerfile, block->ownerline); @@ -585,7 +489,7 @@ void Z_CheckHeap(INT32 i) #ifdef ZDEBUG , block->ownerfile, block->ownerline #endif - ); + ); } #endif if (block->user != NULL && *(block->user) != given) @@ -598,7 +502,7 @@ void Z_CheckHeap(INT32 i) #ifdef ZDEBUG , block->ownerfile, block->ownerline #endif - ); + ); } if (block->next->prev != block) { @@ -610,7 +514,7 @@ void Z_CheckHeap(INT32 i) #ifdef ZDEBUG , block->ownerfile, block->ownerline #endif - ); + ); } if (block->prev->next != block) { @@ -622,25 +526,9 @@ void Z_CheckHeap(INT32 i) #ifdef ZDEBUG , block->ownerfile, block->ownerline #endif - ); + ); } -#ifdef VALGRIND_MAKE_MEM_DEFINED - VALGRIND_MAKE_MEM_DEFINED(hdr, sizeof *hdr); -#endif - if (hdr->block != block) - { - I_Error("Z_CheckHeap %d: block %u" -#ifdef ZDEBUG - "(owned by %s:%d)" -#endif - " doesn't have linkback from allocated memory", - i, blocknumon -#ifdef ZDEBUG - , block->ownerfile, block->ownerline -#endif - ); - } - if (hdr->id != ZONEID) + if (block->id != ZONEID) { I_Error("Z_CheckHeap %d: block %u" #ifdef ZDEBUG @@ -650,11 +538,8 @@ void Z_CheckHeap(INT32 i) #ifdef ZDEBUG , block->ownerfile, block->ownerline #endif - ); + ); } -#ifdef VALGRIND_MAKE_MEM_NOACCESS - VALGRIND_MAKE_MEM_NOACCESS(hdr, sizeof *hdr); -#endif } } @@ -676,35 +561,14 @@ void Z_ChangeTag(void *ptr, INT32 tag) #endif { memblock_t *block; - memhdr_t *hdr; if (ptr == NULL) return; - hdr = (memhdr_t *)((UINT8 *)ptr - sizeof *hdr); + block = MEMBLOCK(ptr); -#ifdef VALGRIND_MAKE_MEM_DEFINED - VALGRIND_MAKE_MEM_DEFINED(hdr, sizeof *hdr); -#endif - -#ifdef VALGRIND_MEMPOOL_EXISTS - if (!VALGRIND_MEMPOOL_EXISTS(hdr->block)) - { #ifdef PARANOIA - I_Error("Z_CT at %s:%d: bad memblock", file, line); -#else - I_Error("Z_CT: bad memblock"); -#endif - } -#endif -#ifdef PARANOIA - if (hdr->id != ZONEID) I_Error("Z_CT at %s:%d: wrong id", file, line); -#endif - - block = hdr->block; - -#ifdef VALGRIND_MAKE_MEM_NOACCESS - VALGRIND_MAKE_MEM_NOACCESS(hdr, sizeof *hdr); + if (block->id != ZONEID) I_Error("Z_ChangeTag at %s:%d: wrong id", file, line); #endif if (tag >= PU_PURGELEVEL && block->user == NULL) @@ -728,25 +592,14 @@ void Z_SetUser(void *ptr, void **newuser) #endif { memblock_t *block; - memhdr_t *hdr; if (ptr == NULL) return; - hdr = (memhdr_t *)((UINT8 *)ptr - sizeof *hdr); - -#ifdef VALGRIND_MAKE_MEM_DEFINED - VALGRIND_MAKE_MEM_DEFINED(hdr, sizeof *hdr); -#endif + block = MEMBLOCK(ptr); #ifdef PARANOIA - if (hdr->id != ZONEID) I_Error("Z_CT at %s:%d: wrong id", file, line); -#endif - - block = hdr->block; - -#ifdef VALGRIND_MAKE_MEM_NOACCESS - VALGRIND_MAKE_MEM_NOACCESS(hdr, sizeof *hdr); + if (block->id != ZONEID) I_Error("Z_SetUser at %s:%d: wrong id", file, line); #endif if (block->tag >= PU_PURGELEVEL && newuser == NULL) From 36e6a2001a8a3f5ea3faf9add65a84ffc3ac08b9 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Thu, 20 Jul 2023 01:43:10 -0400 Subject: [PATCH 264/586] Paired down OS Lua library Pretty much removed everything except for time operations. File operations steps on the toes of the IO library, and the others were useless or invasive. The only one I wasn't sure about was `os.tmpname()`, but I think that's something that could be implemented for IO library instead if necessary. The main reason I want this is because os.time provides an OK way to initially seed RNG on game first boot. But it would also be cute to let Lua modders be able to re-implement Christmas mode / day&night cycles themselves :p --- src/blua/Sourcefile | 1 + src/blua/linit.c | 1 + src/blua/loslib.c | 167 ++++++++++++++++++++++++++++++++++++++++++++ src/blua/lualib.h | 3 + 4 files changed, 172 insertions(+) create mode 100644 src/blua/loslib.c diff --git a/src/blua/Sourcefile b/src/blua/Sourcefile index f99c89c8d..dae943109 100644 --- a/src/blua/Sourcefile +++ b/src/blua/Sourcefile @@ -23,3 +23,4 @@ lstring.c ltable.c ltm.c lvm.c +loslib.c diff --git a/src/blua/linit.c b/src/blua/linit.c index d17390b20..dcf05d9f2 100644 --- a/src/blua/linit.c +++ b/src/blua/linit.c @@ -18,6 +18,7 @@ static const luaL_Reg lualibs[] = { {"", luaopen_base}, {LUA_TABLIBNAME, luaopen_table}, {LUA_IOLIBNAME, luaopen_io}, + {LUA_OSLIBNAME, luaopen_os}, {LUA_STRLIBNAME, luaopen_string}, {NULL, NULL} }; diff --git a/src/blua/loslib.c b/src/blua/loslib.c new file mode 100644 index 000000000..ba2e1e384 --- /dev/null +++ b/src/blua/loslib.c @@ -0,0 +1,167 @@ +/* +** $Id: loslib.c,v 1.19.1.3 2008/01/18 16:38:18 roberto Exp $ +** Standard Operating System library +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include +#include +#include + +#define loslib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +static int os_clock (lua_State *L) { + lua_pushnumber(L, ((lua_Number)clock())/(lua_Number)CLOCKS_PER_SEC); + return 1; +} + + +/* +** {====================================================== +** Time/Date operations +** { year=%Y, month=%m, day=%d, hour=%H, min=%M, sec=%S, +** wday=%w+1, yday=%j, isdst=? } +** ======================================================= +*/ + +static void setfield (lua_State *L, const char *key, int value) { + lua_pushinteger(L, value); + lua_setfield(L, -2, key); +} + +static void setboolfield (lua_State *L, const char *key, int value) { + if (value < 0) /* undefined? */ + return; /* does not set field */ + lua_pushboolean(L, value); + lua_setfield(L, -2, key); +} + +static int getboolfield (lua_State *L, const char *key) { + int res; + lua_getfield(L, -1, key); + res = lua_isnil(L, -1) ? -1 : lua_toboolean(L, -1); + lua_pop(L, 1); + return res; +} + + +static int getfield (lua_State *L, const char *key, int d) { + int res; + lua_getfield(L, -1, key); + if (lua_isnumber(L, -1)) + res = (int)lua_tointeger(L, -1); + else { + if (d < 0) + return luaL_error(L, "field " LUA_QS " missing in date table", key); + res = d; + } + lua_pop(L, 1); + return res; +} + + +static int os_date (lua_State *L) { + const char *s = luaL_optstring(L, 1, "%c"); + time_t t = luaL_opt(L, (time_t)luaL_checknumber, 2, time(NULL)); + struct tm *stm; + if (*s == '!') { /* UTC? */ + stm = gmtime(&t); + s++; /* skip `!' */ + } + else + stm = localtime(&t); + if (stm == NULL) /* invalid date? */ + lua_pushnil(L); + else if (strcmp(s, "*t") == 0) { + lua_createtable(L, 0, 9); /* 9 = number of fields */ + setfield(L, "sec", stm->tm_sec); + setfield(L, "min", stm->tm_min); + setfield(L, "hour", stm->tm_hour); + setfield(L, "day", stm->tm_mday); + setfield(L, "month", stm->tm_mon+1); + setfield(L, "year", stm->tm_year+1900); + setfield(L, "wday", stm->tm_wday+1); + setfield(L, "yday", stm->tm_yday+1); + setboolfield(L, "isdst", stm->tm_isdst); + } + else { + char cc[3]; + luaL_Buffer b; + cc[0] = '%'; cc[2] = '\0'; + luaL_buffinit(L, &b); + for (; *s; s++) { + if (*s != '%' || *(s + 1) == '\0') /* no conversion specifier? */ + luaL_addchar(&b, *s); + else { + size_t reslen; + char buff[200]; /* should be big enough for any conversion result */ + cc[1] = *(++s); + reslen = strftime(buff, sizeof(buff), cc, stm); + luaL_addlstring(&b, buff, reslen); + } + } + luaL_pushresult(&b); + } + return 1; +} + + +static int os_time (lua_State *L) { + time_t t; + if (lua_isnoneornil(L, 1)) /* called without args? */ + t = time(NULL); /* get current time */ + else { + struct tm ts; + luaL_checktype(L, 1, LUA_TTABLE); + lua_settop(L, 1); /* make sure table is at the top */ + ts.tm_sec = getfield(L, "sec", 0); + ts.tm_min = getfield(L, "min", 0); + ts.tm_hour = getfield(L, "hour", 12); + ts.tm_mday = getfield(L, "day", -1); + ts.tm_mon = getfield(L, "month", -1) - 1; + ts.tm_year = getfield(L, "year", -1) - 1900; + ts.tm_isdst = getboolfield(L, "isdst"); + t = mktime(&ts); + } + if (t == (time_t)(-1)) + lua_pushnil(L); + else + lua_pushnumber(L, (lua_Number)t); + return 1; +} + + +static int os_difftime (lua_State *L) { + lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)), + (time_t)(luaL_optnumber(L, 2, 0)))); + return 1; +} + +/* }====================================================== */ + +static const luaL_Reg syslib[] = { + {"clock", os_clock}, + {"date", os_date}, + {"difftime", os_difftime}, + {"time", os_time}, + {NULL, NULL} +}; + +/* }====================================================== */ + + + +LUALIB_API int luaopen_os (lua_State *L) { + luaL_register(L, LUA_OSLIBNAME, syslib); + return 1; +} diff --git a/src/blua/lualib.h b/src/blua/lualib.h index 4ea97edf3..7127e4d77 100644 --- a/src/blua/lualib.h +++ b/src/blua/lualib.h @@ -24,6 +24,9 @@ LUALIB_API int (luaopen_table) (lua_State *L); #define LUA_IOLIBNAME "io" LUALIB_API int (luaopen_io) (lua_State *L); +#define LUA_OSLIBNAME "os" +LUALIB_API int (luaopen_os) (lua_State *L); + #define LUA_STRLIBNAME "string" LUALIB_API int (luaopen_string) (lua_State *L); From dee24896205c4ed9ae18662bdf8c4aa4a9865770 Mon Sep 17 00:00:00 2001 From: toaster Date: Thu, 20 Jul 2023 17:54:47 +0100 Subject: [PATCH 265/586] P_GetNodeType: Do not dereference invalid pointer for **nodedata parameter --- src/p_setup.c | 52 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 15 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index a10326986..3c83c6c91 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3205,10 +3205,17 @@ static nodetype_t P_GetNodetype(const virtres_t *virt, UINT8 **nodedata) nodetype_t nodetype = NT_UNSUPPORTED; char signature[4 + 1]; + *nodedata = NULL; + if (udmf) { - *nodedata = vres_Find(virt, "ZNODES")->data; - supported[NT_XGLN] = supported[NT_XGL3] = true; + virtlump_t *virtznodes = vres_Find(virt, "ZNODES"); + + if (virtznodes && virtznodes->size) + { + *nodedata = virtznodes->data; + supported[NT_XGLN] = supported[NT_XGL3] = true; + } } else { @@ -3217,24 +3224,39 @@ static nodetype_t P_GetNodetype(const virtres_t *virt, UINT8 **nodedata) if (virtsegs && virtsegs->size) { - *nodedata = vres_Find(virt, "NODES")->data; - return NT_DOOM; // Traditional map format BSP tree. - } - - virtssectors = vres_Find(virt, "SSECTORS"); - - if (virtssectors && virtssectors->size) - { // Possibly GL nodes: NODES ignored, SSECTORS takes precedence as nodes lump, (It is confusing yeah) and has a signature. - *nodedata = virtssectors->data; - supported[NT_XGLN] = supported[NT_ZGLN] = supported[NT_XGL3] = true; + virtlump_t *virtnodes = vres_Find(virt, "NODES"); + if (virtnodes && virtnodes->size) + { + *nodedata = virtnodes->data; + return NT_DOOM; // Traditional map format BSP tree. + } } else - { // Possibly ZDoom extended nodes: SSECTORS is empty, NODES has a signature. - *nodedata = vres_Find(virt, "NODES")->data; - supported[NT_XNOD] = supported[NT_ZNOD] = true; + { + virtssectors = vres_Find(virt, "SSECTORS"); + + if (virtssectors && virtssectors->size) + { // Possibly GL nodes: NODES ignored, SSECTORS takes precedence as nodes lump, (It is confusing yeah) and has a signature. + *nodedata = virtssectors->data; + supported[NT_XGLN] = supported[NT_ZGLN] = supported[NT_XGL3] = true; + } + else + { // Possibly ZDoom extended nodes: SSECTORS is empty, NODES has a signature. + virtlump_t *virtnodes = vres_Find(virt, "NODES"); + if (virtnodes && virtnodes->size) + { + *nodedata = virtnodes->data; + supported[NT_XNOD] = supported[NT_ZNOD] = true; + } + } } } + if (*nodedata == NULL) + { + I_Error("Level has no nodes (does your map have at least 2 sectors?)"); + } + M_Memcpy(signature, *nodedata, 4); signature[4] = '\0'; (*nodedata) += 4; From 66dd952fdd854800832aa563047c17e813a36c71 Mon Sep 17 00:00:00 2001 From: toaster Date: Thu, 20 Jul 2023 19:42:21 +0100 Subject: [PATCH 266/586] Tidier conversion of string properties on linedefs to UDMF Previously, many concatenated texture field strings were turned to text, then had that string run through get_number, then had it converted back into a string to become a stringarg. Now, the concatenated string is copied directly to the relevant stringarg, with no intermediary steps. This fixes an issue where a map with object or state properties would have "context drift" - breaking when the object or state list changed, due to differently ordered freeslots, or new hardcoded objects. Affected types: - doomednum 1110/Action 9 (Custom Mace/Chain) - doomednum 700 and those immediately following (Ambient Sound) - Action 4 and 414 (dash pad, play sound effect) - Action 14 (bustable block parameters) - Action 434 (Award Power) - doomednum 757/Action 15 (fan particle generator) - doomednum 1202 (bumpable hazard rock/apple spawner) - This one has undefined behaviour in the binary map format which was not previously forbidden. This undefined behaviour is EXTREMELY vulnerable to context drift, and so it's simply not worth creating a system to write numerical values into object types - we write an explicit name only for the intended range, and otherwise report the threat of context drift when converting. In addition, to reduce duplicated zone memory, (sidedef_t).text and (linedef_t).text have been removed from all but the Lua API. In Lua, in binary maps, they point to the host line's stringargs - the line's text and a frontside's text will return stringargs[0], while a backside's text will return stringargs[1]. I've done my best to match the previous API as closely possible, to the point of reporting false nils if the line didn't previously have text available. However, there are four linedef Actions for which the sidedef text will be different between builds containing and not containing this commit - 331, 332, 333 (the Character-specific linedef executors), and 443 (Call Lua Script), and only if the text is long enough to go over two lines. Given that both halves would be incomplete nonsense in this case, I'm willing to wager this minor point of discrepancy is not a breaking issue. --- src/lua_maplib.c | 35 +++++- src/p_setup.c | 322 ++++++++++++++++++++++++++--------------------- src/r_defs.h | 3 - 3 files changed, 208 insertions(+), 152 deletions(-) diff --git a/src/lua_maplib.c b/src/lua_maplib.c index f73b3c7d2..904b4316b 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -1032,8 +1032,24 @@ static int line_get(lua_State *L) LUA_PushUserdata(L, line->polyobj, META_POLYOBJ); return 1; case line_text: - lua_pushstring(L, line->text); - return 1; + { + if (udmf) + { + LUA_Deprecated(L, "(linedef_t).text", "(linedef_t).stringargs"); + lua_pushnil(L); + return 1; + } + + if (line->special == 331 || line->special == 443) + { + // See P_ProcessLinedefsAfterSidedefs, P_ConvertBinaryLinedefTypes + lua_pushstring(L, line->stringargs[0]); + } + else + lua_pushnil(L); + + return 1; + } case line_callcount: lua_pushinteger(L, line->callcount); return 1; @@ -1149,8 +1165,19 @@ static int side_get(lua_State *L) lua_pushinteger(L, side->repeatcnt); return 1; case side_text: - lua_pushstring(L, side->text); - return 1; + { + if (udmf) + { + LUA_Deprecated(L, "(sidedef_t).text", "(sidedef_t).line.stringargs"); + lua_pushnil(L); + return 1; + } + + boolean isfrontside = side->line->sidenum[0] == side-sides; + + lua_pushstring(L, side->line->stringargs[isfrontside ? 0 : 1]); + return 1; + } } return 0; } diff --git a/src/p_setup.c b/src/p_setup.c index 3c83c6c91..27ddb0775 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1103,7 +1103,6 @@ static void P_InitializeLinedef(line_t *ld) ld->validcount = 0; ld->polyobj = NULL; - ld->text = NULL; ld->callcount = 0; // cph 2006/09/30 - fix sidedef errors right away. @@ -1207,10 +1206,108 @@ static void P_InitializeSidedef(side_t *sd) sd->special = sd->line->special; } - sd->text = NULL; sd->colormap_data = NULL; } +static boolean contextdrift = false; + +// In Ring Racers, this is just the reference implementation. +// But in SRB2, backwards compatibility is a design goal!? +// So we let the map function on load, but report that there's +// an issue which could prevent saving it as a UDMF map. +// +// ... "context drift" is a term I learned from the story "Lena", +// styled after a wikipedia article on a man whose brain scan +// spawns an industry of digital brain emulation. It is a term +// to describe that the understanding of the world MMAcevedo has +// is rooted in a specific moment and time and will lose relevance +// as societal norms, languages, and events change and are changed. +// It is on the real wikipedia, but under the name "concept drift". +// I am connecting the idea of the rooted-in-time brainstate with +// the numerical evaluation of get_number(), the ground truth +// CONTEXT for all these silly integers, that will trip up future +// builds of SRB2 that have modified states and object lists. +// Golden statues rotating in place of carousel rides is perhaps +// not quite what qntm meant, but is a TEXTMAP, a human-readable +// document for imparting a sense of place made/read by machines, +// not its own language providing a vulnerable context? +// ~toast 200723, see https://qntm.org/mmacevedo +// +static void P_WriteConstant(INT32 constant, char **target, const char *desc, UINT32 id) +{ + char buffer[12]; + size_t len; + + CONS_Alert( + CONS_WARNING, M_GetText( + "P_WriteConstant has been called for %s %d, " + "this level is vulnerable to context drift " + "if -writetextmap is used.\n"), + desc, id + ); + + contextdrift = true; + + sprintf(buffer, "%d", constant); + len = strlen(buffer) + 1; + *target = Z_Malloc(len, PU_LEVEL, NULL); + M_Memcpy(*target, buffer, len); +} + +static void P_WriteDuplicateText(const char *text, char **target) +{ + if (text == NULL || text[0] == '\0') + return; + + size_t len = strlen(text) + 1; + *target = Z_Malloc(len, PU_LEVEL, NULL); + M_Memcpy(*target, text, len); +} + +static void P_WriteSkincolor(INT32 constant, char **target) +{ + if (constant <= SKINCOLOR_NONE + || constant >= (INT32)numskincolors) + return; + + P_WriteDuplicateText( + va("SKINCOLOR_%s", skincolors[constant].name), + target + ); +} + +static void P_WriteSfx(INT32 constant, char **target) +{ + if (constant <= sfx_None + || constant >= (INT32)sfxfree) + return; + + P_WriteDuplicateText( + va("sfx_%s", S_sfx[constant].name), + target + ); +} + +static void P_WriteTics(INT32 tics, char **target) +{ + if (!tics) + return; + + INT32 seconds = (tics / TICRATE); + tics %= TICRATE; + + const char *text; + + if (tics && !seconds) + text = va("%d", tics); + else if (seconds && !tics) + text = va("(%d*TICRATE)", seconds); + else + text = va("(%d*TICRATE)%s%d", seconds, (tics > 0) ? "+" : "", tics); + + P_WriteDuplicateText(text, target); +} + static void P_LoadSidedefs(UINT8 *data) { mapsidedef_t *msd = (mapsidedef_t*)data; @@ -1259,9 +1356,13 @@ static void P_LoadSidedefs(UINT8 *data) case 413: // Change music { + sd->toptexture = sd->midtexture = sd->bottomtexture = 0; + + if (!isfrontside) + break; + char process[8+1]; - sd->toptexture = sd->midtexture = sd->bottomtexture = 0; if (msd->bottomtexture[0] != '-' || msd->bottomtexture[1] != '\0') { M_Memcpy(process,msd->bottomtexture,8); @@ -1276,48 +1377,39 @@ static void P_LoadSidedefs(UINT8 *data) sd->midtexture = get_number(process); } - sd->text = Z_Malloc(7, PU_LEVEL, NULL); - if (isfrontside && !(msd->toptexture[0] == '-' && msd->toptexture[1] == '\0')) + if (msd->toptexture[0] != '-' && msd->toptexture[1] != '\0') { + sd->line->stringargs[0] = Z_Malloc(7, PU_LEVEL, NULL); + M_Memcpy(process,msd->toptexture,8); process[8] = '\0'; // If they type in O_ or D_ and their music name, just shrug, // then copy the rest instead. if ((process[0] == 'O' || process[0] == 'D') && process[7]) - M_Memcpy(sd->text, process+2, 6); + M_Memcpy(sd->line->stringargs[0], process+2, 6); else // Assume it's a proper music name. - M_Memcpy(sd->text, process, 6); - sd->text[6] = 0; + M_Memcpy(sd->line->stringargs[0], process, 6); + sd->line->stringargs[0][6] = '\0'; } - else - sd->text[0] = 0; + break; } case 4: // Speed pad parameters - { - sd->toptexture = sd->midtexture = sd->bottomtexture = 0; - if (msd->toptexture[0] != '-' || msd->toptexture[1] != '\0') - { - char process[8+1]; - M_Memcpy(process,msd->toptexture,8); - process[8] = '\0'; - sd->toptexture = get_number(process); - } - break; - } - case 414: // Play SFX { sd->toptexture = sd->midtexture = sd->bottomtexture = 0; + + if (!isfrontside) + break; + if (msd->toptexture[0] != '-' || msd->toptexture[1] != '\0') { char process[8 + 1]; M_Memcpy(process, msd->toptexture, 8); process[8] = '\0'; - sd->text = Z_Malloc(strlen(process) + 1, PU_LEVEL, NULL); - M_Memcpy(sd->text, process, strlen(process) + 1); + P_WriteDuplicateText(process, &sd->line->stringargs[0]); } break; } @@ -1326,21 +1418,13 @@ static void P_LoadSidedefs(UINT8 *data) case 14: // Bustable block parameters case 15: // Fan particle spawner parameters { - char process[8*3+1]; - memset(process,0,8*3+1); - sd->toptexture = sd->midtexture = sd->bottomtexture = 0; - if (msd->toptexture[0] == '-' && msd->toptexture[1] == '\0') + if (msd->toptexture[7] == '\0' && strcasecmp(msd->toptexture, "MT_NULL") == 0) + { + // Don't bulk the conversion with irrelevant types break; - else - M_Memcpy(process,msd->toptexture,8); - if (msd->midtexture[0] != '-' || msd->midtexture[1] != '\0') - M_Memcpy(process+strlen(process), msd->midtexture, 8); - if (msd->bottomtexture[0] != '-' || msd->bottomtexture[1] != '\0') - M_Memcpy(process+strlen(process), msd->bottomtexture, 8); - sd->toptexture = get_number(process); - break; + } } - + // FALLTHRU case 331: // Trigger linedef executor: Skin - Continuous case 332: // Trigger linedef executor: Skin - Each time case 333: // Trigger linedef executor: Skin - Once @@ -1366,8 +1450,11 @@ static void P_LoadSidedefs(UINT8 *data) M_Memcpy(process+strlen(process), msd->midtexture, 8); if (msd->bottomtexture[0] != '-' || msd->bottomtexture[1] != '\0') M_Memcpy(process+strlen(process), msd->bottomtexture, 8); - sd->text = Z_Malloc(strlen(process)+1, PU_LEVEL, NULL); - M_Memcpy(sd->text, process, strlen(process)+1); + + P_WriteDuplicateText( + process, + &sd->line->stringargs[(isfrontside) ? 0 : 1] + ); break; } @@ -2716,6 +2803,15 @@ static void P_WriteTextmap(void) Z_Free(wlines); Z_Free(wsides); Z_Free(specialthings); + + if (contextdrift) + { + CONS_Alert( + CONS_WARNING, M_GetText( + "Some elements of this level are vulnerable to context drift." + "Please check the console log for more information.\n") + ); + } } /** Loads the textmap data, after obtaining the elements count and allocating their respective space. @@ -2909,15 +3005,20 @@ static void P_ProcessLinedefsAfterSidedefs(void) case 332: // Trigger linedef executor: Skin - Each time case 333: // Trigger linedef executor: Skin - Once case 443: // Calls a named Lua function - if (sides[ld->sidenum[0]].text) + if (ld->stringargs[0] && ld->stringargs[1]) { - size_t len = strlen(sides[ld->sidenum[0]].text) + 1; - if (ld->sidenum[1] != 0xffff && sides[ld->sidenum[1]].text) - len += strlen(sides[ld->sidenum[1]].text); - ld->text = Z_Malloc(len, PU_LEVEL, NULL); - M_Memcpy(ld->text, sides[ld->sidenum[0]].text, strlen(sides[ld->sidenum[0]].text) + 1); - if (ld->sidenum[1] != 0xffff && sides[ld->sidenum[1]].text) - M_Memcpy(ld->text + strlen(ld->text) + 1, sides[ld->sidenum[1]].text, strlen(sides[ld->sidenum[1]].text) + 1); + size_t len[2]; + len[0] = strlen(ld->stringargs[0]); + len[1] = strlen(ld->stringargs[1]); + + if (len[1]) + { + ld->stringargs[0] = Z_Realloc(ld->stringargs[0], len[0] + len[1] + 1, PU_LEVEL, NULL); + M_Memcpy(ld->stringargs[0] + len[0] + 1, ld->stringargs[1], len[1] + 1); + } + + Z_Free(ld->stringargs[1]); + ld->stringargs[1] = NULL; } break; case 447: // Change colormap @@ -4033,14 +4134,6 @@ static void P_AddBinaryMapTags(void) } } -static void P_WriteConstant(INT32 constant, char **target) -{ - char buffer[12]; - sprintf(buffer, "%d", constant); - *target = Z_Malloc(strlen(buffer) + 1, PU_LEVEL, NULL); - M_Memcpy(*target, buffer, strlen(buffer) + 1); -} - static line_t *P_FindPointPushLine(taglist_t *list) { INT32 i, l; @@ -4183,7 +4276,6 @@ static void P_ConvertBinaryLinedefTypes(void) lines[i].args[1] |= TMSP_NOTELEPORT; if (lines[i].flags & ML_WRAPMIDTEX) lines[i].args[1] |= TMSP_FORCESPIN; - P_WriteConstant(sides[lines[i].sidenum[0]].toptexture ? sides[lines[i].sidenum[0]].toptexture : sfx_spdpad, &lines[i].stringargs[0]); break; case 7: //Sector flat alignment lines[i].args[0] = tag; @@ -4269,8 +4361,6 @@ static void P_ConvertBinaryLinedefTypes(void) lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; lines[i].args[1] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS; lines[i].args[2] = !!(lines[i].flags & ML_SKEWTD); - if (sides[lines[i].sidenum[0]].toptexture) - P_WriteConstant(sides[lines[i].sidenum[0]].toptexture, &lines[i].stringargs[0]); break; case 16: //Minecart parameters lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; @@ -4733,7 +4823,7 @@ static void P_ConvertBinaryLinedefTypes(void) lines[i].args[2] = 16; } if (lines[i].flags & ML_MIDSOLID) - P_WriteConstant(sides[lines[i].sidenum[0]].textureoffset >> FRACBITS, &lines[i].stringargs[0]); + P_WriteSfx(sides[lines[i].sidenum[0]].textureoffset >> FRACBITS, &lines[i].stringargs[0]); break; case 252: //FOF: Shatter block case 253: //FOF: Shatter block, translucent @@ -5000,11 +5090,6 @@ static void P_ConvertBinaryLinedefTypes(void) else lines[i].args[0] = TMT_CONTINUOUS; lines[i].args[1] = !!(lines[i].flags & ML_NOCLIMB); - if (lines[i].text) - { - lines[i].stringargs[0] = Z_Malloc(strlen(lines[i].text) + 1, PU_LEVEL, NULL); - M_Memcpy(lines[i].stringargs[0], lines[i].text, strlen(lines[i].text) + 1); - } lines[i].special = 331; break; case 334: // Object dye - continuous @@ -5017,11 +5102,6 @@ static void P_ConvertBinaryLinedefTypes(void) else lines[i].args[0] = TMT_CONTINUOUS; lines[i].args[1] = !!(lines[i].flags & ML_NOCLIMB); - if (sides[lines[i].sidenum[0]].text) - { - lines[i].stringargs[0] = Z_Malloc(strlen(sides[lines[i].sidenum[0]].text) + 1, PU_LEVEL, NULL); - M_Memcpy(lines[i].stringargs[0], sides[lines[i].sidenum[0]].text, strlen(sides[lines[i].sidenum[0]].text) + 1); - } lines[i].special = 334; break; case 337: //Emerald check - continuous @@ -5168,11 +5248,6 @@ static void P_ConvertBinaryLinedefTypes(void) lines[i].args[4] = (lines[i].sidenum[1] != 0xffff) ? sides[lines[i].sidenum[1]].textureoffset >> FRACBITS : 0; lines[i].args[5] = (lines[i].sidenum[1] != 0xffff) ? sides[lines[i].sidenum[1]].rowoffset >> FRACBITS : -1; lines[i].args[6] = sides[lines[i].sidenum[0]].bottomtexture; - if (sides[lines[i].sidenum[0]].text) - { - lines[i].stringargs[0] = Z_Malloc(strlen(sides[lines[i].sidenum[0]].text) + 1, PU_LEVEL, NULL); - M_Memcpy(lines[i].stringargs[0], sides[lines[i].sidenum[0]].text, strlen(sides[lines[i].sidenum[0]].text) + 1); - } break; case 414: //Play sound effect lines[i].args[2] = tag; @@ -5212,11 +5287,6 @@ static void P_ConvertBinaryLinedefTypes(void) lines[i].args[1] = TMSL_EVERYONE; } } - if (sides[lines[i].sidenum[0]].text) - { - lines[i].stringargs[0] = Z_Malloc(strlen(sides[lines[i].sidenum[0]].text) + 1, PU_LEVEL, NULL); - M_Memcpy(lines[i].stringargs[0], sides[lines[i].sidenum[0]].text, strlen(sides[lines[i].sidenum[0]].text) + 1); - } break; case 415: //Run script { @@ -5307,13 +5377,6 @@ static void P_ConvertBinaryLinedefTypes(void) lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; lines[i].args[1] = !!(lines[i].flags & ML_NOCLIMB); break; - case 425: //Change object state - if (sides[lines[i].sidenum[0]].text) - { - lines[i].stringargs[0] = Z_Malloc(strlen(sides[lines[i].sidenum[0]].text) + 1, PU_LEVEL, NULL); - M_Memcpy(lines[i].stringargs[0], sides[lines[i].sidenum[0]].text, strlen(sides[lines[i].sidenum[0]].text) + 1); - } - break; case 426: //Stop object lines[i].args[0] = !!(lines[i].flags & ML_NOCLIMB); break; @@ -5353,18 +5416,18 @@ static void P_ConvertBinaryLinedefTypes(void) lines[i].args[2] = !!(lines[i].flags & ML_BLOCKMONSTERS); break; case 434: //Award power-up - if (sides[lines[i].sidenum[0]].text) + if ((lines[i].flags & ML_BLOCKMONSTERS) == 0) { - lines[i].stringargs[0] = Z_Malloc(strlen(sides[lines[i].sidenum[0]].text) + 1, PU_LEVEL, NULL); - M_Memcpy(lines[i].stringargs[0], sides[lines[i].sidenum[0]].text, strlen(sides[lines[i].sidenum[0]].text) + 1); + // do NOT read power from back sidedef if this flag is not present + if (lines[i].stringargs[1] != NULL) + { + Z_Free(lines[i].stringargs[1]); + lines[i].stringargs[1] = NULL; + } + + // Instead... write the desired time! + P_WriteTics((lines[i].flags & ML_NOCLIMB) ? -1 : (sides[lines[i].sidenum[0]].textureoffset >> FRACBITS), &lines[i].stringargs[1]); } - if (lines[i].sidenum[1] != 0xffff && lines[i].flags & ML_BLOCKMONSTERS) // read power from back sidedef - { - lines[i].stringargs[1] = Z_Malloc(strlen(sides[lines[i].sidenum[1]].text) + 1, PU_LEVEL, NULL); - M_Memcpy(lines[i].stringargs[1], sides[lines[i].sidenum[1]].text, strlen(sides[lines[i].sidenum[1]].text) + 1); - } - else - P_WriteConstant((lines[i].flags & ML_NOCLIMB) ? -1 : (sides[lines[i].sidenum[0]].textureoffset >> FRACBITS), &lines[i].stringargs[1]); break; case 435: //Change plane scroller direction lines[i].args[0] = tag; @@ -5392,30 +5455,10 @@ static void P_ConvertBinaryLinedefTypes(void) break; case 442: //Change object type state lines[i].args[0] = tag; - if (sides[lines[i].sidenum[0]].text) - { - lines[i].stringargs[0] = Z_Malloc(strlen(sides[lines[i].sidenum[0]].text) + 1, PU_LEVEL, NULL); - M_Memcpy(lines[i].stringargs[0], sides[lines[i].sidenum[0]].text, strlen(sides[lines[i].sidenum[0]].text) + 1); - } - if (lines[i].sidenum[1] == 0xffff) - lines[i].args[1] = 1; - else - { - lines[i].args[1] = 0; - if (sides[lines[i].sidenum[1]].text) - { - lines[i].stringargs[1] = Z_Malloc(strlen(sides[lines[i].sidenum[1]].text) + 1, PU_LEVEL, NULL); - M_Memcpy(lines[i].stringargs[1], sides[lines[i].sidenum[1]].text, strlen(sides[lines[i].sidenum[1]].text) + 1); - } - } + lines[i].args[3] = (lines[i].sidenum[1] == 0xffff) ? 1 : 0; break; case 443: //Call Lua function - if (lines[i].text) - { - lines[i].stringargs[0] = Z_Malloc(strlen(lines[i].text) + 1, PU_LEVEL, NULL); - M_Memcpy(lines[i].stringargs[0], lines[i].text, strlen(lines[i].text) + 1); - } - else + if (lines[i].stringargs[0] == NULL) CONS_Alert(CONS_WARNING, "Linedef %s is missing the hook name of the Lua function to call! (This should be given in the front texture fields)\n", sizeu1(i)); break; case 444: //Earthquake @@ -5568,11 +5611,6 @@ static void P_ConvertBinaryLinedefTypes(void) if (lines[i].flags & ML_MIDSOLID) lines[i].args[2] |= TMP_FREEZETHINKERS;*/ lines[i].args[3] = (lines[i].sidenum[1] != 0xFFFF) ? sides[lines[i].sidenum[1]].textureoffset >> FRACBITS : tag; - if (sides[lines[i].sidenum[0]].text) - { - lines[i].stringargs[0] = Z_Malloc(strlen(sides[lines[i].sidenum[0]].text) + 1, PU_LEVEL, NULL); - M_Memcpy(lines[i].stringargs[0], sides[lines[i].sidenum[0]].text, strlen(sides[lines[i].sidenum[0]].text) + 1); - } break; case 460: //Award rings lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; @@ -5600,18 +5638,6 @@ static void P_ConvertBinaryLinedefTypes(void) } else lines[i].args[4] = 0; - if (sides[lines[i].sidenum[0]].text) - { - lines[i].stringargs[0] = Z_Malloc(strlen(sides[lines[i].sidenum[0]].text) + 1, PU_LEVEL, NULL); - M_Memcpy(lines[i].stringargs[0], sides[lines[i].sidenum[0]].text, strlen(sides[lines[i].sidenum[0]].text) + 1); - } - break; - case 463: //Dye object - if (sides[lines[i].sidenum[0]].text) - { - lines[i].stringargs[0] = Z_Malloc(strlen(sides[lines[i].sidenum[0]].text) + 1, PU_LEVEL, NULL); - M_Memcpy(lines[i].stringargs[0], sides[lines[i].sidenum[0]].text, strlen(sides[lines[i].sidenum[0]].text) + 1); - } break; case 464: //Trigger egg capsule lines[i].args[0] = tag; @@ -6440,7 +6466,7 @@ static void P_ConvertBinaryThingTypes(void) break; case 543: //Balloon if (mapthings[i].angle > 0) - P_WriteConstant(((mapthings[i].angle - 1) % (numskincolors - 1)) + 1, &mapthings[i].stringargs[0]); + P_WriteSkincolor(((mapthings[i].angle - 1) % (numskincolors - 1)) + 1, &mapthings[i].stringargs[0]); mapthings[i].args[0] = !!(mapthings[i].options & MTF_AMBUSH); break; case 555: //Diagonal yellow spring @@ -6465,22 +6491,22 @@ static void P_ConvertBinaryThingTypes(void) case 706: //Water ambience G case 707: //Water ambience H mapthings[i].args[0] = 35; - P_WriteConstant(sfx_amwtr1 + mapthings[i].type - 700, &mapthings[i].stringargs[0]); + P_WriteSfx(sfx_amwtr1 + mapthings[i].type - 700, &mapthings[i].stringargs[0]); mapthings[i].type = 700; break; case 708: //Disco ambience mapthings[i].args[0] = 512; - P_WriteConstant(sfx_ambint, &mapthings[i].stringargs[0]); + P_WriteSfx(sfx_ambint, &mapthings[i].stringargs[0]); mapthings[i].type = 700; break; case 709: //Volcano ambience mapthings[i].args[0] = 220; - P_WriteConstant(sfx_ambin2, &mapthings[i].stringargs[0]); + P_WriteSfx(sfx_ambin2, &mapthings[i].stringargs[0]); mapthings[i].type = 700; break; case 710: //Machine ambience mapthings[i].args[0] = 24; - P_WriteConstant(sfx_ambmac, &mapthings[i].stringargs[0]); + P_WriteSfx(sfx_ambmac, &mapthings[i].stringargs[0]); mapthings[i].type = 700; break; case 750: //Slope vertex @@ -6543,8 +6569,7 @@ static void P_ConvertBinaryThingTypes(void) mapthings[i].args[3] = sides[lines[j].sidenum[0]].rowoffset >> FRACBITS; mapthings[i].args[4] = lines[j].backsector ? sides[lines[j].sidenum[1]].textureoffset >> FRACBITS : 0; mapthings[i].args[6] = mapthings[i].angle; - if (sides[lines[j].sidenum[0]].toptexture) - P_WriteConstant(sides[lines[j].sidenum[0]].toptexture, &mapthings[i].stringargs[0]); + P_WriteDuplicateText(lines[j].stringargs[0], &mapthings[i].stringargs[0]); break; } case 762: //PolyObject spawn point (crush) @@ -6633,8 +6658,8 @@ static void P_ConvertBinaryThingTypes(void) mapthings[i].args[8] |= TMM_ALWAYSTHINK; if (mapthings[i].type == 1110) { - P_WriteConstant(sides[lines[j].sidenum[0]].toptexture, &mapthings[i].stringargs[0]); - P_WriteConstant(lines[j].backsector ? sides[lines[j].sidenum[1]].toptexture : MT_NULL, &mapthings[i].stringargs[1]); + P_WriteDuplicateText(lines[j].stringargs[0], &mapthings[i].stringargs[0]); + P_WriteDuplicateText(lines[j].stringargs[1], &mapthings[i].stringargs[1]); } break; } @@ -6675,7 +6700,13 @@ static void P_ConvertBinaryThingTypes(void) mapthings[i].args[0] = P_AproxDistance(lines[j].dx, lines[j].dy) >> FRACBITS; mapthings[i].args[1] = sides[lines[j].sidenum[0]].textureoffset >> FRACBITS; mapthings[i].args[2] = !!(lines[j].flags & ML_NOCLIMB); - P_WriteConstant(MT_ROCKCRUMBLE1 + (sides[lines[j].sidenum[0]].rowoffset >> FRACBITS), &mapthings[i].stringargs[0]); + INT32 id = (sides[lines[j].sidenum[0]].rowoffset >> FRACBITS); + // Rather than introduce deh_tables.h as a dependency for literally one + // conversion, we just... recreate the string expected to be produced. + if (id > 0 && id < 16) + P_WriteDuplicateText(va("MT_ROCKCRUMBLE%d", id+1), &mapthings[i].stringargs[0]); + else + P_WriteConstant(MT_ROCKCRUMBLE1 + id, &mapthings[i].stringargs[0], "Mapthing", i); break; } case 1221: //Minecart saloon door @@ -6808,6 +6839,7 @@ static void P_ConvertBinaryLinedefFlags(void) //For maps in binary format, converts setup of specials to UDMF format. static void P_ConvertBinaryMap(void) { + contextdrift = false; P_ConvertBinaryLinedefTypes(); P_ConvertBinarySectorTypes(); P_ConvertBinaryThingTypes(); diff --git a/src/r_defs.h b/src/r_defs.h index 963d655b1..2c98ec3f3 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -547,7 +547,6 @@ typedef struct line_s size_t validcount; // if == validcount, already checked polyobj_t *polyobj; // Belongs to a polyobject? - char *text; // a concatenation of all front and back texture names, for linedef specials that require a string. INT16 callcount; // no. of calls left before triggering, for the "X calls" linedef specials, defaults to 0 } line_t; @@ -576,8 +575,6 @@ typedef struct INT16 special; // the special of the linedef this side belongs to INT16 repeatcnt; // # of times to repeat midtexture - char *text; // a concatenation of all top, bottom, and mid texture names, for linedef specials that require a string. - extracolormap_t *colormap_data; // storage for colormaps; not applied to sectors. } side_t; From e914c19e8fe18339ff9688503eb5c3d5485b6f8d Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 21 Jul 2023 14:41:22 +0100 Subject: [PATCH 267/586] P_WriteSfx: Work around the weird case sensitivity in internal instances of get_number by always providing an uppercase prefix on conversion --- 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 27ddb0775..05c9572d5 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1283,7 +1283,7 @@ static void P_WriteSfx(INT32 constant, char **target) return; P_WriteDuplicateText( - va("sfx_%s", S_sfx[constant].name), + va("SFX_%s", S_sfx[constant].name), target ); } From 69089e0858170fecad52461cc663400aa3d881fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Sat, 22 Jul 2023 22:47:52 +0200 Subject: [PATCH 268/586] Fix build errors when building without SDL --- src/dummy/i_video.c | 2 ++ src/hardware/Sourcefile | 1 - src/hardware/hw_model.c | 2 +- src/{hardware => }/u_list.c | 2 +- src/{hardware => }/u_list.h | 0 5 files changed, 4 insertions(+), 3 deletions(-) rename src/{hardware => }/u_list.c (99%) rename src/{hardware => }/u_list.h (100%) diff --git a/src/dummy/i_video.c b/src/dummy/i_video.c index 3b0a12a32..bb796b676 100644 --- a/src/dummy/i_video.c +++ b/src/dummy/i_video.c @@ -57,6 +57,8 @@ const char *VID_GetModeName(INT32 modenum) return NULL; } +UINT32 I_GetRefreshRate(void) { return 35; } + void I_UpdateNoBlit(void){} void I_FinishUpdate(void){} diff --git a/src/hardware/Sourcefile b/src/hardware/Sourcefile index 1c05de76c..6c374621d 100644 --- a/src/hardware/Sourcefile +++ b/src/hardware/Sourcefile @@ -8,6 +8,5 @@ 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/hardware/hw_model.c b/src/hardware/hw_model.c index 4ed03744b..b69bce0e2 100644 --- a/src/hardware/hw_model.c +++ b/src/hardware/hw_model.c @@ -15,7 +15,7 @@ #include "hw_md2load.h" #include "hw_md3load.h" #include "hw_md2.h" -#include "u_list.h" +#include "../u_list.h" #include static float PI = (3.1415926535897932384626433832795f); diff --git a/src/hardware/u_list.c b/src/u_list.c similarity index 99% rename from src/hardware/u_list.c rename to src/u_list.c index dc49a74e7..d5cfd5717 100644 --- a/src/hardware/u_list.c +++ b/src/u_list.c @@ -8,7 +8,7 @@ */ #include "u_list.h" -#include "../z_zone.h" +#include "z_zone.h" // Utility for managing // structures in a linked diff --git a/src/hardware/u_list.h b/src/u_list.h similarity index 100% rename from src/hardware/u_list.h rename to src/u_list.h From d42d1e9a45ff9bc5ac4bdcefa1297f92c198e90b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Sat, 22 Jul 2023 22:56:17 +0200 Subject: [PATCH 269/586] fixup! Fix build errors when building without SDL --- src/Sourcefile | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Sourcefile b/src/Sourcefile index fb08c2171..7c5305000 100644 --- a/src/Sourcefile +++ b/src/Sourcefile @@ -83,6 +83,7 @@ i_tcp.c lzf.c vid_copy.s b_bot.c +u_list.c lua_script.c lua_baselib.c lua_mathlib.c From 4bc7b2da1172f9a0142555c5c6d2ea5bdc7303cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Sat, 22 Jul 2023 22:59:00 +0200 Subject: [PATCH 270/586] fixup! fixup! Fix build errors when building without SDL --- 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 b23aaa5a0..0f14a4965 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -49,7 +49,7 @@ #include "m_anigif.h" #include "md5.h" #include "m_perfstats.h" -#include "hardware/u_list.h" // TODO: this should be a standard utility class +#include "u_list.h" #ifdef NETGAME_DEVMODE #define CV_RESTRICT CV_NETVAR From 66f8908b03b68cc0d350b1556f49af3d6eb39ab6 Mon Sep 17 00:00:00 2001 From: SMS Alfredo <65426124+SMS-Alfredo@users.noreply.github.com> Date: Sat, 22 Jul 2023 20:44:22 -0500 Subject: [PATCH 271/586] Reset Camera only if a new camera is set / Fix Lua jank with setting awayviewmobj or awayviewtics solo --- src/lua_playerlib.c | 27 ++++++++++++++++++++------- src/p_spec.c | 8 ++++---- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 1c3b4f46c..4b4c9d30f 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -1278,17 +1278,30 @@ static int player_set(lua_State *L) mobj_t *mo = NULL; if (!lua_isnil(L, 3)) mo = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); - P_SetTarget(&plr->awayviewmobj, mo); - if (plr == &players[displayplayer]) - P_ResetCamera(plr, &camera); // reset p1 camera on p1 getting an awayviewmobj - else if (splitscreen && plr == &players[secondarydisplayplayer]) - P_ResetCamera(plr, &camera2); // reset p2 camera on p2 getting an awayviewmobj + if (plr->awayviewmobj != mo) { + P_SetTarget(&plr->awayviewmobj, mo); + if (plr->awayviewtics) { + if (!plr->awayviewmobj) + plr->awayviewtics = 0; // can't have a NULL awayviewmobj with awayviewtics! + if (plr == &players[displayplayer]) + P_ResetCamera(plr, &camera); // reset p1 camera on p1 getting an awayviewmobj + else if (splitscreen && plr == &players[secondarydisplayplayer]) + P_ResetCamera(plr, &camera2); // reset p2 camera on p2 getting an awayviewmobj + } + } break; } case player_awayviewtics: - plr->awayviewtics = (INT32)luaL_checkinteger(L, 3); - if (plr->awayviewtics && !plr->awayviewmobj) // awayviewtics must ALWAYS have an awayviewmobj set!! + INT32 tics = (INT32)luaL_checkinteger(L, 3); + if (tics && !plr->awayviewmobj) // awayviewtics must ALWAYS have an awayviewmobj set!! P_SetTarget(&plr->awayviewmobj, plr->mo); // but since the script might set awayviewmobj immediately AFTER setting awayviewtics, use player mobj as filler for now. + if ((tics && !plr->awayviewtics) || (!tics && plr->awayviewtics)) { + if (plr == &players[displayplayer]) + P_ResetCamera(plr, &camera); // reset p1 camera on p1 transitioning to/from zero awayviewtics + else if (splitscreen && plr == &players[secondarydisplayplayer]) + P_ResetCamera(plr, &camera2); // reset p2 camera on p2 transitioning to/from zero awayviewtics + } + plr->awayviewtics = tics; break; case player_awayviewaiming: plr->awayviewaiming = luaL_checkangle(L, 3); diff --git a/src/p_spec.c b/src/p_spec.c index 877b9c7bc..33253e521 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -2661,10 +2661,8 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) // This is not revoked until overwritten; awayviewtics is ignored if (titlemapinaction) titlemapcameraref = altview; - else - { + else if (!mo->player->awayviewtics || mo->player->awayviewmobj != altview) { P_SetTarget(&mo->player->awayviewmobj, altview); - mo->player->awayviewtics = line->args[1]; if (mo->player == &players[displayplayer]) P_ResetCamera(mo->player, &camera); // reset p1 camera on p1 getting an awayviewmobj @@ -2679,8 +2677,10 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) aim <<= 8; if (titlemapinaction) titlemapcameraref->cusval = (angle_t)aim; - else + else { mo->player->awayviewaiming = (angle_t)aim; + mo->player->awayviewtics = line->args[1]; + } } break; From 95cbee52c6b9293c03cb6c33007e73b2f1df7895 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Tue, 28 May 2019 17:21:22 -0400 Subject: [PATCH 272/586] Model tilts - Add modeltilt variable, for more manual control of the model tilting. By default this just copies standingslope, but doesn't get cleared in the air. - Shadows & trailing bananas now tilt to match the ground they are on. - Rocket Sneakers & afterimages now tilt to match the player's current orientation. --- src/hardware/hw_md2.c | 8 ++++---- src/p_map.c | 6 ++++++ src/p_mobj.c | 6 ++++++ src/p_mobj.h | 3 +++ src/p_saveg.c | 4 ++++ src/p_slopes.c | 6 ++++++ src/p_user.c | 4 ++++ 7 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 38e8e8fc4..16f25118f 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1647,11 +1647,11 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) #ifdef USE_FTRANSFORM_ANGLEZ // Slope rotation from Kart p.anglez = 0.0f; - if (spr->mobj->standingslope) + if (spr->mobj->modeltilt) { - fixed_t tempz = spr->mobj->standingslope->normal.z; - fixed_t tempy = spr->mobj->standingslope->normal.y; - fixed_t tempx = spr->mobj->standingslope->normal.x; + fixed_t tempz = spr->mobj->modeltilt->normal.z; + fixed_t tempy = spr->mobj->modeltilt->normal.y; + fixed_t tempx = spr->mobj->modeltilt->normal.x; fixed_t tempangle = AngleFixed(R_PointToAngle2(0, 0, FixedSqrt(FixedMul(tempy, tempy) + FixedMul(tempz, tempz)), tempx)); p.anglez = FIXED_TO_FLOAT(tempangle); tempangle = -AngleFixed(R_PointToAngle2(0, 0, tempz, tempy)); diff --git a/src/p_map.c b/src/p_map.c index 0021fe450..e486136ff 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -2928,6 +2928,9 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) if (thing->momz <= 0) { thing->standingslope = tmfloorslope; +#ifdef HWRENDER + thing->modeltilt = thing->standingslope; +#endif if (thing->momz == 0 && thing->player && !startingonground) P_PlayerHitFloor(thing->player, true); } @@ -2939,6 +2942,9 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) if (thing->momz >= 0) { thing->standingslope = tmceilingslope; +#ifdef HWRENDER + thing->modeltilt = thing->standingslope; +#endif if (thing->momz == 0 && thing->player && !startingonground) P_PlayerHitFloor(thing->player, true); } diff --git a/src/p_mobj.c b/src/p_mobj.c index a43afc9b1..cce79b496 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1985,6 +1985,9 @@ void P_XYMovement(mobj_t *mo) // Now compare the Zs of the different quantizations if (oldangle-newangle > ANG30 && oldangle-newangle < ANGLE_180) { // Allow for a bit of sticking - this value can be adjusted later mo->standingslope = oldslope; +#ifdef HWRENDER + mo->modeltilt = mo->standingslope; +#endif P_SlopeLaunch(mo); //CONS_Printf("launched off of slope - "); @@ -2557,6 +2560,9 @@ boolean P_ZMovement(mobj_t *mo) if (((mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope) && (mo->type != MT_STEAM)) { mo->standingslope = (mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope; +#ifdef HWRENDER + mo->modeltilt = mo->standingslope; +#endif P_ReverseQuantizeMomentumToSlope(&mom, mo->standingslope); } diff --git a/src/p_mobj.h b/src/p_mobj.h index f573e9020..a17b94b87 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -394,6 +394,9 @@ typedef struct mobj_s INT32 cvmem; struct pslope_s *standingslope; // The slope that the object is standing on (shouldn't need synced in savegames, right?) +#ifdef HWRENDER + struct pslope_s *modeltilt; // Slope used for model tilting. Also is not synched, this is totally visual. +#endif boolean resetinterp; // if true, some fields should not be interpolated (see R_InterpolateMobjState implementation) boolean colorized; // Whether the mobj uses the rainbow colormap diff --git a/src/p_saveg.c b/src/p_saveg.c index 40fd65638..65c9eff64 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -2996,7 +2996,11 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) if (diff2 & MD2_HPREV) mobj->hprev = (mobj_t *)(size_t)READUINT32(save_p); if (diff2 & MD2_SLOPE) + { mobj->standingslope = P_SlopeById(READUINT16(save_p)); +#ifdef HWRENDER + mobj->modeltilt = mobj->standingslope; +#endif if (diff2 & MD2_COLORIZED) mobj->colorized = READUINT8(save_p); if (diff2 & MD2_MIRRORED) diff --git a/src/p_slopes.c b/src/p_slopes.c index 1f07b8f37..023ee46b9 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -899,6 +899,9 @@ void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope) if (P_MobjFlip(thing)*(thing->momz) < 0) // falling, land on slope { thing->standingslope = slope; +#ifdef HWRENDER + thing->modeltilt = thing->standingslope; +#endif if (!thing->player || !(thing->player->pflags & PF_BOUNCING)) thing->momz = -P_MobjFlip(thing); } @@ -915,6 +918,9 @@ void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope) thing->momx = mom.x; thing->momy = mom.y; thing->standingslope = slope; +#ifdef HWRENDER + thing->modeltilt = thing->standingslope; +#endif if (!thing->player || !(thing->player->pflags & PF_BOUNCING)) thing->momz = -P_MobjFlip(thing); } diff --git a/src/p_user.c b/src/p_user.c index 1adf6bc3f..f8cbf8fdb 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1995,6 +1995,10 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj) ghost->fuse = ghost->info->damage; ghost->skin = mobj->skin; + ghost->standingslope = mobj->standingslope; +#ifdef HWRENDER + ghost->modeltilt = mobj->modeltilt; +#endif if (mobj->flags2 & MF2_OBJECTFLIP) ghost->flags |= MF2_OBJECTFLIP; From ae233b000ff7d859e0fcdf43cfc9df4d2ade904d Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Wed, 28 Oct 2020 18:36:26 -0400 Subject: [PATCH 273/586] Remove modeltilt, use roll & pitch instead Broken currently, about half of the slopes you can go into have the wrong tilt --- src/hardware/hw_defs.h | 7 +------ src/hardware/hw_md2.c | 20 ++++++++------------ src/hardware/r_opengl/r_opengl.c | 2 -- src/p_local.h | 1 + src/p_map.c | 10 ++++------ src/p_mobj.c | 28 ++++++++++++++++++++++------ src/p_mobj.h | 3 --- src/p_saveg.c | 4 ---- src/p_slopes.c | 9 +++------ src/p_user.c | 5 ++--- 10 files changed, 41 insertions(+), 48 deletions(-) diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index 227fdf92b..131d2caa3 100644 --- a/src/hardware/hw_defs.h +++ b/src/hardware/hw_defs.h @@ -94,8 +94,7 @@ typedef struct FVector //BP: transform order : scale(rotation_x(rotation_y(translation(v)))) // Kart features -//#define USE_FTRANSFORM_ANGLEZ -//#define USE_FTRANSFORM_MIRROR +#define USE_FTRANSFORM_MIRROR // Vanilla features #define USE_MODEL_NEXTFRAME @@ -103,11 +102,7 @@ typedef struct FVector typedef struct { FLOAT x,y,z; // position -#ifdef USE_FTRANSFORM_ANGLEZ FLOAT anglex,angley,anglez; // aimingangle / viewangle -#else - FLOAT anglex,angley; // aimingangle / viewangle -#endif FLOAT scalex,scaley,scalez; FLOAT fovxangle, fovyangle; UINT8 splitscreen; diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 16f25118f..cc7ef1e71 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1642,22 +1642,18 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) p.rollflip *= -1; } + p.anglez = 0.0f; p.anglex = 0.0f; -#ifdef USE_FTRANSFORM_ANGLEZ - // Slope rotation from Kart - p.anglez = 0.0f; - if (spr->mobj->modeltilt) + if (spr->mobj->pitch) { - fixed_t tempz = spr->mobj->modeltilt->normal.z; - fixed_t tempy = spr->mobj->modeltilt->normal.y; - fixed_t tempx = spr->mobj->modeltilt->normal.x; - fixed_t tempangle = AngleFixed(R_PointToAngle2(0, 0, FixedSqrt(FixedMul(tempy, tempy) + FixedMul(tempz, tempz)), tempx)); - p.anglez = FIXED_TO_FLOAT(tempangle); - tempangle = -AngleFixed(R_PointToAngle2(0, 0, tempz, tempy)); - p.anglex = FIXED_TO_FLOAT(tempangle); + p.anglez = FIXED_TO_FLOAT(-AngleFixed(spr->mobj->pitch)); + } + + if (spr->mobj->roll) + { + p.anglex = FIXED_TO_FLOAT(AngleFixed(spr->mobj->roll)); } -#endif // SRB2CBTODO: MD2 scaling support finalscale *= FIXED_TO_FLOAT(interp.scale); diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 2fc1df881..0ba32a27e 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -2815,9 +2815,7 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, float duration, float if (hflipped) scalez = -scalez; -#ifdef USE_FTRANSFORM_ANGLEZ pglRotatef(pos->anglez, 0.0f, 0.0f, -1.0f); // rotate by slope from Kart -#endif pglRotatef(pos->angley, 0.0f, -1.0f, 0.0f); pglRotatef(pos->anglex, 1.0f, 0.0f, 0.0f); diff --git a/src/p_local.h b/src/p_local.h index 3c84d6fe2..563e257d8 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -537,5 +537,6 @@ void P_Thrust(mobj_t *mo, angle_t angle, fixed_t move); void P_DoSuperTransformation(player_t *player, boolean giverings); void P_ExplodeMissile(mobj_t *mo); void P_CheckGravity(mobj_t *mo, boolean affect); +void P_SetPitchRollFromSlope(mobj_t *mo, pslope_t *slope); #endif // __P_LOCAL__ diff --git a/src/p_map.c b/src/p_map.c index e486136ff..4dffb8e10 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -2928,9 +2928,8 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) if (thing->momz <= 0) { thing->standingslope = tmfloorslope; -#ifdef HWRENDER - thing->modeltilt = thing->standingslope; -#endif + P_SetPitchRollFromSlope(thing, thing->standingslope); + if (thing->momz == 0 && thing->player && !startingonground) P_PlayerHitFloor(thing->player, true); } @@ -2942,9 +2941,8 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) if (thing->momz >= 0) { thing->standingslope = tmceilingslope; -#ifdef HWRENDER - thing->modeltilt = thing->standingslope; -#endif + P_SetPitchRollFromSlope(thing, thing->standingslope); + if (thing->momz == 0 && thing->player && !startingonground) P_PlayerHitFloor(thing->player, true); } diff --git a/src/p_mobj.c b/src/p_mobj.c index cce79b496..9c6df4cf5 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1551,6 +1551,26 @@ void P_CheckGravity(mobj_t *mo, boolean affect) } } +// +// P_SetPitchRollFromSlope +// +void P_SetPitchRollFromSlope(mobj_t *mo, pslope_t *slope) +{ + if (slope) + { + fixed_t tempz = slope->normal.z; + fixed_t tempy = slope->normal.y; + fixed_t tempx = slope->normal.x; + + mo->pitch = -R_PointToAngle2(0, 0, FixedSqrt(FixedMul(tempy, tempy) + FixedMul(tempz, tempz)), tempx); + mo->roll = -R_PointToAngle2(0, 0, tempz, tempy); + } + else + { + mo->pitch = mo->roll = 0; + } +} + #define STOPSPEED (FRACUNIT) // @@ -1985,9 +2005,7 @@ void P_XYMovement(mobj_t *mo) // Now compare the Zs of the different quantizations if (oldangle-newangle > ANG30 && oldangle-newangle < ANGLE_180) { // Allow for a bit of sticking - this value can be adjusted later mo->standingslope = oldslope; -#ifdef HWRENDER - mo->modeltilt = mo->standingslope; -#endif + P_SetPitchRollFromSlope(mo, mo->standingslope); P_SlopeLaunch(mo); //CONS_Printf("launched off of slope - "); @@ -2560,9 +2578,7 @@ boolean P_ZMovement(mobj_t *mo) if (((mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope) && (mo->type != MT_STEAM)) { mo->standingslope = (mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope; -#ifdef HWRENDER - mo->modeltilt = mo->standingslope; -#endif + P_SetPitchRollFromSlope(mo, mo->standingslope); P_ReverseQuantizeMomentumToSlope(&mom, mo->standingslope); } diff --git a/src/p_mobj.h b/src/p_mobj.h index a17b94b87..f573e9020 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -394,9 +394,6 @@ typedef struct mobj_s INT32 cvmem; struct pslope_s *standingslope; // The slope that the object is standing on (shouldn't need synced in savegames, right?) -#ifdef HWRENDER - struct pslope_s *modeltilt; // Slope used for model tilting. Also is not synched, this is totally visual. -#endif boolean resetinterp; // if true, some fields should not be interpolated (see R_InterpolateMobjState implementation) boolean colorized; // Whether the mobj uses the rainbow colormap diff --git a/src/p_saveg.c b/src/p_saveg.c index 65c9eff64..40fd65638 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -2996,11 +2996,7 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) if (diff2 & MD2_HPREV) mobj->hprev = (mobj_t *)(size_t)READUINT32(save_p); if (diff2 & MD2_SLOPE) - { mobj->standingslope = P_SlopeById(READUINT16(save_p)); -#ifdef HWRENDER - mobj->modeltilt = mobj->standingslope; -#endif if (diff2 & MD2_COLORIZED) mobj->colorized = READUINT8(save_p); if (diff2 & MD2_MIRRORED) diff --git a/src/p_slopes.c b/src/p_slopes.c index 023ee46b9..6aca116a5 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -899,9 +899,8 @@ void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope) if (P_MobjFlip(thing)*(thing->momz) < 0) // falling, land on slope { thing->standingslope = slope; -#ifdef HWRENDER - thing->modeltilt = thing->standingslope; -#endif + P_SetPitchRollFromSlope(thing, slope); + if (!thing->player || !(thing->player->pflags & PF_BOUNCING)) thing->momz = -P_MobjFlip(thing); } @@ -918,9 +917,7 @@ void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope) thing->momx = mom.x; thing->momy = mom.y; thing->standingslope = slope; -#ifdef HWRENDER - thing->modeltilt = thing->standingslope; -#endif + P_SetPitchRollFromSlope(thing, slope); if (!thing->player || !(thing->player->pflags & PF_BOUNCING)) thing->momz = -P_MobjFlip(thing); } diff --git a/src/p_user.c b/src/p_user.c index f8cbf8fdb..74b5b7175 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1976,6 +1976,8 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj) ghost->colorized = mobj->colorized; // alternatively, "true" for sonic advance style colourisation ghost->angle = (mobj->player ? mobj->player->drawangle : mobj->angle); + ghost->roll = mobj->roll; + ghost->pitch = mobj->pitch; ghost->rollangle = mobj->rollangle; ghost->sprite = mobj->sprite; @@ -1996,9 +1998,6 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj) ghost->fuse = ghost->info->damage; ghost->skin = mobj->skin; ghost->standingslope = mobj->standingslope; -#ifdef HWRENDER - ghost->modeltilt = mobj->modeltilt; -#endif if (mobj->flags2 & MF2_OBJECTFLIP) ghost->flags |= MF2_OBJECTFLIP; From 5c23fdda246f412b2342e80a298c02518336c8fd Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Wed, 28 Oct 2020 21:05:58 -0400 Subject: [PATCH 274/586] Fix incorrect tilts --- src/hardware/hw_md2.c | 14 ++------------ src/hardware/r_opengl/r_opengl.c | 4 ++-- src/p_mobj.c | 4 ++-- 3 files changed, 6 insertions(+), 16 deletions(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index cc7ef1e71..83a9146cd 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1642,18 +1642,8 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) p.rollflip *= -1; } - p.anglez = 0.0f; - p.anglex = 0.0f; - - if (spr->mobj->pitch) - { - p.anglez = FIXED_TO_FLOAT(-AngleFixed(spr->mobj->pitch)); - } - - if (spr->mobj->roll) - { - p.anglex = FIXED_TO_FLOAT(AngleFixed(spr->mobj->roll)); - } + p.anglez = FIXED_TO_FLOAT(AngleFixed(spr->mobj->pitch)); + p.anglex = FIXED_TO_FLOAT(AngleFixed(spr->mobj->roll)); // SRB2CBTODO: MD2 scaling support finalscale *= FIXED_TO_FLOAT(interp.scale); diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 0ba32a27e..f50479a71 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -2815,9 +2815,9 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, float duration, float if (hflipped) scalez = -scalez; - pglRotatef(pos->anglez, 0.0f, 0.0f, -1.0f); // rotate by slope from Kart - pglRotatef(pos->angley, 0.0f, -1.0f, 0.0f); + pglRotatef(pos->anglez, 0.0f, 0.0f, -1.0f); pglRotatef(pos->anglex, 1.0f, 0.0f, 0.0f); + pglRotatef(pos->angley, 0.0f, -1.0f, 0.0f); if (pos->roll) { diff --git a/src/p_mobj.c b/src/p_mobj.c index 9c6df4cf5..9b22647c8 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1562,8 +1562,8 @@ void P_SetPitchRollFromSlope(mobj_t *mo, pslope_t *slope) fixed_t tempy = slope->normal.y; fixed_t tempx = slope->normal.x; - mo->pitch = -R_PointToAngle2(0, 0, FixedSqrt(FixedMul(tempy, tempy) + FixedMul(tempz, tempz)), tempx); - mo->roll = -R_PointToAngle2(0, 0, tempz, tempy); + mo->pitch = R_PointToAngle2(0, 0, FixedSqrt(FixedMul(tempy, tempy) + FixedMul(tempz, tempz)), tempx); + mo->roll = R_PointToAngle2(0, 0, tempz, tempy); } else { From 7c2a2410426a5143b7879af0e19b5ab16f1e1d62 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 30 Oct 2020 02:15:49 -0400 Subject: [PATCH 275/586] Remove the need for setting rotation axis in spriteinfo for models Now it just does it like Software --- src/deh_soc.c | 2 +- src/hardware/hw_defs.h | 8 +------ src/hardware/hw_main.c | 14 +++++++---- src/hardware/hw_md2.c | 41 ++++++++++---------------------- src/hardware/r_opengl/r_opengl.c | 26 ++------------------ src/lua_infolib.c | 9 ++++--- src/lua_mobjlib.c | 16 ++++++++----- src/p_enemy.c | 8 +++---- src/p_inter.c | 2 +- src/p_mobj.c | 11 +++++++-- src/p_mobj.h | 4 ++-- src/p_saveg.c | 14 +++++------ src/p_user.c | 19 ++++++++------- src/r_fps.c | 19 +++++++++++++++ src/r_fps.h | 3 +++ src/r_picformats.c | 8 ------- src/r_picformats.h | 1 - src/r_splats.c | 2 +- src/r_things.c | 6 ++--- 19 files changed, 102 insertions(+), 111 deletions(-) diff --git a/src/deh_soc.c b/src/deh_soc.c index 8dd849daf..2193cd875 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -912,7 +912,7 @@ static void readspriteframe(MYFILE *f, spriteinfo_t *sprinfo, UINT8 frame) else if (fastcmp(word, "YPIVOT")) sprinfo->pivot[frame].y = value; else if (fastcmp(word, "ROTAXIS")) - sprinfo->pivot[frame].rotaxis = value; + deh_warning("SpriteInfo: ROTAXIS is deprecated and will be removed."); else { f->curpos = lastline; diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index 131d2caa3..74c4ed7d2 100644 --- a/src/hardware/hw_defs.h +++ b/src/hardware/hw_defs.h @@ -93,9 +93,6 @@ typedef struct FVector //Hurdler: Transform (coords + angles) //BP: transform order : scale(rotation_x(rotation_y(translation(v)))) -// Kart features -#define USE_FTRANSFORM_MIRROR - // Vanilla features #define USE_MODEL_NEXTFRAME @@ -108,13 +105,10 @@ typedef struct UINT8 splitscreen; boolean flip; // screenflip boolean roll; - SINT8 rollflip; FLOAT rollangle; // done to not override USE_FTRANSFORM_ANGLEZ - UINT8 rotaxis; FLOAT centerx, centery; -#ifdef USE_FTRANSFORM_MIRROR + FLOAT rollx, rollz; boolean mirror; // SRB2Kart: Encore Mode -#endif boolean shearing; // 14042019 float viewaiming; // 17052019 } FTransform; diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 4e1b7975e..bb2ce9001 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -4158,7 +4158,7 @@ static void HWR_DrawSprite(gl_vissprite_t *spr) angle = viewangle; if (!spr->rotated) - angle += spr->mobj->rollangle; + angle += spr->mobj->spriteroll; angle = -angle; angle += ANGLE_90; @@ -5245,17 +5245,17 @@ static void HWR_ProjectSprite(mobj_t *thing) spr_topoffset = spritecachedinfo[lumpoff].topoffset; #ifdef ROTSPRITE - if (thing->rollangle + if (interp.spriteroll && !(splat && !(thing->renderflags & RF_NOSPLATROLLANGLE))) { if (papersprite) { // a positive rollangle should should pitch papersprites upwards relative to their facing angle - rollangle = R_GetRollAngle(InvAngle(thing->rollangle)); + rollangle = R_GetRollAngle(InvAngle(interp.spriteroll)); } else { - rollangle = R_GetRollAngle(thing->rollangle); + rollangle = R_GetRollAngle(interp.spriteroll); } rotsprite = Patch_GetRotatedSprite(sprframe, (thing->frame & FF_FRAMEMASK), rot, flip, false, sprinfo, rollangle); @@ -5913,6 +5913,8 @@ static void HWR_DrawSkyBackground(player_t *player) fixed_t rol = AngleFixed(player->viewrollangle); dometransform.rollangle = FIXED_TO_FLOAT(rol); dometransform.roll = true; + dometransform.rollx = 1.0f; + dometransform.rollz = 0.0f; } dometransform.splitscreen = splitscreen; @@ -6191,6 +6193,8 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player) fixed_t rol = AngleFixed(player->viewrollangle); atransform.rollangle = FIXED_TO_FLOAT(rol); atransform.roll = true; + atransform.rollx = 1.0f; + atransform.rollz = 0.0f; } atransform.splitscreen = splitscreen; @@ -6405,6 +6409,8 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) fixed_t rol = AngleFixed(player->viewrollangle); atransform.rollangle = FIXED_TO_FLOAT(rol); atransform.roll = true; + atransform.rollx = 1.0f; + atransform.rollz = 0.0f; } atransform.splitscreen = splitscreen; diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 83a9146cd..baacc2490 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1346,8 +1346,6 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) const UINT8 hflip = (UINT8)(!(spr->mobj->mirrored) != !R_ThingHorizontallyFlipped(spr->mobj)); spritedef_t *sprdef; spriteframe_t *sprframe; - spriteinfo_t *sprinfo; - angle_t ang; INT32 mod; float finalscale; interpmobjstate_t interp; @@ -1388,12 +1386,10 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) { md2 = &md2_playermodels[(skin_t*)spr->mobj->skin-skins]; md2->skin = (skin_t*)spr->mobj->skin-skins; - sprinfo = &((skin_t *)spr->mobj->skin)->sprinfo[spr->mobj->sprite2]; } else { md2 = &md2_models[spr->mobj->sprite]; - sprinfo = &spriteinfo[spr->mobj->sprite]; } // texture loading before model init, so it knows if sprite graphics are used, which @@ -1615,43 +1611,32 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) } p.rollangle = 0.0f; - p.rollflip = 1; - p.rotaxis = 0; - if (spr->mobj->rollangle) + + if (interp.spriteroll) { - fixed_t anglef = AngleFixed(spr->mobj->rollangle); + fixed_t camAngleDiff = AngleFixed(viewangle) - FLOAT_TO_FIXED(p.angley); // dumb reconversion back, I know + fixed_t anglef = AngleFixed(interp.spriteroll); + p.rollangle = FIXED_TO_FLOAT(anglef); p.roll = true; // rotation pivot - p.centerx = FIXED_TO_FLOAT(spr->mobj->radius/2); - p.centery = FIXED_TO_FLOAT(spr->mobj->height/(flip ? -2 : 2)); + p.centerx = FIXED_TO_FLOAT(spr->mobj->radius / 2); + p.centery = FIXED_TO_FLOAT(spr->mobj->height / 2); - // rotation axis - if (sprinfo->available) - p.rotaxis = (UINT8)(sprinfo->pivot[(spr->mobj->frame & FF_FRAMEMASK)].rotaxis); - - // for NiGHTS specifically but should work everywhere else - ang = R_PointToAngle (interp.x, interp.y) - interp.angle; - if ((sprframe->rotate & SRF_RIGHT) && (ang < ANGLE_180)) // See from right - p.rollflip = 1; - else if ((sprframe->rotate & SRF_LEFT) && (ang >= ANGLE_180)) // See from left - p.rollflip = -1; - - if (flip) - p.rollflip *= -1; + // rotation axes relative to camera + p.rollx = FIXED_TO_FLOAT(FINECOSINE(FixedAngle(camAngleDiff) >> ANGLETOFINESHIFT)); + p.rollz = FIXED_TO_FLOAT(FINESINE(FixedAngle(camAngleDiff) >> ANGLETOFINESHIFT)); } - p.anglez = FIXED_TO_FLOAT(AngleFixed(spr->mobj->pitch)); - p.anglex = FIXED_TO_FLOAT(AngleFixed(spr->mobj->roll)); + p.anglez = FIXED_TO_FLOAT(AngleFixed(interp.pitch)); + p.anglex = FIXED_TO_FLOAT(AngleFixed(interp.roll)); // SRB2CBTODO: MD2 scaling support finalscale *= FIXED_TO_FLOAT(interp.scale); p.flip = atransform.flip; -#ifdef USE_FTRANSFORM_MIRROR - p.mirror = atransform.mirror; // from Kart -#endif + p.mirror = atransform.mirror; HWD.pfnSetShader(SHADER_MODEL); // model shader HWD.pfnDrawModel(md2->model, frame, durs, tics, nextFrame, &p, finalscale, flip, hflip, &Surf); diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index f50479a71..d785b3cbf 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -2782,7 +2782,6 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, float duration, float pglEnable(GL_CULL_FACE); pglEnable(GL_NORMALIZE); -#ifdef USE_FTRANSFORM_MIRROR // flipped is if the object is vertically flipped // hflipped is if the object is horizontally flipped // pos->flip is if the screen is flipped vertically @@ -2795,17 +2794,6 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, float duration, float else pglCullFace(GL_BACK); } -#else - // pos->flip is if the screen is flipped too - if (flipped ^ hflipped ^ pos->flip) // If one or three of these are active, but not two, invert the model's culling - { - pglCullFace(GL_FRONT); - } - else - { - pglCullFace(GL_BACK); - } -#endif pglPushMatrix(); // should be the same as glLoadIdentity //Hurdler: now it seems to work @@ -2821,14 +2809,8 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, float duration, float if (pos->roll) { - float roll = (1.0f * pos->rollflip); pglTranslatef(pos->centerx, pos->centery, 0); - if (pos->rotaxis == 2) // Z - pglRotatef(pos->rollangle, 0.0f, 0.0f, roll); - else if (pos->rotaxis == 1) // Y - pglRotatef(pos->rollangle, 0.0f, roll, 0.0f); - else // X - pglRotatef(pos->rollangle, roll, 0.0f, 0.0f); + pglRotatef(pos->rollangle, pos->rollx, 0.0f, pos->rollz); pglTranslatef(-pos->centerx, -pos->centery, 0); } @@ -3001,13 +2983,9 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform) if (stransform) { used_fov = stransform->fovxangle; -#ifdef USE_FTRANSFORM_MIRROR - // mirroring from Kart if (stransform->mirror) pglScalef(-stransform->scalex, stransform->scaley, -stransform->scalez); - else -#endif - if (stransform->flip) + else if (stransform->flip) pglScalef(stransform->scalex, -stransform->scaley, -stransform->scalez); else pglScalef(stransform->scalex, stransform->scaley, -stransform->scalez); diff --git a/src/lua_infolib.c b/src/lua_infolib.c index 578878b21..10baa3c67 100644 --- a/src/lua_infolib.c +++ b/src/lua_infolib.c @@ -319,7 +319,7 @@ static int PopPivotSubTable(spriteframepivot_t *pivot, lua_State *L, int stk, in else if (ikey == 2 || (key && fastcmp(key, "y"))) pivot[idx].y = (INT32)value; else if (ikey == 3 || (key && fastcmp(key, "rotaxis"))) - pivot[idx].rotaxis = (UINT8)value; + LUA_UsageWarning(L, "\"rotaxis\" is deprecated and will be removed.") else if (ikey == -1 && (key != NULL)) FIELDERROR("pivot key", va("invalid option %s", key)); okcool = 1; @@ -576,7 +576,10 @@ static int framepivot_get(lua_State *L) else if (fastcmp("y", field)) lua_pushinteger(L, framepivot->y); else if (fastcmp("rotaxis", field)) - lua_pushinteger(L, (UINT8)framepivot->rotaxis); + { + LUA_UsageWarning(L, "\"rotaxis\" is deprecated and will be removed."); + lua_pushinteger(L, 0); + } else return luaL_error(L, va("Field %s does not exist in spriteframepivot_t", field)); @@ -602,7 +605,7 @@ static int framepivot_set(lua_State *L) else if (fastcmp("y", field)) framepivot->y = luaL_checkinteger(L, 3); else if (fastcmp("rotaxis", field)) - framepivot->rotaxis = luaL_checkinteger(L, 3); + LUA_UsageWarning(L, "\"rotaxis\" is deprecated and will be removed.") else return luaL_error(L, va("Field %s does not exist in spriteframepivot_t", field)); diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index 09d244c91..404af016a 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -33,7 +33,8 @@ enum mobj_e { mobj_angle, mobj_pitch, mobj_roll, - mobj_rollangle, + mobj_spriteroll, + mobj_rollangle, // backwards compat mobj_sprite, mobj_frame, mobj_sprite2, @@ -110,7 +111,8 @@ static const char *const mobj_opt[] = { "angle", "pitch", "roll", - "rollangle", + "spriteroll", + "rollangle", // backwards compat "sprite", "frame", "sprite2", @@ -229,8 +231,9 @@ static int mobj_get(lua_State *L) case mobj_roll: lua_pushangle(L, mo->roll); break; - case mobj_rollangle: - lua_pushangle(L, mo->rollangle); + case mobj_spriteroll: + case mobj_rollangle: // backwards compat + lua_pushangle(L, mo->spriteroll); break; case mobj_sprite: lua_pushinteger(L, mo->sprite); @@ -518,8 +521,9 @@ static int mobj_set(lua_State *L) case mobj_roll: mo->roll = luaL_checkangle(L, 3); break; - case mobj_rollangle: - mo->rollangle = luaL_checkangle(L, 3); + case mobj_spriteroll: + case mobj_rollangle: // backwards compat + mo->spriteroll = luaL_checkangle(L, 3); break; case mobj_sprite: mo->sprite = luaL_checkinteger(L, 3); diff --git a/src/p_enemy.c b/src/p_enemy.c index d9b44e603..b40525b2d 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -8687,10 +8687,10 @@ void A_RollAngle(mobj_t *actor) // relative (default) if (!locvar2) - actor->rollangle += angle; + actor->spriteroll += angle; // absolute else - actor->rollangle = angle; + actor->spriteroll = angle; } // Function: A_ChangeRollAngleRelative @@ -8715,7 +8715,7 @@ void A_ChangeRollAngleRelative(mobj_t *actor) I_Error("A_ChangeRollAngleRelative: var1 is greater than var2"); #endif - actor->rollangle += FixedAngle(P_RandomRange(amin, amax)); + actor->spriteroll += FixedAngle(P_RandomRange(amin, amax)); } // Function: A_ChangeRollAngleAbsolute @@ -8740,7 +8740,7 @@ void A_ChangeRollAngleAbsolute(mobj_t *actor) I_Error("A_ChangeRollAngleAbsolute: var1 is greater than var2"); #endif - actor->rollangle = FixedAngle(P_RandomRange(amin, amax)); + actor->spriteroll = FixedAngle(P_RandomRange(amin, amax)); } // Function: A_PlaySound diff --git a/src/p_inter.c b/src/p_inter.c index 8c57beac8..4d22ba343 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -3117,7 +3117,7 @@ static void P_NiGHTSDamage(mobj_t *target, mobj_t *source) P_SetPlayerMobjState(target, S_PLAY_NIGHTS_STUN); S_StartSound(target, sfx_nghurt); - player->mo->rollangle = 0; + player->mo->spriteroll = 0; if (oldnightstime > 10*TICRATE && player->nightstime < 10*TICRATE) diff --git a/src/p_mobj.c b/src/p_mobj.c index 9b22647c8..9a889d516 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9868,9 +9868,9 @@ static boolean P_MobjRegularThink(mobj_t *mobj) break; case MT_MINUS: if (P_IsObjectOnGround(mobj)) - mobj->rollangle = 0; + mobj->spriteroll = 0; else - mobj->rollangle = R_PointToAngle2(0, 0, P_MobjFlip(mobj)*mobj->momz, (mobj->scale << 1) - min(abs(mobj->momz), mobj->scale << 1)); + mobj->spriteroll = R_PointToAngle2(0, 0, P_MobjFlip(mobj)*mobj->momz, (mobj->scale << 1) - min(abs(mobj->momz), mobj->scale << 1)); break; case MT_PUSH: P_PointPushThink(mobj); @@ -14167,6 +14167,13 @@ mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zo newmobj->old_angle = mobj->old_angle; } + newmobj->old_pitch2 = mobj->old_pitch2; + newmobj->old_pitch = mobj->old_pitch; + newmobj->old_roll2 = mobj->old_roll2; + newmobj->old_roll = mobj->old_roll; + newmobj->old_spriteroll2 = mobj->old_spriteroll2; + newmobj->old_spriteroll = mobj->old_spriteroll; + newmobj->old_scale2 = mobj->old_scale2; newmobj->old_scale = mobj->old_scale; newmobj->old_spritexscale = mobj->old_spritexscale; diff --git a/src/p_mobj.h b/src/p_mobj.h index f573e9020..6a5ab84c4 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -292,7 +292,7 @@ typedef struct mobj_s angle_t angle, pitch, roll; // orientation angle_t old_angle, old_pitch, old_roll; // orientation interpolation angle_t old_angle2, old_pitch2, old_roll2; - angle_t rollangle; + angle_t spriteroll, old_spriteroll, old_spriteroll2; spritenum_t sprite; // used to find patch_t and flip value UINT32 frame; // frame number, plus bits see p_pspr.h UINT8 sprite2; // player sprites @@ -429,7 +429,7 @@ typedef struct precipmobj_s angle_t angle, pitch, roll; // orientation angle_t old_angle, old_pitch, old_roll; // orientation interpolation angle_t old_angle2, old_pitch2, old_roll2; - angle_t rollangle; + angle_t spriteroll, old_spriteroll, old_spriteroll2; spritenum_t sprite; // used to find patch_t and flip value UINT32 frame; // frame number, plus bits see p_pspr.h UINT8 sprite2; // player sprites diff --git a/src/p_saveg.c b/src/p_saveg.c index 40fd65638..ce0b262a3 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1565,7 +1565,7 @@ typedef enum MD2_SLOPE = 1<<11, MD2_COLORIZED = 1<<12, MD2_MIRRORED = 1<<13, - MD2_ROLLANGLE = 1<<14, + MD2_SPRITEROLL = 1<<14, MD2_SHADOWSCALE = 1<<15, MD2_RENDERFLAGS = 1<<16, MD2_BLENDMODE = 1<<17, @@ -1783,8 +1783,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) diff2 |= MD2_COLORIZED; if (mobj->mirrored) diff2 |= MD2_MIRRORED; - if (mobj->rollangle) - diff2 |= MD2_ROLLANGLE; + if (mobj->spriteroll) + diff2 |= MD2_SPRITEROLL; if (mobj->shadowscale) diff2 |= MD2_SHADOWSCALE; if (mobj->renderflags) @@ -1951,8 +1951,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) WRITEUINT8(save_p, mobj->colorized); if (diff2 & MD2_MIRRORED) WRITEUINT8(save_p, mobj->mirrored); - if (diff2 & MD2_ROLLANGLE) - WRITEANGLE(save_p, mobj->rollangle); + if (diff2 & MD2_SPRITEROLL) + WRITEANGLE(save_p, mobj->spriteroll); if (diff2 & MD2_SHADOWSCALE) WRITEFIXED(save_p, mobj->shadowscale); if (diff2 & MD2_RENDERFLAGS) @@ -3001,8 +3001,8 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) mobj->colorized = READUINT8(save_p); if (diff2 & MD2_MIRRORED) mobj->mirrored = READUINT8(save_p); - if (diff2 & MD2_ROLLANGLE) - mobj->rollangle = READANGLE(save_p); + if (diff2 & MD2_SPRITEROLL) + mobj->spriteroll = READANGLE(save_p); if (diff2 & MD2_SHADOWSCALE) mobj->shadowscale = READFIXED(save_p); if (diff2 & MD2_RENDERFLAGS) diff --git a/src/p_user.c b/src/p_user.c index 74b5b7175..16952f775 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -676,7 +676,7 @@ static void P_DeNightserizePlayer(player_t *player) player->marebonuslap = 0; player->flyangle = 0; player->anotherflyangle = 0; - player->mo->rollangle = 0; + player->mo->spriteroll = 0; P_SetTarget(&player->mo->target, NULL); P_SetTarget(&player->axis1, P_SetTarget(&player->axis2, NULL)); @@ -802,7 +802,7 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) player->secondjump = 0; player->flyangle = 0; player->anotherflyangle = 0; - player->mo->rollangle = 0; + player->mo->spriteroll = 0; player->powers[pw_shield] = SH_NONE; player->powers[pw_super] = 0; @@ -1978,7 +1978,7 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj) ghost->angle = (mobj->player ? mobj->player->drawangle : mobj->angle); ghost->roll = mobj->roll; ghost->pitch = mobj->pitch; - ghost->rollangle = mobj->rollangle; + ghost->spriteroll = mobj->spriteroll; ghost->sprite = mobj->sprite; ghost->sprite2 = mobj->sprite2; @@ -2017,6 +2017,7 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj) ghost->old_angle = (mobj->player ? mobj->player->old_drawangle2 : mobj->old_angle2); ghost->old_pitch = mobj->old_pitch2; ghost->old_roll = mobj->old_roll2; + ghost->old_spriteroll = mobj->old_spriteroll2; return ghost; } @@ -6793,9 +6794,9 @@ static void P_DoNiGHTSCapsule(player_t *player) { if ((player->mo->state == &states[S_PLAY_NIGHTS_PULL]) && (player->mo->sprite2 == SPR2_NPUL)) - player->mo->rollangle -= ANG30; + player->mo->spriteroll -= ANG30; else - player->mo->rollangle = 0; + player->mo->spriteroll = 0; } if (G_IsSpecialStage(gamemap)) @@ -7248,7 +7249,7 @@ static void P_NiGHTSMovement(player_t *player) && player->mo->state <= &states[S_PLAY_NIGHTS_TRANS6]) { player->mo->momx = player->mo->momy = player->mo->momz = 0; - player->mo->rollangle = 0; + player->mo->spriteroll = 0; return; } @@ -7266,7 +7267,7 @@ static void P_NiGHTSMovement(player_t *player) { if (player->mo->state != &states[S_PLAY_NIGHTS_DRILL]) P_SetPlayerMobjState(player->mo, S_PLAY_NIGHTS_DRILL); - player->mo->rollangle = ANGLE_90; + player->mo->spriteroll = ANGLE_90; } else #endif @@ -7599,9 +7600,9 @@ static void P_NiGHTSMovement(player_t *player) P_SetPlayerMobjState(player->mo, flystate); if (player->charflags & SF_NONIGHTSROTATION) - player->mo->rollangle = 0; + player->mo->spriteroll = 0; else - player->mo->rollangle = rollangle; + player->mo->spriteroll = rollangle; P_SetPlayerAngle(player, player->mo->angle); diff --git a/src/r_fps.c b/src/r_fps.c index 6166f0408..e8f43f499 100644 --- a/src/r_fps.c +++ b/src/r_fps.c @@ -294,6 +294,9 @@ void R_InterpolateMobjState(mobj_t *mobj, fixed_t frac, interpmobjstate_t *out) out->scale = mobj->scale; out->subsector = mobj->subsector; out->angle = mobj->player ? mobj->player->drawangle : mobj->angle; + out->pitch = mobj->pitch; + out->roll = mobj->roll; + out->spriteroll = mobj->spriteroll; out->spritexscale = mobj->spritexscale; out->spriteyscale = mobj->spriteyscale; out->spritexoffset = mobj->spritexoffset; @@ -323,6 +326,10 @@ void R_InterpolateMobjState(mobj_t *mobj, fixed_t frac, interpmobjstate_t *out) { out->angle = mobj->resetinterp ? mobj->angle : R_LerpAngle(mobj->old_angle, mobj->angle, frac); } + + out->pitch = mobj->resetinterp ? mobj->pitch : R_LerpAngle(mobj->old_pitch, mobj->pitch, frac); + out->roll = mobj->resetinterp ? mobj->roll : R_LerpAngle(mobj->old_roll, mobj->roll, frac); + out->spriteroll = mobj->resetinterp ? mobj->spriteroll : R_LerpAngle(mobj->old_spriteroll, mobj->spriteroll, frac); } void R_InterpolatePrecipMobjState(precipmobj_t *mobj, fixed_t frac, interpmobjstate_t *out) @@ -335,6 +342,9 @@ void R_InterpolatePrecipMobjState(precipmobj_t *mobj, fixed_t frac, interpmobjst out->scale = FRACUNIT; out->subsector = mobj->subsector; out->angle = mobj->angle; + out->pitch = mobj->angle; + out->roll = mobj->roll; + out->spriteroll = mobj->spriteroll; out->spritexscale = mobj->spritexscale; out->spriteyscale = mobj->spriteyscale; out->spritexoffset = mobj->spritexoffset; @@ -354,6 +364,9 @@ void R_InterpolatePrecipMobjState(precipmobj_t *mobj, fixed_t frac, interpmobjst out->subsector = R_PointInSubsector(out->x, out->y); out->angle = R_LerpAngle(mobj->old_angle, mobj->angle, frac); + out->pitch = R_LerpAngle(mobj->old_pitch, mobj->pitch, frac); + out->roll = R_LerpAngle(mobj->old_roll, mobj->roll, frac); + out->spriteroll = R_LerpAngle(mobj->old_spriteroll, mobj->spriteroll, frac); } static void AddInterpolator(levelinterpolator_t* interpolator) @@ -766,6 +779,7 @@ void R_ResetMobjInterpolationState(mobj_t *mobj) mobj->old_angle2 = mobj->old_angle; mobj->old_pitch2 = mobj->old_pitch; mobj->old_roll2 = mobj->old_roll; + mobj->old_spriteroll2 = mobj->old_spriteroll; mobj->old_scale2 = mobj->old_scale; mobj->old_x = mobj->x; mobj->old_y = mobj->y; @@ -773,6 +787,7 @@ void R_ResetMobjInterpolationState(mobj_t *mobj) mobj->old_angle = mobj->angle; mobj->old_pitch = mobj->pitch; mobj->old_roll = mobj->roll; + mobj->old_spriteroll = mobj->spriteroll; mobj->old_scale = mobj->scale; mobj->old_spritexscale = mobj->spritexscale; mobj->old_spriteyscale = mobj->spriteyscale; @@ -801,10 +816,14 @@ void R_ResetPrecipitationMobjInterpolationState(precipmobj_t *mobj) mobj->old_angle2 = mobj->old_angle; mobj->old_pitch2 = mobj->old_pitch; mobj->old_roll2 = mobj->old_roll; + mobj->old_spriteroll2 = mobj->old_spriteroll; mobj->old_x = mobj->x; mobj->old_y = mobj->y; mobj->old_z = mobj->z; mobj->old_angle = mobj->angle; + mobj->old_pitch = mobj->pitch; + mobj->old_roll = mobj->roll; + mobj->old_spriteroll = mobj->spriteroll; mobj->old_spritexscale = mobj->spritexscale; mobj->old_spriteyscale = mobj->spriteyscale; mobj->old_spritexoffset = mobj->spritexoffset; diff --git a/src/r_fps.h b/src/r_fps.h index 85c87a2f4..9a8bfa38a 100644 --- a/src/r_fps.h +++ b/src/r_fps.h @@ -59,6 +59,9 @@ typedef struct { fixed_t z; subsector_t *subsector; angle_t angle; + angle_t pitch; + angle_t roll; + angle_t spriteroll; fixed_t scale; fixed_t spritexscale; fixed_t spriteyscale; diff --git a/src/r_picformats.c b/src/r_picformats.c index 9aea8c6c1..3e817f4a0 100644 --- a/src/r_picformats.c +++ b/src/r_picformats.c @@ -1407,7 +1407,6 @@ static void R_ParseSpriteInfoFrame(spriteinfo_t *info) UINT8 frameFrame = 0xFF; INT16 frameXPivot = 0; INT16 frameYPivot = 0; - rotaxis_t frameRotAxis = 0; // Sprite identifier sprinfoToken = M_GetToken(NULL); @@ -1458,12 +1457,6 @@ static void R_ParseSpriteInfoFrame(spriteinfo_t *info) { Z_Free(sprinfoToken); sprinfoToken = M_GetToken(NULL); - if ((stricmp(sprinfoToken, "X")==0) || (stricmp(sprinfoToken, "XAXIS")==0) || (stricmp(sprinfoToken, "ROLL")==0)) - frameRotAxis = ROTAXIS_X; - else if ((stricmp(sprinfoToken, "Y")==0) || (stricmp(sprinfoToken, "YAXIS")==0) || (stricmp(sprinfoToken, "PITCH")==0)) - frameRotAxis = ROTAXIS_Y; - else if ((stricmp(sprinfoToken, "Z")==0) || (stricmp(sprinfoToken, "ZAXIS")==0) || (stricmp(sprinfoToken, "YAW")==0)) - frameRotAxis = ROTAXIS_Z; } Z_Free(sprinfoToken); @@ -1480,7 +1473,6 @@ static void R_ParseSpriteInfoFrame(spriteinfo_t *info) // set fields info->pivot[frameFrame].x = frameXPivot; info->pivot[frameFrame].y = frameYPivot; - info->pivot[frameFrame].rotaxis = frameRotAxis; } // diff --git a/src/r_picformats.h b/src/r_picformats.h index 4f9637460..4050a1b71 100644 --- a/src/r_picformats.h +++ b/src/r_picformats.h @@ -95,7 +95,6 @@ typedef enum typedef struct { INT32 x, y; - rotaxis_t rotaxis; } spriteframepivot_t; typedef struct diff --git a/src/r_splats.c b/src/r_splats.c index 72bfe74b3..d182d628b 100644 --- a/src/r_splats.c +++ b/src/r_splats.c @@ -191,7 +191,7 @@ void R_DrawFloorSplat(vissprite_t *spr) splatangle = spr->viewpoint.angle; if (!(spr->cut & SC_ISROTATED)) - splatangle += mobj->rollangle; + splatangle += mobj->spriteroll; splat.angle = -splatangle; splat.angle += ANGLE_90; diff --git a/src/r_things.c b/src/r_things.c index 19b8ee83d..eab8d13c2 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1743,17 +1743,17 @@ static void R_ProjectSprite(mobj_t *thing) patch = W_CachePatchNum(sprframe->lumppat[rot], PU_SPRITE); #ifdef ROTSPRITE - if (thing->rollangle + if (interp.spriteroll && !(splat && !(thing->renderflags & RF_NOSPLATROLLANGLE))) { if (papersprite && ang >= ANGLE_180) { // Makes Software act much more sane like OpenGL - rollangle = R_GetRollAngle(InvAngle(thing->rollangle)); + rollangle = R_GetRollAngle(InvAngle(interp.spriteroll)); } else { - rollangle = R_GetRollAngle(thing->rollangle); + rollangle = R_GetRollAngle(interp.spriteroll); } rotsprite = Patch_GetRotatedSprite(sprframe, (thing->frame & FF_FRAMEMASK), rot, flip, false, sprinfo, rollangle); From b6129a6d42babaec67319e523db12af9d9e7b4a2 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 30 Oct 2020 15:54:58 -0400 Subject: [PATCH 276/586] Add R_SpriteRotationAngle function Gets the rotation angle for the mobj's sprite. Meant for pitch & roll later, but that part is if'd out currently and just returns mobj->rollangle --- src/hardware/hw_main.c | 10 +++++++--- src/r_patch.h | 2 ++ src/r_patchrotation.c | 18 ++++++++++++++++++ src/r_things.c | 9 ++++++--- 4 files changed, 33 insertions(+), 6 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index bb2ce9001..8c1bc09e0 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5078,6 +5078,7 @@ static void HWR_ProjectSprite(mobj_t *thing) #ifdef ROTSPRITE patch_t *rotsprite = NULL; INT32 rollangle = 0; + angle_t spriterotangle = 0; #endif // uncapped/interpolation @@ -5245,18 +5246,21 @@ static void HWR_ProjectSprite(mobj_t *thing) spr_topoffset = spritecachedinfo[lumpoff].topoffset; #ifdef ROTSPRITE - if (interp.spriteroll + spriterotangle = R_SpriteRotationAngle(&interp); + + if (spriterotangle != 0 && !(splat && !(thing->renderflags & RF_NOSPLATROLLANGLE))) { if (papersprite) { // a positive rollangle should should pitch papersprites upwards relative to their facing angle - rollangle = R_GetRollAngle(InvAngle(interp.spriteroll)); + rollangle = R_GetRollAngle(InvAngle(spriterotangle)); } else { - rollangle = R_GetRollAngle(interp.spriteroll); + rollangle = R_GetRollAngle(spriterotangle); } + rotsprite = Patch_GetRotatedSprite(sprframe, (thing->frame & FF_FRAMEMASK), rot, flip, false, sprinfo, rollangle); if (rotsprite != NULL) diff --git a/src/r_patch.h b/src/r_patch.h index d2106a390..27f7bddb6 100644 --- a/src/r_patch.h +++ b/src/r_patch.h @@ -14,6 +14,7 @@ #include "r_defs.h" #include "r_picformats.h" +#include "r_fps.h" #include "doomdef.h" // Patch functions @@ -38,6 +39,7 @@ patch_t *Patch_GetRotatedSprite( size_t frame, size_t spriteangle, boolean flip, boolean adjustfeet, void *info, INT32 rotationangle); +angle_t R_SpriteRotationAngle(interpmobjstate_t *interp); INT32 R_GetRollAngle(angle_t rollangle); #endif diff --git a/src/r_patchrotation.c b/src/r_patchrotation.c index 3d3c6c512..f9c4ec797 100644 --- a/src/r_patchrotation.c +++ b/src/r_patchrotation.c @@ -13,11 +13,29 @@ #include "r_things.h" // FEETADJUST #include "z_zone.h" #include "w_wad.h" +#include "r_main.h" // R_PointToAngle #ifdef ROTSPRITE fixed_t rollcosang[ROTANGLES]; fixed_t rollsinang[ROTANGLES]; +// +// R_SpriteRotationAngle +// +// Gets the rollangle for the input object. +// +angle_t R_SpriteRotationAngle(interpmobjstate_t *interp) +{ + angle_t viewingAngle = R_PointToAngle(interp->x, interp->y); + + fixed_t pitchMul = -FINESINE(viewingAngle >> ANGLETOFINESHIFT); + fixed_t rollMul = FINECOSINE(viewingAngle >> ANGLETOFINESHIFT); + + angle_t rollOrPitch = FixedMul(interp->pitch, pitchMul) + FixedMul(interp->roll, rollMul); + + return (rollOrPitch + interp->spriteroll); +} + INT32 R_GetRollAngle(angle_t rollangle) { INT32 ra = AngleFixed(rollangle)>>FRACBITS; diff --git a/src/r_things.c b/src/r_things.c index eab8d13c2..248357e11 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1594,6 +1594,7 @@ static void R_ProjectSprite(mobj_t *thing) #ifdef ROTSPRITE patch_t *rotsprite = NULL; INT32 rollangle = 0; + angle_t spriterotangle = 0; #endif // uncapped/interpolation @@ -1743,17 +1744,19 @@ static void R_ProjectSprite(mobj_t *thing) patch = W_CachePatchNum(sprframe->lumppat[rot], PU_SPRITE); #ifdef ROTSPRITE - if (interp.spriteroll + spriterotangle = R_SpriteRotationAngle(&interp); + + if (spriterotangle != 0 && !(splat && !(thing->renderflags & RF_NOSPLATROLLANGLE))) { if (papersprite && ang >= ANGLE_180) { // Makes Software act much more sane like OpenGL - rollangle = R_GetRollAngle(InvAngle(interp.spriteroll)); + rollangle = R_GetRollAngle(InvAngle(spriterotangle)); } else { - rollangle = R_GetRollAngle(interp.spriteroll); + rollangle = R_GetRollAngle(spriterotangle); } rotsprite = Patch_GetRotatedSprite(sprframe, (thing->frame & FF_FRAMEMASK), rot, flip, false, sprinfo, rollangle); From 7db09b657b2735ea7b5655a6aa8df52f30dc913e Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 9 Dec 2021 22:13:56 -0800 Subject: [PATCH 277/586] Tilt models --- src/hardware/hw_md2.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index baacc2490..a20d80848 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1610,23 +1610,26 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) p.angley = FIXED_TO_FLOAT(anglef); } - p.rollangle = 0.0f; - - if (interp.spriteroll) { - fixed_t camAngleDiff = AngleFixed(viewangle) - FLOAT_TO_FIXED(p.angley); // dumb reconversion back, I know - fixed_t anglef = AngleFixed(interp.spriteroll); + fixed_t anglef = AngleFixed(R_SpriteRotationAngle(&interp)); - p.rollangle = FIXED_TO_FLOAT(anglef); - p.roll = true; + p.rollangle = 0.0f; - // rotation pivot - p.centerx = FIXED_TO_FLOAT(spr->mobj->radius / 2); - p.centery = FIXED_TO_FLOAT(spr->mobj->height / 2); + if (anglef) + { + fixed_t camAngleDiff = AngleFixed(viewangle) - FLOAT_TO_FIXED(p.angley); // dumb reconversion back, I know - // rotation axes relative to camera - p.rollx = FIXED_TO_FLOAT(FINECOSINE(FixedAngle(camAngleDiff) >> ANGLETOFINESHIFT)); - p.rollz = FIXED_TO_FLOAT(FINESINE(FixedAngle(camAngleDiff) >> ANGLETOFINESHIFT)); + p.rollangle = FIXED_TO_FLOAT(anglef); + p.roll = true; + + // rotation pivot + p.centerx = FIXED_TO_FLOAT(spr->mobj->radius / 2); + p.centery = FIXED_TO_FLOAT(spr->mobj->height / 2); + + // rotation axes relative to camera + p.rollx = FIXED_TO_FLOAT(FINECOSINE(FixedAngle(camAngleDiff) >> ANGLETOFINESHIFT)); + p.rollz = FIXED_TO_FLOAT(FINESINE(FixedAngle(camAngleDiff) >> ANGLETOFINESHIFT)); + } } p.anglez = FIXED_TO_FLOAT(AngleFixed(interp.pitch)); From c065029b01d6e3bfea4542b5f3443ad3115422fc Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 9 Dec 2021 22:41:35 -0800 Subject: [PATCH 278/586] Model stretching --- src/hardware/hw_drv.h | 3 +-- src/hardware/hw_md2.c | 6 +++++- src/hardware/r_opengl/r_opengl.c | 15 ++++++++------- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h index 426d2f283..1c4cd99ab 100644 --- a/src/hardware/hw_drv.h +++ b/src/hardware/hw_drv.h @@ -51,7 +51,7 @@ EXPORT void HWRAPI(ClearMipMapCache) (void); EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value); //Hurdler: added for new development -EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, float duration, float tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface); +EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, float duration, float tics, INT32 nextFrameIndex, FTransform *pos, float hscale, float vscale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface); EXPORT void HWRAPI(CreateModelVBOs) (model_t *model); EXPORT void HWRAPI(SetTransform) (FTransform *ptransform); EXPORT INT32 HWRAPI(GetTextureUsed) (void); @@ -136,4 +136,3 @@ extern struct hwdriver_s hwdriver; #endif //not defined _CREATE_DLL_ #endif //__HWR_DRV_H__ - diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index a20d80848..0f9195a75 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1642,7 +1642,11 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) p.mirror = atransform.mirror; HWD.pfnSetShader(SHADER_MODEL); // model shader - HWD.pfnDrawModel(md2->model, frame, durs, tics, nextFrame, &p, finalscale, flip, hflip, &Surf); + { + float xs = finalscale * FIXED_TO_FLOAT(spr->mobj->spritexscale); + float ys = finalscale * FIXED_TO_FLOAT(spr->mobj->spriteyscale); + HWD.pfnDrawModel(md2->model, frame, durs, tics, nextFrame, &p, xs, ys, flip, hflip, &Surf); + } } return true; diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index d785b3cbf..71cb5ca70 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -2679,7 +2679,7 @@ EXPORT void HWRAPI(CreateModelVBOs) (model_t *model) #define BUFFER_OFFSET(i) ((void*)(i)) -static void DrawModelEx(model_t *model, INT32 frameIndex, float duration, float tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface) +static void DrawModelEx(model_t *model, INT32 frameIndex, float duration, float tics, INT32 nextFrameIndex, FTransform *pos, float hscale, float vscale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface) { static GLRGBAFloat poly = {0,0,0,0}; static GLRGBAFloat tint = {0,0,0,0}; @@ -2703,10 +2703,11 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, float duration, float #endif // Affect input model scaling - scale *= 0.5f; - scalex = scale; - scaley = scale; - scalez = scale; + hscale *= 0.5f; + vscale *= 0.5f; + scalex = hscale; + scaley = vscale; + scalez = hscale; if (duration > 0.0 && tics >= 0.0) // don't interpolate if instantaneous or infinite in length { @@ -2964,9 +2965,9 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, float duration, float // -----------------+ // HWRAPI DrawModel : Draw a model // -----------------+ -EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, float duration, float tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface) +EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, float duration, float tics, INT32 nextFrameIndex, FTransform *pos, float hscale, float vscale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface) { - DrawModelEx(model, frameIndex, duration, tics, nextFrameIndex, pos, scale, flipped, hflipped, Surface); + DrawModelEx(model, frameIndex, duration, tics, nextFrameIndex, pos, hscale, vscale, flipped, hflipped, Surface); } // -----------------+ From 6d9512d2905ff2ad5defd06de60e044ae5a79932 Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 10 Dec 2021 00:32:46 -0800 Subject: [PATCH 279/586] Do not factor roll and pitch into model rollangle Those transformations are applied separately so the model tilts in 3d space. --- src/hardware/hw_md2.c | 2 +- src/r_patch.h | 1 + src/r_patchrotation.c | 12 ++++++------ 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 0f9195a75..096d24f52 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1611,7 +1611,7 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) } { - fixed_t anglef = AngleFixed(R_SpriteRotationAngle(&interp)); + fixed_t anglef = AngleFixed(R_ModelRotationAngle(&interp)); p.rollangle = 0.0f; diff --git a/src/r_patch.h b/src/r_patch.h index 27f7bddb6..a0ab3e75a 100644 --- a/src/r_patch.h +++ b/src/r_patch.h @@ -39,6 +39,7 @@ patch_t *Patch_GetRotatedSprite( size_t frame, size_t spriteangle, boolean flip, boolean adjustfeet, void *info, INT32 rotationangle); +angle_t R_ModelRotationAngle(interpmobjstate_t *interp); angle_t R_SpriteRotationAngle(interpmobjstate_t *interp); INT32 R_GetRollAngle(angle_t rollangle); #endif diff --git a/src/r_patchrotation.c b/src/r_patchrotation.c index f9c4ec797..a17b725d6 100644 --- a/src/r_patchrotation.c +++ b/src/r_patchrotation.c @@ -19,11 +19,11 @@ fixed_t rollcosang[ROTANGLES]; fixed_t rollsinang[ROTANGLES]; -// -// R_SpriteRotationAngle -// -// Gets the rollangle for the input object. -// +angle_t R_ModelRotationAngle(interpmobjstate_t *interp) +{ + return interp->spriteroll; +} + angle_t R_SpriteRotationAngle(interpmobjstate_t *interp) { angle_t viewingAngle = R_PointToAngle(interp->x, interp->y); @@ -33,7 +33,7 @@ angle_t R_SpriteRotationAngle(interpmobjstate_t *interp) angle_t rollOrPitch = FixedMul(interp->pitch, pitchMul) + FixedMul(interp->roll, rollMul); - return (rollOrPitch + interp->spriteroll); + return (rollOrPitch + R_ModelRotationAngle(interp)); } INT32 R_GetRollAngle(angle_t rollangle) From a71a7f271036487eb608ef7196c0fe3b3575d321 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 25 Oct 2022 02:36:35 -0700 Subject: [PATCH 280/586] Support spritexoffset/spriteyoffset for 3D models --- src/hardware/hw_main.c | 2 +- src/hardware/hw_main.h | 1 + src/hardware/hw_md2.c | 22 ++++++++++++++-------- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 8c1bc09e0..cb519877c 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -140,7 +140,7 @@ static fixed_t dup_viewx, dup_viewy, dup_viewz; static angle_t dup_viewangle; static float gl_viewx, gl_viewy, gl_viewz; -static float gl_viewsin, gl_viewcos; +float gl_viewsin, gl_viewcos; // Maybe not necessary with the new T&L code (needs to be checked!) static float gl_viewludsin, gl_viewludcos; // look up down kik test diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index 4a1b412fc..9450ca2c5 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -115,6 +115,7 @@ extern float gl_viewwindowx, gl_basewindowcentery; // BP: big hack for a test in lighting ref : 1249753487AB extern fixed_t *hwbbox; extern FTransform atransform; +extern float gl_viewsin, gl_viewcos; // Render stats diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 096d24f52..f0108969f 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1347,7 +1347,6 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) spritedef_t *sprdef; spriteframe_t *sprframe; INT32 mod; - float finalscale; interpmobjstate_t interp; if (R_UsingFrameInterpolation() && !paused) @@ -1451,7 +1450,6 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) } //HWD.pfnSetBlend(blend); // This seems to actually break translucency? - finalscale = md2->scale; //Hurdler: arf, I don't like that implementation at all... too much crappy if (gpatch && hwrPatch && hwrPatch->mipmap->format) // else if meant that if a texture couldn't be loaded, it would just end up using something else's texture @@ -1635,17 +1633,25 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) p.anglez = FIXED_TO_FLOAT(AngleFixed(interp.pitch)); p.anglex = FIXED_TO_FLOAT(AngleFixed(interp.roll)); - // SRB2CBTODO: MD2 scaling support - finalscale *= FIXED_TO_FLOAT(interp.scale); - p.flip = atransform.flip; p.mirror = atransform.mirror; HWD.pfnSetShader(SHADER_MODEL); // model shader { - float xs = finalscale * FIXED_TO_FLOAT(spr->mobj->spritexscale); - float ys = finalscale * FIXED_TO_FLOAT(spr->mobj->spriteyscale); - HWD.pfnDrawModel(md2->model, frame, durs, tics, nextFrame, &p, xs, ys, flip, hflip, &Surf); + float this_scale = FIXED_TO_FLOAT(interp.scale); + + float xs = this_scale * FIXED_TO_FLOAT(interp.spritexscale); + float ys = this_scale * FIXED_TO_FLOAT(interp.spriteyscale); + + float ox = xs * FIXED_TO_FLOAT(interp.spritexoffset); + float oy = ys * FIXED_TO_FLOAT(interp.spriteyoffset); + + // offset perpendicular to the camera angle + p.x -= ox * gl_viewsin; + p.y += ox * gl_viewcos; + p.z += oy; + + HWD.pfnDrawModel(md2->model, frame, durs, tics, nextFrame, &p, md2->scale * xs, md2->scale * ys, flip, hflip, &Surf); } } From bc9e7c146126bdd65f79c8fb5f37930d41b2816e Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 25 Oct 2022 22:20:20 -0700 Subject: [PATCH 281/586] Disable sprite/model rotation on slopes for now --- src/hardware/hw_md2.c | 5 +++++ src/p_mobj.c | 5 +++++ src/r_patchrotation.c | 4 ++++ 3 files changed, 14 insertions(+) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index f0108969f..fca3af217 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1630,8 +1630,13 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) } } +#if 0 p.anglez = FIXED_TO_FLOAT(AngleFixed(interp.pitch)); p.anglex = FIXED_TO_FLOAT(AngleFixed(interp.roll)); +#else + p.anglez = 0.f; + p.anglex = 0.f; +#endif p.flip = atransform.flip; p.mirror = atransform.mirror; diff --git a/src/p_mobj.c b/src/p_mobj.c index 9a889d516..a25b5643b 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1556,6 +1556,7 @@ void P_CheckGravity(mobj_t *mo, boolean affect) // void P_SetPitchRollFromSlope(mobj_t *mo, pslope_t *slope) { +#if 0 if (slope) { fixed_t tempz = slope->normal.z; @@ -1569,6 +1570,10 @@ void P_SetPitchRollFromSlope(mobj_t *mo, pslope_t *slope) { mo->pitch = mo->roll = 0; } +#else + (void)mo; + (void)slope; +#endif } #define STOPSPEED (FRACUNIT) diff --git a/src/r_patchrotation.c b/src/r_patchrotation.c index a17b725d6..b0cbeaa42 100644 --- a/src/r_patchrotation.c +++ b/src/r_patchrotation.c @@ -26,6 +26,7 @@ angle_t R_ModelRotationAngle(interpmobjstate_t *interp) angle_t R_SpriteRotationAngle(interpmobjstate_t *interp) { +#if 0 angle_t viewingAngle = R_PointToAngle(interp->x, interp->y); fixed_t pitchMul = -FINESINE(viewingAngle >> ANGLETOFINESHIFT); @@ -34,6 +35,9 @@ angle_t R_SpriteRotationAngle(interpmobjstate_t *interp) angle_t rollOrPitch = FixedMul(interp->pitch, pitchMul) + FixedMul(interp->roll, rollMul); return (rollOrPitch + R_ModelRotationAngle(interp)); +#else + return R_ModelRotationAngle(interp); +#endif } INT32 R_GetRollAngle(angle_t rollangle) From 516e06bcba5fd9477ec951be63637eb7a0c65519 Mon Sep 17 00:00:00 2001 From: katsy <205-katsy@users.noreply.git.do.srb2.org> Date: Mon, 24 Jul 2023 09:12:05 +0000 Subject: [PATCH 282/586] Autobackup old gamedatas (resolves #1031) --- src/g_game.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/g_game.c b/src/g_game.c index b23980044..e188a772b 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -4372,6 +4372,17 @@ void G_LoadGameData(gamedata_t *data) { goto datacorrupt; } + + // make a backup of the old data + char currentfilename[64]; + char backupfilename[69]; + char bak[5]; + + strcpy(bak, ".bak"); + strcpy(currentfilename, gamedatafilename); + STRBUFCPY(backupfilename, strcat(currentfilename, bak)); + + FIL_WriteFile(va(pandf, srb2home, backupfilename), savebuffer, length); } else #endif From a9d0630b15293ebdb403db9da979d40b1dac9373 Mon Sep 17 00:00:00 2001 From: Shane Ellis Date: Thu, 8 Jul 2021 18:07:34 -0400 Subject: [PATCH 283/586] Add lives check to Team name HUD --- 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 9cac145a7..3e1638370 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -884,7 +884,7 @@ static void ST_drawLivesArea(void) } } // Team name - else if (G_GametypeHasTeams()) + else if (G_GametypeHasTeams() && !(gametyperules & GTR_LIVES)) { if (stplyr->ctfteam == 1) { From 84e448eb63a3d805cc9ac98446461975b339378f Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 24 Jul 2023 06:09:50 -0400 Subject: [PATCH 284/586] Improve handling of team lives labels The lives counter check is now always run, and team name is displayed in its place when its false. --- src/st_stuff.c | 73 +++++++++++++++++++++++++++++++------------------- 1 file changed, 46 insertions(+), 27 deletions(-) diff --git a/src/st_stuff.c b/src/st_stuff.c index 3e1638370..c6e6befc6 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -815,7 +815,7 @@ static inline void ST_drawRings(void) static void ST_drawLivesArea(void) { INT32 v_colmap = V_YELLOWMAP, livescount; - boolean notgreyedout; + boolean notgreyedout = false; if (!stplyr->skincolor) return; // Just joined a server, skin isn't loaded yet! @@ -868,39 +868,36 @@ static void ST_drawLivesArea(void) if (metalrecording) { if (((2*leveltime)/TICRATE) & 1) + { V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, hudinfo[HUD_LIVES].f|V_PERPLAYER|V_REDMAP|V_HUDTRANS, "REC"); + } } // Spectator else if (stplyr->spectator) + { v_colmap = V_GRAYMAP; - // Tag - else if (gametyperules & GTR_TAG) - { - if (stplyr->pflags & PF_TAGIT) - { - V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "IT!"); - v_colmap = V_ORANGEMAP; - } } - // Team name - else if (G_GametypeHasTeams() && !(gametyperules & GTR_LIVES)) - { - if (stplyr->ctfteam == 1) - { - V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "RED"); - v_colmap = V_REDMAP; - } - else if (stplyr->ctfteam == 2) - { - V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "BLUE"); - v_colmap = V_BLUEMAP; - } - } - // Lives number else { - boolean candrawlives = true; + boolean candrawlives = false; + + // Set the player's name color. + if (G_TagGametype() && (stplyr->pflags & PF_TAGIT)) + { + v_colmap = V_ORANGEMAP; + } + else if (G_GametypeHasTeams()) + { + if (stplyr->ctfteam == 1) + { + v_colmap = V_REDMAP; + } + else if (stplyr->ctfteam == 2) + { + v_colmap = V_BLUEMAP; + } + } // Co-op and Competition, normal life counter if (G_GametypeUsesLives()) @@ -936,12 +933,15 @@ static void ST_drawLivesArea(void) livescount = (((netgame || multiplayer) && G_GametypeUsesCoopLives() && cv_cooplives.value == 0) ? INFLIVES : stplyr->lives); notgreyedout = true; } + + candrawlives = true; } // Infinity symbol (Race) else if (G_PlatformGametype() && !(gametyperules & GTR_LIVES)) { livescount = INFLIVES; notgreyedout = true; + candrawlives = true; } // Otherwise nothing, sorry. // Special Stages keep not showing lives, @@ -950,8 +950,6 @@ static void ST_drawLivesArea(void) // cannot show up because Special Stages // still have the GTR_LIVES gametype rule // by default. - else - candrawlives = false; // Draw the lives counter here. if (candrawlives) @@ -959,8 +957,10 @@ static void ST_drawLivesArea(void) // x V_DrawScaledPatch(hudinfo[HUD_LIVES].x+22, hudinfo[HUD_LIVES].y+10, hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, stlivex); if (livescount == INFLIVES) + { V_DrawCharacter(hudinfo[HUD_LIVES].x+50, hudinfo[HUD_LIVES].y+8, '\x16' | 0x80 | hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, false); + } else { if (stplyr->playerstate == PST_DEAD && !(stplyr->spectator) && (livescount || stplyr->deadtimer < (TICRATE<<1)) && !(stplyr->pflags & PF_FINISHED)) @@ -971,6 +971,25 @@ static void ST_drawLivesArea(void) hudinfo[HUD_LIVES].f|V_PERPLAYER|(notgreyedout ? V_HUDTRANS : V_HUDTRANSHALF), va("%d",livescount)); } } + else + { + // Draw team name instead of lives, if possible. + if (G_TagGametype() && (stplyr->pflags & PF_TAGIT)) + { + V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "IT!"); + } + else if (G_GametypeHasTeams()) + { + if (stplyr->ctfteam == 1) + { + V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "RED"); + } + else if (stplyr->ctfteam == 2) + { + V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "BLUE"); + } + } + } #undef ST_drawLivesX } From 86b4f9361001ea1b6ba7c2d0966932e4fd11473c Mon Sep 17 00:00:00 2001 From: spherallic Date: Wed, 2 Mar 2022 23:47:15 +0100 Subject: [PATCH 285/586] Allow obtaining ring, time & grade emblems in regular SP gameplay. --- src/d_netcmd.c | 2 +- src/d_player.h | 3 +- src/g_game.c | 354 ++++++++++++++++++++++++++------------------ src/g_game.h | 3 +- src/lua_playerlib.c | 8 + src/m_cond.c | 2 +- src/m_cond.h | 2 +- src/p_saveg.c | 61 ++++++-- src/p_setup.c | 2 +- src/p_user.c | 12 +- 10 files changed, 279 insertions(+), 170 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 90078f062..52790b2ce 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -2339,7 +2339,7 @@ static void Got_Clearscores(UINT8 **cp, INT32 playernum) } for (i = 0; i < MAXPLAYERS; i++) - players[i].score = 0; + players[i].score = players[i].recordscore = 0; CONS_Printf(M_GetText("Scores have been reset by the server.\n")); } diff --git a/src/d_player.h b/src/d_player.h index f407c29e9..7ad5b9f81 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -453,7 +453,8 @@ typedef struct player_s INT32 skin; UINT32 availabilities; - UINT32 score; // player score + UINT32 score; // player score (total) + UINT32 recordscore; // player score (per life / map) fixed_t dashspeed; // dashing speed fixed_t normalspeed; // Normal ground diff --git a/src/g_game.c b/src/g_game.c index 571756503..81942f462 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -519,140 +519,154 @@ UINT8 G_GetBestNightsGrade(INT16 map, UINT8 mare, gamedata_t *data) } // For easy adding of NiGHTS records -void G_AddTempNightsRecords(UINT32 pscore, tic_t ptime, UINT8 mare) +void G_AddTempNightsRecords(player_t *player, UINT32 pscore, tic_t ptime, UINT8 mare) { - ntemprecords.score[mare] = pscore; - ntemprecords.grade[mare] = P_GetGrade(pscore, gamemap, mare - 1); - ntemprecords.time[mare] = ptime; + const UINT8 playerID = player - players; + + I_Assert(player != NULL); + + ntemprecords[playerID].score[mare] = pscore; + ntemprecords[playerID].grade[mare] = P_GetGrade(pscore, gamemap, mare - 1); + ntemprecords[playerID].time[mare] = ptime; // Update nummares // Note that mare "0" is overall, mare "1" is the first real mare - if (ntemprecords.nummares < mare) - ntemprecords.nummares = mare; + if (ntemprecords[playerID].nummares < mare) + ntemprecords[playerID].nummares = mare; } // -// G_UpdateRecordReplays +// G_SetMainRecords // // Update replay files/data, etc. for Record Attack // See G_SetNightsRecords for NiGHTS Attack. // -static void G_UpdateRecordReplays(gamedata_t *data) +static void G_SetMainRecords(gamedata_t *data, player_t *player) { - const size_t glen = strlen(srb2home)+1+strlen("replay")+1+strlen(timeattackfolder)+1+strlen("MAPXX")+1; - char *gpath; - char lastdemo[256], bestdemo[256]; UINT8 earnedEmblems; + I_Assert(player != NULL); + // Record new best time if (!data->mainrecords[gamemap-1]) G_AllocMainRecordData(gamemap-1, data); - if (players[consoleplayer].score > data->mainrecords[gamemap-1]->score) - data->mainrecords[gamemap-1]->score = players[consoleplayer].score; + if (player->recordscore > data->mainrecords[gamemap-1]->score) + data->mainrecords[gamemap-1]->score = player->recordscore; - if ((data->mainrecords[gamemap-1]->time == 0) || (players[consoleplayer].realtime < data->mainrecords[gamemap-1]->time)) - data->mainrecords[gamemap-1]->time = players[consoleplayer].realtime; + if ((data->mainrecords[gamemap-1]->time == 0) || (player->realtime < data->mainrecords[gamemap-1]->time)) + data->mainrecords[gamemap-1]->time = player->realtime; - if ((UINT16)(players[consoleplayer].rings) > data->mainrecords[gamemap-1]->rings) - data->mainrecords[gamemap-1]->rings = (UINT16)(players[consoleplayer].rings); + if ((UINT16)(player->rings) > data->mainrecords[gamemap-1]->rings) + data->mainrecords[gamemap-1]->rings = (UINT16)(player->rings); - // Save demo! - bestdemo[255] = '\0'; - lastdemo[255] = '\0'; - G_SetDemoTime(players[consoleplayer].realtime, players[consoleplayer].score, (UINT16)(players[consoleplayer].rings)); - G_CheckDemoStatus(); - - I_mkdir(va("%s"PATHSEP"replay", srb2home), 0755); - I_mkdir(va("%s"PATHSEP"replay"PATHSEP"%s", srb2home, timeattackfolder), 0755); - - if ((gpath = malloc(glen)) == NULL) - I_Error("Out of memory for replay filepath\n"); - - sprintf(gpath,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, G_BuildMapName(gamemap)); - snprintf(lastdemo, 255, "%s-%s-last.lmp", gpath, skins[cv_chooseskin.value-1].name); - - if (FIL_FileExists(lastdemo)) + if (modeattacking) { - UINT8 *buf; - size_t len = FIL_ReadFile(lastdemo, &buf); + const size_t glen = strlen(srb2home)+1+strlen("replay")+1+strlen(timeattackfolder)+1+strlen("MAPXX")+1; + char *gpath; + char lastdemo[256], bestdemo[256]; - snprintf(bestdemo, 255, "%s-%s-time-best.lmp", gpath, skins[cv_chooseskin.value-1].name); - if (!FIL_FileExists(bestdemo) || G_CmpDemoTime(bestdemo, lastdemo) & 1) - { // Better time, save this demo. - if (FIL_FileExists(bestdemo)) - remove(bestdemo); - FIL_WriteFile(bestdemo, buf, len); - CONS_Printf("\x83%s\x80 %s '%s'\n", M_GetText("NEW RECORD TIME!"), M_GetText("Saved replay as"), bestdemo); + // Save demo! + bestdemo[255] = '\0'; + lastdemo[255] = '\0'; + G_SetDemoTime(player->realtime, player->recordscore, (UINT16)(player->rings)); + G_CheckDemoStatus(); + + I_mkdir(va("%s"PATHSEP"replay", srb2home), 0755); + I_mkdir(va("%s"PATHSEP"replay"PATHSEP"%s", srb2home, timeattackfolder), 0755); + + if ((gpath = malloc(glen)) == NULL) + I_Error("Out of memory for replay filepath\n"); + + sprintf(gpath,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, G_BuildMapName(gamemap)); + snprintf(lastdemo, 255, "%s-%s-last.lmp", gpath, skins[cv_chooseskin.value-1].name); + + if (FIL_FileExists(lastdemo)) + { + UINT8 *buf; + size_t len = FIL_ReadFile(lastdemo, &buf); + + snprintf(bestdemo, 255, "%s-%s-time-best.lmp", gpath, skins[cv_chooseskin.value-1].name); + if (!FIL_FileExists(bestdemo) || G_CmpDemoTime(bestdemo, lastdemo) & 1) + { // Better time, save this demo. + if (FIL_FileExists(bestdemo)) + remove(bestdemo); + FIL_WriteFile(bestdemo, buf, len); + CONS_Printf("\x83%s\x80 %s '%s'\n", M_GetText("NEW RECORD TIME!"), M_GetText("Saved replay as"), bestdemo); + } + + snprintf(bestdemo, 255, "%s-%s-score-best.lmp", gpath, skins[cv_chooseskin.value-1].name); + if (!FIL_FileExists(bestdemo) || (G_CmpDemoTime(bestdemo, lastdemo) & (1<<1))) + { // Better score, save this demo. + if (FIL_FileExists(bestdemo)) + remove(bestdemo); + FIL_WriteFile(bestdemo, buf, len); + CONS_Printf("\x83%s\x80 %s '%s'\n", M_GetText("NEW HIGH SCORE!"), M_GetText("Saved replay as"), bestdemo); + } + + snprintf(bestdemo, 255, "%s-%s-rings-best.lmp", gpath, skins[cv_chooseskin.value-1].name); + if (!FIL_FileExists(bestdemo) || (G_CmpDemoTime(bestdemo, lastdemo) & (1<<2))) + { // Better rings, save this demo. + if (FIL_FileExists(bestdemo)) + remove(bestdemo); + FIL_WriteFile(bestdemo, buf, len); + CONS_Printf("\x83%s\x80 %s '%s'\n", M_GetText("NEW MOST RINGS!"), M_GetText("Saved replay as"), bestdemo); + } + + //CONS_Printf("%s '%s'\n", M_GetText("Saved replay as"), lastdemo); + + Z_Free(buf); } - - snprintf(bestdemo, 255, "%s-%s-score-best.lmp", gpath, skins[cv_chooseskin.value-1].name); - if (!FIL_FileExists(bestdemo) || (G_CmpDemoTime(bestdemo, lastdemo) & (1<<1))) - { // Better score, save this demo. - if (FIL_FileExists(bestdemo)) - remove(bestdemo); - FIL_WriteFile(bestdemo, buf, len); - CONS_Printf("\x83%s\x80 %s '%s'\n", M_GetText("NEW HIGH SCORE!"), M_GetText("Saved replay as"), bestdemo); - } - - snprintf(bestdemo, 255, "%s-%s-rings-best.lmp", gpath, skins[cv_chooseskin.value-1].name); - if (!FIL_FileExists(bestdemo) || (G_CmpDemoTime(bestdemo, lastdemo) & (1<<2))) - { // Better rings, save this demo. - if (FIL_FileExists(bestdemo)) - remove(bestdemo); - FIL_WriteFile(bestdemo, buf, len); - CONS_Printf("\x83%s\x80 %s '%s'\n", M_GetText("NEW MOST RINGS!"), M_GetText("Saved replay as"), bestdemo); - } - - //CONS_Printf("%s '%s'\n", M_GetText("Saved replay as"), lastdemo); - - Z_Free(buf); + free(gpath); } - free(gpath); // Check emblems when level data is updated if ((earnedEmblems = M_CheckLevelEmblems(data))) + { CONS_Printf(M_GetText("\x82" "Earned %hu emblem%s for Record Attack records.\n"), (UINT16)earnedEmblems, earnedEmblems > 1 ? "s" : ""); + } // Update timeattack menu's replay availability. Nextmap_OnChange(); } -void G_SetNightsRecords(gamedata_t *data) +static void G_SetNightsRecords(gamedata_t *data, player_t *player) { - INT32 i; + nightsdata_t *const ntemprecord = &ntemprecords[player - players]; UINT32 totalscore = 0; tic_t totaltime = 0; + INT32 i; + UINT8 earnedEmblems; - const size_t glen = strlen(srb2home)+1+strlen("replay")+1+strlen(timeattackfolder)+1+strlen("MAPXX")+1; - char *gpath; - char lastdemo[256], bestdemo[256]; - - if (!ntemprecords.nummares) + if (!ntemprecord->nummares) + { return; + } // Set overall { UINT8 totalrank = 0, realrank = 0; - for (i = 1; i <= ntemprecords.nummares; ++i) + for (i = 1; i <= ntemprecord->nummares; ++i) { - totalscore += ntemprecords.score[i]; - totalrank += ntemprecords.grade[i]; - totaltime += ntemprecords.time[i]; + totalscore += ntemprecord->score[i]; + totalrank += ntemprecord->grade[i]; + totaltime += ntemprecord->time[i]; } // Determine overall grade - realrank = (UINT8)((FixedDiv((fixed_t)totalrank << FRACBITS, ntemprecords.nummares << FRACBITS) + (FRACUNIT/2)) >> FRACBITS); + realrank = (UINT8)((FixedDiv((fixed_t)totalrank << FRACBITS, ntemprecord->nummares << FRACBITS) + (FRACUNIT/2)) >> FRACBITS); // You need ALL rainbow As to get a rainbow A overall - if (realrank == GRADE_S && (totalrank / ntemprecords.nummares) != GRADE_S) + if (realrank == GRADE_S && (totalrank / ntemprecord->nummares) != GRADE_S) + { realrank = GRADE_A; + } - ntemprecords.score[0] = totalscore; - ntemprecords.grade[0] = realrank; - ntemprecords.time[0] = totaltime; + ntemprecord->score[0] = totalscore; + ntemprecord->grade[0] = realrank; + ntemprecord->time[0] = totaltime; } // Now take all temp records and put them in the actual records @@ -660,71 +674,85 @@ void G_SetNightsRecords(gamedata_t *data) nightsdata_t *maprecords; if (!data->nightsrecords[gamemap-1]) + { G_AllocNightsRecordData(gamemap-1, data); + } + maprecords = data->nightsrecords[gamemap-1]; - if (maprecords->nummares != ntemprecords.nummares) - maprecords->nummares = ntemprecords.nummares; - - for (i = 0; i < ntemprecords.nummares + 1; ++i) + if (maprecords->nummares != ntemprecord->nummares) { - if (maprecords->score[i] < ntemprecords.score[i]) - maprecords->score[i] = ntemprecords.score[i]; - if (maprecords->grade[i] < ntemprecords.grade[i]) - maprecords->grade[i] = ntemprecords.grade[i]; - if (!maprecords->time[i] || maprecords->time[i] > ntemprecords.time[i]) - maprecords->time[i] = ntemprecords.time[i]; + maprecords->nummares = ntemprecord->nummares; + } + + for (i = 0; i < ntemprecord->nummares + 1; ++i) + { + if (maprecords->score[i] < ntemprecord->score[i]) + maprecords->score[i] = ntemprecord->score[i]; + if (maprecords->grade[i] < ntemprecord->grade[i]) + maprecords->grade[i] = ntemprecord->grade[i]; + if (!maprecords->time[i] || maprecords->time[i] > ntemprecord->time[i]) + maprecords->time[i] = ntemprecord->time[i]; } } - memset(&ntemprecords, 0, sizeof(nightsdata_t)); + memset(&ntemprecords[player - players], 0, sizeof(nightsdata_t)); - // Save demo! - bestdemo[255] = '\0'; - lastdemo[255] = '\0'; - G_SetDemoTime(totaltime, totalscore, 0); - G_CheckDemoStatus(); - - I_mkdir(va("%s"PATHSEP"replay", srb2home), 0755); - I_mkdir(va("%s"PATHSEP"replay"PATHSEP"%s", srb2home, timeattackfolder), 0755); - - if ((gpath = malloc(glen)) == NULL) - I_Error("Out of memory for replay filepath\n"); - - sprintf(gpath,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, G_BuildMapName(gamemap)); - snprintf(lastdemo, 255, "%s-%s-last.lmp", gpath, skins[cv_chooseskin.value-1].name); - - if (FIL_FileExists(lastdemo)) + if (modeattacking) { - UINT8 *buf; - size_t len = FIL_ReadFile(lastdemo, &buf); + const size_t glen = strlen(srb2home)+1+strlen("replay")+1+strlen(timeattackfolder)+1+strlen("MAPXX")+1; + char *gpath; + char lastdemo[256], bestdemo[256]; - snprintf(bestdemo, 255, "%s-%s-time-best.lmp", gpath, skins[cv_chooseskin.value-1].name);; - if (!FIL_FileExists(bestdemo) || G_CmpDemoTime(bestdemo, lastdemo) & 1) - { // Better time, save this demo. - if (FIL_FileExists(bestdemo)) - remove(bestdemo); - FIL_WriteFile(bestdemo, buf, len); - CONS_Printf("\x83%s\x80 %s '%s'\n", M_GetText("NEW RECORD TIME!"), M_GetText("Saved replay as"), bestdemo); + // Save demo! + bestdemo[255] = '\0'; + lastdemo[255] = '\0'; + G_SetDemoTime(totaltime, totalscore, 0); + G_CheckDemoStatus(); + + I_mkdir(va("%s"PATHSEP"replay", srb2home), 0755); + I_mkdir(va("%s"PATHSEP"replay"PATHSEP"%s", srb2home, timeattackfolder), 0755); + + if ((gpath = malloc(glen)) == NULL) + I_Error("Out of memory for replay filepath\n"); + + sprintf(gpath,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, G_BuildMapName(gamemap)); + snprintf(lastdemo, 255, "%s-%s-last.lmp", gpath, skins[cv_chooseskin.value-1].name); + + if (FIL_FileExists(lastdemo)) + { + UINT8 *buf; + size_t len = FIL_ReadFile(lastdemo, &buf); + + snprintf(bestdemo, 255, "%s-%s-time-best.lmp", gpath, skins[cv_chooseskin.value-1].name);; + if (!FIL_FileExists(bestdemo) || G_CmpDemoTime(bestdemo, lastdemo) & 1) + { // Better time, save this demo. + if (FIL_FileExists(bestdemo)) + remove(bestdemo); + FIL_WriteFile(bestdemo, buf, len); + CONS_Printf("\x83%s\x80 %s '%s'\n", M_GetText("NEW RECORD TIME!"), M_GetText("Saved replay as"), bestdemo); + } + + snprintf(bestdemo, 255, "%s-%s-score-best.lmp", gpath, skins[cv_chooseskin.value-1].name); + if (!FIL_FileExists(bestdemo) || (G_CmpDemoTime(bestdemo, lastdemo) & (1<<1))) + { // Better score, save this demo. + if (FIL_FileExists(bestdemo)) + remove(bestdemo); + FIL_WriteFile(bestdemo, buf, len); + CONS_Printf("\x83%s\x80 %s '%s'\n", M_GetText("NEW HIGH SCORE!"), M_GetText("Saved replay as"), bestdemo); + } + + //CONS_Printf("%s '%s'\n", M_GetText("Saved replay as"), lastdemo); + + Z_Free(buf); } - - snprintf(bestdemo, 255, "%s-%s-score-best.lmp", gpath, skins[cv_chooseskin.value-1].name); - if (!FIL_FileExists(bestdemo) || (G_CmpDemoTime(bestdemo, lastdemo) & (1<<1))) - { // Better score, save this demo. - if (FIL_FileExists(bestdemo)) - remove(bestdemo); - FIL_WriteFile(bestdemo, buf, len); - CONS_Printf("\x83%s\x80 %s '%s'\n", M_GetText("NEW HIGH SCORE!"), M_GetText("Saved replay as"), bestdemo); - } - - //CONS_Printf("%s '%s'\n", M_GetText("Saved replay as"), lastdemo); - - Z_Free(buf); + free(gpath); } - free(gpath); if ((earnedEmblems = M_CheckLevelEmblems(data))) + { CONS_Printf(M_GetText("\x82" "Earned %hu emblem%s for NiGHTS records.\n"), (UINT16)earnedEmblems, earnedEmblems > 1 ? "s" : ""); + } // If the mare count changed, this will update the score display Nextmap_OnChange(); @@ -2287,7 +2315,7 @@ void G_Ticker(boolean run) p->lives = startinglivesbalance[0]; p->continues = 1; - p->score = 0; + p->score = p->recordscore = 0; // The latter two should clear by themselves, but just in case p->pflags &= ~(PF_TAGIT|PF_GAMETYPEOVER|PF_FULLSTASIS); @@ -2490,6 +2518,7 @@ static inline void G_PlayerFinishLevel(INT32 player) memset(p->powers, 0, sizeof (p->powers)); p->ringweapons = 0; + p->recordscore = 0; p->mo->flags2 &= ~MF2_SHADOW; // cancel invisibility P_FlashPal(p, 0, 0); // Resets @@ -2513,6 +2542,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) { player_t *p; INT32 score; + INT32 recordscore; INT32 lives; INT32 continues; fixed_t camerascale; @@ -3165,6 +3195,7 @@ void G_DoReborn(INT32 playernum) { if (!playeringame[i]) continue; + players[i].recordscore = 0; players[i].starpostscale = 0; players[i].starpostangle = 0; players[i].starposttime = 0; @@ -3844,15 +3875,16 @@ static INT16 RandMap(UINT32 tolflags, INT16 pprevmap) // // G_UpdateVisited // -static void G_UpdateVisited(gamedata_t *data, boolean silent) +static void G_UpdateVisited(gamedata_t *data, player_t *player, boolean silent) { - boolean spec = G_IsSpecialStage(gamemap); // Update visitation flags? if (!demoplayback && G_CoopGametype() // Campaign mode && !stagefailed) // Did not fail the stage { UINT8 earnedEmblems; + UINT16 totalrings = 0; + INT32 i; // Update visitation flags data->mapvisited[gamemap-1] |= MV_BEATEN; @@ -3861,36 +3893,62 @@ static void G_UpdateVisited(gamedata_t *data, boolean silent) if (ultimatemode) data->mapvisited[gamemap-1] |= MV_ULTIMATE; + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + { + continue; + } + + totalrings += players[i].rings; + } + // may seem incorrect but IS possible in what the main game uses as mp special stages, and nummaprings will be -1 in NiGHTS - if (nummaprings > 0 && players[consoleplayer].rings >= nummaprings) + if (nummaprings > 0 && totalrings >= nummaprings) { data->mapvisited[gamemap-1] |= MV_PERFECT; if (modeattacking) data->mapvisited[gamemap-1] |= MV_PERFECTRA; } - if (!spec) + if (!G_IsSpecialStage(gamemap)) { // not available to special stages because they can only really be done in one order in an unmodified game, so impossible for first six and trivial for seventh if (ALL7EMERALDS(emeralds)) data->mapvisited[gamemap-1] |= MV_ALLEMERALDS; } + if ((earnedEmblems = M_CompletionEmblems(data)) && !silent) + { + CONS_Printf(M_GetText("\x82" "Earned %hu emblem%s for level completion.\n"), (UINT16)earnedEmblems, earnedEmblems > 1 ? "s" : ""); + } + if (silent) { - if (modeattacking) - M_CheckLevelEmblems(data); + M_CheckLevelEmblems(data); } else { - if (modeattacking == ATTACKING_RECORD) - G_UpdateRecordReplays(data); - else if (modeattacking == ATTACKING_NIGHTS) - G_SetNightsRecords(data); + if (mapheaderinfo[gamemap-1]->menuflags & LF2_RECORDATTACK) + G_SetMainRecords(data, player); + else if (mapheaderinfo[gamemap-1]->menuflags & LF2_NIGHTSATTACK) + G_SetNightsRecords(data, player); } + } +} - if ((earnedEmblems = M_CompletionEmblems(data)) && !silent) - CONS_Printf(M_GetText("\x82" "Earned %hu emblem%s for level completion.\n"), (UINT16)earnedEmblems, earnedEmblems > 1 ? "s" : ""); +static void G_UpdateAllVisited(void) +{ + // Update server + G_UpdateVisited(serverGamedata, &players[serverplayer], true); + + // Update client + G_UpdateVisited(clientGamedata, &players[consoleplayer], false); + + if (splitscreen) + { + // Allow P2 to get emblems too, why not :) + G_UpdateVisited(clientGamedata, &players[secondarydisplayplayer], false); } } @@ -3914,6 +3972,9 @@ static boolean CanSaveLevel(INT32 mapnum) static void G_HandleSaveLevel(void) { + // Update records & emblems + G_UpdateAllVisited(); + // do this before running the intermission or custom cutscene, mostly for the sake of marathon mode but it also massively reduces redundant file save events in f_finale.c if (nextmap >= 1100-1) { @@ -4092,8 +4153,6 @@ static void G_DoCompleted(void) if ((skipstats && !modeattacking) || (modeattacking && stagefailed) || (intertype == int_none)) { - G_UpdateVisited(serverGamedata, true); - G_UpdateVisited(clientGamedata, false); G_HandleSaveLevel(); G_AfterIntermission(); } @@ -4102,8 +4161,6 @@ static void G_DoCompleted(void) G_SetGamestate(GS_INTERMISSION); Y_StartIntermission(); Y_LoadIntermissionData(); - G_UpdateVisited(serverGamedata, true); - G_UpdateVisited(clientGamedata, false); G_HandleSaveLevel(); } } @@ -4992,6 +5049,7 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean players[i].playerstate = PST_REBORN; players[i].starpostscale = players[i].starpostangle = players[i].starpostnum = players[i].starposttime = 0; players[i].starpostx = players[i].starposty = players[i].starpostz = 0; + players[i].recordscore = 0; if (netgame || multiplayer) { diff --git a/src/g_game.h b/src/g_game.h index 6cda7ca9c..a8c285f79 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -260,8 +260,7 @@ UINT32 G_GetBestNightsScore(INT16 map, UINT8 mare, gamedata_t *data); tic_t G_GetBestNightsTime(INT16 map, UINT8 mare, gamedata_t *data); UINT8 G_GetBestNightsGrade(INT16 map, UINT8 mare, gamedata_t *data); -void G_AddTempNightsRecords(UINT32 pscore, tic_t ptime, UINT8 mare); -void G_SetNightsRecords(gamedata_t *data); +void G_AddTempNightsRecords(player_t *player, UINT32 pscore, tic_t ptime, UINT8 mare); FUNCMATH INT32 G_TicsToHours(tic_t tics); FUNCMATH INT32 G_TicsToMinutes(tic_t tics, boolean full); diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index c056be463..055acfd80 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -114,6 +114,7 @@ enum player_e player_skin, player_availabilities, player_score, + player_recordscore, player_dashspeed, player_normalspeed, player_runspeed, @@ -260,6 +261,7 @@ static const char *const player_opt[] = { "skin", "availabilities", "score", + "recordscore", "dashspeed", "normalspeed", "runspeed", @@ -495,6 +497,9 @@ static int player_get(lua_State *L) case player_score: lua_pushinteger(L, plr->score); break; + case player_recordscore: + lua_pushinteger(L, plr->recordscore); + break; case player_dashspeed: lua_pushfixed(L, plr->dashspeed); break; @@ -957,6 +962,9 @@ static int player_set(lua_State *L) case player_score: plr->score = (UINT32)luaL_checkinteger(L, 3); break; + case player_recordscore: + plr->recordscore = (UINT32)luaL_checkinteger(L, 3); + break; case player_dashspeed: plr->dashspeed = luaL_checkfixed(L, 3); break; diff --git a/src/m_cond.c b/src/m_cond.c index a54988f67..b21778c69 100644 --- a/src/m_cond.c +++ b/src/m_cond.c @@ -45,7 +45,7 @@ INT32 numemblems = 0; INT32 numextraemblems = 0; // Temporary holding place for nights data for the current map -nightsdata_t ntemprecords; +nightsdata_t ntemprecords[MAXPLAYERS]; // Create a new gamedata_t, for start-up gamedata_t *M_NewGameDataStruct(void) diff --git a/src/m_cond.h b/src/m_cond.h index 95c3e1ebe..2be8d564b 100644 --- a/src/m_cond.h +++ b/src/m_cond.h @@ -181,7 +181,7 @@ typedef struct #define MV_MAX 63 // used in gamedata check, update whenever MV's are added // Temporary holding place for nights data for the current map -extern nightsdata_t ntemprecords; +extern nightsdata_t ntemprecords[MAXPLAYERS]; // GAMEDATA STRUCTURE // Everything that would get saved in gamedata.dat diff --git a/src/p_saveg.c b/src/p_saveg.c index 8eac91105..3565d0125 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -179,6 +179,7 @@ static void P_NetArchivePlayers(void) WRITEINT32(save_p, players[i].skin); WRITEUINT32(save_p, players[i].availabilities); WRITEUINT32(save_p, players[i].score); + WRITEUINT32(save_p, players[i].recordscore); WRITEFIXED(save_p, players[i].dashspeed); WRITESINT8(save_p, players[i].lives); WRITESINT8(save_p, players[i].continues); @@ -407,6 +408,7 @@ static void P_NetUnArchivePlayers(void) players[i].skin = READINT32(save_p); players[i].availabilities = READUINT32(save_p); players[i].score = READUINT32(save_p); + players[i].recordscore = READUINT32(save_p); players[i].dashspeed = READFIXED(save_p); // dashing speed players[i].lives = READSINT8(save_p); players[i].continues = READSINT8(save_p); // continues that player has acquired @@ -4342,8 +4344,6 @@ static void P_NetArchiveMisc(boolean resending) WRITEUINT32(save_p, hidetime); - WRITEUINT32(save_p, unlocktriggers); - // Is it paused? if (paused) WRITEUINT8(save_p, 0x2f); @@ -4442,8 +4442,6 @@ static inline boolean P_NetUnArchiveMisc(boolean reloading) hidetime = READUINT32(save_p); - unlocktriggers = READUINT32(save_p); - // Is it paused? if (READUINT8(save_p) == 0x2f) paused = true; @@ -4451,7 +4449,6 @@ static inline boolean P_NetUnArchiveMisc(boolean reloading) return true; } - static inline void P_NetArchiveEmblems(void) { gamedata_t *data = serverGamedata; @@ -4550,6 +4547,27 @@ static inline void P_NetArchiveEmblems(void) WRITEUINT32(save_p, data->nightsrecords[i]->time[curmare]); } } + + // Mid-map stuff + WRITEUINT32(save_p, unlocktriggers); + + for (i = 0; i < MAXPLAYERS; i++) + { + if (!ntemprecords[i].nummares) + { + WRITEUINT8(save_p, 0); + continue; + } + + WRITEUINT8(save_p, ntemprecords[i].nummares); + + for (curmare = 0; curmare < (ntemprecords[i].nummares + 1); ++curmare) + { + WRITEUINT32(save_p, ntemprecords[i].score[curmare]); + WRITEUINT8(save_p, ntemprecords[i].grade[curmare]); + WRITEUINT32(save_p, ntemprecords[i].time[curmare]); + } + } } static inline void P_NetUnArchiveEmblems(void) @@ -4569,9 +4587,9 @@ static inline void P_NetUnArchiveEmblems(void) savemoddata = (boolean)READUINT8(save_p); // this one is actually necessary because savemoddata stays false otherwise for some reason. if (numemblems != READINT32(save_p)) - I_Error("numemblems mismatch"); + I_Error("Bad $$$.sav dearchiving Emblems (numemblems mismatch)"); if (numextraemblems != READINT32(save_p)) - I_Error("numextraemblems mismatch"); + I_Error("Bad $$$.sav dearchiving Emblems (numextraemblems mismatch)"); // This shouldn't happen, but if something really fucked up happens and you transfer // the SERVER player's gamedata over your own CLIENT gamedata, @@ -4590,7 +4608,7 @@ static inline void P_NetUnArchiveEmblems(void) // TODO put another cipher on these things? meh, I don't care... for (i = 0; i < NUMMAPS; i++) if ((data->mapvisited[i] = READUINT8(save_p)) > MV_MAX) - I_Error("Bad $$$.sav dearchiving Emblems"); + I_Error("Bad $$$.sav dearchiving Emblems (invalid visit flags)"); // To save space, use one bit per collected/achieved/unlocked flag for (i = 0; i < MAXEMBLEMS;) @@ -4634,7 +4652,7 @@ static inline void P_NetUnArchiveEmblems(void) recrings = READUINT16(save_p); if (recrings > 10000 || recscore > MAXSCORE) - I_Error("Bad $$$.sav dearchiving Emblems"); + I_Error("Bad $$$.sav dearchiving Emblems (invalid score)"); if (recscore || rectime || recrings) { @@ -4661,12 +4679,35 @@ static inline void P_NetUnArchiveEmblems(void) if (data->nightsrecords[i]->grade[curmare] > GRADE_S) { - I_Error("Bad $$$.sav dearchiving Emblems"); + I_Error("Bad $$$.sav dearchiving Emblems (invalid grade)"); } } data->nightsrecords[i]->nummares = recmares; } + + // Mid-map stuff + unlocktriggers = READUINT32(save_p); + + for (i = 0; i < MAXPLAYERS; ++i) + { + if ((recmares = READUINT8(save_p)) == 0) + continue; + + for (curmare = 0; curmare < (recmares+1); ++curmare) + { + ntemprecords[i].score[curmare] = READUINT32(save_p); + ntemprecords[i].grade[curmare] = READUINT8(save_p); + ntemprecords[i].time[curmare] = (tic_t)READUINT32(save_p); + + if (ntemprecords[i].grade[curmare] > GRADE_S) + { + I_Error("Bad $$$.sav dearchiving Emblems (invalid temp grade)"); + } + } + + ntemprecords[i].nummares = recmares; + } } static inline void P_ArchiveLuabanksAndConsistency(void) diff --git a/src/p_setup.c b/src/p_setup.c index bfb70751d..051853017 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -6985,7 +6985,7 @@ static void P_InitLevelSettings(void) stagefailed = G_IsSpecialStage(gamemap); // Reset temporary record data - memset(&ntemprecords, 0, sizeof(nightsdata_t)); + memset(&ntemprecords, 0, sizeof(ntemprecords)); // earthquake camera memset(&quake,0,sizeof(struct quake)); diff --git a/src/p_user.c b/src/p_user.c index b89552673..a0de50b8f 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -882,8 +882,7 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) } // Add score to leaderboards now - if (!(netgame||multiplayer) && P_IsLocalPlayer(&players[i])) - G_AddTempNightsRecords(players[i].marescore, leveltime - player->marebegunat, players[i].mare + 1); + G_AddTempNightsRecords(player, players[i].marescore, leveltime - player->marebegunat, players[i].mare + 1); // transfer scores anyway players[i].totalmarescore += players[i].marescore; @@ -909,8 +908,7 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) player->finishedrings = (INT16)(player->rings); // Add score to temp leaderboards - if (!(netgame||multiplayer) && P_IsLocalPlayer(player)) - G_AddTempNightsRecords(player->marescore, leveltime - player->marebegunat, (UINT8)(oldmare + 1)); + G_AddTempNightsRecords(player, player->marescore, leveltime - player->marebegunat, (UINT8)(oldmare + 1)); // Starting a new mare, transfer scores player->totalmarescore += player->marescore; @@ -1440,6 +1438,10 @@ void P_AddPlayerScore(player_t *player, UINT32 amount) if (player->score > MAXSCORE) player->score = MAXSCORE; + player->recordscore += amount; + if (player->recordscore > MAXSCORE) + player->recordscore = MAXSCORE; + // check for extra lives every 50000 pts if (!ultimatemode && !modeattacking && player->score > oldscore && player->score % 50000 < amount && (gametyperules & GTR_LIVES)) { @@ -11732,7 +11734,7 @@ void P_PlayerThink(player_t *player) if (player->spectator) { if (!(gametyperules & GTR_CAMPAIGN)) - player->score = 0; + player->score = player->recordscore = 0; } else if ((netgame || multiplayer) && player->lives <= 0 && !G_CoopGametype()) { From 8bddf0f097a2886a5edf642acca3aa9ab304626d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Mon, 24 Jul 2023 17:12:24 +0200 Subject: [PATCH 286/586] fixup! fixup! fixup! Fix build errors when building without SDL --- src/sdl/Srb2SDL-vc10.vcxproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sdl/Srb2SDL-vc10.vcxproj b/src/sdl/Srb2SDL-vc10.vcxproj index c20265ed1..0b95cd0b2 100644 --- a/src/sdl/Srb2SDL-vc10.vcxproj +++ b/src/sdl/Srb2SDL-vc10.vcxproj @@ -259,7 +259,7 @@ - + @@ -424,7 +424,7 @@ - + @@ -556,4 +556,4 @@ - \ No newline at end of file + From b36ca89e1646a370fd3be933ff066ddbf1fd60b8 Mon Sep 17 00:00:00 2001 From: Jisk Date: Mon, 24 Jul 2023 18:00:31 +0000 Subject: [PATCH 287/586] Port player.ping from SRB2Kart --- src/lua_playerlib.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index f76ec1689..ae3c06d31 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -222,6 +222,7 @@ enum player_e player_blocked, player_jointime, player_quittime, + player_ping, #ifdef HWRENDER player_fovadd, #endif @@ -368,6 +369,7 @@ static const char *const player_opt[] = { "blocked", "jointime", "quittime", + "ping", #ifdef HWRENDER "fovadd", #endif @@ -819,6 +821,9 @@ static int player_get(lua_State *L) case player_quittime: lua_pushinteger(L, plr->quittime); break; + case player_ping: + lua_pushinteger(L, playerpingtable[plr - players]); + break; #ifdef HWRENDER case player_fovadd: lua_pushfixed(L, plr->fovadd); From 4212035729c11197f2502b6f50f1eb4e7bf17b89 Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Mon, 24 Jul 2023 21:44:53 -0500 Subject: [PATCH 288/586] Fix errors due to declaring variables in switch bodies --- src/lua_maplib.c | 2 ++ src/lua_mobjlib.c | 2 ++ src/lua_playerlib.c | 2 ++ 3 files changed, 6 insertions(+) diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 568a99b68..3d95cdb75 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -2822,6 +2822,7 @@ static int mapheaderinfo_get(lua_State *L) break; // TODO add support for reading numGradedMares and grades default: + { // Read custom vars now // (note: don't include the "LUA." in your lua scripts!) UINT8 j = 0; @@ -2832,6 +2833,7 @@ static int mapheaderinfo_get(lua_State *L) else lua_pushnil(L); } + } return 1; } diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index 404af016a..851c569d2 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -1043,11 +1043,13 @@ static int mapthing_set(lua_State *L) mt->z = (INT16)luaL_checkinteger(L, 3); break; case mapthing_extrainfo: + { INT32 extrainfo = luaL_checkinteger(L, 3); if (extrainfo & ~15) return luaL_error(L, "mapthing_t extrainfo set %d out of range (%d - %d)", extrainfo, 0, 15); mt->extrainfo = (UINT8)extrainfo; break; + } case mapthing_tag: Tag_FSet(&mt->tags, (INT16)luaL_checkinteger(L, 3)); break; diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index f0fa2ed94..510e481e6 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -1297,6 +1297,7 @@ static int player_set(lua_State *L) break; } case player_awayviewtics: + { INT32 tics = (INT32)luaL_checkinteger(L, 3); if (tics && !plr->awayviewmobj) // awayviewtics must ALWAYS have an awayviewmobj set!! P_SetTarget(&plr->awayviewmobj, plr->mo); // but since the script might set awayviewmobj immediately AFTER setting awayviewtics, use player mobj as filler for now. @@ -1308,6 +1309,7 @@ static int player_set(lua_State *L) } plr->awayviewtics = tics; break; + } case player_awayviewaiming: plr->awayviewaiming = luaL_checkangle(L, 3); break; From 1a2f66acd9b14b4c64a6a4f6db049d097ac9c852 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 25 Jul 2023 06:47:32 -0400 Subject: [PATCH 289/586] Update .gitignore --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index cd828dc11..2b4d9d2fb 100644 --- a/.gitignore +++ b/.gitignore @@ -22,4 +22,4 @@ Win32_LIB_ASM_Release /make /bin /build -/build.* +/build/* From 77576c3c5d526651074ec6b9f4c664671e0ab273 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 25 Jul 2023 08:40:36 -0400 Subject: [PATCH 290/586] Allow Record Attack in modified games Replays now store & validate the add-on list before loading them. Custom characters can now be allowed in Record Attack. --- src/d_netcmd.c | 19 ++- src/f_finale.c | 1 + src/g_demo.c | 387 ++++++++++++++++++++++++++++++++++++++++++++++--- src/g_demo.h | 22 +++ src/m_menu.c | 93 ++++++++++-- 5 files changed, 487 insertions(+), 35 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 72d020c22..45a394eff 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1643,9 +1643,14 @@ static void Command_Playdemo_f(void) { char name[256]; - if (COM_Argc() != 2) + if (COM_Argc() < 2) { - CONS_Printf(M_GetText("playdemo : playback a demo\n")); + CONS_Printf("playdemo [-addfiles / -force]:\n"); + CONS_Printf(M_GetText( + "Play back a demo file. The full path from your SRB2 directory must be given.\n\n" + + "* With \"-addfiles\", any required files are added from a list contained within the demo file.\n" + "* With \"-force\", the demo is played even if the necessary files have not been added.\n")); return; } @@ -1667,6 +1672,16 @@ static void Command_Playdemo_f(void) CONS_Printf(M_GetText("Playing back demo '%s'.\n"), name); + demofileoverride = DFILE_OVERRIDE_NONE; + if (strcmp(COM_Argv(2), "-addfiles") == 0) + { + demofileoverride = DFILE_OVERRIDE_LOAD; + } + else if (strcmp(COM_Argv(2), "-force") == 0) + { + demofileoverride = DFILE_OVERRIDE_SKIP; + } + // Internal if no extension, external if one exists // If external, convert the file name to a path in SRB2's home directory if (FIL_CheckExtension(name)) diff --git a/src/f_finale.c b/src/f_finale.c index e59b43472..d03795dc4 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -3509,6 +3509,7 @@ void F_TitleScreenTicker(boolean run) } titledemo = true; + demofileoverride = DFILE_OVERRIDE_NONE; G_DoPlayDemo(dname); } } diff --git a/src/g_demo.c b/src/g_demo.c index 0403da16d..230f6da2d 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -39,6 +39,7 @@ #include "v_video.h" #include "lua_hook.h" #include "md5.h" // demo checksums +#include "d_netfil.h" // G_CheckDemoExtraFiles boolean timingdemo; // if true, exit with report on completion boolean nodrawers; // for comparative timing purposes @@ -49,6 +50,7 @@ static char demoname[64]; boolean demorecording; boolean demoplayback; boolean titledemo; // Title Screen demo can be cancelled by any key +demo_file_override_e demofileoverride; static UINT8 *demobuffer = NULL; static UINT8 *demo_p, *demotime_p; static UINT8 *demoend; @@ -95,7 +97,7 @@ demoghost *ghosts = NULL; // DEMO RECORDING // -#define DEMOVERSION 0x000f +#define DEMOVERSION 0x0010 #define DEMOHEADER "\xF0" "SRB2Replay" "\x0F" #define DF_GHOST 0x01 // This demo contains ghost data too! @@ -1413,6 +1415,10 @@ void G_BeginRecording(void) char name[MAXCOLORNAME+1]; player_t *player = &players[consoleplayer]; + char *filename; + UINT8 totalfiles; + UINT8 *m; + if (demo_p) return; memset(name,0,sizeof(name)); @@ -1435,23 +1441,43 @@ void G_BeginRecording(void) M_Memcpy(demo_p, mapmd5, 16); demo_p += 16; WRITEUINT8(demo_p,demoflags); + + // file list + m = demo_p;/* file count */ + demo_p += 1; + + totalfiles = 0; + for (i = mainwads; ++i < numwadfiles; ) + { + if (wadfiles[i]->important) + { + nameonly(( filename = va("%s", wadfiles[i]->filename) )); + WRITESTRINGL(demo_p, filename, MAX_WADPATH); + WRITEMEM(demo_p, wadfiles[i]->md5sum, 16); + + totalfiles++; + } + } + + WRITEUINT8(m, totalfiles); + switch ((demoflags & DF_ATTACKMASK)>>DF_ATTACKSHIFT) { - case ATTACKING_NONE: // 0 - break; - case ATTACKING_RECORD: // 1 - demotime_p = demo_p; - WRITEUINT32(demo_p,UINT32_MAX); // time - WRITEUINT32(demo_p,0); // score - WRITEUINT16(demo_p,0); // rings - break; - case ATTACKING_NIGHTS: // 2 - demotime_p = demo_p; - WRITEUINT32(demo_p,UINT32_MAX); // time - WRITEUINT32(demo_p,0); // score - break; - default: // 3 - break; + case ATTACKING_NONE: // 0 + break; + case ATTACKING_RECORD: // 1 + demotime_p = demo_p; + WRITEUINT32(demo_p,UINT32_MAX); // time + WRITEUINT32(demo_p,0); // score + WRITEUINT16(demo_p,0); // rings + break; + case ATTACKING_NIGHTS: // 2 + demotime_p = demo_p; + WRITEUINT32(demo_p,UINT32_MAX); // time + WRITEUINT32(demo_p,0); // score + break; + default: // 3 + break; } WRITEUINT32(demo_p,P_GetInitSeed()); @@ -1590,6 +1616,177 @@ void G_BeginMetal(void) oldmetal.angle = mo->angle>>24; } +static void G_LoadDemoExtraFiles(UINT8 **pp) +{ + UINT8 totalfiles; + char filename[MAX_WADPATH]; + UINT8 md5sum[16]; + filestatus_t ncs; + boolean toomany = false; + boolean alreadyloaded; + UINT8 i, j; + + totalfiles = READUINT8((*pp)); + for (i = 0; i < totalfiles; ++i) + { + if (toomany) + SKIPSTRING((*pp)); + else + { + strlcpy(filename, (char *)(*pp), sizeof filename); + SKIPSTRING((*pp)); + } + READMEM((*pp), md5sum, 16); + + if (!toomany) + { + alreadyloaded = false; + + for (j = 0; j < numwadfiles; ++j) + { + if (memcmp(md5sum, wadfiles[j]->md5sum, 16) == 0) + { + alreadyloaded = true; + break; + } + } + + if (alreadyloaded) + continue; + + if (numwadfiles >= MAX_WADFILES) + toomany = true; + else + ncs = findfile(filename, md5sum, false); + + if (toomany) + { + CONS_Alert(CONS_WARNING, M_GetText("Too many files loaded to add anymore for demo playback\n")); + if (!CON_Ready()) + M_StartMessage(M_GetText("There are too many files loaded to add this demo's addons.\n\nDemo playback may desync.\n\nPress ESC\n"), NULL, MM_NOTHING); + } + else if (ncs != FS_FOUND) + { + if (ncs == FS_NOTFOUND) + CONS_Alert(CONS_NOTICE, M_GetText("You do not have a copy of %s\n"), filename); + else if (ncs == FS_MD5SUMBAD) + CONS_Alert(CONS_NOTICE, M_GetText("Checksum mismatch on %s\n"), filename); + else + CONS_Alert(CONS_NOTICE, M_GetText("Unknown error finding file %s\n"), filename); + + if (!CON_Ready()) + M_StartMessage(M_GetText("There were errors trying to add this demo's addons. Check the console for more information.\n\nDemo playback may desync.\n\nPress ESC\n"), NULL, MM_NOTHING); + } + else + { + P_AddWadFile(filename); + } + } + } +} + +static void G_SkipDemoExtraFiles(UINT8 **pp) +{ + UINT8 totalfiles; + UINT8 i; + + if (demoversion < 0x0010) + { + // demo has no file list + return; + } + + totalfiles = READUINT8((*pp)); + for (i = 0; i < totalfiles; ++i) + { + SKIPSTRING((*pp));// file name + (*pp) += 16;// md5 + } +} + +// G_CheckDemoExtraFiles: checks if our loaded WAD list matches the demo's. +// Enabling quick prevents filesystem checks to see if needed files are available to load. +static UINT8 G_CheckDemoExtraFiles(UINT8 **pp, boolean quick) +{ + UINT8 totalfiles, filesloaded, nmusfilecount; + char filename[MAX_WADPATH]; + UINT8 md5sum[16]; + boolean toomany = false; + boolean alreadyloaded; + UINT8 i, j; + UINT8 error = DFILE_ERROR_NONE; + + if (demoversion < 0x0010) + { + // demo has no file list + return DFILE_ERROR_NONE; + } + + totalfiles = READUINT8((*pp)); + filesloaded = 0; + for (i = 0; i < totalfiles; ++i) + { + if (toomany) + SKIPSTRING((*pp)); + else + { + strlcpy(filename, (char *)(*pp), sizeof filename); + SKIPSTRING((*pp)); + } + READMEM((*pp), md5sum, 16); + + if (!toomany) + { + alreadyloaded = false; + nmusfilecount = 0; + + for (j = 0; j < numwadfiles; ++j) + { + if (wadfiles[j]->important && j > mainwads) + nmusfilecount++; + else + continue; + + if (memcmp(md5sum, wadfiles[j]->md5sum, 16) == 0) + { + alreadyloaded = true; + + if (i != nmusfilecount-1 && error < DFILE_ERROR_OUTOFORDER) + error |= DFILE_ERROR_OUTOFORDER; + + break; + } + } + + if (alreadyloaded) + { + filesloaded++; + continue; + } + + if (numwadfiles >= MAX_WADFILES) + error = DFILE_ERROR_CANNOTLOAD; + else if (!quick && findfile(filename, md5sum, false) != FS_FOUND) + error = DFILE_ERROR_CANNOTLOAD; + else if (error < DFILE_ERROR_INCOMPLETEOUTOFORDER) + error |= DFILE_ERROR_NOTLOADED; + } else + error = DFILE_ERROR_CANNOTLOAD; + } + + // Get final file count + nmusfilecount = 0; + + for (j = 0; j < numwadfiles; ++j) + if (wadfiles[j]->important && j > mainwads) + nmusfilecount++; + + if (!error && filesloaded < nmusfilecount) + error = DFILE_ERROR_EXTRAFILES; + + return error; +} + void G_SetDemoTime(UINT32 ptime, UINT32 pscore, UINT16 prings) { if (!demorecording || !demotime_p) @@ -1645,7 +1842,7 @@ UINT8 G_CmpDemoTime(char *oldname, char *newname) p += 2; // gamemap p += 16; // map md5 flags = READUINT8(p); // demoflags - + G_SkipDemoExtraFiles(&p); aflags = flags & (DF_RECORDATTACK|DF_NIGHTSATTACK); I_Assert(aflags); if (flags & DF_RECORDATTACK) @@ -1710,6 +1907,7 @@ UINT8 G_CmpDemoTime(char *oldname, char *newname) p += 2; // gamemap p += 16; // mapmd5 flags = READUINT8(p); + G_SkipDemoExtraFiles(&p); if (!(flags & aflags)) { CONS_Alert(CONS_NOTICE, M_GetText("File '%s' not from same game mode. It will be overwritten.\n"), oldname); @@ -1871,6 +2069,73 @@ void G_DoPlayDemo(char *defdemoname) demo_p += 16; // mapmd5 demoflags = READUINT8(demo_p); + + if (demoversion < 0x0010) + { + ; // Don't do anything with files. + } + else if (titledemo) + { + // Titledemos should always play and ought to always be compatible with whatever wadlist is running. + G_SkipDemoExtraFiles(&demo_p); + } + else if (demofileoverride == DFILE_OVERRIDE_LOAD) + { + G_LoadDemoExtraFiles(&demo_p); + } + else if (demofileoverride == DFILE_OVERRIDE_SKIP) + { + G_SkipDemoExtraFiles(&demo_p); + } + else + { + UINT8 error = G_CheckDemoExtraFiles(&demo_p, false); + + if (error) + { + switch (error) + { + case DFILE_ERROR_NOTLOADED: + snprintf(msg, 1024, + M_GetText("Required files for this demo are not loaded.\n\nUse\n\"playdemo %s -addfiles\"\nto load them and play the demo.\n"), + pdemoname); + break; + + case DFILE_ERROR_OUTOFORDER: + snprintf(msg, 1024, + M_GetText("Required files for this demo are loaded out of order.\n\nUse\n\"playdemo %s -force\"\nto play the demo anyway.\n"), + pdemoname); + break; + + case DFILE_ERROR_INCOMPLETEOUTOFORDER: + snprintf(msg, 1024, + M_GetText("Required files for this demo are not loaded, and some are out of order.\n\nUse\n\"playdemo %s -addfiles\"\nto load needed files and play the demo.\n"), + pdemoname); + break; + + case DFILE_ERROR_CANNOTLOAD: + snprintf(msg, 1024, + M_GetText("Required files for this demo cannot be loaded.\n\nUse\n\"playdemo %s -force\"\nto play the demo anyway.\n"), + pdemoname); + break; + + case DFILE_ERROR_EXTRAFILES: + snprintf(msg, 1024, + M_GetText("You have additional files loaded beyond the demo's file list.\n\nUse\n\"playdemo %s -force\"\nto play the demo anyway.\n"), + pdemoname); + break; + } + + CONS_Alert(CONS_ERROR, "%s", msg); + M_StartMessage(msg, NULL, MM_NOTHING); + Z_Free(pdemoname); + Z_Free(demobuffer); + demoplayback = false; + titledemo = false; + return; + } + } + modeattacking = (demoflags & DF_ATTACKMASK)>>DF_ATTACKSHIFT; CON_ToggleOff(); @@ -2026,6 +2291,91 @@ void G_DoPlayDemo(char *defdemoname) demo_start = true; } +// +// Check if a replay can be loaded from the menu +// +UINT8 G_CheckDemoForError(char *defdemoname) +{ + lumpnum_t l; + char *n,*pdemoname; + + n = defdemoname+strlen(defdemoname); + while (*n != '/' && *n != '\\' && n != defdemoname) + n--; + if (n != defdemoname) + n++; + pdemoname = ZZ_Alloc(strlen(n)+1); + strcpy(pdemoname,n); + + // Internal if no extension, external if one exists + if (FIL_CheckExtension(defdemoname)) + { + //FIL_DefaultExtension(defdemoname, ".lmp"); + if (!FIL_ReadFile(defdemoname, &demobuffer)) + { + return DFILE_ERROR_NOTDEMO; + } + demo_p = demobuffer; + } + // load demo resource from WAD + else if ((l = W_CheckNumForName(defdemoname)) == LUMPERROR) + { + return DFILE_ERROR_NOTDEMO; + } + else // it's an internal demo + { + demobuffer = demo_p = W_CacheLumpNum(l, PU_STATIC); + } + + // read demo header + if (memcmp(demo_p, DEMOHEADER, 12)) + { + return DFILE_ERROR_NOTDEMO; + } + demo_p += 12; // DEMOHEADER + + demo_p++; // version + demo_p++; // subversion + demoversion = READUINT16(demo_p); + switch(demoversion) + { + case 0x000d: + case 0x000e: + case 0x000f: + case DEMOVERSION: // latest always supported + break; +#ifdef OLD22DEMOCOMPAT + case 0x000c: + break; +#endif + // too old, cannot support. + default: + return DFILE_ERROR_NOTDEMO; + } + demo_p += 16; // demo checksum + if (memcmp(demo_p, "PLAY", 4)) + { + return DFILE_ERROR_NOTDEMO; + } + demo_p += 4; // "PLAY" + demo_p += 2; // gamemap + demo_p += 16; // mapmd5 + + demo_p++; // demoflags + + // Don't do anything with files. + if (demoversion < 0x0010) + { + return DFILE_ERROR_NONE; + } + else if (titledemo) + { + return DFILE_ERROR_NONE; + } + + return G_CheckDemoExtraFiles(&demo_p, true); +} + void G_AddGhost(char *defdemoname) { INT32 i; @@ -2130,6 +2480,9 @@ void G_AddGhost(char *defdemoname) Z_Free(buffer); return; } + + G_SkipDemoExtraFiles(&p); // Don't wanna modify the file list for ghosts. + switch ((flags & DF_ATTACKMASK)>>DF_ATTACKSHIFT) { case ATTACKING_NONE: // 0 diff --git a/src/g_demo.h b/src/g_demo.h index f25315a58..383d2719b 100644 --- a/src/g_demo.h +++ b/src/g_demo.h @@ -26,6 +26,15 @@ extern boolean demoplayback, titledemo, demorecording, timingdemo; extern tic_t demostarttime; +typedef enum +{ + DFILE_OVERRIDE_NONE = 0, // Show errors normally + DFILE_OVERRIDE_LOAD, // Forcefully load demo, add files beforehand + DFILE_OVERRIDE_SKIP, // Forcefully load demo, skip file list +} demo_file_override_e; + +extern demo_file_override_e demofileoverride; + // Quit after playing a demo from cmdline. extern boolean singledemo; extern boolean demo_start; @@ -53,6 +62,18 @@ typedef enum GHC_RETURNSKIN // ditto } ghostcolor_t; +// G_CheckDemoExtraFiles: checks if our loaded WAD list matches the demo's. +typedef enum +{ + DFILE_ERROR_NONE = 0, // No file error + DFILE_ERROR_NOTLOADED, // Files are not loaded, but can be without a restart. + DFILE_ERROR_OUTOFORDER, // Files are loaded, but out of order. + DFILE_ERROR_INCOMPLETEOUTOFORDER, // Some files are loaded out of order, but others are not. + DFILE_ERROR_CANNOTLOAD, // Files are missing and cannot be loaded. + DFILE_ERROR_EXTRAFILES, // Extra files outside of the replay's file list are loaded. + DFILE_ERROR_NOTDEMO = UINT8_MAX, // This replay isn't even a replay... +} demo_file_error_e; + // Record/playback tics void G_ReadDemoTiccmd(ticcmd_t *cmd, INT32 playernum); void G_WriteDemoTiccmd(ticcmd_t *cmd, INT32 playernum); @@ -83,5 +104,6 @@ ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(boolean kill); void G_StopDemo(void); boolean G_CheckDemoStatus(void); INT32 G_ConvertOldFrameFlags(INT32 frame); +UINT8 G_CheckDemoForError(char *defdemoname); #endif // __G_DEMO__ diff --git a/src/m_menu.c b/src/m_menu.c index 12003f945..828fc1aee 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -3500,10 +3500,10 @@ boolean M_Responder(event_t *ev) #ifndef DEVELOP // TODO: Replays are scary, so I left the remaining instances of this alone. // It'd be nice to get rid of this once and for all though! - if (((currentMenu->menuitems[itemOn].status & IT_CALLTYPE) & IT_CALL_NOTMODIFIED) && (modifiedgame && !savemoddata) && !usedCheats) + if (((currentMenu->menuitems[itemOn].status & IT_CALLTYPE) & IT_CALL_NOTMODIFIED) && usedCheats) { S_StartSound(NULL, sfx_skid); - M_StartMessage(M_GetText("This cannot be done in a modified game.\n\n(Press a key)\n"), NULL, MM_NOTHING); + M_StartMessage(M_GetText("This cannot be done in a cheated game.\n\n(Press a key)\n"), NULL, MM_NOTHING); return true; } #endif @@ -10449,13 +10449,23 @@ static void M_ChooseTimeAttack(INT32 choice) G_DeferedInitNew(false, G_BuildMapName(cv_nextmap.value), (UINT8)(cv_chooseskin.value-1), false, false); } +static char ra_demoname[1024]; + +static void M_StartTimeAttackReplay(INT32 choice) +{ + if (choice == 'y' || choice == KEY_ENTER) + { + M_ClearMenus(true); + modeattacking = ATTACKING_RECORD; // set modeattacking before G_DoPlayDemo so the map loader knows + G_DoPlayDemo(ra_demoname); + } +} + // Player has selected the "REPLAY" from the time attack screen static void M_ReplayTimeAttack(INT32 choice) { const char *which; - char *demoname; - M_ClearMenus(true); - modeattacking = ATTACKING_RECORD; // set modeattacking before G_DoPlayDemo so the map loader knows + UINT8 error = DFILE_ERROR_NONE; if (currentMenu == &SP_ReplayDef) { @@ -10475,11 +10485,15 @@ static void M_ReplayTimeAttack(INT32 choice) break; case 4: // guest // srb2/replay/main/map01-guest.lmp - G_DoPlayDemo(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value))); - return; + snprintf(ra_demoname, 1024, "%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value)); + break; + } + + if (choice != 4) + { + // srb2/replay/main/map01-sonic-time-best.lmp + snprintf(ra_demoname, 1024, "%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), skins[cv_chooseskin.value-1].name, which); } - // srb2/replay/main/map01-sonic-time-best.lmp - G_DoPlayDemo(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), skins[cv_chooseskin.value-1].name, which)); } else if (currentMenu == &SP_NightsReplayDef) { @@ -10495,19 +10509,66 @@ static void M_ReplayTimeAttack(INT32 choice) which = "last"; break; case 3: // guest - G_DoPlayDemo(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value))); - return; + snprintf(ra_demoname, 1024, "%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value)); + break; } - demoname = va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), skins[cv_chooseskin.value-1].name, which); + if (choice != 3) + { + snprintf(ra_demoname, 1024, "%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), skins[cv_chooseskin.value-1].name, which); #ifdef OLDNREPLAYNAME // Check for old style named NiGHTS replay if a new style replay doesn't exist. - if (!FIL_FileExists(demoname)) - demoname = va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), which); + if (!FIL_FileExists(ra_demoname)) + { + snprintf(ra_demoname, 1024, "%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), which); + } #endif - - G_DoPlayDemo(demoname); + } } + + demofileoverride = DFILE_OVERRIDE_NONE; + error = G_CheckDemoForError(ra_demoname); + + if (error) + { + S_StartSound(NULL, sfx_skid); + + switch (error) + { + case DFILE_ERROR_NOTDEMO: + M_StartMessage(M_GetText("An error occurred loading this replay.\n\n(Press a key)\n"), NULL, MM_NOTHING); + break; + + case DFILE_ERROR_NOTLOADED: + demofileoverride = DFILE_OVERRIDE_LOAD; + M_StartMessage(M_GetText("Add-ons for this replay\nhave not been loaded.\n\nAttempt to load files?\n\n(Press 'Y' to confirm)\n"), M_StartTimeAttackReplay, MM_YESNO); + break; + + case DFILE_ERROR_OUTOFORDER: + demofileoverride = DFILE_OVERRIDE_SKIP; + M_StartMessage(M_GetText("Add-ons for this replay\nwere loaded out of order.\n\nAttempt to playback anyway?\n\n(Press 'Y' to confirm)\n"), M_StartTimeAttackReplay, MM_YESNO); + break; + + case DFILE_ERROR_INCOMPLETEOUTOFORDER: + demofileoverride = DFILE_OVERRIDE_LOAD; + M_StartMessage(M_GetText("Add-ons for this replay\nhave not been loaded,\nand some are in the wrong order.\n\nAttempt to load files?\n\n(Press 'Y' to confirm)\n"), M_StartTimeAttackReplay, MM_YESNO); + break; + + case DFILE_ERROR_CANNOTLOAD: + demofileoverride = DFILE_OVERRIDE_SKIP; + M_StartMessage(M_GetText("Add-ons for this replay\ncould not be loaded.\n\nAttempt to playback anyway?\n\n(Press 'Y' to confirm)\n"), M_StartTimeAttackReplay, MM_YESNO); + break; + + case DFILE_ERROR_EXTRAFILES: + demofileoverride = DFILE_OVERRIDE_SKIP; + M_StartMessage(M_GetText("You have more files loaded\nthan the replay does.\n\nAttempt to playback anyway?\n\n(Press 'Y' to confirm)\n"), M_StartTimeAttackReplay, MM_YESNO); + break; + } + + return; + } + + M_StartTimeAttackReplay(KEY_ENTER); } static void M_EraseGuest(INT32 choice) From f99cf91d3ddd08ec58ff099f588fd85819c3842f Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 25 Jul 2023 09:29:09 -0400 Subject: [PATCH 291/586] Promote file count to UINT16 --- src/g_demo.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/g_demo.c b/src/g_demo.c index 230f6da2d..8c6064c57 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -1416,7 +1416,7 @@ void G_BeginRecording(void) player_t *player = &players[consoleplayer]; char *filename; - UINT8 totalfiles; + UINT16 totalfiles; UINT8 *m; if (demo_p) @@ -1459,7 +1459,7 @@ void G_BeginRecording(void) } } - WRITEUINT8(m, totalfiles); + WRITEUINT16(m, totalfiles); switch ((demoflags & DF_ATTACKMASK)>>DF_ATTACKSHIFT) { @@ -1618,15 +1618,15 @@ void G_BeginMetal(void) static void G_LoadDemoExtraFiles(UINT8 **pp) { - UINT8 totalfiles; + UINT16 totalfiles; char filename[MAX_WADPATH]; UINT8 md5sum[16]; filestatus_t ncs; boolean toomany = false; boolean alreadyloaded; - UINT8 i, j; + UINT16 i, j; - totalfiles = READUINT8((*pp)); + totalfiles = READUINT16((*pp)); for (i = 0; i < totalfiles; ++i) { if (toomany) @@ -1687,8 +1687,8 @@ static void G_LoadDemoExtraFiles(UINT8 **pp) static void G_SkipDemoExtraFiles(UINT8 **pp) { - UINT8 totalfiles; - UINT8 i; + UINT16 totalfiles; + UINT16 i; if (demoversion < 0x0010) { @@ -1696,7 +1696,7 @@ static void G_SkipDemoExtraFiles(UINT8 **pp) return; } - totalfiles = READUINT8((*pp)); + totalfiles = READUINT16((*pp)); for (i = 0; i < totalfiles; ++i) { SKIPSTRING((*pp));// file name @@ -1708,12 +1708,12 @@ static void G_SkipDemoExtraFiles(UINT8 **pp) // Enabling quick prevents filesystem checks to see if needed files are available to load. static UINT8 G_CheckDemoExtraFiles(UINT8 **pp, boolean quick) { - UINT8 totalfiles, filesloaded, nmusfilecount; + UINT16 totalfiles, filesloaded, nmusfilecount; char filename[MAX_WADPATH]; UINT8 md5sum[16]; boolean toomany = false; boolean alreadyloaded; - UINT8 i, j; + UINT16 i, j; UINT8 error = DFILE_ERROR_NONE; if (demoversion < 0x0010) @@ -1722,7 +1722,7 @@ static UINT8 G_CheckDemoExtraFiles(UINT8 **pp, boolean quick) return DFILE_ERROR_NONE; } - totalfiles = READUINT8((*pp)); + totalfiles = READUINT16((*pp)); filesloaded = 0; for (i = 0; i < totalfiles; ++i) { From dded3522933aaa068f564c024096c97a174166c0 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 25 Jul 2023 09:34:55 -0400 Subject: [PATCH 292/586] Harsher replay menu Don't allow loading demos with invalid file lists at all. If you insist on doing this, it has to be done from the command line now. --- src/g_demo.c | 2 +- src/m_menu.c | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/g_demo.c b/src/g_demo.c index 8c6064c57..438d3dfc9 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -1444,7 +1444,7 @@ void G_BeginRecording(void) // file list m = demo_p;/* file count */ - demo_p += 1; + demo_p += 2; totalfiles = 0; for (i = mainwads; ++i < numwadfiles; ) diff --git a/src/m_menu.c b/src/m_menu.c index 828fc1aee..21ba98dd2 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -10545,23 +10545,35 @@ static void M_ReplayTimeAttack(INT32 choice) break; case DFILE_ERROR_OUTOFORDER: + /* demofileoverride = DFILE_OVERRIDE_SKIP; M_StartMessage(M_GetText("Add-ons for this replay\nwere loaded out of order.\n\nAttempt to playback anyway?\n\n(Press 'Y' to confirm)\n"), M_StartTimeAttackReplay, MM_YESNO); + */ + M_StartMessage(M_GetText("Add-ons for this replay\nwere loaded out of order.\n\n(Press a key)\n"), NULL, MM_NOTHING); break; case DFILE_ERROR_INCOMPLETEOUTOFORDER: + /* demofileoverride = DFILE_OVERRIDE_LOAD; M_StartMessage(M_GetText("Add-ons for this replay\nhave not been loaded,\nand some are in the wrong order.\n\nAttempt to load files?\n\n(Press 'Y' to confirm)\n"), M_StartTimeAttackReplay, MM_YESNO); + */ + M_StartMessage(M_GetText("Add-ons for this replay\nhave not been loaded,\nand some are in the wrong order.\n\n(Press a key)\n"), NULL, MM_NOTHING); break; case DFILE_ERROR_CANNOTLOAD: + /* demofileoverride = DFILE_OVERRIDE_SKIP; M_StartMessage(M_GetText("Add-ons for this replay\ncould not be loaded.\n\nAttempt to playback anyway?\n\n(Press 'Y' to confirm)\n"), M_StartTimeAttackReplay, MM_YESNO); + */ + M_StartMessage(M_GetText("Add-ons for this replay\ncould not be loaded.\n\n(Press a key)\n"), NULL, MM_NOTHING); break; case DFILE_ERROR_EXTRAFILES: + /* demofileoverride = DFILE_OVERRIDE_SKIP; M_StartMessage(M_GetText("You have more files loaded\nthan the replay does.\n\nAttempt to playback anyway?\n\n(Press 'Y' to confirm)\n"), M_StartTimeAttackReplay, MM_YESNO); + */ + M_StartMessage(M_GetText("You have more files loaded\nthan the replay does.\n\n(Press a key)\n"), NULL, MM_NOTHING); break; } From 0e2682d5908bf825d6125664144fe70ba20c9b9b Mon Sep 17 00:00:00 2001 From: Zwip-Zwap Zapony Date: Fri, 30 Jun 2023 00:09:20 +0200 Subject: [PATCH 293/586] Add "drawonlyforplayer" and "dontdrawforviewmobj" --- src/b_bot.c | 3 +- src/g_game.c | 1 + src/lua_baselib.c | 3 +- src/lua_mobjlib.c | 33 ++++++++++++ src/p_mobj.c | 6 +-- src/p_mobj.h | 2 + src/p_saveg.c | 69 +++++++++++++++--------- src/p_user.c | 130 +++++++++++++++++++++++++++++++++------------- src/r_things.c | 11 ++-- 9 files changed, 188 insertions(+), 70 deletions(-) diff --git a/src/b_bot.c b/src/b_bot.c index d1465f891..57f762304 100644 --- a/src/b_bot.c +++ b/src/b_bot.c @@ -631,7 +631,8 @@ void B_HandleFlightIndicator(player_t *player) } // otherwise, update its visibility - if (P_IsLocalPlayer(player->botleader)) + tails->hnext->drawonlyforplayer = player->botleader; // Hide it from the other player in splitscreen, and yourself when spectating + if (P_IsLocalPlayer(player->botleader)) // Only display it on your own view. Don't display it for spectators tails->hnext->flags2 &= ~MF2_DONTDRAW; else tails->hnext->flags2 |= MF2_DONTDRAW; diff --git a/src/g_game.c b/src/g_game.c index 15b1e1081..8264fbe6b 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1441,6 +1441,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) // I assume this is netgame-safe because gunslinger spawns this for only the local player...... *sweats intensely* 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]); + newtarget->drawonlyforplayer = player; // Hide it from the other player in splitscreen, and yourself when spectating if (player->mo && P_AproxDistance( player->mo->x - ticcmd_ztargetfocus[forplayer]->x, diff --git a/src/lua_baselib.c b/src/lua_baselib.c index ed5736fa7..838e2f53b 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -689,11 +689,12 @@ static int lib_pSpawnLockOn(lua_State *L) return LUA_ErrInvalid(L, "player_t"); if (state >= NUMSTATES) return luaL_error(L, "state %d out of range (0 - %d)", state, NUMSTATES-1); - if (P_IsLocalPlayer(player)) // Only display it on your own view. + if (P_IsLocalPlayer(player)) // Only display it on your own view. Don't display it for spectators { mobj_t *visual = P_SpawnMobj(lockon->x, lockon->y, lockon->z, MT_LOCKON); // positioning, flip handled in P_SceneryThinker P_SetTarget(&visual->target, lockon); visual->flags2 |= MF2_DONTDRAW; + visual->drawonlyforplayer = player; // Hide it from the other player in splitscreen, and yourself when spectating P_SetMobjStateNF(visual, state); } return 0; diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index 851c569d2..fd8dcec92 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -44,6 +44,8 @@ enum mobj_e { mobj_spritexoffset, mobj_spriteyoffset, mobj_floorspriteslope, + mobj_drawonlyforplayer, + mobj_dontdrawforviewmobj, mobj_touching_sectorlist, mobj_subsector, mobj_floorz, @@ -122,6 +124,8 @@ static const char *const mobj_opt[] = { "spritexoffset", "spriteyoffset", "floorspriteslope", + "drawonlyforplayer", + "dontdrawforviewmobj", "touching_sectorlist", "subsector", "floorz", @@ -262,6 +266,17 @@ static int mobj_get(lua_State *L) case mobj_floorspriteslope: LUA_PushUserdata(L, mo->floorspriteslope, META_SLOPE); break; + case mobj_drawonlyforplayer: + LUA_PushUserdata(L, mo->drawonlyforplayer, META_PLAYER); + break; + case mobj_dontdrawforviewmobj: + if (mo->dontdrawforviewmobj && P_MobjWasRemoved(mo->dontdrawforviewmobj)) + { // don't put invalid mobj back into Lua. + P_SetTarget(&mo->dontdrawforviewmobj, NULL); + return 0; + } + LUA_PushUserdata(L, mo->dontdrawforviewmobj, META_MOBJ); + break; case mobj_touching_sectorlist: return UNIMPLEMENTED; case mobj_subsector: @@ -551,6 +566,24 @@ static int mobj_set(lua_State *L) break; case mobj_floorspriteslope: return NOSET; + case mobj_drawonlyforplayer: + if (lua_isnil(L, 3)) + mo->drawonlyforplayer = NULL; + else + { + player_t *drawonlyforplayer = *((player_t **)luaL_checkudata(L, 3, META_PLAYER)); + mo->drawonlyforplayer = drawonlyforplayer; + } + break; + case mobj_dontdrawforviewmobj: + if (lua_isnil(L, 3)) + P_SetTarget(&mo->dontdrawforviewmobj, NULL); + else + { + mobj_t *dontdrawforviewmobj = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); + P_SetTarget(&mo->dontdrawforviewmobj, dontdrawforviewmobj); + } + break; case mobj_touching_sectorlist: return UNIMPLEMENTED; case mobj_subsector: diff --git a/src/p_mobj.c b/src/p_mobj.c index a25b5643b..4ca59285f 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6882,6 +6882,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->player ? mo->target->player->drawangle : mo->target->angle) + mo->movedir; + P_SetTarget(&mo->dontdrawforviewmobj, mo->target->dontdrawforviewmobj); // Hide the overlay from the view that its target is hidden from - But don't copy drawonlyforplayer! if (!(mo->state->frame & FF_ANIMATE)) zoffs = FixedMul(((signed)mo->state->var2)*FRACUNIT, mo->scale); @@ -7951,11 +7952,6 @@ static void P_MobjSceneryThink(mobj_t *mobj) return; } - if (!camera.chase) - mobj->flags2 |= MF2_DONTDRAW; - else - mobj->flags2 &= ~MF2_DONTDRAW; - P_UnsetThingPosition(mobj); { fixed_t radius = FixedMul(10*mobj->info->speed, mobj->target->scale); diff --git a/src/p_mobj.h b/src/p_mobj.h index 6a5ab84c4..9c598f59e 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -334,6 +334,8 @@ typedef struct mobj_s // Player and mobj sprites in multiplayer modes are modified // using an internal color lookup table for re-indexing. UINT16 color; // This replaces MF_TRANSLATION. Use 0 for default (no translation). + struct player_s *drawonlyforplayer; // If set, hides the mobj for everyone except this player and their spectators + struct mobj_s *dontdrawforviewmobj; // If set, hides the mobj if dontdrawforviewmobj is the current camera (first-person player or awayviewmobj) // Interaction info, by BLOCKMAP. // Links in blocks (if needed). diff --git a/src/p_saveg.c b/src/p_saveg.c index 76f1661ac..8f11e63e5 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1553,30 +1553,32 @@ typedef enum typedef enum { - MD2_CUSVAL = 1, - MD2_CVMEM = 1<<1, - MD2_SKIN = 1<<2, - MD2_COLOR = 1<<3, - MD2_SCALESPEED = 1<<4, - MD2_EXTVAL1 = 1<<5, - MD2_EXTVAL2 = 1<<6, - MD2_HNEXT = 1<<7, - MD2_HPREV = 1<<8, - MD2_FLOORROVER = 1<<9, - MD2_CEILINGROVER = 1<<10, - MD2_SLOPE = 1<<11, - MD2_COLORIZED = 1<<12, - MD2_MIRRORED = 1<<13, - MD2_SPRITEROLL = 1<<14, - MD2_SHADOWSCALE = 1<<15, - MD2_RENDERFLAGS = 1<<16, - MD2_BLENDMODE = 1<<17, - MD2_SPRITEXSCALE = 1<<18, - MD2_SPRITEYSCALE = 1<<19, - MD2_SPRITEXOFFSET = 1<<20, - MD2_SPRITEYOFFSET = 1<<21, - MD2_FLOORSPRITESLOPE = 1<<22, - MD2_DISPOFFSET = 1<<23 + MD2_CUSVAL = 1, + MD2_CVMEM = 1<<1, + MD2_SKIN = 1<<2, + MD2_COLOR = 1<<3, + MD2_SCALESPEED = 1<<4, + MD2_EXTVAL1 = 1<<5, + MD2_EXTVAL2 = 1<<6, + MD2_HNEXT = 1<<7, + MD2_HPREV = 1<<8, + MD2_FLOORROVER = 1<<9, + MD2_CEILINGROVER = 1<<10, + MD2_SLOPE = 1<<11, + MD2_COLORIZED = 1<<12, + MD2_MIRRORED = 1<<13, + MD2_SPRITEROLL = 1<<14, + MD2_SHADOWSCALE = 1<<15, + MD2_RENDERFLAGS = 1<<16, + MD2_BLENDMODE = 1<<17, + MD2_SPRITEXSCALE = 1<<18, + MD2_SPRITEYSCALE = 1<<19, + MD2_SPRITEXOFFSET = 1<<20, + MD2_SPRITEYOFFSET = 1<<21, + MD2_FLOORSPRITESLOPE = 1<<22, + MD2_DISPOFFSET = 1<<23, + MD2_DRAWONLYFORPLAYER = 1<<24, + MD2_DONTDRAWFORVIEWMOBJ = 1<<25 } mobj_diff2_t; typedef enum @@ -1811,6 +1813,10 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) || (slope->normal.z != FRACUNIT)) diff2 |= MD2_FLOORSPRITESLOPE; } + if (mobj->drawonlyforplayer) + diff2 |= MD2_DRAWONLYFORPLAYER; + if (mobj->dontdrawforviewmobj) + diff2 |= MD2_DONTDRAWFORVIEWMOBJ; if (mobj->dispoffset != mobj->info->dispoffset) diff2 |= MD2_DISPOFFSET; @@ -1988,6 +1994,10 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) WRITEFIXED(save_p, slope->normal.y); WRITEFIXED(save_p, slope->normal.z); } + if (diff2 & MD2_DRAWONLYFORPLAYER) + WRITEUINT8(save_p, mobj->drawonlyforplayer-players); + if (diff2 & MD2_DONTDRAWFORVIEWMOBJ) + WRITEUINT32(save_p, mobj->dontdrawforviewmobj->mobjnum); if (diff2 & MD2_DISPOFFSET) WRITEINT32(save_p, mobj->dispoffset); @@ -3044,6 +3054,10 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) slope->normal.y = READFIXED(save_p); slope->normal.z = READFIXED(save_p); } + if (diff2 & MD2_DRAWONLYFORPLAYER) + mobj->drawonlyforplayer = &players[READUINT8(save_p)]; + if (diff2 & MD2_DONTDRAWFORVIEWMOBJ) + mobj->dontdrawforviewmobj = (mobj_t *)(size_t)READUINT32(save_p); if (diff2 & MD2_DISPOFFSET) mobj->dispoffset = READINT32(save_p); else @@ -4063,6 +4077,13 @@ static void P_RelinkPointers(void) if (mobj->type == MT_HOOP || mobj->type == MT_HOOPCOLLIDE || mobj->type == MT_HOOPCENTER) continue; + if (mobj->dontdrawforviewmobj) + { + temp = (UINT32)(size_t)mobj->dontdrawforviewmobj; + mobj->dontdrawforviewmobj = NULL; + if (!P_SetTarget(&mobj->dontdrawforviewmobj, P_FindNewPosition(temp))) + CONS_Debug(DBG_GAMELOGIC, "dontdrawforviewmobj not found on %d\n", mobj->type); + } if (mobj->tracer) { temp = (UINT32)(size_t)mobj->tracer; diff --git a/src/p_user.c b/src/p_user.c index 62dd2fcb2..889e887c1 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -398,6 +398,7 @@ void P_GiveFinishFlags(player_t *player) angle += FixedAngle(120*FRACUNIT); P_SetTarget(&flag->target, player->mo); + P_SetTarget(&flag->dontdrawforviewmobj, player->mo); // Hide the flag in first-person } } @@ -1840,6 +1841,7 @@ void P_SpawnShieldOrb(player_t *player) shieldobj = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, orbtype); shieldobj->flags2 |= MF2_SHIELD; P_SetTarget(&shieldobj->target, player->mo); + P_SetTarget(&shieldobj->dontdrawforviewmobj, player->mo); // Hide the shield in first-person if ((player->powers[pw_shield] & SH_NOSTACK) == SH_PINK) { shieldobj->color = SKINCOLOR_PINK; @@ -1964,6 +1966,7 @@ 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_SetTarget(&ghost->dontdrawforviewmobj, mobj); // Hide the ghost in first-person P_SetScale(ghost, mobj->scale); ghost->destscale = mobj->scale; @@ -2009,6 +2012,7 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj) mobj_t *ghost2 = P_SpawnGhostMobj(mobj->player->followmobj); P_SetTarget(&ghost2->tracer, ghost); P_SetTarget(&ghost->tracer, ghost2); + P_SetTarget(&ghost2->dontdrawforviewmobj, mobj); // Hide the follow-ghost for the non-follow object ghost2->flags2 |= (mobj->player->followmobj->flags2 & MF2_LINKDRAW); } @@ -3123,39 +3127,41 @@ static void P_DoBubbleBreath(player_t *player) // static void P_DoPlayerHeadSigns(player_t *player) { + mobj_t *sign = NULL; + if (G_TagGametype()) { - // If you're "IT", show a big "IT" over your head for others to see. - if (player->pflags & PF_TAGIT && !P_IsLocalPlayer(player)) + // If you're "IT", show a big "IT" over your head for others to see, including spectators + // (and even yourself if you spectate someone else). + if (player->pflags & PF_TAGIT && (!P_IsLocalPlayer(player) || consoleplayer != displayplayer || splitscreen)) { - mobj_t* it = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_TAG); - it->x = player->mo->x; - it->y = player->mo->y; - it->z = player->mo->z; - it->old_x = player->mo->old_x; - it->old_y = player->mo->old_y; - it->old_z = player->mo->old_z; + sign = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_TAG); + sign->x = player->mo->x; + sign->y = player->mo->y; + sign->z = player->mo->z; + sign->old_x = player->mo->old_x; + sign->old_y = player->mo->old_y; + sign->old_z = player->mo->old_z; if (!(player->mo->eflags & MFE_VERTICALFLIP)) { - it->z += player->mo->height; - it->old_z += player->mo->height; + sign->z += player->mo->height; + sign->old_z += player->mo->height; } else { - it->z -= mobjinfo[MT_TAG].height; - it->old_z -= mobjinfo[MT_TAG].height; + sign->z -= mobjinfo[MT_TAG].height; + sign->old_z -= mobjinfo[MT_TAG].height; } } } else if ((gametyperules & GTR_TEAMFLAGS) && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG))) // If you have the flag (duh). { - // Spawn a got-flag message over the head of the player that - // has it (but not on your own screen if you have the flag). - if (splitscreen || player != &players[consoleplayer]) + // Spawn a got-flag message over the head of the player that has it + // (but not on your own screen if you have the flag, unless you're spectating). + if (!P_IsLocalPlayer(player) || consoleplayer != displayplayer || splitscreen) { fixed_t zofs; - mobj_t *sign; boolean player_is_flipped = (player->mo->eflags & MFE_VERTICALFLIP) > 0; zofs = player->mo->momz; @@ -3187,6 +3193,43 @@ static void P_DoPlayerHeadSigns(player_t *player) sign->frame = 2|FF_FULLBRIGHT; } } + + if (!P_MobjWasRemoved(sign) && splitscreen) // Hide the sign from yourself in splitscreen - In single-screen, it wouldn't get spawned if it shouldn't be visible + { + if (player == &players[displayplayer]) + sign->drawonlyforplayer = &players[secondarydisplayplayer]; + else + sign->drawonlyforplayer = &players[displayplayer]; + +#ifdef QUADS + if (splitscreen > 1) // Can be seen by at least two local views, so we need an extra copy of the sign + { + UINT32 signframe = sign->frame; // Copy the flag frame + sign = P_SpawnMobjFromMobj(sign, 0, 0, 0, MT_TAG); + if (P_MobjWasRemoved(sign)) + return; + + sign->frame = signframe; + if (player == &players[displayplayer] || player == &players[secondarydisplayplayer]) + sign->drawonlyforplayer = &players[thirddisplayplayer]; + else + sign->drawonlyforplayer = &players[secondarydisplayplayer]; + + if (splitscreen > 2) // Can be seen by three local views + { + sign = P_SpawnMobjFromMobj(sign, 0, 0, 0, MT_TAG); + if (P_MobjWasRemoved(sign)) + return; + + sign->frame = signframe; + if (player != &players[fourthdisplayplayer]) + sign->drawonlyforplayer = &players[fourthdisplayplayer]; + else + sign->drawonlyforplayer = &players[thirddisplayplayer]; + } + } +#endif + } } // @@ -4707,10 +4750,11 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) mobj_t *lockon = P_LookForEnemies(player, false, true); if (lockon) { - if (P_IsLocalPlayer(player)) // Only display it on your own view. + if (P_IsLocalPlayer(player)) // Only display it on your own view. Don't display it for spectators { mobj_t *visual = P_SpawnMobj(lockon->x, lockon->y, lockon->z, MT_LOCKON); // positioning, flip handled in P_SceneryThinker P_SetTarget(&visual->target, lockon); + visual->drawonlyforplayer = player; // Hide it from the other player in splitscreen, and yourself when spectating } } if ((cmd->buttons & BT_SPIN) && !(player->pflags & PF_SPINDOWN)) @@ -5054,7 +5098,7 @@ static boolean P_PlayerShieldThink(player_t *player, ticcmd_t *cmd, mobj_t *lock { if ((lockonshield = P_LookForEnemies(player, false, false))) { - if (P_IsLocalPlayer(player)) // Only display it on your own view. + if (P_IsLocalPlayer(player)) // Only display it on your own view. Don't display it for spectators { boolean dovis = true; if (lockonshield == lockonthok) @@ -5068,6 +5112,7 @@ static boolean P_PlayerShieldThink(player_t *player, ticcmd_t *cmd, mobj_t *lock { visual = P_SpawnMobj(lockonshield->x, lockonshield->y, lockonshield->z, MT_LOCKON); // positioning, flip handled in P_SceneryThinker P_SetTarget(&visual->target, lockonshield); + visual->drawonlyforplayer = player; // Hide it from the other player in splitscreen, and yourself when spectating P_SetMobjStateNF(visual, visual->info->spawnstate+1); } } @@ -5171,10 +5216,11 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) if ((player->charability == CA_HOMINGTHOK) && !player->homing && (player->pflags & PF_JUMPED) && (!(player->pflags & PF_THOKKED) || (player->charflags & SF_MULTIABILITY)) && (lockonthok = P_LookForEnemies(player, true, false))) { - if (P_IsLocalPlayer(player)) // Only display it on your own view. + if (P_IsLocalPlayer(player)) // Only display it on your own view. Don't display it for spectators { visual = P_SpawnMobj(lockonthok->x, lockonthok->y, lockonthok->z, MT_LOCKON); // positioning, flip handled in P_SceneryThinker P_SetTarget(&visual->target, lockonthok); + visual->drawonlyforplayer = player; // Hide it from the other player in splitscreen, and yourself when spectating } } @@ -11084,17 +11130,30 @@ static void P_MinecartThink(player_t *player) // Mark interpolation; the old positions need to be relative to the displacement from the minecart _after_ it's moved. // This isn't quite correct (it captures the landing wobble) but it works well enough + // Additionally, hide other players' marks if (detleft) { - detleft->old_x = detleft->x - (minecart->old_x - minecart->old_x2); - detleft->old_y = detleft->y - (minecart->old_y - minecart->old_y2); - detleft->old_z = detleft->z - (minecart->old_z - minecart->old_z2); + if (P_IsLocalPlayer(player)) + { + detleft->old_x = detleft->x - (minecart->old_x - minecart->old_x2); + detleft->old_y = detleft->y - (minecart->old_y - minecart->old_y2); + detleft->old_z = detleft->z - (minecart->old_z - minecart->old_z2); + detleft->drawonlyforplayer = player; // Hide it from the other player in splitscreen, and yourself when spectating + } + else // Don't see others' marks when spectating others + P_RemoveMobj(detleft); // Lock-on markers are only spawned client-side, so this SHOULD be safe too... } if (detright) { - detright->old_x = detright->x - (minecart->old_x - minecart->old_x2); - detright->old_y = detright->y - (minecart->old_y - minecart->old_y2); - detright->old_z = detright->z - (minecart->old_z - minecart->old_z2); + if (P_IsLocalPlayer(player)) + { + detright->old_x = detright->x - (minecart->old_x - minecart->old_x2); + detright->old_y = detright->y - (minecart->old_y - minecart->old_y2); + detright->old_z = detright->z - (minecart->old_z - minecart->old_z2); + detright->drawonlyforplayer = player; + } + else + P_RemoveMobj(detleft); } } else @@ -11386,12 +11445,15 @@ static void P_DoMetalJetFume(player_t *player, mobj_t *fume) for (i = -1; i < 2; i += 2) { + mobj_t *bubble; offsetH = i*P_ReturnThrustX(fume, fume->movedir, radiusV); 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 + heightoffset + offsetV; - P_SpawnMobj(x, y, z, MT_SMALLBUBBLE)->scale = mo->scale >> 1; + bubble = P_SpawnMobj(x, y, z, MT_SMALLBUBBLE); + bubble->scale = mo->scale >> 1; + P_SetTarget(&bubble->dontdrawforviewmobj, mo); // Hide the bubble in first-person } fume->movefactor = 0; @@ -11460,7 +11522,11 @@ static void P_DoMetalJetFume(player_t *player, mobj_t *fume) // If dashmode is high enough, spawn a trail if (player->normalspeed >= skins[player->skin].normalspeed*2) - P_SpawnGhostMobj(fume); + { + mobj_t *ghost = P_SpawnGhostMobj(fume); + if (!P_MobjWasRemoved(ghost)) + P_SetTarget(&ghost->dontdrawforviewmobj, mo); // Hide the trail in first-person + } } // @@ -12104,14 +12170,6 @@ void P_PlayerThink(player_t *player) gmobj->tracer->frame |= tr_trans70<flags2 |= MF2_DONTDRAW; } #endif diff --git a/src/r_things.c b/src/r_things.c index 248357e11..eee284d46 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -3322,9 +3322,14 @@ void R_ClipSprites(drawseg_t* dsstart, portal_t* portal) boolean R_ThingVisible (mobj_t *thing) { return (!( - thing->sprite == SPR_NULL || - ( thing->flags2 & (MF2_DONTDRAW) ) || - (r_viewmobj && (thing == r_viewmobj || (r_viewmobj->player && r_viewmobj->player->followmobj == thing))) + (thing->sprite == SPR_NULL) || // Don't draw null-sprites + (thing->flags2 & MF2_DONTDRAW) || // Don't draw MF2_LINKDRAW objects + (thing->drawonlyforplayer && thing->drawonlyforplayer != viewplayer) || // Don't draw other players' personal objects + (r_viewmobj && ( + (r_viewmobj == thing) || // Don't draw first-person players or awayviewmobj objects + (r_viewmobj->player && r_viewmobj->player->followmobj == thing) || // Don't draw first-person players' followmobj + (r_viewmobj == thing->dontdrawforviewmobj) // Don't draw objects that are hidden for the current view + )) )); } From 10a8f2d05ec81ab1f348b139a9452afb27accc27 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 25 Jul 2023 11:30:55 -0400 Subject: [PATCH 294/586] Fix some minor warnings - Fix `lib_getSkinSprite` overshadowing `sprites` global - Rename terrible result_e `ok` so it stops overshadowing crap - Remove inlining from w_wad.c since it reached the inline limit (remember kids, your compiler knows better than you these days whenever or not to inline something) - Remove unused variable in G_PlayerReborn --- src/g_game.c | 1 - src/lua_skinlib.c | 4 ++-- src/p_floor.c | 8 ++++---- src/p_spec.h | 2 +- src/w_wad.c | 10 +++++----- 5 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 8264fbe6b..b8c434998 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2547,7 +2547,6 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) { player_t *p; INT32 score; - INT32 recordscore; INT32 lives; INT32 continues; fixed_t camerascale; diff --git a/src/lua_skinlib.c b/src/lua_skinlib.c index b7890a6c7..13e0dd987 100644 --- a/src/lua_skinlib.c +++ b/src/lua_skinlib.c @@ -334,13 +334,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 *sksprites = *(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_PushUserdata(L, &sprites[i], META_SKINSPRITESLIST); + LUA_PushUserdata(L, &sksprites[i], META_SKINSPRITESLIST); return 1; } diff --git a/src/p_floor.c b/src/p_floor.c index 9c24f5851..38f0c5a0f 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -155,7 +155,7 @@ result_e T_MovePlane(sector_t *sector, fixed_t speed, fixed_t dest, boolean crus } } - return ok; + return planeok; } // @@ -1128,7 +1128,7 @@ void T_ThwompSector(thwomp_t *thwomp) thwomp->direction // direction ); - if (res == ok || res == pastdest) + if (res == planeok || res == pastdest) T_MovePlane ( thwomp->sector, // sector @@ -1160,7 +1160,7 @@ void T_ThwompSector(thwomp_t *thwomp) thwomp->direction // direction ); - if (res == ok || res == pastdest) + if (res == planeok || res == pastdest) T_MovePlane ( thwomp->sector, // sector @@ -1465,7 +1465,7 @@ void T_RaiseSector(raise_t *raise) direction // direction ); - if (res == ok || res == pastdest) + if (res == planeok || res == pastdest) T_MovePlane ( raise->sector, // sector diff --git a/src/p_spec.h b/src/p_spec.h index c8701749f..50ab6410f 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -895,7 +895,7 @@ typedef struct typedef enum { - ok, + planeok, crushed, pastdest } result_e; diff --git a/src/w_wad.c b/src/w_wad.c index b13dc8cc1..171eab4f3 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -201,7 +201,7 @@ FILE *W_OpenWadFile(const char **filename, boolean useerrors) } // Look for all DEHACKED and Lua scripts inside a PK3 archive. -static inline void W_LoadDehackedLumpsPK3(UINT16 wadnum, boolean mainfile) +static void W_LoadDehackedLumpsPK3(UINT16 wadnum, boolean mainfile) { UINT16 posStart, posEnd; @@ -241,7 +241,7 @@ static inline void W_LoadDehackedLumpsPK3(UINT16 wadnum, boolean mainfile) } // search for all DEHACKED lump in all wads and load it -static inline void W_LoadDehackedLumps(UINT16 wadnum, boolean mainfile) +static void W_LoadDehackedLumps(UINT16 wadnum, boolean mainfile) { UINT16 lump; @@ -305,7 +305,7 @@ static inline void W_LoadDehackedLumps(UINT16 wadnum, boolean mainfile) * \param resblock resulting MD5 checksum * \return 0 if MD5 checksum was made, and is at resblock, 1 if error was found */ -static inline INT32 W_MakeFileMD5(const char *filename, void *resblock) +static INT32 W_MakeFileMD5(const char *filename, void *resblock) { #ifdef NOMD5 (void)filename; @@ -1956,7 +1956,7 @@ void *W_CacheLumpNumForce(lumpnum_t lumpnum, INT32 tag) // return false. // // no outside code uses the PWAD form, for now -static inline boolean W_IsLumpCachedPWAD(UINT16 wad, UINT16 lump, void *ptr) +static boolean W_IsLumpCachedPWAD(UINT16 wad, UINT16 lump, void *ptr) { void *lcache; @@ -1988,7 +1988,7 @@ boolean W_IsLumpCached(lumpnum_t lumpnum, void *ptr) // return false. // // no outside code uses the PWAD form, for now -static inline boolean W_IsPatchCachedPWAD(UINT16 wad, UINT16 lump, void *ptr) +static boolean W_IsPatchCachedPWAD(UINT16 wad, UINT16 lump, void *ptr) { void *lcache; From c6c3cc3209833557a70933c87d25564a4ba39014 Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Wed, 26 Jul 2023 00:06:52 -0300 Subject: [PATCH 295/586] Drawseg clipping optimized, from prboom-plus Co-authored-by: Sally Coolatta --- src/r_things.c | 202 +++++++++++++++++++++++++++++++++++++------------ src/r_things.h | 1 - 2 files changed, 154 insertions(+), 49 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 248357e11..5f0f83c5c 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -80,6 +80,33 @@ static spriteframe_t sprtemp[64]; static size_t maxframe; static const char *spritename; +// +// Clipping against drawsegs optimization, from prboom-plus +// +// TODO: This should be done with proper subsector pass through +// sprites which would ideally remove the need to do it at all. +// Unfortunately, SRB2's drawing loop has lots of annoying +// changes from Doom for portals, which make it hard to implement. + +typedef struct drawseg_xrange_item_s +{ + INT16 x1, x2; + drawseg_t *user; +} drawseg_xrange_item_t; + +typedef struct drawsegs_xrange_s +{ + drawseg_xrange_item_t *items; + INT32 count; +} drawsegs_xrange_t; + +#define DS_RANGES_COUNT 3 +static drawsegs_xrange_t drawsegs_xranges[DS_RANGES_COUNT]; + +static drawseg_xrange_item_t *drawsegs_xrange; +static size_t drawsegs_xrange_size = 0; +static INT32 drawsegs_xrange_count = 0; + // ========================================================================== // // Sprite loading routines: support sprites in pwad, dehacked sprite renaming, @@ -3136,7 +3163,7 @@ static void R_HeightSecClip(vissprite_t *spr, INT32 x1, INT32 x2) // R_ClipVisSprite // Clips vissprites without drawing, so that portals can work. -Red -void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2, drawseg_t* dsstart, portal_t* portal) +static void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2, portal_t* portal) { drawseg_t *ds; INT32 x; @@ -3156,21 +3183,23 @@ void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2, drawseg_t* dsstart, p // Pointer check was originally nonportable // and buggy, by going past LEFT end of array: - // for (ds = ds_p-1; ds >= drawsegs; ds--) old buggy code - for (ds = ds_p; ds-- > dsstart;) + // e6y: optimization + if (drawsegs_xrange_size) { - // determine if the drawseg obscures the sprite - if (ds->x1 > x2 || - ds->x2 < x1 || - (!ds->silhouette - && !ds->maskedtexturecol)) - { - // does not cover sprite - continue; - } + const drawseg_xrange_item_t *last = &drawsegs_xrange[drawsegs_xrange_count - 1]; + drawseg_xrange_item_t *curr = &drawsegs_xrange[-1]; - if (ds->portalpass != 66) + while (++curr <= last) { + // determine if the drawseg obscures the sprite + if (curr->x1 > x2 || curr->x2 < x1) + { + // does not cover sprite + continue; + } + + ds = curr->user; + if (ds->portalpass > 0 && ds->portalpass <= portalrender) continue; // is a portal @@ -3195,43 +3224,43 @@ void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2, drawseg_t* dsstart, p // seg is behind sprite continue; } - } - r1 = ds->x1 < x1 ? x1 : ds->x1; - r2 = ds->x2 > x2 ? x2 : ds->x2; + r1 = ds->x1 < x1 ? x1 : ds->x1; + r2 = ds->x2 > x2 ? x2 : ds->x2; - // clip this piece of the sprite - silhouette = ds->silhouette; + // clip this piece of the sprite + silhouette = ds->silhouette; - if (spr->gz >= ds->bsilheight) - silhouette &= ~SIL_BOTTOM; + if (spr->gz >= ds->bsilheight) + silhouette &= ~SIL_BOTTOM; - if (spr->gzt <= ds->tsilheight) - silhouette &= ~SIL_TOP; + if (spr->gzt <= ds->tsilheight) + silhouette &= ~SIL_TOP; - if (silhouette == SIL_BOTTOM) - { - // bottom sil - for (x = r1; x <= r2; x++) - if (spr->clipbot[x] == -2) - spr->clipbot[x] = ds->sprbottomclip[x]; - } - else if (silhouette == SIL_TOP) - { - // top sil - for (x = r1; x <= r2; x++) - if (spr->cliptop[x] == -2) - spr->cliptop[x] = ds->sprtopclip[x]; - } - else if (silhouette == (SIL_TOP|SIL_BOTTOM)) - { - // both - for (x = r1; x <= r2; x++) + if (silhouette == SIL_BOTTOM) { - if (spr->clipbot[x] == -2) - spr->clipbot[x] = ds->sprbottomclip[x]; - if (spr->cliptop[x] == -2) - spr->cliptop[x] = ds->sprtopclip[x]; + // bottom sil + for (x = r1; x <= r2; x++) + if (spr->clipbot[x] == -2) + spr->clipbot[x] = ds->sprbottomclip[x]; + } + else if (silhouette == SIL_TOP) + { + // top sil + for (x = r1; x <= r2; x++) + if (spr->cliptop[x] == -2) + spr->cliptop[x] = ds->sprtopclip[x]; + } + else if (silhouette == (SIL_TOP|SIL_BOTTOM)) + { + // both + for (x = r1; x <= r2; x++) + { + if (spr->clipbot[x] == -2) + spr->clipbot[x] = ds->sprbottomclip[x]; + if (spr->cliptop[x] == -2) + spr->cliptop[x] = ds->sprtopclip[x]; + } } } } @@ -3305,16 +3334,93 @@ void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2, drawseg_t* dsstart, p void R_ClipSprites(drawseg_t* dsstart, portal_t* portal) { + const size_t maxdrawsegs = ds_p - drawsegs; + const INT32 cx = viewwidth / 2; + drawseg_t* ds; + INT32 i; + + // e6y + // Reducing of cache misses in the following R_DrawSprite() + // Makes sense for scenes with huge amount of drawsegs. + // ~12% of speed improvement on epic.wad map05 + for (i = 0; i < DS_RANGES_COUNT; i++) + { + drawsegs_xranges[i].count = 0; + } + + if (visspritecount - clippedvissprites <= 0) + { + return; + } + + if (drawsegs_xrange_size < maxdrawsegs) + { + drawsegs_xrange_size = 2 * maxdrawsegs; + + for (i = 0; i < DS_RANGES_COUNT; i++) + { + drawsegs_xranges[i].items = Z_Realloc( + drawsegs_xranges[i].items, + drawsegs_xrange_size * sizeof(drawsegs_xranges[i].items[0]), + PU_STATIC, NULL + ); + } + } + + for (ds = ds_p; ds-- > dsstart;) + { + if (ds->silhouette || ds->maskedtexturecol) + { + drawsegs_xranges[0].items[drawsegs_xranges[0].count].x1 = ds->x1; + drawsegs_xranges[0].items[drawsegs_xranges[0].count].x2 = ds->x2; + drawsegs_xranges[0].items[drawsegs_xranges[0].count].user = ds; + + // e6y: ~13% of speed improvement on sunder.wad map10 + if (ds->x1 < cx) + { + drawsegs_xranges[1].items[drawsegs_xranges[1].count] = + drawsegs_xranges[0].items[drawsegs_xranges[0].count]; + drawsegs_xranges[1].count++; + } + + if (ds->x2 >= cx) + { + drawsegs_xranges[2].items[drawsegs_xranges[2].count] = + drawsegs_xranges[0].items[drawsegs_xranges[0].count]; + drawsegs_xranges[2].count++; + } + + drawsegs_xranges[0].count++; + } + } + for (; clippedvissprites < visspritecount; clippedvissprites++) { vissprite_t *spr = R_GetVisSprite(clippedvissprites); - if (!(spr->cut & SC_BBOX)) // Do not clip bounding boxes + if (spr->cut & SC_BBOX) + continue; + + INT32 x1 = (spr->cut & SC_SPLAT) ? 0 : spr->x1; + INT32 x2 = (spr->cut & SC_SPLAT) ? viewwidth : spr->x2; + + if (x2 < cx) { - INT32 x1 = (spr->cut & SC_SPLAT) ? 0 : spr->x1; - INT32 x2 = (spr->cut & SC_SPLAT) ? viewwidth : spr->x2; - R_ClipVisSprite(spr, x1, x2, dsstart, portal); + drawsegs_xrange = drawsegs_xranges[1].items; + drawsegs_xrange_count = drawsegs_xranges[1].count; } + else if (x1 >= cx) + { + drawsegs_xrange = drawsegs_xranges[2].items; + drawsegs_xrange_count = drawsegs_xranges[2].count; + } + else + { + drawsegs_xrange = drawsegs_xranges[0].items; + drawsegs_xrange_count = drawsegs_xranges[0].count; + } + + R_ClipVisSprite(spr, x1, x2, portal); } } diff --git a/src/r_things.h b/src/r_things.h index bb8a1e97b..e11005363 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -222,7 +222,6 @@ typedef struct vissprite_s extern UINT32 visspritecount; void R_ClipSprites(drawseg_t* dsstart, portal_t* portal); -void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2, drawseg_t* dsstart, portal_t* portal); boolean R_SpriteIsFlashing(vissprite_t *vis); From e12288be3f3823e5e51c22adccd0ffbf74b7e944 Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Wed, 26 Jul 2023 00:19:55 -0300 Subject: [PATCH 296/586] Move these two lines after calculating the slopes --- src/r_bbox.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/r_bbox.c b/src/r_bbox.c index 59d0893c4..4302d1b9a 100644 --- a/src/r_bbox.c +++ b/src/r_bbox.c @@ -129,9 +129,6 @@ draw_bbox_row x1 = a->x; x2 = b->x; - if (x2 >= viewwidth) - x2 = viewwidth - 1; - if (x1 == x2 || x1 >= viewwidth || x2 < 0) return; @@ -159,6 +156,9 @@ draw_bbox_row x1 = 0; } + if (x2 >= viewwidth) + x2 = viewwidth - 1; + while (x1 < x2) { raster_bbox_seg(x1, y1, s1, bb->color); From 29f7ecd46051884e365022bf62ce5291d7c36a06 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Tue, 18 Jul 2023 09:01:29 -0400 Subject: [PATCH 297/586] Remove P_RandomFixed call when players are moving "Add some extra randomization" is not how RNG works --- src/p_user.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 889e887c1..dcb84451b 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -11623,10 +11623,6 @@ void P_PlayerThink(player_t *player) cmd = &player->cmd; - // Add some extra randomization. - if (cmd->forwardmove) - P_RandomFixed(); - #ifdef PARANOIA if (player->playerstate == PST_REBORN) I_Error("player %s is in PST_REBORN\n", sizeu1(playeri)); From dc9346a45df2e5f9e7711846cd198c6d150e5537 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Wed, 26 Jul 2023 07:50:47 -0400 Subject: [PATCH 298/586] Add forwardmove rng backwards compat with demos --- src/g_demo.c | 3 +++ src/g_demo.h | 1 + src/p_user.c | 7 +++++++ 3 files changed, 11 insertions(+) diff --git a/src/g_demo.c b/src/g_demo.c index a7b9098fa..adb8e891d 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -58,6 +58,7 @@ static UINT8 demoflags; static UINT16 demoversion; boolean singledemo; // quit after playing a demo from cmdline boolean demo_start; // don't start playing demo right away +boolean demo_forwardmove_rng; // old demo backwards compatibility boolean demosynced = true; // console warning message boolean metalrecording; // recording as metal sonic @@ -2028,6 +2029,7 @@ void G_DoPlayDemo(char *defdemoname) version = READUINT8(demo_p); subversion = READUINT8(demo_p); demoversion = READUINT16(demo_p); + demo_forwardmove_rng = (demoversion < 0x0010); switch(demoversion) { case 0x000f: @@ -2339,6 +2341,7 @@ UINT8 G_CheckDemoForError(char *defdemoname) demo_p++; // version demo_p++; // subversion demoversion = READUINT16(demo_p); + demo_forwardmove_rng = (demoversion < 0x0010); switch(demoversion) { case 0x000d: diff --git a/src/g_demo.h b/src/g_demo.h index 383d2719b..379c57428 100644 --- a/src/g_demo.h +++ b/src/g_demo.h @@ -38,6 +38,7 @@ extern demo_file_override_e demofileoverride; // Quit after playing a demo from cmdline. extern boolean singledemo; extern boolean demo_start; +extern boolean demo_forwardmove_rng; extern boolean demosynced; extern mobj_t *metalplayback; diff --git a/src/p_user.c b/src/p_user.c index dcb84451b..1c2e4f7c9 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -11623,6 +11623,13 @@ void P_PlayerThink(player_t *player) cmd = &player->cmd; + if (demoplayback && demo_forwardmove_rng) + { + // Smelly demo backwards compatibility + if (cmd->forwardmove) + P_RandomFixed(); + } + #ifdef PARANOIA if (player->playerstate == PST_REBORN) I_Error("player %s is in PST_REBORN\n", sizeu1(playeri)); From 0abe55619731b0c70e05d6aed996366814d04f6f Mon Sep 17 00:00:00 2001 From: Eidolon Date: Sat, 5 Nov 2022 20:50:57 -0500 Subject: [PATCH 299/586] cmake: Enable C++ 17 and C11 --- src/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2f4467a32..7ec229fe0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -5,6 +5,8 @@ if("${CMAKE_COMPILER_IS_GNUCC}" AND "${CMAKE_SYSTEM_NAME}" MATCHES "Windows" AND target_link_options(SRB2SDL2 PRIVATE "-static") endif() +target_compile_features(SRB2SDL2 PRIVATE c_std_11 cxx_std_17) + # Core sources target_sourcefile(c) target_sources(SRB2SDL2 PRIVATE comptime.c md5.c config.h.in) From 763912700396b9d1eba495cd084317997b1232e1 Mon Sep 17 00:00:00 2001 From: Eidolon Date: Sun, 6 Nov 2022 01:08:43 -0600 Subject: [PATCH 300/586] cmake: Add Catch2 unit testing --- CMakeLists.txt | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 915912af5..568789a0d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,6 +58,7 @@ option( "Link dependencies using CMake's find_package and do not use internal builds" ${SRB2_CONFIG_SYSTEM_LIBRARIES_DEFAULT} ) +option(SRB2_CONFIG_ENABLE_TESTS "Build the test suite" ON) # This option isn't recommended for distribution builds and probably won't work (yet). cmake_dependent_option( SRB2_CONFIG_SHARED_INTERNAL_LIBRARIES @@ -76,6 +77,25 @@ option(SRB2_CONFIG_ZDEBUG "Compile with ZDEBUG defined." OFF) option(SRB2_CONFIG_PROFILEMODE "Compile for profiling (GCC only)." OFF) set(SRB2_CONFIG_ASSET_DIRECTORY "" CACHE PATH "Path to directory that contains all asset files for the installer. If set, assets will be part of installation and cpack.") +if(SRB2_CONFIG_ENABLE_TESTS) + # https://github.com/catchorg/Catch2 + CPMAddPackage( + NAME Catch2 + VERSION 3.1.1 + GITHUB_REPOSITORY catchorg/Catch2 + OPTIONS + "CATCH_INSTALL_DOCS OFF" + ) + list(APPEND CMAKE_MODULE_PATH "${Catch2_SOURCE_DIR}/extras") + include(CTest) + include(Catch) + add_executable(srb2tests) + # To add tests, use target_sources to add individual test files to the target in subdirs. + target_link_libraries(srb2tests PRIVATE Catch2::Catch2 Catch2::Catch2WithMain) + target_compile_features(srb2tests PRIVATE c_std_11 cxx_std_17) + catch_discover_tests(srb2tests) +endif() + # Enable CCache # (Set USE_CCACHE=ON to use, CCACHE_OPTIONS for options) if("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL Windows) From 2a8dbed3369afad767c23444fc55a635cd9afa26 Mon Sep 17 00:00:00 2001 From: Eidolon Date: Sun, 13 Nov 2022 20:06:15 -0600 Subject: [PATCH 301/586] Redefine boolean for C++ compatibility --- src/CMakeLists.txt | 1 + src/doomtype.h | 58 +++++++++++++++++----------------------- src/tests/CMakeLists.txt | 3 +++ src/tests/boolcompat.cpp | 8 ++++++ 4 files changed, 37 insertions(+), 33 deletions(-) create mode 100644 src/tests/CMakeLists.txt create mode 100644 src/tests/boolcompat.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7ec229fe0..9352d55ef 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -291,6 +291,7 @@ if(SRB2_CONFIG_PROFILEMODE AND "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") endif() add_subdirectory(sdl) +add_subdirectory(tests) # strip debug symbols into separate file when using gcc. # to be consistent with Makefile, don't generate for OS X. diff --git a/src/doomtype.h b/src/doomtype.h index f6c236e20..f834a3f4f 100644 --- a/src/doomtype.h +++ b/src/doomtype.h @@ -17,6 +17,10 @@ #ifndef __DOOMTYPE__ #define __DOOMTYPE__ +#ifdef __cplusplus +extern "C" { +#endif + #ifdef _WIN32 //#define WIN32_LEAN_AND_MEAN #define RPC_NO_WINDOWS_H @@ -100,24 +104,6 @@ char *strcasestr(const char *in, const char *what); int startswith (const char *base, const char *tag); int endswith (const char *base, const char *tag); -#if defined (macintosh) //|| defined (__APPLE__) //skip all boolean/Boolean crap - #define true 1 - #define false 0 - #define min(x,y) (((x)<(y)) ? (x) : (y)) - #define max(x,y) (((x)>(y)) ? (x) : (y)) - -#ifdef macintosh - #define stricmp strcmp - #define strnicmp strncmp -#endif - - #define boolean INT32 - - #ifndef O_BINARY - #define O_BINARY 0 - #endif -#endif //macintosh - #if defined (_WIN32) || defined (__HAIKU__) #define HAVE_DOSSTR_FUNCS #endif @@ -144,22 +130,24 @@ size_t strlcpy(char *dst, const char *src, size_t siz); /* Boolean type definition */ -// \note __BYTEBOOL__ used to be set above if "macintosh" was defined, -// if macintosh's version of boolean type isn't needed anymore, then isn't this macro pointless now? -#ifndef __BYTEBOOL__ - #define __BYTEBOOL__ +// Note: C++ bool and C99/C11 _Bool are NOT compatible. +// Historically, boolean was win32 BOOL on Windows. For equivalence, it's now +// int32_t. "true" and "false" are only declared for C code; in C++, conversion +// between "bool" and "int32_t" takes over. +#ifndef _WIN32 +typedef int32_t boolean; +#else +#define BOOL boolean +#endif - //faB: clean that up !! - #if defined( _MSC_VER) && (_MSC_VER >= 1800) // MSVC 2013 and forward - #include "stdbool.h" - #elif defined (_WIN32) - #define false FALSE // use windows types - #define true TRUE - #define boolean BOOL - #else - typedef enum {false, true} boolean; - #endif -#endif // __BYTEBOOL__ +#ifndef __cplusplus +#ifndef _WIN32 +enum {false = 0, true = 1}; +#else +#define false FALSE +#define true TRUE +#endif +#endif /* 7.18.2.1 Limits of exact-width integer types */ @@ -387,4 +375,8 @@ unset_bit_array (bitarray_t * const array, const int value) typedef UINT64 precise_t; +#ifdef __cplusplus +} // extern "C" +#endif + #endif //__DOOMTYPE__ diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt new file mode 100644 index 000000000..28c4ce492 --- /dev/null +++ b/src/tests/CMakeLists.txt @@ -0,0 +1,3 @@ +target_sources(srb2tests PRIVATE + boolcompat.cpp +) diff --git a/src/tests/boolcompat.cpp b/src/tests/boolcompat.cpp new file mode 100644 index 000000000..fee40cd36 --- /dev/null +++ b/src/tests/boolcompat.cpp @@ -0,0 +1,8 @@ +#include + +#include "../doomtype.h" + +TEST_CASE("C++ bool is convertible to doomtype.h boolean") { + REQUIRE(static_cast(true) == 1); + REQUIRE(static_cast(false) == 0); +} From 12b6a7cabfdd298e7c23d1c5030e637d224e2288 Mon Sep 17 00:00:00 2001 From: Eidolon Date: Sun, 13 Nov 2022 20:07:36 -0600 Subject: [PATCH 302/586] Don't preproc. define `inline` in C++ --- src/doomtype.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/doomtype.h b/src/doomtype.h index f834a3f4f..e6da5e50c 100644 --- a/src/doomtype.h +++ b/src/doomtype.h @@ -82,7 +82,9 @@ typedef long ssize_t; #endif #define strncasecmp strnicmp #define strcasecmp stricmp +#ifndef __cplusplus #define inline __inline +#endif #elif defined (__WATCOMC__) #include #include From 101cdea022167a6b5c7aefa2a1faa5e47d9168b4 Mon Sep 17 00:00:00 2001 From: Eidolon Date: Sat, 5 Nov 2022 18:31:06 -0500 Subject: [PATCH 303/586] cmake: Add optional clang-tidy integration clang-tidy performs static analysis over the compilation unit, producing more comprehensive compile warnings than are normally generated by the compiler. For example, it will trace branches in a function to find the exact conditions in which a null dereference can occur. Note that this produces an absurd amount of warnings for our existing C code, and significantly slows compile times. It is pretty effective at its job though. I think it would be good to turn on by default for upcoming C++ code. --- CMakeLists.txt | 3 +++ cmake/Modules/clang-tidy-default.cmake | 21 +++++++++++++++++++++ src/CMakeLists.txt | 10 ++++++++++ 3 files changed, 34 insertions(+) create mode 100644 cmake/Modules/clang-tidy-default.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 915912af5..7fc050ea0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,6 +53,9 @@ else() set(SRB2_CONFIG_SYSTEM_LIBRARIES_DEFAULT OFF) endif() +# Clang tidy options will be ignored if CMAKE__CLANG_TIDY are set. +option(SRB2_CONFIG_ENABLE_CLANG_TIDY_C "Enable default clang-tidy check configuration for C" OFF) +option(SRB2_CONFIG_ENABLE_CLANG_TIDY_CXX "Enable default clang-tidy check configuration for C++" OFF) option( SRB2_CONFIG_SYSTEM_LIBRARIES "Link dependencies using CMake's find_package and do not use internal builds" diff --git a/cmake/Modules/clang-tidy-default.cmake b/cmake/Modules/clang-tidy-default.cmake new file mode 100644 index 000000000..2be3af10d --- /dev/null +++ b/cmake/Modules/clang-tidy-default.cmake @@ -0,0 +1,21 @@ +find_program(CLANG_TIDY clang-tidy) + +# Note: Apple Clang does not ship with clang tools. If you want clang-tidy on +# macOS, it's best to install the Homebrew llvm bottle and set CLANG_TIDY +# in your build directory. The llvm package is keg-only, so it will not +# collide with Apple Clang. + +function(target_set_default_clang_tidy target lang checks) + if("${CLANG_TIDY}" STREQUAL "CLANG_TIDY-NOTFOUND") + return() + endif() + + get_target_property(c_clang_tidy_prop SRB2SDL2 C_CLANG_TIDY) + if(NOT ("${c_clang_tidy_prop}" STREQUAL "c_clang_tidy_prop-NOTFOUND")) + return() + endif() + + set_target_properties("${target}" PROPERTIES + ${lang}_CLANG_TIDY "${CLANG_TIDY};-checks=${checks}" + ) +endfunction() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2f4467a32..18c16eeb4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,3 +1,5 @@ +include(clang-tidy-default) + add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32) if("${CMAKE_COMPILER_IS_GNUCC}" AND "${CMAKE_SYSTEM_NAME}" MATCHES "Windows" AND NOT "${SRB2_CONFIG_SYSTEM_LIBRARIES}" AND NOT "${SRB2_CONFIG_SHARED_INTERNAL_LIBRARIES}") @@ -329,3 +331,11 @@ if("${CMAKE_SYSTEM_NAME}" STREQUAL Windows AND NOT "${SRB2_CONFIG_INTERNAL_LIBRA COMMENT "Copying runtime DLLs" ) endif() + +# Setup clang-tidy +if(SRB2_CONFIG_ENABLE_CLANG_TIDY_C) + target_set_default_clang_tidy(SRB2SDL2 C "-*,clang-analyzer-*,-clang-analyzer-cplusplus-*") +endif() +if(SRB2_CONFIG_ENABLE_CLANG_TIDY_CXX) + target_set_default_clang_tidy(SRB2SDL2 CXX "-*,clang-analyzer-*,modernize-*") +endif() From 9253a8cc549e862a9f997b18f060a9ecb1335b03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Fri, 2 Jun 2023 18:49:37 +0200 Subject: [PATCH 304/586] Fix use-after-free when calling v.drawString in Lua --- src/lua_hudlib_drawlist.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/lua_hudlib_drawlist.c b/src/lua_hudlib_drawlist.c index 6f83094ac..c518ba525 100644 --- a/src/lua_hudlib_drawlist.c +++ b/src/lua_hudlib_drawlist.c @@ -177,9 +177,18 @@ static const char *CopyString(huddrawlist_h list, const char* str) lenstr = strlen(str); if (list->strbuf_capacity <= list->strbuf_len + lenstr + 1) { + const char *old_offset = list->strbuf; + size_t i; if (list->strbuf_capacity == 0) list->strbuf_capacity = 256; else list->strbuf_capacity *= 2; list->strbuf = (char*) Z_Realloc(list->strbuf, sizeof(char) * list->strbuf_capacity, PU_STATIC, NULL); + + // align the string pointers to make sure old pointers don't point towards invalid addresses + // this is necessary since Z_ReallocAlign might actually move the string buffer in memory + for (i = 0; i < list->items_len; i++) + { + list->items[i].str += list->strbuf - old_offset; + } } const char *result = (const char *) &list->strbuf[list->strbuf_len]; strncpy(&list->strbuf[list->strbuf_len], str, lenstr + 1); From 4bbf4c21c2cd81e402537509e68d05292d931e16 Mon Sep 17 00:00:00 2001 From: katsy <205-katsy@users.noreply.git.do.srb2.org> Date: Wed, 26 Jul 2023 12:14:21 +0000 Subject: [PATCH 305/586] Warn in console instead of hard erroring when attempting to modify a vanilla skincolor (resolves #1046) --- src/lua_infolib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lua_infolib.c b/src/lua_infolib.c index 4d150347d..1144648d0 100644 --- a/src/lua_infolib.c +++ b/src/lua_infolib.c @@ -1709,7 +1709,7 @@ static int lib_setSkinColor(lua_State *L) else if (i == 6 || (str && fastcmp(str,"accessible"))) { boolean v = lua_toboolean(L, 3); if (cnum < FIRSTSUPERCOLOR && v != skincolors[cnum].accessible) - return luaL_error(L, "skincolors[] index %d is a standard color; accessibility changes are prohibited.", cnum); + CONS_Alert(CONS_WARNING, "skincolors[] index %d is a standard color; accessibility changes are prohibited.", cnum); else info->accessible = v; } @@ -1804,7 +1804,7 @@ static int skincolor_set(lua_State *L) else if (fastcmp(field,"accessible")) { boolean v = lua_toboolean(L, 3); if (cnum < FIRSTSUPERCOLOR && v != skincolors[cnum].accessible) - return luaL_error(L, "skincolors[] index %d is a standard color; accessibility changes are prohibited.", cnum); + CONS_Alert(CONS_WARNING, "skincolors[] index %d is a standard color; accessibility changes are prohibited.", cnum); else info->accessible = v; } else From 9e5a8285089c671f827d52b8a30f9cc903445a0f Mon Sep 17 00:00:00 2001 From: tertu marybig Date: Wed, 26 Jul 2023 14:53:01 +0000 Subject: [PATCH 306/586] New M_Random implementation --- src/android/i_system.c | 22 +++++ src/d_main.c | 12 +-- src/dummy/i_system.c | 5 ++ src/i_system.h | 4 + src/lua_hudlib.c | 9 -- src/m_random.c | 192 ++++++++++++++++++++++++++++++++++++++--- src/m_random.h | 3 + src/sdl/i_system.c | 38 ++++++++ 8 files changed, 259 insertions(+), 26 deletions(-) diff --git a/src/android/i_system.c b/src/android/i_system.c index ff8b88de5..9d798d452 100644 --- a/src/android/i_system.c +++ b/src/android/i_system.c @@ -278,4 +278,26 @@ char *I_ClipboardPaste(void) void I_RegisterSysCommands(void) {} +// This is identical to the SDL implementation. +size_t I_GetRandomBytes(char *destination, size_t count) +{ + FILE *rndsource; + size_t actual_bytes; + + if (!(rndsource = fopen("/dev/urandom", "r"))) + if (!(rndsource = fopen("/dev/random", "r"))) + actual_bytes = 0; + + if (rndsource) + { + actual_bytes = fread(destination, 1, count, rndsource); + fclose(rndsource); + } + + if (actual_bytes == 0) + I_OutputMsg("I_GetRandomBytes(): couldn't get any random bytes"); + + return actual_bytes; +} + #include "../sdl/dosstr.c" diff --git a/src/d_main.c b/src/d_main.c index 5861f9886..389cdd2db 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -70,6 +70,7 @@ #include "filesrch.h" // refreshdirmenu #include "g_input.h" // tutorial mode control scheming #include "m_perfstats.h" +#include "m_random.h" #ifdef CMAKECONFIG #include "config.h" @@ -1334,11 +1335,12 @@ void D_SRB2Main(void) snprintf(addonsdir, sizeof addonsdir, "%s%s%s", srb2home, PATHSEP, "addons"); I_mkdir(addonsdir, 0755); - // rand() needs seeded regardless of password - srand((unsigned int)time(NULL)); - rand(); - rand(); - rand(); + // seed M_Random because it is necessary; seed P_Random for scripts that + // might want to use random numbers immediately at start + if (!M_RandomSeedFromOS()) + M_RandomSeed((UINT32)time(NULL)); // less good but serviceable + + P_SetRandSeed(M_RandomizedSeed()); if (M_CheckParm("-password") && M_IsNextParm()) D_SetPassword(M_GetNextParm()); diff --git a/src/dummy/i_system.c b/src/dummy/i_system.c index 8556c0248..125d2e8ae 100644 --- a/src/dummy/i_system.c +++ b/src/dummy/i_system.c @@ -180,6 +180,11 @@ const char *I_ClipboardPaste(void) return NULL; } +size_t I_GetRandomBytes(char *destination, size_t amount) +{ + return 0; +} + void I_RegisterSysCommands(void) {} void I_GetCursorPosition(INT32 *x, INT32 *y) diff --git a/src/i_system.h b/src/i_system.h index deea9f8a8..834dd4091 100644 --- a/src/i_system.h +++ b/src/i_system.h @@ -49,6 +49,10 @@ size_t I_GetFreeMem(size_t *total); */ precise_t I_GetPreciseTime(void); +/** \brief Fills a buffer with random data, returns amount of data obtained. + */ +size_t I_GetRandomBytes(char *destination, size_t count); + /** \brief Get the precision of precise_t in units per second. Invocations of this function for the program's duration MUST return the same value. */ diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index c7f67e93a..2e3bb9c68 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -1256,8 +1256,6 @@ static int libd_RandomKey(lua_State *L) INT32 a = (INT32)luaL_checkinteger(L, 1); HUDONLY - if (a > 65536) - LUA_UsageWarning(L, "v.RandomKey: range > 65536 is undefined behavior"); lua_pushinteger(L, M_RandomKey(a)); return 1; } @@ -1268,13 +1266,6 @@ static int libd_RandomRange(lua_State *L) INT32 b = (INT32)luaL_checkinteger(L, 2); HUDONLY - if (b < a) { - INT32 c = a; - a = b; - b = c; - } - if ((b-a+1) > 65536) - LUA_UsageWarning(L, "v.RandomRange: range > 65536 is undefined behavior"); lua_pushinteger(L, M_RandomRange(a, b)); return 1; } diff --git a/src/m_random.c b/src/m_random.c index 8b5138b9c..536fbfbbd 100644 --- a/src/m_random.c +++ b/src/m_random.c @@ -3,6 +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) 2022-2023 by tertu marybig. // Copyright (C) 1999-2023 by Sonic Team Junior. // // This program is free software distributed under the @@ -14,11 +15,122 @@ #include "doomdef.h" #include "doomtype.h" +#include "i_system.h" // I_GetRandomBytes #include "m_random.h" #include "m_fixed.h" -#include "m_cond.h" // totalplaytime +// SFC32 random number generator implementation + +typedef struct rnstate_s { + UINT32 data[3]; + UINT32 counter; +} rnstate_t; + +/** Generate a raw uniform random number using a particular state. + * + * \param state The RNG state to use. + * \return A random UINT32. + */ +static inline UINT32 RandomState_Get32(rnstate_t *state) { + UINT32 result, b, c; + + b = state->data[1]; + c = state->data[2]; + result = state->data[0] + b + state->counter++; + + state->data[0] = b ^ (b >> 9); + state->data[1] = c * 9; + state->data[2] = ((c << 21) | (c >> 11)) + result; + + return result; +} + +/** Seed an SFC32 RNG state with up to 96 bits of seed data. + * + * \param state The RNG state to seed. + * \param seeds A pointer to up to 3 UINT32s to use as seed data. + * \param seed_count The number of seed words. + */ +static inline void RandomState_Seed(rnstate_t *state, UINT32 *seeds, size_t seed_count) +{ + size_t i; + + state->counter = 1; + + for(i = 0; i < 3; i++) + { + UINT32 seed_word; + + if(i < seed_count) + seed_word = seeds[i]; + else + seed_word = 0; + + // For SFC32, seed data should be stored in the state in reverse order. + state->data[2-i] = seed_word; + } + + for(i = 0; i < 16; i++) + RandomState_Get32(state); +} + +/** Gets a uniform number in the range [0, limit). + * Technique is based on a combination of scaling and rejection sampling + * and is adapted from Daniel Lemire. + * + * \note Any UINT32 is a valid argument for limit. + * + * \param state The RNG state to use. + * \param limit The upper limit of the range. + * \return A UINT32 in the range [0, limit). + */ +static inline UINT32 RandomState_GetKey32(rnstate_t *state, const UINT32 limit) +{ + UINT32 raw_random, scaled_lower_word; + UINT64 scaled_random; + + // This algorithm won't work correctly if passed a 0. + if (limit == 0) return 0; + + raw_random = RandomState_Get32(state); + scaled_random = (UINT64)raw_random * (UINT64)limit; + + /*The high bits of scaled_random now contain the number we want, but it is + possible, depending on the number we generated and the value of limit, + that there is bias in the result. The rest of this code is for ensuring + that does not happen. + */ + scaled_lower_word = (UINT32)scaled_random; + + // If we're lucky, we can bail out now and avoid the division + if (scaled_lower_word < limit) + { + // Scale the limit to improve the chance of success. + // After this, the first result might turn out to be good enough. + UINT32 scaled_limit; + // An explanation for this trick: scaled_limit should be + // (UINT32_MAX+1)%range, but if that was computed directly the result + // would need to be computed as a UINT64. This trick allows it to be + // computed using 32-bit arithmetic. + scaled_limit = (-limit) % limit; + + while (scaled_lower_word < scaled_limit) + { + raw_random = RandomState_Get32(state); + scaled_random = (UINT64)raw_random * (UINT64)limit; + scaled_lower_word = (UINT32)scaled_random; + } + } + + return scaled_random >> 32; +} + +// The default seed is the hexadecimal digits of pi, though it will be overwritten. +static rnstate_t m_randomstate = { + .data = {0x4A3B6035U, 0x99555606U, 0x6F603421U}, + .counter = 16 +}; // --------------------------- // RNG functions (not synched) @@ -31,13 +143,7 @@ */ fixed_t M_RandomFixed(void) { -#if RAND_MAX < 65535 - // Compensate for insufficient randomness. - fixed_t rndv = (rand()&1)<<15; - return rand()^rndv; -#else - return (rand() & 0xFFFF); -#endif + return RandomState_Get32(&m_randomstate) >> (32-FRACBITS); } /** Provides a random byte. Distribution is uniform. @@ -47,7 +153,7 @@ fixed_t M_RandomFixed(void) */ UINT8 M_RandomByte(void) { - return (rand() & 0xFF); + return RandomState_Get32(&m_randomstate) >> 24; } /** Provides a random integer for picking random elements from an array. @@ -59,7 +165,22 @@ UINT8 M_RandomByte(void) */ INT32 M_RandomKey(INT32 a) { - return (INT32)((rand()/((float)RAND_MAX+1.0f))*a); + boolean range_is_negative; + INT64 range; + INT32 random_result; + + range = a; + range_is_negative = range < 0; + + if(range_is_negative) + range = -range; + + random_result = RandomState_GetKey32(&m_randomstate, (UINT32)range); + + if(range_is_negative) + random_result = -random_result; + + return random_result; } /** Provides a random integer in a given range. @@ -72,7 +193,46 @@ INT32 M_RandomKey(INT32 a) */ INT32 M_RandomRange(INT32 a, INT32 b) { - return (INT32)((rand()/((float)RAND_MAX+1.0f))*(b-a+1))+a; + if (b < a) + { + INT32 temp; + + temp = a; + a = b; + b = temp; + } + + const UINT32 spread = b-a+1; + return (INT32)((INT64)RandomState_GetKey32(&m_randomstate, spread) + a); +} + +/** Attempts to seed the unsynched RNG from a good random number source + * provided by the operating system. + * \return true on success, false on failure. + */ +boolean M_RandomSeedFromOS(void) +{ + UINT32 complete_word_count; + + union { + UINT32 words[3]; + char bytes[sizeof(UINT32[3])]; + } seed_data; + + complete_word_count = I_GetRandomBytes((char *)&seed_data.bytes, sizeof(seed_data)) / sizeof(UINT32); + + // If we get even 1 word of seed, it's fine, but any less probably is not fine. + if (complete_word_count == 0) + return false; + + RandomState_Seed(&m_randomstate, (UINT32 *)&seed_data.words, complete_word_count); + + return true; +} + +void M_RandomSeed(UINT32 seed) +{ + RandomState_Seed(&m_randomstate, &seed, 1); } @@ -246,10 +406,18 @@ void P_SetRandSeedD(const char *rfile, INT32 rline, UINT32 seed) } /** Gets a randomized seed for setting the random seed. + * This function will never return 0, as the current P_Random implementation + * cannot handle a zero seed. Any other seed is equally likely. * * \sa P_GetRandSeed */ UINT32 M_RandomizedSeed(void) { - return ((serverGamedata->totalplaytime & 0xFFFF) << 16) | M_RandomFixed(); + UINT32 seed; + + do { + seed = RandomState_Get32(&m_randomstate); + } while(seed == 0); + + return seed; } diff --git a/src/m_random.h b/src/m_random.h index 824287e27..a7c07a46b 100644 --- a/src/m_random.h +++ b/src/m_random.h @@ -3,6 +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) 2022-2023 by tertu marybig. // Copyright (C) 1999-2023 by Sonic Team Junior. // // This program is free software distributed under the @@ -29,6 +30,8 @@ fixed_t M_RandomFixed(void); UINT8 M_RandomByte(void); INT32 M_RandomKey(INT32 a); INT32 M_RandomRange(INT32 a, INT32 b); +boolean M_RandomSeedFromOS(void); +void M_RandomSeed(UINT32 a); // PRNG functions #ifdef DEBUGRANDOM diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 847ab2646..c21226ac3 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -41,6 +41,12 @@ typedef DWORD (WINAPI *p_timeGetTime) (void); typedef UINT (WINAPI *p_timeEndPeriod) (UINT); typedef HANDLE (WINAPI *p_OpenFileMappingA) (DWORD, BOOL, LPCSTR); typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); + +// This is for RtlGenRandom. +#define SystemFunction036 NTAPI SystemFunction036 +#include +#undef SystemFunction036 + #endif #include #include @@ -2776,6 +2782,38 @@ INT32 I_PutEnv(char *variable) #endif } +size_t I_GetRandomBytes(char *destination, size_t count) +{ +#if defined (__unix__) || defined (UNIXCOMMON) || defined(__APPLE__) + FILE *rndsource; + size_t actual_bytes; + + if (!(rndsource = fopen("/dev/urandom", "r"))) + if (!(rndsource = fopen("/dev/random", "r"))) + actual_bytes = 0; + + if (rndsource) + { + actual_bytes = fread(destination, 1, count, rndsource); + fclose(rndsource); + } + + if (actual_bytes == 0) + I_OutputMsg("I_GetRandomBytes(): couldn't get any random bytes"); + + return actual_bytes; +#elif defined (_WIN32) + if (RtlGenRandom(destination, count)) + return count; + + I_OutputMsg("I_GetRandomBytes(): couldn't get any random bytes"); + return 0; +#else + #warning SDL I_GetRandomBytes is not implemented on this platform. + return 0; +#endif +} + INT32 I_ClipboardCopy(const char *data, size_t size) { char storage[256]; From 42bf107b71f157058ae0a57d40d2d85a0d5c52ae Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Thu, 15 Dec 2022 20:54:15 -0500 Subject: [PATCH 307/586] #define BOOL boolean -> #define boolean BOOL --- src/doomtype.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doomtype.h b/src/doomtype.h index e6da5e50c..c59e17381 100644 --- a/src/doomtype.h +++ b/src/doomtype.h @@ -139,7 +139,7 @@ size_t strlcpy(char *dst, const char *src, size_t siz); #ifndef _WIN32 typedef int32_t boolean; #else -#define BOOL boolean +#define boolean BOOL #endif #ifndef __cplusplus From 91e915b963456c1a26ea6951ba96aa4c54f0780c Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Wed, 26 Jul 2023 13:44:43 -0400 Subject: [PATCH 308/586] Fix recordscore not including intermission bonuses --- src/y_inter.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/y_inter.c b/src/y_inter.c index 6e7d362a7..1b1f49e0b 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -2065,6 +2065,9 @@ static void Y_AwardCoopBonuses(void) players[i].score += localbonuses[j].points; if (players[i].score > MAXSCORE) players[i].score = MAXSCORE; + players[i].recordscore += localbonuses[j].points; + if (players[i].recordscore > MAXSCORE) + players[i].recordscore = MAXSCORE; } ptlives = min( @@ -2121,6 +2124,10 @@ static void Y_AwardSpecialStageBonus(void) players[i].score += localbonuses[1].points; if (players[i].score > MAXSCORE) players[i].score = MAXSCORE; + players[i].recordscore += localbonuses[0].points; + players[i].recordscore += localbonuses[1].points; + if (players[i].recordscore > MAXSCORE) + players[i].recordscore = MAXSCORE; // grant extra lives right away since tally is faked ptlives = min( From dc103330ac4b9f177307b7a25a178420803d1278 Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 30 Dec 2022 20:17:26 -0800 Subject: [PATCH 309/586] Rename strcasestr to nongnu_strcasestr, macro strcasestr ifndef _GNU_SOURCE Fix for GCC C++ compiler, which always defines _GNU_SOURCE. --- src/doomtype.h | 5 ++++- src/strcasestr.c | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/doomtype.h b/src/doomtype.h index c59e17381..617fd4d47 100644 --- a/src/doomtype.h +++ b/src/doomtype.h @@ -100,7 +100,10 @@ typedef long ssize_t; #define strnicmp(x,y,n) strncasecmp(x,y,n) #endif -char *strcasestr(const char *in, const char *what); +char *nongnu_strcasestr(const char *in, const char *what); +#ifndef _GNU_SOURCE +#define strcasestr nongnu_strcasestr +#endif #define stristr strcasestr int startswith (const char *base, const char *tag); diff --git a/src/strcasestr.c b/src/strcasestr.c index 2796f11d5..37899a842 100644 --- a/src/strcasestr.c +++ b/src/strcasestr.c @@ -61,7 +61,7 @@ swapp (char ***ppap, char ***ppbp, char **cpap, char **cpbp) } char * -strcasestr (const char *s, const char *q) +nongnu_strcasestr (const char *s, const char *q) { size_t qn; From 34f2594b4826a200ca50ecbf62652d5ffa181617 Mon Sep 17 00:00:00 2001 From: SteelT Date: Wed, 26 Jul 2023 14:09:48 -0400 Subject: [PATCH 310/586] Update Catch2 to latest version This combined with the previous commit fixes building the test suite --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a21d22b34..7d36c1fb6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -84,7 +84,7 @@ if(SRB2_CONFIG_ENABLE_TESTS) # https://github.com/catchorg/Catch2 CPMAddPackage( NAME Catch2 - VERSION 3.1.1 + VERSION 3.4.0 GITHUB_REPOSITORY catchorg/Catch2 OPTIONS "CATCH_INSTALL_DOCS OFF" From 7261db1eee9ee02fceb52c54265c233b0fff3ca5 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 20 Feb 2023 02:15:50 -0800 Subject: [PATCH 311/586] cmake: fix -DSRB2_CONFIG_ENABLE_TESTS=OFF build --- src/CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f3ed96f89..b62237374 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -293,7 +293,9 @@ if(SRB2_CONFIG_PROFILEMODE AND "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") endif() add_subdirectory(sdl) -add_subdirectory(tests) +if(SRB2_CONFIG_ENABLE_TESTS) + add_subdirectory(tests) +endif() # strip debug symbols into separate file when using gcc. # to be consistent with Makefile, don't generate for OS X. From d01f25d91dff89f318801962f53b8bd966c13078 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Wed, 26 Jul 2023 23:18:07 +0200 Subject: [PATCH 312/586] Fix FreeBSD build errors --- src/Makefile.d/nix.mk | 2 +- src/sdl/i_system.c | 43 ++++++++++--------------------------------- 2 files changed, 11 insertions(+), 34 deletions(-) diff --git a/src/Makefile.d/nix.mk b/src/Makefile.d/nix.mk index 767b64c12..728795771 100644 --- a/src/Makefile.d/nix.mk +++ b/src/Makefile.d/nix.mk @@ -29,7 +29,7 @@ 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 +libs+=-L/usr/X11R6/lib -lkvm -lexecinfo endif # FIXME: UNTESTED diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index c21226ac3..3616300c1 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -96,7 +96,7 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); #include #endif #include -#include +#include #endif #endif @@ -3037,40 +3037,17 @@ static long get_entry(const char* name, const char* buf) size_t I_GetFreeMem(size_t *total) { #ifdef FREEBSD - struct vmmeter sum; - kvm_t *kd; - struct nlist namelist[] = - { -#define X_SUM 0 - {"_cnt"}, - {NULL} - }; - if ((kd = kvm_open(NULL, NULL, NULL, O_RDONLY, "kvm_open")) == NULL) - { - if (total) - *total = 0L; - return 0; - } - if (kvm_nlist(kd, namelist) != 0) - { - kvm_close (kd); - if (total) - *total = 0L; - return 0; - } - if (kvm_read(kd, namelist[X_SUM].n_value, &sum, - sizeof (sum)) != sizeof (sum)) - { - kvm_close(kd); - if (total) - *total = 0L; - return 0; - } - kvm_close(kd); + u_int v_free_count, v_page_size, v_page_count; + size_t size = sizeof(v_free_count); + sysctlbyname("vm.stat.vm.v_free_count", &v_free_count, &size, NULL, 0); + size_t size = sizeof(v_page_size); + sysctlbyname("vm.stat.vm.v_page_size", &v_page_size, &size, NULL, 0); + size_t size = sizeof(v_page_count); + sysctlbyname("vm.stat.vm.v_page_count", &v_page_count, &size, NULL, 0); if (total) - *total = sum.v_page_count * sum.v_page_size; - return sum.v_free_count * sum.v_page_size; + *total = v_page_count * v_page_size; + return v_free_count * v_page_size; #elif defined (SOLARIS) /* Just guess */ if (total) From 606797a5a4f6ec1f2af72639ac60f6744253895e Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Thu, 27 Jul 2023 14:41:02 +0200 Subject: [PATCH 313/586] Temporarily revert recent netcode changes --- src/d_clisrv.c | 465 +++++++++---------------------------- src/d_clisrv.h | 10 +- src/d_net.c | 31 +-- src/d_net.h | 2 +- src/d_netcmd.c | 594 ++++++++++++++++++++++------------------------- src/d_netcmd.h | 14 +- src/d_netfil.c | 4 +- src/d_netfil.h | 2 +- src/http-mserv.c | 30 +-- src/i_addrinfo.c | 2 +- src/i_addrinfo.h | 2 +- src/i_net.h | 13 +- src/i_tcp.c | 73 ++---- src/i_tcp.h | 2 +- src/mserv.c | 10 +- src/mserv.h | 6 +- 16 files changed, 447 insertions(+), 813 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index c66c8d798..3091f3344 100755 --- 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-2023 by Sonic Team Junior. +// Copyright (C) 1999-2022 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -25,7 +25,8 @@ #include "st_stuff.h" #include "hu_stuff.h" #include "keys.h" -#include "g_input.h" // JOY1 +#include "g_input.h" +#include "i_gamepad.h" #include "m_menu.h" #include "console.h" #include "d_netfil.h" @@ -33,6 +34,7 @@ #include "p_saveg.h" #include "z_zone.h" #include "p_local.h" +#include "p_haptic.h" #include "m_misc.h" #include "am_map.h" #include "m_random.h" @@ -49,7 +51,7 @@ #include "m_perfstats.h" // aaaaaa -#include "i_joy.h" +#include "i_gamepad.h" #ifndef NONET // cl loading screen @@ -120,8 +122,6 @@ UINT8 hu_redownloadinggamestate = 0; // true when a player is connecting or disconnecting so that the gameplay has stopped in its tracks boolean hu_stopped = false; -consvar_t cv_dedicatedidletime = CVAR_INIT ("dedicatedidletime", "10", CV_SAVE, CV_Unsigned, NULL); - UINT8 adminpassmd5[16]; boolean adminpasswordset = false; @@ -655,22 +655,6 @@ static UINT8 Snake_GetOppositeDir(UINT8 dir) return 12 + 5 - dir; } -event_t *snakejoyevents[MAXEVENTS]; -UINT16 joyeventcount = 0; - -// I'm screaming the hack is clean - ashi -static boolean Snake_Joy_Grabber(event_t *ev) -{ - if (ev->type == ev_joystick && ev->key == 0) - { - snakejoyevents[joyeventcount] = ev; - joyeventcount++; - return true; - } - else - return false; -} - static void Snake_FindFreeSlot(UINT8 *freex, UINT8 *freey, UINT8 headx, UINT8 heady) { UINT8 x, y; @@ -697,19 +681,17 @@ static void Snake_Handle(void) UINT8 x, y; UINT8 oldx, oldy; UINT16 i; - UINT16 j; UINT16 joystate = 0; - static INT32 pjoyx = 0, pjoyy = 0; // Handle retry - if (snake->gameover && (PLAYER1INPUTDOWN(GC_JUMP) || gamekeydown[KEY_ENTER])) + if (snake->gameover && (G_PlayerInputDown(0, 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 (G_PlayerInputDown(0, GC_PAUSE) || gamekeydown[KEY_ENTER]) { if (!snake->pausepressed) snake->paused = !snake->paused; @@ -728,58 +710,23 @@ static void Snake_Handle(void) oldx = snake->snakex[1]; oldy = snake->snakey[1]; - // process the input events in here dear lord - for (j = 0; j < joyeventcount; j++) - { - event_t *ev = snakejoyevents[j]; - const INT32 jdeadzone = (JOYAXISRANGE * cv_digitaldeadzone.value) / FRACUNIT; - if (ev->y != INT32_MAX) - { - if (Joystick.bGamepadStyle || abs(ev->y) > jdeadzone) - { - if (ev->y < 0 && pjoyy >= 0) - joystate = 1; - else if (ev->y > 0 && pjoyy <= 0) - joystate = 2; - pjoyy = ev->y; - } - else - pjoyy = 0; - } - - if (ev->x != INT32_MAX) - { - if (Joystick.bGamepadStyle || abs(ev->x) > jdeadzone) - { - if (ev->x < 0 && pjoyx >= 0) - joystate = 3; - else if (ev->x > 0 && pjoyx <= 0) - joystate = 4; - pjoyx = ev->x; - } - else - pjoyx = 0; - } - } - joyeventcount = 0; - // Update direction - if (PLAYER1INPUTDOWN(GC_STRAFELEFT) || gamekeydown[KEY_LEFTARROW] || joystate == 3) + if (G_PlayerInputDown(0, GC_STRAFELEFT) || gamekeydown[KEY_LEFTARROW] || joystate == 3) { if (snake->snakelength < 2 || x <= oldx) snake->snakedir[0] = 1; } - else if (PLAYER1INPUTDOWN(GC_STRAFERIGHT) || gamekeydown[KEY_RIGHTARROW] || joystate == 4) + else if (G_PlayerInputDown(0, GC_STRAFERIGHT) || gamekeydown[KEY_RIGHTARROW] || joystate == 4) { if (snake->snakelength < 2 || x >= oldx) snake->snakedir[0] = 2; } - else if (PLAYER1INPUTDOWN(GC_FORWARD) || gamekeydown[KEY_UPARROW] || joystate == 1) + else if (G_PlayerInputDown(0, GC_FORWARD) || gamekeydown[KEY_UPARROW] || joystate == 1) { if (snake->snakelength < 2 || y <= oldy) snake->snakedir[0] = 3; } - else if (PLAYER1INPUTDOWN(GC_BACKWARD) || gamekeydown[KEY_DOWNARROW] || joystate == 2) + else if (G_PlayerInputDown(0, GC_BACKWARD) || gamekeydown[KEY_DOWNARROW] || joystate == 2) { if (snake->snakelength < 2 || y >= oldy) snake->snakedir[0] = 4; @@ -1295,7 +1242,6 @@ static boolean CL_AskFileList(INT32 firstfile) static boolean CL_SendJoin(void) { UINT8 localplayers = 1; - char const *player2name; if (netgame) CONS_Printf(M_GetText("Sending join request...\n")); netbuffer->packettype = PT_CLIENTJOIN; @@ -1312,23 +1258,18 @@ static boolean CL_SendJoin(void) CleanupPlayerName(consoleplayer, cv_playername.zstring); if (splitscreen) CleanupPlayerName(1, cv_playername2.zstring);/* 1 is a HACK? oh no */ - // Avoid empty string on bots to avoid softlocking in singleplayer - if (botingame) - player2name = strcmp(cv_playername.zstring, "Tails") == 0 ? "Tail" : "Tails"; - else - player2name = cv_playername2.zstring; strncpy(netbuffer->u.clientcfg.names[0], cv_playername.zstring, MAXPLAYERNAME); - strncpy(netbuffer->u.clientcfg.names[1], player2name, 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 addressbuffer[64]; + char strippednodeaddress[64]; const char *nodeaddress; - const char *strippednodeaddress; + char *port; INT32 i; // Make sure there is no dead dress before proceeding to the stripping @@ -1339,8 +1280,10 @@ static INT32 FindRejoinerNum(SINT8 node) return -1; // Strip the address of its port - strcpy(addressbuffer, nodeaddress); - strippednodeaddress = I_NetSplitAddress(addressbuffer, NULL); + strcpy(strippednodeaddress, nodeaddress); + port = strchr(strippednodeaddress, ':'); + if (port) + *port = '\0'; // Check if any player matches the stripped address for (i = 0; i < MAXPLAYERS; i++) @@ -1383,9 +1326,8 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime) netbuffer->u.serverinfo.time = (tic_t)LONG(servertime); netbuffer->u.serverinfo.leveltime = (tic_t)LONG(leveltime); - // Exclude bots from both counts - netbuffer->u.serverinfo.numberofplayer = (UINT8)(D_NumPlayers() - D_NumBots()); - netbuffer->u.serverinfo.maxplayer = (UINT8)(cv_maxplayers.value - D_NumBots()); + netbuffer->u.serverinfo.numberofplayer = (UINT8)D_NumPlayers(); + netbuffer->u.serverinfo.maxplayer = (UINT8)cv_maxplayers.value; netbuffer->u.serverinfo.refusereason = GetRefuseReason(node); @@ -1512,7 +1454,6 @@ static boolean SV_SendServerConfig(INT32 node) netbuffer->u.servercfg.gamestate = (UINT8)gamestate; netbuffer->u.servercfg.gametype = (UINT8)gametype; netbuffer->u.servercfg.modifiedgame = (UINT8)modifiedgame; - netbuffer->u.servercfg.usedCheats = (UINT8)usedCheats; memcpy(netbuffer->u.servercfg.server_context, server_context, 8); @@ -1711,6 +1652,8 @@ static void CL_LoadReceivedSavegame(boolean reloading) titledemo = false; automapactive = false; + P_StopRumble(NULL); + // load a base level if (P_LoadNetGame(reloading)) { @@ -1997,9 +1940,10 @@ void CL_UpdateServerList(boolean internetsearch, INT32 room) static void M_ConfirmConnect(event_t *ev) { #ifndef NONET - if (ev->type == ev_keydown) + + if (ev->type == ev_keydown || ev->type == ev_gamepad_down) { - if (ev->key == ' ' || ev->key == 'y' || ev->key == KEY_ENTER || ev->key == KEY_JOY1) + if ((ev->type == ev_keydown && (ev->key == ' ' || ev->key == 'y' || ev->key == KEY_ENTER)) || (ev->type == ev_gamepad_down && ev->which == 0 && ev->key == GAMEPAD_BUTTON_A)) { if (totalfilesrequestednum > 0) { @@ -2014,7 +1958,7 @@ static void M_ConfirmConnect(event_t *ev) M_ClearMenus(true); } - else if (ev->key == 'n' || ev->key == KEY_ESCAPE || ev->key == KEY_JOY1 + 3) + else if ((ev->type == ev_keydown && (ev->key == 'n' || ev->key == KEY_ESCAPE)) || (ev->type == ev_gamepad_down && ev->which == 0 && ev->key == GAMEPAD_BUTTON_B)) { cl_mode = CL_ABORTED; M_ClearMenus(true); @@ -2448,14 +2392,11 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic // my hand has been forced and I am dearly sorry for this awful hack :vomit: for (; eventtail != eventhead; eventtail = (eventtail+1) & (MAXEVENTS-1)) { -#ifndef NONET - if (!Snake_Joy_Grabber(&events[eventtail])) -#endif - G_MapEventsToControls(&events[eventtail]); + G_MapEventsToControls(&events[eventtail]); } } - if (gamekeydown[KEY_ESCAPE] || gamekeydown[KEY_JOY1+1] || cl_mode == CL_ABORTED) + if (gamekeydown[KEY_ESCAPE] || gamepads[0].buttons[GAMEPAD_BUTTON_B] || 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); @@ -2493,7 +2434,7 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic { if (!snake) { - F_MenuPresTicker(); // title sky + F_MenuPresTicker(true); // title sky F_TitleScreenTicker(true); F_TitleScreenDrawer(); } @@ -2608,8 +2549,6 @@ static void CL_ConnectToServer(void) } while (!(cl_mode == CL_CONNECTED && (client || (server && nodewaited <= pnumnodes)))); - if (netgame) - F_StartWaitingPlayers(); DEBFILE(va("Synchronisation Finished\n")); displayplayer = consoleplayer; @@ -3516,10 +3455,10 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum) 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_ALLOWLUA, CV_OnOff, 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|CV_ALLOWLUA, maxplayers_cons_t, 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}}; @@ -3547,22 +3486,22 @@ void D_ClientServerInit(void) VERSION/100, VERSION%100, SUBVERSION)); #ifndef NONET - COM_AddCommand("getplayernum", Command_GetPlayerNum, COM_LUA); - COM_AddCommand("kick", Command_Kick, COM_LUA); - COM_AddCommand("ban", Command_Ban, COM_LUA); - COM_AddCommand("banip", Command_BanIP, COM_LUA); - COM_AddCommand("clearbans", Command_ClearBans, COM_LUA); - COM_AddCommand("showbanlist", Command_ShowBan, COM_LUA); - COM_AddCommand("reloadbans", Command_ReloadBan, COM_LUA); - COM_AddCommand("connect", Command_connect, COM_LUA); - COM_AddCommand("nodes", Command_Nodes, COM_LUA); - COM_AddCommand("resendgamestate", Command_ResendGamestate, COM_LUA); + 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_LUA); - COM_AddCommand("droprate", Command_Droprate, COM_LUA); + COM_AddCommand("drop", Command_Drop); + COM_AddCommand("droprate", Command_Droprate); #endif #ifdef _DEBUG - COM_AddCommand("numnodes", Command_Numnodes, COM_LUA); + COM_AddCommand("numnodes", Command_Numnodes); #endif #endif @@ -3653,9 +3592,6 @@ void SV_ResetServer(void) CV_RevertNetVars(); - // Ensure synched when creating a new server - M_CopyGameData(serverGamedata, clientGamedata); - DEBFILE("\n-=-=-=-=-=-=-= Server Reset =-=-=-=-=-=-=-\n\n"); } @@ -3779,13 +3715,14 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum) if (server && I_GetNodeAddress) { - char addressbuffer[64]; const char *address = I_GetNodeAddress(node); + char *port = NULL; if (address) // MI: fix msvcrt.dll!_mbscat crash? { - strcpy(addressbuffer, address); - strcpy(playeraddress[newplayernum], - I_NetSplitAddress(addressbuffer, NULL)); + strcpy(playeraddress[newplayernum], address); + port = strchr(playeraddress[newplayernum], ':'); + if (port) + *port = '\0'; } } } @@ -4089,7 +4026,7 @@ ConnectionRefused (SINT8 node, INT32 rejoinernum) { return va( "Maximum players reached: %d", - cv_maxplayers.value - D_NumBots()); + cv_maxplayers.value); } } @@ -4417,8 +4354,6 @@ static void HandlePacketFromAwayNode(SINT8 node) maketic = gametic = neededtic = (tic_t)LONG(netbuffer->u.servercfg.gametic); G_SetGametype(netbuffer->u.servercfg.gametype); modifiedgame = netbuffer->u.servercfg.modifiedgame; - if (netbuffer->u.servercfg.usedCheats) - G_SetUsedCheats(true); memcpy(server_context, netbuffer->u.servercfg.server_context, 8); } @@ -4528,7 +4463,6 @@ static void HandlePacketFromPlayer(SINT8 node) netconsole = 0; else netconsole = nodetoplayer[node]; - #ifdef PARANOIA if (netconsole >= MAXPLAYERS) I_Error("bad table nodetoplayer: node %d player %d", doomcom->remotenode, netconsole); @@ -4567,32 +4501,21 @@ static void HandlePacketFromPlayer(SINT8 node) // Update the nettics nettics[node] = realend; - // This should probably still timeout though, as the node should always have a player 1 number - if (netconsole == -1) + // 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; - // Don't do anything for packets of type NODEKEEPALIVE? - // Sryder 2018/07/01: Update the freezetimeout still! - if (netbuffer->packettype == PT_NODEKEEPALIVE - || netbuffer->packettype == PT_NODEKEEPALIVEMIS) - break; - - // If we've alredy received a ticcmd for this tic, just submit it for the next one. - tic_t faketic = maketic; - if ((!!(netcmds[maketic % BACKUPTICS][netconsole].angleturn & TICCMD_RECEIVED)) - && (maketic - firstticstosend < BACKUPTICS)) - faketic++; - // Copy ticcmd - G_MoveTiccmd(&netcmds[faketic%BACKUPTICS][netconsole], &netbuffer->u.clientpak.cmd, 1); + G_MoveTiccmd(&netcmds[maketic%BACKUPTICS][netconsole], &netbuffer->u.clientpak.cmd, 1); // Check ticcmd for "speed hacks" - if (netcmds[faketic%BACKUPTICS][netconsole].forwardmove > MAXPLMOVE || netcmds[faketic%BACKUPTICS][netconsole].forwardmove < -MAXPLMOVE - || netcmds[faketic%BACKUPTICS][netconsole].sidemove > MAXPLMOVE || netcmds[faketic%BACKUPTICS][netconsole].sidemove < -MAXPLMOVE) + 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); @@ -4604,10 +4527,9 @@ static void HandlePacketFromPlayer(SINT8 node) // Splitscreen cmd if ((netbuffer->packettype == PT_CLIENT2CMD || netbuffer->packettype == PT_CLIENT2MIS) && nodetoplayer2[node] >= 0) - G_MoveTiccmd(&netcmds[faketic%BACKUPTICS][(UINT8)nodetoplayer2[node]], + 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) @@ -4644,21 +4566,6 @@ static void HandlePacketFromPlayer(SINT8 node) } } break; - case PT_BASICKEEPALIVE: - if (client) - break; - - // This should probably still timeout though, as the node should always have a player 1 number - if (netconsole == -1) - break; - - // If a client sends this it should mean they are done receiving the savegame - sendingsavegame[node] = false; - - // As long as clients send keep alives, the server can keep running, so reset the timeout - /// \todo Use a separate cvar for that kind of timeout? - freezetimeout[node] = I_GetTime() + connectiontimeout; - break; case PT_TEXTCMD2: // splitscreen special netconsole = nodetoplayer2[node]; /* FALLTHRU */ @@ -5085,66 +4992,39 @@ static INT16 Consistancy(void) return (INT16)(ret & 0xFFFF); } -// confusing, but this DOESN'T send PT_NODEKEEPALIVE, it sends PT_BASICKEEPALIVE -// used during wipes to tell the server that a node is still connected -static void CL_SendClientKeepAlive(void) -{ - netbuffer->packettype = PT_BASICKEEPALIVE; - - HSendPacket(servernode, false, 0, 0); -} - -static void SV_SendServerKeepAlive(void) -{ - INT32 n; - - for (n = 1; n < MAXNETNODES; n++) - { - if (nodeingame[n]) - { - netbuffer->packettype = PT_BASICKEEPALIVE; - HSendPacket(n, false, 0, 0); - } - } -} - // send the client packet to the server static void CL_SendClientCmd(void) { size_t packetsize = 0; - boolean mis = false; netbuffer->packettype = PT_CLIENTCMD; if (cl_packetmissed) - { - netbuffer->packettype = PT_CLIENTMIS; - mis = true; - } - + 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 = (mis ? PT_NODEKEEPALIVEMIS : PT_NODEKEEPALIVE); + netbuffer->packettype += 4; packetsize = sizeof (clientcmd_pak) - sizeof (ticcmd_t) - sizeof (INT16); HSendPacket(servernode, false, 0, packetsize); } else if (gamestate != GS_NULL && (addedtogame || dedicated)) { - packetsize = sizeof (clientcmd_pak); 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 = (mis ? PT_CLIENT2MIS : PT_CLIENT2CMD); - packetsize = sizeof (client2cmd_pak); + 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); } @@ -5155,7 +5035,7 @@ static void CL_SendClientCmd(void) if (localtextcmd[0]) { netbuffer->packettype = PT_TEXTCMD; - M_Memcpy(netbuffer->u.textcmd, localtextcmd, localtextcmd[0]+1); + 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; @@ -5299,7 +5179,7 @@ static void Local_Maketic(INT32 realtics) // game responder calls HU_Responder, AM_Responder, // and G_MapEventsToControls if (!dedicated) rendergametic = gametic; - // translate inputs (keyboard/mouse/joystick) into game controls + // translate inputs (keyboard/mouse/gamepad) into game controls G_BuildTiccmd(&localcmds, realtics, 1); if (splitscreen || botingame) G_BuildTiccmd(&localcmds2, realtics, 2); @@ -5535,11 +5415,28 @@ static inline void PingUpdate(void) pingmeasurecount = 1; //Reset count } -static tic_t gametime = 0; - -static void UpdatePingTable(void) +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) { @@ -5551,150 +5448,6 @@ static void UpdatePingTable(void) realpingtable[i] += G_TicsToMilliseconds(GetLag(playernode[i])); pingmeasurecount++; } -} - -// Handle timeouts to prevent definitive freezes from happenning -static void HandleNodeTimeouts(void) -{ - INT32 i; - - 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); - } -} - -// Keep the network alive while not advancing tics! -void NetKeepAlive(void) -{ - tic_t nowtime; - INT32 realtics; - - nowtime = I_GetTime(); - realtics = nowtime - gametime; - - // return if there's no time passed since the last call - if (realtics <= 0) // nothing new to update - return; - - UpdatePingTable(); - - GetPackets(); - -#ifdef MASTERSERVER - MasterClient_Ticker(); -#endif - - if (client) - { - // send keep alive - CL_SendClientKeepAlive(); - // No need to check for resynch because we aren't running any tics - } - else - { - SV_SendServerKeepAlive(); - } - - // No else because no tics are being run and we can't resynch during this - - Net_AckTicker(); - HandleNodeTimeouts(); - FileSendTicker(); -} - -void NetUpdate(void) -{ - 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; - } - - if (server && dedicated && gamestate == GS_LEVEL) - { - const tic_t dedicatedidletime = cv_dedicatedidletime.value * TICRATE; - static tic_t dedicatedidletimeprev = 0; - static tic_t dedicatedidle = 0; - - if (dedicatedidletime > 0) - { - for (i = 1; i < MAXNETNODES; ++i) - if (nodeingame[i]) - { - if (dedicatedidle >= dedicatedidletime) - { - CONS_Printf("DEDICATED: Awakening from idle (Node %d detected...)\n", i); - dedicatedidle = 0; - } - break; - } - - if (i == MAXNETNODES) - { - if (leveltime == 2) - { - // On next tick... - dedicatedidle = dedicatedidletime-1; - } - else if (dedicatedidle >= dedicatedidletime) - { - if (D_GetExistingTextcmd(gametic, 0) || D_GetExistingTextcmd(gametic+1, 0)) - { - CONS_Printf("DEDICATED: Awakening from idle (Netxcmd detected...)\n"); - dedicatedidle = 0; - } - else - { - realtics = 0; - } - } - else if ((dedicatedidle += realtics) >= dedicatedidletime) - { - const char *idlereason = "at round start"; - if (leveltime > 3) - idlereason = va("for %d seconds", dedicatedidle/TICRATE); - - CONS_Printf("DEDICATED: No nodes %s, idling...\n", idlereason); - realtics = 0; - dedicatedidle = dedicatedidletime; - } - } - } - else - { - if (dedicatedidletimeprev > 0 && dedicatedidle >= dedicatedidletimeprev) - { - CONS_Printf("DEDICATED: Awakening from idle (Idle disabled...)\n"); - } - dedicatedidle = 0; - } - - dedicatedidletimeprev = dedicatedidletime; - } - - gametime = nowtime; - - UpdatePingTable(); if (client) maketic = neededtic; @@ -5726,25 +5479,24 @@ void NetUpdate(void) } else { - if (!demoplayback && realtics > 0) + if (!demoplayback) { INT32 counts; hu_redownloadinggamestate = false; - // Don't erase tics not acknowledged - counts = realtics; - firstticstosend = gametic; for (i = 0; i < MAXNETNODES; i++) - { - if (!nodeingame[i]) - continue; - if (nettics[i] < firstticstosend) + if (nodeingame[i] && nettics[i] < firstticstosend) + { firstticstosend = nettics[i]; - if (maketic + counts >= nettics[i] + (BACKUPTICS - TICRATE)) - Net_ConnectionTimeout(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; @@ -5762,10 +5514,20 @@ void NetUpdate(void) } Net_AckTicker(); - HandleNodeTimeouts(); + + // 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; @@ -5796,19 +5558,6 @@ INT32 D_NumPlayers(void) return num; } -/** Similar to the above, but counts only bots. - * Purpose is to remove bots from both the player count and the - * max player count on the server view -*/ -INT32 D_NumBots(void) -{ - INT32 num = 0, ix; - for (ix = 0; ix < MAXPLAYERS; ix++) - if (playeringame[ix] && players[ix].bot) - num++; - return num; -} - tic_t GetLag(INT32 node) { return gametic - nettics[node]; diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 49fb5fc1d..e07864122 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-2023 by Sonic Team Junior. +// Copyright (C) 1999-2022 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -77,8 +77,6 @@ typedef enum PT_ASKLUAFILE, // Client telling the server they don't have the file PT_HASLUAFILE, // Client telling the server they have the file - PT_BASICKEEPALIVE,// Keep the network alive during wipes, as tics aren't advanced and NetUpdate isn't called - // Add non-PT_CANFAIL packet types here to avoid breaking MS compatibility. PT_CANFAIL, // This is kind of a priority. Anything bigger than CANFAIL @@ -160,7 +158,6 @@ typedef struct UINT8 gametype; UINT8 modifiedgame; - UINT8 usedCheats; char server_context[8]; // Unique context id, generated at server startup. } ATTRPACK serverconfig_pak; @@ -400,7 +397,6 @@ extern tic_t servermaxping; extern consvar_t cv_netticbuffer, cv_allownewplayer, cv_joinnextround, cv_maxplayers, cv_joindelay, cv_rejointimeout; extern consvar_t cv_resynchattempts, cv_blamecfail; extern consvar_t cv_maxsend, cv_noticedownload, cv_downloadspeed; -extern consvar_t cv_dedicatedidletime; // Used in d_net, the only dependence tic_t ExpandTics(INT32 low, INT32 node); @@ -415,9 +411,6 @@ void SendKick(UINT8 playernum, UINT8 msg); // Create any new ticcmds and broadcast to other players. void NetUpdate(void); -// Maintain connections to nodes without timing them all out. -void NetKeepAlive(void); - void SV_StartSinglePlayerServer(void); boolean SV_SpawnServer(void); void SV_StopServer(void); @@ -454,7 +447,6 @@ extern char motd[254], server_context[8]; extern UINT8 playernode[MAXPLAYERS]; INT32 D_NumPlayers(void); -INT32 D_NumBots(void); void D_ResetTiccmds(void); tic_t GetLag(INT32 node); diff --git a/src/d_net.c b/src/d_net.c index 6d8c72942..a7e1eb16d 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-2023 by Sonic Team Junior. +// Copyright (C) 1999-2022 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -869,9 +869,6 @@ static void DebugPrintpacket(const char *header) (UINT32)ExpandTics(netbuffer->u.clientpak.client_tic, doomcom->remotenode), (UINT32)ExpandTics (netbuffer->u.clientpak.resendfrom, doomcom->remotenode)); break; - case PT_BASICKEEPALIVE: - fprintf(debugfile, " wipetime\n"); - break; case PT_TEXTCMD: case PT_TEXTCMD2: fprintf(debugfile, " length %d\n ", netbuffer->u.textcmd[0]); @@ -1210,32 +1207,26 @@ static void Internal_FreeNodenum(INT32 nodenum) (void)nodenum; } -char *I_NetSplitAddress(char *host, char **port) -{ - boolean v4 = (strchr(host, '.') != NULL); - - host = strtok(host, v4 ? ":" : "[]"); - - if (port) - *port = strtok(NULL, ":"); - - return host; -} - SINT8 I_NetMakeNode(const char *hostname) { SINT8 newnode = -1; if (I_NetMakeNodewPort) { char *localhostname = strdup(hostname); - char *port; + char *t = localhostname; + const char *port; if (!localhostname) return newnode; - // retrieve portnum from address! - hostname = I_NetSplitAddress(localhostname, &port); + strtok(localhostname, ":"); + port = strtok(NULL, ":"); - newnode = I_NetMakeNodewPort(hostname, port); + // remove the port in the hostname as we've it already + while ((*t != ':') && (*t != '\0')) + t++; + *t = '\0'; + + newnode = I_NetMakeNodewPort(localhostname, port); free(localhostname); } return newnode; diff --git a/src/d_net.h b/src/d_net.h index ddedbef4a..5baa593a0 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-2023 by Sonic Team Junior. +// Copyright (C) 1999-2022 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 45a394eff..5f02bc2de 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-2023 by Sonic Team Junior. +// Copyright (C) 1999-2022 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -21,6 +21,7 @@ #include "g_game.h" #include "hu_stuff.h" #include "g_input.h" +#include "i_gamepad.h" #include "m_menu.h" #include "r_local.h" #include "r_skins.h" @@ -49,7 +50,6 @@ #include "m_anigif.h" #include "md5.h" #include "m_perfstats.h" -#include "u_list.h" #ifdef NETGAME_DEVMODE #define CV_RESTRICT CV_NETVAR @@ -182,14 +182,6 @@ static CV_PossibleValue_t mouse2port_cons_t[] = {{1, "COM1"}, {2, "COM2"}, {3, " {0, NULL}}; #endif -#ifdef LJOYSTICK -static CV_PossibleValue_t joyport_cons_t[] = {{1, "/dev/js0"}, {2, "/dev/js1"}, {3, "/dev/js2"}, - {4, "/dev/js3"}, {0, NULL}}; -#else -// accept whatever value - it is in fact the joystick device number -#define usejoystick_cons_t NULL -#endif - static CV_PossibleValue_t teamscramble_cons_t[] = {{0, "Off"}, {1, "Random"}, {2, "Points"}, {0, NULL}}; static CV_PossibleValue_t startingliveslimit_cons_t[] = {{1, "MIN"}, {99, "MAX"}, {0, NULL}}; @@ -203,37 +195,37 @@ static CV_PossibleValue_t matchboxes_cons_t[] = {{0, "Normal"}, {1, "Mystery"}, static CV_PossibleValue_t chances_cons_t[] = {{0, "MIN"}, {9, "MAX"}, {0, NULL}}; static CV_PossibleValue_t pause_cons_t[] = {{0, "Server"}, {1, "All"}, {0, NULL}}; -consvar_t cv_showinputjoy = CVAR_INIT ("showinputjoy", "Off", CV_ALLOWLUA, CV_OnOff, NULL); +consvar_t cv_showinputjoy = CVAR_INIT ("showinputjoy", "Off", 0, CV_OnOff, NULL); #ifdef NETGAME_DEVMODE static consvar_t cv_fishcake = CVAR_INIT ("fishcake", "Off", CV_CALL|CV_NOSHOWHELP|CV_RESTRICT, CV_OnOff, Fishcake_OnChange); #endif static consvar_t cv_dummyconsvar = CVAR_INIT ("dummyconsvar", "Off", CV_CALL|CV_NOSHOWHELP, CV_OnOff, DummyConsvar_OnChange); -consvar_t cv_restrictskinchange = CVAR_INIT ("restrictskinchange", "Yes", CV_SAVE|CV_NETVAR|CV_CHEAT|CV_ALLOWLUA, CV_YesNo, NULL); -consvar_t cv_allowteamchange = CVAR_INIT ("allowteamchange", "Yes", CV_SAVE|CV_NETVAR|CV_ALLOWLUA, CV_YesNo, NULL); +consvar_t cv_restrictskinchange = CVAR_INIT ("restrictskinchange", "Yes", CV_SAVE|CV_NETVAR|CV_CHEAT, CV_YesNo, NULL); +consvar_t cv_allowteamchange = CVAR_INIT ("allowteamchange", "Yes", CV_SAVE|CV_NETVAR, CV_YesNo, NULL); -consvar_t cv_startinglives = CVAR_INIT ("startinglives", "3", CV_SAVE|CV_NETVAR|CV_CHEAT|CV_ALLOWLUA, startingliveslimit_cons_t, NULL); +consvar_t cv_startinglives = CVAR_INIT ("startinglives", "3", CV_SAVE|CV_NETVAR|CV_CHEAT, startingliveslimit_cons_t, NULL); static CV_PossibleValue_t respawntime_cons_t[] = {{1, "MIN"}, {30, "MAX"}, {0, "Off"}, {0, NULL}}; -consvar_t cv_respawntime = CVAR_INIT ("respawndelay", "3", CV_SAVE|CV_NETVAR|CV_CHEAT|CV_ALLOWLUA, respawntime_cons_t, NULL); +consvar_t cv_respawntime = CVAR_INIT ("respawndelay", "3", CV_SAVE|CV_NETVAR|CV_CHEAT, respawntime_cons_t, NULL); -consvar_t cv_competitionboxes = CVAR_INIT ("competitionboxes", "Mystery", CV_SAVE|CV_NETVAR|CV_CHEAT|CV_ALLOWLUA, competitionboxes_cons_t, NULL); +consvar_t cv_competitionboxes = CVAR_INIT ("competitionboxes", "Mystery", CV_SAVE|CV_NETVAR|CV_CHEAT, competitionboxes_cons_t, NULL); 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|CV_ALLOWLUA, seenames_cons_t, 0); -consvar_t cv_allowseenames = CVAR_INIT ("allowseenames", "Yes", CV_SAVE|CV_NETVAR|CV_ALLOWLUA, CV_YesNo, 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); // names consvar_t cv_playername = CVAR_INIT ("name", "Sonic", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Name_OnChange); consvar_t cv_playername2 = CVAR_INIT ("name2", "Tails", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Name2_OnChange); // player colors UINT16 lastgoodcolor = SKINCOLOR_BLUE, lastgoodcolor2 = SKINCOLOR_BLUE; -consvar_t cv_playercolor = CVAR_INIT ("color", "Blue", CV_CALL|CV_NOINIT|CV_ALLOWLUA, Color_cons_t, Color_OnChange); -consvar_t cv_playercolor2 = CVAR_INIT ("color2", "Orange", CV_CALL|CV_NOINIT|CV_ALLOWLUA, Color_cons_t, Color2_OnChange); +consvar_t cv_playercolor = CVAR_INIT ("color", "Blue", CV_CALL|CV_NOINIT, Color_cons_t, Color_OnChange); +consvar_t cv_playercolor2 = CVAR_INIT ("color2", "Orange", CV_CALL|CV_NOINIT, Color_cons_t, Color2_OnChange); // player's skin, saved for commodity, when using a favorite skins wad.. -consvar_t cv_skin = CVAR_INIT ("skin", DEFAULTSKIN, CV_CALL|CV_NOINIT|CV_ALLOWLUA, NULL, Skin_OnChange); -consvar_t cv_skin2 = CVAR_INIT ("skin2", DEFAULTSKIN2, CV_CALL|CV_NOINIT|CV_ALLOWLUA, NULL, Skin2_OnChange); +consvar_t cv_skin = CVAR_INIT ("skin", DEFAULTSKIN, CV_CALL|CV_NOINIT, NULL, Skin_OnChange); +consvar_t cv_skin2 = CVAR_INIT ("skin2", DEFAULTSKIN2, CV_CALL|CV_NOINIT, NULL, Skin2_OnChange); // saved versions of the above six consvar_t cv_defaultplayercolor = CVAR_INIT ("defaultcolor", "Blue", CV_SAVE, Color_cons_t, NULL); @@ -248,19 +240,61 @@ INT32 cv_debug; consvar_t cv_usemouse = CVAR_INIT ("use_mouse", "On", CV_SAVE|CV_CALL,usemouse_cons_t, I_StartupMouse); consvar_t cv_usemouse2 = CVAR_INIT ("use_mouse2", "Off", CV_SAVE|CV_CALL,usemouse_cons_t, I_StartupMouse2); -consvar_t cv_usejoystick = CVAR_INIT ("use_gamepad", "1", CV_SAVE|CV_CALL, usejoystick_cons_t, I_InitJoystick); -consvar_t cv_usejoystick2 = CVAR_INIT ("use_gamepad2", "2", CV_SAVE|CV_CALL, usejoystick_cons_t, I_InitJoystick2); -#if (defined (LJOYSTICK) || defined (HAVE_SDL)) -#ifdef LJOYSTICK -consvar_t cv_joyport = CVAR_INIT ("padport", "/dev/js0", CV_SAVE, joyport_cons_t, NULL); -consvar_t cv_joyport2 = CVAR_INIT ("padport2", "/dev/js0", CV_SAVE, joyport_cons_t, NULL); //Alam: for later -#endif -consvar_t cv_joyscale = CVAR_INIT ("padscale", "1", CV_SAVE|CV_CALL, NULL, I_JoyScale); -consvar_t cv_joyscale2 = CVAR_INIT ("padscale2", "1", CV_SAVE|CV_CALL, NULL, I_JoyScale2); -#else -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 +// We use cv_usegamepad.string as the USER-SET var +// and cv_usegamepad.value as the INTERNAL var +// +// In practice, if cv_usegamepad.string == 0, this overrides +// cv_usegamepad.value and always disables + +static void UseGamepad_OnChange(void) +{ + I_ChangeGamepad(0); +} + +static void UseGamepad2_OnChange(void) +{ + I_ChangeGamepad(1); +} + +consvar_t cv_usegamepad[2] = { + CVAR_INIT ("use_gamepad", "1", CV_SAVE|CV_CALL, NULL, UseGamepad_OnChange), + CVAR_INIT ("use_gamepad2", "2", CV_SAVE|CV_CALL, NULL, UseGamepad2_OnChange) +}; + +static void PadScale_OnChange(void) +{ + I_SetGamepadDigital(0, cv_gamepad_scale[0].value == 0); +} + +static void PadScale2_OnChange(void) +{ + I_SetGamepadDigital(1, cv_gamepad_scale[1].value == 0); +} + +consvar_t cv_gamepad_scale[2] = { + CVAR_INIT ("padscale", "1", CV_SAVE|CV_CALL, NULL, PadScale_OnChange), + CVAR_INIT ("padscale2", "1", CV_SAVE|CV_CALL, NULL, PadScale2_OnChange) +}; + +static void PadRumble_OnChange(void) +{ + if (!cv_gamepad_rumble[0].value) + I_StopGamepadRumble(0); +} + +static void PadRumble2_OnChange(void) +{ + if (!cv_gamepad_rumble[1].value) + I_StopGamepadRumble(1); +} + +consvar_t cv_gamepad_rumble[2] = { + CVAR_INIT ("padrumble", "Off", CV_SAVE|CV_CALL, CV_OnOff, PadRumble_OnChange), + CVAR_INIT ("padrumble2", "Off", CV_SAVE|CV_CALL, CV_OnOff, PadRumble2_OnChange) +}; + +consvar_t cv_gamepad_autopause = CVAR_INIT ("pauseongamepaddisconnect", "On", CV_SAVE, CV_OnOff, NULL); + #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); @@ -268,43 +302,43 @@ consvar_t cv_mouse2opt = CVAR_INIT ("mouse2opt", "0", CV_SAVE, NULL, NULL); consvar_t cv_mouse2port = CVAR_INIT ("mouse2port", "COM2", CV_SAVE, mouse2port_cons_t, NULL); #endif -consvar_t cv_matchboxes = CVAR_INIT ("matchboxes", "Normal", CV_SAVE|CV_NETVAR|CV_CHEAT|CV_ALLOWLUA, matchboxes_cons_t, NULL); -consvar_t cv_specialrings = CVAR_INIT ("specialrings", "On", CV_SAVE|CV_NETVAR|CV_ALLOWLUA, CV_OnOff, NULL); -consvar_t cv_powerstones = CVAR_INIT ("powerstones", "On", CV_SAVE|CV_NETVAR|CV_ALLOWLUA, CV_OnOff, NULL); +consvar_t cv_matchboxes = CVAR_INIT ("matchboxes", "Normal", CV_SAVE|CV_NETVAR|CV_CHEAT, matchboxes_cons_t, NULL); +consvar_t cv_specialrings = CVAR_INIT ("specialrings", "On", CV_SAVE|CV_NETVAR, CV_OnOff, NULL); +consvar_t cv_powerstones = CVAR_INIT ("powerstones", "On", CV_SAVE|CV_NETVAR, CV_OnOff, NULL); -consvar_t cv_recycler = CVAR_INIT ("tv_recycler", "5", CV_SAVE|CV_NETVAR|CV_CHEAT|CV_ALLOWLUA, chances_cons_t, NULL); -consvar_t cv_teleporters = CVAR_INIT ("tv_teleporter", "5", CV_SAVE|CV_NETVAR|CV_CHEAT|CV_ALLOWLUA, chances_cons_t, NULL); -consvar_t cv_superring = CVAR_INIT ("tv_superring", "5", CV_SAVE|CV_NETVAR|CV_CHEAT|CV_ALLOWLUA, chances_cons_t, NULL); -consvar_t cv_supersneakers = CVAR_INIT ("tv_supersneaker", "5", CV_SAVE|CV_NETVAR|CV_CHEAT|CV_ALLOWLUA, chances_cons_t, NULL); -consvar_t cv_invincibility = CVAR_INIT ("tv_invincibility", "5", CV_SAVE|CV_NETVAR|CV_CHEAT|CV_ALLOWLUA, chances_cons_t, NULL); -consvar_t cv_jumpshield = CVAR_INIT ("tv_jumpshield", "5", CV_SAVE|CV_NETVAR|CV_CHEAT|CV_ALLOWLUA, chances_cons_t, NULL); -consvar_t cv_watershield = CVAR_INIT ("tv_watershield", "5", CV_SAVE|CV_NETVAR|CV_CHEAT|CV_ALLOWLUA, chances_cons_t, NULL); -consvar_t cv_ringshield = CVAR_INIT ("tv_ringshield", "5", CV_SAVE|CV_NETVAR|CV_CHEAT|CV_ALLOWLUA, chances_cons_t, NULL); -consvar_t cv_forceshield = CVAR_INIT ("tv_forceshield", "5", CV_SAVE|CV_NETVAR|CV_CHEAT|CV_ALLOWLUA, chances_cons_t, NULL); -consvar_t cv_bombshield = CVAR_INIT ("tv_bombshield", "5", CV_SAVE|CV_NETVAR|CV_CHEAT|CV_ALLOWLUA, chances_cons_t, NULL); -consvar_t cv_1up = CVAR_INIT ("tv_1up", "5", CV_SAVE|CV_NETVAR|CV_CHEAT|CV_ALLOWLUA, chances_cons_t, NULL); -consvar_t cv_eggmanbox = CVAR_INIT ("tv_eggman", "5", CV_SAVE|CV_NETVAR|CV_CHEAT|CV_ALLOWLUA, chances_cons_t, NULL); +consvar_t cv_recycler = CVAR_INIT ("tv_recycler", "5", CV_SAVE|CV_NETVAR|CV_CHEAT, chances_cons_t, NULL); +consvar_t cv_teleporters = CVAR_INIT ("tv_teleporter", "5", CV_SAVE|CV_NETVAR|CV_CHEAT, chances_cons_t, NULL); +consvar_t cv_superring = CVAR_INIT ("tv_superring", "5", CV_SAVE|CV_NETVAR|CV_CHEAT, chances_cons_t, NULL); +consvar_t cv_supersneakers = CVAR_INIT ("tv_supersneaker", "5", CV_SAVE|CV_NETVAR|CV_CHEAT, chances_cons_t, NULL); +consvar_t cv_invincibility = CVAR_INIT ("tv_invincibility", "5", CV_SAVE|CV_NETVAR|CV_CHEAT, chances_cons_t, NULL); +consvar_t cv_jumpshield = CVAR_INIT ("tv_jumpshield", "5", CV_SAVE|CV_NETVAR|CV_CHEAT, chances_cons_t, NULL); +consvar_t cv_watershield = CVAR_INIT ("tv_watershield", "5", CV_SAVE|CV_NETVAR|CV_CHEAT, chances_cons_t, NULL); +consvar_t cv_ringshield = CVAR_INIT ("tv_ringshield", "5", CV_SAVE|CV_NETVAR|CV_CHEAT, chances_cons_t, NULL); +consvar_t cv_forceshield = CVAR_INIT ("tv_forceshield", "5", CV_SAVE|CV_NETVAR|CV_CHEAT, chances_cons_t, NULL); +consvar_t cv_bombshield = CVAR_INIT ("tv_bombshield", "5", CV_SAVE|CV_NETVAR|CV_CHEAT, chances_cons_t, NULL); +consvar_t cv_1up = CVAR_INIT ("tv_1up", "5", CV_SAVE|CV_NETVAR|CV_CHEAT, chances_cons_t, NULL); +consvar_t cv_eggmanbox = CVAR_INIT ("tv_eggman", "5", CV_SAVE|CV_NETVAR|CV_CHEAT, chances_cons_t, NULL); -consvar_t cv_ringslinger = CVAR_INIT ("ringslinger", "No", CV_NETVAR|CV_NOSHOWHELP|CV_CALL|CV_CHEAT|CV_ALLOWLUA, CV_YesNo, Ringslinger_OnChange); -consvar_t cv_gravity = CVAR_INIT ("gravity", "0.5", CV_RESTRICT|CV_FLOAT|CV_CALL|CV_ALLOWLUA, NULL, Gravity_OnChange); +consvar_t cv_ringslinger = CVAR_INIT ("ringslinger", "No", CV_NETVAR|CV_NOSHOWHELP|CV_CALL|CV_CHEAT, CV_YesNo, Ringslinger_OnChange); +consvar_t cv_gravity = CVAR_INIT ("gravity", "0.5", CV_RESTRICT|CV_FLOAT|CV_CALL, NULL, Gravity_OnChange); consvar_t cv_soundtest = CVAR_INIT ("soundtest", "0", CV_CALL, NULL, SoundTest_OnChange); 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|CV_ALLOWLUA, minitimelimit_cons_t, 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_ALLOWLUA, CV_OnOff, NULL); -consvar_t cv_hidetime = CVAR_INIT ("hidetime", "30", CV_SAVE|CV_NETVAR|CV_CALL|CV_ALLOWLUA, minitimelimit_cons_t, Hidetime_OnChange); +consvar_t cv_touchtag = CVAR_INIT ("touchtag", "Off", CV_SAVE|CV_NETVAR, CV_OnOff, NULL); +consvar_t cv_hidetime = CVAR_INIT ("hidetime", "30", CV_SAVE|CV_NETVAR|CV_CALL, minitimelimit_cons_t, Hidetime_OnChange); -consvar_t cv_autobalance = CVAR_INIT ("autobalance", "Off", CV_SAVE|CV_NETVAR|CV_CALL|CV_ALLOWLUA, CV_OnOff, AutoBalance_OnChange); -consvar_t cv_teamscramble = CVAR_INIT ("teamscramble", "Off", CV_SAVE|CV_NETVAR|CV_CALL|CV_NOINIT|CV_ALLOWLUA, teamscramble_cons_t, TeamScramble_OnChange); -consvar_t cv_scrambleonchange = CVAR_INIT ("scrambleonchange", "Off", CV_SAVE|CV_NETVAR|CV_ALLOWLUA, teamscramble_cons_t, NULL); +consvar_t cv_autobalance = CVAR_INIT ("autobalance", "Off", CV_SAVE|CV_NETVAR|CV_CALL, CV_OnOff, AutoBalance_OnChange); +consvar_t cv_teamscramble = CVAR_INIT ("teamscramble", "Off", CV_SAVE|CV_NETVAR|CV_CALL|CV_NOINIT, teamscramble_cons_t, TeamScramble_OnChange); +consvar_t cv_scrambleonchange = CVAR_INIT ("scrambleonchange", "Off", CV_SAVE|CV_NETVAR, teamscramble_cons_t, NULL); -consvar_t cv_friendlyfire = CVAR_INIT ("friendlyfire", "Off", CV_SAVE|CV_NETVAR|CV_ALLOWLUA, CV_OnOff, NULL); -consvar_t cv_itemfinder = CVAR_INIT ("itemfinder", "Off", CV_CALL|CV_ALLOWLUA, CV_OnOff, ItemFinder_OnChange); +consvar_t cv_friendlyfire = CVAR_INIT ("friendlyfire", "Off", CV_SAVE|CV_NETVAR, CV_OnOff, NULL); +consvar_t cv_itemfinder = CVAR_INIT ("itemfinder", "Off", CV_CALL, CV_OnOff, ItemFinder_OnChange); // Scoring type options -consvar_t cv_overtime = CVAR_INIT ("overtime", "Yes", CV_SAVE|CV_NETVAR|CV_ALLOWLUA, CV_YesNo, NULL); +consvar_t cv_overtime = CVAR_INIT ("overtime", "Yes", CV_SAVE|CV_NETVAR, CV_YesNo, NULL); consvar_t cv_rollingdemos = CVAR_INIT ("rollingdemos", "On", CV_SAVE, CV_OnOff, NULL); @@ -315,13 +349,13 @@ static CV_PossibleValue_t powerupdisplay_cons_t[] = {{0, "Never"}, {1, "First-pe consvar_t cv_powerupdisplay = CVAR_INIT ("powerupdisplay", "First-person only", CV_SAVE, powerupdisplay_cons_t, NULL); static CV_PossibleValue_t pointlimit_cons_t[] = {{1, "MIN"}, {MAXSCORE, "MAX"}, {0, "None"}, {0, NULL}}; -consvar_t cv_pointlimit = CVAR_INIT ("pointlimit", "None", CV_SAVE|CV_NETVAR|CV_CALL|CV_NOINIT|CV_ALLOWLUA, pointlimit_cons_t, PointLimit_OnChange); +consvar_t cv_pointlimit = CVAR_INIT ("pointlimit", "None", CV_SAVE|CV_NETVAR|CV_CALL|CV_NOINIT, pointlimit_cons_t, PointLimit_OnChange); static CV_PossibleValue_t timelimit_cons_t[] = {{1, "MIN"}, {30, "MAX"}, {0, "None"}, {0, NULL}}; -consvar_t cv_timelimit = CVAR_INIT ("timelimit", "None", CV_SAVE|CV_NETVAR|CV_CALL|CV_NOINIT|CV_ALLOWLUA, timelimit_cons_t, TimeLimit_OnChange); +consvar_t cv_timelimit = CVAR_INIT ("timelimit", "None", CV_SAVE|CV_NETVAR|CV_CALL|CV_NOINIT, timelimit_cons_t, TimeLimit_OnChange); static CV_PossibleValue_t numlaps_cons_t[] = {{1, "MIN"}, {50, "MAX"}, {0, NULL}}; -consvar_t cv_numlaps = CVAR_INIT ("numlaps", "4", CV_NETVAR|CV_CALL|CV_NOINIT|CV_ALLOWLUA, numlaps_cons_t, NumLaps_OnChange); +consvar_t cv_numlaps = CVAR_INIT ("numlaps", "4", CV_NETVAR|CV_CALL|CV_NOINIT, numlaps_cons_t, NumLaps_OnChange); static CV_PossibleValue_t basenumlaps_cons_t[] = {{1, "MIN"}, {50, "MAX"}, {0, "Map default"}, {0, NULL}}; -consvar_t cv_basenumlaps = CVAR_INIT ("basenumlaps", "Map default", CV_SAVE|CV_NETVAR|CV_CALL|CV_CHEAT|CV_ALLOWLUA, basenumlaps_cons_t, BaseNumLaps_OnChange); +consvar_t cv_basenumlaps = CVAR_INIT ("basenumlaps", "Map default", CV_SAVE|CV_NETVAR|CV_CALL|CV_CHEAT, basenumlaps_cons_t, BaseNumLaps_OnChange); // Point and time limits for every gametype INT32 pointlimits[NUMGAMETYPES]; @@ -330,11 +364,11 @@ INT32 timelimits[NUMGAMETYPES]; // log elemental hazards -- not a netvar, is local to current player consvar_t cv_hazardlog = CVAR_INIT ("hazardlog", "Yes", 0, CV_YesNo, NULL); -consvar_t cv_forceskin = CVAR_INIT ("forceskin", "None", CV_NETVAR|CV_CALL|CV_CHEAT|CV_ALLOWLUA, NULL, ForceSkin_OnChange); +consvar_t cv_forceskin = CVAR_INIT ("forceskin", "None", CV_NETVAR|CV_CALL|CV_CHEAT, NULL, ForceSkin_OnChange); consvar_t cv_downloading = CVAR_INIT ("downloading", "On", 0, CV_OnOff, NULL); -consvar_t cv_allowexitlevel = CVAR_INIT ("allowexitlevel", "No", CV_SAVE|CV_NETVAR|CV_ALLOWLUA, CV_YesNo, NULL); +consvar_t cv_allowexitlevel = CVAR_INIT ("allowexitlevel", "No", CV_SAVE|CV_NETVAR, CV_YesNo, NULL); -consvar_t cv_killingdead = CVAR_INIT ("killingdead", "Off", CV_NETVAR|CV_ALLOWLUA, CV_OnOff, NULL); +consvar_t cv_killingdead = CVAR_INIT ("killingdead", "Off", CV_NETVAR, CV_OnOff, NULL); consvar_t cv_netstat = CVAR_INIT ("netstat", "Off", 0, CV_OnOff, NULL); // show bandwidth statistics static CV_PossibleValue_t nettimeout_cons_t[] = {{TICRATE/7, "MIN"}, {60*TICRATE, "MAX"}, {0, NULL}}; @@ -352,26 +386,26 @@ consvar_t cv_showping = CVAR_INIT ("showping", "Warning", CV_SAVE, showping_cons // Intermission time Tails 04-19-2002 static CV_PossibleValue_t inttime_cons_t[] = {{0, "MIN"}, {3600, "MAX"}, {0, NULL}}; -consvar_t cv_inttime = CVAR_INIT ("inttime", "10", CV_SAVE|CV_NETVAR|CV_ALLOWLUA, inttime_cons_t, NULL); +consvar_t cv_inttime = CVAR_INIT ("inttime", "10", CV_SAVE|CV_NETVAR, inttime_cons_t, NULL); static CV_PossibleValue_t coopstarposts_cons_t[] = {{0, "Per-player"}, {1, "Shared"}, {2, "Teamwork"}, {0, NULL}}; -consvar_t cv_coopstarposts = CVAR_INIT ("coopstarposts", "Per-player", CV_SAVE|CV_NETVAR|CV_CALL|CV_ALLOWLUA, coopstarposts_cons_t, CoopStarposts_OnChange); +consvar_t cv_coopstarposts = CVAR_INIT ("coopstarposts", "Per-player", CV_SAVE|CV_NETVAR|CV_CALL, coopstarposts_cons_t, CoopStarposts_OnChange); static CV_PossibleValue_t cooplives_cons_t[] = {{0, "Infinite"}, {1, "Per-player"}, {2, "Avoid Game Over"}, {3, "Single pool"}, {0, NULL}}; -consvar_t cv_cooplives = CVAR_INIT ("cooplives", "Avoid Game Over", CV_SAVE|CV_NETVAR|CV_CALL|CV_CHEAT|CV_ALLOWLUA, cooplives_cons_t, CoopLives_OnChange); +consvar_t cv_cooplives = CVAR_INIT ("cooplives", "Avoid Game Over", CV_SAVE|CV_NETVAR|CV_CALL|CV_CHEAT, cooplives_cons_t, CoopLives_OnChange); static CV_PossibleValue_t advancemap_cons_t[] = {{0, "Off"}, {1, "Next"}, {2, "Random"}, {0, NULL}}; -consvar_t cv_advancemap = CVAR_INIT ("advancemap", "Next", CV_SAVE|CV_NETVAR|CV_ALLOWLUA, advancemap_cons_t, NULL); +consvar_t cv_advancemap = CVAR_INIT ("advancemap", "Next", CV_SAVE|CV_NETVAR, advancemap_cons_t, NULL); static CV_PossibleValue_t playersforexit_cons_t[] = {{0, "One"}, {1, "1/4"}, {2, "Half"}, {3, "3/4"}, {4, "All"}, {0, NULL}}; -consvar_t cv_playersforexit = CVAR_INIT ("playersforexit", "All", CV_SAVE|CV_NETVAR|CV_ALLOWLUA, playersforexit_cons_t, NULL); +consvar_t cv_playersforexit = CVAR_INIT ("playersforexit", "All", CV_SAVE|CV_NETVAR, playersforexit_cons_t, NULL); -consvar_t cv_exitmove = CVAR_INIT ("exitmove", "On", CV_SAVE|CV_NETVAR|CV_CALL|CV_ALLOWLUA, CV_OnOff, ExitMove_OnChange); +consvar_t cv_exitmove = CVAR_INIT ("exitmove", "On", CV_SAVE|CV_NETVAR|CV_CALL, CV_OnOff, ExitMove_OnChange); -consvar_t cv_runscripts = CVAR_INIT ("runscripts", "Yes", CV_ALLOWLUA, CV_YesNo, NULL); +consvar_t cv_runscripts = CVAR_INIT ("runscripts", "Yes", 0, CV_YesNo, NULL); -consvar_t cv_pause = CVAR_INIT ("pausepermission", "Server", CV_SAVE|CV_NETVAR|CV_ALLOWLUA, pause_cons_t, NULL); -consvar_t cv_mute = CVAR_INIT ("mute", "Off", CV_NETVAR|CV_CALL|CV_ALLOWLUA, CV_OnOff, Mute_OnChange); +consvar_t cv_pause = CVAR_INIT ("pausepermission", "Server", CV_SAVE|CV_NETVAR, pause_cons_t, NULL); +consvar_t cv_mute = CVAR_INIT ("mute", "Off", CV_NETVAR|CV_CALL, CV_OnOff, Mute_OnChange); consvar_t cv_sleep = CVAR_INIT ("cpusleep", "1", CV_SAVE, sleeping_cons_t, NULL); @@ -464,57 +498,57 @@ void D_RegisterServerCommands(void) RegisterNetXCmd(XD_LUAFILE, Got_LuaFile); // Remote Administration - COM_AddCommand("password", Command_Changepassword_f, COM_LUA); - COM_AddCommand("login", Command_Login_f, COM_LUA); // useful in dedicated to kick off remote admin - COM_AddCommand("promote", Command_Verify_f, COM_LUA); + COM_AddCommand("password", Command_Changepassword_f); + COM_AddCommand("login", Command_Login_f); // useful in dedicated to kick off remote admin + COM_AddCommand("promote", Command_Verify_f); RegisterNetXCmd(XD_VERIFIED, Got_Verification); - COM_AddCommand("demote", Command_RemoveAdmin_f, COM_LUA); + COM_AddCommand("demote", Command_RemoveAdmin_f); RegisterNetXCmd(XD_DEMOTED, Got_Removal); - COM_AddCommand("motd", Command_MotD_f, COM_LUA); + COM_AddCommand("motd", Command_MotD_f); RegisterNetXCmd(XD_SETMOTD, Got_MotD_f); // For remote admin RegisterNetXCmd(XD_TEAMCHANGE, Got_Teamchange); - COM_AddCommand("serverchangeteam", Command_ServerTeamChange_f, COM_LUA); + COM_AddCommand("serverchangeteam", Command_ServerTeamChange_f); RegisterNetXCmd(XD_CLEARSCORES, Got_Clearscores); - COM_AddCommand("clearscores", Command_Clearscores_f, COM_LUA); - COM_AddCommand("map", Command_Map_f, COM_LUA); + COM_AddCommand("clearscores", Command_Clearscores_f); + COM_AddCommand("map", Command_Map_f); - COM_AddCommand("exitgame", Command_ExitGame_f, COM_LUA); - COM_AddCommand("retry", Command_Retry_f, COM_LUA); - COM_AddCommand("exitlevel", Command_ExitLevel_f, COM_LUA); - COM_AddCommand("showmap", Command_Showmap_f, COM_LUA); - COM_AddCommand("mapmd5", Command_Mapmd5_f, COM_LUA); + COM_AddCommand("exitgame", Command_ExitGame_f); + COM_AddCommand("retry", Command_Retry_f); + COM_AddCommand("exitlevel", Command_ExitLevel_f); + COM_AddCommand("showmap", Command_Showmap_f); + COM_AddCommand("mapmd5", Command_Mapmd5_f); - COM_AddCommand("addfolder", Command_Addfolder, COM_LUA); - COM_AddCommand("addfile", Command_Addfile, COM_LUA); - COM_AddCommand("listwad", Command_ListWADS_f, COM_LUA); + COM_AddCommand("addfolder", Command_Addfolder); + COM_AddCommand("addfile", Command_Addfile); + COM_AddCommand("listwad", Command_ListWADS_f); - COM_AddCommand("runsoc", Command_RunSOC, COM_LUA); - COM_AddCommand("pause", Command_Pause, COM_LUA); - COM_AddCommand("suicide", Command_Suicide, COM_LUA); + COM_AddCommand("runsoc", Command_RunSOC); + COM_AddCommand("pause", Command_Pause); + COM_AddCommand("suicide", Command_Suicide); - COM_AddCommand("gametype", Command_ShowGametype_f, COM_LUA); - COM_AddCommand("version", Command_Version_f, COM_LUA); + COM_AddCommand("gametype", Command_ShowGametype_f); + COM_AddCommand("version", Command_Version_f); #ifdef UPDATE_ALERT - COM_AddCommand("mod_details", Command_ModDetails_f, COM_LUA); + COM_AddCommand("mod_details", Command_ModDetails_f); #endif - COM_AddCommand("quit", Command_Quit_f, COM_LUA); + COM_AddCommand("quit", Command_Quit_f); - COM_AddCommand("saveconfig", Command_SaveConfig_f, 0); - COM_AddCommand("loadconfig", Command_LoadConfig_f, 0); - COM_AddCommand("changeconfig", Command_ChangeConfig_f, 0); - COM_AddCommand("isgamemodified", Command_Isgamemodified_f, COM_LUA); // test - COM_AddCommand("showscores", Command_ShowScores_f, COM_LUA); - COM_AddCommand("showtime", Command_ShowTime_f, COM_LUA); - COM_AddCommand("cheats", Command_Cheats_f, COM_LUA); // test + COM_AddCommand("saveconfig", Command_SaveConfig_f); + COM_AddCommand("loadconfig", Command_LoadConfig_f); + COM_AddCommand("changeconfig", Command_ChangeConfig_f); + COM_AddCommand("isgamemodified", Command_Isgamemodified_f); // test + COM_AddCommand("showscores", Command_ShowScores_f); + COM_AddCommand("showtime", Command_ShowTime_f); + COM_AddCommand("cheats", Command_Cheats_f); // test #ifdef _DEBUG - COM_AddCommand("togglemodified", Command_Togglemodified_f, COM_LUA); - COM_AddCommand("archivetest", Command_Archivetest_f, COM_LUA); + COM_AddCommand("togglemodified", Command_Togglemodified_f); + COM_AddCommand("archivetest", Command_Archivetest_f); #endif - COM_AddCommand("downloads", Command_Downloads_f, COM_LUA); + COM_AddCommand("downloads", Command_Downloads_f); // for master server connection AddMServCommands(); @@ -599,10 +633,9 @@ void D_RegisterServerCommands(void) CV_RegisterVar(&cv_joinnextround); CV_RegisterVar(&cv_showjoinaddress); CV_RegisterVar(&cv_blamecfail); - CV_RegisterVar(&cv_dedicatedidletime); #endif - COM_AddCommand("ping", Command_Ping_f, COM_LUA); + COM_AddCommand("ping", Command_Ping_f); CV_RegisterVar(&cv_nettimeout); CV_RegisterVar(&cv_jointimeout); @@ -614,10 +647,6 @@ void D_RegisterServerCommands(void) CV_RegisterVar(&cv_allowseenames); - // Other filesrch.c consvars are defined in D_RegisterClientCommands - CV_RegisterVar(&cv_addons_option); - CV_RegisterVar(&cv_addons_folder); - CV_RegisterVar(&cv_dummyconsvar); } @@ -650,25 +679,25 @@ void D_RegisterClientCommands(void) if (dedicated) return; - COM_AddCommand("numthinkers", Command_Numthinkers_f, COM_LUA); - COM_AddCommand("countmobjs", Command_CountMobjs_f, COM_LUA); + COM_AddCommand("numthinkers", Command_Numthinkers_f); + COM_AddCommand("countmobjs", Command_CountMobjs_f); - COM_AddCommand("changeteam", Command_Teamchange_f, COM_LUA); - COM_AddCommand("changeteam2", Command_Teamchange2_f, COM_LUA); + COM_AddCommand("changeteam", Command_Teamchange_f); + COM_AddCommand("changeteam2", Command_Teamchange2_f); - COM_AddCommand("playdemo", Command_Playdemo_f, 0); - COM_AddCommand("timedemo", Command_Timedemo_f, 0); - COM_AddCommand("stopdemo", Command_Stopdemo_f, COM_LUA); - COM_AddCommand("playintro", Command_Playintro_f, COM_LUA); + COM_AddCommand("playdemo", Command_Playdemo_f); + COM_AddCommand("timedemo", Command_Timedemo_f); + COM_AddCommand("stopdemo", Command_Stopdemo_f); + COM_AddCommand("playintro", Command_Playintro_f); - COM_AddCommand("resetcamera", Command_ResetCamera_f, COM_LUA); + COM_AddCommand("resetcamera", Command_ResetCamera_f); - COM_AddCommand("setcontrol", Command_Setcontrol_f, 0); - COM_AddCommand("setcontrol2", Command_Setcontrol2_f, 0); + COM_AddCommand("setcontrol", Command_Setcontrol_f); + COM_AddCommand("setcontrol2", Command_Setcontrol2_f); - COM_AddCommand("screenshot", M_ScreenShot, COM_LUA); - COM_AddCommand("startmovie", Command_StartMovie_f, COM_LUA); - COM_AddCommand("stopmovie", Command_StopMovie_f, COM_LUA); + COM_AddCommand("screenshot", M_ScreenShot); + COM_AddCommand("startmovie", Command_StartMovie_f); + COM_AddCommand("stopmovie", Command_StopMovie_f); CV_RegisterVar(&cv_screenshot_option); CV_RegisterVar(&cv_screenshot_folder); @@ -730,7 +759,7 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_ghost_last); CV_RegisterVar(&cv_ghost_guest); - COM_AddCommand("displayplayer", Command_Displayplayer_f, COM_LUA); + COM_AddCommand("displayplayer", Command_Displayplayer_f); // FIXME: not to be here.. but needs be done for config loading CV_RegisterVar(&cv_globalgamma); @@ -777,30 +806,30 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_pauseifunfocused); // g_input.c - CV_RegisterVar(&cv_sideaxis); - CV_RegisterVar(&cv_sideaxis2); - CV_RegisterVar(&cv_turnaxis); - CV_RegisterVar(&cv_turnaxis2); - CV_RegisterVar(&cv_moveaxis); - CV_RegisterVar(&cv_moveaxis2); - CV_RegisterVar(&cv_lookaxis); - CV_RegisterVar(&cv_lookaxis2); - CV_RegisterVar(&cv_jumpaxis); - CV_RegisterVar(&cv_jumpaxis2); - CV_RegisterVar(&cv_spinaxis); - CV_RegisterVar(&cv_spinaxis2); - CV_RegisterVar(&cv_fireaxis); - CV_RegisterVar(&cv_fireaxis2); - CV_RegisterVar(&cv_firenaxis); - CV_RegisterVar(&cv_firenaxis2); - CV_RegisterVar(&cv_deadzone); - CV_RegisterVar(&cv_deadzone2); - CV_RegisterVar(&cv_digitaldeadzone); - CV_RegisterVar(&cv_digitaldeadzone2); + CV_RegisterVar(&cv_sideaxis[0]); + CV_RegisterVar(&cv_sideaxis[1]); + CV_RegisterVar(&cv_turnaxis[0]); + CV_RegisterVar(&cv_turnaxis[1]); + CV_RegisterVar(&cv_moveaxis[0]); + CV_RegisterVar(&cv_moveaxis[1]); + CV_RegisterVar(&cv_lookaxis[0]); + CV_RegisterVar(&cv_lookaxis[1]); + CV_RegisterVar(&cv_jumpaxis[0]); + CV_RegisterVar(&cv_jumpaxis[1]); + CV_RegisterVar(&cv_spinaxis[0]); + CV_RegisterVar(&cv_spinaxis[1]); + CV_RegisterVar(&cv_fireaxis[0]); + CV_RegisterVar(&cv_fireaxis[1]); + CV_RegisterVar(&cv_firenaxis[0]); + CV_RegisterVar(&cv_firenaxis[1]); + CV_RegisterVar(&cv_deadzone[0]); + CV_RegisterVar(&cv_deadzone[1]); + CV_RegisterVar(&cv_digitaldeadzone[0]); + CV_RegisterVar(&cv_digitaldeadzone[1]); // filesrch.c - //CV_RegisterVar(&cv_addons_option); // These two are now defined - //CV_RegisterVar(&cv_addons_folder); // in D_RegisterServerCommands + CV_RegisterVar(&cv_addons_option); + CV_RegisterVar(&cv_addons_folder); CV_RegisterVar(&cv_addons_md5); CV_RegisterVar(&cv_addons_showall); CV_RegisterVar(&cv_addons_search_type); @@ -825,14 +854,14 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_mousemove); CV_RegisterVar(&cv_mousemove2); - CV_RegisterVar(&cv_usejoystick); - CV_RegisterVar(&cv_usejoystick2); -#ifdef LJOYSTICK - CV_RegisterVar(&cv_joyport); - CV_RegisterVar(&cv_joyport2); -#endif - CV_RegisterVar(&cv_joyscale); - CV_RegisterVar(&cv_joyscale2); + for (i = 0; i < 2; i++) + { + CV_RegisterVar(&cv_usegamepad[i]); + CV_RegisterVar(&cv_gamepad_scale[i]); + CV_RegisterVar(&cv_gamepad_rumble[i]); + } + + CV_RegisterVar(&cv_gamepad_autopause); // Analog Control CV_RegisterVar(&cv_analog[0]); @@ -874,15 +903,10 @@ void D_RegisterClientCommands(void) // screen.c CV_RegisterVar(&cv_fullscreen); CV_RegisterVar(&cv_renderview); - CV_RegisterVar(&cv_renderhitboxinterpolation); - CV_RegisterVar(&cv_renderhitboxgldepth); - CV_RegisterVar(&cv_renderhitbox); CV_RegisterVar(&cv_renderer); CV_RegisterVar(&cv_scr_depth); CV_RegisterVar(&cv_scr_width); CV_RegisterVar(&cv_scr_height); - CV_RegisterVar(&cv_scr_width_w); - CV_RegisterVar(&cv_scr_height_w); CV_RegisterVar(&cv_soundtest); @@ -891,7 +915,7 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_ps_descriptor); // ingame object placing - COM_AddCommand("objectplace", Command_ObjectPlace_f, COM_LUA); + COM_AddCommand("objectplace", Command_ObjectPlace_f); //COM_AddCommand("writethings", Command_Writethings_f); CV_RegisterVar(&cv_speed); CV_RegisterVar(&cv_opflags); @@ -903,32 +927,32 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_freedemocamera); // add cheat commands - COM_AddCommand("noclip", Command_CheatNoClip_f, COM_LUA); - COM_AddCommand("god", Command_CheatGod_f, COM_LUA); - COM_AddCommand("notarget", Command_CheatNoTarget_f, COM_LUA); - COM_AddCommand("getallemeralds", Command_Getallemeralds_f, COM_LUA); - COM_AddCommand("resetemeralds", Command_Resetemeralds_f, COM_LUA); - COM_AddCommand("setrings", Command_Setrings_f, COM_LUA); - COM_AddCommand("setlives", Command_Setlives_f, COM_LUA); - COM_AddCommand("setcontinues", Command_Setcontinues_f, COM_LUA); - COM_AddCommand("devmode", Command_Devmode_f, COM_LUA); - COM_AddCommand("savecheckpoint", Command_Savecheckpoint_f, COM_LUA); - COM_AddCommand("scale", Command_Scale_f, COM_LUA); - COM_AddCommand("gravflip", Command_Gravflip_f, COM_LUA); - COM_AddCommand("hurtme", Command_Hurtme_f, COM_LUA); - COM_AddCommand("jumptoaxis", Command_JumpToAxis_f, COM_LUA); - COM_AddCommand("charability", Command_Charability_f, COM_LUA); - COM_AddCommand("charspeed", Command_Charspeed_f, COM_LUA); - COM_AddCommand("teleport", Command_Teleport_f, COM_LUA); - COM_AddCommand("rteleport", Command_RTeleport_f, COM_LUA); - COM_AddCommand("skynum", Command_Skynum_f, COM_LUA); - COM_AddCommand("weather", Command_Weather_f, COM_LUA); - COM_AddCommand("toggletwod", Command_Toggletwod_f, COM_LUA); + COM_AddCommand("noclip", Command_CheatNoClip_f); + COM_AddCommand("god", Command_CheatGod_f); + COM_AddCommand("notarget", Command_CheatNoTarget_f); + COM_AddCommand("getallemeralds", Command_Getallemeralds_f); + COM_AddCommand("resetemeralds", Command_Resetemeralds_f); + COM_AddCommand("setrings", Command_Setrings_f); + COM_AddCommand("setlives", Command_Setlives_f); + COM_AddCommand("setcontinues", Command_Setcontinues_f); + COM_AddCommand("devmode", Command_Devmode_f); + COM_AddCommand("savecheckpoint", Command_Savecheckpoint_f); + COM_AddCommand("scale", Command_Scale_f); + COM_AddCommand("gravflip", Command_Gravflip_f); + COM_AddCommand("hurtme", Command_Hurtme_f); + COM_AddCommand("jumptoaxis", Command_JumpToAxis_f); + COM_AddCommand("charability", Command_Charability_f); + COM_AddCommand("charspeed", Command_Charspeed_f); + COM_AddCommand("teleport", Command_Teleport_f); + COM_AddCommand("rteleport", Command_RTeleport_f); + COM_AddCommand("skynum", Command_Skynum_f); + COM_AddCommand("weather", Command_Weather_f); + COM_AddCommand("toggletwod", Command_Toggletwod_f); #ifdef _DEBUG - COM_AddCommand("causecfail", Command_CauseCfail_f, COM_LUA); + COM_AddCommand("causecfail", Command_CauseCfail_f); #endif #ifdef LUA_ALLOW_BYTECODE - COM_AddCommand("dumplua", Command_Dumplua_f, COM_LUA); + COM_AddCommand("dumplua", Command_Dumplua_f); #endif } @@ -1643,14 +1667,9 @@ static void Command_Playdemo_f(void) { char name[256]; - if (COM_Argc() < 2) + if (COM_Argc() != 2) { - CONS_Printf("playdemo [-addfiles / -force]:\n"); - CONS_Printf(M_GetText( - "Play back a demo file. The full path from your SRB2 directory must be given.\n\n" - - "* With \"-addfiles\", any required files are added from a list contained within the demo file.\n" - "* With \"-force\", the demo is played even if the necessary files have not been added.\n")); + CONS_Printf(M_GetText("playdemo : playback a demo\n")); return; } @@ -1672,16 +1691,6 @@ static void Command_Playdemo_f(void) CONS_Printf(M_GetText("Playing back demo '%s'.\n"), name); - demofileoverride = DFILE_OVERRIDE_NONE; - if (strcmp(COM_Argv(2), "-addfiles") == 0) - { - demofileoverride = DFILE_OVERRIDE_LOAD; - } - else if (strcmp(COM_Argv(2), "-force") == 0) - { - demofileoverride = DFILE_OVERRIDE_SKIP; - } - // Internal if no extension, external if one exists // If external, convert the file name to a path in SRB2's home directory if (FIL_CheckExtension(name)) @@ -1903,7 +1912,7 @@ static void Command_Map_f(void) const char *gametypename; boolean newresetplayers; - boolean wouldSetCheats; + boolean mustmodifygame; INT32 newmapnum; @@ -1924,11 +1933,11 @@ static void Command_Map_f(void) option_gametype = COM_CheckPartialParm("-g"); newresetplayers = ! COM_CheckParm("-noresetplayers"); - wouldSetCheats = - !( netgame || multiplayer ) && - !( usedCheats ); + mustmodifygame = + !( netgame || multiplayer ) && + (!modifiedgame || savemoddata ); - if (wouldSetCheats && !option_force) + if (mustmodifygame && !option_force) { /* May want to be more descriptive? */ CONS_Printf(M_GetText("Sorry, level change disabled in single player.\n")); @@ -1982,9 +1991,9 @@ static void Command_Map_f(void) return; } - if (wouldSetCheats && option_force) + if (mustmodifygame && option_force) { - G_SetUsedCheats(false); + G_SetGameModified(false); } // new gametype value @@ -2057,7 +2066,7 @@ static void Command_Map_f(void) // ... unless you're in a dedicated server. Yes, technically this means you can view any level by // running a dedicated server and joining it yourself, but that's better than making dedicated server's // lives hell. - if (!dedicated && M_MapLocked(newmapnum, serverGamedata)) + if (!dedicated && M_MapLocked(newmapnum)) { CONS_Alert(CONS_NOTICE, M_GetText("You need to unlock this level before you can warp to it!\n")); Z_Free(realmapname); @@ -2192,7 +2201,7 @@ static void Command_Pause(void) if (cv_pause.value || server || (IsPlayerAdmin(consoleplayer))) { - if (modeattacking || !(gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_WAITINGPLAYERS) || (marathonmode && 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; @@ -2241,9 +2250,14 @@ static void Got_Pause(UINT8 **cp, INT32 playernum) { if (!menuactive || netgame) S_PauseAudio(); + + P_PauseRumble(NULL); } else + { S_ResumeAudio(); + P_UnpauseRumble(NULL); + } } I_UpdateMouseGrab(); @@ -2355,7 +2369,7 @@ static void Got_Clearscores(UINT8 **cp, INT32 playernum) } for (i = 0; i < MAXPLAYERS; i++) - players[i].score = players[i].recordscore = 0; + players[i].score = 0; CONS_Printf(M_GetText("Scores have been reset by the server.\n")); } @@ -3298,69 +3312,6 @@ static void Got_RunSOCcmd(UINT8 **cp, INT32 playernum) G_SetGameModified(true); } -// C++ would make this SO much simpler! -typedef struct addedfile_s -{ - struct addedfile_s *next; - struct addedfile_s *prev; - char *value; -} addedfile_t; - -static boolean AddedFileContains(addedfile_t *list, const char *value) -{ - addedfile_t *node; - for (node = list; node; node = node->next) - { - if (!strcmp(value, node->value)) - return true; - } - - return false; -} - -static void AddedFilesAdd(addedfile_t **list, const char *value) -{ - addedfile_t *item = Z_Calloc(sizeof(addedfile_t), PU_STATIC, NULL); - item->value = Z_StrDup(value); - ListAdd(item, (listitem_t**)list); -} - -static void AddedFilesRemove(void *pItem, addedfile_t **itemHead) -{ - addedfile_t *item = (addedfile_t *)pItem; - - if (item == *itemHead) // Start of list - { - *itemHead = item->next; - - if (*itemHead) - (*itemHead)->prev = NULL; - } - else if (item->next == NULL) // end of list - { - item->prev->next = NULL; - } - else // Somewhere in between - { - item->prev->next = item->next; - item->next->prev = item->prev; - } - - Z_Free(item->value); - Z_Free(item); -} - -static void AddedFilesClearList(addedfile_t **itemHead) -{ - addedfile_t *item; - addedfile_t *next; - for (item = *itemHead; item; item = next) - { - next = item->next; - AddedFilesRemove(item, itemHead); - } -} - /** Adds a pwad at runtime. * Searches for sounds, maps, music, new images. */ @@ -3369,7 +3320,8 @@ static void Command_Addfile(void) size_t argc = COM_Argc(); // amount of arguments total size_t curarg; // current argument index - addedfile_t *addedfiles = NULL; // list of filenames already processed + const char *addedfiles[argc]; // list of filenames already processed + size_t numfilesadded = 0; // the amount of filenames processed if (argc < 2) { @@ -3384,14 +3336,25 @@ static void Command_Addfile(void) char buf[256]; char *buf_p = buf; INT32 i; + size_t ii; int musiconly; // W_VerifyNMUSlumps isn't boolean boolean fileadded = false; fn = COM_Argv(curarg); // For the amount of filenames previously processed... - fileadded = AddedFileContains(addedfiles, fn); - if (fileadded) // If this is one of them, don't try to add it. + for (ii = 0; ii < numfilesadded; ii++) + { + // If this is one of them, don't try to add it. + if (!strcmp(fn, addedfiles[ii])) + { + fileadded = true; + break; + } + } + + // If we've added this one, skip to the next one. + if (fileadded) { CONS_Alert(CONS_WARNING, M_GetText("Already processed %s, skipping\n"), fn); continue; @@ -3400,16 +3363,13 @@ static void Command_Addfile(void) // Disallow non-printing characters and semicolons. for (i = 0; fn[i] != '\0'; i++) if (!isprint(fn[i]) || fn[i] == ';') - { - AddedFilesClearList(&addedfiles); return; - } musiconly = W_VerifyNMUSlumps(fn, false); if (musiconly == -1) { - AddedFilesAdd(&addedfiles, fn); + addedfiles[numfilesadded++] = fn; continue; } @@ -3428,7 +3388,7 @@ static void Command_Addfile(void) if (!(netgame || multiplayer) || musiconly) { P_AddWadFile(fn); - AddedFilesAdd(&addedfiles, fn); + addedfiles[numfilesadded++] = fn; continue; } @@ -3443,7 +3403,6 @@ static void Command_Addfile(void) if (numwadfiles >= MAX_WADFILES) { CONS_Alert(CONS_ERROR, M_GetText("Too many files loaded to add %s\n"), fn); - AddedFilesClearList(&addedfiles); return; } @@ -3483,15 +3442,13 @@ static void Command_Addfile(void) WRITEMEM(buf_p, md5sum, 16); } - AddedFilesAdd(&addedfiles, fn); + addedfiles[numfilesadded++] = fn; if (IsPlayerAdmin(consoleplayer) && (!server)) // Request to add file SendNetXCmd(XD_REQADDFILE, buf, buf_p - buf); else SendNetXCmd(XD_ADDFILE, buf, buf_p - buf); } - - AddedFilesClearList(&addedfiles); } static void Command_Addfolder(void) @@ -3499,7 +3456,8 @@ static void Command_Addfolder(void) size_t argc = COM_Argc(); // amount of arguments total size_t curarg; // current argument index - addedfile_t *addedfolders = NULL; // list of filenames already processed + const char *addedfolders[argc]; // list of filenames already processed + size_t numfoldersadded = 0; // the amount of filenames processed if (argc < 2) { @@ -3515,13 +3473,24 @@ static void Command_Addfolder(void) char buf[256]; char *buf_p = buf; INT32 i, stat; + size_t ii; boolean folderadded = false; fn = COM_Argv(curarg); // For the amount of filenames previously processed... - folderadded = AddedFileContains(addedfolders, fn); - if (folderadded) // If we've added this one, skip to the next one. + 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; @@ -3530,16 +3499,13 @@ static void Command_Addfolder(void) // Disallow non-printing characters and semicolons. for (i = 0; fn[i] != '\0'; i++) if (!isprint(fn[i]) || fn[i] == ';') - { - AddedFilesClearList(&addedfolders); return; - } // Add file on your client directly if you aren't in a netgame. if (!(netgame || multiplayer)) { P_AddFolder(fn); - AddedFilesAdd(&addedfolders, fn); + addedfolders[numfoldersadded++] = fn; continue; } @@ -3561,7 +3527,6 @@ static void Command_Addfolder(void) if (numwadfiles >= MAX_WADFILES) { CONS_Alert(CONS_ERROR, M_GetText("Too many files loaded to add %s\n"), fn); - AddedFilesClearList(&addedfolders); return; } @@ -3607,7 +3572,7 @@ static void Command_Addfolder(void) Z_Free(fullpath); - AddedFilesAdd(&addedfolders, fn); + addedfolders[numfoldersadded++] = fn; WRITESTRINGN(buf_p,p,240); @@ -3966,12 +3931,18 @@ void ItemFinder_OnChange(void) if (!cv_itemfinder.value) return; // it's fine. - if (!M_SecretUnlocked(SECRET_ITEMFINDER, clientGamedata)) + if (!M_SecretUnlocked(SECRET_ITEMFINDER)) { CONS_Printf(M_GetText("You haven't earned this yet.\n")); CV_StealthSetValue(&cv_itemfinder, 0); return; } + else if (netgame || multiplayer) + { + CONS_Printf(M_GetText("This only works in single player.\n")); + CV_StealthSetValue(&cv_itemfinder, 0); + return; + } } /** Deals with a pointlimit change by printing the change to the console. @@ -4320,7 +4291,7 @@ void D_GameTypeChanged(INT32 lastgametype) static void Ringslinger_OnChange(void) { - if (!M_SecretUnlocked(SECRET_PANDORA, serverGamedata) && !netgame && cv_ringslinger.value && !cv_debug) + if (!M_SecretUnlocked(SECRET_PANDORA) && !netgame && cv_ringslinger.value && !cv_debug) { CONS_Printf(M_GetText("You haven't earned this yet.\n")); CV_StealthSetValue(&cv_ringslinger, 0); @@ -4328,12 +4299,12 @@ static void Ringslinger_OnChange(void) } if (cv_ringslinger.value) // Only if it's been turned on - G_SetUsedCheats(false); + G_SetGameModified(multiplayer); } static void Gravity_OnChange(void) { - if (!M_SecretUnlocked(SECRET_PANDORA, serverGamedata) && !netgame && !cv_debug + if (!M_SecretUnlocked(SECRET_PANDORA) && !netgame && !cv_debug && strcmp(cv_gravity.string, cv_gravity.defaultvalue)) { CONS_Printf(M_GetText("You haven't earned this yet.\n")); @@ -4349,7 +4320,7 @@ static void Gravity_OnChange(void) #endif if (!CV_IsSetToDefault(&cv_gravity)) - G_SetUsedCheats(false); + G_SetGameModified(multiplayer); gravity = cv_gravity.value; } @@ -4630,9 +4601,10 @@ void Command_ExitGame_f(void) botskin = 0; cv_debug = 0; emeralds = 0; - automapactive = false; memset(&luabanks, 0, sizeof(luabanks)); + P_StopRumble(NULL); + if (dirmenu) closefilemenu(true); @@ -4666,7 +4638,7 @@ static void Fishcake_OnChange(void) // so don't make modifiedgame always on! if (cv_debug) { - G_SetUsedCheats(false); + G_SetGameModified(multiplayer); } else if (cv_debug != cv_fishcake.value) @@ -4683,11 +4655,11 @@ static void Fishcake_OnChange(void) static void Command_Isgamemodified_f(void) { if (savemoddata) - CONS_Printf(M_GetText("modifiedgame is true, but you can save time data in this mod.\n")); + CONS_Printf(M_GetText("modifiedgame is true, but you can save emblem and time data in this mod.\n")); else if (modifiedgame) - CONS_Printf(M_GetText("modifiedgame is true, time data can't be saved\n")); + CONS_Printf(M_GetText("modifiedgame is true, extras will not be unlocked\n")); else - CONS_Printf(M_GetText("modifiedgame is false, you can save time data\n")); + CONS_Printf(M_GetText("modifiedgame is false, you can unlock extras\n")); } static void Command_Cheats_f(void) diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 26bf4d5c6..47f68a17e 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-2023 by Sonic Team Junior. +// Copyright (C) 1999-2022 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -33,14 +33,10 @@ extern consvar_t cv_defaultskin2; extern consvar_t cv_seenames, cv_allowseenames; extern consvar_t cv_usemouse; -extern consvar_t cv_usejoystick; -extern consvar_t cv_usejoystick2; -#ifdef LJOYSTICK -extern consvar_t cv_joyport; -extern consvar_t cv_joyport2; -#endif -extern consvar_t cv_joyscale; -extern consvar_t cv_joyscale2; +extern consvar_t cv_usegamepad[2]; +extern consvar_t cv_gamepad_scale[2]; +extern consvar_t cv_gamepad_rumble[2]; +extern consvar_t cv_gamepad_autopause; // splitscreen with second mouse extern consvar_t cv_mouse2port; diff --git a/src/d_netfil.c b/src/d_netfil.c index 3fef75681..edbef30bb 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-2023 by Sonic Team Junior. +// Copyright (C) 1999-2022 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -498,7 +498,7 @@ INT32 CL_CheckFiles(void) CONS_Debug(DBG_NETPLAY, "searching for '%s' ", fileneeded[i].filename); // Check in already loaded files - for (j = mainwads; j < numwadfiles; j++) + for (j = mainwads; wadfiles[j]; j++) { nameonly(strcpy(wadfilename, wadfiles[j]->filename)); if (!stricmp(wadfilename, fileneeded[i].filename) && diff --git a/src/d_netfil.h b/src/d_netfil.h index ecec976be..f778a518f 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-2023 by Sonic Team Junior. +// Copyright (C) 1999-2022 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 b7032e89a..b0ef37fa1 100644 --- a/src/http-mserv.c +++ b/src/http-mserv.c @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2020-2023 by James R. +// Copyright (C) 2020-2022 by James R. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -65,8 +65,6 @@ static I_mutex hms_api_mutex; static char *hms_server_token; -static char hms_useragent[512]; - struct HMS_buffer { CURL *curl; @@ -83,22 +81,6 @@ Contact_error (void) ); } -static void -get_user_agent(char *buf, size_t len) -{ - if (snprintf(buf, len, "%s/%s (%s; %s; %i; %i) SRB2BASE/%i", SRB2APPLICATION, VERSIONSTRING, compbranch, comprevision, MODID, MODVERSION, CODEBASE) < 0) - I_Error("http-mserv: get_user_agent failed"); -} - -static void -init_user_agent_once(void) -{ - if (hms_useragent[0] != '\0') - return; - - get_user_agent(hms_useragent, 512); -} - static size_t HMS_on_read (char *s, size_t _1, size_t n, void *userdata) { @@ -174,8 +156,6 @@ HMS_connect (const char *format, ...) I_lock_mutex(&hms_api_mutex); #endif - init_user_agent_once(); - seek = strlen(hms_api) + 1;/* + '/' */ va_start (ap, format); @@ -216,18 +196,12 @@ HMS_connect (const char *format, ...) curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); - -#ifndef NO_IPV6 - if (M_CheckParm("-noipv6")) -#endif - curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); + curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); curl_easy_setopt(curl, CURLOPT_TIMEOUT, cv_masterserver_timeout.value); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, HMS_on_read); curl_easy_setopt(curl, CURLOPT_WRITEDATA, buffer); - curl_easy_setopt(curl, CURLOPT_USERAGENT, hms_useragent); - curl_free(quack_token); free(url); diff --git a/src/i_addrinfo.c b/src/i_addrinfo.c index 9efaff4da..49aadf27d 100644 --- a/src/i_addrinfo.c +++ b/src/i_addrinfo.c @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2011-2023 by Sonic Team Junior. +// Copyright (C) 2011-2022 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 79cfb05b2..592e693f4 100644 --- a/src/i_addrinfo.h +++ b/src/i_addrinfo.h @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2011-2023 by Sonic Team Junior. +// Copyright (C) 2011-2022 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 12a07f183..62b7528d5 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-2023 by Sonic Team Junior. +// Copyright (C) 1999-2022 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -109,17 +109,6 @@ extern boolean (*I_NetCanSend)(void); */ extern void (*I_NetFreeNodenum)(INT32 nodenum); -/** - \brief split a string into address and port - - \param address string to split - - \param port double pointer to hold port component (optional) - - \return address component -*/ -extern char *I_NetSplitAddress(char *address, char **port); - /** \brief open a connection with specified address \param address address to connect to diff --git a/src/i_tcp.c b/src/i_tcp.c index d95b381f4..8838ba725 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-2023 by Sonic Team Junior. +// Copyright (C) 1999-2022 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -340,14 +340,8 @@ static inline void I_UPnP_rem(const char *port, const char * servicetype) static const char *SOCK_AddrToStr(mysockaddr_t *sk) { - static char s[64]; // 255.255.255.255:65535 or - // [ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]:65535 + static char s[64]; // 255.255.255.255:65535 or IPv6:65535 #ifdef HAVE_NTOP -#ifdef HAVE_IPV6 - int v6 = (sk->any.sa_family == AF_INET6); -#else - int v6 = 0; -#endif void *addr; if(sk->any.sa_family == AF_INET) @@ -361,21 +355,14 @@ static const char *SOCK_AddrToStr(mysockaddr_t *sk) if(addr == NULL) sprintf(s, "No address"); - else if(inet_ntop(sk->any.sa_family, addr, &s[v6], sizeof (s) - v6) == NULL) + else if(inet_ntop(sk->any.sa_family, addr, s, sizeof (s)) == NULL) sprintf(s, "Unknown family type, error #%u", errno); #ifdef HAVE_IPV6 - else if(sk->any.sa_family == AF_INET6) - { - s[0] = '['; - strcat(s, "]"); - - if (sk->ip6.sin6_port != 0) - strcat(s, va(":%d", ntohs(sk->ip6.sin6_port))); - } + else if(sk->any.sa_family == AF_INET6 && sk->ip6.sin6_port != 0) + strcat(s, va(":%d", ntohs(sk->ip6.sin6_port))); #endif else if(sk->any.sa_family == AF_INET && sk->ip4.sin_port != 0) strcat(s, va(":%d", ntohs(sk->ip4.sin_port))); - #else if (sk->any.sa_family == AF_INET) { @@ -440,7 +427,7 @@ static boolean SOCK_cmpaddr(mysockaddr_t *a, mysockaddr_t *b, UINT8 mask) && (b->ip4.sin_port == 0 || (a->ip4.sin_port == b->ip4.sin_port)); #ifdef HAVE_IPV6 else if (b->any.sa_family == AF_INET6) - return !memcmp(&a->ip6.sin6_addr, &b->ip6.sin6_addr, sizeof(b->ip6.sin6_addr)) + return memcmp(&a->ip6.sin6_addr, &b->ip6.sin6_addr, sizeof(b->ip6.sin6_addr)) && (b->ip6.sin6_port == 0 || (a->ip6.sin6_port == b->ip6.sin6_port)); #endif else @@ -748,7 +735,8 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen unsigned long trueval = true; #endif mysockaddr_t straddr; - socklen_t len = sizeof(straddr); + struct sockaddr_in sin; + socklen_t len = sizeof(sin); if (s == (SOCKET_TYPE)ERRSOCKET) return (SOCKET_TYPE)ERRSOCKET; @@ -766,12 +754,14 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen } #endif - memcpy(&straddr, addr, addrlen); + straddr.any = *addr; I_OutputMsg("Binding to %s\n", SOCK_AddrToStr(&straddr)); if (family == AF_INET) { - if (straddr.ip4.sin_addr.s_addr == htonl(INADDR_ANY)) + mysockaddr_t tmpaddr; + tmpaddr.any = *addr ; + if (tmpaddr.ip4.sin_addr.s_addr == htonl(INADDR_ANY)) { opt = true; opts = (socklen_t)sizeof(opt); @@ -788,7 +778,7 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen #ifdef HAVE_IPV6 else if (family == AF_INET6) { - if (memcmp(&straddr.ip6.sin6_addr, &in6addr_any, sizeof(in6addr_any)) == 0) //IN6_ARE_ADDR_EQUAL + if (memcmp(addr, &in6addr_any, sizeof(in6addr_any)) == 0) //IN6_ARE_ADDR_EQUAL { opt = true; opts = (socklen_t)sizeof(opt); @@ -798,7 +788,7 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen // make it IPv6 ony opt = true; opts = (socklen_t)sizeof(opt); - if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&opt, opts)) + if (setsockopt(s, SOL_SOCKET, IPV6_V6ONLY, (char *)&opt, opts)) { CONS_Alert(CONS_WARNING, M_GetText("Could not limit IPv6 bind\n")); // I do not care anymore } @@ -840,17 +830,10 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen CONS_Printf(M_GetText("Network system buffer set to: %dKb\n"), opt>>10); } - if (getsockname(s, &straddr.any, &len) == -1) + if (getsockname(s, (struct sockaddr *)&sin, &len) == -1) CONS_Alert(CONS_WARNING, M_GetText("Failed to get port number\n")); else - { - if (family == AF_INET) - current_port = (UINT16)ntohs(straddr.ip4.sin_port); -#ifdef HAVE_IPV6 - else if (family == AF_INET6) - current_port = (UINT16)ntohs(straddr.ip6.sin6_port); -#endif - } + current_port = (UINT16)ntohs(sin.sin_port); return s; } @@ -861,7 +844,7 @@ static boolean UDP_Socket(void) struct my_addrinfo *ai, *runp, hints; int gaie; #ifdef HAVE_IPV6 - const INT32 b_ipv6 = !M_CheckParm("-noipv6"); + const INT32 b_ipv6 = M_CheckParm("-ipv6"); #endif const char *serv; @@ -1173,7 +1156,6 @@ static SINT8 SOCK_NetMakeNodewPort(const char *address, const char *port) SINT8 newnode = -1; struct my_addrinfo *ai = NULL, *runp, hints; int gaie; - size_t i; if (!port || !port[0]) port = DEFAULTPORT; @@ -1201,24 +1183,13 @@ static SINT8 SOCK_NetMakeNodewPort(const char *address, const char *port) while (runp != NULL) { - // test ip address of server - for (i = 0; i < mysocketses; ++i) + // find ip of the server + if (sendto(mysockets[0], NULL, 0, 0, runp->ai_addr, runp->ai_addrlen) == 0) { - /* sendto tests that there is a network to this - address */ - if (runp->ai_addr->sa_family == myfamily[i] && - sendto(mysockets[i], NULL, 0, 0, - runp->ai_addr, runp->ai_addrlen) == 0) - { - memcpy(&clientaddress[newnode], runp->ai_addr, runp->ai_addrlen); - break; - } - } - - if (i < mysocketses) - runp = runp->ai_next; - else + memcpy(&clientaddress[newnode], runp->ai_addr, runp->ai_addrlen); break; + } + runp = runp->ai_next; } I_freeaddrinfo(ai); return newnode; diff --git a/src/i_tcp.h b/src/i_tcp.h index ae9983bf1..b6e5b9235 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-2023 by Sonic Team Junior. +// Copyright (C) 1999-2022 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 62cda96e4..bff562c95 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-2023 by Sonic Team Junior. -// Copyright (C) 2020-2023 by James R. +// Copyright (C) 1999-2022 by Sonic Team Junior. +// Copyright (C) 2020-2022 by James R. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -62,7 +62,7 @@ static CV_PossibleValue_t masterserver_update_rate_cons_t[] = { }; consvar_t cv_masterserver = CVAR_INIT ("masterserver", "https://mb.srb2.org/MS/0", CV_SAVE|CV_CALL, NULL, MasterServer_OnChange); -consvar_t cv_servername = CVAR_INIT ("servername", "SRB2 server", CV_SAVE|CV_NETVAR|CV_CALL|CV_NOINIT|CV_ALLOWLUA, NULL, Update_parameters); +consvar_t cv_servername = CVAR_INIT ("servername", "SRB2 server", CV_SAVE|CV_NETVAR|CV_CALL|CV_NOINIT, NULL, Update_parameters); consvar_t cv_masterserver_update_rate = CVAR_INIT ("masterserver_update_rate", "15", CV_SAVE|CV_CALL|CV_NOINIT, masterserver_update_rate_cons_t, Update_parameters); @@ -97,8 +97,8 @@ void AddMServCommands(void) CV_RegisterVar(&cv_masterserver_token); CV_RegisterVar(&cv_servername); #ifdef MASTERSERVER - COM_AddCommand("listserv", Command_Listserv_f, 0); - COM_AddCommand("masterserver_update", Update_parameters, COM_LUA); // allows people to updates manually in case you were delisted by accident + COM_AddCommand("listserv", Command_Listserv_f); + COM_AddCommand("masterserver_update", Update_parameters); // allows people to updates manually in case you were delisted by accident #endif #endif } diff --git a/src/mserv.h b/src/mserv.h index 07253da85..23b26fbc5 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-2023 by Sonic Team Junior. -// Copyright (C) 2020-2023 by James R. +// Copyright (C) 1999-2022 by Sonic Team Junior. +// Copyright (C) 2020-2022 by James R. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -33,7 +33,7 @@ typedef union typedef struct { msg_header_t header; - char ip[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"]; + char ip[16]; char port[8]; char name[32]; INT32 room; From 77253157899492a2c7aab1967f7995b90c46fbbe Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Wed, 28 Dec 2022 16:12:05 +0100 Subject: [PATCH 314/586] Move snake minigame to its own files --- src/Sourcefile | 1 + src/d_clisrv.c | 525 +----------------------------------------------- src/snake.c | 535 +++++++++++++++++++++++++++++++++++++++++++++++++ src/snake.h | 20 ++ 4 files changed, 564 insertions(+), 517 deletions(-) create mode 100644 src/snake.c create mode 100644 src/snake.h diff --git a/src/Sourcefile b/src/Sourcefile index 7c5305000..c55752b09 100644 --- a/src/Sourcefile +++ b/src/Sourcefile @@ -84,6 +84,7 @@ lzf.c vid_copy.s b_bot.c u_list.c +snake.c lua_script.c lua_baselib.c lua_mathlib.c diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 3091f3344..be10e4f9b 100755 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -57,6 +57,7 @@ // cl loading screen #include "v_video.h" #include "f_finale.h" +#include "snake.h" #endif // @@ -543,505 +544,7 @@ static cl_mode_t cl_mode = CL_SEARCHING; static UINT16 cl_lastcheckedfilecount = 0; // used for full file list #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; - UINT16 joystate = 0; - - // Handle retry - if (snake->gameover && (G_PlayerInputDown(0, GC_JUMP) || gamekeydown[KEY_ENTER])) - { - Snake_Initialise(); - snake->pausepressed = true; // Avoid accidental pause on respawn - } - - // Handle pause - if (G_PlayerInputDown(0, 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 (G_PlayerInputDown(0, GC_STRAFELEFT) || gamekeydown[KEY_LEFTARROW] || joystate == 3) - { - if (snake->snakelength < 2 || x <= oldx) - snake->snakedir[0] = 1; - } - else if (G_PlayerInputDown(0, GC_STRAFERIGHT) || gamekeydown[KEY_RIGHTARROW] || joystate == 4) - { - if (snake->snakelength < 2 || x >= oldx) - snake->snakedir[0] = 2; - } - else if (G_PlayerInputDown(0, GC_FORWARD) || gamekeydown[KEY_UPARROW] || joystate == 1) - { - if (snake->snakelength < 2 || y <= oldy) - snake->snakedir[0] = 3; - } - else if (G_PlayerInputDown(0, GC_BACKWARD) || gamekeydown[KEY_DOWNARROW] || joystate == 2) - { - 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_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); - - 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 - ); -} +static void *snake = NULL; static void CL_DrawConnectionStatusBox(void) { @@ -1167,7 +670,7 @@ static inline void CL_DrawConnectionStatus(void) char *filename; if (snake) - Snake_Draw(); + Snake_Draw(snake); // Draw the bottom box. CL_DrawConnectionStatusBox(); @@ -1213,7 +716,7 @@ static inline void CL_DrawConnectionStatus(void) else { if (snake) - Snake_Draw(); + Snake_Draw(snake); CL_DrawConnectionStatusBox(); V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-16-24, V_YELLOWMAP, @@ -1950,7 +1453,7 @@ static void M_ConfirmConnect(event_t *ev) if (CL_SendFileRequest()) { cl_mode = CL_DOWNLOADFILES; - Snake_Initialise(); + Snake_Allocate(&snake); } } else @@ -2300,13 +1803,7 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic if (waitmore) break; // exit the case -#ifndef NONET - if (snake) - { - free(snake); - snake = NULL; - } -#endif + Snake_Free(&snake); cl_mode = CL_LOADFILES; break; @@ -2401,13 +1898,7 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic 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 + Snake_Free(&snake); D_QuitNetGame(); CL_Reset(); @@ -2417,7 +1908,7 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic } #ifndef NONET else if (cl_mode == CL_DOWNLOADFILES && snake) - Snake_Handle(); + Snake_Update(snake); #endif if (client && (cl_mode == CL_DOWNLOADFILES || cl_mode == CL_DOWNLOADSAVEGAME)) diff --git a/src/snake.c b/src/snake.c new file mode 100644 index 000000000..2c80adeb9 --- /dev/null +++ b/src/snake.c @@ -0,0 +1,535 @@ +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 2023-2023 by Louis-Antoine de Moulins de Rochefort. +// +// 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 snake.c +/// \brief Snake minigame for the download screen. + +#include "snake.h" +#include "g_input.h" +#include "m_random.h" +#include "s_sound.h" +#include "screen.h" +#include "v_video.h" +#include "w_wad.h" +#include "z_zone.h" + +#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, +}; + +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 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", +}; + +static void Snake_Initialise(snake_t *snake) +{ + 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(snake_t *snake, 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; +} + +void Snake_Allocate(void **opaque) +{ + if (*opaque) + Snake_Free(opaque); + *opaque = malloc(sizeof(snake_t)); + Snake_Initialise(*opaque); +} + +void Snake_Update(void *opaque) +{ + UINT8 x, y; + UINT8 oldx, oldy; + UINT16 i; + UINT16 joystate = 0; + + snake_t *snake = opaque; + + // Handle retry + if (snake->gameover && (G_PlayerInputDown(0, GC_JUMP) || gamekeydown[KEY_ENTER])) + { + Snake_Initialise(snake); + snake->pausepressed = true; // Avoid accidental pause on respawn + } + + // Handle pause + if (G_PlayerInputDown(0, 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 (G_PlayerInputDown(0, GC_STRAFELEFT) || gamekeydown[KEY_LEFTARROW] || joystate == 3) + { + if (snake->snakelength < 2 || x <= oldx) + snake->snakedir[0] = 1; + } + else if (G_PlayerInputDown(0, GC_STRAFERIGHT) || gamekeydown[KEY_RIGHTARROW] || joystate == 4) + { + if (snake->snakelength < 2 || x >= oldx) + snake->snakedir[0] = 2; + } + else if (G_PlayerInputDown(0, GC_FORWARD) || gamekeydown[KEY_UPARROW] || joystate == 1) + { + if (snake->snakelength < 2 || y <= oldy) + snake->snakedir[0] = 3; + } + else if (G_PlayerInputDown(0, GC_BACKWARD) || gamekeydown[KEY_DOWNARROW] || joystate == 2) + { + 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, &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, &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; + } +} + +void Snake_Draw(void *opaque) +{ + INT16 i; + + snake_t *snake = opaque; + + // Background + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); + + 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 + ); +} + +void Snake_Free(void **opaque) +{ + if (*opaque) + { + free(opaque); + *opaque = NULL; + } +} diff --git a/src/snake.h b/src/snake.h new file mode 100644 index 000000000..a3106bb0f --- /dev/null +++ b/src/snake.h @@ -0,0 +1,20 @@ +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 2023-2023 by Louis-Antoine de Moulins de Rochefort. +// +// 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 snake.h +/// \brief Snake minigame for the download screen. + +#ifndef __SNAKE__ +#define __SNAKE__ + +void Snake_Allocate(void **opaque); +void Snake_Update(void *opaque); +void Snake_Draw(void *opaque); +void Snake_Free(void **opaque); + +#endif From 60f150a826e608d3fe57eaa67d44b160ecbc198e Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Wed, 28 Dec 2022 18:50:00 +0100 Subject: [PATCH 315/586] Remove snake_ prefix --- src/snake.c | 198 ++++++++++++++++++++++++++-------------------------- 1 file changed, 99 insertions(+), 99 deletions(-) diff --git a/src/snake.c b/src/snake.c index 2c80adeb9..21e79401d 100644 --- a/src/snake.c +++ b/src/snake.c @@ -18,31 +18,31 @@ #include "w_wad.h" #include "z_zone.h" -#define SNAKE_SPEED 5 +#define 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 NUM_BLOCKS_X 20 +#define NUM_BLOCKS_Y 10 +#define BLOCK_SIZE 12 +#define 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 MAP_WIDTH (NUM_BLOCKS_X * BLOCK_SIZE) +#define MAP_HEIGHT (NUM_BLOCKS_Y * 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) +#define LEFT_X ((BASEVIDWIDTH - MAP_WIDTH) / 2 - BORDER_SIZE) +#define RIGHT_X (LEFT_X + MAP_WIDTH + BORDER_SIZE * 2 - 1) +#define BOTTOM_Y (BASEVIDHEIGHT - 48) +#define TOP_Y (BOTTOM_Y - MAP_HEIGHT - 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, +enum bonustype_s { + BONUS_NONE = 0, + BONUS_SLOW, + BONUS_FAST, + BONUS_GHOST, + BONUS_NUKE, + BONUS_SCISSORS, + BONUS_REVERSE, + BONUS_EGGMAN, + NUM_BONUSES, }; typedef struct snake_s @@ -55,21 +55,21 @@ typedef struct snake_s UINT8 background; UINT16 snakelength; - enum snake_bonustype_s snakebonus; + enum 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 snakex[NUM_BLOCKS_X * NUM_BLOCKS_Y]; + UINT8 snakey[NUM_BLOCKS_X * NUM_BLOCKS_Y]; + UINT8 snakedir[NUM_BLOCKS_X * NUM_BLOCKS_Y]; UINT8 applex; UINT8 appley; - enum snake_bonustype_s bonustype; + enum bonustype_s bonustype; UINT8 bonusx; UINT8 bonusy; } snake_t; -static const char *snake_bonuspatches[] = { +static const char *bonuspatches[] = { NULL, "DL_SLOW", "TVSSC0", @@ -80,7 +80,7 @@ static const char *snake_bonuspatches[] = { "TVEGC0", }; -static const char *snake_backgrounds[] = { +static const char *backgrounds[] = { "RVPUMICF", "FRSTRCKF", "TAR", @@ -93,29 +93,29 @@ static const char *snake_backgrounds[] = { "RVZGRS04", }; -static void Snake_Initialise(snake_t *snake) +static void Initialise(snake_t *snake) { snake->paused = false; snake->pausepressed = false; snake->time = 0; - snake->nextupdate = SNAKE_SPEED; + snake->nextupdate = SPEED; snake->gameover = false; - snake->background = M_RandomKey(sizeof(snake_backgrounds) / sizeof(*snake_backgrounds)); + snake->background = M_RandomKey(sizeof(backgrounds) / sizeof(*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->snakebonus = BONUS_NONE; + snake->snakex[0] = M_RandomKey(NUM_BLOCKS_X); + snake->snakey[0] = M_RandomKey(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->applex = M_RandomKey(NUM_BLOCKS_X); + snake->appley = M_RandomKey(NUM_BLOCKS_Y); - snake->bonustype = SNAKE_BONUS_NONE; + snake->bonustype = BONUS_NONE; } -static UINT8 Snake_GetOppositeDir(UINT8 dir) +static UINT8 GetOppositeDir(UINT8 dir) { if (dir == 1 || dir == 3) return dir + 1; @@ -125,22 +125,22 @@ static UINT8 Snake_GetOppositeDir(UINT8 dir) return 12 + 5 - dir; } -static void Snake_FindFreeSlot(snake_t *snake, UINT8 *freex, UINT8 *freey, UINT8 headx, UINT8 heady) +static void FindFreeSlot(snake_t *snake, 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); + x = M_RandomKey(NUM_BLOCKS_X); + y = M_RandomKey(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)); + || (snake->bonustype != BONUS_NONE && x == snake->bonusx && y == snake->bonusy)); *freex = x; *freey = y; @@ -151,7 +151,7 @@ void Snake_Allocate(void **opaque) if (*opaque) Snake_Free(opaque); *opaque = malloc(sizeof(snake_t)); - Snake_Initialise(*opaque); + Initialise(*opaque); } void Snake_Update(void *opaque) @@ -166,7 +166,7 @@ void Snake_Update(void *opaque) // Handle retry if (snake->gameover && (G_PlayerInputDown(0, GC_JUMP) || gamekeydown[KEY_ENTER])) { - Snake_Initialise(snake); + Initialise(snake); snake->pausepressed = true; // Avoid accidental pause on respawn } @@ -216,18 +216,18 @@ void Snake_Update(void *opaque) { snake->snakebonustime--; if (!snake->snakebonustime) - snake->snakebonus = SNAKE_BONUS_NONE; + snake->snakebonus = 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; + if (snake->snakebonus == BONUS_SLOW) + snake->nextupdate = SPEED * 2; + else if (snake->snakebonus == BONUS_FAST) + snake->nextupdate = SPEED * 2 / 3; else - snake->nextupdate = SNAKE_SPEED; + snake->nextupdate = SPEED; if (snake->gameover) return; @@ -242,7 +242,7 @@ void Snake_Update(void *opaque) snake->gameover = true; break; case 2: - if (x < SNAKE_NUM_BLOCKS_X - 1) + if (x < NUM_BLOCKS_X - 1) x++; else snake->gameover = true; @@ -254,7 +254,7 @@ void Snake_Update(void *opaque) snake->gameover = true; break; case 4: - if (y < SNAKE_NUM_BLOCKS_Y - 1) + if (y < NUM_BLOCKS_Y - 1) y++; else snake->gameover = true; @@ -262,13 +262,13 @@ void Snake_Update(void *opaque) } // Check collision with snake - if (snake->snakebonus != SNAKE_BONUS_GHOST) + if (snake->snakebonus != 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) + if (snake->snakebonus == BONUS_SCISSORS) { - snake->snakebonus = SNAKE_BONUS_NONE; + snake->snakebonus = BONUS_NONE; snake->snakelength = i; S_StartSound(NULL, sfx_adderr); } @@ -285,7 +285,7 @@ void Snake_Update(void *opaque) // Check collision with apple if (x == snake->applex && y == snake->appley) { - if (snake->snakelength + 3 < SNAKE_NUM_BLOCKS_X * SNAKE_NUM_BLOCKS_Y) + if (snake->snakelength + 3 < NUM_BLOCKS_X * NUM_BLOCKS_Y) { snake->snakelength++; snake->snakex [snake->snakelength - 1] = snake->snakex [snake->snakelength - 2]; @@ -294,18 +294,18 @@ void Snake_Update(void *opaque) } // Spawn new apple - Snake_FindFreeSlot(snake, &snake->applex, &snake->appley, x, y); + FindFreeSlot(snake, &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->bonustype = M_RandomKey(NUM_BONUSES - 1) + 1; + } while (snake->snakelength > NUM_BLOCKS_X * NUM_BLOCKS_Y * 3 / 4 + && (snake->bonustype == BONUS_EGGMAN || snake->bonustype == BONUS_FAST || snake->bonustype == BONUS_REVERSE)); - Snake_FindFreeSlot(snake, &snake->bonusx, &snake->bonusy, x, y); + FindFreeSlot(snake, &snake->bonusx, &snake->bonusy, x, y); } S_StartSound(NULL, sfx_s3k6b); @@ -350,25 +350,25 @@ void Snake_Update(void *opaque) snake->snakey[0] = y; // Check collision with bonus - if (snake->bonustype != SNAKE_BONUS_NONE && x == snake->bonusx && y == snake->bonusy) + if (snake->bonustype != 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; + case BONUS_SLOW: + snake->snakebonus = BONUS_SLOW; snake->snakebonustime = 20 * TICRATE; break; - case SNAKE_BONUS_FAST: - snake->snakebonus = SNAKE_BONUS_FAST; + case BONUS_FAST: + snake->snakebonus = BONUS_FAST; snake->snakebonustime = 20 * TICRATE; break; - case SNAKE_BONUS_GHOST: - snake->snakebonus = SNAKE_BONUS_GHOST; + case BONUS_GHOST: + snake->snakebonus = BONUS_GHOST; snake->snakebonustime = 10 * TICRATE; break; - case SNAKE_BONUS_NUKE: + case BONUS_NUKE: for (i = 0; i < snake->snakelength; i++) { snake->snakex [i] = snake->snakex [0]; @@ -378,11 +378,11 @@ void Snake_Update(void *opaque) S_StartSound(NULL, sfx_bkpoof); break; - case SNAKE_BONUS_SCISSORS: - snake->snakebonus = SNAKE_BONUS_SCISSORS; + case BONUS_SCISSORS: + snake->snakebonus = BONUS_SCISSORS; snake->snakebonustime = 60 * TICRATE; break; - case SNAKE_BONUS_REVERSE: + case BONUS_REVERSE: for (i = 0; i < (snake->snakelength + 1) / 2; i++) { UINT16 i2 = snake->snakelength - 1 - i; @@ -393,10 +393,10 @@ void Snake_Update(void *opaque) // 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->snakedir[i] = GetOppositeDir(snake->snakedir[i2]); snake->snakex [i2] = tmpx; snake->snakey [i2] = tmpy; - snake->snakedir[i2] = Snake_GetOppositeDir(tmpdir); + snake->snakedir[i2] = GetOppositeDir(tmpdir); } snake->snakedir[0] = 0; @@ -404,14 +404,14 @@ void Snake_Update(void *opaque) S_StartSound(NULL, sfx_gravch); break; default: - if (snake->snakebonus != SNAKE_BONUS_GHOST) + if (snake->snakebonus != BONUS_GHOST) { snake->gameover = true; S_StartSound(NULL, sfx_lose); } } - snake->bonustype = SNAKE_BONUS_NONE; + snake->bonustype = BONUS_NONE; } } @@ -425,23 +425,23 @@ void Snake_Draw(void *opaque) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); 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]) + LEFT_X + BORDER_SIZE, + TOP_Y + BORDER_SIZE, + MAP_WIDTH, + MAP_HEIGHT, + W_GetNumForName(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 + V_DrawFill(LEFT_X, TOP_Y, BORDER_SIZE + MAP_WIDTH, BORDER_SIZE, 242); // Top + V_DrawFill(LEFT_X + BORDER_SIZE + MAP_WIDTH, TOP_Y, BORDER_SIZE, BORDER_SIZE + MAP_HEIGHT, 242); // Right + V_DrawFill(LEFT_X + BORDER_SIZE, TOP_Y + BORDER_SIZE + MAP_HEIGHT, BORDER_SIZE + MAP_WIDTH, BORDER_SIZE, 242); // Bottom + V_DrawFill(LEFT_X, TOP_Y + BORDER_SIZE, BORDER_SIZE, BORDER_SIZE + 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, + (LEFT_X + BORDER_SIZE + snake->applex * BLOCK_SIZE + BLOCK_SIZE / 2) * FRACUNIT, + (TOP_Y + BORDER_SIZE + snake->appley * BLOCK_SIZE + BLOCK_SIZE / 2) * FRACUNIT, FRACUNIT / 4, 0, W_CachePatchLongName("DL_APPLE", PU_HUDGFX), @@ -449,13 +449,13 @@ void Snake_Draw(void *opaque) ); // Bonus - if (snake->bonustype != SNAKE_BONUS_NONE) + if (snake->bonustype != 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, + (LEFT_X + BORDER_SIZE + snake->bonusx * BLOCK_SIZE + BLOCK_SIZE / 2 ) * FRACUNIT, + (TOP_Y + BORDER_SIZE + snake->bonusy * BLOCK_SIZE + BLOCK_SIZE / 2 + 4) * FRACUNIT, FRACUNIT / 2, 0, - W_CachePatchLongName(snake_bonuspatches[snake->bonustype], PU_HUDGFX), + W_CachePatchLongName(bonuspatches[snake->bonustype], PU_HUDGFX), NULL ); @@ -499,10 +499,10 @@ void Snake_Draw(void *opaque) } 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, + (LEFT_X + BORDER_SIZE + snake->snakex[i] * BLOCK_SIZE + BLOCK_SIZE / 2) * FRACUNIT, + (TOP_Y + BORDER_SIZE + snake->snakey[i] * BLOCK_SIZE + BLOCK_SIZE / 2) * FRACUNIT, i == 0 && dir == 0 ? FRACUNIT / 5 : FRACUNIT / 2, - snake->snakebonus == SNAKE_BONUS_GHOST ? V_TRANSLUCENT : 0, + snake->snakebonus == BONUS_GHOST ? V_TRANSLUCENT : 0, W_CachePatchLongName(patchname, PU_HUDGFX), NULL ); @@ -510,17 +510,17 @@ void Snake_Draw(void *opaque) } // Length - V_DrawString(SNAKE_RIGHT_X + 4, SNAKE_TOP_Y, V_MONOSPACE, va("%u", snake->snakelength)); + V_DrawString(RIGHT_X + 4, TOP_Y, V_MONOSPACE, va("%u", snake->snakelength)); // Bonus - if (snake->snakebonus != SNAKE_BONUS_NONE + if (snake->snakebonus != BONUS_NONE && (snake->snakebonustime >= 3 * TICRATE || snake->time % 4 < 4 / 2)) V_DrawFixedPatch( - (SNAKE_RIGHT_X + 10) * FRACUNIT, - (SNAKE_TOP_Y + 24) * FRACUNIT, + (RIGHT_X + 10) * FRACUNIT, + (TOP_Y + 24) * FRACUNIT, FRACUNIT / 2, 0, - W_CachePatchLongName(snake_bonuspatches[snake->snakebonus], PU_HUDGFX), + W_CachePatchLongName(bonuspatches[snake->snakebonus], PU_HUDGFX), NULL ); } From 27b500ce9aa021493a85ba46824960a1f24f06c7 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Thu, 29 Dec 2022 10:23:12 +0100 Subject: [PATCH 316/586] Split packet handling switch into functions --- src/d_clisrv.c | 1111 ++++++++++++++++++++++++------------------------ src/d_netfil.c | 49 ++- src/d_netfil.h | 8 +- 3 files changed, 605 insertions(+), 563 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index be10e4f9b..d3f6854c7 100755 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -3677,8 +3677,531 @@ static void HandleServerInfo(SINT8 node) } #endif -static void PT_WillResendGamestate(void) +// Helper function for packets that should only be sent by the server +// If it is NOT from the server, bail out and close the connection! +static boolean ServerOnly(SINT8 node) { + if (node == servernode) + return false; + + Net_CloseConnection(node); + return true; +} + +static void PT_AskInfoViaMS(SINT8 node) +{ + Net_CloseConnection(node); +} + +static void PT_TellFilesNeeded(SINT8 node) +{ + if (server && serverrunning) + { + 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); +} + +static void PT_MoreFilesNeeded(SINT8 node) +{ + if (server && serverrunning) + { // But wait I thought I'm the server? + Net_CloseConnection(node); + return; + } + if (ServerOnly(node)) + return; + 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 + } +} + +static void PT_AskInfo(SINT8 node) +{ + if (server && serverrunning) + { + SV_SendServerInfo(node, (tic_t)LONG(netbuffer->u.askinfo.time)); + SV_SendPlayerInfo(node); // Send extra info + } + Net_CloseConnection(node); +} + +// Negative response of client join request +static void PT_ServerRefuse(SINT8 node) +{ + if (server && serverrunning) + { // But wait I thought I'm the server? + Net_CloseConnection(node); + return; + } + if (ServerOnly(node)) + return; + 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"); + + 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); + return; + } + + 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. + cl_mode = CL_ABORTED; + } +} + +// Positive response of client join request +static void PT_ServerCFG(SINT8 node) +{ + if (server && serverrunning && node != servernode) + { // but wait I thought I'm the server? + Net_CloseConnection(node); + return; + } + if (ServerOnly(node)) + return; + /// \note how would this happen? and is it doing the right thing if it does? + if (cl_mode != CL_WAITJOINRESPONSE) + return; + + 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; +} + +static void PT_ClientCmd(SINT8 node, INT32 netconsole) +{ + tic_t realend, realstart; + + if (client) + return; + + // 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])); + return; + } + + // 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) + return; + + // 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); + return; + } + + // 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) +#ifndef NONET + && !SV_ResendingSavegameToAnyone() +#endif + && !resendingsavegame[node] && savegameresendcooldown[node] <= I_GetTime()) + { + 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))); + return; + } + 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))); + return; + } + } +} + +static void PT_TextCmd(SINT8 node, INT32 netconsole) +{ + if (client) + return; + + // splitscreen special + if (netbuffer->packettype == PT_TEXTCMD2) + netconsole = nodetoplayer2[node]; + + 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); + return; + } + + // 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); + return; + } + + // 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); + return; + } + + // 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]; + } +} + +static void PT_Login(SINT8 node, INT32 netconsole) +{ + (void)node; + + if (client) + return; + +#ifndef NOMD5 + UINT8 finalmd5[16];/* Well, it's the cool thing to do? */ + + if (doomcom->datalength < 16)/* ignore partial sends */ + return; + + if (!adminpasswordset) + { + CONS_Printf(M_GetText("Password from %s failed (no password set).\n"), player_names[netconsole]); + return; + } + + // 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]); +#else + (void)netconsole; +#endif +} + +static void PT_ClientQuit(SINT8 node, INT32 netconsole) +{ + if (client) + return; + + if (!nodeingame[node]) + { + Net_CloseConnection(node); + return; + } + + // 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; +} + +static void PT_CanReceiveGamestate(SINT8 node) +{ +#ifndef NONET + 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; +#else + (void)node; +#endif +} + +static void PT_AskLuaFile(SINT8 node) +{ + if (server && luafiletransfers && luafiletransfers->nodestatus[node] == LFTNS_ASKED) + AddLuaFileToSendQueue(node, luafiletransfers->realfilename); +} + +static void PT_HasLuaFile(SINT8 node) +{ + if (server && luafiletransfers && luafiletransfers->nodestatus[node] == LFTNS_SENDING) + SV_HandleLuaFileSent(node); +} + +static void PT_ReceivedGamestate(SINT8 node) +{ + sendingsavegame[node] = false; + resendingsavegame[node] = false; + savegameresendcooldown[node] = I_GetTime() + 5 * TICRATE; +} + +static void PT_ServerTics(SINT8 node, INT32 netconsole) +{ + UINT8 *pak, *txtpak, numtxtpak; + tic_t realend, realstart; + + if (!nodeingame[node]) + { + // Do not remove my own server (we have just get a out of order packet) + if (node != servernode) + { + DEBFILE(va("unknown packet received (%d) from unknown host\n",netbuffer->packettype)); + Net_CloseConnection(node); + } + return; + } + + // 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); + return; + } + + realstart = netbuffer->u.serverpak.starttic; + realend = realstart + netbuffer->u.serverpak.numtics; + + 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);*/ + } +} + +static void PT_Ping(SINT8 node, INT32 netconsole) +{ + // 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); + return; + } + + //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]; + } +} + +static void PT_WillResendGamestate(SINT8 node) +{ + (void)node; + #ifndef NONET char tmpsave[256]; @@ -3705,19 +4228,12 @@ static void PT_WillResendGamestate(void) #endif } -static void PT_CanReceiveGamestate(SINT8 node) +static void PT_SendingLuaFile(SINT8 node) { -#ifndef NONET - 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; -#else (void)node; -#endif + + if (client) + CL_PrepareDownloadLuaFile(); } /** Handles a packet received from a node that isn't in game @@ -3733,202 +4249,27 @@ 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: - Net_CloseConnection(node); - break; - - case PT_TELLFILESNEEDED: - if (server && serverrunning) - { - 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 - } - 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"); - - 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. - 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 */ + case PT_ASKINFOVIAMS : PT_AskInfoViaMS (node ); break; + case PT_TELLFILESNEEDED: PT_TellFilesNeeded(node ); break; + case PT_MOREFILESNEEDED: PT_MoreFilesNeeded(node ); break; + case PT_ASKINFO : PT_AskInfo (node ); break; + case PT_SERVERREFUSE : PT_ServerRefuse (node ); break; + case PT_SERVERCFG : PT_ServerCFG (node ); break; + case PT_FILEFRAGMENT : PT_FileFragment (node, -1); break; + case PT_FILEACK : PT_FileAck (node ); break; + case PT_FILERECEIVED : PT_FileReceived (node ); break; + case PT_REQUESTFILE : PT_RequestFile (node ); break; + case PT_NODETIMEOUT : PT_ClientQuit (node, -1); break; + case PT_CLIENTQUIT : PT_ClientQuit (node, -1); break; + case PT_SERVERTICS : PT_ServerTics (node, -1); break; + case PT_CLIENTCMD : break; // This is not an "unknown packet" 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 @@ -3942,13 +4283,6 @@ static void HandlePacketFromAwayNode(SINT8 node) 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; @@ -3961,358 +4295,39 @@ static void HandlePacketFromPlayer(SINT8 node) switch (netbuffer->packettype) { -// -------------------------------------------- SERVER RECEIVE ---------- + // 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) -#ifndef NONET - && !SV_ResendingSavegameToAnyone() -#endif - && !resendingsavegame[node] && savegameresendcooldown[node] <= I_GetTime()) - { - 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; - } - } + PT_ClientCmd(node, netconsole); break; - case PT_TEXTCMD2: // splitscreen special - netconsole = nodetoplayer2[node]; - /* FALLTHRU */ - case PT_TEXTCMD: - if (client) - break; + case PT_TEXTCMD : PT_TextCmd (node, netconsole); break; + case PT_TEXTCMD2 : PT_TextCmd (node, netconsole); break; + case PT_LOGIN : PT_Login (node, netconsole); break; + case PT_NODETIMEOUT : PT_ClientQuit (node, netconsole); break; + case PT_CLIENTQUIT : PT_ClientQuit (node, netconsole); break; + case PT_CANRECEIVEGAMESTATE: PT_CanReceiveGamestate(node ); break; + case PT_ASKLUAFILE : PT_AskLuaFile (node ); break; + case PT_HASLUAFILE : PT_HasLuaFile (node ); break; + case PT_RECEIVEDGAMESTATE : PT_ReceivedGamestate (node ); break; - if (netconsole < 0 || netconsole >= MAXPLAYERS) - Net_UnAcknowledgePacket(node); - else - { - size_t j; - tic_t tic = maketic; - UINT8 *textcmd; + // CLIENT RECEIVE + case PT_SERVERTICS : PT_ServerTics (node, netconsole); break; + case PT_PING : PT_Ping (node, netconsole); break; + case PT_FILEFRAGMENT : PT_FileFragment (node, netconsole); break; + case PT_FILEACK : PT_FileAck (node ); break; + case PT_FILERECEIVED : PT_FileReceived (node ); break; + case PT_WILLRESENDGAMESTATE: PT_WillResendGamestate(node ); break; + case PT_SENDINGLUAFILE : PT_SendingLuaFile (node ); break; + case PT_SERVERCFG : break; - // 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() + 5 * 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 diff --git a/src/d_netfil.c b/src/d_netfil.c index edbef30bb..7c9ed54d8 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -413,12 +413,17 @@ boolean CL_SendFileRequest(void) } // get request filepak and put it on the send queue -// returns false if a requested file was not found or cannot be sent -boolean PT_RequestFile(INT32 node) +void PT_RequestFile(SINT8 node) { UINT8 *p = netbuffer->u.textcmd; UINT8 id; + if (client || !cv_downloading.value) + { + Net_CloseConnection(node); // close connection if you are not the server or disabled downloading + return; + } + while (p < netbuffer->u.textcmd + MAXTEXTCMD-1) // Don't allow hacked client to overflow { id = READUINT8(p); @@ -428,11 +433,12 @@ boolean PT_RequestFile(INT32 node) if (!AddFileToSendQueue(node, id)) { SV_AbortSendFiles(node); - return false; // don't read the rest of the files + Net_CloseConnection(node); // close connection if one of the requested files could not be sent + return; // don't read the rest of the files } } - return true; // no problems with any files + return; // no problems with any files } /** Checks if the files needed aren't already loaded or on the disk @@ -1137,13 +1143,15 @@ void FileSendTicker(void) } } -void PT_FileAck(void) +void PT_FileAck(SINT8 node) { fileack_pak *packet = &netbuffer->u.fileack; - INT32 node = doomcom->remotenode; filetran_t *trans = &transfer[node]; INT32 i, j; + if (client) + return; + // Wrong file id? Ignore it, it's probably a late packet if (!(trans->txlist && packet->fileid == trans->txlist->fileid)) return; @@ -1190,12 +1198,12 @@ void PT_FileAck(void) } } -void PT_FileReceived(void) +void PT_FileReceived(SINT8 node) { - filetx_t *trans = transfer[doomcom->remotenode].txlist; + filetx_t *trans = transfer[node].txlist; - if (trans && netbuffer->u.filereceived == trans->fileid) - SV_EndFileSend(doomcom->remotenode); + if (server && trans && netbuffer->u.filereceived == trans->fileid) + SV_EndFileSend(node); } static void SendAckPacket(fileack_pak *packet, UINT8 fileid) @@ -1281,8 +1289,27 @@ void FileReceiveTicker(void) } } -void PT_FileFragment(void) +void PT_FileFragment(SINT8 node, INT32 netconsole) { + if (nodeingame[node]) + { + // 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); + return; + } + if (server) + return; + } + else if (server || node != servernode) + { + Net_CloseConnection(node); + return; + } + INT32 filenum = netbuffer->u.filetxpak.fileid; fileneeded_t *file = &fileneeded[filenum]; UINT32 fragmentpos = LONG(netbuffer->u.filetxpak.position); diff --git a/src/d_netfil.h b/src/d_netfil.h index f778a518f..5c7f4ef49 100644 --- a/src/d_netfil.h +++ b/src/d_netfil.h @@ -90,16 +90,16 @@ void AddRamToSendQueue(INT32 node, void *data, size_t size, freemethod_t freemet UINT8 fileid); void FileSendTicker(void); -void PT_FileAck(void); -void PT_FileReceived(void); +void PT_FileAck(SINT8 node); +void PT_FileReceived(SINT8 node); boolean SendingFile(INT32 node); void FileReceiveTicker(void); -void PT_FileFragment(void); +void PT_FileFragment(SINT8 node, INT32 netconsole); boolean CL_CheckDownloadable(void); boolean CL_SendFileRequest(void); -boolean PT_RequestFile(INT32 node); +void PT_RequestFile(SINT8 node); typedef enum { From 4c0705008e46051bdae26dd1e3cdbbd148ccf33a Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Thu, 29 Dec 2022 15:52:45 +0100 Subject: [PATCH 317/586] Merge node arrays into a structure --- src/d_clisrv.c | 202 ++++++++++++++++++++++++------------------------- src/d_net.h | 23 +++++- src/d_netfil.c | 4 +- src/i_tcp.c | 14 ++-- 4 files changed, 125 insertions(+), 118 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index d3f6854c7..e311bf15a 100755 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -84,6 +84,8 @@ boolean serverrunning = false; INT32 serverplayer = 0; char motd[254], server_context[8]; // Message of the Day, Unique Context (even without Mumble support) +netnode_t netnodes[MAXNETNODES]; + // Server specific vars UINT8 playernode[MAXPLAYERS]; char playeraddress[MAXPLAYERS][64]; @@ -91,10 +93,6 @@ 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. @@ -103,14 +101,8 @@ 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; @@ -218,14 +210,14 @@ tic_t ExpandTics(INT32 low, INT32 node) { INT32 delta; - delta = low - (nettics[node] & UINT8_MAX); + delta = low - (netnodes[node].tic & UINT8_MAX); if (delta >= -64 && delta <= 64) - return (nettics[node] & ~UINT8_MAX) + low; + return (netnodes[node].tic & ~UINT8_MAX) + low; else if (delta > 64) - return (nettics[node] & ~UINT8_MAX) - 256 + low; + return (netnodes[node].tic & ~UINT8_MAX) - 256 + low; else //if (delta < -64) - return (nettics[node] & ~UINT8_MAX) + 256 + low; + return (netnodes[node].tic & ~UINT8_MAX) + 256 + low; } // ----------------------------------------------------------------- @@ -999,7 +991,7 @@ static boolean SV_ResendingSavegameToAnyone(void) INT32 i; for (i = 0; i < MAXNETNODES; i++) - if (resendingsavegame[i]) + if (netnodes[i].resendingsavegame) return true; return false; } @@ -1068,8 +1060,8 @@ static void SV_SendSaveGame(INT32 node, boolean resending) 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 + netnodes[node].sendingsavegame = true; + netnodes[node].freezetimeout = I_GetTime() + jointimeout + length / 1024; // 1 extra tic for each kilobyte } #ifdef DUMPCONSISTENCY @@ -2034,7 +2026,7 @@ static void CL_ConnectToServer(void) { pnumnodes = 0; for (i = 0; i < MAXNETNODES; i++) - if (nodeingame[i]) + if (netnodes[i].ingame) pnumnodes++; } } @@ -2316,10 +2308,10 @@ void CL_RemovePlayer(INT32 playernum, kickreason_t reason) if (server && !demoplayback && playernode[playernum] != UINT8_MAX) { INT32 node = playernode[playernum]; - playerpernode[node]--; - if (playerpernode[node] <= 0) + netnodes[node].numplayers--; + if (netnodes[node].numplayers <= 0) { - nodeingame[node] = false; + netnodes[node].ingame = false; Net_CloseConnection(node); ResetNode(node); } @@ -2431,7 +2423,7 @@ void CL_Reset(void) if (servernode > 0 && servernode < MAXNETNODES) { - nodeingame[(UINT8)servernode] = false; + netnodes[(UINT8)servernode].ingame = false; Net_CloseConnection(servernode); } D_CloseConnection(); // netgame = false @@ -2674,7 +2666,7 @@ static void Command_Kick(void) // 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]]) + if (server && playernode[pn] != UINT8_MAX && netnodes[playernode[pn]].sendingsavegame) { Net_ConnectionTimeout(playernode[pn]); return; @@ -2763,8 +2755,8 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum) // Is playernum authorized to make this kick? if (playernum != serverplayer && !IsPlayerAdmin(playernum) - && !(playernode[playernum] != UINT8_MAX && playerpernode[playernode[playernum]] == 2 - && nodetoplayer2[playernode[playernum]] == pnum)) + && !(playernode[playernum] != UINT8_MAX && netnodes[playernode[playernum]].numplayers == 2 + && netnodes[playernode[playernum]].player2 == pnum)) { // We received a kick command from someone who isn't the // server or admin, and who isn't in splitscreen removing @@ -2802,10 +2794,10 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum) "\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]]); + playernode[playernum], netnodes[playernode[playernum]].numplayers, + netnodes[playernode[playernum]].player2, + playernode[pnum], netnodes[playernode[pnum]].numplayers, + netnodes[playernode[pnum]].player2); */ pnum = playernum; msg = KICK_MSG_CON_FAIL; @@ -2926,10 +2918,10 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum) if (server && !demoplayback && playernode[pnum] != UINT8_MAX) { INT32 node = playernode[pnum]; - playerpernode[node]--; - if (playerpernode[node] <= 0) + netnodes[node].numplayers--; + if (netnodes[node].numplayers <= 0) { - nodeingame[node] = false; + netnodes[node].ingame = false; Net_CloseConnection(node); ResetNode(node); } @@ -3017,19 +3009,19 @@ void D_ClientServerInit(void) static void ResetNode(INT32 node) { - nodeingame[node] = false; - nodewaiting[node] = 0; + netnodes[node].ingame = false; + netnodes[node].numplayerswaiting = 0; - nettics[node] = gametic; - supposedtics[node] = gametic; + netnodes[node].tic = gametic; + netnodes[node].supposedtic = gametic; - nodetoplayer[node] = -1; - nodetoplayer2[node] = -1; - playerpernode[node] = 0; + netnodes[node].player = -1; + netnodes[node].player2 = -1; + netnodes[node].numplayers = 0; - sendingsavegame[node] = false; - resendingsavegame[node] = false; - savegameresendcooldown[node] = 0; + netnodes[node].sendingsavegame = false; + netnodes[node].resendingsavegame = false; + netnodes[node].savegameresendcooldown = 0; } void SV_ResetServer(void) @@ -3067,7 +3059,7 @@ void SV_ResetServer(void) if (dedicated) { - nodeingame[0] = true; + netnodes[0].ingame = true; serverplayer = 0; } else @@ -3130,14 +3122,14 @@ void D_QuitNetGame(void) netbuffer->packettype = PT_SERVERSHUTDOWN; for (i = 0; i < MAXNETNODES; i++) - if (nodeingame[i]) + if (netnodes[i].ingame) HSendPacket(i, true, 0, 0); #ifdef MASTERSERVER if (serverrunning && ms_RoomId > 0) UnregisterServer(); #endif } - else if (servernode > 0 && servernode < MAXNETNODES && nodeingame[(UINT8)servernode]) + else if (servernode > 0 && servernode < MAXNETNODES && netnodes[(UINT8)servernode].ingame) { netbuffer->packettype = PT_CLIENTQUIT; HSendPacket(servernode, true, 0, 0); @@ -3161,12 +3153,12 @@ void D_QuitNetGame(void) // 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; + netnodes[node].tic = gametic; + netnodes[node].supposedtic = gametic; // little hack because the server connects to itself and puts // nodeingame when connected not here if (node) - nodeingame[node] = true; + netnodes[node].ingame = true; } // Xcmd XD_ADDPLAYER @@ -3311,7 +3303,7 @@ static boolean SV_AddWaitingPlayers(const char *name, const char *name2) for (node = 0; node < MAXNETNODES; node++) { // splitscreen can allow 2 player in one node - for (; nodewaiting[node] > 0; nodewaiting[node]--) + for (; netnodes[node].numplayerswaiting > 0; netnodes[node].numplayerswaiting--) { newplayer = true; @@ -3325,7 +3317,7 @@ static boolean SV_AddWaitingPlayers(const char *name, const char *name2) if (playeringame[newplayernum]) continue; for (n = 0; n < MAXNETNODES; n++) - if (nodetoplayer[n] == newplayernum || nodetoplayer2[n] == newplayernum) + if (netnodes[n].player == newplayernum || netnodes[n].player2 == newplayernum) break; if (n == MAXNETNODES) break; @@ -3341,18 +3333,18 @@ static boolean SV_AddWaitingPlayers(const char *name, const char *name2) p = buf + 2; buf[0] = (UINT8)node; buf[1] = newplayernum; - if (playerpernode[node] < 1) + if (netnodes[node].numplayers < 1) { - nodetoplayer[node] = newplayernum; + netnodes[node].player = newplayernum; WRITESTRINGN(p, name, MAXPLAYERNAME); } else { - nodetoplayer2[node] = newplayernum; + netnodes[node].player2 = newplayernum; buf[1] |= 0x80; WRITESTRINGN(p, name2, MAXPLAYERNAME); } - playerpernode[node]++; + netnodes[node].numplayers++; SendNetXCmd(XD_ADDPLAYER, &buf, p - buf); @@ -3571,7 +3563,7 @@ static void HandleConnect(SINT8 node) boolean newnode = false; #endif - for (i = 0; i < netbuffer->u.clientcfg.localplayers - playerpernode[node]; i++) + for (i = 0; i < netbuffer->u.clientcfg.localplayers - netnodes[node].numplayers; i++) { strlcpy(names[i], netbuffer->u.clientcfg.names[i], MAXPLAYERNAME + 1); if (!EnsurePlayerNameIsGood(names[i], rejoinernum)) @@ -3582,8 +3574,8 @@ static void HandleConnect(SINT8 node) } // client authorised to join - nodewaiting[node] = (UINT8)(netbuffer->u.clientcfg.localplayers - playerpernode[node]); - if (!nodeingame[node]) + netnodes[node].numplayerswaiting = (UINT8)(netbuffer->u.clientcfg.localplayers - netnodes[node].numplayers); + if (!netnodes[node].ingame) { gamestate_t backupstate = gamestate; #ifndef NONET @@ -3608,7 +3600,7 @@ static void HandleConnect(SINT8 node) DEBFILE("new node joined\n"); } #ifndef NONET - if (nodewaiting[node]) + if (netnodes[node].numplayerswaiting) { if ((gamestate == GS_LEVEL || gamestate == GS_INTERMISSION) && newnode) { @@ -3803,7 +3795,7 @@ static void PT_ServerCFG(SINT8 node) memcpy(server_context, netbuffer->u.servercfg.server_context, 8); } - nodeingame[(UINT8)servernode] = true; + netnodes[(UINT8)servernode].ingame = true; serverplayer = netbuffer->u.servercfg.serverplayer; doomcom->numslots = SHORT(netbuffer->u.servercfg.totalslotnum); mynode = netbuffer->u.servercfg.clientnode; @@ -3844,19 +3836,19 @@ static void PT_ClientCmd(SINT8 node, INT32 netconsole) if (netbuffer->packettype == PT_CLIENTMIS || netbuffer->packettype == PT_CLIENT2MIS || netbuffer->packettype == PT_NODEKEEPALIVEMIS - || supposedtics[node] < realend) + || netnodes[node].supposedtic < realend) { - supposedtics[node] = realend; + netnodes[node].supposedtic = realend; } // Discard out of order packet - if (nettics[node] > realend) + if (netnodes[node].tic > realend) { - DEBFILE(va("out of order ticcmd discarded nettics = %u\n", nettics[node])); + DEBFILE(va("out of order ticcmd discarded nettics = %u\n", netnodes[node].tic)); return; } // Update the nettics - nettics[node] = realend; + netnodes[node].tic = realend; // Don't do anything for packets of type NODEKEEPALIVE? if (netconsole == -1 || netbuffer->packettype == PT_NODEKEEPALIVE @@ -3865,7 +3857,7 @@ static void PT_ClientCmd(SINT8 node, INT32 netconsole) // 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; + netnodes[node].freezetimeout = I_GetTime() + connectiontimeout; // Copy ticcmd G_MoveTiccmd(&netcmds[maketic%BACKUPTICS][netconsole], &netbuffer->u.clientpak.cmd, 1); @@ -3883,8 +3875,8 @@ static void PT_ClientCmd(SINT8 node, INT32 netconsole) // Splitscreen cmd if ((netbuffer->packettype == PT_CLIENT2CMD || netbuffer->packettype == PT_CLIENT2MIS) - && nodetoplayer2[node] >= 0) - G_MoveTiccmd(&netcmds[maketic%BACKUPTICS][(UINT8)nodetoplayer2[node]], + && netnodes[node].player2 >= 0) + G_MoveTiccmd(&netcmds[maketic%BACKUPTICS][(UINT8)netnodes[node].player2], &netbuffer->u.client2pak.cmd2, 1); // Check player consistancy during the level @@ -3893,7 +3885,7 @@ static void PT_ClientCmd(SINT8 node, INT32 netconsole) #ifndef NONET && !SV_ResendingSavegameToAnyone() #endif - && !resendingsavegame[node] && savegameresendcooldown[node] <= I_GetTime()) + && !netnodes[node].resendingsavegame && netnodes[node].savegameresendcooldown <= I_GetTime()) { if (cv_resynchattempts.value) { @@ -3901,7 +3893,7 @@ static void PT_ClientCmd(SINT8 node, INT32 netconsole) netbuffer->packettype = PT_WILLRESENDGAMESTATE; HSendPacket(node, true, 0, 0); - resendingsavegame[node] = true; + netnodes[node].resendingsavegame = true; if (cv_blamecfail.value) CONS_Printf(M_GetText("Synch failure for player %d (%s); expected %hd, got %hd\n"), @@ -3931,7 +3923,7 @@ static void PT_TextCmd(SINT8 node, INT32 netconsole) // splitscreen special if (netbuffer->packettype == PT_TEXTCMD2) - netconsole = nodetoplayer2[node]; + netconsole = netnodes[node].player2; if (netconsole < 0 || netconsole >= MAXPLAYERS) Net_UnAcknowledgePacket(node); @@ -4033,7 +4025,7 @@ static void PT_ClientQuit(SINT8 node, INT32 netconsole) if (client) return; - if (!nodeingame[node]) + if (!netnodes[node].ingame) { Net_CloseConnection(node); return; @@ -4041,7 +4033,7 @@ static void PT_ClientQuit(SINT8 node, INT32 netconsole) // 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; + netnodes[node].numplayerswaiting = 0; if (netconsole != -1 && playeringame[netconsole]) { UINT8 kickmsg; @@ -4053,29 +4045,29 @@ static void PT_ClientQuit(SINT8 node, INT32 netconsole) kickmsg |= KICK_MSG_KEEP_BODY; SendKick(netconsole, kickmsg); - nodetoplayer[node] = -1; + netnodes[node].player = -1; - if (nodetoplayer2[node] != -1 && nodetoplayer2[node] >= 0 - && playeringame[(UINT8)nodetoplayer2[node]]) + if (netnodes[node].player2 != -1 && netnodes[node].player2 >= 0 + && playeringame[(UINT8)netnodes[node].player2]) { - SendKick(nodetoplayer2[node], kickmsg); - nodetoplayer2[node] = -1; + SendKick(netnodes[node].player2, kickmsg); + netnodes[node].player2 = -1; } } Net_CloseConnection(node); - nodeingame[node] = false; + netnodes[node].ingame = false; } static void PT_CanReceiveGamestate(SINT8 node) { #ifndef NONET - if (client || sendingsavegame[node]) + if (client || netnodes[node].sendingsavegame) return; - CONS_Printf(M_GetText("Resending game state to %s...\n"), player_names[nodetoplayer[node]]); + CONS_Printf(M_GetText("Resending game state to %s...\n"), player_names[netnodes[node].player]); SV_SendSaveGame(node, true); // Resend a complete game state - resendingsavegame[node] = true; + netnodes[node].resendingsavegame = true; #else (void)node; #endif @@ -4095,9 +4087,9 @@ static void PT_HasLuaFile(SINT8 node) static void PT_ReceivedGamestate(SINT8 node) { - sendingsavegame[node] = false; - resendingsavegame[node] = false; - savegameresendcooldown[node] = I_GetTime() + 5 * TICRATE; + netnodes[node].sendingsavegame = false; + netnodes[node].resendingsavegame = false; + netnodes[node].savegameresendcooldown = I_GetTime() + 5 * TICRATE; } static void PT_ServerTics(SINT8 node, INT32 netconsole) @@ -4105,7 +4097,7 @@ static void PT_ServerTics(SINT8 node, INT32 netconsole) UINT8 *pak, *txtpak, numtxtpak; tic_t realend, realstart; - if (!nodeingame[node]) + if (!netnodes[node].ingame) { // Do not remove my own server (we have just get a out of order packet) if (node != servernode) @@ -4287,7 +4279,7 @@ static void HandlePacketFromPlayer(SINT8 node) if (dedicated && node == 0) netconsole = 0; else - netconsole = nodetoplayer[node]; + netconsole = netnodes[node].player; #ifdef PARANOIA if (netconsole >= MAXPLAYERS) I_Error("bad table nodetoplayer: node %d player %d", doomcom->remotenode, netconsole); @@ -4376,7 +4368,7 @@ static void GetPackets(void) continue; // We do nothing with PLAYERINFO, that's for the MS browser. // Packet received from someone already playing - if (nodeingame[node]) + if (netnodes[node].ingame) HandlePacketFromPlayer(node); // Packet received from someone not playing else @@ -4572,13 +4564,13 @@ static void SV_SendTics(void) // 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 + // x is computed using netnodes[n].supposedtic, max packet size and maketic for (n = 1; n < MAXNETNODES; n++) - if (nodeingame[n]) + if (netnodes[n].ingame) { - // assert supposedtics[n]>=nettics[n] - realfirsttic = supposedtics[n]; - lasttictosend = min(maketic, nettics[n] + CLIENTBACKUPTICS); + // assert netnodes[n].supposedtic>=netnodes[n].tic + realfirsttic = netnodes[n].supposedtic; + lasttictosend = min(maketic, netnodes[n].tic + CLIENTBACKUPTICS); if (realfirsttic >= lasttictosend) { @@ -4587,8 +4579,8 @@ static void SV_SendTics(void) // 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]; + n, maketic, netnodes[n].supposedtic, netnodes[n].tic)); + realfirsttic = netnodes[n].tic; if (realfirsttic >= lasttictosend || (I_GetTime() + n)&3) // all tic are ok continue; @@ -4666,13 +4658,13 @@ static void SV_SendTics(void) 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; + netnodes[n].supposedtic = lasttictosend-doomcom->extratics; else - supposedtics[n] = lasttictosend; - if (supposedtics[n] < nettics[n]) supposedtics[n] = nettics[n]; + netnodes[n].supposedtic = lasttictosend; + if (netnodes[n].supposedtic < netnodes[n].tic) netnodes[n].supposedtic = netnodes[n].tic; } // node 0 is me! - supposedtics[0] = maketic; + netnodes[0].supposedtic = maketic; } // @@ -4915,7 +4907,7 @@ static inline void PingUpdate(void) //send out our ping packets for (i = 0; i < MAXNETNODES; i++) - if (nodeingame[i]) + if (netnodes[i].ingame) HSendPacket(i, true, 0, sizeof(INT32) * (MAXPLAYERS+1)); pingmeasurecount = 1; //Reset count @@ -4993,11 +4985,11 @@ void NetUpdate(void) firstticstosend = gametic; for (i = 0; i < MAXNETNODES; i++) - if (nodeingame[i] && nettics[i] < firstticstosend) + if (netnodes[i].ingame && netnodes[i].tic < firstticstosend) { - firstticstosend = nettics[i]; + firstticstosend = netnodes[i].tic; - if (maketic + 1 >= nettics[i] + BACKUPTICS) + if (maketic + 1 >= netnodes[i].tic + BACKUPTICS) Net_ConnectionTimeout(i); } @@ -5025,7 +5017,7 @@ void NetUpdate(void) if (server) { for (i = 1; i < MAXNETNODES; i++) - if (nodeingame[i] && freezetimeout[i] < I_GetTime()) + if (netnodes[i].ingame && netnodes[i].freezetimeout < I_GetTime()) Net_ConnectionTimeout(i); // In case the cvar value was lowered @@ -5066,7 +5058,7 @@ INT32 D_NumPlayers(void) tic_t GetLag(INT32 node) { - return gametic - nettics[node]; + return gametic - netnodes[node].tic; } void D_MD5PasswordPass(const UINT8 *buffer, size_t len, const char *salt, void *dest) diff --git a/src/d_net.h b/src/d_net.h index 5baa593a0..9eee53894 100644 --- a/src/d_net.h +++ b/src/d_net.h @@ -37,10 +37,25 @@ boolean Net_GetNetStat(void); extern INT32 getbytes; extern INT64 sendbytes; // Realtime updated -extern SINT8 nodetoplayer[MAXNETNODES]; -extern SINT8 nodetoplayer2[MAXNETNODES]; // Say the numplayer for this node if any (splitscreen) -extern UINT8 playerpernode[MAXNETNODES]; // Used specially for splitscreen -extern boolean nodeingame[MAXNETNODES]; // Set false as nodes leave game +typedef struct netnode_s +{ + boolean ingame; // set false as nodes leave game + tic_t freezetimeout; // Until when can this node freeze the server before getting a timeout? + + SINT8 player; + SINT8 player2; // say the numplayer for this node if any (splitscreen) + UINT8 numplayers; // used specialy for scplitscreen + UINT8 numplayerswaiting; + + tic_t tic; // what tic the client have received + tic_t supposedtic; // nettics prevision for smaller packet + + boolean sendingsavegame; // Are we sending the savegame? + boolean resendingsavegame; // Are we resending the savegame? + tic_t savegameresendcooldown; // How long before we can resend again? +} netnode_t; + +extern netnode_t netnodes[MAXNETNODES]; extern boolean serverrunning; diff --git a/src/d_netfil.c b/src/d_netfil.c index 7c9ed54d8..1fee1df81 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -667,7 +667,7 @@ void SV_PrepareSendLuaFile(void) // Set status to "waiting" for everyone for (i = 0; i < MAXNETNODES; i++) - luafiletransfers->nodestatus[i] = (nodeingame[i] ? LFTNS_WAITING : LFTNS_NONE); + luafiletransfers->nodestatus[i] = (netnodes[i].ingame ? LFTNS_WAITING : LFTNS_NONE); if (FIL_ReadFileOK(luafiletransfers->realfilename)) { @@ -1291,7 +1291,7 @@ void FileReceiveTicker(void) void PT_FileFragment(SINT8 node, INT32 netconsole) { - if (nodeingame[node]) + if (netnodes[node].ingame) { // Only accept PT_FILEFRAGMENT from the server. if (node != servernode) diff --git a/src/i_tcp.c b/src/i_tcp.c index 8838ba725..00aebddd3 100644 --- a/src/i_tcp.c +++ b/src/i_tcp.c @@ -449,7 +449,7 @@ static void cleanupnodes(void) // Why can't I start at zero? for (j = 1; j < MAXNETNODES; j++) - if (!(nodeingame[j] || SendingFile(j))) + if (!(netnodes[j].ingame || SendingFile(j))) nodeconnected[j] = false; } @@ -473,7 +473,7 @@ static SINT8 getfreenode(void) */ /*I_Error("No more free nodes!!1!11!11!!1111\n"); for (j = 1; j < MAXNETNODES; j++) - if (!nodeingame[j]) + if (!netnodes[j].ingame) return j;*/ return -1; @@ -488,24 +488,24 @@ void Command_Numnodes(void) for (i = 1; i < MAXNETNODES; i++) { - if (!(nodeconnected[i] || nodeingame[i])) + if (!(nodeconnected[i] || netnodes[i].ingame)) continue; if (nodeconnected[i]) connected++; - if (nodeingame[i]) + if (netnodes[i].ingame) ingame++; CONS_Printf("%2d - ", i); - if (nodetoplayer[i] != -1) - CONS_Printf("player %.2d", nodetoplayer[i]); + if (netnodes[i].player != -1) + CONS_Printf("player %.2d", netnodes[i].player); else CONS_Printf(" "); if (nodeconnected[i]) CONS_Printf(" - connected"); else CONS_Printf(" - "); - if (nodeingame[i]) + if (netnodes[i].ingame) CONS_Printf(" - ingame"); else CONS_Printf(" - "); From f1117095b76a6cb8d85c6ea809bd47ddaa64f914 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Thu, 29 Dec 2022 20:45:56 +0100 Subject: [PATCH 318/586] Cleanup ResetNode --- src/d_clisrv.c | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index e311bf15a..3ab0df1d0 100755 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2278,7 +2278,12 @@ static void Command_connect(void) } #endif -static void ResetNode(INT32 node); +static void ResetNode(INT32 node) +{ + memset(&netnodes[node], 0, sizeof(*netnodes)); + netnodes[node].player = -1; + netnodes[node].player2 = -1; +} // // CL_ClearPlayer @@ -3007,23 +3012,6 @@ void D_ClientServerInit(void) SV_SpawnServer(); } -static void ResetNode(INT32 node) -{ - netnodes[node].ingame = false; - netnodes[node].numplayerswaiting = 0; - - netnodes[node].tic = gametic; - netnodes[node].supposedtic = gametic; - - netnodes[node].player = -1; - netnodes[node].player2 = -1; - netnodes[node].numplayers = 0; - - netnodes[node].sendingsavegame = false; - netnodes[node].resendingsavegame = false; - netnodes[node].savegameresendcooldown = 0; -} - void SV_ResetServer(void) { INT32 i; From ecacb14fc19fd312ca049a9df666c8b4c30f4274 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Thu, 29 Dec 2022 20:48:17 +0100 Subject: [PATCH 319/586] Move player-node unlinking to a function --- src/d_clisrv.c | 48 ++++++++++++++++++++++-------------------------- 1 file changed, 22 insertions(+), 26 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 3ab0df1d0..1fee20a3f 100755 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2298,6 +2298,24 @@ void CL_ClearPlayer(INT32 playernum) memset(playeraddress[playernum], 0, sizeof(*playeraddress)); } +static void UnlinkPlayerFromNode(INT32 playernum) +{ + INT32 node = playernode[playernum]; + + if (node == UINT8_MAX) + return; + + playernode[playernum] = UINT8_MAX; + + netnodes[node].numplayers--; + if (netnodes[node].numplayers <= 0) + { + netnodes[node].ingame = false; + Net_CloseConnection(node); + ResetNode(node); + } +} + // // CL_RemovePlayer // @@ -2310,17 +2328,8 @@ void CL_RemovePlayer(INT32 playernum, kickreason_t reason) if (!playeringame[playernum]) return; - if (server && !demoplayback && playernode[playernum] != UINT8_MAX) - { - INT32 node = playernode[playernum]; - netnodes[node].numplayers--; - if (netnodes[node].numplayers <= 0) - { - netnodes[node].ingame = false; - Net_CloseConnection(node); - ResetNode(node); - } - } + if (server) + UnlinkPlayerFromNode(playernum); if (gametyperules & GTR_TEAMFLAGS) P_PlayerFlagBurst(&players[playernum], false); // Don't take the flag with you! @@ -2392,7 +2401,6 @@ void CL_RemovePlayer(INT32 playernum, kickreason_t reason) // remove avatar of player playeringame[playernum] = false; - playernode[playernum] = UINT8_MAX; while (!playeringame[doomcom->numslots-1] && doomcom->numslots > 1) doomcom->numslots--; @@ -2920,20 +2928,8 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum) } else if (keepbody) { - if (server && !demoplayback && playernode[pnum] != UINT8_MAX) - { - INT32 node = playernode[pnum]; - netnodes[node].numplayers--; - if (netnodes[node].numplayers <= 0) - { - netnodes[node].ingame = false; - Net_CloseConnection(node); - ResetNode(node); - } - } - - playernode[pnum] = UINT8_MAX; - + if (server) + UnlinkPlayerFromNode(pnum); players[pnum].quittime = 1; } else From 2de6b623c09c33cca862b553ce925c8340cd5a4a Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Thu, 29 Dec 2022 21:28:53 +0100 Subject: [PATCH 320/586] Move sphere redistribution to its own function --- src/d_clisrv.c | 106 ++++++++++++++++++++++++++----------------------- 1 file changed, 56 insertions(+), 50 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 1fee20a3f..eee820db2 100755 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2316,6 +2316,61 @@ static void UnlinkPlayerFromNode(INT32 playernum) } } +// If in a special stage, redistribute the player's +// spheres across the remaining players. +// I feel like this shouldn't even be in this file at all, but well. +static void RedistributeSpecialStageSpheres(INT32 playernum) +{ + INT32 i, count, sincrement, spheres, rincrement, rings; + + if (!G_IsSpecialStage(gamemap)) + return; + + 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; + } + } + } +} + // // CL_RemovePlayer // @@ -2334,56 +2389,7 @@ void CL_RemovePlayer(INT32 playernum, kickreason_t reason) 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; - } - } - } - } + RedistributeSpecialStageSpheres(playernum); LUA_HookPlayerQuit(&players[playernum], reason); // Lua hook for player quitting From 0053eaac009a1a675fcf57a7c67f488faf0f1882 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Thu, 29 Dec 2022 22:16:08 +0100 Subject: [PATCH 321/586] Fix sphere redistribution --- src/d_clisrv.c | 54 +++++++++++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index eee820db2..432001b80 100755 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2333,39 +2333,39 @@ static void RedistributeSpecialStageSpheres(INT32 playernum) } count--; - sincrement = spheres = players[playernum].spheres; - rincrement = rings = players[playernum].rings; + spheres = players[playernum].spheres; + rings = players[playernum].rings; - if (count) + while (count && (spheres || rings)) { - sincrement /= count; - rincrement /= count; - } + sincrement = max(spheres / count, 1); + rincrement = max(rings / count, 1); - for (i = 0; i < MAXPLAYERS; i++) - { - if (playeringame[i] && i != playernum) + for (i = 0; i < MAXPLAYERS; i++) { - if (spheres < 2*sincrement) + if (playeringame[i] && i != playernum) { - P_GivePlayerSpheres(&players[i], spheres); - spheres = 0; - } - else - { - P_GivePlayerSpheres(&players[i], sincrement); - spheres -= sincrement; - } + if (spheres < 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; + if (rings < rincrement) + { + P_GivePlayerRings(&players[i], rings); + rings = 0; + } + else + { + P_GivePlayerRings(&players[i], rincrement); + rings -= rincrement; + } } } } From 394e925c16c7bab4fc8906046b3bf23a1ceee823 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Thu, 29 Dec 2022 22:30:26 +0100 Subject: [PATCH 322/586] Cleanup sphere redistribution --- src/d_clisrv.c | 57 ++++++++++++++++---------------------------------- 1 file changed, 18 insertions(+), 39 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 432001b80..1b344a0de 100755 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2321,52 +2321,31 @@ static void UnlinkPlayerFromNode(INT32 playernum) // I feel like this shouldn't even be in this file at all, but well. static void RedistributeSpecialStageSpheres(INT32 playernum) { - INT32 i, count, sincrement, spheres, rincrement, rings; - - if (!G_IsSpecialStage(gamemap)) + if (!G_IsSpecialStage(gamemap) || D_NumPlayers() <= 1) return; - for (i = 0, count = 0; i < MAXPLAYERS; i++) + INT32 count = D_NumPlayers() - 1; + INT32 spheres = players[playernum].spheres; + INT32 rings = players[playernum].rings; + + while (spheres || rings) { - if (playeringame[i]) - count++; - } - - count--; - spheres = players[playernum].spheres; - rings = players[playernum].rings; - - while (count && (spheres || rings)) - { - sincrement = max(spheres / count, 1); - rincrement = max(rings / count, 1); + INT32 sincrement = max(spheres / count, 1); + INT32 rincrement = max(rings / count, 1); + INT32 i, n; for (i = 0; i < MAXPLAYERS; i++) { - if (playeringame[i] && i != playernum) - { - if (spheres < sincrement) - { - P_GivePlayerSpheres(&players[i], spheres); - spheres = 0; - } - else - { - P_GivePlayerSpheres(&players[i], sincrement); - spheres -= sincrement; - } + if (!playeringame[i] || i == playernum) + continue; - if (rings < rincrement) - { - P_GivePlayerRings(&players[i], rings); - rings = 0; - } - else - { - P_GivePlayerRings(&players[i], rincrement); - rings -= rincrement; - } - } + n = min(spheres, sincrement); + P_GivePlayerSpheres(&players[i], n); + spheres -= n; + + n = min(rings, rincrement); + P_GivePlayerRings(&players[i], n); + rings -= n; } } } From 160db6383c1f04075491a0522196e9edd7b7d2c7 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Fri, 30 Dec 2022 00:24:06 +0100 Subject: [PATCH 323/586] Remove useless return value for SV_AddWaitingPlayers --- src/d_clisrv.c | 12 +++--------- src/d_clisrv.h | 2 +- src/d_netcmd.c | 3 +-- 3 files changed, 5 insertions(+), 12 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 1b344a0de..0c6960236 100755 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -3262,9 +3262,9 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum) LUA_HookInt(newplayernum, HOOK(PlayerJoin)); } -static boolean SV_AddWaitingPlayers(const char *name, const char *name2) +static void SV_AddWaitingPlayers(const char *name, const char *name2) { - INT32 node, n, newplayer = false; + INT32 node, n; UINT8 buf[2 + MAXPLAYERNAME]; UINT8 *p; INT32 newplayernum; @@ -3274,8 +3274,6 @@ static boolean SV_AddWaitingPlayers(const char *name, const char *name2) // splitscreen can allow 2 player in one node for (; netnodes[node].numplayerswaiting > 0; netnodes[node].numplayerswaiting--) { - newplayer = true; - newplayernum = FindRejoinerNum(node); if (newplayernum == -1) { @@ -3320,8 +3318,6 @@ static boolean SV_AddWaitingPlayers(const char *name, const char *name2) DEBFILE(va("Server added player %d node %d\n", newplayernum, node)); } } - - return newplayer; } void CL_AddSplitscreenPlayer(void) @@ -3344,7 +3340,7 @@ boolean Playing(void) return (server && serverrunning) || (client && cl_mode == CL_CONNECTED); } -boolean SV_SpawnServer(void) +void SV_SpawnServer(void) { if (demoplayback) G_StopDemo(); // reset engine parameter @@ -3371,8 +3367,6 @@ boolean SV_SpawnServer(void) CL_ConnectToServer(); else doomcom->numslots = 1; } - - return SV_AddWaitingPlayers(cv_playername.zstring, cv_playername2.zstring); } void SV_StopServer(void) diff --git a/src/d_clisrv.h b/src/d_clisrv.h index e07864122..b3ee95c0c 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -412,7 +412,7 @@ void SendKick(UINT8 playernum, UINT8 msg); void NetUpdate(void); void SV_StartSinglePlayerServer(void); -boolean SV_SpawnServer(void); +void SV_SpawnServer(void); void SV_StopServer(void); void SV_ResetServer(void); void CL_AddSplitscreenPlayer(void); diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 5f02bc2de..243501ba4 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1850,8 +1850,7 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pultmode, boolean rese // reset players if there is a new one if (!IsPlayerAdmin(consoleplayer)) { - if (SV_SpawnServer()) - buf[0] &= ~(1<<1); + SV_SpawnServer(); if (!Playing()) // you failed to start a server somehow, so cancel the map change return; } From 6ab9b9ae8a29fda62129650c757bd9e2d72a2e64 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Fri, 30 Dec 2022 01:48:26 +0100 Subject: [PATCH 324/586] Remove useless condition --- src/d_clisrv.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 0c6960236..bc0992539 100755 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -3563,17 +3563,14 @@ static void HandleConnect(SINT8 node) DEBFILE("new node joined\n"); } #ifndef NONET - if (netnodes[node].numplayerswaiting) + if ((gamestate == GS_LEVEL || gamestate == GS_INTERMISSION) && newnode) { - 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; + 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 } } From f501c4b25072a063141649353f86bfbada89d83e Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Fri, 30 Dec 2022 02:46:59 +0100 Subject: [PATCH 325/586] Remove unneeded numplayerswaiting field --- src/d_clisrv.c | 98 ++++++++++++++++++++++++-------------------------- src/d_net.h | 1 - 2 files changed, 47 insertions(+), 52 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index bc0992539..7aafdf539 100755 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -3262,62 +3262,54 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum) LUA_HookInt(newplayernum, HOOK(PlayerJoin)); } -static void SV_AddWaitingPlayers(const char *name, const char *name2) +static void SV_AddPlayer(SINT8 node, const char *name) { - INT32 node, n; + INT32 n; UINT8 buf[2 + MAXPLAYERNAME]; UINT8 *p; INT32 newplayernum; - for (node = 0; node < MAXNETNODES; node++) + newplayernum = FindRejoinerNum(node); + if (newplayernum == -1) { - // splitscreen can allow 2 player in one node - for (; netnodes[node].numplayerswaiting > 0; netnodes[node].numplayerswaiting--) + // search for a free playernum + // we can't use playeringame since it is not updated here + for (newplayernum = dedicated ? 1 : 0; newplayernum < MAXPLAYERS; newplayernum++) { - 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 (netnodes[n].player == newplayernum || netnodes[n].player2 == 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 (netnodes[node].numplayers < 1) - { - netnodes[node].player = newplayernum; - WRITESTRINGN(p, name, MAXPLAYERNAME); - } - else - { - netnodes[node].player2 = newplayernum; - buf[1] |= 0x80; - WRITESTRINGN(p, name2, MAXPLAYERNAME); - } - netnodes[node].numplayers++; - - SendNetXCmd(XD_ADDPLAYER, &buf, p - buf); - - DEBFILE(va("Server added player %d node %d\n", newplayernum, node)); + if (playeringame[newplayernum]) + continue; + for (n = 0; n < MAXNETNODES; n++) + if (netnodes[n].player == newplayernum || netnodes[n].player2 == 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 (netnodes[node].numplayers < 1) + { + netnodes[node].player = newplayernum; + } + else + { + netnodes[node].player2 = newplayernum; + buf[1] |= 0x80; + } + WRITESTRINGN(p, name, MAXPLAYERNAME); + netnodes[node].numplayers++; + + SendNetXCmd(XD_ADDPLAYER, &buf, p - buf); + + DEBFILE(va("Server added player %d node %d\n", newplayernum, node)); } void CL_AddSplitscreenPlayer(void) @@ -3522,11 +3514,12 @@ static void HandleConnect(SINT8 node) SV_SendRefuse(node, refuse); else { + INT32 numplayers = netbuffer->u.clientcfg.localplayers; #ifndef NONET boolean newnode = false; #endif - for (i = 0; i < netbuffer->u.clientcfg.localplayers - netnodes[node].numplayers; i++) + for (i = 0; i < numplayers; i++) { strlcpy(names[i], netbuffer->u.clientcfg.names[i], MAXPLAYERNAME + 1); if (!EnsurePlayerNameIsGood(names[i], rejoinernum)) @@ -3537,7 +3530,6 @@ static void HandleConnect(SINT8 node) } // client authorised to join - netnodes[node].numplayerswaiting = (UINT8)(netbuffer->u.clientcfg.localplayers - netnodes[node].numplayers); if (!netnodes[node].ingame) { gamestate_t backupstate = gamestate; @@ -3568,7 +3560,12 @@ static void HandleConnect(SINT8 node) SV_SendSaveGame(node, false); // send a complete game state DEBFILE("send savegame\n"); } - SV_AddWaitingPlayers(names[0], names[1]); + + // Splitscreen can allow 2 players in one node + SV_AddPlayer(node, names[0]); + if (numplayers > 1) + SV_AddPlayer(node, names[1]); + joindelay += cv_joindelay.value * TICRATE; player_joining = true; #endif @@ -3993,7 +3990,6 @@ static void PT_ClientQuit(SINT8 node, INT32 netconsole) // 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 - netnodes[node].numplayerswaiting = 0; if (netconsole != -1 && playeringame[netconsole]) { UINT8 kickmsg; diff --git a/src/d_net.h b/src/d_net.h index 9eee53894..c6c9e2894 100644 --- a/src/d_net.h +++ b/src/d_net.h @@ -45,7 +45,6 @@ typedef struct netnode_s SINT8 player; SINT8 player2; // say the numplayer for this node if any (splitscreen) UINT8 numplayers; // used specialy for scplitscreen - UINT8 numplayerswaiting; tic_t tic; // what tic the client have received tic_t supposedtic; // nettics prevision for smaller packet From b66353932d80f27ba780ac474061a8c1cc841708 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Fri, 30 Dec 2022 13:10:01 +0100 Subject: [PATCH 326/586] Remove broken joinnextround console variable --- src/d_clisrv.c | 6 ------ src/d_clisrv.h | 2 +- src/d_netcmd.c | 1 - 3 files changed, 1 insertion(+), 8 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 7aafdf539..31a19001a 100755 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2925,7 +2925,6 @@ static CV_PossibleValue_t netticbuffer_cons_t[] = {{0, "MIN"}, {3, "MAX"}, {0, N 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}}; @@ -3532,17 +3531,13 @@ static void HandleConnect(SINT8 node) // client authorised to join if (!netnodes[node].ingame) { - 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")); @@ -3551,7 +3546,6 @@ static void HandleConnect(SINT8 node) } //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 diff --git a/src/d_clisrv.h b/src/d_clisrv.h index b3ee95c0c..99d859924 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -394,7 +394,7 @@ extern UINT32 realpingtable[MAXPLAYERS]; extern UINT32 playerpingtable[MAXPLAYERS]; extern tic_t servermaxping; -extern consvar_t cv_netticbuffer, cv_allownewplayer, cv_joinnextround, cv_maxplayers, cv_joindelay, cv_rejointimeout; +extern consvar_t cv_netticbuffer, cv_allownewplayer, cv_maxplayers, cv_joindelay, cv_rejointimeout; extern consvar_t cv_resynchattempts, cv_blamecfail; extern consvar_t cv_maxsend, cv_noticedownload, cv_downloadspeed; diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 243501ba4..64f478ff7 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -630,7 +630,6 @@ void D_RegisterServerCommands(void) CV_RegisterVar(&cv_downloadspeed); #ifndef NONET CV_RegisterVar(&cv_allownewplayer); - CV_RegisterVar(&cv_joinnextround); CV_RegisterVar(&cv_showjoinaddress); CV_RegisterVar(&cv_blamecfail); #endif From d816e4d111499a820f09df3fbc9acaa57a1859bc Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Fri, 30 Dec 2022 14:01:03 +0100 Subject: [PATCH 327/586] Cleanup HandleConnect --- src/d_clisrv.c | 96 +++++++++++++++++++++----------------------------- 1 file changed, 41 insertions(+), 55 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 31a19001a..699c372d7 100755 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -3501,69 +3501,55 @@ ConnectionRefused (SINT8 node, INT32 rejoinernum) static void HandleConnect(SINT8 node) { char names[MAXSPLITSCREENPLAYERS][MAXPLAYERNAME + 1]; + INT32 numplayers = netbuffer->u.clientcfg.localplayers; INT32 rejoinernum; INT32 i; - const char *refuse; rejoinernum = FindRejoinerNum(node); - refuse = ConnectionRefused(node, rejoinernum); - + const char *refuse = ConnectionRefused(node, rejoinernum); if (refuse) - SV_SendRefuse(node, refuse); - else { - INT32 numplayers = netbuffer->u.clientcfg.localplayers; -#ifndef NONET - boolean newnode = false; -#endif - - for (i = 0; i < numplayers; 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 - if (!netnodes[node].ingame) - { -#ifndef NONET - newnode = true; -#endif - SV_AddNode(node); - - if (!SV_SendServerConfig(node)) - { - /// \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 - DEBFILE("new node joined\n"); - } -#ifndef NONET - if ((gamestate == GS_LEVEL || gamestate == GS_INTERMISSION) && newnode) - { - SV_SendSaveGame(node, false); // send a complete game state - DEBFILE("send savegame\n"); - } - - // Splitscreen can allow 2 players in one node - SV_AddPlayer(node, names[0]); - if (numplayers > 1) - SV_AddPlayer(node, names[1]); - - joindelay += cv_joindelay.value * TICRATE; - player_joining = true; -#endif + SV_SendRefuse(node, refuse); + return; } + + for (i = 0; i < numplayers; i++) + { + strlcpy(names[i], netbuffer->u.clientcfg.names[i], MAXPLAYERNAME + 1); + if (!EnsurePlayerNameIsGood(names[i], rejoinernum)) + { + SV_SendRefuse(node, "Bad player name"); + return; + } + } + + SV_AddNode(node); + + if (!SV_SendServerConfig(node)) + { + /// \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 + } + DEBFILE("new node joined\n"); + +#ifndef NONET + if (gamestate == GS_LEVEL || gamestate == GS_INTERMISSION) + { + SV_SendSaveGame(node, false); // send a complete game state + DEBFILE("send savegame\n"); + } + + // Splitscreen can allow 2 players in one node + for (i = 0; i < numplayers; i++) + SV_AddPlayer(node, names[i]); + + joindelay += cv_joindelay.value * TICRATE; + player_joining = true; +#endif } /** Called when a PT_SERVERSHUTDOWN packet is received From 7b96efc17964972753bc38ca310dcd64732d9ca9 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Fri, 30 Dec 2022 14:01:37 +0100 Subject: [PATCH 328/586] Rename ConnectionRefused to be more descriptive --- src/d_clisrv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 699c372d7..d7d02f9bb 100755 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -3422,7 +3422,7 @@ static size_t TotalTextCmdPerTic(tic_t tic) } static const char * -ConnectionRefused (SINT8 node, INT32 rejoinernum) +GetRefuseMessage (SINT8 node, INT32 rejoinernum) { clientconfig_pak *cc = &netbuffer->u.clientcfg; @@ -3507,7 +3507,7 @@ static void HandleConnect(SINT8 node) rejoinernum = FindRejoinerNum(node); - const char *refuse = ConnectionRefused(node, rejoinernum); + const char *refuse = GetRefuseMessage(node, rejoinernum); if (refuse) { SV_SendRefuse(node, refuse); From 1f4c71739ab57fbd035bd1f13d178b981a2836f4 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Fri, 30 Dec 2022 14:03:32 +0100 Subject: [PATCH 329/586] Ignore duplicate PT_CLIENTJOIN packets --- src/d_clisrv.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index d7d02f9bb..b25e34c56 100755 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -3505,6 +3505,10 @@ static void HandleConnect(SINT8 node) INT32 rejoinernum; INT32 i; + // Ignore duplicate packets + if (netnodes[node].ingame) + return; + rejoinernum = FindRejoinerNum(node); const char *refuse = GetRefuseMessage(node, rejoinernum); From 07bc9222737a026859bc99d56b598c8973a66bb9 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Fri, 30 Dec 2022 15:07:57 +0100 Subject: [PATCH 330/586] Delete netcode Just kidding, I just deleted NONET --- src/Makefile | 1 - src/Makefile.d/features.mk | 4 +- src/Makefile.d/win32.mk | 2 - src/d_clisrv.c | 85 +------------ src/d_clisrv.h | 2 - src/d_net.c | 48 -------- src/d_net.h | 2 - src/d_netcmd.c | 2 - src/d_netfil.c | 6 - src/d_netfil.h | 2 - src/deh_tables.c | 2 +- src/doomdef.h | 3 +- src/hu_stuff.c | 31 ----- src/i_tcp.c | 238 ++++++++++++++----------------------- src/m_menu.c | 57 +-------- src/m_menu.h | 2 +- src/mserv.c | 6 - src/sdl/i_system.c | 4 - 18 files changed, 97 insertions(+), 400 deletions(-) diff --git a/src/Makefile b/src/Makefile index 36b1a7efa..7fe7f8990 100644 --- a/src/Makefile +++ b/src/Makefile @@ -64,7 +64,6 @@ # # Netplay incompatible # -------------------- -# NONET=1 - Disable online capability. # NOMD5=1 - Disable MD5 checksum (validation tool). # NOPOSTPROCESSING=1 - ? # MOBJCONSISTANCY=1 - ?? diff --git a/src/Makefile.d/features.mk b/src/Makefile.d/features.mk index 8ba33383b..9acbb4d86 100644 --- a/src/Makefile.d/features.mk +++ b/src/Makefile.d/features.mk @@ -3,7 +3,7 @@ # passthru_opts+=\ - NONET NO_IPV6 NOHW NOMD5 NOPOSTPROCESSING\ + NO_IPV6 NOHW NOMD5 NOPOSTPROCESSING\ MOBJCONSISTANCY PACKETDROP ZDEBUG\ HAVE_MINIUPNPC\ @@ -46,13 +46,11 @@ 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 diff --git a/src/Makefile.d/win32.mk b/src/Makefile.d/win32.mk index 0e48ed683..e7269e1e7 100644 --- a/src/Makefile.d/win32.mk +++ b/src/Makefile.d/win32.mk @@ -35,12 +35,10 @@ libs+=-lws2_32 endif endif -ifndef NONET ifndef MINGW64 # miniupnc is broken with MINGW64 opts+=-I../libs -DSTATIC_MINIUPNPC libs+=-L../libs/miniupnpc/mingw$(32) -lws2_32 -liphlpapi endif -endif ifndef MINGW64 32=32 diff --git a/src/d_clisrv.c b/src/d_clisrv.c index b25e34c56..cb1ccd539 100755 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -53,12 +53,10 @@ // aaaaaa #include "i_gamepad.h" -#ifndef NONET // cl loading screen #include "v_video.h" #include "f_finale.h" #include "snake.h" -#endif // // NETWORKING @@ -535,7 +533,6 @@ static cl_mode_t cl_mode = CL_SEARCHING; static UINT16 cl_lastcheckedfilecount = 0; // used for full file list -#ifndef NONET static void *snake = NULL; static void CL_DrawConnectionStatusBox(void) @@ -716,7 +713,6 @@ static inline void CL_DrawConnectionStatus(void) } } } -#endif static boolean CL_AskFileList(INT32 firstfile) { @@ -983,7 +979,6 @@ static boolean SV_SendServerConfig(INT32 node) return waspacketsent; } -#ifndef NONET #define SAVEGAMESIZE (768*1024) static boolean SV_ResendingSavegameToAnyone(void) @@ -1210,9 +1205,7 @@ static void CL_ReloadReceivedSavegame(void) CONS_Printf(M_GetText("Game state reloaded\n")); } -#endif -#ifndef NONET static void SendAskInfo(INT32 node) { const tic_t asktime = I_GetTime(); @@ -1430,12 +1423,8 @@ void CL_UpdateServerList(boolean internetsearch, INT32 room) #endif/*MASTERSERVER*/ } -#endif // ifndef NONET - static void M_ConfirmConnect(event_t *ev) { -#ifndef NONET - if (ev->type == ev_keydown || ev->type == ev_gamepad_down) { if ((ev->type == ev_keydown && (ev->key == ' ' || ev->key == 'y' || ev->key == KEY_ENTER)) || (ev->type == ev_gamepad_down && ev->which == 0 && ev->key == GAMEPAD_BUTTON_A)) @@ -1459,9 +1448,6 @@ static void M_ConfirmConnect(event_t *ev) M_ClearMenus(true); } } -#else - (void)ev; -#endif } static boolean CL_FinishedFileList(void) @@ -1541,7 +1527,6 @@ static boolean CL_FinishedFileList(void) return false; } -#ifndef NONET downloadcompletednum = 0; downloadcompletedsize = 0; totalfilesrequestednum = 0; @@ -1561,7 +1546,6 @@ static boolean CL_FinishedFileList(void) downloadsize = Z_StrDup(va("%uM",totalfilesrequestedsize>>20)); else downloadsize = Z_StrDup(va("%uK",totalfilesrequestedsize>>10)); -#endif if (serverisfull) M_StartMessage(va(M_GetText( @@ -1586,7 +1570,6 @@ static boolean CL_FinishedFileList(void) return true; } -#ifndef NONET static const char * InvalidServerReason (serverinfo_pak *info) { #define EOT "\nPress ESC\n" @@ -1650,7 +1633,6 @@ static const char * InvalidServerReason (serverinfo_pak *info) #undef EOT } -#endif // ifndef NONET /** Called by CL_ServerConnectionTicker * @@ -1662,7 +1644,6 @@ static const char * InvalidServerReason (serverinfo_pak *info) */ static boolean CL_ServerConnectionSearchTicker(tic_t *asksent) { -#ifndef NONET INT32 i; // serverlist is updated by GetPacket function @@ -1732,11 +1713,6 @@ static boolean CL_ServerConnectionSearchTicker(tic_t *asksent) 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; } @@ -1756,10 +1732,6 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic boolean waitmore; INT32 i; -#ifdef NONET - (void)tmpsave; -#endif - switch (cl_mode) { case CL_SEARCHING: @@ -1824,12 +1796,12 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic ), 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 (I_GetTime() >= *asksent && CL_SendJoin()) { *asksent = I_GetTime() + NEWTICRATE*3; @@ -1842,7 +1814,6 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic cl_mode = CL_ASKJOIN; } break; -#ifndef NONET case CL_DOWNLOADSAVEGAME: // At this state, the first (and only) needed file is the gamestate if (fileneeded[0].status == FS_FOUND) @@ -1853,7 +1824,6 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic } // don't break case continue to CL_CONNECTED else break; -#endif case CL_CONNECTED: case CL_CONFIRMCONNECT: //logic is handled by M_ConfirmConnect @@ -1898,10 +1868,8 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic memset(gamekeydown, 0, NUMKEYS); return false; } -#ifndef NONET else if (cl_mode == CL_DOWNLOADFILES && snake) Snake_Update(snake); -#endif if (client && (cl_mode == CL_DOWNLOADFILES || cl_mode == CL_DOWNLOADSAVEGAME)) FileReceiveTicker(); @@ -1912,7 +1880,6 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic //FileSendTicker(); *oldtic = I_GetTime(); -#ifndef NONET if (client && cl_mode != CL_CONNECTED && cl_mode != CL_ABORTED) { if (!snake) @@ -1935,10 +1902,6 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic S_UpdateSounds(); S_UpdateClosedCaptions(); } -#else - CON_Drawer(); - I_UpdateNoVsync(); -#endif } else { @@ -1958,22 +1921,18 @@ 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) { @@ -1994,7 +1953,6 @@ static void CL_ConnectToServer(void) pnumnodes = 1; oldtic = I_GetTime() - 1; -#ifndef NONET asksent = (tic_t) - TICRATE; firstconnectattempttime = I_GetTime(); @@ -2010,16 +1968,11 @@ static void CL_ConnectToServer(void) 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) @@ -2037,7 +1990,6 @@ static void CL_ConnectToServer(void) displayplayer = consoleplayer; } -#ifndef NONET typedef struct banreason_s { char *reason; @@ -2276,7 +2228,6 @@ static void Command_connect(void) botskin = 0; CL_ConnectToServer(); } -#endif static void ResetNode(INT32 node) { @@ -2437,10 +2388,8 @@ void CL_Reset(void) FreeFileNeeded(); fileneedednum = 0; -#ifndef NONET totalfilesrequestednum = 0; totalfilesrequestedsize = 0; -#endif firstconnectattempttime = 0; serverisfull = false; connectiontimeout = (tic_t)cv_nettimeout.value; //reset this temporary hack @@ -2448,7 +2397,6 @@ void CL_Reset(void) // D_StartTitle should get done now, but the calling function will handle it } -#ifndef NONET static void Command_GetPlayerNum(void) { INT32 i; @@ -2726,7 +2674,6 @@ static void Command_ResendGamestate(void) return; } } -#endif static void Got_KickCmd(UINT8 **p, INT32 playernum) { @@ -2810,10 +2757,8 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum) { 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) @@ -2953,7 +2898,6 @@ 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); @@ -2970,17 +2914,14 @@ void D_ClientServerInit(void) #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; @@ -3540,7 +3481,6 @@ static void HandleConnect(SINT8 node) } DEBFILE("new node joined\n"); -#ifndef NONET if (gamestate == GS_LEVEL || gamestate == GS_INTERMISSION) { SV_SendSaveGame(node, false); // send a complete game state @@ -3553,7 +3493,6 @@ static void HandleConnect(SINT8 node) joindelay += cv_joindelay.value * TICRATE; player_joining = true; -#endif } /** Called when a PT_SERVERSHUTDOWN packet is received @@ -3586,7 +3525,6 @@ static void HandleTimeout(SINT8 node) 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 @@ -3608,7 +3546,6 @@ static void HandleServerInfo(SINT8 node) SL_InsertServer(&netbuffer->u.serverinfo, node); } -#endif // Helper function for packets that should only be sent by the server // If it is NOT from the server, bail out and close the connection! @@ -3744,14 +3681,9 @@ static void PT_ServerCFG(SINT8 node) 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... @@ -3759,7 +3691,6 @@ static void PT_ServerCFG(SINT8 node) netbuffer->u.servercfg.gamestate == GS_INTERMISSION*/) cl_mode = CL_DOWNLOADSAVEGAME; else -#endif cl_mode = CL_CONNECTED; } @@ -3823,9 +3754,7 @@ static void PT_ClientCmd(SINT8 node, INT32 netconsole) // Check player consistancy during the level if (realstart <= gametic && realstart + BACKUPTICS - 1 > gametic && gamestate == GS_LEVEL && consistancy[realstart%BACKUPTICS] != SHORT(netbuffer->u.clientpak.consistancy) -#ifndef NONET && !SV_ResendingSavegameToAnyone() -#endif && !netnodes[node].resendingsavegame && netnodes[node].savegameresendcooldown <= I_GetTime()) { if (cv_resynchattempts.value) @@ -4000,7 +3929,6 @@ static void PT_ClientQuit(SINT8 node, INT32 netconsole) static void PT_CanReceiveGamestate(SINT8 node) { -#ifndef NONET if (client || netnodes[node].sendingsavegame) return; @@ -4008,9 +3936,6 @@ static void PT_CanReceiveGamestate(SINT8 node) SV_SendSaveGame(node, true); // Resend a complete game state netnodes[node].resendingsavegame = true; -#else - (void)node; -#endif } static void PT_AskLuaFile(SINT8 node) @@ -4134,7 +4059,6 @@ static void PT_WillResendGamestate(SINT8 node) { (void)node; -#ifndef NONET char tmpsave[256]; if (server || cl_redownloadinggamestate) @@ -4157,7 +4081,6 @@ static void PT_WillResendGamestate(SINT8 node) CL_PrepareDownloadSaveGame(tmpsave); cl_redownloadinggamestate = true; -#endif } static void PT_SendingLuaFile(SINT8 node) @@ -4296,13 +4219,11 @@ static void GetPackets(void) } } -#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. @@ -4906,11 +4827,9 @@ 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; diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 99d859924..0d6add13a 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -437,11 +437,9 @@ boolean TryRunTics(tic_t realtic); /*boolean AddLmpExtradata(UINT8 **demo_p, INT32 playernum); void ReadLmpExtraData(UINT8 **demo_pointer, INT32 playernum);*/ -#ifndef NONET // translate a playername in a player number return -1 if not found and // print a error message in the console SINT8 nametonum(const char *name); -#endif extern char motd[254], server_context[8]; extern UINT8 playernode[MAXPLAYERS]; diff --git a/src/d_net.c b/src/d_net.c index a7e1eb16d..9e3759d32 100644 --- a/src/d_net.c +++ b/src/d_net.c @@ -138,7 +138,6 @@ boolean Net_GetNetStat(void) #define URGENTFREESLOTNUM 10 #define ACKTOSENDTIMEOUT (TICRATE/11) -#ifndef NONET typedef struct { UINT8 acknum; @@ -152,7 +151,6 @@ typedef struct doomdata_t data; } pak; } ackpak_t; -#endif typedef enum { @@ -160,10 +158,8 @@ typedef enum NF_TIMEOUT = 2, // Flag is set when the node got a timeout } node_flags_t; -#ifndef NONET // Table of packets that were not acknowleged can be resent (the sender window) static ackpak_t ackpak[MAXACKPACKETS]; -#endif typedef struct { @@ -191,7 +187,6 @@ typedef struct static node_t nodes[MAXNETNODES]; #define NODETIMEOUT 14 -#ifndef NONET // return <0 if a < b (mod 256) // 0 if a = n (mod 256) // >0 if a > b (mod 256) @@ -426,21 +421,15 @@ static boolean Processackpak(void) } return goodpacket; } -#endif // send special packet with only ack on it void Net_SendAcks(INT32 node) { -#ifdef NONET - (void)node; -#else netbuffer->packettype = PT_NOTHING; M_Memcpy(netbuffer->u.textcmd, nodes[node].acktosend, MAXACKTOSEND); HSendPacket(node, false, 0, MAXACKTOSEND); -#endif } -#ifndef NONET static void GotAcks(void) { INT32 i, j; @@ -463,7 +452,6 @@ static void GotAcks(void) } } } -#endif void Net_ConnectionTimeout(INT32 node) { @@ -489,7 +477,6 @@ void Net_ConnectionTimeout(INT32 node) // Resend the data if needed void Net_AckTicker(void) { -#ifndef NONET INT32 i; for (i = 0; i < MAXACKPACKETS; i++) @@ -536,16 +523,12 @@ void Net_AckTicker(void) } } } -#endif } // Remove last packet received ack before resending the ackreturn // (the higher layer doesn't have room, or something else ....) void Net_UnAcknowledgePacket(INT32 node) { -#ifdef NONET - (void)node; -#else INT32 hm1 = (nodes[node].acktosend_head-1+MAXACKTOSEND) % MAXACKTOSEND; DEBFILE(va("UnAcknowledge node %d\n", node)); if (!node) @@ -577,10 +560,8 @@ void Net_UnAcknowledgePacket(INT32 node) if (!nodes[node].firstacktosend) nodes[node].firstacktosend = 1; } -#endif } -#ifndef NONET /** Checks if all acks have been received * * \return True if all acks have been received @@ -596,7 +577,6 @@ static boolean Net_AllAcksReceived(void) return true; } -#endif /** Waits for all ackreturns * @@ -605,9 +585,6 @@ static boolean Net_AllAcksReceived(void) */ void Net_WaitAllAckReceived(UINT32 timeout) { -#ifdef NONET - (void)timeout; -#else tic_t tictac = I_GetTime(); timeout = tictac + timeout*NEWTICRATE; @@ -623,7 +600,6 @@ void Net_WaitAllAckReceived(UINT32 timeout) HGetPacket(); Net_AckTicker(); } -#endif } static void InitNode(node_t *node) @@ -639,10 +615,8 @@ static void InitAck(void) { INT32 i; -#ifndef NONET for (i = 0; i < MAXACKPACKETS; i++) ackpak[i].acknum = 0; -#endif for (i = 0; i < MAXNETNODES; i++) InitNode(&nodes[i]); @@ -655,9 +629,6 @@ static void InitAck(void) */ void Net_AbortPacketType(UINT8 packettype) { -#ifdef NONET - (void)packettype; -#else INT32 i; for (i = 0; i < MAXACKPACKETS; i++) if (ackpak[i].acknum && (ackpak[i].pak.data.packettype == packettype @@ -665,7 +636,6 @@ void Net_AbortPacketType(UINT8 packettype) { ackpak[i].acknum = 0; } -#endif } // ----------------------------------------------------------------- @@ -675,9 +645,6 @@ void Net_AbortPacketType(UINT8 packettype) // remove a node, clear all ack from this node and reset askret void Net_CloseConnection(INT32 node) { -#ifdef NONET - (void)node; -#else INT32 i; boolean forceclose = (node & FORCECLOSE) != 0; @@ -722,10 +689,8 @@ void Net_CloseConnection(INT32 node) if (server) SV_AbortLuaFileTransfer(node); I_NetFreeNodenum(node); -#endif } -#ifndef NONET // // Checksum // @@ -741,7 +706,6 @@ static UINT32 NetbufferChecksum(void) return LONG(c); } -#endif #ifdef DEBUGFILE @@ -983,14 +947,12 @@ void Command_Droprate(void) packetdroprate = droprate; } -#ifndef NONET static boolean ShouldDropPacket(void) { return (packetdropquantity[netbuffer->packettype]) || (packetdroprate != 0 && rand() < (RAND_MAX * (packetdroprate / 100.f))) || packetdroprate == 100; } #endif -#endif // // HSendPacket @@ -1025,11 +987,6 @@ boolean HSendPacket(INT32 node, boolean reliable, UINT8 acknum, size_t packetlen if (!netgame) I_Error("Tried to transmit to another node"); -#ifdef NONET - (void)node; - (void)reliable; - (void)acknum; -#else // do this before GetFreeAcknum because this function backups // the current packet doomcom->remotenode = (INT16)node; @@ -1090,8 +1047,6 @@ boolean HSendPacket(INT32 node, boolean reliable, UINT8 acknum, size_t packetlen } #endif -#endif // ndef NONET - return true; } @@ -1125,8 +1080,6 @@ boolean HGetPacket(void) if (!netgame) return false; -#ifndef NONET - while(true) { //nodejustjoined = I_NetGet(); @@ -1186,7 +1139,6 @@ boolean HGetPacket(void) } break; } -#endif // ndef NONET return true; } diff --git a/src/d_net.h b/src/d_net.h index c6c9e2894..803b49d74 100644 --- a/src/d_net.h +++ b/src/d_net.h @@ -66,9 +66,7 @@ boolean HSendPacket(INT32 node, boolean reliable, UINT8 acknum, size_t packetlength); boolean HGetPacket(void); void D_SetDoomcom(void); -#ifndef NONET void D_SaveBan(void); -#endif boolean D_CheckNetGame(void); void D_CloseConnection(void); void Net_UnAcknowledgePacket(INT32 node); diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 64f478ff7..69eed90de 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -628,11 +628,9 @@ void D_RegisterServerCommands(void) CV_RegisterVar(&cv_maxsend); CV_RegisterVar(&cv_noticedownload); CV_RegisterVar(&cv_downloadspeed); -#ifndef NONET CV_RegisterVar(&cv_allownewplayer); CV_RegisterVar(&cv_showjoinaddress); CV_RegisterVar(&cv_blamecfail); -#endif COM_AddCommand("ping", Command_Ping_f); CV_RegisterVar(&cv_nettimeout); diff --git a/src/d_netfil.c b/src/d_netfil.c index 1fee1df81..bf3952cc9 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -103,14 +103,12 @@ typedef struct } pauseddownload_t; 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; boolean waitingforluafiletransfer = false; @@ -250,9 +248,7 @@ void D_ParseFileneeded(INT32 fileneedednum_parm, UINT8 *fileneededstr, UINT16 fi void CL_PrepareDownloadSaveGame(const char *tmpsave) { -#ifndef NONET lastfilenum = -1; -#endif FreeFileNeeded(); AllocFileNeeded(1); @@ -1466,9 +1462,7 @@ void PT_FileFragment(SINT8 node, INT32 netconsole) I_Error("Received a file not requested (file id: %d, file status: %s)\n", filenum, s); } -#ifndef NONET lastfilenum = filenum; -#endif } /** \brief Checks if a node is downloading a file diff --git a/src/d_netfil.h b/src/d_netfil.h index 5c7f4ef49..ec53be587 100644 --- a/src/d_netfil.h +++ b/src/d_netfil.h @@ -70,13 +70,11 @@ extern INT32 fileneedednum; 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 void AllocFileNeeded(INT32 size); void FreeFileNeeded(void); diff --git a/src/deh_tables.c b/src/deh_tables.c index 6a815b6ea..5607142e5 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -4879,7 +4879,7 @@ const char *const MENUTYPES_LIST[] = { "MP_SERVER", "MP_CONNECT", "MP_ROOM", - "MP_PLAYERSETUP", // MP_PlayerSetupDef shared with SPLITSCREEN if #defined NONET + "MP_PLAYERSETUP", "MP_SERVER_OPTIONS", // Options diff --git a/src/doomdef.h b/src/doomdef.h index 84404d6ed..22cafa190 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -56,7 +56,6 @@ #endif #ifdef _WINDOWS -#define NONET #if !defined (HWRENDER) && !defined (NOHW) #define HWRENDER #endif @@ -707,7 +706,7 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; /// Maintain compatibility with older 2.2 demos #define OLD22DEMOCOMPAT -#if defined (HAVE_CURL) && ! defined (NONET) +#ifdef HAVE_CURL #define MASTERSERVER #else #undef UPDATE_ALERT diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 091e2b2fb..c423f2905 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -175,14 +175,12 @@ static huddrawlist_h luahuddrawlist_scores; static tic_t resynch_ticker = 0; -#ifndef NONET // just after static void Command_Say_f(void); static void Command_Sayto_f(void); static void Command_Sayteam_f(void); static void Command_CSay_f(void); static void Got_Saycmd(UINT8 **p, INT32 playernum); -#endif void HU_LoadGraphics(void) { @@ -327,13 +325,11 @@ void HU_LoadGraphics(void) // void HU_Init(void) { -#ifndef NONET COM_AddCommand("say", Command_Say_f, COM_LUA); COM_AddCommand("sayto", Command_Sayto_f, COM_LUA); COM_AddCommand("sayteam", Command_Sayteam_f, COM_LUA); COM_AddCommand("csay", Command_CSay_f, COM_LUA); RegisterNetXCmd(XD_SAY, Got_Saycmd); -#endif // set shift translation table shiftxform = english_shiftxform; @@ -363,8 +359,6 @@ void HU_Start(void) // EXECUTION //====================================================================== -#ifndef NONET - // EVERY CHANGE IN THIS SCRIPT IS LOL XD! BY VINCYTM static UINT32 chat_nummsg_log = 0; @@ -412,11 +406,9 @@ static void HU_removeChatText_Log(void) } chat_nummsg_log--; // lost 1 msg. } -#endif void HU_AddChatText(const char *text, boolean playsound) { -#ifndef NONET if (playsound && cv_consolechat.value != 2) // Don't play the sound if we're using hidden chat. S_StartSound(NULL, sfx_radio); // reguardless of our preferences, put all of this in the chat buffer in case we decide to change from oldchat mid-game. @@ -438,14 +430,8 @@ void HU_AddChatText(const char *text, boolean playsound) CONS_Printf("%s\n", text); else // if we aren't, still save the message to log.txt CON_LogMessage(va("%s\n", text)); -#else - (void)playsound; - CONS_Printf("%s\n", text); -#endif } -#ifndef NONET - /** Runs a say command, sending an ::XD_SAY message. * A say command consists of a signed 8-bit integer for the target, an * unsigned 8-bit flag variable, and then the message itself. @@ -865,8 +851,6 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) #endif } -#endif - // // void HU_Ticker(void) @@ -882,7 +866,6 @@ void HU_Ticker(void) else hu_showscores = false; -#ifndef NONET if (chat_on) { // count down the scroll timer. @@ -910,7 +893,6 @@ void HU_Ticker(void) HU_removeChatText_Mini(); } } -#endif if (cechotimer > 0) --cechotimer; @@ -918,8 +900,6 @@ void HU_Ticker(void) resynch_ticker++; } -#ifndef NONET - static boolean teamtalk = false; static boolean justscrolleddown; static boolean justscrolledup; @@ -1027,8 +1007,6 @@ static void HU_sendChatMessage(void) } } -#endif - void HU_clearChatChars(void) { memset(w_chat, '\0', sizeof(w_chat)); @@ -1043,9 +1021,7 @@ void HU_clearChatChars(void) // boolean HU_Responder(event_t *ev) { -#ifndef NONET INT32 c=0; -#endif if (ev->type != ev_keydown) return false; @@ -1072,7 +1048,6 @@ boolean HU_Responder(event_t *ev) return false; }*/ //We don't actually care about that unless we get splitscreen netgames. :V -#ifndef NONET c = (INT32)ev->key; if (!chat_on) @@ -1222,7 +1197,6 @@ boolean HU_Responder(event_t *ev) return true; } -#endif return false; } @@ -1232,8 +1206,6 @@ boolean HU_Responder(event_t *ev) // HEADS UP DRAWING //====================================================================== -#ifndef NONET - // Precompile a wordwrapped string to any given width. // This is a muuuch better method than V_WORDWRAP. // again stolen and modified a bit from video.c, don't mind me, will need to rearrange this one day. @@ -1813,7 +1785,6 @@ static void HU_DrawChat_Old(void) if (hu_tick < 4) V_DrawCharacter(HU_INPUTX + c, y, '_' | cv_constextsize.value |V_NOSCALESTART|t, true); } -#endif // Draw crosshairs at the exact center of the view. // In splitscreen, crosshairs are stretched vertically to compensate for V_PERPLAYER squishing them. @@ -1953,7 +1924,6 @@ static void HU_DrawDemoInfo(void) // void HU_Drawer(void) { -#ifndef NONET // draw chat string plus cursor if (chat_on) { @@ -1970,7 +1940,6 @@ void HU_Drawer(void) if (!OLDCHAT && cv_consolechat.value < 2 && netgame) // Don't display minimized chat if you set the mode to Window (Hidden) HU_drawMiniChat(); // draw messages in a cool fashion. } -#endif if (cechotimer) HU_DrawCEcho(); diff --git a/src/i_tcp.c b/src/i_tcp.c index 00aebddd3..ec3d1ae93 100644 --- a/src/i_tcp.c +++ b/src/i_tcp.c @@ -38,96 +38,87 @@ #include "doomdef.h" -#if defined (NOMD5) && !defined (NONET) - //#define NONET +#ifdef USE_WINSOCK1 + #include +#else + #ifndef USE_WINSOCK + #include + #ifdef __APPLE_CC__ + #ifndef _BSD_SOCKLEN_T_ + #define _BSD_SOCKLEN_T_ + #endif //_BSD_SOCKLEN_T_ + #endif //__APPLE_CC__ + #include + #include + #include + #include + #endif //normal BSD API + + #include + #include + + #if defined (__unix__) || defined (__APPLE__) || defined (UNIXCOMMON) + #include + #endif // UNIXCOMMON #endif -#ifdef NONET - #undef HAVE_MINIUPNPC -#else - #ifdef USE_WINSOCK1 - #include - #else - #ifndef USE_WINSOCK - #include - #ifdef __APPLE_CC__ - #ifndef _BSD_SOCKLEN_T_ - #define _BSD_SOCKLEN_T_ - #endif //_BSD_SOCKLEN_T_ - #endif //__APPLE_CC__ - #include - #include - #include - #include - #endif //normal BSD API - - #include - #include - - #if defined (__unix__) || defined (__APPLE__) || defined (UNIXCOMMON) - #include - #endif // UNIXCOMMON +#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 - - #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 - - typedef union - { - struct sockaddr any; - struct sockaddr_in ip4; - #ifdef HAVE_IPV6 - struct sockaddr_in6 ip6; + #define EWOULDBLOCK WSAEWOULDBLOCK + #ifdef EMSGSIZE + #undef EMSGSIZE #endif - } mysockaddr_t; + #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 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 +typedef union +{ + struct sockaddr any; + struct sockaddr_in ip4; +#ifdef HAVE_IPV6 + struct sockaddr_in6 ip6; +#endif +} mysockaddr_t; -#endif // !NONET +#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 #define MAXBANS 100 @@ -151,7 +142,7 @@ #define SELECTTEST #define DEFAULTPORT "5029" -#if defined (USE_WINSOCK) && !defined (NONET) +#ifdef USE_WINSOCK typedef SOCKET SOCKET_TYPE; #define ERRSOCKET (SOCKET_ERROR) #else @@ -163,22 +154,20 @@ #define ERRSOCKET (-1) #endif -#ifndef NONET - // define socklen_t in DOS/Windows if it is not already defined - #ifdef 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]; +// define socklen_t in DOS/Windows if it is not already defined +#ifdef 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]; static size_t numbans = 0; static boolean SOCK_bannednode[MAXNETNODES+1]; /// \note do we really need the +1? @@ -187,7 +176,6 @@ static boolean init_tcp_driver = false; static const char *serverport_name = DEFAULTPORT; static const char *clientport_name;/* any port */ -#ifndef NONET #ifdef USE_WINSOCK // stupid microsoft makes things complicated static char *get_WSAErrorStr(int e) @@ -374,47 +362,33 @@ static const char *SOCK_AddrToStr(mysockaddr_t *sk) #endif return s; } -#endif static const char *SOCK_GetNodeAddress(INT32 node) { if (node == 0) return "self"; -#ifdef NONET - return NULL; -#else if (!nodeconnected[node]) return NULL; return SOCK_AddrToStr(&clientaddress[node]); -#endif } static const char *SOCK_GetBanAddress(size_t ban) { if (ban >= numbans) return NULL; -#ifdef NONET - return NULL; -#else return SOCK_AddrToStr(&banned[ban]); -#endif } static const char *SOCK_GetBanMask(size_t ban) { -#ifdef NONET - (void)ban; -#else static char s[16]; //255.255.255.255 netmask? no, just CDIR for only if (ban >= numbans) return NULL; if (sprintf(s,"%d",bannedmask[ban]) > 0) return s; -#endif return NULL; } -#ifndef NONET static boolean SOCK_cmpaddr(mysockaddr_t *a, mysockaddr_t *b, UINT8 mask) { UINT32 bitmask = INADDR_NONE; @@ -518,9 +492,7 @@ void Command_Numnodes(void) connected, ingame); } #endif -#endif -#ifndef NONET // Returns true if a packet was received from a new node, false in all other cases static boolean SOCK_Get(void) { @@ -583,10 +555,8 @@ static boolean SOCK_Get(void) doomcom->remotenode = -1; // no packet return false; } -#endif // check if we can send (do not go over the buffer) -#ifndef NONET static fd_set masterset; @@ -636,9 +606,7 @@ static boolean SOCK_CanGet(void) return false; } #endif -#endif -#ifndef NONET static inline ssize_t SOCK_SendToAddr(SOCKET_TYPE socket, mysockaddr_t *sockaddr) { socklen_t d4 = (socklen_t)sizeof(struct sockaddr_in); @@ -701,9 +669,7 @@ static void SOCK_Send(void) SOCK_GetNodeAddress(doomcom->remotenode), e, strerror(e)); } } -#endif -#ifndef NONET static void SOCK_FreeNodenum(INT32 numnode) { // can't disconnect from self :) @@ -718,12 +684,10 @@ static void SOCK_FreeNodenum(INT32 numnode) // put invalid address memset(&clientaddress[numnode], 0, sizeof (clientaddress[numnode])); } -#endif // // UDPsocket // -#ifndef NONET // allocate a socket static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen) @@ -1044,12 +1008,10 @@ static boolean UDP_Socket(void) return true; } -#endif boolean I_InitTcpDriver(void) { boolean tcp_was_up = init_tcp_driver; -#ifndef NONET if (!init_tcp_driver) { #ifdef USE_WINSOCK @@ -1104,7 +1066,7 @@ boolean I_InitTcpDriver(void) #endif init_tcp_driver = true; } -#endif + if (!tcp_was_up && init_tcp_driver) { I_AddExitFunc(I_ShutdownTcpDriver); @@ -1118,7 +1080,6 @@ boolean I_InitTcpDriver(void) return init_tcp_driver; } -#ifndef NONET static void SOCK_CloseSocket(void) { size_t i; @@ -1133,11 +1094,9 @@ static void SOCK_CloseSocket(void) mysockets[i] = ERRSOCKET; } } -#endif void I_ShutdownTcpDriver(void) { -#ifndef NONET SOCK_CloseSocket(); CONS_Printf("I_ShutdownTcpDriver: "); @@ -1147,10 +1106,8 @@ void I_ShutdownTcpDriver(void) #endif CONS_Printf("shut down\n"); init_tcp_driver = false; -#endif } -#ifndef NONET static SINT8 SOCK_NetMakeNodewPort(const char *address, const char *port) { SINT8 newnode = -1; @@ -1194,11 +1151,9 @@ static SINT8 SOCK_NetMakeNodewPort(const char *address, const char *port) I_freeaddrinfo(ai); return newnode; } -#endif static boolean SOCK_OpenSocket(void) { -#ifndef NONET size_t i; memset(clientaddress, 0, sizeof (clientaddress)); @@ -1222,18 +1177,12 @@ static boolean SOCK_OpenSocket(void) // build the socket but close it first SOCK_CloseSocket(); return UDP_Socket(); -#else - return false; -#endif } static boolean SOCK_Ban(INT32 node) { if (node > MAXNETNODES) return false; -#ifdef NONET - return false; -#else if (numbans == MAXBANS) return false; @@ -1252,16 +1201,10 @@ static boolean SOCK_Ban(INT32 node) #endif numbans++; return true; -#endif } static boolean SOCK_SetBanAddress(const char *address, const char *mask) { -#ifdef NONET - (void)address; - (void)mask; - return false; -#else struct my_addrinfo *ai, *runp, hints; int gaie; @@ -1306,7 +1249,6 @@ static boolean SOCK_SetBanAddress(const char *address, const char *mask) I_freeaddrinfo(ai); return true; -#endif } static void SOCK_ClearBans(void) diff --git a/src/m_menu.c b/src/m_menu.c index 21ba98dd2..3e1d30feb 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -149,9 +149,7 @@ levellist_mode_t levellistmode = LLM_CREATESERVER; UINT8 maplistoption = 0; static char joystickInfo[MAX_JOYSTICKS+1][29]; -#ifndef NONET static UINT32 serverlistpage; -#endif static UINT8 numsaves = 0; static saveinfo_t* savegameinfo = NULL; // Extra info about the save games. @@ -190,10 +188,8 @@ static void M_GoBack(INT32 choice); static void M_StopMessage(INT32 choice); static boolean stopstopmessage = false; -#ifndef NONET static void M_HandleServerPage(INT32 choice); static void M_RoomMenu(INT32 choice); -#endif // Prototyping is fun, innit? // ========================================================================== @@ -296,7 +292,6 @@ static void M_SetupMultiPlayer2(INT32 choice); static void M_StartSplitServerMenu(INT32 choice); static void M_StartServer(INT32 choice); static void M_ServerOptions(INT32 choice); -#ifndef NONET static void M_StartServerMenu(INT32 choice); static void M_ConnectMenu(INT32 choice); static void M_ConnectMenuModChecks(INT32 choice); @@ -304,7 +299,6 @@ static void M_Refresh(INT32 choice); static void M_Connect(INT32 choice); static void M_ChooseRoom(INT32 choice); menu_t MP_MainDef; -#endif // Options // Split into multiple parts due to size @@ -382,11 +376,9 @@ static void M_DrawVideoMode(void); static void M_DrawColorMenu(void); static void M_DrawScreenshotMenu(void); static void M_DrawMonitorToggles(void); -#ifndef NONET static void M_DrawConnectMenu(void); static void M_DrawMPMainMenu(void); static void M_DrawRoomMenu(void); -#endif static void M_DrawJoystick(void); static void M_DrawSetupMultiPlayerMenu(void); static void M_DrawColorRamp(INT32 x, INT32 y, INT32 w, INT32 h, skincolor_t color); @@ -401,10 +393,8 @@ static void M_HandleImageDef(INT32 choice); static void M_HandleLoadSave(INT32 choice); static void M_HandleLevelStats(INT32 choice); static void M_HandlePlaystyleMenu(INT32 choice); -#ifndef NONET static boolean M_CancelConnect(void); static void M_HandleConnectIP(INT32 choice); -#endif static void M_HandleSetupMultiPlayer(INT32 choice); static void M_HandleVideoMode(INT32 choice); @@ -503,11 +493,7 @@ consvar_t cv_dummyloadless = CVAR_INIT ("dummyloadless", "In-game", CV_HIDEN, lo static menuitem_t MainMenu[] = { {IT_STRING|IT_CALL, NULL, "1 Player", M_SinglePlayerMenu, 76}, -#ifndef NONET {IT_STRING|IT_SUBMENU, NULL, "Multiplayer", &MP_MainDef, 84}, -#else - {IT_STRING|IT_CALL, NULL, "Multiplayer", M_StartSplitServerMenu, 84}, -#endif {IT_STRING|IT_CALL, NULL, "Extras", M_SecretsMenu, 92}, {IT_CALL |IT_STRING, NULL, "Addons", M_Addons, 100}, {IT_STRING|IT_CALL, NULL, "Options", M_Options, 108}, @@ -930,16 +916,10 @@ static menuitem_t SP_PlayerMenu[] = static menuitem_t MP_SplitServerMenu[] = { {IT_STRING|IT_CALL, NULL, "Select Gametype/Level...", M_MapChange, 100}, -#ifdef NONET // In order to keep player setup accessible. - {IT_STRING|IT_CALL, NULL, "Player 1 setup...", M_SetupMultiPlayer, 110}, - {IT_STRING|IT_CALL, NULL, "Player 2 setup...", M_SetupMultiPlayer2, 120}, -#endif {IT_STRING|IT_CALL, NULL, "More Options...", M_ServerOptions, 130}, {IT_WHITESTRING|IT_CALL, NULL, "Start", M_StartServer, 140}, }; -#ifndef NONET - static menuitem_t MP_MainMenu[] = { {IT_HEADER, NULL, "Join a game", NULL, 0}, @@ -1026,8 +1006,6 @@ menuitem_t MP_RoomMenu[] = {IT_DISABLED, NULL, "", M_ChooseRoom, 162}, }; -#endif - static menuitem_t MP_PlayerSetupMenu[] = { {IT_KEYHANDLER, NULL, "", M_HandleSetupMultiPlayer, 0}, // name @@ -1586,14 +1564,12 @@ enum static menuitem_t OP_ServerOptionsMenu[] = { {IT_HEADER, NULL, "General", NULL, 0}, -#ifndef NONET {IT_STRING | IT_CVAR | IT_CV_STRING, NULL, "Server name", &cv_servername, 7}, {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, 41}, {IT_STRING | IT_CVAR, NULL, "Intermission Timer", &cv_inttime, 46}, @@ -1632,7 +1608,6 @@ static menuitem_t OP_ServerOptionsMenu[] = {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, 230}, {IT_STRING | IT_CVAR | IT_CV_STRING, NULL, "Master server", &cv_masterserver, 236}, @@ -1640,7 +1615,6 @@ static menuitem_t OP_ServerOptionsMenu[] = {IT_STRING | IT_CVAR, NULL, "Attempts to resynchronise", &cv_resynchattempts, 256}, {IT_STRING | IT_CVAR, NULL, "Show IP Address of Joiners", &cv_showjoinaddress, 261}, -#endif }; static menuitem_t OP_MonitorToggleMenu[] = @@ -1954,11 +1928,7 @@ menu_t MP_SplitServerDef = MTREE2(MN_MP_MAIN, MN_MP_SPLITSCREEN), "M_MULTI", sizeof (MP_SplitServerMenu)/sizeof (menuitem_t), -#ifndef NONET &MP_MainDef, -#else - &MainDef, -#endif MP_SplitServerMenu, M_DrawServerMenu, 27, 30 - 50, @@ -1966,8 +1936,6 @@ menu_t MP_SplitServerDef = NULL }; -#ifndef NONET - menu_t MP_MainDef = { MN_MP_MAIN, @@ -2019,15 +1987,10 @@ menu_t MP_RoomDef = 0, NULL }; -#endif menu_t MP_PlayerSetupDef = { -#ifdef NONET - MTREE2(MN_MP_MAIN, MN_MP_PLAYERSETUP), -#else MTREE3(MN_MP_MAIN, MN_MP_SPLITSCREEN, MN_MP_PLAYERSETUP), -#endif "M_SPLAYR", sizeof (MP_PlayerSetupMenu)/sizeof (menuitem_t), &MainDef, // doesn't matter @@ -3956,9 +3919,7 @@ void M_Init(void) OP_JoystickSetMenu[i].itemaction = M_AssignJoystick; } -#ifndef NONET CV_RegisterVar(&cv_serversort); -#endif } void M_InitCharacterTables(void) @@ -11110,7 +11071,6 @@ static void M_EndGame(INT32 choice) #define S_LINEY(n) currentMenu->y + SERVERHEADERHEIGHT + (n * SERVERLINEHEIGHT) -#ifndef NONET static UINT32 localservercount; static void M_HandleServerPage(INT32 choice) @@ -11382,11 +11342,9 @@ static int ServerListEntryComparator_modified(const void *entry1, const void *en // Default to strcmp. return strcmp(sa->info.servername, sb->info.servername); } -#endif void M_SortServerList(void) { -#ifndef NONET switch(cv_serversort.value) { case 0: // Ping. @@ -11408,10 +11366,8 @@ void M_SortServerList(void) qsort(serverlist, serverlistcount, sizeof(serverelem_t), ServerListEntryComparator_gametypename); break; } -#endif } -#ifndef NONET #ifdef UPDATE_ALERT static boolean M_CheckMODVersion(int id) { @@ -11610,7 +11566,6 @@ static void M_ChooseRoom(INT32 choice) if (currentMenu == &MP_ConnectDef) M_Refresh(0); } -#endif //NONET //=========================================================================== // Start Server Menu @@ -11658,7 +11613,6 @@ static void M_DrawServerMenu(void) { M_DrawGenericMenu(); -#ifndef NONET // Room name if (currentMenu == &MP_ServerDef) { @@ -11670,15 +11624,10 @@ static void M_DrawServerMenu(void) V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + MP_ServerMenu[mp_server_room].alphaKey, V_YELLOWMAP, room_list[menuRoomIndex].name); } -#endif if (cv_nextmap.value) { -#ifndef NONET #define imgheight MP_ServerMenu[mp_server_levelgt].alphaKey -#else -#define imgheight 100 -#endif patch_t *PictureOfLevel; lumpnum_t lumpnum; char headerstr[40]; @@ -11730,7 +11679,6 @@ static void M_ServerOptions(INT32 choice) { (void)choice; -#ifndef NONET if ((splitscreen && !netgame) || currentMenu == &MP_SplitServerDef) { OP_ServerOptionsMenu[ 1].status = IT_GRAYEDOUT; // Server name @@ -11751,7 +11699,6 @@ static void M_ServerOptions(INT32 choice) OP_ServerOptionsMenu[37].status = IT_STRING | IT_CVAR; OP_ServerOptionsMenu[38].status = IT_STRING | IT_CVAR; } -#endif /* Disable fading because of different menu head. */ if (currentMenu == &OP_MainDef)/* from Options menu */ @@ -11763,7 +11710,6 @@ static void M_ServerOptions(INT32 choice) M_SetupNextMenu(&OP_ServerOptionsDef); } -#ifndef NONET static void M_StartServerMenu(INT32 choice) { (void)choice; @@ -12030,7 +11976,6 @@ static void M_HandleConnectIP(INT32 choice) M_ClearMenus(true); } } -#endif //!NONET // ======================== // MULTIPLAYER PLAYER SETUP @@ -12544,7 +12489,7 @@ static void M_SetupMultiPlayer2(INT32 choice) multi_frame = 0; multi_tics = 4*FRACUNIT; - + strcpy (setupm_name, cv_playername2.string); // set for splitscreen secondary player diff --git a/src/m_menu.h b/src/m_menu.h index c925c7f49..e91b91013 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -74,7 +74,7 @@ typedef enum MN_MP_SERVER, MN_MP_CONNECT, MN_MP_ROOM, - MN_MP_PLAYERSETUP, // MP_PlayerSetupDef shared with SPLITSCREEN if #defined NONET + MN_MP_PLAYERSETUP, MN_MP_SERVER_OPTIONS, // Options diff --git a/src/mserv.c b/src/mserv.c index bff562c95..90091d241 100644 --- a/src/mserv.c +++ b/src/mserv.c @@ -45,9 +45,7 @@ static I_cond MSCond; # define Unlock_state() #endif/*HAVE_THREADS*/ -#ifndef NONET static void Command_Listserv_f(void); -#endif #endif/*MASTERSERVER*/ @@ -89,7 +87,6 @@ msg_rooms_t room_list[NUM_LIST_ROOMS+1]; // +1 for easy test */ void AddMServCommands(void) { -#ifndef NONET CV_RegisterVar(&cv_masterserver); CV_RegisterVar(&cv_masterserver_update_rate); CV_RegisterVar(&cv_masterserver_timeout); @@ -100,7 +97,6 @@ void AddMServCommands(void) COM_AddCommand("listserv", Command_Listserv_f); COM_AddCommand("masterserver_update", Update_parameters); // allows people to updates manually in case you were delisted by accident #endif -#endif } #ifdef MASTERSERVER @@ -189,7 +185,6 @@ void GetMODVersion_Console(void) } #endif -#ifndef NONET /** Gets a list of game servers. Called from console. */ static void Command_Listserv_f(void) @@ -200,7 +195,6 @@ static void Command_Listserv_f(void) HMS_list_servers(); } } -#endif static void Finish_registration (void) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index c21226ac3..ba4dd7985 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -2389,9 +2389,7 @@ void I_Quit(void) SDLforceUngrabMouse(); quiting = SDL_FALSE; M_SaveConfig(NULL); //save game config, cvars.. -#ifndef NONET D_SaveBan(); // save the ban list -#endif G_SaveGameData(clientGamedata); // Tails 12-08-2002 //added:16-02-98: when recording a demo, should exit using 'q' key, // but sometimes we forget and use 'F10'.. so save here too. @@ -2506,9 +2504,7 @@ void I_Error(const char *error, ...) // --- M_SaveConfig(NULL); // save game config, cvars.. -#ifndef NONET D_SaveBan(); // save the ban list -#endif G_SaveGameData(clientGamedata); // Tails 12-08-2002 // Shutdown. Here might be other errors. From 0b17e3c4180d5d8e6f8002c2a3cadfeaf7b25aff Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sat, 31 Dec 2022 14:10:19 +0100 Subject: [PATCH 331/586] Move netcode files to a new folder --- src/Makefile | 1 + src/Sourcefile | 7 ---- src/android/i_net.c | 2 +- src/blua/liolib.c | 2 +- src/command.c | 4 +- src/d_main.c | 6 +-- src/deh_soc.c | 2 +- src/deh_soc.h | 2 +- src/doomstat.h | 2 +- src/dummy/i_net.c | 2 +- src/f_finale.c | 2 +- src/filesrch.c | 2 +- src/filesrch.h | 2 +- src/g_demo.c | 2 +- src/g_game.c | 2 +- src/g_input.c | 2 +- src/hardware/hw_main.c | 2 +- src/hu_stuff.c | 2 +- src/i_time.c | 2 +- src/lua_baselib.c | 4 +- src/lua_hooklib.c | 2 +- src/lua_script.c | 2 +- src/m_cheat.c | 2 +- src/m_menu.c | 6 +-- src/m_menu.h | 2 +- src/m_perfstats.c | 2 +- src/netcode/Sourcefile | 7 ++++ src/{ => netcode}/d_clisrv.c | 68 +++++++++++++++++----------------- src/{ => netcode}/d_clisrv.h | 6 +-- src/{ => netcode}/d_net.c | 16 ++++---- src/{ => netcode}/d_net.h | 0 src/{ => netcode}/d_netcmd.c | 66 ++++++++++++++++----------------- src/{ => netcode}/d_netcmd.h | 2 +- src/{ => netcode}/d_netfil.c | 30 +++++++-------- src/{ => netcode}/d_netfil.h | 2 +- src/{ => netcode}/http-mserv.c | 10 ++--- src/{ => netcode}/i_addrinfo.c | 0 src/{ => netcode}/i_addrinfo.h | 0 src/{ => netcode}/i_net.h | 4 +- src/{ => netcode}/i_tcp.c | 8 ++-- src/{ => netcode}/i_tcp.h | 0 src/{ => netcode}/mserv.c | 12 +++--- src/{ => netcode}/mserv.h | 2 +- src/p_ceilng.c | 2 +- src/p_lights.c | 2 +- src/p_user.c | 2 +- src/r_segs.c | 2 +- src/r_things.c | 2 +- src/screen.c | 2 +- src/sdl/i_net.c | 6 +-- src/sdl/i_system.c | 4 +- src/sdl/i_ttf.c | 2 +- src/w_wad.c | 4 +- src/y_inter.c | 2 +- 54 files changed, 166 insertions(+), 165 deletions(-) create mode 100644 src/netcode/Sourcefile rename src/{ => netcode}/d_clisrv.c (99%) mode change 100755 => 100644 rename src/{ => netcode}/d_clisrv.h (99%) rename src/{ => netcode}/d_net.c (99%) rename src/{ => netcode}/d_net.h (100%) rename src/{ => netcode}/d_netcmd.c (99%) rename src/{ => netcode}/d_netcmd.h (99%) rename src/{ => netcode}/d_netfil.c (99%) rename src/{ => netcode}/d_netfil.h (99%) rename src/{ => netcode}/http-mserv.c (98%) rename src/{ => netcode}/i_addrinfo.c (100%) rename src/{ => netcode}/i_addrinfo.h (100%) rename src/{ => netcode}/i_net.h (98%) rename src/{ => netcode}/i_tcp.c (99%) rename src/{ => netcode}/i_tcp.h (100%) rename src/{ => netcode}/mserv.c (98%) rename src/{ => netcode}/mserv.h (99%) diff --git a/src/Makefile b/src/Makefile index 7fe7f8990..1968e995b 100644 --- a/src/Makefile +++ b/src/Makefile @@ -207,6 +207,7 @@ objdir:=$(makedir)/objs sources+=\ $(call List,Sourcefile)\ $(call List,blua/Sourcefile)\ + $(call List,netcode/Sourcefile)\ depends:=$(basename $(filter %.c %.s,$(sources))) objects:=$(basename $(filter %.c %.s %.nas,$(sources))) diff --git a/src/Sourcefile b/src/Sourcefile index c55752b09..004673367 100644 --- a/src/Sourcefile +++ b/src/Sourcefile @@ -1,9 +1,5 @@ string.c d_main.c -d_clisrv.c -d_net.c -d_netfil.c -d_netcmd.c dehacked.c deh_soc.c deh_lua.c @@ -77,9 +73,6 @@ 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 diff --git a/src/android/i_net.c b/src/android/i_net.c index f6e642022..4c30dc767 100644 --- a/src/android/i_net.c +++ b/src/android/i_net.c @@ -1,4 +1,4 @@ -#include "../i_net.h" +#include "../netcode/i_net.h" boolean I_InitNetwork(void) { diff --git a/src/blua/liolib.c b/src/blua/liolib.c index 545f9c144..00e31e965 100644 --- a/src/blua/liolib.c +++ b/src/blua/liolib.c @@ -19,7 +19,7 @@ #include "lualib.h" #include "../i_system.h" #include "../g_game.h" -#include "../d_netfil.h" +#include "../netcode/d_netfil.h" #include "../lua_libs.h" #include "../byteptr.h" #include "../lua_script.h" diff --git a/src/command.c b/src/command.c index e1a43522d..0256365f3 100644 --- a/src/command.c +++ b/src/command.c @@ -28,11 +28,11 @@ #include "byteptr.h" #include "p_saveg.h" #include "g_game.h" // for player_names -#include "d_netcmd.h" +#include "netcode/d_netcmd.h" #include "hu_stuff.h" #include "p_setup.h" #include "lua_script.h" -#include "d_netfil.h" // findfile +#include "netcode/d_netfil.h" // findfile #include "r_data.h" // Color_cons_t #include "d_main.h" // D_IsPathAllowed diff --git a/src/d_main.c b/src/d_main.c index b7b7f6616..a4238c8b1 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -34,7 +34,7 @@ #include "doomdef.h" #include "am_map.h" #include "console.h" -#include "d_net.h" +#include "netcode/d_net.h" #include "f_finale.h" #include "g_game.h" #include "hu_stuff.h" @@ -56,11 +56,11 @@ #include "w_wad.h" #include "z_zone.h" #include "d_main.h" -#include "d_netfil.h" +#include "netcode/d_netfil.h" #include "m_cheat.h" #include "y_inter.h" #include "p_local.h" // chasecam -#include "mserv.h" // ms_RoomId +#include "netcode/mserv.h" // ms_RoomId #include "m_misc.h" // screenshot functionality #include "deh_tables.h" // Dehacked list test #include "m_cond.h" // condition initialization diff --git a/src/deh_soc.c b/src/deh_soc.c index 2193cd875..59eb0a9bd 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -34,7 +34,7 @@ #include "r_sky.h" #include "fastcmp.h" #include "lua_script.h" // Reluctantly included for LUA_EvalMath -#include "d_clisrv.h" +#include "netcode/d_clisrv.h" #ifdef HWRENDER #include "hardware/hw_light.h" diff --git a/src/deh_soc.h b/src/deh_soc.h index 0cab545f6..029390133 100644 --- a/src/deh_soc.h +++ b/src/deh_soc.h @@ -35,7 +35,7 @@ #include "r_sky.h" #include "fastcmp.h" #include "lua_script.h" // Reluctantly included for LUA_EvalMath -#include "d_clisrv.h" +#include "netcode/d_clisrv.h" #ifdef HWRENDER #include "hardware/hw_light.h" diff --git a/src/doomstat.h b/src/doomstat.h index a812cc304..27889726e 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -633,7 +633,7 @@ extern boolean singletics; // Netgame stuff // ============= -#include "d_clisrv.h" +#include "netcode/d_clisrv.h" extern consvar_t cv_timetic; // display high resolution timer extern consvar_t cv_powerupdisplay; // display powerups diff --git a/src/dummy/i_net.c b/src/dummy/i_net.c index f6e642022..4c30dc767 100644 --- a/src/dummy/i_net.c +++ b/src/dummy/i_net.c @@ -1,4 +1,4 @@ -#include "../i_net.h" +#include "../netcode/i_net.h" boolean I_InitNetwork(void) { diff --git a/src/f_finale.c b/src/f_finale.c index d03795dc4..82c2a4f96 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -14,7 +14,7 @@ #include "doomdef.h" #include "doomstat.h" #include "d_main.h" -#include "d_netcmd.h" +#include "netcode/d_netcmd.h" #include "f_finale.h" #include "g_game.h" #include "hu_stuff.h" diff --git a/src/filesrch.c b/src/filesrch.c index 9ee64f5ba..313f286e1 100644 --- a/src/filesrch.c +++ b/src/filesrch.c @@ -26,7 +26,7 @@ #include #include "filesrch.h" -#include "d_netfil.h" +#include "netcode/d_netfil.h" #include "m_misc.h" #include "z_zone.h" #include "m_menu.h" // Addons_option_Onchange diff --git a/src/filesrch.h b/src/filesrch.h index 59ef5269b..a934c48d6 100644 --- a/src/filesrch.h +++ b/src/filesrch.h @@ -5,7 +5,7 @@ #define __FILESRCH_H__ #include "doomdef.h" -#include "d_netfil.h" +#include "netcode/d_netfil.h" #include "m_menu.h" // MAXSTRINGLENGTH #include "w_wad.h" diff --git a/src/g_demo.c b/src/g_demo.c index adb8e891d..dea80e793 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -15,7 +15,7 @@ #include "console.h" #include "d_main.h" #include "d_player.h" -#include "d_clisrv.h" +#include "netcode/d_clisrv.h" #include "p_setup.h" #include "i_time.h" #include "i_system.h" diff --git a/src/g_game.c b/src/g_game.c index b8c434998..f47aa2183 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -15,7 +15,7 @@ #include "console.h" #include "d_main.h" #include "d_player.h" -#include "d_clisrv.h" +#include "netcode/d_clisrv.h" #include "f_finale.h" #include "p_setup.h" #include "p_saveg.h" diff --git a/src/g_input.c b/src/g_input.c index 826dcecbd..fa30c1984 100644 --- a/src/g_input.c +++ b/src/g_input.c @@ -16,7 +16,7 @@ #include "g_input.h" #include "keys.h" #include "hu_stuff.h" // need HUFONT start & end -#include "d_net.h" +#include "netcode/d_net.h" #include "console.h" #define MAXMOUSESENSITIVITY 100 // sensitivity steps diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 36ff86abd..b14a168a1 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -29,7 +29,7 @@ #include "../r_patch.h" #include "../r_picformats.h" #include "../r_bsp.h" -#include "../d_clisrv.h" +#include "../netcode/d_clisrv.h" #include "../w_wad.h" #include "../z_zone.h" #include "../r_splats.h" diff --git a/src/hu_stuff.c b/src/hu_stuff.c index c423f2905..33ef8a404 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -19,7 +19,7 @@ #include "m_cond.h" // emblems #include "m_misc.h" // word jumping -#include "d_clisrv.h" +#include "netcode/d_clisrv.h" #include "g_game.h" #include "g_input.h" diff --git a/src/i_time.c b/src/i_time.c index 2a22503f1..fae26abed 100644 --- a/src/i_time.c +++ b/src/i_time.c @@ -17,7 +17,7 @@ #include "command.h" #include "doomtype.h" -#include "d_netcmd.h" +#include "netcode/d_netcmd.h" #include "m_fixed.h" #include "i_system.h" diff --git a/src/lua_baselib.c b/src/lua_baselib.c index bf3fd1dec..42e37e55e 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -26,11 +26,11 @@ #include "y_inter.h" #include "hu_stuff.h" // HU_AddChatText #include "console.h" -#include "d_netcmd.h" // IsPlayerAdmin +#include "netcode/d_netcmd.h" // IsPlayerAdmin #include "m_menu.h" // Player Setup menu color stuff #include "m_misc.h" // M_MapNumber #include "b_bot.h" // B_UpdateBotleader -#include "d_clisrv.h" // CL_RemovePlayer +#include "netcode/d_clisrv.h" // CL_RemovePlayer #include "i_system.h" // I_GetPreciseTime, I_GetPrecisePrecision #include "lua_script.h" diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 039a9677f..0fc25ee6c 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -24,7 +24,7 @@ #include "lua_hud.h" // hud_running errors #include "m_perfstats.h" -#include "d_netcmd.h" // for cv_perfstats +#include "netcode/d_netcmd.h" // for cv_perfstats #include "i_system.h" // I_GetPreciseTime /* ========================================================================= diff --git a/src/lua_script.c b/src/lua_script.c index a8263ea5f..ed5adbe3f 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -28,7 +28,7 @@ #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 +#include "netcode/d_netfil.h" // for LUA_DumpFile #endif #include "lua_script.h" diff --git a/src/m_cheat.c b/src/m_cheat.c index e370335f8..69b3b643c 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -19,7 +19,7 @@ #include "r_local.h" #include "p_local.h" #include "p_setup.h" -#include "d_net.h" +#include "netcode/d_net.h" #include "m_cheat.h" #include "m_menu.h" diff --git a/src/m_menu.c b/src/m_menu.c index 3e1d30feb..72e50de69 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -20,7 +20,7 @@ #include "doomdef.h" #include "d_main.h" -#include "d_netcmd.h" +#include "netcode/d_netcmd.h" #include "console.h" #include "r_fps.h" #include "r_local.h" @@ -53,8 +53,8 @@ #include "hardware/hw_main.h" #endif -#include "d_net.h" -#include "mserv.h" +#include "netcode/d_net.h" +#include "netcode/mserv.h" #include "m_misc.h" #include "m_anigif.h" #include "byteptr.h" diff --git a/src/m_menu.h b/src/m_menu.h index e91b91013..b8fe3b808 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -20,7 +20,7 @@ #include "command.h" #include "f_finale.h" // for ttmode_enum #include "i_threads.h" -#include "mserv.h" +#include "netcode/mserv.h" #include "r_things.h" // for SKINNAMESIZE // Compatibility with old-style named NiGHTS replay files. diff --git a/src/m_perfstats.c b/src/m_perfstats.c index 17e026b3e..151185932 100644 --- a/src/m_perfstats.c +++ b/src/m_perfstats.c @@ -12,7 +12,7 @@ #include "m_perfstats.h" #include "v_video.h" #include "i_video.h" -#include "d_netcmd.h" +#include "netcode/d_netcmd.h" #include "r_main.h" #include "i_system.h" #include "z_zone.h" diff --git a/src/netcode/Sourcefile b/src/netcode/Sourcefile new file mode 100644 index 000000000..9087917d0 --- /dev/null +++ b/src/netcode/Sourcefile @@ -0,0 +1,7 @@ +d_clisrv.c +d_net.c +d_netcmd.c +d_netfil.c +http-mserv.c +i_tcp.c +mserv.c diff --git a/src/d_clisrv.c b/src/netcode/d_clisrv.c old mode 100755 new mode 100644 similarity index 99% rename from src/d_clisrv.c rename to src/netcode/d_clisrv.c index cb1ccd539..9b11e23ff --- a/src/d_clisrv.c +++ b/src/netcode/d_clisrv.c @@ -15,48 +15,48 @@ #include //for unlink #endif -#include "i_time.h" +#include "../i_time.h" #include "i_net.h" -#include "i_system.h" -#include "i_video.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" -#include "i_gamepad.h" -#include "m_menu.h" -#include "console.h" +#include "../d_main.h" +#include "../g_game.h" +#include "../st_stuff.h" +#include "../hu_stuff.h" +#include "../keys.h" +#include "../g_input.h" +#include "../i_gamepad.h" +#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 "p_haptic.h" -#include "m_misc.h" -#include "am_map.h" -#include "m_random.h" +#include "../byteptr.h" +#include "../p_saveg.h" +#include "../z_zone.h" +#include "../p_local.h" +#include "../p_haptic.h" +#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 "lua_libs.h" -#include "md5.h" -#include "m_perfstats.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 "../lua_libs.h" +#include "../md5.h" +#include "../m_perfstats.h" // aaaaaa -#include "i_gamepad.h" +#include "../i_gamepad.h" // cl loading screen -#include "v_video.h" -#include "f_finale.h" -#include "snake.h" +#include "../v_video.h" +#include "../f_finale.h" +#include "../snake.h" // // NETWORKING diff --git a/src/d_clisrv.h b/src/netcode/d_clisrv.h similarity index 99% rename from src/d_clisrv.h rename to src/netcode/d_clisrv.h index 0d6add13a..50b86e9f0 100644 --- a/src/d_clisrv.h +++ b/src/netcode/d_clisrv.h @@ -13,12 +13,12 @@ #ifndef __D_CLISRV__ #define __D_CLISRV__ -#include "d_ticcmd.h" +#include "../d_ticcmd.h" #include "d_net.h" #include "d_netcmd.h" #include "d_net.h" -#include "tables.h" -#include "d_player.h" +#include "../tables.h" +#include "../d_player.h" #include "mserv.h" /* diff --git a/src/d_net.c b/src/netcode/d_net.c similarity index 99% rename from src/d_net.c rename to src/netcode/d_net.c index 9e3759d32..ae0605001 100644 --- a/src/d_net.c +++ b/src/netcode/d_net.c @@ -16,19 +16,19 @@ /// This protocol uses a mix of "goback n" and "selective repeat" implementation /// The NOTHING packet is sent when connection is idle to acknowledge packets -#include "doomdef.h" -#include "g_game.h" -#include "i_time.h" +#include "../doomdef.h" +#include "../g_game.h" +#include "../i_time.h" #include "i_net.h" -#include "i_system.h" -#include "m_argv.h" +#include "../i_system.h" +#include "../m_argv.h" #include "d_net.h" -#include "w_wad.h" +#include "../w_wad.h" #include "d_netfil.h" #include "d_clisrv.h" -#include "z_zone.h" +#include "../z_zone.h" #include "i_tcp.h" -#include "d_main.h" // srb2home +#include "../d_main.h" // srb2home // // NETWORKING diff --git a/src/d_net.h b/src/netcode/d_net.h similarity index 100% rename from src/d_net.h rename to src/netcode/d_net.h diff --git a/src/d_netcmd.c b/src/netcode/d_netcmd.c similarity index 99% rename from src/d_netcmd.c rename to src/netcode/d_netcmd.c index 69eed90de..ed310805d 100644 --- a/src/d_netcmd.c +++ b/src/netcode/d_netcmd.c @@ -12,44 +12,44 @@ /// commands are executed through the command buffer /// like console commands, other miscellaneous commands (at the end) -#include "doomdef.h" +#include "../doomdef.h" -#include "console.h" -#include "command.h" -#include "i_time.h" -#include "i_system.h" -#include "g_game.h" -#include "hu_stuff.h" -#include "g_input.h" -#include "i_gamepad.h" -#include "m_menu.h" -#include "r_local.h" -#include "r_skins.h" -#include "p_local.h" -#include "p_setup.h" -#include "s_sound.h" -#include "i_sound.h" -#include "m_misc.h" -#include "am_map.h" -#include "byteptr.h" +#include "../console.h" +#include "../command.h" +#include "../i_time.h" +#include "../i_system.h" +#include "../g_game.h" +#include "../hu_stuff.h" +#include "../g_input.h" +#include "../i_gamepad.h" +#include "../m_menu.h" +#include "../r_local.h" +#include "../r_skins.h" +#include "../p_local.h" +#include "../p_setup.h" +#include "../s_sound.h" +#include "../i_sound.h" +#include "../m_misc.h" +#include "../am_map.h" +#include "../byteptr.h" #include "d_netfil.h" -#include "p_spec.h" -#include "m_cheat.h" +#include "../p_spec.h" +#include "../m_cheat.h" #include "d_clisrv.h" #include "d_net.h" -#include "v_video.h" -#include "d_main.h" -#include "m_random.h" -#include "f_finale.h" -#include "filesrch.h" +#include "../v_video.h" +#include "../d_main.h" +#include "../m_random.h" +#include "../f_finale.h" +#include "../filesrch.h" #include "mserv.h" -#include "z_zone.h" -#include "lua_script.h" -#include "lua_hook.h" -#include "m_cond.h" -#include "m_anigif.h" -#include "md5.h" -#include "m_perfstats.h" +#include "../z_zone.h" +#include "../lua_script.h" +#include "../lua_hook.h" +#include "../m_cond.h" +#include "../m_anigif.h" +#include "../md5.h" +#include "../m_perfstats.h" #ifdef NETGAME_DEVMODE #define CV_RESTRICT CV_NETVAR diff --git a/src/d_netcmd.h b/src/netcode/d_netcmd.h similarity index 99% rename from src/d_netcmd.h rename to src/netcode/d_netcmd.h index 47f68a17e..797a686a7 100644 --- a/src/d_netcmd.h +++ b/src/netcode/d_netcmd.h @@ -15,7 +15,7 @@ #ifndef __D_NETCMD__ #define __D_NETCMD__ -#include "command.h" +#include "../command.h" // console vars extern consvar_t cv_playername; diff --git a/src/d_netfil.c b/src/netcode/d_netfil.c similarity index 99% rename from src/d_netfil.c rename to src/netcode/d_netfil.c index bf3952cc9..80fa06852 100644 --- a/src/d_netfil.c +++ b/src/netcode/d_netfil.c @@ -31,24 +31,24 @@ #include #endif -#include "doomdef.h" -#include "doomstat.h" -#include "d_main.h" -#include "g_game.h" -#include "i_time.h" +#include "../doomdef.h" +#include "../doomstat.h" +#include "../d_main.h" +#include "../g_game.h" +#include "../i_time.h" #include "i_net.h" -#include "i_system.h" -#include "m_argv.h" +#include "../i_system.h" +#include "../m_argv.h" #include "d_net.h" -#include "w_wad.h" +#include "../w_wad.h" #include "d_netfil.h" -#include "z_zone.h" -#include "byteptr.h" -#include "p_setup.h" -#include "m_misc.h" -#include "m_menu.h" -#include "md5.h" -#include "filesrch.h" +#include "../z_zone.h" +#include "../byteptr.h" +#include "../p_setup.h" +#include "../m_misc.h" +#include "../m_menu.h" +#include "../md5.h" +#include "../filesrch.h" #include diff --git a/src/d_netfil.h b/src/netcode/d_netfil.h similarity index 99% rename from src/d_netfil.h rename to src/netcode/d_netfil.h index ec53be587..732efcd5e 100644 --- a/src/d_netfil.h +++ b/src/netcode/d_netfil.h @@ -15,7 +15,7 @@ #include "d_net.h" #include "d_clisrv.h" -#include "w_wad.h" +#include "../w_wad.h" typedef enum { diff --git a/src/http-mserv.c b/src/netcode/http-mserv.c similarity index 98% rename from src/http-mserv.c rename to src/netcode/http-mserv.c index b0ef37fa1..72dc1cafb 100644 --- a/src/http-mserv.c +++ b/src/netcode/http-mserv.c @@ -18,14 +18,14 @@ Documentation available here. #include #endif -#include "doomdef.h" +#include "../doomdef.h" #include "d_clisrv.h" -#include "command.h" -#include "m_argv.h" -#include "m_menu.h" +#include "../command.h" +#include "../m_argv.h" +#include "../m_menu.h" #include "mserv.h" #include "i_tcp.h"/* for current_port */ -#include "i_threads.h" +#include "../i_threads.h" /* reasonable default I guess?? */ #define DEFAULT_BUFFER_SIZE (4096) diff --git a/src/i_addrinfo.c b/src/netcode/i_addrinfo.c similarity index 100% rename from src/i_addrinfo.c rename to src/netcode/i_addrinfo.c diff --git a/src/i_addrinfo.h b/src/netcode/i_addrinfo.h similarity index 100% rename from src/i_addrinfo.h rename to src/netcode/i_addrinfo.h diff --git a/src/i_net.h b/src/netcode/i_net.h similarity index 98% rename from src/i_net.h rename to src/netcode/i_net.h index 62b7528d5..66126d050 100644 --- a/src/i_net.h +++ b/src/netcode/i_net.h @@ -18,8 +18,8 @@ #pragma interface #endif -#include "doomdef.h" -#include "command.h" +#include "../doomdef.h" +#include "../command.h" /// \brief program net id #define DOOMCOM_ID (INT32)0x12345678l diff --git a/src/i_tcp.c b/src/netcode/i_tcp.c similarity index 99% rename from src/i_tcp.c rename to src/netcode/i_tcp.c index ec3d1ae93..6baba6275 100644 --- a/src/i_tcp.c +++ b/src/netcode/i_tcp.c @@ -36,7 +36,7 @@ #include #endif -#include "doomdef.h" +#include "../doomdef.h" #ifdef USE_WINSOCK1 #include @@ -122,14 +122,14 @@ typedef union #define MAXBANS 100 -#include "i_system.h" +#include "../i_system.h" #include "i_net.h" #include "d_net.h" #include "d_netfil.h" #include "i_tcp.h" -#include "m_argv.h" +#include "../m_argv.h" -#include "doomstat.h" +#include "../doomstat.h" // win32 #ifdef USE_WINSOCK diff --git a/src/i_tcp.h b/src/netcode/i_tcp.h similarity index 100% rename from src/i_tcp.h rename to src/netcode/i_tcp.h diff --git a/src/mserv.c b/src/netcode/mserv.c similarity index 98% rename from src/mserv.c rename to src/netcode/mserv.c index 90091d241..78301f4d9 100644 --- a/src/mserv.c +++ b/src/netcode/mserv.c @@ -15,13 +15,13 @@ #include #endif -#include "doomstat.h" -#include "doomdef.h" -#include "command.h" -#include "i_threads.h" +#include "../doomstat.h" +#include "../doomdef.h" +#include "../command.h" +#include "../i_threads.h" #include "mserv.h" -#include "m_menu.h" -#include "z_zone.h" +#include "../m_menu.h" +#include "../z_zone.h" #ifdef MASTERSERVER diff --git a/src/mserv.h b/src/netcode/mserv.h similarity index 99% rename from src/mserv.h rename to src/netcode/mserv.h index 23b26fbc5..7fdf3ed1b 100644 --- a/src/mserv.h +++ b/src/netcode/mserv.h @@ -14,7 +14,7 @@ #ifndef _MSERV_H_ #define _MSERV_H_ -#include "i_threads.h" +#include "../i_threads.h" // lowered from 32 due to menu changes #define NUM_LIST_ROOMS 16 diff --git a/src/p_ceilng.c b/src/p_ceilng.c index 98e931362..61430d73f 100644 --- a/src/p_ceilng.c +++ b/src/p_ceilng.c @@ -17,7 +17,7 @@ #include "r_main.h" #include "s_sound.h" #include "z_zone.h" -#include "d_netcmd.h" +#include "netcode/d_netcmd.h" // ========================================================================== // CEILINGS diff --git a/src/p_lights.c b/src/p_lights.c index 4b6a3673b..971165e88 100644 --- a/src/p_lights.c +++ b/src/p_lights.c @@ -17,7 +17,7 @@ #include "r_state.h" #include "z_zone.h" #include "m_random.h" -#include "d_netcmd.h" +#include "netcode/d_netcmd.h" /** Removes any active lighting effects in a sector. * diff --git a/src/p_user.c b/src/p_user.c index 1c2e4f7c9..6bbefcb19 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -17,7 +17,7 @@ #include "doomdef.h" #include "i_system.h" #include "d_event.h" -#include "d_net.h" +#include "netcode/d_net.h" #include "g_game.h" #include "p_local.h" #include "r_fps.h" diff --git a/src/r_segs.c b/src/r_segs.c index facab62ab..00ee4fd6d 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -20,7 +20,7 @@ #include "w_wad.h" #include "z_zone.h" -#include "d_netcmd.h" +#include "netcode/d_netcmd.h" #include "m_misc.h" #include "p_local.h" // Camera... #include "p_slopes.h" diff --git a/src/r_things.c b/src/r_things.c index 90b80dda8..642f3a8e2 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -34,7 +34,7 @@ #include "p_tick.h" #include "p_local.h" #include "p_slopes.h" -#include "d_netfil.h" // blargh. for nameonly(). +#include "netcode/d_netfil.h" // blargh. for nameonly(). #include "m_cheat.h" // objectplace #ifdef HWRENDER #include "hardware/hw_md2.h" diff --git a/src/screen.c b/src/screen.c index fe5b39995..05bbcfabb 100644 --- a/src/screen.c +++ b/src/screen.c @@ -27,7 +27,7 @@ #include "hu_stuff.h" #include "z_zone.h" #include "d_main.h" -#include "d_clisrv.h" +#include "netcode/d_clisrv.h" #include "f_finale.h" #include "y_inter.h" // usebuffer #include "i_sound.h" // closed captions diff --git a/src/sdl/i_net.c b/src/sdl/i_net.c index ee4a34c13..515a85568 100644 --- a/src/sdl/i_net.c +++ b/src/sdl/i_net.c @@ -21,16 +21,16 @@ #include "../i_system.h" #include "../d_event.h" -#include "../d_net.h" +#include "../netcode/d_net.h" #include "../m_argv.h" #include "../doomstat.h" -#include "../i_net.h" +#include "../netcode/i_net.h" #include "../z_zone.h" -#include "../i_tcp.h" +#include "../netcode/i_tcp.h" #ifdef HAVE_SDL diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index ba4dd7985..50ceae34c 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -193,7 +193,7 @@ static char returnWadPath[256]; #include "../i_system.h" #include "../i_threads.h" #include "../screen.h" //vid.WndParent -#include "../d_net.h" +#include "../netcode/d_net.h" #include "../g_game.h" #include "../filesrch.h" #include "endtxt.h" @@ -214,7 +214,7 @@ static char returnWadPath[256]; #if !defined(NOMUMBLE) && defined(HAVE_MUMBLE) // Mumble context string -#include "../d_clisrv.h" +#include "../netcode/d_clisrv.h" #include "../byteptr.h" #endif diff --git a/src/sdl/i_ttf.c b/src/sdl/i_ttf.c index f2cd497ee..1f838e9b4 100644 --- a/src/sdl/i_ttf.c +++ b/src/sdl/i_ttf.c @@ -21,7 +21,7 @@ #include "SDL_ttf.h" #include "../doomdef.h" #include "../doomstat.h" -#include "../d_netfil.h" +#include "../netcode/d_netfil.h" #include "../filesrch.h" #include "i_ttf.h" diff --git a/src/w_wad.c b/src/w_wad.c index 171eab4f3..23d84c336 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -51,8 +51,8 @@ #include "filesrch.h" #include "d_main.h" -#include "d_netfil.h" -#include "d_clisrv.h" +#include "netcode/d_netfil.h" +#include "netcode/d_clisrv.h" #include "dehacked.h" #include "r_defs.h" #include "r_data.h" diff --git a/src/y_inter.c b/src/y_inter.c index 1b1f49e0b..c8bd06d91 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -15,7 +15,7 @@ #include "f_finale.h" #include "g_game.h" #include "hu_stuff.h" -#include "i_net.h" +#include "netcode/i_net.h" #include "i_video.h" #include "p_tick.h" #include "r_defs.h" From e090f0e4006e329fc6faf7d66cb508fab7e6be5a Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sat, 31 Dec 2022 21:37:35 +0100 Subject: [PATCH 332/586] Move client connection handling to a new file --- src/m_menu.c | 1 + src/netcode/Sourcefile | 1 + src/netcode/client_connection.c | 1181 ++++++++++++++++++++++++++++++ src/netcode/client_connection.h | 61 ++ src/netcode/d_clisrv.c | 1184 +------------------------------ src/netcode/d_clisrv.h | 16 +- src/netcode/http-mserv.c | 1 + src/netcode/mserv.c | 1 + 8 files changed, 1256 insertions(+), 1190 deletions(-) create mode 100644 src/netcode/client_connection.c create mode 100644 src/netcode/client_connection.h diff --git a/src/m_menu.c b/src/m_menu.c index 72e50de69..f0691c17f 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -55,6 +55,7 @@ #include "netcode/d_net.h" #include "netcode/mserv.h" +#include "netcode/client_connection.h" #include "m_misc.h" #include "m_anigif.h" #include "byteptr.h" diff --git a/src/netcode/Sourcefile b/src/netcode/Sourcefile index 9087917d0..c11b3d6c1 100644 --- a/src/netcode/Sourcefile +++ b/src/netcode/Sourcefile @@ -1,4 +1,5 @@ d_clisrv.c +client_connection.c d_net.c d_netcmd.c d_netfil.c diff --git a/src/netcode/client_connection.c b/src/netcode/client_connection.c new file mode 100644 index 000000000..bfaea2e81 --- /dev/null +++ b/src/netcode/client_connection.c @@ -0,0 +1,1181 @@ +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2022 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 client_connection.h +/// \brief Client connection handling + +#include "client_connection.h" +#include "d_clisrv.h" +#include "d_netfil.h" +#include "../d_main.h" +#include "../f_finale.h" +#include "../g_game.h" +#include "../i_gamepad.h" +#include "i_net.h" +#include "../i_system.h" +#include "../i_time.h" +#include "../i_video.h" +#include "../m_menu.h" +#include "../m_misc.h" +#include "../snake.h" +#include "../s_sound.h" +#include "../v_video.h" +#include "../y_inter.h" +#include "../z_zone.h" +#include "../doomtype.h" +#include "../doomstat.h" + +cl_mode_t cl_mode = CL_SEARCHING; +static UINT16 cl_lastcheckedfilecount = 0; // used for full file list +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 +tic_t firstconnectattempttime = 0; +UINT8 mynode; // my address pointofview server +static void *snake = NULL; + +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 +// +// Keep the local client informed of our status. +// +static inline void CL_DrawConnectionStatus(void) +{ + INT32 ccstime = I_GetTime(); + + // Draw background fade + V_DrawFadeScreen(0xFF00, 16); // force default + + if (cl_mode != CL_DOWNLOADFILES && cl_mode != CL_LOADFILES) + { + INT32 i, animtime = ((ccstime / 4) & 15) + 16; + 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) // 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 (fileneeded && 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_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: + 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..."); + break; + } + V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-16-24, V_YELLOWMAP, cltext); + } + else + { + 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; + char *filename; + + if (snake) + Snake_Draw(snake); + + // 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); + 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 + { + if (snake) + Snake_Draw(snake); + + CL_DrawConnectionStatusBox(); + V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-16-24, V_YELLOWMAP, + M_GetText("Waiting to download files...")); + } + } +} + +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... + * + */ +boolean CL_SendJoin(void) +{ + UINT8 localplayers = 1; + if (netgame) + 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; + + 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 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 + + /* 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->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*/ +} + +static void M_ConfirmConnect(event_t *ev) +{ + if (ev->type == ev_keydown || ev->type == ev_gamepad_down) + { + if ((ev->type == ev_keydown && (ev->key == ' ' || ev->key == 'y' || ev->key == KEY_ENTER)) || (ev->type == ev_gamepad_down && ev->which == 0 && ev->key == GAMEPAD_BUTTON_A)) + { + if (totalfilesrequestednum > 0) + { + if (CL_SendFileRequest()) + { + cl_mode = CL_DOWNLOADFILES; + Snake_Allocate(&snake); + } + } + else + cl_mode = CL_LOADFILES; + + M_ClearMenus(true); + } + else if ((ev->type == ev_keydown && (ev->key == 'n' || ev->key == KEY_ESCAPE)) || (ev->type == ev_gamepad_down && ev->which == 0 && ev->key == GAMEPAD_BUTTON_B)) + { + cl_mode = CL_ABORTED; + M_ClearMenus(true); + } + } +} + +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; + } + + 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)); + + 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" + + /* 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); + } + + 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" + "joins for the moment.\n" EOT; + case REFUSE_SLOTS_FULL: + return va( + "Maximum players reached: %d\n" EOT, + info->maxplayer); + 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; + +#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. + * \return False if the connection was aborted + * \sa CL_ServerConnectionTicker + * \sa CL_ConnectToServer + * + */ +static boolean CL_ServerConnectionSearchTicker(tic_t *asksent) +{ + 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; + } + + if (client) + { + serverinfo_pak *info = &serverlist[i].info; + + if (info->refusereason == REFUSE_SLOTS_FULL) + serverisfull = true; + else + { + 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(message, NULL, MM_NOTHING); + Z_Free(message); + return false; + } + } + + 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; + } + + // Ask the info to the server (askinfo packet) + if (*asksent + NEWTICRATE < I_GetTime()) + { + SendAskInfo(servernode); + *asksent = I_GetTime(); + } + + 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; + + switch (cl_mode) + { + case CL_SEARCHING: + if (!CL_ServerConnectionSearchTicker(asksent)) + 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++) + if (fileneeded[i].status == FS_DOWNLOADING + || fileneeded[i].status == FS_REQUESTED) + { + waitmore = true; + break; + } + if (waitmore) + break; // exit the case + + Snake_Free(&snake); + + 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: + 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; + } + + // 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); + + 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; + 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; + + case CL_CONNECTED: + case CL_CONFIRMCONNECT: //logic is handled by M_ConfirmConnect + 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(); + + if (cl_mode == CL_CONFIRMCONNECT) + D_ProcessEvents(); //needed for menu system to receive inputs + else + { + // my hand has been forced and I am dearly sorry for this awful hack :vomit: + for (; eventtail != eventhead; eventtail = (eventtail+1) & (MAXEVENTS-1)) + { + G_MapEventsToControls(&events[eventtail]); + } + } + + if (gamekeydown[KEY_ESCAPE] || gamepads[0].buttons[GAMEPAD_BUTTON_B] || 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); + + Snake_Free(&snake); + + D_QuitNetGame(); + CL_Reset(); + D_StartTitle(); + memset(gamekeydown, 0, NUMKEYS); + return false; + } + else if (cl_mode == CL_DOWNLOADFILES && snake) + Snake_Update(snake); + + 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(); + + if (client && cl_mode != CL_CONNECTED && cl_mode != CL_ABORTED) + { + 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(); + S_UpdateSounds(); + S_UpdateClosedCaptions(); + } + } + else + { + I_Sleep(cv_sleep.value); + I_UpdateTime(cv_timescale.value); + } + + return true; +} + +#define TMPSAVENAME "$$$.sav" + +/** Use adaptive send using net_bandwidth and stat.sendbytes + * + * \todo Better description... + * + */ +void CL_ConnectToServer(void) +{ + INT32 pnumnodes, nodewaited = doomcom->numnodes, i; + tic_t oldtic; + tic_t asksent; + char tmpsave[256]; + + sprintf(tmpsave, "%s" PATHSEP TMPSAVENAME, srb2home); + + lastfilenum = -1; + + cl_mode = CL_SEARCHING; + + // 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); + + 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; + + asksent = (tic_t) - TICRATE; + firstconnectattempttime = I_GetTime(); + + 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); + + do + { + // If the connection was aborted for some reason, leave + if (!CL_ServerConnectionTicker(tmpsave, &oldtic, &asksent)) + return; + + if (server) + { + pnumnodes = 0; + for (i = 0; i < MAXNETNODES; i++) + if (netnodes[i].ingame) + pnumnodes++; + } + } + while (!(cl_mode == CL_CONNECTED && (client || (server && nodewaited <= pnumnodes)))); + + DEBFILE(va("Synchronisation Finished\n")); + + displayplayer = consoleplayer; +} + +/** 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? + * + */ +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); +} + +// Helper function for packets that should only be sent by the server +// If it is NOT from the server, bail out and close the connection! +static boolean ServerOnly(SINT8 node) +{ + if (node == servernode) + return false; + + Net_CloseConnection(node); + return true; +} + +void PT_MoreFilesNeeded(SINT8 node) +{ + if (server && serverrunning) + { // But wait I thought I'm the server? + Net_CloseConnection(node); + return; + } + if (ServerOnly(node)) + return; + 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 + } +} + +// Negative response of client join request +void PT_ServerRefuse(SINT8 node) +{ + if (server && serverrunning) + { // But wait I thought I'm the server? + Net_CloseConnection(node); + return; + } + if (ServerOnly(node)) + return; + 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"); + + 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); + return; + } + + 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. + cl_mode = CL_ABORTED; + } +} + +// Positive response of client join request +void PT_ServerCFG(SINT8 node) +{ + if (server && serverrunning && node != servernode) + { // but wait I thought I'm the server? + Net_CloseConnection(node); + return; + } + if (ServerOnly(node)) + return; + /// \note how would this happen? and is it doing the right thing if it does? + if (cl_mode != CL_WAITJOINRESPONSE) + return; + + 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); + } + + netnodes[(UINT8)servernode].ingame = 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) + CONS_Printf(M_GetText("Join accepted, waiting for complete game state...\n")); + DEBFILE(va("Server accept join gametic=%u mynode=%d\n", gametic, mynode)); + + /// \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 + cl_mode = CL_CONNECTED; +} diff --git a/src/netcode/client_connection.h b/src/netcode/client_connection.h new file mode 100644 index 000000000..a76411ba6 --- /dev/null +++ b/src/netcode/client_connection.h @@ -0,0 +1,61 @@ +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2022 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 client_connection.h +/// \brief Client connection handling + +#ifndef __D_CLIENT_CONNECTION__ +#define __D_CLIENT_CONNECTION__ + +#include "../doomtype.h" +#include "d_clisrv.h" + +#define MAXSERVERLIST (MAXNETNODES-1) + +typedef struct +{ + SINT8 node; + serverinfo_pak info; +} serverelem_t; + +typedef enum +{ + CL_SEARCHING, + CL_CHECKFILES, + CL_DOWNLOADFILES, + CL_ASKJOIN, + CL_LOADFILES, + CL_WAITJOINRESPONSE, + CL_DOWNLOADSAVEGAME, + CL_CONNECTED, + CL_ABORTED, + CL_ASKFULLFILELIST, + CL_CONFIRMCONNECT +} cl_mode_t; + +extern serverelem_t serverlist[MAXSERVERLIST]; +extern UINT32 serverlistcount; + +extern cl_mode_t cl_mode; +extern boolean serverisfull; //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 +extern tic_t firstconnectattempttime; +extern UINT8 mynode; // my address pointofview server + +void CL_QueryServerList(msg_server_t *list); +void CL_UpdateServerList(boolean internetsearch, INT32 room); + +void CL_ConnectToServer(void); +boolean CL_SendJoin(void); + +void HandleServerInfo(SINT8 node); +void PT_MoreFilesNeeded(SINT8 node); +void PT_ServerRefuse(SINT8 node); +void PT_ServerCFG(SINT8 node); + +#endif diff --git a/src/netcode/d_clisrv.c b/src/netcode/d_clisrv.c index 9b11e23ff..f7a9260e1 100644 --- a/src/netcode/d_clisrv.c +++ b/src/netcode/d_clisrv.c @@ -49,14 +49,7 @@ #include "../lua_libs.h" #include "../md5.h" #include "../m_perfstats.h" - -// aaaaaa -#include "../i_gamepad.h" - -// cl loading screen -#include "../v_video.h" -#include "../f_finale.h" -#include "../snake.h" +#include "client_connection.h" // // NETWORKING @@ -103,7 +96,7 @@ tic_t servermaxping = 800; // server's max ping. Defaults to 800 static tic_t firstticstosend; // min of the nettics static tic_t tictoclear = 0; // optimize d_clearticcmd -static tic_t maketic; +tic_t maketic; static INT16 consistancy[BACKUPTICS]; @@ -121,21 +114,17 @@ 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; +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 @@ -512,250 +501,6 @@ void ReadLmpExtraData(UINT8 **demo_pointer, INT32 playernum) 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_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 - -static void *snake = NULL; - -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 -// -// Keep the local client informed of our status. -// -static inline void CL_DrawConnectionStatus(void) -{ - INT32 ccstime = I_GetTime(); - - // Draw background fade - V_DrawFadeScreen(0xFF00, 16); // force default - - if (cl_mode != CL_DOWNLOADFILES && cl_mode != CL_LOADFILES) - { - INT32 i, animtime = ((ccstime / 4) & 15) + 16; - 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) // 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 (fileneeded && 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_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: - 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..."); - break; - } - V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-16-24, V_YELLOWMAP, cltext); - } - else - { - 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; - char *filename; - - if (snake) - Snake_Draw(snake); - - // 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); - 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 - { - if (snake) - Snake_Draw(snake); - - CL_DrawConnectionStatusBox(); - V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-16-24, V_YELLOWMAP, - M_GetText("Waiting to download files...")); - } - } -} - -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... - * - */ -static boolean CL_SendJoin(void) -{ - UINT8 localplayers = 1; - if (netgame) - 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; - - 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]; @@ -1105,7 +850,7 @@ static void SV_SavedGame(void) #define TMPSAVENAME "$$$.sav" -static void CL_LoadReceivedSavegame(boolean reloading) +void CL_LoadReceivedSavegame(boolean reloading) { UINT8 *savebuffer = NULL; size_t length, decompressedlen; @@ -1206,790 +951,6 @@ static void CL_ReloadReceivedSavegame(void) CONS_Printf(M_GetText("Game state reloaded\n")); } -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 - - /* 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->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*/ -} - -static void M_ConfirmConnect(event_t *ev) -{ - if (ev->type == ev_keydown || ev->type == ev_gamepad_down) - { - if ((ev->type == ev_keydown && (ev->key == ' ' || ev->key == 'y' || ev->key == KEY_ENTER)) || (ev->type == ev_gamepad_down && ev->which == 0 && ev->key == GAMEPAD_BUTTON_A)) - { - if (totalfilesrequestednum > 0) - { - if (CL_SendFileRequest()) - { - cl_mode = CL_DOWNLOADFILES; - Snake_Allocate(&snake); - } - } - else - cl_mode = CL_LOADFILES; - - M_ClearMenus(true); - } - else if ((ev->type == ev_keydown && (ev->key == 'n' || ev->key == KEY_ESCAPE)) || (ev->type == ev_gamepad_down && ev->which == 0 && ev->key == GAMEPAD_BUTTON_B)) - { - cl_mode = CL_ABORTED; - M_ClearMenus(true); - } - } -} - -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; - } - - 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)); - - 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" - - /* 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); - } - - 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" - "joins for the moment.\n" EOT; - case REFUSE_SLOTS_FULL: - return va( - "Maximum players reached: %d\n" EOT, - info->maxplayer); - 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; - -#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. - * \return False if the connection was aborted - * \sa CL_ServerConnectionTicker - * \sa CL_ConnectToServer - * - */ -static boolean CL_ServerConnectionSearchTicker(tic_t *asksent) -{ - 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; - } - - if (client) - { - serverinfo_pak *info = &serverlist[i].info; - - if (info->refusereason == REFUSE_SLOTS_FULL) - serverisfull = true; - else - { - 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(message, NULL, MM_NOTHING); - Z_Free(message); - return false; - } - } - - 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; - } - - // Ask the info to the server (askinfo packet) - if (*asksent + NEWTICRATE < I_GetTime()) - { - SendAskInfo(servernode); - *asksent = I_GetTime(); - } - - 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; - - switch (cl_mode) - { - case CL_SEARCHING: - if (!CL_ServerConnectionSearchTicker(asksent)) - 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++) - if (fileneeded[i].status == FS_DOWNLOADING - || fileneeded[i].status == FS_REQUESTED) - { - waitmore = true; - break; - } - if (waitmore) - break; // exit the case - - Snake_Free(&snake); - - 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: - 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; - } - - // 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); - - 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; - 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; - - case CL_CONNECTED: - case CL_CONFIRMCONNECT: //logic is handled by M_ConfirmConnect - 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(); - - if (cl_mode == CL_CONFIRMCONNECT) - D_ProcessEvents(); //needed for menu system to receive inputs - else - { - // my hand has been forced and I am dearly sorry for this awful hack :vomit: - for (; eventtail != eventhead; eventtail = (eventtail+1) & (MAXEVENTS-1)) - { - G_MapEventsToControls(&events[eventtail]); - } - } - - if (gamekeydown[KEY_ESCAPE] || gamepads[0].buttons[GAMEPAD_BUTTON_B] || 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); - - Snake_Free(&snake); - - D_QuitNetGame(); - CL_Reset(); - D_StartTitle(); - memset(gamekeydown, 0, NUMKEYS); - return false; - } - else if (cl_mode == CL_DOWNLOADFILES && snake) - Snake_Update(snake); - - 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(); - - if (client && cl_mode != CL_CONNECTED && cl_mode != CL_ABORTED) - { - 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(); - S_UpdateSounds(); - S_UpdateClosedCaptions(); - } - } - else - { - I_Sleep(cv_sleep.value); - I_UpdateTime(cv_timescale.value); - } - - 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; - tic_t asksent; - char tmpsave[256]; - - sprintf(tmpsave, "%s" PATHSEP TMPSAVENAME, srb2home); - - lastfilenum = -1; - - cl_mode = CL_SEARCHING; - - // 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); - - 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; - - asksent = (tic_t) - TICRATE; - firstconnectattempttime = I_GetTime(); - - 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); - - do - { - // If the connection was aborted for some reason, leave - if (!CL_ServerConnectionTicker(tmpsave, &oldtic, &asksent)) - return; - - if (server) - { - pnumnodes = 0; - for (i = 0; i < MAXNETNODES; i++) - if (netnodes[i].ingame) - pnumnodes++; - } - } - while (!(cl_mode == CL_CONNECTED && (client || (server && nodewaited <= pnumnodes)))); - - DEBFILE(va("Synchronisation Finished\n")); - - displayplayer = consoleplayer; -} - typedef struct banreason_s { char *reason; @@ -3525,39 +2486,6 @@ static void HandleTimeout(SINT8 node) M_StartMessage(M_GetText("Server Timeout\n\nPress Esc\n"), NULL, MM_NOTHING); } -/** 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); -} - -// Helper function for packets that should only be sent by the server -// If it is NOT from the server, bail out and close the connection! -static boolean ServerOnly(SINT8 node) -{ - if (node == servernode) - return false; - - Net_CloseConnection(node); - return true; -} - static void PT_AskInfoViaMS(SINT8 node) { Net_CloseConnection(node); @@ -3582,23 +2510,6 @@ static void PT_TellFilesNeeded(SINT8 node) Net_CloseConnection(node); } -static void PT_MoreFilesNeeded(SINT8 node) -{ - if (server && serverrunning) - { // But wait I thought I'm the server? - Net_CloseConnection(node); - return; - } - if (ServerOnly(node)) - return; - 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 - } -} - static void PT_AskInfo(SINT8 node) { if (server && serverrunning) @@ -3609,91 +2520,6 @@ static void PT_AskInfo(SINT8 node) Net_CloseConnection(node); } -// Negative response of client join request -static void PT_ServerRefuse(SINT8 node) -{ - if (server && serverrunning) - { // But wait I thought I'm the server? - Net_CloseConnection(node); - return; - } - if (ServerOnly(node)) - return; - 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"); - - 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); - return; - } - - 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. - cl_mode = CL_ABORTED; - } -} - -// Positive response of client join request -static void PT_ServerCFG(SINT8 node) -{ - if (server && serverrunning && node != servernode) - { // but wait I thought I'm the server? - Net_CloseConnection(node); - return; - } - if (ServerOnly(node)) - return; - /// \note how would this happen? and is it doing the right thing if it does? - if (cl_mode != CL_WAITJOINRESPONSE) - return; - - 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); - } - - netnodes[(UINT8)servernode].ingame = 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) - CONS_Printf(M_GetText("Join accepted, waiting for complete game state...\n")); - DEBFILE(va("Server accept join gametic=%u mynode=%d\n", gametic, mynode)); - - /// \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 - cl_mode = CL_CONNECTED; -} - static void PT_ClientCmd(SINT8 node, INT32 netconsole) { tic_t realend, realstart; @@ -4190,7 +3016,7 @@ static void HandlePacketFromPlayer(SINT8 node) * \todo Add details to this description (lol) * */ -static void GetPackets(void) +void GetPackets(void) { SINT8 node; // The packet sender diff --git a/src/netcode/d_clisrv.h b/src/netcode/d_clisrv.h index 50b86e9f0..3b0690a79 100644 --- a/src/netcode/d_clisrv.h +++ b/src/netcode/d_clisrv.h @@ -332,15 +332,6 @@ typedef struct #pragma pack() #endif -#define MAXSERVERLIST (MAXNETNODES-1) -typedef struct -{ - SINT8 node; - serverinfo_pak info; -} serverelem_t; - -extern serverelem_t serverlist[MAXSERVERLIST]; -extern UINT32 serverlistcount; extern INT32 mapchangepending; // Points inside doomcom @@ -385,6 +376,8 @@ extern boolean dedicated; // For dedicated server extern UINT16 software_MAXPACKETLENGTH; extern boolean acceptnewnode; extern SINT8 servernode; +extern tic_t maketic; +extern tic_t neededtic; void Command_Ping_f(void); extern tic_t connectiontimeout; @@ -411,6 +404,8 @@ void SendKick(UINT8 playernum, UINT8 msg); // Create any new ticcmds and broadcast to other players. void NetUpdate(void); +void GetPackets(void); + void SV_StartSinglePlayerServer(void); void SV_SpawnServer(void); void SV_StopServer(void); @@ -419,9 +414,8 @@ void CL_AddSplitscreenPlayer(void); void CL_RemoveSplitscreenPlayer(void); 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); +void CL_LoadReceivedSavegame(boolean reloading); // Is there a game running boolean Playing(void); diff --git a/src/netcode/http-mserv.c b/src/netcode/http-mserv.c index 72dc1cafb..68e46b52a 100644 --- a/src/netcode/http-mserv.c +++ b/src/netcode/http-mserv.c @@ -20,6 +20,7 @@ Documentation available here. #include "../doomdef.h" #include "d_clisrv.h" +#include "client_connection.h" #include "../command.h" #include "../m_argv.h" #include "../m_menu.h" diff --git a/src/netcode/mserv.c b/src/netcode/mserv.c index 78301f4d9..f603d78e5 100644 --- a/src/netcode/mserv.c +++ b/src/netcode/mserv.c @@ -20,6 +20,7 @@ #include "../command.h" #include "../i_threads.h" #include "mserv.h" +#include "client_connection.h" #include "../m_menu.h" #include "../z_zone.h" From fc41dd78f46f5683612a5e33f922d94881d2b13e Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sun, 1 Jan 2023 11:45:09 +0100 Subject: [PATCH 333/586] Move server-side connection handling to a new file --- src/netcode/Sourcefile | 1 + src/netcode/d_clisrv.c | 475 +----------------------------- src/netcode/d_clisrv.h | 3 +- src/netcode/d_netcmd.c | 1 + src/netcode/server_connection.c | 497 ++++++++++++++++++++++++++++++++ src/netcode/server_connection.h | 29 ++ 6 files changed, 533 insertions(+), 473 deletions(-) create mode 100644 src/netcode/server_connection.c create mode 100644 src/netcode/server_connection.h diff --git a/src/netcode/Sourcefile b/src/netcode/Sourcefile index c11b3d6c1..4177166a4 100644 --- a/src/netcode/Sourcefile +++ b/src/netcode/Sourcefile @@ -1,4 +1,5 @@ d_clisrv.c +server_connection.c client_connection.c d_net.c d_netcmd.c diff --git a/src/netcode/d_clisrv.c b/src/netcode/d_clisrv.c index f7a9260e1..c1264768e 100644 --- a/src/netcode/d_clisrv.c +++ b/src/netcode/d_clisrv.c @@ -49,6 +49,7 @@ #include "../lua_libs.h" #include "../md5.h" #include "../m_perfstats.h" +#include "server_connection.h" #include "client_connection.h" // @@ -79,15 +80,6 @@ netnode_t netnodes[MAXNETNODES]; // 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); - -// 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. @@ -100,7 +92,6 @@ tic_t maketic; static INT16 consistancy[BACKUPTICS]; -static UINT8 player_joining = false; UINT8 hu_redownloadinggamestate = 0; // true when a player is connecting or disconnecting so that the gameplay has stopped in its tracks @@ -501,229 +492,6 @@ void ReadLmpExtraData(UINT8 **demo_pointer, INT32 playernum) static INT16 Consistancy(void); -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 UINT8 -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) - return REFUSE_SLOTS_FULL; - else - return 0; -} - -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; - - netbuffer->u.serverinfo.refusereason = GetRefuseReason(node); - - 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.flags = (dedicated ? SV_DEDICATED : 0); - 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(0); - - 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.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; -} - #define SAVEGAMESIZE (768*1024) static boolean SV_ResendingSavegameToAnyone(void) @@ -736,7 +504,7 @@ static boolean SV_ResendingSavegameToAnyone(void) return false; } -static void SV_SendSaveGame(INT32 node, boolean resending) +void SV_SendSaveGame(INT32 node, boolean resending) { size_t length, compressedlen; UINT8 *savebuffer; @@ -1190,7 +958,7 @@ static void Command_connect(void) CL_ConnectToServer(); } -static void ResetNode(INT32 node) +void ResetNode(INT32 node) { memset(&netnodes[node], 0, sizeof(*netnodes)); netnodes[node].player = -1; @@ -2020,17 +1788,6 @@ void D_QuitNetGame(void) #endif } -// Adds a node to the game (player will follow at map change or at savegame....) -static inline void SV_AddNode(INT32 node) -{ - netnodes[node].tic = gametic; - netnodes[node].supposedtic = gametic; - // little hack because the server connects to itself and puts - // nodeingame when connected not here - if (node) - netnodes[node].ingame = true; -} - // Xcmd XD_ADDPLAYER static void Got_AddPlayer(UINT8 **p, INT32 playernum) { @@ -2163,56 +1920,6 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum) LUA_HookInt(newplayernum, HOOK(PlayerJoin)); } -static void SV_AddPlayer(SINT8 node, const char *name) -{ - INT32 n; - UINT8 buf[2 + MAXPLAYERNAME]; - UINT8 *p; - INT32 newplayernum; - - 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 (netnodes[n].player == newplayernum || netnodes[n].player2 == 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 (netnodes[node].numplayers < 1) - { - netnodes[node].player = newplayernum; - } - else - { - netnodes[node].player2 = newplayernum; - buf[1] |= 0x80; - } - WRITESTRINGN(p, name, MAXPLAYERNAME); - netnodes[node].numplayers++; - - SendNetXCmd(XD_ADDPLAYER, &buf, p - buf); - - DEBFILE(va("Server added player %d node %d\n", newplayernum, node)); -} - void CL_AddSplitscreenPlayer(void) { if (cl_mode == CL_CONNECTED) @@ -2298,15 +2005,6 @@ void SV_StartSinglePlayerServer(void) 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) { @@ -2323,139 +2021,6 @@ static size_t TotalTextCmdPerTic(tic_t tic) return total; } -static const char * -GetRefuseMessage (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 - * - */ -static void HandleConnect(SINT8 node) -{ - char names[MAXSPLITSCREENPLAYERS][MAXPLAYERNAME + 1]; - INT32 numplayers = netbuffer->u.clientcfg.localplayers; - INT32 rejoinernum; - INT32 i; - - // Ignore duplicate packets - if (netnodes[node].ingame) - return; - - rejoinernum = FindRejoinerNum(node); - - const char *refuse = GetRefuseMessage(node, rejoinernum); - if (refuse) - { - SV_SendRefuse(node, refuse); - return; - } - - for (i = 0; i < numplayers; i++) - { - strlcpy(names[i], netbuffer->u.clientcfg.names[i], MAXPLAYERNAME + 1); - if (!EnsurePlayerNameIsGood(names[i], rejoinernum)) - { - SV_SendRefuse(node, "Bad player name"); - return; - } - } - - SV_AddNode(node); - - if (!SV_SendServerConfig(node)) - { - /// \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 - } - DEBFILE("new node joined\n"); - - if (gamestate == GS_LEVEL || gamestate == GS_INTERMISSION) - { - SV_SendSaveGame(node, false); // send a complete game state - DEBFILE("send savegame\n"); - } - - // Splitscreen can allow 2 players in one node - for (i = 0; i < numplayers; i++) - SV_AddPlayer(node, names[i]); - - joindelay += cv_joindelay.value * TICRATE; - player_joining = true; -} - /** Called when a PT_SERVERSHUTDOWN packet is received * * \param node The packet sender (should be the server) @@ -2486,40 +2051,6 @@ static void HandleTimeout(SINT8 node) M_StartMessage(M_GetText("Server Timeout\n\nPress Esc\n"), NULL, MM_NOTHING); } -static void PT_AskInfoViaMS(SINT8 node) -{ - Net_CloseConnection(node); -} - -static void PT_TellFilesNeeded(SINT8 node) -{ - if (server && serverrunning) - { - 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); -} - -static void PT_AskInfo(SINT8 node) -{ - if (server && serverrunning) - { - SV_SendServerInfo(node, (tic_t)LONG(netbuffer->u.askinfo.time)); - SV_SendPlayerInfo(node); // Send extra info - } - Net_CloseConnection(node); -} - static void PT_ClientCmd(SINT8 node, INT32 netconsole) { tic_t realend, realstart; diff --git a/src/netcode/d_clisrv.h b/src/netcode/d_clisrv.h index 3b0690a79..b8da645ba 100644 --- a/src/netcode/d_clisrv.h +++ b/src/netcode/d_clisrv.h @@ -381,7 +381,6 @@ extern tic_t neededtic; void Command_Ping_f(void); extern tic_t connectiontimeout; -extern tic_t jointimeout; extern UINT16 pingmeasurecount; extern UINT32 realpingtable[MAXPLAYERS]; extern UINT32 playerpingtable[MAXPLAYERS]; @@ -405,11 +404,13 @@ void SendKick(UINT8 playernum, UINT8 msg); void NetUpdate(void); void GetPackets(void); +void ResetNode(INT32 node); void SV_StartSinglePlayerServer(void); void SV_SpawnServer(void); void SV_StopServer(void); void SV_ResetServer(void); +void SV_SendSaveGame(INT32 node, boolean resending); void CL_AddSplitscreenPlayer(void); void CL_RemoveSplitscreenPlayer(void); void CL_Reset(void); diff --git a/src/netcode/d_netcmd.c b/src/netcode/d_netcmd.c index ed310805d..fe4cf22bd 100644 --- a/src/netcode/d_netcmd.c +++ b/src/netcode/d_netcmd.c @@ -36,6 +36,7 @@ #include "../p_spec.h" #include "../m_cheat.h" #include "d_clisrv.h" +#include "server_connection.h" #include "d_net.h" #include "../v_video.h" #include "../d_main.h" diff --git a/src/netcode/server_connection.c b/src/netcode/server_connection.c new file mode 100644 index 000000000..9e397b0f3 --- /dev/null +++ b/src/netcode/server_connection.c @@ -0,0 +1,497 @@ +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2022 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 server_connection.c +/// \brief Server-side part of connection handling + +#include "server_connection.h" +#include "i_net.h" +#include "d_clisrv.h" +#include "d_netfil.h" +#include "mserv.h" +#include "../byteptr.h" +#include "../g_game.h" +#include "../g_state.h" +#include "../p_setup.h" +#include "../p_tick.h" +#include "../doomstat.h" + +// Minimum timeout for sending the savegame +// The actual timeout will be longer depending on the savegame length +tic_t jointimeout = (10*TICRATE); + +// 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. +tic_t joindelay = 0; + +// Minimum timeout for sending the savegame +// The actual timeout will be longer depending on the savegame length +char playeraddress[MAXPLAYERS][64]; + +UINT8 player_joining = false; + +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 UINT8 +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) + return REFUSE_SLOTS_FULL; + else + return 0; +} + +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; + + netbuffer->u.serverinfo.refusereason = GetRefuseReason(node); + + 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.flags = (dedicated ? SV_DEDICATED : 0); + 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(0); + + 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.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; +} + +// Adds a node to the game (player will follow at map change or at savegame....) +static inline void SV_AddNode(INT32 node) +{ + netnodes[node].tic = gametic; + netnodes[node].supposedtic = gametic; + // little hack because the server connects to itself and puts + // nodeingame when connected not here + if (node) + netnodes[node].ingame = true; +} + +static void SV_AddPlayer(SINT8 node, const char *name) +{ + INT32 n; + UINT8 buf[2 + MAXPLAYERNAME]; + UINT8 *p; + INT32 newplayernum; + + 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 (netnodes[n].player == newplayernum || netnodes[n].player2 == 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 (netnodes[node].numplayers < 1) + { + netnodes[node].player = newplayernum; + } + else + { + netnodes[node].player2 = newplayernum; + buf[1] |= 0x80; + } + WRITESTRINGN(p, name, MAXPLAYERNAME); + netnodes[node].numplayers++; + + SendNetXCmd(XD_ADDPLAYER, &buf, p - buf); + + DEBFILE(va("Server added player %d node %d\n", newplayernum, node)); +} + +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); +} + +static const char * +GetRefuseMessage (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 + * + */ +void HandleConnect(SINT8 node) +{ + char names[MAXSPLITSCREENPLAYERS][MAXPLAYERNAME + 1]; + INT32 numplayers = netbuffer->u.clientcfg.localplayers; + INT32 rejoinernum; + INT32 i; + + // Ignore duplicate packets + if (netnodes[node].ingame) + return; + + rejoinernum = FindRejoinerNum(node); + + const char *refuse = GetRefuseMessage(node, rejoinernum); + if (refuse) + { + SV_SendRefuse(node, refuse); + return; + } + + for (i = 0; i < numplayers; i++) + { + strlcpy(names[i], netbuffer->u.clientcfg.names[i], MAXPLAYERNAME + 1); + if (!EnsurePlayerNameIsGood(names[i], rejoinernum)) + { + SV_SendRefuse(node, "Bad player name"); + return; + } + } + + SV_AddNode(node); + + if (!SV_SendServerConfig(node)) + { + /// \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 + } + DEBFILE("new node joined\n"); + + if (gamestate == GS_LEVEL || gamestate == GS_INTERMISSION) + { + SV_SendSaveGame(node, false); // send a complete game state + DEBFILE("send savegame\n"); + } + + // Splitscreen can allow 2 players in one node + for (i = 0; i < numplayers; i++) + SV_AddPlayer(node, names[i]); + + joindelay += cv_joindelay.value * TICRATE; + player_joining = true; +} + +void PT_AskInfoViaMS(SINT8 node) +{ + Net_CloseConnection(node); +} + +void PT_TellFilesNeeded(SINT8 node) +{ + if (server && serverrunning) + { + 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); +} + +void PT_AskInfo(SINT8 node) +{ + if (server && serverrunning) + { + SV_SendServerInfo(node, (tic_t)LONG(netbuffer->u.askinfo.time)); + SV_SendPlayerInfo(node); // Send extra info + } + Net_CloseConnection(node); +} diff --git a/src/netcode/server_connection.h b/src/netcode/server_connection.h new file mode 100644 index 000000000..4204db2e6 --- /dev/null +++ b/src/netcode/server_connection.h @@ -0,0 +1,29 @@ +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2022 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 server_connection.h +/// \brief Server-side part of connection handling + +#ifndef __D_SERVER_CONNECTION__ +#define __D_SERVER_CONNECTION__ + +#include "../doomdef.h" +#include "../doomtype.h" + +void HandleConnect(SINT8 node); +void PT_AskInfoViaMS(SINT8 node); +void PT_TellFilesNeeded(SINT8 node); +void PT_AskInfo(SINT8 node); + +extern tic_t jointimeout; +extern tic_t joindelay; +extern char playeraddress[MAXPLAYERS][64]; +extern UINT8 player_joining; + +#endif From 0ade3ae0bc020e3ca932f98e977c78301dcbaa0d Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Thu, 5 Jan 2023 22:51:17 +0100 Subject: [PATCH 334/586] Move tic and net command handling to new files --- src/blua/liolib.c | 1 + src/command.c | 1 + src/g_game.c | 1 + src/hu_stuff.c | 1 + src/lua_consolelib.c | 1 + src/netcode/Sourcefile | 2 + src/netcode/d_clisrv.c | 878 +------------------------------- src/netcode/d_clisrv.h | 12 +- src/netcode/d_net.c | 1 + src/netcode/d_netcmd.c | 1 + src/netcode/d_netfil.c | 1 + src/netcode/net_command.c | 315 ++++++++++++ src/netcode/net_command.h | 62 +++ src/netcode/server_connection.c | 1 + src/netcode/tic_command.c | 504 ++++++++++++++++++ src/netcode/tic_command.h | 44 ++ src/p_inter.c | 1 + src/p_mobj.c | 1 + src/p_setup.c | 2 + src/p_tick.c | 1 + src/p_user.c | 1 + 21 files changed, 955 insertions(+), 877 deletions(-) create mode 100644 src/netcode/net_command.c create mode 100644 src/netcode/net_command.h create mode 100644 src/netcode/tic_command.c create mode 100644 src/netcode/tic_command.h diff --git a/src/blua/liolib.c b/src/blua/liolib.c index 00e31e965..6b44e2eb8 100644 --- a/src/blua/liolib.c +++ b/src/blua/liolib.c @@ -20,6 +20,7 @@ #include "../i_system.h" #include "../g_game.h" #include "../netcode/d_netfil.h" +#include "../netcode/net_command.h" #include "../lua_libs.h" #include "../byteptr.h" #include "../lua_script.h" diff --git a/src/command.c b/src/command.c index 0256365f3..e0deff8e1 100644 --- a/src/command.c +++ b/src/command.c @@ -29,6 +29,7 @@ #include "p_saveg.h" #include "g_game.h" // for player_names #include "netcode/d_netcmd.h" +#include "netcode/net_command.h" #include "hu_stuff.h" #include "p_setup.h" #include "lua_script.h" diff --git a/src/g_game.c b/src/g_game.c index f47aa2183..70d249a2f 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -16,6 +16,7 @@ #include "d_main.h" #include "d_player.h" #include "netcode/d_clisrv.h" +#include "netcode/net_command.h" #include "f_finale.h" #include "p_setup.h" #include "p_saveg.h" diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 33ef8a404..1e5e47df6 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -20,6 +20,7 @@ #include "m_misc.h" // word jumping #include "netcode/d_clisrv.h" +#include "netcode/net_command.h" #include "g_game.h" #include "g_input.h" diff --git a/src/lua_consolelib.c b/src/lua_consolelib.c index 9e5d1e2ee..831dceba5 100644 --- a/src/lua_consolelib.c +++ b/src/lua_consolelib.c @@ -16,6 +16,7 @@ #include "g_game.h" #include "byteptr.h" #include "z_zone.h" +#include "netcode/net_command.h" #include "lua_script.h" #include "lua_libs.h" diff --git a/src/netcode/Sourcefile b/src/netcode/Sourcefile index 4177166a4..1039b218a 100644 --- a/src/netcode/Sourcefile +++ b/src/netcode/Sourcefile @@ -1,6 +1,8 @@ d_clisrv.c server_connection.c client_connection.c +tic_command.c +net_command.c d_net.c d_netcmd.c d_netfil.c diff --git a/src/netcode/d_clisrv.c b/src/netcode/d_clisrv.c index c1264768e..06e6da751 100644 --- a/src/netcode/d_clisrv.c +++ b/src/netcode/d_clisrv.c @@ -51,6 +51,8 @@ #include "../m_perfstats.h" #include "server_connection.h" #include "client_connection.h" +#include "tic_command.h" +#include "net_command.h" // // NETWORKING @@ -86,11 +88,9 @@ UINT32 realpingtable[MAXPLAYERS]; //the base table of ping where an average will UINT32 playerpingtable[MAXPLAYERS]; //table of player latency values. tic_t servermaxping = 800; // server's max ping. Defaults to 800 -static tic_t firstticstosend; // min of the nettics -static tic_t tictoclear = 0; // optimize d_clearticcmd tic_t maketic; -static INT16 consistancy[BACKUPTICS]; +INT16 consistancy[BACKUPTICS]; UINT8 hu_redownloadinggamestate = 0; @@ -101,14 +101,9 @@ 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 boolean cl_redownloadinggamestate = false; -static UINT8 localtextcmd[MAXTEXTCMD]; -static UINT8 localtextcmd2[MAXTEXTCMD]; // splitscreen tic_t neededtic; SINT8 servernode = 0; // the number of the server node @@ -116,385 +111,19 @@ SINT8 servernode = 0; // the number of the server node /// \todo WORK! boolean acceptnewnode = true; -// engine - -// Must be a power of two -#define TEXTCMD_HASH_SIZE 4 - -typedef struct textcmdplayer_s -{ - INT32 playernum; - UINT8 cmd[MAXTEXTCMD]; - struct textcmdplayer_s *next; -} textcmdplayer_t; - -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 - (netnodes[node].tic & UINT8_MAX); - - if (delta >= -64 && delta <= 64) - return (netnodes[node].tic & ~UINT8_MAX) + low; - else if (delta > 64) - return (netnodes[node].tic & ~UINT8_MAX) - 256 + low; - else //if (delta < -64) - return (netnodes[node].tic & ~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); - #define SAVEGAMESIZE (768*1024) -static boolean SV_ResendingSavegameToAnyone(void) +boolean SV_ResendingSavegameToAnyone(void) { INT32 i; @@ -2005,22 +1634,6 @@ void SV_StartSinglePlayerServer(void) multiplayer = true; } -// 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_SERVERSHUTDOWN packet is received * * \param node The packet sender (should be the server) @@ -2051,168 +1664,6 @@ static void HandleTimeout(SINT8 node) M_StartMessage(M_GetText("Server Timeout\n\nPress Esc\n"), NULL, MM_NOTHING); } -static void PT_ClientCmd(SINT8 node, INT32 netconsole) -{ - tic_t realend, realstart; - - if (client) - return; - - // 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 - || netnodes[node].supposedtic < realend) - { - netnodes[node].supposedtic = realend; - } - // Discard out of order packet - if (netnodes[node].tic > realend) - { - DEBFILE(va("out of order ticcmd discarded nettics = %u\n", netnodes[node].tic)); - return; - } - - // Update the nettics - netnodes[node].tic = realend; - - // Don't do anything for packets of type NODEKEEPALIVE? - if (netconsole == -1 || netbuffer->packettype == PT_NODEKEEPALIVE - || netbuffer->packettype == PT_NODEKEEPALIVEMIS) - return; - - // 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? - netnodes[node].freezetimeout = 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); - return; - } - - // Splitscreen cmd - if ((netbuffer->packettype == PT_CLIENT2CMD || netbuffer->packettype == PT_CLIENT2MIS) - && netnodes[node].player2 >= 0) - G_MoveTiccmd(&netcmds[maketic%BACKUPTICS][(UINT8)netnodes[node].player2], - &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) - && !SV_ResendingSavegameToAnyone() - && !netnodes[node].resendingsavegame && netnodes[node].savegameresendcooldown <= I_GetTime()) - { - if (cv_resynchattempts.value) - { - // Tell the client we are about to resend them the gamestate - netbuffer->packettype = PT_WILLRESENDGAMESTATE; - HSendPacket(node, true, 0, 0); - - netnodes[node].resendingsavegame = 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))); - return; - } - 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))); - return; - } - } -} - -static void PT_TextCmd(SINT8 node, INT32 netconsole) -{ - if (client) - return; - - // splitscreen special - if (netbuffer->packettype == PT_TEXTCMD2) - netconsole = netnodes[node].player2; - - 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); - return; - } - - // 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); - return; - } - - // 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); - return; - } - - // 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]; - } -} - static void PT_Login(SINT8 node, INT32 netconsole) { (void)node; @@ -2314,81 +1765,6 @@ static void PT_ReceivedGamestate(SINT8 node) netnodes[node].savegameresendcooldown = I_GetTime() + 5 * TICRATE; } -static void PT_ServerTics(SINT8 node, INT32 netconsole) -{ - UINT8 *pak, *txtpak, numtxtpak; - tic_t realend, realstart; - - if (!netnodes[node].ingame) - { - // Do not remove my own server (we have just get a out of order packet) - if (node != servernode) - { - DEBFILE(va("unknown packet received (%d) from unknown host\n",netbuffer->packettype)); - Net_CloseConnection(node); - } - return; - } - - // 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); - return; - } - - realstart = netbuffer->u.serverpak.starttic; - realend = realstart + netbuffer->u.serverpak.numtics; - - 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);*/ - } -} - static void PT_Ping(SINT8 node, INT32 netconsole) { // Only accept PT_PING from the server. @@ -2602,7 +1978,7 @@ void GetPackets(void) // 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) +INT16 Consistancy(void) { INT32 i; UINT32 ret = 0; @@ -2708,239 +2084,11 @@ static INT16 Consistancy(void) 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 netnodes[n].supposedtic, max packet size and maketic - for (n = 1; n < MAXNETNODES; n++) - if (netnodes[n].ingame) - { - // assert netnodes[n].supposedtic>=netnodes[n].tic - realfirsttic = netnodes[n].supposedtic; - lasttictosend = min(maketic, netnodes[n].tic + 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, netnodes[n].supposedtic, netnodes[n].tic)); - realfirsttic = netnodes[n].tic; - 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) - netnodes[n].supposedtic = lasttictosend-doomcom->extratics; - else - netnodes[n].supposedtic = lasttictosend; - if (netnodes[n].supposedtic < netnodes[n].tic) netnodes[n].supposedtic = netnodes[n].tic; - } - // node 0 is me! - netnodes[0].supposedtic = 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/gamepad) 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++; -} +/* +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. +*/ boolean TryRunTics(tic_t realtics) { @@ -3049,12 +2197,6 @@ boolean TryRunTics(tic_t realtics) return ticking; } -/* -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) diff --git a/src/netcode/d_clisrv.h b/src/netcode/d_clisrv.h index b8da645ba..8b73170da 100644 --- a/src/netcode/d_clisrv.h +++ b/src/netcode/d_clisrv.h @@ -378,6 +378,7 @@ extern boolean acceptnewnode; extern SINT8 servernode; extern tic_t maketic; extern tic_t neededtic; +extern INT16 consistancy[BACKUPTICS]; void Command_Ping_f(void); extern tic_t connectiontimeout; @@ -391,20 +392,15 @@ extern consvar_t cv_resynchattempts, cv_blamecfail; extern consvar_t cv_maxsend, cv_noticedownload, cv_downloadspeed; // Used in d_net, the only dependence -tic_t ExpandTics(INT32 low, INT32 node); void D_ClientServerInit(void); -// Initialise the other field -void RegisterNetXCmd(netxcmd_t id, void (*cmd_f)(UINT8 **p, INT32 playernum)); -void SendNetXCmd(netxcmd_t id, const void *param, size_t nparam); -void SendNetXCmd2(netxcmd_t id, const void *param, size_t nparam); // splitsreen player -void SendKick(UINT8 playernum, UINT8 msg); - // Create any new ticcmds and broadcast to other players. void NetUpdate(void); void GetPackets(void); void ResetNode(INT32 node); +INT16 Consistancy(void); +boolean SV_ResendingSavegameToAnyone(void); void SV_StartSinglePlayerServer(void); void SV_SpawnServer(void); @@ -440,10 +436,8 @@ extern char motd[254], server_context[8]; extern UINT8 playernode[MAXPLAYERS]; INT32 D_NumPlayers(void); -void D_ResetTiccmds(void); tic_t GetLag(INT32 node); -UINT8 GetFreeXCmdSize(void); void D_MD5PasswordPass(const UINT8 *buffer, size_t len, const char *salt, void *dest); diff --git a/src/netcode/d_net.c b/src/netcode/d_net.c index ae0605001..972342282 100644 --- a/src/netcode/d_net.c +++ b/src/netcode/d_net.c @@ -26,6 +26,7 @@ #include "../w_wad.h" #include "d_netfil.h" #include "d_clisrv.h" +#include "tic_command.h" #include "../z_zone.h" #include "i_tcp.h" #include "../d_main.h" // srb2home diff --git a/src/netcode/d_netcmd.c b/src/netcode/d_netcmd.c index fe4cf22bd..0d1785510 100644 --- a/src/netcode/d_netcmd.c +++ b/src/netcode/d_netcmd.c @@ -37,6 +37,7 @@ #include "../m_cheat.h" #include "d_clisrv.h" #include "server_connection.h" +#include "net_command.h" #include "d_net.h" #include "../v_video.h" #include "../d_main.h" diff --git a/src/netcode/d_netfil.c b/src/netcode/d_netfil.c index 80fa06852..e581be2ac 100644 --- a/src/netcode/d_netfil.c +++ b/src/netcode/d_netfil.c @@ -42,6 +42,7 @@ #include "d_net.h" #include "../w_wad.h" #include "d_netfil.h" +#include "net_command.h" #include "../z_zone.h" #include "../byteptr.h" #include "../p_setup.h" diff --git a/src/netcode/net_command.c b/src/netcode/net_command.c new file mode 100644 index 000000000..eeb479d21 --- /dev/null +++ b/src/netcode/net_command.c @@ -0,0 +1,315 @@ +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2022 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 net_command.c +/// \brief Net command handling + +#include "net_command.h" +#include "tic_command.h" +#include "d_clisrv.h" +#include "i_net.h" +#include "../g_game.h" +#include "../z_zone.h" +#include "../doomtype.h" + +textcmdtic_t *textcmds[TEXTCMD_HASH_SIZE] = {NULL}; +UINT8 localtextcmd[MAXTEXTCMD]; +UINT8 localtextcmd2[MAXTEXTCMD]; // splitscreen +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 +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 +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 +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; +} + +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); +} + +// used at txtcmds received to check packetsize bound +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; +} + +void PT_TextCmd(SINT8 node, INT32 netconsole) +{ + if (client) + return; + + // splitscreen special + if (netbuffer->packettype == PT_TEXTCMD2) + netconsole = netnodes[node].player2; + + 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); + return; + } + + // 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); + return; + } + + // 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); + return; + } + + // 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]; + } +} + +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); +} diff --git a/src/netcode/net_command.h b/src/netcode/net_command.h new file mode 100644 index 000000000..1fc5035c8 --- /dev/null +++ b/src/netcode/net_command.h @@ -0,0 +1,62 @@ +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2022 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 net_command.h +/// \brief Net command handling + +#ifndef __D_NET_COMMAND__ +#define __D_NET_COMMAND__ + +#include "d_clisrv.h" +#include "../doomtype.h" + +// Must be a power of two +#define TEXTCMD_HASH_SIZE 4 + +typedef struct textcmdplayer_s +{ + INT32 playernum; + UINT8 cmd[MAXTEXTCMD]; + struct textcmdplayer_s *next; +} textcmdplayer_t; + +typedef struct textcmdtic_s +{ + tic_t tic; + textcmdplayer_t *playercmds[TEXTCMD_HASH_SIZE]; + struct textcmdtic_s *next; +} textcmdtic_t; + +extern textcmdtic_t *textcmds[TEXTCMD_HASH_SIZE]; + +extern UINT8 localtextcmd[MAXTEXTCMD]; +extern UINT8 localtextcmd2[MAXTEXTCMD]; // splitscreen + +void RegisterNetXCmd(netxcmd_t id, void (*cmd_f)(UINT8 **p, INT32 playernum)); +void SendNetXCmd(netxcmd_t id, const void *param, size_t nparam); +void SendNetXCmd2(netxcmd_t id, const void *param, size_t nparam); // splitsreen player + +UINT8 GetFreeXCmdSize(void); +void D_FreeTextcmd(tic_t tic); + +// Gets the buffer for the specified ticcmd, or NULL if there isn't one +UINT8* D_GetExistingTextcmd(tic_t tic, INT32 playernum); + +// Gets the buffer for the specified ticcmd, creating one if necessary +UINT8* D_GetTextcmd(tic_t tic, INT32 playernum); + +void ExtraDataTicker(void); + +// used at txtcmds received to check packetsize bound +size_t TotalTextCmdPerTic(tic_t tic); + +void PT_TextCmd(SINT8 node, INT32 netconsole); +void SendKick(UINT8 playernum, UINT8 msg); + +#endif diff --git a/src/netcode/server_connection.c b/src/netcode/server_connection.c index 9e397b0f3..b776db422 100644 --- a/src/netcode/server_connection.c +++ b/src/netcode/server_connection.c @@ -15,6 +15,7 @@ #include "d_clisrv.h" #include "d_netfil.h" #include "mserv.h" +#include "net_command.h" #include "../byteptr.h" #include "../g_game.h" #include "../g_state.h" diff --git a/src/netcode/tic_command.c b/src/netcode/tic_command.c new file mode 100644 index 000000000..e7df895ff --- /dev/null +++ b/src/netcode/tic_command.c @@ -0,0 +1,504 @@ +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2022 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 tic_command.c +/// \brief Tic command handling + +#include "tic_command.h" +#include "d_clisrv.h" +#include "net_command.h" +#include "client_connection.h" +#include "i_net.h" +#include "../d_main.h" +#include "../g_game.h" +#include "../i_system.h" +#include "../i_time.h" +#include "../byteptr.h" +#include "../doomstat.h" +#include "../doomtype.h" + +tic_t firstticstosend; // min of the nettics +tic_t tictoclear = 0; // optimize d_clearticcmd +ticcmd_t localcmds; +ticcmd_t localcmds2; +boolean cl_packetmissed; +ticcmd_t netcmds[BACKUPTICS][MAXPLAYERS]; + +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; +} + +/** 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 - (netnodes[node].tic & UINT8_MAX); + + if (delta >= -64 && delta <= 64) + return (netnodes[node].tic & ~UINT8_MAX) + low; + else if (delta > 64) + return (netnodes[node].tic & ~UINT8_MAX) - 256 + low; + else //if (delta < -64) + return (netnodes[node].tic & ~UINT8_MAX) + 256 + low; +} + +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 PT_ClientCmd(SINT8 node, INT32 netconsole) +{ + tic_t realend, realstart; + + if (client) + return; + + // 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 + || netnodes[node].supposedtic < realend) + { + netnodes[node].supposedtic = realend; + } + // Discard out of order packet + if (netnodes[node].tic > realend) + { + DEBFILE(va("out of order ticcmd discarded nettics = %u\n", netnodes[node].tic)); + return; + } + + // Update the nettics + netnodes[node].tic = realend; + + // Don't do anything for packets of type NODEKEEPALIVE? + if (netconsole == -1 || netbuffer->packettype == PT_NODEKEEPALIVE + || netbuffer->packettype == PT_NODEKEEPALIVEMIS) + return; + + // 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? + netnodes[node].freezetimeout = 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); + return; + } + + // Splitscreen cmd + if ((netbuffer->packettype == PT_CLIENT2CMD || netbuffer->packettype == PT_CLIENT2MIS) + && netnodes[node].player2 >= 0) + G_MoveTiccmd(&netcmds[maketic%BACKUPTICS][(UINT8)netnodes[node].player2], + &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) + && !SV_ResendingSavegameToAnyone() + && !netnodes[node].resendingsavegame && netnodes[node].savegameresendcooldown <= I_GetTime()) + { + if (cv_resynchattempts.value) + { + // Tell the client we are about to resend them the gamestate + netbuffer->packettype = PT_WILLRESENDGAMESTATE; + HSendPacket(node, true, 0, 0); + + netnodes[node].resendingsavegame = 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))); + return; + } + 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))); + return; + } + } +} + +void PT_ServerTics(SINT8 node, INT32 netconsole) +{ + UINT8 *pak, *txtpak, numtxtpak; + tic_t realend, realstart; + + if (!netnodes[node].ingame) + { + // Do not remove my own server (we have just get a out of order packet) + if (node != servernode) + { + DEBFILE(va("unknown packet received (%d) from unknown host\n",netbuffer->packettype)); + Net_CloseConnection(node); + } + return; + } + + // 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); + return; + } + + realstart = netbuffer->u.serverpak.starttic; + realend = realstart + netbuffer->u.serverpak.numtics; + + 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);*/ + } +} + +// send the client packet to the server +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 +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 netnodes[n].supposedtic, max packet size and maketic + for (n = 1; n < MAXNETNODES; n++) + if (netnodes[n].ingame) + { + // assert netnodes[n].supposedtic>=netnodes[n].tic + realfirsttic = netnodes[n].supposedtic; + lasttictosend = min(maketic, netnodes[n].tic + 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, netnodes[n].supposedtic, netnodes[n].tic)); + realfirsttic = netnodes[n].tic; + 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) + netnodes[n].supposedtic = lasttictosend-doomcom->extratics; + else + netnodes[n].supposedtic = lasttictosend; + if (netnodes[n].supposedtic < netnodes[n].tic) netnodes[n].supposedtic = netnodes[n].tic; + } + // node 0 is me! + netnodes[0].supposedtic = maketic; +} + +// +// TryRunTics +// +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/gamepad) 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 +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++; +} diff --git a/src/netcode/tic_command.h b/src/netcode/tic_command.h new file mode 100644 index 000000000..d19f4c1aa --- /dev/null +++ b/src/netcode/tic_command.h @@ -0,0 +1,44 @@ +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2022 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 tic_command.h +/// \brief Tic command handling + +#ifndef __D_TIC_COMMAND__ +#define __D_TIC_COMMAND__ + +#include "d_clisrv.h" +#include "../d_ticcmd.h" +#include "../doomdef.h" +#include "../doomtype.h" + +extern tic_t firstticstosend; // min of the nettics +extern tic_t tictoclear; // optimize d_clearticcmd + +extern ticcmd_t localcmds; +extern ticcmd_t localcmds2; +extern boolean cl_packetmissed; + +extern ticcmd_t netcmds[BACKUPTICS][MAXPLAYERS]; + +tic_t ExpandTics(INT32 low, INT32 node); +void D_Clearticcmd(tic_t tic); +void D_ResetTiccmds(void); + +void PT_ClientCmd(SINT8 node, INT32 netconsole); +void PT_ServerTics(SINT8 node, INT32 netconsole); + +// send the client packet to the server +void CL_SendClientCmd(void); + +void SV_SendTics(void); +void Local_Maketic(INT32 realtics); +void SV_Maketic(void); + +#endif diff --git a/src/p_inter.c b/src/p_inter.c index 4d22ba343..490065a1f 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -28,6 +28,7 @@ #include "m_misc.h" #include "v_video.h" // video flags for CEchos #include "f_finale.h" +#include "netcode/net_command.h" // CTF player names #define CTFTEAMCODE(pl) pl->ctfteam ? (pl->ctfteam == 1 ? "\x85" : "\x84") : "" diff --git a/src/p_mobj.c b/src/p_mobj.c index 4ca59285f..807368890 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -36,6 +36,7 @@ #include "p_slopes.h" #include "f_finale.h" #include "m_cond.h" +#include "netcode/net_command.h" static CV_PossibleValue_t CV_BobSpeed[] = {{0, "MIN"}, {4*FRACUNIT, "MAX"}, {0, NULL}}; consvar_t cv_movebob = CVAR_INIT ("movebob", "1.0", CV_FLOAT|CV_SAVE, CV_BobSpeed, NULL); diff --git a/src/p_setup.c b/src/p_setup.c index 175ab3328..4dc37d667 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -87,6 +87,8 @@ #include "taglist.h" +#include "netcode/net_command.h" + // // Map MD5, calculated on level load. // Sent to clients in PT_SERVERINFO. diff --git a/src/p_tick.c b/src/p_tick.c index b1fd367ed..4b724e333 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -26,6 +26,7 @@ #include "r_main.h" #include "r_fps.h" #include "i_video.h" // rendermode +#include "netcode/net_command.h" // Object place #include "m_cheat.h" diff --git a/src/p_user.c b/src/p_user.c index 6bbefcb19..c8657f8c5 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -18,6 +18,7 @@ #include "i_system.h" #include "d_event.h" #include "netcode/d_net.h" +#include "netcode/net_command.h" #include "g_game.h" #include "p_local.h" #include "r_fps.h" From 1a7f42d172e3ec4c68003988436b4c15ef23e765 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Thu, 5 Jan 2023 23:48:44 +0100 Subject: [PATCH 335/586] Declare data exchanged through the network to a new file --- src/netcode/d_clisrv.c | 1 + src/netcode/d_clisrv.h | 313 +------------------------------------- src/netcode/d_net.h | 2 + src/netcode/protocol.h | 335 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 339 insertions(+), 312 deletions(-) create mode 100644 src/netcode/protocol.h diff --git a/src/netcode/d_clisrv.c b/src/netcode/d_clisrv.c index 06e6da751..b834c92f5 100644 --- a/src/netcode/d_clisrv.c +++ b/src/netcode/d_clisrv.c @@ -53,6 +53,7 @@ #include "client_connection.h" #include "tic_command.h" #include "net_command.h" +#include "protocol.h" // // NETWORKING diff --git a/src/netcode/d_clisrv.h b/src/netcode/d_clisrv.h index 8b73170da..691a2787f 100644 --- a/src/netcode/d_clisrv.h +++ b/src/netcode/d_clisrv.h @@ -13,6 +13,7 @@ #ifndef __D_CLISRV__ #define __D_CLISRV__ +#include "protocol.h" #include "../d_ticcmd.h" #include "d_net.h" #include "d_netcmd.h" @@ -21,85 +22,7 @@ #include "../d_player.h" #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. - -If you change the struct or the meaning of a field -therein, increment this number. -*/ -#define PACKETVERSION 4 - -// Network play related stuff. -// There is a data struct that stores network -// communication related stuff, and another -// one that defines the actual packets to -// be transmitted. - -// Networking and tick handling related. -#define BACKUPTICS 1024 #define CLIENTBACKUPTICS 32 -#define MAXTEXTCMD 256 -// -// Packet structure -// -typedef enum -{ - PT_NOTHING, // To send a nop through the network. ^_~ - PT_SERVERCFG, // Server config used in start game - // (must stay 1 for backwards compatibility). - // This is a positive response to a CLIENTJOIN request. - PT_CLIENTCMD, // Ticcmd of the client. - PT_CLIENTMIS, // Same as above with but saying resend from. - PT_CLIENT2CMD, // 2 cmds in the packet for splitscreen. - PT_CLIENT2MIS, // Same as above with but saying resend from - PT_NODEKEEPALIVE, // Same but without ticcmd and consistancy - PT_NODEKEEPALIVEMIS, - PT_SERVERTICS, // All cmds for the tic. - PT_SERVERREFUSE, // Server refuses joiner (reason inside). - PT_SERVERSHUTDOWN, - PT_CLIENTQUIT, // Client closes the connection. - - PT_ASKINFO, // Anyone can ask info of the server. - PT_SERVERINFO, // Send game & server info (gamespy). - PT_PLAYERINFO, // Send information for players in game (gamespy). - PT_REQUESTFILE, // Client requests a file transfer - PT_ASKINFOVIAMS, // Packet from the MS requesting info be sent to new client. - // If this ID changes, update masterserver definition. - - PT_WILLRESENDGAMESTATE, // Hey Client, I am about to resend you the gamestate! - PT_CANRECEIVEGAMESTATE, // Okay Server, I'm ready to receive it, you can go ahead. - PT_RECEIVEDGAMESTATE, // Thank you Server, I am ready to play again! - - PT_SENDINGLUAFILE, // Server telling a client Lua needs to open a file - PT_ASKLUAFILE, // Client telling the server they don't have the file - PT_HASLUAFILE, // Client telling the server they have the file - - // Add non-PT_CANFAIL packet types here to avoid breaking MS compatibility. - - PT_CANFAIL, // This is kind of a priority. Anything bigger than CANFAIL - // allows HSendPacket(*, true, *, *) to return false. - // In addition, this packet can't occupy all the available slots. - - PT_FILEFRAGMENT = PT_CANFAIL, // A part of a file. - PT_FILEACK, - PT_FILERECEIVED, - - PT_TEXTCMD, // Extra text commands from the client. - PT_TEXTCMD2, // Splitscreen text commands. - PT_CLIENTJOIN, // Client wants to join; used in start game. - PT_NODETIMEOUT, // Packet sent to self if the connection times out. - - 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; #ifdef PACKETDROP void Command_Drop(void); @@ -109,229 +32,6 @@ void Command_Droprate(void); void Command_Numnodes(void); #endif -#if defined(_MSC_VER) -#pragma pack(1) -#endif - -// Client to server packet -typedef struct -{ - UINT8 client_tic; - UINT8 resendfrom; - INT16 consistancy; - ticcmd_t cmd; -} ATTRPACK clientcmd_pak; - -// Splitscreen packet -// WARNING: must have the same format of clientcmd_pak, for more easy use -typedef struct -{ - UINT8 client_tic; - UINT8 resendfrom; - INT16 consistancy; - ticcmd_t cmd, cmd2; -} ATTRPACK client2cmd_pak; - -#ifdef _MSC_VER -#pragma warning(disable : 4200) -#endif - -// Server to client packet -// this packet is too large -typedef struct -{ - tic_t starttic; - UINT8 numtics; - UINT8 numslots; // "Slots filled": Highest player number in use plus one. - ticcmd_t cmds[45]; // Normally [BACKUPTIC][MAXPLAYERS] but too large -} ATTRPACK servertics_pak; - -typedef struct -{ - // Server launch stuffs - UINT8 serverplayer; - UINT8 totalslotnum; // "Slots": highest player number in use plus one. - - tic_t gametic; - UINT8 clientnode; - UINT8 gamestate; - - UINT8 gametype; - UINT8 modifiedgame; - - char server_context[8]; // Unique context id, generated at server startup. -} ATTRPACK serverconfig_pak; - -typedef struct -{ - UINT8 fileid; - UINT32 filesize; - UINT8 iteration; - UINT32 position; - UINT16 size; - UINT8 data[0]; // Size is variable using hardware_MAXPACKETLENGTH -} ATTRPACK filetx_pak; - -typedef struct -{ - UINT32 start; - UINT32 acks; -} ATTRPACK fileacksegment_t; - -typedef struct -{ - UINT8 fileid; - UINT8 iteration; - UINT8 numsegments; - fileacksegment_t segments[0]; -} ATTRPACK fileack_pak; - -#ifdef _MSC_VER -#pragma warning(default : 4200) -#endif - -#define MAXAPPLICATION 16 - -typedef struct -{ - UINT8 modversion; - char application[MAXAPPLICATION]; - UINT8 localplayers; - UINT8 mode; - 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, - REFUSE_BANNED, -}; - -#define MAXSERVERNAME 32 -#define MAXFILENEEDED 915 -// This packet is too large -typedef struct -{ - /* - In the old packet, 'version' is the first field. Now that field is set - to 255 always, so older versions won't be confused with the new - versions or vice-versa. - */ - UINT8 _255; - UINT8 packetversion; - char application[MAXAPPLICATION]; - UINT8 version; - UINT8 subversion; - UINT8 numberofplayer; - UINT8 maxplayer; - UINT8 refusereason; // 0: joinable, REFUSE enum - char gametypename[24]; - UINT8 modifiedgame; - UINT8 cheatsenabled; - UINT8 flags; - UINT8 fileneedednum; - tic_t time; - tic_t leveltime; - char servername[MAXSERVERNAME]; - char mapname[8]; - char maptitle[33]; - unsigned char mapmd5[16]; - UINT8 actnum; - UINT8 iszone; - UINT8 fileneeded[MAXFILENEEDED]; // is filled with writexxx (byteptr.h) -} ATTRPACK serverinfo_pak; - -typedef struct -{ - char reason[255]; -} ATTRPACK serverrefuse_pak; - -typedef struct -{ - UINT8 version; - tic_t time; // used for ping evaluation -} ATTRPACK askinfo_pak; - -typedef struct -{ - char clientaddr[22]; - tic_t time; // used for ping evaluation -} ATTRPACK msaskinfo_pak; - -// Shorter player information for external use. -typedef struct -{ - UINT8 num; - char name[MAXPLAYERNAME+1]; - UINT8 address[4]; // sending another string would run us up against MAXPACKETLENGTH - UINT8 team; - UINT8 skin; - UINT8 data; // Color is first four bits, hasflag, isit and issuper have one bit each, the last is unused. - UINT32 score; - UINT16 timeinserver; // In seconds. -} ATTRPACK plrinfo; - -// Shortest player information for join during intermission. -typedef struct -{ - char name[MAXPLAYERNAME+1]; - UINT8 skin; - UINT16 color; - UINT32 pflags; - UINT32 score; - 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 -// -typedef struct -{ - UINT32 checksum; - UINT8 ack; // If not zero the node asks for acknowledgement, the receiver must resend the ack - UINT8 ackreturn; // The return of the ack number - - UINT8 packettype; - UINT8 reserved; // Padding - union - { - clientcmd_pak clientpak; // 144 bytes - client2cmd_pak client2pak; // 200 bytes - servertics_pak serverpak; // 132495 bytes (more around 360, no?) - serverconfig_pak servercfg; // 773 bytes - UINT8 textcmd[MAXTEXTCMD+1]; // 66049 bytes (wut??? 64k??? More like 257 bytes...) - filetx_pak filetxpak; // 139 bytes - fileack_pak fileack; - UINT8 filereceived; - clientconfig_pak clientcfg; // 136 bytes - UINT8 md5sum[16]; - serverinfo_pak serverinfo; // 1024 bytes - serverrefuse_pak serverrefuse; // 65025 bytes (somehow I feel like those values are garbage...) - askinfo_pak askinfo; // 61 bytes - 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; - -#if defined(_MSC_VER) -#pragma pack() -#endif - extern INT32 mapchangepending; // Points inside doomcom @@ -341,19 +41,8 @@ extern consvar_t cv_showjoinaddress; extern consvar_t cv_playbackspeed; #define BASEPACKETSIZE offsetof(doomdata_t, u) -#define FILETXHEADER offsetof(filetx_pak, data) #define BASESERVERTICSSIZE offsetof(doomdata_t, u.serverpak.cmds[0]) -#define KICK_MSG_GO_AWAY 1 -#define KICK_MSG_CON_FAIL 2 -#define KICK_MSG_PLAYER_QUIT 3 -#define KICK_MSG_TIMEOUT 4 -#define KICK_MSG_BANNED 5 -#define KICK_MSG_PING_HIGH 6 -#define KICK_MSG_CUSTOM_KICK 7 -#define KICK_MSG_CUSTOM_BAN 8 -#define KICK_MSG_KEEP_BODY 0x80 - typedef enum { KR_KICK = 1, //Kicked by server diff --git a/src/netcode/d_net.h b/src/netcode/d_net.h index 803b49d74..857c3463c 100644 --- a/src/netcode/d_net.h +++ b/src/netcode/d_net.h @@ -18,6 +18,8 @@ #ifndef __D_NET__ #define __D_NET__ +#include "../doomtype.h" + // Max computers in a game // 127 is probably as high as this can go, because // SINT8 is used for nodes sometimes >:( diff --git a/src/netcode/protocol.h b/src/netcode/protocol.h new file mode 100644 index 000000000..566d10d8c --- /dev/null +++ b/src/netcode/protocol.h @@ -0,0 +1,335 @@ +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2022 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 protocol.h +/// \brief Data exchanged through the network + +#ifndef __PROTOCOL__ +#define __PROTOCOL__ + +#include "d_net.h" +#include "../d_ticcmd.h" +#include "../doomdef.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. + +If you change the struct or the meaning of a field +therein, increment this number. +*/ +#define PACKETVERSION 4 + +// Network play related stuff. +// There is a data struct that stores network +// communication related stuff, and another +// one that defines the actual packets to +// be transmitted. + +#define BACKUPTICS 1024 +#define MAXTEXTCMD 256 + +// +// Packet structure +// +typedef enum +{ + PT_NOTHING, // To send a nop through the network. ^_~ + PT_SERVERCFG, // Server config used in start game + // (must stay 1 for backwards compatibility). + // This is a positive response to a CLIENTJOIN request. + PT_CLIENTCMD, // Ticcmd of the client. + PT_CLIENTMIS, // Same as above with but saying resend from. + PT_CLIENT2CMD, // 2 cmds in the packet for splitscreen. + PT_CLIENT2MIS, // Same as above with but saying resend from + PT_NODEKEEPALIVE, // Same but without ticcmd and consistancy + PT_NODEKEEPALIVEMIS, + PT_SERVERTICS, // All cmds for the tic. + PT_SERVERREFUSE, // Server refuses joiner (reason inside). + PT_SERVERSHUTDOWN, + PT_CLIENTQUIT, // Client closes the connection. + + PT_ASKINFO, // Anyone can ask info of the server. + PT_SERVERINFO, // Send game & server info (gamespy). + PT_PLAYERINFO, // Send information for players in game (gamespy). + PT_REQUESTFILE, // Client requests a file transfer + PT_ASKINFOVIAMS, // Packet from the MS requesting info be sent to new client. + // If this ID changes, update masterserver definition. + + PT_WILLRESENDGAMESTATE, // Hey Client, I am about to resend you the gamestate! + PT_CANRECEIVEGAMESTATE, // Okay Server, I'm ready to receive it, you can go ahead. + PT_RECEIVEDGAMESTATE, // Thank you Server, I am ready to play again! + + PT_SENDINGLUAFILE, // Server telling a client Lua needs to open a file + PT_ASKLUAFILE, // Client telling the server they don't have the file + PT_HASLUAFILE, // Client telling the server they have the file + + // Add non-PT_CANFAIL packet types here to avoid breaking MS compatibility. + + PT_CANFAIL, // This is kind of a priority. Anything bigger than CANFAIL + // allows HSendPacket(*, true, *, *) to return false. + // In addition, this packet can't occupy all the available slots. + + PT_FILEFRAGMENT = PT_CANFAIL, // A part of a file. + PT_FILEACK, + PT_FILERECEIVED, + + PT_TEXTCMD, // Extra text commands from the client. + PT_TEXTCMD2, // Splitscreen text commands. + PT_CLIENTJOIN, // Client wants to join; used in start game. + PT_NODETIMEOUT, // Packet sent to self if the connection times out. + + 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; + +#if defined(_MSC_VER) +#pragma pack(1) +#endif + +// Client to server packet +typedef struct +{ + UINT8 client_tic; + UINT8 resendfrom; + INT16 consistancy; + ticcmd_t cmd; +} ATTRPACK clientcmd_pak; + +// Splitscreen packet +// WARNING: must have the same format of clientcmd_pak, for more easy use +typedef struct +{ + UINT8 client_tic; + UINT8 resendfrom; + INT16 consistancy; + ticcmd_t cmd, cmd2; +} ATTRPACK client2cmd_pak; + +#ifdef _MSC_VER +#pragma warning(disable : 4200) +#endif + +// Server to client packet +// this packet is too large +typedef struct +{ + tic_t starttic; + UINT8 numtics; + UINT8 numslots; // "Slots filled": Highest player number in use plus one. + ticcmd_t cmds[45]; // Normally [BACKUPTIC][MAXPLAYERS] but too large +} ATTRPACK servertics_pak; + +typedef struct +{ + // Server launch stuffs + UINT8 serverplayer; + UINT8 totalslotnum; // "Slots": highest player number in use plus one. + + tic_t gametic; + UINT8 clientnode; + UINT8 gamestate; + + UINT8 gametype; + UINT8 modifiedgame; + + char server_context[8]; // Unique context id, generated at server startup. +} ATTRPACK serverconfig_pak; + +typedef struct +{ + UINT8 fileid; + UINT32 filesize; + UINT8 iteration; + UINT32 position; + UINT16 size; + UINT8 data[0]; // Size is variable using hardware_MAXPACKETLENGTH +} ATTRPACK filetx_pak; + +typedef struct +{ + UINT32 start; + UINT32 acks; +} ATTRPACK fileacksegment_t; + +typedef struct +{ + UINT8 fileid; + UINT8 iteration; + UINT8 numsegments; + fileacksegment_t segments[0]; +} ATTRPACK fileack_pak; + +#ifdef _MSC_VER +#pragma warning(default : 4200) +#endif + +#define MAXAPPLICATION 16 + +typedef struct +{ + UINT8 modversion; + char application[MAXAPPLICATION]; + UINT8 localplayers; + UINT8 mode; + 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, + REFUSE_BANNED, +}; + +#define MAXSERVERNAME 32 +#define MAXFILENEEDED 915 + +// This packet is too large +typedef struct +{ + /* + In the old packet, 'version' is the first field. Now that field is set + to 255 always, so older versions won't be confused with the new + versions or vice-versa. + */ + UINT8 _255; + UINT8 packetversion; + char application[MAXAPPLICATION]; + UINT8 version; + UINT8 subversion; + UINT8 numberofplayer; + UINT8 maxplayer; + UINT8 refusereason; // 0: joinable, REFUSE enum + char gametypename[24]; + UINT8 modifiedgame; + UINT8 cheatsenabled; + UINT8 flags; + UINT8 fileneedednum; + tic_t time; + tic_t leveltime; + char servername[MAXSERVERNAME]; + char mapname[8]; + char maptitle[33]; + unsigned char mapmd5[16]; + UINT8 actnum; + UINT8 iszone; + UINT8 fileneeded[MAXFILENEEDED]; // is filled with writexxx (byteptr.h) +} ATTRPACK serverinfo_pak; + +typedef struct +{ + char reason[255]; +} ATTRPACK serverrefuse_pak; + +typedef struct +{ + UINT8 version; + tic_t time; // used for ping evaluation +} ATTRPACK askinfo_pak; + +typedef struct +{ + char clientaddr[22]; + tic_t time; // used for ping evaluation +} ATTRPACK msaskinfo_pak; + +// Shorter player information for external use. +typedef struct +{ + UINT8 num; + char name[MAXPLAYERNAME+1]; + UINT8 address[4]; // sending another string would run us up against MAXPACKETLENGTH + UINT8 team; + UINT8 skin; + UINT8 data; // Color is first four bits, hasflag, isit and issuper have one bit each, the last is unused. + UINT32 score; + UINT16 timeinserver; // In seconds. +} ATTRPACK plrinfo; + +// Shortest player information for join during intermission. +typedef struct +{ + char name[MAXPLAYERNAME+1]; + UINT8 skin; + UINT16 color; + UINT32 pflags; + UINT32 score; + 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 +// +typedef struct +{ + UINT32 checksum; + UINT8 ack; // If not zero the node asks for acknowledgement, the receiver must resend the ack + UINT8 ackreturn; // The return of the ack number + + UINT8 packettype; + UINT8 reserved; // Padding + union + { + clientcmd_pak clientpak; // 144 bytes + client2cmd_pak client2pak; // 200 bytes + servertics_pak serverpak; // 132495 bytes (more around 360, no?) + serverconfig_pak servercfg; // 773 bytes + UINT8 textcmd[MAXTEXTCMD+1]; // 66049 bytes (wut??? 64k??? More like 257 bytes...) + filetx_pak filetxpak; // 139 bytes + fileack_pak fileack; + UINT8 filereceived; + clientconfig_pak clientcfg; // 136 bytes + UINT8 md5sum[16]; + serverinfo_pak serverinfo; // 1024 bytes + serverrefuse_pak serverrefuse; // 65025 bytes (somehow I feel like those values are garbage...) + askinfo_pak askinfo; // 61 bytes + 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; + +#if defined(_MSC_VER) +#pragma pack() +#endif + +#define FILETXHEADER offsetof(filetx_pak, data) + +#define KICK_MSG_GO_AWAY 1 +#define KICK_MSG_CON_FAIL 2 +#define KICK_MSG_PLAYER_QUIT 3 +#define KICK_MSG_TIMEOUT 4 +#define KICK_MSG_BANNED 5 +#define KICK_MSG_PING_HIGH 6 +#define KICK_MSG_CUSTOM_KICK 7 +#define KICK_MSG_CUSTOM_BAN 8 +#define KICK_MSG_KEEP_BODY 0x80 + +#endif From de46eef068b5fa241c2340edf88a6ff24c74c24c Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sat, 7 Jan 2023 13:01:48 +0100 Subject: [PATCH 336/586] Move gamestate handling to a new file --- src/hu_stuff.c | 1 + src/netcode/Sourcefile | 1 + src/netcode/d_clisrv.c | 308 +---------------------------- src/netcode/d_clisrv.h | 5 - src/netcode/gamestate.c | 341 ++++++++++++++++++++++++++++++++ src/netcode/gamestate.h | 31 +++ src/netcode/net_command.c | 1 + src/netcode/server_connection.c | 1 + src/netcode/tic_command.c | 1 + 9 files changed, 378 insertions(+), 312 deletions(-) create mode 100644 src/netcode/gamestate.c create mode 100644 src/netcode/gamestate.h diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 1e5e47df6..dc4dfe4b7 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -21,6 +21,7 @@ #include "netcode/d_clisrv.h" #include "netcode/net_command.h" +#include "netcode/gamestate.h" #include "g_game.h" #include "g_input.h" diff --git a/src/netcode/Sourcefile b/src/netcode/Sourcefile index 1039b218a..c59050367 100644 --- a/src/netcode/Sourcefile +++ b/src/netcode/Sourcefile @@ -3,6 +3,7 @@ server_connection.c client_connection.c tic_command.c net_command.c +gamestate.c d_net.c d_netcmd.c d_netfil.c diff --git a/src/netcode/d_clisrv.c b/src/netcode/d_clisrv.c index b834c92f5..8ba10f6ea 100644 --- a/src/netcode/d_clisrv.c +++ b/src/netcode/d_clisrv.c @@ -53,6 +53,7 @@ #include "client_connection.h" #include "tic_command.h" #include "net_command.h" +#include "gamestate.h" #include "protocol.h" // @@ -93,18 +94,12 @@ tic_t maketic; INT16 consistancy[BACKUPTICS]; -UINT8 hu_redownloadinggamestate = 0; - // true when a player is connecting or disconnecting so that the gameplay has stopped in its tracks boolean hu_stopped = false; UINT8 adminpassmd5[16]; boolean adminpasswordset = false; -// Client specific -// here it is for the secondary local player (splitscreen) -static boolean cl_redownloadinggamestate = false; - tic_t neededtic; SINT8 servernode = 0; // the number of the server node @@ -122,233 +117,6 @@ consvar_t cv_playbackspeed = CVAR_INIT ("playbackspeed", "1", 0, playbackspeed_c // of 512 bytes is like 0.1) UINT16 software_MAXPACKETLENGTH; -#define SAVEGAMESIZE (768*1024) - -boolean SV_ResendingSavegameToAnyone(void) -{ - INT32 i; - - for (i = 0; i < MAXNETNODES; i++) - if (netnodes[i].resendingsavegame) - return true; - return false; -} - -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 - netnodes[node].sendingsavegame = true; - netnodes[node].freezetimeout = 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" - - -void CL_LoadReceivedSavegame(boolean reloading) -{ - UINT8 *savebuffer = NULL; - size_t length, decompressedlen; - char tmpsave[256]; - - FreeFileNeeded(); - - 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; - - P_StopRumble(NULL); - - // 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"); - } - - // 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++) - { - LUA_InvalidatePlayer(&players[i]); - 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")); -} - typedef struct banreason_s { char *reason; @@ -1006,34 +774,6 @@ static void Command_Kick(void) 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; - } -} - static void Got_KickCmd(UINT8 **p, INT32 playernum) { INT32 pnum, msg; @@ -1736,17 +1476,6 @@ static void PT_ClientQuit(SINT8 node, INT32 netconsole) netnodes[node].ingame = false; } -static void PT_CanReceiveGamestate(SINT8 node) -{ - if (client || netnodes[node].sendingsavegame) - return; - - CONS_Printf(M_GetText("Resending game state to %s...\n"), player_names[netnodes[node].player]); - - SV_SendSaveGame(node, true); // Resend a complete game state - netnodes[node].resendingsavegame = true; -} - static void PT_AskLuaFile(SINT8 node) { if (server && luafiletransfers && luafiletransfers->nodestatus[node] == LFTNS_ASKED) @@ -1759,13 +1488,6 @@ static void PT_HasLuaFile(SINT8 node) SV_HandleLuaFileSent(node); } -static void PT_ReceivedGamestate(SINT8 node) -{ - netnodes[node].sendingsavegame = false; - netnodes[node].resendingsavegame = false; - netnodes[node].savegameresendcooldown = I_GetTime() + 5 * TICRATE; -} - static void PT_Ping(SINT8 node, INT32 netconsole) { // Only accept PT_PING from the server. @@ -1789,34 +1511,6 @@ static void PT_Ping(SINT8 node, INT32 netconsole) } } -static void PT_WillResendGamestate(SINT8 node) -{ - (void)node; - - 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_SendingLuaFile(SINT8 node) { (void)node; diff --git a/src/netcode/d_clisrv.h b/src/netcode/d_clisrv.h index 691a2787f..d5bafe750 100644 --- a/src/netcode/d_clisrv.h +++ b/src/netcode/d_clisrv.h @@ -89,19 +89,16 @@ void NetUpdate(void); void GetPackets(void); void ResetNode(INT32 node); INT16 Consistancy(void); -boolean SV_ResendingSavegameToAnyone(void); void SV_StartSinglePlayerServer(void); void SV_SpawnServer(void); void SV_StopServer(void); void SV_ResetServer(void); -void SV_SendSaveGame(INT32 node, boolean resending); void CL_AddSplitscreenPlayer(void); void CL_RemoveSplitscreenPlayer(void); void CL_Reset(void); void CL_ClearPlayer(INT32 playernum); void CL_RemovePlayer(INT32 playernum, kickreason_t reason); -void CL_LoadReceivedSavegame(boolean reloading); // Is there a game running boolean Playing(void); @@ -130,8 +127,6 @@ tic_t GetLag(INT32 node); void D_MD5PasswordPass(const UINT8 *buffer, size_t len, const char *salt, void *dest); -extern UINT8 hu_redownloadinggamestate; - extern UINT8 adminpassmd5[16]; extern boolean adminpasswordset; diff --git a/src/netcode/gamestate.c b/src/netcode/gamestate.c new file mode 100644 index 000000000..4a3e9f3af --- /dev/null +++ b/src/netcode/gamestate.c @@ -0,0 +1,341 @@ +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2022 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 gamestate.c +/// \brief Gamestate (re)sending + +#include "d_clisrv.h" +#include "d_netfil.h" +#include "gamestate.h" +#include "i_net.h" +#include "protocol.h" +#include "server_connection.h" +#include "../am_map.h" +#include "../byteptr.h" +#include "../console.h" +#include "../d_main.h" +#include "../doomstat.h" +#include "../doomtype.h" +#include "../f_finale.h" +#include "../g_demo.h" +#include "../g_game.h" +#include "../i_time.h" +#include "../lua_script.h" +#include "../lzf.h" +#include "../m_misc.h" +#include "../p_haptic.h" +#include "../p_local.h" +#include "../p_saveg.h" +#include "../r_main.h" +#include "../tables.h" +#include "../z_zone.h" + +#define SAVEGAMESIZE (768*1024) + +UINT8 hu_redownloadinggamestate = 0; +boolean cl_redownloadinggamestate = false; + +boolean SV_ResendingSavegameToAnyone(void) +{ + INT32 i; + + for (i = 0; i < MAXNETNODES; i++) + if (netnodes[i].resendingsavegame) + return true; + return false; +} + +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 + netnodes[node].sendingsavegame = true; + netnodes[node].freezetimeout = 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); + +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" + + +void CL_LoadReceivedSavegame(boolean reloading) +{ + UINT8 *savebuffer = NULL; + size_t length, decompressedlen; + char tmpsave[256]; + + FreeFileNeeded(); + + 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; + + P_StopRumble(NULL); + + // 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"); + } + + // 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); +} + +void CL_ReloadReceivedSavegame(void) +{ + INT32 i; + + for (i = 0; i < MAXPLAYERS; i++) + { + LUA_InvalidatePlayer(&players[i]); + 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")); +} + +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; + } +} + +void PT_CanReceiveGamestate(SINT8 node) +{ + if (client || netnodes[node].sendingsavegame) + return; + + CONS_Printf(M_GetText("Resending game state to %s...\n"), player_names[netnodes[node].player]); + + SV_SendSaveGame(node, true); // Resend a complete game state + netnodes[node].resendingsavegame = true; +} + +void PT_ReceivedGamestate(SINT8 node) +{ + netnodes[node].sendingsavegame = false; + netnodes[node].resendingsavegame = false; + netnodes[node].savegameresendcooldown = I_GetTime() + 5 * TICRATE; +} + +void PT_WillResendGamestate(SINT8 node) +{ + (void)node; + + 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; +} diff --git a/src/netcode/gamestate.h b/src/netcode/gamestate.h new file mode 100644 index 000000000..9d2779772 --- /dev/null +++ b/src/netcode/gamestate.h @@ -0,0 +1,31 @@ +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2022 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 gamestate.h +/// \brief Gamestate (re)sending + +#ifndef __GAMESTATE__ +#define __GAMESTATE__ + +#include "../doomtype.h" + +extern UINT8 hu_redownloadinggamestate; +extern boolean cl_redownloadinggamestate; + +boolean SV_ResendingSavegameToAnyone(void); +void SV_SendSaveGame(INT32 node, boolean resending); +void SV_SavedGame(void); +void CL_LoadReceivedSavegame(boolean reloading); +void CL_ReloadReceivedSavegame(void); +void Command_ResendGamestate(void); +void PT_CanReceiveGamestate(SINT8 node); +void PT_ReceivedGamestate(SINT8 node); +void PT_WillResendGamestate(SINT8 node); + +#endif diff --git a/src/netcode/net_command.c b/src/netcode/net_command.c index eeb479d21..6f9f3f79a 100644 --- a/src/netcode/net_command.c +++ b/src/netcode/net_command.c @@ -12,6 +12,7 @@ #include "net_command.h" #include "tic_command.h" +#include "gamestate.h" #include "d_clisrv.h" #include "i_net.h" #include "../g_game.h" diff --git a/src/netcode/server_connection.c b/src/netcode/server_connection.c index b776db422..28d97c052 100644 --- a/src/netcode/server_connection.c +++ b/src/netcode/server_connection.c @@ -16,6 +16,7 @@ #include "d_netfil.h" #include "mserv.h" #include "net_command.h" +#include "gamestate.h" #include "../byteptr.h" #include "../g_game.h" #include "../g_state.h" diff --git a/src/netcode/tic_command.c b/src/netcode/tic_command.c index e7df895ff..180d54e69 100644 --- a/src/netcode/tic_command.c +++ b/src/netcode/tic_command.c @@ -14,6 +14,7 @@ #include "d_clisrv.h" #include "net_command.h" #include "client_connection.h" +#include "gamestate.h" #include "i_net.h" #include "../d_main.h" #include "../g_game.h" From 91f9f53cfc45503767e3fa7f2724c3151bab91eb Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sat, 7 Jan 2023 13:37:33 +0100 Subject: [PATCH 337/586] Remove unused stuff --- src/netcode/d_clisrv.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/netcode/d_clisrv.c b/src/netcode/d_clisrv.c index 8ba10f6ea..36116b931 100644 --- a/src/netcode/d_clisrv.c +++ b/src/netcode/d_clisrv.c @@ -69,13 +69,9 @@ // 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) From d841bfb23647a2f5e97c863b5cb729fcde87fedd Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sat, 7 Jan 2023 15:57:04 +0100 Subject: [PATCH 338/586] Move netcode console variables to appropriate files --- src/m_menu.c | 1 + src/netcode/client_connection.c | 1 + src/netcode/d_clisrv.c | 40 +++++++++------------------------ src/netcode/d_clisrv.h | 7 +----- src/netcode/d_netfil.c | 9 ++++++++ src/netcode/d_netfil.h | 2 ++ src/netcode/net_command.c | 1 + src/netcode/server_connection.c | 14 ++++++++++++ src/netcode/server_connection.h | 2 ++ src/p_tick.c | 1 + 10 files changed, 43 insertions(+), 35 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index f0691c17f..6a8d59f48 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -55,6 +55,7 @@ #include "netcode/d_net.h" #include "netcode/mserv.h" +#include "netcode/server_connection.h" #include "netcode/client_connection.h" #include "m_misc.h" #include "m_anigif.h" diff --git a/src/netcode/client_connection.c b/src/netcode/client_connection.c index bfaea2e81..a00157a50 100644 --- a/src/netcode/client_connection.c +++ b/src/netcode/client_connection.c @@ -11,6 +11,7 @@ /// \brief Client connection handling #include "client_connection.h" +#include "gamestate.h" #include "d_clisrv.h" #include "d_netfil.h" #include "../d_main.h" diff --git a/src/netcode/d_clisrv.c b/src/netcode/d_clisrv.c index 36116b931..0b1c487d8 100644 --- a/src/netcode/d_clisrv.c +++ b/src/netcode/d_clisrv.c @@ -103,11 +103,6 @@ SINT8 servernode = 0; // the number of the server node /// \todo WORK! boolean acceptnewnode = true; -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); - // 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) @@ -123,6 +118,17 @@ typedef struct banreason_s static banreason_t *reasontail = NULL; //last entry, use prev static banreason_t *reasonhead = NULL; //1st entry, use next +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); + +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); + +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 void Command_ShowBan(void) //Print out ban list { size_t i; @@ -961,30 +967,6 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum) CL_RemovePlayer(pnum, kickreason); } -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); -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", "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); -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"}, {204800, "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[] = {{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); // called one time at init diff --git a/src/netcode/d_clisrv.h b/src/netcode/d_clisrv.h index d5bafe750..9cb3ef3e8 100644 --- a/src/netcode/d_clisrv.h +++ b/src/netcode/d_clisrv.h @@ -37,9 +37,6 @@ extern INT32 mapchangepending; // Points inside doomcom extern doomdata_t *netbuffer; -extern consvar_t cv_showjoinaddress; -extern consvar_t cv_playbackspeed; - #define BASEPACKETSIZE offsetof(doomdata_t, u) #define BASESERVERTICSSIZE offsetof(doomdata_t, u.serverpak.cmds[0]) @@ -76,9 +73,7 @@ extern UINT32 realpingtable[MAXPLAYERS]; extern UINT32 playerpingtable[MAXPLAYERS]; extern tic_t servermaxping; -extern consvar_t cv_netticbuffer, cv_allownewplayer, cv_maxplayers, cv_joindelay, cv_rejointimeout; -extern consvar_t cv_resynchattempts, cv_blamecfail; -extern consvar_t cv_maxsend, cv_noticedownload, cv_downloadspeed; +extern consvar_t cv_netticbuffer, cv_resynchattempts, cv_blamecfail, cv_playbackspeed; // Used in d_net, the only dependence void D_ClientServerInit(void); diff --git a/src/netcode/d_netfil.c b/src/netcode/d_netfil.c index e581be2ac..205abf713 100644 --- a/src/netcode/d_netfil.c +++ b/src/netcode/d_netfil.c @@ -116,6 +116,15 @@ boolean waitingforluafiletransfer = false; boolean waitingforluafilecommand = false; char luafiledir[256 + 16] = "luafiles"; +// max file size to send to a player (in kilobytes) +static CV_PossibleValue_t maxsend_cons_t[] = {{0, "MIN"}, {204800, "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[] = {{1, "MIN"}, {300, "MAX"}, {0, NULL}}; +consvar_t cv_downloadspeed = CVAR_INIT ("downloadspeed", "16", CV_SAVE|CV_NETVAR, downloadspeed_cons_t, NULL); static UINT16 GetWadNumFromFileNeededId(UINT8 id) { diff --git a/src/netcode/d_netfil.h b/src/netcode/d_netfil.h index 732efcd5e..850e24d49 100644 --- a/src/netcode/d_netfil.h +++ b/src/netcode/d_netfil.h @@ -76,6 +76,8 @@ extern UINT32 downloadcompletedsize; extern INT32 totalfilesrequestednum; extern UINT32 totalfilesrequestedsize; +extern consvar_t cv_maxsend, cv_noticedownload, cv_downloadspeed; + void AllocFileNeeded(INT32 size); void FreeFileNeeded(void); UINT8 *PutFileNeeded(UINT16 firstfile); diff --git a/src/netcode/net_command.c b/src/netcode/net_command.c index 6f9f3f79a..95a49a959 100644 --- a/src/netcode/net_command.c +++ b/src/netcode/net_command.c @@ -13,6 +13,7 @@ #include "net_command.h" #include "tic_command.h" #include "gamestate.h" +#include "server_connection.h" #include "d_clisrv.h" #include "i_net.h" #include "../g_game.h" diff --git a/src/netcode/server_connection.c b/src/netcode/server_connection.c index 28d97c052..ce1192475 100644 --- a/src/netcode/server_connection.c +++ b/src/netcode/server_connection.c @@ -22,6 +22,7 @@ #include "../g_state.h" #include "../p_setup.h" #include "../p_tick.h" +#include "../command.h" #include "../doomstat.h" // Minimum timeout for sending the savegame @@ -38,6 +39,19 @@ char playeraddress[MAXPLAYERS][64]; UINT8 player_joining = false; +consvar_t cv_showjoinaddress = CVAR_INIT ("showjoinaddress", "Off", CV_SAVE|CV_NETVAR, CV_OnOff, NULL); + +consvar_t cv_allownewplayer = CVAR_INIT ("allowjoin", "On", CV_SAVE|CV_NETVAR, CV_OnOff, NULL); + +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", "2", CV_SAVE|CV_NETVAR|CV_FLOAT, rejointimeout_cons_t, NULL); + static INT32 FindRejoinerNum(SINT8 node) { char strippednodeaddress[64]; diff --git a/src/netcode/server_connection.h b/src/netcode/server_connection.h index 4204db2e6..a40bd4603 100644 --- a/src/netcode/server_connection.h +++ b/src/netcode/server_connection.h @@ -13,6 +13,7 @@ #ifndef __D_SERVER_CONNECTION__ #define __D_SERVER_CONNECTION__ +#include "../command.h" #include "../doomdef.h" #include "../doomtype.h" @@ -25,5 +26,6 @@ extern tic_t jointimeout; extern tic_t joindelay; extern char playeraddress[MAXPLAYERS][64]; extern UINT8 player_joining; +extern consvar_t cv_showjoinaddress, cv_allownewplayer, cv_maxplayers, cv_joindelay, cv_rejointimeout; #endif diff --git a/src/p_tick.c b/src/p_tick.c index 4b724e333..2473d5fac 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -27,6 +27,7 @@ #include "r_fps.h" #include "i_video.h" // rendermode #include "netcode/net_command.h" +#include "netcode/server_connection.h" // Object place #include "m_cheat.h" From 332a0f6b9322c07a5ec36616b621e365a2569c29 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sat, 7 Jan 2023 15:57:17 +0100 Subject: [PATCH 339/586] Add missing PT_ prefix to a few packet handlers --- src/netcode/client_connection.c | 4 ++-- src/netcode/client_connection.h | 2 +- src/netcode/d_clisrv.c | 12 ++++++------ src/netcode/server_connection.c | 2 +- src/netcode/server_connection.h | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/netcode/client_connection.c b/src/netcode/client_connection.c index a00157a50..bed445a64 100644 --- a/src/netcode/client_connection.c +++ b/src/netcode/client_connection.c @@ -1052,7 +1052,7 @@ void CL_ConnectToServer(void) * \note What happens if the packet comes from a client or something like that? * */ -void HandleServerInfo(SINT8 node) +void PT_ServerInfo(SINT8 node) { // compute ping in ms const tic_t ticnow = I_GetTime(); @@ -1173,7 +1173,7 @@ void PT_ServerCFG(SINT8 node) /// \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... + /// Also, according to PT_Connect, 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; diff --git a/src/netcode/client_connection.h b/src/netcode/client_connection.h index a76411ba6..74cff61ff 100644 --- a/src/netcode/client_connection.h +++ b/src/netcode/client_connection.h @@ -53,7 +53,7 @@ void CL_UpdateServerList(boolean internetsearch, INT32 room); void CL_ConnectToServer(void); boolean CL_SendJoin(void); -void HandleServerInfo(SINT8 node); +void PT_ServerInfo(SINT8 node); void PT_MoreFilesNeeded(SINT8 node); void PT_ServerRefuse(SINT8 node); void PT_ServerCFG(SINT8 node); diff --git a/src/netcode/d_clisrv.c b/src/netcode/d_clisrv.c index 0b1c487d8..4589c83d3 100644 --- a/src/netcode/d_clisrv.c +++ b/src/netcode/d_clisrv.c @@ -1358,7 +1358,7 @@ void SV_StartSinglePlayerServer(void) * \param node The packet sender (should be the server) * */ -static void HandleShutdown(SINT8 node) +static void PT_Shutdown(SINT8 node) { (void)node; LUA_HookBool(false, HOOK(GameQuit)); @@ -1373,7 +1373,7 @@ static void HandleShutdown(SINT8 node) * \param node The packet sender (should be the server) * */ -static void HandleTimeout(SINT8 node) +static void PT_Timeout(SINT8 node) { (void)node; LUA_HookBool(false, HOOK(GameQuit)); @@ -1608,26 +1608,26 @@ void GetPackets(void) if (netbuffer->packettype == PT_CLIENTJOIN && server) { - HandleConnect(node); + PT_Connect(node); continue; } if (node == servernode && client && cl_mode != CL_SEARCHING) { if (netbuffer->packettype == PT_SERVERSHUTDOWN) { - HandleShutdown(node); + PT_Shutdown(node); continue; } if (netbuffer->packettype == PT_NODETIMEOUT) { - HandleTimeout(node); + PT_Timeout(node); continue; } } if (netbuffer->packettype == PT_SERVERINFO) { - HandleServerInfo(node); + PT_ServerInfo(node); continue; } diff --git a/src/netcode/server_connection.c b/src/netcode/server_connection.c index ce1192475..e37c45951 100644 --- a/src/netcode/server_connection.c +++ b/src/netcode/server_connection.c @@ -422,7 +422,7 @@ GetRefuseMessage (SINT8 node, INT32 rejoinernum) * \param node The packet sender * */ -void HandleConnect(SINT8 node) +void PT_Connect(SINT8 node) { char names[MAXSPLITSCREENPLAYERS][MAXPLAYERNAME + 1]; INT32 numplayers = netbuffer->u.clientcfg.localplayers; diff --git a/src/netcode/server_connection.h b/src/netcode/server_connection.h index a40bd4603..585c9e428 100644 --- a/src/netcode/server_connection.h +++ b/src/netcode/server_connection.h @@ -17,7 +17,7 @@ #include "../doomdef.h" #include "../doomtype.h" -void HandleConnect(SINT8 node); +void PT_Connect(SINT8 node); void PT_AskInfoViaMS(SINT8 node); void PT_TellFilesNeeded(SINT8 node); void PT_AskInfo(SINT8 node); From 39556e8af74d2d34976159b7654a9af684152d14 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sat, 7 Jan 2023 16:14:41 +0100 Subject: [PATCH 340/586] Add missing _pak suffix to a few packet structures --- src/netcode/protocol.h | 8 ++++---- src/netcode/server_connection.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/netcode/protocol.h b/src/netcode/protocol.h index 566d10d8c..1eba9286b 100644 --- a/src/netcode/protocol.h +++ b/src/netcode/protocol.h @@ -260,7 +260,7 @@ typedef struct UINT8 data; // Color is first four bits, hasflag, isit and issuper have one bit each, the last is unused. UINT32 score; UINT16 timeinserver; // In seconds. -} ATTRPACK plrinfo; +} ATTRPACK plrinfo_pak; // Shortest player information for join during intermission. typedef struct @@ -271,7 +271,7 @@ typedef struct UINT32 pflags; UINT32 score; UINT8 ctfteam; -} ATTRPACK plrconfig; +} ATTRPACK plrconfig_pak; typedef struct { @@ -308,8 +308,8 @@ typedef struct serverrefuse_pak serverrefuse; // 65025 bytes (somehow I feel like those values are garbage...) askinfo_pak askinfo; // 61 bytes msaskinfo_pak msaskinfo; // 22 bytes - plrinfo playerinfo[MAXPLAYERS]; // 576 bytes(?) - plrconfig playerconfig[MAXPLAYERS]; // (up to) 528 bytes(?) + plrinfo_pak playerinfo[MAXPLAYERS]; // 576 bytes(?) + plrconfig_pak playerconfig[MAXPLAYERS]; // (up to) 528 bytes(?) INT32 filesneedednum; // 4 bytes filesneededconfig_pak filesneededcfg; // ??? bytes UINT32 pingtable[MAXPLAYERS+1]; // 68 bytes diff --git a/src/netcode/server_connection.c b/src/netcode/server_connection.c index e37c45951..924aa82d6 100644 --- a/src/netcode/server_connection.c +++ b/src/netcode/server_connection.c @@ -219,7 +219,7 @@ static void SV_SendPlayerInfo(INT32 node) netbuffer->u.playerinfo[i].data |= 0x80; } - HSendPacket(node, false, 0, sizeof(plrinfo) * MAXPLAYERS); + HSendPacket(node, false, 0, sizeof(plrinfo_pak) * MAXPLAYERS); } /** Sends a PT_SERVERCFG packet From 94761d3a5505d79d6f7ebdf96e7fbf88991bff47 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sun, 8 Jan 2023 00:43:18 +0100 Subject: [PATCH 341/586] Remove outdated or misleading comments --- src/netcode/client_connection.c | 11 ++--------- src/netcode/d_clisrv.c | 14 ++------------ src/netcode/protocol.h | 32 ++++++++++++++++---------------- src/netcode/server_connection.c | 2 +- src/netcode/tic_command.c | 8 -------- 5 files changed, 21 insertions(+), 46 deletions(-) diff --git a/src/netcode/client_connection.c b/src/netcode/client_connection.c index bed445a64..1adc3a65e 100644 --- a/src/netcode/client_connection.c +++ b/src/netcode/client_connection.c @@ -36,7 +36,7 @@ cl_mode_t cl_mode = CL_SEARCHING; static UINT16 cl_lastcheckedfilecount = 0; // used for full file list 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 tic_t firstconnectattempttime = 0; -UINT8 mynode; // my address pointofview server +UINT8 mynode; static void *snake = NULL; static void CL_DrawConnectionStatusBox(void) @@ -226,12 +226,9 @@ static boolean CL_AskFileList(INT32 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 +/** Sends a PT_CLIENTJOIN packet to the server * * \return True if the packet was successfully sent - * \todo Improve the description... * */ boolean CL_SendJoin(void) @@ -928,10 +925,6 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic 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(); if (client && cl_mode != CL_CONNECTED && cl_mode != CL_ABORTED) diff --git a/src/netcode/d_clisrv.c b/src/netcode/d_clisrv.c index 4589c83d3..eef9bdfe5 100644 --- a/src/netcode/d_clisrv.c +++ b/src/netcode/d_clisrv.c @@ -99,13 +99,8 @@ boolean adminpasswordset = false; tic_t neededtic; SINT8 servernode = 0; // the number of the server node -/// \brief do we accept new players? -/// \todo WORK! boolean acceptnewnode = true; -// 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; typedef struct banreason_s @@ -300,9 +295,6 @@ static void Command_connect(void) 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")) @@ -1768,7 +1760,7 @@ boolean TryRunTics(tic_t realtics) boolean ticking; // the machine has lagged but it is not so bad - if (realtics > TICRATE/7) // FIXME: consistency failure!! + if (realtics > TICRATE/7) { if (server) realtics = 1; @@ -1802,8 +1794,6 @@ boolean TryRunTics(tic_t realtics) #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; @@ -1983,7 +1973,7 @@ void NetUpdate(void) if (client) maketic = neededtic; - Local_Maketic(realtics); // make local tic, and call menu? + Local_Maketic(realtics); if (server) CL_SendClientCmd(); // send it diff --git a/src/netcode/protocol.h b/src/netcode/protocol.h index 1eba9286b..cbeb37f36 100644 --- a/src/netcode/protocol.h +++ b/src/netcode/protocol.h @@ -294,25 +294,25 @@ typedef struct UINT8 reserved; // Padding union { - clientcmd_pak clientpak; // 144 bytes - client2cmd_pak client2pak; // 200 bytes - servertics_pak serverpak; // 132495 bytes (more around 360, no?) - serverconfig_pak servercfg; // 773 bytes - UINT8 textcmd[MAXTEXTCMD+1]; // 66049 bytes (wut??? 64k??? More like 257 bytes...) - filetx_pak filetxpak; // 139 bytes + clientcmd_pak clientpak; + client2cmd_pak client2pak; + servertics_pak serverpak; + serverconfig_pak servercfg; + UINT8 textcmd[MAXTEXTCMD+1]; + filetx_pak filetxpak; fileack_pak fileack; UINT8 filereceived; - clientconfig_pak clientcfg; // 136 bytes + clientconfig_pak clientcfg; UINT8 md5sum[16]; - serverinfo_pak serverinfo; // 1024 bytes - serverrefuse_pak serverrefuse; // 65025 bytes (somehow I feel like those values are garbage...) - askinfo_pak askinfo; // 61 bytes - msaskinfo_pak msaskinfo; // 22 bytes - plrinfo_pak playerinfo[MAXPLAYERS]; // 576 bytes(?) - plrconfig_pak playerconfig[MAXPLAYERS]; // (up to) 528 bytes(?) - INT32 filesneedednum; // 4 bytes - filesneededconfig_pak filesneededcfg; // ??? bytes - UINT32 pingtable[MAXPLAYERS+1]; // 68 bytes + serverinfo_pak serverinfo; + serverrefuse_pak serverrefuse; + askinfo_pak askinfo; + msaskinfo_pak msaskinfo; + plrinfo_pak playerinfo[MAXPLAYERS]; + plrconfig_pak playerconfig[MAXPLAYERS]; + INT32 filesneedednum; + filesneededconfig_pak filesneededcfg; + UINT32 pingtable[MAXPLAYERS+1]; } u; // This is needed to pack diff packet types data together } ATTRPACK doomdata_t; diff --git a/src/netcode/server_connection.c b/src/netcode/server_connection.c index 924aa82d6..f2b0306e6 100644 --- a/src/netcode/server_connection.c +++ b/src/netcode/server_connection.c @@ -460,7 +460,7 @@ void PT_Connect(SINT8 node) ResetNode(node); SV_SendRefuse(node, M_GetText("Server couldn't send info, please try again")); /// \todo fix this !!! - return; // restart the while + return; } DEBFILE("new node joined\n"); diff --git a/src/netcode/tic_command.c b/src/netcode/tic_command.c index 180d54e69..bab0fad0a 100644 --- a/src/netcode/tic_command.c +++ b/src/netcode/tic_command.c @@ -262,11 +262,6 @@ void PT_ServerTics(SINT8 node, INT32 netconsole) 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);*/ } } @@ -447,9 +442,6 @@ void SV_SendTics(void) netnodes[0].supposedtic = maketic; } -// -// TryRunTics -// void Local_Maketic(INT32 realtics) { I_OsPolling(); // I_Getevent From cb634402a843e6542d00c851fda814d9f2df9a23 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sun, 8 Jan 2023 00:46:12 +0100 Subject: [PATCH 342/586] Rename packet handlers to match their associated PT_ constants --- src/netcode/client_connection.c | 2 +- src/netcode/d_clisrv.c | 4 ++-- src/netcode/server_connection.c | 2 +- src/netcode/server_connection.h | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/netcode/client_connection.c b/src/netcode/client_connection.c index 1adc3a65e..ff20a6fc7 100644 --- a/src/netcode/client_connection.c +++ b/src/netcode/client_connection.c @@ -1166,7 +1166,7 @@ void PT_ServerCFG(SINT8 node) /// \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 PT_Connect, the server will send the savegame even during intermission... + /// Also, according to PT_ClientJoin, 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; diff --git a/src/netcode/d_clisrv.c b/src/netcode/d_clisrv.c index eef9bdfe5..7fc64b456 100644 --- a/src/netcode/d_clisrv.c +++ b/src/netcode/d_clisrv.c @@ -1350,7 +1350,7 @@ void SV_StartSinglePlayerServer(void) * \param node The packet sender (should be the server) * */ -static void PT_Shutdown(SINT8 node) +static void PT_ServerShutdown(SINT8 node) { (void)node; LUA_HookBool(false, HOOK(GameQuit)); @@ -1365,7 +1365,7 @@ static void PT_Shutdown(SINT8 node) * \param node The packet sender (should be the server) * */ -static void PT_Timeout(SINT8 node) +static void PT_NodeTimeout(SINT8 node) { (void)node; LUA_HookBool(false, HOOK(GameQuit)); diff --git a/src/netcode/server_connection.c b/src/netcode/server_connection.c index f2b0306e6..3e7d46ef6 100644 --- a/src/netcode/server_connection.c +++ b/src/netcode/server_connection.c @@ -422,7 +422,7 @@ GetRefuseMessage (SINT8 node, INT32 rejoinernum) * \param node The packet sender * */ -void PT_Connect(SINT8 node) +void PT_ClientJoin(SINT8 node) { char names[MAXSPLITSCREENPLAYERS][MAXPLAYERNAME + 1]; INT32 numplayers = netbuffer->u.clientcfg.localplayers; diff --git a/src/netcode/server_connection.h b/src/netcode/server_connection.h index 585c9e428..96f7566ba 100644 --- a/src/netcode/server_connection.h +++ b/src/netcode/server_connection.h @@ -17,7 +17,7 @@ #include "../doomdef.h" #include "../doomtype.h" -void PT_Connect(SINT8 node); +void PT_ClientJoin(SINT8 node); void PT_AskInfoViaMS(SINT8 node); void PT_TellFilesNeeded(SINT8 node); void PT_AskInfo(SINT8 node); From 5d5e2c78e4e116b40de4bfb81b2d409b4211c189 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sun, 8 Jan 2023 00:47:33 +0100 Subject: [PATCH 343/586] Call all packet handlers from the same place --- src/netcode/d_clisrv.c | 41 +++++++++++---------------------- src/netcode/server_connection.c | 2 +- 2 files changed, 14 insertions(+), 29 deletions(-) diff --git a/src/netcode/d_clisrv.c b/src/netcode/d_clisrv.c index 7fc64b456..c004eeede 100644 --- a/src/netcode/d_clisrv.c +++ b/src/netcode/d_clisrv.c @@ -1352,6 +1352,9 @@ void SV_StartSinglePlayerServer(void) */ static void PT_ServerShutdown(SINT8 node) { + if (node != servernode || server || cl_mode == CL_SEARCHING) + return; + (void)node; LUA_HookBool(false, HOOK(GameQuit)); D_QuitNetGame(); @@ -1412,7 +1415,11 @@ static void PT_Login(SINT8 node, INT32 netconsole) static void PT_ClientQuit(SINT8 node, INT32 netconsole) { if (client) + { + if (node == servernode && cl_mode != CL_SEARCHING && netbuffer->packettype == PT_NODETIMEOUT) + PT_NodeTimeout(node); return; + } if (!netnodes[node].ingame) { @@ -1505,6 +1512,7 @@ static void HandlePacketFromAwayNode(SINT8 node) switch (netbuffer->packettype) { case PT_ASKINFOVIAMS : PT_AskInfoViaMS (node ); break; + case PT_SERVERINFO : PT_ServerInfo (node ); break; case PT_TELLFILESNEEDED: PT_TellFilesNeeded(node ); break; case PT_MOREFILESNEEDED: PT_MoreFilesNeeded(node ); break; case PT_ASKINFO : PT_AskInfo (node ); break; @@ -1517,6 +1525,8 @@ static void HandlePacketFromAwayNode(SINT8 node) case PT_NODETIMEOUT : PT_ClientQuit (node, -1); break; case PT_CLIENTQUIT : PT_ClientQuit (node, -1); break; case PT_SERVERTICS : PT_ServerTics (node, -1); break; + case PT_CLIENTJOIN : PT_ClientJoin (node ); break; + case PT_SERVERSHUTDOWN : PT_ServerShutdown (node ); break; case PT_CLIENTCMD : break; // This is not an "unknown packet" default: @@ -1566,6 +1576,7 @@ static void HandlePacketFromPlayer(SINT8 node) case PT_ASKLUAFILE : PT_AskLuaFile (node ); break; case PT_HASLUAFILE : PT_HasLuaFile (node ); break; case PT_RECEIVEDGAMESTATE : PT_ReceivedGamestate (node ); break; + case PT_SERVERINFO : PT_ServerInfo (node ); break; // CLIENT RECEIVE case PT_SERVERTICS : PT_ServerTics (node, netconsole); break; @@ -1575,7 +1586,9 @@ static void HandlePacketFromPlayer(SINT8 node) case PT_FILERECEIVED : PT_FileReceived (node ); break; case PT_WILLRESENDGAMESTATE: PT_WillResendGamestate(node ); break; case PT_SENDINGLUAFILE : PT_SendingLuaFile (node ); break; + case PT_SERVERSHUTDOWN : PT_ServerShutdown (node ); break; case PT_SERVERCFG : break; + case PT_CLIENTJOIN : break; default: DEBFILE(va("UNKNOWN PACKET TYPE RECEIVED %d from host %d\n", @@ -1598,34 +1611,6 @@ void GetPackets(void) { node = (SINT8)doomcom->remotenode; - if (netbuffer->packettype == PT_CLIENTJOIN && server) - { - PT_Connect(node); - continue; - } - if (node == servernode && client && cl_mode != CL_SEARCHING) - { - if (netbuffer->packettype == PT_SERVERSHUTDOWN) - { - PT_Shutdown(node); - continue; - } - if (netbuffer->packettype == PT_NODETIMEOUT) - { - PT_Timeout(node); - continue; - } - } - - if (netbuffer->packettype == PT_SERVERINFO) - { - PT_ServerInfo(node); - continue; - } - - if (netbuffer->packettype == PT_PLAYERINFO) - continue; // We do nothing with PLAYERINFO, that's for the MS browser. - // Packet received from someone already playing if (netnodes[node].ingame) HandlePacketFromPlayer(node); diff --git a/src/netcode/server_connection.c b/src/netcode/server_connection.c index 3e7d46ef6..9b41da920 100644 --- a/src/netcode/server_connection.c +++ b/src/netcode/server_connection.c @@ -430,7 +430,7 @@ void PT_ClientJoin(SINT8 node) INT32 i; // Ignore duplicate packets - if (netnodes[node].ingame) + if (client || netnodes[node].ingame) return; rejoinernum = FindRejoinerNum(node); From 2bd2b728bf530b65de3c12cbb9a7f75e79d94c5f Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sun, 8 Jan 2023 13:27:08 +0100 Subject: [PATCH 344/586] Remove useless variable --- src/netcode/d_clisrv.c | 9 --------- src/netcode/server_connection.c | 3 --- src/netcode/server_connection.h | 1 - 3 files changed, 13 deletions(-) diff --git a/src/netcode/d_clisrv.c b/src/netcode/d_clisrv.c index c004eeede..ecd7c9bbe 100644 --- a/src/netcode/d_clisrv.c +++ b/src/netcode/d_clisrv.c @@ -1605,8 +1605,6 @@ void GetPackets(void) { SINT8 node; // The packet sender - player_joining = false; - while (HGetPacket()) { node = (SINT8)doomcom->remotenode; @@ -1793,13 +1791,6 @@ boolean TryRunTics(tic_t realtics) hu_stopped = false; } - if (player_joining) - { - if (realtics) - hu_stopped = true; - return false; - } - if (ticking) { if (advancedemo) diff --git a/src/netcode/server_connection.c b/src/netcode/server_connection.c index 9b41da920..ed0e28309 100644 --- a/src/netcode/server_connection.c +++ b/src/netcode/server_connection.c @@ -37,8 +37,6 @@ tic_t joindelay = 0; // The actual timeout will be longer depending on the savegame length char playeraddress[MAXPLAYERS][64]; -UINT8 player_joining = false; - consvar_t cv_showjoinaddress = CVAR_INIT ("showjoinaddress", "Off", CV_SAVE|CV_NETVAR, CV_OnOff, NULL); consvar_t cv_allownewplayer = CVAR_INIT ("allowjoin", "On", CV_SAVE|CV_NETVAR, CV_OnOff, NULL); @@ -475,7 +473,6 @@ void PT_ClientJoin(SINT8 node) SV_AddPlayer(node, names[i]); joindelay += cv_joindelay.value * TICRATE; - player_joining = true; } void PT_AskInfoViaMS(SINT8 node) diff --git a/src/netcode/server_connection.h b/src/netcode/server_connection.h index 96f7566ba..7481d0eb5 100644 --- a/src/netcode/server_connection.h +++ b/src/netcode/server_connection.h @@ -25,7 +25,6 @@ void PT_AskInfo(SINT8 node); extern tic_t jointimeout; extern tic_t joindelay; extern char playeraddress[MAXPLAYERS][64]; -extern UINT8 player_joining; extern consvar_t cv_showjoinaddress, cv_allownewplayer, cv_maxplayers, cv_joindelay, cv_rejointimeout; #endif From b42336c23254e795e351aad18a4ef83989f987a1 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sun, 8 Jan 2023 16:28:41 +0100 Subject: [PATCH 345/586] Simplify convoluted code --- src/netcode/d_clisrv.c | 38 ++++++++++++-------------------------- 1 file changed, 12 insertions(+), 26 deletions(-) diff --git a/src/netcode/d_clisrv.c b/src/netcode/d_clisrv.c index ecd7c9bbe..5bb2c4600 100644 --- a/src/netcode/d_clisrv.c +++ b/src/netcode/d_clisrv.c @@ -1421,15 +1421,9 @@ static void PT_ClientQuit(SINT8 node, INT32 netconsole) return; } - if (!netnodes[node].ingame) - { - Net_CloseConnection(node); - return; - } - // 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 - if (netconsole != -1 && playeringame[netconsole]) + if (netnodes[node].ingame && netconsole != -1 && playeringame[netconsole]) { UINT8 kickmsg; @@ -1440,17 +1434,18 @@ static void PT_ClientQuit(SINT8 node, INT32 netconsole) kickmsg |= KICK_MSG_KEEP_BODY; SendKick(netconsole, kickmsg); - netnodes[node].player = -1; if (netnodes[node].player2 != -1 && netnodes[node].player2 >= 0 && playeringame[(UINT8)netnodes[node].player2]) { SendKick(netnodes[node].player2, kickmsg); - netnodes[node].player2 = -1; } } + Net_CloseConnection(node); netnodes[node].ingame = false; + netnodes[node].player = -1; + netnodes[node].player2 = -1; } static void PT_AskLuaFile(SINT8 node) @@ -1603,11 +1598,9 @@ static void HandlePacketFromPlayer(SINT8 node) */ void GetPackets(void) { - SINT8 node; // The packet sender - while (HGetPacket()) { - node = (SINT8)doomcom->remotenode; + SINT8 node = doomcom->remotenode; // Packet received from someone already playing if (netnodes[node].ingame) @@ -1740,8 +1733,6 @@ If they're not lagging, decrement the timer by 1. Of course, reset all of this i boolean TryRunTics(tic_t realtics) { - boolean ticking; - // the machine has lagged but it is not so bad if (realtics > TICRATE/7) { @@ -1783,16 +1774,11 @@ boolean TryRunTics(tic_t realtics) } #endif - ticking = neededtic > gametic; - - if (ticking) + if (neededtic > gametic) { if (realtics) hu_stopped = false; - } - if (ticking) - { if (advancedemo) { if (timedemo_quit) @@ -1826,16 +1812,19 @@ boolean TryRunTics(tic_t realtics) if (client && gamestate == GS_LEVEL && leveltime > 3 && neededtic <= gametic + cv_netticbuffer.value) break; } + + return true; } else { if (realtics) hu_stopped = true; - } - return ticking; + return false; + } } + static INT32 pingtimeout[MAXPLAYERS]; static inline void PingUpdate(void) @@ -1976,8 +1965,6 @@ void NetUpdate(void) { if (!demoplayback) { - INT32 counts; - hu_redownloadinggamestate = false; firstticstosend = gametic; @@ -1991,8 +1978,7 @@ void NetUpdate(void) } // Don't erase tics not acknowledged - counts = realtics; - + INT32 counts = realtics; if (maketic + counts >= firstticstosend + BACKUPTICS) counts = firstticstosend+BACKUPTICS-maketic-1; From 2f9a2ebc86f6252526f5186793c81933d71f9293 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sun, 8 Jan 2023 16:33:21 +0100 Subject: [PATCH 346/586] Move comment to an appropriate place --- src/netcode/d_clisrv.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/netcode/d_clisrv.c b/src/netcode/d_clisrv.c index 5bb2c4600..b0d534b84 100644 --- a/src/netcode/d_clisrv.c +++ b/src/netcode/d_clisrv.c @@ -1725,12 +1725,6 @@ INT16 Consistancy(void) return (INT16)(ret & 0xFFFF); } -/* -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. -*/ - boolean TryRunTics(tic_t realtics) { // the machine has lagged but it is not so bad @@ -1824,6 +1818,11 @@ boolean TryRunTics(tic_t realtics) } } +/* +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]; From 35dac244ef1a0727ba54a3dbdb6dd797220fdbcd Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Mon, 9 Jan 2023 21:39:33 +0100 Subject: [PATCH 347/586] Fix clients not being able to join servers --- src/netcode/d_clisrv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/netcode/d_clisrv.c b/src/netcode/d_clisrv.c index b0d534b84..6680c7e42 100644 --- a/src/netcode/d_clisrv.c +++ b/src/netcode/d_clisrv.c @@ -1523,6 +1523,7 @@ static void HandlePacketFromAwayNode(SINT8 node) case PT_CLIENTJOIN : PT_ClientJoin (node ); break; case PT_SERVERSHUTDOWN : PT_ServerShutdown (node ); break; case PT_CLIENTCMD : break; // This is not an "unknown packet" + case PT_PLAYERINFO : break; // This is not an "unknown packet" default: DEBFILE(va("unknown packet received (%d) from unknown host\n",netbuffer->packettype)); From 456c6b1a0012c8b04881ba9f7042869e111c9471 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Mon, 9 Jan 2023 22:14:58 +0100 Subject: [PATCH 348/586] Remove reboundstore timeout hack --- src/netcode/d_clisrv.c | 50 ++++++++------------------------------- src/netcode/d_clisrv.h | 1 + src/netcode/d_net.c | 19 +++++---------- src/netcode/net_command.c | 10 ++++++++ src/netcode/net_command.h | 1 + src/netcode/protocol.h | 1 - 6 files changed, 28 insertions(+), 54 deletions(-) diff --git a/src/netcode/d_clisrv.c b/src/netcode/d_clisrv.c index 6680c7e42..81d7e5543 100644 --- a/src/netcode/d_clisrv.c +++ b/src/netcode/d_clisrv.c @@ -479,6 +479,15 @@ void CL_RemovePlayer(INT32 playernum, kickreason_t reason) P_CheckRacers(); } +void CL_HandleTimeout(void) +{ + LUA_HookBool(false, HOOK(GameQuit)); + D_QuitNetGame(); + CL_Reset(); + D_StartTitle(); + M_StartMessage(M_GetText("Server Timeout\n\nPress Esc\n"), NULL, MM_NOTHING); +} + void CL_Reset(void) { if (metalrecording) @@ -1363,21 +1372,6 @@ static void PT_ServerShutdown(SINT8 node) 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 PT_NodeTimeout(SINT8 node) -{ - (void)node; - LUA_HookBool(false, HOOK(GameQuit)); - D_QuitNetGame(); - CL_Reset(); - D_StartTitle(); - M_StartMessage(M_GetText("Server Timeout\n\nPress Esc\n"), NULL, MM_NOTHING); -} - static void PT_Login(SINT8 node, INT32 netconsole) { (void)node; @@ -1415,32 +1409,10 @@ static void PT_Login(SINT8 node, INT32 netconsole) static void PT_ClientQuit(SINT8 node, INT32 netconsole) { if (client) - { - if (node == servernode && cl_mode != CL_SEARCHING && netbuffer->packettype == PT_NODETIMEOUT) - PT_NodeTimeout(node); return; - } - // 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 if (netnodes[node].ingame && 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); - - if (netnodes[node].player2 != -1 && netnodes[node].player2 >= 0 - && playeringame[(UINT8)netnodes[node].player2]) - { - SendKick(netnodes[node].player2, kickmsg); - } - } + SendKicksForNode(node, KICK_MSG_PLAYER_QUIT | KICK_MSG_KEEP_BODY); Net_CloseConnection(node); netnodes[node].ingame = false; @@ -1517,7 +1489,6 @@ static void HandlePacketFromAwayNode(SINT8 node) case PT_FILEACK : PT_FileAck (node ); break; case PT_FILERECEIVED : PT_FileReceived (node ); break; case PT_REQUESTFILE : PT_RequestFile (node ); break; - case PT_NODETIMEOUT : PT_ClientQuit (node, -1); break; case PT_CLIENTQUIT : PT_ClientQuit (node, -1); break; case PT_SERVERTICS : PT_ServerTics (node, -1); break; case PT_CLIENTJOIN : PT_ClientJoin (node ); break; @@ -1566,7 +1537,6 @@ static void HandlePacketFromPlayer(SINT8 node) case PT_TEXTCMD : PT_TextCmd (node, netconsole); break; case PT_TEXTCMD2 : PT_TextCmd (node, netconsole); break; case PT_LOGIN : PT_Login (node, netconsole); break; - case PT_NODETIMEOUT : PT_ClientQuit (node, netconsole); break; case PT_CLIENTQUIT : PT_ClientQuit (node, netconsole); break; case PT_CANRECEIVEGAMESTATE: PT_CanReceiveGamestate(node ); break; case PT_ASKLUAFILE : PT_AskLuaFile (node ); break; diff --git a/src/netcode/d_clisrv.h b/src/netcode/d_clisrv.h index 9cb3ef3e8..0abd638ce 100644 --- a/src/netcode/d_clisrv.h +++ b/src/netcode/d_clisrv.h @@ -94,6 +94,7 @@ void CL_RemoveSplitscreenPlayer(void); void CL_Reset(void); void CL_ClearPlayer(INT32 playernum); void CL_RemovePlayer(INT32 playernum, kickreason_t reason); +void CL_HandleTimeout(void); // Is there a game running boolean Playing(void); diff --git a/src/netcode/d_net.c b/src/netcode/d_net.c index 972342282..3c16392d0 100644 --- a/src/netcode/d_net.c +++ b/src/netcode/d_net.c @@ -27,6 +27,7 @@ #include "d_netfil.h" #include "d_clisrv.h" #include "tic_command.h" +#include "net_command.h" #include "../z_zone.h" #include "i_tcp.h" #include "../d_main.h" // srb2home @@ -461,14 +462,10 @@ void Net_ConnectionTimeout(INT32 node) return; nodes[node].flags |= NF_TIMEOUT; - // Send a very special packet to self (hack the reboundstore queue) - // Main code will handle it - reboundstore[rebound_head].packettype = PT_NODETIMEOUT; - reboundstore[rebound_head].ack = 0; - reboundstore[rebound_head].ackreturn = 0; - reboundstore[rebound_head].u.textcmd[0] = (UINT8)node; - reboundsize[rebound_head] = (INT16)(BASEPACKETSIZE + 1); - rebound_head = (rebound_head+1) % MAXREBOUND; + if (server) + SendKicksForNode(node, KICK_MSG_TIMEOUT | KICK_MSG_KEEP_BODY); + else + CL_HandleTimeout(); // Do not redo it quickly (if we do not close connection it is // for a good reason!) @@ -782,7 +779,6 @@ static const char *packettypename[NUMPACKETTYPE] = "TEXTCMD", "TEXTCMD2", "CLIENTJOIN", - "NODETIMEOUT", "LOGIN", "TELLFILESNEEDED", "MOREFILESNEEDED", @@ -1065,10 +1061,7 @@ boolean HGetPacket(void) { M_Memcpy(netbuffer, &reboundstore[rebound_tail], reboundsize[rebound_tail]); doomcom->datalength = reboundsize[rebound_tail]; - if (netbuffer->packettype == PT_NODETIMEOUT) - doomcom->remotenode = netbuffer->u.textcmd[0]; - else - doomcom->remotenode = 0; + doomcom->remotenode = 0; rebound_tail = (rebound_tail+1) % MAXREBOUND; #ifdef DEBUGFILE diff --git a/src/netcode/net_command.c b/src/netcode/net_command.c index 95a49a959..13477d42d 100644 --- a/src/netcode/net_command.c +++ b/src/netcode/net_command.c @@ -315,3 +315,13 @@ void SendKick(UINT8 playernum, UINT8 msg) buf[1] = msg; SendNetXCmd(XD_KICK, &buf, 2); } + +void SendKicksForNode(SINT8 node, UINT8 msg) +{ + if (!netnodes[node].ingame) + return; + + for (INT32 playernum = netnodes[node].player; playernum != -1; playernum = netnodes[node].player2) + if (playernum != -1 && playeringame[playernum]) + SendKick(playernum, msg); +} diff --git a/src/netcode/net_command.h b/src/netcode/net_command.h index 1fc5035c8..f1b4b2f3f 100644 --- a/src/netcode/net_command.h +++ b/src/netcode/net_command.h @@ -58,5 +58,6 @@ size_t TotalTextCmdPerTic(tic_t tic); void PT_TextCmd(SINT8 node, INT32 netconsole); void SendKick(UINT8 playernum, UINT8 msg); +void SendKicksForNode(SINT8 node, UINT8 msg); #endif diff --git a/src/netcode/protocol.h b/src/netcode/protocol.h index cbeb37f36..374cc5bff 100644 --- a/src/netcode/protocol.h +++ b/src/netcode/protocol.h @@ -85,7 +85,6 @@ typedef enum PT_TEXTCMD, // Extra text commands from the client. PT_TEXTCMD2, // Splitscreen text commands. PT_CLIENTJOIN, // Client wants to join; used in start game. - PT_NODETIMEOUT, // Packet sent to self if the connection times out. PT_LOGIN, // Login attempt from the client. From 79356fe6280d95828c27479301425410156edc11 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Thu, 12 Jan 2023 19:40:31 +0100 Subject: [PATCH 349/586] Move netgame commands to a new file --- src/netcode/Sourcefile | 1 + src/netcode/commands.c | 489 +++++++++++++++++++++++++++++++++++++++++ src/netcode/commands.h | 33 +++ src/netcode/d_clisrv.c | 460 +------------------------------------- src/netcode/d_net.h | 1 - 5 files changed, 524 insertions(+), 460 deletions(-) create mode 100644 src/netcode/commands.c create mode 100644 src/netcode/commands.h diff --git a/src/netcode/Sourcefile b/src/netcode/Sourcefile index c59050367..7c0354714 100644 --- a/src/netcode/Sourcefile +++ b/src/netcode/Sourcefile @@ -4,6 +4,7 @@ client_connection.c tic_command.c net_command.c gamestate.c +commands.c d_net.c d_netcmd.c d_netfil.c diff --git a/src/netcode/commands.c b/src/netcode/commands.c new file mode 100644 index 000000000..834e1c666 --- /dev/null +++ b/src/netcode/commands.c @@ -0,0 +1,489 @@ +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2022 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 commands.c +/// \brief Various netgame commands, such as kick and ban + +#include "commands.h" +#include "d_clisrv.h" +#include "client_connection.h" +#include "net_command.h" +#include "d_netcmd.h" +#include "d_net.h" +#include "i_net.h" +#include "protocol.h" +#include "../byteptr.h" +#include "../d_main.h" +#include "../g_game.h" +#include "../w_wad.h" +#include "../z_zone.h" +#include "../doomstat.h" +#include "../doomdef.h" +#include "../r_local.h" +#include +#include +#include +#include + +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 + +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 Ban_Clear(void) +{ + banreason_t *temp; + + I_ClearBans(); + + reasontail = NULL; + + while (reasonhead) + { + temp = reasonhead->next; + Z_Free(reasonhead->reason); + free(reasonhead); + reasonhead = temp; + } +} + +void Ban_Load_File(boolean warning) +{ + FILE *f; + size_t i; + const char *address, *mask; + char buffer[MAX_WADPATH]; + + if (!I_ClearBans) + return; + + 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; + } + + Ban_Clear(); + + 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); +} + +void D_SaveBan(void) +{ + FILE *f; + 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"); + + 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); +} + +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 Command_ClearBans(void) +{ + if (!I_ClearBans) + return; + + Ban_Clear(); + D_SaveBan(); +} + +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")); + +} + +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; + } + } +} + +void Command_ReloadBan(void) //recheck ban.txt +{ + Ban_Load_File(true); +} + +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 (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 && netnodes[playernode[pn]].sendingsavegame) + { + 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")); +} + +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; + } + + 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(); +} + +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]); + } +} + +/** Lists all players and their player numbers. + * + * \sa Command_GetPlayerNum + */ +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"); + } + } +} diff --git a/src/netcode/commands.h b/src/netcode/commands.h new file mode 100644 index 000000000..5ff4d1cae --- /dev/null +++ b/src/netcode/commands.h @@ -0,0 +1,33 @@ +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2022 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 commands.h +/// \brief Various netgame commands, such as kick and ban + +#ifndef __COMMANDS__ +#define __COMMANDS__ + +#include "../doomdef.h" + +#define MAX_REASONLENGTH 30 + +void Ban_Add(const char *reason); +void D_SaveBan(void); +void Ban_Load_File(boolean warning); +void Command_ShowBan(void); +void Command_ClearBans(void); +void Command_Ban(void); +void Command_BanIP(void); +void Command_ReloadBan(void); +void Command_Kick(void); +void Command_connect(void); +void Command_GetPlayerNum(void); +void Command_Nodes(void); + +#endif diff --git a/src/netcode/d_clisrv.c b/src/netcode/d_clisrv.c index 81d7e5543..506de8c02 100644 --- a/src/netcode/d_clisrv.c +++ b/src/netcode/d_clisrv.c @@ -54,6 +54,7 @@ #include "tic_command.h" #include "net_command.h" #include "gamestate.h" +#include "commands.h" #include "protocol.h" // @@ -69,8 +70,6 @@ // firstticstosend is used to optimize a condition // Normally maketic >= gametic > 0 -#define MAX_REASONLENGTH 30 - boolean server = true; // true or false but !server == client boolean serverrunning = false; INT32 serverplayer = 0; @@ -103,16 +102,6 @@ boolean acceptnewnode = true; UINT16 software_MAXPACKETLENGTH; -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 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); @@ -124,232 +113,6 @@ consvar_t cv_blamecfail = CVAR_INIT ("blamecfail", "Off", CV_SAVE|CV_NETVAR, CV_ 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 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; - const char *path = va("%s"PATHSEP"%s", srb2home, "ban.txt"); - - if (!reasonhead) - { - remove(path); - return; - } - - f = fopen(path, "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 Ban_Clear(void) -{ - banreason_t *temp; - - I_ClearBans(); - - reasontail = NULL; - - while (reasonhead) - { - temp = reasonhead->next; - Z_Free(reasonhead->reason); - free(reasonhead); - reasonhead = temp; - } -} - -static void Command_ClearBans(void) -{ - if (!I_ClearBans) - return; - - Ban_Clear(); - D_SaveBan(); -} - -static void Ban_Load_File(boolean warning) -{ - FILE *f; - size_t i; - const char *address, *mask; - char buffer[MAX_WADPATH]; - - if (!I_ClearBans) - return; - - 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; - } - - Ban_Clear(); - - 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; - } - - 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(); -} - void ResetNode(INT32 node) { memset(&netnodes[node], 0, sizeof(*netnodes)); @@ -527,20 +290,6 @@ void CL_Reset(void) // D_StartTitle should get done now, but the calling function will handle it } -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; @@ -570,213 +319,6 @@ SINT8 nametonum(const char *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 (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 && netnodes[playernode[pn]].sendingsavegame) - { - 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")); -} - static void Got_KickCmd(UINT8 **p, INT32 playernum) { INT32 pnum, msg; diff --git a/src/netcode/d_net.h b/src/netcode/d_net.h index 857c3463c..039f5b3b4 100644 --- a/src/netcode/d_net.h +++ b/src/netcode/d_net.h @@ -68,7 +68,6 @@ boolean HSendPacket(INT32 node, boolean reliable, UINT8 acknum, size_t packetlength); boolean HGetPacket(void); void D_SetDoomcom(void); -void D_SaveBan(void); boolean D_CheckNetGame(void); void D_CloseConnection(void); void Net_UnAcknowledgePacket(INT32 node); From 2c6bb7172678ac54ccbdd2eabc0cd0c9a00ea726 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Fri, 13 Jan 2023 22:05:57 +0100 Subject: [PATCH 350/586] Reorder functions in d_clisrv.c --- src/netcode/d_clisrv.c | 1249 ++++++++++++++++++++-------------------- 1 file changed, 623 insertions(+), 626 deletions(-) diff --git a/src/netcode/d_clisrv.c b/src/netcode/d_clisrv.c index 506de8c02..1658856b6 100644 --- a/src/netcode/d_clisrv.c +++ b/src/netcode/d_clisrv.c @@ -83,6 +83,7 @@ UINT8 playernode[MAXPLAYERS]; 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. +static INT32 pingtimeout[MAXPLAYERS]; tic_t servermaxping = 800; // server's max ping. Defaults to 800 tic_t maketic; @@ -120,137 +121,6 @@ void ResetNode(INT32 node) netnodes[node].player2 = -1; } -// -// 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)); -} - -static void UnlinkPlayerFromNode(INT32 playernum) -{ - INT32 node = playernode[playernum]; - - if (node == UINT8_MAX) - return; - - playernode[playernum] = UINT8_MAX; - - netnodes[node].numplayers--; - if (netnodes[node].numplayers <= 0) - { - netnodes[node].ingame = false; - Net_CloseConnection(node); - ResetNode(node); - } -} - -// If in a special stage, redistribute the player's -// spheres across the remaining players. -// I feel like this shouldn't even be in this file at all, but well. -static void RedistributeSpecialStageSpheres(INT32 playernum) -{ - if (!G_IsSpecialStage(gamemap) || D_NumPlayers() <= 1) - return; - - INT32 count = D_NumPlayers() - 1; - INT32 spheres = players[playernum].spheres; - INT32 rings = players[playernum].rings; - - while (spheres || rings) - { - INT32 sincrement = max(spheres / count, 1); - INT32 rincrement = max(rings / count, 1); - - INT32 i, n; - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i] || i == playernum) - continue; - - n = min(spheres, sincrement); - P_GivePlayerSpheres(&players[i], n); - spheres -= n; - - n = min(rings, rincrement); - P_GivePlayerRings(&players[i], n); - rings -= n; - } - } -} - -// -// CL_RemovePlayer -// -// Removes a player from the current game -// -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) - UnlinkPlayerFromNode(playernum); - - if (gametyperules & GTR_TEAMFLAGS) - P_PlayerFlagBurst(&players[playernum], false); // Don't take the flag with you! - - RedistributeSpecialStageSpheres(playernum); - - 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. - LUA_HookViewpointSwitch(&players[consoleplayer], &players[consoleplayer], true); - displayplayer = consoleplayer; - } - - // Reset player data - CL_ClearPlayer(playernum); - - // remove avatar of player - playeringame[playernum] = false; - 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_HandleTimeout(void) -{ - LUA_HookBool(false, HOOK(GameQuit)); - D_QuitNetGame(); - CL_Reset(); - D_StartTitle(); - M_StartMessage(M_GetText("Server Timeout\n\nPress Esc\n"), NULL, MM_NOTHING); -} - void CL_Reset(void) { if (metalrecording) @@ -290,33 +160,181 @@ void CL_Reset(void) // D_StartTitle should get done now, but the calling function will handle it } -SINT8 nametonum(const char *name) +// +// CL_ClearPlayer +// +// Clears the player data so that a future client can use this slot +// +void CL_ClearPlayer(INT32 playernum) { - INT32 playernum, i; + if (players[playernum].mo) + P_RemoveMobj(players[playernum].mo); + memset(&players[playernum], 0, sizeof (player_t)); + memset(playeraddress[playernum], 0, sizeof(*playeraddress)); +} - if (!strcmp(name, "0")) - return 0; +// Xcmd XD_ADDPLAYER +static void Got_AddPlayer(UINT8 **p, INT32 playernum) +{ + INT16 node, newplayernum; + boolean splitscreenplayer; + boolean rejoined; + player_t *newplayer; - playernum = (SINT8)atoi(name); - - if (playernum < 0 || playernum >= MAXPLAYERS) - return -1; - - if (playernum) + if (playernum != serverplayer && !IsPlayerAdmin(playernum)) { - if (playeringame[playernum]) - return (SINT8)playernum; - else - return -1; + // 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; } - for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && !stricmp(player_names[i], name)) - return (SINT8)i; + node = READUINT8(*p); + newplayernum = READUINT8(*p); + splitscreenplayer = newplayernum & 0x80; + newplayernum &= ~0x80; - CONS_Printf(M_GetText("There is no player named \"%s\"\n"), name); + rejoined = playeringame[newplayernum]; - return -1; + 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) + LUA_HookInt(newplayernum, HOOK(PlayerJoin)); +} + +static void UnlinkPlayerFromNode(INT32 playernum) +{ + INT32 node = playernode[playernum]; + + if (node == UINT8_MAX) + return; + + playernode[playernum] = UINT8_MAX; + + netnodes[node].numplayers--; + if (netnodes[node].numplayers <= 0) + { + netnodes[node].ingame = false; + Net_CloseConnection(node); + ResetNode(node); + } +} + +static void PT_ClientQuit(SINT8 node, INT32 netconsole) +{ + if (client) + return; + + if (netnodes[node].ingame && netconsole != -1 && playeringame[netconsole]) + SendKicksForNode(node, KICK_MSG_PLAYER_QUIT | KICK_MSG_KEEP_BODY); + + Net_CloseConnection(node); + netnodes[node].ingame = false; + netnodes[node].player = -1; + netnodes[node].player2 = -1; } static void Got_KickCmd(UINT8 **p, INT32 playernum) @@ -510,47 +528,175 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum) CL_RemovePlayer(pnum, kickreason); } -static void Got_AddPlayer(UINT8 **p, INT32 playernum); - -// called one time at init -void D_ClientServerInit(void) +// If in a special stage, redistribute the player's +// spheres across the remaining players. +// I feel like this shouldn't even be in this file at all, but well. +static void RedistributeSpecialStageSpheres(INT32 playernum) { - DEBFILE(va("- - -== SRB2 v%d.%.2d.%d "VERSIONSTRING" debugfile ==- - -\n", - VERSION/100, VERSION%100, SUBVERSION)); + if (!G_IsSpecialStage(gamemap) || D_NumPlayers() <= 1) + return; - 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); + INT32 count = D_NumPlayers() - 1; + INT32 spheres = players[playernum].spheres; + INT32 rings = players[playernum].rings; + + while (spheres || rings) + { + INT32 sincrement = max(spheres / count, 1); + INT32 rincrement = max(rings / count, 1); + + INT32 i, n; + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i] || i == playernum) + continue; + + n = min(spheres, sincrement); + P_GivePlayerSpheres(&players[i], n); + spheres -= n; + + n = min(rings, rincrement); + P_GivePlayerRings(&players[i], n); + rings -= n; + } + } +} + +// +// CL_RemovePlayer +// +// Removes a player from the current game +// +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) + UnlinkPlayerFromNode(playernum); + + if (gametyperules & GTR_TEAMFLAGS) + P_PlayerFlagBurst(&players[playernum], false); // Don't take the flag with you! + + RedistributeSpecialStageSpheres(playernum); + + 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. + LUA_HookViewpointSwitch(&players[consoleplayer], &players[consoleplayer], true); + displayplayer = consoleplayer; + } + + // Reset player data + CL_ClearPlayer(playernum); + + // remove avatar of player + playeringame[playernum] = false; + 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(); +} + +// +// D_QuitNetGame +// Called before quitting to leave a net game +// without hanging the other players +// +void D_QuitNetGame(void) +{ + mousegrabbedbylua = true; + I_UpdateMouseGrab(); + + 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 (netnodes[i].ingame) + HSendPacket(i, true, 0, 0); +#ifdef MASTERSERVER + if (serverrunning && ms_RoomId > 0) + UnregisterServer(); #endif -#ifdef _DEBUG - COM_AddCommand("numnodes", Command_Numnodes); + } + else if (servernode > 0 && servernode < MAXNETNODES && netnodes[(UINT8)servernode].ingame) + { + 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 +} - RegisterNetXCmd(XD_KICK, Got_KickCmd); - RegisterNetXCmd(XD_ADDPLAYER, Got_AddPlayer); -#ifdef DUMPCONSISTENCY - CV_RegisterVar(&cv_dumpconsistency); -#endif - Ban_Load_File(false); +void CL_HandleTimeout(void) +{ + LUA_HookBool(false, HOOK(GameQuit)); + D_QuitNetGame(); + CL_Reset(); + D_StartTitle(); + M_StartMessage(M_GetText("Server Timeout\n\nPress Esc\n"), NULL, MM_NOTHING); +} - gametic = 0; - localgametic = 0; +void CL_AddSplitscreenPlayer(void) +{ + if (cl_mode == CL_CONNECTED) + CL_SendJoin(); +} - // do not send anything before the real begin - SV_StopServer(); - SV_ResetServer(); - if (dedicated) - SV_SpawnServer(); +void CL_RemoveSplitscreenPlayer(void) +{ + if (cl_mode != CL_CONNECTED) + return; + + SendKick(secondarydisplayplayer, KICK_MSG_PLAYER_QUIT); } void SV_ResetServer(void) @@ -622,215 +768,6 @@ static inline void SV_GenContext(void) } } -// -// D_QuitNetGame -// Called before quitting to leave a net game -// without hanging the other players -// -void D_QuitNetGame(void) -{ - mousegrabbedbylua = true; - I_UpdateMouseGrab(); - - 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 (netnodes[i].ingame) - HSendPacket(i, true, 0, 0); -#ifdef MASTERSERVER - if (serverrunning && ms_RoomId > 0) - UnregisterServer(); -#endif - } - else if (servernode > 0 && servernode < MAXNETNODES && netnodes[(UINT8)servernode].ingame) - { - 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 -} - -// 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) - LUA_HookInt(newplayernum, HOOK(PlayerJoin)); -} - -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); -} - void SV_SpawnServer(void) { if (demoplayback) @@ -860,6 +797,21 @@ void SV_SpawnServer(void) } } +// 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; +} + void SV_StopServer(void) { tic_t i; @@ -881,21 +833,6 @@ void SV_StopServer(void) 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; -} - /** Called when a PT_SERVERSHUTDOWN packet is received * * \param node The packet sender (should be the server) @@ -948,20 +885,6 @@ static void PT_Login(SINT8 node, INT32 netconsole) #endif } -static void PT_ClientQuit(SINT8 node, INT32 netconsole) -{ - if (client) - return; - - if (netnodes[node].ingame && netconsole != -1 && playeringame[netconsole]) - SendKicksForNode(node, KICK_MSG_PLAYER_QUIT | KICK_MSG_KEEP_BODY); - - Net_CloseConnection(node); - netnodes[node].ingame = false; - netnodes[node].player = -1; - netnodes[node].player2 = -1; -} - static void PT_AskLuaFile(SINT8 node) { if (server && luafiletransfers && luafiletransfers->nodestatus[node] == LFTNS_ASKED) @@ -974,6 +897,94 @@ static void PT_HasLuaFile(SINT8 node) SV_HandleLuaFileSent(node); } +static void PT_SendingLuaFile(SINT8 node) +{ + (void)node; + + if (client) + CL_PrepareDownloadLuaFile(); +} + +/* +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 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 (netnodes[i].ingame) + HSendPacket(i, true, 0, sizeof(INT32) * (MAXPLAYERS+1)); + + pingmeasurecount = 1; //Reset count +} + static void PT_Ping(SINT8 node, INT32 netconsole) { // Only accept PT_PING from the server. @@ -997,14 +1008,6 @@ static void PT_Ping(SINT8 node, INT32 netconsole) } } -static void PT_SendingLuaFile(SINT8 node) -{ - (void)node; - - if (client) - CL_PrepareDownloadLuaFile(); -} - /** Handles a packet received from a node that isn't in game * * \param node The packet sender @@ -1124,120 +1127,6 @@ void GetPackets(void) } } -// -// 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. -// -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 - 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) - 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); -} - boolean TryRunTics(tic_t realtics) { // the machine has lagged but it is not so bad @@ -1331,88 +1220,6 @@ boolean TryRunTics(tic_t realtics) } } -/* -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 (netnodes[i].ingame) - HSendPacket(i, true, 0, sizeof(INT32) * (MAXPLAYERS+1)); - - pingmeasurecount = 1; //Reset count -} - void NetUpdate(void) { static tic_t gametime = 0; @@ -1537,6 +1344,82 @@ void NetUpdate(void) FileSendTicker(); } +// called one time at init +void D_ClientServerInit(void) +{ + DEBFILE(va("- - -== SRB2 v%d.%.2d.%d "VERSIONSTRING" debugfile ==- - -\n", + VERSION/100, VERSION%100, SUBVERSION)); + + 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 + + RegisterNetXCmd(XD_KICK, Got_KickCmd); + RegisterNetXCmd(XD_ADDPLAYER, Got_AddPlayer); +#ifdef DUMPCONSISTENCY + CV_RegisterVar(&cv_dumpconsistency); +#endif + Ban_Load_File(false); + + gametic = 0; + localgametic = 0; + + // do not send anything before the real begin + SV_StopServer(); + SV_ResetServer(); + if (dedicated) + SV_SpawnServer(); +} + +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; +} + +// is there a game running +boolean Playing(void) +{ + return (server && serverrunning) || (client && cl_mode == CL_CONNECTED); +} + /** Returns the number of players playing. * \return Number of players. Can be zero if we're running a ::dedicated * server. @@ -1551,6 +1434,120 @@ INT32 D_NumPlayers(void) return num; } +// +// 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. +// +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 + 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) + 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); +} + tic_t GetLag(INT32 node) { return gametic - netnodes[node].tic; From 684382fc5e18de501b88ab292b1a7c81bbc78843 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Fri, 13 Jan 2023 22:28:03 +0100 Subject: [PATCH 351/586] Add missing include directive --- src/sdl/i_system.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 50ceae34c..38769e667 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -194,6 +194,7 @@ static char returnWadPath[256]; #include "../i_threads.h" #include "../screen.h" //vid.WndParent #include "../netcode/d_net.h" +#include "../netcode/commands.h" #include "../g_game.h" #include "../filesrch.h" #include "endtxt.h" From 715893ad25ba2c5077de8c60b9516edd822da954 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sat, 14 Jan 2023 14:49:33 +0100 Subject: [PATCH 352/586] Split PT_ClientCmd into functions --- src/netcode/tic_command.c | 95 +++++++++++++++++++++------------------ 1 file changed, 51 insertions(+), 44 deletions(-) diff --git a/src/netcode/tic_command.c b/src/netcode/tic_command.c index bab0fad0a..417a2fdfd 100644 --- a/src/netcode/tic_command.c +++ b/src/netcode/tic_command.c @@ -103,6 +103,55 @@ void D_ResetTiccmds(void) D_Clearticcmd(textcmds[i]->tic); } +// Check ticcmd for "speed hacks" +static void CheckTiccmdHacks(INT32 playernum) +{ + ticcmd_t *cmd = &netcmds[maketic%BACKUPTICS][playernum]; + if (cmd->forwardmove > MAXPLMOVE || cmd->forwardmove < -MAXPLMOVE + || cmd->sidemove > MAXPLMOVE || cmd->sidemove < -MAXPLMOVE) + { + CONS_Alert(CONS_WARNING, M_GetText("Illegal movement value received from node %d\n"), playernum); + SendKick(playernum, KICK_MSG_CON_FAIL); + } +} + +// Check player consistancy during the level +static void CheckConsistancy(SINT8 nodenum, tic_t tic) +{ + netnode_t *node = &netnodes[nodenum]; + INT16 neededconsistancy = consistancy[tic%BACKUPTICS]; + INT16 clientconsistancy = SHORT(netbuffer->u.clientpak.consistancy); + + if (tic > gametic || tic + BACKUPTICS - 1 <= gametic || gamestate != GS_LEVEL + || neededconsistancy == clientconsistancy || SV_ResendingSavegameToAnyone() + || node->resendingsavegame || node->savegameresendcooldown > I_GetTime()) + return; + + if (cv_resynchattempts.value) + { + // Tell the client we are about to resend them the gamestate + netbuffer->packettype = PT_WILLRESENDGAMESTATE; + HSendPacket(nodenum, true, 0, 0); + + node->resendingsavegame = true; + + if (cv_blamecfail.value) + CONS_Printf(M_GetText("Synch failure for player %d (%s); expected %hd, got %hd\n"), + node->player+1, player_names[node->player], + neededconsistancy, clientconsistancy); + + DEBFILE(va("Restoring player %d (synch failure) [%update] %d!=%d\n", + node->player, tic, neededconsistancy, clientconsistancy)); + } + else + { + SendKick(node->player, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY); + + DEBFILE(va("player %d kicked (synch failure) [%u] %d!=%d\n", + node->player, tic, neededconsistancy, clientconsistancy)); + } +} + void PT_ClientCmd(SINT8 node, INT32 netconsole) { tic_t realend, realstart; @@ -143,56 +192,14 @@ void PT_ClientCmd(SINT8 node, INT32 netconsole) // 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); - return; - } - // Splitscreen cmd if ((netbuffer->packettype == PT_CLIENT2CMD || netbuffer->packettype == PT_CLIENT2MIS) && netnodes[node].player2 >= 0) G_MoveTiccmd(&netcmds[maketic%BACKUPTICS][(UINT8)netnodes[node].player2], &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) - && !SV_ResendingSavegameToAnyone() - && !netnodes[node].resendingsavegame && netnodes[node].savegameresendcooldown <= I_GetTime()) - { - if (cv_resynchattempts.value) - { - // Tell the client we are about to resend them the gamestate - netbuffer->packettype = PT_WILLRESENDGAMESTATE; - HSendPacket(node, true, 0, 0); - - netnodes[node].resendingsavegame = 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))); - return; - } - 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))); - return; - } - } + CheckTiccmdHacks(netconsole); + CheckConsistancy(node, realstart); } void PT_ServerTics(SINT8 node, INT32 netconsole) From 2639dc176df55f14a5fa1310554d4d768da2d8c3 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sat, 14 Jan 2023 14:52:13 +0100 Subject: [PATCH 353/586] Move net command copying to a new function --- src/netcode/net_command.c | 20 ++++++++++++++++++++ src/netcode/net_command.h | 1 + src/netcode/tic_command.c | 21 +++------------------ 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/src/netcode/net_command.c b/src/netcode/net_command.c index 13477d42d..227b78660 100644 --- a/src/netcode/net_command.c +++ b/src/netcode/net_command.c @@ -304,6 +304,26 @@ void PT_TextCmd(SINT8 node, INT32 netconsole) } } +void SV_CopyNetCommandsToServerPacket(tic_t tic) +{ + servertics_pak *packet = &netbuffer->u.serverpak; + UINT8 *cmds = (UINT8*)&packet->cmds[packet->numslots * packet->numtics]; + UINT8 numcmds; + + numcmds = *cmds++; + + for (UINT32 i = 0; i < numcmds; i++) + { + INT32 playernum = *cmds++; // playernum + size_t size = cmds[0]+1; + + if (tic >= gametic) // Don't copy old net commands + M_Memcpy(D_GetTextcmd(tic, playernum), cmds, size); + cmds += size; + } +} + +void CL_SendNetCommands(void) void SendKick(UINT8 playernum, UINT8 msg) { UINT8 buf[2]; diff --git a/src/netcode/net_command.h b/src/netcode/net_command.h index f1b4b2f3f..a9447ed7a 100644 --- a/src/netcode/net_command.h +++ b/src/netcode/net_command.h @@ -57,6 +57,7 @@ void ExtraDataTicker(void); size_t TotalTextCmdPerTic(tic_t tic); void PT_TextCmd(SINT8 node, INT32 netconsole); +void SV_CopyNetCommandsToServerPacket(tic_t tic); void SendKick(UINT8 playernum, UINT8 msg); void SendKicksForNode(SINT8 node, UINT8 msg); diff --git a/src/netcode/tic_command.c b/src/netcode/tic_command.c index 417a2fdfd..2eb3b10ac 100644 --- a/src/netcode/tic_command.c +++ b/src/netcode/tic_command.c @@ -204,7 +204,6 @@ void PT_ClientCmd(SINT8 node, INT32 netconsole) void PT_ServerTics(SINT8 node, INT32 netconsole) { - UINT8 *pak, *txtpak, numtxtpak; tic_t realend, realstart; if (!netnodes[node].ingame) @@ -230,19 +229,15 @@ void PT_ServerTics(SINT8 node, INT32 netconsole) realstart = netbuffer->u.serverpak.starttic; realend = realstart + netbuffer->u.serverpak.numtics; - 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; + UINT8 *pak = (UINT8 *)&netbuffer->u.serverpak.cmds; - for (i = realstart; i < realend; i++) + for (tic_t i = realstart; i < realend; i++) { // clear first D_Clearticcmd(i); @@ -251,17 +246,7 @@ void PT_ServerTics(SINT8 node, INT32 netconsole) 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; - } + SV_CopyNetCommandsToServerPacket(i); } neededtic = realend; From e4c403408b1b3a306b316c135a91e0121c44a33e Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sat, 14 Jan 2023 14:53:27 +0100 Subject: [PATCH 354/586] Move net command sending to a new function --- src/netcode/net_command.c | 22 ++++++++++++++++++++++ src/netcode/net_command.h | 1 + src/netcode/tic_command.c | 22 +--------------------- 3 files changed, 24 insertions(+), 21 deletions(-) diff --git a/src/netcode/net_command.c b/src/netcode/net_command.c index 227b78660..9e089a1a2 100644 --- a/src/netcode/net_command.c +++ b/src/netcode/net_command.c @@ -324,6 +324,28 @@ void SV_CopyNetCommandsToServerPacket(tic_t tic) } void CL_SendNetCommands(void) +{ + // 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; + } +} + void SendKick(UINT8 playernum, UINT8 msg) { UINT8 buf[2]; diff --git a/src/netcode/net_command.h b/src/netcode/net_command.h index a9447ed7a..3a433ebe4 100644 --- a/src/netcode/net_command.h +++ b/src/netcode/net_command.h @@ -58,6 +58,7 @@ size_t TotalTextCmdPerTic(tic_t tic); void PT_TextCmd(SINT8 node, INT32 netconsole); void SV_CopyNetCommandsToServerPacket(tic_t tic); +void CL_SendNetCommands(void); void SendKick(UINT8 playernum, UINT8 msg); void SendKicksForNode(SINT8 node, UINT8 msg); diff --git a/src/netcode/tic_command.c b/src/netcode/tic_command.c index 2eb3b10ac..76d46451f 100644 --- a/src/netcode/tic_command.c +++ b/src/netcode/tic_command.c @@ -295,27 +295,7 @@ void CL_SendClientCmd(void) } 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; - } - } + CL_SendNetCommands(); } // send the server packet From a69204b609376532eacb255199e628d791904fa5 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sat, 14 Jan 2023 15:14:09 +0100 Subject: [PATCH 355/586] Fix function name --- src/netcode/net_command.c | 2 +- src/netcode/net_command.h | 2 +- src/netcode/tic_command.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/netcode/net_command.c b/src/netcode/net_command.c index 9e089a1a2..98c578b79 100644 --- a/src/netcode/net_command.c +++ b/src/netcode/net_command.c @@ -304,7 +304,7 @@ void PT_TextCmd(SINT8 node, INT32 netconsole) } } -void SV_CopyNetCommandsToServerPacket(tic_t tic) +void CL_CopyNetCommandsFromServerPacket(tic_t tic) { servertics_pak *packet = &netbuffer->u.serverpak; UINT8 *cmds = (UINT8*)&packet->cmds[packet->numslots * packet->numtics]; diff --git a/src/netcode/net_command.h b/src/netcode/net_command.h index 3a433ebe4..0e8339ef7 100644 --- a/src/netcode/net_command.h +++ b/src/netcode/net_command.h @@ -57,7 +57,7 @@ void ExtraDataTicker(void); size_t TotalTextCmdPerTic(tic_t tic); void PT_TextCmd(SINT8 node, INT32 netconsole); -void SV_CopyNetCommandsToServerPacket(tic_t tic); +void CL_CopyNetCommandsFromServerPacket(tic_t tic); void CL_SendNetCommands(void); void SendKick(UINT8 playernum, UINT8 msg); void SendKicksForNode(SINT8 node, UINT8 msg); diff --git a/src/netcode/tic_command.c b/src/netcode/tic_command.c index 76d46451f..6b237ed61 100644 --- a/src/netcode/tic_command.c +++ b/src/netcode/tic_command.c @@ -246,7 +246,7 @@ void PT_ServerTics(SINT8 node, INT32 netconsole) pak = G_ScpyTiccmd(netcmds[i%BACKUPTICS], pak, netbuffer->u.serverpak.numslots*sizeof (ticcmd_t)); - SV_CopyNetCommandsToServerPacket(i); + CL_CopyNetCommandsFromServerPacket(i); } neededtic = realend; From 8df0debd541a253a2161267bc77cba1823184852 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sat, 14 Jan 2023 19:01:36 +0100 Subject: [PATCH 356/586] Split SV_SendTics into functions --- src/netcode/net_command.c | 21 +++++++++ src/netcode/net_command.h | 1 + src/netcode/tic_command.c | 95 ++++++++++++++++++--------------------- 3 files changed, 66 insertions(+), 51 deletions(-) diff --git a/src/netcode/net_command.c b/src/netcode/net_command.c index 98c578b79..11b351af7 100644 --- a/src/netcode/net_command.c +++ b/src/netcode/net_command.c @@ -304,6 +304,27 @@ void PT_TextCmd(SINT8 node, INT32 netconsole) } } +void SV_WriteNetCommandsForTic(tic_t tic, UINT8 **buf) +{ + UINT8 *numcmds; + + numcmds = (*buf)++; + *numcmds = 0; + for (INT32 i = 0; i < MAXPLAYERS; i++) + { + UINT8 *cmd = D_GetExistingTextcmd(tic, i); + INT32 size = cmd ? cmd[0] : 0; + + if ((!i || playeringame[i]) && size) + { + (*numcmds)++; + WRITEUINT8(*buf, i); + M_Memcpy(*buf, cmd, size + 1); + *buf += size + 1; + } + } +} + void CL_CopyNetCommandsFromServerPacket(tic_t tic) { servertics_pak *packet = &netbuffer->u.serverpak; diff --git a/src/netcode/net_command.h b/src/netcode/net_command.h index 0e8339ef7..cc26aeb0e 100644 --- a/src/netcode/net_command.h +++ b/src/netcode/net_command.h @@ -57,6 +57,7 @@ void ExtraDataTicker(void); size_t TotalTextCmdPerTic(tic_t tic); void PT_TextCmd(SINT8 node, INT32 netconsole); +void SV_WriteNetCommandsForTic(tic_t tic, UINT8 **buf); void CL_CopyNetCommandsFromServerPacket(tic_t tic); void CL_SendNetCommands(void); void SendKick(UINT8 playernum, UINT8 msg); diff --git a/src/netcode/tic_command.c b/src/netcode/tic_command.c index 6b237ed61..bf8c5d21d 100644 --- a/src/netcode/tic_command.c +++ b/src/netcode/tic_command.c @@ -298,16 +298,56 @@ void CL_SendClientCmd(void) CL_SendNetCommands(); } +// PT_SERVERTICS packets can grow too large for a single UDP packet, +// So this checks how many tics worth of data can be sent in one packet. +// The rest can be sent later, usually the next tic. +static tic_t SV_CalculateNumTicsForPacket(SINT8 nodenum, tic_t firsttic, tic_t lasttic) +{ + size_t size = BASESERVERTICSSIZE; + tic_t tic; + + for (tic = firsttic; tic < lasttic; tic++) + { + size += sizeof (ticcmd_t) * doomcom->numslots; + size += TotalTextCmdPerTic(tic); + + if (size > software_MAXPACKETLENGTH) + { + DEBFILE(va("packet too large (%s) at tic %d (should be from %d to %d)\n", + sizeu1(size), tic, firsttic, lasttic)); + lasttic = tic; + + // 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 (lasttic == firsttic) + { + if (size > 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(size), doomcom->numslots, nodenum); + else + { + lasttic++; // send it anyway! + DEBFILE("sending it anyway\n"); + } + } + break; + } + } + + return lasttic - firsttic; +} + // send the server packet // send tic from firstticstosend to maketic-1 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 @@ -336,38 +376,7 @@ void SV_SendTics(void) 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; - } - } + lasttictosend = realfirsttic + SV_CalculateNumTicsForPacket(n, realfirsttic, lasttictosend); // Send the tics netbuffer->packettype = PT_SERVERTICS; @@ -383,23 +392,7 @@ void SV_SendTics(void) // 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; - } - } - } + SV_WriteNetCommandsForTic(); packsize = bufpos - (UINT8 *)&(netbuffer->u); HSendPacket(n, false, 0, packsize); From a54155e2cccacd6a8025485088d1c7ba0fcf3efa Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sat, 14 Jan 2023 20:02:06 +0100 Subject: [PATCH 357/586] Cleanup --- src/netcode/client_connection.c | 21 ++++------ src/netcode/commands.c | 23 +++++------ src/netcode/d_clisrv.c | 57 ++++++++++---------------- src/netcode/d_net.c | 66 ++++++++++++------------------ src/netcode/d_netfil.c | 71 ++++++++++++--------------------- src/netcode/gamestate.c | 8 +--- src/netcode/i_tcp.c | 34 ++++++---------- src/netcode/net_command.c | 11 ++--- src/netcode/server_connection.c | 11 ++--- src/netcode/tic_command.c | 56 +++++++++++--------------- 10 files changed, 132 insertions(+), 226 deletions(-) diff --git a/src/netcode/client_connection.c b/src/netcode/client_connection.c index ff20a6fc7..faa91b6d7 100644 --- a/src/netcode/client_connection.c +++ b/src/netcode/client_connection.c @@ -60,7 +60,7 @@ static inline void CL_DrawConnectionStatus(void) if (cl_mode != CL_DOWNLOADFILES && cl_mode != CL_LOADFILES) { - INT32 i, animtime = ((ccstime / 4) & 15) + 16; + INT32 animtime = ((ccstime / 4) & 15) + 16; UINT8 palstart; const char *cltext; @@ -75,7 +75,7 @@ static inline void CL_DrawConnectionStatus(void) palstart = 96; // Green if (!(cl_mode == CL_DOWNLOADSAVEGAME && lastfilenum != -1)) - for (i = 0; i < 16; ++i) // 15 pal entries total. + for (INT32 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) @@ -134,14 +134,13 @@ static inline void CL_DrawConnectionStatus(void) { 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++) + for (INT32 i = 0; i < fileneedednum; i++) if (fileneeded[i].status == FS_OPEN) loadcompletednum++; } @@ -277,9 +276,7 @@ UINT32 serverlistcount = 0; static void SL_ClearServerList(INT32 connectedserver) { - UINT32 i; - - for (i = 0; i < serverlistcount; i++) + for (UINT32 i = 0; i < serverlistcount; i++) if (connectedserver != serverlist[i].node) { Net_CloseConnection(serverlist[i].node|FORCECLOSE); @@ -290,8 +287,7 @@ static void SL_ClearServerList(INT32 connectedserver) static UINT32 SL_SearchServer(INT32 node) { - UINT32 i; - for (i = 0; i < serverlistcount; i++) + for (UINT32 i = 0; i < serverlistcount; i++) if (serverlist[i].node == node) return i; @@ -388,9 +384,7 @@ Fetch_servers_thread (struct Fetch_servers_ctx *ctx) void CL_QueryServerList (msg_server_t *server_list) { - INT32 i; - - for (i = 0; server_list[i].header.buffer[0]; i++) + for (INT32 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. @@ -781,7 +775,6 @@ static boolean CL_ServerConnectionSearchTicker(tic_t *asksent) static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic_t *asksent) { boolean waitmore; - INT32 i; switch (cl_mode) { @@ -808,7 +801,7 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic break; case CL_DOWNLOADFILES: waitmore = false; - for (i = 0; i < fileneedednum; i++) + for (INT32 i = 0; i < fileneedednum; i++) if (fileneeded[i].status == FS_DOWNLOADING || fileneeded[i].status == FS_REQUESTED) { diff --git a/src/netcode/commands.c b/src/netcode/commands.c index 834e1c666..4d9a48b6b 100644 --- a/src/netcode/commands.c +++ b/src/netcode/commands.c @@ -79,7 +79,6 @@ static void Ban_Clear(void) void Ban_Load_File(boolean warning) { FILE *f; - size_t i; const char *address, *mask; char buffer[MAX_WADPATH]; @@ -97,7 +96,7 @@ void Ban_Load_File(boolean warning) Ban_Clear(); - for (i=0; fgets(buffer, (int)sizeof(buffer), f); i++) + for (size_t i=0; fgets(buffer, (int)sizeof(buffer), f); i++) { address = strtok(buffer, " \t\r\n"); mask = strtok(NULL, " \t\r\n"); @@ -113,7 +112,6 @@ void Ban_Load_File(boolean warning) void D_SaveBan(void) { FILE *f; - size_t i; banreason_t *reasonlist = reasonhead; const char *address, *mask; const char *path = va("%s"PATHSEP"%s", srb2home, "ban.txt"); @@ -132,7 +130,7 @@ void D_SaveBan(void) return; } - for (i = 0;(address = I_GetBanAddress(i)) != NULL;i++) + for (size_t i = 0;(address = I_GetBanAddress(i)) != NULL;i++) { if (!I_GetBanMask || (mask = I_GetBanMask(i)) == NULL) fprintf(f, "%s 0", address); @@ -236,12 +234,12 @@ void Command_Ban(void) } else { - size_t i, j = COM_Argc(); + size_t 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++) + for (size_t i = 3; i < j; i++) { strlcat(message, " ", sizeof message); strlcat(message, COM_Argv(i), sizeof message); @@ -340,12 +338,12 @@ void Command_Kick(void) } else { - size_t i, j = COM_Argc(); + size_t 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++) + for (size_t i = 3; i < j; i++) { strlcat(message, " ", sizeof message); strlcat(message, COM_Argv(i), sizeof message); @@ -435,9 +433,7 @@ void Command_connect(void) void Command_GetPlayerNum(void) { - INT32 i; - - for (i = 0; i < MAXPLAYERS; i++) + for (INT32 i = 0; i < MAXPLAYERS; i++) if (playeringame[i]) { if (serverplayer == i) @@ -453,18 +449,17 @@ void Command_GetPlayerNum(void) */ void Command_Nodes(void) { - INT32 i; size_t maxlen = 0; const char *address; - for (i = 0; i < MAXPLAYERS; i++) + for (INT32 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++) + for (INT32 i = 0; i < MAXPLAYERS; i++) { if (playeringame[i]) { diff --git a/src/netcode/d_clisrv.c b/src/netcode/d_clisrv.c index 1658856b6..105526dd2 100644 --- a/src/netcode/d_clisrv.c +++ b/src/netcode/d_clisrv.c @@ -440,11 +440,9 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum) 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++) + for (INT32 i = 0; i < MAXPLAYERS; i++) { if (!playeringame[i]) continue; @@ -545,8 +543,8 @@ static void RedistributeSpecialStageSpheres(INT32 playernum) INT32 sincrement = max(spheres / count, 1); INT32 rincrement = max(rings / count, 1); - INT32 i, n; - for (i = 0; i < MAXPLAYERS; i++) + INT32 n; + for (INT32 i = 0; i < MAXPLAYERS; i++) { if (!playeringame[i] || i == playernum) continue; @@ -644,10 +642,8 @@ void D_QuitNetGame(void) if (server) { - INT32 i; - netbuffer->packettype = PT_SERVERSHUTDOWN; - for (i = 0; i < MAXNETNODES; i++) + for (INT32 i = 0; i < MAXNETNODES; i++) if (netnodes[i].ingame) HSendPacket(i, true, 0, 0); #ifdef MASTERSERVER @@ -701,8 +697,6 @@ void CL_RemoveSplitscreenPlayer(void) 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 @@ -713,10 +707,10 @@ void SV_ResetServer(void) joindelay = 0; - for (i = 0; i < MAXNETNODES; i++) + for (INT32 i = 0; i < MAXNETNODES; i++) ResetNode(i); - for (i = 0; i < MAXPLAYERS; i++) + for (INT32 i = 0; i < MAXPLAYERS; i++) { LUA_InvalidatePlayer(&players[i]); playeringame[i] = false; @@ -755,10 +749,9 @@ void SV_ResetServer(void) 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++) + for (UINT8 i = 0; i < 8; i++) { const char a = M_RandomKey(26*2); if (a < 26) // uppercase @@ -814,8 +807,6 @@ void SV_StartSinglePlayerServer(void) void SV_StopServer(void) { - tic_t i; - if (gamestate == GS_INTERMISSION) Y_EndIntermission(); gamestate = wipegamestate = GS_NULL; @@ -823,7 +814,7 @@ void SV_StopServer(void) localtextcmd[0] = 0; localtextcmd2[0] = 0; - for (i = firstticstosend; i < firstticstosend + BACKUPTICS; i++) + for (tic_t i = firstticstosend; i < firstticstosend + BACKUPTICS; i++) D_Clearticcmd(i); consoleplayer = 0; @@ -913,7 +904,6 @@ If they're not lagging, decrement the timer by 1. Of course, reset all of this i static inline void PingUpdate(void) { - INT32 i; boolean laggers[MAXPLAYERS]; UINT8 numlaggers = 0; memset(laggers, 0, sizeof(boolean) * MAXPLAYERS); @@ -923,7 +913,7 @@ static inline void PingUpdate(void) //check for ping limit breakage. if (cv_maxping.value) { - for (i = 1; i < MAXPLAYERS; i++) + for (INT32 i = 1; i < MAXPLAYERS; i++) { if (playeringame[i] && !players[i].quittime && (realpingtable[i] / pingmeasurecount > (unsigned)cv_maxping.value)) @@ -940,7 +930,7 @@ static inline void PingUpdate(void) //in that case, it is probably the server's fault. if (numlaggers < D_NumPlayers() - 1) { - for (i = 1; i < MAXPLAYERS; i++) + for (INT32 i = 1; i < MAXPLAYERS; i++) { if (playeringame[i] && laggers[i]) { @@ -965,7 +955,7 @@ static inline void PingUpdate(void) } //make the ping packet and clear server data for next one - for (i = 0; i < MAXPLAYERS; i++) + for (INT32 i = 0; i < MAXPLAYERS; i++) { netbuffer->u.pingtable[i] = realpingtable[i] / pingmeasurecount; //server takes a snapshot of the real ping for display. @@ -978,7 +968,7 @@ static inline void PingUpdate(void) netbuffer->u.pingtable[MAXPLAYERS] = cv_maxping.value; //send out our ping packets - for (i = 0; i < MAXNETNODES; i++) + for (INT32 i = 0; i < MAXNETNODES; i++) if (netnodes[i].ingame) HSendPacket(i, true, 0, sizeof(INT32) * (MAXPLAYERS+1)); @@ -999,8 +989,7 @@ static void PT_Ping(SINT8 node, INT32 netconsole) //Update client ping table from the server. if (client) { - UINT8 i; - for (i = 0; i < MAXPLAYERS; i++) + for (INT32 i = 0; i < MAXPLAYERS; i++) if (playeringame[i]) playerpingtable[i] = (tic_t)netbuffer->u.pingtable[i]; @@ -1225,7 +1214,6 @@ void NetUpdate(void) static tic_t gametime = 0; static tic_t resptime = 0; tic_t nowtime; - INT32 i; INT32 realtics; nowtime = I_GetTime(); @@ -1248,7 +1236,7 @@ void NetUpdate(void) 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++) + for (INT32 i = 0; i < MAXPLAYERS; i++) if (playeringame[i] && playernode[i] != UINT8_MAX) realpingtable[i] += G_TicsToMilliseconds(GetLag(playernode[i])); pingmeasurecount++; @@ -1287,7 +1275,7 @@ void NetUpdate(void) hu_redownloadinggamestate = false; firstticstosend = gametic; - for (i = 0; i < MAXNETNODES; i++) + for (INT32 i = 0; i < MAXNETNODES; i++) if (netnodes[i].ingame && netnodes[i].tic < firstticstosend) { firstticstosend = netnodes[i].tic; @@ -1301,7 +1289,7 @@ void NetUpdate(void) if (maketic + counts >= firstticstosend + BACKUPTICS) counts = firstticstosend+BACKUPTICS-maketic-1; - for (i = 0; i < counts; i++) + for (INT32 i = 0; i < counts; i++) SV_Maketic(); // Create missed tics and increment maketic for (; tictoclear < firstticstosend; tictoclear++) // Clear only when acknowledged @@ -1318,7 +1306,7 @@ void NetUpdate(void) // Handle timeouts to prevent definitive freezes from happenning if (server) { - for (i = 1; i < MAXNETNODES; i++) + for (INT32 i = 1; i < MAXNETNODES; i++) if (netnodes[i].ingame && netnodes[i].freezetimeout < I_GetTime()) Net_ConnectionTimeout(i); @@ -1387,7 +1375,7 @@ void D_ClientServerInit(void) SINT8 nametonum(const char *name) { - INT32 playernum, i; + INT32 playernum; if (!strcmp(name, "0")) return 0; @@ -1405,7 +1393,7 @@ SINT8 nametonum(const char *name) return -1; } - for (i = 0; i < MAXPLAYERS; i++) + for (INT32 i = 0; i < MAXPLAYERS; i++) if (playeringame[i] && !stricmp(player_names[i], name)) return (SINT8)i; @@ -1427,8 +1415,8 @@ boolean Playing(void) */ INT32 D_NumPlayers(void) { - INT32 num = 0, ix; - for (ix = 0; ix < MAXPLAYERS; ix++) + INT32 num = 0; + for (INT32 ix = 0; ix < MAXPLAYERS; ix++) if (playeringame[ix]) num++; return num; @@ -1444,7 +1432,6 @@ INT32 D_NumPlayers(void) // INT16 Consistancy(void) { - INT32 i; UINT32 ret = 0; #ifdef MOBJCONSISTANCY thinker_t *th; @@ -1453,7 +1440,7 @@ INT16 Consistancy(void) DEBFILE(va("TIC %u ", gametic)); - for (i = 0; i < MAXPLAYERS; i++) + for (INT32 i = 0; i < MAXPLAYERS; i++) { if (!playeringame[i]) ret ^= 0xCCCC; diff --git a/src/netcode/d_net.c b/src/netcode/d_net.c index 3c16392d0..a4b0778e3 100644 --- a/src/netcode/d_net.c +++ b/src/netcode/d_net.c @@ -211,7 +211,7 @@ FUNCMATH static INT32 cmpack(UINT8 a, UINT8 b) static boolean GetFreeAcknum(UINT8 *freeack, boolean lowtimer) { node_t *node = &nodes[doomcom->remotenode]; - INT32 i, numfreeslot = 0; + INT32 numfreeslot = 0; if (cmpack((UINT8)((node->remotefirstack + MAXACKTOSEND) % 256), node->nextacknum) < 0) { @@ -219,7 +219,7 @@ static boolean GetFreeAcknum(UINT8 *freeack, boolean lowtimer) return false; } - for (i = 0; i < MAXACKPACKETS; i++) + for (INT32 i = 0; i < MAXACKPACKETS; i++) if (!ackpak[i].acknum) { // For low priority packets, make sure to let freeslots so urgent packets can be sent @@ -276,10 +276,10 @@ static boolean GetFreeAcknum(UINT8 *freeack, boolean lowtimer) */ INT32 Net_GetFreeAcks(boolean urgent) { - INT32 i, numfreeslot = 0; + INT32 numfreeslot = 0; INT32 n = 0; // Number of free acks found - for (i = 0; i < MAXACKPACKETS; i++) + for (INT32 i = 0; i < MAXACKPACKETS; i++) if (!ackpak[i].acknum) { // For low priority packets, make sure to let freeslots so urgent packets can be sent @@ -315,7 +315,6 @@ static void RemoveAck(INT32 i) // We have got a packet, proceed the ack request and ack return static boolean Processackpak(void) { - INT32 i; boolean goodpacket = true; node_t *node = &nodes[doomcom->remotenode]; @@ -324,7 +323,7 @@ static boolean Processackpak(void) { node->remotefirstack = netbuffer->ackreturn; // Search the ackbuffer and free it - for (i = 0; i < MAXACKPACKETS; i++) + for (INT32 i = 0; i < MAXACKPACKETS; i++) if (ackpak[i].acknum && ackpak[i].destinationnode == node - nodes && cmpack(ackpak[i].acknum, netbuffer->ackreturn) <= 0) { @@ -346,7 +345,7 @@ static boolean Processackpak(void) else { // Check if it is not already in the queue - for (i = node->acktosend_tail; i != node->acktosend_head; i = (i+1) % MAXACKTOSEND) + for (INT32 i = node->acktosend_tail; i != node->acktosend_head; i = (i+1) % MAXACKTOSEND) if (node->acktosend[i] == ack) { DEBFILE(va("Discard(2) ack %d (duplicated)\n", ack)); @@ -374,7 +373,7 @@ static boolean Processackpak(void) while (change) { change = false; - for (i = node->acktosend_tail; i != node->acktosend_head; + for (INT32 i = node->acktosend_tail; i != node->acktosend_head; i = (i+1) % MAXACKTOSEND) { if (cmpack(node->acktosend[i], nextfirstack) <= 0) @@ -434,11 +433,9 @@ void Net_SendAcks(INT32 node) static void GotAcks(void) { - INT32 i, j; - - for (j = 0; j < MAXACKTOSEND; j++) + for (INT32 j = 0; j < MAXACKTOSEND; j++) if (netbuffer->u.textcmd[j]) - for (i = 0; i < MAXACKPACKETS; i++) + for (INT32 i = 0; i < MAXACKPACKETS; i++) if (ackpak[i].acknum && ackpak[i].destinationnode == doomcom->remotenode) { if (ackpak[i].acknum == netbuffer->u.textcmd[j]) @@ -475,9 +472,8 @@ void Net_ConnectionTimeout(INT32 node) // Resend the data if needed void Net_AckTicker(void) { - INT32 i; - for (i = 0; i < MAXACKPACKETS; i++) + for (INT32 i = 0; i < MAXACKPACKETS; i++) { const INT32 nodei = ackpak[i].destinationnode; node_t *node = &nodes[nodei]; @@ -504,7 +500,7 @@ void Net_AckTicker(void) } } - for (i = 1; i < MAXNETNODES; i++) + for (INT32 i = 1; i < MAXNETNODES; i++) { // This is something like node open flag if (nodes[i].firstacktosend) @@ -567,9 +563,7 @@ void Net_UnAcknowledgePacket(INT32 node) */ static boolean Net_AllAcksReceived(void) { - INT32 i; - - for (i = 0; i < MAXACKPACKETS; i++) + for (INT32 i = 0; i < MAXACKPACKETS; i++) if (ackpak[i].acknum) return false; @@ -611,12 +605,10 @@ static void InitNode(node_t *node) static void InitAck(void) { - INT32 i; - - for (i = 0; i < MAXACKPACKETS; i++) + for (INT32 i = 0; i < MAXACKPACKETS; i++) ackpak[i].acknum = 0; - for (i = 0; i < MAXNETNODES; i++) + for (INT32 i = 0; i < MAXNETNODES; i++) InitNode(&nodes[i]); } @@ -627,8 +619,7 @@ static void InitAck(void) */ void Net_AbortPacketType(UINT8 packettype) { - INT32 i; - for (i = 0; i < MAXACKPACKETS; i++) + for (INT32 i = 0; i < MAXACKPACKETS; i++) if (ackpak[i].acknum && (ackpak[i].pak.data.packettype == packettype || packettype == UINT8_MAX)) { @@ -643,7 +634,6 @@ void Net_AbortPacketType(UINT8 packettype) // remove a node, clear all ack from this node and reset askret void Net_CloseConnection(INT32 node) { - INT32 i; boolean forceclose = (node & FORCECLOSE) != 0; if (node == -1) @@ -673,7 +663,7 @@ void Net_CloseConnection(INT32 node) } // check if we are waiting for an ack from this node - for (i = 0; i < MAXACKPACKETS; i++) + for (INT32 i = 0; i < MAXACKPACKETS; i++) if (ackpak[i].acknum && ackpak[i].destinationnode == node) { if (!forceclose) @@ -697,9 +687,8 @@ static UINT32 NetbufferChecksum(void) UINT32 c = 0x1234567; const INT32 l = doomcom->datalength - 4; const UINT8 *buf = (UINT8 *)netbuffer + 4; - INT32 i; - for (i = 0; i < l; i++, buf++) + for (INT32 i = 0; i < l; i++, buf++) c += (*buf) * (i+1); return LONG(c); @@ -710,9 +699,8 @@ static UINT32 NetbufferChecksum(void) static void fprintfstring(char *s, size_t len) { INT32 mode = 0; - size_t i; - for (i = 0; i < len; i++) + for (size_t i = 0; i < len; i++) if (s[i] < 32) { if (!mode) @@ -879,7 +867,6 @@ void Command_Drop(void) { INT32 packetquantity; const char *packetname; - size_t i; if (COM_Argc() < 2) { @@ -909,11 +896,11 @@ void Command_Drop(void) packetname = COM_Argv(1); if (!(stricmp(packetname, "all") && stricmp(packetname, "any"))) - for (i = 0; i < NUMPACKETTYPE; i++) + for (size_t i = 0; i < NUMPACKETTYPE; i++) packetdropquantity[i] = packetquantity; else { - for (i = 0; i < NUMPACKETTYPE; i++) + for (size_t i = 0; i < NUMPACKETTYPE; i++) if (!stricmp(packetname, packettypename[i])) { packetdropquantity[i] = packetquantity; @@ -1336,13 +1323,12 @@ void Command_Ping_f(void) int name_width = 0; int ms_width = 0; - int n; - INT32 i; - pingc = 0; - for (i = 1; i < MAXPLAYERS; ++i) + for (INT32 i = 1; i < MAXPLAYERS; ++i) if (playeringame[i]) { + int n; + n = strlen(player_names[i]); if (n > name_width) name_width = n; @@ -1362,7 +1348,7 @@ void Command_Ping_f(void) qsort(pingv, pingc, sizeof (struct pingcell), &pingcellcmp); - for (i = 0; i < pingc; ++i) + for (INT32 i = 0; i < pingc; ++i) { CONS_Printf("%02d : %-*s %*d ms\n", pingv[i].num, @@ -1378,15 +1364,13 @@ void Command_Ping_f(void) void D_CloseConnection(void) { - INT32 i; - if (netgame) { // wait the ackreturn with timout of 5 Sec Net_WaitAllAckReceived(5); // close all connection - for (i = 0; i < MAXNETNODES; i++) + for (INT32 i = 0; i < MAXNETNODES; i++) Net_CloseConnection(i|FORCECLOSE); InitAck(); diff --git a/src/netcode/d_netfil.c b/src/netcode/d_netfil.c index 205abf713..10b7359ad 100644 --- a/src/netcode/d_netfil.c +++ b/src/netcode/d_netfil.c @@ -128,9 +128,7 @@ consvar_t cv_downloadspeed = CVAR_INIT ("downloadspeed", "16", CV_SAVE|CV_NETVAR static UINT16 GetWadNumFromFileNeededId(UINT8 id) { - UINT16 wadnum; - - for (wadnum = mainwads; wadnum < numwadfiles; wadnum++) + for (UINT16 wadnum = mainwads; wadnum < numwadfiles; wadnum++) { if (!wadfiles[wadnum]->important) continue; @@ -150,14 +148,13 @@ static UINT16 GetWadNumFromFileNeededId(UINT8 id) */ UINT8 *PutFileNeeded(UINT16 firstfile) { - 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 = mainwads; i < numwadfiles; i++) //mainwads, otherwise we start on the first mainwad + for (size_t 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) @@ -232,7 +229,6 @@ void FreeFileNeeded(void) */ void D_ParseFileneeded(INT32 fileneedednum_parm, UINT8 *fileneededstr, UINT16 firstfile) { - INT32 i; UINT8 *p; UINT8 filestatus; @@ -241,7 +237,7 @@ void D_ParseFileneeded(INT32 fileneedednum_parm, UINT8 *fileneededstr, UINT16 fi AllocFileNeeded(fileneedednum); - for (i = firstfile; i < fileneedednum; i++) + for (INT32 i = firstfile; i < fileneedednum; i++) { fileneeded[i].type = FILENEEDED_WAD; fileneeded[i].status = FS_NOTCHECKED; // We haven't even started looking for the file yet @@ -281,9 +277,9 @@ void CL_PrepareDownloadSaveGame(const char *tmpsave) */ boolean CL_CheckDownloadable(void) { - UINT8 i,dlstatus = 0; + UINT8 dlstatus = 0; - for (i = 0; i < fileneedednum; i++) + for (UINT8 i = 0; i < fileneedednum; i++) if (fileneeded[i].status != FS_FOUND && fileneeded[i].status != FS_OPEN) { if (fileneeded[i].willsend == 1) @@ -304,7 +300,7 @@ boolean CL_CheckDownloadable(void) // not downloadable, put reason in console CONS_Alert(CONS_NOTICE, M_GetText("You need additional files to connect to this server:\n")); - for (i = 0; i < fileneedednum; i++) + for (UINT8 i = 0; i < fileneedednum; i++) if (fileneeded[i].status != FS_FOUND && fileneeded[i].status != FS_OPEN) { CONS_Printf(" * \"%s\" (%dK)", fileneeded[i].filename, fileneeded[i].totalsize >> 10); @@ -374,14 +370,13 @@ void CL_AbortDownloadResume(void) boolean CL_SendFileRequest(void) { char *p; - INT32 i; INT64 totalfreespaceneeded = 0, availablefreespace; #ifdef PARANOIA if (M_CheckParm("-nodownload")) I_Error("Attempted to download files in -nodownload mode"); - for (i = 0; i < fileneedednum; i++) + for (INT32 i = 0; i < fileneedednum; i++) if (fileneeded[i].status != FS_FOUND && fileneeded[i].status != FS_OPEN && (fileneeded[i].willsend == 0 || fileneeded[i].willsend == 2)) { @@ -391,7 +386,7 @@ boolean CL_SendFileRequest(void) netbuffer->packettype = PT_REQUESTFILE; p = (char *)netbuffer->u.textcmd; - for (i = 0; i < fileneedednum; i++) + for (INT32 i = 0; i < fileneedednum; i++) if ((fileneeded[i].status == FS_NOTFOUND || fileneeded[i].status == FS_MD5SUMBAD)) { totalfreespaceneeded += fileneeded[i].totalsize; @@ -422,7 +417,6 @@ boolean CL_SendFileRequest(void) void PT_RequestFile(SINT8 node) { UINT8 *p = netbuffer->u.textcmd; - UINT8 id; if (client || !cv_downloading.value) { @@ -432,7 +426,7 @@ void PT_RequestFile(SINT8 node) while (p < netbuffer->u.textcmd + MAXTEXTCMD-1) // Don't allow hacked client to overflow { - id = READUINT8(p); + UINT8 id = READUINT8(p); if (id == 0xFF) break; @@ -543,9 +537,7 @@ INT32 CL_CheckFiles(void) // Load it now boolean CL_LoadServerFiles(void) { - INT32 i; - - for (i = 0; i < fileneedednum; i++) + for (INT32 i = 0; i < fileneedednum; i++) { if (fileneeded[i].status == FS_OPEN) continue; // Already loaded @@ -641,11 +633,10 @@ void AddLuaFileTransfer(const char *filename, const char *mode) static void SV_PrepareSendLuaFileToNextNode(void) { - INT32 i; UINT8 success = 1; // Find a client to send the file to - for (i = 1; i < MAXNETNODES; i++) + for (INT32 i = 1; i < MAXNETNODES; i++) if (luafiletransfers->nodestatus[i] == LFTNS_WAITING) // Node waiting { // Tell the client we're about to send them the file @@ -667,12 +658,11 @@ static void SV_PrepareSendLuaFileToNextNode(void) void SV_PrepareSendLuaFile(void) { char *binfilename; - INT32 i; luafiletransfers->ongoing = true; // Set status to "waiting" for everyone - for (i = 0; i < MAXNETNODES; i++) + for (INT32 i = 0; i < MAXNETNODES; i++) luafiletransfers->nodestatus[i] = (netnodes[i].ingame ? LFTNS_WAITING : LFTNS_NONE); if (FIL_ReadFileOK(luafiletransfers->realfilename)) @@ -1153,7 +1143,6 @@ void PT_FileAck(SINT8 node) { fileack_pak *packet = &netbuffer->u.fileack; filetran_t *trans = &transfer[node]; - INT32 i, j; if (client) return; @@ -1175,11 +1164,11 @@ void PT_FileAck(SINT8 node) trans->dontsenduntil = 0; } - for (i = 0; i < packet->numsegments; i++) + for (INT32 i = 0; i < packet->numsegments; i++) { fileacksegment_t *segment = &packet->segments[i]; - for (j = 0; j < 32; j++) + for (INT32 j = 0; j < 32; j++) if (LONG(segment->acks) & (1 << j)) { if (LONG(segment->start) * FILEFRAGMENTSIZE >= trans->txlist->size) @@ -1215,13 +1204,12 @@ void PT_FileReceived(SINT8 node) static void SendAckPacket(fileack_pak *packet, UINT8 fileid) { size_t packetsize; - INT32 i; packetsize = sizeof(*packet) + packet->numsegments * sizeof(*packet->segments); // Finalise the packet packet->fileid = fileid; - for (i = 0; i < packet->numsegments; i++) + for (INT32 i = 0; i < packet->numsegments; i++) { packet->segments[i].start = LONG(packet->segments[i].start); packet->segments[i].acks = LONG(packet->segments[i].acks); @@ -1261,9 +1249,7 @@ static void AddFragmentToAckPacket(fileack_pak *packet, UINT8 iteration, UINT32 void FileReceiveTicker(void) { - INT32 i; - - for (i = 0; i < fileneedednum; i++) + for (INT32 i = 0; i < fileneedednum; i++) { fileneeded_t *file = &fileneeded[i]; @@ -1277,8 +1263,7 @@ void FileReceiveTicker(void) if (file->ackresendposition != UINT32_MAX && file->status == FS_DOWNLOADING) { // Acknowledge ~70 MB/s, whichs means the client sends ~18 KB/s - INT32 j; - for (j = 0; j < 2048; j++) + for (INT32 j = 0; j < 2048; j++) { if (file->receivedfragments[file->ackresendposition]) AddFragmentToAckPacket(file->ackpacket, file->iteration, file->ackresendposition, i); @@ -1500,15 +1485,14 @@ void SV_AbortSendFiles(INT32 node) void CloseNetFile(void) { - INT32 i; // Is sending? - for (i = 0; i < MAXNETNODES; i++) + for (INT32 i = 0; i < MAXNETNODES; i++) SV_AbortSendFiles(i); // Receiving a file? if (fileneeded) { - for (i = 0; i < fileneedednum; i++) + for (INT32 i = 0; i < fileneedednum; i++) if (fileneeded[i].status == FS_DOWNLOADING && fileneeded[i].file) { fclose(fileneeded[i].file); @@ -1541,9 +1525,7 @@ void CloseNetFile(void) void Command_Downloads_f(void) { - INT32 node; - - for (node = 0; node < MAXNETNODES; node++) + for (INT32 node = 0; node < MAXNETNODES; node++) if (transfer[node].txlist && transfer[node].txlist->ram == SF_FILE) // Node is downloading a file? { @@ -1577,14 +1559,11 @@ void Command_Downloads_f(void) void nameonly(char *s) { - size_t j, len; - void *ns; - - for (j = strlen(s); j != (size_t)-1; j--) + for (size_t j = strlen(s); j != (size_t)-1; j--) if ((s[j] == '\\') || (s[j] == ':') || (s[j] == '/')) { - ns = &(s[j+1]); - len = strlen(ns); + void *ns = &(s[j+1]); + size_t len = strlen(ns); #if 0 M_Memcpy(s, ns, len+1); #else @@ -1597,9 +1576,9 @@ void nameonly(char *s) // Returns the length in characters of the last element of a path. size_t nameonlylength(const char *s) { - size_t j, len = strlen(s); + size_t len = strlen(s); - for (j = len; j != (size_t)-1; j--) + for (size_t j = len; j != (size_t)-1; j--) if ((s[j] == '\\') || (s[j] == ':') || (s[j] == '/')) return len - j - 1; diff --git a/src/netcode/gamestate.c b/src/netcode/gamestate.c index 4a3e9f3af..d284164c0 100644 --- a/src/netcode/gamestate.c +++ b/src/netcode/gamestate.c @@ -43,9 +43,7 @@ boolean cl_redownloadinggamestate = false; boolean SV_ResendingSavegameToAnyone(void) { - INT32 i; - - for (i = 0; i < MAXNETNODES; i++) + for (INT32 i = 0; i < MAXNETNODES; i++) if (netnodes[i].resendingsavegame) return true; return false; @@ -236,9 +234,7 @@ void CL_LoadReceivedSavegame(boolean reloading) void CL_ReloadReceivedSavegame(void) { - INT32 i; - - for (i = 0; i < MAXPLAYERS; i++) + for (INT32 i = 0; i < MAXPLAYERS; i++) { LUA_InvalidatePlayer(&players[i]); sprintf(player_names[i], "Player %d", i + 1); diff --git a/src/netcode/i_tcp.c b/src/netcode/i_tcp.c index 6baba6275..bd950c355 100644 --- a/src/netcode/i_tcp.c +++ b/src/netcode/i_tcp.c @@ -416,24 +416,20 @@ static boolean SOCK_cmpaddr(mysockaddr_t *a, mysockaddr_t *b, UINT8 mask) */ static void cleanupnodes(void) { - SINT8 j; - if (!Playing()) return; // Why can't I start at zero? - for (j = 1; j < MAXNETNODES; j++) + for (SINT8 j = 1; j < MAXNETNODES; j++) if (!(netnodes[j].ingame || SendingFile(j))) nodeconnected[j] = false; } static SINT8 getfreenode(void) { - SINT8 j; - cleanupnodes(); - for (j = 0; j < MAXNETNODES; j++) + for (SINT8 j = 0; j < MAXNETNODES; j++) if (!nodeconnected[j]) { nodeconnected[j] = true; @@ -446,7 +442,7 @@ static SINT8 getfreenode(void) * downloading a needed wad, but it's better than not letting anyone join... */ /*I_Error("No more free nodes!!1!11!11!!1111\n"); - for (j = 1; j < MAXNETNODES; j++) + for (SINT8 j = 1; j < MAXNETNODES; j++) if (!netnodes[j].ingame) return j;*/ @@ -458,9 +454,8 @@ void Command_Numnodes(void) { INT32 connected = 0; INT32 ingame = 0; - INT32 i; - for (i = 1; i < MAXNETNODES; i++) + for (INT32 i = 1; i < MAXNETNODES; i++) { if (!(nodeconnected[i] || netnodes[i].ingame)) continue; @@ -496,13 +491,13 @@ void Command_Numnodes(void) // Returns true if a packet was received from a new node, false in all other cases static boolean SOCK_Get(void) { - size_t i, n; + size_t i; int j; ssize_t c; mysockaddr_t fromaddress; socklen_t fromlen; - for (n = 0; n < mysocketses; n++) + for (size_t n = 0; n < mysocketses; n++) { fromlen = (socklen_t)sizeof(fromaddress); c = recvfrom(mysockets[n], (char *)&doomcom->data, MAXPACKETLENGTH, 0, @@ -563,10 +558,9 @@ static fd_set masterset; #ifdef SELECTTEST static boolean FD_CPY(fd_set *src, fd_set *dst, SOCKET_TYPE *fd, size_t len) { - size_t i; boolean testset = false; FD_ZERO(dst); - for (i = 0; i < len;i++) + for (size_t i = 0; i < len;i++) { if(fd[i] != (SOCKET_TYPE)ERRSOCKET && FD_ISSET(fd[i], src) && !FD_ISSET(fd[i], dst)) // no checking for dups @@ -630,16 +624,15 @@ static inline ssize_t SOCK_SendToAddr(SOCKET_TYPE socket, mysockaddr_t *sockaddr static void SOCK_Send(void) { ssize_t c = ERRSOCKET; - size_t i, j; if (!nodeconnected[doomcom->remotenode]) return; if (doomcom->remotenode == BROADCASTADDR) { - for (i = 0; i < mysocketses; i++) + for (size_t i = 0; i < mysocketses; i++) { - for (j = 0; j < broadcastaddresses; j++) + for (size_t j = 0; j < broadcastaddresses; j++) { if (myfamily[i] == broadcastaddress[j].any.sa_family) SOCK_SendToAddr(mysockets[i], &broadcastaddress[j]); @@ -649,7 +642,7 @@ static void SOCK_Send(void) } else if (nodesocket[doomcom->remotenode] == (SOCKET_TYPE)ERRSOCKET) { - for (i = 0; i < mysocketses; i++) + for (size_t i = 0; i < mysocketses; i++) { if (myfamily[i] == clientaddress[doomcom->remotenode].any.sa_family) SOCK_SendToAddr(mysockets[i], &clientaddress[doomcom->remotenode]); @@ -1082,8 +1075,7 @@ boolean I_InitTcpDriver(void) static void SOCK_CloseSocket(void) { - size_t i; - for (i=0; i < MAXNETNODES+1; i++) + for (size_t i=0; i < MAXNETNODES+1; i++) { if (mysockets[i] != (SOCKET_TYPE)ERRSOCKET && FD_ISSET(mysockets[i], &masterset)) @@ -1154,12 +1146,10 @@ static SINT8 SOCK_NetMakeNodewPort(const char *address, const char *port) static boolean SOCK_OpenSocket(void) { - size_t i; - memset(clientaddress, 0, sizeof (clientaddress)); nodeconnected[0] = true; // always connected to self - for (i = 1; i < MAXNETNODES; i++) + for (size_t i = 1; i < MAXNETNODES; i++) nodeconnected[i] = false; nodeconnected[BROADCASTADDR] = true; I_NetSend = SOCK_Send; diff --git a/src/netcode/net_command.c b/src/netcode/net_command.c index 11b351af7..887b7fa2a 100644 --- a/src/netcode/net_command.c +++ b/src/netcode/net_command.c @@ -90,13 +90,11 @@ void D_FreeTextcmd(tic_t tic) if (textcmdtic) { - INT32 i; - // Remove this tic from the list. *tctprev = textcmdtic->next; // Free all players. - for (i = 0; i < TEXTCMD_HASH_SIZE; i++) + for (INT32 i = 0; i < TEXTCMD_HASH_SIZE; i++) { textcmdplayer_t *textcmdplayer = textcmdtic->playercmds[i]; @@ -174,9 +172,7 @@ UINT8* D_GetTextcmd(tic_t tic, INT32 playernum) void ExtraDataTicker(void) { - INT32 i; - - for (i = 0; i < MAXPLAYERS; i++) + for (INT32 i = 0; i < MAXPLAYERS; i++) if (playeringame[i] || i == 0) { UINT8 *bufferstart = D_GetExistingTextcmd(gametic, i); @@ -221,10 +217,9 @@ void ExtraDataTicker(void) // used at txtcmds received to check packetsize bound 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++) + for (INT32 i = 0; i < MAXPLAYERS; i++) { UINT8 *textcmd = D_GetExistingTextcmd(tic, i); if ((!i || playeringame[i]) && textcmd) diff --git a/src/netcode/server_connection.c b/src/netcode/server_connection.c index ed0e28309..f8ec3c7bd 100644 --- a/src/netcode/server_connection.c +++ b/src/netcode/server_connection.c @@ -55,7 +55,6 @@ 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) @@ -71,7 +70,7 @@ static INT32 FindRejoinerNum(SINT8 node) *port = '\0'; // Check if any player matches the stripped address - for (i = 0; i < MAXPLAYERS; i++) + for (INT32 i = 0; i < MAXPLAYERS; i++) { if (playeringame[i] && playeraddress[i][0] && playernode[i] == UINT8_MAX && !strcmp(playeraddress[i], strippednodeaddress)) @@ -162,10 +161,9 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime) static void SV_SendPlayerInfo(INT32 node) { - UINT8 i; netbuffer->packettype = PT_PLAYERINFO; - for (i = 0; i < MAXPLAYERS; i++) + for (UINT8 i = 0; i < MAXPLAYERS; i++) { if (!playeringame[i]) { @@ -425,7 +423,6 @@ void PT_ClientJoin(SINT8 node) char names[MAXSPLITSCREENPLAYERS][MAXPLAYERNAME + 1]; INT32 numplayers = netbuffer->u.clientcfg.localplayers; INT32 rejoinernum; - INT32 i; // Ignore duplicate packets if (client || netnodes[node].ingame) @@ -440,7 +437,7 @@ void PT_ClientJoin(SINT8 node) return; } - for (i = 0; i < numplayers; i++) + for (INT32 i = 0; i < numplayers; i++) { strlcpy(names[i], netbuffer->u.clientcfg.names[i], MAXPLAYERNAME + 1); if (!EnsurePlayerNameIsGood(names[i], rejoinernum)) @@ -469,7 +466,7 @@ void PT_ClientJoin(SINT8 node) } // Splitscreen can allow 2 players in one node - for (i = 0; i < numplayers; i++) + for (INT32 i = 0; i < numplayers; i++) SV_AddPlayer(node, names[i]); joindelay += cv_joindelay.value * TICRATE; diff --git a/src/netcode/tic_command.c b/src/netcode/tic_command.c index bf8c5d21d..befe8a5cd 100644 --- a/src/netcode/tic_command.c +++ b/src/netcode/tic_command.c @@ -80,11 +80,9 @@ tic_t ExpandTics(INT32 low, INT32 node) void D_Clearticcmd(tic_t tic) { - INT32 i; - D_FreeTextcmd(tic); - for (i = 0; i < MAXPLAYERS; i++) + for (INT32 i = 0; i < MAXPLAYERS; i++) netcmds[tic%BACKUPTICS][i].angleturn = 0; DEBFILE(va("clear tic %5u (%2u)\n", tic, tic%BACKUPTICS)); @@ -92,13 +90,11 @@ void D_Clearticcmd(tic_t tic) 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++) + for (INT32 i = 0; i < TEXTCMD_HASH_SIZE; i++) while (textcmds[i]) D_Clearticcmd(textcmds[i]->tic); } @@ -229,8 +225,7 @@ void PT_ServerTics(SINT8 node, INT32 netconsole) realstart = netbuffer->u.serverpak.starttic; realend = realstart + netbuffer->u.serverpak.numtics; - if (realend > gametic + CLIENTBACKUPTICS) - realend = gametic + CLIENTBACKUPTICS; + realend = min(realend, gametic + CLIENTBACKUPTICS); cl_packetmissed = realstart > neededtic; if (realstart <= neededtic && realend > neededtic) @@ -304,9 +299,8 @@ void CL_SendClientCmd(void) static tic_t SV_CalculateNumTicsForPacket(SINT8 nodenum, tic_t firsttic, tic_t lasttic) { size_t size = BASESERVERTICSSIZE; - tic_t tic; - for (tic = firsttic; tic < lasttic; tic++) + for (tic_t tic = firsttic; tic < lasttic; tic++) { size += sizeof (ticcmd_t) * doomcom->numslots; size += TotalTextCmdPerTic(tic); @@ -344,15 +338,12 @@ static tic_t SV_CalculateNumTicsForPacket(SINT8 nodenum, tic_t firsttic, tic_t l // send tic from firstticstosend to maketic-1 void SV_SendTics(void) { - tic_t realfirsttic, lasttictosend, i; - UINT32 n; - size_t packsize; - UINT8 *bufpos; + tic_t realfirsttic, lasttictosend; // send to all client but not to me // for each node create a packet with x tics and send it // x is computed using netnodes[n].supposedtic, max packet size and maketic - for (n = 1; n < MAXNETNODES; n++) + for (INT32 n = 1; n < MAXNETNODES; n++) if (netnodes[n].ingame) { // assert netnodes[n].supposedtic>=netnodes[n].tic @@ -367,42 +358,42 @@ void SV_SendTics(void) // (getpacket servertics case) DEBFILE(va("Nothing to send node %u mak=%u sup=%u net=%u \n", n, maketic, netnodes[n].supposedtic, netnodes[n].tic)); + realfirsttic = netnodes[n].tic; + if (realfirsttic >= lasttictosend || (I_GetTime() + n)&3) // all tic are ok continue; + DEBFILE(va("Sent %d anyway\n", realfirsttic)); } - if (realfirsttic < firstticstosend) - realfirsttic = firstticstosend; + realfirsttic = max(realfirsttic, firstticstosend); lasttictosend = realfirsttic + SV_CalculateNumTicsForPacket(n, realfirsttic, lasttictosend); - // Send the tics + // Prepare the packet header 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++) - { + // Fill and send the packet + UINT8 *bufpos = (UINT8 *)&netbuffer->u.serverpak.cmds; + for (tic_t 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++) - SV_WriteNetCommandsForTic(); - packsize = bufpos - (UINT8 *)&(netbuffer->u); - + for (tic_t i = realfirsttic; i < lasttictosend; i++) + SV_WriteNetCommandsForTic(i, &bufpos); + size_t 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) netnodes[n].supposedtic = lasttictosend-doomcom->extratics; else netnodes[n].supposedtic = lasttictosend; - if (netnodes[n].supposedtic < netnodes[n].tic) netnodes[n].supposedtic = netnodes[n].tic; + netnodes[n].supposedtic = max(netnodes[n].supposedtic, netnodes[n].tic); } + // node 0 is me! netnodes[0].supposedtic = maketic; } @@ -413,7 +404,8 @@ void Local_Maketic(INT32 realtics) D_ProcessEvents(); // menu responder, cons responder, // game responder calls HU_Responder, AM_Responder, // and G_MapEventsToControls - if (!dedicated) rendergametic = gametic; + if (!dedicated) + rendergametic = gametic; // translate inputs (keyboard/mouse/gamepad) into game controls G_BuildTiccmd(&localcmds, realtics, 1); if (splitscreen || botingame) @@ -426,9 +418,7 @@ void Local_Maketic(INT32 realtics) // create missed tic void SV_Maketic(void) { - INT32 i; - - for (i = 0; i < MAXPLAYERS; i++) + for (INT32 i = 0; i < MAXPLAYERS; i++) { if (!playeringame[i]) continue; From 69af7e1ea486d946557004eb308508ac1a56fb79 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sat, 14 Jan 2023 20:02:20 +0100 Subject: [PATCH 358/586] Add missing include directive --- src/netcode/net_command.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/netcode/net_command.c b/src/netcode/net_command.c index 887b7fa2a..efc8bd0ef 100644 --- a/src/netcode/net_command.c +++ b/src/netcode/net_command.c @@ -16,6 +16,7 @@ #include "server_connection.h" #include "d_clisrv.h" #include "i_net.h" +#include "../byteptr.h" #include "../g_game.h" #include "../z_zone.h" #include "../doomtype.h" From 6f536835194bee1dfbd495ba658cf9ab3ca29ef3 Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sun, 15 Jan 2023 13:08:31 +0100 Subject: [PATCH 359/586] Cleanup --- src/netcode/gamestate.c | 3 +-- src/netcode/tic_command.c | 43 +++++++++++++++++++++------------------ src/netcode/tic_command.h | 2 +- 3 files changed, 25 insertions(+), 23 deletions(-) diff --git a/src/netcode/gamestate.c b/src/netcode/gamestate.c index d284164c0..c1ceb95b5 100644 --- a/src/netcode/gamestate.c +++ b/src/netcode/gamestate.c @@ -242,8 +242,7 @@ void CL_ReloadReceivedSavegame(void) CL_LoadReceivedSavegame(true); - if (neededtic < gametic) - neededtic = gametic; + neededtic = max(neededtic, gametic); maketic = neededtic; ticcmd_oldangleturn[0] = players[consoleplayer].oldrelangleturn; diff --git a/src/netcode/tic_command.c b/src/netcode/tic_command.c index befe8a5cd..0fbf87c0c 100644 --- a/src/netcode/tic_command.c +++ b/src/netcode/tic_command.c @@ -148,8 +148,9 @@ static void CheckConsistancy(SINT8 nodenum, tic_t tic) } } -void PT_ClientCmd(SINT8 node, INT32 netconsole) +void PT_ClientCmd(SINT8 nodenum, INT32 netconsole) { + netnode_t *node = &netnodes[nodenum]; tic_t realend, realstart; if (client) @@ -157,24 +158,24 @@ void PT_ClientCmd(SINT8 node, INT32 netconsole) // 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); + realstart = ExpandTics(netbuffer->u.clientpak.client_tic, nodenum); + realend = ExpandTics(netbuffer->u.clientpak.resendfrom, nodenum); if (netbuffer->packettype == PT_CLIENTMIS || netbuffer->packettype == PT_CLIENT2MIS || netbuffer->packettype == PT_NODEKEEPALIVEMIS - || netnodes[node].supposedtic < realend) + || node->supposedtic < realend) { - netnodes[node].supposedtic = realend; + node->supposedtic = realend; } // Discard out of order packet - if (netnodes[node].tic > realend) + if (node->tic > realend) { - DEBFILE(va("out of order ticcmd discarded nettics = %u\n", netnodes[node].tic)); + DEBFILE(va("out of order ticcmd discarded nettics = %u\n", node->tic)); return; } // Update the nettics - netnodes[node].tic = realend; + node->tic = realend; // Don't do anything for packets of type NODEKEEPALIVE? if (netconsole == -1 || netbuffer->packettype == PT_NODEKEEPALIVE @@ -183,19 +184,19 @@ void PT_ClientCmd(SINT8 node, INT32 netconsole) // 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? - netnodes[node].freezetimeout = I_GetTime() + connectiontimeout; + node->freezetimeout = I_GetTime() + connectiontimeout; // Copy ticcmd G_MoveTiccmd(&netcmds[maketic%BACKUPTICS][netconsole], &netbuffer->u.clientpak.cmd, 1); // Splitscreen cmd if ((netbuffer->packettype == PT_CLIENT2CMD || netbuffer->packettype == PT_CLIENT2MIS) - && netnodes[node].player2 >= 0) - G_MoveTiccmd(&netcmds[maketic%BACKUPTICS][(UINT8)netnodes[node].player2], + && node->player2 >= 0) + G_MoveTiccmd(&netcmds[maketic%BACKUPTICS][(UINT8)node->player2], &netbuffer->u.client2pak.cmd2, 1); CheckTiccmdHacks(netconsole); - CheckConsistancy(node, realstart); + CheckConsistancy(nodenum, realstart); } void PT_ServerTics(SINT8 node, INT32 netconsole) @@ -346,9 +347,11 @@ void SV_SendTics(void) for (INT32 n = 1; n < MAXNETNODES; n++) if (netnodes[n].ingame) { - // assert netnodes[n].supposedtic>=netnodes[n].tic - realfirsttic = netnodes[n].supposedtic; - lasttictosend = min(maketic, netnodes[n].tic + CLIENTBACKUPTICS); + netnode_t *node = netnodes[n]; + + // assert node->supposedtic>=node->tic + realfirsttic = node->supposedtic; + lasttictosend = min(maketic, node->tic + CLIENTBACKUPTICS); if (realfirsttic >= lasttictosend) { @@ -357,9 +360,9 @@ void SV_SendTics(void) // 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, netnodes[n].supposedtic, netnodes[n].tic)); + n, maketic, node->supposedtic, node->tic)); - realfirsttic = netnodes[n].tic; + realfirsttic = node->tic; if (realfirsttic >= lasttictosend || (I_GetTime() + n)&3) // all tic are ok @@ -388,10 +391,10 @@ void SV_SendTics(void) // when tic are too large, only one tic is sent so don't go backward! if (lasttictosend-doomcom->extratics > realfirsttic) - netnodes[n].supposedtic = lasttictosend-doomcom->extratics; + node->supposedtic = lasttictosend-doomcom->extratics; else - netnodes[n].supposedtic = lasttictosend; - netnodes[n].supposedtic = max(netnodes[n].supposedtic, netnodes[n].tic); + node->supposedtic = lasttictosend; + node->supposedtic = max(node->supposedtic, node->tic); } // node 0 is me! diff --git a/src/netcode/tic_command.h b/src/netcode/tic_command.h index d19f4c1aa..289750fb3 100644 --- a/src/netcode/tic_command.h +++ b/src/netcode/tic_command.h @@ -31,7 +31,7 @@ tic_t ExpandTics(INT32 low, INT32 node); void D_Clearticcmd(tic_t tic); void D_ResetTiccmds(void); -void PT_ClientCmd(SINT8 node, INT32 netconsole); +void PT_ClientCmd(SINT8 nodenum, INT32 netconsole); void PT_ServerTics(SINT8 node, INT32 netconsole); // send the client packet to the server From 7f4e82e7d9e1fdb5f01b3381c0f70d3c70eea7dd Mon Sep 17 00:00:00 2001 From: LJ Sonic Date: Sun, 15 Jan 2023 13:10:23 +0100 Subject: [PATCH 360/586] Cleanup comments --- src/netcode/client_connection.c | 41 ++++++++++++++------------------- src/netcode/d_clisrv.c | 11 ++++----- src/netcode/protocol.h | 3 +-- src/netcode/tic_command.c | 35 ++++++++++++++-------------- 4 files changed, 39 insertions(+), 51 deletions(-) diff --git a/src/netcode/client_connection.c b/src/netcode/client_connection.c index faa91b6d7..d363d7d5a 100644 --- a/src/netcode/client_connection.c +++ b/src/netcode/client_connection.c @@ -34,7 +34,7 @@ cl_mode_t cl_mode = CL_SEARCHING; static UINT16 cl_lastcheckedfilecount = 0; // used for full file list -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 +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 tic_t firstconnectattempttime = 0; UINT8 mynode; static void *snake = NULL; @@ -137,7 +137,7 @@ static inline void CL_DrawConnectionStatus(void) V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-16-16, V_YELLOWMAP, "Press ESC to abort"); - //ima just count files here + // ima just count files here if (fileneeded) { for (INT32 i = 0; i < fileneedednum; i++) @@ -248,7 +248,7 @@ boolean CL_SendJoin(void) CleanupPlayerName(consoleplayer, cv_playername.zstring); if (splitscreen) - CleanupPlayerName(1, cv_playername2.zstring);/* 1 is a HACK? oh no */ + 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); @@ -306,14 +306,14 @@ static void SL_InsertServer(serverinfo_pak* info, SINT8 node) if (serverlistcount >= MAXSERVERLIST) return; // list full - /* check it later if connecting to this one */ + // check it later if connecting to this one if (node != servernode) { if (info->_255 != 255) - return;/* old packet format */ + return; // Old packet format if (info->packetversion != PACKETVERSION) - return;/* old new packet format */ + return; // Old new packet format if (info->version != VERSION) return; // Not same version. @@ -322,7 +322,7 @@ static void SL_InsertServer(serverinfo_pak* info, SINT8 node) return; // Close, but no cigar. if (strcmp(info->application, SRB2APPLICATION)) - return;/* that's a different mod */ + return; // That's a different mod } i = serverlistcount++; @@ -380,7 +380,7 @@ Fetch_servers_thread (struct Fetch_servers_ctx *ctx) free(ctx); } -#endif/*defined (MASTERSERVER) && defined (HAVE_THREADS)*/ +#endif // defined (MASTERSERVER) && defined (HAVE_THREADS) void CL_QueryServerList (msg_server_t *server_list) { @@ -389,7 +389,7 @@ void CL_QueryServerList (msg_server_t *server_list) // Make sure MS version matches our own, to // thwart nefarious servers who lie to the MS. - /* lol bruh, that version COMES from the servers */ + // 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); @@ -441,7 +441,7 @@ void CL_UpdateServerList(boolean internetsearch, INT32 room) ctx = malloc(sizeof *ctx); - /* This called from M_Refresh so I don't use a mutex */ + // This called from M_Refresh so I don't use a mutex m_waiting_mode = M_WAITING_SERVERS; I_lock_mutex(&ms_QueryId_mutex); @@ -465,7 +465,7 @@ void CL_UpdateServerList(boolean internetsearch, INT32 room) } #endif } -#endif/*MASTERSERVER*/ +#endif // MASTERSERVER } static void M_ConfirmConnect(event_t *ev) @@ -619,7 +619,7 @@ static const char * InvalidServerReason (serverinfo_pak *info) { #define EOT "\nPress ESC\n" - /* magic number for new packet format */ + // Magic number for new packet format if (info->_255 != 255) { return @@ -691,10 +691,10 @@ static boolean CL_ServerConnectionSearchTicker(tic_t *asksent) { INT32 i; - // serverlist is updated by GetPacket function + // serverlist is updated by GetPackets if (serverlistcount > 0) { - // this can be a responce to our broadcast request + // This can be a response to our broadcast request if (servernode == -1 || servernode >= MAXNETNODES) { i = 0; @@ -819,7 +819,7 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic if (CL_LoadServerFiles()) { FreeFileNeeded(); - *asksent = 0; //This ensure the first join ask is right away + *asksent = 0; // This ensures the first join request is right away firstconnectattempttime = I_GetTime(); cl_mode = CL_ASKJOIN; } @@ -841,9 +841,7 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic return false; } - // 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... + // Prepare structures to save the file CL_PrepareDownloadSaveGame(tmpsave); if (I_GetTime() >= *asksent && CL_SendJoin()) @@ -954,11 +952,6 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic #define TMPSAVENAME "$$$.sav" -/** Use adaptive send using net_bandwidth and stat.sendbytes - * - * \todo Better description... - * - */ void CL_ConnectToServer(void) { INT32 pnumnodes, nodewaited = doomcom->numnodes, i; @@ -1158,7 +1151,7 @@ void PT_ServerCFG(SINT8 node) DEBFILE(va("Server accept join gametic=%u mynode=%d\n", gametic, mynode)); /// \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? + /// Shouldn't they be downloaded even at intermission time? /// Also, according to PT_ClientJoin, the server will send the savegame even during intermission... if (netbuffer->u.servercfg.gamestate == GS_LEVEL/* || netbuffer->u.servercfg.gamestate == GS_INTERMISSION*/) diff --git a/src/netcode/d_clisrv.c b/src/netcode/d_clisrv.c index 105526dd2..18eae580c 100644 --- a/src/netcode/d_clisrv.c +++ b/src/netcode/d_clisrv.c @@ -1252,8 +1252,8 @@ void NetUpdate(void) 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 + // The client sends the command after receiving from the server + // The server sends it before because this is better in single player #ifdef MASTERSERVER MasterClient_Ticker(); // Acking the Master Server @@ -1402,7 +1402,7 @@ SINT8 nametonum(const char *name) return -1; } -// is there a game running +// Is there a game running? boolean Playing(void) { return (server && serverrunning) || (client && cl_mode == CL_CONNECTED); @@ -1423,11 +1423,8 @@ INT32 D_NumPlayers(void) } // -// NetUpdate -// Builds ticcmds for console player, -// sends out a packet +// Consistancy // -// no more use random generator, because at very first tic isn't yet synchronized // Note: It is called consistAncy on purpose. // INT16 Consistancy(void) diff --git a/src/netcode/protocol.h b/src/netcode/protocol.h index 374cc5bff..9866e4c5a 100644 --- a/src/netcode/protocol.h +++ b/src/netcode/protocol.h @@ -123,13 +123,12 @@ typedef struct #endif // Server to client packet -// this packet is too large typedef struct { tic_t starttic; UINT8 numtics; UINT8 numslots; // "Slots filled": Highest player number in use plus one. - ticcmd_t cmds[45]; // Normally [BACKUPTIC][MAXPLAYERS] but too large + ticcmd_t cmds[45]; } ATTRPACK servertics_pak; typedef struct diff --git a/src/netcode/tic_command.c b/src/netcode/tic_command.c index 0fbf87c0c..620a10f7a 100644 --- a/src/netcode/tic_command.c +++ b/src/netcode/tic_command.c @@ -24,8 +24,8 @@ #include "../doomstat.h" #include "../doomtype.h" -tic_t firstticstosend; // min of the nettics -tic_t tictoclear = 0; // optimize d_clearticcmd +tic_t firstticstosend; // Smallest netnode.tic +tic_t tictoclear = 0; // Optimize D_ClearTiccmd ticcmd_t localcmds; ticcmd_t localcmds2; boolean cl_packetmissed; @@ -312,10 +312,9 @@ static tic_t SV_CalculateNumTicsForPacket(SINT8 nodenum, tic_t firsttic, tic_t l sizeu1(size), tic, firsttic, lasttic)); lasttic = tic; - // 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 + // Too bad: too many players have sent extra data + // and there is too much data for a single tic. + // To avoid that, keep the data for the next tic (see PT_TEXTCMD). if (lasttic == firsttic) { if (size > MAXPACKETLENGTH) @@ -335,15 +334,15 @@ static tic_t SV_CalculateNumTicsForPacket(SINT8 nodenum, tic_t firsttic, tic_t l return lasttic - firsttic; } -// send the server packet -// send tic from firstticstosend to maketic-1 +// Sends the server packet +// Sends tic/net commands from firstticstosend to maketic-1 void SV_SendTics(void) { tic_t realfirsttic, lasttictosend; - // send to all client but not to me - // for each node create a packet with x tics and send it - // x is computed using netnodes[n].supposedtic, max packet size and maketic + // Send to all clients except yourself + // For each node, create a packet with x tics and send it + // x is computed using node.supposedtic, max packet size and maketic for (INT32 n = 1; n < MAXNETNODES; n++) if (netnodes[n].ingame) { @@ -355,17 +354,17 @@ void SV_SendTics(void) 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) + // Well, we have sent all the tics, so we will use extra bandwidth + // to resend packets that are supposed lost. + // This is necessary since lost packet detection + // works when we receive a packet with firsttic > neededtic (PT_SERVERTICS) DEBFILE(va("Nothing to send node %u mak=%u sup=%u net=%u \n", n, maketic, node->supposedtic, node->tic)); realfirsttic = node->tic; if (realfirsttic >= lasttictosend || (I_GetTime() + n)&3) - // all tic are ok + // All tics are Ok continue; DEBFILE(va("Sent %d anyway\n", realfirsttic)); @@ -389,7 +388,7 @@ void SV_SendTics(void) size_t 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! + // When tics are too large, only one tic is sent so don't go backwards! if (lasttictosend-doomcom->extratics > realfirsttic) node->supposedtic = lasttictosend-doomcom->extratics; else @@ -450,6 +449,6 @@ void SV_Maketic(void) } } - // all tic are now proceed make the next + // All tics have been processed, make the next maketic++; } From 97311dc5b00ab232a6e898c085c20d2f6bdbfa3b Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Thu, 27 Jul 2023 19:15:35 -0300 Subject: [PATCH 361/586] Use separate table for maskedtexturecol --- src/r_defs.h | 4 +- src/r_main.c | 1 + src/r_plane.c | 6 - src/r_plane.h | 3 - src/r_segs.c | 729 +++++++++++++++++++++++++------------------------- src/r_segs.h | 1 + 6 files changed, 365 insertions(+), 379 deletions(-) diff --git a/src/r_defs.h b/src/r_defs.h index a9b9a4a08..dfd2d6d70 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -757,12 +757,12 @@ typedef struct drawseg_s // Pointers to lists for sprite clipping, all three adjusted so [x1] is first value. INT16 *sprtopclip; INT16 *sprbottomclip; - INT16 *maskedtexturecol; + fixed_t *maskedtexturecol; struct visplane_s *ffloorplanes[MAXFFLOORS]; INT32 numffloorplanes; struct ffloor_s *thicksides[MAXFFLOORS]; - INT16 *thicksidecol; + fixed_t *thicksidecol; INT32 numthicksides; fixed_t frontscale[MAXVIDWIDTH]; diff --git a/src/r_main.c b/src/r_main.c index 55bb9c4ff..952171405 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1479,6 +1479,7 @@ void R_RenderPlayerView(player_t *player) R_ClearClipSegs(); } R_ClearDrawSegs(); + R_ClearSegTables(); R_ClearSprites(); Portal_InitList(); diff --git a/src/r_plane.c b/src/r_plane.c index c568484b6..29ce26b29 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -53,10 +53,6 @@ INT32 numffloors; #define visplane_hash(picnum,lightlevel,height) \ ((unsigned)((picnum)*3+(lightlevel)+(height)*7) & VISPLANEHASHMASK) -//SoM: 3/23/2000: Use boom opening limit removal -size_t maxopenings; -INT16 *openings, *lastopening; /// \todo free leak - // // Clip values are the solid pixel bounding the range. // floorclip starts out SCREENHEIGHT @@ -366,8 +362,6 @@ void R_ClearPlanes(void) freehead = &(*freehead)->next; } - lastopening = openings; - // texture calculation memset(cachedheight, 0, sizeof (cachedheight)); } diff --git a/src/r_plane.h b/src/r_plane.h index 9870a43e2..917e8b041 100644 --- a/src/r_plane.h +++ b/src/r_plane.h @@ -60,9 +60,6 @@ extern visplane_t *floorplane; extern visplane_t *ceilingplane; // Visplane related. -extern INT16 *lastopening, *openings; -extern size_t maxopenings; - extern INT16 floorclip[MAXVIDWIDTH], ceilingclip[MAXVIDWIDTH]; extern fixed_t frontscale[MAXVIDWIDTH], yslopetab[MAXVIDHEIGHT*16]; extern fixed_t cachedheight[MAXVIDHEIGHT]; diff --git a/src/r_segs.c b/src/r_segs.c index facab62ab..9ee3bcfec 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -71,9 +71,22 @@ static fixed_t topfrac, topstep; static fixed_t bottomfrac, bottomstep; static lighttable_t **walllights; -static INT16 *maskedtexturecol; +static fixed_t *maskedtexturecol; static fixed_t *maskedtextureheight = NULL; +//SoM: 3/23/2000: Use boom opening limit removal +static size_t numopenings; +static INT16 *openings, *lastopening; + +static size_t texturecolumntablesize; +static fixed_t *texturecolumntable, *curtexturecolumntable; + +void R_ClearSegTables(void) +{ + lastopening = openings; + curtexturecolumntable = texturecolumntable; +} + // ========================================================================== // R_RenderMaskedSegRange // ========================================================================== @@ -350,170 +363,115 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) dc_texturemid += (textureheight[texnum])*times + textureheight[texnum]; else dc_texturemid -= (textureheight[texnum])*times; - // calculate lighting - if (maskedtexturecol[dc_x] != INT16_MAX) + + // Check for overflows first + overflow_test = (INT64)centeryfrac - (((INT64)dc_texturemid*spryscale)>>FRACBITS); + if (overflow_test < 0) overflow_test = -overflow_test; + if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) { - // Check for overflows first - overflow_test = (INT64)centeryfrac - (((INT64)dc_texturemid*spryscale)>>FRACBITS); - if (overflow_test < 0) overflow_test = -overflow_test; - if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) + // Eh, no, go away, don't waste our time + if (dc_numlights) { - // Eh, no, go away, don't waste our time - if (dc_numlights) + for (i = 0; i < dc_numlights; i++) { - for (i = 0; i < dc_numlights; i++) + rlight = &dc_lightlist[i]; + rlight->height += rlight->heightstep; + } + } + spryscale += rw_scalestep; + continue; + } + + // calculate lighting + if (dc_numlights) + { + lighttable_t **xwalllights; + + sprbotscreen = INT32_MAX; + sprtopscreen = windowtop = (centeryfrac - FixedMul(dc_texturemid, spryscale)); + + realbot = windowbottom = FixedMul(textureheight[texnum], spryscale) + sprtopscreen; + dc_iscale = 0xffffffffu / (unsigned)spryscale; + + // draw the texture + col = (column_t *)((UINT8 *)R_GetColumn(texnum, (maskedtexturecol[dc_x] >> FRACBITS)) - 3); + + for (i = 0; i < dc_numlights; i++) + { + rlight = &dc_lightlist[i]; + + if ((rlight->flags & FOF_NOSHADE)) + continue; + + if (rlight->lightnum < 0) + xwalllights = scalelight[0]; + else if (rlight->lightnum >= LIGHTLEVELS) + xwalllights = scalelight[LIGHTLEVELS-1]; + else + xwalllights = scalelight[rlight->lightnum]; + + pindex = FixedMul(spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT; + + if (pindex >= MAXLIGHTSCALE) + pindex = MAXLIGHTSCALE - 1; + + if (rlight->extra_colormap) + rlight->rcolormap = rlight->extra_colormap->colormap + (xwalllights[pindex] - colormaps); + else + rlight->rcolormap = xwalllights[pindex]; + + height = rlight->height; + rlight->height += rlight->heightstep; + + if (height <= windowtop) + { + dc_colormap = rlight->rcolormap; + continue; + } + + windowbottom = height; + if (windowbottom >= realbot) + { + windowbottom = realbot; + colfunc_2s(col); + for (i++; i < dc_numlights; i++) { rlight = &dc_lightlist[i]; rlight->height += rlight->heightstep; } + + continue; } - spryscale += rw_scalestep; - continue; - } - - if (dc_numlights) - { - lighttable_t **xwalllights; - - sprbotscreen = INT32_MAX; - sprtopscreen = windowtop = (centeryfrac - FixedMul(dc_texturemid, spryscale)); - - realbot = windowbottom = FixedMul(textureheight[texnum], spryscale) + sprtopscreen; - dc_iscale = 0xffffffffu / (unsigned)spryscale; - - // draw the texture - col = (column_t *)((UINT8 *)R_GetColumn(texnum, maskedtexturecol[dc_x]) - 3); - - for (i = 0; i < dc_numlights; i++) - { - rlight = &dc_lightlist[i]; - - if ((rlight->flags & FOF_NOSHADE)) - continue; - - if (rlight->lightnum < 0) - xwalllights = scalelight[0]; - else if (rlight->lightnum >= LIGHTLEVELS) - xwalllights = scalelight[LIGHTLEVELS-1]; - else - xwalllights = scalelight[rlight->lightnum]; - - pindex = FixedMul(spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT; - - if (pindex >= MAXLIGHTSCALE) - pindex = MAXLIGHTSCALE - 1; - - if (rlight->extra_colormap) - rlight->rcolormap = rlight->extra_colormap->colormap + (xwalllights[pindex] - colormaps); - else - rlight->rcolormap = xwalllights[pindex]; - - height = rlight->height; - rlight->height += rlight->heightstep; - - if (height <= windowtop) - { - dc_colormap = rlight->rcolormap; - continue; - } - - windowbottom = height; - if (windowbottom >= realbot) - { - windowbottom = realbot; - colfunc_2s(col); - for (i++; i < dc_numlights; i++) - { - rlight = &dc_lightlist[i]; - rlight->height += rlight->heightstep; - } - - continue; - } - colfunc_2s(col); - windowtop = windowbottom + 1; - dc_colormap = rlight->rcolormap; - } - windowbottom = realbot; - if (windowtop < windowbottom) - colfunc_2s(col); - - spryscale += rw_scalestep; - continue; - } - - // calculate lighting - pindex = FixedMul(spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT; - - if (pindex >= MAXLIGHTSCALE) - pindex = MAXLIGHTSCALE - 1; - - dc_colormap = walllights[pindex]; - - if (frontsector->extra_colormap) - dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); - - sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); - dc_iscale = 0xffffffffu / (unsigned)spryscale; - - // draw the texture - col = (column_t *)((UINT8 *)R_GetColumn(texnum, maskedtexturecol[dc_x]) - 3); - -#if 0 // Disabling this allows inside edges to render below the planes, for until the clipping is fixed to work right when POs are near the camera. -Red - if (curline->dontrenderme && curline->polyseg && (curline->polyseg->flags & POF_RENDERPLANES)) - { - fixed_t my_topscreen; - fixed_t my_bottomscreen; - fixed_t my_yl, my_yh; - - my_topscreen = sprtopscreen + spryscale*col->topdelta; - my_bottomscreen = sprbotscreen == INT32_MAX ? my_topscreen + spryscale*col->length - : sprbotscreen + spryscale*col->length; - - my_yl = (my_topscreen+FRACUNIT-1)>>FRACBITS; - my_yh = (my_bottomscreen-1)>>FRACBITS; - // CONS_Debug(DBG_RENDER, "my_topscreen: %d\nmy_bottomscreen: %d\nmy_yl: %d\nmy_yh: %d\n", my_topscreen, my_bottomscreen, my_yl, my_yh); - - if (numffloors) - { - INT32 top = my_yl; - INT32 bottom = my_yh; - - for (i = 0; i < numffloors; i++) - { - if (!ffloor[i].polyobj || ffloor[i].polyobj != curline->polyseg) - continue; - - if (ffloor[i].height < viewz) - { - INT32 top_w = ffloor[i].plane->top[dc_x]; - - // CONS_Debug(DBG_RENDER, "Leveltime : %d\n", leveltime); - // CONS_Debug(DBG_RENDER, "Top is %d, top_w is %d\n", top, top_w); - if (top_w < top) - { - ffloor[i].plane->top[dc_x] = (INT16)top; - ffloor[i].plane->picnum = 0; - } - // CONS_Debug(DBG_RENDER, "top_w is now %d\n", ffloor[i].plane->top[dc_x]); - } - else if (ffloor[i].height > viewz) - { - INT32 bottom_w = ffloor[i].plane->bottom[dc_x]; - - if (bottom_w > bottom) - { - ffloor[i].plane->bottom[dc_x] = (INT16)bottom; - ffloor[i].plane->picnum = 0; - } - } - } - } - } - else -#endif colfunc_2s(col); + windowtop = windowbottom + 1; + dc_colormap = rlight->rcolormap; + } + windowbottom = realbot; + if (windowtop < windowbottom) + colfunc_2s(col); + + spryscale += rw_scalestep; + continue; } + + // calculate lighting + pindex = FixedMul(spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT; + + if (pindex >= MAXLIGHTSCALE) + pindex = MAXLIGHTSCALE - 1; + + dc_colormap = walllights[pindex]; + + if (frontsector->extra_colormap) + dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); + + sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); + dc_iscale = 0xffffffffu / (unsigned)spryscale; + + // draw the texture + col = (column_t *)((UINT8 *)R_GetColumn(texnum, (maskedtexturecol[dc_x] >> FRACBITS)) - 3); + colfunc_2s(col); + spryscale += rw_scalestep; } } @@ -857,183 +815,182 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) // draw the columns for (dc_x = x1; dc_x <= x2; dc_x++) { - if (maskedtexturecol[dc_x] != INT16_MAX) + // skew FOF walls + if (ffloortextureslide) { - if (ffloortextureslide) { // skew FOF walls - if (oldx != -1) - dc_texturemid += FixedMul(ffloortextureslide, (maskedtexturecol[oldx]-maskedtexturecol[dc_x])< (INT64)CLAMPMAX) sprtopscreen = windowtop = CLAMPMAX; - else if (top_frac > (INT64)CLAMPMIN) sprtopscreen = windowtop = (fixed_t)top_frac; - else sprtopscreen = windowtop = CLAMPMIN; - if (bottom_frac > (INT64)CLAMPMAX) sprbotscreen = windowbottom = CLAMPMAX; - else if (bottom_frac > (INT64)CLAMPMIN) sprbotscreen = windowbottom = (fixed_t)bottom_frac; - else sprbotscreen = windowbottom = CLAMPMIN; + // Calculate bounds + // clamp the values if necessary to avoid overflows and rendering glitches caused by them + if (top_frac > (INT64)CLAMPMAX) sprtopscreen = windowtop = CLAMPMAX; + else if (top_frac > (INT64)CLAMPMIN) sprtopscreen = windowtop = (fixed_t)top_frac; + else sprtopscreen = windowtop = CLAMPMIN; + if (bottom_frac > (INT64)CLAMPMAX) sprbotscreen = windowbottom = CLAMPMAX; + else if (bottom_frac > (INT64)CLAMPMIN) sprbotscreen = windowbottom = (fixed_t)bottom_frac; + else sprbotscreen = windowbottom = CLAMPMIN; - top_frac += top_step; - bottom_frac += bottom_step; + top_frac += top_step; + bottom_frac += bottom_step; - // SoM: If column is out of range, why bother with it?? - if (windowbottom < topbounds || windowtop > bottombounds) + // SoM: If column is out of range, why bother with it?? + if (windowbottom < topbounds || windowtop > bottombounds) + { + if (dc_numlights) { - if (dc_numlights) + for (i = 0; i < dc_numlights; i++) { - for (i = 0; i < dc_numlights; i++) + rlight = &dc_lightlist[i]; + rlight->height += rlight->heightstep; + if (rlight->flags & FOF_CUTLEVEL) + rlight->botheight += rlight->botheightstep; + } + } + spryscale += rw_scalestep; + continue; + } + + dc_iscale = 0xffffffffu / (unsigned)spryscale; + + // Get data for the column + col = (column_t *)((UINT8 *)R_GetColumn(texnum, (maskedtexturecol[dc_x] >> FRACBITS)) - 3); + + // SoM: New code does not rely on R_DrawColumnShadowed_8 which + // will (hopefully) put less strain on the stack. + if (dc_numlights) + { + lighttable_t **xwalllights; + fixed_t height; + fixed_t bheight = 0; + INT32 solid = 0; + INT32 lighteffect = 0; + + for (i = 0; i < dc_numlights; i++) + { + // Check if the current light effects the colormap/lightlevel + rlight = &dc_lightlist[i]; + lighteffect = !(dc_lightlist[i].flags & FOF_NOSHADE); + if (lighteffect) + { + lightnum = rlight->lightnum; + + if (lightnum < 0) + xwalllights = scalelight[0]; + else if (lightnum >= LIGHTLEVELS) + xwalllights = scalelight[LIGHTLEVELS-1]; + else + xwalllights = scalelight[lightnum]; + + pindex = FixedMul(spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT; + + if (pindex >= MAXLIGHTSCALE) + pindex = MAXLIGHTSCALE-1; + + if (pfloor->fofflags & FOF_FOG) + { + if (pfloor->master->frontsector->extra_colormap) + rlight->rcolormap = pfloor->master->frontsector->extra_colormap->colormap + (xwalllights[pindex] - colormaps); + else + rlight->rcolormap = xwalllights[pindex]; + } + else + { + if (rlight->extra_colormap) + rlight->rcolormap = rlight->extra_colormap->colormap + (xwalllights[pindex] - colormaps); + else + rlight->rcolormap = xwalllights[pindex]; + } + } + + solid = 0; // don't carry over solid-cutting flag from the previous light + + // Check if the current light can cut the current 3D floor. + if (rlight->flags & FOF_CUTSOLIDS && !(pfloor->fofflags & FOF_EXTRA)) + solid = 1; + else if (rlight->flags & FOF_CUTEXTRA && pfloor->fofflags & FOF_EXTRA) + { + if (rlight->flags & FOF_EXTRA) + { + // The light is from an extra 3D floor... Check the flags so + // there are no undesired cuts. + if ((rlight->flags & (FOF_FOG|FOF_SWIMMABLE)) == (pfloor->fofflags & (FOF_FOG|FOF_SWIMMABLE))) + solid = 1; + } + else + solid = 1; + } + else + solid = 0; + + height = rlight->height; + rlight->height += rlight->heightstep; + + if (solid) + { + bheight = rlight->botheight - (FRACUNIT >> 1); + rlight->botheight += rlight->botheightstep; + } + + if (height <= windowtop) + { + if (lighteffect) + dc_colormap = rlight->rcolormap; + if (solid && windowtop < bheight) + windowtop = bheight; + continue; + } + + windowbottom = height; + if (windowbottom >= sprbotscreen) + { + windowbottom = sprbotscreen; + // draw the texture + colfunc_2s (col); + for (i++; i < dc_numlights; i++) { rlight = &dc_lightlist[i]; rlight->height += rlight->heightstep; if (rlight->flags & FOF_CUTLEVEL) rlight->botheight += rlight->botheightstep; } + continue; } - spryscale += rw_scalestep; - continue; + // draw the texture + colfunc_2s (col); + if (solid) + windowtop = bheight; + else + windowtop = windowbottom + 1; + if (lighteffect) + dc_colormap = rlight->rcolormap; } + windowbottom = sprbotscreen; + // draw the texture, if there is any space left + if (windowtop < windowbottom) + colfunc_2s (col); - dc_iscale = 0xffffffffu / (unsigned)spryscale; - - // Get data for the column - col = (column_t *)((UINT8 *)R_GetColumn(texnum,maskedtexturecol[dc_x]) - 3); - - // SoM: New code does not rely on R_DrawColumnShadowed_8 which - // will (hopefully) put less strain on the stack. - if (dc_numlights) - { - lighttable_t **xwalllights; - fixed_t height; - fixed_t bheight = 0; - INT32 solid = 0; - INT32 lighteffect = 0; - - for (i = 0; i < dc_numlights; i++) - { - // Check if the current light effects the colormap/lightlevel - rlight = &dc_lightlist[i]; - lighteffect = !(dc_lightlist[i].flags & FOF_NOSHADE); - if (lighteffect) - { - lightnum = rlight->lightnum; - - if (lightnum < 0) - xwalllights = scalelight[0]; - else if (lightnum >= LIGHTLEVELS) - xwalllights = scalelight[LIGHTLEVELS-1]; - else - xwalllights = scalelight[lightnum]; - - pindex = FixedMul(spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT; - - if (pindex >= MAXLIGHTSCALE) - pindex = MAXLIGHTSCALE-1; - - if (pfloor->fofflags & FOF_FOG) - { - if (pfloor->master->frontsector->extra_colormap) - rlight->rcolormap = pfloor->master->frontsector->extra_colormap->colormap + (xwalllights[pindex] - colormaps); - else - rlight->rcolormap = xwalllights[pindex]; - } - else - { - if (rlight->extra_colormap) - rlight->rcolormap = rlight->extra_colormap->colormap + (xwalllights[pindex] - colormaps); - else - rlight->rcolormap = xwalllights[pindex]; - } - } - - solid = 0; // don't carry over solid-cutting flag from the previous light - - // Check if the current light can cut the current 3D floor. - if (rlight->flags & FOF_CUTSOLIDS && !(pfloor->fofflags & FOF_EXTRA)) - solid = 1; - else if (rlight->flags & FOF_CUTEXTRA && pfloor->fofflags & FOF_EXTRA) - { - if (rlight->flags & FOF_EXTRA) - { - // The light is from an extra 3D floor... Check the flags so - // there are no undesired cuts. - if ((rlight->flags & (FOF_FOG|FOF_SWIMMABLE)) == (pfloor->fofflags & (FOF_FOG|FOF_SWIMMABLE))) - solid = 1; - } - else - solid = 1; - } - else - solid = 0; - - height = rlight->height; - rlight->height += rlight->heightstep; - - if (solid) - { - bheight = rlight->botheight - (FRACUNIT >> 1); - rlight->botheight += rlight->botheightstep; - } - - if (height <= windowtop) - { - if (lighteffect) - dc_colormap = rlight->rcolormap; - if (solid && windowtop < bheight) - windowtop = bheight; - continue; - } - - windowbottom = height; - if (windowbottom >= sprbotscreen) - { - windowbottom = sprbotscreen; - // draw the texture - colfunc_2s (col); - for (i++; i < dc_numlights; i++) - { - rlight = &dc_lightlist[i]; - rlight->height += rlight->heightstep; - if (rlight->flags & FOF_CUTLEVEL) - rlight->botheight += rlight->botheightstep; - } - continue; - } - // draw the texture - colfunc_2s (col); - if (solid) - windowtop = bheight; - else - windowtop = windowbottom + 1; - if (lighteffect) - dc_colormap = rlight->rcolormap; - } - windowbottom = sprbotscreen; - // draw the texture, if there is any space left - if (windowtop < windowbottom) - colfunc_2s (col); - - spryscale += rw_scalestep; - continue; - } - - // calculate lighting - pindex = FixedMul(spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT; - - if (pindex >= MAXLIGHTSCALE) - pindex = MAXLIGHTSCALE - 1; - - dc_colormap = walllights[pindex]; - - if (pfloor->fofflags & FOF_FOG && pfloor->master->frontsector->extra_colormap) - dc_colormap = pfloor->master->frontsector->extra_colormap->colormap + (dc_colormap - colormaps); - else if (frontsector->extra_colormap) - dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); - - // draw the texture - colfunc_2s (col); spryscale += rw_scalestep; + continue; } + + // calculate lighting + pindex = FixedMul(spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT; + + if (pindex >= MAXLIGHTSCALE) + pindex = MAXLIGHTSCALE - 1; + + dc_colormap = walllights[pindex]; + + if (pfloor->fofflags & FOF_FOG && pfloor->master->frontsector->extra_colormap) + dc_colormap = pfloor->master->frontsector->extra_colormap->colormap + (dc_colormap - colormaps); + else if (frontsector->extra_colormap) + dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); + + // draw the texture + colfunc_2s (col); + spryscale += rw_scalestep; } colfunc = colfuncs[BASEDRAWFUNC]; @@ -1270,7 +1227,7 @@ static void R_RenderSegLoop (void) } oldtexturecolumn = texturecolumn; - texturecolumn >>= FRACBITS; + INT32 itexturecolumn = texturecolumn >> FRACBITS; // texturecolumn and lighting are independent of wall tiers if (segtextured) @@ -1336,7 +1293,7 @@ static void R_RenderSegLoop (void) dc_yl = yl; dc_yh = yh; dc_texturemid = rw_midtexturemid; - dc_source = R_GetColumn(midtexture,texturecolumn + (rw_offset_mid>>FRACBITS)); + dc_source = R_GetColumn(midtexture, itexturecolumn + (rw_offset_mid>>FRACBITS)); dc_texheight = textureheight[midtexture]>>FRACBITS; //profile stuff --------------------------------------------------------- @@ -1397,7 +1354,7 @@ static void R_RenderSegLoop (void) dc_yl = yl; dc_yh = mid; dc_texturemid = rw_toptexturemid; - dc_source = R_GetColumn(toptexture,texturecolumn + (rw_offset_top>>FRACBITS)); + dc_source = R_GetColumn(toptexture, itexturecolumn + (rw_offset_top>>FRACBITS)); dc_texheight = textureheight[toptexture]>>FRACBITS; colfunc(); ceilingclip[rw_x] = (INT16)mid; @@ -1433,8 +1390,7 @@ static void R_RenderSegLoop (void) dc_yl = mid; dc_yh = yh; dc_texturemid = rw_bottomtexturemid; - dc_source = R_GetColumn(bottomtexture, - texturecolumn + (rw_offset_bot>>FRACBITS)); + dc_source = R_GetColumn(bottomtexture, itexturecolumn + (rw_offset_bot>>FRACBITS)); dc_texheight = textureheight[bottomtexture]>>FRACBITS; colfunc(); floorclip[rw_x] = (INT16)mid; @@ -1453,7 +1409,7 @@ static void R_RenderSegLoop (void) { // save texturecol // for backdrawing of masked mid texture - maskedtexturecol[rw_x] = (INT16)(texturecolumn + (rw_offset_mid>>FRACBITS)); + maskedtexturecol[rw_x] = texturecolumn + rw_offset_mid; if (maskedtextureheight != NULL) { maskedtextureheight[rw_x] = (curline->linedef->flags & ML_MIDPEG) ? @@ -1512,6 +1468,67 @@ static INT64 R_CalcSegDist(seg_t* seg, INT64 x2, INT64 y2) } } +//SoM: Code to remove limits on openings. +static void R_AllocClippingTables(size_t range) +{ + size_t pos = lastopening - openings; + size_t need = range * 2; // for both sprtopclip and sprbottomclip + + if (pos + need < numopenings) + return; + + INT16 *oldopenings = openings; + INT16 *oldlast = lastopening; + + if (numopenings == 0) + numopenings = 16384; + + numopenings += need; + openings = Z_Realloc(openings, numopenings * sizeof (*openings), PU_STATIC, NULL); + lastopening = openings + pos; + + // borrowed fix from *cough* zdoom *cough* + // [RH] We also need to adjust the openings pointers that + // were already stored in drawsegs. + for (drawseg_t *ds = drawsegs; ds < ds_p; ds++) + { + // Check if it's in range of the openings + if (ds->sprtopclip + ds->x1 >= oldopenings && ds->sprtopclip + ds->x1 <= oldlast) + ds->sprtopclip = (ds->sprtopclip - oldopenings) + openings; + if (ds->sprbottomclip + ds->x1 >= oldopenings && ds->sprbottomclip + ds->x1 <= oldlast) + ds->sprbottomclip = (ds->sprbottomclip - oldopenings) + openings; + } +} + +static void R_AllocTextureColumnTables(size_t range) +{ + size_t pos = curtexturecolumntable - texturecolumntable; + + // For both tables, we reserve exactly an amount of memory that's equivalent to + // how many columns the seg will take on the entire screen (think about it) + if (pos + range < texturecolumntablesize) + return; + + fixed_t *oldtable = texturecolumntable; + fixed_t *oldlast = curtexturecolumntable; + + if (texturecolumntablesize == 0) + texturecolumntablesize = 16384; + + texturecolumntablesize += range; + texturecolumntable = Z_Realloc(texturecolumntable, texturecolumntablesize * sizeof (*texturecolumntable), PU_STATIC, NULL); + curtexturecolumntable = texturecolumntable + pos; + + for (drawseg_t *ds = drawsegs; ds < ds_p; ds++) + { + // Check if it's in range of the tables + if (ds->maskedtexturecol + ds->x1 >= oldtable && ds->maskedtexturecol + ds->x1 <= oldlast) + ds->maskedtexturecol = (ds->maskedtexturecol - oldtable) + texturecolumntable; + if (ds->thicksidecol + ds->x1 >= oldtable && ds->thicksidecol + ds->x1 <= oldlast) + ds->thicksidecol = (ds->thicksidecol - oldtable) + texturecolumntable; + } +} + // // R_StoreWallRange // A wall segment will be drawn @@ -1580,37 +1597,6 @@ void R_StoreWallRange(INT32 start, INT32 stop) ds_p->curline = curline; rw_stopx = stop+1; - //SoM: Code to remove limits on openings. - { - size_t pos = lastopening - openings; - size_t need = (rw_stopx - start)*4 + pos; - if (need > maxopenings) - { - drawseg_t *ds; //needed for fix from *cough* zdoom *cough* - INT16 *oldopenings = openings; - INT16 *oldlast = lastopening; - - do - maxopenings = maxopenings ? maxopenings*2 : 16384; - while (need > maxopenings); - openings = Z_Realloc(openings, maxopenings * sizeof (*openings), PU_STATIC, NULL); - lastopening = openings + pos; - - // borrowed fix from *cough* zdoom *cough* - // [RH] We also need to adjust the openings pointers that - // were already stored in drawsegs. - for (ds = drawsegs; ds < ds_p; ds++) - { -#define ADJUST(p) if (ds->p + ds->x1 >= oldopenings && ds->p + ds->x1 <= oldlast) ds->p = ds->p - oldopenings + openings; - ADJUST(maskedtexturecol); - ADJUST(sprtopclip); - ADJUST(sprbottomclip); - ADJUST(thicksidecol); -#undef ADJUST - } - } - } // end of code to remove limits on openings - // calculate scale at both ends and step ds_p->scale1 = rw_scale = R_ScaleFromGlobalAngle(viewangle + xtoviewangle[start]); @@ -2026,6 +2012,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) rw_toptexturemid += sidedef->rowoffset + sidedef->offsety_top; rw_bottomtexturemid += sidedef->rowoffset + sidedef->offsety_bot; + R_AllocTextureColumnTables(rw_stopx - start); + // allocate space for masked texture tables if (frontsector && backsector && !Tag_Compare(&frontsector->tags, &backsector->tags) && (backsector->ffloors || frontsector->ffloors)) { @@ -2040,8 +2028,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) //markceiling = markfloor = true; maskedtexture = true; - ds_p->thicksidecol = maskedtexturecol = lastopening - rw_x; - lastopening += rw_stopx - rw_x; + ds_p->thicksidecol = maskedtexturecol = curtexturecolumntable - rw_x; + curtexturecolumntable += rw_stopx - rw_x; lowcut = max(worldbottom, worldlow) + viewz; highcut = min(worldtop, worldhigh) + viewz; @@ -2224,8 +2212,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) // masked midtexture if (!ds_p->thicksidecol) { - ds_p->maskedtexturecol = maskedtexturecol = lastopening - rw_x; - lastopening += rw_stopx - rw_x; + ds_p->maskedtexturecol = maskedtexturecol = curtexturecolumntable - rw_x; + curtexturecolumntable += rw_stopx - rw_x; } else ds_p->maskedtexturecol = ds_p->thicksidecol; @@ -2737,29 +2725,34 @@ void R_StoreWallRange(INT32 start, INT32 stop) ds_p->portalpass = 0; // save sprite clipping info - if (((ds_p->silhouette & SIL_TOP) || maskedtexture) && !ds_p->sprtopclip) + if (maskedtexture || (ds_p->silhouette & (SIL_TOP | SIL_BOTTOM))) { - M_Memcpy(lastopening, ceilingclip+start, 2*(rw_stopx - start)); - ds_p->sprtopclip = lastopening - start; - lastopening += rw_stopx - start; - } + R_AllocClippingTables(rw_stopx - start); - if (((ds_p->silhouette & SIL_BOTTOM) || maskedtexture) && !ds_p->sprbottomclip) - { - M_Memcpy(lastopening, floorclip + start, 2*(rw_stopx-start)); - ds_p->sprbottomclip = lastopening - start; - lastopening += rw_stopx - start; + if (((ds_p->silhouette & SIL_TOP) || maskedtexture) && !ds_p->sprtopclip) + { + M_Memcpy(lastopening, ceilingclip + start, 2*(rw_stopx - start)); + ds_p->sprtopclip = lastopening - start; + lastopening += rw_stopx - start; + } + + if (((ds_p->silhouette & SIL_BOTTOM) || maskedtexture) && !ds_p->sprbottomclip) + { + M_Memcpy(lastopening, floorclip + start, 2*(rw_stopx - start)); + ds_p->sprbottomclip = lastopening - start; + lastopening += rw_stopx - start; + } } if (maskedtexture && !(ds_p->silhouette & SIL_TOP)) { ds_p->silhouette |= SIL_TOP; - ds_p->tsilheight = (sidedef->midtexture > 0 && sidedef->midtexture < numtextures) ? INT32_MIN: INT32_MAX; + ds_p->tsilheight = (sidedef->midtexture > 0 && sidedef->midtexture < numtextures) ? INT32_MIN : INT32_MAX; } if (maskedtexture && !(ds_p->silhouette & SIL_BOTTOM)) { ds_p->silhouette |= SIL_BOTTOM; - ds_p->bsilheight = (sidedef->midtexture > 0 && sidedef->midtexture < numtextures) ? INT32_MAX: INT32_MIN; + ds_p->bsilheight = (sidedef->midtexture > 0 && sidedef->midtexture < numtextures) ? INT32_MAX : INT32_MIN; } ds_p++; } diff --git a/src/r_segs.h b/src/r_segs.h index 09c68b27e..cad014674 100644 --- a/src/r_segs.h +++ b/src/r_segs.h @@ -22,5 +22,6 @@ transnum_t R_GetLinedefTransTable(fixed_t alpha); void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2); void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pffloor); void R_StoreWallRange(INT32 start, INT32 stop); +void R_ClearSegTables(void); #endif From 7634a960314d5a576656cc4300a74caf889f8d7f Mon Sep 17 00:00:00 2001 From: katsy Date: Thu, 27 Jul 2023 23:58:53 -0500 Subject: [PATCH 362/586] delete ASM code, remove NASM --- SRB2.cbp | 18 - SRB2_common.props | 3 - Srb2.dev | 52 +- appveyor.yml | 8 - cmake/Modules/CMakeASM_YASMInformation.cmake | 46 - .../CMakeDetermineASM_YASMCompiler.cmake | 27 - cmake/Modules/CMakeTestASM_YASMCompiler.cmake | 23 - src/Android.mk | 2 +- src/CMakeLists.txt | 35 - src/Makefile | 23 - src/Makefile.d/features.mk | 7 - src/Makefile.d/nix.mk | 5 - src/Makefile.d/platform.mk | 1 - src/Makefile.d/sdl.mk | 7 - src/Makefile.d/win32.mk | 2 - src/Sourcefile | 1 - src/asm_defs.inc | 43 - src/d_netcmd.c | 5 - src/p5prof.h | 278 --- src/r_draw.c | 2 - src/r_draw.h | 12 - src/r_splats.c | 12 - src/screen.c | 27 - src/sdl/CMakeLists.txt | 17 - src/sdl/MakeCYG.cfg | 1 - src/sdl/i_main.c | 34 - src/tmap.nas | 957 ---------- src/tmap.s | 1587 ----------------- src/tmap_asm.s | 322 ---- src/tmap_mmx.nas | 674 ------- src/tmap_vc.nas | 48 - src/v_video.c | 10 - src/vid_copy.s | 61 - tools/anglechk.c | 1 - 34 files changed, 2 insertions(+), 4349 deletions(-) delete mode 100644 cmake/Modules/CMakeASM_YASMInformation.cmake delete mode 100644 cmake/Modules/CMakeDetermineASM_YASMCompiler.cmake delete mode 100644 cmake/Modules/CMakeTestASM_YASMCompiler.cmake delete mode 100644 src/asm_defs.inc delete mode 100644 src/p5prof.h delete mode 100644 src/tmap.nas delete mode 100644 src/tmap.s delete mode 100644 src/tmap_asm.s delete mode 100644 src/tmap_mmx.nas delete mode 100644 src/tmap_vc.nas delete mode 100644 src/vid_copy.s diff --git a/SRB2.cbp b/SRB2.cbp index 2a1eb87b8..9e887bf85 100644 --- a/SRB2.cbp +++ b/SRB2.cbp @@ -1992,24 +1992,6 @@ HW3SOUND for 3D hardware sound support