#define	LIBQTOOLS_CORE
#include "../include/libqtools.h"

/*#undef        oprintf */
/*#define       oprintf printf */

/*
 * =============
 * PrintBSPFileSizes
 * 
 * Dumps info about current file
 * =============
 */
void PrintClusters(__memBase, int printType, bool toDisk)
{
  if (bspMem) {
    if (!bspMem->bspVersion)
      bspMem->bspVersion = BSP_VERSION_Q1;
    if (!printType)
      printType = bspMem->availHeaders;

    oprintf("printmask: %lx\n", printType);

    mprintf("----- Statistics --------\n");
    if (bspMem->availHeaders & printType & LUMP_PLANES)
      mprintf("%5i planes       %6i\n", bspMem->shared.all.numplanes, (int)(bspMem->shared.all.numplanes * sizeof(struct dplane_t)));

    if (bspMem->availHeaders & printType & LUMP_VERTEXES)
      mprintf("%5i vertexes     %6i\n", bspMem->shared.all.numvertexes, (int)(bspMem->shared.all.numvertexes * sizeof(struct dvertex_t)));

    if (bspMem->availHeaders & printType & LUMP_FACES)
      mprintf("%5i faces        %6i\n", bspMem->shared.all.numfaces, (int)(bspMem->shared.all.numfaces * sizeof(struct dface_t)));

    if (bspMem->availHeaders & printType & LUMP_MARKSURFACES)
      mprintf("%5i %s %6i\n", bspMem->shared.all.nummarksurfaces, (bspMem->bspVersion == BSP_VERSION_Q1 ? "marksurfaces" : "leaffaces   "), (int)(bspMem->shared.all.nummarksurfaces * sizeof(unsigned short int)));

    if (bspMem->availHeaders & printType & LUMP_SURFEDGES)
      mprintf("%5i surfedges    %6i\n", bspMem->shared.all.numsurfedges, (int)(bspMem->shared.all.numsurfedges * sizeof(int)));

    if (bspMem->availHeaders & printType & LUMP_EDGES)
      mprintf("%5i edges        %6i\n", bspMem->shared.all.numedges, (int)(bspMem->shared.all.numedges * sizeof(struct dedge_t)));

    if (bspMem->availHeaders & printType & LUMP_LIGHTING)
      mprintf("      lightdata    %6i\n", bspMem->shared.all.lightdatasize);
    if (bspMem->availHeaders & printType & LUMP_VISIBILITY)
      mprintf("      visdata      %6i\n", bspMem->shared.all.visdatasize);
    if (bspMem->availHeaders & printType & LUMP_ENTITIES)
      mprintf("      entdata      %6i\n", bspMem->shared.all.entdatasize);

    if (bspMem->availHeaders & printType & LUMP_NODES)
      mprintf("%5i nodes        %6i\n", bspMem->shared.all.numnodes, (int)(bspMem->shared.all.numnodes * (bspMem->bspVersion == BSP_VERSION_Q1 ? sizeof(struct dnode_t) : sizeof(struct dnode2_t))));

    if (bspMem->availHeaders & printType & LUMP_MODELS)
      mprintf("%5i models       %6i\n", bspMem->shared.all.nummodels, (int)(bspMem->shared.all.nummodels * (bspMem->bspVersion == BSP_VERSION_Q1 ? sizeof(struct dmodel_t) : sizeof(struct dmodel2_t))));

    if (bspMem->availHeaders & printType & LUMP_TEXINFO)
      mprintf("%5i texinfo      %6i\n", bspMem->shared.all.numtexinfo, (int)(bspMem->shared.all.numtexinfo * (bspMem->bspVersion == BSP_VERSION_Q1 ? sizeof(struct texinfo) : sizeof(struct texinfo2))));

    if (bspMem->availHeaders & printType & LUMP_LEAFS)
      mprintf("%5i leafs        %6i\n", bspMem->shared.all.numleafs, (int)(bspMem->shared.all.numleafs * (bspMem->bspVersion == BSP_VERSION_Q1 ? sizeof(struct dleaf_t) : sizeof(struct dleaf2_t))));

    /*if(bspMem->bspVersion == BSP_VERSION_Q1) { */
    if (bspMem->availHeaders & printType & LUMP_CLIPNODES)
      mprintf("%5i clipnodes    %6i\n", bspMem->shared.quake1.numclipnodes, (int)(bspMem->shared.quake1.numclipnodes * sizeof(struct dclipnode_t)));

    if (bspMem->availHeaders & printType & LUMP_TEXTURES) {
      if (!bspMem->shared.quake1.texdatasize)
	mprintf("    0 textures          0\n");
      else
	mprintf("%5i textures     %6i\n", toDisk ? LittleLong(((struct dmiptexlump_t *)bspMem->shared.quake1.dtexdata)->nummiptex) : ((struct dmiptexlump_t *)bspMem->shared.quake1.dtexdata)->nummiptex, bspMem->shared.quake1.texdatasize);
    }
    /*} */
    /*else if(bspMem->bspVersion == BSP_VERSION_Q2) { */
    if (bspMem->availHeaders & printType & LUMP_AREAS)
      mprintf("%5i areas        %6i\n", bspMem->shared.quake2.numareas, (int)(bspMem->shared.quake2.numareas * sizeof(struct darea2_t)));

    if (bspMem->availHeaders & printType & LUMP_AREAPORTALS)
      mprintf("%5i areaportals  %6i\n", bspMem->shared.quake2.numareaportals, (int)(bspMem->shared.quake2.numareaportals * sizeof(struct dareaportal2_t)));

    if (bspMem->availHeaders & printType & LUMP_BRUSHES)
      mprintf("%5i brushes      %6i\n", bspMem->shared.quake2.numbrushes, (int)(bspMem->shared.quake2.numbrushes * sizeof(struct dbrush2_t)));

    if (bspMem->availHeaders & printType & LUMP_BRUSHSIDES)
      mprintf("%5i brushsides   %6i\n", bspMem->shared.quake2.numbrushsides, (int)(bspMem->shared.quake2.numbrushsides * sizeof(struct dbrushside2_t)));

    if (bspMem->availHeaders & printType & LUMP_LEAFBRUSHES)
      mprintf("%5i leafbrushes  %6i\n", bspMem->shared.quake2.numleafbrushes, (int)(bspMem->shared.quake2.numleafbrushes * sizeof(unsigned short int)));

    /*} */

    if (bspMem->availHeaders & printType & MAP_ENTITIES)
      mprintf("%5i entities     %6i\n", bspMem->nummapentities, (int)(bspMem->nummapentities * sizeof(struct entity)));

    if (bspMem->availHeaders & printType & MAP_TEXSTRINGS)
      mprintf("%5i texstrings   %6i\n", bspMem->nummaptexstrings, (int)(bspMem->nummaptexstrings * (sizeof(char *) + 16)));

    if (bspMem->availHeaders & printType & MAP_BRUSHFACES)
      mprintf("%5i brushfaces   %6i\n", bspMem->numbrushfaces, (int)(bspMem->numbrushfaces * sizeof(struct mface)));

    if (bspMem->availHeaders & printType & MAP_BRUSHPLANES)
      mprintf("%5i brushplanes  %6i\n", bspMem->numbrushplanes, (int)(bspMem->numbrushplanes * sizeof(struct plane)));
  }
}

