Compare commits

..

1 Commits

Author SHA1 Message Date
Alibek Omarov
ca7f19067e gha: first attempt at signing binaries 2024-08-18 13:24:29 +03:00
38 changed files with 684 additions and 511 deletions

View File

@@ -543,8 +543,14 @@ typedef struct
#define MAX_CLIENT_SPRITES 512 // SpriteTextures (0-256 hud, 256-512 client)
#define MAX_REQUESTS 64
STATIC_CHECK_SIZEOF( mextrasurf_t, 324, 496 );
STATIC_CHECK_SIZEOF( decal_t, 60, 88 );
STATIC_CHECK_SIZEOF( mfaceinfo_t, 176, 304 );
#if ! XASH_64BIT
STATIC_ASSERT( sizeof( mextrasurf_t ) == 324, "mextrasurf_t unexpected size" );
STATIC_ASSERT( sizeof( decal_t ) == 60, "decal_t unexpected size");
STATIC_ASSERT( sizeof( mfaceinfo_t ) == 176, "mfaceinfo_t unexpected size");
#else
STATIC_ASSERT( sizeof( mextrasurf_t) == 496, "mextrasurf_t unexpected size");
STATIC_ASSERT( sizeof( decal_t ) == 88, "decal_t unexpected size");
STATIC_ASSERT( sizeof( mfaceinfo_t ) == 304, "mfaceinfo_t unexpected size");
#endif
#endif//COM_MODEL_H

View File

@@ -14,9 +14,6 @@
****/
#ifndef CONST_H
#define CONST_H
#include <stddef.h> // ptrdiff_t
//
// Constants shared by the engine and dlls
// This header file included by engine files and DLL files.
@@ -724,7 +721,7 @@ enum
};
typedef int func_t;
typedef ptrdiff_t string_t;
typedef int string_t;
typedef unsigned short word;

View File

@@ -1,122 +1,49 @@
/*
cvardef.h - quake cvar definition
Copyright (C) 1997-2001 Id Software, Inc.
Copyright (C) 2024 Alibek Omarov
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
* Use, distribution, and modification of this source code and/or resulting
* object code is restricted to non-commercial enhancements to products from
* Valve LLC. All other use, distribution, or modification is prohibited
* without written permission from Valve LLC.
*
****/
#ifndef CVARDEF_H
#define CVARDEF_H
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
#define FCVAR_ARCHIVE (1<<0) // set to cause it to be saved to vars.rc
#define FCVAR_USERINFO (1<<1) // changes the client's info string
#define FCVAR_SERVER (1<<2) // notifies players when changed
#define FCVAR_EXTDLL (1<<3) // defined by external DLL
#define FCVAR_CLIENTDLL (1<<4) // defined by the client dll
#define FCVAR_PROTECTED (1<<5) // It's a server cvar, but we don't send the data since it's a password, etc. Sends 1 if it's not bland/zero, 0 otherwise as value
#define FCVAR_SPONLY (1<<6) // This cvar cannot be changed by clients connected to a multiplayer server.
#define FCVAR_PRINTABLEONLY (1<<7) // This cvar's string cannot contain unprintable characters ( e.g., used for player name etc ).
#define FCVAR_UNLOGGED (1<<8) // If this is a FCVAR_SERVER, don't log changes to the log file / console if we are creating a log
#define FCVAR_NOEXTRAWHITEPACE (1<<9) // strip trailing/leading white space from this cvar
#define FCVAR_PRIVILEGED (1<<10) // only available in privileged mode
#define FCVAR_FILTERABLE (1<<11) // filtered in unprivileged mode if cl_filterstuffcmd is 1
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// Xash3D extensions
#define FCVAR_GLCONFIG (1<<12) // write it into <renderer>.cfg(see RefAPI)
#define FCVAR_CHANGED (1<<13) // set each time the cvar is changed
#define FCVAR_GAMEUIDLL (1<<14) // defined by the menu DLL
#define FCVAR_CHEAT (1<<15) // can not be changed if cheats are disabled
See the GNU General Public License for more details.
// a1ba: let's reuse higher bits for flags extensions from now on
#define FCVAR_LATCH (1<<30) // notify client what this cvar will be applied only after server restart (but don't does more nothing)
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef CVAR
#define CVAR
#include STDINT_H
#include "xash3d_types.h"
/*
cvar_t variables are used to hold scalar or string variables that can be changed
or displayed at the console or prog code as well as accessed directly
in C code.
The user can access cvars from the console in three ways:
r_draworder prints the current value
r_draworder 0 sets the current value to 0
set r_draworder 0 as above, but creates the cvar if not present
Cvars are restricted from having the same names as commands to keep this
interface from being ambiguous.
The are also occasionally used to communicated information between different
modules of the program.
*/
enum
typedef struct cvar_s
{
// GoldSrc compatibility flags
FCVAR_ARCHIVE = 1 << 0, // set to cause it to be saved to vars.rc
FCVAR_USERINFO = 1 << 1, // added to userinfo when changed
FCVAR_SERVER = 1 << 2, // added to serverinfo when changed, will notify clients by default
FCVAR_EXTDLL = 1 << 3, // defined by server.dll
FCVAR_CLIENTDLL = 1 << 4, // defined by client.dll
FCVAR_PROTECTED = 1 << 5, // private server cvar
FCVAR_SPONLY = 1 << 6, // can be set only in singleplayer
FCVAR_PRINTABLEONLY = 1 << 7, // only allows printable characters
FCVAR_UNLOGGED = 1 << 8, // disables notifying client about server cvar change
FCVAR_NOEXTRAWHITESPACE = 1 << 9, // removes space characters from the beginning and the end of the string
FCVAR_PRIVILEGED = 1 << 10, // only available in privileged mode
FCVAR_FILTERABLE = 1 << 11, // treated as privileged if cl_filterstuffcmd is 1, otherwise ignored
char *name;
char *string;
int flags;
float value;
struct cvar_s *next;
} cvar_t;
// Xash3D public flags
// FCVAR_LATCH = 1 << 11, // deprecated Xash3D flag, conflicts with FCVAR_FILTERABLE. Use another FCVAR_LATCH!
FCVAR_GLCONFIG = 1 << 12, // set to cause it to be saved to <renderer>.cfg (see RefAPI)
FCVAR_CHANGED = 1 << 13, // set each time the cvar changed
FCVAR_GAMEUIDLL = 1 << 14, // defined by menu.dll
FCVAR_CHEAT = 1 << 15, // cannot be changed if sv_cheats is 0
#if REF_DLL || ENGINE_DLL // Xash3D internal flags, MUST NOT be used outside of engine
FCVAR_RENDERINFO = 1 << 16, // set to cause it to be saved to video.cfg
FCVAR_READ_ONLY = 1 << 17, // display only, cannot be set by user at all
FCVAR_EXTENDED = 1 << 18, // extended cvar structure
FCVAR_ALLOCATED = 1 << 19, // allocated by the engine, must be freed with Mem_Free
FCVAR_VIDRESTART = 1 << 20, // triggers video subsystem to recreate/modify window parameters
FCVAR_TEMPORARY = 1 << 21, // only used to temporarly hold some value, can be unlinked
FCVAR_MOVEVARS = 1 << 22, // access to movevars_t structure, synchornized between client and server
FCVAR_USER_CREATED = 1 << 23, // created by a set command
FCVAR_REFDLL = 1 << 29, // (Xash3D FWGS internal flag) defined by the renderer DLL
#endif // REF_DLL || ENGINE_DLL
FCVAR_LATCH = 1 << 30, // (Xash3D FWGS public flag, was FCVAR_FILTERABLE in Xash3D) save changes until server restart
};
struct cvar_s {
char *name;
char *string;
uint32_t flags;
float value;
struct cvar_s *next;
};
typedef struct cvar_s cvar_t;
STATIC_CHECK_SIZEOF( struct cvar_s, 20, 32 );
#if REF_DLL || ENGINE_DLL // Xash3D internal cvar format, MUST NOT be used outside of engine
struct convar_s {
char *name;
char *string;
uint32_t flags;
float value;
struct convar_s *next;
char *desc;
char *def_string;
};
typedef struct convar_s convar_t;
#if XASH_64BIT
#define CVAR_SENTINEL (uintptr_t)0xDEADBEEFDEADBEEF
#else
#define CVAR_SENTINEL (uintptr_t)0xDEADBEEF
#endif
#define CVAR_CHECK_SENTINEL( cv ) ((uintptr_t)(cv)->next == CVAR_SENTINEL)
#define CVAR_DEFINE( cv, cvname, cvstr, cvflags, cvdesc ) \
convar_t cv = { (char*)cvname, (char*)cvstr, cvflags, 0.0f, (void *)CVAR_SENTINEL, (char*)cvdesc, NULL }
#define CVAR_DEFINE_AUTO( cv, cvstr, cvflags, cvdesc ) CVAR_DEFINE( cv, #cv, cvstr, cvflags, cvdesc )
#endif // REF_DLL || ENGINE_DLL
#endif // CVAR
#endif//CVARDEF_H

