Compare commits

..

12 Commits

Author SHA1 Message Date
Alibek Omarov
3fb92e22fd Documentation: extensions: add documentation piece for lightmapped water 2024-08-26 21:28:06 +03:00
Alibek Omarov
7364765d62 ref: gl: implement reading engine's world flag and extra info for lightmapped water
* Rename gl_litwater to gl_litwater_force because it doesn't affect maps that declare
  litwater support
2024-08-26 21:27:13 +03:00
Alibek Omarov
b64329d1ee engine: add _litwater worldspawn key to allow mod developers to declare lightmapped water support 2024-08-26 17:10:06 +03:00
Alibek Omarov
ff1d3c4257 ref: gl: add cvars to scale and set minimum light for lightmapped water 2024-08-25 23:15:39 +03:00
Alibek Omarov
d418fb5f28 ref: gl: don't draw water backfaces when drawing lightmapped water 2024-08-25 22:30:12 +03:00
Alibek Omarov
62d7959843 ref: gl: move EmitWaterPolys to gl_rsurf and make it static. Slight refactoring, don't set SURF_DRAWTURB_QUADS if context isn't OpenGL 2024-08-25 19:19:03 +03:00
Alibek Omarov
980f356fe9 ref: gl: discard surfaces that don't have lightmaps in one place, remove unneeded checks 2024-08-25 18:56:46 +03:00
Alibek Omarov
83194ca0f5 ref: gl: support lightmapped water on transparent brushes 2024-08-22 23:13:34 +03:00
Alibek Omarov
d23968b12e ref: gl: add lightmapped water rendering, including wavy water 2024-08-22 23:13:08 +03:00
Alibek Omarov
5034b860c8 ref: gl: split lightmap chain handling from R_RenderBrushPoly 2024-08-22 23:08:52 +03:00
Alibek Omarov
5a708f90c6 ref: gl: build lightmap texcoords for subdivided SURF_DRAWTURB surface 2024-08-22 23:00:38 +03:00
Alibek Omarov
4118ac2561 ref: gl: add cvar gl_litwater to enable lightmapped water 2024-08-22 21:42:04 +03:00
45 changed files with 1260 additions and 1144 deletions

View File

@@ -14,4 +14,3 @@ When `-bugcomp` is specified with argument, it interpreted as flags separated wi
| ------- | ----------- | ---------------------------- |
| `peoei` | Reverts `pfnPEntityOfEntIndex` behavior to GoldSrc, where it returns NULL for last player due to incorrect player index comparison | * Counter-Strike: Condition Zero - Deleted Scenes |
| `gsmrf` | Rewrites message at the moment when Game DLL attempts to write an internal engine message, usually specific to GoldSrc protocol. Right now only supports `svc_spawnstaticsound`, more messages added by request. | * MetaMod/AMXModX based mods |
| `sp_attn_none` | Makes sounds with attenuation zero spatialized, i.e. have a stereo effect. | Possibly, every game that was made for GoldSrc. |

View 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.

View File

@@ -56,8 +56,6 @@ color24 gTracerColors[] =
};
*/
#define TRACER_COLORINDEX_DEFAULT 4
// Temporary entity array
#define TENTPRIORITY_LOW 0
#define TENTPRIORITY_HIGH 1

View File

@@ -79,22 +79,11 @@ typedef uint64_t longtime_t;
#define GAME_EXPORT
#endif
#define MALLOC __attribute__(( malloc ))
// added in GCC 11
#if __GNUC__ >= 11
// might want to set noclone due to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116893
// but it's easier to not force mismatched-dealloc to error yet
#define MALLOC_LIKE( x, y ) __attribute__(( malloc( x, y )))
#else
#define MALLOC_LIKE( x, y ) MALLOC
#endif
#define NORETURN __attribute__(( noreturn ))
#define NONNULL __attribute__(( nonnull ))
#define _format( x ) __attribute__(( format( printf, x, x + 1 )))
#define ALLOC_CHECK( x ) __attribute__(( alloc_size( x )))
#define NO_ASAN __attribute__(( no_sanitize( "address" )))
#define WARN_UNUSED_RESULT __attribute__(( warn_unused_result ))
#define RENAME_SYMBOL( x ) asm( x )
#else
#if defined( _MSC_VER )
@@ -110,9 +99,6 @@ typedef uint64_t longtime_t;
#define _format( x )
#define ALLOC_CHECK( x )
#define RENAME_SYMBOL( x )
#define MALLOC
#define MALLOC_LIKE( x, y )
#define WARN_UNUSED_RESULT
#endif
#if __GNUC__ >= 3

View File

