/* dependencies */
#include "q3map2.h"
+#if GDEF_OS_POSIX
+#include <sys/ioctl.h>
+#endif // GDEF_OS_POSIX
+static unsigned terminalColumns = 80;
struct HelpOption
{
const char* description;
};
+// FIXME: low column width cause an endless loop
void HelpOptions(const char* group_name, int indentation, int width, struct HelpOption* options, int count)
{
indentation *= 2;
putchar('\n');
printed = indentation+26;
}
+
if ( j == 0 )
{
printf("%s\n",options[i].description+j);
void HelpBsp()
{
struct HelpOption bsp[] = {
- {"-bsp <filename.map>", "Switch that enters this stage"},
+ {"-bsp [options] <filename.map>", "Switch that enters this stage"},
{"-altsplit", "Alternate BSP tree splitting weights (should give more fps)"},
{"-bspfile <filename.bsp>", "BSP file to write"},
{"-celshader <shadername>", "Sets a global cel shader name"},
{"-deep", "Use detail brushes in the BSP tree, but at lowest priority (should give more fps)"},
{"-de <F>", "Distance epsilon for plane snapping etc."},
{"-fakemap", "Write fakemap.map containing all world brushes"},
- {"-flares", "Turn on support for flares (TEST?)"},
+ {"-fastmeta", "Use small lightmap/surface verts/number maximum numbers (like Q3A), to be used with `-meta`"},
+ {"-flares", "Turn on support for flares"},
{"-flat", "Enable flat shading (good for combining with -celshader)"},
{"-fulldetail", "Treat detail brushes as structural ones"},
+ {"-keeplights", "Keep light entities in the BSP file after compile"},
{"-leaktest", "Abort if a leak was found"},
{"-linfile <filename.lin>", "Line file to write"},
+ {"-maxarea", "Use Max Area face surface generation"},
+ {"-maxlightmapvertices <N>", "Sets the maximum number of vertices per lightmapped surface"},
+ {"-maxsurfaceindexes <N>", "Sets the maximum number of indexes per surface"},
+ {"-maxsurfacevertices <N>", "Sets the maximum number of vertices per surface"},
{"-meta", "Combine adjacent triangles of the same texture to surfaces (ALWAYS USE THIS)"},
+ {"-metaadequatescore <N>", "Adequate score for adding triangles to meta surfaces"},
+ {"-metagoodscore <N>", "Good score for adding triangles to meta surfaces"},
+ {"-metamaxbboxdistance <F>", "Maximum bounding box distance for meta surfaces"},
{"-minsamplesize <N>", "Sets minimum lightmap resolution in luxels/qu"},
- {"-mi <N>", "Sets the maximum number of indexes per surface"},
- {"-mv <N>", "Sets the maximum number of vertices of a lightmapped surface"},
+ {"-mi <N>", "Deprecated alias for `-maxsurfaceindexes`"},
+ {"-mv <N>", "Deprecated alias for `-maxlightmapverts`"},
{"-ne <F>", "Normal epsilon for plane snapping etc."},
{"-nocurves", "Turn off support for patches"},
{"-nodetail", "Leave out detail brushes"},
{"-noflares", "Turn off support for flares"},
{"-nofog", "Turn off support for fog volumes"},
{"-nohint", "Turn off support for hint brushes"},
+ {"-nosRGB", "Treat colors and textures as linear colorspace"},
+ {"-nosRGBcolor", "Treat shader and light entity colors as linear colorspace"},
+ {"-nosRGBtex", "Treat textures as linear colorspace"},
{"-nosubdivide", "Turn off support for `q3map_tessSize` (breaks water vertex deforms)"},
{"-notjunc", "Do not fix T-junctions (causes cracks between triangles, do not use)"},
{"-nowater", "Turn off support for water, slime or lava (Stef, this is for you)"},
{"-skyfix", "Turn sky box into six surfaces to work around ATI problems"},
{"-snap <N>", "Snap brush bevel planes to the given number of units"},
{"-srffile <filename.srf>", "Surface file to write"},
+ {"-sRGBcolor", "Treat shader and light entity colors as sRGB colorspace"},
+ {"-sRGBtex", "Treat textures as sRGB colorspace"},
{"-tempname <filename.map>", "Read the MAP file from the given file name"},
{"-texrange <N>", "Limit per-surface texture range to the given number of units, and subdivide surfaces like with `q3map_tessSize` if this is not met"},
{"-tmpout", "Write the BSP file to /tmp"},
{"-verboseentities", "Enable `-v` only for map entities, not for the world"},
};
- HelpOptions("BSP Stage", 0, 80, bsp, sizeof(bsp)/sizeof(struct HelpOption));
+
+ HelpOptions("BSP Stage", 0, terminalColumns, bsp, sizeof(bsp)/sizeof(struct HelpOption));
}
void HelpVis()
{
struct HelpOption vis[] = {
- {"-vis <filename.map>", "Switch that enters this stage"},
+ {"-vis [options] <filename.map>", "Switch that enters this stage"},
{"-fast", "Very fast and crude vis calculation"},
{"-hint", "Merge all but hint portals"},
{"-mergeportals", "The less crude half of `-merge`, makes vis sometimes much faster but doesn't hurt fps usually"},
{"-saveprt", "Keep the Portal file after running vis (so you can run vis again)"},
{"-tmpin", "Use /tmp folder for input"},
{"-tmpout", "Use /tmp folder for output"},
+ {"-v -v", "Extra verbose mode for cluster debug"}, // q3map2 common takes first -v
};
- HelpOptions("VIS Stage", 0, 80, vis, sizeof(vis)/sizeof(struct HelpOption));
+
+ HelpOptions("VIS Stage", 0, terminalColumns, vis, sizeof(vis)/sizeof(struct HelpOption));
}
void HelpLight()
{
struct HelpOption light[] = {
- {"-light <filename.map>", "Switch that enters this stage"},
- {"-vlight <filename.map>", "Deprecated alias for `-light -fast` ... filename.map"},
+ {"-light [options] <filename.map>", "Switch that enters this stage"},
+ {"-vlight [options] <filename.map>", "Deprecated alias for `-light -fast` ... filename.map"},
{"-approx <N>", "Vertex light approximation tolerance (never use in conjunction with deluxemapping)"},
{"-areascale <F, `-area` F>", "Scaling factor for area lights (surfacelight)"},
{"-border", "Add a red border to lightmaps for debugging"},
{"-export", "Export lightmaps when compile finished (like `-export` mode)"},
{"-exposure <F>", "Lightmap exposure to better support overbright spots"},
{"-external", "Force external lightmaps even if at size of internal lightmaps"},
+ {"-extradist <F>", "Extra distance for lights in map units"},
{"-extravisnudge", "Broken feature to nudge the luxel origin to a better vis cluster"},
{"-extrawide", "Deprecated alias for `-super 2 -filter`"},
{"-extra", "Deprecated alias for `-super 2`"},
- {"-fastallocate", "Use `-fastallocate` to trade lightmap size against allocation time (useful with hi res lightmaps on large maps: reduce allocation time from days to minutes for only some extra bytes)"},
+ {"-fastallocate", "Trade lightmap size against packing time (useful with hi res lightmaps on large maps: reduce allocation time from days to minutes for only some extra bytes)"},
+ {"-slowallocate", "Use old (a bit more careful, but much slower) lightmaps packing algorithm (default)"},
{"-fastbounce", "Use `-fast` style lighting for radiosity"},
{"-faster", "Use a faster falloff curve for lighting; also implies `-fast`"},
{"-fastgrid", "Use `-fast` style lighting for the light grid"},
+ {"-fastlightmapsearch", "Deprecated alias for `-fastallocate`"},
{"-fast", "Ignore tiny light contributions"},
- {"-filter", "Lightmap filtering"},
+ {"-fill", "Fill lightmap colors from surrounding pixels to improve JPEG compression"},
+ {"-filter", "Lightmap filtering, doesn't play nice with some other effects, don't use it, use `-samples` instead"},
{"-floodlight", "Enable floodlight (zero-effort somewhat decent lighting)"},
{"-gamma <F>", "Lightmap gamma"},
+ {"-gridambientdirectionality <F>", "Ambient directional lighting received (default: 0.0)"},
{"-gridambientscale <F>", "Scaling factor for the light grid ambient components only"},
+ {"-griddirectionality <F>", "Directional lighting received (default: 1.0)"},
{"-gridscale <F>", "Scaling factor for the light grid only"},
- {"-keeplights", "Keep light entities in the BSP file after compile"},
+ {"-lightanglehl 0", "Disable half lambert light angle attenuation"},
+ {"-lightanglehl 1", "Enable half lambert light angle attenuation"},
{"-lightmapdir <directory>", "Directory to store external lightmaps (default: same as map name without extension)"},
{"-lightmapsearchblocksize <N>", "Restrict lightmap search to block size <N>"},
{"-lightmapsearchpower <N>", "Optimize for lightmap merge power <N>"},
{"-lomem", "Low memory but slower lighting mode"},
{"-lowquality", "Low quality floodlight (appears to currently break floodlight)"},
{"-minsamplesize <N>", "Sets minimum lightmap resolution in luxels/qu"},
+ {"-nobouncestore", "Do not store BSP, lightmap and shader files between bounces"},
{"-nocollapse", "Do not collapse identical lightmaps"},
{"-nodeluxe, -nodeluxemap", "Disable deluxemapping"},
+ {"-nofastpoint", "Disable fast point light calculation"},
{"-nogrid", "Disable grid light calculation (makes all entities fullbright)"},
{"-nolightmapsearch", "Do not optimize lightmap packing for GPU memory usage (as doing so costs fps)"},
{"-normalmap", "Color the lightmaps according to the direction of the surface normal (TODO is this identical to `-debugnormals`?)"},
+ {"-nosRGB", "Treat colors, textures, and lightmaps as linear colorspace"},
+ {"-nosRGBcolor", "Treat shader and light entity colors as linear colorspace"},
+ {"-nosRGBlight", "Write lightmaps as linear colorspace"},
+ {"-nosRGBtex", "Treat textures as linear colorspace"},
{"-nostyle, -nostyles", "Disable support for light styles"},
{"-nosurf", "Disable tracing against surfaces (only uses BSP nodes then)"},
{"-notrace", "Disable shadow occlusion"},
{"-novertex", "Disable vertex lighting"},
{"-patchshadows", "Cast shadows from patches"},
- {"-pointscale <F, `-point` F>", "Scaling factor for point lights (light entities)"},
+ {"-pointscale <F, `-point` F>", "Scaling factor for spherical and spot point lights (light entities)"},
{"-q3", "Use nonlinear falloff curve by default (like Q3A)"},
+ {"-randomsamples", "Use random sampling for lightmaps"},
+ {"-rawlightmapsizelimit <N>", "Sets maximum lightmap resolution in luxels/qu (only affects patches if used -patchmeta in BSP stage)"},
{"-samplescale <F>", "Scales all lightmap resolutions"},
{"-samplesize <N>", "Sets default lightmap resolution in luxels/qu"},
+ {"-samplessearchboxsize <N>", "Search box size (1 to 4) for lightmap adaptive supersampling"},
{"-samples <N>", "Adaptive supersampling quality"},
{"-scale <F>", "Scaling factor for all light types"},
{"-shadeangle <A>", "Angle for phong shading"},
{"-shade", "Enable phong shading at default shade angle"},
{"-skyscale <F, `-sky` F>", "Scaling factor for sky and sun light"},
+ {"-slowallocate", "Use old (a bit more careful, but much slower) lightmaps packing algorithm (default)"},
{"-smooth", "Deprecated alias for `-samples 2`"},
+ {"-sphericalscale <F, `-spherical` F>", "Scaling factor for spherical point light entities"},
+ {"-spotscale <F, `-spot` F>", "Scaling factor for spot point light entities"},
{"-srffile <filename.srf>", "Surface file to read"},
+ {"-sRGB", "Treat colors, textures, and lightmaps as sRGB colorspace"},
+ {"-sRGBcolor", "Treat shader and light entity colors as sRGB colorspace"},
+ {"-sRGBlight", "Write lightmaps as sRGB colorspace"},
+ {"-sRGBtex", "Treat textures as sRGB colorspace"},
{"-style, -styles", "Enable support for light styles"},
{"-sunonly", "Only compute sun light"},
- {"-super <N, `-supersample` N>", "Ordered grid supersampling quality"},
+ {"-super <N, `-supersample` N>", "Ordered grid supersampling quality, much slower than `-samples`"},
{"-thresh <F>", "Triangle subdivision threshold"},
{"-trianglecheck", "Broken check that should ensure luxels apply to the right triangle"},
{"-trisoup", "Convert brush faces to triangle soup"},
{"-wolf", "Use linear falloff curve by default (like W:ET)"},
};
- HelpOptions("Light Stage", 0, 80, light, sizeof(light)/sizeof(struct HelpOption));
+ HelpOptions("Light Stage", 0, terminalColumns, light, sizeof(light)/sizeof(struct HelpOption));
}
void HelpAnalyze()
{
struct HelpOption analyze[] = {
- {"-analyze <filename.bsp>", "Switch that enters this mode"},
+ {"-analyze [options] <filename.bsp>", "Switch that enters this mode"},
{"-lumpswap", "Swap byte order in the lumps"},
};
- HelpOptions("Analyzing BSP-like file structure", 0, 80, analyze, sizeof(analyze)/sizeof(struct HelpOption));
+ HelpOptions("Analyzing BSP-like file structure", 0, terminalColumns, analyze, sizeof(analyze)/sizeof(struct HelpOption));
}
void HelpScale()
{
struct HelpOption scale[] = {
- {"-scale <S filename.bsp>", "Scale uniformly"},
- {"-scale <SX SY SZ filename.bsp>", "Scale non-uniformly"},
- {"-scale -tex <S filename.bsp>", "Scale uniformly without texture lock"},
- {"-scale -tex <SX SY SZ filename.bsp>", "Scale non-uniformly without texture lock"},
+ {"-scale [options] <S filename.bsp>", "Scale uniformly"},
+ {"-scale [options] <SX SY SZ filename.bsp>", "Scale non-uniformly"},
+ {"-tex", "Scale without texture lock"},
+ {"-spawn_ref <F>", "Vertical offset for info_player_* entities (adds spawn_ref, scales, subtracts spawn_ref)"},
};
- HelpOptions("Scaling", 0, 80, scale, sizeof(scale)/sizeof(struct HelpOption));
+
+ HelpOptions("Scaling", 0, terminalColumns, scale, sizeof(scale)/sizeof(struct HelpOption));
}
void HelpConvert()
{
struct HelpOption convert[] = {
- {"-convert <filename.bsp>", "Switch that enters this mode"},
- {"-de <number>", "Distance epsilon for the conversion"},
- {"-format <converter>", "Select the converter (available: map, ase, or game names)"},
- {"-ne <F>", "Normal epsilon for the conversion"},
- {"-shadersasbitmap", "(only for ase) use the shader names as \\*BITMAP key so they work as prefabs"},
+ {"-convert [options] <filename.bsp>", "Switch that enters this mode"},
+ {"-deluxemapsastexcoord", "Save deluxemap names and texcoords instead of textures (only when writing ase and obj)"},
+ {"-de <F>", "Distance epsilon for the conversion (only when reading map)"},
+ {"-format <converter>", "Select the converter, default ase (available: map, map_bp, ase, obj, or game names)"},
+ {"-lightmapsastexcoord", "Save lightmap names and texcoords instead of textures (only when writing ase and obj)"},
+ {"-meta", "Combine adjacent triangles of the same texture to surfaces (only when reading map)"},
+ {"-ne <F>", "Normal epsilon for the conversion (only when reading map)"},
+ {"-patchmeta", "Turn patches into triangle meshes for display (only when reading map)"},
+ {"-readbsp", "Force converting bsp to selected format"},
+ {"-readmap", "Force converting map to selected format"},
+ {"-shadersasbitmap", "Save shader names as bitmap names in the model so it works as a prefab (only when writing ase and obj)"},
};
- HelpOptions("Converting & Decompiling", 0, 80, convert, sizeof(convert)/sizeof(struct HelpOption));
+ HelpOptions("Converting & Decompiling", 0, terminalColumns, convert, sizeof(convert)/sizeof(struct HelpOption));
}
void HelpExport()
{
struct HelpOption exportl[] = {
- {"-export <filename.bsp>", "Copies lightmaps from the BSP to `filename/lightmap_0000.tga` ff"}
+ {"-export <filename.bsp>", "Copies lightmaps from the BSP to `filename/lightmap_0000.tga`"}
};
- HelpOptions("Exporting lightmaps", 0, 80, exportl, sizeof(exportl)/sizeof(struct HelpOption));
+ HelpOptions("Exporting lightmaps", 0, terminalColumns, exportl, sizeof(exportl)/sizeof(struct HelpOption));
}
void HelpExportEnts()
struct HelpOption exportents[] = {
{"-exportents <filename.bsp>", "Exports the entities to a text file (.ent)"},
};
- HelpOptions("ExportEnts Stage", 0, 80, exportents, sizeof(exportents)/sizeof(struct HelpOption));
+ HelpOptions("ExportEnts Stage", 0, terminalColumns, exportents, sizeof(exportents)/sizeof(struct HelpOption));
}
void HelpFixaas()
{"-fixaas <filename.bsp>", "Switch that enters this mode"},
};
- HelpOptions("Fixing AAS checksum", 0, 80, fixaas, sizeof(fixaas)/sizeof(struct HelpOption));
+ HelpOptions("Fixing AAS checksum", 0, terminalColumns, fixaas, sizeof(fixaas)/sizeof(struct HelpOption));
}
void HelpInfo()
{"-info <filename.bsp>", "Switch that enters this mode"},
};
- HelpOptions("Get info about BSP file", 0, 80, info, sizeof(info)/sizeof(struct HelpOption));
+ HelpOptions("Get info about BSP file", 0, terminalColumns, info, sizeof(info)/sizeof(struct HelpOption));
}
void HelpImport()
{"-import <filename.bsp>", "Copies lightmaps from `filename/lightmap_0000.tga` ff into the BSP"},
};
- HelpOptions("Importing lightmaps", 0, 80, import, sizeof(import)/sizeof(struct HelpOption));
+ HelpOptions("Importing lightmaps", 0, terminalColumns, import, sizeof(import)/sizeof(struct HelpOption));
}
void HelpMinimap()
{
struct HelpOption minimap[] = {
- {"-minimap <filename.bsp>", "Creates a minimap of the BSP, by default writes to `../gfx/filename_mini.tga`"},
+ {"-minimap [options] <filename.bsp>", "Creates a minimap of the BSP, by default writes to `../gfx/filename_mini.tga`"},
+ {"-autolevel", "Automatically level brightness and contrast"},
{"-black", "Write the minimap as a black-on-transparency RGBA32 image"},
{"-boost <F>", "Sets the contrast boost value (higher values make a brighter image); contrast boost is somewhat similar to gamma, but continuous even at zero"},
{"-border <F>", "Sets the amount of border pixels relative to the total image size"},
+ {"-brightness <F>", "Sets brightness value to add to minimap values"},
+ {"-contrast <F>", "Sets contrast value to scale minimap values (doesn't affect brightness)"},
{"-gray", "Write the minimap as a white-on-black GRAY8 image"},
{"-keepaspect", "Ensure the aspect ratio is kept (the minimap is then letterboxed to keep aspect)"},
{"-minmax <xmin ymin zmin xmax ymax zmax>", "Forces specific map dimensions (note: the minimap actually uses these dimensions, scaled to the target size while keeping aspect with centering, and 1/64 of border appended to all sides)"},
+ {"-noautolevel", "Do not automatically level brightness and contrast"},
{"-nokeepaspect", "Do not ensure the aspect ratio is kept (makes it easier to use the image in your code, but looks bad together with sharpening)"},
{"-o <filename.tga>", "Sets the output file name"},
{"-random <N>", "Sets the randomized supersampling count (cannot be combined with `-samples`)"},
{"-white", "Write the minimap as a white-on-transparency RGBA32 image"},
};
- HelpOptions("MiniMap", 0, 80, minimap, sizeof(minimap)/sizeof(struct HelpOption));
+ HelpOptions("MiniMap", 0, terminalColumns, minimap, sizeof(minimap)/sizeof(struct HelpOption));
}
void HelpCommon()
{
struct HelpOption common[] = {
- {"-connect <address>", "Talk to a NetRadiant instance using a specific XML based protocol"},
+ {"-connect <address>", "Talk to a " RADIANT_NAME " instance using a specific XML based protocol"},
{"-force", "Allow reading some broken/unsupported BSP files e.g. when decompiling, may also crash"},
{"-fs_basepath <path>", "Sets the given path as main directory of the game (can be used more than once to look in multiple paths)"},
+ {"-fs_forbiddenpath <pattern>", "Pattern to ignore directories, pk3, and pk3dir; example pak?.pk3 (can be used more than once to look for multiple patterns)"},
{"-fs_game <gamename>", "Sets a different game directory name (default for Q3A: baseq3, can be used more than once)"},
- {"-fs_homebase <dir>", "Specifies where the user home directory name is on Linux (default for Q3A: .q3a)"},
- {"-fs_homepath <path>", "Sets the given path as home directory name"},
+ {"-fs_home <dir>", "Specifies where the user home directory is on Linux"},
+ {"-fs_homebase <dir>", "Specifies game home directory relative to user home directory on Linux (default for Q3A: .q3a)"},
+ {"-fs_homepath <path>", "Sets the given path as the game home directory name (fs_home + fs_homebase)"},
{"-fs_nobasepath", "Do not load base paths in VFS, imply -fs_nomagicpath"},
{"-fs_nomagicpath", "Do not try to guess base path magically"},
{"-fs_nohomepath", "Do not load home path in VFS"},
{"-fs_pakpath <path>", "Specify a package directory (can be used more than once to look in multiple paths)"},
{"-game <gamename>", "Load settings for the given game (default: quake3)"},
- {"-subdivisions <F>", "multiplier for patch subdivisions quality"},
- {"-threads <N>", "number of threads to use"},
+ {"-subdivisions <F>", "Multiplier for patch subdivisions quality"},
+ {"-threads <N>", "Number of threads to use"},
{"-v", "Verbose mode"},
{"-werror", "Make all warnings into errors"}
};
- HelpOptions("Common Options", 0, 80, common, sizeof(common)/sizeof(struct HelpOption));
+ HelpOptions("Common Options", 0, terminalColumns, common, sizeof(common)/sizeof(struct HelpOption));
+}
+
+void HelpGames()
+{
+ printf("Games:\n");
+ qboolean begin = qtrue;
+
+ // TODO: sort alphabetically
+ for ( unsigned i = 0, length = 0; games[ i ].arg != NULL; i++ )
+ {
+ // 3 for two whitespaces at the beginning and one (optional) comma a the end
+ if ( length + 3 + strlen( games[ i ].arg ) > terminalColumns )
+ {
+ printf(",\n");
+ length = 0;
+ begin = qtrue;
+ }
+ if ( begin )
+ {
+ printf(" %s", games[ i ].arg );
+ begin = qfalse;
+ }
+ else
+ {
+ printf(", %s", games[ i ].arg );
+ }
+
+ length += 2 + strlen( games[ i ].arg );
+ }
+
+ printf("\n\n");
}
void HelpMain(const char* arg)
{
printf("Usage: q3map2 [stage] [common options...] [stage options...] [stage source file]\n");
- printf(" q3map2 -help [stage]\n\n");
+ printf(" q3map2 -help [stage]\n");
+ printf(" q3map2 -help all\n\n");
+
+#if GDEF_OS_POSIX
+ struct winsize ws;
+ ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws);
+ if (ws.ws_col > 60) {
+ terminalColumns = ws.ws_col;
+ }
+#endif // GDEF_OS_POSIX
HelpCommon();
+ HelpGames();
+
struct HelpOption stages[] = {
{"-bsp", "BSP Stage"},
{"-vis", "VIS Stage"},
{"-import", "Importing lightmaps"},
{"-minimap", "MiniMap"},
};
+
void(*help_funcs[])() = {
HelpBsp,
HelpVis,
if ( arg && strlen(arg) > 0 )
{
if ( arg[0] == '-' )
+ {
arg++;
+ }
- unsigned i;
- for ( i = 0; i < sizeof(stages)/sizeof(struct HelpOption); i++ )
+ if ( strcmp(arg, "all") == 0 )
+ {
+ HelpOptions("Stages", 0, terminalColumns, stages, sizeof(stages)/sizeof(struct HelpOption));
+
+ for ( unsigned i = 0; i < sizeof(stages)/sizeof(struct HelpOption); i++ )
+ {
+ help_funcs[i]();
+ }
+ return;
+ }
+
+ for ( unsigned i = 0; i < sizeof(stages)/sizeof(struct HelpOption); i++ )
+ {
if ( strcmp(arg, stages[i].name+1) == 0 )
{
help_funcs[i]();
return;
}
- }
+ }
+ }
- HelpOptions("Stages", 0, 80, stages, sizeof(stages)/sizeof(struct HelpOption));
+ HelpOptions("Stages", 0, terminalColumns, stages, sizeof(stages)/sizeof(struct HelpOption));
}
/* create a light */
numSunLights++;
- light = safe_malloc( sizeof( *light ) );
- memset( light, 0, sizeof( *light ) );
+ light = safe_malloc0( sizeof( *light ) );
light->next = lights;
lights = light;
/* create a light */
numPointLights++;
- light = safe_malloc( sizeof( *light ) );
- memset( light, 0, sizeof( *light ) );
+ light = safe_malloc0( sizeof( *light ) );
light->next = lights;
lights = light;
VectorScale( origin, 0.5f, origin );
/* create a light */
- light = safe_malloc( sizeof( *light ) );
- memset( light, 0, sizeof( *light ) );
+ light = safe_malloc0( sizeof( *light ) );
light->next = lights;
lights = light;
}
/* vortex: apply gridscale and gridambientscale here */
- ColorToBytes(color, bgp->ambient[i], gridScale * gridAmbientScale);
+ if (gp->directed[i][0] || gp->directed[i][1] || gp->directed[i][2]) {
+ /*
+ * HACK: if there's a non-zero directed component, this
+ * lightgrid cell is useful. However, ioq3 skips grid
+ * cells with zero ambient. So let's force ambient to be
+ * nonzero unless directed is zero too.
+ */
+ ColorToBytesNonZero(color, bgp->ambient[i], gridScale * gridAmbientScale);
+ } else {
+ ColorToBytes( color, bgp->ambient[ i ], gridScale * gridAmbientScale );
+ }
ColorToBytes( gp->directed[ i ], bgp->directed[ i ], gridScale );
}
numBSPGridPoints = numRawGridPoints;
/* allocate lightgrid */
- rawGridPoints = safe_malloc( numRawGridPoints * sizeof( *rawGridPoints ) );
- memset( rawGridPoints, 0, numRawGridPoints * sizeof( *rawGridPoints ) );
+ rawGridPoints = safe_malloc0( numRawGridPoints * sizeof( *rawGridPoints ) );
if ( bspGridPoints != NULL ) {
free( bspGridPoints );
}
- bspGridPoints = safe_malloc( numBSPGridPoints * sizeof( *bspGridPoints ) );
- memset( bspGridPoints, 0, numBSPGridPoints * sizeof( *bspGridPoints ) );
+ bspGridPoints = safe_malloc0( numBSPGridPoints * sizeof( *bspGridPoints ) );
/* clear lightgrid */
for ( i = 0; i < numRawGridPoints; i++ )
does what it says...
*/
-void LightWorld( const char *BSPFilePath, qboolean fastAllocate ){
+void LightWorld( const char *BSPFilePath, qboolean fastAllocate, qboolean noBounceStore ){
vec3_t color;
float f;
int b, bt;
qboolean minVertex, minGrid;
const char *value;
-
/* ydnar: smooth normals */
if ( shade ) {
Sys_Printf( "--- SmoothNormals ---\n" );
/* radiosity */
b = 1;
bt = bounce;
+
while ( bounce > 0 )
{
+ qboolean storeForReal = !noBounceStore;
+
/* store off the bsp between bounces */
- StoreSurfaceLightmaps( fastAllocate );
+ StoreSurfaceLightmaps( fastAllocate, storeForReal );
UnparseEntities();
- Sys_Printf( "Writing %s\n", BSPFilePath );
- WriteBSPFile( BSPFilePath );
+
+ if ( storeForReal ) {
+ Sys_Printf( "Writing %s\n", BSPFilePath );
+ WriteBSPFile( BSPFilePath );
+ }
/* note it */
Sys_Printf( "\n--- Radiosity (bounce %d of %d) ---\n", b, bt );
SetupEnvelopes( qfalse, fastbounce );
if ( numLights == 0 ) {
Sys_Printf( "No diffuse light to calculate, ending radiosity.\n" );
+ if ( noBounceStore ) {
+ break;
+ }
return;
}
bounce--;
b++;
}
+
/* ydnar: store off lightmaps */
- StoreSurfaceLightmaps( fastAllocate );
+ StoreSurfaceLightmaps( fastAllocate, qtrue );
+}
+
+
+
+/*
+ LoadSurfaceFlags()
+ added by spoon to get back the changed surfaceflags
+ from tex file
+*/
+
+void LoadSurfaceFlags( char *filename ) {
+ int i;
+
+ for( i = 0; i < numBSPShaders; i++ ) {
+ shaderInfo_t *si;
+
+ si = ShaderInfoForShader( bspShaders[i].shader );
+
+ bspShaders[ i ].surfaceFlags = si->surfaceFlags;
+ }
}
const char *value;
int lightmapMergeSize = 0;
qboolean lightSamplesInsist = qfalse;
- qboolean fastAllocate = qfalse;
+ qboolean fastAllocate = qtrue;
+ qboolean noBounceStore = qfalse;
/* note it */
Sys_Printf( "--- Light ---\n" );
else if ( !strcmp( argv[ i ], "-lightmapdir" ) ) {
lmCustomDir = argv[i + 1];
+ argv[ i ] = NULL;
i++;
+ argv[ i ] = NULL;
Sys_Printf( "Lightmap directory set to %s\n", lmCustomDir );
externalLightmaps = qtrue;
Sys_Printf( "Storing all lightmaps externally\n" );
Sys_Printf( "Storing bounced light (radiosity) only\n" );
}
+ else if ( !strcmp( argv[ i ], "-nobouncestore" ) ) {
+ noBounceStore = qtrue;
+ Sys_Printf( "Do not store BSP, lightmap and shader files between bounces\n" );
+ }
+
else if ( !strcmp( argv[ i ], "-nocollapse" ) ) {
noCollapse = qtrue;
Sys_Printf( "Identical lightmap collapsing disabled\n" );
Sys_Printf( "Faster mode enabled\n" );
}
- else if ( !strcmp( argv[ i ], "-fastallocate" ) ) {
+ else if ( !strcmp( argv[ i ], "-fastallocate" ) || !strcmp( argv[ i ], "-fastlightmapsearch" ) ) {
fastAllocate = qtrue;
- Sys_Printf( "Fast allocation mode enabled\n" );
+
+ if ( !strcmp( argv[ i ], "-fastlightmapsearch" ) ) {
+ Sys_Printf( "The -fastlightmapsearch argument is deprecated, use \"-fastallocate\" instead\n" );
+ }
+ else {
+ Sys_Printf( "Fast lightmap allocation mode enabled\n" );
+ }
+ }
+
+ else if ( !strcmp( argv[ i ], "-slowallocate" ) ) {
+ fastAllocate = qfalse;
+ Sys_Printf( "Slow lightmap allocation mode enabled (default)\n" );
}
+ else if ( !strcmp( argv[ i ], "-slowallocate" ) ) {
+ fastAllocate = qfalse;
+ Sys_Printf( "Slow allocation mode enabled\n" );
+ }
+
else if ( !strcmp( argv[ i ], "-fastgrid" ) ) {
fastgrid = qtrue;
Sys_Printf( "Fast grid lighting enabled\n" );
else if ( !strcmp( argv[ i ], "-bspfile" ) )
{
strcpy( BSPFilePath, argv[i + 1] );
+ argv[ i ] = NULL;
i++;
+ argv[ i ] = NULL;
Sys_Printf( "Use %s as bsp file\n", BSPFilePath );
}
else if ( !strcmp( argv[ i ], "-srffile" ) )
{
strcpy( surfaceFilePath, argv[i + 1] );
+ argv[ i ] = NULL;
i++;
+ argv[ i ] = NULL;
Sys_Printf( "Use %s as surface file\n", surfaceFilePath );
}
/* unhandled args */
Sys_Printf( "Restricted lightmap searching enabled - block size adjusted to %d\n", lightmapSearchBlockSize );
}
+ /* arg checking */
+ if ( i != ( argc - 1 ) ) {
+ Error( "usage: q3map -light [options] <bspfile>" );
+ }
+
strcpy( source, ExpandArg( argv[ i ] ) );
StripExtension( source );
DefaultExtension( source, ".map" );
SetupTraceNodes();
/* light the world */
- LightWorld( BSPFilePath, fastAllocate );
+ LightWorld( BSPFilePath, fastAllocate, noBounceStore );
/* write out the bsp */
UnparseEntities();
/* allocate a buffer and set it up */
buffer = safe_malloc( width * height * 3 + 18 );
+ /* we may also use safe_malloc0 on the whole instead,
+ * this would just be a bit slower */
memset( buffer, 0, 18 );
buffer[ 2 ] = 2;
buffer[ 12 ] = width & 255;
int ExportLightmapsMain( int argc, char **argv ){
/* arg checking */
- if ( argc < 1 ) {
+ if ( argc < 2 ) {
Sys_Printf( "Usage: q3map -export [-v] <mapname>\n" );
return 0;
}
/* arg checking */
- if ( argc < 1 ) {
+ if ( argc < 2 ) {
Sys_Printf( "Usage: q3map -import [-v] <mapname>\n" );
return 0;
}
/* for planar surfaces, create lightmap vectors for st->xyz conversion */
if ( VectorLength( ds->lightmapVecs[ 2 ] ) || 1 ) { /* ydnar: can't remember what exactly i was thinking here... */
/* allocate space for the vectors */
- lm->vecs = safe_malloc( 3 * sizeof( vec3_t ) );
- memset( lm->vecs, 0, 3 * sizeof( vec3_t ) );
+ lm->vecs = safe_malloc0( 3 * sizeof( vec3_t ) );
VectorCopy( ds->lightmapVecs[ 2 ], lm->vecs[ 2 ] );
/* project stepped lightmap blocks and subtract to get planevecs */
/* allocate a list of surface clusters */
numSurfaceClusters = 0;
maxSurfaceClusters = numBSPLeafSurfaces;
- surfaceClusters = safe_malloc( maxSurfaceClusters * sizeof( *surfaceClusters ) );
- memset( surfaceClusters, 0, maxSurfaceClusters * sizeof( *surfaceClusters ) );
+ surfaceClusters = safe_malloc0( maxSurfaceClusters * sizeof( *surfaceClusters ) );
/* allocate a list for per-surface info */
- surfaceInfos = safe_malloc( numBSPDrawSurfaces * sizeof( *surfaceInfos ) );
- memset( surfaceInfos, 0, numBSPDrawSurfaces * sizeof( *surfaceInfos ) );
+ surfaceInfos = safe_malloc0( numBSPDrawSurfaces * sizeof( *surfaceInfos ) );
for ( i = 0; i < numBSPDrawSurfaces; i++ )
surfaceInfos[ i ].childSurfaceNum = -1;
/* allocate a list of surface indexes to be sorted */
- sortSurfaces = safe_malloc( numBSPDrawSurfaces * sizeof( int ) );
- memset( sortSurfaces, 0, numBSPDrawSurfaces * sizeof( int ) );
+ sortSurfaces = safe_malloc0( numBSPDrawSurfaces * sizeof( int ) );
/* walk each model in the bsp */
for ( i = 0; i < numBSPModels; i++ )
/* allocate a list of surfaces that would go into raw lightmaps */
numLightSurfaces = 0;
- lightSurfaces = safe_malloc( numSurfsLightmapped * sizeof( int ) );
- memset( lightSurfaces, 0, numSurfsLightmapped * sizeof( int ) );
+ lightSurfaces = safe_malloc0( numSurfsLightmapped * sizeof( int ) );
/* allocate a list of raw lightmaps */
numRawSuperLuxels = 0;
numRawLightmaps = 0;
- rawLightmaps = safe_malloc( numSurfsLightmapped * sizeof( *rawLightmaps ) );
- memset( rawLightmaps, 0, numSurfsLightmapped * sizeof( *rawLightmaps ) );
+ rawLightmaps = safe_malloc0( numSurfsLightmapped * sizeof( *rawLightmaps ) );
/* walk the list of sorted surfaces */
for ( i = 0; i < numBSPDrawSurfaces; i++ )
/* allocate vertex luxel storage */
for ( k = 0; k < MAX_LIGHTMAPS; k++ )
{
- vertexLuxels[ k ] = safe_malloc( numBSPDrawVerts * VERTEX_LUXEL_SIZE * sizeof( float ) );
- memset( vertexLuxels[ k ], 0, numBSPDrawVerts * VERTEX_LUXEL_SIZE * sizeof( float ) );
- radVertexLuxels[ k ] = safe_malloc( numBSPDrawVerts * VERTEX_LUXEL_SIZE * sizeof( float ) );
- memset( radVertexLuxels[ k ], 0, numBSPDrawVerts * VERTEX_LUXEL_SIZE * sizeof( float ) );
+ vertexLuxels[ k ] = safe_malloc0( numBSPDrawVerts * VERTEX_LUXEL_SIZE * sizeof( float ) );
+ radVertexLuxels[ k ] = safe_malloc0( numBSPDrawVerts * VERTEX_LUXEL_SIZE * sizeof( float ) );
}
/* emit some stats */
olm->numShaders = 0;
/* allocate buffers */
- olm->lightBits = safe_malloc( ( olm->customWidth * olm->customHeight / 8 ) + 8 );
- memset( olm->lightBits, 0, ( olm->customWidth * olm->customHeight / 8 ) + 8 );
- olm->bspLightBytes = safe_malloc( olm->customWidth * olm->customHeight * 3 );
- memset( olm->bspLightBytes, 0, olm->customWidth * olm->customHeight * 3 );
+ olm->lightBits = safe_malloc0( ( olm->customWidth * olm->customHeight / 8 ) + 8 );
+ olm->bspLightBytes = safe_malloc0( olm->customWidth * olm->customHeight * 3 );
if ( deluxemap ) {
- olm->bspDirBytes = safe_malloc( olm->customWidth * olm->customHeight * 3 );
- memset( olm->bspDirBytes, 0, olm->customWidth * olm->customHeight * 3 );
+ olm->bspDirBytes = safe_malloc0( olm->customWidth * olm->customHeight * 3 );
}
}
qboolean ok;
int xIncrement, yIncrement;
-
/* set default lightmap number (-3 = LIGHTMAP_BY_VERTEX) */
for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
lm->outLightmapNums[ lightmapNum ] = -3;
/* get min number of surfaces */
min = ( alm->numLightSurfaces < blm->numLightSurfaces ? alm->numLightSurfaces : blm->numLightSurfaces );
+ //#define allocate_bigger_first
+ #ifdef allocate_bigger_first
+ /* compare size, allocate bigger first */
+ // fastAllocate commit part: can kick fps by unique lightmap/shader combinations*=~2 + bigger compile time
+ //return -diff; makes packing faster and rough
+ diff = ( blm->w * blm->h ) - ( alm->w * alm->h );
+ if ( diff != 0 ) {
+ return diff;
+ }
+ #endif
/* iterate */
for ( i = 0; i < min; i++ )
{
if ( diff ) {
return diff;
}
-
+ #ifndef allocate_bigger_first
/* compare size */
diff = ( blm->w * blm->h ) - ( alm->w * alm->h );
if ( diff != 0 ) {
return diff;
}
-
+ #endif
/* must be equivalent */
return 0;
}
}
}
-
-
/*
StoreSurfaceLightmaps()
stores the surface lightmaps into the bsp as byte rgb triplets
*/
-void StoreSurfaceLightmaps( qboolean fastAllocate ){
+void StoreSurfaceLightmaps( qboolean fastAllocate, qboolean storeForReal ){
- int i, j, k, x, y, lx, ly, sx, sy, *cluster, mappedSamples;
+ int i, j, k, x, y, lx, ly, sx, sy, *cluster, mappedSamples, timer_start;
int style, size, lightmapNum, lightmapNum2;
float *normal, *luxel, *bspLuxel, *bspLuxel2, *radLuxel, samples, occludedSamples;
vec3_t sample, occludedSample, dirSample, colorMins, colorMaxs;
/* note it */
Sys_FPrintf( SYS_VRB, "Subsampling..." );
+ timer_start = I_FloatTime();
+
/* walk the list of raw lightmaps */
numUsed = 0;
numTwins = 0;
/* allocate bsp luxel storage */
if ( lm->bspLuxels[ lightmapNum ] == NULL ) {
size = lm->w * lm->h * BSP_LUXEL_SIZE * sizeof( float );
- lm->bspLuxels[ lightmapNum ] = safe_malloc( size );
- memset( lm->bspLuxels[ lightmapNum ], 0, size );
+ lm->bspLuxels[ lightmapNum ] = safe_malloc0( size );
}
/* allocate radiosity lightmap storage */
}
}
+ Sys_FPrintf( SYS_VRB, "%d.", (int) ( I_FloatTime() - timer_start ) );
+
/* -----------------------------------------------------------------
convert modelspace deluxemaps to tangentspace
----------------------------------------------------------------- */
vec3_t worldUp, myNormal, myTangent, myBinormal;
float dist;
+ timer_start = I_FloatTime();
+
Sys_Printf( "converting..." );
for ( i = 0; i < numRawLightmaps; i++ )
}
}
}
+
+ Sys_FPrintf( SYS_VRB, "%d.", (int) ( I_FloatTime() - timer_start ) );
}
}
collapse non-unique lightmaps
----------------------------------------------------------------- */
- if ( noCollapse == qfalse && deluxemap == qfalse ) {
+ if ( storeForReal && noCollapse == qfalse && deluxemap == qfalse ) {
/* note it */
Sys_FPrintf( SYS_VRB, "collapsing..." );
+ timer_start = I_FloatTime();
+
/* set all twin refs to null */
for ( i = 0; i < numRawLightmaps; i++ )
{
}
}
}
+
+ Sys_FPrintf( SYS_VRB, "%d.", (int) ( I_FloatTime() - timer_start ) );
}
/* -----------------------------------------------------------------
/* note it */
Sys_FPrintf( SYS_VRB, "sorting..." );
+ timer_start = I_FloatTime();
+
/* allocate a new sorted list */
if ( sortLightmaps == NULL ) {
sortLightmaps = safe_malloc( numRawLightmaps * sizeof( int ) );
sortLightmaps[ i ] = i;
qsort( sortLightmaps, numRawLightmaps, sizeof( int ), CompareRawLightmap );
+ Sys_FPrintf( SYS_VRB, "%d.", (int) ( I_FloatTime() - timer_start ) );
+
/* -----------------------------------------------------------------
allocate output lightmaps
----------------------------------------------------------------- */
- /* note it */
- Sys_FPrintf( SYS_VRB, "allocating..." );
+ if ( storeForReal ) {
+ /* note it */
+ Sys_FPrintf( SYS_VRB, "allocating..." );
- /* kill all existing output lightmaps */
- if ( outLightmaps != NULL ) {
- for ( i = 0; i < numOutLightmaps; i++ )
- {
- free( outLightmaps[ i ].lightBits );
- free( outLightmaps[ i ].bspLightBytes );
+ timer_start = I_FloatTime();
+
+ /* kill all existing output lightmaps */
+ if ( outLightmaps != NULL ) {
+ for ( i = 0; i < numOutLightmaps; i++ )
+ {
+ free( outLightmaps[ i ].lightBits );
+ free( outLightmaps[ i ].bspLightBytes );
+ }
+ free( outLightmaps );
+ outLightmaps = NULL;
}
- free( outLightmaps );
- outLightmaps = NULL;
- }
-
- numLightmapShaders = 0;
- numOutLightmaps = 0;
- numBSPLightmaps = 0;
- numExtLightmaps = 0;
- /* find output lightmap */
- for ( i = 0; i < numRawLightmaps; i++ )
- {
- lm = &rawLightmaps[ sortLightmaps[ i ] ];
- FindOutLightmaps( lm, fastAllocate );
- }
+ numLightmapShaders = 0;
+ numOutLightmaps = 0;
+ numBSPLightmaps = 0;
+ numExtLightmaps = 0;
- /* set output numbers in twinned lightmaps */
- for ( i = 0; i < numRawLightmaps; i++ )
- {
- /* get lightmap */
- lm = &rawLightmaps[ sortLightmaps[ i ] ];
+ /* find output lightmap */
+ for ( i = 0; i < numRawLightmaps; i++ )
+ {
+ lm = &rawLightmaps[ sortLightmaps[ i ] ];
+ FindOutLightmaps( lm, fastAllocate );
+ }
- /* walk lightmaps */
- for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
+ /* set output numbers in twinned lightmaps */
+ for ( i = 0; i < numRawLightmaps; i++ )
{
- /* get twin */
- lm2 = lm->twins[ lightmapNum ];
- if ( lm2 == NULL ) {
- continue;
- }
- lightmapNum2 = lm->twinNums[ lightmapNum ];
+ /* get lightmap */
+ lm = &rawLightmaps[ sortLightmaps[ i ] ];
- /* find output lightmap from twin */
- lm->outLightmapNums[ lightmapNum ] = lm2->outLightmapNums[ lightmapNum2 ];
- lm->lightmapX[ lightmapNum ] = lm2->lightmapX[ lightmapNum2 ];
- lm->lightmapY[ lightmapNum ] = lm2->lightmapY[ lightmapNum2 ];
+ /* walk lightmaps */
+ for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
+ {
+ /* get twin */
+ lm2 = lm->twins[ lightmapNum ];
+ if ( lm2 == NULL ) {
+ continue;
+ }
+ lightmapNum2 = lm->twinNums[ lightmapNum ];
+
+ /* find output lightmap from twin */
+ lm->outLightmapNums[ lightmapNum ] = lm2->outLightmapNums[ lightmapNum2 ];
+ lm->lightmapX[ lightmapNum ] = lm2->lightmapX[ lightmapNum2 ];
+ lm->lightmapY[ lightmapNum ] = lm2->lightmapY[ lightmapNum2 ];
+ }
}
}
+ Sys_FPrintf( SYS_VRB, "%d.", (int) ( I_FloatTime() - timer_start ) );
+
/* -----------------------------------------------------------------
store output lightmaps
----------------------------------------------------------------- */
- /* note it */
- Sys_FPrintf( SYS_VRB, "storing..." );
+ if ( storeForReal ) {
+ /* note it */
+ Sys_FPrintf( SYS_VRB, "storing..." );
- /* count the bsp lightmaps and allocate space */
- if ( bspLightBytes != NULL ) {
- free( bspLightBytes );
- }
- if ( numBSPLightmaps == 0 || externalLightmaps ) {
- numBSPLightBytes = 0;
- bspLightBytes = NULL;
- }
- else
- {
- numBSPLightBytes = ( numBSPLightmaps * game->lightmapSize * game->lightmapSize * 3 );
- bspLightBytes = safe_malloc( numBSPLightBytes );
- memset( bspLightBytes, 0, numBSPLightBytes );
- }
-
- /* walk the list of output lightmaps */
- for ( i = 0; i < numOutLightmaps; i++ )
- {
- /* get output lightmap */
- olm = &outLightmaps[ i ];
-
- /* fill output lightmap */
- if ( lightmapFill ) {
- FillOutLightmap( olm );
+ timer_start = I_FloatTime();
+
+ /* count the bsp lightmaps and allocate space */
+ if ( bspLightBytes != NULL ) {
+ free( bspLightBytes );
+ }
+ if ( numBSPLightmaps == 0 || externalLightmaps ) {
+ numBSPLightBytes = 0;
+ bspLightBytes = NULL;
+ }
+ else
+ {
+ numBSPLightBytes = ( numBSPLightmaps * game->lightmapSize * game->lightmapSize * 3 );
+ bspLightBytes = safe_malloc0( numBSPLightBytes );
}
- /* is this a valid bsp lightmap? */
- if ( olm->lightmapNum >= 0 && !externalLightmaps ) {
- /* copy lighting data */
- lb = bspLightBytes + ( olm->lightmapNum * game->lightmapSize * game->lightmapSize * 3 );
- memcpy( lb, olm->bspLightBytes, game->lightmapSize * game->lightmapSize * 3 );
+ /* walk the list of output lightmaps */
+ for ( i = 0; i < numOutLightmaps; i++ )
+ {
+ /* get output lightmap */
+ olm = &outLightmaps[ i ];
- /* copy direction data */
- if ( deluxemap ) {
- lb = bspLightBytes + ( ( olm->lightmapNum + 1 ) * game->lightmapSize * game->lightmapSize * 3 );
- memcpy( lb, olm->bspDirBytes, game->lightmapSize * game->lightmapSize * 3 );
+ /* fill output lightmap */
+ if ( lightmapFill ) {
+ FillOutLightmap( olm );
}
- }
- /* external lightmap? */
- if ( olm->lightmapNum < 0 || olm->extLightmapNum >= 0 || externalLightmaps ) {
- /* make a directory for the lightmaps */
- Q_mkdir( dirname );
+ /* is this a valid bsp lightmap? */
+ if ( olm->lightmapNum >= 0 && !externalLightmaps ) {
+ /* copy lighting data */
+ lb = bspLightBytes + ( olm->lightmapNum * game->lightmapSize * game->lightmapSize * 3 );
+ memcpy( lb, olm->bspLightBytes, game->lightmapSize * game->lightmapSize * 3 );
- /* set external lightmap number */
- olm->extLightmapNum = numExtLightmaps;
+ /* copy direction data */
+ if ( deluxemap ) {
+ lb = bspLightBytes + ( ( olm->lightmapNum + 1 ) * game->lightmapSize * game->lightmapSize * 3 );
+ memcpy( lb, olm->bspDirBytes, game->lightmapSize * game->lightmapSize * 3 );
+ }
+ }
+
+ /* external lightmap? */
+ if ( olm->lightmapNum < 0 || olm->extLightmapNum >= 0 || externalLightmaps ) {
+ /* make a directory for the lightmaps */
+ Q_mkdir( dirname );
- /* write lightmap */
- sprintf( filename, "%s/" EXTERNAL_LIGHTMAP, dirname, numExtLightmaps );
- Sys_FPrintf( SYS_VRB, "\nwriting %s", filename );
- WriteTGA24( filename, olm->bspLightBytes, olm->customWidth, olm->customHeight, qtrue );
- numExtLightmaps++;
+ /* set external lightmap number */
+ olm->extLightmapNum = numExtLightmaps;
- /* write deluxemap */
- if ( deluxemap ) {
+ /* write lightmap */
sprintf( filename, "%s/" EXTERNAL_LIGHTMAP, dirname, numExtLightmaps );
Sys_FPrintf( SYS_VRB, "\nwriting %s", filename );
- WriteTGA24( filename, olm->bspDirBytes, olm->customWidth, olm->customHeight, qtrue );
+ WriteTGA24( filename, olm->bspLightBytes, olm->customWidth, olm->customHeight, qtrue );
numExtLightmaps++;
- if ( debugDeluxemap ) {
- olm->extLightmapNum++;
+ /* write deluxemap */
+ if ( deluxemap ) {
+ sprintf( filename, "%s/" EXTERNAL_LIGHTMAP, dirname, numExtLightmaps );
+ Sys_FPrintf( SYS_VRB, "\nwriting %s", filename );
+ WriteTGA24( filename, olm->bspDirBytes, olm->customWidth, olm->customHeight, qtrue );
+ numExtLightmaps++;
+
+ if ( debugDeluxemap ) {
+ olm->extLightmapNum++;
+ }
}
}
}
- }
-
- if ( numExtLightmaps > 0 ) {
- Sys_FPrintf( SYS_VRB, "\n" );
- }
- /* delete unused external lightmaps */
- for ( i = numExtLightmaps; i; i++ )
- {
- /* determine if file exists */
- sprintf( filename, "%s/" EXTERNAL_LIGHTMAP, dirname, i );
- if ( !FileExists( filename ) ) {
- break;
+ if ( numExtLightmaps > 0 ) {
+ Sys_FPrintf( SYS_VRB, "\n" );
}
- /* delete it */
- remove( filename );
+ /* delete unused external lightmaps */
+ for ( i = numExtLightmaps; i; i++ )
+ {
+ /* determine if file exists */
+ sprintf( filename, "%s/" EXTERNAL_LIGHTMAP, dirname, i );
+ if ( !FileExists( filename ) ) {
+ break;
+ }
+
+ /* delete it */
+ remove( filename );
+ }
}
+ Sys_FPrintf( SYS_VRB, "%d.", (int) ( I_FloatTime() - timer_start ) );
+
/* -----------------------------------------------------------------
project the lightmaps onto the bsp surfaces
----------------------------------------------------------------- */
- /* note it */
- Sys_FPrintf( SYS_VRB, "projecting..." );
+ if ( storeForReal ) {
+ /* note it */
+ Sys_FPrintf( SYS_VRB, "projecting..." );
- /* walk the list of surfaces */
- for ( i = 0; i < numBSPDrawSurfaces; i++ )
- {
- /* get the surface and info */
- ds = &bspDrawSurfaces[ i ];
- info = &surfaceInfos[ i ];
- lm = info->lm;
- olm = NULL;
-
- /* handle surfaces with identical parent */
- if ( info->parentSurfaceNum >= 0 ) {
- /* preserve original data and get parent */
- parent = &bspDrawSurfaces[ info->parentSurfaceNum ];
- memcpy( &dsTemp, ds, sizeof( *ds ) );
-
- /* overwrite child with parent data */
- memcpy( ds, parent, sizeof( *ds ) );
-
- /* restore key parts */
- ds->fogNum = dsTemp.fogNum;
- ds->firstVert = dsTemp.firstVert;
- ds->firstIndex = dsTemp.firstIndex;
- memcpy( ds->lightmapVecs, dsTemp.lightmapVecs, sizeof( dsTemp.lightmapVecs ) );
-
- /* set vertex data */
- dv = &bspDrawVerts[ ds->firstVert ];
- dvParent = &bspDrawVerts[ parent->firstVert ];
- for ( j = 0; j < ds->numVerts; j++ )
- {
- memcpy( dv[ j ].lightmap, dvParent[ j ].lightmap, sizeof( dv[ j ].lightmap ) );
- memcpy( dv[ j ].color, dvParent[ j ].color, sizeof( dv[ j ].color ) );
- }
+ timer_start = I_FloatTime();
+
+ /* walk the list of surfaces */
+ for ( i = 0; i < numBSPDrawSurfaces; i++ )
+ {
+ /* get the surface and info */
+ ds = &bspDrawSurfaces[ i ];
+ info = &surfaceInfos[ i ];
+ lm = info->lm;
+ olm = NULL;
- /* skip the rest */
- continue;
- }
+ /* handle surfaces with identical parent */
+ if ( info->parentSurfaceNum >= 0 ) {
+ /* preserve original data and get parent */
+ parent = &bspDrawSurfaces[ info->parentSurfaceNum ];
+ memcpy( &dsTemp, ds, sizeof( *ds ) );
- /* handle vertex lit or approximated surfaces */
- else if ( lm == NULL || lm->outLightmapNums[ 0 ] < 0 ) {
- for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
- {
- ds->lightmapNum[ lightmapNum ] = -3;
- ds->lightmapStyles[ lightmapNum ] = ds->vertexStyles[ lightmapNum ];
- }
- }
+ /* overwrite child with parent data */
+ memcpy( ds, parent, sizeof( *ds ) );
- /* handle lightmapped surfaces */
- else
- {
- /* walk lightmaps */
- for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
- {
- /* set style */
- ds->lightmapStyles[ lightmapNum ] = lm->styles[ lightmapNum ];
+ /* restore key parts */
+ ds->fogNum = dsTemp.fogNum;
+ ds->firstVert = dsTemp.firstVert;
+ ds->firstIndex = dsTemp.firstIndex;
+ memcpy( ds->lightmapVecs, dsTemp.lightmapVecs, sizeof( dsTemp.lightmapVecs ) );
- /* handle unused style */
- if ( lm->styles[ lightmapNum ] == LS_NONE || lm->outLightmapNums[ lightmapNum ] < 0 ) {
+ /* set vertex data */
+ dv = &bspDrawVerts[ ds->firstVert ];
+ dvParent = &bspDrawVerts[ parent->firstVert ];
+ for ( j = 0; j < ds->numVerts; j++ )
+ {
+ memcpy( dv[ j ].lightmap, dvParent[ j ].lightmap, sizeof( dv[ j ].lightmap ) );
+ memcpy( dv[ j ].color, dvParent[ j ].color, sizeof( dv[ j ].color ) );
+ }
+
+ /* skip the rest */
+ continue;
+ }
+
+ /* handle vertex lit or approximated surfaces */
+ else if ( lm == NULL || lm->outLightmapNums[ 0 ] < 0 ) {
+ for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
+ {
ds->lightmapNum[ lightmapNum ] = -3;
- continue;
+ ds->lightmapStyles[ lightmapNum ] = ds->vertexStyles[ lightmapNum ];
}
+ }
- /* get output lightmap */
- olm = &outLightmaps[ lm->outLightmapNums[ lightmapNum ] ];
+ /* handle lightmapped surfaces */
+ else
+ {
+ /* walk lightmaps */
+ for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
+ {
+ /* set style */
+ ds->lightmapStyles[ lightmapNum ] = lm->styles[ lightmapNum ];
- /* set bsp lightmap number */
- ds->lightmapNum[ lightmapNum ] = olm->lightmapNum;
+ /* handle unused style */
+ if ( lm->styles[ lightmapNum ] == LS_NONE || lm->outLightmapNums[ lightmapNum ] < 0 ) {
+ ds->lightmapNum[ lightmapNum ] = -3;
+ continue;
+ }
- /* deluxemap debugging makes the deluxemap visible */
- if ( deluxemap && debugDeluxemap && lightmapNum == 0 ) {
- ds->lightmapNum[ lightmapNum ]++;
- }
+ /* get output lightmap */
+ olm = &outLightmaps[ lm->outLightmapNums[ lightmapNum ] ];
- /* calc lightmap origin in texture space */
- lmx = (float) lm->lightmapX[ lightmapNum ] / (float) olm->customWidth;
- lmy = (float) lm->lightmapY[ lightmapNum ] / (float) olm->customHeight;
+ /* set bsp lightmap number */
+ ds->lightmapNum[ lightmapNum ] = olm->lightmapNum;
- /* calc lightmap st coords */
- dv = &bspDrawVerts[ ds->firstVert ];
- ydv = &yDrawVerts[ ds->firstVert ];
- for ( j = 0; j < ds->numVerts; j++ )
- {
- if ( lm->solid[ lightmapNum ] ) {
- dv[ j ].lightmap[ lightmapNum ][ 0 ] = lmx + ( 0.5f / (float) olm->customWidth );
- dv[ j ].lightmap[ lightmapNum ][ 1 ] = lmy + ( 0.5f / (float) olm->customWidth );
+ /* deluxemap debugging makes the deluxemap visible */
+ if ( deluxemap && debugDeluxemap && lightmapNum == 0 ) {
+ ds->lightmapNum[ lightmapNum ]++;
}
- else
+
+ /* calc lightmap origin in texture space */
+ lmx = (float) lm->lightmapX[ lightmapNum ] / (float) olm->customWidth;
+ lmy = (float) lm->lightmapY[ lightmapNum ] / (float) olm->customHeight;
+
+ /* calc lightmap st coords */
+ dv = &bspDrawVerts[ ds->firstVert ];
+ ydv = &yDrawVerts[ ds->firstVert ];
+ for ( j = 0; j < ds->numVerts; j++ )
{
- dv[ j ].lightmap[ lightmapNum ][ 0 ] = lmx + ( ydv[ j ].lightmap[ 0 ][ 0 ] / ( superSample * olm->customWidth ) );
- dv[ j ].lightmap[ lightmapNum ][ 1 ] = lmy + ( ydv[ j ].lightmap[ 0 ][ 1 ] / ( superSample * olm->customHeight ) );
+ if ( lm->solid[ lightmapNum ] ) {
+ dv[ j ].lightmap[ lightmapNum ][ 0 ] = lmx + ( 0.5f / (float) olm->customWidth );
+ dv[ j ].lightmap[ lightmapNum ][ 1 ] = lmy + ( 0.5f / (float) olm->customWidth );
+ }
+ else
+ {
+ dv[ j ].lightmap[ lightmapNum ][ 0 ] = lmx + ( ydv[ j ].lightmap[ 0 ][ 0 ] / ( superSample * olm->customWidth ) );
+ dv[ j ].lightmap[ lightmapNum ][ 1 ] = lmy + ( ydv[ j ].lightmap[ 0 ][ 1 ] / ( superSample * olm->customHeight ) );
+ }
}
}
}
- }
- /* store vertex colors */
- dv = &bspDrawVerts[ ds->firstVert ];
- for ( j = 0; j < ds->numVerts; j++ )
- {
- /* walk lightmaps */
- for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
+ /* store vertex colors */
+ dv = &bspDrawVerts[ ds->firstVert ];
+ for ( j = 0; j < ds->numVerts; j++ )
{
- /* handle unused style */
- if ( ds->vertexStyles[ lightmapNum ] == LS_NONE ) {
- VectorClear( color );
- }
- else
+ /* walk lightmaps */
+ for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
{
- /* get vertex color */
- luxel = VERTEX_LUXEL( lightmapNum, ds->firstVert + j );
- VectorCopy( luxel, color );
+ /* handle unused style */
+ if ( ds->vertexStyles[ lightmapNum ] == LS_NONE ) {
+ VectorClear( color );
+ }
+ else
+ {
+ /* get vertex color */
+ luxel = VERTEX_LUXEL( lightmapNum, ds->firstVert + j );
+ VectorCopy( luxel, color );
- /* set minimum light */
- if ( lightmapNum == 0 ) {
- for ( k = 0; k < 3; k++ )
- if ( color[ k ] < minVertexLight[ k ] ) {
- color[ k ] = minVertexLight[ k ];
- }
+ /* set minimum light */
+ if ( lightmapNum == 0 ) {
+ for ( k = 0; k < 3; k++ )
+ if ( color[ k ] < minVertexLight[ k ] ) {
+ color[ k ] = minVertexLight[ k ];
+ }
+ }
}
- }
- /* store to bytes */
- if ( !info->si->noVertexLight ) {
- ColorToBytes( color, dv[ j ].color[ lightmapNum ], info->si->vertexScale );
+ /* store to bytes */
+ if ( !info->si->noVertexLight ) {
+ ColorToBytes( color, dv[ j ].color[ lightmapNum ], info->si->vertexScale );
+ }
}
}
- }
-
- /* surfaces with styled lightmaps and a style marker get a custom generated shader (fixme: make this work with external lightmaps) */
- if ( olm != NULL && lm != NULL && lm->styles[ 1 ] != LS_NONE && game->load != LoadRBSPFile ) { //% info->si->styleMarker > 0 )
- qboolean dfEqual;
- char key[ 32 ], styleStage[ 512 ], styleStages[ 4096 ], rgbGen[ 128 ], alphaGen[ 128 ];
-
- /* setup */
- sprintf( styleStages, "\n\t// Q3Map2 custom lightstyle stage(s)\n" );
- dv = &bspDrawVerts[ ds->firstVert ];
-
- /* depthFunc equal? */
- if ( info->si->styleMarker == 2 || info->si->implicitMap == IM_MASKED ) {
- dfEqual = qtrue;
- }
- else{
- dfEqual = qfalse;
- }
+ /* surfaces with styled lightmaps and a style marker get a custom generated shader (fixme: make this work with external lightmaps) */
+ if ( olm != NULL && lm != NULL && lm->styles[ 1 ] != LS_NONE && game->load != LoadRBSPFile ) { //% info->si->styleMarker > 0 )
+ qboolean dfEqual;
+ char key[ 32 ], styleStage[ 512 ], styleStages[ 4096 ], rgbGen[ 128 ], alphaGen[ 128 ];
- /* generate stages for styled lightmaps */
- for ( lightmapNum = 1; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
- {
- /* early out */
- style = lm->styles[ lightmapNum ];
- if ( style == LS_NONE || lm->outLightmapNums[ lightmapNum ] < 0 ) {
- continue;
- }
- /* get output lightmap */
- olm = &outLightmaps[ lm->outLightmapNums[ lightmapNum ] ];
+ /* setup */
+ sprintf( styleStages, "\n\t// Q3Map2 custom lightstyle stage(s)\n" );
+ dv = &bspDrawVerts[ ds->firstVert ];
- /* lightmap name */
- if ( lm->outLightmapNums[ lightmapNum ] == lm->outLightmapNums[ 0 ] ) {
- strcpy( lightmapName, "$lightmap" );
+ /* depthFunc equal? */
+ if ( info->si->styleMarker == 2 || info->si->implicitMap == IM_MASKED ) {
+ dfEqual = qtrue;
}
else{
- sprintf( lightmapName, "maps/%s/" EXTERNAL_LIGHTMAP, mapName, olm->extLightmapNum );
+ dfEqual = qfalse;
}
- /* get rgbgen string */
- if ( rgbGenValues[ style ] == NULL ) {
- sprintf( key, "_style%drgbgen", style );
- rgbGenValues[ style ] = ValueForKey( &entities[ 0 ], key );
- if ( rgbGenValues[ style ][ 0 ] == '\0' ) {
- rgbGenValues[ style ] = "wave noise 0.5 1 0 5.37";
+ /* generate stages for styled lightmaps */
+ for ( lightmapNum = 1; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
+ {
+ /* early out */
+ style = lm->styles[ lightmapNum ];
+ if ( style == LS_NONE || lm->outLightmapNums[ lightmapNum ] < 0 ) {
+ continue;
+ }
+
+ /* get output lightmap */
+ olm = &outLightmaps[ lm->outLightmapNums[ lightmapNum ] ];
+
+ /* lightmap name */
+ if ( lm->outLightmapNums[ lightmapNum ] == lm->outLightmapNums[ 0 ] ) {
+ strcpy( lightmapName, "$lightmap" );
+ }
+ else{
+ sprintf( lightmapName, "maps/%s/" EXTERNAL_LIGHTMAP, mapName, olm->extLightmapNum );
+ }
+
+ /* get rgbgen string */
+ if ( rgbGenValues[ style ] == NULL ) {
+ sprintf( key, "_style%drgbgen", style );
+ rgbGenValues[ style ] = ValueForKey( &entities[ 0 ], key );
+ if ( rgbGenValues[ style ][ 0 ] == '\0' ) {
+ rgbGenValues[ style ] = "wave noise 0.5 1 0 5.37";
+ }
}
- }
- rgbGen[ 0 ] = '\0';
- if ( rgbGenValues[ style ][ 0 ] != '\0' ) {
- sprintf( rgbGen, "\t\trgbGen %s // style %d\n", rgbGenValues[ style ], style );
- }
- else{
rgbGen[ 0 ] = '\0';
- }
+ if ( rgbGenValues[ style ][ 0 ] != '\0' ) {
+ sprintf( rgbGen, "\t\trgbGen %s // style %d\n", rgbGenValues[ style ], style );
+ }
+ else{
+ rgbGen[ 0 ] = '\0';
+ }
- /* get alphagen string */
- if ( alphaGenValues[ style ] == NULL ) {
- sprintf( key, "_style%dalphagen", style );
- alphaGenValues[ style ] = ValueForKey( &entities[ 0 ], key );
- }
- if ( alphaGenValues[ style ][ 0 ] != '\0' ) {
- sprintf( alphaGen, "\t\talphaGen %s // style %d\n", alphaGenValues[ style ], style );
- }
- else{
- alphaGen[ 0 ] = '\0';
- }
+ /* get alphagen string */
+ if ( alphaGenValues[ style ] == NULL ) {
+ sprintf( key, "_style%dalphagen", style );
+ alphaGenValues[ style ] = ValueForKey( &entities[ 0 ], key );
+ }
+ if ( alphaGenValues[ style ][ 0 ] != '\0' ) {
+ sprintf( alphaGen, "\t\talphaGen %s // style %d\n", alphaGenValues[ style ], style );
+ }
+ else{
+ alphaGen[ 0 ] = '\0';
+ }
- /* calculate st offset */
- lmx = dv[ 0 ].lightmap[ lightmapNum ][ 0 ] - dv[ 0 ].lightmap[ 0 ][ 0 ];
- lmy = dv[ 0 ].lightmap[ lightmapNum ][ 1 ] - dv[ 0 ].lightmap[ 0 ][ 1 ];
-
- /* create additional stage */
- if ( lmx == 0.0f && lmy == 0.0f ) {
- sprintf( styleStage, "\t{\n"
- "\t\tmap %s\n" /* lightmap */
- "\t\tblendFunc GL_SRC_ALPHA GL_ONE\n"
- "%s" /* depthFunc equal */
- "%s" /* rgbGen */
- "%s" /* alphaGen */
- "\t\ttcGen lightmap\n"
- "\t}\n",
- lightmapName,
- ( dfEqual ? "\t\tdepthFunc equal\n" : "" ),
- rgbGen,
- alphaGen );
+ /* calculate st offset */
+ lmx = dv[ 0 ].lightmap[ lightmapNum ][ 0 ] - dv[ 0 ].lightmap[ 0 ][ 0 ];
+ lmy = dv[ 0 ].lightmap[ lightmapNum ][ 1 ] - dv[ 0 ].lightmap[ 0 ][ 1 ];
+
+ /* create additional stage */
+ if ( lmx == 0.0f && lmy == 0.0f ) {
+ sprintf( styleStage, "\t{\n"
+ "\t\tmap %s\n" /* lightmap */
+ "\t\tblendFunc GL_SRC_ALPHA GL_ONE\n"
+ "%s" /* depthFunc equal */
+ "%s" /* rgbGen */
+ "%s" /* alphaGen */
+ "\t\ttcGen lightmap\n"
+ "\t}\n",
+ lightmapName,
+ ( dfEqual ? "\t\tdepthFunc equal\n" : "" ),
+ rgbGen,
+ alphaGen );
+ }
+ else
+ {
+ sprintf( styleStage, "\t{\n"
+ "\t\tmap %s\n" /* lightmap */
+ "\t\tblendFunc GL_SRC_ALPHA GL_ONE\n"
+ "%s" /* depthFunc equal */
+ "%s" /* rgbGen */
+ "%s" /* alphaGen */
+ "\t\ttcGen lightmap\n"
+ "\t\ttcMod transform 1 0 0 1 %1.5f %1.5f\n" /* st offset */
+ "\t}\n",
+ lightmapName,
+ ( dfEqual ? "\t\tdepthFunc equal\n" : "" ),
+ rgbGen,
+ alphaGen,
+ lmx, lmy );
+
+ }
+
+ /* concatenate */
+ strcat( styleStages, styleStage );
}
- else
- {
- sprintf( styleStage, "\t{\n"
- "\t\tmap %s\n" /* lightmap */
- "\t\tblendFunc GL_SRC_ALPHA GL_ONE\n"
- "%s" /* depthFunc equal */
- "%s" /* rgbGen */
- "%s" /* alphaGen */
- "\t\ttcGen lightmap\n"
- "\t\ttcMod transform 1 0 0 1 %1.5f %1.5f\n" /* st offset */
- "\t}\n",
- lightmapName,
- ( dfEqual ? "\t\tdepthFunc equal\n" : "" ),
- rgbGen,
- alphaGen,
- lmx, lmy );
+ /* create custom shader */
+ if ( info->si->styleMarker == 2 ) {
+ csi = CustomShader( info->si, "q3map_styleMarker2", styleStages );
+ }
+ else{
+ csi = CustomShader( info->si, "q3map_styleMarker", styleStages );
}
- /* concatenate */
- strcat( styleStages, styleStage );
- }
+ /* emit remap command */
+ //% EmitVertexRemapShader( csi->shader, info->si->shader );
- /* create custom shader */
- if ( info->si->styleMarker == 2 ) {
- csi = CustomShader( info->si, "q3map_styleMarker2", styleStages );
- }
- else{
- csi = CustomShader( info->si, "q3map_styleMarker", styleStages );
+ /* store it */
+ //% Sys_Printf( "Emitting: %s (%d", csi->shader, strlen( csi->shader ) );
+ ds->shaderNum = EmitShader( csi->shader, &bspShaders[ ds->shaderNum ].contentFlags, &bspShaders[ ds->shaderNum ].surfaceFlags );
+ //% Sys_Printf( ")\n" );
}
- /* emit remap command */
- //% EmitVertexRemapShader( csi->shader, info->si->shader );
-
- /* store it */
- //% Sys_Printf( "Emitting: %s (%d", csi->shader, strlen( csi->shader ) );
- ds->shaderNum = EmitShader( csi->shader, &bspShaders[ ds->shaderNum ].contentFlags, &bspShaders[ ds->shaderNum ].surfaceFlags );
- //% Sys_Printf( ")\n" );
- }
-
- /* devise a custom shader for this surface (fixme: make this work with light styles) */
- else if ( olm != NULL && lm != NULL && !externalLightmaps &&
- ( olm->customWidth != game->lightmapSize || olm->customHeight != game->lightmapSize ) ) {
- /* get output lightmap */
- olm = &outLightmaps[ lm->outLightmapNums[ 0 ] ];
+ /* devise a custom shader for this surface (fixme: make this work with light styles) */
+ else if ( olm != NULL && lm != NULL && !externalLightmaps &&
+ ( olm->customWidth != game->lightmapSize || olm->customHeight != game->lightmapSize ) ) {
+ /* get output lightmap */
+ olm = &outLightmaps[ lm->outLightmapNums[ 0 ] ];
- /* do some name mangling */
- sprintf( lightmapName, "maps/%s/" EXTERNAL_LIGHTMAP, mapName, olm->extLightmapNum );
+ /* do some name mangling */
+ sprintf( lightmapName, "maps/%s/" EXTERNAL_LIGHTMAP, mapName, olm->extLightmapNum );
- /* create custom shader */
- csi = CustomShader( info->si, "$lightmap", lightmapName );
+ /* create custom shader */
+ csi = CustomShader( info->si, "$lightmap", lightmapName );
- /* store it */
- //% Sys_Printf( "Emitting: %s (%d", csi->shader, strlen( csi->shader ) );
- ds->shaderNum = EmitShader( csi->shader, &bspShaders[ ds->shaderNum ].contentFlags, &bspShaders[ ds->shaderNum ].surfaceFlags );
- //% Sys_Printf( ")\n" );
- }
+ /* store it */
+ //% Sys_Printf( "Emitting: %s (%d", csi->shader, strlen( csi->shader ) );
+ ds->shaderNum = EmitShader( csi->shader, &bspShaders[ ds->shaderNum ].contentFlags, &bspShaders[ ds->shaderNum ].surfaceFlags );
+ //% Sys_Printf( ")\n" );
+ }
- /* use the normal plain-jane shader */
- else{
- ds->shaderNum = EmitShader( info->si->shader, &bspShaders[ ds->shaderNum ].contentFlags, &bspShaders[ ds->shaderNum ].surfaceFlags );
+ /* use the normal plain-jane shader */
+ else{
+ ds->shaderNum = EmitShader( info->si->shader, &bspShaders[ ds->shaderNum ].contentFlags, &bspShaders[ ds->shaderNum ].surfaceFlags );
+ }
}
}
+ Sys_FPrintf( SYS_VRB, "%d.", (int) ( I_FloatTime() - timer_start ) );
+
/* finish */
Sys_FPrintf( SYS_VRB, "done.\n" );
? 0
: (float) numUsed / (float) numStored;
- /* print stats */
- Sys_Printf( "%9d luxels used\n", numUsed );
- Sys_Printf( "%9d luxels stored (%3.2f percent efficiency)\n", numStored, efficiency * 100.0f );
- Sys_Printf( "%9d solid surface lightmaps\n", numSolidLightmaps );
- Sys_Printf( "%9d identical surface lightmaps, using %d luxels\n", numTwins, numTwinLuxels );
- Sys_Printf( "%9d vertex forced surfaces\n", numSurfsVertexForced );
- Sys_Printf( "%9d vertex approximated surfaces\n", numSurfsVertexApproximated );
- Sys_Printf( "%9d BSP lightmaps\n", numBSPLightmaps );
- Sys_Printf( "%9d total lightmaps\n", numOutLightmaps );
- Sys_Printf( "%9d unique lightmap/shader combinations\n", numLightmapShaders );
-
- /* write map shader file */
- WriteMapShaderFile();
+ if ( storeForReal ) {
+ /* print stats */
+ Sys_Printf( "%9d luxels used\n", numUsed );
+ Sys_Printf( "%9d luxels stored (%3.2f percent efficiency)\n", numStored, efficiency * 100.0f );
+ Sys_Printf( "%9d solid surface lightmaps\n", numSolidLightmaps );
+ Sys_Printf( "%9d identical surface lightmaps, using %d luxels\n", numTwins, numTwinLuxels );
+ Sys_Printf( "%9d vertex forced surfaces\n", numSurfsVertexForced );
+ Sys_Printf( "%9d vertex approximated surfaces\n", numSurfsVertexApproximated );
+ Sys_Printf( "%9d BSP lightmaps\n", numBSPLightmaps );
+ Sys_Printf( "%9d total lightmaps\n", numOutLightmaps );
+ Sys_Printf( "%9d unique lightmap/shader combinations\n", numLightmapShaders );
+
+ /* write map shader file */
+ WriteMapShaderFile();
+ }
}
char *skinfilecontent;
int skinfilesize;
char *skinfileptr, *skinfilenextptr;
- int ok=0, notok=0, spf = ( spawnFlags & 8088 );
+ //int ok=0, notok=0;
+ int spf = ( spawnFlags & 8088 );
float limDepth=0;
/* set particulars */
ds->numVerts = PicoGetSurfaceNumVertexes( surface );
- ds->verts = safe_malloc( ds->numVerts * sizeof( ds->verts[ 0 ] ) );
- memset( ds->verts, 0, ds->numVerts * sizeof( ds->verts[ 0 ] ) );
+ ds->verts = safe_malloc0( ds->numVerts * sizeof( ds->verts[ 0 ] ) );
ds->numIndexes = PicoGetSurfaceNumIndexes( surface );
- ds->indexes = safe_malloc( ds->numIndexes * sizeof( ds->indexes[ 0 ] ) );
- memset( ds->indexes, 0, ds->numIndexes * sizeof( ds->indexes[ 0 ] ) );
+ ds->indexes = safe_malloc0( ds->numIndexes * sizeof( ds->indexes[ 0 ] ) );
/* copy vertexes */
for ( i = 0; i < ds->numVerts; i++ )
( spf == 5632 ) || //EXTRUDE_DOWNWARDS+EXTRUDE_UPWARDS+AXIAL_BACKPLANE
( spf == 3072 ) || //EXTRUDE_UPWARDS+MAX_EXTRUDE
( spf == 5120 ) ){ //EXTRUDE_UPWARDS+AXIAL_BACKPLANE
- vec3_t points[ 4 ], backs[ 3 ], cnt, bestNormal, nrm, Vnorm[3], Enorm[3];
+ vec3_t points[ 4 ], cnt, bestNormal, nrm, Vnorm[3], Enorm[3];
vec4_t plane, reverse, p[3];
double normalEpsilon_save;
qboolean snpd;
------------------------------------------------------------------------------- */
/* 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 )
ds->sampleSize = b->lightmapSampleSize;
ds->lightmapScale = b->lightmapScale;
ds->numVerts = w->numpoints;
- ds->verts = safe_malloc( ds->numVerts * sizeof( *ds->verts ) );
- memset( ds->verts, 0, ds->numVerts * sizeof( *ds->verts ) );
+ ds->verts = safe_malloc0( ds->numVerts * sizeof( *ds->verts ) );
/* compute s/t coordinates from brush primitive texture matrix (compute axis base) */
ComputeAxisBase( mapplanes[ s->planenum ].normal, texX, texY );
int FilterWindingIntoTree_r( winding_t *w, mapDrawSurface_t *ds, node_t *node ){
int i, refs = 0;
- plane_t *p1, *p2;
- vec4_t plane1, plane2;
+ plane_t *p1;
+ vec4_t plane1;
winding_t *fat, *front, *back;
shaderInfo_t *si;
/* check if surface is planar */
if ( ds->planeNum >= 0 ) {
+ #if 0
+ plane_t *p2;
+ vec4_t plane2;
+
/* get surface plane */
p2 = &mapplanes[ ds->planeNum ];
VectorCopy( p2->normal, plane2 );
plane2[ 3 ] = p2->dist;
- #if 0
/* div0: this is the plague (inaccurate) */
vec4_t reverse;
return FilterWindingIntoTree_r( w, ds, node->children[ 1 ] );
}
#else
- (void) plane2;
/* div0: this is the cholera (doesn't hit enough) */
/* the drawsurf might have an associated plane, if so, force a filter here */
VectorCopy( p->plane.normal, ds->lightmapVecs[ 2 ] );
ds->fogNum = -1;
ds->numVerts = w->numpoints;
- ds->verts = safe_malloc( ds->numVerts * sizeof( *ds->verts ) );
- memset( ds->verts, 0, ds->numVerts * sizeof( *ds->verts ) );
+ ds->verts = safe_malloc0( ds->numVerts * sizeof( *ds->verts ) );
/* walk the winding */
for ( i = 0; i < ds->numVerts; i++ )
ds->shaderInfo = si;
ds->fogNum = -1;
ds->numVerts = 8;
- ds->verts = safe_malloc( ds->numVerts * sizeof( *ds->verts ) );
- memset( ds->verts, 0, ds->numVerts * sizeof( *ds->verts ) );
+ ds->verts = safe_malloc0( ds->numVerts * sizeof( *ds->verts ) );
ds->numIndexes = 36;
- ds->indexes = safe_malloc( ds->numIndexes * sizeof( *ds->indexes ) );
- memset( ds->indexes, 0, ds->numIndexes * sizeof( *ds->indexes ) );
+ ds->indexes = safe_malloc0( ds->numIndexes * sizeof( *ds->indexes ) );
/* set verts */
VectorSet( ds->verts[ 0 ].xyz, fogMins[ 0 ], fogMins[ 1 ], fogMins[ 2 ] );