View File

@@ -30,6 +30,6 @@ typedef struct
int state; // low bit is down state
} kbutton_t;
STATIC_CHECK_SIZEOF( kbutton_t, 12, 12 );
STATIC_ASSERT( sizeof( kbutton_t ) == 12, "kbutton_t isn't 12 bytes!" );
#endif // KBUTTON_H

View File

@@ -69,6 +69,6 @@ typedef struct netadr_s
} netadr_t;
#pragma pack( pop )
STATIC_CHECK_SIZEOF( netadr_t, 20, 20 );
STATIC_ASSERT( sizeof( netadr_t ) == 20, "netadr_t isn't 20 bytes!" );
#endif // NET_ADR_H

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

@@ -130,15 +130,6 @@ typedef uint64_t longtime_t;
#define STATIC_ASSERT( x, y ) STATIC_ASSERT_2( __LINE__, x, y )
#endif
// at least, statically check size of some public structures
#if XASH_64BIT
#define STATIC_CHECK_SIZEOF( type, size32, size64 ) \
STATIC_ASSERT( sizeof( type ) == size64, #type " unexpected size" )
#else
#define STATIC_CHECK_SIZEOF( type, size32, size64 ) \
STATIC_ASSERT( sizeof( type ) == size32, #type " unexpected size" )
#endif
#if !defined( __cplusplus ) && __STDC_VERSION__ >= 199101L // not C++ and C99 or newer
#define XASH_RESTRICT restrict
#elif _MSC_VER || __GNUC__ || __clang__ // compiler-specific extensions

View File

@@ -74,7 +74,7 @@ typedef struct
float size;
} daliashdr_t;
STATIC_CHECK_SIZEOF( daliashdr_t, 84, 84 );
STATIC_ASSERT( sizeof( daliashdr_t ) == 84, "invalid daliashdr_t size" );
typedef struct
{
@@ -83,7 +83,7 @@ typedef struct
int32_t t;
} stvert_t;
STATIC_CHECK_SIZEOF( stvert_t, 12, 12 );
STATIC_ASSERT( sizeof( stvert_t ) == 12, "invalid stvert_t size" );
typedef struct dtriangle_s
{
@@ -91,7 +91,7 @@ typedef struct dtriangle_s
int32_t vertindex[3];
} dtriangle_t;
STATIC_CHECK_SIZEOF( dtriangle_t, 16, 16 );
STATIC_ASSERT( sizeof( dtriangle_t ) == 16, "invalid dtriangle_t size" );
#define DT_FACES_FRONT 0x0010
#define ALIAS_ONSEAM 0x0020
@@ -103,7 +103,7 @@ typedef struct
char name[16]; // frame name from grabbing
} daliasframe_t;
STATIC_CHECK_SIZEOF( daliasframe_t, 24, 24 );
STATIC_ASSERT( sizeof( daliasframe_t ) == 24, "invalid daliasframe_t size" );
typedef struct
{
@@ -112,41 +112,41 @@ typedef struct
trivertex_t bboxmax; // lightnormal isn't used
} daliasgroup_t;
STATIC_CHECK_SIZEOF( daliasgroup_t, 12, 12 );
STATIC_ASSERT( sizeof( daliasgroup_t ) == 12, "invalid daliasgrou_t size" );
typedef struct
{
int32_t numskins;
} daliasskingroup_t;
STATIC_CHECK_SIZEOF( daliasskingroup_t, 4, 4 );
STATIC_ASSERT( sizeof( daliasskingroup_t ) == 4, "invalid daliasskingroup_t size" );
typedef struct
{
float interval;
} daliasinterval_t;
STATIC_CHECK_SIZEOF( daliasinterval_t, 4, 4 );
STATIC_ASSERT( sizeof( daliasinterval_t ) == 4, "invalid daliasinterval_t size" );
typedef struct
{
float interval;
} daliasskininterval_t;
STATIC_CHECK_SIZEOF( daliasskininterval_t, 4, 4 );
STATIC_ASSERT( sizeof( daliasskininterval_t ) == 4, "invalid daliasskininterval_t size" );
typedef struct
{
uint32_t type; // was aliasframetype_t
} daliasframetype_t;
STATIC_CHECK_SIZEOF( daliasframetype_t, 4, 4 );
STATIC_ASSERT( sizeof( daliasframetype_t ) == 4, "invalid daliasframetype_t size" );
typedef struct
{
uint32_t type; // was aliasskintype_t
} daliasskintype_t;
STATIC_CHECK_SIZEOF( daliasskintype_t, 4, 4 );
STATIC_ASSERT( sizeof( daliasskintype_t ) == 4, "invalid daliasskintype_t size" );
#endif//ALIAS_H

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