@@ -274,13 +274,6 @@ void CL_GenericShot_f( void )
string checkname;
int i;
// allow overriding screenshot by users request
if( Cmd_Argc() > 1 )
{
Q_strncpy( cls.shotname, Cmd_Argv( 1 ), sizeof( cls.shotname ));
break;
}
if( type == scrshot_snapshot )
{
fmt = "../%s_%04d.png";

View File

@@ -250,7 +250,7 @@ static particle_t *R_AllocTracer( const vec3_t org, const vec3_t vel, float life
VectorCopy( vel, p->vel );
p->die = cl.time + life;
p->ramp = tracerlength.value;
p->color = TRACER_COLORINDEX_DEFAULT; // select custom color
p->color = 4; // select custom color
p->packedColor = 255; // alpha
return p;

View File

@@ -388,6 +388,7 @@ void CL_ParseStaticDecal( sizebuf_t *msg )
{
vec3_t origin;
int decalIndex, entityIndex, modelIndex;
cl_entity_t *ent = NULL;
float scale;
int flags;
@@ -1180,16 +1181,17 @@ CL_ParseBaseline
*/
void CL_ParseBaseline( sizebuf_t *msg, qboolean legacy )
{
const entity_state_t nullstate = { 0 };
int i, newnum;
entity_state_t nullstate;
qboolean player;
cl_entity_t *ent;
Delta_InitClient (); // finalize client delta's
memset( &nullstate, 0, sizeof( nullstate ));
while( 1 )
{
cl_entity_t *ent;
qboolean player;
int newnum;
if( legacy )
{
newnum = MSG_ReadWord( msg );
@@ -1205,10 +1207,10 @@ void CL_ParseBaseline( sizebuf_t *msg, qboolean legacy )
Host_Error( "%s: no free edicts\n", __func__ );
ent = CL_EDICT_NUM( newnum );
ent->prevstate = nullstate;
memset( &ent->prevstate, 0, sizeof( ent->prevstate ));
ent->index = newnum;
MSG_ReadDeltaEntity( msg, &nullstate, &ent->baseline, newnum, player, 1.0f );
MSG_ReadDeltaEntity( msg, &ent->prevstate, &ent->baseline, newnum, player, 1.0f );
if( legacy )
{
@@ -1218,13 +1220,11 @@ void CL_ParseBaseline( sizebuf_t *msg, qboolean legacy )
if( !legacy )
{
int i;
cl.instanced_baseline_count = MSG_ReadUBitLong( msg, 6 );
for( i = 0; i < cl.instanced_baseline_count; i++ )
{
int newnum = MSG_ReadUBitLong( msg, MAX_ENTITY_BITS );
newnum = MSG_ReadUBitLong( msg, MAX_ENTITY_BITS );
MSG_ReadDeltaEntity( msg, &nullstate, &cl.instanced_baseline[i], newnum, false, 1.0f );
}
}

View File

@@ -1269,73 +1269,6 @@ void GAME_EXPORT R_Sprite_Smoke( TEMPENTITY *pTemp, float scale )
pTemp->entity.curstate.scale = scale;
}
static void R_Spray_Generic( const char *func, const vec3_t pos, const vec3_t dir, int modelIndex, int count, int speed, int spread, int rendermode, qboolean sprite_spray )
{
model_t *mod = CL_ModelHandle( modelIndex );
float noise = spread / 100.0f;
float znoise = noise * 1.5f;
int i;
znoise = Q_min( 1.0f, znoise );
if( !mod )
{
Con_Reportf( "%s: No model %d!\n", func, modelIndex );
return;
}
for( i = 0; i < count; i++ )
{
TEMPENTITY *tent = CL_TempEntAlloc( pos, mod );
float rand_speed;
vec3_t noise_vec, vout;
if( !tent )
break;
tent->flags |= FTENT_SLOWGRAVITY;
tent->entity.curstate.rendermode = rendermode;
tent->entity.curstate.renderamt = 255;
tent->entity.baseline.renderamt = 255;
tent->entity.curstate.renderfx = kRenderFxNoDissipation;
noise_vec[0] = COM_RandomFloat( -noise, noise );
noise_vec[1] = COM_RandomFloat( -noise, noise );
noise_vec[2] = COM_RandomFloat( 0.0f, znoise );
rand_speed = COM_RandomFloat( speed * 0.8f, speed * 1.2f );
VectorAdd( dir, noise_vec, vout );
VectorScale( vout, rand_speed, tent->entity.baseline.origin );
if( sprite_spray ) // if TE_SPRITE_SPRAY
{
tent->flags |= FTENT_FADEOUT;
tent->fadeSpeed = 2.0f;
tent->entity.curstate.framerate = 0.5f;
tent->die = cl.time + 0.35;
tent->entity.curstate.frame = COM_RandomLong( 0, tent->frameMax ); // frameMax inclusive
}
else
{
tent->flags |= FTENT_COLLIDEWORLD;
if( tent->frameMax > 1 )
{
tent->flags |= FTENT_SPRANIMATE;
tent->entity.curstate.framerate = 10.0f;
tent->die = cl.time + tent->frameMax * 0.1;
}
else
{
tent->entity.curstate.framerate = 1.0f;
tent->die = cl.time + 0.35;
}
tent->entity.curstate.frame = 0.0f;
}
}
}
/*
===============
R_Spray
@@ -1345,7 +1278,61 @@ Throws a shower of sprites or models
*/
void GAME_EXPORT R_Spray( const vec3_t pos, const vec3_t dir, int modelIndex, int count, int speed, int spread, int rendermode )
{
R_Spray_Generic( __func__, pos, dir, modelIndex, count, speed, spread, rendermode, false );
TEMPENTITY *pTemp;
float noise;
float znoise;
model_t *pmodel;
int i;
if(( pmodel = CL_ModelHandle( modelIndex )) == NULL )
{
Con_Reportf( "No model %d!\n", modelIndex );
return;
}
noise = (float)spread / 100.0f;
// more vertical displacement
znoise = Q_min( 1.0f, noise * 1.5f );
for( i = 0; i < count; i++ )
{
pTemp = CL_TempEntAlloc( pos, pmodel );
if( !pTemp ) return;
pTemp->entity.curstate.rendermode = rendermode;
pTemp->entity.baseline.renderamt = pTemp->entity.curstate.renderamt = 255;
pTemp->entity.curstate.renderfx = kRenderFxNoDissipation;
if( rendermode != kRenderGlow )
{
// spray
pTemp->flags |= FTENT_COLLIDEWORLD | FTENT_SLOWGRAVITY;
if( pTemp->frameMax > 1 )
{
pTemp->flags |= FTENT_COLLIDEWORLD | FTENT_SLOWGRAVITY | FTENT_SPRANIMATE;
pTemp->die = cl.time + (pTemp->frameMax * 0.1f);
pTemp->entity.curstate.framerate = 10;
}
else pTemp->die = cl.time + 0.35f;
}
else
{
// sprite spray
pTemp->entity.curstate.frame = COM_RandomLong( 0, pTemp->frameMax );
pTemp->flags |= FTENT_FADEOUT | FTENT_SLOWGRAVITY;
pTemp->entity.curstate.framerate = 0.5;
pTemp->die = cl.time + 0.35f;
pTemp->fadeSpeed = 2.0;
}
// make the spittle fly the direction indicated, but mix in some noise.
pTemp->entity.baseline.origin[0] = dir[0] + COM_RandomFloat( -noise, noise );
pTemp->entity.baseline.origin[1] = dir[1] + COM_RandomFloat( -noise, noise );
pTemp->entity.baseline.origin[2] = dir[2] + COM_RandomFloat( 0, znoise );
VectorScale( pTemp->entity.baseline.origin, COM_RandomFloat(( speed * 0.8f ), ( speed * 1.2f )), pTemp->entity.baseline.origin );
}
}
/*
@@ -1357,7 +1344,7 @@ Spray of alpha sprites
*/
void GAME_EXPORT R_Sprite_Spray( const vec3_t pos, const vec3_t dir, int modelIndex, int count, int speed, int spread )
{
R_Spray_Generic( __func__, pos, dir, modelIndex, count, speed, spread, kRenderTransAlpha, true );
R_Spray( pos, dir, modelIndex, count, speed, spread, kRenderGlow );
}
/*
@@ -3126,3 +3113,4 @@ void CL_ClearEffects( void )
CL_ClearParticles ();
CL_ClearLightStyles ();
}

View File

@@ -524,11 +524,8 @@ static void SND_Spatialize( channel_t *ch )
dist = VectorNormalizeLength( source_vec );
dot = DotProduct( s_listener.right, source_vec );
if( !FBitSet( host.bugcomp, BUGCOMP_SPATIALIZE_SOUND_WITH_ATTN_NONE ))
{
// don't pan sounds with no attenuation
if( ch->dist_mult <= 0.0f ) dot = 0.0f;
}
// don't pan sounds with no attenuation
if( ch->dist_mult <= 0.0f ) dot = 0.0f;
// fill out channel volumes for single location
S_SpatializeChannel( &ch->leftvol, &ch->rightvol, ch->master_vol, gain, dot, dist * ch->dist_mult );

View File

@@ -112,9 +112,6 @@ typedef enum
#include "con_nprint.h"
#include "crclib.h"
#include "ref_api.h"
#define FSCALLBACK_OVERRIDE_OPEN
#define FSCALLBACK_OVERRIDE_LOADFILE
#define FSCALLBACK_OVERRIDE_MALLOC_LIKE
#include "fscallback.h"
// PERFORMANCE INFO
@@ -276,9 +273,6 @@ typedef enum bugcomp_e
// rewrites mod's attempts to write GoldSrc-specific messages into Xash protocol
// (new wrappers are added by request)
BUGCOMP_MESSAGE_REWRITE_FACILITY_FLAG = BIT( 1 ),
// makes sound with no attenuation spatialized, like in GoldSrc
BUGCOMP_SPATIALIZE_SOUND_WITH_ATTN_NONE = BIT( 2 ),
} bugcomp_t;
typedef struct host_parm_s
@@ -365,49 +359,12 @@ extern host_parm_t host;
typedef void (*xcommand_t)( void );
//
// zone.c
//
void Memory_Init( void );
void _Mem_Free( void *data, const char *filename, int fileline );
void *_Mem_Realloc( poolhandle_t poolptr, void *memptr, size_t size, qboolean clear, const char *filename, int fileline )
ALLOC_CHECK( 3 ) WARN_UNUSED_RESULT;
void *_Mem_Alloc( poolhandle_t poolptr, size_t size, qboolean clear, const char *filename, int fileline )
ALLOC_CHECK( 2 ) MALLOC_LIKE( _Mem_Free, 1 ) WARN_UNUSED_RESULT;
poolhandle_t _Mem_AllocPool( const char *name, const char *filename, int fileline )
WARN_UNUSED_RESULT;
void _Mem_FreePool( poolhandle_t *poolptr, const char *filename, int fileline );
void _Mem_EmptyPool( poolhandle_t poolptr, const char *filename, int fileline );
void _Mem_Check( const char *filename, int fileline );
qboolean Mem_IsAllocatedExt( poolhandle_t poolptr, void *data );
void Mem_PrintList( size_t minallocationsize );
void Mem_PrintStats( void );
#define Mem_Malloc( pool, size ) _Mem_Alloc( pool, size, false, __FILE__, __LINE__ )
#define Mem_Calloc( pool, size ) _Mem_Alloc( pool, size, true, __FILE__, __LINE__ )
#define Mem_Realloc( pool, ptr, size ) _Mem_Realloc( pool, ptr, size, true, __FILE__, __LINE__ )
#define Mem_Free( mem ) _Mem_Free( mem, __FILE__, __LINE__ )
#define Mem_AllocPool( name ) _Mem_AllocPool( name, __FILE__, __LINE__ )
#define Mem_FreePool( pool ) _Mem_FreePool( pool, __FILE__, __LINE__ )
#define Mem_EmptyPool( pool ) _Mem_EmptyPool( pool, __FILE__, __LINE__ )
#define Mem_IsAllocated( mem ) Mem_IsAllocatedExt( NULL, mem )
#define Mem_Check() _Mem_Check( __FILE__, __LINE__ )
//
// filesystem_engine.c
//
void FS_Init( const char *basedir );
void FS_Shutdown( void );
void *FS_GetNativeObject( const char *obj );
int FS_Close( file_t *file );
search_t *FS_Search( const char *pattern, int caseinsensitive, int gamedironly )
MALLOC_LIKE( _Mem_Free, 1 ) WARN_UNUSED_RESULT;
file_t *FS_Open( const char *filepath, const char *mode, qboolean gamedironly )
MALLOC_LIKE( FS_Close, 1 ) WARN_UNUSED_RESULT;
byte *FS_LoadFile( const char *path, fs_offset_t *filesizeptr, qboolean gamedironly )
MALLOC_LIKE( _Mem_Free, 1 ) WARN_UNUSED_RESULT;
byte *FS_LoadDirectFile( const char *path, fs_offset_t *filesizeptr )
MALLOC_LIKE( _Mem_Free, 1 ) WARN_UNUSED_RESULT;
//
// cmd.c
@@ -440,6 +397,30 @@ void Cmd_ExecuteString( const char *text );
void Cmd_ForwardToServer( void );
void Cmd_Escape( char *newCommand, const char *oldCommand, int len );
//
// zone.c
//
void Memory_Init( void );
void *_Mem_Realloc( poolhandle_t poolptr, void *memptr, size_t size, qboolean clear, const char *filename, int fileline ) ALLOC_CHECK( 3 );
void *_Mem_Alloc( poolhandle_t poolptr, size_t size, qboolean clear, const char *filename, int fileline ) ALLOC_CHECK( 2 );
poolhandle_t _Mem_AllocPool( const char *name, const char *filename, int fileline );
void _Mem_FreePool( poolhandle_t *poolptr, const char *filename, int fileline );
void _Mem_EmptyPool( poolhandle_t poolptr, const char *filename, int fileline );
void _Mem_Free( void *data, const char *filename, int fileline );
void _Mem_Check( const char *filename, int fileline );
qboolean Mem_IsAllocatedExt( poolhandle_t poolptr, void *data );
void Mem_PrintList( size_t minallocationsize );
void Mem_PrintStats( void );
#define Mem_Malloc( pool, size ) _Mem_Alloc( pool, size, false, __FILE__, __LINE__ )
#define Mem_Calloc( pool, size ) _Mem_Alloc( pool, size, true, __FILE__, __LINE__ )
#define Mem_Realloc( pool, ptr, size ) _Mem_Realloc( pool, ptr, size, true, __FILE__, __LINE__ )
#define Mem_Free( mem ) _Mem_Free( mem, __FILE__, __LINE__ )
#define Mem_AllocPool( name ) _Mem_AllocPool( name, __FILE__, __LINE__ )
#define Mem_FreePool( pool ) _Mem_FreePool( pool, __FILE__, __LINE__ )
#define Mem_EmptyPool( pool ) _Mem_EmptyPool( pool, __FILE__, __LINE__ )
#define Mem_IsAllocated( mem ) Mem_IsAllocatedExt( NULL, mem )
#define Mem_Check() _Mem_Check( __FILE__, __LINE__ )
//
// imagelib
@@ -450,10 +431,10 @@ void Image_Setup( void );
void Image_Init( void );
void Image_Shutdown( void );
void Image_AddCmdFlags( uint flags );
void FS_FreeImage( rgbdata_t *pack );
rgbdata_t *FS_LoadImage( const char *filename, const byte *buffer, size_t size ) MALLOC_LIKE( FS_FreeImage, 1 ) WARN_UNUSED_RESULT;
rgbdata_t *FS_LoadImage( const char *filename, const byte *buffer, size_t size );
qboolean FS_SaveImage( const char *filename, rgbdata_t *pix );
rgbdata_t *FS_CopyImage( rgbdata_t *in ) MALLOC_LIKE( FS_FreeImage, 1 ) WARN_UNUSED_RESULT;
rgbdata_t *FS_CopyImage( rgbdata_t *in );
void FS_FreeImage( rgbdata_t *pack );
extern const bpc_desc_t PFDesc[]; // image get pixelformat
qboolean Image_Process( rgbdata_t **pix, int width, int height, uint flags, float reserved );
void Image_PaletteHueReplace( byte *palSrc, int newHue, int start, int end, int pal_size );
@@ -508,14 +489,14 @@ typedef struct
//
void Sound_Init( void );
void Sound_Shutdown( void );
wavdata_t *FS_LoadSound( const char *filename, const byte *buffer, size_t size );
void FS_FreeSound( wavdata_t *pack );
void FS_FreeStream( stream_t *stream );
wavdata_t *FS_LoadSound( const char *filename, const byte *buffer, size_t size ) MALLOC_LIKE( FS_FreeSound, 1 ) WARN_UNUSED_RESULT;
stream_t *FS_OpenStream( const char *filename ) MALLOC_LIKE( FS_FreeStream, 1 ) WARN_UNUSED_RESULT;
stream_t *FS_OpenStream( const char *filename );
wavdata_t *FS_StreamInfo( stream_t *stream );
int FS_ReadStream( stream_t *stream, int bytes, void *buffer );
int FS_SetStreamPos( stream_t *stream, int newpos );
int FS_GetStreamPos( stream_t *stream );
void FS_FreeStream( stream_t *stream );
qboolean Sound_Process( wavdata_t **wav, int rate, int width, int channels, uint flags );
uint Sound_GetApproxWavePlayLen( const char *filepath );
qboolean Sound_SupportedFileFormat( const char *fileext );
@@ -580,7 +561,7 @@ qboolean SV_Active( void );
char *COM_MemFgets( byte *pMemFile, int fileSize, int *filePos, char *pBuffer, int bufferSize );
void COM_HexConvert( const char *pszInput, int nInputLength, byte *pOutput );
int COM_SaveFile( const char *filename, const void *data, int len );
byte *COM_LoadFileForMe( const char *filename, int *pLength ) MALLOC_LIKE( free, 1 );
byte* COM_LoadFileForMe( const char *filename, int *pLength );
qboolean COM_IsSafeFileToDownload( const char *filename );
cvar_t *pfnCVarGetPointer( const char *szVarName );
int pfnDrawConsoleString( int x, int y, char *string );
@@ -683,7 +664,7 @@ char *CL_Userinfo( void );
void CL_LegacyUpdateInfo( void );
void CL_CharEvent( int key );
qboolean CL_DisableVisibility( void );
byte *COM_LoadFile( const char *filename, int usehunk, int *pLength ) MALLOC_LIKE( free, 1 );
byte *COM_LoadFile( const char *filename, int usehunk, int *pLength );
struct cmd_s *Cmd_GetFirstFunctionHandle( void );
struct cmd_s *Cmd_GetNextFunctionHandle( struct cmd_s *cmd );
struct cmdalias_s *Cmd_AliasGetList( void );

View File

@@ -27,31 +27,6 @@ fs_globals_t *FI;
static pfnCreateInterface_t fs_pfnCreateInterface;
static HINSTANCE fs_hInstance;
search_t *FS_Search( const char *pattern, int caseinsensitive, int gamedironly )
{
return g_fsapi.Search( pattern, caseinsensitive, gamedironly );
}
int FS_Close( file_t *file )
{
return g_fsapi.Close( file );
}
file_t *FS_Open( const char *filepath, const char *mode, qboolean gamedironly )
{
return g_fsapi.Open( filepath, mode, gamedironly );
}
byte *FS_LoadFile( const char *path, fs_offset_t *filesizeptr, qboolean gamedironly )
{
return g_fsapi.LoadFile( path, filesizeptr, gamedironly );
}
byte *FS_LoadDirectFile( const char *path, fs_offset_t *filesizeptr )
{
return g_fsapi.LoadDirectFile( path, filesizeptr );
}
static void COM_StripDirectorySlash( char *pname )
{
size_t len;

View File

@@ -73,7 +73,6 @@ static feature_message_t bugcomp_features[] =
{
{ BUGCOMP_PENTITYOFENTINDEX_FLAG, "pfnPEntityOfEntIndex bugfix revert", "peoei" },
{ BUGCOMP_MESSAGE_REWRITE_FACILITY_FLAG, "GoldSrc Message Rewrite Facility", "gsmrf" },
{ BUGCOMP_SPATIALIZE_SOUND_WITH_ATTN_NONE, "spatialize sounds with zero attenuation", "sp_attn_none" },
};
static feature_message_t engine_features[] =

View File

@@ -110,7 +110,7 @@ void Image_Reset( void )
image.size = 0;
}
static MALLOC_LIKE( FS_FreeImage, 1 ) rgbdata_t *ImagePack( void )
static rgbdata_t *ImagePack( void )
{
rgbdata_t *pack;
@@ -547,7 +547,7 @@ static void Test_CheckImage( const char *name, rgbdata_t *rgb )
TASSERT( load->size == rgb->size )
TASSERT( memcmp(load->buffer, rgb->buffer, rgb->size ) == 0 )
FS_FreeImage( load );
Mem_Free( load );
}
void Test_RunImagelib( void )

View File

@@ -420,8 +420,7 @@ void NET_InitMasters( void )
// keep main master always there
NET_AddMaster( MASTERSERVER_ADR, false );
NET_AddMaster( "aaaa.mentality.rip:27010", false ); // IPv6-only
NET_AddMaster( "mentality.rip:27011", false ); // testing server, might be offline
NET_AddMaster( "aaaa.mentality.rip:27011", false ); // IPv6-only, testing server, might be offline
NET_AddMaster( "mentality.rip:27011", false );
NET_LoadMasters( );
}

View File

@@ -30,6 +30,13 @@ GNU General Public License for more details.
#define MIPTEX_CUSTOM_PALETTE_SIZE_BYTES ( sizeof( int16_t ) + 768 )
typedef struct wadlist_s
{
char wadnames[MAX_MAP_WADS][32];
int wadusage[MAX_MAP_WADS];
int count;
} wadlist_t;
typedef struct leaflist_s
{
int count;
@@ -129,6 +136,7 @@ typedef struct
dclipnode32_t *clipnodes_out; // temporary 32-bit array to hold clipnodes
// misc stuff
wadlist_t wadlist;
int lightmap_samples; // samples per lightmap (1 or 3)
int version; // model version
qboolean isworld;
@@ -1669,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
}
@@ -1827,7 +1836,9 @@ static void Mod_LoadEntities( model_t *mod, dbspmodel_t *bmod )
world.generator[0] = '\0';
world.compiler[0] = '\0';
world.message[0] = '\0';
world.wadlist.count = 0;
world.litwater_minlight = -1;
world.litwater_scale = -1.0f;
bmod->wadlist.count = 0;
// parse all the wads for loading textures in right ordering
while(( pfile = COM_ParseFile( pfile, token, sizeof( token ))) != NULL )
@@ -1870,12 +1881,12 @@ static void Mod_LoadEntities( model_t *mod, dbspmodel_t *bmod )
// make sure that wad is really exist
if( FS_FileExists( va( "%s.wad", token ), false ))
{
int num = world.wadlist.count++;
Q_strncpy( world.wadlist.wadnames[num], token, sizeof( world.wadlist.wadnames[0] ));
world.wadlist.wadusage[num] = 0;
int num = bmod->wadlist.count++;
Q_strncpy( bmod->wadlist.wadnames[num], token, sizeof( bmod->wadlist.wadnames[0] ));
bmod->wadlist.wadusage[num] = 0;
}
if( world.wadlist.count >= MAX_MAP_WADS )
if( bmod->wadlist.count >= MAX_MAP_WADS )
break; // too many wads...
}
}
@@ -1885,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
}
@@ -2022,35 +2042,24 @@ static void Mod_LoadMarkSurfaces( model_t *mod, dbspmodel_t *bmod )
if( bmod->version == QBSP2_VERSION )
{
const dmarkface32_t *in = bmod->markfaces32;
dmarkface32_t *in = bmod->markfaces32;
for( i = 0; i < bmod->nummarkfaces; i++ )
for( i = 0; i < bmod->nummarkfaces; i++, in++ )
{
if( in[i] < 0 || in[i] >= mod->numsurfaces )
Host_Error( "%s: bad surface number %i at %i (max %i) in '%s'\n", __func__, in[i], i, mod->numsurfaces, mod->name );
out[i] = mod->surfaces + in[i];
if( *in < 0 || *in >= mod->numsurfaces )
Host_Error( "%s: bad surface number in '%s'\n", __func__, mod->name );
out[i] = mod->surfaces + *in;
}
}
else
{
const dmarkface_t *in = bmod->markfaces;
dmarkface_t *in = bmod->markfaces;
for( i = 0; i < bmod->nummarkfaces; i++ )
for( i = 0; i < bmod->nummarkfaces; i++, in++ )
{
// NOTE: some of the buggy compilers have written a broken BSP file
// with marksurface pointing at negative surface, for example darkf6.bsp
// and darkf26.bsp in darkfuture mod. GoldSrc straight up writes
// invalid pointer to a surface. Try to fix up these cases...
if( mod->numsurfaces <= INT16_MAX && (int16_t)in[i] < 0 )
{
Con_Printf( S_WARN "%s: fixing up bad surface number %i at %i (max %i) in '%s'\n", __func__, in[i], i, mod->numsurfaces, mod->name );
out[i] = mod->surfaces;
continue;
}
if( in[i] < 0 || in[i] >= mod->numsurfaces )
Host_Error( "%s: bad surface number %i at %i (max %i) in '%s'\n", __func__, in[i], i, mod->numsurfaces, mod->name );
out[i] = mod->surfaces + in[i];
if( *in < 0 || *in >= mod->numsurfaces )
Host_Error( "%s: bad surface number in '%s'\n", __func__, mod->name );
out[i] = mod->surfaces + *in;
}
}
}
@@ -2312,9 +2321,9 @@ static void Mod_LoadTextureData( model_t *mod, dbspmodel_t *bmod, int textureInd
}
// Try WAD texture (force while r_wadtextures is 1)
if( !texture->gl_texturenum && (( r_wadtextures.value && world.wadlist.count > 0 ) || mipTex->offsets[0] <= 0 ))
if( !texture->gl_texturenum && (( r_wadtextures.value && bmod->wadlist.count > 0 ) || mipTex->offsets[0] <= 0 ))
{
int wadIndex = Mod_FindTextureInWadList( &world.wadlist, mipTex->name, texpath, sizeof( texpath ));
int wadIndex = Mod_FindTextureInWadList( &bmod->wadlist, mipTex->name, texpath, sizeof( texpath ));
if( wadIndex >= 0 )
{
@@ -2322,7 +2331,7 @@ static void Mod_LoadTextureData( model_t *mod, dbspmodel_t *bmod, int textureInd
if( !Host_IsDedicated( ))
texture->gl_texturenum = ref.dllFuncs.GL_LoadTexture( texpath, NULL, 0, txFlags );
#endif // !XASH_DEDICATED
world.wadlist.wadusage[wadIndex]++;
bmod->wadlist.wadusage[wadIndex]++;
}
}
@@ -2380,12 +2389,12 @@ static void Mod_LoadTextureData( model_t *mod, dbspmodel_t *bmod, int textureInd
// doesn't exist there. The original texture is already loaded, but cannot be modified.
// Instead, load the original texture again and convert it to luma.
wadIndex = Mod_FindTextureInWadList( &world.wadlist, texture->name, texpath, sizeof( texpath ));
wadIndex = Mod_FindTextureInWadList( &bmod->wadlist, texture->name, texpath, sizeof( texpath ));
if( wadIndex >= 0 )
{
src = FS_LoadFile( texpath, &srcSize, false );
world.wadlist.wadusage[wadIndex]++;
bmod->wadlist.wadusage[wadIndex]++;
}
// OK, loading it from wad or hi-res version
@@ -3418,14 +3427,18 @@ static qboolean Mod_LoadBmodelLumps( model_t *mod, const byte *mod_base, qboolea
Mod_CalcPHS( mod );
}
for( i = 0; i < world.wadlist.count; i++ )
for( i = 0; i < bmod->wadlist.count; i++ )
{
string wadname;
if( !world.wadlist.wadusage[i] )
if( !bmod->wadlist.wadusage[i] )
continue;
Q_snprintf( wadname, sizeof( wadname ), "%s.wad", world.wadlist.wadnames[i] );
Q_snprintf( wadname, sizeof( wadname ), "%s.wad", bmod->wadlist.wadnames[i] );
// a1ba: automatically precache used wad files so client will download it
if( SV_Active( ))
SV_GenericIndex( wadname );
if( !wadlist_warn )
{

View File

@@ -83,12 +83,6 @@ typedef struct
uint num_polys;
} hull_model_t;
typedef struct wadlist_s
{
char wadnames[MAX_MAP_WADS][32];
int wadusage[MAX_MAP_WADS];
int count;
} wadlist_t;
typedef struct world_static_s
{
@@ -126,7 +120,9 @@ typedef struct world_static_s
byte *compressed_phs;
size_t *phsofs;
wadlist_t wadlist;
// lightmapped water extra info
float litwater_scale;
int litwater_minlight;
} world_static_t;
#ifndef REF_DLL

View File

@@ -988,7 +988,7 @@ compare fields by offsets
assume from and to is valid
=====================
*/
static qboolean Delta_CompareField( delta_t *pField, const void *from, const void *to )
static qboolean Delta_CompareField( delta_t *pField, void *from, void *to, double timebase )
{
int signbit = ( pField->flags & DT_SIGNED ) ? 1 : 0;
float val_a, val_b;
@@ -1109,7 +1109,7 @@ Delta_TestBaseline
compare baselines to find optimal
=====================
*/
int Delta_TestBaseline( const entity_state_t *from, const entity_state_t *to, qboolean player, double timebase )
int Delta_TestBaseline( entity_state_t *from, entity_state_t *to, qboolean player, double timebase )
{
delta_info_t *dt = NULL;
delta_t *pField;
@@ -1145,7 +1145,7 @@ int Delta_TestBaseline( const entity_state_t *from, const entity_state_t *to, qb
// flag about field change (sets always)
countBits++;
if( !Delta_CompareField( pField, from, to ))
if( !Delta_CompareField( pField, from, to, timebase ))
{
// strings are handled differently
if( FBitSet( pField->flags, DT_STRING ))
@@ -1166,7 +1166,7 @@ write fields by offsets
assume from and to is valid
=====================
*/
static qboolean Delta_WriteField( sizebuf_t *msg, delta_t *pField, const void *from, const void *to, double timebase )
static qboolean Delta_WriteField( sizebuf_t *msg, delta_t *pField, void *from, void *to, double timebase )
{
int signbit = FBitSet( pField->flags, DT_SIGNED ) ? 1 : 0;
float flValue, flAngle;
@@ -1174,7 +1174,7 @@ static qboolean Delta_WriteField( sizebuf_t *msg, delta_t *pField, const void *f
int dt;
const char *pStr;
if( Delta_CompareField( pField, from, to ))
if( Delta_CompareField( pField, from, to, timebase ))
{
MSG_WriteOneBit( msg, 0 ); // unchanged
return false;
@@ -1264,7 +1264,7 @@ Delta_CopyField
====================
*/
static void Delta_CopyField( delta_t *pField, const void *from, void *to, double timebase )
static void Delta_CopyField( delta_t *pField, void *from, void *to, double timebase )
{
qboolean bSigned = FBitSet( pField->flags, DT_SIGNED );
uint8_t *to_field = (uint8_t *)to + pField->offset;
@@ -1313,7 +1313,7 @@ read fields by offsets
assume 'from' and 'to' is valid
=====================
*/
static qboolean Delta_ReadField( sizebuf_t *msg, delta_t *pField, const void *from, void *to, double timebase )
static qboolean Delta_ReadField( sizebuf_t *msg, delta_t *pField, void *from, void *to, double timebase )
{
qboolean bSigned = ( pField->flags & DT_SIGNED ) ? true : false;
float flValue, flAngle, flTime;
@@ -1425,7 +1425,7 @@ usercmd_t communication
MSG_WriteDeltaUsercmd
=====================
*/
void MSG_WriteDeltaUsercmd( sizebuf_t *msg, const usercmd_t *from, const usercmd_t *to )
void MSG_WriteDeltaUsercmd( sizebuf_t *msg, usercmd_t *from, usercmd_t *to )
{
delta_t *pField;
delta_info_t *dt;
@@ -1452,7 +1452,7 @@ void MSG_WriteDeltaUsercmd( sizebuf_t *msg, const usercmd_t *from, const usercmd
MSG_ReadDeltaUsercmd
=====================
*/
void MSG_ReadDeltaUsercmd( sizebuf_t *msg, const usercmd_t *from, usercmd_t *to )
void MSG_ReadDeltaUsercmd( sizebuf_t *msg, usercmd_t *from, usercmd_t *to )
{
delta_t *pField;
delta_info_t *dt;
@@ -1487,7 +1487,7 @@ event_args_t communication
MSG_WriteDeltaEvent
=====================
*/
void MSG_WriteDeltaEvent( sizebuf_t *msg, const event_args_t *from, const event_args_t *to )
void MSG_WriteDeltaEvent( sizebuf_t *msg, event_args_t *from, event_args_t *to )
{
delta_t *pField;
delta_info_t *dt;
@@ -1514,7 +1514,7 @@ void MSG_WriteDeltaEvent( sizebuf_t *msg, const event_args_t *from, const event_
MSG_ReadDeltaEvent
=====================
*/
void MSG_ReadDeltaEvent( sizebuf_t *msg, const event_args_t *from, event_args_t *to )
void MSG_ReadDeltaEvent( sizebuf_t *msg, event_args_t *from, event_args_t *to )
{
delta_t *pField;
delta_info_t *dt;
@@ -1542,7 +1542,7 @@ movevars_t communication
=============================================================================
*/
qboolean MSG_WriteDeltaMovevars( sizebuf_t *msg, const movevars_t *from, const movevars_t *to )
qboolean MSG_WriteDeltaMovevars( sizebuf_t *msg, movevars_t *from, movevars_t *to )
{
delta_t *pField;
delta_info_t *dt;
@@ -1578,7 +1578,7 @@ qboolean MSG_WriteDeltaMovevars( sizebuf_t *msg, const movevars_t *from, const m
return true;
}
void MSG_ReadDeltaMovevars( sizebuf_t *msg, const movevars_t *from, movevars_t *to )
void MSG_ReadDeltaMovevars( sizebuf_t *msg, movevars_t *from, movevars_t *to )
{
delta_t *pField;
delta_info_t *dt;
@@ -1614,7 +1614,7 @@ Writes current client data only for local client
Other clients can grab the client state from entity_state_t
==================
*/
void MSG_WriteClientData( sizebuf_t *msg, const clientdata_t *from, const clientdata_t *to, double timebase )
void MSG_WriteClientData( sizebuf_t *msg, clientdata_t *from, clientdata_t *to, double timebase )
{
delta_t *pField;
delta_info_t *dt;
@@ -1654,7 +1654,7 @@ MSG_ReadClientData
Read the clientdata
==================
*/
void MSG_ReadClientData( sizebuf_t *msg, const clientdata_t *from, clientdata_t *to, double timebase )
void MSG_ReadClientData( sizebuf_t *msg, clientdata_t *from, clientdata_t *to, double timebase )
{
#if !XASH_DEDICATED
delta_t *pField;
@@ -1695,7 +1695,7 @@ Writes current client data only for local client
Other clients can grab the client state from entity_state_t
==================
*/
void MSG_WriteWeaponData( sizebuf_t *msg, const weapon_data_t *from, const weapon_data_t *to, double timebase, int index )
void MSG_WriteWeaponData( sizebuf_t *msg, weapon_data_t *from, weapon_data_t *to, double timebase, int index )
{
delta_t *pField;
delta_info_t *dt;
@@ -1734,7 +1734,7 @@ MSG_ReadWeaponData
Read the clientdata
==================
*/
void MSG_ReadWeaponData( sizebuf_t *msg, const weapon_data_t *from, weapon_data_t *to, double timebase )
void MSG_ReadWeaponData( sizebuf_t *msg, weapon_data_t *from, weapon_data_t *to, double timebase )
{
delta_t *pField;
delta_info_t *dt;
@@ -1771,7 +1771,7 @@ If force is not set, then nothing at all will be generated if the entity is
identical, under the assumption that the in-order delta code will catch it.
==================
*/
void MSG_WriteDeltaEntity( const entity_state_t *from, const entity_state_t *to, sizebuf_t *msg, qboolean force, int delta_type, double timebase, int baseline )
void MSG_WriteDeltaEntity( entity_state_t *from, entity_state_t *to, sizebuf_t *msg, qboolean force, int delta_type, double timebase, int baseline )
{
delta_info_t *dt = NULL;
delta_t *pField;
@@ -1873,7 +1873,7 @@ If the delta removes the entity, entity_state_t->number will be set to MAX_EDICT
Can go from either a baseline or a previous packet_entity
==================
*/
qboolean MSG_ReadDeltaEntity( sizebuf_t *msg, const entity_state_t *from, entity_state_t *to, int number, int delta_type, double timebase )
qboolean MSG_ReadDeltaEntity( sizebuf_t *msg, entity_state_t *from, entity_state_t *to, int number, int delta_type, double timebase )
{
#if !XASH_DEDICATED
delta_info_t *dt = NULL;

View File

@@ -96,18 +96,18 @@ struct event_args_s;
struct movevars_s;
struct clientdata_s;
struct weapon_data_s;
void MSG_WriteDeltaUsercmd( sizebuf_t *msg, const struct usercmd_s *from, const struct usercmd_s *to );
void MSG_ReadDeltaUsercmd( sizebuf_t *msg, const struct usercmd_s *from, struct usercmd_s *to );
void MSG_WriteDeltaEvent( sizebuf_t *msg, const struct event_args_s *from, const struct event_args_s *to );
void MSG_ReadDeltaEvent( sizebuf_t *msg, const struct event_args_s *from, struct event_args_s *to );
qboolean MSG_WriteDeltaMovevars( sizebuf_t *msg, const struct movevars_s *from, const struct movevars_s *to );
void MSG_ReadDeltaMovevars( sizebuf_t *msg, const struct movevars_s *from, struct movevars_s *to );
void MSG_WriteClientData( sizebuf_t *msg, const struct clientdata_s *from, const struct clientdata_s *to, double timebase );
void MSG_ReadClientData( sizebuf_t *msg, const struct clientdata_s *from, struct clientdata_s *to, double timebase );
void MSG_WriteWeaponData( sizebuf_t *msg, const struct weapon_data_s *from, const struct weapon_data_s *to, double timebase, int index );
void MSG_ReadWeaponData( sizebuf_t *msg, const struct weapon_data_s *from, struct weapon_data_s *to, double timebase );
void MSG_WriteDeltaEntity( const struct entity_state_s *from, const struct entity_state_s *to, sizebuf_t *msg, qboolean force, int type, double timebase, int ofs );
qboolean MSG_ReadDeltaEntity( sizebuf_t *msg, const struct entity_state_s *from, struct entity_state_s *to, int num, int type, double timebase );
int Delta_TestBaseline( const struct entity_state_s *from, const struct entity_state_s *to, qboolean player, double timebase );
void MSG_WriteDeltaUsercmd( sizebuf_t *msg, struct usercmd_s *from, struct usercmd_s *to );
void MSG_ReadDeltaUsercmd( sizebuf_t *msg, struct usercmd_s *from, struct usercmd_s *to );
void MSG_WriteDeltaEvent( sizebuf_t *msg, struct event_args_s *from, struct event_args_s *to );
void MSG_ReadDeltaEvent( sizebuf_t *msg, struct event_args_s *from, struct event_args_s *to );
qboolean MSG_WriteDeltaMovevars( sizebuf_t *msg, struct movevars_s *from, struct movevars_s *to );
void MSG_ReadDeltaMovevars( sizebuf_t *msg, struct movevars_s *from, struct movevars_s *to );
void MSG_WriteClientData( sizebuf_t *msg, struct clientdata_s *from, struct clientdata_s *to, double timebase );
void MSG_ReadClientData( sizebuf_t *msg, struct clientdata_s *from, struct clientdata_s *to, double timebase );
void MSG_WriteWeaponData( sizebuf_t *msg, struct weapon_data_s *from, struct weapon_data_s *to, double timebase, int index );
void MSG_ReadWeaponData( sizebuf_t *msg, struct weapon_data_s *from, struct weapon_data_s *to, double timebase );
void MSG_WriteDeltaEntity( struct entity_state_s *from, struct entity_state_s *to, sizebuf_t *msg, qboolean force, int type, double timebase, int ofs );
qboolean MSG_ReadDeltaEntity( sizebuf_t *msg, struct entity_state_s *from, struct entity_state_s *to, int num, int type, double timebase );
int Delta_TestBaseline( struct entity_state_s *from, struct entity_state_s *to, qboolean player, double timebase );
#endif//NET_ENCODE_H

View File

@@ -30,10 +30,6 @@ GNU General Public License for more details.
static const struct in6_addr in6addr_any;
#endif
#if XASH_SDL == 2
#include <SDL_thread.h>
#endif
#define NET_USE_FRAGMENTS
#define MAX_LOOPBACK 4
@@ -367,44 +363,27 @@ static qboolean NET_GetHostByName( const char *hostname, int family, struct sock
#ifdef CAN_ASYNC_NS_RESOLVE
static void NET_ResolveThread( void );
#if XASH_SDL == 2
#define mutex_create( x ) (( x ) = SDL_CreateMutex() )
#define mutex_destroy( x ) SDL_DestroyMutex(( x ))
#define mutex_lock( x ) SDL_LockMutex(( x ))
#define mutex_unlock( x ) SDL_UnlockMutex(( x ))
#define create_thread( thread, pfn ) (( thread ) = SDL_CreateThread(( pfn ), "DNS resolver thread", NULL ))
#define detach_thread( x ) SDL_DetachThread(( x ))
typedef SDL_mutex *mutex_t;
typedef SDL_Thread *thread_t;
static int NET_ThreadStart( void *ununsed )
{
NET_ResolveThread();
return 0;
}
#elif !XASH_WIN32
#if !XASH_WIN32
#include <pthread.h>
#define mutex_create( x ) pthread_mutex_init( &( x ), NULL )
#define mutex_destroy( x ) pthread_mutex_destroy( &( x ))
#define mutex_lock( x ) pthread_mutex_lock( &( x ))
#define mutex_unlock( x ) pthread_mutex_unlock( &( x ))
#define create_thread( thread, pfn ) !pthread_create( &( thread ), NULL, ( pfn ), NULL )
#define detach_thread( x ) pthread_detach( x )
typedef pthread_mutex_t mutex_t;
typedef pthread_t thread_t;
#define mutex_lock pthread_mutex_lock
#define mutex_unlock pthread_mutex_unlock
#define exit_thread( x ) pthread_exit(x)
#define create_thread( pfn ) !pthread_create( &nsthread.thread, NULL, (pfn), NULL )
#define detach_thread( x ) pthread_detach(x)
#define mutex_t pthread_mutex_t
#define thread_t pthread_t
static void *NET_ThreadStart( void *unused )
{
NET_ResolveThread();
return NULL;
}
#else // WIN32
#define mutex_create( x ) InitializeCriticalSection( &( x ))
#define mutex_destroy( x ) DeleteCriticalSection( &( x ))
#define mutex_lock( x ) EnterCriticalSection( &( x ))
#define mutex_unlock( x ) LeaveCriticalSection( &( x ))
#define create_thread( thread, pfn ) (( thread ) = CreateThread( NULL, 0, ( pfn ), NULL, 0, NULL ))
#define detach_thread( x ) CloseHandle(( x ))
typedef CRITICAL_SECTION mutex_t;
typedef HANDLE thread_t;
#define mutex_lock EnterCriticalSection
#define mutex_unlock LeaveCriticalSection
#define detach_thread( x ) CloseHandle(x)
#define create_thread( pfn ) ( nsthread.thread = CreateThread( NULL, 0, pfn, NULL, 0, NULL ))
#define mutex_t CRITICAL_SECTION
#define thread_t HANDLE
DWORD WINAPI NET_ThreadStart( LPVOID unused )
{
NET_ResolveThread();
@@ -421,30 +400,27 @@ DWORD WINAPI NET_ThreadStart( LPVOID unused )
static struct nsthread_s
{
mutex_t mutexns;
mutex_t mutexres;
mutex_t mutexns;
mutex_t mutexres;
thread_t thread;
int result;
string hostname;
int family;
int result;
string hostname;
int family;
struct sockaddr_storage addr;
qboolean busy;
} nsthread;
} nsthread
#if !XASH_WIN32
= { PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER }
#endif
;
static void NET_InitializeCriticalSections( void )
{
net.threads_initialized = true;
mutex_create( nsthread.mutexns );
mutex_create( nsthread.mutexres );
}
static void NET_DeleteCriticalSections( void )
{
net.threads_initialized = false;
mutex_destroy( nsthread.mutexns );
mutex_destroy( nsthread.mutexres );
#if XASH_WIN32
InitializeCriticalSection( &nsthread.mutexns );
InitializeCriticalSection( &nsthread.mutexres );
#endif
}
void NET_ResolveThread( void )
@@ -464,12 +440,12 @@ void NET_ResolveThread( void )
RESOLVE_DBG( "[resolve thread] success\n" );
else
RESOLVE_DBG( "[resolve thread] failed\n" );
mutex_lock( nsthread.mutexres );
mutex_lock( &nsthread.mutexres );
nsthread.addr = addr;
nsthread.busy = false;
nsthread.result = res ? NET_EAI_OK : NET_EAI_NONAME;
RESOLVE_DBG( "[resolve thread] returning result\n" );
mutex_unlock( nsthread.mutexres );
mutex_unlock( &nsthread.mutexres );
RESOLVE_DBG( "[resolve thread] exiting thread\n" );
}
#endif // CAN_ASYNC_NS_RESOLVE
@@ -534,11 +510,11 @@ static net_gai_state_t NET_StringToSockaddr( const char *s, struct sockaddr_stor
#ifdef CAN_ASYNC_NS_RESOLVE
if( net.threads_initialized && nonblocking )
{
mutex_lock( nsthread.mutexres );
mutex_lock( &nsthread.mutexres );
if( nsthread.busy )
{
mutex_unlock( nsthread.mutexres );
mutex_unlock( &nsthread.mutexres );
return NET_EAI_AGAIN;
}
@@ -559,9 +535,9 @@ static net_gai_state_t NET_StringToSockaddr( const char *s, struct sockaddr_stor
Q_strncpy( nsthread.hostname, copy, sizeof( nsthread.hostname ));
nsthread.family = family;
nsthread.busy = true;
mutex_unlock( nsthread.mutexres );
mutex_unlock( &nsthread.mutexres );
if( create_thread( nsthread.thread, NET_ThreadStart ))
if( create_thread( NET_ThreadStart ))
{
asyncfailed = false;
return NET_EAI_AGAIN;
@@ -573,7 +549,7 @@ static net_gai_state_t NET_StringToSockaddr( const char *s, struct sockaddr_stor
}
}
mutex_unlock( nsthread.mutexres );
mutex_unlock( &nsthread.mutexres );
}
#endif // CAN_ASYNC_NS_RESOLVE
@@ -2191,11 +2167,6 @@ void NET_Shutdown( void )
NET_ClearLagData( true, true );
NET_Config( false, false );
#ifdef CAN_ASYNC_NS_RESOLVE
NET_DeleteCriticalSections();
#endif
#if XASH_WIN32
WSACleanup();
#endif

View File

@@ -30,7 +30,7 @@ static void Sound_Reset( void )
sound.size = 0;
}
static MALLOC_LIKE( FS_FreeSound, 1 ) wavdata_t *SoundPack( void )
static wavdata_t *SoundPack( void )
{
wavdata_t *pack = Mem_Calloc( host.soundpool, sizeof( wavdata_t ));

View File

@@ -230,20 +230,13 @@ static void Sys_PrintLogfile( const int fd, const char *logtime, const char *msg
if( p == NULL )
{
if( write( fd, msg, Q_strlen( msg )) < 0 )
{
// don't call engine Msg, might cause recursion
fprintf( stderr, "%s: write failed: %s\n", __func__, strerror( errno ));
}
write( fd, msg, Q_strlen( msg ));
break;
}
else if( IsColorString( p ))
{
if( p != msg )
{
if( write( fd, msg, p - msg ) < 0 )
fprintf( stderr, "%s: write failed: %s\n", __func__, strerror( errno ));
}
write( fd, msg, p - msg );
msg = p + 2;
if( colorize )
@@ -251,8 +244,7 @@ static void Sys_PrintLogfile( const int fd, const char *logtime, const char *msg
}
else
{
if( write( fd, msg, p - msg + 1 ) < 0 )
fprintf( stderr, "%s: write failed: %s\n", __func__, strerror( errno ));
write( fd, msg, p - msg + 1 );
msg = p + 1;
}
}

View File

@@ -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)
@@ -389,13 +390,10 @@ typedef struct ref_api_s
int (*pfnGetStudioModelInterface)( int version, struct r_studio_interface_s **ppinterface, struct engine_studio_api_s *pstudio );
// memory
poolhandle_t (*_Mem_AllocPool)( const char *name, const char *filename, int fileline )
WARN_UNUSED_RESULT;
poolhandle_t (*_Mem_AllocPool)( const char *name, const char *filename, int fileline );
void (*_Mem_FreePool)( poolhandle_t *poolptr, const char *filename, int fileline );
void *(*_Mem_Alloc)( poolhandle_t poolptr, size_t size, qboolean clear, const char *filename, int fileline )
ALLOC_CHECK( 2 ) WARN_UNUSED_RESULT;
void *(*_Mem_Realloc)( poolhandle_t poolptr, void *memptr, size_t size, qboolean clear, const char *filename, int fileline )
ALLOC_CHECK( 3 ) WARN_UNUSED_RESULT;
void *(*_Mem_Alloc)( poolhandle_t poolptr, size_t size, qboolean clear, const char *filename, int fileline ) ALLOC_CHECK( 2 );
void *(*_Mem_Realloc)( poolhandle_t poolptr, void *memptr, size_t size, qboolean clear, const char *filename, int fileline ) ALLOC_CHECK( 3 );
void (*_Mem_Free)( void *data, const char *filename, int fileline );
// library management

View File

@@ -363,7 +363,6 @@ loads external resource list
static void SV_CreateGenericResources( void )
{
string filename;
int i;
Q_strncpy( filename, sv.model_precache[1], sizeof( filename ));
COM_ReplaceExtension( filename, ".res", sizeof( filename ));
@@ -371,16 +370,6 @@ static void SV_CreateGenericResources( void )
SV_ReadResourceList( filename );
SV_ReadResourceList( "reslist.txt" );
for( i = 0; i < world.wadlist.count; i++ )
{
if( world.wadlist.wadusage[i] > 0 )
{
string wadname;
Q_snprintf( wadname, sizeof( wadname ), "%s.wad", world.wadlist.wadnames[i] );
SV_GenericIndex( wadname );
}
}
}
/*

View File

@@ -125,16 +125,6 @@ static void FS_BackupFileName( file_t *file, const char *path, uint options ) {}
static void FS_InitMemory( void );
static void FS_Purge( file_t* file );
void _Mem_Free( void *data, const char *filename, int fileline )
{
g_engfuncs._Mem_Free( data, filename, fileline );
}
void *_Mem_Alloc( poolhandle_t poolptr, size_t size, qboolean clear, const char *filename, int fileline )
{
return g_engfuncs._Mem_Alloc( poolptr, size, clear, filename, fileline );
}
/*
=============================================================================
@@ -1422,34 +1412,34 @@ static qboolean FS_FindLibrary( const char *dllname, qboolean directpath, fs_dll
return true;
}
static poolhandle_t Mem_AllocPoolStub( const char *name, const char *filename, int fileline )
static poolhandle_t _Mem_AllocPool( const char *name, const char *filename, int fileline )
{
return (poolhandle_t)0xDEADC0DE;
}
static void Mem_FreePoolStub( poolhandle_t *poolptr, const char *filename, int fileline )
static void _Mem_FreePool( poolhandle_t *poolptr, const char *filename, int fileline )
{
// stub
}
static void *Mem_AllocStub( poolhandle_t poolptr, size_t size, qboolean clear, const char *filename, int fileline )
static void *_Mem_Alloc( poolhandle_t poolptr, size_t size, qboolean clear, const char *filename, int fileline )
{
void *ptr = malloc( size );
if( clear ) memset( ptr, 0, size );
return ptr;
}
static void *Mem_ReallocStub( poolhandle_t poolptr, void *memptr, size_t size, qboolean clear, const char *filename, int fileline )
static void *_Mem_Realloc( poolhandle_t poolptr, void *memptr, size_t size, qboolean clear, const char *filename, int fileline )
{
return realloc( memptr, size );
}
static void Mem_FreeStub( void *data, const char *filename, int fileline )
static void _Mem_Free( void *data, const char *filename, int fileline )
{
free( data );
}
static void Con_PrintfStub( const char *fmt, ... )
static void _Con_Printf( const char *fmt, ... )
{
va_list ap;
@@ -1458,7 +1448,7 @@ static void Con_PrintfStub( const char *fmt, ... )
va_end( ap );
}
static void Sys_ErrorStub( const char *fmt, ... )
static void _Sys_Error( const char *fmt, ... )
{
va_list ap;
@@ -1469,7 +1459,7 @@ static void Sys_ErrorStub( const char *fmt, ... )
exit( 1 );
}
static void *Sys_GetNativeObjectStub( const char *object )
static void *Sys_GetNativeObject_stub( const char *object )
{
return NULL;
}
@@ -2534,7 +2524,7 @@ byte *FS_LoadFileMalloc( const char *path, fs_offset_t *filesizeptr, qboolean ga
byte *FS_LoadFile( const char *path, fs_offset_t *filesizeptr, qboolean gamedironly )
{
return FS_LoadFile_( path, filesizeptr, gamedironly, true );
return FS_LoadFile_( path, filesizeptr, gamedironly, g_engfuncs._Mem_Alloc != _Mem_Alloc );
}
qboolean CRC32_File( dword *crcvalue, const char *filename )
@@ -2946,6 +2936,14 @@ search_t *FS_Search( const char *pattern, int caseinsensitive, int gamedironly )
return search;
}
static const char *FS_ArchivePath( file_t *f )
{
if( f->searchpath )
return f->searchpath->filename;
return "plain";
}
static qboolean FS_IsArchiveExtensionSupported( const char *ext, uint flags )
{
int i;
@@ -2973,16 +2971,16 @@ void FS_InitMemory( void )
fs_interface_t g_engfuncs =
{
Con_PrintfStub,
Con_PrintfStub,
Con_PrintfStub,
Sys_ErrorStub,
Mem_AllocPoolStub,
Mem_FreePoolStub,
Mem_AllocStub,
Mem_ReallocStub,
Mem_FreeStub,
Sys_GetNativeObjectStub,
_Con_Printf,
_Con_Printf,
_Con_Printf,
_Sys_Error,
_Mem_AllocPool,
_Mem_FreePool,
_Mem_Alloc,
_Mem_Realloc,
_Mem_Free,
Sys_GetNativeObject_stub
};
static qboolean FS_InitInterface( int version, const fs_interface_t *engfuncs )

View File

@@ -217,10 +217,8 @@ typedef struct fs_interface_t
// memory
poolhandle_t (*_Mem_AllocPool)( const char *name, const char *filename, int fileline );
void (*_Mem_FreePool)( poolhandle_t *poolptr, const char *filename, int fileline );
void *(*_Mem_Alloc)( poolhandle_t poolptr, size_t size, qboolean clear, const char *filename, int fileline )
ALLOC_CHECK( 2 ) WARN_UNUSED_RESULT;
void *(*_Mem_Realloc)( poolhandle_t poolptr, void *memptr, size_t size, qboolean clear, const char *filename, int fileline )
ALLOC_CHECK( 3 ) WARN_UNUSED_RESULT;
void *(*_Mem_Alloc)( poolhandle_t poolptr, size_t size, qboolean clear, const char *filename, int fileline ) ALLOC_CHECK( 2 );
void *(*_Mem_Realloc)( poolhandle_t poolptr, void *memptr, size_t size, qboolean clear, const char *filename, int fileline ) ALLOC_CHECK( 3 );
void (*_Mem_Free)( void *data, const char *filename, int fileline );
// platform

View File

@@ -19,7 +19,6 @@ GNU General Public License for more details.
#ifndef FILESYSTEM_INTERNAL_H
#define FILESYSTEM_INTERNAL_H
#include <stdlib.h>
#include "xash3d_types.h"
#include "filesystem.h"
@@ -130,10 +129,10 @@ extern const fs_archive_t g_archives[];
#define GI FI.GameInfo
#define Mem_Malloc( pool, size ) _Mem_Alloc( pool, size, false, __FILE__, __LINE__ )
#define Mem_Calloc( pool, size ) _Mem_Alloc( pool, size, true, __FILE__, __LINE__ )
#define Mem_Malloc( pool, size ) g_engfuncs._Mem_Alloc( pool, size, false, __FILE__, __LINE__ )
#define Mem_Calloc( pool, size ) g_engfuncs._Mem_Alloc( pool, size, true, __FILE__, __LINE__ )
#define Mem_Realloc( pool, ptr, size ) g_engfuncs._Mem_Realloc( pool, ptr, size, true, __FILE__, __LINE__ )
#define Mem_Free( mem ) _Mem_Free( mem, __FILE__, __LINE__ )
#define Mem_Free( mem ) g_engfuncs._Mem_Free( mem, __FILE__, __LINE__ )
#define Mem_AllocPool( name ) g_engfuncs._Mem_AllocPool( name, __FILE__, __LINE__ )
#define Mem_FreePool( pool ) g_engfuncs._Mem_FreePool( pool, __FILE__, __LINE__ )
@@ -149,9 +148,6 @@ extern const fs_archive_t g_archives[];
qboolean FS_InitStdio( qboolean caseinsensitive, const char *rootdir, const char *basedir, const char *gamedir, const char *rodir );
void FS_ShutdownStdio( void );
searchpath_t *FS_AddArchive_Fullpath( const fs_archive_t *archive, const char *file, int flags );
void _Mem_Free( void *data, const char *filename, int fileline );
void *_Mem_Alloc( poolhandle_t poolptr, size_t size, qboolean clear, const char *filename, int fileline )
ALLOC_CHECK( 2 ) MALLOC_LIKE( _Mem_Free, 1 ) WARN_UNUSED_RESULT;
// search path utils
void FS_Rescan( void );
@@ -159,8 +155,7 @@ void FS_ClearSearchPath( void );
void FS_AllowDirectPaths( qboolean enable );
void FS_AddGameDirectory( const char *dir, uint flags );
void FS_AddGameHierarchy( const char *dir, uint flags );
search_t *FS_Search( const char *pattern, int caseinsensitive, int gamedironly )
MALLOC_LIKE( _Mem_Free, 1 ) WARN_UNUSED_RESULT;
search_t *FS_Search( const char *pattern, int caseinsensitive, int gamedironly );
int FS_SetCurrentDirectory( const char *path );
void FS_Path_f( void );
@@ -168,15 +163,14 @@ void FS_Path_f( void );
void FS_LoadGameInfo( const char *rootfolder );
// file ops
int FS_Close( file_t *file );
file_t *FS_Open( const char *filepath, const char *mode, qboolean gamedironly )
MALLOC_LIKE( FS_Close, 1 ) WARN_UNUSED_RESULT;
file_t *FS_Open( const char *filepath, const char *mode, qboolean gamedironly );
fs_offset_t FS_Write( file_t *file, const void *data, size_t datasize );
fs_offset_t FS_Read( file_t *file, void *buffer, size_t buffersize );
int FS_Seek( file_t *file, fs_offset_t offset, int whence );
fs_offset_t FS_Tell( file_t *file );
qboolean FS_Eof( file_t *file );
int FS_Flush( file_t *file );
int FS_Close( file_t *file );
int FS_Gets( file_t *file, char *string, size_t bufsize );
int FS_UnGetc( file_t *file, char c );
int FS_Getc( file_t *file );
@@ -187,12 +181,9 @@ fs_offset_t FS_FileLength( file_t *f );
qboolean FS_FileCopy( file_t *pOutput, file_t *pInput, int fileSize );
// file buffer ops
byte *FS_LoadFile( const char *path, fs_offset_t *filesizeptr, qboolean gamedironly )
MALLOC_LIKE( _Mem_Free, 1 ) WARN_UNUSED_RESULT;
byte *FS_LoadFileMalloc( const char *path, fs_offset_t *filesizeptr, qboolean gamedironly )
MALLOC_LIKE( free, 1 ) WARN_UNUSED_RESULT;
byte *FS_LoadDirectFile( const char *path, fs_offset_t *filesizeptr )
MALLOC_LIKE( _Mem_Free, 1 ) WARN_UNUSED_RESULT;
byte *FS_LoadFile( const char *path, fs_offset_t *filesizeptr, qboolean gamedironly );
byte *FS_LoadFileMalloc( const char *path, fs_offset_t *filesizeptr, qboolean gamedironly );
byte *FS_LoadDirectFile( const char *path, fs_offset_t *filesizeptr );
qboolean FS_WriteFile( const char *filename, const void *data, fs_offset_t len );
// file hashing

View File

@@ -36,9 +36,7 @@ extern fs_globals_t *FI;
#define FS_AllowDirectPaths (*g_fsapi.AllowDirectPaths)
#define FS_AddGameDirectory (*g_fsapi.AddGameDirectory)
#define FS_AddGameHierarchy (*g_fsapi.AddGameHierarchy)
#ifndef FSCALLBACK_OVERRIDE_MALLOC_LIKE
#define FS_Search (*g_fsapi.Search)
#endif
#define FS_SetCurrentDirectory (*g_fsapi.SetCurrentDirectory)
#define FS_Path_f (*g_fsapi.Path_f)
@@ -46,16 +44,14 @@ extern fs_globals_t *FI;
#define FS_LoadGameInfo (*g_fsapi.LoadGameInfo)
// file ops
#ifndef FSCALLBACK_OVERRIDE_MALLOC_LIKE
#define FS_Open (*g_fsapi.Open)
#define FS_Close (*g_fsapi.Close)
#endif
#define FS_Write (*g_fsapi.Write)
#define FS_Read (*g_fsapi.Read)
#define FS_Seek (*g_fsapi.Seek)
#define FS_Tell (*g_fsapi.Tell)
#define FS_Eof (*g_fsapi.Eof)
#define FS_Flush (*g_fsapi.Flush)
#define FS_Close (*g_fsapi.Close)
#define FS_Gets (*g_fsapi.Gets)
#define FS_UnGetc (*g_fsapi.UnGetc)
#define FS_Getc (*g_fsapi.Getc)
@@ -66,10 +62,8 @@ extern fs_globals_t *FI;
#define FS_FileCopy (*g_fsapi.FileCopy)
// file buffer ops
#ifndef FSCALLBACK_OVERRIDE_MALLOC_LIKE
#define FS_LoadFile (*g_fsapi.LoadFile)
#define FS_LoadDirectFile (*g_fsapi.LoadDirectFile)
#endif
#define FS_WriteFile (*g_fsapi.WriteFile)
// file hashing

View File

@@ -299,6 +299,7 @@ static zip_t *FS_LoadZip( const char *zipfile, int *error )
if( error )
*error = ZIP_LOAD_BAD_HEADER;
Mem_Free( info );
FS_CloseZIP( zip );
return NULL;
}
@@ -315,6 +316,7 @@ static zip_t *FS_LoadZip( const char *zipfile, int *error )
if( error )
*error = ZIP_LOAD_CORRUPTED;
Mem_Free( info );
FS_CloseZIP( zip );
return NULL;
}
@@ -362,6 +364,7 @@ static zip_t *FS_LoadZip( const char *zipfile, int *error )
if( error )
*error = ZIP_LOAD_CORRUPTED;
Mem_Free( info );
FS_CloseZIP( zip );
return NULL;
}

View File

@@ -19,6 +19,13 @@ GNU General Public License for more details.
#include "com_model.h"
#include "xash3d_mathlib.h"
const matrix3x4 m_matrix3x4_identity =
{
{ 1, 0, 0, 0 }, // PITCH [forward], org[0]
{ 0, 1, 0, 0 }, // YAW [right] , org[1]
{ 0, 0, 1, 0 }, // ROLL [up] , org[2]
};
/*
========================================================================
@@ -218,6 +225,14 @@ void Matrix3x4_TransformAABB( const matrix3x4 world, const vec3_t mins, const ve
VectorAdd( worldCenter, worldExtents, absmax );
}
const matrix4x4 m_matrix4x4_identity =
{
{ 1, 0, 0, 0 }, // PITCH
{ 0, 1, 0, 0 }, // YAW
{ 0, 0, 1, 0 }, // ROLL
{ 0, 0, 0, 1 }, // ORIGIN
};
/*
========================================================================

View File

@@ -2,7 +2,7 @@
#include "crtlib.h"
#include <stdio.h>
static int Test_ExtractFilePath( void )
int Test_ExtractFilePath( void )
{
char dst[64];
const char *strings[] =

View File

@@ -18,14 +18,15 @@ GNU General Public License for more details.
#include "com_model.h"
#include "xash3d_mathlib.h"
#include "eiface.h"
#include "studio.h"
#define NUM_HULL_ROUNDS ARRAYSIZE( hull_table )
#define HULL_PRECISION 4
static const word hull_table[] = { 2, 4, 6, 8, 12, 16, 18, 24, 28, 32, 36, 40, 48, 54, 56, 60, 64, 72, 80, 112, 120, 128, 140, 176 };
vec3_t vec3_origin = { 0, 0, 0 };
const int boxpnt[6][4] =
static word hull_table[] = { 2, 4, 6, 8, 12, 16, 18, 24, 28, 32, 36, 40, 48, 54, 56, 60, 64, 72, 80, 112, 120, 128, 140, 176 };
int boxpnt[6][4] =
{
{ 0, 4, 6, 2 }, // +X
{ 0, 1, 5, 4 }, // +Y
@@ -41,7 +42,18 @@ const float m_bytenormals[NUMVERTEXNORMALS][3] =
#include "anorms.h"
};
uint16_t FloatToHalf( float v )
/*
=================
anglemod
=================
*/
float anglemod( float a )
{
a = (360.0f / 65536) * ((int)(a*(65536/360.0f)) & 65535);
return a;
}
word FloatToHalf( float v )
{
unsigned int i = FloatAsUint( v );
unsigned int e = (i >> 23) & 0x00ff;
@@ -57,7 +69,7 @@ uint16_t FloatToHalf( float v )
return h;
}
float HalfToFloat( uint16_t h )
float HalfToFloat( word h )
{
unsigned int f = (h << 16) & 0x80000000;
unsigned int em = h & 0x7fff;
@@ -139,6 +151,57 @@ void RoundUpHullSize( vec3_t size )
}
}
/*
=================
SignbitsForPlane
fast box on planeside test
=================
*/
int SignbitsForPlane( const vec3_t normal )
{
int bits, i;
for( bits = i = 0; i < 3; i++ )
if( normal[i] < 0.0f ) bits |= 1<<i;
return bits;
}
/*
=================
PlaneTypeForNormal
=================
*/
int PlaneTypeForNormal( const vec3_t normal )
{
if( normal[0] == 1.0f )
return PLANE_X;
if( normal[1] == 1.0f )
return PLANE_Y;
if( normal[2] == 1.0f )
return PLANE_Z;
return PLANE_NONAXIAL;
}
/*
=================
NearestPOW
=================
*/
int NearestPOW( int value, qboolean roundDown )
{
int n = 1;
if( value <= 0 ) return 1;
while( n < value ) n <<= 1;
if( roundDown )
{
if( n > value ) n >>= 1;
}
return n;
}
/*
=================
rsqrt
@@ -161,6 +224,43 @@ float rsqrt( float number )
return y;
}
/*
==============
VectorCompareEpsilon
==============
*/
qboolean VectorCompareEpsilon( const vec3_t vec1, const vec3_t vec2, vec_t epsilon )
{
vec_t ax, ay, az;
ax = fabs( vec1[0] - vec2[0] );
ay = fabs( vec1[1] - vec2[1] );
az = fabs( vec1[2] - vec2[2] );
if(( ax <= epsilon ) && ( ay <= epsilon ) && ( az <= epsilon ))
return true;
return false;
}
float VectorNormalizeLength2( const vec3_t v, vec3_t out )
{
float length, ilength;
length = v[0] * v[0] + v[1] * v[1] + v[2] * v[2];
length = sqrt( length );
if( length )
{
ilength = 1.0f / length;
out[0] = v[0] * ilength;
out[1] = v[1] * ilength;
out[2] = v[2] * ilength;
}
return length;
}
void VectorVectors( const vec3_t forward, vec3_t right, vec3_t up )
{
float d;
@@ -176,6 +276,42 @@ void VectorVectors( const vec3_t forward, vec3_t right, vec3_t up )
VectorNormalize( up );
}
/*
=================
AngleVectors
=================
*/
void GAME_EXPORT AngleVectors( const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up )
{
float sr, sp, sy, cr, cp, cy;
SinCos( DEG2RAD( angles[YAW] ), &sy, &cy );
SinCos( DEG2RAD( angles[PITCH] ), &sp, &cp );
SinCos( DEG2RAD( angles[ROLL] ), &sr, &cr );
if( forward )
{
forward[0] = cp * cy;
forward[1] = cp * sy;
forward[2] = -sp;
}
if( right )
{
right[0] = (-1.0f * sr * sp * cy + -1.0f * cr * -sy );
right[1] = (-1.0f * sr * sp * sy + -1.0f * cr * cy );
right[2] = (-1.0f * sr * cp);
}
if( up )
{
up[0] = (cr * sp * cy + -sr * -sy );
up[1] = (cr * sp * sy + -sr * cy );
up[2] = (cr * cp);
}
}
/*
=================
VectorAngles
@@ -248,6 +384,39 @@ void VectorsAngles( const vec3_t forward, const vec3_t right, const vec3_t up, v
//
// bounds operations
//
/*
=================
AddPointToBounds
=================
*/
void AddPointToBounds( const vec3_t v, vec3_t mins, vec3_t maxs )
{
float val;
int i;
for( i = 0; i < 3; i++ )
{
val = v[i];
if( val < mins[i] ) mins[i] = val;
if( val > maxs[i] ) maxs[i] = val;
}
}
/*
=================
ExpandBounds (not used anywhere?)
=================
*/
void ExpandBounds( vec3_t mins, vec3_t maxs, float offset )
{
mins[0] -= offset;
mins[1] -= offset;
mins[2] -= offset;
maxs[0] += offset;
maxs[1] += offset;
maxs[2] += offset;
}
/*
=================
SphereIntersect
@@ -288,9 +457,67 @@ void PlaneIntersect( const mplane_t *plane, const vec3_t p0, const vec3_t p1, ve
VectorMA( p0, sect, p1, out );
}
/*
=================
RadiusFromBounds
=================
*/
float RadiusFromBounds( const vec3_t mins, const vec3_t maxs )
{
vec3_t corner;
int i;
for( i = 0; i < 3; i++ )
{
corner[i] = fabs( mins[i] ) > fabs( maxs[i] ) ? fabs( mins[i] ) : fabs( maxs[i] );
}
return VectorLength( corner );
}
//
// studio utils
//
/*
====================
AngleQuaternion
====================
*/
void AngleQuaternion( const vec3_t angles, vec4_t q, qboolean studio )
{
float sr, sp, sy, cr, cp, cy;
if( studio )
{
SinCos( angles[ROLL] * 0.5f, &sy, &cy );
SinCos( angles[YAW] * 0.5f, &sp, &cp );
SinCos( angles[PITCH] * 0.5f, &sr, &cr );
}
else
{
SinCos( DEG2RAD( angles[YAW] ) * 0.5f, &sy, &cy );
SinCos( DEG2RAD( angles[PITCH] ) * 0.5f, &sp, &cp );
SinCos( DEG2RAD( angles[ROLL] ) * 0.5f, &sr, &cr );
}
q[0] = sr * cp * cy - cr * sp * sy; // X
q[1] = cr * sp * cy + sr * cp * sy; // Y
q[2] = cr * cp * sy - sr * sp * cy; // Z
q[3] = cr * cp * cy + sr * sp * sy; // W
}
/*
====================
QuaternionAngle
====================
*/
void QuaternionAngle( const vec4_t q, vec3_t angles )
{
matrix3x4 mat;
Matrix3x4_FromOriginQuat( mat, q, vec3_origin );
Matrix3x4_AnglesFromMatrix( mat, angles );
}
/*
====================
@@ -453,6 +680,25 @@ int BoxOnPlaneSide( const vec3_t emins, const vec3_t emaxs, const mplane_t *p )
return sides;
}
/*
====================
StudioSlerpBones
====================
*/
void R_StudioSlerpBones( int numbones, vec4_t q1[], float pos1[][3], const vec4_t q2[], const float pos2[][3], float s )
{
int i;
s = bound( 0.0f, s, 1.0f );
for( i = 0; i < numbones; i++ )
{
QuaternionSlerp( q1[i], q2[i], s, q1[i] );
VectorLerp( pos1[i], s, pos2[i], pos1[i] );
}
}
/*
====================
StudioCalcBoneQuaternion

View File

@@ -23,65 +23,74 @@ GNU General Public License for more details.
#include "build.h"
#include "xash3d_types.h"
/*
===========================
CONSTANTS AND HELPER MACROS
===========================
*/
#include "const.h"
#include "com_model.h"
#include "studio.h"
// euler angle order
#define PITCH 0
#define YAW 1
#define ROLL 2
#define PITCH 0
#define YAW 1
#define ROLL 2
#ifndef M_PI
#define M_PI (double)3.14159265358979323846
#define M_PI (double)3.14159265358979323846
#endif
#define M_PI2 ((double)(M_PI * 2))
#define M_PI_F ((float)(M_PI))
#define M_PI2_F ((float)(M_PI2))
#ifndef M_PI2
#define M_PI2 ((double)(M_PI * 2))
#endif
#define RAD2DEG( x ) ((double)(x) * (double)(180.0 / M_PI))
#define DEG2RAD( x ) ((double)(x) * (double)(M_PI / 180.0))
#define M_PI_F ((float)(M_PI))
#define M_PI2_F ((float)(M_PI2))
#define NUMVERTEXNORMALS 162
#define RAD2DEG( x ) ((double)(x) * (double)(180.0 / M_PI))
#define DEG2RAD( x ) ((double)(x) * (double)(M_PI / 180.0))
#define BOGUS_RANGE ((vec_t)114032.64) // world.size * 1.74
#define NUMVERTEXNORMALS 162
#define SIDE_FRONT 0
#define SIDE_BACK 1
#define SIDE_ON 2
#define SIDE_CROSS -2
#define BOGUS_RANGE ((vec_t)114032.64) // world.size * 1.74
#define PLANE_X 0 // 0 - 2 are axial planes
#define PLANE_Y 1 // 3 needs alternate calc
#define PLANE_Z 2
#define PLANE_NONAXIAL 3
#define SIDE_FRONT 0
#define SIDE_BACK 1
#define SIDE_ON 2
#define SIDE_CROSS -2
#define EQUAL_EPSILON 0.001f
#define STOP_EPSILON 0.1f
#define ON_EPSILON 0.1f
#define PLANE_X 0 // 0 - 2 are axial planes
#define PLANE_Y 1 // 3 needs alternate calc
#define PLANE_Z 2
#define PLANE_NONAXIAL 3
#define RAD_TO_STUDIO (32768.0 / M_PI)
#define STUDIO_TO_RAD (M_PI / 32768.0)
#define EQUAL_EPSILON 0.001f
#define STOP_EPSILON 0.1f
#define ON_EPSILON 0.1f
#define INV127F ( 1.0f / 127.0f )
#define INV255F ( 1.0f / 255.0f )
#define MAKE_SIGNED( x ) ((( x ) * INV127F ) - 1.0f )
#define RAD_TO_STUDIO (32768.0 / M_PI)
#define STUDIO_TO_RAD (M_PI / 32768.0)
#define Q_min( a, b ) (((a) < (b)) ? (a) : (b))
#define Q_max( a, b ) (((a) > (b)) ? (a) : (b))
#define INV127F ( 1.0f / 127.0f )
#define INV255F ( 1.0f / 255.0f )
#define MAKE_SIGNED( x ) ((( x ) * INV127F ) - 1.0f )
#define Q_min( a, b ) (((a) < (b)) ? (a) : (b))
#define Q_max( a, b ) (((a) > (b)) ? (a) : (b))
#define Q_equal_e( a, b, e ) (((a) >= ((b) - (e))) && ((a) <= ((b) + (e))))
#define Q_equal( a, b ) Q_equal_e( a, b, EQUAL_EPSILON )
#define Q_floor( a ) ((float)(int)(a))
#define Q_ceil( a ) ((float)(int)((a) + 1))
#define Q_round( x, y ) (floor( x / y + 0.5f ) * y )
#define Q_rint(x) ((x) < 0.0f ? ((int)((x)-0.5f)) : ((int)((x)+0.5f)))
#define ALIGN( x, a ) ((( x ) + (( size_t )( a ) - 1 )) & ~(( size_t )( a ) - 1 ))
#define Q_recip( a ) ((float)(1.0f / (float)(a)))
#define Q_floor( a ) ((float)(int)(a))
#define Q_ceil( a ) ((float)(int)((a) + 1))
#define Q_round( x, y ) (floor( x / y + 0.5f ) * y )
#define Q_rint(x) ((x) < 0.0f ? ((int)((x)-0.5f)) : ((int)((x)+0.5f)))
#ifdef XASH_IRIX
#undef isnan
#endif
#ifdef isnan // check for C99 isnan
#define IS_NAN isnan
#else
#define IS_NAN(x) (((*(int *)&x) & (255<<23)) == (255<<23))
#endif
#define ALIGN( x, a ) ((( x ) + (( size_t )( a ) - 1 )) & ~(( size_t )( a ) - 1 ))
#define VectorIsNAN(v) (IS_NAN(v[0]) || IS_NAN(v[1]) || IS_NAN(v[2]))
#define DotProduct(x,y) ((x)[0]*(y)[0]+(x)[1]*(y)[1]+(x)[2]*(y)[2])
@@ -109,11 +118,8 @@ CONSTANTS AND HELPER MACROS
#define Vector2Average(a,b,o) ((o)[0]=((a)[0]+(b)[0])*0.5f,(o)[1]=((a)[1]+(b)[1])*0.5f)
#define VectorAverage(a,b,o) ((o)[0]=((a)[0]+(b)[0])*0.5f,(o)[1]=((a)[1]+(b)[1])*0.5f,(o)[2]=((a)[2]+(b)[2])*0.5f)
#define Vector2Set(v, x, y) ((v)[0]=(x),(v)[1]=(y))
#define Vector2Unpack(v, x, y) ((x)=(v)[0],(y)=(v)[1])
#define VectorSet(v, x, y, z) ((v)[0]=(x),(v)[1]=(y),(v)[2]=(z))
#define VectorUnpack(v, x, y, z) ((x)=(v)[0],(y)=(v)[1],(z)=(v)[2])
#define Vector4Set(v, a, b, c, d) ((v)[0]=(a),(v)[1]=(b),(v)[2]=(c),(v)[3]=(d))
#define Vector4Unpack(v, a, b, c, d) ((a)=(v)[0],(b)=(v)[1],(c)=(v)[2],(d)=(v)[3])
#define Vector4Set(v, a, b, c, d) ((v)[0]=(a),(v)[1]=(b),(v)[2]=(c),(v)[3] = (d))
#define VectorClear(x) ((x)[0]=(x)[1]=(x)[2]=0)
#define Vector2Lerp( v1, lerp, v2, c ) ((c)[0] = (v1)[0] + (lerp) * ((v2)[0] - (v1)[0]), (c)[1] = (v1)[1] + (lerp) * ((v2)[1] - (v1)[1]))
#define VectorLerp( v1, lerp, v2, c ) ((c)[0] = (v1)[0] + (lerp) * ((v2)[0] - (v1)[0]), (c)[1] = (v1)[1] + (lerp) * ((v2)[1] - (v1)[1]), (c)[2] = (v1)[2] + (lerp) * ((v2)[2] - (v1)[2]))
@@ -132,95 +138,9 @@ CONSTANTS AND HELPER MACROS
#define PlaneDiff(point,plane) (((plane)->type < 3 ? (point)[(plane)->type] : DotProduct((point), (plane)->normal)) - (plane)->dist)
#define bound( min, num, max ) ((num) >= (min) ? ((num) < (max) ? (num) : (max)) : (min))
/*
===========================
CONSTANTS GLOBALS
===========================
*/
// a1ba: we never return pointers to these globals
// so help compiler optimize constants away
#define vec3_origin ((vec3_t){ 0.0f, 0.0f, 0.0f })
#define m_matrix3x4_identity ((matrix3x4) { \
{ 1.0f, 0.0f, 0.0f, 0.0f }, \
{ 0.0f, 1.0f, 0.0f, 0.0f }, \
{ 0.0f, 0.0f, 1.0f, 0.0f }} )
#define m_matrix4x4_identity ((matrix4x4) { \
{ 1.0f, 0.0f, 0.0f, 0.0f }, \
{ 0.0f, 1.0f, 0.0f, 0.0f }, \
{ 0.0f, 0.0f, 1.0f, 0.0f }, \
{ 0.0f, 0.0f, 0.0f, 1.0f }} )
extern const int boxpnt[6][4];
extern const float m_bytenormals[NUMVERTEXNORMALS][3];
/*
===========================
MATH FUNCTIONS
===========================
*/
typedef struct mplane_s mplane_t;
typedef struct mstudiobone_s mstudiobone_t;
typedef struct mstudioanim_s mstudioanim_t;
float rsqrt( float number );
uint16_t FloatToHalf( float v );
float HalfToFloat( uint16_t h );
void RoundUpHullSize( vec3_t size );
void VectorVectors( const vec3_t forward, vec3_t right, vec3_t up );
void VectorAngles( const float *forward, float *angles );
void VectorsAngles( const vec3_t forward, const vec3_t right, const vec3_t up, vec3_t angles );
void PlaneIntersect( const mplane_t *plane, const vec3_t p0, const vec3_t p1, vec3_t out );
qboolean SphereIntersect( const vec3_t vSphereCenter, float fSphereRadiusSquared, const vec3_t vLinePt, const vec3_t vLineDir );
void QuaternionSlerp( const vec4_t p, const vec4_t q, float t, vec4_t qt );
void R_StudioCalcBoneQuaternion( int frame, float s, const mstudiobone_t *pbone, const mstudioanim_t *panim, const float *adj, vec4_t q );
void R_StudioCalcBonePosition( int frame, float s, const mstudiobone_t *pbone, const mstudioanim_t *panim, const vec3_t adj, vec3_t pos );
int BoxOnPlaneSide( const vec3_t emins, const vec3_t emaxs, const mplane_t *p );
#define BOX_ON_PLANE_SIDE( emins, emaxs, p ) \
((( p )->type < 3 ) ? \
( \
((p)->dist <= (emins)[(p)->type]) ? 1 : \
( \
((p)->dist >= (emaxs)[(p)->type] ) ? 2 : 3 \
) \
) : BoxOnPlaneSide(( emins ), ( emaxs ), ( p )))
//
// matrixlib.c
//
#define Matrix3x4_LoadIdentity( mat ) Matrix3x4_Copy( mat, m_matrix3x4_identity )
#define Matrix3x4_Copy( out, in ) memcpy( out, in, sizeof( matrix3x4 ))
void Matrix3x4_VectorTransform( const matrix3x4 in, const float v[3], float out[3] );
void Matrix3x4_VectorITransform( const matrix3x4 in, const float v[3], float out[3] );
void Matrix3x4_VectorRotate( const matrix3x4 in, const float v[3], float out[3] );
void Matrix3x4_VectorIRotate( const matrix3x4 in, const float v[3], float out[3] );
void Matrix3x4_ConcatTransforms( matrix3x4 out, const matrix3x4 in1, const matrix3x4 in2 );
void Matrix3x4_FromOriginQuat( matrix3x4 out, const vec4_t quaternion, const vec3_t origin );
void Matrix3x4_CreateFromEntity( matrix3x4 out, const vec3_t angles, const vec3_t origin, float scale );
void Matrix3x4_TransformAABB( const matrix3x4 world, const vec3_t mins, const vec3_t maxs, vec3_t absmin, vec3_t absmax );
void Matrix3x4_AnglesFromMatrix( const matrix3x4 in, vec3_t out );
#define Matrix4x4_LoadIdentity( mat ) Matrix4x4_Copy( mat, m_matrix4x4_identity )
#define Matrix4x4_Copy( out, in ) memcpy( out, in, sizeof( matrix4x4 ))
void Matrix4x4_VectorTransform( const matrix4x4 in, const float v[3], float out[3] );
void Matrix4x4_VectorITransform( const matrix4x4 in, const float v[3], float out[3] );
void Matrix4x4_VectorRotate( const matrix4x4 in, const float v[3], float out[3] );
void Matrix4x4_VectorIRotate( const matrix4x4 in, const float v[3], float out[3] );
void Matrix4x4_ConcatTransforms( matrix4x4 out, const matrix4x4 in1, const matrix4x4 in2 );
void Matrix4x4_CreateFromEntity( matrix4x4 out, const vec3_t angles, const vec3_t origin, float scale );
void Matrix4x4_TransformPositivePlane( const matrix4x4 in, const vec3_t normal, float d, vec3_t out, float *dist );
void Matrix4x4_ConvertToEntity( const matrix4x4 in, vec3_t angles, vec3_t origin );
void Matrix4x4_Invert_Simple( matrix4x4 out, const matrix4x4 in1 );
qboolean Matrix4x4_Invert_Full( matrix4x4 out, const matrix4x4 in1 );
// horrible cast but helps not breaking strict aliasing in mathlib
// as union type punning should be fine in C but not in C++
// so don't carry over this to C++ code
#ifndef __cplusplus
typedef union
{
float fl;
@@ -253,98 +173,28 @@ static inline float UintAsFloat( uint32_t u )
bits.u = u;
return bits.fl;
}
#endif // __cplusplus
// isnan implementation is broken on IRIX as reported in https://github.com/FWGS/xash3d-fwgs/pull/1211
#if defined( XASH_IRIX ) || !defined( isnan )
static inline int IS_NAN( float x )
{
int32_t i = FloatAsInt( x ); // only C
return i & ( 255 << 23 ) == ( 255 << 23 );
}
#else
#define IS_NAN isnan
#endif
static inline float anglemod( float a )
{
a = (360.0f / 65536) * ((int)(a*(65536/360.0f)) & 65535);
return a;
}
static inline void SinCos( float radians, float *sine, float *cosine )
{
*sine = sin( radians );
*cosine = cos( radians );
*sine = sin(radians);
*cosine = cos(radians);
}
static inline int NearestPOW( int value, qboolean roundDown )
{
int n = 1;
if( value <= 0 ) return 1;
while( n < value ) n <<= 1;
if( roundDown )
{
if( n > value ) n >>= 1;
}
return n;
}
static inline qboolean VectorCompareEpsilon( const vec3_t vec1, const vec3_t vec2, vec_t epsilon )
{
vec_t ax = fabs( vec1[0] - vec2[0] );
vec_t ay = fabs( vec1[1] - vec2[1] );
vec_t az = fabs( vec1[2] - vec2[2] );
return ( ax <= epsilon ) && ( ay <= epsilon ) && ( az <= epsilon ) ? true : false;
}
static inline float VectorNormalizeLength2( const vec3_t v, vec3_t out )
{
float length = VectorLength( v );
if( length )
{
float ilength = 1.0f / length;
out[0] = v[0] * ilength;
out[1] = v[1] * ilength;
out[2] = v[2] * ilength;
}
return length;
}
static inline void GAME_EXPORT AngleVectors( const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up )
{
float sr, sp, sy, cr, cp, cy;
SinCos( DEG2RAD( angles[YAW] ), &sy, &cy );
SinCos( DEG2RAD( angles[PITCH] ), &sp, &cp );
SinCos( DEG2RAD( angles[ROLL] ), &sr, &cr );
if( forward )
{
forward[0] = cp * cy;
forward[1] = cp * sy;
forward[2] = -sp;
}
if( right )
{
right[0] = (-1.0f * sr * sp * cy + -1.0f * cr * -sy );
right[1] = (-1.0f * sr * sp * sy + -1.0f * cr * cy );
right[2] = (-1.0f * sr * cp);
}
if( up )
{
up[0] = (cr * sp * cy + -sr * -sy );
up[1] = (cr * sp * sy + -sr * cy );
up[2] = (cr * cp);
}
}
float rsqrt( float number );
float anglemod( float a );
word FloatToHalf( float v );
float HalfToFloat( word h );
void RoundUpHullSize( vec3_t size );
int SignbitsForPlane( const vec3_t normal );
int PlaneTypeForNormal( const vec3_t normal );
int NearestPOW( int value, qboolean roundDown );
float VectorNormalizeLength2( const vec3_t v, vec3_t out );
qboolean VectorCompareEpsilon( const vec3_t vec1, const vec3_t vec2, vec_t epsilon );
void VectorVectors( const vec3_t forward, vec3_t right, vec3_t up );
void VectorAngles( const float *forward, float *angles );
void AngleVectors( const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up );
void VectorsAngles( const vec3_t forward, const vec3_t right, const vec3_t up, vec3_t angles );
void PlaneIntersect( const struct mplane_s *plane, const vec3_t p0, const vec3_t p1, vec3_t out );
static inline void ClearBounds( vec3_t mins, vec3_t maxs )
{
@@ -371,85 +221,20 @@ static inline qboolean BoundsAndSphereIntersect( const vec3_t mins, const vec3_t
return true;
}
static inline float RadiusFromBounds( const vec3_t mins, const vec3_t maxs )
{
vec3_t corner;
int i;
void AddPointToBounds( const vec3_t v, vec3_t mins, vec3_t maxs );
qboolean SphereIntersect( const vec3_t vSphereCenter, float fSphereRadiusSquared, const vec3_t vLinePt, const vec3_t vLineDir );
float RadiusFromBounds( const vec3_t mins, const vec3_t maxs );
void ExpandBounds( vec3_t mins, vec3_t maxs, float offset );
for( i = 0; i < 3; i++ )
{
float a = fabs( mins[i] );
float b = fabs( maxs[i] );
corner[i] = Q_max( a, b );
}
void AngleQuaternion( const vec3_t angles, vec4_t q, qboolean studio );
void QuaternionAngle( const vec4_t q, vec3_t angles );
void QuaternionSlerp( const vec4_t p, const vec4_t q, float t, vec4_t qt );
return VectorLength( corner );
}
static inline void AddPointToBounds( const vec3_t v, vec3_t mins, vec3_t maxs )
{
int i;
for( i = 0; i < 3; i++ )
{
float val = v[i];
if( val < mins[i] ) mins[i] = val;
if( val > maxs[i] ) maxs[i] = val;
}
}
static inline void ExpandBounds( vec3_t mins, vec3_t maxs, float offset )
{
mins[0] -= offset;
mins[1] -= offset;
mins[2] -= offset;
maxs[0] += offset;
maxs[1] += offset;
maxs[2] += offset;
}
static inline int SignbitsForPlane( const vec3_t normal )
{
int bits, i;
for( bits = i = 0; i < 3; i++ )
if( normal[i] < 0.0f ) bits |= 1<<i;
return bits;
}
static inline int PlaneTypeForNormal( const vec3_t normal )
{
if( normal[0] == 1.0f )
return PLANE_X;
if( normal[1] == 1.0f )
return PLANE_Y;
if( normal[2] == 1.0f )
return PLANE_Z;
return PLANE_NONAXIAL;
}
static inline void AngleQuaternion( const vec3_t angles, vec4_t q, qboolean studio )
{
float sr, sp, sy, cr, cp, cy;
if( studio )
{
SinCos( angles[ROLL] * 0.5f, &sy, &cy );
SinCos( angles[YAW] * 0.5f, &sp, &cp );
SinCos( angles[PITCH] * 0.5f, &sr, &cr );
}
else
{
SinCos( DEG2RAD( angles[YAW] ) * 0.5f, &sy, &cy );
SinCos( DEG2RAD( angles[PITCH] ) * 0.5f, &sp, &cp );
SinCos( DEG2RAD( angles[ROLL] ) * 0.5f, &sr, &cr );
}
q[0] = sr * cp * cy - cr * sp * sy; // X
q[1] = cr * sp * cy + sr * cp * sy; // Y
q[2] = cr * cp * sy - sr * sp * cy; // Z
q[3] = cr * cp * cy + sr * sp * sy; // W
}
//
// matrixlib.c
//
#define Matrix3x4_LoadIdentity( mat ) Matrix3x4_Copy( mat, m_matrix3x4_identity )
#define Matrix3x4_Copy( out, in ) memcpy( out, in, sizeof( matrix3x4 ))
static inline void Matrix3x4_SetOrigin( matrix3x4 out, float x, float y, float z )
{
@@ -465,23 +250,56 @@ static inline void Matrix3x4_OriginFromMatrix( const matrix3x4 in, float *out )
out[2] = in[2][3];
}
static inline void QuaternionAngle( const vec4_t q, vec3_t angles )
{
matrix3x4 mat;
Matrix3x4_FromOriginQuat( mat, q, vec3_origin );
Matrix3x4_AnglesFromMatrix( mat, angles );
}
void Matrix3x4_VectorTransform( const matrix3x4 in, const float v[3], float out[3] );
void Matrix3x4_VectorITransform( const matrix3x4 in, const float v[3], float out[3] );
void Matrix3x4_VectorRotate( const matrix3x4 in, const float v[3], float out[3] );
void Matrix3x4_VectorIRotate( const matrix3x4 in, const float v[3], float out[3] );
void Matrix3x4_ConcatTransforms( matrix3x4 out, const matrix3x4 in1, const matrix3x4 in2 );
void Matrix3x4_FromOriginQuat( matrix3x4 out, const vec4_t quaternion, const vec3_t origin );
void Matrix3x4_CreateFromEntity( matrix3x4 out, const vec3_t angles, const vec3_t origin, float scale );
void Matrix3x4_TransformAABB( const matrix3x4 world, const vec3_t mins, const vec3_t maxs, vec3_t absmin, vec3_t absmax );
void Matrix3x4_AnglesFromMatrix( const matrix3x4 in, vec3_t out );
static inline void R_StudioSlerpBones( int numbones, vec4_t q1[], float pos1[][3], const vec4_t q2[], const float pos2[][3], float s )
{
int i;
s = bound( 0.0f, s, 1.0f );
#define Matrix4x4_LoadIdentity( mat ) Matrix4x4_Copy( mat, m_matrix4x4_identity )
#define Matrix4x4_Copy( out, in ) memcpy( out, in, sizeof( matrix4x4 ))
for( i = 0; i < numbones; i++ )
{
QuaternionSlerp( q1[i], q2[i], s, q1[i] );
VectorLerp( pos1[i], s, pos2[i], pos1[i] );
}
}
void Matrix4x4_VectorTransform( const matrix4x4 in, const float v[3], float out[3] );
void Matrix4x4_VectorITransform( const matrix4x4 in, const float v[3], float out[3] );
void Matrix4x4_VectorRotate( const matrix4x4 in, const float v[3], float out[3] );
void Matrix4x4_VectorIRotate( const matrix4x4 in, const float v[3], float out[3] );
void Matrix4x4_ConcatTransforms( matrix4x4 out, const matrix4x4 in1, const matrix4x4 in2 );
void Matrix4x4_CreateFromEntity( matrix4x4 out, const vec3_t angles, const vec3_t origin, float scale );
void Matrix4x4_TransformPositivePlane( const matrix4x4 in, const vec3_t normal, float d, vec3_t out, float *dist );
void Matrix4x4_ConvertToEntity( const matrix4x4 in, vec3_t angles, vec3_t origin );
void Matrix4x4_Invert_Simple( matrix4x4 out, const matrix4x4 in1 );
qboolean Matrix4x4_Invert_Full( matrix4x4 out, const matrix4x4 in1 );
void R_StudioSlerpBones( int numbones, vec4_t q1[], float pos1[][3], const vec4_t q2[], const float pos2[][3], float s );
void R_StudioCalcBoneQuaternion( int frame, float s, const mstudiobone_t *pbone, const mstudioanim_t *panim, const float *adj, vec4_t q );
void R_StudioCalcBonePosition( int frame, float s, const mstudiobone_t *pbone, const mstudioanim_t *panim, const vec3_t adj, vec3_t pos );
int BoxOnPlaneSide( const vec3_t emins, const vec3_t emaxs, const mplane_t *p );
#define BOX_ON_PLANE_SIDE( emins, emaxs, p ) \
((( p )->type < 3 ) ? \
( \
((p)->dist <= (emins)[(p)->type]) ? \
1 \
: \
( \
((p)->dist >= (emaxs)[(p)->type]) ? \
2 \
: \
3 \
) \
) \
: \
BoxOnPlaneSide(( emins ), ( emaxs ), ( p )))
extern vec3_t vec3_origin;
extern int boxpnt[6][4];
extern const matrix3x4 m_matrix3x4_identity;
extern const matrix4x4 m_matrix4x4_identity;
extern const float m_bytenormals[NUMVERTEXNORMALS][3];
#endif // XASH3D_MATHLIB_H

View File

@@ -27,16 +27,6 @@ ref_globals_t *gpGlobals;
ref_client_t *gp_cl;
ref_host_t *gp_host;
void _Mem_Free( void *data, const char *filename, int fileline )
{
gEngfuncs._Mem_Free( data, filename, fileline );
}
void *_Mem_Alloc( poolhandle_t poolptr, size_t size, qboolean clear, const char *filename, int fileline )
{
return gEngfuncs._Mem_Alloc( poolptr, size, clear, filename, fileline );
}
static void R_ClearScreen( void )
{
pglClearColor( 0.0f, 0.0f, 0.0f, 0.0f );

View File

@@ -445,9 +445,6 @@ void R_GenerateVBO( void );
void R_ClearVBO( void );
void R_AddDecalVBO( decal_t *pdecal, msurface_t *surf );
void R_LightmapCoord( const vec3_t v, const msurface_t *surf, const float sample_size, vec2_t coords );
qboolean R_HasGeneratedVBO( void );
void R_EnableVBO( qboolean enable );
qboolean R_HasEnabledVBO( void );
//
// gl_rpart.c
@@ -497,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"
@@ -752,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;
@@ -782,14 +781,10 @@ DECLARE_ENGINE_SHARED_CVAR_LIST()
//
#include "crtlib.h"
void _Mem_Free( void *data, const char *filename, int fileline );
void *_Mem_Alloc( poolhandle_t poolptr, size_t size, qboolean clear, const char *filename, int fileline )
ALLOC_CHECK( 2 ) MALLOC_LIKE( _Mem_Free, 1 ) WARN_UNUSED_RESULT;
#define Mem_Malloc( pool, size ) _Mem_Alloc( pool, size, false, __FILE__, __LINE__ )
#define Mem_Calloc( pool, size ) _Mem_Alloc( pool, size, true, __FILE__, __LINE__ )
#define Mem_Malloc( pool, size ) gEngfuncs._Mem_Alloc( pool, size, false, __FILE__, __LINE__ )
#define Mem_Calloc( pool, size ) gEngfuncs._Mem_Alloc( pool, size, true, __FILE__, __LINE__ )
#define Mem_Realloc( pool, ptr, size ) gEngfuncs._Mem_Realloc( pool, ptr, size, true, __FILE__, __LINE__ )
#define Mem_Free( mem ) _Mem_Free( mem, __FILE__, __LINE__ )
#define Mem_Free( mem ) gEngfuncs._Mem_Free( mem, __FILE__, __LINE__ )
#define Mem_AllocPool( name ) gEngfuncs._Mem_AllocPool( name, __FILE__, __LINE__ )
#define Mem_FreePool( pool ) gEngfuncs._Mem_FreePool( pool, __FILE__, __LINE__ )
#define Mem_EmptyPool( pool ) gEngfuncs._Mem_EmptyPool( pool, __FILE__, __LINE__ )

View File

@@ -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" );
@@ -742,8 +745,10 @@ static void R_RenderInfo_f( void )
gEngfuncs.Con_Printf( "GL4ES_VERSION: %s\n", version );
if( extensions )
gEngfuncs.Con_Reportf( "GL4ES_EXTENSIONS: %s\n", extensions );
}
gEngfuncs.Con_Printf( "GL_MAX_TEXTURE_SIZE: %i\n", glConfig.max_2d_texture_size );
if( GL_Support( GL_ARB_MULTITEXTURE ))
@@ -1148,10 +1153,6 @@ void GL_InitExtensions( void )
gEngfuncs.Cvar_SetValue( "gl_finish", 1 );
#endif
// we do not want to write vbo code that does not use multitexture
if( !GL_Support( GL_ARB_VERTEX_BUFFER_OBJECT_EXT ) || !GL_Support( GL_ARB_MULTITEXTURE ) || glConfig.max_texture_units < 2 )
gEngfuncs.Cvar_FullSet( "gl_vbo", "0", FCVAR_READ_ONLY );
R_RenderInfo_f();
tr.framecount = tr.visframecount = 1;
@@ -1209,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 );

View File

@@ -1010,32 +1010,29 @@ void R_GammaChanged( qboolean do_reset_gamma )
}
}
static void R_CheckCvars( void )
static void R_CheckGamma( void )
{
qboolean rebuild = false;
if( FBitSet( gl_overbright.flags, FCVAR_CHANGED ))
{
rebuild = true;
ClearBits( gl_overbright.flags, FCVAR_CHANGED );
rebuild = true;
}
if( FBitSet( r_vbo.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 );
R_EnableVBO( r_vbo.value ? true : false );
if( R_HasEnabledVBO( ))
R_GenerateVBO();
if( gl_overbright.value )
rebuild = true;
ClearBits( r_vbo_overbrightmode.flags, FCVAR_CHANGED );
}
if( FBitSet( r_vbo_overbrightmode.flags, FCVAR_CHANGED ) && gl_overbright.value )
// 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 ))
{
ClearBits( r_vbo_overbrightmode.flags, FCVAR_CHANGED );
rebuild = true;
ClearBits( gl_litwater_scale.flags, FCVAR_CHANGED );
ClearBits( gl_litwater_minlight.flags, FCVAR_CHANGED );
}
if( rebuild )
@@ -1057,7 +1054,7 @@ void R_BeginFrame( qboolean clearScene )
pglClear( GL_COLOR_BUFFER_BIT );
}
R_CheckCvars();
R_CheckGamma();
R_Set2DMode( true );

View File

@@ -147,10 +147,7 @@ void R_NewMap( void )
}
GL_BuildLightmaps ();
R_ClearVBO();
if( R_HasEnabledVBO( ))
R_GenerateVBO();
R_GenerateVBO();
R_ResetRipples();
if( gEngfuncs.drawFuncs->R_NewMap != NULL )

View File

@@ -229,9 +229,10 @@ void CL_DrawTracers( double frametime, particle_t *cl_active_tracers )
VectorAdd( verts[0], delta, verts[2] );
VectorAdd( verts[1], delta, verts[3] );
if( p->color < 0 || p->color > sizeof( gTracerColors ) / sizeof( gTracerColors[0] ))
if( p->color > sizeof( gTracerColors ) / sizeof( gTracerColors[0] ))
{
p->color = TRACER_COLORINDEX_DEFAULT;
gEngfuncs.Con_Printf( S_ERROR "UserTracer with color(%d) > %zu\n", p->color, sizeof( gTracerColors ) / sizeof( gTracerColors[0] ));
p->color = 0;
}
color = gTracerColors[p->color];

File diff suppressed because it is too large Load Diff

View File

@@ -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;
}

View File

@@ -23,17 +23,6 @@ gl_globals_t tr;
ref_speeds_t r_stats;
poolhandle_t r_temppool;
viddef_t vid;
void _Mem_Free( void *data, const char *filename, int fileline )
{
gEngfuncs._Mem_Free( data, filename, fileline );
}
void *_Mem_Alloc( poolhandle_t poolptr, size_t size, qboolean clear, const char *filename, int fileline )
{
return gEngfuncs._Mem_Alloc( poolptr, size, clear, filename, fileline );
}
static void GAME_EXPORT R_ClearScreen( void )
{

View File

@@ -1237,14 +1237,10 @@ void R_SetUpWorldTransform (void);
#include "crtlib.h"
#include "crclib.h"
#if 1
void _Mem_Free( void *data, const char *filename, int fileline );
void *_Mem_Alloc( poolhandle_t poolptr, size_t size, qboolean clear, const char *filename, int fileline )
ALLOC_CHECK( 2 ) MALLOC_LIKE( _Mem_Free, 1 ) WARN_UNUSED_RESULT;
#define Mem_Malloc( pool, size ) _Mem_Alloc( pool, size, false, __FILE__, __LINE__ )
#define Mem_Calloc( pool, size ) _Mem_Alloc( pool, size, true, __FILE__, __LINE__ )
#define Mem_Malloc( pool, size ) gEngfuncs._Mem_Alloc( pool, size, false, __FILE__, __LINE__ )
#define Mem_Calloc( pool, size ) gEngfuncs._Mem_Alloc( pool, size, true, __FILE__, __LINE__ )
#define Mem_Realloc( pool, ptr, size ) gEngfuncs._Mem_Realloc( pool, ptr, size, true, __FILE__, __LINE__ )
#define Mem_Free( mem ) _Mem_Free( mem, __FILE__, __LINE__ )
#define Mem_Free( mem ) gEngfuncs._Mem_Free( mem, __FILE__, __LINE__ )
#define Mem_AllocPool( name ) gEngfuncs._Mem_AllocPool( name, __FILE__, __LINE__ )
#define Mem_FreePool( pool ) gEngfuncs._Mem_FreePool( pool, __FILE__, __LINE__ )
#define Mem_EmptyPool( pool ) gEngfuncs._Mem_EmptyPool( pool, __FILE__, __LINE__ )

View File

@@ -236,9 +236,10 @@ void GAME_EXPORT CL_DrawTracers( double frametime, particle_t *cl_active_tracers
VectorAdd( verts[0], delta, verts[2] );
VectorAdd( verts[1], delta, verts[3] );
if( p->color < 0 || p->color > sizeof( gTracerColors ) / sizeof( gTracerColors[0] ))
if( p->color > sizeof( gTracerColors ) / sizeof( gTracerColors[0] ))
{
p->color = TRACER_COLORINDEX_DEFAULT;
gEngfuncs.Con_Printf( S_ERROR "UserTracer with color(%d) > %zu\n", p->color, sizeof( gTracerColors ) / sizeof( gTracerColors[0] ));
p->color = 0;
}
color = gTracerColors[p->color];

View File

@@ -27,7 +27,7 @@ WINSDK_LATEST=$(ls -1 "C:/Program Files (x86)/Windows Kits/10/bin" | grep -E '^1
echo "Latest installed Windows SDK is $WINSDK_LATEST"
"C:/Program Files (x86)/Windows Kits/10/bin/$WINSDK_LATEST/x64/signtool.exe" \
sign //f scripts/fwgs.pfx //fd SHA256 //p "$FWGS_PFX_PASSWORD" *.dll *.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 .

View File

@@ -81,7 +81,6 @@ SUBDIRS = [
Subproject('ref/null', lambda x: not x.env.DEDICATED and x.env.NULL),
Subproject('3rdparty/mainui', lambda x: not x.env.DEDICATED),
Subproject('3rdparty/vgui_support', lambda x: not x.env.DEDICATED),
# Subproject('3rdparty/freevgui', lambda x: not x.env.DEDICATED),
Subproject('stub/client', lambda x: not x.env.DEDICATED),
Subproject('game_launch', lambda x: not x.env.DISABLE_LAUNCHER),
@@ -228,10 +227,12 @@ def configure(conf):
elif conf.env.DEST_OS == 'nswitch':
conf.options.NO_VGUI = True
conf.options.GL = True
conf.options.NO_ASYNC_RESOLVE = True
conf.options.USE_STBTT = True
elif conf.env.DEST_OS == 'psvita':
conf.options.NO_VGUI = True
conf.options.GL = True
conf.options.NO_ASYNC_RESOLVE = True
conf.options.USE_STBTT = True
# we'll specify -fPIC by hand for shared libraries only
enforce_pic = False
@@ -306,10 +307,9 @@ def configure(conf):
'-Werror=alloc-size',
'-Werror=bool-compare',
'-Werror=bool-operation',
# '-Werror=cast-align=strict',
'-Werror=cast-align=strict',
'-Werror=duplicated-cond',
'-Werror=format-extra-args',
'-Werror=free-nonheap-object',
'-Werror=implicit-fallthrough=2',
'-Werror=logical-op',
'-Werror=nonnull',
@@ -334,7 +334,6 @@ def configure(conf):
'-Wformat=2',
'-Winit-self',
'-Wmisleading-indentation',
'-Wmismatched-dealloc',
'-Wstringop-overflow',
'-Wunintialized',