/*
 * =============
 * AllocBSP
 * =============
 */
void AllocClusters(__memBase, int allocType)
{
  if (bspMem) {
    if (!bspMem->bspVersion)
      bspMem->bspVersion = BSP_VERSION_Q1;

    oprintf("allocmask: %lx\n", allocType);

    if (allocType & LUMP_ENTITIES) {
      if (bspMem->shared.all.dentdata)
	tfree(bspMem->shared.all.dentdata);
      if (!(bspMem->shared.all.dentdata = tmalloc((bspMem->shared.all.max_entdatasize = CLUSTER_ENTSTRING) * sizeof(char))))
	  Error(failed_memoryunsize, "entities");

      bspMem->shared.all.entdatasize = 0;
      oprintf("first cluster for entities allocated: %7d bytes (%lx)\n", CLUSTER_ENTSTRING * sizeof(char), bspMem->shared.all.dentdata);
    }
    if (allocType & LUMP_PLANES) {
      if (bspMem->shared.all.dplanes)
	tfree(bspMem->shared.all.dplanes);
      if (!(bspMem->shared.all.dplanes = tmalloc((bspMem->shared.all.max_numplanes = CLUSTER_PLANES) * sizeof(struct dplane_t))))
	  Error(failed_memoryunsize, "planes");

      bspMem->shared.all.numplanes = 0;
      oprintf("first cluster for planes allocated: %7d bytes (%lx)\n", CLUSTER_PLANES * sizeof(struct dplane_t), bspMem->shared.all.dplanes);
    }
    if (allocType & LUMP_VERTEXES) {
      if (bspMem->shared.all.dvertexes)
	tfree(bspMem->shared.all.dvertexes);
      if (!(bspMem->shared.all.dvertexes = tmalloc((bspMem->shared.all.max_numvertexes = CLUSTER_VERTS) * sizeof(struct dvertex_t))))
	  Error(failed_memoryunsize, "vertexes");

      bspMem->shared.all.numvertexes = 0;
      oprintf("first cluster for vertexes allocated: %7d bytes (%lx)\n", CLUSTER_VERTS * sizeof(struct dvertex_t), bspMem->shared.all.dvertexes);
    }
    if (allocType & LUMP_VISIBILITY) {
      if (bspMem->shared.all.dvisdata)
	tfree(bspMem->shared.all.dvisdata);
      if (!(bspMem->shared.all.dvisdata = tmalloc((bspMem->shared.all.max_visdatasize = CLUSTER_VISIBILITY) * sizeof(char))))
	  Error(failed_memoryunsize, "visibility");

      bspMem->shared.all.visdatasize = 0;
      oprintf("first cluster for visibility allocated: %7d bytes (%lx)\n", CLUSTER_VISIBILITY * sizeof(char), bspMem->shared.all.dvisdata);
    }
    if (allocType & LUMP_NODES) {
      if (bspMem->shared.all.dnodes)
	tfree(bspMem->shared.all.dnodes);
      if (!(bspMem->shared.all.dnodes = tmalloc((bspMem->shared.all.max_numnodes = CLUSTER_NODES) * (bspMem->bspVersion == BSP_VERSION_Q1 ? sizeof(struct dnode_t) : sizeof(struct dnode2_t)))))
	  Error(failed_memoryunsize, "nodes");

      bspMem->shared.all.numnodes = 0;
      oprintf("first cluster for nodes allocated: %7d bytes (%lx)\n", CLUSTER_NODES * (bspMem->bspVersion == BSP_VERSION_Q1 ? sizeof(struct dnode_t) : sizeof(struct dnode2_t)), bspMem->shared.all.dnodes);
    }
    if (allocType & LUMP_TEXINFO) {
      if (bspMem->shared.all.texinfo)
	tfree(bspMem->shared.all.texinfo);
      if (!(bspMem->shared.all.texinfo = tmalloc((bspMem->shared.all.max_numtexinfo = CLUSTER_TEXINFO) * (bspMem->bspVersion == BSP_VERSION_Q1 ? sizeof(struct texinfo) : sizeof(struct texinfo2)))))
	  Error(failed_memoryunsize, "texinfo");

      bspMem->shared.all.numtexinfo = 0;
      oprintf("first cluster for texinfo allocated: %7d bytes (%lx)\n", CLUSTER_TEXINFO * (bspMem->bspVersion == BSP_VERSION_Q1 ? sizeof(struct texinfo) : sizeof(struct texinfo2)), bspMem->shared.all.texinfo);
    }
    if (allocType & LUMP_FACES) {
      if (bspMem->shared.all.dfaces)
	tfree(bspMem->shared.all.dfaces);
      if (!(bspMem->shared.all.dfaces = tmalloc((bspMem->shared.all.max_numfaces = CLUSTER_FACES) * sizeof(struct dface_t))))
	  Error(failed_memoryunsize, "faces");

      bspMem->shared.all.numfaces = 0;
      oprintf("first cluster for faces allocated: %7d bytes (%lx)\n", CLUSTER_FACES * sizeof(struct dface_t), bspMem->shared.all.dfaces);
    }
    if (allocType & LUMP_LIGHTING) {
      if (bspMem->shared.all.dlightdata)
	tfree(bspMem->shared.all.dlightdata);
      if (!(bspMem->shared.all.dlightdata = tmalloc((bspMem->shared.all.max_lightdatasize = CLUSTER_LIGHTING) * sizeof(char))))
	  Error(failed_memoryunsize, "lightdata");

      bspMem->shared.all.lightdatasize = 0;
      oprintf("first cluster for lighting allocated: %7d bytes (%lx)\n", CLUSTER_LIGHTING * sizeof(char), bspMem->shared.all.dlightdata);
    }
    if (allocType & LUMP_LEAFS) {
      if (bspMem->shared.all.dleafs)
	tfree(bspMem->shared.all.dleafs);
      if (!(bspMem->shared.all.dleafs = tmalloc((bspMem->shared.all.max_numleafs = CLUSTER_LEAFS) * (bspMem->bspVersion == BSP_VERSION_Q1 ? sizeof(struct dleaf_t) : sizeof(struct dleaf2_t)))))
	  Error(failed_memoryunsize, "leafs");

      bspMem->shared.all.numleafs = 0;
      oprintf("first cluster for leafs allocated: %7d bytes (%lx)\n", CLUSTER_LEAFS * (bspMem->bspVersion == BSP_VERSION_Q1 ? sizeof(struct dleaf_t) : sizeof(struct dleaf2_t)), bspMem->shared.all.dleafs);
    }
    if (allocType & LUMP_MARKSURFACES) {
      if (bspMem->shared.all.dmarksurfaces)
	tfree(bspMem->shared.all.dmarksurfaces);
      if (!(bspMem->shared.all.dmarksurfaces = tmalloc((bspMem->shared.all.max_nummarksurfaces = CLUSTER_MARKSURFACES) * sizeof(unsigned short int))))
	  Error(failed_memoryunsize, "marksurfaces");

      bspMem->shared.all.nummarksurfaces = 0;
      oprintf("first cluster for marksurfaces allocated: %7d bytes (%lx)\n", CLUSTER_MARKSURFACES * sizeof(unsigned short int), bspMem->shared.all.dmarksurfaces);
    }
    if (allocType & LUMP_EDGES) {
      if (bspMem->shared.all.dedges)
	tfree(bspMem->shared.all.dedges);
      if (bspMem->edgefaces[0])
	tfree(bspMem->edgefaces[0]);
      if (bspMem->edgefaces[1])
	tfree(bspMem->edgefaces[1]);

      if (!(bspMem->shared.all.dedges = tmalloc((bspMem->shared.all.max_numedges = CLUSTER_EDGES) * sizeof(struct dedge_t))))
	  Error(failed_memoryunsize, "edges");
      if (!(bspMem->edgefaces[0] = tmalloc(CLUSTER_EDGES * sizeof(struct visfacet **))))
	  Error(failed_memoryunsize, "edgefaces[0]");
      if (!(bspMem->edgefaces[1] = tmalloc(CLUSTER_EDGES * sizeof(struct visfacet **))))
	  Error(failed_memoryunsize, "edgefaces[1]");

      bspMem->shared.all.numedges = 0;
      oprintf("first cluster for edges allocated: %7d bytes (%lx)\n", CLUSTER_EDGES * sizeof(struct dedge_t), bspMem->shared.all.dedges);
      oprintf("first cluster for edgefaces[0] allocated: %7d bytes (%lx)\n", CLUSTER_EDGES * sizeof(struct visfacet **), bspMem->edgefaces[0]);
      oprintf("first cluster for edgefaces[1] allocated: %7d bytes (%lx)\n", CLUSTER_EDGES * sizeof(struct visfacet **), bspMem->edgefaces[1]);
    }
    if (allocType & LUMP_SURFEDGES) {
      if (bspMem->shared.all.dsurfedges)
	tfree(bspMem->shared.all.dsurfedges);
      if (!(bspMem->shared.all.dsurfedges = tmalloc((bspMem->shared.all.max_numsurfedges = CLUSTER_SURFEDGES) * sizeof(int))))
	  Error(failed_memoryunsize, "surfedges");

      bspMem->shared.all.numsurfedges = 0;
      oprintf("first cluster for surfedges allocated: %7d bytes (%lx)\n", CLUSTER_SURFEDGES * sizeof(int), bspMem->shared.all.dsurfedges);
    }
    if (allocType & LUMP_MODELS) {
      if (bspMem->shared.all.dmodels)
	tfree(bspMem->shared.all.dmodels);
      if (!(bspMem->shared.all.dmodels = tmalloc((bspMem->shared.all.max_nummodels = CLUSTER_MODELS) * (bspMem->bspVersion == BSP_VERSION_Q1 ? sizeof(struct dmodel_t) : sizeof(struct dmodel2_t)))))
	  Error(failed_memoryunsize, "models");

      bspMem->shared.all.nummodels = 0;
      oprintf("first cluster for models allocated: %7d bytes (%lx)\n", CLUSTER_MODELS * (bspMem->bspVersion == BSP_VERSION_Q1 ? sizeof(struct dmodel_t) : sizeof(struct dmodel2_t)), bspMem->shared.all.dmodels);
    }

    /*if(bspMem->bspVersion == BSP_VERSION_Q1) { */
    if (allocType & LUMP_TEXTURES) {
      if (bspMem->shared.quake1.dtexdata)
	tfree(bspMem->shared.quake1.dtexdata);
      if (!(bspMem->shared.quake1.dtexdata = tmalloc((bspMem->shared.quake1.max_texdatasize = CLUSTER_TEXTURES) * sizeof(char))))
	  Error(failed_memoryunsize, "textures");

      bspMem->shared.quake1.texdatasize = 0;
      oprintf("first cluster for textures allocated: %7d bytes (%lx)\n", CLUSTER_TEXTURES * sizeof(char), bspMem->shared.quake1.dtexdata);
    }
    if (allocType & LUMP_CLIPNODES) {
      if (bspMem->shared.quake1.dclipnodes)
	tfree(bspMem->shared.quake1.dclipnodes);
      if (!(bspMem->shared.quake1.dclipnodes = tmalloc((bspMem->shared.quake1.max_numclipnodes = CLUSTER_CLIPNODES) * sizeof(struct dclipnode_t))))
	  Error(failed_memoryunsize, "clipnodes");

      bspMem->shared.quake1.numclipnodes = 0;
      oprintf("first cluster for clipnodes allocated: %7d bytes (%lx)\n", CLUSTER_CLIPNODES * sizeof(struct dclipnode_t), bspMem->shared.quake1.dclipnodes);
    }
    /*} */
    /*else if(bspMem->bspVersion == BSP_VERSION_Q2) { */
    if (allocType & LUMP_AREAS) {
      if (bspMem->shared.quake2.dareas)
	tfree(bspMem->shared.quake2.dareas);
      if (!(bspMem->shared.quake2.dareas = tmalloc((bspMem->shared.quake2.max_numareas = CLUSTER_AREAS) * sizeof(struct darea2_t))))
	  Error(failed_memoryunsize, "areas");

      bspMem->shared.quake2.numareas = 0;
      oprintf("first cluster for areas allocated: %7d bytes (%lx)\n", CLUSTER_AREAS * sizeof(struct darea2_t), bspMem->shared.quake2.dareas);
    }
    if (allocType & LUMP_AREAPORTALS) {
      if (bspMem->shared.quake2.dareaportals)
	tfree(bspMem->shared.quake2.dareaportals);
      if (!(bspMem->shared.quake2.dareaportals = tmalloc((bspMem->shared.quake2.max_numareaportals = CLUSTER_AREAPORTALS) * sizeof(struct dareaportal2_t))))
	  Error(failed_memoryunsize, "areaportals");

      bspMem->shared.quake2.numareaportals = 0;
      oprintf("first cluster for areaportals allocated: %7d bytes (%lx)\n", CLUSTER_AREAPORTALS * sizeof(struct dareaportal2_t), bspMem->shared.quake2.dareaportals);
    }
    if (allocType & LUMP_BRUSHES) {
      if (bspMem->shared.quake2.dbrushes)
	tfree(bspMem->shared.quake2.dbrushes);
      if (!(bspMem->shared.quake2.dbrushes = tmalloc((bspMem->shared.quake2.max_numbrushes = CLUSTER_BRUSHES) * sizeof(struct dbrush2_t))))
	  Error(failed_memoryunsize, "brushes");

      bspMem->shared.quake2.numbrushes = 0;
      oprintf("first cluster for brushes allocated: %7d bytes (%lx)\n", CLUSTER_BRUSHES * sizeof(struct dbrush2_t), bspMem->shared.quake2.dbrushes);
    }
    if (allocType & LUMP_BRUSHSIDES) {
      if (bspMem->shared.quake2.dbrushsides)
	tfree(bspMem->shared.quake2.dbrushsides);
      if (!(bspMem->shared.quake2.dbrushsides = tmalloc((bspMem->shared.quake2.max_numbrushsides = CLUSTER_BRUSHSIDES) * sizeof(struct dbrushside2_t))))
	  Error(failed_memoryunsize, "brushsides");

      bspMem->shared.quake2.numbrushsides = 0;
      oprintf("first cluster for brushsides allocated: %7d bytes (%lx)\n", CLUSTER_BRUSHSIDES * sizeof(struct dbrushside2_t), bspMem->shared.quake2.dbrushsides);
    }
    if (allocType & LUMP_LEAFBRUSHES) {
      if (bspMem->shared.quake2.dleafbrushes)
	tfree(bspMem->shared.quake2.dleafbrushes);
      if (!(bspMem->shared.quake2.dleafbrushes = tmalloc((bspMem->shared.quake2.max_numleafbrushes = CLUSTER_LEAFBRUSHES) * sizeof(unsigned short int))))
	  Error(failed_memoryunsize, "leafbrushes");

      bspMem->shared.quake2.numleafbrushes = 0;
      oprintf("first cluster for leafbrushes allocated: %7d bytes (%lx)\n", CLUSTER_LEAFBRUSHES * sizeof(unsigned short int), bspMem->shared.quake2.dleafbrushes);
    }
    /*} */

    if (allocType & MAP_ENTITIES) {
      if (bspMem->mapentities)
	tfree(bspMem->mapentities);
      if (!(bspMem->mapentities = tmalloc((bspMem->max_nummapentities = CLUSTER_ENTITIES) * sizeof(struct entity))))
	  Error(failed_memoryunsize, "entities");

      bspMem->nummapentities = 0;
      oprintf("first cluster for brushes allocated: %7d bytes (%lx)\n", CLUSTER_ENTITIES * sizeof(struct entity), bspMem->mapentities);
    }
    if (allocType & MAP_TEXSTRINGS) {
      int i;
      char *text;

      if (bspMem->maptexstrings)
	tfree(bspMem->maptexstrings);
      if (!(bspMem->maptexstrings = tmalloc((bspMem->max_nummaptexstrings = CLUSTER_TEXSTRINGS) * (sizeof(char *) + 16))))
	  Error(failed_memoryunsize, "texstrings");

      bspMem->nummaptexstrings = 0;
      for (i = 0, text = (char *)&bspMem->maptexstrings[bspMem->max_nummaptexstrings]; i < bspMem->max_nummaptexstrings; i++, text += 16)
	bspMem->maptexstrings[i] = text;
      oprintf("first cluster for texstrings allocated: %7d bytes (%lx)\n", CLUSTER_TEXSTRINGS * (sizeof(char *) + 16), bspMem->maptexstrings);
    }
    if (allocType & MAP_BRUSHFACES) {
      if (bspMem->brushfaces)
	tfree(bspMem->brushfaces);
      if (!(bspMem->brushfaces = tmalloc((bspMem->max_numbrushfaces = CLUSTER_BRUSHFACES) * sizeof(struct mface))))
	  Error(failed_memoryunsize, "brushfaces");

      bspMem->numbrushfaces = 0;
      oprintf("first cluster for brushfaces allocated: %7d bytes (%lx)\n", CLUSTER_BRUSHFACES * sizeof(struct mface), bspMem->brushfaces);
    }
    if (allocType & MAP_BRUSHPLANES) {
      if (bspMem->brushplanes)
	tfree(bspMem->brushplanes);
      if (!(bspMem->brushplanes = tmalloc((bspMem->max_numbrushplanes = CLUSTER_BRUSHPLANES) * sizeof(struct plane))))
	  Error(failed_memoryunsize, "brushplanes");

      bspMem->numbrushplanes = 0;
      oprintf("first cluster for brushes allocated: %7d bytes (%lx)\n", CLUSTER_BRUSHPLANES * sizeof(struct plane), bspMem->brushplanes);
    }
    bspMem->availHeaders |= allocType;

#ifdef	CUSTOM_MAXIMA
    if (!bspMem->maxpoints)
      bspMem->maxpoints = DEFPOINTS;
    if (!bspMem->maxedges)
      bspMem->maxedges = DEFEDGES;
    if (!bspMem->maxedges_in_region)
      bspMem->maxedges_in_region = DEF_EDGES_IN_REGION;
    if (!bspMem->maxportals)
      bspMem->maxportals = DEF_PORTALS;
    if (!bspMem->maxportals_in_leaf)
      bspMem->maxportals_in_leaf = DEF_PORTALS_IN_LEAF;
#endif
  }
}