@@ -171,22 +171,6 @@ static intptr_t pfnEngineGetParm( int parm, int arg )
return CL_RenderGetParm( parm, arg, false ); // prevent recursion
}
static cvar_t *pfnCvar_Get( const char *szName, const char *szValue, int flags, const char *description )
{
return (cvar_t *)Cvar_Get( szName, szValue, flags | FCVAR_REFDLL, description );
}
static void pfnCvar_RegisterVariable( convar_t *var )
{
SetBits( var->flags, FCVAR_REFDLL );
Cvar_RegisterVariable( var );
}
static void pfnCvar_FullSet( const char *var_name, const char *value, int flags )
{
Cvar_FullSet( var_name, value, flags | FCVAR_REFDLL );
}
static void pfnStudioEvent( const mstudioevent_t *event, const cl_entity_t *e )
{
clgame.dllFuncs.pfnStudioEvent( event, e );
@@ -305,14 +289,14 @@ static const ref_api_t gEngfuncs =
{
pfnEngineGetParm,
pfnCvar_Get,
(void*)Cvar_Get,
(void*)Cvar_FindVarExt,
Cvar_VariableValue,
Cvar_VariableString,
Cvar_SetValue,
Cvar_Set,
pfnCvar_RegisterVariable,
pfnCvar_FullSet,
Cvar_RegisterVariable,
Cvar_FullSet,
Cmd_AddRefCommand,
Cmd_RemoveCommand,
@@ -447,7 +431,7 @@ static void R_UnloadProgs( void )
Cvar_FullSet( "host_refloaded", "0", FCVAR_READ_ONLY );
Cvar_Unlink( FCVAR_RENDERINFO | FCVAR_GLCONFIG | FCVAR_REFDLL );
Cvar_Unlink( FCVAR_RENDERINFO | FCVAR_GLCONFIG );
Cmd_Unlink( CMD_REFDLL );
COM_FreeLibrary( ref.hInstance );
@@ -489,7 +473,7 @@ static qboolean R_LoadProgs( const char *name )
if( ref.hInstance ) R_UnloadProgs();
FS_AllowDirectPaths( true );
if( !( ref.hInstance = COM_LoadLibrary( name, false, true )))
if( !(ref.hInstance = COM_LoadLibrary( name, false, true ) ))
{
FS_AllowDirectPaths( false );
Con_Reportf( "%s: can't load renderer library %s: %s\n", __func__, name, COM_GetLibraryError() );
@@ -498,9 +482,11 @@ static qboolean R_LoadProgs( const char *name )
FS_AllowDirectPaths( false );
if( !( GetRefAPI = (REFAPI)COM_GetProcAddress( ref.hInstance, GET_REF_API )))
if( !( GetRefAPI = (REFAPI)COM_GetProcAddress( ref.hInstance, GET_REF_API )) )
{
COM_FreeLibrary( ref.hInstance );
Con_Reportf( "%s: can't find GetRefAPI entry point in %s\n", __func__, name );
ref.hInstance = NULL;
return false;
}
@@ -509,15 +495,19 @@ static qboolean R_LoadProgs( const char *name )
if( GetRefAPI( REF_API_VERSION, &ref.dllFuncs, &gpEngfuncs, &refState ) != REF_API_VERSION )
{
COM_FreeLibrary( ref.hInstance );
Con_Reportf( "%s: can't init renderer API: wrong version\n", __func__ );
ref.hInstance = NULL;
return false;
}
refState.developer = host_developer.value;
if( !ref.dllFuncs.R_Init( ))
if( !ref.dllFuncs.R_Init( ) )
{
COM_FreeLibrary( ref.hInstance );
Con_Reportf( "%s: can't init renderer!\n", __func__ ); //, ref.dllFuncs.R_GetInitError() );
ref.hInstance = NULL;
return false;
}
@@ -644,6 +634,9 @@ static void R_CollectRendererNames( void )
#endif
#if XASH_REF_SOFT_ENABLED
"soft",
#endif
#if XASH_REF_NULL_ENABLED
"null",
#endif
};
@@ -667,6 +660,9 @@ static void R_CollectRendererNames( void )
#endif
#if XASH_REF_SOFT_ENABLED
"Software",
#endif
#if XASH_REF_NULL_ENABLED
"Null Renderer",
#endif
};
@@ -678,8 +674,7 @@ static void R_CollectRendererNames( void )
qboolean R_Init( void )
{
qboolean success = false;
string requested_cmdline;
string requested_cvar;
string requested;
Cvar_RegisterVariable( &gl_vsync );
Cvar_RegisterVariable( &r_showtextures );
@@ -729,16 +724,15 @@ qboolean R_Init( void )
// 1. Command line `-ref` argument.
// 2. `ref_dll` cvar.
// 3. Detected renderers in `DEFAULT_RENDERERS` order.
requested_cmdline[0] = 0;
requested_cvar[0] = 0;
requested[0] = 0;
if( Sys_GetParmFromCmdLine( "-ref", requested_cmdline ))
success = R_LoadRenderer( requested_cmdline );
if( !success && Sys_GetParmFromCmdLine( "-ref", requested ))
success = R_LoadRenderer( requested );
if( !success && COM_CheckString( r_refdll.string ) && Q_stricmp( requested_cmdline, r_refdll.string ))
if( !success && COM_CheckString( r_refdll.string ))
{
Q_strncpy( requested_cvar, r_refdll.string, sizeof( requested_cvar ));
success = R_LoadRenderer( requested_cvar );
Q_strncpy( requested, r_refdll.string, sizeof( requested ));
success = R_LoadRenderer( requested );
}
if( !success )
@@ -748,10 +742,7 @@ qboolean R_Init( void )
for( i = 0; i < ref.numRenderers && !success; i++ )
{
// skip renderer that was requested but failed to load
if( !Q_strcmp( requested_cmdline, ref.shortNames[i] ))
continue;
if( !Q_strcmp( requested_cvar, ref.shortNames[i] ))
if( !Q_strcmp( requested, ref.shortNames[i] ))
continue;
success = R_LoadRenderer( ref.shortNames[i] );
@@ -760,7 +751,7 @@ qboolean R_Init( void )
if( !success )
{
Sys_Error( "Can't initialize any renderer. Check your video drivers!\n" );
Host_Error( "Can't initialize any renderer. Check your video drivers!\n" );
return false;
}

View File

@@ -524,6 +524,9 @@ static void SND_Spatialize( channel_t *ch )
dist = VectorNormalizeLength( source_vec );
dot = DotProduct( s_listener.right, source_vec );
// 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

@@ -387,7 +387,7 @@ static void Cmd_Echo_f( void )
int i;
for( i = 1; i < Cmd_Argc(); i++ )
Con_Printf( "%s ", Cmd_Argv( i ));
Con_Printf( "%s", Cmd_Argv( i ));
Con_Printf( "\n" );
}

View File

@@ -230,7 +230,7 @@ static const char *Cvar_ValidateString( convar_t *var, const char *value )
if( !COM_CheckStringEmpty( szNew ) ) Q_strncpy( szNew, "empty", sizeof( szNew ));
}
if( FBitSet( var->flags, FCVAR_NOEXTRAWHITESPACE ))
if( FBitSet( var->flags, FCVAR_NOEXTRAWHITEPACE ))
{
char *szVal = szNew;
int len = 0;

View File

@@ -18,6 +18,45 @@ GNU General Public License for more details.
#include "cvardef.h"
#ifdef XASH_64BIT
#define CVAR_SENTINEL 0xDEADBEEFDEADBEEF
#else
#define CVAR_SENTINEL 0xDEADBEEF
#endif
#define CVAR_CHECK_SENTINEL( cv ) ((uintptr_t)(cv)->next == CVAR_SENTINEL)
// NOTE: if this is changed, it must be changed in cvardef.h too
typedef struct convar_s
{
// this part shared with cvar_t
char *name;
char *string;
int flags;
float value;
struct convar_s *next;
// this part unique for convar_t
char *desc; // variable descrition info
char *def_string; // keep pointer to initial value
} convar_t;
// cvar internal flags
#define FCVAR_RENDERINFO (1<<16) // save to a seperate config called video.cfg
#define FCVAR_READ_ONLY (1<<17) // cannot be set by user at all, and can't be requested by CvarGetPointer from game dlls
#define FCVAR_EXTENDED (1<<18) // this is convar_t (sets on registration)
#define FCVAR_ALLOCATED (1<<19) // this convar_t is fully dynamic allocated (include description)
#define FCVAR_VIDRESTART (1<<20) // recreate the window is cvar with this flag was changed
#define FCVAR_TEMPORARY (1<<21) // these cvars holds their values and can be unlink in any time
#define FCVAR_MOVEVARS (1<<22) // this cvar is a part of movevars_t struct that shared between client and server
#define FCVAR_USER_CREATED (1<<23) // created by a set command (dll's used)
#define CVAR_DEFINE( cv, cvname, cvstr, cvflags, cvdesc ) \
convar_t cv = { (char*)cvname, (char*)cvstr, cvflags, 0.0f, (void *)CVAR_SENTINEL, (char*)cvdesc, NULL }
#define CVAR_DEFINE_AUTO( cv, cvstr, cvflags, cvdesc ) \
CVAR_DEFINE( cv, #cv, cvstr, cvflags, cvdesc )
#ifndef REF_DLL
cvar_t *Cvar_GetList( void );
#define Cvar_FindVar( name ) Cvar_FindVarExt( name, 0 )
convar_t *Cvar_FindVarExt( const char *var_name, int ignore_group );
@@ -42,5 +81,6 @@ qboolean Cvar_CommandWithPrivilegeCheck( convar_t *v, qboolean isPrivileged );
void Cvar_Init( void );
void Cvar_PostFSInit( void );
void Cvar_Unlink( int group );
#endif // REF_DLL
#endif//CVAR_H

View File

@@ -67,7 +67,7 @@ typedef struct dresource_s
} dresource_t;
#pragma pack( pop )
STATIC_CHECK_SIZEOF( dresource_t, 136, 136 );
STATIC_ASSERT( sizeof( dresource_t ) == 136, "invalid dresource_t size, HPAKs won't be compatible (no custom logo in multiplayer!)" );
typedef struct
{
@@ -76,7 +76,7 @@ typedef struct
int infotableofs;
} hpak_header_t;
STATIC_CHECK_SIZEOF( hpak_header_t, 12, 12 );
STATIC_ASSERT( sizeof( hpak_header_t ) == 12, "invalid hpak_header_t size" );
typedef struct
{
@@ -85,7 +85,7 @@ typedef struct
int disksize;
} hpak_lump_t;
STATIC_CHECK_SIZEOF( hpak_lump_t, 144, 144 );
STATIC_ASSERT( sizeof( hpak_lump_t ) == 144, "invalid hpak_lump_t size" );
typedef struct
{

View File

@@ -126,20 +126,14 @@ dll_user_t *FS_FindLibrary( const char *dllname, qboolean directpath )
=============================================================================
*/
static void COM_GenerateCommonLibraryName( const char *name, const char *ext, const char *suffix, char *out, size_t size )
static void COM_GenerateCommonLibraryName( const char *name, const char *ext, char *out, size_t size )
{
#if ( XASH_WIN32 || XASH_LINUX || XASH_APPLE ) && XASH_X86
if( suffix )
Q_snprintf( out, size, "%s_%s.%s", name, suffix, ext );
else Q_snprintf( out, size, "%s.%s", name, ext );
Q_snprintf( out, size, "%s.%s", name, ext );
#elif ( XASH_WIN32 || XASH_LINUX || XASH_APPLE )
if( suffix )
Q_snprintf( out, size, "%s_%s_%s.%s", name, Q_buildarch(), suffix, ext );
else Q_snprintf( out, size, "%s_%s.%s", name, Q_buildarch(), ext );
Q_snprintf( out, size, "%s_%s.%s", name, Q_buildarch(), ext );
#else
if( suffix )
Q_snprintf( out, size, "%s_%s_%s_%s.%s", name, Q_buildos(), Q_buildarch(), suffix, ext );
else Q_snprintf( out, size, "%s_%s_%s.%s", name, Q_buildos(), Q_buildarch(), ext );
Q_snprintf( out, size, "%s_%s_%s.%s", name, Q_buildos(), Q_buildarch(), ext );
#endif
}
@@ -160,7 +154,7 @@ static void COM_GenerateClientLibraryPath( const char *name, char *out, size_t s
// we don't have any library prefixes, so we can safely append dll_path here
Q_snprintf( dllpath, sizeof( dllpath ), "%s/%s", GI->dll_path, name );
COM_GenerateCommonLibraryName( dllpath, OS_LIB_EXT, NULL, out, size );
COM_GenerateCommonLibraryName( dllpath, OS_LIB_EXT, out, size );
#endif
}
@@ -217,13 +211,7 @@ static void COM_GenerateServerLibraryPath( char *out, size_t size )
COM_StripExtension( dllpath );
COM_StripIntelSuffix( dllpath );
#if XASH_ARCH_USES_ONLY_ABI2
COM_GenerateCommonLibraryName( dllpath, ext, NULL, out, size );
#elif XASH_64BIT
COM_GenerateCommonLibraryName( dllpath, ext, "st64", out, size );
#else
COM_GenerateCommonLibraryName( dllpath, ext, NULL, out, size );
#endif
COM_GenerateCommonLibraryName( dllpath, ext, out, size );
#endif
}

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

@@ -160,6 +160,17 @@ void MSG_InitMasks( void )
ExtraMasks[maskBit] = (uint)BIT( maskBit ) - 1;
}
void MSG_WriteOneBit( sizebuf_t *sb, int nValue )
{
if( !MSG_Overflow( sb, 1 ))
{
if( nValue ) sb->pData[sb->iCurBit>>3] |= BIT( sb->iCurBit & 7 );
else sb->pData[sb->iCurBit>>3] &= ~BIT( sb->iCurBit & 7 );
sb->iCurBit++;
}
}
void MSG_WriteUBitLong( sizebuf_t *sb, uint curData, int numbits )
{
Assert( numbits >= 0 && numbits <= 32 );

View File

@@ -173,17 +173,7 @@ void MSG_InitMasks( void ); // called once at startup engine
void MSG_ExciseBits( sizebuf_t *sb, int startbit, int bitstoremove );
// Bit-write functions
static inline void MSG_WriteOneBit( sizebuf_t *sb, int nValue )
{
if( !MSG_Overflow( sb, 1 ))
{
if( nValue ) sb->pData[sb->iCurBit>>3] |= BIT( sb->iCurBit & 7 );
else sb->pData[sb->iCurBit>>3] &= ~BIT( sb->iCurBit & 7 );
sb->iCurBit++;
}
}
void MSG_WriteOneBit( sizebuf_t *sb, int nValue );
NO_ASAN void MSG_WriteUBitLong( sizebuf_t *sb, uint curData, int numbits );
void MSG_WriteSBitLong( sizebuf_t *sb, int data, int numbits );
void MSG_WriteBitLong( sizebuf_t *sb, uint data, int numbits, qboolean bSigned );

View File

@@ -25,7 +25,8 @@ typedef struct did3v2_header_s
uint8_t flags;
uint32_t length; // size of extended header, padding and frames
} did3v2_header_t;
STATIC_CHECK_SIZEOF( did3v2_header_t, 10, 10 );
STATIC_ASSERT( sizeof( did3v2_header_t ) == 10,
"invalid did3v2_header_t size" );
typedef struct did3v2_extended_header_s
{
@@ -33,7 +34,8 @@ typedef struct did3v2_extended_header_s
uint8_t flags_length;
uint8_t flags[1];
} did3v2_extended_header_t;
STATIC_CHECK_SIZEOF( did3v2_extended_header_t, 6, 6 );
STATIC_ASSERT( sizeof( did3v2_extended_header_t ) == 6,
"invalid did3v2_extended_header_t size" );
typedef struct did3v2_frame_s
{
@@ -41,7 +43,8 @@ typedef struct did3v2_frame_s
uint32_t length;
uint8_t flags[2];
} did3v2_frame_t;
STATIC_CHECK_SIZEOF( did3v2_frame_t, 10, 10 );
STATIC_ASSERT( sizeof( did3v2_frame_t ) == 10,
"invalid did3v2_frame_t size" );
#pragma pack( pop )
typedef enum did3v2_header_flags_e

View File

@@ -95,7 +95,12 @@ typedef struct customization_s
#define FCUST_WIPEDATA ( 1<<1 )
#define FCUST_IGNOREINIT ( 1<<2 )
STATIC_CHECK_SIZEOF( customization_t, 164, 192 );
STATIC_CHECK_SIZEOF( resource_t, 136, 144 );
#if !XASH_64BIT
STATIC_ASSERT( sizeof( customization_t ) == 164, "invalid customization_t size, broken API" );
STATIC_ASSERT( sizeof( resource_t ) == 136, "invalid resource_t size, broken API" );
#else
STATIC_ASSERT( sizeof( customization_t ) == 192, "invalid customization_t size, broken API" );
STATIC_ASSERT( sizeof( resource_t ) == 144, "invalid resource_t size, broken API" );
#endif
#endif // CUSTOM_H

View File

@@ -125,7 +125,7 @@ typedef struct enginefuncs_s
void (*pfnAngleVectors)( const float *rgflVector, float *forward, float *right, float *up );
edict_t* (*pfnCreateEntity)( void );
void (*pfnRemoveEntity)( edict_t* e );
edict_t* (*pfnCreateNamedEntity)( string_t className );
edict_t* (*pfnCreateNamedEntity)( int className );
void (*pfnMakeStatic)( edict_t *ent );
int (*pfnEntIsOnFloor)( edict_t *e );
int (*pfnDropToFloor)( edict_t* e );
@@ -168,8 +168,8 @@ typedef struct enginefuncs_s
void* (*pfnPvAllocEntPrivateData)( edict_t *pEdict, long cb );
void* (*pfnPvEntPrivateData)( edict_t *pEdict );
void (*pfnFreeEntPrivateData)( edict_t *pEdict );
const char *(*pfnSzFromIndex)( string_t iString );
string_t (*pfnAllocString)( const char *szValue );
const char *(*pfnSzFromIndex)( int iString );
int (*pfnAllocString)( const char *szValue );
struct entvars_s *(*pfnGetVarsOfEnt)( edict_t *pEdict );
edict_t* (*pfnPEntityOfEntOffset)( int iEntOffset );
int (*pfnEntOffsetOfPEntity)( const edict_t *pEdict );

View File

@@ -1015,10 +1015,9 @@ qboolean R_Init_Video( const int type )
{
string safe;
qboolean retval;
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
SDL_DisplayMode displayMode;
SDL_GetCurrentDisplayMode( 0, &displayMode );
SDL_GetCurrentDisplayMode(0, &displayMode);
refState.desktopBitsPixel = SDL_BITSPERPIXEL( displayMode.format );
#else
refState.desktopBitsPixel = 16;
@@ -1096,7 +1095,7 @@ rserr_t R_ChangeDisplaySettings( int width, int height, window_mode_t window_mod
if( SDL_GetCurrentDisplayMode( 0, &displayMode ) < 0 )
{
Con_Printf( S_ERROR "SDL_GetCurrentDisplayMode: %s\n", SDL_GetError( ));
Con_Printf( S_ERROR "SDL_GetCurrentDisplayMode: %s", SDL_GetError( ));
return rserr_invalid_mode;
}
@@ -1240,6 +1239,10 @@ void R_Free_Video( void )
R_FreeVideoModes();
ref.dllFuncs.GL_ClearExtensions();
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
SDL_VideoQuit();
#endif
}
#endif // XASH_DEDICATED

View File

@@ -85,8 +85,8 @@ typedef struct entvars_s
int modelindex;
string_t model;
string_t viewmodel; // player's viewmodel
string_t weaponmodel; // what other players see
int viewmodel; // player's viewmodel
int weaponmodel; // what other players see
vec3_t absmin; // BB max translated to world coord
vec3_t absmax; // BB max translated to world coord
@@ -144,7 +144,7 @@ typedef struct entvars_s
int flags;
int colormap; // lowbyte topcolor, highbyte bottomcolor
string_t team;
int team;
float max_health;
float teleport_time;

View File

@@ -3000,6 +3000,25 @@ static void *GAME_EXPORT pfnPvEntPrivateData( edict_t *pEdict )
}
#ifdef XASH_64BIT
static struct str64_s
{
size_t maxstringarray;
qboolean allowdup;
char *staticstringarray;
char *pstringarray;
char *pstringarraystatic;
char *pstringbase;
char *poldstringbase;
char *plast;
qboolean dynamic;
size_t maxalloc;
size_t numdups;
size_t numoverflows;
size_t totalalloc;
} str64;
#endif
/*
==================
SV_EmptyStringPool
@@ -3009,7 +3028,17 @@ Free strings on server stop. Reset string pointer on 64 bits
*/
void SV_EmptyStringPool( void )
{
#ifdef XASH_64BIT
if( str64.dynamic ) // switch only after array fill (more space for multiplayer games)
str64.pstringbase = str64.pstringarray;
else
{
str64.pstringbase = str64.poldstringbase = str64.pstringarraystatic;
str64.plast = str64.pstringbase + 1;
}
#else
Mem_EmptyPool( svgame.stringspool );
#endif
}
/*
@@ -3023,8 +3052,23 @@ this helps not to lose strings that belongs to static game part
*/
void SV_SetStringArrayMode( qboolean dynamic )
{
#ifdef XASH_64BIT
Con_Reportf( "%s(%d) %d\n", __func__, dynamic, str64.dynamic );
if( dynamic == str64.dynamic )
return;
str64.dynamic = dynamic;
SV_EmptyStringPool();
#endif
}
#if XASH_64BIT && !XASH_WIN32 && !XASH_APPLE && !XASH_NSWITCH && !XASH_ANDROID
#define USE_MMAP
#include <sys/mman.h>
#endif
/*
==================
SV_AllocStringPool
@@ -3037,13 +3081,104 @@ this case need patched game dll with MAKE_STRING checking ptrdiff size
*/
static void SV_AllocStringPool( void )
{
#ifdef XASH_64BIT
void *ptr = NULL;
string lenstr;
Con_Reportf( "%s()\n", __func__ );
if( Sys_GetParmFromCmdLine( "-str64alloc", lenstr ) )
{
str64.maxstringarray = Q_atoi( lenstr );
if( str64.maxstringarray < 1024 || str64.maxstringarray >= INT_MAX )
str64.maxstringarray = 65536;
}
else str64.maxstringarray = 65536;
if( Sys_CheckParm( "-str64dup" ) )
str64.allowdup = true;
#ifdef USE_MMAP
{
uint flags;
size_t pagesize = sysconf( _SC_PAGESIZE );
int arrlen = (str64.maxstringarray * 2) & ~(pagesize - 1);
void *base = svgame.dllFuncs.pfnGameInit;
void *start = svgame.hInstance - arrlen;
#if defined(MAP_ANON)
flags = MAP_ANON | MAP_PRIVATE;
#elif defined(MAP_ANONYMOUS)
flags = MAP_ANONYMOUS | MAP_PRIVATE;
#endif
while( start - base > INT_MIN )
{
void *mapptr = mmap((void*)((unsigned long)start & ~(pagesize - 1)), arrlen, PROT_READ | PROT_WRITE, flags, 0, 0 );
if( mapptr && mapptr != (void*)-1 && mapptr - base > INT_MIN && mapptr - base < INT_MAX )
{
ptr = mapptr;
break;
}
if( mapptr ) munmap( mapptr, arrlen );
start -= arrlen;
}
if( !ptr )
{
start = base;
while( start - base < INT_MAX )
{
void *mapptr = mmap((void*)((unsigned long)start & ~(pagesize - 1)), arrlen, PROT_READ | PROT_WRITE, flags, 0, 0 );
if( mapptr && mapptr != (void*)-1 && mapptr - base > INT_MIN && mapptr - base < INT_MAX )
{
ptr = mapptr;
break;
}
if( mapptr ) munmap( mapptr, arrlen );
start += arrlen;
}
}
if( ptr )
{
Con_Reportf( "%s: Allocated string array near the server library: %p %p\n", __func__, base, ptr );
}
else
{
Con_Reportf( "%s: Failed to allocate string array near the server library!\n", __func__ );
ptr = str64.staticstringarray = Mem_Calloc( host.mempool, str64.maxstringarray * 2 );
}
}
#else
ptr = str64.staticstringarray = Mem_Calloc( host.mempool, str64.maxstringarray * 2 );
#endif
str64.pstringarray = ptr;
str64.pstringarraystatic = (byte*)ptr + str64.maxstringarray;
str64.pstringbase = str64.poldstringbase = ptr;
str64.plast = (byte*)ptr + 1;
svgame.globals->pStringBase = ptr;
#else
svgame.stringspool = Mem_AllocPool( "Server Strings" );
svgame.globals->pStringBase = "";
#endif
}
static void SV_FreeStringPool( void )
{
#ifdef XASH_64BIT
Con_Reportf( "%s()\n", __func__ );
#ifdef USE_MMAP
if( str64.pstringarray != str64.staticstringarray )
munmap( str64.pstringarray, (str64.maxstringarray * 2) & ~(sysconf( _SC_PAGESIZE ) - 1) );
else
#endif
Mem_Free( str64.staticstringarray );
#else
Mem_FreePool( &svgame.stringspool );
#endif
}
/*
@@ -3114,6 +3249,9 @@ string_t GAME_EXPORT SV_AllocString( const char *szValue )
{
char *newString = NULL;
uint len;
#ifdef XASH_64BIT
int cmp;
#endif
if( svgame.physFuncs.pfnAllocString != NULL )
{
@@ -3129,16 +3267,67 @@ string_t GAME_EXPORT SV_AllocString( const char *szValue )
return i;
}
#ifdef XASH_64BIT
cmp = 1;
if( !str64.allowdup )
{
for( newString = str64.poldstringbase + 1;
newString < str64.plast && ( cmp = Q_strcmp( newString, szValue ) );
newString += Q_strlen( newString ) + 1 );
}
if( cmp )
{
uint len = SV_ProcessString( NULL, szValue );
if( str64.plast - str64.poldstringbase + len + 1 > str64.maxstringarray )
{
str64.plast = str64.pstringbase + 1;
str64.poldstringbase = str64.pstringbase;
str64.numoverflows++;
}
//MsgDev( D_NOTE, "SV_AllocString: %ld %s\n", str64.plast - svgame.globals->pStringBase, szValue );
SV_ProcessString( str64.plast, szValue );
str64.totalalloc += len;
newString = str64.plast;
str64.plast += len;
}
else
{
str64.numdups++;
//MsgDev( D_NOTE, "SV_AllocString: dup %ld %s\n", newString - svgame.globals->pStringBase, szValue );
}
if( newString - str64.pstringarray > str64.maxalloc )
str64.maxalloc = newString - str64.pstringarray;
return newString - svgame.globals->pStringBase;
#else
len = SV_ProcessString( NULL, szValue );
newString = Mem_Malloc( svgame.stringspool, len );
SV_ProcessString( newString, szValue );
return newString - svgame.globals->pStringBase;
#endif
}
void SV_PrintStr64Stats_f( void )
{
#ifdef XASH_64BIT
Con_Printf( "====================\n" );
Con_Printf( "64 bit string pool statistics\n" );
Con_Printf( "====================\n" );
Con_Printf( "string array size: %lu\n", str64.maxstringarray );
Con_Printf( "total alloc %lu\n", str64.totalalloc );
Con_Printf( "maximum array usage: %lu\n", str64.maxalloc );
Con_Printf( "overflow counter: %lu\n", str64.numoverflows );
Con_Printf( "dup string counter: %lu\n", str64.numdups );
#else
Con_Printf( "Not implemented\n" );
#endif
}
/*
@@ -3152,8 +3341,17 @@ string_t SV_MakeString( const char *szValue )
{
if( svgame.physFuncs.pfnMakeString != NULL )
return svgame.physFuncs.pfnMakeString( szValue );
#ifdef XASH_64BIT
{
long long ptrdiff = szValue - svgame.globals->pStringBase;
if( ptrdiff > INT_MAX || ptrdiff < INT_MIN )
return SV_AllocString(szValue);
else
return (int)ptrdiff;
}
#else
return szValue - svgame.globals->pStringBase;
#endif
}
/*

View File

@@ -72,7 +72,7 @@ typedef struct
int32_t version; // current version 2
} dsprite_t;
STATIC_CHECK_SIZEOF( dsprite_t, 8, 8 );
STATIC_ASSERT( sizeof( dsprite_t ) == 8, "invalid dsprite_t size" );
typedef struct
{
@@ -86,7 +86,7 @@ typedef struct
uint32_t synctype; // animation synctype, was synctype_t
} dsprite_q1_t;
STATIC_CHECK_SIZEOF( dsprite_q1_t, 36, 36 );
STATIC_ASSERT( sizeof( dsprite_q1_t ) == 36, "invalid dsprite_q1_t size" );
typedef struct
{
@@ -101,7 +101,7 @@ typedef struct
uint32_t synctype; // animation synctype, was synctype_t
} dsprite_hl_t;
STATIC_CHECK_SIZEOF( dsprite_hl_t, 40, 40 );
STATIC_ASSERT( sizeof( dsprite_hl_t ) == 40, "invalid dsprite_hl_t size" );
typedef struct
{
@@ -110,27 +110,27 @@ typedef struct
int32_t height;
} dspriteframe_t;
STATIC_CHECK_SIZEOF( dspriteframe_t, 16, 16 );
STATIC_ASSERT( sizeof( dspriteframe_t ) == 16, "invalid dspriteframe_t size" );
typedef struct
{
int32_t numframes;
} dspritegroup_t;
STATIC_CHECK_SIZEOF( dspritegroup_t, 4, 4 );
STATIC_ASSERT( sizeof( dspritegroup_t ) == 4, "invalid dspritegroup_t size" );
typedef struct
{
float interval;
} dspriteinterval_t;
STATIC_CHECK_SIZEOF( dspriteinterval_t, 4, 4 );
STATIC_ASSERT( sizeof( dspriteinterval_t ) == 4, "invalid dspriteinterval_t size" );
typedef struct
{
uint32_t type; // was frametype_t
} dframetype_t;
STATIC_CHECK_SIZEOF( dframetype_t, 4, 4 );
STATIC_ASSERT( sizeof( dframetype_t ) == 4, "invalid dframetype_t size" );
#endif//SPRITE_H

View File

@@ -110,8 +110,6 @@ def configure(conf):
conf.env.append_unique('CFLAGS', '-fsanitize=fuzzer-no-link')
conf.env.append_unique('LINKFLAGS', '-fsanitize=fuzzer')
conf.define('ENGINE_DLL', 1)
conf.define_cond('XASH_ENGINE_TESTS', conf.env.ENGINE_TESTS)
conf.define_cond('XASH_STATIC_LIBS', conf.env.STATIC_LINKING)
conf.define_cond('XASH_CUSTOM_SWAP', conf.options.CUSTOM_SWAP)

View File

@@ -31,7 +31,7 @@ GNU General Public License for more details.
#include "enginefeatures.h"
#include "com_strings.h"
#include "pm_movevars.h"
#include "cvardef.h"
#include "common/cvar.h"
#include "gl_export.h"
#include "wadfile.h"
#include "common/mod_local.h"
@@ -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

View File

@@ -742,8 +742,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 +1150,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;

View File

@@ -1010,32 +1010,21 @@ 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, FCVAR_CHANGED ) || FBitSet( 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;
}
if( FBitSet( r_vbo_overbrightmode.flags, FCVAR_CHANGED ) && gl_overbright.value )
{
ClearBits( r_vbo_overbrightmode.flags, FCVAR_CHANGED );
rebuild = true;
}
if( rebuild )
@@ -1057,7 +1046,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];

View File

@@ -718,7 +718,7 @@ static void R_BuildLightMap( msurface_t *surf, byte *dest, int stride, qboolean
tmax = ( info->lightextents[1] / sample_size ) + 1;
size = smax * tmax;
if( gl_overbright.value )
lightscale = ( R_HasEnabledVBO() && !r_vbo_overbrightmode.value) ? 171 : 256;
lightscale = (r_vbo.value && !r_vbo_overbrightmode.value) ? 171 : 256;
else lightscale = ( pow( 2.0f, 1.0f / v_lightgamma->value ) * 256 ) + 0.5;
lm = surf->samples;
@@ -927,7 +927,7 @@ static void R_BlendLightmaps( void )
if( gl_overbright.value )
{
pglBlendFunc( GL_DST_COLOR, GL_SRC_COLOR );
if(!( R_HasEnabledVBO() && !r_vbo_overbrightmode.value ))
if(!( r_vbo.value && !r_vbo_overbrightmode.value ))
pglColor4f( 128.0f / 192.0f, 128.0f / 192.0f, 128.0f / 192.0f, 1.0f );
}
else
@@ -1135,148 +1135,6 @@ static void R_RenderDetails( int passes )
GL_ResetFogColor();
}
static void R_RenderFullbrightForSurface( msurface_t *fa, texture_t *t )
{
if( !t->fb_texturenum )
return;
fa->info->lumachain = fullbright_surfaces[t->fb_texturenum];
fullbright_surfaces[t->fb_texturenum] = fa->info;
draw_fullbrights = true;
}
static void R_RenderDetailsForSurface( msurface_t *fa, texture_t *t )
{
if( !r_detailtextures.value )
return;
if( glState.isFogEnabled )
{
// don't apply detail textures for windows in the fog
if( RI.currententity->curstate.rendermode != kRenderTransTexture )
{
if( t->dt_texturenum )
{
fa->info->detailchain = detail_surfaces[t->dt_texturenum];
detail_surfaces[t->dt_texturenum] = fa->info;
}
else
{
// draw stub detail texture for underwater surfaces
fa->info->detailchain = detail_surfaces[tr.grayTexture];
detail_surfaces[tr.grayTexture] = fa->info;
}
draw_details = true;
}
}
else if( t->dt_texturenum )
{
fa->info->detailchain = detail_surfaces[t->dt_texturenum];
detail_surfaces[t->dt_texturenum] = fa->info;
draw_details = true;
}
}
static void R_RenderDecalsForSurface( msurface_t *fa, int cull_type )
{
if( RI.currententity->curstate.rendermode == kRenderNormal )
{
// batch decals to draw later
if( tr.num_draw_decals < MAX_DECAL_SURFS && fa->pdecals )
tr.draw_decals[tr.num_draw_decals++] = fa;
}
else
{
// if rendermode != kRenderNormal draw decals sequentially
DrawSurfaceDecals( fa, true, (cull_type == CULL_BACKSIDE));
}
}
static qboolean R_CheckLightMap( msurface_t *fa )
{
qboolean is_dynamic = false;
int maps;
// check for lightmap modification
for( maps = 0; maps < MAXLIGHTMAPS && fa->styles[maps] != 255; maps++ )
{
if( tr.lightstylevalue[fa->styles[maps]] != fa->cached_light[maps] )
goto dynamic;
}
// dynamic this frame or dynamic previously
if( fa->dlightframe == tr.framecount )
{
dynamic:
// NOTE: at this point we have only valid textures
if( r_dynamic->value )
is_dynamic = true;
}
if( is_dynamic )
{
const int style = fa->styles[maps];
if( maps < MAXLIGHTMAPS && ( style >= 32 || style == 0 || style == 20 ) && fa->dlightframe != tr.framecount )
{
byte temp[132*132*4];
mextrasurf_t *info = fa->info;
int sample_size;
int smax, tmax;
sample_size = gEngfuncs.Mod_SampleSizeForFace( fa );
smax = ( info->lightextents[0] / sample_size ) + 1;
tmax = ( info->lightextents[1] / sample_size ) + 1;
if( smax < 132 && tmax < 132 )
R_BuildLightMap( fa, temp, smax * 4, true );
else
{
smax = Q_min( smax, 132 );
tmax = Q_min( tmax, 132 );
memset( temp, 255, sizeof( temp ));
//Host_MapDesignError( "%s: bad surface extents: %d %d", __func__, fa->extents[0], fa->extents[1] );
}
R_SetCacheState( fa );
#ifdef XASH_WES
GL_Bind( XASH_TEXTURE1, tr.lightmapTextures[fa->lightmaptexturenum] );
pglTexParameteri( GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE );
#else
GL_Bind( XASH_TEXTURE0, tr.lightmapTextures[fa->lightmaptexturenum] );
#endif
pglTexSubImage2D( GL_TEXTURE_2D, 0, fa->light_s, fa->light_t, smax, tmax, GL_RGBA, GL_UNSIGNED_BYTE, temp );
#ifdef XASH_WES
GL_SelectTexture( XASH_TEXTURE0 );
#endif
}
else
return true; // add to dynamic chain
}
return false; // updated
}
static void R_RenderLightmapForSurface( msurface_t *fa )
{
if( !fa->polys || FBitSet( fa->flags, SURF_DRAWTILED ))
return;
if( R_CheckLightMap( fa ))
{
fa->info->lightmapchain = gl_lms.dynamic_surfaces;
gl_lms.dynamic_surfaces = fa;
}
else
{
fa->info->lightmapchain = gl_lms.lightmap_surfaces[fa->lightmaptexturenum];
gl_lms.lightmap_surfaces[fa->lightmaptexturenum] = fa;
}
}
/*
================
R_RenderBrushPoly
@@ -1284,6 +1142,8 @@ R_RenderBrushPoly
*/
static void R_RenderBrushPoly( msurface_t *fa, int cull_type )
{
qboolean is_dynamic = false;
int maps;
texture_t *t;
r_stats.c_world_polys++;
@@ -1303,11 +1163,109 @@ static void R_RenderBrushPoly( msurface_t *fa, int cull_type )
}
else GL_Bind( XASH_TEXTURE0, t->gl_texturenum );
R_RenderFullbrightForSurface( fa, t );
R_RenderDetailsForSurface( fa, t );
if( t->fb_texturenum )
{
fa->info->lumachain = fullbright_surfaces[t->fb_texturenum];
fullbright_surfaces[t->fb_texturenum] = fa->info;
draw_fullbrights = true;
}
if( r_detailtextures.value )
{
if( glState.isFogEnabled )
{
// don't apply detail textures for windows in the fog
if( RI.currententity->curstate.rendermode != kRenderTransTexture )
{
if( t->dt_texturenum )
{
fa->info->detailchain = detail_surfaces[t->dt_texturenum];
detail_surfaces[t->dt_texturenum] = fa->info;
}
else
{
// draw stub detail texture for underwater surfaces
fa->info->detailchain = detail_surfaces[tr.grayTexture];
detail_surfaces[tr.grayTexture] = fa->info;
}
draw_details = true;
}
}
else if( t->dt_texturenum )
{
fa->info->detailchain = detail_surfaces[t->dt_texturenum];
detail_surfaces[t->dt_texturenum] = fa->info;
draw_details = true;
}
}
DrawGLPoly( fa->polys, 0.0f, 0.0f );
R_RenderDecalsForSurface( fa, cull_type );
R_RenderLightmapForSurface( fa );
if( RI.currententity->curstate.rendermode == kRenderNormal )
{
// batch decals to draw later
if( tr.num_draw_decals < MAX_DECAL_SURFS && fa->pdecals )
tr.draw_decals[tr.num_draw_decals++] = fa;
}
else
{
// if rendermode != kRenderNormal draw decals sequentially
DrawSurfaceDecals( fa, true, (cull_type == CULL_BACKSIDE));
}
if( FBitSet( fa->flags, SURF_DRAWTILED ))
return; // no lightmaps anyway
// check for lightmap modification
for( maps = 0; maps < MAXLIGHTMAPS && fa->styles[maps] != 255; maps++ )
{
if( tr.lightstylevalue[fa->styles[maps]] != fa->cached_light[maps] )
goto dynamic;
}
// dynamic this frame or dynamic previously
if( fa->dlightframe == tr.framecount )
{
dynamic:
// NOTE: at this point we have only valid textures
if( r_dynamic->value ) is_dynamic = true;
}
if( is_dynamic )
{
if(( maps < MAXLIGHTMAPS ) && ( fa->styles[maps] >= 32 || fa->styles[maps] == 0 || fa->styles[maps] == 20 ) && ( fa->dlightframe != tr.framecount ))
{
byte temp[132*132*4];
mextrasurf_t *info = fa->info;
int sample_size;
int smax, tmax;
sample_size = gEngfuncs.Mod_SampleSizeForFace( fa );
smax = ( info->lightextents[0] / sample_size ) + 1;
tmax = ( info->lightextents[1] / sample_size ) + 1;
R_BuildLightMap( fa, temp, smax * 4, true );
R_SetCacheState( fa );
GL_Bind( XASH_TEXTURE0, tr.lightmapTextures[fa->lightmaptexturenum] );
pglTexSubImage2D( GL_TEXTURE_2D, 0, fa->light_s, fa->light_t, smax, tmax,
GL_RGBA, GL_UNSIGNED_BYTE, temp );
fa->info->lightmapchain = gl_lms.lightmap_surfaces[fa->lightmaptexturenum];
gl_lms.lightmap_surfaces[fa->lightmaptexturenum] = fa;
}
else
{
fa->info->lightmapchain = gl_lms.dynamic_surfaces;
gl_lms.dynamic_surfaces = fa;
}
}
else
{
fa->info->lightmapchain = gl_lms.lightmap_surfaces[fa->lightmaptexturenum];
gl_lms.lightmap_surfaces[fa->lightmaptexturenum] = fa;
}
}
/*
@@ -1583,7 +1541,7 @@ void R_DrawBrushModel( cl_entity_t *e )
model_t *clmodel;
qboolean rotated;
dlight_t *l;
qboolean allow_vbo = R_HasEnabledVBO();
qboolean allow_vbo = r_vbo.value;
if( !RI.drawWorld ) return;
@@ -1833,10 +1791,6 @@ struct vbo_static_s
int maxarraysplit_tex;
int minarraysplit_lm;
int maxarraysplit_lm;
// cvar state potentially might be changed during frame
// so only enable VBO at the beginning of frame
qboolean enabled;
} vbos;
struct multitexturestate_s
@@ -1873,6 +1827,7 @@ enum lightmap_state_e
VBO_LIGHTMAP_DYNAMIC
};
static struct arraystate_s
{
enum array_state_e astate;
@@ -1882,20 +1837,6 @@ static struct arraystate_s
qboolean decal_mode;
} vboarray;
qboolean R_HasGeneratedVBO( void )
{
return vbos.mempool != 0;
}
void R_EnableVBO( qboolean enable )
{
vbos.enabled = enable;
}
qboolean R_HasEnabledVBO( void )
{
return vbos.enabled;
}
/*
===================
@@ -1907,23 +1848,29 @@ Allocate memory for arrays, fill it with vertex attribs and upload to GPU
void R_GenerateVBO( void )
{
model_t *world = WORLDMODEL;
msurface_t *surfaces;
int numsurfaces;
int numtextures;
const int numlightmaps = gl_lms.current_lightmap_texture;
msurface_t *surfaces = world->surfaces;
int numsurfaces = world->numsurfaces;
int numtextures = world->numtextures;
int numlightmaps = gl_lms.current_lightmap_texture;
int k, len = 0;
vboarray_t *vbo;
uint maxindex = 0;
double t1, t2, t3;
if( R_HasGeneratedVBO() || !world || !world->surfaces )
R_ClearVBO();
// 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 );
return;
}
t1 = gEngfuncs.pfnTime();
surfaces = world->surfaces;
numsurfaces = world->numsurfaces;
numtextures = world->numtextures;
// save in config if enabled manually
if( r_vbo.value )
r_vbo.flags |= FCVAR_ARCHIVE;
vbos.mempool = Mem_AllocPool("Render VBO Zone");
@@ -3074,14 +3021,14 @@ void R_DrawVBO( qboolean drawlightmap, qboolean drawtextures )
int k;
vboarray_t *vbo = vbos.arraylist;
if( !R_HasGeneratedVBO() || !R_HasEnabledVBO() )
if( !r_vbo.value )
return;
GL_SetupFogColorForSurfacesEx( 1, 0.5f, false );
R_SetupVBOArrayStatic( vbo, drawlightmap, drawtextures );
mtst.skiptexture = !drawtextures;
mtst.tmu_dt = glConfig.max_texture_units > 2 && r_vbo_detail.value == 2 ? XASH_TEXTURE2 : -1;
mtst.tmu_dt = glConfig.max_texture_units > 2 && r_vbo_detail.value == 2? XASH_TEXTURE2:-1;
// setup limits
if( vbos.minlightmap > vbos.minarraysplit_lm )
@@ -3175,71 +3122,171 @@ void R_DrawVBO( qboolean drawlightmap, qboolean drawtextures )
vbos.maxtexture = 0;
}
qboolean R_AddSurfToVBO( msurface_t *surf, qboolean buildlightmap )
/*
================
R_CheckLightMap
update surface's lightmap if needed and return true if it is dynamic
================
*/
static qboolean R_CheckLightMap( msurface_t *fa )
{
const int idx = surf - WORLDMODEL->surfaces;
vbotexture_t *vbotex;
int texturenum;
int maps;
qboolean is_dynamic = false;
if( !R_HasGeneratedVBO() || !R_HasEnabledVBO( ))
// check for lightmap modification
for( maps = 0; maps < MAXLIGHTMAPS && fa->styles[maps] != 255; maps++ )
{
if( tr.lightstylevalue[fa->styles[maps]] != fa->cached_light[maps] )
{
is_dynamic = true;
break;
}
}
// already up to date
if( !is_dynamic && ( fa->dlightframe != tr.framecount ))
return false;
// find vbotexture_t assotiated with this surface
vbotex = vbos.surfdata[idx].vbotexture;
texturenum = vbos.surfdata[idx].texturenum;
// build lightmap
if(( maps < MAXLIGHTMAPS ) && ( fa->styles[maps] >= 32 || fa->styles[maps] == 0 ) && ( fa->dlightframe != tr.framecount ))
{
byte temp[132*132*4];
int smax, tmax;
int sample_size;
mextrasurf_t *info;
if( !vbotex )
return false;
info = fa->info;
sample_size = gEngfuncs.Mod_SampleSizeForFace( fa );
smax = ( info->lightextents[0] / sample_size ) + 1;
tmax = ( info->lightextents[1] / sample_size ) + 1;
if( !surf->polys )
if( smax < 132 && tmax < 132 )
{
R_BuildLightMap( fa, temp, smax * 4, true );
}
else
{
smax = Q_min( smax, 132 );
tmax = Q_min( tmax, 132 );
//Host_MapDesignError( "R_RenderBrushPoly: bad surface extents: %d %d", fa->extents[0], fa->extents[1] );
memset( temp, 255, sizeof( temp ) );
}
R_SetCacheState( fa );
#ifdef XASH_WES
GL_Bind( XASH_TEXTURE1, tr.lightmapTextures[fa->lightmaptexturenum] );
pglTexParameteri( GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE );
#else
GL_Bind( XASH_TEXTURE0, tr.lightmapTextures[fa->lightmaptexturenum] );
#endif
pglTexSubImage2D( GL_TEXTURE_2D, 0, fa->light_s, fa->light_t, smax, tmax,
GL_RGBA, GL_UNSIGNED_BYTE, temp );
#ifdef XASH_WES
GL_SelectTexture( XASH_TEXTURE0 );
#endif
}
// add to dynamic chain
else
return true;
if( vbos.maxlightmap < surf->lightmaptexturenum + 1 )
vbos.maxlightmap = surf->lightmaptexturenum + 1;
if( vbos.minlightmap > surf->lightmaptexturenum )
vbos.minlightmap = surf->lightmaptexturenum;
if( vbos.maxtexture < texturenum + 1 )
vbos.maxtexture = texturenum + 1;
if( vbos.mintexture > texturenum )
vbos.mintexture = texturenum;
// updated
return false;
}
buildlightmap &= !r_fullbright->value && !!WORLDMODEL->lightdata;
// draw details in regular way
if( r_vbo_detail.value == 0 && surf->texinfo )
R_RenderDetailsForSurface( surf, surf->texinfo->texture );
if( buildlightmap && R_CheckLightMap( surf ))
qboolean R_AddSurfToVBO( msurface_t *surf, qboolean buildlightmap )
{
if( r_vbo.value && vbos.surfdata[surf - WORLDMODEL->surfaces].vbotexture )
{
// every vbotex has own lightmap chain (as we sorted if by textures to use multitexture)
surf->info->lightmapchain = vbotex->dlightchain;
vbotex->dlightchain = surf;
}
else
{
uint indexbase = vbos.surfdata[idx].startindex;
uint index;
// find vbotexture_t assotiated with this surface
int idx = surf - WORLDMODEL->surfaces;
vbotexture_t *vbotex = vbos.surfdata[idx].vbotexture;
int texturenum = vbos.surfdata[idx].texturenum;
// GL_TRIANGLE_FAN: 0 1 2 0 2 3 0 3 4 ...
for( index = indexbase + 2; index < indexbase + surf->polys->numverts; index++ )
if( !surf->polys )
return true;
if( vbos.maxlightmap < surf->lightmaptexturenum + 1 )
vbos.maxlightmap = surf->lightmaptexturenum + 1;
if( vbos.minlightmap > surf->lightmaptexturenum )
vbos.minlightmap = surf->lightmaptexturenum;
if( vbos.maxtexture < texturenum + 1 )
vbos.maxtexture = texturenum + 1;
if( vbos.mintexture > texturenum )
vbos.mintexture = texturenum;
buildlightmap &= !r_fullbright->value && !!WORLDMODEL->lightdata;
/* draw details in regular way */
if( r_vbo_detail.value == 0 )
{
vbotex->indexarray[vbotex->curindex++] = indexbase;
vbotex->indexarray[vbotex->curindex++] = index - 1;
vbotex->indexarray[vbotex->curindex++] = index;
if( r_detailtextures.value && surf->texinfo && surf->texinfo )
{
texture_t *t = surf->texinfo->texture;
if( glState.isFogEnabled )
{
// don't apply detail textures for windows in the fog
if( RI.currententity->curstate.rendermode != kRenderTransTexture )
{
if( t->dt_texturenum )
{
surf->info->detailchain = detail_surfaces[t->dt_texturenum];
detail_surfaces[t->dt_texturenum] = surf->info;
}
else
{
// draw stub detail texture for underwater surfaces
surf->info->detailchain = detail_surfaces[tr.grayTexture];
detail_surfaces[tr.grayTexture] = surf->info;
}
draw_details = true;
}
}
else if( t->dt_texturenum )
{
surf->info->detailchain = detail_surfaces[t->dt_texturenum];
detail_surfaces[t->dt_texturenum] = surf->info;
draw_details = true;
}
}
}
// if surface has decals, add it to decal lightmapchain
if( surf->pdecals )
if( buildlightmap && R_CheckLightMap( surf ) )
{
surf->info->lightmapchain = vbos.decaldata->lm[vbotex->lightmaptexturenum];
vbos.decaldata->lm[vbotex->lightmaptexturenum] = surf;
// every vbotex has own lightmap chain (as we sorted if by textures to use multitexture)
surf->info->lightmapchain = vbotex->dlightchain;
vbotex->dlightchain = surf;
}
else
{
uint indexbase = vbos.surfdata[idx].startindex;
uint index;
// GL_TRIANGLE_FAN: 0 1 2 0 2 3 0 3 4 ...
for( index = indexbase + 2; index < indexbase + surf->polys->numverts; index++ )
{
vbotex->indexarray[vbotex->curindex++] = indexbase;
vbotex->indexarray[vbotex->curindex++] = index - 1;
vbotex->indexarray[vbotex->curindex++] = index;
}
// if surface has decals, add it to decal lightmapchain
if( surf->pdecals )
{
surf->info->lightmapchain = vbos.decaldata->lm[vbotex->lightmaptexturenum];
vbos.decaldata->lm[vbotex->lightmaptexturenum] = surf;
}
}
// now this path does not draw wapred surfaces, so count it as one poly
r_stats.c_world_polys++;
return true;
}
// now this path does not draw wapred surfaces, so count it as one poly
r_stats.c_world_polys++;
return true;
return false;
}
/*
@@ -3577,7 +3624,7 @@ void R_DrawWorld( void )
GL_ResetFogColor();
R_BlendLightmaps();
R_RenderFullbrights();
R_RenderDetails( R_HasEnabledVBO() ? 2 : 3 );
R_RenderDetails( r_vbo.value? 2 : 3 );
if( skychain )
R_DrawSkyBox();

View File

@@ -30,7 +30,7 @@ GNU General Public License for more details.
#include "enginefeatures.h"
#include "com_strings.h"
#include "pm_movevars.h"
#include "cvardef.h"
#include "common/cvar.h"
typedef struct mip_s mip_t;
typedef int fixed8_t;

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

@@ -172,12 +172,7 @@ def options(opt):
def configure(conf):
conf.load('fwgslib reconfigure compiler_optimizations')
if conf.options.ALLOW64:
conf.env.MSVC_TARGETS = ['x64']
elif sys.maxsize > 2 ** 32:
conf.env.MSVC_TARGETS = ['amd64_x86', 'x86']
else:
conf.env.MSVC_TARGETS = ['x86']
conf.env.MSVC_TARGETS = ['x86' if not conf.options.ALLOW64 else 'x64']
# Load compilers early
conf.load('xshlib xcompile compiler_c compiler_cxx cmake gccdeps')