numBSPDrawVerts = n;
numBSPDrawVertsBuffer = numBSPDrawVerts;
- bspDrawVerts = safe_malloc_info( sizeof( bspDrawVert_t ) * numBSPDrawVertsBuffer, "IncDrawVerts" );
-
- memset( bspDrawVerts, 0, n * sizeof( bspDrawVert_t ) );
+ bspDrawVerts = safe_malloc0_info( sizeof( bspDrawVert_t ) * numBSPDrawVertsBuffer, "IncDrawVerts" );
}
int numBSPDrawSurfacesBuffer = 0;
numBSPDrawSurfacesBuffer = MAX_MAP_DRAW_SURFS;
- bspDrawSurfaces = safe_malloc_info( sizeof( bspDrawSurface_t ) * numBSPDrawSurfacesBuffer, "IncDrawSurfaces" );
-
- memset( bspDrawSurfaces, 0, MAX_MAP_DRAW_SURFS * sizeof( bspDrawSurface_t ) );
+ bspDrawSurfaces = safe_malloc0_info( sizeof( bspDrawSurface_t ) * numBSPDrawSurfacesBuffer, "IncDrawSurfaces" );
}
void SetDrawSurfaces( int n ){
numBSPDrawSurfaces = n;
numBSPDrawSurfacesBuffer = numBSPDrawSurfaces;
- bspDrawSurfaces = safe_malloc_info( sizeof( bspDrawSurface_t ) * numBSPDrawSurfacesBuffer, "IncDrawSurfaces" );
-
- memset( bspDrawSurfaces, 0, n * sizeof( bspDrawSurface_t ) );
+ bspDrawSurfaces = safe_malloc0_info( sizeof( bspDrawSurface_t ) * numBSPDrawSurfacesBuffer, "IncDrawSurfaces" );
}
void BSPFilesCleanup(){
void AddLump( FILE *file, bspHeader_t *header, int lumpNum, const void *data, int length ){
bspLump_t *lump;
-
/* add lump to bsp file header */
lump = &header->lumps[ lumpNum ];
lump->offset = LittleLong( ftell( file ) );
lump->length = LittleLong( length );
/* write lump to file */
- SafeWrite( file, data, ( length + 3 ) & ~3 );
+ SafeWrite( file, data, length );
+
+ /* write padding zeros */
+ SafeWrite( file, (const byte[3]){ 0, 0, 0 }, ( ( length + 3 ) & ~3 ) - length );
}
if ( numEntities <= 0 ) {
ParseEntities();
}
-
+ int patchCount = 0;
+ bspDrawSurface_t *s;
+ for ( s = bspDrawSurfaces; s != bspDrawSurfaces + numBSPDrawSurfaces; ++s ){
+ if ( s->surfaceType == MST_PATCH )
+ ++patchCount;
+ }
/* note that this is abstracted */
Sys_Printf( "Abstracted BSP file components (*actual sizes may differ)\n" );
Sys_Printf( "%9d drawsurfaces %9d *\n",
numBSPDrawSurfaces, (int) ( numBSPDrawSurfaces * sizeof( *bspDrawSurfaces ) ) );
+ Sys_Printf( "%9d patchsurfaces \n",
+ patchCount );
Sys_Printf( "%9d drawverts %9d *\n",
numBSPDrawVerts, (int) ( numBSPDrawVerts * sizeof( *bspDrawVerts ) ) );
Sys_Printf( "%9d drawindexes %9d\n",
/* allocate and clear new epair */
- e = safe_malloc( sizeof( epair_t ) );
- memset( e, 0, sizeof( epair_t ) );
+ e = safe_malloc0( sizeof( epair_t ) );
/* handle key */
if ( strlen( token ) >= ( MAX_KEY - 1 ) ) {
for ( i = beginArgs; i < endArgs; ++i )
{
+ if ( argv[i] == NULL ) {
+ continue;
+ }
if ( outpos != sentinel && i != beginArgs ) {
*outpos++ = ' ';
}
+/*
+ Modulo1IfNegative()
+ Previously the bias computation was doing:
+
+ while ( f < 0.0f ) {
+ f += 1.0f;
+ }
+
+ That may end in infinite loop in some case.
+ It may also be slower because of useless loops.
+ I don't know what that computation is for.
+ -- illwieckz
+*/
+float Modulo1IfNegative( float f ){
+ return f < 0.0f ? f - floor( f ) : f;
+}
+
/*
*/
qboolean RadSampleImage( byte *pixels, int width, int height, float st[ 2 ], float color[ 4 ] ){
- float sto[ 2 ];
int x, y;
-
/* clear color first */
color[ 0 ] = color[ 1 ] = color[ 2 ] = color[ 3 ] = 255;
return qfalse;
}
- /* bias st */
- sto[ 0 ] = st[ 0 ];
- while ( sto[ 0 ] < 0.0f )
- sto[ 0 ] += 1.0f;
- sto[ 1 ] = st[ 1 ];
- while ( sto[ 1 ] < 0.0f )
- sto[ 1 ] += 1.0f;
-
/* get offsets */
- x = ( (float) width * sto[ 0 ] ) + 0.5f;
+ x = ( (float) width * Modulo1IfNegative( st[ 0 ] ) ) + 0.5f;
x %= width;
- y = ( (float) height * sto[ 1 ] ) + 0.5f;
+ y = ( (float) height * Modulo1IfNegative( st[ 1 ] ) ) + 0.5f;
y %= height;
/* get pixel */
#define RADIOSITY_MIN 0.0001f
#define RADIOSITY_CLIP_EPSILON 0.125f
+
+
static void RadSubdivideDiffuseLight( int lightmapNum, bspDrawSurface_t *ds, rawLightmap_t *lm, shaderInfo_t *si,
- float scale, float subdivide, qboolean original, radWinding_t *rw, clipWork_t *cw ){
+ float scale, float subdivide, radWinding_t *rw, clipWork_t *cw ){
int i, style = 0;
float dist, area, value;
vec3_t mins, maxs, normal, d1, d2, cross, color, gradient;
light_t *light, *splash;
- winding_t *w;
+ winding_t *w, *splash_w;
/* dummy check */
RadClipWindingEpsilon( rw, normal, dist, RADIOSITY_CLIP_EPSILON, &front, &back, cw );
/* recurse */
- RadSubdivideDiffuseLight( lightmapNum, ds, lm, si, scale, subdivide, qfalse, &front, cw );
- RadSubdivideDiffuseLight( lightmapNum, ds, lm, si, scale, subdivide, qfalse, &back, cw );
+ RadSubdivideDiffuseLight( lightmapNum, ds, lm, si, scale, subdivide, &front, cw );
+ RadSubdivideDiffuseLight( lightmapNum, ds, lm, si, scale, subdivide, &back, cw );
return;
}
}
/* if color gradient is too high, subdivide again */
if ( subdivide > minDiffuseSubdivide &&
( gradient[ 0 ] > RADIOSITY_MAX_GRADIENT || gradient[ 1 ] > RADIOSITY_MAX_GRADIENT || gradient[ 2 ] > RADIOSITY_MAX_GRADIENT ) ) {
- RadSubdivideDiffuseLight( lightmapNum, ds, lm, si, scale, ( subdivide / 2.0f ), qfalse, rw, cw );
+ RadSubdivideDiffuseLight( lightmapNum, ds, lm, si, scale, ( subdivide / 2.0f ), rw, cw );
return;
}
}
}
/* create a light */
- light = safe_malloc( sizeof( *light ) );
- memset( light, 0, sizeof( *light ) );
+ light = safe_malloc0( sizeof( *light ) );
/* attach it */
ThreadLock();
VectorMA( light->origin, 1.0f, light->normal, light->origin );
light->dist = DotProduct( light->origin, normal );
- /* optionally create a point backsplash light for first pass */
- if ( original && si->backsplashFraction > 0 ) {
+ #if 0
+ /* optionally create a point backsplash light */
+ if ( si->backsplashFraction > 0 ) {
+
/* allocate a new point light */
- splash = safe_malloc( sizeof( *splash ) );
- memset( splash, 0, sizeof( *splash ) );
+ splash = safe_malloc0( sizeof( *splash ) );
+
splash->next = lights;
lights = splash;
+
/* set it up */
splash->flags = LIGHT_Q3A_DEFAULT;
splash->type = EMIT_POINT;
splash->photons = light->photons * si->backsplashFraction;
+
splash->fade = 1.0f;
splash->si = si;
VectorMA( light->origin, si->backsplashDistance, normal, splash->origin );
VectorCopy( si->color, splash->color );
+
splash->falloffTolerance = falloffTolerance;
splash->style = noStyles ? LS_NORMAL : light->style;
/* add to counts */
numPointLights++;
}
+ #endif
+
+ #if 1
+ /* optionally create area backsplash light */
+ //if ( original && si->backsplashFraction > 0 ) {
+ if ( si->backsplashFraction > 0 && !( si->compileFlags & C_SKY ) ) {
+ /* allocate a new area light */
+ splash = safe_malloc( sizeof( *splash ) );
+ memset( splash, 0, sizeof( *splash ) );
+ ThreadLock();
+ splash->next = lights;
+ lights = splash;
+ ThreadUnlock();
+
+ /* set it up */
+ splash->flags = LIGHT_AREA_DEFAULT;
+ splash->type = EMIT_AREA;
+ splash->photons = light->photons * 7.0f * si->backsplashFraction;
+ splash->add = light->add * 7.0f * si->backsplashFraction;
+ splash->fade = 1.0f;
+ splash->si = si;
+ VectorCopy( si->color, splash->color );
+ VectorScale( splash->color, splash->add, splash->emitColor );
+ splash->falloffTolerance = falloffTolerance;
+ splash->style = noStyles ? LS_NORMAL : si->lightStyle;
+ if ( splash->style < LS_NORMAL || splash->style >= LS_NONE ) {
+ splash->style = LS_NORMAL;
+ }
+
+ /* create a regular winding */
+ splash_w = AllocWinding( rw->numVerts );
+ splash_w->numpoints = rw->numVerts;
+ for ( i = 0; i < rw->numVerts; i++ )
+ VectorMA( rw->verts[rw->numVerts - 1 - i].xyz, si->backsplashDistance, normal, splash_w->p[ i ] );
+ splash->w = splash_w;
+
+ VectorMA( light->origin, si->backsplashDistance, normal, splash->origin );
+ VectorNegate( normal, splash->normal );
+ splash->dist = DotProduct( splash->origin, splash->normal );
+
+ // splash->flags |= LIGHT_TWOSIDED;
+ }
+ #endif
+
}
else
{
}
-
/*
RadLightForTriangles()
creates unbounced diffuse lights for triangle soup (misc_models, etc)
}
/* subdivide into area lights */
- RadSubdivideDiffuseLight( lightmapNum, ds, lm, si, scale, subdivide, qtrue, &rw, cw );
+ RadSubdivideDiffuseLight( lightmapNum, ds, lm, si, scale, subdivide, &rw, cw );
}
}
}
/* subdivide into area lights */
- RadSubdivideDiffuseLight( lightmapNum, ds, lm, si, scale, subdivide, qtrue, &rw, cw );
+ RadSubdivideDiffuseLight( lightmapNum, ds, lm, si, scale, subdivide, &rw, cw );
}
/* generate 2 tris */
}
/* subdivide into area lights */
- RadSubdivideDiffuseLight( lightmapNum, ds, lm, si, scale, subdivide, qtrue, &rw, cw );
+ RadSubdivideDiffuseLight( lightmapNum, ds, lm, si, scale, subdivide, &rw, cw );
}
}
}
/* -help */
if ( !strcmp( argv[ i ], "-h" ) || !strcmp( argv[ i ], "--help" )
|| !strcmp( argv[ i ], "-help" ) ) {
- HelpMain(argv[i+1]);
+ HelpMain( ( i + 1 < argc ) ? argv[ i + 1 ] : NULL );
return 0;
}
/* -connect */
if ( !strcmp( argv[ i ], "-connect" ) ) {
- argv[ i ] = NULL;
- i++;
+ if ( ++i >= argc || !argv[ i ] ) {
+ Error( "Out of arguments: No address specified after %s", argv[ i - 1 ] );
+ }
+ argv[ i - 1 ] = NULL;
Broadcast_Setup( argv[ i ] );
argv[ i ] = NULL;
}
/* patch subdivisions */
else if ( !strcmp( argv[ i ], "-subdivisions" ) ) {
- argv[ i ] = NULL;
- i++;
+ if ( ++i >= argc || !argv[ i ] ) {
+ Error( "Out of arguments: No value specified after %s", argv[ i - 1 ] );
+ }
+ argv[ i - 1 ] = NULL;
patchSubdivisions = atoi( argv[ i ] );
argv[ i ] = NULL;
if ( patchSubdivisions <= 0 ) {
/* threads */
else if ( !strcmp( argv[ i ], "-threads" ) ) {
- argv[ i ] = NULL;
- i++;
+ if ( ++i >= argc || !argv[ i ] ) {
+ Error( "Out of arguments: No value specified after %s", argv[ i - 1 ] );
+ }
+ argv[ i - 1 ] = NULL;
numthreads = atoi( argv[ i ] );
argv[ i ] = NULL;
}
Sys_Printf( "Q3Map - v1.0r (c) 1999 Id Software Inc.\n" );
Sys_Printf( "Q3Map (ydnar) - v" Q3MAP_VERSION "\n" );
- Sys_Printf( "NetRadiant - v" RADIANT_VERSION " " __DATE__ " " __TIME__ "\n" );
+ Sys_Printf( RADIANT_NAME " - v" RADIANT_VERSION " " __DATE__ " " __TIME__ "\n" );
Sys_Printf( "%s\n", Q3MAP_MOTD );
Sys_Printf( "%s\n", argv[0] );
/* check if we have enough options left to attempt something */
if ( argc < 2 ) {
- Error( "Usage: %s [general options] [options] mapfile", argv[ 0 ] );
+ Error( "Usage: %s [general options] [options] mapfile\n%s -help for help", argv[ 0 ] , argv[ 0 ] );
}
/* fixaas */
/* ydnar: otherwise create a bsp */
else{
+ /* used to write Smokin'Guns like tex file */
+ compile_map = qtrue;
+
r = BSPMain( argc, argv );
}
------------------------------------------------------------------------------- */
-
-
/* marker */
#define PATH_INIT_C
-
-
/* dependencies */
#include "q3map2.h"
-
-
/* path support */
#define MAX_BASE_PATHS 10
#define MAX_GAME_PATHS 10
#define MAX_PAK_PATHS 200
+qboolean customHomePath = qfalse;
char *homePath;
+
+#if GDEF_OS_MACOS
+char *macLibraryApplicationSupportPath;
+#elif GDEF_OS_XDG
+char *xdgDataHomePath;
+#endif // GDEF_OS_XDG
+
char installPath[ MAX_OS_PATH ];
int numBasePaths;
*/
char *LokiGetHomeDir( void ){
- #ifndef Q_UNIX
+ #if GDEF_OS_WINDOWS
return NULL;
- #else
+ #else // !GDEF_OS_WINDOWS
static char buf[ 4096 ];
struct passwd pw, *pwp;
char *home;
- static char homeBuf[MAX_OS_PATH];
-
/* get the home environment variable */
home = getenv( "HOME" );
/* look up home dir in password database */
- if(!home)
+ if( home == NULL )
{
if ( getpwuid_r( getuid(), &pw, buf, sizeof( buf ), &pwp ) == 0 ) {
return pw.pw_dir;
}
}
- snprintf( homeBuf, sizeof( homeBuf ), "%s/.", home );
-
/* return it */
- return homeBuf;
- #endif
+ return home;
+ #endif // !GDEF_OS_WINDOWS
}
void LokiInitPaths( char *argv0 ){
char *home;
- if ( !homePath ) {
+ if ( homePath == NULL ) {
/* get home dir */
home = LokiGetHomeDir();
if ( home == NULL ) {
/* set home path */
homePath = home;
}
- else {
+ else{
home = homePath;
}
- #ifndef Q_UNIX
+ #if GDEF_OS_MACOS
+ char *subPath = "/Library/Application Support";
+ macLibraryApplicationSupportPath = safe_malloc( sizeof( char ) * ( strlen( home ) + strlen( subPath ) ) + 1 );
+ sprintf( macLibraryApplicationSupportPath, "%s%s", home, subPath );
+ #elif GDEF_OS_XDG
+ xdgDataHomePath = getenv( "XDG_DATA_HOME" );
+
+ if ( xdgDataHomePath == NULL ) {
+ char *subPath = "/.local/share";
+ xdgDataHomePath = safe_malloc( sizeof( char ) * ( strlen( home ) + strlen( subPath ) ) + 1 );
+ sprintf( xdgDataHomePath, "%s%s", home, subPath );
+ }
+ #endif // GDEF_OS_XDG
+
+ #if GDEF_OS_WINDOWS
/* this is kinda crap, but hey */
strcpy( installPath, "../" );
- #else
+ #else // !GDEF_OS_WINDOWS
char temp[ MAX_OS_PATH ];
char *path;
if ( strrchr( temp, '/' ) ) {
argv0 = strrchr( argv0, '/' ) + 1;
}
- else if ( path ) {
+ else if ( path != NULL ) {
/*
This code has a special behavior when q3map2 is a symbolic link.
path++;
}
+
/* concatenate */
if ( last > ( path + 1 ) ) {
// +1 hack: Q_strncat calls Q_strncpyz that expects a len including '\0'
*( strrchr( installPath, '/' ) ) = '\0';
*( strrchr( installPath, '/' ) ) = '\0';
}
- #endif
+ #endif // !GDEF_OS_WINDOWS
}
/*
AddHomeBasePath() - ydnar
- adds a base path to the beginning of the list, prefixed by ~/
+ adds a base path to the beginning of the list
*/
void AddHomeBasePath( char *path ){
int i;
char temp[ MAX_OS_PATH ];
- int homePathLen;
- if ( !homePath ) {
+ if ( homePath == NULL ) {
return;
}
return;
}
- /* strip leading dot, if homePath does not end in /. */
- homePathLen = strlen( homePath );
- if ( !strcmp( path, "." ) ) {
+ if ( strcmp( path, "." ) == 0 ) {
/* -fs_homebase . means that -fs_home is to be used as is */
strcpy( temp, homePath );
}
- else if ( homePathLen >= 2 && !strcmp( homePath + homePathLen - 2, "/." ) ) {
- /* remove trailing /. of homePath */
- homePathLen -= 2;
+ else {
+ char *tempHomePath;
+ tempHomePath = homePath;
- /* concatenate home dir and path */
- sprintf( temp, "%.*s/%s", homePathLen, homePath, path );
+ /* homePath is . on Windows if not user supplied */
+
+ #if GDEF_OS_MACOS
+ /*
+ use ${HOME}/Library/Application as ${HOME}
+ if home path is not user supplied
+ and strip the leading dot from prefix in any case
+
+ basically it produces
+ ${HOME}/Library/Application/unvanquished
+ /user/supplied/home/path/unvanquished
+ */
+ tempHomePath = macLibraryApplicationSupportPath;
+ path = path + 1;
+ #elif GDEF_OS_XDG
+ /*
+ on Linux, check if game uses ${XDG_DATA_HOME}/prefix instead of ${HOME}/.prefix
+ if yes and home path is not user supplied
+ use XDG_DATA_HOME instead of HOME
+ and strip the leading dot
+
+ basically it produces
+ ${XDG_DATA_HOME}/unvanquished
+ /user/supplied/home/path/unvanquished
+
+ or
+ ${HOME}/.q3a
+ /user/supplied/home/path/.q3a
+ */
+
+ sprintf( temp, "%s/%s", xdgDataHomePath, ( path + 1 ) );
+ if ( access( temp, X_OK ) == 0 ) {
+ if ( customHomePath == qfalse ) {
+ tempHomePath = xdgDataHomePath;
- }
+ }
- else
- {
- /* remove leading . of path */
- if ( path[0] == '.' ) {
- ++path;
+ path = path + 1;
}
+ #endif // GDEF_OS_XDG
/* concatenate home dir and path */
- sprintf( temp, "%s/%s", homePath, path );
+ sprintf( temp, "%s/%s", tempHomePath, path );
}
/* make a hole */
/* -game */
if ( strcmp( argv[ i ], "-game" ) == 0 ) {
- if ( ++i >= *argc ) {
+ if ( ++i >= *argc || !argv[ i ] ) {
Error( "Out of arguments: No game specified after %s", argv[ i - 1 ] );
}
argv[ i - 1 ] = NULL;
/* -fs_forbiddenpath */
else if ( strcmp( argv[ i ], "-fs_forbiddenpath" ) == 0 ) {
- if ( ++i >= *argc ) {
+ if ( ++i >= *argc || !argv[ i ] ) {
Error( "Out of arguments: No path specified after %s.", argv[ i - 1 ] );
}
argv[ i - 1 ] = NULL;
/* -fs_basepath */
else if ( strcmp( argv[ i ], "-fs_basepath" ) == 0 ) {
- if ( ++i >= *argc ) {
+ if ( ++i >= *argc || !argv[ i ] ) {
Error( "Out of arguments: No path specified after %s.", argv[ i - 1 ] );
}
argv[ i - 1 ] = NULL;
/* -fs_game */
else if ( strcmp( argv[ i ], "-fs_game" ) == 0 ) {
- if ( ++i >= *argc ) {
+ if ( ++i >= *argc || !argv[ i ] ) {
Error( "Out of arguments: No path specified after %s.", argv[ i - 1 ] );
}
argv[ i - 1 ] = NULL;
/* -fs_home */
else if ( strcmp( argv[ i ], "-fs_home" ) == 0 ) {
- if ( ++i >= *argc ) {
+ if ( ++i >= *argc || !argv[ i ] ) {
Error( "Out of arguments: No path specified after %s.", argv[ i - 1 ] );
}
argv[ i - 1 ] = NULL;
+ customHomePath = qtrue;
homePath = argv[i];
argv[ i ] = NULL;
}
/* -fs_homebase */
else if ( strcmp( argv[ i ], "-fs_homebase" ) == 0 ) {
- if ( ++i >= *argc ) {
+ if ( ++i >= *argc || !argv[ i ] ) {
Error( "Out of arguments: No path specified after %s.", argv[ i - 1 ] );
}
argv[ i - 1 ] = NULL;
/* -fs_homepath - sets both of them */
else if ( strcmp( argv[ i ], "-fs_homepath" ) == 0 ) {
- if ( ++i >= *argc ) {
+ if ( ++i >= *argc || !argv[ i ] ) {
Error( "Out of arguments: No path specified after %s.", argv[ i - 1 ] );
}
argv[ i - 1 ] = NULL;
homeBasePath = ".";
argv[ i ] = NULL;
}
+
+ /* -fs_pakpath */
+ else if ( strcmp( argv[ i ], "-fs_pakpath" ) == 0 ) {
+ if ( ++i >= *argc || !argv[ i ] ) {
+ Error( "Out of arguments: No path specified after %s.", argv[ i - 1 ] );
+ }
+ argv[ i - 1 ] = NULL;
+ AddPakPath( argv[ i ] );
+ argv[ i ] = NULL;
+ }
}
/* remove processed arguments */
------------------------------------------------------------------------------- */
/* platform-specific */
-#if GDEF_OS_LINUX || GDEF_OS_MACOS
- #define Q_UNIX
-#endif
-
-#ifdef Q_UNIX
+#if GDEF_OS_POSIX
#include <unistd.h>
#include <pwd.h>
#include <limits.h>
/* general */
-#include "version.h" /* ttimo: might want to guard that if built outside of the GtkRadiant tree */
-
#include "cmdlib.h"
#include "mathlib.h"
#include "md5lib.h"
------------------------------------------------------------------------------- */
-#define MAC_STATIC_HACK 0
-#if GDEF_OS_MACOS && MAC_STATIC_HACK
- #define MAC_STATIC static
-#else
- #define MAC_STATIC
-#endif
-
-#if 1
#if GDEF_OS_WINDOWS
#define Q_stricmp stricmp
#define Q_strncasecmp strnicmp
#define Q_stricmp strcasecmp
#define Q_strncasecmp strncasecmp
#endif
+
+// hack to declare and define in the same file
+#ifdef MAIN_C
+ #define Q_EXTERN
+ #define Q_ASSIGN( a ) = a
+#else
+ #define Q_EXTERN extern
+ #define Q_ASSIGN( a )
#endif
/* macro version */
/* general */
#define MAX_QPATH 64
-#define MAX_IMAGES 512
+#define MAX_IMAGES 2048
#define DEFAULT_IMAGE "*default"
-#define MAX_MODELS 512
+#define MAX_MODELS 2048
#define DEF_BACKSPLASH_FRACTION 0.05f /* 5% backsplash by default */
#define DEF_BACKSPLASH_DISTANCE 23
#define C_DETAIL 0x08000000 /* THIS MUST BE THE SAME AS IN RADIANT! */
+/* new tex surface flags, like Smokin'Guns */
+#define TEX_SURF_METAL 0x00001000
+#define TEX_SURF_WOOD 0x00080000
+#define TEX_SURF_CLOTH 0x00100000
+#define TEX_SURF_DIRT 0x00200000
+#define TEX_SURF_GLASS 0x00400000
+#define TEX_SURF_PLANT 0x00800000
+#define TEX_SURF_SAND 0x01000000
+#define TEX_SURF_SNOW 0x02000000
+#define TEX_SURF_STONE 0x04000000
+#define TEX_SURF_WATER 0x08000000
+#define TEX_SURF_GRASS 0x10000000
+#define TEX_SURF_BREAKABLE 0x20000000
+
+
/* shadow flags */
#define WORLDSPAWN_CAST_SHADOWS 1
#define WORLDSPAWN_RECV_SHADOWS 1
}
miniMapMode_t;
+typedef enum
+{
+ MINIMAP_SIDECAR_NONE,
+ MINIMAP_SIDECAR_UNVANQUISHED
+}
+miniMapSidecarFormat_t;
+
typedef struct game_s
{
char *arg; /* -game matches this */
int maxLMSurfaceVerts; /* default maximum meta surface verts */
int maxSurfaceVerts; /* default maximum surface verts */
int maxSurfaceIndexes; /* default maximum surface indexes (tris * 3) */
+ qboolean texFile; /* enable per shader prefix surface flags and .tex file */
qboolean emitFlares; /* when true, emit flare surfaces */
char *flareShader; /* default flare shader (MUST BE SET) */
qboolean wolfLight; /* when true, lights work like wolf q3map */
qboolean miniMapKeepAspect; /* minimap keep aspect ratio by letterboxing */
miniMapMode_t miniMapMode; /* minimap mode */
char *miniMapNameFormat; /* minimap name format */
+ miniMapSidecarFormat_t miniMapSidecarFormat; /* minimap sidecar format */
char *bspIdent; /* 4-letter bsp file prefix */
int bspVersion; /* bsp version to use */
qboolean lumpSwap; /* cod-style len/ofs order */
}
surfaceType_t;
-char *surfaceTypes[ NUM_SURFACE_TYPES ]
+Q_EXTERN char *surfaceTypes[ NUM_SURFACE_TYPES ]
#ifndef MAIN_C
;
#else
/* light_ydnar.c */
void ColorToBytes( const float *color, byte *colorBytes, float scale );
+void ColorToBytesNonZero( const float *color, byte *colorBytes, float scale );
void SmoothNormals( void );
void MapRawLightmap( int num );
void SetupSurfaceLightmaps( void );
void StitchSurfaceLightmaps( void );
-void StoreSurfaceLightmaps( qboolean fastAllocate );
+void StoreSurfaceLightmaps( qboolean fastAllocate, qboolean storeForReal );
+ /* exportents.c */
+ void ExportEntities( void );
+ int ExportEntitiesMain( int argc, char **argv );
+
+
/* exportents.c */
void ExportEntities( void );
int ExportEntitiesMain( int argc, char **argv );
void WriteBSPFile( const char *filename );
void PrintBSPFileSizes( void );
+void WriteTexFile( char *name );
+void LoadSurfaceFlags( char *filename );
+int GetSurfaceParm( const char *tex );
+void RestoreSurfaceFlags( char *filename );
+
epair_t *ParseEPair( void );
void ParseEntities( void );
void UnparseEntities( void );
------------------------------------------------------------------------------- */
-#ifdef MAIN_C
- #define Q_EXTERN
- #define Q_ASSIGN( a ) = a
-#else
- #define Q_EXTERN extern
- #define Q_ASSIGN( a )
-#endif
-
/* game support */
Q_EXTERN game_t games[]
#ifndef MAIN_C
=
{
#include "game_quake3.h"
+ ,
+ #include "game_nexuiz.h" /* must be after game_quake3.h as they share defines! */
+ ,
+ #include "game_oa.h" /* must be after game_quake3.h as they share defines! */
+ ,
+ #include "game_q3rally.h" /* must be after game_quake3.h as they share defines! */
,
#include "game_quakelive.h" /* must be after game_quake3.h as they share defines! */
,
- #include "game_nexuiz.h" /* must be after game_quake3.h as they share defines! */
+ #include "game_reaction.h" /* must be after game_quake3.h */
,
- #include "game_xonotic.h" /* must be after game_quake3.h as they share defines! */
+ #include "game_smokinguns.h" /* must be after game_quake3.h */
,
#include "game_tremulous.h" /*LinuxManMikeC: must be after game_quake3.h, depends on #define's set in it */
,
#include "game_unvanquished.h" /* must be after game_tremulous.h as they share defines! */
+ ,
+ #include "game_wop.h" /* must be after game_quake3.h as they share defines! */
+ ,
+ #include "game_xonotic.h" /* must be after game_quake3.h as they share defines! */
,
#include "game_tenebrae.h"
,
,
#include "game_qfusion.h" /* qfusion game */
,
- #include "game_reaction.h" /* must be after game_quake3.h */
+ #include "game_warsow.h" /* must be after game_qfusion.h as they share defines! */
+ ,
+ #include "game_warfork.h" /* must be after game_qfusion.h as they share defines! */
,
- #include "game_darkplaces.h" /* vortex: darkplaces q1 engine */
+ #include "game_darkplaces.h" /* darkplaces q1 engine */
,
- #include "game_dq.h" /* vortex: deluxe quake game ( darkplaces q1 engine) */
+ #include "game_dq.h" /* deluxe quake game ( darkplaces q1 engine) */
,
#include "game_prophecy.h" /* vortex: prophecy game ( darkplaces q1 engine) */
,
/* ydnar: sinusoid samples */
Q_EXTERN float jitters[ MAX_JITTERS ];
-/* can't code */
+/*can't code*/
Q_EXTERN qboolean doingBSP Q_ASSIGN( qfalse );
/* commandline arguments */
-Q_EXTERN qboolean verbose;
Q_EXTERN qboolean verboseEntities Q_ASSIGN( qfalse );
Q_EXTERN qboolean force Q_ASSIGN( qfalse );
Q_EXTERN qboolean infoMode Q_ASSIGN( qfalse );
Q_EXTERN int numBSPAds Q_ASSIGN( 0 );
Q_EXTERN bspAdvertisement_t bspAds[ MAX_MAP_ADVERTISEMENTS ];
-#define AUTOEXPAND_BY_REALLOC( ptr, reqitem, allocated, def ) \
+// Used for tex file support, Smokin'Guns globals
+Q_EXTERN qboolean compile_map;
+
+#define _AUTOEXPAND_BY_REALLOC( ptr, reqitem, allocated, def, fillWithZeros ) \
do \
{ \
+ int prevAllocated = allocated; \
if ( reqitem >= allocated ) \
{ \
if ( allocated == 0 ) { \
- allocated = def; } \
+ allocated = def; \
+ } \
while ( reqitem >= allocated && allocated ) \
+ { \
allocated *= 2; \
+ } \
if ( !allocated || allocated > 2147483647 / (int)sizeof( *ptr ) ) \
{ \
Error( # ptr " over 2 GB" ); \
} \
ptr = realloc( ptr, sizeof( *ptr ) * allocated ); \
if ( !ptr ) { \
- Error( # ptr " out of memory" ); } \
+ Error( #ptr " out of memory" ); \
+ } \
+ if ( fillWithZeros ) \
+ { \
+ memset( ptr + ( sizeof( *ptr ) * prevAllocated ), 0 , sizeof( *ptr ) * ( allocated - prevAllocated ) ); \
+ } \
} \
} \
while ( 0 )
+#define AUTOEXPAND_BY_REALLOC( ptr, reqitem, allocated, def ) _AUTOEXPAND_BY_REALLOC( ptr, reqitem, allocated, def, qfalse )
+
+#define AUTOEXPAND_BY_REALLOC0( ptr, reqitem, allocated, def ) _AUTOEXPAND_BY_REALLOC( ptr, reqitem, allocated, def, qtrue )
+
#define AUTOEXPAND_BY_REALLOC_BSP( suffix, def ) AUTOEXPAND_BY_REALLOC( bsp ## suffix, numBSP ## suffix, allocatedBSP ## suffix, def )
+#define AUTOEXPAND_BY_REALLOC0_BSP( suffix, def ) AUTOEXPAND_BY_REALLOC0( bsp##suffix, numBSP##suffix, allocatedBSP##suffix, def )
+
#define Image_LinearFloatFromsRGBFloat( c ) ( ( ( c ) <= 0.04045f ) ? ( c ) * ( 1.0f / 12.92f ) : (float)pow( ( ( c ) + 0.055f ) * ( 1.0f / 1.055f ), 2.4f ) )
#define Image_sRGBFloatFromLinearFloat( c ) ( ( ( c ) < 0.0031308f ) ? ( c ) * 12.92f : 1.055f * (float)pow( ( c ), 1.0f / 2.4f ) - 0.055f )