/*
 * =============
 * ExpandBSP
 * =============
 * for all use trealloc instead ?
 */
void ExpandClusters(__memBase, int allocType)
{
  if (bspMem) {
    if (!bspMem->bspVersion)
      bspMem->bspVersion = BSP_VERSION_Q1;
    oprintf("expandmask: %lx\n", allocType);

    if (allocType & LUMP_ENTITIES) {
      if (!(bspMem->shared.all.dentdata = trealloc(bspMem->shared.all.dentdata, (bspMem->shared.all.max_entdatasize += CLUSTER_ENTSTRING) * sizeof(char))))
	  Error(failed_memoryunsize, "entities");
      oprintf("additional cluster for entities allocated: %7d bytes (%lx)\n", bspMem->shared.all.max_entdatasize * sizeof(char), bspMem->shared.all.dentdata);
    }
    if (allocType & LUMP_PLANES) {
      if (!(bspMem->shared.all.dplanes = trealloc(bspMem->shared.all.dplanes, (bspMem->shared.all.max_numplanes += CLUSTER_PLANES) * sizeof(struct dplane_t))))
	  Error(failed_memoryunsize, "planes");
      oprintf("additional cluster for planes allocated: %7d bytes (%lx)\n", bspMem->shared.all.max_numplanes * sizeof(struct dplane_t), bspMem->shared.all.dplanes);
    }
    if (allocType & LUMP_VERTEXES) {
      if (!(bspMem->shared.all.dvertexes = trealloc(bspMem->shared.all.dvertexes, (bspMem->shared.all.max_numvertexes += CLUSTER_VERTS) * sizeof(struct dvertex_t))))
	  Error(failed_memoryunsize, "vertexes");
      oprintf("additional cluster for vertexes allocated: %7d bytes (%lx)\n", bspMem->shared.all.max_numvertexes * sizeof(struct dvertex_t), bspMem->shared.all.dvertexes);
    }
    if (allocType & LUMP_VISIBILITY) {
      if (!(bspMem->shared.all.dvisdata = trealloc(bspMem->shared.all.dvisdata, (bspMem->shared.all.max_visdatasize += CLUSTER_VISIBILITY) * sizeof(char))))
	  Error(failed_memoryunsize, "visibility");
      oprintf("additional cluster for visibility allocated: %7d bytes (%lx)\n", bspMem->shared.all.max_visdatasize * sizeof(char), bspMem->shared.all.dvisdata);
    }
    if (allocType & LUMP_NODES) {
      if ((bspMem->shared.all.dnodes = trealloc(bspMem->shared.all.dnodes, (bspMem->shared.all.max_numnodes += CLUSTER_NODES) * (bspMem->bspVersion == BSP_VERSION_Q1 ? sizeof(struct dnode_t) : sizeof(struct dnode2_t)))))
	  Error(failed_memoryunsize, "nodes");
      oprintf("additional cluster for nodes allocated: %7d bytes (%lx)\n", bspMem->shared.all.max_numnodes * (bspMem->bspVersion == BSP_VERSION_Q1 ? sizeof(struct dnode_t) : sizeof(struct dnode2_t)), bspMem->shared.all.dnodes);
    }
    if (allocType & LUMP_TEXINFO) {
      if (!(bspMem->shared.all.texinfo = trealloc(bspMem->shared.all.texinfo, (bspMem->shared.all.max_numtexinfo += CLUSTER_TEXINFO) * (bspMem->bspVersion == BSP_VERSION_Q1 ? sizeof(struct texinfo) : sizeof(struct texinfo2)))))
	  Error(failed_memoryunsize, "texinfo");
      oprintf("additional cluster for texinfo allocated: %7d bytes (%lx)\n", bspMem->shared.all.max_numtexinfo * (bspMem->bspVersion == BSP_VERSION_Q1 ? sizeof(struct texinfo) : sizeof(struct texinfo2)), bspMem->shared.all.texinfo);
    }
    if (allocType & LUMP_FACES) {
      if (!(bspMem->shared.all.dfaces = trealloc(bspMem->shared.all.dfaces, (bspMem->shared.all.max_numfaces += CLUSTER_FACES) * sizeof(struct dface_t))))
	  Error(failed_memoryunsize, "faces");
      oprintf("additional cluster for faces allocated: %7d bytes (%lx)\n", bspMem->shared.all.max_numfaces * sizeof(struct dface_t), bspMem->shared.all.dfaces);
    }
    if (allocType & LUMP_LIGHTING) {
      if (!(bspMem->shared.all.dlightdata = trealloc(bspMem->shared.all.dlightdata, (bspMem->shared.all.max_lightdatasize += CLUSTER_LIGHTING) * sizeof(char))))
	  Error(failed_memoryunsize, "lightdata");
      oprintf("additional cluster for lighting allocated: %7d bytes (%lx)\n", bspMem->shared.all.max_lightdatasize * sizeof(char), bspMem->shared.all.dlightdata);
    }
    if (allocType & LUMP_LEAFS) {
      if (!(bspMem->shared.all.dleafs = trealloc(bspMem->shared.all.dleafs, (bspMem->shared.all.max_numleafs += CLUSTER_LEAFS) * (bspMem->bspVersion == BSP_VERSION_Q1 ? sizeof(struct dleaf_t) : sizeof(struct dleaf2_t)))))
	  Error(failed_memoryunsize, "leafs");
      oprintf("additional cluster for leafs allocated: %7d bytes (%lx)\n", bspMem->shared.all.max_numleafs * (bspMem->bspVersion == BSP_VERSION_Q1 ? sizeof(struct dleaf_t) : sizeof(struct dleaf2_t)), bspMem->shared.all.dleafs);
    }
    if (allocType & LUMP_MARKSURFACES) {
      if (!(bspMem->shared.all.dmarksurfaces = trealloc(bspMem->shared.all.dmarksurfaces, (bspMem->shared.all.max_nummarksurfaces += CLUSTER_MARKSURFACES) * sizeof(unsigned short int))))
	  Error(failed_memoryunsize, "marksurfaces");
      oprintf("additional cluster for marksurfaces allocated: %7d bytes (%lx)\n", bspMem->shared.all.max_nummarksurfaces * sizeof(unsigned short int), bspMem->shared.all.dmarksurfaces);
    }
    if (allocType & LUMP_EDGES) {
      if (!(bspMem->shared.all.dedges = trealloc(bspMem->shared.all.dedges, (bspMem->shared.all.max_numedges += CLUSTER_EDGES) * sizeof(struct dedge_t))))
	  Error(failed_memoryunsize, "edges");
      if (!(bspMem->edgefaces[0] = trealloc(bspMem->edgefaces[0], bspMem->shared.all.max_numedges * sizeof(struct visfacet **))))
	  Error(failed_memoryunsize, "edgefaces[0]");
      if (!(bspMem->edgefaces[1] = trealloc(bspMem->edgefaces[1], bspMem->shared.all.max_numedges * sizeof(struct visfacet **))))
	  Error(failed_memoryunsize, "edgefaces[1]");
      oprintf("additional cluster for edges allocated: %7d bytes (%lx)\n", bspMem->shared.all.max_numedges * sizeof(struct dedge_t), bspMem->shared.all.dedges);
      oprintf("additional cluster for edgefaces[0] allocated: %7d bytes (%lx)\n", bspMem->shared.all.max_numedges * sizeof(struct visfacet **), bspMem->edgefaces[0]);
      oprintf("additional cluster for edgefaces[1] allocated: %7d bytes (%lx)\n", bspMem->shared.all.max_numedges * sizeof(struct visfacet **), bspMem->edgefaces[1]);
    }
    if (allocType & LUMP_SURFEDGES) {
      if (!(bspMem->shared.all.dsurfedges = trealloc(bspMem->shared.all.dsurfedges, (bspMem->shared.all.max_numsurfedges += CLUSTER_SURFEDGES) * sizeof(int))))
	  Error(failed_memoryunsize, "surfedges");
      oprintf("additional cluster for surfedges allocated: %7d bytes (%lx)\n", bspMem->shared.all.max_numsurfedges * sizeof(int), bspMem->shared.all.dsurfedges);
    }
    if (allocType & LUMP_MODELS) {
      if (!(bspMem->shared.all.dmodels = trealloc(bspMem->shared.all.dmodels, (bspMem->shared.all.max_nummodels += CLUSTER_MODELS) * (bspMem->bspVersion == BSP_VERSION_Q1 ? sizeof(struct dmodel_t) : sizeof(struct dmodel2_t)))))
	  Error(failed_memoryunsize, "models");
      oprintf("additional cluster for models allocated: %7d bytes (%lx)\n", bspMem->shared.all.max_nummodels * (bspMem->bspVersion == BSP_VERSION_Q1 ? sizeof(struct dmodel_t) : sizeof(struct dmodel2_t)), bspMem->shared.all.dmodels);
    }

    /*if(bspMem->bspVersion == BSP_VERSION_Q1) { */
    if (allocType & LUMP_TEXTURES) {
      if (!(bspMem->shared.quake1.dtexdata = trealloc(bspMem->shared.quake1.dtexdata, (bspMem->shared.quake1.max_texdatasize += CLUSTER_TEXTURES) * sizeof(char))))
	  Error(failed_memoryunsize, "textures");
      oprintf("additional cluster for textures allocated: %7d bytes (%lx)\n", bspMem->shared.quake1.max_texdatasize * sizeof(char), bspMem->shared.quake1.dtexdata);
    }
    if (allocType & LUMP_CLIPNODES) {
      if (!(bspMem->shared.quake1.dclipnodes = trealloc(bspMem->shared.quake1.dclipnodes, (bspMem->shared.quake1.max_numclipnodes += CLUSTER_CLIPNODES) * sizeof(struct dclipnode_t))))
	  Error(failed_memoryunsize, "clipnodes");
      oprintf("additional cluster for clipnodes allocated: %7d bytes (%lx)\n", bspMem->shared.quake1.max_numclipnodes * sizeof(struct dclipnode_t), bspMem->shared.quake1.dclipnodes);
    }
    /*} */
    /*else if(bspMem->bspVersion == BSP_VERSION_Q2) { */
    if (allocType & LUMP_AREAS) {
      if (!(bspMem->shared.quake2.dareas = trealloc(bspMem->shared.quake2.dareas, (bspMem->shared.quake2.max_numareas += CLUSTER_AREAS) * sizeof(struct darea2_t))))
	  Error(failed_memoryunsize, "areas");
      oprintf("additional cluster for areas allocated: %7d bytes (%lx)\n", bspMem->shared.quake2.max_numareas * sizeof(struct darea2_t), bspMem->shared.quake2.dareas);
    }
    if (allocType & LUMP_AREAPORTALS) {
      if (!(bspMem->shared.quake2.dareaportals = trealloc(bspMem->shared.quake2.dareaportals, (bspMem->shared.quake2.max_numareaportals += CLUSTER_AREAPORTALS) * sizeof(struct dareaportal2_t))))
	  Error(failed_memoryunsize, "areaportals");
      oprintf("additional cluster for areaportals allocated: %7d bytes (%lx)\n", bspMem->shared.quake2.max_numareaportals * sizeof(struct dareaportal2_t), bspMem->shared.quake2.dareaportals);
    }
    if (allocType & LUMP_BRUSHES) {
      if (!(bspMem->shared.quake2.dbrushes = trealloc(bspMem->shared.quake2.dbrushes, (bspMem->shared.quake2.max_numbrushes += CLUSTER_BRUSHES) * sizeof(struct dbrush2_t))))
	  Error(failed_memoryunsize, "brushes");
      oprintf("additional cluster for brushes allocated: %7d bytes (%lx)\n", bspMem->shared.quake2.max_numbrushes * sizeof(struct dbrush2_t), bspMem->shared.quake2.dbrushes);
    }
    if (allocType & LUMP_BRUSHSIDES) {
      if (!(bspMem->shared.quake2.dbrushsides = trealloc(bspMem->shared.quake2.dbrushsides, (bspMem->shared.quake2.max_numbrushsides += CLUSTER_BRUSHSIDES) * sizeof(struct dbrushside2_t))))
	  Error(failed_memoryunsize, "brushsides");
      oprintf("additional cluster for brushsides allocated: %7d bytes (%lx)\n", bspMem->shared.quake2.max_numbrushsides * sizeof(struct dbrushside2_t), bspMem->shared.quake2.dbrushsides);
    }
    if (allocType & LUMP_LEAFBRUSHES) {
      if (!(bspMem->shared.quake2.dleafbrushes = trealloc(bspMem->shared.quake2.dleafbrushes, (bspMem->shared.quake2.max_numleafbrushes += CLUSTER_LEAFBRUSHES) * sizeof(unsigned short int))))
	  Error(failed_memoryunsize, "leafbrushes");
      oprintf("additional cluster for leafbrushes allocated: %7d bytes (%lx)\n", bspMem->shared.quake2.max_numleafbrushes * sizeof(unsigned short int), bspMem->shared.quake2.dleafbrushes);
    }
    /*} */

    if (allocType & MAP_ENTITIES) {
      if (!(bspMem->mapentities = trealloc(bspMem->mapentities, (bspMem->max_nummapentities += CLUSTER_ENTITIES) * sizeof(struct entity))))
	  Error(failed_memoryunsize, "entities");
      oprintf("additional cluster for mapentities allocated: %7d bytes (%lx)\n", bspMem->max_nummapentities * sizeof(struct entity), bspMem->mapentities);
    }
    if (allocType & MAP_TEXSTRINGS) {
      int i;
      char *text;
      char **maptexstrings = bspMem->maptexstrings;
      if (!(bspMem->maptexstrings = tmalloc((bspMem->max_nummaptexstrings += CLUSTER_TEXSTRINGS) * (sizeof(char *) + 16))))
	  Error(failed_memoryunsize, "texstrings");

      for (i = 0, text = (char *)&bspMem->maptexstrings[bspMem->max_nummaptexstrings]; i < bspMem->max_nummaptexstrings; i++, text += 16)
	bspMem->maptexstrings[i] = text;
      __memcpy(bspMem->maptexstrings[0], maptexstrings[0], bspMem->nummaptexstrings * 16);
      tfree(maptexstrings);
      oprintf("additional cluster for mapstrings allocated: %7d bytes (%lx)\n", bspMem->max_nummaptexstrings * (sizeof(char *) + 16), bspMem->maptexstrings);
    }
    if (allocType & MAP_BRUSHFACES) {
      if (!(bspMem->brushfaces = trealloc(bspMem->brushfaces, (bspMem->max_numbrushplanes += CLUSTER_BRUSHFACES) * sizeof(struct mface))))
	  Error(failed_memoryunsize, "brushfaces");
      oprintf("additional cluster for brushplanes allocated: %7d bytes (%lx)\n", bspMem->max_numbrushplanes * sizeof(struct mface), bspMem->brushfaces);
    }
    if (allocType & MAP_BRUSHPLANES) {
      if (!(bspMem->brushplanes = trealloc(bspMem->brushplanes, (bspMem->max_numbrushplanes += CLUSTER_BRUSHPLANES) * sizeof(struct plane))))
	  Error(failed_memoryunsize, "brushplanes");
      oprintf("additional cluster for brushplanes allocated: %7d bytes (%lx)\n", bspMem->max_numbrushplanes * sizeof(struct plane), bspMem->brushplanes);
    }
    bspMem->availHeaders |= allocType;

#ifdef	CUSTOM_MAXIMA
    if (!bspMem->maxpoints)
      bspMem->maxpoints = DEFPOINTS;
    if (!bspMem->maxedges)
      bspMem->maxedges = DEFEDGES;
    if (!bspMem->maxedges_in_region)
      bspMem->maxedges_in_region = DEF_EDGES_IN_REGION;
    if (!bspMem->maxportals)
      bspMem->maxportals = DEF_PORTALS;
    if (!bspMem->maxportals_in_leaf)
      bspMem->maxportals_in_leaf = DEF_PORTALS_IN_LEAF;
#endif
  }
}

