]> de.git.xonotic.org Git - xonotic/netradiant.git/commitdiff
Merge commit 'aa4bc3893f6c0c360c91896eba46631e53b2f0d1' into master-merge
authorThomas Debesse <dev@illwieckz.net>
Tue, 21 Jun 2022 04:18:35 +0000 (06:18 +0200)
committerThomas Debesse <dev@illwieckz.net>
Tue, 21 Jun 2022 04:18:35 +0000 (06:18 +0200)
1  2 
tools/quake3/q3map2/help.c
tools/quake3/q3map2/light.c
tools/quake3/q3map2/lightmaps_ydnar.c
tools/quake3/q3map2/model.c
tools/quake3/q3map2/q3map2.h
tools/quake3/q3map2/surface.c

index 60631e3d72f175a38c581b28a50df232ea8289ab,53cccff9470cd10ba68650a354f16546b58c997d..fe613d042936d168d0fe75255b46a242edb78a2d
  /* dependencies */
  #include "q3map2.h"
  
 +#if GDEF_OS_POSIX
 +#include <sys/ioctl.h>
 +#endif // GDEF_OS_POSIX
  
 +static unsigned terminalColumns = 80;
  
  struct HelpOption
  {
@@@ -43,7 -39,6 +43,7 @@@
        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;
@@@ -73,7 -68,6 +73,7 @@@
                        putchar('\n');
                        printed = indentation+26;
                }
 +
                if ( j == 0 )
                {
                        printf("%s\n",options[i].description+j);
@@@ -92,7 -86,7 +92,7 @@@
  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));
  }
