diff --git a/.circleci/config.yml b/.circleci/config.yml index 1784ba1ea..e7916074b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -36,7 +36,7 @@ jobs: - v1-SRB2-APT - run: name: Install SDK - command: apt-get -qq -y --no-install-recommends install git build-essential nasm libpng-dev:i386 libsdl2-mixer-dev:i386 libgme-dev:i386 gettext ccache wget gcc-multilib upx openssh-client + command: apt-get -qq -y --no-install-recommends install git build-essential nasm libpng-dev:i386 libsdl2-mixer-dev:i386 libgme-dev:i386 libcurl4-openssl-dev:i386 gettext ccache wget gcc-multilib upx openssh-client - save_cache: key: v1-SRB2-APT paths: diff --git a/.travis.yml b/.travis.yml index 6d2e8cddf..4959e4d2d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,6 +23,7 @@ matrix: - libpng-dev - libgl1-mesa-dev - libgme-dev + - libcurl4-openssl-dev - p7zip-full - gcc-4.4 compiler: gcc-4.4 @@ -37,6 +38,7 @@ matrix: - libpng-dev - libgl1-mesa-dev - libgme-dev + - libcurl4-openssl-dev - p7zip-full - gcc-4.6 compiler: gcc-4.6 @@ -51,6 +53,7 @@ matrix: - libpng-dev - libgl1-mesa-dev - libgme-dev + - libcurl4-openssl-dev - p7zip-full - gcc-4.7 compiler: gcc-4.7 @@ -72,6 +75,7 @@ matrix: - libpng-dev - libgl1-mesa-dev - libgme-dev + - libcurl4-openssl-dev - p7zip-full - gcc-4.8 compiler: gcc-4.8 @@ -88,6 +92,7 @@ matrix: - libpng-dev - libgl1-mesa-dev - libgme-dev + - libcurl4-openssl-dev - p7zip-full - gcc-7 compiler: gcc-7 @@ -104,6 +109,7 @@ matrix: - libpng-dev - libgl1-mesa-dev - libgme-dev + - libcurl4-openssl-dev - p7zip-full - gcc-8 compiler: gcc-8 @@ -124,6 +130,7 @@ matrix: - libpng-dev - libgl1-mesa-dev - libgme-dev + - libcurl4-openssl-dev - p7zip-full - clang-3.5 compiler: clang-3.5 @@ -140,6 +147,7 @@ matrix: - libpng-dev - libgl1-mesa-dev - libgme-dev + - libcurl4-openssl-dev - p7zip-full - clang-3.6 compiler: clang-3.6 @@ -156,6 +164,7 @@ matrix: - libpng-dev - libgl1-mesa-dev - libgme-dev + - libcurl4-openssl-dev - p7zip-full - clang-3.7 compiler: clang-3.7 @@ -172,6 +181,7 @@ matrix: - libpng-dev - libgl1-mesa-dev - libgme-dev + - libcurl4-openssl-dev - p7zip-full - clang-3.8 compiler: clang-3.8 @@ -188,6 +198,7 @@ matrix: - libpng-dev - libgl1-mesa-dev - libgme-dev + - libcurl4-openssl-dev - p7zip-full - clang-3.9 compiler: clang-3.9 @@ -294,6 +305,7 @@ matrix: - libpng-dev - libgl1-mesa-dev - libgme-dev + - libcurl4-openssl-dev - p7zip-full - gcc-4.8 compiler: gcc-4.8 @@ -435,6 +447,7 @@ matrix: - libpng-dev - libgl1-mesa-dev - libgme-dev + - libcurl4-openssl-dev - p7zip-full - gcc-4.8 compiler: gcc-4.8 @@ -458,6 +471,7 @@ matrix: - libpng-dev - libgl1-mesa-dev - libgme-dev + - libcurl4-openssl-dev - p7zip-full - gcc-4.8 compiler: gcc-4.8 @@ -481,6 +495,7 @@ matrix: - libpng-dev - libgl1-mesa-dev - libgme-dev + - libcurl4-openssl-dev - p7zip-full - gcc-4.8 compiler: gcc-4.8 @@ -504,6 +519,7 @@ matrix: - libpng-dev - libgl1-mesa-dev - libgme-dev + - libcurl4-openssl-dev - p7zip-full - gcc-4.8 compiler: gcc-4.8 @@ -527,6 +543,7 @@ matrix: - libpng-dev - libgl1-mesa-dev - libgme-dev + - libcurl4-openssl-dev - p7zip-full - gcc-4.8 compiler: gcc-4.8 @@ -567,6 +584,7 @@ addons: - libgl1-mesa-dev - libgme-dev - zlib1g-dev + - libcurl4-openssl-dev - p7zip-full homebrew: taps: @@ -576,6 +594,7 @@ addons: - game-music-emu - p7zip - cmake + - curl update: true diff --git a/CMakeLists.txt b/CMakeLists.txt index 7995034d3..51f98707d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.0) # DO NOT CHANGE THIS SRB2 STRING! Some variable names depend on this string. # Version change is fine. project(SRB2 - VERSION 1.1.0 + VERSION 1.2 LANGUAGES C) if(${PROJECT_SOURCE_DIR} MATCHES ${PROJECT_BINARY_DIR}) diff --git a/appveyor.yml b/appveyor.yml index 3d46cf6de..79aecf9c3 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 1.1.0.{branch}-{build} +version: 1.2.{branch}-{build} os: MinGW environment: @@ -29,7 +29,7 @@ environment: ############################## DPL_ENABLED: 0 DPL_TAG_ENABLED: 0 - DPL_INSTALLER_NAME: srb2kart-v110 + DPL_INSTALLER_NAME: srb2kart-v12 # Asset handling is barebones vs. Travis Deployer. We operate on 7z only. # Include the README files and the OpenGL batch in the main and patch archives. # The x86/x64 archives contain the DLL binaries. diff --git a/debian-template/control b/debian-template/control index e1348d704..4db1d8752 100644 --- a/debian-template/control +++ b/debian-template/control @@ -10,6 +10,7 @@ Build-Depends: debhelper (>= 7.0.50~), libpng-dev | libpng16-dev | libpng12-dev (>= 1.2.7), zlib1g-dev, libgme-dev, + libcurl4-openssl-dev, libglu1-dev | libglu-dev, libosmesa6-dev | libgl-dev, nasm [i386] @@ -24,6 +25,7 @@ Depends: ${SHLIBS_DEPENDS}, ${MISC_DEPENDS}, libsdl2-mixer-2.0-0, zlib1g, libgme0, + libcurl4, libpng | libpng16-16 | libpng12-0 Description: A cross-platform 3D Sonic fangame Sonic Robo Blast 2 is a 3D open-source Sonic the Hedgehog diff --git a/debian-template/source/options b/debian-template/source/options index 9532ff202..7829e2976 100644 --- a/debian-template/source/options +++ b/debian-template/source/options @@ -2,7 +2,10 @@ tar-ignore = "assets/*.srb" tar-ignore = "assets/*.pk3" tar-ignore = "assets/*.dta" tar-ignore = "assets/*.wad" +<<<<<<< HEAD:debian-template/source/options tar-ignore = "assets/*.kart" +======= +>>>>>>> e251f9c230beda984cdcdea7e903d765f1c68f6f:debian-template/source/options tar-ignore = "assets/debian/${PACKAGE_NAME}-data/*" tar-ignore = "assets/debian/tmp/*" tar-ignore = "*.obj" diff --git a/libs/curl/include/curl/curl.h b/libs/curl/include/curl/curl.h index ee9754da8..b7cb30a58 100644 --- a/libs/curl/include/curl/curl.h +++ b/libs/curl/include/curl/curl.h @@ -1,5 +1,5 @@ -#ifndef __CURL_CURL_H -#define __CURL_CURL_H +#ifndef CURLINC_CURL_H +#define CURLINC_CURL_H /*************************************************************************** * _ _ ____ _ * Project ___| | | | _ \| | @@ -7,11 +7,11 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms - * are also available at http://curl.haxx.se/docs/copyright.html. + * are also available at https://curl.haxx.se/docs/copyright.html. * * You may opt to use, copy, modify, merge, publish, distribute and/or sell * copies of the Software, and permit persons to whom the Software is @@ -24,23 +24,26 @@ /* * If you have libcurl problems, all docs and details are found here: - * http://curl.haxx.se/libcurl/ + * https://curl.haxx.se/libcurl/ * * curl-library mailing list subscription and unsubscription web interface: - * http://cool.haxx.se/mailman/listinfo/curl-library/ + * https://cool.haxx.se/mailman/listinfo/curl-library/ */ +#ifdef CURL_NO_OLDIES +#define CURL_STRICTER +#endif + #include "curlver.h" /* libcurl version defines */ -#include "curlbuild.h" /* libcurl build definitions */ -#include "curlrules.h" /* libcurl rules enforcement */ +#include "system.h" /* determine things run-time */ /* - * Define WIN32 when build target is Win32 API + * Define CURL_WIN32 when build target is Win32 API */ -#if (defined(_WIN32) || defined(__WIN32__)) && \ - !defined(WIN32) && !defined(__SYMBIAN32__) -#define WIN32 +#if (defined(_WIN32) || defined(__WIN32__) || defined(WIN32)) && \ + !defined(__SYMBIAN32__) +#define CURL_WIN32 #endif #include @@ -55,74 +58,79 @@ #include #include -#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(__GNUC__) && \ - !defined(__CYGWIN__) || defined(__MINGW32__) -#if !(defined(_WINSOCKAPI_) || defined(_WINSOCK_H)) +#if defined(CURL_WIN32) && !defined(_WIN32_WCE) && !defined(__CYGWIN__) +#if !(defined(_WINSOCKAPI_) || defined(_WINSOCK_H) || \ + defined(__LWIP_OPT_H__) || defined(LWIP_HDR_OPT_H)) /* The check above prevents the winsock2 inclusion if winsock.h already was included, since they can't co-exist without problems */ #include #include #endif -#else +#endif /* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish - libc5-based Linux systems. Only include it on system that are known to + libc5-based Linux systems. Only include it on systems that are known to require it! */ #if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \ defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY) || \ - defined(ANDROID) || \ + defined(ANDROID) || defined(__ANDROID__) || defined(__OpenBSD__) || \ + defined(__CYGWIN__) || \ (defined(__FreeBSD_version) && (__FreeBSD_version < 800000)) #include #endif -#ifndef _WIN32_WCE +#if !defined(CURL_WIN32) && !defined(_WIN32_WCE) #include #endif -#if !defined(WIN32) && !defined(__WATCOMC__) && !defined(__VXWORKS__) + +#if !defined(CURL_WIN32) && !defined(__WATCOMC__) && !defined(__VXWORKS__) #include #endif -#include -#endif #ifdef __BEOS__ #include #endif +/* Compatibility for non-Clang compilers */ +#ifndef __has_declspec_attribute +# define __has_declspec_attribute(x) 0 +#endif + #ifdef __cplusplus extern "C" { #endif +#if defined(BUILDING_LIBCURL) || defined(CURL_STRICTER) +typedef struct Curl_easy CURL; +typedef struct Curl_share CURLSH; +#else typedef void CURL; +typedef void CURLSH; +#endif /* - * Decorate exportable functions for Win32 and Symbian OS DLL linking. - * This avoids using a .def file for building libcurl.dll. + * libcurl external API function linkage decorations. */ -#if (defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__)) && \ - !defined(CURL_STATICLIB) -#if defined(BUILDING_LIBCURL) -#define CURL_EXTERN __declspec(dllexport) -#else -#define CURL_EXTERN __declspec(dllimport) -#endif -#else -#ifdef CURL_HIDDEN_SYMBOLS -/* - * This definition is used to make external definitions visible in the - * shared library when symbols are hidden by default. It makes no - * difference when compiling applications whether this is set or not, - * only when compiling the library. - */ -#define CURL_EXTERN CURL_EXTERN_SYMBOL +#ifdef CURL_STATICLIB +# define CURL_EXTERN +#elif defined(CURL_WIN32) || defined(__SYMBIAN32__) || \ + (__has_declspec_attribute(dllexport) && \ + __has_declspec_attribute(dllimport)) +# if defined(BUILDING_LIBCURL) +# define CURL_EXTERN __declspec(dllexport) +# else +# define CURL_EXTERN __declspec(dllimport) +# endif +#elif defined(BUILDING_LIBCURL) && defined(CURL_HIDDEN_SYMBOLS) +# define CURL_EXTERN CURL_EXTERN_SYMBOL #else -#define CURL_EXTERN -#endif +# define CURL_EXTERN #endif #ifndef curl_socket_typedef /* socket typedef */ -#ifdef WIN32 +#if defined(CURL_WIN32) && !defined(__LWIP_OPT_H__) && !defined(LWIP_HDR_OPT_H) typedef SOCKET curl_socket_t; #define CURL_SOCKET_BAD INVALID_SOCKET #else @@ -132,46 +140,103 @@ typedef int curl_socket_t; #define curl_socket_typedef #endif /* curl_socket_typedef */ +/* enum for the different supported SSL backends */ +typedef enum { + CURLSSLBACKEND_NONE = 0, + CURLSSLBACKEND_OPENSSL = 1, + CURLSSLBACKEND_GNUTLS = 2, + CURLSSLBACKEND_NSS = 3, + CURLSSLBACKEND_OBSOLETE4 = 4, /* Was QSOSSL. */ + CURLSSLBACKEND_GSKIT = 5, + CURLSSLBACKEND_POLARSSL = 6, + CURLSSLBACKEND_WOLFSSL = 7, + CURLSSLBACKEND_SCHANNEL = 8, + CURLSSLBACKEND_SECURETRANSPORT = 9, + CURLSSLBACKEND_AXTLS = 10, /* never used since 7.63.0 */ + CURLSSLBACKEND_MBEDTLS = 11, + CURLSSLBACKEND_MESALINK = 12, + CURLSSLBACKEND_BEARSSL = 13 +} curl_sslbackend; + +/* aliases for library clones and renames */ +#define CURLSSLBACKEND_LIBRESSL CURLSSLBACKEND_OPENSSL +#define CURLSSLBACKEND_BORINGSSL CURLSSLBACKEND_OPENSSL + +/* deprecated names: */ +#define CURLSSLBACKEND_CYASSL CURLSSLBACKEND_WOLFSSL +#define CURLSSLBACKEND_DARWINSSL CURLSSLBACKEND_SECURETRANSPORT + struct curl_httppost { struct curl_httppost *next; /* next entry in the list */ char *name; /* pointer to allocated name */ long namelength; /* length of name length */ char *contents; /* pointer to allocated data contents */ - long contentslength; /* length of contents field */ + long contentslength; /* length of contents field, see also + CURL_HTTPPOST_LARGE */ char *buffer; /* pointer to allocated buffer contents */ long bufferlength; /* length of buffer field */ char *contenttype; /* Content-Type */ - struct curl_slist* contentheader; /* list of extra headers for this form */ + struct curl_slist *contentheader; /* list of extra headers for this form */ struct curl_httppost *more; /* if one field name has more than one file, this link should link to following files */ long flags; /* as defined below */ -#define HTTPPOST_FILENAME (1<<0) /* specified content is a file name */ -#define HTTPPOST_READFILE (1<<1) /* specified content is a file name */ -#define HTTPPOST_PTRNAME (1<<2) /* name is only stored pointer - do not free in formfree */ -#define HTTPPOST_PTRCONTENTS (1<<3) /* contents is only stored pointer - do not free in formfree */ -#define HTTPPOST_BUFFER (1<<4) /* upload file from buffer */ -#define HTTPPOST_PTRBUFFER (1<<5) /* upload file from pointer contents */ -#define HTTPPOST_CALLBACK (1<<6) /* upload file contents by using the - regular read callback to get the data - and pass the given pointer as custom - pointer */ + +/* specified content is a file name */ +#define CURL_HTTPPOST_FILENAME (1<<0) +/* specified content is a file name */ +#define CURL_HTTPPOST_READFILE (1<<1) +/* name is only stored pointer do not free in formfree */ +#define CURL_HTTPPOST_PTRNAME (1<<2) +/* contents is only stored pointer do not free in formfree */ +#define CURL_HTTPPOST_PTRCONTENTS (1<<3) +/* upload file from buffer */ +#define CURL_HTTPPOST_BUFFER (1<<4) +/* upload file from pointer contents */ +#define CURL_HTTPPOST_PTRBUFFER (1<<5) +/* upload file contents by using the regular read callback to get the data and + pass the given pointer as custom pointer */ +#define CURL_HTTPPOST_CALLBACK (1<<6) +/* use size in 'contentlen', added in 7.46.0 */ +#define CURL_HTTPPOST_LARGE (1<<7) char *showfilename; /* The file name to show. If not set, the actual file name will be used (if this is a file part) */ void *userp; /* custom pointer used for HTTPPOST_CALLBACK posts */ + curl_off_t contentlen; /* alternative length of contents + field. Used if CURL_HTTPPOST_LARGE is + set. Added in 7.46.0 */ }; + +/* This is a return code for the progress callback that, when returned, will + signal libcurl to continue executing the default progress function */ +#define CURL_PROGRESSFUNC_CONTINUE 0x10000001 + +/* This is the CURLOPT_PROGRESSFUNCTION callback prototype. It is now + considered deprecated but was the only choice up until 7.31.0 */ typedef int (*curl_progress_callback)(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow); +/* This is the CURLOPT_XFERINFOFUNCTION callback prototype. It was introduced + in 7.32.0, avoids the use of floating point numbers and provides more + detailed information. */ +typedef int (*curl_xferinfo_callback)(void *clientp, + curl_off_t dltotal, + curl_off_t dlnow, + curl_off_t ultotal, + curl_off_t ulnow); + +#ifndef CURL_MAX_READ_SIZE + /* The maximum receive buffer size configurable via CURLOPT_BUFFERSIZE. */ +#define CURL_MAX_READ_SIZE 524288 +#endif + #ifndef CURL_MAX_WRITE_SIZE /* Tests have proven that 20K is a very bad buffer size for uploads on Windows, while 16K for some odd reason performed a lot better. @@ -189,16 +254,18 @@ typedef int (*curl_progress_callback)(void *clientp, #define CURL_MAX_HTTP_HEADER (100*1024) #endif - /* This is a magic return code for the write callback that, when returned, will signal libcurl to pause receiving on the current transfer. */ #define CURL_WRITEFUNC_PAUSE 0x10000001 + typedef size_t (*curl_write_callback)(char *buffer, size_t size, size_t nitems, void *outstream); - +/* This callback will be called when a new resolver request is made */ +typedef int (*curl_resolver_start_callback)(void *resolver_state, + void *reserved, void *userdata); /* enumeration of file types */ typedef enum { @@ -223,14 +290,11 @@ typedef enum { #define CURLFINFOFLAG_KNOWN_SIZE (1<<6) #define CURLFINFOFLAG_KNOWN_HLINKCOUNT (1<<7) -/* Content of this structure depends on information which is known and is - achievable (e.g. by FTP LIST parsing). Please see the url_easy_setopt(3) man - page for callbacks returning this structure -- some fields are mandatory, - some others are optional. The FLAG field has special meaning. */ +/* Information about a single file, used when doing FTP wildcard matching */ struct curl_fileinfo { char *filename; curlfiletype filetype; - time_t time; + time_t time; /* always zero! */ unsigned int perm; int uid; int gid; @@ -249,7 +313,7 @@ struct curl_fileinfo { unsigned int flags; /* used internally */ - char * b_data; + char *b_data; size_t b_size; size_t b_used; }; @@ -305,14 +369,25 @@ typedef int (*curl_seek_callback)(void *instream, signal libcurl to pause sending data on the current transfer. */ #define CURL_READFUNC_PAUSE 0x10000001 +/* Return code for when the trailing headers' callback has terminated + without any errors*/ +#define CURL_TRAILERFUNC_OK 0 +/* Return code for when was an error in the trailing header's list and we + want to abort the request */ +#define CURL_TRAILERFUNC_ABORT 1 + typedef size_t (*curl_read_callback)(char *buffer, size_t size, size_t nitems, void *instream); -typedef enum { - CURLSOCKTYPE_IPCXN, /* socket created for a specific IP connection */ - CURLSOCKTYPE_LAST /* never use */ +typedef int (*curl_trailer_callback)(struct curl_slist **list, + void *userdata); + +typedef enum { + CURLSOCKTYPE_IPCXN, /* socket created for a specific IP connection */ + CURLSOCKTYPE_ACCEPT, /* socket created by accept() call */ + CURLSOCKTYPE_LAST /* never use */ } curlsocktype; /* The return code from the sockopt_callback can signal information back @@ -341,6 +416,9 @@ typedef curl_socket_t curlsocktype purpose, struct curl_sockaddr *address); +typedef int +(*curl_closesocket_callback)(void *clientp, curl_socket_t item); + typedef enum { CURLIOE_OK, /* I/O operation successful */ CURLIOE_UNKNOWNCMD, /* command was unknown to callback */ @@ -348,7 +426,7 @@ typedef enum { CURLIOE_LAST /* never use */ } curlioerr; -typedef enum { +typedef enum { CURLIOCMD_NOP, /* no operation */ CURLIOCMD_RESTARTREAD, /* restart the read stream from start */ CURLIOCMD_LAST /* never use */ @@ -358,6 +436,7 @@ typedef curlioerr (*curl_ioctl_callback)(CURL *handle, int cmd, void *clientp); +#ifndef CURL_DID_MEMORY_FUNC_TYPEDEFS /* * The following typedef's are signatures of malloc, free, realloc, strdup and * calloc respectively. Function pointers of these types can be passed to the @@ -370,6 +449,9 @@ typedef void *(*curl_realloc_callback)(void *ptr, size_t size); typedef char *(*curl_strdup_callback)(const char *str); typedef void *(*curl_calloc_callback)(size_t nmemb, size_t size); +#define CURL_DID_MEMORY_FUNC_TYPEDEFS +#endif + /* the kind of data that is passed to information_callback*/ typedef enum { CURLINFO_TEXT = 0, @@ -406,17 +488,22 @@ typedef enum { CURLE_COULDNT_RESOLVE_PROXY, /* 5 */ CURLE_COULDNT_RESOLVE_HOST, /* 6 */ CURLE_COULDNT_CONNECT, /* 7 */ - CURLE_FTP_WEIRD_SERVER_REPLY, /* 8 */ + CURLE_WEIRD_SERVER_REPLY, /* 8 */ CURLE_REMOTE_ACCESS_DENIED, /* 9 a service was denied by the server due to lack of access - when login fails this is not returned. */ - CURLE_OBSOLETE10, /* 10 - NOT USED */ + CURLE_FTP_ACCEPT_FAILED, /* 10 - [was obsoleted in April 2006 for + 7.15.4, reused in Dec 2011 for 7.24.0]*/ CURLE_FTP_WEIRD_PASS_REPLY, /* 11 */ - CURLE_OBSOLETE12, /* 12 - NOT USED */ + CURLE_FTP_ACCEPT_TIMEOUT, /* 12 - timeout occurred accepting server + [was obsoleted in August 2007 for 7.17.0, + reused in Dec 2011 for 7.24.0]*/ CURLE_FTP_WEIRD_PASV_REPLY, /* 13 */ CURLE_FTP_WEIRD_227_FORMAT, /* 14 */ CURLE_FTP_CANT_GET_HOST, /* 15 */ - CURLE_OBSOLETE16, /* 16 - NOT USED */ + CURLE_HTTP2, /* 16 - A problem in the http2 framing layer. + [was obsoleted in August 2007 for 7.17.0, + reused in July 2014 for 7.38.0] */ CURLE_FTP_COULDNT_SET_TYPE, /* 17 */ CURLE_PARTIAL_FILE, /* 18 */ CURLE_FTP_COULDNT_RETR_FILE, /* 19 */ @@ -445,18 +532,17 @@ typedef enum { CURLE_LDAP_CANNOT_BIND, /* 38 */ CURLE_LDAP_SEARCH_FAILED, /* 39 */ CURLE_OBSOLETE40, /* 40 - NOT USED */ - CURLE_FUNCTION_NOT_FOUND, /* 41 */ + CURLE_FUNCTION_NOT_FOUND, /* 41 - NOT USED starting with 7.53.0 */ CURLE_ABORTED_BY_CALLBACK, /* 42 */ CURLE_BAD_FUNCTION_ARGUMENT, /* 43 */ CURLE_OBSOLETE44, /* 44 - NOT USED */ CURLE_INTERFACE_FAILED, /* 45 - CURLOPT_INTERFACE failed */ CURLE_OBSOLETE46, /* 46 - NOT USED */ - CURLE_TOO_MANY_REDIRECTS , /* 47 - catch endless re-direct loops */ + CURLE_TOO_MANY_REDIRECTS, /* 47 - catch endless re-direct loops */ CURLE_UNKNOWN_OPTION, /* 48 - User specified an unknown option */ - CURLE_TELNET_OPTION_SYNTAX , /* 49 - Malformed telnet option */ + CURLE_TELNET_OPTION_SYNTAX, /* 49 - Malformed telnet option */ CURLE_OBSOLETE50, /* 50 - NOT USED */ - CURLE_PEER_FAILED_VERIFICATION, /* 51 - peer's certificate or fingerprint - wasn't verified fine */ + CURLE_OBSOLETE51, /* 51 - NOT USED */ CURLE_GOT_NOTHING, /* 52 - when this is a specific error */ CURLE_SSL_ENGINE_NOTFOUND, /* 53 - SSL crypto engine not found */ CURLE_SSL_ENGINE_SETFAILED, /* 54 - can not set SSL crypto engine as @@ -466,7 +552,8 @@ typedef enum { CURLE_OBSOLETE57, /* 57 - NOT IN USE */ CURLE_SSL_CERTPROBLEM, /* 58 - problem with the local certificate */ CURLE_SSL_CIPHER, /* 59 - couldn't use specified cipher */ - CURLE_SSL_CACERT, /* 60 - problem with the CA cert (path?) */ + CURLE_PEER_FAILED_VERIFICATION, /* 60 - peer's certificate or fingerprint + wasn't verified fine */ CURLE_BAD_CONTENT_ENCODING, /* 61 - Unrecognized/bad encoding */ CURLE_LDAP_INVALID_URL, /* 62 - Invalid LDAP URL */ CURLE_FILESIZE_EXCEEDED, /* 63 - Maximum file size exceeded */ @@ -507,18 +594,41 @@ typedef enum { 7.19.0) */ CURLE_FTP_PRET_FAILED, /* 84 - a PRET command failed */ CURLE_RTSP_CSEQ_ERROR, /* 85 - mismatch of RTSP CSeq numbers */ - CURLE_RTSP_SESSION_ERROR, /* 86 - mismatch of RTSP Session Identifiers */ + CURLE_RTSP_SESSION_ERROR, /* 86 - mismatch of RTSP Session Ids */ CURLE_FTP_BAD_FILE_LIST, /* 87 - unable to parse FTP file list */ CURLE_CHUNK_FAILED, /* 88 - chunk callback reported error */ - + CURLE_NO_CONNECTION_AVAILABLE, /* 89 - No connection available, the + session will be queued */ + CURLE_SSL_PINNEDPUBKEYNOTMATCH, /* 90 - specified pinned public key did not + match */ + CURLE_SSL_INVALIDCERTSTATUS, /* 91 - invalid certificate status */ + CURLE_HTTP2_STREAM, /* 92 - stream error in HTTP/2 framing layer + */ + CURLE_RECURSIVE_API_CALL, /* 93 - an api function was called from + inside a callback */ + CURLE_AUTH_ERROR, /* 94 - an authentication function returned an + error */ + CURLE_HTTP3, /* 95 - An HTTP/3 layer problem */ + CURLE_QUIC_CONNECT_ERROR, /* 96 - QUIC connection error */ CURL_LAST /* never use! */ } CURLcode; #ifndef CURL_NO_OLDIES /* define this to test if your app builds with all the obsolete stuff removed! */ +/* Previously obsolete error code re-used in 7.38.0 */ +#define CURLE_OBSOLETE16 CURLE_HTTP2 + +/* Previously obsolete error codes re-used in 7.24.0 */ +#define CURLE_OBSOLETE10 CURLE_FTP_ACCEPT_FAILED +#define CURLE_OBSOLETE12 CURLE_FTP_ACCEPT_TIMEOUT + /* compatibility with older names */ #define CURLOPT_ENCODING CURLOPT_ACCEPT_ENCODING +#define CURLE_FTP_WEIRD_SERVER_REPLY CURLE_WEIRD_SERVER_REPLY + +/* The following were added in 7.62.0 */ +#define CURLE_SSL_CACERT CURLE_PEER_FAILED_VERIFICATION /* The following were added in 7.21.5, April 2011 */ #define CURLE_UNKNOWN_TELNET_OPTION CURLE_UNKNOWN_OPTION @@ -567,14 +677,26 @@ typedef enum { make programs break */ #define CURLE_ALREADY_COMPLETE 99999 +/* Provide defines for really old option names */ +#define CURLOPT_FILE CURLOPT_WRITEDATA /* name changed in 7.9.7 */ +#define CURLOPT_INFILE CURLOPT_READDATA /* name changed in 7.9.7 */ +#define CURLOPT_WRITEHEADER CURLOPT_HEADERDATA + +/* Since long deprecated options with no code in the lib that does anything + with them. */ +#define CURLOPT_WRITEINFO CURLOPT_OBSOLETE40 +#define CURLOPT_CLOSEPOLICY CURLOPT_OBSOLETE72 + #endif /*!CURL_NO_OLDIES*/ /* This prototype applies to all conversion callbacks */ typedef CURLcode (*curl_conv_callback)(char *buffer, size_t length); typedef CURLcode (*curl_ssl_ctx_callback)(CURL *curl, /* easy handle */ - void *ssl_ctx, /* actually an - OpenSSL SSL_CTX */ + void *ssl_ctx, /* actually an OpenSSL + or WolfSSL SSL_CTX, + or an mbedTLS + mbedtls_ssl_config */ void *userptr); typedef enum { @@ -582,6 +704,7 @@ typedef enum { CONNECT HTTP/1.1 */ CURLPROXY_HTTP_1_0 = 1, /* added in 7.19.4, force to use CONNECT HTTP/1.0 */ + CURLPROXY_HTTPS = 2, /* added in 7.52.0 */ CURLPROXY_SOCKS4 = 4, /* support added in 7.15.2, enum existed already in 7.10 */ CURLPROXY_SOCKS5 = 5, /* added in 7.10 */ @@ -591,17 +714,39 @@ typedef enum { in 7.18.0 */ } curl_proxytype; /* this enum was added in 7.10 */ -#define CURLAUTH_NONE 0 /* nothing */ -#define CURLAUTH_BASIC (1<<0) /* Basic (default) */ -#define CURLAUTH_DIGEST (1<<1) /* Digest */ -#define CURLAUTH_GSSNEGOTIATE (1<<2) /* GSS-Negotiate */ -#define CURLAUTH_NTLM (1<<3) /* NTLM */ -#define CURLAUTH_DIGEST_IE (1<<4) /* Digest with IE flavour */ -#define CURLAUTH_ONLY (1<<31) /* used together with a single other - type to force no auth or just that - single type */ -#define CURLAUTH_ANY (~CURLAUTH_DIGEST_IE) /* all fine types set */ -#define CURLAUTH_ANYSAFE (~(CURLAUTH_BASIC|CURLAUTH_DIGEST_IE)) +/* + * Bitmasks for CURLOPT_HTTPAUTH and CURLOPT_PROXYAUTH options: + * + * CURLAUTH_NONE - No HTTP authentication + * CURLAUTH_BASIC - HTTP Basic authentication (default) + * CURLAUTH_DIGEST - HTTP Digest authentication + * CURLAUTH_NEGOTIATE - HTTP Negotiate (SPNEGO) authentication + * CURLAUTH_GSSNEGOTIATE - Alias for CURLAUTH_NEGOTIATE (deprecated) + * CURLAUTH_NTLM - HTTP NTLM authentication + * CURLAUTH_DIGEST_IE - HTTP Digest authentication with IE flavour + * CURLAUTH_NTLM_WB - HTTP NTLM authentication delegated to winbind helper + * CURLAUTH_BEARER - HTTP Bearer token authentication + * CURLAUTH_ONLY - Use together with a single other type to force no + * authentication or just that single type + * CURLAUTH_ANY - All fine types set + * CURLAUTH_ANYSAFE - All fine types except Basic + */ + +#define CURLAUTH_NONE ((unsigned long)0) +#define CURLAUTH_BASIC (((unsigned long)1)<<0) +#define CURLAUTH_DIGEST (((unsigned long)1)<<1) +#define CURLAUTH_NEGOTIATE (((unsigned long)1)<<2) +/* Deprecated since the advent of CURLAUTH_NEGOTIATE */ +#define CURLAUTH_GSSNEGOTIATE CURLAUTH_NEGOTIATE +/* Used for CURLOPT_SOCKS5_AUTH to stay terminologically correct */ +#define CURLAUTH_GSSAPI CURLAUTH_NEGOTIATE +#define CURLAUTH_NTLM (((unsigned long)1)<<3) +#define CURLAUTH_DIGEST_IE (((unsigned long)1)<<4) +#define CURLAUTH_NTLM_WB (((unsigned long)1)<<5) +#define CURLAUTH_BEARER (((unsigned long)1)<<6) +#define CURLAUTH_ONLY (((unsigned long)1)<<31) +#define CURLAUTH_ANY (~CURLAUTH_DIGEST_IE) +#define CURLAUTH_ANYSAFE (~(CURLAUTH_BASIC|CURLAUTH_DIGEST_IE)) #define CURLSSH_AUTH_ANY ~0 /* all types supported by the server */ #define CURLSSH_AUTH_NONE 0 /* none allowed, silly but complete */ @@ -609,20 +754,30 @@ typedef enum { #define CURLSSH_AUTH_PASSWORD (1<<1) /* password */ #define CURLSSH_AUTH_HOST (1<<2) /* host key files */ #define CURLSSH_AUTH_KEYBOARD (1<<3) /* keyboard interactive */ +#define CURLSSH_AUTH_AGENT (1<<4) /* agent (ssh-agent, pageant...) */ +#define CURLSSH_AUTH_GSSAPI (1<<5) /* gssapi (kerberos, ...) */ #define CURLSSH_AUTH_DEFAULT CURLSSH_AUTH_ANY +#define CURLGSSAPI_DELEGATION_NONE 0 /* no delegation (default) */ +#define CURLGSSAPI_DELEGATION_POLICY_FLAG (1<<0) /* if permitted by policy */ +#define CURLGSSAPI_DELEGATION_FLAG (1<<1) /* delegate always */ + #define CURL_ERROR_SIZE 256 +enum curl_khtype { + CURLKHTYPE_UNKNOWN, + CURLKHTYPE_RSA1, + CURLKHTYPE_RSA, + CURLKHTYPE_DSS, + CURLKHTYPE_ECDSA, + CURLKHTYPE_ED25519 +}; + struct curl_khkey { const char *key; /* points to a zero-terminated string encoded with base64 if len is zero, otherwise to the "raw" data */ size_t len; - enum type { - CURLKHTYPE_UNKNOWN, - CURLKHTYPE_RSA1, - CURLKHTYPE_RSA, - CURLKHTYPE_DSS - } keytype; + enum curl_khtype keytype; }; /* this is the set of return values expected from the curl_sshkeycallback @@ -661,6 +816,31 @@ typedef enum { CURLUSESSL_LAST /* not an option, never use */ } curl_usessl; +/* Definition of bits for the CURLOPT_SSL_OPTIONS argument: */ + +/* - ALLOW_BEAST tells libcurl to allow the BEAST SSL vulnerability in the + name of improving interoperability with older servers. Some SSL libraries + have introduced work-arounds for this flaw but those work-arounds sometimes + make the SSL communication fail. To regain functionality with those broken + servers, a user can this way allow the vulnerability back. */ +#define CURLSSLOPT_ALLOW_BEAST (1<<0) + +/* - NO_REVOKE tells libcurl to disable certificate revocation checks for those + SSL backends where such behavior is present. */ +#define CURLSSLOPT_NO_REVOKE (1<<1) + +/* - NO_PARTIALCHAIN tells libcurl to *NOT* accept a partial certificate chain + if possible. The OpenSSL backend has this ability. */ +#define CURLSSLOPT_NO_PARTIALCHAIN (1<<2) + +/* The default connection attempt delay in milliseconds for happy eyeballs. + CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.3 and happy-eyeballs-timeout-ms.d document + this value, keep them in sync. */ +#define CURL_HET_DEFAULT 200L + +/* The default connection upkeep interval in milliseconds. */ +#define CURL_UPKEEP_INTERVAL_DEFAULT 60000L + #ifndef CURL_NO_OLDIES /* define this to test if your app builds with all the obsolete stuff removed! */ @@ -711,6 +891,18 @@ typedef enum { CURLFTPMETHOD_LAST /* not an option, never use */ } curl_ftpmethod; +/* bitmask defines for CURLOPT_HEADEROPT */ +#define CURLHEADER_UNIFIED 0 +#define CURLHEADER_SEPARATE (1<<0) + +/* CURLALTSVC_* are bits for the CURLOPT_ALTSVC_CTRL option */ +#define CURLALTSVC_IMMEDIATELY (1<<0) + +#define CURLALTSVC_READONLYFILE (1<<2) +#define CURLALTSVC_H1 (1<<3) +#define CURLALTSVC_H2 (1<<4) +#define CURLALTSVC_H3 (1<<5) + /* CURLPROTO_ defines are for the CURLOPT_*PROTOCOLS options */ #define CURLPROTO_HTTP (1<<0) #define CURLPROTO_HTTPS (1<<1) @@ -738,6 +930,8 @@ typedef enum { #define CURLPROTO_RTMPS (1<<23) #define CURLPROTO_RTMPTS (1<<24) #define CURLPROTO_GOPHER (1<<25) +#define CURLPROTO_SMB (1<<26) +#define CURLPROTO_SMBS (1<<27) #define CURLPROTO_ALL (~0) /* enable everything */ /* long may be 32 or 64 bits, but we should never depend on anything else @@ -747,71 +941,61 @@ typedef enum { #define CURLOPTTYPE_FUNCTIONPOINT 20000 #define CURLOPTTYPE_OFF_T 30000 -/* name is uppercase CURLOPT_, - type is one of the defined CURLOPTTYPE_ - number is unique identifier */ -#ifdef CINIT -#undef CINIT -#endif +/* *STRINGPOINT is an alias for OBJECTPOINT to allow tools to extract the + string options from the header file */ -#ifdef CURL_ISOCPP -#define CINIT(name,type,number) CURLOPT_ ## name = CURLOPTTYPE_ ## type + number -#else -/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ -#define LONG CURLOPTTYPE_LONG -#define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT -#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT -#define OFF_T CURLOPTTYPE_OFF_T -#define CINIT(name,type,number) CURLOPT_/**/name = type + number -#endif + +#define CURLOPT(na,t,nu) na = t + nu + +/* handy aliases that make no run-time difference */ +#define CURLOPTTYPE_STRINGPOINT CURLOPTTYPE_OBJECTPOINT +#define CURLOPTTYPE_SLISTPOINT CURLOPTTYPE_OBJECTPOINT /* - * This macro-mania below setups the CURLOPT_[what] enum, to be used with - * curl_easy_setopt(). The first argument in the CINIT() macro is the [what] - * word. + * All CURLOPT_* values. */ typedef enum { /* This is the FILE * or void * the regular output should be written to. */ - CINIT(FILE, OBJECTPOINT, 1), + CURLOPT(CURLOPT_WRITEDATA, CURLOPTTYPE_OBJECTPOINT, 1), /* The full URL to get/put */ - CINIT(URL, OBJECTPOINT, 2), + CURLOPT(CURLOPT_URL, CURLOPTTYPE_STRINGPOINT, 2), /* Port number to connect to, if other than default. */ - CINIT(PORT, LONG, 3), + CURLOPT(CURLOPT_PORT, CURLOPTTYPE_LONG, 3), /* Name of proxy to use. */ - CINIT(PROXY, OBJECTPOINT, 4), + CURLOPT(CURLOPT_PROXY, CURLOPTTYPE_STRINGPOINT, 4), - /* "name:password" to use when fetching. */ - CINIT(USERPWD, OBJECTPOINT, 5), + /* "user:password;options" to use when fetching. */ + CURLOPT(CURLOPT_USERPWD, CURLOPTTYPE_STRINGPOINT, 5), - /* "name:password" to use with proxy. */ - CINIT(PROXYUSERPWD, OBJECTPOINT, 6), + /* "user:password" to use with proxy. */ + CURLOPT(CURLOPT_PROXYUSERPWD, CURLOPTTYPE_STRINGPOINT, 6), /* Range to get, specified as an ASCII string. */ - CINIT(RANGE, OBJECTPOINT, 7), + CURLOPT(CURLOPT_RANGE, CURLOPTTYPE_STRINGPOINT, 7), /* not used */ /* Specified file stream to upload from (use as input): */ - CINIT(INFILE, OBJECTPOINT, 9), + CURLOPT(CURLOPT_READDATA, CURLOPTTYPE_OBJECTPOINT, 9), /* Buffer to receive error messages in, must be at least CURL_ERROR_SIZE - * bytes big. If this is not used, error messages go to stderr instead: */ - CINIT(ERRORBUFFER, OBJECTPOINT, 10), + * bytes big. */ + CURLOPT(CURLOPT_ERRORBUFFER, CURLOPTTYPE_OBJECTPOINT, 10), /* Function that will be called to store the output (instead of fwrite). The * parameters will use fwrite() syntax, make sure to follow them. */ - CINIT(WRITEFUNCTION, FUNCTIONPOINT, 11), + CURLOPT(CURLOPT_WRITEFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 11), /* Function that will be called to read the input (instead of fread). The * parameters will use fread() syntax, make sure to follow them. */ - CINIT(READFUNCTION, FUNCTIONPOINT, 12), + CURLOPT(CURLOPT_READFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 12), /* Time-out the read operation after this amount of seconds */ - CINIT(TIMEOUT, LONG, 13), + CURLOPT(CURLOPT_TIMEOUT, CURLOPTTYPE_LONG, 13), /* If the CURLOPT_INFILE is used, this can be used to inform libcurl about * how large the file being sent really is. That allows better error @@ -822,20 +1006,20 @@ typedef enum { * which takes an off_t type, allowing platforms with larger off_t * sizes to handle larger files. See below for INFILESIZE_LARGE. */ - CINIT(INFILESIZE, LONG, 14), + CURLOPT(CURLOPT_INFILESIZE, CURLOPTTYPE_LONG, 14), /* POST static input fields. */ - CINIT(POSTFIELDS, OBJECTPOINT, 15), + CURLOPT(CURLOPT_POSTFIELDS, CURLOPTTYPE_OBJECTPOINT, 15), /* Set the referrer page (needed by some CGIs) */ - CINIT(REFERER, OBJECTPOINT, 16), + CURLOPT(CURLOPT_REFERER, CURLOPTTYPE_STRINGPOINT, 16), /* Set the FTP PORT string (interface name, named or numerical IP address) Use i.e '-' to use default address. */ - CINIT(FTPPORT, OBJECTPOINT, 17), + CURLOPT(CURLOPT_FTPPORT, CURLOPTTYPE_STRINGPOINT, 17), /* Set the User-Agent string (examined by some CGIs) */ - CINIT(USERAGENT, OBJECTPOINT, 18), + CURLOPT(CURLOPT_USERAGENT, CURLOPTTYPE_STRINGPOINT, 18), /* If the download receives less than "low speed limit" bytes/second * during "low speed time" seconds, the operations is aborted. @@ -844,10 +1028,10 @@ typedef enum { */ /* Set the "low speed limit" */ - CINIT(LOW_SPEED_LIMIT, LONG, 19), + CURLOPT(CURLOPT_LOW_SPEED_LIMIT, CURLOPTTYPE_LONG, 19), /* Set the "low speed time" */ - CINIT(LOW_SPEED_TIME, LONG, 20), + CURLOPT(CURLOPT_LOW_SPEED_TIME, CURLOPTTYPE_LONG, 20), /* Set the continuation offset. * @@ -855,47 +1039,48 @@ typedef enum { * off_t types, allowing for large file offsets on platforms which * use larger-than-32-bit off_t's. Look below for RESUME_FROM_LARGE. */ - CINIT(RESUME_FROM, LONG, 21), + CURLOPT(CURLOPT_RESUME_FROM, CURLOPTTYPE_LONG, 21), /* Set cookie in request: */ - CINIT(COOKIE, OBJECTPOINT, 22), + CURLOPT(CURLOPT_COOKIE, CURLOPTTYPE_STRINGPOINT, 22), - /* This points to a linked list of headers, struct curl_slist kind */ - CINIT(HTTPHEADER, OBJECTPOINT, 23), + /* This points to a linked list of headers, struct curl_slist kind. This + list is also used for RTSP (in spite of its name) */ + CURLOPT(CURLOPT_HTTPHEADER, CURLOPTTYPE_SLISTPOINT, 23), /* This points to a linked list of post entries, struct curl_httppost */ - CINIT(HTTPPOST, OBJECTPOINT, 24), + CURLOPT(CURLOPT_HTTPPOST, CURLOPTTYPE_OBJECTPOINT, 24), /* name of the file keeping your private SSL-certificate */ - CINIT(SSLCERT, OBJECTPOINT, 25), + CURLOPT(CURLOPT_SSLCERT, CURLOPTTYPE_STRINGPOINT, 25), /* password for the SSL or SSH private key */ - CINIT(KEYPASSWD, OBJECTPOINT, 26), + CURLOPT(CURLOPT_KEYPASSWD, CURLOPTTYPE_STRINGPOINT, 26), /* send TYPE parameter? */ - CINIT(CRLF, LONG, 27), + CURLOPT(CURLOPT_CRLF, CURLOPTTYPE_LONG, 27), /* send linked-list of QUOTE commands */ - CINIT(QUOTE, OBJECTPOINT, 28), + CURLOPT(CURLOPT_QUOTE, CURLOPTTYPE_SLISTPOINT, 28), /* send FILE * or void * to store headers to, if you use a callback it is simply passed to the callback unmodified */ - CINIT(WRITEHEADER, OBJECTPOINT, 29), + CURLOPT(CURLOPT_HEADERDATA, CURLOPTTYPE_OBJECTPOINT, 29), /* point to a file to read the initial cookies from, also enables "cookie awareness" */ - CINIT(COOKIEFILE, OBJECTPOINT, 31), + CURLOPT(CURLOPT_COOKIEFILE, CURLOPTTYPE_STRINGPOINT, 31), /* What version to specifically try to use. See CURL_SSLVERSION defines below. */ - CINIT(SSLVERSION, LONG, 32), + CURLOPT(CURLOPT_SSLVERSION, CURLOPTTYPE_LONG, 32), /* What kind of HTTP time condition to use, see defines */ - CINIT(TIMECONDITION, LONG, 33), + CURLOPT(CURLOPT_TIMECONDITION, CURLOPTTYPE_LONG, 33), /* Time to use with the above condition. Specified in number of seconds since 1 Jan 1970 */ - CINIT(TIMEVALUE, LONG, 34), + CURLOPT(CURLOPT_TIMEVALUE, CURLOPTTYPE_LONG, 34), /* 35 = OBSOLETE */ @@ -903,304 +1088,326 @@ typedef enum { HTTP: DELETE, TRACE and others FTP: to use a different list command */ - CINIT(CUSTOMREQUEST, OBJECTPOINT, 36), + CURLOPT(CURLOPT_CUSTOMREQUEST, CURLOPTTYPE_STRINGPOINT, 36), - /* HTTP request, for odd commands like DELETE, TRACE and others */ - CINIT(STDERR, OBJECTPOINT, 37), + /* FILE handle to use instead of stderr */ + CURLOPT(CURLOPT_STDERR, CURLOPTTYPE_OBJECTPOINT, 37), /* 38 is not used */ /* send linked-list of post-transfer QUOTE commands */ - CINIT(POSTQUOTE, OBJECTPOINT, 39), + CURLOPT(CURLOPT_POSTQUOTE, CURLOPTTYPE_SLISTPOINT, 39), - /* Pass a pointer to string of the output using full variable-replacement - as described elsewhere. */ - CINIT(WRITEINFO, OBJECTPOINT, 40), + /* OBSOLETE, do not use! */ + CURLOPT(CURLOPT_OBSOLETE40, CURLOPTTYPE_OBJECTPOINT, 40), - CINIT(VERBOSE, LONG, 41), /* talk a lot */ - CINIT(HEADER, LONG, 42), /* throw the header out too */ - CINIT(NOPROGRESS, LONG, 43), /* shut off the progress meter */ - CINIT(NOBODY, LONG, 44), /* use HEAD to get http document */ - CINIT(FAILONERROR, LONG, 45), /* no output on http error codes >= 300 */ - CINIT(UPLOAD, LONG, 46), /* this is an upload */ - CINIT(POST, LONG, 47), /* HTTP POST method */ - CINIT(DIRLISTONLY, LONG, 48), /* return bare names when listing directories */ + /* talk a lot */ + CURLOPT(CURLOPT_VERBOSE, CURLOPTTYPE_LONG, 41), - CINIT(APPEND, LONG, 50), /* Append instead of overwrite on upload! */ + /* throw the header out too */ + CURLOPT(CURLOPT_HEADER, CURLOPTTYPE_LONG, 42), + + /* shut off the progress meter */ + CURLOPT(CURLOPT_NOPROGRESS, CURLOPTTYPE_LONG, 43), + + /* use HEAD to get http document */ + CURLOPT(CURLOPT_NOBODY, CURLOPTTYPE_LONG, 44), + + /* no output on http error codes >= 400 */ + CURLOPT(CURLOPT_FAILONERROR, CURLOPTTYPE_LONG, 45), + + /* this is an upload */ + CURLOPT(CURLOPT_UPLOAD, CURLOPTTYPE_LONG, 46), + + /* HTTP POST method */ + CURLOPT(CURLOPT_POST, CURLOPTTYPE_LONG, 47), + + /* bare names when listing directories */ + CURLOPT(CURLOPT_DIRLISTONLY, CURLOPTTYPE_LONG, 48), + + /* Append instead of overwrite on upload! */ + CURLOPT(CURLOPT_APPEND, CURLOPTTYPE_LONG, 50), /* Specify whether to read the user+password from the .netrc or the URL. * This must be one of the CURL_NETRC_* enums below. */ - CINIT(NETRC, LONG, 51), + CURLOPT(CURLOPT_NETRC, CURLOPTTYPE_LONG, 51), - CINIT(FOLLOWLOCATION, LONG, 52), /* use Location: Luke! */ + /* use Location: Luke! */ + CURLOPT(CURLOPT_FOLLOWLOCATION, CURLOPTTYPE_LONG, 52), - CINIT(TRANSFERTEXT, LONG, 53), /* transfer data in text/ASCII format */ - CINIT(PUT, LONG, 54), /* HTTP PUT */ + /* transfer data in text/ASCII format */ + CURLOPT(CURLOPT_TRANSFERTEXT, CURLOPTTYPE_LONG, 53), + + /* HTTP PUT */ + CURLOPT(CURLOPT_PUT, CURLOPTTYPE_LONG, 54), /* 55 = OBSOLETE */ - /* Function that will be called instead of the internal progress display + /* DEPRECATED + * Function that will be called instead of the internal progress display * function. This function should be defined as the curl_progress_callback * prototype defines. */ - CINIT(PROGRESSFUNCTION, FUNCTIONPOINT, 56), + CURLOPT(CURLOPT_PROGRESSFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 56), - /* Data passed to the progress callback */ - CINIT(PROGRESSDATA, OBJECTPOINT, 57), + /* Data passed to the CURLOPT_PROGRESSFUNCTION and CURLOPT_XFERINFOFUNCTION + callbacks */ + CURLOPT(CURLOPT_PROGRESSDATA, CURLOPTTYPE_OBJECTPOINT, 57), +#define CURLOPT_XFERINFODATA CURLOPT_PROGRESSDATA /* We want the referrer field set automatically when following locations */ - CINIT(AUTOREFERER, LONG, 58), + CURLOPT(CURLOPT_AUTOREFERER, CURLOPTTYPE_LONG, 58), /* Port of the proxy, can be set in the proxy string as well with: "[host]:[port]" */ - CINIT(PROXYPORT, LONG, 59), + CURLOPT(CURLOPT_PROXYPORT, CURLOPTTYPE_LONG, 59), /* size of the POST input data, if strlen() is not good to use */ - CINIT(POSTFIELDSIZE, LONG, 60), + CURLOPT(CURLOPT_POSTFIELDSIZE, CURLOPTTYPE_LONG, 60), /* tunnel non-http operations through a HTTP proxy */ - CINIT(HTTPPROXYTUNNEL, LONG, 61), + CURLOPT(CURLOPT_HTTPPROXYTUNNEL, CURLOPTTYPE_LONG, 61), /* Set the interface string to use as outgoing network interface */ - CINIT(INTERFACE, OBJECTPOINT, 62), + CURLOPT(CURLOPT_INTERFACE, CURLOPTTYPE_STRINGPOINT, 62), /* Set the krb4/5 security level, this also enables krb4/5 awareness. This * is a string, 'clear', 'safe', 'confidential' or 'private'. If the string * is set but doesn't match one of these, 'private' will be used. */ - CINIT(KRBLEVEL, OBJECTPOINT, 63), + CURLOPT(CURLOPT_KRBLEVEL, CURLOPTTYPE_STRINGPOINT, 63), /* Set if we should verify the peer in ssl handshake, set 1 to verify. */ - CINIT(SSL_VERIFYPEER, LONG, 64), + CURLOPT(CURLOPT_SSL_VERIFYPEER, CURLOPTTYPE_LONG, 64), /* The CApath or CAfile used to validate the peer certificate this option is used only if SSL_VERIFYPEER is true */ - CINIT(CAINFO, OBJECTPOINT, 65), + CURLOPT(CURLOPT_CAINFO, CURLOPTTYPE_STRINGPOINT, 65), /* 66 = OBSOLETE */ /* 67 = OBSOLETE */ /* Maximum number of http redirects to follow */ - CINIT(MAXREDIRS, LONG, 68), + CURLOPT(CURLOPT_MAXREDIRS, CURLOPTTYPE_LONG, 68), /* Pass a long set to 1 to get the date of the requested document (if possible)! Pass a zero to shut it off. */ - CINIT(FILETIME, LONG, 69), + CURLOPT(CURLOPT_FILETIME, CURLOPTTYPE_LONG, 69), /* This points to a linked list of telnet options */ - CINIT(TELNETOPTIONS, OBJECTPOINT, 70), + CURLOPT(CURLOPT_TELNETOPTIONS, CURLOPTTYPE_SLISTPOINT, 70), /* Max amount of cached alive connections */ - CINIT(MAXCONNECTS, LONG, 71), + CURLOPT(CURLOPT_MAXCONNECTS, CURLOPTTYPE_LONG, 71), - /* What policy to use when closing connections when the cache is filled - up */ - CINIT(CLOSEPOLICY, LONG, 72), + /* OBSOLETE, do not use! */ + CURLOPT(CURLOPT_OBSOLETE72, CURLOPTTYPE_LONG, 72), /* 73 = OBSOLETE */ /* Set to explicitly use a new connection for the upcoming transfer. Do not use this unless you're absolutely sure of this, as it makes the operation slower and is less friendly for the network. */ - CINIT(FRESH_CONNECT, LONG, 74), + CURLOPT(CURLOPT_FRESH_CONNECT, CURLOPTTYPE_LONG, 74), /* Set to explicitly forbid the upcoming transfer's connection to be re-used when done. Do not use this unless you're absolutely sure of this, as it makes the operation slower and is less friendly for the network. */ - CINIT(FORBID_REUSE, LONG, 75), + CURLOPT(CURLOPT_FORBID_REUSE, CURLOPTTYPE_LONG, 75), /* Set to a file name that contains random data for libcurl to use to seed the random engine when doing SSL connects. */ - CINIT(RANDOM_FILE, OBJECTPOINT, 76), + CURLOPT(CURLOPT_RANDOM_FILE, CURLOPTTYPE_STRINGPOINT, 76), /* Set to the Entropy Gathering Daemon socket pathname */ - CINIT(EGDSOCKET, OBJECTPOINT, 77), + CURLOPT(CURLOPT_EGDSOCKET, CURLOPTTYPE_STRINGPOINT, 77), - /* Time-out connect operations after this amount of seconds, if connects - are OK within this time, then fine... This only aborts the connect - phase. [Only works on unix-style/SIGALRM operating systems] */ - CINIT(CONNECTTIMEOUT, LONG, 78), + /* Time-out connect operations after this amount of seconds, if connects are + OK within this time, then fine... This only aborts the connect phase. */ + CURLOPT(CURLOPT_CONNECTTIMEOUT, CURLOPTTYPE_LONG, 78), /* Function that will be called to store headers (instead of fwrite). The * parameters will use fwrite() syntax, make sure to follow them. */ - CINIT(HEADERFUNCTION, FUNCTIONPOINT, 79), + CURLOPT(CURLOPT_HEADERFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 79), /* Set this to force the HTTP request to get back to GET. Only really usable if POST, PUT or a custom request have been used first. */ - CINIT(HTTPGET, LONG, 80), + CURLOPT(CURLOPT_HTTPGET, CURLOPTTYPE_LONG, 80), /* Set if we should verify the Common name from the peer certificate in ssl * handshake, set 1 to check existence, 2 to ensure that it matches the * provided hostname. */ - CINIT(SSL_VERIFYHOST, LONG, 81), + CURLOPT(CURLOPT_SSL_VERIFYHOST, CURLOPTTYPE_LONG, 81), /* Specify which file name to write all known cookies in after completed operation. Set file name to "-" (dash) to make it go to stdout. */ - CINIT(COOKIEJAR, OBJECTPOINT, 82), + CURLOPT(CURLOPT_COOKIEJAR, CURLOPTTYPE_STRINGPOINT, 82), /* Specify which SSL ciphers to use */ - CINIT(SSL_CIPHER_LIST, OBJECTPOINT, 83), + CURLOPT(CURLOPT_SSL_CIPHER_LIST, CURLOPTTYPE_STRINGPOINT, 83), /* Specify which HTTP version to use! This must be set to one of the CURL_HTTP_VERSION* enums set below. */ - CINIT(HTTP_VERSION, LONG, 84), + CURLOPT(CURLOPT_HTTP_VERSION, CURLOPTTYPE_LONG, 84), /* Specifically switch on or off the FTP engine's use of the EPSV command. By default, that one will always be attempted before the more traditional PASV command. */ - CINIT(FTP_USE_EPSV, LONG, 85), + CURLOPT(CURLOPT_FTP_USE_EPSV, CURLOPTTYPE_LONG, 85), /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") */ - CINIT(SSLCERTTYPE, OBJECTPOINT, 86), + CURLOPT(CURLOPT_SSLCERTTYPE, CURLOPTTYPE_STRINGPOINT, 86), /* name of the file keeping your private SSL-key */ - CINIT(SSLKEY, OBJECTPOINT, 87), + CURLOPT(CURLOPT_SSLKEY, CURLOPTTYPE_STRINGPOINT, 87), /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") */ - CINIT(SSLKEYTYPE, OBJECTPOINT, 88), + CURLOPT(CURLOPT_SSLKEYTYPE, CURLOPTTYPE_STRINGPOINT, 88), /* crypto engine for the SSL-sub system */ - CINIT(SSLENGINE, OBJECTPOINT, 89), + CURLOPT(CURLOPT_SSLENGINE, CURLOPTTYPE_STRINGPOINT, 89), /* set the crypto engine for the SSL-sub system as default the param has no meaning... */ - CINIT(SSLENGINE_DEFAULT, LONG, 90), + CURLOPT(CURLOPT_SSLENGINE_DEFAULT, CURLOPTTYPE_LONG, 90), /* Non-zero value means to use the global dns cache */ - CINIT(DNS_USE_GLOBAL_CACHE, LONG, 91), /* To become OBSOLETE soon */ + /* DEPRECATED, do not use! */ + CURLOPT(CURLOPT_DNS_USE_GLOBAL_CACHE, CURLOPTTYPE_LONG, 91), /* DNS cache timeout */ - CINIT(DNS_CACHE_TIMEOUT, LONG, 92), + CURLOPT(CURLOPT_DNS_CACHE_TIMEOUT, CURLOPTTYPE_LONG, 92), /* send linked-list of pre-transfer QUOTE commands */ - CINIT(PREQUOTE, OBJECTPOINT, 93), + CURLOPT(CURLOPT_PREQUOTE, CURLOPTTYPE_SLISTPOINT, 93), /* set the debug function */ - CINIT(DEBUGFUNCTION, FUNCTIONPOINT, 94), + CURLOPT(CURLOPT_DEBUGFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 94), /* set the data for the debug function */ - CINIT(DEBUGDATA, OBJECTPOINT, 95), + CURLOPT(CURLOPT_DEBUGDATA, CURLOPTTYPE_OBJECTPOINT, 95), /* mark this as start of a cookie session */ - CINIT(COOKIESESSION, LONG, 96), + CURLOPT(CURLOPT_COOKIESESSION, CURLOPTTYPE_LONG, 96), /* The CApath directory used to validate the peer certificate this option is used only if SSL_VERIFYPEER is true */ - CINIT(CAPATH, OBJECTPOINT, 97), + CURLOPT(CURLOPT_CAPATH, CURLOPTTYPE_STRINGPOINT, 97), /* Instruct libcurl to use a smaller receive buffer */ - CINIT(BUFFERSIZE, LONG, 98), + CURLOPT(CURLOPT_BUFFERSIZE, CURLOPTTYPE_LONG, 98), /* Instruct libcurl to not use any signal/alarm handlers, even when using timeouts. This option is useful for multi-threaded applications. See libcurl-the-guide for more background information. */ - CINIT(NOSIGNAL, LONG, 99), + CURLOPT(CURLOPT_NOSIGNAL, CURLOPTTYPE_LONG, 99), /* Provide a CURLShare for mutexing non-ts data */ - CINIT(SHARE, OBJECTPOINT, 100), + CURLOPT(CURLOPT_SHARE, CURLOPTTYPE_OBJECTPOINT, 100), /* indicates type of proxy. accepted values are CURLPROXY_HTTP (default), - CURLPROXY_SOCKS4, CURLPROXY_SOCKS4A and CURLPROXY_SOCKS5. */ - CINIT(PROXYTYPE, LONG, 101), + CURLPROXY_HTTPS, CURLPROXY_SOCKS4, CURLPROXY_SOCKS4A and + CURLPROXY_SOCKS5. */ + CURLOPT(CURLOPT_PROXYTYPE, CURLOPTTYPE_LONG, 101), /* Set the Accept-Encoding string. Use this to tell a server you would like the response to be compressed. Before 7.21.6, this was known as CURLOPT_ENCODING */ - CINIT(ACCEPT_ENCODING, OBJECTPOINT, 102), + CURLOPT(CURLOPT_ACCEPT_ENCODING, CURLOPTTYPE_STRINGPOINT, 102), /* Set pointer to private data */ - CINIT(PRIVATE, OBJECTPOINT, 103), + CURLOPT(CURLOPT_PRIVATE, CURLOPTTYPE_OBJECTPOINT, 103), /* Set aliases for HTTP 200 in the HTTP Response header */ - CINIT(HTTP200ALIASES, OBJECTPOINT, 104), + CURLOPT(CURLOPT_HTTP200ALIASES, CURLOPTTYPE_SLISTPOINT, 104), /* Continue to send authentication (user+password) when following locations, even when hostname changed. This can potentially send off the name and password to whatever host the server decides. */ - CINIT(UNRESTRICTED_AUTH, LONG, 105), + CURLOPT(CURLOPT_UNRESTRICTED_AUTH, CURLOPTTYPE_LONG, 105), - /* Specifically switch on or off the FTP engine's use of the EPRT command ( it - also disables the LPRT attempt). By default, those ones will always be + /* Specifically switch on or off the FTP engine's use of the EPRT command ( + it also disables the LPRT attempt). By default, those ones will always be attempted before the good old traditional PORT command. */ - CINIT(FTP_USE_EPRT, LONG, 106), + CURLOPT(CURLOPT_FTP_USE_EPRT, CURLOPTTYPE_LONG, 106), /* Set this to a bitmask value to enable the particular authentications methods you like. Use this in combination with CURLOPT_USERPWD. Note that setting multiple bits may cause extra network round-trips. */ - CINIT(HTTPAUTH, LONG, 107), + CURLOPT(CURLOPT_HTTPAUTH, CURLOPTTYPE_LONG, 107), - /* Set the ssl context callback function, currently only for OpenSSL ssl_ctx - in second argument. The function must be matching the - curl_ssl_ctx_callback proto. */ - CINIT(SSL_CTX_FUNCTION, FUNCTIONPOINT, 108), + /* Set the ssl context callback function, currently only for OpenSSL or + WolfSSL ssl_ctx, or mbedTLS mbedtls_ssl_config in the second argument. + The function must match the curl_ssl_ctx_callback prototype. */ + CURLOPT(CURLOPT_SSL_CTX_FUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 108), /* Set the userdata for the ssl context callback function's third argument */ - CINIT(SSL_CTX_DATA, OBJECTPOINT, 109), + CURLOPT(CURLOPT_SSL_CTX_DATA, CURLOPTTYPE_OBJECTPOINT, 109), /* FTP Option that causes missing dirs to be created on the remote server. In 7.19.4 we introduced the convenience enums for this option using the CURLFTP_CREATE_DIR prefix. */ - CINIT(FTP_CREATE_MISSING_DIRS, LONG, 110), + CURLOPT(CURLOPT_FTP_CREATE_MISSING_DIRS, CURLOPTTYPE_LONG, 110), /* Set this to a bitmask value to enable the particular authentications methods you like. Use this in combination with CURLOPT_PROXYUSERPWD. Note that setting multiple bits may cause extra network round-trips. */ - CINIT(PROXYAUTH, LONG, 111), + CURLOPT(CURLOPT_PROXYAUTH, CURLOPTTYPE_LONG, 111), /* FTP option that changes the timeout, in seconds, associated with getting a response. This is different from transfer timeout time and essentially places a demand on the FTP server to acknowledge commands in a timely manner. */ - CINIT(FTP_RESPONSE_TIMEOUT, LONG, 112), + CURLOPT(CURLOPT_FTP_RESPONSE_TIMEOUT, CURLOPTTYPE_LONG, 112), #define CURLOPT_SERVER_RESPONSE_TIMEOUT CURLOPT_FTP_RESPONSE_TIMEOUT /* Set this option to one of the CURL_IPRESOLVE_* defines (see below) to tell libcurl to resolve names to those IP versions only. This only has affect on systems with support for more than one, i.e IPv4 _and_ IPv6. */ - CINIT(IPRESOLVE, LONG, 113), + CURLOPT(CURLOPT_IPRESOLVE, CURLOPTTYPE_LONG, 113), /* Set this option to limit the size of a file that will be downloaded from an HTTP or FTP server. Note there is also _LARGE version which adds large file support for platforms which have larger off_t sizes. See MAXFILESIZE_LARGE below. */ - CINIT(MAXFILESIZE, LONG, 114), + CURLOPT(CURLOPT_MAXFILESIZE, CURLOPTTYPE_LONG, 114), /* See the comment for INFILESIZE above, but in short, specifies * the size of the file being uploaded. -1 means unknown. */ - CINIT(INFILESIZE_LARGE, OFF_T, 115), + CURLOPT(CURLOPT_INFILESIZE_LARGE, CURLOPTTYPE_OFF_T, 115), - /* Sets the continuation offset. There is also a LONG version of this; - * look above for RESUME_FROM. + /* Sets the continuation offset. There is also a CURLOPTTYPE_LONG version + * of this; look above for RESUME_FROM. */ - CINIT(RESUME_FROM_LARGE, OFF_T, 116), + CURLOPT(CURLOPT_RESUME_FROM_LARGE, CURLOPTTYPE_OFF_T, 116), /* Sets the maximum size of data that will be downloaded from * an HTTP or FTP server. See MAXFILESIZE above for the LONG version. */ - CINIT(MAXFILESIZE_LARGE, OFF_T, 117), + CURLOPT(CURLOPT_MAXFILESIZE_LARGE, CURLOPTTYPE_OFF_T, 117), /* Set this option to the file name of your .netrc file you want libcurl to parse (using the CURLOPT_NETRC option). If not set, libcurl will do a poor attempt to find the user's home directory and check for a .netrc file in there. */ - CINIT(NETRC_FILE, OBJECTPOINT, 118), + CURLOPT(CURLOPT_NETRC_FILE, CURLOPTTYPE_STRINGPOINT, 118), /* Enable SSL/TLS for FTP, pick one of: - CURLFTPSSL_TRY - try using SSL, proceed anyway otherwise - CURLFTPSSL_CONTROL - SSL for the control connection or fail - CURLFTPSSL_ALL - SSL for all communication or fail + CURLUSESSL_TRY - try using SSL, proceed anyway otherwise + CURLUSESSL_CONTROL - SSL for the control connection or fail + CURLUSESSL_ALL - SSL for all communication or fail */ - CINIT(USE_SSL, LONG, 119), + CURLOPT(CURLOPT_USE_SSL, CURLOPTTYPE_LONG, 119), /* The _LARGE version of the standard POSTFIELDSIZE option */ - CINIT(POSTFIELDSIZE_LARGE, OFF_T, 120), + CURLOPT(CURLOPT_POSTFIELDSIZE_LARGE, CURLOPTTYPE_OFF_T, 120), /* Enable/disable the TCP Nagle algorithm */ - CINIT(TCP_NODELAY, LONG, 121), + CURLOPT(CURLOPT_TCP_NODELAY, CURLOPTTYPE_LONG, 121), /* 122 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ /* 123 OBSOLETE. Gone in 7.16.0 */ @@ -1220,144 +1427,143 @@ typedef enum { CURLFTPAUTH_SSL - try "AUTH SSL" first, then TLS CURLFTPAUTH_TLS - try "AUTH TLS" first, then SSL */ - CINIT(FTPSSLAUTH, LONG, 129), + CURLOPT(CURLOPT_FTPSSLAUTH, CURLOPTTYPE_LONG, 129), - CINIT(IOCTLFUNCTION, FUNCTIONPOINT, 130), - CINIT(IOCTLDATA, OBJECTPOINT, 131), + CURLOPT(CURLOPT_IOCTLFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 130), + CURLOPT(CURLOPT_IOCTLDATA, CURLOPTTYPE_OBJECTPOINT, 131), /* 132 OBSOLETE. Gone in 7.16.0 */ /* 133 OBSOLETE. Gone in 7.16.0 */ /* zero terminated string for pass on to the FTP server when asked for "account" info */ - CINIT(FTP_ACCOUNT, OBJECTPOINT, 134), + CURLOPT(CURLOPT_FTP_ACCOUNT, CURLOPTTYPE_STRINGPOINT, 134), - /* feed cookies into cookie engine */ - CINIT(COOKIELIST, OBJECTPOINT, 135), + /* feed cookie into cookie engine */ + CURLOPT(CURLOPT_COOKIELIST, CURLOPTTYPE_STRINGPOINT, 135), /* ignore Content-Length */ - CINIT(IGNORE_CONTENT_LENGTH, LONG, 136), + CURLOPT(CURLOPT_IGNORE_CONTENT_LENGTH, CURLOPTTYPE_LONG, 136), /* Set to non-zero to skip the IP address received in a 227 PASV FTP server response. Typically used for FTP-SSL purposes but is not restricted to that. libcurl will then instead use the same IP address it used for the control connection. */ - CINIT(FTP_SKIP_PASV_IP, LONG, 137), + CURLOPT(CURLOPT_FTP_SKIP_PASV_IP, CURLOPTTYPE_LONG, 137), /* Select "file method" to use when doing FTP, see the curl_ftpmethod above. */ - CINIT(FTP_FILEMETHOD, LONG, 138), + CURLOPT(CURLOPT_FTP_FILEMETHOD, CURLOPTTYPE_LONG, 138), /* Local port number to bind the socket to */ - CINIT(LOCALPORT, LONG, 139), + CURLOPT(CURLOPT_LOCALPORT, CURLOPTTYPE_LONG, 139), /* Number of ports to try, including the first one set with LOCALPORT. Thus, setting it to 1 will make no additional attempts but the first. */ - CINIT(LOCALPORTRANGE, LONG, 140), + CURLOPT(CURLOPT_LOCALPORTRANGE, CURLOPTTYPE_LONG, 140), /* no transfer, set up connection and let application use the socket by extracting it with CURLINFO_LASTSOCKET */ - CINIT(CONNECT_ONLY, LONG, 141), + CURLOPT(CURLOPT_CONNECT_ONLY, CURLOPTTYPE_LONG, 141), /* Function that will be called to convert from the network encoding (instead of using the iconv calls in libcurl) */ - CINIT(CONV_FROM_NETWORK_FUNCTION, FUNCTIONPOINT, 142), + CURLOPT(CURLOPT_CONV_FROM_NETWORK_FUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 142), /* Function that will be called to convert to the network encoding (instead of using the iconv calls in libcurl) */ - CINIT(CONV_TO_NETWORK_FUNCTION, FUNCTIONPOINT, 143), + CURLOPT(CURLOPT_CONV_TO_NETWORK_FUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 143), /* Function that will be called to convert from UTF8 (instead of using the iconv calls in libcurl) Note that this is used only for SSL certificate processing */ - CINIT(CONV_FROM_UTF8_FUNCTION, FUNCTIONPOINT, 144), + CURLOPT(CURLOPT_CONV_FROM_UTF8_FUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 144), /* if the connection proceeds too quickly then need to slow it down */ /* limit-rate: maximum number of bytes per second to send or receive */ - CINIT(MAX_SEND_SPEED_LARGE, OFF_T, 145), - CINIT(MAX_RECV_SPEED_LARGE, OFF_T, 146), + CURLOPT(CURLOPT_MAX_SEND_SPEED_LARGE, CURLOPTTYPE_OFF_T, 145), + CURLOPT(CURLOPT_MAX_RECV_SPEED_LARGE, CURLOPTTYPE_OFF_T, 146), /* Pointer to command string to send if USER/PASS fails. */ - CINIT(FTP_ALTERNATIVE_TO_USER, OBJECTPOINT, 147), + CURLOPT(CURLOPT_FTP_ALTERNATIVE_TO_USER, CURLOPTTYPE_STRINGPOINT, 147), /* callback function for setting socket options */ - CINIT(SOCKOPTFUNCTION, FUNCTIONPOINT, 148), - CINIT(SOCKOPTDATA, OBJECTPOINT, 149), + CURLOPT(CURLOPT_SOCKOPTFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 148), + CURLOPT(CURLOPT_SOCKOPTDATA, CURLOPTTYPE_OBJECTPOINT, 149), /* set to 0 to disable session ID re-use for this transfer, default is enabled (== 1) */ - CINIT(SSL_SESSIONID_CACHE, LONG, 150), + CURLOPT(CURLOPT_SSL_SESSIONID_CACHE, CURLOPTTYPE_LONG, 150), /* allowed SSH authentication methods */ - CINIT(SSH_AUTH_TYPES, LONG, 151), + CURLOPT(CURLOPT_SSH_AUTH_TYPES, CURLOPTTYPE_LONG, 151), /* Used by scp/sftp to do public/private key authentication */ - CINIT(SSH_PUBLIC_KEYFILE, OBJECTPOINT, 152), - CINIT(SSH_PRIVATE_KEYFILE, OBJECTPOINT, 153), + CURLOPT(CURLOPT_SSH_PUBLIC_KEYFILE, CURLOPTTYPE_STRINGPOINT, 152), + CURLOPT(CURLOPT_SSH_PRIVATE_KEYFILE, CURLOPTTYPE_STRINGPOINT, 153), /* Send CCC (Clear Command Channel) after authentication */ - CINIT(FTP_SSL_CCC, LONG, 154), + CURLOPT(CURLOPT_FTP_SSL_CCC, CURLOPTTYPE_LONG, 154), /* Same as TIMEOUT and CONNECTTIMEOUT, but with ms resolution */ - CINIT(TIMEOUT_MS, LONG, 155), - CINIT(CONNECTTIMEOUT_MS, LONG, 156), + CURLOPT(CURLOPT_TIMEOUT_MS, CURLOPTTYPE_LONG, 155), + CURLOPT(CURLOPT_CONNECTTIMEOUT_MS, CURLOPTTYPE_LONG, 156), /* set to zero to disable the libcurl's decoding and thus pass the raw body data to the application even when it is encoded/compressed */ - CINIT(HTTP_TRANSFER_DECODING, LONG, 157), - CINIT(HTTP_CONTENT_DECODING, LONG, 158), + CURLOPT(CURLOPT_HTTP_TRANSFER_DECODING, CURLOPTTYPE_LONG, 157), + CURLOPT(CURLOPT_HTTP_CONTENT_DECODING, CURLOPTTYPE_LONG, 158), /* Permission used when creating new files and directories on the remote server for protocols that support it, SFTP/SCP/FILE */ - CINIT(NEW_FILE_PERMS, LONG, 159), - CINIT(NEW_DIRECTORY_PERMS, LONG, 160), + CURLOPT(CURLOPT_NEW_FILE_PERMS, CURLOPTTYPE_LONG, 159), + CURLOPT(CURLOPT_NEW_DIRECTORY_PERMS, CURLOPTTYPE_LONG, 160), /* Set the behaviour of POST when redirecting. Values must be set to one of CURL_REDIR* defines below. This used to be called CURLOPT_POST301 */ - CINIT(POSTREDIR, LONG, 161), + CURLOPT(CURLOPT_POSTREDIR, CURLOPTTYPE_LONG, 161), /* used by scp/sftp to verify the host's public key */ - CINIT(SSH_HOST_PUBLIC_KEY_MD5, OBJECTPOINT, 162), + CURLOPT(CURLOPT_SSH_HOST_PUBLIC_KEY_MD5, CURLOPTTYPE_STRINGPOINT, 162), /* Callback function for opening socket (instead of socket(2)). Optionally, callback is able change the address or refuse to connect returning CURL_SOCKET_BAD. The callback should have type curl_opensocket_callback */ - CINIT(OPENSOCKETFUNCTION, FUNCTIONPOINT, 163), - CINIT(OPENSOCKETDATA, OBJECTPOINT, 164), + CURLOPT(CURLOPT_OPENSOCKETFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 163), + CURLOPT(CURLOPT_OPENSOCKETDATA, CURLOPTTYPE_OBJECTPOINT, 164), /* POST volatile input fields. */ - CINIT(COPYPOSTFIELDS, OBJECTPOINT, 165), + CURLOPT(CURLOPT_COPYPOSTFIELDS, CURLOPTTYPE_OBJECTPOINT, 165), /* set transfer mode (;type=) when doing FTP via an HTTP proxy */ - CINIT(PROXY_TRANSFER_MODE, LONG, 166), + CURLOPT(CURLOPT_PROXY_TRANSFER_MODE, CURLOPTTYPE_LONG, 166), /* Callback function for seeking in the input stream */ - CINIT(SEEKFUNCTION, FUNCTIONPOINT, 167), - CINIT(SEEKDATA, OBJECTPOINT, 168), + CURLOPT(CURLOPT_SEEKFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 167), + CURLOPT(CURLOPT_SEEKDATA, CURLOPTTYPE_OBJECTPOINT, 168), /* CRL file */ - CINIT(CRLFILE, OBJECTPOINT, 169), + CURLOPT(CURLOPT_CRLFILE, CURLOPTTYPE_STRINGPOINT, 169), /* Issuer certificate */ - CINIT(ISSUERCERT, OBJECTPOINT, 170), + CURLOPT(CURLOPT_ISSUERCERT, CURLOPTTYPE_STRINGPOINT, 170), /* (IPv6) Address scope */ - CINIT(ADDRESS_SCOPE, LONG, 171), + CURLOPT(CURLOPT_ADDRESS_SCOPE, CURLOPTTYPE_LONG, 171), /* Collect certificate chain info and allow it to get retrievable with - CURLINFO_CERTINFO after the transfer is complete. (Unfortunately) only - working with OpenSSL-powered builds. */ - CINIT(CERTINFO, LONG, 172), + CURLINFO_CERTINFO after the transfer is complete. */ + CURLOPT(CURLOPT_CERTINFO, CURLOPTTYPE_LONG, 172), /* "name" and "pwd" to use when fetching. */ - CINIT(USERNAME, OBJECTPOINT, 173), - CINIT(PASSWORD, OBJECTPOINT, 174), + CURLOPT(CURLOPT_USERNAME, CURLOPTTYPE_STRINGPOINT, 173), + CURLOPT(CURLOPT_PASSWORD, CURLOPTTYPE_STRINGPOINT, 174), /* "name" and "pwd" to use with Proxy when fetching. */ - CINIT(PROXYUSERNAME, OBJECTPOINT, 175), - CINIT(PROXYPASSWORD, OBJECTPOINT, 176), + CURLOPT(CURLOPT_PROXYUSERNAME, CURLOPTTYPE_STRINGPOINT, 175), + CURLOPT(CURLOPT_PROXYPASSWORD, CURLOPTTYPE_STRINGPOINT, 176), /* Comma separated list of hostnames defining no-proxy zones. These should match both hostnames directly, and hostnames within a domain. For @@ -1366,103 +1572,103 @@ typedef enum { implementations of this, .local.com will be considered to be the same as local.com. A single * is the only valid wildcard, and effectively disables the use of proxy. */ - CINIT(NOPROXY, OBJECTPOINT, 177), + CURLOPT(CURLOPT_NOPROXY, CURLOPTTYPE_STRINGPOINT, 177), /* block size for TFTP transfers */ - CINIT(TFTP_BLKSIZE, LONG, 178), + CURLOPT(CURLOPT_TFTP_BLKSIZE, CURLOPTTYPE_LONG, 178), /* Socks Service */ - CINIT(SOCKS5_GSSAPI_SERVICE, OBJECTPOINT, 179), + /* DEPRECATED, do not use! */ + CURLOPT(CURLOPT_SOCKS5_GSSAPI_SERVICE, CURLOPTTYPE_STRINGPOINT, 179), /* Socks Service */ - CINIT(SOCKS5_GSSAPI_NEC, LONG, 180), + CURLOPT(CURLOPT_SOCKS5_GSSAPI_NEC, CURLOPTTYPE_LONG, 180), /* set the bitmask for the protocols that are allowed to be used for the transfer, which thus helps the app which takes URLs from users or other external inputs and want to restrict what protocol(s) to deal with. Defaults to CURLPROTO_ALL. */ - CINIT(PROTOCOLS, LONG, 181), + CURLOPT(CURLOPT_PROTOCOLS, CURLOPTTYPE_LONG, 181), /* set the bitmask for the protocols that libcurl is allowed to follow to, as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs - to be set in both bitmasks to be allowed to get redirected to. Defaults - to all protocols except FILE and SCP. */ - CINIT(REDIR_PROTOCOLS, LONG, 182), + to be set in both bitmasks to be allowed to get redirected to. */ + CURLOPT(CURLOPT_REDIR_PROTOCOLS, CURLOPTTYPE_LONG, 182), /* set the SSH knownhost file name to use */ - CINIT(SSH_KNOWNHOSTS, OBJECTPOINT, 183), + CURLOPT(CURLOPT_SSH_KNOWNHOSTS, CURLOPTTYPE_STRINGPOINT, 183), /* set the SSH host key callback, must point to a curl_sshkeycallback function */ - CINIT(SSH_KEYFUNCTION, FUNCTIONPOINT, 184), + CURLOPT(CURLOPT_SSH_KEYFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 184), /* set the SSH host key callback custom pointer */ - CINIT(SSH_KEYDATA, OBJECTPOINT, 185), + CURLOPT(CURLOPT_SSH_KEYDATA, CURLOPTTYPE_OBJECTPOINT, 185), /* set the SMTP mail originator */ - CINIT(MAIL_FROM, OBJECTPOINT, 186), + CURLOPT(CURLOPT_MAIL_FROM, CURLOPTTYPE_STRINGPOINT, 186), - /* set the SMTP mail receiver(s) */ - CINIT(MAIL_RCPT, OBJECTPOINT, 187), + /* set the list of SMTP mail receiver(s) */ + CURLOPT(CURLOPT_MAIL_RCPT, CURLOPTTYPE_SLISTPOINT, 187), /* FTP: send PRET before PASV */ - CINIT(FTP_USE_PRET, LONG, 188), + CURLOPT(CURLOPT_FTP_USE_PRET, CURLOPTTYPE_LONG, 188), /* RTSP request method (OPTIONS, SETUP, PLAY, etc...) */ - CINIT(RTSP_REQUEST, LONG, 189), + CURLOPT(CURLOPT_RTSP_REQUEST, CURLOPTTYPE_LONG, 189), /* The RTSP session identifier */ - CINIT(RTSP_SESSION_ID, OBJECTPOINT, 190), + CURLOPT(CURLOPT_RTSP_SESSION_ID, CURLOPTTYPE_STRINGPOINT, 190), /* The RTSP stream URI */ - CINIT(RTSP_STREAM_URI, OBJECTPOINT, 191), + CURLOPT(CURLOPT_RTSP_STREAM_URI, CURLOPTTYPE_STRINGPOINT, 191), /* The Transport: header to use in RTSP requests */ - CINIT(RTSP_TRANSPORT, OBJECTPOINT, 192), + CURLOPT(CURLOPT_RTSP_TRANSPORT, CURLOPTTYPE_STRINGPOINT, 192), /* Manually initialize the client RTSP CSeq for this handle */ - CINIT(RTSP_CLIENT_CSEQ, LONG, 193), + CURLOPT(CURLOPT_RTSP_CLIENT_CSEQ, CURLOPTTYPE_LONG, 193), /* Manually initialize the server RTSP CSeq for this handle */ - CINIT(RTSP_SERVER_CSEQ, LONG, 194), + CURLOPT(CURLOPT_RTSP_SERVER_CSEQ, CURLOPTTYPE_LONG, 194), /* The stream to pass to INTERLEAVEFUNCTION. */ - CINIT(INTERLEAVEDATA, OBJECTPOINT, 195), + CURLOPT(CURLOPT_INTERLEAVEDATA, CURLOPTTYPE_OBJECTPOINT, 195), /* Let the application define a custom write method for RTP data */ - CINIT(INTERLEAVEFUNCTION, FUNCTIONPOINT, 196), + CURLOPT(CURLOPT_INTERLEAVEFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 196), /* Turn on wildcard matching */ - CINIT(WILDCARDMATCH, LONG, 197), + CURLOPT(CURLOPT_WILDCARDMATCH, CURLOPTTYPE_LONG, 197), /* Directory matching callback called before downloading of an individual file (chunk) started */ - CINIT(CHUNK_BGN_FUNCTION, FUNCTIONPOINT, 198), + CURLOPT(CURLOPT_CHUNK_BGN_FUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 198), /* Directory matching callback called after the file (chunk) was downloaded, or skipped */ - CINIT(CHUNK_END_FUNCTION, FUNCTIONPOINT, 199), + CURLOPT(CURLOPT_CHUNK_END_FUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 199), /* Change match (fnmatch-like) callback for wildcard matching */ - CINIT(FNMATCH_FUNCTION, FUNCTIONPOINT, 200), + CURLOPT(CURLOPT_FNMATCH_FUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 200), /* Let the application define custom chunk data pointer */ - CINIT(CHUNK_DATA, OBJECTPOINT, 201), + CURLOPT(CURLOPT_CHUNK_DATA, CURLOPTTYPE_OBJECTPOINT, 201), /* FNMATCH_FUNCTION user pointer */ - CINIT(FNMATCH_DATA, OBJECTPOINT, 202), + CURLOPT(CURLOPT_FNMATCH_DATA, CURLOPTTYPE_OBJECTPOINT, 202), /* send linked-list of name:port:address sets */ - CINIT(RESOLVE, OBJECTPOINT, 203), + CURLOPT(CURLOPT_RESOLVE, CURLOPTTYPE_SLISTPOINT, 203), /* Set a username for authenticated TLS */ - CINIT(TLSAUTH_USERNAME, OBJECTPOINT, 204), + CURLOPT(CURLOPT_TLSAUTH_USERNAME, CURLOPTTYPE_STRINGPOINT, 204), /* Set a password for authenticated TLS */ - CINIT(TLSAUTH_PASSWORD, OBJECTPOINT, 205), + CURLOPT(CURLOPT_TLSAUTH_PASSWORD, CURLOPTTYPE_STRINGPOINT, 205), /* Set authentication type for authenticated TLS */ - CINIT(TLSAUTH_TYPE, OBJECTPOINT, 206), + CURLOPT(CURLOPT_TLSAUTH_TYPE, CURLOPTTYPE_STRINGPOINT, 206), /* Set to 1 to enable the "TE:" header in HTTP requests to ask for compressed transfer-encoded responses. Set to 0 to disable the use of TE: @@ -1474,7 +1680,274 @@ typedef enum { option is set to 1. */ - CINIT(TRANSFER_ENCODING, LONG, 207), + CURLOPT(CURLOPT_TRANSFER_ENCODING, CURLOPTTYPE_LONG, 207), + + /* Callback function for closing socket (instead of close(2)). The callback + should have type curl_closesocket_callback */ + CURLOPT(CURLOPT_CLOSESOCKETFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 208), + CURLOPT(CURLOPT_CLOSESOCKETDATA, CURLOPTTYPE_OBJECTPOINT, 209), + + /* allow GSSAPI credential delegation */ + CURLOPT(CURLOPT_GSSAPI_DELEGATION, CURLOPTTYPE_LONG, 210), + + /* Set the name servers to use for DNS resolution */ + CURLOPT(CURLOPT_DNS_SERVERS, CURLOPTTYPE_STRINGPOINT, 211), + + /* Time-out accept operations (currently for FTP only) after this amount + of milliseconds. */ + CURLOPT(CURLOPT_ACCEPTTIMEOUT_MS, CURLOPTTYPE_LONG, 212), + + /* Set TCP keepalive */ + CURLOPT(CURLOPT_TCP_KEEPALIVE, CURLOPTTYPE_LONG, 213), + + /* non-universal keepalive knobs (Linux, AIX, HP-UX, more) */ + CURLOPT(CURLOPT_TCP_KEEPIDLE, CURLOPTTYPE_LONG, 214), + CURLOPT(CURLOPT_TCP_KEEPINTVL, CURLOPTTYPE_LONG, 215), + + /* Enable/disable specific SSL features with a bitmask, see CURLSSLOPT_* */ + CURLOPT(CURLOPT_SSL_OPTIONS, CURLOPTTYPE_LONG, 216), + + /* Set the SMTP auth originator */ + CURLOPT(CURLOPT_MAIL_AUTH, CURLOPTTYPE_STRINGPOINT, 217), + + /* Enable/disable SASL initial response */ + CURLOPT(CURLOPT_SASL_IR, CURLOPTTYPE_LONG, 218), + + /* Function that will be called instead of the internal progress display + * function. This function should be defined as the curl_xferinfo_callback + * prototype defines. (Deprecates CURLOPT_PROGRESSFUNCTION) */ + CURLOPT(CURLOPT_XFERINFOFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 219), + + /* The XOAUTH2 bearer token */ + CURLOPT(CURLOPT_XOAUTH2_BEARER, CURLOPTTYPE_STRINGPOINT, 220), + + /* Set the interface string to use as outgoing network + * interface for DNS requests. + * Only supported by the c-ares DNS backend */ + CURLOPT(CURLOPT_DNS_INTERFACE, CURLOPTTYPE_STRINGPOINT, 221), + + /* Set the local IPv4 address to use for outgoing DNS requests. + * Only supported by the c-ares DNS backend */ + CURLOPT(CURLOPT_DNS_LOCAL_IP4, CURLOPTTYPE_STRINGPOINT, 222), + + /* Set the local IPv6 address to use for outgoing DNS requests. + * Only supported by the c-ares DNS backend */ + CURLOPT(CURLOPT_DNS_LOCAL_IP6, CURLOPTTYPE_STRINGPOINT, 223), + + /* Set authentication options directly */ + CURLOPT(CURLOPT_LOGIN_OPTIONS, CURLOPTTYPE_STRINGPOINT, 224), + + /* Enable/disable TLS NPN extension (http2 over ssl might fail without) */ + CURLOPT(CURLOPT_SSL_ENABLE_NPN, CURLOPTTYPE_LONG, 225), + + /* Enable/disable TLS ALPN extension (http2 over ssl might fail without) */ + CURLOPT(CURLOPT_SSL_ENABLE_ALPN, CURLOPTTYPE_LONG, 226), + + /* Time to wait for a response to a HTTP request containing an + * Expect: 100-continue header before sending the data anyway. */ + CURLOPT(CURLOPT_EXPECT_100_TIMEOUT_MS, CURLOPTTYPE_LONG, 227), + + /* This points to a linked list of headers used for proxy requests only, + struct curl_slist kind */ + CURLOPT(CURLOPT_PROXYHEADER, CURLOPTTYPE_SLISTPOINT, 228), + + /* Pass in a bitmask of "header options" */ + CURLOPT(CURLOPT_HEADEROPT, CURLOPTTYPE_LONG, 229), + + /* The public key in DER form used to validate the peer public key + this option is used only if SSL_VERIFYPEER is true */ + CURLOPT(CURLOPT_PINNEDPUBLICKEY, CURLOPTTYPE_STRINGPOINT, 230), + + /* Path to Unix domain socket */ + CURLOPT(CURLOPT_UNIX_SOCKET_PATH, CURLOPTTYPE_STRINGPOINT, 231), + + /* Set if we should verify the certificate status. */ + CURLOPT(CURLOPT_SSL_VERIFYSTATUS, CURLOPTTYPE_LONG, 232), + + /* Set if we should enable TLS false start. */ + CURLOPT(CURLOPT_SSL_FALSESTART, CURLOPTTYPE_LONG, 233), + + /* Do not squash dot-dot sequences */ + CURLOPT(CURLOPT_PATH_AS_IS, CURLOPTTYPE_LONG, 234), + + /* Proxy Service Name */ + CURLOPT(CURLOPT_PROXY_SERVICE_NAME, CURLOPTTYPE_STRINGPOINT, 235), + + /* Service Name */ + CURLOPT(CURLOPT_SERVICE_NAME, CURLOPTTYPE_STRINGPOINT, 236), + + /* Wait/don't wait for pipe/mutex to clarify */ + CURLOPT(CURLOPT_PIPEWAIT, CURLOPTTYPE_LONG, 237), + + /* Set the protocol used when curl is given a URL without a protocol */ + CURLOPT(CURLOPT_DEFAULT_PROTOCOL, CURLOPTTYPE_STRINGPOINT, 238), + + /* Set stream weight, 1 - 256 (default is 16) */ + CURLOPT(CURLOPT_STREAM_WEIGHT, CURLOPTTYPE_LONG, 239), + + /* Set stream dependency on another CURL handle */ + CURLOPT(CURLOPT_STREAM_DEPENDS, CURLOPTTYPE_OBJECTPOINT, 240), + + /* Set E-xclusive stream dependency on another CURL handle */ + CURLOPT(CURLOPT_STREAM_DEPENDS_E, CURLOPTTYPE_OBJECTPOINT, 241), + + /* Do not send any tftp option requests to the server */ + CURLOPT(CURLOPT_TFTP_NO_OPTIONS, CURLOPTTYPE_LONG, 242), + + /* Linked-list of host:port:connect-to-host:connect-to-port, + overrides the URL's host:port (only for the network layer) */ + CURLOPT(CURLOPT_CONNECT_TO, CURLOPTTYPE_SLISTPOINT, 243), + + /* Set TCP Fast Open */ + CURLOPT(CURLOPT_TCP_FASTOPEN, CURLOPTTYPE_LONG, 244), + + /* Continue to send data if the server responds early with an + * HTTP status code >= 300 */ + CURLOPT(CURLOPT_KEEP_SENDING_ON_ERROR, CURLOPTTYPE_LONG, 245), + + /* The CApath or CAfile used to validate the proxy certificate + this option is used only if PROXY_SSL_VERIFYPEER is true */ + CURLOPT(CURLOPT_PROXY_CAINFO, CURLOPTTYPE_STRINGPOINT, 246), + + /* The CApath directory used to validate the proxy certificate + this option is used only if PROXY_SSL_VERIFYPEER is true */ + CURLOPT(CURLOPT_PROXY_CAPATH, CURLOPTTYPE_STRINGPOINT, 247), + + /* Set if we should verify the proxy in ssl handshake, + set 1 to verify. */ + CURLOPT(CURLOPT_PROXY_SSL_VERIFYPEER, CURLOPTTYPE_LONG, 248), + + /* Set if we should verify the Common name from the proxy certificate in ssl + * handshake, set 1 to check existence, 2 to ensure that it matches + * the provided hostname. */ + CURLOPT(CURLOPT_PROXY_SSL_VERIFYHOST, CURLOPTTYPE_LONG, 249), + + /* What version to specifically try to use for proxy. + See CURL_SSLVERSION defines below. */ + CURLOPT(CURLOPT_PROXY_SSLVERSION, CURLOPTTYPE_LONG, 250), + + /* Set a username for authenticated TLS for proxy */ + CURLOPT(CURLOPT_PROXY_TLSAUTH_USERNAME, CURLOPTTYPE_STRINGPOINT, 251), + + /* Set a password for authenticated TLS for proxy */ + CURLOPT(CURLOPT_PROXY_TLSAUTH_PASSWORD, CURLOPTTYPE_STRINGPOINT, 252), + + /* Set authentication type for authenticated TLS for proxy */ + CURLOPT(CURLOPT_PROXY_TLSAUTH_TYPE, CURLOPTTYPE_STRINGPOINT, 253), + + /* name of the file keeping your private SSL-certificate for proxy */ + CURLOPT(CURLOPT_PROXY_SSLCERT, CURLOPTTYPE_STRINGPOINT, 254), + + /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") for + proxy */ + CURLOPT(CURLOPT_PROXY_SSLCERTTYPE, CURLOPTTYPE_STRINGPOINT, 255), + + /* name of the file keeping your private SSL-key for proxy */ + CURLOPT(CURLOPT_PROXY_SSLKEY, CURLOPTTYPE_STRINGPOINT, 256), + + /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") for + proxy */ + CURLOPT(CURLOPT_PROXY_SSLKEYTYPE, CURLOPTTYPE_STRINGPOINT, 257), + + /* password for the SSL private key for proxy */ + CURLOPT(CURLOPT_PROXY_KEYPASSWD, CURLOPTTYPE_STRINGPOINT, 258), + + /* Specify which SSL ciphers to use for proxy */ + CURLOPT(CURLOPT_PROXY_SSL_CIPHER_LIST, CURLOPTTYPE_STRINGPOINT, 259), + + /* CRL file for proxy */ + CURLOPT(CURLOPT_PROXY_CRLFILE, CURLOPTTYPE_STRINGPOINT, 260), + + /* Enable/disable specific SSL features with a bitmask for proxy, see + CURLSSLOPT_* */ + CURLOPT(CURLOPT_PROXY_SSL_OPTIONS, CURLOPTTYPE_LONG, 261), + + /* Name of pre proxy to use. */ + CURLOPT(CURLOPT_PRE_PROXY, CURLOPTTYPE_STRINGPOINT, 262), + + /* The public key in DER form used to validate the proxy public key + this option is used only if PROXY_SSL_VERIFYPEER is true */ + CURLOPT(CURLOPT_PROXY_PINNEDPUBLICKEY, CURLOPTTYPE_STRINGPOINT, 263), + + /* Path to an abstract Unix domain socket */ + CURLOPT(CURLOPT_ABSTRACT_UNIX_SOCKET, CURLOPTTYPE_STRINGPOINT, 264), + + /* Suppress proxy CONNECT response headers from user callbacks */ + CURLOPT(CURLOPT_SUPPRESS_CONNECT_HEADERS, CURLOPTTYPE_LONG, 265), + + /* The request target, instead of extracted from the URL */ + CURLOPT(CURLOPT_REQUEST_TARGET, CURLOPTTYPE_STRINGPOINT, 266), + + /* bitmask of allowed auth methods for connections to SOCKS5 proxies */ + CURLOPT(CURLOPT_SOCKS5_AUTH, CURLOPTTYPE_LONG, 267), + + /* Enable/disable SSH compression */ + CURLOPT(CURLOPT_SSH_COMPRESSION, CURLOPTTYPE_LONG, 268), + + /* Post MIME data. */ + CURLOPT(CURLOPT_MIMEPOST, CURLOPTTYPE_OBJECTPOINT, 269), + + /* Time to use with the CURLOPT_TIMECONDITION. Specified in number of + seconds since 1 Jan 1970. */ + CURLOPT(CURLOPT_TIMEVALUE_LARGE, CURLOPTTYPE_OFF_T, 270), + + /* Head start in milliseconds to give happy eyeballs. */ + CURLOPT(CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS, CURLOPTTYPE_LONG, 271), + + /* Function that will be called before a resolver request is made */ + CURLOPT(CURLOPT_RESOLVER_START_FUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 272), + + /* User data to pass to the resolver start callback. */ + CURLOPT(CURLOPT_RESOLVER_START_DATA, CURLOPTTYPE_OBJECTPOINT, 273), + + /* send HAProxy PROXY protocol header? */ + CURLOPT(CURLOPT_HAPROXYPROTOCOL, CURLOPTTYPE_LONG, 274), + + /* shuffle addresses before use when DNS returns multiple */ + CURLOPT(CURLOPT_DNS_SHUFFLE_ADDRESSES, CURLOPTTYPE_LONG, 275), + + /* Specify which TLS 1.3 ciphers suites to use */ + CURLOPT(CURLOPT_TLS13_CIPHERS, CURLOPTTYPE_STRINGPOINT, 276), + CURLOPT(CURLOPT_PROXY_TLS13_CIPHERS, CURLOPTTYPE_STRINGPOINT, 277), + + /* Disallow specifying username/login in URL. */ + CURLOPT(CURLOPT_DISALLOW_USERNAME_IN_URL, CURLOPTTYPE_LONG, 278), + + /* DNS-over-HTTPS URL */ + CURLOPT(CURLOPT_DOH_URL, CURLOPTTYPE_STRINGPOINT, 279), + + /* Preferred buffer size to use for uploads */ + CURLOPT(CURLOPT_UPLOAD_BUFFERSIZE, CURLOPTTYPE_LONG, 280), + + /* Time in ms between connection upkeep calls for long-lived connections. */ + CURLOPT(CURLOPT_UPKEEP_INTERVAL_MS, CURLOPTTYPE_LONG, 281), + + /* Specify URL using CURL URL API. */ + CURLOPT(CURLOPT_CURLU, CURLOPTTYPE_OBJECTPOINT, 282), + + /* add trailing data just after no more data is available */ + CURLOPT(CURLOPT_TRAILERFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 283), + + /* pointer to be passed to HTTP_TRAILER_FUNCTION */ + CURLOPT(CURLOPT_TRAILERDATA, CURLOPTTYPE_OBJECTPOINT, 284), + + /* set this to 1L to allow HTTP/0.9 responses or 0L to disallow */ + CURLOPT(CURLOPT_HTTP09_ALLOWED, CURLOPTTYPE_LONG, 285), + + /* alt-svc control bitmask */ + CURLOPT(CURLOPT_ALTSVC_CTRL, CURLOPTTYPE_LONG, 286), + + /* alt-svc cache file name to possibly read from/write to */ + CURLOPT(CURLOPT_ALTSVC, CURLOPTTYPE_STRINGPOINT, 287), + + /* maximum age of a connection to consider it for reuse (in seconds) */ + CURLOPT(CURLOPT_MAXAGE_CONN, CURLOPTTYPE_LONG, 288), + + /* SASL authorisation identity */ + CURLOPT(CURLOPT_SASL_AUTHZID, CURLOPTTYPE_STRINGPOINT, 289), + + /* allow RCPT TO command to fail for some recipients */ + CURLOPT(CURLOPT_MAIL_RCPT_ALLLOWFAILS, CURLOPTTYPE_LONG, 290), CURLOPT_LASTENTRY /* the last unused */ } CURLoption; @@ -1512,13 +1985,10 @@ typedef enum { option might be handy to force libcurl to use a specific IP version. */ #define CURL_IPRESOLVE_WHATEVER 0 /* default, resolves addresses to all IP versions that your system allows */ -#define CURL_IPRESOLVE_V4 1 /* resolve to ipv4 addresses */ -#define CURL_IPRESOLVE_V6 2 /* resolve to ipv6 addresses */ +#define CURL_IPRESOLVE_V4 1 /* resolve to IPv4 addresses */ +#define CURL_IPRESOLVE_V6 2 /* resolve to IPv6 addresses */ /* three convenient "aliases" that follow the name scheme better */ -#define CURLOPT_WRITEDATA CURLOPT_FILE -#define CURLOPT_READDATA CURLOPT_INFILE -#define CURLOPT_HEADERDATA CURLOPT_WRITEHEADER #define CURLOPT_RTSPHEADER CURLOPT_HTTPHEADER /* These enums are for use with the CURLOPT_HTTP_VERSION option. */ @@ -1528,10 +1998,20 @@ enum { for us! */ CURL_HTTP_VERSION_1_0, /* please use HTTP 1.0 in the request */ CURL_HTTP_VERSION_1_1, /* please use HTTP 1.1 in the request */ - + CURL_HTTP_VERSION_2_0, /* please use HTTP 2 in the request */ + CURL_HTTP_VERSION_2TLS, /* use version 2 for HTTPS, version 1.1 for HTTP */ + CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE, /* please use HTTP 2 without HTTP/1.1 + Upgrade */ + CURL_HTTP_VERSION_3 = 30, /* Makes use of explicit HTTP/3 without fallback. + Use CURLOPT_ALTSVC to enable HTTP/3 upgrade */ CURL_HTTP_VERSION_LAST /* *ILLEGAL* http version */ }; +/* Convenience definition simple because the name of the version is HTTP/2 and + not 2.0. The 2_0 version of the enum name was set while the version was + still planned to be 2.0 and we stick to it for compatibility. */ +#define CURL_HTTP_VERSION_2 CURL_HTTP_VERSION_2_0 + /* * Public API enums for RTSP requests */ @@ -1565,13 +2045,29 @@ enum CURL_NETRC_OPTION { enum { CURL_SSLVERSION_DEFAULT, - CURL_SSLVERSION_TLSv1, + CURL_SSLVERSION_TLSv1, /* TLS 1.x */ CURL_SSLVERSION_SSLv2, CURL_SSLVERSION_SSLv3, + CURL_SSLVERSION_TLSv1_0, + CURL_SSLVERSION_TLSv1_1, + CURL_SSLVERSION_TLSv1_2, + CURL_SSLVERSION_TLSv1_3, CURL_SSLVERSION_LAST /* never use, keep last */ }; +enum { + CURL_SSLVERSION_MAX_NONE = 0, + CURL_SSLVERSION_MAX_DEFAULT = (CURL_SSLVERSION_TLSv1 << 16), + CURL_SSLVERSION_MAX_TLSv1_0 = (CURL_SSLVERSION_TLSv1_0 << 16), + CURL_SSLVERSION_MAX_TLSv1_1 = (CURL_SSLVERSION_TLSv1_1 << 16), + CURL_SSLVERSION_MAX_TLSv1_2 = (CURL_SSLVERSION_TLSv1_2 << 16), + CURL_SSLVERSION_MAX_TLSv1_3 = (CURL_SSLVERSION_TLSv1_3 << 16), + + /* never use, keep last */ + CURL_SSLVERSION_MAX_LAST = (CURL_SSLVERSION_LAST << 16) +}; + enum CURL_TLSAUTH { CURL_TLSAUTH_NONE, CURL_TLSAUTH_SRP, @@ -1579,13 +2075,16 @@ enum CURL_TLSAUTH { }; /* symbols to use with CURLOPT_POSTREDIR. - CURL_REDIR_POST_301 and CURL_REDIR_POST_302 can be bitwise ORed so that - CURL_REDIR_POST_301 | CURL_REDIR_POST_302 == CURL_REDIR_POST_ALL */ + CURL_REDIR_POST_301, CURL_REDIR_POST_302 and CURL_REDIR_POST_303 + can be bitwise ORed so that CURL_REDIR_POST_301 | CURL_REDIR_POST_302 + | CURL_REDIR_POST_303 == CURL_REDIR_POST_ALL */ #define CURL_REDIR_GET_ALL 0 #define CURL_REDIR_POST_301 1 #define CURL_REDIR_POST_302 2 -#define CURL_REDIR_POST_ALL (CURL_REDIR_POST_301|CURL_REDIR_POST_302) +#define CURL_REDIR_POST_303 4 +#define CURL_REDIR_POST_ALL \ + (CURL_REDIR_POST_301|CURL_REDIR_POST_302|CURL_REDIR_POST_303) typedef enum { CURL_TIMECOND_NONE, @@ -1597,56 +2096,168 @@ typedef enum { CURL_TIMECOND_LAST } curl_TimeCond; +/* Special size_t value signaling a zero-terminated string. */ +#define CURL_ZERO_TERMINATED ((size_t) -1) /* curl_strequal() and curl_strnequal() are subject for removal in a future - libcurl, see lib/README.curlx for details */ -CURL_EXTERN int (curl_strequal)(const char *s1, const char *s2); -CURL_EXTERN int (curl_strnequal)(const char *s1, const char *s2, size_t n); + release */ +CURL_EXTERN int curl_strequal(const char *s1, const char *s2); +CURL_EXTERN int curl_strnequal(const char *s1, const char *s2, size_t n); -/* name is uppercase CURLFORM_ */ -#ifdef CFINIT -#undef CFINIT -#endif +/* Mime/form handling support. */ +typedef struct curl_mime_s curl_mime; /* Mime context. */ +typedef struct curl_mimepart_s curl_mimepart; /* Mime part context. */ -#ifdef CURL_ISOCPP -#define CFINIT(name) CURLFORM_ ## name -#else -/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ -#define CFINIT(name) CURLFORM_/**/name -#endif +/* + * NAME curl_mime_init() + * + * DESCRIPTION + * + * Create a mime context and return its handle. The easy parameter is the + * target handle. + */ +CURL_EXTERN curl_mime *curl_mime_init(CURL *easy); + +/* + * NAME curl_mime_free() + * + * DESCRIPTION + * + * release a mime handle and its substructures. + */ +CURL_EXTERN void curl_mime_free(curl_mime *mime); + +/* + * NAME curl_mime_addpart() + * + * DESCRIPTION + * + * Append a new empty part to the given mime context and return a handle to + * the created part. + */ +CURL_EXTERN curl_mimepart *curl_mime_addpart(curl_mime *mime); + +/* + * NAME curl_mime_name() + * + * DESCRIPTION + * + * Set mime/form part name. + */ +CURL_EXTERN CURLcode curl_mime_name(curl_mimepart *part, const char *name); + +/* + * NAME curl_mime_filename() + * + * DESCRIPTION + * + * Set mime part remote file name. + */ +CURL_EXTERN CURLcode curl_mime_filename(curl_mimepart *part, + const char *filename); + +/* + * NAME curl_mime_type() + * + * DESCRIPTION + * + * Set mime part type. + */ +CURL_EXTERN CURLcode curl_mime_type(curl_mimepart *part, const char *mimetype); + +/* + * NAME curl_mime_encoder() + * + * DESCRIPTION + * + * Set mime data transfer encoder. + */ +CURL_EXTERN CURLcode curl_mime_encoder(curl_mimepart *part, + const char *encoding); + +/* + * NAME curl_mime_data() + * + * DESCRIPTION + * + * Set mime part data source from memory data, + */ +CURL_EXTERN CURLcode curl_mime_data(curl_mimepart *part, + const char *data, size_t datasize); + +/* + * NAME curl_mime_filedata() + * + * DESCRIPTION + * + * Set mime part data source from named file. + */ +CURL_EXTERN CURLcode curl_mime_filedata(curl_mimepart *part, + const char *filename); + +/* + * NAME curl_mime_data_cb() + * + * DESCRIPTION + * + * Set mime part data source from callback function. + */ +CURL_EXTERN CURLcode curl_mime_data_cb(curl_mimepart *part, + curl_off_t datasize, + curl_read_callback readfunc, + curl_seek_callback seekfunc, + curl_free_callback freefunc, + void *arg); + +/* + * NAME curl_mime_subparts() + * + * DESCRIPTION + * + * Set mime part data source from subparts. + */ +CURL_EXTERN CURLcode curl_mime_subparts(curl_mimepart *part, + curl_mime *subparts); +/* + * NAME curl_mime_headers() + * + * DESCRIPTION + * + * Set mime part headers. + */ +CURL_EXTERN CURLcode curl_mime_headers(curl_mimepart *part, + struct curl_slist *headers, + int take_ownership); typedef enum { - CFINIT(NOTHING), /********* the first one is unused ************/ + CURLFORM_NOTHING, /********* the first one is unused ************/ + CURLFORM_COPYNAME, + CURLFORM_PTRNAME, + CURLFORM_NAMELENGTH, + CURLFORM_COPYCONTENTS, + CURLFORM_PTRCONTENTS, + CURLFORM_CONTENTSLENGTH, + CURLFORM_FILECONTENT, + CURLFORM_ARRAY, + CURLFORM_OBSOLETE, + CURLFORM_FILE, - /* */ - CFINIT(COPYNAME), - CFINIT(PTRNAME), - CFINIT(NAMELENGTH), - CFINIT(COPYCONTENTS), - CFINIT(PTRCONTENTS), - CFINIT(CONTENTSLENGTH), - CFINIT(FILECONTENT), - CFINIT(ARRAY), - CFINIT(OBSOLETE), - CFINIT(FILE), + CURLFORM_BUFFER, + CURLFORM_BUFFERPTR, + CURLFORM_BUFFERLENGTH, - CFINIT(BUFFER), - CFINIT(BUFFERPTR), - CFINIT(BUFFERLENGTH), + CURLFORM_CONTENTTYPE, + CURLFORM_CONTENTHEADER, + CURLFORM_FILENAME, + CURLFORM_END, + CURLFORM_OBSOLETE2, - CFINIT(CONTENTTYPE), - CFINIT(CONTENTHEADER), - CFINIT(FILENAME), - CFINIT(END), - CFINIT(OBSOLETE2), - - CFINIT(STREAM), + CURLFORM_STREAM, + CURLFORM_CONTENTLEN, /* added in 7.46.0, provide a curl_off_t length */ CURLFORM_LASTENTRY /* the last unused */ } CURLformoption; -#undef CFINIT /* done */ - /* structure to be used as parameter for CURLFORM_ARRAY */ struct curl_forms { CURLformoption option; @@ -1704,7 +2315,8 @@ CURL_EXTERN CURLFORMcode curl_formadd(struct curl_httppost **httppost, * Should return the buffer length passed to it as the argument "len" on * success. */ -typedef size_t (*curl_formget_callback)(void *arg, const char *buf, size_t len); +typedef size_t (*curl_formget_callback)(void *arg, const char *buf, + size_t len); /* * NAME curl_formget() @@ -1842,6 +2454,47 @@ struct curl_slist { struct curl_slist *next; }; +/* + * NAME curl_global_sslset() + * + * DESCRIPTION + * + * When built with multiple SSL backends, curl_global_sslset() allows to + * choose one. This function can only be called once, and it must be called + * *before* curl_global_init(). + * + * The backend can be identified by the id (e.g. CURLSSLBACKEND_OPENSSL). The + * backend can also be specified via the name parameter (passing -1 as id). + * If both id and name are specified, the name will be ignored. If neither id + * nor name are specified, the function will fail with + * CURLSSLSET_UNKNOWN_BACKEND and set the "avail" pointer to the + * NULL-terminated list of available backends. + * + * Upon success, the function returns CURLSSLSET_OK. + * + * If the specified SSL backend is not available, the function returns + * CURLSSLSET_UNKNOWN_BACKEND and sets the "avail" pointer to a NULL-terminated + * list of available SSL backends. + * + * The SSL backend can be set only once. If it has already been set, a + * subsequent attempt to change it will result in a CURLSSLSET_TOO_LATE. + */ + +typedef struct { + curl_sslbackend id; + const char *name; +} curl_ssl_backend; + +typedef enum { + CURLSSLSET_OK = 0, + CURLSSLSET_UNKNOWN_BACKEND, + CURLSSLSET_TOO_LATE, + CURLSSLSET_NO_BACKENDS /* libcurl was built without any SSL support */ +} CURLsslset; + +CURL_EXTERN CURLsslset curl_global_sslset(curl_sslbackend id, const char *name, + const curl_ssl_backend ***avail); + /* * NAME curl_slist_append() * @@ -1873,8 +2526,8 @@ CURL_EXTERN void curl_slist_free_all(struct curl_slist *); */ CURL_EXTERN time_t curl_getdate(const char *p, const time_t *unused); -/* info about the certificate chain, only for OpenSSL builds. Asked - for with CURLOPT_CERTINFO / CURLINFO_CERTINFO */ +/* info about the certificate chain, only for OpenSSL, GnuTLS, Schannel, NSS + and GSKit builds. Asked for with CURLOPT_CERTINFO / CURLINFO_CERTINFO */ struct curl_certinfo { int num_of_certs; /* number of certificates with information */ struct curl_slist **certinfo; /* for each index in this array, there's a @@ -1882,10 +2535,21 @@ struct curl_certinfo { format "name: value" */ }; +/* Information about the SSL library used and the respective internal SSL + handle, which can be used to obtain further information regarding the + connection. Asked for with CURLINFO_TLS_SSL_PTR or CURLINFO_TLS_SESSION. */ +struct curl_tlssessioninfo { + curl_sslbackend backend; + void *internals; +}; + #define CURLINFO_STRING 0x100000 #define CURLINFO_LONG 0x200000 #define CURLINFO_DOUBLE 0x300000 #define CURLINFO_SLIST 0x400000 +#define CURLINFO_PTR 0x400000 /* same as SLIST */ +#define CURLINFO_SOCKET 0x500000 +#define CURLINFO_OFF_T 0x600000 #define CURLINFO_MASK 0x0fffff #define CURLINFO_TYPEMASK 0xf00000 @@ -1898,15 +2562,22 @@ typedef enum { CURLINFO_CONNECT_TIME = CURLINFO_DOUBLE + 5, CURLINFO_PRETRANSFER_TIME = CURLINFO_DOUBLE + 6, CURLINFO_SIZE_UPLOAD = CURLINFO_DOUBLE + 7, + CURLINFO_SIZE_UPLOAD_T = CURLINFO_OFF_T + 7, CURLINFO_SIZE_DOWNLOAD = CURLINFO_DOUBLE + 8, + CURLINFO_SIZE_DOWNLOAD_T = CURLINFO_OFF_T + 8, CURLINFO_SPEED_DOWNLOAD = CURLINFO_DOUBLE + 9, + CURLINFO_SPEED_DOWNLOAD_T = CURLINFO_OFF_T + 9, CURLINFO_SPEED_UPLOAD = CURLINFO_DOUBLE + 10, + CURLINFO_SPEED_UPLOAD_T = CURLINFO_OFF_T + 10, CURLINFO_HEADER_SIZE = CURLINFO_LONG + 11, CURLINFO_REQUEST_SIZE = CURLINFO_LONG + 12, CURLINFO_SSL_VERIFYRESULT = CURLINFO_LONG + 13, CURLINFO_FILETIME = CURLINFO_LONG + 14, + CURLINFO_FILETIME_T = CURLINFO_OFF_T + 14, CURLINFO_CONTENT_LENGTH_DOWNLOAD = CURLINFO_DOUBLE + 15, + CURLINFO_CONTENT_LENGTH_DOWNLOAD_T = CURLINFO_OFF_T + 15, CURLINFO_CONTENT_LENGTH_UPLOAD = CURLINFO_DOUBLE + 16, + CURLINFO_CONTENT_LENGTH_UPLOAD_T = CURLINFO_OFF_T + 16, CURLINFO_STARTTRANSFER_TIME = CURLINFO_DOUBLE + 17, CURLINFO_CONTENT_TYPE = CURLINFO_STRING + 18, CURLINFO_REDIRECT_TIME = CURLINFO_DOUBLE + 19, @@ -1924,7 +2595,7 @@ typedef enum { CURLINFO_REDIRECT_URL = CURLINFO_STRING + 31, CURLINFO_PRIMARY_IP = CURLINFO_STRING + 32, CURLINFO_APPCONNECT_TIME = CURLINFO_DOUBLE + 33, - CURLINFO_CERTINFO = CURLINFO_SLIST + 34, + CURLINFO_CERTINFO = CURLINFO_PTR + 34, CURLINFO_CONDITION_UNMET = CURLINFO_LONG + 35, CURLINFO_RTSP_SESSION_ID = CURLINFO_STRING + 36, CURLINFO_RTSP_CLIENT_CSEQ = CURLINFO_LONG + 37, @@ -1933,9 +2604,27 @@ typedef enum { CURLINFO_PRIMARY_PORT = CURLINFO_LONG + 40, CURLINFO_LOCAL_IP = CURLINFO_STRING + 41, CURLINFO_LOCAL_PORT = CURLINFO_LONG + 42, + CURLINFO_TLS_SESSION = CURLINFO_PTR + 43, + CURLINFO_ACTIVESOCKET = CURLINFO_SOCKET + 44, + CURLINFO_TLS_SSL_PTR = CURLINFO_PTR + 45, + CURLINFO_HTTP_VERSION = CURLINFO_LONG + 46, + CURLINFO_PROXY_SSL_VERIFYRESULT = CURLINFO_LONG + 47, + CURLINFO_PROTOCOL = CURLINFO_LONG + 48, + CURLINFO_SCHEME = CURLINFO_STRING + 49, /* Fill in new entries below here! */ - CURLINFO_LASTONE = 42 + /* Preferably these would be defined conditionally based on the + sizeof curl_off_t being 64-bits */ + CURLINFO_TOTAL_TIME_T = CURLINFO_OFF_T + 50, + CURLINFO_NAMELOOKUP_TIME_T = CURLINFO_OFF_T + 51, + CURLINFO_CONNECT_TIME_T = CURLINFO_OFF_T + 52, + CURLINFO_PRETRANSFER_TIME_T = CURLINFO_OFF_T + 53, + CURLINFO_STARTTRANSFER_TIME_T = CURLINFO_OFF_T + 54, + CURLINFO_REDIRECT_TIME_T = CURLINFO_OFF_T + 55, + CURLINFO_APPCONNECT_TIME_T = CURLINFO_OFF_T + 56, + CURLINFO_RETRY_AFTER = CURLINFO_OFF_T + 57, + + CURLINFO_LASTONE = 57 } CURLINFO; /* CURLINFO_RESPONSE_CODE is the new name for the option previously known as @@ -1954,11 +2643,12 @@ typedef enum { CURLCLOSEPOLICY_LAST /* last, never use this */ } curl_closepolicy; -#define CURL_GLOBAL_SSL (1<<0) +#define CURL_GLOBAL_SSL (1<<0) /* no purpose since since 7.57.0 */ #define CURL_GLOBAL_WIN32 (1<<1) #define CURL_GLOBAL_ALL (CURL_GLOBAL_SSL|CURL_GLOBAL_WIN32) #define CURL_GLOBAL_NOTHING 0 #define CURL_GLOBAL_DEFAULT CURL_GLOBAL_ALL +#define CURL_GLOBAL_ACK_EINTR (1<<2) /***************************************************************************** @@ -1977,6 +2667,7 @@ typedef enum { CURL_LOCK_DATA_DNS, CURL_LOCK_DATA_SSL_SESSION, CURL_LOCK_DATA_CONNECT, + CURL_LOCK_DATA_PSL, CURL_LOCK_DATA_LAST } curl_lock_data; @@ -1996,15 +2687,15 @@ typedef void (*curl_unlock_function)(CURL *handle, curl_lock_data data, void *userptr); -typedef void CURLSH; typedef enum { CURLSHE_OK, /* all is fine */ CURLSHE_BAD_OPTION, /* 1 */ CURLSHE_IN_USE, /* 2 */ CURLSHE_INVALID, /* 3 */ - CURLSHE_NOMEM, /* out of memory */ - CURLSHE_LAST /* never use */ + CURLSHE_NOMEM, /* 4 out of memory */ + CURLSHE_NOT_BUILT_IN, /* 5 feature not present in lib */ + CURLSHE_LAST /* never use */ } CURLSHcode; typedef enum { @@ -2031,6 +2722,8 @@ typedef enum { CURLVERSION_SECOND, CURLVERSION_THIRD, CURLVERSION_FOURTH, + CURLVERSION_FIFTH, + CURLVERSION_SIXTH, CURLVERSION_LAST /* never actually use this */ } CURLversion; @@ -2039,7 +2732,7 @@ typedef enum { meant to be a built-in version number for what kind of struct the caller expects. If the struct ever changes, we redefine the NOW to another enum from above. */ -#define CURLVERSION_NOW CURLVERSION_FOURTH +#define CURLVERSION_NOW CURLVERSION_SIXTH typedef struct { CURLversion age; /* age of the returned struct */ @@ -2067,25 +2760,54 @@ typedef struct { const char *libssh_version; /* human readable string */ + /* These fields were added in CURLVERSION_FIFTH */ + unsigned int brotli_ver_num; /* Numeric Brotli version + (MAJOR << 24) | (MINOR << 12) | PATCH */ + const char *brotli_version; /* human readable string. */ + + /* These fields were added in CURLVERSION_SIXTH */ + unsigned int nghttp2_ver_num; /* Numeric nghttp2 version + (MAJOR << 16) | (MINOR << 8) | PATCH */ + const char *nghttp2_version; /* human readable string. */ + const char *quic_version; /* human readable quic (+ HTTP/3) library + + version or NULL */ } curl_version_info_data; -#define CURL_VERSION_IPV6 (1<<0) /* IPv6-enabled */ -#define CURL_VERSION_KERBEROS4 (1<<1) /* kerberos auth is supported */ -#define CURL_VERSION_SSL (1<<2) /* SSL options are present */ -#define CURL_VERSION_LIBZ (1<<3) /* libz features are present */ -#define CURL_VERSION_NTLM (1<<4) /* NTLM auth is supported */ -#define CURL_VERSION_GSSNEGOTIATE (1<<5) /* Negotiate auth support */ -#define CURL_VERSION_DEBUG (1<<6) /* built with debug capabilities */ -#define CURL_VERSION_ASYNCHDNS (1<<7) /* asynchronous dns resolves */ -#define CURL_VERSION_SPNEGO (1<<8) /* SPNEGO auth */ -#define CURL_VERSION_LARGEFILE (1<<9) /* supports files bigger than 2GB */ -#define CURL_VERSION_IDN (1<<10) /* International Domain Names support */ -#define CURL_VERSION_SSPI (1<<11) /* SSPI is supported */ -#define CURL_VERSION_CONV (1<<12) /* character conversions supported */ -#define CURL_VERSION_CURLDEBUG (1<<13) /* debug memory tracking supported */ -#define CURL_VERSION_TLSAUTH_SRP (1<<14) /* TLS-SRP auth is supported */ +#define CURL_VERSION_IPV6 (1<<0) /* IPv6-enabled */ +#define CURL_VERSION_KERBEROS4 (1<<1) /* Kerberos V4 auth is supported + (deprecated) */ +#define CURL_VERSION_SSL (1<<2) /* SSL options are present */ +#define CURL_VERSION_LIBZ (1<<3) /* libz features are present */ +#define CURL_VERSION_NTLM (1<<4) /* NTLM auth is supported */ +#define CURL_VERSION_GSSNEGOTIATE (1<<5) /* Negotiate auth is supported + (deprecated) */ +#define CURL_VERSION_DEBUG (1<<6) /* Built with debug capabilities */ +#define CURL_VERSION_ASYNCHDNS (1<<7) /* Asynchronous DNS resolves */ +#define CURL_VERSION_SPNEGO (1<<8) /* SPNEGO auth is supported */ +#define CURL_VERSION_LARGEFILE (1<<9) /* Supports files larger than 2GB */ +#define CURL_VERSION_IDN (1<<10) /* Internationized Domain Names are + supported */ +#define CURL_VERSION_SSPI (1<<11) /* Built against Windows SSPI */ +#define CURL_VERSION_CONV (1<<12) /* Character conversions supported */ +#define CURL_VERSION_CURLDEBUG (1<<13) /* Debug memory tracking supported */ +#define CURL_VERSION_TLSAUTH_SRP (1<<14) /* TLS-SRP auth is supported */ +#define CURL_VERSION_NTLM_WB (1<<15) /* NTLM delegation to winbind helper + is supported */ +#define CURL_VERSION_HTTP2 (1<<16) /* HTTP2 support built-in */ +#define CURL_VERSION_GSSAPI (1<<17) /* Built against a GSS-API library */ +#define CURL_VERSION_KERBEROS5 (1<<18) /* Kerberos V5 auth is supported */ +#define CURL_VERSION_UNIX_SOCKETS (1<<19) /* Unix domain sockets support */ +#define CURL_VERSION_PSL (1<<20) /* Mozilla's Public Suffix List, used + for cookie domain verification */ +#define CURL_VERSION_HTTPS_PROXY (1<<21) /* HTTPS-proxy support built-in */ +#define CURL_VERSION_MULTI_SSL (1<<22) /* Multiple SSL backends available */ +#define CURL_VERSION_BROTLI (1<<23) /* Brotli features are present. */ +#define CURL_VERSION_ALTSVC (1<<24) /* Alt-Svc handling built-in */ +#define CURL_VERSION_HTTP3 (1<<25) /* HTTP3 support built-in */ -/* +#define CURL_VERSION_ESNI (1<<26) /* ESNI support */ + + /* * NAME curl_version_info() * * DESCRIPTION @@ -2145,6 +2867,7 @@ CURL_EXTERN CURLcode curl_easy_pause(CURL *handle, int bitmask); stuff before they can be included! */ #include "easy.h" /* nothing in curl is fun without the easy stuff */ #include "multi.h" +#include "urlapi.h" /* the typechecker doesn't work in C++ (yet) */ #if defined(__GNUC__) && defined(__GNUC_MINOR__) && \ @@ -2163,4 +2886,4 @@ CURL_EXTERN CURLcode curl_easy_pause(CURL *handle, int bitmask); #endif /* __STDC__ >= 1 */ #endif /* gcc >= 4.3 && !__cplusplus */ -#endif /* __CURL_CURL_H */ +#endif /* CURLINC_CURL_H */ diff --git a/libs/curl/include/curl/curlver.h b/libs/curl/include/curl/curlver.h index 4db21857d..5264f1986 100644 --- a/libs/curl/include/curl/curlver.h +++ b/libs/curl/include/curl/curlver.h @@ -1,5 +1,5 @@ -#ifndef __CURL_CURLVER_H -#define __CURL_CURLVER_H +#ifndef CURLINC_CURLVER_H +#define CURLINC_CURLVER_H /*************************************************************************** * _ _ ____ _ * Project ___| | | | _ \| | @@ -7,11 +7,11 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms - * are also available at http://curl.haxx.se/docs/copyright.html. + * are also available at https://curl.haxx.se/docs/copyright.html. * * You may opt to use, copy, modify, merge, publish, distribute and/or sell * copies of the Software, and permit persons to whom the Software is @@ -26,17 +26,17 @@ a script at release-time. This was made its own header file in 7.11.2 */ /* This is the global package copyright */ -#define LIBCURL_COPYRIGHT "1996 - 2011 Daniel Stenberg, ." +#define LIBCURL_COPYRIGHT "1996 - 2020 Daniel Stenberg, ." /* This is the version number of the libcurl package from which this header file origins: */ -#define LIBCURL_VERSION "7.21.6" +#define LIBCURL_VERSION "7.69.0" /* The numeric version number is also available "in parts" by using these defines: */ #define LIBCURL_VERSION_MAJOR 7 -#define LIBCURL_VERSION_MINOR 21 -#define LIBCURL_VERSION_PATCH 6 +#define LIBCURL_VERSION_MINOR 69 +#define LIBCURL_VERSION_PATCH 0 /* This is the numeric version of the libcurl version number, meant for easier parsing and comparions by programs. The LIBCURL_VERSION_NUM define will @@ -52,18 +52,26 @@ This 6-digit (24 bits) hexadecimal number does not show pre-release number, and it is always a greater number in a more recent release. It makes comparisons with greater than and less than work. + + Note: This define is the full hex number and _does not_ use the + CURL_VERSION_BITS() macro since curl's own configure script greps for it + and needs it to contain the full number. */ -#define LIBCURL_VERSION_NUM 0x071506 +#define LIBCURL_VERSION_NUM 0x074500 /* * This is the date and time when the full source package was created. The * timestamp is not stored in git, as the timestamp is properly set in the * tarballs by the maketgz script. * - * The format of the date should follow this template: + * The format of the date follows this template: * - * "Mon Feb 12 11:35:33 UTC 2007" + * "2007-11-23" */ -#define LIBCURL_TIMESTAMP "Fri Apr 22 17:18:50 UTC 2011" +#define LIBCURL_TIMESTAMP "2020-03-04" -#endif /* __CURL_CURLVER_H */ +#define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|(z)) +#define CURL_AT_LEAST_VERSION(x,y,z) \ + (LIBCURL_VERSION_NUM >= CURL_VERSION_BITS(x, y, z)) + +#endif /* CURLINC_CURLVER_H */ diff --git a/libs/curl/include/curl/easy.h b/libs/curl/include/curl/easy.h index c1e3e7609..592f5d3c1 100644 --- a/libs/curl/include/curl/easy.h +++ b/libs/curl/include/curl/easy.h @@ -1,5 +1,5 @@ -#ifndef __CURL_EASY_H -#define __CURL_EASY_H +#ifndef CURLINC_EASY_H +#define CURLINC_EASY_H /*************************************************************************** * _ _ ____ _ * Project ___| | | | _ \| | @@ -7,11 +7,11 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2008, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms - * are also available at http://curl.haxx.se/docs/copyright.html. + * are also available at https://curl.haxx.se/docs/copyright.html. * * You may opt to use, copy, modify, merge, publish, distribute and/or sell * copies of the Software, and permit persons to whom the Software is @@ -58,7 +58,7 @@ CURL_EXTERN CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...); * curl_easy_duphandle() for each new thread to avoid a series of identical * curl_easy_setopt() invokes in every thread. */ -CURL_EXTERN CURL* curl_easy_duphandle(CURL *curl); +CURL_EXTERN CURL *curl_easy_duphandle(CURL *curl); /* * NAME curl_easy_reset() @@ -95,6 +95,16 @@ CURL_EXTERN CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen, CURL_EXTERN CURLcode curl_easy_send(CURL *curl, const void *buffer, size_t buflen, size_t *n); + +/* + * NAME curl_easy_upkeep() + * + * DESCRIPTION + * + * Performs connection upkeep for the given session handle. + */ +CURL_EXTERN CURLcode curl_easy_upkeep(CURL *curl); + #ifdef __cplusplus } #endif diff --git a/libs/curl/include/curl/mprintf.h b/libs/curl/include/curl/mprintf.h index de7dd2f3c..f615ed7d6 100644 --- a/libs/curl/include/curl/mprintf.h +++ b/libs/curl/include/curl/mprintf.h @@ -1,5 +1,5 @@ -#ifndef __CURL_MPRINTF_H -#define __CURL_MPRINTF_H +#ifndef CURLINC_MPRINTF_H +#define CURLINC_MPRINTF_H /*************************************************************************** * _ _ ____ _ * Project ___| | | | _ \| | @@ -7,11 +7,11 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2006, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms - * are also available at http://curl.haxx.se/docs/copyright.html. + * are also available at https://curl.haxx.se/docs/copyright.html. * * You may opt to use, copy, modify, merge, publish, distribute and/or sell * copies of the Software, and permit persons to whom the Software is @@ -24,8 +24,7 @@ #include #include /* needed for FILE */ - -#include "curl.h" +#include "curl.h" /* for CURL_EXTERN */ #ifdef __cplusplus extern "C" { @@ -44,38 +43,8 @@ CURL_EXTERN int curl_mvsnprintf(char *buffer, size_t maxlength, CURL_EXTERN char *curl_maprintf(const char *format, ...); CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args); -#ifdef _MPRINTF_REPLACE -# undef printf -# undef fprintf -# undef sprintf -# undef vsprintf -# undef snprintf -# undef vprintf -# undef vfprintf -# undef vsnprintf -# undef aprintf -# undef vaprintf -# define printf curl_mprintf -# define fprintf curl_mfprintf -#ifdef CURLDEBUG -/* When built with CURLDEBUG we define away the sprintf() functions since we - don't want internal code to be using them */ -# define sprintf sprintf_was_used -# define vsprintf vsprintf_was_used -#else -# define sprintf curl_msprintf -# define vsprintf curl_mvsprintf -#endif -# define snprintf curl_msnprintf -# define vprintf curl_mvprintf -# define vfprintf curl_mvfprintf -# define vsnprintf curl_mvsnprintf -# define aprintf curl_maprintf -# define vaprintf curl_mvaprintf -#endif - #ifdef __cplusplus } #endif -#endif /* __CURL_MPRINTF_H */ +#endif /* CURLINC_MPRINTF_H */ diff --git a/libs/curl/include/curl/multi.h b/libs/curl/include/curl/multi.h index f96566669..bda9bb7b8 100644 --- a/libs/curl/include/curl/multi.h +++ b/libs/curl/include/curl/multi.h @@ -1,5 +1,5 @@ -#ifndef __CURL_MULTI_H -#define __CURL_MULTI_H +#ifndef CURLINC_MULTI_H +#define CURLINC_MULTI_H /*************************************************************************** * _ _ ____ _ * Project ___| | | | _ \| | @@ -7,11 +7,11 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2007, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms - * are also available at http://curl.haxx.se/docs/copyright.html. + * are also available at https://curl.haxx.se/docs/copyright.html. * * You may opt to use, copy, modify, merge, publish, distribute and/or sell * copies of the Software, and permit persons to whom the Software is @@ -52,7 +52,11 @@ extern "C" { #endif +#if defined(BUILDING_LIBCURL) || defined(CURL_STRICTER) +typedef struct Curl_multi CURLM; +#else typedef void CURLM; +#endif typedef enum { CURLM_CALL_MULTI_PERFORM = -1, /* please call curl_multi_perform() or @@ -64,6 +68,12 @@ typedef enum { CURLM_INTERNAL_ERROR, /* this is a libcurl bug */ CURLM_BAD_SOCKET, /* the passed in socket argument did not match */ CURLM_UNKNOWN_OPTION, /* curl_multi_setopt() with unsupported option */ + CURLM_ADDED_ALREADY, /* an easy handle already added to a multi handle was + attempted to get added - again */ + CURLM_RECURSIVE_API_CALL, /* an api function was called from inside a + callback */ + CURLM_WAKEUP_FAILURE, /* wakeup is unavailable or failed */ + CURLM_BAD_FUNCTION_ARGUMENT, /* function called with a bad parameter */ CURLM_LAST } CURLMcode; @@ -72,6 +82,11 @@ typedef enum { curl_multi_perform() and CURLM_CALL_MULTI_PERFORM */ #define CURLM_CALL_MULTI_SOCKET CURLM_CALL_MULTI_PERFORM +/* bitmask bits for CURLMOPT_PIPELINING */ +#define CURLPIPE_NOTHING 0L +#define CURLPIPE_HTTP1 1L +#define CURLPIPE_MULTIPLEX 2L + typedef enum { CURLMSG_NONE, /* first, not used */ CURLMSG_DONE, /* This easy handle has completed. 'result' contains @@ -89,6 +104,19 @@ struct CURLMsg { }; typedef struct CURLMsg CURLMsg; +/* Based on poll(2) structure and values. + * We don't use pollfd and POLL* constants explicitly + * to cover platforms without poll(). */ +#define CURL_WAIT_POLLIN 0x0001 +#define CURL_WAIT_POLLPRI 0x0002 +#define CURL_WAIT_POLLOUT 0x0004 + +struct curl_waitfd { + curl_socket_t fd; + short events; + short revents; /* not supported yet */ +}; + /* * Name: curl_multi_init() * @@ -133,6 +161,43 @@ CURL_EXTERN CURLMcode curl_multi_fdset(CURLM *multi_handle, fd_set *exc_fd_set, int *max_fd); +/* + * Name: curl_multi_wait() + * + * Desc: Poll on all fds within a CURLM set as well as any + * additional fds passed to the function. + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_wait(CURLM *multi_handle, + struct curl_waitfd extra_fds[], + unsigned int extra_nfds, + int timeout_ms, + int *ret); + +/* + * Name: curl_multi_poll() + * + * Desc: Poll on all fds within a CURLM set as well as any + * additional fds passed to the function. + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_poll(CURLM *multi_handle, + struct curl_waitfd extra_fds[], + unsigned int extra_nfds, + int timeout_ms, + int *ret); + +/* + * Name: curl_multi_wakeup() + * + * Desc: wakes up a sleeping curl_multi_poll call. + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_wakeup(CURLM *multi_handle); + /* * Name: curl_multi_perform() * @@ -146,8 +211,8 @@ CURL_EXTERN CURLMcode curl_multi_fdset(CURLM *multi_handle, * * Returns: CURLMcode type, general multi error code. *NOTE* that this only * returns errors etc regarding the whole multi stack. There might - * still have occurred problems on invidual transfers even when this - * returns OK. + * still have occurred problems on individual transfers even when + * this returns OK. */ CURL_EXTERN CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles); @@ -180,7 +245,7 @@ CURL_EXTERN CURLMcode curl_multi_cleanup(CURLM *multi_handle); * curl_multi_cleanup(). * * The 'CURLMsg' struct is meant to be very simple and only contain - * very basic informations. If more involved information is wanted, + * very basic information. If more involved information is wanted, * we will provide the particular "transfer handle" in that struct * and that should/could/would be used in subsequent * curl_easy_getinfo() calls (or similar). The point being that we @@ -279,37 +344,58 @@ CURL_EXTERN CURLMcode curl_multi_socket_all(CURLM *multi_handle, CURL_EXTERN CURLMcode curl_multi_timeout(CURLM *multi_handle, long *milliseconds); -#undef CINIT /* re-using the same name as in curl.h */ - -#ifdef CURL_ISOCPP -#define CINIT(name,type,num) CURLMOPT_ ## name = CURLOPTTYPE_ ## type + num -#else -/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ -#define LONG CURLOPTTYPE_LONG -#define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT -#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT -#define OFF_T CURLOPTTYPE_OFF_T -#define CINIT(name,type,number) CURLMOPT_/**/name = type + number -#endif - typedef enum { /* This is the socket callback function pointer */ - CINIT(SOCKETFUNCTION, FUNCTIONPOINT, 1), + CURLOPT(CURLMOPT_SOCKETFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 1), /* This is the argument passed to the socket callback */ - CINIT(SOCKETDATA, OBJECTPOINT, 2), + CURLOPT(CURLMOPT_SOCKETDATA, CURLOPTTYPE_OBJECTPOINT, 2), /* set to 1 to enable pipelining for this multi handle */ - CINIT(PIPELINING, LONG, 3), + CURLOPT(CURLMOPT_PIPELINING, CURLOPTTYPE_LONG, 3), /* This is the timer callback function pointer */ - CINIT(TIMERFUNCTION, FUNCTIONPOINT, 4), + CURLOPT(CURLMOPT_TIMERFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 4), /* This is the argument passed to the timer callback */ - CINIT(TIMERDATA, OBJECTPOINT, 5), + CURLOPT(CURLMOPT_TIMERDATA, CURLOPTTYPE_OBJECTPOINT, 5), /* maximum number of entries in the connection cache */ - CINIT(MAXCONNECTS, LONG, 6), + CURLOPT(CURLMOPT_MAXCONNECTS, CURLOPTTYPE_LONG, 6), + + /* maximum number of (pipelining) connections to one host */ + CURLOPT(CURLMOPT_MAX_HOST_CONNECTIONS, CURLOPTTYPE_LONG, 7), + + /* maximum number of requests in a pipeline */ + CURLOPT(CURLMOPT_MAX_PIPELINE_LENGTH, CURLOPTTYPE_LONG, 8), + + /* a connection with a content-length longer than this + will not be considered for pipelining */ + CURLOPT(CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE, CURLOPTTYPE_OFF_T, 9), + + /* a connection with a chunk length longer than this + will not be considered for pipelining */ + CURLOPT(CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE, CURLOPTTYPE_OFF_T, 10), + + /* a list of site names(+port) that are blacklisted from + pipelining */ + CURLOPT(CURLMOPT_PIPELINING_SITE_BL, CURLOPTTYPE_OBJECTPOINT, 11), + + /* a list of server types that are blacklisted from + pipelining */ + CURLOPT(CURLMOPT_PIPELINING_SERVER_BL, CURLOPTTYPE_OBJECTPOINT, 12), + + /* maximum number of open connections in total */ + CURLOPT(CURLMOPT_MAX_TOTAL_CONNECTIONS, CURLOPTTYPE_LONG, 13), + + /* This is the server push callback function pointer */ + CURLOPT(CURLMOPT_PUSHFUNCTION, CURLOPTTYPE_FUNCTIONPOINT, 14), + + /* This is the argument passed to the server push callback */ + CURLOPT(CURLMOPT_PUSHDATA, CURLOPTTYPE_OBJECTPOINT, 15), + + /* maximum number of concurrent streams to support on a connection */ + CURLOPT(CURLMOPT_MAX_CONCURRENT_STREAMS, CURLOPTTYPE_LONG, 16), CURLMOPT_LASTENTRY /* the last unused */ } CURLMoption; @@ -338,6 +424,31 @@ CURL_EXTERN CURLMcode curl_multi_setopt(CURLM *multi_handle, CURL_EXTERN CURLMcode curl_multi_assign(CURLM *multi_handle, curl_socket_t sockfd, void *sockp); + +/* + * Name: curl_push_callback + * + * Desc: This callback gets called when a new stream is being pushed by the + * server. It approves or denies the new stream. + * + * Returns: CURL_PUSH_OK or CURL_PUSH_DENY. + */ +#define CURL_PUSH_OK 0 +#define CURL_PUSH_DENY 1 + +struct curl_pushheaders; /* forward declaration only */ + +CURL_EXTERN char *curl_pushheader_bynum(struct curl_pushheaders *h, + size_t num); +CURL_EXTERN char *curl_pushheader_byname(struct curl_pushheaders *h, + const char *name); + +typedef int (*curl_push_callback)(CURL *parent, + CURL *easy, + size_t num_headers, + struct curl_pushheaders *headers, + void *userp); + #ifdef __cplusplus } /* end of extern "C" */ #endif diff --git a/libs/curl/include/curl/stdcheaders.h b/libs/curl/include/curl/stdcheaders.h index ad82ef633..a6bdc1a25 100644 --- a/libs/curl/include/curl/stdcheaders.h +++ b/libs/curl/include/curl/stdcheaders.h @@ -1,5 +1,5 @@ -#ifndef __STDC_HEADERS_H -#define __STDC_HEADERS_H +#ifndef CURLINC_STDCHEADERS_H +#define CURLINC_STDCHEADERS_H /*************************************************************************** * _ _ ____ _ * Project ___| | | | _ \| | @@ -7,11 +7,11 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2010, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms - * are also available at http://curl.haxx.se/docs/copyright.html. + * are also available at https://curl.haxx.se/docs/copyright.html. * * You may opt to use, copy, modify, merge, publish, distribute and/or sell * copies of the Software, and permit persons to whom the Software is @@ -24,10 +24,10 @@ #include -size_t fread (void *, size_t, size_t, FILE *); -size_t fwrite (const void *, size_t, size_t, FILE *); +size_t fread(void *, size_t, size_t, FILE *); +size_t fwrite(const void *, size_t, size_t, FILE *); int strcasecmp(const char *, const char *); int strncasecmp(const char *, const char *, size_t); -#endif /* __STDC_HEADERS_H */ +#endif /* CURLINC_STDCHEADERS_H */ diff --git a/libs/curl/include/curl/system.h b/libs/curl/include/curl/system.h new file mode 100644 index 000000000..867af6141 --- /dev/null +++ b/libs/curl/include/curl/system.h @@ -0,0 +1,504 @@ +#ifndef CURLINC_SYSTEM_H +#define CURLINC_SYSTEM_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* + * Try to keep one section per platform, compiler and architecture, otherwise, + * if an existing section is reused for a different one and later on the + * original is adjusted, probably the piggybacking one can be adversely + * changed. + * + * In order to differentiate between platforms/compilers/architectures use + * only compiler built in predefined preprocessor symbols. + * + * curl_off_t + * ---------- + * + * For any given platform/compiler curl_off_t must be typedef'ed to a 64-bit + * wide signed integral data type. The width of this data type must remain + * constant and independent of any possible large file support settings. + * + * As an exception to the above, curl_off_t shall be typedef'ed to a 32-bit + * wide signed integral data type if there is no 64-bit type. + * + * As a general rule, curl_off_t shall not be mapped to off_t. This rule shall + * only be violated if off_t is the only 64-bit data type available and the + * size of off_t is independent of large file support settings. Keep your + * build on the safe side avoiding an off_t gating. If you have a 64-bit + * off_t then take for sure that another 64-bit data type exists, dig deeper + * and you will find it. + * + */ + +#if defined(__DJGPP__) || defined(__GO32__) +# if defined(__DJGPP__) && (__DJGPP__ > 1) +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# else +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T int + +#elif defined(__SALFORDC__) +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# define CURL_TYPEOF_CURL_SOCKLEN_T int + +#elif defined(__BORLANDC__) +# if (__BORLANDC__ < 0x520) +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# else +# define CURL_TYPEOF_CURL_OFF_T __int64 +# define CURL_FORMAT_CURL_OFF_T "I64d" +# define CURL_FORMAT_CURL_OFF_TU "I64u" +# define CURL_SUFFIX_CURL_OFF_T i64 +# define CURL_SUFFIX_CURL_OFF_TU ui64 +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T int + +#elif defined(__TURBOC__) +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# define CURL_TYPEOF_CURL_SOCKLEN_T int + +#elif defined(__WATCOMC__) +# if defined(__386__) +# define CURL_TYPEOF_CURL_OFF_T __int64 +# define CURL_FORMAT_CURL_OFF_T "I64d" +# define CURL_FORMAT_CURL_OFF_TU "I64u" +# define CURL_SUFFIX_CURL_OFF_T i64 +# define CURL_SUFFIX_CURL_OFF_TU ui64 +# else +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T int + +#elif defined(__POCC__) +# if (__POCC__ < 280) +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# elif defined(_MSC_VER) +# define CURL_TYPEOF_CURL_OFF_T __int64 +# define CURL_FORMAT_CURL_OFF_T "I64d" +# define CURL_FORMAT_CURL_OFF_TU "I64u" +# define CURL_SUFFIX_CURL_OFF_T i64 +# define CURL_SUFFIX_CURL_OFF_TU ui64 +# else +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T int + +#elif defined(__LCC__) +# if defined(__e2k__) /* MCST eLbrus C Compiler */ +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t +# define CURL_PULL_SYS_TYPES_H 1 +# define CURL_PULL_SYS_SOCKET_H 1 +# else /* Local (or Little) C Compiler */ +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# endif + +#elif defined(__SYMBIAN32__) +# if defined(__EABI__) /* Treat all ARM compilers equally */ +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# elif defined(__CW32__) +# pragma longlong on +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# elif defined(__VC32__) +# define CURL_TYPEOF_CURL_OFF_T __int64 +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int + +#elif defined(__MWERKS__) +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# define CURL_TYPEOF_CURL_SOCKLEN_T int + +#elif defined(_WIN32_WCE) +# define CURL_TYPEOF_CURL_OFF_T __int64 +# define CURL_FORMAT_CURL_OFF_T "I64d" +# define CURL_FORMAT_CURL_OFF_TU "I64u" +# define CURL_SUFFIX_CURL_OFF_T i64 +# define CURL_SUFFIX_CURL_OFF_TU ui64 +# define CURL_TYPEOF_CURL_SOCKLEN_T int + +#elif defined(__MINGW32__) +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "I64d" +# define CURL_FORMAT_CURL_OFF_TU "I64u" +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t +# define CURL_PULL_SYS_TYPES_H 1 +# define CURL_PULL_WS2TCPIP_H 1 + +#elif defined(__VMS) +# if defined(__VAX) +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# else +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int + +#elif defined(__OS400__) +# if defined(__ILEC400__) +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t +# define CURL_PULL_SYS_TYPES_H 1 +# define CURL_PULL_SYS_SOCKET_H 1 +# endif + +#elif defined(__MVS__) +# if defined(__IBMC__) || defined(__IBMCPP__) +# if defined(_ILP32) +# elif defined(_LP64) +# endif +# if defined(_LONG_LONG) +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# elif defined(_LP64) +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# else +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t +# define CURL_PULL_SYS_TYPES_H 1 +# define CURL_PULL_SYS_SOCKET_H 1 +# endif + +#elif defined(__370__) +# if defined(__IBMC__) || defined(__IBMCPP__) +# if defined(_ILP32) +# elif defined(_LP64) +# endif +# if defined(_LONG_LONG) +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# elif defined(_LP64) +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# else +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t +# define CURL_PULL_SYS_TYPES_H 1 +# define CURL_PULL_SYS_SOCKET_H 1 +# endif + +#elif defined(TPF) +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# define CURL_TYPEOF_CURL_SOCKLEN_T int + +#elif defined(__TINYC__) /* also known as tcc */ +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t +# define CURL_PULL_SYS_TYPES_H 1 +# define CURL_PULL_SYS_SOCKET_H 1 + +#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) /* Oracle Solaris Studio */ +# if !defined(__LP64) && (defined(__ILP32) || \ + defined(__i386) || \ + defined(__sparcv8) || \ + defined(__sparcv8plus)) +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# elif defined(__LP64) || \ + defined(__amd64) || defined(__sparcv9) +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t +# define CURL_PULL_SYS_TYPES_H 1 +# define CURL_PULL_SYS_SOCKET_H 1 + +#elif defined(__xlc__) /* IBM xlc compiler */ +# if !defined(_LP64) +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# else +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t +# define CURL_PULL_SYS_TYPES_H 1 +# define CURL_PULL_SYS_SOCKET_H 1 + +/* ===================================== */ +/* KEEP MSVC THE PENULTIMATE ENTRY */ +/* ===================================== */ + +#elif defined(_MSC_VER) +# if (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64) +# define CURL_TYPEOF_CURL_OFF_T __int64 +# define CURL_FORMAT_CURL_OFF_T "I64d" +# define CURL_FORMAT_CURL_OFF_TU "I64u" +# define CURL_SUFFIX_CURL_OFF_T i64 +# define CURL_SUFFIX_CURL_OFF_TU ui64 +# else +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T int + +/* ===================================== */ +/* KEEP GENERIC GCC THE LAST ENTRY */ +/* ===================================== */ + +#elif defined(__GNUC__) && !defined(_SCO_DS) +# if !defined(__LP64__) && \ + (defined(__ILP32__) || defined(__i386__) || defined(__hppa__) || \ + defined(__ppc__) || defined(__powerpc__) || defined(__arm__) || \ + defined(__sparc__) || defined(__mips__) || defined(__sh__) || \ + defined(__XTENSA__) || \ + (defined(__SIZEOF_LONG__) && __SIZEOF_LONG__ == 4) || \ + (defined(__LONG_MAX__) && __LONG_MAX__ == 2147483647L)) +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# elif defined(__LP64__) || \ + defined(__x86_64__) || defined(__ppc64__) || defined(__sparc64__) || \ + defined(__e2k__) || \ + (defined(__SIZEOF_LONG__) && __SIZEOF_LONG__ == 8) || \ + (defined(__LONG_MAX__) && __LONG_MAX__ == 9223372036854775807L) +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t +# define CURL_PULL_SYS_TYPES_H 1 +# define CURL_PULL_SYS_SOCKET_H 1 + +#else +/* generic "safe guess" on old 32 bit style */ +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# define CURL_TYPEOF_CURL_SOCKLEN_T int +#endif + +#ifdef _AIX +/* AIX needs */ +#define CURL_PULL_SYS_POLL_H +#endif + + +/* CURL_PULL_WS2TCPIP_H is defined above when inclusion of header file */ +/* ws2tcpip.h is required here to properly make type definitions below. */ +#ifdef CURL_PULL_WS2TCPIP_H +# include +# include +# include +#endif + +/* CURL_PULL_SYS_TYPES_H is defined above when inclusion of header file */ +/* sys/types.h is required here to properly make type definitions below. */ +#ifdef CURL_PULL_SYS_TYPES_H +# include +#endif + +/* CURL_PULL_SYS_SOCKET_H is defined above when inclusion of header file */ +/* sys/socket.h is required here to properly make type definitions below. */ +#ifdef CURL_PULL_SYS_SOCKET_H +# include +#endif + +/* CURL_PULL_SYS_POLL_H is defined above when inclusion of header file */ +/* sys/poll.h is required here to properly make type definitions below. */ +#ifdef CURL_PULL_SYS_POLL_H +# include +#endif + +/* Data type definition of curl_socklen_t. */ +#ifdef CURL_TYPEOF_CURL_SOCKLEN_T + typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t; +#endif + +/* Data type definition of curl_off_t. */ + +#ifdef CURL_TYPEOF_CURL_OFF_T + typedef CURL_TYPEOF_CURL_OFF_T curl_off_t; +#endif + +/* + * CURL_ISOCPP and CURL_OFF_T_C definitions are done here in order to allow + * these to be visible and exported by the external libcurl interface API, + * while also making them visible to the library internals, simply including + * curl_setup.h, without actually needing to include curl.h internally. + * If some day this section would grow big enough, all this should be moved + * to its own header file. + */ + +/* + * Figure out if we can use the ## preprocessor operator, which is supported + * by ISO/ANSI C and C++. Some compilers support it without setting __STDC__ + * or __cplusplus so we need to carefully check for them too. + */ + +#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) || \ + defined(__HP_aCC) || defined(__BORLANDC__) || defined(__LCC__) || \ + defined(__POCC__) || defined(__SALFORDC__) || defined(__HIGHC__) || \ + defined(__ILEC400__) + /* This compiler is believed to have an ISO compatible preprocessor */ +#define CURL_ISOCPP +#else + /* This compiler is believed NOT to have an ISO compatible preprocessor */ +#undef CURL_ISOCPP +#endif + +/* + * Macros for minimum-width signed and unsigned curl_off_t integer constants. + */ + +#if defined(__BORLANDC__) && (__BORLANDC__ == 0x0551) +# define CURLINC_OFF_T_C_HLPR2(x) x +# define CURLINC_OFF_T_C_HLPR1(x) CURLINC_OFF_T_C_HLPR2(x) +# define CURL_OFF_T_C(Val) CURLINC_OFF_T_C_HLPR1(Val) ## \ + CURLINC_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_T) +# define CURL_OFF_TU_C(Val) CURLINC_OFF_T_C_HLPR1(Val) ## \ + CURLINC_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_TU) +#else +# ifdef CURL_ISOCPP +# define CURLINC_OFF_T_C_HLPR2(Val,Suffix) Val ## Suffix +# else +# define CURLINC_OFF_T_C_HLPR2(Val,Suffix) Val/**/Suffix +# endif +# define CURLINC_OFF_T_C_HLPR1(Val,Suffix) CURLINC_OFF_T_C_HLPR2(Val,Suffix) +# define CURL_OFF_T_C(Val) CURLINC_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_T) +# define CURL_OFF_TU_C(Val) CURLINC_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_TU) +#endif + +#endif /* CURLINC_SYSTEM_H */ diff --git a/libs/curl/include/curl/typecheck-gcc.h b/libs/curl/include/curl/typecheck-gcc.h index 46f92d728..03c84fc85 100644 --- a/libs/curl/include/curl/typecheck-gcc.h +++ b/libs/curl/include/curl/typecheck-gcc.h @@ -1,5 +1,5 @@ -#ifndef __CURL_TYPECHECK_GCC_H -#define __CURL_TYPECHECK_GCC_H +#ifndef CURLINC_TYPECHECK_GCC_H +#define CURLINC_TYPECHECK_GCC_H /*************************************************************************** * _ _ ____ _ * Project ___| | | | _ \| | @@ -7,11 +7,11 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms - * are also available at http://curl.haxx.se/docs/copyright.html. + * are also available at https://curl.haxx.se/docs/copyright.html. * * You may opt to use, copy, modify, merge, publish, distribute and/or sell * copies of the Software, and permit persons to whom the Software is @@ -25,10 +25,10 @@ /* wraps curl_easy_setopt() with typechecking */ /* To add a new kind of warning, add an - * if(_curl_is_sometype_option(_curl_opt)) - * if(!_curl_is_sometype(value)) + * if(curlcheck_sometype_option(_curl_opt)) + * if(!curlcheck_sometype(value)) * _curl_easy_setopt_err_sometype(); - * block and define _curl_is_sometype_option, _curl_is_sometype and + * block and define curlcheck_sometype_option, curlcheck_sometype and * _curl_easy_setopt_err_sometype below * * NOTE: We use two nested 'if' statements here instead of the && operator, in @@ -38,99 +38,115 @@ * To add an option that uses the same type as an existing option, you'll just * need to extend the appropriate _curl_*_option macro */ -#define curl_easy_setopt(handle, option, value) \ -__extension__ ({ \ - __typeof__ (option) _curl_opt = option; \ - if (__builtin_constant_p(_curl_opt)) { \ - if (_curl_is_long_option(_curl_opt)) \ - if (!_curl_is_long(value)) \ - _curl_easy_setopt_err_long(); \ - if (_curl_is_off_t_option(_curl_opt)) \ - if (!_curl_is_off_t(value)) \ - _curl_easy_setopt_err_curl_off_t(); \ - if (_curl_is_string_option(_curl_opt)) \ - if (!_curl_is_string(value)) \ - _curl_easy_setopt_err_string(); \ - if (_curl_is_write_cb_option(_curl_opt)) \ - if (!_curl_is_write_cb(value)) \ - _curl_easy_setopt_err_write_callback(); \ - if ((_curl_opt) == CURLOPT_READFUNCTION) \ - if (!_curl_is_read_cb(value)) \ - _curl_easy_setopt_err_read_cb(); \ - if ((_curl_opt) == CURLOPT_IOCTLFUNCTION) \ - if (!_curl_is_ioctl_cb(value)) \ - _curl_easy_setopt_err_ioctl_cb(); \ - if ((_curl_opt) == CURLOPT_SOCKOPTFUNCTION) \ - if (!_curl_is_sockopt_cb(value)) \ - _curl_easy_setopt_err_sockopt_cb(); \ - if ((_curl_opt) == CURLOPT_OPENSOCKETFUNCTION) \ - if (!_curl_is_opensocket_cb(value)) \ - _curl_easy_setopt_err_opensocket_cb(); \ - if ((_curl_opt) == CURLOPT_PROGRESSFUNCTION) \ - if (!_curl_is_progress_cb(value)) \ - _curl_easy_setopt_err_progress_cb(); \ - if ((_curl_opt) == CURLOPT_DEBUGFUNCTION) \ - if (!_curl_is_debug_cb(value)) \ - _curl_easy_setopt_err_debug_cb(); \ - if ((_curl_opt) == CURLOPT_SSL_CTX_FUNCTION) \ - if (!_curl_is_ssl_ctx_cb(value)) \ - _curl_easy_setopt_err_ssl_ctx_cb(); \ - if (_curl_is_conv_cb_option(_curl_opt)) \ - if (!_curl_is_conv_cb(value)) \ - _curl_easy_setopt_err_conv_cb(); \ - if ((_curl_opt) == CURLOPT_SEEKFUNCTION) \ - if (!_curl_is_seek_cb(value)) \ - _curl_easy_setopt_err_seek_cb(); \ - if (_curl_is_cb_data_option(_curl_opt)) \ - if (!_curl_is_cb_data(value)) \ - _curl_easy_setopt_err_cb_data(); \ - if ((_curl_opt) == CURLOPT_ERRORBUFFER) \ - if (!_curl_is_error_buffer(value)) \ - _curl_easy_setopt_err_error_buffer(); \ - if ((_curl_opt) == CURLOPT_STDERR) \ - if (!_curl_is_FILE(value)) \ - _curl_easy_setopt_err_FILE(); \ - if (_curl_is_postfields_option(_curl_opt)) \ - if (!_curl_is_postfields(value)) \ - _curl_easy_setopt_err_postfields(); \ - if ((_curl_opt) == CURLOPT_HTTPPOST) \ - if (!_curl_is_arr((value), struct curl_httppost)) \ - _curl_easy_setopt_err_curl_httpost(); \ - if (_curl_is_slist_option(_curl_opt)) \ - if (!_curl_is_arr((value), struct curl_slist)) \ - _curl_easy_setopt_err_curl_slist(); \ - if ((_curl_opt) == CURLOPT_SHARE) \ - if (!_curl_is_ptr((value), CURLSH)) \ - _curl_easy_setopt_err_CURLSH(); \ - } \ - curl_easy_setopt(handle, _curl_opt, value); \ -}) +#define curl_easy_setopt(handle, option, value) \ + __extension__({ \ + __typeof__(option) _curl_opt = option; \ + if(__builtin_constant_p(_curl_opt)) { \ + if(curlcheck_long_option(_curl_opt)) \ + if(!curlcheck_long(value)) \ + _curl_easy_setopt_err_long(); \ + if(curlcheck_off_t_option(_curl_opt)) \ + if(!curlcheck_off_t(value)) \ + _curl_easy_setopt_err_curl_off_t(); \ + if(curlcheck_string_option(_curl_opt)) \ + if(!curlcheck_string(value)) \ + _curl_easy_setopt_err_string(); \ + if(curlcheck_write_cb_option(_curl_opt)) \ + if(!curlcheck_write_cb(value)) \ + _curl_easy_setopt_err_write_callback(); \ + if((_curl_opt) == CURLOPT_RESOLVER_START_FUNCTION) \ + if(!curlcheck_resolver_start_callback(value)) \ + _curl_easy_setopt_err_resolver_start_callback(); \ + if((_curl_opt) == CURLOPT_READFUNCTION) \ + if(!curlcheck_read_cb(value)) \ + _curl_easy_setopt_err_read_cb(); \ + if((_curl_opt) == CURLOPT_IOCTLFUNCTION) \ + if(!curlcheck_ioctl_cb(value)) \ + _curl_easy_setopt_err_ioctl_cb(); \ + if((_curl_opt) == CURLOPT_SOCKOPTFUNCTION) \ + if(!curlcheck_sockopt_cb(value)) \ + _curl_easy_setopt_err_sockopt_cb(); \ + if((_curl_opt) == CURLOPT_OPENSOCKETFUNCTION) \ + if(!curlcheck_opensocket_cb(value)) \ + _curl_easy_setopt_err_opensocket_cb(); \ + if((_curl_opt) == CURLOPT_PROGRESSFUNCTION) \ + if(!curlcheck_progress_cb(value)) \ + _curl_easy_setopt_err_progress_cb(); \ + if((_curl_opt) == CURLOPT_DEBUGFUNCTION) \ + if(!curlcheck_debug_cb(value)) \ + _curl_easy_setopt_err_debug_cb(); \ + if((_curl_opt) == CURLOPT_SSL_CTX_FUNCTION) \ + if(!curlcheck_ssl_ctx_cb(value)) \ + _curl_easy_setopt_err_ssl_ctx_cb(); \ + if(curlcheck_conv_cb_option(_curl_opt)) \ + if(!curlcheck_conv_cb(value)) \ + _curl_easy_setopt_err_conv_cb(); \ + if((_curl_opt) == CURLOPT_SEEKFUNCTION) \ + if(!curlcheck_seek_cb(value)) \ + _curl_easy_setopt_err_seek_cb(); \ + if(curlcheck_cb_data_option(_curl_opt)) \ + if(!curlcheck_cb_data(value)) \ + _curl_easy_setopt_err_cb_data(); \ + if((_curl_opt) == CURLOPT_ERRORBUFFER) \ + if(!curlcheck_error_buffer(value)) \ + _curl_easy_setopt_err_error_buffer(); \ + if((_curl_opt) == CURLOPT_STDERR) \ + if(!curlcheck_FILE(value)) \ + _curl_easy_setopt_err_FILE(); \ + if(curlcheck_postfields_option(_curl_opt)) \ + if(!curlcheck_postfields(value)) \ + _curl_easy_setopt_err_postfields(); \ + if((_curl_opt) == CURLOPT_HTTPPOST) \ + if(!curlcheck_arr((value), struct curl_httppost)) \ + _curl_easy_setopt_err_curl_httpost(); \ + if((_curl_opt) == CURLOPT_MIMEPOST) \ + if(!curlcheck_ptr((value), curl_mime)) \ + _curl_easy_setopt_err_curl_mimepost(); \ + if(curlcheck_slist_option(_curl_opt)) \ + if(!curlcheck_arr((value), struct curl_slist)) \ + _curl_easy_setopt_err_curl_slist(); \ + if((_curl_opt) == CURLOPT_SHARE) \ + if(!curlcheck_ptr((value), CURLSH)) \ + _curl_easy_setopt_err_CURLSH(); \ + } \ + curl_easy_setopt(handle, _curl_opt, value); \ + }) /* wraps curl_easy_getinfo() with typechecking */ -/* FIXME: don't allow const pointers */ -#define curl_easy_getinfo(handle, info, arg) \ -__extension__ ({ \ - __typeof__ (info) _curl_info = info; \ - if (__builtin_constant_p(_curl_info)) { \ - if (_curl_is_string_info(_curl_info)) \ - if (!_curl_is_arr((arg), char *)) \ - _curl_easy_getinfo_err_string(); \ - if (_curl_is_long_info(_curl_info)) \ - if (!_curl_is_arr((arg), long)) \ - _curl_easy_getinfo_err_long(); \ - if (_curl_is_double_info(_curl_info)) \ - if (!_curl_is_arr((arg), double)) \ - _curl_easy_getinfo_err_double(); \ - if (_curl_is_slist_info(_curl_info)) \ - if (!_curl_is_arr((arg), struct curl_slist *)) \ - _curl_easy_getinfo_err_curl_slist(); \ - } \ - curl_easy_getinfo(handle, _curl_info, arg); \ -}) +#define curl_easy_getinfo(handle, info, arg) \ + __extension__({ \ + __typeof__(info) _curl_info = info; \ + if(__builtin_constant_p(_curl_info)) { \ + if(curlcheck_string_info(_curl_info)) \ + if(!curlcheck_arr((arg), char *)) \ + _curl_easy_getinfo_err_string(); \ + if(curlcheck_long_info(_curl_info)) \ + if(!curlcheck_arr((arg), long)) \ + _curl_easy_getinfo_err_long(); \ + if(curlcheck_double_info(_curl_info)) \ + if(!curlcheck_arr((arg), double)) \ + _curl_easy_getinfo_err_double(); \ + if(curlcheck_slist_info(_curl_info)) \ + if(!curlcheck_arr((arg), struct curl_slist *)) \ + _curl_easy_getinfo_err_curl_slist(); \ + if(curlcheck_tlssessioninfo_info(_curl_info)) \ + if(!curlcheck_arr((arg), struct curl_tlssessioninfo *)) \ + _curl_easy_getinfo_err_curl_tlssesssioninfo(); \ + if(curlcheck_certinfo_info(_curl_info)) \ + if(!curlcheck_arr((arg), struct curl_certinfo *)) \ + _curl_easy_getinfo_err_curl_certinfo(); \ + if(curlcheck_socket_info(_curl_info)) \ + if(!curlcheck_arr((arg), curl_socket_t)) \ + _curl_easy_getinfo_err_curl_socket(); \ + if(curlcheck_off_t_info(_curl_info)) \ + if(!curlcheck_arr((arg), curl_off_t)) \ + _curl_easy_getinfo_err_curl_off_t(); \ + } \ + curl_easy_getinfo(handle, _curl_info, arg); \ + }) -/* TODO: typechecking for curl_share_setopt() and curl_multi_setopt(), - * for now just make sure that the functions are called with three - * arguments +/* + * For now, just make sure that the functions are called with three arguments */ #define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param) #define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param) @@ -140,61 +156,84 @@ __extension__ ({ \ * functions */ /* To define a new warning, use _CURL_WARNING(identifier, "message") */ -#define _CURL_WARNING(id, message) \ - static void __attribute__((warning(message))) __attribute__((unused)) \ - __attribute__((noinline)) id(void) { __asm__(""); } +#define CURLWARNING(id, message) \ + static void __attribute__((__warning__(message))) \ + __attribute__((__unused__)) __attribute__((__noinline__)) \ + id(void) { __asm__(""); } -_CURL_WARNING(_curl_easy_setopt_err_long, +CURLWARNING(_curl_easy_setopt_err_long, "curl_easy_setopt expects a long argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_curl_off_t, +CURLWARNING(_curl_easy_setopt_err_curl_off_t, "curl_easy_setopt expects a curl_off_t argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_string, - "curl_easy_setopt expects a string (char* or char[]) argument for this option" +CURLWARNING(_curl_easy_setopt_err_string, + "curl_easy_setopt expects a " + "string ('char *' or char[]) argument for this option" ) -_CURL_WARNING(_curl_easy_setopt_err_write_callback, +CURLWARNING(_curl_easy_setopt_err_write_callback, "curl_easy_setopt expects a curl_write_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_read_cb, - "curl_easy_setopt expects a curl_read_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_ioctl_cb, - "curl_easy_setopt expects a curl_ioctl_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_sockopt_cb, - "curl_easy_setopt expects a curl_sockopt_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_opensocket_cb, - "curl_easy_setopt expects a curl_opensocket_callback argument for this option" +CURLWARNING(_curl_easy_setopt_err_resolver_start_callback, + "curl_easy_setopt expects a " + "curl_resolver_start_callback argument for this option" ) -_CURL_WARNING(_curl_easy_setopt_err_progress_cb, +CURLWARNING(_curl_easy_setopt_err_read_cb, + "curl_easy_setopt expects a curl_read_callback argument for this option") +CURLWARNING(_curl_easy_setopt_err_ioctl_cb, + "curl_easy_setopt expects a curl_ioctl_callback argument for this option") +CURLWARNING(_curl_easy_setopt_err_sockopt_cb, + "curl_easy_setopt expects a curl_sockopt_callback argument for this option") +CURLWARNING(_curl_easy_setopt_err_opensocket_cb, + "curl_easy_setopt expects a " + "curl_opensocket_callback argument for this option" + ) +CURLWARNING(_curl_easy_setopt_err_progress_cb, "curl_easy_setopt expects a curl_progress_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_debug_cb, +CURLWARNING(_curl_easy_setopt_err_debug_cb, "curl_easy_setopt expects a curl_debug_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_ssl_ctx_cb, +CURLWARNING(_curl_easy_setopt_err_ssl_ctx_cb, "curl_easy_setopt expects a curl_ssl_ctx_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_conv_cb, +CURLWARNING(_curl_easy_setopt_err_conv_cb, "curl_easy_setopt expects a curl_conv_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_seek_cb, +CURLWARNING(_curl_easy_setopt_err_seek_cb, "curl_easy_setopt expects a curl_seek_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_cb_data, - "curl_easy_setopt expects a private data pointer as argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_error_buffer, - "curl_easy_setopt expects a char buffer of CURL_ERROR_SIZE as argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_FILE, - "curl_easy_setopt expects a FILE* argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_postfields, - "curl_easy_setopt expects a void* or char* argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_curl_httpost, - "curl_easy_setopt expects a struct curl_httppost* argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_curl_slist, - "curl_easy_setopt expects a struct curl_slist* argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_CURLSH, +CURLWARNING(_curl_easy_setopt_err_cb_data, + "curl_easy_setopt expects a " + "private data pointer as argument for this option") +CURLWARNING(_curl_easy_setopt_err_error_buffer, + "curl_easy_setopt expects a " + "char buffer of CURL_ERROR_SIZE as argument for this option") +CURLWARNING(_curl_easy_setopt_err_FILE, + "curl_easy_setopt expects a 'FILE *' argument for this option") +CURLWARNING(_curl_easy_setopt_err_postfields, + "curl_easy_setopt expects a 'void *' or 'char *' argument for this option") +CURLWARNING(_curl_easy_setopt_err_curl_httpost, + "curl_easy_setopt expects a 'struct curl_httppost *' " + "argument for this option") +CURLWARNING(_curl_easy_setopt_err_curl_mimepost, + "curl_easy_setopt expects a 'curl_mime *' " + "argument for this option") +CURLWARNING(_curl_easy_setopt_err_curl_slist, + "curl_easy_setopt expects a 'struct curl_slist *' argument for this option") +CURLWARNING(_curl_easy_setopt_err_CURLSH, "curl_easy_setopt expects a CURLSH* argument for this option") -_CURL_WARNING(_curl_easy_getinfo_err_string, - "curl_easy_getinfo expects a pointer to char * for this info") -_CURL_WARNING(_curl_easy_getinfo_err_long, +CURLWARNING(_curl_easy_getinfo_err_string, + "curl_easy_getinfo expects a pointer to 'char *' for this info") +CURLWARNING(_curl_easy_getinfo_err_long, "curl_easy_getinfo expects a pointer to long for this info") -_CURL_WARNING(_curl_easy_getinfo_err_double, +CURLWARNING(_curl_easy_getinfo_err_double, "curl_easy_getinfo expects a pointer to double for this info") -_CURL_WARNING(_curl_easy_getinfo_err_curl_slist, - "curl_easy_getinfo expects a pointer to struct curl_slist * for this info") +CURLWARNING(_curl_easy_getinfo_err_curl_slist, + "curl_easy_getinfo expects a pointer to 'struct curl_slist *' for this info") +CURLWARNING(_curl_easy_getinfo_err_curl_tlssesssioninfo, + "curl_easy_getinfo expects a pointer to " + "'struct curl_tlssessioninfo *' for this info") +CURLWARNING(_curl_easy_getinfo_err_curl_certinfo, + "curl_easy_getinfo expects a pointer to " + "'struct curl_certinfo *' for this info") +CURLWARNING(_curl_easy_getinfo_err_curl_socket, + "curl_easy_getinfo expects a pointer to curl_socket_t for this info") +CURLWARNING(_curl_easy_getinfo_err_curl_off_t, + "curl_easy_getinfo expects a pointer to curl_off_t for this info") /* groups of curl_easy_setops options that take the same type of argument */ @@ -205,131 +244,188 @@ _CURL_WARNING(_curl_easy_getinfo_err_curl_slist, */ /* evaluates to true if option takes a long argument */ -#define _curl_is_long_option(option) \ +#define curlcheck_long_option(option) \ (0 < (option) && (option) < CURLOPTTYPE_OBJECTPOINT) -#define _curl_is_off_t_option(option) \ +#define curlcheck_off_t_option(option) \ ((option) > CURLOPTTYPE_OFF_T) /* evaluates to true if option takes a char* argument */ -#define _curl_is_string_option(option) \ - ((option) == CURLOPT_URL || \ - (option) == CURLOPT_PROXY || \ - (option) == CURLOPT_INTERFACE || \ - (option) == CURLOPT_NETRC_FILE || \ - (option) == CURLOPT_USERPWD || \ - (option) == CURLOPT_USERNAME || \ - (option) == CURLOPT_PASSWORD || \ - (option) == CURLOPT_PROXYUSERPWD || \ - (option) == CURLOPT_PROXYUSERNAME || \ - (option) == CURLOPT_PROXYPASSWORD || \ - (option) == CURLOPT_NOPROXY || \ +#define curlcheck_string_option(option) \ + ((option) == CURLOPT_ABSTRACT_UNIX_SOCKET || \ (option) == CURLOPT_ACCEPT_ENCODING || \ - (option) == CURLOPT_REFERER || \ - (option) == CURLOPT_USERAGENT || \ + (option) == CURLOPT_ALTSVC || \ + (option) == CURLOPT_CAINFO || \ + (option) == CURLOPT_CAPATH || \ (option) == CURLOPT_COOKIE || \ (option) == CURLOPT_COOKIEFILE || \ (option) == CURLOPT_COOKIEJAR || \ (option) == CURLOPT_COOKIELIST || \ - (option) == CURLOPT_FTPPORT || \ - (option) == CURLOPT_FTP_ALTERNATIVE_TO_USER || \ - (option) == CURLOPT_FTP_ACCOUNT || \ - (option) == CURLOPT_RANGE || \ - (option) == CURLOPT_CUSTOMREQUEST || \ - (option) == CURLOPT_SSLCERT || \ - (option) == CURLOPT_SSLCERTTYPE || \ - (option) == CURLOPT_SSLKEY || \ - (option) == CURLOPT_SSLKEYTYPE || \ - (option) == CURLOPT_KEYPASSWD || \ - (option) == CURLOPT_SSLENGINE || \ - (option) == CURLOPT_CAINFO || \ - (option) == CURLOPT_CAPATH || \ - (option) == CURLOPT_RANDOM_FILE || \ - (option) == CURLOPT_EGDSOCKET || \ - (option) == CURLOPT_SSL_CIPHER_LIST || \ - (option) == CURLOPT_KRBLEVEL || \ - (option) == CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 || \ - (option) == CURLOPT_SSH_PUBLIC_KEYFILE || \ - (option) == CURLOPT_SSH_PRIVATE_KEYFILE || \ (option) == CURLOPT_CRLFILE || \ + (option) == CURLOPT_CUSTOMREQUEST || \ + (option) == CURLOPT_DEFAULT_PROTOCOL || \ + (option) == CURLOPT_DNS_INTERFACE || \ + (option) == CURLOPT_DNS_LOCAL_IP4 || \ + (option) == CURLOPT_DNS_LOCAL_IP6 || \ + (option) == CURLOPT_DNS_SERVERS || \ + (option) == CURLOPT_DOH_URL || \ + (option) == CURLOPT_EGDSOCKET || \ + (option) == CURLOPT_FTPPORT || \ + (option) == CURLOPT_FTP_ACCOUNT || \ + (option) == CURLOPT_FTP_ALTERNATIVE_TO_USER || \ + (option) == CURLOPT_INTERFACE || \ (option) == CURLOPT_ISSUERCERT || \ - (option) == CURLOPT_SOCKS5_GSSAPI_SERVICE || \ - (option) == CURLOPT_SSH_KNOWNHOSTS || \ + (option) == CURLOPT_KEYPASSWD || \ + (option) == CURLOPT_KRBLEVEL || \ + (option) == CURLOPT_LOGIN_OPTIONS || \ + (option) == CURLOPT_MAIL_AUTH || \ (option) == CURLOPT_MAIL_FROM || \ + (option) == CURLOPT_NETRC_FILE || \ + (option) == CURLOPT_NOPROXY || \ + (option) == CURLOPT_PASSWORD || \ + (option) == CURLOPT_PINNEDPUBLICKEY || \ + (option) == CURLOPT_PRE_PROXY || \ + (option) == CURLOPT_PROXY || \ + (option) == CURLOPT_PROXYPASSWORD || \ + (option) == CURLOPT_PROXYUSERNAME || \ + (option) == CURLOPT_PROXYUSERPWD || \ + (option) == CURLOPT_PROXY_CAINFO || \ + (option) == CURLOPT_PROXY_CAPATH || \ + (option) == CURLOPT_PROXY_CRLFILE || \ + (option) == CURLOPT_PROXY_KEYPASSWD || \ + (option) == CURLOPT_PROXY_PINNEDPUBLICKEY || \ + (option) == CURLOPT_PROXY_SERVICE_NAME || \ + (option) == CURLOPT_PROXY_SSLCERT || \ + (option) == CURLOPT_PROXY_SSLCERTTYPE || \ + (option) == CURLOPT_PROXY_SSLKEY || \ + (option) == CURLOPT_PROXY_SSLKEYTYPE || \ + (option) == CURLOPT_PROXY_SSL_CIPHER_LIST || \ + (option) == CURLOPT_PROXY_TLS13_CIPHERS || \ + (option) == CURLOPT_PROXY_TLSAUTH_PASSWORD || \ + (option) == CURLOPT_PROXY_TLSAUTH_TYPE || \ + (option) == CURLOPT_PROXY_TLSAUTH_USERNAME || \ + (option) == CURLOPT_RANDOM_FILE || \ + (option) == CURLOPT_RANGE || \ + (option) == CURLOPT_REFERER || \ + (option) == CURLOPT_REQUEST_TARGET || \ (option) == CURLOPT_RTSP_SESSION_ID || \ (option) == CURLOPT_RTSP_STREAM_URI || \ (option) == CURLOPT_RTSP_TRANSPORT || \ + (option) == CURLOPT_SASL_AUTHZID || \ + (option) == CURLOPT_SERVICE_NAME || \ + (option) == CURLOPT_SOCKS5_GSSAPI_SERVICE || \ + (option) == CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 || \ + (option) == CURLOPT_SSH_KNOWNHOSTS || \ + (option) == CURLOPT_SSH_PRIVATE_KEYFILE || \ + (option) == CURLOPT_SSH_PUBLIC_KEYFILE || \ + (option) == CURLOPT_SSLCERT || \ + (option) == CURLOPT_SSLCERTTYPE || \ + (option) == CURLOPT_SSLENGINE || \ + (option) == CURLOPT_SSLKEY || \ + (option) == CURLOPT_SSLKEYTYPE || \ + (option) == CURLOPT_SSL_CIPHER_LIST || \ + (option) == CURLOPT_TLS13_CIPHERS || \ + (option) == CURLOPT_TLSAUTH_PASSWORD || \ + (option) == CURLOPT_TLSAUTH_TYPE || \ + (option) == CURLOPT_TLSAUTH_USERNAME || \ + (option) == CURLOPT_UNIX_SOCKET_PATH || \ + (option) == CURLOPT_URL || \ + (option) == CURLOPT_USERAGENT || \ + (option) == CURLOPT_USERNAME || \ + (option) == CURLOPT_USERPWD || \ + (option) == CURLOPT_XOAUTH2_BEARER || \ 0) /* evaluates to true if option takes a curl_write_callback argument */ -#define _curl_is_write_cb_option(option) \ - ((option) == CURLOPT_HEADERFUNCTION || \ +#define curlcheck_write_cb_option(option) \ + ((option) == CURLOPT_HEADERFUNCTION || \ (option) == CURLOPT_WRITEFUNCTION) /* evaluates to true if option takes a curl_conv_callback argument */ -#define _curl_is_conv_cb_option(option) \ - ((option) == CURLOPT_CONV_TO_NETWORK_FUNCTION || \ - (option) == CURLOPT_CONV_FROM_NETWORK_FUNCTION || \ +#define curlcheck_conv_cb_option(option) \ + ((option) == CURLOPT_CONV_TO_NETWORK_FUNCTION || \ + (option) == CURLOPT_CONV_FROM_NETWORK_FUNCTION || \ (option) == CURLOPT_CONV_FROM_UTF8_FUNCTION) /* evaluates to true if option takes a data argument to pass to a callback */ -#define _curl_is_cb_data_option(option) \ - ((option) == CURLOPT_WRITEDATA || \ - (option) == CURLOPT_READDATA || \ - (option) == CURLOPT_IOCTLDATA || \ - (option) == CURLOPT_SOCKOPTDATA || \ - (option) == CURLOPT_OPENSOCKETDATA || \ - (option) == CURLOPT_PROGRESSDATA || \ - (option) == CURLOPT_WRITEHEADER || \ +#define curlcheck_cb_data_option(option) \ + ((option) == CURLOPT_CHUNK_DATA || \ + (option) == CURLOPT_CLOSESOCKETDATA || \ (option) == CURLOPT_DEBUGDATA || \ - (option) == CURLOPT_SSL_CTX_DATA || \ - (option) == CURLOPT_SEEKDATA || \ - (option) == CURLOPT_PRIVATE || \ - (option) == CURLOPT_SSH_KEYDATA || \ - (option) == CURLOPT_INTERLEAVEDATA || \ - (option) == CURLOPT_CHUNK_DATA || \ (option) == CURLOPT_FNMATCH_DATA || \ + (option) == CURLOPT_HEADERDATA || \ + (option) == CURLOPT_INTERLEAVEDATA || \ + (option) == CURLOPT_IOCTLDATA || \ + (option) == CURLOPT_OPENSOCKETDATA || \ + (option) == CURLOPT_PRIVATE || \ + (option) == CURLOPT_PROGRESSDATA || \ + (option) == CURLOPT_READDATA || \ + (option) == CURLOPT_SEEKDATA || \ + (option) == CURLOPT_SOCKOPTDATA || \ + (option) == CURLOPT_SSH_KEYDATA || \ + (option) == CURLOPT_SSL_CTX_DATA || \ + (option) == CURLOPT_WRITEDATA || \ + (option) == CURLOPT_RESOLVER_START_DATA || \ + (option) == CURLOPT_TRAILERDATA || \ 0) /* evaluates to true if option takes a POST data argument (void* or char*) */ -#define _curl_is_postfields_option(option) \ +#define curlcheck_postfields_option(option) \ ((option) == CURLOPT_POSTFIELDS || \ (option) == CURLOPT_COPYPOSTFIELDS || \ 0) /* evaluates to true if option takes a struct curl_slist * argument */ -#define _curl_is_slist_option(option) \ - ((option) == CURLOPT_HTTPHEADER || \ - (option) == CURLOPT_HTTP200ALIASES || \ - (option) == CURLOPT_QUOTE || \ +#define curlcheck_slist_option(option) \ + ((option) == CURLOPT_HTTP200ALIASES || \ + (option) == CURLOPT_HTTPHEADER || \ + (option) == CURLOPT_MAIL_RCPT || \ (option) == CURLOPT_POSTQUOTE || \ (option) == CURLOPT_PREQUOTE || \ + (option) == CURLOPT_PROXYHEADER || \ + (option) == CURLOPT_QUOTE || \ + (option) == CURLOPT_RESOLVE || \ (option) == CURLOPT_TELNETOPTIONS || \ - (option) == CURLOPT_MAIL_RCPT || \ + (option) == CURLOPT_CONNECT_TO || \ 0) /* groups of curl_easy_getinfo infos that take the same type of argument */ /* evaluates to true if info expects a pointer to char * argument */ -#define _curl_is_string_info(info) \ +#define curlcheck_string_info(info) \ (CURLINFO_STRING < (info) && (info) < CURLINFO_LONG) /* evaluates to true if info expects a pointer to long argument */ -#define _curl_is_long_info(info) \ +#define curlcheck_long_info(info) \ (CURLINFO_LONG < (info) && (info) < CURLINFO_DOUBLE) /* evaluates to true if info expects a pointer to double argument */ -#define _curl_is_double_info(info) \ +#define curlcheck_double_info(info) \ (CURLINFO_DOUBLE < (info) && (info) < CURLINFO_SLIST) /* true if info expects a pointer to struct curl_slist * argument */ -#define _curl_is_slist_info(info) \ - (CURLINFO_SLIST < (info)) +#define curlcheck_slist_info(info) \ + (((info) == CURLINFO_SSL_ENGINES) || ((info) == CURLINFO_COOKIELIST)) + +/* true if info expects a pointer to struct curl_tlssessioninfo * argument */ +#define curlcheck_tlssessioninfo_info(info) \ + (((info) == CURLINFO_TLS_SSL_PTR) || ((info) == CURLINFO_TLS_SESSION)) + +/* true if info expects a pointer to struct curl_certinfo * argument */ +#define curlcheck_certinfo_info(info) ((info) == CURLINFO_CERTINFO) + +/* true if info expects a pointer to struct curl_socket_t argument */ +#define curlcheck_socket_info(info) \ + (CURLINFO_SOCKET < (info) && (info) < CURLINFO_OFF_T) + +/* true if info expects a pointer to curl_off_t argument */ +#define curlcheck_off_t_info(info) \ + (CURLINFO_OFF_T < (info)) /* typecheck helpers -- check whether given expression has requested type*/ -/* For pointers, you can use the _curl_is_ptr/_curl_is_arr macros, +/* For pointers, you can use the curlcheck_ptr/curlcheck_arr macros, * otherwise define a new macro. Search for __builtin_types_compatible_p * in the GCC manual. * NOTE: these macros MUST NOT EVALUATE their arguments! The argument is @@ -338,36 +434,36 @@ _CURL_WARNING(_curl_easy_getinfo_err_curl_slist, * == or whatsoever. */ -/* XXX: should evaluate to true iff expr is a pointer */ -#define _curl_is_any_ptr(expr) \ - (sizeof(expr) == sizeof(void*)) +/* XXX: should evaluate to true if expr is a pointer */ +#define curlcheck_any_ptr(expr) \ + (sizeof(expr) == sizeof(void *)) /* evaluates to true if expr is NULL */ /* XXX: must not evaluate expr, so this check is not accurate */ -#define _curl_is_NULL(expr) \ +#define curlcheck_NULL(expr) \ (__builtin_types_compatible_p(__typeof__(expr), __typeof__(NULL))) /* evaluates to true if expr is type*, const type* or NULL */ -#define _curl_is_ptr(expr, type) \ - (_curl_is_NULL(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), type *) || \ +#define curlcheck_ptr(expr, type) \ + (curlcheck_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), type *) || \ __builtin_types_compatible_p(__typeof__(expr), const type *)) /* evaluates to true if expr is one of type[], type*, NULL or const type* */ -#define _curl_is_arr(expr, type) \ - (_curl_is_ptr((expr), type) || \ +#define curlcheck_arr(expr, type) \ + (curlcheck_ptr((expr), type) || \ __builtin_types_compatible_p(__typeof__(expr), type [])) /* evaluates to true if expr is a string */ -#define _curl_is_string(expr) \ - (_curl_is_arr((expr), char) || \ - _curl_is_arr((expr), signed char) || \ - _curl_is_arr((expr), unsigned char)) +#define curlcheck_string(expr) \ + (curlcheck_arr((expr), char) || \ + curlcheck_arr((expr), signed char) || \ + curlcheck_arr((expr), unsigned char)) /* evaluates to true if expr is a long (no matter the signedness) * XXX: for now, int is also accepted (and therefore short and char, which * are promoted to int when passed to a variadic function) */ -#define _curl_is_long(expr) \ +#define curlcheck_long(expr) \ (__builtin_types_compatible_p(__typeof__(expr), long) || \ __builtin_types_compatible_p(__typeof__(expr), signed long) || \ __builtin_types_compatible_p(__typeof__(expr), unsigned long) || \ @@ -382,175 +478,194 @@ _CURL_WARNING(_curl_easy_getinfo_err_curl_slist, __builtin_types_compatible_p(__typeof__(expr), unsigned char)) /* evaluates to true if expr is of type curl_off_t */ -#define _curl_is_off_t(expr) \ +#define curlcheck_off_t(expr) \ (__builtin_types_compatible_p(__typeof__(expr), curl_off_t)) /* evaluates to true if expr is abuffer suitable for CURLOPT_ERRORBUFFER */ /* XXX: also check size of an char[] array? */ -#define _curl_is_error_buffer(expr) \ - (__builtin_types_compatible_p(__typeof__(expr), char *) || \ +#define curlcheck_error_buffer(expr) \ + (curlcheck_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), char *) || \ __builtin_types_compatible_p(__typeof__(expr), char[])) /* evaluates to true if expr is of type (const) void* or (const) FILE* */ #if 0 -#define _curl_is_cb_data(expr) \ - (_curl_is_ptr((expr), void) || \ - _curl_is_ptr((expr), FILE)) +#define curlcheck_cb_data(expr) \ + (curlcheck_ptr((expr), void) || \ + curlcheck_ptr((expr), FILE)) #else /* be less strict */ -#define _curl_is_cb_data(expr) \ - _curl_is_any_ptr(expr) +#define curlcheck_cb_data(expr) \ + curlcheck_any_ptr(expr) #endif /* evaluates to true if expr is of type FILE* */ -#define _curl_is_FILE(expr) \ - (__builtin_types_compatible_p(__typeof__(expr), FILE *)) +#define curlcheck_FILE(expr) \ + (curlcheck_NULL(expr) || \ + (__builtin_types_compatible_p(__typeof__(expr), FILE *))) /* evaluates to true if expr can be passed as POST data (void* or char*) */ -#define _curl_is_postfields(expr) \ - (_curl_is_ptr((expr), void) || \ - _curl_is_arr((expr), char)) +#define curlcheck_postfields(expr) \ + (curlcheck_ptr((expr), void) || \ + curlcheck_arr((expr), char) || \ + curlcheck_arr((expr), unsigned char)) -/* FIXME: the whole callback checking is messy... - * The idea is to tolerate char vs. void and const vs. not const - * pointers in arguments at least - */ /* helper: __builtin_types_compatible_p distinguishes between functions and * function pointers, hide it */ -#define _curl_callback_compatible(func, type) \ - (__builtin_types_compatible_p(__typeof__(func), type) || \ - __builtin_types_compatible_p(__typeof__(func), type*)) +#define curlcheck_cb_compatible(func, type) \ + (__builtin_types_compatible_p(__typeof__(func), type) || \ + __builtin_types_compatible_p(__typeof__(func) *, type)) + +/* evaluates to true if expr is of type curl_resolver_start_callback */ +#define curlcheck_resolver_start_callback(expr) \ + (curlcheck_NULL(expr) || \ + curlcheck_cb_compatible((expr), curl_resolver_start_callback)) /* evaluates to true if expr is of type curl_read_callback or "similar" */ -#define _curl_is_read_cb(expr) \ - (_curl_is_NULL(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), __typeof__(fread)) || \ - __builtin_types_compatible_p(__typeof__(expr), curl_read_callback) || \ - _curl_callback_compatible((expr), _curl_read_callback1) || \ - _curl_callback_compatible((expr), _curl_read_callback2) || \ - _curl_callback_compatible((expr), _curl_read_callback3) || \ - _curl_callback_compatible((expr), _curl_read_callback4) || \ - _curl_callback_compatible((expr), _curl_read_callback5) || \ - _curl_callback_compatible((expr), _curl_read_callback6)) -typedef size_t (_curl_read_callback1)(char *, size_t, size_t, void*); -typedef size_t (_curl_read_callback2)(char *, size_t, size_t, const void*); -typedef size_t (_curl_read_callback3)(char *, size_t, size_t, FILE*); -typedef size_t (_curl_read_callback4)(void *, size_t, size_t, void*); -typedef size_t (_curl_read_callback5)(void *, size_t, size_t, const void*); -typedef size_t (_curl_read_callback6)(void *, size_t, size_t, FILE*); +#define curlcheck_read_cb(expr) \ + (curlcheck_NULL(expr) || \ + curlcheck_cb_compatible((expr), __typeof__(fread) *) || \ + curlcheck_cb_compatible((expr), curl_read_callback) || \ + curlcheck_cb_compatible((expr), _curl_read_callback1) || \ + curlcheck_cb_compatible((expr), _curl_read_callback2) || \ + curlcheck_cb_compatible((expr), _curl_read_callback3) || \ + curlcheck_cb_compatible((expr), _curl_read_callback4) || \ + curlcheck_cb_compatible((expr), _curl_read_callback5) || \ + curlcheck_cb_compatible((expr), _curl_read_callback6)) +typedef size_t (*_curl_read_callback1)(char *, size_t, size_t, void *); +typedef size_t (*_curl_read_callback2)(char *, size_t, size_t, const void *); +typedef size_t (*_curl_read_callback3)(char *, size_t, size_t, FILE *); +typedef size_t (*_curl_read_callback4)(void *, size_t, size_t, void *); +typedef size_t (*_curl_read_callback5)(void *, size_t, size_t, const void *); +typedef size_t (*_curl_read_callback6)(void *, size_t, size_t, FILE *); /* evaluates to true if expr is of type curl_write_callback or "similar" */ -#define _curl_is_write_cb(expr) \ - (_curl_is_read_cb(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), __typeof__(fwrite)) || \ - __builtin_types_compatible_p(__typeof__(expr), curl_write_callback) || \ - _curl_callback_compatible((expr), _curl_write_callback1) || \ - _curl_callback_compatible((expr), _curl_write_callback2) || \ - _curl_callback_compatible((expr), _curl_write_callback3) || \ - _curl_callback_compatible((expr), _curl_write_callback4) || \ - _curl_callback_compatible((expr), _curl_write_callback5) || \ - _curl_callback_compatible((expr), _curl_write_callback6)) -typedef size_t (_curl_write_callback1)(const char *, size_t, size_t, void*); -typedef size_t (_curl_write_callback2)(const char *, size_t, size_t, - const void*); -typedef size_t (_curl_write_callback3)(const char *, size_t, size_t, FILE*); -typedef size_t (_curl_write_callback4)(const void *, size_t, size_t, void*); -typedef size_t (_curl_write_callback5)(const void *, size_t, size_t, - const void*); -typedef size_t (_curl_write_callback6)(const void *, size_t, size_t, FILE*); +#define curlcheck_write_cb(expr) \ + (curlcheck_read_cb(expr) || \ + curlcheck_cb_compatible((expr), __typeof__(fwrite) *) || \ + curlcheck_cb_compatible((expr), curl_write_callback) || \ + curlcheck_cb_compatible((expr), _curl_write_callback1) || \ + curlcheck_cb_compatible((expr), _curl_write_callback2) || \ + curlcheck_cb_compatible((expr), _curl_write_callback3) || \ + curlcheck_cb_compatible((expr), _curl_write_callback4) || \ + curlcheck_cb_compatible((expr), _curl_write_callback5) || \ + curlcheck_cb_compatible((expr), _curl_write_callback6)) +typedef size_t (*_curl_write_callback1)(const char *, size_t, size_t, void *); +typedef size_t (*_curl_write_callback2)(const char *, size_t, size_t, + const void *); +typedef size_t (*_curl_write_callback3)(const char *, size_t, size_t, FILE *); +typedef size_t (*_curl_write_callback4)(const void *, size_t, size_t, void *); +typedef size_t (*_curl_write_callback5)(const void *, size_t, size_t, + const void *); +typedef size_t (*_curl_write_callback6)(const void *, size_t, size_t, FILE *); /* evaluates to true if expr is of type curl_ioctl_callback or "similar" */ -#define _curl_is_ioctl_cb(expr) \ - (_curl_is_NULL(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), curl_ioctl_callback) || \ - _curl_callback_compatible((expr), _curl_ioctl_callback1) || \ - _curl_callback_compatible((expr), _curl_ioctl_callback2) || \ - _curl_callback_compatible((expr), _curl_ioctl_callback3) || \ - _curl_callback_compatible((expr), _curl_ioctl_callback4)) -typedef curlioerr (_curl_ioctl_callback1)(CURL *, int, void*); -typedef curlioerr (_curl_ioctl_callback2)(CURL *, int, const void*); -typedef curlioerr (_curl_ioctl_callback3)(CURL *, curliocmd, void*); -typedef curlioerr (_curl_ioctl_callback4)(CURL *, curliocmd, const void*); +#define curlcheck_ioctl_cb(expr) \ + (curlcheck_NULL(expr) || \ + curlcheck_cb_compatible((expr), curl_ioctl_callback) || \ + curlcheck_cb_compatible((expr), _curl_ioctl_callback1) || \ + curlcheck_cb_compatible((expr), _curl_ioctl_callback2) || \ + curlcheck_cb_compatible((expr), _curl_ioctl_callback3) || \ + curlcheck_cb_compatible((expr), _curl_ioctl_callback4)) +typedef curlioerr (*_curl_ioctl_callback1)(CURL *, int, void *); +typedef curlioerr (*_curl_ioctl_callback2)(CURL *, int, const void *); +typedef curlioerr (*_curl_ioctl_callback3)(CURL *, curliocmd, void *); +typedef curlioerr (*_curl_ioctl_callback4)(CURL *, curliocmd, const void *); /* evaluates to true if expr is of type curl_sockopt_callback or "similar" */ -#define _curl_is_sockopt_cb(expr) \ - (_curl_is_NULL(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), curl_sockopt_callback) || \ - _curl_callback_compatible((expr), _curl_sockopt_callback1) || \ - _curl_callback_compatible((expr), _curl_sockopt_callback2)) -typedef int (_curl_sockopt_callback1)(void *, curl_socket_t, curlsocktype); -typedef int (_curl_sockopt_callback2)(const void *, curl_socket_t, +#define curlcheck_sockopt_cb(expr) \ + (curlcheck_NULL(expr) || \ + curlcheck_cb_compatible((expr), curl_sockopt_callback) || \ + curlcheck_cb_compatible((expr), _curl_sockopt_callback1) || \ + curlcheck_cb_compatible((expr), _curl_sockopt_callback2)) +typedef int (*_curl_sockopt_callback1)(void *, curl_socket_t, curlsocktype); +typedef int (*_curl_sockopt_callback2)(const void *, curl_socket_t, curlsocktype); -/* evaluates to true if expr is of type curl_opensocket_callback or "similar" */ -#define _curl_is_opensocket_cb(expr) \ - (_curl_is_NULL(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), curl_opensocket_callback) ||\ - _curl_callback_compatible((expr), _curl_opensocket_callback1) || \ - _curl_callback_compatible((expr), _curl_opensocket_callback2) || \ - _curl_callback_compatible((expr), _curl_opensocket_callback3) || \ - _curl_callback_compatible((expr), _curl_opensocket_callback4)) -typedef curl_socket_t (_curl_opensocket_callback1) +/* evaluates to true if expr is of type curl_opensocket_callback or + "similar" */ +#define curlcheck_opensocket_cb(expr) \ + (curlcheck_NULL(expr) || \ + curlcheck_cb_compatible((expr), curl_opensocket_callback) || \ + curlcheck_cb_compatible((expr), _curl_opensocket_callback1) || \ + curlcheck_cb_compatible((expr), _curl_opensocket_callback2) || \ + curlcheck_cb_compatible((expr), _curl_opensocket_callback3) || \ + curlcheck_cb_compatible((expr), _curl_opensocket_callback4)) +typedef curl_socket_t (*_curl_opensocket_callback1) (void *, curlsocktype, struct curl_sockaddr *); -typedef curl_socket_t (_curl_opensocket_callback2) +typedef curl_socket_t (*_curl_opensocket_callback2) (void *, curlsocktype, const struct curl_sockaddr *); -typedef curl_socket_t (_curl_opensocket_callback3) +typedef curl_socket_t (*_curl_opensocket_callback3) (const void *, curlsocktype, struct curl_sockaddr *); -typedef curl_socket_t (_curl_opensocket_callback4) +typedef curl_socket_t (*_curl_opensocket_callback4) (const void *, curlsocktype, const struct curl_sockaddr *); /* evaluates to true if expr is of type curl_progress_callback or "similar" */ -#define _curl_is_progress_cb(expr) \ - (_curl_is_NULL(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), curl_progress_callback) || \ - _curl_callback_compatible((expr), _curl_progress_callback1) || \ - _curl_callback_compatible((expr), _curl_progress_callback2)) -typedef int (_curl_progress_callback1)(void *, +#define curlcheck_progress_cb(expr) \ + (curlcheck_NULL(expr) || \ + curlcheck_cb_compatible((expr), curl_progress_callback) || \ + curlcheck_cb_compatible((expr), _curl_progress_callback1) || \ + curlcheck_cb_compatible((expr), _curl_progress_callback2)) +typedef int (*_curl_progress_callback1)(void *, double, double, double, double); -typedef int (_curl_progress_callback2)(const void *, +typedef int (*_curl_progress_callback2)(const void *, double, double, double, double); /* evaluates to true if expr is of type curl_debug_callback or "similar" */ -#define _curl_is_debug_cb(expr) \ - (_curl_is_NULL(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), curl_debug_callback) || \ - _curl_callback_compatible((expr), _curl_debug_callback1) || \ - _curl_callback_compatible((expr), _curl_debug_callback2) || \ - _curl_callback_compatible((expr), _curl_debug_callback3) || \ - _curl_callback_compatible((expr), _curl_debug_callback4)) -typedef int (_curl_debug_callback1) (CURL *, +#define curlcheck_debug_cb(expr) \ + (curlcheck_NULL(expr) || \ + curlcheck_cb_compatible((expr), curl_debug_callback) || \ + curlcheck_cb_compatible((expr), _curl_debug_callback1) || \ + curlcheck_cb_compatible((expr), _curl_debug_callback2) || \ + curlcheck_cb_compatible((expr), _curl_debug_callback3) || \ + curlcheck_cb_compatible((expr), _curl_debug_callback4) || \ + curlcheck_cb_compatible((expr), _curl_debug_callback5) || \ + curlcheck_cb_compatible((expr), _curl_debug_callback6) || \ + curlcheck_cb_compatible((expr), _curl_debug_callback7) || \ + curlcheck_cb_compatible((expr), _curl_debug_callback8)) +typedef int (*_curl_debug_callback1) (CURL *, curl_infotype, char *, size_t, void *); -typedef int (_curl_debug_callback2) (CURL *, +typedef int (*_curl_debug_callback2) (CURL *, curl_infotype, char *, size_t, const void *); -typedef int (_curl_debug_callback3) (CURL *, +typedef int (*_curl_debug_callback3) (CURL *, curl_infotype, const char *, size_t, void *); -typedef int (_curl_debug_callback4) (CURL *, +typedef int (*_curl_debug_callback4) (CURL *, curl_infotype, const char *, size_t, const void *); +typedef int (*_curl_debug_callback5) (CURL *, + curl_infotype, unsigned char *, size_t, void *); +typedef int (*_curl_debug_callback6) (CURL *, + curl_infotype, unsigned char *, size_t, const void *); +typedef int (*_curl_debug_callback7) (CURL *, + curl_infotype, const unsigned char *, size_t, void *); +typedef int (*_curl_debug_callback8) (CURL *, + curl_infotype, const unsigned char *, size_t, const void *); /* evaluates to true if expr is of type curl_ssl_ctx_callback or "similar" */ /* this is getting even messier... */ -#define _curl_is_ssl_ctx_cb(expr) \ - (_curl_is_NULL(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), curl_ssl_ctx_callback) || \ - _curl_callback_compatible((expr), _curl_ssl_ctx_callback1) || \ - _curl_callback_compatible((expr), _curl_ssl_ctx_callback2) || \ - _curl_callback_compatible((expr), _curl_ssl_ctx_callback3) || \ - _curl_callback_compatible((expr), _curl_ssl_ctx_callback4) || \ - _curl_callback_compatible((expr), _curl_ssl_ctx_callback5) || \ - _curl_callback_compatible((expr), _curl_ssl_ctx_callback6) || \ - _curl_callback_compatible((expr), _curl_ssl_ctx_callback7) || \ - _curl_callback_compatible((expr), _curl_ssl_ctx_callback8)) -typedef CURLcode (_curl_ssl_ctx_callback1)(CURL *, void *, void *); -typedef CURLcode (_curl_ssl_ctx_callback2)(CURL *, void *, const void *); -typedef CURLcode (_curl_ssl_ctx_callback3)(CURL *, const void *, void *); -typedef CURLcode (_curl_ssl_ctx_callback4)(CURL *, const void *, const void *); +#define curlcheck_ssl_ctx_cb(expr) \ + (curlcheck_NULL(expr) || \ + curlcheck_cb_compatible((expr), curl_ssl_ctx_callback) || \ + curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback1) || \ + curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback2) || \ + curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback3) || \ + curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback4) || \ + curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback5) || \ + curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback6) || \ + curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback7) || \ + curlcheck_cb_compatible((expr), _curl_ssl_ctx_callback8)) +typedef CURLcode (*_curl_ssl_ctx_callback1)(CURL *, void *, void *); +typedef CURLcode (*_curl_ssl_ctx_callback2)(CURL *, void *, const void *); +typedef CURLcode (*_curl_ssl_ctx_callback3)(CURL *, const void *, void *); +typedef CURLcode (*_curl_ssl_ctx_callback4)(CURL *, const void *, + const void *); #ifdef HEADER_SSL_H /* hack: if we included OpenSSL's ssl.h, we know about SSL_CTX * this will of course break if we're included before OpenSSL headers... */ -typedef CURLcode (_curl_ssl_ctx_callback5)(CURL *, SSL_CTX, void *); -typedef CURLcode (_curl_ssl_ctx_callback6)(CURL *, SSL_CTX, const void *); -typedef CURLcode (_curl_ssl_ctx_callback7)(CURL *, const SSL_CTX, void *); -typedef CURLcode (_curl_ssl_ctx_callback8)(CURL *, const SSL_CTX, const void *); +typedef CURLcode (*_curl_ssl_ctx_callback5)(CURL *, SSL_CTX, void *); +typedef CURLcode (*_curl_ssl_ctx_callback6)(CURL *, SSL_CTX, const void *); +typedef CURLcode (*_curl_ssl_ctx_callback7)(CURL *, const SSL_CTX, void *); +typedef CURLcode (*_curl_ssl_ctx_callback8)(CURL *, const SSL_CTX, + const void *); #else typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback5; typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback6; @@ -559,26 +674,26 @@ typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback8; #endif /* evaluates to true if expr is of type curl_conv_callback or "similar" */ -#define _curl_is_conv_cb(expr) \ - (_curl_is_NULL(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), curl_conv_callback) || \ - _curl_callback_compatible((expr), _curl_conv_callback1) || \ - _curl_callback_compatible((expr), _curl_conv_callback2) || \ - _curl_callback_compatible((expr), _curl_conv_callback3) || \ - _curl_callback_compatible((expr), _curl_conv_callback4)) +#define curlcheck_conv_cb(expr) \ + (curlcheck_NULL(expr) || \ + curlcheck_cb_compatible((expr), curl_conv_callback) || \ + curlcheck_cb_compatible((expr), _curl_conv_callback1) || \ + curlcheck_cb_compatible((expr), _curl_conv_callback2) || \ + curlcheck_cb_compatible((expr), _curl_conv_callback3) || \ + curlcheck_cb_compatible((expr), _curl_conv_callback4)) typedef CURLcode (*_curl_conv_callback1)(char *, size_t length); typedef CURLcode (*_curl_conv_callback2)(const char *, size_t length); typedef CURLcode (*_curl_conv_callback3)(void *, size_t length); typedef CURLcode (*_curl_conv_callback4)(const void *, size_t length); /* evaluates to true if expr is of type curl_seek_callback or "similar" */ -#define _curl_is_seek_cb(expr) \ - (_curl_is_NULL(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), curl_seek_callback) || \ - _curl_callback_compatible((expr), _curl_seek_callback1) || \ - _curl_callback_compatible((expr), _curl_seek_callback2)) +#define curlcheck_seek_cb(expr) \ + (curlcheck_NULL(expr) || \ + curlcheck_cb_compatible((expr), curl_seek_callback) || \ + curlcheck_cb_compatible((expr), _curl_seek_callback1) || \ + curlcheck_cb_compatible((expr), _curl_seek_callback2)) typedef CURLcode (*_curl_seek_callback1)(void *, curl_off_t, int); typedef CURLcode (*_curl_seek_callback2)(const void *, curl_off_t, int); -#endif /* __CURL_TYPECHECK_GCC_H */ +#endif /* CURLINC_TYPECHECK_GCC_H */ diff --git a/libs/curl/include/curl/urlapi.h b/libs/curl/include/curl/urlapi.h new file mode 100644 index 000000000..f2d06770d --- /dev/null +++ b/libs/curl/include/curl/urlapi.h @@ -0,0 +1,125 @@ +#ifndef CURLINC_URLAPI_H +#define CURLINC_URLAPI_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2018 - 2019, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* the error codes for the URL API */ +typedef enum { + CURLUE_OK, + CURLUE_BAD_HANDLE, /* 1 */ + CURLUE_BAD_PARTPOINTER, /* 2 */ + CURLUE_MALFORMED_INPUT, /* 3 */ + CURLUE_BAD_PORT_NUMBER, /* 4 */ + CURLUE_UNSUPPORTED_SCHEME, /* 5 */ + CURLUE_URLDECODE, /* 6 */ + CURLUE_OUT_OF_MEMORY, /* 7 */ + CURLUE_USER_NOT_ALLOWED, /* 8 */ + CURLUE_UNKNOWN_PART, /* 9 */ + CURLUE_NO_SCHEME, /* 10 */ + CURLUE_NO_USER, /* 11 */ + CURLUE_NO_PASSWORD, /* 12 */ + CURLUE_NO_OPTIONS, /* 13 */ + CURLUE_NO_HOST, /* 14 */ + CURLUE_NO_PORT, /* 15 */ + CURLUE_NO_QUERY, /* 16 */ + CURLUE_NO_FRAGMENT /* 17 */ +} CURLUcode; + +typedef enum { + CURLUPART_URL, + CURLUPART_SCHEME, + CURLUPART_USER, + CURLUPART_PASSWORD, + CURLUPART_OPTIONS, + CURLUPART_HOST, + CURLUPART_PORT, + CURLUPART_PATH, + CURLUPART_QUERY, + CURLUPART_FRAGMENT, + CURLUPART_ZONEID /* added in 7.65.0 */ +} CURLUPart; + +#define CURLU_DEFAULT_PORT (1<<0) /* return default port number */ +#define CURLU_NO_DEFAULT_PORT (1<<1) /* act as if no port number was set, + if the port number matches the + default for the scheme */ +#define CURLU_DEFAULT_SCHEME (1<<2) /* return default scheme if + missing */ +#define CURLU_NON_SUPPORT_SCHEME (1<<3) /* allow non-supported scheme */ +#define CURLU_PATH_AS_IS (1<<4) /* leave dot sequences */ +#define CURLU_DISALLOW_USER (1<<5) /* no user+password allowed */ +#define CURLU_URLDECODE (1<<6) /* URL decode on get */ +#define CURLU_URLENCODE (1<<7) /* URL encode on set */ +#define CURLU_APPENDQUERY (1<<8) /* append a form style part */ +#define CURLU_GUESS_SCHEME (1<<9) /* legacy curl-style guessing */ +#define CURLU_NO_AUTHORITY (1<<10) /* Allow empty authority when the + scheme is unknown. */ + +typedef struct Curl_URL CURLU; + +/* + * curl_url() creates a new CURLU handle and returns a pointer to it. + * Must be freed with curl_url_cleanup(). + */ +CURL_EXTERN CURLU *curl_url(void); + +/* + * curl_url_cleanup() frees the CURLU handle and related resources used for + * the URL parsing. It will not free strings previously returned with the URL + * API. + */ +CURL_EXTERN void curl_url_cleanup(CURLU *handle); + +/* + * curl_url_dup() duplicates a CURLU handle and returns a new copy. The new + * handle must also be freed with curl_url_cleanup(). + */ +CURL_EXTERN CURLU *curl_url_dup(CURLU *in); + +/* + * curl_url_get() extracts a specific part of the URL from a CURLU + * handle. Returns error code. The returned pointer MUST be freed with + * curl_free() afterwards. + */ +CURL_EXTERN CURLUcode curl_url_get(CURLU *handle, CURLUPart what, + char **part, unsigned int flags); + +/* + * curl_url_set() sets a specific part of the URL in a CURLU handle. Returns + * error code. The passed in string will be copied. Passing a NULL instead of + * a part string, clears that part. + */ +CURL_EXTERN CURLUcode curl_url_set(CURLU *handle, CURLUPart what, + const char *part, unsigned int flags); + + +#ifdef __cplusplus +} /* end of extern "C" */ +#endif + +#endif /* CURLINC_URLAPI_H */ diff --git a/libs/curl/lib32/libcurl.a b/libs/curl/lib32/libcurl.a index 2f5a29f62..4e4907c5b 100644 Binary files a/libs/curl/lib32/libcurl.a and b/libs/curl/lib32/libcurl.a differ diff --git a/libs/curl/lib32/libcurl.dll b/libs/curl/lib32/libcurl.dll new file mode 100644 index 000000000..61925326f Binary files /dev/null and b/libs/curl/lib32/libcurl.dll differ diff --git a/libs/curl/lib32/libcurl.dll.a b/libs/curl/lib32/libcurl.dll.a new file mode 100644 index 000000000..ff1003b6e Binary files /dev/null and b/libs/curl/lib32/libcurl.dll.a differ diff --git a/libs/curl/lib64/libcurl-x64.dll b/libs/curl/lib64/libcurl-x64.dll new file mode 100644 index 000000000..7dab52541 Binary files /dev/null and b/libs/curl/lib64/libcurl-x64.dll differ diff --git a/libs/curl/lib64/libcurl.a b/libs/curl/lib64/libcurl.a index 2112cd8f0..d30b71aca 100644 Binary files a/libs/curl/lib64/libcurl.a and b/libs/curl/lib64/libcurl.a differ diff --git a/libs/curl/lib64/libcurl.dll.a b/libs/curl/lib64/libcurl.dll.a new file mode 100644 index 000000000..d83f092d5 Binary files /dev/null and b/libs/curl/lib64/libcurl.dll.a differ diff --git a/libs/libgme.props b/libs/libgme.props new file mode 100644 index 000000000..209f6b9a8 --- /dev/null +++ b/libs/libgme.props @@ -0,0 +1,16 @@ + + + + + + $(SolutionDir)libs\gme\include;$(IncludePath) + $(SolutionDir)libs\gme\win32;$(LibraryPath) + $(SolutionDir)libs\gme\win64;$(LibraryPath) + + + + libgme.dll.a;%(AdditionalDependencies) + + + + \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2f97c173c..c0d673a6f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -220,6 +220,8 @@ set(SRB2_CONFIG_HAVE_ZLIB ON CACHE BOOL "Enable zlib support.") set(SRB2_CONFIG_HAVE_GME ON CACHE BOOL "Enable GME support.") +set(SRB2_CONFIG_HAVE_CURL ON CACHE BOOL + "Enable curl support, used for downloading files via HTTP.") set(SRB2_CONFIG_HWRENDER ON CACHE BOOL "Enable hardware rendering through OpenGL.") set(SRB2_CONFIG_USEASM OFF CACHE BOOL @@ -391,6 +393,26 @@ if(${SRB2_CONFIG_HAVE_PNG} AND ${SRB2_CONFIG_HAVE_ZLIB}) endif() endif() +if(${SRB2_CONFIG_HAVE_CURL}) + if(${SRB2_CONFIG_USE_INTERNAL_LIBRARIES}) + set(CURL_FOUND ON) + set(CURL_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/libs/curl) + if(${SRB2_SYSTEM_BITS} EQUAL 64) + set(CURL_LIBRARIES "-L${CMAKE_SOURCE_DIR}/libs/curl/lib64 -lcurl") + else() # 32-bit + set(CURL_LIBRARIES "-L${CMAKE_SOURCE_DIR}/libs/curl/lib32 -lcurl") + endif() + else() + find_package(CURL) + endif() + if(${CURL_FOUND}) + set(SRB2_HAVE_CURL ON) + add_definitions(-DHAVE_CURL) + else() + message(WARNING "You have specified that CURL is available but it was not found. SRB2Kart may not compile correctly.") + endif() +endif() + if(${SRB2_CONFIG_HWRENDER}) add_definitions(-DHWRENDER) set(SRB2_HWRENDER_SOURCES @@ -414,7 +436,6 @@ if(${SRB2_CONFIG_HWRENDER}) ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_defs.h ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_dll.h ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_drv.h - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_glide.h ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_glob.h ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_light.h ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_main.h diff --git a/src/Makefile b/src/Makefile index 214c2bf7a..8eda8c400 100644 --- a/src/Makefile +++ b/src/Makefile @@ -267,6 +267,7 @@ endif ifdef NONET OPTS+=-DNONET + NOCURL=1 else ifdef NO_IPV6 OPTS+=-DNO_IPV6 @@ -369,6 +370,16 @@ else NOPNG=1 endif +ifndef NOCURL +OPTS+=-DHAVE_CURL +CURLCONFIG?=curl-config +CURL_CFLAGS?=$(shell $(CURLCONFIG) --cflags) +CURL_LDFLAGS?=$(shell $(CURLCONFIG) --libs) + +LIBS+=$(CURL_LDFLAGS) +CFLAGS+=$(CURL_CFLAGS) +endif + ifdef STATIC LIBS:=-static $(LIBS) endif @@ -741,8 +752,8 @@ ifdef SDL ifdef MINGW $(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \ doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \ - command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \ - hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \ + command.h hardware/hw_data.h hardware/hw_defs.h hardware/hw_md2.h \ + hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \ hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \ am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \ p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h @@ -750,8 +761,8 @@ $(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h else $(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \ doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \ - command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \ - hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \ + command.h hardware/hw_data.h hardware/hw_defs.h hardware/hw_md2.h \ + hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \ hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \ am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \ p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h @@ -904,8 +915,8 @@ ifndef SDL ifndef NOHW $(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \ doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \ - command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \ - hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \ + command.h hardware/hw_data.h hardware/hw_defs.h hardware/hw_md2.h \ + hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \ hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \ am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \ p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h @@ -913,8 +924,8 @@ $(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h $(OBJDIR)/ogl_win.o: hardware/r_opengl/ogl_win.c hardware/r_opengl/r_opengl.h \ doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \ - command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \ - hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \ + command.h hardware/hw_data.h hardware/hw_defs.h hardware/hw_md2.h \ + hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \ hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \ am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \ p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h @@ -922,8 +933,8 @@ $(OBJDIR)/ogl_win.o: hardware/r_opengl/ogl_win.c hardware/r_opengl/r_opengl.h \ $(OBJDIR)/r_minigl.o: hardware/r_minigl/r_minigl.c hardware/r_opengl/r_opengl.h \ doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \ - command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \ - hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \ + command.h hardware/hw_data.h hardware/hw_defs.h hardware/hw_md2.h \ + hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \ hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \ am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \ p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h diff --git a/src/Makefile.cfg b/src/Makefile.cfg index 8402e349f..ff4d2bac1 100644 --- a/src/Makefile.cfg +++ b/src/Makefile.cfg @@ -222,7 +222,7 @@ endif ifdef GCC71 WFLAGS+=-Wno-error=implicit-fallthrough WFLAGS+=-Wno-implicit-fallthrough - WFLAGS+=-Wno-error=format-truncation + WFLAGS+=-Wno-format-truncation endif ifdef GCC80 WFLAGS+=-Wno-error=format-overflow diff --git a/src/command.c b/src/command.c index dff83c2cc..cf60a086e 100644 --- a/src/command.c +++ b/src/command.c @@ -86,7 +86,7 @@ static boolean joyaxis_default[4] = {false,false,false,false}; static INT32 joyaxis_count[4] = {0,0,0,0}; #endif -#define COM_BUF_SIZE 8192 // command buffer size +#define COM_BUF_SIZE 0x4000 // command buffer size, 0x4000 = 16384 #define MAX_ALIAS_RECURSION 100 // max recursion allowed for aliases static INT32 com_wait; // one command per frame (for cmd sequences) @@ -532,7 +532,6 @@ static void COM_ExecuteString(char *ptext) { if (!stricmp(com_argv[0], cmd->name)) //case insensitive now that we have lower and uppercase! { - recursion = 0; cmd->function(); return; } @@ -544,7 +543,7 @@ static void COM_ExecuteString(char *ptext) if (!stricmp(com_argv[0], a->name)) { if (recursion > MAX_ALIAS_RECURSION) - { + { CONS_Alert(CONS_WARNING, M_GetText("Alias recursion cycle detected!\n")); recursion = 0; } @@ -586,8 +585,6 @@ static void COM_ExecuteString(char *ptext) } } - recursion = 0; - // check cvars // Hurdler: added at Ebola's request ;) // (don't flood the console in software mode with bad gr_xxx command) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index e09518e78..ccbd21e1d 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -170,6 +170,8 @@ consvar_t cv_showjoinaddress = {"showjoinaddress", "On", CV_SAVE, CV_OnOff, NULL static CV_PossibleValue_t playbackspeed_cons_t[] = {{1, "MIN"}, {10, "MAX"}, {0, NULL}}; consvar_t cv_playbackspeed = {"playbackspeed", "1", 0, playbackspeed_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_httpsource = {"http_source", "", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; + static inline void *G_DcpyTiccmd(void* dest, const ticcmd_t* src, const size_t n) { const size_t d = n / sizeof(ticcmd_t); @@ -673,7 +675,7 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i) static void resynch_read_player(resynch_pak *rsp) { INT32 i = rsp->playernum, j; - mobj_t *savedmo = players[i].mo; + //mobj_t *savedmo = players[i].mo; // Do not send anything visual related. // Only send data that we need to know for physics. @@ -766,11 +768,17 @@ static void resynch_read_player(resynch_pak *rsp) return; //...but keep old mo even if it is corrupt or null! - players[i].mo = savedmo; + //players[i].mo = savedmo; //Transfer important mo information if they have a valid mo. if (!rsp->hasmo) + { + // Get rid of their object if they aren't supposed to have one.....?? + if (players[i].mo) + P_RemoveMobj(players[i].mo); + return; + } //server thinks player has a body. //Give them a new body that can be then manipulated by the server's info. @@ -1023,6 +1031,7 @@ static void SV_SendResynch(INT32 node) return; } + resynch_inprogress[node] = false; // Let's see if there's REALLY anyone left to sync..... netbuffer->packettype = PT_RESYNCHING; for (i = 0, j = 0; i < MAXPLAYERS; ++i) { @@ -1030,10 +1039,24 @@ static void SV_SendResynch(INT32 node) if (!(resynch_status[node] & 1< TICRATE) + { + CONS_Alert(CONS_ERROR, "Node %d (%s) somehow had a stupidly-long resync delay?! (%d tics to resync player %d)\n", + node, player_names[nodetoplayer[node]], resynch_sent[node][i], i + ); + resynch_sent[node][i] = TICRATE; + } + continue; } @@ -1047,6 +1070,15 @@ static void SV_SendResynch(INT32 node) break; } + if (!resynch_inprogress[node]) + { + CONS_Alert(CONS_ERROR, "Node %d (%s) somehow had resync status for nonexistent players?! (%08x)\n", + node, player_names[nodetoplayer[node]], resynch_status[node] = 0x00 + ); + resynch_status[node] = 0x00; + resynch_inprogress[node] = true; // So they get the PT_RESYNCHEND... + } + if (resynch_score[node] > (unsigned)cv_resynchattempts.value*250) { XBOXSTATIC UINT8 buf[2]; @@ -1103,6 +1135,10 @@ typedef enum CL_ASKFULLFILELIST, CL_ASKDOWNLOADFILES, CL_WAITDOWNLOADFILESRESPONSE, +#ifdef HAVE_CURL + CL_PREPAREHTTPFILES, + CL_DOWNLOADHTTPFILES, +#endif CL_CHALLENGE } cl_mode_t; @@ -1117,6 +1153,11 @@ static UINT8 cl_challengequestion[MD5_LEN+1]; static char cl_challengepassword[65]; static UINT8 cl_challengeanswer[MD5_LEN+1]; static UINT8 cl_challengeattempted = 0; +static char cl_challengeaddress[64]; + +#ifdef HAVE_CURL +char http_source[MAX_MIRROR_LENGTH]; +#endif // Player name send/load @@ -1171,7 +1212,11 @@ static inline void CL_DrawConnectionStatus(void) M_DrawTextBox(BASEVIDWIDTH/2-128-8, BASEVIDHEIGHT-24-8, 32, 1); V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-24-24, V_YELLOWMAP, "Press ESC to abort"); - if (cl_mode != CL_DOWNLOADFILES) + if (cl_mode != CL_DOWNLOADFILES +#ifdef HAVE_CURL + && cl_mode != CL_DOWNLOADHTTPFILES +#endif + ) { INT32 i, animtime = ((ccstime / 4) & 15) + 16; UINT8 palstart = (cl_mode == CL_SEARCHING) ? 128 : 160; @@ -1238,6 +1283,9 @@ static inline void CL_DrawConnectionStatus(void) break; case CL_ASKDOWNLOADFILES: case CL_WAITDOWNLOADFILESRESPONSE: +#ifdef HAVE_CURL + case CL_PREPAREHTTPFILES: +#endif cltext = M_GetText("Waiting to download files..."); default: cltext = M_GetText("Connecting to server..."); @@ -1322,22 +1370,34 @@ static boolean CL_SendJoin(void) localplayers++; netbuffer->u.clientcfg.localplayers = localplayers; + netbuffer->u.clientcfg._255 = 255; + netbuffer->u.clientcfg.packetversion = PACKETVERSION; netbuffer->u.clientcfg.version = VERSION; netbuffer->u.clientcfg.subversion = SUBVERSION; + strncpy(netbuffer->u.clientcfg.application, SRB2APPLICATION, + sizeof netbuffer->u.clientcfg.application); netbuffer->u.clientcfg.needsdownload = cl_needsdownload; netbuffer->u.clientcfg.challengenum = cl_challengenum; memcpy(netbuffer->u.clientcfg.challengeanswer, cl_challengeanswer, MD5_LEN); - return HSendPacket(servernode, true, 0, sizeof (clientconfig_pak)); + return HSendPacket(servernode, false, 0, sizeof (clientconfig_pak)); } static void SV_SendServerInfo(INT32 node, tic_t servertime) { UINT8 *p; +#ifdef HAVE_CURL + size_t mirror_length; + const char *httpurl = cv_httpsource.string; +#endif 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); @@ -1366,6 +1426,7 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime) netbuffer->u.serverinfo.iszone = 0; memset(netbuffer->u.serverinfo.maptitle, 0, 33); + memset(netbuffer->u.serverinfo.httpsource, 0, MAX_MIRROR_LENGTH); if (!(mapheaderinfo[gamemap-1]->menuflags & LF2_HIDEINMENU) && mapheaderinfo[gamemap-1]->lvlttl[0]) { @@ -1417,6 +1478,21 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime) netbuffer->u.serverinfo.actnum = 0; //mapheaderinfo[gamemap-1]->actnum +#ifdef HAVE_CURL + if (! D_IsJoinPasswordOn()) + { + mirror_length = strlen(httpurl); + if (mirror_length > MAX_MIRROR_LENGTH) + mirror_length = MAX_MIRROR_LENGTH; + + if (snprintf(netbuffer->u.serverinfo.httpsource, mirror_length+1, "%s", httpurl) < 0) + // If there's an encoding error, send nothing, we accept that the above may be truncated + strncpy(netbuffer->u.serverinfo.httpsource, "", mirror_length); + + netbuffer->u.serverinfo.httpsource[MAX_MIRROR_LENGTH-1] = '\0'; + } +#endif + p = PutFileNeeded(0); HSendPacket(node, false, 0, p - ((UINT8 *)&netbuffer->u)); @@ -1807,12 +1883,21 @@ static void SL_InsertServer(serverinfo_pak* info, SINT8 node) if (serverlistcount >= MAXSERVERLIST) return; // list full + if (info->_255 != 255) + return;/* old packet format */ + + if (info->packetversion != PACKETVERSION) + return;/* old new packet format */ + if (info->version != VERSION) return; // Not same version. if (info->subversion != SUBVERSION) return; // Close, but no cigar. + if (strcmp(info->application, SRB2APPLICATION)) + return;/* that's a different mod */ + i = serverlistcount++; } @@ -1850,7 +1935,7 @@ void CL_UpdateServerList(boolean internetsearch, INT32 room) { char version[8] = ""; #if VERSION > 0 || SUBVERSION > 0 - snprintf(version, sizeof (version), "%d.%d.%d", VERSION/100, VERSION%100, SUBVERSION); + snprintf(version, sizeof (version), "%d.%d", VERSION, SUBVERSION); #else strcpy(version, GetRevisionString()); #endif @@ -1930,27 +2015,7 @@ static boolean CL_FinishedFileList(void) else if (i == 1) cl_mode = CL_ASKJOIN; else - { - // must download something - // can we, though? - if (!CL_CheckDownloadable()) // nope! - { - D_QuitNetGame(); - CL_Reset(); - D_StartTitle(); - M_StartMessage(M_GetText( - "You cannot connect to this server\n" - "because you cannot download the files\n" - "that you are missing from the server.\n\n" - "See the console or log file for\n" - "more details.\n\n" - "Press ESC\n" - ), NULL, MM_NOTHING); - return false; - } - cl_mode = CL_ASKDOWNLOADFILES; - } return true; } @@ -2073,6 +2138,46 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic } break; +#ifdef HAVE_CURL + case CL_PREPAREHTTPFILES: + { + for (i = 0; i < fileneedednum; i++) + if (fileneeded[i].status == FS_NOTFOUND || fileneeded[i].status == FS_MD5SUMBAD) + curl_transfers++; + + cl_mode = CL_DOWNLOADHTTPFILES; + } + break; + + case CL_DOWNLOADHTTPFILES: + waitmore = false; + for (i = 0; i < fileneedednum; i++) + if (fileneeded[i].status == FS_NOTFOUND || fileneeded[i].status == FS_MD5SUMBAD) + { + if (!curl_running) + CURLPrepareFile(http_source, i); + waitmore = true; + break; + } + + if (curl_running) + CURLGetFile(); + + if (waitmore) + break; // exit the case + + if (curl_failedwebdownload && !curl_transfers) + { + CONS_Printf("One or more files failed to download, falling back to internal downloader\n"); + cl_mode = CL_ASKDOWNLOADFILES; + break; + } + + if (!curl_transfers) + cl_mode = CL_ASKJOIN; // don't break case continue to cljoin request now + + break; +#endif case CL_DOWNLOADFILES: waitmore = false; for (i = 0; i < fileneedednum; i++) @@ -2245,6 +2350,8 @@ boolean CL_Responder(event_t *ev) #ifndef NONET SL_ClearServerList(servernode); + if (I_NetMakeNodewPort) + servernode = I_NetMakeNode(cl_challengeaddress); #endif cl_mode = CL_SEARCHING; @@ -2300,6 +2407,8 @@ static void CL_ConnectToServer(boolean viams) if (gamestate == GS_VOTING) Y_EndVote(); + resynch_local_inprogress = false; // Just in case this was never cleared... + DEBFILE(va("waiting %d nodes\n", doomcom->numnodes)); G_SetGamestate(GS_WAITINGPLAYERS); wipegamestate = GS_WAITINGPLAYERS; @@ -2324,8 +2433,8 @@ static void CL_ConnectToServer(boolean viams) gametypestr = Gametype_Names[num]; if (gametypestr) 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); + CONS_Printf(M_GetText("Version: %d.%d\n"), + serverlist[i].info.version, serverlist[i].info.subversion); } SL_ClearServerList(servernode); #endif @@ -2751,6 +2860,13 @@ void CL_Reset(void) fileneedednum = 0; memset(fileneeded, 0, sizeof(fileneeded)); +#ifdef HAVE_CURL + curl_failedwebdownload = false; + curl_transfers = 0; + curl_running = false; + http_source[0] = '\0'; +#endif + // D_StartTitle should get done now, but the calling function will handle it } @@ -3235,8 +3351,8 @@ static void Got_RemovePlayer(UINT8 **p, INT32 playernum); // called one time at init void D_ClientServerInit(void) { - DEBFILE(va("- - -== SRB2Kart v%d.%.2d.%d "VERSIONSTRING" debugfile ==- - -\n", - VERSION/100, VERSION%100, SUBVERSION)); + DEBFILE(va("- - -== SRB2Kart v%d.%d "VERSIONSTRING" debugfile ==- - -\n", + VERSION, SUBVERSION)); #ifndef NONET COM_AddCommand("getplayernum", Command_GetPlayerNum); @@ -3396,6 +3512,7 @@ void D_QuitNetGame(void) HSendPacket(servernode, true, 0, 0); } + resynch_local_inprogress = false; // No more resyncing! D_CloseConnection(); ClearAdminPlayers(); @@ -3729,9 +3846,15 @@ static void HandleConnect(SINT8 node) if (bannednode && bannednode[node]) SV_SendRefuse(node, M_GetText("You have been banned\nfrom the server")); + else if (netbuffer->u.clientcfg._255 != 255 || + netbuffer->u.clientcfg.packetversion != PACKETVERSION) + SV_SendRefuse(node, "Incompatible packet formats."); + else if (strncmp(netbuffer->u.clientcfg.application, SRB2APPLICATION, + sizeof netbuffer->u.clientcfg.application)) + SV_SendRefuse(node, "Different SRB2 modifications\nare not compatible."); else if (netbuffer->u.clientcfg.version != VERSION || netbuffer->u.clientcfg.subversion != SUBVERSION) - SV_SendRefuse(node, va(M_GetText("Different SRB2Kart versions cannot\nplay a netgame!\n(server version %d.%d.%d)"), VERSION/100, VERSION%100, SUBVERSION)); + SV_SendRefuse(node, va(M_GetText("Different SRB2Kart versions cannot\nplay a netgame!\n(server version %d.%d)"), VERSION, SUBVERSION)); else if (!cv_allownewplayer.value && node) SV_SendRefuse(node, M_GetText("The server is not accepting\njoins for the moment")); else if (D_NumPlayers() >= maxplayers) @@ -3761,7 +3884,7 @@ static void HandleConnect(SINT8 node) D_MakeJoinPasswordChallenge(&netbuffer->u.joinchallenge.challengenum, netbuffer->u.joinchallenge.question); netbuffer->packettype = PT_JOINCHALLENGE; - HSendPacket(node, true, 0, sizeof(joinchallenge_pak)); + HSendPacket(node, false, 0, sizeof(joinchallenge_pak)); Net_CloseConnection(node); return; @@ -3771,7 +3894,9 @@ static void HandleConnect(SINT8 node) if (netbuffer->u.clientcfg.needsdownload) { netbuffer->packettype = PT_DOWNLOADFILESOKAY; - HSendPacket(node, true, 0, 0); + strncpy(netbuffer->u.filecfg.http_source, cv_httpsource.string, + MAX_MIRROR_LENGTH); + HSendPacket(node, true, 0, sizeof netbuffer->u.filecfg); return; } @@ -3873,6 +3998,8 @@ static void HandleServerInfo(SINT8 node) 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.gametype = (UINT8)((netbuffer->u.serverinfo.gametype == VANILLA_GT_MATCH) ? GT_MATCH : GT_RACE); SL_InsertServer(&netbuffer->u.serverinfo, node); @@ -3984,7 +4111,9 @@ static void HandlePacketFromAwayNode(SINT8 node) cl_challengenum = netbuffer->u.joinchallenge.challengenum; memcpy(cl_challengequestion, netbuffer->u.joinchallenge.question, 16); - Net_CloseConnection(node|FORCECLOSE); // Don't need to stay connected while challenging + if (I_GetNodeAddress) + strcpy(cl_challengeaddress, I_GetNodeAddress(node)); + Net_CloseConnection(node); // Don't need to stay connected while challenging cl_mode = CL_CHALLENGE; @@ -3993,7 +4122,14 @@ static void HandlePacketFromAwayNode(SINT8 node) case 2: // We already sent a correct password, so throw it back up again. D_ComputeChallengeAnswer(cl_challengequestion, cl_challengepassword, cl_challengeanswer); - cl_mode = CL_ASKJOIN; +#ifndef NONET + if (I_NetMakeNodewPort) + servernode = I_NetMakeNode(cl_challengeaddress); +#endif + if (cl_needsdownload) + cl_mode = CL_ASKDOWNLOADFILES; + else + cl_mode = CL_ASKJOIN; break; case 1: @@ -4046,30 +4182,52 @@ static void HandlePacketFromAwayNode(SINT8 node) SERVERONLY - // This should've already been checked, but just to be safe... - if (!CL_CheckDownloadable()) + if (netbuffer->u.filecfg.http_source[0] != '\0') { - D_QuitNetGame(); - CL_Reset(); - D_StartTitle(); - M_StartMessage(M_GetText( - "You cannot connect to this server\n" - "because you cannot download the files\n" - "that you are missing from the server.\n\n" - "See the console or log file for\n" - "more details.\n\n" - "Press ESC\n" - ), NULL, MM_NOTHING); - break; + netbuffer->u.filecfg.http_source[MAX_MIRROR_LENGTH-1] = '\0'; + +#ifdef HAVE_CURL + if (! curl_failedwebdownload) + { + strncpy(http_source, netbuffer->u.filecfg.http_source, + sizeof http_source); + + cl_mode = CL_PREPAREHTTPFILES; + } +#else + CONS_Printf("We received a http url from the server, however it will not be used as this build lacks curl support (%s)\n", netbuffer->u.filecfg.http_source); +#endif + } + + if (cl_mode == CL_WAITDOWNLOADFILESRESPONSE) + { + if (CL_CheckDownloadable()) + { + CONS_Printf("trying to download\n"); + if (CL_SendRequestFile()) + cl_mode = CL_DOWNLOADFILES; + } + else + { + D_QuitNetGame(); + CL_Reset(); + D_StartTitle(); + M_StartMessage(M_GetText( + "You cannot connect to this server\n" + "because you cannot download the files\n" + "that you are missing from the server.\n\n" + "See the console or log file for\n" + "more details.\n\n" + "Press ESC\n" + ), NULL, MM_NOTHING); + break; + } } if (cl_challengeattempted == 1) // Successful password noise. S_StartSound(NULL, sfx_s221); cl_challengeattempted = 2; - CONS_Printf("trying to download\n"); - if (CL_SendRequestFile()) - cl_mode = CL_DOWNLOADFILES; break; case PT_SERVERCFG: // Positive response of client join request @@ -4914,6 +5072,20 @@ static void CL_SendClientKeepAlive(void) 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) { @@ -5160,7 +5332,7 @@ static void Local_Maketic(INT32 realtics) void SV_SpawnPlayer(INT32 playernum, INT32 x, INT32 y, angle_t angle) { tic_t tic; - UINT8 numadjust = 0; + UINT16 numadjust = 0; (void)x; (void)y; @@ -5431,9 +5603,6 @@ void NetKeepAlive(void) UpdatePingTable(); - if (server) - CL_SendClientKeepAlive(); - // Sryder: What is FILESTAMP??? FILESTAMP GetPackets(); @@ -5447,6 +5616,11 @@ FILESTAMP 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(); diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 27260ca99..0f4ca3792 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -21,6 +21,13 @@ #include "md5.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. +*/ +#define PACKETVERSION 0 + // Network play related stuff. // There is a data struct that stores network // communication related stuff, and another @@ -345,8 +352,13 @@ typedef struct { #pragma warning(default : 4200) #endif +#define MAXAPPLICATION 16 + typedef struct { + UINT8 _255;/* see serverinfo_pak */ + UINT8 packetversion; + char application[MAXAPPLICATION]; UINT8 version; // Different versions don't work UINT8 subversion; // Contains build version UINT8 localplayers; @@ -368,9 +380,18 @@ typedef struct #define MAXSERVERNAME 32 #define MAXFILENEEDED 915 +#define MAX_MIRROR_LENGTH 256 // 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; @@ -380,7 +401,6 @@ typedef struct UINT8 cheatsenabled; UINT8 kartvars; // Previously isdedicated, now appropriated for our own nefarious purposes UINT8 fileneedednum; - SINT8 adminplayer; tic_t time; tic_t leveltime; char servername[MAXSERVERNAME]; @@ -389,6 +409,7 @@ typedef struct unsigned char mapmd5[16]; UINT8 actnum; UINT8 iszone; + char httpsource[MAX_MIRROR_LENGTH]; // HTTP URL to download from, always defined for compatibility UINT8 fileneeded[MAXFILENEEDED]; // is filled with writexxx (byteptr.h) } ATTRPACK serverinfo_pak; @@ -441,6 +462,11 @@ typedef struct UINT8 files[MAXFILENEEDED]; // is filled with writexxx (byteptr.h) } ATTRPACK filesneededconfig_pak; +typedef struct +{ + char http_source[MAX_MIRROR_LENGTH];/* first byte 0? no die! */ +} ATTRPACK fileconfig; + // // Network packet data // @@ -475,6 +501,7 @@ typedef struct plrconfig playerconfig[MAXPLAYERS]; // (up to) 528 bytes(?) INT32 filesneedednum; // 4 bytes filesneededconfig_pak filesneededcfg; // ??? bytes + fileconfig filecfg; UINT32 pingtable[MAXPLAYERS+1]; // 68 bytes } u; // This is needed to pack diff packet types data together } ATTRPACK doomdata_t; @@ -496,7 +523,7 @@ extern INT32 mapchangepending; // Points inside doomcom extern doomdata_t *netbuffer; - +extern consvar_t cv_httpsource; extern consvar_t cv_showjoinaddress; extern consvar_t cv_playbackspeed; diff --git a/src/d_main.c b/src/d_main.c index 9c63bd91c..b6347f9f2 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -180,6 +180,7 @@ void D_PostEvent_end(void) {}; #endif // modifier keys +// Now handled in I_OsPolling UINT8 shiftdown = 0; // 0x1 left, 0x2 right UINT8 ctrldown = 0; // 0x1 left, 0x2 right UINT8 altdown = 0; // 0x1 left, 0x2 right @@ -226,9 +227,6 @@ void D_ProcessEvents(void) { ev = &events[eventtail]; - // Set global shift/ctrl/alt down variables - D_ModifierKeyResponder(ev); // never eats events - // Screenshots over everything so that they can be taken anywhere. if (M_ScreenshotResponder(ev)) continue; // ate the event @@ -281,29 +279,29 @@ static void D_Display(void) INT32 wipedefindex = 0; UINT8 i; - if (dedicated) - return; - - if (nodrawers) - return; // for comparative timing/profiling - - // check for change of screen size (video mode) - if (setmodeneeded && !wipe) - SCR_SetMode(); // change video mode - - if (vid.recalc) - SCR_Recalc(); // NOTE! setsizeneeded is set by SCR_Recalc() - - // change the view size if needed - if (setsizeneeded) + if (!dedicated) { - R_ExecuteSetViewSize(); - forcerefresh = true; // force background redraw - } + if (nodrawers) + return; // for comparative timing/profiling + + // check for change of screen size (video mode) + if (setmodeneeded && !wipe) + SCR_SetMode(); // change video mode - // draw buffered stuff to screen - // Used only by linux GGI version - I_UpdateNoBlit(); + if (vid.recalc) + SCR_Recalc(); // NOTE! setsizeneeded is set by SCR_Recalc() + + // change the view size if needed + if (setsizeneeded) + { + R_ExecuteSetViewSize(); + forcerefresh = true; // force background redraw + } + + // draw buffered stuff to screen + // Used only by linux GGI version + I_UpdateNoBlit(); + } // save the current screen if about to wipe wipe = (gamestate != wipegamestate); @@ -321,7 +319,7 @@ static void D_Display(void) wipedefindex = wipe_multinter_toblack; } - if (rendermode != render_none) + if (!dedicated) { // Fade to black first if (gamestate != GS_LEVEL // fades to black on its own timing, always @@ -341,8 +339,16 @@ static void D_Display(void) F_WipeStartScreen(); } + else //dedicated servers + { + F_RunWipe(wipedefs[wipedefindex], gamestate != GS_TIMEATTACK); + wipegamestate = gamestate; + } } + if (dedicated) //bail out after wipe logic + return; + // do buffered drawing switch (gamestate) { @@ -618,9 +624,6 @@ void D_SRB2Loop(void) // Pushing of + parameters is now done back in D_SRB2Main, not here. - CONS_Printf("I_StartupKeyboard()...\n"); - I_StartupKeyboard(); - #ifdef _WINDOWS CONS_Printf("I_StartupMouse()...\n"); I_DoStartupMouse(); @@ -1306,6 +1309,14 @@ void D_SRB2Main(void) CONS_Printf("I_StartupGraphics()...\n"); I_StartupGraphics(); +#ifdef HWRENDER + if (rendermode == render_opengl) + { + for (i = 0; i < numwadfiles; i++) + HWR_LoadShaders(i, (wadfiles[i]->type == RET_PK3)); + } +#endif + //--------------------------------------------------------- CONSOLE // setup loading screen SCR_Startup(); diff --git a/src/d_net.c b/src/d_net.c index 8c9c3e955..09b6b043d 100644 --- a/src/d_net.c +++ b/src/d_net.c @@ -339,6 +339,7 @@ static boolean Processackpak(void) { UINT8 ack = netbuffer->ack; getackpacket++; + if (cmpack(ack, node->firstacktosend) <= 0) { DEBFILE(va("Discard(1) ack %d (duplicated)\n", ack)); @@ -361,6 +362,7 @@ static boolean Processackpak(void) // Is a good packet so increment the acknowledge number, // Then search for a "hole" in the queue UINT8 nextfirstack = (UINT8)(node->firstacktosend + 1); + if (!nextfirstack) nextfirstack = 1; @@ -779,6 +781,8 @@ static const char *packettypename[NUMPACKETTYPE] = { "NOTHING", "SERVERCFG", + + "CLIENTCMD", "CLIENTMIS", "CLIENT2CMD", @@ -799,6 +803,9 @@ static const char *packettypename[NUMPACKETTYPE] = "RESYNCHEND", "RESYNCHGET", + + + "CLIENT3CMD", "CLIENT3MIS", "CLIENT4CMD", @@ -809,13 +816,20 @@ static const char *packettypename[NUMPACKETTYPE] = "DOWNLOADFILESOKAY", "FILEFRAGMENT", + "TEXTCMD", "TEXTCMD2", "TEXTCMD3", "TEXTCMD4", + "CLIENTJOIN", "NODETIMEOUT", "RESYNCHING", + + + "TELLFILESNEEDED", + "MOREFILESNEEDED", + "PING" }; @@ -1070,6 +1084,10 @@ boolean HSendPacket(INT32 node, boolean reliable, UINT8 acknum, size_t packetlen netbuffer->checksum = NetbufferChecksum(); sendbytes += packetheaderlength + doomcom->datalength; // For stat + // Joinpasswords close nodes, this may try to send to a waiting-to-close node, so cancel closing? + if (netbuffer->packettype == PT_CLIENTJOIN) + nodes[node].flags &= ~NF_CLOSE; + #ifdef PACKETDROP // Simulate internet :) //if (rand() >= (INT32)(RAND_MAX * (PACKETLOSSRATE / 100.f))) @@ -1106,7 +1124,7 @@ boolean HSendPacket(INT32 node, boolean reliable, UINT8 acknum, size_t packetlen // boolean HGetPacket(void) { - //boolean nodejustjoined; + boolean nodejustjoined; // Get a packet from self if (rebound_tail != rebound_head) @@ -1133,11 +1151,56 @@ boolean HGetPacket(void) while(true) { - //nodejustjoined = I_NetGet(); - I_NetGet(); + nodejustjoined = I_NetGet(); + //I_NetGet(); if (doomcom->remotenode == -1) // No packet received - return false; + { + if (nodejustjoined) // _This_ means we did receive a packet, but either from a node we couldn't allocate or a gone player ackreting... + continue; + else + return false; + } + + if (nodejustjoined) + { + // If a new node sends an unexpected packet, just ignore it + if (server + && !(netbuffer->packettype == PT_ASKINFO + || netbuffer->packettype == PT_SERVERINFO + || netbuffer->packettype == PT_PLAYERINFO + || netbuffer->packettype == PT_REQUESTFILE + || netbuffer->packettype == PT_ASKINFOVIAMS + || netbuffer->packettype == PT_CLIENTJOIN + || netbuffer->packettype == PT_TELLFILESNEEDED + || netbuffer->packettype == PT_CLIENTCMD)) + { + DEBFILE(va("New node sent an unexpected %s packet\n", packettypename[netbuffer->packettype])); + CONS_Alert(CONS_NOTICE, "New node sent an unexpected %s packet\n", packettypename[netbuffer->packettype]); + Net_CloseConnection(doomcom->remotenode | FORCECLOSE); + continue; + } + + // UGLY PROBABLY-BAD HACK: If we get PT_CLIENTJOIN, assume this is an in-order packet? + if (netbuffer->packettype == PT_CLIENTJOIN) + nodes[doomcom->remotenode].firstacktosend = (UINT8)((netbuffer->ack-1+MAXACKTOSEND) % MAXACKTOSEND); + + if (netbuffer->ack > 1 && !(server && netbuffer->packettype == PT_CLIENTJOIN)) + { + DEBFILE("New node sent a packet with an out-of-sequence ack. Ghost connection? Ignoring...\n"); + CONS_Alert(CONS_NOTICE, "New node sent a packet with an out-of-sequence ack. Ghost connection? Ignoring...\n"); + Net_CloseConnection(doomcom->remotenode | FORCECLOSE); + continue; + } + + // Reinitialize vars for the new node just in case there's anything left over from other players..... + InitNode(&nodes[doomcom->remotenode]); + SV_AbortSendFiles(doomcom->remotenode); + } + + // Joinpasswords close nodes, this may receive from a waiting-to-close node, so cancel closing? + if (netbuffer->packettype == PT_CLIENTJOIN) + nodes[doomcom->remotenode].flags &= ~NF_CLOSE; getbytes += packetheaderlength + doomcom->datalength; // For stat @@ -1152,8 +1215,8 @@ boolean HGetPacket(void) if (netbuffer->checksum != NetbufferChecksum()) { DEBFILE("Bad packet checksum\n"); - //Net_CloseConnection(nodejustjoined ? (doomcom->remotenode | FORCECLOSE) : doomcom->remotenode); - Net_CloseConnection(doomcom->remotenode); + Net_CloseConnection(nodejustjoined ? (doomcom->remotenode | FORCECLOSE) : doomcom->remotenode); + //Net_CloseConnection(doomcom->remotenode); continue; } @@ -1162,21 +1225,6 @@ boolean HGetPacket(void) DebugPrintpacket("GET"); #endif - /*// If a new node sends an unexpected packet, just ignore it - if (nodejustjoined && server - && !(netbuffer->packettype == PT_ASKINFO - || netbuffer->packettype == PT_SERVERINFO - || netbuffer->packettype == PT_PLAYERINFO - || netbuffer->packettype == PT_REQUESTFILE - || netbuffer->packettype == PT_ASKINFOVIAMS - || netbuffer->packettype == PT_CLIENTJOIN)) - { - DEBFILE(va("New node sent an unexpected %s packet\n", packettypename[netbuffer->packettype])); - //CONS_Alert(CONS_NOTICE, "New node sent an unexpected %s packet\n", packettypename[netbuffer->packettype]); - Net_CloseConnection(doomcom->remotenode | FORCECLOSE); - continue; - }*/ - // Proceed the ack and ackreturn field if (!Processackpak()) continue; // discarded (duplicated) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index e77a93b72..1dc79f586 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -686,6 +686,7 @@ void D_RegisterServerCommands(void) CV_RegisterVar(&cv_maxsend); CV_RegisterVar(&cv_noticedownload); CV_RegisterVar(&cv_downloadspeed); + CV_RegisterVar(&cv_httpsource); #ifndef NONET CV_RegisterVar(&cv_allownewplayer); #ifdef VANILLAJOINNEXTROUND @@ -5340,11 +5341,11 @@ static void Fishcake_OnChange(void) static void Command_Isgamemodified_f(void) { if (majormods) - CONS_Printf("The game has been modified with major add-ons, so you cannot play Record Attack.\n"); + CONS_Printf("The game has been modified with major addons, so you cannot play Record Attack.\n"); else if (savemoddata) - CONS_Printf("The game has been modified with an add-on with its own save data, so you can play Record Attack and earn medals.\n"); + CONS_Printf("The game has been modified with an addon with its own save data, so you can play Record Attack and earn medals.\n"); else if (modifiedgame) - CONS_Printf("The game has been modified with only minor add-ons. You can play Record Attack, earn medals and unlock extras.\n"); + CONS_Printf("The game has been modified with only minor addons. You can play Record Attack, earn medals and unlock extras.\n"); else CONS_Printf("The game has not been modified. You can play Record Attack, earn medals and unlock extras.\n"); } diff --git a/src/d_netfil.c b/src/d_netfil.c index 76b66836b..821d2a5bc 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -42,6 +42,10 @@ #include #endif +#ifdef HAVE_CURL +#include "curl/curl.h" +#endif + #include "doomdef.h" #include "doomstat.h" #include "d_main.h" @@ -65,6 +69,11 @@ // Prototypes static boolean SV_SendFile(INT32 node, const char *filename, UINT8 fileid); +#ifdef HAVE_CURL +size_t curlwrite_data(void *ptr, size_t size, size_t nmemb, FILE *stream); +int curlprogress_callback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow); +#endif + // Sender structure typedef struct filetx_s { @@ -101,6 +110,22 @@ char downloaddir[512] = "DOWNLOAD"; INT32 lastfilenum = -1; #endif +#ifdef HAVE_CURL +static CURL *http_handle; +static CURLM *multi_handle; +boolean curl_running = false; +boolean curl_failedwebdownload = false; +static double curl_dlnow; +static double curl_dltotal; +static time_t curl_starttime; +INT32 curl_transfers = 0; +static int curl_runninghandles = 0; +static UINT32 curl_origfilesize; +static UINT32 curl_origtotalfilesize; +static char *curl_realname = NULL; +fileneeded_t *curl_curfile = NULL; +#endif + /** Fills a serverinfo packet with information about wad files loaded. * * \todo Give this function a better name since it is in global scope. @@ -238,10 +263,10 @@ boolean CL_CheckDownloadable(void) { CONS_Printf(" * \"%s\" (%dK)", fileneeded[i].filename, fileneeded[i].totalsize >> 10); - if (fileneeded[i].status == FS_NOTFOUND) - CONS_Printf(M_GetText(" not found, md5: ")); - else if (fileneeded[i].status == FS_MD5SUMBAD) + if (fileneeded[i].status == FS_MD5SUMBAD) CONS_Printf(M_GetText(" wrong version, md5: ")); + else + CONS_Printf(M_GetText(" not found, md5: ")); { INT32 j; @@ -296,7 +321,7 @@ boolean CL_SendRequestFile(void) netbuffer->packettype = PT_REQUESTFILE; p = (char *)netbuffer->u.textcmd; for (i = 0; i < fileneedednum; i++) - if ((fileneeded[i].status == FS_NOTFOUND || fileneeded[i].status == FS_MD5SUMBAD)) + if ((fileneeded[i].status == FS_NOTFOUND || fileneeded[i].status == FS_MD5SUMBAD || fileneeded[i].status == FS_FALLBACK)) { totalfreespaceneeded += fileneeded[i].totalsize; nameonly(fileneeded[i].filename); @@ -1015,3 +1040,153 @@ filestatus_t findfile(char *filename, const UINT8 *wantedmd5sum, boolean complet return (badmd5 ? FS_MD5SUMBAD : FS_NOTFOUND); // md5 sum bad or file not found } + +#ifdef HAVE_CURL +size_t curlwrite_data(void *ptr, size_t size, size_t nmemb, FILE *stream) +{ + size_t written; + written = fwrite(ptr, size, nmemb, stream); + return written; +} + +int curlprogress_callback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow) +{ + (void)clientp; + (void)ultotal; + (void)ulnow; // Function prototype requires these but we won't use, so just discard + curl_dlnow = dlnow; + curl_dltotal = dltotal; + getbytes = curl_dlnow / (time(NULL) - curl_starttime); // To-do: Make this more accurate??? + return 0; +} + +void CURLPrepareFile(const char* url, int dfilenum) +{ +#ifdef PARANOIA + if (M_CheckParm("-nodownload")) + I_Error("Attempted to download files in -nodownload mode"); +#endif + + curl_global_init(CURL_GLOBAL_ALL); + + http_handle = curl_easy_init(); + multi_handle = curl_multi_init(); + + if (http_handle && multi_handle) + { + I_mkdir(downloaddir, 0755); + + curl_curfile = &fileneeded[dfilenum]; + curl_realname = curl_curfile->filename; + nameonly(curl_realname); + + curl_origfilesize = curl_curfile->currentsize; + curl_origtotalfilesize = curl_curfile->totalsize; + + curl_easy_setopt(http_handle, CURLOPT_URL, va("%s/%s", url, curl_realname)); + + // Only allow HTTP and HTTPS + curl_easy_setopt(http_handle, CURLOPT_PROTOCOLS, CURLPROTO_HTTP|CURLPROTO_HTTPS); + + curl_easy_setopt(http_handle, CURLOPT_USERAGENT, va("SRB2Kart/v%d.%d.%d", VERSION/100, VERSION%100, SUBVERSION)); // Set user agent as some servers won't accept invalid user agents. + + // Follow a redirect request, if sent by the server. + curl_easy_setopt(http_handle, CURLOPT_FOLLOWLOCATION, 1L); + + curl_easy_setopt(http_handle, CURLOPT_FAILONERROR, 1L); + + CONS_Printf("Downloading %s from %s\n", curl_realname, url); + + strcatbf(curl_curfile->filename, downloaddir, "/"); + curl_curfile->file = fopen(curl_curfile->filename, "wb"); + curl_easy_setopt(http_handle, CURLOPT_WRITEDATA, curl_curfile->file); + curl_easy_setopt(http_handle, CURLOPT_WRITEFUNCTION, curlwrite_data); + curl_easy_setopt(http_handle, CURLOPT_NOPROGRESS, 0L); + curl_easy_setopt(http_handle, CURLOPT_PROGRESSFUNCTION, curlprogress_callback); + + curl_curfile->status = FS_DOWNLOADING; + lastfilenum = dfilenum; + curl_multi_add_handle(multi_handle, http_handle); + + curl_multi_perform(multi_handle, &curl_runninghandles); + curl_starttime = time(NULL); + curl_running = true; + } +} + +void CURLGetFile(void) +{ + CURLMcode mc; /* return code used by curl_multi_wait() */ + CURLcode easyres; /* Return from easy interface */ + int numfds; + CURLMsg *m; /* for picking up messages with the transfer status */ + CURL *e; + int msgs_left; /* how many messages are left */ + const char *easy_handle_error; + long response_code = 0; + + if (curl_runninghandles) + { + curl_multi_perform(multi_handle, &curl_runninghandles); + + /* wait for activity, timeout or "nothing" */ + mc = curl_multi_wait(multi_handle, NULL, 0, 1000, &numfds); + + if (mc != CURLM_OK) + { + CONS_Alert(CONS_WARNING, "curl_multi_wait() failed, code %d.\n", mc); + return; + } + curl_curfile->currentsize = curl_dlnow; + curl_curfile->totalsize = curl_dltotal; + } + + /* See how the transfers went */ + while ((m = curl_multi_info_read(multi_handle, &msgs_left))) + { + if (m && (m->msg == CURLMSG_DONE)) + { + e = m->easy_handle; + easyres = m->data.result; + if (easyres != CURLE_OK) + { + if (easyres == CURLE_HTTP_RETURNED_ERROR) + curl_easy_getinfo(e, CURLINFO_RESPONSE_CODE, &response_code); + + easy_handle_error = (response_code) ? va("HTTP reponse code %ld", response_code) : curl_easy_strerror(easyres); + curl_curfile->status = FS_FALLBACK; + curl_curfile->currentsize = curl_origfilesize; + curl_curfile->totalsize = curl_origtotalfilesize; + curl_failedwebdownload = true; + fclose(curl_curfile->file); + remove(curl_curfile->filename); + curl_curfile->file = NULL; + //nameonly(curl_curfile->filename); + nameonly(curl_realname); + CONS_Printf(M_GetText("Failed to download %s (%s)\n"), curl_realname, easy_handle_error); + } + else + { + nameonly(curl_realname); + CONS_Printf(M_GetText("Finished downloading %s\n"), curl_realname); + curl_curfile->status = FS_FOUND; + fclose(curl_curfile->file); + } + + curl_running = false; + curl_transfers--; + curl_multi_remove_handle(multi_handle, e); + curl_easy_cleanup(e); + + if (!curl_transfers) + break; + } + } + + if (!curl_transfers) + { + curl_multi_cleanup(multi_handle); + curl_global_cleanup(); + } +} +#endif diff --git a/src/d_netfil.h b/src/d_netfil.h index 2f0333311..f37df371f 100644 --- a/src/d_netfil.h +++ b/src/d_netfil.h @@ -30,7 +30,8 @@ typedef enum FS_REQUESTED, FS_DOWNLOADING, FS_OPEN, // Is opened and used in w_wad - FS_MD5SUMBAD + FS_MD5SUMBAD, + FS_FALLBACK, // HTTP failed } filestatus_t; typedef struct @@ -53,6 +54,12 @@ extern char downloaddir[512]; extern INT32 lastfilenum; #endif +#ifdef HAVE_CURL +extern boolean curl_failedwebdownload; +extern boolean curl_running; +extern INT32 curl_transfers; +#endif + UINT8 *PutFileNeeded(UINT16 firstfile); void D_ParseFileneeded(INT32 fileneedednum_parm, UINT8 *fileneededstr, UINT16 firstfile); void CL_PrepareDownloadSaveGame(const char *tmpsave); @@ -83,4 +90,9 @@ filestatus_t checkfilemd5(char *filename, const UINT8 *wantedmd5sum); void nameonly(char *s); size_t nameonlylength(const char *s); +#ifdef HAVE_CURL +void CURLPrepareFile(const char* url, int dfilenum); +void CURLGetFile(void); +#endif + #endif // __D_NETFIL__ diff --git a/src/dehacked.c b/src/dehacked.c index 05a8e1b1a..96d82fff4 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -42,10 +42,6 @@ #include "r_draw.h" // translation colormap consts (for lua) #endif -#ifdef HWRENDER -#include "hardware/hw_light.h" -#endif - #ifdef PC_DOS #include // for snprintf //int snprintf(char *str, size_t n, const char *fmt, ...); @@ -335,21 +331,6 @@ static INT32 searchvalue(const char *s) } } -#ifdef HWRENDER -static float searchfvalue(const char *s) -{ - while (s[0] != '=' && s[0]) - s++; - if (s[0] == '=') - return (float)atof(&s[1]); - else - { - deh_warning("No value found"); - return 0; - } -} -#endif - // These are for clearing all of various things static void clear_conditionsets(void) { @@ -854,128 +835,6 @@ static void readthing(MYFILE *f, INT32 num) Z_Free(s); } -#ifdef HWRENDER -static void readlight(MYFILE *f, INT32 num) -{ - char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); - char *word; - char *tmp; - INT32 value; - float fvalue; - - do - { - if (myfgets(s, MAXLINELEN, f)) - { - if (s[0] == '\n') - break; - - tmp = strchr(s, '#'); - if (tmp) - *tmp = '\0'; - if (s == tmp) - continue; // Skip comment lines, but don't break. - - fvalue = searchfvalue(s); - value = searchvalue(s); - - word = strtok(s, " "); - if (word) - strupr(word); - else - break; - - if (fastcmp(word, "TYPE")) - { - DEH_WriteUndoline(word, va("%d", lspr[num].type), UNDO_NONE); - lspr[num].type = (UINT16)value; - } - else if (fastcmp(word, "OFFSETX")) - { - DEH_WriteUndoline(word, va("%f", lspr[num].light_xoffset), UNDO_NONE); - lspr[num].light_xoffset = fvalue; - } - else if (fastcmp(word, "OFFSETY")) - { - DEH_WriteUndoline(word, va("%f", lspr[num].light_yoffset), UNDO_NONE); - lspr[num].light_yoffset = fvalue; - } - else if (fastcmp(word, "CORONACOLOR")) - { - DEH_WriteUndoline(word, va("%u", lspr[num].corona_color), UNDO_NONE); - lspr[num].corona_color = value; - } - else if (fastcmp(word, "CORONARADIUS")) - { - DEH_WriteUndoline(word, va("%f", lspr[num].corona_radius), UNDO_NONE); - lspr[num].corona_radius = fvalue; - } - else if (fastcmp(word, "DYNAMICCOLOR")) - { - DEH_WriteUndoline(word, va("%u", lspr[num].dynamic_color), UNDO_NONE); - lspr[num].dynamic_color = value; - } - else if (fastcmp(word, "DYNAMICRADIUS")) - { - DEH_WriteUndoline(word, va("%f", lspr[num].dynamic_radius), UNDO_NONE); - lspr[num].dynamic_radius = fvalue; - - /// \note Update the sqrradius! unnecessary? - lspr[num].dynamic_sqrradius = fvalue * fvalue; - } - else - deh_warning("Light %d: unknown word '%s'", num, word); - } - } while (!myfeof(f)); // finish when the line is empty - - Z_Free(s); -} - -static void readspritelight(MYFILE *f, INT32 num) -{ - char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); - char *word; - char *tmp; - INT32 value; - - do - { - if (myfgets(s, MAXLINELEN, f)) - { - if (s[0] == '\n') - break; - - tmp = strchr(s, '#'); - if (tmp) - *tmp = '\0'; - if (s == tmp) - continue; // Skip comment lines, but don't break. - - value = searchvalue(s); - - word = strtok(s, " "); - if (word) - strupr(word); - else - break; - - if (fastcmp(word, "LIGHTTYPE")) - { - INT32 oldvar; - for (oldvar = 0; t_lspr[num] != &lspr[oldvar]; oldvar++) - ; - DEH_WriteUndoline(word, va("%d", oldvar), UNDO_NONE); - t_lspr[num] = &lspr[value]; - } - else - deh_warning("Sprite %d: unknown word '%s'", num, word); - } - } while (!myfeof(f)); // finish when the line is empty - - Z_Free(s); -} -#endif // HWRENDER - static const struct { const char *name; const UINT16 flag; @@ -3513,37 +3372,6 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad) readAnimTex(f, i); // This is not a major mod. }*/ - else if (fastcmp(word, "LIGHT")) - { -#ifdef HWRENDER - // TODO: Read lights by name - if (i > 0 && i < NUMLIGHTS) - readlight(f, i); - else - { - deh_warning("Light number %d out of range (1 - %d)", i, NUMLIGHTS-1); - ignorelines(f); - } - DEH_WriteUndoline(word, word2, UNDO_HEADER); - // This is not a major mod. -#endif - } - else if (fastcmp(word, "SPRITE")) - { -#ifdef HWRENDER - if (i == 0 && word2[0] != '0') // If word2 isn't a number - i = get_sprite(word2); // find a sprite by name - if (i < NUMSPRITES && i >= 0) - readspritelight(f, i); - else - { - deh_warning("Sprite number %d out of range (0 - %d)", i, NUMSPRITES-1); - ignorelines(f); - } - DEH_WriteUndoline(word, word2, UNDO_HEADER); - // This is not a major mod. -#endif - } else if (fastcmp(word, "LEVEL")) { // Support using the actual map name, @@ -7391,7 +7219,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s // Castle Eggman Scenery "MT_CHAIN", // CEZ Chain - "MT_FLAME", // Flame (has corona) + "MT_FLAME", // Flame "MT_EGGSTATUE", // Eggman Statue "MT_MACEPOINT", // Mace rotation point "MT_SWINGMACEPOINT", // Mace swinging point diff --git a/src/doomdef.h b/src/doomdef.h index 24b52e8d2..ed41e346e 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -138,8 +138,12 @@ #ifdef LOGMESSAGES extern FILE *logstream; +extern char logfilename[1024]; #endif +/* A mod name to further distinguish versions. */ +#define SRB2APPLICATION "SRB2Kart" + //#define DEVELOP // Disable this for release builds to remove excessive cheat commands and enable MD5 checking and stuff, all in one go. :3 #ifdef DEVELOP #define VERSION 0 // Game version @@ -149,10 +153,10 @@ extern FILE *logstream; // most interface strings are ignored in development mode. // we use comprevision and compbranch instead. #else -#define VERSION 110 // Game version -#define SUBVERSION 0 // more precise version number -#define VERSIONSTRING "v1.1" -#define VERSIONSTRINGW L"v1.1" +#define VERSION 1 // Game version +#define SUBVERSION 2 // more precise version number +#define VERSIONSTRING "v1.2" +#define VERSIONSTRINGW L"v1.2" // Hey! If you change this, add 1 to the MODVERSION below! Otherwise we can't force updates! // And change CMakeLists.txt, for CMake users! // AND appveyor.yml, for the build bots! @@ -225,7 +229,7 @@ extern FILE *logstream; // 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.1.0 is not version "1". -#define MODVERSION 5 +#define MODVERSION 6 // Filter consvars by version // To version config.cfg, MAJOREXECVERSION is set equal to MODVERSION automatically. @@ -548,6 +552,9 @@ extern INT32 cv_debug; extern UINT8 shiftdown, ctrldown, altdown; extern boolean capslock; +// WARNING: a should be unsigned but to add with 2048, it isn't! +#define AIMINGTODY(a) (FINETANGENT((2048+(((INT32)a)>>ANGLETOFINESHIFT)) & FINEMASK)*160) + // if we ever make our alloc stuff... #define ZZ_Alloc(x) Z_Malloc(x, PU_STATIC, NULL) @@ -633,11 +640,6 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; /// Most modifications should probably enable this. //#define SAVEGAME_OTHERVERSIONS -#if !defined (_NDS) && !defined (_PSP) -/// Shuffle's incomplete OpenGL sorting code. -#define SHUFFLE // This has nothing to do with sorting, why was it disabled? -#endif - #if !defined (_NDS) && !defined (_PSP) /// Allow the use of the SOC RESETINFO command. /// \note Builds that are tight on memory should disable this. @@ -674,6 +676,9 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; /// on the bright side it fixes some weird issues with translucent walls /// \note SRB2CB port. /// SRB2CB itself ported this from PrBoom+ -#define NEWCLIP +//#define NEWCLIP + +/// Hardware renderer: OpenGL +#define GL_SHADERS #endif // __DOOMDEF__ diff --git a/src/f_wipe.c b/src/f_wipe.c index 3c8713d18..bb1397bcf 100644 --- a/src/f_wipe.c +++ b/src/f_wipe.c @@ -372,7 +372,9 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu) HWR_DoWipe(wipetype, wipeframe-1); // send in the wipe type and wipeframe because we need to cache the graphic else #endif - F_DoWipe(fmask); + if (rendermode != render_none) //this allows F_RunWipe to be called in dedicated servers + F_DoWipe(fmask); + I_OsPolling(); I_UpdateNoBlit(); diff --git a/src/g_game.c b/src/g_game.c index 4fce4db86..a7ad1e68d 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -785,7 +785,7 @@ void G_SetGameModified(boolean silent, boolean major) majormods = true; if (!silent) - CONS_Alert(CONS_NOTICE, M_GetText("Game must be restarted to play record attack.\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) @@ -6629,7 +6629,7 @@ static void G_LoadDemoExtraFiles(UINT8 **pp) { 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 add-ons.\n\nDemo playback may desync.\n\nPress ESC\n"), NULL, MM_NOTHING); + 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) { @@ -6641,7 +6641,7 @@ static void G_LoadDemoExtraFiles(UINT8 **pp) 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 add-ons. Check the console for more information.\n\nDemo playback may desync.\n\nPress ESC\n"), NULL, MM_NOTHING); + 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 { @@ -7472,7 +7472,7 @@ void G_DoPlayDemo(char *defdemoname) if (modeattacking) { - snprintf(msg, 1024, M_GetText("%s is a record attack replay with spectators, and is thus invalid.\n"), pdemoname); + snprintf(msg, 1024, M_GetText("%s is a Record Attack replay with spectators, and is thus invalid.\n"), pdemoname); CONS_Alert(CONS_ERROR, "%s", msg); M_StartMessage(msg, NULL, MM_NOTHING); Z_Free(pdemoname); @@ -7486,7 +7486,7 @@ void G_DoPlayDemo(char *defdemoname) if (modeattacking && numslots > 1) { - snprintf(msg, 1024, M_GetText("%s is a record attack replay with multiple players, and is thus invalid.\n"), pdemoname); + snprintf(msg, 1024, M_GetText("%s is a Record Attack replay with multiple players, and is thus invalid.\n"), pdemoname); CONS_Alert(CONS_ERROR, "%s", msg); M_StartMessage(msg, NULL, MM_NOTHING); Z_Free(pdemoname); diff --git a/src/hardware/hw_bsp.c b/src/hardware/hw_bsp.c index 9e454bcd5..da802aaf9 100644 --- a/src/hardware/hw_bsp.c +++ b/src/hardware/hw_bsp.c @@ -1,17 +1,12 @@ -// Emacs style mode select -*- C++ -*- +// SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// +// Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2019 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 -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// 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 /// \brief convert SRB2 map @@ -19,6 +14,7 @@ #include "../doomdef.h" #include "../doomstat.h" #ifdef HWRENDER +#include "hw_main.h" #include "hw_glob.h" #include "../r_local.h" #include "../z_zone.h" @@ -60,77 +56,12 @@ static INT32 totalsubsecpolys = 0; // -------------------------------------------------------------------------- // Polygon fast alloc / free // -------------------------------------------------------------------------- -//hurdler: quick fix for those who wants to play with larger wad - -#define ZPLANALLOC -#ifndef ZPLANALLOC -//#define POLYPOOLSIZE 1024000 // may be much over what is needed -/// \todo check out how much is used -static size_t POLYPOOLSIZE = 1024000; - -static UINT8 *gr_polypool = NULL; -static UINT8 *gr_ppcurrent; -static size_t gr_ppfree; -#endif - -// only between levels, clear poly pool -static void HWR_ClearPolys(void) -{ -#ifndef ZPLANALLOC - gr_ppcurrent = gr_polypool; - gr_ppfree = POLYPOOLSIZE; -#endif -} - -// allocate pool for fast alloc of polys -void HWR_InitPolyPool(void) -{ -#ifndef ZPLANALLOC - INT32 pnum; - - //hurdler: quick fix for those who wants to play with larger wad - if ((pnum = M_CheckParm("-polypoolsize"))) - POLYPOOLSIZE = atoi(myargv[pnum+1])*1024; // (in kb) - - CONS_Debug(DBG_RENDER, "HWR_InitPolyPool(): allocating %d bytes\n", POLYPOOLSIZE); - gr_polypool = malloc(POLYPOOLSIZE); - if (!gr_polypool) - I_Error("HWR_InitPolyPool(): couldn't malloc polypool\n"); - HWR_ClearPolys(); -#endif -} - -void HWR_FreePolyPool(void) -{ -#ifndef ZPLANALLOC - if (gr_polypool) - free(gr_polypool); - gr_polypool = NULL; -#endif -} static poly_t *HWR_AllocPoly(INT32 numpts) { poly_t *p; size_t size = sizeof (poly_t) + sizeof (polyvertex_t) * numpts; -#ifdef ZPLANALLOC p = Z_Malloc(size, PU_HWRPLANE, NULL); -#else -#ifdef PARANOIA - if (!gr_polypool) - I_Error("Used gr_polypool without init!\n"); - if (!gr_ppcurrent) - I_Error("gr_ppcurrent == NULL!\n"); -#endif - - if (gr_ppfree < size) - I_Error("HWR_AllocPoly(): no more memory %u bytes left, %u bytes needed\n\n%s\n", - gr_ppfree, size, "You can try the param -polypoolsize 2048 (or higher if needed)"); - - p = (poly_t *)gr_ppcurrent; - gr_ppcurrent += size; - gr_ppfree -= size; -#endif p->numpts = numpts; return p; } @@ -139,17 +70,7 @@ static polyvertex_t *HWR_AllocVertex(void) { polyvertex_t *p; size_t size = sizeof (polyvertex_t); -#ifdef ZPLANALLOC p = Z_Malloc(size, PU_HWRPLANE, NULL); -#else - if (gr_ppfree < size) - I_Error("HWR_AllocVertex(): no more memory %u bytes left, %u bytes needed\n\n%s\n", - gr_ppfree, size, "You can try the param -polypoolsize 2048 (or higher if needed)"); - - p = (polyvertex_t *)gr_ppcurrent; - gr_ppcurrent += size; - gr_ppfree -= size; -#endif return p; } @@ -157,16 +78,9 @@ static polyvertex_t *HWR_AllocVertex(void) /// for now don't free because it doesn't free in reverse order static void HWR_FreePoly(poly_t *poly) { -#ifdef ZPLANALLOC Z_Free(poly); -#else - const size_t size = sizeof (poly_t) + sizeof (polyvertex_t) * poly->numpts; - memset(poly, 0x00, size); - //mempoly -= polysize; -#endif } - // Return interception along bsp line, // with the polygon segment // @@ -577,8 +491,8 @@ static inline void SearchDivline(node_t *bsp, fdivline_t *divline) divline->dy = FIXED_TO_FLOAT(bsp->dy); } -#ifdef HWR_LOADING_SCREEN //Hurdler: implement a loading status +#ifdef HWR_LOADING_SCREEN static size_t ls_count = 0; static UINT8 ls_percent = 0; @@ -836,8 +750,6 @@ static INT32 SolveTProblem(void) return 0; CONS_Debug(DBG_RENDER, "Solving T-joins. This may take a while. Please wait...\n"); - CON_Drawer(); //let the user know what we are doing - I_FinishUpdate(); // page flip or blit buffer numsplitpoly = 0; @@ -964,11 +876,9 @@ void HWR_CreatePlanePolygons(INT32 bspnum) CONS_Debug(DBG_RENDER, "Creating polygons, please wait...\n"); #ifdef HWR_LOADING_SCREEN ls_count = ls_percent = 0; // reset the loading status -#endif CON_Drawer(); //let the user know what we are doing I_FinishUpdate(); // page flip or blit buffer - - HWR_ClearPolys(); +#endif // find min/max boundaries of map //CONS_Debug(DBG_RENDER, "Looking for boundaries of map...\n"); diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 956b6aded..eb9511492 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -1,18 +1,12 @@ -// Emacs style mode select -*- C++ -*- +// SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// +// Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2019 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 -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// +// 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 /// \brief load and convert graphics to the hardware format @@ -20,6 +14,7 @@ #include "../doomdef.h" #ifdef HWRENDER +#include "hw_main.h" #include "hw_glob.h" #include "hw_drv.h" @@ -31,10 +26,6 @@ #include "../v_video.h" #include "../r_draw.h" -//Hurdler: 25/04/2000: used for new colormap code in hardware mode -//static UINT8 *gr_colormap = NULL; // by default it must be NULL ! (because colormap tables are not initialized) -boolean firetranslucent = false; - // Values set after a call to HWR_ResizeBlock() static INT32 blocksize, blockwidth, blockheight; @@ -139,17 +130,17 @@ static void HWR_DrawPatchInCache(GLMipmap_t *mipmap, count--; texel = source[yfrac>>FRACBITS]; - - if (firetranslucent && (transtables[(texel<<8)+0x40000]!=texel)) - alpha = 0x80; - else - alpha = 0xff; + alpha = 0xff; //Hurdler: not perfect, but better than holes if (texel == HWR_PATCHES_CHROMAKEY_COLORINDEX && (mipmap->flags & TF_CHROMAKEYED)) - texel = HWR_CHROMAKEY_EQUIVALENTCOLORINDEX; + alpha = 0x00; + + //texel = HWR_CHROMAKEY_EQUIVALENTCOLORINDEX; + // Lat: Don't do that, some weirdos still use CYAN on their WALLTEXTURES for translucency :V + //Hurdler: 25/04/2000: now support colormap in hardware mode - else if (mipmap->colormap) + if (mipmap->colormap) texel = mipmap->colormap[texel]; // hope compiler will get this switch out of the loops (dreams...) @@ -181,16 +172,16 @@ static void HWR_DrawPatchInCache(GLMipmap_t *mipmap, } -// resize the patch to be 3dfx compliant +// resize the patch // set : blocksize = blockwidth * blockheight (no bpp used) // blockwidth // blockheight //note : 8bit (1 byte per pixel) palettized format static void HWR_ResizeBlock(INT32 originalwidth, INT32 originalheight, - GrTexInfo *grInfo) + GLTexInfo *grInfo) { // Build the full textures from patches. - static const GrLOD_t gr_lods[9] = + static const GLlod_t gr_lods[9] = { GR_LOD_LOG2_256, GR_LOD_LOG2_128, @@ -205,7 +196,7 @@ static void HWR_ResizeBlock(INT32 originalwidth, INT32 originalheight, typedef struct { - GrAspectRatio_t aspect; + GLAspectRatio_t aspect; float max_s; float max_t; } booring_aspect_t; @@ -226,41 +217,21 @@ static void HWR_ResizeBlock(INT32 originalwidth, INT32 originalheight, INT32 j,k; INT32 max,min; - // find a power of 2 width/height - if (cv_grrounddown.value) - { - blockwidth = 256; - while (originalwidth < blockwidth) - blockwidth >>= 1; - if (blockwidth < 1) - I_Error("3D GenerateTexture : too small"); + // size up to nearest power of 2 + blockwidth = 1; + while (blockwidth < originalwidth) + blockwidth <<= 1; + // scale down the original graphics to fit in 2048 + if (blockwidth > 2048) + blockwidth = 2048; - blockheight = 256; - while (originalheight < blockheight) - blockheight >>= 1; - if (blockheight < 1) - I_Error("3D GenerateTexture : too small"); - } - else - { - //size up to nearest power of 2 - blockwidth = 1; - while (blockwidth < originalwidth) - blockwidth <<= 1; - // scale down the original graphics to fit in 256 - if (blockwidth > 2048) - blockwidth = 2048; - //I_Error("3D GenerateTexture : too big"); - - //size up to nearest power of 2 - blockheight = 1; - while (blockheight < originalheight) - blockheight <<= 1; - // scale down the original graphics to fit in 256 - if (blockheight > 2048) - blockheight = 2048; - //I_Error("3D GenerateTexture : too big"); - } + // size up to nearest power of 2 + blockheight = 1; + while (blockheight < originalheight) + blockheight <<= 1; + // scale down the original graphics to fit in 2048 + if (blockheight > 2048) + blockheight = 2048; // do the boring LOD stuff.. blech! if (blockwidth >= blockheight) @@ -324,7 +295,7 @@ static UINT8 *MakeBlock(GLMipmap_t *grMipmap) { UINT8 *block; INT32 bpp, i; - UINT16 bu16 = ((0x00 <<8) | HWR_CHROMAKEY_EQUIVALENTCOLORINDEX); + UINT16 bu16 = ((0x00 <<8) | HWR_PATCHES_CHROMAKEY_COLORINDEX); bpp = format2bpp[grMipmap->grInfo.format]; block = Z_Malloc(blocksize*bpp, PU_HWRCACHE, &(grMipmap->grInfo.data)); @@ -335,8 +306,8 @@ static UINT8 *MakeBlock(GLMipmap_t *grMipmap) case 2: // fill background with chromakey, alpha = 0 for (i = 0; i < blocksize; i++) - //[segabor] memcpy(block+i*sizeof(UINT16), &bu16, sizeof(UINT16)); + break; case 4: memset(block, 0x00, blocksize*sizeof(UINT32)); break; } @@ -386,7 +357,6 @@ static void HWR_GenerateTexture(INT32 texnum, GLTexture_t *grtex) grtex->mipmap.colormap += (256*32); #endif - block = MakeBlock(&grtex->mipmap); if (skyspecial) //Hurdler: not efficient, but better than holes in the sky (and it's done only at level loading) @@ -438,7 +408,7 @@ static void HWR_GenerateTexture(INT32 texnum, GLTexture_t *grtex) } // patch may be NULL if grMipmap has been initialised already and makebitmap is false -void HWR_MakePatch (const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipmap, boolean makebitmap) +void HWR_MakePatch (patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipmap, boolean makebitmap) { INT32 newwidth, newheight; @@ -453,8 +423,8 @@ void HWR_MakePatch (const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipm grPatch->leftoffset = SHORT(patch->leftoffset); grPatch->topoffset = SHORT(patch->topoffset); - // find the good 3dfx size (boring spec) - HWR_ResizeBlock (SHORT(patch->width), SHORT(patch->height), &grMipmap->grInfo); + // resize patch + HWR_ResizeBlock(SHORT(patch->width), SHORT(patch->height), &grMipmap->grInfo); grMipmap->width = (UINT16)blockwidth; grMipmap->height = (UINT16)blockheight; @@ -473,23 +443,12 @@ void HWR_MakePatch (const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipm Z_Free(grMipmap->grInfo.data); grMipmap->grInfo.data = NULL; - // if rounddown, rounddown patches as well as textures - if (cv_grrounddown.value) - { - newwidth = blockwidth; - newheight = blockheight; - } - else - { - // no rounddown, do not size up patches, so they don't look 'scaled' - newwidth = min(grPatch->width, blockwidth); - newheight = min(grPatch->height, blockheight); - } + newwidth = min(grPatch->width, blockwidth); + newheight = min(grPatch->height, blockheight); if (makebitmap) { MakeBlock(grMipmap); - HWR_DrawPatchInCache(grMipmap, newwidth, newheight, blockwidth*format2bpp[grMipmap->grInfo.format], @@ -503,7 +462,6 @@ void HWR_MakePatch (const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipm grPatch->max_t = (float)newheight / (float)blockheight; } - // ================================================= // CACHING HANDLING // ================================================= @@ -523,10 +481,10 @@ static void FreeMipmapColormap(INT32 patchnum, void *patch) { GLPatch_t* const grpatch = patch; (void)patchnum; //unused - while (grpatch->mipmap.nextcolormap) + while (grpatch->mipmap->nextcolormap) { - GLMipmap_t *grmip = grpatch->mipmap.nextcolormap; - grpatch->mipmap.nextcolormap = grmip->nextcolormap; + GLMipmap_t *grmip = grpatch->mipmap->nextcolormap; + grpatch->mipmap->nextcolormap = grmip->nextcolormap; if (grmip->grInfo.data) Z_Free(grmip->grInfo.data); free(grmip); } @@ -570,7 +528,7 @@ void HWR_PrepLevelCache(size_t pnumtextures) gr_numtextures = pnumtextures; gr_textures = calloc(pnumtextures, sizeof (*gr_textures)); if (gr_textures == NULL) - I_Error("3D can't alloc gr_textures"); + I_Error("HWR_PrepLevelCache: can't alloc gr_textures"); } void HWR_SetPalette(RGBA_t *palette) @@ -601,7 +559,7 @@ GLTexture_t *HWR_GetTexture(INT32 tex) GLTexture_t *grtex; #ifdef PARANOIA if ((unsigned)tex >= gr_numtextures) - I_Error(" HWR_GetTexture: tex >= numtextures\n"); + I_Error("HWR_GetTexture: tex >= numtextures\n"); #endif grtex = &gr_textures[tex]; @@ -619,12 +577,11 @@ GLTexture_t *HWR_GetTexture(INT32 tex) static void HWR_CacheFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum) { - size_t size, pflatsize; - #ifdef GLENCORE UINT8 *flat; - UINT32 steppy; + size_t steppy; #endif + size_t size, pflatsize; // setup the texture info @@ -681,7 +638,14 @@ void HWR_GetFlat(lumpnum_t flatlumpnum, boolean noencoremap) { GLMipmap_t *grmip; - grmip = &HWR_GetCachedGLPatch(flatlumpnum)->mipmap; + grmip = HWR_GetCachedGLPatch(flatlumpnum)->mipmap; + + grmip->colormap = colormaps; + +#ifdef GLENCORE + if (!noencoremap && encoremap) + grmip->colormap += (256*32); +#endif grmip->colormap = colormaps; @@ -726,22 +690,22 @@ static void HWR_LoadMappedPatch(GLMipmap_t *grmip, GLPatch_t *gpatch) void HWR_GetPatch(GLPatch_t *gpatch) { // is it in hardware cache - if (!gpatch->mipmap.downloaded && !gpatch->mipmap.grInfo.data) + if (!gpatch->mipmap->downloaded && !gpatch->mipmap->grInfo.data) { // load the software patch, PU_STATIC or the Z_Malloc for hardware patch will // flush the software patch before the conversion! oh yeah I suffered - patch_t *ptr = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC); - HWR_MakePatch(ptr, gpatch, &gpatch->mipmap, true); + patch_t *patch = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC); + HWR_MakePatch(patch, gpatch, gpatch->mipmap, true); // this is inefficient.. but the hardware patch in heap is purgeable so it should // not fragment memory, and besides the REAL cache here is the hardware memory - Z_Free(ptr); + Z_Free(patch); } - HWD.pfnSetTexture(&gpatch->mipmap); + HWD.pfnSetTexture(gpatch->mipmap); // The system-memory patch data can be purged now. - Z_ChangeTag(gpatch->mipmap.grInfo.data, PU_HWRCACHE_UNLOCKED); + Z_ChangeTag(gpatch->mipmap->grInfo.data, PU_HWRCACHE_UNLOCKED); } @@ -761,7 +725,7 @@ void HWR_GetMappedPatch(GLPatch_t *gpatch, const UINT8 *colormap) // search for the mimmap // skip the first (no colormap translated) - for (grmip = &gpatch->mipmap; grmip->nextcolormap; ) + for (grmip = gpatch->mipmap; grmip->nextcolormap; ) { grmip = grmip->nextcolormap; if (grmip->colormap == colormap) @@ -791,164 +755,10 @@ void HWR_UnlockCachedPatch(GLPatch_t *gpatch) if (!gpatch) return; - Z_ChangeTag(gpatch->mipmap.grInfo.data, PU_HWRCACHE_UNLOCKED); + Z_ChangeTag(gpatch->mipmap->grInfo.data, PU_HWRCACHE_UNLOCKED); Z_ChangeTag(gpatch, PU_HWRPATCHINFO_UNLOCKED); } -static const INT32 picmode2GR[] = -{ - GR_TEXFMT_P_8, // PALETTE - 0, // INTENSITY (unsupported yet) - GR_TEXFMT_ALPHA_INTENSITY_88, // INTENSITY_ALPHA (corona use this) - 0, // RGB24 (unsupported yet) - GR_RGBA, // RGBA32 (opengl only) -}; - -static void HWR_DrawPicInCache(UINT8 *block, INT32 pblockwidth, INT32 pblockheight, - INT32 blockmodulo, pic_t *pic, INT32 bpp) -{ - INT32 i,j; - fixed_t posx, posy, stepx, stepy; - UINT8 *dest, *src, texel; - UINT16 texelu16; - INT32 picbpp; - RGBA_t col; - - stepy = ((INT32)SHORT(pic->height)<width)<mode]]; - posy = 0; - for (j = 0; j < pblockheight; j++) - { - posx = 0; - dest = &block[j*blockmodulo]; - src = &pic->data[(posy>>FRACBITS)*SHORT(pic->width)*picbpp]; - for (i = 0; i < pblockwidth;i++) - { - switch (pic->mode) - { // source bpp - case PALETTE : - texel = src[(posx+FRACUNIT/2)>>FRACBITS]; - switch (bpp) - { // destination bpp - case 1 : - *dest++ = texel; break; - case 2 : - texelu16 = (UINT16)(texel | 0xff00); - memcpy(dest, &texelu16, sizeof(UINT16)); - dest += sizeof(UINT16); - break; - case 3 : - col = V_GetColor(texel); - memcpy(dest, &col, sizeof(RGBA_t)-sizeof(UINT8)); - dest += sizeof(RGBA_t)-sizeof(UINT8); - break; - case 4 : - memcpy(dest, &V_GetColor(texel), sizeof(RGBA_t)); - dest += sizeof(RGBA_t); - break; - } - break; - case INTENSITY : - *dest++ = src[(posx+FRACUNIT/2)>>FRACBITS]; - break; - case INTENSITY_ALPHA : // assume dest bpp = 2 - memcpy(dest, src + ((posx+FRACUNIT/2)>>FRACBITS)*sizeof(UINT16), sizeof(UINT16)); - dest += sizeof(UINT16); - break; - case RGB24 : - break; // not supported yet - case RGBA32 : // assume dest bpp = 4 - dest += sizeof(UINT32); - memcpy(dest, src + ((posx+FRACUNIT/2)>>FRACBITS)*sizeof(UINT32), sizeof(UINT32)); - break; - } - posx += stepx; - } - posy += stepy; - } -} - -// -----------------+ -// HWR_GetPic : Download a Doom pic (raw row encoded with no 'holes') -// Returns : -// -----------------+ -GLPatch_t *HWR_GetPic(lumpnum_t lumpnum) -{ - GLPatch_t *grpatch; - - grpatch = HWR_GetCachedGLPatch(lumpnum); - - if (!grpatch->mipmap.downloaded && !grpatch->mipmap.grInfo.data) - { - pic_t *pic; - UINT8 *block; - size_t len; - INT32 newwidth, newheight; - - pic = W_CacheLumpNum(lumpnum, PU_CACHE); - grpatch->width = SHORT(pic->width); - grpatch->height = SHORT(pic->height); - len = W_LumpLength(lumpnum) - sizeof (pic_t); - - grpatch->leftoffset = 0; - grpatch->topoffset = 0; - - // find the good 3dfx size (boring spec) - HWR_ResizeBlock (grpatch->width, grpatch->height, &grpatch->mipmap.grInfo); - grpatch->mipmap.width = (UINT16)blockwidth; - grpatch->mipmap.height = (UINT16)blockheight; - - if (pic->mode == PALETTE) - grpatch->mipmap.grInfo.format = textureformat; // can be set by driver - else - grpatch->mipmap.grInfo.format = picmode2GR[pic->mode]; - - Z_Free(grpatch->mipmap.grInfo.data); - - // allocate block - block = MakeBlock(&grpatch->mipmap); - - // if rounddown, rounddown patches as well as textures - if (cv_grrounddown.value) - { - newwidth = blockwidth; - newheight = blockheight; - } - else - { - // no rounddown, do not size up patches, so they don't look 'scaled' - newwidth = min(SHORT(pic->width),blockwidth); - newheight = min(SHORT(pic->height),blockheight); - } - - - if (grpatch->width == blockwidth && - grpatch->height == blockheight && - format2bpp[grpatch->mipmap.grInfo.format] == format2bpp[picmode2GR[pic->mode]]) - { - // no conversion needed - M_Memcpy(grpatch->mipmap.grInfo.data, pic->data,len); - } - else - HWR_DrawPicInCache(block, newwidth, newheight, - blockwidth*format2bpp[grpatch->mipmap.grInfo.format], - pic, - format2bpp[grpatch->mipmap.grInfo.format]); - - Z_Unlock(pic); - Z_ChangeTag(block, PU_HWRCACHE_UNLOCKED); - - grpatch->mipmap.flags = 0; - grpatch->max_s = (float)newwidth / (float)blockwidth; - grpatch->max_t = (float)newheight / (float)blockheight; - } - HWD.pfnSetTexture(&grpatch->mipmap); - //CONS_Debug(DBG_RENDER, "picloaded at %x as texture %d\n",grpatch->mipmap.grInfo.data, grpatch->mipmap.downloaded); - - return grpatch; -} - GLPatch_t *HWR_GetCachedGLPatchPwad(UINT16 wadnum, UINT16 lumpnum) { aatree_t *hwrcache = wadfiles[wadnum]->hwrcache; @@ -959,6 +769,7 @@ GLPatch_t *HWR_GetCachedGLPatchPwad(UINT16 wadnum, UINT16 lumpnum) grpatch = Z_Calloc(sizeof(GLPatch_t), PU_HWRPATCHINFO, NULL); grpatch->wadnum = wadnum; grpatch->lumpnum = lumpnum; + grpatch->mipmap = Z_Calloc(sizeof(GLMipmap_t), PU_HWRPATCHINFO, NULL); M_AATreeSet(hwrcache, lumpnum, grpatch); } @@ -1062,7 +873,7 @@ void HWR_GetFadeMask(lumpnum_t fademasklumpnum) { GLMipmap_t *grmip; - grmip = &HWR_GetCachedGLPatch(fademasklumpnum)->mipmap; + grmip = HWR_GetCachedGLPatch(fademasklumpnum)->mipmap; if (!grmip->downloaded && !grmip->grInfo.data) HWR_CacheFadeMask(grmip, fademasklumpnum); diff --git a/src/hardware/hw_clip.c b/src/hardware/hw_clip.c index a63527083..8ef5636aa 100644 --- a/src/hardware/hw_clip.c +++ b/src/hardware/hw_clip.c @@ -70,16 +70,17 @@ #include #include "../v_video.h" +#include "hw_main.h" #include "hw_clip.h" #include "hw_glob.h" -#include "../r_main.h" #include "../r_state.h" #include "../tables.h" #include "r_opengl/r_opengl.h" +#include "../r_main.h" // for cv_fov #ifdef HAVE_SPHEREFRUSTRUM -static GLfloat viewMatrix[16]; -static GLfloat projMatrix[16]; +static GLdouble viewMatrix[16]; +static GLdouble projMatrix[16]; float frustum[6][4]; #endif @@ -320,12 +321,12 @@ void gld_clipper_Clear(void) #define RMUL (1.6f/1.333333f) -angle_t gld_FrustumAngle(void) +angle_t gld_FrustumAngle(angle_t tiltangle) { double floatangle; angle_t a1; - float tilt = (float)fabs(((double)(int)aimingangle) / ANG1); + float tilt = (float)fabs(((double)(int)tiltangle) / ANG1); // NEWCLIP TODO: SRB2CBTODO: make a global render_fov for this function @@ -334,12 +335,10 @@ angle_t gld_FrustumAngle(void) float render_multiplier = 64.0f / render_fovratio / RMUL; if (tilt > 90.0f) - { tilt = 90.0f; - } // If the pitch is larger than this you can look all around at a FOV of 90 - if (abs((signed)aimingangle) > 46 * ANG1) + if (abs((signed)tiltangle) > 46 * ANG1) return 0xffffffff; // ok, this is a gross hack that barely works... @@ -352,7 +351,7 @@ angle_t gld_FrustumAngle(void) } // SRB2CB I don't think used any of this stuff, let's disable for now since SRB2 probably doesn't want it either -// compiler complains about (p)glGetDoublev anyway, in case anyone wants this +// compiler complains about (p)glGetFloatv anyway, in case anyone wants this // only r_opengl.c can use the base gl funcs as it turns out, that's a problem for whoever wants sphere frustum checks // btw to renable define HAVE_SPHEREFRUSTRUM in hw_clip.h #ifdef HAVE_SPHEREFRUSTRUM @@ -381,7 +380,7 @@ void gld_FrustrumSetup(void) float t; float clip[16]; - pglGeFloatv(GL_PROJECTION_MATRIX, projMatrix); + pglGetFloatv(GL_PROJECTION_MATRIX, projMatrix); pglGetFloatv(GL_MODELVIEW_MATRIX, viewMatrix); clip[0] = CALCMATRIX(0, 0, 1, 4, 2, 8, 3, 12); @@ -463,4 +462,4 @@ boolean gld_SphereInFrustum(float x, float y, float z, float radius) } return true; } -#endif +#endif \ No newline at end of file diff --git a/src/hardware/hw_clip.h b/src/hardware/hw_clip.h index 3ba26e5e5..27a2ed1ef 100644 --- a/src/hardware/hw_clip.h +++ b/src/hardware/hw_clip.h @@ -17,7 +17,7 @@ boolean gld_clipper_SafeCheckRange(angle_t startAngle, angle_t endAngle); void gld_clipper_SafeAddClipRange(angle_t startangle, angle_t endangle); void gld_clipper_Clear(void); -angle_t gld_FrustumAngle(void); +angle_t gld_FrustumAngle(angle_t tiltangle); #ifdef HAVE_SPHEREFRUSTRUM void gld_FrustrumSetup(void); boolean gld_SphereInFrustum(float x, float y, float z, float radius); diff --git a/src/hardware/hw_data.h b/src/hardware/hw_data.h index 4bbc578ed..a96d4c915 100644 --- a/src/hardware/hw_data.h +++ b/src/hardware/hw_data.h @@ -1,77 +1,101 @@ -// Emacs style mode select -*- C++ -*- +// SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// +// Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2019 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 -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// +// 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 -/// \brief defines structures and exports for the standard 3D driver DLL used by Doom Legacy +/// \brief defines structures and exports for the standard GPU driver #ifndef _HWR_DATA_ #define _HWR_DATA_ -#if defined (_WIN32) && !defined (__CYGWIN__) && !defined (_XBOX) -//#define WIN32_LEAN_AND_MEAN -#define RPC_NO_WINDOWS_H -#include -#endif - #include "../doomdef.h" -//THIS MUST DISAPPEAR!!! -#include "hw_glide.h" #include "../screen.h" - // ========================================================================== // TEXTURE INFO // ========================================================================== +// +// hw_glide.h +// + +typedef long GLAspectRatio_t; +#define GR_ASPECT_LOG2_8x1 3 /* 8W x 1H */ +#define GR_ASPECT_LOG2_4x1 2 /* 4W x 1H */ +#define GR_ASPECT_LOG2_2x1 1 /* 2W x 1H */ +#define GR_ASPECT_LOG2_1x1 0 /* 1W x 1H */ +#define GR_ASPECT_LOG2_1x2 -1 /* 1W x 2H */ +#define GR_ASPECT_LOG2_1x4 -2 /* 1W x 4H */ +#define GR_ASPECT_LOG2_1x8 -3 /* 1W x 8H */ + +typedef long GLlod_t; +#define GR_LOD_LOG2_256 0x8 +#define GR_LOD_LOG2_128 0x7 +#define GR_LOD_LOG2_64 0x6 +#define GR_LOD_LOG2_32 0x5 +#define GR_LOD_LOG2_16 0x4 +#define GR_LOD_LOG2_8 0x3 +#define GR_LOD_LOG2_4 0x2 +#define GR_LOD_LOG2_2 0x1 +#define GR_LOD_LOG2_1 0x0 + +typedef long GLTextureFormat_t; +#define GR_TEXFMT_ALPHA_8 0x2 /* (0..0xFF) alpha */ +#define GR_TEXFMT_INTENSITY_8 0x3 /* (0..0xFF) intensity */ +#define GR_TEXFMT_ALPHA_INTENSITY_44 0x4 +#define GR_TEXFMT_P_8 0x5 /* 8-bit palette */ +#define GR_TEXFMT_RGB_565 0xa +#define GR_TEXFMT_ARGB_1555 0xb +#define GR_TEXFMT_ARGB_4444 0xc +#define GR_TEXFMT_ALPHA_INTENSITY_88 0xd +#define GR_TEXFMT_AP_88 0xe /* 8-bit alpha 8-bit palette */ +#define GR_RGBA 0x6 // 32 bit RGBA ! + +typedef struct +{ + GLlod_t smallLodLog2; + GLlod_t largeLodLog2; + GLAspectRatio_t aspectRatioLog2; + GLTextureFormat_t format; + void *data; +} GLTexInfo; + // grInfo.data holds the address of the graphics data cached in heap memory // NULL if the texture is not in Doom heap cache. struct GLMipmap_s { - GrTexInfo grInfo; //for TexDownloadMipMap - FxU32 flags; - UINT16 height; - UINT16 width; - UINT32 downloaded; // the dll driver have it in there cache ? + GLTexInfo grInfo; + unsigned long flags; + UINT16 width, height; + UINT32 downloaded; // tex_downloaded - struct GLMipmap_s *nextcolormap; - const UINT8 *colormap; - - // opengl - struct GLMipmap_s *nextmipmap; // opengl : liste of all texture in opengl driver + struct GLMipmap_s *nextmipmap; + struct GLMipmap_s *nextcolormap; + const UINT8 *colormap; }; typedef struct GLMipmap_s GLMipmap_t; - // // Doom texture info, as cached for hardware rendering // struct GLTexture_s { - GLMipmap_t mipmap; - float scaleX; //used for scaling textures on walls - float scaleY; + GLMipmap_t mipmap; + float scaleX; //used for scaling textures on walls + float scaleY; }; typedef struct GLTexture_s GLTexture_t; - // a cached patch as converted to hardware format, holding the original patch_t // header so that the existing code can retrieve ->width, ->height as usual // This is returned by W_CachePatchNum()/W_CachePatchName(), when rendermode // is 'render_opengl'. Else it returns the normal patch_t data. - struct GLPatch_s { // the 4 first fields come right away from the original patch_t @@ -83,8 +107,10 @@ struct GLPatch_s float max_s,max_t; UINT16 wadnum; // the software patch lump num for when the hardware patch UINT16 lumpnum; // was flushed, and we need to re-create it - GLMipmap_t mipmap; -}; + GLMipmap_t *mipmap; + + boolean notfound; // if the texture file was not found, mark it here (used in model texture loading) +} ATTRPACK; typedef struct GLPatch_s GLPatch_t; #endif //_HWR_DATA_ diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index b37850bb7..af545191a 100644 --- a/src/hardware/hw_defs.h +++ b/src/hardware/hw_defs.h @@ -19,6 +19,7 @@ #ifndef _HWR_DEFS_ #define _HWR_DEFS_ #include "../doomtype.h" +#include "../r_defs.h" #define ZCLIP_PLANE 4.0f // Used for the actual game drawing #define NZCLIP_PLANE 0.9f // Seems to be only used for the HUD and screen textures @@ -41,17 +42,8 @@ typedef unsigned char FBOOLEAN; // ========================================================================== // byte value for paletted graphics, which represent the transparent color -#ifdef _NDS -// NDS is hardwired to use zero as transparent color -#define HWR_PATCHES_CHROMAKEY_COLORINDEX 0 -#define HWR_CHROMAKEY_EQUIVALENTCOLORINDEX 1 -#else #define HWR_PATCHES_CHROMAKEY_COLORINDEX 247 #define HWR_CHROMAKEY_EQUIVALENTCOLORINDEX 220 -#endif - -// the chroma key color shows on border sprites, set it to black -#define HWR_PATCHES_CHROMAKEY_COLORVALUE (0x00000000) //RGBA format as in grSstWinOpen() // RGBA Color components with float type ranging [ 0 ... 1 ] struct FRGBAFloat @@ -73,8 +65,6 @@ struct FColorARGB typedef struct FColorARGB ARGB_t; typedef struct FColorARGB FColorARGB; - - // ========================================================================== // VECTORS // ========================================================================== @@ -85,22 +75,65 @@ typedef struct FLOAT x,y; } F2DCoord, v2d_t; -// Simple 3D vector -typedef struct FVector -{ - FLOAT x,y,z; -} FVector; +// ====================== +// wallVert3D +// ---------------------- +// :crab: IS GONE! :crab: +// ====================== -// 3D model vector (coords + texture coords) +// ----------- +// structures +// ----------- + +// a vertex of a Doom 'plane' polygon typedef struct { - //FVector Point; - FLOAT x,y,z; - FLOAT s,t,w; // texture coordinates -} v3d_t, wallVert3D; + float x; + float y; + float z; +} polyvertex_t; -//Hurdler: Transform (coords + angles) -//BP: transform order : scale(rotation_x(rotation_y(translation(v)))) +#ifdef _MSC_VER +#pragma warning(disable : 4200) +#endif + +// a convex 'plane' polygon, clockwise order +typedef struct +{ + INT32 numpts; + polyvertex_t pts[0]; +} poly_t; + +#ifdef _MSC_VER +#pragma warning(default : 4200) +#endif + +// holds extra info for 3D render, for each subsector in subsectors[] +typedef struct +{ + poly_t *planepoly; // the generated convex polygon +} extrasubsector_t; + +// needed for sprite rendering +// equivalent of the software renderer's vissprites +typedef struct gr_vissprite_s +{ + // Doubly linked list + struct gr_vissprite_s *prev; + struct gr_vissprite_s *next; + float x1, x2; + float z1, z2; + float tz, ty; + lumpnum_t patchlumpnum; + boolean flip; + UINT8 translucency; //alpha level 0-255 + mobj_t *mobj; + boolean precip; // Tails 08-25-2002 + boolean vflip; + //Hurdler: 25/04/2000: now support colormap in hardware mode + UINT8 *colormap; + INT32 dispoffset; // copy of info->dispoffset, affects ordering but not drawing +} gr_vissprite_t; // Kart features #define USE_FTRANSFORM_ANGLEZ @@ -124,18 +157,17 @@ typedef struct #ifdef USE_FTRANSFORM_MIRROR boolean mirror; // SRB2Kart: Encore Mode #endif + boolean shearing; // 14042019 + angle_t viewaiming; // 17052019 } FTransform; // Transformed vector, as passed to HWR API typedef struct { FLOAT x,y,z; - FUINT argb; // flat-shaded color - FLOAT sow; // s texture ordinate (s over w) - FLOAT tow; // t texture ordinate (t over w) + FLOAT s,t; } FOutVector; - // ========================================================================== // RENDER MODES // ========================================================================== @@ -144,7 +176,7 @@ typedef struct // You pass a combination of these flags to DrawPolygon() enum EPolyFlags { - // the first 5 are mutually exclusive + // the first 5 are mutually exclusive PF_Masked = 0x00000001, // Poly is alpha scaled and 0 alpha pels are discarded (holes in texture) PF_Translucent = 0x00000002, // Poly is transparent, alpha = level of transparency @@ -156,7 +188,7 @@ enum EPolyFlags PF_Fog = 0x00000040, // Fog blocks PF_Blending = (PF_Environment|PF_Additive|PF_Translucent|PF_Masked|PF_Substractive|PF_Fog)&~PF_NoAlphaTest, - // other flag bits + // other flag bits PF_Occlude = 0x00000100, // Update the depth buffer PF_NoDepthTest = 0x00000200, // Disable the depth test mode @@ -164,21 +196,15 @@ enum EPolyFlags PF_Decal = 0x00000800, // Enable polygon offset PF_Modulated = 0x00001000, // Modulation (multiply output with constant ARGB) // When set, pass the color constant into the FSurfaceInfo -> FlatColor - PF_NoTexture = 0x00002000, // Use the small white texture - PF_Corona = 0x00004000, // Tell the rendrer we are drawing a corona - PF_Unused = 0x00008000, // Unused + PF_NoTexture = 0x00002000, // Disable texture + PF_Ripple = 0x00004000, // Water shader effect + // 0x00008000 PF_RemoveYWrap = 0x00010000, // Force clamp texture on Y PF_ForceWrapX = 0x00020000, // Force repeat texture on X PF_ForceWrapY = 0x00040000, // Force repeat texture on Y - PF_Clip = 0x40000000, // clip to frustum and nearz plane (glide only, automatic in opengl) - PF_NoZClip = 0x20000000, // in conjonction with PF_Clip - PF_Debug = 0x80000000 // print debug message in driver :) -}; - - -enum ESurfFlags -{ - SF_DYNLIGHT = 0x00000001, + // 0x20000000 + // 0x40000000 + // 0x80000000 }; @@ -191,46 +217,42 @@ enum ETextureFlags TF_TRANSPARENT = 0x00000040, // texture with some alpha == 0 }; -#ifdef TODO -struct FTextureInfo -{ - FUINT Width; // Pixels - FUINT Height; // Pixels - FUBYTE *TextureData; // Image data - FUINT Format; // FORMAT_RGB, ALPHA ... - FBITFIELD Flags; // Flags to tell driver about texture (see ETextureFlags) - void DriverExtra; // (OpenGL texture object nr, ...) - // chromakey enabled,... - - struct FTextureInfo *Next; // Manage list of downloaded textures. -}; -#else typedef struct GLMipmap_s FTextureInfo; -#endif + +// jimita 14032019 +struct FLightInfo +{ + FUINT light_level; + FUINT fade_start; + FUINT fade_end; +}; +typedef struct FLightInfo FLightInfo; // Description of a renderable surface struct FSurfaceInfo { - FUINT PolyFlags; // Surface flags -- UNUSED YET -- - RGBA_t FlatColor; // Flat-shaded color used with PF_Modulated mode + FUINT PolyFlags; + RGBA_t PolyColor; + RGBA_t TintColor; + RGBA_t FadeColor; + FLightInfo LightInfo; // jimita 14032019 }; typedef struct FSurfaceInfo FSurfaceInfo; -//Hurdler: added for backward compatibility enum hwdsetspecialstate { - HWD_SET_FOG_TABLE = 1, - HWD_SET_FOG_MODE, - HWD_SET_FOG_COLOR, - HWD_SET_FOG_DENSITY, - HWD_SET_FOV, + HWD_SET_SHADERS, + HWD_SET_TEXTUREFILTERMODE, HWD_SET_TEXTUREANISOTROPICMODE, + HWD_NUMSTATE }; - typedef enum hwdsetspecialstate hwdspecialstate_t; +#define GL_DEFAULTMIX 0x00000000 +#define GL_DEFAULTFOG 0xFF000000 + enum hwdfiltermode { HWD_SET_TEXTUREFILTER_POINTSAMPLED, @@ -241,5 +263,4 @@ enum hwdfiltermode HWD_SET_TEXTUREFILTER_MIXED3, }; - #endif //_HWR_DEFS_ diff --git a/src/hardware/hw_dll.h b/src/hardware/hw_dll.h index 466452783..14040432d 100644 --- a/src/hardware/hw_dll.h +++ b/src/hardware/hw_dll.h @@ -54,8 +54,6 @@ #endif #endif -typedef void (*I_Error_t) (const char *error, ...) FUNCIERROR; - // ========================================================================== // MATHS // ========================================================================== @@ -63,7 +61,8 @@ typedef void (*I_Error_t) (const char *error, ...) FUNCIERROR; // Constants #define DEGREE (0.017453292519943295769236907684883l) // 2*PI/360 -void DBG_Printf(const char *lpFmt, ...) /*FUNCPRINTF*/; +void GL_DBG_Printf(const char *format, ...) /*FUNCPRINTF*/; +#define DBG_Printf GL_DBG_Printf #ifdef _WINDOWS BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved); diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index ac63df156..ba069420e 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -1,17 +1,12 @@ -// Emacs style mode select -*- C++ -*- +// SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// +// Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2019 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 -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// 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 /// \brief miscellaneous drawing (mainly 2d) @@ -23,6 +18,7 @@ #include "../doomdef.h" #ifdef HWRENDER +#include "hw_main.h" #include "hw_glob.h" #include "hw_drv.h" @@ -41,9 +37,6 @@ #define O_BINARY 0 #endif -float gr_patch_scalex; -float gr_patch_scaley; - #if defined(_MSC_VER) #pragma pack(1) #endif @@ -63,9 +56,6 @@ typedef struct #if defined(_MSC_VER) #pragma pack() #endif -typedef UINT8 GLRGB[3]; - -#define BLENDMODE PF_Translucent static UINT8 softwaretranstogl[11] = { 0, 25, 51, 76,102,127,153,178,204,229,255}; static UINT8 softwaretranstogl_hi[11] = { 0, 51,102,153,204,255,255,255,255,255,255}; @@ -119,12 +109,12 @@ void HWR_DrawPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option) v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; - v[0].sow = v[3].sow = 0.0f; - v[2].sow = v[1].sow = gpatch->max_s; - v[0].tow = v[1].tow = 0.0f; - v[2].tow = v[3].tow = gpatch->max_t; + v[0].s = v[3].s = 0.0f; + v[2].s = v[1].s = gpatch->max_s; + v[0].t = v[1].t = 0.0f; + v[2].t = v[3].t = gpatch->max_t; - flags = BLENDMODE|PF_Clip|PF_NoZClip|PF_NoDepthTest; + flags = PF_Translucent|PF_NoDepthTest; if (option & V_WRAPX) flags |= PF_ForceWrapX; @@ -220,7 +210,7 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, // if it's meant to cover the whole screen, black out the rest // cx and cy are possibly *slightly* off from float maths // This is done before here compared to software because we directly alter cx and cy to centre - /*if (cx >= -0.1f && cx <= 0.1f && SHORT(gpatch->width) == BASEVIDWIDTH && cy >= -0.1f && cy <= 0.1f && SHORT(gpatch->height) == BASEVIDHEIGHT) + if (cx >= -0.1f && cx <= 0.1f && SHORT(gpatch->width) == BASEVIDWIDTH && cy >= -0.1f && cy <= 0.1f && SHORT(gpatch->height) == BASEVIDHEIGHT) { // Need to temporarily cache the real patch to get the colour of the top left pixel patch_t *realpatch = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC); @@ -228,7 +218,7 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, const UINT8 *source = (const UINT8 *)(column) + 3; HWR_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0])); Z_Free(realpatch); - }*/ + } // centre screen if (fabsf((float)vid.width - (float)BASEVIDWIDTH * dupx) > 1.0E-36f) { @@ -279,19 +269,19 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, if (option & V_FLIP) { - v[0].sow = v[3].sow = gpatch->max_s; - v[2].sow = v[1].sow = 0.0f; + v[0].s = v[3].s = gpatch->max_s; + v[2].s = v[1].s = 0.0f; } else { - v[0].sow = v[3].sow = 0.0f; - v[2].sow = v[1].sow = gpatch->max_s; + v[0].s = v[3].s = 0.0f; + v[2].s = v[1].s = gpatch->max_s; } - v[0].tow = v[1].tow = 0.0f; - v[2].tow = v[3].tow = gpatch->max_t; + v[0].t = v[1].t = 0.0f; + v[2].t = v[3].t = gpatch->max_t; - flags = BLENDMODE|PF_Clip|PF_NoZClip|PF_NoDepthTest; + flags = PF_Translucent|PF_NoDepthTest; if (option & V_WRAPX) flags |= PF_ForceWrapX; @@ -302,11 +292,11 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, if (alphalevel) { FSurfaceInfo Surf; - Surf.FlatColor.s.red = Surf.FlatColor.s.green = Surf.FlatColor.s.blue = 0xff; - if (alphalevel == 13) Surf.FlatColor.s.alpha = softwaretranstogl_lo[hudtrans]; - else if (alphalevel == 14) Surf.FlatColor.s.alpha = softwaretranstogl[hudtrans]; - else if (alphalevel == 15) Surf.FlatColor.s.alpha = softwaretranstogl_hi[hudtrans]; - else Surf.FlatColor.s.alpha = softwaretranstogl[10-alphalevel]; + Surf.PolyColor.s.red = Surf.PolyColor.s.green = Surf.PolyColor.s.blue = 0xff; + if (alphalevel == 13) Surf.PolyColor.s.alpha = softwaretranstogl_lo[hudtrans]; + else if (alphalevel == 14) Surf.PolyColor.s.alpha = softwaretranstogl[hudtrans]; + else if (alphalevel == 15) Surf.PolyColor.s.alpha = softwaretranstogl_hi[hudtrans]; + else Surf.PolyColor.s.alpha = softwaretranstogl[10-alphalevel]; flags |= PF_Modulated; HWD.pfnDrawPolygon(&Surf, v, 4, flags); } @@ -368,7 +358,7 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal // if it's meant to cover the whole screen, black out the rest // cx and cy are possibly *slightly* off from float maths // This is done before here compared to software because we directly alter cx and cy to centre - /*if (cx >= -0.1f && cx <= 0.1f && SHORT(gpatch->width) == BASEVIDWIDTH && cy >= -0.1f && cy <= 0.1f && SHORT(gpatch->height) == BASEVIDHEIGHT) + if (cx >= -0.1f && cx <= 0.1f && SHORT(gpatch->width) == BASEVIDWIDTH && cy >= -0.1f && cy <= 0.1f && SHORT(gpatch->height) == BASEVIDHEIGHT) { // Need to temporarily cache the real patch to get the colour of the top left pixel patch_t *realpatch = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC); @@ -376,7 +366,7 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal const UINT8 *source = (const UINT8 *)(column) + 3; HWR_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0])); Z_Free(realpatch); - }*/ + } // centre screen if (fabsf((float)vid.width - (float)BASEVIDWIDTH * dupx) > 1.0E-36f) { @@ -440,12 +430,12 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; - v[0].sow = v[3].sow = ((sx)/(float)SHORT(gpatch->width) )*gpatch->max_s; - v[2].sow = v[1].sow = ((w )/(float)SHORT(gpatch->width) )*gpatch->max_s; - v[0].tow = v[1].tow = ((sy)/(float)SHORT(gpatch->height))*gpatch->max_t; - v[2].tow = v[3].tow = ((h )/(float)SHORT(gpatch->height))*gpatch->max_t; + v[0].s = v[3].s = ((sx)/(float)SHORT(gpatch->width) )*gpatch->max_s; + v[2].s = v[1].s = ((w )/(float)SHORT(gpatch->width) )*gpatch->max_s; + v[0].t = v[1].t = ((sy)/(float)SHORT(gpatch->height))*gpatch->max_t; + v[2].t = v[3].t = ((h )/(float)SHORT(gpatch->height))*gpatch->max_t; - flags = BLENDMODE|PF_Clip|PF_NoZClip|PF_NoDepthTest; + flags = PF_Translucent|PF_NoDepthTest; if (option & V_WRAPX) flags |= PF_ForceWrapX; @@ -456,11 +446,11 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal if (alphalevel) { FSurfaceInfo Surf; - Surf.FlatColor.s.red = Surf.FlatColor.s.green = Surf.FlatColor.s.blue = 0xff; - if (alphalevel == 13) Surf.FlatColor.s.alpha = softwaretranstogl_lo[hudtrans]; - else if (alphalevel == 14) Surf.FlatColor.s.alpha = softwaretranstogl[hudtrans]; - else if (alphalevel == 15) Surf.FlatColor.s.alpha = softwaretranstogl_hi[hudtrans]; - else Surf.FlatColor.s.alpha = softwaretranstogl[10-alphalevel]; + Surf.PolyColor.s.red = Surf.PolyColor.s.green = Surf.PolyColor.s.blue = 0xff; + if (alphalevel == 13) Surf.PolyColor.s.alpha = softwaretranstogl_lo[cv_translucenthud.value]; + else if (alphalevel == 14) Surf.PolyColor.s.alpha = softwaretranstogl[cv_translucenthud.value]; + else if (alphalevel == 15) Surf.PolyColor.s.alpha = softwaretranstogl_hi[cv_translucenthud.value]; + else Surf.PolyColor.s.alpha = softwaretranstogl[10-alphalevel]; flags |= PF_Modulated; HWD.pfnDrawPolygon(&Surf, v, 4, flags); } @@ -468,41 +458,6 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal HWD.pfnDrawPolygon(NULL, v, 4, flags); } -void HWR_DrawPic(INT32 x, INT32 y, lumpnum_t lumpnum) -{ - FOutVector v[4]; - const GLPatch_t *patch; - - // make pic ready in hardware cache - patch = HWR_GetPic(lumpnum); - -// 3--2 -// | /| -// |/ | -// 0--1 - - v[0].x = v[3].x = 2.0f * (float)x/vid.width - 1; - v[2].x = v[1].x = 2.0f * (float)(x + patch->width*FIXED_TO_FLOAT(vid.fdupx))/vid.width - 1; - v[0].y = v[1].y = 1.0f - 2.0f * (float)y/vid.height; - v[2].y = v[3].y = 1.0f - 2.0f * (float)(y + patch->height*FIXED_TO_FLOAT(vid.fdupy))/vid.height; - - v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; - - v[0].sow = v[3].sow = 0; - v[2].sow = v[1].sow = patch->max_s; - v[0].tow = v[1].tow = 0; - v[2].tow = v[3].tow = patch->max_t; - - - //Hurdler: Boris, the same comment as above... but maybe for pics - // it not a problem since they don't have any transparent pixel - // if I'm right !? - // But then, the question is: why not 0 instead of PF_Masked ? - // or maybe PF_Environment ??? (like what I said above) - // BP: PF_Environment don't change anything ! and 0 is undifined - HWD.pfnDrawPolygon(NULL, v, 4, BLENDMODE | PF_NoDepthTest | PF_Clip | PF_NoZClip); -} - // ========================================================================== // V_VIDEO.C STUFF // ========================================================================== @@ -563,12 +518,12 @@ void HWR_DrawFlatFill (INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatlumpnum v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; // flat is 64x64 lod and texture offsets are [0.0, 1.0] - v[0].sow = v[3].sow = (float)((x & flatflag)/dflatsize); - v[2].sow = v[1].sow = (float)(v[0].sow + w/dflatsize); - v[0].tow = v[1].tow = (float)((y & flatflag)/dflatsize); - v[2].tow = v[3].tow = (float)(v[0].tow + h/dflatsize); + v[0].s = v[3].s = (float)((x & flatflag)/dflatsize); + v[2].s = v[1].s = (float)(v[0].s + w/dflatsize); + v[0].t = v[1].t = (float)((y & flatflag)/dflatsize); + v[2].t = v[3].t = (float)(v[0].t + h/dflatsize); - HWR_GetFlat(flatlumpnum, false); + HWR_GetFlat(flatlumpnum, false); // Never Encore map drawflatfill, duh. //Hurdler: Boris, the same comment as above... but maybe for pics // it not a problem since they don't have any transparent pixel @@ -598,20 +553,20 @@ void HWR_FadeScreenMenuBack(UINT16 color, UINT8 strength) v[2].y = v[3].y = 1.0f; v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; - v[0].sow = v[3].sow = 0.0f; - v[2].sow = v[1].sow = 1.0f; - v[0].tow = v[1].tow = 1.0f; - v[2].tow = v[3].tow = 0.0f; + v[0].s = v[3].s = 0.0f; + v[2].s = v[1].s = 1.0f; + v[0].t = v[1].t = 1.0f; + v[2].t = v[3].t = 0.0f; if (color & 0xFF00) // Do COLORMAP fade. { - Surf.FlatColor.rgba = UINT2RGBA(0x01010160); - Surf.FlatColor.s.alpha = (strength*8); + Surf.PolyColor.rgba = UINT2RGBA(0x01010160); + Surf.PolyColor.s.alpha = (strength*8); } else // Do TRANSMAP** fade. { - Surf.FlatColor.rgba = pLocalPalette[color].rgba; - Surf.FlatColor.s.alpha = (UINT8)(strength*25.5f); + Surf.PolyColor.rgba = pLocalPalette[color].rgba; + Surf.PolyColor.s.alpha = (UINT8)(strength*25.5f); } HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest); } @@ -632,13 +587,13 @@ void HWR_DrawConsoleBack(UINT32 color, INT32 height) v[2].y = v[3].y = 1.0f; v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; - v[0].sow = v[3].sow = 0.0f; - v[2].sow = v[1].sow = 1.0f; - v[0].tow = v[1].tow = 1.0f; - v[2].tow = v[3].tow = 0.0f; + v[0].s = v[3].s = 0.0f; + v[2].s = v[1].s = 1.0f; + v[0].t = v[1].t = 1.0f; + v[2].t = v[3].t = 0.0f; - Surf.FlatColor.rgba = UINT2RGBA(color); - Surf.FlatColor.s.alpha = 0x80; + Surf.PolyColor.rgba = UINT2RGBA(color); + Surf.PolyColor.s.alpha = 0x80; HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest); } @@ -773,6 +728,7 @@ void HWR_DrawViewBorder(INT32 clearlines) } + // ========================================================================== // AM_MAP.C DRAWING STUFF // ========================================================================== @@ -797,225 +753,6 @@ void HWR_drawAMline(const fline_t *fl, INT32 color) HWD.pfnDraw2DLine(&v1, &v2, color_rgba); } -// -----------------+ -// HWR_DrawFill : draw flat coloured rectangle, with no texture -// -----------------+ -void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color) -{ - FOutVector v[4]; - FSurfaceInfo Surf; - float fx, fy, fw, fh; - - if (w < 0 || h < 0) - return; // consistency w/ software - -// 3--2 -// | /| -// |/ | -// 0--1 - - fx = (float)x; - fy = (float)y; - fw = (float)w; - fh = (float)h; - - if (!(color & V_NOSCALESTART)) - { - float dupx = (float)vid.dupx, dupy = (float)vid.dupy; - - if (x == 0 && y == 0 && w == BASEVIDWIDTH && h == BASEVIDHEIGHT) - { - RGBA_t rgbaColour = V_GetColor(color); - FRGBAFloat clearColour; - clearColour.red = (float)rgbaColour.s.red / 255; - clearColour.green = (float)rgbaColour.s.green / 255; - clearColour.blue = (float)rgbaColour.s.blue / 255; - clearColour.alpha = 1; - HWD.pfnClearBuffer(true, false, &clearColour); - return; - } - - fx *= dupx; - fy *= dupy; - fw *= dupx; - fh *= dupy; - - if (fabsf((float)vid.width - (float)BASEVIDWIDTH * dupx) > 1.0E-36f) - { - if (color & V_SNAPTORIGHT) - fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)); - else if (!(color & V_SNAPTOLEFT)) - fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 2; - } - if (fabsf((float)vid.height - (float)BASEVIDHEIGHT * dupy) > 1.0E-36f) - { - // same thing here - if (color & V_SNAPTOBOTTOM) - fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)); - else if (!(color & V_SNAPTOTOP)) - fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 2; - } - if (color & V_SPLITSCREEN) - fy += ((float)BASEVIDHEIGHT * dupy)/2; - if (color & V_HORZSCREEN) - fx += ((float)BASEVIDWIDTH * dupx)/2; - } - - if (fx >= vid.width || fy >= vid.height) - return; - if (fx < 0) - { - fw += fx; - fx = 0; - } - if (fy < 0) - { - fh += fy; - fy = 0; - } - - if (fw <= 0 || fh <= 0) - return; - if (fx + fw > vid.width) - fw = (float)vid.width - fx; - if (fy + fh > vid.height) - fh = (float)vid.height - fy; - - fx = -1 + fx / (vid.width / 2); - fy = 1 - fy / (vid.height / 2); - fw = fw / (vid.width / 2); - fh = fh / (vid.height / 2); - - v[0].x = v[3].x = fx; - v[2].x = v[1].x = fx + fw; - v[0].y = v[1].y = fy; - v[2].y = v[3].y = fy - fh; - - //Hurdler: do we still use this argb color? if not, we should remove it - v[0].argb = v[1].argb = v[2].argb = v[3].argb = 0xff00ff00; //; - v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; - - v[0].sow = v[3].sow = 0.0f; - v[2].sow = v[1].sow = 1.0f; - v[0].tow = v[1].tow = 0.0f; - v[2].tow = v[3].tow = 1.0f; - - Surf.FlatColor = V_GetColor(color); - - HWD.pfnDrawPolygon(&Surf, v, 4, - PF_Modulated|PF_NoTexture|PF_NoDepthTest); -} - - -// -------------------+ -// HWR_DrawConsoleFill : draw flat coloured transparent rectangle because that's cool, and hw sucks less than sw for that. -// -------------------+ -void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, UINT32 color, INT32 options) -{ - FOutVector v[4]; - FSurfaceInfo Surf; - float fx, fy, fw, fh; - - if (w < 0 || h < 0) - return; // consistency w/ software - -// 3--2 -// | /| -// |/ | -// 0--1 - - fx = (float)x; - fy = (float)y; - fw = (float)w; - fh = (float)h; - - if (!(options & V_NOSCALESTART)) - { - float dupx = (float)vid.dupx, dupy = (float)vid.dupy; - - if (x == 0 && y == 0 && w == BASEVIDWIDTH && h == BASEVIDHEIGHT) - { - RGBA_t rgbaColour = V_GetColor(color); - FRGBAFloat clearColour; - clearColour.red = (float)rgbaColour.s.red / 255; - clearColour.green = (float)rgbaColour.s.green / 255; - clearColour.blue = (float)rgbaColour.s.blue / 255; - clearColour.alpha = 1; - HWD.pfnClearBuffer(true, false, &clearColour); - return; - } - - fx *= dupx; - fy *= dupy; - fw *= dupx; - fh *= dupy; - - if (fabsf((float)vid.width - ((float)BASEVIDWIDTH * dupx)) > 1.0E-36f) - { - if (options & V_SNAPTORIGHT) - fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)); - else if (!(options & V_SNAPTOLEFT)) - fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 2; - } - if (fabsf((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) > 1.0E-36f) - { - // same thing here - if (options & V_SNAPTOBOTTOM) - fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)); - else if (!(options & V_SNAPTOTOP)) - fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 2; - } - if (options & V_SPLITSCREEN) - fy += ((float)BASEVIDHEIGHT * dupy)/2; - if (options & V_HORZSCREEN) - fx += ((float)BASEVIDWIDTH * dupx)/2; - } - - if (fx >= vid.width || fy >= vid.height) - return; - if (fx < 0) - { - fw += fx; - fx = 0; - } - if (fy < 0) - { - fh += fy; - fy = 0; - } - - if (fw <= 0 || fh <= 0) - return; - if (fx + fw > vid.width) - fw = (float)vid.width - fx; - if (fy + fh > vid.height) - fh = (float)vid.height - fy; - - fx = -1 + fx / (vid.width / 2); - fy = 1 - fy / (vid.height / 2); - fw = fw / (vid.width / 2); - fh = fh / (vid.height / 2); - - v[0].x = v[3].x = fx; - v[2].x = v[1].x = fx + fw; - v[0].y = v[1].y = fy; - v[2].y = v[3].y = fy - fh; - - //Hurdler: do we still use this argb color? if not, we should remove it - v[0].argb = v[1].argb = v[2].argb = v[3].argb = 0xff00ff00; //; - v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; - - v[0].sow = v[3].sow = 0.0f; - v[2].sow = v[1].sow = 1.0f; - v[0].tow = v[1].tow = 0.0f; - v[2].tow = v[3].tow = 1.0f; - - Surf.FlatColor.rgba = UINT2RGBA(color); - Surf.FlatColor.s.alpha = 0x80; - - HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest); -} - // -----------------+ // HWR_DrawDiag : draw flat coloured rectangle, with no texture // -----------------+ @@ -1097,22 +834,234 @@ void HWR_DrawDiag(INT32 x, INT32 y, INT32 wh, INT32 color) v[3].y = fy - fh; v[2].y = fy - fwait; - //Hurdler: do we still use this argb color? if not, we should remove it - v[0].argb = v[1].argb = v[2].argb = v[3].argb = 0xff00ff00; //; v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; - v[0].sow = v[3].sow = 0.0f; - v[2].sow = v[1].sow = 1.0f; - v[0].tow = v[1].tow = 0.0f; - v[2].tow = v[3].tow = 1.0f; + v[0].s = v[3].s = 0.0f; + v[2].s = v[1].s = 1.0f; + v[0].t = v[1].t = 0.0f; + v[2].t = v[3].t = 1.0f; - Surf.FlatColor = V_GetColor(color); + Surf.PolyColor = V_GetColor(color); HWD.pfnDrawPolygon(&Surf, v, 4, PF_Modulated|PF_NoTexture|PF_NoDepthTest); } +// -------------------+ +// HWR_DrawConsoleFill : draw flat coloured transparent rectangle because that's cool, and hw sucks less than sw for that. +// -------------------+ +void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, UINT32 color, INT32 options) +{ + FOutVector v[4]; + FSurfaceInfo Surf; + float fx, fy, fw, fh; + if (w < 0 || h < 0) + return; // consistency w/ software + +// 3--2 +// | /| +// |/ | +// 0--1 + + fx = (float)x; + fy = (float)y; + fw = (float)w; + fh = (float)h; + + if (!(options & V_NOSCALESTART)) + { + float dupx = (float)vid.dupx, dupy = (float)vid.dupy; + + if (x == 0 && y == 0 && w == BASEVIDWIDTH && h == BASEVIDHEIGHT) + { + RGBA_t rgbaColour = V_GetColor(color); + FRGBAFloat clearColour; + clearColour.red = (float)rgbaColour.s.red / 255; + clearColour.green = (float)rgbaColour.s.green / 255; + clearColour.blue = (float)rgbaColour.s.blue / 255; + clearColour.alpha = 1; + HWD.pfnClearBuffer(true, false, &clearColour); + return; + } + + fx *= dupx; + fy *= dupy; + fw *= dupx; + fh *= dupy; + + if (fabsf((float)vid.width - ((float)BASEVIDWIDTH * dupx)) > 1.0E-36f) + { + if (options & V_SNAPTORIGHT) + fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)); + else if (!(options & V_SNAPTOLEFT)) + fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 2; + } + if (fabsf((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) > 1.0E-36f) + { + // same thing here + if (options & V_SNAPTOBOTTOM) + fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)); + else if (!(options & V_SNAPTOTOP)) + fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 2; + } + if (options & V_SPLITSCREEN) + fy += ((float)BASEVIDHEIGHT * dupy)/2; + if (options & V_HORZSCREEN) + fx += ((float)BASEVIDWIDTH * dupx)/2; + + } + + if (fx >= vid.width || fy >= vid.height) + return; + if (fx < 0) + { + fw += fx; + fx = 0; + } + if (fy < 0) + { + fh += fy; + fy = 0; + } + + if (fw <= 0 || fh <= 0) + return; + if (fx + fw > vid.width) + fw = (float)vid.width - fx; + if (fy + fh > vid.height) + fh = (float)vid.height - fy; + + fx = -1 + fx / (vid.width / 2); + fy = 1 - fy / (vid.height / 2); + fw = fw / (vid.width / 2); + fh = fh / (vid.height / 2); + + v[0].x = v[3].x = fx; + v[2].x = v[1].x = fx + fw; + v[0].y = v[1].y = fy; + v[2].y = v[3].y = fy - fh; + + v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; + + v[0].s = v[3].s = 0.0f; + v[2].s = v[1].s = 1.0f; + v[0].t = v[1].t = 0.0f; + v[2].t = v[3].t = 1.0f; + + Surf.PolyColor.rgba = UINT2RGBA(color); + Surf.PolyColor.s.alpha = 0x80; + + HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest); +} + +// -----------------+ +// HWR_DrawFill : draw flat coloured rectangle, with no texture +// -----------------+ +void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color) +{ + FOutVector v[4]; + FSurfaceInfo Surf; + float fx, fy, fw, fh; + + if (w < 0 || h < 0) + return; // consistency w/ software + +// 3--2 +// | /| +// |/ | +// 0--1 + + fx = (float)x; + fy = (float)y; + fw = (float)w; + fh = (float)h; + + if (!(color & V_NOSCALESTART)) + { + float dupx = (float)vid.dupx, dupy = (float)vid.dupy; + + if (x == 0 && y == 0 && w == BASEVIDWIDTH && h == BASEVIDHEIGHT) + { + RGBA_t rgbaColour = V_GetColor(color); + FRGBAFloat clearColour; + clearColour.red = (float)rgbaColour.s.red / 255; + clearColour.green = (float)rgbaColour.s.green / 255; + clearColour.blue = (float)rgbaColour.s.blue / 255; + clearColour.alpha = 1; + HWD.pfnClearBuffer(true, false, &clearColour); + return; + } + + fx *= dupx; + fy *= dupy; + fw *= dupx; + fh *= dupy; + + if (fabsf((float)vid.width - (float)BASEVIDWIDTH * dupx) > 1.0E-36f) + { + if (color & V_SNAPTORIGHT) + fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)); + else if (!(color & V_SNAPTOLEFT)) + fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 2; + } + if (fabsf((float)vid.height - (float)BASEVIDHEIGHT * dupy) > 1.0E-36f) + { + // same thing here + if (color & V_SNAPTOBOTTOM) + fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)); + else if (!(color & V_SNAPTOTOP)) + fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 2; + } + if (color & V_SPLITSCREEN) + fy += ((float)BASEVIDHEIGHT * dupy)/2; + if (color & V_HORZSCREEN) + fx += ((float)BASEVIDWIDTH * dupx)/2; + + } + + if (fx >= vid.width || fy >= vid.height) + return; + if (fx < 0) + { + fw += fx; + fx = 0; + } + if (fy < 0) + { + fh += fy; + fy = 0; + } + + if (fw <= 0 || fh <= 0) + return; + if (fx + fw > vid.width) + fw = (float)vid.width - fx; + if (fy + fh > vid.height) + fh = (float)vid.height - fy; + + fx = -1 + fx / (vid.width / 2); + fy = 1 - fy / (vid.height / 2); + fw = fw / (vid.width / 2); + fh = fh / (vid.height / 2); + + v[0].x = v[3].x = fx; + v[2].x = v[1].x = fx + fw; + v[0].y = v[1].y = fy; + v[2].y = v[3].y = fy - fh; + + v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; + + v[0].s = v[3].s = 0.0f; + v[2].s = v[1].s = 1.0f; + v[0].t = v[1].t = 0.0f; + v[2].t = v[3].t = 1.0f; + + Surf.PolyColor = V_GetColor(color); + + HWD.pfnDrawPolygon(&Surf, v, 4, + PF_Modulated|PF_NoTexture|PF_NoDepthTest); +} #ifdef HAVE_PNG @@ -1196,21 +1145,24 @@ UINT8 *HWR_GetScreenshot(void) return buf; } -boolean HWR_Screenshot(const char *lbmname) +boolean HWR_Screenshot(const char *pathname) { boolean ret; UINT8 *buf = malloc(vid.width * vid.height * 3 * sizeof (*buf)); if (!buf) + { + CONS_Debug(DBG_RENDER, "HWR_Screenshot: Failed to allocate memory\n"); return false; + } // returns 24bit 888 RGB HWD.pfnReadRect(0, 0, vid.width, vid.height, vid.width * 3, (void *)buf); #ifdef USE_PNG - ret = M_SavePNG(lbmname, buf, vid.width, vid.height, NULL); + ret = M_SavePNG(pathname, buf, vid.width, vid.height, NULL); #else - ret = saveTGA(lbmname, buf, vid.width, vid.height); + ret = saveTGA(pathname, buf, vid.width, vid.height); #endif free(buf); return ret; diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h index 54bd9e786..bf8eb40f3 100644 --- a/src/hardware/hw_drv.h +++ b/src/hardware/hw_drv.h @@ -1,21 +1,15 @@ -// Emacs style mode select -*- C++ -*- +// SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// +// Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2019 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 -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// +// 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 -/// \brief imports/exports for the 3D hardware low-level interface API +/// \brief imports/exports for the GPU hardware low-level interface API #ifndef __HWR_DRV_H__ #define __HWR_DRV_H__ @@ -32,13 +26,7 @@ // STANDARD DLL EXPORTS // ========================================================================== -EXPORT boolean HWRAPI(Init) (I_Error_t ErrorFunction); -#ifndef HAVE_SDL -EXPORT void HWRAPI(Shutdown) (void); -#endif -#ifdef _WINDOWS -EXPORT void HWRAPI(GetModeList) (vmode_t **pvidmodes, INT32 *numvidmodes); -#endif +EXPORT boolean HWRAPI(Init) (void); #if defined (PURESDL) || defined (macintosh) EXPORT void HWRAPI(SetPalette) (INT32 *, RGBA_t *gamma); #else @@ -58,14 +46,13 @@ 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, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 *color); +EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, FSurfaceInfo *Surface); EXPORT void HWRAPI(CreateModelVBOs) (model_t *model); -EXPORT void HWRAPI(SetTransform) (FTransform *ptransform); +EXPORT void HWRAPI(SetTransform) (FTransform *stransform); EXPORT INT32 HWRAPI(GetTextureUsed) (void); -EXPORT INT32 HWRAPI(GetRenderVersion) (void); -#define SCREENVERTS 10 -EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]); +EXPORT void HWRAPI(RenderSkyDome) (INT32 tex, INT32 texture_width, INT32 texture_height, FTransform transform); + EXPORT void HWRAPI(FlushScreenTextures) (void); EXPORT void HWRAPI(StartScreenWipe) (void); EXPORT void HWRAPI(EndScreenWipe) (void); @@ -74,6 +61,22 @@ EXPORT void HWRAPI(DrawIntermissionBG) (void); EXPORT void HWRAPI(MakeScreenTexture) (void); EXPORT void HWRAPI(MakeScreenFinalTexture) (void); EXPORT void HWRAPI(DrawScreenFinalTexture) (int width, int height); + +#define SCREENVERTS 10 +EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]); + +// jimita +EXPORT boolean HWRAPI(LoadShaders) (void); +EXPORT void HWRAPI(KillShaders) (void); +EXPORT void HWRAPI(SetShader) (int shader); +EXPORT void HWRAPI(UnSetShader) (void); + +EXPORT void HWRAPI(LoadCustomShader) (int number, char *shader, size_t size, boolean fragment); +EXPORT void HWRAPI(InitCustomShaders) (void); + +EXPORT void HWRAPI(StartBatching) (void); +EXPORT void HWRAPI(RenderBatches) (int *sNumPolys, int *sNumVerts, int *sNumCalls, int *sNumShaders, int *sNumTextures, int *sNumPolyFlags, int *sNumColors); + // ========================================================================== // HWR DRIVER OBJECT, FOR CLIENT PROGRAM // ========================================================================== @@ -93,18 +96,11 @@ struct hwdriver_s ReadRect pfnReadRect; GClipRect pfnGClipRect; ClearMipMapCache pfnClearMipMapCache; - SetSpecialState pfnSetSpecialState;//Hurdler: added for backward compatibility + SetSpecialState pfnSetSpecialState; DrawModel pfnDrawModel; CreateModelVBOs pfnCreateModelVBOs; SetTransform pfnSetTransform; GetTextureUsed pfnGetTextureUsed; - GetRenderVersion pfnGetRenderVersion; -#ifdef _WINDOWS - GetModeList pfnGetModeList; -#endif -#ifndef HAVE_SDL - Shutdown pfnShutdown; -#endif PostImgRedraw pfnPostImgRedraw; FlushScreenTextures pfnFlushScreenTextures; StartScreenWipe pfnStartScreenWipe; @@ -114,16 +110,25 @@ struct hwdriver_s MakeScreenTexture pfnMakeScreenTexture; MakeScreenFinalTexture pfnMakeScreenFinalTexture; DrawScreenFinalTexture pfnDrawScreenFinalTexture; + + RenderSkyDome pfnRenderSkyDome; + + LoadShaders pfnLoadShaders; + KillShaders pfnKillShaders; + SetShader pfnSetShader; + UnSetShader pfnUnSetShader; + + LoadCustomShader pfnLoadCustomShader; + InitCustomShaders pfnInitCustomShaders; + + StartBatching pfnStartBatching; + RenderBatches pfnRenderBatches; }; extern struct hwdriver_s hwdriver; -//Hurdler: 16/10/99: added for OpenGL gamma correction -//extern RGBA_t gamma_correction; - #define HWD hwdriver #endif //not defined _CREATE_DLL_ -#endif //__HWR_DRV_H__ - +#endif //__HWR_DRV_H__ \ No newline at end of file diff --git a/src/hardware/hw_glide.h b/src/hardware/hw_glide.h deleted file mode 100644 index 2625d5864..000000000 --- a/src/hardware/hw_glide.h +++ /dev/null @@ -1,71 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1998-2000 by DooM Legacy Team. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -//----------------------------------------------------------------------------- -/// \file -/// \brief Declaration needed by Glide renderer -/// !!! To be replaced by our own def in the future !!! - -#ifndef _GLIDE_H_ -#define _GLIDE_H_ - -#ifndef __GLIDE_H__ - -typedef unsigned long FxU32; -typedef long FxI32; - -typedef FxI32 GrAspectRatio_t; -#define GR_ASPECT_LOG2_8x1 3 /* 8W x 1H */ -#define GR_ASPECT_LOG2_4x1 2 /* 4W x 1H */ -#define GR_ASPECT_LOG2_2x1 1 /* 2W x 1H */ -#define GR_ASPECT_LOG2_1x1 0 /* 1W x 1H */ -#define GR_ASPECT_LOG2_1x2 -1 /* 1W x 2H */ -#define GR_ASPECT_LOG2_1x4 -2 /* 1W x 4H */ -#define GR_ASPECT_LOG2_1x8 -3 /* 1W x 8H */ - -typedef FxI32 GrLOD_t; -#define GR_LOD_LOG2_256 0x8 -#define GR_LOD_LOG2_128 0x7 -#define GR_LOD_LOG2_64 0x6 -#define GR_LOD_LOG2_32 0x5 -#define GR_LOD_LOG2_16 0x4 -#define GR_LOD_LOG2_8 0x3 -#define GR_LOD_LOG2_4 0x2 -#define GR_LOD_LOG2_2 0x1 -#define GR_LOD_LOG2_1 0x0 - -typedef FxI32 GrTextureFormat_t; -#define GR_TEXFMT_ALPHA_8 0x2 /* (0..0xFF) alpha */ -#define GR_TEXFMT_INTENSITY_8 0x3 /* (0..0xFF) intensity */ -#define GR_TEXFMT_ALPHA_INTENSITY_44 0x4 -#define GR_TEXFMT_P_8 0x5 /* 8-bit palette */ -#define GR_TEXFMT_RGB_565 0xa -#define GR_TEXFMT_ARGB_1555 0xb -#define GR_TEXFMT_ARGB_4444 0xc -#define GR_TEXFMT_ALPHA_INTENSITY_88 0xd -#define GR_TEXFMT_AP_88 0xe /* 8-bit alpha 8-bit palette */ -#define GR_RGBA 0x6 // 32 bit RGBA ! - -typedef struct -{ - GrLOD_t smallLodLog2; - GrLOD_t largeLodLog2; - GrAspectRatio_t aspectRatioLog2; - GrTextureFormat_t format; - void *data; -} GrTexInfo; - -#endif // __GLIDE_H__ (defined in ) - -#endif // _GLIDE_H_ diff --git a/src/hardware/hw_glob.h b/src/hardware/hw_glob.h index 2fb7cff77..3d03e7fa1 100644 --- a/src/hardware/hw_glob.h +++ b/src/hardware/hw_glob.h @@ -1,18 +1,12 @@ -// Emacs style mode select -*- C++ -*- +// SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// +// Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2019 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 -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// +// 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 /// \brief globals (shared data & code) for hw_ modules @@ -21,78 +15,18 @@ #define _HWR_GLOB_H_ #include "hw_defs.h" -#include "hw_main.h" #include "../m_misc.h" - -// the original aspect ratio of Doom graphics isn't square -#define ORIGINAL_ASPECT (320.0f/200.0f) +#include "../r_defs.h" // Uncomment this to enable the OpenGL loading screen //#define HWR_LOADING_SCREEN -// ----------- -// structures -// ----------- - -// a vertex of a Doom 'plane' polygon -typedef struct -{ - float x; - float y; - float z; -} polyvertex_t; - -#ifdef _MSC_VER -#pragma warning(disable : 4200) -#endif - -// a convex 'plane' polygon, clockwise order -typedef struct -{ - INT32 numpts; - polyvertex_t pts[0]; -} poly_t; - -#ifdef _MSC_VER -#pragma warning(default : 4200) -#endif - -// holds extra info for 3D render, for each subsector in subsectors[] -typedef struct -{ - poly_t *planepoly; // the generated convex polygon -} extrasubsector_t; - -// needed for sprite rendering -// equivalent of the software renderer's vissprites -typedef struct gr_vissprite_s -{ - // Doubly linked list - struct gr_vissprite_s *prev; - struct gr_vissprite_s *next; - float x1, x2; - float tz, ty; - lumpnum_t patchlumpnum; - boolean flip; - UINT8 translucency; //alpha level 0-255 - mobj_t *mobj; - boolean precip; // Tails 08-25-2002 - boolean vflip; - //Hurdler: 25/04/2000: now support colormap in hardware mode - UINT8 *colormap; - INT32 dispoffset; // copy of info->dispoffset, affects ordering but not drawing - float z1, z2; -} gr_vissprite_t; - // -------- // hw_bsp.c // -------- extern extrasubsector_t *extrasubsectors; extern size_t addsubsector; -void HWR_InitPolyPool(void); -void HWR_FreePolyPool(void); - // -------- // hw_cache.c // -------- @@ -100,14 +34,14 @@ void HWR_InitTextureCache(void); void HWR_FreeTextureCache(void); void HWR_FreeExtraSubsectors(void); -void HWR_GetFlat(lumpnum_t flatlumpnum, boolean noencore); +void HWR_GetFlat(lumpnum_t flatlumpnum, boolean noencoremap); // ^ some flats must NOT be remapped to encore, since we remap them as we cache them for ease, adding a toggle here seems wise. GLTexture_t *HWR_GetTexture(INT32 tex); void HWR_GetPatch(GLPatch_t *gpatch); void HWR_GetMappedPatch(GLPatch_t *gpatch, const UINT8 *colormap); +void HWR_MakePatch(patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipmap, boolean makebitmap); void HWR_UnlockCachedPatch(GLPatch_t *gpatch); -GLPatch_t *HWR_GetPic(lumpnum_t lumpnum); void HWR_SetPalette(RGBA_t *palette); GLPatch_t *HWR_GetCachedGLPatchPwad(UINT16 wad, UINT16 lump); GLPatch_t *HWR_GetCachedGLPatch(lumpnum_t lumpnum); @@ -116,13 +50,9 @@ void HWR_GetFadeMask(lumpnum_t fademasklumpnum); // -------- // hw_draw.c // -------- -extern float gr_patch_scalex; -extern float gr_patch_scaley; - extern consvar_t cv_grrounddown; // on/off extern INT32 patchformat; extern INT32 textureformat; -extern boolean firetranslucent; -#endif //_HW_GLOB_ +#endif //_HW_GLOB_ \ No newline at end of file diff --git a/src/hardware/hw_light.c b/src/hardware/hw_light.c index ee0cca745..079349c37 100644 --- a/src/hardware/hw_light.c +++ b/src/hardware/hw_light.c @@ -1,21 +1,14 @@ -// Emacs style mode select -*- C++ -*- +// SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// +// Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2019 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 -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// 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 -/// \brief Corona/Dynamic/Static lighting add on by Hurdler -/// !!! Under construction !!! #include "../doomdef.h" @@ -31,1346 +24,4 @@ #include "../r_main.h" #include "../p_local.h" -//============================================================================= -// DEFINES -//============================================================================= - -#define DL_SQRRADIUS(x) dynlights->p_lspr[(x)]->dynamic_sqrradius -#define DL_RADIUS(x) dynlights->p_lspr[(x)]->dynamic_radius -#define LIGHT_POS(i) dynlights->position[(i)] - -#define DL_HIGH_QUALITY -//#define STATICLIGHT //Hurdler: TODO! -//#define LIGHTMAPFLAGS (PF_Masked|PF_Clip|PF_NoAlphaTest) // debug see overdraw -#define LIGHTMAPFLAGS (PF_Modulated|PF_Additive|PF_Clip) - -#ifdef ALAM_LIGHTING -static dynlights_t view_dynlights[4]; // 4 players for splitscreen modes -static dynlights_t *dynlights = &view_dynlights[0]; -#endif - -#define UNDEFINED_SPR 0x0 // actually just for testing -#define CORONA_SPR 0x1 // a light source which only emit a corona -#define DYNLIGHT_SPR 0x2 // a light source which is only used for dynamic lighting -#define LIGHT_SPR (DYNLIGHT_SPR|CORONA_SPR) -#define ROCKET_SPR (DYNLIGHT_SPR|CORONA_SPR|0x10) -//#define MONSTER_SPR 4 -//#define AMMO_SPR 8 -//#define BONUS_SPR 16 - -//Hurdler: now we can change those values via FS :) -light_t lspr[NUMLIGHTS] = -{ - // type offset x, y coronas color, c_size,light color,l_radius, sqr radius computed at init - // UNDEFINED: 0 - { UNDEFINED_SPR, 0.0f, 0.0f, 0x00000000, 24.0f, 0x00000000, 0.0f, 0.0f}, - // weapons - // RINGSPARK_L - { LIGHT_SPR, 0.0f, 0.0f, 0x0000e0ff, 16.0f, 0x0000e0ff, 32.0f, 0.0f}, // Tails 09-08-2002 - // SUPERSONIC_L - { DYNLIGHT_SPR, 0.0f, 0.0f, 0xff00e0ff, 32.0f, 0xff00e0ff, 128.0f, 0.0f}, // Tails 09-08-2002 - // SUPERSPARK_L - { LIGHT_SPR, 0.0f, 0.0f, 0xe0ffffff, 8.0f, 0xe0ffffff, 64.0f, 0.0f}, - // INVINCIBLE_L - { DYNLIGHT_SPR, 0.0f, 0.0f, 0x10ffaaaa, 16.0f, 0x10ffaaaa, 128.0f, 0.0f}, - // GREENSHIELD_L - { DYNLIGHT_SPR, 0.0f, 0.0f, 0x602b7337, 32.0f, 0x602b7337, 128.0f, 0.0f}, - // BLUESHIELD_L - { DYNLIGHT_SPR, 0.0f, 0.0f, 0x60cb0000, 32.0f, 0x60cb0000, 128.0f, 0.0f}, - - // tall lights - // YELLOWSHIELD_L - { DYNLIGHT_SPR, 0.0f, 0.0f, 0x601f7baf, 32.0f, 0x601f7baf, 128.0f, 0.0f}, - - // REDSHIELD_L - { DYNLIGHT_SPR, 0.0f, 0.0f, 0x600000cb, 32.0f, 0x600000cb, 128.0f, 0.0f}, - - // BLACKSHIELD_L // Black light? lol - { DYNLIGHT_SPR, 0.0f, 0.0f, 0x60010101, 32.0f, 0x60ff00ff, 128.0f, 0.0f}, - - // WHITESHIELD_L - { DYNLIGHT_SPR, 0.0f, 0.0f, 0x60ffffff, 32.0f, 0x60ffffff, 128.0f, 0.0f}, - - // SMALLREDBALL_L - { DYNLIGHT_SPR, 0.0f, 0.0f, 0x606060f0, 0.0f, 0x302070ff, 32.0f, 0.0f}, - - // small lights - // RINGLIGHT_L - { DYNLIGHT_SPR, 0.0f, 0.0f, 0x60b0f0f0, 0.0f, 0x30b0f0f0, 100.0f, 0.0f}, - // GREENSMALL_L - { LIGHT_SPR, 0.0f, 14.0f, 0x6070ff70, 60.0f, 0x4070ff70, 100.0f, 0.0f}, - // REDSMALL_L - { LIGHT_SPR, 0.0f, 14.0f, 0x705070ff, 60.0f, 0x405070ff, 100.0f, 0.0f}, - - // type offset x, y coronas color, c_size,light color,l_radius, sqr radius computed at init - // GREENSHINE_L - { LIGHT_SPR, 0.0f, 0.0f, 0xff00ff00, 64.0f, 0xff00ff00, 256.0f, 0.0f}, - // ORANGESHINE_L - { LIGHT_SPR, 0.0f, 0.0f, 0xff0080ff, 64.0f, 0xff0080ff, 256.0f, 0.0f}, - // PINKSHINE_L - { LIGHT_SPR, 0.0f, 0.0f, 0xffe080ff, 64.0f, 0xffe080ff, 256.0f, 0.0f}, - // BLUESHINE_L - { LIGHT_SPR, 0.0f, 0.0f, 0xffff0000, 64.0f, 0xffff0000, 256.0f, 0.0f}, - // REDSHINE_L - { LIGHT_SPR, 0.0f, 0.0f, 0xff0000ff, 64.0f, 0xff0000ff, 256.0f, 0.0f}, - // LBLUESHINE_L - { LIGHT_SPR, 0.0f, 0.0f, 0xffff8080, 64.0f, 0xffff8080, 256.0f, 0.0f}, - // GREYSHINE_L - { LIGHT_SPR, 0.0f, 0.0f, 0xffe0e0e0, 64.0f, 0xffe0e0e0, 256.0f, 0.0f}, - - // monsters - // REDBALL_L - { DYNLIGHT_SPR, 0.0f, 0.0f, 0x606060ff, 0.0f, 0x606060ff, 100.0f, 0.0f}, - // GREENBALL_L - { DYNLIGHT_SPR, 0.0f, 0.0f, 0x6060ff60, 120.0f, 0x6060ff60, 100.0f, 0.0f}, - // BLUEBALL_L - { DYNLIGHT_SPR, 0.0f, 0.0f, 0x60ff6060, 120.0f, 0x60ff6060, 100.0f, 0.0f}, - - // NIGHTSLIGHT_L - { LIGHT_SPR, 0.0f, 6.0f, 0x60ffffff, 16.0f, 0x30ffffff, 32.0f, 0.0f}, - - // JETLIGHT_L - { DYNLIGHT_SPR, 0.0f, 6.0f, 0x60ffaaaa, 16.0f, 0x30ffaaaa, 64.0f, 0.0f}, - - // GOOPLIGHT_L - { DYNLIGHT_SPR, 0.0f, 6.0f, 0x60ff00ff, 16.0f, 0x30ff00ff, 32.0f, 0.0f}, - - // STREETLIGHT_L - { LIGHT_SPR, 0.0f, 0.0f, 0xe0ffffff, 64.0f, 0xe0ffffff, 384.0f, 0.0f}, -}; - -light_t *t_lspr[NUMSPRITES] = -{ - &lspr[NOLIGHT], // SPR_NULL - &lspr[NOLIGHT], // SPR_UNKN - - &lspr[NOLIGHT], // SPR_THOK - &lspr[SUPERSONIC_L],// SPR_PLAY - - // Enemies - &lspr[NOLIGHT], // SPR_POSS - &lspr[NOLIGHT], // SPR_SPOS - &lspr[NOLIGHT], // SPR_FISH - &lspr[NOLIGHT], // SPR_BUZZ Graue 03-10-2004 - &lspr[NOLIGHT], // SPR_RBUZ Graue 03-10-2004 - &lspr[NOLIGHT], // SPR_JETB - &lspr[NOLIGHT], // SPR_JETW - &lspr[NOLIGHT], // SPR_JETG - &lspr[NOLIGHT], // SPR_CCOM - &lspr[NOLIGHT], // SPR_DETN - &lspr[NOLIGHT], // SPR_SKIM - &lspr[NOLIGHT], // SPR_TRET - &lspr[NOLIGHT], // SPR_TURR - &lspr[NOLIGHT], // SPR_SHRP - &lspr[NOLIGHT], // SPR_JJAW - &lspr[NOLIGHT], // SPR_SNLR - &lspr[NOLIGHT], // SPR_VLTR - &lspr[NOLIGHT], // SPR_PNTY - &lspr[NOLIGHT], // SPR_ARCH - &lspr[NOLIGHT], // SPR_CBFS - &lspr[NOLIGHT], // SPR_SPSH - &lspr[NOLIGHT], // SPR_ESHI - &lspr[NOLIGHT], // SPR_GSNP - &lspr[NOLIGHT], // SPR_MNUS - &lspr[NOLIGHT], // SPR_SSHL - &lspr[NOLIGHT], // SPR_UNID - &lspr[NOLIGHT], // SPR_BBUZ - - // Generic Boos Items - &lspr[JETLIGHT_L], // SPR_JETF // Boss jet fumes - - // Boss 1, (Greenflower) - &lspr[NOLIGHT], // SPR_EGGM - - // Boss 2, (Techno Hill) - &lspr[NOLIGHT], // SPR_EGGN - &lspr[NOLIGHT], // SPR_TNKA - &lspr[NOLIGHT], // SPR_TNKB - &lspr[NOLIGHT], // SPR_SPNK - &lspr[NOLIGHT], // SPR_GOOP - - // Boss 3 (Deep Sea) - &lspr[NOLIGHT], // SPR_EGGO - &lspr[NOLIGHT], // SPR_PRPL - &lspr[NOLIGHT], // SPR_FAKE - - // Boss 4 (Castle Eggman) - &lspr[NOLIGHT], // SPR_EGGP - &lspr[REDBALL_L], // SPR_EFIR - - // Boss 5 (Arid Canyon) - &lspr[NOLIGHT], // SPR_EGGQ - - // Boss 6 (Red Volcano) - &lspr[NOLIGHT], // SPR_EEGR - - // Boss 7 (Dark City) - &lspr[NOLIGHT], // SPR_BRAK - &lspr[NOLIGHT], // SPR_BGOO - &lspr[NOLIGHT], // SPR_BMSL - - // Boss 8 (Egg Rock) - &lspr[NOLIGHT], // SPR_EGGT - - &lspr[NOLIGHT], //SPR_RCKT - &lspr[NOLIGHT], //SPR_ELEC - &lspr[NOLIGHT], //SPR_TARG - &lspr[NOLIGHT], //SPR_NPLM - &lspr[NOLIGHT], //SPR_MNPL - - // Metal Sonic - &lspr[NOLIGHT], // SPR_METL - &lspr[NOLIGHT], // SPR_MSCF - &lspr[NOLIGHT], // SPR_MSCB - - // Collectible Items - &lspr[NOLIGHT], // SPR_RING - &lspr[NOLIGHT], // SPR_TRNG - &lspr[NOLIGHT], // SPR_EMMY - &lspr[BLUEBALL_L], // SPR_TOKE - &lspr[REDBALL_L], // SPR_RFLG - &lspr[BLUEBALL_L], // SPR_BFLG - &lspr[NOLIGHT], // SPR_NWNG - &lspr[NOLIGHT], // SPR_EMBM - &lspr[NOLIGHT], // SPR_CEMG - &lspr[NOLIGHT], // SPR_EMER - - // Interactive Objects - &lspr[NOLIGHT], // SPR_FANS - &lspr[NOLIGHT], // SPR_BUBL - &lspr[NOLIGHT], // SPR_SIGN - &lspr[NOLIGHT], // SPR_STEM - &lspr[NOLIGHT], // SPR_SPIK - &lspr[NOLIGHT], // SPR_SFLM - &lspr[NOLIGHT], // SPR_USPK - &lspr[NOLIGHT], // SPR_STPT - &lspr[NOLIGHT], // SPR_BMNE - - // Monitor Boxes - &lspr[NOLIGHT], // SPR_SRBX - &lspr[NOLIGHT], // SPR_RRBX - &lspr[NOLIGHT], // SPR_BRBX - &lspr[NOLIGHT], // SPR_SHTV - &lspr[NOLIGHT], // SPR_PINV - &lspr[NOLIGHT], // SPR_YLTV - &lspr[NOLIGHT], // SPR_BLTV - &lspr[NOLIGHT], // SPR_BKTV - &lspr[NOLIGHT], // SPR_WHTV - &lspr[NOLIGHT], // SPR_GRTV - &lspr[NOLIGHT], // SPR_ELTV - &lspr[NOLIGHT], // SPR_EGGB - &lspr[NOLIGHT], // SPR_MIXU - &lspr[NOLIGHT], // SPR_RECY - &lspr[NOLIGHT], // SPR_QUES - &lspr[NOLIGHT], // SPR_GBTV - &lspr[NOLIGHT], // SPR_PRUP - &lspr[NOLIGHT], // SPR_PTTV - - // Monitor Miscellany - &lspr[NOLIGHT], // SPR_MTEX - - // Projectiles - &lspr[NOLIGHT], // SPR_MISL - &lspr[NOLIGHT], // SPR_TORP - &lspr[NOLIGHT], // SPR_ENRG - &lspr[NOLIGHT], // SPR_MINE - &lspr[NOLIGHT], // SPR_JBUL - &lspr[SMALLREDBALL_L], // SPR_TRLS - &lspr[NOLIGHT], // SPR_CBLL - &lspr[NOLIGHT], // SPR_AROW - &lspr[NOLIGHT], // SPR_CFIR - - // Greenflower Scenery - &lspr[NOLIGHT], // SPR_FWR1 - &lspr[NOLIGHT], // SPR_FWR2 - &lspr[NOLIGHT], // SPR_FWR3 - &lspr[NOLIGHT], // SPR_FWR4 - &lspr[NOLIGHT], // SPR_BUS1 - &lspr[NOLIGHT], // SPR_BUS2 - - // Techno Hill Scenery - &lspr[NOLIGHT], // SPR_THZP - &lspr[REDBALL_L], // SPR_ALRM - - // Deep Sea Scenery - &lspr[NOLIGHT], // SPR_GARG - &lspr[NOLIGHT], // SPR_SEWE - &lspr[NOLIGHT], // SPR_DRIP - &lspr[NOLIGHT], // SPR_CRL1 - &lspr[NOLIGHT], // SPR_CRL2 - &lspr[NOLIGHT], // SPR_CRL3 - &lspr[NOLIGHT], // SPR_BCRY - - // Castle Eggman Scenery - &lspr[NOLIGHT], // SPR_CHAN - &lspr[REDBALL_L], // SPR_FLAM - &lspr[NOLIGHT], // SPR_ESTA - &lspr[NOLIGHT], // SPR_SMCH - &lspr[NOLIGHT], // SPR_BMCH - &lspr[NOLIGHT], // SPR_SMCE - &lspr[NOLIGHT], // SPR_BMCE - - // Arid Canyon Scenery - &lspr[NOLIGHT], // SPR_BTBL - &lspr[NOLIGHT], // SPR_STBL - &lspr[NOLIGHT], // SPR_CACT - - // Red Volcano Scenery - &lspr[REDBALL_L], // SPR_FLME - &lspr[REDBALL_L], // SPR_DFLM - - // Dark City Scenery - - // Egg Rock Scenery - - // Christmas Scenery - &lspr[NOLIGHT], // SPR_XMS1 - &lspr[NOLIGHT], // SPR_XMS2 - &lspr[NOLIGHT], // SPR_XMS3 - - // Botanic Serenity Scenery - &lspr[NOLIGHT], // SPR_BSZ1 - &lspr[NOLIGHT], // SPR_BSZ2 - &lspr[NOLIGHT], // SPR_BSZ3 - &lspr[NOLIGHT], // SPR_BSZ4 - &lspr[NOLIGHT], // SPR_BSZ5 - &lspr[NOLIGHT], // SPR_BSZ6 - &lspr[NOLIGHT], // SPR_BSZ7 - &lspr[NOLIGHT], // SPR_BSZ8 - - // Stalagmites - &lspr[NOLIGHT], // SPR_STLG - - // Disco Ball - &lspr[NOLIGHT], // SPR_DBAL - - // ATZ Red Crystal - &lspr[NOLIGHT], // SPR_RCRY - - // Powerup Indicators - &lspr[NOLIGHT], // SPR_ARMA - &lspr[NOLIGHT], // SPR_ARMF - &lspr[NOLIGHT], // SPR_ARMB - &lspr[NOLIGHT], // SPR_WIND - &lspr[NOLIGHT], // SPR_MAGN - &lspr[NOLIGHT], // SPR_ELEM - &lspr[NOLIGHT], // SPR_FORC - &lspr[NOLIGHT], // SPR_PITY - &lspr[INVINCIBLE_L], // SPR_IVSP - &lspr[SUPERSPARK_L], // SPR_SSPK - - &lspr[NOLIGHT], // SPR_GOAL - - // Freed Animals - &lspr[NOLIGHT], // SPR_BIRD - &lspr[NOLIGHT], // SPR_BUNY - &lspr[NOLIGHT], // SPR_MOUS - &lspr[NOLIGHT], // SPR_CHIC - &lspr[NOLIGHT], // SPR_COWZ - &lspr[NOLIGHT], // SPR_RBRD - - // Springs - &lspr[NOLIGHT], // SPR_SPRY - &lspr[NOLIGHT], // SPR_SPRR - &lspr[NOLIGHT], // SPR_SPRB Graue - &lspr[NOLIGHT], // SPR_YSPR - &lspr[NOLIGHT], // SPR_RSPR - - // Environmentals Effects - &lspr[NOLIGHT], // SPR_RAIN - &lspr[NOLIGHT], // SPR_SNO1 - &lspr[NOLIGHT], // SPR_SPLH - &lspr[NOLIGHT], // SPR_SPLA - &lspr[NOLIGHT], // SPR_SMOK - &lspr[NOLIGHT], // SPR_BUBP - &lspr[NOLIGHT], // SPR_BUBO - &lspr[NOLIGHT], // SPR_BUBN - &lspr[NOLIGHT], // SPR_BUBM - &lspr[NOLIGHT], // SPR_POPP - &lspr[SUPERSPARK_L], // SPR_TFOG - &lspr[NIGHTSLIGHT_L], // SPR_SEED // Sonic CD flower seed - &lspr[NOLIGHT], // SPR_PRTL - - // Game Indicators - &lspr[NOLIGHT], // SPR_SCOR - &lspr[NOLIGHT], // SPR_DRWN - &lspr[NOLIGHT], // SPR_TTAG - &lspr[NOLIGHT], // SPR_GFLG - - // Ring Weapons - &lspr[RINGLIGHT_L], // SPR_RRNG - &lspr[RINGLIGHT_L], // SPR_RNGB - &lspr[RINGLIGHT_L], // SPR_RNGR - &lspr[RINGLIGHT_L], // SPR_RNGI - &lspr[RINGLIGHT_L], // SPR_RNGA - &lspr[RINGLIGHT_L], // SPR_RNGE - &lspr[RINGLIGHT_L], // SPR_RNGS - &lspr[RINGLIGHT_L], // SPR_RNGG - - &lspr[RINGLIGHT_L], // SPR_PIKB - &lspr[RINGLIGHT_L], // SPR_PIKR - &lspr[RINGLIGHT_L], // SPR_PIKA - &lspr[RINGLIGHT_L], // SPR_PIKE - &lspr[RINGLIGHT_L], // SPR_PIKS - &lspr[RINGLIGHT_L], // SPR_PIKG - - &lspr[RINGLIGHT_L], // SPR_TAUT - &lspr[RINGLIGHT_L], // SPR_TGRE - &lspr[RINGLIGHT_L], // SPR_TSCR - - // Mario-specific stuff - &lspr[NOLIGHT], // SPR_COIN - &lspr[NOLIGHT], // SPR_CPRK - &lspr[NOLIGHT], // SPR_GOOM - &lspr[NOLIGHT], // SPR_BGOM - &lspr[REDBALL_L], // SPR_FFWR - &lspr[SMALLREDBALL_L], // SPR_FBLL - &lspr[NOLIGHT], // SPR_SHLL - &lspr[REDBALL_L], // SPR_PUMA - &lspr[NOLIGHT], // SPR_HAMM - &lspr[NOLIGHT], // SPR_KOOP - &lspr[REDBALL_L], // SPR_BFLM - &lspr[NOLIGHT], // SPR_MAXE - &lspr[NOLIGHT], // SPR_MUS1 - &lspr[NOLIGHT], // SPR_MUS2 - &lspr[NOLIGHT], // SPR_TOAD - - // NiGHTS Stuff - &lspr[SUPERSONIC_L], // SPR_NDRN // NiGHTS drone - &lspr[SUPERSONIC_L], // SPR_SUPE // NiGHTS character flying - &lspr[SUPERSONIC_L], // SPR_SUPZ // NiGHTS hurt - &lspr[SUPERSONIC_L], // SPR_NDRL // NiGHTS character drilling - &lspr[NOLIGHT], // SPR_NSPK - &lspr[NOLIGHT], // SPR_NBMP - &lspr[NOLIGHT], // SPR_HOOP - &lspr[NOLIGHT], // SPR_HSCR - &lspr[NOLIGHT], // SPR_NPRU - &lspr[NOLIGHT], // SPR_CAPS - &lspr[SUPERSONIC_L], // SPR_SUPT - - // Debris - &lspr[RINGSPARK_L], // SPR_SPRK - &lspr[NOLIGHT], // SPR_BOM1 - &lspr[SUPERSPARK_L], // SPR_BOM2 - &lspr[SUPERSPARK_L], // SPR_BOM3 - &lspr[NOLIGHT], // SPR_BOM4 - - // Crumbly rocks - &lspr[NOLIGHT], // SPR_ROIA - &lspr[NOLIGHT], // SPR_ROIB - &lspr[NOLIGHT], // SPR_ROIC - &lspr[NOLIGHT], // SPR_ROID - &lspr[NOLIGHT], // SPR_ROIE - &lspr[NOLIGHT], // SPR_ROIF - &lspr[NOLIGHT], // SPR_ROIG - &lspr[NOLIGHT], // SPR_ROIH - &lspr[NOLIGHT], // SPR_ROII - &lspr[NOLIGHT], // SPR_ROIJ - &lspr[NOLIGHT], // SPR_ROIK - &lspr[NOLIGHT], // SPR_ROIL - &lspr[NOLIGHT], // SPR_ROIM - &lspr[NOLIGHT], // SPR_ROIN - &lspr[NOLIGHT], // SPR_ROIO - &lspr[NOLIGHT], // SPR_ROIP - - // Blue Spheres - &lspr[NOLIGHT], // SPR_BBAL - - // Gravity Well Objects - &lspr[NOLIGHT], // SPR_GWLG - &lspr[NOLIGHT], // SPR_GWLR - - // SRB1 Sprites - &lspr[NOLIGHT], // SPR_SRBA - &lspr[NOLIGHT], // SPR_SRBB - &lspr[NOLIGHT], // SPR_SRBC - &lspr[NOLIGHT], // SPR_SRBD - &lspr[NOLIGHT], // SPR_SRBE - &lspr[NOLIGHT], // SPR_SRBF - &lspr[NOLIGHT], // SPR_SRBG - &lspr[NOLIGHT], // SPR_SRBH - &lspr[NOLIGHT], // SPR_SRBI - &lspr[NOLIGHT], // SPR_SRBJ - &lspr[NOLIGHT], // SPR_SRBK - &lspr[NOLIGHT], // SPR_SRBL - &lspr[NOLIGHT], // SPR_SRBM - &lspr[NOLIGHT], // SPR_SRBN - &lspr[NOLIGHT], // SPR_SRBO - - &lspr[NOLIGHT], //"SPRG", - &lspr[NOLIGHT], //"BSPR", - - &lspr[NOLIGHT], //"RNDM", - &lspr[NOLIGHT], //"KFRE", - &lspr[NOLIGHT], //"DRIF", - &lspr[NOLIGHT], //"DSMO", - - &lspr[NOLIGHT], //"FITM", - &lspr[NOLIGHT], //"BANA", - &lspr[NOLIGHT], //"GSHE", - &lspr[NOLIGHT], //"RSHE", - &lspr[NOLIGHT], //"SSMN", - &lspr[NOLIGHT], //"BLIG", - &lspr[NOLIGHT], //"LIGH", - &lspr[NOLIGHT], //"SINK", - &lspr[NOLIGHT], //"SITR", - &lspr[NOLIGHT], //"KBLN", - - &lspr[NOLIGHT], //"LAKI", - - &lspr[NOLIGHT], //"POKE", - &lspr[NOLIGHT], //"AUDI", - &lspr[NOLIGHT], //"DECO", - &lspr[NOLIGHT], //"DOOD", - &lspr[NOLIGHT], //"SNES", - &lspr[NOLIGHT], //"GBAS", - &lspr[NOLIGHT], //"SPRS", - &lspr[NOLIGHT], //"BUZB", - &lspr[NOLIGHT], //"CHOM", - &lspr[NOLIGHT], //"SACO", - &lspr[NOLIGHT], //"CRAB", - &lspr[NOLIGHT], //"SHAD", - - &lspr[NOLIGHT], //"BUMP", - &lspr[NOLIGHT], //"FLEN", - &lspr[NOLIGHT], //"CLAS", - &lspr[NOLIGHT], //"PSHW", - - &lspr[NOLIGHT], //"ARRO", - - &lspr[NOLIGHT], //"PBOM" - - // Free slots - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], - &lspr[NOLIGHT], -}; - -#ifdef ALAM_LIGHTING - -//============================================================================= -// PROTOS -//============================================================================= - -static void HWR_SetLight(void); - -// -------------------------------------------------------------------------- -// calcul la projection d'un point sur une droite (determin� par deux -// points) et ensuite calcul la distance (au carr� de ce point au point -// project�sur cette droite -// -------------------------------------------------------------------------- -static float HWR_DistP2D(FOutVector *p1, FOutVector *p2, FVector *p3, FVector *inter) -{ - if (p1->z == p2->z) - { - inter->x = p3->x; - inter->z = p1->z; - } - else if (p1->x == p2->x) - { - inter->x = p1->x; - inter->z = p3->z; - } - else - { - register float local, pente; - // Wat een mooie formula! Hurdler's math;-) - pente = (p1->z-p2->z) / (p1->x-p2->x); - local = p1->z - p1->x*pente; - inter->x = (p3->z - local + p3->x/pente) * (pente/(pente*pente+1)); - inter->z = inter->x*pente + local; - } - - return (p3->x-inter->x)*(p3->x-inter->x) + (p3->z-inter->z)*(p3->z-inter->z); -} - -// check if sphere (radius r) centred in p3 touch the bounding box defined by p1, p2 -static boolean SphereTouchBBox3D(FOutVector *p1, FOutVector *p2, FVector *p3, float r) -{ - float minx = p1->x,maxx = p2->x,miny = p2->y,maxy = p1->y,minz = p2->z,maxz = p1->z; - - if (minx > maxx) - { - minx = maxx; - maxx = p1->x; - } - if (miny > maxy) - { - miny = maxy; - maxy = p2->y; - } - if (minz > maxz) - { - minz = maxz; - maxz = p2->z; - } - - if (minx-r > p3->x) return false; - if (maxx+r < p3->x) return false; - if (miny-r > p3->y) return false; - if (maxy+r < p3->y) return false; - if (minz-r > p3->z) return false; - if (maxz+r < p3->z) return false; - return true; -} - -// Hurdler: The old code was removed by me because I don't think it will be used one day. -// (It's still available on the CVS for educational purpose: Revision 1.8) - -// -------------------------------------------------------------------------- -// calcul du dynamic lighting sur les murs -// lVerts contient les coords du mur sans le mlook (up/down) -// -------------------------------------------------------------------------- -void HWR_WallLighting(FOutVector *wlVerts) -{ - int i, j; - - // dynlights->nb == 0 if cv_grdynamiclighting.value is not set - for (j = 0; j < dynlights->nb; j++) - { - FVector inter; - FSurfaceInfo Surf; - float dist_p2d, d[4], s; - - // check bounding box first - if (SphereTouchBBox3D(&wlVerts[2], &wlVerts[0], &LIGHT_POS(j), DL_RADIUS(j))==false) - continue; - d[0] = wlVerts[2].x - wlVerts[0].x; - d[1] = wlVerts[2].z - wlVerts[0].z; - d[2] = LIGHT_POS(j).x - wlVerts[0].x; - d[3] = LIGHT_POS(j).z - wlVerts[0].z; - // backface cull - if (d[2]*d[1] - d[3]*d[0] < 0) - continue; - // check exact distance - dist_p2d = HWR_DistP2D(&wlVerts[2], &wlVerts[0], &LIGHT_POS(j), &inter); - if (dist_p2d >= DL_SQRRADIUS(j)) - continue; - - d[0] = (float)sqrt((wlVerts[0].x-inter.x)*(wlVerts[0].x-inter.x) - + (wlVerts[0].z-inter.z)*(wlVerts[0].z-inter.z)); - d[1] = (float)sqrt((wlVerts[2].x-inter.x)*(wlVerts[2].x-inter.x) - + (wlVerts[2].z-inter.z)*(wlVerts[2].z-inter.z)); - //dAB = sqrtf((wlVerts[0].x-wlVerts[2].x)*(wlVerts[0].x-wlVerts[2].x)+(wlVerts[0].z-wlVerts[2].z)*(wlVerts[0].z-wlVerts[2].z)); - //if ((d[0] < dAB) && (d[1] < dAB)) // test if the intersection is on the wall - //{ - // d[0] = -d[0]; // if yes, the left distcance must be negative for texcoord - //} - // test if the intersection is on the wall - if ((wlVerts[0].x < inter.x && wlVerts[2].x > inter.x) || - (wlVerts[0].x > inter.x && wlVerts[2].x < inter.x) || - (wlVerts[0].z < inter.z && wlVerts[2].z > inter.z) || - (wlVerts[0].z > inter.z && wlVerts[2].z < inter.z)) - { - d[0] = -d[0]; // if yes, the left distcance must be negative for texcoord - } - d[2] = d[1]; d[3] = d[0]; -#ifdef DL_HIGH_QUALITY - s = 0.5f / DL_RADIUS(j); -#else - s = 0.5f / sqrtf(DL_SQRRADIUS(j)-dist_p2d); -#endif - for (i = 0; i < 4; i++) - { - wlVerts[i].sow = (float)(0.5f + d[i]*s); - wlVerts[i].tow = (float)(0.5f + (wlVerts[i].y-LIGHT_POS(j).y)*s*1.2f); - } - - HWR_SetLight(); - - Surf.FlatColor.rgba = LONG(dynlights->p_lspr[j]->dynamic_color); -#ifdef DL_HIGH_QUALITY - Surf.FlatColor.s.alpha = (UINT8)((1-dist_p2d/DL_SQRRADIUS(j))*Surf.FlatColor.s.alpha); -#endif - if (!dynlights->mo[j]->state) - return; - // next state is null so fade out with alpha - if (dynlights->mo[j]->state->nextstate == S_NULL) - Surf.FlatColor.s.alpha = (UINT8)(((float)dynlights->mo[j]->tics/(float)dynlights->mo[j]->state->tics)*Surf.FlatColor.s.alpha); - - HWD.pfnDrawPolygon (&Surf, wlVerts, 4, LIGHTMAPFLAGS); - - } // end for (j = 0; j < dynlights->nb; j++) -} - -// -------------------------------------------------------------------------- -// calcul du dynamic lighting sur le sol -// clVerts contient les coords du sol avec le mlook (up/down) -// -------------------------------------------------------------------------- -void HWR_PlaneLighting(FOutVector *clVerts, int nrClipVerts) -{ - int i, j; - FOutVector p1,p2; - - p1.z = FIXED_TO_FLOAT(hwbbox[BOXTOP ]); - p1.x = FIXED_TO_FLOAT(hwbbox[BOXLEFT ]); - p2.z = FIXED_TO_FLOAT(hwbbox[BOXBOTTOM]); - p2.x = FIXED_TO_FLOAT(hwbbox[BOXRIGHT ]); - p2.y = clVerts[0].y; - p1.y = clVerts[0].y; - - for (j = 0; j < dynlights->nb; j++) - { - FSurfaceInfo Surf; - float dist_p2d, s; - - // BP: The kickass Optimization: check if light touch bounding box - if (SphereTouchBBox3D(&p1, &p2, &dynlights->position[j], DL_RADIUS(j))==false) - continue; - // backface cull - //Hurdler: doesn't work with new TANDL code - if ((clVerts[0].y > atransform.z) // true mean it is a ceiling false is a floor - ^ (LIGHT_POS(j).y < clVerts[0].y)) // true mean light is down plane false light is up plane - continue; - dist_p2d = (clVerts[0].y-LIGHT_POS(j).y); - dist_p2d *= dist_p2d; - // done in SphereTouchBBox3D - //if (dist_p2d >= DL_SQRRADIUS(j)) - // continue; - -#ifdef DL_HIGH_QUALITY - s = 0.5f / DL_RADIUS(j); -#else - s = 0.5f / sqrtf(DL_SQRRADIUS(j)-dist_p2d); -#endif - for (i = 0; i < nrClipVerts; i++) - { - clVerts[i].sow = 0.5f + (clVerts[i].x-LIGHT_POS(j).x)*s; - clVerts[i].tow = 0.5f + (clVerts[i].z-LIGHT_POS(j).z)*s*1.2f; - } - - HWR_SetLight(); - - Surf.FlatColor.rgba = LONG(dynlights->p_lspr[j]->dynamic_color); -#ifdef DL_HIGH_QUALITY - Surf.FlatColor.s.alpha = (unsigned char)((1 - dist_p2d/DL_SQRRADIUS(j))*Surf.FlatColor.s.alpha); -#endif - if (!dynlights->mo[j]->state) - return; - // next state is null so fade out with alpha - if ((dynlights->mo[j]->state->nextstate == S_NULL)) - Surf.FlatColor.s.alpha = (unsigned char)(((float)dynlights->mo[j]->tics/(float)dynlights->mo[j]->state->tics)*Surf.FlatColor.s.alpha); - - HWD.pfnDrawPolygon (&Surf, clVerts, nrClipVerts, LIGHTMAPFLAGS); - - } // end for (j = 0; j < dynlights->nb; j++) -} - - -static lumpnum_t coronalumpnum = LUMPERROR; -#ifndef NEWCORONAS -// -------------------------------------------------------------------------- -// coronas lighting -// -------------------------------------------------------------------------- -void HWR_DoCoronasLighting(FOutVector *outVerts, gr_vissprite_t *spr) -{ - light_t *p_lspr; - - if (coronalumpnum == LUMPERROR) - return; - - //CONS_Debug(DBG_RENDER, "sprite (type): %d (%s)\n", spr->type, sprnames[spr->type]); - p_lspr = t_lspr[spr->mobj->sprite]; - if ((spr->mobj->state>=&states[S_EXPLODE1] && spr->mobj->state<=&states[S_EXPLODE3]) - || (spr->mobj->state>=&states[S_FATSHOTX1] && spr->mobj->state<=&states[S_FATSHOTX3])) - { - p_lspr = &lspr[ROCKETEXP_L]; - } - - if (cv_grcoronas.value && (p_lspr->type & CORONA_SPR)) - { // it's an object which emits light - FOutVector light[4]; - FSurfaceInfo Surf; - float cx = 0.0f, cy = 0.0f, cz = 0.0f; // gravity center - float size; - UINT8 i; - - switch (p_lspr->type) - { - case LIGHT_SPR: - size = p_lspr->corona_radius * ((outVerts[0].z+120.0f)/950.0f); // d'ou vienne ces constante ? - break; - case ROCKET_SPR: - p_lspr->corona_color = (((M_RandomByte()>>1)&0xff)<<24)|0x0040ff; - // don't need a break - case CORONA_SPR: - size = p_lspr->corona_radius * ((outVerts[0].z+60.0f)/100.0f); // d'ou vienne ces constante ? - break; - default: - I_Error("HWR_DoCoronasLighting: unknow light type %d",p_lspr->type); - return; - } - if (size > p_lspr->corona_radius) - size = p_lspr->corona_radius; - size *= FIXED_TO_FLOAT(cv_grcoronasize.value<<1); - - // compute position doing average - for (i = 0; i < 4; i++) - { - cx += outVerts[i].x; - cy += outVerts[i].y; - cz += outVerts[i].z; - } - cx /= 4.0f; cy /= 4.0f; cz /= 4.0f; - - // more realistique corona ! - if (cz >= 255*8+250) - return; - Surf.FlatColor.rgba = p_lspr->corona_color; - if (cz > 250.0f) - Surf.FlatColor.s.alpha = 0xff-((int)cz-250)/8; - else - Surf.FlatColor.s.alpha = 0xff; - - // do not be hide by sprite of the light itself ! - cz = cz - 2.0f; - - // Bp; je comprend pas, ou est la rotation haut/bas ? - // tu ajoute un offset a y mais si la tu la reguarde de haut - // sa devrais pas marcher ... comprend pas :( - // (...) bon je croit que j'ai comprit il est tout pourit le code ? - // car comme l'offset est minime sa ce voit pas ! - light[0].x = cx-size; light[0].z = cz; - light[0].y = cy-size*1.33f+p_lspr->light_yoffset; - light[0].sow = 0.0f; light[0].tow = 0.0f; - - light[1].x = cx+size; light[1].z = cz; - light[1].y = cy-size*1.33f+p_lspr->light_yoffset; - light[1].sow = 1.0f; light[1].tow = 0.0f; - - light[2].x = cx+size; light[2].z = cz; - light[2].y = cy+size*1.33f+p_lspr->light_yoffset; - light[2].sow = 1.0f; light[2].tow = 1.0f; - - light[3].x = cx-size; light[3].z = cz; - light[3].y = cy+size*1.33f+p_lspr->light_yoffset; - light[3].sow = 0.0f; light[3].tow = 1.0f; - - HWR_GetPic(coronalumpnum); /// \todo use different coronas - - HWD.pfnDrawPolygon (&Surf, light, 4, PF_Modulated | PF_Additive | PF_Clip | PF_Corona | PF_NoDepthTest); - } -} -#endif - -#ifdef NEWCORONAS -// use the lightlist of the frame to draw the coronas at the top of everythink -void HWR_DrawCoronas(void) -{ - int j; - - if (!cv_grcoronas.value || dynlights->nb <= 0 || coronalumpnum == LUMPERROR) - return; - - HWR_GetPic(coronalumpnum); /// \todo use different coronas - for (j = 0;j < dynlights->nb;j++) - { - FOutVector light[4]; - FSurfaceInfo Surf; - float cx = LIGHT_POS(j).x; - float cy = LIGHT_POS(j).y; - float cz = LIGHT_POS(j).z; // gravity center - float size; - light_t *p_lspr = dynlights->p_lspr[j]; - - // it's an object which emits light - if (!(p_lspr->type & CORONA_SPR)) - continue; - - transform(&cx,&cy,&cz); - - // more realistique corona ! - if (cz >= 255*8+250) - continue; - Surf.FlatColor.rgba = p_lspr->corona_color; - if (cz > 250.0f) - Surf.FlatColor.s.alpha = (UINT8)(0xff-(UINT8)(((int)cz-250)/8)); - else - Surf.FlatColor.s.alpha = 0xff; - - switch (p_lspr->type) - { - case LIGHT_SPR: - size = p_lspr->corona_radius * ((cz+120.0f)/950.0f); // d'ou vienne ces constante ? - break; - case ROCKET_SPR: - Surf.FlatColor.s.alpha = (UINT8)((M_RandomByte()>>1)&0xff); - // don't need a break - case CORONA_SPR: - size = p_lspr->corona_radius * ((cz+60.0f)/100.0f); // d'ou vienne ces constante ? - break; - default: - I_Error("HWR_DoCoronasLighting: unknow light type %d",p_lspr->type); - continue; - } - if (size > p_lspr->corona_radius) - size = p_lspr->corona_radius; - size = (float)(FIXED_TO_FLOAT(cv_grcoronasize.value<<1)*size); - - // put light little forward the sprite so there is no - // z-buffer problem (coplanar polygons) - // BP: use PF_Decal do not help :( - cz = cz - 5.0f; - - light[0].x = cx-size; light[0].z = cz; - light[0].y = cy-size*1.33f; - light[0].sow = 0.0f; light[0].tow = 0.0f; - - light[1].x = cx+size; light[1].z = cz; - light[1].y = cy-size*1.33f; - light[1].sow = 1.0f; light[1].tow = 0.0f; - - light[2].x = cx+size; light[2].z = cz; - light[2].y = cy+size*1.33f; - light[2].sow = 1.0f; light[2].tow = 1.0f; - - light[3].x = cx-size; light[3].z = cz; - light[3].y = cy+size*1.33f; - light[3].sow = 0.0f; light[3].tow = 1.0f; - - HWD.pfnDrawPolygon (&Surf, light, 4, PF_Modulated | PF_Additive | PF_Clip | PF_NoDepthTest | PF_Corona); - } -} -#endif - -// -------------------------------------------------------------------------- -// Remove all the dynamic lights at eatch frame -// -------------------------------------------------------------------------- -void HWR_ResetLights(void) -{ - dynlights->nb = 0; -} - -// -------------------------------------------------------------------------- -// Change view, thus change lights (splitscreen) -// -------------------------------------------------------------------------- -void HWR_SetLights(int viewnumber) -{ - dynlights = &view_dynlights[viewnumber]; -} - -// -------------------------------------------------------------------------- -// Add a light for dynamic lighting -// The light position is already transformed execpt for mlook -// -------------------------------------------------------------------------- -void HWR_DL_AddLight(gr_vissprite_t *spr, GLPatch_t *patch) -{ - light_t *p_lspr; - - //Hurdler: moved here because it's better;-) - (void)patch; - if (!cv_grdynamiclighting.value) - return; - - if (!spr->mobj) -#ifdef PARANOIA - I_Error("vissprite without mobj !!!"); -#else - return; -#endif - - // check if sprite contain dynamic light - p_lspr = t_lspr[spr->mobj->sprite]; - if ((p_lspr->type&DYNLIGHT_SPR) - && ((p_lspr->type != LIGHT_SPR) || cv_grstaticlighting.value) - && (dynlights->nb < DL_MAX_LIGHT) - - && spr->mobj->state) - { - LIGHT_POS(dynlights->nb).x = FIXED_TO_FLOAT(spr->mobj->x); - LIGHT_POS(dynlights->nb).y = FIXED_TO_FLOAT(spr->mobj->z)+FIXED_TO_FLOAT(spr->mobj->height>>1)+p_lspr->light_yoffset; - LIGHT_POS(dynlights->nb).z = FIXED_TO_FLOAT(spr->mobj->y); - - P_SetTarget(&dynlights->mo[dynlights->nb], spr->mobj); - - dynlights->p_lspr[dynlights->nb] = p_lspr; - - dynlights->nb++; - } -} - -static GLPatch_t lightmappatch; - -void HWR_InitLight(void) -{ - size_t i; - - // precalculate sqr radius - for (i = 0;i < NUMLIGHTS;i++) - lspr[i].dynamic_sqrradius = lspr[i].dynamic_radius*lspr[i].dynamic_radius; - - lightmappatch.mipmap.downloaded = false; - coronalumpnum = W_CheckNumForName("CORONA"); -} - -// -----------------+ -// HWR_SetLight : Download a disc shaped alpha map for rendering fake lights -// -----------------+ -static void HWR_SetLight(void) -{ - int i, j; - - if (!lightmappatch.mipmap.downloaded && !lightmappatch.mipmap.grInfo.data) - { - - UINT16 *Data = Z_Malloc(129*128*sizeof (UINT16), PU_HWRCACHE, &lightmappatch.mipmap.grInfo.data); - - for (i = 0; i < 128; i++) - { - for (j = 0; j < 128; j++) - { - int pos = ((i-64)*(i-64))+((j-64)*(j-64)); - if (pos <= 63*63) - Data[i*128+j] = (UINT16)(((UINT8)(255-(4*(float)sqrt((float)pos)))) << 8 | 0xff); - else - Data[i*128+j] = 0; - } - } - lightmappatch.mipmap.grInfo.format = GR_TEXFMT_ALPHA_INTENSITY_88; - - lightmappatch.width = 128; - lightmappatch.height = 128; - lightmappatch.mipmap.width = 128; - lightmappatch.mipmap.height = 128; - lightmappatch.mipmap.grInfo.smallLodLog2 = GR_LOD_LOG2_128; - lightmappatch.mipmap.grInfo.largeLodLog2 = GR_LOD_LOG2_128; - lightmappatch.mipmap.grInfo.aspectRatioLog2 = GR_ASPECT_LOG2_1x1; - lightmappatch.mipmap.flags = 0; //TF_WRAPXY; // DEBUG: view the overdraw ! - } - HWD.pfnSetTexture(&lightmappatch.mipmap); - - // The system-memory data can be purged now. - Z_ChangeTag(lightmappatch.mipmap.grInfo.data, PU_HWRCACHE_UNLOCKED); -} - -//********************************************************** -// Hurdler: new code for faster static lighting and and T&L -//********************************************************** - -#ifdef STATICLIGHT -// is this really necessary? -static sector_t *lgr_backsector; -static seg_t *lgr_curline; -#endif - -// p1 et p2 c'est le deux bou du seg en float -static inline void HWR_BuildWallLightmaps(FVector *p1, FVector *p2, int lighnum, seg_t *line) -{ - lightmap_t *lp; - - // (...) calcul presit de la projection et de la distance - -// if (dist_p2d >= DL_SQRRADIUS(lightnum)) -// return; - - // (...) attention faire le backfase cull histoir de faire mieux que Q3 ! - - (void)lighnum; - (void)p1; - (void)p2; - lp = malloc(sizeof (*lp)); - lp->next = line->lightmaps; - line->lightmaps = lp; - - // (...) encore des b�calcul bien lourd et on stock tout sa dans la lightmap -} - -#ifdef STATICLIGHT -static void HWR_AddLightMapForLine(int lightnum, seg_t *line) -{ - /* - int x1; - int x2; - angle_t angle1; - angle_t angle2; - angle_t span; - angle_t tspan; - */ - FVector p1,p2; - - lgr_curline = line; - lgr_backsector = line->backsector; - - // Reject empty lines used for triggers and special events. - // Identical floor and ceiling on both sides, - // identical light levels on both sides, - // and no middle texture. -/* - if ( lgr_backsector->ceilingpic == gr_frontsector->ceilingpic - && lgr_backsector->floorpic == gr_frontsector->floorpic - && lgr_backsector->lightlevel == gr_frontsector->lightlevel - && lgr_curline->sidedef->midtexture == 0) - { - return; - } -*/ - - p1.y = FIXED_TO_FLOAT(lgr_curline->v1->y); - p1.x = FIXED_TO_FLOAT(lgr_curline->v1->x); - p2.y = FIXED_TO_FLOAT(lgr_curline->v2->y); - p2.x = FIXED_TO_FLOAT(lgr_curline->v2->x); - - // check bbox of the seg -// if (CircleTouchBBox(&p1, &p2, &LIGHT_POS(lightnum), DL_RADIUS(lightnum))==false) -// return; - - HWR_BuildWallLightmaps(&p1, &p2, lightnum, line); -} - -/// \todo see what HWR_AddLine does -static void HWR_CheckSubsector(size_t num, fixed_t *bbox) -{ - int count; - seg_t *line; - subsector_t *sub; - FVector p1,p2; - int lightnum; - - p1.y = FIXED_TO_FLOAT(bbox[BOXTOP ]); - p1.x = FIXED_TO_FLOAT(bbox[BOXLEFT ]); - p2.y = FIXED_TO_FLOAT(bbox[BOXBOTTOM]); - p2.x = FIXED_TO_FLOAT(bbox[BOXRIGHT ]); - - - if (num < numsubsectors) - { - sub = &subsectors[num]; // subsector - for (lightnum = 0; lightnum < dynlights->nb; lightnum++) - { -// if (CircleTouchBBox(&p1, &p2, &LIGHT_POS(lightnum), DL_RADIUS(lightnum))==false) -// continue; - - count = sub->numlines; // how many linedefs - line = &segs[sub->firstline]; // first line seg - while (count--) - { - HWR_AddLightMapForLine (lightnum, line); // compute lightmap - line++; - } - } - } -} - - -// -------------------------------------------------------------------------- -// Hurdler: this adds lights by mobj. -// -------------------------------------------------------------------------- -static void HWR_AddMobjLights(mobj_t *thing) -{ - if (t_lspr[thing->sprite]->type & CORONA_SPR) - { - LIGHT_POS(dynlights->nb).x = FIXED_TO_FLOAT(thing->x); - LIGHT_POS(dynlights->nb).y = FIXED_TO_FLOAT(thing->z) + t_lspr[thing->sprite]->light_yoffset; - LIGHT_POS(dynlights->nb).z = FIXED_TO_FLOAT(thing->y); - - dynlights->p_lspr[dynlights->nb] = t_lspr[thing->sprite]; - - dynlights->nb++; - if (dynlights->nb > DL_MAX_LIGHT) - dynlights->nb = DL_MAX_LIGHT; - } -} - -//Hurdler: The goal of this function is to walk through all the bsp starting -// on the top. -// We need to do that to know all the lights in the map and all the walls -static void HWR_ComputeLightMapsInBSPNode(int bspnum, fixed_t *bbox) -{ - if (bspnum & NF_SUBSECTOR) // Found a subsector? - { - if (bspnum == -1) - HWR_CheckSubsector(0, bbox); // probably unecessary: see boris' comment in hw_bsp - else - HWR_CheckSubsector(bspnum&(~NF_SUBSECTOR), bbox); - return; - } - HWR_ComputeLightMapsInBSPNode(nodes[bspnum].children[0], nodes[bspnum].bbox[0]); - HWR_ComputeLightMapsInBSPNode(nodes[bspnum].children[1], nodes[bspnum].bbox[1]); -} - -static void HWR_SearchLightsInMobjs(void) -{ - thinker_t * th; - //mobj_t * mobj; - - // search in the list of thinkers - for (th = thinkercap.next; th != &thinkercap; th = th->next) - { - // a mobj ? - if (th->function.acp1 == (actionf_p1)P_MobjThinker) - HWR_AddMobjLights((mobj_t *)th); - } -} -#endif - -// -// HWR_CreateStaticLightmaps() -// -void HWR_CreateStaticLightmaps(int bspnum) -{ -#ifdef STATICLIGHT - CONS_Debug(DBG_RENDER, "HWR_CreateStaticLightmaps\n"); - - dynlights->nb = 0; - - // First: Searching for lights - // BP: if i was you, I will make it in create mobj since mobj can be create - // at runtime now with fragle scipt - HWR_SearchLightsInMobjs(); - CONS_Debug(DBG_RENDER, "%d lights found\n", dynlights->nb); - - // Second: Build all lightmap for walls covered by lights - validcount++; // to be sure - HWR_ComputeLightMapsInBSPNode(bspnum, NULL); - - dynlights->nb = 0; -#else - (void)bspnum; -#endif -} - -/** - \todo - - - Les coronas ne sont pas g�er avec le nouveau systeme, seul le dynamic lighting l'est - - calculer l'offset des coronas au chargement du level et non faire la moyenne - au moment de l'afficher - BP: euh non en fait il faux encoder la position de la light dans le sprite - car c'est pas focement au mileux de plus il peut en y avoir plusieur (chandelier) - - changer la comparaison pour l'affichage des coronas (+ un epsilon) - BP: non non j'ai trouver mieux :) : lord du AddSprite tu rajoute aussi la coronas - dans la sprite list ! avec un z de epsilon (attention au ZCLIP_PLANE) et donc on - l'affiche en dernier histoir qu'il puisse etre cacher par d'autre sprite :) - Bon fait metre pas mal de code special dans hwr_project sprite mais sa vaux le - coup - - gerer dynamic et static : retenir le nombre de lightstatic et clearer toute les - light > lightstatic (les dynamique) et les lightmap correspondant dans les segs - puit refaire une passe avec le code si dessus mais rien que pour les dynamiques - (tres petite modification) - - finalement virer le hack splitscreen, il n'est plus necessaire ! -*/ -#endif #endif // HWRENDER diff --git a/src/hardware/hw_light.h b/src/hardware/hw_light.h index 2733cc698..fbc1d1f26 100644 --- a/src/hardware/hw_light.h +++ b/src/hardware/hw_light.h @@ -1,17 +1,12 @@ -// Emacs style mode select -*- C++ -*- +// SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// +// Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2019 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 -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// 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 /// \brief Dynamic lighting & coronas add on by Hurdler @@ -22,79 +17,4 @@ #include "hw_glob.h" #include "hw_defs.h" -#define NUMLIGHTFREESLOTS 32 // Free light slots (for SOCs) - -#ifdef ALAM_LIGHTING -#define NEWCORONAS - -#define DL_MAX_LIGHT 256 // maximum number of lights (extra lights are ignored) - -void HWR_InitLight(void); -void HWR_DL_AddLight(gr_vissprite_t *spr, GLPatch_t *patch); -void HWR_PlaneLighting(FOutVector *clVerts, int nrClipVerts); -void HWR_WallLighting(FOutVector *wlVerts); -void HWR_ResetLights(void); -void HWR_SetLights(int viewnumber); - -#ifdef NEWCORONAS -void HWR_DrawCoronas(void); -#else -void HWR_DoCoronasLighting(FOutVector *outVerts, gr_vissprite_t *spr); -#endif - -typedef struct -{ - int nb; - light_t *p_lspr[DL_MAX_LIGHT]; - FVector position[DL_MAX_LIGHT]; // actually maximum DL_MAX_LIGHT lights - mobj_t *mo[DL_MAX_LIGHT]; -} dynlights_t; - -#endif - -typedef enum -{ - NOLIGHT = 0, - RINGSPARK_L, - SUPERSONIC_L, // Cool. =) - SUPERSPARK_L, - INVINCIBLE_L, - GREENSHIELD_L, - BLUESHIELD_L, - YELLOWSHIELD_L, - REDSHIELD_L, - BLACKSHIELD_L, - WHITESHIELD_L, - SMALLREDBALL_L, - RINGLIGHT_L, - GREENSMALL_L, - REDSMALL_L, - GREENSHINE_L, - ORANGESHINE_L, - PINKSHINE_L, - BLUESHINE_L, - REDSHINE_L, - LBLUESHINE_L, - GREYSHINE_L, - REDBALL_L, - GREENBALL_L, - BLUEBALL_L, - NIGHTSLIGHT_L, - JETLIGHT_L, - GOOPLIGHT_L, - STREETLIGHT_L, - - // free slots for SOCs at run-time -------------------- - FREESLOT0_L, - // - // ... 32 free lights here ... - // - LASTFREESLOT_L = (FREESLOT0_L+NUMLIGHTFREESLOTS-1), - // end of freeslots --------------------------------------------- - - NUMLIGHTS -} lightspritenum_t; - -extern light_t lspr[NUMLIGHTS]; -extern light_t *t_lspr[NUMSPRITES]; #endif diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index d64bbdc29..20861b008 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -1,17 +1,12 @@ -// Emacs style mode select -*- C++ -*- +// SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// +// Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2019 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 -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// 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 /// \brief hardware renderer, using the standard HardWareRender driver DLL for SRB2 @@ -21,9 +16,12 @@ #include "../doomstat.h" #ifdef HWRENDER +#include "hw_main.h" #include "hw_glob.h" -#include "hw_light.h" #include "hw_drv.h" +#include "hw_md2.h" +#include "hw_clip.h" +#include "hw_light.h" #include "../i_video.h" // for rendermode == render_glide #include "../v_video.h" @@ -31,6 +29,7 @@ #include "../p_setup.h" #include "../r_local.h" #include "../r_bsp.h" // R_NoEncore +#include "../r_main.h" // cv_fov #include "../d_clisrv.h" #include "../w_wad.h" #include "../z_zone.h" @@ -39,19 +38,14 @@ #include "../st_stuff.h" #include "../i_system.h" #include "../m_cheat.h" + #ifdef ESLOPE #include "../p_slopes.h" #endif -#include "hw_md2.h" -#ifdef NEWCLIP -#include "hw_clip.h" -#endif +#include // qsort -#define R_FAKEFLOORS -#define HWPRECIP -#define SORTING -//#define POLYSKY +#define ABS(x) ((x) < 0 ? -(x) : (x)) // ========================================================================== // the hardware driver object @@ -59,36 +53,11 @@ struct hwdriver_s hwdriver; // ========================================================================== -// PROTOS +// Commands and console variables // ========================================================================== - -static void HWR_AddSprites(sector_t *sec); -static void HWR_ProjectSprite(mobj_t *thing); -#ifdef HWPRECIP -static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing); -#endif - -#ifdef SORTING -void HWR_AddTransparentFloor(lumpnum_t lumpnum, 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(lumpnum_t lumpnum, polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, - INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, extracolormap_t *planecolormap); -#else -static void HWR_Add3DWater(lumpnum_t lumpnum, extrasubsector_t *xsub, fixed_t fixedheight, - INT32 lightlevel, INT32 alpha, sector_t *FOFSector); -static void HWR_Render3DWater(void); -static void HWR_RenderTransparentWalls(void); -#endif -static void HWR_FoggingOn(void); -static UINT32 atohex(const char *s); - static void CV_filtermode_ONChange(void); static void CV_anisotropic_ONChange(void); -static void CV_FogDensity_ONChange(void); -// ========================================================================== -// 3D ENGINE COMMANDS & CONSOLE VARS -// ========================================================================== static CV_PossibleValue_t grfiltermode_cons_t[]= {{HWD_SET_TEXTUREFILTER_POINTSAMPLED, "Nearest"}, {HWD_SET_TEXTUREFILTER_BILINEAR, "Bilinear"}, {HWD_SET_TEXTUREFILTER_TRILINEAR, "Trilinear"}, @@ -98,34 +67,17 @@ static CV_PossibleValue_t grfiltermode_cons_t[]= {{HWD_SET_TEXTUREFILTER_POINTSA {0, NULL}}; CV_PossibleValue_t granisotropicmode_cons_t[] = {{1, "MIN"}, {16, "MAX"}, {0, NULL}}; -boolean drawsky = true; - -// needs fix: walls are incorrectly clipped one column less -#ifndef NEWCLIP -static consvar_t cv_grclipwalls = {"gr_clipwalls", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -#endif -//development variables for diverse uses -static consvar_t cv_gralpha = {"gr_alpha", "160", 0, CV_Unsigned, NULL, 0, NULL, NULL, 0, 0, NULL}; -static consvar_t cv_grbeta = {"gr_beta", "0", 0, CV_Unsigned, NULL, 0, NULL, NULL, 0, 0, NULL}; - -static float HWRWipeCounter = 1.0f; consvar_t cv_grrounddown = {"gr_rounddown", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_grfogdensity = {"gr_fogdensity", "150", CV_CALL|CV_NOINIT, CV_Unsigned, - CV_FogDensity_ONChange, 0, NULL, NULL, 0, 0, NULL}; -// Unfortunately, this can no longer be saved.. -consvar_t cv_grfiltermode = {"gr_filtermode", "Nearest", CV_CALL, grfiltermode_cons_t, + +consvar_t cv_grfiltermode = {"gr_filtermode", "Nearest", CV_CALL|CV_SAVE, grfiltermode_cons_t, CV_filtermode_ONChange, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_granisotropicmode = {"gr_anisotropicmode", "1", CV_CALL, granisotropicmode_cons_t, +consvar_t cv_granisotropicmode = {"gr_anisotropicmode", "1", CV_CALL|CV_SAVE, granisotropicmode_cons_t, CV_anisotropic_ONChange, 0, NULL, NULL, 0, 0, NULL}; -//static consvar_t cv_grzbuffer = {"gr_zbuffer", "On", 0, CV_OnOff}; consvar_t cv_grcorrecttricks = {"gr_correcttricks", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grsolvetjoin = {"gr_solvetjoin", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -static void CV_FogDensity_ONChange(void) -{ - HWD.pfnSetSpecialState(HWD_SET_FOG_DENSITY, cv_grfogdensity.value); -} +consvar_t cv_grbatching = {"gr_batching", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; static void CV_filtermode_ONChange(void) { @@ -137,193 +89,9 @@ static void CV_anisotropic_ONChange(void) HWD.pfnSetSpecialState(HWD_SET_TEXTUREANISOTROPICMODE, cv_granisotropicmode.value); } -/* - * lookuptable for lightvalues - * calculated as follow: - * floatlight = (1.0-exp((light^3)*gamma)) / (1.0-exp(1.0*gamma)); - * gamma=-0,2;-2,0;-4,0;-6,0;-8,0 - * light = 0,0 .. 1,0 - */ -static const float lighttable[5][256] = -{ - { - 0.00000f,0.00000f,0.00000f,0.00000f,0.00000f,0.00001f,0.00001f,0.00002f,0.00003f,0.00004f, - 0.00006f,0.00008f,0.00010f,0.00013f,0.00017f,0.00020f,0.00025f,0.00030f,0.00035f,0.00041f, - 0.00048f,0.00056f,0.00064f,0.00073f,0.00083f,0.00094f,0.00106f,0.00119f,0.00132f,0.00147f, - 0.00163f,0.00180f,0.00198f,0.00217f,0.00237f,0.00259f,0.00281f,0.00305f,0.00331f,0.00358f, - 0.00386f,0.00416f,0.00447f,0.00479f,0.00514f,0.00550f,0.00587f,0.00626f,0.00667f,0.00710f, - 0.00754f,0.00800f,0.00848f,0.00898f,0.00950f,0.01003f,0.01059f,0.01117f,0.01177f,0.01239f, - 0.01303f,0.01369f,0.01437f,0.01508f,0.01581f,0.01656f,0.01734f,0.01814f,0.01896f,0.01981f, - 0.02069f,0.02159f,0.02251f,0.02346f,0.02444f,0.02544f,0.02647f,0.02753f,0.02862f,0.02973f, - 0.03088f,0.03205f,0.03325f,0.03448f,0.03575f,0.03704f,0.03836f,0.03971f,0.04110f,0.04252f, - 0.04396f,0.04545f,0.04696f,0.04851f,0.05009f,0.05171f,0.05336f,0.05504f,0.05676f,0.05852f, - 0.06031f,0.06214f,0.06400f,0.06590f,0.06784f,0.06981f,0.07183f,0.07388f,0.07597f,0.07810f, - 0.08027f,0.08248f,0.08473f,0.08702f,0.08935f,0.09172f,0.09414f,0.09659f,0.09909f,0.10163f, - 0.10421f,0.10684f,0.10951f,0.11223f,0.11499f,0.11779f,0.12064f,0.12354f,0.12648f,0.12946f, - 0.13250f,0.13558f,0.13871f,0.14188f,0.14511f,0.14838f,0.15170f,0.15507f,0.15850f,0.16197f, - 0.16549f,0.16906f,0.17268f,0.17635f,0.18008f,0.18386f,0.18769f,0.19157f,0.19551f,0.19950f, - 0.20354f,0.20764f,0.21179f,0.21600f,0.22026f,0.22458f,0.22896f,0.23339f,0.23788f,0.24242f, - 0.24702f,0.25168f,0.25640f,0.26118f,0.26602f,0.27091f,0.27587f,0.28089f,0.28596f,0.29110f, - 0.29630f,0.30156f,0.30688f,0.31226f,0.31771f,0.32322f,0.32879f,0.33443f,0.34013f,0.34589f, - 0.35172f,0.35761f,0.36357f,0.36960f,0.37569f,0.38185f,0.38808f,0.39437f,0.40073f,0.40716f, - 0.41366f,0.42022f,0.42686f,0.43356f,0.44034f,0.44718f,0.45410f,0.46108f,0.46814f,0.47527f, - 0.48247f,0.48974f,0.49709f,0.50451f,0.51200f,0.51957f,0.52721f,0.53492f,0.54271f,0.55058f, - 0.55852f,0.56654f,0.57463f,0.58280f,0.59105f,0.59937f,0.60777f,0.61625f,0.62481f,0.63345f, - 0.64217f,0.65096f,0.65984f,0.66880f,0.67783f,0.68695f,0.69615f,0.70544f,0.71480f,0.72425f, - 0.73378f,0.74339f,0.75308f,0.76286f,0.77273f,0.78268f,0.79271f,0.80283f,0.81304f,0.82333f, - 0.83371f,0.84417f,0.85472f,0.86536f,0.87609f,0.88691f,0.89781f,0.90880f,0.91989f,0.93106f, - 0.94232f,0.95368f,0.96512f,0.97665f,0.98828f,1.00000f - }, - { - 0.00000f,0.00000f,0.00000f,0.00000f,0.00001f,0.00002f,0.00003f,0.00005f,0.00007f,0.00010f, - 0.00014f,0.00019f,0.00024f,0.00031f,0.00038f,0.00047f,0.00057f,0.00069f,0.00081f,0.00096f, - 0.00112f,0.00129f,0.00148f,0.00170f,0.00193f,0.00218f,0.00245f,0.00274f,0.00306f,0.00340f, - 0.00376f,0.00415f,0.00456f,0.00500f,0.00547f,0.00597f,0.00649f,0.00704f,0.00763f,0.00825f, - 0.00889f,0.00957f,0.01029f,0.01104f,0.01182f,0.01264f,0.01350f,0.01439f,0.01532f,0.01630f, - 0.01731f,0.01836f,0.01945f,0.02058f,0.02176f,0.02298f,0.02424f,0.02555f,0.02690f,0.02830f, - 0.02974f,0.03123f,0.03277f,0.03436f,0.03600f,0.03768f,0.03942f,0.04120f,0.04304f,0.04493f, - 0.04687f,0.04886f,0.05091f,0.05301f,0.05517f,0.05738f,0.05964f,0.06196f,0.06434f,0.06677f, - 0.06926f,0.07181f,0.07441f,0.07707f,0.07979f,0.08257f,0.08541f,0.08831f,0.09126f,0.09428f, - 0.09735f,0.10048f,0.10368f,0.10693f,0.11025f,0.11362f,0.11706f,0.12056f,0.12411f,0.12773f, - 0.13141f,0.13515f,0.13895f,0.14281f,0.14673f,0.15072f,0.15476f,0.15886f,0.16303f,0.16725f, - 0.17153f,0.17587f,0.18028f,0.18474f,0.18926f,0.19383f,0.19847f,0.20316f,0.20791f,0.21272f, - 0.21759f,0.22251f,0.22748f,0.23251f,0.23760f,0.24274f,0.24793f,0.25318f,0.25848f,0.26383f, - 0.26923f,0.27468f,0.28018f,0.28573f,0.29133f,0.29697f,0.30266f,0.30840f,0.31418f,0.32001f, - 0.32588f,0.33179f,0.33774f,0.34374f,0.34977f,0.35585f,0.36196f,0.36810f,0.37428f,0.38050f, - 0.38675f,0.39304f,0.39935f,0.40570f,0.41207f,0.41847f,0.42490f,0.43136f,0.43784f,0.44434f, - 0.45087f,0.45741f,0.46398f,0.47057f,0.47717f,0.48379f,0.49042f,0.49707f,0.50373f,0.51041f, - 0.51709f,0.52378f,0.53048f,0.53718f,0.54389f,0.55061f,0.55732f,0.56404f,0.57075f,0.57747f, - 0.58418f,0.59089f,0.59759f,0.60429f,0.61097f,0.61765f,0.62432f,0.63098f,0.63762f,0.64425f, - 0.65086f,0.65746f,0.66404f,0.67060f,0.67714f,0.68365f,0.69015f,0.69662f,0.70307f,0.70948f, - 0.71588f,0.72224f,0.72857f,0.73488f,0.74115f,0.74739f,0.75359f,0.75976f,0.76589f,0.77199f, - 0.77805f,0.78407f,0.79005f,0.79599f,0.80189f,0.80774f,0.81355f,0.81932f,0.82504f,0.83072f, - 0.83635f,0.84194f,0.84747f,0.85296f,0.85840f,0.86378f,0.86912f,0.87441f,0.87964f,0.88482f, - 0.88995f,0.89503f,0.90005f,0.90502f,0.90993f,0.91479f,0.91959f,0.92434f,0.92903f,0.93366f, - 0.93824f,0.94276f,0.94723f,0.95163f,0.95598f,0.96027f,0.96451f,0.96868f,0.97280f,0.97686f, - 0.98086f,0.98481f,0.98869f,0.99252f,0.99629f,1.00000f - }, - { - 0.00000f,0.00000f,0.00000f,0.00001f,0.00002f,0.00003f,0.00005f,0.00008f,0.00013f,0.00018f, - 0.00025f,0.00033f,0.00042f,0.00054f,0.00067f,0.00083f,0.00101f,0.00121f,0.00143f,0.00168f, - 0.00196f,0.00227f,0.00261f,0.00299f,0.00339f,0.00383f,0.00431f,0.00483f,0.00538f,0.00598f, - 0.00661f,0.00729f,0.00802f,0.00879f,0.00961f,0.01048f,0.01140f,0.01237f,0.01340f,0.01447f, - 0.01561f,0.01680f,0.01804f,0.01935f,0.02072f,0.02215f,0.02364f,0.02520f,0.02682f,0.02850f, - 0.03026f,0.03208f,0.03397f,0.03594f,0.03797f,0.04007f,0.04225f,0.04451f,0.04684f,0.04924f, - 0.05172f,0.05428f,0.05691f,0.05963f,0.06242f,0.06530f,0.06825f,0.07129f,0.07441f,0.07761f, - 0.08089f,0.08426f,0.08771f,0.09125f,0.09487f,0.09857f,0.10236f,0.10623f,0.11019f,0.11423f, - 0.11836f,0.12257f,0.12687f,0.13125f,0.13571f,0.14027f,0.14490f,0.14962f,0.15442f,0.15931f, - 0.16427f,0.16932f,0.17445f,0.17966f,0.18496f,0.19033f,0.19578f,0.20130f,0.20691f,0.21259f, - 0.21834f,0.22417f,0.23007f,0.23605f,0.24209f,0.24820f,0.25438f,0.26063f,0.26694f,0.27332f, - 0.27976f,0.28626f,0.29282f,0.29944f,0.30611f,0.31284f,0.31962f,0.32646f,0.33334f,0.34027f, - 0.34724f,0.35426f,0.36132f,0.36842f,0.37556f,0.38273f,0.38994f,0.39718f,0.40445f,0.41174f, - 0.41907f,0.42641f,0.43378f,0.44116f,0.44856f,0.45598f,0.46340f,0.47084f,0.47828f,0.48573f, - 0.49319f,0.50064f,0.50809f,0.51554f,0.52298f,0.53042f,0.53784f,0.54525f,0.55265f,0.56002f, - 0.56738f,0.57472f,0.58203f,0.58932f,0.59658f,0.60381f,0.61101f,0.61817f,0.62529f,0.63238f, - 0.63943f,0.64643f,0.65339f,0.66031f,0.66717f,0.67399f,0.68075f,0.68746f,0.69412f,0.70072f, - 0.70726f,0.71375f,0.72017f,0.72653f,0.73282f,0.73905f,0.74522f,0.75131f,0.75734f,0.76330f, - 0.76918f,0.77500f,0.78074f,0.78640f,0.79199f,0.79751f,0.80295f,0.80831f,0.81359f,0.81880f, - 0.82393f,0.82898f,0.83394f,0.83883f,0.84364f,0.84836f,0.85301f,0.85758f,0.86206f,0.86646f, - 0.87078f,0.87502f,0.87918f,0.88326f,0.88726f,0.89118f,0.89501f,0.89877f,0.90245f,0.90605f, - 0.90957f,0.91301f,0.91638f,0.91966f,0.92288f,0.92601f,0.92908f,0.93206f,0.93498f,0.93782f, - 0.94059f,0.94329f,0.94592f,0.94848f,0.95097f,0.95339f,0.95575f,0.95804f,0.96027f,0.96244f, - 0.96454f,0.96658f,0.96856f,0.97049f,0.97235f,0.97416f,0.97591f,0.97760f,0.97924f,0.98083f, - 0.98237f,0.98386f,0.98530f,0.98669f,0.98803f,0.98933f,0.99058f,0.99179f,0.99295f,0.99408f, - 0.99516f,0.99620f,0.99721f,0.99817f,0.99910f,1.00000f - }, - { - 0.00000f,0.00000f,0.00000f,0.00001f,0.00002f,0.00005f,0.00008f,0.00012f,0.00019f,0.00026f, - 0.00036f,0.00048f,0.00063f,0.00080f,0.00099f,0.00122f,0.00148f,0.00178f,0.00211f,0.00249f, - 0.00290f,0.00335f,0.00386f,0.00440f,0.00500f,0.00565f,0.00636f,0.00711f,0.00793f,0.00881f, - 0.00975f,0.01075f,0.01182f,0.01295f,0.01416f,0.01543f,0.01678f,0.01821f,0.01971f,0.02129f, - 0.02295f,0.02469f,0.02652f,0.02843f,0.03043f,0.03252f,0.03469f,0.03696f,0.03933f,0.04178f, - 0.04433f,0.04698f,0.04973f,0.05258f,0.05552f,0.05857f,0.06172f,0.06498f,0.06834f,0.07180f, - 0.07537f,0.07905f,0.08283f,0.08672f,0.09072f,0.09483f,0.09905f,0.10337f,0.10781f,0.11236f, - 0.11701f,0.12178f,0.12665f,0.13163f,0.13673f,0.14193f,0.14724f,0.15265f,0.15817f,0.16380f, - 0.16954f,0.17538f,0.18132f,0.18737f,0.19351f,0.19976f,0.20610f,0.21255f,0.21908f,0.22572f, - 0.23244f,0.23926f,0.24616f,0.25316f,0.26023f,0.26739f,0.27464f,0.28196f,0.28935f,0.29683f, - 0.30437f,0.31198f,0.31966f,0.32740f,0.33521f,0.34307f,0.35099f,0.35896f,0.36699f,0.37506f, - 0.38317f,0.39133f,0.39952f,0.40775f,0.41601f,0.42429f,0.43261f,0.44094f,0.44929f,0.45766f, - 0.46604f,0.47443f,0.48283f,0.49122f,0.49962f,0.50801f,0.51639f,0.52476f,0.53312f,0.54146f, - 0.54978f,0.55807f,0.56633f,0.57457f,0.58277f,0.59093f,0.59905f,0.60713f,0.61516f,0.62314f, - 0.63107f,0.63895f,0.64676f,0.65452f,0.66221f,0.66984f,0.67739f,0.68488f,0.69229f,0.69963f, - 0.70689f,0.71407f,0.72117f,0.72818f,0.73511f,0.74195f,0.74870f,0.75536f,0.76192f,0.76839f, - 0.77477f,0.78105f,0.78723f,0.79331f,0.79930f,0.80518f,0.81096f,0.81664f,0.82221f,0.82768f, - 0.83305f,0.83832f,0.84347f,0.84853f,0.85348f,0.85832f,0.86306f,0.86770f,0.87223f,0.87666f, - 0.88098f,0.88521f,0.88933f,0.89334f,0.89726f,0.90108f,0.90480f,0.90842f,0.91194f,0.91537f, - 0.91870f,0.92193f,0.92508f,0.92813f,0.93109f,0.93396f,0.93675f,0.93945f,0.94206f,0.94459f, - 0.94704f,0.94941f,0.95169f,0.95391f,0.95604f,0.95810f,0.96009f,0.96201f,0.96386f,0.96564f, - 0.96735f,0.96900f,0.97059f,0.97212f,0.97358f,0.97499f,0.97634f,0.97764f,0.97888f,0.98007f, - 0.98122f,0.98231f,0.98336f,0.98436f,0.98531f,0.98623f,0.98710f,0.98793f,0.98873f,0.98949f, - 0.99021f,0.99090f,0.99155f,0.99218f,0.99277f,0.99333f,0.99387f,0.99437f,0.99486f,0.99531f, - 0.99575f,0.99616f,0.99654f,0.99691f,0.99726f,0.99759f,0.99790f,0.99819f,0.99847f,0.99873f, - 0.99897f,0.99920f,0.99942f,0.99963f,0.99982f,1.00000f - }, - { - 0.00000f,0.00000f,0.00000f,0.00001f,0.00003f,0.00006f,0.00010f,0.00017f,0.00025f,0.00035f, - 0.00048f,0.00064f,0.00083f,0.00106f,0.00132f,0.00163f,0.00197f,0.00237f,0.00281f,0.00330f, - 0.00385f,0.00446f,0.00513f,0.00585f,0.00665f,0.00751f,0.00845f,0.00945f,0.01054f,0.01170f, - 0.01295f,0.01428f,0.01569f,0.01719f,0.01879f,0.02048f,0.02227f,0.02415f,0.02614f,0.02822f, - 0.03042f,0.03272f,0.03513f,0.03765f,0.04028f,0.04303f,0.04589f,0.04887f,0.05198f,0.05520f, - 0.05855f,0.06202f,0.06561f,0.06933f,0.07318f,0.07716f,0.08127f,0.08550f,0.08987f,0.09437f, - 0.09900f,0.10376f,0.10866f,0.11369f,0.11884f,0.12414f,0.12956f,0.13512f,0.14080f,0.14662f, - 0.15257f,0.15865f,0.16485f,0.17118f,0.17764f,0.18423f,0.19093f,0.19776f,0.20471f,0.21177f, - 0.21895f,0.22625f,0.23365f,0.24117f,0.24879f,0.25652f,0.26435f,0.27228f,0.28030f,0.28842f, - 0.29662f,0.30492f,0.31329f,0.32175f,0.33028f,0.33889f,0.34756f,0.35630f,0.36510f,0.37396f, - 0.38287f,0.39183f,0.40084f,0.40989f,0.41897f,0.42809f,0.43723f,0.44640f,0.45559f,0.46479f, - 0.47401f,0.48323f,0.49245f,0.50167f,0.51088f,0.52008f,0.52927f,0.53843f,0.54757f,0.55668f, - 0.56575f,0.57479f,0.58379f,0.59274f,0.60164f,0.61048f,0.61927f,0.62799f,0.63665f,0.64524f, - 0.65376f,0.66220f,0.67056f,0.67883f,0.68702f,0.69511f,0.70312f,0.71103f,0.71884f,0.72655f, - 0.73415f,0.74165f,0.74904f,0.75632f,0.76348f,0.77053f,0.77747f,0.78428f,0.79098f,0.79756f, - 0.80401f,0.81035f,0.81655f,0.82264f,0.82859f,0.83443f,0.84013f,0.84571f,0.85117f,0.85649f, - 0.86169f,0.86677f,0.87172f,0.87654f,0.88124f,0.88581f,0.89026f,0.89459f,0.89880f,0.90289f, - 0.90686f,0.91071f,0.91445f,0.91807f,0.92157f,0.92497f,0.92826f,0.93143f,0.93450f,0.93747f, - 0.94034f,0.94310f,0.94577f,0.94833f,0.95081f,0.95319f,0.95548f,0.95768f,0.95980f,0.96183f, - 0.96378f,0.96565f,0.96744f,0.96916f,0.97081f,0.97238f,0.97388f,0.97532f,0.97669f,0.97801f, - 0.97926f,0.98045f,0.98158f,0.98266f,0.98369f,0.98467f,0.98560f,0.98648f,0.98732f,0.98811f, - 0.98886f,0.98958f,0.99025f,0.99089f,0.99149f,0.99206f,0.99260f,0.99311f,0.99359f,0.99404f, - 0.99446f,0.99486f,0.99523f,0.99559f,0.99592f,0.99623f,0.99652f,0.99679f,0.99705f,0.99729f, - 0.99751f,0.99772f,0.99792f,0.99810f,0.99827f,0.99843f,0.99857f,0.99871f,0.99884f,0.99896f, - 0.99907f,0.99917f,0.99926f,0.99935f,0.99943f,0.99951f,0.99958f,0.99964f,0.99970f,0.99975f, - 0.99980f,0.99985f,0.99989f,0.99993f,0.99997f,1.00000f - } -}; - -#define gld_CalcLightLevel(lightlevel) (lighttable[1][max(min((lightlevel),255),0)]) - // ========================================================================== -// VIEW GLOBALS +// Globals // ========================================================================== -// Fineangles in the SCREENWIDTH wide window. -#define FIELDOFVIEW ANGLE_90 -#define ABS(x) ((x) < 0 ? -(x) : (x)) - -static angle_t gr_clipangle; - -// The viewangletox[viewangle + FINEANGLES/4] lookup -// maps the visible view angles to screen X coordinates, -// flattening the arc to a flat projection plane. -// There will be many angles mapped to the same X. -static INT32 gr_viewangletox[FINEANGLES/2]; - -// The xtoviewangleangle[] table maps a screen pixel -// to the lowest viewangle that maps back to x ranges -// from clipangle to -clipangle. -static angle_t gr_xtoviewangle[MAXVIDWIDTH+1]; - -// ========================================================================== -// GLOBALS -// ========================================================================== - -// uncomment to remove the plane rendering -#define DOPLANES -//#define DOWALLS - -// test of drawing sky by polygons like in software with visplane, unfortunately -// this doesn't work since we must have z for pixel and z for texture (not like now with z = oow) -//#define POLYSKY - -// test change fov when looking up/down but bsp projection messup :( -//#define NOCRAPPYMLOOK // base values set at SetViewSize static float gr_basecentery; @@ -343,187 +111,163 @@ static float gr_windowcentery; static float gr_pspritexscale, gr_pspriteyscale; + static seg_t *gr_curline; static side_t *gr_sidedef; static line_t *gr_linedef; static sector_t *gr_frontsector; static sector_t *gr_backsector; -// -------------------------------------------------------------------------- -// STUFF FOR THE PROJECTION CODE -// -------------------------------------------------------------------------- +boolean gr_shadersavailable = true; + +// ========================================================================== +// View position +// ========================================================================== FTransform atransform; -// duplicates of the main code, set after R_SetupFrame() passed them into sharedstruct, -// copied here for local use -static fixed_t dup_viewx, dup_viewy, dup_viewz; -static angle_t dup_viewangle; +// Float variants of viewx, viewy, viewz, etc. static float gr_viewx, gr_viewy, gr_viewz; static float gr_viewsin, gr_viewcos; -// Maybe not necessary with the new T&L code (needs to be checked!) -static float gr_viewludsin, gr_viewludcos; // look up down kik test -static float gr_fovlud; +static angle_t gr_aimingangle; +static float gr_viewludsin, gr_viewludcos; + +static INT32 drawcount = 0; // ========================================================================== -// LIGHT stuffs +// Lighting // ========================================================================== -static UINT8 lightleveltonumlut[256]; - -// added to SRB2's sector lightlevel to make things a bit brighter (sprites/walls/planes) -FUNCMATH UINT8 LightLevelToLum(INT32 l) +void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *colormap) { - return (UINT8)(255*gld_CalcLightLevel(l)); + RGBA_t poly_color, tint_color, fade_color; + + poly_color.rgba = 0xFFFFFFFF; + tint_color.rgba = (colormap != NULL) ? (UINT32)colormap->rgba : GL_DEFAULTMIX; + fade_color.rgba = (colormap != NULL) ? (UINT32)colormap->fadergba : GL_DEFAULTFOG; + + // Crappy backup coloring if you can't do shaders + if (!(cv_grshaders.value && gr_shadersavailable)) + { + // be careful, this may get negative for high lightlevel values. + float tint_alpha, fade_alpha; + float red, green, blue; + + red = (float)poly_color.s.red; + green = (float)poly_color.s.green; + blue = (float)poly_color.s.blue; + + // 48 is just an arbritrary value that looked relatively okay. + tint_alpha = (float)(sqrt(tint_color.s.alpha) * 48) / 255.0f; + + // 8 is roughly the brightness of the "close" color in Software, and 16 the brightness of the "far" color. + // 8 is too bright for dark levels, and 16 is too dark for bright levels. + // 12 is the compromise value. It doesn't look especially good anywhere, but it's the most balanced. + // (Also, as far as I can tell, fade_color's alpha is actually not used in Software, so we only use light level.) + fade_alpha = (float)(sqrt(255-light_level) * 12) / 255.0f; + + // Clamp the alpha values + tint_alpha = min(max(tint_alpha, 0.0f), 1.0f); + fade_alpha = min(max(fade_alpha, 0.0f), 1.0f); + + red = (tint_color.s.red * tint_alpha) + (red * (1.0f - tint_alpha)); + green = (tint_color.s.green * tint_alpha) + (green * (1.0f - tint_alpha)); + blue = (tint_color.s.blue * tint_alpha) + (blue * (1.0f - tint_alpha)); + + red = (fade_color.s.red * fade_alpha) + (red * (1.0f - fade_alpha)); + green = (fade_color.s.green * fade_alpha) + (green * (1.0f - fade_alpha)); + blue = (fade_color.s.blue * fade_alpha) + (blue * (1.0f - fade_alpha)); + + poly_color.s.red = (UINT8)red; + poly_color.s.green = (UINT8)green; + poly_color.s.blue = (UINT8)blue; + } + + Surface->PolyColor.rgba = poly_color.rgba; + Surface->TintColor.rgba = tint_color.rgba; + Surface->FadeColor.rgba = fade_color.rgba; + Surface->LightInfo.light_level = light_level; + Surface->LightInfo.fade_start = (colormap != NULL) ? colormap->fadestart : 0; + Surface->LightInfo.fade_end = (colormap != NULL) ? colormap->fadeend : 31; } -static inline void InitLumLut(void) -{ - INT32 i, k = 0; - for (i = 0; i < 256; i++) - { - if (i > 128) - k += 2; - else - k = 1; - lightleveltonumlut[i] = (UINT8)(k); - } -} - -//#define FOGFACTOR 300 //was 600 >> Covered by cv_grfogdensity -#define NORMALFOG 0x00000000 -#define FADEFOG 0x19000000 -#define CALCFOGDENSITY(x) ((float)((5220.0f*(1.0f/((x)/41.0f+1.0f)))-(5220.0f*(1.0f/(255.0f/41.0f+1.0f))))) // Approximate fog calculation based off of software walls -#define CALCFOGDENSITYFLOOR(x) ((float)((40227.0f*(1.0f/((x)/11.0f+1.0f)))-(40227.0f*(1.0f/(255.0f/11.0f+1.0f))))) // Approximate fog calculation based off of software floors -#define CALCLIGHT(x,y) ((float)(x)*((y)/255.0f)) -UINT32 HWR_Lighting(INT32 light, UINT32 color, UINT32 fadecolor, boolean fogblockpoly, boolean plane) -{ - RGBA_t realcolor, fogcolor, surfcolor; - INT32 alpha, fogalpha; - - (void)fogblockpoly; - - // Don't go out of bounds - if (light < 0) - light = 0; - else if (light > 255) - light = 255; - - realcolor.rgba = color; - fogcolor.rgba = fadecolor; - - alpha = (realcolor.s.alpha*255)/25; - fogalpha = (fogcolor.s.alpha*255)/25; - - if (cv_grfog.value && cv_grsoftwarefog.value) // Only do this when fog is on, software fog mode is on, and the poly is not from a fog block - { - // Modulate the colors by alpha. - realcolor.s.red = (UINT8)(CALCLIGHT(alpha,realcolor.s.red)); - realcolor.s.green = (UINT8)(CALCLIGHT(alpha,realcolor.s.green)); - realcolor.s.blue = (UINT8)(CALCLIGHT(alpha,realcolor.s.blue)); - - // Set the surface colors and further modulate the colors by light. - surfcolor.s.red = (UINT8)(CALCLIGHT((0xFF-alpha),255)+CALCLIGHT(realcolor.s.red,255)); - surfcolor.s.green = (UINT8)(CALCLIGHT((0xFF-alpha),255)+CALCLIGHT(realcolor.s.green,255)); - surfcolor.s.blue = (UINT8)(CALCLIGHT((0xFF-alpha),255)+CALCLIGHT(realcolor.s.blue,255)); - surfcolor.s.alpha = 0xFF; - - // Modulate the colors by alpha. - fogcolor.s.red = (UINT8)(CALCLIGHT(fogalpha,fogcolor.s.red)); - fogcolor.s.green = (UINT8)(CALCLIGHT(fogalpha,fogcolor.s.green)); - fogcolor.s.blue = (UINT8)(CALCLIGHT(fogalpha,fogcolor.s.blue)); - } - else - { - // Modulate the colors by alpha. - realcolor.s.red = (UINT8)(CALCLIGHT(alpha,realcolor.s.red)); - realcolor.s.green = (UINT8)(CALCLIGHT(alpha,realcolor.s.green)); - realcolor.s.blue = (UINT8)(CALCLIGHT(alpha,realcolor.s.blue)); - - // Set the surface colors and further modulate the colors by light. - surfcolor.s.red = (UINT8)(CALCLIGHT((0xFF-alpha),light)+CALCLIGHT(realcolor.s.red,light)); - surfcolor.s.green = (UINT8)(CALCLIGHT((0xFF-alpha),light)+CALCLIGHT(realcolor.s.green,light)); - surfcolor.s.blue = (UINT8)(CALCLIGHT((0xFF-alpha),light)+CALCLIGHT(realcolor.s.blue,light)); - - // Modulate the colors by alpha. - fogcolor.s.red = (UINT8)(CALCLIGHT(fogalpha,fogcolor.s.red)); - fogcolor.s.green = (UINT8)(CALCLIGHT(fogalpha,fogcolor.s.green)); - fogcolor.s.blue = (UINT8)(CALCLIGHT(fogalpha,fogcolor.s.blue)); - - // Set the surface colors and further modulate the colors by light. - surfcolor.s.red = surfcolor.s.red+((UINT8)(CALCLIGHT((0xFF-fogalpha),(255-light))+CALCLIGHT(fogcolor.s.red,(255-light)))); - surfcolor.s.green = surfcolor.s.green+((UINT8)(CALCLIGHT((0xFF-fogalpha),(255-light))+CALCLIGHT(fogcolor.s.green,(255-light)))); - surfcolor.s.blue = surfcolor.s.blue+((UINT8)(CALCLIGHT((0xFF-fogalpha),(255-light))+CALCLIGHT(fogcolor.s.blue,(255-light)))); - surfcolor.s.alpha = 0xFF; - } - - if(cv_grfog.value) - { - if (cv_grsoftwarefog.value) - { - fogcolor.s.red = (UINT8)((CALCLIGHT(fogcolor.s.red,(255-light)))+(CALCLIGHT(realcolor.s.red,light))); - fogcolor.s.green = (UINT8)((CALCLIGHT(fogcolor.s.green,(255-light)))+(CALCLIGHT(realcolor.s.green,light))); - fogcolor.s.blue = (UINT8)((CALCLIGHT(fogcolor.s.blue,(255-light)))+(CALCLIGHT(realcolor.s.blue,light))); - - // Set the fog options. - if (cv_grsoftwarefog.value == 1 && plane) // With floors, software draws them way darker for their distance - HWD.pfnSetSpecialState(HWD_SET_FOG_DENSITY, (INT32)(CALCFOGDENSITYFLOOR(light))); - else // everything else is drawn like walls - HWD.pfnSetSpecialState(HWD_SET_FOG_DENSITY, (INT32)(CALCFOGDENSITY(light))); - } - else - { - fogcolor.s.red = (UINT8)((CALCLIGHT(fogcolor.s.red,(255-light)))+(CALCLIGHT(realcolor.s.red,light))); - fogcolor.s.green = (UINT8)((CALCLIGHT(fogcolor.s.green,(255-light)))+(CALCLIGHT(realcolor.s.green,light))); - fogcolor.s.blue = (UINT8)((CALCLIGHT(fogcolor.s.blue,(255-light)))+(CALCLIGHT(realcolor.s.blue,light))); - - fogalpha = (UINT8)((CALCLIGHT(fogalpha,(255-light)))+(CALCLIGHT(alpha,light))); - - // Set the fog options. - light = (UINT8)(CALCLIGHT(light,(255-fogalpha))); - HWD.pfnSetSpecialState(HWD_SET_FOG_DENSITY, (INT32)(cv_grfogdensity.value-(cv_grfogdensity.value*(float)light/255.0f))); - } - - HWD.pfnSetSpecialState(HWD_SET_FOG_COLOR, (fogcolor.s.red*0x10000)+(fogcolor.s.green*0x100)+fogcolor.s.blue); - HWD.pfnSetSpecialState(HWD_SET_FOG_MODE, 1); - } - return surfcolor.rgba; -} - - -static UINT8 HWR_FogBlockAlpha(INT32 light, UINT32 color) // Let's see if this can work +UINT8 HWR_FogBlockAlpha(INT32 light, extracolormap_t *colormap) // Let's see if this can work { RGBA_t realcolor, surfcolor; INT32 alpha; - // Don't go out of bounds - if (light < 0) - light = 0; - else if (light > 255) - light = 255; + realcolor.rgba = (colormap != NULL) ? colormap->rgba : GL_DEFAULTMIX; - realcolor.rgba = color; + if (!(cv_grshaders.value && gr_shadersavailable)) + { + light = light - (255 - light); - alpha = (realcolor.s.alpha*255)/25; + // Don't go out of bounds + if (light < 0) + light = 0; + else if (light > 255) + light = 255; - // at 255 brightness, alpha is between 0 and 127, at 0 brightness alpha will always be 255 - surfcolor.s.alpha = (alpha*light)/(2*256)+255-light; + alpha = (realcolor.s.alpha*255)/25; + + // at 255 brightness, alpha is between 0 and 127, at 0 brightness alpha will always be 255 + surfcolor.s.alpha = (alpha*light) / (2*256) + 255-light; + } + else + { + surfcolor.s.alpha = (255 - light); + } return surfcolor.s.alpha; } +static FUINT HWR_CalcWallLight(FUINT lightnum, fixed_t v1x, fixed_t v1y, fixed_t v2x, fixed_t v2y) +{ + INT16 finallight = lightnum; + + if (cv_grfakecontrast.value != 0) + { + const UINT8 contrast = 8; + fixed_t extralight = 0; + + if (cv_grfakecontrast.value == 2) // Smooth setting + { + extralight = (-(contrast<> FRACBITS; + } + else + { + if (v1y == v2y) + extralight = -contrast; + else if (v1x == v2x) + extralight = contrast; + } + + if (extralight != 0) + { + finallight += extralight; + + if (finallight < 0) + finallight = 0; + if (finallight > 255) + finallight = 255; + } + } + + return (FUINT)finallight; +} + // ========================================================================== -// FLOOR/CEILING GENERATION FROM SUBSECTORS +// Floor and ceiling generation from subsectors // ========================================================================== -#ifdef DOPLANES - -// -----------------+ -// HWR_RenderPlane : Render a floor or ceiling convex polygon -// -----------------+ -static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, - FBITFIELD PolyFlags, INT32 lightlevel, lumpnum_t lumpnum, sector_t *FOFsector, UINT8 alpha, boolean fogplane, extracolormap_t *planecolormap) +// HWR_RenderPlane +// Render a floor or ceiling convex polygon +void HWR_RenderPlane(extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, FBITFIELD PolyFlags, INT32 lightlevel, lumpnum_t lumpnum, sector_t *FOFsector, UINT8 alpha, extracolormap_t *planecolormap) { polyvertex_t * pv; float height; //constant y for all points on the convex flat polygon @@ -545,8 +289,6 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is static FOutVector *planeVerts = NULL; static UINT16 numAllocedPlaneVerts = 0; - (void)sector; ///@TODO remove shitty unused variable - // no convex poly were generated for this subsector if (!xsub->planepoly) return; @@ -581,12 +323,6 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is if (nrPlaneVerts < 3) //not even a triangle ? return; - if (nrPlaneVerts > INT16_MAX) // FIXME: exceeds plVerts size - { - CONS_Debug(DBG_RENDER, "polygon size of %d exceeds max value of %d vertices\n", nrPlaneVerts, UINT16_MAX); - return; - } - // Allocate plane-vertex buffer if we need to if (!planeVerts || nrPlaneVerts > numAllocedPlaneVerts) { @@ -667,10 +403,11 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is } } + if (angle) // Only needs to be done if there's an altered angle { - angle = InvAngle(angle)>>ANGLETOFINESHIFT; + angle = (InvAngle(angle)+ANGLE_180)>>ANGLETOFINESHIFT; // This needs to be done so that it scrolls in a different direction after rotation like software /*tempxsow = FLOAT_TO_FIXED(scrollx); @@ -686,26 +423,27 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is flatyref = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINESINE(angle)) + FixedMul(tempytow, FINECOSINE(angle)))); } + for (i = 0; i < nrPlaneVerts; i++,v3d++,pv++) { // Hurdler: add scrolling texture on floor/ceiling - v3d->sow = (float)((pv->x / fflatsize) - flatxref + scrollx); - v3d->tow = (float)(-(pv->y / fflatsize) + flatyref + scrolly); + v3d->s = (float)((pv->x / fflatsize) - flatxref + scrollx); + v3d->t = (float)(flatyref - (pv->y / fflatsize) + scrolly); - //v3d->sow = (float)(pv->x / fflatsize); - //v3d->tow = (float)(pv->y / fflatsize); + //v3d->s = (float)(pv->x / fflatsize); + //v3d->t = (float)(pv->y / fflatsize); // Need to rotate before translate if (angle) // Only needs to be done if there's an altered angle { - tempxsow = FLOAT_TO_FIXED(v3d->sow); - tempytow = FLOAT_TO_FIXED(v3d->tow); - v3d->sow = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINECOSINE(angle)) - FixedMul(tempytow, FINESINE(angle)))); - v3d->tow = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINESINE(angle)) + FixedMul(tempytow, FINECOSINE(angle)))); + tempxsow = FLOAT_TO_FIXED(v3d->s); + tempytow = FLOAT_TO_FIXED(v3d->t); + v3d->s = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINECOSINE(angle)) - FixedMul(tempytow, FINESINE(angle)))); + v3d->t = (FIXED_TO_FLOAT(-FixedMul(tempxsow, FINESINE(angle)) - FixedMul(tempytow, FINECOSINE(angle)))); } - //v3d->sow = (float)(v3d->sow - flatxref + scrollx); - //v3d->tow = (float)(flatyref - v3d->tow + scrolly); + //v3d->s = (float)(v3d->s - flatxref + scrollx); + //v3d->t = (float)(flatyref - v3d->t + scrolly); v3d->x = pv->x; v3d->y = height; @@ -720,142 +458,33 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is #endif } - // only useful for flat coloured triangles - //Surf.FlatColor = 0xff804020; - - // use different light tables - // for horizontal / vertical / diagonal - // note: try to get the same visual feel as the original - Surf.FlatColor.s.red = Surf.FlatColor.s.green = - Surf.FlatColor.s.blue = LightLevelToLum(lightlevel); // Don't take from the frontsector, or the game will crash - -#if 0 // no colormap test - // colormap test - if (gr_frontsector) - { - sector_t *psector = gr_frontsector; - -#ifdef ESLOPE - if (slope) - fixedheight = P_GetZAt(slope, psector->soundorg.x, psector->soundorg.y); -#endif - - if (psector->ffloors) - { - ffloor_t *caster = psector->lightlist[R_GetPlaneLight(psector, fixedheight, false)].caster; - psector = caster ? §ors[caster->secnum] : psector; - - if (caster) - { - lightlevel = psector->lightlevel; - Surf.FlatColor.s.red = Surf.FlatColor.s.green = Surf.FlatColor.s.blue = LightLevelToLum(lightlevel); - } - } - if (psector->extra_colormap) - Surf.FlatColor.rgba = HWR_Lighting(lightlevel,psector->extra_colormap->rgba,psector->extra_colormap->fadergba, false, true); - else - Surf.FlatColor.rgba = HWR_Lighting(lightlevel,NORMALFOG,FADEFOG, false, true); - } - else - Surf.FlatColor.rgba = HWR_Lighting(lightlevel,NORMALFOG,FADEFOG, false, true); - -#endif // NOPE - - if (planecolormap) - { - if (fogplane) - Surf.FlatColor.rgba = HWR_Lighting(lightlevel, planecolormap->rgba, planecolormap->fadergba, true, false); - else - Surf.FlatColor.rgba = HWR_Lighting(lightlevel, planecolormap->rgba, planecolormap->fadergba, false, true); - } - else - { - if (fogplane) - Surf.FlatColor.rgba = HWR_Lighting(lightlevel, NORMALFOG, FADEFOG, true, false); - else - Surf.FlatColor.rgba = HWR_Lighting(lightlevel, NORMALFOG, FADEFOG, false, true); - } + HWR_Lighting(&Surf, lightlevel, planecolormap); if (PolyFlags & (PF_Translucent|PF_Fog)) { - Surf.FlatColor.s.alpha = (UINT8)alpha; - PolyFlags |= PF_Modulated|PF_Clip; + Surf.PolyColor.s.alpha = (UINT8)alpha; + PolyFlags |= PF_Modulated; } else - PolyFlags |= PF_Masked|PF_Modulated|PF_Clip; + PolyFlags |= PF_Masked|PF_Modulated; + + if (PolyFlags & PF_Fog) + HWD.pfnSetShader(6); // fog shader + else if (PolyFlags & PF_Ripple) + HWD.pfnSetShader(5); // water shader + else + HWD.pfnSetShader(1); // floor shader HWD.pfnDrawPolygon(&Surf, planeVerts, nrPlaneVerts, PolyFlags); - -#ifdef ALAM_LIGHTING - // add here code for dynamic lighting on planes - HWR_PlaneLighting(planeVerts, nrPlaneVerts); -#endif } -#ifdef POLYSKY -// this don't draw anything it only update the z-buffer so there isn't problem with -// wall/things upper that sky (map12) -static void HWR_RenderSkyPlane(extrasubsector_t *xsub, fixed_t fixedheight) -{ - polyvertex_t *pv; - float height; //constant y for all points on the convex flat polygon - FOutVector *v3d; - INT32 nrPlaneVerts; //verts original define of convex flat polygon - INT32 i; - - // no convex poly were generated for this subsector - if (!xsub->planepoly) - return; - - height = FIXED_TO_FLOAT(fixedheight); - - pv = xsub->planepoly->pts; - nrPlaneVerts = xsub->planepoly->numpts; - - if (nrPlaneVerts < 3) // not even a triangle? - return; - - if (nrPlaneVerts > MAXPLANEVERTICES) // FIXME: exceeds plVerts size - { - CONS_Debug(DBG_RENDER, "polygon size of %d exceeds max value of %d vertices\n", nrPlaneVerts, MAXPLANEVERTICES); - return; - } - - // transform - v3d = planeVerts; - for (i = 0; i < nrPlaneVerts; i++,v3d++,pv++) - { - v3d->sow = 0.0f; - v3d->tow = 0.0f; - v3d->x = pv->x; - v3d->y = height; - v3d->z = pv->y; - } - - HWD.pfnDrawPolygon(NULL, planeVerts, nrPlaneVerts, - PF_Clip|PF_Invisible|PF_NoTexture|PF_Occlude); -} -#endif //polysky - -#endif //doplanes - -/* - wallVerts order is : - 3--2 - | /| - |/ | - 0--1 -*/ #ifdef WALLSPLATS static void HWR_DrawSegsSplats(FSurfaceInfo * pSurf) { - FOutVector trVerts[4], *wv; - wallVert3D wallVerts[4]; - wallVert3D *pwallVerts; + FOutVector wallVerts[4]; wallsplat_t *splat; GLPatch_t *gpatch; fixed_t i; - FSurfaceInfo pSurf2; // seg bbox fixed_t segbbox[4]; @@ -893,186 +522,69 @@ static void HWR_DrawSegsSplats(FSurfaceInfo * pSurf) wallVerts[3].s = wallVerts[3].t = wallVerts[2].s = wallVerts[0].t = 0.0f; wallVerts[1].s = wallVerts[1].t = wallVerts[2].t = wallVerts[0].s = 1.0f; - // transform - wv = trVerts; - pwallVerts = wallVerts; - for (i = 0; i < 4; i++,wv++,pwallVerts++) - { - wv->x = pwallVerts->x; - wv->z = pwallVerts->z; - wv->y = pwallVerts->y; - - // Kalaron: TOW and SOW needed to be switched - wv->sow = pwallVerts->t; - wv->tow = pwallVerts->s; - } - M_Memcpy(&pSurf2,pSurf,sizeof (FSurfaceInfo)); switch (splat->flags & SPLATDRAWMODE_MASK) { case SPLATDRAWMODE_OPAQUE : - pSurf2.FlatColor.s.alpha = 0xff; + pSurf.PolyColor.s.alpha = 0xff; i = PF_Translucent; break; case SPLATDRAWMODE_TRANS : - pSurf2.FlatColor.s.alpha = 128; + pSurf.PolyColor.s.alpha = 128; i = PF_Translucent; break; case SPLATDRAWMODE_SHADE : - pSurf2.FlatColor.s.alpha = 0xff; + pSurf.PolyColor.s.alpha = 0xff; i = PF_Substractive; break; } - HWD.pfnDrawPolygon(&pSurf2, trVerts, 4, i|PF_Modulated|PF_Clip|PF_Decal); + HWD.pfnSetShader(2); // wall shader + HWD.pfnDrawPolygon(&pSurf, wallVerts, 4, i|PF_Modulated|PF_Decal); } } #endif -// ========================================================================== -// WALL GENERATION FROM SUBSECTOR SEGS -// ========================================================================== - - FBITFIELD HWR_TranstableToAlpha(INT32 transtablenum, FSurfaceInfo *pSurf) { switch (transtablenum) { - case tr_trans10 : pSurf->FlatColor.s.alpha = 0xe6;return PF_Translucent; - case tr_trans20 : pSurf->FlatColor.s.alpha = 0xcc;return PF_Translucent; - case tr_trans30 : pSurf->FlatColor.s.alpha = 0xb3;return PF_Translucent; - case tr_trans40 : pSurf->FlatColor.s.alpha = 0x99;return PF_Translucent; - case tr_trans50 : pSurf->FlatColor.s.alpha = 0x80;return PF_Translucent; - case tr_trans60 : pSurf->FlatColor.s.alpha = 0x66;return PF_Translucent; - case tr_trans70 : pSurf->FlatColor.s.alpha = 0x4c;return PF_Translucent; - case tr_trans80 : pSurf->FlatColor.s.alpha = 0x33;return PF_Translucent; - case tr_trans90 : pSurf->FlatColor.s.alpha = 0x19;return PF_Translucent; + case tr_trans10 : pSurf->PolyColor.s.alpha = 0xe6;return PF_Translucent; + case tr_trans20 : pSurf->PolyColor.s.alpha = 0xcc;return PF_Translucent; + case tr_trans30 : pSurf->PolyColor.s.alpha = 0xb3;return PF_Translucent; + case tr_trans40 : pSurf->PolyColor.s.alpha = 0x99;return PF_Translucent; + case tr_trans50 : pSurf->PolyColor.s.alpha = 0x80;return PF_Translucent; + case tr_trans60 : pSurf->PolyColor.s.alpha = 0x66;return PF_Translucent; + case tr_trans70 : pSurf->PolyColor.s.alpha = 0x4c;return PF_Translucent; + case tr_trans80 : pSurf->PolyColor.s.alpha = 0x33;return PF_Translucent; + case tr_trans90 : pSurf->PolyColor.s.alpha = 0x19;return PF_Translucent; } return PF_Translucent; } -// v1,v2 : the start & end vertices along the original wall segment, that may have been -// clipped so that only a visible portion of the wall seg is drawn. -// floorheight, ceilingheight : depend on wall upper/lower/middle, comes from the sectors. +// ========================================================================== +// Wall generation from subsector segs +// ========================================================================== -static void HWR_AddTransparentWall(wallVert3D *wallVerts, FSurfaceInfo * pSurf, INT32 texnum, FBITFIELD blend, boolean fogwall, INT32 lightlevel, extracolormap_t *wallcolormap); - -// -----------------+ -// HWR_ProjectWall : -// -----------------+ -/* - wallVerts order is : - 3--2 - | /| - |/ | - 0--1 -*/ -static void HWR_ProjectWall(wallVert3D * wallVerts, - FSurfaceInfo * pSurf, - FBITFIELD blendmode, INT32 lightlevel, extracolormap_t *wallcolormap) +// +// HWR_ProjectWall +// +void HWR_ProjectWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blendmode, INT32 lightlevel, extracolormap_t *wallcolormap) { - FOutVector trVerts[4]; - FOutVector *wv; + HWR_Lighting(pSurf, lightlevel, wallcolormap); - // transform - wv = trVerts; - // it sounds really stupid to do this conversion with the new T&L code - // we should directly put the right information in the right structure - // wallVerts3D seems ok, doesn't need FOutVector - // also remove the light copy - - // More messy to unwrap, but it's also quicker, uses less memory. - wv->sow = wallVerts->s; - wv->tow = wallVerts->t; - wv->x = wallVerts->x; - wv->y = wallVerts->y; - wv->z = wallVerts->z; - wv++; wallVerts++; - wv->sow = wallVerts->s; - wv->tow = wallVerts->t; - wv->x = wallVerts->x; - wv->y = wallVerts->y; - wv->z = wallVerts->z; - wv++; wallVerts++; - wv->sow = wallVerts->s; - wv->tow = wallVerts->t; - wv->x = wallVerts->x; - wv->y = wallVerts->y; - wv->z = wallVerts->z; - wv++; wallVerts++; - wv->sow = wallVerts->s; - wv->tow = wallVerts->t; - wv->x = wallVerts->x; - wv->y = wallVerts->y; - wv->z = wallVerts->z; - - if (wallcolormap) - { - pSurf->FlatColor.rgba = HWR_Lighting(lightlevel, wallcolormap->rgba, wallcolormap->fadergba, false, false); - } - else - { - pSurf->FlatColor.rgba = HWR_Lighting(lightlevel, NORMALFOG, FADEFOG, false, false); - } - - HWD.pfnDrawPolygon(pSurf, trVerts, 4, blendmode|PF_Modulated|PF_Occlude|PF_Clip); + HWD.pfnSetShader(2); // wall shader + HWD.pfnDrawPolygon(pSurf, wallVerts, 4, blendmode|PF_Modulated|PF_Occlude); #ifdef WALLSPLATS if (gr_curline->linedef->splats && cv_splats.value) HWR_DrawSegsSplats(pSurf); #endif -#ifdef ALAM_LIGHTING - //Hurdler: TDOD: do static lighting using gr_curline->lm - HWR_WallLighting(trVerts); - - //Hurdler: for better dynamic light in dark area, we should draw the light first - // and then the wall all that with the right blending func - //HWD.pfnDrawPolygon(pSurf, trVerts, 4, PF_Additive|PF_Modulated|PF_Occlude|PF_Clip); -#endif } -// ========================================================================== -// BSP, CULL, ETC.. -// ========================================================================== - -// return the frac from the interception of the clipping line -// (in fact a clipping plane that has a constant, so can clip with simple 2d) -// with the wall segment -// -#ifndef NEWCLIP -static float HWR_ClipViewSegment(INT32 x, polyvertex_t *v1, polyvertex_t *v2) -{ - float num, den; - float v1x, v1y, v1dx, v1dy, v2dx, v2dy; - angle_t pclipangle = gr_xtoviewangle[x]; - - // a segment of a polygon - v1x = v1->x; - v1y = v1->y; - v1dx = (v2->x - v1->x); - v1dy = (v2->y - v1->y); - - // the clipping line - pclipangle = pclipangle + dup_viewangle; //back to normal angle (non-relative) - v2dx = FIXED_TO_FLOAT(FINECOSINE(pclipangle>>ANGLETOFINESHIFT)); - v2dy = FIXED_TO_FLOAT(FINESINE(pclipangle>>ANGLETOFINESHIFT)); - - den = v2dy*v1dx - v2dx*v1dy; - if (den == 0) - return -1; // parallel - - // calc the frac along the polygon segment, - //num = (v2x - v1x)*v2dy + (v1y - v2y)*v2dx; - //num = -v1x * v2dy + v1y * v2dx; - num = (gr_viewx - v1x)*v2dy + (v1y - gr_viewy)*v2dx; - - return num / den; -} -#endif - // // HWR_SplitWall // -static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, FSurfaceInfo* Surf, INT32 cutflag, ffloor_t *pfloor) +void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, FSurfaceInfo* Surf, INT32 cutflag, ffloor_t *pfloor) { /* SoM: split up and light walls according to the lightlist. This may also include leaving out parts @@ -1098,8 +610,8 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, INT32 solid, i; lightlist_t * list = sector->lightlist; - const UINT8 alpha = Surf->FlatColor.s.alpha; - FUINT lightnum = sector->lightlevel; + const UINT8 alpha = Surf->PolyColor.s.alpha; + FUINT lightnum = HWR_CalcWallLight(sector->lightlevel, v1x, v1y, v2x, v2y); extracolormap_t *colormap = NULL; realtop = top = wallVerts[3].y; @@ -1119,22 +631,21 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, for (i = 0; i < sector->numlights; i++) { #ifdef ESLOPE - if (endtop < endrealbot) + if (endtop < endrealbot) #endif if (top < realbot) return; - // There's a compiler warning here if this comment isn't here because of indentation if (!(list[i].flags & FF_NOSHADE)) { if (pfloor && (pfloor->flags & FF_FOG)) { - lightnum = pfloor->master->frontsector->lightlevel; + lightnum = HWR_CalcWallLight(pfloor->master->frontsector->lightlevel, v1x, v1y, v2x, v2y); colormap = pfloor->master->frontsector->extra_colormap; } else { - lightnum = *list[i].lightlevel; + lightnum = HWR_CalcWallLight(*list[i].lightlevel, v1x, v1y, v2x, v2y); colormap = list[i].extra_colormap; } } @@ -1244,7 +755,7 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, if (endbot < endrealbot) endbot = endrealbot; #endif - Surf->FlatColor.s.alpha = alpha; + Surf->PolyColor.s.alpha = alpha; #ifdef ESLOPE wallVerts[3].t = pegt + ((realtop - top) * pegmul); @@ -1287,7 +798,7 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, if (top <= realbot) return; - Surf->FlatColor.s.alpha = alpha; + Surf->PolyColor.s.alpha = alpha; #ifdef ESLOPE wallVerts[3].t = pegt + ((realtop - top) * pegmul); @@ -1319,7 +830,7 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, // HWR_DrawSkyWalls // Draw walls into the depth buffer so that anything behind is culled properly -static void HWR_DrawSkyWall(wallVert3D *wallVerts, FSurfaceInfo *Surf) +void HWR_DrawSkyWall(FOutVector *wallVerts, FSurfaceInfo *Surf) { HWD.pfnSetTexture(NULL); // no texture @@ -1327,26 +838,23 @@ static void HWR_DrawSkyWall(wallVert3D *wallVerts, FSurfaceInfo *Surf) wallVerts[0].t = wallVerts[1].t = 0; wallVerts[0].s = wallVerts[3].s = 0; wallVerts[2].s = wallVerts[1].s = 0; - HWR_ProjectWall(wallVerts, Surf, PF_Invisible|PF_Clip|PF_NoTexture, 255, NULL); + + HWR_ProjectWall(wallVerts, Surf, PF_Invisible|PF_NoTexture, 255, NULL); // PF_Invisible so it's not drawn into the colour buffer // PF_NoTexture for no texture // PF_Occlude is set in HWR_ProjectWall to draw into the depth buffer } // -// HWR_StoreWallRange +// HWR_ProcessSeg // A portion or all of a wall segment will be drawn, from startfrac to endfrac, // where 0 is the start of the segment, 1 the end of the segment // Anything between means the wall segment has been clipped with solidsegs, // reducing wall overdraw to a minimum // -#ifdef NEWCLIP -static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom -#else -static void HWR_StoreWallRange(double startfrac, double endfrac) -#endif +void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom { - wallVert3D wallVerts[4]; + FOutVector wallVerts[4]; v2d_t vs, ve; // start, end vertices of 2d line (view from above) fixed_t worldtop, worldbottom; @@ -1369,11 +877,6 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) extracolormap_t *colormap; FSurfaceInfo Surf; -#ifndef NEWCLIP - if (startfrac > endfrac) - return; -#endif - gr_sidedef = gr_curline->sidedef; gr_linedef = gr_curline->linedef; @@ -1415,35 +918,19 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) wallVerts[0].z = wallVerts[3].z = vs.y; wallVerts[2].x = wallVerts[1].x = ve.x; wallVerts[2].z = wallVerts[1].z = ve.y; - wallVerts[0].w = wallVerts[1].w = wallVerts[2].w = wallVerts[3].w = 1.0f; + // x offset the texture { - // x offset the texture fixed_t texturehpeg = gr_sidedef->textureoffset + gr_curline->offset; - -#ifndef NEWCLIP - // clip texture s start/end coords with solidsegs - if (startfrac > 0.0f && startfrac < 1.0f) - cliplow = (float)(texturehpeg + (gr_curline->flength*FRACUNIT) * startfrac); - else -#endif - cliplow = (float)texturehpeg; - -#ifndef NEWCLIP - if (endfrac > 0.0f && endfrac < 1.0f) - cliphigh = (float)(texturehpeg + (gr_curline->flength*FRACUNIT) * endfrac); - else -#endif - cliphigh = (float)(texturehpeg + (gr_curline->flength*FRACUNIT)); + cliplow = (float)texturehpeg; + cliphigh = (float)(texturehpeg + (gr_curline->flength*FRACUNIT)); } - lightnum = gr_frontsector->lightlevel; + lightnum = HWR_CalcWallLight(gr_frontsector->lightlevel, vs.x, vs.y, ve.x, ve.y); colormap = gr_frontsector->extra_colormap; if (gr_frontsector) - { - Surf.FlatColor.s.alpha = 255; - } + Surf.PolyColor.s.alpha = 255; if (gr_backsector) { @@ -1471,11 +958,9 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) { // Both front and back sectors are sky, needs skywall from the frontsector's ceiling, but only if the // backsector is lower - if ((worldhigh <= worldtop) -#ifdef ESLOPE - && (worldhighslope <= worldtopslope) -#endif - ) + if ((worldhigh <= worldtop && worldhighslope <= worldtopslope)// Assuming ESLOPE is always on with my changes + && (worldhigh != worldtop || worldhighslope != worldtopslope)) + // Removing the second line above will render more rarely visible skywalls. Example: Cave garden ceiling in Dark race { #ifdef ESLOPE wallVerts[0].y = FIXED_TO_FLOAT(worldhigh); @@ -1521,10 +1006,9 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) // Both front and back sectors are sky, needs skywall from the backsector's floor, but only if the // it's higher, also needs to check for bottomtexture as the floors don't usually move down // when both sides are sky floors - if ((worldlow >= worldbottom) -#ifdef ESLOPE - && (worldlowslope >= worldbottomslope) -#endif + if ((worldlow >= worldbottom && worldlowslope >= worldbottomslope) + && (worldlow != worldbottom || worldlowslope != worldbottomslope) + // Removing the second line above will render more rarely visible skywalls. Example: Cave garden ceiling in Dark race && !(gr_sidedef->bottomtexture)) { #ifdef ESLOPE @@ -1562,6 +1046,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) HWR_DrawSkyWall(wallVerts, &Surf); } + } // hack to allow height changes in outdoor areas @@ -1987,7 +1472,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) { if (gr_curline->polyseg->translucency >= NUMTRANSMAPS) // wall not drawn { - Surf.FlatColor.s.alpha = 0x00; // This shouldn't draw anything regardless of blendmode + Surf.PolyColor.s.alpha = 0x00; // This shouldn't draw anything regardless of blendmode blendmode = PF_Masked; } else @@ -2008,21 +1493,13 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) HWR_AddTransparentWall(wallVerts, &Surf, gr_midtexture, blendmode, false, lightnum, colormap); else HWR_ProjectWall(wallVerts, &Surf, blendmode, lightnum, colormap); - - // If there is a colormap change, remove it. -/* if (!(Surf.FlatColor.s.red + Surf.FlatColor.s.green + Surf.FlatColor.s.blue == Surf.FlatColor.s.red/3) - { - Surf.FlatColor.s.red = Surf.FlatColor.s.green = Surf.FlatColor.s.blue = 0xff; - Surf.FlatColor.rgba = 0xffffffff; - }*/ } } else { // Single sided line... Deal only with the middletexture (if one exists) gr_midtexture = R_GetTextureNum(gr_sidedef->midtexture); - if (gr_midtexture - && gr_linedef->special != 41) // Ignore horizon line for OGL + if (gr_midtexture && gr_linedef->special != 41) // (Ignore horizon line for OGL) { { fixed_t texturevpeg; @@ -2072,9 +1549,10 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(worldtop); wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(worldbottom); #endif - // I don't think that solid walls can use translucent linedef types... + if (gr_frontsector->numlights) HWR_SplitWall(gr_frontsector, wallVerts, gr_midtexture, &Surf, FF_CUTLEVEL, NULL); + // I don't think that solid walls can use translucent linedef types... else { if (grTex->mipmap.flags & TF_TRANSPARENT) @@ -2134,7 +1612,6 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) //Hurdler: 3d-floors test -#ifdef R_FAKEFLOORS if (gr_frontsector && gr_backsector && gr_frontsector->tag != gr_backsector->tag && (gr_backsector->ffloors || gr_frontsector->ffloors)) { ffloor_t * rover; @@ -2274,18 +1751,10 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) blendmode = PF_Fog|PF_NoTexture; - lightnum = rover->master->frontsector->lightlevel; + lightnum = HWR_CalcWallLight(rover->master->frontsector->lightlevel, vs.x, vs.y, ve.x, ve.y); colormap = rover->master->frontsector->extra_colormap; - if (rover->master->frontsector->extra_colormap) - { - - Surf.FlatColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel,rover->master->frontsector->extra_colormap->rgba); - } - else - { - Surf.FlatColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel,NORMALFOG); - } + Surf.PolyColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel, rover->master->frontsector->extra_colormap); if (gr_frontsector->numlights) HWR_SplitWall(gr_frontsector, wallVerts, 0, &Surf, rover->flags, rover); @@ -2299,7 +1768,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) if (rover->flags & FF_TRANSLUCENT && rover->alpha < 256) { blendmode = PF_Translucent; - Surf.FlatColor.s.alpha = (UINT8)rover->alpha-1 > 255 ? 255 : rover->alpha-1; + Surf.PolyColor.s.alpha = (UINT8)rover->alpha-1 > 255 ? 255 : rover->alpha-1; } if (gr_frontsector->numlights) @@ -2394,17 +1863,10 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) blendmode = PF_Fog|PF_NoTexture; - lightnum = rover->master->frontsector->lightlevel; + lightnum = HWR_CalcWallLight(rover->master->frontsector->lightlevel, vs.x, vs.y, ve.x, ve.y); colormap = rover->master->frontsector->extra_colormap; - if (rover->master->frontsector->extra_colormap) - { - Surf.FlatColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel,rover->master->frontsector->extra_colormap->rgba); - } - else - { - Surf.FlatColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel,NORMALFOG); - } + Surf.PolyColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel, rover->master->frontsector->extra_colormap); if (gr_backsector->numlights) HWR_SplitWall(gr_backsector, wallVerts, 0, &Surf, rover->flags, rover); @@ -2418,7 +1880,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) if (rover->flags & FF_TRANSLUCENT && rover->alpha < 256) { blendmode = PF_Translucent; - Surf.FlatColor.s.alpha = (UINT8)rover->alpha-1 > 255 ? 255 : rover->alpha-1; + Surf.PolyColor.s.alpha = (UINT8)rover->alpha-1 > 255 ? 255 : rover->alpha-1; } if (gr_backsector->numlights) @@ -2434,19 +1896,18 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) } } } -#endif //Hurdler: end of 3d-floors test } // From PrBoom: // -// e6y: Check whether the player can look beyond this line +// e6y: Check whether the player can look beyond this line, rturns true if we can't // -#ifdef NEWCLIP -static boolean checkforemptylines = true; + +boolean checkforemptylines = true; // Don't modify anything here, just check // Kalaron: Modified for sloped linedefs -static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacksector) +static boolean CheckClip(sector_t * afrontsector, sector_t * abacksector) { fixed_t frontf1,frontf2, frontc1, frontc2; // front floor/ceiling ends fixed_t backf1, backf2, backc1, backc2; // back floor ceiling ends @@ -2483,34 +1944,45 @@ static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacks backc1 = backc2 = abacksector->ceilingheight; } - if (viewsector != abacksector && viewsector != afrontsector) + + // now check for closed sectors! + + // here we're talking about a CEILING lower than a floor. ...yeah we don't even need to bother. + if (backc1 <= frontf1 && backc2 <= frontf2) { - boolean mydoorclosed = false; // My door? Closed!? (doorclosed is actually otherwise unused in openGL) + checkforemptylines = false; + return true; + } - // If the sector behind the line blocks all kinds of view past it - // (back ceiling is lower than close floor, or back floor is higher than close ceiling) - if ((backc1 <= frontf1 && backc2 <= frontf2) - || (backf1 >= frontc1 && backf2 >= frontc2)) - { - checkforemptylines = false; - return true; - } + // here we're talking about floors higher than ceilings, don't even bother either. + if (backf1 >= frontc1 && backf2 >= frontc2) + { + checkforemptylines = false; + return true; + } - // The door is closed if: - // backsector is 0 height or less and - // back ceiling is higher than close ceiling or we need to render a top texture and - // back floor is lower than close floor or we need to render a bottom texture and - // neither front or back sectors are using the sky ceiling - mydoorclosed = (backc1 <= backf1 && backc2 <= backf2 - && ((backc1 >= frontc1 && backc2 >= frontc2) || seg->sidedef->toptexture) - && ((backf1 <= frontf1 && backf2 >= frontf2) || seg->sidedef->bottomtexture) - && (abacksector->ceilingpic != skyflatnum || afrontsector->ceilingpic != skyflatnum)); + // Lat: Ok, here's what we need to do, we want to draw thok barriers. Let's define what a thok barrier is; + // -Must have ceilheight <= floorheight + // -ceilpic must be skyflatnum + // -an adjacant sector needs to have a ceilingheight or a floor height different than the one we have, otherwise, it's just a huge ass wall, we shouldn't render past it. + // -said adjacant sector cannot also be a thok barrier, because that's also dumb and we could render far more than we need to as a result :V - if (mydoorclosed) - { - checkforemptylines = false; - return true; - } + if (backc1 <= backf1 && backc2 <= backf2) + { + checkforemptylines = false; + + // before we do anything, if both sectors are thok barriers, GET ME OUT OF HERE! + if (frontc1 <= backc1 && frontc2 <= backc2) + return true; // STOP RENDERING. + + // draw floors at the top of thok barriers: + if (backc1 < frontc1 || backc2 < frontc2) + return false; + + if (backf1 > frontf1 || backf2 > frontf2) + return false; + + return true; } // Window. @@ -2526,306 +1998,12 @@ static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacks // stays true return false; } -#else -//Hurdler: just like in r_bsp.c -#if 1 -#define MAXSEGS MAXVIDWIDTH/2+1 -#else -//Alam_GBC: Or not (may cause overflow) -#define MAXSEGS 128 -#endif -// hw_newend is one past the last valid seg -static cliprange_t * hw_newend; -static cliprange_t gr_solidsegs[MAXSEGS]; - - -static void printsolidsegs(void) -{ - cliprange_t * start; - if (!hw_newend || cv_grbeta.value != 2) - return; - for (start = gr_solidsegs;start != hw_newend;start++) - { - CONS_Debug(DBG_RENDER, "%d-%d|",start->first,start->last); - } - CONS_Debug(DBG_RENDER, "\n\n"); -} - -// -// -// -static void HWR_ClipSolidWallSegment(INT32 first, INT32 last) -{ - cliprange_t *next, *start; - float lowfrac, highfrac; - boolean poorhack = false; - - // Find the first range that touches the range - // (adjacent pixels are touching). - start = gr_solidsegs; - while (start->last < first-1) - start++; - - if (first < start->first) - { - if (last < start->first-1) - { - // Post is entirely visible (above start), - // so insert a new clippost. - HWR_StoreWallRange(first, last); - - next = hw_newend; - hw_newend++; - - while (next != start) - { - *next = *(next-1); - next--; - } - - next->first = first; - next->last = last; - printsolidsegs(); - return; - } - - // There is a fragment above *start. - if (!cv_grclipwalls.value) - { - if (!poorhack) HWR_StoreWallRange(first, last); - poorhack = true; - } - else - { - highfrac = HWR_ClipViewSegment(start->first+1, (polyvertex_t *)gr_curline->pv1, (polyvertex_t *)gr_curline->pv2); - HWR_StoreWallRange(0, highfrac); - } - // Now adjust the clip size. - start->first = first; - } - - // Bottom contained in start? - if (last <= start->last) - { - printsolidsegs(); - return; - } - next = start; - while (last >= (next+1)->first-1) - { - // There is a fragment between two posts. - if (!cv_grclipwalls.value) - { - if (!poorhack) HWR_StoreWallRange(first,last); - poorhack = true; - } - else - { - lowfrac = HWR_ClipViewSegment(next->last-1, (polyvertex_t *)gr_curline->pv1, (polyvertex_t *)gr_curline->pv2); - highfrac = HWR_ClipViewSegment((next+1)->first+1, (polyvertex_t *)gr_curline->pv1, (polyvertex_t *)gr_curline->pv2); - HWR_StoreWallRange(lowfrac, highfrac); - } - next++; - - if (last <= next->last) - { - // Bottom is contained in next. - // Adjust the clip size. - start->last = next->last; - goto crunch; - } - } - - if (first == next->first+1) // 1 line texture - { - if (!cv_grclipwalls.value) - { - if (!poorhack) HWR_StoreWallRange(first,last); - poorhack = true; - } - else - HWR_StoreWallRange(0, 1); - } - else - { - // There is a fragment after *next. - if (!cv_grclipwalls.value) - { - if (!poorhack) HWR_StoreWallRange(first,last); - poorhack = true; - } - else - { - lowfrac = HWR_ClipViewSegment(next->last-1, (polyvertex_t *)gr_curline->pv1, (polyvertex_t *)gr_curline->pv2); - HWR_StoreWallRange(lowfrac, 1); - } - } - - // Adjust the clip size. - start->last = last; - - // Remove start+1 to next from the clip list, - // because start now covers their area. -crunch: - if (next == start) - { - printsolidsegs(); - // Post just extended past the bottom of one post. - return; - } - - - while (next++ != hw_newend) - { - // Remove a post. - *++start = *next; - } - - hw_newend = start; - printsolidsegs(); -} - -// -// handle LineDefs with upper and lower texture (windows) -// -static void HWR_ClipPassWallSegment(INT32 first, INT32 last) -{ - cliprange_t *start; - float lowfrac, highfrac; - //to allow noclipwalls but still solidseg reject of non-visible walls - boolean poorhack = false; - - // Find the first range that touches the range - // (adjacent pixels are touching). - start = gr_solidsegs; - while (start->last < first - 1) - start++; - - if (first < start->first) - { - if (last < start->first-1) - { - // Post is entirely visible (above start). - HWR_StoreWallRange(0, 1); - return; - } - - // There is a fragment above *start. - if (!cv_grclipwalls.value) - { //20/08/99: Changed by Hurdler (taken from faB's code) - if (!poorhack) HWR_StoreWallRange(0, 1); - poorhack = true; - } - else - { - highfrac = HWR_ClipViewSegment(min(start->first + 1, - start->last), (polyvertex_t *)gr_curline->pv1, - (polyvertex_t *)gr_curline->pv2); - HWR_StoreWallRange(0, highfrac); - } - } - - // Bottom contained in start? - if (last <= start->last) - return; - - while (last >= (start+1)->first-1) - { - // There is a fragment between two posts. - if (!cv_grclipwalls.value) - { - if (!poorhack) HWR_StoreWallRange(0, 1); - poorhack = true; - } - else - { - lowfrac = HWR_ClipViewSegment(max(start->last-1,start->first), (polyvertex_t *)gr_curline->pv1, (polyvertex_t *)gr_curline->pv2); - highfrac = HWR_ClipViewSegment(min((start+1)->first+1,(start+1)->last), (polyvertex_t *)gr_curline->pv1, (polyvertex_t *)gr_curline->pv2); - HWR_StoreWallRange(lowfrac, highfrac); - } - start++; - - if (last <= start->last) - return; - } - - if (first == start->first+1) // 1 line texture - { - if (!cv_grclipwalls.value) - { - if (!poorhack) HWR_StoreWallRange(0, 1); - poorhack = true; - } - else - HWR_StoreWallRange(0, 1); - } - else - { - // There is a fragment after *next. - if (!cv_grclipwalls.value) - { - if (!poorhack) HWR_StoreWallRange(0,1); - poorhack = true; - } - else - { - lowfrac = HWR_ClipViewSegment(max(start->last - 1, - start->first), (polyvertex_t *)gr_curline->pv1, - (polyvertex_t *)gr_curline->pv2); - HWR_StoreWallRange(lowfrac, 1); - } - } -} - -// -------------------------------------------------------------------------- -// HWR_ClipToSolidSegs check if it is hide by wall (solidsegs) -// -------------------------------------------------------------------------- -static boolean HWR_ClipToSolidSegs(INT32 first, INT32 last) -{ - cliprange_t * start; - - // Find the first range that touches the range - // (adjacent pixels are touching). - start = gr_solidsegs; - while (start->last < first-1) - start++; - - if (first < start->first) - return true; - - // Bottom contained in start? - if (last <= start->last) - return false; - - return true; -} - -// -// HWR_ClearClipSegs -// -static void HWR_ClearClipSegs(void) -{ - gr_solidsegs[0].first = -0x7fffffff; - gr_solidsegs[0].last = -1; - gr_solidsegs[1].first = vid.width; //viewwidth; - gr_solidsegs[1].last = 0x7fffffff; - hw_newend = gr_solidsegs+2; -} -#endif // NEWCLIP - -// -----------------+ -// HWR_AddLine : Clips the given segment and adds any visible pieces to the line list. -// Notes : gr_cursectorlight is set to the current subsector -> sector -> light value -// : (it may be mixed with the wall's own flat colour in the future ...) -// -----------------+ -static void HWR_AddLine(seg_t * line) +// HWR_AddLine +// Clips the given segment and adds any visible pieces to the line list. +void HWR_AddLine(seg_t *line) { angle_t angle1, angle2; -#ifndef NEWCLIP - INT32 x1, x2; - angle_t span, tspan; -#endif // SoM: Backsector needs to be run through R_FakeFlat static sector_t tempsec; @@ -2844,114 +2022,27 @@ static void HWR_AddLine(seg_t * line) v2y = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv2)->y); // OPTIMIZE: quickly reject orthogonal back sides. - angle1 = R_PointToAngle(v1x, v1y); - angle2 = R_PointToAngle(v2x, v2y); + angle1 = R_PointToAngleEx(viewx, viewy, v1x, v1y); + angle2 = R_PointToAngleEx(viewx, viewy, v2x, v2y); -#ifdef NEWCLIP // PrBoom: Back side, i.e. backface culling - read: endAngle >= startAngle! if (angle2 - angle1 < ANGLE_180) return; // PrBoom: use REAL clipping math YAYYYYYYY!!! - if (!gld_clipper_SafeCheckRange(angle2, angle1)) - { return; - } checkforemptylines = true; -#else - // Clip to view edges. - span = angle1 - angle2; - - // backface culling : span is < ANGLE_180 if ang1 > ang2 : the seg is facing - if (span >= ANGLE_180) - return; - - // Global angle needed by segcalc. - //rw_angle1 = angle1; - angle1 -= dup_viewangle; - angle2 -= dup_viewangle; - - tspan = angle1 + gr_clipangle; - if (tspan > 2*gr_clipangle) - { - tspan -= 2*gr_clipangle; - - // Totally off the left edge? - if (tspan >= span) - return; - - angle1 = gr_clipangle; - } - tspan = gr_clipangle - angle2; - if (tspan > 2*gr_clipangle) - { - tspan -= 2*gr_clipangle; - - // Totally off the left edge? - if (tspan >= span) - return; - - angle2 = (angle_t)-(signed)gr_clipangle; - } - -#if 0 - { - float fx1,fx2,fy1,fy2; - //BP: test with a better projection than viewangletox[R_PointToAngle(angle)] - // do not enable this at release 4 mul and 2 div - fx1 = ((polyvertex_t *)(line->pv1))->x-gr_viewx; - fy1 = ((polyvertex_t *)(line->pv1))->y-gr_viewy; - fy2 = (fx1 * gr_viewcos + fy1 * gr_viewsin); - if (fy2 < 0) - // the point is back - fx1 = 0; - else - fx1 = gr_windowcenterx + (fx1 * gr_viewsin - fy1 * gr_viewcos) * gr_centerx / fy2; - - fx2 = ((polyvertex_t *)(line->pv2))->x-gr_viewx; - fy2 = ((polyvertex_t *)(line->pv2))->y-gr_viewy; - fy1 = (fx2 * gr_viewcos + fy2 * gr_viewsin); - if (fy1 < 0) - // the point is back - fx2 = vid.width; - else - fx2 = gr_windowcenterx + (fx2 * gr_viewsin - fy2 * gr_viewcos) * gr_centerx / fy1; - - x1 = fx1+0.5f; - x2 = fx2+0.5f; - } -#else - // The seg is in the view range, - // but not necessarily visible. - angle1 = (angle1+ANGLE_90)>>ANGLETOFINESHIFT; - angle2 = (angle2+ANGLE_90)>>ANGLETOFINESHIFT; - - x1 = gr_viewangletox[angle1]; - x2 = gr_viewangletox[angle2]; -#endif - // Does not cross a pixel? -// if (x1 == x2) -/* { - // BP: HERE IS THE MAIN PROBLEM ! - //CONS_Debug(DBG_RENDER, "tineline\n"); - return; - } -*/ -#endif gr_backsector = line->backsector; -#ifdef NEWCLIP if (!line->backsector) - { gld_clipper_SafeAddClipRange(angle2, angle1); - } - else - { + else + { gr_backsector = R_FakeFlat(gr_backsector, &tempsec, NULL, NULL, true); - if (CheckClip(line, gr_frontsector, gr_backsector)) + if (CheckClip(gr_frontsector, gr_backsector)) { gld_clipper_SafeAddClipRange(angle2, angle1); checkforemptylines = false; @@ -2966,98 +2057,6 @@ static void HWR_AddLine(seg_t * line) HWR_ProcessSeg(); // Doesn't need arguments because they're defined globally :D return; -#else - // Single sided line? - if (!gr_backsector) - goto clipsolid; - - gr_backsector = R_FakeFlat(gr_backsector, &tempsec, NULL, NULL, true); - -#ifdef ESLOPE - if (gr_frontsector->f_slope || gr_frontsector->c_slope || gr_backsector->f_slope || gr_backsector->c_slope) - { - fixed_t frontf1,frontf2, frontc1, frontc2; // front floor/ceiling ends - fixed_t backf1, backf2, backc1, backc2; // back floor ceiling ends - -#define SLOPEPARAMS(slope, end1, end2, normalheight) \ - if (slope) { \ - end1 = P_GetZAt(slope, v1x, v1y); \ - end2 = P_GetZAt(slope, v2x, v2y); \ - } else \ - end1 = end2 = normalheight; - - SLOPEPARAMS(gr_frontsector->f_slope, frontf1, frontf2, gr_frontsector->floorheight) - SLOPEPARAMS(gr_frontsector->c_slope, frontc1, frontc2, gr_frontsector->ceilingheight) - SLOPEPARAMS( gr_backsector->f_slope, backf1, backf2, gr_backsector->floorheight) - SLOPEPARAMS( gr_backsector->c_slope, backc1, backc2, gr_backsector->ceilingheight) -#undef SLOPEPARAMS - - if (viewsector != gr_backsector && viewsector != gr_frontsector) - { - // Closed door. - if ((backc1 <= frontf1 && backc2 <= frontf2) - || (backf1 >= frontc1 && backf2 >= frontc2)) - { - goto clipsolid; - } - } - - // Check for automap fix. - if (backc1 <= backf1 && backc2 <= backf2 - && ((backc1 >= frontc1 && backc2 >= frontc2) || gr_curline->sidedef->toptexture) - && ((backf1 <= frontf1 && backf2 >= frontf2) || gr_curline->sidedef->bottomtexture) - && (gr_backsector->ceilingpic != skyflatnum || gr_frontsector->ceilingpic != skyflatnum)) - goto clipsolid; - - // Window. - if (backc1 != frontc1 || backc2 != frontc2 - || backf1 != frontf1 || backf2 != frontf2) - { - goto clippass; - } - } - else -#endif - { - if (viewsector != gr_backsector && viewsector != gr_frontsector) - { - // Closed door. - if (gr_backsector->ceilingheight <= gr_frontsector->floorheight || - gr_backsector->floorheight >= gr_frontsector->ceilingheight) - goto clipsolid; - } - - // Check for automap fix. - if (gr_backsector->ceilingheight <= gr_backsector->floorheight - && ((gr_backsector->ceilingheight >= gr_frontsector->ceilingheight) || gr_curline->sidedef->toptexture) - && ((gr_backsector->floorheight <= gr_backsector->floorheight) || gr_curline->sidedef->bottomtexture) - && (gr_backsector->ceilingpic != skyflatnum || gr_frontsector->ceilingpic != skyflatnum)) - goto clipsolid; - - // Window. - if (gr_backsector->ceilingheight != gr_frontsector->ceilingheight || - gr_backsector->floorheight != gr_frontsector->floorheight) - goto clippass; - } - - // Reject empty lines used for triggers and special events. - // Identical floor and ceiling on both sides, - // identical light levels on both sides, - // and no middle texture. - if (R_IsEmptyLine(gr_curline, gr_frontsector, gr_backsector)) - return; - -clippass: - if (x1 == x2) - { x2++;x1 -= 2; } - HWR_ClipPassWallSegment(x1, x2-1); - return; - -clipsolid: - if (x1 == x2) - goto clippass; - HWR_ClipSolidWallSegment(x1, x2-1); -#endif } // HWR_CheckBBox @@ -3067,28 +2066,24 @@ clipsolid: // // modified to use local variables -static boolean HWR_CheckBBox(fixed_t *bspcoord) +boolean HWR_CheckBBox(fixed_t *bspcoord) { INT32 boxpos; fixed_t px1, py1, px2, py2; angle_t angle1, angle2; -#ifndef NEWCLIP - INT32 sx1, sx2; - angle_t span, tspan; -#endif // Find the corners of the box // that define the edges from current viewpoint. - if (dup_viewx <= bspcoord[BOXLEFT]) + if (viewx <= bspcoord[BOXLEFT]) boxpos = 0; - else if (dup_viewx < bspcoord[BOXRIGHT]) + else if (viewx < bspcoord[BOXRIGHT]) boxpos = 1; else boxpos = 2; - if (dup_viewy >= bspcoord[BOXTOP]) + if (viewy >= bspcoord[BOXTOP]) boxpos |= 0; - else if (dup_viewy > bspcoord[BOXBOTTOM]) + else if (viewy > bspcoord[BOXBOTTOM]) boxpos |= 1<<2; else boxpos |= 2<<2; @@ -3101,59 +2096,9 @@ static boolean HWR_CheckBBox(fixed_t *bspcoord) px2 = bspcoord[checkcoord[boxpos][2]]; py2 = bspcoord[checkcoord[boxpos][3]]; -#ifdef NEWCLIP - angle1 = R_PointToAngle(px1, py1); - angle2 = R_PointToAngle(px2, py2); + angle1 = R_PointToAngleEx(viewx, viewy, px1, py1); + angle2 = R_PointToAngleEx(viewx, viewy, px2, py2); return gld_clipper_SafeCheckRange(angle2, angle1); -#else - // check clip list for an open space - angle1 = R_PointToAngle2(dup_viewx>>1, dup_viewy>>1, px1>>1, py1>>1) - dup_viewangle; - angle2 = R_PointToAngle2(dup_viewx>>1, dup_viewy>>1, px2>>1, py2>>1) - dup_viewangle; - - span = angle1 - angle2; - - // Sitting on a line? - if (span >= ANGLE_180) - return true; - - tspan = angle1 + gr_clipangle; - - if (tspan > 2*gr_clipangle) - { - tspan -= 2*gr_clipangle; - - // Totally off the left edge? - if (tspan >= span) - return false; - - angle1 = gr_clipangle; - } - tspan = gr_clipangle - angle2; - if (tspan > 2*gr_clipangle) - { - tspan -= 2*gr_clipangle; - - // Totally off the left edge? - if (tspan >= span) - return false; - - angle2 = (angle_t)-(signed)gr_clipangle; - } - - // Find the first clippost - // that touches the source post - // (adjacent pixels are touching). - angle1 = (angle1+ANGLE_90)>>ANGLETOFINESHIFT; - angle2 = (angle2+ANGLE_90)>>ANGLETOFINESHIFT; - sx1 = gr_viewangletox[angle1]; - sx2 = gr_viewangletox[angle2]; - - // Does not cross a pixel. - if (sx1 == sx2) - return false; - - return HWR_ClipToSolidSegs(sx1, sx2 - 1); -#endif } #ifdef POLYOBJECTS @@ -3165,7 +2110,7 @@ static boolean HWR_CheckBBox(fixed_t *bspcoord) // Adds all segs in all polyobjects in the given subsector. // Modified for hardware rendering. // -static inline void HWR_AddPolyObjectSegs(void) +void HWR_AddPolyObjectSegs(void) { size_t i, j; seg_t *gr_fakeline = Z_Calloc(sizeof(seg_t), PU_STATIC, NULL); @@ -3201,9 +2146,7 @@ static inline void HWR_AddPolyObjectSegs(void) } #ifdef POLYOBJECTS_PLANES -static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, - FBITFIELD blendmode, UINT8 lightlevel, lumpnum_t lumpnum, sector_t *FOFsector, - UINT8 alpha, extracolormap_t *planecolormap) +void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, FBITFIELD blendmode, UINT8 lightlevel, lumpnum_t lumpnum, sector_t *FOFsector, UINT8 alpha, extracolormap_t *planecolormap) { float height; //constant y for all points on the convex flat polygon FOutVector *v3d; @@ -3333,16 +2276,16 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, for (i = 0; i < (INT32)nrPlaneVerts; i++,v3d++) { // Hurdler: add scrolling texture on floor/ceiling - v3d->sow = (float)((FIXED_TO_FLOAT(polysector->origVerts[i].x) / fflatsize) - flatxref + scrollx); // Go from the polysector's original vertex locations - v3d->tow = (float)(flatyref - (FIXED_TO_FLOAT(polysector->origVerts[i].y) / fflatsize) + scrolly); // Means the flat is offset based on the original vertex locations + v3d->s = (float)((FIXED_TO_FLOAT(polysector->origVerts[i].x) / fflatsize) - flatxref + scrollx); // Go from the polysector's original vertex locations + v3d->t = (float)(flatyref - (FIXED_TO_FLOAT(polysector->origVerts[i].y) / fflatsize) + scrolly); // Means the flat is offset based on the original vertex locations // Need to rotate before translate if (angle) // Only needs to be done if there's an altered angle { - tempxsow = FLOAT_TO_FIXED(v3d->sow); - tempytow = FLOAT_TO_FIXED(v3d->tow); - v3d->sow = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINECOSINE(angle)) - FixedMul(tempytow, FINESINE(angle)))); - v3d->tow = (FIXED_TO_FLOAT(-FixedMul(tempxsow, FINESINE(angle)) - FixedMul(tempytow, FINECOSINE(angle)))); + tempxsow = FLOAT_TO_FIXED(v3d->s); + tempytow = FLOAT_TO_FIXED(v3d->t); + v3d->s = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINECOSINE(angle)) - FixedMul(tempytow, FINESINE(angle)))); + v3d->t = (FIXED_TO_FLOAT(-FixedMul(tempxsow, FINESINE(angle)) - FixedMul(tempytow, FINECOSINE(angle)))); } v3d->x = FIXED_TO_FLOAT(polysector->vertices[i]->x); @@ -3350,23 +2293,21 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, v3d->z = FIXED_TO_FLOAT(polysector->vertices[i]->y); } - if (planecolormap) - Surf.FlatColor.rgba = HWR_Lighting(lightlevel, planecolormap->rgba, planecolormap->fadergba, false, true); - else - Surf.FlatColor.rgba = HWR_Lighting(lightlevel, NORMALFOG, FADEFOG, false, true); + HWR_Lighting(&Surf, lightlevel, planecolormap); if (blendmode & PF_Translucent) { - Surf.FlatColor.s.alpha = (UINT8)alpha; - blendmode |= PF_Modulated|PF_Occlude|PF_Clip; + Surf.PolyColor.s.alpha = (UINT8)alpha; + blendmode |= PF_Modulated|PF_Occlude; } else - blendmode |= PF_Masked|PF_Modulated|PF_Clip; + blendmode |= PF_Masked|PF_Modulated; + HWD.pfnSetShader(1); // floor shader HWD.pfnDrawPolygon(&Surf, planeVerts, nrPlaneVerts, blendmode); } -static void HWR_AddPolyObjectPlanes(void) +void HWR_AddPolyObjectPlanes(void) { size_t i; sector_t *polyobjsector; @@ -3393,7 +2334,7 @@ static void HWR_AddPolyObjectPlanes(void) FSurfaceInfo Surf; FBITFIELD blendmode = HWR_TranstableToAlpha(po_ptrs[i]->translucency, &Surf); HWR_AddTransparentPolyobjectFloor(levelflats[polyobjsector->floorpic].lumpnum, po_ptrs[i], false, polyobjsector->floorheight, - polyobjsector->lightlevel, Surf.FlatColor.s.alpha, polyobjsector, blendmode, NULL); + polyobjsector->lightlevel, Surf.PolyColor.s.alpha, polyobjsector, blendmode, NULL); } else { @@ -3415,11 +2356,11 @@ static void HWR_AddPolyObjectPlanes(void) memset(&Surf, 0x00, sizeof(Surf)); blendmode = HWR_TranstableToAlpha(po_ptrs[i]->translucency, &Surf); HWR_AddTransparentPolyobjectFloor(levelflats[polyobjsector->ceilingpic].lumpnum, po_ptrs[i], true, polyobjsector->ceilingheight, - polyobjsector->lightlevel, Surf.FlatColor.s.alpha, polyobjsector, blendmode, NULL); + polyobjsector->lightlevel, Surf.PolyColor.s.alpha, polyobjsector, blendmode, NULL); } else { - HWR_GetFlat(levelflats[polyobjsector->ceilingpic].lumpnum, R_NoEncore(polyobjsector, false)); + HWR_GetFlat(levelflats[polyobjsector->ceilingpic].lumpnum, R_NoEncore(polyobjsector, true)); HWR_RenderPolyObjectPlane(po_ptrs[i], true, polyobjsector->ceilingheight, PF_Occlude, polyobjsector->lightlevel, levelflats[polyobjsector->floorpic].lumpnum, polyobjsector, 255, NULL); @@ -3434,9 +2375,8 @@ static void HWR_AddPolyObjectPlanes(void) // HWR_Subsector : Determine floor/ceiling planes. // : Add sprites of things in sector. // : Draw one or more line segments. -// Notes : Sets gr_cursectorlight to the light of the parent sector, to modulate wall textures // -----------------+ -static void HWR_Subsector(size_t num) +void HWR_Subsector(size_t num) { INT16 count; seg_t *line; @@ -3454,11 +2394,6 @@ static void HWR_Subsector(size_t num) if (num >= addsubsector) I_Error("HWR_Subsector: ss %s with numss = %s, addss = %s\n", sizeu1(num), sizeu2(numsubsectors), sizeu3(addsubsector)); - - /*if (num >= numsubsectors) - I_Error("HWR_Subsector: ss %i with numss = %i", - num, - numsubsectors);*/ #endif if (num < numsubsectors) @@ -3488,16 +2423,6 @@ static void HWR_Subsector(size_t num) floorcolormap = ceilingcolormap = gr_frontsector->extra_colormap; - // ------------------------------------------------------------------------ - // sector lighting, DISABLED because it's done in HWR_StoreWallRange - // ------------------------------------------------------------------------ - /// \todo store a RGBA instead of just intensity, allow coloured sector lighting - //light = (FUBYTE)(sub->sector->lightlevel & 0xFF) / 255.0f; - //gr_cursectorlight.red = light; - //gr_cursectorlight.green = light; - //gr_cursectorlight.blue = light; - //gr_cursectorlight.alpha = light; - // ----- for special tricks with HW renderer ----- if (gr_frontsector->pseudoSector) { @@ -3564,59 +2489,39 @@ static void HWR_Subsector(size_t num) sub->sector->extra_colormap = gr_frontsector->extra_colormap; // render floor ? -#ifdef DOPLANES // yeah, easy backface cull! :) - if (cullFloorHeight < dup_viewz) + if (cullFloorHeight < viewz) { if (gr_frontsector->floorpic != skyflatnum) { if (sub->validcount != validcount) { HWR_GetFlat(levelflats[gr_frontsector->floorpic].lumpnum, R_NoEncore(gr_frontsector, false)); - HWR_RenderPlane(gr_frontsector, &extrasubsectors[num], false, + HWR_RenderPlane(&extrasubsectors[num], false, // Hack to make things continue to work around slopes. locFloorHeight == cullFloorHeight ? locFloorHeight : gr_frontsector->floorheight, // We now return you to your regularly scheduled rendering. - PF_Occlude, floorlightlevel, levelflats[gr_frontsector->floorpic].lumpnum, NULL, 255, false, floorcolormap); + PF_Occlude, floorlightlevel, levelflats[gr_frontsector->floorpic].lumpnum, NULL, 255, floorcolormap); } } - else - { -#ifdef POLYSKY - HWR_RenderSkyPlane(&extrasubsectors[num], locFloorHeight); -#endif - } } - if (cullCeilingHeight > dup_viewz) + if (cullCeilingHeight > viewz) { if (gr_frontsector->ceilingpic != skyflatnum) { if (sub->validcount != validcount) { - HWR_GetFlat(levelflats[gr_frontsector->ceilingpic].lumpnum, R_NoEncore(gr_frontsector, false)); - HWR_RenderPlane(NULL, &extrasubsectors[num], true, + HWR_GetFlat(levelflats[gr_frontsector->ceilingpic].lumpnum, R_NoEncore(gr_frontsector, true)); + HWR_RenderPlane(&extrasubsectors[num], true, // Hack to make things continue to work around slopes. locCeilingHeight == cullCeilingHeight ? locCeilingHeight : gr_frontsector->ceilingheight, // We now return you to your regularly scheduled rendering. - PF_Occlude, ceilinglightlevel, levelflats[gr_frontsector->ceilingpic].lumpnum,NULL, 255, false, ceilingcolormap); + PF_Occlude, ceilinglightlevel, levelflats[gr_frontsector->ceilingpic].lumpnum,NULL, 255, ceilingcolormap); } } - else - { -#ifdef POLYSKY - HWR_RenderSkyPlane(&extrasubsectors[num], locCeilingHeight); -#endif - } } -#ifndef POLYSKY - // Moved here because before, when above the ceiling and the floor does not have the sky flat, it doesn't draw the sky - if (gr_frontsector->ceilingpic == skyflatnum || gr_frontsector->floorpic == skyflatnum) - drawsky = true; -#endif - -#ifdef R_FAKEFLOORS if (gr_frontsector->ffloors) { /// \todo fix light, xoffs, yoffs, extracolormap ? @@ -3644,19 +2549,16 @@ static void HWR_Subsector(size_t num) if (centerHeight <= locCeilingHeight && centerHeight >= locFloorHeight && - ((dup_viewz < cullHeight && !(rover->flags & FF_INVERTPLANES)) || - (dup_viewz > cullHeight && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES)))) + ((viewz < cullHeight && !(rover->flags & FF_INVERTPLANES)) || + (viewz > cullHeight && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES)))) { if (rover->flags & FF_FOG) { UINT8 alpha; - light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false); + light = R_GetPlaneLight(gr_frontsector, centerHeight, viewz < cullHeight ? true : false); - if (rover->master->frontsector->extra_colormap) - alpha = HWR_FogBlockAlpha(*gr_frontsector->lightlist[light].lightlevel, rover->master->frontsector->extra_colormap->rgba); - else - alpha = HWR_FogBlockAlpha(*gr_frontsector->lightlist[light].lightlevel, NORMALFOG); + alpha = HWR_FogBlockAlpha(*gr_frontsector->lightlist[light].lightlevel, rover->master->frontsector->extra_colormap); HWR_AddTransparentFloor(0, &extrasubsectors[num], @@ -3668,29 +2570,21 @@ static void HWR_Subsector(size_t num) } else if (rover->flags & FF_TRANSLUCENT && rover->alpha < 256) // SoM: Flags are more efficient { - light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false); -#ifndef SORTING - HWR_Add3DWater(levelflats[*rover->bottompic].lumpnum, - &extrasubsectors[num], - *rover->bottomheight, - *gr_frontsector->lightlist[light].lightlevel, - rover->alpha-1, rover->master->frontsector); -#else + light = R_GetPlaneLight(gr_frontsector, centerHeight, viewz < cullHeight ? true : false); HWR_AddTransparentFloor(levelflats[*rover->bottompic].lumpnum, &extrasubsectors[num], false, *rover->bottomheight, *gr_frontsector->lightlist[light].lightlevel, - rover->alpha-1 > 255 ? 255 : rover->alpha-1, rover->master->frontsector, PF_Translucent, + rover->alpha-1 > 255 ? 255 : rover->alpha-1, rover->master->frontsector, (rover->flags & FF_RIPPLE ? PF_Ripple : 0)|PF_Translucent, false, gr_frontsector->lightlist[light].extra_colormap); -#endif } else { HWR_GetFlat(levelflats[*rover->bottompic].lumpnum, R_NoEncore(gr_frontsector, false)); - light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false); - HWR_RenderPlane(NULL, &extrasubsectors[num], false, *rover->bottomheight, PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, levelflats[*rover->bottompic].lumpnum, - rover->master->frontsector, 255, false, gr_frontsector->lightlist[light].extra_colormap); + light = R_GetPlaneLight(gr_frontsector, centerHeight, viewz < cullHeight ? true : false); + HWR_RenderPlane(&extrasubsectors[num], false, *rover->bottomheight, (rover->flags & FF_RIPPLE ? PF_Ripple : 0)|PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, levelflats[*rover->bottompic].lumpnum, + rover->master->frontsector, 255, gr_frontsector->lightlist[light].extra_colormap); } } @@ -3707,19 +2601,16 @@ static void HWR_Subsector(size_t num) if (centerHeight >= locFloorHeight && centerHeight <= locCeilingHeight && - ((dup_viewz > cullHeight && !(rover->flags & FF_INVERTPLANES)) || - (dup_viewz < cullHeight && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES)))) + ((viewz > cullHeight && !(rover->flags & FF_INVERTPLANES)) || + (viewz < cullHeight && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES)))) { if (rover->flags & FF_FOG) { UINT8 alpha; - light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false); + light = R_GetPlaneLight(gr_frontsector, centerHeight, viewz < cullHeight ? true : false); - if (rover->master->frontsector->extra_colormap) - alpha = HWR_FogBlockAlpha(*gr_frontsector->lightlist[light].lightlevel, rover->master->frontsector->extra_colormap->rgba); - else - alpha = HWR_FogBlockAlpha(*gr_frontsector->lightlist[light].lightlevel, NORMALFOG); + alpha = HWR_FogBlockAlpha(*gr_frontsector->lightlist[light].lightlevel, rover->master->frontsector->extra_colormap); HWR_AddTransparentFloor(0, &extrasubsectors[num], @@ -3731,36 +2622,25 @@ static void HWR_Subsector(size_t num) } else if (rover->flags & FF_TRANSLUCENT && rover->alpha < 256) { - light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false); -#ifndef SORTING - HWR_Add3DWater(levelflats[*rover->toppic].lumpnum, - &extrasubsectors[num], - *rover->topheight, - *gr_frontsector->lightlist[light].lightlevel, - rover->alpha-1, rover->master->frontsector); -#else + light = R_GetPlaneLight(gr_frontsector, centerHeight, viewz < cullHeight ? true : false); HWR_AddTransparentFloor(levelflats[*rover->toppic].lumpnum, &extrasubsectors[num], true, *rover->topheight, *gr_frontsector->lightlist[light].lightlevel, - rover->alpha-1 > 255 ? 255 : rover->alpha-1, rover->master->frontsector, PF_Translucent, + rover->alpha-1 > 255 ? 255 : rover->alpha-1, rover->master->frontsector, (rover->flags & FF_RIPPLE ? PF_Ripple : 0)|PF_Translucent, false, gr_frontsector->lightlist[light].extra_colormap); -#endif - } else { - HWR_GetFlat(levelflats[*rover->toppic].lumpnum, R_NoEncore(gr_frontsector, false)); - light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false); - HWR_RenderPlane(NULL, &extrasubsectors[num], true, *rover->topheight, PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, levelflats[*rover->toppic].lumpnum, - rover->master->frontsector, 255, false, gr_frontsector->lightlist[light].extra_colormap); + HWR_GetFlat(levelflats[*rover->toppic].lumpnum, R_NoEncore(gr_frontsector, true)); + light = R_GetPlaneLight(gr_frontsector, centerHeight, viewz < cullHeight ? true : false); + HWR_RenderPlane(&extrasubsectors[num], true, *rover->topheight, (rover->flags & FF_RIPPLE ? PF_Ripple : 0)|PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, levelflats[*rover->toppic].lumpnum, + rover->master->frontsector, 255, gr_frontsector->lightlist[light].extra_colormap); } } } } -#endif -#endif //doplanes #ifdef POLYOBJECTS // Draw all the polyobjects in this subsector @@ -3829,59 +2709,8 @@ static void HWR_Subsector(size_t num) // traversing subtree recursively. // Just call with BSP root. -#ifdef coolhack -//t;b;l;r -static fixed_t hackbbox[4]; -//BOXTOP, -//BOXBOTTOM, -//BOXLEFT, -//BOXRIGHT -static boolean HWR_CheckHackBBox(fixed_t *bb) +void HWR_RenderBSPNode(INT32 bspnum) { - if (bb[BOXTOP] < hackbbox[BOXBOTTOM]) //y up - return false; - if (bb[BOXBOTTOM] > hackbbox[BOXTOP]) - return false; - if (bb[BOXLEFT] > hackbbox[BOXRIGHT]) - return false; - if (bb[BOXRIGHT] < hackbbox[BOXLEFT]) - return false; - return true; -} -#endif - -// BP: big hack for a test in lighning ref : 1249753487AB -fixed_t *hwbbox; - -static void HWR_RenderBSPNode(INT32 bspnum) -{ - /*//GZDoom code - if(bspnum == -1) - { - HWR_Subsector(subsectors); - return; - } - while(!((size_t)bspnum&(~NF_SUBSECTOR))) // Keep going until found a subsector - { - node_t *bsp = &nodes[bspnum]; - - // Decide which side the view point is on - INT32 side = R_PointOnSide(dup_viewx, dup_viewy, bsp); - - // Recursively divide front space (toward the viewer) - HWR_RenderBSPNode(bsp->children[side]); - - // Possibly divide back space (away from viewer) - side ^= 1; - - if (!HWR_CheckBBox(bsp->bbox[side])) - return; - - bspnum = bsp->children[side]; - } - - HWR_Subsector(bspnum-1); -*/ node_t *bsp = &nodes[bspnum]; // Decide which side the view point is on @@ -3890,129 +2719,20 @@ static void HWR_RenderBSPNode(INT32 bspnum) // Found a subsector? if (bspnum & NF_SUBSECTOR) { - if (bspnum == -1) - { - //*(gr_drawsubsector_p++) = 0; - HWR_Subsector(0); - } - else - { - //*(gr_drawsubsector_p++) = bspnum&(~NF_SUBSECTOR); + if (bspnum != -1) HWR_Subsector(bspnum&(~NF_SUBSECTOR)); - } return; } // Decide which side the view point is on. - side = R_PointOnSide(dup_viewx, dup_viewy, bsp); - - // BP: big hack for a test in lighning ref : 1249753487AB - hwbbox = bsp->bbox[side]; + side = R_PointOnSide(viewx, viewy, bsp); // Recursively divide front space. HWR_RenderBSPNode(bsp->children[side]); // Possibly divide back space. if (HWR_CheckBBox(bsp->bbox[side^1])) - { - // BP: big hack for a test in lighning ref : 1249753487AB - hwbbox = bsp->bbox[side^1]; HWR_RenderBSPNode(bsp->children[side^1]); - } -} - -/* -// -// Clear 'stack' of subsectors to draw -// -static void HWR_ClearDrawSubsectors(void) -{ - gr_drawsubsector_p = gr_drawsubsectors; -} - -// -// Draw subsectors pushed on the drawsubsectors 'stack', back to front -// -static void HWR_RenderSubsectors(void) -{ - while (gr_drawsubsector_p > gr_drawsubsectors) - { - HWR_RenderBSPNode( - lastsubsec->nextsubsec = bspnum & (~NF_SUBSECTOR); - } -} -*/ - -// ========================================================================== -// FROM R_MAIN.C -// ========================================================================== - -//BP : exactely the same as R_InitTextureMapping -void HWR_InitTextureMapping(void) -{ - angle_t i; - INT32 x; - INT32 t; - fixed_t focallength; - fixed_t grcenterx; - fixed_t grcenterxfrac; - INT32 grviewwidth; - -#define clipanglefov (FIELDOFVIEW>>ANGLETOFINESHIFT) - - grviewwidth = vid.width; - grcenterx = grviewwidth/2; - grcenterxfrac = grcenterx< FRACUNIT*2) - t = -1; - else if (FINETANGENT(i) < -FRACUNIT*2) - t = grviewwidth+1; - else - { - t = FixedMul(FINETANGENT(i), focallength); - t = (grcenterxfrac - t+FRACUNIT-1)>>FRACBITS; - - if (t < -1) - t = -1; - else if (t > grviewwidth+1) - t = grviewwidth+1; - } - gr_viewangletox[i] = t; - } - - // Scan viewangletox[] to generate xtoviewangle[]: - // xtoviewangle will give the smallest view angle - // that maps to x. - for (x = 0; x <= grviewwidth; x++) - { - i = 0; - while (gr_viewangletox[i]>x) - i++; - gr_xtoviewangle[x] = (i<flip) { - swallVerts[0].sow = swallVerts[3].sow = gpatch->max_s; - swallVerts[2].sow = swallVerts[1].sow = 0; + swallVerts[0].s = swallVerts[3].s = gpatch->max_s; + swallVerts[2].s = swallVerts[1].s = 0; } else { - swallVerts[0].sow = swallVerts[3].sow = 0; - swallVerts[2].sow = swallVerts[1].sow = gpatch->max_s; + swallVerts[0].s = swallVerts[3].s = 0; + swallVerts[2].s = swallVerts[1].s = gpatch->max_s; } // flip the texture coords (look familiar?) if (spr->vflip) { - swallVerts[3].tow = swallVerts[2].tow = gpatch->max_t; - swallVerts[0].tow = swallVerts[1].tow = 0; + swallVerts[3].t = swallVerts[2].t = gpatch->max_t; + swallVerts[0].t = swallVerts[1].t = 0; } else { - swallVerts[3].tow = swallVerts[2].tow = 0; - swallVerts[0].tow = swallVerts[1].tow = gpatch->max_t; + swallVerts[3].t = swallVerts[2].t = 0; + swallVerts[0].t = swallVerts[1].t = gpatch->max_t; } - sSurf.FlatColor.s.red = 0x00; - sSurf.FlatColor.s.blue = 0x00; - sSurf.FlatColor.s.green = 0x00; - - /*if (spr->mobj->frame & FF_TRANSMASK || spr->mobj->flags2 & MF2_SHADOW) - { - sector_t *sector = spr->mobj->subsector->sector; - UINT8 lightlevel = 255; - extracolormap_t *colormap = sector->extra_colormap; - - if (sector->numlights) - { - INT32 light = R_GetPlaneLight(sector, spr->mobj->floorz, false); - - if (!(spr->mobj->frame & FF_FULLBRIGHT)) - lightlevel = *sector->lightlist[light].lightlevel; - - if (sector->lightlist[light].extra_colormap) - colormap = sector->lightlist[light].extra_colormap; - } - else - { - lightlevel = sector->lightlevel; - - if (sector->extra_colormap) - colormap = sector->extra_colormap; - } - - if (colormap) - sSurf.FlatColor.rgba = HWR_Lighting(lightlevel/2, colormap->rgba, colormap->fadergba, false, true); - else - sSurf.FlatColor.rgba = HWR_Lighting(lightlevel/2, NORMALFOG, FADEFOG, false, true); - }*/ + sSurf.PolyColor.s.red = 0x00; + sSurf.PolyColor.s.blue = 0x00; + sSurf.PolyColor.s.green = 0x00; // shadow is always half as translucent as the sprite itself if (!cv_translucency.value) // use default translucency (main sprite won't have any translucency) - sSurf.FlatColor.s.alpha = 0x80; // default + sSurf.PolyColor.s.alpha = 0x80; // default else if (spr->mobj->flags2 & MF2_SHADOW) - sSurf.FlatColor.s.alpha = 0x20; + sSurf.PolyColor.s.alpha = 0x20; else if (spr->mobj->frame & FF_TRANSMASK) { HWR_TranstableToAlpha((spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &sSurf); - sSurf.FlatColor.s.alpha /= 2; //cut alpha in half! + sSurf.PolyColor.s.alpha /= 2; //cut alpha in half! } else - sSurf.FlatColor.s.alpha = 0x80; // default + sSurf.PolyColor.s.alpha = 0x80; // default - if (sSurf.FlatColor.s.alpha > floorheight/4) + if (sSurf.PolyColor.s.alpha > floorheight/4) { - sSurf.FlatColor.s.alpha = (UINT8)(sSurf.FlatColor.s.alpha - floorheight/4); - HWD.pfnDrawPolygon(&sSurf, swallVerts, 4, PF_Translucent|PF_Modulated|PF_Clip); + sSurf.PolyColor.s.alpha = (UINT8)(sSurf.PolyColor.s.alpha - floorheight/4); + HWD.pfnSetShader(1); // floor shader + HWD.pfnDrawPolygon(&sSurf, swallVerts, 4, PF_Translucent|PF_Modulated); } } // This is expecting a pointer to an array containing 4 wallVerts for a sprite static void HWR_RotateSpritePolyToAim(gr_vissprite_t *spr, FOutVector *wallVerts) { - if (cv_grspritebillboarding.value - && spr && spr->mobj && !(spr->mobj->frame & FF_PAPERSPRITE) - && wallVerts) + if (cv_grspritebillboarding.value && spr && spr->mobj && !(spr->mobj->frame & FF_PAPERSPRITE) && wallVerts) { float basey = FIXED_TO_FLOAT(spr->mobj->z); float lowy = wallVerts[0].y; @@ -4384,10 +3073,6 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) if (cv_shadow.value // Shadows enabled && (spr->mobj->flags & (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY)) != (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY) // Ceiling scenery have no shadow. && !(spr->mobj->flags2 & MF2_DEBRIS) // Debris have no corona or shadow. -#ifdef ALAM_LIGHTING - && !(t_lspr[spr->mobj->sprite]->type // Things with dynamic lights have no shadow. - && (!spr->mobj->player || spr->mobj->player->powers[pw_super])) // Except for non-super players. -#endif && (spr->mobj->z >= spr->mobj->floorz)) // Without this, your shadow shows on the floor, even after you die and fall through the ground. { //////////////////// @@ -4414,44 +3099,46 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) if (spr->flip) { - baseWallVerts[0].sow = baseWallVerts[3].sow = gpatch->max_s; - baseWallVerts[2].sow = baseWallVerts[1].sow = 0; + baseWallVerts[0].s = baseWallVerts[3].s = gpatch->max_s; + baseWallVerts[2].s = baseWallVerts[1].s = 0; } else { - baseWallVerts[0].sow = baseWallVerts[3].sow = 0; - baseWallVerts[2].sow = baseWallVerts[1].sow = gpatch->max_s; + baseWallVerts[0].s = baseWallVerts[3].s = 0; + baseWallVerts[2].s = baseWallVerts[1].s = gpatch->max_s; } // flip the texture coords (look familiar?) if (spr->vflip) { - baseWallVerts[3].tow = baseWallVerts[2].tow = gpatch->max_t; - baseWallVerts[0].tow = baseWallVerts[1].tow = 0; + baseWallVerts[3].t = baseWallVerts[2].t = gpatch->max_t; + baseWallVerts[0].t = baseWallVerts[1].t = 0; } else { - baseWallVerts[3].tow = baseWallVerts[2].tow = 0; - baseWallVerts[0].tow = baseWallVerts[1].tow = gpatch->max_t; - } - - // if it has a dispoffset, push it a little towards the camera - if (spr->dispoffset) { - float co = -gr_viewcos*(0.05f*spr->dispoffset); - float si = -gr_viewsin*(0.05f*spr->dispoffset); - baseWallVerts[0].z = baseWallVerts[3].z = baseWallVerts[0].z+si; - baseWallVerts[1].z = baseWallVerts[2].z = baseWallVerts[1].z+si; - baseWallVerts[0].x = baseWallVerts[3].x = baseWallVerts[0].x+co; - baseWallVerts[1].x = baseWallVerts[2].x = baseWallVerts[1].x+co; + baseWallVerts[3].t = baseWallVerts[2].t = 0; + baseWallVerts[0].t = baseWallVerts[1].t = gpatch->max_t; } // Let dispoffset work first since this adjust each vertex HWR_RotateSpritePolyToAim(spr, baseWallVerts); + // push it toward the camera to mitigate floor-clipping sprites + { + float sprdist = sqrtf((spr->x1 - gr_viewx)*(spr->x1 - gr_viewx) + (spr->z1 - gr_viewy)*(spr->z1 - gr_viewy) + (spr->ty - gr_viewz)*(spr->ty - gr_viewz)); + float distfact = ((2.0f*spr->dispoffset) + 20.0f) / sprdist; + for (i = 0; i < 4; i++) + { + baseWallVerts[i].x += (gr_viewx - baseWallVerts[i].x)*distfact; + baseWallVerts[i].z += (gr_viewy - baseWallVerts[i].z)*distfact; + baseWallVerts[i].y += (gr_viewz - baseWallVerts[i].y)*distfact; + } + } + realtop = top = baseWallVerts[3].y; realbot = bot = baseWallVerts[0].y; - towtop = baseWallVerts[3].tow; - towbot = baseWallVerts[0].tow; + towtop = baseWallVerts[3].t; + towbot = baseWallVerts[0].t; towmult = (towbot - towtop) / (top - bot); #ifdef ESLOPE @@ -4466,12 +3153,12 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) if (!cv_translucency.value) // translucency disabled { - Surf.FlatColor.s.alpha = 0xFF; + Surf.PolyColor.s.alpha = 0xFF; blend = PF_Translucent|PF_Occlude; } else if (spr->mobj->flags2 & MF2_SHADOW) { - Surf.FlatColor.s.alpha = 0x40; + Surf.PolyColor.s.alpha = 0x40; blend = PF_Translucent; } else if (spr->mobj->frame & FF_TRANSMASK) @@ -4482,11 +3169,11 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) // work properly under glide nor with fogcolor to ffffff :( // Hurdler: PF_Environement would be cool, but we need to fix // the issue with the fog before - Surf.FlatColor.s.alpha = 0xFF; + Surf.PolyColor.s.alpha = 0xFF; blend = PF_Translucent|PF_Occlude; } - alpha = Surf.FlatColor.s.alpha; + alpha = Surf.PolyColor.s.alpha; // Start with the lightlevel and colormap from the top of the sprite lightlevel = *list[sector->numlights - 1].lightlevel; @@ -4581,10 +3268,10 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) #endif #ifdef ESLOPE - wallVerts[3].tow = towtop + ((realtop - top) * towmult); - wallVerts[2].tow = towtop + ((endrealtop - endtop) * towmult); - wallVerts[0].tow = towtop + ((realtop - bot) * towmult); - wallVerts[1].tow = towtop + ((endrealtop - endbot) * towmult); + wallVerts[3].t = towtop + ((realtop - top) * towmult); + wallVerts[2].t = towtop + ((endrealtop - endtop) * towmult); + wallVerts[0].t = towtop + ((realtop - bot) * towmult); + wallVerts[1].t = towtop + ((endrealtop - endbot) * towmult); wallVerts[3].y = top; wallVerts[2].y = endtop; @@ -4592,8 +3279,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) wallVerts[1].y = endbot; // The x and y only need to be adjusted in the case that it's not a papersprite - if (cv_grspritebillboarding.value - && spr->mobj && !(spr->mobj->frame & FF_PAPERSPRITE)) + if (cv_grspritebillboarding.value && spr->mobj && !(spr->mobj->frame & FF_PAPERSPRITE)) { // Get the x and z of the vertices so billboarding draws correctly realheight = realbot - realtop; @@ -4615,15 +3301,14 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) wallVerts[1].z = baseWallVerts[2].z + (baseWallVerts[2].z - baseWallVerts[1].z) * heightmult; } #else - wallVerts[3].tow = wallVerts[2].tow = towtop + ((realtop - top) * towmult); - wallVerts[0].tow = wallVerts[1].tow = towtop + ((realtop - bot) * towmult); + wallVerts[3].t = wallVerts[2].t = towtop + ((realtop - top) * towmult); + wallVerts[0].t = wallVerts[1].t = towtop + ((realtop - bot) * towmult); wallVerts[2].y = wallVerts[3].y = top; wallVerts[0].y = wallVerts[1].y = bot; // The x and y only need to be adjusted in the case that it's not a papersprite - if (cv_grspritebillboarding.value - && spr->mobj && !(spr->mobj->frame & FF_PAPERSPRITE)) + if (cv_grspritebillboarding.value && spr->mobj && !(spr->mobj->frame & FF_PAPERSPRITE)) { // Get the x and z of the vertices so billboarding draws correctly realheight = realbot - realtop; @@ -4641,14 +3326,12 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) } #endif - if (colormap) - Surf.FlatColor.rgba = HWR_Lighting(lightlevel, colormap->rgba, colormap->fadergba, false, false); - else - Surf.FlatColor.rgba = HWR_Lighting(lightlevel, NORMALFOG, FADEFOG, false, false); + HWR_Lighting(&Surf, lightlevel, colormap); - Surf.FlatColor.s.alpha = alpha; + Surf.PolyColor.s.alpha = alpha; - HWD.pfnDrawPolygon(&Surf, wallVerts, 4, blend|PF_Modulated|PF_Clip); + HWD.pfnSetShader(3); // sprite shader + HWD.pfnDrawPolygon(&Surf, wallVerts, 4, blend|PF_Modulated); top = bot; #ifdef ESLOPE @@ -4666,31 +3349,29 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) // If we're ever down here, somehow the above loop hasn't draw all the light levels of sprite #ifdef ESLOPE - wallVerts[3].tow = towtop + ((realtop - top) * towmult); - wallVerts[2].tow = towtop + ((endrealtop - endtop) * towmult); - wallVerts[0].tow = towtop + ((realtop - bot) * towmult); - wallVerts[1].tow = towtop + ((endrealtop - endbot) * towmult); + wallVerts[3].t = towtop + ((realtop - top) * towmult); + wallVerts[2].t = towtop + ((endrealtop - endtop) * towmult); + wallVerts[0].t = towtop + ((realtop - bot) * towmult); + wallVerts[1].t = towtop + ((endrealtop - endbot) * towmult); wallVerts[3].y = top; wallVerts[2].y = endtop; wallVerts[0].y = bot; wallVerts[1].y = endbot; #else - wallVerts[3].tow = wallVerts[2].tow = towtop + ((realtop - top) * towmult); - wallVerts[0].tow = wallVerts[1].tow = towtop + ((realtop - bot) * towmult); + wallVerts[3].t = wallVerts[2].t = towtop + ((realtop - top) * towmult); + wallVerts[0].t = wallVerts[1].t = towtop + ((realtop - bot) * towmult); wallVerts[2].y = wallVerts[3].y = top; wallVerts[0].y = wallVerts[1].y = bot; #endif - if (colormap) - Surf.FlatColor.rgba = HWR_Lighting(lightlevel, colormap->rgba, colormap->fadergba, false, false); - else - Surf.FlatColor.rgba = HWR_Lighting(lightlevel, NORMALFOG, FADEFOG, false, false); + HWR_Lighting(&Surf, lightlevel, colormap); - Surf.FlatColor.s.alpha = alpha; + Surf.PolyColor.s.alpha = alpha; - HWD.pfnDrawPolygon(&Surf, wallVerts, 4, blend|PF_Modulated|PF_Clip); + HWD.pfnSetShader(3); // sprite shader + HWD.pfnDrawPolygon(&Surf, wallVerts, 4, blend|PF_Modulated); } // -----------------+ @@ -4705,7 +3386,6 @@ static void HWR_DrawSprite(gr_vissprite_t *spr) GLPatch_t *gpatch; // sprite patch converted to hardware FSurfaceInfo Surf; const boolean hires = (spr->mobj && spr->mobj->skin && ((skin_t *)spr->mobj->skin)->flags & SF_HIRES); - //const boolean papersprite = (spr->mobj && (spr->mobj->frame & FF_PAPERSPRITE)); if (spr->mobj) this_scale = FIXED_TO_FLOAT(spr->mobj->scale); if (hires) @@ -4731,12 +3411,6 @@ static void HWR_DrawSprite(gr_vissprite_t *spr) gpatch = W_CachePatchNum(spr->patchlumpnum, PU_CACHE); -#ifdef ALAM_LIGHTING - if (!(spr->mobj->flags2 & MF2_DEBRIS) && (spr->mobj->sprite != SPR_PLAY || - (spr->mobj->player && spr->mobj->player->powers[pw_super]))) - HWR_DL_AddLight(spr, gpatch); -#endif - // create the sprite billboard // // 3--2 @@ -4760,21 +3434,21 @@ static void HWR_DrawSprite(gr_vissprite_t *spr) if (spr->flip) { - wallVerts[0].sow = wallVerts[3].sow = gpatch->max_s; - wallVerts[2].sow = wallVerts[1].sow = 0; + wallVerts[0].s = wallVerts[3].s = gpatch->max_s; + wallVerts[2].s = wallVerts[1].s = 0; }else{ - wallVerts[0].sow = wallVerts[3].sow = 0; - wallVerts[2].sow = wallVerts[1].sow = gpatch->max_s; + wallVerts[0].s = wallVerts[3].s = 0; + wallVerts[2].s = wallVerts[1].s = gpatch->max_s; } // flip the texture coords (look familiar?) if (spr->vflip) { - wallVerts[3].tow = wallVerts[2].tow = gpatch->max_t; - wallVerts[0].tow = wallVerts[1].tow = 0; + wallVerts[3].t = wallVerts[2].t = gpatch->max_t; + wallVerts[0].t = wallVerts[1].t = 0; }else{ - wallVerts[3].tow = wallVerts[2].tow = 0; - wallVerts[0].tow = wallVerts[1].tow = gpatch->max_t; + wallVerts[3].t = wallVerts[2].t = 0; + wallVerts[0].t = wallVerts[1].t = gpatch->max_t; } // cache the patch in the graphics card memory @@ -4786,10 +3460,6 @@ static void HWR_DrawSprite(gr_vissprite_t *spr) if (cv_shadow.value // Shadows enabled && (spr->mobj->flags & (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY)) != (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY) // Ceiling scenery have no shadow. && !(spr->mobj->flags2 & MF2_DEBRIS) // Debris have no corona or shadow. -#ifdef ALAM_LIGHTING - && !(t_lspr[spr->mobj->sprite]->type // Things with dynamic lights have no shadow. - && (!spr->mobj->player || spr->mobj->player->powers[pw_super])) // Except for non-super players. -#endif && (spr->mobj->z >= spr->mobj->floorz)) // Without this, your shadow shows on the floor, even after you die and fall through the ground. { //////////////////// @@ -4798,19 +3468,23 @@ static void HWR_DrawSprite(gr_vissprite_t *spr) HWR_DrawSpriteShadow(spr, gpatch, this_scale); } - // if it has a dispoffset, push it a little towards the camera - if (spr->dispoffset) { - float co = -gr_viewcos*(0.05f*spr->dispoffset); - float si = -gr_viewsin*(0.05f*spr->dispoffset); - wallVerts[0].z = wallVerts[3].z = wallVerts[0].z+si; - wallVerts[1].z = wallVerts[2].z = wallVerts[1].z+si; - wallVerts[0].x = wallVerts[3].x = wallVerts[0].x+co; - wallVerts[1].x = wallVerts[2].x = wallVerts[1].x+co; - } - // Let dispoffset work first since this adjust each vertex + // ...nah HWR_RotateSpritePolyToAim(spr, wallVerts); + // push it toward the camera to mitigate floor-clipping sprites + { + float sprdist = sqrtf((spr->x1 - gr_viewx)*(spr->x1 - gr_viewx) + (spr->z1 - gr_viewy)*(spr->z1 - gr_viewy) + (spr->ty - gr_viewz)*(spr->ty - gr_viewz)); + float distfact = ((2.0f*spr->dispoffset) + 20.0f) / sprdist; + size_t i; + for (i = 0; i < 4; i++) + { + wallVerts[i].x += (gr_viewx - wallVerts[i].x)*distfact; + wallVerts[i].z += (gr_viewy - wallVerts[i].z)*distfact; + wallVerts[i].y += (gr_viewz - wallVerts[i].y)*distfact; + } + } + // This needs to be AFTER the shadows so that the regular sprites aren't drawn completely black. // sprite lighting by modulating the RGB components /// \todo coloured @@ -4824,22 +3498,19 @@ static void HWR_DrawSprite(gr_vissprite_t *spr) if (!(spr->mobj->frame & FF_FULLBRIGHT)) lightlevel = sector->lightlevel; - if (colormap) - Surf.FlatColor.rgba = HWR_Lighting(lightlevel, colormap->rgba, colormap->fadergba, false, false); - else - Surf.FlatColor.rgba = HWR_Lighting(lightlevel, NORMALFOG, FADEFOG, false, false); + HWR_Lighting(&Surf, lightlevel, colormap); } { FBITFIELD blend = 0; if (!cv_translucency.value) // translucency disabled { - Surf.FlatColor.s.alpha = 0xFF; + Surf.PolyColor.s.alpha = 0xFF; blend = PF_Translucent|PF_Occlude; } else if (spr->mobj->flags2 & MF2_SHADOW) { - Surf.FlatColor.s.alpha = 0x40; + Surf.PolyColor.s.alpha = 0x40; blend = PF_Translucent; } else if (spr->mobj->frame & FF_TRANSMASK) @@ -4850,15 +3521,15 @@ static void HWR_DrawSprite(gr_vissprite_t *spr) // work properly under glide nor with fogcolor to ffffff :( // Hurdler: PF_Environement would be cool, but we need to fix // the issue with the fog before - Surf.FlatColor.s.alpha = 0xFF; + Surf.PolyColor.s.alpha = 0xFF; blend = PF_Translucent|PF_Occlude; } - HWD.pfnDrawPolygon(&Surf, wallVerts, 4, blend|PF_Modulated|PF_Clip); + HWD.pfnSetShader(3); // sprite shader + HWD.pfnDrawPolygon(&Surf, wallVerts, 4, blend|PF_Modulated); } } -#ifdef HWPRECIP // Sprite drawer for precipitation static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr) { @@ -4895,11 +3566,11 @@ static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr) // Let dispoffset work first since this adjust each vertex HWR_RotateSpritePolyToAim(spr, wallVerts); - wallVerts[0].sow = wallVerts[3].sow = 0; - wallVerts[2].sow = wallVerts[1].sow = gpatch->max_s; + wallVerts[0].s = wallVerts[3].s = 0; + wallVerts[2].s = wallVerts[1].s = gpatch->max_s; - wallVerts[3].tow = wallVerts[2].tow = 0; - wallVerts[0].tow = wallVerts[1].tow = gpatch->max_t; + wallVerts[3].t = wallVerts[2].t = 0; + wallVerts[0].t = wallVerts[1].t = gpatch->max_t; // cache the patch in the graphics card memory //12/12/99: Hurdler: same comment as above (for md2) @@ -4933,15 +3604,12 @@ static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr) colormap = sector->extra_colormap; } - if (colormap) - Surf.FlatColor.rgba = HWR_Lighting(lightlevel, colormap->rgba, colormap->fadergba, false, false); - else - Surf.FlatColor.rgba = HWR_Lighting(lightlevel, NORMALFOG, FADEFOG, false, false); + HWR_Lighting(&Surf, lightlevel, colormap); } if (spr->mobj->flags2 & MF2_SHADOW) { - Surf.FlatColor.s.alpha = 0x40; + Surf.PolyColor.s.alpha = 0x40; blend = PF_Translucent; } else if (spr->mobj->frame & FF_TRANSMASK) @@ -4952,121 +3620,66 @@ static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr) // work properly under glide nor with fogcolor to ffffff :( // Hurdler: PF_Environement would be cool, but we need to fix // the issue with the fog before - Surf.FlatColor.s.alpha = 0xFF; + Surf.PolyColor.s.alpha = 0xFF; blend = PF_Translucent|PF_Occlude; } - HWD.pfnDrawPolygon(&Surf, wallVerts, 4, blend|PF_Modulated|PF_Clip); + HWD.pfnSetShader(3); // sprite shader + HWD.pfnDrawPolygon(&Surf, wallVerts, 4, blend|PF_Modulated); } -#endif // -------------------------------------------------------------------------- // Sort vissprites by distance // -------------------------------------------------------------------------- -static gr_vissprite_t gr_vsprsortedhead; + +gr_vissprite_t* gr_vsprorder[MAXVISSPRITES]; + +// For more correct transparency the transparent sprites would need to be +// sorted and drawn together with transparent surfaces. +static int CompareVisSprites(const void *p1, const void *p2) +{ + gr_vissprite_t* spr1 = *(gr_vissprite_t*const*)p1; + gr_vissprite_t* spr2 = *(gr_vissprite_t*const*)p2; + int idiff; + float fdiff; + + // make transparent sprites last + // "boolean to int" + + int transparency1 = (spr1->mobj->flags2 & MF2_SHADOW) || (spr1->mobj->frame & FF_TRANSMASK); + int transparency2 = (spr2->mobj->flags2 & MF2_SHADOW) || (spr2->mobj->frame & FF_TRANSMASK); + idiff = transparency1 - transparency2; + if (idiff != 0) return idiff; + + fdiff = spr2->tz - spr1->tz;// this order seems correct when checking with apitrace. Back to front. + if (fabsf(fdiff) < 1.0E-36f) + return spr1->dispoffset - spr2->dispoffset;// smallest dispoffset first if sprites are at (almost) same location. + else if (fdiff > 0) + return 1; + else + return -1; +} + static void HWR_SortVisSprites(void) { UINT32 i; - gr_vissprite_t *ds, *dsprev, *dsnext, *dsfirst; - gr_vissprite_t *best = NULL; - gr_vissprite_t unsorted; - float bestdist = 0.0f; - INT32 bestdispoffset = 0; - - if (!gr_visspritecount) - return; - - dsfirst = HWR_GetVisSprite(0); - - for (i = 0, dsnext = dsfirst, ds = NULL; i < gr_visspritecount; i++) - { - dsprev = ds; - ds = dsnext; - if (i < gr_visspritecount - 1) dsnext = HWR_GetVisSprite(i + 1); - - ds->next = dsnext; - ds->prev = dsprev; - } - - // Fix first and last. ds still points to the last one after the loop - dsfirst->prev = &unsorted; - unsorted.next = dsfirst; - if (ds) - ds->next = &unsorted; - unsorted.prev = ds; - - // pull the vissprites out by scale - gr_vsprsortedhead.next = gr_vsprsortedhead.prev = &gr_vsprsortedhead; for (i = 0; i < gr_visspritecount; i++) { - best = NULL; - for (ds = unsorted.next; ds != &unsorted; ds = ds->next) - { - if (!best || ds->tz > bestdist) - { - bestdist = ds->tz; - bestdispoffset = ds->dispoffset; - best = ds; - } - // order visprites of same scale by dispoffset, smallest first - else if (fabsf(ds->tz - bestdist) < 1.0E-36f && ds->dispoffset < bestdispoffset) - { - bestdispoffset = ds->dispoffset; - best = ds; - } - } - if (best) - { - best->next->prev = best->prev; - best->prev->next = best->next; - best->next = &gr_vsprsortedhead; - best->prev = gr_vsprsortedhead.prev; - } - gr_vsprsortedhead.prev->next = best; - gr_vsprsortedhead.prev = best; - } - - // Sryder: Oh boy, while it's nice having ALL the sprites sorted properly, it fails when we bring MD2's into the - // mix and they want to be translucent. So let's place all the translucent sprites and MD2's AFTER - // everything else, but still ordered of course, the depth buffer can handle the opaque ones plenty fine. - // We just need to move all translucent ones to the end in order - // TODO: Fully sort all sprites and MD2s with walls and floors, this part will be unnecessary after that - best = gr_vsprsortedhead.next; - for (i = 0; i < gr_visspritecount; i++) - { - if ((best->mobj->flags2 & MF2_SHADOW) || (best->mobj->frame & FF_TRANSMASK)) - { - if (best == gr_vsprsortedhead.next) - { - gr_vsprsortedhead.next = best->next; - } - best->prev->next = best->next; - best->next->prev = best->prev; - best->prev = gr_vsprsortedhead.prev; - gr_vsprsortedhead.prev->next = best; - gr_vsprsortedhead.prev = best; - ds = best; - best = best->next; - ds->next = &gr_vsprsortedhead; - } - else - best = best->next; + gr_vsprorder[i] = HWR_GetVisSprite(i); } + qsort(gr_vsprorder, gr_visspritecount, sizeof(gr_vissprite_t*), CompareVisSprites); } // A drawnode is something that points to a 3D floor, 3D side, or masked // middle texture. This is used for sorting with sprites. typedef struct { - wallVert3D wallVerts[4]; + FOutVector wallVerts[4]; FSurfaceInfo Surf; INT32 texnum; FBITFIELD blend; INT32 drawcount; -#ifndef SORTING - fixed_t fixedheight; -#endif boolean fogwall; INT32 lightlevel; extracolormap_t *wallcolormap; // Doing the lighting in HWR_RenderWall now for correct fog after sorting @@ -5075,10 +3688,6 @@ typedef struct static wallinfo_t *wallinfo = NULL; static size_t numwalls = 0; // a list of transparent walls to be drawn -static void HWR_RenderWall(wallVert3D *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blend, boolean fogwall, INT32 lightlevel, extracolormap_t *wallcolormap); - -#define MAX_TRANSPARENTWALL 256 - typedef struct { extrasubsector_t *xsub; @@ -5114,30 +3723,19 @@ typedef struct static size_t numpolyplanes = 0; // a list of transparent poyobject floors to be drawn static polyplaneinfo_t *polyplaneinfo = NULL; -#ifndef SORTING -size_t numfloors = 0; -#else -//static floorinfo_t *floorinfo = NULL; -//static size_t numfloors = 0; -//Hurdler: 3D water sutffs typedef struct gr_drawnode_s { planeinfo_t *plane; polyplaneinfo_t *polyplane; wallinfo_t *wall; gr_vissprite_t *sprite; - -// struct gr_drawnode_s *next; -// struct gr_drawnode_s *prev; } gr_drawnode_t; -static INT32 drawcount = 0; - +#define MAX_TRANSPARENTWALL 256 #define MAX_TRANSPARENTFLOOR 512 // This will likely turn into a copy of HWR_Add3DWater and replace it. -void HWR_AddTransparentFloor(lumpnum_t lumpnum, extrasubsector_t *xsub, boolean isceiling, - fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, extracolormap_t *planecolormap) +void HWR_AddTransparentFloor(lumpnum_t lumpnum, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, extracolormap_t *planecolormap) { static size_t allocedplanes = 0; @@ -5168,8 +3766,7 @@ void HWR_AddTransparentFloor(lumpnum_t lumpnum, extrasubsector_t *xsub, boolean // Adding this for now until I can create extrasubsector info for polyobjects // When that happens it'll just be done through HWR_AddTransparentFloor and HWR_RenderPlane -void HWR_AddTransparentPolyobjectFloor(lumpnum_t lumpnum, polyobj_t *polysector, boolean isceiling, - fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, extracolormap_t *planecolormap) +void HWR_AddTransparentPolyobjectFloor(lumpnum_t lumpnum, polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, extracolormap_t *planecolormap) { static size_t allocedpolyplanes = 0; @@ -5196,28 +3793,65 @@ void HWR_AddTransparentPolyobjectFloor(lumpnum_t lumpnum, polyobj_t *polysector, numpolyplanes++; } -// -// HWR_CreateDrawNodes -// Creates and sorts a list of drawnodes for the scene being rendered. -static void HWR_CreateDrawNodes(void) +// putting sortindex and sortnode here so the comparator function can see them +gr_drawnode_t *sortnode; +size_t *sortindex; + +static int CompareDrawNodes(const void *p1, const void *p2) { - UINT32 i = 0, p = 0, prev = 0, loop; - const fixed_t pviewz = dup_viewz; + size_t n1 = *(const size_t*)p1; + size_t n2 = *(const size_t*)p2; + INT32 v1 = 0; + INT32 v2 = 0; + INT32 diff; + if (sortnode[n1].plane) + v1 = sortnode[n1].plane->drawcount; + else if (sortnode[n1].polyplane) + v1 = sortnode[n1].polyplane->drawcount; + else if (sortnode[n1].wall) + v1 = sortnode[n1].wall->drawcount; + else I_Error("n1 unknown"); + + if (sortnode[n2].plane) + v2 = sortnode[n2].plane->drawcount; + else if (sortnode[n2].polyplane) + v2 = sortnode[n2].polyplane->drawcount; + else if (sortnode[n2].wall) + v2 = sortnode[n2].wall->drawcount; + else I_Error("n2 unknown"); + + diff = v2 - v1; + if (diff == 0) I_Error("diff is zero"); + return diff; +} + +static int CompareDrawNodePlanes(const void *p1, const void *p2) +{ + size_t n1 = *(const size_t*)p1; + size_t n2 = *(const size_t*)p2; + if (!sortnode[n1].plane) I_Error("Uh.. This isn't a plane! (n1)"); + if (!sortnode[n2].plane) I_Error("Uh.. This isn't a plane! (n2)"); + return ABS(sortnode[n2].plane->fixedheight - viewz) - ABS(sortnode[n1].plane->fixedheight - viewz); +} + +// HWR_RenderDrawNodes +// Creates, sorts and renders a list of drawnodes for the current frame. +void HWR_RenderDrawNodes(void) +{ + UINT32 i = 0, p = 0; + size_t run_start = 0; // Dump EVERYTHING into a huge drawnode list. Then we'll sort it! // Could this be optimized into _AddTransparentWall/_AddTransparentPlane? // Hell yes! But sort algorithm must be modified to use a linked list. - gr_drawnode_t *sortnode = Z_Calloc((sizeof(planeinfo_t)*numplanes) + sortnode = Z_Calloc((sizeof(planeinfo_t)*numplanes) + (sizeof(polyplaneinfo_t)*numpolyplanes) + (sizeof(wallinfo_t)*numwalls) ,PU_STATIC, NULL); // todo: // However, in reality we shouldn't be re-copying and shifting all this information // that is already lying around. This should all be in some sort of linked list or lists. - size_t *sortindex = Z_Calloc(sizeof(size_t) * (numplanes + numpolyplanes + numwalls), PU_STATIC, NULL); - - // If true, swap the draw order. - boolean shift = false; + sortindex = Z_Calloc(sizeof(size_t) * (numplanes + numpolyplanes + numwalls), PU_STATIC, NULL); for (i = 0; i < numplanes; i++, p++) { @@ -5244,102 +3878,45 @@ static void HWR_CreateDrawNodes(void) // through the lists of masked textures and // translucent ffloors being drawn. - // This is a bubble sort! Wahoo! + // im not sure if this sort on the next line is needed. + // it sorts the list based on the value of the 'drawcount' member of the drawnodes. + // im thinking the list might already be in that order, but i havent bothered to check yet. + // anyway doing this sort does not hurt and does not take much time. + // the while loop after this sort is important however! + qsort(sortindex, p, sizeof(size_t), CompareDrawNodes); - // Stuff is sorted: - // sortnode[sortindex[0]] = farthest away - // sortnode[sortindex[p-1]] = closest - // "i" should be closer. "prev" should be further. - // The lower drawcount is, the further it is from the screen. - - for (loop = 0; loop < p; loop++) + // try solving floor order here. for each consecutive run of floors in the list, sort that run. + while (run_start < p-1)// p-1 because a 1 plane run at the end of the list does not count { - for (i = 1; i < p; i++) + // locate run start + if (sortnode[sortindex[run_start]].plane) { - prev = i-1; - if (sortnode[sortindex[i]].plane) + // found it, now look for run end + size_t run_end;// (inclusive) + for (i = run_start+1; i < p; i++)// size_t and UINT32 being used mixed here... shouldnt break anything though.. { - // What are we comparing it with? - if (sortnode[sortindex[prev]].plane) - { - // Plane (i) is further away than plane (prev) - if (ABS(sortnode[sortindex[i]].plane->fixedheight - pviewz) > ABS(sortnode[sortindex[prev]].plane->fixedheight - pviewz)) - shift = true; - } - if (sortnode[sortindex[prev]].polyplane) - { - // Plane (i) is further away than polyplane (prev) - if (ABS(sortnode[sortindex[i]].plane->fixedheight - pviewz) > ABS(sortnode[sortindex[prev]].polyplane->fixedheight - pviewz)) - shift = true; - } - else if (sortnode[sortindex[prev]].wall) - { - // Plane (i) is further than wall (prev) - if (sortnode[sortindex[i]].plane->drawcount > sortnode[sortindex[prev]].wall->drawcount) - shift = true; - } + if (!sortnode[sortindex[i]].plane) break; } - else if (sortnode[sortindex[i]].polyplane) + run_end = i-1; + if (run_end > run_start)// if there are multiple consecutive planes, not just one { - // What are we comparing it with? - if (sortnode[sortindex[prev]].plane) - { - // Plane (i) is further away than plane (prev) - if (ABS(sortnode[sortindex[i]].polyplane->fixedheight - pviewz) > ABS(sortnode[sortindex[prev]].plane->fixedheight - pviewz)) - shift = true; - } - if (sortnode[sortindex[prev]].polyplane) - { - // Plane (i) is further away than polyplane (prev) - if (ABS(sortnode[sortindex[i]].polyplane->fixedheight - pviewz) > ABS(sortnode[sortindex[prev]].polyplane->fixedheight - pviewz)) - shift = true; - } - else if (sortnode[sortindex[prev]].wall) - { - // Plane (i) is further than wall (prev) - if (sortnode[sortindex[i]].polyplane->drawcount > sortnode[sortindex[prev]].wall->drawcount) - shift = true; - } - } - else if (sortnode[sortindex[i]].wall) - { - // What are we comparing it with? - if (sortnode[sortindex[prev]].plane) - { - // Wall (i) is further than plane(prev) - if (sortnode[sortindex[i]].wall->drawcount > sortnode[sortindex[prev]].plane->drawcount) - shift = true; - } - if (sortnode[sortindex[prev]].polyplane) - { - // Wall (i) is further than polyplane(prev) - if (sortnode[sortindex[i]].wall->drawcount > sortnode[sortindex[prev]].polyplane->drawcount) - shift = true; - } - else if (sortnode[sortindex[prev]].wall) - { - // Wall (i) is further than wall (prev) - if (sortnode[sortindex[i]].wall->drawcount > sortnode[sortindex[prev]].wall->drawcount) - shift = true; - } + // consecutive run of planes found, now sort it + // not sure how long these runs can be in reality... + qsort(sortindex + run_start, run_end - run_start + 1, sizeof(size_t), CompareDrawNodePlanes); } + run_start = run_end + 1;// continue looking for runs coming right after this one + } + else + { + // this wasnt the run start, try next one + run_start++; + } + } - if (shift) - { - size_t temp; - - temp = sortindex[prev]; - sortindex[prev] = sortindex[i]; - sortindex[i] = temp; - - shift = false; - } - - } //i++ - } // loop++ - - HWD.pfnSetTransform(&atransform); // Okay! Let's draw it all! Woo! + HWD.pfnSetTransform(&atransform); + HWD.pfnSetShader(0); + for (i = 0; i < p; i++) { if (sortnode[sortindex[i]].plane) @@ -5349,8 +3926,8 @@ static void HWR_CreateDrawNodes(void) if (!(sortnode[sortindex[i]].plane->blend & PF_NoTexture)) HWR_GetFlat(sortnode[sortindex[i]].plane->lumpnum, R_NoEncore(sortnode[sortindex[i]].plane->FOFSector, sortnode[sortindex[i]].plane->isceiling)); - HWR_RenderPlane(NULL, sortnode[sortindex[i]].plane->xsub, sortnode[sortindex[i]].plane->isceiling, sortnode[sortindex[i]].plane->fixedheight, sortnode[sortindex[i]].plane->blend, sortnode[sortindex[i]].plane->lightlevel, - sortnode[sortindex[i]].plane->lumpnum, sortnode[sortindex[i]].plane->FOFSector, sortnode[sortindex[i]].plane->alpha, sortnode[sortindex[i]].plane->fogplane, sortnode[sortindex[i]].plane->planecolormap); + HWR_RenderPlane(sortnode[sortindex[i]].plane->xsub, sortnode[sortindex[i]].plane->isceiling, sortnode[sortindex[i]].plane->fixedheight, sortnode[sortindex[i]].plane->blend, sortnode[sortindex[i]].plane->lightlevel, + sortnode[sortindex[i]].plane->lumpnum, sortnode[sortindex[i]].plane->FOFSector, sortnode[sortindex[i]].plane->alpha, /*sortnode[sortindex[i]].plane->fogplane,*/ sortnode[sortindex[i]].plane->planecolormap); } else if (sortnode[sortindex[i]].polyplane) { @@ -5380,60 +3957,44 @@ static void HWR_CreateDrawNodes(void) Z_Free(sortindex); } -#endif - // -------------------------------------------------------------------------- // Draw all vissprites // -------------------------------------------------------------------------- -#ifdef SORTING -// added the stransform so they can be switched as drawing happenes so MD2s and sprites are sorted correctly with each other -static void HWR_DrawSprites(void) +void HWR_DrawSprites(void) { - if (gr_visspritecount > 0) + UINT32 i; + for (i = 0; i < gr_visspritecount; i++) { - gr_vissprite_t *spr; - - // draw all vissprites back to front - for (spr = gr_vsprsortedhead.next; - spr != &gr_vsprsortedhead; - spr = spr->next) - { -#ifdef HWPRECIP - if (spr->precip) - HWR_DrawPrecipitationSprite(spr); - else -#endif - if (spr->mobj && spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) - { - // 8/1/19: Only don't display player models if no default SPR_PLAY is found. - if (!cv_grmdls.value || ((md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound || md2_playermodels[(skin_t*)spr->mobj->skin-skins].scale < 0.0f) && ((!cv_grfallbackplayermodel.value) || md2_models[SPR_PLAY].notfound || md2_models[SPR_PLAY].scale < 0.0f))) - HWR_DrawSprite(spr); - else - HWR_DrawMD2(spr); - } + gr_vissprite_t *spr = gr_vsprorder[i]; + if (spr->precip) + HWR_DrawPrecipitationSprite(spr); + else + if (spr->mobj && spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) + { + // 8/1/19: Only don't display player models if no default SPR_PLAY is found. + if (!cv_grmdls.value || ((md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound || md2_playermodels[(skin_t*)spr->mobj->skin-skins].scale < 0.0f) && ((!cv_grfallbackplayermodel.value) || md2_models[SPR_PLAY].notfound || md2_models[SPR_PLAY].scale < 0.0f))) + HWR_DrawSprite(spr); else - { - if (!cv_grmdls.value || md2_models[spr->mobj->sprite].notfound || md2_models[spr->mobj->sprite].scale < 0.0f) - HWR_DrawSprite(spr); - else - HWR_DrawMD2(spr); - } - } + HWR_DrawMD2(spr); + } + else + { + if (!cv_grmdls.value || md2_models[spr->mobj->sprite].notfound || md2_models[spr->mobj->sprite].scale < 0.0f) + HWR_DrawSprite(spr); + else + HWR_DrawMD2(spr); + } } } -#endif // -------------------------------------------------------------------------- // HWR_AddSprites // During BSP traversal, this adds sprites by sector. // -------------------------------------------------------------------------- -static UINT8 sectorlight; -static void HWR_AddSprites(sector_t *sec) +void HWR_AddSprites(sector_t *sec) { mobj_t *thing; -#ifdef HWPRECIP precipmobj_t *precipthing; -#endif fixed_t approx_dist, limit_dist; INT32 splitflags; @@ -5449,9 +4010,6 @@ static void HWR_AddSprites(sector_t *sec) // Well, now it will be done. sec->validcount = validcount; - // sprite lighting - sectorlight = sec->lightlevel & 0xff; - // Handle all things in sector. // If a limit exists, handle things a tiny bit different. if ((limit_dist = (fixed_t)(/*(maptol & TOL_NIGHTS) ? cv_drawdist_nights.value : */cv_drawdist.value) << FRACBITS)) @@ -5539,7 +4097,6 @@ static void HWR_AddSprites(sector_t *sec) } } -#ifdef HWPRECIP // No to infinite precipitation draw distance. if ((limit_dist = (fixed_t)cv_drawdist_precip.value << FRACBITS)) { @@ -5556,7 +4113,6 @@ static void HWR_AddSprites(sector_t *sec) HWR_ProjectPrecipitationSprite(precipthing); } } -#endif } // -------------------------------------------------------------------------- @@ -5564,12 +4120,13 @@ static void HWR_AddSprites(sector_t *sec) // Generates a vissprite for a thing if it might be visible. // -------------------------------------------------------------------------- // BP why not use xtoviexangle/viewangletox like in bsp ?.... -static void HWR_ProjectSprite(mobj_t *thing) +void HWR_ProjectSprite(mobj_t *thing) { gr_vissprite_t *vis; float tr_x, tr_y; float tz; float x1, x2; + float z1, z2; float rightsin, rightcos; float this_scale; float gz, gzt; @@ -5579,9 +4136,8 @@ static void HWR_ProjectSprite(mobj_t *thing) unsigned rot; UINT8 flip; angle_t ang; - INT32 heightsec, phs; const boolean papersprite = (thing->frame & FF_PAPERSPRITE); - float z1, z2; + INT32 heightsec, phs; if (!thing) return; @@ -5709,6 +4265,7 @@ static void HWR_ProjectSprite(mobj_t *thing) x1 = tr_x + x1 * rightcos; x2 = tr_x - x2 * rightcos; + if (thing->eflags & MFE_VERTICALFLIP) { gz = FIXED_TO_FLOAT(thing->z+thing->height) - FIXED_TO_FLOAT(spritecachedinfo[lumpoff].topoffset) * this_scale; @@ -5755,8 +4312,7 @@ static void HWR_ProjectSprite(mobj_t *thing) vis->patchlumpnum = sprframe->lumppat[rot]; vis->flip = flip; vis->mobj = thing; - vis->z1 = z1; - vis->z2 = z2; + //Hurdler: 25/04/2000: now support colormap in hardware mode if ((vis->mobj->flags & MF_BOSS) && (vis->mobj->flags2 & MF2_FRET) && (leveltime & 1)) // Bosses "flash" @@ -5785,7 +4341,7 @@ static void HWR_ProjectSprite(mobj_t *thing) { vis->colormap = colormaps; #ifdef GLENCORE - if (encoremap && (thing->flags & (MF_SCENERY|MF_NOTHINK)) && !(thing->flags & MF_DONTENCOREMAP)) + if (encoremap && (thing->flags & (MF_SCENERY|MF_NOTHINK)) && !(thing->flags & MF_DONTENCOREMAP)) vis->colormap += (256*32); #endif } @@ -5804,9 +4360,8 @@ static void HWR_ProjectSprite(mobj_t *thing) vis->precip = false; } -#ifdef HWPRECIP // Precipitation projector for hardware mode -static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing) +void HWR_ProjectPrecipitationSprite(precipmobj_t *thing) { gr_vissprite_t *vis; float tr_x, tr_y; @@ -5902,6 +4457,7 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing) vis->mobj = (mobj_t *)thing; vis->colormap = colormaps; + #ifdef GLENCORE if (encoremap && !(thing->flags & MF_DONTENCOREMAP)) vis->colormap += (256*32); @@ -5912,96 +4468,40 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing) vis->precip = true; } -#endif -// ========================================================================== -// -// ========================================================================== -static void HWR_DrawSkyBackground(void) +static boolean drewsky = false; + +void HWR_DrawSkyBackground(float fpov) { - FOutVector v[4]; - angle_t angle; - float dimensionmultiply; - float aspectratio; - float angleturn; + FTransform dometransform; + + if (drewsky) + return; + + memset(&dometransform, 0x00, sizeof(FTransform)); + + //04/01/2000: Hurdler: added for T&L + // It should replace all other gr_viewxxx when finished + if (!atransform.shearing) + dometransform.anglex = (float)(aimingangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES); + dometransform.angley = (float)((viewangle-ANGLE_270)>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES); + + dometransform.flip = atransform.flip; + dometransform.mirror = atransform.mirror; + dometransform.shearing = atransform.shearing; + dometransform.viewaiming = atransform.viewaiming; + + dometransform.scalex = 1; + dometransform.scaley = (float)vid.width/vid.height; + dometransform.scalez = 1; + dometransform.fovxangle = fpov; // Tails + dometransform.fovyangle = fpov; // Tails + dometransform.splitscreen = splitscreen; HWR_GetTexture(texturetranslation[skytexture]); - aspectratio = (float)vid.width/(float)vid.height; - - //Hurdler: the sky is the only texture who need 4.0f instead of 1.0 - // because it's called just after clearing the screen - // and thus, the near clipping plane is set to 3.99 - // Sryder: Just use the near clipping plane value then - - // 3--2 - // | /| - // |/ | - // 0--1 - v[0].x = v[3].x = -ZCLIP_PLANE-1; - v[1].x = v[2].x = ZCLIP_PLANE+1; - v[0].y = v[1].y = -ZCLIP_PLANE-1; - v[2].y = v[3].y = ZCLIP_PLANE+1; - - v[0].z = v[1].z = v[2].z = v[3].z = ZCLIP_PLANE+1; - - // X - - // NOTE: This doesn't work right with texture widths greater than 1024 - // software doesn't draw any further than 1024 for skies anyway, but this doesn't overlap properly - // The only time this will probably be an issue is when a sky wider than 1024 is used as a sky AND a regular wall texture - - angle = (dup_viewangle + gr_xtoviewangle[0]); - dimensionmultiply = ((float)textures[texturetranslation[skytexture]]->width/256.0f); - - if (atransform.mirror) - { - angle = InvAngle(angle); - dimensionmultiply *= -1; - } - - v[0].sow = v[3].sow = ((float) angle / ((ANGLE_90-1)*dimensionmultiply)); - v[2].sow = v[1].sow = (-1.0f/dimensionmultiply)+((float) angle / ((ANGLE_90-1)*dimensionmultiply)); - - // Y - angle = aimingangle; - - dimensionmultiply = ((float)textures[texturetranslation[skytexture]]->height/(128.0f*aspectratio)); - - if (splitscreen == 1) - { - dimensionmultiply *= 2; - angle *= 2; - } - - // Middle of the sky should always be at angle 0 - // need to keep correct aspect ratio with X - if (atransform.flip) - { - // During vertical flip the sky should be flipped and it's y movement should also be flipped obviously - v[3].tow = v[2].tow = -(0.5f-(0.5f/dimensionmultiply)); - v[0].tow = v[1].tow = (-1.0f/dimensionmultiply)-(0.5f-(0.5f/dimensionmultiply)); - } - else - { - v[3].tow = v[2].tow = (-1.0f/dimensionmultiply)-(0.5f-(0.5f/dimensionmultiply)); - v[0].tow = v[1].tow = -(0.5f-(0.5f/dimensionmultiply)); - } - - angleturn = (((float)ANGLE_45-1.0f)*aspectratio)*dimensionmultiply; - - if (angle > ANGLE_180) // Do this because we don't want the sky to suddenly teleport when crossing over 0 to 360 and vice versa - { - angle = InvAngle(angle); - v[3].tow = v[2].tow += ((float) angle / angleturn); - v[0].tow = v[1].tow += ((float) angle / angleturn); - } - else - { - v[3].tow = v[2].tow -= ((float) angle / angleturn); - v[0].tow = v[1].tow -= ((float) angle / angleturn); - } - - HWD.pfnDrawPolygon(NULL, v, 4, 0); + HWD.pfnSetShader(7); // sky shader + HWD.pfnRenderSkyDome(skytexture, textures[skytexture]->width, textures[skytexture]->height, dometransform); + HWD.pfnSetShader(0); } @@ -6010,23 +4510,12 @@ static void HWR_DrawSkyBackground(void) // -----------------+ static inline void HWR_ClearView(void) { - // 3--2 - // | /| - // |/ | - // 0--1 - - /// \bug faB - enable depth mask, disable color mask - HWD.pfnGClipRect((INT32)gr_viewwindowx, (INT32)gr_viewwindowy, (INT32)(gr_viewwindowx + gr_viewwidth), (INT32)(gr_viewwindowy + gr_viewheight), ZCLIP_PLANE); HWD.pfnClearBuffer(false, true, 0); - - //disable clip window - set to full size - // rem by Hurdler - // HWD.pfnGClipRect(0, 0, vid.width, vid.height); } @@ -6060,35 +4549,16 @@ void HWR_SetViewSize(void) HWD.pfnFlushScreenTextures(); } + // ========================================================================== -// Same as rendering the player view, but from the skybox object +// Render the current frame. // ========================================================================== -void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player) +void HWR_RenderFrame(INT32 viewnumber, player_t *player, boolean skybox) { + angle_t a1; const float fpov = FIXED_TO_FLOAT(cv_fov.value+player->fovadd); - postimg_t *type; - - type = &postimgtype[viewnumber]; - - { - // do we really need to save player (is it not the same)? - player_t *saved_player = stplyr; - stplyr = player; - ST_doPaletteStuff(); - stplyr = saved_player; -#ifdef ALAM_LIGHTING - HWR_SetLights(viewnumber); -#endif - } - - // note: sets viewangle, viewx, viewy, viewz - R_SkyboxFrame(player); - - // copy view cam position for local use - dup_viewx = viewx; - dup_viewy = viewy; - dup_viewz = viewz; - dup_viewangle = viewangle; + postimg_t *postprocessor = &postimgtype[0]; + INT32 i; // set window position gr_centerx = gr_basecenterx; @@ -6113,163 +4583,115 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player) // check for new console commands. NetUpdate(); - gr_viewx = FIXED_TO_FLOAT(dup_viewx); - gr_viewy = FIXED_TO_FLOAT(dup_viewy); - gr_viewz = FIXED_TO_FLOAT(dup_viewz); + gr_viewx = FIXED_TO_FLOAT(viewx); + gr_viewy = FIXED_TO_FLOAT(viewy); + gr_viewz = FIXED_TO_FLOAT(viewz); gr_viewsin = FIXED_TO_FLOAT(viewsin); gr_viewcos = FIXED_TO_FLOAT(viewcos); - gr_viewludsin = FIXED_TO_FLOAT(FINECOSINE(aimingangle>>ANGLETOFINESHIFT)); - gr_viewludcos = FIXED_TO_FLOAT(-FINESINE(aimingangle>>ANGLETOFINESHIFT)); + // Set T&L transform + atransform.x = gr_viewx; + atransform.y = gr_viewy; + atransform.z = gr_viewz; - //04/01/2000: Hurdler: added for T&L - // It should replace all other gr_viewxxx when finished - atransform.anglex = (float)(aimingangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES); - atransform.angley = (float)(viewangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES); - atransform.anglez = 0.0f; - - if (*type == postimg_flip) - atransform.flip = true; - else - atransform.flip = false; - - if (*type == postimg_mirror) - atransform.mirror = true; - else - atransform.mirror = false; - - atransform.x = gr_viewx; // FIXED_TO_FLOAT(viewx) - atransform.y = gr_viewy; // FIXED_TO_FLOAT(viewy) - atransform.z = gr_viewz; // FIXED_TO_FLOAT(viewz) atransform.scalex = 1; atransform.scaley = (float)vid.width/vid.height; atransform.scalez = 1; + + // 14042019 + gr_aimingangle = aimingangle; + atransform.shearing = false; + atransform.viewaiming = aimingangle; + + if (cv_grshearing.value) + { + gr_aimingangle = 0; + atransform.shearing = true; + } + + gr_viewludsin = FIXED_TO_FLOAT(FINECOSINE(gr_aimingangle>>ANGLETOFINESHIFT)); + gr_viewludcos = FIXED_TO_FLOAT(-FINESINE(gr_aimingangle>>ANGLETOFINESHIFT)); + + atransform.anglex = (float)(gr_aimingangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES); + atransform.angley = (float)(viewangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES); + atransform.fovxangle = fpov; // Tails atransform.fovyangle = fpov; // Tails atransform.splitscreen = splitscreen; - gr_fovlud = (float)(1.0l/tan((double)(fpov*M_PIl/360l))); + for (i = 0; i <= splitscreen; i++) + { + if (player == &players[displayplayers[i]]) + postprocessor = &postimgtype[i]; + } - //------------------------------------------------------------------------ + atransform.flip = false; + if (*postprocessor == postimg_flip) + atransform.flip = true; + + atransform.mirror = false; + if (*postprocessor == postimg_mirror) + atransform.mirror = true; + + // Clear view, set viewport (glViewport), set perspective... HWR_ClearView(); - -if (0) -{ // I don't think this is ever used. - if (cv_grfog.value) - HWR_FoggingOn(); // First of all, turn it on, set the default user settings too - else - HWD.pfnSetSpecialState(HWD_SET_FOG_MODE, 0); // Turn it off -} - - if (drawsky) - HWR_DrawSkyBackground(); - - //Hurdler: it doesn't work in splitscreen mode - drawsky = splitscreen; - HWR_ClearSprites(); -#ifdef SORTING - drawcount = 0; -#endif -#ifdef NEWCLIP - if (rendermode == render_opengl) - { - angle_t a1 = gld_FrustumAngle(); - gld_clipper_Clear(); - gld_clipper_SafeAddClipRange(viewangle + a1, viewangle - a1); + ST_doPaletteStuff(); + + // Draw the sky background. + HWR_DrawSkyBackground(fpov); + if (skybox) + drewsky = true; + + a1 = gld_FrustumAngle(gr_aimingangle); + gld_clipper_Clear(); + gld_clipper_SafeAddClipRange(viewangle + a1, viewangle - a1); #ifdef HAVE_SPHEREFRUSTRUM - gld_FrustrumSetup(); -#endif - } -#else - HWR_ClearClipSegs(); + gld_FrustrumSetup(); #endif - //04/01/2000: Hurdler: added for T&L - // Actually it only works on Walls and Planes + // Set transform. HWD.pfnSetTransform(&atransform); + // Reset the shader state. + HWD.pfnSetSpecialState(HWD_SET_SHADERS, cv_grshaders.value); + HWD.pfnSetShader(0); + + if (cv_grbatching.value) + HWD.pfnStartBatching(); + + drawcount = 0; validcount++; + // Recursively "render" the BSP tree. HWR_RenderBSPNode((INT32)numnodes-1); -#ifndef NEWCLIP - // Make a viewangle int so we can render things based on mouselook - if (player == &players[consoleplayer]) - viewangle = localaiming[0]; - else if (splitscreen && player == &players[displayplayers[1]]) - viewangle = localaiming[1]; - else if (splitscreen > 1 && player == &players[displayplayers[2]]) - viewangle = localaiming[2]; - else if (splitscreen > 2 && player == &players[displayplayers[3]]) - viewangle = localaiming[3]; - - // Handle stuff when you are looking farther up or down. - if ((aimingangle || cv_fov.value+player->fovadd > 90*FRACUNIT)) + if (cv_grbatching.value) { - dup_viewangle += ANGLE_90; - HWR_ClearClipSegs(); - HWR_RenderBSPNode((INT32)numnodes-1); //left - - dup_viewangle += ANGLE_90; - if (((INT32)aimingangle > ANGLE_45 || (INT32)aimingangle<-ANGLE_45)) - { - HWR_ClearClipSegs(); - HWR_RenderBSPNode((INT32)numnodes-1); //back - } - - dup_viewangle += ANGLE_90; - HWR_ClearClipSegs(); - HWR_RenderBSPNode((INT32)numnodes-1); //right - - dup_viewangle += ANGLE_90; + int dummy = 0;// the vars in RenderBatches are meant for render stats. But we don't have that stuff in this branch + // so that stuff could be removed... + HWD.pfnRenderBatches(&dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy); } -#endif // Check for new console commands. - NetUpdate(); - -#ifdef ALAM_LIGHTING - //14/11/99: Hurdler: moved here because it doesn't work with - // subsector, see other comments; - HWR_ResetLights(); -#endif + // this was removed since it caused crashes on leaving record attack with models on since it was removing mobjs that were about to be rendered + //NetUpdate(); // Draw MD2 and sprites -#ifdef SORTING HWR_SortVisSprites(); -#endif - -#ifdef SORTING HWR_DrawSprites(); -#endif -#ifdef NEWCORONAS - //Hurdler: they must be drawn before translucent planes, what about gl fog? - HWR_DrawCoronas(); -#endif -#ifdef SORTING - if (numplanes || numpolyplanes || numwalls) //Hurdler: render 3D water and transparent walls after everything - { - HWR_CreateDrawNodes(); - } -#else - if (numfloors || numwalls) - { - HWD.pfnSetTransform(&atransform); - if (numfloors) - HWR_Render3DWater(); - if (numwalls) - HWR_RenderTransparentWalls(); - } -#endif + if (numplanes || numpolyplanes || numwalls) // Render FOFs and translucent walls after everything + HWR_RenderDrawNodes(); + // Unset transform and shader HWD.pfnSetTransform(NULL); + HWD.pfnUnSetShader(); - // put it off for menus etc - if (cv_grfog.value) - HWD.pfnSetSpecialState(HWD_SET_FOG_MODE, 0); + // Run post processor effects + if (!skybox) + HWR_DoPostProcessor(player); // Check for new console commands. NetUpdate(); @@ -6280,300 +4702,44 @@ if (0) } // ========================================================================== -// +// Render the player view. // ========================================================================== void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) { - const float fpov = FIXED_TO_FLOAT(cv_fov.value+player->fovadd); - postimg_t *type = &postimgtype[viewnumber]; - const boolean skybox = (skyboxmo[0] && cv_skybox.value); // True if there's a skybox object and skyboxes are on - FRGBAFloat ClearColor; - - type = &postimgtype[viewnumber]; - - ClearColor.red = 0.0f; - ClearColor.green = 0.0f; - ClearColor.blue = 0.0f; - ClearColor.alpha = 1.0f; - + // Clear the color buffer, stops HOMs. Also seems to fix the skybox issue on Intel GPUs. if (viewnumber == 0) // Only do it if it's the first screen being rendered - HWD.pfnClearBuffer(true, false, &ClearColor); // Clear the Color Buffer, stops HOMs. Also seems to fix the skybox issue on Intel GPUs. - - if (skybox && drawsky) // If there's a skybox and we should be drawing the sky, draw the skybox - HWR_RenderSkyboxView(viewnumber, player); // This is drawn before everything else so it is placed behind - { - // do we really need to save player (is it not the same)? - player_t *saved_player = stplyr; - stplyr = player; - ST_doPaletteStuff(); - stplyr = saved_player; -#ifdef ALAM_LIGHTING - HWR_SetLights(viewnumber); -#endif + FRGBAFloat ClearColor; + + ClearColor.red = 0.0f; + ClearColor.green = 0.0f; + ClearColor.blue = 0.0f; + ClearColor.alpha = 1.0f; + + HWD.pfnClearBuffer(true, false, &ClearColor); + } + + if (viewnumber > 3) + return; + + // Render the skybox if there is one. + drewsky = false; + if (skybox) + { + R_SkyboxFrame(player); + HWR_RenderFrame(viewnumber, player, true); } - // note: sets viewangle, viewx, viewy, viewz R_SetupFrame(player, false); // This can stay false because it is only used to set viewsky in r_main.c, which isn't used here - - // copy view cam position for local use - dup_viewx = viewx; - dup_viewy = viewy; - dup_viewz = viewz; - dup_viewangle = viewangle; - - // set window position - gr_centerx = gr_basecenterx; - gr_viewwindowx = gr_baseviewwindowx; - gr_windowcenterx = gr_basewindowcenterx; - gr_centery = gr_basecentery; - gr_viewwindowy = gr_baseviewwindowy; - gr_windowcentery = gr_basewindowcentery; - - if ((splitscreen == 1 && viewnumber == 1) || (splitscreen > 1 && viewnumber > 1)) - { - gr_viewwindowy += gr_viewheight; - gr_windowcentery += gr_viewheight; - } - - if (splitscreen > 1 && viewnumber & 1) - { - gr_viewwindowx += gr_viewwidth; - gr_windowcenterx += gr_viewwidth; - } - - // check for new console commands. - NetUpdate(); - - gr_viewx = FIXED_TO_FLOAT(dup_viewx); - gr_viewy = FIXED_TO_FLOAT(dup_viewy); - gr_viewz = FIXED_TO_FLOAT(dup_viewz); - gr_viewsin = FIXED_TO_FLOAT(viewsin); - gr_viewcos = FIXED_TO_FLOAT(viewcos); - - gr_viewludsin = FIXED_TO_FLOAT(FINECOSINE(aimingangle>>ANGLETOFINESHIFT)); - gr_viewludcos = FIXED_TO_FLOAT(-FINESINE(aimingangle>>ANGLETOFINESHIFT)); - - //04/01/2000: Hurdler: added for T&L - // It should replace all other gr_viewxxx when finished - atransform.anglex = (float)(aimingangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES); - atransform.angley = (float)(viewangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES); - atransform.anglez = 0.0f; - - if (*type == postimg_flip) - atransform.flip = true; - else - atransform.flip = false; - - if (*type == postimg_mirror) - atransform.mirror = true; - else - atransform.mirror = false; - - atransform.x = gr_viewx; // FIXED_TO_FLOAT(viewx) - atransform.y = gr_viewy; // FIXED_TO_FLOAT(viewy) - atransform.z = gr_viewz; // FIXED_TO_FLOAT(viewz) - atransform.scalex = 1; - atransform.scaley = (float)vid.width/vid.height; - atransform.scalez = 1; - atransform.fovxangle = fpov; // Tails - atransform.fovyangle = fpov; // Tails - atransform.splitscreen = splitscreen; - - gr_fovlud = (float)(1.0l/tan((double)(fpov*M_PIl/360l))); - - //------------------------------------------------------------------------ - HWR_ClearView(); // Clears the depth buffer and resets the view I believe - -if (0) -{ // I don't think this is ever used. - if (cv_grfog.value) - HWR_FoggingOn(); // First of all, turn it on, set the default user settings too - else - HWD.pfnSetSpecialState(HWD_SET_FOG_MODE, 0); // Turn it off -} - - if (!skybox && drawsky) // Don't draw the regular sky if there's a skybox - HWR_DrawSkyBackground(); - - //Hurdler: it doesn't work in splitscreen mode - drawsky = splitscreen; - - HWR_ClearSprites(); - -#ifdef SORTING - drawcount = 0; -#endif -#ifdef NEWCLIP - if (rendermode == render_opengl) - { - angle_t a1 = gld_FrustumAngle(); - gld_clipper_Clear(); - gld_clipper_SafeAddClipRange(viewangle + a1, viewangle - a1); -#ifdef HAVE_SPHEREFRUSTRUM - gld_FrustrumSetup(); -#endif - } -#else - HWR_ClearClipSegs(); -#endif - - //04/01/2000: Hurdler: added for T&L - // Actually it only works on Walls and Planes - HWD.pfnSetTransform(&atransform); - - validcount++; - - HWR_RenderBSPNode((INT32)numnodes-1); - -#ifndef NEWCLIP - // Make a viewangle int so we can render things based on mouselook - if (player == &players[consoleplayer]) - viewangle = localaiming[0]; - else if (splitscreen && player == &players[displayplayers[1]]) - viewangle = localaiming[1]; - else if (splitscreen > 1 && player == &players[displayplayers[2]]) - viewangle = localaiming[2]; - else if (splitscreen > 2 && player == &players[displayplayers[3]]) - viewangle = localaiming[3]; - - // Handle stuff when you are looking farther up or down. - if ((aimingangle || cv_fov.value+player->fovadd > 90*FRACUNIT)) - { - dup_viewangle += ANGLE_90; - HWR_ClearClipSegs(); - HWR_RenderBSPNode((INT32)numnodes-1); //left - - dup_viewangle += ANGLE_90; - if (((INT32)aimingangle > ANGLE_45 || (INT32)aimingangle<-ANGLE_45)) - { - HWR_ClearClipSegs(); - HWR_RenderBSPNode((INT32)numnodes-1); //back - } - - dup_viewangle += ANGLE_90; - HWR_ClearClipSegs(); - HWR_RenderBSPNode((INT32)numnodes-1); //right - - dup_viewangle += ANGLE_90; - } -#endif - - // Check for new console commands. - NetUpdate(); - -#ifdef ALAM_LIGHTING - //14/11/99: Hurdler: moved here because it doesn't work with - // subsector, see other comments; - HWR_ResetLights(); -#endif - - // Draw MD2 and sprites -#ifdef SORTING - HWR_SortVisSprites(); -#endif - -#ifdef SORTING - HWR_DrawSprites(); -#endif -#ifdef NEWCORONAS - //Hurdler: they must be drawn before translucent planes, what about gl fog? - HWR_DrawCoronas(); -#endif - -#ifdef SORTING - if (numplanes || numpolyplanes || numwalls) //Hurdler: render 3D water and transparent walls after everything - { - HWR_CreateDrawNodes(); - } -#else - if (numfloors || numpolyplanes || numwalls) - { - HWD.pfnSetTransform(&atransform); - if (numfloors) - HWR_Render3DWater(); - if (numwalls) - HWR_RenderTransparentWalls(); - } -#endif - - HWD.pfnSetTransform(NULL); - - // put it off for menus etc - if (cv_grfog.value) - HWD.pfnSetSpecialState(HWD_SET_FOG_MODE, 0); - - HWR_DoPostProcessor(player); - - // Check for new console commands. - NetUpdate(); - - // added by Hurdler for correct splitscreen - // moved here by hurdler so it works with the new near clipping plane - HWD.pfnGClipRect(0, 0, vid.width, vid.height, NZCLIP_PLANE); -} - -// ========================================================================== -// FOG -// ========================================================================== - -/// \author faB - -static UINT32 atohex(const char *s) -{ - INT32 iCol; - const char *sCol; - char cCol; - INT32 i; - - if (strlen(s)<6) - return 0; - - iCol = 0; - sCol = s; - for (i = 0; i < 6; i++, sCol++) - { - iCol <<= 4; - cCol = *sCol; - if (cCol >= '0' && cCol <= '9') - iCol |= cCol - '0'; - else - { - if (cCol >= 'F') - cCol -= 'a' - 'A'; - if (cCol >= 'A' && cCol <= 'F') - iCol = iCol | (cCol - 'A' + 10); - } - } - //CONS_Debug(DBG_RENDER, "col %x\n", iCol); - return iCol; -} - -static void HWR_FoggingOn(void) -{ - HWD.pfnSetSpecialState(HWD_SET_FOG_COLOR, atohex(cv_grfogcolor.string)); - HWD.pfnSetSpecialState(HWD_SET_FOG_DENSITY, cv_grfogdensity.value); - HWD.pfnSetSpecialState(HWD_SET_FOG_MODE, 1); + HWR_RenderFrame(viewnumber, player, false); } // ========================================================================== // 3D ENGINE COMMANDS // ========================================================================== - - -static void Command_GrStats_f(void) -{ - Z_CheckHeap(9875); // debug - - CONS_Printf(M_GetText("Patch info headers: %7s kb\n"), sizeu1(Z_TagUsage(PU_HWRPATCHINFO)>>10)); - CONS_Printf(M_GetText("3D Texture cache : %7s kb\n"), sizeu1(Z_TagUsage(PU_HWRCACHE)>>10)); - CONS_Printf(M_GetText("Plane polygon : %7s kb\n"), sizeu1(Z_TagUsage(PU_HWRPLANE)>>10)); -} - - // ************************************************************************** // 3D ENGINE SETUP // ************************************************************************** @@ -6585,31 +4751,14 @@ static void Command_GrStats_f(void) void HWR_AddCommands(void) { CV_RegisterVar(&cv_grrounddown); - CV_RegisterVar(&cv_grfogdensity); CV_RegisterVar(&cv_grfiltermode); CV_RegisterVar(&cv_granisotropicmode); CV_RegisterVar(&cv_grcorrecttricks); CV_RegisterVar(&cv_grsolvetjoin); + + CV_RegisterVar(&cv_grbatching); } -static inline void HWR_AddEngineCommands(void) -{ - // engine state variables - //CV_RegisterVar(&cv_grzbuffer); -#ifndef NEWCLIP - CV_RegisterVar(&cv_grclipwalls); -#endif - - // engine development mode variables - // - usage may vary from version to version.. - CV_RegisterVar(&cv_gralpha); - CV_RegisterVar(&cv_grbeta); - - // engine commands - COM_AddCommand("gr_stats", Command_GrStats_f); -} - - // -------------------------------------------------------------------------- // Setup the hardware renderer // -------------------------------------------------------------------------- @@ -6617,27 +4766,12 @@ void HWR_Startup(void) { static boolean startupdone = false; - // setup GLPatch_t scaling - gr_patch_scalex = (float)(1.0f / vid.width); - gr_patch_scaley = (float)(1.0f / vid.height); - - // initalze light lut translation - InitLumLut(); - // do this once if (!startupdone) { - CONS_Printf("HWR_Startup()\n"); - HWR_InitPolyPool(); - // add console cmds & vars - HWR_AddEngineCommands(); + CONS_Printf("HWR_Startup()...\n"); HWR_InitTextureCache(); - HWR_InitMD2(); - -#ifdef ALAM_LIGHTING - HWR_InitLight(); -#endif } if (rendermode == render_opengl) @@ -6649,6 +4783,11 @@ void HWR_Startup(void) #endif startupdone = true; + + // jimita + HWD.pfnKillShaders(); + if (!HWD.pfnLoadShaders()) + gr_shadersavailable = false; } @@ -6659,137 +4798,11 @@ void HWR_Shutdown(void) { CONS_Printf("HWR_Shutdown()\n"); HWR_FreeExtraSubsectors(); - HWR_FreePolyPool(); HWR_FreeTextureCache(); HWD.pfnFlushScreenTextures(); } -void transform(float *cx, float *cy, float *cz) -{ - float tr_x,tr_y; - // translation - tr_x = *cx - gr_viewx; - tr_y = *cz - gr_viewy; -// *cy = *cy; - - // rotation around vertical y axis - *cx = (tr_x * gr_viewsin) - (tr_y * gr_viewcos); - tr_x = (tr_x * gr_viewcos) + (tr_y * gr_viewsin); - - //look up/down ----TOTAL SUCKS!!!--- do the 2 in one!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - tr_y = *cy - gr_viewz; - - *cy = (tr_x * gr_viewludcos) + (tr_y * gr_viewludsin); - *cz = (tr_x * gr_viewludsin) - (tr_y * gr_viewludcos); - - //scale y before frustum so that frustum can be scaled to screen height - *cy *= ORIGINAL_ASPECT * gr_fovlud; - *cx *= gr_fovlud; -} - - -//Hurdler: 3D Water stuff -#define MAX_3DWATER 512 - -#ifndef SORTING -static void HWR_Add3DWater(lumpnum_t lumpnum, extrasubsector_t *xsub, - fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector) -{ - static size_t allocedplanes = 0; - - // Force realloc if buffer has been freed - if (!planeinfo) - allocedplanes = 0; - - if (allocedplanes < numfloors + 1) - { - allocedplanes += MAX_3DWATER; - Z_Realloc(planeinfo, allocedplanes * sizeof (*planeinfo), PU_LEVEL, &planeinfo); - } - planeinfo[numfloors].fixedheight = fixedheight; - planeinfo[numfloors].lightlevel = lightlevel; - planeinfo[numfloors].lumpnum = lumpnum; - planeinfo[numfloors].xsub = xsub; - planeinfo[numfloors].alpha = alpha; - planeinfo[numfloors].FOFSector = FOFSector; - numfloors++; -} -#endif - -#define DIST_PLANE(i) ABS(planeinfo[(i)].fixedheight-dup_viewz) - -#if 0 -static void HWR_QuickSortPlane(INT32 start, INT32 finish) -{ - INT32 left = start; - INT32 right = finish; - INT32 starterval = (INT32)((right+left)/2); //pick a starter - - planeinfo_t temp; - - //'sort of sort' the two halves of the data list about starterval - while (right > left); - { - while (DIST_PLANE(left) < DIST_PLANE(starterval)) left++; //attempt to find a bigger value on the left - while (DIST_PLANE(right) > DIST_PLANE(starterval)) right--; //attempt to find a smaller value on the right - - if (left < right) //if we haven't gone too far - { - //switch them - M_Memcpy(&temp, &planeinfo[left], sizeof (planeinfo_t)); - M_Memcpy(&planeinfo[left], &planeinfo[right], sizeof (planeinfo_t)); - M_Memcpy(&planeinfo[right], &temp, sizeof (planeinfo_t)); - //move the bounds - left++; - right--; - } - } - - if (start < right) HWR_QuickSortPlane(start, right); - if (left < finish) HWR_QuickSortPlane(left, finish); -} -#endif - -#ifndef SORTING -static void HWR_Render3DWater(void) -{ - size_t i; - - //bubble sort 3D Water for correct alpha blending - { - boolean permut = true; - while (permut) - { - size_t j; - for (j = 0, permut= false; j < numfloors-1; j++) - { - if (ABS(planeinfo[j].fixedheight-dup_viewz) < ABS(planeinfo[j+1].fixedheight-dup_viewz)) - { - planeinfo_t temp; - M_Memcpy(&temp, &planeinfo[j+1], sizeof (planeinfo_t)); - M_Memcpy(&planeinfo[j+1], &planeinfo[j], sizeof (planeinfo_t)); - M_Memcpy(&planeinfo[j], &temp, sizeof (planeinfo_t)); - permut = true; - } - } - } - } -#if 0 //thanks epat, but it's goes looping forever on CTF map Silver Cascade Zone - HWR_QuickSortPlane(0, numplanes-1); -#endif - - gr_frontsector = NULL; //Hurdler: gr_fronsector is no longer valid - for (i = 0; i < numfloors; i++) - { - HWR_GetFlat(planeinfo[i].lumpnum); - HWR_RenderPlane(NULL, planeinfo[i].xsub, planeinfo[i].isceiling, planeinfo[i].fixedheight, PF_Translucent, planeinfo[i].lightlevel, planeinfo[i].lumpnum, - planeinfo[i].FOFSector, planeinfo[i].alpha, planeinfo[i].fogplane, planeinfo[i].planecolormap); - } - numfloors = 0; -} -#endif - -static void HWR_AddTransparentWall(wallVert3D *wallVerts, FSurfaceInfo *pSurf, INT32 texnum, FBITFIELD blend, boolean fogwall, INT32 lightlevel, extracolormap_t *wallcolormap) +void HWR_AddTransparentWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, INT32 texnum, FBITFIELD blend, boolean fogwall, INT32 lightlevel, extracolormap_t *wallcolormap) { static size_t allocedwalls = 0; @@ -6807,108 +4820,42 @@ static void HWR_AddTransparentWall(wallVert3D *wallVerts, FSurfaceInfo *pSurf, I M_Memcpy(&wallinfo[numwalls].Surf, pSurf, sizeof (FSurfaceInfo)); wallinfo[numwalls].texnum = texnum; wallinfo[numwalls].blend = blend; -#ifdef SORTING wallinfo[numwalls].drawcount = drawcount++; -#endif wallinfo[numwalls].fogwall = fogwall; wallinfo[numwalls].lightlevel = lightlevel; wallinfo[numwalls].wallcolormap = wallcolormap; numwalls++; } -#ifndef SORTING -static void HWR_RenderTransparentWalls(void) + +void HWR_RenderWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blend, boolean fogwall, INT32 lightlevel, extracolormap_t *wallcolormap) { - size_t i; - - /*{ // sorting is disbale for now, do it! - INT32 permut = 1; - while (permut) - { - INT32 j; - for (j = 0, permut = 0; j < numwalls-1; j++) - { - if (ABS(wallinfo[j].fixedheight-dup_viewz) < ABS(wallinfo[j+1].fixedheight-dup_viewz)) - { - wallinfo_t temp; - M_Memcpy(&temp, &wallinfo[j+1], sizeof (wallinfo_t)); - M_Memcpy(&wallinfo[j+1], &wallinfo[j], sizeof (wallinfo_t)); - M_Memcpy(&wallinfo[j], &temp, sizeof (wallinfo_t)); - permut = 1; - } - } - } - }*/ - - for (i = 0; i < numwalls; i++) - { - HWR_GetTexture(wallinfo[i].texnum); - HWR_RenderWall(wallinfo[i].wallVerts, &wallinfo[i].Surf, wallinfo[i].blend, wallinfo[i].wall->fogwall, wallinfo[i].wall->lightlevel, wallinfo[i].wall->wallcolormap); - } - numwalls = 0; -} -#endif -static void HWR_RenderWall(wallVert3D *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blend, boolean fogwall, INT32 lightlevel, extracolormap_t *wallcolormap) -{ - FOutVector trVerts[4]; - UINT8 i; - FOutVector *wv; - UINT8 alpha; - - // transform - wv = trVerts; - // it sounds really stupid to do this conversion with the new T&L code - // we should directly put the right information in the right structure - // wallVerts3D seems ok, doesn't need FOutVector - // also remove the light copy - for (i = 0; i < 4; i++, wv++, wallVerts++) - { - wv->sow = wallVerts->s; - wv->tow = wallVerts->t; - wv->x = wallVerts->x; - wv->y = wallVerts->y; - wv->z = wallVerts->z; - } - - alpha = pSurf->FlatColor.s.alpha; // retain the alpha + FBITFIELD blendmode = blend; + UINT8 alpha = pSurf->PolyColor.s.alpha; // retain the alpha // Lighting is done here instead so that fog isn't drawn incorrectly on transparent walls after sorting + HWR_Lighting(pSurf, lightlevel, wallcolormap); - if (wallcolormap) - { - if (fogwall) - pSurf->FlatColor.rgba = HWR_Lighting(lightlevel, wallcolormap->rgba, wallcolormap->fadergba, true, false); - else - pSurf->FlatColor.rgba = HWR_Lighting(lightlevel, wallcolormap->rgba, wallcolormap->fadergba, false, false); - } - else - { - if (fogwall) - pSurf->FlatColor.rgba = HWR_Lighting(lightlevel, NORMALFOG, FADEFOG, true, false); - else - pSurf->FlatColor.rgba = HWR_Lighting(lightlevel, NORMALFOG, FADEFOG, false, false); - } + pSurf->PolyColor.s.alpha = alpha; // put the alpha back after lighting - pSurf->FlatColor.s.alpha = alpha; // put the alpha back after lighting + HWD.pfnSetShader(2); // wall shader if (blend & PF_Environment) - HWD.pfnDrawPolygon(pSurf, trVerts, 4, blend|PF_Modulated|PF_Clip|PF_Occlude); // PF_Occlude must be used for solid objects - else - HWD.pfnDrawPolygon(pSurf, trVerts, 4, blend|PF_Modulated|PF_Clip); // No PF_Occlude means overlapping (incorrect) transparency + blendmode |= PF_Occlude; // PF_Occlude must be used for solid objects + + if (fogwall) + { + blendmode |= PF_Fog; + HWD.pfnSetShader(6); // fog shader + } + + blendmode |= PF_Modulated; // No PF_Occlude means overlapping (incorrect) transparency + + HWD.pfnDrawPolygon(pSurf, wallVerts, 4, blendmode); #ifdef WALLSPLATS if (gr_curline->linedef->splats && cv_splats.value) HWR_DrawSegsSplats(pSurf); - -#ifdef ALAM_LIGHTING - //Hurdler: TODO: do static lighting using gr_curline->lm - HWR_WallLighting(trVerts); #endif -#endif -} - -INT32 HWR_GetTextureUsed(void) -{ - return HWD.pfnGetTextureUsed(); } void HWR_DoPostProcessor(player_t *player) @@ -6916,6 +4863,8 @@ void HWR_DoPostProcessor(player_t *player) postimg_t *type = &postimgtype[0]; UINT8 i; + HWD.pfnUnSetShader(); + for (i = splitscreen; i > 0; i--) { if (player == &players[displayplayers[i]]) @@ -6939,15 +4888,15 @@ void HWR_DoPostProcessor(player_t *player) // This won't change if the flash palettes are changed unfortunately, but it works for its purpose if (player->flashpal == PAL_NUKE) { - Surf.FlatColor.s.red = 0xff; - Surf.FlatColor.s.green = Surf.FlatColor.s.blue = 0x7F; // The nuke palette is kind of pink-ish + Surf.PolyColor.s.red = 0xff; + Surf.PolyColor.s.green = Surf.PolyColor.s.blue = 0x7F; // The nuke palette is kind of pink-ish } else - Surf.FlatColor.s.red = Surf.FlatColor.s.green = Surf.FlatColor.s.blue = 0xff; + Surf.PolyColor.s.red = Surf.PolyColor.s.green = Surf.PolyColor.s.blue = 0xff; - Surf.FlatColor.s.alpha = 0xc0; // match software mode + Surf.PolyColor.s.alpha = 0xc0; // match software mode - HWD.pfnDrawPolygon(&Surf, v, 4, PF_Modulated|PF_Additive|PF_NoTexture|PF_NoDepthTest|PF_Clip|PF_NoZClip); + HWD.pfnDrawPolygon(&Surf, v, 4, PF_Modulated|PF_Translucent|PF_NoTexture|PF_NoDepthTest); } // Capture the screen for intermission and screen waving @@ -6962,7 +4911,7 @@ void HWR_DoPostProcessor(player_t *player) { // 10 by 10 grid. 2 coordinates (xy) float v[SCREENVERTS][SCREENVERTS][2]; - static double disStart = 0; + double disStart = leveltime; UINT8 x, y; INT32 WAVELENGTH; INT32 AMPLITUDE; @@ -6992,7 +4941,6 @@ void HWR_DoPostProcessor(player_t *player) } } HWD.pfnPostImgRedraw(v); - disStart += 1; // Capture the screen again for screen waving on the intermission if(gamestate != GS_INTERMISSION) @@ -7003,14 +4951,11 @@ void HWR_DoPostProcessor(player_t *player) void HWR_StartScreenWipe(void) { - //CONS_Debug(DBG_RENDER, "In HWR_StartScreenWipe()\n"); HWD.pfnStartScreenWipe(); } void HWR_EndScreenWipe(void) { - HWRWipeCounter = 0.0f; - //CONS_Debug(DBG_RENDER, "In HWR_EndScreenWipe()\n"); HWD.pfnEndScreenWipe(); } @@ -7044,13 +4989,7 @@ void HWR_DoWipe(UINT8 wipenum, UINT8 scrnnum) } HWR_GetFadeMask(lumpnum); - HWD.pfnDoScreenWipe(); - - HWRWipeCounter += 0.05f; // increase opacity of end screen - - if (HWRWipeCounter > 1.0f) - HWRWipeCounter = 1.0f; } void HWR_MakeScreenFinalTexture(void) @@ -7063,4 +5002,161 @@ void HWR_DrawScreenFinalTexture(int width, int height) HWD.pfnDrawScreenFinalTexture(width, height); } +// jimita 18032019 +typedef struct +{ + char type[16]; + INT32 id; +} shaderxlat_t; + +static inline UINT16 HWR_CheckShader(UINT16 wadnum) +{ + UINT16 i; + lumpinfo_t *lump_p; + + lump_p = wadfiles[wadnum]->lumpinfo; + for (i = 0; i < wadfiles[wadnum]->numlumps; i++, lump_p++) + if (memcmp(lump_p->name, "SHADERS", 7) == 0) + return i; + + return INT16_MAX; +} + +void HWR_LoadShaders(UINT16 wadnum, boolean PK3) +{ + UINT16 lump; + char *shaderdef, *line; + char *stoken; + char *value; + size_t size; + int linenum = 1; + int shadertype = 0; + int i; + + #define SHADER_TYPES 7 + shaderxlat_t shaderxlat[SHADER_TYPES] = + { + {"Flat", 1}, + {"WallTexture", 2}, + {"Sprite", 3}, + {"Model", 4}, + {"WaterRipple", 5}, + {"Fog", 6}, + {"Sky", 7}, + }; + + lump = HWR_CheckShader(wadnum); + if (lump == INT16_MAX) + return; + + shaderdef = W_CacheLumpNumPwad(wadnum, lump, PU_CACHE); + size = W_LumpLengthPwad(wadnum, lump); + + line = Z_Malloc(size+1, PU_STATIC, NULL); + if (!line) + I_Error("HWR_LoadShaders: No more free memory\n"); + + M_Memcpy(line, shaderdef, size); + line[size] = '\0'; + + stoken = strtok(line, "\r\n "); + while (stoken) + { + if ((stoken[0] == '/' && stoken[1] == '/') + || (stoken[0] == '#'))// skip comments + { + stoken = strtok(NULL, "\r\n"); + goto skip_field; + } + + if (!stricmp(stoken, "GLSL")) + { + value = strtok(NULL, "\r\n "); + if (!value) + { + CONS_Alert(CONS_WARNING, "HWR_LoadShaders: Missing shader type (file %s, line %d)\n", wadfiles[wadnum]->filename, linenum); + stoken = strtok(NULL, "\r\n"); // skip end of line + goto skip_lump; + } + + if (!stricmp(value, "VERTEX")) + shadertype = 1; + else if (!stricmp(value, "FRAGMENT")) + shadertype = 2; + +skip_lump: + stoken = strtok(NULL, "\r\n "); + linenum++; + } + else + { + value = strtok(NULL, "\r\n= "); + if (!value) + { + CONS_Alert(CONS_WARNING, "HWR_LoadShaders: Missing shader target (file %s, line %d)\n", wadfiles[wadnum]->filename, linenum); + stoken = strtok(NULL, "\r\n"); // skip end of line + goto skip_field; + } + + if (!shadertype) + { + CONS_Alert(CONS_ERROR, "HWR_LoadShaders: Missing shader type (file %s, line %d)\n", wadfiles[wadnum]->filename, linenum); + Z_Free(line); + return; + } + + for (i = 0; i < SHADER_TYPES; i++) + { + if (!stricmp(shaderxlat[i].type, stoken)) + { + size_t shader_size; + char *shader_source; + char *shader_lumpname; + UINT16 shader_lumpnum; + + if (PK3) + { + shader_lumpname = Z_Malloc(strlen(value) + 12, PU_STATIC, NULL); + strcpy(shader_lumpname, "Shaders/sh_"); + strcat(shader_lumpname, value); + shader_lumpnum = W_CheckNumForFullNamePK3(shader_lumpname, wadnum, 0); + } + else + { + shader_lumpname = Z_Malloc(strlen(value) + 4, PU_STATIC, NULL); + strcpy(shader_lumpname, "SH_"); + strcat(shader_lumpname, value); + shader_lumpnum = W_CheckNumForNamePwad(shader_lumpname, wadnum, 0); + } + + if (shader_lumpnum == INT16_MAX) + { + CONS_Alert(CONS_ERROR, "HWR_LoadShaders: Missing shader source %s (file %s, line %d)\n", shader_lumpname, wadfiles[wadnum]->filename, linenum); + Z_Free(shader_lumpname); + continue; + } + + shader_size = W_LumpLengthPwad(wadnum, shader_lumpnum); + shader_source = Z_Malloc(shader_size, PU_STATIC, NULL); + W_ReadLumpPwad(wadnum, shader_lumpnum, shader_source); + + HWD.pfnLoadCustomShader(shaderxlat[i].id, shader_source, shader_size, (shadertype == 2)); + + Z_Free(shader_source); + Z_Free(shader_lumpname); + } + } + +skip_field: + stoken = strtok(NULL, "\r\n= "); + linenum++; + } + } + + HWD.pfnInitCustomShaders(); + + Z_Free(line); + return; +} + #endif // HWRENDER diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index e6c1fb6ff..bc4a74e5f 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -22,6 +22,7 @@ #ifndef __HWR_MAIN_H__ #define __HWR_MAIN_H__ +#include "hw_glob.h" #include "hw_data.h" #include "hw_defs.h" @@ -29,38 +30,51 @@ #include "../d_player.h" #include "../r_defs.h" +#define GLENCORE + // Startup & Shutdown the hardware mode renderer void HWR_Startup(void); void HWR_Shutdown(void); -void HWR_drawAMline(const fline_t *fl, INT32 color); -void HWR_FadeScreenMenuBack(UINT16 color, UINT8 strength); -void HWR_DrawConsoleBack(UINT32 color, INT32 height); -void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player); -void HWR_RenderPlayerView(INT32 viewnumber, player_t *player); -void HWR_DrawViewBorder(INT32 clearlines); -void HWR_DrawFlatFill(INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatlumpnum); -UINT8 *HWR_GetScreenshot(void); -boolean HWR_Screenshot(const char *lbmname); -void HWR_InitTextureMapping(void); -void HWR_SetViewSize(void); +extern float gr_viewwidth, gr_viewheight, gr_baseviewwindowx, gr_baseviewwindowy; + +extern float gr_basewindowcenterx, gr_basewindowcentery; + +extern FTransform atransform; + +// hw_draw.c void HWR_DrawPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option); void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t scale, INT32 option, const UINT8 *colormap); -void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t scale, INT32 option, fixed_t sx, fixed_t sy, fixed_t w, fixed_t h); -void HWR_MakePatch (const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipmap, boolean makebitmap); -void HWR_CreatePlanePolygons(INT32 bspnum); -void HWR_CreateStaticLightmaps(INT32 bspnum); -void HWR_PrepLevelCache(size_t pnumtextures); +void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, INT32 option, fixed_t sx, fixed_t sy, fixed_t w, fixed_t h); void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color); void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, UINT32 color, INT32 options); // Lat: separate flags from color since color needs to be an uint to work right. void HWR_DrawDiag(INT32 x, INT32 y, INT32 wh, INT32 color); -void HWR_DrawPic(INT32 x,INT32 y,lumpnum_t lumpnum); +void HWR_drawAMline(const fline_t *fl, INT32 color); +void HWR_FadeScreenMenuBack(UINT16 color, UINT8 strength); +void HWR_DrawConsoleBack(UINT32 color, INT32 height); +void HWR_DrawViewBorder(INT32 clearlines); +void HWR_DrawFlatFill(INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatlumpnum); +UINT8 *HWR_GetScreenshot(void); +boolean HWR_Screenshot(const char *lbmname); + +// hw_main.c +void HWR_RenderFrame(INT32 viewnumber, player_t *player, boolean skybox); +void HWR_RenderPlayerView(INT32 viewnumber, player_t *player); +void HWR_LoadShaders(UINT16 wadnum, boolean PK3); +void HWR_SetViewSize(void); void HWR_AddCommands(void); -void HWR_CorrectSWTricks(void); -void transform(float *cx, float *cy, float *cz); + +// My original intention was to split hw_main.c +// into files like hw_bsp.c, hw_sprites.c... + +// hw_main.c: Lighting and fog +void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *colormap); +UINT8 HWR_FogBlockAlpha(INT32 light, extracolormap_t *colormap); // Let's see if this can work + FBITFIELD HWR_TranstableToAlpha(INT32 transtablenum, FSurfaceInfo *pSurf); -INT32 HWR_GetTextureUsed(void); + +// hw_main.c: Post-rendering void HWR_DoPostProcessor(player_t *player); void HWR_StartScreenWipe(void); void HWR_EndScreenWipe(void); @@ -69,24 +83,60 @@ void HWR_DoWipe(UINT8 wipenum, UINT8 scrnnum); void HWR_MakeScreenFinalTexture(void); void HWR_DrawScreenFinalTexture(int width, int height); -// This stuff is put here so MD2's can use them -UINT32 HWR_Lighting(INT32 light, UINT32 color, UINT32 fadecolor, boolean fogblockpoly, boolean plane); -FUNCMATH UINT8 LightLevelToLum(INT32 l); +// hw_main.c: Planes +void HWR_RenderPlane(extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, FBITFIELD PolyFlags, INT32 lightlevel, lumpnum_t lumpnum, sector_t *FOFsector, UINT8 alpha, extracolormap_t *planecolormap); +void HWR_AddTransparentFloor(lumpnum_t lumpnum, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, extracolormap_t *planecolormap); -extern CV_PossibleValue_t granisotropicmode_cons_t[]; - -#ifdef ALAM_LIGHTING -extern consvar_t cv_grdynamiclighting; -extern consvar_t cv_grstaticlighting; -extern consvar_t cv_grcoronas; -extern consvar_t cv_grcoronasize; +#ifdef POLYOBJECTS +#ifdef POLYOBJECTS_PLANES +void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, FBITFIELD blendmode, UINT8 lightlevel, lumpnum_t lumpnum, sector_t *FOFsector, UINT8 alpha, extracolormap_t *planecolormap); +void HWR_AddPolyObjectPlanes(void); +void HWR_AddTransparentPolyobjectFloor(lumpnum_t lumpnum, polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, extracolormap_t *planecolormap); #endif +#endif + +// hw_main.c: Segs +void HWR_ProcessSeg(void); // Sort of like GLWall::Process in GZDoom +void HWR_RenderWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blend, boolean fogwall, INT32 lightlevel, extracolormap_t *wallcolormap); +void HWR_ProjectWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blendmode, INT32 lightlevel, extracolormap_t *wallcolormap); +void HWR_AddTransparentWall(FOutVector *wallVerts, FSurfaceInfo * pSurf, INT32 texnum, FBITFIELD blend, boolean fogwall, INT32 lightlevel, extracolormap_t *wallcolormap); +void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, FSurfaceInfo* Surf, INT32 cutflag, ffloor_t *pfloor); +void HWR_DrawSkyWall(FOutVector *wallVerts, FSurfaceInfo *Surf); +void HWR_DrawSkyBackground(float fpov); + +#ifdef POLYOBJECTS +void HWR_AddPolyObjectSegs(void); +#endif + +// hw_main.c: BSP +void HWR_RenderBSPNode(INT32 bspnum); +void HWR_Subsector(size_t num); +void HWR_AddLine(seg_t *line); +boolean HWR_CheckBBox(fixed_t *bspcoord); +void HWR_RenderDrawNodes(void); + +// hw_main.c: Sprites +void HWR_AddSprites(sector_t *sec); +void HWR_ProjectSprite(mobj_t *thing); +void HWR_ProjectPrecipitationSprite(precipmobj_t *thing); +void HWR_DrawSprites(void); + +// hw_bsp.c +void HWR_CreatePlanePolygons(INT32 bspnum); + +// hw_cache.c +void HWR_PrepLevelCache(size_t pnumtextures); + +// hw_trick.c +void HWR_CorrectSWTricks(void); + +// Console variables +extern consvar_t cv_grshaders; +extern consvar_t cv_grshearing; +extern consvar_t cv_grfov; extern consvar_t cv_grmdls; -extern consvar_t cv_grfallbackplayermodel; extern consvar_t cv_grfog; -extern consvar_t cv_grfogcolor; extern consvar_t cv_grfogdensity; -extern consvar_t cv_grsoftwarefog; extern consvar_t cv_grgammared; extern consvar_t cv_grgammagreen; extern consvar_t cv_grgammablue; @@ -96,22 +146,9 @@ extern consvar_t cv_grcorrecttricks; extern consvar_t cv_grfovchange; extern consvar_t cv_grsolvetjoin; extern consvar_t cv_grspritebillboarding; +extern consvar_t cv_grfakecontrast; +extern consvar_t cv_grfallbackplayermodel; -extern float gr_viewwidth, gr_viewheight, gr_baseviewwindowx, gr_baseviewwindowy; - -extern float gr_basewindowcenterx, gr_basewindowcentery; - -// BP: big hack for a test in lighting ref : 1249753487AB -extern fixed_t *hwbbox; -extern FTransform atransform; - -typedef struct -{ - wallVert3D floorVerts[4]; - FSurfaceInfo Surf; - INT32 texnum; - INT32 blend; - INT32 drawcount; -} floorinfo_t; +extern CV_PossibleValue_t granisotropicmode_cons_t[]; #endif diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index d217f4094..9e77d22bc 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1,17 +1,12 @@ -// Emacs style mode select -*- C++ -*- +// SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// +// Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2019 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 -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// 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 /// \brief MD2 Handling @@ -90,7 +85,6 @@ static void md2_freeModel (model_t *model) } #endif - // // load model // @@ -151,7 +145,7 @@ static void PNG_warn(png_structp PNG, png_const_charp pngtext) CONS_Debug(DBG_RENDER, "libpng warning at %p: %s", PNG, pngtext); } -static GrTextureFormat_t PNG_Load(const char *filename, int *w, int *h, GLPatch_t *grpatch) +static GLTextureFormat_t PNG_Load(const char *filename, int *w, int *h, GLPatch_t *grpatch) { png_structp png_ptr; png_infop png_info_ptr; @@ -205,7 +199,7 @@ static GrTextureFormat_t PNG_Load(const char *filename, int *w, int *h, GLPatch_ //CONS_Debug(DBG_RENDER, "libpng load error on %s\n", filename); png_destroy_read_struct(&png_ptr, &png_info_ptr, NULL); fclose(png_FILE); - Z_Free(grpatch->mipmap.grInfo.data); + Z_Free(grpatch->mipmap->grInfo.data); return 0; } #ifdef USE_FAR_KEYWORD @@ -246,7 +240,7 @@ static GrTextureFormat_t PNG_Load(const char *filename, int *w, int *h, GLPatch_ { png_uint_32 i, pitch = png_get_rowbytes(png_ptr, png_info_ptr); - png_bytep PNG_image = Z_Malloc(pitch*height, PU_HWRCACHE, &grpatch->mipmap.grInfo.data); + png_bytep PNG_image = Z_Malloc(pitch*height, PU_HWRCACHE, &grpatch->mipmap->grInfo.data); png_bytepp row_pointers = png_malloc(png_ptr, height * sizeof (png_bytep)); for (i = 0; i < height; i++) row_pointers[i] = PNG_image + i*pitch; @@ -285,7 +279,7 @@ typedef struct UINT8 filler[54]; } PcxHeader; -static GrTextureFormat_t PCX_Load(const char *filename, int *w, int *h, +static GLTextureFormat_t PCX_Load(const char *filename, int *w, int *h, GLPatch_t *grpatch) { PcxHeader header; @@ -326,7 +320,7 @@ static GrTextureFormat_t PCX_Load(const char *filename, int *w, int *h, pw = *w = header.xmax - header.xmin + 1; ph = *h = header.ymax - header.ymin + 1; - image = Z_Malloc(pw*ph*4, PU_HWRCACHE, &grpatch->mipmap.grInfo.data); + image = Z_Malloc(pw*ph*4, PU_HWRCACHE, &grpatch->mipmap->grInfo.data); if (fread(palette, sizeof (UINT8), PALSIZE, file) != PALSIZE) { @@ -374,37 +368,43 @@ static void md2_loadTexture(md2_t *model) if (model->grpatch) { grpatch = model->grpatch; - Z_Free(grpatch->mipmap.grInfo.data); + Z_Free(grpatch->mipmap->grInfo.data); } else + { grpatch = Z_Calloc(sizeof *grpatch, PU_HWRPATCHINFO, &(model->grpatch)); + grpatch->mipmap = Z_Calloc(sizeof (GLMipmap_t), PU_HWRPATCHINFO, NULL); + } - if (!grpatch->mipmap.downloaded && !grpatch->mipmap.grInfo.data) + if (!grpatch->mipmap->downloaded && !grpatch->mipmap->grInfo.data) { int w = 0, h = 0; #ifdef HAVE_PNG - grpatch->mipmap.grInfo.format = PNG_Load(filename, &w, &h, grpatch); - if (grpatch->mipmap.grInfo.format == 0) + grpatch->mipmap->grInfo.format = PNG_Load(filename, &w, &h, grpatch); + if (grpatch->mipmap->grInfo.format == 0) #endif - grpatch->mipmap.grInfo.format = PCX_Load(filename, &w, &h, grpatch); - if (grpatch->mipmap.grInfo.format == 0) + grpatch->mipmap->grInfo.format = PCX_Load(filename, &w, &h, grpatch); + if (grpatch->mipmap->grInfo.format == 0) + { + grpatch->notfound = true;// mark it so its not searched for again repeatedly return; + } - grpatch->mipmap.downloaded = 0; - grpatch->mipmap.flags = 0; + grpatch->mipmap->downloaded = 0; + grpatch->mipmap->flags = 0; grpatch->width = (INT16)w; grpatch->height = (INT16)h; - grpatch->mipmap.width = (UINT16)w; - grpatch->mipmap.height = (UINT16)h; + grpatch->mipmap->width = (UINT16)w; + grpatch->mipmap->height = (UINT16)h; // not correct! - grpatch->mipmap.grInfo.smallLodLog2 = GR_LOD_LOG2_256; - grpatch->mipmap.grInfo.largeLodLog2 = GR_LOD_LOG2_256; - grpatch->mipmap.grInfo.aspectRatioLog2 = GR_ASPECT_LOG2_1x1; + grpatch->mipmap->grInfo.smallLodLog2 = GR_LOD_LOG2_256; + grpatch->mipmap->grInfo.largeLodLog2 = GR_LOD_LOG2_256; + grpatch->mipmap->grInfo.aspectRatioLog2 = GR_ASPECT_LOG2_1x1; } - HWD.pfnSetTexture(&grpatch->mipmap); + HWD.pfnSetTexture(grpatch->mipmap); HWR_UnlockCachedPatch(grpatch); } @@ -422,40 +422,44 @@ static void md2_loadBlendTexture(md2_t *model) if (model->blendgrpatch) { grpatch = model->blendgrpatch; - Z_Free(grpatch->mipmap.grInfo.data); + Z_Free(grpatch->mipmap->grInfo.data); } else + { grpatch = Z_Calloc(sizeof *grpatch, PU_HWRPATCHINFO, &(model->blendgrpatch)); + grpatch->mipmap = Z_Calloc(sizeof (GLMipmap_t), PU_HWRPATCHINFO, NULL); + } - if (!grpatch->mipmap.downloaded && !grpatch->mipmap.grInfo.data) + if (!grpatch->mipmap->downloaded && !grpatch->mipmap->grInfo.data) { int w = 0, h = 0; #ifdef HAVE_PNG - grpatch->mipmap.grInfo.format = PNG_Load(filename, &w, &h, grpatch); - if (grpatch->mipmap.grInfo.format == 0) + grpatch->mipmap->grInfo.format = PNG_Load(filename, &w, &h, grpatch); + if (grpatch->mipmap->grInfo.format == 0) #endif - grpatch->mipmap.grInfo.format = PCX_Load(filename, &w, &h, grpatch); - if (grpatch->mipmap.grInfo.format == 0) + grpatch->mipmap->grInfo.format = PCX_Load(filename, &w, &h, grpatch); + if (grpatch->mipmap->grInfo.format == 0) { + grpatch->notfound = true;// mark it so its not searched for again repeatedly Z_Free(filename); return; } - grpatch->mipmap.downloaded = 0; - grpatch->mipmap.flags = 0; + grpatch->mipmap->downloaded = 0; + grpatch->mipmap->flags = 0; grpatch->width = (INT16)w; grpatch->height = (INT16)h; - grpatch->mipmap.width = (UINT16)w; - grpatch->mipmap.height = (UINT16)h; + grpatch->mipmap->width = (UINT16)w; + grpatch->mipmap->height = (UINT16)h; // not correct! - grpatch->mipmap.grInfo.smallLodLog2 = GR_LOD_LOG2_256; - grpatch->mipmap.grInfo.largeLodLog2 = GR_LOD_LOG2_256; - grpatch->mipmap.grInfo.aspectRatioLog2 = GR_ASPECT_LOG2_1x1; + grpatch->mipmap->grInfo.smallLodLog2 = GR_LOD_LOG2_256; + grpatch->mipmap->grInfo.largeLodLog2 = GR_LOD_LOG2_256; + grpatch->mipmap->grInfo.aspectRatioLog2 = GR_ASPECT_LOG2_1x1; } - HWD.pfnSetTexture(&grpatch->mipmap); // We do need to do this so that it can be cleared and knows to recreate it when necessary + HWD.pfnSetTexture(grpatch->mipmap); // We do need to do this so that it can be cleared and knows to recreate it when necessary HWR_UnlockCachedPatch(grpatch); Z_Free(filename); @@ -544,7 +548,7 @@ void HWR_InitMD2(void) goto md2found; } } - // no sprite/player skin name found?!? + // no sprite/player skin name found?!?D CONS_Printf("Unknown sprite/player skin %s detected in mdls.dat\n", name); md2found: // move on to next line... @@ -579,7 +583,7 @@ void HWR_AddPlayerMD2(int skin) // For MD2's that were added after startup } } - // Check for any MD2s that match the names of player skins! + // Check for any MD2s that match the names of sprite names! while (fscanf(f, "%19s %31s %f %f", name, filename, &scale, &offset) == 4) { if (stricmp(name, skins[skin].name) == 0) @@ -655,18 +659,24 @@ spritemd2found: // 0.0722 to blue // (See this same define in k_kart.c!) #define SETBRIGHTNESS(brightness,r,g,b) \ - brightness = (UINT8)(((1063*((UINT16)r)/5000) + (3576*((UINT16)g)/5000) + (361*((UINT16)b)/5000)) / 3) + brightness = (UINT8)(((1063*(UINT16)(r))/5000) + ((3576*(UINT16)(g))/5000) + ((361*(UINT16)(b))/5000)) static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, GLMipmap_t *grmip, INT32 skinnum, skincolors_t color) { - UINT8 i; UINT16 w = gpatch->width, h = gpatch->height; UINT32 size = w*h; RGBA_t *image, *blendimage, *cur, blendcolor; + UINT8 translation[16]; // First the color index + UINT8 cutoff[16]; // Brightness cutoff before using the next color + UINT8 translen = 0; + UINT8 i; + + blendcolor = V_GetColor(0); // initialize + memset(translation, 0, sizeof(translation)); + memset(cutoff, 0, sizeof(cutoff)); if (grmip->width == 0) { - grmip->width = gpatch->width; grmip->height = gpatch->height; @@ -676,110 +686,297 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, grmip->grInfo.format = GR_RGBA; } - Z_Free(grmip->grInfo.data); - grmip->grInfo.data = NULL; + if (grmip->grInfo.data) + { + Z_Free(grmip->grInfo.data); + grmip->grInfo.data = NULL; + } cur = Z_Malloc(size*4, PU_HWRCACHE, &grmip->grInfo.data); memset(cur, 0x00, size*4); - image = gpatch->mipmap.grInfo.data; - blendimage = blendgpatch->mipmap.grInfo.data; + image = gpatch->mipmap->grInfo.data; + blendimage = blendgpatch->mipmap->grInfo.data; - // Average all of the translation's colors + // TC_METALSONIC includes an actual skincolor translation, on top of its flashing. + if (skinnum == TC_METALSONIC) + color = SKINCOLOR_BLUEBERRY; + + if (color != SKINCOLOR_NONE) { - const UINT8 div = 6; - const UINT8 start = 4; - UINT32 r, g, b; + UINT8 numdupes = 1; + UINT8 prevdupes = numdupes; - blendcolor = V_GetColor(colortranslations[color][start]); - r = (UINT32)(blendcolor.s.red*blendcolor.s.red); - g = (UINT32)(blendcolor.s.green*blendcolor.s.green); - b = (UINT32)(blendcolor.s.blue*blendcolor.s.blue); + translation[translen] = colortranslations[color][0]; + cutoff[translen] = 255; - for (i = 1; i < div; i++) + for (i = 1; i < 16; i++) { - RGBA_t nextcolor = V_GetColor(colortranslations[color][start+i]); - r += (UINT32)(nextcolor.s.red*nextcolor.s.red); - g += (UINT32)(nextcolor.s.green*nextcolor.s.green); - b += (UINT32)(nextcolor.s.blue*nextcolor.s.blue); + if (translation[translen] == colortranslations[color][i]) + { + numdupes++; + continue; + } + + if (translen > 0) + { + INT16 newcutoff = cutoff[translen-1] - (255 / (16 / prevdupes)); + + if (newcutoff < 0) + newcutoff = 0; + + cutoff[translen] = (UINT8)newcutoff; + } + + prevdupes = numdupes; + numdupes = 1; + translen++; + + translation[translen] = (UINT8)colortranslations[color][i]; } - blendcolor.s.red = (UINT8)(FixedSqrt((r/div)<>FRACBITS); - blendcolor.s.green = (UINT8)(FixedSqrt((g/div)<>FRACBITS); - blendcolor.s.blue = (UINT8)(FixedSqrt((b/div)<>FRACBITS); + translen++; } - // rainbow support, could theoretically support boss ones too - if (skinnum == TC_RAINBOW) + while (size--) { - while (size--) + if (skinnum == TC_BOSS) { - if (image->s.alpha == 0 && blendimage->s.alpha == 0) + // Turn everything below a certain threshold white + if ((image->s.red == image->s.green) && (image->s.green == image->s.blue) && image->s.blue < 127) { - // Don't bother with blending the pixel if the alpha of the blend pixel is 0 - cur->rgba = image->rgba; + // Lactozilla: Invert the colors + cur->s.red = cur->s.green = cur->s.blue = (255 - image->s.blue); } else + { + cur->s.red = image->s.red; + cur->s.green = image->s.green; + cur->s.blue = image->s.blue; + } + + cur->s.alpha = image->s.alpha; + } + else if (skinnum == TC_ALLWHITE) + { + // Turn everything white + cur->s.red = cur->s.green = cur->s.blue = 255; + cur->s.alpha = image->s.alpha; + } + else + { + // All settings that use skincolors! + UINT16 brightness; + + // Everything below requires a blend image + if (blendimage == NULL) + { + cur->rgba = image->rgba; + goto skippixel; + } + + if (translen <= 0) + { + cur->rgba = image->rgba; + goto skippixel; + } + + // Don't bother with blending the pixel if the alpha of the blend pixel is 0 + if (skinnum == TC_RAINBOW) + { + if (image->s.alpha == 0 && blendimage->s.alpha == 0) + { + cur->rgba = image->rgba; + goto skippixel; + } + else + { + UINT16 imagebright, blendbright; + SETBRIGHTNESS(imagebright,image->s.red,image->s.green,image->s.blue); + SETBRIGHTNESS(blendbright,blendimage->s.red,blendimage->s.green,blendimage->s.blue); + // slightly dumb average between the blend image color and base image colour, usually one or the other will be fully opaque anyway + brightness = (imagebright*(255-blendimage->s.alpha))/255 + (blendbright*blendimage->s.alpha)/255; + } + } + else + { + if (blendimage->s.alpha == 0) + { + cur->rgba = image->rgba; + goto skippixel; // for metal sonic blend + } + else + { + SETBRIGHTNESS(brightness,blendimage->s.red,blendimage->s.green,blendimage->s.blue); + } + } + + // Calculate a sort of "gradient" for the skincolor + // (Me splitting this into a function didn't work, so I had to ruin this entire function's groove...) + { + RGBA_t nextcolor; + UINT8 firsti, secondi, mul, mulmax; + INT32 r, g, b; + + // Rainbow needs to find the closest match to the textures themselves, instead of matching brightnesses to other colors. + // Ensue horrible mess. + if (skinnum == TC_RAINBOW) + { + UINT16 brightdif = 256; + UINT8 colorbrightnesses[16]; + INT32 compare, m, d; + + // Ignore pure white & pitch black + if (brightness > 253 || brightness < 2) + { + cur->rgba = image->rgba; + cur++; image++; blendimage++; + continue; + } + + firsti = 0; + mul = 0; + mulmax = 1; + + for (i = 0; i < translen; i++) + { + RGBA_t tempc = V_GetColor(translation[i]); + SETBRIGHTNESS(colorbrightnesses[i], tempc.s.red, tempc.s.green, tempc.s.blue); // store brightnesses for comparison + } + + for (i = 0; i < translen; i++) + { + if (brightness > colorbrightnesses[i]) // don't allow greater matches (because calculating a makeshift gradient for this is already a huge mess as is) + continue; + + compare = abs((INT16)(colorbrightnesses[i]) - (INT16)(brightness)); + + if (compare < brightdif) + { + brightdif = (UINT16)compare; + firsti = i; // best matching color that's equal brightness or darker + } + } + + secondi = firsti+1; // next color in line + + m = (INT16)brightness - (INT16)colorbrightnesses[secondi]; + d = (INT16)colorbrightnesses[firsti] - (INT16)colorbrightnesses[secondi]; + + if (m >= d) + m = d-1; + + mulmax = 16; + + // calculate the "gradient" multiplier based on how close this color is to the one next in line + if (m <= 0 || d <= 0) + mul = 0; + else + mul = (mulmax-1) - ((m * mulmax) / d); + } + else + { + // Just convert brightness to a skincolor value, use distance to next position to find the gradient multipler + firsti = 0; + + for (i = 1; i < translen; i++) + { + if (brightness >= cutoff[i]) + break; + firsti = i; + } + + secondi = firsti+1; + + mulmax = cutoff[firsti] - cutoff[secondi]; + mul = cutoff[firsti] - brightness; + } + + blendcolor = V_GetColor(translation[firsti]); + + if (mul > 0) // If it's 0, then we only need the first color. + { + nextcolor = V_GetColor(translation[secondi]); + + // Find difference between points + r = (INT32)(nextcolor.s.red - blendcolor.s.red); + g = (INT32)(nextcolor.s.green - blendcolor.s.green); + b = (INT32)(nextcolor.s.blue - blendcolor.s.blue); + + // Find the gradient of the two points + r = ((mul * r) / mulmax); + g = ((mul * g) / mulmax); + b = ((mul * b) / mulmax); + + // Add gradient value to color + blendcolor.s.red += r; + blendcolor.s.green += g; + blendcolor.s.blue += b; + } + } + + if (skinnum == TC_RAINBOW) { UINT32 tempcolor; - UINT16 imagebright, blendbright, finalbright, colorbright; - SETBRIGHTNESS(imagebright,image->s.red,image->s.green,image->s.blue); - SETBRIGHTNESS(blendbright,blendimage->s.red,blendimage->s.green,blendimage->s.blue); - // slightly dumb average between the blend image color and base image colour, usually one or the other will be fully opaque anyway - finalbright = (imagebright*(255-blendimage->s.alpha))/255 + (blendbright*blendimage->s.alpha)/255; - SETBRIGHTNESS(colorbright,blendcolor.s.red,blendcolor.s.green,blendcolor.s.blue); + UINT16 colorbright; - tempcolor = (finalbright*blendcolor.s.red)/colorbright; + SETBRIGHTNESS(colorbright,blendcolor.s.red,blendcolor.s.green,blendcolor.s.blue); + if (colorbright == 0) + colorbright = 1; // no dividing by 0 please + + tempcolor = (brightness * blendcolor.s.red) / colorbright; tempcolor = min(255, tempcolor); cur->s.red = (UINT8)tempcolor; - tempcolor = (finalbright*blendcolor.s.green)/colorbright; + + tempcolor = (brightness * blendcolor.s.green) / colorbright; tempcolor = min(255, tempcolor); cur->s.green = (UINT8)tempcolor; - tempcolor = (finalbright*blendcolor.s.blue)/colorbright; + + tempcolor = (brightness * blendcolor.s.blue) / colorbright; tempcolor = min(255, tempcolor); cur->s.blue = (UINT8)tempcolor; cur->s.alpha = image->s.alpha; } - - cur++; image++; blendimage++; - } - } - else - { - while (size--) - { - if (blendimage->s.alpha == 0) - { - // Don't bother with blending the pixel if the alpha of the blend pixel is 0 - cur->rgba = image->rgba; - } else { + // Color strength depends on image alpha INT32 tempcolor; - INT16 tempmult, tempalpha; - tempalpha = -(abs(blendimage->s.red-127)-127)*2; - if (tempalpha > 255) - tempalpha = 255; - else if (tempalpha < 0) - tempalpha = 0; - tempmult = (blendimage->s.red-127)*2; - if (tempmult > 255) - tempmult = 255; - else if (tempmult < 0) - tempmult = 0; - - tempcolor = (image->s.red*(255-blendimage->s.alpha))/255 + ((tempmult + ((tempalpha*blendcolor.s.red)/255)) * blendimage->s.alpha)/255; + tempcolor = ((image->s.red * (255-blendimage->s.alpha)) / 255) + ((blendcolor.s.red * blendimage->s.alpha) / 255); + tempcolor = min(255, tempcolor); cur->s.red = (UINT8)tempcolor; - tempcolor = (image->s.green*(255-blendimage->s.alpha))/255 + ((tempmult + ((tempalpha*blendcolor.s.green)/255)) * blendimage->s.alpha)/255; + + tempcolor = ((image->s.green * (255-blendimage->s.alpha)) / 255) + ((blendcolor.s.green * blendimage->s.alpha) / 255); + tempcolor = min(255, tempcolor); cur->s.green = (UINT8)tempcolor; - tempcolor = (image->s.blue*(255-blendimage->s.alpha))/255 + ((tempmult + ((tempalpha*blendcolor.s.blue)/255)) * blendimage->s.alpha)/255; + + tempcolor = ((image->s.blue * (255-blendimage->s.alpha)) / 255) + ((blendcolor.s.blue * blendimage->s.alpha) / 255); + tempcolor = min(255, tempcolor); cur->s.blue = (UINT8)tempcolor; cur->s.alpha = image->s.alpha; } - cur++; image++; blendimage++; +skippixel: + + // *Now* we can do Metal Sonic's flashing + if (skinnum == TC_METALSONIC) + { + // Blend dark blue into white + if (cur->s.alpha > 0 && cur->s.red == 0 && cur->s.green == 0 && cur->s.blue < 255 && cur->s.blue > 31) + { + // Sal: Invert non-blue + cur->s.red = cur->s.green = (255 - cur->s.blue); + cur->s.blue = 255; + } + + cur->s.alpha = image->s.alpha; + } } + + cur++; image++; + + if (blendimage != NULL) + blendimage++; } return; @@ -795,13 +992,13 @@ static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, INT if (colormap == colormaps || colormap == NULL) { // Don't do any blending - HWD.pfnSetTexture(&gpatch->mipmap); + HWD.pfnSetTexture(gpatch->mipmap); return; } // search for the mimmap // skip the first (no colormap translated) - for (grmip = &gpatch->mipmap; grmip->nextcolormap; ) + for (grmip = gpatch->mipmap; grmip->nextcolormap; ) { grmip = grmip->nextcolormap; if (grmip->colormap == colormap) @@ -837,35 +1034,19 @@ static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, INT // -----------------+ // HWR_DrawMD2 : Draw MD2 -// : (monsters, bonuses, weapons, lights, ...) +// : // Returns : // -----------------+ - /* - wait/stand - death - pain - walk - shoot/fire - die? - atka? - atkb? - attacka/b/c/d? - res? - run? - */ -#define NORMALFOG 0x00000000 -#define FADEFOG 0x19000000 void HWR_DrawMD2(gr_vissprite_t *spr) { - FSurfaceInfo Surf; + md2_t *md2; char filename[64]; INT32 frame = 0; INT32 nextFrame = -1; FTransform p; - md2_t *md2; - UINT8 color[4]; + FSurfaceInfo Surf; if (!cv_grmdls.value) return; @@ -878,8 +1059,8 @@ void HWR_DrawMD2(gr_vissprite_t *spr) if (spr->mobj->subsector) { sector_t *sector = spr->mobj->subsector->sector; - UINT8 lightlevel = 255; extracolormap_t *colormap = sector->extra_colormap; + UINT8 lightlevel = 255; if (sector->numlights) { @@ -902,14 +1083,11 @@ void HWR_DrawMD2(gr_vissprite_t *spr) colormap = sector->extra_colormap; } - if (colormap) - Surf.FlatColor.rgba = HWR_Lighting(lightlevel, colormap->rgba, colormap->fadergba, false, false); - else - Surf.FlatColor.rgba = HWR_Lighting(lightlevel, NORMALFOG, FADEFOG, false, false); + HWR_Lighting(&Surf, lightlevel, colormap); } else { - Surf.FlatColor.rgba = 0xFFFFFFFF; + Surf.PolyColor.rgba = 0xFFFFFFFF; } // Look at HWR_ProjectSprite for more @@ -928,11 +1106,11 @@ void HWR_DrawMD2(gr_vissprite_t *spr) //durs = tics; if (spr->mobj->flags2 & MF2_SHADOW) - Surf.FlatColor.s.alpha = 0x40; + Surf.PolyColor.s.alpha = 0x40; else if (spr->mobj->frame & FF_TRANSMASK) HWR_TranstableToAlpha((spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &Surf); else - Surf.FlatColor.s.alpha = 0xFF; + Surf.PolyColor.s.alpha = 0xFF; // dont forget to enabled the depth test because we can't do this like // before: polygons models are not sorted @@ -967,22 +1145,23 @@ void HWR_DrawMD2(gr_vissprite_t *spr) return; } } - //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 gpatch = md2->grpatch; - if (!gpatch || !gpatch->mipmap.grInfo.format || !gpatch->mipmap.downloaded) + if (!gpatch || ((!gpatch->mipmap->grInfo.format || !gpatch->mipmap->downloaded) && !gpatch->notfound)) md2_loadTexture(md2); gpatch = md2->grpatch; // Load it again, because it isn't being loaded into gpatch after md2_loadtexture... - if ((gpatch && gpatch->mipmap.grInfo.format) // don't load the blend texture if the base texture isn't available - && (!md2->blendgrpatch || !((GLPatch_t *)md2->blendgrpatch)->mipmap.grInfo.format || !((GLPatch_t *)md2->blendgrpatch)->mipmap.downloaded)) + if ((gpatch && gpatch->mipmap->grInfo.format) // don't load the blend texture if the base texture isn't available + && (!md2->blendgrpatch + || ((!((GLPatch_t *)md2->blendgrpatch)->mipmap->grInfo.format || !((GLPatch_t *)md2->blendgrpatch)->mipmap->downloaded) + && !((GLPatch_t *)md2->blendgrpatch)->notfound))) md2_loadBlendTexture(md2); - if (gpatch && gpatch->mipmap.grInfo.format) // else if meant that if a texture couldn't be loaded, it would just end up using something else's texture + if (gpatch && gpatch->mipmap->grInfo.format) // else if meant that if a texture couldn't be loaded, it would just end up using something else's texture { if ((skincolors_t)spr->mobj->color != SKINCOLOR_NONE && - md2->blendgrpatch && ((GLPatch_t *)md2->blendgrpatch)->mipmap.grInfo.format + md2->blendgrpatch && ((GLPatch_t *)md2->blendgrpatch)->mipmap->grInfo.format && gpatch->width == ((GLPatch_t *)md2->blendgrpatch)->width && gpatch->height == ((GLPatch_t *)md2->blendgrpatch)->height) { INT32 skinnum = TC_DEFAULT; @@ -1013,7 +1192,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr) else { // This is safe, since we know the texture has been downloaded - HWD.pfnSetTexture(&gpatch->mipmap); + HWD.pfnSetTexture(gpatch->mipmap); } } else @@ -1103,11 +1282,6 @@ void HWR_DrawMD2(gr_vissprite_t *spr) } #endif - color[0] = Surf.FlatColor.s.red; - color[1] = Surf.FlatColor.s.green; - color[2] = Surf.FlatColor.s.blue; - color[3] = Surf.FlatColor.s.alpha; - // SRB2CBTODO: MD2 scaling support finalscale *= FIXED_TO_FLOAT(spr->mobj->scale); @@ -1116,7 +1290,8 @@ void HWR_DrawMD2(gr_vissprite_t *spr) p.mirror = atransform.mirror; // from Kart #endif - HWD.pfnDrawModel(md2->model, frame, durs, tics, nextFrame, &p, finalscale, flip, color); + HWD.pfnSetShader(4); // model shader + HWD.pfnDrawModel(md2->model, frame, durs, tics, nextFrame, &p, finalscale, flip, &Surf); } } diff --git a/src/hardware/hw_md2.h b/src/hardware/hw_md2.h index 57d8026b9..fab8e6ad9 100644 --- a/src/hardware/hw_md2.h +++ b/src/hardware/hw_md2.h @@ -1,18 +1,12 @@ -// Emacs style mode select -*- C++ -*- +// SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// +// Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2019 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 -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// +// 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 /// \brief MD2 Handling diff --git a/src/hardware/hw_trick.c b/src/hardware/hw_trick.c index 97d86b944..de4a76c59 100644 --- a/src/hardware/hw_trick.c +++ b/src/hardware/hw_trick.c @@ -44,6 +44,7 @@ #include "../doomstat.h" #ifdef HWRENDER +#include "hw_main.h" #include "hw_glob.h" #include "hw_dll.h" #include "../r_local.h" diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 9fcc8d157..f06020634 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -1,18 +1,12 @@ -// Emacs style mode select -*- C++ -*- +// SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- +// Copyright (C) 1993-1996 by id Software, Inc. +// Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2019 by Sonic Team Junior. // -// Copyright (C) 1998-2018 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 -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// +// 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 /// \brief OpenGL API for Sonic Robo Blast 2 @@ -32,6 +26,8 @@ #include "r_opengl.h" #include "r_vbo.h" +#include "../../p_tick.h" // for leveltime (NOTE: THIS IS BAD, FIGURE OUT HOW TO PROPERLY IMPLEMENT gl_leveltime) + #if defined (HWRENDER) && !defined (NOROPENGL) struct GLRGBAFloat @@ -49,8 +45,7 @@ static const GLubyte white[4] = { 255, 255, 255, 255 }; // ========================================================================== // With OpenGL 1.1+, the first texture should be 1 -#define NOTEXTURE_NUM 1 // small white texture -#define FIRST_TEX_AVAIL (NOTEXTURE_NUM + 1) +#define NOTEXTURE_NUM 0 #define N_PI_DEMI (M_PIl/2.0f) //(1.5707963268f) @@ -63,13 +58,8 @@ static float NEAR_CLIPPING_PLANE = NZCLIP_PLANE; // ************************************************************************** -static GLuint NextTexAvail = FIRST_TEX_AVAIL; static GLuint tex_downloaded = 0; static GLfloat fov = 90.0f; -#if 0 -static GLuint pal_col = 0; -static FRGBAFloat const_pal_col; -#endif static FBITFIELD CurrentPolyFlags; static FTextureInfo* gr_cachetail = NULL; @@ -87,30 +77,28 @@ static GLint mag_filter = GL_LINEAR; static GLint anisotropic_filter = 0; static FTransform md2_transform; +const GLubyte *gl_version = NULL; +const GLubyte *gl_renderer = NULL; const GLubyte *gl_extensions = NULL; //Hurdler: 04/10/2000: added for the kick ass coronas as Boris wanted;-) -static GLfloat modelMatrix[16]; -static GLfloat projMatrix[16]; -static GLint viewport[4]; +static GLfloat modelMatrix[16]; +static GLfloat projMatrix[16]; +static GLint viewport[4]; + +#ifdef USE_PALETTED_TEXTURE + PFNGLCOLORTABLEEXTPROC glColorTableEXT = NULL; + GLubyte palette_tex[256*3]; +#endif -// Yay for arbitrary numbers! NextTexAvail is buggy for some reason. // Sryder: NextTexAvail is broken for these because palette changes or changes to the texture filter or antialiasing // flush all of the stored textures, leaving them unavailable at times such as between levels -// These need to start at 0 and be set to their number, and be reset to 0 when deleted so that intel GPUs +// These need to start at 0 and be set to their number, and be reset to 0 when deleted so that Intel GPUs // can know when the textures aren't there, as textures are always considered resident in their virtual memory -// TODO: Store them in a more normal way -#define SCRTEX_SCREENTEXTURE 4294967295U -#define SCRTEX_STARTSCREENWIPE 4294967294U -#define SCRTEX_ENDSCREENWIPE 4294967293U -#define SCRTEX_FINALSCREENTEXTURE 4294967292U static GLuint screentexture = 0; static GLuint startScreenWipe = 0; static GLuint endScreenWipe = 0; static GLuint finalScreenTexture = 0; -#if 0 -GLuint screentexture = FIRST_TEX_AVAIL; -#endif // shortcut for ((float)1/i) static const GLfloat byte2float[256] = { @@ -148,31 +136,32 @@ static const GLfloat byte2float[256] = { 0.972549f, 0.976471f, 0.980392f, 0.984314f, 0.988235f, 0.992157f, 0.996078f, 1.000000f }; -float byteasfloat(UINT8 fbyte) -{ - return (float)(byte2float[fbyte]*2.0f); -} - -static I_Error_t I_Error_GL = NULL; - // -----------------+ -// DBG_Printf : Output error messages to debug log if DEBUG_TO_FILE is defined, +// GL_DBG_Printf : Output debug messages to debug log if DEBUG_TO_FILE is defined, // : else do nothing // Returns : // -----------------+ -FUNCPRINTF void DBG_Printf(const char *lpFmt, ...) + +#ifdef DEBUG_TO_FILE +FILE *gllogstream; +#endif + +FUNCPRINTF void GL_DBG_Printf(const char *format, ...) { #ifdef DEBUG_TO_FILE - char str[4096] = ""; + char str[4096] = ""; va_list arglist; - va_start (arglist, lpFmt); - vsnprintf (str, 4096, lpFmt, arglist); - va_end (arglist); - if (gllogstream) - fwrite(str, strlen(str), 1, gllogstream); + if (!gllogstream) + gllogstream = fopen("ogllog.txt", "w"); + + va_start(arglist, format); + vsnprintf(str, 4096, format, arglist); + va_end(arglist); + + fwrite(str, strlen(str), 1, gllogstream); #else - (void)lpFmt; + (void)format; #endif } @@ -190,9 +179,6 @@ FUNCPRINTF void DBG_Printf(const char *lpFmt, ...) #define pglEnable glEnable #define pglDisable glDisable #define pglGetFloatv glGetFloatv -//glGetIntegerv -//glGetString -#define pglHint glHint /* Depth Buffer */ #define pglClearDepth glClearDepth @@ -206,7 +192,7 @@ FUNCPRINTF void DBG_Printf(const char *lpFmt, ...) #define pglPushMatrix glPushMatrix #define pglPopMatrix glPopMatrix #define pglLoadIdentity glLoadIdentity -#define pglMultMatrixf glMultMatrixf +#define pglMultMatrixd glMultMatrixd #define pglRotatef glRotatef #define pglScalef glScalef #define pglTranslatef glTranslatef @@ -231,6 +217,7 @@ FUNCPRINTF void DBG_Printf(const char *lpFmt, ...) #define pglLightfv glLightfv #define pglLightModelfv glLightModelfv #define pglMaterialfv glMaterialfv +#define pglMateriali glMateriali /* Raster functions */ #define pglPixelStorei glPixelStorei @@ -247,6 +234,7 @@ FUNCPRINTF void DBG_Printf(const char *lpFmt, ...) /* 1.1 functions */ /* texture objects */ //GL_EXT_texture_object +#define pglGenTextures glGenTextures #define pglDeleteTextures glDeleteTextures #define pglBindTexture glBindTexture /* texture mapping */ //GL_EXT_copy_texture @@ -259,7 +247,6 @@ FUNCPRINTF void DBG_Printf(const char *lpFmt, ...) /* Miscellaneous */ typedef void (APIENTRY * PFNglClearColor) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); static PFNglClearColor pglClearColor; -//glClear typedef void (APIENTRY * PFNglColorMask) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); static PFNglColorMask pglColorMask; typedef void (APIENTRY * PFNglAlphaFunc) (GLenum func, GLclampf ref); @@ -278,8 +265,6 @@ typedef void (APIENTRY * PFNglDisable) (GLenum cap); static PFNglDisable pglDisable; typedef void (APIENTRY * PFNglGetFloatv) (GLenum pname, GLfloat *params); static PFNglGetFloatv pglGetFloatv; -//glGetIntegerv -//glGetString /* Depth Buffer */ typedef void (APIENTRY * PFNglClearDepth) (GLclampd depth); @@ -337,7 +322,6 @@ static PFNglBufferData pglBufferData; typedef void (APIENTRY * PFNglDeleteBuffers) (GLsizei n, const GLuint *buffers); static PFNglDeleteBuffers pglDeleteBuffers; - /* Lighting */ typedef void (APIENTRY * PFNglShadeModel) (GLenum mode); static PFNglShadeModel pglShadeModel; @@ -347,6 +331,8 @@ typedef void (APIENTRY * PFNglLightModelfv) (GLenum pname, GLfloat *params); static PFNglLightModelfv pglLightModelfv; typedef void (APIENTRY * PFNglMaterialfv) (GLint face, GLenum pname, GLfloat *params); static PFNglMaterialfv pglMaterialfv; +typedef void (APIENTRY * PFNglMateriali) (GLint face, GLenum pname, GLint param); +static PFNglMateriali pglMateriali; /* Raster functions */ typedef void (APIENTRY * PFNglPixelStorei) (GLenum pname, GLint param); @@ -370,6 +356,8 @@ static PFNglFogfv pglFogfv; /* 1.1 functions */ /* texture objects */ //GL_EXT_texture_object +typedef void (APIENTRY * PFNglGenTextures) (GLsizei n, const GLuint *textures); +static PFNglGenTextures pglGenTextures; typedef void (APIENTRY * PFNglDeleteTextures) (GLsizei n, const GLuint *textures); static PFNglDeleteTextures pglDeleteTextures; typedef void (APIENTRY * PFNglBindTexture) (GLenum target, GLuint texture); @@ -394,6 +382,10 @@ static PFNglMultiTexCoord2fv pglMultiTexCoord2fv; typedef void (APIENTRY *PFNglClientActiveTexture) (GLenum); static PFNglClientActiveTexture pglClientActiveTexture; +// sky dome needs this +typedef void (APIENTRY *PFNglColorPointer) (GLint, GLenum, GLsizei, const GLvoid*); +static PFNglColorPointer pglColorPointer; + /* 1.2 Parms */ /* GL_CLAMP_TO_EDGE_EXT */ #ifndef GL_CLAMP_TO_EDGE @@ -421,7 +413,7 @@ boolean SetupGLfunc(void) func = GetGLFunc(#proc); \ if (!func) \ { \ - DBG_Printf("failed to get OpenGL function: %s", #proc); \ + GL_DBG_Printf("failed to get OpenGL function: %s\n", #proc); \ } \ GETOPENGLFUNC(pglClearColor, glClearColor) @@ -439,22 +431,23 @@ boolean SetupGLfunc(void) GETOPENGLFUNC(pglGetIntegerv, glGetIntegerv) GETOPENGLFUNC(pglGetString, glGetString) - GETOPENGLFUNC(pglClearDepth , glClearDepth) - GETOPENGLFUNC(pglDepthFunc , glDepthFunc) - GETOPENGLFUNC(pglDepthMask , glDepthMask) - GETOPENGLFUNC(pglDepthRange , glDepthRange) + GETOPENGLFUNC(pglClearDepth, glClearDepth) + GETOPENGLFUNC(pglDepthFunc, glDepthFunc) + GETOPENGLFUNC(pglDepthMask, glDepthMask) + GETOPENGLFUNC(pglDepthRange, glDepthRange) - GETOPENGLFUNC(pglMatrixMode , glMatrixMode) - GETOPENGLFUNC(pglViewport , glViewport) - GETOPENGLFUNC(pglPushMatrix , glPushMatrix) - GETOPENGLFUNC(pglPopMatrix , glPopMatrix) - GETOPENGLFUNC(pglLoadIdentity , glLoadIdentity) - GETOPENGLFUNC(pglMultMatrixf , glMultMatrixf) - GETOPENGLFUNC(pglRotatef , glRotatef) - GETOPENGLFUNC(pglScalef , glScalef) - GETOPENGLFUNC(pglTranslatef , glTranslatef) + GETOPENGLFUNC(pglMatrixMode, glMatrixMode) + GETOPENGLFUNC(pglViewport, glViewport) + GETOPENGLFUNC(pglPushMatrix, glPushMatrix) + GETOPENGLFUNC(pglPopMatrix, glPopMatrix) + GETOPENGLFUNC(pglLoadIdentity, glLoadIdentity) + GETOPENGLFUNC(pglMultMatrixf, glMultMatrixf) + GETOPENGLFUNC(pglRotatef, glRotatef) + GETOPENGLFUNC(pglScalef, glScalef) + GETOPENGLFUNC(pglTranslatef, glTranslatef) GETOPENGLFUNC(pglColor4ubv, glColor4ubv) + GETOPENGLFUNC(pglVertexPointer, glVertexPointer) GETOPENGLFUNC(pglNormalPointer, glNormalPointer) GETOPENGLFUNC(pglTexCoordPointer, glTexCoordPointer) @@ -463,38 +456,329 @@ boolean SetupGLfunc(void) GETOPENGLFUNC(pglEnableClientState, glEnableClientState) GETOPENGLFUNC(pglDisableClientState, glDisableClientState) - GETOPENGLFUNC(pglShadeModel , glShadeModel) + GETOPENGLFUNC(pglShadeModel, glShadeModel) GETOPENGLFUNC(pglLightfv, glLightfv) - GETOPENGLFUNC(pglLightModelfv , glLightModelfv) - GETOPENGLFUNC(pglMaterialfv , glMaterialfv) + GETOPENGLFUNC(pglLightModelfv, glLightModelfv) + GETOPENGLFUNC(pglMaterialfv, glMaterialfv) + GETOPENGLFUNC(pglMateriali, glMateriali) - GETOPENGLFUNC(pglPixelStorei , glPixelStorei) - GETOPENGLFUNC(pglReadPixels , glReadPixels) + GETOPENGLFUNC(pglPixelStorei, glPixelStorei) + GETOPENGLFUNC(pglReadPixels, glReadPixels) - GETOPENGLFUNC(pglTexEnvi , glTexEnvi) - GETOPENGLFUNC(pglTexParameteri , glTexParameteri) - GETOPENGLFUNC(pglTexImage2D , glTexImage2D) + GETOPENGLFUNC(pglTexEnvi, glTexEnvi) + GETOPENGLFUNC(pglTexParameteri, glTexParameteri) + GETOPENGLFUNC(pglTexImage2D, glTexImage2D) - GETOPENGLFUNC(pglFogf , glFogf) - GETOPENGLFUNC(pglFogfv , glFogfv) + GETOPENGLFUNC(pglFogf, glFogf) + GETOPENGLFUNC(pglFogfv, glFogfv) - GETOPENGLFUNC(pglDeleteTextures , glDeleteTextures) - GETOPENGLFUNC(pglBindTexture , glBindTexture) + GETOPENGLFUNC(pglGenTextures, glGenTextures) + GETOPENGLFUNC(pglDeleteTextures, glDeleteTextures) + GETOPENGLFUNC(pglBindTexture, glBindTexture) - GETOPENGLFUNC(pglCopyTexImage2D , glCopyTexImage2D) - GETOPENGLFUNC(pglCopyTexSubImage2D , glCopyTexSubImage2D) + GETOPENGLFUNC(pglCopyTexImage2D, glCopyTexImage2D) + GETOPENGLFUNC(pglCopyTexSubImage2D, glCopyTexSubImage2D) #undef GETOPENGLFUNC - - pgluBuild2DMipmaps = GetGLFunc("gluBuild2DMipmaps"); - #endif return true; } -// This has to be done after the context is created so the version number can be obtained -// This is stupid -- even some of the oldest usable OpenGL hardware today supports 1.3-level featureset. -boolean SetupGLFunc13(void) +#ifdef GL_SHADERS +typedef GLuint (APIENTRY *PFNglCreateShader) (GLenum); +typedef void (APIENTRY *PFNglShaderSource) (GLuint, GLsizei, const GLchar**, GLint*); +typedef void (APIENTRY *PFNglCompileShader) (GLuint); +typedef void (APIENTRY *PFNglGetShaderiv) (GLuint, GLenum, GLint*); +typedef void (APIENTRY *PFNglGetShaderInfoLog) (GLuint, GLsizei, GLsizei*, GLchar*); +typedef void (APIENTRY *PFNglDeleteShader) (GLuint); +typedef GLuint (APIENTRY *PFNglCreateProgram) (void); +typedef void (APIENTRY *PFNglAttachShader) (GLuint, GLuint); +typedef void (APIENTRY *PFNglLinkProgram) (GLuint); +typedef void (APIENTRY *PFNglGetProgramiv) (GLuint, GLenum, GLint*); +typedef void (APIENTRY *PFNglUseProgram) (GLuint); +typedef void (APIENTRY *PFNglUniform1i) (GLint, GLint); +typedef void (APIENTRY *PFNglUniform1f) (GLint, GLfloat); +typedef void (APIENTRY *PFNglUniform2f) (GLint, GLfloat, GLfloat); +typedef void (APIENTRY *PFNglUniform3f) (GLint, GLfloat, GLfloat, GLfloat); +typedef void (APIENTRY *PFNglUniform4f) (GLint, GLfloat, GLfloat, GLfloat, GLfloat); +typedef void (APIENTRY *PFNglUniform1fv) (GLint, GLsizei, const GLfloat*); +typedef void (APIENTRY *PFNglUniform2fv) (GLint, GLsizei, const GLfloat*); +typedef void (APIENTRY *PFNglUniform3fv) (GLint, GLsizei, const GLfloat*); +typedef GLint (APIENTRY *PFNglGetUniformLocation) (GLuint, const GLchar*); + +static PFNglCreateShader pglCreateShader; +static PFNglShaderSource pglShaderSource; +static PFNglCompileShader pglCompileShader; +static PFNglGetShaderiv pglGetShaderiv; +static PFNglGetShaderInfoLog pglGetShaderInfoLog; +static PFNglDeleteShader pglDeleteShader; +static PFNglCreateProgram pglCreateProgram; +static PFNglAttachShader pglAttachShader; +static PFNglLinkProgram pglLinkProgram; +static PFNglGetProgramiv pglGetProgramiv; +static PFNglUseProgram pglUseProgram; +static PFNglUniform1i pglUniform1i; +static PFNglUniform1f pglUniform1f; +static PFNglUniform2f pglUniform2f; +static PFNglUniform3f pglUniform3f; +static PFNglUniform4f pglUniform4f; +static PFNglUniform1fv pglUniform1fv; +static PFNglUniform2fv pglUniform2fv; +static PFNglUniform3fv pglUniform3fv; +static PFNglGetUniformLocation pglGetUniformLocation; + +#define MAXSHADERS 16 +#define MAXSHADERPROGRAMS 16 + +// 18032019 +static char *gl_customvertexshaders[MAXSHADERS]; +static char *gl_customfragmentshaders[MAXSHADERS]; + +static boolean gl_allowshaders = false; +static boolean gl_shadersenabled = false; +static GLuint gl_currentshaderprogram = 0; +static boolean gl_shaderprogramchanged = true; + +static boolean gl_batching = false;// are we currently collecting batches? + +// 13062019 +typedef enum +{ + // lighting + gluniform_poly_color, + gluniform_tint_color, + gluniform_fade_color, + gluniform_lighting, + gluniform_fade_start, + gluniform_fade_end, + + // misc. (custom shaders) + gluniform_leveltime, + + gluniform_max, +} gluniform_t; + +typedef struct gl_shaderprogram_s +{ + GLuint program; + boolean custom; + GLint uniforms[gluniform_max+1]; +} gl_shaderprogram_t; +static gl_shaderprogram_t gl_shaderprograms[MAXSHADERPROGRAMS]; + +// ======================== +// Fragment shader macros +// ======================== + +// +// GLSL Software fragment shader +// + +#define GLSL_DOOM_COLORMAP \ + "float R_DoomColormap(float light, float z)\n" \ + "{\n" \ + "float lightnum = clamp(light / 17.0, 0.0, 15.0);\n" \ + "float lightz = clamp(z / 16.0, 0.0, 127.0);\n" \ + "float startmap = (15.0 - lightnum) * 4.0;\n" \ + "float scale = 160.0 / (lightz + 1.0);\n" \ + "return startmap - scale * 0.5;\n" \ + "}\n" + +#define GLSL_DOOM_LIGHT_EQUATION \ + "float R_DoomLightingEquation(float light)\n" \ + "{\n" \ + "float z = gl_FragCoord.z / gl_FragCoord.w;\n" \ + "float colormap = floor(R_DoomColormap(light, z)) + 0.5;\n" \ + "return clamp(colormap, 0.0, 31.0) / 32.0;\n" \ + "}\n" + +#define GLSL_SOFTWARE_TINT_EQUATION \ + "if (tint_color.a > 0.0) {\n" \ + "float color_bright = sqrt((base_color.r * base_color.r) + (base_color.g * base_color.g) + (base_color.b * base_color.b));\n" \ + "float strength = sqrt(9.0 * tint_color.a);\n" \ + "final_color.r = clamp((color_bright * (tint_color.r * strength)) + (base_color.r * (1.0 - strength)), 0.0, 1.0);\n" \ + "final_color.g = clamp((color_bright * (tint_color.g * strength)) + (base_color.g * (1.0 - strength)), 0.0, 1.0);\n" \ + "final_color.b = clamp((color_bright * (tint_color.b * strength)) + (base_color.b * (1.0 - strength)), 0.0, 1.0);\n" \ + "}\n" + +#define GLSL_SOFTWARE_FADE_EQUATION \ + "float darkness = R_DoomLightingEquation(lighting);\n" \ + "if (fade_start != 0.0 || fade_end != 31.0) {\n" \ + "float fs = fade_start / 31.0;\n" \ + "float fe = fade_end / 31.0;\n" \ + "float fd = fe - fs;\n" \ + "darkness = clamp((darkness - fs) * (1.0 / fd), 0.0, 1.0);\n" \ + "}\n" \ + "final_color = mix(final_color, fade_color, darkness);\n" + +#define GLSL_SOFTWARE_FRAGMENT_SHADER \ + "uniform sampler2D tex;\n" \ + "uniform vec4 poly_color;\n" \ + "uniform vec4 tint_color;\n" \ + "uniform vec4 fade_color;\n" \ + "uniform float lighting;\n" \ + "uniform float fade_start;\n" \ + "uniform float fade_end;\n" \ + GLSL_DOOM_COLORMAP \ + GLSL_DOOM_LIGHT_EQUATION \ + "void main(void) {\n" \ + "vec4 texel = texture2D(tex, gl_TexCoord[0].st);\n" \ + "vec4 base_color = texel * poly_color;\n" \ + "vec4 final_color = base_color;\n" \ + GLSL_SOFTWARE_TINT_EQUATION \ + GLSL_SOFTWARE_FADE_EQUATION \ + "final_color.a = texel.a * poly_color.a;\n" \ + "gl_FragColor = final_color;\n" \ + "}\0" + +// +// Water surface shader +// +// Mostly guesstimated, rather than the rest being built off Software science. +// Still needs to distort things underneath/around the water... +// + +#define GLSL_WATER_FRAGMENT_SHADER \ + "uniform sampler2D tex;\n" \ + "uniform vec4 poly_color;\n" \ + "uniform vec4 tint_color;\n" \ + "uniform vec4 fade_color;\n" \ + "uniform float lighting;\n" \ + "uniform float fade_start;\n" \ + "uniform float fade_end;\n" \ + "uniform float leveltime;\n" \ + "const float freq = 0.025;\n" \ + "const float amp = 0.025;\n" \ + "const float speed = 2.0;\n" \ + "const float pi = 3.14159;\n" \ + GLSL_DOOM_COLORMAP \ + GLSL_DOOM_LIGHT_EQUATION \ + "void main(void) {\n" \ + "float z = (gl_FragCoord.z / gl_FragCoord.w) / 2.0;\n" \ + "float a = -pi * (z * freq) + (leveltime * speed);\n" \ + "float sdistort = sin(a) * amp;\n" \ + "float cdistort = cos(a) * amp;\n" \ + "vec4 texel = texture2D(tex, vec2(gl_TexCoord[0].s - sdistort, gl_TexCoord[0].t - cdistort));\n" \ + "vec4 base_color = texel * poly_color;\n" \ + "vec4 final_color = base_color;\n" \ + GLSL_SOFTWARE_TINT_EQUATION \ + GLSL_SOFTWARE_FADE_EQUATION \ + "final_color.a = texel.a * poly_color.a;\n" \ + "gl_FragColor = final_color;\n" \ + "}\0" + +// +// Fog block shader +// +// Alpha of the planes themselves are still slightly off -- see HWR_FogBlockAlpha +// + +#define GLSL_FOG_FRAGMENT_SHADER \ + "uniform vec4 tint_color;\n" \ + "uniform vec4 fade_color;\n" \ + "uniform float lighting;\n" \ + "uniform float fade_start;\n" \ + "uniform float fade_end;\n" \ + GLSL_DOOM_COLORMAP \ + GLSL_DOOM_LIGHT_EQUATION \ + "void main(void) {\n" \ + "vec4 base_color = gl_Color;\n" \ + "vec4 final_color = base_color;\n" \ + GLSL_SOFTWARE_TINT_EQUATION \ + GLSL_SOFTWARE_FADE_EQUATION \ + "gl_FragColor = final_color;\n" \ + "}\0" + +// +// GLSL generic fragment shader +// + +#define GLSL_DEFAULT_FRAGMENT_SHADER \ + "uniform sampler2D tex;\n" \ + "uniform vec4 poly_color;\n" \ + "void main(void) {\n" \ + "gl_FragColor = texture2D(tex, gl_TexCoord[0].st) * poly_color;\n" \ + "}\0" + +static const char *fragment_shaders[] = { + // Default fragment shader + GLSL_DEFAULT_FRAGMENT_SHADER, + + // Floor fragment shader + GLSL_SOFTWARE_FRAGMENT_SHADER, + + // Wall fragment shader + GLSL_SOFTWARE_FRAGMENT_SHADER, + + // Sprite fragment shader + GLSL_SOFTWARE_FRAGMENT_SHADER, + + // Model fragment shader + GLSL_SOFTWARE_FRAGMENT_SHADER, + + // Water fragment shader + GLSL_WATER_FRAGMENT_SHADER, + + // Fog fragment shader + GLSL_FOG_FRAGMENT_SHADER, + + // Sky fragment shader + "uniform sampler2D tex;\n" + "void main(void) {\n" + "gl_FragColor = texture2D(tex, gl_TexCoord[0].st);\n" + "}\0", + + NULL, +}; + +// ====================== +// Vertex shader macros +// ====================== + +// +// GLSL generic vertex shader +// + +#define GLSL_DEFAULT_VERTEX_SHADER \ + "void main()\n" \ + "{\n" \ + "gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;\n" \ + "gl_FrontColor = gl_Color;\n" \ + "gl_TexCoord[0].xy = gl_MultiTexCoord0.xy;\n" \ + "gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;\n" \ + "}\0" + +static const char *vertex_shaders[] = { + // Default vertex shader + GLSL_DEFAULT_VERTEX_SHADER, + + // Floor vertex shader + GLSL_DEFAULT_VERTEX_SHADER, + + // Wall vertex shader + GLSL_DEFAULT_VERTEX_SHADER, + + // Sprite vertex shader + GLSL_DEFAULT_VERTEX_SHADER, + + // Model vertex shader + GLSL_DEFAULT_VERTEX_SHADER, + + // Water vertex shader + GLSL_DEFAULT_VERTEX_SHADER, + + // Fog vertex shader + GLSL_DEFAULT_VERTEX_SHADER, + + // Sky vertex shader + GLSL_DEFAULT_VERTEX_SHADER, + + NULL, +}; + +#endif // GL_SHADERS + +void SetupGLFunc4(void) { pglActiveTexture = GetGLFunc("glActiveTexture"); pglMultiTexCoord2f = GetGLFunc("glMultiTexCoord2f"); @@ -504,17 +788,224 @@ boolean SetupGLFunc13(void) pglBindBuffer = GetGLFunc("glBindBuffer"); pglBufferData = GetGLFunc("glBufferData"); pglDeleteBuffers = GetGLFunc("glDeleteBuffers"); + pglColorPointer = GetGLFunc("glColorPointer"); +#ifdef GL_SHADERS + pglCreateShader = GetGLFunc("glCreateShader"); + pglShaderSource = GetGLFunc("glShaderSource"); + pglCompileShader = GetGLFunc("glCompileShader"); + pglGetShaderiv = GetGLFunc("glGetShaderiv"); + pglGetShaderInfoLog = GetGLFunc("glGetShaderInfoLog"); + pglDeleteShader = GetGLFunc("glDeleteShader"); + pglCreateProgram = GetGLFunc("glCreateProgram"); + pglAttachShader = GetGLFunc("glAttachShader"); + pglLinkProgram = GetGLFunc("glLinkProgram"); + pglGetProgramiv = GetGLFunc("glGetProgramiv"); + pglUseProgram = GetGLFunc("glUseProgram"); + pglUniform1i = GetGLFunc("glUniform1i"); + pglUniform1f = GetGLFunc("glUniform1f"); + pglUniform2f = GetGLFunc("glUniform2f"); + pglUniform3f = GetGLFunc("glUniform3f"); + pglUniform4f = GetGLFunc("glUniform4f"); + pglUniform1fv = GetGLFunc("glUniform1fv"); + pglUniform2fv = GetGLFunc("glUniform2fv"); + pglUniform3fv = GetGLFunc("glUniform3fv"); + pglGetUniformLocation = GetGLFunc("glGetUniformLocation"); +#endif + + // GLU + pgluBuild2DMipmaps = GetGLFunc("gluBuild2DMipmaps"); +} + +// jimita +EXPORT boolean HWRAPI(LoadShaders) (void) +{ +#ifdef GL_SHADERS + GLuint gl_vertShader, gl_fragShader; + GLint i, result; + + if (!pglUseProgram) return false; + + gl_customvertexshaders[0] = NULL; + gl_customfragmentshaders[0] = NULL; + + for (i = 0; vertex_shaders[i] && fragment_shaders[i]; i++) + { + gl_shaderprogram_t *shader; + const GLchar* vert_shader = vertex_shaders[i]; + const GLchar* frag_shader = fragment_shaders[i]; + boolean custom = ((gl_customvertexshaders[i] || gl_customfragmentshaders[i]) && (i > 0)); + + // 18032019 + if (gl_customvertexshaders[i]) + vert_shader = gl_customvertexshaders[i]; + if (gl_customfragmentshaders[i]) + frag_shader = gl_customfragmentshaders[i]; + + if (i >= MAXSHADERS) + break; + if (i >= MAXSHADERPROGRAMS) + break; + + // + // Load and compile vertex shader + // + gl_vertShader = pglCreateShader(GL_VERTEX_SHADER); + if (!gl_vertShader) + I_Error("Hardware driver: Error creating vertex shader %d", i); + + pglShaderSource(gl_vertShader, 1, &vert_shader, NULL); + pglCompileShader(gl_vertShader); + + // check for compile errors + pglGetShaderiv(gl_vertShader, GL_COMPILE_STATUS, &result); + if (result == GL_FALSE) + { + GLchar* infoLog; + GLint logLength; + + pglGetShaderiv(gl_vertShader, GL_INFO_LOG_LENGTH, &logLength); + + infoLog = malloc(logLength); + pglGetShaderInfoLog(gl_vertShader, logLength, NULL, infoLog); + + I_Error("Hardware driver: Error compiling vertex shader %d\n%s", i, infoLog); + } + + // + // Load and compile fragment shader + // + gl_fragShader = pglCreateShader(GL_FRAGMENT_SHADER); + if (!gl_fragShader) + I_Error("Hardware driver: Error creating fragment shader %d", i); + + pglShaderSource(gl_fragShader, 1, &frag_shader, NULL); + pglCompileShader(gl_fragShader); + + // check for compile errors + pglGetShaderiv(gl_fragShader, GL_COMPILE_STATUS, &result); + if (result == GL_FALSE) + { + GLchar* infoLog; + GLint logLength; + + pglGetShaderiv(gl_fragShader, GL_INFO_LOG_LENGTH, &logLength); + + infoLog = malloc(logLength); + pglGetShaderInfoLog(gl_fragShader, logLength, NULL, infoLog); + + I_Error("Hardware driver: Error compiling fragment shader %d\n%s", i, infoLog); + } + + shader = &gl_shaderprograms[i]; + shader->program = pglCreateProgram(); + shader->custom = custom; + pglAttachShader(shader->program, gl_vertShader); + pglAttachShader(shader->program, gl_fragShader); + pglLinkProgram(shader->program); + + // check link status + pglGetProgramiv(shader->program, GL_LINK_STATUS, &result); + if (result != GL_TRUE) + I_Error("Hardware driver: Error linking shader program %d", i); + + // delete the shader objects + pglDeleteShader(gl_vertShader); + pglDeleteShader(gl_fragShader); + + // 13062019 +#define GETUNI(uniform) pglGetUniformLocation(shader->program, uniform); + + // lighting + shader->uniforms[gluniform_poly_color] = GETUNI("poly_color"); + shader->uniforms[gluniform_tint_color] = GETUNI("tint_color"); + shader->uniforms[gluniform_fade_color] = GETUNI("fade_color"); + shader->uniforms[gluniform_lighting] = GETUNI("lighting"); + shader->uniforms[gluniform_fade_start] = GETUNI("fade_start"); + shader->uniforms[gluniform_fade_end] = GETUNI("fade_end"); + + // misc. (custom shaders) + shader->uniforms[gluniform_leveltime] = GETUNI("leveltime"); + +#undef GETUNI + } +#endif return true; } +// +// Custom shader loading +// +EXPORT void HWRAPI(LoadCustomShader) (int number, char *shader, size_t size, boolean fragment) +{ +#ifdef GL_SHADERS + if (!pglUseProgram) return; + if (number < 1 || number > MAXSHADERS) + I_Error("LoadCustomShader(): cannot load shader %d (max %d)", number, MAXSHADERS); + + if (fragment) + { + gl_customfragmentshaders[number] = malloc(size+1); + strncpy(gl_customfragmentshaders[number], shader, size); + gl_customfragmentshaders[number][size] = 0; + } + else + { + gl_customvertexshaders[number] = malloc(size+1); + strncpy(gl_customvertexshaders[number], shader, size); + gl_customvertexshaders[number][size] = 0; + } +#endif +} + +EXPORT void HWRAPI(InitCustomShaders) (void) +{ +#ifdef GL_SHADERS + KillShaders(); + LoadShaders(); +#endif +} + +EXPORT void HWRAPI(SetShader) (int shader) +{ +#ifdef GL_SHADERS + if (gl_allowshaders) + { + gl_shadersenabled = true; + if ((GLuint)shader != gl_currentshaderprogram) + { + gl_currentshaderprogram = shader; + gl_shaderprogramchanged = true; + } + } + else +#endif + gl_shadersenabled = false; +} + +EXPORT void HWRAPI(UnSetShader) (void) +{ +#ifdef GL_SHADERS + gl_shadersenabled = false; + gl_currentshaderprogram = 0; + gl_shaderprogramchanged = true;// not sure if this is needed + if (!pglUseProgram) return; + pglUseProgram(0); +#endif +} + +EXPORT void HWRAPI(KillShaders) (void) +{ + // unused......................... +} + // -----------------+ // SetNoTexture : Disable texture // -----------------+ static void SetNoTexture(void) { - // Set small white texture. - if (tex_downloaded != NOTEXTURE_NUM) + // Disable texture. + if (tex_downloaded != NOTEXTURE_NUM && !gl_batching) { pglBindTexture(GL_TEXTURE_2D, NOTEXTURE_NUM); tex_downloaded = NOTEXTURE_NUM; @@ -533,7 +1024,7 @@ static void GLPerspective(GLfloat fovy, GLfloat aspect) const GLfloat zNear = NEAR_CLIPPING_PLANE; const GLfloat zFar = FAR_CLIPPING_PLANE; const GLfloat radians = (GLfloat)(fovy / 2.0f * M_PIl / 180.0f); - const GLfloat sine = sinf(radians); + const GLfloat sine = sin(radians); const GLfloat deltaZ = zFar - zNear; GLfloat cotangent; @@ -547,56 +1038,15 @@ static void GLPerspective(GLfloat fovy, GLfloat aspect) m[1][1] = cotangent; m[2][2] = -(zFar + zNear) / deltaZ; m[3][2] = -2.0f * zNear * zFar / deltaZ; - pglMultMatrixf(&m[0][0]); } -static void GLProject(GLfloat objX, GLfloat objY, GLfloat objZ, - GLfloat* winX, GLfloat* winY, GLfloat* winZ) -{ - GLfloat in[4], out[4]; - int i; - - for (i=0; i<4; i++) - { - out[i] = - objX * modelMatrix[0*4+i] + - objY * modelMatrix[1*4+i] + - objZ * modelMatrix[2*4+i] + - modelMatrix[3*4+i]; - } - for (i=0; i<4; i++) - { - in[i] = - out[0] * projMatrix[0*4+i] + - out[1] * projMatrix[1*4+i] + - out[2] * projMatrix[2*4+i] + - out[3] * projMatrix[3*4+i]; - } - if (fpclassify(in[3]) == FP_ZERO) return; - in[0] /= in[3]; - in[1] /= in[3]; - in[2] /= in[3]; - /* Map x, y and z to range 0-1 */ - in[0] = in[0] * 0.5f + 0.5f; - in[1] = in[1] * 0.5f + 0.5f; - in[2] = in[2] * 0.5f + 0.5f; - - /* Map x,y to viewport */ - in[0] = in[0] * viewport[2] + viewport[0]; - in[1] = in[1] * viewport[3] + viewport[1]; - - *winX=in[0]; - *winY=in[1]; - *winZ=in[2]; -} - // -----------------+ // SetModelView : // -----------------+ void SetModelView(GLint w, GLint h) { -// DBG_Printf("SetModelView(): %dx%d\n", (int)w, (int)h); + //GL_DBG_Printf("SetModelView(): %dx%d\n", (int)w, (int)h); // The screen textures need to be flushed if the width or height change so that they be remade for the correct size if (screen_width != w || screen_height != h) @@ -617,128 +1067,64 @@ void SetModelView(GLint w, GLint h) pglLoadIdentity(); GLPerspective(fov, ASPECT_RATIO); - //pglScalef(1.0f, 320.0f/200.0f, 1.0f); // gr_scalefrustum (ORIGINAL_ASPECT) // added for new coronas' code (without depth buffer) pglGetIntegerv(GL_VIEWPORT, viewport); pglGetFloatv(GL_PROJECTION_MATRIX, projMatrix); } - // -----------------+ // SetStates : Set permanent states // -----------------+ void SetStates(void) { - // Bind little white RGBA texture to ID NOTEXTURE_NUM. - /* - FUINT Data[8*8]; - INT32 i; - */ -#ifdef GL_LIGHT_MODEL_AMBIENT - GLfloat LightDiffuse[] = {1.0f, 1.0f, 1.0f, 1.0f}; -#endif - -// DBG_Printf("SetStates()\n"); - - // Hurdler: not necessary, is it? - pglShadeModel(GL_SMOOTH); // iterate vertice colors - //pglShadeModel(GL_FLAT); - pglEnable(GL_TEXTURE_2D); // two-dimensional texturing - pglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); pglAlphaFunc(GL_NOTEQUAL, 0.0f); - - //pglBlendFunc(GL_ONE, GL_ZERO); // copy pixel to frame buffer (opaque) pglEnable(GL_BLEND); // enable color blending pglColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - //pglDisable(GL_DITHER); // faB: ??? (undocumented in OpenGL 1.1) - // Hurdler: yes, it is! pglEnable(GL_DEPTH_TEST); // check the depth buffer pglDepthMask(GL_TRUE); // enable writing to depth buffer pglClearDepth(1.0f); pglDepthRange(0.0f, 1.0f); pglDepthFunc(GL_LEQUAL); - // this set CurrentPolyFlags to the acctual configuration + // this set CurrentPolyFlags to the actual configuration CurrentPolyFlags = 0xffffffff; SetBlend(0); - /* - for (i = 0; i < 64; i++) - Data[i] = 0xffFFffFF; // white pixel - */ - - tex_downloaded = (GLuint)-1; + //tex_downloaded = (GLuint)-1; SetNoTexture(); - //pglBindTexture(GL_TEXTURE_2D, NOTEXTURE_NUM); - //tex_downloaded = NOTEXTURE_NUM; - //pglTexImage2D(GL_TEXTURE_2D, 0, 4, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, Data); pglPolygonOffset(-1.0f, -1.0f); - //pglEnable(GL_CULL_FACE); - //pglCullFace(GL_FRONT); - - //glFogi(GL_FOG_MODE, GL_EXP); - //pglHint(GL_FOG_HINT, GL_FASTEST); - //pglFogfv(GL_FOG_COLOR, fogcolor); - //pglFogf(GL_FOG_DENSITY, 0.0005f); - - // Lighting for models -#ifdef GL_LIGHT_MODEL_AMBIENT - pglLightModelfv(GL_LIGHT_MODEL_AMBIENT, LightDiffuse); - pglEnable(GL_LIGHT0); -#endif - // bp : when no t&l :) pglLoadIdentity(); pglScalef(1.0f, 1.0f, -1.0f); pglGetFloatv(GL_MODELVIEW_MATRIX, modelMatrix); // added for new coronas' code (without depth buffer) } - // -----------------+ // Flush : flush OpenGL textures // : Clear list of downloaded mipmaps // -----------------+ void Flush(void) { - //DBG_Printf ("HWR_Flush()\n"); + //GL_DBG_Printf("HWR_Flush()\n"); while (gr_cachehead) { // ceci n'est pas du tout necessaire vu que tu les a charger normalement et // donc il sont dans ta liste ! -#if 0 - //Hurdler: 25/04/2000: now support colormap in hardware mode - FTextureInfo *tmp = gr_cachehead->nextskin; - - // The memory should be freed in the main code - while (tmp) - { - pglDeleteTextures(1, &tmp->downloaded); - tmp->downloaded = 0; - tmp = tmp->nextcolormap; - } -#endif - pglDeleteTextures(1, (GLuint *)&gr_cachehead->downloaded); + if (gr_cachehead->downloaded) + pglDeleteTextures(1, (GLuint *)&gr_cachehead->downloaded); gr_cachehead->downloaded = 0; gr_cachehead = gr_cachehead->nextmipmap; } gr_cachetail = gr_cachehead = NULL; //Hurdler: well, gr_cachehead is already NULL - NextTexAvail = FIRST_TEX_AVAIL; -#if 0 - if (screentexture != FIRST_TEX_AVAIL) - { - pglDeleteTextures(1, &screentexture); - screentexture = FIRST_TEX_AVAIL; - } -#endif tex_downloaded = 0; } @@ -776,10 +1162,8 @@ INT32 isExtAvailable(const char *extension, const GLubyte *start) // Init : Initialise the OpenGL interface API // Returns : // -----------------+ -EXPORT boolean HWRAPI(Init) (I_Error_t FatalErrorFunction) +EXPORT boolean HWRAPI(Init) (void) { - I_Error_GL = FatalErrorFunction; - DBG_Printf ("%s %s\n", DRIVER_STRING, VERSIONSTRING); return LoadGL(); } @@ -789,7 +1173,6 @@ EXPORT boolean HWRAPI(Init) (I_Error_t FatalErrorFunction) // -----------------+ EXPORT void HWRAPI(ClearMipMapCache) (void) { - // DBG_Printf ("HWR_Flush(exe)\n"); Flush(); } @@ -803,7 +1186,7 @@ EXPORT void HWRAPI(ReadRect) (INT32 x, INT32 y, INT32 width, INT32 height, INT32 dst_stride, UINT16 * dst_data) { INT32 i; - // DBG_Printf ("ReadRect()\n"); + //GL_DBG_Printf("ReadRect()\n"); if (dst_stride == width*3) { GLubyte*top = (GLvoid*)dst_data, *bottom = top + dst_stride * (height - 1); @@ -851,7 +1234,7 @@ EXPORT void HWRAPI(ReadRect) (INT32 x, INT32 y, INT32 width, INT32 height, // -----------------+ EXPORT void HWRAPI(GClipRect) (INT32 minx, INT32 miny, INT32 maxx, INT32 maxy, float nearclip) { - // DBG_Printf ("GClipRect(%d, %d, %d, %d)\n", minx, miny, maxx, maxy); + //GL_DBG_Printf("GClipRect(%d, %d, %d, %d)\n", minx, miny, maxx, maxy); pglViewport(minx, screen_height-maxy, maxx-minx, maxy-miny); NEAR_CLIPPING_PLANE = nearclip; @@ -875,7 +1258,7 @@ EXPORT void HWRAPI(ClearBuffer) (FBOOLEAN ColorMask, FBOOLEAN DepthMask, FRGBAFloat * ClearColor) { - // DBG_Printf ("ClearBuffer(%d)\n", alpha); + //GL_DBG_Printf("ClearBuffer(%d)\n", alpha); GLbitfield ClearMask = 0; if (ColorMask) @@ -910,7 +1293,7 @@ EXPORT void HWRAPI(Draw2DLine) (F2DCoord * v1, F2DCoord * v2, RGBA_t Color) { - // DBG_Printf ("DrawLine() (%f %f %f) %d\n", v1->x, -v1->y, -v1->z, v1->argb); + //GL_DBG_Printf("DrawLine(): %f %f, %f %f\n", v1->x, v1->y, v2->x, v2->y); GLfloat p[12]; GLfloat dx, dy; GLfloat angle; @@ -1002,7 +1385,6 @@ EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags) break; } } - if (Xor & PF_NoAlphaTest) { if (PolyFlags & PF_NoAlphaTest) @@ -1018,7 +1400,6 @@ EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags) else pglDisable(GL_POLYGON_OFFSET_FILL); } - if (Xor&PF_NoDepthTest) { if (PolyFlags & PF_NoDepthTest) @@ -1055,22 +1436,19 @@ EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags) } else #endif + + // mix texture colour with Surface->PolyColor if (PolyFlags & PF_Modulated) - { // mix texture colour with Surface->FlatColor pglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - } + // colour from texture is unchanged before blending else - { // colour from texture is unchanged before blending pglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - } } if (Xor & PF_Occlude) // depth test but (no) depth write { if (PolyFlags&PF_Occlude) - { pglDepthMask(1); - } else pglDepthMask(0); } @@ -1088,9 +1466,7 @@ EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags) } } if (PolyFlags & PF_NoTexture) - { SetNoTexture(); - } } CurrentPolyFlags = PolyFlags; } @@ -1110,7 +1486,8 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo) { if (pTexInfo->downloaded != tex_downloaded) { - pglBindTexture(GL_TEXTURE_2D, pTexInfo->downloaded); + if (!gl_batching) + pglBindTexture(GL_TEXTURE_2D, pTexInfo->downloaded); tex_downloaded = pTexInfo->downloaded; } } @@ -1120,12 +1497,25 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo) static RGBA_t tex[2048*2048]; const GLvoid *ptex = tex; INT32 w, h; + GLuint texnum = 0; - //DBG_Printf ("DownloadMipmap %d %x\n",NextTexAvail,pTexInfo->grInfo.data); + pglGenTextures(1, &texnum); + //GL_DBG_Printf("DownloadMipmap %d\n", (INT32)texnum, pTexInfo->grInfo.data); w = pTexInfo->width; h = pTexInfo->height; +#ifdef USE_PALETTED_TEXTURE + if (glColorTableEXT && + (pTexInfo->grInfo.format == GR_TEXFMT_P_8) && + !(pTexInfo->flags & TF_CHROMAKEYED)) + { + // do nothing here. + // Not a problem with MiniGL since we don't use paletted texture + } + else +#endif + if ((pTexInfo->grInfo.format == GR_TEXFMT_P_8) || (pTexInfo->grInfo.format == GR_TEXFMT_AP_88)) { @@ -1207,11 +1597,12 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo) } } else - DBG_Printf ("SetTexture(bad format) %ld\n", pTexInfo->grInfo.format); + GL_DBG_Printf("SetTexture(bad format) %ld\n", pTexInfo->grInfo.format); - pTexInfo->downloaded = NextTexAvail++; - tex_downloaded = pTexInfo->downloaded; - pglBindTexture(GL_TEXTURE_2D, pTexInfo->downloaded); + // the texture number was already generated by pglGenTextures + pglBindTexture(GL_TEXTURE_2D, texnum); + pTexInfo->downloaded = texnum; + tex_downloaded = texnum; // disable texture filtering on any texture that has holes so there's no dumb borders or blending issues if (pTexInfo->flags & TF_TRANSPARENT) @@ -1225,6 +1616,17 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo) pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter); } +#ifdef USE_PALETTED_TEXTURE + //Hurdler: not really supported and not tested recently + if (glColorTableEXT && + (pTexInfo->grInfo.format == GR_TEXFMT_P_8) && + !(pTexInfo->flags & TF_CHROMAKEYED)) + { + glColorTableEXT(GL_TEXTURE_2D, GL_RGB8, 256, GL_RGB, GL_UNSIGNED_BYTE, palette_tex); + pglTexImage2D(GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT, w, h, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, pTexInfo->grInfo.data); + } + else +#endif if (pTexInfo->grInfo.format == GR_TEXFMT_ALPHA_INTENSITY_88) { //pglTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, ptex); @@ -1309,102 +1711,880 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo) } } +static void load_shaders(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAFloat *tint, GLRGBAFloat *fade) +{ +#ifdef GL_SHADERS + if (gl_shadersenabled && pglUseProgram) + { + gl_shaderprogram_t *shader = &gl_shaderprograms[gl_currentshaderprogram]; + if (shader->program) + { + boolean custom = (gl_shaderprograms[gl_currentshaderprogram].custom); + // 13062019 + // Check for fog + //if (changed) + { + if (!custom) + { + if (gl_shaderprogramchanged) + { + pglUseProgram(gl_shaderprograms[gl_currentshaderprogram].program); + gl_shaderprogramchanged = false; + } + } + else // always load custom shaders + { + if (gl_shaderprogramchanged) + { + pglUseProgram(gl_shaderprograms[gl_currentshaderprogram].program); + gl_shaderprogramchanged = false; + } + } + } + + // set uniforms + { + #define UNIFORM_1(uniform, a, function) \ + if (uniform != -1) \ + function (uniform, a); + + #define UNIFORM_2(uniform, a, b, function) \ + if (uniform != -1) \ + function (uniform, a, b); + + #define UNIFORM_3(uniform, a, b, c, function) \ + if (uniform != -1) \ + function (uniform, a, b, c); + + #define UNIFORM_4(uniform, a, b, c, d, function) \ + if (uniform != -1) \ + function (uniform, a, b, c, d); + + // polygon + UNIFORM_4(shader->uniforms[gluniform_poly_color], poly->red, poly->green, poly->blue, poly->alpha, pglUniform4f); + UNIFORM_4(shader->uniforms[gluniform_tint_color], tint->red, tint->green, tint->blue, tint->alpha, pglUniform4f); + UNIFORM_4(shader->uniforms[gluniform_fade_color], fade->red, fade->green, fade->blue, fade->alpha, pglUniform4f); + UNIFORM_1(shader->uniforms[gluniform_lighting], Surface->LightInfo.light_level, pglUniform1f); + UNIFORM_1(shader->uniforms[gluniform_fade_start], Surface->LightInfo.fade_start, pglUniform1f); + UNIFORM_1(shader->uniforms[gluniform_fade_end], Surface->LightInfo.fade_end, pglUniform1f); + UNIFORM_1(shader->uniforms[gluniform_leveltime], ((float)leveltime) / TICRATE, pglUniform1f); + + #undef UNIFORM_1 + #undef UNIFORM_2 + #undef UNIFORM_3 + #undef UNIFORM_4 + } + } + else + pglUseProgram(0); + } +#endif +} + +// unfinished draw call batching + +// Note: could use realloc in the array reallocation code + +typedef struct +{ + FSurfaceInfo surf;// surf also has its own polyflags for some reason, but it seems unused + unsigned int vertsIndex;// location of verts in unsortedVertexArray + FUINT numVerts; + FBITFIELD polyFlags; + GLuint texNum; + GLuint shader; +} PolygonArrayEntry; + +FOutVector* finalVertexArray = NULL;// contains subset of sorted vertices and texture coordinates to be sent to gpu +UINT32* finalVertexIndexArray = NULL;// contains indexes for glDrawElements, taking into account fan->triangles conversion +// NOTE have this alloced as 3x finalVertexArray size +int finalVertexArrayAllocSize = 65536; +//GLubyte* colorArray = NULL;// contains color data to be sent to gpu, if needed +//int colorArrayAllocSize = 65536; +// not gonna use this for now, just sort by color and change state when it changes +// later maybe when using vertex attributes if it's needed + +PolygonArrayEntry* polygonArray = NULL;// contains the polygon data from DrawPolygon, waiting to be processed +int polygonArraySize = 0; +unsigned int* polygonIndexArray = NULL;// contains sorting pointers for polygonArray +int polygonArrayAllocSize = 65536; + +FOutVector* unsortedVertexArray = NULL;// contains unsorted vertices and texture coordinates from DrawPolygon +int unsortedVertexArraySize = 0; +int unsortedVertexArrayAllocSize = 65536; + +EXPORT void HWRAPI(StartBatching) (void) +{ + //CONS_Printf("StartBatching begin\n"); + // init arrays if that has not been done yet + if (!finalVertexArray) + { + finalVertexArray = malloc(finalVertexArrayAllocSize * sizeof(FOutVector)); + finalVertexIndexArray = malloc(finalVertexArrayAllocSize * 3 * sizeof(UINT32)); + polygonArray = malloc(polygonArrayAllocSize * sizeof(PolygonArrayEntry)); + polygonIndexArray = malloc(polygonArrayAllocSize * sizeof(unsigned int)); + unsortedVertexArray = malloc(unsortedVertexArrayAllocSize * sizeof(FOutVector)); + } + // drawing functions will now collect the drawing data instead of passing it to opengl + gl_batching = true; + //CONS_Printf("StartBatching end\n"); +} + +static int comparePolygons(const void *p1, const void *p2) +{ + PolygonArrayEntry* poly1 = &polygonArray[*(const unsigned int*)p1]; + PolygonArrayEntry* poly2 = &polygonArray[*(const unsigned int*)p2]; + int diff; + INT64 diff64; + + int shader1 = poly1->shader; + int shader2 = poly2->shader; + // make skywalls first in order + if (poly1->polyFlags & PF_NoTexture) + shader1 = -1; + if (poly2->polyFlags & PF_NoTexture) + shader2 = -1; + diff = shader1 - shader2; + if (diff != 0) return diff; + + diff = poly1->texNum - poly2->texNum; + if (diff != 0) return diff; + + diff = poly1->polyFlags - poly2->polyFlags; + if (diff != 0) return diff; + + diff64 = poly1->surf.PolyColor.rgba - poly2->surf.PolyColor.rgba; + if (diff64 < 0) return -1; else if (diff64 > 0) return 1; + diff64 = poly1->surf.TintColor.rgba - poly2->surf.TintColor.rgba; + if (diff64 < 0) return -1; else if (diff64 > 0) return 1; + diff64 = poly1->surf.FadeColor.rgba - poly2->surf.FadeColor.rgba; + if (diff64 < 0) return -1; else if (diff64 > 0) return 1; + + diff = poly1->surf.LightInfo.light_level - poly2->surf.LightInfo.light_level; + return diff; +} + +static int comparePolygonsNoShaders(const void *p1, const void *p2) +{ + PolygonArrayEntry* poly1 = &polygonArray[*(const unsigned int*)p1]; + PolygonArrayEntry* poly2 = &polygonArray[*(const unsigned int*)p2]; + int diff; + INT64 diff64; + + GLuint texNum1 = poly1->texNum; + GLuint texNum2 = poly2->texNum; + if (poly1->polyFlags & PF_NoTexture) + texNum1 = 0; + if (poly2->polyFlags & PF_NoTexture) + texNum2 = 0; + diff = texNum1 - texNum2; + if (diff != 0) return diff; + + diff = poly1->polyFlags - poly2->polyFlags; + if (diff != 0) return diff; + + diff64 = poly1->surf.PolyColor.rgba - poly2->surf.PolyColor.rgba; + if (diff64 < 0) return -1; else if (diff64 > 0) return 1; + + return 0; +} + +// the parameters for this functions (numPolys etc.) are used to return rendering stats +EXPORT void HWRAPI(RenderBatches) (int *sNumPolys, int *sNumVerts, int *sNumCalls, int *sNumShaders, int *sNumTextures, int *sNumPolyFlags, int *sNumColors) +{ + int finalVertexWritePos = 0;// position in finalVertexArray + int finalIndexWritePos = 0;// position in finalVertexIndexArray + + int polygonReadPos = 0;// position in polygonIndexArray + + GLuint currentShader; + GLuint currentTexture; + FBITFIELD currentPolyFlags; + FSurfaceInfo currentSurfaceInfo; + + GLRGBAFloat firstPoly = {0,0,0,0}; // may be misleading but this means first PolyColor + GLRGBAFloat firstTint = {0,0,0,0}; + GLRGBAFloat firstFade = {0,0,0,0}; + + boolean needRebind = false; + + int i; + + //CONS_Printf("RenderBatches\n"); + gl_batching = false;// no longer collecting batches + if (!polygonArraySize) + { + *sNumPolys = *sNumCalls = *sNumShaders = *sNumTextures = *sNumPolyFlags = *sNumColors = 0; + return;// nothing to draw + } + // init stats vars + *sNumPolys = polygonArraySize; + *sNumCalls = *sNumVerts = 0; + *sNumShaders = *sNumTextures = *sNumPolyFlags = *sNumColors = 1; + // init polygonIndexArray + for (i = 0; i < polygonArraySize; i++) + { + polygonIndexArray[i] = i; + } + + // sort polygons + //CONS_Printf("qsort polys\n"); + //*sSortTime = I_GetTimeMicros(); + if (gl_allowshaders) + qsort(polygonIndexArray, polygonArraySize, sizeof(unsigned int), comparePolygons); + else + qsort(polygonIndexArray, polygonArraySize, sizeof(unsigned int), comparePolygonsNoShaders); + //*sSortTime = I_GetTimeMicros() - *sSortTime; + //CONS_Printf("sort done\n"); + // sort order + // 1. shader + // 2. texture + // 3. polyflags + // 4. colors + light level + // not sure about order of last 2, or if it even matters + + //*sDrawTime = I_GetTimeMicros(); + + currentShader = polygonArray[polygonIndexArray[0]].shader; + currentTexture = polygonArray[polygonIndexArray[0]].texNum; + currentPolyFlags = polygonArray[polygonIndexArray[0]].polyFlags; + currentSurfaceInfo = polygonArray[polygonIndexArray[0]].surf; + // For now, will sort and track the colors. Vertex attributes could be used instead of uniforms + // and a color array could replace the color calls. + + // set state for first batch + //CONS_Printf("set first state\n"); + gl_currentshaderprogram = currentShader; + gl_shaderprogramchanged = true; + if (currentPolyFlags & PF_Modulated) + { + // Poly color + firstPoly.red = byte2float[currentSurfaceInfo.PolyColor.s.red]; + firstPoly.green = byte2float[currentSurfaceInfo.PolyColor.s.green]; + firstPoly.blue = byte2float[currentSurfaceInfo.PolyColor.s.blue]; + firstPoly.alpha = byte2float[currentSurfaceInfo.PolyColor.s.alpha]; + pglColor4ubv((GLubyte*)¤tSurfaceInfo.PolyColor.s); + } + // Tint color + firstTint.red = byte2float[currentSurfaceInfo.TintColor.s.red]; + firstTint.green = byte2float[currentSurfaceInfo.TintColor.s.green]; + firstTint.blue = byte2float[currentSurfaceInfo.TintColor.s.blue]; + firstTint.alpha = byte2float[currentSurfaceInfo.TintColor.s.alpha]; + // Fade color + firstFade.red = byte2float[currentSurfaceInfo.FadeColor.s.red]; + firstFade.green = byte2float[currentSurfaceInfo.FadeColor.s.green]; + firstFade.blue = byte2float[currentSurfaceInfo.FadeColor.s.blue]; + firstFade.alpha = byte2float[currentSurfaceInfo.FadeColor.s.alpha]; + + if (gl_allowshaders) + load_shaders(¤tSurfaceInfo, &firstPoly, &firstTint, &firstFade); + + if (currentPolyFlags & PF_NoTexture) + currentTexture = 0; + pglBindTexture(GL_TEXTURE_2D, currentTexture); + tex_downloaded = currentTexture; + + SetBlend(currentPolyFlags); + + //CONS_Printf("first pointers to ogl\n"); + pglVertexPointer(3, GL_FLOAT, sizeof(FOutVector), &finalVertexArray[0].x); + pglTexCoordPointer(2, GL_FLOAT, sizeof(FOutVector), &finalVertexArray[0].s); + + while (1)// note: remember handling notexture polyflag as having texture number 0 (also in comparePolygons) + { + int firstIndex; + int lastIndex; + + boolean stopFlag = false; + boolean changeState = false; + boolean changeShader = false; + GLuint nextShader; + boolean changeTexture = false; + GLuint nextTexture; + boolean changePolyFlags = false; + FBITFIELD nextPolyFlags; + boolean changeSurfaceInfo = false; + FSurfaceInfo nextSurfaceInfo; + + //CONS_Printf("loop iter start\n"); + // new try: + // write vertices + // check for changes or end, otherwise go back to writing + // changes will affect the next vars and the change bools + // end could set flag for stopping + // execute draw call + // could check ending flag here + // change states according to next vars and change bools, updating the current vars and reseting the bools + // reset write pos + // repeat loop + + int index = polygonIndexArray[polygonReadPos++]; + int numVerts = polygonArray[index].numVerts; + // before writing, check if there is enough room + // using 'while' instead of 'if' here makes sure that there will *always* be enough room. + // probably never will this loop run more than once though + while (finalVertexWritePos + numVerts > finalVertexArrayAllocSize) + { + FOutVector* new_array; + unsigned int* new_index_array; + //CONS_Printf("final vert realloc\n"); + finalVertexArrayAllocSize *= 2; + new_array = malloc(finalVertexArrayAllocSize * sizeof(FOutVector)); + memcpy(new_array, finalVertexArray, finalVertexWritePos * sizeof(FOutVector)); + free(finalVertexArray); + finalVertexArray = new_array; + // also increase size of index array, 3x of vertex array since + // going from fans to triangles increases vertex count to 3x + new_index_array = malloc(finalVertexArrayAllocSize * 3 * sizeof(UINT32)); + memcpy(new_index_array, finalVertexIndexArray, finalIndexWritePos * sizeof(UINT32)); + free(finalVertexIndexArray); + finalVertexIndexArray = new_index_array; + // if vertex buffers are reallocated then opengl needs to know too + needRebind = true; + } + //CONS_Printf("write verts to final\n"); + // write the vertices of the polygon + memcpy(&finalVertexArray[finalVertexWritePos], &unsortedVertexArray[polygonArray[index].vertsIndex], + numVerts * sizeof(FOutVector)); + // write the indexes, pointing to the fan vertexes but in triangles format + firstIndex = finalVertexWritePos; + lastIndex = finalVertexWritePos + numVerts; + finalVertexWritePos += 2; + //CONS_Printf("write final vert indices\n"); + while (finalVertexWritePos < lastIndex) + { + finalVertexIndexArray[finalIndexWritePos++] = firstIndex; + finalVertexIndexArray[finalIndexWritePos++] = finalVertexWritePos - 1; + finalVertexIndexArray[finalIndexWritePos++] = finalVertexWritePos++; + } + + if (polygonReadPos >= polygonArraySize) + { + stopFlag = true; + } + else + { + //CONS_Printf("state change check\n"); + // check if a state change is required, set the change bools and next vars + int nextIndex = polygonIndexArray[polygonReadPos]; + nextShader = polygonArray[nextIndex].shader; + nextTexture = polygonArray[nextIndex].texNum; + nextPolyFlags = polygonArray[nextIndex].polyFlags; + nextSurfaceInfo = polygonArray[nextIndex].surf; + if (nextPolyFlags & PF_NoTexture) + nextTexture = 0; + if (currentShader != nextShader) + { + changeState = true; + changeShader = true; + } + if (currentTexture != nextTexture) + { + changeState = true; + changeTexture = true; + } + if (currentPolyFlags != nextPolyFlags) + { + changeState = true; + changePolyFlags = true; + } + if (gl_allowshaders) + { + if (currentSurfaceInfo.PolyColor.rgba != nextSurfaceInfo.PolyColor.rgba || + currentSurfaceInfo.TintColor.rgba != nextSurfaceInfo.TintColor.rgba || + currentSurfaceInfo.FadeColor.rgba != nextSurfaceInfo.FadeColor.rgba || + currentSurfaceInfo.LightInfo.light_level != nextSurfaceInfo.LightInfo.light_level) + { + changeState = true; + changeSurfaceInfo = true; + } + } + else + { + if (currentSurfaceInfo.PolyColor.rgba != nextSurfaceInfo.PolyColor.rgba) + { + changeState = true; + changeSurfaceInfo = true; + } + } + } + + if (changeState || stopFlag) + { + if (needRebind) + { + //CONS_Printf("rebind\n"); + pglVertexPointer(3, GL_FLOAT, sizeof(FOutVector), &finalVertexArray[0].x); + pglTexCoordPointer(2, GL_FLOAT, sizeof(FOutVector), &finalVertexArray[0].s); + needRebind = false; + } + //CONS_Printf("exec draw call\n"); + // execute draw call + pglDrawElements(GL_TRIANGLES, finalIndexWritePos, GL_UNSIGNED_INT, finalVertexIndexArray); + //CONS_Printf("draw call done\n"); + // update stats + (*sNumCalls)++; + *sNumVerts += finalIndexWritePos; + // reset write positions + finalVertexWritePos = 0; + finalIndexWritePos = 0; + } + else continue; + + // if we're here then either its time to stop or time to change state + if (stopFlag) break; + + //CONS_Printf("state change\n"); + + // change state according to change bools and next vars, update current vars and reset bools + if (changeShader) + { + GLRGBAFloat poly = {0,0,0,0}; + GLRGBAFloat tint = {0,0,0,0}; + GLRGBAFloat fade = {0,0,0,0}; + gl_currentshaderprogram = nextShader; + gl_shaderprogramchanged = true; + if (nextPolyFlags & PF_Modulated) + { + // Poly color + poly.red = byte2float[nextSurfaceInfo.PolyColor.s.red]; + poly.green = byte2float[nextSurfaceInfo.PolyColor.s.green]; + poly.blue = byte2float[nextSurfaceInfo.PolyColor.s.blue]; + poly.alpha = byte2float[nextSurfaceInfo.PolyColor.s.alpha]; + } + // Tint color + tint.red = byte2float[nextSurfaceInfo.TintColor.s.red]; + tint.green = byte2float[nextSurfaceInfo.TintColor.s.green]; + tint.blue = byte2float[nextSurfaceInfo.TintColor.s.blue]; + tint.alpha = byte2float[nextSurfaceInfo.TintColor.s.alpha]; + // Fade color + fade.red = byte2float[nextSurfaceInfo.FadeColor.s.red]; + fade.green = byte2float[nextSurfaceInfo.FadeColor.s.green]; + fade.blue = byte2float[nextSurfaceInfo.FadeColor.s.blue]; + fade.alpha = byte2float[nextSurfaceInfo.FadeColor.s.alpha]; + + load_shaders(&nextSurfaceInfo, &poly, &tint, &fade); + currentShader = nextShader; + changeShader = false; + + (*sNumShaders)++; + } + if (changeTexture) + { + // texture should be already ready for use from calls to SetTexture during batch collection + pglBindTexture(GL_TEXTURE_2D, nextTexture); + tex_downloaded = nextTexture; + currentTexture = nextTexture; + changeTexture = false; + + (*sNumTextures)++; + } + if (changePolyFlags) + { + SetBlend(nextPolyFlags); + currentPolyFlags = nextPolyFlags; + changePolyFlags = false; + + (*sNumPolyFlags)++; + } + if (changeSurfaceInfo) + { + GLRGBAFloat poly = {0,0,0,0}; + GLRGBAFloat tint = {0,0,0,0}; + GLRGBAFloat fade = {0,0,0,0}; + gl_shaderprogramchanged = false; + if (nextPolyFlags & PF_Modulated) + { + // Poly color + poly.red = byte2float[nextSurfaceInfo.PolyColor.s.red]; + poly.green = byte2float[nextSurfaceInfo.PolyColor.s.green]; + poly.blue = byte2float[nextSurfaceInfo.PolyColor.s.blue]; + poly.alpha = byte2float[nextSurfaceInfo.PolyColor.s.alpha]; + pglColor4ubv((GLubyte*)&nextSurfaceInfo.PolyColor.s); + } + if (gl_allowshaders) + { + // Tint color + tint.red = byte2float[nextSurfaceInfo.TintColor.s.red]; + tint.green = byte2float[nextSurfaceInfo.TintColor.s.green]; + tint.blue = byte2float[nextSurfaceInfo.TintColor.s.blue]; + tint.alpha = byte2float[nextSurfaceInfo.TintColor.s.alpha]; + // Fade color + fade.red = byte2float[nextSurfaceInfo.FadeColor.s.red]; + fade.green = byte2float[nextSurfaceInfo.FadeColor.s.green]; + fade.blue = byte2float[nextSurfaceInfo.FadeColor.s.blue]; + fade.alpha = byte2float[nextSurfaceInfo.FadeColor.s.alpha]; + + load_shaders(&nextSurfaceInfo, &poly, &tint, &fade); + } + currentSurfaceInfo = nextSurfaceInfo; + changeSurfaceInfo = false; + + (*sNumColors)++; + } + // and that should be it? + } + // reset the arrays (set sizes to 0) + polygonArraySize = 0; + unsortedVertexArraySize = 0; + + //*sDrawTime = I_GetTimeMicros() - *sDrawTime; +} // -----------------+ // DrawPolygon : Render a polygon, set the texture, set render mode // -----------------+ -EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, - //FTextureInfo *pTexInfo, - FOutVector *pOutVerts, - FUINT iNumPts, - FBITFIELD PolyFlags) +EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags) { - FUINT i; - FUINT j; - - if ((PolyFlags & PF_Corona) && (oglflags & GLF_NOZBUFREAD)) - PolyFlags &= ~(PF_NoDepthTest|PF_Corona); - - SetBlend(PolyFlags); //TODO: inline (#pragma..) - - // If Modulated, mix the surface colour to the texture - if ((CurrentPolyFlags & PF_Modulated) && pSurf) - pglColor4ubv((GLubyte*)&pSurf->FlatColor.s); - - // this test is added for new coronas' code (without depth buffer) - // I think I should do a separate function for drawing coronas, so it will be a little faster - if (PolyFlags & PF_Corona) // check to see if we need to draw the corona + if (gl_batching) { - //rem: all 8 (or 8.0f) values are hard coded: it can be changed to a higher value - GLfloat buf[8][8]; - GLfloat cx, cy, cz; - GLfloat px = 0.0f, py = 0.0f, pz = -1.0f; - GLfloat scalef = 0.0f; + //CONS_Printf("Batched DrawPolygon\n"); + if (!pSurf) + I_Error("Got a null FSurfaceInfo in batching");// nulls should only come in sky background pic drawing + if (polygonArraySize == polygonArrayAllocSize) + { + PolygonArrayEntry* new_array; + // ran out of space, make new array double the size + polygonArrayAllocSize *= 2; + new_array = malloc(polygonArrayAllocSize * sizeof(PolygonArrayEntry)); + memcpy(new_array, polygonArray, polygonArraySize * sizeof(PolygonArrayEntry)); + free(polygonArray); + polygonArray = new_array; + // also need to redo the index array, dont need to copy it though + free(polygonIndexArray); + polygonIndexArray = malloc(polygonArrayAllocSize * sizeof(unsigned int)); + } - GLubyte c[4]; + while (unsortedVertexArraySize + (int)iNumPts > unsortedVertexArrayAllocSize) + { + FOutVector* new_array; + // need more space for vertices in unsortedVertexArray + unsortedVertexArrayAllocSize *= 2; + new_array = malloc(unsortedVertexArrayAllocSize * sizeof(FOutVector)); + memcpy(new_array, unsortedVertexArray, unsortedVertexArraySize * sizeof(FOutVector)); + free(unsortedVertexArray); + unsortedVertexArray = new_array; + } - float alpha; + // add the polygon data to the arrays - cx = (pOutVerts[0].x + pOutVerts[2].x) / 2.0f; // we should change the coronas' ... - cy = (pOutVerts[0].y + pOutVerts[2].y) / 2.0f; // ... code so its only done once. - cz = pOutVerts[0].z; + polygonArray[polygonArraySize].surf = *pSurf; + polygonArray[polygonArraySize].vertsIndex = unsortedVertexArraySize; + polygonArray[polygonArraySize].numVerts = iNumPts; + polygonArray[polygonArraySize].polyFlags = PolyFlags; + polygonArray[polygonArraySize].texNum = tex_downloaded; + polygonArray[polygonArraySize].shader = gl_currentshaderprogram; + polygonArraySize++; - // I dont know if this is slow or not - GLProject(cx, cy, cz, &px, &py, &pz); - //DBG_Printf("Projection: (%f, %f, %f)\n", px, py, pz); - - if ((pz < 0.0l) || - (px < -8.0l) || - (py < viewport[1]-8.0l) || - (px > viewport[2]+8.0l) || - (py > viewport[1]+viewport[3]+8.0l)) - return; - - // the damned slow glReadPixels functions :( - pglReadPixels((INT32)px-4, (INT32)py, 8, 8, GL_DEPTH_COMPONENT, GL_FLOAT, buf); - //DBG_Printf("DepthBuffer: %f %f\n", buf[0][0], buf[3][3]); - - for (i = 0; i < 8; i++) - for (j = 0; j < 8; j++) - scalef += (pz > buf[i][j]+0.00005f) ? 0 : 1; - - // quick test for screen border (not 100% correct, but looks ok) - if (px < 4) scalef -= (GLfloat)(8*(4-px)); - if (py < viewport[1]+4) scalef -= (GLfloat)(8*(viewport[1]+4-py)); - if (px > viewport[2]-4) scalef -= (GLfloat)(8*(4-(viewport[2]-px))); - if (py > viewport[1]+viewport[3]-4) scalef -= (GLfloat)(8*(4-(viewport[1]+viewport[3]-py))); - - scalef /= 64; - //DBG_Printf("Scale factor: %f\n", scalef); - - if (scalef < 0.05f) - return; - - // GLubyte c[4]; - c[0] = pSurf->FlatColor.s.red; - c[1] = pSurf->FlatColor.s.green; - c[2] = pSurf->FlatColor.s.blue; - - alpha = byte2float[pSurf->FlatColor.s.alpha]; - alpha *= scalef; // change the alpha value (it seems better than changing the size of the corona) - c[3] = (unsigned char)(alpha * 255); - pglColor4ubv(c); + memcpy(&unsortedVertexArray[unsortedVertexArraySize], pOutVerts, iNumPts * sizeof(FOutVector)); + unsortedVertexArraySize += iNumPts; } + else + { + static GLRGBAFloat poly = {0,0,0,0}; + static GLRGBAFloat tint = {0,0,0,0}; + static GLRGBAFloat fade = {0,0,0,0}; - pglVertexPointer(3, GL_FLOAT, sizeof(FOutVector), &pOutVerts[0].x); - pglTexCoordPointer(2, GL_FLOAT, sizeof(FOutVector), &pOutVerts[0].sow); - pglDrawArrays(GL_TRIANGLE_FAN, 0, iNumPts); + SetBlend(PolyFlags); //TODO: inline (#pragma..) - if (PolyFlags & PF_RemoveYWrap) - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + // PolyColor + if (pSurf) + { + // If Modulated, mix the surface colour to the texture + if (CurrentPolyFlags & PF_Modulated) + { + // Poly color + poly.red = byte2float[pSurf->PolyColor.s.red]; + poly.green = byte2float[pSurf->PolyColor.s.green]; + poly.blue = byte2float[pSurf->PolyColor.s.blue]; + poly.alpha = byte2float[pSurf->PolyColor.s.alpha]; - if (PolyFlags & PF_ForceWrapX) - Clamp2D(GL_TEXTURE_WRAP_S); + pglColor4ubv((GLubyte*)&pSurf->PolyColor.s); + } + + // Tint color + tint.red = byte2float[pSurf->TintColor.s.red]; + tint.green = byte2float[pSurf->TintColor.s.green]; + tint.blue = byte2float[pSurf->TintColor.s.blue]; + tint.alpha = byte2float[pSurf->TintColor.s.alpha]; - if (PolyFlags & PF_ForceWrapY) - Clamp2D(GL_TEXTURE_WRAP_T); + // Fade color + fade.red = byte2float[pSurf->FadeColor.s.red]; + fade.green = byte2float[pSurf->FadeColor.s.green]; + fade.blue = byte2float[pSurf->FadeColor.s.blue]; + fade.alpha = byte2float[pSurf->FadeColor.s.alpha]; + } + + load_shaders(pSurf, &poly, &tint, &fade); + + pglVertexPointer(3, GL_FLOAT, sizeof(FOutVector), &pOutVerts[0].x); + pglTexCoordPointer(2, GL_FLOAT, sizeof(FOutVector), &pOutVerts[0].s); + pglDrawArrays(GL_TRIANGLE_FAN, 0, iNumPts); + + if (PolyFlags & PF_RemoveYWrap) + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + if (PolyFlags & PF_ForceWrapX) + Clamp2D(GL_TEXTURE_WRAP_S); + + if (PolyFlags & PF_ForceWrapY) + Clamp2D(GL_TEXTURE_WRAP_T); + } } +// Sky dome code, taken/backported from SRB2 + +typedef struct vbo_vertex_s +{ + float x, y, z; + float u, v; + unsigned char r, g, b, a; +} vbo_vertex_t; + +typedef struct +{ + int mode; + int vertexcount; + int vertexindex; + int use_texture; +} GLSkyLoopDef; + +typedef struct +{ + unsigned int id; + int rows, columns; + int loopcount; + GLSkyLoopDef *loops; + vbo_vertex_t *data; +} GLSkyVBO; + +static const boolean gl_ext_arb_vertex_buffer_object = true; + +#define NULL_VBO_VERTEX ((vbo_vertex_t*)NULL) +#define sky_vbo_x (gl_ext_arb_vertex_buffer_object ? &NULL_VBO_VERTEX->x : &vbo->data[0].x) +#define sky_vbo_u (gl_ext_arb_vertex_buffer_object ? &NULL_VBO_VERTEX->u : &vbo->data[0].u) +#define sky_vbo_r (gl_ext_arb_vertex_buffer_object ? &NULL_VBO_VERTEX->r : &vbo->data[0].r) + +// The texture offset to be applied to the texture coordinates in SkyVertex(). +static int rows, columns; +static signed char yflip; +static int texw, texh; +static boolean foglayer; +static float delta = 0.0f; + +static int gl_sky_detail = 16; + +static INT32 lasttex = -1; + +#define MAP_COEFF 128.0f + +static void SkyVertex(vbo_vertex_t *vbo, int r, int c) +{ + const float radians = (float)(M_PIl / 180.0f); + const float scale = 10000.0f; + const float maxSideAngle = 60.0f; + + float topAngle = (c / (float)columns * 360.0f); + float sideAngle = (maxSideAngle * (rows - r) / rows); + float height = (float)(sin(sideAngle * radians)); + float realRadius = (float)(scale * cos(sideAngle * radians)); + float x = (float)(realRadius * cos(topAngle * radians)); + float y = (!yflip) ? scale * height : -scale * height; + float z = (float)(realRadius * sin(topAngle * radians)); + float timesRepeat = (4 * (256.0f / texw)); + if (fpclassify(timesRepeat) == FP_ZERO) + timesRepeat = 1.0f; + + if (!foglayer) + { + vbo->r = 255; + vbo->g = 255; + vbo->b = 255; + vbo->a = (r == 0 ? 0 : 255); + + // And the texture coordinates. + //vbo->u = (-timesRepeat * c / (float)columns); + vbo->u = (timesRepeat * c / (float)columns);// TEST + if (!yflip) // Flipped Y is for the lower hemisphere. + vbo->v = (r / (float)rows) + 0.5f; + else + vbo->v = 1.0f + ((rows - r) / (float)rows) + 0.5f; + } + + if (r != 4) + { + y += 300.0f; + } + + // And finally the vertex. + vbo->x = x; + vbo->y = y + delta; + vbo->z = z; +} + +static GLSkyVBO sky_vbo; + +static void gld_BuildSky(int row_count, int col_count) +{ + int c, r; + vbo_vertex_t *vertex_p; + int vertex_count = 2 * row_count * (col_count * 2 + 2) + col_count * 2; + + GLSkyVBO *vbo = &sky_vbo; + + if ((vbo->columns != col_count) || (vbo->rows != row_count)) + { + free(vbo->loops); + free(vbo->data); + memset(vbo, 0, sizeof(&vbo)); + } + + if (!vbo->data) + { + memset(vbo, 0, sizeof(&vbo)); + vbo->loops = malloc((row_count * 2 + 2) * sizeof(vbo->loops[0])); + // create vertex array + vbo->data = malloc(vertex_count * sizeof(vbo->data[0])); + } + + vbo->columns = col_count; + vbo->rows = row_count; + + vertex_p = &vbo->data[0]; + vbo->loopcount = 0; + + for (yflip = 0; yflip < 2; yflip++) + { + vbo->loops[vbo->loopcount].mode = GL_TRIANGLE_FAN; + vbo->loops[vbo->loopcount].vertexindex = vertex_p - &vbo->data[0]; + vbo->loops[vbo->loopcount].vertexcount = col_count; + vbo->loops[vbo->loopcount].use_texture = false; + vbo->loopcount++; + + delta = 0.0f; + foglayer = true; + for (c = 0; c < col_count; c++) + { + SkyVertex(vertex_p, 1, c); + vertex_p->r = 255; + vertex_p->g = 255; + vertex_p->b = 255; + vertex_p->a = 255; + vertex_p++; + } + foglayer = false; + + delta = (yflip ? 5.0f : -5.0f) / MAP_COEFF; + + for (r = 0; r < row_count; r++) + { + vbo->loops[vbo->loopcount].mode = GL_TRIANGLE_STRIP; + vbo->loops[vbo->loopcount].vertexindex = vertex_p - &vbo->data[0]; + vbo->loops[vbo->loopcount].vertexcount = 2 * col_count + 2; + vbo->loops[vbo->loopcount].use_texture = true; + vbo->loopcount++; + + for (c = 0; c <= col_count; c++) + { + SkyVertex(vertex_p++, r + (yflip ? 1 : 0), (c ? c : 0)); + SkyVertex(vertex_p++, r + (yflip ? 0 : 1), (c ? c : 0)); + } + } + } +} + +//----------------------------------------------------------------------------- +// +// +// +//----------------------------------------------------------------------------- + +static void RenderDome(INT32 skytexture) +{ + int i, j; + int vbosize; + GLSkyVBO *vbo = &sky_vbo; + + rows = 4; + columns = 4 * gl_sky_detail; + + vbosize = 2 * rows * (columns * 2 + 2) + columns * 2; + + // Build the sky dome! Yes! + if (lasttex != skytexture) + { + // delete VBO when already exists + if (gl_ext_arb_vertex_buffer_object) + { + if (vbo->id) + pglDeleteBuffers(1, &vbo->id); + } + + lasttex = skytexture; + gld_BuildSky(rows, columns); + + if (gl_ext_arb_vertex_buffer_object) + { + // generate a new VBO and get the associated ID + pglGenBuffers(1, &vbo->id); + + // bind VBO in order to use + pglBindBuffer(GL_ARRAY_BUFFER, vbo->id); + + // upload data to VBO + pglBufferData(GL_ARRAY_BUFFER, vbosize * sizeof(vbo->data[0]), vbo->data, GL_STATIC_DRAW); + } + } + + // bind VBO in order to use + if (gl_ext_arb_vertex_buffer_object) + pglBindBuffer(GL_ARRAY_BUFFER, vbo->id); + + // activate and specify pointers to arrays + pglVertexPointer(3, GL_FLOAT, sizeof(vbo->data[0]), sky_vbo_x); + pglTexCoordPointer(2, GL_FLOAT, sizeof(vbo->data[0]), sky_vbo_u); + pglColorPointer(4, GL_UNSIGNED_BYTE, sizeof(vbo->data[0]), sky_vbo_r); + + // activate color arrays + pglEnableClientState(GL_COLOR_ARRAY); + + // set transforms + pglScalef(1.0f, (float)texh / 230.0f, 1.0f); + pglRotatef(270.0f, 0.0f, 1.0f, 0.0f); + + for (j = 0; j < 2; j++) + { + for (i = 0; i < vbo->loopcount; i++) + { + GLSkyLoopDef *loop = &vbo->loops[i]; + + if (j == 0 ? loop->use_texture : !loop->use_texture) + continue; + + pglDrawArrays(loop->mode, loop->vertexindex, loop->vertexcount); + } + } + + pglScalef(1.0f, 1.0f, 1.0f); + pglColor4ubv(white); + + // bind with 0, so, switch back to normal pointer operation + if (gl_ext_arb_vertex_buffer_object) + pglBindBuffer(GL_ARRAY_BUFFER, 0); + + // deactivate color array + pglDisableClientState(GL_COLOR_ARRAY); +} + +EXPORT void HWRAPI(RenderSkyDome) (INT32 tex, INT32 texture_width, INT32 texture_height, FTransform transform) +{ + SetBlend(PF_Translucent|PF_NoDepthTest|PF_Modulated); + SetTransform(&transform); + texw = texture_width; + texh = texture_height; + RenderDome(tex); + SetBlend(0); +} // ========================================================================== // @@ -1413,56 +2593,16 @@ EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value) { switch (IdState) { - -#if 0 - case 77: - { - //08/01/00: Hurdler this is a test for mirror - if (!Value) - ClearBuffer(false, true, 0); // clear depth buffer - break; - } -#endif - - case HWD_SET_FOG_COLOR: - { - GLfloat fogcolor[4]; - - fogcolor[0] = byte2float[((Value>>16)&0xff)]; - fogcolor[1] = byte2float[((Value>>8)&0xff)]; - fogcolor[2] = byte2float[((Value)&0xff)]; - fogcolor[3] = 0x0; - pglFogfv(GL_FOG_COLOR, fogcolor); - break; - } - case HWD_SET_FOG_DENSITY: - pglFogf(GL_FOG_DENSITY, Value*1200/(500*1000000.0f)); - break; - - case HWD_SET_FOG_MODE: - if (Value) + case HWD_SET_SHADERS: + switch (Value) { - pglEnable(GL_FOG); - // experimental code - /* - switch (Value) - { - case 1: - glFogi(GL_FOG_MODE, GL_LINEAR); - pglFogf(GL_FOG_START, -1000.0f); - pglFogf(GL_FOG_END, 2000.0f); - break; - case 2: - glFogi(GL_FOG_MODE, GL_EXP); - break; - case 3: - glFogi(GL_FOG_MODE, GL_EXP2); - break; - } - */ + case 1: + gl_allowshaders = true; + break; + default: + gl_allowshaders = false; + break; } - else - pglDisable(GL_FOG); break; case HWD_SET_TEXTUREFILTERMODE: @@ -1632,6 +2772,10 @@ static void CreateModelVBO(mesh_t *mesh, mdlframe_t *frame) pglBindBuffer(GL_ARRAY_BUFFER, frame->vboID); pglBufferData(GL_ARRAY_BUFFER, bufferSize, buffer, GL_STATIC_DRAW); free(buffer); + + // Don't leave the array buffer bound to the model, + // since this is called mid-frame + pglBindBuffer(GL_ARRAY_BUFFER, 0); } static void CreateModelVBOTiny(mesh_t *mesh, tinyframe_t *frame) @@ -1673,6 +2817,10 @@ static void CreateModelVBOTiny(mesh_t *mesh, tinyframe_t *frame) pglBindBuffer(GL_ARRAY_BUFFER, frame->vboID); pglBufferData(GL_ARRAY_BUFFER, bufferSize, buffer, GL_STATIC_DRAW); free(buffer); + + // Don't leave the array buffer bound to the model, + // since this is called mid-frame + pglBindBuffer(GL_ARRAY_BUFFER, 0); } EXPORT void HWRAPI(CreateModelVBOs) (model_t *model) @@ -1709,12 +2857,13 @@ EXPORT void HWRAPI(CreateModelVBOs) (model_t *model) } } -#define BUFFER_OFFSET(i) ((char*)NULL + (i)) +#define BUFFER_OFFSET(i) ((char*)(i)) -static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 *color) +static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, FSurfaceInfo *Surface) { - GLfloat ambient[4]; - GLfloat diffuse[4]; + static GLRGBAFloat poly = {0,0,0,0}; + static GLRGBAFloat tint = {0,0,0,0}; + static GLRGBAFloat fade = {0,0,0,0}; float pol = 0.0f; float scalex, scaley, scalez; @@ -1723,9 +2872,6 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 int i; - // Because Otherwise, scaling the screen negatively vertically breaks the lighting - GLfloat LightPos[] = {0.0f, 1.0f, 0.0f, 0.0f}; - // Affect input model scaling scale *= 0.5f; scalex = scale; @@ -1745,24 +2891,29 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 pol = 0.0f; } - if (color) - { - ambient[0] = (color[0]/255.0f); - ambient[1] = (color[1]/255.0f); - ambient[2] = (color[2]/255.0f); - ambient[3] = (color[3]/255.0f); - diffuse[0] = (color[0]/255.0f); - diffuse[1] = (color[1]/255.0f); - diffuse[2] = (color[2]/255.0f); - diffuse[3] = (color[3]/255.0f); + poly.red = byte2float[Surface->PolyColor.s.red]; + poly.green = byte2float[Surface->PolyColor.s.green]; + poly.blue = byte2float[Surface->PolyColor.s.blue]; + poly.alpha = byte2float[Surface->PolyColor.s.alpha]; - if (ambient[0] > 0.75f) - ambient[0] = 0.75f; - if (ambient[1] > 0.75f) - ambient[1] = 0.75f; - if (ambient[2] > 0.75f) - ambient[2] = 0.75f; - } + if (poly.alpha < 1) + SetBlend(PF_Translucent|PF_Modulated); + else + SetBlend(PF_Masked|PF_Modulated|PF_Occlude); + + pglColor4ubv((GLubyte*)&Surface->PolyColor.s); + + tint.red = byte2float[Surface->TintColor.s.red]; + tint.green = byte2float[Surface->TintColor.s.green]; + tint.blue = byte2float[Surface->TintColor.s.blue]; + tint.alpha = byte2float[Surface->TintColor.s.alpha]; + + fade.red = byte2float[Surface->FadeColor.s.red]; + fade.green = byte2float[Surface->FadeColor.s.green]; + fade.blue = byte2float[Surface->FadeColor.s.blue]; + fade.alpha = byte2float[Surface->FadeColor.s.alpha]; + + load_shaders(Surface, &poly, &tint, &fade); pglEnable(GL_CULL_FACE); pglEnable(GL_NORMALIZE); @@ -1782,33 +2933,12 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 #else // pos->flip is if the screen is flipped too if (flipped != pos->flip) // If either are active, but not both, invert the model's culling - { pglCullFace(GL_FRONT); - } else - { pglCullFace(GL_BACK); - } #endif - pglLightfv(GL_LIGHT0, GL_POSITION, LightPos); - - pglShadeModel(GL_SMOOTH); - if (color) - { -#ifdef GL_LIGHT_MODEL_AMBIENT - pglEnable(GL_LIGHTING); - pglMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient); - pglMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse); -#endif - if (color[3] < 255) - SetBlend(PF_Translucent|PF_Modulated|PF_Clip); - else - SetBlend(PF_Masked|PF_Modulated|PF_Occlude|PF_Clip); - } - pglPushMatrix(); // should be the same as glLoadIdentity - //Hurdler: now it seems to work pglTranslatef(pos->x, pos->z, pos->y); if (flipped) scaley = -scaley; @@ -1845,7 +2975,6 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 pglVertexPointer(3, GL_SHORT, sizeof(vbotiny_t), BUFFER_OFFSET(0)); pglNormalPointer(GL_BYTE, sizeof(vbotiny_t), BUFFER_OFFSET(sizeof(short)*3)); pglTexCoordPointer(2, GL_FLOAT, sizeof(vbotiny_t), BUFFER_OFFSET(sizeof(short) * 3 + sizeof(char) * 6)); - pglDrawElements(GL_TRIANGLES, mesh->numTriangles * 3, GL_UNSIGNED_SHORT, mesh->indices); pglBindBuffer(GL_ARRAY_BUFFER, 0); } @@ -1853,13 +2982,12 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 { short *vertPtr; char *normPtr; - int j; + int j = 0; // Dangit, I soooo want to do this in a GLSL shader... AllocLerpTinyBuffer(mesh->numVertices * sizeof(short) * 3); vertPtr = vertTinyBuffer; normPtr = normTinyBuffer; - j = 0; for (j = 0; j < mesh->numVertices * 3; j++) { @@ -1885,19 +3013,12 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 if (!nextframe || fpclassify(pol) == FP_ZERO) { // Zoom! Take advantage of just shoving the entire arrays to the GPU. -/* pglVertexPointer(3, GL_FLOAT, 0, frame->vertices); - pglNormalPointer(GL_FLOAT, 0, frame->normals); - pglTexCoordPointer(2, GL_FLOAT, 0, mesh->uvs); - pglDrawArrays(GL_TRIANGLES, 0, mesh->numTriangles * 3);*/ - pglBindBuffer(GL_ARRAY_BUFFER, frame->vboID); pglVertexPointer(3, GL_FLOAT, sizeof(vbo64_t), BUFFER_OFFSET(0)); pglNormalPointer(GL_FLOAT, sizeof(vbo64_t), BUFFER_OFFSET(sizeof(float) * 3)); pglTexCoordPointer(2, GL_FLOAT, sizeof(vbo64_t), BUFFER_OFFSET(sizeof(float) * 6)); pglDrawArrays(GL_TRIANGLES, 0, mesh->numTriangles * 3); - // No tinyframes, no mesh indices - //pglDrawElements(GL_TRIANGLES, mesh->numTriangles * 3, GL_UNSIGNED_SHORT, mesh->indices); pglBindBuffer(GL_ARRAY_BUFFER, 0); } else @@ -1910,7 +3031,6 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 AllocLerpBuffer(mesh->numVertices * sizeof(float) * 3); vertPtr = vertBuffer; normPtr = normBuffer; - //int j = 0; for (j = 0; j < mesh->numVertices * 3; j++) { @@ -1930,19 +3050,16 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 pglDisableClientState(GL_NORMAL_ARRAY); pglPopMatrix(); // should be the same as glLoadIdentity - if (color) - pglDisable(GL_LIGHTING); - pglShadeModel(GL_FLAT); pglDisable(GL_CULL_FACE); pglDisable(GL_NORMALIZE); } // -----------------+ -// HWRAPI DrawMD2 : Draw an MD2 model with glcommands +// HWRAPI DrawModel : Draw a model // -----------------+ -EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 *color) +EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, FSurfaceInfo *Surface) { - DrawModelEx(model, frameIndex, duration, tics, nextFrameIndex, pos, scale, flipped, color); + DrawModelEx(model, frameIndex, duration, tics, nextFrameIndex, pos, scale, flipped, Surface); } // -----------------+ @@ -1952,10 +3069,12 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform) { static boolean special_splitscreen; GLdouble used_fov; + boolean shearing = false; pglLoadIdentity(); if (stransform) { used_fov = stransform->fovxangle; + shearing = stransform->shearing; // keep a trace of the transformation for md2 memcpy(&md2_transform, stransform, sizeof (md2_transform)); @@ -1970,7 +3089,8 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform) else pglScalef(stransform->scalex, stransform->scaley, -stransform->scalez); - pglRotatef(stransform->anglex , 1.0f, 0.0f, 0.0f); + pglMatrixMode(GL_MODELVIEW); + pglRotatef(stransform->anglex, 1.0f, 0.0f, 0.0f); pglRotatef(stransform->angley+270.0f, 0.0f, 1.0f, 0.0f); pglTranslatef(-stransform->x, -stransform->z, -stransform->y); @@ -1985,9 +3105,19 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform) pglMatrixMode(GL_PROJECTION); pglLoadIdentity(); + + // jimita 14042019 + // Simulate Software's y-shearing + // https://zdoom.org/wiki/Y-shearing + if (shearing) + { + float dy = FIXED_TO_FLOAT(AIMINGTODY(stransform->viewaiming)) * 2; //screen_width/BASEVIDWIDTH; + pglTranslatef(0.0f, -dy/BASEVIDHEIGHT, 0.0f); + } + if (special_splitscreen) { - used_fov = atan(tan(used_fov*M_PIl/360.0l)*0.8l)*360/M_PIl; + used_fov = atan(tan(used_fov*M_PIl/360)*0.8)*360/M_PIl; GLPerspective((GLfloat)used_fov, 2*ASPECT_RATIO); } else @@ -2011,11 +3141,6 @@ EXPORT INT32 HWRAPI(GetTextureUsed) (void) return res; } -EXPORT INT32 HWRAPI(GetRenderVersion) (void) -{ - return VERSION; -} - EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]) { INT32 x, y; @@ -2031,7 +3156,7 @@ EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]) 16.0f, -16.0f, 6.0f }; - // Use a power of two texture, dammit + // Use a power of two texture if(screen_width <= 1024) texsize = 1024; if(screen_width <= 512) @@ -2044,8 +3169,6 @@ EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]) pglDisable(GL_DEPTH_TEST); pglDisable(GL_BLEND); - // const float blackBack[16] - // Draw a black square behind the screen texture, // so nothing shows through the edges pglColor4ubv(white); @@ -2053,6 +3176,7 @@ EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]) pglVertexPointer(3, GL_FLOAT, 0, blackBack); pglDrawArrays(GL_TRIANGLE_FAN, 0, 4); + pglEnableClientState(GL_TEXTURE_COORD_ARRAY); for(x=0;x0; i--) { - const char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i-1]); + char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i-1]); size_t j = 0; INT32 linescount = 0; @@ -1524,6 +1524,8 @@ static void HU_drawMiniChat(void) dy = 0; dx = 0; msglines += linescount+1; + if (msg) + Z_Free(msg); } y = chaty - charheight*(msglines+1); @@ -1550,7 +1552,7 @@ static void HU_drawMiniChat(void) INT32 timer = ((cv_chattime.value*TICRATE)-chat_timers[i]) - cv_chattime.value*TICRATE+9; // see below... INT32 transflag = (timer >= 0 && timer <= 9) ? (timer*V_10TRANS) : 0; // you can make bad jokes out of this one. size_t j = 0; - const char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i]); // get the current message, and word wrap it. + char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i]); // get the current message, and word wrap it. UINT8 *colormap = NULL; while(msg[j]) // iterate through msg @@ -1596,6 +1598,8 @@ static void HU_drawMiniChat(void) } dy += charheight; dx = 0; + if (msg) + Z_Free(msg); } // decrement addy and make that shit smooth: @@ -1651,7 +1655,7 @@ static void HU_drawChatLog(INT32 offset) { INT32 clrflag = 0; INT32 j = 0; - const char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_log[i]); // get the current message, and word wrap it. + char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_log[i]); // get the current message, and word wrap it. UINT8 *colormap = NULL; while(msg[j]) // iterate through msg { @@ -1691,6 +1695,8 @@ static void HU_drawChatLog(INT32 offset) } dy += charheight; dx = 0; + if (msg) + Z_Free(msg); } diff --git a/src/i_system.h b/src/i_system.h index d1708fe5a..3e589c69a 100644 --- a/src/i_system.h +++ b/src/i_system.h @@ -226,10 +226,6 @@ void I_StartupMouse(void); */ void I_StartupMouse2(void); -/** \brief keyboard startup, shutdown, handler -*/ -void I_StartupKeyboard(void); - /** \brief setup timer irq and user timer routine. */ void I_StartupTimer(void); diff --git a/src/i_tcp.c b/src/i_tcp.c index f58aa22bc..7de94573d 100644 --- a/src/i_tcp.c +++ b/src/i_tcp.c @@ -508,6 +508,8 @@ static boolean SOCK_cmpaddr(mysockaddr_t *a, mysockaddr_t *b, UINT8 mask) return false; } +static void SOCK_FreeNodenum(INT32 numnode); + // This is a hack. For some reason, nodes aren't being freed properly. // This goes through and cleans up what nodes were supposed to be freed. /** \warning This function causes the file downloading to stop if someone joins. @@ -524,7 +526,7 @@ static void cleanupnodes(void) // Why can't I start at zero? for (j = 1; j < MAXNETNODES; j++) if (!(nodeingame[j] || SV_SendingFile(j))) - nodeconnected[j] = false; + SOCK_FreeNodenum(j); // At least free this PROPERLY } static SINT8 getfreenode(void) @@ -624,6 +626,13 @@ static boolean SOCK_Get(void) } // not found + if (netbuffer->packettype == PT_NOTHING) + { + DEBFILE(va("Ackret received from disconnected address:%s, ignoring...\n", SOCK_AddrToStr(&fromaddress))); + doomcom->remotenode = -1; // no packet + return true; + } + // find a free slot j = getfreenode(); if (j > 0) @@ -650,7 +659,11 @@ static boolean SOCK_Get(void) return true; } else + { DEBFILE("New node detected: No more free slots\n"); + doomcom->remotenode = -1; // no packet + return true; + } } } diff --git a/src/info.c b/src/info.c index d609bf553..d639b617e 100644 --- a/src/info.c +++ b/src/info.c @@ -20,9 +20,6 @@ #include "z_zone.h" #include "d_player.h" #include "lzf.h" -#ifdef HWRENDER -#include "hardware/hw_light.h" -#endif // Hey, moron! If you change this table, don't forget about the sprite enum in info.h and the sprite lights in hw_light.c! char sprnames[NUMSPRITES + 1][5] = @@ -20101,7 +20098,7 @@ void P_PatchInfoTables(void) char *tempname; #if NUMSPRITEFREESLOTS > 1000 -"Update P_PatchInfoTables, you big dumb head" +#error "Update P_PatchInfoTables, you big dumb head" #endif // empty out free slots @@ -20113,9 +20110,6 @@ void P_PatchInfoTables(void) tempname[2] = (char)('0' + (char)(((i-SPR_FIRSTFREESLOT+1)/10)%10)); tempname[3] = (char)('0' + (char)((i-SPR_FIRSTFREESLOT+1)%10)); tempname[4] = '\0'; -#ifdef HWRENDER - t_lspr[i] = &lspr[NOLIGHT]; -#endif } sprnames[i][0] = '\0'; // i == NUMSPRITES memset(&states[S_FIRSTFREESLOT], 0, sizeof (state_t) * NUMSTATEFREESLOTS); diff --git a/src/info.h b/src/info.h index 0e23a07c5..a00b53d08 100644 --- a/src/info.h +++ b/src/info.h @@ -226,7 +226,7 @@ void A_NapalmScatter(); void A_SpawnFreshCopy(); // ratio of states to sprites to mobj types is roughly 6 : 1 : 1 -#define NUMMOBJFREESLOTS 256 +#define NUMMOBJFREESLOTS 512 #define NUMSPRITEFREESLOTS NUMMOBJFREESLOTS #define NUMSTATEFREESLOTS (NUMMOBJFREESLOTS*8) @@ -4301,7 +4301,7 @@ typedef enum mobj_type // Castle Eggman Scenery MT_CHAIN, // CEZ Chain - MT_FLAME, // Flame (has corona) + MT_FLAME, // Flame MT_EGGSTATUE, // Eggman Statue MT_MACEPOINT, // Mace rotation point MT_SWINGMACEPOINT, // Mace swinging point diff --git a/src/k_kart.c b/src/k_kart.c index f9af5a24f..04ba82441 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -409,7 +409,7 @@ UINT8 colortranslations[MAXTRANSLATIONS][16] = { // 0.0722 to blue // (See this same define in hw_md2.c!) #define SETBRIGHTNESS(brightness,r,g,b) \ - brightness = (UINT8)(((1063*((UINT16)r)/5000) + (3576*((UINT16)g)/5000) + (361*((UINT16)b)/5000)) / 3) + brightness = (UINT8)(((1063*(UINT16)(r))/5000) + ((3576*(UINT16)(g))/5000) + ((361*(UINT16)(b))/5000)) /** \brief Generates the rainbow colourmaps that are used when a player has the invincibility power diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 32cbbf4fd..d7292cd60 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -774,11 +774,14 @@ static int lib_pRestoreMusic(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); NOHUD - if (!player) - return LUA_ErrInvalid(L, "player_t"); - if (P_IsLocalPlayer(player)) + if (!player || P_IsLocalPlayer(player)) + { P_RestoreMusic(player); - return 0; + lua_pushboolean(L, true); + } + else + lua_pushnil(L); + return 1; } static int lib_pSpawnShieldOrb(lua_State *L) @@ -1867,8 +1870,13 @@ static int lib_sChangeMusic(lua_State *L) fadeinms = (UINT32)luaL_optinteger(L, 7, 0); if (!player || P_IsLocalPlayer(player)) + { S_ChangeMusicEx(music_name, music_flags, looping, position, prefadems, fadeinms); - return 0; + lua_pushboolean(L, true); + } + else + lua_pushnil(L); + return 1; } static int lib_sSpeedMusic(lua_State *L) @@ -1884,8 +1892,230 @@ static int lib_sSpeedMusic(lua_State *L) return LUA_ErrInvalid(L, "player_t"); } if (!player || P_IsLocalPlayer(player)) - S_SpeedMusic(speed); - return 0; + lua_pushboolean(L, S_SpeedMusic(speed)); + else + lua_pushnil(L); + return 1; +} + +static int lib_sMusicType(lua_State *L) +{ + player_t *player = NULL; + NOHUD + if (!lua_isnone(L, 1) && lua_isuserdata(L, 1)) + { + player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + if (!player) + return LUA_ErrInvalid(L, "player_t"); + } + if (!player || P_IsLocalPlayer(player)) + lua_pushinteger(L, S_MusicType()); + else + lua_pushnil(L); + return 1; +} + +static int lib_sMusicPlaying(lua_State *L) +{ + player_t *player = NULL; + NOHUD + if (!lua_isnone(L, 1) && lua_isuserdata(L, 1)) + { + player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + if (!player) + return LUA_ErrInvalid(L, "player_t"); + } + if (!player || P_IsLocalPlayer(player)) + lua_pushboolean(L, S_MusicPlaying()); + else + lua_pushnil(L); + return 1; +} + +static int lib_sMusicPaused(lua_State *L) +{ + player_t *player = NULL; + NOHUD + if (!lua_isnone(L, 1) && lua_isuserdata(L, 1)) + { + player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + if (!player) + return LUA_ErrInvalid(L, "player_t"); + } + if (!player || P_IsLocalPlayer(player)) + lua_pushboolean(L, S_MusicPaused()); + else + lua_pushnil(L); + return 1; +} + +static int lib_sMusicName(lua_State *L) +{ + player_t *player = NULL; + NOHUD + if (!lua_isnone(L, 1) && lua_isuserdata(L, 1)) + { + player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + if (!player) + return LUA_ErrInvalid(L, "player_t"); + } + if (!player || P_IsLocalPlayer(player)) + lua_pushstring(L, S_MusicName()); + else + lua_pushnil(L); + return 1; +} + +static int lib_sMusicInfo(lua_State *L) +{ + player_t *player = NULL; + NOHUD + if (!lua_isnone(L, 1) && lua_isuserdata(L, 1)) + { + player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + if (!player) + return LUA_ErrInvalid(L, "player_t"); + } + if (!player || P_IsLocalPlayer(player)) + { + char mname[7]; + UINT16 mflags; + boolean looping; + if (S_MusicInfo(mname, &mflags, &looping)) + { + lua_pushstring(L, mname); + lua_pushinteger(L, mflags); + lua_pushboolean(L, looping); + } + else + lua_pushboolean(L, false); + } + else + lua_pushnil(L); + return 1; +} + +static int lib_sMusicExists(lua_State *L) +{ + boolean checkMIDI = lua_opttrueboolean(L, 2); + boolean checkDigi = lua_opttrueboolean(L, 3); +#ifdef MUSICSLOT_COMPATIBILITY + const char *music_name; + UINT32 music_num; + char music_compat_name[7]; + UINT16 music_flags = 0; + NOHUD + if (lua_isnumber(L, 1)) + { + music_num = (UINT32)luaL_checkinteger(L, 1); + music_flags = (UINT16)(music_num & 0x0000FFFF); + if (music_flags && music_flags <= 1035) + snprintf(music_compat_name, 7, "%sM", G_BuildMapName((INT32)music_flags)); + else if (music_flags && music_flags <= 1050) + strncpy(music_compat_name, compat_special_music_slots[music_flags - 1036], 7); + else + music_compat_name[0] = 0; // becomes empty string + music_compat_name[6] = 0; + music_name = (const char *)&music_compat_name; + } + else + { + music_num = 0; + music_name = luaL_checkstring(L, 1); + } +#else + const char *music_name = luaL_checkstring(L, 1); +#endif + NOHUD + lua_pushboolean(L, S_MusicExists(music_name, checkMIDI, checkDigi)); + return 1; +} + +static int lib_sGetMusicLength(lua_State *L) +{ + player_t *player = NULL; + NOHUD + if (!lua_isnone(L, 1) && lua_isuserdata(L, 1)) + { + player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + if (!player) + return LUA_ErrInvalid(L, "player_t"); + } + if (!player || P_IsLocalPlayer(player)) + lua_pushinteger(L, (int)S_GetMusicLength()); + else + lua_pushnil(L); + return 1; +} + +static int lib_sSetMusicLoopPoint(lua_State *L) +{ + UINT32 looppoint = (UINT32)luaL_checkinteger(L, 1); + player_t *player = NULL; + NOHUD + if (!lua_isnone(L, 2) && lua_isuserdata(L, 2)) + { + player = *((player_t **)luaL_checkudata(L, 2, META_PLAYER)); + if (!player) + return LUA_ErrInvalid(L, "player_t"); + } + if (!player || P_IsLocalPlayer(player)) + lua_pushboolean(L, S_SetMusicLoopPoint(looppoint)); + else + lua_pushnil(L); + return 1; +} + +static int lib_sGetMusicLoopPoint(lua_State *L) +{ + player_t *player = NULL; + NOHUD + if (!lua_isnone(L, 1) && lua_isuserdata(L, 1)) + { + player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + if (!player) + return LUA_ErrInvalid(L, "player_t"); + } + if (!player || P_IsLocalPlayer(player)) + lua_pushinteger(L, (int)S_GetMusicLoopPoint()); + else + lua_pushnil(L); + return 1; +} + +static int lib_sSetMusicPosition(lua_State *L) +{ + UINT32 position = (UINT32)luaL_checkinteger(L, 1); + player_t *player = NULL; + NOHUD + if (!lua_isnone(L, 2) && lua_isuserdata(L, 2)) + { + player = *((player_t **)luaL_checkudata(L, 2, META_PLAYER)); + if (!player) + return LUA_ErrInvalid(L, "player_t"); + } + if (!player || P_IsLocalPlayer(player)) + lua_pushboolean(L, S_SetMusicPosition(position)); + else + lua_pushnil(L); + return 1; +} + +static int lib_sGetMusicPosition(lua_State *L) +{ + player_t *player = NULL; + NOHUD + if (!lua_isnone(L, 1) && lua_isuserdata(L, 1)) + { + player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + if (!player) + return LUA_ErrInvalid(L, "player_t"); + } + if (!player || P_IsLocalPlayer(player)) + lua_pushinteger(L, (int)S_GetMusicPosition()); + else + lua_pushnil(L); + return 1; } static int lib_sStopMusic(lua_State *L) @@ -1899,8 +2129,53 @@ static int lib_sStopMusic(lua_State *L) return LUA_ErrInvalid(L, "player_t"); } if (!player || P_IsLocalPlayer(player)) + { S_StopMusic(); - return 0; + lua_pushboolean(L, true); + } + else + lua_pushnil(L); + return 1; +} + +static int lib_sPauseMusic(lua_State *L) +{ + player_t *player = NULL; + NOHUD + if (!lua_isnone(L, 1) && lua_isuserdata(L, 1)) + { + player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + if (!player) + return LUA_ErrInvalid(L, "player_t"); + } + if (!player || P_IsLocalPlayer(player)) + { + S_PauseAudio(); + lua_pushboolean(L, true); + } + else + lua_pushnil(L); + return 1; +} + +static int lib_sResumeMusic(lua_State *L) +{ + player_t *player = NULL; + NOHUD + if (!lua_isnone(L, 1) && lua_isuserdata(L, 1)) + { + player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + if (!player) + return LUA_ErrInvalid(L, "player_t"); + } + if (!player || P_IsLocalPlayer(player)) + { + S_ResumeAudio(); + lua_pushboolean(L, true); + } + else + lua_pushnil(L); + return 1; } static int lib_sSetInternalMusicVolume(lua_State *L) @@ -2837,6 +3112,19 @@ static luaL_Reg lib[] = { {"S_ShowMusicCredit",lib_sShowMusicCredit}, {"S_ChangeMusic",lib_sChangeMusic}, {"S_SpeedMusic",lib_sSpeedMusic}, + {"S_MusicType",lib_sMusicType}, + {"S_MusicPlaying",lib_sMusicPlaying}, + {"S_MusicPaused",lib_sMusicPaused}, + {"S_MusicName",lib_sMusicName}, + {"S_MusicInfo",lib_sMusicInfo}, + {"S_MusicExists",lib_sMusicExists}, + {"S_GetMusicLength",lib_sGetMusicLength}, + {"S_SetMusicLoopPoint",lib_sSetMusicLoopPoint}, + {"S_GetMusicLoopPoint",lib_sGetMusicLoopPoint}, + {"S_SetMusicPosition",lib_sSetMusicPosition}, + {"S_GetMusicPosition",lib_sGetMusicPosition}, + {"S_PauseMusic",lib_sPauseMusic}, + {"S_ResumeMusic",lib_sResumeMusic}, {"S_StopMusic",lib_sStopMusic}, {"S_SetInternalMusicVolume", lib_sSetInternalMusicVolume}, {"S_StopFadingMusic",lib_sStopFadingMusic}, diff --git a/src/lua_hook.h b/src/lua_hook.h index a12998bd8..6af3941f1 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -44,6 +44,7 @@ enum hook { hook_HurtMsg, hook_PlayerSpawn, hook_PlayerQuit, + hook_MusicChange, hook_ShouldSpin, //SRB2KART hook_ShouldExplode, //SRB2KART hook_ShouldSquish, //SRB2KART @@ -90,6 +91,8 @@ boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg, int mute); boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source); // Hook for hurt messages #define LUAh_PlayerSpawn(player) LUAh_PlayerHook(player, hook_PlayerSpawn) // Hook for G_SpawnPlayer void LUAh_PlayerQuit(player_t *plr, int reason); // Hook for player quitting +boolean LUAh_MusicChange(const char *oldname, char *newname, UINT16 *mflags, boolean *looping, + UINT32 *position, UINT32 *prefadems, UINT32 *fadeinms); // Hook for music changes UINT8 LUAh_ShouldSpin(player_t *player, mobj_t *inflictor, mobj_t *source); // SRB2KART: Should player be spun out? UINT8 LUAh_ShouldExplode(player_t *player, mobj_t *inflictor, mobj_t *source); // SRB2KART: Should player be exploded? diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 009a16dda..41a436e01 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -55,6 +55,7 @@ const char *const hookNames[hook_MAX+1] = { "HurtMsg", "PlayerSpawn", "PlayerQuit", + "MusicChange", "ShouldSpin", "ShouldExplode", "ShouldSquish", @@ -1213,6 +1214,65 @@ void LUAh_PlayerQuit(player_t *plr, int reason) lua_settop(gL, 0); } +// Hook for music changes +boolean LUAh_MusicChange(const char *oldname, char *newname, UINT16 *mflags, boolean *looping, + UINT32 *position, UINT32 *prefadems, UINT32 *fadeinms) +{ + hook_p hookp; + boolean hooked = false; + + if (!gL || !(hooksAvailable[hook_MusicChange/8] & (1<<(hook_MusicChange%8)))) + return false; + + lua_settop(gL, 0); + + for (hookp = roothook; hookp; hookp = hookp->next) + if (hookp->type == hook_MusicChange) + { + lua_pushfstring(gL, FMT_HOOKID, hookp->id); + lua_gettable(gL, LUA_REGISTRYINDEX); + lua_pushstring(gL, oldname); + lua_pushstring(gL, newname); + lua_pushinteger(gL, *mflags); + lua_pushboolean(gL, *looping); + lua_pushinteger(gL, *position); + lua_pushinteger(gL, *prefadems); + lua_pushinteger(gL, *fadeinms); + if (lua_pcall(gL, 7, 6, 0)) { + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1)); + lua_pop(gL, 1); + continue; + } + + // output 1: true, false, or string musicname override + if (lua_isboolean(gL, -6) && lua_toboolean(gL, -6)) + hooked = true; + else if (lua_isstring(gL, -6)) + strncpy(newname, lua_tostring(gL, -6), 7); + // output 2: mflags override + if (lua_isnumber(gL, -5)) + *mflags = lua_tonumber(gL, -5); + // output 3: looping override + if (lua_isboolean(gL, -4)) + *looping = lua_toboolean(gL, -4); + // output 4: position override + if (lua_isboolean(gL, -3)) + *position = lua_tonumber(gL, -3); + // output 5: prefadems override + if (lua_isboolean(gL, -2)) + *prefadems = lua_tonumber(gL, -2); + // output 6: fadeinms override + if (lua_isboolean(gL, -1)) + *fadeinms = lua_tonumber(gL, -1); + + lua_pop(gL, 6); + } + + lua_settop(gL, 0); + newname[6] = 0; + return hooked; +} + // Hook for K_SpinPlayer. Determines if yes or no we should get damaged reguardless of circumstances. UINT8 LUAh_ShouldSpin(player_t *player, mobj_t *inflictor, mobj_t *source) { diff --git a/src/m_fixed.c b/src/m_fixed.c index 5e7896739..7241be9c0 100644 --- a/src/m_fixed.c +++ b/src/m_fixed.c @@ -411,6 +411,19 @@ boolean FV3_Equal(const vector3_t *a_1, const vector3_t *a_2) return false; } +// ClosestPointOnVector +// +// Similar to ClosestPointOnLine, but uses a vector instead of two points. +// +void FV3_ClosestPointOnVector(const vector3_t *dir, const vector3_t *p, vector3_t *out) +{ + fixed_t t = FV3_Dot(dir, p); + + // Return the point on the line closest + FV3_MulEx(dir, t, out); + return; +} + fixed_t FV3_Dot(const vector3_t *a_1, const vector3_t *a_2) { return (FixedMul(a_1->x, a_2->x) + FixedMul(a_1->y, a_2->y) + FixedMul(a_1->z, a_2->z)); @@ -458,19 +471,6 @@ vector3_t *FV3_ClosestPointOnLine(const vector3_t *Line, const vector3_t *p, vec return FV3_AddEx(&Line[0], &V, out); } -// -// ClosestPointOnVector -// -// Similar to ClosestPointOnLine, but uses a vector instead of two points. -// -void FV3_ClosestPointOnVector(const vector3_t *dir, const vector3_t *p, vector3_t *out) -{ - fixed_t t = FV3_Dot(dir, p); - - // Return the point on the line closest - FV3_MulEx(dir, t, out); - return; -} // // ClosestPointOnTriangle diff --git a/src/m_menu.c b/src/m_menu.c index 7bbe1e9b8..223bc31b9 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -279,7 +279,7 @@ static void M_ResetControls(INT32 choice); // Video & Sound menu_t OP_VideoOptionsDef, OP_VideoModeDef; #ifdef HWRENDER -menu_t OP_OpenGLOptionsDef, OP_OpenGLFogDef, OP_OpenGLColorDef; +menu_t OP_OpenGLOptionsDef, OP_OpenGLColorDef; #endif menu_t OP_SoundOptionsDef; //static void M_RestartAudio(void); @@ -346,7 +346,6 @@ static void M_DrawHUDOptions(void); static void M_DrawVideoMode(void); static void M_DrawMonitorToggles(void); #ifdef HWRENDER -static void M_OGL_DrawFogMenu(void); static void M_OGL_DrawColorMenu(void); #endif static void M_DrawMPMainMenu(void); @@ -372,9 +371,6 @@ static void M_HandleLevelStats(INT32 choice); static void M_HandleConnectIP(INT32 choice); #endif static void M_HandleSetupMultiPlayer(INT32 choice); -#ifdef HWRENDER -static void M_HandleFogColor(INT32 choice); -#endif static void M_HandleVideoMode(INT32 choice); static void M_HandleMonitorToggles(INT32 choice); @@ -578,7 +574,7 @@ typedef enum // --------------------- static menuitem_t MPauseMenu[] = { - {IT_STRING | IT_CALL, NULL, "Add-ons...", M_Addons, 8}, + {IT_STRING | IT_CALL, NULL, "Addons...", M_Addons, 8}, {IT_STRING | IT_SUBMENU, NULL, "Scramble Teams...", &MISC_ScrambleTeamDef, 16}, {IT_STRING | IT_CALL, NULL, "Switch Map..." , M_MapChange, 24}, @@ -1245,15 +1241,13 @@ static menuitem_t OP_VideoOptionsMenu[] = {IT_STRING | IT_CVAR, NULL, "Weather Draw Distance",&cv_drawdist_precip, 55}, //{IT_STRING | IT_CVAR, NULL, "Weather Density", &cv_precipdensity, 65}, {IT_STRING | IT_CVAR, NULL, "Skyboxes", &cv_skybox, 65}, - {IT_STRING | IT_CVAR, NULL, "Field of View", &cv_fov, 75}, + {IT_STRING | IT_CVAR, NULL, "Field of View", &cv_fov, 75}, {IT_STRING | IT_CVAR, NULL, "Show FPS", &cv_ticrate, 90}, {IT_STRING | IT_CVAR, NULL, "Vertical Sync", &cv_vidwait, 100}, #ifdef HWRENDER - {IT_STRING | IT_CVAR, NULL, "3D models", &cv_grmdls, 115}, - {IT_STRING | IT_CVAR, NULL, "Fallback Player 3D Model", &cv_grfallbackplayermodel, 125}, - {IT_SUBMENU|IT_STRING, NULL, "OpenGL Options...", &OP_OpenGLOptionsDef, 135}, + {IT_SUBMENU|IT_STRING, NULL, "OpenGL Options...", &OP_OpenGLOptionsDef, 120}, #endif }; @@ -1272,8 +1266,6 @@ enum op_video_fps, op_video_vsync, #ifdef HWRENDER - op_video_md2, - op_video_kartman, op_video_ogl, #endif }; @@ -1286,36 +1278,19 @@ static menuitem_t OP_VideoModeMenu[] = #ifdef HWRENDER static menuitem_t OP_OpenGLOptionsMenu[] = { - {IT_SUBMENU|IT_STRING, NULL, "Fog...", &OP_OpenGLFogDef, 10}, - {IT_SUBMENU|IT_STRING, NULL, "Gamma...", &OP_OpenGLColorDef, 20}, + {IT_STRING | IT_CVAR, NULL, "3D Models", &cv_grmdls, 10}, + {IT_STRING | IT_CVAR, NULL, "Fallback Player 3D Model", &cv_grfallbackplayermodel, 20}, + {IT_STRING|IT_CVAR, NULL, "Shaders", &cv_grshaders, 30}, - {IT_STRING|IT_CVAR, NULL, "Quality", &cv_scr_depth, 35}, - {IT_STRING|IT_CVAR, NULL, "Texture Filter", &cv_grfiltermode, 45}, - {IT_STRING|IT_CVAR, NULL, "Anisotropic", &cv_granisotropicmode, 55}, -/*#ifdef _WINDOWS - {IT_STRING|IT_CVAR, NULL, "Fullscreen", &cv_fullscreen, 50}, -#endif -#ifdef ALAM_LIGHTING - {IT_SUBMENU|IT_STRING, NULL, "Lighting...", &OP_OpenGLLightingDef, 70}, -#endif*/ -}; + {IT_STRING|IT_CVAR, NULL, "Texture Quality", &cv_scr_depth, 50}, + {IT_STRING|IT_CVAR, NULL, "Texture Filter", &cv_grfiltermode, 60}, + {IT_STRING|IT_CVAR, NULL, "Anisotropic", &cv_granisotropicmode, 70}, -#ifdef ALAM_LIGHTING -static menuitem_t OP_OpenGLLightingMenu[] = -{ - {IT_STRING|IT_CVAR, NULL, "Coronas", &cv_grcoronas, 0}, - {IT_STRING|IT_CVAR, NULL, "Coronas size", &cv_grcoronasize, 10}, - {IT_STRING|IT_CVAR, NULL, "Dynamic lighting", &cv_grdynamiclighting, 20}, - {IT_STRING|IT_CVAR, NULL, "Static lighting", &cv_grstaticlighting, 30}, -}; -#endif + {IT_STRING|IT_CVAR, NULL, "Wall Contrast Style", &cv_grfakecontrast, 90}, + {IT_STRING|IT_CVAR, NULL, "Sprite Billboarding", &cv_grspritebillboarding, 100}, + {IT_STRING|IT_CVAR, NULL, "Software Perspective", &cv_grshearing, 110}, -static menuitem_t OP_OpenGLFogMenu[] = -{ - {IT_STRING|IT_CVAR, NULL, "Fog", &cv_grfog, 10}, - {IT_STRING|IT_KEYHANDLER, NULL, "Fog Color", M_HandleFogColor, 20}, - {IT_STRING|IT_CVAR, NULL, "Fog Density", &cv_grfogdensity, 30}, - {IT_STRING|IT_CVAR, NULL, "Software Fog",&cv_grsoftwarefog,40}, + {IT_SUBMENU|IT_STRING, NULL, "Gamma...", &OP_OpenGLColorDef, 130}, }; static menuitem_t OP_OpenGLColorMenu[] = @@ -1363,7 +1338,7 @@ static menuitem_t OP_SoundOptionsMenu[] = static menuitem_t OP_DataOptionsMenu[] = { {IT_STRING | IT_CALL, NULL, "Screenshot Options...", M_ScreenshotOptions, 10}, - {IT_STRING | IT_CALL, NULL, "Add-on Options...", M_AddonsOptions, 20}, + {IT_STRING | IT_CALL, NULL, "Addon Options...", M_AddonsOptions, 20}, {IT_STRING | IT_SUBMENU, NULL, "Replay Options...", &MISC_ReplayOptionsDef, 30}, {IT_STRING | IT_SUBMENU, NULL, "Erase Data...", &OP_EraseDataDef, 50}, @@ -1415,7 +1390,7 @@ static menuitem_t OP_AddonsOptionsMenu[] = {IT_HEADER, NULL, "Menu", NULL, 0}, {IT_STRING|IT_CVAR, NULL, "Location", &cv_addons_option, 10}, {IT_STRING|IT_CVAR|IT_CV_STRING, NULL, "Custom Folder", &cv_addons_folder, 20}, - {IT_STRING|IT_CVAR, NULL, "Identify add-ons via", &cv_addons_md5, 48}, + {IT_STRING|IT_CVAR, NULL, "Identify addons via", &cv_addons_md5, 48}, {IT_STRING|IT_CVAR, NULL, "Show unsupported file types", &cv_addons_showall, 58}, {IT_HEADER, NULL, "Search", NULL, 76}, @@ -1502,7 +1477,7 @@ static menuitem_t OP_ServerOptionsMenu[] = #ifndef NONET {IT_STRING | IT_CVAR, NULL, "Max. Player Count", &cv_maxplayers, 90}, {IT_STRING | IT_CVAR, NULL, "Allow Players to Join", &cv_allownewplayer, 100}, - {IT_STRING | IT_CVAR, NULL, "Allow Add-on Downloading", &cv_downloading, 110}, + {IT_STRING | IT_CVAR, NULL, "Allow Addon Downloading", &cv_downloading, 110}, {IT_STRING | IT_CVAR, NULL, "Pause Permission", &cv_pause, 120}, {IT_STRING | IT_CVAR, NULL, "Mute All Chat", &cv_mute, 130}, @@ -2079,20 +2054,6 @@ menu_t OP_MonitorToggleDef = #ifdef HWRENDER menu_t OP_OpenGLOptionsDef = DEFAULTMENUSTYLE("M_VIDEO", OP_OpenGLOptionsMenu, &OP_VideoOptionsDef, 30, 30); -#ifdef ALAM_LIGHTING -menu_t OP_OpenGLLightingDef = DEFAULTMENUSTYLE("M_VIDEO", OP_OpenGLLightingMenu, &OP_OpenGLOptionsDef, 60, 40); -#endif -menu_t OP_OpenGLFogDef = -{ - "M_VIDEO", - sizeof (OP_OpenGLFogMenu)/sizeof (menuitem_t), - &OP_OpenGLOptionsDef, - OP_OpenGLFogMenu, - M_OGL_DrawFogMenu, - 60, 40, - 0, - NULL -}; menu_t OP_OpenGLColorDef = { "M_VIDEO", @@ -2912,7 +2873,7 @@ boolean M_Responder(event_t *ev) if (((currentMenu->menuitems[itemOn].status & IT_CALLTYPE) & IT_CALL_NOTMODIFIED) && majormods) { S_StartSound(NULL, sfx_menu1); - M_StartMessage(M_GetText("This cannot be done with complex add-ons\nor in a cheated game.\n\n(Press a key)\n"), NULL, MM_NOTHING); + M_StartMessage(M_GetText("This cannot be done with complex addons\nor in a cheated game.\n\n(Press a key)\n"), NULL, MM_NOTHING); return true; } } @@ -3476,9 +3437,7 @@ void M_Init(void) #ifdef HWRENDER // Permanently hide some options based on render mode if (rendermode == render_soft) - OP_VideoOptionsMenu[op_video_ogl].status = - OP_VideoOptionsMenu[op_video_kartman].status = - OP_VideoOptionsMenu[op_video_md2] .status = IT_DISABLED; + OP_VideoOptionsMenu[op_video_ogl].status = IT_DISABLED; #endif #ifndef NONET @@ -4643,21 +4602,11 @@ static void M_StopMessage(INT32 choice) // You can even put multiple images in one menu! static void M_DrawImageDef(void) { - // this is probably what the V_DrawFixedPatch screen-fill bullshit was for, right - //V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); -- never mind, screen fade - - // Grr. Need to autodetect for pic_ts. - pic_t *pictest = (pic_t *)W_CachePatchName(currentMenu->menuitems[itemOn].text,PU_CACHE); - if (!pictest->zero) - V_DrawScaledPic(0,0,0,W_GetNumForName(currentMenu->menuitems[itemOn].text)); + patch_t *patch = W_CachePatchName(currentMenu->menuitems[itemOn].text,PU_CACHE); + if (patch->width <= BASEVIDWIDTH) + V_DrawScaledPatch(0,0,0,patch); else - { - patch_t *patch = W_CachePatchName(currentMenu->menuitems[itemOn].text,PU_CACHE); - if (patch->height <= BASEVIDHEIGHT) - V_DrawScaledPatch(0,0,0,patch); - else - V_DrawSmallScaledPatch(0,0,0,patch); - } + V_DrawSmallScaledPatch(0,0,0,patch); if (currentMenu->menuitems[itemOn].alphaKey) { @@ -4727,8 +4676,8 @@ static void M_AddonsOptions(INT32 choice) M_SetupNextMenu(&OP_AddonsOptionsDef); } -#define LOCATIONSTRING1 "Visit \x83SRB2.ORG/MODS\x80 to get & make add-ons!" -#define LOCATIONSTRING2 "Visit \x88SRB2.ORG/MODS\x80 to get & make add-ons!" +#define LOCATIONSTRING1 "Visit \x83SRB2.ORG/MODS\x80 to get & make addons!" +#define LOCATIONSTRING2 "Visit \x88SRB2.ORG/MODS\x80 to get & make addons!" static void M_Addons(INT32 choice) { @@ -4904,7 +4853,7 @@ static boolean M_AddonsRefresh(void) { S_StartSound(NULL, sfx_s26d); if (refreshdirmenu & REFRESHDIR_MAX) - message = va("%c%s\x80\nMaximum number of add-ons reached.\nA file could not be loaded.\nIf you wish to play with this add-on, restart the game to clear existing ones.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname); + message = va("%c%s\x80\nMaximum number of addons reached.\nA file could not be loaded.\nIf you wish to play with this addon, restart the game to clear existing ones.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname); else message = va("%c%s\x80\nA file was not loaded.\nCheck the console log for more information.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname); } @@ -4916,7 +4865,7 @@ static boolean M_AddonsRefresh(void) else if (majormods && !prevmajormods) { S_StartSound(NULL, sfx_s221); - message = va("%c%s\x80\nGameplay has now been modified.\nIf you wish to play Record Attack mode, restart the game to clear existing add-ons.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname); + message = va("%c%s\x80\nGameplay has now been modified.\nIf you wish to play Record Attack mode, restart the game to clear existing addons.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname); prevmajormods = majormods; } @@ -5811,7 +5760,7 @@ static void M_DrawReplayStartMenu(void) case DFILE_ERROR_NOTLOADED: case DFILE_ERROR_INCOMPLETEOUTOFORDER: - warning = "Loading addons will mark your game as modified, and record attack may be unavailable.\nYou can watch without loading addons, but desyncs may occur."; + warning = "Loading addons will mark your game as modified, and Record Attack may be unavailable.\nYou can watch without loading addons, but desyncs may occur."; break; case DFILE_ERROR_EXTRAFILES: @@ -8623,7 +8572,7 @@ static void M_ConnectMenuModChecks(INT32 choice) if (modifiedgame) { - M_StartMessage(M_GetText("Add-ons are currently loaded.\n\nYou will only be able to join a server if\nit has the same ones loaded in the same order, which may be unlikely.\n\nIf you wish to play on other servers,\nrestart the game to clear existing add-ons.\n\n(Press a key)\n"),M_ConnectMenu,MM_EVENTHANDLER); + M_StartMessage(M_GetText("Addons are currently loaded.\n\nYou will only be able to join a server if\nit has the same ones loaded in the same order, which may be unlikely.\n\nIf you wish to play on other servers,\nrestart the game to clear existing addons.\n\n(Press a key)\n"),M_ConnectMenu,MM_EVENTHANDLER); return; } @@ -11165,25 +11114,6 @@ static void M_QuitSRB2(INT32 choice) // OpenGL specific options // ===================================================================== -#define FOG_COLOR_ITEM 1 -// =================== -// M_OGL_DrawFogMenu() -// =================== -static void M_OGL_DrawFogMenu(void) -{ - INT32 mx, my; - - mx = currentMenu->x; - my = currentMenu->y; - M_DrawGenericMenu(); // use generic drawer for cursor, items and title - V_DrawString(BASEVIDWIDTH - mx - V_StringWidth(cv_grfogcolor.string, 0), - my + currentMenu->menuitems[FOG_COLOR_ITEM].alphaKey, highlightflags, cv_grfogcolor.string); - // blink cursor on FOG_COLOR_ITEM if selected - if (itemOn == FOG_COLOR_ITEM && skullAnimCounter < 4) - V_DrawCharacter(BASEVIDWIDTH - mx, - my + currentMenu->menuitems[FOG_COLOR_ITEM].alphaKey, '_' | 0x80,false); -} - // ===================== // M_OGL_DrawColorMenu() // ===================== @@ -11197,61 +11127,4 @@ static void M_OGL_DrawColorMenu(void) V_DrawString(mx, my + currentMenu->menuitems[0].alphaKey - 10, highlightflags, "Gamma correction"); } - -//=================== -// M_HandleFogColor() -//=================== -static void M_HandleFogColor(INT32 choice) -{ - size_t i, l; - char temp[8]; - boolean exitmenu = false; // exit to previous menu and send name change - - switch (choice) - { - case KEY_DOWNARROW: - S_StartSound(NULL, sfx_menu1); - itemOn++; - break; - - case KEY_UPARROW: - S_StartSound(NULL, sfx_menu1); - itemOn--; - break; - - case KEY_ESCAPE: - exitmenu = true; - break; - - case KEY_BACKSPACE: - S_StartSound(NULL, sfx_menu1); - strcpy(temp, cv_grfogcolor.string); - strcpy(cv_grfogcolor.zstring, "000000"); - l = strlen(temp)-1; - for (i = 0; i < l; i++) - cv_grfogcolor.zstring[i + 6 - l] = temp[i]; - break; - - default: - if ((choice >= '0' && choice <= '9') || (choice >= 'a' && choice <= 'f') - || (choice >= 'A' && choice <= 'F')) - { - S_StartSound(NULL, sfx_menu1); - strcpy(temp, cv_grfogcolor.string); - strcpy(cv_grfogcolor.zstring, "000000"); - l = strlen(temp); - for (i = 0; i < l; i++) - cv_grfogcolor.zstring[5 - i] = temp[l - i]; - cv_grfogcolor.zstring[5] = (char)choice; - } - break; - } - if (exitmenu) - { - if (currentMenu->prevMenu) - M_SetupNextMenu(currentMenu->prevMenu); - else - M_ClearMenus(true); - } -} #endif diff --git a/src/m_misc.c b/src/m_misc.c index 2774910e5..6f07102bc 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -30,6 +30,7 @@ #include "g_game.h" #include "m_misc.h" #include "hu_stuff.h" +#include "st_stuff.h" #include "v_video.h" #include "z_zone.h" #include "g_input.h" @@ -586,6 +587,21 @@ void M_SaveConfig(const char *filename) fclose(f); } +// ========================================================================== +// SCREENSHOTS +// ========================================================================== +static UINT8 screenshot_palette[768]; +static void M_CreateScreenShotPalette(void) +{ + size_t i, j; + for (i = 0, j = 0; i < 768; i += 3, j++) + { + RGBA_t locpal = pLocalPalette[(max(st_palette,0)*256)+j]; + screenshot_palette[i] = locpal.s.red; + screenshot_palette[i+1] = locpal.s.green; + screenshot_palette[i+2] = locpal.s.blue; + } +} #if NUMSCREENS > 2 static const char *Newsnapshotfile(const char *pathname, const char *ext) @@ -1017,6 +1033,7 @@ static boolean M_SetupaPNG(png_const_charp filename, png_bytep pal) static inline moviemode_t M_StartMovieAPNG(const char *pathname) { #ifdef USE_APNG + UINT8 *palette; const char *freename = NULL; boolean ret = false; @@ -1032,10 +1049,8 @@ static inline moviemode_t M_StartMovieAPNG(const char *pathname) return MM_OFF; } - if (rendermode == render_soft) - ret = M_SetupaPNG(va(pandf,pathname,freename), W_CacheLumpName(GetPalette(), PU_CACHE)); - else - ret = M_SetupaPNG(va(pandf,pathname,freename), NULL); + if (rendermode == render_soft) M_CreateScreenShotPalette(); + ret = M_SetupaPNG(va(pandf,pathname,freename), (palette = screenshot_palette)); if (!ret) { @@ -1234,7 +1249,7 @@ void M_StopMovie(void) * \param data The image data. * \param width Width of the picture. * \param height Height of the picture. - * \param palette Palette of image data + * \param palette Palette of image data. * \note if palette is NULL, BGR888 format */ boolean M_SavePNG(const char *filename, void *data, int width, int height, const UINT8 *palette) @@ -1256,8 +1271,7 @@ boolean M_SavePNG(const char *filename, void *data, int width, int height, const return false; } - png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, - PNG_error, PNG_warn); + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, PNG_error, PNG_warn); if (!png_ptr) { CONS_Debug(DBG_RENDER, "M_SavePNG: Error on initialize libpng\n"); @@ -1411,9 +1425,8 @@ void M_ScreenShot(void) } /** Takes a screenshot. - * The screenshot is saved as "kartxxxx.pcx" (or "kartxxxx.tga" in hardware - * rendermode) where xxxx is the lowest four-digit number for which a file - * does not already exist. + * The screenshot is saved as "srb2xxxx.png" where xxxx is the lowest + * four-digit number for which a file does not already exist. * * \sa HWR_ScreenShot */ @@ -1427,6 +1440,10 @@ void M_DoScreenShot(void) // Don't take multiple screenshots, obviously takescreenshot = false; + // how does one take a screenshot without a render system? + if (rendermode == render_none) + return; + if (cv_screenshot_option.value == 0) pathname = usehome ? srb2home : srb2path; else if (cv_screenshot_option.value == 1) @@ -1437,16 +1454,13 @@ void M_DoScreenShot(void) pathname = cv_screenshot_folder.string; #ifdef USE_PNG - if (rendermode != render_none) - freename = Newsnapshotfile(pathname,"png"); + freename = Newsnapshotfile(pathname,"png"); #else if (rendermode == render_soft) freename = Newsnapshotfile(pathname,"pcx"); - else if (rendermode != render_none) + else if (rendermode == render_opengl) freename = Newsnapshotfile(pathname,"tga"); #endif - else - I_Error("Can't take a screenshot without a render system"); if (rendermode == render_soft) { @@ -1460,18 +1474,16 @@ void M_DoScreenShot(void) // save the pcx file #ifdef HWRENDER - if (rendermode != render_soft) + if (rendermode == render_opengl) ret = HWR_Screenshot(va(pandf,pathname,freename)); else #endif - if (rendermode != render_none) { + M_CreateScreenShotPalette(); #ifdef USE_PNG - ret = M_SavePNG(va(pandf,pathname,freename), linear, vid.width, vid.height, - W_CacheLumpName(GetPalette(), PU_CACHE)); + ret = M_SavePNG(va(pandf,pathname,freename), linear, vid.width, vid.height, screenshot_palette); #else - ret = WritePCXfile(va(pandf,pathname,freename), linear, vid.width, vid.height, - W_CacheLumpName(GetPalette(), PU_CACHE)); + ret = WritePCXfile(va(pandf,pathname,freename), linear, vid.width, vid.height, screenshot_palette); #endif } @@ -1479,14 +1491,14 @@ failure: if (ret) { if (moviemode != MM_SCREENSHOT) - CONS_Printf(M_GetText("screen shot %s saved in %s\n"), freename, pathname); + CONS_Printf(M_GetText("Screen shot %s saved in %s\n"), freename, pathname); } else { if (freename) - CONS_Printf(M_GetText("Couldn't create screen shot %s in %s\n"), freename, pathname); + CONS_Alert(CONS_ERROR, M_GetText("Couldn't create screen shot %s in %s\n"), freename, pathname); else - CONS_Printf(M_GetText("Couldn't create screen shot (all 10000 slots used!) in %s\n"), pathname); + CONS_Alert(CONS_ERROR, M_GetText("Couldn't create screen shot in %s (all 10000 slots used!)\n"), pathname); if (moviemode == MM_SCREENSHOT) M_StopMovie(); diff --git a/src/mserv.c b/src/mserv.c index c7344b16a..12469928d 100644 --- a/src/mserv.c +++ b/src/mserv.c @@ -751,7 +751,7 @@ static INT32 AddToMasterServer(boolean firstadd) strcpy(info->name, cv_servername.string); M_Memcpy(&info->room, & room, sizeof (INT32)); #if VERSION > 0 || SUBVERSION > 0 - sprintf(info->version, "%d.%d.%d", VERSION/100, VERSION%100, SUBVERSION); + sprintf(info->version, "%d.%d", VERSION, SUBVERSION); #else // Trunk build, send revision info strcpy(info->version, GetRevisionString()); #endif @@ -789,7 +789,7 @@ static INT32 RemoveFromMasterSever(void) strcpy(info->ip, ""); strcpy(info->port, int2str(current_port)); strcpy(info->name, registered_server.name); - sprintf(info->version, "%d.%d.%d", VERSION/100, VERSION%100, SUBVERSION); + sprintf(info->version, "%d.%d", VERSION, SUBVERSION); msg.type = REMOVE_SERVER_MSG; msg.length = (UINT32)sizeof (msg_server_t); diff --git a/src/nds/r_nds3d.c b/src/nds/r_nds3d.c index dbdcec158..6734e8c15 100644 --- a/src/nds/r_nds3d.c +++ b/src/nds/r_nds3d.c @@ -160,7 +160,7 @@ void NDS3D_DrawPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts z = pOutVerts[index].z; } - glTexCoord2f(pOutVerts[index].sow, pOutVerts[index].tow); + glTexCoord2f(pOutVerts[index].s, pOutVerts[index].tow); glVertex3f(x,y,z); } glEnd(); diff --git a/src/p_setup.c b/src/p_setup.c index 7e1154c79..decdc5291 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -465,11 +465,7 @@ static void P_LoadRawSegs(UINT8 *data, size_t i) li->length = P_SegLength(li); #ifdef HWRENDER if (rendermode == render_opengl) - { li->flength = P_SegLengthFloat(li); - //Hurdler: 04/12/2000: for now, only used in hardware mode - li->lightmaps = NULL; // list of static lightmap for this seg - } li->pv1 = li->pv2 = NULL; #endif @@ -2893,26 +2889,34 @@ boolean P_SetupLevel(boolean skipprecip) // Encore mode fade to pink to white // This is handled BEFORE sounds are stopped. - if (rendermode != render_none && encoremode && !prevencoremode && !demo.rewinding) + if (encoremode && !prevencoremode && !demo.rewinding) { tic_t locstarttime, endtime, nowtime; - S_StopMusic(); // er, about that... + if (rendermode != render_none) + { + S_StopMusic(); // er, about that... - S_StartSound(NULL, sfx_ruby1); + S_StartSound(NULL, sfx_ruby1); - F_WipeStartScreen(); - V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 122); + F_WipeStartScreen(); + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 122); - F_WipeEndScreen(); - F_RunWipe(wipedefs[wipe_speclevel_towhite], false); + F_WipeEndScreen(); + F_RunWipe(wipedefs[wipe_speclevel_towhite], false); - F_WipeStartScreen(); - V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 120); - - F_WipeEndScreen(); - F_RunWipe(wipedefs[wipe_level_final], false); + F_WipeStartScreen(); + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 120); + F_WipeEndScreen(); + F_RunWipe(wipedefs[wipe_level_final], false); + } + else //dedicated servers can call this now, to wait the appropriate amount of time for clients to wipe + { + F_RunWipe(wipedefs[wipe_speclevel_towhite], false); + F_RunWipe(wipedefs[wipe_level_final], false); + } + locstarttime = nowtime = lastwipetic; endtime = locstarttime + (3*TICRATE)/2; @@ -2945,13 +2949,20 @@ boolean P_SetupLevel(boolean skipprecip) // Let's fade to white here // But only if we didn't do the encore startup wipe - if (rendermode != render_none && !ranspecialwipe && !demo.rewinding) + if (!ranspecialwipe && !demo.rewinding) { - F_WipeStartScreen(); - V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, levelfadecol); + if(rendermode != render_none) + { + F_WipeStartScreen(); + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, levelfadecol); - F_WipeEndScreen(); - F_RunWipe(wipedefs[(encoremode ? wipe_level_final : wipe_level_toblack)], false); + F_WipeEndScreen(); + F_RunWipe(wipedefs[(encoremode ? wipe_level_final : wipe_level_toblack)], false); + } + else //dedicated servers + { + F_RunWipe(wipedefs[(encoremode ? wipe_level_final : wipe_level_toblack)], false); + } } // Reset the palette now all fades have been done @@ -3132,10 +3143,6 @@ boolean P_SetupLevel(boolean skipprecip) #ifdef HWRENDER // not win32 only 19990829 by Kin if (rendermode != render_soft && rendermode != render_none) { -#ifdef ALAM_LIGHTING - // BP: reset light between levels (we draw preview frame lights on current frame) - HWR_ResetLights(); -#endif // Correct missing sidedefs & deep water trick HWR_CorrectSWTricks(); HWR_CreatePlanePolygons((INT32)numnodes - 1); diff --git a/src/p_user.c b/src/p_user.c index 641652a1c..e0fb6fb47 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -7231,9 +7231,13 @@ static ticcmd_t *P_CameraCmd(camera_t *cam) boolean turnleft, turnright, mouseaiming; boolean invertmouse, lookaxis, usejoystick, kbl; angle_t lang; + INT32 player_invert; + INT32 screen_invert; ticcmd_t *cmd = &cameracmd; + (void)cam; + if (!demo.playback) return cmd; // empty cmd, no. @@ -7312,8 +7316,8 @@ static ticcmd_t *P_CameraCmd(camera_t *cam) // spectator aiming shit, ahhhh... - INT32 player_invert = invertmouse ? -1 : 1; - INT32 screen_invert = 1; // nope + player_invert = invertmouse ? -1 : 1; + screen_invert = 1; // nope // mouse look stuff (mouse look is not the same as mouse aim) kbl = false; @@ -7425,13 +7429,12 @@ void P_DemoCameraMovement(camera_t *cam) void P_ResetCamera(player_t *player, camera_t *thiscam) { + tic_t tries = 0; + fixed_t x, y, z; if (demo.freecam) return; // do not reset the camera there. - tic_t tries = 0; - fixed_t x, y, z; - if (!player->mo) return; diff --git a/src/r_bsp.h b/src/r_bsp.h index 3350ce8e9..1e4ca68fc 100644 --- a/src/r_bsp.h +++ b/src/r_bsp.h @@ -44,7 +44,6 @@ void R_AddPortal(INT32 line1, INT32 line2, INT32 x1, INT32 x2); // no longer a static since this is used for encore in hw_main.c as well now: boolean R_NoEncore(sector_t *sector, boolean ceiling); - #ifdef POLYOBJECTS void R_SortPolyObjects(subsector_t *sub); diff --git a/src/r_data.c b/src/r_data.c index d5e384bb9..25387deca 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -198,7 +198,7 @@ static UINT8 *R_GenerateTexture(size_t texnum) int x, x1, x2, i; size_t blocksize; column_t *patchcol; - UINT32 *colofs; + UINT8 *colofs; I_Assert(texnum <= (size_t)numtextures); texture = textures[texnum]; @@ -219,10 +219,10 @@ static UINT8 *R_GenerateTexture(size_t texnum) // Check the patch for holes. if (texture->width > SHORT(realpatch->width) || texture->height > SHORT(realpatch->height)) holey = true; - colofs = (UINT32 *)realpatch->columnofs; + colofs = (UINT8 *)realpatch->columnofs; for (x = 0; x < texture->width && !holey; x++) { - column_t *col = (column_t *)((UINT8 *)realpatch + LONG(colofs[x])); + column_t *col = (column_t *)((UINT8 *)realpatch + LONG(*(UINT32 *)&colofs[x<<2])); INT32 topdelta, prevdelta = -1, y = 0; while (col->topdelta != 0xff) { @@ -250,11 +250,11 @@ static UINT8 *R_GenerateTexture(size_t texnum) texturememory += blocksize; // use the patch's column lookup - colofs = (UINT32 *)(void *)(block + 8); - texturecolumnofs[texnum] = colofs; + colofs = (block + 8); + texturecolumnofs[texnum] = (UINT32 *)colofs; blocktex = block; for (x = 0; x < texture->width; x++) - colofs[x] = LONG(LONG(colofs[x]) + 3); + *(UINT32 *)&colofs[x<<2] = LONG(LONG(*(UINT32 *)&colofs[x<<2]) + 3); goto done; } @@ -270,8 +270,8 @@ static UINT8 *R_GenerateTexture(size_t texnum) memset(block, 0xF7, blocksize+1); // Transparency hack // columns lookup table - colofs = (UINT32 *)(void *)block; - texturecolumnofs[texnum] = colofs; + colofs = block; + texturecolumnofs[texnum] = (UINT32 *)colofs; // texture data after the lookup table blocktex = block + (texture->width*4); @@ -296,8 +296,8 @@ static UINT8 *R_GenerateTexture(size_t texnum) patchcol = (column_t *)((UINT8 *)realpatch + LONG(realpatch->columnofs[x-x1])); // generate column ofset lookup - colofs[x] = LONG((x * texture->height) + (texture->width*4)); - R_DrawColumnInCache(patchcol, block + LONG(colofs[x]), patch->originy, texture->height); + *(UINT32 *)&colofs[x<<2] = LONG((x * texture->height) + (texture->width*4)); + R_DrawColumnInCache(patchcol, block + LONG(*(UINT32 *)&colofs[x<<2]), patch->originy, texture->height); } } @@ -1177,7 +1177,6 @@ void R_ClearColormaps(void) // static double deltas[256][3], map[256][3]; -UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b); static int RoundUp(double number); #ifdef HASINVERT diff --git a/src/r_data.h b/src/r_data.h index 3b12b576f..bd404789d 100644 --- a/src/r_data.h +++ b/src/r_data.h @@ -102,4 +102,6 @@ UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b); extern INT32 numtextures; +UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b); + #endif diff --git a/src/r_defs.h b/src/r_defs.h index 52a3be80e..00036e9e9 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -526,31 +526,6 @@ typedef struct mprecipsecnode_s boolean visited; // used in search algorithms } mprecipsecnode_t; -// for now, only used in hardware mode -// maybe later for software as well? -// that's why it's moved here -typedef struct light_s -{ - UINT16 type; // light,... (cfr #define in hwr_light.c) - - float light_xoffset; - float light_yoffset; // y offset to adjust corona's height - - UINT32 corona_color; // color of the light for static lighting - float corona_radius; // radius of the coronas - - UINT32 dynamic_color; // color of the light for dynamic lighting - float dynamic_radius; // radius of the light ball - float dynamic_sqrradius; // radius^2 of the light ball -} light_t; - -typedef struct lightmap_s -{ - float s[2], t[2]; - light_t *light; - struct lightmap_s *next; -} lightmap_t; - // // The lineseg. // @@ -579,8 +554,6 @@ typedef struct seg_s void *pv1; // polyvertex_t void *pv2; // polyvertex_t float flength; // length of the seg, used by hardware renderer - - lightmap_t *lightmaps; // for static lightmap #endif // Why slow things down by calculating lightlists for every thick side? diff --git a/src/r_main.c b/src/r_main.c index 1735c8d8d..2ec064975 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -137,7 +137,7 @@ static CV_PossibleValue_t drawdist_precip_cons_t[] = { {1024, "1024"}, {1536, "1536"}, {2048, "2048"}, {0, "None"}, {0, NULL}}; -static CV_PossibleValue_t fov_cons_t[] = {{0, "MIN"}, {179*FRACUNIT, "MAX"}, {0, NULL}}; +static CV_PossibleValue_t fov_cons_t[] = {{5*FRACUNIT, "MIN"}, {178*FRACUNIT, "MAX"}, {0, NULL}}; //static CV_PossibleValue_t precipdensity_cons_t[] = {{0, "None"}, {1, "Light"}, {2, "Moderate"}, {4, "Heavy"}, {6, "Thick"}, {8, "V.Thick"}, {0, NULL}}; static CV_PossibleValue_t translucenthud_cons_t[] = {{0, "MIN"}, {10, "MAX"}, {0, NULL}}; @@ -181,7 +181,9 @@ consvar_t cv_drawdist = {"drawdist", "Infinite", CV_SAVE, drawdist_cons_t, NULL, //consvar_t cv_drawdist_nights = {"drawdist_nights", "2048", CV_SAVE, drawdist_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_drawdist_precip = {"drawdist_precip", "1024", CV_SAVE, drawdist_precip_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; //consvar_t cv_precipdensity = {"precipdensity", "Moderate", CV_SAVE, precipdensity_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_fov = {"fov", "90", CV_FLOAT|CV_CALL, fov_cons_t, Fov_OnChange, 0, NULL, NULL, 0, 0, NULL}; + +// cap fov, fov too high tears software apart. +consvar_t cv_fov = {"fov", "90", CV_FLOAT|CV_CALL|CV_SAVE, fov_cons_t, Fov_OnChange, 0, NULL, NULL, 0, 0, NULL}; // Okay, whoever said homremoval causes a performance hit should be shot. consvar_t cv_homremoval = {"homremoval", "Yes", CV_SAVE, homremoval_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -540,9 +542,9 @@ static void R_InitTextureMapping(void) for (i = 0; i < FINEANGLES/2; i++) { - if (FINETANGENT(i) > FRACUNIT*2) + if (FINETANGENT(i) > fovtan*2) t = -1; - else if (FINETANGENT(i) < -FRACUNIT*2) + else if (FINETANGENT(i) < -fovtan*2) t = viewwidth+1; else { @@ -686,11 +688,6 @@ void R_ExecuteSetViewSize(void) R_InitTextureMapping(); -#ifdef HWRENDER - if (rendermode != render_soft) - HWR_InitTextureMapping(); -#endif - // thing clipping for (i = 0; i < viewwidth; i++) screenheightarray[i] = (INT16)viewheight; @@ -820,29 +817,31 @@ subsector_t *R_IsPointInSubsector(fixed_t x, fixed_t y) static mobj_t *viewmobj; -// WARNING: a should be unsigned but to add with 2048, it isn't! -#define AIMINGTODY(a) FixedDiv((FINETANGENT((2048+(((INT32)a)>>ANGLETOFINESHIFT)) & FINEMASK)*160)>>FRACBITS, fovtan) - // recalc necessary stuff for mouseaiming // slopes are already calculated for the full possible view (which is 4*viewheight). // 18/08/18: (No it's actually 16*viewheight, thanks Jimita for finding this out) static void R_SetupFreelook(void) { INT32 dy = 0; + + // clip it in the case we are looking a hardware 90 degrees full aiming + // (lmps, network and use F12...) + if (rendermode == render_soft +#ifdef HWRENDER + || cv_grshearing.value +#endif + ) + G_SoftwareClipAimingPitch((INT32 *)&aimingangle); + if (rendermode == render_soft) { - // clip it in the case we are looking a hardware 90 degrees full aiming - // (lmps, network and use F12...) - G_SoftwareClipAimingPitch((INT32 *)&aimingangle); - dy = AIMINGTODY(aimingangle) * viewwidth/BASEVIDWIDTH; + dy = (AIMINGTODY(aimingangle)/fovtan) * viewwidth/BASEVIDWIDTH; yslope = &yslopetab[viewheight*8 - (viewheight/2 + dy)]; } centery = (viewheight/2) + dy; centeryfrac = centery<0 && SHORT(patch.topoffset) + @@ -222,7 +223,6 @@ - @@ -488,4 +488,4 @@ - \ No newline at end of file + diff --git a/src/sdl/Srb2SDL-vc10.vcxproj.filters b/src/sdl/Srb2SDL-vc10.vcxproj.filters index 8556627b8..9e5b98375 100644 --- a/src/sdl/Srb2SDL-vc10.vcxproj.filters +++ b/src/sdl/Srb2SDL-vc10.vcxproj.filters @@ -231,9 +231,6 @@ Hw_Hardware - - Hw_Hardware - Hw_Hardware @@ -639,7 +636,7 @@ Hw_Hardware - + Hw_Hardware @@ -924,4 +921,4 @@ SDLApp - \ No newline at end of file + diff --git a/src/sdl/Srb2SDL-vc9.vcproj b/src/sdl/Srb2SDL-vc9.vcproj index 3898aeba4..b21eedb87 100644 --- a/src/sdl/Srb2SDL-vc9.vcproj +++ b/src/sdl/Srb2SDL-vc9.vcproj @@ -2410,10 +2410,6 @@ RelativePath="..\hardware\hw_drv.h" > - - diff --git a/src/sdl/Srb2SDL.dsp b/src/sdl/Srb2SDL.dsp index 879113ca2..ce35e2e23 100644 --- a/src/sdl/Srb2SDL.dsp +++ b/src/sdl/Srb2SDL.dsp @@ -7,19 +7,19 @@ CFG=Srb2SDL - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run -!MESSAGE +!MESSAGE !MESSAGE NMAKE /f "Srb2SDL.mak". -!MESSAGE +!MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE +!MESSAGE !MESSAGE NMAKE /f "Srb2SDL.mak" CFG="Srb2SDL - Win32 Debug" -!MESSAGE +!MESSAGE !MESSAGE Possible choices for configuration are: -!MESSAGE +!MESSAGE !MESSAGE "Srb2SDL - Win32 Release" (based on "Win32 (x86) Console Application") !MESSAGE "Srb2SDL - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE +!MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 @@ -85,7 +85,7 @@ LINK32=link.exe # ADD LINK32 SDL.lib SDL_mixer.lib user32.lib advapi32.lib ws2_32.lib /nologo /subsystem:console /pdb:"C:\srb2demo2\srb2sdldebug.pdb" /debug /machine:I386 /out:"C:\srb2demo2\srb2sdldebug.exe" /pdbtype:sept # SUBTRACT LINK32 /pdb:none -!ENDIF +!ENDIF # Begin Target @@ -213,7 +213,7 @@ SOURCE=.\SDL_main\SDL_win32_main.c # PROP Exclude_From_Build 1 -!ENDIF +!ENDIF # End Source File # Begin Source File @@ -274,7 +274,7 @@ InputName=tmap # End Custom Build -!ENDIF +!ENDIF # End Source File # Begin Source File @@ -308,7 +308,7 @@ InputName=tmap_mmx # End Custom Build -!ENDIF +!ENDIF # End Source File # Begin Source File @@ -339,7 +339,7 @@ InputName=tmap_vc # End Custom Build -!ENDIF +!ENDIF # End Source File # End Group @@ -576,10 +576,6 @@ SOURCE=..\hardware\hw_drv.h # End Source File # Begin Source File -SOURCE=..\hardware\hw_glide.h -# End Source File -# Begin Source File - SOURCE=..\hardware\hw_glob.h # End Source File # Begin Source File diff --git a/src/sdl/Srb2SDL.props b/src/sdl/Srb2SDL.props index 260f81eed..75839a5b2 100644 --- a/src/sdl/Srb2SDL.props +++ b/src/sdl/Srb2SDL.props @@ -5,7 +5,10 @@ - USE_WGL_SWAP;DIRECTFULLSCREEN;HAVE_SDL;HWRENDER;HW3SOUND;HAVE_FILTER;HAVE_MIXER;SDLMAIN;%(PreprocessorDefinitions) + + HAVE_ZLIB;HAVE_LIBGME;USE_WGL_SWAP;DIRECTFULLSCREEN;HAVE_SDL;HWRENDER;HW3SOUND;HAVE_FILTER;HAVE_MIXER;SDLMAIN;%(PreprocessorDefinitions) + + USE_WGL_SWAP;DIRECTFULLSCREEN;HAVE_SDL;HWRENDER;HW3SOUND;HAVE_FILTER;HAVE_MIXER;SDLMAIN;%(PreprocessorDefinitions) diff --git a/src/sdl/hwsym_sdl.c b/src/sdl/hwsym_sdl.c index 4e083b4c2..2627c3fdb 100644 --- a/src/sdl/hwsym_sdl.c +++ b/src/sdl/hwsym_sdl.c @@ -75,7 +75,8 @@ void *hwSym(const char *funcName,void *handle) void *funcPointer = NULL; #ifdef HWRENDER if (0 == strcmp("SetPalette", funcName)) - funcPointer = &OglSdlSetPalette; + funcPointer = &OglSdlSetPalette; + GETFUNC(Init); GETFUNC(Draw2DLine); GETFUNC(DrawPolygon); @@ -90,7 +91,6 @@ void *hwSym(const char *funcName,void *handle) GETFUNC(DrawModel); GETFUNC(CreateModelVBOs); GETFUNC(SetTransform); - GETFUNC(GetRenderVersion); GETFUNC(PostImgRedraw); GETFUNC(FlushScreenTextures); GETFUNC(StartScreenWipe); @@ -100,6 +100,20 @@ void *hwSym(const char *funcName,void *handle) GETFUNC(MakeScreenTexture); GETFUNC(MakeScreenFinalTexture); GETFUNC(DrawScreenFinalTexture); + + GETFUNC(RenderSkyDome); + + GETFUNC(LoadShaders); + GETFUNC(KillShaders); + GETFUNC(SetShader); + GETFUNC(UnSetShader); + + GETFUNC(LoadCustomShader); + GETFUNC(InitCustomShaders); + + GETFUNC(StartBatching); + GETFUNC(RenderBatches); + #else //HWRENDER if (0 == strcmp("FinishUpdate", funcName)) return funcPointer; //&FinishUpdate; diff --git a/src/sdl/i_main.c b/src/sdl/i_main.c index 41a9d7cd6..41874e9f7 100644 --- a/src/sdl/i_main.c +++ b/src/sdl/i_main.c @@ -45,6 +45,7 @@ extern int SDL_main(int argc, char *argv[]); #ifdef LOGMESSAGES FILE *logstream = NULL; +char logfilename[1024]; #endif #ifndef DOXYGEN @@ -130,10 +131,12 @@ int main(int argc, char **argv) #ifdef LOGMESSAGES #ifdef DEFAULTDIR if (logdir) - logstream = fopen(va("%s/"DEFAULTDIR"/log.txt",logdir), "wt"); + strcpy(logfilename, va("%s/"DEFAULTDIR"/log.txt",logdir)); else #endif - logstream = fopen("./log.txt", "wt"); + strcpy(logfilename, "./log.txt"); + + logstream = fopen(logfilename, "wt"); #endif //I_OutputMsg("I_StartupSystem() ...\n"); @@ -157,6 +160,7 @@ int main(int argc, char **argv) #endif MakeCodeWritable(); #endif + // startup SRB2 CONS_Printf("Setting up SRB2Kart...\n"); D_SRB2Main(); diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index c0fca64da..ef769564c 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -102,6 +102,12 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); #endif #endif +#if (defined (__unix__) && !defined (_MSDOS)) || defined (UNIXCOMMON) +#include +#include +#define NEWSIGNALHANDLER +#endif + #ifndef NOMUMBLE #ifdef __linux__ // need -lrt #include @@ -246,13 +252,11 @@ SDL_bool framebuffer = SDL_FALSE; UINT8 keyboard_started = false; -FUNCNORETURN static ATTRNORETURN void signal_handler(INT32 num) +static void I_ReportSignal(int num, int coredumped) { //static char msg[] = "oh no! back to reality!\r\n"; const char * sigmsg; - char sigdef[32]; - - D_QuitNetGame(); // Fix server freezes + char msg[128]; switch (num) { @@ -278,20 +282,41 @@ FUNCNORETURN static ATTRNORETURN void signal_handler(INT32 num) sigmsg = "SIGABRT - abnormal termination triggered by abort call"; break; default: - sprintf(sigdef,"signal number %d", num); - sigmsg = sigdef; + sprintf(msg,"signal number %d", num); + if (coredumped) + sigmsg = 0; + else + sigmsg = msg; } - I_OutputMsg("\nsignal_handler() error: %s\n", sigmsg); + if (coredumped) + { + if (sigmsg) + sprintf(msg, "%s (core dumped)", sigmsg); + else + strcat(msg, " (core dumped)"); + + sigmsg = msg; + } + + I_OutputMsg("\nProcess killed by signal: %s\n\n", sigmsg); SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, - "Signal caught", + "Process killed by signal", sigmsg, NULL); +} + +#ifndef NEWSIGNALHANDLER +FUNCNORETURN static ATTRNORETURN void signal_handler(INT32 num) +{ + D_QuitNetGame(); // Fix server freezes + I_ReportSignal(num, 0); I_ShutdownSystem(); signal(num, SIG_DFL); //default signal action raise(num); I_Quit(); } +#endif FUNCNORETURN static ATTRNORETURN void quit_handler(int num) { @@ -667,7 +692,7 @@ static inline void I_ShutdownConsole(void){} // // StartupKeyboard // -void I_StartupKeyboard (void) +static void I_RegisterSignals (void) { #ifdef SIGINT signal(SIGINT , quit_handler); @@ -681,10 +706,12 @@ void I_StartupKeyboard (void) // If these defines don't exist, // then compilation would have failed above us... +#ifndef NEWSIGNALHANDLER signal(SIGILL , signal_handler); signal(SIGSEGV , signal_handler); signal(SIGABRT , signal_handler); signal(SIGFPE , signal_handler); +#endif } // @@ -3022,6 +3049,85 @@ void I_Sleep(void) SDL_Delay(cv_sleep.value); } +#ifdef NEWSIGNALHANDLER +static void newsignalhandler_Warn(const char *pr) +{ + char text[128]; + + snprintf(text, sizeof text, + "Error while setting up signal reporting: %s: %s", + pr, + strerror(errno) + ); + + I_OutputMsg("%s\n", text); + + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, + "Startup error", + text, NULL); + + I_ShutdownConsole(); + exit(-1); +} + +static void I_Fork(void) +{ + int child; + int status; + int signum; + int c; + + child = fork(); + + switch (child) + { + case -1: + newsignalhandler_Warn("fork()"); + break; + case 0: + break; + default: + if (logstream) + fclose(logstream);/* the child has this */ + + c = wait(&status); + +#ifdef LOGMESSAGES + /* By the way, exit closes files. */ + logstream = fopen(logfilename, "at"); +#else + logstream = 0; +#endif + + if (c == -1) + { + kill(child, SIGKILL); + newsignalhandler_Warn("wait()"); + } + else + { + if (WIFSIGNALED (status)) + { + signum = WTERMSIG (status); +#ifdef WCOREDUMP + I_ReportSignal(signum, WCOREDUMP (status)); +#else + I_ReportSignal(signum, 0); +#endif + status = 128 + signum; + } + else if (WIFEXITED (status)) + { + status = WEXITSTATUS (status); + } + + I_ShutdownConsole(); + exit(status); + } + } +} +#endif/*NEWSIGNALHANDLER*/ + INT32 I_StartupSystem(void) { SDL_version SDLcompiled; @@ -3029,6 +3135,10 @@ INT32 I_StartupSystem(void) SDL_VERSION(&SDLcompiled) SDL_GetVersion(&SDLlinked); I_StartupConsole(); +#ifdef NEWSIGNALHANDLER + I_Fork(); +#endif + I_RegisterSignals(); I_OutputMsg("Compiled for SDL version: %d.%d.%d\n", SDLcompiled.major, SDLcompiled.minor, SDLcompiled.patch); I_OutputMsg("Linked with SDL version: %d.%d.%d\n", @@ -3271,6 +3381,10 @@ void I_ShutdownSystem(void) { INT32 c; +#ifndef NEWSIGNALHANDLER + I_ShutdownConsole(); +#endif + for (c = MAX_QUIT_FUNCS-1; c >= 0; c--) if (quit_funcs[c]) (*quit_funcs[c])(); diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index c9c3022df..a740ef84d 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -351,11 +351,6 @@ static INT32 Impl_SDL_Scancode_To_Keycode(SDL_Scancode code) case SDL_SCANCODE_RGUI: return KEY_RIGHTWIN; default: break; } -#ifdef HWRENDER - DBG_Printf("Unknown incoming scancode: %d, represented %c\n", - code, - SDL_GetKeyName(SDL_GetKeyFromScancode(code))); -#endif return 0; } @@ -635,11 +630,6 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt) if (cv_usemouse.value) I_StartupMouse(); } //else firsttimeonmouse = SDL_FALSE; - - capslock = !!( SDL_GetModState() & KMOD_CAPS );// in case CL changes - - if (USE_MOUSEINPUT) - SDLdoGrabMouse(); } else if (!mousefocus && !kbfocus) { @@ -1296,6 +1286,8 @@ void I_StartupMouse(void) // void I_OsPolling(void) { + SDL_Keymod mod; + if (consolevent) I_GetConsoleEvents(); if (SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK) @@ -1310,6 +1302,18 @@ void I_OsPolling(void) I_GetMouseEvents(); I_GetEvent(); + + mod = SDL_GetModState(); + /* Handle here so that our state is always synched with the system. */ + shiftdown = ctrldown = altdown = 0; + capslock = false; + if (mod & KMOD_LSHIFT) shiftdown |= 1; + if (mod & KMOD_RSHIFT) shiftdown |= 2; + if (mod & KMOD_LCTRL) ctrldown |= 1; + if (mod & KMOD_RCTRL) ctrldown |= 2; + if (mod & KMOD_LALT) altdown |= 1; + if (mod & KMOD_RALT) altdown |= 2; + if (mod & KMOD_CAPS) capslock = true; } // @@ -1827,9 +1831,11 @@ void I_StartupGraphics(void) framebuffer = SDL_TRUE; } if (M_CheckParm("-software")) - { rendermode = render_soft; - } +#ifdef HWRENDER + else if (M_CheckParm("-opengl")) + rendermode = render_opengl; +#endif usesdl2soft = M_CheckParm("-softblit"); borderlesswindow = M_CheckParm("-borderless"); @@ -1837,9 +1843,8 @@ void I_StartupGraphics(void) //SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY>>1,SDL_DEFAULT_REPEAT_INTERVAL<<2); VID_Command_ModeList_f(); #ifdef HWRENDER - if (M_CheckParm("-opengl") || rendermode == render_opengl) + if (rendermode == render_opengl) { - rendermode = render_opengl; HWD.pfnInit = hwSym("Init",NULL); HWD.pfnFinishUpdate = NULL; HWD.pfnDraw2DLine = hwSym("Draw2DLine",NULL); @@ -1856,7 +1861,6 @@ void I_StartupGraphics(void) HWD.pfnDrawModel = hwSym("DrawModel",NULL); HWD.pfnCreateModelVBOs = hwSym("CreateModelVBOs",NULL); HWD.pfnSetTransform = hwSym("SetTransform",NULL); - HWD.pfnGetRenderVersion = hwSym("GetRenderVersion",NULL); HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL); HWD.pfnFlushScreenTextures=hwSym("FlushScreenTextures",NULL); HWD.pfnStartScreenWipe = hwSym("StartScreenWipe",NULL); @@ -1866,13 +1870,22 @@ void I_StartupGraphics(void) HWD.pfnMakeScreenTexture= hwSym("MakeScreenTexture",NULL); HWD.pfnMakeScreenFinalTexture=hwSym("MakeScreenFinalTexture",NULL); HWD.pfnDrawScreenFinalTexture=hwSym("DrawScreenFinalTexture",NULL); - // check gl renderer lib - if (HWD.pfnGetRenderVersion() != VERSION) - I_Error("%s", M_GetText("The version of the renderer doesn't match the version of the executable\nBe sure you have installed SRB2Kart properly.\n")); - if (!HWD.pfnInit(I_Error)) // let load the OpenGL library - { + + HWD.pfnRenderSkyDome = hwSym("RenderSkyDome",NULL); + + HWD.pfnLoadShaders = hwSym("LoadShaders",NULL); + HWD.pfnKillShaders = hwSym("KillShaders",NULL); + HWD.pfnSetShader = hwSym("SetShader",NULL); + HWD.pfnUnSetShader = hwSym("UnSetShader",NULL); + + HWD.pfnLoadCustomShader = hwSym("LoadCustomShader",NULL); + HWD.pfnInitCustomShaders = hwSym("InitCustomShaders",NULL); + + HWD.pfnStartBatching = hwSym("StartBatching",NULL); + HWD.pfnRenderBatches = hwSym("RenderBatches",NULL); + + if (!HWD.pfnInit()) // load the OpenGL library rendermode = render_soft; - } } #endif diff --git a/src/sdl/macosx/Srb2mac.pbproj/project.pbxproj b/src/sdl/macosx/Srb2mac.pbproj/project.pbxproj index de12201f5..ee0bf4697 100644 --- a/src/sdl/macosx/Srb2mac.pbproj/project.pbxproj +++ b/src/sdl/macosx/Srb2mac.pbproj/project.pbxproj @@ -1064,13 +1064,6 @@ path = ../../hardware/hw_drv.h; refType = 2; }; - 8417773B085A106C000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = hw_glide.h; - path = ../../hardware/hw_glide.h; - refType = 2; - }; 8417773C085A106C000C01D8 = { fileEncoding = 30; isa = PBXFileReference; diff --git a/src/sdl/macosx/Srb2mac.xcodeproj/project.pbxproj b/src/sdl/macosx/Srb2mac.xcodeproj/project.pbxproj index a8ecbf7f8..00930bfb3 100644 --- a/src/sdl/macosx/Srb2mac.xcodeproj/project.pbxproj +++ b/src/sdl/macosx/Srb2mac.xcodeproj/project.pbxproj @@ -181,7 +181,6 @@ 1E44AE640B67CC2B00BAD059 /* hw_cache.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = hw_cache.c; path = ../../hardware/hw_cache.c; sourceTree = SOURCE_ROOT; }; 1E44AE650B67CC2B00BAD059 /* hw_dll.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hw_dll.h; path = ../../hardware/hw_dll.h; sourceTree = SOURCE_ROOT; }; 1E44AE660B67CC2B00BAD059 /* hw_drv.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hw_drv.h; path = ../../hardware/hw_drv.h; sourceTree = SOURCE_ROOT; }; - 1E44AE670B67CC2B00BAD059 /* hw_glide.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hw_glide.h; path = ../../hardware/hw_glide.h; sourceTree = SOURCE_ROOT; }; 1E44AE680B67CC2B00BAD059 /* hw_light.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = hw_light.c; path = ../../hardware/hw_light.c; sourceTree = SOURCE_ROOT; }; 1E44AE690B67CC2B00BAD059 /* hw_light.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hw_light.h; path = ../../hardware/hw_light.h; sourceTree = SOURCE_ROOT; }; 1E44AE6A0B67CC2B00BAD059 /* hw3sound.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hw3sound.h; path = ../../hardware/hw3sound.h; sourceTree = SOURCE_ROOT; }; @@ -535,7 +534,6 @@ 1E44AE640B67CC2B00BAD059 /* hw_cache.c */, 1E44AE650B67CC2B00BAD059 /* hw_dll.h */, 1E44AE660B67CC2B00BAD059 /* hw_drv.h */, - 1E44AE670B67CC2B00BAD059 /* hw_glide.h */, 1E44AE680B67CC2B00BAD059 /* hw_light.c */, 1E44AE690B67CC2B00BAD059 /* hw_light.h */, 1E44AE6A0B67CC2B00BAD059 /* hw3sound.h */, @@ -1219,7 +1217,7 @@ C01FCF4B08A954540054247B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - CURRENT_PROJECT_VERSION = 2.1.23; + CURRENT_PROJECT_VERSION = 2.1.24; GCC_PREPROCESSOR_DEFINITIONS = ( "$(inherited)", NORMALSRB2, @@ -1231,7 +1229,7 @@ C01FCF4C08A954540054247B /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - CURRENT_PROJECT_VERSION = 2.1.23; + CURRENT_PROJECT_VERSION = 2.1.24; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_PREPROCESSOR_DEFINITIONS = ( diff --git a/src/sdl/ogl_sdl.c b/src/sdl/ogl_sdl.c index 4347b35b2..b006047f5 100644 --- a/src/sdl/ogl_sdl.c +++ b/src/sdl/ogl_sdl.c @@ -36,6 +36,7 @@ #ifdef HWRENDER #include "../hardware/r_opengl/r_opengl.h" +#include "../hardware/hw_main.h" #include "ogl_sdl.h" #include "../i_system.h" #include "hwsym_sdl.h" @@ -89,15 +90,15 @@ boolean LoadGL(void) const char *OGLLibname = NULL; const char *GLULibname = NULL; - if (M_CheckParm ("-OGLlib") && M_IsNextParm()) + if (M_CheckParm("-OGLlib") && M_IsNextParm()) OGLLibname = M_GetNextParm(); if (SDL_GL_LoadLibrary(OGLLibname) != 0) { - I_OutputMsg("Could not load OpenGL Library: %s\n" + CONS_Alert(CONS_ERROR, "Could not load OpenGL Library: %s\n" "Falling back to Software mode.\n", SDL_GetError()); - if (!M_CheckParm ("-OGLlib")) - I_OutputMsg("If you know what is the OpenGL library's name, use -OGLlib\n"); + if (!M_CheckParm("-OGLlib")) + CONS_Printf("If you know what is the OpenGL library's name, use -OGLlib\n"); return 0; } @@ -117,7 +118,7 @@ boolean LoadGL(void) GLULibname = NULL; #endif - if (M_CheckParm ("-GLUlib") && M_IsNextParm()) + if (M_CheckParm("-GLUlib") && M_IsNextParm()) GLULibname = M_GetNextParm(); if (GLULibname) @@ -127,15 +128,15 @@ boolean LoadGL(void) return SetupGLfunc(); else { - I_OutputMsg("Could not load GLU Library: %s\n", GLULibname); - if (!M_CheckParm ("-GLUlib")) - I_OutputMsg("If you know what is the GLU library's name, use -GLUlib\n"); + CONS_Alert(CONS_ERROR, "Could not load GLU Library: %s\n", GLULibname); + if (!M_CheckParm("-GLUlib")) + CONS_Printf("If you know what is the GLU library's name, use -GLUlib\n"); } } else { - I_OutputMsg("Could not load GLU Library\n"); - I_OutputMsg("If you know what is the GLU library's name, use -GLUlib\n"); + CONS_Alert(CONS_ERROR, "Could not load GLU Library\n"); + CONS_Printf("If you know what is the GLU library's name, use -GLUlib\n"); } #endif return SetupGLfunc(); @@ -151,31 +152,29 @@ boolean LoadGL(void) */ boolean OglSdlSurface(INT32 w, INT32 h) { - INT32 cbpp; - const GLvoid *glvendor = NULL, *glrenderer = NULL, *glversion = NULL; + INT32 cbpp = cv_scr_depth.value < 16 ? 16 : cv_scr_depth.value; + static boolean first_init = false; - cbpp = cv_scr_depth.value < 16 ? 16 : cv_scr_depth.value; - - glvendor = pglGetString(GL_VENDOR); - // Get info and extensions. - //BP: why don't we make it earlier ? - //Hurdler: we cannot do that before intialising gl context - glrenderer = pglGetString(GL_RENDERER); - glversion = pglGetString(GL_VERSION); - gl_extensions = pglGetString(GL_EXTENSIONS); - - DBG_Printf("Vendor : %s\n", glvendor); - DBG_Printf("Renderer : %s\n", glrenderer); - DBG_Printf("Version : %s\n", glversion); - DBG_Printf("Extensions : %s\n", gl_extensions); oglflags = 0; + if (!first_init) + { + gl_version = pglGetString(GL_VERSION); + gl_renderer = pglGetString(GL_RENDERER); + gl_extensions = pglGetString(GL_EXTENSIONS); + + GL_DBG_Printf("OpenGL %s\n", gl_version); + GL_DBG_Printf("GPU: %s\n", gl_renderer); + GL_DBG_Printf("Extensions: %s\n", gl_extensions); + } + first_init = true; + if (isExtAvailable("GL_EXT_texture_filter_anisotropic", gl_extensions)) pglGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maximumAnisotropy); else maximumAnisotropy = 1; - SetupGLFunc13(); + SetupGLFunc4(); granisotropicmode_cons_t[1].value = maximumAnisotropy; @@ -221,7 +220,7 @@ void OglSdlFinishUpdate(boolean waitvbl) HWR_DrawScreenFinalTexture(realwidth, realheight); } -EXPORT void HWRAPI( OglSdlSetPalette) (RGBA_t *palette, RGBA_t *pgamma) +EXPORT void HWRAPI(OglSdlSetPalette) (RGBA_t *palette, RGBA_t *pgamma) { INT32 i = -1; UINT32 redgamma = pgamma->s.red, greengamma = pgamma->s.green, diff --git a/src/sdl12/Srb2SDL-vc10.vcxproj b/src/sdl12/Srb2SDL-vc10.vcxproj index 0ac7e9e55..d7f13751e 100644 --- a/src/sdl12/Srb2SDL-vc10.vcxproj +++ b/src/sdl12/Srb2SDL-vc10.vcxproj @@ -1375,7 +1375,6 @@ - diff --git a/src/sdl12/Srb2SDL-vc9.vcproj b/src/sdl12/Srb2SDL-vc9.vcproj index fa386e381..9d807be21 100644 --- a/src/sdl12/Srb2SDL-vc9.vcproj +++ b/src/sdl12/Srb2SDL-vc9.vcproj @@ -2410,10 +2410,6 @@ RelativePath="..\hardware\hw_drv.h" > - - diff --git a/src/sdl12/Srb2SDL.dsp b/src/sdl12/Srb2SDL.dsp index 879113ca2..ce35e2e23 100644 --- a/src/sdl12/Srb2SDL.dsp +++ b/src/sdl12/Srb2SDL.dsp @@ -7,19 +7,19 @@ CFG=Srb2SDL - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run -!MESSAGE +!MESSAGE !MESSAGE NMAKE /f "Srb2SDL.mak". -!MESSAGE +!MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE +!MESSAGE !MESSAGE NMAKE /f "Srb2SDL.mak" CFG="Srb2SDL - Win32 Debug" -!MESSAGE +!MESSAGE !MESSAGE Possible choices for configuration are: -!MESSAGE +!MESSAGE !MESSAGE "Srb2SDL - Win32 Release" (based on "Win32 (x86) Console Application") !MESSAGE "Srb2SDL - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE +!MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 @@ -85,7 +85,7 @@ LINK32=link.exe # ADD LINK32 SDL.lib SDL_mixer.lib user32.lib advapi32.lib ws2_32.lib /nologo /subsystem:console /pdb:"C:\srb2demo2\srb2sdldebug.pdb" /debug /machine:I386 /out:"C:\srb2demo2\srb2sdldebug.exe" /pdbtype:sept # SUBTRACT LINK32 /pdb:none -!ENDIF +!ENDIF # Begin Target @@ -213,7 +213,7 @@ SOURCE=.\SDL_main\SDL_win32_main.c # PROP Exclude_From_Build 1 -!ENDIF +!ENDIF # End Source File # Begin Source File @@ -274,7 +274,7 @@ InputName=tmap # End Custom Build -!ENDIF +!ENDIF # End Source File # Begin Source File @@ -308,7 +308,7 @@ InputName=tmap_mmx # End Custom Build -!ENDIF +!ENDIF # End Source File # Begin Source File @@ -339,7 +339,7 @@ InputName=tmap_vc # End Custom Build -!ENDIF +!ENDIF # End Source File # End Group @@ -576,10 +576,6 @@ SOURCE=..\hardware\hw_drv.h # End Source File # Begin Source File -SOURCE=..\hardware\hw_glide.h -# End Source File -# Begin Source File - SOURCE=..\hardware\hw_glob.h # End Source File # Begin Source File diff --git a/src/sdl12/hwsym_sdl.c b/src/sdl12/hwsym_sdl.c index 49340138f..b6f6313f6 100644 --- a/src/sdl12/hwsym_sdl.c +++ b/src/sdl12/hwsym_sdl.c @@ -49,14 +49,6 @@ #define _CREATE_DLL_ // necessary for Unix AND Windows -#ifdef HWRENDER -#include "../hardware/hw_drv.h" -#include "ogl_sdl.h" -#ifdef STATIC_OPENGL -#include "../hardware/r_opengl/r_opengl.h" -#endif -#endif - #ifdef HW3SOUND #include "../hardware/hw3dsdrv.h" #endif @@ -79,39 +71,8 @@ void *hwSym(const char *funcName,void *handle) { void *funcPointer = NULL; -#ifdef HWRENDER - if (0 == strcmp("SetPalette", funcName)) - funcPointer = &OglSdlSetPalette; - GETFUNC(Init); - GETFUNC(Draw2DLine); - GETFUNC(DrawPolygon); - GETFUNC(SetBlend); - GETFUNC(ClearBuffer); - GETFUNC(SetTexture); - GETFUNC(ReadRect); - GETFUNC(GClipRect); - GETFUNC(ClearMipMapCache); - GETFUNC(SetSpecialState); - GETFUNC(GetTextureUsed); - GETFUNC(DrawMD2); - GETFUNC(DrawMD2i); - GETFUNC(SetTransform); - GETFUNC(GetRenderVersion); -#ifdef SHUFFLE - GETFUNC(PostImgRedraw); -#endif //SHUFFLE - GETFUNC(FlushScreenTextures); - GETFUNC(StartScreenWipe); - GETFUNC(EndScreenWipe); - GETFUNC(DoScreenWipe); - GETFUNC(DrawIntermissionBG); - GETFUNC(MakeScreenTexture); - GETFUNC(MakeScreenFinalTexture); - GETFUNC(DrawScreenFinalTexture); -#else //HWRENDER if (0 == strcmp("FinishUpdate", funcName)) return funcPointer; //&FinishUpdate; -#endif //!HWRENDER #ifdef STATIC3DS GETFUNC(Startup); GETFUNC(AddSfx); diff --git a/src/sdl12/i_video.c b/src/sdl12/i_video.c index a2a20c611..45ce67cf5 100644 --- a/src/sdl12/i_video.c +++ b/src/sdl12/i_video.c @@ -104,13 +104,6 @@ #include "../console.h" #include "../command.h" #include "sdlmain.h" -#ifdef HWRENDER -#include "../hardware/hw_main.h" -#include "../hardware/hw_drv.h" -// For dynamic referencing of HW rendering functions -#include "hwsym_sdl.h" -#include "ogl_sdl.h" -#endif #ifdef REMOTE_DEBUGGING #ifdef _WII @@ -169,9 +162,7 @@ static SDL_bool disable_mouse = SDL_FALSE; static INT32 firstEntry = 0; // SDL vars -#ifndef HWRENDER //[segabor] !!! I had problem compiling this source with gcc 3.3 static SDL_Surface *vidSurface = NULL; -#endif static SDL_Surface *bufSurface = NULL; static SDL_Surface *icoSurface = NULL; static SDL_Color localPalette[256]; @@ -664,11 +655,7 @@ static void VID_Command_ModeList_f(void) { #if !defined (DC) && !defined (_WIN32_WCE) && !defined (_PSP) && !defined(GP2X) INT32 i; -#ifdef HWRENDER - if (rendermode == render_opengl) - modeList = SDL_ListModes(NULL, SDL_OPENGL|SDL_FULLSCREEN); - else -#endif + modeList = SDL_ListModes(NULL, surfaceFlagsF|SDL_HWSURFACE); //Alam: At least hardware surface if (modeList == (SDL_Rect **)0 && cv_fullscreen.value) @@ -1277,11 +1264,7 @@ void I_UpdateNoBlit(void) { if (!vidSurface) return; -#ifdef HWRENDER - if (rendermode != render_soft) - OglSdlFinishUpdate(cv_vidwait.value); - else -#endif + if (vidSurface->flags&SDL_DOUBLEBUF) SDL_Flip(vidSurface); else if (exposevideo) @@ -1494,12 +1477,6 @@ void I_FinishUpdate(void) else I_OutputMsg("%s\n",SDL_GetError()); } -#ifdef HWRENDER - else - { - OglSdlFinishUpdate(cv_vidwait.value); - } -#endif exposevideo = SDL_FALSE; } @@ -1646,11 +1623,6 @@ void VID_PrepareModeList(void) firstEntry = 0; -#ifdef HWRENDER - if (rendermode == render_opengl) - modeList = SDL_ListModes(NULL, SDL_OPENGL|SDL_FULLSCREEN); - else -#endif modeList = SDL_ListModes(NULL, surfaceFlagsF|SDL_HWSURFACE); //Alam: At least hardware surface if (disable_fullscreen?0:cv_fullscreen.value) // only fullscreen needs preparation @@ -1786,23 +1758,6 @@ INT32 VID_SetMode(INT32 modeNum) I_Error("Could not set vidmode: %s\n",SDL_GetError()); } } -#ifdef HWRENDER - else // (render_soft != rendermode) - { - if (!OglSdlSurface(vid.width, vid.height, true)) - { - cv_fullscreen.value = 0; - modeNum = VID_GetModeForSize(vid.width,vid.height); - vid.width = windowedModes[modeNum][0]; - vid.height = windowedModes[modeNum][1]; - if (!OglSdlSurface(vid.width, vid.height,false)) - I_Error("Could not set vidmode: %s\n",SDL_GetError()); - } - - realwidth = (Uint16)vid.width; - realheight = (Uint16)vid.height; - } -#endif } else //(cv_fullscreen.value) { @@ -1815,15 +1770,6 @@ INT32 VID_SetMode(INT32 modeNum) if (!vidSurface) I_Error("Could not set vidmode: %s\n",SDL_GetError()); } -#ifdef HWRENDER - else //(render_soft != rendermode) - { - if (!OglSdlSurface(vid.width, vid.height, false)) - I_Error("Could not set vidmode: %s\n",SDL_GetError()); - realwidth = (Uint16)vid.width; - realheight = (Uint16)vid.height; - } -#endif } vid.modenum = VID_GetModeForSize(vidSurface->w,vidSurface->h); @@ -1950,92 +1896,31 @@ void I_StartupGraphics(void) //DisableAero(); //also disable Aero on Vista #endif -#ifdef HWRENDER - if (M_CheckParm("-opengl") || rendermode == render_opengl) - { - rendermode = render_opengl; - HWD.pfnInit = hwSym("Init",NULL); - HWD.pfnFinishUpdate = NULL; - HWD.pfnDraw2DLine = hwSym("Draw2DLine",NULL); - HWD.pfnDrawPolygon = hwSym("DrawPolygon",NULL); - HWD.pfnSetBlend = hwSym("SetBlend",NULL); - HWD.pfnClearBuffer = hwSym("ClearBuffer",NULL); - HWD.pfnSetTexture = hwSym("SetTexture",NULL); - HWD.pfnReadRect = hwSym("ReadRect",NULL); - HWD.pfnGClipRect = hwSym("GClipRect",NULL); - HWD.pfnClearMipMapCache = hwSym("ClearMipMapCache",NULL); - HWD.pfnSetSpecialState = hwSym("SetSpecialState",NULL); - HWD.pfnSetPalette = hwSym("SetPalette",NULL); - HWD.pfnGetTextureUsed = hwSym("GetTextureUsed",NULL); - HWD.pfnDrawMD2 = hwSym("DrawMD2",NULL); - HWD.pfnDrawMD2i = hwSym("DrawMD2i",NULL); - HWD.pfnSetTransform = hwSym("SetTransform",NULL); - HWD.pfnGetRenderVersion = hwSym("GetRenderVersion",NULL); -#ifdef SHUFFLE - HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL); -#endif - HWD.pfnFlushScreenTextures=hwSym("FlushScreenTextures",NULL); - HWD.pfnStartScreenWipe = hwSym("StartScreenWipe",NULL); - HWD.pfnEndScreenWipe = hwSym("EndScreenWipe",NULL); - HWD.pfnDoScreenWipe = hwSym("DoScreenWipe",NULL); - HWD.pfnDrawIntermissionBG=hwSym("DrawIntermissionBG",NULL); - HWD.pfnMakeScreenTexture= hwSym("MakeScreenTexture",NULL); - // check gl renderer lib - if (HWD.pfnGetRenderVersion() != VERSION) - I_Error("%s", M_GetText("The version of the renderer doesn't match the version of the executable\nBe sure you have installed SRB2 properly.\n")); -#if 1 //#ifdef _WIN32_WCE - vid.width = BASEVIDWIDTH; - vid.height = BASEVIDHEIGHT; -#else - vid.width = 640; // hack to make voodoo cards work in 640x480 - vid.height = 480; -#endif - if (HWD.pfnInit(I_Error)) // let load the OpenGL library - { - /* - * We want at least 1 bit R, G, and B, - * and at least 16 bpp. Why 1 bit? May be more? - */ - SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 1); - SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 1); - SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 1); - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - if (!OglSdlSurface(vid.width, vid.height, (USE_FULLSCREEN))) - if (!OglSdlSurface(vid.width, vid.height, !(USE_FULLSCREEN))) - rendermode = render_soft; - } - else - rendermode = render_soft; - } -#else rendermode = render_soft; //force software mode when there no HWRENDER code -#endif - if (render_soft == rendermode) - { #if defined(_WII) - vid.width = 640; - vid.height = 480; + vid.width = 640; + vid.height = 480; #elif defined(_PS3) - vid.width = 720; - vid.height = 480; + vid.width = 720; + vid.height = 480; #else - vid.width = BASEVIDWIDTH; - vid.height = BASEVIDHEIGHT; + vid.width = BASEVIDWIDTH; + vid.height = BASEVIDHEIGHT; #endif - SDLSetMode(vid.width, vid.height, BitsPerPixel, surfaceFlagsW); - if (!vidSurface) - { - CONS_Printf(M_GetText("Could not set vidmode: %s\n") ,SDL_GetError()); - vid.rowbytes = 0; - graphics_started = true; - return; - } - vid.rowbytes = vid.width * vid.bpp; - vid.direct = SDLGetDirect(); - vid.buffer = malloc(vid.rowbytes*vid.height*NUMSCREENS); - if (vid.buffer) memset(vid.buffer,0x00,vid.rowbytes*vid.height*NUMSCREENS); - else CONS_Printf("%s", M_GetText("Not enough memory for video buffer\n")); + SDLSetMode(vid.width, vid.height, BitsPerPixel, surfaceFlagsW); + if (!vidSurface) + { + CONS_Printf(M_GetText("Could not set vidmode: %s\n") ,SDL_GetError()); + vid.rowbytes = 0; + graphics_started = true; + return; } + vid.rowbytes = vid.width * vid.bpp; + vid.direct = SDLGetDirect(); + vid.buffer = malloc(vid.rowbytes*vid.height*NUMSCREENS); + if (vid.buffer) memset(vid.buffer,0x00,vid.rowbytes*vid.height*NUMSCREENS); + else CONS_Printf("%s", M_GetText("Not enough memory for video buffer\n")); + if (M_CheckParm("-nomousegrab")) mousegrabok = SDL_FALSE; #ifdef _DEBUG @@ -2091,10 +1976,6 @@ void I_ShutdownGraphics(void) #endif graphics_started = false; CONS_Printf("%s", M_GetText("shut down\n")); -#ifdef HWRENDER - if (GLUhandle) - hwClose(GLUhandle); -#endif #ifndef _arch_dreamcast SDL_QuitSubSystem(SDL_INIT_VIDEO); #endif diff --git a/src/sdl12/macosx/Srb2mac.pbproj/project.pbxproj b/src/sdl12/macosx/Srb2mac.pbproj/project.pbxproj index 1f8e3276a..1fe2ea2d8 100644 --- a/src/sdl12/macosx/Srb2mac.pbproj/project.pbxproj +++ b/src/sdl12/macosx/Srb2mac.pbproj/project.pbxproj @@ -1064,13 +1064,6 @@ path = ../../hardware/hw_drv.h; refType = 2; }; - 8417773B085A106C000C01D8 = { - fileEncoding = 30; - isa = PBXFileReference; - name = hw_glide.h; - path = ../../hardware/hw_glide.h; - refType = 2; - }; 8417773C085A106C000C01D8 = { fileEncoding = 30; isa = PBXFileReference; diff --git a/src/sdl12/macosx/Srb2mac.xcodeproj/project.pbxproj b/src/sdl12/macosx/Srb2mac.xcodeproj/project.pbxproj index 69c544c56..9b9d33b7a 100644 --- a/src/sdl12/macosx/Srb2mac.xcodeproj/project.pbxproj +++ b/src/sdl12/macosx/Srb2mac.xcodeproj/project.pbxproj @@ -181,7 +181,6 @@ 1E44AE640B67CC2B00BAD059 /* hw_cache.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = hw_cache.c; path = ../../hardware/hw_cache.c; sourceTree = SOURCE_ROOT; }; 1E44AE650B67CC2B00BAD059 /* hw_dll.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hw_dll.h; path = ../../hardware/hw_dll.h; sourceTree = SOURCE_ROOT; }; 1E44AE660B67CC2B00BAD059 /* hw_drv.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hw_drv.h; path = ../../hardware/hw_drv.h; sourceTree = SOURCE_ROOT; }; - 1E44AE670B67CC2B00BAD059 /* hw_glide.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hw_glide.h; path = ../../hardware/hw_glide.h; sourceTree = SOURCE_ROOT; }; 1E44AE680B67CC2B00BAD059 /* hw_light.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = hw_light.c; path = ../../hardware/hw_light.c; sourceTree = SOURCE_ROOT; }; 1E44AE690B67CC2B00BAD059 /* hw_light.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hw_light.h; path = ../../hardware/hw_light.h; sourceTree = SOURCE_ROOT; }; 1E44AE6A0B67CC2B00BAD059 /* hw3sound.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hw3sound.h; path = ../../hardware/hw3sound.h; sourceTree = SOURCE_ROOT; }; @@ -535,7 +534,6 @@ 1E44AE640B67CC2B00BAD059 /* hw_cache.c */, 1E44AE650B67CC2B00BAD059 /* hw_dll.h */, 1E44AE660B67CC2B00BAD059 /* hw_drv.h */, - 1E44AE670B67CC2B00BAD059 /* hw_glide.h */, 1E44AE680B67CC2B00BAD059 /* hw_light.c */, 1E44AE690B67CC2B00BAD059 /* hw_light.h */, 1E44AE6A0B67CC2B00BAD059 /* hw3sound.h */, @@ -1219,7 +1217,7 @@ C01FCF4B08A954540054247B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - CURRENT_PROJECT_VERSION = 2.1.23; + CURRENT_PROJECT_VERSION = 2.1.24; GCC_PREPROCESSOR_DEFINITIONS = ( "$(inherited)", NORMALSRB2, @@ -1231,7 +1229,7 @@ C01FCF4C08A954540054247B /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - CURRENT_PROJECT_VERSION = 2.1.23; + CURRENT_PROJECT_VERSION = 2.1.24; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_PREPROCESSOR_DEFINITIONS = ( diff --git a/src/sdl12/ogl_sdl.c b/src/sdl12/ogl_sdl.c deleted file mode 100644 index eb7e9996d..000000000 --- a/src/sdl12/ogl_sdl.c +++ /dev/null @@ -1,317 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1998-2000 by DooM Legacy Team. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -//----------------------------------------------------------------------------- -/// \file -/// \brief SDL specific part of the OpenGL API for SRB2 - -#ifdef _MSC_VER -#pragma warning(disable : 4214 4244) -#endif - -#ifdef HAVE_SDL - -#include "SDL.h" - -#ifdef _MSC_VER -#pragma warning(default : 4214 4244) -#endif - -#include "../doomdef.h" - -#ifdef HWRENDER -#include "../hardware/r_opengl/r_opengl.h" -#include "ogl_sdl.h" -#include "../i_system.h" -#include "hwsym_sdl.h" -#include "../m_argv.h" - -#ifdef DEBUG_TO_FILE -#include -#if defined (_WIN32) && !defined (__CYGWIN__) -#include -#else -#include -#endif -#include -#include -#endif - -#ifdef USE_WGL_SWAP -PFNWGLEXTSWAPCONTROLPROC wglSwapIntervalEXT = NULL; -#else -typedef int (*PFNGLXSWAPINTERVALPROC) (int); -PFNGLXSWAPINTERVALPROC glXSwapIntervalSGIEXT = NULL; -#endif - -#ifndef STATIC_OPENGL -PFNglClear pglClear; -PFNglGetIntegerv pglGetIntegerv; -PFNglGetString pglGetString; -#endif - -#ifdef _PSP -static const Uint32 WOGLFlags = SDL_HWSURFACE|SDL_OPENGL/*|SDL_RESIZABLE*/; -static const Uint32 FOGLFlags = SDL_HWSURFACE|SDL_OPENGL|SDL_FULLSCREEN; -#else -static const Uint32 WOGLFlags = SDL_OPENGL/*|SDL_RESIZABLE*/; -static const Uint32 FOGLFlags = SDL_OPENGL|SDL_FULLSCREEN; -#endif - -/** \brief SDL video display surface -*/ -SDL_Surface *vidSurface = NULL; -INT32 oglflags = 0; -void *GLUhandle = NULL; - -#ifndef STATIC_OPENGL -void *GetGLFunc(const char *proc) -{ - if (strncmp(proc, "glu", 3) == 0) - { - if (GLUhandle) - return hwSym(proc, GLUhandle); - else - return NULL; - } - return SDL_GL_GetProcAddress(proc); -} -#endif - -boolean LoadGL(void) -{ -#ifndef STATIC_OPENGL - const char *OGLLibname = NULL; - const char *GLULibname = NULL; - - if (M_CheckParm ("-OGLlib") && M_IsNextParm()) - OGLLibname = M_GetNextParm(); - - if (SDL_GL_LoadLibrary(OGLLibname) != 0) - { - I_OutputMsg("Could not load OpenGL Library: %s\n" - "Falling back to Software mode.\n", SDL_GetError()); - if (!M_CheckParm ("-OGLlib")) - I_OutputMsg("If you know what is the OpenGL library's name, use -OGLlib\n"); - return 0; - } - -#if 0 - GLULibname = "/proc/self/exe"; -#elif defined (_WIN32) - GLULibname = "GLU32.DLL"; -#elif defined (__MACH__) - GLULibname = "/System/Library/Frameworks/OpenGL.framework/Libraries/libGLU.dylib"; -#elif defined (macintos) - GLULibname = "OpenGLLibrary"; -#elif defined (__unix__) - GLULibname = "libGLU.so.1"; -#elif defined (__HAIKU__) - GLULibname = "libGLU.so"; -#else - GLULibname = NULL; -#endif - - if (M_CheckParm ("-GLUlib") && M_IsNextParm()) - GLULibname = M_GetNextParm(); - - if (GLULibname) - { - GLUhandle = hwOpen(GLULibname); - if (GLUhandle) - return SetupGLfunc(); - else - { - I_OutputMsg("Could not load GLU Library: %s\n", GLULibname); - if (!M_CheckParm ("-GLUlib")) - I_OutputMsg("If you know what is the GLU library's name, use -GLUlib\n"); - } - } - else - { - I_OutputMsg("Could not load GLU Library\n"); - I_OutputMsg("If you know what is the GLU library's name, use -GLUlib\n"); - } -#endif - return SetupGLfunc(); -} - -/** \brief The OglSdlSurface function - - \param w width - \param h height - \param isFullscreen if true, go fullscreen - - \return if true, changed video mode -*/ -boolean OglSdlSurface(INT32 w, INT32 h, boolean isFullscreen) -{ - INT32 cbpp; - Uint32 OGLFlags; - const GLvoid *glvendor = NULL, *glrenderer = NULL, *glversion = NULL; - - cbpp = cv_scr_depth.value < 16 ? 16 : cv_scr_depth.value; - - if (vidSurface) - { - //Alam: SDL_Video system free vidSurface for me -#ifdef VOODOOSAFESWITCHING - SDL_QuitSubSystem(SDL_INIT_VIDEO); - SDL_InitSubSystem(SDL_INIT_VIDEO); -#endif - } - - if (isFullscreen) - OGLFlags = FOGLFlags; - else - OGLFlags = WOGLFlags; - - cbpp = SDL_VideoModeOK(w, h, cbpp, OGLFlags); - if (cbpp < 16) - return true; //Alam: Let just say we did, ok? - - vidSurface = SDL_SetVideoMode(w, h, cbpp, OGLFlags); - if (!vidSurface) - return false; - - glvendor = pglGetString(GL_VENDOR); - // Get info and extensions. - //BP: why don't we make it earlier ? - //Hurdler: we cannot do that before intialising gl context - glrenderer = pglGetString(GL_RENDERER); - glversion = pglGetString(GL_VERSION); - gl_extensions = pglGetString(GL_EXTENSIONS); - - DBG_Printf("Vendor : %s\n", glvendor); - DBG_Printf("Renderer : %s\n", glrenderer); - DBG_Printf("Version : %s\n", glversion); - DBG_Printf("Extensions : %s\n", gl_extensions); - oglflags = 0; - -#ifdef _WIN32 - // BP: disable advenced feature that don't work on somes hardware - // Hurdler: Now works on G400 with bios 1.6 and certified drivers 6.04 - if (strstr(glrenderer, "810")) oglflags |= GLF_NOZBUFREAD; -#elif defined (unix) || defined (UNIXCOMMON) - // disable advanced features not working on somes hardware - if (strstr(glrenderer, "G200")) oglflags |= GLF_NOTEXENV; - if (strstr(glrenderer, "G400")) oglflags |= GLF_NOTEXENV; -#endif - DBG_Printf("oglflags : 0x%X\n", oglflags ); - -#ifdef USE_PALETTED_TEXTURE - if (isExtAvailable("GL_EXT_paletted_texture", gl_extensions)) - glColorTableEXT = SDL_GL_GetProcAddress("glColorTableEXT"); - else - glColorTableEXT = NULL; -#endif - -#ifdef USE_WGL_SWAP - if (isExtAvailable("WGL_EXT_swap_control", gl_extensions)) - wglSwapIntervalEXT = SDL_GL_GetProcAddress("wglSwapIntervalEXT"); - else - wglSwapIntervalEXT = NULL; -#else - if (isExtAvailable("GLX_SGI_swap_control", gl_extensions)) - glXSwapIntervalSGIEXT = SDL_GL_GetProcAddress("glXSwapIntervalSGI"); - else - glXSwapIntervalSGIEXT = NULL; -#endif - -#ifndef KOS_GL_COMPATIBILITY - if (isExtAvailable("GL_EXT_texture_filter_anisotropic", gl_extensions)) - pglGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maximumAnisotropy); - else -#endif - maximumAnisotropy = 0; - - SetupGLFunc13(); - - granisotropicmode_cons_t[1].value = maximumAnisotropy; - - SetModelView(w, h); - SetStates(); - pglClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); - - HWR_Startup(); -#ifdef KOS_GL_COMPATIBILITY - textureformatGL = GL_ARGB4444; -#else - textureformatGL = cbpp > 16 ? GL_RGBA : GL_RGB5_A1; -#endif - - return true; -} - -/** \brief The OglSdlFinishUpdate function - - \param vidwait wait for video sync - - \return void -*/ -void OglSdlFinishUpdate(boolean waitvbl) -{ - static boolean oldwaitvbl = false; - if (oldwaitvbl != waitvbl) - { -#ifdef USE_WGL_SWAP - if (wglSwapIntervalEXT) - wglSwapIntervalEXT(waitvbl); -#else - if (glXSwapIntervalSGIEXT) - glXSwapIntervalSGIEXT(waitvbl); -#endif - } - oldwaitvbl = waitvbl; - - SDL_GL_SwapBuffers(); -} - -EXPORT void HWRAPI( OglSdlSetPalette) (RGBA_t *palette, RGBA_t *pgamma) -{ - INT32 i = -1; - UINT32 redgamma = pgamma->s.red, greengamma = pgamma->s.green, - bluegamma = pgamma->s.blue; - -#if 0 // changing the gamma to 127 is a bad idea - i = SDL_SetGamma(byteasfloat(redgamma), byteasfloat(greengamma), byteasfloat(bluegamma)); -#endif - if (i == 0) redgamma = greengamma = bluegamma = 0x7F; //Alam: cool - for (i = 0; i < 256; i++) - { - myPaletteData[i].s.red = (UINT8)MIN((palette[i].s.red * redgamma) /127, 255); - myPaletteData[i].s.green = (UINT8)MIN((palette[i].s.green * greengamma)/127, 255); - myPaletteData[i].s.blue = (UINT8)MIN((palette[i].s.blue * bluegamma) /127, 255); - myPaletteData[i].s.alpha = palette[i].s.alpha; - } -#ifdef USE_PALETTED_TEXTURE - if (glColorTableEXT) - { - for (i = 0; i < 256; i++) - { - palette_tex[(3*i)+0] = palette[i].s.red; - palette_tex[(3*i)+1] = palette[i].s.green; - palette_tex[(3*i)+2] = palette[i].s.blue; - } - glColorTableEXT(GL_TEXTURE_2D, GL_RGB8, 256, GL_RGB, GL_UNSIGNED_BYTE, palette_tex); - } -#endif - // on a chang�de palette, il faut recharger toutes les textures - // jaja, und noch viel mehr ;-) - Flush(); -} - -#endif //HWRENDER -#endif //SDL diff --git a/src/sdl12/ogl_sdl.h b/src/sdl12/ogl_sdl.h deleted file mode 100644 index 43c28fa42..000000000 --- a/src/sdl12/ogl_sdl.h +++ /dev/null @@ -1,30 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright (C) 1998-2000 by DooM Legacy Team. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -//----------------------------------------------------------------------------- -/// \file -/// \brief SDL specific part of the OpenGL API for SRB2 - -#include "../v_video.h" - -extern SDL_Surface *vidSurface; -extern void *GLUhandle; - -boolean OglSdlSurface(INT32 w, INT32 h, boolean isFullscreen); - -void OglSdlFinishUpdate(boolean vidwait); - -#ifdef _CREATE_DLL_ -EXPORT void HWRAPI( OglSdlSetPalette ) (RGBA_t *palette, RGBA_t *pgamma); -#endif diff --git a/src/sounds.h b/src/sounds.h index bb46ea9d8..dfd0bbdcd 100644 --- a/src/sounds.h +++ b/src/sounds.h @@ -54,7 +54,7 @@ typedef enum } skinsound_t; // free sfx for S_AddSoundFx() -#define NUMSFXFREESLOTS 800 // Matches SOC Editor. +#define NUMSFXFREESLOTS 1600 // Matches SOC Editor. #define NUMSKINSFXSLOTS (MAXSKINS*NUMSKINSOUNDS) // diff --git a/src/st_stuff.c b/src/st_stuff.c index 76cef76e0..756cde575 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -203,7 +203,7 @@ void ST_Ticker(void) } // 0 is default, any others are special palettes. -static INT32 st_palette = 0; +INT32 st_palette = 0; void ST_doPaletteStuff(void) { @@ -614,9 +614,7 @@ static void ST_drawDebugInfo(void) } if (cv_debug & DBG_MEMORY) - { V_DrawRightAlignedString(320, height, V_MONOSPACE, va("Heap used: %7sKB", sizeu1(Z_TagsUsage(0, INT32_MAX)>>10))); - } } /* @@ -2039,8 +2037,6 @@ static void ST_overlayDrawer(void) break; } } - - ST_drawDebugInfo(); } void ST_DrawDemoTitleEntry(void) @@ -2142,4 +2138,5 @@ void ST_Drawer(void) else V_DrawFadeScreen(120, 15-timeinmap); // Then gradually fade out from there } + ST_drawDebugInfo(); } diff --git a/src/st_stuff.h b/src/st_stuff.h index 16f7b8811..5ed5dd1c6 100644 --- a/src/st_stuff.h +++ b/src/st_stuff.h @@ -61,6 +61,7 @@ boolean ST_SameTeam(player_t *a, player_t *b); //-------------------- extern boolean st_overlay; // sb overlay on or off when fullscreen +extern INT32 st_palette; // 0 is default, any others are special palettes. extern lumpnum_t st_borderpatchnum; // patches, also used in intermission diff --git a/src/v_video.c b/src/v_video.c index 19cf88c2b..47fe4c8e2 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -27,7 +27,7 @@ #include "doomstat.h" #ifdef HWRENDER -#include "hardware/hw_glob.h" +#include "hardware/hw_main.h" #endif // Each screen is [vid.width*vid.height]; @@ -58,30 +58,25 @@ static void CV_Gammaxxx_ONChange(void); // - You can change them in software, // but they won't do anything. static CV_PossibleValue_t grgamma_cons_t[] = {{1, "MIN"}, {255, "MAX"}, {0, NULL}}; -static CV_PossibleValue_t grsoftwarefog_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "LightPlanes"}, {0, NULL}}; +static CV_PossibleValue_t grfakecontrast_cons_t[] = {{0, "Off"}, {1, "Standard"}, {2, "Smooth"}, {0, NULL}}; +consvar_t cv_grshaders = {"gr_shaders", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grfovchange = {"gr_fovchange", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_grfog = {"gr_fog", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_grfogcolor = {"gr_fogcolor", "AAAAAA", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_grsoftwarefog = {"gr_softwarefog", "Off", CV_SAVE, grsoftwarefog_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grgammared = {"gr_gammared", "127", CV_SAVE|CV_CALL, grgamma_cons_t, CV_Gammaxxx_ONChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grgammagreen = {"gr_gammagreen", "127", CV_SAVE|CV_CALL, grgamma_cons_t, CV_Gammaxxx_ONChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grgammablue = {"gr_gammablue", "127", CV_SAVE|CV_CALL, grgamma_cons_t, CV_Gammaxxx_ONChange, 0, NULL, NULL, 0, 0, NULL}; -#ifdef ALAM_LIGHTING -consvar_t cv_grdynamiclighting = {"gr_dynamiclighting", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_grstaticlighting = {"gr_staticlighting", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_grcoronas = {"gr_coronas", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_grcoronasize = {"gr_coronasize", "1", CV_SAVE| CV_FLOAT, 0, NULL, 0, NULL, NULL, 0, 0, NULL}; -#endif //static CV_PossibleValue_t CV_MD2[] = {{0, "Off"}, {1, "On"}, {2, "Old"}, {0, NULL}}; // console variables in development consvar_t cv_grmdls = {"gr_mdls", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grfallbackplayermodel = {"gr_fallbackplayermodel", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; + +consvar_t cv_grshearing = {"gr_shearing", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grspritebillboarding = {"gr_spritebillboarding", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_grfakecontrast = {"gr_fakecontrast", "Standard", CV_SAVE, grfakecontrast_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; #endif const UINT8 gammatable[5][256] = @@ -350,7 +345,7 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t #ifdef HWRENDER //if (rendermode != render_soft && !con_startup) // Why? - if (rendermode != render_soft) + if (rendermode == render_opengl) { HWR_DrawFixedPatch((GLPatch_t *)patch, x, y, pscale, scrn, colormap); return; @@ -572,8 +567,7 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_ return; #ifdef HWRENDER - // Done - if (rendermode != render_soft && !con_startup) + if (rendermode == render_opengl) { HWR_DrawCroppedPatch((GLPatch_t*)patch,x,y,pscale,scrn,sx,sy,w,h); return; @@ -719,61 +713,6 @@ void V_DrawBlock(INT32 x, INT32 y, INT32 scrn, INT32 width, INT32 height, const } } -static void V_BlitScaledPic(INT32 px1, INT32 py1, INT32 scrn, pic_t *pic); -// Draw a linear pic, scaled, TOTALLY CRAP CODE!!! OPTIMISE AND ASM!! -// -void V_DrawScaledPic(INT32 rx1, INT32 ry1, INT32 scrn, INT32 lumpnum) -{ -#ifdef HWRENDER - if (rendermode != render_soft) - { - HWR_DrawPic(rx1, ry1, lumpnum); - return; - } -#endif - - V_BlitScaledPic(rx1, ry1, scrn, W_CacheLumpNum(lumpnum, PU_CACHE)); -} - -static void V_BlitScaledPic(INT32 rx1, INT32 ry1, INT32 scrn, pic_t * pic) -{ - INT32 dupx, dupy; - INT32 x, y; - UINT8 *src, *dest; - INT32 width, height; - - width = SHORT(pic->width); - height = SHORT(pic->height); - scrn &= V_PARAMMASK; - - if (pic->mode != 0) - { - CONS_Debug(DBG_RENDER, "pic mode %d not supported in Software\n", pic->mode); - return; - } - - dest = screens[scrn] + max(0, ry1 * vid.width) + max(0, rx1); - // y cliping to the screen - if (ry1 + height * vid.dupy >= vid.width) - height = (vid.width - ry1) / vid.dupy - 1; - // WARNING no x clipping (not needed for the moment) - - for (y = max(0, -ry1 / vid.dupy); y < height; y++) - { - for (dupy = vid.dupy; dupy; dupy--) - { - src = pic->data + y * width; - for (x = 0; x < width; x++) - { - for (dupx = vid.dupx; dupx; dupx--) - *dest++ = *src; - src++; - } - dest += vid.width - vid.dupx * width; - } - } -} - // // Fills a box of pixels with a single color, NOTE: scaled to screen size // @@ -786,7 +725,7 @@ void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c) return; #ifdef HWRENDER - if (rendermode != render_soft && !con_startup) + if (rendermode == render_opengl) { HWR_DrawFill(x, y, w, h, c); return; @@ -906,7 +845,7 @@ void V_DrawFillConsoleMap(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c) return; #ifdef HWRENDER - if (rendermode != render_soft && rendermode != render_none) + if (rendermode == render_opengl) { UINT32 hwcolor = V_GetHWConsBackColor(); HWR_DrawConsoleFill(x, y, w, h, hwcolor, c); // we still use the regular color stuff but only for flags. actual draw color is "hwcolor" for this. @@ -1117,7 +1056,7 @@ void V_DrawFlatFill(INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatnum) size_t size, lflatsize, flatshift; #ifdef HWRENDER - if (rendermode != render_soft && rendermode != render_none) + if (rendermode == render_opengl) { HWR_DrawFlatFill(x, y, w, h, flatnum); return; @@ -1317,7 +1256,7 @@ void V_DrawFadeConsBack(INT32 plines) UINT8 *deststop, *buf; #ifdef HWRENDER // not win32 only 19990829 by Kin - if (rendermode != render_soft && rendermode != render_none) + if (rendermode == render_opengl) { UINT32 hwcolor = V_GetHWConsBackColor(); HWR_DrawConsoleBack(hwcolor, plines); @@ -2423,8 +2362,7 @@ void V_DoPostProcessor(INT32 view, postimg_t type, INT32 param) INT32 yoffset, xoffset; #ifdef HWRENDER - // draw a hardware converted patch - if (rendermode != render_soft && rendermode != render_none) + if (rendermode != render_soft) return; #endif diff --git a/src/v_video.h b/src/v_video.h index 800dd69c1..17028a075 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -154,9 +154,6 @@ void V_DrawContinueIcon(INT32 x, INT32 y, INT32 flags, INT32 skinnum, UINT8 skin // Draw a linear block of pixels into the view buffer. void V_DrawBlock(INT32 x, INT32 y, INT32 scrn, INT32 width, INT32 height, const UINT8 *src); -// draw a pic_t, SCALED -void V_DrawScaledPic (INT32 px1, INT32 py1, INT32 scrn, INT32 lumpnum); - // fill a box with a single color void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c); void V_DrawFillConsoleMap(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c); diff --git a/src/w_wad.c b/src/w_wad.c index da82a276d..841d8fd3e 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -196,6 +196,7 @@ static inline void W_LoadDehackedLumpsPK3(UINT16 wadnum) LUA_LoadLump(wadnum, posStart); } #endif + posStart = W_CheckNumForFolderStartPK3("SOC/", wadnum, 0); if (posStart != INT16_MAX) { @@ -212,7 +213,6 @@ static inline void W_LoadDehackedLumpsPK3(UINT16 wadnum) DEH_LoadDehackedLumpPwad(wadnum, posStart); free(name); } - } } @@ -764,6 +764,11 @@ UINT16 W_InitFile(const char *filename) wadfiles[numwadfiles] = wadfile; numwadfiles++; // must come BEFORE W_LoadDehackedLumps, so any addfile called by COM_BufInsertText called by Lua doesn't overwrite what we just loaded +#ifdef HWRENDER + if (rendermode == render_opengl) + HWR_LoadShaders(numwadfiles - 1, (wadfile->type == RET_PK3)); +#endif + // TODO: HACK ALERT - Load Lua & SOC stuff right here. I feel like this should be out of this place, but... Let's stick with this for now. switch (wadfile->type) { @@ -1480,22 +1485,22 @@ static inline void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag) grPatch = HWR_GetCachedGLPatchPwad(wad, lump); - if (grPatch->mipmap.grInfo.data) + if (grPatch->mipmap->grInfo.data) { if (tag == PU_CACHE) tag = PU_HWRCACHE; - Z_ChangeTag(grPatch->mipmap.grInfo.data, tag); + Z_ChangeTag(grPatch->mipmap->grInfo.data, tag); } else { patch_t *ptr = NULL; // Only load the patch if we haven't initialised the grPatch yet - if (grPatch->mipmap.width == 0) + if (grPatch->mipmap->width == 0) ptr = W_CacheLumpNumPwad(grPatch->wadnum, grPatch->lumpnum, PU_STATIC); // Run HWR_MakePatch in all cases, to recalculate some things - HWR_MakePatch(ptr, grPatch, &grPatch->mipmap, false); + HWR_MakePatch(ptr, grPatch, grPatch->mipmap, false); Z_Free(ptr); } @@ -1532,6 +1537,7 @@ void *W_CachePatchName(const char *name, INT32 tag) return W_CachePatchNum(W_GetNumForName("MISSING"), tag); return W_CachePatchNum(num, tag); } + #ifndef NOMD5 /** @@ -1720,11 +1726,14 @@ int W_VerifyNMUSlumps(const char *filename) {"RRINGS", 6}, // Rings HUD (not named as SBO) {"YB_", 3}, // Intermission graphics, goes with the above {"M_", 2}, // As does menu stuff - {"MKFNT", 5}, // Kart font changes {"K_", 2}, // Kart graphic changes {"MUSICDEF", 8}, // Kart song definitions +#ifdef HWRENDER + {"SHADERS", 7}, + {"SH_", 3}, +#endif {NULL, 0}, }; return W_VerifyFile(filename, NMUSlist, false); diff --git a/src/win32/CMakeLists.txt b/src/win32/CMakeLists.txt index 39b01588b..71ce88d02 100644 --- a/src/win32/CMakeLists.txt +++ b/src/win32/CMakeLists.txt @@ -1,10 +1,5 @@ file(GLOB SRB2_WIN_SOURCES *.c *.h *.rc) -if(${SRB2_CONFIG_HWRENDER}) - set(SRB2_WIN_SOURCES ${SRB2_WIN_SOURCES} ${SRB2_HWRENDER_SOURCES} ${SRB2_HWRENDER_HEADERS}) - set(SRB2_WIN_SOURCES ${SRB2_WIN_SOURCES} ${SRB2_R_OPENGL_SOURCES} ${SRB2_R_OPENGL_HEADERS}) -endif() - add_executable(SRB2DD EXCLUDE_FROM_ALL WIN32 ${SRB2_WIN_SOURCES} ) diff --git a/src/win32/Makefile.cfg b/src/win32/Makefile.cfg index e6675421e..46b103df9 100644 --- a/src/win32/Makefile.cfg +++ b/src/win32/Makefile.cfg @@ -138,3 +138,12 @@ else LDFLAGS+=-L../libs/miniupnpc/mingw32 endif #MINGW64 endif + +ifndef NOCURL + CURL_CFLAGS+=-I../libs/curl/include +ifdef MINGW64 + CURL_LDFLAGS+=-L../libs/curl/lib64 -lcurl +else + CURL_LDFLAGS+=-L../libs/curl/lib32 -lcurl +endif #MINGW64 +endif \ No newline at end of file diff --git a/src/win32/Srb2win-vc10.vcxproj b/src/win32/Srb2win-vc10.vcxproj index ced3d128e..65500d9bc 100644 --- a/src/win32/Srb2win-vc10.vcxproj +++ b/src/win32/Srb2win-vc10.vcxproj @@ -91,6 +91,7 @@ + @@ -222,19 +223,6 @@ - - - - - - - - - - - - - @@ -388,20 +376,6 @@ - - - - - - - - - - - - - - @@ -502,4 +476,4 @@ - \ No newline at end of file + diff --git a/src/win32/Srb2win-vc10.vcxproj.filters b/src/win32/Srb2win-vc10.vcxproj.filters index 8f6077969..e5401d720 100644 --- a/src/win32/Srb2win-vc10.vcxproj.filters +++ b/src/win32/Srb2win-vc10.vcxproj.filters @@ -87,30 +87,6 @@ Win32app - - Hw_Hardware - - - Hw_Hardware - - - Hw_Hardware - - - Hw_Hardware - - - Hw_Hardware - - - Hw_Hardware - - - Hw_Hardware - - - Hw_Hardware - Hw_Hardware @@ -480,45 +456,6 @@ Win32app - - Hw_Hardware - - - Hw_Hardware - - - Hw_Hardware - - - Hw_Hardware - - - Hw_Hardware - - - Hw_Hardware - - - Hw_Hardware - - - Hw_Hardware - - - Hw_Hardware - - - Hw_Hardware - - - Hw_Hardware - - - Hw_Hardware - - - Hw_Hardware - Hw_Hardware @@ -897,4 +834,4 @@ A_Asm - \ No newline at end of file + diff --git a/src/win32/Srb2win-vc9.vcproj b/src/win32/Srb2win-vc9.vcproj index a64b8638c..cac081ad4 100644 --- a/src/win32/Srb2win-vc9.vcproj +++ b/src/win32/Srb2win-vc9.vcproj @@ -2151,10 +2151,6 @@ RelativePath="..\hardware\hw_drv.h" > - - diff --git a/src/win32/Srb2win.dsp b/src/win32/Srb2win.dsp index 501bd26b8..c52873f7b 100644 --- a/src/win32/Srb2win.dsp +++ b/src/win32/Srb2win.dsp @@ -7,19 +7,19 @@ CFG=Srb2win - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run -!MESSAGE +!MESSAGE !MESSAGE NMAKE /f "Srb2win.mak". -!MESSAGE +!MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE +!MESSAGE !MESSAGE NMAKE /f "Srb2win.mak" CFG="Srb2win - Win32 Debug" -!MESSAGE +!MESSAGE !MESSAGE Possible choices for configuration are: -!MESSAGE +!MESSAGE !MESSAGE "Srb2win - Win32 Release" (based on "Win32 (x86) Application") !MESSAGE "Srb2win - Win32 Debug" (based on "Win32 (x86) Application") -!MESSAGE +!MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 @@ -84,7 +84,7 @@ LINK32=link.exe # ADD LINK32 dxguid.lib user32.lib gdi32.lib winmm.lib advapi32.lib ws2_32.lib dinput.lib /nologo /subsystem:windows /profile /debug /machine:I386 /out:"C:\srb2demo2\srb2debug.exe" # SUBTRACT LINK32 /nodefaultlib -!ENDIF +!ENDIF # Begin Target @@ -148,7 +148,7 @@ SOURCE=.\Srb2win.rc !ELSEIF "$(CFG)" == "Srb2win - Win32 Debug" -!ENDIF +!ENDIF # End Source File # Begin Source File @@ -233,7 +233,7 @@ InputName=tmap # End Custom Build -!ENDIF +!ENDIF # End Source File # Begin Source File @@ -266,7 +266,7 @@ InputName=tmap_mmx # End Custom Build -!ENDIF +!ENDIF # End Source File # Begin Source File @@ -298,7 +298,7 @@ InputName=tmap_vc # End Custom Build -!ENDIF +!ENDIF # End Source File # End Group @@ -535,10 +535,6 @@ SOURCE=..\hardware\hw_drv.h # End Source File # Begin Source File -SOURCE=..\hardware\hw_glide.h -# End Source File -# Begin Source File - SOURCE=..\hardware\hw_glob.h # End Source File # Begin Source File diff --git a/src/win32/Srb2win.props b/src/win32/Srb2win.props index 44a30d50d..fa152f0c9 100644 --- a/src/win32/Srb2win.props +++ b/src/win32/Srb2win.props @@ -5,7 +5,10 @@ - _WINDOWS;%(PreprocessorDefinitions) + + HAVE_ZLIB;HAVE_LIBGME;_WINDOWS;%(PreprocessorDefinitions) + + _WINDOWS;%(PreprocessorDefinitions) diff --git a/src/win32/win_dll.c b/src/win32/win_dll.c index bc67f04a5..77ddc6e30 100644 --- a/src/win32/win_dll.c +++ b/src/win32/win_dll.c @@ -17,9 +17,6 @@ /// \brief load and initialise the 3D driver DLL #include "../doomdef.h" -#ifdef HWRENDER -#include "../hardware/hw_drv.h" // get the standard 3D Driver DLL exports prototypes -#endif #ifdef HW3SOUND #include "../hardware/hw3dsdrv.h" // get the 3D sound driver DLL export prototypes @@ -30,7 +27,7 @@ #include "win_dll.h" #include "win_main.h" // I_ShowLastError() -#if defined(HWRENDER) || defined(HW3SOUND) +#if defined(HW3SOUND) typedef struct loadfunc_s { LPCSTR fnName; LPVOID fnPointer; @@ -84,92 +81,6 @@ static VOID UnloadDLL (HMODULE* pModule) } #endif -// ========================================================================== -// STANDARD 3D DRIVER DLL FOR DOOM LEGACY -// ========================================================================== - -// note : the 3D driver loading should be put somewhere else.. - -#ifdef HWRENDER -static HMODULE hwdModule = NULL; - -static loadfunc_t hwdFuncTable[] = { -#ifdef _X86_ - {"Init@4", &hwdriver.pfnInit}, - {"Shutdown@0", &hwdriver.pfnShutdown}, - {"GetModeList@8", &hwdriver.pfnGetModeList}, - {"SetPalette@8", &hwdriver.pfnSetPalette}, - {"FinishUpdate@4", &hwdriver.pfnFinishUpdate}, - {"Draw2DLine@12", &hwdriver.pfnDraw2DLine}, - {"DrawPolygon@16", &hwdriver.pfnDrawPolygon}, - {"SetBlend@4", &hwdriver.pfnSetBlend}, - {"ClearBuffer@12", &hwdriver.pfnClearBuffer}, - {"SetTexture@4", &hwdriver.pfnSetTexture}, - {"ReadRect@24", &hwdriver.pfnReadRect}, - {"GClipRect@20", &hwdriver.pfnGClipRect}, - {"ClearMipMapCache@0", &hwdriver.pfnClearMipMapCache}, - {"SetSpecialState@8", &hwdriver.pfnSetSpecialState}, - {"DrawModel@16", &hwdriver.pfnDrawModel}, - {"SetTransform@4", &hwdriver.pfnSetTransform}, - {"GetTextureUsed@0", &hwdriver.pfnGetTextureUsed}, - {"GetRenderVersion@0", &hwdriver.pfnGetRenderVersion}, -#ifdef SHUFFLE - {"PostImgRedraw@4", &hwdriver.pfnPostImgRedraw}, -#endif - {"FlushScreenTextures@0",&hwdriver.pfnFlushScreenTextures}, - {"StartScreenWipe@0", &hwdriver.pfnStartScreenWipe}, - {"EndScreenWipe@0", &hwdriver.pfnEndScreenWipe}, - {"DoScreenWipe@4", &hwdriver.pfnDoScreenWipe}, - {"DrawIntermissionBG@0",&hwdriver.pfnDrawIntermissionBG}, - {"MakeScreenTexture@0", &hwdriver.pfnMakeScreenTexture}, - {"MakeScreenFinalTexture@0", &hwdriver.pfnMakeScreenFinalTexture}, - {"DrawScreenFinalTexture@8", &hwdriver.pfnDrawScreenFinalTexture}, -#else - {"Init", &hwdriver.pfnInit}, - {"Shutdown", &hwdriver.pfnShutdown}, - {"GetModeList", &hwdriver.pfnGetModeList}, - {"SetPalette", &hwdriver.pfnSetPalette}, - {"FinishUpdate", &hwdriver.pfnFinishUpdate}, - {"Draw2DLine", &hwdriver.pfnDraw2DLine}, - {"DrawPolygon", &hwdriver.pfnDrawPolygon}, - {"SetBlend", &hwdriver.pfnSetBlend}, - {"ClearBuffer", &hwdriver.pfnClearBuffer}, - {"SetTexture", &hwdriver.pfnSetTexture}, - {"ReadRect", &hwdriver.pfnReadRect}, - {"GClipRect", &hwdriver.pfnGClipRect}, - {"ClearMipMapCache", &hwdriver.pfnClearMipMapCache}, - {"SetSpecialState", &hwdriver.pfnSetSpecialState}, - {"DrawModel", &hwdriver.pfnDrawModel}, - {"SetTransform", &hwdriver.pfnSetTransform}, - {"GetTextureUsed", &hwdriver.pfnGetTextureUsed}, - {"GetRenderVersion", &hwdriver.pfnGetRenderVersion}, -#ifdef SHUFFLE - {"PostImgRedraw", &hwdriver.pfnPostImgRedraw}, -#endif - {"FlushScreenTextures", &hwdriver.pfnFlushScreenTextures}, - {"StartScreenWipe", &hwdriver.pfnStartScreenWipe}, - {"EndScreenWipe", &hwdriver.pfnEndScreenWipe}, - {"DoScreenWipe", &hwdriver.pfnDoScreenWipe}, - {"DrawIntermissionBG", &hwdriver.pfnDrawIntermissionBG}, - {"MakeScreenTexture", &hwdriver.pfnMakeScreenTexture}, - {"MakeScreenFinalTexture", &hwdriver.pfnMakeScreenFinalTexture}, - {"DrawScreenFinalTexture", &hwdriver.pfnDrawScreenFinalTexture}, -#endif - {NULL,NULL} -}; - -BOOL Init3DDriver (LPCSTR dllName) -{ - hwdModule = LoadDLL(dllName, hwdFuncTable); - return (hwdModule != NULL); -} - -VOID Shutdown3DDriver (VOID) -{ - UnloadDLL(&hwdModule); -} -#endif - #ifdef HW3SOUND static HMODULE hwsModule = NULL; diff --git a/src/win32/win_dll.h b/src/win32/win_dll.h index b4b259587..f69a8c21f 100644 --- a/src/win32/win_dll.h +++ b/src/win32/win_dll.h @@ -20,11 +20,6 @@ #define RPC_NO_WINDOWS_H #include -#ifdef HWRENDER -BOOL Init3DDriver (LPCSTR dllName); -VOID Shutdown3DDriver (VOID); -#endif - #ifdef HW3SOUND BOOL Init3DSDriver(LPCSTR dllName); VOID Shutdown3DSDriver(VOID); diff --git a/src/win32/win_vid.c b/src/win32/win_vid.c index 45f96e9d4..ecdd01674 100644 --- a/src/win32/win_vid.c +++ b/src/win32/win_vid.c @@ -36,12 +36,6 @@ #include "../command.h" #include "../screen.h" -#ifdef HWRENDER -#include "win_dll.h" // loading the render DLL -#include "../hardware/hw_drv.h" // calling driver init & shutdown -#include "../hardware/hw_main.h" // calling HWR module init & shutdown -#endif - // ------- // Globals // ------- @@ -222,12 +216,7 @@ void I_StartupGraphics(void) if (graphics_started) return; -#ifdef HWRENDER - else if (M_CheckParm("-opengl")) - rendermode = render_opengl; - else -#endif - rendermode = render_soft; + rendermode = render_soft; if (dedicated) rendermode = render_none; @@ -245,10 +234,6 @@ void I_StartupGraphics(void) // ------------------ void I_ShutdownGraphics(void) { -#ifdef HWRENDER - const rendermode_t oldrendermode = rendermode; -#endif - // This is BAD because it makes the I_Error box screw up! // rendermode = render_none; @@ -273,15 +258,6 @@ void I_ShutdownGraphics(void) bmiMain = NULL; } -#ifdef HWRENDER - if (oldrendermode != render_soft) - { - HWR_Shutdown(); // free stuff from the hardware renderer - HWD.pfnShutdown(); // close 3d card display - Shutdown3DDriver(); // free the driver DLL - } -#endif - // free the last video mode screen buffers if (vid.buffer) { @@ -289,10 +265,7 @@ void I_ShutdownGraphics(void) vid.buffer = NULL; } -#ifdef HWRENDER - if (rendermode == render_soft) -#endif - CloseDirectDraw(); + CloseDirectDraw(); graphics_started = false; } @@ -380,11 +353,6 @@ void I_FinishUpdate(void) DIB_RGB_COLORS); } else -#ifdef HWRENDER - if (rendermode != render_soft) - HWD.pfnFinishUpdate(cv_vidwait.value); - else -#endif { // DIRECT DRAW // copy virtual screen to real screen @@ -486,9 +454,6 @@ void I_SetPalette(RGBA_t *palette) } } else -#ifdef HWRENDER - if (rendermode == render_soft) -#endif { PALETTEENTRY mainpal[256]; @@ -680,56 +645,14 @@ static VOID VID_Init(VOID) bDIBMode = TRUE; bAppFullScreen = FALSE; -#ifdef HWRENDER - // initialize the appropriate display device - if (rendermode != render_soft) + if (!bWinParm) { - const char *drvname = NULL; - - switch (rendermode) - { - case render_opengl: - drvname = "r_opengl.dll"; - break; - default: - I_Error("Unknown hardware render mode"); - } - - // load the DLL - if (drvname && Init3DDriver(drvname)) - { - int hwdversion = HWD.pfnGetRenderVersion(); - if (hwdversion != VERSION) - CONS_Alert(CONS_WARNING, M_GetText("This r_opengl version is not supported, use it at your own risk!\n")); - - // perform initialisations - HWD.pfnInit(I_Error); - // get available display modes for the device - HWD.pfnGetModeList(&pvidmodes, &numvidmodes); - } - else - { - switch (rendermode) - { - case render_opengl: - I_Error("Error initializing OpenGL"); - default: - break; - } - rendermode = render_soft; - } + if (!CreateDirectDrawInstance()) + bWinParm = TRUE; + else // get available display modes for the device + VID_GetExtraModes(); } - if (rendermode == render_soft) -#endif - if (!bWinParm) - { - if (!CreateDirectDrawInstance()) - bWinParm = TRUE; - else // get available display modes for the device - VID_GetExtraModes(); - } - // the game boots in 320x200 standard VGA, but // we need a highcolor mode to run the game in highcolor if (highcolor && !numvidmodes) @@ -927,14 +850,6 @@ INT32 VID_SetMode(INT32 modenum) // we switch to fullscreen bAppFullScreen = TRUE; bDIBMode = FALSE; -#ifdef HWRENDER - if (rendermode != render_soft) - { - // purge all patch graphics stored in software format - //Z_FreeTags (PU_PURGELEVEL, PU_PURGELEVEL+100); - HWR_Startup(); - } -#endif } I_RestartSysMouse(); diff --git a/src/win32ce/win_dll.c b/src/win32ce/win_dll.c index 8b88f84dd..2bda7126d 100644 --- a/src/win32ce/win_dll.c +++ b/src/win32ce/win_dll.c @@ -17,9 +17,6 @@ /// \brief load and initialise the 3D driver DLL #include "../doomdef.h" -#ifdef HWRENDER -#include "../hardware/hw_drv.h" // get the standard 3D Driver DLL exports prototypes -#endif #ifdef HW3SOUND #include "../hardware/hw3dsdrv.h" // get the 3D sound driver DLL export prototypes @@ -28,7 +25,7 @@ #include "win_dll.h" #include "win_main.h" // I_GetLastErrorMsgBox() -#if defined(HWRENDER) || defined(HW3SOUND) +#if defined(HW3SOUND) typedef struct loadfunc_s { LPCSTR fnName; LPVOID fnPointer; @@ -82,49 +79,6 @@ static inline VOID UnloadDLL (HMODULE* pModule) } #endif -// ========================================================================== -// STANDARD 3D DRIVER DLL FOR DOOM LEGACY -// ========================================================================== - -// note : the 3D driver loading should be put somewhere else.. - -#ifdef HWRENDER -static HMODULE hwdModule = NULL; - -static loadfunc_t hwdFuncTable[] = { - {"_Init@4", &hwdriver.pfnInit}, - {"_Shutdown@0", &hwdriver.pfnShutdown}, - {"_GetModeList@8", &hwdriver.pfnGetModeList}, - {"_SetPalette@8", &hwdriver.pfnSetPalette}, - {"_FinishUpdate@4", &hwdriver.pfnFinishUpdate}, - {"_Draw2DLine@12", &hwdriver.pfnDraw2DLine}, - {"_DrawPolygon@16", &hwdriver.pfnDrawPolygon}, - {"_SetBlend@4", &hwdriver.pfnSetBlend}, - {"_ClearBuffer@12", &hwdriver.pfnClearBuffer}, - {"_SetTexture@4", &hwdriver.pfnSetTexture}, - {"_ReadRect@24", &hwdriver.pfnReadRect}, - {"_GClipRect@20", &hwdriver.pfnGClipRect}, - {"_ClearMipMapCache@0",&hwdriver.pfnClearMipMapCache}, - {"_SetSpecialState@8", &hwdriver.pfnSetSpecialState}, - {"_DrawMD2@16", &hwdriver.pfnDrawMD2}, - {"_SetTransform@4", &hwdriver.pfnSetTransform}, - {"_GetTextureUsed@0", &hwdriver.pfnGetTextureUsed}, - {"_GetRenderVersion@0",&hwdriver.pfnGetRenderVersion}, - {NULL,NULL} -}; - -BOOL Init3DDriver (LPCSTR dllName) -{ - hwdModule = LoadDLL(dllName, hwdFuncTable); - return (hwdModule != NULL); -} - -VOID Shutdown3DDriver (VOID) -{ - UnloadDLL(&hwdModule); -} -#endif - #ifdef HW3SOUND static HMODULE hwsModule = NULL; diff --git a/src/win32ce/win_dll.h b/src/win32ce/win_dll.h index b4b259587..f69a8c21f 100644 --- a/src/win32ce/win_dll.h +++ b/src/win32ce/win_dll.h @@ -20,11 +20,6 @@ #define RPC_NO_WINDOWS_H #include -#ifdef HWRENDER -BOOL Init3DDriver (LPCSTR dllName); -VOID Shutdown3DDriver (VOID); -#endif - #ifdef HW3SOUND BOOL Init3DSDriver(LPCSTR dllName); VOID Shutdown3DSDriver(VOID); diff --git a/src/win32ce/win_vid.c b/src/win32ce/win_vid.c index 244dfaf3e..439103f38 100644 --- a/src/win32ce/win_vid.c +++ b/src/win32ce/win_vid.c @@ -34,12 +34,6 @@ #include "../command.h" #include "../screen.h" -#ifdef HWRENDER -#include "win_dll.h" // loading the render DLL -#include "../hardware/hw_drv.h" // calling driver init & shutdown -#include "../hardware/hw_main.h" // calling HWR module init & shutdown -#endif - // ------- // Globals // ------- @@ -110,13 +104,6 @@ void I_StartupGraphics(void) if (graphics_started) return; -#ifdef HWRENDER - if (M_CheckParm("-opengl")) - rendermode = render_opengl; - else - rendermode = render_soft; -#endif - if (dedicated) rendermode = render_none; else @@ -152,15 +139,6 @@ void I_ShutdownGraphics(void) bmiMain = NULL; } -#ifdef HWRENDER - if (rendermode != render_soft) - { - HWR_Shutdown(); // free stuff from the hardware renderer - HWD.pfnShutdown(); // close 3d card display - Shutdown3DDriver(); // free the driver DLL - } -#endif - // free the last video mode screen buffers if (vid.buffer) { @@ -168,10 +146,7 @@ void I_ShutdownGraphics(void) vid.buffer = NULL; } -#ifdef HWRENDER - if (rendermode == render_soft) -#endif - CloseDirectDraw(); + CloseDirectDraw(); graphics_started = false; } @@ -212,11 +187,6 @@ void I_FinishUpdate(void) DIB_RGB_COLORS); } else -#ifdef HWRENDER - if (rendermode != render_soft) - HWD.pfnFinishUpdate(cv_vidwait.value); - else -#endif { // DIRECT DRAW // copy virtual screen to real screen @@ -295,9 +265,6 @@ void I_SetPalette(RGBA_t *palette) } } else -#ifdef HWRENDER - if (rendermode == render_soft) -#endif { PALETTEENTRY mainpal[256]; @@ -458,56 +425,14 @@ static void VID_Init(void) bDIBMode = TRUE; bAppFullScreen = FALSE; -#ifdef HWRENDER - // initialize the appropriate display device - if (rendermode != render_soft) + if (!bWinParm) { - const char *drvname = NULL; - - switch (rendermode) - { - case render_opengl: - drvname = "r_opengl.dll"; - break; - default: - I_Error("Unknown hardware render mode"); - } - - // load the DLL - if (drvname && Init3DDriver(drvname)) - { - int hwdversion = HWD.pfnGetRenderVersion(); - if (hwdversion != VERSION) - CONS_Printf("WARNING: This r_opengl version is not supported, use it at your own risk.\n"); - - // perform initialisations - HWD.pfnInit(I_Error); - // get available display modes for the device - HWD.pfnGetModeList(&pvidmodes, &numvidmodes); - } - else - { - switch (rendermode) - { - case render_opengl: - I_Error("Error initializing OpenGL"); - default: - break; - } - rendermode = render_soft; - } + if (!CreateDirectDrawInstance()) + I_Error("Error initializing DirectDraw"); + // get available display modes for the device + VID_GetExtraModes(); } - if (rendermode == render_soft) -#endif - if (!bWinParm) - { - if (!CreateDirectDrawInstance()) - I_Error("Error initializing DirectDraw"); - // get available display modes for the device - VID_GetExtraModes(); - } - // the game boots in 320x200 standard VGA, but // we need a highcolor mode to run the game in highcolor if (highcolor && !numvidmodes) @@ -705,14 +630,6 @@ INT32 VID_SetMode(INT32 modenum) // we switch to fullscreen bAppFullScreen = TRUE; bDIBMode = FALSE; -#ifdef HWRENDER - if (rendermode != render_soft) - { - // purge all patch graphics stored in software format - //Z_FreeTags (PU_PURGELEVEL, PU_PURGELEVEL+100); - HWR_Startup(); - } -#endif } I_RestartSysMouse(); diff --git a/src/z_zone.c b/src/z_zone.c index a3e13422f..dae7dff04 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -637,7 +637,6 @@ void Command_Memfree_f(void) CONS_Printf(M_GetText("Mipmap patches : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPATCHCOLMIPMAP)>>10)); CONS_Printf(M_GetText("HW Texture cache : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRCACHE)>>10)); CONS_Printf(M_GetText("Plane polygons : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPLANE)>>10)); - CONS_Printf(M_GetText("HW Texture used : %7d KB\n"), HWR_GetTextureUsed()>>10); } #endif