/*
 * =============
 * FreeBSP
 * =============
 */
void FreeClusters(__memBase, int freeType)
{
  if (bspMem) {
    if (!bspMem->bspVersion)
      bspMem->bspVersion = BSP_VERSION_Q1;
    if (!freeType)
      freeType = bspMem->availHeaders;

    oprintf("freemask: %lx\n", freeType);

    if ((bspMem->availHeaders & freeType & LUMP_ENTITIES)) {
      oprintf("free entities\n");
      tfree(bspMem->shared.all.dentdata);
    }
    if ((bspMem->availHeaders & freeType & LUMP_PLANES)) {
      oprintf("free planes\n");
      tfree(bspMem->shared.all.dplanes);
    }
    if ((bspMem->availHeaders & freeType & LUMP_VERTEXES)) {
      oprintf("free vertexes\n");
      tfree(bspMem->shared.all.dvertexes);
    }
    if ((bspMem->availHeaders & freeType & LUMP_VISIBILITY)) {
      oprintf("free visibility\n");
      tfree(bspMem->shared.all.dvisdata);
    }
    if ((bspMem->availHeaders & freeType & LUMP_NODES)) {
      oprintf("free nodes\n");
      tfree(bspMem->shared.all.dnodes);
    }
    if ((bspMem->availHeaders & freeType & LUMP_TEXINFO)) {
      oprintf("free texinfo\n");
      tfree(bspMem->shared.all.texinfo);
    }
    if ((bspMem->availHeaders & freeType & LUMP_FACES)) {
      oprintf("free faces\n");
      tfree(bspMem->shared.all.dfaces);
    }
    if ((bspMem->availHeaders & freeType & LUMP_LIGHTING)) {
      oprintf("free lighting\n");
      tfree(bspMem->shared.all.dlightdata);
    }
    if ((bspMem->availHeaders & freeType & LUMP_LEAFS)) {
      oprintf("free leafs\n");
      tfree(bspMem->shared.all.dleafs);
    }
    if ((bspMem->availHeaders & freeType & LUMP_MARKSURFACES)) {
      oprintf("free marksurfaces\n");
      tfree(bspMem->shared.all.dmarksurfaces);
    }
    if ((bspMem->availHeaders & freeType & LUMP_EDGES)) {
      oprintf("free edges\n");
      tfree(bspMem->shared.all.dedges);
      if (bspMem->edgefaces[0])
	tfree(bspMem->edgefaces[0]);
      if (bspMem->edgefaces[1])
	tfree(bspMem->edgefaces[1]);
    }
    if ((bspMem->availHeaders & freeType & LUMP_SURFEDGES)) {
      oprintf("free surfedges\n");
      tfree(bspMem->shared.all.dsurfedges);
    }
    if ((bspMem->availHeaders & freeType & LUMP_MODELS)) {
      oprintf("free models\n");
      tfree(bspMem->shared.all.dmodels);
    }

    /*if(bspMem->bspVersion == BSP_VERSION_Q1) { */
    if ((bspMem->availHeaders & freeType & LUMP_TEXTURES)) {
      oprintf("free textures\n");
      tfree(bspMem->shared.quake1.dtexdata);
    }
    if ((bspMem->availHeaders & freeType & LUMP_CLIPNODES)) {
      oprintf("free clipnodes\n");
      tfree(bspMem->shared.quake1.dclipnodes);
    }
    /*} */
    /*else if(bspMem->bspVersion == BSP_VERSION_Q2) { */
    if ((bspMem->availHeaders & freeType & LUMP_AREAS)) {
      oprintf("free areas\n");
      tfree(bspMem->shared.quake2.dareas);
    }
    if ((bspMem->availHeaders & freeType & LUMP_AREAPORTALS)) {
      oprintf("free areaportals\n");
      tfree(bspMem->shared.quake2.dareaportals);
    }
    if ((bspMem->availHeaders & freeType & LUMP_BRUSHES)) {
      oprintf("free brushes\n");
      tfree(bspMem->shared.quake2.dbrushes);
    }
    if ((bspMem->availHeaders & freeType & LUMP_BRUSHSIDES)) {
      oprintf("free brushsides\n");
      tfree(bspMem->shared.quake2.dbrushsides);
    }
    if ((bspMem->availHeaders & freeType & LUMP_LEAFBRUSHES)) {
      oprintf("free leafbrushes\n");
      tfree(bspMem->shared.quake2.dleafbrushes);
    }
    /*} */

    if ((bspMem->availHeaders & freeType & MAP_ENTITIES)) {
      struct entity *ent;
      int i;

      oprintf("free entities\n");
      for (i = 0, ent = bspMem->mapentities; i < bspMem->nummapentities; i++, ent++) {
	struct epair *ep = ent->epairs;
	struct mbrush *mbr = ent->brushes;

	while (ep) {
	  struct epair *en = ep->next;

	  tfree(ep->key);
	  tfree(ep->value);
	  tfree(ep);
	  ep = en;
	}
	while (mbr) {
	  struct mbrush *mbn = mbr->next;
	  struct mface *mfc = mbr->faces;

	  while (mfc) {
	    struct mface *mfn = mfc->next;

	    tfree(mfc);
	    mfc = mfn;
	  }
	  tfree(mbr);
	  mbr = mbn;
	}
      }
      tfree(bspMem->mapentities);
    }
    if ((bspMem->availHeaders & freeType & MAP_TEXSTRINGS)) {
      oprintf("free texstrings\n");
      tfree(bspMem->maptexstrings);
    }
    if ((bspMem->availHeaders & freeType & MAP_BRUSHFACES)) {
      oprintf("free brushfaces\n");
      tfree(bspMem->brushfaces);
    }
    if ((bspMem->availHeaders & freeType & MAP_BRUSHPLANES)) {
      oprintf("free brushmaps\n");
      tfree(bspMem->brushplanes);
    }

    /*
     * probably this is not ours;
     * tfree(bspMem);
     */
  }
  bspMem->availHeaders &= ~freeType;
}