index f14cc43c843c4f8c8efdb30d632767832898ca82,7d3be10e592df2b826ec280ea1f336f374ef0707..20252c36a9d2b113efa943cf0f4d771722e38006
@@@ -107,7 -107,8 +107,7 @@@ static void CreateSunLight( sun_t *sun 
  
                /* create a light */
                numSunLights++;
 -              light = safe_malloc( sizeof( *light ) );
 -              memset( light, 0, sizeof( *light ) );
 +              light = safe_malloc0( sizeof( *light ) );
                light->next = lights;
                lights = light;
  
@@@ -253,7 -254,8 +253,7 @@@ void CreateEntityLights( void )
  
                /* create a light */
                numPointLights++;
 -              light = safe_malloc( sizeof( *light ) );
 -              memset( light, 0, sizeof( *light ) );
 +              light = safe_malloc0( sizeof( *light ) );
                light->next = lights;
                lights = light;
  
@@@ -590,7 -592,8 +590,7 @@@ void CreateSurfaceLights( void )
                        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;
  
@@@ -1771,17 -1774,7 +1771,17 @@@ void TraceGrid( int num )
                        }
  
                /* 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 );
        }
  
@@@ -1864,12 -1857,14 +1864,12 @@@ void SetupGrid( void )
        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;
 +      }
  }
  
  
@@@ -2153,8 -2119,7 +2153,8 @@@ int LightMain( int argc, char **argv )
        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();
index 3c08c8b60d13c1223ba795bdf08a556121300bf1,6d61b8d7be998c8e83762df7d17b75935f233c6b..2802ecaf4370c223b2d8c3e29ce6b8061154ca9d
@@@ -67,8 -67,6 +67,8 @@@ void WriteTGA24( char *filename, byte *
  
        /* 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;
@@@ -155,7 -153,7 +155,7 @@@ void ExportLightmaps( void )
  
  int ExportLightmapsMain( int argc, char **argv ){
        /* arg checking */
 -      if ( argc < 1 ) {
 +      if ( argc < 2 ) {
                Sys_Printf( "Usage: q3map -export [-v] <mapname>\n" );
                return 0;
        }
@@@ -190,7 -188,7 +190,7 @@@ int ImportLightmapsMain( int argc, cha
  
  
        /* arg checking */
 -      if ( argc < 1 ) {
 +      if ( argc < 2 ) {
                Sys_Printf( "Usage: q3map -import [-v] <mapname>\n" );
                return 0;
        }
@@@ -828,7 -826,8 +828,7 @@@ qboolean AddSurfaceToRawLightmap( int n
        /* 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 */
@@@ -998,15 -997,18 +998,15 @@@ void SetupSurfaceLightmaps( void )
        /* 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 */
@@@ -1973,10 -1979,13 +1973,10 @@@ static void SetupOutLightmap( rawLightm
        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 );
        }
  }
  
@@@ -1998,6 -2007,7 +1998,6 @@@ static void FindOutLightmaps( rawLightm
        qboolean ok;
        int xIncrement, yIncrement;
  
 -
        /* set default lightmap number (-3 = LIGHTMAP_BY_VERTEX) */
        for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; lightmapNum++ )
                lm->outLightmapNums[ lightmapNum ] = -3;
@@@ -2325,6 -2335,16 +2325,16 @@@ static int CompareRawLightmap( const vo
        /* 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;
  }
@@@ -2471,15 -2491,13 +2481,13 @@@ void FillOutLightmap( outLightmap_t *ol
        }
  }
  
  /*
     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();
 +      }
  }
index 17e690e7a1c67d1a97c1523f62685aaefb2d8095,2fd322dcbced12f6c906e409fdd6db98f0a5b956..b9760e2e39c0b3f23869cf40be5fe495dc436c7b
@@@ -230,7 -230,8 +230,8 @@@ void InsertModel( const char *name, in
        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;
index e644cc8be83d94971d63b1d0e6342cde8b5993cd,f6296f1b72aae3412f8dcd4c90c175d1503195a8..720dec29053fc042f0541d74295b7e0cc0d053cf
     ------------------------------------------------------------------------------- */
  
  /* 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>
@@@ -62,6 -66,8 +62,6 @@@
  
  
  /* 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
@@@ -560,13 -551,6 +560,13 @@@ typedef enu
  }
  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 */
@@@ -1024,7 -1006,7 +1024,7 @@@ typedef enu
  }
  surfaceType_t;
  
 -char            *surfaceTypes[ NUM_SURFACE_TYPES ]
 +Q_EXTERN char *surfaceTypes[ NUM_SURFACE_TYPES ]
  #ifndef MAIN_C
  ;
  #else
@@@ -1838,7 -1820,6 +1838,7 @@@ void                        RadFreeLigh
  
  /* 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 );
@@@ -1879,14 -1860,9 +1879,9 @@@ int                         ImportLight
  
  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 );
@@@ -1941,11 -1917,6 +1936,11 @@@ void                        PartialLoad
  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 );
@@@ -1981,6 -1952,14 +1976,6 @@@ void                        WriteRBSPFi
  
     ------------------------------------------------------------------------------- */
  
 -#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) */
        ,
@@@ -2065,10 -2032,11 +2060,10 @@@ Q_EXTERN qboolean warnImage Q_ASSIGN( q
  /* 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 );
@@@ -2613,46 -2581,28 +2608,46 @@@ Q_EXTERN bspFog_t bspFogs[ MAX_MAP_FOG
  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 )
  
index 77765fe4ed8a63243b9c71f3895f1544c27c8848,12063360c32f8272fc00782d9e35a193f4c4c48a..569fbf0811aaecbb71d5263002f49ba9a9b8e715
@@@ -961,7 -961,8 +961,7 @@@ mapDrawSurface_t *DrawSurfaceForSide( e
        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 );
@@@ -2114,8 -2115,8 +2114,8 @@@ int FilterPointConvexHullIntoTree_r( ve
  
  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 */
@@@ -3031,7 -3034,8 +3033,7 @@@ static void MakeDebugPortalSurfs_r( nod
                        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++ )
@@@ -3122,9 -3126,11 +3124,9 @@@ void MakeFogHullSurfs( entity_t *e, tre
        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 ] );