mirror of
https://github.com/FWGS/xash3d-fwgs.git
synced 2026-08-05 19:45:05 +08:00
Compare commits
28 Commits
continuous
...
continuous
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3fb92e22fd | ||
|
|
7364765d62 | ||
|
|
b64329d1ee | ||
|
|
ff1d3c4257 | ||
|
|
d418fb5f28 | ||
|
|
62d7959843 | ||
|
|
980f356fe9 | ||
|
|
83194ca0f5 | ||
|
|
d23968b12e | ||
|
|
5034b860c8 | ||
|
|
5a708f90c6 | ||
|
|
4118ac2561 | ||
|
|
5777431577 | ||
|
|
cd86f80203 | ||
|
|
8c885d3f37 | ||
|
|
dddb46a6d0 | ||
|
|
6b0f378c5b | ||
|
|
9dd7f37d42 | ||
|
|
9f10fb6472 | ||
|
|
64dbccb9bd | ||
|
|
9a432a5a13 | ||
|
|
842e494fa6 | ||
|
|
7fc9ee154a | ||
|
|
5f84010c2a | ||
|
|
3dcd6cb80b | ||
|
|
79e94bf766 | ||
|
|
3de370f3d5 | ||
|
|
c84d2f4624 |
2
.github/workflows/c-cpp.yml
vendored
2
.github/workflows/c-cpp.yml
vendored
@@ -60,6 +60,8 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: bash scripts/gha/deps_${{ matrix.targetos }}.sh
|
||||
- name: Build engine
|
||||
env:
|
||||
FWGS_PFX_PASSWORD: ${{ secrets.FWGS_PFX_PASSWORD }}
|
||||
run: bash scripts/gha/build_${{ matrix.targetos }}.sh
|
||||
- name: Upload engine (artifacts)
|
||||
uses: actions/upload-artifact@v4
|
||||
|
||||
2
3rdparty/mainui
vendored
2
3rdparty/mainui
vendored
Submodule 3rdparty/mainui updated: ad333f6152...b7edbaf2de
19
Documentation/extensions/litwater.md
Normal file
19
Documentation/extensions/litwater.md
Normal file
@@ -0,0 +1,19 @@
|
||||
## Lightmapped water
|
||||
|
||||
Xash3D FWGS supports lightmapped water, as an extension. It adds three new cvars and new worldspawn key values.
|
||||
|
||||
### For level designers:
|
||||
|
||||
If you're a level designer and intend to make your level to have lightmapped water, you can put these keyvalues to worldspawn entity description (always first entity in entities list):
|
||||
|
||||
| Key | Value | Description |
|
||||
| ---------------------- | ------- | ----------- |
|
||||
| `_litwater` | integer | Set to any non-zero value to enable lightmapped water. Overrides `gl_litwater_force` cvar value. |
|
||||
| `_litwater_minlight` | integer | Minimal lightmap value water surface will receive. Helps to avoid too dark areas when water isn't properly lit. If not set, defaults to zero. |
|
||||
| `_litwater_scale` | float | Scales up lightmap value for water surfaces. If not set, defaults to 1.0. |
|
||||
|
||||
### For players:
|
||||
|
||||
Some of the maps already have computed lightmap for water surfaces and sometimes water has been properly lit but the support hasn't been declared by the level designer.
|
||||
|
||||
As a player, you can enable it in `Video options` menu or through console with `gl_litwater_force` cvar. There are also `gl_litwater_minlight` and `gl_litwater_scale` cvars that function similar to keys above. The default values has been set to `192` and `1.25` respectively to slightly avoid issues with maps that wasn't intended to have lightmapped water.
|
||||
@@ -543,14 +543,8 @@ typedef struct
|
||||
#define MAX_CLIENT_SPRITES 512 // SpriteTextures (0-256 hud, 256-512 client)
|
||||
#define MAX_REQUESTS 64
|
||||
|
||||
#if ! XASH_64BIT
|
||||
STATIC_ASSERT( sizeof( mextrasurf_t ) == 324, "mextrasurf_t unexpected size" );
|
||||
STATIC_ASSERT( sizeof( decal_t ) == 60, "decal_t unexpected size");
|
||||
STATIC_ASSERT( sizeof( mfaceinfo_t ) == 176, "mfaceinfo_t unexpected size");
|
||||
#else
|
||||
STATIC_ASSERT( sizeof( mextrasurf_t) == 496, "mextrasurf_t unexpected size");
|
||||
STATIC_ASSERT( sizeof( decal_t ) == 88, "decal_t unexpected size");
|
||||
STATIC_ASSERT( sizeof( mfaceinfo_t ) == 304, "mfaceinfo_t unexpected size");
|
||||
#endif
|
||||
STATIC_CHECK_SIZEOF( mextrasurf_t, 324, 496 );
|
||||
STATIC_CHECK_SIZEOF( decal_t, 60, 88 );
|
||||
STATIC_CHECK_SIZEOF( mfaceinfo_t, 176, 304 );
|
||||
|
||||
#endif//COM_MODEL_H
|
||||
|
||||
159
common/cvardef.h
159
common/cvardef.h
@@ -1,49 +1,122 @@
|
||||
/***
|
||||
*
|
||||
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
|
||||
*
|
||||
* This product contains software technology licensed from Id
|
||||
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Use, distribution, and modification of this source code and/or resulting
|
||||
* object code is restricted to non-commercial enhancements to products from
|
||||
* Valve LLC. All other use, distribution, or modification is prohibited
|
||||
* without written permission from Valve LLC.
|
||||
*
|
||||
****/
|
||||
#ifndef CVARDEF_H
|
||||
#define CVARDEF_H
|
||||
/*
|
||||
cvardef.h - quake cvar definition
|
||||
Copyright (C) 1997-2001 Id Software, Inc.
|
||||
Copyright (C) 2024 Alibek Omarov
|
||||
|
||||
#define FCVAR_ARCHIVE (1<<0) // set to cause it to be saved to vars.rc
|
||||
#define FCVAR_USERINFO (1<<1) // changes the client's info string
|
||||
#define FCVAR_SERVER (1<<2) // notifies players when changed
|
||||
#define FCVAR_EXTDLL (1<<3) // defined by external DLL
|
||||
#define FCVAR_CLIENTDLL (1<<4) // defined by the client dll
|
||||
#define FCVAR_PROTECTED (1<<5) // It's a server cvar, but we don't send the data since it's a password, etc. Sends 1 if it's not bland/zero, 0 otherwise as value
|
||||
#define FCVAR_SPONLY (1<<6) // This cvar cannot be changed by clients connected to a multiplayer server.
|
||||
#define FCVAR_PRINTABLEONLY (1<<7) // This cvar's string cannot contain unprintable characters ( e.g., used for player name etc ).
|
||||
#define FCVAR_UNLOGGED (1<<8) // If this is a FCVAR_SERVER, don't log changes to the log file / console if we are creating a log
|
||||
#define FCVAR_NOEXTRAWHITEPACE (1<<9) // strip trailing/leading white space from this cvar
|
||||
#define FCVAR_PRIVILEGED (1<<10) // only available in privileged mode
|
||||
#define FCVAR_FILTERABLE (1<<11) // filtered in unprivileged mode if cl_filterstuffcmd is 1
|
||||
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.
|
||||
|
||||
// Xash3D extensions
|
||||
#define FCVAR_GLCONFIG (1<<12) // write it into <renderer>.cfg(see RefAPI)
|
||||
#define FCVAR_CHANGED (1<<13) // set each time the cvar is changed
|
||||
#define FCVAR_GAMEUIDLL (1<<14) // defined by the menu DLL
|
||||
#define FCVAR_CHEAT (1<<15) // can not be changed if cheats are disabled
|
||||
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.
|
||||
|
||||
// a1ba: let's reuse higher bits for flags extensions from now on
|
||||
#define FCVAR_LATCH (1<<30) // notify client what this cvar will be applied only after server restart (but don't does more nothing)
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
typedef struct cvar_s
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef CVAR
|
||||
#define CVAR
|
||||
|
||||
#include STDINT_H
|
||||
#include "xash3d_types.h"
|
||||
|
||||
/*
|
||||
|
||||
cvar_t variables are used to hold scalar or string variables that can be changed
|
||||
or displayed at the console or prog code as well as accessed directly
|
||||
in C code.
|
||||
|
||||
The user can access cvars from the console in three ways:
|
||||
r_draworder prints the current value
|
||||
r_draworder 0 sets the current value to 0
|
||||
set r_draworder 0 as above, but creates the cvar if not present
|
||||
|
||||
Cvars are restricted from having the same names as commands to keep this
|
||||
interface from being ambiguous.
|
||||
|
||||
The are also occasionally used to communicated information between different
|
||||
modules of the program.
|
||||
|
||||
*/
|
||||
|
||||
enum
|
||||
{
|
||||
char *name;
|
||||
char *string;
|
||||
int flags;
|
||||
float value;
|
||||
struct cvar_s *next;
|
||||
} cvar_t;
|
||||
// GoldSrc compatibility flags
|
||||
FCVAR_ARCHIVE = 1 << 0, // set to cause it to be saved to vars.rc
|
||||
FCVAR_USERINFO = 1 << 1, // added to userinfo when changed
|
||||
FCVAR_SERVER = 1 << 2, // added to serverinfo when changed, will notify clients by default
|
||||
FCVAR_EXTDLL = 1 << 3, // defined by server.dll
|
||||
FCVAR_CLIENTDLL = 1 << 4, // defined by client.dll
|
||||
FCVAR_PROTECTED = 1 << 5, // private server cvar
|
||||
FCVAR_SPONLY = 1 << 6, // can be set only in singleplayer
|
||||
FCVAR_PRINTABLEONLY = 1 << 7, // only allows printable characters
|
||||
FCVAR_UNLOGGED = 1 << 8, // disables notifying client about server cvar change
|
||||
FCVAR_NOEXTRAWHITESPACE = 1 << 9, // removes space characters from the beginning and the end of the string
|
||||
FCVAR_PRIVILEGED = 1 << 10, // only available in privileged mode
|
||||
FCVAR_FILTERABLE = 1 << 11, // treated as privileged if cl_filterstuffcmd is 1, otherwise ignored
|
||||
|
||||
#endif//CVARDEF_H
|
||||
// Xash3D public flags
|
||||
// FCVAR_LATCH = 1 << 11, // deprecated Xash3D flag, conflicts with FCVAR_FILTERABLE. Use another FCVAR_LATCH!
|
||||
FCVAR_GLCONFIG = 1 << 12, // set to cause it to be saved to <renderer>.cfg (see RefAPI)
|
||||
FCVAR_CHANGED = 1 << 13, // set each time the cvar changed
|
||||
FCVAR_GAMEUIDLL = 1 << 14, // defined by menu.dll
|
||||
FCVAR_CHEAT = 1 << 15, // cannot be changed if sv_cheats is 0
|
||||
|
||||
#if REF_DLL || ENGINE_DLL // Xash3D internal flags, MUST NOT be used outside of engine
|
||||
FCVAR_RENDERINFO = 1 << 16, // set to cause it to be saved to video.cfg
|
||||
FCVAR_READ_ONLY = 1 << 17, // display only, cannot be set by user at all
|
||||
FCVAR_EXTENDED = 1 << 18, // extended cvar structure
|
||||
FCVAR_ALLOCATED = 1 << 19, // allocated by the engine, must be freed with Mem_Free
|
||||
FCVAR_VIDRESTART = 1 << 20, // triggers video subsystem to recreate/modify window parameters
|
||||
FCVAR_TEMPORARY = 1 << 21, // only used to temporarly hold some value, can be unlinked
|
||||
FCVAR_MOVEVARS = 1 << 22, // access to movevars_t structure, synchornized between client and server
|
||||
FCVAR_USER_CREATED = 1 << 23, // created by a set command
|
||||
|
||||
FCVAR_REFDLL = 1 << 29, // (Xash3D FWGS internal flag) defined by the renderer DLL
|
||||
#endif // REF_DLL || ENGINE_DLL
|
||||
|
||||
FCVAR_LATCH = 1 << 30, // (Xash3D FWGS public flag, was FCVAR_FILTERABLE in Xash3D) save changes until server restart
|
||||
};
|
||||
|
||||
struct cvar_s {
|
||||
char *name;
|
||||
char *string;
|
||||
uint32_t flags;
|
||||
float value;
|
||||
struct cvar_s *next;
|
||||
};
|
||||
typedef struct cvar_s cvar_t;
|
||||
|
||||
STATIC_CHECK_SIZEOF( struct cvar_s, 20, 32 );
|
||||
|
||||
#if REF_DLL || ENGINE_DLL // Xash3D internal cvar format, MUST NOT be used outside of engine
|
||||
struct convar_s {
|
||||
char *name;
|
||||
char *string;
|
||||
uint32_t flags;
|
||||
float value;
|
||||
struct convar_s *next;
|
||||
char *desc;
|
||||
char *def_string;
|
||||
};
|
||||
typedef struct convar_s convar_t;
|
||||
|
||||
#if XASH_64BIT
|
||||
#define CVAR_SENTINEL (uintptr_t)0xDEADBEEFDEADBEEF
|
||||
#else
|
||||
#define CVAR_SENTINEL (uintptr_t)0xDEADBEEF
|
||||
#endif
|
||||
|
||||
#define CVAR_CHECK_SENTINEL( cv ) ((uintptr_t)(cv)->next == CVAR_SENTINEL)
|
||||
|
||||
#define CVAR_DEFINE( cv, cvname, cvstr, cvflags, cvdesc ) \
|
||||
convar_t cv = { (char*)cvname, (char*)cvstr, cvflags, 0.0f, (void *)CVAR_SENTINEL, (char*)cvdesc, NULL }
|
||||
|
||||
#define CVAR_DEFINE_AUTO( cv, cvstr, cvflags, cvdesc ) CVAR_DEFINE( cv, #cv, cvstr, cvflags, cvdesc )
|
||||
#endif // REF_DLL || ENGINE_DLL
|
||||
|
||||
#endif // CVAR
|
||||
|
||||
@@ -30,6 +30,6 @@ typedef struct
|
||||
int state; // low bit is down state
|
||||
} kbutton_t;
|
||||
|
||||
STATIC_ASSERT( sizeof( kbutton_t ) == 12, "kbutton_t isn't 12 bytes!" );
|
||||
STATIC_CHECK_SIZEOF( kbutton_t, 12, 12 );
|
||||
|
||||
#endif // KBUTTON_H
|
||||
|
||||
@@ -69,6 +69,6 @@ typedef struct netadr_s
|
||||
} netadr_t;
|
||||
#pragma pack( pop )
|
||||
|
||||
STATIC_ASSERT( sizeof( netadr_t ) == 20, "netadr_t isn't 20 bytes!" );
|
||||
STATIC_CHECK_SIZEOF( netadr_t, 20, 20 );
|
||||
|
||||
#endif // NET_ADR_H
|
||||
|
||||
@@ -130,6 +130,15 @@ typedef uint64_t longtime_t;
|
||||
#define STATIC_ASSERT( x, y ) STATIC_ASSERT_2( __LINE__, x, y )
|
||||
#endif
|
||||
|
||||
// at least, statically check size of some public structures
|
||||
#if XASH_64BIT
|
||||
#define STATIC_CHECK_SIZEOF( type, size32, size64 ) \
|
||||
STATIC_ASSERT( sizeof( type ) == size64, #type " unexpected size" )
|
||||
#else
|
||||
#define STATIC_CHECK_SIZEOF( type, size32, size64 ) \
|
||||
STATIC_ASSERT( sizeof( type ) == size32, #type " unexpected size" )
|
||||
#endif
|
||||
|
||||
#if !defined( __cplusplus ) && __STDC_VERSION__ >= 199101L // not C++ and C99 or newer
|
||||
#define XASH_RESTRICT restrict
|
||||
#elif _MSC_VER || __GNUC__ || __clang__ // compiler-specific extensions
|
||||
|
||||
@@ -74,7 +74,7 @@ typedef struct
|
||||
float size;
|
||||
} daliashdr_t;
|
||||
|
||||
STATIC_ASSERT( sizeof( daliashdr_t ) == 84, "invalid daliashdr_t size" );
|
||||
STATIC_CHECK_SIZEOF( daliashdr_t, 84, 84 );
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -83,7 +83,7 @@ typedef struct
|
||||
int32_t t;
|
||||
} stvert_t;
|
||||
|
||||
STATIC_ASSERT( sizeof( stvert_t ) == 12, "invalid stvert_t size" );
|
||||
STATIC_CHECK_SIZEOF( stvert_t, 12, 12 );
|
||||
|
||||
typedef struct dtriangle_s
|
||||
{
|
||||
@@ -91,7 +91,7 @@ typedef struct dtriangle_s
|
||||
int32_t vertindex[3];
|
||||
} dtriangle_t;
|
||||
|
||||
STATIC_ASSERT( sizeof( dtriangle_t ) == 16, "invalid dtriangle_t size" );
|
||||
STATIC_CHECK_SIZEOF( dtriangle_t, 16, 16 );
|
||||
|
||||
#define DT_FACES_FRONT 0x0010
|
||||
#define ALIAS_ONSEAM 0x0020
|
||||
@@ -103,7 +103,7 @@ typedef struct
|
||||
char name[16]; // frame name from grabbing
|
||||
} daliasframe_t;
|
||||
|
||||
STATIC_ASSERT( sizeof( daliasframe_t ) == 24, "invalid daliasframe_t size" );
|
||||
STATIC_CHECK_SIZEOF( daliasframe_t, 24, 24 );
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -112,41 +112,41 @@ typedef struct
|
||||
trivertex_t bboxmax; // lightnormal isn't used
|
||||
} daliasgroup_t;
|
||||
|
||||
STATIC_ASSERT( sizeof( daliasgroup_t ) == 12, "invalid daliasgrou_t size" );
|
||||
STATIC_CHECK_SIZEOF( daliasgroup_t, 12, 12 );
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int32_t numskins;
|
||||
} daliasskingroup_t;
|
||||
|
||||
STATIC_ASSERT( sizeof( daliasskingroup_t ) == 4, "invalid daliasskingroup_t size" );
|
||||
STATIC_CHECK_SIZEOF( daliasskingroup_t, 4, 4 );
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float interval;
|
||||
} daliasinterval_t;
|
||||
|
||||
STATIC_ASSERT( sizeof( daliasinterval_t ) == 4, "invalid daliasinterval_t size" );
|
||||
STATIC_CHECK_SIZEOF( daliasinterval_t, 4, 4 );
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float interval;
|
||||
} daliasskininterval_t;
|
||||
|
||||
STATIC_ASSERT( sizeof( daliasskininterval_t ) == 4, "invalid daliasskininterval_t size" );
|
||||
STATIC_CHECK_SIZEOF( daliasskininterval_t, 4, 4 );
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t type; // was aliasframetype_t
|
||||
} daliasframetype_t;
|
||||
|
||||
STATIC_ASSERT( sizeof( daliasframetype_t ) == 4, "invalid daliasframetype_t size" );
|
||||
STATIC_CHECK_SIZEOF( daliasframetype_t, 4, 4 );
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t type; // was aliasskintype_t
|
||||
} daliasskintype_t;
|
||||
|
||||
STATIC_ASSERT( sizeof( daliasskintype_t ) == 4, "invalid daliasskintype_t size" );
|
||||
STATIC_CHECK_SIZEOF( daliasskintype_t, 4, 4 );
|
||||
|
||||
#endif//ALIAS_H
|
||||
|
||||
@@ -171,6 +171,22 @@ static intptr_t pfnEngineGetParm( int parm, int arg )
|
||||
return CL_RenderGetParm( parm, arg, false ); // prevent recursion
|
||||
}
|
||||
|
||||
static cvar_t *pfnCvar_Get( const char *szName, const char *szValue, int flags, const char *description )
|
||||
{
|
||||
return (cvar_t *)Cvar_Get( szName, szValue, flags | FCVAR_REFDLL, description );
|
||||
}
|
||||
|
||||
static void pfnCvar_RegisterVariable( convar_t *var )
|
||||
{
|
||||
SetBits( var->flags, FCVAR_REFDLL );
|
||||
Cvar_RegisterVariable( var );
|
||||
}
|
||||
|
||||
static void pfnCvar_FullSet( const char *var_name, const char *value, int flags )
|
||||
{
|
||||
Cvar_FullSet( var_name, value, flags | FCVAR_REFDLL );
|
||||
}
|
||||
|
||||
static void pfnStudioEvent( const mstudioevent_t *event, const cl_entity_t *e )
|
||||
{
|
||||
clgame.dllFuncs.pfnStudioEvent( event, e );
|
||||
@@ -289,14 +305,14 @@ static const ref_api_t gEngfuncs =
|
||||
{
|
||||
pfnEngineGetParm,
|
||||
|
||||
(void*)Cvar_Get,
|
||||
pfnCvar_Get,
|
||||
(void*)Cvar_FindVarExt,
|
||||
Cvar_VariableValue,
|
||||
Cvar_VariableString,
|
||||
Cvar_SetValue,
|
||||
Cvar_Set,
|
||||
Cvar_RegisterVariable,
|
||||
Cvar_FullSet,
|
||||
pfnCvar_RegisterVariable,
|
||||
pfnCvar_FullSet,
|
||||
|
||||
Cmd_AddRefCommand,
|
||||
Cmd_RemoveCommand,
|
||||
@@ -431,7 +447,7 @@ static void R_UnloadProgs( void )
|
||||
|
||||
Cvar_FullSet( "host_refloaded", "0", FCVAR_READ_ONLY );
|
||||
|
||||
Cvar_Unlink( FCVAR_RENDERINFO | FCVAR_GLCONFIG );
|
||||
Cvar_Unlink( FCVAR_RENDERINFO | FCVAR_GLCONFIG | FCVAR_REFDLL );
|
||||
Cmd_Unlink( CMD_REFDLL );
|
||||
|
||||
COM_FreeLibrary( ref.hInstance );
|
||||
@@ -473,7 +489,7 @@ static qboolean R_LoadProgs( const char *name )
|
||||
if( ref.hInstance ) R_UnloadProgs();
|
||||
|
||||
FS_AllowDirectPaths( true );
|
||||
if( !(ref.hInstance = COM_LoadLibrary( name, false, true ) ))
|
||||
if( !( ref.hInstance = COM_LoadLibrary( name, false, true )))
|
||||
{
|
||||
FS_AllowDirectPaths( false );
|
||||
Con_Reportf( "%s: can't load renderer library %s: %s\n", __func__, name, COM_GetLibraryError() );
|
||||
@@ -482,11 +498,9 @@ static qboolean R_LoadProgs( const char *name )
|
||||
|
||||
FS_AllowDirectPaths( false );
|
||||
|
||||
if( !( GetRefAPI = (REFAPI)COM_GetProcAddress( ref.hInstance, GET_REF_API )) )
|
||||
if( !( GetRefAPI = (REFAPI)COM_GetProcAddress( ref.hInstance, GET_REF_API )))
|
||||
{
|
||||
COM_FreeLibrary( ref.hInstance );
|
||||
Con_Reportf( "%s: can't find GetRefAPI entry point in %s\n", __func__, name );
|
||||
ref.hInstance = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -495,19 +509,15 @@ static qboolean R_LoadProgs( const char *name )
|
||||
|
||||
if( GetRefAPI( REF_API_VERSION, &ref.dllFuncs, &gpEngfuncs, &refState ) != REF_API_VERSION )
|
||||
{
|
||||
COM_FreeLibrary( ref.hInstance );
|
||||
Con_Reportf( "%s: can't init renderer API: wrong version\n", __func__ );
|
||||
ref.hInstance = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
refState.developer = host_developer.value;
|
||||
|
||||
if( !ref.dllFuncs.R_Init( ) )
|
||||
if( !ref.dllFuncs.R_Init( ))
|
||||
{
|
||||
COM_FreeLibrary( ref.hInstance );
|
||||
Con_Reportf( "%s: can't init renderer!\n", __func__ ); //, ref.dllFuncs.R_GetInitError() );
|
||||
ref.hInstance = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -634,9 +644,6 @@ static void R_CollectRendererNames( void )
|
||||
#endif
|
||||
#if XASH_REF_SOFT_ENABLED
|
||||
"soft",
|
||||
#endif
|
||||
#if XASH_REF_NULL_ENABLED
|
||||
"null",
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -660,9 +667,6 @@ static void R_CollectRendererNames( void )
|
||||
#endif
|
||||
#if XASH_REF_SOFT_ENABLED
|
||||
"Software",
|
||||
#endif
|
||||
#if XASH_REF_NULL_ENABLED
|
||||
"Null Renderer",
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -674,7 +678,8 @@ static void R_CollectRendererNames( void )
|
||||
qboolean R_Init( void )
|
||||
{
|
||||
qboolean success = false;
|
||||
string requested;
|
||||
string requested_cmdline;
|
||||
string requested_cvar;
|
||||
|
||||
Cvar_RegisterVariable( &gl_vsync );
|
||||
Cvar_RegisterVariable( &r_showtextures );
|
||||
@@ -724,15 +729,16 @@ qboolean R_Init( void )
|
||||
// 1. Command line `-ref` argument.
|
||||
// 2. `ref_dll` cvar.
|
||||
// 3. Detected renderers in `DEFAULT_RENDERERS` order.
|
||||
requested[0] = 0;
|
||||
requested_cmdline[0] = 0;
|
||||
requested_cvar[0] = 0;
|
||||
|
||||
if( !success && Sys_GetParmFromCmdLine( "-ref", requested ))
|
||||
success = R_LoadRenderer( requested );
|
||||
if( Sys_GetParmFromCmdLine( "-ref", requested_cmdline ))
|
||||
success = R_LoadRenderer( requested_cmdline );
|
||||
|
||||
if( !success && COM_CheckString( r_refdll.string ))
|
||||
if( !success && COM_CheckString( r_refdll.string ) && Q_stricmp( requested_cmdline, r_refdll.string ))
|
||||
{
|
||||
Q_strncpy( requested, r_refdll.string, sizeof( requested ));
|
||||
success = R_LoadRenderer( requested );
|
||||
Q_strncpy( requested_cvar, r_refdll.string, sizeof( requested_cvar ));
|
||||
success = R_LoadRenderer( requested_cvar );
|
||||
}
|
||||
|
||||
if( !success )
|
||||
@@ -742,7 +748,10 @@ qboolean R_Init( void )
|
||||
for( i = 0; i < ref.numRenderers && !success; i++ )
|
||||
{
|
||||
// skip renderer that was requested but failed to load
|
||||
if( !Q_strcmp( requested, ref.shortNames[i] ))
|
||||
if( !Q_strcmp( requested_cmdline, ref.shortNames[i] ))
|
||||
continue;
|
||||
|
||||
if( !Q_strcmp( requested_cvar, ref.shortNames[i] ))
|
||||
continue;
|
||||
|
||||
success = R_LoadRenderer( ref.shortNames[i] );
|
||||
@@ -751,7 +760,7 @@ qboolean R_Init( void )
|
||||
|
||||
if( !success )
|
||||
{
|
||||
Host_Error( "Can't initialize any renderer. Check your video drivers!\n" );
|
||||
Sys_Error( "Can't initialize any renderer. Check your video drivers!\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -387,7 +387,7 @@ static void Cmd_Echo_f( void )
|
||||
int i;
|
||||
|
||||
for( i = 1; i < Cmd_Argc(); i++ )
|
||||
Con_Printf( "%s", Cmd_Argv( i ));
|
||||
Con_Printf( "%s ", Cmd_Argv( i ));
|
||||
Con_Printf( "\n" );
|
||||
}
|
||||
|
||||
|
||||
@@ -230,7 +230,7 @@ static const char *Cvar_ValidateString( convar_t *var, const char *value )
|
||||
if( !COM_CheckStringEmpty( szNew ) ) Q_strncpy( szNew, "empty", sizeof( szNew ));
|
||||
}
|
||||
|
||||
if( FBitSet( var->flags, FCVAR_NOEXTRAWHITEPACE ))
|
||||
if( FBitSet( var->flags, FCVAR_NOEXTRAWHITESPACE ))
|
||||
{
|
||||
char *szVal = szNew;
|
||||
int len = 0;
|
||||
|
||||
@@ -18,45 +18,6 @@ GNU General Public License for more details.
|
||||
|
||||
#include "cvardef.h"
|
||||
|
||||
#ifdef XASH_64BIT
|
||||
#define CVAR_SENTINEL 0xDEADBEEFDEADBEEF
|
||||
#else
|
||||
#define CVAR_SENTINEL 0xDEADBEEF
|
||||
#endif
|
||||
#define CVAR_CHECK_SENTINEL( cv ) ((uintptr_t)(cv)->next == CVAR_SENTINEL)
|
||||
|
||||
// NOTE: if this is changed, it must be changed in cvardef.h too
|
||||
typedef struct convar_s
|
||||
{
|
||||
// this part shared with cvar_t
|
||||
char *name;
|
||||
char *string;
|
||||
int flags;
|
||||
float value;
|
||||
struct convar_s *next;
|
||||
|
||||
// this part unique for convar_t
|
||||
char *desc; // variable descrition info
|
||||
char *def_string; // keep pointer to initial value
|
||||
} convar_t;
|
||||
|
||||
// cvar internal flags
|
||||
#define FCVAR_RENDERINFO (1<<16) // save to a seperate config called video.cfg
|
||||
#define FCVAR_READ_ONLY (1<<17) // cannot be set by user at all, and can't be requested by CvarGetPointer from game dlls
|
||||
#define FCVAR_EXTENDED (1<<18) // this is convar_t (sets on registration)
|
||||
#define FCVAR_ALLOCATED (1<<19) // this convar_t is fully dynamic allocated (include description)
|
||||
#define FCVAR_VIDRESTART (1<<20) // recreate the window is cvar with this flag was changed
|
||||
#define FCVAR_TEMPORARY (1<<21) // these cvars holds their values and can be unlink in any time
|
||||
#define FCVAR_MOVEVARS (1<<22) // this cvar is a part of movevars_t struct that shared between client and server
|
||||
#define FCVAR_USER_CREATED (1<<23) // created by a set command (dll's used)
|
||||
|
||||
#define CVAR_DEFINE( cv, cvname, cvstr, cvflags, cvdesc ) \
|
||||
convar_t cv = { (char*)cvname, (char*)cvstr, cvflags, 0.0f, (void *)CVAR_SENTINEL, (char*)cvdesc, NULL }
|
||||
|
||||
#define CVAR_DEFINE_AUTO( cv, cvstr, cvflags, cvdesc ) \
|
||||
CVAR_DEFINE( cv, #cv, cvstr, cvflags, cvdesc )
|
||||
|
||||
#ifndef REF_DLL
|
||||
cvar_t *Cvar_GetList( void );
|
||||
#define Cvar_FindVar( name ) Cvar_FindVarExt( name, 0 )
|
||||
convar_t *Cvar_FindVarExt( const char *var_name, int ignore_group );
|
||||
@@ -81,6 +42,5 @@ qboolean Cvar_CommandWithPrivilegeCheck( convar_t *v, qboolean isPrivileged );
|
||||
void Cvar_Init( void );
|
||||
void Cvar_PostFSInit( void );
|
||||
void Cvar_Unlink( int group );
|
||||
#endif // REF_DLL
|
||||
|
||||
#endif//CVAR_H
|
||||
|
||||
@@ -67,7 +67,7 @@ typedef struct dresource_s
|
||||
} dresource_t;
|
||||
#pragma pack( pop )
|
||||
|
||||
STATIC_ASSERT( sizeof( dresource_t ) == 136, "invalid dresource_t size, HPAKs won't be compatible (no custom logo in multiplayer!)" );
|
||||
STATIC_CHECK_SIZEOF( dresource_t, 136, 136 );
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -76,7 +76,7 @@ typedef struct
|
||||
int infotableofs;
|
||||
} hpak_header_t;
|
||||
|
||||
STATIC_ASSERT( sizeof( hpak_header_t ) == 12, "invalid hpak_header_t size" );
|
||||
STATIC_CHECK_SIZEOF( hpak_header_t, 12, 12 );
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -85,7 +85,7 @@ typedef struct
|
||||
int disksize;
|
||||
} hpak_lump_t;
|
||||
|
||||
STATIC_ASSERT( sizeof( hpak_lump_t ) == 144, "invalid hpak_lump_t size" );
|
||||
STATIC_CHECK_SIZEOF( hpak_lump_t, 144, 144 );
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
||||
@@ -1677,9 +1677,10 @@ static void Mod_SetupSubmodels( model_t *mod, dbspmodel_t *bmod )
|
||||
// mark models that have origin brushes
|
||||
if( !VectorIsNull( bm->origin ))
|
||||
SetBits( mod->flags, MODEL_HAS_ORIGIN );
|
||||
|
||||
#ifdef HACKS_RELATED_HLMODS
|
||||
// c2a1 doesn't have origin brush it's just placed at center of the level
|
||||
if( !Q_stricmp( name, "maps/c2a1.bsp" ) && ( i == 11 ))
|
||||
if( i == 11 && !Q_stricmp( name, "maps/c2a1.bsp" ))
|
||||
SetBits( mod->flags, MODEL_HAS_ORIGIN );
|
||||
#endif
|
||||
}
|
||||
@@ -1835,6 +1836,8 @@ static void Mod_LoadEntities( model_t *mod, dbspmodel_t *bmod )
|
||||
world.generator[0] = '\0';
|
||||
world.compiler[0] = '\0';
|
||||
world.message[0] = '\0';
|
||||
world.litwater_minlight = -1;
|
||||
world.litwater_scale = -1.0f;
|
||||
bmod->wadlist.count = 0;
|
||||
|
||||
// parse all the wads for loading textures in right ordering
|
||||
@@ -1893,6 +1896,15 @@ static void Mod_LoadEntities( model_t *mod, dbspmodel_t *bmod )
|
||||
Q_strncpy( world.compiler, token, sizeof( world.compiler ));
|
||||
else if( !Q_stricmp( keyname, "generator" ) || !Q_stricmp( keyname, "_generator" ))
|
||||
Q_strncpy( world.generator, token, sizeof( world.generator ));
|
||||
else if( !Q_stricmp( keyname, "_litwater" ))
|
||||
{
|
||||
if( Q_atoi( token ) != 0 )
|
||||
SetBits( world.flags, FWORLD_HAS_LITWATER );
|
||||
}
|
||||
else if( !Q_stricmp( keyname, "_litwater_minlight" ))
|
||||
world.litwater_minlight = Q_atoi( token );
|
||||
else if( !Q_stricmp( keyname, "_litwater_scale" ))
|
||||
world.litwater_scale = Q_atof( token );
|
||||
}
|
||||
return; // all done
|
||||
}
|
||||
|
||||
@@ -119,6 +119,10 @@ typedef struct world_static_s
|
||||
// Potentially Hearable Set
|
||||
byte *compressed_phs;
|
||||
size_t *phsofs;
|
||||
|
||||
// lightmapped water extra info
|
||||
float litwater_scale;
|
||||
int litwater_minlight;
|
||||
} world_static_t;
|
||||
|
||||
#ifndef REF_DLL
|
||||
|
||||
@@ -160,17 +160,6 @@ void MSG_InitMasks( void )
|
||||
ExtraMasks[maskBit] = (uint)BIT( maskBit ) - 1;
|
||||
}
|
||||
|
||||
void MSG_WriteOneBit( sizebuf_t *sb, int nValue )
|
||||
{
|
||||
if( !MSG_Overflow( sb, 1 ))
|
||||
{
|
||||
if( nValue ) sb->pData[sb->iCurBit>>3] |= BIT( sb->iCurBit & 7 );
|
||||
else sb->pData[sb->iCurBit>>3] &= ~BIT( sb->iCurBit & 7 );
|
||||
|
||||
sb->iCurBit++;
|
||||
}
|
||||
}
|
||||
|
||||
void MSG_WriteUBitLong( sizebuf_t *sb, uint curData, int numbits )
|
||||
{
|
||||
Assert( numbits >= 0 && numbits <= 32 );
|
||||
|
||||
@@ -173,7 +173,17 @@ void MSG_InitMasks( void ); // called once at startup engine
|
||||
void MSG_ExciseBits( sizebuf_t *sb, int startbit, int bitstoremove );
|
||||
|
||||
// Bit-write functions
|
||||
void MSG_WriteOneBit( sizebuf_t *sb, int nValue );
|
||||
static inline void MSG_WriteOneBit( sizebuf_t *sb, int nValue )
|
||||
{
|
||||
if( !MSG_Overflow( sb, 1 ))
|
||||
{
|
||||
if( nValue ) sb->pData[sb->iCurBit>>3] |= BIT( sb->iCurBit & 7 );
|
||||
else sb->pData[sb->iCurBit>>3] &= ~BIT( sb->iCurBit & 7 );
|
||||
|
||||
sb->iCurBit++;
|
||||
}
|
||||
}
|
||||
|
||||
NO_ASAN void MSG_WriteUBitLong( sizebuf_t *sb, uint curData, int numbits );
|
||||
void MSG_WriteSBitLong( sizebuf_t *sb, int data, int numbits );
|
||||
void MSG_WriteBitLong( sizebuf_t *sb, uint data, int numbits, qboolean bSigned );
|
||||
|
||||
@@ -25,8 +25,7 @@ typedef struct did3v2_header_s
|
||||
uint8_t flags;
|
||||
uint32_t length; // size of extended header, padding and frames
|
||||
} did3v2_header_t;
|
||||
STATIC_ASSERT( sizeof( did3v2_header_t ) == 10,
|
||||
"invalid did3v2_header_t size" );
|
||||
STATIC_CHECK_SIZEOF( did3v2_header_t, 10, 10 );
|
||||
|
||||
typedef struct did3v2_extended_header_s
|
||||
{
|
||||
@@ -34,8 +33,7 @@ typedef struct did3v2_extended_header_s
|
||||
uint8_t flags_length;
|
||||
uint8_t flags[1];
|
||||
} did3v2_extended_header_t;
|
||||
STATIC_ASSERT( sizeof( did3v2_extended_header_t ) == 6,
|
||||
"invalid did3v2_extended_header_t size" );
|
||||
STATIC_CHECK_SIZEOF( did3v2_extended_header_t, 6, 6 );
|
||||
|
||||
typedef struct did3v2_frame_s
|
||||
{
|
||||
@@ -43,8 +41,7 @@ typedef struct did3v2_frame_s
|
||||
uint32_t length;
|
||||
uint8_t flags[2];
|
||||
} did3v2_frame_t;
|
||||
STATIC_ASSERT( sizeof( did3v2_frame_t ) == 10,
|
||||
"invalid did3v2_frame_t size" );
|
||||
STATIC_CHECK_SIZEOF( did3v2_frame_t, 10, 10 );
|
||||
#pragma pack( pop )
|
||||
|
||||
typedef enum did3v2_header_flags_e
|
||||
|
||||
@@ -95,12 +95,7 @@ typedef struct customization_s
|
||||
#define FCUST_WIPEDATA ( 1<<1 )
|
||||
#define FCUST_IGNOREINIT ( 1<<2 )
|
||||
|
||||
#if !XASH_64BIT
|
||||
STATIC_ASSERT( sizeof( customization_t ) == 164, "invalid customization_t size, broken API" );
|
||||
STATIC_ASSERT( sizeof( resource_t ) == 136, "invalid resource_t size, broken API" );
|
||||
#else
|
||||
STATIC_ASSERT( sizeof( customization_t ) == 192, "invalid customization_t size, broken API" );
|
||||
STATIC_ASSERT( sizeof( resource_t ) == 144, "invalid resource_t size, broken API" );
|
||||
#endif
|
||||
STATIC_CHECK_SIZEOF( customization_t, 164, 192 );
|
||||
STATIC_CHECK_SIZEOF( resource_t, 136, 144 );
|
||||
|
||||
#endif // CUSTOM_H
|
||||
|
||||
@@ -1015,9 +1015,10 @@ qboolean R_Init_Video( const int type )
|
||||
{
|
||||
string safe;
|
||||
qboolean retval;
|
||||
|
||||
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
|
||||
SDL_DisplayMode displayMode;
|
||||
SDL_GetCurrentDisplayMode(0, &displayMode);
|
||||
SDL_GetCurrentDisplayMode( 0, &displayMode );
|
||||
refState.desktopBitsPixel = SDL_BITSPERPIXEL( displayMode.format );
|
||||
#else
|
||||
refState.desktopBitsPixel = 16;
|
||||
@@ -1095,7 +1096,7 @@ rserr_t R_ChangeDisplaySettings( int width, int height, window_mode_t window_mod
|
||||
|
||||
if( SDL_GetCurrentDisplayMode( 0, &displayMode ) < 0 )
|
||||
{
|
||||
Con_Printf( S_ERROR "SDL_GetCurrentDisplayMode: %s", SDL_GetError( ));
|
||||
Con_Printf( S_ERROR "SDL_GetCurrentDisplayMode: %s\n", SDL_GetError( ));
|
||||
return rserr_invalid_mode;
|
||||
}
|
||||
|
||||
@@ -1239,10 +1240,6 @@ void R_Free_Video( void )
|
||||
R_FreeVideoModes();
|
||||
|
||||
ref.dllFuncs.GL_ClearExtensions();
|
||||
|
||||
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
|
||||
SDL_VideoQuit();
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // XASH_DEDICATED
|
||||
|
||||
@@ -80,10 +80,11 @@ GNU General Public License for more details.
|
||||
#define MODEL_CLIENT BIT( 30 ) // client sprite
|
||||
|
||||
// goes into world.flags
|
||||
#define FWORLD_SKYSPHERE BIT( 0 )
|
||||
#define FWORLD_CUSTOM_SKYBOX BIT( 1 )
|
||||
#define FWORLD_WATERALPHA BIT( 2 )
|
||||
#define FWORLD_HAS_DELUXEMAP BIT( 3 )
|
||||
#define FWORLD_SKYSPHERE BIT( 0 )
|
||||
#define FWORLD_CUSTOM_SKYBOX BIT( 1 )
|
||||
#define FWORLD_WATERALPHA BIT( 2 )
|
||||
#define FWORLD_HAS_DELUXEMAP BIT( 3 )
|
||||
#define FWORLD_HAS_LITWATER BIT( 4 )
|
||||
|
||||
// special rendermode for screenfade modulate
|
||||
// (probably will be expanded at some point)
|
||||
|
||||
@@ -3064,7 +3064,7 @@ void SV_SetStringArrayMode( qboolean dynamic )
|
||||
#endif
|
||||
}
|
||||
|
||||
#if XASH_64BIT && !XASH_WIN32 && !XASH_APPLE && !XASH_NSWITCH && !XASH_ANDROID
|
||||
#if XASH_AMD64 && XASH_LINUX && !XASH_ANDROID
|
||||
#define USE_MMAP
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
@@ -72,7 +72,7 @@ typedef struct
|
||||
int32_t version; // current version 2
|
||||
} dsprite_t;
|
||||
|
||||
STATIC_ASSERT( sizeof( dsprite_t ) == 8, "invalid dsprite_t size" );
|
||||
STATIC_CHECK_SIZEOF( dsprite_t, 8, 8 );
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -86,7 +86,7 @@ typedef struct
|
||||
uint32_t synctype; // animation synctype, was synctype_t
|
||||
} dsprite_q1_t;
|
||||
|
||||
STATIC_ASSERT( sizeof( dsprite_q1_t ) == 36, "invalid dsprite_q1_t size" );
|
||||
STATIC_CHECK_SIZEOF( dsprite_q1_t, 36, 36 );
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -101,7 +101,7 @@ typedef struct
|
||||
uint32_t synctype; // animation synctype, was synctype_t
|
||||
} dsprite_hl_t;
|
||||
|
||||
STATIC_ASSERT( sizeof( dsprite_hl_t ) == 40, "invalid dsprite_hl_t size" );
|
||||
STATIC_CHECK_SIZEOF( dsprite_hl_t, 40, 40 );
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -110,27 +110,27 @@ typedef struct
|
||||
int32_t height;
|
||||
} dspriteframe_t;
|
||||
|
||||
STATIC_ASSERT( sizeof( dspriteframe_t ) == 16, "invalid dspriteframe_t size" );
|
||||
STATIC_CHECK_SIZEOF( dspriteframe_t, 16, 16 );
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int32_t numframes;
|
||||
} dspritegroup_t;
|
||||
|
||||
STATIC_ASSERT( sizeof( dspritegroup_t ) == 4, "invalid dspritegroup_t size" );
|
||||
STATIC_CHECK_SIZEOF( dspritegroup_t, 4, 4 );
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float interval;
|
||||
} dspriteinterval_t;
|
||||
|
||||
STATIC_ASSERT( sizeof( dspriteinterval_t ) == 4, "invalid dspriteinterval_t size" );
|
||||
STATIC_CHECK_SIZEOF( dspriteinterval_t, 4, 4 );
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t type; // was frametype_t
|
||||
} dframetype_t;
|
||||
|
||||
STATIC_ASSERT( sizeof( dframetype_t ) == 4, "invalid dframetype_t size" );
|
||||
STATIC_CHECK_SIZEOF( dframetype_t, 4, 4 );
|
||||
|
||||
#endif//SPRITE_H
|
||||
|
||||
@@ -110,6 +110,8 @@ def configure(conf):
|
||||
conf.env.append_unique('CFLAGS', '-fsanitize=fuzzer-no-link')
|
||||
conf.env.append_unique('LINKFLAGS', '-fsanitize=fuzzer')
|
||||
|
||||
conf.define('ENGINE_DLL', 1)
|
||||
|
||||
conf.define_cond('XASH_ENGINE_TESTS', conf.env.ENGINE_TESTS)
|
||||
conf.define_cond('XASH_STATIC_LIBS', conf.env.STATIC_LINKING)
|
||||
conf.define_cond('XASH_CUSTOM_SWAP', conf.options.CUSTOM_SWAP)
|
||||
|
||||
@@ -31,7 +31,7 @@ GNU General Public License for more details.
|
||||
#include "enginefeatures.h"
|
||||
#include "com_strings.h"
|
||||
#include "pm_movevars.h"
|
||||
#include "common/cvar.h"
|
||||
#include "cvardef.h"
|
||||
#include "gl_export.h"
|
||||
#include "wadfile.h"
|
||||
#include "common/mod_local.h"
|
||||
@@ -494,11 +494,10 @@ void R_ClearSkyBox( void );
|
||||
void R_DrawSkyBox( void );
|
||||
void R_DrawClouds( void );
|
||||
void R_UnloadSkybox( void );
|
||||
void EmitWaterPolys( msurface_t *warp, qboolean reverse );
|
||||
void R_InitRipples( void );
|
||||
void R_ResetRipples( void );
|
||||
void R_AnimateRipples( void );
|
||||
void R_UploadRipples( texture_t *image );
|
||||
float R_UploadRipples( texture_t *image );
|
||||
|
||||
//#include "vid_common.h"
|
||||
|
||||
@@ -749,6 +748,9 @@ extern convar_t gl_test; // cvar to testify new effects
|
||||
extern convar_t gl_msaa;
|
||||
extern convar_t gl_stencilbits;
|
||||
extern convar_t gl_overbright;
|
||||
extern convar_t gl_litwater_force;
|
||||
extern convar_t gl_litwater_minlight;
|
||||
extern convar_t gl_litwater_scale;
|
||||
|
||||
extern convar_t r_lighting_extended;
|
||||
extern convar_t r_lighting_ambient;
|
||||
|
||||
@@ -20,6 +20,9 @@ CVAR_DEFINE_AUTO( gl_test, "0", 0, "engine developer cvar for quick testing new
|
||||
CVAR_DEFINE_AUTO( gl_msaa, "1", FCVAR_GLCONFIG, "enable or disable multisample anti-aliasing" );
|
||||
CVAR_DEFINE_AUTO( gl_stencilbits, "8", FCVAR_GLCONFIG|FCVAR_READ_ONLY, "pixelformat stencil bits (0 - auto)" );
|
||||
CVAR_DEFINE_AUTO( gl_overbright, "1", FCVAR_GLCONFIG, "overbrights" );
|
||||
CVAR_DEFINE_AUTO( gl_litwater_force, "0", FCVAR_GLCONFIG, "force enable lightmapped water, even if support not declared in the map" );
|
||||
CVAR_DEFINE_AUTO( gl_litwater_minlight, "192", FCVAR_GLCONFIG, "minimal light water receives, helps avoid too dark lightmapped water" );
|
||||
CVAR_DEFINE_AUTO( gl_litwater_scale, "1.5", FCVAR_GLCONFIG, "lightmapped water scale factor" );
|
||||
CVAR_DEFINE_AUTO( r_lighting_extended, "1", FCVAR_GLCONFIG, "allow to get lighting from world and bmodels" );
|
||||
CVAR_DEFINE_AUTO( r_lighting_ambient, "0.3", FCVAR_GLCONFIG, "map ambient lighting scale" );
|
||||
CVAR_DEFINE_AUTO( r_detailtextures, "1", FCVAR_ARCHIVE, "enable detail textures support" );
|
||||
@@ -1207,6 +1210,9 @@ static void GL_InitCommands( void )
|
||||
gEngfuncs.Cvar_RegisterVariable( &gl_stencilbits );
|
||||
gEngfuncs.Cvar_RegisterVariable( &gl_round_down );
|
||||
gEngfuncs.Cvar_RegisterVariable( &gl_overbright );
|
||||
gEngfuncs.Cvar_RegisterVariable( &gl_litwater_force );
|
||||
gEngfuncs.Cvar_RegisterVariable( &gl_litwater_minlight );
|
||||
gEngfuncs.Cvar_RegisterVariable( &gl_litwater_scale );
|
||||
|
||||
// these cvar not used by engine but some mods requires this
|
||||
gEngfuncs.Cvar_RegisterVariable( &gl_polyoffset );
|
||||
|
||||
@@ -1020,13 +1020,21 @@ static void R_CheckGamma( void )
|
||||
ClearBits( gl_overbright.flags, FCVAR_CHANGED );
|
||||
}
|
||||
|
||||
if( gl_overbright.value && ( FBitSet( r_vbo.flags, FCVAR_CHANGED ) || FBitSet( r_vbo_overbrightmode.flags, FCVAR_CHANGED ) ) )
|
||||
if( gl_overbright.value && FBitSet( r_vbo.flags|r_vbo_overbrightmode.flags, FCVAR_CHANGED ))
|
||||
{
|
||||
rebuild = true;
|
||||
ClearBits( r_vbo.flags, FCVAR_CHANGED );
|
||||
ClearBits( r_vbo_overbrightmode.flags, FCVAR_CHANGED );
|
||||
}
|
||||
|
||||
// we only recalculate lightmap on the fly if map hasn't declared support for lightmapped water
|
||||
if( !FBitSet( tr.world->flags, FWORLD_HAS_LITWATER ) && FBitSet( gl_litwater_scale.flags|gl_litwater_minlight.flags, FCVAR_CHANGED ))
|
||||
{
|
||||
rebuild = true;
|
||||
ClearBits( gl_litwater_scale.flags, FCVAR_CHANGED );
|
||||
ClearBits( gl_litwater_minlight.flags, FCVAR_CHANGED );
|
||||
}
|
||||
|
||||
if( rebuild )
|
||||
R_GammaChanged( false );
|
||||
}
|
||||
|
||||
@@ -17,6 +17,14 @@ GNU General Public License for more details.
|
||||
#include "xash3d_mathlib.h"
|
||||
#include "mod_local.h"
|
||||
|
||||
// speed up sin calculations
|
||||
static const float r_turbsin[] =
|
||||
{
|
||||
#include "warpsin.h"
|
||||
};
|
||||
|
||||
static const float TURBSCALE = 256.0f / ( M_PI2 );
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int allocated[BLOCK_SIZE_MAX];
|
||||
@@ -42,6 +50,43 @@ static gllightmapstate_t gl_lms;
|
||||
static void LM_UploadBlock( qboolean dynamic );
|
||||
static qboolean R_AddSurfToVBO( msurface_t *surf, qboolean buildlightmaps );
|
||||
static void R_DrawVBO( qboolean drawlightmaps, qboolean drawtextures );
|
||||
static void R_RenderLightmap( msurface_t *fa );
|
||||
|
||||
static qboolean Mod_HaveLightmappedWater( void )
|
||||
{
|
||||
// if this flag set, it's level designer's job to ensure water has been properly lit
|
||||
if( FBitSet( tr.world->flags, FWORLD_HAS_LITWATER ))
|
||||
return true;
|
||||
|
||||
// otherwise, check user preference, as some maps have lightmapped water
|
||||
return gl_litwater_force.value ? true : false;
|
||||
}
|
||||
|
||||
static int Mod_LightmappedWaterMinlight( void )
|
||||
{
|
||||
if( FBitSet( tr.world->flags, FWORLD_HAS_LITWATER ))
|
||||
{
|
||||
if( tr.world->litwater_minlight >= 0 )
|
||||
return tr.world->litwater_minlight;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Q_max( (int)gl_litwater_minlight.value, 0 );
|
||||
}
|
||||
|
||||
static float Mod_LightmappedWaterScale( void )
|
||||
{
|
||||
if( FBitSet( tr.world->flags, FWORLD_HAS_LITWATER ))
|
||||
{
|
||||
if( tr.world->litwater_scale >= 0.0f )
|
||||
return tr.world->litwater_scale;
|
||||
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
return gl_litwater_scale.value;
|
||||
}
|
||||
|
||||
byte *Mod_GetCurrentVis( void )
|
||||
{
|
||||
@@ -206,12 +251,29 @@ static void SubdividePolygon_r( model_t *loadmodel, msurface_t *warpface, int nu
|
||||
{
|
||||
VectorCopy( verts, poly->verts[i] );
|
||||
R_TextureCoord( verts, warpface, &poly->verts[i][3] );
|
||||
// lightmap texcoords for subdivided surfaces will be calculated later
|
||||
}
|
||||
}
|
||||
|
||||
// for speed reasons
|
||||
if( !FBitSet( warpface->flags, SURF_DRAWTURB ))
|
||||
static void GL_BuildLightmapWater( model_t *mod, msurface_t *fa )
|
||||
{
|
||||
float sample_size;
|
||||
glpoly2_t *poly;
|
||||
|
||||
if( !mod || !fa->texinfo || !fa->texinfo->texture )
|
||||
return; // bad polygon?
|
||||
|
||||
sample_size = gEngfuncs.Mod_SampleSizeForFace( fa );
|
||||
|
||||
for( poly = fa->polys; poly; poly = poly->next )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0; i < poly->numverts; i++ )
|
||||
{
|
||||
// lightmap texture coordinates
|
||||
R_LightmapCoord( verts, warpface, sample_size, &poly->verts[i][5] );
|
||||
vec3_t vec;
|
||||
VectorCopy( poly->verts[i], vec );
|
||||
R_LightmapCoord( vec, fa, sample_size, &poly->verts[i][5] );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -285,7 +347,8 @@ void GL_SubdivideSurface( model_t *loadmodel, msurface_t *fa )
|
||||
for( i = 0; i < fa->numedges; i++ )
|
||||
R_GetEdgePosition( loadmodel, fa, i, verts[i] );
|
||||
|
||||
SetBits( fa->flags, SURF_DRAWTURB_QUADS ); // predict state
|
||||
if( glConfig.context == CONTEXT_TYPE_GL )
|
||||
SetBits( fa->flags, SURF_DRAWTURB_QUADS ); // predict state
|
||||
|
||||
// do subdivide
|
||||
SubdividePolygon_r( loadmodel, fa, fa->numedges, verts[0] );
|
||||
@@ -712,6 +775,8 @@ static void R_BuildLightMap( msurface_t *surf, byte *dest, int stride, qboolean
|
||||
mextrasurf_t *info = surf->info;
|
||||
color24 *lm;
|
||||
int lightscale;
|
||||
const int litwater_minlight = Mod_LightmappedWaterMinlight();
|
||||
const float litwater_scale = Mod_LightmappedWaterScale();
|
||||
|
||||
sample_size = gEngfuncs.Mod_SampleSizeForFace( surf );
|
||||
smax = ( info->lightextents[0] / sample_size ) + 1;
|
||||
@@ -755,6 +820,15 @@ static void R_BuildLightMap( msurface_t *surf, byte *dest, int stride, qboolean
|
||||
{
|
||||
int t = bl[i] * lightscale >> 14;
|
||||
|
||||
// amp up water lightmap to avoid too dark water
|
||||
// when the it wasn't properly lit by the level designer
|
||||
if( FBitSet( surf->flags, SURF_DRAWTURB ))
|
||||
{
|
||||
float ft = t * litwater_scale;
|
||||
|
||||
t = Q_max( litwater_minlight, Q_rint( ft ));
|
||||
}
|
||||
|
||||
if( t > 1023 )
|
||||
t = 1023;
|
||||
|
||||
@@ -844,6 +918,137 @@ void DrawGLPoly( glpoly2_t *p, float xScale, float yScale )
|
||||
GL_SetupFogColorForSurfaces();
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
EmitWaterPolys
|
||||
|
||||
Does a water warp on the pre-fragmented glpoly_t chain
|
||||
=============
|
||||
*/
|
||||
static void EmitWaterPolys( msurface_t *warp, qboolean reverse, float ripplescale )
|
||||
{
|
||||
const qboolean useQuads = FBitSet( warp->flags, SURF_DRAWTURB_QUADS );
|
||||
const int vertexstep = reverse ? -VERTEXSIZE : VERTEXSIZE;
|
||||
glpoly2_t *p;
|
||||
float waveHeight = RI.currententity->curstate.scale;
|
||||
|
||||
if( !warp->polys ) return;
|
||||
|
||||
// set the current waveheight
|
||||
if( warp->polys->verts[0][2] >= RI.vieworg[2] )
|
||||
waveHeight = -waveHeight;
|
||||
|
||||
// reset fog color for nonlightmapped water
|
||||
// TODO: don't do when water is lightmapped
|
||||
GL_ResetFogColor();
|
||||
|
||||
if( useQuads )
|
||||
pglBegin( GL_QUADS );
|
||||
|
||||
for( p = warp->polys; p; p = p->next )
|
||||
{
|
||||
float *v = p->verts[0];
|
||||
int i;
|
||||
|
||||
if( reverse )
|
||||
v += ( p->numverts - 1 ) * VERTEXSIZE;
|
||||
|
||||
if( !useQuads )
|
||||
pglBegin( GL_POLYGON );
|
||||
|
||||
for( i = 0; i < p->numverts; i++, v += vertexstep )
|
||||
{
|
||||
float s, t, os = v[3], ot = v[4];
|
||||
|
||||
if( !r_ripple.value )
|
||||
{
|
||||
s = os + r_turbsin[(int)((ot * 0.125f + gp_cl->time) * TURBSCALE) & 255];
|
||||
t = ot + r_turbsin[(int)((os * 0.125f + gp_cl->time) * TURBSCALE) & 255];
|
||||
}
|
||||
else
|
||||
{
|
||||
s = os / ripplescale;
|
||||
t = ot / ripplescale;
|
||||
}
|
||||
|
||||
s *= ( 1.0f / SUBDIVIDE_SIZE );
|
||||
t *= ( 1.0f / SUBDIVIDE_SIZE );
|
||||
|
||||
pglTexCoord2f( s, t );
|
||||
|
||||
if( waveHeight )
|
||||
{
|
||||
float nv = r_turbsin[(int)(gp_cl->time * 160.0f + v[1] + v[0]) & 255] + 8.0f;
|
||||
nv = (r_turbsin[(int)(v[0] * 5.0f + gp_cl->time * 171.0f - v[1]) & 255] + 8.0f ) * 0.8f + nv;
|
||||
nv = nv * waveHeight + v[2];
|
||||
|
||||
pglVertex3f( v[0], v[1], nv );
|
||||
}
|
||||
else pglVertex3fv( v );
|
||||
}
|
||||
|
||||
if( !useQuads )
|
||||
pglEnd();
|
||||
}
|
||||
|
||||
if( useQuads )
|
||||
pglEnd();
|
||||
|
||||
GL_SetupFogColorForSurfaces();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
EmitWaterLightPolys
|
||||
|
||||
Render water lightmaps
|
||||
================
|
||||
*/
|
||||
static void EmitWaterLightPolys( msurface_t *warp, float soffset, float toffset, qboolean dynamic )
|
||||
{
|
||||
const qboolean useQuads = FBitSet( warp->flags, SURF_DRAWTURB_QUADS );
|
||||
glpoly2_t *p;
|
||||
float waveHeight = RI.currententity->curstate.scale;
|
||||
|
||||
// set the current waveheight
|
||||
if( warp->polys->verts[0][2] >= RI.vieworg[2] )
|
||||
waveHeight = -waveHeight;
|
||||
|
||||
if( useQuads )
|
||||
pglBegin( GL_QUADS );
|
||||
|
||||
for( p = warp->polys; p; p = p->next )
|
||||
{
|
||||
float *v = p->verts[0];
|
||||
int i;
|
||||
|
||||
if( !useQuads )
|
||||
pglBegin( GL_POLYGON );
|
||||
|
||||
for( i = 0; i < p->numverts; i++, v += VERTEXSIZE )
|
||||
{
|
||||
if( !dynamic ) pglTexCoord2f( v[5], v[6] );
|
||||
else pglTexCoord2f( v[5] - soffset, v[6] - toffset );
|
||||
|
||||
if( waveHeight )
|
||||
{
|
||||
float nv = r_turbsin[(int)(gp_cl->time * 160.0f + v[1] + v[0]) & 255] + 8.0f;
|
||||
nv = (r_turbsin[(int)(v[0] * 5.0f + gp_cl->time * 171.0f - v[1]) & 255] + 8.0f ) * 0.8f + nv;
|
||||
nv = nv * waveHeight + v[2];
|
||||
|
||||
pglVertex3f( v[0], v[1], nv );
|
||||
}
|
||||
else pglVertex3fv( v );
|
||||
}
|
||||
|
||||
if( !useQuads )
|
||||
pglEnd ();
|
||||
}
|
||||
|
||||
if( useQuads )
|
||||
pglEnd();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
DrawGLPolyChain
|
||||
@@ -851,12 +1056,15 @@ DrawGLPolyChain
|
||||
Render lightmaps
|
||||
================
|
||||
*/
|
||||
static void DrawGLPolyChain( glpoly2_t *p, float soffset, float toffset )
|
||||
static void DrawGLPolyChain( glpoly2_t *p, float soffset, float toffset, msurface_t *surf )
|
||||
{
|
||||
qboolean dynamic = true;
|
||||
qboolean dynamic = soffset != 0.0f || toffset != 0.0f;
|
||||
|
||||
if( soffset == 0.0f && toffset == 0.0f )
|
||||
dynamic = false;
|
||||
if( FBitSet( surf->flags, SURF_DRAWTURB ))
|
||||
{
|
||||
EmitWaterLightPolys( surf, soffset, toffset, dynamic );
|
||||
return;
|
||||
}
|
||||
|
||||
for( ; p != NULL; p = p->chain )
|
||||
{
|
||||
@@ -890,6 +1098,8 @@ static qboolean R_HasLightmap( void )
|
||||
switch( RI.currententity->curstate.rendermode )
|
||||
{
|
||||
case kRenderTransTexture:
|
||||
return FBitSet( RI.currentmodel->flags, MODEL_LIQUID ) ? true : false;
|
||||
|
||||
case kRenderTransColor:
|
||||
case kRenderTransAdd:
|
||||
case kRenderGlow:
|
||||
@@ -919,21 +1129,29 @@ static void R_BlendLightmaps( void )
|
||||
pglEnable( GL_BLEND );
|
||||
else pglDisable( GL_BLEND );
|
||||
|
||||
// lightmapped solid surfaces
|
||||
pglDepthMask( GL_FALSE );
|
||||
pglDepthFunc( GL_EQUAL );
|
||||
|
||||
pglDisable( GL_ALPHA_TEST );
|
||||
if( gl_overbright.value )
|
||||
|
||||
if( RI.currententity->curstate.rendermode == kRenderTransTexture )
|
||||
{
|
||||
pglBlendFunc( GL_DST_COLOR, GL_SRC_COLOR );
|
||||
if(!( r_vbo.value && !r_vbo_overbrightmode.value ))
|
||||
pglColor4f( 128.0f / 192.0f, 128.0f / 192.0f, 128.0f / 192.0f, 1.0f );
|
||||
pglBlendFunc( GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA );
|
||||
}
|
||||
else
|
||||
{
|
||||
pglBlendFunc( GL_ZERO, GL_SRC_COLOR );
|
||||
// lightmapped solid surfaces
|
||||
pglDepthMask( GL_FALSE );
|
||||
pglDepthFunc( GL_EQUAL );
|
||||
if( gl_overbright.value )
|
||||
{
|
||||
pglBlendFunc( GL_DST_COLOR, GL_SRC_COLOR );
|
||||
if(!( r_vbo.value && !r_vbo_overbrightmode.value ))
|
||||
pglColor4f( 128.0f / 192.0f, 128.0f / 192.0f, 128.0f / 192.0f, 1.0f );
|
||||
}
|
||||
else
|
||||
{
|
||||
pglBlendFunc( GL_ZERO, GL_SRC_COLOR );
|
||||
}
|
||||
}
|
||||
|
||||
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
|
||||
|
||||
// render static lightmaps first
|
||||
@@ -945,7 +1163,7 @@ static void R_BlendLightmaps( void )
|
||||
|
||||
for( surf = gl_lms.lightmap_surfaces[i]; surf != NULL; surf = surf->info->lightmapchain )
|
||||
{
|
||||
if( surf->polys ) DrawGLPolyChain( surf->polys, 0.0f, 0.0f );
|
||||
DrawGLPolyChain( surf->polys, 0.0f, 0.0f, surf );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -986,12 +1204,10 @@ static void R_BlendLightmaps( void )
|
||||
// draw all surfaces that use this lightmap
|
||||
for( drawsurf = newsurf; drawsurf != surf; drawsurf = drawsurf->info->lightmapchain )
|
||||
{
|
||||
if( drawsurf->polys )
|
||||
{
|
||||
DrawGLPolyChain( drawsurf->polys,
|
||||
DrawGLPolyChain( drawsurf->polys,
|
||||
( drawsurf->light_s - drawsurf->info->dlight_s ) * ( 1.0f / (float)BLOCK_SIZE ),
|
||||
( drawsurf->light_t - drawsurf->info->dlight_t ) * ( 1.0f / (float)BLOCK_SIZE ));
|
||||
}
|
||||
( drawsurf->light_t - drawsurf->info->dlight_t ) * ( 1.0f / (float)BLOCK_SIZE ),
|
||||
drawsurf );
|
||||
}
|
||||
|
||||
newsurf = drawsurf;
|
||||
@@ -1015,12 +1231,10 @@ static void R_BlendLightmaps( void )
|
||||
|
||||
for( surf = newsurf; surf != NULL; surf = surf->info->lightmapchain )
|
||||
{
|
||||
if( surf->polys )
|
||||
{
|
||||
DrawGLPolyChain( surf->polys,
|
||||
DrawGLPolyChain( surf->polys,
|
||||
( surf->light_s - surf->info->dlight_s ) * ( 1.0f / (float)BLOCK_SIZE ),
|
||||
( surf->light_t - surf->info->dlight_t ) * ( 1.0f / (float)BLOCK_SIZE ));
|
||||
}
|
||||
( surf->light_t - surf->info->dlight_t ) * ( 1.0f / (float)BLOCK_SIZE ),
|
||||
surf );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1142,9 +1356,7 @@ R_RenderBrushPoly
|
||||
*/
|
||||
static void R_RenderBrushPoly( msurface_t *fa, int cull_type )
|
||||
{
|
||||
qboolean is_dynamic = false;
|
||||
int maps;
|
||||
texture_t *t;
|
||||
texture_t *t;
|
||||
|
||||
r_stats.c_world_polys++;
|
||||
|
||||
@@ -1155,10 +1367,15 @@ static void R_RenderBrushPoly( msurface_t *fa, int cull_type )
|
||||
|
||||
if( FBitSet( fa->flags, SURF_DRAWTURB ))
|
||||
{
|
||||
R_UploadRipples( t );
|
||||
float ripplescale = R_UploadRipples( t );
|
||||
|
||||
// warp texture
|
||||
EmitWaterPolys( fa, (cull_type == CULL_BACKSIDE), ripplescale );
|
||||
|
||||
// add lightmaps if requested
|
||||
if( Mod_HaveLightmappedWater( ))
|
||||
R_RenderLightmap( fa );
|
||||
|
||||
// warp texture, no lightmaps
|
||||
EmitWaterPolys( fa, (cull_type == CULL_BACKSIDE));
|
||||
return;
|
||||
}
|
||||
else GL_Bind( XASH_TEXTURE0, t->gl_texturenum );
|
||||
@@ -1213,14 +1430,25 @@ static void R_RenderBrushPoly( msurface_t *fa, int cull_type )
|
||||
DrawSurfaceDecals( fa, true, (cull_type == CULL_BACKSIDE));
|
||||
}
|
||||
|
||||
if( FBitSet( fa->flags, SURF_DRAWTILED ))
|
||||
return; // no lightmaps anyway
|
||||
R_RenderLightmap( fa );
|
||||
}
|
||||
|
||||
static void R_RenderLightmap( msurface_t *fa )
|
||||
{
|
||||
qboolean is_dynamic;
|
||||
int maps;
|
||||
|
||||
if( !fa->polys || FBitSet( fa->flags, SURF_DRAWTILED ))
|
||||
return;
|
||||
|
||||
// check for lightmap modification
|
||||
for( maps = 0; maps < MAXLIGHTMAPS && fa->styles[maps] != 255; maps++ )
|
||||
{
|
||||
if( tr.lightstylevalue[fa->styles[maps]] != fa->cached_light[maps] )
|
||||
goto dynamic;
|
||||
{
|
||||
is_dynamic = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// dynamic this frame or dynamic previously
|
||||
@@ -1422,6 +1650,8 @@ void R_DrawWaterSurfaces( void )
|
||||
|
||||
for( i = 0; i < WORLDMODEL->numtextures; i++ )
|
||||
{
|
||||
float ripplescale;
|
||||
|
||||
t = WORLDMODEL->textures[i];
|
||||
if( !t ) continue;
|
||||
|
||||
@@ -1432,14 +1662,22 @@ void R_DrawWaterSurfaces( void )
|
||||
continue;
|
||||
|
||||
// set modulate mode explicitly
|
||||
R_UploadRipples( t );
|
||||
ripplescale = R_UploadRipples( t );
|
||||
|
||||
for( ; s; s = s->texturechain )
|
||||
EmitWaterPolys( s, false );
|
||||
{
|
||||
EmitWaterPolys( s, false, ripplescale );
|
||||
|
||||
if( Mod_HaveLightmappedWater( ))
|
||||
R_RenderLightmap( s );
|
||||
}
|
||||
|
||||
t->texturechain = NULL;
|
||||
}
|
||||
|
||||
GL_ResetFogColor();
|
||||
R_BlendLightmaps();
|
||||
|
||||
pglDisable( GL_BLEND );
|
||||
pglDepthMask( GL_TRUE );
|
||||
pglDisable( GL_ALPHA_TEST );
|
||||
@@ -1634,8 +1872,16 @@ void R_DrawBrushModel( cl_entity_t *e )
|
||||
|
||||
if( cull_type == CULL_BACKSIDE )
|
||||
{
|
||||
if( !FBitSet( psurf->flags, SURF_DRAWTURB ) && !( psurf->pdecals && e->curstate.rendermode == kRenderTransTexture ))
|
||||
continue;
|
||||
if( FBitSet( psurf->flags, SURF_DRAWTURB ))
|
||||
{
|
||||
if( Mod_HaveLightmappedWater( ))
|
||||
continue; // we don't want back faces when drawing lightmaps to avoid Z fighting
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !( psurf->pdecals && e->curstate.rendermode == kRenderTransTexture ))
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if( num_sorted < gpGlobals->max_surfaces )
|
||||
@@ -1663,7 +1909,7 @@ void R_DrawBrushModel( cl_entity_t *e )
|
||||
GL_ResetFogColor();
|
||||
R_BlendLightmaps();
|
||||
R_RenderFullbrights();
|
||||
R_RenderDetails( allow_vbo? 2: 3 );
|
||||
R_RenderDetails( allow_vbo ? 2 : 3 );
|
||||
|
||||
// restore fog here
|
||||
if( e->curstate.rendermode == kRenderTransAdd )
|
||||
@@ -2282,14 +2528,13 @@ static texture_t *R_SetupVBOTexture( texture_t *tex, int number )
|
||||
}
|
||||
else R_DisableDetail();
|
||||
|
||||
GL_Bind( mtst.tmu_gl, r_lightmap->value ?tr.whiteTexture:tex->gl_texturenum );
|
||||
if(number)
|
||||
GL_Bind( mtst.tmu_gl, r_lightmap->value ? tr.whiteTexture : tex->gl_texturenum );
|
||||
if( number )
|
||||
vboarray.itexture = number;
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
||||
|
||||
static void R_SetupVBOArrayStatic( vboarray_t *vbo, qboolean drawlightmap, qboolean drawtextures )
|
||||
{
|
||||
if( vboarray.astate != VBO_ARRAY_STATIC )
|
||||
@@ -2333,11 +2578,8 @@ static void R_SetupVBOArrayStatic( vboarray_t *vbo, qboolean drawlightmap, qbool
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void R_SetupVBOArrayDlight( vboarray_t *vbo, texture_t *texture )
|
||||
{
|
||||
|
||||
if( vboarray.astate != VBO_ARRAY_DLIGHT )
|
||||
{
|
||||
if( vboarray.astate == VBO_ARRAY_DECAL_DLIGHT )
|
||||
@@ -2401,7 +2643,6 @@ static void R_SetupVBOArrayDecalDlight( int decalcount )
|
||||
vboarray.lstate = VBO_LIGHTMAP_DYNAMIC;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===================
|
||||
R_AdditionalPasses
|
||||
@@ -2469,11 +2710,9 @@ static void R_AdditionalPasses( vboarray_t *vbo, int indexlen, void *indexarray,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define MINIMIZE_UPLOAD
|
||||
#define DISCARD_DLIGHTS
|
||||
|
||||
|
||||
static void R_DrawDlightedDecals( vboarray_t *vbo, msurface_t *newsurf, msurface_t *surf, int decalcount, texture_t *texture )
|
||||
{
|
||||
msurface_t *decalsurf;
|
||||
@@ -3871,9 +4110,8 @@ void GL_BuildLightmaps( void )
|
||||
GL_CreateSurfaceLightmap( m->surfaces + j, m );
|
||||
|
||||
if( m->surfaces[j].flags & SURF_DRAWTURB )
|
||||
continue;
|
||||
|
||||
GL_BuildPolygonFromSurface( m, m->surfaces + j );
|
||||
GL_BuildLightmapWater( m, m->surfaces + j );
|
||||
else GL_BuildPolygonFromSurface( m, m->surfaces + j );
|
||||
}
|
||||
|
||||
// clearing visframe
|
||||
|
||||
116
ref/gl/gl_warp.c
116
ref/gl/gl_warp.c
@@ -19,7 +19,6 @@ GNU General Public License for more details.
|
||||
|
||||
#define SKYCLOUDS_QUALITY 12
|
||||
#define MAX_CLIP_VERTS 128 // skybox clip vertices
|
||||
#define TURBSCALE ( 256.0f / ( M_PI2 ))
|
||||
|
||||
static const int r_skyTexOrder[SKYBOX_MAX_SIDES] = { 0, 2, 1, 3, 4, 5 };
|
||||
|
||||
@@ -55,12 +54,6 @@ static const int vec_to_st[SKYBOX_MAX_SIDES][3] =
|
||||
{ -2, 1, -3 }
|
||||
};
|
||||
|
||||
// speed up sin calculations
|
||||
static float r_turbsin[] =
|
||||
{
|
||||
#include "warpsin.h"
|
||||
};
|
||||
|
||||
#define RIPPLES_CACHEWIDTH_BITS 7
|
||||
#define RIPPLES_CACHEWIDTH ( 1 << RIPPLES_CACHEWIDTH_BITS )
|
||||
#define RIPPLES_CACHEWIDTH_MASK (( RIPPLES_CACHEWIDTH ) - 1 )
|
||||
@@ -81,10 +74,8 @@ static struct
|
||||
uint32_t texture[RIPPLES_TEXSIZE];
|
||||
int gl_texturenum;
|
||||
int rippletexturenum;
|
||||
float texturescale; // not all textures are 128x128, scale the texcoords down
|
||||
} g_ripple;
|
||||
|
||||
|
||||
static void DrawSkyPolygon( int nump, vec3_t vecs )
|
||||
{
|
||||
int i, j, axis;
|
||||
@@ -558,89 +549,6 @@ void R_DrawClouds( void )
|
||||
pglFogf( GL_FOG_DENSITY, RI.fogDensity );
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
EmitWaterPolys
|
||||
|
||||
Does a water warp on the pre-fragmented glpoly_t chain
|
||||
=============
|
||||
*/
|
||||
void EmitWaterPolys( msurface_t *warp, qboolean reverse )
|
||||
{
|
||||
float *v, nv, waveHeight;
|
||||
float s, t, os, ot;
|
||||
glpoly2_t *p;
|
||||
int i;
|
||||
|
||||
const qboolean useQuads = FBitSet( warp->flags, SURF_DRAWTURB_QUADS ) && glConfig.context == CONTEXT_TYPE_GL;
|
||||
|
||||
if( !warp->polys ) return;
|
||||
|
||||
// set the current waveheight
|
||||
if( warp->polys->verts[0][2] >= RI.vieworg[2] )
|
||||
waveHeight = -RI.currententity->curstate.scale;
|
||||
else waveHeight = RI.currententity->curstate.scale;
|
||||
|
||||
// reset fog color for nonlightmapped water
|
||||
GL_ResetFogColor();
|
||||
|
||||
if( useQuads )
|
||||
pglBegin( GL_QUADS );
|
||||
|
||||
for( p = warp->polys; p; p = p->next )
|
||||
{
|
||||
if( reverse )
|
||||
v = p->verts[0] + ( p->numverts - 1 ) * VERTEXSIZE;
|
||||
else v = p->verts[0];
|
||||
|
||||
if( !useQuads )
|
||||
pglBegin( GL_POLYGON );
|
||||
|
||||
for( i = 0; i < p->numverts; i++ )
|
||||
{
|
||||
if( waveHeight )
|
||||
{
|
||||
nv = r_turbsin[(int)(gp_cl->time * 160.0f + v[1] + v[0]) & 255] + 8.0f;
|
||||
nv = (r_turbsin[(int)(v[0] * 5.0f + gp_cl->time * 171.0f - v[1]) & 255] + 8.0f ) * 0.8f + nv;
|
||||
nv = nv * waveHeight + v[2];
|
||||
}
|
||||
else nv = v[2];
|
||||
|
||||
os = v[3];
|
||||
ot = v[4];
|
||||
|
||||
if( !r_ripple.value )
|
||||
{
|
||||
s = os + r_turbsin[(int)((ot * 0.125f + gp_cl->time) * TURBSCALE) & 255];
|
||||
t = ot + r_turbsin[(int)((os * 0.125f + gp_cl->time) * TURBSCALE) & 255];
|
||||
}
|
||||
else
|
||||
{
|
||||
s = os / g_ripple.texturescale;
|
||||
t = ot / g_ripple.texturescale;
|
||||
}
|
||||
|
||||
s *= ( 1.0f / SUBDIVIDE_SIZE );
|
||||
t *= ( 1.0f / SUBDIVIDE_SIZE );
|
||||
|
||||
pglTexCoord2f( s, t );
|
||||
pglVertex3f( v[0], v[1], nv );
|
||||
|
||||
if( reverse )
|
||||
v -= VERTEXSIZE;
|
||||
else v += VERTEXSIZE;
|
||||
}
|
||||
|
||||
if( !useQuads )
|
||||
pglEnd();
|
||||
}
|
||||
|
||||
if( useQuads )
|
||||
pglEnd();
|
||||
|
||||
GL_SetupFogColorForSurfaces();
|
||||
}
|
||||
|
||||
/*
|
||||
============================================================
|
||||
|
||||
@@ -750,43 +658,39 @@ void R_AnimateRipples( void )
|
||||
R_RunRipplesAnimation( g_ripple.oldbuf, g_ripple.curbuf );
|
||||
}
|
||||
|
||||
void R_UploadRipples( texture_t *image )
|
||||
float R_UploadRipples( texture_t *image )
|
||||
{
|
||||
gl_texture_t *glt;
|
||||
uint32_t *pixels;
|
||||
int wbits, wmask, wshft;
|
||||
int y;
|
||||
float texturescale;
|
||||
|
||||
// discard unuseful textures
|
||||
if( !r_ripple.value || image->width > RIPPLES_CACHEWIDTH || image->width != image->height )
|
||||
{
|
||||
GL_Bind( XASH_TEXTURE0, image->gl_texturenum );
|
||||
return;
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
glt = R_GetTexture( image->gl_texturenum );
|
||||
if( !glt || !glt->original || !glt->original->buffer || !FBitSet( glt->flags, TF_EXPAND_SOURCE ))
|
||||
{
|
||||
GL_Bind( XASH_TEXTURE0, image->gl_texturenum );
|
||||
return;
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
GL_Bind( XASH_TEXTURE0, g_ripple.rippletexturenum );
|
||||
|
||||
if( r_ripple.value == 1.0f )
|
||||
texturescale = Q_max( 1.0f, image->width / 64.0f );
|
||||
else texturescale = 1.0f;
|
||||
|
||||
// no updates this frame
|
||||
if( !g_ripple.update && image->gl_texturenum == g_ripple.gl_texturenum )
|
||||
return;
|
||||
return texturescale;
|
||||
|
||||
g_ripple.gl_texturenum = image->gl_texturenum;
|
||||
if( r_ripple.value == 1.0f )
|
||||
{
|
||||
g_ripple.texturescale = Q_max( 1.0f, image->width / 64.0f );
|
||||
}
|
||||
else
|
||||
{
|
||||
g_ripple.texturescale = 1.0f;
|
||||
}
|
||||
|
||||
|
||||
pixels = (uint32_t *)glt->original->buffer;
|
||||
wbits = MostSignificantBit( image->width );
|
||||
@@ -813,4 +717,6 @@ void R_UploadRipples( texture_t *image )
|
||||
|
||||
pglTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, image->width, image->width, 0,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, g_ripple.texture );
|
||||
|
||||
return texturescale;
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ GNU General Public License for more details.
|
||||
#include "enginefeatures.h"
|
||||
#include "com_strings.h"
|
||||
#include "pm_movevars.h"
|
||||
#include "common/cvar.h"
|
||||
#include "cvardef.h"
|
||||
typedef struct mip_s mip_t;
|
||||
|
||||
typedef int fixed8_t;
|
||||
|
||||
@@ -17,13 +17,22 @@ fi
|
||||
|
||||
if [ "$ARCH" = "i386" ]; then
|
||||
cp SDL2_VC/lib/x86/SDL2.dll . # Install SDL2
|
||||
cp 3rdparty/vgui_support/vgui-dev/lib/win32_vc6/vgui.dll .
|
||||
elif [ "$ARCH" = "amd64" ]; then
|
||||
cp SDL2_VC/lib/x64/SDL2.dll .
|
||||
else
|
||||
die
|
||||
fi
|
||||
|
||||
WINSDK_LATEST=$(ls -1 "C:/Program Files (x86)/Windows Kits/10/bin" | grep -E '^10' | sort -rV | head -n1)
|
||||
echo "Latest installed Windows SDK is $WINSDK_LATEST"
|
||||
|
||||
"C:/Program Files (x86)/Windows Kits/10/bin/$WINSDK_LATEST/x64/signtool.exe" \
|
||||
/f scripts/fwgs.pfx /fd SHA256 /p "$FWGS_PFX_PASSWORD" *.dll *.exe
|
||||
|
||||
if [ "$ARCH" = "i386" ]; then # VGUI is already signed
|
||||
cp 3rdparty/vgui_support/vgui-dev/lib/win32_vc6/vgui.dll .
|
||||
fi
|
||||
|
||||
mkdir -p artifacts/
|
||||
7z a -t7z artifacts/xash3d-fwgs-win32-$ARCH.7z -m0=lzma2 -mx=9 -mfb=64 -md=32m -ms=on \
|
||||
*.dll *.exe *.pdb activities.txt \
|
||||
|
||||
7
wscript
7
wscript
@@ -172,7 +172,12 @@ def options(opt):
|
||||
|
||||
def configure(conf):
|
||||
conf.load('fwgslib reconfigure compiler_optimizations')
|
||||
conf.env.MSVC_TARGETS = ['x86' if not conf.options.ALLOW64 else 'x64']
|
||||
if conf.options.ALLOW64:
|
||||
conf.env.MSVC_TARGETS = ['x64']
|
||||
elif sys.maxsize > 2 ** 32:
|
||||
conf.env.MSVC_TARGETS = ['amd64_x86', 'x86']
|
||||
else:
|
||||
conf.env.MSVC_TARGETS = ['x86']
|
||||
|
||||
# Load compilers early
|
||||
conf.load('xshlib xcompile compiler_c compiler_cxx cmake gccdeps')
|
||||
|
||||
Reference in New Issue
Block a user