aboutsummaryrefslogtreecommitdiffstats
path: root/code/bspc
diff options
context:
space:
mode:
Diffstat (limited to 'code/bspc')
-rw-r--r--code/bspc/Makefile114
-rw-r--r--code/bspc/_files.c63
-rw-r--r--code/bspc/aas_areamerging.c390
-rw-r--r--code/bspc/aas_areamerging.h24
-rw-r--r--code/bspc/aas_cfg.c252
-rw-r--r--code/bspc/aas_cfg.h73
-rw-r--r--code/bspc/aas_create.c1142
-rw-r--r--code/bspc/aas_create.h136
-rw-r--r--code/bspc/aas_edgemelting.c108
-rw-r--r--code/bspc/aas_edgemelting.h24
-rw-r--r--code/bspc/aas_facemerging.c282
-rw-r--r--code/bspc/aas_facemerging.h24
-rw-r--r--code/bspc/aas_file.c549
-rw-r--r--code/bspc/aas_file.h25
-rw-r--r--code/bspc/aas_gsubdiv.c656
-rw-r--r--code/bspc/aas_gsubdiv.h25
-rw-r--r--code/bspc/aas_map.c849
-rw-r--r--code/bspc/aas_map.h23
-rw-r--r--code/bspc/aas_prunenodes.c89
-rw-r--r--code/bspc/aas_prunenodes.h24
-rw-r--r--code/bspc/aas_store.c1082
-rw-r--r--code/bspc/aas_store.h107
-rw-r--r--code/bspc/aasfile.h252
-rw-r--r--code/bspc/be_aas_bspc.c292
-rw-r--r--code/bspc/be_aas_bspc.h23
-rw-r--r--code/bspc/brushbsp.c1871
-rw-r--r--code/bspc/bspc.c991
-rw-r--r--code/bspc/bspc.sln28
-rw-r--r--code/bspc/bspc.vcproj1381
-rw-r--r--code/bspc/cfgq3.c84
-rw-r--r--code/bspc/csg.c1005
-rw-r--r--code/bspc/faces.c978
-rw-r--r--code/bspc/gldraw.c232
-rw-r--r--code/bspc/glfile.c149
-rw-r--r--code/bspc/l_bsp_ent.c180
-rw-r--r--code/bspc/l_bsp_ent.h58
-rw-r--r--code/bspc/l_bsp_hl.c888
-rw-r--r--code/bspc/l_bsp_hl.h314
-rw-r--r--code/bspc/l_bsp_q1.c620
-rw-r--r--code/bspc/l_bsp_q1.h275
-rw-r--r--code/bspc/l_bsp_q2.c1134
-rw-r--r--code/bspc/l_bsp_q2.h98
-rw-r--r--code/bspc/l_bsp_q3.c824
-rw-r--r--code/bspc/l_bsp_q3.h81
-rw-r--r--code/bspc/l_bsp_sin.c1186
-rw-r--r--code/bspc/l_bsp_sin.h106
-rw-r--r--code/bspc/l_cmd.c1230
-rw-r--r--code/bspc/l_cmd.h157
-rw-r--r--code/bspc/l_log.c215
-rw-r--r--code/bspc/l_log.h42
-rw-r--r--code/bspc/l_math.c289
-rw-r--r--code/bspc/l_math.h93
-rw-r--r--code/bspc/l_mem.c441
-rw-r--r--code/bspc/l_mem.h51
-rw-r--r--code/bspc/l_poly.c1411
-rw-r--r--code/bspc/l_poly.h120
-rw-r--r--code/bspc/l_qfiles.c663
-rw-r--r--code/bspc/l_qfiles.h91
-rw-r--r--code/bspc/l_threads.c1510
-rw-r--r--code/bspc/l_threads.h45
-rw-r--r--code/bspc/l_utils.c259
-rw-r--r--code/bspc/l_utils.h79
-rw-r--r--code/bspc/lcc.mak61
-rw-r--r--code/bspc/leakfile.c101
-rw-r--r--code/bspc/linux-i386.mak109
-rw-r--r--code/bspc/map.c1267
-rw-r--r--code/bspc/map_hl.c1114
-rw-r--r--code/bspc/map_q1.c1174
-rw-r--r--code/bspc/map_q2.c1162
-rw-r--r--code/bspc/map_q3.c681
-rw-r--r--code/bspc/map_sin.c1211
-rw-r--r--code/bspc/nodraw.c47
-rw-r--r--code/bspc/portals.c1297
-rw-r--r--code/bspc/prtfile.c287
-rw-r--r--code/bspc/q2files.h487
-rw-r--r--code/bspc/q3files.h374
-rw-r--r--code/bspc/qbsp.h477
-rw-r--r--code/bspc/qfiles.h487
-rw-r--r--code/bspc/sinfiles.h365
-rw-r--r--code/bspc/tetrahedron.c1389
-rw-r--r--code/bspc/tetrahedron.h24
-rw-r--r--code/bspc/textures.c228
-rw-r--r--code/bspc/tree.c283
-rw-r--r--code/bspc/writebsp.c595
84 files changed, 0 insertions, 39027 deletions
diff --git a/code/bspc/Makefile b/code/bspc/Makefile
deleted file mode 100644
index b6d3b94..0000000
--- a/code/bspc/Makefile
+++ /dev/null
@@ -1,114 +0,0 @@
-#
-# Makefile for the BSPC tool for the Gladiator Bot
-# Intended for gcc/Linux
-#
-# TTimo 5/15/2001
-# some cleanup .. only used on i386 for GtkRadiant setups AFAIK .. removing the i386 tag
-# TODO: the intermediate object files should go into their own directory
-# specially for ../botlib and ../qcommon, the compilation flags on those might not be what you expect
-
-#ARCH=i386
-CC=gcc
-BASE_CFLAGS=-Dstricmp=strcasecmp
-
-#use these cflags to optimize it
-CFLAGS=$(BASE_CFLAGS) -m486 -O6 -ffast-math -funroll-loops \
- -fomit-frame-pointer -fexpensive-optimizations -malign-loops=2 \
- -malign-jumps=2 -malign-functions=2 -DLINUX -DBSPC
-#use these when debugging
-#CFLAGS=$(BASE_CFLAGS) -g
-
-LDFLAGS=-ldl -lm -lpthread
-
-DO_CC=$(CC) $(CFLAGS) -o $@ -c $<
-
-#############################################################################
-# SETUP AND BUILD BSPC
-#############################################################################
-
-.c.o:
- $(DO_CC)
-
-GAME_OBJS = \
- _files.o\
- aas_areamerging.o\
- aas_cfg.o\
- aas_create.o\
- aas_edgemelting.o\
- aas_facemerging.o\
- aas_file.o\
- aas_gsubdiv.o\
- aas_map.o\
- aas_prunenodes.o\
- aas_store.o\
- be_aas_bspc.o\
- ../botlib/be_aas_bspq3.o\
- ../botlib/be_aas_cluster.o\
- ../botlib/be_aas_move.o\
- ../botlib/be_aas_optimize.o\
- ../botlib/be_aas_reach.o\
- ../botlib/be_aas_sample.o\
- brushbsp.o\
- bspc.o\
- ../qcommon/cm_load.o\
- ../qcommon/cm_patch.o\
- ../qcommon/cm_test.o\
- ../qcommon/cm_trace.o\
- csg.o\
- glfile.o\
- l_bsp_ent.o\
- l_bsp_hl.o\
- l_bsp_q1.o\
- l_bsp_q2.o\
- l_bsp_q3.o\
- l_bsp_sin.o\
- l_cmd.o\
- ../botlib/l_libvar.o\
- l_log.o\
- l_math.o\
- l_mem.o\
- l_poly.o\
- ../botlib/l_precomp.o\
- l_qfiles.o\
- ../botlib/l_script.o\
- ../botlib/l_struct.o\
- l_threads.o\
- l_utils.o\
- leakfile.o\
- map.o\
- map_hl.o\
- map_q1.o\
- map_q2.o\
- map_q3.o\
- map_sin.o\
- ../qcommon/md4.o\
- nodraw.o\
- portals.o\
- textures.o\
- tree.o\
- ../qcommon/unzip.o
-
- #tetrahedron.o
-
-bspc : $(GAME_OBJS)
- $(CC) $(CFLAGS) -o $@ $(GAME_OBJS) $(LDFLAGS)
- strip $@
-
-
-#############################################################################
-# MISC
-#############################################################################
-
-clean:
- -rm -f $(GAME_OBJS)
-
-depend:
- gcc -MM $(GAME_OBJS:.o=.c)
-
-#install:
-# cp bspci386 ..
-
-#
-# From "make depend"
-#
-
diff --git a/code/bspc/_files.c b/code/bspc/_files.c
deleted file mode 100644
index 8f4fcff..0000000
--- a/code/bspc/_files.c
+++ /dev/null
@@ -1,63 +0,0 @@
-//===========================================================================
-//
-// Name: _files.c
-// Function:
-// Programmer: Mr Elusive
-// Last update: 1999-12-02
-// Tab Size: 4
-//===========================================================================
-
-/*
-
-aas_areamerging.c //AAS area merging
-aas_cfg.c //AAS configuration for different games
-aas_create.c //AAS creating
-aas_edgemelting.c //AAS edge melting
-aas_facemerging.c //AAS face merging
-aas_file.c //AAS file writing
-aas_gsubdiv.c //AAS gravitational and ladder subdivision
-aas_map.c //AAS map brush creation
-aas_prunenodes.c //AAS node pruning
-aas_store.c //AAS file storing
-
-map.c //map file loading and writing
-map_hl.c //Half-Life map loading
-map_q1.c //Quake1 map loading
-map_q2.c //Quake2 map loading
-map_q3.c //Quake3 map loading
-map_sin.c //Sin map loading
-tree.c //BSP tree management + node pruning (*)
-brushbsp.c //brush bsp creation (*)
-portals.c //BSP portal creation and leaf filling (*)
-csg.c //Constructive Solid Geometry brush chopping (*)
-leakfile.c //leak file writing (*)
-textures.c //Quake2 BSP textures (*)
-
-l_bsp_ent.c //BSP entity parsing
-l_bsp_hl.c //Half-Life BSP loading and writing
-l_bsp_q1.c //Quake1 BSP loading and writing
-l_bsp_q2.c //Quake2 BSP loading and writing
-l_bsp_q3.c //Quake2 BSP loading and writing
-l_bsp_sin.c //Sin BSP loading and writing
-l_cmd.c //cmd library
-l_log.c //log file library
-l_math.c //math library
-l_mem.c //memory management library
-l_poly.c //polygon (winding) library
-l_script.c //script file parsing library
-l_threads.c //multi-threading library
-l_utils.c //utility library
-l_qfiles.c //loading of quake files
-
-gldraw.c //GL drawing (*)
-glfile.c //GL file writing (*)
-nodraw.c //no draw module (*)
-
-bspc.c //BSPC Win32 console version
-winbspc.c //WinBSPC Win32 GUI version
-win32_terminal.c //Win32 terminal output
-win32_qfiles.c //Win32 game file management (also .pak .sin)
-win32_font.c //Win32 fonts
-win32_folder.c //Win32 folder dialogs
-
-*/
diff --git a/code/bspc/aas_areamerging.c b/code/bspc/aas_areamerging.c
deleted file mode 100644
index 4f40384..0000000
--- a/code/bspc/aas_areamerging.c
+++ /dev/null
@@ -1,390 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-#include "qbsp.h"
-#include "../botlib/aasfile.h"
-#include "aas_create.h"
-#include "aas_store.h"
-
-#define CONVEX_EPSILON 0.3
-
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-tmp_node_t *AAS_RefreshMergedTree_r(tmp_node_t *tmpnode)
-{
- tmp_area_t *tmparea;
-
- //if this is a solid leaf
- if (!tmpnode) return NULL;
- //if this is an area leaf
- if (tmpnode->tmparea)
- {
- tmparea = tmpnode->tmparea;
- while(tmparea->mergedarea) tmparea = tmparea->mergedarea;
- tmpnode->tmparea = tmparea;
- return tmpnode;
- } //end if
- //do the children recursively
- tmpnode->children[0] = AAS_RefreshMergedTree_r(tmpnode->children[0]);
- tmpnode->children[1] = AAS_RefreshMergedTree_r(tmpnode->children[1]);
- return tmpnode;
-} //end of the function AAS_RefreshMergedTree_r
-//===========================================================================
-// returns true if the two given faces would create a non-convex area at
-// the given sides, otherwise false is returned
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int NonConvex(tmp_face_t *face1, tmp_face_t *face2, int side1, int side2)
-{
- int i;
- winding_t *w1, *w2;
- plane_t *plane1, *plane2;
-
- w1 = face1->winding;
- w2 = face2->winding;
-
- plane1 = &mapplanes[face1->planenum ^ side1];
- plane2 = &mapplanes[face2->planenum ^ side2];
-
- //check if one of the points of face1 is at the back of the plane of face2
- for (i = 0; i < w1->numpoints; i++)
- {
- if (DotProduct(plane2->normal, w1->p[i]) - plane2->dist < -CONVEX_EPSILON) return true;
- } //end for
- //check if one of the points of face2 is at the back of the plane of face1
- for (i = 0; i < w2->numpoints; i++)
- {
- if (DotProduct(plane1->normal, w2->p[i]) - plane1->dist < -CONVEX_EPSILON) return true;
- } //end for
-
- return false;
-} //end of the function NonConvex
-//===========================================================================
-// try to merge the areas at both sides of the given face
-//
-// Parameter: seperatingface : face that seperates two areas
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int AAS_TryMergeFaceAreas(tmp_face_t *seperatingface)
-{
- int side1, side2, area1faceflags, area2faceflags;
- tmp_area_t *tmparea1, *tmparea2, *newarea;
- tmp_face_t *face1, *face2, *nextface1, *nextface2;
-
- tmparea1 = seperatingface->frontarea;
- tmparea2 = seperatingface->backarea;
-
- //areas must have the same presence type
- if (tmparea1->presencetype != tmparea2->presencetype) return false;
- //areas must have the same area contents
- if (tmparea1->contents != tmparea2->contents) return false;
- //areas must have the same bsp model inside (or both none)
- if (tmparea1->modelnum != tmparea2->modelnum) return false;
-
- area1faceflags = 0;
- area2faceflags = 0;
- for (face1 = tmparea1->tmpfaces; face1; face1 = face1->next[side1])
- {
- side1 = (face1->frontarea != tmparea1);
- //debug: check if the area belongs to the area
- if (face1->frontarea != tmparea1 &&
- face1->backarea != tmparea1) Error("face does not belong to area1");
- //just continue if the face is seperating the two areas
- //NOTE: a result of this is that ground and gap areas can
- // be merged if the seperating face is the gap
- if ((face1->frontarea == tmparea1 &&
- face1->backarea == tmparea2) ||
- (face1->frontarea == tmparea2 &&
- face1->backarea == tmparea1)) continue;
- //get area1 face flags
- area1faceflags |= face1->faceflags;
- if (AAS_GapFace(face1, side1)) area1faceflags |= FACE_GAP;
- //
- for (face2 = tmparea2->tmpfaces; face2; face2 = face2->next[side2])
- {
- side2 = (face2->frontarea != tmparea2);
- //debug: check if the area belongs to the area
- if (face2->frontarea != tmparea2 &&
- face2->backarea != tmparea2) Error("face does not belong to area2");
- //just continue if the face is seperating the two areas
- //NOTE: a result of this is that ground and gap areas can
- // be merged if the seperating face is the gap
- if ((face2->frontarea == tmparea1 &&
- face2->backarea == tmparea2) ||
- (face2->frontarea == tmparea2 &&
- face2->backarea == tmparea1)) continue;
- //get area2 face flags
- area2faceflags |= face2->faceflags;
- if (AAS_GapFace(face2, side2)) area2faceflags |= FACE_GAP;
- //if the two faces would create a non-convex area
- if (NonConvex(face1, face2, side1, side2)) return false;
- } //end for
- } //end for
- //if one area has gap faces (that aren't seperating the two areas)
- //and the other has ground faces (that aren't seperating the two areas),
- //the areas can't be merged
- if (((area1faceflags & FACE_GROUND) && (area2faceflags & FACE_GAP)) ||
- ((area2faceflags & FACE_GROUND) && (area1faceflags & FACE_GAP)))
- {
-// Log_Print(" can't merge: ground/gap\n");
- return false;
- } //end if
-
-// Log_Print("merged area %d & %d to %d with %d faces\n", tmparea1->areanum, tmparea2->areanum, newarea->areanum, numfaces);
-// return false;
- //
- //AAS_CheckArea(tmparea1);
- //AAS_CheckArea(tmparea2);
- //create the new area
- newarea = AAS_AllocTmpArea();
- newarea->presencetype = tmparea1->presencetype;
- newarea->contents = tmparea1->contents;
- newarea->modelnum = tmparea1->modelnum;
- newarea->tmpfaces = NULL;
-
- //add all the faces (except the seperating ones) from the first area
- //to the new area
- for (face1 = tmparea1->tmpfaces; face1; face1 = nextface1)
- {
- side1 = (face1->frontarea != tmparea1);
- nextface1 = face1->next[side1];
- //don't add seperating faces
- if ((face1->frontarea == tmparea1 &&
- face1->backarea == tmparea2) ||
- (face1->frontarea == tmparea2 &&
- face1->backarea == tmparea1))
- {
- continue;
- } //end if
- //
- AAS_RemoveFaceFromArea(face1, tmparea1);
- AAS_AddFaceSideToArea(face1, side1, newarea);
- } //end for
- //add all the faces (except the seperating ones) from the second area
- //to the new area
- for (face2 = tmparea2->tmpfaces; face2; face2 = nextface2)
- {
- side2 = (face2->frontarea != tmparea2);
- nextface2 = face2->next[side2];
- //don't add seperating faces
- if ((face2->frontarea == tmparea1 &&
- face2->backarea == tmparea2) ||
- (face2->frontarea == tmparea2 &&
- face2->backarea == tmparea1))
- {
- continue;
- } //end if
- //
- AAS_RemoveFaceFromArea(face2, tmparea2);
- AAS_AddFaceSideToArea(face2, side2, newarea);
- } //end for
- //free all shared faces
- for (face1 = tmparea1->tmpfaces; face1; face1 = nextface1)
- {
- side1 = (face1->frontarea != tmparea1);
- nextface1 = face1->next[side1];
- //
- AAS_RemoveFaceFromArea(face1, face1->frontarea);
- AAS_RemoveFaceFromArea(face1, face1->backarea);
- AAS_FreeTmpFace(face1);
- } //end for
- //
- tmparea1->mergedarea = newarea;
- tmparea1->invalid = true;
- tmparea2->mergedarea = newarea;
- tmparea2->invalid = true;
- //
- AAS_CheckArea(newarea);
- AAS_FlipAreaFaces(newarea);
-// Log_Print("merged area %d & %d to %d with %d faces\n", tmparea1->areanum, tmparea2->areanum, newarea->areanum);
- return true;
-} //end of the function AAS_TryMergeFaceAreas
-//===========================================================================
-// try to merge areas
-// merged areas are added to the end of the convex area list so merging
-// will be tried for those areas as well
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: tmpaasworld
-//===========================================================================
-/*
-void AAS_MergeAreas(void)
-{
- int side, nummerges;
- tmp_area_t *tmparea, *othertmparea;
- tmp_face_t *face;
-
- nummerges = 0;
- Log_Write("AAS_MergeAreas\r\n");
- qprintf("%6d areas merged", 1);
- //first merge grounded areas only
- //NOTE: this is useless because the area settings aren't available yet
- for (tmparea = tmpaasworld.areas; tmparea; tmparea = tmparea->l_next)
- {
-// Log_Print("checking area %d\n", i);
- //if the area is invalid
- if (tmparea->invalid)
- {
-// Log_Print(" area invalid\n");
- continue;
- } //end if
- //
-// if (!(tmparea->settings->areaflags & AREA_GROUNDED)) continue;
- //
- for (face = tmparea->tmpfaces; face; face = face->next[side])
- {
- side = (face->frontarea != tmparea);
- //if the face has both a front and back area
- if (face->frontarea && face->backarea)
- {
- //
- if (face->frontarea == tmparea) othertmparea = face->backarea;
- else othertmparea = face->frontarea;
-// if (!(othertmparea->settings->areaflags & AREA_GROUNDED)) continue;
-// Log_Print(" checking area %d with %d\n", face->frontarea, face->backarea);
- if (AAS_TryMergeFaceAreas(face))
- {
- qprintf("\r%6d", ++nummerges);
- break;
- } //end if
- } //end if
- } //end for
- } //end for
- //merge all areas
- for (tmparea = tmpaasworld.areas; tmparea; tmparea = tmparea->l_next)
- {
-// Log_Print("checking area %d\n", i);
- //if the area is invalid
- if (tmparea->invalid)
- {
-// Log_Print(" area invalid\n");
- continue;
- } //end if
- //
- for (face = tmparea->tmpfaces; face; face = face->next[side])
- {
- side = (face->frontarea != tmparea);
- //if the face has both a front and back area
- if (face->frontarea && face->backarea)
- {
-// Log_Print(" checking area %d with %d\n", face->frontarea, face->backarea);
- if (AAS_TryMergeFaceAreas(face))
- {
- qprintf("\r%6d", ++nummerges);
- break;
- } //end if
- } //end if
- } //end for
- } //end for
- Log_Print("\r%6d areas merged\n", nummerges);
- //refresh the merged tree
- AAS_RefreshMergedTree_r(tmpaasworld.nodes);
-} //end of the function AAS_MergeAreas*/
-
-int AAS_GroundArea(tmp_area_t *tmparea)
-{
- tmp_face_t *face;
- int side;
-
- for (face = tmparea->tmpfaces; face; face = face->next[side])
- {
- side = (face->frontarea != tmparea);
- if (face->faceflags & FACE_GROUND) return true;
- } //end for
- return false;
-} //end of the function AAS_GroundArea
-
-void AAS_MergeAreas(void)
-{
- int side, nummerges, merges, groundfirst;
- tmp_area_t *tmparea, *othertmparea;
- tmp_face_t *face;
-
- nummerges = 0;
- Log_Write("AAS_MergeAreas\r\n");
- qprintf("%6d areas merged", 1);
- //
- groundfirst = true;
- //for (i = 0; i < 4 || merges; i++)
- while(1)
- {
- //if (i < 2) groundfirst = true;
- //else groundfirst = false;
- //
- merges = 0;
- //first merge grounded areas only
- for (tmparea = tmpaasworld.areas; tmparea; tmparea = tmparea->l_next)
- {
- //if the area is invalid
- if (tmparea->invalid)
- {
- continue;
- } //end if
- //
- if (groundfirst)
- {
- if (!AAS_GroundArea(tmparea)) continue;
- } //end if
- //
- for (face = tmparea->tmpfaces; face; face = face->next[side])
- {
- side = (face->frontarea != tmparea);
- //if the face has both a front and back area
- if (face->frontarea && face->backarea)
- {
- //
- if (face->frontarea == tmparea) othertmparea = face->backarea;
- else othertmparea = face->frontarea;
- //
- if (groundfirst)
- {
- if (!AAS_GroundArea(othertmparea)) continue;
- } //end if
- if (AAS_TryMergeFaceAreas(face))
- {
- qprintf("\r%6d", ++nummerges);
- merges++;
- break;
- } //end if
- } //end if
- } //end for
- } //end for
- if (!merges)
- {
- if (groundfirst) groundfirst = false;
- else break;
- } //end if
- } //end for
- qprintf("\n");
- Log_Write("%6d areas merged\r\n", nummerges);
- //refresh the merged tree
- AAS_RefreshMergedTree_r(tmpaasworld.nodes);
-} //end of the function AAS_MergeAreas
diff --git a/code/bspc/aas_areamerging.h b/code/bspc/aas_areamerging.h
deleted file mode 100644
index a9abacc..0000000
--- a/code/bspc/aas_areamerging.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-void AAS_MergeAreas(void);
-
diff --git a/code/bspc/aas_cfg.c b/code/bspc/aas_cfg.c
deleted file mode 100644
index d8c8fd7..0000000
--- a/code/bspc/aas_cfg.c
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-#include "qbsp.h"
-#include "float.h"
-#include "../botlib/aasfile.h"
-#include "aas_store.h"
-#include "aas_cfg.h"
-#include "../botlib/l_precomp.h"
-#include "../botlib/l_struct.h"
-#include "../botlib/l_libvar.h"
-
-//structure field offsets
-#define BBOX_OFS(x) (int)&(((aas_bbox_t *)0)->x)
-#define CFG_OFS(x) (int)&(((cfg_t *)0)->x)
-
-//bounding box definition
-fielddef_t bbox_fields[] =
-{
- {"presencetype", BBOX_OFS(presencetype), FT_INT},
- {"flags", BBOX_OFS(flags), FT_INT},
- {"mins", BBOX_OFS(mins), FT_FLOAT|FT_ARRAY, 3},
- {"maxs", BBOX_OFS(maxs), FT_FLOAT|FT_ARRAY, 3},
- {NULL, 0, 0, 0}
-};
-
-fielddef_t cfg_fields[] =
-{
- {"phys_gravitydirection", CFG_OFS(phys_gravitydirection), FT_FLOAT|FT_ARRAY, 3},
- {"phys_friction", CFG_OFS(phys_friction), FT_FLOAT},
- {"phys_stopspeed", CFG_OFS(phys_stopspeed), FT_FLOAT},
- {"phys_gravity", CFG_OFS(phys_gravity), FT_FLOAT},
- {"phys_waterfriction", CFG_OFS(phys_waterfriction), FT_FLOAT},
- {"phys_watergravity", CFG_OFS(phys_watergravity), FT_FLOAT},
- {"phys_maxvelocity", CFG_OFS(phys_maxvelocity), FT_FLOAT},
- {"phys_maxwalkvelocity", CFG_OFS(phys_maxwalkvelocity), FT_FLOAT},
- {"phys_maxcrouchvelocity", CFG_OFS(phys_maxcrouchvelocity), FT_FLOAT},
- {"phys_maxswimvelocity", CFG_OFS(phys_maxswimvelocity), FT_FLOAT},
- {"phys_walkaccelerate", CFG_OFS(phys_walkaccelerate), FT_FLOAT},
- {"phys_airaccelerate", CFG_OFS(phys_airaccelerate), FT_FLOAT},
- {"phys_swimaccelerate", CFG_OFS(phys_swimaccelerate), FT_FLOAT},
- {"phys_maxstep", CFG_OFS(phys_maxstep), FT_FLOAT},
- {"phys_maxsteepness", CFG_OFS(phys_maxsteepness), FT_FLOAT},
- {"phys_maxwaterjump", CFG_OFS(phys_maxwaterjump), FT_FLOAT},
- {"phys_maxbarrier", CFG_OFS(phys_maxbarrier), FT_FLOAT},
- {"phys_jumpvel", CFG_OFS(phys_jumpvel), FT_FLOAT},
- {"phys_falldelta5", CFG_OFS(phys_falldelta5), FT_FLOAT},
- {"phys_falldelta10", CFG_OFS(phys_falldelta10), FT_FLOAT},
- {"rs_waterjump", CFG_OFS(rs_waterjump), FT_FLOAT},
- {"rs_teleport", CFG_OFS(rs_teleport), FT_FLOAT},
- {"rs_barrierjump", CFG_OFS(rs_barrierjump), FT_FLOAT},
- {"rs_startcrouch", CFG_OFS(rs_startcrouch), FT_FLOAT},
- {"rs_startgrapple", CFG_OFS(rs_startgrapple), FT_FLOAT},
- {"rs_startwalkoffledge", CFG_OFS(rs_startwalkoffledge), FT_FLOAT},
- {"rs_startjump", CFG_OFS(rs_startjump), FT_FLOAT},
- {"rs_rocketjump", CFG_OFS(rs_rocketjump), FT_FLOAT},
- {"rs_bfgjump", CFG_OFS(rs_bfgjump), FT_FLOAT},
- {"rs_jumppad", CFG_OFS(rs_jumppad), FT_FLOAT},
- {"rs_aircontrolledjumppad", CFG_OFS(rs_aircontrolledjumppad), FT_FLOAT},
- {"rs_funcbob", CFG_OFS(rs_funcbob), FT_FLOAT},
- {"rs_startelevator", CFG_OFS(rs_startelevator), FT_FLOAT},
- {"rs_falldamage5", CFG_OFS(rs_falldamage5), FT_FLOAT},
- {"rs_falldamage10", CFG_OFS(rs_falldamage10), FT_FLOAT},
- {"rs_maxjumpfallheight", CFG_OFS(rs_maxjumpfallheight), FT_FLOAT},
- {NULL, 0, 0, 0}
-};
-
-structdef_t bbox_struct =
-{
- sizeof(aas_bbox_t), bbox_fields
-};
-structdef_t cfg_struct =
-{
- sizeof(cfg_t), cfg_fields
-};
-
-//global cfg
-cfg_t cfg;
-
-//===========================================================================
-// the default Q3A configuration
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void DefaultCfg(void)
-{
- int i;
-
- // default all float values to infinite
- for (i = 0; cfg_fields[i].name; i++)
- {
- if ((cfg_fields[i].type & FT_TYPE) == FT_FLOAT)
- *(float *)( ((char*)&cfg) + cfg_fields[i].offset ) = FLT_MAX;
- } //end for
- //
- cfg.numbboxes = 2;
- //bbox 0
- cfg.bboxes[0].presencetype = PRESENCE_NORMAL;
- cfg.bboxes[0].flags = 0;
- cfg.bboxes[0].mins[0] = -15;
- cfg.bboxes[0].mins[1] = -15;
- cfg.bboxes[0].mins[2] = -24;
- cfg.bboxes[0].maxs[0] = 15;
- cfg.bboxes[0].maxs[1] = 15;
- cfg.bboxes[0].maxs[2] = 32;
- //bbox 1
- cfg.bboxes[1].presencetype = PRESENCE_CROUCH;
- cfg.bboxes[1].flags = 1;
- cfg.bboxes[1].mins[0] = -15;
- cfg.bboxes[1].mins[1] = -15;
- cfg.bboxes[1].mins[2] = -24;
- cfg.bboxes[1].maxs[0] = 15;
- cfg.bboxes[1].maxs[1] = 15;
- cfg.bboxes[1].maxs[2] = 16;
- //
- cfg.allpresencetypes = PRESENCE_NORMAL|PRESENCE_CROUCH;
- cfg.phys_gravitydirection[0] = 0;
- cfg.phys_gravitydirection[1] = 0;
- cfg.phys_gravitydirection[2] = -1;
- cfg.phys_maxsteepness = 0.7;
-} //end of the function DefaultCfg
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-char * QDECL va( char *format, ... )
-{
- va_list argptr;
- static char string[2][32000]; // in case va is called by nested functions
- static int index = 0;
- char *buf;
-
- buf = string[index & 1];
- index++;
-
- va_start (argptr, format);
- vsprintf (buf, format,argptr);
- va_end (argptr);
-
- return buf;
-} //end of the function va
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void SetCfgLibVars(void)
-{
- int i;
- float value;
-
- for (i = 0; cfg_fields[i].name; i++)
- {
- if ((cfg_fields[i].type & FT_TYPE) == FT_FLOAT)
- {
- value = *(float *)(((char*)&cfg) + cfg_fields[i].offset);
- if (value != FLT_MAX)
- {
- LibVarSet(cfg_fields[i].name, va("%f", value));
- } //end if
- } //end if
- } //end for
-} //end of the function SetCfgLibVars
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int LoadCfgFile(char *filename)
-{
- source_t *source;
- token_t token;
- int settingsdefined;
-
- source = LoadSourceFile(filename);
- if (!source)
- {
- Log_Print("couldn't open cfg file %s\n", filename);
- return false;
- } //end if
-
- settingsdefined = false;
- memset(&cfg, 0, sizeof(cfg_t));
-
- while(PC_ReadToken(source, &token))
- {
- if (!stricmp(token.string, "bbox"))
- {
- if (cfg.numbboxes >= AAS_MAX_BBOXES)
- {
- SourceError(source, "too many bounding box volumes defined");
- } //end if
- if (!ReadStructure(source, &bbox_struct, (char *) &cfg.bboxes[cfg.numbboxes]))
- {
- FreeSource(source);
- return false;
- } //end if
- cfg.allpresencetypes |= cfg.bboxes[cfg.numbboxes].presencetype;
- cfg.numbboxes++;
- } //end if
- else if (!stricmp(token.string, "settings"))
- {
- if (settingsdefined)
- {
- SourceWarning(source, "settings already defined\n");
- } //end if
- settingsdefined = true;
- if (!ReadStructure(source, &cfg_struct, (char *) &cfg))
- {
- FreeSource(source);
- return false;
- } //end if
- } //end else if
- } //end while
- if (VectorLength(cfg.phys_gravitydirection) < 0.9 || VectorLength(cfg.phys_gravitydirection) > 1.1)
- {
- SourceError(source, "invalid gravity direction specified");
- } //end if
- if (cfg.numbboxes <= 0)
- {
- SourceError(source, "no bounding volumes specified");
- } //end if
- FreeSource(source);
- SetCfgLibVars();
- Log_Print("using cfg file %s\n", filename);
- return true;
-} //end of the function LoadCfgFile
diff --git a/code/bspc/aas_cfg.h b/code/bspc/aas_cfg.h
deleted file mode 100644
index 7007002..0000000
--- a/code/bspc/aas_cfg.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-#define BBOXFL_GROUNDED 1 //bounding box only valid when on ground
-#define BBOXFL_NOTGROUNDED 2 //bounding box only valid when NOT on ground
-
-typedef struct cfg_s
-{
- int numbboxes; //number of bounding boxes
- aas_bbox_t bboxes[AAS_MAX_BBOXES]; //all the bounding boxes
- int allpresencetypes; //or of all presence types
- // aas settings
- vec3_t phys_gravitydirection;
- float phys_friction;
- float phys_stopspeed;
- float phys_gravity;
- float phys_waterfriction;
- float phys_watergravity;
- float phys_maxvelocity;
- float phys_maxwalkvelocity;
- float phys_maxcrouchvelocity;
- float phys_maxswimvelocity;
- float phys_walkaccelerate;
- float phys_airaccelerate;
- float phys_swimaccelerate;
- float phys_maxstep;
- float phys_maxsteepness;
- float phys_maxwaterjump;
- float phys_maxbarrier;
- float phys_jumpvel;
- float phys_falldelta5;
- float phys_falldelta10;
- float rs_waterjump;
- float rs_teleport;
- float rs_barrierjump;
- float rs_startcrouch;
- float rs_startgrapple;
- float rs_startwalkoffledge;
- float rs_startjump;
- float rs_rocketjump;
- float rs_bfgjump;
- float rs_jumppad;
- float rs_aircontrolledjumppad;
- float rs_funcbob;
- float rs_startelevator;
- float rs_falldamage5;
- float rs_falldamage10;
- float rs_maxjumpfallheight;
-} cfg_t;
-
-extern cfg_t cfg;
-
-void DefaultCfg(void);
-int LoadCfgFile(char *filename);
diff --git a/code/bspc/aas_create.c b/code/bspc/aas_create.c
deleted file mode 100644
index 6eea740..0000000
--- a/code/bspc/aas_create.c
+++ /dev/null
@@ -1,1142 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-#include "qbsp.h"
-#include "../botlib/aasfile.h"
-#include "aas_create.h"
-#include "aas_store.h"
-#include "aas_gsubdiv.h"
-#include "aas_facemerging.h"
-#include "aas_areamerging.h"
-#include "aas_edgemelting.h"
-#include "aas_prunenodes.h"
-#include "aas_cfg.h"
-#include "../qcommon/surfaceflags.h"
-
-//#define AW_DEBUG
-//#define L_DEBUG
-
-#define AREAONFACESIDE(face, area) (face->frontarea != area)
-
-tmp_aas_t tmpaasworld;
-
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_InitTmpAAS(void)
-{
- //tmp faces
- tmpaasworld.numfaces = 0;
- tmpaasworld.facenum = 0;
- tmpaasworld.faces = NULL;
- //tmp convex areas
- tmpaasworld.numareas = 0;
- tmpaasworld.areanum = 0;
- tmpaasworld.areas = NULL;
- //tmp nodes
- tmpaasworld.numnodes = 0;
- tmpaasworld.nodes = NULL;
- //
- tmpaasworld.nodebuffer = NULL;
-} //end of the function AAS_InitTmpAAS
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_FreeTmpAAS(void)
-{
- tmp_face_t *f, *nextf;
- tmp_area_t *a, *nexta;
- tmp_nodebuf_t *nb, *nextnb;
-
- //free all the faces
- for (f = tmpaasworld.faces; f; f = nextf)
- {
- nextf = f->l_next;
- if (f->winding) FreeWinding(f->winding);
- FreeMemory(f);
- } //end if
- //free all tmp areas
- for (a = tmpaasworld.areas; a; a = nexta)
- {
- nexta = a->l_next;
- if (a->settings) FreeMemory(a->settings);
- FreeMemory(a);
- } //end for
- //free all the tmp nodes
- for (nb = tmpaasworld.nodebuffer; nb; nb = nextnb)
- {
- nextnb = nb->next;
- FreeMemory(nb);
- } //end for
-} //end of the function AAS_FreeTmpAAS
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-tmp_face_t *AAS_AllocTmpFace(void)
-{
- tmp_face_t *tmpface;
-
- tmpface = (tmp_face_t *) GetClearedMemory(sizeof(tmp_face_t));
- tmpface->num = tmpaasworld.facenum++;
- tmpface->l_prev = NULL;
- tmpface->l_next = tmpaasworld.faces;
- if (tmpaasworld.faces) tmpaasworld.faces->l_prev = tmpface;
- tmpaasworld.faces = tmpface;
- tmpaasworld.numfaces++;
- return tmpface;
-} //end of the function AAS_AllocTmpFace
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_FreeTmpFace(tmp_face_t *tmpface)
-{
- if (tmpface->l_next) tmpface->l_next->l_prev = tmpface->l_prev;
- if (tmpface->l_prev) tmpface->l_prev->l_next = tmpface->l_next;
- else tmpaasworld.faces = tmpface->l_next;
- //free the winding
- if (tmpface->winding) FreeWinding(tmpface->winding);
- //free the face
- FreeMemory(tmpface);
- tmpaasworld.numfaces--;
-} //end of the function AAS_FreeTmpFace
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-tmp_area_t *AAS_AllocTmpArea(void)
-{
- tmp_area_t *tmparea;
-
- tmparea = (tmp_area_t *) GetClearedMemory(sizeof(tmp_area_t));
- tmparea->areanum = tmpaasworld.areanum++;
- tmparea->l_prev = NULL;
- tmparea->l_next = tmpaasworld.areas;
- if (tmpaasworld.areas) tmpaasworld.areas->l_prev = tmparea;
- tmpaasworld.areas = tmparea;
- tmpaasworld.numareas++;
- return tmparea;
-} //end of the function AAS_AllocTmpArea
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_FreeTmpArea(tmp_area_t *tmparea)
-{
- if (tmparea->l_next) tmparea->l_next->l_prev = tmparea->l_prev;
- if (tmparea->l_prev) tmparea->l_prev->l_next = tmparea->l_next;
- else tmpaasworld.areas = tmparea->l_next;
- if (tmparea->settings) FreeMemory(tmparea->settings);
- FreeMemory(tmparea);
- tmpaasworld.numareas--;
-} //end of the function AAS_FreeTmpArea
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-tmp_node_t *AAS_AllocTmpNode(void)
-{
- tmp_nodebuf_t *nodebuf;
-
- if (!tmpaasworld.nodebuffer ||
- tmpaasworld.nodebuffer->numnodes >= NODEBUF_SIZE)
- {
- nodebuf = (tmp_nodebuf_t *) GetClearedMemory(sizeof(tmp_nodebuf_t));
- nodebuf->next = tmpaasworld.nodebuffer;
- nodebuf->numnodes = 0;
- tmpaasworld.nodebuffer = nodebuf;
- } //end if
- tmpaasworld.numnodes++;
- return &tmpaasworld.nodebuffer->nodes[tmpaasworld.nodebuffer->numnodes++];
-} //end of the function AAS_AllocTmpNode
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_FreeTmpNode(tmp_node_t *tmpnode)
-{
- tmpaasworld.numnodes--;
-} //end of the function AAS_FreeTmpNode
-//===========================================================================
-// returns true if the face is a gap from the given side
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int AAS_GapFace(tmp_face_t *tmpface, int side)
-{
- vec3_t invgravity;
-
- //if the face is a solid or ground face it can't be a gap
- if (tmpface->faceflags & (FACE_GROUND | FACE_SOLID)) return 0;
-
- VectorCopy(cfg.phys_gravitydirection, invgravity);
- VectorInverse(invgravity);
-
- return (DotProduct(invgravity, mapplanes[tmpface->planenum ^ side].normal) > cfg.phys_maxsteepness);
-} //end of the function AAS_GapFace
-//===========================================================================
-// returns true if the face is a ground face
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int AAS_GroundFace(tmp_face_t *tmpface)
-{
- vec3_t invgravity;
-
- //must be a solid face
- if (!(tmpface->faceflags & FACE_SOLID)) return 0;
-
- VectorCopy(cfg.phys_gravitydirection, invgravity);
- VectorInverse(invgravity);
-
- return (DotProduct(invgravity, mapplanes[tmpface->planenum].normal) > cfg.phys_maxsteepness);
-} //end of the function AAS_GroundFace
-//===========================================================================
-// adds the side of a face to an area
-//
-// side : 0 = front side
-// 1 = back side
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_AddFaceSideToArea(tmp_face_t *tmpface, int side, tmp_area_t *tmparea)
-{
- int tmpfaceside;
-
- if (side)
- {
- if (tmpface->backarea) Error("AAS_AddFaceSideToArea: already a back area\n");
- } //end if
- else
- {
- if (tmpface->frontarea) Error("AAS_AddFaceSideToArea: already a front area\n");
- } //end else
-
- if (side) tmpface->backarea = tmparea;
- else tmpface->frontarea = tmparea;
-
- if (tmparea->tmpfaces)
- {
- tmpfaceside = tmparea->tmpfaces->frontarea != tmparea;
- tmparea->tmpfaces->prev[tmpfaceside] = tmpface;
- } //end if
- tmpface->next[side] = tmparea->tmpfaces;
- tmpface->prev[side] = NULL;
- tmparea->tmpfaces = tmpface;
-} //end of the function AAS_AddFaceSideToArea
-//===========================================================================
-// remove (a side of) a face from an area
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_RemoveFaceFromArea(tmp_face_t *tmpface, tmp_area_t *tmparea)
-{
- int side, prevside, nextside;
-
- if (tmpface->frontarea != tmparea &&
- tmpface->backarea != tmparea)
- {
- Error("AAS_RemoveFaceFromArea: face not part of the area");
- } //end if
- side = tmpface->frontarea != tmparea;
- if (tmpface->prev[side])
- {
- prevside = tmpface->prev[side]->frontarea != tmparea;
- tmpface->prev[side]->next[prevside] = tmpface->next[side];
- } //end if
- else
- {
- tmparea->tmpfaces = tmpface->next[side];
- } //end else
- if (tmpface->next[side])
- {
- nextside = tmpface->next[side]->frontarea != tmparea;
- tmpface->next[side]->prev[nextside] = tmpface->prev[side];
- } //end if
- //remove the area number from the face depending on the side
- if (side) tmpface->backarea = NULL;
- else tmpface->frontarea = NULL;
- tmpface->prev[side] = NULL;
- tmpface->next[side] = NULL;
-} //end of the function AAS_RemoveFaceFromArea
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_CheckArea(tmp_area_t *tmparea)
-{
- int side;
- tmp_face_t *face;
- plane_t *plane;
- vec3_t wcenter, acenter = {0, 0, 0};
- vec3_t normal;
- float n, dist;
-
- if (tmparea->invalid) Log_Print("AAS_CheckArea: invalid area\n");
- for (n = 0, face = tmparea->tmpfaces; face; face = face->next[side])
- {
- //side of the face the area is on
- side = face->frontarea != tmparea;
- WindingCenter(face->winding, wcenter);
- VectorAdd(acenter, wcenter, acenter);
- n++;
- } //end for
- n = 1 / n;
- VectorScale(acenter, n, acenter);
- for (face = tmparea->tmpfaces; face; face = face->next[side])
- {
- //side of the face the area is on
- side = face->frontarea != tmparea;
-
-#ifdef L_DEBUG
- if (WindingError(face->winding))
- {
- Log_Write("AAS_CheckArea: area %d face %d: %s\r\n", tmparea->areanum,
- face->num, WindingErrorString());
- } //end if
-#endif L_DEBUG
-
- plane = &mapplanes[face->planenum ^ side];
-
- if (DotProduct(plane->normal, acenter) - plane->dist < 0)
- {
- Log_Print("AAS_CheckArea: area %d face %d is flipped\n", tmparea->areanum, face->num);
- Log_Print("AAS_CheckArea: area %d center is %f %f %f\n", tmparea->areanum, acenter[0], acenter[1], acenter[2]);
- } //end if
- //check if the winding plane is the same as the face plane
- WindingPlane(face->winding, normal, &dist);
- plane = &mapplanes[face->planenum];
-#ifdef L_DEBUG
- if (fabs(dist - plane->dist) > 0.4 ||
- fabs(normal[0] - plane->normal[0]) > 0.0001 ||
- fabs(normal[1] - plane->normal[1]) > 0.0001 ||
- fabs(normal[2] - plane->normal[2]) > 0.0001)
- {
- Log_Write("AAS_CheckArea: area %d face %d winding plane unequal to face plane\r\n",
- tmparea->areanum, face->num);
- } //end if
-#endif L_DEBUG
- } //end for
-} //end of the function AAS_CheckArea
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_CheckFaceWindingPlane(tmp_face_t *face)
-{
- float dist, sign1, sign2;
- vec3_t normal;
- plane_t *plane;
- winding_t *w;
-
- //check if the winding plane is the same as the face plane
- WindingPlane(face->winding, normal, &dist);
- plane = &mapplanes[face->planenum];
- //
- sign1 = DotProduct(plane->normal, normal);
- //
- if (fabs(dist - plane->dist) > 0.4 ||
- fabs(normal[0] - plane->normal[0]) > 0.0001 ||
- fabs(normal[1] - plane->normal[1]) > 0.0001 ||
- fabs(normal[2] - plane->normal[2]) > 0.0001)
- {
- VectorInverse(normal);
- dist = -dist;
- if (fabs(dist - plane->dist) > 0.4 ||
- fabs(normal[0] - plane->normal[0]) > 0.0001 ||
- fabs(normal[1] - plane->normal[1]) > 0.0001 ||
- fabs(normal[2] - plane->normal[2]) > 0.0001)
- {
- Log_Write("AAS_CheckFaceWindingPlane: face %d winding plane unequal to face plane\r\n",
- face->num);
- //
- sign2 = DotProduct(plane->normal, normal);
- if ((sign1 < 0 && sign2 > 0) ||
- (sign1 > 0 && sign2 < 0))
- {
- Log_Write("AAS_CheckFaceWindingPlane: face %d winding reversed\r\n",
- face->num);
- w = face->winding;
- face->winding = ReverseWinding(w);
- FreeWinding(w);
- } //end if
- } //end if
- else
- {
- Log_Write("AAS_CheckFaceWindingPlane: face %d winding reversed\r\n",
- face->num);
- w = face->winding;
- face->winding = ReverseWinding(w);
- FreeWinding(w);
- } //end else
- } //end if
-} //end of the function AAS_CheckFaceWindingPlane
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_CheckAreaWindingPlanes(void)
-{
- int side;
- tmp_area_t *tmparea;
- tmp_face_t *face;
-
- Log_Write("AAS_CheckAreaWindingPlanes:\r\n");
- for (tmparea = tmpaasworld.areas; tmparea; tmparea = tmparea->l_next)
- {
- if (tmparea->invalid) continue;
- for (face = tmparea->tmpfaces; face; face = face->next[side])
- {
- side = face->frontarea != tmparea;
- AAS_CheckFaceWindingPlane(face);
- } //end for
- } //end for
-} //end of the function AAS_CheckAreaWindingPlanes
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_FlipAreaFaces(tmp_area_t *tmparea)
-{
- int side;
- tmp_face_t *face;
- plane_t *plane;
- vec3_t wcenter, acenter = {0, 0, 0};
- //winding_t *w;
- float n;
-
- for (n = 0, face = tmparea->tmpfaces; face; face = face->next[side])
- {
- if (!face->frontarea) Error("face %d has no front area\n", face->num);
- //side of the face the area is on
- side = face->frontarea != tmparea;
- WindingCenter(face->winding, wcenter);
- VectorAdd(acenter, wcenter, acenter);
- n++;
- } //end for
- n = 1 / n;
- VectorScale(acenter, n, acenter);
- for (face = tmparea->tmpfaces; face; face = face->next[side])
- {
- //side of the face the area is on
- side = face->frontarea != tmparea;
-
- plane = &mapplanes[face->planenum ^ side];
-
- if (DotProduct(plane->normal, acenter) - plane->dist < 0)
- {
- Log_Print("area %d face %d flipped: front area %d, back area %d\n", tmparea->areanum, face->num,
- face->frontarea ? face->frontarea->areanum : 0,
- face->backarea ? face->backarea->areanum : 0);
- /*
- face->planenum = face->planenum ^ 1;
- w = face->winding;
- face->winding = ReverseWinding(w);
- FreeWinding(w);
- */
- } //end if
-#ifdef L_DEBUG
- {
- float dist;
- vec3_t normal;
-
- //check if the winding plane is the same as the face plane
- WindingPlane(face->winding, normal, &dist);
- plane = &mapplanes[face->planenum];
- if (fabs(dist - plane->dist) > 0.4 ||
- fabs(normal[0] - plane->normal[0]) > 0.0001 ||
- fabs(normal[1] - plane->normal[1]) > 0.0001 ||
- fabs(normal[2] - plane->normal[2]) > 0.0001)
- {
- Log_Write("area %d face %d winding plane unequal to face plane\r\n",
- tmparea->areanum, face->num);
- } //end if
- }
-#endif
- } //end for
-} //end of the function AAS_FlipAreaFaces
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_RemoveAreaFaceColinearPoints(void)
-{
- int side;
- tmp_face_t *face;
- tmp_area_t *tmparea;
-
- //FIXME: loop over the faces instead of area->faces
- for (tmparea = tmpaasworld.areas; tmparea; tmparea = tmparea->l_next)
- {
- for (face = tmparea->tmpfaces; face; face = face->next[side])
- {
- side = face->frontarea != tmparea;
- RemoveColinearPoints(face->winding);
-// RemoveEqualPoints(face->winding, 0.1);
- } //end for
- } //end for
-} //end of the function AAS_RemoveAreaFaceColinearPoints
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_RemoveTinyFaces(void)
-{
- int side, num;
- tmp_face_t *face, *nextface;
- tmp_area_t *tmparea;
-
- //FIXME: loop over the faces instead of area->faces
- Log_Write("AAS_RemoveTinyFaces\r\n");
- num = 0;
- for (tmparea = tmpaasworld.areas; tmparea; tmparea = tmparea->l_next)
- {
- for (face = tmparea->tmpfaces; face; face = nextface)
- {
- side = face->frontarea != tmparea;
- nextface = face->next[side];
- //
- if (WindingArea(face->winding) < 1)
- {
- if (face->frontarea) AAS_RemoveFaceFromArea(face, face->frontarea);
- if (face->backarea) AAS_RemoveFaceFromArea(face, face->backarea);
- AAS_FreeTmpFace(face);
- //Log_Write("area %d face %d is tiny\r\n", tmparea->areanum, face->num);
- num++;
- } //end if
- } //end for
- } //end for
- Log_Write("%d tiny faces removed\r\n", num);
-} //end of the function AAS_RemoveTinyFaces
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_CreateAreaSettings(void)
-{
- int i, flags, side, numgrounded, numladderareas, numliquidareas;
- tmp_face_t *face;
- tmp_area_t *tmparea;
-
- numgrounded = 0;
- numladderareas = 0;
- numliquidareas = 0;
- Log_Write("AAS_CreateAreaSettings\r\n");
- i = 0;
- qprintf("%6d areas provided with settings", i);
- for (tmparea = tmpaasworld.areas; tmparea; tmparea = tmparea->l_next)
- {
- //if the area is invalid there no need to create settings for it
- if (tmparea->invalid) continue;
-
- tmparea->settings = (tmp_areasettings_t *) GetClearedMemory(sizeof(tmp_areasettings_t));
- tmparea->settings->contents = tmparea->contents;
- tmparea->settings->modelnum = tmparea->modelnum;
- flags = 0;
- for (face = tmparea->tmpfaces; face; face = face->next[side])
- {
- side = face->frontarea != tmparea;
- flags |= face->faceflags;
- } //end for
- tmparea->settings->areaflags = 0;
- if (flags & FACE_GROUND)
- {
- tmparea->settings->areaflags |= AREA_GROUNDED;
- numgrounded++;
- } //end if
- if (flags & FACE_LADDER)
- {
- tmparea->settings->areaflags |= AREA_LADDER;
- numladderareas++;
- } //end if
- if (tmparea->contents & (AREACONTENTS_WATER |
- AREACONTENTS_SLIME |
- AREACONTENTS_LAVA))
- {
- tmparea->settings->areaflags |= AREA_LIQUID;
- numliquidareas++;
- } //end if
- //presence type of the area
- tmparea->settings->presencetype = tmparea->presencetype;
- //
- qprintf("\r%6d", ++i);
- } //end for
- qprintf("\n");
-#ifdef AASINFO
- Log_Print("%6d grounded areas\n", numgrounded);
- Log_Print("%6d ladder areas\n", numladderareas);
- Log_Print("%6d liquid areas\n", numliquidareas);
-#endif //AASINFO
-} //end of the function AAS_CreateAreaSettings
-//===========================================================================
-// create a tmp AAS area from a leaf node
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-tmp_node_t *AAS_CreateArea(node_t *node)
-{
- int pside;
- int areafaceflags;
- portal_t *p;
- tmp_face_t *tmpface;
- tmp_area_t *tmparea;
- tmp_node_t *tmpnode;
- vec3_t up = {0, 0, 1};
-
- //create an area from this leaf
- tmparea = AAS_AllocTmpArea();
- tmparea->tmpfaces = NULL;
- //clear the area face flags
- areafaceflags = 0;
- //make aas faces from the portals
- for (p = node->portals; p; p = p->next[pside])
- {
- pside = (p->nodes[1] == node);
- //don't create faces from very small portals
-// if (WindingArea(p->winding) < 1) continue;
- //if there's already a face created for this portal
- if (p->tmpface)
- {
- //add the back side of the face to the area
- AAS_AddFaceSideToArea(p->tmpface, 1, tmparea);
- } //end if
- else
- {
- tmpface = AAS_AllocTmpFace();
- //set the face pointer at the portal so we can see from
- //the portal there's a face created for it
- p->tmpface = tmpface;
- //FIXME: test this change
- //tmpface->planenum = (p->planenum & ~1) | pside;
- tmpface->planenum = p->planenum ^ pside;
- if (pside) tmpface->winding = ReverseWinding(p->winding);
- else tmpface->winding = CopyWinding(p->winding);
-#ifdef L_DEBUG
- //
- AAS_CheckFaceWindingPlane(tmpface);
-#endif //L_DEBUG
- //if there's solid at the other side of the portal
- if (p->nodes[!pside]->contents & (CONTENTS_SOLID | CONTENTS_PLAYERCLIP))
- {
- tmpface->faceflags |= FACE_SOLID;
- } //end if
- //else there is no solid at the other side and if there
- //is a liquid at this side
- else if (node->contents & (CONTENTS_WATER|CONTENTS_SLIME|CONTENTS_LAVA))
- {
- tmpface->faceflags |= FACE_LIQUID;
- //if there's no liquid at the other side
- if (!(p->nodes[!pside]->contents & (CONTENTS_WATER|CONTENTS_SLIME|CONTENTS_LAVA)))
- {
- tmpface->faceflags |= FACE_LIQUIDSURFACE;
- } //end if
- } //end else
- //if there's ladder contents at other side of the portal
- if ((p->nodes[pside]->contents & CONTENTS_LADDER) ||
- (p->nodes[!pside]->contents & CONTENTS_LADDER))
- {
-
- //NOTE: doesn't have to be solid at the other side because
- // when standing one can use a crouch area (which is not solid)
- // as a ladder
- // imagine a ladder one can walk underthrough,
- // under the ladder against the ladder is a crouch area
- // the (vertical) sides of this crouch area area also used as
- // ladder sides when standing (not crouched)
- tmpface->faceflags |= FACE_LADDER;
- } //end if
- //if it is possible to stand on the face
- if (AAS_GroundFace(tmpface))
- {
- tmpface->faceflags |= FACE_GROUND;
- } //end if
- //
- areafaceflags |= tmpface->faceflags;
- //no aas face number yet (zero is a dummy in the aasworld faces)
- tmpface->aasfacenum = 0;
- //add the front side of the face to the area
- AAS_AddFaceSideToArea(tmpface, 0, tmparea);
- } //end else
- } //end for
- qprintf("\r%6d", tmparea->areanum);
- //presence type in the area
- tmparea->presencetype = ~node->expansionbboxes & cfg.allpresencetypes;
- //
- tmparea->contents = 0;
- if (node->contents & CONTENTS_CLUSTERPORTAL) tmparea->contents |= AREACONTENTS_CLUSTERPORTAL;
- if (node->contents & CONTENTS_MOVER) tmparea->contents |= AREACONTENTS_MOVER;
- if (node->contents & CONTENTS_TELEPORTER) tmparea->contents |= AREACONTENTS_TELEPORTER;
- if (node->contents & CONTENTS_JUMPPAD) tmparea->contents |= AREACONTENTS_JUMPPAD;
- if (node->contents & CONTENTS_DONOTENTER) tmparea->contents |= AREACONTENTS_DONOTENTER;
- if (node->contents & CONTENTS_WATER) tmparea->contents |= AREACONTENTS_WATER;
- if (node->contents & CONTENTS_LAVA) tmparea->contents |= AREACONTENTS_LAVA;
- if (node->contents & CONTENTS_SLIME) tmparea->contents |= AREACONTENTS_SLIME;
- if (node->contents & CONTENTS_NOTTEAM1) tmparea->contents |= AREACONTENTS_NOTTEAM1;
- if (node->contents & CONTENTS_NOTTEAM2) tmparea->contents |= AREACONTENTS_NOTTEAM2;
-
- //store the bsp model that's inside this node
- tmparea->modelnum = node->modelnum;
- //sorta check for flipped area faces (remove??)
- AAS_FlipAreaFaces(tmparea);
- //check if the area is ok (remove??)
- AAS_CheckArea(tmparea);
- //
- tmpnode = AAS_AllocTmpNode();
- tmpnode->planenum = 0;
- tmpnode->children[0] = 0;
- tmpnode->children[1] = 0;
- tmpnode->tmparea = tmparea;
- //
- return tmpnode;
-} //end of the function AAS_CreateArea
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-tmp_node_t *AAS_CreateAreas_r(node_t *node)
-{
- tmp_node_t *tmpnode;
-
- //recurse down to leafs
- if (node->planenum != PLANENUM_LEAF)
- {
- //the first tmp node is a dummy
- tmpnode = AAS_AllocTmpNode();
- tmpnode->planenum = node->planenum;
- tmpnode->children[0] = AAS_CreateAreas_r(node->children[0]);
- tmpnode->children[1] = AAS_CreateAreas_r(node->children[1]);
- return tmpnode;
- } //end if
- //areas won't be created for solid leafs
- if (node->contents & CONTENTS_SOLID)
- {
- //just return zero for a solid leaf (in tmp AAS NULL is a solid leaf)
- return NULL;
- } //end if
-
- return AAS_CreateArea(node);
-} //end of the function AAS_CreateAreas_r
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_CreateAreas(node_t *node)
-{
- Log_Write("AAS_CreateAreas\r\n");
- qprintf("%6d areas created", 0);
- tmpaasworld.nodes = AAS_CreateAreas_r(node);
- qprintf("\n");
- Log_Write("%6d areas created\r\n", tmpaasworld.numareas);
-} //end of the function AAS_CreateAreas
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_PrintNumGroundFaces(void)
-{
- tmp_face_t *tmpface;
- int numgroundfaces = 0;
-
- for (tmpface = tmpaasworld.faces; tmpface; tmpface = tmpface->l_next)
- {
- if (tmpface->faceflags & FACE_GROUND)
- {
- numgroundfaces++;
- } //end if
- } //end for
- qprintf("%6d ground faces\n", numgroundfaces);
-} //end of the function AAS_PrintNumGroundFaces
-//===========================================================================
-// checks the number of shared faces between the given two areas
-// since areas are convex they should only have ONE shared face
-// however due to crappy face merging there are sometimes several
-// shared faces
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_CheckAreaSharedFaces(tmp_area_t *tmparea1, tmp_area_t *tmparea2)
-{
- int numsharedfaces, side;
- tmp_face_t *face1, *sharedface;
-
- if (tmparea1->invalid || tmparea2->invalid) return;
-
- sharedface = NULL;
- numsharedfaces = 0;
- for (face1 = tmparea1->tmpfaces; face1; face1 = face1->next[side])
- {
- side = face1->frontarea != tmparea1;
- if (face1->backarea == tmparea2 || face1->frontarea == tmparea2)
- {
- sharedface = face1;
- numsharedfaces++;
- } //end if
- } //end if
- if (!sharedface) return;
- //the areas should only have one shared face
- if (numsharedfaces > 1)
- {
- Log_Write("---- tmp area %d and %d have %d shared faces\r\n",
- tmparea1->areanum, tmparea2->areanum, numsharedfaces);
- for (face1 = tmparea1->tmpfaces; face1; face1 = face1->next[side])
- {
- side = face1->frontarea != tmparea1;
- if (face1->backarea == tmparea2 || face1->frontarea == tmparea2)
- {
- Log_Write("face %d, planenum = %d, face->frontarea = %d face->backarea = %d\r\n",
- face1->num, face1->planenum, face1->frontarea->areanum, face1->backarea->areanum);
- } //end if
- } //end if
- } //end if
-} //end of the function AAS_CheckAreaSharedFaces
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_CheckSharedFaces(void)
-{
- tmp_area_t *tmparea1, *tmparea2;
-
- for (tmparea1 = tmpaasworld.areas; tmparea1; tmparea1 = tmparea1->l_next)
- {
- for (tmparea2 = tmpaasworld.areas; tmparea2; tmparea2 = tmparea2->l_next)
- {
- if (tmparea1 == tmparea2) continue;
- AAS_CheckAreaSharedFaces(tmparea1, tmparea2);
- } //end for
- } //end for
-} //end of the function AAS_CheckSharedFaces
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_FlipFace(tmp_face_t *face)
-{
- tmp_area_t *frontarea, *backarea;
- winding_t *w;
-
- frontarea = face->frontarea;
- backarea = face->backarea;
- //must have an area at both sides before flipping is allowed
- if (!frontarea || !backarea) return;
- //flip the face winding
- w = face->winding;
- face->winding = ReverseWinding(w);
- FreeWinding(w);
- //flip the face plane
- face->planenum ^= 1;
- //flip the face areas
- AAS_RemoveFaceFromArea(face, frontarea);
- AAS_RemoveFaceFromArea(face, backarea);
- AAS_AddFaceSideToArea(face, 1, frontarea);
- AAS_AddFaceSideToArea(face, 0, backarea);
-} //end of the function AAS_FlipFace
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-/*
-void AAS_FlipAreaSharedFaces(tmp_area_t *tmparea1, tmp_area_t *tmparea2)
-{
- int numsharedfaces, side, area1facing, area2facing;
- tmp_face_t *face1, *sharedface;
-
- if (tmparea1->invalid || tmparea2->invalid) return;
-
- sharedface = NULL;
- numsharedfaces = 0;
- area1facing = 0; //number of shared faces facing towards area 1
- area2facing = 0; //number of shared faces facing towards area 2
- for (face1 = tmparea1->tmpfaces; face1; face1 = face1->next[side])
- {
- side = face1->frontarea != tmparea1;
- if (face1->backarea == tmparea2 || face1->frontarea == tmparea2)
- {
- sharedface = face1;
- numsharedfaces++;
- if (face1->frontarea == tmparea1) area1facing++;
- else area2facing++;
- } //end if
- } //end if
- if (!sharedface) return;
- //if there's only one shared face
- if (numsharedfaces <= 1) return;
- //if all the shared faces are facing to the same area
- if (numsharedfaces == area1facing || numsharedfaces == area2facing) return;
- //
- do
- {
- for (face1 = tmparea1->tmpfaces; face1; face1 = face1->next[side])
- {
- side = face1->frontarea != tmparea1;
- if (face1->backarea == tmparea2 || face1->frontarea == tmparea2)
- {
- if (face1->frontarea != tmparea1)
- {
- AAS_FlipFace(face1);
- break;
- } //end if
- } //end if
- } //end for
- } while(face1);
-} //end of the function AAS_FlipAreaSharedFaces
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_FlipSharedFaces(void)
-{
- int i;
- tmp_area_t *tmparea1, *tmparea2;
-
- i = 0;
- qprintf("%6d areas checked for shared face flipping", i);
- for (tmparea1 = tmpaasworld.areas; tmparea1; tmparea1 = tmparea1->l_next)
- {
- if (tmparea1->invalid) continue;
- for (tmparea2 = tmpaasworld.areas; tmparea2; tmparea2 = tmparea2->l_next)
- {
- if (tmparea2->invalid) continue;
- if (tmparea1 == tmparea2) continue;
- AAS_FlipAreaSharedFaces(tmparea1, tmparea2);
- } //end for
- qprintf("\r%6d", ++i);
- } //end for
- Log_Print("\r%6d areas checked for shared face flipping\n", i);
-} //end of the function AAS_FlipSharedFaces
-*/
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_FlipSharedFaces(void)
-{
- int i, side1, side2;
- tmp_area_t *tmparea1;
- tmp_face_t *face1, *face2;
-
- i = 0;
- qprintf("%6d areas checked for shared face flipping", i);
- for (tmparea1 = tmpaasworld.areas; tmparea1; tmparea1 = tmparea1->l_next)
- {
- if (tmparea1->invalid) continue;
- for (face1 = tmparea1->tmpfaces; face1; face1 = face1->next[side1])
- {
- side1 = face1->frontarea != tmparea1;
- if (!face1->frontarea || !face1->backarea) continue;
- //
- for (face2 = face1->next[side1]; face2; face2 = face2->next[side2])
- {
- side2 = face2->frontarea != tmparea1;
- if (!face2->frontarea || !face2->backarea) continue;
- //
- if (face1->frontarea == face2->backarea &&
- face1->backarea == face2->frontarea)
- {
- AAS_FlipFace(face2);
- } //end if
- //recheck side
- side2 = face2->frontarea != tmparea1;
- } //end for
- } //end for
- qprintf("\r%6d", ++i);
- } //end for
- qprintf("\n");
- Log_Write("%6d areas checked for shared face flipping\r\n", i);
-} //end of the function AAS_FlipSharedFaces
-//===========================================================================
-// creates an .AAS file with the given name
-// a MAP should be loaded before calling this
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_Create(char *aasfile)
-{
- entity_t *e;
- tree_t *tree;
- double start_time;
-
- //for a possible leak file
- strcpy(source, aasfile);
- StripExtension(source);
- //the time started
- start_time = I_FloatTime();
- //set the default number of threads (depends on number of processors)
- ThreadSetDefault();
- //set the global entity number to the world model
- entity_num = 0;
- //the world entity
- e = &entities[entity_num];
- //process the whole world
- tree = ProcessWorldBrushes(e->firstbrush, e->firstbrush + e->numbrushes);
- //if the conversion is cancelled
- if (cancelconversion)
- {
- Tree_Free(tree);
- return;
- } //end if
- //display BSP tree creation time
- Log_Print("BSP tree created in %5.0f seconds\n", I_FloatTime() - start_time);
- //prune the bsp tree
- Tree_PruneNodes(tree->headnode);
- //if the conversion is cancelled
- if (cancelconversion)
- {
- Tree_Free(tree);
- return;
- } //end if
- //create the tree portals
- MakeTreePortals(tree);
- //if the conversion is cancelled
- if (cancelconversion)
- {
- Tree_Free(tree);
- return;
- } //end if
- //Marks all nodes that can be reached by entites
- if (FloodEntities(tree))
- {
- //fill out nodes that can't be reached
- FillOutside(tree->headnode);
- } //end if
- else
- {
- LeakFile(tree);
- Error("**** leaked ****\n");
- return;
- } //end else
- //create AAS from the BSP tree
- //==========================================
- //initialize tmp aas
- AAS_InitTmpAAS();
- //create the convex areas from the leaves
- AAS_CreateAreas(tree->headnode);
- //free the BSP tree because it isn't used anymore
- if (freetree) Tree_Free(tree);
- //try to merge area faces
- AAS_MergeAreaFaces();
- //do gravitational subdivision
- AAS_GravitationalSubdivision();
- //merge faces if possible
- AAS_MergeAreaFaces();
- AAS_RemoveAreaFaceColinearPoints();
- //merge areas if possible
- AAS_MergeAreas();
- //NOTE: prune nodes directly after area merging
- AAS_PruneNodes();
- //flip shared faces so they are all facing to the same area
- AAS_FlipSharedFaces();
- AAS_RemoveAreaFaceColinearPoints();
- //merge faces if possible
- AAS_MergeAreaFaces();
- //merge area faces in the same plane
- AAS_MergeAreaPlaneFaces();
- //do ladder subdivision
- AAS_LadderSubdivision();
- //FIXME: melting is buggy
- AAS_MeltAreaFaceWindings();
- //remove tiny faces
- AAS_RemoveTinyFaces();
- //create area settings
- AAS_CreateAreaSettings();
- //check if the winding plane is equal to the face plane
- //AAS_CheckAreaWindingPlanes();
- //
- //AAS_CheckSharedFaces();
- //==========================================
- //if the conversion is cancelled
- if (cancelconversion)
- {
- Tree_Free(tree);
- AAS_FreeTmpAAS();
- return;
- } //end if
- //store the created AAS stuff in the AAS file format and write the file
- AAS_StoreFile(aasfile);
- //free the temporary AAS memory
- AAS_FreeTmpAAS();
- //display creation time
- Log_Print("\nAAS created in %5.0f seconds\n", I_FloatTime() - start_time);
-} //end of the function AAS_Create
diff --git a/code/bspc/aas_create.h b/code/bspc/aas_create.h
deleted file mode 100644
index f80a9ae..0000000
--- a/code/bspc/aas_create.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-#define AREA_PORTAL 1
-
-//temporary AAS face
-typedef struct tmp_face_s
-{
- int num; //face number
- int planenum; //number of the plane the face is in
- winding_t *winding; //winding of the face
- struct tmp_area_s *frontarea; //area at the front of the face
- struct tmp_area_s *backarea; //area at the back of the face
- int faceflags; //flags of this face
- int aasfacenum; //the number of the aas face used for this face
- //double link list pointers for front and back area
- struct tmp_face_s *prev[2], *next[2];
- //links in the list with faces
- struct tmp_face_s *l_prev, *l_next;
-} tmp_face_t;
-
-//temporary AAS area settings
-typedef struct tmp_areasettings_s
-{
- //could also add all kind of statistic fields
- int contents; //contents of the area
- int modelnum; //bsp model inside this area
- int areaflags; //area flags
- int presencetype; //how a bot can be present in this area
- int numreachableareas; //number of reachable areas from this one
- int firstreachablearea; //first reachable area in the reachable area index
-} tmp_areasettings_t;
-
-//temporary AAS area
-typedef struct tmp_area_s
-{
- int areanum; //number of the area
- struct tmp_face_s *tmpfaces; //the faces of the area
- int presencetype; //presence type of the area
- int contents; //area contents
- int modelnum; //bsp model inside this area
- int invalid; //true if the area is invalid
- tmp_areasettings_t *settings; //area settings
- struct tmp_area_s *mergedarea; //points to the new area after merging
- //when mergedarea != 0 the area has only the
- //seperating face of the merged areas
- int aasareanum; //number of the aas area created for this tmp area
- //links in the list with areas
- struct tmp_area_s *l_prev, *l_next;
-} tmp_area_t;
-
-//temporary AAS node
-typedef struct tmp_node_s
-{
- int planenum; //node plane number
- struct tmp_area_s *tmparea; //points to an area if this node is an area
- struct tmp_node_s *children[2]; //child nodes of this node
-} tmp_node_t;
-
-#define NODEBUF_SIZE 128
-//node buffer
-typedef struct tmp_nodebuf_s
-{
- int numnodes;
- struct tmp_nodebuf_s *next;
- tmp_node_t nodes[NODEBUF_SIZE];
-} tmp_nodebuf_t;
-
-//the whole temorary AAS
-typedef struct tmp_aas_s
-{
- //faces
- int numfaces;
- int facenum;
- tmp_face_t *faces;
- //areas
- int numareas;
- int areanum;
- tmp_area_t *areas;
- //area settings
- int numareasettings;
- tmp_areasettings_t *areasettings;
- //nodes
- int numnodes;
- tmp_node_t *nodes;
- //node buffer
- tmp_nodebuf_t *nodebuffer;
-} tmp_aas_t;
-
-extern tmp_aas_t tmpaasworld;
-
-//creates a .AAS file with the given name from an already loaded map
-void AAS_Create(char *aasfile);
-//adds a face side to an area
-void AAS_AddFaceSideToArea(tmp_face_t *tmpface, int side, tmp_area_t *tmparea);
-//remvoes a face from an area
-void AAS_RemoveFaceFromArea(tmp_face_t *tmpface, tmp_area_t *tmparea);
-//allocate a tmp face
-tmp_face_t *AAS_AllocTmpFace(void);
-//free the tmp face
-void AAS_FreeTmpFace(tmp_face_t *tmpface);
-//allocate a tmp area
-tmp_area_t *AAS_AllocTmpArea(void);
-//free a tmp area
-void AAS_FreeTmpArea(tmp_area_t *tmparea);
-//allocate a tmp node
-tmp_node_t *AAS_AllocTmpNode(void);
-//free a tmp node
-void AAS_FreeTmpNode(tmp_node_t *node);
-//checks if an area is ok
-void AAS_CheckArea(tmp_area_t *tmparea);
-//flips the area faces where needed
-void AAS_FlipAreaFaces(tmp_area_t *tmparea);
-//returns true if the face is a gap seen from the given side
-int AAS_GapFace(tmp_face_t *tmpface, int side);
-//returns true if the face is a ground face
-int AAS_GroundFace(tmp_face_t *tmpface);
diff --git a/code/bspc/aas_edgemelting.c b/code/bspc/aas_edgemelting.c
deleted file mode 100644
index 201dfe2..0000000
--- a/code/bspc/aas_edgemelting.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-#include "qbsp.h"
-#include "../botlib/aasfile.h"
-#include "aas_create.h"
-
-//===========================================================================
-// try to melt the windings of the two faces
-// FIXME: this is buggy
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int AAS_MeltFaceWinding(tmp_face_t *face1, tmp_face_t *face2)
-{
- int i, n;
- int splits = 0;
- winding_t *w2, *neww;
- plane_t *plane1;
-
-#ifdef DEBUG
- if (!face1->winding) Error("face1 %d without winding", face1->num);
- if (!face2->winding) Error("face2 %d without winding", face2->num);
-#endif //DEBUG
- w2 = face2->winding;
- plane1 = &mapplanes[face1->planenum];
- for (i = 0; i < w2->numpoints; i++)
- {
- if (PointOnWinding(face1->winding, plane1->normal, plane1->dist, w2->p[i], &n))
- {
- neww = AddWindingPoint(face1->winding, w2->p[i], n);
- FreeWinding(face1->winding);
- face1->winding = neww;
-
- splits++;
- } //end if
- } //end for
- return splits;
-} //end of the function AAS_MeltFaceWinding
-//===========================================================================
-// melt the windings of the area faces
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int AAS_MeltFaceWindingsOfArea(tmp_area_t *tmparea)
-{
- int side1, side2, num_windingsplits = 0;
- tmp_face_t *face1, *face2;
-
- for (face1 = tmparea->tmpfaces; face1; face1 = face1->next[side1])
- {
- side1 = face1->frontarea != tmparea;
- for (face2 = tmparea->tmpfaces; face2; face2 = face2->next[side2])
- {
- side2 = face2->frontarea != tmparea;
- if (face1 == face2) continue;
- num_windingsplits += AAS_MeltFaceWinding(face1, face2);
- } //end for
- } //end for
- return num_windingsplits;
-} //end of the function AAS_MeltFaceWindingsOfArea
-//===========================================================================
-// melt the windings of the faces of all areas
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_MeltAreaFaceWindings(void)
-{
- tmp_area_t *tmparea;
- int num_windingsplits = 0;
-
- Log_Write("AAS_MeltAreaFaceWindings\r\n");
- qprintf("%6d edges melted", num_windingsplits);
- //NOTE: first convex area (zero) is a dummy
- for (tmparea = tmpaasworld.areas; tmparea; tmparea = tmparea->l_next)
- {
- num_windingsplits += AAS_MeltFaceWindingsOfArea(tmparea);
- qprintf("\r%6d", num_windingsplits);
- } //end for
- qprintf("\n");
- Log_Write("%6d edges melted\r\n", num_windingsplits);
-} //end of the function AAS_MeltAreaFaceWindings
-
diff --git a/code/bspc/aas_edgemelting.h b/code/bspc/aas_edgemelting.h
deleted file mode 100644
index 4397969..0000000
--- a/code/bspc/aas_edgemelting.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-void AAS_MeltAreaFaceWindings(void);
-
diff --git a/code/bspc/aas_facemerging.c b/code/bspc/aas_facemerging.c
deleted file mode 100644
index ea20ffd..0000000
--- a/code/bspc/aas_facemerging.c
+++ /dev/null
@@ -1,282 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-#include "qbsp.h"
-#include "../botlib/aasfile.h"
-#include "aas_create.h"
-
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int AAS_TryMergeFaces(tmp_face_t *face1, tmp_face_t *face2)
-{
- winding_t *neww;
-
-#ifdef DEBUG
- if (!face1->winding) Error("face1 %d without winding", face1->num);
- if (!face2->winding) Error("face2 %d without winding", face2->num);
-#endif //DEBUG
- //
- if (face1->faceflags != face2->faceflags) return false;
- //NOTE: if the front or back area is zero this doesn't mean there's
- //a real area. It means there's solid at that side of the face
- //if both faces have the same front area
- if (face1->frontarea == face2->frontarea)
- {
- //if both faces have the same back area
- if (face1->backarea == face2->backarea)
- {
- //if the faces are in the same plane
- if (face1->planenum == face2->planenum)
- {
- //if they have both a front and a back area (no solid on either side)
- if (face1->frontarea && face1->backarea)
- {
- neww = MergeWindings(face1->winding, face2->winding,
- mapplanes[face1->planenum].normal);
- } //end if
- else
- {
- //this function is to be found in l_poly.c
- neww = TryMergeWinding(face1->winding, face2->winding,
- mapplanes[face1->planenum].normal);
- } //end else
- if (neww)
- {
- FreeWinding(face1->winding);
- face1->winding = neww;
- if (face2->frontarea) AAS_RemoveFaceFromArea(face2, face2->frontarea);
- if (face2->backarea) AAS_RemoveFaceFromArea(face2, face2->backarea);
- AAS_FreeTmpFace(face2);
- return true;
- } //end if
- } //end if
- else if ((face1->planenum & ~1) == (face2->planenum & ~1))
- {
- Log_Write("face %d and %d, same front and back area but flipped planes\r\n",
- face1->num, face2->num);
- } //end if
- } //end if
- } //end if
- return false;
-} //end of the function AAS_TryMergeFaces
-/*
-int AAS_TryMergeFaces(tmp_face_t *face1, tmp_face_t *face2)
-{
- winding_t *neww;
-
-#ifdef DEBUG
- if (!face1->winding) Error("face1 %d without winding", face1->num);
- if (!face2->winding) Error("face2 %d without winding", face2->num);
-#endif //DEBUG
- //if the faces are in the same plane
- if ((face1->planenum & ~1) != (face2->planenum & ~1)) return false;
-// if (face1->planenum != face2->planenum) return false;
- //NOTE: if the front or back area is zero this doesn't mean there's
- //a real area. It means there's solid at that side of the face
- //if both faces have the same front area
- if (face1->frontarea != face2->frontarea ||
- face1->backarea != face2->backarea)
- {
- if (!face1->frontarea || !face1->backarea ||
- !face2->frontarea || !face2->backarea) return false;
- else if (face1->frontarea != face2->backarea ||
- face1->backarea != face2->frontarea) return false;
-// return false;
- } //end if
- //this function is to be found in l_poly.c
- neww = TryMergeWinding(face1->winding, face2->winding,
- mapplanes[face1->planenum].normal);
- if (!neww) return false;
- //
- FreeWinding(face1->winding);
- face1->winding = neww;
- //remove face2
- if (face2->frontarea)
- AAS_RemoveFaceFromArea(face2, &tmpaasworld.areas[face2->frontarea]);
- if (face2->backarea)
- AAS_RemoveFaceFromArea(face2, &tmpaasworld.areas[face2->backarea]);
- return true;
-} //end of the function AAS_TryMergeFaces*/
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_MergeAreaFaces(void)
-{
- int num_facemerges = 0;
- int side1, side2, restart;
- tmp_area_t *tmparea, *lasttmparea;
- tmp_face_t *face1, *face2;
-
- Log_Write("AAS_MergeAreaFaces\r\n");
- qprintf("%6d face merges", num_facemerges);
- //NOTE: first convex area is a dummy
- lasttmparea = tmpaasworld.areas;
- for (tmparea = tmpaasworld.areas; tmparea; tmparea = tmparea->l_next)
- {
- restart = false;
- //
- if (tmparea->invalid) continue;
- //
- for (face1 = tmparea->tmpfaces; face1; face1 = face1->next[side1])
- {
- side1 = face1->frontarea != tmparea;
- for (face2 = face1->next[side1]; face2; face2 = face2->next[side2])
- {
- side2 = face2->frontarea != tmparea;
- //if succesfully merged
- if (AAS_TryMergeFaces(face1, face2))
- {
- //start over again after merging two faces
- restart = true;
- num_facemerges++;
- qprintf("\r%6d", num_facemerges);
- AAS_CheckArea(tmparea);
- break;
- } //end if
- } //end for
- if (restart)
- {
- tmparea = lasttmparea;
- break;
- } //end if
- } //end for
- lasttmparea = tmparea;
- } //end for
- qprintf("\n");
- Log_Write("%6d face merges\r\n", num_facemerges);
-} //end of the function AAS_MergeAreaFaces
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_MergePlaneFaces(tmp_area_t *tmparea, int planenum)
-{
- tmp_face_t *face1, *face2, *nextface2;
- winding_t *neww;
- int side1, side2;
-
- for (face1 = tmparea->tmpfaces; face1; face1 = face1->next[side1])
- {
- side1 = face1->frontarea != tmparea;
- if (face1->planenum != planenum) continue;
- //
- for (face2 = face1->next[side1]; face2; face2 = nextface2)
- {
- side2 = face2->frontarea != tmparea;
- nextface2 = face2->next[side2];
- //
- if ((face2->planenum & ~1) != (planenum & ~1)) continue;
- //
- neww = MergeWindings(face1->winding, face2->winding,
- mapplanes[face1->planenum].normal);
- FreeWinding(face1->winding);
- face1->winding = neww;
- if (face2->frontarea) AAS_RemoveFaceFromArea(face2, face2->frontarea);
- if (face2->backarea) AAS_RemoveFaceFromArea(face2, face2->backarea);
- AAS_FreeTmpFace(face2);
- //
- nextface2 = face1->next[side1];
- } //end for
- } //end for
-} //end of the function AAS_MergePlaneFaces
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int AAS_CanMergePlaneFaces(tmp_area_t *tmparea, int planenum)
-{
- tmp_area_t *frontarea, *backarea;
- tmp_face_t *face1;
- int side1, merge, faceflags;
-
- frontarea = backarea = NULL;
- merge = false;
- for (face1 = tmparea->tmpfaces; face1; face1 = face1->next[side1])
- {
- side1 = face1->frontarea != tmparea;
- if ((face1->planenum & ~1) != (planenum & ~1)) continue;
- if (!frontarea && !backarea)
- {
- frontarea = face1->frontarea;
- backarea = face1->backarea;
- faceflags = face1->faceflags;
- } //end if
- else
- {
- if (frontarea != face1->frontarea) return false;
- if (backarea != face1->backarea) return false;
- if (faceflags != face1->faceflags) return false;
- merge = true;
- } //end else
- } //end for
- return merge;
-} //end of the function AAS_CanMergePlaneFaces
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_MergeAreaPlaneFaces(void)
-{
- int num_facemerges = 0;
- int side1;
- tmp_area_t *tmparea, *nexttmparea;
- tmp_face_t *face1;
-
- Log_Write("AAS_MergePlaneFaces\r\n");
- qprintf("%6d plane face merges", num_facemerges);
- //NOTE: first convex area is a dummy
- for (tmparea = tmpaasworld.areas; tmparea; tmparea = nexttmparea)
- {
- nexttmparea = tmparea->l_next;
- //
- if (tmparea->invalid) continue;
- //
- for (face1 = tmparea->tmpfaces; face1; face1 = face1->next[side1])
- {
- side1 = face1->frontarea != tmparea;
- //
- if (AAS_CanMergePlaneFaces(tmparea, face1->planenum))
- {
- AAS_MergePlaneFaces(tmparea, face1->planenum);
- nexttmparea = tmparea;
- num_facemerges++;
- qprintf("\r%6d", num_facemerges);
- break;
- } //end if
- } //end for
- } //end for
- qprintf("\n");
- Log_Write("%6d plane face merges\r\n", num_facemerges);
-} //end of the function AAS_MergeAreaPlaneFaces
diff --git a/code/bspc/aas_facemerging.h b/code/bspc/aas_facemerging.h
deleted file mode 100644
index f8d1a3e..0000000
--- a/code/bspc/aas_facemerging.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-void AAS_MergeAreaFaces(void);
-void AAS_MergeAreaPlaneFaces(void);
diff --git a/code/bspc/aas_file.c b/code/bspc/aas_file.c
deleted file mode 100644
index 0761206..0000000
--- a/code/bspc/aas_file.c
+++ /dev/null
@@ -1,549 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-#include "qbsp.h"
-#include "../botlib/aasfile.h"
-#include "aas_file.h"
-#include "aas_store.h"
-#include "aas_create.h"
-
-#define AAS_Error Error
-
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_SwapAASData(void)
-{
- int i, j;
- //bounding boxes
- for (i = 0; i < aasworld.numbboxes; i++)
- {
- aasworld.bboxes[i].presencetype = LittleLong(aasworld.bboxes[i].presencetype);
- aasworld.bboxes[i].flags = LittleLong(aasworld.bboxes[i].flags);
- for (j = 0; j < 3; j++)
- {
- aasworld.bboxes[i].mins[j] = LittleLong(aasworld.bboxes[i].mins[j]);
- aasworld.bboxes[i].maxs[j] = LittleLong(aasworld.bboxes[i].maxs[j]);
- } //end for
- } //end for
- //vertexes
- for (i = 0; i < aasworld.numvertexes; i++)
- {
- for (j = 0; j < 3; j++)
- aasworld.vertexes[i][j] = LittleFloat(aasworld.vertexes[i][j]);
- } //end for
- //planes
- for (i = 0; i < aasworld.numplanes; i++)
- {
- for (j = 0; j < 3; j++)
- aasworld.planes[i].normal[j] = LittleFloat(aasworld.planes[i].normal[j]);
- aasworld.planes[i].dist = LittleFloat(aasworld.planes[i].dist);
- aasworld.planes[i].type = LittleLong(aasworld.planes[i].type);
- } //end for
- //edges
- for (i = 0; i < aasworld.numedges; i++)
- {
- aasworld.edges[i].v[0] = LittleLong(aasworld.edges[i].v[0]);
- aasworld.edges[i].v[1] = LittleLong(aasworld.edges[i].v[1]);
- } //end for
- //edgeindex
- for (i = 0; i < aasworld.edgeindexsize; i++)
- {
- aasworld.edgeindex[i] = LittleLong(aasworld.edgeindex[i]);
- } //end for
- //faces
- for (i = 0; i < aasworld.numfaces; i++)
- {
- aasworld.faces[i].planenum = LittleLong(aasworld.faces[i].planenum);
- aasworld.faces[i].faceflags = LittleLong(aasworld.faces[i].faceflags);
- aasworld.faces[i].numedges = LittleLong(aasworld.faces[i].numedges);
- aasworld.faces[i].firstedge = LittleLong(aasworld.faces[i].firstedge);
- aasworld.faces[i].frontarea = LittleLong(aasworld.faces[i].frontarea);
- aasworld.faces[i].backarea = LittleLong(aasworld.faces[i].backarea);
- } //end for
- //face index
- for (i = 0; i < aasworld.faceindexsize; i++)
- {
- aasworld.faceindex[i] = LittleLong(aasworld.faceindex[i]);
- } //end for
- //convex areas
- for (i = 0; i < aasworld.numareas; i++)
- {
- aasworld.areas[i].areanum = LittleLong(aasworld.areas[i].areanum);
- aasworld.areas[i].numfaces = LittleLong(aasworld.areas[i].numfaces);
- aasworld.areas[i].firstface = LittleLong(aasworld.areas[i].firstface);
- for (j = 0; j < 3; j++)
- {
- aasworld.areas[i].mins[j] = LittleFloat(aasworld.areas[i].mins[j]);
- aasworld.areas[i].maxs[j] = LittleFloat(aasworld.areas[i].maxs[j]);
- aasworld.areas[i].center[j] = LittleFloat(aasworld.areas[i].center[j]);
- } //end for
- } //end for
- //area settings
- for (i = 0; i < aasworld.numareasettings; i++)
- {
- aasworld.areasettings[i].contents = LittleLong(aasworld.areasettings[i].contents);
- aasworld.areasettings[i].areaflags = LittleLong(aasworld.areasettings[i].areaflags);
- aasworld.areasettings[i].presencetype = LittleLong(aasworld.areasettings[i].presencetype);
- aasworld.areasettings[i].cluster = LittleLong(aasworld.areasettings[i].cluster);
- aasworld.areasettings[i].clusterareanum = LittleLong(aasworld.areasettings[i].clusterareanum);
- aasworld.areasettings[i].numreachableareas = LittleLong(aasworld.areasettings[i].numreachableareas);
- aasworld.areasettings[i].firstreachablearea = LittleLong(aasworld.areasettings[i].firstreachablearea);
- } //end for
- //area reachability
- for (i = 0; i < aasworld.reachabilitysize; i++)
- {
- aasworld.reachability[i].areanum = LittleLong(aasworld.reachability[i].areanum);
- aasworld.reachability[i].facenum = LittleLong(aasworld.reachability[i].facenum);
- aasworld.reachability[i].edgenum = LittleLong(aasworld.reachability[i].edgenum);
- for (j = 0; j < 3; j++)
- {
- aasworld.reachability[i].start[j] = LittleFloat(aasworld.reachability[i].start[j]);
- aasworld.reachability[i].end[j] = LittleFloat(aasworld.reachability[i].end[j]);
- } //end for
- aasworld.reachability[i].traveltype = LittleLong(aasworld.reachability[i].traveltype);
- aasworld.reachability[i].traveltime = LittleShort(aasworld.reachability[i].traveltime);
- } //end for
- //nodes
- for (i = 0; i < aasworld.numnodes; i++)
- {
- aasworld.nodes[i].planenum = LittleLong(aasworld.nodes[i].planenum);
- aasworld.nodes[i].children[0] = LittleLong(aasworld.nodes[i].children[0]);
- aasworld.nodes[i].children[1] = LittleLong(aasworld.nodes[i].children[1]);
- } //end for
- //cluster portals
- for (i = 0; i < aasworld.numportals; i++)
- {
- aasworld.portals[i].areanum = LittleLong(aasworld.portals[i].areanum);
- aasworld.portals[i].frontcluster = LittleLong(aasworld.portals[i].frontcluster);
- aasworld.portals[i].backcluster = LittleLong(aasworld.portals[i].backcluster);
- aasworld.portals[i].clusterareanum[0] = LittleLong(aasworld.portals[i].clusterareanum[0]);
- aasworld.portals[i].clusterareanum[1] = LittleLong(aasworld.portals[i].clusterareanum[1]);
- } //end for
- //cluster portal index
- for (i = 0; i < aasworld.portalindexsize; i++)
- {
- aasworld.portalindex[i] = LittleLong(aasworld.portalindex[i]);
- } //end for
- //cluster
- for (i = 0; i < aasworld.numclusters; i++)
- {
- aasworld.clusters[i].numareas = LittleLong(aasworld.clusters[i].numareas);
- aasworld.clusters[i].numportals = LittleLong(aasworld.clusters[i].numportals);
- aasworld.clusters[i].firstportal = LittleLong(aasworld.clusters[i].firstportal);
- } //end for
-} //end of the function AAS_SwapAASData
-//===========================================================================
-// dump the current loaded aas file
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_DumpAASData(void)
-{
- /*
- if (aasworld.vertexes) FreeMemory(aasworld.vertexes);
- aasworld.vertexes = NULL;
- if (aasworld.planes) FreeMemory(aasworld.planes);
- aasworld.planes = NULL;
- if (aasworld.edges) FreeMemory(aasworld.edges);
- aasworld.edges = NULL;
- if (aasworld.edgeindex) FreeMemory(aasworld.edgeindex);
- aasworld.edgeindex = NULL;
- if (aasworld.faces) FreeMemory(aasworld.faces);
- aasworld.faces = NULL;
- if (aasworld.faceindex) FreeMemory(aasworld.faceindex);
- aasworld.faceindex = NULL;
- if (aasworld.areas) FreeMemory(aasworld.areas);
- aasworld.areas = NULL;
- if (aasworld.areasettings) FreeMemory(aasworld.areasettings);
- aasworld.areasettings = NULL;
- if (aasworld.reachability) FreeMemory(aasworld.reachability);
- aasworld.reachability = NULL;
- */
- aasworld.loaded = false;
-} //end of the function AAS_DumpAASData
-//===========================================================================
-// allocate memory and read a lump of a AAS file
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-char *AAS_LoadAASLump(FILE *fp, int offset, int length, void *buf)
-{
- if (!length)
- {
- printf("lump size 0\n");
- return buf;
- } //end if
- //seek to the data
- if (fseek(fp, offset, SEEK_SET))
- {
- AAS_Error("can't seek to lump\n");
- AAS_DumpAASData();
- fclose(fp);
- return 0;
- } //end if
- //allocate memory
- if (!buf) buf = (void *) GetClearedMemory(length);
- //read the data
- if (fread((char *) buf, 1, length, fp) != length)
- {
- AAS_Error("can't read lump\n");
- FreeMemory(buf);
- AAS_DumpAASData();
- fclose(fp);
- return NULL;
- } //end if
- return buf;
-} //end of the function AAS_LoadAASLump
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_DData(unsigned char *data, int size)
-{
- int i;
-
- for (i = 0; i < size; i++)
- {
- data[i] ^= (unsigned char) i * 119;
- } //end for
-} //end of the function AAS_DData
-//===========================================================================
-// load an aas file
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-qboolean AAS_LoadAASFile(char *filename, int fpoffset, int fplength)
-{
- FILE *fp;
- aas_header_t header;
- int offset, length;
-
- //dump current loaded aas file
- AAS_DumpAASData();
- //open the file
- fp = fopen(filename, "rb");
- if (!fp)
- {
- AAS_Error("can't open %s\n", filename);
- return false;
- } //end if
- //seek to the correct position (in the pak file)
- if (fseek(fp, fpoffset, SEEK_SET))
- {
- AAS_Error("can't seek to file %s\n");
- fclose(fp);
- return false;
- } //end if
- //read the header
- if (fread(&header, sizeof(aas_header_t), 1, fp) != 1)
- {
- AAS_Error("can't read header of file %s\n", filename);
- fclose(fp);
- return false;
- } //end if
- //check header identification
- header.ident = LittleLong(header.ident);
- if (header.ident != AASID)
- {
- AAS_Error("%s is not an AAS file\n", filename);
- fclose(fp);
- return false;
- } //end if
- //check the version
- header.version = LittleLong(header.version);
- if (header.version != AASVERSION_OLD && header.version != AASVERSION)
- {
- AAS_Error("%s is version %i, not %i\n", filename, header.version, AASVERSION);
- fclose(fp);
- return false;
- } //end if
- //
- if (header.version == AASVERSION)
- {
- AAS_DData((unsigned char *) &header + 8, sizeof(aas_header_t) - 8);
- } //end if
- aasworld.bspchecksum = LittleLong(header.bspchecksum);
- //load the lumps:
- //bounding boxes
- offset = fpoffset + LittleLong(header.lumps[AASLUMP_BBOXES].fileofs);
- length = LittleLong(header.lumps[AASLUMP_BBOXES].filelen);
- aasworld.bboxes = (aas_bbox_t *) AAS_LoadAASLump(fp, offset, length, aasworld.bboxes);
- if (!aasworld.bboxes) return false;
- aasworld.numbboxes = length / sizeof(aas_bbox_t);
- //vertexes
- offset = fpoffset + LittleLong(header.lumps[AASLUMP_VERTEXES].fileofs);
- length = LittleLong(header.lumps[AASLUMP_VERTEXES].filelen);
- aasworld.vertexes = (aas_vertex_t *) AAS_LoadAASLump(fp, offset, length, aasworld.vertexes);
- if (!aasworld.vertexes) return false;
- aasworld.numvertexes = length / sizeof(aas_vertex_t);
- //planes
- offset = fpoffset + LittleLong(header.lumps[AASLUMP_PLANES].fileofs);
- length = LittleLong(header.lumps[AASLUMP_PLANES].filelen);
- aasworld.planes = (aas_plane_t *) AAS_LoadAASLump(fp, offset, length, aasworld.planes);
- if (!aasworld.planes) return false;
- aasworld.numplanes = length / sizeof(aas_plane_t);
- //edges
- offset = fpoffset + LittleLong(header.lumps[AASLUMP_EDGES].fileofs);
- length = LittleLong(header.lumps[AASLUMP_EDGES].filelen);
- aasworld.edges = (aas_edge_t *) AAS_LoadAASLump(fp, offset, length, aasworld.edges);
- if (!aasworld.edges) return false;
- aasworld.numedges = length / sizeof(aas_edge_t);
- //edgeindex
- offset = fpoffset + LittleLong(header.lumps[AASLUMP_EDGEINDEX].fileofs);
- length = LittleLong(header.lumps[AASLUMP_EDGEINDEX].filelen);
- aasworld.edgeindex = (aas_edgeindex_t *) AAS_LoadAASLump(fp, offset, length, aasworld.edgeindex);
- if (!aasworld.edgeindex) return false;
- aasworld.edgeindexsize = length / sizeof(aas_edgeindex_t);
- //faces
- offset = fpoffset + LittleLong(header.lumps[AASLUMP_FACES].fileofs);
- length = LittleLong(header.lumps[AASLUMP_FACES].filelen);
- aasworld.faces = (aas_face_t *) AAS_LoadAASLump(fp, offset, length, aasworld.faces);
- if (!aasworld.faces) return false;
- aasworld.numfaces = length / sizeof(aas_face_t);
- //faceindex
- offset = fpoffset + LittleLong(header.lumps[AASLUMP_FACEINDEX].fileofs);
- length = LittleLong(header.lumps[AASLUMP_FACEINDEX].filelen);
- aasworld.faceindex = (aas_faceindex_t *) AAS_LoadAASLump(fp, offset, length, aasworld.faceindex);
- if (!aasworld.faceindex) return false;
- aasworld.faceindexsize = length / sizeof(int);
- //convex areas
- offset = fpoffset + LittleLong(header.lumps[AASLUMP_AREAS].fileofs);
- length = LittleLong(header.lumps[AASLUMP_AREAS].filelen);
- aasworld.areas = (aas_area_t *) AAS_LoadAASLump(fp, offset, length, aasworld.areas);
- if (!aasworld.areas) return false;
- aasworld.numareas = length / sizeof(aas_area_t);
- //area settings
- offset = fpoffset + LittleLong(header.lumps[AASLUMP_AREASETTINGS].fileofs);
- length = LittleLong(header.lumps[AASLUMP_AREASETTINGS].filelen);
- aasworld.areasettings = (aas_areasettings_t *) AAS_LoadAASLump(fp, offset, length, aasworld.areasettings);
- if (!aasworld.areasettings) return false;
- aasworld.numareasettings = length / sizeof(aas_areasettings_t);
- //reachability list
- offset = fpoffset + LittleLong(header.lumps[AASLUMP_REACHABILITY].fileofs);
- length = LittleLong(header.lumps[AASLUMP_REACHABILITY].filelen);
- aasworld.reachability = (aas_reachability_t *) AAS_LoadAASLump(fp, offset, length, aasworld.reachability);
- if (length && !aasworld.reachability) return false;
- aasworld.reachabilitysize = length / sizeof(aas_reachability_t);
- //nodes
- offset = fpoffset + LittleLong(header.lumps[AASLUMP_NODES].fileofs);
- length = LittleLong(header.lumps[AASLUMP_NODES].filelen);
- aasworld.nodes = (aas_node_t *) AAS_LoadAASLump(fp, offset, length, aasworld.nodes);
- if (!aasworld.nodes) return false;
- aasworld.numnodes = length / sizeof(aas_node_t);
- //cluster portals
- offset = fpoffset + LittleLong(header.lumps[AASLUMP_PORTALS].fileofs);
- length = LittleLong(header.lumps[AASLUMP_PORTALS].filelen);
- aasworld.portals = (aas_portal_t *) AAS_LoadAASLump(fp, offset, length, aasworld.portals);
- if (length && !aasworld.portals) return false;
- aasworld.numportals = length / sizeof(aas_portal_t);
- //cluster portal index
- offset = fpoffset + LittleLong(header.lumps[AASLUMP_PORTALINDEX].fileofs);
- length = LittleLong(header.lumps[AASLUMP_PORTALINDEX].filelen);
- aasworld.portalindex = (aas_portalindex_t *) AAS_LoadAASLump(fp, offset, length, aasworld.portalindex);
- if (length && !aasworld.portalindex) return false;
- aasworld.portalindexsize = length / sizeof(aas_portalindex_t);
- //clusters
- offset = fpoffset + LittleLong(header.lumps[AASLUMP_CLUSTERS].fileofs);
- length = LittleLong(header.lumps[AASLUMP_CLUSTERS].filelen);
- aasworld.clusters = (aas_cluster_t *) AAS_LoadAASLump(fp, offset, length, aasworld.clusters);
- if (length && !aasworld.clusters) return false;
- aasworld.numclusters = length / sizeof(aas_cluster_t);
- //swap everything
- AAS_SwapAASData();
- //aas file is loaded
- aasworld.loaded = true;
- //close the file
- fclose(fp);
- return true;
-} //end of the function AAS_LoadAASFile
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int AAS_WriteAASLump(FILE *fp, aas_header_t *h, int lumpnum, void *data, int length)
-{
- aas_lump_t *lump;
-
- lump = &h->lumps[lumpnum];
-
- lump->fileofs = LittleLong(ftell(fp));
- lump->filelen = LittleLong(length);
-
- if (length > 0)
- {
- if (fwrite(data, length, 1, fp) < 1)
- {
- Log_Print("error writing lump %s\n", lumpnum);
- fclose(fp);
- return false;
- } //end if
- } //end if
- return true;
-} //end of the function AAS_WriteAASLump
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_ShowNumReachabilities(int tt, char *name)
-{
- int i, num;
-
- num = 0;
- for (i = 0; i < aasworld.reachabilitysize; i++)
- {
- if ((aasworld.reachability[i].traveltype & TRAVELTYPE_MASK) == tt)
- num++;
- } //end for
- Log_Print("%6d %s\n", num, name);
-} //end of the function AAS_ShowNumReachabilities
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_ShowTotals(void)
-{
- Log_Print("numvertexes = %d\r\n", aasworld.numvertexes);
- Log_Print("numplanes = %d\r\n", aasworld.numplanes);
- Log_Print("numedges = %d\r\n", aasworld.numedges);
- Log_Print("edgeindexsize = %d\r\n", aasworld.edgeindexsize);
- Log_Print("numfaces = %d\r\n", aasworld.numfaces);
- Log_Print("faceindexsize = %d\r\n", aasworld.faceindexsize);
- Log_Print("numareas = %d\r\n", aasworld.numareas);
- Log_Print("numareasettings = %d\r\n", aasworld.numareasettings);
- Log_Print("reachabilitysize = %d\r\n", aasworld.reachabilitysize);
- Log_Print("numnodes = %d\r\n", aasworld.numnodes);
- Log_Print("numportals = %d\r\n", aasworld.numportals);
- Log_Print("portalindexsize = %d\r\n", aasworld.portalindexsize);
- Log_Print("numclusters = %d\r\n", aasworld.numclusters);
- AAS_ShowNumReachabilities(TRAVEL_WALK, "walk");
- AAS_ShowNumReachabilities(TRAVEL_CROUCH, "crouch");
- AAS_ShowNumReachabilities(TRAVEL_BARRIERJUMP, "barrier jump");
- AAS_ShowNumReachabilities(TRAVEL_JUMP, "jump");
- AAS_ShowNumReachabilities(TRAVEL_LADDER, "ladder");
- AAS_ShowNumReachabilities(TRAVEL_WALKOFFLEDGE, "walk off ledge");
- AAS_ShowNumReachabilities(TRAVEL_SWIM, "swim");
- AAS_ShowNumReachabilities(TRAVEL_WATERJUMP, "water jump");
- AAS_ShowNumReachabilities(TRAVEL_TELEPORT, "teleport");
- AAS_ShowNumReachabilities(TRAVEL_ELEVATOR, "elevator");
- AAS_ShowNumReachabilities(TRAVEL_ROCKETJUMP, "rocket jump");
- AAS_ShowNumReachabilities(TRAVEL_BFGJUMP, "bfg jump");
- AAS_ShowNumReachabilities(TRAVEL_GRAPPLEHOOK, "grapple hook");
- AAS_ShowNumReachabilities(TRAVEL_DOUBLEJUMP, "double jump");
- AAS_ShowNumReachabilities(TRAVEL_RAMPJUMP, "ramp jump");
- AAS_ShowNumReachabilities(TRAVEL_STRAFEJUMP, "strafe jump");
- AAS_ShowNumReachabilities(TRAVEL_JUMPPAD, "jump pad");
- AAS_ShowNumReachabilities(TRAVEL_FUNCBOB, "func bob");
-} //end of the function AAS_ShowTotals
-//===========================================================================
-// aas data is useless after writing to file because it is byte swapped
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-qboolean AAS_WriteAASFile(char *filename)
-{
- aas_header_t header;
- FILE *fp;
-
- Log_Print("writing %s\n", filename);
- AAS_ShowTotals();
- //swap the aas data
- AAS_SwapAASData();
- //initialize the file header
- memset(&header, 0, sizeof(aas_header_t));
- header.ident = LittleLong(AASID);
- header.version = LittleLong(AASVERSION);
- header.bspchecksum = LittleLong(aasworld.bspchecksum);
- //open a new file
- fp = fopen(filename, "wb");
- if (!fp)
- {
- Log_Print("error opening %s\n", filename);
- return false;
- } //end if
- //write the header
- if (fwrite(&header, sizeof(aas_header_t), 1, fp) < 1)
- {
- fclose(fp);
- return false;
- } //end if
- //add the data lumps to the file
- if (!AAS_WriteAASLump(fp, &header, AASLUMP_BBOXES, aasworld.bboxes,
- aasworld.numbboxes * sizeof(aas_bbox_t))) return false;
- if (!AAS_WriteAASLump(fp, &header, AASLUMP_VERTEXES, aasworld.vertexes,
- aasworld.numvertexes * sizeof(aas_vertex_t))) return false;
- if (!AAS_WriteAASLump(fp, &header, AASLUMP_PLANES, aasworld.planes,
- aasworld.numplanes * sizeof(aas_plane_t))) return false;
- if (!AAS_WriteAASLump(fp, &header, AASLUMP_EDGES, aasworld.edges,
- aasworld.numedges * sizeof(aas_edge_t))) return false;
- if (!AAS_WriteAASLump(fp, &header, AASLUMP_EDGEINDEX, aasworld.edgeindex,
- aasworld.edgeindexsize * sizeof(aas_edgeindex_t))) return false;
- if (!AAS_WriteAASLump(fp, &header, AASLUMP_FACES, aasworld.faces,
- aasworld.numfaces * sizeof(aas_face_t))) return false;
- if (!AAS_WriteAASLump(fp, &header, AASLUMP_FACEINDEX, aasworld.faceindex,
- aasworld.faceindexsize * sizeof(aas_faceindex_t))) return false;
- if (!AAS_WriteAASLump(fp, &header, AASLUMP_AREAS, aasworld.areas,
- aasworld.numareas * sizeof(aas_area_t))) return false;
- if (!AAS_WriteAASLump(fp, &header, AASLUMP_AREASETTINGS, aasworld.areasettings,
- aasworld.numareasettings * sizeof(aas_areasettings_t))) return false;
- if (!AAS_WriteAASLump(fp, &header, AASLUMP_REACHABILITY, aasworld.reachability,
- aasworld.reachabilitysize * sizeof(aas_reachability_t))) return false;
- if (!AAS_WriteAASLump(fp, &header, AASLUMP_NODES, aasworld.nodes,
- aasworld.numnodes * sizeof(aas_node_t))) return false;
- if (!AAS_WriteAASLump(fp, &header, AASLUMP_PORTALS, aasworld.portals,
- aasworld.numportals * sizeof(aas_portal_t))) return false;
- if (!AAS_WriteAASLump(fp, &header, AASLUMP_PORTALINDEX, aasworld.portalindex,
- aasworld.portalindexsize * sizeof(aas_portalindex_t))) return false;
- if (!AAS_WriteAASLump(fp, &header, AASLUMP_CLUSTERS, aasworld.clusters,
- aasworld.numclusters * sizeof(aas_cluster_t))) return false;
- //rewrite the header with the added lumps
- fseek(fp, 0, SEEK_SET);
- AAS_DData((unsigned char *) &header + 8, sizeof(aas_header_t) - 8);
- if (fwrite(&header, sizeof(aas_header_t), 1, fp) < 1)
- {
- fclose(fp);
- return false;
- } //end if
- //close the file
- fclose(fp);
- return true;
-} //end of the function AAS_WriteAASFile
-
diff --git a/code/bspc/aas_file.h b/code/bspc/aas_file.h
deleted file mode 100644
index 321ddef..0000000
--- a/code/bspc/aas_file.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-qboolean AAS_WriteAASFile(char *filename);
-qboolean AAS_LoadAASFile(char *filename, int fpoffset, int fplength);
-
diff --git a/code/bspc/aas_gsubdiv.c b/code/bspc/aas_gsubdiv.c
deleted file mode 100644
index dfe696c..0000000
--- a/code/bspc/aas_gsubdiv.c
+++ /dev/null
@@ -1,656 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-#include "qbsp.h"
-#include "../botlib/aasfile.h"
-#include "aas_create.h"
-#include "aas_store.h"
-#include "aas_cfg.h"
-
-#define FACECLIP_EPSILON 0.2
-#define FACE_EPSILON 1.0
-
-int numgravitationalsubdivisions = 0;
-int numladdersubdivisions = 0;
-
-//NOTE: only do gravitational subdivision BEFORE area merging!!!!!!!
-// because the bsp tree isn't refreshes like with ladder subdivision
-
-//===========================================================================
-// NOTE: the original face is invalid after splitting
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_SplitFace(tmp_face_t *face, vec3_t normal, float dist,
- tmp_face_t **frontface, tmp_face_t **backface)
-{
- winding_t *frontw, *backw;
-
- //
- *frontface = *backface = NULL;
-
- ClipWindingEpsilon(face->winding, normal, dist, FACECLIP_EPSILON, &frontw, &backw);
-
-#ifdef DEBUG
- //
- if (frontw)
- {
- if (WindingIsTiny(frontw))
- {
- Log_Write("AAS_SplitFace: tiny back face\r\n");
- FreeWinding(frontw);
- frontw = NULL;
- } //end if
- } //end if
- if (backw)
- {
- if (WindingIsTiny(backw))
- {
- Log_Write("AAS_SplitFace: tiny back face\r\n");
- FreeWinding(backw);
- backw = NULL;
- } //end if
- } //end if
-#endif //DEBUG
- //if the winding was split
- if (frontw)
- {
- //check bounds
- (*frontface) = AAS_AllocTmpFace();
- (*frontface)->planenum = face->planenum;
- (*frontface)->winding = frontw;
- (*frontface)->faceflags = face->faceflags;
- } //end if
- if (backw)
- {
- //check bounds
- (*backface) = AAS_AllocTmpFace();
- (*backface)->planenum = face->planenum;
- (*backface)->winding = backw;
- (*backface)->faceflags = face->faceflags;
- } //end if
-} //end of the function AAS_SplitFace
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-winding_t *AAS_SplitWinding(tmp_area_t *tmparea, int planenum)
-{
- tmp_face_t *face;
- plane_t *plane;
- int side;
- winding_t *splitwinding;
-
- //
- plane = &mapplanes[planenum];
- //create a split winding, first base winding for plane
- splitwinding = BaseWindingForPlane(plane->normal, plane->dist);
- //chop with all the faces of the area
- for (face = tmparea->tmpfaces; face && splitwinding; face = face->next[side])
- {
- //side of the face the original area was on
- side = face->frontarea != tmparea;
- plane = &mapplanes[face->planenum ^ side];
- ChopWindingInPlace(&splitwinding, plane->normal, plane->dist, 0); // PLANESIDE_EPSILON);
- } //end for
- return splitwinding;
-} //end of the function AAS_SplitWinding
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int AAS_TestSplitPlane(tmp_area_t *tmparea, vec3_t normal, float dist,
- int *facesplits, int *groundsplits, int *epsilonfaces)
-{
- int j, side, front, back, planenum;
- float d, d_front, d_back;
- tmp_face_t *face;
- winding_t *w;
-
- *facesplits = *groundsplits = *epsilonfaces = 0;
-
- planenum = FindFloatPlane(normal, dist);
-
- w = AAS_SplitWinding(tmparea, planenum);
- if (!w) return false;
- FreeWinding(w);
- //
- for (face = tmparea->tmpfaces; face; face = face->next[side])
- {
- //side of the face the area is on
- side = face->frontarea != tmparea;
-
- if ((face->planenum & ~1) == (planenum & ~1))
- {
- Log_Print("AAS_TestSplitPlane: tried face plane as splitter\n");
- return false;
- } //end if
- w = face->winding;
- //reset distance at front and back side of plane
- d_front = d_back = 0;
- //reset front and back flags
- front = back = 0;
- for (j = 0; j < w->numpoints; j++)
- {
- d = DotProduct(w->p[j], normal) - dist;
- if (d > d_front) d_front = d;
- if (d < d_back) d_back = d;
-
- if (d > 0.4) // PLANESIDE_EPSILON)
- front = 1;
- if (d < -0.4) // PLANESIDE_EPSILON)
- back = 1;
- } //end for
- //check for an epsilon face
- if ( (d_front > FACECLIP_EPSILON && d_front < FACE_EPSILON)
- || (d_back < -FACECLIP_EPSILON && d_back > -FACE_EPSILON) )
- {
- (*epsilonfaces)++;
- } //end if
- //if the face has points at both sides of the plane
- if (front && back)
- {
- (*facesplits)++;
- if (face->faceflags & FACE_GROUND)
- {
- (*groundsplits)++;
- } //end if
- } //end if
- } //end for
- return true;
-} //end of the function AAS_TestSplitPlane
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_SplitArea(tmp_area_t *tmparea, int planenum, tmp_area_t **frontarea, tmp_area_t **backarea)
-{
- int side;
- tmp_area_t *facefrontarea, *facebackarea, *faceotherarea;
- tmp_face_t *face, *frontface, *backface, *splitface, *nextface;
- winding_t *splitwinding;
- plane_t *splitplane;
-
-/*
-#ifdef AW_DEBUG
- int facesplits, groundsplits, epsilonface;
- Log_Print("\n----------------------\n");
- Log_Print("splitting area %d\n", areanum);
- Log_Print("with normal = \'%f %f %f\', dist = %f\n", normal[0], normal[1], normal[2], dist);
- AAS_TestSplitPlane(areanum, normal, dist,
- &facesplits, &groundsplits, &epsilonface);
- Log_Print("face splits = %d\nground splits = %d\n", facesplits, groundsplits);
- if (epsilonface) Log_Print("aaahh epsilon face\n");
-#endif //AW_DEBUG*/
- //the original area
-
- AAS_FlipAreaFaces(tmparea);
- AAS_CheckArea(tmparea);
- //
- splitplane = &mapplanes[planenum];
-/* //create a split winding, first base winding for plane
- splitwinding = BaseWindingForPlane(splitplane->normal, splitplane->dist);
- //chop with all the faces of the area
- for (face = tmparea->tmpfaces; face && splitwinding; face = face->next[side])
- {
- //side of the face the original area was on
- side = face->frontarea != tmparea->areanum;
- plane = &mapplanes[face->planenum ^ side];
- ChopWindingInPlace(&splitwinding, plane->normal, plane->dist, 0); // PLANESIDE_EPSILON);
- } //end for*/
- splitwinding = AAS_SplitWinding(tmparea, planenum);
- if (!splitwinding)
- {
-/*
-#ifdef DEBUG
- AAS_TestSplitPlane(areanum, normal, dist,
- &facesplits, &groundsplits, &epsilonface);
- Log_Print("\nface splits = %d\nground splits = %d\n", facesplits, groundsplits);
- if (epsilonface) Log_Print("aaahh epsilon face\n");
-#endif //DEBUG*/
- Error("AAS_SplitArea: no split winding when splitting area %d\n", tmparea->areanum);
- } //end if
- //create a split face
- splitface = AAS_AllocTmpFace();
- //get the map plane
- splitface->planenum = planenum;
- //store the split winding
- splitface->winding = splitwinding;
- //the new front area
- (*frontarea) = AAS_AllocTmpArea();
- (*frontarea)->presencetype = tmparea->presencetype;
- (*frontarea)->contents = tmparea->contents;
- (*frontarea)->modelnum = tmparea->modelnum;
- (*frontarea)->tmpfaces = NULL;
- //the new back area
- (*backarea) = AAS_AllocTmpArea();
- (*backarea)->presencetype = tmparea->presencetype;
- (*backarea)->contents = tmparea->contents;
- (*backarea)->modelnum = tmparea->modelnum;
- (*backarea)->tmpfaces = NULL;
- //add the split face to the new areas
- AAS_AddFaceSideToArea(splitface, 0, (*frontarea));
- AAS_AddFaceSideToArea(splitface, 1, (*backarea));
-
- //split all the faces of the original area
- for (face = tmparea->tmpfaces; face; face = nextface)
- {
- //side of the face the original area was on
- side = face->frontarea != tmparea;
- //next face of the original area
- nextface = face->next[side];
- //front area of the face
- facefrontarea = face->frontarea;
- //back area of the face
- facebackarea = face->backarea;
- //remove the face from both the front and back areas
- if (facefrontarea) AAS_RemoveFaceFromArea(face, facefrontarea);
- if (facebackarea) AAS_RemoveFaceFromArea(face, facebackarea);
- //split the face
- AAS_SplitFace(face, splitplane->normal, splitplane->dist, &frontface, &backface);
- //free the original face
- AAS_FreeTmpFace(face);
- //get the number of the area at the other side of the face
- if (side) faceotherarea = facefrontarea;
- else faceotherarea = facebackarea;
- //if there is an area at the other side of the original face
- if (faceotherarea)
- {
- if (frontface) AAS_AddFaceSideToArea(frontface, !side, faceotherarea);
- if (backface) AAS_AddFaceSideToArea(backface, !side, faceotherarea);
- } //end if
- //add the front and back part left after splitting the original face to the new areas
- if (frontface) AAS_AddFaceSideToArea(frontface, side, (*frontarea));
- if (backface) AAS_AddFaceSideToArea(backface, side, (*backarea));
- } //end for
-
- if (!(*frontarea)->tmpfaces) Log_Print("AAS_SplitArea: front area without faces\n");
- if (!(*backarea)->tmpfaces) Log_Print("AAS_SplitArea: back area without faces\n");
-
- tmparea->invalid = true;
-/*
-#ifdef AW_DEBUG
- for (i = 0, face = frontarea->tmpfaces; face; face = face->next[side])
- {
- side = face->frontarea != frontarea->areanum;
- i++;
- } //end for
- Log_Print("created front area %d with %d faces\n", frontarea->areanum, i);
-
- for (i = 0, face = backarea->tmpfaces; face; face = face->next[side])
- {
- side = face->frontarea != backarea->areanum;
- i++;
- } //end for
- Log_Print("created back area %d with %d faces\n", backarea->areanum, i);
-#endif //AW_DEBUG*/
-
- AAS_FlipAreaFaces((*frontarea));
- AAS_FlipAreaFaces((*backarea));
- //
- AAS_CheckArea((*frontarea));
- AAS_CheckArea((*backarea));
-} //end of the function AAS_SplitArea
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int AAS_FindBestAreaSplitPlane(tmp_area_t *tmparea, vec3_t normal, float *dist)
-{
- int side1, side2;
- int foundsplitter, facesplits, groundsplits, epsilonfaces, bestepsilonfaces;
- float bestvalue, value;
- tmp_face_t *face1, *face2;
- vec3_t tmpnormal, invgravity;
- float tmpdist;
-
- //get inverse of gravity direction
- VectorCopy(cfg.phys_gravitydirection, invgravity);
- VectorInverse(invgravity);
-
- foundsplitter = false;
- bestvalue = -999999;
- bestepsilonfaces = 0;
- //
-#ifdef AW_DEBUG
- Log_Print("finding split plane for area %d\n", tmparea->areanum);
-#endif //AW_DEBUG
- for (face1 = tmparea->tmpfaces; face1; face1 = face1->next[side1])
- {
- //side of the face the area is on
- side1 = face1->frontarea != tmparea;
- //
- if (WindingIsTiny(face1->winding))
- {
- Log_Write("gsubdiv: area %d has a tiny winding\r\n", tmparea->areanum);
- continue;
- } //end if
- //if the face isn't a gap or ground there's no split edge
- if (!(face1->faceflags & FACE_GROUND) && !AAS_GapFace(face1, side1)) continue;
- //
- for (face2 = face1->next[side1]; face2; face2 = face2->next[side2])
- {
- //side of the face the area is on
- side2 = face2->frontarea != tmparea;
- //
- if (WindingIsTiny(face1->winding))
- {
- Log_Write("gsubdiv: area %d has a tiny winding\r\n", tmparea->areanum);
- continue;
- } //end if
- //if the face isn't a gap or ground there's no split edge
- if (!(face2->faceflags & FACE_GROUND) && !AAS_GapFace(face2, side2)) continue;
- //only split between gaps and ground
- if (!(((face1->faceflags & FACE_GROUND) && AAS_GapFace(face2, side2)) ||
- ((face2->faceflags & FACE_GROUND) && AAS_GapFace(face1, side1)))) continue;
- //find a plane seperating the windings of the faces
- if (!FindPlaneSeperatingWindings(face1->winding, face2->winding, invgravity,
- tmpnormal, &tmpdist)) continue;
-#ifdef AW_DEBUG
- Log_Print("normal = \'%f %f %f\', dist = %f\n",
- tmpnormal[0], tmpnormal[1], tmpnormal[2], tmpdist);
-#endif //AW_DEBUG
- //get metrics for this vertical plane
- if (!AAS_TestSplitPlane(tmparea, tmpnormal, tmpdist,
- &facesplits, &groundsplits, &epsilonfaces))
- {
- continue;
- } //end if
-#ifdef AW_DEBUG
- Log_Print("face splits = %d\nground splits = %d\n",
- facesplits, groundsplits);
-#endif //AW_DEBUG
- value = 100 - facesplits - 2 * groundsplits;
- //avoid epsilon faces
- value += epsilonfaces * -1000;
- if (value > bestvalue)
- {
- VectorCopy(tmpnormal, normal);
- *dist = tmpdist;
- bestvalue = value;
- bestepsilonfaces = epsilonfaces;
- foundsplitter = true;
- } //end if
- } //end for
- } //end for
- if (bestepsilonfaces)
- {
- Log_Write("found %d epsilon faces trying to split area %d\r\n",
- epsilonfaces, tmparea->areanum);
- } //end else
- return foundsplitter;
-} //end of the function AAS_FindBestAreaSplitPlane
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-tmp_node_t *AAS_SubdivideArea_r(tmp_node_t *tmpnode)
-{
- int planenum;
- tmp_area_t *frontarea, *backarea;
- tmp_node_t *tmpnode1, *tmpnode2;
- vec3_t normal;
- float dist;
-
- if (AAS_FindBestAreaSplitPlane(tmpnode->tmparea, normal, &dist))
- {
- qprintf("\r%6d", ++numgravitationalsubdivisions);
- //
- planenum = FindFloatPlane(normal, dist);
- //split the area
- AAS_SplitArea(tmpnode->tmparea, planenum, &frontarea, &backarea);
- //
- tmpnode->tmparea = NULL;
- tmpnode->planenum = FindFloatPlane(normal, dist);
- //
- tmpnode1 = AAS_AllocTmpNode();
- tmpnode1->planenum = 0;
- tmpnode1->tmparea = frontarea;
- //
- tmpnode2 = AAS_AllocTmpNode();
- tmpnode2->planenum = 0;
- tmpnode2->tmparea = backarea;
- //subdivide the areas created by splitting recursively
- tmpnode->children[0] = AAS_SubdivideArea_r(tmpnode1);
- tmpnode->children[1] = AAS_SubdivideArea_r(tmpnode2);
- } //end if
- return tmpnode;
-} //end of the function AAS_SubdivideArea_r
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-tmp_node_t *AAS_GravitationalSubdivision_r(tmp_node_t *tmpnode)
-{
- //if this is a solid leaf
- if (!tmpnode) return NULL;
- //negative so it's an area
- if (tmpnode->tmparea) return AAS_SubdivideArea_r(tmpnode);
- //do the children recursively
- tmpnode->children[0] = AAS_GravitationalSubdivision_r(tmpnode->children[0]);
- tmpnode->children[1] = AAS_GravitationalSubdivision_r(tmpnode->children[1]);
- return tmpnode;
-} //end of the function AAS_GravitationalSubdivision_r
-//===========================================================================
-// NOTE: merge faces and melt edges first
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_GravitationalSubdivision(void)
-{
- Log_Write("AAS_GravitationalSubdivision\r\n");
- numgravitationalsubdivisions = 0;
- qprintf("%6i gravitational subdivisions", numgravitationalsubdivisions);
- //start with the head node
- AAS_GravitationalSubdivision_r(tmpaasworld.nodes);
- qprintf("\n");
- Log_Write("%6i gravitational subdivisions\r\n", numgravitationalsubdivisions);
-} //end of the function AAS_GravitationalSubdivision
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-tmp_node_t *AAS_RefreshLadderSubdividedTree_r(tmp_node_t *tmpnode, tmp_area_t *tmparea,
- tmp_node_t *tmpnode1, tmp_node_t *tmpnode2, int planenum)
-{
- //if this is a solid leaf
- if (!tmpnode) return NULL;
- //negative so it's an area
- if (tmpnode->tmparea)
- {
- if (tmpnode->tmparea == tmparea)
- {
- tmpnode->tmparea = NULL;
- tmpnode->planenum = planenum;
- tmpnode->children[0] = tmpnode1;
- tmpnode->children[1] = tmpnode2;
- } //end if
- return tmpnode;
- } //end if
- //do the children recursively
- tmpnode->children[0] = AAS_RefreshLadderSubdividedTree_r(tmpnode->children[0],
- tmparea, tmpnode1, tmpnode2, planenum);
- tmpnode->children[1] = AAS_RefreshLadderSubdividedTree_r(tmpnode->children[1],
- tmparea, tmpnode1, tmpnode2, planenum);
- return tmpnode;
-} //end of the function AAS_RefreshLadderSubdividedTree_r
-//===========================================================================
-// find an area with ladder faces and ground faces that are not connected
-// split the area with a horizontal plane at the lowest vertex of all
-// ladder faces in the area
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-tmp_node_t *AAS_LadderSubdivideArea_r(tmp_node_t *tmpnode)
-{
- int side1, i, planenum;
- int foundladderface, foundgroundface;
- float dist;
- tmp_area_t *tmparea, *frontarea, *backarea;
- tmp_face_t *face1;
- tmp_node_t *tmpnode1, *tmpnode2;
- vec3_t lowestpoint, normal = {0, 0, 1};
- plane_t *plane;
- winding_t *w;
-
- tmparea = tmpnode->tmparea;
- //skip areas with a liquid
- if (tmparea->contents & (AREACONTENTS_WATER
- | AREACONTENTS_LAVA
- | AREACONTENTS_SLIME)) return tmpnode;
- //must be possible to stand in the area
- if (!(tmparea->presencetype & PRESENCE_NORMAL)) return tmpnode;
- //
- foundladderface = false;
- foundgroundface = false;
- lowestpoint[2] = 99999;
- //
- for (face1 = tmparea->tmpfaces; face1; face1 = face1->next[side1])
- {
- //side of the face the area is on
- side1 = face1->frontarea != tmparea;
- //if the face is a ladder face
- if (face1->faceflags & FACE_LADDER)
- {
- plane = &mapplanes[face1->planenum];
- //the ladder face plane should be pretty much vertical
- if (DotProduct(plane->normal, normal) > -0.1)
- {
- foundladderface = true;
- //find lowest point
- for (i = 0; i < face1->winding->numpoints; i++)
- {
- if (face1->winding->p[i][2] < lowestpoint[2])
- {
- VectorCopy(face1->winding->p[i], lowestpoint);
- } //end if
- } //end for
- } //end if
- } //end if
- else if (face1->faceflags & FACE_GROUND)
- {
- foundgroundface = true;
- } //end else if
- } //end for
- //
- if ((!foundladderface) || (!foundgroundface)) return tmpnode;
- //
- for (face1 = tmparea->tmpfaces; face1; face1 = face1->next[side1])
- {
- //side of the face the area is on
- side1 = face1->frontarea != tmparea;
- //if the face isn't a ground face
- if (!(face1->faceflags & FACE_GROUND)) continue;
- //the ground plane
- plane = &mapplanes[face1->planenum];
- //get the difference between the ground plane and the lowest point
- dist = DotProduct(plane->normal, lowestpoint) - plane->dist;
- //if the lowest point is very near one of the ground planes
- if (dist > -1 && dist < 1)
- {
- return tmpnode;
- } //end if
- } //end for
- //
- dist = DotProduct(normal, lowestpoint);
- planenum = FindFloatPlane(normal, dist);
- //
- w = AAS_SplitWinding(tmparea, planenum);
- if (!w) return tmpnode;
- FreeWinding(w);
- //split the area with a horizontal plane through the lowest point
- qprintf("\r%6d", ++numladdersubdivisions);
- //
- AAS_SplitArea(tmparea, planenum, &frontarea, &backarea);
- //
- tmpnode->tmparea = NULL;
- tmpnode->planenum = planenum;
- //
- tmpnode1 = AAS_AllocTmpNode();
- tmpnode1->planenum = 0;
- tmpnode1->tmparea = frontarea;
- //
- tmpnode2 = AAS_AllocTmpNode();
- tmpnode2->planenum = 0;
- tmpnode2->tmparea = backarea;
- //subdivide the areas created by splitting recursively
- tmpnode->children[0] = AAS_LadderSubdivideArea_r(tmpnode1);
- tmpnode->children[1] = AAS_LadderSubdivideArea_r(tmpnode2);
- //refresh the tree
- AAS_RefreshLadderSubdividedTree_r(tmpaasworld.nodes, tmparea, tmpnode1, tmpnode2, planenum);
- //
- return tmpnode;
-} //end of the function AAS_LadderSubdivideArea_r
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-tmp_node_t *AAS_LadderSubdivision_r(tmp_node_t *tmpnode)
-{
- //if this is a solid leaf
- if (!tmpnode) return 0;
- //negative so it's an area
- if (tmpnode->tmparea) return AAS_LadderSubdivideArea_r(tmpnode);
- //do the children recursively
- tmpnode->children[0] = AAS_LadderSubdivision_r(tmpnode->children[0]);
- tmpnode->children[1] = AAS_LadderSubdivision_r(tmpnode->children[1]);
- return tmpnode;
-} //end of the function AAS_LadderSubdivision_r
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_LadderSubdivision(void)
-{
- Log_Write("AAS_LadderSubdivision\r\n");
- numladdersubdivisions = 0;
- qprintf("%6i ladder subdivisions", numladdersubdivisions);
- //start with the head node
- AAS_LadderSubdivision_r(tmpaasworld.nodes);
- //
- qprintf("\n");
- Log_Write("%6i ladder subdivisions\r\n", numladdersubdivisions);
-} //end of the function AAS_LadderSubdivision
diff --git a/code/bspc/aas_gsubdiv.h b/code/bspc/aas_gsubdiv.h
deleted file mode 100644
index 8539a11..0000000
--- a/code/bspc/aas_gsubdiv.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-//works with the global tmpaasworld
-void AAS_GravitationalSubdivision(void);
-void AAS_LadderSubdivision(void);
diff --git a/code/bspc/aas_map.c b/code/bspc/aas_map.c
deleted file mode 100644
index b4a5afd..0000000
--- a/code/bspc/aas_map.c
+++ /dev/null
@@ -1,849 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-#include "qbsp.h"
-#include "l_mem.h"
-#include "../botlib/aasfile.h" //aas_bbox_t
-#include "aas_store.h" //AAS_MAX_BBOXES
-#include "aas_cfg.h"
-#include "../qcommon/surfaceflags.h"
-
-#define SPAWNFLAG_NOT_EASY 0x00000100
-#define SPAWNFLAG_NOT_MEDIUM 0x00000200
-#define SPAWNFLAG_NOT_HARD 0x00000400
-#define SPAWNFLAG_NOT_DEATHMATCH 0x00000800
-#define SPAWNFLAG_NOT_COOP 0x00001000
-
-#define STATE_TOP 0
-#define STATE_BOTTOM 1
-#define STATE_UP 2
-#define STATE_DOWN 3
-
-#define DOOR_START_OPEN 1
-#define DOOR_REVERSE 2
-#define DOOR_CRUSHER 4
-#define DOOR_NOMONSTER 8
-#define DOOR_TOGGLE 32
-#define DOOR_X_AXIS 64
-#define DOOR_Y_AXIS 128
-
-#define BBOX_NORMAL_EPSILON 0.0001
-
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-vec_t BoxOriginDistanceFromPlane(vec3_t normal, vec3_t mins, vec3_t maxs, int side)
-{
- vec3_t v1, v2;
- int i;
-
- if (side)
- {
- for (i = 0; i < 3; i++)
- {
- if (normal[i] > BBOX_NORMAL_EPSILON) v1[i] = maxs[i];
- else if (normal[i] < -BBOX_NORMAL_EPSILON) v1[i] = mins[i];
- else v1[i] = 0;
- } //end for
- } //end if
- else
- {
- for (i = 0; i < 3; i++)
- {
- if (normal[i] > BBOX_NORMAL_EPSILON) v1[i] = mins[i];
- else if (normal[i] < -BBOX_NORMAL_EPSILON) v1[i] = maxs[i];
- else v1[i] = 0;
- } //end for
- } //end else
- VectorCopy(normal, v2);
- VectorInverse(v2);
- return DotProduct(v1, v2);
-} //end of the function BoxOriginDistanceFromPlane
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-vec_t CapsuleOriginDistanceFromPlane(vec3_t normal, vec3_t mins, vec3_t maxs)
-{
- float offset_up, offset_down, width, radius;
-
- width = maxs[0] - mins[0];
- // if the box is less high then it is wide
- if (maxs[2] - mins[2] < width) {
- width = maxs[2] - mins[2];
- }
- radius = width * 0.5;
- // offset to upper and lower sphere
- offset_up = maxs[2] - radius;
- offset_down = -mins[2] - radius;
-
- // if normal points upward
- if ( normal[2] > 0 ) {
- // touches lower sphere first
- return normal[2] * offset_down + radius;
- }
- else {
- // touched upper sphere first
- return -normal[2] * offset_up + radius;
- }
-}
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_ExpandMapBrush(mapbrush_t *brush, vec3_t mins, vec3_t maxs)
-{
- int sn;
- float dist;
- side_t *s;
- plane_t *plane;
-
- for (sn = 0; sn < brush->numsides; sn++)
- {
- s = brush->original_sides + sn;
- plane = &mapplanes[s->planenum];
- dist = plane->dist;
- if (capsule_collision) {
- dist += CapsuleOriginDistanceFromPlane(plane->normal, mins, maxs);
- }
- else {
- dist += BoxOriginDistanceFromPlane(plane->normal, mins, maxs, 0);
- }
- s->planenum = FindFloatPlane(plane->normal, dist);
- //the side isn't a bevel after expanding
- s->flags &= ~SFL_BEVEL;
- //don't skip the surface
- s->surf &= ~SURF_SKIP;
- //make sure the texinfo is not TEXINFO_NODE
- //when player clip contents brushes are read from the bsp tree
- //they have the texinfo field set to TEXINFO_NODE
- //s->texinfo = 0;
- } //end for
-} //end of the function AAS_ExpandMapBrush
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_SetTexinfo(mapbrush_t *brush)
-{
- int n;
- side_t *side;
-
- if (brush->contents & (CONTENTS_LADDER
- | CONTENTS_AREAPORTAL
- | CONTENTS_CLUSTERPORTAL
- | CONTENTS_TELEPORTER
- | CONTENTS_JUMPPAD
- | CONTENTS_DONOTENTER
- | CONTENTS_WATER
- | CONTENTS_LAVA
- | CONTENTS_SLIME
- | CONTENTS_WINDOW
- | CONTENTS_PLAYERCLIP))
- {
- //we just set texinfo to 0 because these brush sides MUST be used as
- //bsp splitters textured or not textured
- for (n = 0; n < brush->numsides; n++)
- {
- side = brush->original_sides + n;
- //side->flags |= SFL_TEXTURED|SFL_VISIBLE;
- side->texinfo = 0;
- } //end for
- } //end if
- else
- {
- //only use brush sides as splitters if they are textured
- //texinfo of non-textured sides will be set to TEXINFO_NODE
- for (n = 0; n < brush->numsides; n++)
- {
- side = brush->original_sides + n;
- //don't use side as splitter (set texinfo to TEXINFO_NODE) if not textured
- if (side->flags & (SFL_TEXTURED|SFL_BEVEL)) side->texinfo = 0;
- else side->texinfo = TEXINFO_NODE;
- } //end for
- } //end else
-} //end of the function AAS_SetTexinfo
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void FreeBrushWindings(mapbrush_t *brush)
-{
- int n;
- side_t *side;
- //
- for (n = 0; n < brush->numsides; n++)
- {
- side = brush->original_sides + n;
- //
- if (side->winding) FreeWinding(side->winding);
- } //end for
-} //end of the function FreeBrushWindings
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_AddMapBrushSide(mapbrush_t *brush, int planenum)
-{
- side_t *side;
- //
- if (nummapbrushsides >= MAX_MAPFILE_BRUSHSIDES)
- Error ("MAX_MAPFILE_BRUSHSIDES");
- //
- side = brush->original_sides + brush->numsides;
- side->original = NULL;
- side->winding = NULL;
- side->contents = brush->contents;
- side->flags &= ~(SFL_BEVEL|SFL_VISIBLE);
- side->surf = 0;
- side->planenum = planenum;
- side->texinfo = 0;
- //
- nummapbrushsides++;
- brush->numsides++;
-} //end of the function AAS_AddMapBrushSide
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_FixMapBrush(mapbrush_t *brush)
-{
- int i, j, planenum;
- float dist;
- winding_t *w;
- plane_t *plane, *plane1, *plane2;
- side_t *side;
- vec3_t normal;
-
- //calculate the brush bounds
- ClearBounds(brush->mins, brush->maxs);
- for (i = 0; i < brush->numsides; i++)
- {
- plane = &mapplanes[brush->original_sides[i].planenum];
- w = BaseWindingForPlane(plane->normal, plane->dist);
- for (j = 0; j < brush->numsides && w; j++)
- {
- if (i == j) continue;
- //there are no brush bevels marked but who cares :)
- if (brush->original_sides[j].flags & SFL_BEVEL) continue;
- plane = &mapplanes[brush->original_sides[j].planenum^1];
- ChopWindingInPlace(&w, plane->normal, plane->dist, 0); //CLIP_EPSILON);
- } //end for
-
- side = &brush->original_sides[i];
- side->winding = w;
- if (w)
- {
- for (j = 0; j < w->numpoints; j++)
- {
- AddPointToBounds(w->p[j], brush->mins, brush->maxs);
- } //end for
- } //end if
- } //end for
- //
- for (i = 0; i < brush->numsides; i++)
- {
- for (j = 0; j < brush->numsides; j++)
- {
- if (i == j) continue;
- plane1 = &mapplanes[brush->original_sides[i].planenum];
- plane2 = &mapplanes[brush->original_sides[j].planenum];
- if (WindingsNonConvex(brush->original_sides[i].winding,
- brush->original_sides[j].winding,
- plane1->normal, plane2->normal,
- plane1->dist, plane2->dist))
- {
- Log_Print("non convex brush");
- } //end if
- } //end for
- } //end for
-
- //NOW close the fucking brush!!
- for (i = 0; i < 3; i++)
- {
- if (brush->mins[i] < -MAX_MAP_BOUNDS)
- {
- VectorClear(normal);
- normal[i] = -1;
- dist = MAX_MAP_BOUNDS - 10;
- planenum = FindFloatPlane(normal, dist);
- //
- Log_Print("mins out of range: added extra brush side\n");
- AAS_AddMapBrushSide(brush, planenum);
- } //end if
- if (brush->maxs[i] > MAX_MAP_BOUNDS)
- {
- VectorClear(normal);
- normal[i] = 1;
- dist = MAX_MAP_BOUNDS - 10;
- planenum = FindFloatPlane(normal, dist);
- //
- Log_Print("maxs out of range: added extra brush side\n");
- AAS_AddMapBrushSide(brush, planenum);
- } //end if
- if (brush->mins[i] > MAX_MAP_BOUNDS || brush->maxs[i] < -MAX_MAP_BOUNDS)
- {
- Log_Print("entity %i, brush %i: no visible sides on brush\n", brush->entitynum, brush->brushnum);
- } //end if
- } //end for
- //free all the windings
- FreeBrushWindings(brush);
-} //end of the function AAS_FixMapBrush
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-qboolean AAS_MakeBrushWindings(mapbrush_t *ob)
-{
- int i, j;
- winding_t *w;
- side_t *side;
- plane_t *plane, *plane1, *plane2;
-
- ClearBounds (ob->mins, ob->maxs);
-
- for (i = 0; i < ob->numsides; i++)
- {
- plane = &mapplanes[ob->original_sides[i].planenum];
- w = BaseWindingForPlane(plane->normal, plane->dist);
- for (j = 0; j <ob->numsides && w; j++)
- {
- if (i == j) continue;
- if (ob->original_sides[j].flags & SFL_BEVEL) continue;
- plane = &mapplanes[ob->original_sides[j].planenum^1];
- ChopWindingInPlace(&w, plane->normal, plane->dist, 0); //CLIP_EPSILON);
- }
-
- side = &ob->original_sides[i];
- side->winding = w;
- if (w)
- {
- side->flags |= SFL_VISIBLE;
- for (j = 0; j < w->numpoints; j++)
- AddPointToBounds (w->p[j], ob->mins, ob->maxs);
- }
- }
- //check if the brush is convex
- for (i = 0; i < ob->numsides; i++)
- {
- for (j = 0; j < ob->numsides; j++)
- {
- if (i == j) continue;
- plane1 = &mapplanes[ob->original_sides[i].planenum];
- plane2 = &mapplanes[ob->original_sides[j].planenum];
- if (WindingsNonConvex(ob->original_sides[i].winding,
- ob->original_sides[j].winding,
- plane1->normal, plane2->normal,
- plane1->dist, plane2->dist))
- {
- Log_Print("non convex brush");
- } //end if
- } //end for
- } //end for
- //check for out of bound brushes
- for (i = 0; i < 3; i++)
- {
- //IDBUG: all the indexes into the mins and maxs were zero (not using i)
- if (ob->mins[i] < -MAX_MAP_BOUNDS || ob->maxs[i] > MAX_MAP_BOUNDS)
- {
- Log_Print("entity %i, brush %i: bounds out of range\n", ob->entitynum, ob->brushnum);
- Log_Print("ob->mins[%d] = %f, ob->maxs[%d] = %f\n", i, ob->mins[i], i, ob->maxs[i]);
- ob->numsides = 0; //remove the brush
- break;
- } //end if
- if (ob->mins[i] > MAX_MAP_BOUNDS || ob->maxs[i] < -MAX_MAP_BOUNDS)
- {
- Log_Print("entity %i, brush %i: no visible sides on brush\n", ob->entitynum, ob->brushnum);
- Log_Print("ob->mins[%d] = %f, ob->maxs[%d] = %f\n", i, ob->mins[i], i, ob->maxs[i]);
- ob->numsides = 0; //remove the brush
- break;
- } //end if
- } //end for
- return true;
-} //end of the function AAS_MakeBrushWindings
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-mapbrush_t *AAS_CopyMapBrush(mapbrush_t *brush, entity_t *mapent)
-{
- int n;
- mapbrush_t *newbrush;
- side_t *side, *newside;
-
- if (nummapbrushes >= MAX_MAPFILE_BRUSHES)
- Error ("MAX_MAPFILE_BRUSHES");
-
- newbrush = &mapbrushes[nummapbrushes];
- newbrush->original_sides = &brushsides[nummapbrushsides];
- newbrush->entitynum = brush->entitynum;
- newbrush->brushnum = nummapbrushes - mapent->firstbrush;
- newbrush->numsides = brush->numsides;
- newbrush->contents = brush->contents;
-
- //copy the sides
- for (n = 0; n < brush->numsides; n++)
- {
- if (nummapbrushsides >= MAX_MAPFILE_BRUSHSIDES)
- Error ("MAX_MAPFILE_BRUSHSIDES");
- side = brush->original_sides + n;
-
- newside = newbrush->original_sides + n;
- newside->original = NULL;
- newside->winding = NULL;
- newside->contents = side->contents;
- newside->flags = side->flags;
- newside->surf = side->surf;
- newside->planenum = side->planenum;
- newside->texinfo = side->texinfo;
- nummapbrushsides++;
- } //end for
- //
- nummapbrushes++;
- mapent->numbrushes++;
- return newbrush;
-} //end of the function AAS_CopyMapBrush
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int mark_entities[MAX_MAP_ENTITIES];
-
-int AAS_AlwaysTriggered_r(char *targetname)
-{
- int i;
-
- if (!strlen(targetname)) {
- return false;
- }
- //
- for (i = 0; i < num_entities; i++) {
- // if the entity will activate the given targetname
- if ( !strcmp(targetname, ValueForKey(&entities[i], "target")) ) {
- // if this activator is present in deathmatch
- if (!(atoi(ValueForKey(&entities[i], "spawnflags")) & SPAWNFLAG_NOT_DEATHMATCH)) {
- // if it is a trigger_always entity
- if (!strcmp("trigger_always", ValueForKey(&entities[i], "classname"))) {
- return true;
- }
- // check for possible trigger_always entities activating this entity
- if ( mark_entities[i] ) {
- Warning( "entity %d, classname %s has recursive targetname %s\n", i,
- ValueForKey(&entities[i], "classname"), targetname );
- return false;
- }
- mark_entities[i] = true;
- if ( AAS_AlwaysTriggered_r(ValueForKey(&entities[i], "targetname")) ) {
- return true;
- }
- }
- }
- }
- return false;
-}
-
-int AAS_AlwaysTriggered(char *targetname) {
- memset( mark_entities, 0, sizeof(mark_entities) );
- return AAS_AlwaysTriggered_r( targetname );
-}
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int AAS_ValidEntity(entity_t *mapent)
-{
- int i;
- char target[1024];
-
- //all world brushes are used for AAS
- if (mapent == &entities[0])
- {
- return true;
- } //end if
- //some of the func_wall brushes are also used for AAS
- else if (!strcmp("func_wall", ValueForKey(mapent, "classname")))
- {
- //Log_Print("found func_wall entity %d\n", mapent - entities);
- //if the func wall is used in deathmatch
- if (!(atoi(ValueForKey(mapent, "spawnflags")) & SPAWNFLAG_NOT_DEATHMATCH))
- {
- //Log_Print("func_wall USED in deathmatch mode %d\n", atoi(ValueForKey(mapent, "spawnflags")));
- return true;
- } //end if
- } //end else if
- else if (!strcmp("func_door_rotating", ValueForKey(mapent, "classname")))
- {
- //if the func_door_rotating is present in deathmatch
- if (!(atoi(ValueForKey(mapent, "spawnflags")) & SPAWNFLAG_NOT_DEATHMATCH))
- {
- //if the func_door_rotating is always activated in deathmatch
- if (AAS_AlwaysTriggered(ValueForKey(mapent, "targetname")))
- {
- //Log_Print("found func_door_rotating in deathmatch\ntargetname %s\n", ValueForKey(mapent, "targetname"));
- return true;
- } //end if
- } //end if
- } //end else if
- else if (!strcmp("trigger_hurt", ValueForKey(mapent, "classname")))
- {
- //"dmg" is the damage, for instance: "dmg" "666"
- return true;
- } //end else if
- else if (!strcmp("trigger_push", ValueForKey(mapent, "classname")))
- {
- return true;
- } //end else if
- else if (!strcmp("trigger_multiple", ValueForKey(mapent, "classname")))
- {
- //find out if the trigger_multiple is pointing to a target_teleporter
- strcpy(target, ValueForKey(mapent, "target"));
- for (i = 0; i < num_entities; i++)
- {
- //if the entity will activate the given targetname
- if (!strcmp(target, ValueForKey(&entities[i], "targetname")))
- {
- if (!strcmp("target_teleporter", ValueForKey(&entities[i], "classname")))
- {
- return true;
- } //end if
- } //end if
- } //end for
- } //end else if
- else if (!strcmp("trigger_teleport", ValueForKey(mapent, "classname")))
- {
- return true;
- } //end else if
- else if (!strcmp("func_static", ValueForKey(mapent, "classname")))
- {
- //FIXME: easy/medium/hard/deathmatch specific?
- return true;
- } //end else if
- else if (!strcmp("func_door", ValueForKey(mapent, "classname")))
- {
- return true;
- } //end else if
- return false;
-} //end of the function AAS_ValidEntity
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int AAS_TransformPlane(int planenum, vec3_t origin, vec3_t angles)
-{
- float newdist, matrix[3][3];
- vec3_t normal;
-
- //rotate the node plane
- VectorCopy(mapplanes[planenum].normal, normal);
- CreateRotationMatrix(angles, matrix);
- RotatePoint(normal, matrix);
- newdist = mapplanes[planenum].dist + DotProduct(normal, origin);
- return FindFloatPlane(normal, newdist);
-} //end of the function AAS_TransformPlane
-//===========================================================================
-// this function sets the func_rotating_door in it's final position
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_PositionFuncRotatingBrush(entity_t *mapent, mapbrush_t *brush)
-{
- int spawnflags, i;
- float distance;
- vec3_t movedir, angles, pos1, pos2;
- side_t *s;
-
- spawnflags = FloatForKey(mapent, "spawnflags");
- VectorClear(movedir);
- if (spawnflags & DOOR_X_AXIS)
- movedir[2] = 1.0; //roll
- else if (spawnflags & DOOR_Y_AXIS)
- movedir[0] = 1.0; //pitch
- else // Z_AXIS
- movedir[1] = 1.0; //yaw
-
- // check for reverse rotation
- if (spawnflags & DOOR_REVERSE)
- VectorInverse(movedir);
-
- distance = FloatForKey(mapent, "distance");
- if (!distance) distance = 90;
-
- GetVectorForKey(mapent, "angles", angles);
- VectorCopy(angles, pos1);
- VectorMA(angles, -distance, movedir, pos2);
- // if it starts open, switch the positions
- if (spawnflags & DOOR_START_OPEN)
- {
- VectorCopy(pos2, angles);
- VectorCopy(pos1, pos2);
- VectorCopy(angles, pos1);
- VectorInverse(movedir);
- } //end if
- //
- for (i = 0; i < brush->numsides; i++)
- {
- s = &brush->original_sides[i];
- s->planenum = AAS_TransformPlane(s->planenum, mapent->origin, pos2);
- } //end for
- //
- FreeBrushWindings(brush);
- AAS_MakeBrushWindings(brush);
- AddBrushBevels(brush);
- FreeBrushWindings(brush);
-} //end of the function AAS_PositionFuncRotatingBrush
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_PositionBrush(entity_t *mapent, mapbrush_t *brush)
-{
- side_t *s;
- float newdist;
- int i, notteam;
- char *model;
-
- if (!strcmp(ValueForKey(mapent, "classname"), "func_door_rotating"))
- {
- AAS_PositionFuncRotatingBrush(mapent, brush);
- } //end if
- else
- {
- if (mapent->origin[0] || mapent->origin[1] || mapent->origin[2])
- {
- for (i = 0; i < brush->numsides; i++)
- {
- s = &brush->original_sides[i];
- newdist = mapplanes[s->planenum].dist +
- DotProduct(mapplanes[s->planenum].normal, mapent->origin);
- s->planenum = FindFloatPlane(mapplanes[s->planenum].normal, newdist);
- } //end for
- } //end if
- //if it's a trigger hurt
- if (!strcmp("trigger_hurt", ValueForKey(mapent, "classname")))
- {
- notteam = FloatForKey(mapent, "bot_notteam");
- if ( notteam == 1 ) {
- brush->contents |= CONTENTS_NOTTEAM1;
- }
- else if ( notteam == 2 ) {
- brush->contents |= CONTENTS_NOTTEAM2;
- }
- else {
- // always avoid so set lava contents
- brush->contents |= CONTENTS_LAVA;
- }
- } //end if
- //
- else if (!strcmp("trigger_push", ValueForKey(mapent, "classname")))
- {
- //set the jumppad contents
- brush->contents = CONTENTS_JUMPPAD;
- //Log_Print("found trigger_push brush\n");
- } //end if
- //
- else if (!strcmp("trigger_multiple", ValueForKey(mapent, "classname")))
- {
- //set teleporter contents
- brush->contents = CONTENTS_TELEPORTER;
- //Log_Print("found trigger_multiple teleporter brush\n");
- } //end if
- //
- else if (!strcmp("trigger_teleport", ValueForKey(mapent, "classname")))
- {
- //set teleporter contents
- brush->contents = CONTENTS_TELEPORTER;
- //Log_Print("found trigger_teleport teleporter brush\n");
- } //end if
- else if (!strcmp("func_door", ValueForKey(mapent, "classname")))
- {
- //set mover contents
- brush->contents = CONTENTS_MOVER;
- //get the model number
- model = ValueForKey(mapent, "model");
- brush->modelnum = atoi(model+1);
- } //end if
- } //end else
-} //end of the function AAS_PositionBrush
-//===========================================================================
-// uses the global cfg_t cfg
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_CreateMapBrushes(mapbrush_t *brush, entity_t *mapent, int addbevels)
-{
- int i;
- //side_t *s;
- mapbrush_t *bboxbrushes[16];
-
- //if the brushes are not from an entity used for AAS
- if (!AAS_ValidEntity(mapent))
- {
- nummapbrushsides -= brush->numsides;
- brush->numsides = 0;
- return;
- } //end if
- //
- AAS_PositionBrush(mapent, brush);
- //from all normal solid brushes only the textured brush sides will
- //be used as bsp splitters, so set the right texinfo reference here
- AAS_SetTexinfo(brush);
- //remove contents detail flag, otherwise player clip contents won't be
- //bsped correctly for AAS!
- brush->contents &= ~CONTENTS_DETAIL;
- //if the brush has contents area portal it should be the only contents
- if (brush->contents & (CONTENTS_AREAPORTAL|CONTENTS_CLUSTERPORTAL))
- {
- brush->contents = CONTENTS_CLUSTERPORTAL;
- brush->leafnum = -1;
- } //end if
- //window and playerclip are used for player clipping, make them solid
- if (brush->contents & (CONTENTS_WINDOW | CONTENTS_PLAYERCLIP))
- {
- //
- brush->contents &= ~(CONTENTS_WINDOW | CONTENTS_PLAYERCLIP);
- brush->contents |= CONTENTS_SOLID;
- brush->leafnum = -1;
- } //end if
- //
- if (brush->contents & CONTENTS_BOTCLIP)
- {
- brush->contents = CONTENTS_SOLID;
- brush->leafnum = -1;
- } //end if
- //
- //Log_Write("brush %d contents = ", brush->brushnum);
- //PrintContents(brush->contents);
- //Log_Write("\r\n");
- //if not one of the following brushes then the brush is NOT used for AAS
- if (!(brush->contents & (CONTENTS_SOLID
- | CONTENTS_LADDER
- | CONTENTS_CLUSTERPORTAL
- | CONTENTS_DONOTENTER
- | CONTENTS_TELEPORTER
- | CONTENTS_JUMPPAD
- | CONTENTS_WATER
- | CONTENTS_LAVA
- | CONTENTS_SLIME
- | CONTENTS_MOVER
- )))
- {
- nummapbrushsides -= brush->numsides;
- brush->numsides = 0;
- return;
- } //end if
- //fix the map brush
- //AAS_FixMapBrush(brush);
- //if brush bevels should be added (for real map brushes, not bsp map brushes)
- if (addbevels)
- {
- //NOTE: we first have to get the mins and maxs of the brush before
- // creating the brush bevels... the mins and maxs are used to
- // create them. so we call MakeBrushWindings to get the mins
- // and maxs and then after creating the bevels we free the
- // windings because they are created for all sides (including
- // bevels) a little later
- AAS_MakeBrushWindings(brush);
- AddBrushBevels(brush);
- FreeBrushWindings(brush);
- } //end if
- //NOTE: add the brush to the WORLD entity!!!
- mapent = &entities[0];
- //there's at least one new brush for now
- nummapbrushes++;
- mapent->numbrushes++;
- //liquid brushes are expanded for the maximum possible bounding box
- if (brush->contents & (CONTENTS_WATER
- | CONTENTS_LAVA
- | CONTENTS_SLIME
- | CONTENTS_TELEPORTER
- | CONTENTS_JUMPPAD
- | CONTENTS_DONOTENTER
- | CONTENTS_MOVER
- ))
- {
- brush->expansionbbox = 0;
- //NOTE: the first bounding box is the max
- //FIXME: use max bounding box created from all bboxes
- AAS_ExpandMapBrush(brush, cfg.bboxes[0].mins, cfg.bboxes[0].maxs);
- AAS_MakeBrushWindings(brush);
- } //end if
- //area portal brushes are NOT expanded
- else if (brush->contents & CONTENTS_CLUSTERPORTAL)
- {
- brush->expansionbbox = 0;
- //NOTE: the first bounding box is the max
- //FIXME: use max bounding box created from all bboxes
- AAS_ExpandMapBrush(brush, cfg.bboxes[0].mins, cfg.bboxes[0].maxs);
- AAS_MakeBrushWindings(brush);
- } //end if
- //all solid brushes are expanded for all bounding boxes
- else if (brush->contents & (CONTENTS_SOLID
- | CONTENTS_LADDER
- ))
- {
- //brush for the first bounding box
- bboxbrushes[0] = brush;
- //make a copy for the other bounding boxes
- for (i = 1; i < cfg.numbboxes; i++)
- {
- bboxbrushes[i] = AAS_CopyMapBrush(brush, mapent);
- } //end for
- //expand every brush for it's bounding box and create windings
- for (i = 0; i < cfg.numbboxes; i++)
- {
- AAS_ExpandMapBrush(bboxbrushes[i], cfg.bboxes[i].mins, cfg.bboxes[i].maxs);
- bboxbrushes[i]->expansionbbox = cfg.bboxes[i].presencetype;
- AAS_MakeBrushWindings(bboxbrushes[i]);
- } //end for
- } //end else
-} //end of the function AAS_CreateMapBrushes
diff --git a/code/bspc/aas_map.h b/code/bspc/aas_map.h
deleted file mode 100644
index 4680a2f..0000000
--- a/code/bspc/aas_map.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-void AAS_CreateMapBrushes(mapbrush_t *brush, entity_t *mapent, int addbevels);
diff --git a/code/bspc/aas_prunenodes.c b/code/bspc/aas_prunenodes.c
deleted file mode 100644
index e0f97ac..0000000
--- a/code/bspc/aas_prunenodes.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-#include "qbsp.h"
-#include "../botlib/aasfile.h"
-#include "aas_create.h"
-
-int c_numprunes;
-
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-tmp_node_t *AAS_PruneNodes_r(tmp_node_t *tmpnode)
-{
- tmp_area_t *tmparea1, *tmparea2;
-
- //if it is a solid leaf
- if (!tmpnode) return NULL;
- //
- if (tmpnode->tmparea) return tmpnode;
- //process the children first
- tmpnode->children[0] = AAS_PruneNodes_r(tmpnode->children[0]);
- tmpnode->children[1] = AAS_PruneNodes_r(tmpnode->children[1]);
- //if both children are areas
- if (tmpnode->children[0] && tmpnode->children[1] &&
- tmpnode->children[0]->tmparea && tmpnode->children[1]->tmparea)
- {
- tmparea1 = tmpnode->children[0]->tmparea;
- while(tmparea1->mergedarea) tmparea1 = tmparea1->mergedarea;
-
- tmparea2 = tmpnode->children[1]->tmparea;
- while(tmparea2->mergedarea) tmparea2 = tmparea2->mergedarea;
-
- if (tmparea1 == tmparea2)
- {
- c_numprunes++;
- tmpnode->tmparea = tmparea1;
- tmpnode->planenum = 0;
- AAS_FreeTmpNode(tmpnode->children[0]);
- AAS_FreeTmpNode(tmpnode->children[1]);
- tmpnode->children[0] = NULL;
- tmpnode->children[1] = NULL;
- return tmpnode;
- } //end if
- } //end if
- //if both solid leafs
- if (!tmpnode->children[0] && !tmpnode->children[1])
- {
- c_numprunes++;
- AAS_FreeTmpNode(tmpnode);
- return NULL;
- } //end if
- //
- return tmpnode;
-} //end of the function AAS_PruneNodes_r
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_PruneNodes(void)
-{
- Log_Write("AAS_PruneNodes\r\n");
- AAS_PruneNodes_r(tmpaasworld.nodes);
- Log_Print("%6d nodes pruned\r\n", c_numprunes);
-} //end of the function AAS_PruneNodes
diff --git a/code/bspc/aas_prunenodes.h b/code/bspc/aas_prunenodes.h
deleted file mode 100644
index 417675b..0000000
--- a/code/bspc/aas_prunenodes.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-void AAS_PruneNodes(void);
-
diff --git a/code/bspc/aas_store.c b/code/bspc/aas_store.c
deleted file mode 100644
index 1be5119..0000000
--- a/code/bspc/aas_store.c
+++ /dev/null
@@ -1,1082 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-#include "qbsp.h"
-#include "../botlib/aasfile.h"
-#include "aas_file.h"
-#include "aas_store.h"
-#include "aas_create.h"
-#include "aas_cfg.h"
-
-
-//#define NOTHREEVERTEXFACES
-
-#define STOREPLANESDOUBLE
-
-#define VERTEX_EPSILON 0.1 //NOTE: changed from 0.5
-#define DIST_EPSILON 0.05 //NOTE: changed from 0.9
-#define NORMAL_EPSILON 0.0001 //NOTE: changed from 0.005
-#define INTEGRAL_EPSILON 0.01
-
-#define VERTEX_HASHING
-#define VERTEX_HASH_SHIFT 7
-#define VERTEX_HASH_SIZE ((MAX_MAP_BOUNDS>>(VERTEX_HASH_SHIFT-1))+1) //was 64
-//
-#define PLANE_HASHING
-#define PLANE_HASH_SIZE 1024 //must be power of 2
-//
-#define EDGE_HASHING
-#define EDGE_HASH_SIZE 1024 //must be power of 2
-
-aas_t aasworld;
-
-//vertex hash
-int *aas_vertexchain; // the next vertex in a hash chain
-int aas_hashverts[VERTEX_HASH_SIZE*VERTEX_HASH_SIZE]; // a vertex number, or 0 for no verts
-//plane hash
-int *aas_planechain;
-int aas_hashplanes[PLANE_HASH_SIZE];
-//edge hash
-int *aas_edgechain;
-int aas_hashedges[EDGE_HASH_SIZE];
-
-int allocatedaasmem = 0;
-
-int groundfacesonly = false;//true;
-//
-typedef struct max_aas_s
-{
- int max_bboxes;
- int max_vertexes;
- int max_planes;
- int max_edges;
- int max_edgeindexsize;
- int max_faces;
- int max_faceindexsize;
- int max_areas;
- int max_areasettings;
- int max_reachabilitysize;
- int max_nodes;
- int max_portals;
- int max_portalindexsize;
- int max_clusters;
-} max_aas_t;
-//maximums of everything
-max_aas_t max_aas;
-
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int AAS_CountTmpNodes(tmp_node_t *tmpnode)
-{
- if (!tmpnode) return 0;
- return AAS_CountTmpNodes(tmpnode->children[0]) +
- AAS_CountTmpNodes(tmpnode->children[1]) + 1;
-} //end of the function AAS_CountTmpNodes
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_InitMaxAAS(void)
-{
- int numfaces, numpoints, numareas;
- tmp_face_t *f;
- tmp_area_t *a;
-
- numpoints = 0;
- numfaces = 0;
- for (f = tmpaasworld.faces; f; f = f->l_next)
- {
- numfaces++;
- if (f->winding) numpoints += f->winding->numpoints;
- } //end for
- //
- numareas = 0;
- for (a = tmpaasworld.areas; a; a = a->l_next)
- {
- numareas++;
- } //end for
- max_aas.max_bboxes = AAS_MAX_BBOXES;
- max_aas.max_vertexes = numpoints + 1;
- max_aas.max_planes = nummapplanes;
- max_aas.max_edges = numpoints + 1;
- max_aas.max_edgeindexsize = (numpoints + 1) * 3;
- max_aas.max_faces = numfaces + 10;
- max_aas.max_faceindexsize = (numfaces + 10) * 2;
- max_aas.max_areas = numareas + 10;
- max_aas.max_areasettings = numareas + 10;
- max_aas.max_reachabilitysize = 0;
- max_aas.max_nodes = AAS_CountTmpNodes(tmpaasworld.nodes) + 10;
- max_aas.max_portals = 0;
- max_aas.max_portalindexsize = 0;
- max_aas.max_clusters = 0;
-} //end of the function AAS_InitMaxAAS
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_AllocMaxAAS(void)
-{
- int i;
-
- AAS_InitMaxAAS();
- //bounding boxes
- aasworld.numbboxes = 0;
- aasworld.bboxes = (aas_bbox_t *) GetClearedMemory(max_aas.max_bboxes * sizeof(aas_bbox_t));
- allocatedaasmem += max_aas.max_bboxes * sizeof(aas_bbox_t);
- //vertexes
- aasworld.numvertexes = 0;
- aasworld.vertexes = (aas_vertex_t *) GetClearedMemory(max_aas.max_vertexes * sizeof(aas_vertex_t));
- allocatedaasmem += max_aas.max_vertexes * sizeof(aas_vertex_t);
- //planes
- aasworld.numplanes = 0;
- aasworld.planes = (aas_plane_t *) GetClearedMemory(max_aas.max_planes * sizeof(aas_plane_t));
- allocatedaasmem += max_aas.max_planes * sizeof(aas_plane_t);
- //edges
- aasworld.numedges = 0;
- aasworld.edges = (aas_edge_t *) GetClearedMemory(max_aas.max_edges * sizeof(aas_edge_t));
- allocatedaasmem += max_aas.max_edges * sizeof(aas_edge_t);
- //edge index
- aasworld.edgeindexsize = 0;
- aasworld.edgeindex = (aas_edgeindex_t *) GetClearedMemory(max_aas.max_edgeindexsize * sizeof(aas_edgeindex_t));
- allocatedaasmem += max_aas.max_edgeindexsize * sizeof(aas_edgeindex_t);
- //faces
- aasworld.numfaces = 0;
- aasworld.faces = (aas_face_t *) GetClearedMemory(max_aas.max_faces * sizeof(aas_face_t));
- allocatedaasmem += max_aas.max_faces * sizeof(aas_face_t);
- //face index
- aasworld.faceindexsize = 0;
- aasworld.faceindex = (aas_faceindex_t *) GetClearedMemory(max_aas.max_faceindexsize * sizeof(aas_faceindex_t));
- allocatedaasmem += max_aas.max_faceindexsize * sizeof(aas_faceindex_t);
- //convex areas
- aasworld.numareas = 0;
- aasworld.areas = (aas_area_t *) GetClearedMemory(max_aas.max_areas * sizeof(aas_area_t));
- allocatedaasmem += max_aas.max_areas * sizeof(aas_area_t);
- //convex area settings
- aasworld.numareasettings = 0;
- aasworld.areasettings = (aas_areasettings_t *) GetClearedMemory(max_aas.max_areasettings * sizeof(aas_areasettings_t));
- allocatedaasmem += max_aas.max_areasettings * sizeof(aas_areasettings_t);
- //reachablity list
- aasworld.reachabilitysize = 0;
- aasworld.reachability = (aas_reachability_t *) GetClearedMemory(max_aas.max_reachabilitysize * sizeof(aas_reachability_t));
- allocatedaasmem += max_aas.max_reachabilitysize * sizeof(aas_reachability_t);
- //nodes of the bsp tree
- aasworld.numnodes = 0;
- aasworld.nodes = (aas_node_t *) GetClearedMemory(max_aas.max_nodes * sizeof(aas_node_t));
- allocatedaasmem += max_aas.max_nodes * sizeof(aas_node_t);
- //cluster portals
- aasworld.numportals = 0;
- aasworld.portals = (aas_portal_t *) GetClearedMemory(max_aas.max_portals * sizeof(aas_portal_t));
- allocatedaasmem += max_aas.max_portals * sizeof(aas_portal_t);
- //cluster portal index
- aasworld.portalindexsize = 0;
- aasworld.portalindex = (aas_portalindex_t *) GetClearedMemory(max_aas.max_portalindexsize * sizeof(aas_portalindex_t));
- allocatedaasmem += max_aas.max_portalindexsize * sizeof(aas_portalindex_t);
- //cluster
- aasworld.numclusters = 0;
- aasworld.clusters = (aas_cluster_t *) GetClearedMemory(max_aas.max_clusters * sizeof(aas_cluster_t));
- allocatedaasmem += max_aas.max_clusters * sizeof(aas_cluster_t);
- //
- Log_Print("allocated ");
- PrintMemorySize(allocatedaasmem);
- Log_Print(" of AAS memory\n");
- //reset the has stuff
- aas_vertexchain = (int *) GetClearedMemory(max_aas.max_vertexes * sizeof(int));
- aas_planechain = (int *) GetClearedMemory(max_aas.max_planes * sizeof(int));
- aas_edgechain = (int *) GetClearedMemory(max_aas.max_edges * sizeof(int));
- //
- for (i = 0; i < max_aas.max_vertexes; i++) aas_vertexchain[i] = -1;
- for (i = 0; i < VERTEX_HASH_SIZE * VERTEX_HASH_SIZE; i++) aas_hashverts[i] = -1;
- //
- for (i = 0; i < max_aas.max_planes; i++) aas_planechain[i] = -1;
- for (i = 0; i < PLANE_HASH_SIZE; i++) aas_hashplanes[i] = -1;
- //
- for (i = 0; i < max_aas.max_edges; i++) aas_edgechain[i] = -1;
- for (i = 0; i < EDGE_HASH_SIZE; i++) aas_hashedges[i] = -1;
-} //end of the function AAS_AllocMaxAAS
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_FreeMaxAAS(void)
-{
- //bounding boxes
- if (aasworld.bboxes) FreeMemory(aasworld.bboxes);
- aasworld.bboxes = NULL;
- aasworld.numbboxes = 0;
- //vertexes
- if (aasworld.vertexes) FreeMemory(aasworld.vertexes);
- aasworld.vertexes = NULL;
- aasworld.numvertexes = 0;
- //planes
- if (aasworld.planes) FreeMemory(aasworld.planes);
- aasworld.planes = NULL;
- aasworld.numplanes = 0;
- //edges
- if (aasworld.edges) FreeMemory(aasworld.edges);
- aasworld.edges = NULL;
- aasworld.numedges = 0;
- //edge index
- if (aasworld.edgeindex) FreeMemory(aasworld.edgeindex);
- aasworld.edgeindex = NULL;
- aasworld.edgeindexsize = 0;
- //faces
- if (aasworld.faces) FreeMemory(aasworld.faces);
- aasworld.faces = NULL;
- aasworld.numfaces = 0;
- //face index
- if (aasworld.faceindex) FreeMemory(aasworld.faceindex);
- aasworld.faceindex = NULL;
- aasworld.faceindexsize = 0;
- //convex areas
- if (aasworld.areas) FreeMemory(aasworld.areas);
- aasworld.areas = NULL;
- aasworld.numareas = 0;
- //convex area settings
- if (aasworld.areasettings) FreeMemory(aasworld.areasettings);
- aasworld.areasettings = NULL;
- aasworld.numareasettings = 0;
- //reachablity list
- if (aasworld.reachability) FreeMemory(aasworld.reachability);
- aasworld.reachability = NULL;
- aasworld.reachabilitysize = 0;
- //nodes of the bsp tree
- if (aasworld.nodes) FreeMemory(aasworld.nodes);
- aasworld.nodes = NULL;
- aasworld.numnodes = 0;
- //cluster portals
- if (aasworld.portals) FreeMemory(aasworld.portals);
- aasworld.portals = NULL;
- aasworld.numportals = 0;
- //cluster portal index
- if (aasworld.portalindex) FreeMemory(aasworld.portalindex);
- aasworld.portalindex = NULL;
- aasworld.portalindexsize = 0;
- //clusters
- if (aasworld.clusters) FreeMemory(aasworld.clusters);
- aasworld.clusters = NULL;
- aasworld.numclusters = 0;
-
- Log_Print("freed ");
- PrintMemorySize(allocatedaasmem);
- Log_Print(" of AAS memory\n");
- allocatedaasmem = 0;
- //
- if (aas_vertexchain) FreeMemory(aas_vertexchain);
- aas_vertexchain = NULL;
- if (aas_planechain) FreeMemory(aas_planechain);
- aas_planechain = NULL;
- if (aas_edgechain) FreeMemory(aas_edgechain);
- aas_edgechain = NULL;
-} //end of the function AAS_FreeMaxAAS
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-unsigned AAS_HashVec(vec3_t vec)
-{
- int x, y;
-
- x = (MAX_MAP_BOUNDS + (int)(vec[0]+0.5)) >> VERTEX_HASH_SHIFT;
- y = (MAX_MAP_BOUNDS + (int)(vec[1]+0.5)) >> VERTEX_HASH_SHIFT;
-
- if (x < 0 || x >= VERTEX_HASH_SIZE || y < 0 || y >= VERTEX_HASH_SIZE)
- {
- Log_Print("WARNING! HashVec: point %f %f %f outside valid range\n", vec[0], vec[1], vec[2]);
- Log_Print("This should never happen!\n");
- return -1;
- } //end if
-
- return y*VERTEX_HASH_SIZE + x;
-} //end of the function AAS_HashVec
-//===========================================================================
-// returns true if the vertex was found in the list
-// stores the vertex number in *vnum
-// stores a new vertex if not stored already
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-qboolean AAS_GetVertex(vec3_t v, int *vnum)
-{
- int i;
-#ifndef VERTEX_HASHING
- float diff;
-#endif //VERTEX_HASHING
-
-#ifdef VERTEX_HASHING
- int h, vn;
- vec3_t vert;
-
- for (i = 0; i < 3; i++)
- {
- if ( fabs(v[i] - Q_rint(v[i])) < INTEGRAL_EPSILON)
- vert[i] = Q_rint(v[i]);
- else
- vert[i] = v[i];
- } //end for
-
- h = AAS_HashVec(vert);
- //if the vertex was outside the valid range
- if (h == -1)
- {
- *vnum = -1;
- return true;
- } //end if
-
- for (vn = aas_hashverts[h]; vn >= 0; vn = aas_vertexchain[vn])
- {
- if (fabs(aasworld.vertexes[vn][0] - vert[0]) < VERTEX_EPSILON
- && fabs(aasworld.vertexes[vn][1] - vert[1]) < VERTEX_EPSILON
- && fabs(aasworld.vertexes[vn][2] - vert[2]) < VERTEX_EPSILON)
- {
- *vnum = vn;
- return true;
- } //end if
- } //end for
-#else //VERTEX_HASHING
- //check if the vertex is already stored
- //stupid linear search
- for (i = 0; i < aasworld.numvertexes; i++)
- {
- diff = vert[0] - aasworld.vertexes[i][0];
- if (diff < VERTEX_EPSILON && diff > -VERTEX_EPSILON)
- {
- diff = vert[1] - aasworld.vertexes[i][1];
- if (diff < VERTEX_EPSILON && diff > -VERTEX_EPSILON)
- {
- diff = vert[2] - aasworld.vertexes[i][2];
- if (diff < VERTEX_EPSILON && diff > -VERTEX_EPSILON)
- {
- *vnum = i;
- return true;
- } //end if
- } //end if
- } //end if
- } //end for
-#endif //VERTEX_HASHING
-
- if (aasworld.numvertexes >= max_aas.max_vertexes)
- {
- Error("AAS_MAX_VERTEXES = %d", max_aas.max_vertexes);
- } //end if
- VectorCopy(vert, aasworld.vertexes[aasworld.numvertexes]);
- *vnum = aasworld.numvertexes;
-
-#ifdef VERTEX_HASHING
- aas_vertexchain[aasworld.numvertexes] = aas_hashverts[h];
- aas_hashverts[h] = aasworld.numvertexes;
-#endif //VERTEX_HASHING
-
- aasworld.numvertexes++;
- return false;
-} //end of the function AAS_GetVertex
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-unsigned AAS_HashEdge(int v1, int v2)
-{
- int vnum1, vnum2;
- //
- if (v1 < v2)
- {
- vnum1 = v1;
- vnum2 = v2;
- } //end if
- else
- {
- vnum1 = v2;
- vnum2 = v1;
- } //end else
- return (vnum1 + vnum2) & (EDGE_HASH_SIZE-1);
-} //end of the function AAS_HashVec
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_AddEdgeToHash(int edgenum)
-{
- int hash;
- aas_edge_t *edge;
-
- edge = &aasworld.edges[edgenum];
-
- hash = AAS_HashEdge(edge->v[0], edge->v[1]);
-
- aas_edgechain[edgenum] = aas_hashedges[hash];
- aas_hashedges[hash] = edgenum;
-} //end of the function AAS_AddEdgeToHash
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-qboolean AAS_FindHashedEdge(int v1num, int v2num, int *edgenum)
-{
- int e, hash;
- aas_edge_t *edge;
-
- hash = AAS_HashEdge(v1num, v2num);
- for (e = aas_hashedges[hash]; e >= 0; e = aas_edgechain[e])
- {
- edge = &aasworld.edges[e];
- if (edge->v[0] == v1num)
- {
- if (edge->v[1] == v2num)
- {
- *edgenum = e;
- return true;
- } //end if
- } //end if
- else if (edge->v[1] == v1num)
- {
- if (edge->v[0] == v2num)
- {
- //negative for a reversed edge
- *edgenum = -e;
- return true;
- } //end if
- } //end else
- } //end for
- return false;
-} //end of the function AAS_FindHashedPlane
-//===========================================================================
-// returns true if the edge was found
-// stores the edge number in *edgenum (negative if reversed edge)
-// stores new edge if not stored already
-// returns zero when the edge is degenerate
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-qboolean AAS_GetEdge(vec3_t v1, vec3_t v2, int *edgenum)
-{
- int v1num, v2num;
- qboolean found;
-
- //the first edge is a dummy
- if (aasworld.numedges == 0) aasworld.numedges = 1;
-
- found = AAS_GetVertex(v1, &v1num);
- found &= AAS_GetVertex(v2, &v2num);
- //if one of the vertexes was outside the valid range
- if (v1num == -1 || v2num == -1)
- {
- *edgenum = 0;
- return true;
- } //end if
- //if both vertexes are the same or snapped onto each other
- if (v1num == v2num)
- {
- *edgenum = 0;
- return true;
- } //end if
- //if both vertexes where already stored
- if (found)
- {
-#ifdef EDGE_HASHING
- if (AAS_FindHashedEdge(v1num, v2num, edgenum)) return true;
-#else
- int i;
- for (i = 1; i < aasworld.numedges; i++)
- {
- if (aasworld.edges[i].v[0] == v1num)
- {
- if (aasworld.edges[i].v[1] == v2num)
- {
- *edgenum = i;
- return true;
- } //end if
- } //end if
- else if (aasworld.edges[i].v[1] == v1num)
- {
- if (aasworld.edges[i].v[0] == v2num)
- {
- //negative for a reversed edge
- *edgenum = -i;
- return true;
- } //end if
- } //end else
- } //end for
-#endif //EDGE_HASHING
- } //end if
- if (aasworld.numedges >= max_aas.max_edges)
- {
- Error("AAS_MAX_EDGES = %d", max_aas.max_edges);
- } //end if
- aasworld.edges[aasworld.numedges].v[0] = v1num;
- aasworld.edges[aasworld.numedges].v[1] = v2num;
- *edgenum = aasworld.numedges;
-#ifdef EDGE_HASHING
- AAS_AddEdgeToHash(*edgenum);
-#endif //EDGE_HASHING
- aasworld.numedges++;
- return false;
-} //end of the function AAS_GetEdge
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int AAS_PlaneTypeForNormal(vec3_t normal)
-{
- vec_t ax, ay, az;
-
- //NOTE: epsilon used
- if ( (normal[0] >= 1.0 -NORMAL_EPSILON) ||
- (normal[0] <= -1.0 + NORMAL_EPSILON)) return PLANE_X;
- if ( (normal[1] >= 1.0 -NORMAL_EPSILON) ||
- (normal[1] <= -1.0 + NORMAL_EPSILON)) return PLANE_Y;
- if ( (normal[2] >= 1.0 -NORMAL_EPSILON) ||
- (normal[2] <= -1.0 + NORMAL_EPSILON)) return PLANE_Z;
-
- ax = fabs(normal[0]);
- ay = fabs(normal[1]);
- az = fabs(normal[2]);
-
- if (ax >= ay && ax >= az) return PLANE_ANYX;
- if (ay >= ax && ay >= az) return PLANE_ANYY;
- return PLANE_ANYZ;
-} //end of the function AAS_PlaneTypeForNormal
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_AddPlaneToHash(int planenum)
-{
- int hash;
- aas_plane_t *plane;
-
- plane = &aasworld.planes[planenum];
-
- hash = (int)fabs(plane->dist) / 8;
- hash &= (PLANE_HASH_SIZE-1);
-
- aas_planechain[planenum] = aas_hashplanes[hash];
- aas_hashplanes[hash] = planenum;
-} //end of the function AAS_AddPlaneToHash
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int AAS_PlaneEqual(vec3_t normal, float dist, int planenum)
-{
- float diff;
-
- diff = dist - aasworld.planes[planenum].dist;
- if (diff > -DIST_EPSILON && diff < DIST_EPSILON)
- {
- diff = normal[0] - aasworld.planes[planenum].normal[0];
- if (diff > -NORMAL_EPSILON && diff < NORMAL_EPSILON)
- {
- diff = normal[1] - aasworld.planes[planenum].normal[1];
- if (diff > -NORMAL_EPSILON && diff < NORMAL_EPSILON)
- {
- diff = normal[2] - aasworld.planes[planenum].normal[2];
- if (diff > -NORMAL_EPSILON && diff < NORMAL_EPSILON)
- {
- return true;
- } //end if
- } //end if
- } //end if
- } //end if
- return false;
-} //end of the function AAS_PlaneEqual
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-qboolean AAS_FindPlane(vec3_t normal, float dist, int *planenum)
-{
- int i;
-
- for (i = 0; i < aasworld.numplanes; i++)
- {
- if (AAS_PlaneEqual(normal, dist, i))
- {
- *planenum = i;
- return true;
- } //end if
- } //end for
- return false;
-} //end of the function AAS_FindPlane
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-qboolean AAS_FindHashedPlane(vec3_t normal, float dist, int *planenum)
-{
- int i, p;
- aas_plane_t *plane;
- int hash, h;
-
- hash = (int)fabs(dist) / 8;
- hash &= (PLANE_HASH_SIZE-1);
-
- //search the border bins as well
- for (i = -1; i <= 1; i++)
- {
- h = (hash+i)&(PLANE_HASH_SIZE-1);
- for (p = aas_hashplanes[h]; p >= 0; p = aas_planechain[p])
- {
- plane = &aasworld.planes[p];
- if (AAS_PlaneEqual(normal, dist, p))
- {
- *planenum = p;
- return true;
- } //end if
- } //end for
- } //end for
- return false;
-} //end of the function AAS_FindHashedPlane
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-qboolean AAS_GetPlane(vec3_t normal, vec_t dist, int *planenum)
-{
- aas_plane_t *plane, temp;
-
- //if (AAS_FindPlane(normal, dist, planenum)) return true;
- if (AAS_FindHashedPlane(normal, dist, planenum)) return true;
-
- if (aasworld.numplanes >= max_aas.max_planes-1)
- {
- Error("AAS_MAX_PLANES = %d", max_aas.max_planes);
- } //end if
-
-#ifdef STOREPLANESDOUBLE
- plane = &aasworld.planes[aasworld.numplanes];
- VectorCopy(normal, plane->normal);
- plane->dist = dist;
- plane->type = (plane+1)->type = PlaneTypeForNormal(plane->normal);
-
- VectorCopy(normal, (plane+1)->normal);
- VectorNegate((plane+1)->normal, (plane+1)->normal);
- (plane+1)->dist = -dist;
-
- aasworld.numplanes += 2;
-
- //allways put axial planes facing positive first
- if (plane->type < 3)
- {
- if (plane->normal[0] < 0 || plane->normal[1] < 0 || plane->normal[2] < 0)
- {
- // flip order
- temp = *plane;
- *plane = *(plane+1);
- *(plane+1) = temp;
- *planenum = aasworld.numplanes - 1;
- return false;
- } //end if
- } //end if
- *planenum = aasworld.numplanes - 2;
- //add the planes to the hash
- AAS_AddPlaneToHash(aasworld.numplanes - 1);
- AAS_AddPlaneToHash(aasworld.numplanes - 2);
- return false;
-#else
- plane = &aasworld.planes[aasworld.numplanes];
- VectorCopy(normal, plane->normal);
- plane->dist = dist;
- plane->type = AAS_PlaneTypeForNormal(normal);
-
- *planenum = aasworld.numplanes;
- aasworld.numplanes++;
- //add the plane to the hash
- AAS_AddPlaneToHash(aasworld.numplanes - 1);
- return false;
-#endif //STOREPLANESDOUBLE
-} //end of the function AAS_GetPlane
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-qboolean AAS_GetFace(winding_t *w, plane_t *p, int side, int *facenum)
-{
- int edgenum, i, j;
- aas_face_t *face;
-
- //face zero is a dummy, because of the face index with negative numbers
- if (aasworld.numfaces == 0) aasworld.numfaces = 1;
-
- if (aasworld.numfaces >= max_aas.max_faces)
- {
- Error("AAS_MAX_FACES = %d", max_aas.max_faces);
- } //end if
- face = &aasworld.faces[aasworld.numfaces];
- AAS_GetPlane(p->normal, p->dist, &face->planenum);
- face->faceflags = 0;
- face->firstedge = aasworld.edgeindexsize;
- face->frontarea = 0;
- face->backarea = 0;
- face->numedges = 0;
- for (i = 0; i < w->numpoints; i++)
- {
- if (aasworld.edgeindexsize >= max_aas.max_edgeindexsize)
- {
- Error("AAS_MAX_EDGEINDEXSIZE = %d", max_aas.max_edgeindexsize);
- } //end if
- j = (i+1) % w->numpoints;
- AAS_GetEdge(w->p[i], w->p[j], &edgenum);
- //if the edge wasn't degenerate
- if (edgenum)
- {
- aasworld.edgeindex[aasworld.edgeindexsize++] = edgenum;
- face->numedges++;
- } //end if
- else if (verbose)
- {
- Log_Write("AAS_GetFace: face %d had degenerate edge %d-%d\r\n",
- aasworld.numfaces, i, j);
- } //end else
- } //end for
- if (face->numedges < 1
-#ifdef NOTHREEVERTEXFACES
- || face->numedges < 3
-#endif //NOTHREEVERTEXFACES
- )
- {
- memset(&aasworld.faces[aasworld.numfaces], 0, sizeof(aas_face_t));
- Log_Write("AAS_GetFace: face %d was tiny\r\n", aasworld.numfaces);
- return false;
- } //end if
- *facenum = aasworld.numfaces;
- aasworld.numfaces++;
- return true;
-} //end of the function AAS_GetFace
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-/*
-qboolean AAS_GetFace(winding_t *w, plane_t *p, int side, int *facenum)
-{
- aas_edgeindex_t edges[1024];
- int planenum, numedges, i;
- int j, edgenum;
- qboolean foundplane, foundedges;
- aas_face_t *face;
-
- //face zero is a dummy, because of the face index with negative numbers
- if (aasworld.numfaces == 0) aasworld.numfaces = 1;
-
- foundplane = AAS_GetPlane(p->normal, p->dist, &planenum);
-
- foundedges = true;
- numedges = w->numpoints;
- for (i = 0; i < w->numpoints; i++)
- {
- if (i >= 1024) Error("AAS_GetFace: more than %d edges\n", 1024);
- foundedges &= AAS_GetEdge(w->p[i], w->p[(i+1 >= w->numpoints ? 0 : i+1)], &edges[i]);
- } //end for
-
- //FIXME: use portal number instead of a search
- //if the plane and all edges already existed
- if (foundplane && foundedges)
- {
- for (i = 0; i < aasworld.numfaces; i++)
- {
- face = &aasworld.faces[i];
- if (planenum == face->planenum)
- {
- if (numedges == face->numedges)
- {
- for (j = 0; j < numedges; j++)
- {
- edgenum = abs(aasworld.edgeindex[face->firstedge + j]);
- if (abs(edges[i]) != edgenum) break;
- } //end for
- if (j == numedges)
- {
- //jippy found the face
- *facenum = -i;
- return true;
- } //end if
- } //end if
- } //end if
- } //end for
- } //end if
- if (aasworld.numfaces >= max_aas.max_faces)
- {
- Error("AAS_MAX_FACES = %d", max_aas.max_faces);
- } //end if
- face = &aasworld.faces[aasworld.numfaces];
- face->planenum = planenum;
- face->faceflags = 0;
- face->numedges = numedges;
- face->firstedge = aasworld.edgeindexsize;
- face->frontarea = 0;
- face->backarea = 0;
- for (i = 0; i < numedges; i++)
- {
- if (aasworld.edgeindexsize >= max_aas.max_edgeindexsize)
- {
- Error("AAS_MAX_EDGEINDEXSIZE = %d", max_aas.max_edgeindexsize);
- } //end if
- aasworld.edgeindex[aasworld.edgeindexsize++] = edges[i];
- } //end for
- *facenum = aasworld.numfaces;
- aasworld.numfaces++;
- return false;
-} //end of the function AAS_GetFace*/
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_StoreAreaSettings(tmp_areasettings_t *tmpareasettings)
-{
- aas_areasettings_t *areasettings;
-
- if (aasworld.numareasettings == 0) aasworld.numareasettings = 1;
- areasettings = &aasworld.areasettings[aasworld.numareasettings++];
- areasettings->areaflags = tmpareasettings->areaflags;
- areasettings->presencetype = tmpareasettings->presencetype;
- areasettings->contents = tmpareasettings->contents;
- if (tmpareasettings->modelnum > AREACONTENTS_MAXMODELNUM)
- Log_Print("WARNING: more than %d mover models\n", AREACONTENTS_MAXMODELNUM);
- areasettings->contents |= (tmpareasettings->modelnum & AREACONTENTS_MAXMODELNUM) << AREACONTENTS_MODELNUMSHIFT;
-} //end of the function AAS_StoreAreaSettings
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int AAS_StoreArea(tmp_area_t *tmparea)
-{
- int side, edgenum, i;
- plane_t *plane;
- tmp_face_t *tmpface;
- aas_area_t *aasarea;
- aas_edge_t *edge;
- aas_face_t *aasface;
- aas_faceindex_t aasfacenum;
- vec3_t facecenter;
- winding_t *w;
-
- //when the area is merged go to the merged area
- //FIXME: this isn't necessary anymore because the tree
- // is refreshed after area merging
- while(tmparea->mergedarea) tmparea = tmparea->mergedarea;
- //
- if (tmparea->invalid) Error("AAS_StoreArea: tried to store invalid area");
- //if there is an aas area already stored for this tmp area
- if (tmparea->aasareanum) return -tmparea->aasareanum;
- //
- if (aasworld.numareas >= max_aas.max_areas)
- {
- Error("AAS_MAX_AREAS = %d", max_aas.max_areas);
- } //end if
- //area zero is a dummy
- if (aasworld.numareas == 0) aasworld.numareas = 1;
- //create an area from this leaf
- aasarea = &aasworld.areas[aasworld.numareas];
- aasarea->areanum = aasworld.numareas;
- aasarea->numfaces = 0;
- aasarea->firstface = aasworld.faceindexsize;
- ClearBounds(aasarea->mins, aasarea->maxs);
- VectorClear(aasarea->center);
- //
-// Log_Write("tmparea %d became aasarea %d\r\n", tmparea->areanum, aasarea->areanum);
- //store the aas area number at the tmp area
- tmparea->aasareanum = aasarea->areanum;
- //
- for (tmpface = tmparea->tmpfaces; tmpface; tmpface = tmpface->next[side])
- {
- side = tmpface->frontarea != tmparea;
- //if there's an aas face created for the tmp face already
- if (tmpface->aasfacenum)
- {
- //we're at the back of the face so use a negative index
- aasfacenum = -tmpface->aasfacenum;
-#ifdef DEBUG
- if (tmpface->aasfacenum < 0 || tmpface->aasfacenum > max_aas.max_faces)
- {
- Error("AAS_CreateTree_r: face number out of range");
- } //end if
-#endif //DEBUG
- aasface = &aasworld.faces[tmpface->aasfacenum];
- aasface->backarea = aasarea->areanum;
- } //end if
- else
- {
- plane = &mapplanes[tmpface->planenum ^ side];
- if (side)
- {
- w = tmpface->winding;
- tmpface->winding = ReverseWinding(tmpface->winding);
- } //end if
- if (!AAS_GetFace(tmpface->winding, plane, 0, &aasfacenum)) continue;
- if (side)
- {
- FreeWinding(tmpface->winding);
- tmpface->winding = w;
- } //end if
- aasface = &aasworld.faces[aasfacenum];
- aasface->frontarea = aasarea->areanum;
- aasface->backarea = 0;
- aasface->faceflags = tmpface->faceflags;
- //set the face number at the tmp face
- tmpface->aasfacenum = aasfacenum;
- } //end else
- //add face points to the area bounds and
- //calculate the face 'center'
- VectorClear(facecenter);
- for (edgenum = 0; edgenum < aasface->numedges; edgenum++)
- {
- edge = &aasworld.edges[abs(aasworld.edgeindex[aasface->firstedge + edgenum])];
- for (i = 0; i < 2; i++)
- {
- AddPointToBounds(aasworld.vertexes[edge->v[i]], aasarea->mins, aasarea->maxs);
- VectorAdd(aasworld.vertexes[edge->v[i]], facecenter, facecenter);
- } //end for
- } //end for
- VectorScale(facecenter, 1.0 / (aasface->numedges * 2.0), facecenter);
- //add the face 'center' to the area 'center'
- VectorAdd(aasarea->center, facecenter, aasarea->center);
- //
- if (aasworld.faceindexsize >= max_aas.max_faceindexsize)
- {
- Error("AAS_MAX_FACEINDEXSIZE = %d", max_aas.max_faceindexsize);
- } //end if
- aasworld.faceindex[aasworld.faceindexsize++] = aasfacenum;
- aasarea->numfaces++;
- } //end for
- //if the area has no faces at all (return 0, = solid leaf)
- if (!aasarea->numfaces) return 0;
- //
- VectorScale(aasarea->center, 1.0 / aasarea->numfaces, aasarea->center);
- //Log_Write("area %d center %f %f %f\r\n", aasworld.numareas,
- // aasarea->center[0], aasarea->center[1], aasarea->center[2]);
- //store the area settings
- AAS_StoreAreaSettings(tmparea->settings);
- //
- //Log_Write("tmp area %d became aas area %d\r\n", tmpareanum, aasarea->areanum);
- qprintf("\r%6d", aasarea->areanum);
- //
- aasworld.numareas++;
- return -(aasworld.numareas - 1);
-} //end of the function AAS_StoreArea
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int AAS_StoreTree_r(tmp_node_t *tmpnode)
-{
- int aasnodenum;
- plane_t *plane;
- aas_node_t *aasnode;
-
- //if it is a solid leaf
- if (!tmpnode) return 0;
- //negative so it's an area
- if (tmpnode->tmparea) return AAS_StoreArea(tmpnode->tmparea);
- //it's another node
- //the first node is a dummy
- if (aasworld.numnodes == 0) aasworld.numnodes = 1;
- if (aasworld.numnodes >= max_aas.max_nodes)
- {
- Error("AAS_MAX_NODES = %d", max_aas.max_nodes);
- } //end if
- aasnodenum = aasworld.numnodes;
- aasnode = &aasworld.nodes[aasworld.numnodes++];
- plane = &mapplanes[tmpnode->planenum];
- AAS_GetPlane(plane->normal, plane->dist, &aasnode->planenum);
- aasnode->children[0] = AAS_StoreTree_r(tmpnode->children[0]);
- aasnode->children[1] = AAS_StoreTree_r(tmpnode->children[1]);
- return aasnodenum;
-} //end of the function AAS_StoreTree_r
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_StoreBoundingBoxes(void)
-{
- if (cfg.numbboxes > max_aas.max_bboxes)
- {
- Error("more than %d bounding boxes", max_aas.max_bboxes);
- } //end if
- aasworld.numbboxes = cfg.numbboxes;
- memcpy(aasworld.bboxes, cfg.bboxes, cfg.numbboxes * sizeof(aas_bbox_t));
-} //end of the function AAS_StoreBoundingBoxes
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_StoreFile(char *filename)
-{
- AAS_AllocMaxAAS();
-
- Log_Write("AAS_StoreFile\r\n");
- //
- AAS_StoreBoundingBoxes();
- //
- qprintf("%6d areas stored", 0);
- //start with node 1 because node zero is a dummy
- AAS_StoreTree_r(tmpaasworld.nodes);
- qprintf("\n");
- Log_Write("%6d areas stored\r\n", aasworld.numareas);
- aasworld.loaded = true;
-} //end of the function AAS_StoreFile
diff --git a/code/bspc/aas_store.h b/code/bspc/aas_store.h
deleted file mode 100644
index 47b1714..0000000
--- a/code/bspc/aas_store.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-#define AAS_MAX_BBOXES 5
-#define AAS_MAX_VERTEXES 512000
-#define AAS_MAX_PLANES 65536
-#define AAS_MAX_EDGES 512000
-#define AAS_MAX_EDGEINDEXSIZE 512000
-#define AAS_MAX_FACES 512000
-#define AAS_MAX_FACEINDEXSIZE 512000
-#define AAS_MAX_AREAS 65536
-#define AAS_MAX_AREASETTINGS 65536
-#define AAS_MAX_REACHABILITYSIZE 65536
-#define AAS_MAX_NODES 256000
-#define AAS_MAX_PORTALS 65536
-#define AAS_MAX_PORTALINDEXSIZE 65536
-#define AAS_MAX_CLUSTERS 65536
-
-#define BSPCINCLUDE
-#include "../botlib/be_aas.h"
-#include "../botlib/be_aas_def.h"
-
-/*
-typedef struct bspc_aas_s
-{
- int loaded;
- int initialized; //true when AAS has been initialized
- int savefile; //set true when file should be saved
- //bounding boxes
- int numbboxes;
- aas_bbox_t *bboxes;
- //vertexes
- int numvertexes;
- aas_vertex_t *vertexes;
- //planes
- int numplanes;
- aas_plane_t *planes;
- //edges
- int numedges;
- aas_edge_t *edges;
- //edge index
- int edgeindexsize;
- aas_edgeindex_t *edgeindex;
- //faces
- int numfaces;
- aas_face_t *faces;
- //face index
- int faceindexsize;
- aas_faceindex_t *faceindex;
- //convex areas
- int numareas;
- aas_area_t *areas;
- //convex area settings
- int numareasettings;
- aas_areasettings_t *areasettings;
- //reachablity list
- int reachabilitysize;
- aas_reachability_t *reachability;
- //nodes of the bsp tree
- int numnodes;
- aas_node_t *nodes;
- //cluster portals
- int numportals;
- aas_portal_t *portals;
- //cluster portal index
- int portalindexsize;
- aas_portalindex_t *portalindex;
- //clusters
- int numclusters;
- aas_cluster_t *clusters;
- //
- int numreachabilityareas;
- float reachabilitytime;
-} bspc_aas_t;
-
-extern bspc_aas_t aasworld;
-//*/
-
-extern aas_t aasworld;
-
-//stores the AAS file from the temporary AAS
-void AAS_StoreFile(char *filename);
-//returns a number of the given plane
-qboolean AAS_FindPlane(vec3_t normal, float dist, int *planenum);
-//allocates the maximum AAS memory for storage
-void AAS_AllocMaxAAS(void);
-//frees the maximum AAS memory for storage
-void AAS_FreeMaxAAS(void);
diff --git a/code/bspc/aasfile.h b/code/bspc/aasfile.h
deleted file mode 100644
index 09979c2..0000000
--- a/code/bspc/aasfile.h
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-
-//NOTE: int = default signed
-// default long
-
-#define AASID (('S'<<24)+('A'<<16)+('A'<<8)+'E')
-#define AASVERSION_OLD 4
-#define AASVERSION 5
-
-//presence types
-#define PRESENCE_NONE 1
-#define PRESENCE_NORMAL 2
-#define PRESENCE_CROUCH 4
-
-//travel types
-#define MAX_TRAVELTYPES 32
-#define TRAVEL_INVALID 1 //temporary not possible
-#define TRAVEL_WALK 2 //walking
-#define TRAVEL_CROUCH 3 //crouching
-#define TRAVEL_BARRIERJUMP 4 //jumping onto a barrier
-#define TRAVEL_JUMP 5 //jumping
-#define TRAVEL_LADDER 6 //climbing a ladder
-#define TRAVEL_WALKOFFLEDGE 7 //walking of a ledge
-#define TRAVEL_SWIM 8 //swimming
-#define TRAVEL_WATERJUMP 9 //jump out of the water
-#define TRAVEL_TELEPORT 10 //teleportation
-#define TRAVEL_ELEVATOR 11 //travel by elevator
-#define TRAVEL_ROCKETJUMP 12 //rocket jumping required for travel
-#define TRAVEL_BFGJUMP 13 //bfg jumping required for travel
-#define TRAVEL_GRAPPLEHOOK 14 //grappling hook required for travel
-#define TRAVEL_DOUBLEJUMP 15 //double jump
-#define TRAVEL_RAMPJUMP 16 //ramp jump
-#define TRAVEL_STRAFEJUMP 17 //strafe jump
-#define TRAVEL_JUMPPAD 18 //jump pad
-#define TRAVEL_FUNCBOB 19 //func bob
-
-//face flags
-#define FACE_SOLID 1 //just solid at the other side
-#define FACE_LADDER 2 //ladder
-#define FACE_GROUND 4 //standing on ground when in this face
-#define FACE_GAP 8 //gap in the ground
-#define FACE_LIQUID 16
-#define FACE_LIQUIDSURFACE 32
-
-//area contents
-#define AREACONTENTS_WATER 1
-#define AREACONTENTS_LAVA 2
-#define AREACONTENTS_SLIME 4
-#define AREACONTENTS_CLUSTERPORTAL 8
-#define AREACONTENTS_TELEPORTAL 16
-#define AREACONTENTS_ROUTEPORTAL 32
-#define AREACONTENTS_TELEPORTER 64
-#define AREACONTENTS_JUMPPAD 128
-#define AREACONTENTS_DONOTENTER 256
-#define AREACONTENTS_VIEWPORTAL 512
-
-//area flags
-#define AREA_GROUNDED 1 //bot can stand on the ground
-#define AREA_LADDER 2 //area contains one or more ladder faces
-#define AREA_LIQUID 4 //area contains a liquid
-
-//aas file header lumps
-#define AAS_LUMPS 14
-#define AASLUMP_BBOXES 0
-#define AASLUMP_VERTEXES 1
-#define AASLUMP_PLANES 2
-#define AASLUMP_EDGES 3
-#define AASLUMP_EDGEINDEX 4
-#define AASLUMP_FACES 5
-#define AASLUMP_FACEINDEX 6
-#define AASLUMP_AREAS 7
-#define AASLUMP_AREASETTINGS 8
-#define AASLUMP_REACHABILITY 9
-#define AASLUMP_NODES 10
-#define AASLUMP_PORTALS 11
-#define AASLUMP_PORTALINDEX 12
-#define AASLUMP_CLUSTERS 13
-
-//========== bounding box =========
-
-//bounding box
-typedef struct aas_bbox_s
-{
- int presencetype;
- int flags;
- vec3_t mins, maxs;
-} aas_bbox_t;
-
-//============ settings ===========
-
-//reachability to another area
-typedef struct aas_reachability_s
-{
- int areanum; //number of the reachable area
- int facenum; //number of the face towards the other area
- int edgenum; //number of the edge towards the other area
- vec3_t start; //start point of inter area movement
- vec3_t end; //end point of inter area movement
- int traveltype; //type of travel required to get to the area
- unsigned short int traveltime;//travel time of the inter area movement
-} aas_reachability_t;
-
-//area settings
-typedef struct aas_areasettings_s
-{
- //could also add all kind of statistic fields
- int contents; //contents of the convex area
- int areaflags; //several area flags
- int presencetype; //how a bot can be present in this convex area
- int cluster; //cluster the area belongs to, if negative it's a portal
- int clusterareanum; //number of the area in the cluster
- int numreachableareas; //number of reachable areas from this one
- int firstreachablearea; //first reachable area in the reachable area index
-} aas_areasettings_t;
-
-//cluster portal
-typedef struct aas_portal_s
-{
- int areanum; //area that is the actual portal
- int frontcluster; //cluster at front of portal
- int backcluster; //cluster at back of portal
- int clusterareanum[2]; //number of the area in the front and back cluster
-} aas_portal_t;
-
-//cluster portal index
-typedef int aas_portalindex_t;
-
-//cluster
-typedef struct aas_cluster_s
-{
- int numareas; //number of areas in the cluster
- int numreachabilityareas; //number of areas with reachabilities
- int numportals; //number of cluster portals
- int firstportal; //first cluster portal in the index
-} aas_cluster_t;
-
-//============ 3d definition ============
-
-typedef vec3_t aas_vertex_t;
-
-//just a plane in the third dimension
-typedef struct aas_plane_s
-{
- vec3_t normal; //normal vector of the plane
- float dist; //distance of the plane (normal vector * distance = point in plane)
- int type;
-} aas_plane_t;
-
-//edge
-typedef struct aas_edge_s
-{
- int v[2]; //numbers of the vertexes of this edge
-} aas_edge_t;
-
-//edge index, negative if vertexes are reversed
-typedef int aas_edgeindex_t;
-
-//a face bounds a convex area, often it will also seperate two convex areas
-typedef struct aas_face_s
-{
- int planenum; //number of the plane this face is in
- int faceflags; //face flags (no use to create face settings for just this field)
- int numedges; //number of edges in the boundary of the face
- int firstedge; //first edge in the edge index
- int frontarea; //convex area at the front of this face
- int backarea; //convex area at the back of this face
-} aas_face_t;
-
-//face index, stores a negative index if backside of face
-typedef int aas_faceindex_t;
-
-//convex area with a boundary of faces
-typedef struct aas_area_s
-{
- int areanum; //number of this area
- //3d definition
- int numfaces; //number of faces used for the boundary of the convex area
- int firstface; //first face in the face index used for the boundary of the convex area
- vec3_t mins; //mins of the convex area
- vec3_t maxs; //maxs of the convex area
- vec3_t center; //'center' of the convex area
-} aas_area_t;
-
-//nodes of the bsp tree
-typedef struct aas_node_s
-{
- int planenum;
- int children[2]; //child nodes of this node, or convex areas as leaves when negative
- //when a child is zero it's a solid leaf
-} aas_node_t;
-
-//=========== aas file ===============
-
-//header lump
-typedef struct
-{
- int fileofs;
- int filelen;
-} aas_lump_t;
-
-//aas file header
-typedef struct aas_header_s
-{
- int ident;
- int version;
- int bspchecksum;
- //data entries
- aas_lump_t lumps[AAS_LUMPS];
-} aas_header_t;
-
-
-//====== additional information ======
-/*
-
-- when a node child is a solid leaf the node child number is zero
-- two adjacent areas (sharing a plane at opposite sides) share a face
- this face is a portal between the areas
-- when an area uses a face from the faceindex with a positive index
- then the face plane normal points into the area
-- the face edges are stored counter clockwise using the edgeindex
-- two adjacent convex areas (sharing a face) only share One face
- this is a simple result of the areas being convex
-- the convex areas can't have a mixture of ground and gap faces
- other mixtures of faces in one area are allowed
-- areas with the AREACONTENTS_CLUSTERPORTAL in the settings have
- cluster number zero
-- edge zero is a dummy
-- face zero is a dummy
-- area zero is a dummy
-- node zero is a dummy
-*/
diff --git a/code/bspc/be_aas_bspc.c b/code/bspc/be_aas_bspc.c
deleted file mode 100644
index 4c04aaf..0000000
--- a/code/bspc/be_aas_bspc.c
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-#include "../qcommon/q_shared.h"
-#include "../bspc/l_log.h"
-#include "../bspc/l_qfiles.h"
-#include "../botlib/l_memory.h"
-#include "../botlib/l_script.h"
-#include "../botlib/l_precomp.h"
-#include "../botlib/l_struct.h"
-#include "../botlib/aasfile.h"
-#include "../botlib/botlib.h"
-#include "../botlib/be_aas.h"
-#include "../botlib/be_aas_def.h"
-#include "../qcommon/cm_public.h"
-
-//#define BSPC
-
-extern botlib_import_t botimport;
-extern qboolean capsule_collision;
-
-botlib_import_t botimport;
-clipHandle_t worldmodel;
-
-void Error (char *error, ...);
-
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_Error(char *fmt, ...)
-{
- va_list argptr;
- char text[1024];
-
- va_start(argptr, fmt);
- vsprintf(text, fmt, argptr);
- va_end(argptr);
-
- Error(text);
-} //end of the function AAS_Error
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int Sys_MilliSeconds(void)
-{
- return clock() * 1000 / CLOCKS_PER_SEC;
-} //end of the function Sys_MilliSeconds
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_DebugLine(vec3_t start, vec3_t end, int color)
-{
-} //end of the function AAS_DebugLine
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_ClearShownDebugLines(void)
-{
-} //end of the function AAS_ClearShownDebugLines
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-char *BotImport_BSPEntityData(void)
-{
- return CM_EntityString();
-} //end of the function AAS_GetEntityData
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void BotImport_Trace(bsp_trace_t *bsptrace, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int passent, int contentmask)
-{
- trace_t result;
-
- CM_BoxTrace(&result, start, end, mins, maxs, worldmodel, contentmask, capsule_collision);
-
- bsptrace->allsolid = result.allsolid;
- bsptrace->contents = result.contents;
- VectorCopy(result.endpos, bsptrace->endpos);
- bsptrace->ent = result.entityNum;
- bsptrace->fraction = result.fraction;
- bsptrace->exp_dist = 0;
- bsptrace->plane.dist = result.plane.dist;
- VectorCopy(result.plane.normal, bsptrace->plane.normal);
- bsptrace->plane.signbits = result.plane.signbits;
- bsptrace->plane.type = result.plane.type;
- bsptrace->sidenum = 0;
- bsptrace->startsolid = result.startsolid;
- bsptrace->surface.flags = result.surfaceFlags;
-} //end of the function BotImport_Trace
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int BotImport_PointContents(vec3_t p)
-{
- return CM_PointContents(p, worldmodel);
-} //end of the function BotImport_PointContents
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void *BotImport_GetMemory(int size)
-{
- return GetMemory(size);
-} //end of the function BotImport_GetMemory
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void BotImport_Print(int type, char *fmt, ...)
-{
- va_list argptr;
- char buf[1024];
-
- va_start(argptr, fmt);
- vsprintf(buf, fmt, argptr);
- printf(buf);
- if (buf[0] != '\r') Log_Write(buf);
- va_end(argptr);
-} //end of the function BotImport_Print
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void BotImport_BSPModelMinsMaxsOrigin(int modelnum, vec3_t angles, vec3_t outmins, vec3_t outmaxs, vec3_t origin)
-{
- clipHandle_t h;
- vec3_t mins, maxs;
- float max;
- int i;
-
- h = CM_InlineModel(modelnum);
- CM_ModelBounds(h, mins, maxs);
- //if the model is rotated
- if ((angles[0] || angles[1] || angles[2]))
- { // expand for rotation
-
- max = RadiusFromBounds(mins, maxs);
- for (i = 0; i < 3; i++)
- {
- mins[i] = (mins[i] + maxs[i]) * 0.5 - max;
- maxs[i] = (mins[i] + maxs[i]) * 0.5 + max;
- } //end for
- } //end if
- if (outmins) VectorCopy(mins, outmins);
- if (outmaxs) VectorCopy(maxs, outmaxs);
- if (origin) VectorClear(origin);
-} //end of the function BotImport_BSPModelMinsMaxsOrigin
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void Com_DPrintf(char *fmt, ...)
-{
- va_list argptr;
- char buf[1024];
-
- va_start(argptr, fmt);
- vsprintf(buf, fmt, argptr);
- printf(buf);
- if (buf[0] != '\r') Log_Write(buf);
- va_end(argptr);
-} //end of the function Com_DPrintf
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int COM_Compress( char *data_p ) {
- return strlen(data_p);
-}
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void Com_Memset (void* dest, const int val, const size_t count) {
- memset(dest, val, count);
-}
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void Com_Memcpy (void* dest, const void* src, const size_t count) {
- memcpy(dest, src, count);
-}
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_InitBotImport(void)
-{
- botimport.BSPEntityData = BotImport_BSPEntityData;
- botimport.GetMemory = BotImport_GetMemory;
- botimport.FreeMemory = FreeMemory;
- botimport.Trace = BotImport_Trace;
- botimport.PointContents = BotImport_PointContents;
- botimport.Print = BotImport_Print;
- botimport.BSPModelMinsMaxsOrigin = BotImport_BSPModelMinsMaxsOrigin;
-} //end of the function AAS_InitBotImport
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_CalcReachAndClusters(struct quakefile_s *qf)
-{
- float time;
-
- Log_Print("loading collision map...\n");
- //
- if (!qf->pakfile[0]) strcpy(qf->pakfile, qf->filename);
- //load the map
- CM_LoadMap((char *) qf, qfalse, &aasworld.bspchecksum);
- //get a handle to the world model
- worldmodel = CM_InlineModel(0); // 0 = world, 1 + are bmodels
- //initialize bot import structure
- AAS_InitBotImport();
- //load the BSP entity string
- AAS_LoadBSPFile();
- //init physics settings
- AAS_InitSettings();
- //initialize AAS link heap
- AAS_InitAASLinkHeap();
- //initialize the AAS linked entities for the new map
- AAS_InitAASLinkedEntities();
- //reset all reachabilities and clusters
- aasworld.reachabilitysize = 0;
- aasworld.numclusters = 0;
- //set all view portals as cluster portals in case we re-calculate the reachabilities and clusters (with -reach)
- AAS_SetViewPortalsAsClusterPortals();
- //calculate reachabilities
- AAS_InitReachability();
- time = 0;
- while(AAS_ContinueInitReachability(time)) time++;
- //calculate clusters
- AAS_InitClustering();
-} //end of the function AAS_CalcReachAndClusters
diff --git a/code/bspc/be_aas_bspc.h b/code/bspc/be_aas_bspc.h
deleted file mode 100644
index 92cc0cf..0000000
--- a/code/bspc/be_aas_bspc.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-void AAS_CalcReachAndClusters(struct quakefile_s *qf);
diff --git a/code/bspc/brushbsp.c b/code/bspc/brushbsp.c
deleted file mode 100644
index 8acccfe..0000000
--- a/code/bspc/brushbsp.c
+++ /dev/null
@@ -1,1871 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-#include "qbsp.h"
-#include "l_mem.h"
-#include "../botlib/aasfile.h"
-#include "aas_store.h"
-#include "aas_cfg.h"
-
-#include <assert.h>
-
-/*
-each side has a count of the other sides it splits
-
-the best split will be the one that minimizes the total split counts
-of all remaining sides
-
-precalc side on plane table
-
-evaluate split side
-{
-cost = 0
-for all sides
- for all sides
- get
- if side splits side and splitside is on same child
- cost++;
-}
-*/
-
-int c_nodes;
-int c_nonvis;
-int c_active_brushes;
-int c_solidleafnodes;
-int c_totalsides;
-int c_brushmemory;
-int c_peak_brushmemory;
-int c_nodememory;
-int c_peak_totalbspmemory;
-
-// if a brush just barely pokes onto the other side,
-// let it slide by without chopping
-#define PLANESIDE_EPSILON 0.001
-//0.1
-
-//#ifdef DEBUG
-typedef struct cname_s
-{
- int value;
- char *name;
-} cname_t;
-
-cname_t contentnames[] =
-{
- {CONTENTS_SOLID,"CONTENTS_SOLID"},
- {CONTENTS_WINDOW,"CONTENTS_WINDOW"},
- {CONTENTS_AUX,"CONTENTS_AUX"},
- {CONTENTS_LAVA,"CONTENTS_LAVA"},
- {CONTENTS_SLIME,"CONTENTS_SLIME"},
- {CONTENTS_WATER,"CONTENTS_WATER"},
- {CONTENTS_MIST,"CONTENTS_MIST"},
- {LAST_VISIBLE_CONTENTS,"LAST_VISIBLE_CONTENTS"},
-
- {CONTENTS_AREAPORTAL,"CONTENTS_AREAPORTAL"},
- {CONTENTS_PLAYERCLIP,"CONTENTS_PLAYERCLIP"},
- {CONTENTS_MONSTERCLIP,"CONTENTS_MONSTERCLIP"},
- {CONTENTS_CURRENT_0,"CONTENTS_CURRENT_0"},
- {CONTENTS_CURRENT_90,"CONTENTS_CURRENT_90"},
- {CONTENTS_CURRENT_180,"CONTENTS_CURRENT_180"},
- {CONTENTS_CURRENT_270,"CONTENTS_CURRENT_270"},
- {CONTENTS_CURRENT_UP,"CONTENTS_CURRENT_UP"},
- {CONTENTS_CURRENT_DOWN,"CONTENTS_CURRENT_DOWN"},
- {CONTENTS_ORIGIN,"CONTENTS_ORIGIN"},
- {CONTENTS_MONSTER,"CONTENTS_MONSTER"},
- {CONTENTS_DEADMONSTER,"CONTENTS_DEADMONSTER"},
- {CONTENTS_DETAIL,"CONTENTS_DETAIL"},
- {CONTENTS_Q2TRANSLUCENT,"CONTENTS_TRANSLUCENT"},
- {CONTENTS_LADDER,"CONTENTS_LADDER"},
- {0, 0}
-};
-
-void PrintContents(int contents)
-{
- int i;
-
- for (i = 0; contentnames[i].value; i++)
- {
- if (contents & contentnames[i].value)
- {
- Log_Write("%s,", contentnames[i].name);
- } //end if
- } //end for
-} //end of the function PrintContents
-
-//#endif DEBUG
-
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void ResetBrushBSP(void)
-{
- c_nodes = 0;
- c_nonvis = 0;
- c_active_brushes = 0;
- c_solidleafnodes = 0;
- c_totalsides = 0;
- c_brushmemory = 0;
- c_peak_brushmemory = 0;
- c_nodememory = 0;
- c_peak_totalbspmemory = 0;
-} //end of the function ResetBrushBSP
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void FindBrushInTree (node_t *node, int brushnum)
-{
- bspbrush_t *b;
-
- if (node->planenum == PLANENUM_LEAF)
- {
- for (b=node->brushlist ; b ; b=b->next)
- if (b->original->brushnum == brushnum)
- Log_Print ("here\n");
- return;
- }
- FindBrushInTree(node->children[0], brushnum);
- FindBrushInTree(node->children[1], brushnum);
-} //end of the function FindBrushInTree
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void DrawBrushList (bspbrush_t *brush, node_t *node)
-{
- int i;
- side_t *s;
-
- GLS_BeginScene ();
- for ( ; brush ; brush=brush->next)
- {
- for (i=0 ; i<brush->numsides ; i++)
- {
- s = &brush->sides[i];
- if (!s->winding)
- continue;
- if (s->texinfo == TEXINFO_NODE)
- GLS_Winding (s->winding, 1);
- else if (!(s->flags & SFL_VISIBLE))
- GLS_Winding (s->winding, 2);
- else
- GLS_Winding (s->winding, 0);
- }
- }
- GLS_EndScene ();
-} //end of the function DrawBrushList
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void WriteBrushList (char *name, bspbrush_t *brush, qboolean onlyvis)
-{
- int i;
- side_t *s;
- FILE *f;
-
- qprintf ("writing %s\n", name);
- f = SafeOpenWrite (name);
-
- for ( ; brush ; brush=brush->next)
- {
- for (i=0 ; i<brush->numsides ; i++)
- {
- s = &brush->sides[i];
- if (!s->winding)
- continue;
- if (onlyvis && !(s->flags & SFL_VISIBLE))
- continue;
- OutputWinding (brush->sides[i].winding, f);
- }
- }
-
- fclose (f);
-} //end of the function WriteBrushList
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void PrintBrush (bspbrush_t *brush)
-{
- int i;
-
- printf ("brush: %p\n", brush);
- for (i=0;i<brush->numsides ; i++)
- {
- pw(brush->sides[i].winding);
- printf ("\n");
- } //end for
-} //end of the function PrintBrush
-//===========================================================================
-// Sets the mins/maxs based on the windings
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void BoundBrush (bspbrush_t *brush)
-{
- int i, j;
- winding_t *w;
-
- ClearBounds (brush->mins, brush->maxs);
- for (i=0 ; i<brush->numsides ; i++)
- {
- w = brush->sides[i].winding;
- if (!w)
- continue;
- for (j=0 ; j<w->numpoints ; j++)
- AddPointToBounds (w->p[j], brush->mins, brush->maxs);
- }
-} //end of the function BoundBrush
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void CreateBrushWindings (bspbrush_t *brush)
-{
- int i, j;
- winding_t *w;
- side_t *side;
- plane_t *plane;
-
- for (i=0 ; i<brush->numsides ; i++)
- {
- side = &brush->sides[i];
- plane = &mapplanes[side->planenum];
- w = BaseWindingForPlane (plane->normal, plane->dist);
- for (j=0 ; j<brush->numsides && w; j++)
- {
- if (i == j)
- continue;
- if (brush->sides[j].flags & SFL_BEVEL)
- continue;
- plane = &mapplanes[brush->sides[j].planenum^1];
- ChopWindingInPlace (&w, plane->normal, plane->dist, 0); //CLIP_EPSILON);
- }
-
- side->winding = w;
- }
-
- BoundBrush (brush);
-} //end of the function CreateBrushWindings
-//===========================================================================
-// Creates a new axial brush
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-bspbrush_t *BrushFromBounds (vec3_t mins, vec3_t maxs)
-{
- bspbrush_t *b;
- int i;
- vec3_t normal;
- vec_t dist;
-
- b = AllocBrush (6);
- b->numsides = 6;
- for (i=0 ; i<3 ; i++)
- {
- VectorClear (normal);
- normal[i] = 1;
- dist = maxs[i];
- b->sides[i].planenum = FindFloatPlane (normal, dist);
-
- normal[i] = -1;
- dist = -mins[i];
- b->sides[3+i].planenum = FindFloatPlane (normal, dist);
- }
-
- CreateBrushWindings (b);
-
- return b;
-} //end of the function BrushFromBounds
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int BrushOutOfBounds(bspbrush_t *brush, vec3_t mins, vec3_t maxs, float epsilon)
-{
- int i, j, n;
- winding_t *w;
- side_t *side;
-
- for (i = 0; i < brush->numsides; i++)
- {
- side = &brush->sides[i];
- w = side->winding;
- for (j = 0; j < w->numpoints; j++)
- {
- for (n = 0; n < 3; n++)
- {
- if (w->p[j][n] < (mins[n] + epsilon) || w->p[j][n] > (maxs[n] - epsilon)) return true;
- } //end for
- } //end for
- } //end for
- return false;
-} //end of the function BrushOutOfBounds
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-vec_t BrushVolume (bspbrush_t *brush)
-{
- int i;
- winding_t *w;
- vec3_t corner;
- vec_t d, area, volume;
- plane_t *plane;
-
- if (!brush) return 0;
-
- // grab the first valid point as the corner
- w = NULL;
- for (i = 0; i < brush->numsides; i++)
- {
- w = brush->sides[i].winding;
- if (w) break;
- } //end for
- if (!w) return 0;
- VectorCopy (w->p[0], corner);
-
- // make tetrahedrons to all other faces
- volume = 0;
- for ( ; i < brush->numsides; i++)
- {
- w = brush->sides[i].winding;
- if (!w) continue;
- plane = &mapplanes[brush->sides[i].planenum];
- d = -(DotProduct (corner, plane->normal) - plane->dist);
- area = WindingArea(w);
- volume += d * area;
- } //end for
-
- volume /= 3;
- return volume;
-} //end of the function BrushVolume
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int CountBrushList (bspbrush_t *brushes)
-{
- int c;
-
- c = 0;
- for ( ; brushes; brushes = brushes->next) c++;
- return c;
-} //end of the function CountBrushList
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-node_t *AllocNode (void)
-{
- node_t *node;
-
- node = GetMemory(sizeof(*node));
- memset (node, 0, sizeof(*node));
- if (numthreads == 1)
- {
- c_nodememory += MemorySize(node);
- } //end if
- return node;
-} //end of the function AllocNode
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-bspbrush_t *AllocBrush (int numsides)
-{
- bspbrush_t *bb;
- int c;
-
- c = (int)&(((bspbrush_t *)0)->sides[numsides]);
- bb = GetMemory(c);
- memset (bb, 0, c);
- if (numthreads == 1)
- {
- c_active_brushes++;
- c_brushmemory += MemorySize(bb);
- if (c_brushmemory > c_peak_brushmemory)
- c_peak_brushmemory = c_brushmemory;
- } //end if
- return bb;
-} //end of the function AllocBrush
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void FreeBrush (bspbrush_t *brushes)
-{
- int i;
-
- for (i=0 ; i<brushes->numsides ; i++)
- if (brushes->sides[i].winding)
- FreeWinding(brushes->sides[i].winding);
- if (numthreads == 1)
- {
- c_active_brushes--;
- c_brushmemory -= MemorySize(brushes);
- if (c_brushmemory < 0) c_brushmemory = 0;
- } //end if
- FreeMemory(brushes);
-} //end of the function FreeBrush
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void FreeBrushList (bspbrush_t *brushes)
-{
- bspbrush_t *next;
-
- for ( ; brushes; brushes = next)
- {
- next = brushes->next;
-
- FreeBrush(brushes);
- } //end for
-} //end of the function FreeBrushList
-//===========================================================================
-// Duplicates the brush, the sides, and the windings
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-bspbrush_t *CopyBrush (bspbrush_t *brush)
-{
- bspbrush_t *newbrush;
- int size;
- int i;
-
- size = (int)&(((bspbrush_t *)0)->sides[brush->numsides]);
-
- newbrush = AllocBrush (brush->numsides);
- memcpy (newbrush, brush, size);
-
- for (i=0 ; i<brush->numsides ; i++)
- {
- if (brush->sides[i].winding)
- newbrush->sides[i].winding = CopyWinding (brush->sides[i].winding);
- }
-
- return newbrush;
-} //end of the function CopyBrush
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-node_t *PointInLeaf (node_t *node, vec3_t point)
-{
- vec_t d;
- plane_t *plane;
-
- while (node->planenum != PLANENUM_LEAF)
- {
- plane = &mapplanes[node->planenum];
- d = DotProduct (point, plane->normal) - plane->dist;
- if (d > 0)
- node = node->children[0];
- else
- node = node->children[1];
- }
-
- return node;
-} //end of the function PointInLeaf
-//===========================================================================
-// Returns PSIDE_FRONT, PSIDE_BACK, or PSIDE_BOTH
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-#if 0
-int BoxOnPlaneSide (vec3_t mins, vec3_t maxs, plane_t *plane)
-{
- int side;
- int i;
- vec3_t corners[2];
- vec_t dist1, dist2;
-
- // axial planes are easy
- if (plane->type < 3)
- {
- side = 0;
- if (maxs[plane->type] > plane->dist+PLANESIDE_EPSILON)
- side |= PSIDE_FRONT;
- if (mins[plane->type] < plane->dist-PLANESIDE_EPSILON)
- side |= PSIDE_BACK;
- return side;
- }
-
- // create the proper leading and trailing verts for the box
-
- for (i=0 ; i<3 ; i++)
- {
- if (plane->normal[i] < 0)
- {
- corners[0][i] = mins[i];
- corners[1][i] = maxs[i];
- }
- else
- {
- corners[1][i] = mins[i];
- corners[0][i] = maxs[i];
- }
- }
-
- dist1 = DotProduct (plane->normal, corners[0]) - plane->dist;
- dist2 = DotProduct (plane->normal, corners[1]) - plane->dist;
- side = 0;
- if (dist1 >= PLANESIDE_EPSILON)
- side = PSIDE_FRONT;
- if (dist2 < PLANESIDE_EPSILON)
- side |= PSIDE_BACK;
-
- return side;
-}
-#else
-int BoxOnPlaneSide (vec3_t emins, vec3_t emaxs, plane_t *p)
-{
- float dist1, dist2;
- int sides;
-
- // axial planes are easy
- if (p->type < 3)
- {
- sides = 0;
- if (emaxs[p->type] > p->dist+PLANESIDE_EPSILON) sides |= PSIDE_FRONT;
- if (emins[p->type] < p->dist-PLANESIDE_EPSILON) sides |= PSIDE_BACK;
- return sides;
- } //end if
-
-// general case
- switch (p->signbits)
- {
- case 0:
- dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
- dist2 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
- break;
- case 1:
- dist1 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
- dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
- break;
- case 2:
- dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
- dist2 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
- break;
- case 3:
- dist1 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
- dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
- break;
- case 4:
- dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
- dist2 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
- break;
- case 5:
- dist1 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
- dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
- break;
- case 6:
- dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
- dist2 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
- break;
- case 7:
- dist1 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
- dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
- break;
- default:
- dist1 = dist2 = 0; // shut up compiler
-// assert( 0 );
- break;
- }
-
- sides = 0;
- if (dist1 - p->dist >= PLANESIDE_EPSILON) sides = PSIDE_FRONT;
- if (dist2 - p->dist < PLANESIDE_EPSILON) sides |= PSIDE_BACK;
-
-// assert(sides != 0);
-
- return sides;
-}
-#endif
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int QuickTestBrushToPlanenum (bspbrush_t *brush, int planenum, int *numsplits)
-{
- int i, num;
- plane_t *plane;
- int s;
-
- *numsplits = 0;
-
- plane = &mapplanes[planenum];
-
-#ifdef ME
- //fast axial cases
- if (plane->type < 3)
- {
- if (plane->dist + PLANESIDE_EPSILON < brush->mins[plane->type])
- return PSIDE_FRONT;
- if (plane->dist - PLANESIDE_EPSILON > brush->maxs[plane->type])
- return PSIDE_BACK;
- } //end if
-#endif //ME*/
-
- // if the brush actually uses the planenum,
- // we can tell the side for sure
- for (i = 0; i < brush->numsides; i++)
- {
- num = brush->sides[i].planenum;
- if (num >= MAX_MAPFILE_PLANES)
- Error ("bad planenum");
- if (num == planenum)
- return PSIDE_BACK|PSIDE_FACING;
- if (num == (planenum ^ 1) )
- return PSIDE_FRONT|PSIDE_FACING;
-
- }
-
- // box on plane side
- s = BoxOnPlaneSide (brush->mins, brush->maxs, plane);
-
- // if both sides, count the visible faces split
- if (s == PSIDE_BOTH)
- {
- *numsplits += 3;
- }
-
- return s;
-} //end of the function QuickTestBrushToPlanenum
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int TestBrushToPlanenum (bspbrush_t *brush, int planenum,
- int *numsplits, qboolean *hintsplit, int *epsilonbrush)
-{
- int i, j, num;
- plane_t *plane;
- int s = 0;
- winding_t *w;
- vec_t d, d_front, d_back;
- int front, back;
- int type;
- float dist;
-
- *numsplits = 0;
- *hintsplit = false;
-
- plane = &mapplanes[planenum];
-
-#ifdef ME
- //fast axial cases
- type = plane->type;
- if (type < 3)
- {
- dist = plane->dist;
- if (dist + PLANESIDE_EPSILON < brush->mins[type]) return PSIDE_FRONT;
- if (dist - PLANESIDE_EPSILON > brush->maxs[type]) return PSIDE_BACK;
- if (brush->mins[type] < dist - PLANESIDE_EPSILON &&
- brush->maxs[type] > dist + PLANESIDE_EPSILON) s = PSIDE_BOTH;
- } //end if
-
- if (s != PSIDE_BOTH)
-#endif //ME
- {
- // if the brush actually uses the planenum,
- // we can tell the side for sure
- for (i = 0; i < brush->numsides; i++)
- {
- num = brush->sides[i].planenum;
- if (num >= MAX_MAPFILE_PLANES) Error ("bad planenum");
- if (num == planenum)
- {
- //we don't need to test this side plane again
- brush->sides[i].flags |= SFL_TESTED;
- return PSIDE_BACK|PSIDE_FACING;
- } //end if
- if (num == (planenum ^ 1) )
- {
- //we don't need to test this side plane again
- brush->sides[i].flags |= SFL_TESTED;
- return PSIDE_FRONT|PSIDE_FACING;
- } //end if
- } //end for
-
- // box on plane side
- s = BoxOnPlaneSide (brush->mins, brush->maxs, plane);
-
- if (s != PSIDE_BOTH) return s;
- } //end if
-
- // if both sides, count the visible faces split
- d_front = d_back = 0;
-
- for (i = 0; i < brush->numsides; i++)
- {
- if (brush->sides[i].texinfo == TEXINFO_NODE)
- continue; // on node, don't worry about splits
- if (!(brush->sides[i].flags & SFL_VISIBLE))
- continue; // we don't care about non-visible
- w = brush->sides[i].winding;
- if (!w) continue;
- front = back = 0;
- for (j = 0; j < w->numpoints; j++)
- {
- d = DotProduct(w->p[j], plane->normal) - plane->dist;
- if (d > d_front) d_front = d;
- if (d < d_back) d_back = d;
- if (d > 0.1) // PLANESIDE_EPSILON)
- front = 1;
- if (d < -0.1) // PLANESIDE_EPSILON)
- back = 1;
- } //end for
- if (front && back)
- {
- if ( !(brush->sides[i].surf & SURF_SKIP) )
- {
- (*numsplits)++;
- if (brush->sides[i].surf & SURF_HINT)
- {
- *hintsplit = true;
- } //end if
- } //end if
- } //end if
- } //end for
-
- if ( (d_front > 0.0 && d_front < 1.0)
- || (d_back < 0.0 && d_back > -1.0) )
- (*epsilonbrush)++;
-
-#if 0
- if (*numsplits == 0)
- { // didn't really need to be split
- if (front) s = PSIDE_FRONT;
- else if (back) s = PSIDE_BACK;
- else s = 0;
- }
-#endif
-
- return s;
-} //end of the function TestBrushToPlanenum
-//===========================================================================
-// Returns true if the winding would be crunched out of
-// existance by the vertex snapping.
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-#define EDGE_LENGTH 0.2
-qboolean WindingIsTiny (winding_t *w)
-{
-#if 0
- if (WindingArea (w) < 1)
- return true;
- return false;
-#else
- int i, j;
- vec_t len;
- vec3_t delta;
- int edges;
-
- edges = 0;
- for (i=0 ; i<w->numpoints ; i++)
- {
- j = i == w->numpoints - 1 ? 0 : i+1;
- VectorSubtract (w->p[j], w->p[i], delta);
- len = VectorLength (delta);
- if (len > EDGE_LENGTH)
- {
- if (++edges == 3)
- return false;
- }
- }
- return true;
-#endif
-} //end of the function WindingIsTiny
-//===========================================================================
-// Returns true if the winding still has one of the points
-// from basewinding for plane
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-qboolean WindingIsHuge (winding_t *w)
-{
- int i, j;
-
- for (i=0 ; i<w->numpoints ; i++)
- {
- for (j=0 ; j<3 ; j++)
- if (w->p[i][j] < -BOGUS_RANGE+1 || w->p[i][j] > BOGUS_RANGE-1)
- return true;
- }
- return false;
-} //end of the function WindingIsHuge
-//===========================================================================
-// creates a leaf out of the given nodes with the given brushes
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void LeafNode(node_t *node, bspbrush_t *brushes)
-{
- bspbrush_t *b;
- int i;
-
- node->side = NULL;
- node->planenum = PLANENUM_LEAF;
- node->contents = 0;
-
- for (b = brushes; b; b = b->next)
- {
- // if the brush is solid and all of its sides are on nodes,
- // it eats everything
- if (b->original->contents & CONTENTS_SOLID)
- {
- for (i=0 ; i<b->numsides ; i++)
- if (b->sides[i].texinfo != TEXINFO_NODE)
- break;
- if (i == b->numsides)
- {
- node->contents = CONTENTS_SOLID;
- break;
- } //end if
- } //end if
- node->contents |= b->original->contents;
- } //end for
-
- if (create_aas)
- {
- node->expansionbboxes = 0;
- node->contents = 0;
- for (b = brushes; b; b = b->next)
- {
- node->expansionbboxes |= b->original->expansionbbox;
- node->contents |= b->original->contents;
- if (b->original->modelnum)
- node->modelnum = b->original->modelnum;
- } //end for
- if (node->contents & CONTENTS_SOLID)
- {
- if (node->expansionbboxes != cfg.allpresencetypes)
- {
- node->contents &= ~CONTENTS_SOLID;
- } //end if
- } //end if
- } //end if
-
- node->brushlist = brushes;
-} //end of the function LeafNode
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void CheckPlaneAgainstParents (int pnum, node_t *node)
-{
- node_t *p;
-
- for (p = node->parent; p; p = p->parent)
- {
- if (p->planenum == pnum) Error("Tried parent");
- } //end for
-} //end of the function CheckPlaneAgainstParants
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-qboolean CheckPlaneAgainstVolume (int pnum, node_t *node)
-{
- bspbrush_t *front, *back;
- qboolean good;
-
- SplitBrush (node->volume, pnum, &front, &back);
-
- good = (front && back);
-
- if (front) FreeBrush (front);
- if (back) FreeBrush (back);
-
- return good;
-} //end of the function CheckPlaneAgaintsVolume
-//===========================================================================
-// Using a hueristic, choses one of the sides out of the brushlist
-// to partition the brushes with.
-// Returns NULL if there are no valid planes to split with..
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-side_t *SelectSplitSide (bspbrush_t *brushes, node_t *node)
-{
- int value, bestvalue;
- bspbrush_t *brush, *test;
- side_t *side, *bestside;
- int i, pass, numpasses;
- int pnum;
- int s;
- int front, back, both, facing, splits;
- int bsplits;
- int bestsplits;
- int epsilonbrush;
- qboolean hintsplit = false;
-
- bestside = NULL;
- bestvalue = -99999;
- bestsplits = 0;
-
- // the search order goes: visible-structural, visible-detail,
- // nonvisible-structural, nonvisible-detail.
- // If any valid plane is available in a pass, no further
- // passes will be tried.
- numpasses = 2;
- for (pass = 0; pass < numpasses; pass++)
- {
- for (brush = brushes; brush; brush = brush->next)
- {
- // only check detail the second pass
-// if ( (pass & 1) && !(brush->original->contents & CONTENTS_DETAIL) )
-// continue;
-// if ( !(pass & 1) && (brush->original->contents & CONTENTS_DETAIL) )
-// continue;
- for (i = 0; i < brush->numsides; i++)
- {
- side = brush->sides + i;
-// if (side->flags & SFL_BEVEL)
-// continue; // never use a bevel as a spliter
- if (!side->winding)
- continue; // nothing visible, so it can't split
- if (side->texinfo == TEXINFO_NODE)
- continue; // allready a node splitter
- if (side->flags & SFL_TESTED)
- continue; // we allready have metrics for this plane
-// if (side->surf & SURF_SKIP)
-// continue; // skip surfaces are never chosen
-
-// if (!(side->flags & SFL_VISIBLE) && (pass < 2))
-// continue; // only check visible faces on first pass
-
- if ((side->flags & SFL_CURVE) && (pass < 1))
- continue; // only check curves the second pass
-
- pnum = side->planenum;
- pnum &= ~1; // allways use positive facing plane
-
- CheckPlaneAgainstParents (pnum, node);
-
- if (!CheckPlaneAgainstVolume (pnum, node))
- continue; // would produce a tiny volume
-
- front = 0;
- back = 0;
- both = 0;
- facing = 0;
- splits = 0;
- epsilonbrush = 0;
-
- //inner loop: optimize
- for (test = brushes; test; test = test->next)
- {
- s = TestBrushToPlanenum (test, pnum, &bsplits, &hintsplit, &epsilonbrush);
-
- splits += bsplits;
-// if (bsplits && (s&PSIDE_FACING) )
-// Error ("PSIDE_FACING with splits");
-
- test->testside = s;
- //
- if (s & PSIDE_FACING) facing++;
- if (s & PSIDE_FRONT) front++;
- if (s & PSIDE_BACK) back++;
- if (s == PSIDE_BOTH) both++;
- } //end for
-
- // give a value estimate for using this plane
- value = 5*facing - 5*splits - abs(front-back);
-// value = -5*splits;
-// value = 5*facing - 5*splits;
- if (mapplanes[pnum].type < 3)
- value+=5; // axial is better
-
- value -= epsilonbrush * 1000; // avoid!
-
- // never split a hint side except with another hint
- if (hintsplit && !(side->surf & SURF_HINT) )
- value = -9999999;
-
- // save off the side test so we don't need
- // to recalculate it when we actually seperate
- // the brushes
- if (value > bestvalue)
- {
- bestvalue = value;
- bestside = side;
- bestsplits = splits;
- for (test = brushes; test ; test = test->next)
- test->side = test->testside;
- } //end if
- } //end for
- } //end for (brush = brushes;
-
- // if we found a good plane, don't bother trying any
- // other passes
- if (bestside)
- {
- if (pass > 1)
- {
- if (numthreads == 1) c_nonvis++;
- }
- if (pass > 0) node->detail_seperator = true; // not needed for vis
- break;
- } //end if
- } //end for (pass = 0;
-
- //
- // clear all the tested flags we set
- //
- for (brush = brushes ; brush ; brush=brush->next)
- {
- for (i = 0; i < brush->numsides; i++)
- {
- brush->sides[i].flags &= ~SFL_TESTED;
- } //end for
- } //end for
-
- return bestside;
-} //end of the function SelectSplitSide
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int BrushMostlyOnSide (bspbrush_t *brush, plane_t *plane)
-{
- int i, j;
- winding_t *w;
- vec_t d, max;
- int side;
-
- max = 0;
- side = PSIDE_FRONT;
- for (i=0 ; i<brush->numsides ; i++)
- {
- w = brush->sides[i].winding;
- if (!w)
- continue;
- for (j=0 ; j<w->numpoints ; j++)
- {
- d = DotProduct (w->p[j], plane->normal) - plane->dist;
- if (d > max)
- {
- max = d;
- side = PSIDE_FRONT;
- }
- if (-d > max)
- {
- max = -d;
- side = PSIDE_BACK;
- }
- }
- }
- return side;
-} //end of the function BrushMostlyOnSide
-//===========================================================================
-// Generates two new brushes, leaving the original
-// unchanged
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void SplitBrush (bspbrush_t *brush, int planenum,
- bspbrush_t **front, bspbrush_t **back)
-{
- bspbrush_t *b[2];
- int i, j;
- winding_t *w, *cw[2], *midwinding;
- plane_t *plane, *plane2;
- side_t *s, *cs;
- float d, d_front, d_back;
-
- *front = *back = NULL;
- plane = &mapplanes[planenum];
-
- // check all points
- d_front = d_back = 0;
- for (i=0 ; i<brush->numsides ; i++)
- {
- w = brush->sides[i].winding;
- if (!w)
- continue;
- for (j=0 ; j<w->numpoints ; j++)
- {
- d = DotProduct (w->p[j], plane->normal) - plane->dist;
- if (d > 0 && d > d_front)
- d_front = d;
- if (d < 0 && d < d_back)
- d_back = d;
- }
- }
-
- if (d_front < 0.2) // PLANESIDE_EPSILON)
- { // only on back
- *back = CopyBrush (brush);
- return;
- }
- if (d_back > -0.2) // PLANESIDE_EPSILON)
- { // only on front
- *front = CopyBrush (brush);
- return;
- }
-
- // create a new winding from the split plane
-
- w = BaseWindingForPlane (plane->normal, plane->dist);
- for (i=0 ; i<brush->numsides && w ; i++)
- {
- plane2 = &mapplanes[brush->sides[i].planenum ^ 1];
- ChopWindingInPlace (&w, plane2->normal, plane2->dist, 0); // PLANESIDE_EPSILON);
- }
-
- if (!w || WindingIsTiny(w))
- { // the brush isn't really split
- int side;
-
- side = BrushMostlyOnSide (brush, plane);
- if (side == PSIDE_FRONT)
- *front = CopyBrush (brush);
- if (side == PSIDE_BACK)
- *back = CopyBrush (brush);
- //free a possible winding
- if (w) FreeWinding(w);
- return;
- }
-
- if (WindingIsHuge (w))
- {
- Log_Write("WARNING: huge winding\n");
- }
-
- midwinding = w;
-
- // split it for real
-
- for (i=0 ; i<2 ; i++)
- {
- b[i] = AllocBrush (brush->numsides+1);
- b[i]->original = brush->original;
- }
-
- // split all the current windings
-
- for (i=0 ; i<brush->numsides ; i++)
- {
- s = &brush->sides[i];
- w = s->winding;
- if (!w)
- continue;
- ClipWindingEpsilon (w, plane->normal, plane->dist,
- 0 /*PLANESIDE_EPSILON*/, &cw[0], &cw[1]);
- for (j=0 ; j<2 ; j++)
- {
- if (!cw[j])
- continue;
-#if 0
- if (WindingIsTiny (cw[j]))
- {
- FreeWinding (cw[j]);
- continue;
- }
-#endif
- cs = &b[j]->sides[b[j]->numsides];
- b[j]->numsides++;
- *cs = *s;
-// cs->planenum = s->planenum;
-// cs->texinfo = s->texinfo;
-// cs->original = s->original;
- cs->winding = cw[j];
- cs->flags &= ~SFL_TESTED;
- }
- }
-
-
- // see if we have valid polygons on both sides
-
- for (i=0 ; i<2 ; i++)
- {
- BoundBrush (b[i]);
- for (j=0 ; j<3 ; j++)
- {
- if (b[i]->mins[j] < -MAX_MAP_BOUNDS || b[i]->maxs[j] > MAX_MAP_BOUNDS)
- {
- Log_Write("bogus brush after clip");
- break;
- }
- }
-
- if (b[i]->numsides < 3 || j < 3)
- {
- FreeBrush (b[i]);
- b[i] = NULL;
- }
- }
-
- if ( !(b[0] && b[1]) )
- {
- if (!b[0] && !b[1])
- Log_Write("split removed brush\r\n");
- else
- Log_Write("split not on both sides\r\n");
- if (b[0])
- {
- FreeBrush (b[0]);
- *front = CopyBrush (brush);
- }
- if (b[1])
- {
- FreeBrush (b[1]);
- *back = CopyBrush (brush);
- }
- return;
- }
-
- // add the midwinding to both sides
- for (i=0 ; i<2 ; i++)
- {
- cs = &b[i]->sides[b[i]->numsides];
- b[i]->numsides++;
-
- cs->planenum = planenum^i^1;
- cs->texinfo = TEXINFO_NODE; //never use these sides as splitters
- cs->flags &= ~SFL_VISIBLE;
- cs->flags &= ~SFL_TESTED;
- if (i==0)
- cs->winding = CopyWinding (midwinding);
- else
- cs->winding = midwinding;
- }
-
-{
- vec_t v1;
- int i;
-
- for (i = 0; i < 2; i++)
- {
- v1 = BrushVolume (b[i]);
- if (v1 < 1.0)
- {
- FreeBrush(b[i]);
- b[i] = NULL;
- //Log_Write("tiny volume after clip");
- }
- }
- if (!b[0] && !b[1])
- {
- Log_Write("two tiny brushes\r\n");
- } //end if
-}
-
- *front = b[0];
- *back = b[1];
-} //end of the function SplitBrush
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void SplitBrushList (bspbrush_t *brushes,
- node_t *node, bspbrush_t **front, bspbrush_t **back)
-{
- bspbrush_t *brush, *newbrush, *newbrush2;
- side_t *side;
- int sides;
- int i;
-
- *front = *back = NULL;
-
- for (brush = brushes; brush; brush = brush->next)
- {
- sides = brush->side;
-
- if (sides == PSIDE_BOTH)
- { // split into two brushes
- SplitBrush (brush, node->planenum, &newbrush, &newbrush2);
- if (newbrush)
- {
- newbrush->next = *front;
- *front = newbrush;
- } //end if
- if (newbrush2)
- {
- newbrush2->next = *back;
- *back = newbrush2;
- } //end if
- continue;
- } //end if
-
- newbrush = CopyBrush (brush);
-
- // if the planenum is actualy a part of the brush
- // find the plane and flag it as used so it won't be tried
- // as a splitter again
- if (sides & PSIDE_FACING)
- {
- for (i=0 ; i<newbrush->numsides ; i++)
- {
- side = newbrush->sides + i;
- if ( (side->planenum& ~1) == node->planenum)
- side->texinfo = TEXINFO_NODE;
- } //end for
- } //end if
- if (sides & PSIDE_FRONT)
- {
- newbrush->next = *front;
- *front = newbrush;
- continue;
- } //end if
- if (sides & PSIDE_BACK)
- {
- newbrush->next = *back;
- *back = newbrush;
- continue;
- } //end if
- } //end for
-} //end of the function SplitBrushList
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void CheckBrushLists(bspbrush_t *brushlist1, bspbrush_t *brushlist2)
-{
- bspbrush_t *brush1, *brush2;
-
- for (brush1 = brushlist1; brush1; brush1 = brush1->next)
- {
- for (brush2 = brushlist2; brush2; brush2 = brush2->next)
- {
- assert(brush1 != brush2);
- } //end for
- } //end for
-} //end of the function CheckBrushLists
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int numrecurse = 0;
-
-node_t *BuildTree_r (node_t *node, bspbrush_t *brushes)
-{
- node_t *newnode;
- side_t *bestside;
- int i, totalmem;
- bspbrush_t *children[2];
-
- qprintf("\r%6d", numrecurse);
- numrecurse++;
-
- if (numthreads == 1)
- {
- totalmem = WindingMemory() + c_nodememory + c_brushmemory;
- if (totalmem > c_peak_totalbspmemory)
- c_peak_totalbspmemory = totalmem;
- c_nodes++;
- } //endif
-
- if (drawflag)
- DrawBrushList(brushes, node);
-
- // find the best plane to use as a splitter
- bestside = SelectSplitSide (brushes, node);
- if (!bestside)
- {
- // leaf node
- node->side = NULL;
- node->planenum = -1;
- LeafNode(node, brushes);
- if (node->contents & CONTENTS_SOLID) c_solidleafnodes++;
- if (create_aas)
- {
- //free up memory!!!
- FreeBrushList(node->brushlist);
- node->brushlist = NULL;
- //free the node volume brush
- if (node->volume)
- {
- FreeBrush(node->volume);
- node->volume = NULL;
- } //end if
- } //end if
- return node;
- } //end if
-
- // this is a splitplane node
- node->side = bestside;
- node->planenum = bestside->planenum & ~1; // always use front facing
-
- //split the brush list in two for both children
- SplitBrushList (brushes, node, &children[0], &children[1]);
- //free the old brush list
- FreeBrushList (brushes);
-
- // allocate children before recursing
- for (i = 0; i < 2; i++)
- {
- newnode = AllocNode ();
- newnode->parent = node;
- node->children[i] = newnode;
- } //end for
-
- //split the volume brush of the node for the children
- SplitBrush (node->volume, node->planenum, &node->children[0]->volume,
- &node->children[1]->volume);
-
- if (create_aas)
- {
- //free the volume brush
- if (node->volume)
- {
- FreeBrush(node->volume);
- node->volume = NULL;
- } //end if
- } //end if
- // recursively process children
- for (i = 0; i < 2; i++)
- {
- node->children[i] = BuildTree_r(node->children[i], children[i]);
- } //end for
-
- return node;
-} //end of the function BuildTree_r
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-node_t *firstnode; //first node in the list
-node_t *lastnode; //last node in the list
-int nodelistsize; //number of nodes in the list
-int use_nodequeue = 0; //use nodequeue, otherwise a node stack is used
-int numwaiting = 0;
-
-void (*AddNodeToList)(node_t *node);
-
-//add the node to the front of the node list
-//(effectively using a node stack)
-void AddNodeToStack(node_t *node)
-{
- ThreadLock();
-
- node->next = firstnode;
- firstnode = node;
- if (!lastnode) lastnode = node;
- nodelistsize++;
-
- ThreadUnlock();
- //
- ThreadSemaphoreIncrease(1);
-} //end of the function AddNodeToStack
-//add the node to the end of the node list
-//(effectively using a node queue)
-void AddNodeToQueue(node_t *node)
-{
- ThreadLock();
-
- node->next = NULL;
- if (lastnode) lastnode->next = node;
- else firstnode = node;
- lastnode = node;
- nodelistsize++;
-
- ThreadUnlock();
- //
- ThreadSemaphoreIncrease(1);
-} //end of the function AddNodeToQueue
-//get the first node from the front of the node list
-node_t *NextNodeFromList(void)
-{
- node_t *node;
-
- ThreadLock();
- numwaiting++;
- if (!firstnode)
- {
- if (numwaiting >= GetNumThreads()) ThreadSemaphoreIncrease(GetNumThreads());
- } //end if
- ThreadUnlock();
-
- ThreadSemaphoreWait();
-
- ThreadLock();
-
- numwaiting--;
-
- node = firstnode;
- if (firstnode)
- {
- firstnode = firstnode->next;
- nodelistsize--;
- } //end if
- if (!firstnode) lastnode = NULL;
-
- ThreadUnlock();
-
- return node;
-} //end of the function NextNodeFromList
-//returns the size of the node list
-int NodeListSize(void)
-{
- int size;
-
- ThreadLock();
- size = nodelistsize;
- ThreadUnlock();
-
- return size;
-} //end of the function NodeListSize
-//
-void IncreaseNodeCounter(void)
-{
- ThreadLock();
- //if (verbose) printf("\r%6d", numrecurse++);
- qprintf("\r%6d", numrecurse++);
- //qprintf("\r%6d %d, %5d ", numrecurse++, GetNumThreads(), nodelistsize);
- ThreadUnlock();
-} //end of the function IncreaseNodeCounter
-//thread function, gets nodes from the nodelist and processes them
-void BuildTreeThread(int threadid)
-{
- node_t *newnode, *node;
- side_t *bestside;
- int i, totalmem;
- bspbrush_t *brushes;
-
- for (node = NextNodeFromList(); node; )
- {
- //if the nodelist isn't empty try to add another thread
- //if (NodeListSize() > 10) AddThread(BuildTreeThread);
- //display the number of nodes processed so far
- if (numthreads == 1)
- IncreaseNodeCounter();
-
- brushes = node->brushlist;
-
- if (numthreads == 1)
- {
- totalmem = WindingMemory() + c_nodememory + c_brushmemory;
- if (totalmem > c_peak_totalbspmemory)
- {
- c_peak_totalbspmemory = totalmem;
- } //end if
- c_nodes++;
- } //endif
-
- if (drawflag)
- {
- DrawBrushList(brushes, node);
- } //end if
-
- if (cancelconversion)
- {
- bestside = NULL;
- } //end if
- else
- {
- // find the best plane to use as a splitter
- bestside = SelectSplitSide(brushes, node);
- } //end else
- //if there's no split side left
- if (!bestside)
- {
- //create a leaf out of the node
- LeafNode(node, brushes);
- if (node->contents & CONTENTS_SOLID) c_solidleafnodes++;
- if (create_aas)
- {
- //free up memory!!!
- FreeBrushList(node->brushlist);
- node->brushlist = NULL;
- } //end if
- //free the node volume brush (it is not used anymore)
- if (node->volume)
- {
- FreeBrush(node->volume);
- node->volume = NULL;
- } //end if
- node = NextNodeFromList();
- continue;
- } //end if
-
- // this is a splitplane node
- node->side = bestside;
- node->planenum = bestside->planenum & ~1; //always use front facing
-
- //allocate children
- for (i = 0; i < 2; i++)
- {
- newnode = AllocNode();
- newnode->parent = node;
- node->children[i] = newnode;
- } //end for
-
- //split the brush list in two for both children
- SplitBrushList(brushes, node, &node->children[0]->brushlist, &node->children[1]->brushlist);
-
- CheckBrushLists(node->children[0]->brushlist, node->children[1]->brushlist);
- //free the old brush list
- FreeBrushList(brushes);
- node->brushlist = NULL;
-
- //split the volume brush of the node for the children
- SplitBrush(node->volume, node->planenum, &node->children[0]->volume,
- &node->children[1]->volume);
-
- if (!node->children[0]->volume || !node->children[1]->volume)
- {
- Error("child without volume brush");
- } //end if
-
- //free the volume brush
- if (node->volume)
- {
- FreeBrush(node->volume);
- node->volume = NULL;
- } //end if
- //add both children to the node list
- //AddNodeToList(node->children[0]);
- AddNodeToList(node->children[1]);
- node = node->children[0];
- } //end while
- RemoveThread(threadid);
-} //end of the function BuildTreeThread
-//===========================================================================
-// build the bsp tree using a node list
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void BuildTree(tree_t *tree)
-{
- int i;
-
- firstnode = NULL;
- lastnode = NULL;
- //use a node queue or node stack
- if (use_nodequeue) AddNodeToList = AddNodeToQueue;
- else AddNodeToList = AddNodeToStack;
- //setup thread locking
- ThreadSetupLock();
- ThreadSetupSemaphore();
- numwaiting = 0;
- //
- Log_Print("%6d threads max\n", numthreads);
- if (use_nodequeue) Log_Print("breadth first bsp building\n");
- else Log_Print("depth first bsp building\n");
- qprintf("%6d splits", 0);
- //add the first node to the list
- AddNodeToList(tree->headnode);
- //start the threads
- for (i = 0; i < numthreads; i++)
- AddThread(BuildTreeThread);
- //wait for all added threads to be finished
- WaitForAllThreadsFinished();
- //shutdown the thread locking
- ThreadShutdownLock();
- ThreadShutdownSemaphore();
-} //end of the function BuildTree
-//===========================================================================
-// The incoming brush list will be freed before exiting
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-tree_t *BrushBSP(bspbrush_t *brushlist, vec3_t mins, vec3_t maxs)
-{
- int i, c_faces, c_nonvisfaces, c_brushes;
- bspbrush_t *b;
- node_t *node;
- tree_t *tree;
- vec_t volume;
-// vec3_t point;
-
- Log_Print("-------- Brush BSP ---------\n");
-
- tree = Tree_Alloc();
-
- c_faces = 0;
- c_nonvisfaces = 0;
- c_brushes = 0;
- c_totalsides = 0;
- for (b = brushlist; b; b = b->next)
- {
- c_brushes++;
-
- volume = BrushVolume(b);
- if (volume < microvolume)
- {
- Log_Print("WARNING: entity %i, brush %i: microbrush\n",
- b->original->entitynum, b->original->brushnum);
- } //end if
-
- for (i=0 ; i<b->numsides ; i++)
- {
- if (b->sides[i].flags & SFL_BEVEL)
- continue;
- if (!b->sides[i].winding)
- continue;
- if (b->sides[i].texinfo == TEXINFO_NODE)
- continue;
- if (b->sides[i].flags & SFL_VISIBLE)
- {
- c_faces++;
- } //end if
- else
- {
- c_nonvisfaces++;
- //if (create_aas) b->sides[i].texinfo = TEXINFO_NODE;
- } //end if
- } //end for
- c_totalsides += b->numsides;
-
- AddPointToBounds (b->mins, tree->mins, tree->maxs);
- AddPointToBounds (b->maxs, tree->mins, tree->maxs);
- } //end for
-
- Log_Print("%6i brushes\n", c_brushes);
- Log_Print("%6i visible faces\n", c_faces);
- Log_Print("%6i nonvisible faces\n", c_nonvisfaces);
- Log_Print("%6i total sides\n", c_totalsides);
-
- c_active_brushes = c_brushes;
- c_nodememory = 0;
- c_brushmemory = 0;
- c_peak_brushmemory = 0;
-
- c_nodes = 0;
- c_nonvis = 0;
- node = AllocNode ();
-
- //volume of first node (head node)
- node->volume = BrushFromBounds (mins, maxs);
- //
- tree->headnode = node;
- //just get some statistics and the mins/maxs of the node
- numrecurse = 0;
-// qprintf("%6d splits", numrecurse);
-
- tree->headnode->brushlist = brushlist;
- BuildTree(tree);
-
- //build the bsp tree with the start node from the brushlist
-// node = BuildTree_r(node, brushlist);
-
- //if the conversion is cancelled
- if (cancelconversion) return tree;
-
- qprintf("\n");
- Log_Write("%6d splits\r\n", numrecurse);
-// Log_Print("%6i visible nodes\n", c_nodes/2 - c_nonvis);
-// Log_Print("%6i nonvis nodes\n", c_nonvis);
-// Log_Print("%6i leaves\n", (c_nodes+1)/2);
-// Log_Print("%6i solid leaf nodes\n", c_solidleafnodes);
-// Log_Print("%6i active brushes\n", c_active_brushes);
- if (numthreads == 1)
- {
-// Log_Print("%6i KB of node memory\n", c_nodememory >> 10);
-// Log_Print("%6i KB of brush memory\n", c_brushmemory >> 10);
-// Log_Print("%6i KB of peak brush memory\n", c_peak_brushmemory >> 10);
-// Log_Print("%6i KB of winding memory\n", WindingMemory() >> 10);
-// Log_Print("%6i KB of peak winding memory\n", WindingPeakMemory() >> 10);
- Log_Print("%6i KB of peak total bsp memory\n", c_peak_totalbspmemory >> 10);
- } //end if
-
- /*
- point[0] = 1485;
- point[1] = 956.125;
- point[2] = 352.125;
- node = PointInLeaf(tree->headnode, point);
- if (node->planenum != PLANENUM_LEAF)
- {
- Log_Print("node not a leaf\n");
- } //end if
- Log_Print("at %f %f %f:\n", point[0], point[1], point[2]);
- PrintContents(node->contents);
- Log_Print("node->expansionbboxes = %d\n", node->expansionbboxes);
- //*/
- return tree;
-} //end of the function BrushBSP
-
diff --git a/code/bspc/bspc.c b/code/bspc/bspc.c
deleted file mode 100644
index 9e241b1..0000000
--- a/code/bspc/bspc.c
+++ /dev/null
@@ -1,991 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-#if defined(WIN32) || defined(_WIN32)
-#include <direct.h>
-#include <windows.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#else
-#include <unistd.h>
-#include <glob.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#endif
-#include "qbsp.h"
-#include "l_mem.h"
-#include "../botlib/aasfile.h"
-#include "../botlib/be_aas_cluster.h"
-#include "../botlib/be_aas_optimize.h"
-#include "aas_create.h"
-#include "aas_store.h"
-#include "aas_file.h"
-#include "aas_cfg.h"
-#include "be_aas_bspc.h"
-
-extern int use_nodequeue; //brushbsp.c
-extern int calcgrapplereach; //be_aas_reach.c
-
-float subdivide_size = 240;
-char source[1024];
-char name[1024];
-vec_t microvolume = 1.0;
-char outbase[32];
-int entity_num;
-aas_settings_t aassettings;
-
-qboolean noprune; //don't prune nodes (bspc.c)
-qboolean glview; //create a gl view
-qboolean nodetail; //don't use detail brushes (map.c)
-qboolean fulldetail; //use but don't mark detail brushes (map.c)
-qboolean onlyents; //only process the entities (bspc.c)
-qboolean nomerge; //don't merge bsp node faces (faces.c)
-qboolean nowater; //don't use the water brushes (map.c)
-qboolean nocsg; //don't carve intersecting brushes (bspc.c)
-qboolean noweld; //use unique face vertexes (faces.c)
-qboolean noshare; //don't share bsp edges (faces.c)
-qboolean nosubdiv; //don't subdivide bsp node faces (faces.c)
-qboolean notjunc; //don't create tjunctions (edge melting) (faces.c)
-qboolean optimize; //enable optimisation
-qboolean leaktest; //perform a leak test
-qboolean verboseentities;
-qboolean freetree; //free the bsp tree when not needed anymore
-qboolean create_aas; //create an .AAS file
-qboolean nobrushmerge; //don't merge brushes
-qboolean lessbrushes; //create less brushes instead of correct texture placement
-qboolean cancelconversion; //true if the conversion is being cancelled
-qboolean noliquids; //no liquids when writing map file
-qboolean forcesidesvisible; //force all brush sides to be visible when loaded from bsp
-qboolean capsule_collision = 0;
-
-/*
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void ProcessWorldModel (void)
-{
- entity_t *e;
- tree_t *tree;
- qboolean leaked;
- int brush_start, brush_end;
-
- e = &entities[entity_num];
-
- brush_start = e->firstbrush;
- brush_end = brush_start + e->numbrushes;
- leaked = false;
-
- //process the whole world in one time
- tree = ProcessWorldBrushes(brush_start, brush_end);
- //create the bsp tree portals
- MakeTreePortals(tree);
- //mark all leafs that can be reached by entities
- if (FloodEntities(tree))
- {
- FillOutside(tree->headnode);
- } //end if
- else
- {
- Log_Print("**** leaked ****\n");
- leaked = true;
- LeakFile(tree);
- if (leaktest)
- {
- Log_Print("--- MAP LEAKED ---\n");
- exit(0);
- } //end if
- } //end else
-
- MarkVisibleSides (tree, brush_start, brush_end);
-
- FloodAreas (tree);
-
-#ifndef ME
- if (glview) WriteGLView(tree, source);
-#endif
- MakeFaces(tree->headnode);
- FixTjuncs(tree->headnode);
-
- //NOTE: Never prune the nodes because the portals
- // are screwed when prunning is done and as
- // a result portal writing will crash
- //if (!noprune) PruneNodes(tree->headnode);
-
- WriteBSP(tree->headnode);
-
- if (!leaked) WritePortalFile(tree);
-
- Tree_Free(tree);
-} //end of the function ProcessWorldModel
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void ProcessSubModel (void)
-{
- entity_t *e;
- int start, end;
- tree_t *tree;
- bspbrush_t *list;
- vec3_t mins, maxs;
-
- e = &entities[entity_num];
-
- start = e->firstbrush;
- end = start + e->numbrushes;
-
- mins[0] = mins[1] = mins[2] = -4096;
- maxs[0] = maxs[1] = maxs[2] = 4096;
- list = MakeBspBrushList(start, end, mins, maxs);
- if (!nocsg) list = ChopBrushes (list);
- tree = BrushBSP (list, mins, maxs);
- MakeTreePortals (tree);
- MarkVisibleSides (tree, start, end);
- MakeFaces (tree->headnode);
- FixTjuncs (tree->headnode);
- WriteBSP (tree->headnode);
- Tree_Free(tree);
-} //end of the function ProcessSubModel
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void ProcessModels (void)
-{
- BeginBSPFile();
-
- for (entity_num = 0; entity_num < num_entities; entity_num++)
- {
- if (!entities[entity_num].numbrushes)
- continue;
-
- Log_Print("############### model %i ###############\n", nummodels);
- BeginModel();
- if (entity_num == 0) ProcessWorldModel();
- else ProcessSubModel();
- EndModel();
-
- if (!verboseentities)
- verbose = false; // don't bother printing submodels
- } //end for
- EndBSPFile();
-} //end of the function ProcessModels
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void Win_Map2Bsp(char *bspfilename)
-{
- double start, end;
- char path[1024];
-
- start = I_FloatTime();
-
- ThreadSetDefault();
- //yeah sure Carmack
- //numthreads = 1; // multiple threads aren't helping...
-
- strcpy(source, ExpandArg(bspfilename));
- StripExtension(source);
-
- //delete portal and line files
- sprintf(path, "%s.prt", source);
- remove(path);
- sprintf(path, "%s.lin", source);
- remove(path);
-
- strcpy(name, ExpandArg(bspfilename));
- DefaultExtension(name, ".map"); // might be .reg
-
- Q2_AllocMaxBSP();
- //
- SetModelNumbers();
- SetLightStyles();
- ProcessModels();
- //write the BSP
- Q2_WriteBSPFile(bspfilename);
-
- Q2_FreeMaxBSP();
-
- end = I_FloatTime();
- Log_Print("%5.0f seconds elapsed\n", end-start);
-} //end of the function Win_Map2Bsp
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void Map2Bsp(char *mapfilename, char *outputfilename)
-{
- double start, end;
- char path[1024];
-
- start = I_FloatTime ();
-
- ThreadSetDefault ();
- //yeah sure Carmack
- //numthreads = 1; //multiple threads aren't helping...
- //SetQdirFromPath(bspfilename);
-
- strcpy(source, ExpandArg(mapfilename));
- StripExtension(source);
-
- // delete portal and line files
- sprintf(path, "%s.prt", source);
- remove(path);
- sprintf(path, "%s.lin", source);
- remove(path);
-
- strcpy(name, ExpandArg(mapfilename));
- DefaultExtension(name, ".map"); // might be .reg
-
- //
- // if onlyents, just grab the entites and resave
- //
- if (onlyents)
- {
- char out[1024];
-
- Q2_AllocMaxBSP();
- sprintf (out, "%s.bsp", source);
- Q2_LoadBSPFile(out, 0, 0);
- num_entities = 0;
-
- Q2_LoadMapFile(name);
- SetModelNumbers();
- SetLightStyles();
-
- Q2_UnparseEntities();
-
- Q2_WriteBSPFile(out);
- //
- Q2_FreeMaxBSP();
- } //end if
- else
- {
- //
- // start from scratch
- //
- Q2_AllocMaxBSP();
- //load the map
- Q2_LoadMapFile(name);
- //create the .bsp file
- SetModelNumbers();
- SetLightStyles();
- ProcessModels();
- //write the BSP
- Q2_WriteBSPFile(outputfilename);
- //
- Q2_FreeMaxBSP();
- } //end else
-
- end = I_FloatTime();
- Log_Print("%5.0f seconds elapsed\n", end-start);
-} //end of the function Map2Bsp
-*/
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AASOuputFile(quakefile_t *qf, char *outputpath, char *filename)
-{
- char ext[MAX_PATH];
-
- //
- if (strlen(outputpath))
- {
- strcpy(filename, outputpath);
- //append the bsp file base
- AppendPathSeperator(filename, MAX_PATH);
- ExtractFileBase(qf->origname, &filename[strlen(filename)]);
- //append .aas
- strcat(filename, ".aas");
- return;
- } //end if
- //
- ExtractFileExtension(qf->filename, ext);
- if (!stricmp(ext, "pk3") || !stricmp(ext, "pak") || !stricmp(ext, "sin"))
- {
- strcpy(filename, qf->filename);
- while(strlen(filename) &&
- filename[strlen(filename)-1] != '\\' &&
- filename[strlen(filename)-1] != '/')
- {
- filename[strlen(filename)-1] = '\0';
- } //end while
- strcat(filename, "maps");
- if (access(filename, 0x04)) CreatePath(filename);
- //append the bsp file base
- AppendPathSeperator(filename, MAX_PATH);
- ExtractFileBase(qf->origname, &filename[strlen(filename)]);
- //append .aas
- strcat(filename, ".aas");
- } //end if
- else
- {
- strcpy(filename, qf->filename);
- while(strlen(filename) &&
- filename[strlen(filename)-1] != '.')
- {
- filename[strlen(filename)-1] = '\0';
- } //end while
- strcat(filename, "aas");
- } //end else
-} //end of the function AASOutputFile
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void CreateAASFilesForAllBSPFiles(char *quakepath)
-{
-#if defined(WIN32)|defined(_WIN32)
- WIN32_FIND_DATA filedata;
- HWND handle;
- struct _stat statbuf;
-#else
- glob_t globbuf;
- struct stat statbuf;
- int j;
-#endif
- int done;
- char filter[_MAX_PATH], bspfilter[_MAX_PATH], aasfilter[_MAX_PATH];
- char aasfile[_MAX_PATH], buf[_MAX_PATH], foldername[_MAX_PATH];
- quakefile_t *qf, *qf2, *files, *bspfiles, *aasfiles;
-
- strcpy(filter, quakepath);
- AppendPathSeperator(filter, sizeof(filter));
- strcat(filter, "*");
-
-#if defined(WIN32)|defined(_WIN32)
- handle = FindFirstFile(filter, &filedata);
- done = (handle == INVALID_HANDLE_VALUE);
- while(!done)
- {
- _splitpath(filter, foldername, NULL, NULL, NULL);
- _splitpath(filter, NULL, &foldername[strlen(foldername)], NULL, NULL);
- AppendPathSeperator(foldername, _MAX_PATH);
- strcat(foldername, filedata.cFileName);
- _stat(foldername, &statbuf);
-#else
- glob(filter, 0, NULL, &globbuf);
- for (j = 0; j < globbuf.gl_pathc; j++)
- {
- strcpy(foldername, globbuf.gl_pathv[j]);
- stat(foldername, &statbuf);
-#endif
- //if it is a folder
- if (statbuf.st_mode & S_IFDIR)
- {
- //
- AppendPathSeperator(foldername, sizeof(foldername));
- //get all the bsp files
- strcpy(bspfilter, foldername);
- strcat(bspfilter, "maps/*.bsp");
- files = FindQuakeFiles(bspfilter);
- strcpy(bspfilter, foldername);
- strcat(bspfilter, "*.pk3/maps/*.bsp");
- bspfiles = FindQuakeFiles(bspfilter);
- for (qf = bspfiles; qf; qf = qf->next) if (!qf->next) break;
- if (qf) qf->next = files;
- else bspfiles = files;
- //get all the aas files
- strcpy(aasfilter, foldername);
- strcat(aasfilter, "maps/*.aas");
- files = FindQuakeFiles(aasfilter);
- strcpy(aasfilter, foldername);
- strcat(aasfilter, "*.pk3/maps/*.aas");
- aasfiles = FindQuakeFiles(aasfilter);
- for (qf = aasfiles; qf; qf = qf->next) if (!qf->next) break;
- if (qf) qf->next = files;
- else aasfiles = files;
- //
- for (qf = bspfiles; qf; qf = qf->next)
- {
- sprintf(aasfile, "%s/%s", qf->pakfile, qf->origname);
- Log_Print("found %s\n", aasfile);
- strcpy(&aasfile[strlen(aasfile)-strlen(".bsp")], ".aas");
- for (qf2 = aasfiles; qf2; qf2 = qf2->next)
- {
- sprintf(buf, "%s/%s", qf2->pakfile, qf2->origname);
- if (!stricmp(aasfile, buf))
- {
- Log_Print("found %s\n", buf);
- break;
- } //end if
- } //end for
- } //end for
- } //end if
-#if defined(WIN32)|defined(_WIN32)
- //find the next file
- done = !FindNextFile(handle, &filedata);
- } //end while
-#else
- } //end for
- globfree(&globbuf);
-#endif
-} //end of the function CreateAASFilesForAllBSPFiles
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-quakefile_t *GetArgumentFiles(int argc, char *argv[], int *i, char *ext)
-{
- quakefile_t *qfiles, *lastqf, *qf;
- int j;
- char buf[1024];
-
- qfiles = NULL;
- lastqf = NULL;
- for (; (*i)+1 < argc && argv[(*i)+1][0] != '-'; (*i)++)
- {
- strcpy(buf, argv[(*i)+1]);
- for (j = strlen(buf)-1; j >= strlen(buf)-4; j--)
- if (buf[j] == '.') break;
- if (j >= strlen(buf)-4)
- strcpy(&buf[j+1], ext);
- qf = FindQuakeFiles(buf);
- if (!qf) continue;
- if (lastqf) lastqf->next = qf;
- else qfiles = qf;
- lastqf = qf;
- while(lastqf->next) lastqf = lastqf->next;
- } //end for
- return qfiles;
-} //end of the function GetArgumentFiles
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-
-#define COMP_BSP2MAP 1
-#define COMP_BSP2AAS 2
-#define COMP_REACH 3
-#define COMP_CLUSTER 4
-#define COMP_AASOPTIMIZE 5
-#define COMP_AASINFO 6
-
-int main (int argc, char **argv)
-{
- int i, comp = 0;
- char outputpath[MAX_PATH] = "";
- char filename[MAX_PATH] = "unknown";
- quakefile_t *qfiles, *qf;
- double start_time;
-
- myargc = argc;
- myargv = argv;
-
- start_time = I_FloatTime();
-
- Log_Open("bspc.log"); //open a log file
- Log_Print("BSPC version "BSPC_VERSION", %s %s\n", __DATE__, __TIME__);
-
- DefaultCfg();
- for (i = 1; i < argc; i++)
- {
- if (!stricmp(argv[i],"-threads"))
- {
- if (i + 1 >= argc) {i = 0; break;}
- numthreads = atoi(argv[++i]);
- Log_Print("threads = %d\n", numthreads);
- } //end if
- else if (!stricmp(argv[i], "-noverbose"))
- {
- Log_Print("verbose = false\n");
- verbose = false;
- } //end else if
- else if (!stricmp(argv[i], "-nocsg"))
- {
- Log_Print("nocsg = true\n");
- nocsg = true;
- } //end else if
- else if (!stricmp(argv[i], "-optimize"))
- {
- Log_Print("optimize = true\n");
- optimize = true;
- } //end else if
- /*
- else if (!stricmp(argv[i],"-glview"))
- {
- glview = true;
- } //end else if
- else if (!stricmp(argv[i], "-draw"))
- {
- Log_Print("drawflag = true\n");
- drawflag = true;
- } //end else if
- else if (!stricmp(argv[i], "-noweld"))
- {
- Log_Print("noweld = true\n");
- noweld = true;
- } //end else if
- else if (!stricmp(argv[i], "-noshare"))
- {
- Log_Print("noshare = true\n");
- noshare = true;
- } //end else if
- else if (!stricmp(argv[i], "-notjunc"))
- {
- Log_Print("notjunc = true\n");
- notjunc = true;
- } //end else if
- else if (!stricmp(argv[i], "-nowater"))
- {
- Log_Print("nowater = true\n");
- nowater = true;
- } //end else if
- else if (!stricmp(argv[i], "-noprune"))
- {
- Log_Print("noprune = true\n");
- noprune = true;
- } //end else if
- else if (!stricmp(argv[i], "-nomerge"))
- {
- Log_Print("nomerge = true\n");
- nomerge = true;
- } //end else if
- else if (!stricmp(argv[i], "-nosubdiv"))
- {
- Log_Print("nosubdiv = true\n");
- nosubdiv = true;
- } //end else if
- else if (!stricmp(argv[i], "-nodetail"))
- {
- Log_Print("nodetail = true\n");
- nodetail = true;
- } //end else if
- else if (!stricmp(argv[i], "-fulldetail"))
- {
- Log_Print("fulldetail = true\n");
- fulldetail = true;
- } //end else if
- else if (!stricmp(argv[i], "-onlyents"))
- {
- Log_Print("onlyents = true\n");
- onlyents = true;
- } //end else if
- else if (!stricmp(argv[i], "-micro"))
- {
- if (i + 1 >= argc) {i = 0; break;}
- microvolume = atof(argv[++i]);
- Log_Print("microvolume = %f\n", microvolume);
- } //end else if
- else if (!stricmp(argv[i], "-leaktest"))
- {
- Log_Print("leaktest = true\n");
- leaktest = true;
- } //end else if
- else if (!stricmp(argv[i], "-verboseentities"))
- {
- Log_Print("verboseentities = true\n");
- verboseentities = true;
- } //end else if
- else if (!stricmp(argv[i], "-chop"))
- {
- if (i + 1 >= argc) {i = 0; break;}
- subdivide_size = atof(argv[++i]);
- Log_Print("subdivide_size = %f\n", subdivide_size);
- } //end else if
- else if (!stricmp (argv[i], "-tmpout"))
- {
- strcpy (outbase, "/tmp");
- Log_Print("temp output\n");
- } //end else if
- */
-#ifdef ME
- else if (!stricmp(argv[i], "-freetree"))
- {
- freetree = true;
- Log_Print("freetree = true\n");
- } //end else if
- else if (!stricmp(argv[i], "-grapplereach"))
- {
- calcgrapplereach = true;
- Log_Print("grapplereach = true\n");
- } //end else if
- else if (!stricmp(argv[i], "-nobrushmerge"))
- {
- nobrushmerge = true;
- Log_Print("nobrushmerge = true\n");
- } //end else if
- else if (!stricmp(argv[i], "-noliquids"))
- {
- noliquids = true;
- Log_Print("noliquids = true\n");
- } //end else if
- else if (!stricmp(argv[i], "-forcesidesvisible"))
- {
- forcesidesvisible = true;
- Log_Print("forcesidesvisible = true\n");
- } //end else if
- else if (!stricmp(argv[i], "-output"))
- {
- if (i + 1 >= argc) {i = 0; break;}
- if (access(argv[i+1], 0x04)) Warning("the folder %s does not exist", argv[i+1]);
- strcpy(outputpath, argv[++i]);
- } //end else if
- else if (!stricmp(argv[i], "-breadthfirst"))
- {
- use_nodequeue = true;
- Log_Print("breadthfirst = true\n");
- } //end else if
- else if (!stricmp(argv[i], "-capsule"))
- {
- capsule_collision = true;
- Log_Print("capsule_collision = true\n");
- } //end else if
- else if (!stricmp(argv[i], "-cfg"))
- {
- if (i + 1 >= argc) {i = 0; break;}
- if (!LoadCfgFile(argv[++i]))
- exit(0);
- } //end else if
- else if (!stricmp(argv[i], "-bsp2map"))
- {
- if (i + 1 >= argc) {i = 0; break;}
- comp = COMP_BSP2MAP;
- qfiles = GetArgumentFiles(argc, argv, &i, "bsp");
- } //end else if
- else if (!stricmp(argv[i], "-bsp2aas"))
- {
- if (i + 1 >= argc) {i = 0; break;}
- comp = COMP_BSP2AAS;
- qfiles = GetArgumentFiles(argc, argv, &i, "bsp");
- } //end else if
- else if (!stricmp(argv[i], "-aasall"))
- {
- if (i + 1 >= argc) {i = 0; break;}
- CreateAASFilesForAllBSPFiles(argv[++i]);
- } //end else if
- else if (!stricmp(argv[i], "-reach"))
- {
- if (i + 1 >= argc) {i = 0; break;}
- comp = COMP_REACH;
- qfiles = GetArgumentFiles(argc, argv, &i, "bsp");
- } //end else if
- else if (!stricmp(argv[i], "-cluster"))
- {
- if (i + 1 >= argc) {i = 0; break;}
- comp = COMP_CLUSTER;
- qfiles = GetArgumentFiles(argc, argv, &i, "bsp");
- } //end else if
- else if (!stricmp(argv[i], "-aasinfo"))
- {
- if (i + 1 >= argc) {i = 0; break;}
- comp = COMP_AASINFO;
- qfiles = GetArgumentFiles(argc, argv, &i, "aas");
- } //end else if
- else if (!stricmp(argv[i], "-aasopt"))
- {
- if (i + 1 >= argc) {i = 0; break;}
- comp = COMP_AASOPTIMIZE;
- qfiles = GetArgumentFiles(argc, argv, &i, "aas");
- } //end else if
-#endif //ME
- else
- {
- Log_Print("unknown parameter %s\n", argv[i]);
- break;
- } //end else
- } //end for
-
- //if there are parameters and there's no mismatch in one of the parameters
- if (argc > 1 && i == argc)
- {
- switch(comp)
- {
- case COMP_BSP2MAP:
- {
- if (!qfiles) Log_Print("no files found\n");
- for (qf = qfiles; qf; qf = qf->next)
- {
- //copy the output path
- strcpy(filename, outputpath);
- //append the bsp file base
- AppendPathSeperator(filename, MAX_PATH);
- ExtractFileBase(qf->origname, &filename[strlen(filename)]);
- //append .map
- strcat(filename, ".map");
- //
- Log_Print("bsp2map: %s to %s\n", qf->origname, filename);
- if (qf->type != QFILETYPE_BSP) Warning("%s is probably not a BSP file\n", qf->origname);
- //
- LoadMapFromBSP(qf);
- //write the map file
- WriteMapFile(filename);
- } //end for
- break;
- } //end case
- case COMP_BSP2AAS:
- {
- if (!qfiles) Log_Print("no files found\n");
- for (qf = qfiles; qf; qf = qf->next)
- {
- AASOuputFile(qf, outputpath, filename);
- //
- Log_Print("bsp2aas: %s to %s\n", qf->origname, filename);
- if (qf->type != QFILETYPE_BSP) Warning("%s is probably not a BSP file\n", qf->origname);
- //set before map loading
- create_aas = 1;
- LoadMapFromBSP(qf);
- //create the AAS file
- AAS_Create(filename);
- //if it's a Quake3 map calculate the reachabilities and clusters
- if (loadedmaptype == MAPTYPE_QUAKE3) AAS_CalcReachAndClusters(qf);
- //
- if (optimize) AAS_Optimize();
- //
- //write out the stored AAS file
- if (!AAS_WriteAASFile(filename))
- {
- Error("error writing %s\n", filename);
- } //end if
- //deallocate memory
- AAS_FreeMaxAAS();
- } //end for
- break;
- } //end case
- case COMP_REACH:
- {
- if (!qfiles) Log_Print("no files found\n");
- for (qf = qfiles; qf; qf = qf->next)
- {
- AASOuputFile(qf, outputpath, filename);
- //
- Log_Print("reach: %s to %s\n", qf->origname, filename);
- if (qf->type != QFILETYPE_BSP) Warning("%s is probably not a BSP file\n", qf->origname);
- //if the AAS file exists in the output directory
- if (!access(filename, 0x04))
- {
- if (!AAS_LoadAASFile(filename, 0, 0))
- {
- Error("error loading aas file %s\n", filename);
- } //end if
- //assume it's a Quake3 BSP file
- loadedmaptype = MAPTYPE_QUAKE3;
- } //end if
- else
- {
- Warning("AAS file %s not found in output folder\n", filename);
- Log_Print("creating %s...\n", filename);
- //set before map loading
- create_aas = 1;
- LoadMapFromBSP(qf);
- //create the AAS file
- AAS_Create(filename);
- } //end else
- //if it's a Quake3 map calculate the reachabilities and clusters
- if (loadedmaptype == MAPTYPE_QUAKE3)
- {
- AAS_CalcReachAndClusters(qf);
- } //end if
- //
- if (optimize) AAS_Optimize();
- //write out the stored AAS file
- if (!AAS_WriteAASFile(filename))
- {
- Error("error writing %s\n", filename);
- } //end if
- //deallocate memory
- AAS_FreeMaxAAS();
- } //end for
- break;
- } //end case
- case COMP_CLUSTER:
- {
- if (!qfiles) Log_Print("no files found\n");
- for (qf = qfiles; qf; qf = qf->next)
- {
- AASOuputFile(qf, outputpath, filename);
- //
- Log_Print("cluster: %s to %s\n", qf->origname, filename);
- if (qf->type != QFILETYPE_BSP) Warning("%s is probably not a BSP file\n", qf->origname);
- //if the AAS file exists in the output directory
- if (!access(filename, 0x04))
- {
- if (!AAS_LoadAASFile(filename, 0, 0))
- {
- Error("error loading aas file %s\n", filename);
- } //end if
- //assume it's a Quake3 BSP file
- loadedmaptype = MAPTYPE_QUAKE3;
- //if it's a Quake3 map calculate the clusters
- if (loadedmaptype == MAPTYPE_QUAKE3)
- {
- aasworld.numclusters = 0;
- AAS_InitBotImport();
- AAS_InitClustering();
- } //end if
- } //end if
- else
- {
- Warning("AAS file %s not found in output folder\n", filename);
- Log_Print("creating %s...\n", filename);
- //set before map loading
- create_aas = 1;
- LoadMapFromBSP(qf);
- //create the AAS file
- AAS_Create(filename);
- //if it's a Quake3 map calculate the reachabilities and clusters
- if (loadedmaptype == MAPTYPE_QUAKE3) AAS_CalcReachAndClusters(qf);
- } //end else
- //
- if (optimize) AAS_Optimize();
- //write out the stored AAS file
- if (!AAS_WriteAASFile(filename))
- {
- Error("error writing %s\n", filename);
- } //end if
- //deallocate memory
- AAS_FreeMaxAAS();
- } //end for
- break;
- } //end case
- case COMP_AASOPTIMIZE:
- {
- if (!qfiles) Log_Print("no files found\n");
- for (qf = qfiles; qf; qf = qf->next)
- {
- AASOuputFile(qf, outputpath, filename);
- //
- Log_Print("optimizing: %s to %s\n", qf->origname, filename);
- if (qf->type != QFILETYPE_AAS) Warning("%s is probably not a AAS file\n", qf->origname);
- //
- AAS_InitBotImport();
- //
- if (!AAS_LoadAASFile(qf->filename, qf->offset, qf->length))
- {
- Error("error loading aas file %s\n", qf->filename);
- } //end if
- AAS_Optimize();
- //write out the stored AAS file
- if (!AAS_WriteAASFile(filename))
- {
- Error("error writing %s\n", filename);
- } //end if
- //deallocate memory
- AAS_FreeMaxAAS();
- } //end for
- break;
- } //end case
- case COMP_AASINFO:
- {
- if (!qfiles) Log_Print("no files found\n");
- for (qf = qfiles; qf; qf = qf->next)
- {
- AASOuputFile(qf, outputpath, filename);
- //
- Log_Print("aas info for: %s\n", filename);
- if (qf->type != QFILETYPE_AAS) Warning("%s is probably not a AAS file\n", qf->origname);
- //
- AAS_InitBotImport();
- //
- if (!AAS_LoadAASFile(qf->filename, qf->offset, qf->length))
- {
- Error("error loading aas file %s\n", qf->filename);
- } //end if
- AAS_ShowTotals();
- } //end for
- } //end case
- default:
- {
- Log_Print("don't know what to do\n");
- break;
- } //end default
- } //end switch
- } //end if
- else
- {
- Log_Print("Usage: bspc [-<switch> [-<switch> ...]]\n"
-#if defined(WIN32) || defined(_WIN32)
- "Example 1: bspc -bsp2aas d:\\quake3\\baseq3\\maps\\mymap?.bsp\n"
- "Example 2: bspc -bsp2aas d:\\quake3\\baseq3\\pak0.pk3\\maps/q3dm*.bsp\n"
-#else
- "Example 1: bspc -bsp2aas /quake3/baseq3/maps/mymap?.bsp\n"
- "Example 2: bspc -bsp2aas /quake3/baseq3/pak0.pk3/maps/q3dm*.bsp\n"
-#endif
- "\n"
- "Switches:\n"
- //" bsp2map <[pakfilter/]filter.bsp> = convert BSP to MAP\n"
- //" aasall <quake3folder> = create AAS files for all BSPs\n"
- " bsp2aas <[pakfilter/]filter.bsp> = convert BSP to AAS\n"
- " reach <filter.bsp> = compute reachability & clusters\n"
- " cluster <filter.aas> = compute clusters\n"
- " aasopt <filter.aas> = optimize aas file\n"
- " aasinfo <filter.aas> = show AAS file info\n"
- " output <output path> = set output path\n"
- " threads <X> = set number of threads to X\n"
- " cfg <filename> = use this cfg file\n"
- " optimize = enable optimization\n"
- " noverbose = disable verbose output\n"
- " breadthfirst = breadth first bsp building\n"
- " nobrushmerge = don't merge brushes\n"
- " noliquids = don't write liquids to map\n"
- " freetree = free the bsp tree\n"
- " nocsg = disables brush chopping\n"
- " forcesidesvisible = force all sides to be visible\n"
- " grapplereach = calculate grapple reachabilities\n"
-
-/* " glview = output a GL view\n"
- " draw = enables drawing\n"
- " noweld = disables weld\n"
- " noshare = disables sharing\n"
- " notjunc = disables juncs\n"
- " nowater = disables water brushes\n"
- " noprune = disables node prunes\n"
- " nomerge = disables face merging\n"
- " nosubdiv = disables subdeviding\n"
- " nodetail = disables detail brushes\n"
- " fulldetail = enables full detail\n"
- " onlyents = only compile entities with bsp\n"
- " micro <volume>\n"
- " = sets the micro volume to the given float\n"
- " leaktest = perform a leak test\n"
- " verboseentities\n"
- " = enable entity verbose mode\n"
- " chop <subdivide_size>\n"
- " = sets the subdivide size to the given float\n"*/
- "\n");
- } //end else
- Log_Print("BSPC run time is %5.0f seconds\n", I_FloatTime() - start_time);
- Log_Close(); //close the log file
- return 0;
-} //end of the function main
-
diff --git a/code/bspc/bspc.sln b/code/bspc/bspc.sln
deleted file mode 100644
index b09fb52..0000000
--- a/code/bspc/bspc.sln
+++ /dev/null
@@ -1,28 +0,0 @@
-Microsoft Visual Studio Solution File, Format Version 8.00
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bspc", "bspc.vcproj", "{4E4EBC16-F345-4667-84E1-86633BAFDAE6}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Global
- GlobalSection(SourceCodeControl) = preSolution
- SccNumberOfProjects = 1
- SccProjectUniqueName0 = bspc.vcproj
- SccProjectName0 = \u0022$/source/code/bspc\u0022,\u0020IGAAAAAA
- SccLocalPath0 = .
- SccProvider0 = MSSCCI:Perforce\u0020SCM
- EndGlobalSection
- GlobalSection(SolutionConfiguration) = preSolution
- Debug = Debug
- Release = Release
- EndGlobalSection
- GlobalSection(ProjectConfiguration) = postSolution
- {4E4EBC16-F345-4667-84E1-86633BAFDAE6}.Debug.ActiveCfg = Debug|Win32
- {4E4EBC16-F345-4667-84E1-86633BAFDAE6}.Debug.Build.0 = Debug|Win32
- {4E4EBC16-F345-4667-84E1-86633BAFDAE6}.Release.ActiveCfg = Release|Win32
- {4E4EBC16-F345-4667-84E1-86633BAFDAE6}.Release.Build.0 = Release|Win32
- EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
- EndGlobalSection
- GlobalSection(ExtensibilityAddIns) = postSolution
- EndGlobalSection
-EndGlobal
diff --git a/code/bspc/bspc.vcproj b/code/bspc/bspc.vcproj
deleted file mode 100644
index 0fb1bd7..0000000
--- a/code/bspc/bspc.vcproj
+++ /dev/null
@@ -1,1381 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="7.10"
- Name="bspc"
- SccProjectName="&quot;$/source/code/bspc&quot;, IGAAAAAA"
- SccLocalPath=".">
- <Platforms>
- <Platform
- Name="Win32"/>
- </Platforms>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory=".\Debug"
- IntermediateDirectory=".\Debug"
- ConfigurationType="1"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="FALSE"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BSPC"
- BasicRuntimeChecks="3"
- RuntimeLibrary="1"
- UsePrecompiledHeader="2"
- PrecompiledHeaderFile=".\Debug/bspc.pch"
- AssemblerListingLocation=".\Debug/"
- ObjectFile=".\Debug/"
- ProgramDataBaseFileName=".\Debug/"
- WarningLevel="3"
- SuppressStartupBanner="TRUE"
- DebugInformationFormat="4"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- OutputFile="..\Debug\bspc.exe"
- LinkIncremental="1"
- SuppressStartupBanner="TRUE"
- GenerateDebugInformation="TRUE"
- ProgramDatabaseFile=".\Debug/bspc.pdb"
- SubSystem="1"
- TargetMachine="1"/>
- <Tool
- Name="VCMIDLTool"
- TypeLibraryName=".\Debug/bspc.tlb"
- HeaderFileName=""/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG"
- Culture="1033"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCXMLDataGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- <Tool
- Name="VCManagedWrapperGeneratorTool"/>
- <Tool
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory=".\Release"
- IntermediateDirectory=".\Release"
- ConfigurationType="1"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="FALSE"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- InlineFunctionExpansion="1"
- PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BSPC"
- StringPooling="TRUE"
- RuntimeLibrary="0"
- EnableFunctionLevelLinking="TRUE"
- UsePrecompiledHeader="2"
- PrecompiledHeaderFile=".\Release/bspc.pch"
- AssemblerListingLocation=".\Release/"
- ObjectFile=".\Release/"
- ProgramDataBaseFileName=".\Release/"
- WarningLevel="3"
- SuppressStartupBanner="TRUE"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- OutputFile="..\Release\bspc.exe"
- LinkIncremental="1"
- SuppressStartupBanner="TRUE"
- ProgramDatabaseFile=".\Release/bspc.pdb"
- SubSystem="1"
- TargetMachine="1"/>
- <Tool
- Name="VCMIDLTool"
- TypeLibraryName=".\Release/bspc.tlb"
- HeaderFileName=""/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG"
- Culture="1033"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCXMLDataGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- <Tool
- Name="VCManagedWrapperGeneratorTool"/>
- <Tool
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
- <File
- RelativePath="_files.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="aas_areamerging.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="aas_cfg.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="aas_create.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="aas_edgemelting.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="aas_facemerging.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="aas_file.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="aas_gsubdiv.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="aas_map.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="aas_prunenodes.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="aas_store.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="be_aas_bspc.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\botlib\be_aas_bspq3.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\botlib\be_aas_cluster.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\botlib\be_aas_move.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\botlib\be_aas_optimize.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\botlib\be_aas_reach.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\botlib\be_aas_sample.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="brushbsp.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="bspc.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\qcommon\cm_load.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\qcommon\cm_patch.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\qcommon\cm_test.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\qcommon\cm_trace.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="csg.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="glfile.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="l_bsp_ent.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="l_bsp_hl.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="l_bsp_q1.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="l_bsp_q2.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="l_bsp_q3.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="l_bsp_sin.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="l_cmd.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\botlib\l_libvar.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="l_log.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="l_math.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="l_mem.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="l_poly.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\botlib\l_precomp.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="l_qfiles.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\botlib\l_script.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\botlib\l_struct.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="l_threads.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="l_utils.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="leakfile.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="map.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="map_hl.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="map_q1.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="map_q2.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="map_q3.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="map_sin.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\qcommon\md4.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="nodraw.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="portals.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="textures.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="tree.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- <File
- RelativePath="..\qcommon\unzip.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl">
- <File
- RelativePath="aas_areamerging.h">
- </File>
- <File
- RelativePath="aas_cfg.h">
- </File>
- <File
- RelativePath="aas_create.h">
- </File>
- <File
- RelativePath="aas_edgemelting.h">
- </File>
- <File
- RelativePath="aas_facemerging.h">
- </File>
- <File
- RelativePath="aas_file.h">
- </File>
- <File
- RelativePath="aas_gsubdiv.h">
- </File>
- <File
- RelativePath="aas_map.h">
- </File>
- <File
- RelativePath="aas_prunenodes.h">
- </File>
- <File
- RelativePath="aas_store.h">
- </File>
- <File
- RelativePath="..\botlib\aasfile.h">
- </File>
- <File
- RelativePath="..\botlib\be_aas_bsp.h">
- </File>
- <File
- RelativePath="be_aas_bspc.h">
- </File>
- <File
- RelativePath="..\botlib\be_aas_cluster.h">
- </File>
- <File
- RelativePath="..\botlib\be_aas_debug.h">
- </File>
- <File
- RelativePath="..\botlib\be_aas_def.h">
- </File>
- <File
- RelativePath="..\botlib\be_aas_entity.h">
- </File>
- <File
- RelativePath="..\botlib\be_aas_file.h">
- </File>
- <File
- RelativePath="..\botlib\be_aas_funcs.h">
- </File>
- <File
- RelativePath="..\botlib\be_aas_main.h">
- </File>
- <File
- RelativePath="..\botlib\be_aas_move.h">
- </File>
- <File
- RelativePath="..\botlib\be_aas_optimize.h">
- </File>
- <File
- RelativePath="..\botlib\be_aas_reach.h">
- </File>
- <File
- RelativePath="..\botlib\be_aas_route.h">
- </File>
- <File
- RelativePath="..\botlib\be_aas_routealt.h">
- </File>
- <File
- RelativePath="..\botlib\be_aas_sample.h">
- </File>
- <File
- RelativePath="..\botlib\be_interface.h">
- </File>
- <File
- RelativePath="..\game\bg_public.h">
- </File>
- <File
- RelativePath="..\cgame\cg_public.h">
- </File>
- <File
- RelativePath="..\client\client.h">
- </File>
- <File
- RelativePath="..\qcommon\cm_local.h">
- </File>
- <File
- RelativePath="..\qcommon\cm_patch.h">
- </File>
- <File
- RelativePath="..\qcommon\cm_polylib.h">
- </File>
- <File
- RelativePath="..\qcommon\cm_public.h">
- </File>
- <File
- RelativePath="..\ui\keycodes.h">
- </File>
- <File
- RelativePath="..\client\keys.h">
- </File>
- <File
- RelativePath="l_bsp_ent.h">
- </File>
- <File
- RelativePath="l_bsp_hl.h">
- </File>
- <File
- RelativePath="l_bsp_q1.h">
- </File>
- <File
- RelativePath="l_bsp_q2.h">
- </File>
- <File
- RelativePath="l_bsp_q3.h">
- </File>
- <File
- RelativePath="l_bsp_sin.h">
- </File>
- <File
- RelativePath="l_cmd.h">
- </File>
- <File
- RelativePath="..\botlib\l_libvar.h">
- </File>
- <File
- RelativePath="l_log.h">
- </File>
- <File
- RelativePath="..\botlib\l_log.h">
- </File>
- <File
- RelativePath="l_math.h">
- </File>
- <File
- RelativePath="l_mem.h">
- </File>
- <File
- RelativePath="..\botlib\l_memory.h">
- </File>
- <File
- RelativePath="l_poly.h">
- </File>
- <File
- RelativePath="..\botlib\l_precomp.h">
- </File>
- <File
- RelativePath="l_qfiles.h">
- </File>
- <File
- RelativePath="..\botlib\l_script.h">
- </File>
- <File
- RelativePath="..\botlib\l_struct.h">
- </File>
- <File
- RelativePath="l_threads.h">
- </File>
- <File
- RelativePath="l_utils.h">
- </File>
- <File
- RelativePath="q2files.h">
- </File>
- <File
- RelativePath="q3files.h">
- </File>
- <File
- RelativePath="..\game\q_shared.h">
- </File>
- <File
- RelativePath="qbsp.h">
- </File>
- <File
- RelativePath="..\qcommon\qcommon.h">
- </File>
- <File
- RelativePath="..\qcommon\qfiles.h">
- </File>
- <File
- RelativePath="sinfiles.h">
- </File>
- <File
- RelativePath="..\client\snd_public.h">
- </File>
- <File
- RelativePath="..\game\surfaceflags.h">
- </File>
- <File
- RelativePath="..\renderer\tr_public.h">
- </File>
- <File
- RelativePath="..\cgame\tr_types.h">
- </File>
- <File
- RelativePath="..\ui\ui_public.h">
- </File>
- <File
- RelativePath="..\qcommon\unzip.h">
- </File>
- </Filter>
- <Filter
- Name="Resource Files"
- Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/code/bspc/cfgq3.c b/code/bspc/cfgq3.c
deleted file mode 100644
index 9ec244f..0000000
--- a/code/bspc/cfgq3.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-//===========================================================================
-// BSPC configuration file
-// Quake3
-//===========================================================================
-
-#define PRESENCE_NONE 1
-#define PRESENCE_NORMAL 2
-#define PRESENCE_CROUCH 4
-
-bbox //30x30x56
-{
- presencetype PRESENCE_NORMAL
- flags 0x0000
- mins {-15, -15, -24}
- maxs {15, 15, 32}
-} //end bbox
-
-bbox //30x30x40
-{
- presencetype PRESENCE_CROUCH
- flags 0x0001
- mins {-15, -15, -24}
- maxs {15, 15, 16}
-} //end bbox
-
-settings
-{
- phys_gravitydirection {0, 0, -1}
- phys_friction 6
- phys_stopspeed 100
- phys_gravity 800
- phys_waterfriction 1
- phys_watergravity 400
- phys_maxvelocity 320
- phys_maxwalkvelocity 320
- phys_maxcrouchvelocity 100
- phys_maxswimvelocity 150
- phys_maxacceleration 2200
- phys_airaccelerate 0
- phys_maxstep 18
- phys_maxsteepness 0.7
- phys_maxwaterjump 19
- phys_maxbarrier 33
- phys_jumpvel 270
- phys_falldelta5 40
- phys_falldelta10 60
- rs_waterjump 400
- rs_teleport 50
- rs_barrierjump 100
- rs_startcrouch 300
- rs_startgrapple 500
- rs_startwalkoffledge 70
- rs_startjump 300
- rs_rocketjump 500
- rs_bfgjump 500
- rs_jumppad 250
- rs_aircontrolledjumppad 300
- rs_funcbob 300
- rs_startelevator 50
- rs_falldamage5 300
- rs_falldamage10 500
- rs_maxjumpfallheight 450
-} //end settings
diff --git a/code/bspc/csg.c b/code/bspc/csg.c
deleted file mode 100644
index 4242c09..0000000
--- a/code/bspc/csg.c
+++ /dev/null
@@ -1,1005 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-#include "qbsp.h"
-
-/*
-
-tag all brushes with original contents
-brushes may contain multiple contents
-there will be no brush overlap after csg phase
-
-*/
-
-int minplanenums[3];
-int maxplanenums[3];
-
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void CheckBSPBrush(bspbrush_t *brush)
-{
- int i, j;
- plane_t *plane1, *plane2;
-
- //check if the brush is convex... flipped planes make a brush non-convex
- for (i = 0; i < brush->numsides; i++)
- {
- for (j = 0; j < brush->numsides; j++)
- {
- if (i == j) continue;
- plane1 = &mapplanes[brush->sides[i].planenum];
- plane2 = &mapplanes[brush->sides[j].planenum];
- //
- if (WindingsNonConvex(brush->sides[i].winding,
- brush->sides[j].winding,
- plane1->normal, plane2->normal,
- plane1->dist, plane2->dist))
- {
- Log_Print("non convex brush");
- break;
- } //end if
- } //end for
- } //end for
- BoundBrush(brush);
- //check for out of bound brushes
- for (i = 0; i < 3; i++)
- {
- if (brush->mins[i] < -MAX_MAP_BOUNDS || brush->maxs[i] > MAX_MAP_BOUNDS)
- {
- Log_Print("brush: bounds out of range\n");
- Log_Print("ob->mins[%d] = %f, ob->maxs[%d] = %f\n", i, brush->mins[i], i, brush->maxs[i]);
- break;
- } //end if
- if (brush->mins[i] > MAX_MAP_BOUNDS || brush->maxs[i] < -MAX_MAP_BOUNDS)
- {
- Log_Print("brush: no visible sides on brush\n");
- Log_Print("ob->mins[%d] = %f, ob->maxs[%d] = %f\n", i, brush->mins[i], i, brush->maxs[i]);
- break;
- } //end if
- } //end for
-} //end of the function CheckBSPBrush
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void BSPBrushWindings(bspbrush_t *brush)
-{
- int i, j;
- winding_t *w;
- plane_t *plane;
-
- for (i = 0; i < brush->numsides; i++)
- {
- plane = &mapplanes[brush->sides[i].planenum];
- w = BaseWindingForPlane(plane->normal, plane->dist);
- for (j = 0; j < brush->numsides && w; j++)
- {
- if (i == j) continue;
- plane = &mapplanes[brush->sides[j].planenum^1];
- ChopWindingInPlace(&w, plane->normal, plane->dist, 0); //CLIP_EPSILON);
- } //end for
- brush->sides[i].winding = w;
- } //end for
-} //end of the function BSPBrushWindings
-//===========================================================================
-// NOTE: can't keep brush->original intact
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-bspbrush_t *TryMergeBrushes(bspbrush_t *brush1, bspbrush_t *brush2)
-{
- int i, j, k, n, shared;
- side_t *side1, *side2, *cs;
- plane_t *plane1, *plane2;
- bspbrush_t *newbrush;
-
- //check for bounding box overlapp
- for (i = 0; i < 3; i++)
- {
- if (brush1->mins[i] > brush2->maxs[i] + 2
- || brush1->maxs[i] < brush2->mins[i] - 2)
- {
- return NULL;
- } //end if
- } //end for
- //
- shared = 0;
- //check if the brush is convex... flipped planes make a brush non-convex
- for (i = 0; i < brush1->numsides; i++)
- {
- side1 = &brush1->sides[i];
- //don't check the "shared" sides
- for (k = 0; k < brush2->numsides; k++)
- {
- side2 = &brush2->sides[k];
- if (side1->planenum == (side2->planenum^1))
- {
- shared++;
- //there may only be ONE shared side
- if (shared > 1) return NULL;
- break;
- } //end if
- } //end for
- if (k < brush2->numsides) continue;
- //
- for (j = 0; j < brush2->numsides; j++)
- {
- side2 = &brush2->sides[j];
- //don't check the "shared" sides
- for (n = 0; n < brush1->numsides; n++)
- {
- side1 = &brush1->sides[n];
- if (side1->planenum == (side2->planenum^1)) break;
- } //end for
- if (n < brush1->numsides) continue;
- //
- side1 = &brush1->sides[i];
- //if the side is in the same plane
- //*
- if (side1->planenum == side2->planenum)
- {
- if (side1->texinfo != TEXINFO_NODE &&
- side2->texinfo != TEXINFO_NODE &&
- side1->texinfo != side2->texinfo) return NULL;
- continue;
- } //end if
- //
- plane1 = &mapplanes[side1->planenum];
- plane2 = &mapplanes[side2->planenum];
- //
- if (WindingsNonConvex(side1->winding, side2->winding,
- plane1->normal, plane2->normal,
- plane1->dist, plane2->dist))
- {
- return NULL;
- } //end if
- } //end for
- } //end for
- newbrush = AllocBrush(brush1->numsides + brush2->numsides);
- newbrush->original = brush1->original;
- newbrush->numsides = 0;
- //newbrush->side = brush1->side; //brush contents
- //fix texinfos for sides lying in the same plane
- for (i = 0; i < brush1->numsides; i++)
- {
- side1 = &brush1->sides[i];
- //
- for (n = 0; n < brush2->numsides; n++)
- {
- side2 = &brush2->sides[n];
- //if both sides are in the same plane get the texinfo right
- if (side1->planenum == side2->planenum)
- {
- if (side1->texinfo == TEXINFO_NODE) side1->texinfo = side2->texinfo;
- if (side2->texinfo == TEXINFO_NODE) side2->texinfo = side1->texinfo;
- } //end if
- } //end for
- } //end for
- //
- for (i = 0; i < brush1->numsides; i++)
- {
- side1 = &brush1->sides[i];
- //don't add the "shared" sides
- for (n = 0; n < brush2->numsides; n++)
- {
- side2 = &brush2->sides[n];
- if (side1->planenum == (side2->planenum ^ 1)) break;
- } //end for
- if (n < brush2->numsides) continue;
- //
- for (n = 0; n < newbrush->numsides; n++)
- {
- cs = &newbrush->sides[n];
- if (cs->planenum == side1->planenum)
- {
- Log_Print("brush duplicate plane\n");
- break;
- } //end if
- } //end if
- if (n < newbrush->numsides) continue;
- //add this side
- cs = &newbrush->sides[newbrush->numsides];
- newbrush->numsides++;
- *cs = *side1;
- } //end for
- for (j = 0; j < brush2->numsides; j++)
- {
- side2 = &brush2->sides[j];
- for (n = 0; n < brush1->numsides; n++)
- {
- side1 = &brush1->sides[n];
- //if the side is in the same plane
- if (side2->planenum == side1->planenum) break;
- //don't add the "shared" sides
- if (side2->planenum == (side1->planenum ^ 1)) break;
- } //end for
- if (n < brush1->numsides) continue;
- //
- for (n = 0; n < newbrush->numsides; n++)
- {
- cs = &newbrush->sides[n];
- if (cs->planenum == side2->planenum)
- {
- Log_Print("brush duplicate plane\n");
- break;
- } //end if
- } //end if
- if (n < newbrush->numsides) continue;
- //add this side
- cs = &newbrush->sides[newbrush->numsides];
- newbrush->numsides++;
- *cs = *side2;
- } //end for
- BSPBrushWindings(newbrush);
- BoundBrush(newbrush);
- CheckBSPBrush(newbrush);
- return newbrush;
-} //end of the function TryMergeBrushes
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-bspbrush_t *MergeBrushes(bspbrush_t *brushlist)
-{
- int nummerges, merged;
- bspbrush_t *b1, *b2, *tail, *newbrush, *newbrushlist;
- bspbrush_t *lastb2;
-
- if (!brushlist) return NULL;
-
- qprintf("%5d brushes merged", nummerges = 0);
- do
- {
- for (tail = brushlist; tail; tail = tail->next)
- {
- if (!tail->next) break;
- } //end for
- merged = 0;
- newbrushlist = NULL;
- for (b1 = brushlist; b1; b1 = brushlist)
- {
- lastb2 = b1;
- for (b2 = b1->next; b2; b2 = b2->next)
- {
- //if the brushes don't have the same contents
- if (b1->original->contents != b2->original->contents ||
- b1->original->expansionbbox != b2->original->expansionbbox) newbrush = NULL;
- else newbrush = TryMergeBrushes(b1, b2);
- if (newbrush)
- {
- tail->next = newbrush;
- lastb2->next = b2->next;
- brushlist = brushlist->next;
- FreeBrush(b1);
- FreeBrush(b2);
- for (tail = brushlist; tail; tail = tail->next)
- {
- if (!tail->next) break;
- } //end for
- merged++;
- qprintf("\r%5d", nummerges++);
- break;
- } //end if
- lastb2 = b2;
- } //end for
- //if b1 can't be merged with any of the other brushes
- if (!b2)
- {
- brushlist = brushlist->next;
- //keep b1
- b1->next = newbrushlist;
- newbrushlist = b1;
- } //end else
- } //end for
- brushlist = newbrushlist;
- } while(merged);
- qprintf("\n");
- return newbrushlist;
-} //end of the function MergeBrushes
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void SplitBrush2 (bspbrush_t *brush, int planenum,
- bspbrush_t **front, bspbrush_t **back)
-{
- SplitBrush (brush, planenum, front, back);
-#if 0
- if (*front && (*front)->sides[(*front)->numsides-1].texinfo == -1)
- (*front)->sides[(*front)->numsides-1].texinfo = (*front)->sides[0].texinfo; // not -1
- if (*back && (*back)->sides[(*back)->numsides-1].texinfo == -1)
- (*back)->sides[(*back)->numsides-1].texinfo = (*back)->sides[0].texinfo; // not -1
-#endif
-} //end of the function SplitBrush2
-//===========================================================================
-// Returns a list of brushes that remain after B is subtracted from A.
-// May by empty if A is contained inside B.
-// The originals are undisturbed.
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-bspbrush_t *SubtractBrush (bspbrush_t *a, bspbrush_t *b)
-{ // a - b = out (list)
- int i;
- bspbrush_t *front, *back;
- bspbrush_t *out, *in;
-
- in = a;
- out = NULL;
- for (i = 0; i < b->numsides && in; i++)
- {
- SplitBrush2(in, b->sides[i].planenum, &front, &back);
- if (in != a) FreeBrush(in);
- if (front)
- { // add to list
- front->next = out;
- out = front;
- } //end if
- in = back;
- } //end for
- if (in)
- {
- FreeBrush (in);
- } //end if
- else
- { // didn't really intersect
- FreeBrushList (out);
- return a;
- } //end else
- return out;
-} //end of the function SubtractBrush
-//===========================================================================
-// Returns a single brush made up by the intersection of the
-// two provided brushes, or NULL if they are disjoint.
-//
-// The originals are undisturbed.
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-bspbrush_t *IntersectBrush (bspbrush_t *a, bspbrush_t *b)
-{
- int i;
- bspbrush_t *front, *back;
- bspbrush_t *in;
-
- in = a;
- for (i=0 ; i<b->numsides && in ; i++)
- {
- SplitBrush2(in, b->sides[i].planenum, &front, &back);
- if (in != a) FreeBrush(in);
- if (front) FreeBrush(front);
- in = back;
- } //end for
-
- if (in == a) return NULL;
-
- in->next = NULL;
- return in;
-} //end of the function IntersectBrush
-//===========================================================================
-// Returns true if the two brushes definately do not intersect.
-// There will be false negatives for some non-axial combinations.
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-qboolean BrushesDisjoint (bspbrush_t *a, bspbrush_t *b)
-{
- int i, j;
-
- // check bounding boxes
- for (i=0 ; i<3 ; i++)
- if (a->mins[i] >= b->maxs[i]
- || a->maxs[i] <= b->mins[i])
- return true; // bounding boxes don't overlap
-
- // check for opposing planes
- for (i=0 ; i<a->numsides ; i++)
- {
- for (j=0 ; j<b->numsides ; j++)
- {
- if (a->sides[i].planenum ==
- (b->sides[j].planenum^1) )
- return true; // opposite planes, so not touching
- }
- }
-
- return false; // might intersect
-} //end of the function BrushesDisjoint
-//===========================================================================
-// Returns a content word for the intersection of two brushes.
-// Some combinations will generate a combination (water + clip),
-// but most will be the stronger of the two contents.
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int IntersectionContents (int c1, int c2)
-{
- int out;
-
- out = c1 | c2;
-
- if (out & CONTENTS_SOLID) out = CONTENTS_SOLID;
-
- return out;
-} //end of the function IntersectionContents
-//===========================================================================
-// Any planes shared with the box edge will be set to no texinfo
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-bspbrush_t *ClipBrushToBox(bspbrush_t *brush, vec3_t clipmins, vec3_t clipmaxs)
-{
- int i, j;
- bspbrush_t *front, *back;
- int p;
-
- for (j=0 ; j<2 ; j++)
- {
- if (brush->maxs[j] > clipmaxs[j])
- {
- SplitBrush (brush, maxplanenums[j], &front, &back);
- if (front)
- FreeBrush (front);
- brush = back;
- if (!brush)
- return NULL;
- }
- if (brush->mins[j] < clipmins[j])
- {
- SplitBrush (brush, minplanenums[j], &front, &back);
- if (back)
- FreeBrush (back);
- brush = front;
- if (!brush)
- return NULL;
- }
- }
-
- // remove any colinear faces
-
- for (i=0 ; i<brush->numsides ; i++)
- {
- p = brush->sides[i].planenum & ~1;
- if (p == maxplanenums[0] || p == maxplanenums[1]
- || p == minplanenums[0] || p == minplanenums[1])
- {
- brush->sides[i].texinfo = TEXINFO_NODE;
- brush->sides[i].flags &= ~SFL_VISIBLE;
- }
- }
- return brush;
-} //end of the function ClipBrushToBox
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-bspbrush_t *MakeBspBrushList(int startbrush, int endbrush,
- vec3_t clipmins, vec3_t clipmaxs)
-{
- mapbrush_t *mb;
- bspbrush_t *brushlist, *newbrush;
- int i, j;
- int c_faces;
- int c_brushes;
- int numsides;
- int vis;
- vec3_t normal;
- float dist;
-
- for (i=0 ; i<2 ; i++)
- {
- VectorClear (normal);
- normal[i] = 1;
- dist = clipmaxs[i];
- maxplanenums[i] = FindFloatPlane(normal, dist);
- dist = clipmins[i];
- minplanenums[i] = FindFloatPlane(normal, dist);
- }
-
- brushlist = NULL;
- c_faces = 0;
- c_brushes = 0;
-
- for (i=startbrush ; i<endbrush ; i++)
- {
- mb = &mapbrushes[i];
-
- numsides = mb->numsides;
- if (!numsides)
- continue;
-
- // make sure the brush has at least one face showing
- vis = 0;
- for (j=0 ; j<numsides ; j++)
- if ((mb->original_sides[j].flags & SFL_VISIBLE) && mb->original_sides[j].winding)
- vis++;
-#if 0
- if (!vis)
- continue; // no faces at all
-#endif
- // if the brush is outside the clip area, skip it
- for (j=0 ; j<3 ; j++)
- if (mb->mins[j] >= clipmaxs[j]
- || mb->maxs[j] <= clipmins[j])
- break;
- if (j != 3)
- continue;
-
- //
- // make a copy of the brush
- //
- newbrush = AllocBrush (mb->numsides);
- newbrush->original = mb;
- newbrush->numsides = mb->numsides;
- memcpy (newbrush->sides, mb->original_sides, numsides*sizeof(side_t));
- for (j=0 ; j<numsides ; j++)
- {
- if (newbrush->sides[j].winding)
- newbrush->sides[j].winding = CopyWinding (newbrush->sides[j].winding);
- if (newbrush->sides[j].surf & SURF_HINT)
- newbrush->sides[j].flags |= SFL_VISIBLE; // hints are always visible
- }
- VectorCopy (mb->mins, newbrush->mins);
- VectorCopy (mb->maxs, newbrush->maxs);
-
- //
- // carve off anything outside the clip box
- //
- newbrush = ClipBrushToBox (newbrush, clipmins, clipmaxs);
- if (!newbrush)
- continue;
-
- c_faces += vis;
- c_brushes++;
-
- newbrush->next = brushlist;
- brushlist = newbrush;
- }
-
- return brushlist;
-} //end of the function MakeBspBrushList
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-bspbrush_t *AddBrushListToTail (bspbrush_t *list, bspbrush_t *tail)
-{
- bspbrush_t *walk, *next;
-
- for (walk=list ; walk ; walk=next)
- { // add to end of list
- next = walk->next;
- walk->next = NULL;
- tail->next = walk;
- tail = walk;
- } //end for
- return tail;
-} //end of the function AddBrushListToTail
-//===========================================================================
-// Builds a new list that doesn't hold the given brush
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-bspbrush_t *CullList(bspbrush_t *list, bspbrush_t *skip1)
-{
- bspbrush_t *newlist;
- bspbrush_t *next;
-
- newlist = NULL;
-
- for ( ; list ; list = next)
- {
- next = list->next;
- if (list == skip1)
- {
- FreeBrush (list);
- continue;
- }
- list->next = newlist;
- newlist = list;
- }
- return newlist;
-} //end of the function CullList
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-/*
-void WriteBrushMap(char *name, bspbrush_t *list)
-{
- FILE *f;
- side_t *s;
- int i;
- winding_t *w;
-
- Log_Print("writing %s\n", name);
- f = fopen (name, "wb");
- if (!f)
- Error ("Can't write %s\b", name);
-
- fprintf (f, "{\n\"classname\" \"worldspawn\"\n");
-
- for ( ; list ; list=list->next )
- {
- fprintf (f, "{\n");
- for (i=0,s=list->sides ; i<list->numsides ; i++,s++)
- {
- w = BaseWindingForPlane (mapplanes[s->planenum].normal, mapplanes[s->planenum].dist);
-
- fprintf (f,"( %i %i %i ) ", (int)w->p[0][0], (int)w->p[0][1], (int)w->p[0][2]);
- fprintf (f,"( %i %i %i ) ", (int)w->p[1][0], (int)w->p[1][1], (int)w->p[1][2]);
- fprintf (f,"( %i %i %i ) ", (int)w->p[2][0], (int)w->p[2][1], (int)w->p[2][2]);
-
- fprintf (f, "%s 0 0 0 1 1\n", texinfo[s->texinfo].texture);
- FreeWinding (w);
- }
- fprintf (f, "}\n");
- }
- fprintf (f, "}\n");
-
- fclose (f);
-} //end of the function WriteBrushMap
-*/
-//===========================================================================
-// Returns true if b1 is allowed to bite b2
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-qboolean BrushGE (bspbrush_t *b1, bspbrush_t *b2)
-{
-#ifdef ME
- if (create_aas)
- {
- if (b1->original->expansionbbox != b2->original->expansionbbox)
- {
- return false;
- } //end if
- //never have something else bite a ladder brush
- //never have a ladder brush bite something else
- if ( (b1->original->contents & CONTENTS_LADDER)
- && !(b2->original->contents & CONTENTS_LADDER))
- {
- return false;
- } //end if
- } //end if
-#endif //ME
- // detail brushes never bite structural brushes
- if ( (b1->original->contents & CONTENTS_DETAIL)
- && !(b2->original->contents & CONTENTS_DETAIL) )
- {
- return false;
- } //end if
- if (b1->original->contents & CONTENTS_SOLID)
- {
- return true;
- } //end if
- return false;
-} //end of the function BrushGE
-//===========================================================================
-// Carves any intersecting solid brushes into the minimum number
-// of non-intersecting brushes.
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-bspbrush_t *ChopBrushes (bspbrush_t *head)
-{
- bspbrush_t *b1, *b2, *next;
- bspbrush_t *tail;
- bspbrush_t *keep;
- bspbrush_t *sub, *sub2;
- int c1, c2;
- int num_csg_iterations;
-
- Log_Print("-------- Brush CSG ---------\n");
- Log_Print("%6d original brushes\n", CountBrushList (head));
-
- num_csg_iterations = 0;
- qprintf("%6d output brushes", num_csg_iterations);
-
-#if 0
- if (startbrush == 0)
- WriteBrushList ("before.gl", head, false);
-#endif
- keep = NULL;
-
-newlist:
- // find tail
- if (!head) return NULL;
-
- for (tail = head; tail->next; tail = tail->next)
- ;
-
- for (b1=head ; b1 ; b1=next)
- {
- next = b1->next;
-
- //if the conversion is cancelled
- if (cancelconversion)
- {
- b1->next = keep;
- keep = b1;
- continue;
- } //end if
-
- for (b2 = b1->next; b2; b2 = b2->next)
- {
- if (BrushesDisjoint (b1, b2))
- continue;
-
- sub = NULL;
- sub2 = NULL;
- c1 = 999999;
- c2 = 999999;
-
- if (BrushGE (b2, b1))
- {
- sub = SubtractBrush (b1, b2);
- if (sub == b1)
- {
- continue; // didn't really intersect
- } //end if
- if (!sub)
- { // b1 is swallowed by b2
- head = CullList (b1, b1);
- goto newlist;
- }
- c1 = CountBrushList (sub);
- }
-
- if ( BrushGE (b1, b2) )
- {
- sub2 = SubtractBrush (b2, b1);
- if (sub2 == b2)
- continue; // didn't really intersect
- if (!sub2)
- { // b2 is swallowed by b1
- FreeBrushList (sub);
- head = CullList (b1, b2);
- goto newlist;
- }
- c2 = CountBrushList (sub2);
- }
-
- if (!sub && !sub2)
- continue; // neither one can bite
-
- // only accept if it didn't fragment
- // (commenting this out allows full fragmentation)
- if (c1 > 1 && c2 > 1)
- {
- if (sub2)
- FreeBrushList (sub2);
- if (sub)
- FreeBrushList (sub);
- continue;
- }
-
- if (c1 < c2)
- {
- if (sub2) FreeBrushList (sub2);
- tail = AddBrushListToTail (sub, tail);
- head = CullList (b1, b1);
- goto newlist;
- } //end if
- else
- {
- if (sub) FreeBrushList (sub);
- tail = AddBrushListToTail (sub2, tail);
- head = CullList (b1, b2);
- goto newlist;
- } //end else
- } //end for
-
- if (!b2)
- { // b1 is no longer intersecting anything, so keep it
- b1->next = keep;
- keep = b1;
- } //end if
- num_csg_iterations++;
- qprintf("\r%6d", num_csg_iterations);
- } //end for
-
- if (cancelconversion) return keep;
- //
- qprintf("\n");
- Log_Write("%6d output brushes\r\n", num_csg_iterations);
-
-#if 0
- {
- WriteBrushList ("after.gl", keep, false);
- WriteBrushMap ("after.map", keep);
- }
-#endif
-
- return keep;
-} //end of the function ChopBrushes
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-bspbrush_t *InitialBrushList (bspbrush_t *list)
-{
- bspbrush_t *b;
- bspbrush_t *out, *newb;
- int i;
-
- // only return brushes that have visible faces
- out = NULL;
- for (b=list ; b ; b=b->next)
- {
-#if 0
- for (i=0 ; i<b->numsides ; i++)
- if (b->sides[i].flags & SFL_VISIBLE)
- break;
- if (i == b->numsides)
- continue;
-#endif
- newb = CopyBrush (b);
- newb->next = out;
- out = newb;
-
- // clear visible, so it must be set by MarkVisibleFaces_r
- // to be used in the optimized list
- for (i=0 ; i<b->numsides ; i++)
- {
- newb->sides[i].original = &b->sides[i];
-// newb->sides[i].visible = true;
- b->sides[i].flags &= ~SFL_VISIBLE;
- }
- }
-
- return out;
-} //end of the function InitialBrushList
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-bspbrush_t *OptimizedBrushList (bspbrush_t *list)
-{
- bspbrush_t *b;
- bspbrush_t *out, *newb;
- int i;
-
- // only return brushes that have visible faces
- out = NULL;
- for (b=list ; b ; b=b->next)
- {
- for (i=0 ; i<b->numsides ; i++)
- if (b->sides[i].flags & SFL_VISIBLE)
- break;
- if (i == b->numsides)
- continue;
- newb = CopyBrush (b);
- newb->next = out;
- out = newb;
- } //end for
-
-// WriteBrushList ("vis.gl", out, true);
- return out;
-} //end of the function OptimizeBrushList
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-tree_t *ProcessWorldBrushes(int brush_start, int brush_end)
-{
- bspbrush_t *brushes;
- tree_t *tree;
- node_t *node;
- vec3_t mins, maxs;
-
- //take the whole world
- mins[0] = map_mins[0] - 8;
- mins[1] = map_mins[1] - 8;
- mins[2] = map_mins[2] - 8;
-
- maxs[0] = map_maxs[0] + 8;
- maxs[1] = map_maxs[1] + 8;
- maxs[2] = map_maxs[2] + 8;
-
- //reset the brush bsp
- ResetBrushBSP();
-
- // the makelist and chopbrushes could be cached between the passes...
-
- //create a list with brushes that are within the given mins/maxs
- //some brushes will be cut and only the part that falls within the
- //mins/maxs will be in the bush list
- brushes = MakeBspBrushList(brush_start, brush_end, mins, maxs);
- //
-
- if (!brushes)
- {
- node = AllocNode ();
- node->planenum = PLANENUM_LEAF;
- node->contents = CONTENTS_SOLID;
-
- tree = Tree_Alloc();
- tree->headnode = node;
- VectorCopy(mins, tree->mins);
- VectorCopy(maxs, tree->maxs);
- } //end if
- else
- {
- //Carves any intersecting solid brushes into the minimum number
- //of non-intersecting brushes.
- if (!nocsg)
- {
- brushes = ChopBrushes(brushes);
- /*
- if (create_aas)
- {
- brushes = MergeBrushes(brushes);
- } //end if*/
- } //end if
- //if the conversion is cancelled
- if (cancelconversion)
- {
- FreeBrushList(brushes);
- return NULL;
- } //end if
- //create the actual bsp tree
- tree = BrushBSP(brushes, mins, maxs);
- } //end else
- //return the tree
- return tree;
-} //end of the function ProcessWorldBrushes
diff --git a/code/bspc/faces.c b/code/bspc/faces.c
deleted file mode 100644
index 025703f..0000000
--- a/code/bspc/faces.c
+++ /dev/null
@@ -1,978 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-// faces.c
-
-#include "qbsp.h"
-#include "l_mem.h"
-
-/*
-
- some faces will be removed before saving, but still form nodes:
-
- the insides of sky volumes
- meeting planes of different water current volumes
-
-*/
-
-// undefine for dumb linear searches
-#define USE_HASHING
-
-#define INTEGRAL_EPSILON 0.01
-#define POINT_EPSILON 0.5
-#define OFF_EPSILON 0.5
-
-int c_merge;
-int c_subdivide;
-
-int c_totalverts;
-int c_uniqueverts;
-int c_degenerate;
-int c_tjunctions;
-int c_faceoverflows;
-int c_facecollapse;
-int c_badstartverts;
-
-#define MAX_SUPERVERTS 512
-int superverts[MAX_SUPERVERTS];
-int numsuperverts;
-
-face_t *edgefaces[MAX_MAP_EDGES][2];
-int firstmodeledge = 1;
-int firstmodelface;
-
-int c_tryedges;
-
-vec3_t edge_dir;
-vec3_t edge_start;
-vec_t edge_len;
-
-int num_edge_verts;
-int edge_verts[MAX_MAP_VERTS];
-
-face_t *NewFaceFromFace (face_t *f);
-
-//===========================================================================
-
-typedef struct hashvert_s
-{
- struct hashvert_s *next;
- int num;
-} hashvert_t;
-
-
-#define HASH_SIZE 64
-
-
-int vertexchain[MAX_MAP_VERTS]; // the next vertex in a hash chain
-int hashverts[HASH_SIZE*HASH_SIZE]; // a vertex number, or 0 for no verts
-
-face_t *edgefaces[MAX_MAP_EDGES][2];
-
-//============================================================================
-
-
-unsigned HashVec (vec3_t vec)
-{
- int x, y;
-
- x = (4096 + (int)(vec[0]+0.5)) >> 7;
- y = (4096 + (int)(vec[1]+0.5)) >> 7;
-
- if ( x < 0 || x >= HASH_SIZE || y < 0 || y >= HASH_SIZE )
- Error ("HashVec: point outside valid range");
-
- return y*HASH_SIZE + x;
-}
-
-#ifdef USE_HASHING
-/*
-=============
-GetVertex
-
-Uses hashing
-=============
-*/
-int GetVertexnum (vec3_t in)
-{
- int h;
- int i;
- float *p;
- vec3_t vert;
- int vnum;
-
- c_totalverts++;
-
- for (i=0 ; i<3 ; i++)
- {
- if ( fabs(in[i] - Q_rint(in[i])) < INTEGRAL_EPSILON)
- vert[i] = Q_rint(in[i]);
- else
- vert[i] = in[i];
- }
-
- h = HashVec (vert);
-
- for (vnum=hashverts[h] ; vnum ; vnum=vertexchain[vnum])
- {
- p = dvertexes[vnum].point;
- if ( fabs(p[0]-vert[0])<POINT_EPSILON
- && fabs(p[1]-vert[1])<POINT_EPSILON
- && fabs(p[2]-vert[2])<POINT_EPSILON )
- return vnum;
- }
-
-// emit a vertex
- if (numvertexes == MAX_MAP_VERTS)
- Error ("numvertexes == MAX_MAP_VERTS");
-
- dvertexes[numvertexes].point[0] = vert[0];
- dvertexes[numvertexes].point[1] = vert[1];
- dvertexes[numvertexes].point[2] = vert[2];
-
- vertexchain[numvertexes] = hashverts[h];
- hashverts[h] = numvertexes;
-
- c_uniqueverts++;
-
- numvertexes++;
-
- return numvertexes-1;
-}
-#else
-/*
-==================
-GetVertexnum
-
-Dumb linear search
-==================
-*/
-int GetVertexnum (vec3_t v)
-{
- int i, j;
- dvertex_t *dv;
- vec_t d;
-
- c_totalverts++;
-
- // make really close values exactly integral
- for (i=0 ; i<3 ; i++)
- {
- if ( fabs(v[i] - (int)(v[i]+0.5)) < INTEGRAL_EPSILON )
- v[i] = (int)(v[i]+0.5);
- if (v[i] < -4096 || v[i] > 4096)
- Error ("GetVertexnum: outside +/- 4096");
- }
-
- // search for an existing vertex match
- for (i=0, dv=dvertexes ; i<numvertexes ; i++, dv++)
- {
- for (j=0 ; j<3 ; j++)
- {
- d = v[j] - dv->point[j];
- if ( d > POINT_EPSILON || d < -POINT_EPSILON)
- break;
- }
- if (j == 3)
- return i; // a match
- }
-
- // new point
- if (numvertexes == MAX_MAP_VERTS)
- Error ("MAX_MAP_VERTS");
- VectorCopy (v, dv->point);
- numvertexes++;
- c_uniqueverts++;
-
- return numvertexes-1;
-}
-#endif
-
-
-/*
-==================
-FaceFromSuperverts
-
-The faces vertexes have been added to the superverts[] array,
-and there may be more there than can be held in a face (MAXEDGES).
-
-If less, the faces vertexnums[] will be filled in, otherwise
-face will reference a tree of split[] faces until all of the
-vertexnums can be added.
-
-superverts[base] will become face->vertexnums[0], and the others
-will be circularly filled in.
-==================
-*/
-void FaceFromSuperverts (node_t *node, face_t *f, int base)
-{
- face_t *newf;
- int remaining;
- int i;
-
- remaining = numsuperverts;
- while (remaining > MAXEDGES)
- { // must split into two faces, because of vertex overload
- c_faceoverflows++;
-
- newf = f->split[0] = NewFaceFromFace (f);
- newf = f->split[0];
- newf->next = node->faces;
- node->faces = newf;
-
- newf->numpoints = MAXEDGES;
- for (i=0 ; i<MAXEDGES ; i++)
- newf->vertexnums[i] = superverts[(i+base)%numsuperverts];
-
- f->split[1] = NewFaceFromFace (f);
- f = f->split[1];
- f->next = node->faces;
- node->faces = f;
-
- remaining -= (MAXEDGES-2);
- base = (base+MAXEDGES-1)%numsuperverts;
- }
-
- // copy the vertexes back to the face
- f->numpoints = remaining;
- for (i=0 ; i<remaining ; i++)
- f->vertexnums[i] = superverts[(i+base)%numsuperverts];
-}
-
-
-/*
-==================
-EmitFaceVertexes
-==================
-*/
-void EmitFaceVertexes (node_t *node, face_t *f)
-{
- winding_t *w;
- int i;
-
- if (f->merged || f->split[0] || f->split[1])
- return;
-
- w = f->w;
- for (i=0 ; i<w->numpoints ; i++)
- {
- if (noweld)
- { // make every point unique
- if (numvertexes == MAX_MAP_VERTS)
- Error ("MAX_MAP_VERTS");
- superverts[i] = numvertexes;
- VectorCopy (w->p[i], dvertexes[numvertexes].point);
- numvertexes++;
- c_uniqueverts++;
- c_totalverts++;
- }
- else
- superverts[i] = GetVertexnum (w->p[i]);
- }
- numsuperverts = w->numpoints;
-
- // this may fragment the face if > MAXEDGES
- FaceFromSuperverts (node, f, 0);
-}
-
-/*
-==================
-EmitVertexes_r
-==================
-*/
-void EmitVertexes_r (node_t *node)
-{
- int i;
- face_t *f;
-
- if (node->planenum == PLANENUM_LEAF)
- return;
-
- for (f=node->faces ; f ; f=f->next)
- {
- EmitFaceVertexes (node, f);
- }
-
- for (i=0 ; i<2 ; i++)
- EmitVertexes_r (node->children[i]);
-}
-
-
-#ifdef USE_HASHING
-/*
-==========
-FindEdgeVerts
-
-Uses the hash tables to cut down to a small number
-==========
-*/
-void FindEdgeVerts (vec3_t v1, vec3_t v2)
-{
- int x1, x2, y1, y2, t;
- int x, y;
- int vnum;
-
-#if 0
-{
- int i;
- num_edge_verts = numvertexes-1;
- for (i=0 ; i<numvertexes-1 ; i++)
- edge_verts[i] = i+1;
-}
-#endif
-
- x1 = (4096 + (int)(v1[0]+0.5)) >> 7;
- y1 = (4096 + (int)(v1[1]+0.5)) >> 7;
- x2 = (4096 + (int)(v2[0]+0.5)) >> 7;
- y2 = (4096 + (int)(v2[1]+0.5)) >> 7;
-
- if (x1 > x2)
- {
- t = x1;
- x1 = x2;
- x2 = t;
- }
- if (y1 > y2)
- {
- t = y1;
- y1 = y2;
- y2 = t;
- }
-#if 0
- x1--;
- x2++;
- y1--;
- y2++;
- if (x1 < 0)
- x1 = 0;
- if (x2 >= HASH_SIZE)
- x2 = HASH_SIZE;
- if (y1 < 0)
- y1 = 0;
- if (y2 >= HASH_SIZE)
- y2 = HASH_SIZE;
-#endif
- num_edge_verts = 0;
- for (x=x1 ; x <= x2 ; x++)
- {
- for (y=y1 ; y <= y2 ; y++)
- {
- for (vnum=hashverts[y*HASH_SIZE+x] ; vnum ; vnum=vertexchain[vnum])
- {
- edge_verts[num_edge_verts++] = vnum;
- }
- }
- }
-}
-
-#else
-/*
-==========
-FindEdgeVerts
-
-Forced a dumb check of everything
-==========
-*/
-void FindEdgeVerts (vec3_t v1, vec3_t v2)
-{
- int i;
-
- num_edge_verts = numvertexes-1;
- for (i=0 ; i<num_edge_verts ; i++)
- edge_verts[i] = i+1;
-}
-#endif
-
-/*
-==========
-TestEdge
-
-Can be recursively reentered
-==========
-*/
-void TestEdge (vec_t start, vec_t end, int p1, int p2, int startvert)
-{
- int j, k;
- vec_t dist;
- vec3_t delta;
- vec3_t exact;
- vec3_t off;
- vec_t error;
- vec3_t p;
-
- if (p1 == p2)
- {
- c_degenerate++;
- return; // degenerate edge
- }
-
- for (k=startvert ; k<num_edge_verts ; k++)
- {
- j = edge_verts[k];
- if (j==p1 || j == p2)
- continue;
-
- VectorCopy (dvertexes[j].point, p);
-
- VectorSubtract (p, edge_start, delta);
- dist = DotProduct (delta, edge_dir);
- if (dist <=start || dist >= end)
- continue; // off an end
- VectorMA (edge_start, dist, edge_dir, exact);
- VectorSubtract (p, exact, off);
- error = VectorLength (off);
-
- if (fabs(error) > OFF_EPSILON)
- continue; // not on the edge
-
- // break the edge
- c_tjunctions++;
- TestEdge (start, dist, p1, j, k+1);
- TestEdge (dist, end, j, p2, k+1);
- return;
- }
-
- // the edge p1 to p2 is now free of tjunctions
- if (numsuperverts >= MAX_SUPERVERTS)
- Error ("MAX_SUPERVERTS");
- superverts[numsuperverts] = p1;
- numsuperverts++;
-}
-
-/*
-==================
-FixFaceEdges
-
-==================
-*/
-void FixFaceEdges (node_t *node, face_t *f)
-{
- int p1, p2;
- int i;
- vec3_t e2;
- vec_t len;
- int count[MAX_SUPERVERTS], start[MAX_SUPERVERTS];
- int base;
-
- if (f->merged || f->split[0] || f->split[1])
- return;
-
- numsuperverts = 0;
-
- for (i=0 ; i<f->numpoints ; i++)
- {
- p1 = f->vertexnums[i];
- p2 = f->vertexnums[(i+1)%f->numpoints];
-
- VectorCopy (dvertexes[p1].point, edge_start);
- VectorCopy (dvertexes[p2].point, e2);
-
- FindEdgeVerts (edge_start, e2);
-
- VectorSubtract (e2, edge_start, edge_dir);
- len = VectorNormalize(edge_dir);
-
- start[i] = numsuperverts;
- TestEdge (0, len, p1, p2, 0);
-
- count[i] = numsuperverts - start[i];
- }
-
- if (numsuperverts < 3)
- { // entire face collapsed
- f->numpoints = 0;
- c_facecollapse++;
- return;
- }
-
- // we want to pick a vertex that doesn't have tjunctions
- // on either side, which can cause artifacts on trifans,
- // especially underwater
- for (i=0 ; i<f->numpoints ; i++)
- {
- if (count[i] == 1 && count[(i+f->numpoints-1)%f->numpoints] == 1)
- break;
- }
- if (i == f->numpoints)
- {
- f->badstartvert = true;
- c_badstartverts++;
- base = 0;
- }
- else
- { // rotate the vertex order
- base = start[i];
- }
-
- // this may fragment the face if > MAXEDGES
- FaceFromSuperverts (node, f, base);
-}
-
-/*
-==================
-FixEdges_r
-==================
-*/
-void FixEdges_r (node_t *node)
-{
- int i;
- face_t *f;
-
- if (node->planenum == PLANENUM_LEAF)
- return;
-
- for (f=node->faces ; f ; f=f->next)
- FixFaceEdges (node, f);
-
- for (i=0 ; i<2 ; i++)
- FixEdges_r (node->children[i]);
-}
-
-/*
-===========
-FixTjuncs
-
-===========
-*/
-void FixTjuncs (node_t *headnode)
-{
- // snap and merge all vertexes
- qprintf ("---- snap verts ----\n");
- memset (hashverts, 0, sizeof(hashverts));
- c_totalverts = 0;
- c_uniqueverts = 0;
- c_faceoverflows = 0;
- EmitVertexes_r (headnode);
- qprintf ("%i unique from %i\n", c_uniqueverts, c_totalverts);
-
- // break edges on tjunctions
- qprintf ("---- tjunc ----\n");
- c_tryedges = 0;
- c_degenerate = 0;
- c_facecollapse = 0;
- c_tjunctions = 0;
- if (!notjunc)
- FixEdges_r (headnode);
- qprintf ("%5i edges degenerated\n", c_degenerate);
- qprintf ("%5i faces degenerated\n", c_facecollapse);
- qprintf ("%5i edges added by tjunctions\n", c_tjunctions);
- qprintf ("%5i faces added by tjunctions\n", c_faceoverflows);
- qprintf ("%5i bad start verts\n", c_badstartverts);
-}
-
-
-//========================================================
-
-int c_faces;
-
-face_t *AllocFace (void)
-{
- face_t *f;
-
- f = GetMemory(sizeof(*f));
- memset (f, 0, sizeof(*f));
- c_faces++;
-
- return f;
-}
-
-face_t *NewFaceFromFace (face_t *f)
-{
- face_t *newf;
-
- newf = AllocFace ();
- *newf = *f;
- newf->merged = NULL;
- newf->split[0] = newf->split[1] = NULL;
- newf->w = NULL;
- return newf;
-}
-
-void FreeFace (face_t *f)
-{
- if (f->w)
- FreeWinding (f->w);
- FreeMemory(f);
- c_faces--;
-}
-
-//========================================================
-
-/*
-==================
-GetEdge
-
-Called by writebsp.
-Don't allow four way edges
-==================
-*/
-int GetEdge2 (int v1, int v2, face_t *f)
-{
- dedge_t *edge;
- int i;
-
- c_tryedges++;
-
- if (!noshare)
- {
- for (i=firstmodeledge ; i < numedges ; i++)
- {
- edge = &dedges[i];
- if (v1 == edge->v[1] && v2 == edge->v[0]
- && edgefaces[i][0]->contents == f->contents)
- {
- if (edgefaces[i][1])
- // printf ("WARNING: multiple backward edge\n");
- continue;
- edgefaces[i][1] = f;
- return -i;
- }
- #if 0
- if (v1 == edge->v[0] && v2 == edge->v[1])
- {
- printf ("WARNING: multiple forward edge\n");
- return i;
- }
- #endif
- }
- }
-
-// emit an edge
- if (numedges >= MAX_MAP_EDGES)
- Error ("numedges == MAX_MAP_EDGES");
- edge = &dedges[numedges];
- numedges++;
- edge->v[0] = v1;
- edge->v[1] = v2;
- edgefaces[numedges-1][0] = f;
-
- return numedges-1;
-}
-
-/*
-===========================================================================
-
-FACE MERGING
-
-===========================================================================
-*/
-
-/*
-=============
-TryMerge
-
-If two polygons share a common edge and the edges that meet at the
-common points are both inside the other polygons, merge them
-
-Returns NULL if the faces couldn't be merged, or the new face.
-The originals will NOT be freed.
-=============
-*/
-face_t *TryMerge (face_t *f1, face_t *f2, vec3_t planenormal)
-{
- face_t *newf;
- winding_t *nw;
-
- if (!f1->w || !f2->w)
- return NULL;
- if (f1->texinfo != f2->texinfo)
- return NULL;
- if (f1->planenum != f2->planenum) // on front and back sides
- return NULL;
- if (f1->contents != f2->contents)
- return NULL;
-
-
- nw = TryMergeWinding (f1->w, f2->w, planenormal);
- if (!nw)
- return NULL;
-
- c_merge++;
- newf = NewFaceFromFace (f1);
- newf->w = nw;
-
- f1->merged = newf;
- f2->merged = newf;
-
- return newf;
-}
-
-/*
-===============
-MergeNodeFaces
-===============
-*/
-void MergeNodeFaces (node_t *node)
-{
- face_t *f1, *f2, *end;
- face_t *merged;
- plane_t *plane;
-
- plane = &mapplanes[node->planenum];
- merged = NULL;
-
- for (f1 = node->faces ; f1 ; f1 = f1->next)
- {
- if (f1->merged || f1->split[0] || f1->split[1])
- continue;
-
- for (f2 = node->faces ; f2 != f1 ; f2=f2->next)
- {
- if (f2->merged || f2->split[0] || f2->split[1])
- continue;
-
- //IDBUG: always passes the face's node's normal to TryMerge()
- //regardless of which side the face is on. Approximately 50% of
- //the time the face will be on the other side of node, and thus
- //the result of the convex/concave test in TryMergeWinding(),
- //which depends on the normal, is flipped. This causes faces
- //that shouldn't be merged to be merged and faces that
- //should be merged to not be merged.
- //the following added line fixes this bug
- //thanks to: Alexander Malmberg <alexander@malmberg.org>
- plane = &mapplanes[f1->planenum];
- //
- merged = TryMerge (f1, f2, plane->normal);
- if (!merged)
- continue;
-
- // add merged to the end of the node face list
- // so it will be checked against all the faces again
- for (end = node->faces ; end->next ; end = end->next)
- ;
- merged->next = NULL;
- end->next = merged;
- break;
- }
- }
-}
-
-//=====================================================================
-
-/*
-===============
-SubdivideFace
-
-Chop up faces that are larger than we want in the surface cache
-===============
-*/
-void SubdivideFace (node_t *node, face_t *f)
-{
- float mins, maxs;
- vec_t v;
- int axis, i;
- texinfo_t *tex;
- vec3_t temp;
- vec_t dist;
- winding_t *w, *frontw, *backw;
-
- if (f->merged)
- return;
-
-// special (non-surface cached) faces don't need subdivision
- tex = &texinfo[f->texinfo];
-
- if ( tex->flags & (SURF_WARP|SURF_SKY) )
- {
- return;
- }
-
- for (axis = 0 ; axis < 2 ; axis++)
- {
- while (1)
- {
- mins = 999999;
- maxs = -999999;
-
- VectorCopy (tex->vecs[axis], temp);
- w = f->w;
- for (i=0 ; i<w->numpoints ; i++)
- {
- v = DotProduct (w->p[i], temp);
- if (v < mins)
- mins = v;
- if (v > maxs)
- maxs = v;
- }
-#if 0
- if (maxs - mins <= 0)
- Error ("zero extents");
-#endif
- if (axis == 2)
- { // allow double high walls
- if (maxs - mins <= subdivide_size/* *2 */)
- break;
- }
- else if (maxs - mins <= subdivide_size)
- break;
-
- // split it
- c_subdivide++;
-
- v = VectorNormalize (temp);
-
- dist = (mins + subdivide_size - 16)/v;
-
- ClipWindingEpsilon (w, temp, dist, ON_EPSILON, &frontw, &backw);
- if (!frontw || !backw)
- Error ("SubdivideFace: didn't split the polygon");
-
- f->split[0] = NewFaceFromFace (f);
- f->split[0]->w = frontw;
- f->split[0]->next = node->faces;
- node->faces = f->split[0];
-
- f->split[1] = NewFaceFromFace (f);
- f->split[1]->w = backw;
- f->split[1]->next = node->faces;
- node->faces = f->split[1];
-
- SubdivideFace (node, f->split[0]);
- SubdivideFace (node, f->split[1]);
- return;
- }
- }
-}
-
-void SubdivideNodeFaces (node_t *node)
-{
- face_t *f;
-
- for (f = node->faces ; f ; f=f->next)
- {
- SubdivideFace (node, f);
- }
-}
-
-//===========================================================================
-
-int c_nodefaces;
-
-
-/*
-============
-FaceFromPortal
-
-============
-*/
-face_t *FaceFromPortal (portal_t *p, int pside)
-{
- face_t *f;
- side_t *side;
-
- side = p->side;
- if (!side)
- return NULL; // portal does not bridge different visible contents
-
- f = AllocFace ();
-
- f->texinfo = side->texinfo;
- f->planenum = (side->planenum & ~1) | pside;
- f->portal = p;
-
- if ( (p->nodes[pside]->contents & CONTENTS_WINDOW)
- && VisibleContents(p->nodes[!pside]->contents^p->nodes[pside]->contents) == CONTENTS_WINDOW )
- return NULL; // don't show insides of windows
-
- if (pside)
- {
- f->w = ReverseWinding(p->winding);
- f->contents = p->nodes[1]->contents;
- }
- else
- {
- f->w = CopyWinding(p->winding);
- f->contents = p->nodes[0]->contents;
- }
- return f;
-}
-
-
-/*
-===============
-MakeFaces_r
-
-If a portal will make a visible face,
-mark the side that originally created it
-
- solid / empty : solid
- solid / water : solid
- water / empty : water
- water / water : none
-===============
-*/
-void MakeFaces_r (node_t *node)
-{
- portal_t *p;
- int s;
-
- // recurse down to leafs
- if (node->planenum != PLANENUM_LEAF)
- {
- MakeFaces_r (node->children[0]);
- MakeFaces_r (node->children[1]);
-
- // merge together all visible faces on the node
- if (!nomerge)
- MergeNodeFaces (node);
- if (!nosubdiv)
- SubdivideNodeFaces (node);
-
- return;
- }
-
- // solid leafs never have visible faces
- if (node->contents & CONTENTS_SOLID)
- return;
-
- // see which portals are valid
- for (p=node->portals ; p ; p = p->next[s])
- {
- s = (p->nodes[1] == node);
-
- p->face[s] = FaceFromPortal (p, s);
- if (p->face[s])
- {
- c_nodefaces++;
- p->face[s]->next = p->onnode->faces;
- p->onnode->faces = p->face[s];
- }
- }
-}
-
-/*
-============
-MakeFaces
-============
-*/
-void MakeFaces (node_t *node)
-{
- qprintf ("--- MakeFaces ---\n");
- c_merge = 0;
- c_subdivide = 0;
- c_nodefaces = 0;
-
- MakeFaces_r (node);
-
- qprintf ("%5i makefaces\n", c_nodefaces);
- qprintf ("%5i merged\n", c_merge);
- qprintf ("%5i subdivided\n", c_subdivide);
-}
diff --git a/code/bspc/gldraw.c b/code/bspc/gldraw.c
deleted file mode 100644
index f865a81..0000000
--- a/code/bspc/gldraw.c
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-#include <windows.h>
-#include <GL/gl.h>
-#include <GL/glu.h>
-#include <GL/glaux.h>
-
-#include "qbsp.h"
-
-// can't use the glvertex3fv functions, because the vec3_t fields
-// could be either floats or doubles, depending on DOUBLEVEC_T
-
-qboolean drawflag;
-vec3_t draw_mins, draw_maxs;
-
-
-#define WIN_SIZE 512
-
-void InitWindow (void)
-{
- auxInitDisplayMode (AUX_SINGLE | AUX_RGB);
- auxInitPosition (0, 0, WIN_SIZE, WIN_SIZE);
- auxInitWindow ("qcsg");
-}
-
-void Draw_ClearWindow (void)
-{
- static int init;
- int w, h, g;
- vec_t mx, my;
-
- if (!drawflag)
- return;
-
- if (!init)
- {
- init = true;
- InitWindow ();
- }
-
- glClearColor (1,0.8,0.8,0);
- glClear (GL_COLOR_BUFFER_BIT);
-
- w = (draw_maxs[0] - draw_mins[0]);
- h = (draw_maxs[1] - draw_mins[1]);
-
- mx = draw_mins[0] + w/2;
- my = draw_mins[1] + h/2;
-
- g = w > h ? w : h;
-
- glLoadIdentity ();
- gluPerspective (90, 1, 2, 16384);
- gluLookAt (mx, my, draw_maxs[2] + g/2, mx , my, draw_maxs[2], 0, 1, 0);
-
- glColor3f (0,0,0);
-// glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
- glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
- glDisable (GL_DEPTH_TEST);
- glEnable (GL_BLEND);
- glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
-#if 0
- glColor4f (1,0,0,0.5);
- glBegin (GL_POLYGON);
-
- glVertex3f (0, 500, 0);
- glVertex3f (0, 900, 0);
- glVertex3f (0, 900, 100);
- glVertex3f (0, 500, 100);
-
- glEnd ();
-#endif
-
- glFlush ();
-
-}
-
-void Draw_SetRed (void)
-{
- if (!drawflag)
- return;
-
- glColor3f (1,0,0);
-}
-
-void Draw_SetGrey (void)
-{
- if (!drawflag)
- return;
-
- glColor3f (0.5,0.5,0.5);
-}
-
-void Draw_SetBlack (void)
-{
- if (!drawflag)
- return;
-
- glColor3f (0,0,0);
-}
-
-void DrawWinding (winding_t *w)
-{
- int i;
-
- if (!drawflag)
- return;
-
- glColor4f (0,0,0,0.5);
- glBegin (GL_LINE_LOOP);
- for (i=0 ; i<w->numpoints ; i++)
- glVertex3f (w->p[i][0],w->p[i][1],w->p[i][2] );
- glEnd ();
-
- glColor4f (0,1,0,0.3);
- glBegin (GL_POLYGON);
- for (i=0 ; i<w->numpoints ; i++)
- glVertex3f (w->p[i][0],w->p[i][1],w->p[i][2] );
- glEnd ();
-
- glFlush ();
-}
-
-void DrawAuxWinding (winding_t *w)
-{
- int i;
-
- if (!drawflag)
- return;
-
- glColor4f (0,0,0,0.5);
- glBegin (GL_LINE_LOOP);
- for (i=0 ; i<w->numpoints ; i++)
- glVertex3f (w->p[i][0],w->p[i][1],w->p[i][2] );
- glEnd ();
-
- glColor4f (1,0,0,0.3);
- glBegin (GL_POLYGON);
- for (i=0 ; i<w->numpoints ; i++)
- glVertex3f (w->p[i][0],w->p[i][1],w->p[i][2] );
- glEnd ();
-
- glFlush ();
-}
-
-//============================================================
-
-#define GLSERV_PORT 25001
-
-qboolean wins_init;
-int draw_socket;
-
-void GLS_BeginScene (void)
-{
- WSADATA winsockdata;
- WORD wVersionRequested;
- struct sockaddr_in address;
- int r;
-
- if (!wins_init)
- {
- wins_init = true;
-
- wVersionRequested = MAKEWORD(1, 1);
-
- r = WSAStartup (MAKEWORD(1, 1), &winsockdata);
-
- if (r)
- Error ("Winsock initialization failed.");
-
- }
-
- // connect a socket to the server
-
- draw_socket = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (draw_socket == -1)
- Error ("draw_socket failed");
-
- address.sin_family = AF_INET;
- address.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- address.sin_port = GLSERV_PORT;
- r = connect (draw_socket, (struct sockaddr *)&address, sizeof(address));
- if (r == -1)
- {
- closesocket (draw_socket);
- draw_socket = 0;
- }
-}
-
-void GLS_Winding (winding_t *w, int code)
-{
- byte buf[1024];
- int i, j;
-
- if (!draw_socket)
- return;
-
- ((int *)buf)[0] = w->numpoints;
- ((int *)buf)[1] = code;
- for (i=0 ; i<w->numpoints ; i++)
- for (j=0 ; j<3 ; j++)
- ((float *)buf)[2+i*3+j] = w->p[i][j];
-
- send (draw_socket, buf, w->numpoints*12+8, 0);
-}
-
-void GLS_EndScene (void)
-{
- closesocket (draw_socket);
- draw_socket = 0;
-}
diff --git a/code/bspc/glfile.c b/code/bspc/glfile.c
deleted file mode 100644
index 86a0e61..0000000
--- a/code/bspc/glfile.c
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-#include "qbsp.h"
-
-int c_glfaces;
-
-int PortalVisibleSides (portal_t *p)
-{
- int fcon, bcon;
-
- if (!p->onnode)
- return 0; // outside
-
- fcon = p->nodes[0]->contents;
- bcon = p->nodes[1]->contents;
-
- // same contents never create a face
- if (fcon == bcon)
- return 0;
-
- // FIXME: is this correct now?
- if (!fcon)
- return 1;
- if (!bcon)
- return 2;
- return 0;
-}
-
-void OutputWinding (winding_t *w, FILE *glview)
-{
- static int level = 128;
- vec_t light;
- int i;
-
- fprintf (glview, "%i\n", w->numpoints);
- level+=28;
- light = (level&255)/255.0;
- for (i=0 ; i<w->numpoints ; i++)
- {
- fprintf (glview, "%6.3f %6.3f %6.3f %6.3f %6.3f %6.3f\n",
- w->p[i][0],
- w->p[i][1],
- w->p[i][2],
- light,
- light,
- light);
- }
- fprintf (glview, "\n");
-}
-
-/*
-=============
-OutputPortal
-=============
-*/
-void OutputPortal (portal_t *p, FILE *glview)
-{
- winding_t *w;
- int sides;
-
- sides = PortalVisibleSides (p);
- if (!sides)
- return;
-
- c_glfaces++;
-
- w = p->winding;
-
- if (sides == 2) // back side
- w = ReverseWinding (w);
-
- OutputWinding (w, glview);
-
- if (sides == 2)
- FreeWinding(w);
-}
-
-/*
-=============
-WriteGLView_r
-=============
-*/
-void WriteGLView_r (node_t *node, FILE *glview)
-{
- portal_t *p, *nextp;
-
- if (node->planenum != PLANENUM_LEAF)
- {
- WriteGLView_r (node->children[0], glview);
- WriteGLView_r (node->children[1], glview);
- return;
- }
-
- // write all the portals
- for (p=node->portals ; p ; p=nextp)
- {
- if (p->nodes[0] == node)
- {
- OutputPortal (p, glview);
- nextp = p->next[0];
- }
- else
- nextp = p->next[1];
- }
-}
-
-/*
-=============
-WriteGLView
-=============
-*/
-void WriteGLView (tree_t *tree, char *source)
-{
- char name[1024];
- FILE *glview;
-
- c_glfaces = 0;
- sprintf (name, "%s%s.gl",outbase, source);
- printf ("Writing %s\n", name);
-
- glview = fopen (name, "w");
- if (!glview)
- Error ("Couldn't open %s", name);
- WriteGLView_r (tree->headnode, glview);
- fclose (glview);
-
- printf ("%5i c_glfaces\n", c_glfaces);
-}
-
diff --git a/code/bspc/l_bsp_ent.c b/code/bspc/l_bsp_ent.c
deleted file mode 100644
index 6e0596b..0000000
--- a/code/bspc/l_bsp_ent.c
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-#include "l_cmd.h"
-#include "l_math.h"
-#include "l_mem.h"
-#include "l_log.h"
-#include "../botlib/l_script.h"
-#include "l_bsp_ent.h"
-
-#define MAX_KEY 32
-#define MAX_VALUE 1024
-
-int num_entities;
-entity_t entities[MAX_MAP_ENTITIES];
-
-void StripTrailing(char *e)
-{
- char *s;
-
- s = e + strlen(e)-1;
- while (s >= e && *s <= 32)
- {
- *s = 0;
- s--;
- }
-}
-
-/*
-=================
-ParseEpair
-=================
-*/
-epair_t *ParseEpair(script_t *script)
-{
- epair_t *e;
- token_t token;
-
- e = GetMemory(sizeof(epair_t));
- memset (e, 0, sizeof(epair_t));
-
- PS_ExpectAnyToken(script, &token);
- StripDoubleQuotes(token.string);
- if (strlen(token.string) >= MAX_KEY-1)
- Error ("ParseEpair: token %s too long", token.string);
- e->key = copystring(token.string);
- PS_ExpectAnyToken(script, &token);
- StripDoubleQuotes(token.string);
- if (strlen(token.string) >= MAX_VALUE-1)
- Error ("ParseEpair: token %s too long", token.string);
- e->value = copystring(token.string);
-
- // strip trailing spaces
- StripTrailing(e->key);
- StripTrailing(e->value);
-
- return e;
-} //end of the function ParseEpair
-
-
-/*
-================
-ParseEntity
-================
-*/
-qboolean ParseEntity(script_t *script)
-{
- epair_t *e;
- entity_t *mapent;
- token_t token;
-
- if (!PS_ReadToken(script, &token))
- return false;
-
- if (strcmp(token.string, "{"))
- Error ("ParseEntity: { not found");
-
- if (num_entities == MAX_MAP_ENTITIES)
- Error ("num_entities == MAX_MAP_ENTITIES");
-
- mapent = &entities[num_entities];
- num_entities++;
-
- do
- {
- if (!PS_ReadToken(script, &token))
- Error ("ParseEntity: EOF without closing brace");
- if (!strcmp(token.string, "}") )
- break;
- PS_UnreadLastToken(script);
- e = ParseEpair(script);
- e->next = mapent->epairs;
- mapent->epairs = e;
- } while (1);
-
- return true;
-} //end of the function ParseEntity
-
-void PrintEntity (entity_t *ent)
-{
- epair_t *ep;
-
- printf ("------- entity %p -------\n", ent);
- for (ep=ent->epairs ; ep ; ep=ep->next)
- {
- printf ("%s = %s\n", ep->key, ep->value);
- }
-
-}
-
-void SetKeyValue (entity_t *ent, char *key, char *value)
-{
- epair_t *ep;
-
- for (ep=ent->epairs ; ep ; ep=ep->next)
- if (!strcmp (ep->key, key) )
- {
- FreeMemory(ep->value);
- ep->value = copystring(value);
- return;
- }
- ep = GetMemory(sizeof(*ep));
- ep->next = ent->epairs;
- ent->epairs = ep;
- ep->key = copystring(key);
- ep->value = copystring(value);
-}
-
-char *ValueForKey (entity_t *ent, char *key)
-{
- epair_t *ep;
-
- for (ep=ent->epairs ; ep ; ep=ep->next)
- if (!strcmp (ep->key, key) )
- return ep->value;
- return "";
-}
-
-vec_t FloatForKey (entity_t *ent, char *key)
-{
- char *k;
-
- k = ValueForKey (ent, key);
- return atof(k);
-}
-
-void GetVectorForKey (entity_t *ent, char *key, vec3_t vec)
-{
- char *k;
- double v1, v2, v3;
-
- k = ValueForKey (ent, key);
-// scanf into doubles, then assign, so it is vec_t size independent
- v1 = v2 = v3 = 0;
- sscanf (k, "%lf %lf %lf", &v1, &v2, &v3);
- vec[0] = v1;
- vec[1] = v2;
- vec[2] = v3;
-}
-
-
diff --git a/code/bspc/l_bsp_ent.h b/code/bspc/l_bsp_ent.h
deleted file mode 100644
index 2fda6dc..0000000
--- a/code/bspc/l_bsp_ent.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-#ifndef MAX_MAP_ENTITIES
-#define MAX_MAP_ENTITIES 2048
-#endif
-
-typedef struct epair_s
-{
- struct epair_s *next;
- char *key;
- char *value;
-} epair_t;
-
-typedef struct
-{
- vec3_t origin;
- int firstbrush;
- int numbrushes;
- epair_t *epairs;
- // only valid for func_areaportals
- int areaportalnum;
- int portalareas[2];
- int modelnum; //for bsp 2 map conversion
- qboolean wasdetail; //for SIN
-} entity_t;
-
-extern int num_entities;
-extern entity_t entities[MAX_MAP_ENTITIES];
-
-void StripTrailing(char *e);
-void SetKeyValue(entity_t *ent, char *key, char *value);
-char *ValueForKey(entity_t *ent, char *key); // will return "" if not present
-vec_t FloatForKey(entity_t *ent, char *key);
-void GetVectorForKey(entity_t *ent, char *key, vec3_t vec);
-qboolean ParseEntity(script_t *script);
-epair_t *ParseEpair(script_t *script);
-void PrintEntity(entity_t *ent);
-
diff --git a/code/bspc/l_bsp_hl.c b/code/bspc/l_bsp_hl.c
deleted file mode 100644
index cc7d510..0000000
--- a/code/bspc/l_bsp_hl.c
+++ /dev/null
@@ -1,888 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-#include "l_cmd.h"
-#include "l_math.h"
-#include "l_mem.h"
-#include "l_log.h"
-#include "../botlib/l_script.h"
-#include "l_bsp_hl.h"
-#include "l_bsp_ent.h"
-
-//=============================================================================
-
-int hl_nummodels;
-hl_dmodel_t *hl_dmodels;//[HL_MAX_MAP_MODELS];
-int hl_dmodels_checksum;
-
-int hl_visdatasize;
-byte *hl_dvisdata;//[HL_MAX_MAP_VISIBILITY];
-int hl_dvisdata_checksum;
-
-int hl_lightdatasize;
-byte *hl_dlightdata;//[HL_MAX_MAP_LIGHTING];
-int hl_dlightdata_checksum;
-
-int hl_texdatasize;
-byte *hl_dtexdata;//[HL_MAX_MAP_MIPTEX]; // (dmiptexlump_t)
-int hl_dtexdata_checksum;
-
-int hl_entdatasize;
-char *hl_dentdata;//[HL_MAX_MAP_ENTSTRING];
-int hl_dentdata_checksum;
-
-int hl_numleafs;
-hl_dleaf_t *hl_dleafs;//[HL_MAX_MAP_LEAFS];
-int hl_dleafs_checksum;
-
-int hl_numplanes;
-hl_dplane_t *hl_dplanes;//[HL_MAX_MAP_PLANES];
-int hl_dplanes_checksum;
-
-int hl_numvertexes;
-hl_dvertex_t *hl_dvertexes;//[HL_MAX_MAP_VERTS];
-int hl_dvertexes_checksum;
-
-int hl_numnodes;
-hl_dnode_t *hl_dnodes;//[HL_MAX_MAP_NODES];
-int hl_dnodes_checksum;
-
-int hl_numtexinfo;
-hl_texinfo_t *hl_texinfo;//[HL_MAX_MAP_TEXINFO];
-int hl_texinfo_checksum;
-
-int hl_numfaces;
-hl_dface_t *hl_dfaces;//[HL_MAX_MAP_FACES];
-int hl_dfaces_checksum;
-
-int hl_numclipnodes;
-hl_dclipnode_t *hl_dclipnodes;//[HL_MAX_MAP_CLIPNODES];
-int hl_dclipnodes_checksum;
-
-int hl_numedges;
-hl_dedge_t *hl_dedges;//[HL_MAX_MAP_EDGES];
-int hl_dedges_checksum;
-
-int hl_nummarksurfaces;
-unsigned short *hl_dmarksurfaces;//[HL_MAX_MAP_MARKSURFACES];
-int hl_dmarksurfaces_checksum;
-
-int hl_numsurfedges;
-int *hl_dsurfedges;//[HL_MAX_MAP_SURFEDGES];
-int hl_dsurfedges_checksum;
-
-//int num_entities;
-//entity_t entities[HL_MAX_MAP_ENTITIES];
-
-
-//#ifdef //ME
-
-int hl_bspallocated = false;
-int hl_allocatedbspmem = 0;
-
-void HL_AllocMaxBSP(void)
-{
- //models
- hl_nummodels = 0;
- hl_dmodels = (hl_dmodel_t *) GetMemory(HL_MAX_MAP_MODELS * sizeof(hl_dmodel_t));
- hl_allocatedbspmem = HL_MAX_MAP_MODELS * sizeof(hl_dmodel_t);
- //visibility
- hl_visdatasize = 0;
- hl_dvisdata = (byte *) GetMemory(HL_MAX_MAP_VISIBILITY * sizeof(byte));
- hl_allocatedbspmem += HL_MAX_MAP_VISIBILITY * sizeof(byte);
- //light data
- hl_lightdatasize = 0;
- hl_dlightdata = (byte *) GetMemory(HL_MAX_MAP_LIGHTING * sizeof(byte));
- hl_allocatedbspmem += HL_MAX_MAP_LIGHTING * sizeof(byte);
- //texture data
- hl_texdatasize = 0;
- hl_dtexdata = (byte *) GetMemory(HL_MAX_MAP_MIPTEX * sizeof(byte)); // (dmiptexlump_t)
- hl_allocatedbspmem += HL_MAX_MAP_MIPTEX * sizeof(byte);
- //entities
- hl_entdatasize = 0;
- hl_dentdata = (char *) GetMemory(HL_MAX_MAP_ENTSTRING * sizeof(char));
- hl_allocatedbspmem += HL_MAX_MAP_ENTSTRING * sizeof(char);
- //leaves
- hl_numleafs = 0;
- hl_dleafs = (hl_dleaf_t *) GetMemory(HL_MAX_MAP_LEAFS * sizeof(hl_dleaf_t));
- hl_allocatedbspmem += HL_MAX_MAP_LEAFS * sizeof(hl_dleaf_t);
- //planes
- hl_numplanes = 0;
- hl_dplanes = (hl_dplane_t *) GetMemory(HL_MAX_MAP_PLANES * sizeof(hl_dplane_t));
- hl_allocatedbspmem += HL_MAX_MAP_PLANES * sizeof(hl_dplane_t);
- //vertexes
- hl_numvertexes = 0;
- hl_dvertexes = (hl_dvertex_t *) GetMemory(HL_MAX_MAP_VERTS * sizeof(hl_dvertex_t));
- hl_allocatedbspmem += HL_MAX_MAP_VERTS * sizeof(hl_dvertex_t);
- //nodes
- hl_numnodes = 0;
- hl_dnodes = (hl_dnode_t *) GetMemory(HL_MAX_MAP_NODES * sizeof(hl_dnode_t));
- hl_allocatedbspmem += HL_MAX_MAP_NODES * sizeof(hl_dnode_t);
- //texture info
- hl_numtexinfo = 0;
- hl_texinfo = (hl_texinfo_t *) GetMemory(HL_MAX_MAP_TEXINFO * sizeof(hl_texinfo_t));
- hl_allocatedbspmem += HL_MAX_MAP_TEXINFO * sizeof(hl_texinfo_t);
- //faces
- hl_numfaces = 0;
- hl_dfaces = (hl_dface_t *) GetMemory(HL_MAX_MAP_FACES * sizeof(hl_dface_t));
- hl_allocatedbspmem += HL_MAX_MAP_FACES * sizeof(hl_dface_t);
- //clip nodes
- hl_numclipnodes = 0;
- hl_dclipnodes = (hl_dclipnode_t *) GetMemory(HL_MAX_MAP_CLIPNODES * sizeof(hl_dclipnode_t));
- hl_allocatedbspmem += HL_MAX_MAP_CLIPNODES * sizeof(hl_dclipnode_t);
- //edges
- hl_numedges = 0;
- hl_dedges = (hl_dedge_t *) GetMemory(HL_MAX_MAP_EDGES * sizeof(hl_dedge_t));
- hl_allocatedbspmem += HL_MAX_MAP_EDGES, sizeof(hl_dedge_t);
- //mark surfaces
- hl_nummarksurfaces = 0;
- hl_dmarksurfaces = (unsigned short *) GetMemory(HL_MAX_MAP_MARKSURFACES * sizeof(unsigned short));
- hl_allocatedbspmem += HL_MAX_MAP_MARKSURFACES * sizeof(unsigned short);
- //surface edges
- hl_numsurfedges = 0;
- hl_dsurfedges = (int *) GetMemory(HL_MAX_MAP_SURFEDGES * sizeof(int));
- hl_allocatedbspmem += HL_MAX_MAP_SURFEDGES * sizeof(int);
- //print allocated memory
- Log_Print("allocated ");
- PrintMemorySize(hl_allocatedbspmem);
- Log_Print(" of BSP memory\n");
-} //end of the function HL_AllocMaxBSP
-
-void HL_FreeMaxBSP(void)
-{
- //models
- hl_nummodels = 0;
- FreeMemory(hl_dmodels);
- hl_dmodels = NULL;
- //visibility
- hl_visdatasize = 0;
- FreeMemory(hl_dvisdata);
- hl_dvisdata = NULL;
- //light data
- hl_lightdatasize = 0;
- FreeMemory(hl_dlightdata);
- hl_dlightdata = NULL;
- //texture data
- hl_texdatasize = 0;
- FreeMemory(hl_dtexdata);
- hl_dtexdata = NULL;
- //entities
- hl_entdatasize = 0;
- FreeMemory(hl_dentdata);
- hl_dentdata = NULL;
- //leaves
- hl_numleafs = 0;
- FreeMemory(hl_dleafs);
- hl_dleafs = NULL;
- //planes
- hl_numplanes = 0;
- FreeMemory(hl_dplanes);
- hl_dplanes = NULL;
- //vertexes
- hl_numvertexes = 0;
- FreeMemory(hl_dvertexes);
- hl_dvertexes = NULL;
- //nodes
- hl_numnodes = 0;
- FreeMemory(hl_dnodes);
- hl_dnodes = NULL;
- //texture info
- hl_numtexinfo = 0;
- FreeMemory(hl_texinfo);
- hl_texinfo = NULL;
- //faces
- hl_numfaces = 0;
- FreeMemory(hl_dfaces);
- hl_dfaces = NULL;
- //clip nodes
- hl_numclipnodes = 0;
- FreeMemory(hl_dclipnodes);
- hl_dclipnodes = NULL;
- //edges
- hl_numedges = 0;
- FreeMemory(hl_dedges);
- hl_dedges = NULL;
- //mark surfaces
- hl_nummarksurfaces = 0;
- FreeMemory(hl_dmarksurfaces);
- hl_dmarksurfaces = NULL;
- //surface edges
- hl_numsurfedges = 0;
- FreeMemory(hl_dsurfedges);
- hl_dsurfedges = NULL;
- //
- Log_Print("freed ");
- PrintMemorySize(hl_allocatedbspmem);
- Log_Print(" of BSP memory\n");
- hl_allocatedbspmem = 0;
-} //end of the function HL_FreeMaxBSP
-//#endif //ME
-
-/*
-===============
-FastChecksum
-===============
-*/
-
-int FastChecksum(void *buffer, int bytes)
-{
- int checksum = 0;
-
- while( bytes-- )
- checksum = (checksum << 4) ^ *((char *)buffer)++;
-
- return checksum;
-}
-
-/*
-===============
-HL_CompressVis
-===============
-*/
-int HL_CompressVis(byte *vis, byte *dest)
-{
- int j;
- int rep;
- int visrow;
- byte *dest_p;
-
- dest_p = dest;
- visrow = (hl_numleafs + 7)>>3;
-
- for (j=0 ; j<visrow ; j++)
- {
- *dest_p++ = vis[j];
- if (vis[j])
- continue;
-
- rep = 1;
- for ( j++; j<visrow ; j++)
- if (vis[j] || rep == 255)
- break;
- else
- rep++;
- *dest_p++ = rep;
- j--;
- }
-
- return dest_p - dest;
-}
-
-
-/*
-===================
-HL_DecompressVis
-===================
-*/
-void HL_DecompressVis (byte *in, byte *decompressed)
-{
- int c;
- byte *out;
- int row;
-
- row = (hl_numleafs+7)>>3;
- out = decompressed;
-
- do
- {
- if (*in)
- {
- *out++ = *in++;
- continue;
- }
-
- c = in[1];
- in += 2;
- while (c)
- {
- *out++ = 0;
- c--;
- }
- } while (out - decompressed < row);
-}
-
-//=============================================================================
-
-/*
-=============
-HL_SwapBSPFile
-
-Byte swaps all data in a bsp file.
-=============
-*/
-void HL_SwapBSPFile (qboolean todisk)
-{
- int i, j, c;
- hl_dmodel_t *d;
- hl_dmiptexlump_t *mtl;
-
-
-// models
- for (i = 0; i < hl_nummodels; i++)
- {
- d = &hl_dmodels[i];
-
- for (j = 0; j < HL_MAX_MAP_HULLS; j++)
- d->headnode[j] = LittleLong(d->headnode[j]);
-
- d->visleafs = LittleLong(d->visleafs);
- d->firstface = LittleLong(d->firstface);
- d->numfaces = LittleLong(d->numfaces);
-
- for (j = 0; j < 3; j++)
- {
- d->mins[j] = LittleFloat(d->mins[j]);
- d->maxs[j] = LittleFloat(d->maxs[j]);
- d->origin[j] = LittleFloat(d->origin[j]);
- }
- }
-
-//
-// vertexes
-//
- for (i = 0; i < hl_numvertexes; i++)
- {
- for (j = 0; j < 3; j++)
- hl_dvertexes[i].point[j] = LittleFloat (hl_dvertexes[i].point[j]);
- }
-
-//
-// planes
-//
- for (i=0 ; i<hl_numplanes ; i++)
- {
- for (j=0 ; j<3 ; j++)
- hl_dplanes[i].normal[j] = LittleFloat (hl_dplanes[i].normal[j]);
- hl_dplanes[i].dist = LittleFloat (hl_dplanes[i].dist);
- hl_dplanes[i].type = LittleLong (hl_dplanes[i].type);
- }
-
-//
-// texinfos
-//
- for (i=0 ; i<hl_numtexinfo ; i++)
- {
- for (j=0 ; j<8 ; j++)
- hl_texinfo[i].vecs[0][j] = LittleFloat (hl_texinfo[i].vecs[0][j]);
- hl_texinfo[i].miptex = LittleLong (hl_texinfo[i].miptex);
- hl_texinfo[i].flags = LittleLong (hl_texinfo[i].flags);
- }
-
-//
-// faces
-//
- for (i=0 ; i<hl_numfaces ; i++)
- {
- hl_dfaces[i].texinfo = LittleShort (hl_dfaces[i].texinfo);
- hl_dfaces[i].planenum = LittleShort (hl_dfaces[i].planenum);
- hl_dfaces[i].side = LittleShort (hl_dfaces[i].side);
- hl_dfaces[i].lightofs = LittleLong (hl_dfaces[i].lightofs);
- hl_dfaces[i].firstedge = LittleLong (hl_dfaces[i].firstedge);
- hl_dfaces[i].numedges = LittleShort (hl_dfaces[i].numedges);
- }
-
-//
-// nodes
-//
- for (i=0 ; i<hl_numnodes ; i++)
- {
- hl_dnodes[i].planenum = LittleLong (hl_dnodes[i].planenum);
- for (j=0 ; j<3 ; j++)
- {
- hl_dnodes[i].mins[j] = LittleShort (hl_dnodes[i].mins[j]);
- hl_dnodes[i].maxs[j] = LittleShort (hl_dnodes[i].maxs[j]);
- }
- hl_dnodes[i].children[0] = LittleShort (hl_dnodes[i].children[0]);
- hl_dnodes[i].children[1] = LittleShort (hl_dnodes[i].children[1]);
- hl_dnodes[i].firstface = LittleShort (hl_dnodes[i].firstface);
- hl_dnodes[i].numfaces = LittleShort (hl_dnodes[i].numfaces);
- }
-
-//
-// leafs
-//
- for (i=0 ; i<hl_numleafs ; i++)
- {
- hl_dleafs[i].contents = LittleLong (hl_dleafs[i].contents);
- for (j=0 ; j<3 ; j++)
- {
- hl_dleafs[i].mins[j] = LittleShort (hl_dleafs[i].mins[j]);
- hl_dleafs[i].maxs[j] = LittleShort (hl_dleafs[i].maxs[j]);
- }
-
- hl_dleafs[i].firstmarksurface = LittleShort (hl_dleafs[i].firstmarksurface);
- hl_dleafs[i].nummarksurfaces = LittleShort (hl_dleafs[i].nummarksurfaces);
- hl_dleafs[i].visofs = LittleLong (hl_dleafs[i].visofs);
- }
-
-//
-// clipnodes
-//
- for (i=0 ; i<hl_numclipnodes ; i++)
- {
- hl_dclipnodes[i].planenum = LittleLong (hl_dclipnodes[i].planenum);
- hl_dclipnodes[i].children[0] = LittleShort (hl_dclipnodes[i].children[0]);
- hl_dclipnodes[i].children[1] = LittleShort (hl_dclipnodes[i].children[1]);
- }
-
-//
-// miptex
-//
- if (hl_texdatasize)
- {
- mtl = (hl_dmiptexlump_t *)hl_dtexdata;
- if (todisk)
- c = mtl->nummiptex;
- else
- c = LittleLong(mtl->nummiptex);
- mtl->nummiptex = LittleLong (mtl->nummiptex);
- for (i=0 ; i<c ; i++)
- mtl->dataofs[i] = LittleLong(mtl->dataofs[i]);
- }
-
-//
-// marksurfaces
-//
- for (i=0 ; i<hl_nummarksurfaces ; i++)
- hl_dmarksurfaces[i] = LittleShort (hl_dmarksurfaces[i]);
-
-//
-// surfedges
-//
- for (i=0 ; i<hl_numsurfedges ; i++)
- hl_dsurfedges[i] = LittleLong (hl_dsurfedges[i]);
-
-//
-// edges
-//
- for (i=0 ; i<hl_numedges ; i++)
- {
- hl_dedges[i].v[0] = LittleShort (hl_dedges[i].v[0]);
- hl_dedges[i].v[1] = LittleShort (hl_dedges[i].v[1]);
- }
-} //end of the function HL_SwapBSPFile
-
-
-hl_dheader_t *hl_header;
-int hl_fileLength;
-
-int HL_CopyLump (int lump, void *dest, int size, int maxsize)
-{
- int length, ofs;
-
- length = hl_header->lumps[lump].filelen;
- ofs = hl_header->lumps[lump].fileofs;
-
- if (length % size) {
- Error ("LoadBSPFile: odd lump size");
- }
- // somehow things got out of range
- if ((length/size) > maxsize) {
- printf("WARNING: exceeded max size for lump %d size %d > maxsize %d\n", lump, (length/size), maxsize);
- length = maxsize * size;
- }
- if ( ofs + length > hl_fileLength ) {
- printf("WARNING: exceeded file length for lump %d\n", lump);
- length = hl_fileLength - ofs;
- if ( length <= 0 ) {
- return 0;
- }
- }
-
- memcpy (dest, (byte *)hl_header + ofs, length);
-
- return length / size;
-}
-
-/*
-=============
-HL_LoadBSPFile
-=============
-*/
-void HL_LoadBSPFile (char *filename, int offset, int length)
-{
- int i;
-
-//
-// load the file header
-//
- hl_fileLength = LoadFile (filename, (void **)&hl_header, offset, length);
-
-// swap the header
- for (i=0 ; i< sizeof(hl_dheader_t)/4 ; i++)
- ((int *)hl_header)[i] = LittleLong ( ((int *)hl_header)[i]);
-
- if (hl_header->version != HL_BSPVERSION)
- Error ("%s is version %i, not %i", filename, hl_header->version, HL_BSPVERSION);
-
- hl_nummodels = HL_CopyLump (HL_LUMP_MODELS, hl_dmodels, sizeof(hl_dmodel_t), HL_MAX_MAP_MODELS );
- hl_numvertexes = HL_CopyLump (HL_LUMP_VERTEXES, hl_dvertexes, sizeof(hl_dvertex_t), HL_MAX_MAP_VERTS );
- hl_numplanes = HL_CopyLump (HL_LUMP_PLANES, hl_dplanes, sizeof(hl_dplane_t), HL_MAX_MAP_PLANES );
- hl_numleafs = HL_CopyLump (HL_LUMP_LEAFS, hl_dleafs, sizeof(hl_dleaf_t), HL_MAX_MAP_LEAFS );
- hl_numnodes = HL_CopyLump (HL_LUMP_NODES, hl_dnodes, sizeof(hl_dnode_t), HL_MAX_MAP_NODES );
- hl_numtexinfo = HL_CopyLump (HL_LUMP_TEXINFO, hl_texinfo, sizeof(hl_texinfo_t), HL_MAX_MAP_TEXINFO );
- hl_numclipnodes = HL_CopyLump (HL_LUMP_CLIPNODES, hl_dclipnodes, sizeof(hl_dclipnode_t), HL_MAX_MAP_CLIPNODES );
- hl_numfaces = HL_CopyLump (HL_LUMP_FACES, hl_dfaces, sizeof(hl_dface_t), HL_MAX_MAP_FACES );
- hl_nummarksurfaces = HL_CopyLump (HL_LUMP_MARKSURFACES, hl_dmarksurfaces, sizeof(hl_dmarksurfaces[0]), HL_MAX_MAP_MARKSURFACES );
- hl_numsurfedges = HL_CopyLump (HL_LUMP_SURFEDGES, hl_dsurfedges, sizeof(hl_dsurfedges[0]), HL_MAX_MAP_SURFEDGES );
- hl_numedges = HL_CopyLump (HL_LUMP_EDGES, hl_dedges, sizeof(hl_dedge_t), HL_MAX_MAP_EDGES );
-
- hl_texdatasize = HL_CopyLump (HL_LUMP_TEXTURES, hl_dtexdata, 1, HL_MAX_MAP_MIPTEX );
- hl_visdatasize = HL_CopyLump (HL_LUMP_VISIBILITY, hl_dvisdata, 1, HL_MAX_MAP_VISIBILITY );
- hl_lightdatasize = HL_CopyLump (HL_LUMP_LIGHTING, hl_dlightdata, 1, HL_MAX_MAP_LIGHTING );
- hl_entdatasize = HL_CopyLump (HL_LUMP_ENTITIES, hl_dentdata, 1, HL_MAX_MAP_ENTSTRING );
-
- FreeMemory(hl_header); // everything has been copied out
-
-//
-// swap everything
-//
- HL_SwapBSPFile (false);
-
- hl_dmodels_checksum = FastChecksum( hl_dmodels, hl_nummodels*sizeof(hl_dmodels[0]) );
- hl_dvertexes_checksum = FastChecksum( hl_dvertexes, hl_numvertexes*sizeof(hl_dvertexes[0]) );
- hl_dplanes_checksum = FastChecksum( hl_dplanes, hl_numplanes*sizeof(hl_dplanes[0]) );
- hl_dleafs_checksum = FastChecksum( hl_dleafs, hl_numleafs*sizeof(hl_dleafs[0]) );
- hl_dnodes_checksum = FastChecksum( hl_dnodes, hl_numnodes*sizeof(hl_dnodes[0]) );
- hl_texinfo_checksum = FastChecksum( hl_texinfo, hl_numtexinfo*sizeof(hl_texinfo[0]) );
- hl_dclipnodes_checksum = FastChecksum( hl_dclipnodes, hl_numclipnodes*sizeof(hl_dclipnodes[0]) );
- hl_dfaces_checksum = FastChecksum( hl_dfaces, hl_numfaces*sizeof(hl_dfaces[0]) );
- hl_dmarksurfaces_checksum = FastChecksum( hl_dmarksurfaces, hl_nummarksurfaces*sizeof(hl_dmarksurfaces[0]) );
- hl_dsurfedges_checksum = FastChecksum( hl_dsurfedges, hl_numsurfedges*sizeof(hl_dsurfedges[0]) );
- hl_dedges_checksum = FastChecksum( hl_dedges, hl_numedges*sizeof(hl_dedges[0]) );
- hl_dtexdata_checksum = FastChecksum( hl_dtexdata, hl_numedges*sizeof(hl_dtexdata[0]) );
- hl_dvisdata_checksum = FastChecksum( hl_dvisdata, hl_visdatasize*sizeof(hl_dvisdata[0]) );
- hl_dlightdata_checksum = FastChecksum( hl_dlightdata, hl_lightdatasize*sizeof(hl_dlightdata[0]) );
- hl_dentdata_checksum = FastChecksum( hl_dentdata, hl_entdatasize*sizeof(hl_dentdata[0]) );
-
-}
-
-//============================================================================
-
-FILE *wadfile;
-hl_dheader_t outheader;
-
-void HL_AddLump (int lumpnum, void *data, int len)
-{
- hl_lump_t *lump;
-
- lump = &hl_header->lumps[lumpnum];
-
- lump->fileofs = LittleLong( ftell(wadfile) );
- lump->filelen = LittleLong(len);
- SafeWrite (wadfile, data, (len+3)&~3);
-}
-
-/*
-=============
-HL_WriteBSPFile
-
-Swaps the bsp file in place, so it should not be referenced again
-=============
-*/
-void HL_WriteBSPFile (char *filename)
-{
- hl_header = &outheader;
- memset (hl_header, 0, sizeof(hl_dheader_t));
-
- HL_SwapBSPFile (true);
-
- hl_header->version = LittleLong (HL_BSPVERSION);
-
- wadfile = SafeOpenWrite (filename);
- SafeWrite (wadfile, hl_header, sizeof(hl_dheader_t)); // overwritten later
-
- HL_AddLump (HL_LUMP_PLANES, hl_dplanes, hl_numplanes*sizeof(hl_dplane_t));
- HL_AddLump (HL_LUMP_LEAFS, hl_dleafs, hl_numleafs*sizeof(hl_dleaf_t));
- HL_AddLump (HL_LUMP_VERTEXES, hl_dvertexes, hl_numvertexes*sizeof(hl_dvertex_t));
- HL_AddLump (HL_LUMP_NODES, hl_dnodes, hl_numnodes*sizeof(hl_dnode_t));
- HL_AddLump (HL_LUMP_TEXINFO, hl_texinfo, hl_numtexinfo*sizeof(hl_texinfo_t));
- HL_AddLump (HL_LUMP_FACES, hl_dfaces, hl_numfaces*sizeof(hl_dface_t));
- HL_AddLump (HL_LUMP_CLIPNODES, hl_dclipnodes, hl_numclipnodes*sizeof(hl_dclipnode_t));
- HL_AddLump (HL_LUMP_MARKSURFACES, hl_dmarksurfaces, hl_nummarksurfaces*sizeof(hl_dmarksurfaces[0]));
- HL_AddLump (HL_LUMP_SURFEDGES, hl_dsurfedges, hl_numsurfedges*sizeof(hl_dsurfedges[0]));
- HL_AddLump (HL_LUMP_EDGES, hl_dedges, hl_numedges*sizeof(hl_dedge_t));
- HL_AddLump (HL_LUMP_MODELS, hl_dmodels, hl_nummodels*sizeof(hl_dmodel_t));
-
- HL_AddLump (HL_LUMP_LIGHTING, hl_dlightdata, hl_lightdatasize);
- HL_AddLump (HL_LUMP_VISIBILITY, hl_dvisdata, hl_visdatasize);
- HL_AddLump (HL_LUMP_ENTITIES, hl_dentdata, hl_entdatasize);
- HL_AddLump (HL_LUMP_TEXTURES, hl_dtexdata, hl_texdatasize);
-
- fseek (wadfile, 0, SEEK_SET);
- SafeWrite (wadfile, hl_header, sizeof(hl_dheader_t));
- fclose (wadfile);
-}
-
-//============================================================================
-
-#define ENTRIES(a) (sizeof(a)/sizeof(*(a)))
-#define ENTRYSIZE(a) (sizeof(*(a)))
-
-ArrayUsage( char *szItem, int items, int maxitems, int itemsize )
-{
- float percentage = maxitems ? items * 100.0 / maxitems : 0.0;
-
- qprintf("%-12s %7i/%-7i %7i/%-7i (%4.1f%%)",
- szItem, items, maxitems, items * itemsize, maxitems * itemsize, percentage );
- if ( percentage > 80.0 )
- qprintf( "VERY FULL!\n" );
- else if ( percentage > 95.0 )
- qprintf( "SIZE DANGER!\n" );
- else if ( percentage > 99.9 )
- qprintf( "SIZE OVERFLOW!!!\n" );
- else
- qprintf( "\n" );
- return items * itemsize;
-}
-
-GlobUsage( char *szItem, int itemstorage, int maxstorage )
-{
- float percentage = maxstorage ? itemstorage * 100.0 / maxstorage : 0.0;
-
- qprintf("%-12s [variable] %7i/%-7i (%4.1f%%)",
- szItem, itemstorage, maxstorage, percentage );
- if ( percentage > 80.0 )
- qprintf( "VERY FULL!\n" );
- else if ( percentage > 95.0 )
- qprintf( "SIZE DANGER!\n" );
- else if ( percentage > 99.9 )
- qprintf( "SIZE OVERFLOW!!!\n" );
- else
- qprintf( "\n" );
- return itemstorage;
-}
-
-/*
-=============
-HL_PrintBSPFileSizes
-
-Dumps info about current file
-=============
-*/
-void HL_PrintBSPFileSizes(void)
-{
- int numtextures = hl_texdatasize ? ((hl_dmiptexlump_t*)hl_dtexdata)->nummiptex : 0;
- int totalmemory = 0;
-
- qprintf("\n");
- qprintf("Object names Objects/Maxobjs Memory / Maxmem Fullness\n" );
- qprintf("------------ --------------- --------------- --------\n" );
-
- totalmemory += ArrayUsage( "models", hl_nummodels, ENTRIES(hl_dmodels), ENTRYSIZE(hl_dmodels) );
- totalmemory += ArrayUsage( "planes", hl_numplanes, ENTRIES(hl_dplanes), ENTRYSIZE(hl_dplanes) );
- totalmemory += ArrayUsage( "vertexes", hl_numvertexes, ENTRIES(hl_dvertexes), ENTRYSIZE(hl_dvertexes) );
- totalmemory += ArrayUsage( "nodes", hl_numnodes, ENTRIES(hl_dnodes), ENTRYSIZE(hl_dnodes) );
- totalmemory += ArrayUsage( "texinfos", hl_numtexinfo, ENTRIES(hl_texinfo), ENTRYSIZE(hl_texinfo) );
- totalmemory += ArrayUsage( "faces", hl_numfaces, ENTRIES(hl_dfaces), ENTRYSIZE(hl_dfaces) );
- totalmemory += ArrayUsage( "clipnodes", hl_numclipnodes, ENTRIES(hl_dclipnodes), ENTRYSIZE(hl_dclipnodes) );
- totalmemory += ArrayUsage( "leaves", hl_numleafs, ENTRIES(hl_dleafs), ENTRYSIZE(hl_dleafs) );
- totalmemory += ArrayUsage( "marksurfaces",hl_nummarksurfaces,ENTRIES(hl_dmarksurfaces),ENTRYSIZE(hl_dmarksurfaces) );
- totalmemory += ArrayUsage( "surfedges", hl_numsurfedges, ENTRIES(hl_dsurfedges), ENTRYSIZE(hl_dsurfedges) );
- totalmemory += ArrayUsage( "edges", hl_numedges, ENTRIES(hl_dedges), ENTRYSIZE(hl_dedges) );
-
- totalmemory += GlobUsage( "texdata", hl_texdatasize, sizeof(hl_dtexdata) );
- totalmemory += GlobUsage( "lightdata", hl_lightdatasize, sizeof(hl_dlightdata) );
- totalmemory += GlobUsage( "visdata", hl_visdatasize, sizeof(hl_dvisdata) );
- totalmemory += GlobUsage( "entdata", hl_entdatasize, sizeof(hl_dentdata) );
-
- qprintf( "=== Total BSP file data space used: %d bytes ===\n\n", totalmemory );
-}
-
-
-
-/*
-=================
-ParseEpair
-=================
-* /
-epair_t *ParseEpair (void)
-{
- epair_t *e;
-
- e = malloc (sizeof(epair_t));
- memset (e, 0, sizeof(epair_t));
-
- if (strlen(token) >= MAX_KEY-1)
- Error ("ParseEpar: token too long");
- e->key = copystring(token);
- GetToken (false);
- if (strlen(token) >= MAX_VALUE-1)
- Error ("ParseEpar: token too long");
- e->value = copystring(token);
-
- return e;
-} //*/
-
-
-/*
-================
-ParseEntity
-================
-* /
-qboolean ParseEntity (void)
-{
- epair_t *e;
- entity_t *mapent;
-
- if (!GetToken (true))
- return false;
-
- if (strcmp (token, "{") )
- Error ("ParseEntity: { not found");
-
- if (num_entities == HL_MAX_MAP_ENTITIES)
- Error ("num_entities == HL_MAX_MAP_ENTITIES");
-
- mapent = &entities[num_entities];
- num_entities++;
-
- do
- {
- if (!GetToken (true))
- Error ("ParseEntity: EOF without closing brace");
- if (!strcmp (token, "}") )
- break;
- e = ParseEpair ();
- e->next = mapent->epairs;
- mapent->epairs = e;
- } while (1);
-
- return true;
-} //*/
-
-/*
-================
-ParseEntities
-
-Parses the dentdata string into entities
-================
-*/
-void HL_ParseEntities (void)
-{
- script_t *script;
-
- num_entities = 0;
- script = LoadScriptMemory(hl_dentdata, hl_entdatasize, "*Half-Life bsp file");
- SetScriptFlags(script, SCFL_NOSTRINGWHITESPACES |
- SCFL_NOSTRINGESCAPECHARS);
-
- while(ParseEntity(script))
- {
- } //end while
-
- FreeScript(script);
-} //end of the function HL_ParseEntities
-
-
-/*
-================
-UnparseEntities
-
-Generates the dentdata string from all the entities
-================
-*/
-void HL_UnparseEntities (void)
-{
- char *buf, *end;
- epair_t *ep;
- char line[2048];
- int i;
-
- buf = hl_dentdata;
- end = buf;
- *end = 0;
-
- for (i=0 ; i<num_entities ; i++)
- {
- ep = entities[i].epairs;
- if (!ep)
- continue; // ent got removed
-
- strcat (end,"{\n");
- end += 2;
-
- for (ep = entities[i].epairs ; ep ; ep=ep->next)
- {
- sprintf (line, "\"%s\" \"%s\"\n", ep->key, ep->value);
- strcat (end, line);
- end += strlen(line);
- }
- strcat (end,"}\n");
- end += 2;
-
- if (end > buf + HL_MAX_MAP_ENTSTRING)
- Error ("Entity text too long");
- }
- hl_entdatasize = end - buf + 1;
-} //end of the function HL_UnparseEntities
-
-
-/*
-void SetKeyValue (entity_t *ent, char *key, char *value)
-{
- epair_t *ep;
-
- for (ep=ent->epairs ; ep ; ep=ep->next)
- if (!strcmp (ep->key, key) )
- {
- free (ep->value);
- ep->value = copystring(value);
- return;
- }
- ep = malloc (sizeof(*ep));
- ep->next = ent->epairs;
- ent->epairs = ep;
- ep->key = copystring(key);
- ep->value = copystring(value);
-}
-
-char *ValueForKey (entity_t *ent, char *key)
-{
- epair_t *ep;
-
- for (ep=ent->epairs ; ep ; ep=ep->next)
- if (!strcmp (ep->key, key) )
- return ep->value;
- return "";
-}
-
-vec_t FloatForKey (entity_t *ent, char *key)
-{
- char *k;
-
- k = ValueForKey (ent, key);
- return atof(k);
-}
-
-void GetVectorForKey (entity_t *ent, char *key, vec3_t vec)
-{
- char *k;
- double v1, v2, v3;
-
- k = ValueForKey (ent, key);
-// scanf into doubles, then assign, so it is vec_t size independent
- v1 = v2 = v3 = 0;
- sscanf (k, "%lf %lf %lf", &v1, &v2, &v3);
- vec[0] = v1;
- vec[1] = v2;
- vec[2] = v3;
-} //*/
diff --git a/code/bspc/l_bsp_hl.h b/code/bspc/l_bsp_hl.h
deleted file mode 100644
index 8151771..0000000
--- a/code/bspc/l_bsp_hl.h
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-// upper design bounds
-
-#define HL_MAX_MAP_HULLS 4
-
-#define HL_MAX_MAP_MODELS 400
-#define HL_MAX_MAP_BRUSHES 4096
-#define HL_MAX_MAP_ENTITIES 1024
-#define HL_MAX_MAP_ENTSTRING (128*1024)
-
-#define HL_MAX_MAP_PLANES 32767
-#define HL_MAX_MAP_NODES 32767 // because negative shorts are contents
-#define HL_MAX_MAP_CLIPNODES 32767 //
-#define HL_MAX_MAP_LEAFS 8192
-#define HL_MAX_MAP_VERTS 65535
-#define HL_MAX_MAP_FACES 65535
-#define HL_MAX_MAP_MARKSURFACES 65535
-#define HL_MAX_MAP_TEXINFO 8192
-#define HL_MAX_MAP_EDGES 256000
-#define HL_MAX_MAP_SURFEDGES 512000
-#define HL_MAX_MAP_TEXTURES 512
-#define HL_MAX_MAP_MIPTEX 0x200000
-#define HL_MAX_MAP_LIGHTING 0x200000
-#define HL_MAX_MAP_VISIBILITY 0x200000
-
-#define HL_MAX_MAP_PORTALS 65536
-
-// key / value pair sizes
-
-#define MAX_KEY 32
-#define MAX_VALUE 1024
-
-//=============================================================================
-
-
-#define HL_BSPVERSION 30
-#define HL_TOOLVERSION 2
-
-
-typedef struct
-{
- int fileofs, filelen;
-} hl_lump_t;
-
-#define HL_LUMP_ENTITIES 0
-#define HL_LUMP_PLANES 1
-#define HL_LUMP_TEXTURES 2
-#define HL_LUMP_VERTEXES 3
-#define HL_LUMP_VISIBILITY 4
-#define HL_LUMP_NODES 5
-#define HL_LUMP_TEXINFO 6
-#define HL_LUMP_FACES 7
-#define HL_LUMP_LIGHTING 8
-#define HL_LUMP_CLIPNODES 9
-#define HL_LUMP_LEAFS 10
-#define HL_LUMP_MARKSURFACES 11
-#define HL_LUMP_EDGES 12
-#define HL_LUMP_SURFEDGES 13
-#define HL_LUMP_MODELS 14
-
-#define HL_HEADER_LUMPS 15
-
-typedef struct
-{
- float mins[3], maxs[3];
- float origin[3];
- int headnode[HL_MAX_MAP_HULLS];
- int visleafs; // not including the solid leaf 0
- int firstface, numfaces;
-} hl_dmodel_t;
-
-typedef struct
-{
- int version;
- hl_lump_t lumps[HL_HEADER_LUMPS];
-} hl_dheader_t;
-
-typedef struct
-{
- int nummiptex;
- int dataofs[4]; // [nummiptex]
-} hl_dmiptexlump_t;
-
-#define MIPLEVELS 4
-typedef struct hl_miptex_s
-{
- char name[16];
- unsigned width, height;
- unsigned offsets[MIPLEVELS]; // four mip maps stored
-} hl_miptex_t;
-
-
-typedef struct
-{
- float point[3];
-} hl_dvertex_t;
-
-
-// 0-2 are axial planes
-#define PLANE_X 0
-#define PLANE_Y 1
-#define PLANE_Z 2
-
-// 3-5 are non-axial planes snapped to the nearest
-#define PLANE_ANYX 3
-#define PLANE_ANYY 4
-#define PLANE_ANYZ 5
-
-typedef struct
-{
- float normal[3];
- float dist;
- int type; // PLANE_X - PLANE_ANYZ ?remove? trivial to regenerate
-} hl_dplane_t;
-
-
-
-#define HL_CONTENTS_EMPTY -1
-#define HL_CONTENTS_SOLID -2
-#define HL_CONTENTS_WATER -3
-#define HL_CONTENTS_SLIME -4
-#define HL_CONTENTS_LAVA -5
-#define HL_CONTENTS_SKY -6
-#define HL_CONTENTS_ORIGIN -7 // removed at csg time
-#define HL_CONTENTS_CLIP -8 // changed to contents_solid
-
-#define HL_CONTENTS_CURRENT_0 -9
-#define HL_CONTENTS_CURRENT_90 -10
-#define HL_CONTENTS_CURRENT_180 -11
-#define HL_CONTENTS_CURRENT_270 -12
-#define HL_CONTENTS_CURRENT_UP -13
-#define HL_CONTENTS_CURRENT_DOWN -14
-
-#define HL_CONTENTS_TRANSLUCENT -15
-
-// !!! if this is changed, it must be changed in asm_i386.h too !!!
-typedef struct
-{
- int planenum;
- short children[2]; // negative numbers are -(leafs+1), not nodes
- short mins[3]; // for sphere culling
- short maxs[3];
- unsigned short firstface;
- unsigned short numfaces; // counting both sides
-} hl_dnode_t;
-
-typedef struct
-{
- int planenum;
- short children[2]; // negative numbers are contents
-} hl_dclipnode_t;
-
-
-typedef struct hl_texinfo_s
-{
- float vecs[2][4]; // [s/t][xyz offset]
- int miptex;
- int flags;
-} hl_texinfo_t;
-#define TEX_SPECIAL 1 // sky or slime, no lightmap or 256 subdivision
-
-// note that edge 0 is never used, because negative edge nums are used for
-// counterclockwise use of the edge in a face
-typedef struct
-{
- unsigned short v[2]; // vertex numbers
-} hl_dedge_t;
-
-#define MAXLIGHTMAPS 4
-typedef struct
-{
- short planenum;
- short side;
-
- int firstedge; // we must support > 64k edges
- short numedges;
- short texinfo;
-
-// lighting info
- byte styles[MAXLIGHTMAPS];
- int lightofs; // start of [numstyles*surfsize] samples
-} hl_dface_t;
-
-
-#define AMBIENT_WATER 0
-#define AMBIENT_SKY 1
-#define AMBIENT_SLIME 2
-#define AMBIENT_LAVA 3
-
-#define NUM_AMBIENTS 4 // automatic ambient sounds
-
-// leaf 0 is the generic HL_CONTENTS_SOLID leaf, used for all solid areas
-// all other leafs need visibility info
-typedef struct
-{
- int contents;
- int visofs; // -1 = no visibility info
-
- short mins[3]; // for frustum culling
- short maxs[3];
-
- unsigned short firstmarksurface;
- unsigned short nummarksurfaces;
-
- byte ambient_level[NUM_AMBIENTS];
-} hl_dleaf_t;
-
-
-//============================================================================
-
-#ifndef QUAKE_GAME
-
-#define ANGLE_UP -1
-#define ANGLE_DOWN -2
-
-
-// the utilities get to be lazy and just use large static arrays
-
-extern int hl_nummodels;
-extern hl_dmodel_t *hl_dmodels;//[MAX_MAP_MODELS];
-extern int hl_dmodels_checksum;
-
-extern int hl_visdatasize;
-extern byte *hl_dvisdata;//[MAX_MAP_VISIBILITY];
-extern int hl_dvisdata_checksum;
-
-extern int hl_lightdatasize;
-extern byte *hl_dlightdata;//[MAX_MAP_LIGHTING];
-extern int hl_dlightdata_checksum;
-
-extern int hl_texdatasize;
-extern byte *hl_dtexdata;//[MAX_MAP_MIPTEX]; // (dmiptexlump_t)
-extern int hl_dtexdata_checksum;
-
-extern int hl_entdatasize;
-extern char *hl_dentdata;//[MAX_MAP_ENTSTRING];
-extern int hl_dentdata_checksum;
-
-extern int hl_numleafs;
-extern hl_dleaf_t *hl_dleafs;//[MAX_MAP_LEAFS];
-extern int hl_dleafs_checksum;
-
-extern int hl_numplanes;
-extern hl_dplane_t *hl_dplanes;//[MAX_MAP_PLANES];
-extern int hl_dplanes_checksum;
-
-extern int hl_numvertexes;
-extern hl_dvertex_t *hl_dvertexes;//[MAX_MAP_VERTS];
-extern int hl_dvertexes_checksum;
-
-extern int hl_numnodes;
-extern hl_dnode_t *hl_dnodes;//[MAX_MAP_NODES];
-extern int hl_dnodes_checksum;
-
-extern int hl_numtexinfo;
-extern hl_texinfo_t *hl_texinfo;//[MAX_MAP_TEXINFO];
-extern int hl_texinfo_checksum;
-
-extern int hl_numfaces;
-extern hl_dface_t *hl_dfaces;//[MAX_MAP_FACES];
-extern int hl_dfaces_checksum;
-
-extern int hl_numclipnodes;
-extern hl_dclipnode_t *hl_dclipnodes;//[MAX_MAP_CLIPNODES];
-extern int hl_dclipnodes_checksum;
-
-extern int hl_numedges;
-extern hl_dedge_t *hl_dedges;//[MAX_MAP_EDGES];
-extern int hl_dedges_checksum;
-
-extern int hl_nummarksurfaces;
-extern unsigned short *hl_dmarksurfaces;//[MAX_MAP_MARKSURFACES];
-extern int hl_dmarksurfaces_checksum;
-
-extern int hl_numsurfedges;
-extern int *hl_dsurfedges;//[MAX_MAP_SURFEDGES];
-extern int hl_dsurfedges_checksum;
-
-int FastChecksum(void *buffer, int bytes);
-
-void HL_AllocMaxBSP(void);
-void HL_FreeMaxBSP(void);
-
-void HL_DecompressVis(byte *in, byte *decompressed);
-int HL_CompressVis(byte *vis, byte *dest);
-
-void HL_LoadBSPFile(char *filename, int offset, int length);
-void HL_WriteBSPFile(char *filename);
-void HL_PrintBSPFileSizes(void);
-void HL_PrintBSPFileSizes(void);
-void HL_ParseEntities(void);
-void HL_UnparseEntities(void);
-
-#endif
diff --git a/code/bspc/l_bsp_q1.c b/code/bspc/l_bsp_q1.c
deleted file mode 100644
index f19bce1..0000000
--- a/code/bspc/l_bsp_q1.c
+++ /dev/null
@@ -1,620 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-#include "l_cmd.h"
-#include "l_math.h"
-#include "l_mem.h"
-#include "l_log.h"
-#include "../botlib/l_script.h"
-#include "l_bsp_q1.h"
-#include "l_bsp_ent.h"
-
-//=============================================================================
-
-int q1_nummodels;
-q1_dmodel_t *q1_dmodels;//[MAX_MAP_MODELS];
-
-int q1_visdatasize;
-byte *q1_dvisdata;//[MAX_MAP_VISIBILITY];
-
-int q1_lightdatasize;
-byte *q1_dlightdata;//[MAX_MAP_LIGHTING];
-
-int q1_texdatasize;
-byte *q1_dtexdata;//[MAX_MAP_MIPTEX]; // (dmiptexlump_t)
-
-int q1_entdatasize;
-char *q1_dentdata;//[MAX_MAP_ENTSTRING];
-
-int q1_numleafs;
-q1_dleaf_t *q1_dleafs;//[MAX_MAP_LEAFS];
-
-int q1_numplanes;
-q1_dplane_t *q1_dplanes;//[MAX_MAP_PLANES];
-
-int q1_numvertexes;
-q1_dvertex_t *q1_dvertexes;//[MAX_MAP_VERTS];
-
-int q1_numnodes;
-q1_dnode_t *q1_dnodes;//[MAX_MAP_NODES];
-
-int q1_numtexinfo;
-q1_texinfo_t *q1_texinfo;//[MAX_MAP_TEXINFO];
-
-int q1_numfaces;
-q1_dface_t *q1_dfaces;//[MAX_MAP_FACES];
-
-int q1_numclipnodes;
-q1_dclipnode_t *q1_dclipnodes;//[MAX_MAP_CLIPNODES];
-
-int q1_numedges;
-q1_dedge_t *q1_dedges;//[MAX_MAP_EDGES];
-
-int q1_nummarksurfaces;
-unsigned short *q1_dmarksurfaces;//[MAX_MAP_MARKSURFACES];
-
-int q1_numsurfedges;
-int *q1_dsurfedges;//[MAX_MAP_SURFEDGES];
-
-//=============================================================================
-
-int q1_bspallocated = false;
-int q1_allocatedbspmem = 0;
-
-void Q1_AllocMaxBSP(void)
-{
- //models
- q1_nummodels = 0;
- q1_dmodels = (q1_dmodel_t *) GetMemory(Q1_MAX_MAP_MODELS * sizeof(q1_dmodel_t));
- q1_allocatedbspmem = Q1_MAX_MAP_MODELS * sizeof(q1_dmodel_t);
- //visibility
- q1_visdatasize = 0;
- q1_dvisdata = (byte *) GetMemory(Q1_MAX_MAP_VISIBILITY * sizeof(byte));
- q1_allocatedbspmem += Q1_MAX_MAP_VISIBILITY * sizeof(byte);
- //light data
- q1_lightdatasize = 0;
- q1_dlightdata = (byte *) GetMemory(Q1_MAX_MAP_LIGHTING * sizeof(byte));
- q1_allocatedbspmem += Q1_MAX_MAP_LIGHTING * sizeof(byte);
- //texture data
- q1_texdatasize = 0;
- q1_dtexdata = (byte *) GetMemory(Q1_MAX_MAP_MIPTEX * sizeof(byte)); // (dmiptexlump_t)
- q1_allocatedbspmem += Q1_MAX_MAP_MIPTEX * sizeof(byte);
- //entities
- q1_entdatasize = 0;
- q1_dentdata = (char *) GetMemory(Q1_MAX_MAP_ENTSTRING * sizeof(char));
- q1_allocatedbspmem += Q1_MAX_MAP_ENTSTRING * sizeof(char);
- //leaves
- q1_numleafs = 0;
- q1_dleafs = (q1_dleaf_t *) GetMemory(Q1_MAX_MAP_LEAFS * sizeof(q1_dleaf_t));
- q1_allocatedbspmem += Q1_MAX_MAP_LEAFS * sizeof(q1_dleaf_t);
- //planes
- q1_numplanes = 0;
- q1_dplanes = (q1_dplane_t *) GetMemory(Q1_MAX_MAP_PLANES * sizeof(q1_dplane_t));
- q1_allocatedbspmem += Q1_MAX_MAP_PLANES * sizeof(q1_dplane_t);
- //vertexes
- q1_numvertexes = 0;
- q1_dvertexes = (q1_dvertex_t *) GetMemory(Q1_MAX_MAP_VERTS * sizeof(q1_dvertex_t));
- q1_allocatedbspmem += Q1_MAX_MAP_VERTS * sizeof(q1_dvertex_t);
- //nodes
- q1_numnodes = 0;
- q1_dnodes = (q1_dnode_t *) GetMemory(Q1_MAX_MAP_NODES * sizeof(q1_dnode_t));
- q1_allocatedbspmem += Q1_MAX_MAP_NODES * sizeof(q1_dnode_t);
- //texture info
- q1_numtexinfo = 0;
- q1_texinfo = (q1_texinfo_t *) GetMemory(Q1_MAX_MAP_TEXINFO * sizeof(q1_texinfo_t));
- q1_allocatedbspmem += Q1_MAX_MAP_TEXINFO * sizeof(q1_texinfo_t);
- //faces
- q1_numfaces = 0;
- q1_dfaces = (q1_dface_t *) GetMemory(Q1_MAX_MAP_FACES * sizeof(q1_dface_t));
- q1_allocatedbspmem += Q1_MAX_MAP_FACES * sizeof(q1_dface_t);
- //clip nodes
- q1_numclipnodes = 0;
- q1_dclipnodes = (q1_dclipnode_t *) GetMemory(Q1_MAX_MAP_CLIPNODES * sizeof(q1_dclipnode_t));
- q1_allocatedbspmem += Q1_MAX_MAP_CLIPNODES * sizeof(q1_dclipnode_t);
- //edges
- q1_numedges = 0;
- q1_dedges = (q1_dedge_t *) GetMemory(Q1_MAX_MAP_EDGES * sizeof(q1_dedge_t));
- q1_allocatedbspmem += Q1_MAX_MAP_EDGES, sizeof(q1_dedge_t);
- //mark surfaces
- q1_nummarksurfaces = 0;
- q1_dmarksurfaces = (unsigned short *) GetMemory(Q1_MAX_MAP_MARKSURFACES * sizeof(unsigned short));
- q1_allocatedbspmem += Q1_MAX_MAP_MARKSURFACES * sizeof(unsigned short);
- //surface edges
- q1_numsurfedges = 0;
- q1_dsurfedges = (int *) GetMemory(Q1_MAX_MAP_SURFEDGES * sizeof(int));
- q1_allocatedbspmem += Q1_MAX_MAP_SURFEDGES * sizeof(int);
- //print allocated memory
- Log_Print("allocated ");
- PrintMemorySize(q1_allocatedbspmem);
- Log_Print(" of BSP memory\n");
-} //end of the function Q1_AllocMaxBSP
-
-void Q1_FreeMaxBSP(void)
-{
- //models
- q1_nummodels = 0;
- FreeMemory(q1_dmodels);
- q1_dmodels = NULL;
- //visibility
- q1_visdatasize = 0;
- FreeMemory(q1_dvisdata);
- q1_dvisdata = NULL;
- //light data
- q1_lightdatasize = 0;
- FreeMemory(q1_dlightdata);
- q1_dlightdata = NULL;
- //texture data
- q1_texdatasize = 0;
- FreeMemory(q1_dtexdata);
- q1_dtexdata = NULL;
- //entities
- q1_entdatasize = 0;
- FreeMemory(q1_dentdata);
- q1_dentdata = NULL;
- //leaves
- q1_numleafs = 0;
- FreeMemory(q1_dleafs);
- q1_dleafs = NULL;
- //planes
- q1_numplanes = 0;
- FreeMemory(q1_dplanes);
- q1_dplanes = NULL;
- //vertexes
- q1_numvertexes = 0;
- FreeMemory(q1_dvertexes);
- q1_dvertexes = NULL;
- //nodes
- q1_numnodes = 0;
- FreeMemory(q1_dnodes);
- q1_dnodes = NULL;
- //texture info
- q1_numtexinfo = 0;
- FreeMemory(q1_texinfo);
- q1_texinfo = NULL;
- //faces
- q1_numfaces = 0;
- FreeMemory(q1_dfaces);
- q1_dfaces = NULL;
- //clip nodes
- q1_numclipnodes = 0;
- FreeMemory(q1_dclipnodes);
- q1_dclipnodes = NULL;
- //edges
- q1_numedges = 0;
- FreeMemory(q1_dedges);
- q1_dedges = NULL;
- //mark surfaces
- q1_nummarksurfaces = 0;
- FreeMemory(q1_dmarksurfaces);
- q1_dmarksurfaces = NULL;
- //surface edges
- q1_numsurfedges = 0;
- FreeMemory(q1_dsurfedges);
- q1_dsurfedges = NULL;
- //
- Log_Print("freed ");
- PrintMemorySize(q1_allocatedbspmem);
- Log_Print(" of BSP memory\n");
- q1_allocatedbspmem = 0;
-} //end of the function Q1_FreeMaxBSP
-//#endif //ME
-
-/*
-=============
-Q1_SwapBSPFile
-
-Byte swaps all data in a bsp file.
-=============
-*/
-void Q1_SwapBSPFile (qboolean todisk)
-{
- int i, j, c;
- q1_dmodel_t *d;
- q1_dmiptexlump_t *mtl;
-
-
-// models
- for (i=0 ; i<q1_nummodels ; i++)
- {
- d = &q1_dmodels[i];
-
- for (j=0 ; j<Q1_MAX_MAP_HULLS ; j++)
- d->headnode[j] = LittleLong (d->headnode[j]);
-
- d->visleafs = LittleLong (d->visleafs);
- d->firstface = LittleLong (d->firstface);
- d->numfaces = LittleLong (d->numfaces);
-
- for (j=0 ; j<3 ; j++)
- {
- d->mins[j] = LittleFloat(d->mins[j]);
- d->maxs[j] = LittleFloat(d->maxs[j]);
- d->origin[j] = LittleFloat(d->origin[j]);
- }
- }
-
-//
-// vertexes
-//
- for (i=0 ; i<q1_numvertexes ; i++)
- {
- for (j=0 ; j<3 ; j++)
- q1_dvertexes[i].point[j] = LittleFloat(q1_dvertexes[i].point[j]);
- }
-
-//
-// planes
-//
- for (i=0 ; i<q1_numplanes ; i++)
- {
- for (j=0 ; j<3 ; j++)
- q1_dplanes[i].normal[j] = LittleFloat(q1_dplanes[i].normal[j]);
- q1_dplanes[i].dist = LittleFloat(q1_dplanes[i].dist);
- q1_dplanes[i].type = LittleLong(q1_dplanes[i].type);
- }
-
-//
-// texinfos
-//
- for (i=0 ; i<q1_numtexinfo ; i++)
- {
- for (j=0 ; j<8 ; j++)
- q1_texinfo[i].vecs[0][j] = LittleFloat(q1_texinfo[i].vecs[0][j]);
- q1_texinfo[i].miptex = LittleLong(q1_texinfo[i].miptex);
- q1_texinfo[i].flags = LittleLong(q1_texinfo[i].flags);
- }
-
-//
-// faces
-//
- for (i=0 ; i<q1_numfaces ; i++)
- {
- q1_dfaces[i].texinfo = LittleShort(q1_dfaces[i].texinfo);
- q1_dfaces[i].planenum = LittleShort(q1_dfaces[i].planenum);
- q1_dfaces[i].side = LittleShort(q1_dfaces[i].side);
- q1_dfaces[i].lightofs = LittleLong(q1_dfaces[i].lightofs);
- q1_dfaces[i].firstedge = LittleLong(q1_dfaces[i].firstedge);
- q1_dfaces[i].numedges = LittleShort(q1_dfaces[i].numedges);
- }
-
-//
-// nodes
-//
- for (i=0 ; i<q1_numnodes ; i++)
- {
- q1_dnodes[i].planenum = LittleLong(q1_dnodes[i].planenum);
- for (j=0 ; j<3 ; j++)
- {
- q1_dnodes[i].mins[j] = LittleShort(q1_dnodes[i].mins[j]);
- q1_dnodes[i].maxs[j] = LittleShort(q1_dnodes[i].maxs[j]);
- }
- q1_dnodes[i].children[0] = LittleShort(q1_dnodes[i].children[0]);
- q1_dnodes[i].children[1] = LittleShort(q1_dnodes[i].children[1]);
- q1_dnodes[i].firstface = LittleShort(q1_dnodes[i].firstface);
- q1_dnodes[i].numfaces = LittleShort(q1_dnodes[i].numfaces);
- }
-
-//
-// leafs
-//
- for (i=0 ; i<q1_numleafs ; i++)
- {
- q1_dleafs[i].contents = LittleLong(q1_dleafs[i].contents);
- for (j=0 ; j<3 ; j++)
- {
- q1_dleafs[i].mins[j] = LittleShort(q1_dleafs[i].mins[j]);
- q1_dleafs[i].maxs[j] = LittleShort(q1_dleafs[i].maxs[j]);
- }
-
- q1_dleafs[i].firstmarksurface = LittleShort(q1_dleafs[i].firstmarksurface);
- q1_dleafs[i].nummarksurfaces = LittleShort(q1_dleafs[i].nummarksurfaces);
- q1_dleafs[i].visofs = LittleLong(q1_dleafs[i].visofs);
- }
-
-//
-// clipnodes
-//
- for (i=0 ; i<q1_numclipnodes ; i++)
- {
- q1_dclipnodes[i].planenum = LittleLong(q1_dclipnodes[i].planenum);
- q1_dclipnodes[i].children[0] = LittleShort(q1_dclipnodes[i].children[0]);
- q1_dclipnodes[i].children[1] = LittleShort(q1_dclipnodes[i].children[1]);
- }
-
-//
-// miptex
-//
- if (q1_texdatasize)
- {
- mtl = (q1_dmiptexlump_t *)q1_dtexdata;
- if (todisk)
- c = mtl->nummiptex;
- else
- c = LittleLong(mtl->nummiptex);
- mtl->nummiptex = LittleLong (mtl->nummiptex);
- for (i=0 ; i<c ; i++)
- mtl->dataofs[i] = LittleLong(mtl->dataofs[i]);
- }
-
-//
-// marksurfaces
-//
- for (i=0 ; i<q1_nummarksurfaces ; i++)
- q1_dmarksurfaces[i] = LittleShort(q1_dmarksurfaces[i]);
-
-//
-// surfedges
-//
- for (i=0 ; i<q1_numsurfedges ; i++)
- q1_dsurfedges[i] = LittleLong(q1_dsurfedges[i]);
-
-//
-// edges
-//
- for (i=0 ; i<q1_numedges ; i++)
- {
- q1_dedges[i].v[0] = LittleShort(q1_dedges[i].v[0]);
- q1_dedges[i].v[1] = LittleShort(q1_dedges[i].v[1]);
- }
-}
-
-
-q1_dheader_t *q1_header;
-int q1_fileLength;
-
-int Q1_CopyLump (int lump, void *dest, int size, int maxsize)
-{
- int length, ofs;
-
- length = q1_header->lumps[lump].filelen;
- ofs = q1_header->lumps[lump].fileofs;
-
- if (length % size) {
- Error ("LoadBSPFile: odd lump size");
- }
- // somehow things got out of range
- if ((length/size) > maxsize) {
- printf("WARNING: exceeded max size for lump %d size %d > maxsize %d\n", lump, (length/size), maxsize);
- length = maxsize * size;
- }
- if ( ofs + length > q1_fileLength ) {
- printf("WARNING: exceeded file length for lump %d\n", lump);
- length = q1_fileLength - ofs;
- if ( length <= 0 ) {
- return 0;
- }
- }
-
- memcpy (dest, (byte *)q1_header + ofs, length);
-
- return length / size;
-}
-
-/*
-=============
-Q1_LoadBSPFile
-=============
-*/
-void Q1_LoadBSPFile(char *filename, int offset, int length)
-{
- int i;
-
-//
-// load the file header
-//
- q1_fileLength = LoadFile(filename, (void **)&q1_header, offset, length);
-
-// swap the header
- for (i=0 ; i< sizeof(q1_dheader_t)/4 ; i++)
- ((int *)q1_header)[i] = LittleLong ( ((int *)q1_header)[i]);
-
- if (q1_header->version != Q1_BSPVERSION)
- Error ("%s is version %i, not %i", filename, i, Q1_BSPVERSION);
-
- q1_nummodels = Q1_CopyLump (Q1_LUMP_MODELS, q1_dmodels, sizeof(q1_dmodel_t), Q1_MAX_MAP_MODELS );
- q1_numvertexes = Q1_CopyLump (Q1_LUMP_VERTEXES, q1_dvertexes, sizeof(q1_dvertex_t), Q1_MAX_MAP_VERTS );
- q1_numplanes = Q1_CopyLump (Q1_LUMP_PLANES, q1_dplanes, sizeof(q1_dplane_t), Q1_MAX_MAP_PLANES );
- q1_numleafs = Q1_CopyLump (Q1_LUMP_LEAFS, q1_dleafs, sizeof(q1_dleaf_t), Q1_MAX_MAP_LEAFS );
- q1_numnodes = Q1_CopyLump (Q1_LUMP_NODES, q1_dnodes, sizeof(q1_dnode_t), Q1_MAX_MAP_NODES );
- q1_numtexinfo = Q1_CopyLump (Q1_LUMP_TEXINFO, q1_texinfo, sizeof(q1_texinfo_t), Q1_MAX_MAP_TEXINFO );
- q1_numclipnodes = Q1_CopyLump (Q1_LUMP_CLIPNODES, q1_dclipnodes, sizeof(q1_dclipnode_t), Q1_MAX_MAP_CLIPNODES );
- q1_numfaces = Q1_CopyLump (Q1_LUMP_FACES, q1_dfaces, sizeof(q1_dface_t), Q1_MAX_MAP_FACES );
- q1_nummarksurfaces = Q1_CopyLump (Q1_LUMP_MARKSURFACES, q1_dmarksurfaces, sizeof(q1_dmarksurfaces[0]), Q1_MAX_MAP_MARKSURFACES );
- q1_numsurfedges = Q1_CopyLump (Q1_LUMP_SURFEDGES, q1_dsurfedges, sizeof(q1_dsurfedges[0]), Q1_MAX_MAP_SURFEDGES );
- q1_numedges = Q1_CopyLump (Q1_LUMP_EDGES, q1_dedges, sizeof(q1_dedge_t), Q1_MAX_MAP_EDGES );
-
- q1_texdatasize = Q1_CopyLump (Q1_LUMP_TEXTURES, q1_dtexdata, 1, Q1_MAX_MAP_MIPTEX );
- q1_visdatasize = Q1_CopyLump (Q1_LUMP_VISIBILITY, q1_dvisdata, 1, Q1_MAX_MAP_VISIBILITY );
- q1_lightdatasize = Q1_CopyLump (Q1_LUMP_LIGHTING, q1_dlightdata, 1, Q1_MAX_MAP_LIGHTING );
- q1_entdatasize = Q1_CopyLump (Q1_LUMP_ENTITIES, q1_dentdata, 1, Q1_MAX_MAP_ENTSTRING );
-
- FreeMemory(q1_header); // everything has been copied out
-
-//
-// swap everything
-//
- Q1_SwapBSPFile (false);
-}
-
-//============================================================================
-
-FILE *q1_wadfile;
-q1_dheader_t q1_outheader;
-
-void Q1_AddLump (int lumpnum, void *data, int len)
-{
- q1_lump_t *lump;
-
- lump = &q1_header->lumps[lumpnum];
-
- lump->fileofs = LittleLong(ftell(q1_wadfile));
- lump->filelen = LittleLong(len);
- SafeWrite(q1_wadfile, data, (len+3)&~3);
-}
-
-/*
-=============
-Q1_WriteBSPFile
-
-Swaps the bsp file in place, so it should not be referenced again
-=============
-*/
-void Q1_WriteBSPFile (char *filename)
-{
- q1_header = &q1_outheader;
- memset (q1_header, 0, sizeof(q1_dheader_t));
-
- Q1_SwapBSPFile (true);
-
- q1_header->version = LittleLong (Q1_BSPVERSION);
-
- q1_wadfile = SafeOpenWrite (filename);
- SafeWrite (q1_wadfile, q1_header, sizeof(q1_dheader_t)); // overwritten later
-
- Q1_AddLump (Q1_LUMP_PLANES, q1_dplanes, q1_numplanes*sizeof(q1_dplane_t));
- Q1_AddLump (Q1_LUMP_LEAFS, q1_dleafs, q1_numleafs*sizeof(q1_dleaf_t));
- Q1_AddLump (Q1_LUMP_VERTEXES, q1_dvertexes, q1_numvertexes*sizeof(q1_dvertex_t));
- Q1_AddLump (Q1_LUMP_NODES, q1_dnodes, q1_numnodes*sizeof(q1_dnode_t));
- Q1_AddLump (Q1_LUMP_TEXINFO, q1_texinfo, q1_numtexinfo*sizeof(q1_texinfo_t));
- Q1_AddLump (Q1_LUMP_FACES, q1_dfaces, q1_numfaces*sizeof(q1_dface_t));
- Q1_AddLump (Q1_LUMP_CLIPNODES, q1_dclipnodes, q1_numclipnodes*sizeof(q1_dclipnode_t));
- Q1_AddLump (Q1_LUMP_MARKSURFACES, q1_dmarksurfaces, q1_nummarksurfaces*sizeof(q1_dmarksurfaces[0]));
- Q1_AddLump (Q1_LUMP_SURFEDGES, q1_dsurfedges, q1_numsurfedges*sizeof(q1_dsurfedges[0]));
- Q1_AddLump (Q1_LUMP_EDGES, q1_dedges, q1_numedges*sizeof(q1_dedge_t));
- Q1_AddLump (Q1_LUMP_MODELS, q1_dmodels, q1_nummodels*sizeof(q1_dmodel_t));
-
- Q1_AddLump (Q1_LUMP_LIGHTING, q1_dlightdata, q1_lightdatasize);
- Q1_AddLump (Q1_LUMP_VISIBILITY, q1_dvisdata, q1_visdatasize);
- Q1_AddLump (Q1_LUMP_ENTITIES, q1_dentdata, q1_entdatasize);
- Q1_AddLump (Q1_LUMP_TEXTURES, q1_dtexdata, q1_texdatasize);
-
- fseek (q1_wadfile, 0, SEEK_SET);
- SafeWrite (q1_wadfile, q1_header, sizeof(q1_dheader_t));
- fclose (q1_wadfile);
-}
-
-//============================================================================
-
-/*
-=============
-Q1_PrintBSPFileSizes
-
-Dumps info about current file
-=============
-*/
-void Q1_PrintBSPFileSizes (void)
-{
- printf ("%5i planes %6i\n"
- ,q1_numplanes, (int)(q1_numplanes*sizeof(q1_dplane_t)));
- printf ("%5i vertexes %6i\n"
- ,q1_numvertexes, (int)(q1_numvertexes*sizeof(q1_dvertex_t)));
- printf ("%5i nodes %6i\n"
- ,q1_numnodes, (int)(q1_numnodes*sizeof(q1_dnode_t)));
- printf ("%5i texinfo %6i\n"
- ,q1_numtexinfo, (int)(q1_numtexinfo*sizeof(q1_texinfo_t)));
- printf ("%5i faces %6i\n"
- ,q1_numfaces, (int)(q1_numfaces*sizeof(q1_dface_t)));
- printf ("%5i clipnodes %6i\n"
- ,q1_numclipnodes, (int)(q1_numclipnodes*sizeof(q1_dclipnode_t)));
- printf ("%5i leafs %6i\n"
- ,q1_numleafs, (int)(q1_numleafs*sizeof(q1_dleaf_t)));
- printf ("%5i marksurfaces %6i\n"
- ,q1_nummarksurfaces, (int)(q1_nummarksurfaces*sizeof(q1_dmarksurfaces[0])));
- printf ("%5i surfedges %6i\n"
- ,q1_numsurfedges, (int)(q1_numsurfedges*sizeof(q1_dmarksurfaces[0])));
- printf ("%5i edges %6i\n"
- ,q1_numedges, (int)(q1_numedges*sizeof(q1_dedge_t)));
- if (!q1_texdatasize)
- printf (" 0 textures 0\n");
- else
- printf ("%5i textures %6i\n",((q1_dmiptexlump_t*)q1_dtexdata)->nummiptex, q1_texdatasize);
- printf (" lightdata %6i\n", q1_lightdatasize);
- printf (" visdata %6i\n", q1_visdatasize);
- printf (" entdata %6i\n", q1_entdatasize);
-} //end of the function Q1_PrintBSPFileSizes
-
-
-/*
-================
-Q1_ParseEntities
-
-Parses the dentdata string into entities
-================
-*/
-void Q1_ParseEntities (void)
-{
- script_t *script;
-
- num_entities = 0;
- script = LoadScriptMemory(q1_dentdata, q1_entdatasize, "*Quake1 bsp file");
- SetScriptFlags(script, SCFL_NOSTRINGWHITESPACES |
- SCFL_NOSTRINGESCAPECHARS);
-
- while(ParseEntity(script))
- {
- } //end while
-
- FreeScript(script);
-} //end of the function Q1_ParseEntities
-
-
-/*
-================
-Q1_UnparseEntities
-
-Generates the dentdata string from all the entities
-================
-*/
-void Q1_UnparseEntities (void)
-{
- char *buf, *end;
- epair_t *ep;
- char line[2048];
- int i;
-
- buf = q1_dentdata;
- end = buf;
- *end = 0;
-
- for (i=0 ; i<num_entities ; i++)
- {
- ep = entities[i].epairs;
- if (!ep)
- continue; // ent got removed
-
- strcat (end,"{\n");
- end += 2;
-
- for (ep = entities[i].epairs ; ep ; ep=ep->next)
- {
- sprintf (line, "\"%s\" \"%s\"\n", ep->key, ep->value);
- strcat (end, line);
- end += strlen(line);
- }
- strcat (end,"}\n");
- end += 2;
-
- if (end > buf + Q1_MAX_MAP_ENTSTRING)
- Error ("Entity text too long");
- }
- q1_entdatasize = end - buf + 1;
-} //end of the function Q1_UnparseEntities
diff --git a/code/bspc/l_bsp_q1.h b/code/bspc/l_bsp_q1.h
deleted file mode 100644
index 81d87e5..0000000
--- a/code/bspc/l_bsp_q1.h
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-
-// upper design bounds
-
-#define Q1_MAX_MAP_HULLS 4
-
-#define Q1_MAX_MAP_MODELS 256
-#define Q1_MAX_MAP_BRUSHES 4096
-#define Q1_MAX_MAP_ENTITIES 1024
-#define Q1_MAX_MAP_ENTSTRING 65536
-
-#define Q1_MAX_MAP_PLANES 8192
-#define Q1_MAX_MAP_NODES 32767 // because negative shorts are contents
-#define Q1_MAX_MAP_CLIPNODES 32767 //
-#define Q1_MAX_MAP_LEAFS 32767 //
-#define Q1_MAX_MAP_VERTS 65535
-#define Q1_MAX_MAP_FACES 65535
-#define Q1_MAX_MAP_MARKSURFACES 65535
-#define Q1_MAX_MAP_TEXINFO 4096
-#define Q1_MAX_MAP_EDGES 256000
-#define Q1_MAX_MAP_SURFEDGES 512000
-#define Q1_MAX_MAP_MIPTEX 0x200000
-#define Q1_MAX_MAP_LIGHTING 0x100000
-#define Q1_MAX_MAP_VISIBILITY 0x100000
-
-// key / value pair sizes
-
-#define MAX_KEY 32
-#define MAX_VALUE 1024
-
-//=============================================================================
-
-
-#define Q1_BSPVERSION 29
-
-typedef struct
-{
- int fileofs, filelen;
-} q1_lump_t;
-
-#define Q1_LUMP_ENTITIES 0
-#define Q1_LUMP_PLANES 1
-#define Q1_LUMP_TEXTURES 2
-#define Q1_LUMP_VERTEXES 3
-#define Q1_LUMP_VISIBILITY 4
-#define Q1_LUMP_NODES 5
-#define Q1_LUMP_TEXINFO 6
-#define Q1_LUMP_FACES 7
-#define Q1_LUMP_LIGHTING 8
-#define Q1_LUMP_CLIPNODES 9
-#define Q1_LUMP_LEAFS 10
-#define Q1_LUMP_MARKSURFACES 11
-#define Q1_LUMP_EDGES 12
-#define Q1_LUMP_SURFEDGES 13
-#define Q1_LUMP_MODELS 14
-
-#define Q1_HEADER_LUMPS 15
-
-typedef struct
-{
- float mins[3], maxs[3];
- float origin[3];
- int headnode[Q1_MAX_MAP_HULLS];
- int visleafs; // not including the solid leaf 0
- int firstface, numfaces;
-} q1_dmodel_t;
-
-typedef struct
-{
- int version;
- q1_lump_t lumps[Q1_HEADER_LUMPS];
-} q1_dheader_t;
-
-typedef struct
-{
- int nummiptex;
- int dataofs[4]; // [nummiptex]
-} q1_dmiptexlump_t;
-
-#define MIPLEVELS 4
-typedef struct q1_miptex_s
-{
- char name[16];
- unsigned width, height;
- unsigned offsets[MIPLEVELS]; // four mip maps stored
-} q1_miptex_t;
-
-
-typedef struct
-{
- float point[3];
-} q1_dvertex_t;
-
-
-// 0-2 are axial planes
-#define PLANE_X 0
-#define PLANE_Y 1
-#define PLANE_Z 2
-
-// 3-5 are non-axial planes snapped to the nearest
-#define PLANE_ANYX 3
-#define PLANE_ANYY 4
-#define PLANE_ANYZ 5
-
-typedef struct
-{
- float normal[3];
- float dist;
- int type; // PLANE_X - PLANE_ANYZ ?remove? trivial to regenerate
-} q1_dplane_t;
-
-
-
-#define Q1_CONTENTS_EMPTY -1
-#define Q1_CONTENTS_SOLID -2
-#define Q1_CONTENTS_WATER -3
-#define Q1_CONTENTS_SLIME -4
-#define Q1_CONTENTS_LAVA -5
-#define Q1_CONTENTS_SKY -6
-
-// !!! if this is changed, it must be changed in asm_i386.h too !!!
-typedef struct
-{
- int planenum;
- short children[2]; // negative numbers are -(leafs+1), not nodes
- short mins[3]; // for sphere culling
- short maxs[3];
- unsigned short firstface;
- unsigned short numfaces; // counting both sides
-} q1_dnode_t;
-
-typedef struct
-{
- int planenum;
- short children[2]; // negative numbers are contents
-} q1_dclipnode_t;
-
-
-typedef struct q1_texinfo_s
-{
- float vecs[2][4]; // [s/t][xyz offset]
- int miptex;
- int flags;
-} q1_texinfo_t;
-#define TEX_SPECIAL 1 // sky or slime, no lightmap or 256 subdivision
-
-// note that edge 0 is never used, because negative edge nums are used for
-// counterclockwise use of the edge in a face
-typedef struct
-{
- unsigned short v[2]; // vertex numbers
-} q1_dedge_t;
-
-#define MAXLIGHTMAPS 4
-typedef struct
-{
- short planenum;
- short side;
-
- int firstedge; // we must support > 64k edges
- short numedges;
- short texinfo;
-
-// lighting info
- byte styles[MAXLIGHTMAPS];
- int lightofs; // start of [numstyles*surfsize] samples
-} q1_dface_t;
-
-
-
-#define AMBIENT_WATER 0
-#define AMBIENT_SKY 1
-#define AMBIENT_SLIME 2
-#define AMBIENT_LAVA 3
-
-#define NUM_AMBIENTS 4 // automatic ambient sounds
-
-// leaf 0 is the generic Q1_CONTENTS_SOLID leaf, used for all solid areas
-// all other leafs need visibility info
-typedef struct
-{
- int contents;
- int visofs; // -1 = no visibility info
-
- short mins[3]; // for frustum culling
- short maxs[3];
-
- unsigned short firstmarksurface;
- unsigned short nummarksurfaces;
-
- byte ambient_level[NUM_AMBIENTS];
-} q1_dleaf_t;
-
-//============================================================================
-
-#ifndef QUAKE_GAME
-
-// the utilities get to be lazy and just use large static arrays
-
-extern int q1_nummodels;
-extern q1_dmodel_t *q1_dmodels;//[MAX_MAP_MODELS];
-
-extern int q1_visdatasize;
-extern byte *q1_dvisdata;//[MAX_MAP_VISIBILITY];
-
-extern int q1_lightdatasize;
-extern byte *q1_dlightdata;//[MAX_MAP_LIGHTING];
-
-extern int q1_texdatasize;
-extern byte *q1_dtexdata;//[MAX_MAP_MIPTEX]; // (dmiptexlump_t)
-
-extern int q1_entdatasize;
-extern char *q1_dentdata;//[MAX_MAP_ENTSTRING];
-
-extern int q1_numleafs;
-extern q1_dleaf_t *q1_dleafs;//[MAX_MAP_LEAFS];
-
-extern int q1_numplanes;
-extern q1_dplane_t *q1_dplanes;//[MAX_MAP_PLANES];
-
-extern int q1_numvertexes;
-extern q1_dvertex_t *q1_dvertexes;//[MAX_MAP_VERTS];
-
-extern int q1_numnodes;
-extern q1_dnode_t *q1_dnodes;//[MAX_MAP_NODES];
-
-extern int q1_numtexinfo;
-extern q1_texinfo_t *q1_texinfo;//[MAX_MAP_TEXINFO];
-
-extern int q1_numfaces;
-extern q1_dface_t *q1_dfaces;//[MAX_MAP_FACES];
-
-extern int q1_numclipnodes;
-extern q1_dclipnode_t *q1_dclipnodes;//[MAX_MAP_CLIPNODES];
-
-extern int q1_numedges;
-extern q1_dedge_t *q1_dedges;//[MAX_MAP_EDGES];
-
-extern int q1_nummarksurfaces;
-extern unsigned short *q1_dmarksurfaces;//[MAX_MAP_MARKSURFACES];
-
-extern int q1_numsurfedges;
-extern int *q1_dsurfedges;//[MAX_MAP_SURFEDGES];
-
-
-void Q1_AllocMaxBSP(void);
-void Q1_FreeMaxBSP(void);
-void Q1_LoadBSPFile(char *filename, int offset, int length);
-void Q1_WriteBSPFile(char *filename);
-void Q1_PrintBSPFileSizes(void);
-void Q1_ParseEntities(void);
-void Q1_UnparseEntities(void);
-
-#endif
diff --git a/code/bspc/l_bsp_q2.c b/code/bspc/l_bsp_q2.c
deleted file mode 100644
index fe52bf1..0000000
--- a/code/bspc/l_bsp_q2.c
+++ /dev/null
@@ -1,1134 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-#include "l_cmd.h"
-#include "l_math.h"
-#include "l_mem.h"
-#include "l_log.h"
-#include "l_poly.h"
-#include "../botlib/l_script.h"
-#include "q2files.h"
-#include "l_bsp_q2.h"
-#include "l_bsp_ent.h"
-
-#define q2_dmodel_t dmodel_t
-#define q2_lump_t lump_t
-#define q2_dheader_t dheader_t
-#define q2_dmodel_t dmodel_t
-#define q2_dvertex_t dvertex_t
-#define q2_dplane_t dplane_t
-#define q2_dnode_t dnode_t
-#define q2_texinfo_t texinfo_t
-#define q2_dedge_t dedge_t
-#define q2_dface_t dface_t
-#define q2_dleaf_t dleaf_t
-#define q2_dbrushside_t dbrushside_t
-#define q2_dbrush_t dbrush_t
-#define q2_dvis_t dvis_t
-#define q2_dareaportal_t dareaportal_t
-#define q2_darea_t darea_t
-
-#define q2_nummodels nummodels
-#define q2_dmodels dmodels
-#define q2_numleafs numleafs
-#define q2_dleafs dleafs
-#define q2_numplanes numplanes
-#define q2_dplanes dplanes
-#define q2_numvertexes numvertexes
-#define q2_dvertexes dvertexes
-#define q2_numnodes numnodes
-#define q2_dnodes dnodes
-#define q2_numtexinfo numtexinfo
-#define q2_texinfo texinfo
-#define q2_numfaces numfaces
-#define q2_dfaces dfaces
-#define q2_numedges numedges
-#define q2_dedges dedges
-#define q2_numleaffaces numleaffaces
-#define q2_dleaffaces dleaffaces
-#define q2_numleafbrushes numleafbrushes
-#define q2_dleafbrushes dleafbrushes
-#define q2_dsurfedges dsurfedges
-#define q2_numbrushes numbrushes
-#define q2_dbrushes dbrushes
-#define q2_numbrushsides numbrushsides
-#define q2_dbrushsides dbrushsides
-#define q2_numareas numareas
-#define q2_dareas dareas
-#define q2_numareaportals numareaportals
-#define q2_dareaportals dareaportals
-
-void GetLeafNums (void);
-
-//=============================================================================
-
-int nummodels;
-dmodel_t *dmodels;//[MAX_MAP_MODELS];
-
-int visdatasize;
-byte *dvisdata;//[MAX_MAP_VISIBILITY];
-dvis_t *dvis;// = (dvis_t *)dvisdata;
-
-int lightdatasize;
-byte *dlightdata;//[MAX_MAP_LIGHTING];
-
-int entdatasize;
-char *dentdata;//[MAX_MAP_ENTSTRING];
-
-int numleafs;
-dleaf_t *dleafs;//[MAX_MAP_LEAFS];
-
-int numplanes;
-dplane_t *dplanes;//[MAX_MAP_PLANES];
-
-int numvertexes;
-dvertex_t *dvertexes;//[MAX_MAP_VERTS];
-
-int numnodes;
-dnode_t *dnodes;//[MAX_MAP_NODES];
-
-//NOTE: must be static for q2 .map to q2 .bsp
-int numtexinfo;
-texinfo_t texinfo[MAX_MAP_TEXINFO];
-
-int numfaces;
-dface_t *dfaces;//[MAX_MAP_FACES];
-
-int numedges;
-dedge_t *dedges;//[MAX_MAP_EDGES];
-
-int numleaffaces;
-unsigned short *dleaffaces;//[MAX_MAP_LEAFFACES];
-
-int numleafbrushes;
-unsigned short *dleafbrushes;//[MAX_MAP_LEAFBRUSHES];
-
-int numsurfedges;
-int *dsurfedges;//[MAX_MAP_SURFEDGES];
-
-int numbrushes;
-dbrush_t *dbrushes;//[MAX_MAP_BRUSHES];
-
-int numbrushsides;
-dbrushside_t *dbrushsides;//[MAX_MAP_BRUSHSIDES];
-
-int numareas;
-darea_t *dareas;//[MAX_MAP_AREAS];
-
-int numareaportals;
-dareaportal_t *dareaportals;//[MAX_MAP_AREAPORTALS];
-
-#define MAX_MAP_DPOP 256
-byte dpop[MAX_MAP_DPOP];
-
-//
-char brushsidetextured[MAX_MAP_BRUSHSIDES];
-
-//#ifdef ME
-
-int bspallocated = false;
-int allocatedbspmem = 0;
-
-void Q2_AllocMaxBSP(void)
-{
- //models
- nummodels = 0;
- dmodels = (dmodel_t *) GetClearedMemory(MAX_MAP_MODELS * sizeof(dmodel_t));
- allocatedbspmem += MAX_MAP_MODELS * sizeof(dmodel_t);
- //vis data
- visdatasize = 0;
- dvisdata = (byte *) GetClearedMemory(MAX_MAP_VISIBILITY * sizeof(byte));
- dvis = (dvis_t *) dvisdata;
- allocatedbspmem += MAX_MAP_VISIBILITY * sizeof(byte);
- //light data
- lightdatasize = 0;
- dlightdata = (byte *) GetClearedMemory(MAX_MAP_LIGHTING * sizeof(byte));
- allocatedbspmem += MAX_MAP_LIGHTING * sizeof(byte);
- //entity data
- entdatasize = 0;
- dentdata = (char *) GetClearedMemory(MAX_MAP_ENTSTRING * sizeof(char));
- allocatedbspmem += MAX_MAP_ENTSTRING * sizeof(char);
- //leafs
- numleafs = 0;
- dleafs = (dleaf_t *) GetClearedMemory(MAX_MAP_LEAFS * sizeof(dleaf_t));
- allocatedbspmem += MAX_MAP_LEAFS * sizeof(dleaf_t);
- //planes
- numplanes = 0;
- dplanes = (dplane_t *) GetClearedMemory(MAX_MAP_PLANES * sizeof(dplane_t));
- allocatedbspmem += MAX_MAP_PLANES * sizeof(dplane_t);
- //vertexes
- numvertexes = 0;
- dvertexes = (dvertex_t *) GetClearedMemory(MAX_MAP_VERTS * sizeof(dvertex_t));
- allocatedbspmem += MAX_MAP_VERTS * sizeof(dvertex_t);
- //nodes
- numnodes = 0;
- dnodes = (dnode_t *) GetClearedMemory(MAX_MAP_NODES * sizeof(dnode_t));
- allocatedbspmem += MAX_MAP_NODES * sizeof(dnode_t);
- /*
- //texture info
- numtexinfo = 0;
- texinfo = (texinfo_t *) GetClearedMemory(MAX_MAP_TEXINFO * sizeof(texinfo_t));
- allocatedbspmem += MAX_MAP_TEXINFO * sizeof(texinfo_t);
- //*/
- //faces
- numfaces = 0;
- dfaces = (dface_t *) GetClearedMemory(MAX_MAP_FACES * sizeof(dface_t));
- allocatedbspmem += MAX_MAP_FACES * sizeof(dface_t);
- //edges
- numedges = 0;
- dedges = (dedge_t *) GetClearedMemory(MAX_MAP_EDGES * sizeof(dedge_t));
- allocatedbspmem += MAX_MAP_EDGES * sizeof(dedge_t);
- //leaf faces
- numleaffaces = 0;
- dleaffaces = (unsigned short *) GetClearedMemory(MAX_MAP_LEAFFACES * sizeof(unsigned short));
- allocatedbspmem += MAX_MAP_LEAFFACES * sizeof(unsigned short);
- //leaf brushes
- numleafbrushes = 0;
- dleafbrushes = (unsigned short *) GetClearedMemory(MAX_MAP_LEAFBRUSHES * sizeof(unsigned short));
- allocatedbspmem += MAX_MAP_LEAFBRUSHES * sizeof(unsigned short);
- //surface edges
- numsurfedges = 0;
- dsurfedges = (int *) GetClearedMemory(MAX_MAP_SURFEDGES * sizeof(int));
- allocatedbspmem += MAX_MAP_SURFEDGES * sizeof(int);
- //brushes
- numbrushes = 0;
- dbrushes = (dbrush_t *) GetClearedMemory(MAX_MAP_BRUSHES * sizeof(dbrush_t));
- allocatedbspmem += MAX_MAP_BRUSHES * sizeof(dbrush_t);
- //brushsides
- numbrushsides = 0;
- dbrushsides = (dbrushside_t *) GetClearedMemory(MAX_MAP_BRUSHSIDES * sizeof(dbrushside_t));
- allocatedbspmem += MAX_MAP_BRUSHSIDES * sizeof(dbrushside_t);
- //areas
- numareas = 0;
- dareas = (darea_t *) GetClearedMemory(MAX_MAP_AREAS * sizeof(darea_t));
- allocatedbspmem += MAX_MAP_AREAS * sizeof(darea_t);
- //area portals
- numareaportals = 0;
- dareaportals = (dareaportal_t *) GetClearedMemory(MAX_MAP_AREAPORTALS * sizeof(dareaportal_t));
- allocatedbspmem += MAX_MAP_AREAPORTALS * sizeof(dareaportal_t);
- //print allocated memory
- Log_Print("allocated ");
- PrintMemorySize(allocatedbspmem);
- Log_Print(" of BSP memory\n");
-} //end of the function Q2_AllocMaxBSP
-
-void Q2_FreeMaxBSP(void)
-{
- //models
- nummodels = 0;
- FreeMemory(dmodels);
- dmodels = NULL;
- //vis data
- visdatasize = 0;
- FreeMemory(dvisdata);
- dvisdata = NULL;
- dvis = NULL;
- //light data
- lightdatasize = 0;
- FreeMemory(dlightdata);
- dlightdata = NULL;
- //entity data
- entdatasize = 0;
- FreeMemory(dentdata);
- dentdata = NULL;
- //leafs
- numleafs = 0;
- FreeMemory(dleafs);
- dleafs = NULL;
- //planes
- numplanes = 0;
- FreeMemory(dplanes);
- dplanes = NULL;
- //vertexes
- numvertexes = 0;
- FreeMemory(dvertexes);
- dvertexes = NULL;
- //nodes
- numnodes = 0;
- FreeMemory(dnodes);
- dnodes = NULL;
- /*
- //texture info
- numtexinfo = 0;
- FreeMemory(texinfo);
- texinfo = NULL;
- //*/
- //faces
- numfaces = 0;
- FreeMemory(dfaces);
- dfaces = NULL;
- //edges
- numedges = 0;
- FreeMemory(dedges);
- dedges = NULL;
- //leaf faces
- numleaffaces = 0;
- FreeMemory(dleaffaces);
- dleaffaces = NULL;
- //leaf brushes
- numleafbrushes = 0;
- FreeMemory(dleafbrushes);
- dleafbrushes = NULL;
- //surface edges
- numsurfedges = 0;
- FreeMemory(dsurfedges);
- dsurfedges = NULL;
- //brushes
- numbrushes = 0;
- FreeMemory(dbrushes);
- dbrushes = NULL;
- //brushsides
- numbrushsides = 0;
- FreeMemory(dbrushsides);
- dbrushsides = NULL;
- //areas
- numareas = 0;
- FreeMemory(dareas);
- dareas = NULL;
- //area portals
- numareaportals = 0;
- FreeMemory(dareaportals);
- dareaportals = NULL;
- //
- Log_Print("freed ");
- PrintMemorySize(allocatedbspmem);
- Log_Print(" of BSP memory\n");
- allocatedbspmem = 0;
-} //end of the function Q2_FreeMaxBSP
-
-#define WCONVEX_EPSILON 0.5
-
-int InsideWinding(winding_t *w, vec3_t point, int planenum)
-{
- int i;
- float dist;
- vec_t *v1, *v2;
- vec3_t normal, edgevec;
- dplane_t *plane;
-
- for (i = 1; i <= w->numpoints; i++)
- {
- v1 = w->p[i % w->numpoints];
- v2 = w->p[(i + 1) % w->numpoints];
-
- VectorSubtract(v2, v1, edgevec);
- plane = &dplanes[planenum];
- CrossProduct(plane->normal, edgevec, normal);
- VectorNormalize(normal);
- dist = DotProduct(normal, v1);
- //
- if (DotProduct(normal, point) - dist > WCONVEX_EPSILON) return false;
- } //end for
- return true;
-} //end of the function InsideWinding
-
-int InsideFace(dface_t *face, vec3_t point)
-{
- int i, edgenum, side;
- float dist;
- vec_t *v1, *v2;
- vec3_t normal, edgevec;
- dplane_t *plane;
-
- for (i = 0; i < face->numedges; i++)
- {
- //get the first and second vertex of the edge
- edgenum = dsurfedges[face->firstedge + i];
- side = edgenum < 0;
- v1 = dvertexes[dedges[abs(edgenum)].v[side]].point;
- v2 = dvertexes[dedges[abs(edgenum)].v[!side]].point;
- //create a plane through the edge vector, orthogonal to the face plane
- //and with the normal vector pointing out of the face
- VectorSubtract(v1, v2, edgevec);
- plane = &dplanes[face->planenum];
- CrossProduct(plane->normal, edgevec, normal);
- VectorNormalize(normal);
- dist = DotProduct(normal, v1);
- //
- if (DotProduct(normal, point) - dist > WCONVEX_EPSILON) return false;
- } //end for
- return true;
-} //end of the function InsideFace
-//===========================================================================
-// returns the amount the face and the winding overlap
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-float Q2_FaceOnWinding(q2_dface_t *face, winding_t *winding)
-{
- int i, edgenum, side;
- float dist, area;
- q2_dplane_t plane;
- vec_t *v1, *v2;
- vec3_t normal, edgevec;
- winding_t *w;
-
- //
- w = CopyWinding(winding);
- memcpy(&plane, &q2_dplanes[face->planenum], sizeof(q2_dplane_t));
- //check on which side of the plane the face is
- if (face->side)
- {
- VectorNegate(plane.normal, plane.normal);
- plane.dist = -plane.dist;
- } //end if
- for (i = 0; i < face->numedges && w; i++)
- {
- //get the first and second vertex of the edge
- edgenum = q2_dsurfedges[face->firstedge + i];
- side = edgenum > 0;
- //if the face plane is flipped
- v1 = q2_dvertexes[q2_dedges[abs(edgenum)].v[side]].point;
- v2 = q2_dvertexes[q2_dedges[abs(edgenum)].v[!side]].point;
- //create a plane through the edge vector, orthogonal to the face plane
- //and with the normal vector pointing inward
- VectorSubtract(v1, v2, edgevec);
- CrossProduct(edgevec, plane.normal, normal);
- VectorNormalize(normal);
- dist = DotProduct(normal, v1);
- //
- ChopWindingInPlace(&w, normal, dist, -0.1); //CLIP_EPSILON
- } //end for
- if (w)
- {
- area = WindingArea(w);
- FreeWinding(w);
- return area;
- } //end if
- return 0;
-} //end of the function Q2_FaceOnWinding
-//===========================================================================
-// creates a winding for the given brush side on the given brush
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-winding_t *Q2_BrushSideWinding(dbrush_t *brush, dbrushside_t *baseside)
-{
- int i;
- dplane_t *baseplane, *plane;
- winding_t *w;
- dbrushside_t *side;
-
- //create a winding for the brush side with the given planenumber
- baseplane = &dplanes[baseside->planenum];
- w = BaseWindingForPlane(baseplane->normal, baseplane->dist);
- for (i = 0; i < brush->numsides && w; i++)
- {
- side = &dbrushsides[brush->firstside + i];
- //don't chop with the base plane
- if (side->planenum == baseside->planenum) continue;
- //also don't use planes that are almost equal
- plane = &dplanes[side->planenum];
- if (DotProduct(baseplane->normal, plane->normal) > 0.999
- && fabs(baseplane->dist - plane->dist) < 0.01) continue;
- //
- plane = &dplanes[side->planenum^1];
- ChopWindingInPlace(&w, plane->normal, plane->dist, -0.1); //CLIP_EPSILON);
- } //end for
- return w;
-} //end of the function Q2_BrushSideWinding
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int Q2_HintSkipBrush(dbrush_t *brush)
-{
- int j;
- dbrushside_t *brushside;
-
- for (j = 0; j < brush->numsides; j++)
- {
- brushside = &dbrushsides[brush->firstside + j];
- if (brushside->texinfo > 0)
- {
- if (texinfo[brushside->texinfo].flags & (SURF_SKIP|SURF_HINT))
- {
- return true;
- } //end if
- } //end if
- } //end for
- return false;
-} //end of the function Q2_HintSkipBrush
-//===========================================================================
-// fix screwed brush texture references
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-qboolean WindingIsTiny(winding_t *w);
-
-void Q2_FixTextureReferences(void)
-{
- int i, j, k, we;
- dbrushside_t *brushside;
- dbrush_t *brush;
- dface_t *face;
- winding_t *w;
-
- memset(brushsidetextured, false, MAX_MAP_BRUSHSIDES);
- //go over all the brushes
- for (i = 0; i < numbrushes; i++)
- {
- brush = &dbrushes[i];
- //hint brushes are not textured
- if (Q2_HintSkipBrush(brush)) continue;
- //go over all the sides of the brush
- for (j = 0; j < brush->numsides; j++)
- {
- brushside = &dbrushsides[brush->firstside + j];
- //
- w = Q2_BrushSideWinding(brush, brushside);
- if (!w)
- {
- brushsidetextured[brush->firstside + j] = true;
- continue;
- } //end if
- else
- {
- //RemoveEqualPoints(w, 0.2);
- if (WindingIsTiny(w))
- {
- FreeWinding(w);
- brushsidetextured[brush->firstside + j] = true;
- continue;
- } //end if
- else
- {
- we = WindingError(w);
- if (we == WE_NOTENOUGHPOINTS
- || we == WE_SMALLAREA
- || we == WE_POINTBOGUSRANGE
-// || we == WE_NONCONVEX
- )
- {
- FreeWinding(w);
- brushsidetextured[brush->firstside + j] = true;
- continue;
- } //end if
- } //end else
- } //end else
- if (WindingArea(w) < 20)
- {
- brushsidetextured[brush->firstside + j] = true;
- } //end if
- //find a face for texturing this brush
- for (k = 0; k < numfaces; k++)
- {
- face = &dfaces[k];
- //if the face is in the same plane as the brush side
- if ((face->planenum&~1) != (brushside->planenum&~1)) continue;
- //if the face is partly or totally on the brush side
- if (Q2_FaceOnWinding(face, w))
- {
- brushside->texinfo = face->texinfo;
- brushsidetextured[brush->firstside + j] = true;
- break;
- } //end if
- } //end for
- FreeWinding(w);
- } //end for
- } //end for
-} //end of the function Q2_FixTextureReferences*/
-
-//#endif //ME
-
-
-/*
-===============
-CompressVis
-
-===============
-*/
-int Q2_CompressVis (byte *vis, byte *dest)
-{
- int j;
- int rep;
- int visrow;
- byte *dest_p;
-
- dest_p = dest;
-// visrow = (r_numvisleafs + 7)>>3;
- visrow = (dvis->numclusters + 7)>>3;
-
- for (j=0 ; j<visrow ; j++)
- {
- *dest_p++ = vis[j];
- if (vis[j])
- continue;
-
- rep = 1;
- for ( j++; j<visrow ; j++)
- if (vis[j] || rep == 255)
- break;
- else
- rep++;
- *dest_p++ = rep;
- j--;
- }
-
- return dest_p - dest;
-}
-
-
-/*
-===================
-DecompressVis
-===================
-*/
-void Q2_DecompressVis (byte *in, byte *decompressed)
-{
- int c;
- byte *out;
- int row;
-
-// row = (r_numvisleafs+7)>>3;
- row = (dvis->numclusters+7)>>3;
- out = decompressed;
-
- do
- {
- if (*in)
- {
- *out++ = *in++;
- continue;
- }
-
- c = in[1];
- if (!c)
- Error ("DecompressVis: 0 repeat");
- in += 2;
- while (c)
- {
- *out++ = 0;
- c--;
- }
- } while (out - decompressed < row);
-}
-
-//=============================================================================
-
-/*
-=============
-SwapBSPFile
-
-Byte swaps all data in a bsp file.
-=============
-*/
-void Q2_SwapBSPFile (qboolean todisk)
-{
- int i, j;
- dmodel_t *d;
-
-
-// models
- for (i=0 ; i<nummodels ; i++)
- {
- d = &dmodels[i];
-
- d->firstface = LittleLong (d->firstface);
- d->numfaces = LittleLong (d->numfaces);
- d->headnode = LittleLong (d->headnode);
-
- for (j=0 ; j<3 ; j++)
- {
- d->mins[j] = LittleFloat(d->mins[j]);
- d->maxs[j] = LittleFloat(d->maxs[j]);
- d->origin[j] = LittleFloat(d->origin[j]);
- }
- }
-
-//
-// vertexes
-//
- for (i=0 ; i<numvertexes ; i++)
- {
- for (j=0 ; j<3 ; j++)
- dvertexes[i].point[j] = LittleFloat (dvertexes[i].point[j]);
- }
-
-//
-// planes
-//
- for (i=0 ; i<numplanes ; i++)
- {
- for (j=0 ; j<3 ; j++)
- dplanes[i].normal[j] = LittleFloat (dplanes[i].normal[j]);
- dplanes[i].dist = LittleFloat (dplanes[i].dist);
- dplanes[i].type = LittleLong (dplanes[i].type);
- }
-
-//
-// texinfos
-//
- for (i=0 ; i<numtexinfo ; i++)
- {
- for (j=0 ; j<8 ; j++)
- texinfo[i].vecs[0][j] = LittleFloat (texinfo[i].vecs[0][j]);
- texinfo[i].flags = LittleLong (texinfo[i].flags);
- texinfo[i].value = LittleLong (texinfo[i].value);
- texinfo[i].nexttexinfo = LittleLong (texinfo[i].nexttexinfo);
- }
-
-//
-// faces
-//
- for (i=0 ; i<numfaces ; i++)
- {
- dfaces[i].texinfo = LittleShort (dfaces[i].texinfo);
- dfaces[i].planenum = LittleShort (dfaces[i].planenum);
- dfaces[i].side = LittleShort (dfaces[i].side);
- dfaces[i].lightofs = LittleLong (dfaces[i].lightofs);
- dfaces[i].firstedge = LittleLong (dfaces[i].firstedge);
- dfaces[i].numedges = LittleShort (dfaces[i].numedges);
- }
-
-//
-// nodes
-//
- for (i=0 ; i<numnodes ; i++)
- {
- dnodes[i].planenum = LittleLong (dnodes[i].planenum);
- for (j=0 ; j<3 ; j++)
- {
- dnodes[i].mins[j] = LittleShort (dnodes[i].mins[j]);
- dnodes[i].maxs[j] = LittleShort (dnodes[i].maxs[j]);
- }
- dnodes[i].children[0] = LittleLong (dnodes[i].children[0]);
- dnodes[i].children[1] = LittleLong (dnodes[i].children[1]);
- dnodes[i].firstface = LittleShort (dnodes[i].firstface);
- dnodes[i].numfaces = LittleShort (dnodes[i].numfaces);
- }
-
-//
-// leafs
-//
- for (i=0 ; i<numleafs ; i++)
- {
- dleafs[i].contents = LittleLong (dleafs[i].contents);
- dleafs[i].cluster = LittleShort (dleafs[i].cluster);
- dleafs[i].area = LittleShort (dleafs[i].area);
- for (j=0 ; j<3 ; j++)
- {
- dleafs[i].mins[j] = LittleShort (dleafs[i].mins[j]);
- dleafs[i].maxs[j] = LittleShort (dleafs[i].maxs[j]);
- }
-
- dleafs[i].firstleafface = LittleShort (dleafs[i].firstleafface);
- dleafs[i].numleaffaces = LittleShort (dleafs[i].numleaffaces);
- dleafs[i].firstleafbrush = LittleShort (dleafs[i].firstleafbrush);
- dleafs[i].numleafbrushes = LittleShort (dleafs[i].numleafbrushes);
- }
-
-//
-// leaffaces
-//
- for (i=0 ; i<numleaffaces ; i++)
- dleaffaces[i] = LittleShort (dleaffaces[i]);
-
-//
-// leafbrushes
-//
- for (i=0 ; i<numleafbrushes ; i++)
- dleafbrushes[i] = LittleShort (dleafbrushes[i]);
-
-//
-// surfedges
-//
- for (i=0 ; i<numsurfedges ; i++)
- dsurfedges[i] = LittleLong (dsurfedges[i]);
-
-//
-// edges
-//
- for (i=0 ; i<numedges ; i++)
- {
- dedges[i].v[0] = LittleShort (dedges[i].v[0]);
- dedges[i].v[1] = LittleShort (dedges[i].v[1]);
- }
-
-//
-// brushes
-//
- for (i=0 ; i<numbrushes ; i++)
- {
- dbrushes[i].firstside = LittleLong (dbrushes[i].firstside);
- dbrushes[i].numsides = LittleLong (dbrushes[i].numsides);
- dbrushes[i].contents = LittleLong (dbrushes[i].contents);
- }
-
-//
-// areas
-//
- for (i=0 ; i<numareas ; i++)
- {
- dareas[i].numareaportals = LittleLong (dareas[i].numareaportals);
- dareas[i].firstareaportal = LittleLong (dareas[i].firstareaportal);
- }
-
-//
-// areasportals
-//
- for (i=0 ; i<numareaportals ; i++)
- {
- dareaportals[i].portalnum = LittleLong (dareaportals[i].portalnum);
- dareaportals[i].otherarea = LittleLong (dareaportals[i].otherarea);
- }
-
-//
-// brushsides
-//
- for (i=0 ; i<numbrushsides ; i++)
- {
- dbrushsides[i].planenum = LittleShort (dbrushsides[i].planenum);
- dbrushsides[i].texinfo = LittleShort (dbrushsides[i].texinfo);
- }
-
-//
-// visibility
-//
- if (todisk)
- j = dvis->numclusters;
- else
- j = LittleLong(dvis->numclusters);
- dvis->numclusters = LittleLong (dvis->numclusters);
- for (i=0 ; i<j ; i++)
- {
- dvis->bitofs[i][0] = LittleLong (dvis->bitofs[i][0]);
- dvis->bitofs[i][1] = LittleLong (dvis->bitofs[i][1]);
- }
-} //end of the function Q2_SwapBSPFile
-
-
-dheader_t *header;
-
-int Q2_CopyLump (int lump, void *dest, int size, int maxsize)
-{
- int length, ofs;
-
- length = header->lumps[lump].filelen;
- ofs = header->lumps[lump].fileofs;
-
- if (length % size)
- Error ("LoadBSPFile: odd lump size");
-
- if ((length/size) > maxsize)
- Error ("Q2_LoadBSPFile: exceeded max size for lump %d size %d > maxsize %d\n", lump, (length/size), maxsize);
-
- memcpy (dest, (byte *)header + ofs, length);
-
- return length / size;
-} //end of the function Q2_CopyLump
-
-/*
-=============
-LoadBSPFile
-=============
-*/
-void Q2_LoadBSPFile(char *filename, int offset, int length)
-{
- int i;
-
-//
-// load the file header
-//
- LoadFile (filename, (void **)&header, offset, length);
-
-// swap the header
- for (i=0 ; i< sizeof(dheader_t)/4 ; i++)
- ((int *)header)[i] = LittleLong ( ((int *)header)[i]);
-
- if (header->ident != IDBSPHEADER)
- Error ("%s is not a IBSP file", filename);
- if (header->version != BSPVERSION)
- Error ("%s is version %i, not %i", filename, header->version, BSPVERSION);
-
- nummodels = Q2_CopyLump (LUMP_MODELS, dmodels, sizeof(dmodel_t), MAX_MAP_MODELS);
- numvertexes = Q2_CopyLump (LUMP_VERTEXES, dvertexes, sizeof(dvertex_t), MAX_MAP_VERTS);
- numplanes = Q2_CopyLump (LUMP_PLANES, dplanes, sizeof(dplane_t), MAX_MAP_PLANES);
- numleafs = Q2_CopyLump (LUMP_LEAFS, dleafs, sizeof(dleaf_t), MAX_MAP_LEAFS);
- numnodes = Q2_CopyLump (LUMP_NODES, dnodes, sizeof(dnode_t), MAX_MAP_NODES);
- numtexinfo = Q2_CopyLump (LUMP_TEXINFO, texinfo, sizeof(texinfo_t), MAX_MAP_TEXINFO);
- numfaces = Q2_CopyLump (LUMP_FACES, dfaces, sizeof(dface_t), MAX_MAP_FACES);
- numleaffaces = Q2_CopyLump (LUMP_LEAFFACES, dleaffaces, sizeof(dleaffaces[0]), MAX_MAP_LEAFFACES);
- numleafbrushes = Q2_CopyLump (LUMP_LEAFBRUSHES, dleafbrushes, sizeof(dleafbrushes[0]), MAX_MAP_LEAFBRUSHES);
- numsurfedges = Q2_CopyLump (LUMP_SURFEDGES, dsurfedges, sizeof(dsurfedges[0]), MAX_MAP_SURFEDGES);
- numedges = Q2_CopyLump (LUMP_EDGES, dedges, sizeof(dedge_t), MAX_MAP_EDGES);
- numbrushes = Q2_CopyLump (LUMP_BRUSHES, dbrushes, sizeof(dbrush_t), MAX_MAP_BRUSHES);
- numbrushsides = Q2_CopyLump (LUMP_BRUSHSIDES, dbrushsides, sizeof(dbrushside_t), MAX_MAP_BRUSHSIDES);
- numareas = Q2_CopyLump (LUMP_AREAS, dareas, sizeof(darea_t), MAX_MAP_AREAS);
- numareaportals = Q2_CopyLump (LUMP_AREAPORTALS, dareaportals, sizeof(dareaportal_t), MAX_MAP_AREAPORTALS);
-
- visdatasize = Q2_CopyLump (LUMP_VISIBILITY, dvisdata, 1, MAX_MAP_VISIBILITY);
- lightdatasize = Q2_CopyLump (LUMP_LIGHTING, dlightdata, 1, MAX_MAP_LIGHTING);
- entdatasize = Q2_CopyLump (LUMP_ENTITIES, dentdata, 1, MAX_MAP_ENTSTRING);
-
- Q2_CopyLump (LUMP_POP, dpop, 1, MAX_MAP_DPOP);
-
- FreeMemory(header); // everything has been copied out
-
-//
-// swap everything
-//
- Q2_SwapBSPFile (false);
-
- Q2_FixTextureReferences();
-} //end of the function Q2_LoadBSPFile
-
-
-/*
-=============
-LoadBSPFileTexinfo
-
-Only loads the texinfo lump, so qdata can scan for textures
-=============
-*/
-void Q2_LoadBSPFileTexinfo (char *filename)
-{
- int i;
- FILE *f;
- int length, ofs;
-
- header = GetMemory(sizeof(dheader_t));
-
- f = fopen (filename, "rb");
- fread (header, sizeof(dheader_t), 1, f);
-
-// swap the header
- for (i=0 ; i< sizeof(dheader_t)/4 ; i++)
- ((int *)header)[i] = LittleLong ( ((int *)header)[i]);
-
- if (header->ident != IDBSPHEADER)
- Error ("%s is not a IBSP file", filename);
- if (header->version != BSPVERSION)
- Error ("%s is version %i, not %i", filename, header->version, BSPVERSION);
-
-
- length = header->lumps[LUMP_TEXINFO].filelen;
- ofs = header->lumps[LUMP_TEXINFO].fileofs;
-
- fseek (f, ofs, SEEK_SET);
- fread (texinfo, length, 1, f);
- fclose (f);
-
- numtexinfo = length / sizeof(texinfo_t);
-
- FreeMemory(header); // everything has been copied out
-
- Q2_SwapBSPFile (false);
-} //end of the function Q2_LoadBSPFileTexinfo
-
-
-//============================================================================
-
-FILE *wadfile;
-dheader_t outheader;
-
-void Q2_AddLump (int lumpnum, void *data, int len)
-{
- lump_t *lump;
-
- lump = &header->lumps[lumpnum];
-
- lump->fileofs = LittleLong( ftell(wadfile) );
- lump->filelen = LittleLong(len);
- SafeWrite (wadfile, data, (len+3)&~3);
-} //end of the function Q2_AddLump
-
-/*
-=============
-WriteBSPFile
-
-Swaps the bsp file in place, so it should not be referenced again
-=============
-*/
-void Q2_WriteBSPFile (char *filename)
-{
- header = &outheader;
- memset (header, 0, sizeof(dheader_t));
-
- Q2_SwapBSPFile (true);
-
- header->ident = LittleLong (IDBSPHEADER);
- header->version = LittleLong (BSPVERSION);
-
- wadfile = SafeOpenWrite (filename);
- SafeWrite (wadfile, header, sizeof(dheader_t)); // overwritten later
-
- Q2_AddLump (LUMP_PLANES, dplanes, numplanes*sizeof(dplane_t));
- Q2_AddLump (LUMP_LEAFS, dleafs, numleafs*sizeof(dleaf_t));
- Q2_AddLump (LUMP_VERTEXES, dvertexes, numvertexes*sizeof(dvertex_t));
- Q2_AddLump (LUMP_NODES, dnodes, numnodes*sizeof(dnode_t));
- Q2_AddLump (LUMP_TEXINFO, texinfo, numtexinfo*sizeof(texinfo_t));
- Q2_AddLump (LUMP_FACES, dfaces, numfaces*sizeof(dface_t));
- Q2_AddLump (LUMP_BRUSHES, dbrushes, numbrushes*sizeof(dbrush_t));
- Q2_AddLump (LUMP_BRUSHSIDES, dbrushsides, numbrushsides*sizeof(dbrushside_t));
- Q2_AddLump (LUMP_LEAFFACES, dleaffaces, numleaffaces*sizeof(dleaffaces[0]));
- Q2_AddLump (LUMP_LEAFBRUSHES, dleafbrushes, numleafbrushes*sizeof(dleafbrushes[0]));
- Q2_AddLump (LUMP_SURFEDGES, dsurfedges, numsurfedges*sizeof(dsurfedges[0]));
- Q2_AddLump (LUMP_EDGES, dedges, numedges*sizeof(dedge_t));
- Q2_AddLump (LUMP_MODELS, dmodels, nummodels*sizeof(dmodel_t));
- Q2_AddLump (LUMP_AREAS, dareas, numareas*sizeof(darea_t));
- Q2_AddLump (LUMP_AREAPORTALS, dareaportals, numareaportals*sizeof(dareaportal_t));
-
- Q2_AddLump (LUMP_LIGHTING, dlightdata, lightdatasize);
- Q2_AddLump (LUMP_VISIBILITY, dvisdata, visdatasize);
- Q2_AddLump (LUMP_ENTITIES, dentdata, entdatasize);
- Q2_AddLump (LUMP_POP, dpop, sizeof(dpop));
-
- fseek (wadfile, 0, SEEK_SET);
- SafeWrite (wadfile, header, sizeof(dheader_t));
- fclose (wadfile);
-} //end of the function Q2_WriteBSPFile
-
-//============================================================================
-
-/*
-=============
-PrintBSPFileSizes
-
-Dumps info about current file
-=============
-*/
-void Q2_PrintBSPFileSizes (void)
-{
- if (!num_entities)
- Q2_ParseEntities();
-
- printf ("%6i models %7i\n"
- ,nummodels, (int)(nummodels*sizeof(dmodel_t)));
- printf ("%6i brushes %7i\n"
- ,numbrushes, (int)(numbrushes*sizeof(dbrush_t)));
- printf ("%6i brushsides %7i\n"
- ,numbrushsides, (int)(numbrushsides*sizeof(dbrushside_t)));
- printf ("%6i planes %7i\n"
- ,numplanes, (int)(numplanes*sizeof(dplane_t)));
- printf ("%6i texinfo %7i\n"
- ,numtexinfo, (int)(numtexinfo*sizeof(texinfo_t)));
- printf ("%6i entdata %7i\n", num_entities, entdatasize);
-
- printf ("\n");
-
- printf ("%6i vertexes %7i\n"
- ,numvertexes, (int)(numvertexes*sizeof(dvertex_t)));
- printf ("%6i nodes %7i\n"
- ,numnodes, (int)(numnodes*sizeof(dnode_t)));
- printf ("%6i faces %7i\n"
- ,numfaces, (int)(numfaces*sizeof(dface_t)));
- printf ("%6i leafs %7i\n"
- ,numleafs, (int)(numleafs*sizeof(dleaf_t)));
- printf ("%6i leaffaces %7i\n"
- ,numleaffaces, (int)(numleaffaces*sizeof(dleaffaces[0])));
- printf ("%6i leafbrushes %7i\n"
- ,numleafbrushes, (int)(numleafbrushes*sizeof(dleafbrushes[0])));
- printf ("%6i surfedges %7i\n"
- ,numsurfedges, (int)(numsurfedges*sizeof(dsurfedges[0])));
- printf ("%6i edges %7i\n"
- ,numedges, (int)(numedges*sizeof(dedge_t)));
-//NEW
- printf ("%6i areas %7i\n"
- ,numareas, (int)(numareas*sizeof(darea_t)));
- printf ("%6i areaportals %7i\n"
- ,numareaportals, (int)(numareaportals*sizeof(dareaportal_t)));
-//ENDNEW
- printf (" lightdata %7i\n", lightdatasize);
- printf (" visdata %7i\n", visdatasize);
-} //end of the function Q2_PrintBSPFileSizes
-
-/*
-================
-ParseEntities
-
-Parses the dentdata string into entities
-================
-*/
-void Q2_ParseEntities (void)
-{
- script_t *script;
-
- num_entities = 0;
- script = LoadScriptMemory(dentdata, entdatasize, "*Quake2 bsp file");
- SetScriptFlags(script, SCFL_NOSTRINGWHITESPACES |
- SCFL_NOSTRINGESCAPECHARS);
-
- while(ParseEntity(script))
- {
- } //end while
-
- FreeScript(script);
-} //end of the function Q2_ParseEntities
-
-
-/*
-================
-UnparseEntities
-
-Generates the dentdata string from all the entities
-================
-*/
-void Q2_UnparseEntities (void)
-{
- char *buf, *end;
- epair_t *ep;
- char line[2048];
- int i;
- char key[1024], value[1024];
-
- buf = dentdata;
- end = buf;
- *end = 0;
-
- for (i=0 ; i<num_entities ; i++)
- {
- ep = entities[i].epairs;
- if (!ep)
- continue; // ent got removed
-
- strcat (end,"{\n");
- end += 2;
-
- for (ep = entities[i].epairs ; ep ; ep=ep->next)
- {
- strcpy (key, ep->key);
- StripTrailing (key);
- strcpy (value, ep->value);
- StripTrailing (value);
-
- sprintf (line, "\"%s\" \"%s\"\n", key, value);
- strcat (end, line);
- end += strlen(line);
- }
- strcat (end,"}\n");
- end += 2;
-
- if (end > buf + MAX_MAP_ENTSTRING)
- Error ("Entity text too long");
- }
- entdatasize = end - buf + 1;
-} //end of the function Q2_UnparseEntities
-
diff --git a/code/bspc/l_bsp_q2.h b/code/bspc/l_bsp_q2.h
deleted file mode 100644
index 6692b0d..0000000
--- a/code/bspc/l_bsp_q2.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-#ifndef ME
-#define ME
-#endif //ME
-
-extern int nummodels;
-extern dmodel_t *dmodels;//[MAX_MAP_MODELS];
-
-extern int visdatasize;
-extern byte *dvisdata;//[MAX_MAP_VISIBILITY];
-extern dvis_t *dvis;
-
-extern int lightdatasize;
-extern byte *dlightdata;//[MAX_MAP_LIGHTING];
-
-extern int entdatasize;
-extern char *dentdata;//[MAX_MAP_ENTSTRING];
-
-extern int numleafs;
-extern dleaf_t *dleafs;//[MAX_MAP_LEAFS];
-
-extern int numplanes;
-extern dplane_t *dplanes;//[MAX_MAP_PLANES];
-
-extern int numvertexes;
-extern dvertex_t *dvertexes;//[MAX_MAP_VERTS];
-
-extern int numnodes;
-extern dnode_t *dnodes;//[MAX_MAP_NODES];
-
-extern int numtexinfo;
-extern texinfo_t texinfo[MAX_MAP_TEXINFO];
-
-extern int numfaces;
-extern dface_t *dfaces;//[MAX_MAP_FACES];
-
-extern int numedges;
-extern dedge_t *dedges;//[MAX_MAP_EDGES];
-
-extern int numleaffaces;
-extern unsigned short *dleaffaces;//[MAX_MAP_LEAFFACES];
-
-extern int numleafbrushes;
-extern unsigned short *dleafbrushes;//[MAX_MAP_LEAFBRUSHES];
-
-extern int numsurfedges;
-extern int *dsurfedges;//[MAX_MAP_SURFEDGES];
-
-extern int numareas;
-extern darea_t *dareas;//[MAX_MAP_AREAS];
-
-extern int numareaportals;
-extern dareaportal_t *dareaportals;//[MAX_MAP_AREAPORTALS];
-
-extern int numbrushes;
-extern dbrush_t *dbrushes;//[MAX_MAP_BRUSHES];
-
-extern int numbrushsides;
-extern dbrushside_t *dbrushsides;//[MAX_MAP_BRUSHSIDES];
-
-extern byte dpop[256];
-
-extern char brushsidetextured[MAX_MAP_BRUSHSIDES];
-
-void Q2_AllocMaxBSP(void);
-void Q2_FreeMaxBSP(void);
-
-void Q2_DecompressVis(byte *in, byte *decompressed);
-int Q2_CompressVis(byte *vis, byte *dest);
-
-void Q2_LoadBSPFile(char *filename, int offset, int length);
-void Q2_LoadBSPFileTexinfo(char *filename); // just for qdata
-void Q2_WriteBSPFile(char *filename);
-void Q2_PrintBSPFileSizes(void);
-void Q2_ParseEntities(void);
-void Q2_UnparseEntities(void);
-
diff --git a/code/bspc/l_bsp_q3.c b/code/bspc/l_bsp_q3.c
deleted file mode 100644
index a2bfe4a..0000000
--- a/code/bspc/l_bsp_q3.c
+++ /dev/null
@@ -1,824 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-#include "l_cmd.h"
-#include "l_math.h"
-#include "l_mem.h"
-#include "l_log.h"
-#include "l_poly.h"
-#include "../botlib/l_script.h"
-#include "l_qfiles.h"
-#include "l_bsp_q3.h"
-#include "l_bsp_ent.h"
-
-void Q3_ParseEntities (void);
-void Q3_PrintBSPFileSizes(void);
-
-void GetLeafNums (void);
-
-//=============================================================================
-
-#define WCONVEX_EPSILON 0.5
-
-
-int q3_nummodels;
-q3_dmodel_t *q3_dmodels;//[MAX_MAP_MODELS];
-
-int q3_numShaders;
-q3_dshader_t *q3_dshaders;//[Q3_MAX_MAP_SHADERS];
-
-int q3_entdatasize;
-char *q3_dentdata;//[Q3_MAX_MAP_ENTSTRING];
-
-int q3_numleafs;
-q3_dleaf_t *q3_dleafs;//[Q3_MAX_MAP_LEAFS];
-
-int q3_numplanes;
-q3_dplane_t *q3_dplanes;//[Q3_MAX_MAP_PLANES];
-
-int q3_numnodes;
-q3_dnode_t *q3_dnodes;//[Q3_MAX_MAP_NODES];
-
-int q3_numleafsurfaces;
-int *q3_dleafsurfaces;//[Q3_MAX_MAP_LEAFFACES];
-
-int q3_numleafbrushes;
-int *q3_dleafbrushes;//[Q3_MAX_MAP_LEAFBRUSHES];
-
-int q3_numbrushes;
-q3_dbrush_t *q3_dbrushes;//[Q3_MAX_MAP_BRUSHES];
-
-int q3_numbrushsides;
-q3_dbrushside_t *q3_dbrushsides;//[Q3_MAX_MAP_BRUSHSIDES];
-
-int q3_numLightBytes;
-byte *q3_lightBytes;//[Q3_MAX_MAP_LIGHTING];
-
-int q3_numGridPoints;
-byte *q3_gridData;//[Q3_MAX_MAP_LIGHTGRID];
-
-int q3_numVisBytes;
-byte *q3_visBytes;//[Q3_MAX_MAP_VISIBILITY];
-
-int q3_numDrawVerts;
-q3_drawVert_t *q3_drawVerts;//[Q3_MAX_MAP_DRAW_VERTS];
-
-int q3_numDrawIndexes;
-int *q3_drawIndexes;//[Q3_MAX_MAP_DRAW_INDEXES];
-
-int q3_numDrawSurfaces;
-q3_dsurface_t *q3_drawSurfaces;//[Q3_MAX_MAP_DRAW_SURFS];
-
-int q3_numFogs;
-q3_dfog_t *q3_dfogs;//[Q3_MAX_MAP_FOGS];
-
-char q3_dbrushsidetextured[Q3_MAX_MAP_BRUSHSIDES];
-
-extern qboolean forcesidesvisible;
-
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void Q3_FreeMaxBSP(void)
-{
- if (q3_dmodels) FreeMemory(q3_dmodels);
- q3_dmodels = NULL;
- q3_nummodels = 0;
- if (q3_dshaders) FreeMemory(q3_dshaders);
- q3_dshaders = NULL;
- q3_numShaders = 0;
- if (q3_dentdata) FreeMemory(q3_dentdata);
- q3_dentdata = NULL;
- q3_entdatasize = 0;
- if (q3_dleafs) FreeMemory(q3_dleafs);
- q3_dleafs = NULL;
- q3_numleafs = 0;
- if (q3_dplanes) FreeMemory(q3_dplanes);
- q3_dplanes = NULL;
- q3_numplanes = 0;
- if (q3_dnodes) FreeMemory(q3_dnodes);
- q3_dnodes = NULL;
- q3_numnodes = 0;
- if (q3_dleafsurfaces) FreeMemory(q3_dleafsurfaces);
- q3_dleafsurfaces = NULL;
- q3_numleafsurfaces = 0;
- if (q3_dleafbrushes) FreeMemory(q3_dleafbrushes);
- q3_dleafbrushes = NULL;
- q3_numleafbrushes = 0;
- if (q3_dbrushes) FreeMemory(q3_dbrushes);
- q3_dbrushes = NULL;
- q3_numbrushes = 0;
- if (q3_dbrushsides) FreeMemory(q3_dbrushsides);
- q3_dbrushsides = NULL;
- q3_numbrushsides = 0;
- if (q3_lightBytes) FreeMemory(q3_lightBytes);
- q3_lightBytes = NULL;
- q3_numLightBytes = 0;
- if (q3_gridData) FreeMemory(q3_gridData);
- q3_gridData = NULL;
- q3_numGridPoints = 0;
- if (q3_visBytes) FreeMemory(q3_visBytes);
- q3_visBytes = NULL;
- q3_numVisBytes = 0;
- if (q3_drawVerts) FreeMemory(q3_drawVerts);
- q3_drawVerts = NULL;
- q3_numDrawVerts = 0;
- if (q3_drawIndexes) FreeMemory(q3_drawIndexes);
- q3_drawIndexes = NULL;
- q3_numDrawIndexes = 0;
- if (q3_drawSurfaces) FreeMemory(q3_drawSurfaces);
- q3_drawSurfaces = NULL;
- q3_numDrawSurfaces = 0;
- if (q3_dfogs) FreeMemory(q3_dfogs);
- q3_dfogs = NULL;
- q3_numFogs = 0;
-} //end of the function Q3_FreeMaxBSP
-
-
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void Q3_PlaneFromPoints(vec3_t p0, vec3_t p1, vec3_t p2, vec3_t normal, float *dist)
-{
- vec3_t t1, t2;
-
- VectorSubtract(p0, p1, t1);
- VectorSubtract(p2, p1, t2);
- CrossProduct(t1, t2, normal);
- VectorNormalize(normal);
-
- *dist = DotProduct(p0, normal);
-} //end of the function PlaneFromPoints
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void Q3_SurfacePlane(q3_dsurface_t *surface, vec3_t normal, float *dist)
-{
- int i;
- float *p0, *p1, *p2;
- vec3_t t1, t2;
-
- p0 = q3_drawVerts[surface->firstVert].xyz;
- for (i = 1; i < surface->numVerts-1; i++)
- {
- p1 = q3_drawVerts[surface->firstVert + ((i) % surface->numVerts)].xyz;
- p2 = q3_drawVerts[surface->firstVert + ((i+1) % surface->numVerts)].xyz;
- VectorSubtract(p0, p1, t1);
- VectorSubtract(p2, p1, t2);
- CrossProduct(t1, t2, normal);
- VectorNormalize(normal);
- if (VectorLength(normal)) break;
- } //end for*/
-/*
- float dot;
- for (i = 0; i < surface->numVerts; i++)
- {
- p0 = q3_drawVerts[surface->firstVert + ((i) % surface->numVerts)].xyz;
- p1 = q3_drawVerts[surface->firstVert + ((i+1) % surface->numVerts)].xyz;
- p2 = q3_drawVerts[surface->firstVert + ((i+2) % surface->numVerts)].xyz;
- VectorSubtract(p0, p1, t1);
- VectorSubtract(p2, p1, t2);
- VectorNormalize(t1);
- VectorNormalize(t2);
- dot = DotProduct(t1, t2);
- if (dot > -0.9 && dot < 0.9 &&
- VectorLength(t1) > 0.1 && VectorLength(t2) > 0.1) break;
- } //end for
- CrossProduct(t1, t2, normal);
- VectorNormalize(normal);
-*/
- if (VectorLength(normal) < 0.9)
- {
- printf("surface %d bogus normal vector %f %f %f\n", surface - q3_drawSurfaces, normal[0], normal[1], normal[2]);
- printf("t1 = %f %f %f, t2 = %f %f %f\n", t1[0], t1[1], t1[2], t2[0], t2[1], t2[2]);
- for (i = 0; i < surface->numVerts; i++)
- {
- p1 = q3_drawVerts[surface->firstVert + ((i) % surface->numVerts)].xyz;
- Log_Print("p%d = %f %f %f\n", i, p1[0], p1[1], p1[2]);
- } //end for
- } //end if
- *dist = DotProduct(p0, normal);
-} //end of the function Q3_SurfacePlane
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-q3_dplane_t *q3_surfaceplanes;
-
-void Q3_CreatePlanarSurfacePlanes(void)
-{
- int i;
- q3_dsurface_t *surface;
-
- Log_Print("creating planar surface planes...\n");
- q3_surfaceplanes = (q3_dplane_t *) GetClearedMemory(q3_numDrawSurfaces * sizeof(q3_dplane_t));
-
- for (i = 0; i < q3_numDrawSurfaces; i++)
- {
- surface = &q3_drawSurfaces[i];
- if (surface->surfaceType != MST_PLANAR) continue;
- Q3_SurfacePlane(surface, q3_surfaceplanes[i].normal, &q3_surfaceplanes[i].dist);
- //Log_Print("normal = %f %f %f, dist = %f\n", q3_surfaceplanes[i].normal[0],
- // q3_surfaceplanes[i].normal[1],
- // q3_surfaceplanes[i].normal[2], q3_surfaceplanes[i].dist);
- } //end for
-} //end of the function Q3_CreatePlanarSurfacePlanes
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-/*
-void Q3_SurfacePlane(q3_dsurface_t *surface, vec3_t normal, float *dist)
-{
- //take the plane information from the lightmap vector
- //VectorCopy(surface->lightmapVecs[2], normal);
- //calculate plane dist with first surface vertex
- //*dist = DotProduct(q3_drawVerts[surface->firstVert].xyz, normal);
- Q3_PlaneFromPoints(q3_drawVerts[surface->firstVert].xyz,
- q3_drawVerts[surface->firstVert+1].xyz,
- q3_drawVerts[surface->firstVert+2].xyz, normal, dist);
-} //end of the function Q3_SurfacePlane*/
-//===========================================================================
-// returns the amount the face and the winding overlap
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-float Q3_FaceOnWinding(q3_dsurface_t *surface, winding_t *winding)
-{
- int i;
- float dist, area;
- q3_dplane_t plane;
- vec_t *v1, *v2;
- vec3_t normal, edgevec;
- winding_t *w;
-
- //copy the winding before chopping
- w = CopyWinding(winding);
- //retrieve the surface plane
- Q3_SurfacePlane(surface, plane.normal, &plane.dist);
- //chop the winding with the surface edge planes
- for (i = 0; i < surface->numVerts && w; i++)
- {
- v1 = q3_drawVerts[surface->firstVert + ((i) % surface->numVerts)].xyz;
- v2 = q3_drawVerts[surface->firstVert + ((i+1) % surface->numVerts)].xyz;
- //create a plane through the edge from v1 to v2, orthogonal to the
- //surface plane and with the normal vector pointing inward
- VectorSubtract(v2, v1, edgevec);
- CrossProduct(edgevec, plane.normal, normal);
- VectorNormalize(normal);
- dist = DotProduct(normal, v1);
- //
- ChopWindingInPlace(&w, normal, dist, -0.1); //CLIP_EPSILON
- } //end for
- if (w)
- {
- area = WindingArea(w);
- FreeWinding(w);
- return area;
- } //end if
- return 0;
-} //end of the function Q3_FaceOnWinding
-//===========================================================================
-// creates a winding for the given brush side on the given brush
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-winding_t *Q3_BrushSideWinding(q3_dbrush_t *brush, q3_dbrushside_t *baseside)
-{
- int i;
- q3_dplane_t *baseplane, *plane;
- winding_t *w;
- q3_dbrushside_t *side;
-
- //create a winding for the brush side with the given planenumber
- baseplane = &q3_dplanes[baseside->planeNum];
- w = BaseWindingForPlane(baseplane->normal, baseplane->dist);
- for (i = 0; i < brush->numSides && w; i++)
- {
- side = &q3_dbrushsides[brush->firstSide + i];
- //don't chop with the base plane
- if (side->planeNum == baseside->planeNum) continue;
- //also don't use planes that are almost equal
- plane = &q3_dplanes[side->planeNum];
- if (DotProduct(baseplane->normal, plane->normal) > 0.999
- && fabs(baseplane->dist - plane->dist) < 0.01) continue;
- //
- plane = &q3_dplanes[side->planeNum^1];
- ChopWindingInPlace(&w, plane->normal, plane->dist, -0.1); //CLIP_EPSILON);
- } //end for
- return w;
-} //end of the function Q3_BrushSideWinding
-//===========================================================================
-// fix screwed brush texture references
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-qboolean WindingIsTiny(winding_t *w);
-
-void Q3_FindVisibleBrushSides(void)
-{
- int i, j, k, we, numtextured, numsides;
- float dot;
- q3_dplane_t *plane;
- q3_dbrushside_t *brushside;
- q3_dbrush_t *brush;
- q3_dsurface_t *surface;
- winding_t *w;
-
- memset(q3_dbrushsidetextured, false, Q3_MAX_MAP_BRUSHSIDES);
- //
- numsides = 0;
- //create planes for the planar surfaces
- Q3_CreatePlanarSurfacePlanes();
- Log_Print("searching visible brush sides...\n");
- Log_Print("%6d brush sides", numsides);
- //go over all the brushes
- for (i = 0; i < q3_numbrushes; i++)
- {
- brush = &q3_dbrushes[i];
- //go over all the sides of the brush
- for (j = 0; j < brush->numSides; j++)
- {
- qprintf("\r%6d", numsides++);
- brushside = &q3_dbrushsides[brush->firstSide + j];
- //
- w = Q3_BrushSideWinding(brush, brushside);
- if (!w)
- {
- q3_dbrushsidetextured[brush->firstSide + j] = true;
- continue;
- } //end if
- else
- {
- //RemoveEqualPoints(w, 0.2);
- if (WindingIsTiny(w))
- {
- FreeWinding(w);
- q3_dbrushsidetextured[brush->firstSide + j] = true;
- continue;
- } //end if
- else
- {
- we = WindingError(w);
- if (we == WE_NOTENOUGHPOINTS
- || we == WE_SMALLAREA
- || we == WE_POINTBOGUSRANGE
-// || we == WE_NONCONVEX
- )
- {
- FreeWinding(w);
- q3_dbrushsidetextured[brush->firstSide + j] = true;
- continue;
- } //end if
- } //end else
- } //end else
- if (WindingArea(w) < 20)
- {
- q3_dbrushsidetextured[brush->firstSide + j] = true;
- continue;
- } //end if
- //find a face for texturing this brush
- for (k = 0; k < q3_numDrawSurfaces; k++)
- {
- surface = &q3_drawSurfaces[k];
- if (surface->surfaceType != MST_PLANAR) continue;
- //
- //Q3_SurfacePlane(surface, plane.normal, &plane.dist);
- plane = &q3_surfaceplanes[k];
- //the surface plane and the brush side plane should be pretty much the same
- if (fabs(fabs(plane->dist) - fabs(q3_dplanes[brushside->planeNum].dist)) > 5) continue;
- dot = DotProduct(plane->normal, q3_dplanes[brushside->planeNum].normal);
- if (dot > -0.9 && dot < 0.9) continue;
- //if the face is partly or totally on the brush side
- if (Q3_FaceOnWinding(surface, w))
- {
- q3_dbrushsidetextured[brush->firstSide + j] = true;
- //Log_Write("Q3_FaceOnWinding");
- break;
- } //end if
- } //end for
- FreeWinding(w);
- } //end for
- } //end for
- qprintf("\r%6d brush sides\n", numsides);
- numtextured = 0;
- for (i = 0; i < q3_numbrushsides; i++)
- {
- if (forcesidesvisible) q3_dbrushsidetextured[i] = true;
- if (q3_dbrushsidetextured[i]) numtextured++;
- } //end for
- Log_Print("%d brush sides textured out of %d\n", numtextured, q3_numbrushsides);
-} //end of the function Q3_FindVisibleBrushSides
-
-/*
-=============
-Q3_SwapBlock
-
-If all values are 32 bits, this can be used to swap everything
-=============
-*/
-void Q3_SwapBlock( int *block, int sizeOfBlock ) {
- int i;
-
- sizeOfBlock >>= 2;
- for ( i = 0 ; i < sizeOfBlock ; i++ ) {
- block[i] = LittleLong( block[i] );
- }
-} //end of the function Q3_SwapBlock
-
-/*
-=============
-Q3_SwapBSPFile
-
-Byte swaps all data in a bsp file.
-=============
-*/
-void Q3_SwapBSPFile( void ) {
- int i;
-
- // models
- Q3_SwapBlock( (int *)q3_dmodels, q3_nummodels * sizeof( q3_dmodels[0] ) );
-
- // shaders (don't swap the name)
- for ( i = 0 ; i < q3_numShaders ; i++ ) {
- q3_dshaders[i].contentFlags = LittleLong( q3_dshaders[i].contentFlags );
- q3_dshaders[i].surfaceFlags = LittleLong( q3_dshaders[i].surfaceFlags );
- }
-
- // planes
- Q3_SwapBlock( (int *)q3_dplanes, q3_numplanes * sizeof( q3_dplanes[0] ) );
-
- // nodes
- Q3_SwapBlock( (int *)q3_dnodes, q3_numnodes * sizeof( q3_dnodes[0] ) );
-
- // leafs
- Q3_SwapBlock( (int *)q3_dleafs, q3_numleafs * sizeof( q3_dleafs[0] ) );
-
- // leaffaces
- Q3_SwapBlock( (int *)q3_dleafsurfaces, q3_numleafsurfaces * sizeof( q3_dleafsurfaces[0] ) );
-
- // leafbrushes
- Q3_SwapBlock( (int *)q3_dleafbrushes, q3_numleafbrushes * sizeof( q3_dleafbrushes[0] ) );
-
- // brushes
- Q3_SwapBlock( (int *)q3_dbrushes, q3_numbrushes * sizeof( q3_dbrushes[0] ) );
-
- // brushsides
- Q3_SwapBlock( (int *)q3_dbrushsides, q3_numbrushsides * sizeof( q3_dbrushsides[0] ) );
-
- // vis
- ((int *)&q3_visBytes)[0] = LittleLong( ((int *)&q3_visBytes)[0] );
- ((int *)&q3_visBytes)[1] = LittleLong( ((int *)&q3_visBytes)[1] );
-
- // drawverts (don't swap colors )
- for ( i = 0 ; i < q3_numDrawVerts ; i++ ) {
- q3_drawVerts[i].lightmap[0] = LittleFloat( q3_drawVerts[i].lightmap[0] );
- q3_drawVerts[i].lightmap[1] = LittleFloat( q3_drawVerts[i].lightmap[1] );
- q3_drawVerts[i].st[0] = LittleFloat( q3_drawVerts[i].st[0] );
- q3_drawVerts[i].st[1] = LittleFloat( q3_drawVerts[i].st[1] );
- q3_drawVerts[i].xyz[0] = LittleFloat( q3_drawVerts[i].xyz[0] );
- q3_drawVerts[i].xyz[1] = LittleFloat( q3_drawVerts[i].xyz[1] );
- q3_drawVerts[i].xyz[2] = LittleFloat( q3_drawVerts[i].xyz[2] );
- q3_drawVerts[i].normal[0] = LittleFloat( q3_drawVerts[i].normal[0] );
- q3_drawVerts[i].normal[1] = LittleFloat( q3_drawVerts[i].normal[1] );
- q3_drawVerts[i].normal[2] = LittleFloat( q3_drawVerts[i].normal[2] );
- }
-
- // drawindexes
- Q3_SwapBlock( (int *)q3_drawIndexes, q3_numDrawIndexes * sizeof( q3_drawIndexes[0] ) );
-
- // drawsurfs
- Q3_SwapBlock( (int *)q3_drawSurfaces, q3_numDrawSurfaces * sizeof( q3_drawSurfaces[0] ) );
-
- // fogs
- for ( i = 0 ; i < q3_numFogs ; i++ ) {
- q3_dfogs[i].brushNum = LittleLong( q3_dfogs[i].brushNum );
- }
-}
-
-
-
-/*
-=============
-Q3_CopyLump
-=============
-*/
-int Q3_CopyLump( q3_dheader_t *header, int lump, void **dest, int size ) {
- int length, ofs;
-
- length = header->lumps[lump].filelen;
- ofs = header->lumps[lump].fileofs;
-
- if ( length % size ) {
- Error ("Q3_LoadBSPFile: odd lump size");
- }
-
- *dest = GetMemory(length);
-
- memcpy( *dest, (byte *)header + ofs, length );
-
- return length / size;
-}
-
-/*
-=============
-CountTriangles
-=============
-*/
-void CountTriangles( void ) {
- int i, numTris, numPatchTris;
- q3_dsurface_t *surface;
-
- numTris = numPatchTris = 0;
- for ( i = 0; i < q3_numDrawSurfaces; i++ ) {
- surface = &q3_drawSurfaces[i];
-
- numTris += surface->numIndexes / 3;
-
- if ( surface->patchWidth ) {
- numPatchTris += surface->patchWidth * surface->patchHeight * 2;
- }
- }
-
- Log_Print( "%6d triangles\n", numTris );
- Log_Print( "%6d patch tris\n", numPatchTris );
-}
-
-/*
-=============
-Q3_LoadBSPFile
-=============
-*/
-void Q3_LoadBSPFile(struct quakefile_s *qf)
-{
- q3_dheader_t *header;
-
- // load the file header
- //LoadFile(filename, (void **)&header, offset, length);
- //
- LoadQuakeFile(qf, (void **)&header);
-
- // swap the header
- Q3_SwapBlock( (int *)header, sizeof(*header) );
-
- if ( header->ident != Q3_BSP_IDENT ) {
- Error( "%s is not a IBSP file", qf->filename );
- }
- if ( header->version != Q3_BSP_VERSION ) {
- Error( "%s is version %i, not %i", qf->filename, header->version, Q3_BSP_VERSION );
- }
-
- q3_numShaders = Q3_CopyLump( header, Q3_LUMP_SHADERS, (void *) &q3_dshaders, sizeof(q3_dshader_t) );
- q3_nummodels = Q3_CopyLump( header, Q3_LUMP_MODELS, (void *) &q3_dmodels, sizeof(q3_dmodel_t) );
- q3_numplanes = Q3_CopyLump( header, Q3_LUMP_PLANES, (void *) &q3_dplanes, sizeof(q3_dplane_t) );
- q3_numleafs = Q3_CopyLump( header, Q3_LUMP_LEAFS, (void *) &q3_dleafs, sizeof(q3_dleaf_t) );
- q3_numnodes = Q3_CopyLump( header, Q3_LUMP_NODES, (void *) &q3_dnodes, sizeof(q3_dnode_t) );
- q3_numleafsurfaces = Q3_CopyLump( header, Q3_LUMP_LEAFSURFACES, (void *) &q3_dleafsurfaces, sizeof(q3_dleafsurfaces[0]) );
- q3_numleafbrushes = Q3_CopyLump( header, Q3_LUMP_LEAFBRUSHES, (void *) &q3_dleafbrushes, sizeof(q3_dleafbrushes[0]) );
- q3_numbrushes = Q3_CopyLump( header, Q3_LUMP_BRUSHES, (void *) &q3_dbrushes, sizeof(q3_dbrush_t) );
- q3_numbrushsides = Q3_CopyLump( header, Q3_LUMP_BRUSHSIDES, (void *) &q3_dbrushsides, sizeof(q3_dbrushside_t) );
- q3_numDrawVerts = Q3_CopyLump( header, Q3_LUMP_DRAWVERTS, (void *) &q3_drawVerts, sizeof(q3_drawVert_t) );
- q3_numDrawSurfaces = Q3_CopyLump( header, Q3_LUMP_SURFACES, (void *) &q3_drawSurfaces, sizeof(q3_dsurface_t) );
- q3_numFogs = Q3_CopyLump( header, Q3_LUMP_FOGS, (void *) &q3_dfogs, sizeof(q3_dfog_t) );
- q3_numDrawIndexes = Q3_CopyLump( header, Q3_LUMP_DRAWINDEXES, (void *) &q3_drawIndexes, sizeof(q3_drawIndexes[0]) );
-
- q3_numVisBytes = Q3_CopyLump( header, Q3_LUMP_VISIBILITY, (void *) &q3_visBytes, 1 );
- q3_numLightBytes = Q3_CopyLump( header, Q3_LUMP_LIGHTMAPS, (void *) &q3_lightBytes, 1 );
- q3_entdatasize = Q3_CopyLump( header, Q3_LUMP_ENTITIES, (void *) &q3_dentdata, 1);
-
- q3_numGridPoints = Q3_CopyLump( header, Q3_LUMP_LIGHTGRID, (void *) &q3_gridData, 8 );
-
- CountTriangles();
-
- FreeMemory( header ); // everything has been copied out
-
- // swap everything
- Q3_SwapBSPFile();
-
- Q3_FindVisibleBrushSides();
-
- //Q3_PrintBSPFileSizes();
-}
-
-
-//============================================================================
-
-/*
-=============
-Q3_AddLump
-=============
-*/
-void Q3_AddLump( FILE *bspfile, q3_dheader_t *header, int lumpnum, void *data, int len ) {
- q3_lump_t *lump;
-
- lump = &header->lumps[lumpnum];
-
- lump->fileofs = LittleLong( ftell(bspfile) );
- lump->filelen = LittleLong( len );
- SafeWrite( bspfile, data, (len+3)&~3 );
-}
-
-/*
-=============
-Q3_WriteBSPFile
-
-Swaps the bsp file in place, so it should not be referenced again
-=============
-*/
-void Q3_WriteBSPFile( char *filename )
-{
- q3_dheader_t outheader, *header;
- FILE *bspfile;
-
- header = &outheader;
- memset( header, 0, sizeof(q3_dheader_t) );
-
- Q3_SwapBSPFile();
-
- header->ident = LittleLong( Q3_BSP_IDENT );
- header->version = LittleLong( Q3_BSP_VERSION );
-
- bspfile = SafeOpenWrite( filename );
- SafeWrite( bspfile, header, sizeof(q3_dheader_t) ); // overwritten later
-
- Q3_AddLump( bspfile, header, Q3_LUMP_SHADERS, q3_dshaders, q3_numShaders*sizeof(q3_dshader_t) );
- Q3_AddLump( bspfile, header, Q3_LUMP_PLANES, q3_dplanes, q3_numplanes*sizeof(q3_dplane_t) );
- Q3_AddLump( bspfile, header, Q3_LUMP_LEAFS, q3_dleafs, q3_numleafs*sizeof(q3_dleaf_t) );
- Q3_AddLump( bspfile, header, Q3_LUMP_NODES, q3_dnodes, q3_numnodes*sizeof(q3_dnode_t) );
- Q3_AddLump( bspfile, header, Q3_LUMP_BRUSHES, q3_dbrushes, q3_numbrushes*sizeof(q3_dbrush_t) );
- Q3_AddLump( bspfile, header, Q3_LUMP_BRUSHSIDES, q3_dbrushsides, q3_numbrushsides*sizeof(q3_dbrushside_t) );
- Q3_AddLump( bspfile, header, Q3_LUMP_LEAFSURFACES, q3_dleafsurfaces, q3_numleafsurfaces*sizeof(q3_dleafsurfaces[0]) );
- Q3_AddLump( bspfile, header, Q3_LUMP_LEAFBRUSHES, q3_dleafbrushes, q3_numleafbrushes*sizeof(q3_dleafbrushes[0]) );
- Q3_AddLump( bspfile, header, Q3_LUMP_MODELS, q3_dmodels, q3_nummodels*sizeof(q3_dmodel_t) );
- Q3_AddLump( bspfile, header, Q3_LUMP_DRAWVERTS, q3_drawVerts, q3_numDrawVerts*sizeof(q3_drawVert_t) );
- Q3_AddLump( bspfile, header, Q3_LUMP_SURFACES, q3_drawSurfaces, q3_numDrawSurfaces*sizeof(q3_dsurface_t) );
- Q3_AddLump( bspfile, header, Q3_LUMP_VISIBILITY, q3_visBytes, q3_numVisBytes );
- Q3_AddLump( bspfile, header, Q3_LUMP_LIGHTMAPS, q3_lightBytes, q3_numLightBytes );
- Q3_AddLump( bspfile, header, Q3_LUMP_LIGHTGRID, q3_gridData, 8 * q3_numGridPoints );
- Q3_AddLump( bspfile, header, Q3_LUMP_ENTITIES, q3_dentdata, q3_entdatasize );
- Q3_AddLump( bspfile, header, Q3_LUMP_FOGS, q3_dfogs, q3_numFogs * sizeof(q3_dfog_t) );
- Q3_AddLump( bspfile, header, Q3_LUMP_DRAWINDEXES, q3_drawIndexes, q3_numDrawIndexes * sizeof(q3_drawIndexes[0]) );
-
- fseek (bspfile, 0, SEEK_SET);
- SafeWrite (bspfile, header, sizeof(q3_dheader_t));
- fclose (bspfile);
-}
-
-//============================================================================
-
-/*
-=============
-Q3_PrintBSPFileSizes
-
-Dumps info about current file
-=============
-*/
-void Q3_PrintBSPFileSizes( void )
-{
- if ( !num_entities )
- {
- Q3_ParseEntities();
- }
-
- Log_Print ("%6i models %7i\n"
- ,q3_nummodels, (int)(q3_nummodels*sizeof(q3_dmodel_t)));
- Log_Print ("%6i shaders %7i\n"
- ,q3_numShaders, (int)(q3_numShaders*sizeof(q3_dshader_t)));
- Log_Print ("%6i brushes %7i\n"
- ,q3_numbrushes, (int)(q3_numbrushes*sizeof(q3_dbrush_t)));
- Log_Print ("%6i brushsides %7i\n"
- ,q3_numbrushsides, (int)(q3_numbrushsides*sizeof(q3_dbrushside_t)));
- Log_Print ("%6i fogs %7i\n"
- ,q3_numFogs, (int)(q3_numFogs*sizeof(q3_dfog_t)));
- Log_Print ("%6i planes %7i\n"
- ,q3_numplanes, (int)(q3_numplanes*sizeof(q3_dplane_t)));
- Log_Print ("%6i entdata %7i\n", num_entities, q3_entdatasize);
-
- Log_Print ("\n");
-
- Log_Print ("%6i nodes %7i\n"
- ,q3_numnodes, (int)(q3_numnodes*sizeof(q3_dnode_t)));
- Log_Print ("%6i leafs %7i\n"
- ,q3_numleafs, (int)(q3_numleafs*sizeof(q3_dleaf_t)));
- Log_Print ("%6i leafsurfaces %7i\n"
- ,q3_numleafsurfaces, (int)(q3_numleafsurfaces*sizeof(q3_dleafsurfaces[0])));
- Log_Print ("%6i leafbrushes %7i\n"
- ,q3_numleafbrushes, (int)(q3_numleafbrushes*sizeof(q3_dleafbrushes[0])));
- Log_Print ("%6i drawverts %7i\n"
- ,q3_numDrawVerts, (int)(q3_numDrawVerts*sizeof(q3_drawVerts[0])));
- Log_Print ("%6i drawindexes %7i\n"
- ,q3_numDrawIndexes, (int)(q3_numDrawIndexes*sizeof(q3_drawIndexes[0])));
- Log_Print ("%6i drawsurfaces %7i\n"
- ,q3_numDrawSurfaces, (int)(q3_numDrawSurfaces*sizeof(q3_drawSurfaces[0])));
-
- Log_Print ("%6i lightmaps %7i\n"
- ,q3_numLightBytes / (LIGHTMAP_WIDTH*LIGHTMAP_HEIGHT*3), q3_numLightBytes );
- Log_Print (" visibility %7i\n"
- , q3_numVisBytes );
-}
-
-/*
-================
-Q3_ParseEntities
-
-Parses the q3_dentdata string into entities
-================
-*/
-void Q3_ParseEntities (void)
-{
- script_t *script;
-
- num_entities = 0;
- script = LoadScriptMemory(q3_dentdata, q3_entdatasize, "*Quake3 bsp file");
- SetScriptFlags(script, SCFL_NOSTRINGWHITESPACES |
- SCFL_NOSTRINGESCAPECHARS);
-
- while(ParseEntity(script))
- {
- } //end while
-
- FreeScript(script);
-} //end of the function Q3_ParseEntities
-
-
-/*
-================
-Q3_UnparseEntities
-
-Generates the q3_dentdata string from all the entities
-================
-*/
-void Q3_UnparseEntities (void)
-{
- char *buf, *end;
- epair_t *ep;
- char line[2048];
- int i;
-
- buf = q3_dentdata;
- end = buf;
- *end = 0;
-
- for (i=0 ; i<num_entities ; i++)
- {
- ep = entities[i].epairs;
- if (!ep)
- continue; // ent got removed
-
- strcat (end,"{\n");
- end += 2;
-
- for (ep = entities[i].epairs ; ep ; ep=ep->next)
- {
- sprintf (line, "\"%s\" \"%s\"\n", ep->key, ep->value);
- strcat (end, line);
- end += strlen(line);
- }
- strcat (end,"}\n");
- end += 2;
-
- if (end > buf + Q3_MAX_MAP_ENTSTRING)
- Error ("Entity text too long");
- }
- q3_entdatasize = end - buf + 1;
-} //end of the function Q3_UnparseEntities
-
-
diff --git a/code/bspc/l_bsp_q3.h b/code/bspc/l_bsp_q3.h
deleted file mode 100644
index 82a2442..0000000
--- a/code/bspc/l_bsp_q3.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-#include "q3files.h"
-//#include "surfaceflags.h"
-
-extern int q3_nummodels;
-extern q3_dmodel_t *q3_dmodels;//[MAX_MAP_MODELS];
-
-extern int q3_numShaders;
-extern q3_dshader_t *q3_dshaders;//[Q3_MAX_MAP_SHADERS];
-
-extern int q3_entdatasize;
-extern char *q3_dentdata;//[Q3_MAX_MAP_ENTSTRING];
-
-extern int q3_numleafs;
-extern q3_dleaf_t *q3_dleafs;//[Q3_MAX_MAP_LEAFS];
-
-extern int q3_numplanes;
-extern q3_dplane_t *q3_dplanes;//[Q3_MAX_MAP_PLANES];
-
-extern int q3_numnodes;
-extern q3_dnode_t *q3_dnodes;//[Q3_MAX_MAP_NODES];
-
-extern int q3_numleafsurfaces;
-extern int *q3_dleafsurfaces;//[Q3_MAX_MAP_LEAFFACES];
-
-extern int q3_numleafbrushes;
-extern int *q3_dleafbrushes;//[Q3_MAX_MAP_LEAFBRUSHES];
-
-extern int q3_numbrushes;
-extern q3_dbrush_t *q3_dbrushes;//[Q3_MAX_MAP_BRUSHES];
-
-extern int q3_numbrushsides;
-extern q3_dbrushside_t *q3_dbrushsides;//[Q3_MAX_MAP_BRUSHSIDES];
-
-extern int q3_numLightBytes;
-extern byte *q3_lightBytes;//[Q3_MAX_MAP_LIGHTING];
-
-extern int q3_numGridPoints;
-extern byte *q3_gridData;//[Q3_MAX_MAP_LIGHTGRID];
-
-extern int q3_numVisBytes;
-extern byte *q3_visBytes;//[Q3_MAX_MAP_VISIBILITY];
-
-extern int q3_numDrawVerts;
-extern q3_drawVert_t *q3_drawVerts;//[Q3_MAX_MAP_DRAW_VERTS];
-
-extern int q3_numDrawIndexes;
-extern int *q3_drawIndexes;//[Q3_MAX_MAP_DRAW_INDEXES];
-
-extern int q3_numDrawSurfaces;
-extern q3_dsurface_t *q3_drawSurfaces;//[Q3_MAX_MAP_DRAW_SURFS];
-
-extern int q3_numFogs;
-extern q3_dfog_t *q3_dfogs;//[Q3_MAX_MAP_FOGS];
-
-extern char q3_dbrushsidetextured[Q3_MAX_MAP_BRUSHSIDES];
-
-void Q3_LoadBSPFile(struct quakefile_s *qf);
-void Q3_FreeMaxBSP(void);
-void Q3_ParseEntities (void);
diff --git a/code/bspc/l_bsp_sin.c b/code/bspc/l_bsp_sin.c
deleted file mode 100644
index 702e09d..0000000
--- a/code/bspc/l_bsp_sin.c
+++ /dev/null
@@ -1,1186 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-#include "l_cmd.h"
-#include "l_math.h"
-#include "l_mem.h"
-#include "l_log.h"
-#include "l_poly.h"
-#include "../botlib/l_script.h"
-#include "l_bsp_ent.h"
-#include "l_bsp_sin.h"
-
-void GetLeafNums (void);
-
-//=============================================================================
-
-int sin_nummodels;
-sin_dmodel_t *sin_dmodels;//[SIN_MAX_MAP_MODELS];
-
-int sin_visdatasize;
-byte *sin_dvisdata;//[SIN_MAX_MAP_VISIBILITY];
-sin_dvis_t *sin_dvis;// = (sin_dvis_t *)sin_sin_dvisdata;
-
-int sin_lightdatasize;
-byte *sin_dlightdata;//[SIN_MAX_MAP_LIGHTING];
-
-int sin_entdatasize;
-char *sin_dentdata;//[SIN_MAX_MAP_ENTSTRING];
-
-int sin_numleafs;
-sin_dleaf_t *sin_dleafs;//[SIN_MAX_MAP_LEAFS];
-
-int sin_numplanes;
-sin_dplane_t *sin_dplanes;//[SIN_MAX_MAP_PLANES];
-
-int sin_numvertexes;
-sin_dvertex_t *sin_dvertexes;//[SIN_MAX_MAP_VERTS];
-
-int sin_numnodes;
-sin_dnode_t *sin_dnodes;//[SIN_MAX_MAP_NODES];
-
-int sin_numtexinfo;
-sin_texinfo_t *sin_texinfo;//[SIN_MAX_MAP_sin_texinfo];
-
-int sin_numfaces;
-sin_dface_t *sin_dfaces;//[SIN_MAX_MAP_FACES];
-
-int sin_numedges;
-sin_dedge_t *sin_dedges;//[SIN_MAX_MAP_EDGES];
-
-int sin_numleaffaces;
-unsigned short *sin_dleaffaces;//[SIN_MAX_MAP_LEAFFACES];
-
-int sin_numleafbrushes;
-unsigned short *sin_dleafbrushes;//[SIN_MAX_MAP_LEAFBRUSHES];
-
-int sin_numsurfedges;
-int *sin_dsurfedges;//[SIN_MAX_MAP_SURFEDGES];
-
-int sin_numbrushes;
-sin_dbrush_t *sin_dbrushes;//[SIN_MAX_MAP_BRUSHES];
-
-int sin_numbrushsides;
-sin_dbrushside_t *sin_dbrushsides;//[SIN_MAX_MAP_BRUSHSIDES];
-
-int sin_numareas;
-sin_darea_t *sin_dareas;//[SIN_MAX_MAP_AREAS];
-
-int sin_numareaportals;
-sin_dareaportal_t *sin_dareaportals;//[SIN_MAX_MAP_AREAPORTALS];
-
-int sin_numlightinfo;
-sin_lightvalue_t *sin_lightinfo;//[SIN_MAX_MAP_LIGHTINFO];
-
-byte sin_dpop[256];
-
-char sin_dbrushsidetextured[SIN_MAX_MAP_BRUSHSIDES];
-
-int sin_bspallocated = false;
-int sin_allocatedbspmem = 0;
-
-void Sin_AllocMaxBSP(void)
-{
- //models
- sin_nummodels = 0;
- sin_dmodels = (sin_dmodel_t *) GetClearedMemory(SIN_MAX_MAP_MODELS * sizeof(sin_dmodel_t));
- sin_allocatedbspmem += SIN_MAX_MAP_MODELS * sizeof(sin_dmodel_t);
- //vis data
- sin_visdatasize = 0;
- sin_dvisdata = (byte *) GetClearedMemory(SIN_MAX_MAP_VISIBILITY * sizeof(byte));
- sin_dvis = (sin_dvis_t *) sin_dvisdata;
- sin_allocatedbspmem += SIN_MAX_MAP_VISIBILITY * sizeof(byte);
- //light data
- sin_lightdatasize = 0;
- sin_dlightdata = (byte *) GetClearedMemory(SIN_MAX_MAP_LIGHTING * sizeof(byte));
- sin_allocatedbspmem += SIN_MAX_MAP_LIGHTING * sizeof(byte);
- //entity data
- sin_entdatasize = 0;
- sin_dentdata = (char *) GetClearedMemory(SIN_MAX_MAP_ENTSTRING * sizeof(char));
- sin_allocatedbspmem += SIN_MAX_MAP_ENTSTRING * sizeof(char);
- //leafs
- sin_numleafs = 0;
- sin_dleafs = (sin_dleaf_t *) GetClearedMemory(SIN_MAX_MAP_LEAFS * sizeof(sin_dleaf_t));
- sin_allocatedbspmem += SIN_MAX_MAP_LEAFS * sizeof(sin_dleaf_t);
- //planes
- sin_numplanes = 0;
- sin_dplanes = (sin_dplane_t *) GetClearedMemory(SIN_MAX_MAP_PLANES * sizeof(sin_dplane_t));
- sin_allocatedbspmem += SIN_MAX_MAP_PLANES * sizeof(sin_dplane_t);
- //vertexes
- sin_numvertexes = 0;
- sin_dvertexes = (sin_dvertex_t *) GetClearedMemory(SIN_MAX_MAP_VERTS * sizeof(sin_dvertex_t));
- sin_allocatedbspmem += SIN_MAX_MAP_VERTS * sizeof(sin_dvertex_t);
- //nodes
- sin_numnodes = 0;
- sin_dnodes = (sin_dnode_t *) GetClearedMemory(SIN_MAX_MAP_NODES * sizeof(sin_dnode_t));
- sin_allocatedbspmem += SIN_MAX_MAP_NODES * sizeof(sin_dnode_t);
- //texture info
- sin_numtexinfo = 0;
- sin_texinfo = (sin_texinfo_t *) GetClearedMemory(SIN_MAX_MAP_TEXINFO * sizeof(sin_texinfo_t));
- sin_allocatedbspmem += SIN_MAX_MAP_TEXINFO * sizeof(sin_texinfo_t);
- //faces
- sin_numfaces = 0;
- sin_dfaces = (sin_dface_t *) GetClearedMemory(SIN_MAX_MAP_FACES * sizeof(sin_dface_t));
- sin_allocatedbspmem += SIN_MAX_MAP_FACES * sizeof(sin_dface_t);
- //edges
- sin_numedges = 0;
- sin_dedges = (sin_dedge_t *) GetClearedMemory(SIN_MAX_MAP_EDGES * sizeof(sin_dedge_t));
- sin_allocatedbspmem += SIN_MAX_MAP_EDGES * sizeof(sin_dedge_t);
- //leaf faces
- sin_numleaffaces = 0;
- sin_dleaffaces = (unsigned short *) GetClearedMemory(SIN_MAX_MAP_LEAFFACES * sizeof(unsigned short));
- sin_allocatedbspmem += SIN_MAX_MAP_LEAFFACES * sizeof(unsigned short);
- //leaf brushes
- sin_numleafbrushes = 0;
- sin_dleafbrushes = (unsigned short *) GetClearedMemory(SIN_MAX_MAP_LEAFBRUSHES * sizeof(unsigned short));
- sin_allocatedbspmem += SIN_MAX_MAP_LEAFBRUSHES * sizeof(unsigned short);
- //surface edges
- sin_numsurfedges = 0;
- sin_dsurfedges = (int *) GetClearedMemory(SIN_MAX_MAP_SURFEDGES * sizeof(int));
- sin_allocatedbspmem += SIN_MAX_MAP_SURFEDGES * sizeof(int);
- //brushes
- sin_numbrushes = 0;
- sin_dbrushes = (sin_dbrush_t *) GetClearedMemory(SIN_MAX_MAP_BRUSHES * sizeof(sin_dbrush_t));
- sin_allocatedbspmem += SIN_MAX_MAP_BRUSHES * sizeof(sin_dbrush_t);
- //brushsides
- sin_numbrushsides = 0;
- sin_dbrushsides = (sin_dbrushside_t *) GetClearedMemory(SIN_MAX_MAP_BRUSHSIDES * sizeof(sin_dbrushside_t));
- sin_allocatedbspmem += SIN_MAX_MAP_BRUSHSIDES * sizeof(sin_dbrushside_t);
- //areas
- sin_numareas = 0;
- sin_dareas = (sin_darea_t *) GetClearedMemory(SIN_MAX_MAP_AREAS * sizeof(sin_darea_t));
- sin_allocatedbspmem += SIN_MAX_MAP_AREAS * sizeof(sin_darea_t);
- //area portals
- sin_numareaportals = 0;
- sin_dareaportals = (sin_dareaportal_t *) GetClearedMemory(SIN_MAX_MAP_AREAPORTALS * sizeof(sin_dareaportal_t));
- sin_allocatedbspmem += SIN_MAX_MAP_AREAPORTALS * sizeof(sin_dareaportal_t);
- //light info
- sin_numlightinfo = 0;
- sin_lightinfo = (sin_lightvalue_t *) GetClearedMemory(SIN_MAX_MAP_LIGHTINFO * sizeof(sin_lightvalue_t));
- sin_allocatedbspmem += SIN_MAX_MAP_LIGHTINFO * sizeof(sin_lightvalue_t);
- //print allocated memory
- Log_Print("allocated ");
- PrintMemorySize(sin_allocatedbspmem);
- Log_Print(" of BSP memory\n");
-} //end of the function Sin_AllocMaxBSP
-
-void Sin_FreeMaxBSP(void)
-{
- //models
- sin_nummodels = 0;
- FreeMemory(sin_dmodels);
- sin_dmodels = NULL;
- //vis data
- sin_visdatasize = 0;
- FreeMemory(sin_dvisdata);
- sin_dvisdata = NULL;
- sin_dvis = NULL;
- //light data
- sin_lightdatasize = 0;
- FreeMemory(sin_dlightdata);
- sin_dlightdata = NULL;
- //entity data
- sin_entdatasize = 0;
- FreeMemory(sin_dentdata);
- sin_dentdata = NULL;
- //leafs
- sin_numleafs = 0;
- FreeMemory(sin_dleafs);
- sin_dleafs = NULL;
- //planes
- sin_numplanes = 0;
- FreeMemory(sin_dplanes);
- sin_dplanes = NULL;
- //vertexes
- sin_numvertexes = 0;
- FreeMemory(sin_dvertexes);
- sin_dvertexes = NULL;
- //nodes
- sin_numnodes = 0;
- FreeMemory(sin_dnodes);
- sin_dnodes = NULL;
- //texture info
- sin_numtexinfo = 0;
- FreeMemory(sin_texinfo);
- sin_texinfo = NULL;
- //faces
- sin_numfaces = 0;
- FreeMemory(sin_dfaces);
- sin_dfaces = NULL;
- //edges
- sin_numedges = 0;
- FreeMemory(sin_dedges);
- sin_dedges = NULL;
- //leaf faces
- sin_numleaffaces = 0;
- FreeMemory(sin_dleaffaces);
- sin_dleaffaces = NULL;
- //leaf brushes
- sin_numleafbrushes = 0;
- FreeMemory(sin_dleafbrushes);
- sin_dleafbrushes = NULL;
- //surface edges
- sin_numsurfedges = 0;
- FreeMemory(sin_dsurfedges);
- sin_dsurfedges = NULL;
- //brushes
- sin_numbrushes = 0;
- FreeMemory(sin_dbrushes);
- sin_dbrushes = NULL;
- //brushsides
- sin_numbrushsides = 0;
- FreeMemory(sin_dbrushsides);
- sin_dbrushsides = NULL;
- //areas
- sin_numareas = 0;
- FreeMemory(sin_dareas);
- sin_dareas = NULL;
- //area portals
- sin_numareaportals = 0;
- FreeMemory(sin_dareaportals);
- sin_dareaportals = NULL;
- //light info
- sin_numlightinfo = 0;
- FreeMemory(sin_lightinfo);
- sin_lightinfo = NULL;
- //
- Log_Print("freed ");
- PrintMemorySize(sin_allocatedbspmem);
- Log_Print(" of BSP memory\n");
- sin_allocatedbspmem = 0;
-} //end of the function Sin_FreeMaxBSP
-
-#define WCONVEX_EPSILON 0.5
-
-//===========================================================================
-// returns the amount the face and the winding overlap
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-float Sin_FaceOnWinding(sin_dface_t *face, winding_t *winding)
-{
- int i, edgenum, side;
- float dist, area;
- sin_dplane_t plane;
- vec_t *v1, *v2;
- vec3_t normal, edgevec;
- winding_t *w;
-
- //
- w = CopyWinding(winding);
- memcpy(&plane, &sin_dplanes[face->planenum], sizeof(sin_dplane_t));
- //check on which side of the plane the face is
- if (face->side)
- {
- VectorNegate(plane.normal, plane.normal);
- plane.dist = -plane.dist;
- } //end if
- for (i = 0; i < face->numedges && w; i++)
- {
- //get the first and second vertex of the edge
- edgenum = sin_dsurfedges[face->firstedge + i];
- side = edgenum > 0;
- //if the face plane is flipped
- v1 = sin_dvertexes[sin_dedges[abs(edgenum)].v[side]].point;
- v2 = sin_dvertexes[sin_dedges[abs(edgenum)].v[!side]].point;
- //create a plane through the edge vector, orthogonal to the face plane
- //and with the normal vector pointing out of the face
- VectorSubtract(v1, v2, edgevec);
- CrossProduct(edgevec, plane.normal, normal);
- VectorNormalize(normal);
- dist = DotProduct(normal, v1);
- //
- ChopWindingInPlace(&w, normal, dist, 0.9); //CLIP_EPSILON
- } //end for
- if (w)
- {
- area = WindingArea(w);
- FreeWinding(w);
- return area;
- } //end if
- return 0;
-} //end of the function Sin_FaceOnWinding
-//===========================================================================
-// creates a winding for the given brush side on the given brush
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-winding_t *Sin_BrushSideWinding(sin_dbrush_t *brush, sin_dbrushside_t *baseside)
-{
- int i;
- sin_dplane_t *baseplane, *plane;
- sin_dbrushside_t *side;
- winding_t *w;
-
- //create a winding for the brush side with the given planenumber
- baseplane = &sin_dplanes[baseside->planenum];
- w = BaseWindingForPlane(baseplane->normal, baseplane->dist);
- for (i = 0; i < brush->numsides && w; i++)
- {
- side = &sin_dbrushsides[brush->firstside + i];
- //don't chop with the base plane
- if (side->planenum == baseside->planenum) continue;
- //also don't use planes that are almost equal
- plane = &sin_dplanes[side->planenum];
- if (DotProduct(baseplane->normal, plane->normal) > 0.999
- && fabs(baseplane->dist - plane->dist) < 0.01) continue;
- //
- plane = &sin_dplanes[side->planenum^1];
- ChopWindingInPlace(&w, plane->normal, plane->dist, 0); //CLIP_EPSILON);
- } //end for
- return w;
-} //end of the function Sin_BrushSideWinding
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int Sin_HintSkipBrush(sin_dbrush_t *brush)
-{
- int j;
- sin_dbrushside_t *brushside;
-
- for (j = 0; j < brush->numsides; j++)
- {
- brushside = &sin_dbrushsides[brush->firstside + j];
- if (brushside->texinfo > 0)
- {
- if (sin_texinfo[brushside->texinfo].flags & (SURF_SKIP|SURF_HINT))
- {
- return true;
- } //end if
- } //end if
- } //end for
- return false;
-} //end of the function Sin_HintSkipBrush
-//===========================================================================
-// fix screwed brush texture references
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-qboolean WindingIsTiny(winding_t *w);
-
-void Sin_FixTextureReferences(void)
-{
- int i, j, k, we;
- sin_dbrushside_t *brushside;
- sin_dbrush_t *brush;
- sin_dface_t *face;
- winding_t *w;
-
- memset(sin_dbrushsidetextured, false, SIN_MAX_MAP_BRUSHSIDES);
- //go over all the brushes
- for (i = 0; i < sin_numbrushes; i++)
- {
- brush = &sin_dbrushes[i];
- //hint brushes are not textured
- if (Sin_HintSkipBrush(brush)) continue;
- //go over all the sides of the brush
- for (j = 0; j < brush->numsides; j++)
- {
- brushside = &sin_dbrushsides[brush->firstside + j];
- //
- w = Sin_BrushSideWinding(brush, brushside);
- if (!w)
- {
- sin_dbrushsidetextured[brush->firstside + j] = true;
- continue;
- } //end if
- else
- {
- //RemoveEqualPoints(w, 0.2);
- if (WindingIsTiny(w))
- {
- FreeWinding(w);
- sin_dbrushsidetextured[brush->firstside + j] = true;
- continue;
- } //end if
- else
- {
- we = WindingError(w);
- if (we == WE_NOTENOUGHPOINTS
- || we == WE_SMALLAREA
- || we == WE_POINTBOGUSRANGE
-// || we == WE_NONCONVEX
- )
- {
- FreeWinding(w);
- sin_dbrushsidetextured[brush->firstside + j] = true;
- continue;
- } //end if
- } //end else
- } //end else
- if (WindingArea(w) < 20)
- {
- sin_dbrushsidetextured[brush->firstside + j] = true;
- } //end if
- //find a face for texturing this brush
- for (k = 0; k < sin_numfaces; k++)
- {
- face = &sin_dfaces[k];
- //if the face is in the same plane as the brush side
- if ((face->planenum&~1) != (brushside->planenum&~1)) continue;
- //if the face is partly or totally on the brush side
- if (Sin_FaceOnWinding(face, w))
- {
- brushside->texinfo = face->texinfo;
- sin_dbrushsidetextured[brush->firstside + j] = true;
- break;
- } //end if
- } //end for
- FreeWinding(w);
- } //end for
- } //end for
-} //end of the function Sin_FixTextureReferences*/
-
-/*
-===============
-CompressVis
-
-===============
-*/
-int Sin_CompressVis (byte *vis, byte *dest)
-{
- int j;
- int rep;
- int visrow;
- byte *dest_p;
-
- dest_p = dest;
-// visrow = (r_numvisleafs + 7)>>3;
- visrow = (sin_dvis->numclusters + 7)>>3;
-
- for (j=0 ; j<visrow ; j++)
- {
- *dest_p++ = vis[j];
- if (vis[j])
- continue;
-
- rep = 1;
- for ( j++; j<visrow ; j++)
- if (vis[j] || rep == 255)
- break;
- else
- rep++;
- *dest_p++ = rep;
- j--;
- }
-
- return dest_p - dest;
-} //end of the function Sin_CompressVis
-
-
-/*
-===================
-DecompressVis
-===================
-*/
-void Sin_DecompressVis (byte *in, byte *decompressed)
-{
- int c;
- byte *out;
- int row;
-
-// row = (r_numvisleafs+7)>>3;
- row = (sin_dvis->numclusters+7)>>3;
- out = decompressed;
-
- do
- {
- if (*in)
- {
- *out++ = *in++;
- continue;
- }
-
- c = in[1];
- if (!c)
- Error ("DecompressVis: 0 repeat");
- in += 2;
- while (c)
- {
- *out++ = 0;
- c--;
- }
- } while (out - decompressed < row);
-} //end of the function Sin_DecompressVis
-
-//=============================================================================
-
-/*
-=============
-Sin_SwapBSPFile
-
-Byte swaps all data in a bsp file.
-=============
-*/
-void Sin_SwapBSPFile (qboolean todisk)
-{
- int i, j;
- sin_dmodel_t *d;
-
-
-// models
- for (i=0 ; i<sin_nummodels ; i++)
- {
- d = &sin_dmodels[i];
-
- d->firstface = LittleLong (d->firstface);
- d->numfaces = LittleLong (d->numfaces);
- d->headnode = LittleLong (d->headnode);
-
- for (j=0 ; j<3 ; j++)
- {
- d->mins[j] = LittleFloat(d->mins[j]);
- d->maxs[j] = LittleFloat(d->maxs[j]);
- d->origin[j] = LittleFloat(d->origin[j]);
- }
- }
-
-//
-// vertexes
-//
- for (i=0 ; i<sin_numvertexes ; i++)
- {
- for (j=0 ; j<3 ; j++)
- sin_dvertexes[i].point[j] = LittleFloat (sin_dvertexes[i].point[j]);
- }
-
-//
-// planes
-//
- for (i=0 ; i<sin_numplanes ; i++)
- {
- for (j=0 ; j<3 ; j++)
- sin_dplanes[i].normal[j] = LittleFloat (sin_dplanes[i].normal[j]);
- sin_dplanes[i].dist = LittleFloat (sin_dplanes[i].dist);
- sin_dplanes[i].type = LittleLong (sin_dplanes[i].type);
- }
-
-//
-// sin_texinfos
-//
- for (i = 0; i < sin_numtexinfo; i++)
- {
- for (j=0 ; j<8 ; j++)
- sin_texinfo[i].vecs[0][j] = LittleFloat (sin_texinfo[i].vecs[0][j]);
-#ifdef SIN
- sin_texinfo[i].trans_mag = LittleFloat( sin_texinfo[i].trans_mag );
- sin_texinfo[i].trans_angle = LittleLong( sin_texinfo[i].trans_angle );
- sin_texinfo[i].animtime = LittleFloat( sin_texinfo[i].animtime );
- sin_texinfo[i].nonlit = LittleFloat( sin_texinfo[i].nonlit );
- sin_texinfo[i].translucence = LittleFloat( sin_texinfo[i].translucence );
- sin_texinfo[i].friction = LittleFloat( sin_texinfo[i].friction );
- sin_texinfo[i].restitution = LittleFloat( sin_texinfo[i].restitution );
- sin_texinfo[i].flags = LittleUnsigned (sin_texinfo[i].flags);
-#else
- sin_texinfo[i].value = LittleLong (sin_texinfo[i].value);
- sin_texinfo[i].flags = LittleLong (sin_texinfo[i].flags);
-#endif
- sin_texinfo[i].nexttexinfo = LittleLong (sin_texinfo[i].nexttexinfo);
- }
-
-#ifdef SIN
-//
-// lightinfos
-//
- for (i = 0; i < sin_numlightinfo; i++)
- {
- for (j=0 ; j<3 ; j++)
- {
- sin_lightinfo[i].color[j] = LittleFloat (sin_lightinfo[i].color[j]);
- }
- sin_lightinfo[i].value = LittleLong (sin_lightinfo[i].value);
- sin_lightinfo[i].direct = LittleFloat( sin_lightinfo[i].direct );
- sin_lightinfo[i].directangle = LittleFloat( sin_lightinfo[i].directangle );
- sin_lightinfo[i].directstyle = LittleFloat( sin_lightinfo[i].directstyle );
- }
-#endif
-
-//
-// faces
-//
- for (i=0 ; i<sin_numfaces ; i++)
- {
- sin_dfaces[i].texinfo = LittleShort (sin_dfaces[i].texinfo);
-#ifdef SIN
- sin_dfaces[i].lightinfo = LittleLong (sin_dfaces[i].lightinfo);
- sin_dfaces[i].planenum = LittleUnsignedShort (sin_dfaces[i].planenum);
-#else
- sin_dfaces[i].planenum = LittleShort (sin_dfaces[i].planenum);
-#endif
- sin_dfaces[i].side = LittleShort (sin_dfaces[i].side);
- sin_dfaces[i].lightofs = LittleLong (sin_dfaces[i].lightofs);
- sin_dfaces[i].firstedge = LittleLong (sin_dfaces[i].firstedge);
- sin_dfaces[i].numedges = LittleShort (sin_dfaces[i].numedges);
- }
-
-//
-// nodes
-//
- for (i=0 ; i<sin_numnodes ; i++)
- {
- sin_dnodes[i].planenum = LittleLong (sin_dnodes[i].planenum);
- for (j=0 ; j<3 ; j++)
- {
- sin_dnodes[i].mins[j] = LittleShort (sin_dnodes[i].mins[j]);
- sin_dnodes[i].maxs[j] = LittleShort (sin_dnodes[i].maxs[j]);
- }
- sin_dnodes[i].children[0] = LittleLong (sin_dnodes[i].children[0]);
- sin_dnodes[i].children[1] = LittleLong (sin_dnodes[i].children[1]);
-#ifdef SIN
- sin_dnodes[i].firstface = LittleUnsignedShort (sin_dnodes[i].firstface);
- sin_dnodes[i].numfaces = LittleUnsignedShort (sin_dnodes[i].numfaces);
-#else
- sin_dnodes[i].firstface = LittleShort (sin_dnodes[i].firstface);
- sin_dnodes[i].numfaces = LittleShort (sin_dnodes[i].numfaces);
-#endif
- }
-
-//
-// leafs
-//
- for (i=0 ; i<sin_numleafs ; i++)
- {
- sin_dleafs[i].contents = LittleLong (sin_dleafs[i].contents);
- sin_dleafs[i].cluster = LittleShort (sin_dleafs[i].cluster);
- sin_dleafs[i].area = LittleShort (sin_dleafs[i].area);
- for (j=0 ; j<3 ; j++)
- {
- sin_dleafs[i].mins[j] = LittleShort (sin_dleafs[i].mins[j]);
- sin_dleafs[i].maxs[j] = LittleShort (sin_dleafs[i].maxs[j]);
- }
-#ifdef SIN
- sin_dleafs[i].firstleafface = LittleUnsignedShort (sin_dleafs[i].firstleafface);
- sin_dleafs[i].numleaffaces = LittleUnsignedShort (sin_dleafs[i].numleaffaces);
- sin_dleafs[i].firstleafbrush = LittleUnsignedShort (sin_dleafs[i].firstleafbrush);
- sin_dleafs[i].numleafbrushes = LittleUnsignedShort (sin_dleafs[i].numleafbrushes);
-#else
- sin_dleafs[i].firstleafface = LittleShort (sin_dleafs[i].firstleafface);
- sin_dleafs[i].numleaffaces = LittleShort (sin_dleafs[i].numleaffaces);
- sin_dleafs[i].firstleafbrush = LittleShort (sin_dleafs[i].firstleafbrush);
- sin_dleafs[i].numleafbrushes = LittleShort (sin_dleafs[i].numleafbrushes);
-#endif
- }
-
-//
-// leaffaces
-//
- for (i=0 ; i<sin_numleaffaces ; i++)
- sin_dleaffaces[i] = LittleShort (sin_dleaffaces[i]);
-
-//
-// leafbrushes
-//
- for (i=0 ; i<sin_numleafbrushes ; i++)
- sin_dleafbrushes[i] = LittleShort (sin_dleafbrushes[i]);
-
-//
-// surfedges
-//
- for (i=0 ; i<sin_numsurfedges ; i++)
- sin_dsurfedges[i] = LittleLong (sin_dsurfedges[i]);
-
-//
-// edges
-//
- for (i=0 ; i<sin_numedges ; i++)
- {
-#ifdef SIN
- sin_dedges[i].v[0] = LittleUnsignedShort (sin_dedges[i].v[0]);
- sin_dedges[i].v[1] = LittleUnsignedShort (sin_dedges[i].v[1]);
-#else
- sin_dedges[i].v[0] = LittleShort (sin_dedges[i].v[0]);
- sin_dedges[i].v[1] = LittleShort (sin_dedges[i].v[1]);
-#endif
- }
-
-//
-// brushes
-//
- for (i=0 ; i<sin_numbrushes ; i++)
- {
- sin_dbrushes[i].firstside = LittleLong (sin_dbrushes[i].firstside);
- sin_dbrushes[i].numsides = LittleLong (sin_dbrushes[i].numsides);
- sin_dbrushes[i].contents = LittleLong (sin_dbrushes[i].contents);
- }
-
-//
-// areas
-//
- for (i=0 ; i<sin_numareas ; i++)
- {
- sin_dareas[i].numareaportals = LittleLong (sin_dareas[i].numareaportals);
- sin_dareas[i].firstareaportal = LittleLong (sin_dareas[i].firstareaportal);
- }
-
-//
-// areasportals
-//
- for (i=0 ; i<sin_numareaportals ; i++)
- {
- sin_dareaportals[i].portalnum = LittleLong (sin_dareaportals[i].portalnum);
- sin_dareaportals[i].otherarea = LittleLong (sin_dareaportals[i].otherarea);
- }
-
-//
-// brushsides
-//
- for (i=0 ; i<sin_numbrushsides ; i++)
- {
-#ifdef SIN
- sin_dbrushsides[i].planenum = LittleUnsignedShort (sin_dbrushsides[i].planenum);
-#else
- sin_dbrushsides[i].planenum = LittleShort (sin_dbrushsides[i].planenum);
-#endif
- sin_dbrushsides[i].texinfo = LittleShort (sin_dbrushsides[i].texinfo);
-#ifdef SIN
- sin_dbrushsides[i].lightinfo = LittleLong (sin_dbrushsides[i].lightinfo);
-#endif
- }
-
-//
-// visibility
-//
- if (todisk)
- j = sin_dvis->numclusters;
- else
- j = LittleLong(sin_dvis->numclusters);
- sin_dvis->numclusters = LittleLong (sin_dvis->numclusters);
- for (i=0 ; i<j ; i++)
- {
- sin_dvis->bitofs[i][0] = LittleLong (sin_dvis->bitofs[i][0]);
- sin_dvis->bitofs[i][1] = LittleLong (sin_dvis->bitofs[i][1]);
- }
-} //end of the function Sin_SwapBSPFile
-
-
-sin_dheader_t *header;
-#ifdef SIN
-int Sin_CopyLump (int lump, void *dest, int size, int maxsize)
-{
- int length, ofs;
-
- length = header->lumps[lump].filelen;
- ofs = header->lumps[lump].fileofs;
-
- if (length % size)
- Error ("Sin_LoadBSPFile: odd lump size");
-
- if ((length/size) > maxsize)
- Error ("Sin_LoadBSPFile: exceeded max size for lump %d size %d > maxsize %d\n", lump, (length/size), maxsize );
-
- memcpy (dest, (byte *)header + ofs, length);
-
- return length / size;
-}
-#else
-int Sin_CopyLump (int lump, void *dest, int size)
-{
- int length, ofs;
-
- length = header->lumps[lump].filelen;
- ofs = header->lumps[lump].fileofs;
-
- if (length % size)
- Error ("Sin_LoadBSPFile: odd lump size");
-
- memcpy (dest, (byte *)header + ofs, length);
-
- return length / size;
-}
-#endif
-
-/*
-=============
-Sin_LoadBSPFile
-=============
-*/
-void Sin_LoadBSPFile(char *filename, int offset, int length)
-{
- int i;
-
-//
-// load the file header
-//
- LoadFile (filename, (void **)&header, offset, length);
-
-// swap the header
- for (i=0 ; i< sizeof(sin_dheader_t)/4 ; i++)
- ((int *)header)[i] = LittleLong ( ((int *)header)[i]);
-
- if (header->ident != SIN_BSPHEADER && header->ident != SINGAME_BSPHEADER)
- Error ("%s is not a IBSP file", filename);
- if (header->version != SIN_BSPVERSION && header->version != SINGAME_BSPVERSION)
- Error ("%s is version %i, not %i", filename, header->version, SIN_BSPVERSION);
-
-#ifdef SIN
- sin_nummodels = Sin_CopyLump (SIN_LUMP_MODELS, sin_dmodels, sizeof(sin_dmodel_t), SIN_MAX_MAP_MODELS);
- sin_numvertexes = Sin_CopyLump (SIN_LUMP_VERTEXES, sin_dvertexes, sizeof(sin_dvertex_t), SIN_MAX_MAP_VERTS);
- sin_numplanes = Sin_CopyLump (SIN_LUMP_PLANES, sin_dplanes, sizeof(sin_dplane_t), SIN_MAX_MAP_PLANES);
- sin_numleafs = Sin_CopyLump (SIN_LUMP_LEAFS, sin_dleafs, sizeof(sin_dleaf_t), SIN_MAX_MAP_LEAFS);
- sin_numnodes = Sin_CopyLump (SIN_LUMP_NODES, sin_dnodes, sizeof(sin_dnode_t), SIN_MAX_MAP_NODES);
- sin_numtexinfo = Sin_CopyLump (SIN_LUMP_TEXINFO, sin_texinfo, sizeof(sin_texinfo_t), SIN_MAX_MAP_TEXINFO);
- sin_numfaces = Sin_CopyLump (SIN_LUMP_FACES, sin_dfaces, sizeof(sin_dface_t), SIN_MAX_MAP_FACES);
- sin_numleaffaces = Sin_CopyLump (SIN_LUMP_LEAFFACES, sin_dleaffaces, sizeof(sin_dleaffaces[0]), SIN_MAX_MAP_LEAFFACES);
- sin_numleafbrushes = Sin_CopyLump (SIN_LUMP_LEAFBRUSHES, sin_dleafbrushes, sizeof(sin_dleafbrushes[0]), SIN_MAX_MAP_LEAFBRUSHES);
- sin_numsurfedges = Sin_CopyLump (SIN_LUMP_SURFEDGES, sin_dsurfedges, sizeof(sin_dsurfedges[0]), SIN_MAX_MAP_SURFEDGES);
- sin_numedges = Sin_CopyLump (SIN_LUMP_EDGES, sin_dedges, sizeof(sin_dedge_t), SIN_MAX_MAP_EDGES);
- sin_numbrushes = Sin_CopyLump (SIN_LUMP_BRUSHES, sin_dbrushes, sizeof(sin_dbrush_t), SIN_MAX_MAP_BRUSHES);
- sin_numbrushsides = Sin_CopyLump (SIN_LUMP_BRUSHSIDES, sin_dbrushsides, sizeof(sin_dbrushside_t), SIN_MAX_MAP_BRUSHSIDES);
- sin_numareas = Sin_CopyLump (SIN_LUMP_AREAS, sin_dareas, sizeof(sin_darea_t), SIN_MAX_MAP_AREAS);
- sin_numareaportals = Sin_CopyLump (SIN_LUMP_AREAPORTALS, sin_dareaportals, sizeof(sin_dareaportal_t), SIN_MAX_MAP_AREAPORTALS);
- sin_numlightinfo = Sin_CopyLump (SIN_LUMP_LIGHTINFO, sin_lightinfo, sizeof(sin_lightvalue_t), SIN_MAX_MAP_LIGHTINFO);
-
- sin_visdatasize = Sin_CopyLump (SIN_LUMP_VISIBILITY, sin_dvisdata, 1, SIN_MAX_MAP_VISIBILITY);
- sin_lightdatasize = Sin_CopyLump (SIN_LUMP_LIGHTING, sin_dlightdata, 1, SIN_MAX_MAP_LIGHTING);
- sin_entdatasize = Sin_CopyLump (SIN_LUMP_ENTITIES, sin_dentdata, 1, SIN_MAX_MAP_ENTSTRING);
-
- Sin_CopyLump (SIN_LUMP_POP, sin_dpop, 1, sizeof(sin_dpop));
-#else
- sin_nummodels = Sin_CopyLump (SIN_LUMP_MODELS, sin_dmodels, sizeof(sin_dmodel_t));
- sin_numvertexes = Sin_CopyLump (SIN_LUMP_VERTEXES, sin_dvertexes, sizeof(sin_dvertex_t));
- sin_numplanes = Sin_CopyLump (SIN_LUMP_PLANES, sin_dplanes, sizeof(sin_dplane_t));
- sin_numleafs = Sin_CopyLump (SIN_LUMP_LEAFS, sin_dleafs, sizeof(sin_dleaf_t));
- sin_numnodes = Sin_CopyLump (SIN_LUMP_NODES, sin_dnodes, sizeof(sin_dnode_t));
- sin_numtexinfo = Sin_CopyLump (SIN_LUMP_TEXINFO, sin_texinfo, sizeof(sin_texinfo_t));
- sin_numfaces = Sin_CopyLump (SIN_LUMP_FACES, sin_dfaces, sizeof(sin_dface_t));
- sin_numleaffaces = Sin_CopyLump (SIN_LUMP_LEAFFACES, sin_dleaffaces, sizeof(sin_dleaffaces[0]));
- sin_numleafbrushes = Sin_CopyLump (SIN_LUMP_LEAFBRUSHES, sin_dleafbrushes, sizeof(sin_dleafbrushes[0]));
- sin_numsurfedges = Sin_CopyLump (SIN_LUMP_SURFEDGES, sin_dsurfedges, sizeof(sin_dsurfedges[0]));
- sin_numedges = Sin_CopyLump (SIN_LUMP_EDGES, sin_dedges, sizeof(sin_dedge_t));
- sin_numbrushes = Sin_CopyLump (SIN_LUMP_BRUSHES, sin_dbrushes, sizeof(sin_dbrush_t));
- sin_numbrushsides = Sin_CopyLump (SIN_LUMP_BRUSHSIDES, sin_dbrushsides, sizeof(sin_dbrushside_t));
- sin_numareas = Sin_CopyLump (SIN_LUMP_AREAS, sin_dareas, sizeof(sin_darea_t));
- sin_numareaportals = Sin_CopyLump (SIN_LUMP_AREAPORTALS, sin_dareaportals, sizeof(sin_dareaportal_t));
-
- sin_visdatasize = Sin_CopyLump (SIN_LUMP_VISIBILITY, sin_dvisdata, 1);
- sin_lightdatasize = Sin_CopyLump (SIN_LUMP_LIGHTING, sin_dlightdata, 1);
- sin_entdatasize = Sin_CopyLump (SIN_LUMP_ENTITIES, sin_dentdata, 1);
-
- Sin_CopyLump (SIN_LUMP_POP, sin_dpop, 1);
-#endif
-
- FreeMemory(header); // everything has been copied out
-
-//
-// swap everything
-//
- Sin_SwapBSPFile (false);
-} //end of the function Sin_LoadBSPFile
-
-/*
-=============
-Sin_LoadBSPFilesTexinfo
-
-Only loads the sin_texinfo lump, so qdata can scan for textures
-=============
-*/
-void Sin_LoadBSPFileTexinfo (char *filename)
-{
- int i;
- FILE *f;
- int length, ofs;
-
- header = GetMemory(sizeof(sin_dheader_t));
-
- f = fopen (filename, "rb");
- fread (header, sizeof(sin_dheader_t), 1, f);
-
-// swap the header
- for (i=0 ; i< sizeof(sin_dheader_t)/4 ; i++)
- ((int *)header)[i] = LittleLong ( ((int *)header)[i]);
-
- if (header->ident != SIN_BSPHEADER && header->ident != SINGAME_BSPHEADER)
- Error ("%s is not a IBSP file", filename);
- if (header->version != SIN_BSPVERSION && header->version != SINGAME_BSPVERSION)
- Error ("%s is version %i, not %i", filename, header->version, SIN_BSPVERSION);
-
-
- length = header->lumps[SIN_LUMP_TEXINFO].filelen;
- ofs = header->lumps[SIN_LUMP_TEXINFO].fileofs;
-
- fseek (f, ofs, SEEK_SET);
- fread (sin_texinfo, length, 1, f);
- fclose (f);
-
- sin_numtexinfo = length / sizeof(sin_texinfo_t);
-
- FreeMemory(header); // everything has been copied out
-
- Sin_SwapBSPFile (false);
-} //end of the function Sin_LoadBSPFilesTexinfo
-
-
-//============================================================================
-
-FILE *wadfile;
-sin_dheader_t outheader;
-
-#ifdef SIN
-void Sin_AddLump (int lumpnum, void *data, int len, int size, int maxsize)
-{
- sin_lump_t *lump;
- int totallength;
-
- totallength = len*size;
-
- if (len > maxsize)
- Error ("Sin_WriteBSPFile: exceeded max size for lump %d size %d > maxsize %d\n", lumpnum, len, maxsize );
-
- lump = &header->lumps[lumpnum];
-
- lump->fileofs = LittleLong( ftell(wadfile) );
- lump->filelen = LittleLong(totallength);
- SafeWrite (wadfile, data, (totallength+3)&~3);
-}
-#else
-void Sin_AddLump (int lumpnum, void *data, int len)
-{
- sin_lump_t *lump;
-
- lump = &header->lumps[lumpnum];
-
- lump->fileofs = LittleLong( ftell(wadfile) );
- lump->filelen = LittleLong(len);
- SafeWrite (wadfile, data, (len+3)&~3);
-}
-#endif
-/*
-=============
-Sin_WriteBSPFile
-
-Swaps the bsp file in place, so it should not be referenced again
-=============
-*/
-void Sin_WriteBSPFile (char *filename)
-{
- header = &outheader;
- memset (header, 0, sizeof(sin_dheader_t));
-
- Sin_SwapBSPFile (true);
-
- header->ident = LittleLong (SIN_BSPHEADER);
- header->version = LittleLong (SIN_BSPVERSION);
-
- wadfile = SafeOpenWrite (filename);
- SafeWrite (wadfile, header, sizeof(sin_dheader_t)); // overwritten later
-
-#ifdef SIN
- Sin_AddLump (SIN_LUMP_PLANES, sin_dplanes, sin_numplanes, sizeof(sin_dplane_t), SIN_MAX_MAP_PLANES);
- Sin_AddLump (SIN_LUMP_LEAFS, sin_dleafs, sin_numleafs, sizeof(sin_dleaf_t), SIN_MAX_MAP_LEAFS);
- Sin_AddLump (SIN_LUMP_VERTEXES, sin_dvertexes, sin_numvertexes, sizeof(sin_dvertex_t), SIN_MAX_MAP_VERTS);
- Sin_AddLump (SIN_LUMP_NODES, sin_dnodes, sin_numnodes, sizeof(sin_dnode_t), SIN_MAX_MAP_NODES);
- Sin_AddLump (SIN_LUMP_TEXINFO, sin_texinfo, sin_numtexinfo, sizeof(sin_texinfo_t), SIN_MAX_MAP_TEXINFO);
- Sin_AddLump (SIN_LUMP_FACES, sin_dfaces, sin_numfaces, sizeof(sin_dface_t), SIN_MAX_MAP_FACES);
- Sin_AddLump (SIN_LUMP_BRUSHES, sin_dbrushes, sin_numbrushes, sizeof(sin_dbrush_t), SIN_MAX_MAP_BRUSHES);
- Sin_AddLump (SIN_LUMP_BRUSHSIDES, sin_dbrushsides, sin_numbrushsides, sizeof(sin_dbrushside_t), SIN_MAX_MAP_BRUSHSIDES);
- Sin_AddLump (SIN_LUMP_LEAFFACES, sin_dleaffaces, sin_numleaffaces, sizeof(sin_dleaffaces[0]), SIN_MAX_MAP_LEAFFACES);
- Sin_AddLump (SIN_LUMP_LEAFBRUSHES, sin_dleafbrushes, sin_numleafbrushes, sizeof(sin_dleafbrushes[0]), SIN_MAX_MAP_LEAFBRUSHES);
- Sin_AddLump (SIN_LUMP_SURFEDGES, sin_dsurfedges, sin_numsurfedges, sizeof(sin_dsurfedges[0]), SIN_MAX_MAP_SURFEDGES);
- Sin_AddLump (SIN_LUMP_EDGES, sin_dedges, sin_numedges, sizeof(sin_dedge_t), SIN_MAX_MAP_EDGES);
- Sin_AddLump (SIN_LUMP_MODELS, sin_dmodels, sin_nummodels, sizeof(sin_dmodel_t), SIN_MAX_MAP_MODELS);
- Sin_AddLump (SIN_LUMP_AREAS, sin_dareas, sin_numareas, sizeof(sin_darea_t), SIN_MAX_MAP_AREAS);
- Sin_AddLump (SIN_LUMP_AREAPORTALS, sin_dareaportals, sin_numareaportals, sizeof(sin_dareaportal_t), SIN_MAX_MAP_AREAPORTALS);
- Sin_AddLump (SIN_LUMP_LIGHTINFO, sin_lightinfo, sin_numlightinfo, sizeof(sin_lightvalue_t), SIN_MAX_MAP_LIGHTINFO);
-
- Sin_AddLump (SIN_LUMP_LIGHTING, sin_dlightdata, sin_lightdatasize, 1, SIN_MAX_MAP_LIGHTING);
- Sin_AddLump (SIN_LUMP_VISIBILITY, sin_dvisdata, sin_visdatasize, 1, SIN_MAX_MAP_VISIBILITY);
- Sin_AddLump (SIN_LUMP_ENTITIES, sin_dentdata, sin_entdatasize, 1, SIN_MAX_MAP_ENTSTRING);
- Sin_AddLump (SIN_LUMP_POP, sin_dpop, sizeof(sin_dpop), 1, sizeof(sin_dpop));
-#else
- Sin_AddLump (SIN_LUMP_PLANES, sin_dplanes, sin_numplanes*sizeof(sin_dplane_t));
- Sin_AddLump (SIN_LUMP_LEAFS, sin_dleafs, sin_numleafs*sizeof(sin_dleaf_t));
- Sin_AddLump (SIN_LUMP_VERTEXES, sin_dvertexes, sin_numvertexes*sizeof(sin_dvertex_t));
- Sin_AddLump (SIN_LUMP_NODES, sin_dnodes, sin_numnodes*sizeof(sin_dnode_t));
- Sin_AddLump (SIN_LUMP_TEXINFO, sin_texinfo, sin_numtexinfo*sizeof(sin_texinfo_t));
- Sin_AddLump (SIN_LUMP_FACES, sin_dfaces, sin_numfaces*sizeof(sin_dface_t));
- Sin_AddLump (SIN_LUMP_BRUSHES, sin_dbrushes, sin_numbrushes*sizeof(sin_dbrush_t));
- Sin_AddLump (SIN_LUMP_BRUSHSIDES, sin_dbrushsides, sin_numbrushsides*sizeof(sin_dbrushside_t));
- Sin_AddLump (SIN_LUMP_LEAFFACES, sin_dleaffaces, sin_numleaffaces*sizeof(sin_dleaffaces[0]));
- Sin_AddLump (SIN_LUMP_LEAFBRUSHES, sin_dleafbrushes, sin_numleafbrushes*sizeof(sin_dleafbrushes[0]));
- Sin_AddLump (SIN_LUMP_SURFEDGES, sin_dsurfedges, sin_numsurfedges*sizeof(sin_dsurfedges[0]));
- Sin_AddLump (SIN_LUMP_EDGES, sin_dedges, sin_numedges*sizeof(sin_dedge_t));
- Sin_AddLump (SIN_LUMP_MODELS, sin_dmodels, sin_nummodels*sizeof(sin_dmodel_t));
- Sin_AddLump (SIN_LUMP_AREAS, sin_dareas, sin_numareas*sizeof(sin_darea_t));
- Sin_AddLump (SIN_LUMP_AREAPORTALS, sin_dareaportals, sin_numareaportals*sizeof(sin_dareaportal_t));
-
- Sin_AddLump (SIN_LUMP_LIGHTING, sin_dlightdata, sin_lightdatasize);
- Sin_AddLump (SIN_LUMP_VISIBILITY, sin_dvisdata, sin_visdatasize);
- Sin_AddLump (SIN_LUMP_ENTITIES, sin_dentdata, sin_entdatasize);
- Sin_AddLump (SIN_LUMP_POP, sin_dpop, sizeof(sin_dpop));
-#endif
-
- fseek (wadfile, 0, SEEK_SET);
- SafeWrite (wadfile, header, sizeof(sin_dheader_t));
- fclose (wadfile);
-}
-
-//============================================================================
-
-
-//============================================
-
-/*
-================
-ParseEntities
-
-Parses the sin_dentdata string into entities
-================
-*/
-void Sin_ParseEntities (void)
-{
- script_t *script;
-
- num_entities = 0;
- script = LoadScriptMemory(sin_dentdata, sin_entdatasize, "*sin bsp file");
- SetScriptFlags(script, SCFL_NOSTRINGWHITESPACES |
- SCFL_NOSTRINGESCAPECHARS);
-
- while(ParseEntity(script))
- {
- } //end while
-
- FreeScript(script);
-} //end of the function Sin_ParseEntities
-
-
-/*
-================
-UnparseEntities
-
-Generates the sin_dentdata string from all the entities
-================
-*/
-void Sin_UnparseEntities (void)
-{
- char *buf, *end;
- epair_t *ep;
- char line[2048];
- int i;
- char key[1024], value[1024];
-
- buf = sin_dentdata;
- end = buf;
- *end = 0;
-
- for (i=0 ; i<num_entities ; i++)
- {
- ep = entities[i].epairs;
- if (!ep)
- continue; // ent got removed
-
- strcat (end,"{\n");
- end += 2;
-
- for (ep = entities[i].epairs ; ep ; ep=ep->next)
- {
- strcpy (key, ep->key);
- StripTrailing (key);
- strcpy (value, ep->value);
- StripTrailing (value);
-
- sprintf (line, "\"%s\" \"%s\"\n", key, value);
- strcat (end, line);
- end += strlen(line);
- }
- strcat (end,"}\n");
- end += 2;
-
- if (end > buf + SIN_MAX_MAP_ENTSTRING)
- Error ("Entity text too long");
- }
- sin_entdatasize = end - buf + 1;
-} //end of the function Sin_UnparseEntities
-
-#ifdef SIN
-void FreeValueKeys(entity_t *ent)
-{
- epair_t *ep,*next;
-
- for (ep=ent->epairs ; ep ; ep=next)
- {
- next = ep->next;
- FreeMemory(ep->value);
- FreeMemory(ep->key);
- FreeMemory(ep);
- }
- ent->epairs = NULL;
-}
-#endif
-
-/*
-=============
-Sin_PrintBSPFileSizes
-
-Dumps info about current file
-=============
-*/
-void Sin_PrintBSPFileSizes (void)
-{
- if (!num_entities)
- Sin_ParseEntities ();
-
- Log_Print("%6i models %7i\n"
- ,sin_nummodels, (int)(sin_nummodels*sizeof(sin_dmodel_t)));
- Log_Print("%6i brushes %7i\n"
- ,sin_numbrushes, (int)(sin_numbrushes*sizeof(sin_dbrush_t)));
- Log_Print("%6i brushsides %7i\n"
- ,sin_numbrushsides, (int)(sin_numbrushsides*sizeof(sin_dbrushside_t)));
- Log_Print("%6i planes %7i\n"
- ,sin_numplanes, (int)(sin_numplanes*sizeof(sin_dplane_t)));
- Log_Print("%6i texinfo %7i\n"
- ,sin_numtexinfo, (int)(sin_numtexinfo*sizeof(sin_texinfo_t)));
-#ifdef SIN
- Log_Print("%6i lightinfo %7i\n"
- ,sin_numlightinfo, (int)(sin_numlightinfo*sizeof(sin_lightvalue_t)));
-#endif
- Log_Print("%6i entdata %7i\n", num_entities, sin_entdatasize);
-
- Log_Print("\n");
-
- Log_Print("%6i vertexes %7i\n"
- ,sin_numvertexes, (int)(sin_numvertexes*sizeof(sin_dvertex_t)));
- Log_Print("%6i nodes %7i\n"
- ,sin_numnodes, (int)(sin_numnodes*sizeof(sin_dnode_t)));
- Log_Print("%6i faces %7i\n"
- ,sin_numfaces, (int)(sin_numfaces*sizeof(sin_dface_t)));
- Log_Print("%6i leafs %7i\n"
- ,sin_numleafs, (int)(sin_numleafs*sizeof(sin_dleaf_t)));
- Log_Print("%6i leaffaces %7i\n"
- ,sin_numleaffaces, (int)(sin_numleaffaces*sizeof(sin_dleaffaces[0])));
- Log_Print("%6i leafbrushes %7i\n"
- ,sin_numleafbrushes, (int)(sin_numleafbrushes*sizeof(sin_dleafbrushes[0])));
- Log_Print("%6i surfedges %7i\n"
- ,sin_numsurfedges, (int)(sin_numsurfedges*sizeof(sin_dsurfedges[0])));
- Log_Print("%6i edges %7i\n"
- ,sin_numedges, (int)(sin_numedges*sizeof(sin_dedge_t)));
- Log_Print(" lightdata %7i\n", sin_lightdatasize);
- Log_Print(" visdata %7i\n", sin_visdatasize);
-}
diff --git a/code/bspc/l_bsp_sin.h b/code/bspc/l_bsp_sin.h
deleted file mode 100644
index babebe6..0000000
--- a/code/bspc/l_bsp_sin.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-#include "sinfiles.h"
-
-#define SINGAME_BSPHEADER (('P'<<24)+('S'<<16)+('B'<<8)+'R') //RBSP
-#define SINGAME_BSPVERSION 1
-
-#define SIN_BSPHEADER (('P'<<24)+('S'<<16)+('B'<<8)+'I') //IBSP
-#define SIN_BSPVERSION 41
-
-
-extern int sin_nummodels;
-extern sin_dmodel_t *sin_dmodels;//[MAX_MAP_MODELS];
-
-extern int sin_visdatasize;
-extern byte *sin_dvisdata;//[MAX_MAP_VISIBILITY];
-extern sin_dvis_t *sin_dvis;// = (dvis_t *)sin_sin_dvisdata;
-
-extern int sin_lightdatasize;
-extern byte *sin_dlightdata;//[MAX_MAP_LIGHTING];
-
-extern int sin_entdatasize;
-extern char *sin_dentdata;//[MAX_MAP_ENTSTRING];
-
-extern int sin_numleafs;
-extern sin_dleaf_t *sin_dleafs;//[MAX_MAP_LEAFS];
-
-extern int sin_numplanes;
-extern sin_dplane_t *sin_dplanes;//[MAX_MAP_PLANES];
-
-extern int sin_numvertexes;
-extern sin_dvertex_t *sin_dvertexes;//[MAX_MAP_VERTS];
-
-extern int sin_numnodes;
-extern sin_dnode_t *sin_dnodes;//[MAX_MAP_NODES];
-
-extern int sin_numtexinfo;
-extern sin_texinfo_t *sin_texinfo;//[MAX_MAP_sin_texinfo];
-
-extern int sin_numfaces;
-extern sin_dface_t *sin_dfaces;//[MAX_MAP_FACES];
-
-extern int sin_numedges;
-extern sin_dedge_t *sin_dedges;//[MAX_MAP_EDGES];
-
-extern int sin_numleaffaces;
-extern unsigned short *sin_dleaffaces;//[MAX_MAP_LEAFFACES];
-
-extern int sin_numleafbrushes;
-extern unsigned short *sin_dleafbrushes;//[MAX_MAP_LEAFBRUSHES];
-
-extern int sin_numsurfedges;
-extern int *sin_dsurfedges;//[MAX_MAP_SURFEDGES];
-
-extern int sin_numbrushes;
-extern sin_dbrush_t *sin_dbrushes;//[MAX_MAP_BRUSHES];
-
-extern int sin_numbrushsides;
-extern sin_dbrushside_t *sin_dbrushsides;//[MAX_MAP_BRUSHSIDES];
-
-extern int sin_numareas;
-extern sin_darea_t *sin_dareas;//[MAX_MAP_AREAS];
-
-extern int sin_numareaportals;
-extern sin_dareaportal_t *sin_dareaportals;//[MAX_MAP_AREAPORTALS];
-
-extern int sin_numlightinfo;
-extern sin_lightvalue_t *sin_lightinfo;//[MAX_MAP_LIGHTINFO];
-
-extern byte sin_dpop[256];
-
-extern char sin_dbrushsidetextured[SIN_MAX_MAP_BRUSHSIDES];
-
-void Sin_AllocMaxBSP(void);
-void Sin_FreeMaxBSP(void);
-
-void Sin_DecompressVis(byte *in, byte *decompressed);
-int Sin_CompressVis(byte *vis, byte *dest);
-
-void Sin_LoadBSPFile (char *filename, int offset, int length);
-void Sin_LoadBSPFileTexinfo (char *filename); // just for qdata
-void Sin_WriteBSPFile (char *filename);
-void Sin_PrintBSPFileSizes (void);
-void Sin_ParseEntities(void);
-void Sin_UnparseEntities(void);
-
diff --git a/code/bspc/l_cmd.c b/code/bspc/l_cmd.c
deleted file mode 100644
index ed1f079..0000000
--- a/code/bspc/l_cmd.c
+++ /dev/null
@@ -1,1230 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-// cmdlib.c
-
-#include "l_cmd.h"
-#include "l_log.h"
-#include "l_mem.h"
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#ifndef SIN
-#define SIN
-#endif //SIN
-
-#if defined(WIN32) || defined(_WIN32)
-#include <direct.h>
-#else
-#include <unistd.h>
-#endif
-
-#ifdef NeXT
-#include <libc.h>
-#endif
-
-#define BASEDIRNAME "quake2"
-#define PATHSEPERATOR '/'
-
-// set these before calling CheckParm
-int myargc;
-char **myargv;
-
-char com_token[1024];
-qboolean com_eof;
-
-qboolean archive;
-char archivedir[1024];
-
-
-/*
-===================
-ExpandWildcards
-
-Mimic unix command line expansion
-===================
-*/
-#define MAX_EX_ARGC 1024
-int ex_argc;
-char *ex_argv[MAX_EX_ARGC];
-#ifdef _WIN32
-#include "io.h"
-void ExpandWildcards (int *argc, char ***argv)
-{
- struct _finddata_t fileinfo;
- int handle;
- int i;
- char filename[1024];
- char filebase[1024];
- char *path;
-
- ex_argc = 0;
- for (i=0 ; i<*argc ; i++)
- {
- path = (*argv)[i];
- if ( path[0] == '-'
- || ( !strstr(path, "*") && !strstr(path, "?") ) )
- {
- ex_argv[ex_argc++] = path;
- continue;
- }
-
- handle = _findfirst (path, &fileinfo);
- if (handle == -1)
- return;
-
- ExtractFilePath (path, filebase);
-
- do
- {
- sprintf (filename, "%s%s", filebase, fileinfo.name);
- ex_argv[ex_argc++] = copystring (filename);
- } while (_findnext( handle, &fileinfo ) != -1);
-
- _findclose (handle);
- }
-
- *argc = ex_argc;
- *argv = ex_argv;
-}
-#else
-void ExpandWildcards (int *argc, char ***argv)
-{
-}
-#endif
-
-#ifdef WINBSPC
-
-#include <windows.h>
-
-HWND program_hwnd;
-
-void SetProgramHandle(HWND hwnd)
-{
- program_hwnd = hwnd;
-} //end of the function SetProgramHandle
-
-/*
-=================
-Error
-
-For abnormal program terminations in windowed apps
-=================
-*/
-void Error (char *error, ...)
-{
- va_list argptr;
- char text[1024];
- char text2[1024];
- int err;
-
- err = GetLastError ();
-
- va_start(argptr, error);
- vsprintf(text, error, argptr);
- va_end(argptr);
-
- sprintf(text2, "%s\nGetLastError() = %i", text, err);
- MessageBox(program_hwnd, text2, "Error", 0 /* MB_OK */ );
-
- Log_Write(text);
- Log_Close();
-
- exit(1);
-} //end of the function Error
-
-void Warning(char *szFormat, ...)
-{
- char szBuffer[256];
- va_list argptr;
-
- va_start (argptr, szFormat);
- vsprintf(szBuffer, szFormat, argptr);
- va_end (argptr);
-
- MessageBox(program_hwnd, szBuffer, "Warning", MB_OK);
-
- Log_Write(szBuffer);
-} //end of the function Warning
-
-
-#else
-/*
-=================
-Error
-
-For abnormal program terminations in console apps
-=================
-*/
-void Error (char *error, ...)
-{
- va_list argptr;
- char text[1024];
-
- va_start(argptr, error);
- vsprintf(text, error, argptr);
- va_end(argptr);
- printf("ERROR: %s\n", text);
-
- Log_Write(text);
- Log_Close();
-
- exit (1);
-} //end of the function Error
-
-void Warning(char *warning, ...)
-{
- va_list argptr;
- char text[1024];
-
- va_start(argptr, warning);
- vsprintf(text, warning, argptr);
- va_end(argptr);
- printf("WARNING: %s\n", text);
-
- Log_Write(text);
-} //end of the function Warning
-
-#endif
-
-//only printf if in verbose mode
-qboolean verbose = true;
-
-void qprintf(char *format, ...)
-{
- va_list argptr;
-#ifdef WINBSPC
- char buf[2048];
-#endif //WINBSPC
-
- if (!verbose)
- return;
-
- va_start(argptr,format);
-#ifdef WINBSPC
- vsprintf(buf, format, argptr);
- WinBSPCPrint(buf);
-#else
- vprintf(format, argptr);
-#endif //WINBSPC
- va_end(argptr);
-} //end of the function qprintf
-
-void Com_Error(int level, char *error, ...)
-{
- va_list argptr;
- char text[1024];
-
- va_start(argptr, error);
- vsprintf(text, error, argptr);
- va_end(argptr);
- Error(text);
-} //end of the funcion Com_Error
-
-void Com_Printf( const char *fmt, ... )
-{
- va_list argptr;
- char text[1024];
-
- va_start(argptr, fmt);
- vsprintf(text, fmt, argptr);
- va_end(argptr);
- Log_Print(text);
-} //end of the funcion Com_Printf
-
-/*
-
-qdir will hold the path up to the quake directory, including the slash
-
- f:\quake\
- /raid/quake/
-
-gamedir will hold qdir + the game directory (id1, id2, etc)
-
- */
-
-char qdir[1024];
-char gamedir[1024];
-
-void SetQdirFromPath (char *path)
-{
- char temp[1024];
- char *c;
- int len;
-
- if (!(path[0] == '/' || path[0] == '\\' || path[1] == ':'))
- { // path is partial
- Q_getwd (temp);
- strcat (temp, path);
- path = temp;
- }
-
- // search for "quake2" in path
-
- len = strlen(BASEDIRNAME);
- for (c=path+strlen(path)-1 ; c != path ; c--)
- if (!Q_strncasecmp (c, BASEDIRNAME, len))
- {
- strncpy (qdir, path, c+len+1-path);
- qprintf ("qdir: %s\n", qdir);
- c += len+1;
- while (*c)
- {
- if (*c == '/' || *c == '\\')
- {
- strncpy (gamedir, path, c+1-path);
- qprintf ("gamedir: %s\n", gamedir);
- return;
- }
- c++;
- }
- Error ("No gamedir in %s", path);
- return;
- }
- Error ("SetQdirFromPath: no '%s' in %s", BASEDIRNAME, path);
-}
-
-char *ExpandArg (char *path)
-{
- static char full[1024];
-
- if (path[0] != '/' && path[0] != '\\' && path[1] != ':')
- {
- Q_getwd (full);
- strcat (full, path);
- }
- else
- strcpy (full, path);
- return full;
-}
-
-char *ExpandPath (char *path)
-{
- static char full[1024];
- if (!qdir)
- Error ("ExpandPath called without qdir set");
- if (path[0] == '/' || path[0] == '\\' || path[1] == ':')
- return path;
- sprintf (full, "%s%s", qdir, path);
- return full;
-}
-
-char *ExpandPathAndArchive (char *path)
-{
- char *expanded;
- char archivename[1024];
-
- expanded = ExpandPath (path);
-
- if (archive)
- {
- sprintf (archivename, "%s/%s", archivedir, path);
- QCopyFile (expanded, archivename);
- }
- return expanded;
-}
-
-
-char *copystring(char *s)
-{
- char *b;
- b = GetMemory(strlen(s)+1);
- strcpy (b, s);
- return b;
-}
-
-
-
-/*
-================
-I_FloatTime
-================
-*/
-double I_FloatTime (void)
-{
- time_t t;
-
- time (&t);
-
- return t;
-#if 0
-// more precise, less portable
- struct timeval tp;
- struct timezone tzp;
- static int secbase;
-
- gettimeofday(&tp, &tzp);
-
- if (!secbase)
- {
- secbase = tp.tv_sec;
- return tp.tv_usec/1000000.0;
- }
-
- return (tp.tv_sec - secbase) + tp.tv_usec/1000000.0;
-#endif
-}
-
-void Q_getwd (char *out)
-{
-#if defined(WIN32) || defined(_WIN32)
- getcwd (out, 256);
- strcat (out, "\\");
-#else
- getwd(out);
- strcat(out, "/");
-#endif
-}
-
-
-void Q_mkdir (char *path)
-{
-#ifdef WIN32
- if (_mkdir (path) != -1)
- return;
-#else
- if (mkdir (path, 0777) != -1)
- return;
-#endif
- if (errno != EEXIST)
- Error ("mkdir %s: %s",path, strerror(errno));
-}
-
-/*
-============
-FileTime
-
-returns -1 if not present
-============
-*/
-int FileTime (char *path)
-{
- struct stat buf;
-
- if (stat (path,&buf) == -1)
- return -1;
-
- return buf.st_mtime;
-}
-
-
-
-/*
-==============
-COM_Parse
-
-Parse a token out of a string
-==============
-*/
-char *COM_Parse (char *data)
-{
- int c;
- int len;
-
- len = 0;
- com_token[0] = 0;
-
- if (!data)
- return NULL;
-
-// skip whitespace
-skipwhite:
- while ( (c = *data) <= ' ')
- {
- if (c == 0)
- {
- com_eof = true;
- return NULL; // end of file;
- }
- data++;
- }
-
-// skip // comments
- if (c=='/' && data[1] == '/')
- {
- while (*data && *data != '\n')
- data++;
- goto skipwhite;
- }
-
-
-// handle quoted strings specially
- if (c == '\"')
- {
- data++;
- do
- {
- c = *data++;
- if (c=='\"')
- {
- com_token[len] = 0;
- return data;
- }
- com_token[len] = c;
- len++;
- } while (1);
- }
-
-// parse single characters
- if (c=='{' || c=='}'|| c==')'|| c=='(' || c=='\'' || c==':')
- {
- com_token[len] = c;
- len++;
- com_token[len] = 0;
- return data+1;
- }
-
-// parse a regular word
- do
- {
- com_token[len] = c;
- data++;
- len++;
- c = *data;
- if (c=='{' || c=='}'|| c==')'|| c=='(' || c=='\'' || c==':')
- break;
- } while (c>32);
-
- com_token[len] = 0;
- return data;
-}
-
-
-int Q_strncasecmp (char *s1, char *s2, int n)
-{
- int c1, c2;
-
- do
- {
- c1 = *s1++;
- c2 = *s2++;
-
- if (!n--)
- return 0; // strings are equal until end point
-
- if (c1 != c2)
- {
- if (c1 >= 'a' && c1 <= 'z')
- c1 -= ('a' - 'A');
- if (c2 >= 'a' && c2 <= 'z')
- c2 -= ('a' - 'A');
- if (c1 != c2)
- return -1; // strings not equal
- }
- } while (c1);
-
- return 0; // strings are equal
-}
-
-int Q_strcasecmp (char *s1, char *s2)
-{
- return Q_strncasecmp (s1, s2, 99999);
-}
-
-int Q_stricmp (char *s1, char *s2)
-{
- return Q_strncasecmp (s1, s2, 99999);
-}
-
-void Q_strncpyz( char *dest, const char *src, int destsize ) {
- strncpy( dest, src, destsize-1 );
- dest[destsize-1] = 0;
-}
-
-char *strupr (char *start)
-{
- char *in;
- in = start;
- while (*in)
- {
- *in = toupper(*in);
- in++;
- }
- return start;
-}
-
-char *strlower (char *start)
-{
- char *in;
- in = start;
- while (*in)
- {
- *in = tolower(*in);
- in++;
- }
- return start;
-}
-
-
-/*
-=============================================================================
-
- MISC FUNCTIONS
-
-=============================================================================
-*/
-
-
-/*
-=================
-CheckParm
-
-Checks for the given parameter in the program's command line arguments
-Returns the argument number (1 to argc-1) or 0 if not present
-=================
-*/
-int CheckParm (char *check)
-{
- int i;
-
- for (i = 1;i<myargc;i++)
- {
- if ( !Q_strcasecmp(check, myargv[i]) )
- return i;
- }
-
- return 0;
-}
-
-
-
-/*
-================
-Q_filelength
-================
-*/
-int Q_filelength (FILE *f)
-{
- int pos;
- int end;
-
- pos = ftell (f);
- fseek (f, 0, SEEK_END);
- end = ftell (f);
- fseek (f, pos, SEEK_SET);
-
- return end;
-}
-
-
-FILE *SafeOpenWrite (char *filename)
-{
- FILE *f;
-
- f = fopen(filename, "wb");
-
- if (!f)
- Error ("Error opening %s: %s",filename,strerror(errno));
-
- return f;
-}
-
-FILE *SafeOpenRead (char *filename)
-{
- FILE *f;
-
- f = fopen(filename, "rb");
-
- if (!f)
- Error ("Error opening %s: %s",filename,strerror(errno));
-
- return f;
-}
-
-
-void SafeRead (FILE *f, void *buffer, int count)
-{
- if ( fread (buffer, 1, count, f) != (size_t)count)
- Error ("File read failure");
-}
-
-
-void SafeWrite (FILE *f, void *buffer, int count)
-{
- if (fwrite (buffer, 1, count, f) != (size_t)count)
- Error ("File write failure");
-}
-
-
-/*
-==============
-FileExists
-==============
-*/
-qboolean FileExists (char *filename)
-{
- FILE *f;
-
- f = fopen (filename, "r");
- if (!f)
- return false;
- fclose (f);
- return true;
-}
-
-/*
-==============
-LoadFile
-==============
-*/
-int LoadFile (char *filename, void **bufferptr, int offset, int length)
-{
- FILE *f;
- void *buffer;
-
- f = SafeOpenRead(filename);
- fseek(f, offset, SEEK_SET);
- if (!length) length = Q_filelength(f);
- buffer = GetMemory(length+1);
- ((char *)buffer)[length] = 0;
- SafeRead(f, buffer, length);
- fclose(f);
-
- *bufferptr = buffer;
- return length;
-}
-
-
-/*
-==============
-TryLoadFile
-
-Allows failure
-==============
-*/
-int TryLoadFile (char *filename, void **bufferptr)
-{
- FILE *f;
- int length;
- void *buffer;
-
- *bufferptr = NULL;
-
- f = fopen (filename, "rb");
- if (!f)
- return -1;
- length = Q_filelength (f);
- buffer = GetMemory(length+1);
- ((char *)buffer)[length] = 0;
- SafeRead (f, buffer, length);
- fclose (f);
-
- *bufferptr = buffer;
- return length;
-}
-
-
-/*
-==============
-SaveFile
-==============
-*/
-void SaveFile (char *filename, void *buffer, int count)
-{
- FILE *f;
-
- f = SafeOpenWrite (filename);
- SafeWrite (f, buffer, count);
- fclose (f);
-}
-
-
-
-void DefaultExtension (char *path, char *extension)
-{
- char *src;
-//
-// if path doesnt have a .EXT, append extension
-// (extension should include the .)
-//
- src = path + strlen(path) - 1;
-
- while (*src != PATHSEPERATOR && src != path)
- {
- if (*src == '.')
- return; // it has an extension
- src--;
- }
-
- strcat (path, extension);
-}
-
-
-void DefaultPath (char *path, char *basepath)
-{
- char temp[128];
-
- if (path[0] == PATHSEPERATOR)
- return; // absolute path location
- strcpy (temp,path);
- strcpy (path,basepath);
- strcat (path,temp);
-}
-
-
-void StripFilename (char *path)
-{
- int length;
-
- length = strlen(path)-1;
- while (length > 0 && path[length] != PATHSEPERATOR)
- length--;
- path[length] = 0;
-}
-
-void StripExtension (char *path)
-{
- int length;
-
- length = strlen(path)-1;
- while (length > 0 && path[length] != '.')
- {
- length--;
- if (path[length] == '/')
- return; // no extension
- }
- if (length)
- path[length] = 0;
-}
-
-
-/*
-====================
-Extract file parts
-====================
-*/
-// FIXME: should include the slash, otherwise
-// backing to an empty path will be wrong when appending a slash
-void ExtractFilePath (char *path, char *dest)
-{
- char *src;
-
- src = path + strlen(path) - 1;
-
-//
-// back up until a \ or the start
-//
- while (src != path && *(src-1) != '\\' && *(src-1) != '/')
- src--;
-
- memcpy (dest, path, src-path);
- dest[src-path] = 0;
-}
-
-void ExtractFileBase (char *path, char *dest)
-{
- char *src;
-
- src = path + strlen(path) - 1;
-
-//
-// back up until a \ or the start
-//
- while (src != path && *(src-1) != '\\' && *(src-1) != '/')
- src--;
-
- while (*src && *src != '.')
- {
- *dest++ = *src++;
- }
- *dest = 0;
-}
-
-void ExtractFileExtension (char *path, char *dest)
-{
- char *src;
-
- src = path + strlen(path) - 1;
-
-//
-// back up until a . or the start
-//
- while (src != path && *(src-1) != '.')
- src--;
- if (src == path)
- {
- *dest = 0; // no extension
- return;
- }
-
- strcpy (dest,src);
-}
-
-
-/*
-==============
-ParseNum / ParseHex
-==============
-*/
-int ParseHex (char *hex)
-{
- char *str;
- int num;
-
- num = 0;
- str = hex;
-
- while (*str)
- {
- num <<= 4;
- if (*str >= '0' && *str <= '9')
- num += *str-'0';
- else if (*str >= 'a' && *str <= 'f')
- num += 10 + *str-'a';
- else if (*str >= 'A' && *str <= 'F')
- num += 10 + *str-'A';
- else
- Error ("Bad hex number: %s",hex);
- str++;
- }
-
- return num;
-}
-
-
-int ParseNum (char *str)
-{
- if (str[0] == '$')
- return ParseHex (str+1);
- if (str[0] == '0' && str[1] == 'x')
- return ParseHex (str+2);
- return atol (str);
-}
-
-
-
-/*
-============================================================================
-
- BYTE ORDER FUNCTIONS
-
-============================================================================
-*/
-
-#ifdef _SGI_SOURCE
-#define __BIG_ENDIAN__
-#endif
-
-#ifdef __BIG_ENDIAN__
-
-short LittleShort (short l)
-{
- byte b1,b2;
-
- b1 = l&255;
- b2 = (l>>8)&255;
-
- return (b1<<8) + b2;
-}
-
-short BigShort (short l)
-{
- return l;
-}
-
-
-int LittleLong (int l)
-{
- byte b1,b2,b3,b4;
-
- b1 = l&255;
- b2 = (l>>8)&255;
- b3 = (l>>16)&255;
- b4 = (l>>24)&255;
-
- return ((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4;
-}
-
-int BigLong (int l)
-{
- return l;
-}
-
-
-float LittleFloat (float l)
-{
- union {byte b[4]; float f;} in, out;
-
- in.f = l;
- out.b[0] = in.b[3];
- out.b[1] = in.b[2];
- out.b[2] = in.b[1];
- out.b[3] = in.b[0];
-
- return out.f;
-}
-
-float BigFloat (float l)
-{
- return l;
-}
-
-#ifdef SIN
-unsigned short LittleUnsignedShort (unsigned short l)
-{
- byte b1,b2;
-
- b1 = l&255;
- b2 = (l>>8)&255;
-
- return (b1<<8) + b2;
-}
-
-unsigned short BigUnsignedShort (unsigned short l)
-{
- return l;
-}
-
-unsigned LittleUnsigned (unsigned l)
-{
- byte b1,b2,b3,b4;
-
- b1 = l&255;
- b2 = (l>>8)&255;
- b3 = (l>>16)&255;
- b4 = (l>>24)&255;
-
- return ((unsigned)b1<<24) + ((unsigned)b2<<16) + ((unsigned)b3<<8) + b4;
-}
-
-unsigned BigUnsigned (unsigned l)
-{
- return l;
-}
-#endif
-
-
-#else
-
-
-short BigShort (short l)
-{
- byte b1,b2;
-
- b1 = l&255;
- b2 = (l>>8)&255;
-
- return (b1<<8) + b2;
-}
-
-short LittleShort (short l)
-{
- return l;
-}
-
-
-int BigLong (int l)
-{
- byte b1,b2,b3,b4;
-
- b1 = l&255;
- b2 = (l>>8)&255;
- b3 = (l>>16)&255;
- b4 = (l>>24)&255;
-
- return ((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4;
-}
-
-int LittleLong (int l)
-{
- return l;
-}
-
-float BigFloat (float l)
-{
- union {byte b[4]; float f;} in, out;
-
- in.f = l;
- out.b[0] = in.b[3];
- out.b[1] = in.b[2];
- out.b[2] = in.b[1];
- out.b[3] = in.b[0];
-
- return out.f;
-}
-
-float LittleFloat (float l)
-{
- return l;
-}
-
-#ifdef SIN
-unsigned short BigUnsignedShort (unsigned short l)
-{
- byte b1,b2;
-
- b1 = l&255;
- b2 = (l>>8)&255;
-
- return (b1<<8) + b2;
-}
-
-unsigned short LittleUnsignedShort (unsigned short l)
-{
- return l;
-}
-
-
-unsigned BigUnsigned (unsigned l)
-{
- byte b1,b2,b3,b4;
-
- b1 = l&255;
- b2 = (l>>8)&255;
- b3 = (l>>16)&255;
- b4 = (l>>24)&255;
-
- return ((unsigned)b1<<24) + ((unsigned)b2<<16) + ((unsigned)b3<<8) + b4;
-}
-
-unsigned LittleUnsigned (unsigned l)
-{
- return l;
-}
-#endif
-
-
-#endif
-
-
-//=======================================================
-
-
-// FIXME: byte swap?
-
-// this is a 16 bit, non-reflected CRC using the polynomial 0x1021
-// and the initial and final xor values shown below... in other words, the
-// CCITT standard CRC used by XMODEM
-
-#define CRC_INIT_VALUE 0xffff
-#define CRC_XOR_VALUE 0x0000
-
-static unsigned short crctable[256] =
-{
- 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
- 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
- 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
- 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
- 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
- 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
- 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
- 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
- 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
- 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
- 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
- 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
- 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
- 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
- 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
- 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
- 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
- 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
- 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
- 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
- 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
- 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
- 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
- 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
- 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
- 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
- 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
- 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
- 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
- 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
- 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
- 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
-};
-
-void CRC_Init(unsigned short *crcvalue)
-{
- *crcvalue = CRC_INIT_VALUE;
-}
-
-void CRC_ProcessByte(unsigned short *crcvalue, byte data)
-{
- *crcvalue = (*crcvalue << 8) ^ crctable[(*crcvalue >> 8) ^ data];
-}
-
-unsigned short CRC_Value(unsigned short crcvalue)
-{
- return crcvalue ^ CRC_XOR_VALUE;
-}
-//=============================================================================
-
-/*
-============
-CreatePath
-============
-*/
-void CreatePath (char *path)
-{
- char *ofs, c;
-
- if (path[1] == ':')
- path += 2;
-
- for (ofs = path+1 ; *ofs ; ofs++)
- {
- c = *ofs;
- if (c == '/' || c == '\\')
- { // create the directory
- *ofs = 0;
- Q_mkdir (path);
- *ofs = c;
- }
- }
-}
-
-
-/*
-============
-QCopyFile
-
- Used to archive source files
-============
-*/
-void QCopyFile (char *from, char *to)
-{
- void *buffer;
- int length;
-
- length = LoadFile (from, &buffer, 0, 0);
- CreatePath (to);
- SaveFile (to, buffer, length);
- FreeMemory(buffer);
-}
-
-void FS_FreeFile(void *buf)
-{
- FreeMemory(buf);
-} //end of the function FS_FreeFile
-
-int FS_ReadFileAndCache(const char *qpath, void **buffer)
-{
- return LoadFile((char *) qpath, buffer, 0, 0);
-} //end of the function FS_ReadFileAndCache
-
-int FS_FOpenFileRead( const char *filename, FILE **file, qboolean uniqueFILE )
-{
- *file = fopen(filename, "rb");
- return (*file != NULL);
-} //end of the function FS_FOpenFileRead
diff --git a/code/bspc/l_cmd.h b/code/bspc/l_cmd.h
deleted file mode 100644
index 32a27b5..0000000
--- a/code/bspc/l_cmd.h
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-// cmdlib.h
-
-#ifndef SIN
-#define SIN
-#endif //SIN
-
-#ifndef __CMDLIB__
-#define __CMDLIB__
-
-#ifdef _WIN32
-#pragma warning(disable : 4244) // MIPS
-#pragma warning(disable : 4136) // X86
-#pragma warning(disable : 4051) // ALPHA
-
-#pragma warning(disable : 4018) // signed/unsigned mismatch
-#pragma warning(disable : 4305) // truncate from double to float
-#endif
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <ctype.h>
-#include <time.h>
-#include <stdarg.h>
-
-#ifndef __BYTEBOOL__
-#define __BYTEBOOL__
-typedef enum {false, true} qboolean;
-typedef unsigned char byte;
-#endif
-
-// the dec offsetof macro doesnt work very well...
-#define myoffsetof(type,identifier) ((size_t)&((type *)0)->identifier)
-
-
-// set these before calling CheckParm
-extern int myargc;
-extern char **myargv;
-
-char *strupr (char *in);
-char *strlower (char *in);
-int Q_strncasecmp (char *s1, char *s2, int n);
-int Q_strcasecmp (char *s1, char *s2);
-void Q_getwd (char *out);
-
-int Q_filelength (FILE *f);
-int FileTime (char *path);
-
-void Q_mkdir (char *path);
-
-extern char qdir[1024];
-extern char gamedir[1024];
-void SetQdirFromPath (char *path);
-char *ExpandArg (char *path); // from cmd line
-char *ExpandPath (char *path); // from scripts
-char *ExpandPathAndArchive (char *path);
-
-
-double I_FloatTime (void);
-
-void Error(char *error, ...);
-void Warning(char *warning, ...);
-
-int CheckParm (char *check);
-
-FILE *SafeOpenWrite (char *filename);
-FILE *SafeOpenRead (char *filename);
-void SafeRead (FILE *f, void *buffer, int count);
-void SafeWrite (FILE *f, void *buffer, int count);
-
-int LoadFile (char *filename, void **bufferptr, int offset, int length);
-int TryLoadFile (char *filename, void **bufferptr);
-void SaveFile (char *filename, void *buffer, int count);
-qboolean FileExists (char *filename);
-
-void DefaultExtension (char *path, char *extension);
-void DefaultPath (char *path, char *basepath);
-void StripFilename (char *path);
-void StripExtension (char *path);
-
-void ExtractFilePath (char *path, char *dest);
-void ExtractFileBase (char *path, char *dest);
-void ExtractFileExtension (char *path, char *dest);
-
-int ParseNum (char *str);
-
-short BigShort (short l);
-short LittleShort (short l);
-int BigLong (int l);
-int LittleLong (int l);
-float BigFloat (float l);
-float LittleFloat (float l);
-
-#ifdef SIN
-unsigned short BigUnsignedShort (unsigned short l);
-unsigned short LittleUnsignedShort (unsigned short l);
-unsigned BigUnsigned (unsigned l);
-unsigned LittleUnsigned (unsigned l);
-#endif
-
-
-char *COM_Parse (char *data);
-
-extern char com_token[1024];
-extern qboolean com_eof;
-
-char *copystring(char *s);
-
-
-void CRC_Init(unsigned short *crcvalue);
-void CRC_ProcessByte(unsigned short *crcvalue, byte data);
-unsigned short CRC_Value(unsigned short crcvalue);
-
-void CreatePath (char *path);
-void QCopyFile (char *from, char *to);
-
-extern qboolean archive;
-extern char archivedir[1024];
-
-
-extern qboolean verbose;
-void qprintf (char *format, ...);
-
-void ExpandWildcards (int *argc, char ***argv);
-
-
-// for compression routines
-typedef struct
-{
- byte *data;
- int count;
-} cblock_t;
-
-#endif
-
diff --git a/code/bspc/l_log.c b/code/bspc/l_log.c
deleted file mode 100644
index 2b507e4..0000000
--- a/code/bspc/l_log.c
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "qbsp.h"
-
-#define MAX_LOGFILENAMESIZE 1024
-
-typedef struct logfile_s
-{
- char filename[MAX_LOGFILENAMESIZE];
- FILE *fp;
- int numwrites;
-} logfile_t;
-
-logfile_t logfile;
-
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void Log_Open(char *filename)
-{
- if (!filename || !strlen(filename))
- {
- printf("openlog <filename>\n");
- return;
- } //end if
- if (logfile.fp)
- {
- printf("log file %s is already opened\n", logfile.filename);
- return;
- } //end if
- logfile.fp = fopen(filename, "wb");
- if (!logfile.fp)
- {
- printf("can't open the log file %s\n", filename);
- return;
- } //end if
- strncpy(logfile.filename, filename, MAX_LOGFILENAMESIZE);
- printf("Opened log %s\n", logfile.filename);
-} //end of the function Log_Create
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void Log_Close(void)
-{
- if (!logfile.fp)
- {
- printf("no log file to close\n");
- return;
- } //end if
- if (fclose(logfile.fp))
- {
- printf("can't close log file %s\n", logfile.filename);
- return;
- } //end if
- logfile.fp = NULL;
- printf("Closed log %s\n", logfile.filename);
-} //end of the function Log_Close
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void Log_Shutdown(void)
-{
- if (logfile.fp) Log_Close();
-} //end of the function Log_Shutdown
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void Log_UnifyEndOfLine(char *buf)
-{
- int i;
-
- for (i = 0; buf[i]; i++)
- {
- if (buf[i] == '\n')
- {
- if (i <= 0 || buf[i-1] != '\r')
- {
- memmove(&buf[i+1], &buf[i], strlen(&buf[i])+1);
- buf[i] = '\r';
- i++;
- } //end if
- } //end if
- } //end for
-} //end of the function Log_UnifyEndOfLine
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void Log_Print(char *fmt, ...)
-{
- va_list ap;
- char buf[2048];
-
- va_start(ap, fmt);
- vsprintf(buf, fmt, ap);
- va_end(ap);
-
- if (verbose)
- {
-#ifdef WINBSPC
- WinBSPCPrint(buf);
-#else
- printf("%s", buf);
-#endif //WINBSPS
- } //end if
-
- if (logfile.fp)
- {
- Log_UnifyEndOfLine(buf);
- fprintf(logfile.fp, "%s", buf);
- fflush(logfile.fp);
- } //end if
-} //end of the function Log_Print
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void Log_Write(char *fmt, ...)
-{
- va_list ap;
- char buf[2048];
-
- if (!logfile.fp) return;
- va_start(ap, fmt);
- vsprintf(buf, fmt, ap);
- va_end(ap);
- Log_UnifyEndOfLine(buf);
- fprintf(logfile.fp, "%s", buf);
- fflush(logfile.fp);
-} //end of the function Log_Write
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void Log_WriteTimeStamped(char *fmt, ...)
-{
- va_list ap;
-
- if (!logfile.fp) return;
-/* fprintf(logfile.fp, "%d %02d:%02d:%02d:%02d ",
- logfile.numwrites,
- (int) (botlibglobals.time / 60 / 60),
- (int) (botlibglobals.time / 60),
- (int) (botlibglobals.time),
- (int) ((int) (botlibglobals.time * 100)) -
- ((int) botlibglobals.time) * 100);*/
- va_start(ap, fmt);
- vfprintf(logfile.fp, fmt, ap);
- va_end(ap);
- logfile.numwrites++;
- fflush(logfile.fp);
-} //end of the function Log_Write
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-FILE *Log_FileStruct(void)
-{
- return logfile.fp;
-} //end of the function Log_FileStruct
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void Log_Flush(void)
-{
- if (logfile.fp) fflush(logfile.fp);
-} //end of the function Log_Flush
-
diff --git a/code/bspc/l_log.h b/code/bspc/l_log.h
deleted file mode 100644
index 7871e54..0000000
--- a/code/bspc/l_log.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-//open a log file
-void Log_Open(char *filename);
-//close the current log file
-void Log_Close(void);
-//close log file if present
-void Log_Shutdown(void);
-//print on stdout and write to the current opened log file
-void Log_Print(char *fmt, ...);
-//write to the current opened log file
-void Log_Write(char *fmt, ...);
-//write to the current opened log file with a time stamp
-void Log_WriteTimeStamped(char *fmt, ...);
-//returns the log file structure
-FILE *Log_FileStruct(void);
-//flush log file
-void Log_Flush(void);
-
-#ifdef WINBSPC
-void WinBSPCPrint(char *str);
-#endif //WINBSPC
diff --git a/code/bspc/l_math.c b/code/bspc/l_math.c
deleted file mode 100644
index dab26bf..0000000
--- a/code/bspc/l_math.c
+++ /dev/null
@@ -1,289 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-// mathlib.c -- math primitives
-
-#include "l_cmd.h"
-#include "l_math.h"
-
-vec3_t vec3_origin = {0,0,0};
-
-void AngleVectors (const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up)
-{
- float angle;
- static float sr, sp, sy, cr, cp, cy;
- // static to help MS compiler fp bugs
-
- angle = angles[YAW] * (M_PI*2 / 360);
- sy = sin(angle);
- cy = cos(angle);
- angle = angles[PITCH] * (M_PI*2 / 360);
- sp = sin(angle);
- cp = cos(angle);
- angle = angles[ROLL] * (M_PI*2 / 360);
- sr = sin(angle);
- cr = cos(angle);
-
- if (forward)
- {
- forward[0] = cp*cy;
- forward[1] = cp*sy;
- forward[2] = -sp;
- }
- if (right)
- {
- right[0] = (-1*sr*sp*cy+-1*cr*-sy);
- right[1] = (-1*sr*sp*sy+-1*cr*cy);
- right[2] = -1*sr*cp;
- }
- if (up)
- {
- up[0] = (cr*sp*cy+-sr*-sy);
- up[1] = (cr*sp*sy+-sr*cy);
- up[2] = cr*cp;
- }
-}
-
-/*
-=================
-RadiusFromBounds
-=================
-*/
-float RadiusFromBounds( const vec3_t mins, const vec3_t maxs ) {
- int i;
- vec3_t corner;
- float a, b;
-
- for (i=0 ; i<3 ; i++) {
- a = fabs( mins[i] );
- b = fabs( maxs[i] );
- corner[i] = a > b ? a : b;
- }
-
- return VectorLength (corner);
-}
-
-/*
-================
-R_ConcatRotations
-================
-*/
-void R_ConcatRotations (float in1[3][3], float in2[3][3], float out[3][3])
-{
- out[0][0] = in1[0][0] * in2[0][0] + in1[0][1] * in2[1][0] +
- in1[0][2] * in2[2][0];
- out[0][1] = in1[0][0] * in2[0][1] + in1[0][1] * in2[1][1] +
- in1[0][2] * in2[2][1];
- out[0][2] = in1[0][0] * in2[0][2] + in1[0][1] * in2[1][2] +
- in1[0][2] * in2[2][2];
- out[1][0] = in1[1][0] * in2[0][0] + in1[1][1] * in2[1][0] +
- in1[1][2] * in2[2][0];
- out[1][1] = in1[1][0] * in2[0][1] + in1[1][1] * in2[1][1] +
- in1[1][2] * in2[2][1];
- out[1][2] = in1[1][0] * in2[0][2] + in1[1][1] * in2[1][2] +
- in1[1][2] * in2[2][2];
- out[2][0] = in1[2][0] * in2[0][0] + in1[2][1] * in2[1][0] +
- in1[2][2] * in2[2][0];
- out[2][1] = in1[2][0] * in2[0][1] + in1[2][1] * in2[1][1] +
- in1[2][2] * in2[2][1];
- out[2][2] = in1[2][0] * in2[0][2] + in1[2][1] * in2[1][2] +
- in1[2][2] * in2[2][2];
-}
-
-void AxisClear( vec3_t axis[3] ) {
- axis[0][0] = 1;
- axis[0][1] = 0;
- axis[0][2] = 0;
- axis[1][0] = 0;
- axis[1][1] = 1;
- axis[1][2] = 0;
- axis[2][0] = 0;
- axis[2][1] = 0;
- axis[2][2] = 1;
-}
-
-float VectorLengthSquared(vec3_t v) {
- return DotProduct(v, v);
-}
-
-double VectorLength(vec3_t v)
-{
- int i;
- double length;
-
- length = 0;
- for (i=0 ; i< 3 ; i++)
- length += v[i]*v[i];
- length = sqrt (length); // FIXME
-
- return length;
-}
-
-qboolean VectorCompare (vec3_t v1, vec3_t v2)
-{
- int i;
-
- for (i=0 ; i<3 ; i++)
- if (fabs(v1[i]-v2[i]) > EQUAL_EPSILON)
- return false;
-
- return true;
-}
-
-vec_t Q_rint (vec_t in)
-{
- return floor(in + 0.5);
-}
-
-void CrossProduct (const vec3_t v1, const vec3_t v2, vec3_t cross)
-{
- cross[0] = v1[1]*v2[2] - v1[2]*v2[1];
- cross[1] = v1[2]*v2[0] - v1[0]*v2[2];
- cross[2] = v1[0]*v2[1] - v1[1]*v2[0];
-}
-
-void _VectorMA (vec3_t va, double scale, vec3_t vb, vec3_t vc)
-{
- vc[0] = va[0] + scale*vb[0];
- vc[1] = va[1] + scale*vb[1];
- vc[2] = va[2] + scale*vb[2];
-}
-
-vec_t _DotProduct (vec3_t v1, vec3_t v2)
-{
- return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2];
-}
-
-void _VectorSubtract (vec3_t va, vec3_t vb, vec3_t out)
-{
- out[0] = va[0]-vb[0];
- out[1] = va[1]-vb[1];
- out[2] = va[2]-vb[2];
-}
-
-void _VectorAdd (vec3_t va, vec3_t vb, vec3_t out)
-{
- out[0] = va[0]+vb[0];
- out[1] = va[1]+vb[1];
- out[2] = va[2]+vb[2];
-}
-
-void _VectorCopy (vec3_t in, vec3_t out)
-{
- out[0] = in[0];
- out[1] = in[1];
- out[2] = in[2];
-}
-
-void _VectorScale (vec3_t v, vec_t scale, vec3_t out)
-{
- out[0] = v[0] * scale;
- out[1] = v[1] * scale;
- out[2] = v[2] * scale;
-}
-
-vec_t VectorNormalize(vec3_t inout)
-{
- vec_t length, ilength;
-
- length = sqrt (inout[0]*inout[0] + inout[1]*inout[1] + inout[2]*inout[2]);
- if (length == 0)
- {
- VectorClear (inout);
- return 0;
- }
-
- ilength = 1.0/length;
- inout[0] = inout[0]*ilength;
- inout[1] = inout[1]*ilength;
- inout[2] = inout[2]*ilength;
-
- return length;
-}
-
-vec_t VectorNormalize2(const vec3_t in, vec3_t out)
-{
- vec_t length, ilength;
-
- length = sqrt (in[0]*in[0] + in[1]*in[1] + in[2]*in[2]);
- if (length == 0)
- {
- VectorClear (out);
- return 0;
- }
-
- ilength = 1.0/length;
- out[0] = in[0]*ilength;
- out[1] = in[1]*ilength;
- out[2] = in[2]*ilength;
-
- return length;
-}
-
-vec_t ColorNormalize (vec3_t in, vec3_t out)
-{
- float max, scale;
-
- max = in[0];
- if (in[1] > max)
- max = in[1];
- if (in[2] > max)
- max = in[2];
-
- if (max == 0)
- return 0;
-
- scale = 1.0 / max;
-
- VectorScale (in, scale, out);
-
- return max;
-}
-
-
-
-void VectorInverse (vec3_t v)
-{
- v[0] = -v[0];
- v[1] = -v[1];
- v[2] = -v[2];
-}
-
-void ClearBounds(vec3_t mins, vec3_t maxs)
-{
- mins[0] = mins[1] = mins[2] = 99999;
- maxs[0] = maxs[1] = maxs[2] = -99999;
-}
-
-void AddPointToBounds(const vec3_t v, vec3_t mins, vec3_t maxs)
-{
- int i;
- vec_t val;
-
- for (i=0 ; i<3 ; i++)
- {
- val = v[i];
- if (val < mins[i])
- mins[i] = val;
- if (val > maxs[i])
- maxs[i] = val;
- }
-}
diff --git a/code/bspc/l_math.h b/code/bspc/l_math.h
deleted file mode 100644
index f5d31e9..0000000
--- a/code/bspc/l_math.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-#ifndef __MATHLIB__
-#define __MATHLIB__
-
-// mathlib.h
-
-#include <math.h>
-
-#ifdef DOUBLEVEC_T
-typedef double vec_t;
-#else
-typedef float vec_t;
-#endif
-typedef vec_t vec3_t[3];
-typedef vec_t vec4_t[4];
-
-#define SIDE_FRONT 0
-#define SIDE_ON 2
-#define SIDE_BACK 1
-#define SIDE_CROSS -2
-
-#define PITCH 0
-#define YAW 1
-#define ROLL 2
-
-#define Q_PI 3.14159265358979323846
-
-#define DEG2RAD( a ) ( a * M_PI ) / 180.0F
-
-#ifndef M_PI
-#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h
-#endif
-
-extern vec3_t vec3_origin;
-
-#define EQUAL_EPSILON 0.001
-
-qboolean VectorCompare (vec3_t v1, vec3_t v2);
-
-#define DotProduct(x,y) (x[0]*y[0]+x[1]*y[1]+x[2]*y[2])
-#define VectorSubtract(a,b,c) {c[0]=a[0]-b[0];c[1]=a[1]-b[1];c[2]=a[2]-b[2];}
-#define VectorAdd(a,b,c) {c[0]=a[0]+b[0];c[1]=a[1]+b[1];c[2]=a[2]+b[2];}
-#define VectorCopy(a,b) {b[0]=a[0];b[1]=a[1];b[2]=a[2];}
-#define Vector4Copy(a,b) {b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];}
-#define VectorScale(v, s, o) ((o)[0]=(v)[0]*(s),(o)[1]=(v)[1]*(s),(o)[2]=(v)[2]*(s))
-#define VectorClear(x) {x[0] = x[1] = x[2] = 0;}
-#define VectorNegate(x, y) {y[0]=-x[0];y[1]=-x[1];y[2]=-x[2];}
-#define VectorMA(v, s, b, o) ((o)[0]=(v)[0]+(b)[0]*(s),(o)[1]=(v)[1]+(b)[1]*(s),(o)[2]=(v)[2]+(b)[2]*(s))
-
-vec_t Q_rint (vec_t in);
-vec_t _DotProduct (vec3_t v1, vec3_t v2);
-void _VectorSubtract (vec3_t va, vec3_t vb, vec3_t out);
-void _VectorAdd (vec3_t va, vec3_t vb, vec3_t out);
-void _VectorCopy (vec3_t in, vec3_t out);
-void _VectorScale (vec3_t v, vec_t scale, vec3_t out);
-void _VectorMA(vec3_t va, double scale, vec3_t vb, vec3_t vc);
-
-double VectorLength(vec3_t v);
-void CrossProduct(const vec3_t v1, const vec3_t v2, vec3_t cross);
-vec_t VectorNormalize(vec3_t inout);
-vec_t ColorNormalize(vec3_t in, vec3_t out);
-vec_t VectorNormalize2(const vec3_t v, vec3_t out);
-void VectorInverse (vec3_t v);
-
-void ClearBounds (vec3_t mins, vec3_t maxs);
-void AddPointToBounds (const vec3_t v, vec3_t mins, vec3_t maxs);
-
-void AngleVectors (const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up);
-void R_ConcatRotations (float in1[3][3], float in2[3][3], float out[3][3]);
-void RotatePoint(vec3_t point, float matrix[3][3]);
-void CreateRotationMatrix(vec3_t angles, float matrix[3][3]);
-
-#endif
diff --git a/code/bspc/l_mem.c b/code/bspc/l_mem.c
deleted file mode 100644
index ba8d0f4..0000000
--- a/code/bspc/l_mem.c
+++ /dev/null
@@ -1,441 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-#include "qbsp.h"
-#include "l_log.h"
-
-int allocedmemory;
-
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void PrintMemorySize(unsigned long size)
-{
- unsigned long number1, number2, number3;
- number1 = size >> 20;
- number2 = (size & 0xFFFFF) >> 10;
- number3 = (size & 0x3FF);
- if (number1) Log_Print("%ld MB", number1);
- if (number1 && number2) Log_Print(" and ");
- if (number2) Log_Print("%ld KB", number2);
- if (number2 && number3) Log_Print(" and ");
- if (number3) Log_Print("%ld bytes", number3);
-} //end of the function PrintFileSize
-
-#ifndef MEMDEBUG
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int MemorySize(void *ptr)
-{
-#if defined(WIN32) || defined(_WIN32)
- #ifdef __WATCOMC__
- //Intel 32 bits memory addressing, 16 bytes aligned
- return (_msize(ptr) + 15) >> 4 << 4;
- #else
- return _msize(ptr);
- #endif
-#else
- return 0;
-#endif
-} //end of the function MemorySize
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void *GetClearedMemory(int size)
-{
- void *ptr;
-
- ptr = (void *) malloc(size);
- if (!ptr) Error("out of memory");
- memset(ptr, 0, size);
- allocedmemory += MemorySize(ptr);
- return ptr;
-} //end of the function GetClearedMemory
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void *GetMemory(unsigned long size)
-{
- void *ptr;
- ptr = malloc(size);
- if (!ptr) Error("out of memory");
- allocedmemory += MemorySize(ptr);
- return ptr;
-} //end of the function GetMemory
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void FreeMemory(void *ptr)
-{
- allocedmemory -= MemorySize(ptr);
- free(ptr);
-} //end of the function FreeMemory
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int TotalAllocatedMemory(void)
-{
- return allocedmemory;
-} //end of the function TotalAllocatedMemory
-
-#else
-
-#define MEM_ID 0x12345678l
-
-int totalmemorysize;
-int numblocks;
-
-typedef struct memoryblock_s
-{
- unsigned long int id;
- void *ptr;
- int size;
-#ifdef MEMDEBUG
- char *label;
- char *file;
- int line;
-#endif //MEMDEBUG
- struct memoryblock_s *prev, *next;
-} memoryblock_t;
-
-memoryblock_t *memory;
-
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void LinkMemoryBlock(memoryblock_t *block)
-{
- block->prev = NULL;
- block->next = memory;
- if (memory) memory->prev = block;
- memory = block;
-} //end of the function LinkMemoryBlock
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void UnlinkMemoryBlock(memoryblock_t *block)
-{
- if (block->prev) block->prev->next = block->next;
- else memory = block->next;
- if (block->next) block->next->prev = block->prev;
-} //end of the function UnlinkMemoryBlock
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-#ifdef MEMDEBUG
-void *GetMemoryDebug(unsigned long size, char *label, char *file, int line)
-#else
-void *GetMemory(unsigned long size)
-#endif //MEMDEBUG
-{
- void *ptr;
- memoryblock_t *block;
-
- ptr = malloc(size + sizeof(memoryblock_t));
- block = (memoryblock_t *) ptr;
- block->id = MEM_ID;
- block->ptr = (char *) ptr + sizeof(memoryblock_t);
- block->size = size + sizeof(memoryblock_t);
-#ifdef MEMDEBUG
- block->label = label;
- block->file = file;
- block->line = line;
-#endif //MEMDEBUG
- LinkMemoryBlock(block);
- totalmemorysize += block->size;
- numblocks++;
- return block->ptr;
-} //end of the function GetMemoryDebug
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-#ifdef MEMDEBUG
-void *GetClearedMemoryDebug(unsigned long size, char *label, char *file, int line)
-#else
-void *GetClearedMemory(unsigned long size)
-#endif //MEMDEBUG
-{
- void *ptr;
-#ifdef MEMDEBUG
- ptr = GetMemoryDebug(size, label, file, line);
-#else
- ptr = GetMemory(size);
-#endif //MEMDEBUG
- memset(ptr, 0, size);
- return ptr;
-} //end of the function GetClearedMemoryLabelled
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void *GetClearedHunkMemory(unsigned long size)
-{
- return GetClearedMemory(size);
-} //end of the function GetClearedHunkMemory
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void *GetHunkMemory(unsigned long size)
-{
- return GetMemory(size);
-} //end of the function GetHunkMemory
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-memoryblock_t *BlockFromPointer(void *ptr, char *str)
-{
- memoryblock_t *block;
-
- if (!ptr)
- {
-#ifdef MEMDEBUG
- //char *crash = (char *) NULL;
- //crash[0] = 1;
- Error("%s: NULL pointer\n", str);
-#endif MEMDEBUG
- return NULL;
- } //end if
- block = (memoryblock_t *) ((char *) ptr - sizeof(memoryblock_t));
- if (block->id != MEM_ID)
- {
- Error("%s: invalid memory block\n", str);
- } //end if
- if (block->ptr != ptr)
- {
-
- Error("%s: memory block pointer invalid\n", str);
- } //end if
- return block;
-} //end of the function BlockFromPointer
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void FreeMemory(void *ptr)
-{
- memoryblock_t *block;
-
- block = BlockFromPointer(ptr, "FreeMemory");
- if (!block) return;
- UnlinkMemoryBlock(block);
- totalmemorysize -= block->size;
- numblocks--;
- //
- free(block);
-} //end of the function FreeMemory
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int MemoryByteSize(void *ptr)
-{
- memoryblock_t *block;
-
- block = BlockFromPointer(ptr, "MemoryByteSize");
- if (!block) return 0;
- return block->size;
-} //end of the function MemoryByteSize
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int MemorySize(void *ptr)
-{
- return MemoryByteSize(ptr);
-} //end of the function MemorySize
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void PrintUsedMemorySize(void)
-{
- printf("total botlib memory: %d KB\n", totalmemorysize >> 10);
- printf("total memory blocks: %d\n", numblocks);
-} //end of the function PrintUsedMemorySize
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void PrintMemoryLabels(void)
-{
- memoryblock_t *block;
- int i;
-
- PrintUsedMemorySize();
- i = 0;
- for (block = memory; block; block = block->next)
- {
-#ifdef MEMDEBUG
- Log_Write("%6d, %p, %8d: %24s line %6d: %s", i, block->ptr, block->size, block->file, block->line, block->label);
-#endif //MEMDEBUG
- i++;
- } //end for
-} //end of the function PrintMemoryLabels
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void DumpMemory(void)
-{
- memoryblock_t *block;
-
- for (block = memory; block; block = memory)
- {
- FreeMemory(block->ptr);
- } //end for
- totalmemorysize = 0;
-} //end of the function DumpMemory
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int TotalAllocatedMemory(void)
-{
- return totalmemorysize;
-} //end of the function TotalAllocatedMemory
-#endif
-
-//===========================================================================
-// Q3 Hunk and Z_ memory management
-//===========================================================================
-
-typedef struct memhunk_s
-{
- void *ptr;
- struct memhunk_s *next;
-} memhunk_t;
-
-memhunk_t *memhunk_high;
-memhunk_t *memhunk_low;
-int memhunk_high_size = 16 * 1024 * 1024;
-int memhunk_low_size = 0;
-
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void Hunk_ClearHigh(void)
-{
- memhunk_t *h, *nexth;
-
- for (h = memhunk_high; h; h = nexth)
- {
- nexth = h->next;
- FreeMemory(h);
- } //end for
- memhunk_high = NULL;
- memhunk_high_size = 16 * 1024 * 1024;
-} //end of the function Hunk_ClearHigh
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void *Hunk_Alloc(int size)
-{
- memhunk_t *h;
-
- if (!size) return (void *) memhunk_high_size;
- //
- h = GetClearedMemory(size + sizeof(memhunk_t));
- h->ptr = (char *) h + sizeof(memhunk_t);
- h->next = memhunk_high;
- memhunk_high = h;
- memhunk_high_size -= size;
- return h->ptr;
-} //end of the function Hunk_Alloc
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void *Z_Malloc(int size)
-{
- return GetClearedMemory(size);
-} //end of the function Z_Malloc
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void Z_Free (void *ptr)
-{
- FreeMemory(ptr);
-} //end of the function Z_Free
diff --git a/code/bspc/l_mem.h b/code/bspc/l_mem.h
deleted file mode 100644
index 8a5231f..0000000
--- a/code/bspc/l_mem.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-
-//=============================================================================
-
-// memory.h
-//#define MEMDEBUG
-#undef MEMDEBUG
-
-#ifndef MEMDEBUG
-
-void *GetClearedMemory(int size);
-void *GetMemory(unsigned long size);
-
-#else
-
-#define GetMemory(size) GetMemoryDebug(size, #size, __FILE__, __LINE__);
-#define GetClearedMemory(size) GetClearedMemoryDebug(size, #size, __FILE__, __LINE__);
-//allocate a memory block of the given size
-void *GetMemoryDebug(unsigned long size, char *label, char *file, int line);
-//allocate a memory block of the given size and clear it
-void *GetClearedMemoryDebug(unsigned long size, char *label, char *file, int line);
-//
-void PrintMemoryLabels(void);
-#endif //MEMDEBUG
-
-void FreeMemory(void *ptr);
-int MemorySize(void *ptr);
-void PrintMemorySize(unsigned long size);
-int TotalAllocatedMemory(void);
-
diff --git a/code/bspc/l_poly.c b/code/bspc/l_poly.c
deleted file mode 100644
index 5e0ecda..0000000
--- a/code/bspc/l_poly.c
+++ /dev/null
@@ -1,1411 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-#include <malloc.h>
-#include "l_cmd.h"
-#include "l_math.h"
-#include "l_poly.h"
-#include "l_log.h"
-#include "l_mem.h"
-
-#define BOGUS_RANGE 65535
-
-extern int numthreads;
-
-// counters are only bumped when running single threaded,
-// because they are an awefull coherence problem
-int c_active_windings;
-int c_peak_windings;
-int c_winding_allocs;
-int c_winding_points;
-int c_windingmemory;
-int c_peak_windingmemory;
-
-char windingerror[1024];
-
-void pw(winding_t *w)
-{
- int i;
- for (i=0 ; i<w->numpoints ; i++)
- printf ("(%5.3f, %5.3f, %5.3f)\n",w->p[i][0], w->p[i][1],w->p[i][2]);
-}
-
-
-void ResetWindings(void)
-{
- c_active_windings = 0;
- c_peak_windings = 0;
- c_winding_allocs = 0;
- c_winding_points = 0;
- c_windingmemory = 0;
- c_peak_windingmemory = 0;
-
- strcpy(windingerror, "");
-} //end of the function ResetWindings
-/*
-=============
-AllocWinding
-=============
-*/
-winding_t *AllocWinding (int points)
-{
- winding_t *w;
- int s;
-
- s = sizeof(vec_t)*3*points + sizeof(int);
- w = GetMemory(s);
- memset(w, 0, s);
-
- if (numthreads == 1)
- {
- c_winding_allocs++;
- c_winding_points += points;
- c_active_windings++;
- if (c_active_windings > c_peak_windings)
- c_peak_windings = c_active_windings;
- c_windingmemory += MemorySize(w);
- if (c_windingmemory > c_peak_windingmemory)
- c_peak_windingmemory = c_windingmemory;
- } //end if
- return w;
-} //end of the function AllocWinding
-
-void FreeWinding (winding_t *w)
-{
- if (*(unsigned *)w == 0xdeaddead)
- Error ("FreeWinding: freed a freed winding");
-
- if (numthreads == 1)
- {
- c_active_windings--;
- c_windingmemory -= MemorySize(w);
- } //end if
-
- *(unsigned *)w = 0xdeaddead;
-
- FreeMemory(w);
-} //end of the function FreeWinding
-
-int WindingMemory(void)
-{
- return c_windingmemory;
-} //end of the function WindingMemory
-
-int WindingPeakMemory(void)
-{
- return c_peak_windingmemory;
-} //end of the function WindingPeakMemory
-
-int ActiveWindings(void)
-{
- return c_active_windings;
-} //end of the function ActiveWindings
-/*
-============
-RemoveColinearPoints
-============
-*/
-int c_removed;
-
-void RemoveColinearPoints (winding_t *w)
-{
- int i, j, k;
- vec3_t v1, v2;
- int nump;
- vec3_t p[MAX_POINTS_ON_WINDING];
-
- nump = 0;
- for (i=0 ; i<w->numpoints ; i++)
- {
- j = (i+1)%w->numpoints;
- k = (i+w->numpoints-1)%w->numpoints;
- VectorSubtract (w->p[j], w->p[i], v1);
- VectorSubtract (w->p[i], w->p[k], v2);
- VectorNormalize(v1);
- VectorNormalize(v2);
- if (DotProduct(v1, v2) < 0.999)
- {
- if (nump >= MAX_POINTS_ON_WINDING)
- Error("RemoveColinearPoints: MAX_POINTS_ON_WINDING");
- VectorCopy (w->p[i], p[nump]);
- nump++;
- }
- }
-
- if (nump == w->numpoints)
- return;
-
- if (numthreads == 1)
- c_removed += w->numpoints - nump;
- w->numpoints = nump;
- memcpy (w->p, p, nump*sizeof(p[0]));
-}
-
-/*
-============
-WindingPlane
-============
-*/
-void WindingPlane (winding_t *w, vec3_t normal, vec_t *dist)
-{
- vec3_t v1, v2;
- int i;
-
- //find two vectors each longer than 0.5 units
- for (i = 0; i < w->numpoints; i++)
- {
- VectorSubtract(w->p[(i+1) % w->numpoints], w->p[i], v1);
- VectorSubtract(w->p[(i+2) % w->numpoints], w->p[i], v2);
- if (VectorLength(v1) > 0.5 && VectorLength(v2) > 0.5) break;
- } //end for
- CrossProduct(v2, v1, normal);
- VectorNormalize(normal);
- *dist = DotProduct(w->p[0], normal);
-} //end of the function WindingPlane
-
-/*
-=============
-WindingArea
-=============
-*/
-vec_t WindingArea (winding_t *w)
-{
- int i;
- vec3_t d1, d2, cross;
- vec_t total;
-
- total = 0;
- for (i=2 ; i<w->numpoints ; i++)
- {
- VectorSubtract (w->p[i-1], w->p[0], d1);
- VectorSubtract (w->p[i], w->p[0], d2);
- CrossProduct (d1, d2, cross);
- total += 0.5 * VectorLength ( cross );
- }
- return total;
-}
-
-void WindingBounds (winding_t *w, vec3_t mins, vec3_t maxs)
-{
- vec_t v;
- int i,j;
-
- mins[0] = mins[1] = mins[2] = 99999;
- maxs[0] = maxs[1] = maxs[2] = -99999;
-
- for (i=0 ; i<w->numpoints ; i++)
- {
- for (j=0 ; j<3 ; j++)
- {
- v = w->p[i][j];
- if (v < mins[j])
- mins[j] = v;
- if (v > maxs[j])
- maxs[j] = v;
- }
- }
-}
-
-/*
-=============
-WindingCenter
-=============
-*/
-void WindingCenter (winding_t *w, vec3_t center)
-{
- int i;
- float scale;
-
- VectorCopy (vec3_origin, center);
- for (i=0 ; i<w->numpoints ; i++)
- VectorAdd (w->p[i], center, center);
-
- scale = 1.0/w->numpoints;
- VectorScale (center, scale, center);
-}
-
-/*
-=================
-BaseWindingForPlane
-=================
-*/
-winding_t *BaseWindingForPlane (vec3_t normal, vec_t dist)
-{
- int i, x;
- vec_t max, v;
- vec3_t org, vright, vup;
- winding_t *w;
-
-// find the major axis
-
- max = -BOGUS_RANGE;
- x = -1;
- for (i=0 ; i<3; i++)
- {
- v = fabs(normal[i]);
- if (v > max)
- {
- x = i;
- max = v;
- }
- }
- if (x==-1)
- Error ("BaseWindingForPlane: no axis found");
-
- VectorCopy (vec3_origin, vup);
- switch (x)
- {
- case 0:
- case 1:
- vup[2] = 1;
- break;
- case 2:
- vup[0] = 1;
- break;
- }
-
- v = DotProduct (vup, normal);
- VectorMA (vup, -v, normal, vup);
- VectorNormalize (vup);
-
- VectorScale (normal, dist, org);
-
- CrossProduct (vup, normal, vright);
-
- VectorScale (vup, BOGUS_RANGE, vup);
- VectorScale (vright, BOGUS_RANGE, vright);
-
-// project a really big axis aligned box onto the plane
- w = AllocWinding (4);
-
- VectorSubtract (org, vright, w->p[0]);
- VectorAdd (w->p[0], vup, w->p[0]);
-
- VectorAdd (org, vright, w->p[1]);
- VectorAdd (w->p[1], vup, w->p[1]);
-
- VectorAdd (org, vright, w->p[2]);
- VectorSubtract (w->p[2], vup, w->p[2]);
-
- VectorSubtract (org, vright, w->p[3]);
- VectorSubtract (w->p[3], vup, w->p[3]);
-
- w->numpoints = 4;
-
- return w;
-}
-
-/*
-==================
-CopyWinding
-==================
-*/
-winding_t *CopyWinding (winding_t *w)
-{
- int size;
- winding_t *c;
-
- c = AllocWinding (w->numpoints);
- size = (int)((winding_t *)0)->p[w->numpoints];
- memcpy (c, w, size);
- return c;
-}
-
-/*
-==================
-ReverseWinding
-==================
-*/
-winding_t *ReverseWinding (winding_t *w)
-{
- int i;
- winding_t *c;
-
- c = AllocWinding (w->numpoints);
- for (i=0 ; i<w->numpoints ; i++)
- {
- VectorCopy (w->p[w->numpoints-1-i], c->p[i]);
- }
- c->numpoints = w->numpoints;
- return c;
-}
-
-
-/*
-=============
-ClipWindingEpsilon
-=============
-*/
-void ClipWindingEpsilon (winding_t *in, vec3_t normal, vec_t dist,
- vec_t epsilon, winding_t **front, winding_t **back)
-{
- vec_t dists[MAX_POINTS_ON_WINDING+4];
- int sides[MAX_POINTS_ON_WINDING+4];
- int counts[3];
- //MrElusive: DOH can't use statics when unsing multithreading!!!
- vec_t dot; // VC 4.2 optimizer bug if not static
- int i, j;
- vec_t *p1, *p2;
- vec3_t mid;
- winding_t *f, *b;
- int maxpts;
-
- counts[0] = counts[1] = counts[2] = 0;
-
-// determine sides for each point
- for (i=0 ; i<in->numpoints ; i++)
- {
- dot = DotProduct (in->p[i], normal);
- dot -= dist;
- dists[i] = dot;
- if (dot > epsilon)
- sides[i] = SIDE_FRONT;
- else if (dot < -epsilon)
- sides[i] = SIDE_BACK;
- else
- {
- sides[i] = SIDE_ON;
- }
- counts[sides[i]]++;
- }
- sides[i] = sides[0];
- dists[i] = dists[0];
-
- *front = *back = NULL;
-
- if (!counts[0])
- {
- *back = CopyWinding (in);
- return;
- }
- if (!counts[1])
- {
- *front = CopyWinding (in);
- return;
- }
-
- maxpts = in->numpoints+4; // cant use counts[0]+2 because
- // of fp grouping errors
-
- *front = f = AllocWinding (maxpts);
- *back = b = AllocWinding (maxpts);
-
- for (i=0 ; i<in->numpoints ; i++)
- {
- p1 = in->p[i];
-
- if (sides[i] == SIDE_ON)
- {
- VectorCopy (p1, f->p[f->numpoints]);
- f->numpoints++;
- VectorCopy (p1, b->p[b->numpoints]);
- b->numpoints++;
- continue;
- }
-
- if (sides[i] == SIDE_FRONT)
- {
- VectorCopy (p1, f->p[f->numpoints]);
- f->numpoints++;
- }
- if (sides[i] == SIDE_BACK)
- {
- VectorCopy (p1, b->p[b->numpoints]);
- b->numpoints++;
- }
-
- if (sides[i+1] == SIDE_ON || sides[i+1] == sides[i])
- continue;
-
- // generate a split point
- p2 = in->p[(i+1)%in->numpoints];
-
- dot = dists[i] / (dists[i]-dists[i+1]);
- for (j=0 ; j<3 ; j++)
- { // avoid round off error when possible
- if (normal[j] == 1)
- mid[j] = dist;
- else if (normal[j] == -1)
- mid[j] = -dist;
- else
- mid[j] = p1[j] + dot*(p2[j]-p1[j]);
- }
-
- VectorCopy (mid, f->p[f->numpoints]);
- f->numpoints++;
- VectorCopy (mid, b->p[b->numpoints]);
- b->numpoints++;
- }
-
- if (f->numpoints > maxpts || b->numpoints > maxpts)
- Error ("ClipWinding: points exceeded estimate");
- if (f->numpoints > MAX_POINTS_ON_WINDING || b->numpoints > MAX_POINTS_ON_WINDING)
- Error ("ClipWinding: MAX_POINTS_ON_WINDING");
-}
-
-
-/*
-=============
-ChopWindingInPlace
-=============
-*/
-void ChopWindingInPlace (winding_t **inout, vec3_t normal, vec_t dist, vec_t epsilon)
-{
- winding_t *in;
- vec_t dists[MAX_POINTS_ON_WINDING+4];
- int sides[MAX_POINTS_ON_WINDING+4];
- int counts[3];
- //MrElusive: DOH can't use statics when unsing multithreading!!!
- vec_t dot; // VC 4.2 optimizer bug if not static
- int i, j;
- vec_t *p1, *p2;
- vec3_t mid;
- winding_t *f;
- int maxpts;
-
- in = *inout;
- counts[0] = counts[1] = counts[2] = 0;
-
-// determine sides for each point
- for (i=0 ; i<in->numpoints ; i++)
- {
- dot = DotProduct (in->p[i], normal);
- dot -= dist;
- dists[i] = dot;
- if (dot > epsilon)
- sides[i] = SIDE_FRONT;
- else if (dot < -epsilon)
- sides[i] = SIDE_BACK;
- else
- {
- sides[i] = SIDE_ON;
- }
- counts[sides[i]]++;
- }
- sides[i] = sides[0];
- dists[i] = dists[0];
-
- if (!counts[0])
- {
- FreeWinding (in);
- *inout = NULL;
- return;
- }
- if (!counts[1])
- return; // inout stays the same
-
- maxpts = in->numpoints+4; // cant use counts[0]+2 because
- // of fp grouping errors
-
- f = AllocWinding (maxpts);
-
- for (i=0 ; i<in->numpoints ; i++)
- {
- p1 = in->p[i];
-
- if (sides[i] == SIDE_ON)
- {
- VectorCopy (p1, f->p[f->numpoints]);
- f->numpoints++;
- continue;
- }
-
- if (sides[i] == SIDE_FRONT)
- {
- VectorCopy (p1, f->p[f->numpoints]);
- f->numpoints++;
- }
-
- if (sides[i+1] == SIDE_ON || sides[i+1] == sides[i])
- continue;
-
- // generate a split point
- p2 = in->p[(i+1)%in->numpoints];
-
- dot = dists[i] / (dists[i]-dists[i+1]);
- for (j=0 ; j<3 ; j++)
- { // avoid round off error when possible
- if (normal[j] == 1)
- mid[j] = dist;
- else if (normal[j] == -1)
- mid[j] = -dist;
- else
- mid[j] = p1[j] + dot*(p2[j]-p1[j]);
- }
-
- VectorCopy (mid, f->p[f->numpoints]);
- f->numpoints++;
- }
-
- if (f->numpoints > maxpts)
- Error ("ClipWinding: points exceeded estimate");
- if (f->numpoints > MAX_POINTS_ON_WINDING)
- Error ("ClipWinding: MAX_POINTS_ON_WINDING");
-
- FreeWinding (in);
- *inout = f;
-}
-
-
-/*
-=================
-ChopWinding
-
-Returns the fragment of in that is on the front side
-of the cliping plane. The original is freed.
-=================
-*/
-winding_t *ChopWinding (winding_t *in, vec3_t normal, vec_t dist)
-{
- winding_t *f, *b;
-
- ClipWindingEpsilon (in, normal, dist, ON_EPSILON, &f, &b);
- FreeWinding (in);
- if (b)
- FreeWinding (b);
- return f;
-}
-
-
-/*
-=================
-CheckWinding
-
-=================
-*/
-void CheckWinding (winding_t *w)
-{
- int i, j;
- vec_t *p1, *p2;
- vec_t d, edgedist;
- vec3_t dir, edgenormal, facenormal;
- vec_t area;
- vec_t facedist;
-
- if (w->numpoints < 3)
- Error ("CheckWinding: %i points",w->numpoints);
-
- area = WindingArea(w);
- if (area < 1)
- Error ("CheckWinding: %f area", area);
-
- WindingPlane (w, facenormal, &facedist);
-
- for (i=0 ; i<w->numpoints ; i++)
- {
- p1 = w->p[i];
-
- for (j=0 ; j<3 ; j++)
- if (p1[j] > BOGUS_RANGE || p1[j] < -BOGUS_RANGE)
- Error ("CheckWinding: BUGUS_RANGE: %f",p1[j]);
-
- j = i+1 == w->numpoints ? 0 : i+1;
-
- // check the point is on the face plane
- d = DotProduct (p1, facenormal) - facedist;
- if (d < -ON_EPSILON || d > ON_EPSILON)
- Error ("CheckWinding: point off plane");
-
- // check the edge isnt degenerate
- p2 = w->p[j];
- VectorSubtract (p2, p1, dir);
-
- if (VectorLength (dir) < ON_EPSILON)
- Error ("CheckWinding: degenerate edge");
-
- CrossProduct (facenormal, dir, edgenormal);
- VectorNormalize (edgenormal);
- edgedist = DotProduct (p1, edgenormal);
- edgedist += ON_EPSILON;
-
- // all other points must be on front side
- for (j=0 ; j<w->numpoints ; j++)
- {
- if (j == i)
- continue;
- d = DotProduct (w->p[j], edgenormal);
- if (d > edgedist)
- Error ("CheckWinding: non-convex");
- }
- }
-}
-
-
-/*
-============
-WindingOnPlaneSide
-============
-*/
-int WindingOnPlaneSide (winding_t *w, vec3_t normal, vec_t dist)
-{
- qboolean front, back;
- int i;
- vec_t d;
-
- front = false;
- back = false;
- for (i=0 ; i<w->numpoints ; i++)
- {
- d = DotProduct (w->p[i], normal) - dist;
- if (d < -ON_EPSILON)
- {
- if (front)
- return SIDE_CROSS;
- back = true;
- continue;
- }
- if (d > ON_EPSILON)
- {
- if (back)
- return SIDE_CROSS;
- front = true;
- continue;
- }
- }
-
- if (back)
- return SIDE_BACK;
- if (front)
- return SIDE_FRONT;
- return SIDE_ON;
-}
-
-//#ifdef ME
- #define CONTINUOUS_EPSILON 0.005
-//#else
-// #define CONTINUOUS_EPSILON 0.001
-//#endif
-
-/*
-=============
-TryMergeWinding
-
-If two polygons share a common edge and the edges that meet at the
-common points are both inside the other polygons, merge them
-
-Returns NULL if the faces couldn't be merged, or the new face.
-The originals will NOT be freed.
-=============
-*/
-
-winding_t *TryMergeWinding (winding_t *f1, winding_t *f2, vec3_t planenormal)
-{
- vec_t *p1, *p2, *p3, *p4, *back;
- winding_t *newf;
- int i, j, k, l;
- vec3_t normal, delta;
- vec_t dot;
- qboolean keep1, keep2;
-
-
- //
- // find a common edge
- //
- p1 = p2 = NULL; // stop compiler warning
- j = 0; //
-
- for (i = 0; i < f1->numpoints; i++)
- {
- p1 = f1->p[i];
- p2 = f1->p[(i+1) % f1->numpoints];
- for (j = 0; j < f2->numpoints; j++)
- {
- p3 = f2->p[j];
- p4 = f2->p[(j+1) % f2->numpoints];
- for (k = 0; k < 3; k++)
- {
- if (fabs(p1[k] - p4[k]) > 0.1)//EQUAL_EPSILON) //ME
- break;
- if (fabs(p2[k] - p3[k]) > 0.1)//EQUAL_EPSILON) //ME
- break;
- } //end for
- if (k==3)
- break;
- } //end for
- if (j < f2->numpoints)
- break;
- } //end for
-
- if (i == f1->numpoints)
- return NULL; // no matching edges
-
- //
- // check slope of connected lines
- // if the slopes are colinear, the point can be removed
- //
- back = f1->p[(i+f1->numpoints-1)%f1->numpoints];
- VectorSubtract (p1, back, delta);
- CrossProduct (planenormal, delta, normal);
- VectorNormalize (normal);
-
- back = f2->p[(j+2)%f2->numpoints];
- VectorSubtract (back, p1, delta);
- dot = DotProduct (delta, normal);
- if (dot > CONTINUOUS_EPSILON)
- return NULL; // not a convex polygon
- keep1 = (qboolean)(dot < -CONTINUOUS_EPSILON);
-
- back = f1->p[(i+2)%f1->numpoints];
- VectorSubtract (back, p2, delta);
- CrossProduct (planenormal, delta, normal);
- VectorNormalize (normal);
-
- back = f2->p[(j+f2->numpoints-1)%f2->numpoints];
- VectorSubtract (back, p2, delta);
- dot = DotProduct (delta, normal);
- if (dot > CONTINUOUS_EPSILON)
- return NULL; // not a convex polygon
- keep2 = (qboolean)(dot < -CONTINUOUS_EPSILON);
-
- //
- // build the new polygon
- //
- newf = AllocWinding (f1->numpoints + f2->numpoints);
-
- // copy first polygon
- for (k=(i+1)%f1->numpoints ; k != i ; k=(k+1)%f1->numpoints)
- {
- if (k==(i+1)%f1->numpoints && !keep2)
- continue;
-
- VectorCopy (f1->p[k], newf->p[newf->numpoints]);
- newf->numpoints++;
- }
-
- // copy second polygon
- for (l= (j+1)%f2->numpoints ; l != j ; l=(l+1)%f2->numpoints)
- {
- if (l==(j+1)%f2->numpoints && !keep1)
- continue;
- VectorCopy (f2->p[l], newf->p[newf->numpoints]);
- newf->numpoints++;
- }
-
- return newf;
-}
-
-//#ifdef ME
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-winding_t *MergeWindings(winding_t *w1, winding_t *w2, vec3_t planenormal)
-{
- winding_t *neww;
- float dist;
- int i, j, n, found, insertafter;
- int sides[MAX_POINTS_ON_WINDING+4];
- vec3_t newp[MAX_POINTS_ON_WINDING+4];
- int numpoints;
- vec3_t edgevec, sepnormal, v;
-
- RemoveEqualPoints(w1, 0.2);
- numpoints = w1->numpoints;
- memcpy(newp, w1->p, w1->numpoints * sizeof(vec3_t));
- //
- for (i = 0; i < w2->numpoints; i++)
- {
- VectorCopy(w2->p[i], v);
- for (j = 0; j < numpoints; j++)
- {
- VectorSubtract(newp[(j+1)%numpoints],
- newp[(j)%numpoints], edgevec);
- CrossProduct(edgevec, planenormal, sepnormal);
- VectorNormalize(sepnormal);
- if (VectorLength(sepnormal) < 0.9)
- {
- //remove the point from the new winding
- for (n = j; n < numpoints-1; n++)
- {
- VectorCopy(newp[n+1], newp[n]);
- sides[n] = sides[n+1];
- } //end for
- numpoints--;
- j--;
- Log_Print("MergeWindings: degenerate edge on winding %f %f %f\n", sepnormal[0],
- sepnormal[1],
- sepnormal[2]);
- continue;
- } //end if
- dist = DotProduct(newp[(j)%numpoints], sepnormal);
- if (DotProduct(v, sepnormal) - dist < -0.1) sides[j] = SIDE_BACK;
- else sides[j] = SIDE_FRONT;
- } //end for
- //remove all unnecesary points
- for (j = 0; j < numpoints;)
- {
- if (sides[j] == SIDE_BACK
- && sides[(j+1)%numpoints] == SIDE_BACK)
- {
- //remove the point from the new winding
- for (n = (j+1)%numpoints; n < numpoints-1; n++)
- {
- VectorCopy(newp[n+1], newp[n]);
- sides[n] = sides[n+1];
- } //end for
- numpoints--;
- } //end if
- else
- {
- j++;
- } //end else
- } //end for
- //
- found = false;
- for (j = 0; j < numpoints; j++)
- {
- if (sides[j] == SIDE_FRONT
- && sides[(j+1)%numpoints] == SIDE_BACK)
- {
- if (found) Log_Print("Warning: MergeWindings: front to back found twice\n");
- found = true;
- } //end if
- } //end for
- //
- for (j = 0; j < numpoints; j++)
- {
- if (sides[j] == SIDE_FRONT
- && sides[(j+1)%numpoints] == SIDE_BACK)
- {
- insertafter = (j+1)%numpoints;
- //insert the new point after j+1
- for (n = numpoints-1; n > insertafter; n--)
- {
- VectorCopy(newp[n], newp[n+1]);
- } //end for
- numpoints++;
- VectorCopy(v, newp[(insertafter+1)%numpoints]);
- break;
- } //end if
- } //end for
- } //end for
- neww = AllocWinding(numpoints);
- neww->numpoints = numpoints;
- memcpy(neww->p, newp, numpoints * sizeof(vec3_t));
- RemoveColinearPoints(neww);
- return neww;
-} //end of the function MergeWindings
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-char *WindingErrorString(void)
-{
- return windingerror;
-} //end of the function WindingErrorString
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int WindingError(winding_t *w)
-{
- int i, j;
- vec_t *p1, *p2;
- vec_t d, edgedist;
- vec3_t dir, edgenormal, facenormal;
- vec_t area;
- vec_t facedist;
-
- if (w->numpoints < 3)
- {
- sprintf(windingerror, "winding %i points", w->numpoints);
- return WE_NOTENOUGHPOINTS;
- } //end if
-
- area = WindingArea(w);
- if (area < 1)
- {
- sprintf(windingerror, "winding %f area", area);
- return WE_SMALLAREA;
- } //end if
-
- WindingPlane (w, facenormal, &facedist);
-
- for (i=0 ; i<w->numpoints ; i++)
- {
- p1 = w->p[i];
-
- for (j=0 ; j<3 ; j++)
- {
- if (p1[j] > BOGUS_RANGE || p1[j] < -BOGUS_RANGE)
- {
- sprintf(windingerror, "winding point %d BUGUS_RANGE \'%f %f %f\'", j, p1[0], p1[1], p1[2]);
- return WE_POINTBOGUSRANGE;
- } //end if
- } //end for
-
- j = i+1 == w->numpoints ? 0 : i+1;
-
- // check the point is on the face plane
- d = DotProduct (p1, facenormal) - facedist;
- if (d < -ON_EPSILON || d > ON_EPSILON)
- {
- sprintf(windingerror, "winding point %d off plane", i);
- return WE_POINTOFFPLANE;
- } //end if
-
- // check the edge isnt degenerate
- p2 = w->p[j];
- VectorSubtract (p2, p1, dir);
-
- if (VectorLength (dir) < ON_EPSILON)
- {
- sprintf(windingerror, "winding degenerate edge %d-%d", i, j);
- return WE_DEGENERATEEDGE;
- } //end if
-
- CrossProduct (facenormal, dir, edgenormal);
- VectorNormalize (edgenormal);
- edgedist = DotProduct (p1, edgenormal);
- edgedist += ON_EPSILON;
-
- // all other points must be on front side
- for (j=0 ; j<w->numpoints ; j++)
- {
- if (j == i)
- continue;
- d = DotProduct (w->p[j], edgenormal);
- if (d > edgedist)
- {
- sprintf(windingerror, "winding non-convex");
- return WE_NONCONVEX;
- } //end if
- } //end for
- } //end for
- return WE_NONE;
-} //end of the function WindingError
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void RemoveEqualPoints(winding_t *w, float epsilon)
-{
- int i, nump;
- vec3_t v;
- vec3_t p[MAX_POINTS_ON_WINDING];
-
- VectorCopy(w->p[0], p[0]);
- nump = 1;
- for (i = 1; i < w->numpoints; i++)
- {
- VectorSubtract(w->p[i], p[nump-1], v);
- if (VectorLength(v) > epsilon)
- {
- if (nump >= MAX_POINTS_ON_WINDING)
- Error("RemoveColinearPoints: MAX_POINTS_ON_WINDING");
- VectorCopy (w->p[i], p[nump]);
- nump++;
- } //end if
- } //end for
-
- if (nump == w->numpoints)
- return;
-
- w->numpoints = nump;
- memcpy(w->p, p, nump * sizeof(p[0]));
-} //end of the function RemoveEqualPoints
-//===========================================================================
-// adds the given point to a winding at the given spot
-// (for instance when spot is zero then the point is added at position zero)
-// the original winding is NOT freed
-//
-// Parameter: -
-// Returns: the new winding with the added point
-// Changes Globals: -
-//===========================================================================
-winding_t *AddWindingPoint(winding_t *w, vec3_t point, int spot)
-{
- int i, j;
- winding_t *neww;
-
- if (spot > w->numpoints)
- {
- Error("AddWindingPoint: num > w->numpoints");
- } //end if
- if (spot < 0)
- {
- Error("AddWindingPoint: num < 0");
- } //end if
- neww = AllocWinding(w->numpoints + 1);
- neww->numpoints = w->numpoints + 1;
- for (i = 0, j = 0; i < neww->numpoints; i++)
- {
- if (i == spot)
- {
- VectorCopy(point, neww->p[i]);
- } //end if
- else
- {
- VectorCopy(w->p[j], neww->p[i]);
- j++;
- } //end else
- } //end for
- return neww;
-} //end of the function AddWindingPoint
-//===========================================================================
-// the position where the new point should be added in the winding is
-// stored in *spot
-//
-// Parameter: -
-// Returns: true if the point is on the winding
-// Changes Globals: -
-//===========================================================================
-#define MELT_ON_EPSILON 0.2
-
-int PointOnWinding(winding_t *w, vec3_t normal, float dist, vec3_t point, int *spot)
-{
- int i, j;
- vec3_t v1, v2;
- vec3_t edgenormal, edgevec;
- float edgedist, dot;
-
- *spot = 0;
- //the point must be on the winding plane
- dot = DotProduct(point, normal) - dist;
- if (dot < -MELT_ON_EPSILON || dot > MELT_ON_EPSILON) return false;
- //
- for (i = 0; i < w->numpoints; i++)
- {
- j = (i+1) % w->numpoints;
- //get a plane orthogonal to the winding plane through the edge
- VectorSubtract(w->p[j], w->p[i], edgevec);
- CrossProduct(normal, edgevec, edgenormal);
- VectorNormalize(edgenormal);
- edgedist = DotProduct(edgenormal, w->p[i]);
- //point must be not too far from the plane
- dot = DotProduct(point, edgenormal) - edgedist;
- if (dot < -MELT_ON_EPSILON || dot > MELT_ON_EPSILON) continue;
- //vector from first point of winding to the point to test
- VectorSubtract(point, w->p[i], v1);
- //vector from second point of winding to the point to test
- VectorSubtract(point, w->p[j], v2);
- //if the length of the vector is not larger than 0.5 units then
- //the point is assumend to be the same as one of the winding points
- if (VectorNormalize(v1) < 0.5) return false;
- if (VectorNormalize(v2) < 0.5) return false;
- //point must be between the two winding points
- //(the two vectors must be directed towards each other, and on the
- //same straight line)
- if (DotProduct(v1, v2) < -0.99)
- {
- *spot = i + 1;
- return true;
- } //end if
- } //end for
- return false;
-} //end of the function PointOnWinding
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int FindPlaneSeperatingWindings(winding_t *w1, winding_t *w2, vec3_t dir,
- vec3_t normal, float *dist)
-{
- int i, i2, j, j2, n;
- int sides1[3], sides2[3];
- float dist1, dist2, dot, diff;
- vec3_t normal1, normal2;
- vec3_t v1, v2;
-
- for (i = 0; i < w1->numpoints; i++)
- {
- i2 = (i+1) % w1->numpoints;
- //
- VectorSubtract(w1->p[i2], w1->p[i], v1);
- if (VectorLength(v1) < 0.1)
- {
- //Log_Write("FindPlaneSeperatingWindings: winding1 with degenerate edge\r\n");
- continue;
- } //end if
- CrossProduct(v1, dir, normal1);
- VectorNormalize(normal1);
- dist1 = DotProduct(normal1, w1->p[i]);
- //
- for (j = 0; j < w2->numpoints; j++)
- {
- j2 = (j+1) % w2->numpoints;
- //
- VectorSubtract(w2->p[j2], w2->p[j], v2);
- if (VectorLength(v2) < 0.1)
- {
- //Log_Write("FindPlaneSeperatingWindings: winding2 with degenerate edge\r\n");
- continue;
- } //end if
- CrossProduct(v2, dir, normal2);
- VectorNormalize(normal2);
- dist2 = DotProduct(normal2, w2->p[j]);
- //
- diff = dist1 - dist2;
- if (diff < -0.1 || diff > 0.1)
- {
- dist2 = -dist2;
- VectorNegate(normal2, normal2);
- diff = dist1 - dist2;
- if (diff < -0.1 || diff > 0.1) continue;
- } //end if
- //check if the normal vectors are equal
- for (n = 0; n < 3; n++)
- {
- diff = normal1[n] - normal2[n];
- if (diff < -0.0001 || diff > 0.0001) break;
- } //end for
- if (n != 3) continue;
- //check on which side of the seperating plane the points of
- //the first winding are
- sides1[0] = sides1[1] = sides1[2] = 0;
- for (n = 0; n < w1->numpoints; n++)
- {
- dot = DotProduct(w1->p[n], normal1) - dist1;
- if (dot > 0.1) sides1[0]++;
- else if (dot < -0.1) sides1[1]++;
- else sides1[2]++;
- } //end for
- //check on which side of the seperating plane the points of
- //the second winding are
- sides2[0] = sides2[1] = sides2[2] = 0;
- for (n = 0; n < w2->numpoints; n++)
- {
- //used normal1 and dist1 (they are equal to normal2 and dist2)
- dot = DotProduct(w2->p[n], normal1) - dist1;
- if (dot > 0.1) sides2[0]++;
- else if (dot < -0.1) sides2[1]++;
- else sides2[2]++;
- } //end for
- //if the first winding has points at both sides
- if (sides1[0] && sides1[1])
- {
- Log_Write("FindPlaneSeperatingWindings: winding1 non-convex\r\n");
- continue;
- } //end if
- //if the second winding has points at both sides
- if (sides2[0] && sides2[1])
- {
- Log_Write("FindPlaneSeperatingWindings: winding2 non-convex\r\n");
- continue;
- } //end if
- //
- if ((!sides1[0] && !sides1[1]) || (!sides2[0] && !sides2[1]))
- {
- //don't use one of the winding planes as the seperating plane
- continue;
- } //end if
- //the windings must be at different sides of the seperating plane
- if ((!sides1[0] && !sides2[1]) || (!sides1[1] && !sides2[0]))
- {
- VectorCopy(normal1, normal);
- *dist = dist1;
- return true;
- } //end if
- } //end for
- } //end for
- return false;
-} //end of the function FindPlaneSeperatingWindings
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-#define WCONVEX_EPSILON 0.2
-
-int WindingsNonConvex(winding_t *w1, winding_t *w2,
- vec3_t normal1, vec3_t normal2,
- float dist1, float dist2)
-{
- int i;
-
- if (!w1 || !w2) return false;
-
- //check if one of the points of face1 is at the back of the plane of face2
- for (i = 0; i < w1->numpoints; i++)
- {
- if (DotProduct(normal2, w1->p[i]) - dist2 > WCONVEX_EPSILON) return true;
- } //end for
- //check if one of the points of face2 is at the back of the plane of face1
- for (i = 0; i < w2->numpoints; i++)
- {
- if (DotProduct(normal1, w2->p[i]) - dist1 > WCONVEX_EPSILON) return true;
- } //end for
-
- return false;
-} //end of the function WindingsNonConvex
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-/*
-#define VERTEX_EPSILON 0.5
-
-qboolean EqualVertexes(vec3_t v1, vec3_t v2)
-{
- float diff;
-
- diff = v1[0] - v2[0];
- if (diff > -VERTEX_EPSILON && diff < VERTEX_EPSILON)
- {
- diff = v1[1] - v2[1];
- if (diff > -VERTEX_EPSILON && diff < VERTEX_EPSILON)
- {
- diff = v1[2] - v2[2];
- if (diff > -VERTEX_EPSILON && diff < VERTEX_EPSILON)
- {
- return true;
- } //end if
- } //end if
- } //end if
- return false;
-} //end of the function EqualVertexes
-
-#define CONTINUOUS_EPSILON 0.001
-
-winding_t *AAS_MergeWindings(winding_t *w1, winding_t *w2, vec3_t windingnormal)
-{
- int n, i, k;
- vec3_t normal, delta;
- winding_t *winding, *neww;
- float dist, dot;
- int p1, p2;
- int points[2][64];
- int numpoints[2] = {0, 0};
- int newnumpoints;
- int keep[2];
-
- if (!FindPlaneSeperatingWindings(w1, w2, windingnormal, normal, &dist)) return NULL;
-
- //for both windings
- for (n = 0; n < 2; n++)
- {
- if (n == 0) winding = w1;
- else winding = w2;
- //get the points of the winding which are on the seperating plane
- for (i = 0; i < winding->numpoints; i++)
- {
- dot = DotProduct(winding->p[i], normal) - dist;
- if (dot > -ON_EPSILON && dot < ON_EPSILON)
- {
- //don't allow more than 64 points on the seperating plane
- if (numpoints[n] >= 64) Error("AAS_MergeWindings: more than 64 points on seperating plane\n");
- points[n][numpoints[n]++] = i;
- } //end if
- } //end for
- //there must be at least two points of each winding on the seperating plane
- if (numpoints[n] < 2) return NULL;
- } //end for
-
- //if the first point of winding1 (which is on the seperating plane) is unequal
- //to the last point of winding2 (which is on the seperating plane)
- if (!EqualVertexes(w1->p[points[0][0]], w2->p[points[1][numpoints[1]-1]]))
- {
- return NULL;
- } //end if
- //if the last point of winding1 (which is on the seperating plane) is unequal
- //to the first point of winding2 (which is on the seperating plane)
- if (!EqualVertexes(w1->p[points[0][numpoints[0]-1]], w2->p[points[1][0]]))
- {
- return NULL;
- } //end if
- //
- // check slope of connected lines
- // if the slopes are colinear, the point can be removed
- //
- //first point of winding1 which is on the seperating plane
- p1 = points[0][0];
- //point before p1
- p2 = (p1 + w1->numpoints - 1) % w1->numpoints;
- VectorSubtract(w1->p[p1], w1->p[p2], delta);
- CrossProduct(windingnormal, delta, normal);
- VectorNormalize(normal, normal);
-
- //last point of winding2 which is on the seperating plane
- p1 = points[1][numpoints[1]-1];
- //point after p1
- p2 = (p1 + 1) % w2->numpoints;
- VectorSubtract(w2->p[p2], w2->p[p1], delta);
- dot = DotProduct(delta, normal);
- if (dot > CONTINUOUS_EPSILON) return NULL; //merging would create a non-convex polygon
- keep[0] = (qboolean)(dot < -CONTINUOUS_EPSILON);
-
- //first point of winding2 which is on the seperating plane
- p1 = points[1][0];
- //point before p1
- p2 = (p1 + w2->numpoints - 1) % w2->numpoints;
- VectorSubtract(w2->p[p1], w2->p[p2], delta);
- CrossProduct(windingnormal, delta, normal);
- VectorNormalize(normal, normal);
-
- //last point of winding1 which is on the seperating plane
- p1 = points[0][numpoints[0]-1];
- //point after p1
- p2 = (p1 + 1) % w1->numpoints;
- VectorSubtract(w1->p[p2], w1->p[p1], delta);
- dot = DotProduct(delta, normal);
- if (dot > CONTINUOUS_EPSILON) return NULL; //merging would create a non-convex polygon
- keep[1] = (qboolean)(dot < -CONTINUOUS_EPSILON);
-
- //number of points on the new winding
- newnumpoints = w1->numpoints - numpoints[0] + w2->numpoints - numpoints[1] + 2;
- //allocate the winding
- neww = AllocWinding(newnumpoints);
- neww->numpoints = newnumpoints;
- //copy all the points
- k = 0;
- //for both windings
- for (n = 0; n < 2; n++)
- {
- if (n == 0) winding = w1;
- else winding = w2;
- //copy the points of the winding starting with the last point on the
- //seperating plane and ending before the first point on the seperating plane
- for (i = points[n][numpoints[n]-1]; i != points[n][0]; i = (i+1)%winding->numpoints)
- {
- if (k >= newnumpoints)
- {
- Log_Print("numpoints[0] = %d\n", numpoints[0]);
- Log_Print("numpoints[1] = %d\n", numpoints[1]);
- Error("AAS_MergeWindings: k = %d >= newnumpoints = %d\n", k, newnumpoints);
- } //end if
- VectorCopy(winding->p[i], neww->p[k]);
- k++;
- } //end for
- } //end for
- RemoveEqualPoints(neww);
- if (!WindingIsOk(neww, 1))
- {
- Log_Print("AAS_MergeWindings: winding not ok after merging\n");
- FreeWinding(neww);
- return NULL;
- } //end if
- return neww;
-} //end of the function AAS_MergeWindings*/
-//#endif //ME
diff --git a/code/bspc/l_poly.h b/code/bspc/l_poly.h
deleted file mode 100644
index 76a83f8..0000000
--- a/code/bspc/l_poly.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-//a winding gives the bounding points of a convex polygon
-typedef struct
-{
- int numpoints;
- vec3_t p[4]; //variable sized
-} winding_t;
-
-#define MAX_POINTS_ON_WINDING 96
-
-//you can define on_epsilon in the makefile as tighter
-#ifndef ON_EPSILON
-#define ON_EPSILON 0.1
-#endif
-//winding errors
-#define WE_NONE 0
-#define WE_NOTENOUGHPOINTS 1
-#define WE_SMALLAREA 2
-#define WE_POINTBOGUSRANGE 3
-#define WE_POINTOFFPLANE 4
-#define WE_DEGENERATEEDGE 5
-#define WE_NONCONVEX 6
-
-//allocates a winding
-winding_t *AllocWinding (int points);
-//returns the area of the winding
-vec_t WindingArea (winding_t *w);
-//gives the center of the winding
-void WindingCenter (winding_t *w, vec3_t center);
-//clips the given winding to the given plane and gives the front
-//and back part of the clipped winding
-void ClipWindingEpsilon (winding_t *in, vec3_t normal, vec_t dist,
- vec_t epsilon, winding_t **front, winding_t **back);
-//returns the fragment of the given winding that is on the front
-//side of the cliping plane. The original is freed.
-winding_t *ChopWinding (winding_t *in, vec3_t normal, vec_t dist);
-//returns a copy of the given winding
-winding_t *CopyWinding (winding_t *w);
-//returns the reversed winding of the given one
-winding_t *ReverseWinding (winding_t *w);
-//returns a base winding for the given plane
-winding_t *BaseWindingForPlane (vec3_t normal, vec_t dist);
-//checks the winding for errors
-void CheckWinding (winding_t *w);
-//returns the plane normal and dist the winding is in
-void WindingPlane(winding_t *w, vec3_t normal, vec_t *dist);
-//removes colinear points from the winding
-void RemoveColinearPoints(winding_t *w);
-//returns on which side of the plane the winding is situated
-int WindingOnPlaneSide(winding_t *w, vec3_t normal, vec_t dist);
-//frees the winding
-void FreeWinding(winding_t *w);
-//gets the bounds of the winding
-void WindingBounds(winding_t *w, vec3_t mins, vec3_t maxs);
-//chops the winding with the given plane, the original winding is freed if clipped
-void ChopWindingInPlace (winding_t **w, vec3_t normal, vec_t dist, vec_t epsilon);
-//prints the winding points on STDOUT
-void pw(winding_t *w);
-//try to merge the two windings which are in the given plane
-//the original windings are undisturbed
-//the merged winding is returned when merging was possible
-//NULL is returned otherwise
-winding_t *TryMergeWinding (winding_t *f1, winding_t *f2, vec3_t planenormal);
-//brute force winding merging... creates a convex winding out of
-//the two whatsoever
-winding_t *MergeWindings(winding_t *w1, winding_t *w2, vec3_t planenormal);
-
-//#ifdef ME
-void ResetWindings(void);
-//returns the amount of winding memory
-int WindingMemory(void);
-int WindingPeakMemory(void);
-int ActiveWindings(void);
-//returns the winding error string
-char *WindingErrorString(void);
-//returns one of the WE_ flags when the winding has errors
-int WindingError(winding_t *w);
-//removes equal points from the winding
-void RemoveEqualPoints(winding_t *w, float epsilon);
-//returns a winding with a point added at the given spot to the
-//given winding, original winding is NOT freed
-winding_t *AddWindingPoint(winding_t *w, vec3_t point, int spot);
-//returns true if the point is on one of the winding 'edges'
-//when the point is on one of the edged the number of the first
-//point of the edge is stored in 'spot'
-int PointOnWinding(winding_t *w, vec3_t normal, float dist, vec3_t point, int *spot);
-//find a plane seperating the two windings
-//true is returned when the windings area adjacent
-//the seperating plane normal and distance area stored in 'normal' and 'dist'
-//this plane will contain both the piece of common edge of the two windings
-//and the vector 'dir'
-int FindPlaneSeperatingWindings(winding_t *w1, winding_t *w2, vec3_t dir,
- vec3_t normal, float *dist);
-//
-int WindingsNonConvex(winding_t *w1, winding_t *w2,
- vec3_t normal1, vec3_t normal2,
- float dist1, float dist2);
-//#endif //ME
-
diff --git a/code/bspc/l_qfiles.c b/code/bspc/l_qfiles.c
deleted file mode 100644
index 25aab2b..0000000
--- a/code/bspc/l_qfiles.c
+++ /dev/null
@@ -1,663 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-#if defined(WIN32)|defined(_WIN32)
-#include <windows.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#else
-#include <glob.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#endif
-
-#include "qbsp.h"
-
-//file extensions with their type
-typedef struct qfile_exttype_s
-{
- char *extension;
- int type;
-} qfile_exttyp_t;
-
-qfile_exttyp_t quakefiletypes[] =
-{
- {QFILEEXT_UNKNOWN, QFILETYPE_UNKNOWN},
- {QFILEEXT_PAK, QFILETYPE_PAK},
- {QFILEEXT_PK3, QFILETYPE_PK3},
- {QFILEEXT_SIN, QFILETYPE_PAK},
- {QFILEEXT_BSP, QFILETYPE_BSP},
- {QFILEEXT_MAP, QFILETYPE_MAP},
- {QFILEEXT_MDL, QFILETYPE_MDL},
- {QFILEEXT_MD2, QFILETYPE_MD2},
- {QFILEEXT_MD3, QFILETYPE_MD3},
- {QFILEEXT_WAL, QFILETYPE_WAL},
- {QFILEEXT_WAV, QFILETYPE_WAV},
- {QFILEEXT_AAS, QFILETYPE_AAS},
- {NULL, 0}
-};
-
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int QuakeFileExtensionType(char *extension)
-{
- int i;
-
- for (i = 0; quakefiletypes[i].extension; i++)
- {
- if (!stricmp(extension, quakefiletypes[i].extension))
- {
- return quakefiletypes[i].type;
- } //end if
- } //end for
- return QFILETYPE_UNKNOWN;
-} //end of the function QuakeFileExtensionType
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-char *QuakeFileTypeExtension(int type)
-{
- int i;
-
- for (i = 0; quakefiletypes[i].extension; i++)
- {
- if (quakefiletypes[i].type == type)
- {
- return quakefiletypes[i].extension;
- } //end if
- } //end for
- return QFILEEXT_UNKNOWN;
-} //end of the function QuakeFileExtension
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int QuakeFileType(char *filename)
-{
- char ext[_MAX_PATH] = ".";
-
- ExtractFileExtension(filename, ext+1);
- return QuakeFileExtensionType(ext);
-} //end of the function QuakeFileTypeFromFileName
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-char *StringContains(char *str1, char *str2, int casesensitive)
-{
- int len, i, j;
-
- len = strlen(str1) - strlen(str2);
- for (i = 0; i <= len; i++, str1++)
- {
- for (j = 0; str2[j]; j++)
- {
- if (casesensitive)
- {
- if (str1[j] != str2[j]) break;
- } //end if
- else
- {
- if (toupper(str1[j]) != toupper(str2[j])) break;
- } //end else
- } //end for
- if (!str2[j]) return str1;
- } //end for
- return NULL;
-} //end of the function StringContains
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int FileFilter(char *filter, char *filename, int casesensitive)
-{
- char buf[1024];
- char *ptr;
- int i, found;
-
- while(*filter)
- {
- if (*filter == '*')
- {
- filter++;
- for (i = 0; *filter; i++)
- {
- if (*filter == '*' || *filter == '?') break;
- buf[i] = *filter;
- filter++;
- } //end for
- buf[i] = '\0';
- if (strlen(buf))
- {
- ptr = StringContains(filename, buf, casesensitive);
- if (!ptr) return false;
- filename = ptr + strlen(buf);
- } //end if
- } //end if
- else if (*filter == '?')
- {
- filter++;
- filename++;
- } //end else if
- else if (*filter == '[' && *(filter+1) == '[')
- {
- filter++;
- } //end if
- else if (*filter == '[')
- {
- filter++;
- found = false;
- while(*filter && !found)
- {
- if (*filter == ']' && *(filter+1) != ']') break;
- if (*(filter+1) == '-' && *(filter+2) && (*(filter+2) != ']' || *(filter+3) == ']'))
- {
- if (casesensitive)
- {
- if (*filename >= *filter && *filename <= *(filter+2)) found = true;
- } //end if
- else
- {
- if (toupper(*filename) >= toupper(*filter) &&
- toupper(*filename) <= toupper(*(filter+2))) found = true;
- } //end else
- filter += 3;
- } //end if
- else
- {
- if (casesensitive)
- {
- if (*filter == *filename) found = true;
- } //end if
- else
- {
- if (toupper(*filter) == toupper(*filename)) found = true;
- } //end else
- filter++;
- } //end else
- } //end while
- if (!found) return false;
- while(*filter)
- {
- if (*filter == ']' && *(filter+1) != ']') break;
- filter++;
- } //end while
- filter++;
- filename++;
- } //end else if
- else
- {
- if (casesensitive)
- {
- if (*filter != *filename) return false;
- } //end if
- else
- {
- if (toupper(*filter) != toupper(*filename)) return false;
- } //end else
- filter++;
- filename++;
- } //end else
- } //end while
- return true;
-} //end of the function FileFilter
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-quakefile_t *FindQuakeFilesInZip(char *zipfile, char *filter)
-{
- unzFile uf;
- int err;
- unz_global_info gi;
- char filename_inzip[MAX_PATH];
- unz_file_info file_info;
- int i;
- quakefile_t *qfiles, *lastqf, *qf;
-
- uf = unzOpen(zipfile);
- err = unzGetGlobalInfo(uf, &gi);
-
- if (err != UNZ_OK) return NULL;
-
- unzGoToFirstFile(uf);
-
- qfiles = NULL;
- lastqf = NULL;
- for (i = 0; i < gi.number_entry; i++)
- {
- err = unzGetCurrentFileInfo(uf, &file_info, filename_inzip, sizeof(filename_inzip), NULL,0,NULL,0);
- if (err != UNZ_OK) break;
-
- ConvertPath(filename_inzip);
- if (FileFilter(filter, filename_inzip, false))
- {
- qf = malloc(sizeof(quakefile_t));
- if (!qf) Error("out of memory");
- memset(qf, 0, sizeof(quakefile_t));
- strcpy(qf->pakfile, zipfile);
- strcpy(qf->filename, zipfile);
- strcpy(qf->origname, filename_inzip);
- qf->zipfile = true;
- //memcpy( &buildBuffer[i].zipfileinfo, (unz_s*)uf, sizeof(unz_s));
- memcpy(&qf->zipinfo, (unz_s*)uf, sizeof(unz_s));
- qf->offset = 0;
- qf->length = file_info.uncompressed_size;
- qf->type = QuakeFileType(filename_inzip);
- //add the file ot the list
- qf->next = NULL;
- if (lastqf) lastqf->next = qf;
- else qfiles = qf;
- lastqf = qf;
- } //end if
- unzGoToNextFile(uf);
- } //end for
-
- unzClose(uf);
-
- return qfiles;
-} //end of the function FindQuakeFilesInZip
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-quakefile_t *FindQuakeFilesInPak(char *pakfile, char *filter)
-{
- FILE *fp;
- dpackheader_t packheader;
- dsinpackfile_t *packfiles;
- dpackfile_t *idpackfiles;
- quakefile_t *qfiles, *lastqf, *qf;
- int numpackdirs, i;
-
- qfiles = NULL;
- lastqf = NULL;
- //open the pak file
- fp = fopen(pakfile, "rb");
- if (!fp)
- {
- Warning("can't open pak file %s", pakfile);
- return NULL;
- } //end if
- //read pak header, check for valid pak id and seek to the dir entries
- if ((fread(&packheader, 1, sizeof(dpackheader_t), fp) != sizeof(dpackheader_t))
- || (packheader.ident != IDPAKHEADER && packheader.ident != SINPAKHEADER)
- || (fseek(fp, LittleLong(packheader.dirofs), SEEK_SET))
- )
- {
- fclose(fp);
- Warning("invalid pak file %s", pakfile);
- return NULL;
- } //end if
- //if it is a pak file from id software
- if (packheader.ident == IDPAKHEADER)
- {
- //number of dir entries in the pak file
- numpackdirs = LittleLong(packheader.dirlen) / sizeof(dpackfile_t);
- idpackfiles = (dpackfile_t *) malloc(numpackdirs * sizeof(dpackfile_t));
- if (!idpackfiles) Error("out of memory");
- //read the dir entry
- if (fread(idpackfiles, sizeof(dpackfile_t), numpackdirs, fp) != numpackdirs)
- {
- fclose(fp);
- free(idpackfiles);
- Warning("can't read the Quake pak file dir entries from %s", pakfile);
- return NULL;
- } //end if
- fclose(fp);
- //convert to sin pack files
- packfiles = (dsinpackfile_t *) malloc(numpackdirs * sizeof(dsinpackfile_t));
- if (!packfiles) Error("out of memory");
- for (i = 0; i < numpackdirs; i++)
- {
- strcpy(packfiles[i].name, idpackfiles[i].name);
- packfiles[i].filepos = LittleLong(idpackfiles[i].filepos);
- packfiles[i].filelen = LittleLong(idpackfiles[i].filelen);
- } //end for
- free(idpackfiles);
- } //end if
- else //its a Sin pack file
- {
- //number of dir entries in the pak file
- numpackdirs = LittleLong(packheader.dirlen) / sizeof(dsinpackfile_t);
- packfiles = (dsinpackfile_t *) malloc(numpackdirs * sizeof(dsinpackfile_t));
- if (!packfiles) Error("out of memory");
- //read the dir entry
- if (fread(packfiles, sizeof(dsinpackfile_t), numpackdirs, fp) != numpackdirs)
- {
- fclose(fp);
- free(packfiles);
- Warning("can't read the Sin pak file dir entries from %s", pakfile);
- return NULL;
- } //end if
- fclose(fp);
- for (i = 0; i < numpackdirs; i++)
- {
- packfiles[i].filepos = LittleLong(packfiles[i].filepos);
- packfiles[i].filelen = LittleLong(packfiles[i].filelen);
- } //end for
- } //end else
- //
- for (i = 0; i < numpackdirs; i++)
- {
- ConvertPath(packfiles[i].name);
- if (FileFilter(filter, packfiles[i].name, false))
- {
- qf = malloc(sizeof(quakefile_t));
- if (!qf) Error("out of memory");
- memset(qf, 0, sizeof(quakefile_t));
- strcpy(qf->pakfile, pakfile);
- strcpy(qf->filename, pakfile);
- strcpy(qf->origname, packfiles[i].name);
- qf->zipfile = false;
- qf->offset = packfiles[i].filepos;
- qf->length = packfiles[i].filelen;
- qf->type = QuakeFileType(packfiles[i].name);
- //add the file ot the list
- qf->next = NULL;
- if (lastqf) lastqf->next = qf;
- else qfiles = qf;
- lastqf = qf;
- } //end if
- } //end for
- free(packfiles);
- return qfiles;
-} //end of the function FindQuakeFilesInPak
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-quakefile_t *FindQuakeFilesWithPakFilter(char *pakfilter, char *filter)
-{
-#if defined(WIN32)|defined(_WIN32)
- WIN32_FIND_DATA filedata;
- HWND handle;
- struct _stat statbuf;
-#else
- glob_t globbuf;
- struct stat statbuf;
- int j;
-#endif
- quakefile_t *qfiles, *lastqf, *qf;
- char pakfile[_MAX_PATH], filename[_MAX_PATH], *str;
- int done;
-
- qfiles = NULL;
- lastqf = NULL;
- if (pakfilter && strlen(pakfilter))
- {
-#if defined(WIN32)|defined(_WIN32)
- handle = FindFirstFile(pakfilter, &filedata);
- done = (handle == INVALID_HANDLE_VALUE);
- while(!done)
- {
- _splitpath(pakfilter, pakfile, NULL, NULL, NULL);
- _splitpath(pakfilter, NULL, &pakfile[strlen(pakfile)], NULL, NULL);
- AppendPathSeperator(pakfile, _MAX_PATH);
- strcat(pakfile, filedata.cFileName);
- _stat(pakfile, &statbuf);
-#else
- glob(pakfilter, 0, NULL, &globbuf);
- for (j = 0; j < globbuf.gl_pathc; j++)
- {
- strcpy(pakfile, globbuf.gl_pathv[j]);
- stat(pakfile, &statbuf);
-#endif
- //if the file with .pak or .pk3 is a folder
- if (statbuf.st_mode & S_IFDIR)
- {
- strcpy(filename, pakfilter);
- AppendPathSeperator(filename, _MAX_PATH);
- strcat(filename, filter);
- qf = FindQuakeFilesWithPakFilter(NULL, filename);
- if (lastqf) lastqf->next = qf;
- else qfiles = qf;
- lastqf = qf;
- while(lastqf->next) lastqf = lastqf->next;
- } //end if
- else
- {
-#if defined(WIN32)|defined(_WIN32)
- str = StringContains(pakfile, ".pk3", false);
-#else
- str = StringContains(pakfile, ".pk3", true);
-#endif
- if (str && str == pakfile + strlen(pakfile) - strlen(".pk3"))
- {
- qf = FindQuakeFilesInZip(pakfile, filter);
- } //end if
- else
- {
- qf = FindQuakeFilesInPak(pakfile, filter);
- } //end else
- //
- if (qf)
- {
- if (lastqf) lastqf->next = qf;
- else qfiles = qf;
- lastqf = qf;
- while(lastqf->next) lastqf = lastqf->next;
- } //end if
- } //end else
- //
-#if defined(WIN32)|defined(_WIN32)
- //find the next file
- done = !FindNextFile(handle, &filedata);
- } //end while
-#else
- } //end for
- globfree(&globbuf);
-#endif
- } //end if
- else
- {
-#if defined(WIN32)|defined(_WIN32)
- handle = FindFirstFile(filter, &filedata);
- done = (handle == INVALID_HANDLE_VALUE);
- while(!done)
- {
- _splitpath(filter, filename, NULL, NULL, NULL);
- _splitpath(filter, NULL, &filename[strlen(filename)], NULL, NULL);
- AppendPathSeperator(filename, _MAX_PATH);
- strcat(filename, filedata.cFileName);
-#else
- glob(filter, 0, NULL, &globbuf);
- for (j = 0; j < globbuf.gl_pathc; j++)
- {
- strcpy(filename, globbuf.gl_pathv[j]);
-#endif
- //
- qf = malloc(sizeof(quakefile_t));
- if (!qf) Error("out of memory");
- memset(qf, 0, sizeof(quakefile_t));
- strcpy(qf->pakfile, "");
- strcpy(qf->filename, filename);
- strcpy(qf->origname, filename);
- qf->offset = 0;
- qf->length = 0;
- qf->type = QuakeFileType(filename);
- //add the file ot the list
- qf->next = NULL;
- if (lastqf) lastqf->next = qf;
- else qfiles = qf;
- lastqf = qf;
-#if defined(WIN32)|defined(_WIN32)
- //find the next file
- done = !FindNextFile(handle, &filedata);
- } //end while
-#else
- } //end for
- globfree(&globbuf);
-#endif
- } //end else
- return qfiles;
-} //end of the function FindQuakeFilesWithPakFilter
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-quakefile_t *FindQuakeFiles(char *filter)
-{
- char *str;
- char newfilter[_MAX_PATH];
- char pakfilter[_MAX_PATH];
- char filefilter[_MAX_PATH];
-
- strcpy(newfilter, filter);
- ConvertPath(newfilter);
- strcpy(pakfilter, newfilter);
-
- str = StringContains(pakfilter, ".pak", false);
- if (!str) str = StringContains(pakfilter, ".pk3", false);
-
- if (str)
- {
- str += strlen(".pak");
- if (*str)
- {
- *str++ = '\0';
- while(*str == '\\' || *str == '/') str++;
- strcpy(filefilter, str);
- return FindQuakeFilesWithPakFilter(pakfilter, filefilter);
- } //end if
- } //end else
- return FindQuakeFilesWithPakFilter(NULL, newfilter);
-} //end of the function FindQuakeFiles
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int LoadQuakeFile(quakefile_t *qf, void **bufferptr)
-{
- FILE *fp;
- void *buffer;
- int length;
- unzFile zf;
-
- if (qf->zipfile)
- {
- //open the zip file
- zf = unzOpen(qf->pakfile);
- //set the file pointer
- qf->zipinfo.file = ((unz_s *) zf)->file;
- //open the Quake file in the zip file
- unzOpenCurrentFile(&qf->zipinfo);
- //allocate memory for the buffer
- length = qf->length;
- buffer = GetMemory(length+1);
- //read the Quake file from the zip file
- length = unzReadCurrentFile(&qf->zipinfo, buffer, length);
- //close the Quake file in the zip file
- unzCloseCurrentFile(&qf->zipinfo);
- //close the zip file
- unzClose(zf);
-
- *bufferptr = buffer;
- return length;
- } //end if
- else
- {
- fp = SafeOpenRead(qf->filename);
- if (qf->offset) fseek(fp, qf->offset, SEEK_SET);
- length = qf->length;
- if (!length) length = Q_filelength(fp);
- buffer = GetMemory(length+1);
- ((char *)buffer)[length] = 0;
- SafeRead(fp, buffer, length);
- fclose(fp);
-
- *bufferptr = buffer;
- return length;
- } //end else
-} //end of the function LoadQuakeFile
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int ReadQuakeFile(quakefile_t *qf, void *buffer, int offset, int length)
-{
- FILE *fp;
- int read;
- unzFile zf;
- char tmpbuf[1024];
-
- if (qf->zipfile)
- {
- //open the zip file
- zf = unzOpen(qf->pakfile);
- //set the file pointer
- qf->zipinfo.file = ((unz_s *) zf)->file;
- //open the Quake file in the zip file
- unzOpenCurrentFile(&qf->zipinfo);
- //
- while(offset > 0)
- {
- read = offset;
- if (read > sizeof(tmpbuf)) read = sizeof(tmpbuf);
- unzReadCurrentFile(&qf->zipinfo, tmpbuf, read);
- offset -= read;
- } //end while
- //read the Quake file from the zip file
- length = unzReadCurrentFile(&qf->zipinfo, buffer, length);
- //close the Quake file in the zip file
- unzCloseCurrentFile(&qf->zipinfo);
- //close the zip file
- unzClose(zf);
-
- return length;
- } //end if
- else
- {
- fp = SafeOpenRead(qf->filename);
- if (qf->offset) fseek(fp, qf->offset, SEEK_SET);
- if (offset) fseek(fp, offset, SEEK_CUR);
- SafeRead(fp, buffer, length);
- fclose(fp);
-
- return length;
- } //end else
-} //end of the function ReadQuakeFile
diff --git a/code/bspc/l_qfiles.h b/code/bspc/l_qfiles.h
deleted file mode 100644
index 41ff065..0000000
--- a/code/bspc/l_qfiles.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-#include "../qcommon/unzip.h"
-
-#define QFILETYPE_UNKNOWN 0x8000
-#define QFILETYPE_PAK 0x0001
-#define QFILETYPE_PK3 0x0002
-#define QFILETYPE_BSP 0x0004
-#define QFILETYPE_MAP 0x0008
-#define QFILETYPE_MDL 0x0010
-#define QFILETYPE_MD2 0x0020
-#define QFILETYPE_MD3 0x0040
-#define QFILETYPE_WAL 0x0080
-#define QFILETYPE_WAV 0x0100
-#define QFILETYPE_AAS 0x4000
-
-#define QFILEEXT_UNKNOWN ""
-#define QFILEEXT_PAK ".PAK"
-#define QFILEEXT_PK3 ".PK3"
-#define QFILEEXT_SIN ".SIN"
-#define QFILEEXT_BSP ".BSP"
-#define QFILEEXT_MAP ".MAP"
-#define QFILEEXT_MDL ".MDL"
-#define QFILEEXT_MD2 ".MD2"
-#define QFILEEXT_MD3 ".MD3"
-#define QFILEEXT_WAL ".WAL"
-#define QFILEEXT_WAV ".WAV"
-#define QFILEEXT_AAS ".AAS"
-
-//maximum path length
-#ifndef _MAX_PATH
- #define _MAX_PATH 1024
-#endif
-
-//for Sin packs
-#define MAX_PAK_FILENAME_LENGTH 120
-#define SINPAKHEADER (('K'<<24)+('A'<<16)+('P'<<8)+'S')
-
-typedef struct
-{
- char name[MAX_PAK_FILENAME_LENGTH];
- int filepos, filelen;
-} dsinpackfile_t;
-
-typedef struct quakefile_s
-{
- char pakfile[_MAX_PATH];
- char filename[_MAX_PATH];
- char origname[_MAX_PATH];
- int zipfile;
- int type;
- int offset;
- int length;
- unz_s zipinfo;
- struct quakefile_s *next;
-} quakefile_t;
-
-//returns the file extension for the given type
-char *QuakeFileTypeExtension(int type);
-//returns the file type for the given extension
-int QuakeFileExtensionType(char *extension);
-//return the Quake file type for the given file
-int QuakeFileType(char *filename);
-//returns true if the filename complies to the filter
-int FileFilter(char *filter, char *filename, int casesensitive);
-//find Quake files using the given filter
-quakefile_t *FindQuakeFiles(char *filter);
-//load the given Quake file, returns the length of the file
-int LoadQuakeFile(quakefile_t *qf, void **bufferptr);
-//read part of a Quake file into the buffer
-int ReadQuakeFile(quakefile_t *qf, void *buffer, int offset, int length);
diff --git a/code/bspc/l_threads.c b/code/bspc/l_threads.c
deleted file mode 100644
index bb67760..0000000
--- a/code/bspc/l_threads.c
+++ /dev/null
@@ -1,1510 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-#include "l_cmd.h"
-#include "l_threads.h"
-#include "l_log.h"
-#include "l_mem.h"
-
-#define MAX_THREADS 64
-
-//#define THREAD_DEBUG
-
-int dispatch;
-int workcount;
-int oldf;
-qboolean pacifier;
-qboolean threaded;
-void (*workfunction) (int);
-
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int GetThreadWork(void)
-{
- int r;
- int f;
-
- ThreadLock();
-
- if (dispatch == workcount)
- {
- ThreadUnlock ();
- return -1;
- }
-
- f = 10*dispatch / workcount;
- if (f != oldf)
- {
- oldf = f;
- if (pacifier)
- printf ("%i...", f);
- } //end if
-
- r = dispatch;
- dispatch++;
- ThreadUnlock ();
-
- return r;
-} //end of the function GetThreadWork
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void ThreadWorkerFunction(int threadnum)
-{
- int work;
-
- while(1)
- {
- work = GetThreadWork ();
- if (work == -1)
- break;
-//printf ("thread %i, work %i\n", threadnum, work);
- workfunction(work);
- } //end while
-} //end of the function ThreadWorkerFunction
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void RunThreadsOnIndividual (int workcnt, qboolean showpacifier, void(*func)(int))
-{
- if (numthreads == -1)
- ThreadSetDefault ();
- workfunction = func;
- RunThreadsOn (workcnt, showpacifier, ThreadWorkerFunction);
-} //end of the function RunThreadsOnIndividual
-
-
-//===================================================================
-//
-// WIN32
-//
-//===================================================================
-
-#if defined(WIN32) || defined(_WIN32)
-
-#define USED
-
-#include <windows.h>
-
-typedef struct thread_s
-{
- HANDLE handle;
- int threadid;
- int id;
- struct thread_s *next;
-} thread_t;
-
-thread_t *firstthread;
-thread_t *lastthread;
-int currentnumthreads;
-int currentthreadid;
-
-int numthreads = 1;
-CRITICAL_SECTION crit;
-HANDLE semaphore;
-static int enter;
-static int numwaitingthreads = 0;
-
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void ThreadSetDefault(void)
-{
- SYSTEM_INFO info;
-
- if (numthreads == -1) // not set manually
- {
- GetSystemInfo (&info);
- numthreads = info.dwNumberOfProcessors;
- if (numthreads < 1 || numthreads > 32)
- numthreads = 1;
- } //end if
- qprintf ("%i threads\n", numthreads);
-} //end of the function ThreadSetDefault
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void ThreadLock(void)
-{
- if (!threaded)
- {
- Error("ThreadLock: !threaded");
- return;
- } //end if
- EnterCriticalSection(&crit);
- if (enter)
- Error("Recursive ThreadLock\n");
- enter = 1;
-} //end of the function ThreadLock
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void ThreadUnlock (void)
-{
- if (!threaded)
- {
- Error("ThreadUnlock: !threaded");
- return;
- } //end if
- if (!enter)
- Error("ThreadUnlock without lock\n");
- enter = 0;
- LeaveCriticalSection(&crit);
-} //end of the function ThreadUnlock
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void ThreadSetupLock(void)
-{
- Log_Print("Win32 multi-threading\n");
- InitializeCriticalSection(&crit);
- threaded = true; //Stupid me... forgot this!!!
- currentnumthreads = 0;
- currentthreadid = 0;
-} //end of the function ThreadInitLock
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void ThreadShutdownLock(void)
-{
- DeleteCriticalSection(&crit);
- threaded = false; //Stupid me... forgot this!!!
-} //end of the function ThreadShutdownLock
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void ThreadSetupSemaphore(void)
-{
- semaphore = CreateSemaphore(NULL, 0, 99999999, "bspc");
-} //end of the function ThreadSetupSemaphore
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void ThreadShutdownSemaphore(void)
-{
-} //end of the function ThreadShutdownSemaphore
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void ThreadSemaphoreWait(void)
-{
- WaitForSingleObject(semaphore, INFINITE);
-} //end of the function ThreadSemaphoreWait
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void ThreadSemaphoreIncrease(int count)
-{
- ReleaseSemaphore(semaphore, count, NULL);
-} //end of the function ThreadSemaphoreIncrease
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void RunThreadsOn(int workcnt, qboolean showpacifier, void(*func)(int))
-{
- int threadid[MAX_THREADS];
- HANDLE threadhandle[MAX_THREADS];
- int i;
- int start, end;
-
- Log_Print("Win32 multi-threading\n");
- start = I_FloatTime ();
- dispatch = 0;
- workcount = workcnt;
- oldf = -1;
- pacifier = showpacifier;
- threaded = true;
-
- if (numthreads == -1)
- ThreadSetDefault ();
-
- if (numthreads < 1 || numthreads > MAX_THREADS) numthreads = 1;
- //
- // run threads in parallel
- //
- InitializeCriticalSection (&crit);
-
- numwaitingthreads = 0;
-
- if (numthreads == 1)
- { // use same thread
- func (0);
- } //end if
- else
- {
-// printf("starting %d threads\n", numthreads);
- for (i = 0; i < numthreads; i++)
- {
- threadhandle[i] = CreateThread(
- NULL, // LPSECURITY_ATTRIBUTES lpsa,
- 0, // DWORD cbStack,
- (LPTHREAD_START_ROUTINE)func, // LPTHREAD_START_ROUTINE lpStartAddr,
- (LPVOID)i, // LPVOID lpvThreadParm,
- 0, // DWORD fdwCreate,
- &threadid[i]);
-// printf("started thread %d\n", i);
- } //end for
-
- for (i = 0; i < numthreads; i++)
- WaitForSingleObject (threadhandle[i], INFINITE);
- } //end else
- DeleteCriticalSection (&crit);
-
- threaded = false;
- end = I_FloatTime ();
- if (pacifier) printf (" (%i)\n", end-start);
-} //end of the function RunThreadsOn
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AddThread(void (*func)(int))
-{
- thread_t *thread;
-
- if (numthreads == 1)
- {
- if (currentnumthreads >= numthreads) return;
- currentnumthreads++;
- func(-1);
- currentnumthreads--;
- } //end if
- else
- {
- ThreadLock();
- if (currentnumthreads >= numthreads)
- {
- ThreadUnlock();
- return;
- } //end if
- //allocate new thread
- thread = GetMemory(sizeof(thread_t));
- if (!thread) Error("can't allocate memory for thread\n");
-
- //
- thread->threadid = currentthreadid;
- thread->handle = CreateThread(
- NULL, // LPSECURITY_ATTRIBUTES lpsa,
- 0, // DWORD cbStack,
- (LPTHREAD_START_ROUTINE)func, // LPTHREAD_START_ROUTINE lpStartAddr,
- (LPVOID) thread->threadid, // LPVOID lpvThreadParm,
- 0, // DWORD fdwCreate,
- &thread->id);
-
- //add the thread to the end of the list
- thread->next = NULL;
- if (lastthread) lastthread->next = thread;
- else firstthread = thread;
- lastthread = thread;
- //
-#ifdef THREAD_DEBUG
- qprintf("added thread with id %d\n", thread->threadid);
-#endif //THREAD_DEBUG
- //
- currentnumthreads++;
- currentthreadid++;
- //
- ThreadUnlock();
- } //end else
-} //end of the function AddThread
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void RemoveThread(int threadid)
-{
- thread_t *thread, *last;
-
- //if a single thread
- if (threadid == -1) return;
- //
- ThreadLock();
- last = NULL;
- for (thread = firstthread; thread; thread = thread->next)
- {
- if (thread->threadid == threadid)
- {
- if (last) last->next = thread->next;
- else firstthread = thread->next;
- if (!thread->next) lastthread = last;
- //
- FreeMemory(thread);
- currentnumthreads--;
-#ifdef THREAD_DEBUG
- qprintf("removed thread with id %d\n", threadid);
-#endif //THREAD_DEBUG
- break;
- } //end if
- last = thread;
- } //end if
- if (!thread) Error("couldn't find thread with id %d", threadid);
- ThreadUnlock();
-} //end of the function RemoveThread
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void WaitForAllThreadsFinished(void)
-{
- HANDLE handle;
-
- ThreadLock();
- while(firstthread)
- {
- handle = firstthread->handle;
- ThreadUnlock();
-
- WaitForSingleObject(handle, INFINITE);
-
- ThreadLock();
- } //end while
- ThreadUnlock();
-} //end of the function WaitForAllThreadsFinished
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int GetNumThreads(void)
-{
- return currentnumthreads;
-} //end of the function GetNumThreads
-
-#endif
-
-
-//===================================================================
-//
-// OSF1
-//
-//===================================================================
-
-#if defined(__osf__)
-
-#define USED
-
-#include <pthread.h>
-
-typedef struct thread_s
-{
- pthread_t thread;
- int threadid;
- int id;
- struct thread_s *next;
-} thread_t;
-
-thread_t *firstthread;
-thread_t *lastthread;
-int currentnumthreads;
-int currentthreadid;
-
-int numthreads = 1;
-pthread_mutex_t my_mutex;
-pthread_attr_t attrib;
-static int enter;
-static int numwaitingthreads = 0;
-
-
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void ThreadSetDefault(void)
-{
- if (numthreads == -1) // not set manually
- {
- numthreads = 1;
- } //end if
- qprintf("%i threads\n", numthreads);
-} //end of the function ThreadSetDefault
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void ThreadLock(void)
-{
- if (!threaded)
- {
- Error("ThreadLock: !threaded");
- return;
- } //end if
- if (my_mutex)
- {
- pthread_mutex_lock(my_mutex);
- } //end if
- if (enter)
- Error("Recursive ThreadLock\n");
- enter = 1;
-} //end of the function ThreadLock
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void ThreadUnlock(void)
-{
- if (!threaded)
- {
- Error("ThreadUnlock: !threaded");
- return;
- } //end if
- if (!enter)
- Error("ThreadUnlock without lock\n");
- enter = 0;
- if (my_mutex)
- {
- pthread_mutex_unlock(my_mutex);
- } //end if
-} //end of the function ThreadUnlock
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void ThreadSetupLock(void)
-{
- pthread_mutexattr_t mattrib;
-
- Log_Print("pthread multi-threading\n");
-
- if (!my_mutex)
- {
- my_mutex = GetMemory(sizeof(*my_mutex));
- if (pthread_mutexattr_create (&mattrib) == -1)
- Error ("pthread_mutex_attr_create failed");
- if (pthread_mutexattr_setkind_np (&mattrib, MUTEX_FAST_NP) == -1)
- Error ("pthread_mutexattr_setkind_np failed");
- if (pthread_mutex_init (my_mutex, mattrib) == -1)
- Error ("pthread_mutex_init failed");
- }
-
- if (pthread_attr_create (&attrib) == -1)
- Error ("pthread_attr_create failed");
- if (pthread_attr_setstacksize (&attrib, 0x100000) == -1)
- Error ("pthread_attr_setstacksize failed");
-
- threaded = true;
- currentnumthreads = 0;
- currentthreadid = 0;
-} //end of the function ThreadInitLock
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void ThreadShutdownLock(void)
-{
- threaded = false;
-} //end of the function ThreadShutdownLock
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void RunThreadsOn(int workcnt, qboolean showpacifier, void(*func)(int))
-{
- int i;
- pthread_t work_threads[MAX_THREADS];
- pthread_addr_t status;
- pthread_attr_t attrib;
- pthread_mutexattr_t mattrib;
- int start, end;
-
- Log_Print("pthread multi-threading\n");
-
- start = I_FloatTime ();
- dispatch = 0;
- workcount = workcnt;
- oldf = -1;
- pacifier = showpacifier;
- threaded = true;
-
- if (numthreads < 1 || numthreads > MAX_THREADS) numthreads = 1;
-
- if (pacifier)
- setbuf (stdout, NULL);
-
- if (!my_mutex)
- {
- my_mutex = GetMemory(sizeof(*my_mutex));
- if (pthread_mutexattr_create (&mattrib) == -1)
- Error ("pthread_mutex_attr_create failed");
- if (pthread_mutexattr_setkind_np (&mattrib, MUTEX_FAST_NP) == -1)
- Error ("pthread_mutexattr_setkind_np failed");
- if (pthread_mutex_init (my_mutex, mattrib) == -1)
- Error ("pthread_mutex_init failed");
- }
-
- if (pthread_attr_create (&attrib) == -1)
- Error ("pthread_attr_create failed");
- if (pthread_attr_setstacksize (&attrib, 0x100000) == -1)
- Error ("pthread_attr_setstacksize failed");
-
- for (i=0 ; i<numthreads ; i++)
- {
- if (pthread_create(&work_threads[i], attrib
- , (pthread_startroutine_t)func, (pthread_addr_t)i) == -1)
- Error ("pthread_create failed");
- }
-
- for (i=0 ; i<numthreads ; i++)
- {
- if (pthread_join (work_threads[i], &status) == -1)
- Error ("pthread_join failed");
- }
-
- threaded = false;
-
- end = I_FloatTime ();
- if (pacifier)
- printf (" (%i)\n", end-start);
-} //end of the function RunThreadsOn
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AddThread(void (*func)(int))
-{
- thread_t *thread;
-
- if (numthreads == 1)
- {
- if (currentnumthreads >= numthreads) return;
- currentnumthreads++;
- func(-1);
- currentnumthreads--;
- } //end if
- else
- {
- ThreadLock();
- if (currentnumthreads >= numthreads)
- {
- ThreadUnlock();
- return;
- } //end if
- //allocate new thread
- thread = GetMemory(sizeof(thread_t));
- if (!thread) Error("can't allocate memory for thread\n");
- //
- thread->threadid = currentthreadid;
-
- if (pthread_create(&thread->thread, attrib, (pthread_startroutine_t)func, (pthread_addr_t)thread->threadid) == -1)
- Error ("pthread_create failed");
-
- //add the thread to the end of the list
- thread->next = NULL;
- if (lastthread) lastthread->next = thread;
- else firstthread = thread;
- lastthread = thread;
- //
-#ifdef THREAD_DEBUG
- qprintf("added thread with id %d\n", thread->threadid);
-#endif //THREAD_DEBUG
- //
- currentnumthreads++;
- currentthreadid++;
- //
- ThreadUnlock();
- } //end else
-} //end of the function AddThread
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void RemoveThread(int threadid)
-{
- thread_t *thread, *last;
-
- //if a single thread
- if (threadid == -1) return;
- //
- ThreadLock();
- last = NULL;
- for (thread = firstthread; thread; thread = thread->next)
- {
- if (thread->threadid == threadid)
- {
- if (last) last->next = thread->next;
- else firstthread = thread->next;
- if (!thread->next) lastthread = last;
- //
- FreeMemory(thread);
- currentnumthreads--;
-#ifdef THREAD_DEBUG
- qprintf("removed thread with id %d\n", threadid);
-#endif //THREAD_DEBUG
- break;
- } //end if
- last = thread;
- } //end if
- if (!thread) Error("couldn't find thread with id %d", threadid);
- ThreadUnlock();
-} //end of the function RemoveThread
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void WaitForAllThreadsFinished(void)
-{
- pthread_t *thread;
- pthread_addr_t status;
-
- ThreadLock();
- while(firstthread)
- {
- thread = &firstthread->thread;
- ThreadUnlock();
-
- if (pthread_join(*thread, &status) == -1)
- Error("pthread_join failed");
-
- ThreadLock();
- } //end while
- ThreadUnlock();
-} //end of the function WaitForAllThreadsFinished
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int GetNumThreads(void)
-{
- return currentnumthreads;
-} //end of the function GetNumThreads
-
-#endif
-
-//===================================================================
-//
-// LINUX
-//
-//===================================================================
-
-#if defined(LINUX)
-
-#define USED
-
-#include <pthread.h>
-#include <semaphore.h>
-
-typedef struct thread_s
-{
- pthread_t thread;
- int threadid;
- int id;
- struct thread_s *next;
-} thread_t;
-
-thread_t *firstthread;
-thread_t *lastthread;
-int currentnumthreads;
-int currentthreadid;
-
-int numthreads = 1;
-pthread_mutex_t my_mutex = PTHREAD_MUTEX_INITIALIZER;
-pthread_attr_t attrib;
-sem_t semaphore;
-static int enter;
-static int numwaitingthreads = 0;
-
-
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void ThreadSetDefault(void)
-{
- if (numthreads == -1) // not set manually
- {
- numthreads = 1;
- } //end if
- qprintf("%i threads\n", numthreads);
-} //end of the function ThreadSetDefault
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void ThreadLock(void)
-{
- if (!threaded)
- {
- Error("ThreadLock: !threaded");
- return;
- } //end if
- pthread_mutex_lock(&my_mutex);
- if (enter)
- Error("Recursive ThreadLock\n");
- enter = 1;
-} //end of the function ThreadLock
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void ThreadUnlock(void)
-{
- if (!threaded)
- {
- Error("ThreadUnlock: !threaded");
- return;
- } //end if
- if (!enter)
- Error("ThreadUnlock without lock\n");
- enter = 0;
- pthread_mutex_unlock(&my_mutex);
-} //end of the function ThreadUnlock
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void ThreadSetupLock(void)
-{
- pthread_mutexattr_t mattrib;
-
- Log_Print("pthread multi-threading\n");
-
- threaded = true;
- currentnumthreads = 0;
- currentthreadid = 0;
-} //end of the function ThreadInitLock
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void ThreadShutdownLock(void)
-{
- threaded = false;
-} //end of the function ThreadShutdownLock
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void ThreadSetupSemaphore(void)
-{
- sem_init(&semaphore, 0, 0);
-} //end of the function ThreadSetupSemaphore
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void ThreadShutdownSemaphore(void)
-{
- sem_destroy(&semaphore);
-} //end of the function ThreadShutdownSemaphore
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void ThreadSemaphoreWait(void)
-{
- sem_wait(&semaphore);
-} //end of the function ThreadSemaphoreWait
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void ThreadSemaphoreIncrease(int count)
-{
- int i;
-
- for (i = 0; i < count; i++)
- {
- sem_post(&semaphore);
- } //end for
-} //end of the function ThreadSemaphoreIncrease
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void RunThreadsOn(int workcnt, qboolean showpacifier, void(*func)(int))
-{
- int i;
- pthread_t work_threads[MAX_THREADS];
- void *pthread_return;
- pthread_attr_t attrib;
- pthread_mutexattr_t mattrib;
- int start, end;
-
- Log_Print("pthread multi-threading\n");
-
- start = I_FloatTime ();
- dispatch = 0;
- workcount = workcnt;
- oldf = -1;
- pacifier = showpacifier;
- threaded = true;
-
- if (numthreads < 1 || numthreads > MAX_THREADS) numthreads = 1;
-
- if (pacifier)
- setbuf (stdout, NULL);
-
- for (i=0 ; i<numthreads ; i++)
- {
- if (pthread_create(&work_threads[i], NULL, (void *)func, (void *)i) == -1)
- Error ("pthread_create failed");
- }
-
- for (i=0 ; i<numthreads ; i++)
- {
- if (pthread_join(work_threads[i], &pthread_return) == -1)
- Error ("pthread_join failed");
- }
-
- threaded = false;
-
- end = I_FloatTime ();
- if (pacifier)
- printf (" (%i)\n", end-start);
-} //end of the function RunThreadsOn
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AddThread(void (*func)(int))
-{
- thread_t *thread;
-
- if (numthreads == 1)
- {
- if (currentnumthreads >= numthreads) return;
- currentnumthreads++;
- func(-1);
- currentnumthreads--;
- } //end if
- else
- {
- ThreadLock();
- if (currentnumthreads >= numthreads)
- {
- ThreadUnlock();
- return;
- } //end if
- //allocate new thread
- thread = GetMemory(sizeof(thread_t));
- if (!thread) Error("can't allocate memory for thread\n");
- //
- thread->threadid = currentthreadid;
-
- if (pthread_create(&thread->thread, NULL, (void *)func, (void *)thread->threadid) == -1)
- Error ("pthread_create failed");
-
- //add the thread to the end of the list
- thread->next = NULL;
- if (lastthread) lastthread->next = thread;
- else firstthread = thread;
- lastthread = thread;
- //
-#ifdef THREAD_DEBUG
- qprintf("added thread with id %d\n", thread->threadid);
-#endif //THREAD_DEBUG
- //
- currentnumthreads++;
- currentthreadid++;
- //
- ThreadUnlock();
- } //end else
-} //end of the function AddThread
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void RemoveThread(int threadid)
-{
- thread_t *thread, *last;
-
- //if a single thread
- if (threadid == -1) return;
- //
- ThreadLock();
- last = NULL;
- for (thread = firstthread; thread; thread = thread->next)
- {
- if (thread->threadid == threadid)
- {
- if (last) last->next = thread->next;
- else firstthread = thread->next;
- if (!thread->next) lastthread = last;
- //
- FreeMemory(thread);
- currentnumthreads--;
-#ifdef THREAD_DEBUG
- qprintf("removed thread with id %d\n", threadid);
-#endif //THREAD_DEBUG
- break;
- } //end if
- last = thread;
- } //end if
- if (!thread) Error("couldn't find thread with id %d", threadid);
- ThreadUnlock();
-} //end of the function RemoveThread
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void WaitForAllThreadsFinished(void)
-{
- pthread_t *thread;
- void *pthread_return;
-
- ThreadLock();
- while(firstthread)
- {
- thread = &firstthread->thread;
- ThreadUnlock();
-
- if (pthread_join(*thread, &pthread_return) == -1)
- Error("pthread_join failed");
-
- ThreadLock();
- } //end while
- ThreadUnlock();
-} //end of the function WaitForAllThreadsFinished
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int GetNumThreads(void)
-{
- return currentnumthreads;
-} //end of the function GetNumThreads
-
-#endif //LINUX
-
-
-//===================================================================
-//
-// IRIX
-//
-//===================================================================
-
-#ifdef _MIPS_ISA
-
-#define USED
-
-#include <task.h>
-#include <abi_mutex.h>
-#include <sys/types.h>
-#include <sys/prctl.h>
-
-typedef struct thread_s
-{
- int threadid;
- int id;
- struct thread_s *next;
-} thread_t;
-
-thread_t *firstthread;
-thread_t *lastthread;
-int currentnumthreads;
-int currentthreadid;
-
-int numthreads = 1;
-static int enter;
-static int numwaitingthreads = 0;
-
-abilock_t lck;
-
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void ThreadSetDefault (void)
-{
- if (numthreads == -1)
- numthreads = prctl(PR_MAXPPROCS);
- printf ("%i threads\n", numthreads);
-//@@
- usconfig (CONF_INITUSERS, numthreads);
-} //end of the function ThreadSetDefault
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void ThreadLock (void)
-{
- spin_lock (&lck);
-} //end of the function ThreadLock
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void ThreadUnlock (void)
-{
- release_lock(&lck);
-} //end of the function ThreadUnlock
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void ThreadSetupLock(void)
-{
- init_lock (&lck);
-
- Log_Print("IRIX multi-threading\n");
-
- threaded = true;
- currentnumthreads = 0;
- currentthreadid = 0;
-} //end of the function ThreadInitLock
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void ThreadShutdownLock(void)
-{
- threaded = false;
-} //end of the function ThreadShutdownLock
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void RunThreadsOn (int workcnt, qboolean showpacifier, void(*func)(int))
-{
- int i;
- int pid[MAX_THREADS];
- int start, end;
-
- start = I_FloatTime ();
- dispatch = 0;
- workcount = workcnt;
- oldf = -1;
- pacifier = showpacifier;
- threaded = true;
-
- if (numthreads < 1 || numthreads > MAX_THREADS) numthreads = 1;
-
- if (pacifier)
- setbuf (stdout, NULL);
-
- init_lock (&lck);
-
- for (i=0 ; i<numthreads-1 ; i++)
- {
- pid[i] = sprocsp ( (void (*)(void *, size_t))func, PR_SALL, (void *)i
- , NULL, 0x100000);
-// pid[i] = sprocsp ( (void (*)(void *, size_t))func, PR_SALL, (void *)i
-// , NULL, 0x80000);
- if (pid[i] == -1)
- {
- perror ("sproc");
- Error ("sproc failed");
- }
- }
-
- func(i);
-
- for (i=0 ; i<numthreads-1 ; i++)
- wait (NULL);
-
- threaded = false;
-
- end = I_FloatTime ();
- if (pacifier)
- printf (" (%i)\n", end-start);
-} //end of the function RunThreadsOn
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AddThread(void (*func)(int))
-{
- thread_t *thread;
-
- if (numthreads == 1)
- {
- if (currentnumthreads >= numthreads) return;
- currentnumthreads++;
- func(-1);
- currentnumthreads--;
- } //end if
- else
- {
- ThreadLock();
- if (currentnumthreads >= numthreads)
- {
- ThreadUnlock();
- return;
- } //end if
- //allocate new thread
- thread = GetMemory(sizeof(thread_t));
- if (!thread) Error("can't allocate memory for thread\n");
- //
- thread->threadid = currentthreadid;
-
- thread->id = sprocsp ( (void (*)(void *, size_t))func, PR_SALL, (void *)thread->threadid, NULL, 0x100000);
- if (thread->id == -1)
- {
- perror ("sproc");
- Error ("sproc failed");
- }
-
- //add the thread to the end of the list
- thread->next = NULL;
- if (lastthread) lastthread->next = thread;
- else firstthread = thread;
- lastthread = thread;
- //
-#ifdef THREAD_DEBUG
- qprintf("added thread with id %d\n", thread->threadid);
-#endif //THREAD_DEBUG
- //
- currentnumthreads++;
- currentthreadid++;
- //
- ThreadUnlock();
- } //end else
-} //end of the function AddThread
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void RemoveThread(int threadid)
-{
- thread_t *thread, *last;
-
- //if a single thread
- if (threadid == -1) return;
- //
- ThreadLock();
- last = NULL;
- for (thread = firstthread; thread; thread = thread->next)
- {
- if (thread->threadid == threadid)
- {
- if (last) last->next = thread->next;
- else firstthread = thread->next;
- if (!thread->next) lastthread = last;
- //
- FreeMemory(thread);
- currentnumthreads--;
-#ifdef THREAD_DEBUG
- qprintf("removed thread with id %d\n", threadid);
-#endif //THREAD_DEBUG
- break;
- } //end if
- last = thread;
- } //end if
- if (!thread) Error("couldn't find thread with id %d", threadid);
- ThreadUnlock();
-} //end of the function RemoveThread
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void WaitForAllThreadsFinished(void)
-{
- ThreadLock();
- while(firstthread)
- {
- ThreadUnlock();
-
- //wait (NULL);
-
- ThreadLock();
- } //end while
- ThreadUnlock();
-} //end of the function WaitForAllThreadsFinished
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int GetNumThreads(void)
-{
- return currentnumthreads;
-} //end of the function GetNumThreads
-
-#endif //_MIPS_ISA
-
-
-//=======================================================================
-//
-// SINGLE THREAD
-//
-//=======================================================================
-
-#ifndef USED
-
-int numthreads = 1;
-int currentnumthreads = 0;
-
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void ThreadSetDefault(void)
-{
- numthreads = 1;
-} //end of the function ThreadSetDefault
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void ThreadLock(void)
-{
-} //end of the function ThreadLock
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void ThreadUnlock(void)
-{
-} //end of the function ThreadUnlock
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void ThreadSetupLock(void)
-{
- Log_Print("no multi-threading\n");
-} //end of the function ThreadInitLock
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void ThreadShutdownLock(void)
-{
-} //end of the function ThreadShutdownLock
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void ThreadSetupSemaphore(void)
-{
-} //end of the function ThreadSetupSemaphore
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void ThreadShutdownSemaphore(void)
-{
-} //end of the function ThreadShutdownSemaphore
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void ThreadSemaphoreWait(void)
-{
-} //end of the function ThreadSemaphoreWait
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void ThreadSemaphoreIncrease(int count)
-{
-} //end of the function ThreadSemaphoreIncrease
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void RunThreadsOn(int workcnt, qboolean showpacifier, void(*func)(int))
-{
- int start, end;
-
- Log_Print("no multi-threading\n");
- dispatch = 0;
- workcount = workcnt;
- oldf = -1;
- pacifier = showpacifier;
- start = I_FloatTime ();
-#ifdef NeXT
- if (pacifier)
- setbuf (stdout, NULL);
-#endif
- func(0);
-
- end = I_FloatTime ();
- if (pacifier)
- printf (" (%i)\n", end-start);
-} //end of the function RunThreadsOn
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AddThread(void (*func)(int))
-{
- if (currentnumthreads >= numthreads) return;
- currentnumthreads++;
- func(-1);
- currentnumthreads--;
-} //end of the function AddThread
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void RemoveThread(int threadid)
-{
-} //end of the function RemoveThread
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void WaitForAllThreadsFinished(void)
-{
-} //end of the function WaitForAllThreadsFinished
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int GetNumThreads(void)
-{
- return currentnumthreads;
-} //end of the function GetNumThreads
-
-#endif //USED
diff --git a/code/bspc/l_threads.h b/code/bspc/l_threads.h
deleted file mode 100644
index 5e0df82..0000000
--- a/code/bspc/l_threads.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-extern int numthreads;
-
-void ThreadSetDefault (void);
-int GetThreadWork (void);
-void RunThreadsOnIndividual (int workcnt, qboolean showpacifier, void(*func)(int));
-void RunThreadsOn (int workcnt, qboolean showpacifier, void(*func)(int));
-
-//mutex
-void ThreadSetupLock(void);
-void ThreadShutdownLock(void);
-void ThreadLock (void);
-void ThreadUnlock (void);
-//semaphore
-void ThreadSetupSemaphore(void);
-void ThreadShutdownSemaphore(void);
-void ThreadSemaphoreWait(void);
-void ThreadSemaphoreIncrease(int count);
-//add/remove threads
-void AddThread(void (*func)(int));
-void RemoveThread(int threadid);
-void WaitForAllThreadsFinished(void);
-int GetNumThreads(void);
-
diff --git a/code/bspc/l_utils.c b/code/bspc/l_utils.c
deleted file mode 100644
index bf92e04..0000000
--- a/code/bspc/l_utils.c
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-//#ifndef BOTLIB
-//#define BOTLIB
-//#endif //BOTLIB
-
-#ifdef BOTLIB
-#include "q_shared.h"
-#include "qfiles.h"
-#include "botlib.h"
-#include "l_log.h"
-#include "l_libvar.h"
-#include "l_memory.h"
-//#include "l_utils.h"
-#include "be_interface.h"
-#else //BOTLIB
-#include "qbsp.h"
-#include "l_mem.h"
-#endif //BOTLIB
-
-#ifdef BOTLIB
-//========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//========================================================================
-void Vector2Angles(vec3_t value1, vec3_t angles)
-{
- float forward;
- float yaw, pitch;
-
- if (value1[1] == 0 && value1[0] == 0)
- {
- yaw = 0;
- if (value1[2] > 0) pitch = 90;
- else pitch = 270;
- } //end if
- else
- {
- yaw = (int) (atan2(value1[1], value1[0]) * 180 / M_PI);
- if (yaw < 0) yaw += 360;
-
- forward = sqrt (value1[0]*value1[0] + value1[1]*value1[1]);
- pitch = (int) (atan2(value1[2], forward) * 180 / M_PI);
- if (pitch < 0) pitch += 360;
- } //end else
-
- angles[PITCH] = -pitch;
- angles[YAW] = yaw;
- angles[ROLL] = 0;
-} //end of the function Vector2Angles
-#endif //BOTLIB
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void ConvertPath(char *path)
-{
- while(*path)
- {
- if (*path == '/' || *path == '\\') *path = PATHSEPERATOR_CHAR;
- path++;
- } //end while
-} //end of the function ConvertPath
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AppendPathSeperator(char *path, int length)
-{
- int pathlen = strlen(path);
-
- if (strlen(path) && length-pathlen > 1 && path[pathlen-1] != '/' && path[pathlen-1] != '\\')
- {
- path[pathlen] = PATHSEPERATOR_CHAR;
- path[pathlen+1] = '\0';
- } //end if
-} //end of the function AppenPathSeperator
-
-#if 0
-//===========================================================================
-// returns pointer to file handle
-// sets offset to and length of 'filename' in the pak file
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-qboolean FindFileInPak(char *pakfile, char *filename, foundfile_t *file)
-{
- FILE *fp;
- dpackheader_t packheader;
- dpackfile_t *packfiles;
- int numdirs, i;
- char path[MAX_PATH];
-
- //open the pak file
- fp = fopen(pakfile, "rb");
- if (!fp)
- {
- return false;
- } //end if
- //read pak header, check for valid pak id and seek to the dir entries
- if ((fread(&packheader, 1, sizeof(dpackheader_t), fp) != sizeof(dpackheader_t))
- || (packheader.ident != IDPAKHEADER)
- || (fseek(fp, LittleLong(packheader.dirofs), SEEK_SET))
- )
- {
- fclose(fp);
- return false;
- } //end if
- //number of dir entries in the pak file
- numdirs = LittleLong(packheader.dirlen) / sizeof(dpackfile_t);
- packfiles = (dpackfile_t *) GetMemory(numdirs * sizeof(dpackfile_t));
- //read the dir entry
- if (fread(packfiles, sizeof(dpackfile_t), numdirs, fp) != numdirs)
- {
- fclose(fp);
- FreeMemory(packfiles);
- return false;
- } //end if
- fclose(fp);
- //
- strcpy(path, filename);
- ConvertPath(path);
- //find the dir entry in the pak file
- for (i = 0; i < numdirs; i++)
- {
- //convert the dir entry name
- ConvertPath(packfiles[i].name);
- //compare the dir entry name with the filename
- if (Q_strcasecmp(packfiles[i].name, path) == 0)
- {
- strcpy(file->filename, pakfile);
- file->offset = LittleLong(packfiles[i].filepos);
- file->length = LittleLong(packfiles[i].filelen);
- FreeMemory(packfiles);
- return true;
- } //end if
- } //end for
- FreeMemory(packfiles);
- return false;
-} //end of the function FindFileInPak
-//===========================================================================
-// find a Quake2 file
-// returns full path in 'filename'
-// sets offset and length of the file
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-qboolean FindQuakeFile2(char *basedir, char *gamedir, char *filename, foundfile_t *file)
-{
- int dir, i;
- //NOTE: 3 is necessary (LCC bug???)
- char gamedirs[3][MAX_PATH] = {"","",""};
- char filedir[MAX_PATH] = "";
-
- //
- if (gamedir) strncpy(gamedirs[0], gamedir, MAX_PATH);
- strncpy(gamedirs[1], "baseq2", MAX_PATH);
- //
- //find the file in the two game directories
- for (dir = 0; dir < 2; dir++)
- {
- //check if the file is in a directory
- filedir[0] = 0;
- if (basedir && strlen(basedir))
- {
- strncpy(filedir, basedir, MAX_PATH);
- AppendPathSeperator(filedir, MAX_PATH);
- } //end if
- if (strlen(gamedirs[dir]))
- {
- strncat(filedir, gamedirs[dir], MAX_PATH - strlen(filedir));
- AppendPathSeperator(filedir, MAX_PATH);
- } //end if
- strncat(filedir, filename, MAX_PATH - strlen(filedir));
- ConvertPath(filedir);
- Log_Write("accessing %s", filedir);
- if (!access(filedir, 0x04))
- {
- strcpy(file->filename, filedir);
- file->length = 0;
- file->offset = 0;
- return true;
- } //end if
- //check if the file is in a pak?.pak
- for (i = 0; i < 10; i++)
- {
- filedir[0] = 0;
- if (basedir && strlen(basedir))
- {
- strncpy(filedir, basedir, MAX_PATH);
- AppendPathSeperator(filedir, MAX_PATH);
- } //end if
- if (strlen(gamedirs[dir]))
- {
- strncat(filedir, gamedirs[dir], MAX_PATH - strlen(filedir));
- AppendPathSeperator(filedir, MAX_PATH);
- } //end if
- sprintf(&filedir[strlen(filedir)], "pak%d.pak\0", i);
- if (!access(filedir, 0x04))
- {
- Log_Write("searching %s in %s", filename, filedir);
- if (FindFileInPak(filedir, filename, file)) return true;
- } //end if
- } //end for
- } //end for
- file->offset = 0;
- file->length = 0;
- return false;
-} //end of the function FindQuakeFile2
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-#ifdef BOTLIB
-qboolean FindQuakeFile(char *filename, foundfile_t *file)
-{
- return FindQuakeFile2(LibVarGetString("basedir"),
- LibVarGetString("gamedir"), filename, file);
-} //end of the function FindQuakeFile
-#else //BOTLIB
-qboolean FindQuakeFile(char *basedir, char *gamedir, char *filename, foundfile_t *file)
-{
- return FindQuakeFile2(basedir, gamedir, filename, file);
-} //end of the function FindQuakeFile
-#endif //BOTLIB
-
-#endif
diff --git a/code/bspc/l_utils.h b/code/bspc/l_utils.h
deleted file mode 100644
index 3bbc612..0000000
--- a/code/bspc/l_utils.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-#ifndef MAX_PATH
- #define MAX_PATH 64
-#endif
-
-#ifndef PATH_SEPERATORSTR
- #if defined(WIN32)|defined(_WIN32)|defined(__NT__)|defined(__WINDOWS__)|defined(__WINDOWS_386__)
- #define PATHSEPERATOR_STR "\\"
- #else
- #define PATHSEPERATOR_STR "/"
- #endif
-#endif
-#ifndef PATH_SEPERATORCHAR
- #if defined(WIN32)|defined(_WIN32)|defined(__NT__)|defined(__WINDOWS__)|defined(__WINDOWS_386__)
- #define PATHSEPERATOR_CHAR '\\'
- #else
- #define PATHSEPERATOR_CHAR '/'
- #endif
-#endif
-
-//random in the range [0, 1]
-#define random() ((rand () & 0x7fff) / ((float)0x7fff))
-//random in the range [-1, 1]
-#define crandom() (2.0 * (random() - 0.5))
-//min and max
-#define Maximum(x,y) (x > y ? x : y)
-#define Minimum(x,y) (x < y ? x : y)
-//absolute value
-#define FloatAbs(x) (*(float *) &((* (int *) &(x)) & 0x7FFFFFFF))
-#define IntAbs(x) (~(x))
-//coordinates
-#define _X 0
-#define _Y 1
-#define _Z 2
-
-typedef struct foundfile_s
-{
- int offset;
- int length;
- char filename[MAX_PATH]; //screw LCC, array must be at end of struct
-} foundfile_t;
-
-void Vector2Angles(vec3_t value1, vec3_t angles);
-//set the correct path seperators
-void ConvertPath(char *path);
-//append a path seperator to the given path not exceeding the length
-void AppendPathSeperator(char *path, int length);
-//find a file in a pak file
-qboolean FindFileInPak(char *pakfile, char *filename, foundfile_t *file);
-//find a quake file
-#ifdef BOTLIB
-qboolean FindQuakeFile(char *filename, foundfile_t *file);
-#else //BOTLIB
-qboolean FindQuakeFile(char *basedir, char *gamedir, char *filename, foundfile_t *file);
-#endif //BOTLIB
-
-
-
diff --git a/code/bspc/lcc.mak b/code/bspc/lcc.mak
deleted file mode 100644
index 1b99864..0000000
--- a/code/bspc/lcc.mak
+++ /dev/null
@@ -1,61 +0,0 @@
-#
-# Makefile for the BSPC tool for the Gladiator Bot
-# Intended for LCC-Win32
-#
-
-CC=lcc
-CFLAGS=-DC_ONLY -o
-OBJS= _files.obj\
- aas_areamerging.obj\
- aas_cfg.obj\
- aas_create.obj\
- aas_edgemelting.obj\
- aas_facemerging.obj\
- aas_file.obj\
- aas_gsubdiv.obj\
- aas_map.obj\
- aas_prunenodes.obj\
- aas_store.obj\
- brushbsp.obj\
- bspc.obj\
- csg.obj\
- faces.obj\
- glfile.obj\
- l_bsp_hl.obj\
- l_bsp_q1.obj\
- l_bsp_q2.obj\
- l_bsp_sin.obj\
- l_cmd.obj\
- l_log.obj\
- l_math.obj\
- l_mem.obj\
- l_poly.obj\
- l_qfiles.obj\
- l_script.obj\
- l_threads.obj\
- l_utils.obj\
- leakfile.obj\
- map.obj\
- map_hl.obj\
- map_q1.obj\
- map_q2.obj\
- map_q2_new.obj\
- map_sin.obj\
- nodraw.obj\
- portals.obj\
- prtfile.obj\
- textures.obj\
- tree.obj\
- writebsp.obj
-
-all: bspc.exe
-
-bspc.exe: $(OBJS)
- lcclnk
-
-clean:
- del *.obj bspc.exe
-
-%.obj: %.c
- $(CC) $(CFLAGS) $<
-
diff --git a/code/bspc/leakfile.c b/code/bspc/leakfile.c
deleted file mode 100644
index 15b2d51..0000000
--- a/code/bspc/leakfile.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-#include "qbsp.h"
-
-/*
-==============================================================================
-
-LEAF FILE GENERATION
-
-Save out name.line for qe3 to read
-==============================================================================
-*/
-
-
-/*
-=============
-LeakFile
-
-Finds the shortest possible chain of portals
-that leads from the outside leaf to a specifically
-occupied leaf
-=============
-*/
-void LeakFile (tree_t *tree)
-{
- vec3_t mid;
- FILE *linefile;
- char filename[1024];
- node_t *node;
- int count;
-
- if (!tree->outside_node.occupied)
- return;
-
- qprintf ("--- LeakFile ---\n");
-
- //
- // write the points to the file
- //
- sprintf (filename, "%s.lin", source);
- qprintf ("%s\n", filename);
- linefile = fopen (filename, "w");
- if (!linefile)
- Error ("Couldn't open %s\n", filename);
-
- count = 0;
- node = &tree->outside_node;
- while (node->occupied > 1)
- {
- int next;
- portal_t *p, *nextportal;
- node_t *nextnode;
- int s;
-
- // find the best portal exit
- next = node->occupied;
- for (p=node->portals ; p ; p = p->next[!s])
- {
- s = (p->nodes[0] == node);
- if (p->nodes[s]->occupied
- && p->nodes[s]->occupied < next)
- {
- nextportal = p;
- nextnode = p->nodes[s];
- next = nextnode->occupied;
- }
- }
- node = nextnode;
- WindingCenter (nextportal->winding, mid);
- fprintf (linefile, "%f %f %f\n", mid[0], mid[1], mid[2]);
- count++;
- }
- // add the occupant center
- GetVectorForKey (node->occupant, "origin", mid);
-
- fprintf (linefile, "%f %f %f\n", mid[0], mid[1], mid[2]);
- qprintf ("%5i point linefile\n", count+1);
-
- fclose (linefile);
-}
-
diff --git a/code/bspc/linux-i386.mak b/code/bspc/linux-i386.mak
deleted file mode 100644
index dd9566d..0000000
--- a/code/bspc/linux-i386.mak
+++ /dev/null
@@ -1,109 +0,0 @@
-#
-# Makefile for the BSPC tool for the Gladiator Bot
-# Intended for gcc/Linux
-#
-
-ARCH=i386
-CC=gcc
-BASE_CFLAGS=-Dstricmp=strcasecmp
-
-#use these cflags to optimize it
-CFLAGS=$(BASE_CFLAGS) -m486 -O6 -ffast-math -funroll-loops \
- -fomit-frame-pointer -fexpensive-optimizations -malign-loops=2 \
- -malign-jumps=2 -malign-functions=2 -DLINUX -DBSPC
-#use these when debugging
-#CFLAGS=$(BASE_CFLAGS) -g
-
-LDFLAGS=-ldl -lm -lpthread
-
-DO_CC=$(CC) $(CFLAGS) -o $@ -c $<
-
-#############################################################################
-# SETUP AND BUILD BSPC
-#############################################################################
-
-.c.o:
- $(DO_CC)
-
-GAME_OBJS = \
- _files.o\
- aas_areamerging.o\
- aas_cfg.o\
- aas_create.o\
- aas_edgemelting.o\
- aas_facemerging.o\
- aas_file.o\
- aas_gsubdiv.o\
- aas_map.o\
- aas_prunenodes.o\
- aas_store.o\
- be_aas_bspc.o\
- ../botlib/be_aas_bspq3.o\
- ../botlib/be_aas_cluster.o\
- ../botlib/be_aas_move.o\
- ../botlib/be_aas_optimize.o\
- ../botlib/be_aas_reach.o\
- ../botlib/be_aas_sample.o\
- brushbsp.o\
- bspc.o\
- ../qcommon/cm_load.o\
- ../qcommon/cm_patch.o\
- ../qcommon/cm_test.o\
- ../qcommon/cm_trace.o\
- csg.o\
- glfile.o\
- l_bsp_ent.o\
- l_bsp_hl.o\
- l_bsp_q1.o\
- l_bsp_q2.o\
- l_bsp_q3.o\
- l_bsp_sin.o\
- l_cmd.o\
- ../botlib/l_libvar.o\
- l_log.o\
- l_math.o\
- l_mem.o\
- l_poly.o\
- ../botlib/l_precomp.o\
- l_qfiles.o\
- ../botlib/l_script.o\
- ../botlib/l_struct.o\
- l_threads.o\
- l_utils.o\
- leakfile.o\
- map.o\
- map_hl.o\
- map_q1.o\
- map_q2.o\
- map_q3.o\
- map_sin.o\
- ../qcommon/md4.o\
- nodraw.o\
- portals.o\
- tetrahedron.o\
- textures.o\
- tree.o\
- ../qcommon/unzip.o
-
-bspc$(ARCH) : $(GAME_OBJS)
- $(CC) $(CFLAGS) -o $@ $(GAME_OBJS) $(LDFLAGS)
-
-
-#############################################################################
-# MISC
-#############################################################################
-
-clean:
- -rm -f $(GAME_OBJS)
-
-depend:
- gcc -MM $(GAME_OBJS:.o=.c)
-
-
-install:
- cp bspci386 ..
-
-#
-# From "make depend"
-#
-
diff --git a/code/bspc/map.c b/code/bspc/map.c
deleted file mode 100644
index c3c5104..0000000
--- a/code/bspc/map.c
+++ /dev/null
@@ -1,1267 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-#include "qbsp.h"
-#include "l_bsp_hl.h"
-#include "l_bsp_q1.h"
-#include "l_bsp_q2.h"
-#include "l_bsp_q3.h"
-#include "l_bsp_sin.h"
-#include "l_mem.h"
-#include "../botlib/aasfile.h" //aas_bbox_t
-#include "aas_store.h" //AAS_MAX_BBOXES
-#include "aas_cfg.h"
-
-#define Sign(x) (x < 0 ? 1 : 0)
-
-int nummapbrushes;
-mapbrush_t mapbrushes[MAX_MAPFILE_BRUSHES];
-
-int nummapbrushsides;
-side_t brushsides[MAX_MAPFILE_BRUSHSIDES];
-brush_texture_t side_brushtextures[MAX_MAPFILE_BRUSHSIDES];
-
-int nummapplanes;
-plane_t mapplanes[MAX_MAPFILE_PLANES];
-int mapplaneusers[MAX_MAPFILE_PLANES];
-
-#define PLANE_HASHES 1024
-plane_t *planehash[PLANE_HASHES];
-vec3_t map_mins, map_maxs;
-
-#ifdef SIN
-textureref_t side_newrefs[MAX_MAPFILE_BRUSHSIDES];
-#endif
-
-map_texinfo_t map_texinfo[MAX_MAPFILE_TEXINFO];
-int map_numtexinfo;
-int loadedmaptype; //loaded map type
-
-// undefine to make plane finding use linear sort
-#define USE_HASHING
-
-int c_boxbevels;
-int c_edgebevels;
-int c_areaportals;
-int c_clipbrushes;
-int c_squattbrushes;
-int c_writtenbrushes;
-
-/*
-=============================================================================
-
-PLANE FINDING
-
-=============================================================================
-*/
-
-
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int PlaneSignBits(vec3_t normal)
-{
- int i, signbits;
-
- signbits = 0;
- for (i = 2; i >= 0; i--)
- {
- signbits = (signbits << 1) + Sign(normal[i]);
- } //end for
- return signbits;
-} //end of the function PlaneSignBits
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int PlaneTypeForNormal(vec3_t normal)
-{
- vec_t ax, ay, az;
-
-// NOTE: should these have an epsilon around 1.0?
- if (normal[0] == 1.0 || normal[0] == -1.0)
- return PLANE_X;
- if (normal[1] == 1.0 || normal[1] == -1.0)
- return PLANE_Y;
- if (normal[2] == 1.0 || normal[2] == -1.0)
- return PLANE_Z;
-
- ax = fabs(normal[0]);
- ay = fabs(normal[1]);
- az = fabs(normal[2]);
-
- if (ax >= ay && ax >= az)
- return PLANE_ANYX;
- if (ay >= ax && ay >= az)
- return PLANE_ANYY;
- return PLANE_ANYZ;
-} //end of the function PlaneTypeForNormal
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-//ME NOTE: changed from 0.00001
-#define NORMAL_EPSILON 0.0001
-//ME NOTE: changed from 0.01
-#define DIST_EPSILON 0.02
-qboolean PlaneEqual(plane_t *p, vec3_t normal, vec_t dist)
-{
-#if 1
- if (
- fabs(p->normal[0] - normal[0]) < NORMAL_EPSILON
- && fabs(p->normal[1] - normal[1]) < NORMAL_EPSILON
- && fabs(p->normal[2] - normal[2]) < NORMAL_EPSILON
- && fabs(p->dist - dist) < DIST_EPSILON )
- return true;
-#else
- if (p->normal[0] == normal[0]
- && p->normal[1] == normal[1]
- && p->normal[2] == normal[2]
- && p->dist == dist)
- return true;
-#endif
- return false;
-} //end of the function PlaneEqual
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AddPlaneToHash(plane_t *p)
-{
- int hash;
-
- hash = (int)fabs(p->dist) / 8;
- hash &= (PLANE_HASHES-1);
-
- p->hash_chain = planehash[hash];
- planehash[hash] = p;
-} //end of the function AddPlaneToHash
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int CreateNewFloatPlane (vec3_t normal, vec_t dist)
-{
- plane_t *p, temp;
-
- if (VectorLength(normal) < 0.5)
- Error ("FloatPlane: bad normal");
- // create a new plane
- if (nummapplanes+2 > MAX_MAPFILE_PLANES)
- Error ("MAX_MAPFILE_PLANES");
-
- p = &mapplanes[nummapplanes];
- VectorCopy (normal, p->normal);
- p->dist = dist;
- p->type = (p+1)->type = PlaneTypeForNormal (p->normal);
- p->signbits = PlaneSignBits(p->normal);
-
- VectorSubtract (vec3_origin, normal, (p+1)->normal);
- (p+1)->dist = -dist;
- (p+1)->signbits = PlaneSignBits((p+1)->normal);
-
- nummapplanes += 2;
-
- // allways put axial planes facing positive first
- if (p->type < 3)
- {
- if (p->normal[0] < 0 || p->normal[1] < 0 || p->normal[2] < 0)
- {
- // flip order
- temp = *p;
- *p = *(p+1);
- *(p+1) = temp;
-
- AddPlaneToHash (p);
- AddPlaneToHash (p+1);
- return nummapplanes - 1;
- }
- }
-
- AddPlaneToHash (p);
- AddPlaneToHash (p+1);
- return nummapplanes - 2;
-} //end of the function CreateNewFloatPlane
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void SnapVector(vec3_t normal)
-{
- int i;
-
- for (i=0 ; i<3 ; i++)
- {
- if ( fabs(normal[i] - 1) < NORMAL_EPSILON )
- {
- VectorClear (normal);
- normal[i] = 1;
- break;
- }
- if ( fabs(normal[i] - -1) < NORMAL_EPSILON )
- {
- VectorClear (normal);
- normal[i] = -1;
- break;
- }
- }
-} //end of the function SnapVector
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void SnapPlane(vec3_t normal, vec_t *dist)
-{
- SnapVector(normal);
-
- if (fabs(*dist-Q_rint(*dist)) < DIST_EPSILON)
- *dist = Q_rint(*dist);
-} //end of the function SnapPlane
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-#ifndef USE_HASHING
-int FindFloatPlane(vec3_t normal, vec_t dist)
-{
- int i;
- plane_t *p;
-
- SnapPlane(normal, &dist);
- for (i = 0, p = mapplanes; i < nummapplanes; i++, p++)
- {
- if (PlaneEqual (p, normal, dist))
- {
- mapplaneusers[i]++;
- return i;
- } //end if
- } //end for
- i = CreateNewFloatPlane (normal, dist);
- mapplaneusers[i]++;
- return i;
-} //end of the function FindFloatPlane
-#else
-int FindFloatPlane (vec3_t normal, vec_t dist)
-{
- int i;
- plane_t *p;
- int hash, h;
-
- SnapPlane (normal, &dist);
- hash = (int)fabs(dist) / 8;
- hash &= (PLANE_HASHES-1);
-
- // search the border bins as well
- for (i = -1; i <= 1; i++)
- {
- h = (hash+i)&(PLANE_HASHES-1);
- for (p = planehash[h]; p; p = p->hash_chain)
- {
- if (PlaneEqual(p, normal, dist))
- {
- mapplaneusers[p-mapplanes]++;
- return p - mapplanes;
- } //end if
- } //end for
- } //end for
- i = CreateNewFloatPlane (normal, dist);
- mapplaneusers[i]++;
- return i;
-} //end of the function FindFloatPlane
-#endif
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int PlaneFromPoints (int *p0, int *p1, int *p2)
-{
- vec3_t t1, t2, normal;
- vec_t dist;
-
- VectorSubtract (p0, p1, t1);
- VectorSubtract (p2, p1, t2);
- CrossProduct (t1, t2, normal);
- VectorNormalize (normal);
-
- dist = DotProduct (p0, normal);
-
- return FindFloatPlane (normal, dist);
-} //end of the function PlaneFromPoints
-//===========================================================================
-// Adds any additional planes necessary to allow the brush to be expanded
-// against axial bounding boxes
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AddBrushBevels (mapbrush_t *b)
-{
- int axis, dir;
- int i, j, k, l, order;
- side_t sidetemp;
- brush_texture_t tdtemp;
-#ifdef SIN
- textureref_t trtemp;
-#endif
- side_t *s, *s2;
- vec3_t normal;
- float dist;
- winding_t *w, *w2;
- vec3_t vec, vec2;
- float d;
-
- //
- // add the axial planes
- //
- order = 0;
- for (axis=0 ; axis <3 ; axis++)
- {
- for (dir=-1 ; dir <= 1 ; dir+=2, order++)
- {
- // see if the plane is allready present
- for (i=0, s=b->original_sides ; i<b->numsides ; i++,s++)
- {
- if (mapplanes[s->planenum].normal[axis] == dir)
- break;
- }
-
- if (i == b->numsides)
- { // add a new side
- if (nummapbrushsides == MAX_MAP_BRUSHSIDES)
- Error ("MAX_MAP_BRUSHSIDES");
- nummapbrushsides++;
- b->numsides++;
- VectorClear (normal);
- normal[axis] = dir;
- if (dir == 1)
- dist = b->maxs[axis];
- else
- dist = -b->mins[axis];
- s->planenum = FindFloatPlane (normal, dist);
- s->texinfo = b->original_sides[0].texinfo;
-#ifdef SIN
- s->lightinfo = b->original_sides[0].lightinfo;
-#endif
- s->contents = b->original_sides[0].contents;
- s->flags |= SFL_BEVEL;
- c_boxbevels++;
- }
-
- // if the plane is not in it canonical order, swap it
- if (i != order)
- {
- sidetemp = b->original_sides[order];
- b->original_sides[order] = b->original_sides[i];
- b->original_sides[i] = sidetemp;
-
- j = b->original_sides - brushsides;
- tdtemp = side_brushtextures[j+order];
- side_brushtextures[j+order] = side_brushtextures[j+i];
- side_brushtextures[j+i] = tdtemp;
-
-#ifdef SIN
- trtemp = side_newrefs[j+order];
- side_newrefs[j+order] = side_newrefs[j+i];
- side_newrefs[j+i] = trtemp;
-#endif
- }
- }
- }
-
- //
- // add the edge bevels
- //
- if (b->numsides == 6)
- return; // pure axial
-
- // test the non-axial plane edges
- for (i=6 ; i<b->numsides ; i++)
- {
- s = b->original_sides + i;
- w = s->winding;
- if (!w)
- continue;
- for (j=0 ; j<w->numpoints ; j++)
- {
- k = (j+1)%w->numpoints;
- VectorSubtract (w->p[j], w->p[k], vec);
- if (VectorNormalize (vec) < 0.5)
- continue;
- SnapVector (vec);
- for (k=0 ; k<3 ; k++)
- if ( vec[k] == -1 || vec[k] == 1)
- break; // axial
- if (k != 3)
- continue; // only test non-axial edges
-
- // try the six possible slanted axials from this edge
- for (axis=0 ; axis <3 ; axis++)
- {
- for (dir=-1 ; dir <= 1 ; dir+=2)
- {
- // construct a plane
- VectorClear (vec2);
- vec2[axis] = dir;
- CrossProduct (vec, vec2, normal);
- if (VectorNormalize (normal) < 0.5)
- continue;
- dist = DotProduct (w->p[j], normal);
-
- // if all the points on all the sides are
- // behind this plane, it is a proper edge bevel
- for (k=0 ; k<b->numsides ; k++)
- {
- // if this plane has allready been used, skip it
- if (PlaneEqual (&mapplanes[b->original_sides[k].planenum]
- , normal, dist) )
- break;
-
- w2 = b->original_sides[k].winding;
- if (!w2)
- continue;
- for (l=0 ; l<w2->numpoints ; l++)
- {
- d = DotProduct (w2->p[l], normal) - dist;
- if (d > 0.1)
- break; // point in front
- }
- if (l != w2->numpoints)
- break;
- }
-
- if (k != b->numsides)
- continue; // wasn't part of the outer hull
- // add this plane
- if (nummapbrushsides == MAX_MAP_BRUSHSIDES)
- Error ("MAX_MAP_BRUSHSIDES");
- nummapbrushsides++;
- s2 = &b->original_sides[b->numsides];
- s2->planenum = FindFloatPlane (normal, dist);
- s2->texinfo = b->original_sides[0].texinfo;
-#ifdef SIN
- s2->lightinfo = b->original_sides[0].lightinfo;
-#endif
- s2->contents = b->original_sides[0].contents;
- s2->flags |= SFL_BEVEL;
- c_edgebevels++;
- b->numsides++;
- }
- }
- }
- }
-} //end of the function AddBrushBevels
-//===========================================================================
-// creates windigs for sides and mins / maxs for the brush
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-qboolean MakeBrushWindings(mapbrush_t *ob)
-{
- int i, j;
- winding_t *w;
- side_t *side;
- plane_t *plane;
-
- ClearBounds (ob->mins, ob->maxs);
-
- for (i = 0; i < ob->numsides; i++)
- {
- plane = &mapplanes[ob->original_sides[i].planenum];
- w = BaseWindingForPlane(plane->normal, plane->dist);
- for (j = 0; j <ob->numsides && w; j++)
- {
- if (i == j) continue;
- if (ob->original_sides[j].flags & SFL_BEVEL) continue;
- plane = &mapplanes[ob->original_sides[j].planenum^1];
- ChopWindingInPlace(&w, plane->normal, plane->dist, 0); //CLIP_EPSILON);
- }
-
- side = &ob->original_sides[i];
- side->winding = w;
- if (w)
- {
- side->flags |= SFL_VISIBLE;
- for (j = 0; j < w->numpoints; j++)
- AddPointToBounds (w->p[j], ob->mins, ob->maxs);
- }
- }
-
- for (i = 0; i < 3; i++)
- {
- //IDBUG: all the indexes into the mins and maxs were zero (not using i)
- if (ob->mins[i] < -MAX_MAP_BOUNDS || ob->maxs[i] > MAX_MAP_BOUNDS)
- {
- Log_Print("entity %i, brush %i: bounds out of range\n", ob->entitynum, ob->brushnum);
- ob->numsides = 0; //remove the brush
- break;
- } //end if
- if (ob->mins[i] > MAX_MAP_BOUNDS || ob->maxs[i] < -MAX_MAP_BOUNDS)
- {
- Log_Print("entity %i, brush %i: no visible sides on brush\n", ob->entitynum, ob->brushnum);
- ob->numsides = 0; //remove the brush
- break;
- } //end if
- } //end for
- return true;
-} //end of the function MakeBrushWindings
-//===========================================================================
-// FIXME: currently doesn't mark all bevels
-// NOTE: when one brush bevel is found the remaining sides of the brush
-// are bevels as well (when the brush isn't expanded for AAS :))
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void MarkBrushBevels(mapbrush_t *brush)
-{
- int i;
- int we;
- side_t *s;
-
- //check all the sides of the brush
- for (i = 0; i < brush->numsides; i++)
- {
- s = brush->original_sides + i;
- //if the side has no winding
- if (!s->winding)
- {
- Log_Write("MarkBrushBevels: brush %d no winding", brush->brushnum);
- s->flags |= SFL_BEVEL;
- } //end if
- //if the winding is tiny
- else if (WindingIsTiny(s->winding))
- {
- s->flags |= SFL_BEVEL;
- Log_Write("MarkBrushBevels: brush %d tiny winding", brush->brushnum);
- } //end else if
- //if the winding has errors
- else
- {
- we = WindingError(s->winding);
- if (we == WE_NOTENOUGHPOINTS
- || we == WE_SMALLAREA
- || we == WE_POINTBOGUSRANGE
-// || we == WE_NONCONVEX
- )
- {
- Log_Write("MarkBrushBevels: brush %d %s", brush->brushnum, WindingErrorString());
- s->flags |= SFL_BEVEL;
- } //end else if
- } //end else
- if (s->flags & SFL_BEVEL)
- {
- s->flags &= ~SFL_VISIBLE;
- //if the side has a valid plane
- if (s->planenum > 0 && s->planenum < nummapplanes)
- {
- //if it is an axial plane
- if (mapplanes[s->planenum].type < 3) c_boxbevels++;
- else c_edgebevels++;
- } //end if
- } //end if
- } //end for
-} //end of the function MarkBrushBevels
-//===========================================================================
-// returns true if the map brush already exists
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int BrushExists(mapbrush_t *brush)
-{
- int i, s1, s2;
- side_t *side1, *side2;
- mapbrush_t *brush1, *brush2;
-
- for (i = 0; i < nummapbrushes; i++)
- {
- brush1 = brush;
- brush2 = &mapbrushes[i];
- //compare the brushes
- if (brush1->entitynum != brush2->entitynum) continue;
- //if (brush1->contents != brush2->contents) continue;
- if (brush1->numsides != brush2->numsides) continue;
- for (s1 = 0; s1 < brush1->numsides; s1++)
- {
- side1 = brush1->original_sides + s1;
- //
- for (s2 = 0; s2 < brush2->numsides; s2++)
- {
- side2 = brush2->original_sides + s2;
- //
- if ((side1->planenum & ~1) == (side2->planenum & ~1)
-// && side1->texinfo == side2->texinfo
-// && side1->contents == side2->contents
-// && side1->surf == side2->surf
- ) break;
- } //end if
- if (s2 >= brush2->numsides) break;
- } //end for
- if (s1 >= brush1->numsides) return true;
- } //end for
- return false;
-} //end of the function BrushExists
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-qboolean WriteMapBrush(FILE *fp, mapbrush_t *brush, vec3_t origin)
-{
- int sn, rotate, shift[2], sv, tv, planenum, p1, i, j;
- float scale[2], originshift[2], ang1, ang2, newdist;
- vec3_t vecs[2], axis[2];
- map_texinfo_t *ti;
- winding_t *w;
- side_t *s;
- plane_t *plane;
-
- if (noliquids)
- {
- if (brush->contents & (CONTENTS_WATER|CONTENTS_SLIME|CONTENTS_LAVA))
- {
- return true;
- } //end if
- } //end if
- //if the brush has no contents
- if (!brush->contents) return true;
- //print the leading {
- if (fprintf(fp, " { //brush %d\n", brush->brushnum) < 0) return false;
- //write brush sides
- for (sn = 0; sn < brush->numsides; sn++)
- {
- s = brush->original_sides + sn;
- //don't write out bevels
- if (!(s->flags & SFL_BEVEL))
- {
- //if the entity has an origin set
- if (origin[0] || origin[1] || origin[2])
- {
- newdist = mapplanes[s->planenum].dist +
- DotProduct(mapplanes[s->planenum].normal, origin);
- planenum = FindFloatPlane(mapplanes[s->planenum].normal, newdist);
- } //end if
- else
- {
- planenum = s->planenum;
- } //end else
- //always take the first plane, then flip the points if necesary
- plane = &mapplanes[planenum & ~1];
- w = BaseWindingForPlane(plane->normal, plane->dist);
- //
- for (i = 0; i < 3; i++)
- {
- for (j = 0; j < 3; j++)
- {
- if (fabs(w->p[i][j]) < 0.2) w->p[i][j] = 0;
- else if (fabs((int)w->p[i][j] - w->p[i][j]) < 0.3) w->p[i][j] = (int) w->p[i][j];
- //w->p[i][j] = (int) (w->p[i][j] + 0.2);
- } //end for
- } //end for
- //three non-colinear points to define the plane
- if (planenum & 1) p1 = 1;
- else p1 = 0;
- if (fprintf(fp," ( %5i %5i %5i ) ", (int)w->p[p1][0], (int)w->p[p1][1], (int)w->p[p1][2]) < 0) return false;
- if (fprintf(fp,"( %5i %5i %5i ) ", (int)w->p[!p1][0], (int)w->p[!p1][1], (int)w->p[!p1][2]) < 0) return false;
- if (fprintf(fp,"( %5i %5i %5i ) ", (int)w->p[2][0], (int)w->p[2][1], (int)w->p[2][2]) < 0) return false;
- //free the winding
- FreeWinding(w);
- //
- if (s->texinfo == TEXINFO_NODE)
- {
- if (brush->contents & CONTENTS_PLAYERCLIP)
- {
- //player clip
- if (loadedmaptype == MAPTYPE_SIN)
- {
- if (fprintf(fp, "generic/misc/clip 0 0 0 1 1") < 0) return false;
- } //end if
- else if (loadedmaptype == MAPTYPE_QUAKE2)
- { //FIXME: don't always use e1u1
- if (fprintf(fp, "e1u1/clip 0 0 0 1 1") < 0) return false;
- } //end else
- else if (loadedmaptype == MAPTYPE_QUAKE3)
- {
- if (fprintf(fp, "e1u1/clip 0 0 0 1 1") < 0) return false;
- } //end else if
- else
- {
- if (fprintf(fp, "clip 0 0 0 1 1") < 0) return false;
- } //end else
- } //end if
- else if (brush->contents == CONTENTS_MONSTERCLIP)
- {
- //monster clip
- if (loadedmaptype == MAPTYPE_SIN)
- {
- if (fprintf(fp, "generic/misc/monster 0 0 0 1 1") < 0) return false;
- } //end if
- else if (loadedmaptype == MAPTYPE_QUAKE2)
- {
- if (fprintf(fp, "e1u1/clip_mon 0 0 0 1 1") < 0) return false;
- } //end else
- else
- {
- if (fprintf(fp, "clip 0 0 0 1 1") < 0) return false;
- } //end else
- } //end else
- else
- {
- if (fprintf(fp, "clip 0 0 0 1 1") < 0) return false;
- Log_Write("brush->contents = %d\n", brush->contents);
- } //end else
- } //end if
- else if (loadedmaptype == MAPTYPE_SIN && s->texinfo == 0)
- {
- if (brush->contents & CONTENTS_DUMMYFENCE)
- {
- if (fprintf(fp, "generic/misc/fence 0 0 0 1 1") < 0) return false;
- } //end if
- else if (brush->contents & CONTENTS_MIST)
- {
- if (fprintf(fp, "generic/misc/volumetric_base 0 0 0 1 1") < 0) return false;
- } //end if
- else //unknown so far
- {
- if (fprintf(fp, "generic/misc/red 0 0 0 1 1") < 0) return false;
- } //end else
- } //end if
- else if (loadedmaptype == MAPTYPE_QUAKE3)
- {
- //always use the same texture
- if (fprintf(fp, "e2u3/floor1_2 0 0 0 1 1 1 0 0") < 0) return false;
- } //end else if
- else
- {
- //*
- ti = &map_texinfo[s->texinfo];
- //the scaling of the texture
- scale[0] = 1 / VectorNormalize2(ti->vecs[0], vecs[0]);
- scale[1] = 1 / VectorNormalize2(ti->vecs[1], vecs[1]);
- //
- TextureAxisFromPlane(plane, axis[0], axis[1]);
- //calculate texture shift done by entity origin
- originshift[0] = DotProduct(origin, axis[0]);
- originshift[1] = DotProduct(origin, axis[1]);
- //the texture shift without origin shift
- shift[0] = ti->vecs[0][3] - originshift[0];
- shift[1] = ti->vecs[1][3] - originshift[1];
- //
- if (axis[0][0]) sv = 0;
- else if (axis[0][1]) sv = 1;
- else sv = 2;
- if (axis[1][0]) tv = 0;
- else if (axis[1][1]) tv = 1;
- else tv = 2;
- //calculate rotation of texture
- if (vecs[0][tv] == 0) ang1 = vecs[0][sv] > 0 ? 90.0 : -90.0;
- else ang1 = atan2(vecs[0][sv], vecs[0][tv]) * 180 / Q_PI;
- if (ang1 < 0) ang1 += 360;
- if (ang1 >= 360) ang1 -= 360;
- if (axis[0][tv] == 0) ang2 = axis[0][sv] > 0 ? 90.0 : -90.0;
- else ang2 = atan2(axis[0][sv], axis[0][tv]) * 180 / Q_PI;
- if (ang2 < 0) ang2 += 360;
- if (ang2 >= 360) ang2 -= 360;
- rotate = ang2 - ang1;
- if (rotate < 0) rotate += 360;
- if (rotate >= 360) rotate -= 360;
- //write the texture info
- if (fprintf(fp, "%s %d %d %d", ti->texture, shift[0], shift[1], rotate) < 0) return false;
- if (fabs(scale[0] - ((int) scale[0])) < 0.001)
- {
- if (fprintf(fp, " %d", (int) scale[0]) < 0) return false;
- } //end if
- else
- {
- if (fprintf(fp, " %4f", scale[0]) < 0) return false;
- } //end if
- if (fabs(scale[1] - ((int) scale[1])) < 0.001)
- {
- if (fprintf(fp, " %d", (int) scale[1]) < 0) return false;
- } //end if
- else
- {
- if (fprintf(fp, " %4f", scale[1]) < 0) return false;
- } //end else
- //write the extra brush side info
- if (loadedmaptype == MAPTYPE_QUAKE2)
- {
- if (fprintf(fp, " %ld %ld %ld", s->contents, ti->flags, ti->value) < 0) return false;
- } //end if
- //*/
- } //end else
- if (fprintf(fp, "\n") < 0) return false;
- } //end if
- } //end if
- if (fprintf(fp, " }\n") < 0) return false;
- c_writtenbrushes++;
- return true;
-} //end of the function WriteMapBrush
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-qboolean WriteOriginBrush(FILE *fp, vec3_t origin)
-{
- vec3_t normal;
- float dist;
- int i, s;
- winding_t *w;
-
- if (fprintf(fp, " {\n") < 0) return false;
- //
- for (i = 0; i < 3; i++)
- {
- for (s = -1; s <= 1; s += 2)
- {
- //
- VectorClear(normal);
- normal[i] = s;
- dist = origin[i] * s + 16;
- //
- w = BaseWindingForPlane(normal, dist);
- //three non-colinear points to define the plane
- if (fprintf(fp," ( %5i %5i %5i ) ", (int)w->p[0][0], (int)w->p[0][1], (int)w->p[0][2]) < 0) return false;
- if (fprintf(fp,"( %5i %5i %5i ) ", (int)w->p[1][0], (int)w->p[1][1], (int)w->p[1][2]) < 0) return false;
- if (fprintf(fp,"( %5i %5i %5i ) ", (int)w->p[2][0], (int)w->p[2][1], (int)w->p[2][2]) < 0) return false;
- //free the winding
- FreeWinding(w);
- //write origin texture:
- // CONTENTS_ORIGIN = 16777216
- // SURF_NODRAW = 128
- if (loadedmaptype == MAPTYPE_SIN)
- {
- if (fprintf(fp, "generic/misc/origin 0 0 0 1 1") < 0) return false;
- } //end if
- else if (loadedmaptype == MAPTYPE_HALFLIFE)
- {
- if (fprintf(fp, "origin 0 0 0 1 1") < 0) return false;
- } //end if
- else
- {
- if (fprintf(fp, "e1u1/origin 0 0 0 1 1") < 0) return false;
- } //end else
- //Quake2 extra brush side info
- if (loadedmaptype == MAPTYPE_QUAKE2)
- {
- //if (fprintf(fp, " 16777216 128 0") < 0) return false;
- } //end if
- if (fprintf(fp, "\n") < 0) return false;
- } //end for
- } //end for
- if (fprintf(fp, " }\n") < 0) return false;
- c_writtenbrushes++;
- return true;
-} //end of the function WriteOriginBrush
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-mapbrush_t *GetAreaPortalBrush(entity_t *mapent)
-{
- int portalnum, bn;
- mapbrush_t *brush;
-
- //the area portal number
- portalnum = mapent->areaportalnum;
- //find the area portal brush in the world brushes
- for (bn = 0; bn < nummapbrushes && portalnum; bn++)
- {
- brush = &mapbrushes[bn];
- //must be in world entity
- if (brush->entitynum == 0)
- {
- if (brush->contents & CONTENTS_AREAPORTAL)
- {
- portalnum--;
- } //end if
- } //end if
- } //end for
- if (bn < nummapbrushes)
- {
- return brush;
- } //end if
- else
- {
- Log_Print("area portal %d brush not found\n", mapent->areaportalnum);
- return NULL;
- } //end else
-} //end of the function GetAreaPortalBrush
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-qboolean WriteMapFileSafe(FILE *fp)
-{
- char key[1024], value[1024];
- int i, bn, entitybrushes;
- epair_t *ep;
- mapbrush_t *brush;
- entity_t *mapent;
- //vec3_t vec_origin = {0, 0, 0};
-
- //
- if (fprintf(fp,"//=====================================================\n"
- "//\n"
- "// map file created with BSPC "BSPC_VERSION"\n"
- "//\n"
- "// BSPC is designed to decompile material in which you own the copyright\n"
- "// or have obtained permission to decompile from the copyright owner. Unless\n"
- "// you own the copyright or have permission to decompile from the copyright\n"
- "// owner, you may be violating copyright law and be subject to payment of\n"
- "// damages and other remedies. If you are uncertain about your rights, contact\n"
- "// your legal advisor.\n"
- "//\n") < 0) return false;
- if (loadedmaptype == MAPTYPE_SIN)
- {
- if (fprintf(fp,
- "// generic/misc/red is used for unknown textures\n") < 0) return false;
- } //end if
- if (fprintf(fp,"//\n"
- "//=====================================================\n") < 0) return false;
- //write out all the entities
- for (i = 0; i < num_entities; i++)
- {
- mapent = &entities[i];
- if (!mapent->epairs)
- {
- continue;
- } //end if
- if (fprintf(fp, "{\n") < 0) return false;
- //
- if (loadedmaptype == MAPTYPE_QUAKE3)
- {
- if (!stricmp(ValueForKey(mapent, "classname"), "light"))
- {
- SetKeyValue(mapent, "light", "10000");
- } //end if
- } //end if
- //write epairs
- for (ep = mapent->epairs; ep; ep = ep->next)
- {
- strcpy(key, ep->key);
- StripTrailing (key);
- strcpy(value, ep->value);
- StripTrailing(value);
- //
- if (loadedmaptype == MAPTYPE_QUAKE2 ||
- loadedmaptype == MAPTYPE_SIN)
- {
- //don't write an origin for BSP models
- if (mapent->modelnum >= 0 && !strcmp(key, "origin")) continue;
- } //end if
- //don't write BSP model numbers
- if (mapent->modelnum >= 0 && !strcmp(key, "model") && value[0] == '*') continue;
- //
- if (fprintf(fp, " \"%s\" \"%s\"\n", key, value) < 0) return false;
- } //end for
- //
- if (ValueForKey(mapent, "origin")) GetVectorForKey(mapent, "origin", mapent->origin);
- else mapent->origin[0] = mapent->origin[1] = mapent->origin[2] = 0;
- //if this is an area portal entity
- if (!strcmp("func_areaportal", ValueForKey(mapent, "classname")))
- {
- brush = GetAreaPortalBrush(mapent);
- if (!brush) return false;
- if (!WriteMapBrush(fp, brush, mapent->origin)) return false;
- } //end if
- else
- {
- entitybrushes = false;
- //write brushes
- for (bn = 0; bn < nummapbrushes; bn++)
- {
- brush = &mapbrushes[bn];
- //if the brush is part of this entity
- if (brush->entitynum == i)
- {
- //don't write out area portal brushes in the world
- if (!((brush->contents & CONTENTS_AREAPORTAL) && brush->entitynum == 0))
- {
- /*
- if (!strcmp("func_door_rotating", ValueForKey(mapent, "classname")))
- {
- AAS_PositionFuncRotatingBrush(mapent, brush);
- if (!WriteMapBrush(fp, brush, vec_origin)) return false;
- } //end if
- else //*/
- {
- if (!WriteMapBrush(fp, brush, mapent->origin)) return false;
- } //end else
- entitybrushes = true;
- } //end if
- } //end if
- } //end for
- //if the entity had brushes
- if (entitybrushes)
- {
- //if the entity has an origin set
- if (mapent->origin[0] || mapent->origin[1] || mapent->origin[2])
- {
- if (!WriteOriginBrush(fp, mapent->origin)) return false;
- } //end if
- } //end if
- } //end else
- if (fprintf(fp, "}\n") < 0) return false;
- } //end for
- if (fprintf(fp, "//total of %d brushes\n", c_writtenbrushes) < 0) return false;
- return true;
-} //end of the function WriteMapFileSafe
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void WriteMapFile(char *filename)
-{
- FILE *fp;
- double start_time;
-
- c_writtenbrushes = 0;
- //the time started
- start_time = I_FloatTime();
- //
- Log_Print("writing %s\n", filename);
- fp = fopen(filename, "wb");
- if (!fp)
- {
- Log_Print("can't open %s\n", filename);
- return;
- } //end if
- if (!WriteMapFileSafe(fp))
- {
- fclose(fp);
- Log_Print("error writing map file %s\n", filename);
- return;
- } //end if
- fclose(fp);
- //display creation time
- Log_Print("written %d brushes\n", c_writtenbrushes);
- Log_Print("map file written in %5.0f seconds\n", I_FloatTime() - start_time);
-} //end of the function WriteMapFile
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void PrintMapInfo(void)
-{
- Log_Print("\n");
- Log_Print("%6i brushes\n", nummapbrushes);
- Log_Print("%6i brush sides\n", nummapbrushsides);
-// Log_Print("%6i clipbrushes\n", c_clipbrushes);
-// Log_Print("%6i total sides\n", nummapbrushsides);
-// Log_Print("%6i boxbevels\n", c_boxbevels);
-// Log_Print("%6i edgebevels\n", c_edgebevels);
-// Log_Print("%6i entities\n", num_entities);
-// Log_Print("%6i planes\n", nummapplanes);
-// Log_Print("%6i areaportals\n", c_areaportals);
-// Log_Print("%6i squatt brushes\n", c_squattbrushes);
-// Log_Print("size: %5.0f,%5.0f,%5.0f to %5.0f,%5.0f,%5.0f\n", map_mins[0],map_mins[1],map_mins[2],
-// map_maxs[0],map_maxs[1],map_maxs[2]);
-} //end of the function PrintMapInfo
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void ResetMapLoading(void)
-{
- int i;
- epair_t *ep, *nextep;
-
- Q2_ResetMapLoading();
- Sin_ResetMapLoading();
-
- //free all map brush side windings
- for (i = 0; i < nummapbrushsides; i++)
- {
- if (brushsides[i].winding)
- {
- FreeWinding(brushsides[i].winding);
- } //end for
- } //end for
-
- //reset regular stuff
- nummapbrushes = 0;
- memset(mapbrushes, 0, MAX_MAPFILE_BRUSHES * sizeof(mapbrush_t));
- //
- nummapbrushsides = 0;
- memset(brushsides, 0, MAX_MAPFILE_BRUSHSIDES * sizeof(side_t));
- memset(side_brushtextures, 0, MAX_MAPFILE_BRUSHSIDES * sizeof(brush_texture_t));
- //
- nummapplanes = 0;
- memset(mapplanes, 0, MAX_MAPFILE_PLANES * sizeof(plane_t));
- //
- memset(planehash, 0, PLANE_HASHES * sizeof(plane_t *));
- //
- memset(map_texinfo, 0, MAX_MAPFILE_TEXINFO * sizeof(map_texinfo_t));
- map_numtexinfo = 0;
- //
- VectorClear(map_mins);
- VectorClear(map_maxs);
- //
- c_boxbevels = 0;
- c_edgebevels = 0;
- c_areaportals = 0;
- c_clipbrushes = 0;
- c_writtenbrushes = 0;
- //clear the entities
- for (i = 0; i < num_entities; i++)
- {
- for (ep = entities[i].epairs; ep; ep = nextep)
- {
- nextep = ep->next;
- FreeMemory(ep->key);
- FreeMemory(ep->value);
- FreeMemory(ep);
- } //end for
- } //end for
- num_entities = 0;
- memset(entities, 0, MAX_MAP_ENTITIES * sizeof(entity_t));
-} //end of the function ResetMapLoading
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-#ifndef Q1_BSPVERSION
-#define Q1_BSPVERSION 29
-#endif
-#ifndef HL_BSPVERSION
-#define HL_BSPVERSION 30
-#endif
-
-#define Q2_BSPHEADER (('P'<<24)+('S'<<16)+('B'<<8)+'I') //IBSP
-#define Q2_BSPVERSION 38
-
-#define SINGAME_BSPHEADER (('P'<<24)+('S'<<16)+('B'<<8)+'R') //RBSP
-#define SINGAME_BSPVERSION 1
-
-#define SIN_BSPHEADER (('P'<<24)+('S'<<16)+('B'<<8)+'I') //IBSP
-#define SIN_BSPVERSION 41
-
-typedef struct
-{
- int ident;
- int version;
-} idheader_t;
-
-int LoadMapFromBSP(struct quakefile_s *qf)
-{
- idheader_t idheader;
-
- if (ReadQuakeFile(qf, &idheader, 0, sizeof(idheader_t)) != sizeof(idheader_t))
- {
- return false;
- } //end if
-
- idheader.ident = LittleLong(idheader.ident);
- idheader.version = LittleLong(idheader.version);
- //Quake3 BSP file
- if (idheader.ident == Q3_BSP_IDENT && idheader.version == Q3_BSP_VERSION)
- {
- ResetMapLoading();
- Q3_LoadMapFromBSP(qf);
- Q3_FreeMaxBSP();
- } //end if
- //Quake2 BSP file
- else if (idheader.ident == Q2_BSPHEADER && idheader.version == Q2_BSPVERSION)
- {
- ResetMapLoading();
- Q2_AllocMaxBSP();
- Q2_LoadMapFromBSP(qf->filename, qf->offset, qf->length);
- Q2_FreeMaxBSP();
- } //endif
- //Sin BSP file
- else if ((idheader.ident == SIN_BSPHEADER && idheader.version == SIN_BSPVERSION) ||
- //the dorks gave the same format another ident and verions
- (idheader.ident == SINGAME_BSPHEADER && idheader.version == SINGAME_BSPVERSION))
- {
- ResetMapLoading();
- Sin_AllocMaxBSP();
- Sin_LoadMapFromBSP(qf->filename, qf->offset, qf->length);
- Sin_FreeMaxBSP();
- } //end if
- //the Quake1 bsp files don't have a ident only a version
- else if (idheader.ident == Q1_BSPVERSION)
- {
- ResetMapLoading();
- Q1_AllocMaxBSP();
- Q1_LoadMapFromBSP(qf->filename, qf->offset, qf->length);
- Q1_FreeMaxBSP();
- } //end if
- //Half-Life also only uses a version number
- else if (idheader.ident == HL_BSPVERSION)
- {
- ResetMapLoading();
- HL_AllocMaxBSP();
- HL_LoadMapFromBSP(qf->filename, qf->offset, qf->length);
- HL_FreeMaxBSP();
- } //end if
- else
- {
- Error("unknown BSP format %c%c%c%c, version %d\n",
- (idheader.ident & 0xFF),
- ((idheader.ident >> 8) & 0xFF),
- ((idheader.ident >> 16) & 0xFF),
- ((idheader.ident >> 24) & 0xFF), idheader.version);
- return false;
- } //end if
- //
- return true;
-} //end of the function LoadMapFromBSP
diff --git a/code/bspc/map_hl.c b/code/bspc/map_hl.c
deleted file mode 100644
index b39878b..0000000
--- a/code/bspc/map_hl.c
+++ /dev/null
@@ -1,1114 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-#include "qbsp.h"
-#include "l_bsp_hl.h"
-#include "aas_map.h" //AAS_CreateMapBrushes
-
-int hl_numbrushes;
-int hl_numclipbrushes;
-
-//#define HL_PRINT
-#define HLCONTENTS
-
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int HL_TextureContents(char *name)
-{
- if (!Q_strncasecmp (name, "sky",3))
- return CONTENTS_SOLID;
-
- if (!Q_strncasecmp(name+1,"!lava",5))
- return CONTENTS_LAVA;
-
- if (!Q_strncasecmp(name+1,"!slime",6))
- return CONTENTS_SLIME;
-
- /*
- if (!Q_strncasecmp (name, "!cur_90",7))
- return CONTENTS_CURRENT_90;
- if (!Q_strncasecmp (name, "!cur_0",6))
- return CONTENTS_CURRENT_0;
- if (!Q_strncasecmp (name, "!cur_270",8))
- return CONTENTS_CURRENT_270;
- if (!Q_strncasecmp (name, "!cur_180",8))
- return CONTENTS_CURRENT_180;
- if (!Q_strncasecmp (name, "!cur_up",7))
- return CONTENTS_CURRENT_UP;
- if (!Q_strncasecmp (name, "!cur_dwn",8))
- return CONTENTS_CURRENT_DOWN;
- //*/
- if (name[0] == '!')
- return CONTENTS_WATER;
- /*
- if (!Q_strncasecmp (name, "origin",6))
- return CONTENTS_ORIGIN;
- if (!Q_strncasecmp (name, "clip",4))
- return CONTENTS_CLIP;
- if( !Q_strncasecmp( name, "translucent", 11 ) )
- return CONTENTS_TRANSLUCENT;
- if( name[0] == '@' )
- return CONTENTS_TRANSLUCENT;
- //*/
-
- return CONTENTS_SOLID;
-} //end of the function HL_TextureContents
-//===========================================================================
-// Generates two new brushes, leaving the original
-// unchanged
-//
-// modified for Half-Life because there are quite a lot of tiny node leaves
-// in the Half-Life bsps
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void HL_SplitBrush(bspbrush_t *brush, int planenum, int nodenum,
- bspbrush_t **front, bspbrush_t **back)
-{
- bspbrush_t *b[2];
- int i, j;
- winding_t *w, *cw[2], *midwinding;
- plane_t *plane, *plane2;
- side_t *s, *cs;
- float d, d_front, d_back;
-
- *front = *back = NULL;
- plane = &mapplanes[planenum];
-
- // check all points
- d_front = d_back = 0;
- for (i=0 ; i<brush->numsides ; i++)
- {
- w = brush->sides[i].winding;
- if (!w)
- continue;
- for (j=0 ; j<w->numpoints ; j++)
- {
- d = DotProduct (w->p[j], plane->normal) - plane->dist;
- if (d > 0 && d > d_front)
- d_front = d;
- if (d < 0 && d < d_back)
- d_back = d;
- } //end for
- } //end for
-
- if (d_front < 0.1) // PLANESIDE_EPSILON)
- { // only on back
- *back = CopyBrush (brush);
- Log_Print("HL_SplitBrush: only on back\n");
- return;
- } //end if
- if (d_back > -0.1) // PLANESIDE_EPSILON)
- { // only on front
- *front = CopyBrush (brush);
- Log_Print("HL_SplitBrush: only on front\n");
- return;
- } //end if
-
- // create a new winding from the split plane
-
- w = BaseWindingForPlane (plane->normal, plane->dist);
- for (i = 0; i < brush->numsides && w; i++)
- {
- plane2 = &mapplanes[brush->sides[i].planenum ^ 1];
- ChopWindingInPlace(&w, plane2->normal, plane2->dist, 0); // PLANESIDE_EPSILON);
- } //end for
-
- if (!w || WindingIsTiny(w))
- { // the brush isn't really split
- int side;
-
- Log_Print("HL_SplitBrush: no split winding\n");
- side = BrushMostlyOnSide (brush, plane);
- if (side == PSIDE_FRONT)
- *front = CopyBrush (brush);
- if (side == PSIDE_BACK)
- *back = CopyBrush (brush);
- return;
- }
-
- if (WindingIsHuge(w))
- {
- Log_Print("HL_SplitBrush: WARNING huge split winding\n");
- } //end of
-
- midwinding = w;
-
- // split it for real
-
- for (i = 0; i < 2; i++)
- {
- b[i] = AllocBrush (brush->numsides+1);
- b[i]->original = brush->original;
- } //end for
-
- // split all the current windings
-
- for (i=0 ; i<brush->numsides ; i++)
- {
- s = &brush->sides[i];
- w = s->winding;
- if (!w)
- continue;
- ClipWindingEpsilon (w, plane->normal, plane->dist,
- 0 /*PLANESIDE_EPSILON*/, &cw[0], &cw[1]);
- for (j=0 ; j<2 ; j++)
- {
- if (!cw[j])
- continue;
-#if 0
- if (WindingIsTiny (cw[j]))
- {
- FreeWinding (cw[j]);
- continue;
- }
-#endif
- cs = &b[j]->sides[b[j]->numsides];
- b[j]->numsides++;
- *cs = *s;
-// cs->planenum = s->planenum;
-// cs->texinfo = s->texinfo;
-// cs->visible = s->visible;
-// cs->original = s->original;
- cs->winding = cw[j];
- cs->flags &= ~SFL_TESTED;
- } //end for
- } //end for
-
-
- // see if we have valid polygons on both sides
-
- for (i=0 ; i<2 ; i++)
- {
- BoundBrush (b[i]);
- for (j=0 ; j<3 ; j++)
- {
- if (b[i]->mins[j] < -4096 || b[i]->maxs[j] > 4096)
- {
- Log_Print("HL_SplitBrush: bogus brush after clip\n");
- break;
- } //end if
- } //end for
-
- if (b[i]->numsides < 3 || j < 3)
- {
- FreeBrush (b[i]);
- b[i] = NULL;
- Log_Print("HL_SplitBrush: numsides < 3\n");
- } //end if
- } //end for
-
- if ( !(b[0] && b[1]) )
- {
- if (!b[0] && !b[1])
- Log_Print("HL_SplitBrush: split removed brush\n");
- else
- Log_Print("HL_SplitBrush: split not on both sides\n");
- if (b[0])
- {
- FreeBrush (b[0]);
- *front = CopyBrush (brush);
- } //end if
- if (b[1])
- {
- FreeBrush (b[1]);
- *back = CopyBrush (brush);
- } //end if
- return;
- } //end if
-
- // add the midwinding to both sides
- for (i = 0; i < 2; i++)
- {
- cs = &b[i]->sides[b[i]->numsides];
- b[i]->numsides++;
-
- cs->planenum = planenum^i^1;
- cs->texinfo = 0;
- //store the node number in the surf to find the texinfo later on
- cs->surf = nodenum;
- //
- cs->flags &= ~SFL_VISIBLE;
- cs->flags &= ~SFL_TESTED;
- if (i==0)
- cs->winding = CopyWinding (midwinding);
- else
- cs->winding = midwinding;
- } //end for
-
-
-{
- vec_t v1;
- int i;
-
- for (i=0 ; i<2 ; i++)
- {
- v1 = BrushVolume (b[i]);
- if (v1 < 1)
- {
- FreeBrush (b[i]);
- b[i] = NULL;
- Log_Print("HL_SplitBrush: tiny volume after clip\n");
- } //end if
- } //end for
-} //*/
-
- *front = b[0];
- *back = b[1];
-} //end of the function HL_SplitBrush
-//===========================================================================
-// returns true if the tree starting at nodenum has only solid leaves
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int HL_SolidTree_r(int nodenum)
-{
- if (nodenum < 0)
- {
- switch(hl_dleafs[(-nodenum) - 1].contents)
- {
- case HL_CONTENTS_EMPTY:
- {
- return false;
- } //end case
- case HL_CONTENTS_SOLID:
-#ifdef HLCONTENTS
- case HL_CONTENTS_CLIP:
-#endif //HLCONTENTS
- case HL_CONTENTS_SKY:
-#ifdef HLCONTENTS
- case HL_CONTENTS_TRANSLUCENT:
-#endif //HLCONTENTS
- {
- return true;
- } //end case
- case HL_CONTENTS_WATER:
- case HL_CONTENTS_SLIME:
- case HL_CONTENTS_LAVA:
-#ifdef HLCONTENTS
- //these contents should not be found in the BSP
- case HL_CONTENTS_ORIGIN:
- case HL_CONTENTS_CURRENT_0:
- case HL_CONTENTS_CURRENT_90:
- case HL_CONTENTS_CURRENT_180:
- case HL_CONTENTS_CURRENT_270:
- case HL_CONTENTS_CURRENT_UP:
- case HL_CONTENTS_CURRENT_DOWN:
-#endif //HLCONTENTS
- default:
- {
- return false;
- } //end default
- } //end switch
- return false;
- } //end if
- if (!HL_SolidTree_r(hl_dnodes[nodenum].children[0])) return false;
- if (!HL_SolidTree_r(hl_dnodes[nodenum].children[1])) return false;
- return true;
-} //end of the function HL_SolidTree_r
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-bspbrush_t *HL_CreateBrushes_r(bspbrush_t *brush, int nodenum)
-{
- int planenum;
- bspbrush_t *front, *back;
- hl_dleaf_t *leaf;
-
- //if it is a leaf
- if (nodenum < 0)
- {
- leaf = &hl_dleafs[(-nodenum) - 1];
- if (leaf->contents != HL_CONTENTS_EMPTY)
- {
-#ifdef HL_PRINT
- qprintf("\r%5i", ++hl_numbrushes);
-#endif //HL_PRINT
- } //end if
- switch(leaf->contents)
- {
- case HL_CONTENTS_EMPTY:
- {
- FreeBrush(brush);
- return NULL;
- } //end case
- case HL_CONTENTS_SOLID:
-#ifdef HLCONTENTS
- case HL_CONTENTS_CLIP:
-#endif //HLCONTENTS
- case HL_CONTENTS_SKY:
-#ifdef HLCONTENTS
- case HL_CONTENTS_TRANSLUCENT:
-#endif //HLCONTENTS
- {
- brush->side = CONTENTS_SOLID;
- return brush;
- } //end case
- case HL_CONTENTS_WATER:
- {
- brush->side = CONTENTS_WATER;
- return brush;
- } //end case
- case HL_CONTENTS_SLIME:
- {
- brush->side = CONTENTS_SLIME;
- return brush;
- } //end case
- case HL_CONTENTS_LAVA:
- {
- brush->side = CONTENTS_LAVA;
- return brush;
- } //end case
-#ifdef HLCONTENTS
- //these contents should not be found in the BSP
- case HL_CONTENTS_ORIGIN:
- case HL_CONTENTS_CURRENT_0:
- case HL_CONTENTS_CURRENT_90:
- case HL_CONTENTS_CURRENT_180:
- case HL_CONTENTS_CURRENT_270:
- case HL_CONTENTS_CURRENT_UP:
- case HL_CONTENTS_CURRENT_DOWN:
- {
- Error("HL_CreateBrushes_r: found contents %d in Half-Life BSP", leaf->contents);
- return NULL;
- } //end case
-#endif //HLCONTENTS
- default:
- {
- Error("HL_CreateBrushes_r: unknown contents %d in Half-Life BSP", leaf->contents);
- return NULL;
- } //end default
- } //end switch
- return NULL;
- } //end if
- //if the rest of the tree is solid
- /*if (HL_SolidTree_r(nodenum))
- {
- brush->side = CONTENTS_SOLID;
- return brush;
- } //end if*/
- //
- planenum = hl_dnodes[nodenum].planenum;
- planenum = FindFloatPlane(hl_dplanes[planenum].normal, hl_dplanes[planenum].dist);
- //split the brush with the node plane
- HL_SplitBrush(brush, planenum, nodenum, &front, &back);
- //free the original brush
- FreeBrush(brush);
- //every node must split the brush in two
- if (!front || !back)
- {
- Log_Print("HL_CreateBrushes_r: WARNING node not splitting brush\n");
- //return NULL;
- } //end if
- //create brushes recursively
- if (front) front = HL_CreateBrushes_r(front, hl_dnodes[nodenum].children[0]);
- if (back) back = HL_CreateBrushes_r(back, hl_dnodes[nodenum].children[1]);
- //link the brushes if possible and return them
- if (front)
- {
- for (brush = front; brush->next; brush = brush->next);
- brush->next = back;
- return front;
- } //end if
- else
- {
- return back;
- } //end else
-} //end of the function HL_CreateBrushes_r
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-bspbrush_t *HL_CreateBrushesFromBSP(int modelnum)
-{
- bspbrush_t *brushlist;
- bspbrush_t *brush;
- hl_dnode_t *headnode;
- vec3_t mins, maxs;
- int i;
-
- //
- headnode = &hl_dnodes[hl_dmodels[modelnum].headnode[0]];
- //get the mins and maxs of the world
- VectorCopy(headnode->mins, mins);
- VectorCopy(headnode->maxs, maxs);
- //enlarge these mins and maxs
- for (i = 0; i < 3; i++)
- {
- mins[i] -= 8;
- maxs[i] += 8;
- } //end for
- //NOTE: have to add the BSP tree mins and maxs to the MAP mins and maxs
- AddPointToBounds(mins, map_mins, map_maxs);
- AddPointToBounds(maxs, map_mins, map_maxs);
- //
- if (!modelnum)
- {
- Log_Print("brush size: %5.0f,%5.0f,%5.0f to %5.0f,%5.0f,%5.0f\n",
- map_mins[0], map_mins[1], map_mins[2],
- map_maxs[0], map_maxs[1], map_maxs[2]);
- } //end if
- //create one huge brush containing the whole world
- brush = BrushFromBounds(mins, maxs);
- VectorCopy(mins, brush->mins);
- VectorCopy(maxs, brush->maxs);
- //
-#ifdef HL_PRINT
- qprintf("creating Half-Life brushes\n");
- qprintf("%5d brushes", hl_numbrushes = 0);
-#endif //HL_PRINT
- //create the brushes
- brushlist = HL_CreateBrushes_r(brush, hl_dmodels[modelnum].headnode[0]);
- //
-#ifdef HL_PRINT
- qprintf("\n");
-#endif //HL_PRINT
- //now we've got a list with brushes!
- return brushlist;
-} //end of the function HL_CreateBrushesFromBSP
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-bspbrush_t *HL_MergeBrushes(bspbrush_t *brushlist, int modelnum)
-{
- int nummerges, merged;
- bspbrush_t *b1, *b2, *tail, *newbrush, *newbrushlist;
- bspbrush_t *lastb2;
-
- if (!brushlist) return NULL;
-
- if (!modelnum) qprintf("%5d brushes merged", nummerges = 0);
- do
- {
- for (tail = brushlist; tail; tail = tail->next)
- {
- if (!tail->next) break;
- } //end for
- merged = 0;
- newbrushlist = NULL;
- for (b1 = brushlist; b1; b1 = brushlist)
- {
- lastb2 = b1;
- for (b2 = b1->next; b2; b2 = b2->next)
- {
- //can't merge brushes with different contents
- if (b1->side != b2->side) newbrush = NULL;
- else newbrush = TryMergeBrushes(b1, b2);
- //if a merged brush is created
- if (newbrush)
- {
- //copy the brush contents
- newbrush->side = b1->side;
- //add the new brush to the end of the list
- tail->next = newbrush;
- //remove the second brush from the list
- lastb2->next = b2->next;
- //remove the first brush from the list
- brushlist = brushlist->next;
- //free the merged brushes
- FreeBrush(b1);
- FreeBrush(b2);
- //get a new tail brush
- for (tail = brushlist; tail; tail = tail->next)
- {
- if (!tail->next) break;
- } //end for
- merged++;
- if (!modelnum) qprintf("\r%5d", nummerges++);
- break;
- } //end if
- lastb2 = b2;
- } //end for
- //if b1 can't be merged with any of the other brushes
- if (!b2)
- {
- brushlist = brushlist->next;
- //keep b1
- b1->next = newbrushlist;
- newbrushlist = b1;
- } //end else
- } //end for
- brushlist = newbrushlist;
- } while(merged);
- if (!modelnum) qprintf("\n");
- return newbrushlist;
-} //end of the function HL_MergeBrushes
-//===========================================================================
-// returns the amount the face and the winding have overlap
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-float HL_FaceOnWinding(hl_dface_t *face, winding_t *winding)
-{
- int i, edgenum, side;
- float dist, area;
- hl_dplane_t plane;
- vec_t *v1, *v2;
- vec3_t normal, edgevec;
- winding_t *w;
-
- //
- w = CopyWinding(winding);
- memcpy(&plane, &hl_dplanes[face->planenum], sizeof(hl_dplane_t));
- //check on which side of the plane the face is
- if (face->side)
- {
- VectorNegate(plane.normal, plane.normal);
- plane.dist = -plane.dist;
- } //end if
- for (i = 0; i < face->numedges && w; i++)
- {
- //get the first and second vertex of the edge
- edgenum = hl_dsurfedges[face->firstedge + i];
- side = edgenum > 0;
- //if the face plane is flipped
- v1 = hl_dvertexes[hl_dedges[abs(edgenum)].v[side]].point;
- v2 = hl_dvertexes[hl_dedges[abs(edgenum)].v[!side]].point;
- //create a plane through the edge vector, orthogonal to the face plane
- //and with the normal vector pointing out of the face
- VectorSubtract(v1, v2, edgevec);
- CrossProduct(edgevec, plane.normal, normal);
- VectorNormalize(normal);
- dist = DotProduct(normal, v1);
- //
- ChopWindingInPlace(&w, normal, dist, 0.9); //CLIP_EPSILON
- } //end for
- if (w)
- {
- area = WindingArea(w);
- FreeWinding(w);
- return area;
- } //end if
- return 0;
-} //end of the function HL_FaceOnWinding
-//===========================================================================
-// returns a list with brushes created by splitting the given brush with
-// planes that go through the face edges and are orthogonal to the face plane
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-bspbrush_t *HL_SplitBrushWithFace(bspbrush_t *brush, hl_dface_t *face)
-{
- int i, edgenum, side, planenum, splits;
- float dist;
- hl_dplane_t plane;
- vec_t *v1, *v2;
- vec3_t normal, edgevec;
- bspbrush_t *front, *back, *brushlist;
-
- memcpy(&plane, &hl_dplanes[face->planenum], sizeof(hl_dplane_t));
- //check on which side of the plane the face is
- if (face->side)
- {
- VectorNegate(plane.normal, plane.normal);
- plane.dist = -plane.dist;
- } //end if
- splits = 0;
- brushlist = NULL;
- for (i = 0; i < face->numedges; i++)
- {
- //get the first and second vertex of the edge
- edgenum = hl_dsurfedges[face->firstedge + i];
- side = edgenum > 0;
- //if the face plane is flipped
- v1 = hl_dvertexes[hl_dedges[abs(edgenum)].v[side]].point;
- v2 = hl_dvertexes[hl_dedges[abs(edgenum)].v[!side]].point;
- //create a plane through the edge vector, orthogonal to the face plane
- //and with the normal vector pointing out of the face
- VectorSubtract(v1, v2, edgevec);
- CrossProduct(edgevec, plane.normal, normal);
- VectorNormalize(normal);
- dist = DotProduct(normal, v1);
- //
- planenum = FindFloatPlane(normal, dist);
- //split the current brush
- SplitBrush(brush, planenum, &front, &back);
- //if there is a back brush just put it in the list
- if (back)
- {
- //copy the brush contents
- back->side = brush->side;
- //
- back->next = brushlist;
- brushlist = back;
- splits++;
- } //end if
- if (!front)
- {
- Log_Print("HL_SplitBrushWithFace: no new brush\n");
- FreeBrushList(brushlist);
- return NULL;
- } //end if
- //copy the brush contents
- front->side = brush->side;
- //continue splitting the front brush
- brush = front;
- } //end for
- if (!splits)
- {
- FreeBrush(front);
- return NULL;
- } //end if
- front->next = brushlist;
- brushlist = front;
- return brushlist;
-} //end of the function HL_SplitBrushWithFace
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-bspbrush_t *HL_TextureBrushes(bspbrush_t *brushlist, int modelnum)
-{
- float area, largestarea;
- int i, n, texinfonum, sn, numbrushes, ofs;
- int bestfacenum, sidenodenum;
- side_t *side;
- hl_dmiptexlump_t *miptexlump;
- hl_miptex_t *miptex;
- bspbrush_t *brush, *nextbrush, *prevbrush, *newbrushes, *brushlistend;
- vec_t defaultvec[4] = {1, 0, 0, 0};
-
- if (!modelnum) qprintf("texturing brushes\n");
- if (!modelnum) qprintf("%5d brushes", numbrushes = 0);
- //get a pointer to the last brush in the list
- for (brushlistend = brushlist; brushlistend; brushlistend = brushlistend->next)
- {
- if (!brushlistend->next) break;
- } //end for
- //there's no previous brush when at the start of the list
- prevbrush = NULL;
- //go over the brush list
- for (brush = brushlist; brush; brush = nextbrush)
- {
- nextbrush = brush->next;
- //find a texinfo for every brush side
- for (sn = 0; sn < brush->numsides; sn++)
- {
- side = &brush->sides[sn];
- //
- if (side->flags & SFL_TEXTURED) continue;
- //number of the node that created this brush side
- sidenodenum = side->surf; //see midwinding in HL_SplitBrush
- //no face found yet
- bestfacenum = -1;
- //minimum face size
- largestarea = 1;
- //if optimizing the texture placement and not going for the
- //least number of brushes
- if (!lessbrushes)
- {
- for (i = 0; i < hl_numfaces; i++)
- {
- //the face must be in the same plane as the node plane that created
- //this brush side
- if (hl_dfaces[i].planenum == hl_dnodes[sidenodenum].planenum)
- {
- //get the area the face and the brush side overlap
- area = HL_FaceOnWinding(&hl_dfaces[i], side->winding);
- //if this face overlaps the brush side winding more than previous faces
- if (area > largestarea)
- {
- //if there already was a face for texturing this brush side with
- //a different texture
- if (bestfacenum >= 0 &&
- (hl_dfaces[bestfacenum].texinfo != hl_dfaces[i].texinfo))
- {
- //split the brush to fit the texture
- newbrushes = HL_SplitBrushWithFace(brush, &hl_dfaces[i]);
- //if new brushes where created
- if (newbrushes)
- {
- //remove the current brush from the list
- if (prevbrush) prevbrush->next = brush->next;
- else brushlist = brush->next;
- if (brushlistend == brush)
- {
- brushlistend = prevbrush;
- nextbrush = newbrushes;
- } //end if
- //add the new brushes to the end of the list
- if (brushlistend) brushlistend->next = newbrushes;
- else brushlist = newbrushes;
- //free the current brush
- FreeBrush(brush);
- //don't forget about the prevbrush pointer at the bottom of
- //the outer loop
- brush = prevbrush;
- //find the end of the list
- for (brushlistend = brushlist; brushlistend; brushlistend = brushlistend->next)
- {
- if (!brushlistend->next) break;
- } //end for
- break;
- } //end if
- else
- {
- Log_Write("brush %d: no real texture split", numbrushes);
- } //end else
- } //end if
- else
- {
- //best face for texturing this brush side
- bestfacenum = i;
- } //end else
- } //end if
- } //end if
- } //end for
- //if the brush was split the original brush is removed
- //and we just continue with the next one in the list
- if (i < hl_numfaces) break;
- } //end if
- else
- {
- //find the face with the largest overlap with this brush side
- //for texturing the brush side
- for (i = 0; i < hl_numfaces; i++)
- {
- //the face must be in the same plane as the node plane that created
- //this brush side
- if (hl_dfaces[i].planenum == hl_dnodes[sidenodenum].planenum)
- {
- //get the area the face and the brush side overlap
- area = HL_FaceOnWinding(&hl_dfaces[i], side->winding);
- //if this face overlaps the brush side winding more than previous faces
- if (area > largestarea)
- {
- largestarea = area;
- bestfacenum = i;
- } //end if
- } //end if
- } //end for
- } //end else
- //if a face was found for texturing this brush side
- if (bestfacenum >= 0)
- {
- //set the MAP texinfo values
- texinfonum = hl_dfaces[bestfacenum].texinfo;
- for (n = 0; n < 4; n++)
- {
- map_texinfo[texinfonum].vecs[0][n] = hl_texinfo[texinfonum].vecs[0][n];
- map_texinfo[texinfonum].vecs[1][n] = hl_texinfo[texinfonum].vecs[1][n];
- } //end for
- //make sure the two vectors aren't of zero length otherwise use the default
- //vector to prevent a divide by zero in the map writing
- if (VectorLength(map_texinfo[texinfonum].vecs[0]) < 0.01)
- memcpy(map_texinfo[texinfonum].vecs[0], defaultvec, sizeof(defaultvec));
- if (VectorLength(map_texinfo[texinfonum].vecs[1]) < 0.01)
- memcpy(map_texinfo[texinfonum].vecs[1], defaultvec, sizeof(defaultvec));
- //
- map_texinfo[texinfonum].flags = hl_texinfo[texinfonum].flags;
- map_texinfo[texinfonum].value = 0; //HL_ and HL texinfos don't have a value
- //the mip texture
- miptexlump = (hl_dmiptexlump_t *) hl_dtexdata;
- ofs = miptexlump->dataofs[hl_texinfo[texinfonum].miptex];
- if ( ofs > hl_texdatasize ) {
- ofs = miptexlump->dataofs[0];
- }
- miptex = (hl_miptex_t *)((byte *)miptexlump + ofs );
- //get the mip texture name
- strcpy(map_texinfo[texinfonum].texture, miptex->name);
- //no animations in Quake1 and Half-Life mip textures
- map_texinfo[texinfonum].nexttexinfo = -1;
- //store the texinfo number
- side->texinfo = texinfonum;
- //
- if (texinfonum > map_numtexinfo) map_numtexinfo = texinfonum;
- //this side is textured
- side->flags |= SFL_TEXTURED;
- } //end if
- else
- {
- //no texture for this side
- side->texinfo = TEXINFO_NODE;
- //this side is textured
- side->flags |= SFL_TEXTURED;
- } //end if
- } //end for
- //
- if (!modelnum && prevbrush != brush) qprintf("\r%5d", ++numbrushes);
- //previous brush in the list
- prevbrush = brush;
- } //end for
- if (!modelnum) qprintf("\n");
- //return the new list with brushes
- return brushlist;
-} //end of the function HL_TextureBrushes
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void HL_FixContentsTextures(bspbrush_t *brushlist)
-{
- int i, texinfonum;
- bspbrush_t *brush;
-
- for (brush = brushlist; brush; brush = brush->next)
- {
- //only fix the textures of water, slime and lava brushes
- if (brush->side != CONTENTS_WATER &&
- brush->side != CONTENTS_SLIME &&
- brush->side != CONTENTS_LAVA) continue;
- //
- for (i = 0; i < brush->numsides; i++)
- {
- texinfonum = brush->sides[i].texinfo;
- if (HL_TextureContents(map_texinfo[texinfonum].texture) == brush->side) break;
- } //end for
- //if no specific contents texture was found
- if (i >= brush->numsides)
- {
- texinfonum = -1;
- for (i = 0; i < map_numtexinfo; i++)
- {
- if (HL_TextureContents(map_texinfo[i].texture) == brush->side)
- {
- texinfonum = i;
- break;
- } //end if
- } //end for
- } //end if
- //
- if (texinfonum >= 0)
- {
- //give all the brush sides this contents texture
- for (i = 0; i < brush->numsides; i++)
- {
- brush->sides[i].texinfo = texinfonum;
- } //end for
- } //end if
- else Log_Print("brush contents %d with wrong textures\n", brush->side);
- //
- } //end for
- /*
- for (brush = brushlist; brush; brush = brush->next)
- {
- //give all the brush sides this contents texture
- for (i = 0; i < brush->numsides; i++)
- {
- if (HL_TextureContents(map_texinfo[texinfonum].texture) != brush->side)
- {
- Error("brush contents %d with wrong contents textures %s\n", brush->side,
- HL_TextureContents(map_texinfo[texinfonum].texture));
- } //end if
- } //end for
- } //end for*/
-} //end of the function HL_FixContentsTextures
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void HL_BSPBrushToMapBrush(bspbrush_t *bspbrush, entity_t *mapent)
-{
- mapbrush_t *mapbrush;
- side_t *side;
- int i, besttexinfo;
-
- if (nummapbrushes >= MAX_MAPFILE_BRUSHES)
- Error ("nummapbrushes == MAX_MAPFILE_BRUSHES");
-
- mapbrush = &mapbrushes[nummapbrushes];
- mapbrush->original_sides = &brushsides[nummapbrushsides];
- mapbrush->entitynum = mapent - entities;
- mapbrush->brushnum = nummapbrushes - mapent->firstbrush;
- mapbrush->leafnum = -1;
- mapbrush->numsides = 0;
-
- besttexinfo = TEXINFO_NODE;
- for (i = 0; i < bspbrush->numsides; i++)
- {
- if (!bspbrush->sides[i].winding) continue;
- //
- if (nummapbrushsides >= MAX_MAPFILE_BRUSHSIDES)
- Error ("MAX_MAPFILE_BRUSHSIDES");
- side = &brushsides[nummapbrushsides];
- //the contents of the bsp brush is stored in the side variable
- side->contents = bspbrush->side;
- side->surf = 0;
- side->planenum = bspbrush->sides[i].planenum;
- side->texinfo = bspbrush->sides[i].texinfo;
- if (side->texinfo != TEXINFO_NODE)
- {
- //this brush side is textured
- side->flags |= SFL_TEXTURED;
- besttexinfo = side->texinfo;
- } //end if
- //
- nummapbrushsides++;
- mapbrush->numsides++;
- } //end for
- //
- if (besttexinfo == TEXINFO_NODE)
- {
- mapbrush->numsides = 0;
- hl_numclipbrushes++;
- return;
- } //end if
- //set the texinfo for all the brush sides without texture
- for (i = 0; i < mapbrush->numsides; i++)
- {
- if (mapbrush->original_sides[i].texinfo == TEXINFO_NODE)
- {
- mapbrush->original_sides[i].texinfo = besttexinfo;
- } //end if
- } //end for
- //contents of the brush
- mapbrush->contents = bspbrush->side;
- //
- if (create_aas)
- {
- //create the AAS brushes from this brush, add brush bevels
- AAS_CreateMapBrushes(mapbrush, mapent, true);
- return;
- } //end if
- //create windings for sides and bounds for brush
- MakeBrushWindings(mapbrush);
- //add brush bevels
- AddBrushBevels(mapbrush);
- //a new brush has been created
- nummapbrushes++;
- mapent->numbrushes++;
-} //end of the function HL_BSPBrushToMapBrush
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void HL_CreateMapBrushes(entity_t *mapent, int modelnum)
-{
- bspbrush_t *brushlist, *brush, *nextbrush;
- int i;
-
- //create brushes from the model BSP tree
- brushlist = HL_CreateBrushesFromBSP(modelnum);
- //texture the brushes and split them when necesary
- brushlist = HL_TextureBrushes(brushlist, modelnum);
- //fix the contents textures of all brushes
- HL_FixContentsTextures(brushlist);
- //
- if (!nobrushmerge)
- {
- brushlist = HL_MergeBrushes(brushlist, modelnum);
- //brushlist = HL_MergeBrushes(brushlist, modelnum);
- } //end if
- //
- if (!modelnum) qprintf("converting brushes to map brushes\n");
- if (!modelnum) qprintf("%5d brushes", i = 0);
- for (brush = brushlist; brush; brush = nextbrush)
- {
- nextbrush = brush->next;
- HL_BSPBrushToMapBrush(brush, mapent);
- brush->next = NULL;
- FreeBrush(brush);
- if (!modelnum) qprintf("\r%5d", ++i);
- } //end for
- if (!modelnum) qprintf("\n");
-} //end of the function HL_CreateMapBrushes
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void HL_ResetMapLoading(void)
-{
-} //end of the function HL_ResetMapLoading
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void HL_LoadMapFromBSP(char *filename, int offset, int length)
-{
- int i, modelnum;
- char *model, *classname;
-
- Log_Print("-- HL_LoadMapFromBSP --\n");
- //loaded map type
- loadedmaptype = MAPTYPE_HALFLIFE;
- //
- qprintf("loading map from %s at %d\n", filename, offset);
- //load the Half-Life BSP file
- HL_LoadBSPFile(filename, offset, length);
- //
- hl_numclipbrushes = 0;
- //parse the entities from the BSP
- HL_ParseEntities();
- //clear the map mins and maxs
- ClearBounds(map_mins, map_maxs);
- //
- qprintf("creating Half-Life brushes\n");
- if (lessbrushes) qprintf("creating minimum number of brushes\n");
- else qprintf("placing textures correctly\n");
- //
- for (i = 0; i < num_entities; i++)
- {
- entities[i].firstbrush = nummapbrushes;
- entities[i].numbrushes = 0;
- //
- classname = ValueForKey(&entities[i], "classname");
- if (classname && !strcmp(classname, "worldspawn"))
- {
- modelnum = 0;
- } //end if
- else
- {
- //
- model = ValueForKey(&entities[i], "model");
- if (!model || *model != '*') continue;
- model++;
- modelnum = atoi(model);
- } //end else
- //create map brushes for the entity
- HL_CreateMapBrushes(&entities[i], modelnum);
- } //end for
- //
- qprintf("%5d map brushes\n", nummapbrushes);
- qprintf("%5d clip brushes\n", hl_numclipbrushes);
-} //end of the function HL_LoadMapFromBSP
diff --git a/code/bspc/map_q1.c b/code/bspc/map_q1.c
deleted file mode 100644
index bfd5374..0000000
--- a/code/bspc/map_q1.c
+++ /dev/null
@@ -1,1174 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-#include "qbsp.h"
-#include "l_bsp_q1.h"
-#include "aas_map.h" //AAS_CreateMapBrushes
-
-int q1_numbrushes;
-int q1_numclipbrushes;
-
-//#define Q1_PRINT
-
-//===========================================================================
-// water, slime and lava brush textures names always start with a *
-// followed by the type: "slime", "lava" or otherwise water
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int Q1_TextureContents(char *name)
-{
- if (!Q_strcasecmp(name, "clip")) return CONTENTS_SOLID;
- if (name[0] == '*')
- {
- if (!Q_strncasecmp(name+1,"lava",4)) return CONTENTS_LAVA;
- else if (!Q_strncasecmp(name+1,"slime",5)) return CONTENTS_SLIME;
- else return CONTENTS_WATER;
- } //end if
- else if (!Q_strncasecmp(name, "sky", 3)) return CONTENTS_SOLID;
- else return CONTENTS_SOLID;
-} //end of the function Q1_TextureContents
-//===========================================================================
-// Generates two new brushes, leaving the original
-// unchanged
-//
-// modified for Half-Life because there are quite a lot of tiny node leaves
-// in the Half-Life bsps
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void Q1_SplitBrush(bspbrush_t *brush, int planenum, int nodenum,
- bspbrush_t **front, bspbrush_t **back)
-{
- bspbrush_t *b[2];
- int i, j;
- winding_t *w, *cw[2], *midwinding;
- plane_t *plane, *plane2;
- side_t *s, *cs;
- float d, d_front, d_back;
-
- *front = *back = NULL;
- plane = &mapplanes[planenum];
-
- // check all points
- d_front = d_back = 0;
- for (i=0 ; i<brush->numsides ; i++)
- {
- w = brush->sides[i].winding;
- if (!w)
- continue;
- for (j=0 ; j<w->numpoints ; j++)
- {
- d = DotProduct (w->p[j], plane->normal) - plane->dist;
- if (d > 0 && d > d_front)
- d_front = d;
- if (d < 0 && d < d_back)
- d_back = d;
- } //end for
- } //end for
-
- if (d_front < 0.1) // PLANESIDE_EPSILON)
- { // only on back
- *back = CopyBrush (brush);
- Log_Print("Q1_SplitBrush: only on back\n");
- return;
- } //end if
- if (d_back > -0.1) // PLANESIDE_EPSILON)
- { // only on front
- *front = CopyBrush (brush);
- Log_Print("Q1_SplitBrush: only on front\n");
- return;
- } //end if
-
- // create a new winding from the split plane
-
- w = BaseWindingForPlane (plane->normal, plane->dist);
- for (i = 0; i < brush->numsides && w; i++)
- {
- plane2 = &mapplanes[brush->sides[i].planenum ^ 1];
- ChopWindingInPlace(&w, plane2->normal, plane2->dist, 0); // PLANESIDE_EPSILON);
- } //end for
-
- if (!w || WindingIsTiny(w))
- { // the brush isn't really split
- int side;
-
- Log_Print("Q1_SplitBrush: no split winding\n");
- side = BrushMostlyOnSide (brush, plane);
- if (side == PSIDE_FRONT)
- *front = CopyBrush (brush);
- if (side == PSIDE_BACK)
- *back = CopyBrush (brush);
- return;
- }
-
- if (WindingIsHuge(w))
- {
- Log_Print("Q1_SplitBrush: WARNING huge split winding\n");
- } //end of
-
- midwinding = w;
-
- // split it for real
-
- for (i = 0; i < 2; i++)
- {
- b[i] = AllocBrush (brush->numsides+1);
- b[i]->original = brush->original;
- } //end for
-
- // split all the current windings
-
- for (i=0 ; i<brush->numsides ; i++)
- {
- s = &brush->sides[i];
- w = s->winding;
- if (!w)
- continue;
- ClipWindingEpsilon (w, plane->normal, plane->dist,
- 0 /*PLANESIDE_EPSILON*/, &cw[0], &cw[1]);
- for (j=0 ; j<2 ; j++)
- {
- if (!cw[j])
- continue;
-#if 0
- if (WindingIsTiny (cw[j]))
- {
- FreeWinding (cw[j]);
- continue;
- }
-#endif
- cs = &b[j]->sides[b[j]->numsides];
- b[j]->numsides++;
- *cs = *s;
-// cs->planenum = s->planenum;
-// cs->texinfo = s->texinfo;
-// cs->visible = s->visible;
-// cs->original = s->original;
- cs->winding = cw[j];
- cs->flags &= ~SFL_TESTED;
- } //end for
- } //end for
-
-
- // see if we have valid polygons on both sides
-
- for (i=0 ; i<2 ; i++)
- {
- BoundBrush (b[i]);
- for (j=0 ; j<3 ; j++)
- {
- if (b[i]->mins[j] < -4096 || b[i]->maxs[j] > 4096)
- {
- Log_Print("Q1_SplitBrush: bogus brush after clip\n");
- break;
- } //end if
- } //end for
-
- if (b[i]->numsides < 3 || j < 3)
- {
- FreeBrush (b[i]);
- b[i] = NULL;
- Log_Print("Q1_SplitBrush: numsides < 3\n");
- } //end if
- } //end for
-
- if ( !(b[0] && b[1]) )
- {
- if (!b[0] && !b[1])
- Log_Print("Q1_SplitBrush: split removed brush\n");
- else
- Log_Print("Q1_SplitBrush: split not on both sides\n");
- if (b[0])
- {
- FreeBrush (b[0]);
- *front = CopyBrush (brush);
- } //end if
- if (b[1])
- {
- FreeBrush (b[1]);
- *back = CopyBrush (brush);
- } //end if
- return;
- } //end if
-
- // add the midwinding to both sides
- for (i = 0; i < 2; i++)
- {
- cs = &b[i]->sides[b[i]->numsides];
- b[i]->numsides++;
-
- cs->planenum = planenum^i^1;
- cs->texinfo = 0;
- //store the node number in the surf to find the texinfo later on
- cs->surf = nodenum;
- //
- cs->flags &= ~SFL_VISIBLE;
- cs->flags &= ~SFL_TESTED;
- cs->flags &= ~SFL_TEXTURED;
- if (i==0)
- cs->winding = CopyWinding (midwinding);
- else
- cs->winding = midwinding;
- } //end for
-
-
-{
- vec_t v1;
- int i;
-
- for (i=0 ; i<2 ; i++)
- {
- v1 = BrushVolume (b[i]);
- if (v1 < 1)
- {
- FreeBrush (b[i]);
- b[i] = NULL;
- Log_Print("Q1_SplitBrush: tiny volume after clip\n");
- } //end if
- } //end for
-} //*/
-
- *front = b[0];
- *back = b[1];
-} //end of the function Q1_SplitBrush
-//===========================================================================
-// returns true if the tree starting at nodenum has only solid leaves
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int Q1_SolidTree_r(int nodenum)
-{
- if (nodenum < 0)
- {
- switch(q1_dleafs[(-nodenum) - 1].contents)
- {
- case Q1_CONTENTS_EMPTY:
- {
- return false;
- } //end case
- case Q1_CONTENTS_SOLID:
-#ifdef HLCONTENTS
- case Q1_CONTENTS_CLIP:
-#endif HLCONTENTS
- case Q1_CONTENTS_SKY:
-#ifdef HLCONTENTS
- case Q1_CONTENTS_TRANSLUCENT:
-#endif HLCONTENTS
- {
- return true;
- } //end case
- case Q1_CONTENTS_WATER:
- case Q1_CONTENTS_SLIME:
- case Q1_CONTENTS_LAVA:
-#ifdef HLCONTENTS
- //these contents should not be found in the BSP
- case Q1_CONTENTS_ORIGIN:
- case Q1_CONTENTS_CURRENT_0:
- case Q1_CONTENTS_CURRENT_90:
- case Q1_CONTENTS_CURRENT_180:
- case Q1_CONTENTS_CURRENT_270:
- case Q1_CONTENTS_CURRENT_UP:
- case Q1_CONTENTS_CURRENT_DOWN:
-#endif HLCONTENTS
- default:
- {
- return false;
- } //end default
- } //end switch
- return false;
- } //end if
- if (!Q1_SolidTree_r(q1_dnodes[nodenum].children[0])) return false;
- if (!Q1_SolidTree_r(q1_dnodes[nodenum].children[1])) return false;
- return true;
-} //end of the function Q1_SolidTree_r
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-bspbrush_t *Q1_CreateBrushes_r(bspbrush_t *brush, int nodenum)
-{
- int planenum;
- bspbrush_t *front, *back;
- q1_dleaf_t *leaf;
-
- //if it is a leaf
- if (nodenum < 0)
- {
- leaf = &q1_dleafs[(-nodenum) - 1];
- if (leaf->contents != Q1_CONTENTS_EMPTY)
- {
-#ifdef Q1_PRINT
- qprintf("\r%5i", ++q1_numbrushes);
-#endif //Q1_PRINT
- } //end if
- switch(leaf->contents)
- {
- case Q1_CONTENTS_EMPTY:
- {
- FreeBrush(brush);
- return NULL;
- } //end case
- case Q1_CONTENTS_SOLID:
-#ifdef HLCONTENTS
- case Q1_CONTENTS_CLIP:
-#endif HLCONTENTS
- case Q1_CONTENTS_SKY:
-#ifdef HLCONTENTS
- case Q1_CONTENTS_TRANSLUCENT:
-#endif HLCONTENTS
- {
- brush->side = CONTENTS_SOLID;
- return brush;
- } //end case
- case Q1_CONTENTS_WATER:
- {
- brush->side = CONTENTS_WATER;
- return brush;
- } //end case
- case Q1_CONTENTS_SLIME:
- {
- brush->side = CONTENTS_SLIME;
- return brush;
- } //end case
- case Q1_CONTENTS_LAVA:
- {
- brush->side = CONTENTS_LAVA;
- return brush;
- } //end case
-#ifdef HLCONTENTS
- //these contents should not be found in the BSP
- case Q1_CONTENTS_ORIGIN:
- case Q1_CONTENTS_CURRENT_0:
- case Q1_CONTENTS_CURRENT_90:
- case Q1_CONTENTS_CURRENT_180:
- case Q1_CONTENTS_CURRENT_270:
- case Q1_CONTENTS_CURRENT_UP:
- case Q1_CONTENTS_CURRENT_DOWN:
- {
- Error("Q1_CreateBrushes_r: found contents %d in Half-Life BSP", leaf->contents);
- return NULL;
- } //end case
-#endif HLCONTENTS
- default:
- {
- Error("Q1_CreateBrushes_r: unknown contents %d in Half-Life BSP", leaf->contents);
- return NULL;
- } //end default
- } //end switch
- return NULL;
- } //end if
- //if the rest of the tree is solid
- /*if (Q1_SolidTree_r(nodenum))
- {
- brush->side = CONTENTS_SOLID;
- return brush;
- } //end if*/
- //
- planenum = q1_dnodes[nodenum].planenum;
- planenum = FindFloatPlane(q1_dplanes[planenum].normal, q1_dplanes[planenum].dist);
- //split the brush with the node plane
- Q1_SplitBrush(brush, planenum, nodenum, &front, &back);
- //free the original brush
- FreeBrush(brush);
- //every node must split the brush in two
- if (!front || !back)
- {
- Log_Print("Q1_CreateBrushes_r: WARNING node not splitting brush\n");
- //return NULL;
- } //end if
- //create brushes recursively
- if (front) front = Q1_CreateBrushes_r(front, q1_dnodes[nodenum].children[0]);
- if (back) back = Q1_CreateBrushes_r(back, q1_dnodes[nodenum].children[1]);
- //link the brushes if possible and return them
- if (front)
- {
- for (brush = front; brush->next; brush = brush->next);
- brush->next = back;
- return front;
- } //end if
- else
- {
- return back;
- } //end else
-} //end of the function Q1_CreateBrushes_r
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-bspbrush_t *Q1_CreateBrushesFromBSP(int modelnum)
-{
- bspbrush_t *brushlist;
- bspbrush_t *brush;
- q1_dnode_t *headnode;
- vec3_t mins, maxs;
- int i;
-
- //
- headnode = &q1_dnodes[q1_dmodels[modelnum].headnode[0]];
- //get the mins and maxs of the world
- VectorCopy(headnode->mins, mins);
- VectorCopy(headnode->maxs, maxs);
- //enlarge these mins and maxs
- for (i = 0; i < 3; i++)
- {
- mins[i] -= 8;
- maxs[i] += 8;
- } //end for
- //NOTE: have to add the BSP tree mins and maxs to the MAP mins and maxs
- AddPointToBounds(mins, map_mins, map_maxs);
- AddPointToBounds(maxs, map_mins, map_maxs);
- //
- if (!modelnum)
- {
- Log_Print("brush size: %5.0f,%5.0f,%5.0f to %5.0f,%5.0f,%5.0f\n",
- map_mins[0], map_mins[1], map_mins[2],
- map_maxs[0], map_maxs[1], map_maxs[2]);
- } //end if
- //create one huge brush containing the whole world
- brush = BrushFromBounds(mins, maxs);
- VectorCopy(mins, brush->mins);
- VectorCopy(maxs, brush->maxs);
- //
-#ifdef Q1_PRINT
- qprintf("creating Quake brushes\n");
- qprintf("%5d brushes", q1_numbrushes = 0);
-#endif //Q1_PRINT
- //create the brushes
- brushlist = Q1_CreateBrushes_r(brush, q1_dmodels[modelnum].headnode[0]);
- //
-#ifdef Q1_PRINT
- qprintf("\n");
-#endif //Q1_PRINT
- //now we've got a list with brushes!
- return brushlist;
-} //end of the function Q1_CreateBrushesFromBSP
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-q1_dleaf_t *Q1_PointInLeaf(int startnode, vec3_t point)
-{
- int nodenum;
- vec_t dist;
- q1_dnode_t *node;
- q1_dplane_t *plane;
-
- nodenum = startnode;
- while (nodenum >= 0)
- {
- node = &q1_dnodes[nodenum];
- plane = &q1_dplanes[node->planenum];
- dist = DotProduct(point, plane->normal) - plane->dist;
- if (dist > 0)
- nodenum = node->children[0];
- else
- nodenum = node->children[1];
- } //end while
-
- return &q1_dleafs[-nodenum - 1];
-} //end of the function Q1_PointInLeaf
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-float Q1_FaceArea(q1_dface_t *face)
-{
- int i;
- float total;
- vec_t *v;
- vec3_t d1, d2, cross;
- q1_dedge_t *edge;
-
- edge = &q1_dedges[face->firstedge];
- v = q1_dvertexes[edge->v[0]].point;
-
- total = 0;
- for (i = 1; i < face->numedges - 1; i++)
- {
- edge = &q1_dedges[face->firstedge + i];
- VectorSubtract(q1_dvertexes[edge->v[0]].point, v, d1);
- VectorSubtract(q1_dvertexes[edge->v[1]].point, v, d2);
- CrossProduct(d1, d2, cross);
- total += 0.5 * VectorLength(cross);
- } //end for
- return total;
-} //end of the function AAS_FaceArea
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void Q1_FacePlane(q1_dface_t *face, vec3_t normal, float *dist)
-{
- vec_t *v1, *v2, *v3;
- vec3_t vec1, vec2;
- int side, edgenum;
-
- edgenum = q1_dsurfedges[face->firstedge];
- side = edgenum < 0;
- v1 = q1_dvertexes[q1_dedges[abs(edgenum)].v[side]].point;
- v2 = q1_dvertexes[q1_dedges[abs(edgenum)].v[!side]].point;
- edgenum = q1_dsurfedges[face->firstedge+1];
- side = edgenum < 0;
- v3 = q1_dvertexes[q1_dedges[abs(edgenum)].v[!side]].point;
- //
- VectorSubtract(v2, v1, vec1);
- VectorSubtract(v3, v1, vec2);
-
- CrossProduct(vec1, vec2, normal);
- VectorNormalize(normal);
- *dist = DotProduct(v1, normal);
-} //end of the function Q1_FacePlane
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-bspbrush_t *Q1_MergeBrushes(bspbrush_t *brushlist, int modelnum)
-{
- int nummerges, merged;
- bspbrush_t *b1, *b2, *tail, *newbrush, *newbrushlist;
- bspbrush_t *lastb2;
-
- if (!brushlist) return NULL;
-
- if (!modelnum) qprintf("%5d brushes merged", nummerges = 0);
- do
- {
- for (tail = brushlist; tail; tail = tail->next)
- {
- if (!tail->next) break;
- } //end for
- merged = 0;
- newbrushlist = NULL;
- for (b1 = brushlist; b1; b1 = brushlist)
- {
- lastb2 = b1;
- for (b2 = b1->next; b2; b2 = b2->next)
- {
- //can't merge brushes with different contents
- if (b1->side != b2->side) newbrush = NULL;
- else newbrush = TryMergeBrushes(b1, b2);
- //if a merged brush is created
- if (newbrush)
- {
- //copy the brush contents
- newbrush->side = b1->side;
- //add the new brush to the end of the list
- tail->next = newbrush;
- //remove the second brush from the list
- lastb2->next = b2->next;
- //remove the first brush from the list
- brushlist = brushlist->next;
- //free the merged brushes
- FreeBrush(b1);
- FreeBrush(b2);
- //get a new tail brush
- for (tail = brushlist; tail; tail = tail->next)
- {
- if (!tail->next) break;
- } //end for
- merged++;
- if (!modelnum) qprintf("\r%5d", nummerges++);
- break;
- } //end if
- lastb2 = b2;
- } //end for
- //if b1 can't be merged with any of the other brushes
- if (!b2)
- {
- brushlist = brushlist->next;
- //keep b1
- b1->next = newbrushlist;
- newbrushlist = b1;
- } //end else
- } //end for
- brushlist = newbrushlist;
- } while(merged);
- if (!modelnum) qprintf("\n");
- return newbrushlist;
-} //end of the function Q1_MergeBrushes
-//===========================================================================
-// returns the amount the face and the winding overlap
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-float Q1_FaceOnWinding(q1_dface_t *face, winding_t *winding)
-{
- int i, edgenum, side;
- float dist, area;
- q1_dplane_t plane;
- vec_t *v1, *v2;
- vec3_t normal, edgevec;
- winding_t *w;
-
- //
- w = CopyWinding(winding);
- memcpy(&plane, &q1_dplanes[face->planenum], sizeof(q1_dplane_t));
- //check on which side of the plane the face is
- if (face->side)
- {
- VectorNegate(plane.normal, plane.normal);
- plane.dist = -plane.dist;
- } //end if
- for (i = 0; i < face->numedges && w; i++)
- {
- //get the first and second vertex of the edge
- edgenum = q1_dsurfedges[face->firstedge + i];
- side = edgenum > 0;
- //if the face plane is flipped
- v1 = q1_dvertexes[q1_dedges[abs(edgenum)].v[side]].point;
- v2 = q1_dvertexes[q1_dedges[abs(edgenum)].v[!side]].point;
- //create a plane through the edge vector, orthogonal to the face plane
- //and with the normal vector pointing out of the face
- VectorSubtract(v1, v2, edgevec);
- CrossProduct(edgevec, plane.normal, normal);
- VectorNormalize(normal);
- dist = DotProduct(normal, v1);
- //
- ChopWindingInPlace(&w, normal, dist, 0.9); //CLIP_EPSILON
- } //end for
- if (w)
- {
- area = WindingArea(w);
- FreeWinding(w);
- return area;
- } //end if
- return 0;
-} //end of the function Q1_FaceOnWinding
-//===========================================================================
-// returns a list with brushes created by splitting the given brush with
-// planes that go through the face edges and are orthogonal to the face plane
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-bspbrush_t *Q1_SplitBrushWithFace(bspbrush_t *brush, q1_dface_t *face)
-{
- int i, edgenum, side, planenum, splits;
- float dist;
- q1_dplane_t plane;
- vec_t *v1, *v2;
- vec3_t normal, edgevec;
- bspbrush_t *front, *back, *brushlist;
-
- memcpy(&plane, &q1_dplanes[face->planenum], sizeof(q1_dplane_t));
- //check on which side of the plane the face is
- if (face->side)
- {
- VectorNegate(plane.normal, plane.normal);
- plane.dist = -plane.dist;
- } //end if
- splits = 0;
- brushlist = NULL;
- for (i = 0; i < face->numedges; i++)
- {
- //get the first and second vertex of the edge
- edgenum = q1_dsurfedges[face->firstedge + i];
- side = edgenum > 0;
- //if the face plane is flipped
- v1 = q1_dvertexes[q1_dedges[abs(edgenum)].v[side]].point;
- v2 = q1_dvertexes[q1_dedges[abs(edgenum)].v[!side]].point;
- //create a plane through the edge vector, orthogonal to the face plane
- //and with the normal vector pointing out of the face
- VectorSubtract(v1, v2, edgevec);
- CrossProduct(edgevec, plane.normal, normal);
- VectorNormalize(normal);
- dist = DotProduct(normal, v1);
- //
- planenum = FindFloatPlane(normal, dist);
- //split the current brush
- SplitBrush(brush, planenum, &front, &back);
- //if there is a back brush just put it in the list
- if (back)
- {
- //copy the brush contents
- back->side = brush->side;
- //
- back->next = brushlist;
- brushlist = back;
- splits++;
- } //end if
- if (!front)
- {
- Log_Print("Q1_SplitBrushWithFace: no new brush\n");
- FreeBrushList(brushlist);
- return NULL;
- } //end if
- //copy the brush contents
- front->side = brush->side;
- //continue splitting the front brush
- brush = front;
- } //end for
- if (!splits)
- {
- FreeBrush(front);
- return NULL;
- } //end if
- front->next = brushlist;
- brushlist = front;
- return brushlist;
-} //end of the function Q1_SplitBrushWithFace
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-bspbrush_t *Q1_TextureBrushes(bspbrush_t *brushlist, int modelnum)
-{
- float area, largestarea;
- int i, n, texinfonum, sn, numbrushes, ofs;
- int bestfacenum, sidenodenum;
- side_t *side;
- q1_dmiptexlump_t *miptexlump;
- q1_miptex_t *miptex;
- bspbrush_t *brush, *nextbrush, *prevbrush, *newbrushes, *brushlistend;
- vec_t defaultvec[4] = {1, 0, 0, 0};
-
- if (!modelnum) qprintf("texturing brushes\n");
- if (!modelnum) qprintf("%5d brushes", numbrushes = 0);
- //get a pointer to the last brush in the list
- for (brushlistend = brushlist; brushlistend; brushlistend = brushlistend->next)
- {
- if (!brushlistend->next) break;
- } //end for
- //there's no previous brush when at the start of the list
- prevbrush = NULL;
- //go over the brush list
- for (brush = brushlist; brush; brush = nextbrush)
- {
- nextbrush = brush->next;
- //find a texinfo for every brush side
- for (sn = 0; sn < brush->numsides; sn++)
- {
- side = &brush->sides[sn];
- //
- if (side->flags & SFL_TEXTURED) continue;
- //number of the node that created this brush side
- sidenodenum = side->surf; //see midwinding in Q1_SplitBrush
- //no face found yet
- bestfacenum = -1;
- //minimum face size
- largestarea = 1;
- //if optimizing the texture placement and not going for the
- //least number of brushes
- if (!lessbrushes)
- {
- for (i = 0; i < q1_numfaces; i++)
- {
- //the face must be in the same plane as the node plane that created
- //this brush side
- if (q1_dfaces[i].planenum == q1_dnodes[sidenodenum].planenum)
- {
- //get the area the face and the brush side overlap
- area = Q1_FaceOnWinding(&q1_dfaces[i], side->winding);
- //if this face overlaps the brush side winding more than previous faces
- if (area > largestarea)
- {
- //if there already was a face for texturing this brush side with
- //a different texture
- if (bestfacenum >= 0 &&
- (q1_dfaces[bestfacenum].texinfo != q1_dfaces[i].texinfo))
- {
- //split the brush to fit the texture
- newbrushes = Q1_SplitBrushWithFace(brush, &q1_dfaces[i]);
- //if new brushes where created
- if (newbrushes)
- {
- //remove the current brush from the list
- if (prevbrush) prevbrush->next = brush->next;
- else brushlist = brush->next;
- if (brushlistend == brush)
- {
- brushlistend = prevbrush;
- nextbrush = newbrushes;
- } //end if
- //add the new brushes to the end of the list
- if (brushlistend) brushlistend->next = newbrushes;
- else brushlist = newbrushes;
- //free the current brush
- FreeBrush(brush);
- //don't forget about the prevbrush pointer at the bottom of
- //the outer loop
- brush = prevbrush;
- //find the end of the list
- for (brushlistend = brushlist; brushlistend; brushlistend = brushlistend->next)
- {
- if (!brushlistend->next) break;
- } //end for
- break;
- } //end if
- else
- {
- Log_Write("brush %d: no real texture split", numbrushes);
- } //end else
- } //end if
- else
- {
- //best face for texturing this brush side
- bestfacenum = i;
- } //end else
- } //end if
- } //end if
- } //end for
- //if the brush was split the original brush is removed
- //and we just continue with the next one in the list
- if (i < q1_numfaces) break;
- } //end if
- else
- {
- //find the face with the largest overlap with this brush side
- //for texturing the brush side
- for (i = 0; i < q1_numfaces; i++)
- {
- //the face must be in the same plane as the node plane that created
- //this brush side
- if (q1_dfaces[i].planenum == q1_dnodes[sidenodenum].planenum)
- {
- //get the area the face and the brush side overlap
- area = Q1_FaceOnWinding(&q1_dfaces[i], side->winding);
- //if this face overlaps the brush side winding more than previous faces
- if (area > largestarea)
- {
- largestarea = area;
- bestfacenum = i;
- } //end if
- } //end if
- } //end for
- } //end else
- //if a face was found for texturing this brush side
- if (bestfacenum >= 0)
- {
- //set the MAP texinfo values
- texinfonum = q1_dfaces[bestfacenum].texinfo;
- for (n = 0; n < 4; n++)
- {
- map_texinfo[texinfonum].vecs[0][n] = q1_texinfo[texinfonum].vecs[0][n];
- map_texinfo[texinfonum].vecs[1][n] = q1_texinfo[texinfonum].vecs[1][n];
- } //end for
- //make sure the two vectors aren't of zero length otherwise use the default
- //vector to prevent a divide by zero in the map writing
- if (VectorLength(map_texinfo[texinfonum].vecs[0]) < 0.01)
- memcpy(map_texinfo[texinfonum].vecs[0], defaultvec, sizeof(defaultvec));
- if (VectorLength(map_texinfo[texinfonum].vecs[1]) < 0.01)
- memcpy(map_texinfo[texinfonum].vecs[1], defaultvec, sizeof(defaultvec));
- //
- map_texinfo[texinfonum].flags = q1_texinfo[texinfonum].flags;
- map_texinfo[texinfonum].value = 0; //Q1 and HL texinfos don't have a value
- //the mip texture
- miptexlump = (q1_dmiptexlump_t *) q1_dtexdata;
- ofs = miptexlump->dataofs[q1_texinfo[texinfonum].miptex];
- if ( ofs > q1_texdatasize ) {
- ofs = miptexlump->dataofs[0];
- }
- miptex = (q1_miptex_t *)((byte *)miptexlump + ofs);
- //get the mip texture name
- strcpy(map_texinfo[texinfonum].texture, miptex->name);
- //no animations in Quake1 and Half-Life mip textures
- map_texinfo[texinfonum].nexttexinfo = -1;
- //store the texinfo number
- side->texinfo = texinfonum;
- //
- if (texinfonum > map_numtexinfo) map_numtexinfo = texinfonum;
- //this side is textured
- side->flags |= SFL_TEXTURED;
- } //end if
- else
- {
- //no texture for this side
- side->texinfo = TEXINFO_NODE;
- //this side is textured
- side->flags |= SFL_TEXTURED;
- } //end if
- } //end for
- //
- if (!modelnum && prevbrush != brush) qprintf("\r%5d", ++numbrushes);
- //previous brush in the list
- prevbrush = brush;
- } //end for
- if (!modelnum) qprintf("\n");
- //return the new list with brushes
- return brushlist;
-} //end of the function Q1_TextureBrushes
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void Q1_FixContentsTextures(bspbrush_t *brushlist)
-{
- int i, texinfonum;
- bspbrush_t *brush;
-
- for (brush = brushlist; brush; brush = brush->next)
- {
- //only fix the textures of water, slime and lava brushes
- if (brush->side != CONTENTS_WATER &&
- brush->side != CONTENTS_SLIME &&
- brush->side != CONTENTS_LAVA) continue;
- //
- for (i = 0; i < brush->numsides; i++)
- {
- texinfonum = brush->sides[i].texinfo;
- if (Q1_TextureContents(map_texinfo[texinfonum].texture) == brush->side) break;
- } //end for
- //if no specific contents texture was found
- if (i >= brush->numsides)
- {
- texinfonum = -1;
- for (i = 0; i < map_numtexinfo; i++)
- {
- if (Q1_TextureContents(map_texinfo[i].texture) == brush->side)
- {
- texinfonum = i;
- break;
- } //end if
- } //end for
- } //end if
- //
- if (texinfonum >= 0)
- {
- //give all the brush sides this contents texture
- for (i = 0; i < brush->numsides; i++)
- {
- brush->sides[i].texinfo = texinfonum;
- } //end for
- } //end if
- else Log_Print("brush contents %d with wrong textures\n", brush->side);
- //
- } //end for
- /*
- for (brush = brushlist; brush; brush = brush->next)
- {
- //give all the brush sides this contents texture
- for (i = 0; i < brush->numsides; i++)
- {
- if (Q1_TextureContents(map_texinfo[texinfonum].texture) != brush->side)
- {
- Error("brush contents %d with wrong contents textures %s\n", brush->side,
- Q1_TextureContents(map_texinfo[texinfonum].texture));
- } //end if
- } //end for
- } //end for*/
-} //end of the function Q1_FixContentsTextures
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void Q1_BSPBrushToMapBrush(bspbrush_t *bspbrush, entity_t *mapent)
-{
- mapbrush_t *mapbrush;
- side_t *side;
- int i, besttexinfo;
-
- CheckBSPBrush(bspbrush);
-
- if (nummapbrushes >= MAX_MAPFILE_BRUSHES)
- Error ("nummapbrushes == MAX_MAPFILE_BRUSHES");
-
- mapbrush = &mapbrushes[nummapbrushes];
- mapbrush->original_sides = &brushsides[nummapbrushsides];
- mapbrush->entitynum = mapent - entities;
- mapbrush->brushnum = nummapbrushes - mapent->firstbrush;
- mapbrush->leafnum = -1;
- mapbrush->numsides = 0;
-
- besttexinfo = TEXINFO_NODE;
- for (i = 0; i < bspbrush->numsides; i++)
- {
- if (!bspbrush->sides[i].winding) continue;
- //
- if (nummapbrushsides >= MAX_MAPFILE_BRUSHSIDES)
- Error ("MAX_MAPFILE_BRUSHSIDES");
- side = &brushsides[nummapbrushsides];
- //the contents of the bsp brush is stored in the side variable
- side->contents = bspbrush->side;
- side->surf = 0;
- side->planenum = bspbrush->sides[i].planenum;
- side->texinfo = bspbrush->sides[i].texinfo;
- if (side->texinfo != TEXINFO_NODE)
- {
- //this brush side is textured
- side->flags |= SFL_TEXTURED;
- besttexinfo = side->texinfo;
- } //end if
- //
- nummapbrushsides++;
- mapbrush->numsides++;
- } //end for
- //
- if (besttexinfo == TEXINFO_NODE)
- {
- mapbrush->numsides = 0;
- q1_numclipbrushes++;
- return;
- } //end if
- //set the texinfo for all the brush sides without texture
- for (i = 0; i < mapbrush->numsides; i++)
- {
- if (mapbrush->original_sides[i].texinfo == TEXINFO_NODE)
- {
- mapbrush->original_sides[i].texinfo = besttexinfo;
- } //end if
- } //end for
- //contents of the brush
- mapbrush->contents = bspbrush->side;
- //
- if (create_aas)
- {
- //create the AAS brushes from this brush, add brush bevels
- AAS_CreateMapBrushes(mapbrush, mapent, true);
- return;
- } //end if
- //create windings for sides and bounds for brush
- MakeBrushWindings(mapbrush);
- //add brush bevels
- AddBrushBevels(mapbrush);
- //a new brush has been created
- nummapbrushes++;
- mapent->numbrushes++;
-} //end of the function Q1_BSPBrushToMapBrush
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void Q1_CreateMapBrushes(entity_t *mapent, int modelnum)
-{
- bspbrush_t *brushlist, *brush, *nextbrush;
- int i;
-
- //create brushes from the model BSP tree
- brushlist = Q1_CreateBrushesFromBSP(modelnum);
- //texture the brushes and split them when necesary
- brushlist = Q1_TextureBrushes(brushlist, modelnum);
- //fix the contents textures of all brushes
- Q1_FixContentsTextures(brushlist);
- //
- if (!nobrushmerge)
- {
- brushlist = Q1_MergeBrushes(brushlist, modelnum);
- //brushlist = Q1_MergeBrushes(brushlist, modelnum);
- } //end if
- //
- if (!modelnum) qprintf("converting brushes to map brushes\n");
- if (!modelnum) qprintf("%5d brushes", i = 0);
- for (brush = brushlist; brush; brush = nextbrush)
- {
- nextbrush = brush->next;
- Q1_BSPBrushToMapBrush(brush, mapent);
- brush->next = NULL;
- FreeBrush(brush);
- if (!modelnum) qprintf("\r%5d", ++i);
- } //end for
- if (!modelnum) qprintf("\n");
-} //end of the function Q1_CreateMapBrushes
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void Q1_ResetMapLoading(void)
-{
-} //end of the function Q1_ResetMapLoading
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void Q1_LoadMapFromBSP(char *filename, int offset, int length)
-{
- int i, modelnum;
- char *model, *classname;
-
- Log_Print("-- Q1_LoadMapFromBSP --\n");
- //the loaded map type
- loadedmaptype = MAPTYPE_QUAKE1;
- //
- qprintf("loading map from %s at %d\n", filename, offset);
- //load the Half-Life BSP file
- Q1_LoadBSPFile(filename, offset, length);
- //
- q1_numclipbrushes = 0;
- //CreatePath(path);
- //Q1_CreateQ2WALFiles(path);
- //parse the entities from the BSP
- Q1_ParseEntities();
- //clear the map mins and maxs
- ClearBounds(map_mins, map_maxs);
- //
- qprintf("creating Quake1 brushes\n");
- if (lessbrushes) qprintf("creating minimum number of brushes\n");
- else qprintf("placing textures correctly\n");
- //
- for (i = 0; i < num_entities; i++)
- {
- entities[i].firstbrush = nummapbrushes;
- entities[i].numbrushes = 0;
- //
- classname = ValueForKey(&entities[i], "classname");
- if (classname && !strcmp(classname, "worldspawn"))
- {
- modelnum = 0;
- } //end if
- else
- {
- //
- model = ValueForKey(&entities[i], "model");
- if (!model || *model != '*') continue;
- model++;
- modelnum = atoi(model);
- } //end else
- //create map brushes for the entity
- Q1_CreateMapBrushes(&entities[i], modelnum);
- } //end for
- //
- qprintf("%5d map brushes\n", nummapbrushes);
- qprintf("%5d clip brushes\n", q1_numclipbrushes);
-} //end of the function Q1_LoadMapFromBSP
diff --git a/code/bspc/map_q2.c b/code/bspc/map_q2.c
deleted file mode 100644
index 06dc0a7..0000000
--- a/code/bspc/map_q2.c
+++ /dev/null
@@ -1,1162 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-//===========================================================================
-// ANSI, Area Navigational System Interface
-// AAS, Area Awareness System
-//===========================================================================
-
-#include "qbsp.h"
-#include "l_mem.h"
-#include "../botlib/aasfile.h" //aas_bbox_t
-#include "aas_store.h" //AAS_MAX_BBOXES
-#include "aas_cfg.h"
-#include "aas_map.h" //AAS_CreateMapBrushes
-#include "l_bsp_q2.h"
-
-
-#ifdef ME
-
-#define NODESTACKSIZE 1024
-
-int nodestack[NODESTACKSIZE];
-int *nodestackptr;
-int nodestacksize = 0;
-int brushmodelnumbers[MAX_MAPFILE_BRUSHES];
-int dbrushleafnums[MAX_MAPFILE_BRUSHES];
-int dplanes2mapplanes[MAX_MAPFILE_PLANES];
-
-#endif //ME
-
-//====================================================================
-
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void Q2_CreateMapTexinfo(void)
-{
- int i;
-
- for (i = 0; i < numtexinfo; i++)
- {
- memcpy(map_texinfo[i].vecs, texinfo[i].vecs, sizeof(float) * 2 * 4);
- map_texinfo[i].flags = texinfo[i].flags;
- map_texinfo[i].value = texinfo[i].value;
- strcpy(map_texinfo[i].texture, texinfo[i].texture);
- map_texinfo[i].nexttexinfo = 0;
- } //end for
-} //end of the function Q2_CreateMapTexinfo
-
-/*
-===========
-Q2_BrushContents
-===========
-*/
-int Q2_BrushContents (mapbrush_t *b)
-{
- int contents;
- side_t *s;
- int i;
- int trans;
-
- s = &b->original_sides[0];
- contents = s->contents;
- trans = texinfo[s->texinfo].flags;
- for (i = 1; i < b->numsides; i++, s++)
- {
- s = &b->original_sides[i];
- trans |= texinfo[s->texinfo].flags;
- if (s->contents != contents)
- {
- Log_Print("Entity %i, Brush %i: mixed face contents\n"
- , b->entitynum, b->brushnum);
- Log_Print("texture name = %s\n", texinfo[s->texinfo].texture);
- break;
- }
- }
-
- // if any side is translucent, mark the contents
- // and change solid to window
- if ( trans & (SURF_TRANS33|SURF_TRANS66) )
- {
- contents |= CONTENTS_Q2TRANSLUCENT;
- if (contents & CONTENTS_SOLID)
- {
- contents &= ~CONTENTS_SOLID;
- contents |= CONTENTS_WINDOW;
- }
- }
-
- return contents;
-}
-
-#ifdef ME
-
-#define BBOX_NORMAL_EPSILON 0.0001
-
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void MakeAreaPortalBrush(mapbrush_t *brush)
-{
- int sn;
- side_t *s;
-
- brush->contents = CONTENTS_AREAPORTAL;
-
- for (sn = 0; sn < brush->numsides; sn++)
- {
- s = brush->original_sides + sn;
- //make sure the surfaces are not hint or skip
- s->surf &= ~(SURF_HINT|SURF_SKIP);
- //
- s->texinfo = 0;
- s->contents = CONTENTS_AREAPORTAL;
- } //end for
-} //end of the function MakeAreaPortalBrush
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void DPlanes2MapPlanes(void)
-{
- int i;
-
- for (i = 0; i < numplanes; i++)
- {
- dplanes2mapplanes[i] = FindFloatPlane(dplanes[i].normal, dplanes[i].dist);
- } //end for
-} //end of the function DPlanes2MapPlanes
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void MarkVisibleBrushSides(mapbrush_t *brush)
-{
- int n, i, planenum;
- side_t *side;
- dface_t *face;
- //
- for (n = 0; n < brush->numsides; n++)
- {
- side = brush->original_sides + n;
- //if this side is a bevel or the leaf number of the brush is unknown
- if ((side->flags & SFL_BEVEL) || brush->leafnum < 0)
- {
- //this side is a valid splitter
- side->flags |= SFL_VISIBLE;
- continue;
- } //end if
- //assum this side will not be used as a splitter
- side->flags &= ~SFL_VISIBLE;
- //check if the side plane is used by a visible face
- for (i = 0; i < numfaces; i++)
- {
- face = &dfaces[i];
- planenum = dplanes2mapplanes[face->planenum];
- if ((planenum & ~1) == (side->planenum & ~1))
- {
- //this side is a valid splitter
- side->flags |= SFL_VISIBLE;
- } //end if
- } //end for
- } //end for
-} //end of the function MarkVisibleBrushSides
-
-#endif //ME
-
-/*
-=================
-Q2_ParseBrush
-=================
-*/
-void Q2_ParseBrush (script_t *script, entity_t *mapent)
-{
- mapbrush_t *b;
- int i, j, k;
- int mt;
- side_t *side, *s2;
- int planenum;
- brush_texture_t td;
- int planepts[3][3];
- token_t token;
-
- if (nummapbrushes >= MAX_MAPFILE_BRUSHES)
- Error ("nummapbrushes == MAX_MAPFILE_BRUSHES");
-
- b = &mapbrushes[nummapbrushes];
- b->original_sides = &brushsides[nummapbrushsides];
- b->entitynum = num_entities-1;
- b->brushnum = nummapbrushes - mapent->firstbrush;
- b->leafnum = -1;
-
- do
- {
- if (!PS_ReadToken(script, &token))
- break;
- if (!strcmp(token.string, "}") )
- break;
-
- //IDBUG: mixed use of MAX_MAPFILE_? and MAX_MAP_? this could
- // lead to out of bound indexing of the arrays
- if (nummapbrushsides >= MAX_MAPFILE_BRUSHSIDES)
- Error ("MAX_MAPFILE_BRUSHSIDES");
- side = &brushsides[nummapbrushsides];
-
- //read the three point plane definition
- for (i = 0; i < 3; i++)
- {
- if (i != 0) PS_ExpectTokenString(script, "(");
- for (j = 0; j < 3; j++)
- {
- PS_ExpectAnyToken(script, &token);
- planepts[i][j] = atof(token.string);
- } //end for
- PS_ExpectTokenString(script, ")");
- } //end for
-
- //
- //read the texturedef
- //
- PS_ExpectAnyToken(script, &token);
- strcpy(td.name, token.string);
-
- PS_ExpectAnyToken(script, &token);
- td.shift[0] = atol(token.string);
- PS_ExpectAnyToken(script, &token);
- td.shift[1] = atol(token.string);
- PS_ExpectAnyToken(script, &token);
- td.rotate = atol(token.string);
- PS_ExpectAnyToken(script, &token);
- td.scale[0] = atof(token.string);
- PS_ExpectAnyToken(script, &token);
- td.scale[1] = atof(token.string);
-
- //find default flags and values
- mt = FindMiptex (td.name);
- td.flags = textureref[mt].flags;
- td.value = textureref[mt].value;
- side->contents = textureref[mt].contents;
- side->surf = td.flags = textureref[mt].flags;
-
- //check if there's a number available
- if (PS_CheckTokenType(script, TT_NUMBER, 0, &token))
- {
- side->contents = token.intvalue;
- PS_ExpectTokenType(script, TT_NUMBER, 0, &token);
- side->surf = td.flags = token.intvalue;
- PS_ExpectTokenType(script, TT_NUMBER, 0, &token);
- td.value = token.intvalue;
- }
-
- // translucent objects are automatically classified as detail
- if (side->surf & (SURF_TRANS33|SURF_TRANS66) )
- side->contents |= CONTENTS_DETAIL;
- if (side->contents & (CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP) )
- side->contents |= CONTENTS_DETAIL;
- if (fulldetail)
- side->contents &= ~CONTENTS_DETAIL;
- if (!(side->contents & ((LAST_VISIBLE_CONTENTS-1)
- | CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP|CONTENTS_MIST) ) )
- side->contents |= CONTENTS_SOLID;
-
- // hints and skips are never detail, and have no content
- if (side->surf & (SURF_HINT|SURF_SKIP) )
- {
- side->contents = 0;
- side->surf &= ~CONTENTS_DETAIL;
- }
-
-#ifdef ME
- //for creating AAS... this side is textured
- side->flags |= SFL_TEXTURED;
-#endif //ME
- //
- // find the plane number
- //
- planenum = PlaneFromPoints (planepts[0], planepts[1], planepts[2]);
- if (planenum == -1)
- {
- Log_Print("Entity %i, Brush %i: plane with no normal\n"
- , b->entitynum, b->brushnum);
- continue;
- }
-
- //
- // see if the plane has been used already
- //
- for (k=0 ; k<b->numsides ; k++)
- {
- s2 = b->original_sides + k;
- if (s2->planenum == planenum)
- {
- Log_Print("Entity %i, Brush %i: duplicate plane\n"
- , b->entitynum, b->brushnum);
- break;
- }
- if ( s2->planenum == (planenum^1) )
- {
- Log_Print("Entity %i, Brush %i: mirrored plane\n"
- , b->entitynum, b->brushnum);
- break;
- }
- }
- if (k != b->numsides)
- continue; // duplicated
-
- //
- // keep this side
- //
-
- side = b->original_sides + b->numsides;
- side->planenum = planenum;
- side->texinfo = TexinfoForBrushTexture (&mapplanes[planenum],
- &td, vec3_origin);
-
- // save the td off in case there is an origin brush and we
- // have to recalculate the texinfo
- side_brushtextures[nummapbrushsides] = td;
-
- nummapbrushsides++;
- b->numsides++;
- } while (1);
-
- // get the content for the entire brush
- b->contents = Q2_BrushContents (b);
-
-#ifdef ME
- if (BrushExists(b))
- {
- c_squattbrushes++;
- b->numsides = 0;
- return;
- } //end if
-
- if (create_aas)
- {
- //create AAS brushes, and add brush bevels
- AAS_CreateMapBrushes(b, mapent, true);
- //NOTE: if we return here then duplicate plane errors occur for the non world entities
- return;
- } //end if
-#endif //ME
-
- // allow detail brushes to be removed
- if (nodetail && (b->contents & CONTENTS_DETAIL) )
- {
- b->numsides = 0;
- return;
- }
-
- // allow water brushes to be removed
- if (nowater && (b->contents & (CONTENTS_LAVA | CONTENTS_SLIME | CONTENTS_WATER)) )
- {
- b->numsides = 0;
- return;
- }
-
- // create windings for sides and bounds for brush
- MakeBrushWindings (b);
-
- // brushes that will not be visible at all will never be
- // used as bsp splitters
- if (b->contents & (CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP) )
- {
- c_clipbrushes++;
- for (i=0 ; i<b->numsides ; i++)
- b->original_sides[i].texinfo = TEXINFO_NODE;
- }
-
- //
- // origin brushes are removed, but they set
- // the rotation origin for the rest of the brushes
- // in the entity. After the entire entity is parsed,
- // the planenums and texinfos will be adjusted for
- // the origin brush
- //
- if (b->contents & CONTENTS_ORIGIN)
- {
- char string[32];
- vec3_t origin;
-
- if (num_entities == 1)
- {
- Error ("Entity %i, Brush %i: origin brushes not allowed in world"
- , b->entitynum, b->brushnum);
- return;
- }
-
- VectorAdd (b->mins, b->maxs, origin);
- VectorScale (origin, 0.5, origin);
-
- sprintf (string, "%i %i %i", (int)origin[0], (int)origin[1], (int)origin[2]);
- SetKeyValue (&entities[b->entitynum], "origin", string);
-
- VectorCopy (origin, entities[b->entitynum].origin);
-
- // don't keep this brush
- b->numsides = 0;
-
- return;
- }
-
- AddBrushBevels(b);
-
- nummapbrushes++;
- mapent->numbrushes++;
-}
-
-/*
-================
-Q2_MoveBrushesToWorld
-
-Takes all of the brushes from the current entity and
-adds them to the world's brush list.
-
-Used by func_group and func_areaportal
-================
-*/
-void Q2_MoveBrushesToWorld (entity_t *mapent)
-{
- int newbrushes;
- int worldbrushes;
- mapbrush_t *temp;
- int i;
-
- // this is pretty gross, because the brushes are expected to be
- // in linear order for each entity
-
- newbrushes = mapent->numbrushes;
- worldbrushes = entities[0].numbrushes;
-
- temp = GetMemory(newbrushes*sizeof(mapbrush_t));
- memcpy (temp, mapbrushes + mapent->firstbrush, newbrushes*sizeof(mapbrush_t));
-
-#if 0 // let them keep their original brush numbers
- for (i=0 ; i<newbrushes ; i++)
- temp[i].entitynum = 0;
-#endif
-
- // make space to move the brushes (overlapped copy)
- memmove (mapbrushes + worldbrushes + newbrushes,
- mapbrushes + worldbrushes,
- sizeof(mapbrush_t) * (nummapbrushes - worldbrushes - newbrushes) );
-
- // copy the new brushes down
- memcpy (mapbrushes + worldbrushes, temp, sizeof(mapbrush_t) * newbrushes);
-
- // fix up indexes
- entities[0].numbrushes += newbrushes;
- for (i=1 ; i<num_entities ; i++)
- entities[i].firstbrush += newbrushes;
- FreeMemory(temp);
-
- mapent->numbrushes = 0;
-}
-
-/*
-================
-Q2_ParseMapEntity
-================
-*/
-qboolean Q2_ParseMapEntity(script_t *script)
-{
- entity_t *mapent;
- epair_t *e;
- side_t *s;
- int i, j;
- int startbrush, startsides;
- vec_t newdist;
- mapbrush_t *b;
- token_t token;
-
- if (!PS_ReadToken(script, &token)) return false;
-
- if (strcmp(token.string, "{") )
- Error ("ParseEntity: { not found");
-
- if (num_entities == MAX_MAP_ENTITIES)
- Error ("num_entities == MAX_MAP_ENTITIES");
-
- startbrush = nummapbrushes;
- startsides = nummapbrushsides;
-
- mapent = &entities[num_entities];
- num_entities++;
- memset (mapent, 0, sizeof(*mapent));
- mapent->firstbrush = nummapbrushes;
- mapent->numbrushes = 0;
-// mapent->portalareas[0] = -1;
-// mapent->portalareas[1] = -1;
-
- do
- {
- if (!PS_ReadToken(script, &token))
- {
- Error("ParseEntity: EOF without closing brace");
- } //end if
- if (!strcmp(token.string, "}")) break;
- if (!strcmp(token.string, "{"))
- {
- Q2_ParseBrush(script, mapent);
- } //end if
- else
- {
- PS_UnreadLastToken(script);
- e = ParseEpair(script);
- e->next = mapent->epairs;
- mapent->epairs = e;
- } //end else
- } while(1);
-
- GetVectorForKey(mapent, "origin", mapent->origin);
-
- //
- // if there was an origin brush, offset all of the planes and texinfo
- //
- if (mapent->origin[0] || mapent->origin[1] || mapent->origin[2])
- {
- for (i=0 ; i<mapent->numbrushes ; i++)
- {
- b = &mapbrushes[mapent->firstbrush + i];
- for (j=0 ; j<b->numsides ; j++)
- {
- s = &b->original_sides[j];
- newdist = mapplanes[s->planenum].dist -
- DotProduct (mapplanes[s->planenum].normal, mapent->origin);
- s->planenum = FindFloatPlane (mapplanes[s->planenum].normal, newdist);
- s->texinfo = TexinfoForBrushTexture (&mapplanes[s->planenum],
- &side_brushtextures[s-brushsides], mapent->origin);
- }
- MakeBrushWindings (b);
- }
- }
-
- // group entities are just for editor convenience
- // toss all brushes into the world entity
- if (!strcmp ("func_group", ValueForKey (mapent, "classname")))
- {
- Q2_MoveBrushesToWorld (mapent);
- mapent->numbrushes = 0;
- return true;
- }
-
- // areaportal entities move their brushes, but don't eliminate
- // the entity
- if (!strcmp ("func_areaportal", ValueForKey (mapent, "classname")))
- {
- char str[128];
-
- if (mapent->numbrushes != 1)
- Error ("Entity %i: func_areaportal can only be a single brush", num_entities-1);
-
- b = &mapbrushes[nummapbrushes-1];
- b->contents = CONTENTS_AREAPORTAL;
- c_areaportals++;
- mapent->areaportalnum = c_areaportals;
- // set the portal number as "style"
- sprintf (str, "%i", c_areaportals);
- SetKeyValue (mapent, "style", str);
- Q2_MoveBrushesToWorld (mapent);
- return true;
- }
-
- return true;
-}
-
-//===================================================================
-
-/*
-================
-LoadMapFile
-================
-*/
-void Q2_LoadMapFile(char *filename)
-{
- int i;
- script_t *script;
-
- Log_Print("-- Q2_LoadMapFile --\n");
-#ifdef ME
- //loaded map type
- loadedmaptype = MAPTYPE_QUAKE2;
- //reset the map loading
- ResetMapLoading();
-#endif //ME
-
- script = LoadScriptFile(filename);
- if (!script)
- {
- Log_Print("couldn't open %s\n", filename);
- return;
- } //end if
- //white spaces and escape characters inside a string are not allowed
- SetScriptFlags(script, SCFL_NOSTRINGWHITESPACES |
- SCFL_NOSTRINGESCAPECHARS |
- SCFL_PRIMITIVE);
-
- nummapbrushsides = 0;
- num_entities = 0;
-
- while (Q2_ParseMapEntity(script))
- {
- }
-
- ClearBounds (map_mins, map_maxs);
- for (i=0 ; i<entities[0].numbrushes ; i++)
- {
- if (mapbrushes[i].mins[0] > 4096)
- continue; // no valid points
- AddPointToBounds (mapbrushes[i].mins, map_mins, map_maxs);
- AddPointToBounds (mapbrushes[i].maxs, map_mins, map_maxs);
- } //end for
-
- PrintMapInfo();
-
- //free the script
- FreeScript(script);
-// TestExpandBrushes ();
- //
- Q2_CreateMapTexinfo();
-} //end of the function Q2_LoadMapFile
-
-#ifdef ME //Begin MAP loading from BSP file
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void Q2_SetLeafBrushesModelNumbers(int leafnum, int modelnum)
-{
- int i, brushnum;
- dleaf_t *leaf;
-
- leaf = &dleafs[leafnum];
- for (i = 0; i < leaf->numleafbrushes; i++)
- {
- brushnum = dleafbrushes[leaf->firstleafbrush + i];
- brushmodelnumbers[brushnum] = modelnum;
- dbrushleafnums[brushnum] = leafnum;
- } //end for
-} //end of the function Q2_SetLeafBrushesModelNumbers
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void Q2_InitNodeStack(void)
-{
- nodestackptr = nodestack;
- nodestacksize = 0;
-} //end of the function Q2_InitNodeStack
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void Q2_PushNodeStack(int num)
-{
- *nodestackptr = num;
- nodestackptr++;
- nodestacksize++;
- //
- if (nodestackptr >= &nodestack[NODESTACKSIZE])
- {
- Error("Q2_PushNodeStack: stack overflow\n");
- } //end if
-} //end of the function Q2_PushNodeStack
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int Q2_PopNodeStack(void)
-{
- //if the stack is empty
- if (nodestackptr <= nodestack) return -1;
- //decrease stack pointer
- nodestackptr--;
- nodestacksize--;
- //return the top value from the stack
- return *nodestackptr;
-} //end of the function Q2_PopNodeStack
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void Q2_SetBrushModelNumbers(entity_t *mapent)
-{
- int n, pn;
- int leafnum;
-
- //
- Q2_InitNodeStack();
- //head node (root) of the bsp tree
- n = dmodels[mapent->modelnum].headnode;
- pn = 0;
-
- do
- {
- //if we are in a leaf (negative node number)
- if (n < 0)
- {
- //number of the leaf
- leafnum = (-n) - 1;
- //set the brush numbers
- Q2_SetLeafBrushesModelNumbers(leafnum, mapent->modelnum);
- //walk back into the tree to find a second child to continue with
- for (pn = Q2_PopNodeStack(); pn >= 0; n = pn, pn = Q2_PopNodeStack())
- {
- //if we took the first child at the parent node
- if (dnodes[pn].children[0] == n) break;
- } //end for
- //if the stack wasn't empty (if not processed whole tree)
- if (pn >= 0)
- {
- //push the parent node again
- Q2_PushNodeStack(pn);
- //we proceed with the second child of the parent node
- n = dnodes[pn].children[1];
- } //end if
- } //end if
- else
- {
- //push the current node onto the stack
- Q2_PushNodeStack(n);
- //walk forward into the tree to the first child
- n = dnodes[n].children[0];
- } //end else
- } while(pn >= 0);
-} //end of the function Q2_SetBrushModelNumbers
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void Q2_BSPBrushToMapBrush(dbrush_t *bspbrush, entity_t *mapent)
-{
- mapbrush_t *b;
- int i, k, n;
- side_t *side, *s2;
- int planenum;
- dbrushside_t *bspbrushside;
- dplane_t *bspplane;
-
- if (nummapbrushes >= MAX_MAPFILE_BRUSHES)
- Error ("nummapbrushes >= MAX_MAPFILE_BRUSHES");
-
- b = &mapbrushes[nummapbrushes];
- b->original_sides = &brushsides[nummapbrushsides];
- b->entitynum = mapent-entities;
- b->brushnum = nummapbrushes - mapent->firstbrush;
- b->leafnum = dbrushleafnums[bspbrush - dbrushes];
-
- for (n = 0; n < bspbrush->numsides; n++)
- {
- //pointer to the bsp brush side
- bspbrushside = &dbrushsides[bspbrush->firstside + n];
-
- if (nummapbrushsides >= MAX_MAPFILE_BRUSHSIDES)
- {
- Error ("MAX_MAPFILE_BRUSHSIDES");
- } //end if
- //pointer to the map brush side
- side = &brushsides[nummapbrushsides];
- //if the BSP brush side is textured
- if (brushsidetextured[bspbrush->firstside + n]) side->flags |= SFL_TEXTURED;
- else side->flags &= ~SFL_TEXTURED;
- //ME: can get side contents and surf directly from BSP file
- side->contents = bspbrush->contents;
- //if the texinfo is TEXINFO_NODE
- if (bspbrushside->texinfo < 0) side->surf = 0;
- else side->surf = texinfo[bspbrushside->texinfo].flags;
-
- // translucent objects are automatically classified as detail
- if (side->surf & (SURF_TRANS33|SURF_TRANS66) )
- side->contents |= CONTENTS_DETAIL;
- if (side->contents & (CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP) )
- side->contents |= CONTENTS_DETAIL;
- if (fulldetail)
- side->contents &= ~CONTENTS_DETAIL;
- if (!(side->contents & ((LAST_VISIBLE_CONTENTS-1)
- | CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP|CONTENTS_MIST) ) )
- side->contents |= CONTENTS_SOLID;
-
- // hints and skips are never detail, and have no content
- if (side->surf & (SURF_HINT|SURF_SKIP) )
- {
- side->contents = 0;
- side->surf &= ~CONTENTS_DETAIL;
- }
-
- //ME: get a plane for this side
- bspplane = &dplanes[bspbrushside->planenum];
- planenum = FindFloatPlane(bspplane->normal, bspplane->dist);
- //
- // see if the plane has been used already
- //
- //ME: this really shouldn't happen!!!
- //ME: otherwise the bsp file is corrupted??
- //ME: still it seems to happen, maybe Johny Boy's
- //ME: brush bevel adding is crappy ?
- for (k = 0; k < b->numsides; k++)
- {
- s2 = b->original_sides + k;
-// if (DotProduct (mapplanes[s2->planenum].normal, mapplanes[planenum].normal) > 0.999
-// && fabs(mapplanes[s2->planenum].dist - mapplanes[planenum].dist) < 0.01 )
-
- if (s2->planenum == planenum)
- {
- Log_Print("Entity %i, Brush %i: duplicate plane\n"
- , b->entitynum, b->brushnum);
- break;
- }
- if ( s2->planenum == (planenum^1) )
- {
- Log_Print("Entity %i, Brush %i: mirrored plane\n"
- , b->entitynum, b->brushnum);
- break;
- }
- }
- if (k != b->numsides)
- continue; // duplicated
-
- //
- // keep this side
- //
- //ME: reset pointer to side, why? hell I dunno (pointer is set above already)
- side = b->original_sides + b->numsides;
- //ME: store the plane number
- side->planenum = planenum;
- //ME: texinfo is already stored when bsp is loaded
- //NOTE: check for TEXINFO_NODE, otherwise crash in Q2_BrushContents
- if (bspbrushside->texinfo < 0) side->texinfo = 0;
- else side->texinfo = bspbrushside->texinfo;
-
- // save the td off in case there is an origin brush and we
- // have to recalculate the texinfo
- // ME: don't need to recalculate because it's already done
- // (for non-world entities) in the BSP file
-// side_brushtextures[nummapbrushsides] = td;
-
- nummapbrushsides++;
- b->numsides++;
- } //end for
-
- // get the content for the entire brush
- b->contents = bspbrush->contents;
- Q2_BrushContents(b);
-
- if (BrushExists(b))
- {
- c_squattbrushes++;
- b->numsides = 0;
- return;
- } //end if
-
- //if we're creating AAS
- if (create_aas)
- {
- //create the AAS brushes from this brush, don't add brush bevels
- AAS_CreateMapBrushes(b, mapent, false);
- return;
- } //end if
-
- // allow detail brushes to be removed
- if (nodetail && (b->contents & CONTENTS_DETAIL) )
- {
- b->numsides = 0;
- return;
- } //end if
-
- // allow water brushes to be removed
- if (nowater && (b->contents & (CONTENTS_LAVA | CONTENTS_SLIME | CONTENTS_WATER)) )
- {
- b->numsides = 0;
- return;
- } //end if
-
- // create windings for sides and bounds for brush
- MakeBrushWindings(b);
-
- //mark brushes without winding or with a tiny window as bevels
- MarkBrushBevels(b);
-
- // brushes that will not be visible at all will never be
- // used as bsp splitters
- if (b->contents & (CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP) )
- {
- c_clipbrushes++;
- for (i = 0; i < b->numsides; i++)
- b->original_sides[i].texinfo = TEXINFO_NODE;
- } //end for
-
- //
- // origin brushes are removed, but they set
- // the rotation origin for the rest of the brushes
- // in the entity. After the entire entity is parsed,
- // the planenums and texinfos will be adjusted for
- // the origin brush
- //
- //ME: not needed because the entities in the BSP file already
- // have an origin set
-// if (b->contents & CONTENTS_ORIGIN)
-// {
-// char string[32];
-// vec3_t origin;
-//
-// if (num_entities == 1)
-// {
-// Error ("Entity %i, Brush %i: origin brushes not allowed in world"
-// , b->entitynum, b->brushnum);
-// return;
-// }
-//
-// VectorAdd (b->mins, b->maxs, origin);
-// VectorScale (origin, 0.5, origin);
-//
-// sprintf (string, "%i %i %i", (int)origin[0], (int)origin[1], (int)origin[2]);
-// SetKeyValue (&entities[b->entitynum], "origin", string);
-//
-// VectorCopy (origin, entities[b->entitynum].origin);
-//
-// // don't keep this brush
-// b->numsides = 0;
-//
-// return;
-// }
-
- //ME: the bsp brushes already have bevels, so we won't try to
- // add them again (especially since Johny Boy's bevel adding might
- // be crappy)
-// AddBrushBevels(b);
-
- nummapbrushes++;
- mapent->numbrushes++;
-} //end of the function Q2_BSPBrushToMapBrush
-//===========================================================================
-//===========================================================================
-void Q2_ParseBSPBrushes(entity_t *mapent)
-{
- int i;
-
- //give all the brushes that belong to this entity the number of the
- //BSP model used by this entity
- Q2_SetBrushModelNumbers(mapent);
- //now parse all the brushes with the correct mapent->modelnum
- for (i = 0; i < numbrushes; i++)
- {
- if (brushmodelnumbers[i] == mapent->modelnum)
- {
- Q2_BSPBrushToMapBrush(&dbrushes[i], mapent);
- } //end if
- } //end for
-} //end of the function Q2_ParseBSPBrushes
-//===========================================================================
-//===========================================================================
-qboolean Q2_ParseBSPEntity(int entnum)
-{
- entity_t *mapent;
- char *model;
- int startbrush, startsides;
-
- startbrush = nummapbrushes;
- startsides = nummapbrushsides;
-
- mapent = &entities[entnum];//num_entities];
- mapent->firstbrush = nummapbrushes;
- mapent->numbrushes = 0;
- mapent->modelnum = -1; //-1 = no model
-
- model = ValueForKey(mapent, "model");
- if (model && strlen(model))
- {
- if (*model != '*')
- {
- Error("Q2_ParseBSPEntity: model number without leading *");
- } //end if
- //get the model number of this entity (skip the leading *)
- mapent->modelnum = atoi(&model[1]);
- } //end if
-
- GetVectorForKey(mapent, "origin", mapent->origin);
-
- //if this is the world entity it has model number zero
- //the world entity has no model key
- if (!strcmp("worldspawn", ValueForKey(mapent, "classname")))
- {
- mapent->modelnum = 0;
- } //end if
- //if the map entity has a BSP model (a modelnum of -1 is used for
- //entities that aren't using a BSP model)
- if (mapent->modelnum >= 0)
- {
- //parse the bsp brushes
- Q2_ParseBSPBrushes(mapent);
- } //end if
- //
- //the origin of the entity is already taken into account
- //
- //func_group entities can't be in the bsp file
- //
- //check out the func_areaportal entities
- if (!strcmp ("func_areaportal", ValueForKey (mapent, "classname")))
- {
- c_areaportals++;
- mapent->areaportalnum = c_areaportals;
- return true;
- } //end if
- return true;
-} //end of the function Q2_ParseBSPEntity
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void Q2_LoadMapFromBSP(char *filename, int offset, int length)
-{
- int i;
-
- Log_Print("-- Q2_LoadMapFromBSP --\n");
- //loaded map type
- loadedmaptype = MAPTYPE_QUAKE2;
-
- Log_Print("Loading map from %s...\n", filename);
- //load the bsp file
- Q2_LoadBSPFile(filename, offset, length);
-
- //create an index from bsp planes to map planes
- //DPlanes2MapPlanes();
- //clear brush model numbers
- for (i = 0; i < MAX_MAPFILE_BRUSHES; i++)
- brushmodelnumbers[i] = -1;
-
- nummapbrushsides = 0;
- num_entities = 0;
-
- Q2_ParseEntities();
- //
- for (i = 0; i < num_entities; i++)
- {
- Q2_ParseBSPEntity(i);
- } //end for
-
- //get the map mins and maxs from the world model
- ClearBounds(map_mins, map_maxs);
- for (i = 0; i < entities[0].numbrushes; i++)
- {
- if (mapbrushes[i].mins[0] > 4096)
- continue; //no valid points
- AddPointToBounds (mapbrushes[i].mins, map_mins, map_maxs);
- AddPointToBounds (mapbrushes[i].maxs, map_mins, map_maxs);
- } //end for
-
- PrintMapInfo();
- //
- Q2_CreateMapTexinfo();
-} //end of the function Q2_LoadMapFromBSP
-
-void Q2_ResetMapLoading(void)
-{
- //reset for map loading from bsp
- memset(nodestack, 0, NODESTACKSIZE * sizeof(int));
- nodestackptr = NULL;
- nodestacksize = 0;
- memset(brushmodelnumbers, 0, MAX_MAPFILE_BRUSHES * sizeof(int));
-} //end of the function Q2_ResetMapLoading
-
-//End MAP loading from BSP file
-#endif //ME
-
-//====================================================================
-
-/*
-================
-TestExpandBrushes
-
-Expands all the brush planes and saves a new map out
-================
-*/
-void TestExpandBrushes (void)
-{
- FILE *f;
- side_t *s;
- int i, j, bn;
- winding_t *w;
- char *name = "expanded.map";
- mapbrush_t *brush;
- vec_t dist;
-
- Log_Print("writing %s\n", name);
- f = fopen (name, "wb");
- if (!f)
- Error ("Can't write %s\n", name);
-
- fprintf (f, "{\n\"classname\" \"worldspawn\"\n");
-
- for (bn=0 ; bn<nummapbrushes ; bn++)
- {
- brush = &mapbrushes[bn];
- fprintf (f, "{\n");
- for (i=0 ; i<brush->numsides ; i++)
- {
- s = brush->original_sides + i;
- dist = mapplanes[s->planenum].dist;
- for (j=0 ; j<3 ; j++)
- dist += fabs( 16 * mapplanes[s->planenum].normal[j] );
-
- w = BaseWindingForPlane (mapplanes[s->planenum].normal, dist);
-
- fprintf (f,"( %i %i %i ) ", (int)w->p[0][0], (int)w->p[0][1], (int)w->p[0][2]);
- fprintf (f,"( %i %i %i ) ", (int)w->p[1][0], (int)w->p[1][1], (int)w->p[1][2]);
- fprintf (f,"( %i %i %i ) ", (int)w->p[2][0], (int)w->p[2][1], (int)w->p[2][2]);
-
- fprintf (f, "%s 0 0 0 1 1\n", texinfo[s->texinfo].texture);
- FreeWinding (w);
- }
- fprintf (f, "}\n");
- }
- fprintf (f, "}\n");
-
- fclose (f);
-
- Error ("can't proceed after expanding brushes");
-} //end of the function TestExpandBrushes
-
diff --git a/code/bspc/map_q3.c b/code/bspc/map_q3.c
deleted file mode 100644
index 664dd39..0000000
--- a/code/bspc/map_q3.c
+++ /dev/null
@@ -1,681 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-#include "qbsp.h"
-#include "l_mem.h"
-#include "../botlib/aasfile.h" //aas_bbox_t
-#include "aas_store.h" //AAS_MAX_BBOXES
-#include "aas_cfg.h"
-#include "aas_map.h" //AAS_CreateMapBrushes
-#include "l_bsp_q3.h"
-#include "../qcommon/cm_patch.h"
-#include "../qcommon/surfaceflags.h"
-
-#define NODESTACKSIZE 1024
-
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void PrintContents(int contents);
-
-int Q3_BrushContents(mapbrush_t *b)
-{
- int contents, i, mixed, hint;
- side_t *s;
-
- s = &b->original_sides[0];
- contents = s->contents;
- //
- mixed = false;
- hint = false;
- for (i = 1; i < b->numsides; i++)
- {
- s = &b->original_sides[i];
- if (s->contents != contents) mixed = true;
- if (s->surf & (SURF_HINT|SURF_SKIP)) hint = true;
- contents |= s->contents;
- } //end for
- //
- if (hint)
- {
- if (contents)
- {
- Log_Write("WARNING: hint brush with contents: ");
- PrintContents(contents);
- Log_Write("\r\n");
- //
- Log_Write("brush contents is: ");
- PrintContents(b->contents);
- Log_Write("\r\n");
- } //end if
- return 0;
- } //end if
- //Log_Write("brush %d contents ", nummapbrushes);
- //PrintContents(contents);
- //Log_Write("\r\n");
- //remove ladder and fog contents
- contents &= ~(CONTENTS_LADDER|CONTENTS_FOG);
- //
- if (mixed)
- {
- Log_Write("Entity %i, Brush %i: mixed face contents "
- , b->entitynum, b->brushnum);
- PrintContents(contents);
- Log_Write("\r\n");
- //
- Log_Write("brush contents is: ");
- PrintContents(b->contents);
- Log_Write("\r\n");
- //
- if (contents & CONTENTS_DONOTENTER) return CONTENTS_DONOTENTER;//Log_Print("mixed contents with donotenter\n");
- /*
- Log_Print("contents:"); PrintContents(contents);
- Log_Print("\ncontents:"); PrintContents(s->contents);
- Log_Print("\n");
- Log_Print("texture name = %s\n", texinfo[s->texinfo].texture);
- */
- //if liquid brush
- if (contents & (CONTENTS_LAVA | CONTENTS_SLIME | CONTENTS_WATER))
- {
- return (contents & (CONTENTS_LAVA | CONTENTS_SLIME | CONTENTS_WATER));
- } //end if
- if (contents & CONTENTS_PLAYERCLIP) return (contents & CONTENTS_PLAYERCLIP);
- return (contents & CONTENTS_SOLID);
- } //end if
- /*
- if (contents & CONTENTS_AREAPORTAL)
- {
- static int num;
- Log_Write("Entity %i, Brush %i: area portal %d\r\n", b->entitynum, b->brushnum, num++);
- } //end if*/
- if (contents == (contents & CONTENTS_STRUCTURAL))
- {
- //Log_Print("brush %i is only structural\n", b->brushnum);
- contents = 0;
- } //end if
- if (contents & CONTENTS_DONOTENTER)
- {
- Log_Print("brush %i is a donotenter brush, c = %X\n", b->brushnum, contents);
- } //end if
- return contents;
-} //end of the function Q3_BrushContents
-#define BBOX_NORMAL_EPSILON 0.0001
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void Q3_DPlanes2MapPlanes(void)
-{
- int i;
-
- for (i = 0; i < q3_numplanes; i++)
- {
- dplanes2mapplanes[i] = FindFloatPlane(q3_dplanes[i].normal, q3_dplanes[i].dist);
- } //end for
-} //end of the function Q3_DPlanes2MapPlanes
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void Q3_BSPBrushToMapBrush(q3_dbrush_t *bspbrush, entity_t *mapent)
-{
- mapbrush_t *b;
- int i, k, n;
- side_t *side, *s2;
- int planenum;
- q3_dbrushside_t *bspbrushside;
- q3_dplane_t *bspplane;
-
- if (nummapbrushes >= MAX_MAPFILE_BRUSHES)
- Error ("nummapbrushes >= MAX_MAPFILE_BRUSHES");
-
- b = &mapbrushes[nummapbrushes];
- b->original_sides = &brushsides[nummapbrushsides];
- b->entitynum = mapent-entities;
- b->brushnum = nummapbrushes - mapent->firstbrush;
- b->leafnum = dbrushleafnums[bspbrush - q3_dbrushes];
-
- for (n = 0; n < bspbrush->numSides; n++)
- {
- //pointer to the bsp brush side
- bspbrushside = &q3_dbrushsides[bspbrush->firstSide + n];
-
- if (nummapbrushsides >= MAX_MAPFILE_BRUSHSIDES)
- {
- Error ("MAX_MAPFILE_BRUSHSIDES");
- } //end if
- //pointer to the map brush side
- side = &brushsides[nummapbrushsides];
- //if the BSP brush side is textured
- if (q3_dbrushsidetextured[bspbrush->firstSide + n]) side->flags |= SFL_TEXTURED|SFL_VISIBLE;
- else side->flags &= ~SFL_TEXTURED;
- //NOTE: all Quake3 sides are assumed textured
- //side->flags |= SFL_TEXTURED|SFL_VISIBLE;
- //
- if (bspbrushside->shaderNum < 0)
- {
- side->contents = 0;
- side->surf = 0;
- } //end if
- else
- {
- side->contents = q3_dshaders[bspbrushside->shaderNum].contentFlags;
- side->surf = q3_dshaders[bspbrushside->shaderNum].surfaceFlags;
- if (strstr(q3_dshaders[bspbrushside->shaderNum].shader, "common/hint"))
- {
- //Log_Print("found hint side\n");
- side->surf |= SURF_HINT;
- } //end if
- } //end else
- //
- if (side->surf & SURF_NODRAW)
- {
- side->flags |= SFL_TEXTURED|SFL_VISIBLE;
- } //end if
- /*
- if (side->contents & (CONTENTS_TRANSLUCENT|CONTENTS_STRUCTURAL))
- {
- side->flags |= SFL_TEXTURED|SFL_VISIBLE;
- } //end if*/
-
- // hints and skips are never detail, and have no content
- if (side->surf & (SURF_HINT|SURF_SKIP) )
- {
- side->contents = 0;
- //Log_Print("found hint brush side\n");
- }
- /*
- if ((side->surf & SURF_NODRAW) && (side->surf & SURF_NOIMPACT))
- {
- side->contents = 0;
- side->surf &= ~CONTENTS_DETAIL;
- Log_Print("probably found hint brush in a BSP without hints being used\n");
- } //end if*/
-
- //ME: get a plane for this side
- bspplane = &q3_dplanes[bspbrushside->planeNum];
- planenum = FindFloatPlane(bspplane->normal, bspplane->dist);
- //
- // see if the plane has been used already
- //
- //ME: this really shouldn't happen!!!
- //ME: otherwise the bsp file is corrupted??
- //ME: still it seems to happen, maybe Johny Boy's
- //ME: brush bevel adding is crappy ?
- for (k = 0; k < b->numsides; k++)
- {
- s2 = b->original_sides + k;
-// if (DotProduct (mapplanes[s2->planenum].normal, mapplanes[planenum].normal) > 0.999
-// && fabs(mapplanes[s2->planenum].dist - mapplanes[planenum].dist) < 0.01 )
-
- if (s2->planenum == planenum)
- {
- Log_Print("Entity %i, Brush %i: duplicate plane\n"
- , b->entitynum, b->brushnum);
- break;
- }
- if ( s2->planenum == (planenum^1) )
- {
- Log_Print("Entity %i, Brush %i: mirrored plane\n"
- , b->entitynum, b->brushnum);
- break;
- }
- }
- if (k != b->numsides)
- continue; // duplicated
-
- //
- // keep this side
- //
- //ME: reset pointer to side, why? hell I dunno (pointer is set above already)
- side = b->original_sides + b->numsides;
- //ME: store the plane number
- side->planenum = planenum;
- //ME: texinfo is already stored when bsp is loaded
- //NOTE: check for TEXINFO_NODE, otherwise crash in Q3_BrushContents
- //if (bspbrushside->texinfo < 0) side->texinfo = 0;
- //else side->texinfo = bspbrushside->texinfo;
-
- // save the td off in case there is an origin brush and we
- // have to recalculate the texinfo
- // ME: don't need to recalculate because it's already done
- // (for non-world entities) in the BSP file
-// side_brushtextures[nummapbrushsides] = td;
-
- nummapbrushsides++;
- b->numsides++;
- } //end for
-
- // get the content for the entire brush
- b->contents = q3_dshaders[bspbrush->shaderNum].contentFlags;
- b->contents &= ~(CONTENTS_LADDER|CONTENTS_FOG|CONTENTS_STRUCTURAL);
-// b->contents = Q3_BrushContents(b);
- //
-
- if (BrushExists(b))
- {
- c_squattbrushes++;
- b->numsides = 0;
- return;
- } //end if
-
- //if we're creating AAS
- if (create_aas)
- {
- //create the AAS brushes from this brush, don't add brush bevels
- AAS_CreateMapBrushes(b, mapent, false);
- return;
- } //end if
-
- // allow detail brushes to be removed
- if (nodetail && (b->contents & CONTENTS_DETAIL) )
- {
- b->numsides = 0;
- return;
- } //end if
-
- // allow water brushes to be removed
- if (nowater && (b->contents & (CONTENTS_LAVA | CONTENTS_SLIME | CONTENTS_WATER)) )
- {
- b->numsides = 0;
- return;
- } //end if
-
- // create windings for sides and bounds for brush
- MakeBrushWindings(b);
-
- //mark brushes without winding or with a tiny window as bevels
- MarkBrushBevels(b);
-
- // brushes that will not be visible at all will never be
- // used as bsp splitters
- if (b->contents & (CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP) )
- {
- c_clipbrushes++;
- for (i = 0; i < b->numsides; i++)
- b->original_sides[i].texinfo = TEXINFO_NODE;
- } //end for
-
- //
- // origin brushes are removed, but they set
- // the rotation origin for the rest of the brushes
- // in the entity. After the entire entity is parsed,
- // the planenums and texinfos will be adjusted for
- // the origin brush
- //
- //ME: not needed because the entities in the BSP file already
- // have an origin set
-// if (b->contents & CONTENTS_ORIGIN)
-// {
-// char string[32];
-// vec3_t origin;
-//
-// if (num_entities == 1)
-// {
-// Error ("Entity %i, Brush %i: origin brushes not allowed in world"
-// , b->entitynum, b->brushnum);
-// return;
-// }
-//
-// VectorAdd (b->mins, b->maxs, origin);
-// VectorScale (origin, 0.5, origin);
-//
-// sprintf (string, "%i %i %i", (int)origin[0], (int)origin[1], (int)origin[2]);
-// SetKeyValue (&entities[b->entitynum], "origin", string);
-//
-// VectorCopy (origin, entities[b->entitynum].origin);
-//
-// // don't keep this brush
-// b->numsides = 0;
-//
-// return;
-// }
-
- //ME: the bsp brushes already have bevels, so we won't try to
- // add them again (especially since Johny Boy's bevel adding might
- // be crappy)
-// AddBrushBevels(b);
-
- nummapbrushes++;
- mapent->numbrushes++;
-} //end of the function Q3_BSPBrushToMapBrush
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void Q3_ParseBSPBrushes(entity_t *mapent)
-{
- int i;
-
- for (i = 0; i < q3_dmodels[mapent->modelnum].numBrushes; i++)
- {
- Q3_BSPBrushToMapBrush(&q3_dbrushes[q3_dmodels[mapent->modelnum].firstBrush + i], mapent);
- } //end for
-} //end of the function Q3_ParseBSPBrushes
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-qboolean Q3_ParseBSPEntity(int entnum)
-{
- entity_t *mapent;
- char *model;
- int startbrush, startsides;
-
- startbrush = nummapbrushes;
- startsides = nummapbrushsides;
-
- mapent = &entities[entnum];//num_entities];
- mapent->firstbrush = nummapbrushes;
- mapent->numbrushes = 0;
- mapent->modelnum = -1; //-1 = no BSP model
-
- model = ValueForKey(mapent, "model");
- if (model && strlen(model))
- {
- if (*model == '*')
- {
- //get the model number of this entity (skip the leading *)
- mapent->modelnum = atoi(&model[1]);
- } //end if
- } //end if
-
- GetVectorForKey(mapent, "origin", mapent->origin);
-
- //if this is the world entity it has model number zero
- //the world entity has no model key
- if (!strcmp("worldspawn", ValueForKey(mapent, "classname")))
- {
- mapent->modelnum = 0;
- } //end if
- //if the map entity has a BSP model (a modelnum of -1 is used for
- //entities that aren't using a BSP model)
- if (mapent->modelnum >= 0)
- {
- //parse the bsp brushes
- Q3_ParseBSPBrushes(mapent);
- } //end if
- //
- //the origin of the entity is already taken into account
- //
- //func_group entities can't be in the bsp file
- //
- //check out the func_areaportal entities
- if (!strcmp ("func_areaportal", ValueForKey (mapent, "classname")))
- {
- c_areaportals++;
- mapent->areaportalnum = c_areaportals;
- return true;
- } //end if
- return true;
-} //end of the function Q3_ParseBSPEntity
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-#define MAX_PATCH_VERTS 1024
-
-void AAS_CreateCurveBrushes(void)
-{
- int i, j, n, planenum, numcurvebrushes = 0;
- q3_dsurface_t *surface;
- q3_drawVert_t *dv_p;
- vec3_t points[MAX_PATCH_VERTS];
- int width, height, c;
- patchCollide_t *pc;
- facet_t *facet;
- mapbrush_t *brush;
- side_t *side;
- entity_t *mapent;
- winding_t *winding;
-
- qprintf("nummapbrushsides = %d\n", nummapbrushsides);
- mapent = &entities[0];
- for (i = 0; i < q3_numDrawSurfaces; i++)
- {
- surface = &q3_drawSurfaces[i];
- if ( ! surface->patchWidth ) continue;
- // if the curve is not solid
- if (!(q3_dshaders[surface->shaderNum].contentFlags & (CONTENTS_SOLID|CONTENTS_PLAYERCLIP)))
- {
- //Log_Print("skipped non-solid curve\n");
- continue;
- } //end if
- // if this curve should not be used for AAS
- if ( q3_dshaders[surface->shaderNum].contentFlags & CONTENTS_NOBOTCLIP ) {
- continue;
- }
- //
- width = surface->patchWidth;
- height = surface->patchHeight;
- c = width * height;
- if (c > MAX_PATCH_VERTS)
- {
- Error("ParseMesh: MAX_PATCH_VERTS");
- } //end if
-
- dv_p = q3_drawVerts + surface->firstVert;
- for ( j = 0 ; j < c ; j++, dv_p++ )
- {
- points[j][0] = dv_p->xyz[0];
- points[j][1] = dv_p->xyz[1];
- points[j][2] = dv_p->xyz[2];
- } //end for
- // create the internal facet structure
- pc = CM_GeneratePatchCollide(width, height, points);
- //
- for (j = 0; j < pc->numFacets; j++)
- {
- facet = &pc->facets[j];
- //
- brush = &mapbrushes[nummapbrushes];
- brush->original_sides = &brushsides[nummapbrushsides];
- brush->entitynum = 0;
- brush->brushnum = nummapbrushes - mapent->firstbrush;
- //
- brush->numsides = facet->numBorders + 2;
- nummapbrushsides += brush->numsides;
- brush->contents = CONTENTS_SOLID;
- //
- //qprintf("\r%6d curve brushes", nummapbrushsides);//++numcurvebrushes);
- qprintf("\r%6d curve brushes", ++numcurvebrushes);
- //
- planenum = FindFloatPlane(pc->planes[facet->surfacePlane].plane, pc->planes[facet->surfacePlane].plane[3]);
- //
- side = &brush->original_sides[0];
- side->planenum = planenum;
- side->contents = CONTENTS_SOLID;
- side->flags |= SFL_TEXTURED|SFL_VISIBLE|SFL_CURVE;
- side->surf = 0;
- //
- side = &brush->original_sides[1];
- if (create_aas)
- {
- //the plane is expanded later so it's not a problem that
- //these first two opposite sides are coplanar
- side->planenum = planenum ^ 1;
- } //end if
- else
- {
- side->planenum = FindFloatPlane(mapplanes[planenum^1].normal, mapplanes[planenum^1].dist + 1);
- side->flags |= SFL_TEXTURED|SFL_VISIBLE;
- } //end else
- side->contents = CONTENTS_SOLID;
- side->flags |= SFL_CURVE;
- side->surf = 0;
- //
- winding = BaseWindingForPlane(mapplanes[side->planenum].normal, mapplanes[side->planenum].dist);
- for (n = 0; n < facet->numBorders; n++)
- {
- //never use the surface plane as a border
- if (facet->borderPlanes[n] == facet->surfacePlane) continue;
- //
- side = &brush->original_sides[2 + n];
- side->planenum = FindFloatPlane(pc->planes[facet->borderPlanes[n]].plane, pc->planes[facet->borderPlanes[n]].plane[3]);
- if (facet->borderInward[n]) side->planenum ^= 1;
- side->contents = CONTENTS_SOLID;
- side->flags |= SFL_TEXTURED|SFL_CURVE;
- side->surf = 0;
- //chop the winding in place
- if (winding) ChopWindingInPlace(&winding, mapplanes[side->planenum^1].normal, mapplanes[side->planenum^1].dist, 0.1); //CLIP_EPSILON);
- } //end for
- //VectorCopy(pc->bounds[0], brush->mins);
- //VectorCopy(pc->bounds[1], brush->maxs);
- if (!winding)
- {
- Log_Print("WARNING: AAS_CreateCurveBrushes: no winding\n");
- brush->numsides = 0;
- continue;
- } //end if
- brush->original_sides[0].winding = winding;
- WindingBounds(winding, brush->mins, brush->maxs);
- for (n = 0; n < 3; n++)
- {
- //IDBUG: all the indexes into the mins and maxs were zero (not using i)
- if (brush->mins[n] < -MAX_MAP_BOUNDS || brush->maxs[n] > MAX_MAP_BOUNDS)
- {
- Log_Print("entity %i, brush %i: bounds out of range\n", brush->entitynum, brush->brushnum);
- Log_Print("brush->mins[%d] = %f, brush->maxs[%d] = %f\n", n, brush->mins[n], n, brush->maxs[n]);
- brush->numsides = 0; //remove the brush
- break;
- } //end if
- if (brush->mins[n] > MAX_MAP_BOUNDS || brush->maxs[n] < -MAX_MAP_BOUNDS)
- {
- Log_Print("entity %i, brush %i: no visible sides on brush\n", brush->entitynum, brush->brushnum);
- Log_Print("brush->mins[%d] = %f, brush->maxs[%d] = %f\n", n, brush->mins[n], n, brush->maxs[n]);
- brush->numsides = 0; //remove the brush
- break;
- } //end if
- } //end for
- if (create_aas)
- {
- //NOTE: brush bevels now already added
- //AddBrushBevels(brush);
- AAS_CreateMapBrushes(brush, mapent, false);
- } //end if
- else
- {
- // create windings for sides and bounds for brush
- MakeBrushWindings(brush);
- AddBrushBevels(brush);
- nummapbrushes++;
- mapent->numbrushes++;
- } //end else
- } //end for
- } //end for
- //qprintf("\r%6d curve brushes", nummapbrushsides);//++numcurvebrushes);
- qprintf("\r%6d curve brushes\n", numcurvebrushes);
-} //end of the function AAS_CreateCurveBrushes
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AAS_ExpandMapBrush(mapbrush_t *brush, vec3_t mins, vec3_t maxs);
-
-void Q3_LoadMapFromBSP(struct quakefile_s *qf)
-{
- int i;
- vec3_t mins = {-1,-1,-1}, maxs = {1, 1, 1};
-
- Log_Print("-- Q3_LoadMapFromBSP --\n");
- //loaded map type
- loadedmaptype = MAPTYPE_QUAKE3;
-
- Log_Print("Loading map from %s...\n", qf->filename);
- //load the bsp file
- Q3_LoadBSPFile(qf);
-
- //create an index from bsp planes to map planes
- //DPlanes2MapPlanes();
- //clear brush model numbers
- for (i = 0; i < MAX_MAPFILE_BRUSHES; i++)
- brushmodelnumbers[i] = -1;
-
- nummapbrushsides = 0;
- num_entities = 0;
-
- Q3_ParseEntities();
- //
- for (i = 0; i < num_entities; i++)
- {
- Q3_ParseBSPEntity(i);
- } //end for
-
- AAS_CreateCurveBrushes();
- //get the map mins and maxs from the world model
- ClearBounds(map_mins, map_maxs);
- for (i = 0; i < entities[0].numbrushes; i++)
- {
- if (mapbrushes[i].numsides <= 0)
- continue;
- AddPointToBounds (mapbrushes[i].mins, map_mins, map_maxs);
- AddPointToBounds (mapbrushes[i].maxs, map_mins, map_maxs);
- } //end for
- /*/
- for (i = 0; i < nummapbrushes; i++)
- {
- //if (!mapbrushes[i].original_sides) continue;
- //AddBrushBevels(&mapbrushes[i]);
- //AAS_ExpandMapBrush(&mapbrushes[i], mins, maxs);
- } //end for*/
- /*
- for (i = 0; i < nummapbrushsides; i++)
- {
- Log_Write("side %d flags = %d", i, brushsides[i].flags);
- } //end for
- for (i = 0; i < nummapbrushes; i++)
- {
- Log_Write("brush contents: ");
- PrintContents(mapbrushes[i].contents);
- Log_Print("\n");
- } //end for*/
-} //end of the function Q3_LoadMapFromBSP
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void Q3_ResetMapLoading(void)
-{
- //reset for map loading from bsp
- memset(nodestack, 0, NODESTACKSIZE * sizeof(int));
- nodestackptr = NULL;
- nodestacksize = 0;
- memset(brushmodelnumbers, 0, MAX_MAPFILE_BRUSHES * sizeof(int));
-} //end of the function Q3_ResetMapLoading
-
diff --git a/code/bspc/map_sin.c b/code/bspc/map_sin.c
deleted file mode 100644
index 278c887..0000000
--- a/code/bspc/map_sin.c
+++ /dev/null
@@ -1,1211 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-//-----------------------------------------------------------------------------
-//
-// $Logfile:: /MissionPack/code/bspc/map_sin.c $
-
-#include "qbsp.h"
-#include "l_bsp_sin.h"
-#include "aas_map.h" //AAS_CreateMapBrushes
-
-
-//====================================================================
-
-
-/*
-===========
-Sin_BrushContents
-===========
-*/
-
-int Sin_BrushContents(mapbrush_t *b)
-{
- int contents;
- side_t *s;
- int i;
-#ifdef SIN
- float trans = 0;
-#else
- int trans;
-#endif
-
- s = &b->original_sides[0];
- contents = s->contents;
-
-#ifdef SIN
- trans = sin_texinfo[s->texinfo].translucence;
-#else
- trans = texinfo[s->texinfo].flags;
-#endif
- for (i=1 ; i<b->numsides ; i++, s++)
- {
- s = &b->original_sides[i];
-#ifdef SIN
- trans += sin_texinfo[s->texinfo].translucence;
-#else
- trans |= texinfo[s->texinfo].flags;
-#endif
- if (s->contents != contents)
- {
-#ifdef SIN
- if (
- ( s->contents & CONTENTS_DETAIL && !(contents & CONTENTS_DETAIL) ) ||
- ( !(s->contents & CONTENTS_DETAIL) && contents & CONTENTS_DETAIL )
- )
- {
- s->contents |= CONTENTS_DETAIL;
- contents |= CONTENTS_DETAIL;
- continue;
- }
-#endif
- printf ("Entity %i, Brush %i: mixed face contents\n"
- , b->entitynum, b->brushnum);
- break;
- }
- }
-
-
-#ifdef SIN
- if (contents & CONTENTS_FENCE)
- {
-// contents |= CONTENTS_TRANSLUCENT;
- contents |= CONTENTS_DETAIL;
- contents |= CONTENTS_DUMMYFENCE;
- contents &= ~CONTENTS_SOLID;
- contents &= ~CONTENTS_FENCE;
- contents |= CONTENTS_WINDOW;
- }
-#endif
-
- // if any side is translucent, mark the contents
- // and change solid to window
-#ifdef SIN
- if ( trans > 0 )
-#else
- if ( trans & (SURF_TRANS33|SURF_TRANS66) )
-#endif
- {
- contents |= CONTENTS_Q2TRANSLUCENT;
- if (contents & CONTENTS_SOLID)
- {
- contents &= ~CONTENTS_SOLID;
- contents |= CONTENTS_WINDOW;
- }
- }
-
- return contents;
-} //*/
-
-
-//============================================================================
-
-
-
-/*
-=================
-ParseBrush
-=================
-* /
-void ParseBrush (entity_t *mapent)
-{
- mapbrush_t *b;
- int i,j, k;
- int mt;
- side_t *side, *s2;
- int planenum;
- brush_texture_t td;
-#ifdef SIN
- textureref_t newref;
-#endif
- int planepts[3][3];
-
- if (nummapbrushes == MAX_MAP_BRUSHES)
- Error ("nummapbrushes == MAX_MAP_BRUSHES");
-
- b = &mapbrushes[nummapbrushes];
- b->original_sides = &brushsides[nummapbrushsides];
- b->entitynum = num_entities-1;
- b->brushnum = nummapbrushes - mapent->firstbrush;
-
- do
- {
- if (!GetToken (true))
- break;
- if (!strcmp (token, "}") )
- break;
-
- if (nummapbrushsides == MAX_MAP_BRUSHSIDES)
- Error ("MAX_MAP_BRUSHSIDES");
- side = &brushsides[nummapbrushsides];
-
- // read the three point plane definition
- for (i=0 ; i<3 ; i++)
- {
- if (i != 0)
- GetToken (true);
- if (strcmp (token, "(") )
- Error ("parsing brush");
-
- for (j=0 ; j<3 ; j++)
- {
- GetToken (false);
- planepts[i][j] = atoi(token);
- }
-
- GetToken (false);
- if (strcmp (token, ")") )
- Error ("parsing brush");
-
- }
-
-
- //
- // read the texturedef
- //
- GetToken (false);
- strcpy (td.name, token);
-
- GetToken (false);
- td.shift[0] = atoi(token);
- GetToken (false);
- td.shift[1] = atoi(token);
- GetToken (false);
-#ifdef SIN
- td.rotate = atof(token);
-#else
- td.rotate = atoi(token);
-#endif
- GetToken (false);
- td.scale[0] = atof(token);
- GetToken (false);
- td.scale[1] = atof(token);
-
- // find default flags and values
- mt = FindMiptex (td.name);
-#ifdef SIN
- // clear out the masks on newref
- memset(&newref,0,sizeof(newref));
- // copy over the name
- strcpy( newref.name, td.name );
-
- ParseSurfaceInfo( &newref );
- MergeRefs( &bsp_textureref[mt], &newref, &td.tref );
- side->contents = td.tref.contents;
- side->surf = td.tref.flags;
-#else
- td.flags = textureref[mt].flags;
- td.value = textureref[mt].value;
- side->contents = textureref[mt].contents;
- side->surf = td.flags = textureref[mt].flags;
-
- if (TokenAvailable())
- {
- GetToken (false);
- side->contents = atoi(token);
- GetToken (false);
- side->surf = td.flags = atoi(token);
- GetToken (false);
- td.value = atoi(token);
- }
-#endif
-
- // translucent objects are automatically classified as detail
-#ifdef SIN
- if ( td.tref.translucence > 0 )
-#else
- if (side->surf & (SURF_TRANS33|SURF_TRANS66) )
-#endif
- side->contents |= CONTENTS_DETAIL;
- if (side->contents & (CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP) )
- side->contents |= CONTENTS_DETAIL;
- if (fulldetail)
- side->contents &= ~CONTENTS_DETAIL;
- if (!(side->contents & ((LAST_VISIBLE_CONTENTS-1)
- | CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP|CONTENTS_MIST) ) )
- side->contents |= CONTENTS_SOLID;
-
- // hints and skips are never detail, and have no content
- if (side->surf & (SURF_HINT|SURF_SKIP) )
- {
- side->contents = 0;
-#ifndef SIN // I think this is a bug of some kind
- side->surf &= ~CONTENTS_DETAIL;
-#endif
- }
-
- //
- // find the plane number
- //
- planenum = PlaneFromPoints (planepts[0], planepts[1], planepts[2]);
- if (planenum == -1)
- {
- printf ("Entity %i, Brush %i: plane with no normal\n"
- , b->entitynum, b->brushnum);
- continue;
- }
-
- //
- // see if the plane has been used already
- //
- for (k=0 ; k<b->numsides ; k++)
- {
- s2 = b->original_sides + k;
- if (s2->planenum == planenum)
- {
- printf ("Entity %i, Brush %i: duplicate plane\n"
- , b->entitynum, b->brushnum);
- break;
- }
- if ( s2->planenum == (planenum^1) )
- {
- printf ("Entity %i, Brush %i: mirrored plane\n"
- , b->entitynum, b->brushnum);
- break;
- }
- }
- if (k != b->numsides)
- continue; // duplicated
-
- //
- // keep this side
- //
-
- side = b->original_sides + b->numsides;
- side->planenum = planenum;
-#ifdef SIN
- side->texinfo = TexinfoForBrushTexture (&mapplanes[planenum],
- &td, vec3_origin, &newref);
- //
- // save off lightinfo
- //
- side->lightinfo = LightinfoForBrushTexture ( &td );
-#else
- side->texinfo = TexinfoForBrushTexture (&mapplanes[planenum],
- &td, vec3_origin);
-
-#endif
-
- // save the td off in case there is an origin brush and we
- // have to recalculate the texinfo
- side_brushtextures[nummapbrushsides] = td;
-#ifdef SIN
- // save off the merged tref for animating textures
- side_newrefs[nummapbrushsides] = newref;
-#endif
-
- nummapbrushsides++;
- b->numsides++;
- } while (1);
-
- // get the content for the entire brush
- b->contents = Sin_BrushContents (b);
-
- // allow detail brushes to be removed
- if (nodetail && (b->contents & CONTENTS_DETAIL) )
- {
- b->numsides = 0;
- return;
- }
-
- // allow water brushes to be removed
- if (nowater && (b->contents & (CONTENTS_LAVA | CONTENTS_SLIME | CONTENTS_WATER)) )
- {
- b->numsides = 0;
- return;
- }
-
- // create windings for sides and bounds for brush
- MakeBrushWindings (b);
-
- // brushes that will not be visible at all will never be
- // used as bsp splitters
- if (b->contents & (CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP) )
- {
- c_clipbrushes++;
- for (i=0 ; i<b->numsides ; i++)
- b->original_sides[i].texinfo = TEXINFO_NODE;
- }
-
- //
- // origin brushes are removed, but they set
- // the rotation origin for the rest of the brushes
- // in the entity. After the entire entity is parsed,
- // the planenums and texinfos will be adjusted for
- // the origin brush
- //
- if (b->contents & CONTENTS_ORIGIN)
- {
- char string[32];
- vec3_t origin;
-
- if (num_entities == 1)
- {
- Error ("Entity %i, Brush %i: origin brushes not allowed in world"
- , b->entitynum, b->brushnum);
- return;
- }
-
- VectorAdd (b->mins, b->maxs, origin);
- VectorScale (origin, 0.5, origin);
-
- sprintf (string, "%i %i %i", (int)origin[0], (int)origin[1], (int)origin[2]);
- SetKeyValue (&entities[b->entitynum], "origin", string);
-
- VectorCopy (origin, entities[b->entitynum].origin);
-
- // don't keep this brush
- b->numsides = 0;
-
- return;
- }
-
- AddBrushBevels (b);
-
- nummapbrushes++;
- mapent->numbrushes++;
-} //*/
-
-/*
-================
-MoveBrushesToWorld
-
-Takes all of the brushes from the current entity and
-adds them to the world's brush list.
-
-Used by func_group and func_areaportal
-================
-* /
-void MoveBrushesToWorld (entity_t *mapent)
-{
- int newbrushes;
- int worldbrushes;
- mapbrush_t *temp;
- int i;
-
- // this is pretty gross, because the brushes are expected to be
- // in linear order for each entity
-
- newbrushes = mapent->numbrushes;
- worldbrushes = entities[0].numbrushes;
-
- temp = malloc(newbrushes*sizeof(mapbrush_t));
- memcpy (temp, mapbrushes + mapent->firstbrush, newbrushes*sizeof(mapbrush_t));
-
-#if 0 // let them keep their original brush numbers
- for (i=0 ; i<newbrushes ; i++)
- temp[i].entitynum = 0;
-#endif
-
- // make space to move the brushes (overlapped copy)
- memmove (mapbrushes + worldbrushes + newbrushes,
- mapbrushes + worldbrushes,
- sizeof(mapbrush_t) * (nummapbrushes - worldbrushes - newbrushes) );
-
- // copy the new brushes down
- memcpy (mapbrushes + worldbrushes, temp, sizeof(mapbrush_t) * newbrushes);
-
- // fix up indexes
- entities[0].numbrushes += newbrushes;
- for (i=1 ; i<num_entities ; i++)
- entities[i].firstbrush += newbrushes;
- free (temp);
-
- mapent->numbrushes = 0;
-} //*/
-
-/*
-================
-ParseMapEntity
-================
-* /
-qboolean Sin_ParseMapEntity (void)
-{
- entity_t *mapent;
- epair_t *e;
- side_t *s;
- int i, j;
- int startbrush, startsides;
- vec_t newdist;
- mapbrush_t *b;
-
- if (!GetToken (true))
- return false;
-
- if (strcmp (token, "{") )
- Error ("ParseEntity: { not found");
-
- if (num_entities == MAX_MAP_ENTITIES)
- Error ("num_entities == MAX_MAP_ENTITIES");
-
- startbrush = nummapbrushes;
- startsides = nummapbrushsides;
-
- mapent = &entities[num_entities];
- num_entities++;
- memset (mapent, 0, sizeof(*mapent));
- mapent->firstbrush = nummapbrushes;
- mapent->numbrushes = 0;
-// mapent->portalareas[0] = -1;
-// mapent->portalareas[1] = -1;
-
- do
- {
- if (!GetToken (true))
- Error ("ParseEntity: EOF without closing brace");
- if (!strcmp (token, "}") )
- break;
- if (!strcmp (token, "{") )
- ParseBrush (mapent);
- else
- {
- e = ParseEpair ();
-#ifdef SIN
- //HACK HACK HACK
- // MED Gotta do this here
- if ( !stricmp(e->key, "surfacefile") )
- {
- if (!surfacefile[0])
- {
- strcpy( surfacefile, e->value );
- }
- printf ("--- ParseSurfaceFile ---\n");
- printf ("Surface script: %s\n", surfacefile);
- if (!ParseSurfaceFile(surfacefile))
- {
- Error ("Script file not found: %s\n", surfacefile);
- }
- }
-#endif
- e->next = mapent->epairs;
- mapent->epairs = e;
- }
- } while (1);
-
-#ifdef SIN
- if (!(strlen(ValueForKey(mapent, "origin"))) && ((num_entities-1) != 0))
- {
- mapbrush_t *brush;
- vec3_t origin;
- char string[32];
- vec3_t mins, maxs;
- int start, end;
- // Calculate bounds
-
- start = mapent->firstbrush;
- end = start + mapent->numbrushes;
- ClearBounds (mins, maxs);
-
- for (j=start ; j<end ; j++)
- {
- brush = &mapbrushes[j];
- if (!brush->numsides)
- continue; // not a real brush (origin brush) - shouldn't happen
- AddPointToBounds (brush->mins, mins, maxs);
- AddPointToBounds (brush->maxs, mins, maxs);
- }
-
- // Set the origin to be the centroid of the entity.
- VectorAdd ( mins, maxs, origin);
- VectorScale( origin, 0.5f, origin );
-
- sprintf (string, "%i %i %i", (int)origin[0], (int)origin[1], (int)origin[2]);
- SetKeyValue ( mapent, "origin", string);
-// qprintf("Setting origin to %s\n",string);
- }
-#endif
-
- GetVectorForKey (mapent, "origin", mapent->origin);
-
-#ifdef SIN
- if (
- (!strcmp ("func_areaportal", ValueForKey (mapent, "classname"))) ||
- (!strcmp ("func_group", ValueForKey (mapent, "classname"))) ||
- (!strcmp ("detail", ValueForKey (mapent, "classname")) && !entitydetails)
- )
- {
- VectorClear( mapent->origin );
- }
-#endif
-
- //
- // if there was an origin brush, offset all of the planes and texinfo
- //
- if (mapent->origin[0] || mapent->origin[1] || mapent->origin[2])
- {
- for (i=0 ; i<mapent->numbrushes ; i++)
- {
- b = &mapbrushes[mapent->firstbrush + i];
- for (j=0 ; j<b->numsides ; j++)
- {
- s = &b->original_sides[j];
- newdist = mapplanes[s->planenum].dist -
- DotProduct (mapplanes[s->planenum].normal, mapent->origin);
- s->planenum = FindFloatPlane (mapplanes[s->planenum].normal, newdist);
-#ifdef SIN
- s->texinfo = TexinfoForBrushTexture (&mapplanes[s->planenum],
- &side_brushtextures[s-brushsides], mapent->origin, &side_newrefs[s-brushsides]);
- //
- // save off lightinfo
- //
- s->lightinfo = LightinfoForBrushTexture ( &side_brushtextures[s-brushsides] );
-#else
- s->texinfo = TexinfoForBrushTexture (&mapplanes[s->planenum],
- &side_brushtextures[s-brushsides], mapent->origin);
-#endif
- }
- MakeBrushWindings (b);
- }
- }
-
- // group entities are just for editor convenience
- // toss all brushes into the world entity
- if (!strcmp ("func_group", ValueForKey (mapent, "classname")))
- {
- MoveBrushesToWorld (mapent);
- mapent->numbrushes = 0;
- mapent->wasdetail = true;
- FreeValueKeys( mapent );
- return true;
- }
-#ifdef SIN
- // detail entities are just for editor convenience
- // toss all brushes into the world entity as detail brushes
- if (!strcmp ("detail", ValueForKey (mapent, "classname")) && !entitydetails)
- {
- for (i=0 ; i<mapent->numbrushes ; i++)
- {
- int j;
- side_t * s;
- b = &mapbrushes[mapent->firstbrush + i];
- if (nodetail)
- {
- b->numsides = 0;
- continue;
- }
- if (!fulldetail)
- {
- // set the contents for the entire brush
- b->contents |= CONTENTS_DETAIL;
- // set the contents in the sides as well
- for (j=0, s=b->original_sides ; j<b->numsides ; j++,s++)
- {
- s->contents |= CONTENTS_DETAIL;
- }
- }
- else
- {
- // set the contents for the entire brush
- b->contents |= CONTENTS_SOLID;
- // set the contents in the sides as well
- for (j=0, s=b->original_sides ; j<b->numsides ; j++,s++)
- {
- s->contents |= CONTENTS_SOLID;
- }
- }
- }
- MoveBrushesToWorld (mapent);
- mapent->wasdetail = true;
- FreeValueKeys( mapent );
- // kill off the entity
- // num_entities--;
- return true;
- }
-#endif
-
- // areaportal entities move their brushes, but don't eliminate
- // the entity
- if (!strcmp ("func_areaportal", ValueForKey (mapent, "classname")))
- {
- char str[128];
-
- if (mapent->numbrushes != 1)
- Error ("Entity %i: func_areaportal can only be a single brush", num_entities-1);
-
- b = &mapbrushes[nummapbrushes-1];
- b->contents = CONTENTS_AREAPORTAL;
- c_areaportals++;
- mapent->areaportalnum = c_areaportals;
- // set the portal number as "style"
- sprintf (str, "%i", c_areaportals);
- SetKeyValue (mapent, "style", str);
- MoveBrushesToWorld (mapent);
- return true;
- }
-
- return true;
-} //end of the function Sin_ParseMapEntity */
-
-//===================================================================
-
-/*
-================
-LoadMapFile
-================
-* /
-void Sin_LoadMapFile (char *filename)
-{
- int i;
-#ifdef SIN
- int num_detailsides=0;
- int num_detailbrushes=0;
- int num_worldsides=0;
- int num_worldbrushes=0;
- int j,k;
-#endif
-
- qprintf ("--- LoadMapFile ---\n");
-
- LoadScriptFile (filename);
-
- nummapbrushsides = 0;
- num_entities = 0;
-
- while (ParseMapEntity ())
- {
- }
-
- ClearBounds (map_mins, map_maxs);
- for (i=0 ; i<entities[0].numbrushes ; i++)
- {
- if (mapbrushes[i].mins[0] > 4096)
- continue; // no valid points
- AddPointToBounds (mapbrushes[i].mins, map_mins, map_maxs);
- AddPointToBounds (mapbrushes[i].maxs, map_mins, map_maxs);
- }
-#ifdef SIN
- for (j=0; j<num_entities; j++)
- {
- for (i=0 ; i<entities[j].numbrushes ; i++)
- {
- side_t * s;
- mapbrush_t *b;
- b = &mapbrushes[entities[j].firstbrush + i];
- if (b->numsides && b->contents & CONTENTS_DETAIL)
- num_detailbrushes++;
- else if (b->numsides)
- num_worldbrushes++;
- for (k=0, s=b->original_sides ; k<b->numsides ; k++,s++)
- {
- if (s->contents & CONTENTS_DETAIL)
- num_detailsides++;
- else
- num_worldsides++;
- }
- }
- }
-#endif
-
- qprintf ("%5i brushes\n", nummapbrushes);
- qprintf ("%5i clipbrushes\n", c_clipbrushes);
- qprintf ("%5i total sides\n", nummapbrushsides);
- qprintf ("%5i boxbevels\n", c_boxbevels);
- qprintf ("%5i edgebevels\n", c_edgebevels);
- qprintf ("%5i entities\n", num_entities);
- qprintf ("%5i planes\n", nummapplanes);
- qprintf ("%5i areaportals\n", c_areaportals);
- qprintf ("size: %5.0f,%5.0f,%5.0f to %5.0f,%5.0f,%5.0f\n", map_mins[0],map_mins[1],map_mins[2],
- map_maxs[0],map_maxs[1],map_maxs[2]);
-#ifdef SIN
- qprintf ("%5i detailbrushes\n", num_detailbrushes);
- qprintf ("%5i worldbrushes\n", num_worldbrushes);
- qprintf ("%5i detailsides\n", num_detailsides);
- qprintf ("%5i worldsides\n", num_worldsides);
-#endif
-
-} //end of the function Sin_LoadMap */
-
-
-#ifdef ME //Begin MAP loading from BSP file
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void Sin_CreateMapTexinfo(void)
-{
- int i;
- vec_t defaultvec[4] = {1, 0, 0, 0};
-
- memcpy(map_texinfo[0].vecs[0], defaultvec, sizeof(defaultvec));
- memcpy(map_texinfo[0].vecs[1], defaultvec, sizeof(defaultvec));
- map_texinfo[0].flags = 0;
- map_texinfo[0].value = 0;
- strcpy(map_texinfo[0].texture, "generic/misc/red"); //no texture
- map_texinfo[0].nexttexinfo = -1;
- for (i = 1; i < sin_numtexinfo; i++)
- {
- memcpy(map_texinfo[i].vecs, sin_texinfo[i].vecs, sizeof(float) * 2 * 4);
- map_texinfo[i].flags = sin_texinfo[i].flags;
- map_texinfo[i].value = 0;
- strcpy(map_texinfo[i].texture, sin_texinfo[i].texture);
- map_texinfo[i].nexttexinfo = -1;
- } //end for
-} //end of the function Sin_CreateMapTexinfo
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void Sin_SetLeafBrushesModelNumbers(int leafnum, int modelnum)
-{
- int i, brushnum;
- sin_dleaf_t *leaf;
-
- leaf = &sin_dleafs[leafnum];
- for (i = 0; i < leaf->numleafbrushes; i++)
- {
- brushnum = sin_dleafbrushes[leaf->firstleafbrush + i];
- brushmodelnumbers[brushnum] = modelnum;
- dbrushleafnums[brushnum] = leafnum;
- } //end for
-} //end of the function Sin_SetLeafBrushesModelNumbers
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void Sin_InitNodeStack(void)
-{
- nodestackptr = nodestack;
- nodestacksize = 0;
-} //end of the function Sin_InitNodeStack
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void Sin_PushNodeStack(int num)
-{
- *nodestackptr = num;
- nodestackptr++;
- nodestacksize++;
- //
- if (nodestackptr >= &nodestack[NODESTACKSIZE])
- {
- Error("Sin_PushNodeStack: stack overflow\n");
- } //end if
-} //end of the function Sin_PushNodeStack
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int Sin_PopNodeStack(void)
-{
- //if the stack is empty
- if (nodestackptr <= nodestack) return -1;
- //decrease stack pointer
- nodestackptr--;
- nodestacksize--;
- //return the top value from the stack
- return *nodestackptr;
-} //end of the function Sin_PopNodeStack
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void Sin_SetBrushModelNumbers(entity_t *mapent)
-{
- int n, pn;
- int leafnum;
-
- //
- Sin_InitNodeStack();
- //head node (root) of the bsp tree
- n = sin_dmodels[mapent->modelnum].headnode;
- pn = 0;
-
- do
- {
- //if we are in a leaf (negative node number)
- if (n < 0)
- {
- //number of the leaf
- leafnum = (-n) - 1;
- //set the brush numbers
- Sin_SetLeafBrushesModelNumbers(leafnum, mapent->modelnum);
- //walk back into the tree to find a second child to continue with
- for (pn = Sin_PopNodeStack(); pn >= 0; n = pn, pn = Sin_PopNodeStack())
- {
- //if we took the first child at the parent node
- if (sin_dnodes[pn].children[0] == n) break;
- } //end for
- //if the stack wasn't empty (if not processed whole tree)
- if (pn >= 0)
- {
- //push the parent node again
- Sin_PushNodeStack(pn);
- //we proceed with the second child of the parent node
- n = sin_dnodes[pn].children[1];
- } //end if
- } //end if
- else
- {
- //push the current node onto the stack
- Sin_PushNodeStack(n);
- //walk forward into the tree to the first child
- n = sin_dnodes[n].children[0];
- } //end else
- } while(pn >= 0);
-} //end of the function Sin_SetBrushModelNumbers
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void Sin_BSPBrushToMapBrush(sin_dbrush_t *bspbrush, entity_t *mapent)
-{
- mapbrush_t *b;
- int i, k, n;
- side_t *side, *s2;
- int planenum;
- sin_dbrushside_t *bspbrushside;
- sin_dplane_t *bspplane;
-
- if (nummapbrushes >= MAX_MAPFILE_BRUSHES)
- Error ("nummapbrushes >= MAX_MAPFILE_BRUSHES");
-
- b = &mapbrushes[nummapbrushes];
- b->original_sides = &brushsides[nummapbrushsides];
- b->entitynum = mapent-entities;
- b->brushnum = nummapbrushes - mapent->firstbrush;
- b->leafnum = dbrushleafnums[bspbrush - sin_dbrushes];
-
- for (n = 0; n < bspbrush->numsides; n++)
- {
- //pointer to the bsp brush side
- bspbrushside = &sin_dbrushsides[bspbrush->firstside + n];
-
- if (nummapbrushsides >= MAX_MAPFILE_BRUSHSIDES)
- {
- Error ("MAX_MAPFILE_BRUSHSIDES");
- } //end if
- //pointer to the map brush side
- side = &brushsides[nummapbrushsides];
- //if the BSP brush side is textured
- if (sin_dbrushsidetextured[bspbrush->firstside + n]) side->flags |= SFL_TEXTURED;
- else side->flags &= ~SFL_TEXTURED;
- //ME: can get side contents and surf directly from BSP file
- side->contents = bspbrush->contents;
- //if the texinfo is TEXINFO_NODE
- if (bspbrushside->texinfo < 0) side->surf = 0;
- else side->surf = sin_texinfo[bspbrushside->texinfo].flags;
-
- // translucent objects are automatically classified as detail
- if (side->surf & (SURF_TRANS33|SURF_TRANS66) )
- side->contents |= CONTENTS_DETAIL;
- if (side->contents & (CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP) )
- side->contents |= CONTENTS_DETAIL;
- if (fulldetail)
- side->contents &= ~CONTENTS_DETAIL;
- if (!(side->contents & ((LAST_VISIBLE_CONTENTS-1)
- | CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP|CONTENTS_MIST) ) )
- side->contents |= CONTENTS_SOLID;
-
- // hints and skips are never detail, and have no content
- if (side->surf & (SURF_HINT|SURF_SKIP) )
- {
- side->contents = 0;
- side->surf &= ~CONTENTS_DETAIL;
- }
-
- //ME: get a plane for this side
- bspplane = &sin_dplanes[bspbrushside->planenum];
- planenum = FindFloatPlane(bspplane->normal, bspplane->dist);
- //
- // see if the plane has been used already
- //
- //ME: this really shouldn't happen!!!
- //ME: otherwise the bsp file is corrupted??
- //ME: still it seems to happen, maybe Johny Boy's
- //ME: brush bevel adding is crappy ?
- for (k = 0; k < b->numsides; k++)
- {
- s2 = b->original_sides + k;
- if (s2->planenum == planenum)
- {
- Log_Print("Entity %i, Brush %i: duplicate plane\n"
- , b->entitynum, b->brushnum);
- break;
- }
- if ( s2->planenum == (planenum^1) )
- {
- Log_Print("Entity %i, Brush %i: mirrored plane\n"
- , b->entitynum, b->brushnum);
- break;
- }
- }
- if (k != b->numsides)
- continue; // duplicated
-
- //
- // keep this side
- //
- //ME: reset pointer to side, why? hell I dunno (pointer is set above already)
- side = b->original_sides + b->numsides;
- //ME: store the plane number
- side->planenum = planenum;
- //ME: texinfo is already stored when bsp is loaded
- //NOTE: check for TEXINFO_NODE, otherwise crash in Sin_BrushContents
- if (bspbrushside->texinfo < 0) side->texinfo = 0;
- else side->texinfo = bspbrushside->texinfo;
-
- // save the td off in case there is an origin brush and we
- // have to recalculate the texinfo
- // ME: don't need to recalculate because it's already done
- // (for non-world entities) in the BSP file
-// side_brushtextures[nummapbrushsides] = td;
-
- nummapbrushsides++;
- b->numsides++;
- } //end for
-
- // get the content for the entire brush
- b->contents = bspbrush->contents;
- Sin_BrushContents(b);
-
- if (BrushExists(b))
- {
- c_squattbrushes++;
- b->numsides = 0;
- return;
- } //end if
-
- //if we're creating AAS
- if (create_aas)
- {
- //create the AAS brushes from this brush, don't add brush bevels
- AAS_CreateMapBrushes(b, mapent, false);
- return;
- } //end if
-
- // allow detail brushes to be removed
- if (nodetail && (b->contents & CONTENTS_DETAIL) )
- {
- b->numsides = 0;
- return;
- } //end if
-
- // allow water brushes to be removed
- if (nowater && (b->contents & (CONTENTS_LAVA | CONTENTS_SLIME | CONTENTS_WATER)) )
- {
- b->numsides = 0;
- return;
- } //end if
-
- // create windings for sides and bounds for brush
- MakeBrushWindings(b);
-
- //mark brushes without winding or with a tiny window as bevels
- MarkBrushBevels(b);
-
- // brushes that will not be visible at all will never be
- // used as bsp splitters
- if (b->contents & (CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP) )
- {
- c_clipbrushes++;
- for (i = 0; i < b->numsides; i++)
- b->original_sides[i].texinfo = TEXINFO_NODE;
- } //end for
-
- //
- // origin brushes are removed, but they set
- // the rotation origin for the rest of the brushes
- // in the entity. After the entire entity is parsed,
- // the planenums and texinfos will be adjusted for
- // the origin brush
- //
- //ME: not needed because the entities in the BSP file already
- // have an origin set
-// if (b->contents & CONTENTS_ORIGIN)
-// {
-// char string[32];
-// vec3_t origin;
-//
-// if (num_entities == 1)
-// {
-// Error ("Entity %i, Brush %i: origin brushes not allowed in world"
-// , b->entitynum, b->brushnum);
-// return;
-// }
-//
-// VectorAdd (b->mins, b->maxs, origin);
-// VectorScale (origin, 0.5, origin);
-//
-// sprintf (string, "%i %i %i", (int)origin[0], (int)origin[1], (int)origin[2]);
-// SetKeyValue (&entities[b->entitynum], "origin", string);
-//
-// VectorCopy (origin, entities[b->entitynum].origin);
-//
-// // don't keep this brush
-// b->numsides = 0;
-//
-// return;
-// }
-
- //ME: the bsp brushes already have bevels, so we won't try to
- // add them again (especially since Johny Boy's bevel adding might
- // be crappy)
-// AddBrushBevels(b);
-
- nummapbrushes++;
- mapent->numbrushes++;
-} //end of the function Sin_BSPBrushToMapBrush
-//===========================================================================
-//===========================================================================
-void Sin_ParseBSPBrushes(entity_t *mapent)
-{
- int i, testnum = 0;
-
- //give all the brushes that belong to this entity the number of the
- //BSP model used by this entity
- Sin_SetBrushModelNumbers(mapent);
- //now parse all the brushes with the correct mapent->modelnum
- for (i = 0; i < sin_numbrushes; i++)
- {
- if (brushmodelnumbers[i] == mapent->modelnum)
- {
- testnum++;
- Sin_BSPBrushToMapBrush(&sin_dbrushes[i], mapent);
- } //end if
- } //end for
-} //end of the function Sin_ParseBSPBrushes
-//===========================================================================
-//===========================================================================
-qboolean Sin_ParseBSPEntity(int entnum)
-{
- entity_t *mapent;
- char *model;
- int startbrush, startsides;
-
- startbrush = nummapbrushes;
- startsides = nummapbrushsides;
-
- mapent = &entities[entnum];//num_entities];
- mapent->firstbrush = nummapbrushes;
- mapent->numbrushes = 0;
- mapent->modelnum = -1; //-1 = no model
-
- model = ValueForKey(mapent, "model");
- if (model && *model == '*')
- {
- mapent->modelnum = atoi(&model[1]);
- //Log_Print("model = %s\n", model);
- //Log_Print("mapent->modelnum = %d\n", mapent->modelnum);
- } //end if
-
- GetVectorForKey(mapent, "origin", mapent->origin);
-
- //if this is the world entity it has model number zero
- //the world entity has no model key
- if (!strcmp("worldspawn", ValueForKey(mapent, "classname")))
- {
- mapent->modelnum = 0;
- } //end if
- //if the map entity has a BSP model (a modelnum of -1 is used for
- //entities that aren't using a BSP model)
- if (mapent->modelnum >= 0)
- {
- //parse the bsp brushes
- Sin_ParseBSPBrushes(mapent);
- } //end if
- //
- //the origin of the entity is already taken into account
- //
- //func_group entities can't be in the bsp file
- //
- //check out the func_areaportal entities
- if (!strcmp ("func_areaportal", ValueForKey (mapent, "classname")))
- {
- c_areaportals++;
- mapent->areaportalnum = c_areaportals;
- return true;
- } //end if
- return true;
-} //end of the function Sin_ParseBSPEntity
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void Sin_LoadMapFromBSP(char *filename, int offset, int length)
-{
- int i;
-
- Log_Print("-- Sin_LoadMapFromBSP --\n");
- //loaded map type
- loadedmaptype = MAPTYPE_SIN;
-
- Log_Print("Loading map from %s...\n", filename);
- //load the bsp file
- Sin_LoadBSPFile(filename, offset, length);
-
- //create an index from bsp planes to map planes
- //DPlanes2MapPlanes();
- //clear brush model numbers
- for (i = 0; i < MAX_MAPFILE_BRUSHES; i++)
- brushmodelnumbers[i] = -1;
-
- nummapbrushsides = 0;
- num_entities = 0;
-
- Sin_ParseEntities();
- //
- for (i = 0; i < num_entities; i++)
- {
- Sin_ParseBSPEntity(i);
- } //end for
-
- //get the map mins and maxs from the world model
- ClearBounds(map_mins, map_maxs);
- for (i = 0; i < entities[0].numbrushes; i++)
- {
- if (mapbrushes[i].mins[0] > 4096)
- continue; //no valid points
- AddPointToBounds (mapbrushes[i].mins, map_mins, map_maxs);
- AddPointToBounds (mapbrushes[i].maxs, map_mins, map_maxs);
- } //end for
- //
- Sin_CreateMapTexinfo();
-} //end of the function Sin_LoadMapFromBSP
-
-void Sin_ResetMapLoading(void)
-{
- //reset for map loading from bsp
- memset(nodestack, 0, NODESTACKSIZE * sizeof(int));
- nodestackptr = NULL;
- nodestacksize = 0;
- memset(brushmodelnumbers, 0, MAX_MAPFILE_BRUSHES * sizeof(int));
-} //end of the function Sin_ResetMapLoading
-
-//End MAP loading from BSP file
-
-#endif //ME
diff --git a/code/bspc/nodraw.c b/code/bspc/nodraw.c
deleted file mode 100644
index 4649387..0000000
--- a/code/bspc/nodraw.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-#include "qbsp.h"
-
-vec3_t draw_mins, draw_maxs;
-qboolean drawflag;
-
-void Draw_ClearWindow (void)
-{
-}
-
-//============================================================
-
-#define GLSERV_PORT 25001
-
-
-void GLS_BeginScene (void)
-{
-}
-
-void GLS_Winding (winding_t *w, int code)
-{
-}
-
-void GLS_EndScene (void)
-{
-}
diff --git a/code/bspc/portals.c b/code/bspc/portals.c
deleted file mode 100644
index 0c03aaf..0000000
--- a/code/bspc/portals.c
+++ /dev/null
@@ -1,1297 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-#include "qbsp.h"
-#include "l_mem.h"
-
-int c_active_portals;
-int c_peak_portals;
-int c_boundary;
-int c_boundary_sides;
-int c_portalmemory;
-
-//portal_t *portallist = NULL;
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-portal_t *AllocPortal (void)
-{
- portal_t *p;
-
- p = GetMemory(sizeof(portal_t));
- memset (p, 0, sizeof(portal_t));
-
- if (numthreads == 1)
- {
- c_active_portals++;
- if (c_active_portals > c_peak_portals)
- {
- c_peak_portals = c_active_portals;
- } //end if
- c_portalmemory += MemorySize(p);
- } //end if
-
-// p->nextportal = portallist;
-// portallist = p;
-
- return p;
-} //end of the function AllocPortal
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void FreePortal (portal_t *p)
-{
- if (p->winding) FreeWinding(p->winding);
- if (numthreads == 1)
- {
- c_active_portals--;
- c_portalmemory -= MemorySize(p);
- } //end if
- FreeMemory(p);
-} //end of the function FreePortal
-//===========================================================================
-// Returns the single content bit of the
-// strongest visible content present
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int VisibleContents (int contents)
-{
- int i;
-
- for (i=1 ; i<=LAST_VISIBLE_CONTENTS ; i<<=1)
- if (contents & i )
- return i;
-
- return 0;
-} //end of the function VisibleContents
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int ClusterContents (node_t *node)
-{
- int c1, c2, c;
-
- if (node->planenum == PLANENUM_LEAF)
- return node->contents;
-
- c1 = ClusterContents(node->children[0]);
- c2 = ClusterContents(node->children[1]);
- c = c1|c2;
-
- // a cluster may include some solid detail areas, but
- // still be seen into
- if ( ! (c1&CONTENTS_SOLID) || ! (c2&CONTENTS_SOLID) )
- c &= ~CONTENTS_SOLID;
- return c;
-} //end of the function ClusterContents
-
-//===========================================================================
-// Returns true if the portal is empty or translucent, allowing
-// the PVS calculation to see through it.
-// The nodes on either side of the portal may actually be clusters,
-// not leaves, so all contents should be ored together
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-qboolean Portal_VisFlood (portal_t *p)
-{
- int c1, c2;
-
- if (!p->onnode)
- return false; // to global outsideleaf
-
- c1 = ClusterContents(p->nodes[0]);
- c2 = ClusterContents(p->nodes[1]);
-
- if (!VisibleContents (c1^c2))
- return true;
-
- if (c1 & (CONTENTS_Q2TRANSLUCENT|CONTENTS_DETAIL))
- c1 = 0;
- if (c2 & (CONTENTS_Q2TRANSLUCENT|CONTENTS_DETAIL))
- c2 = 0;
-
- if ( (c1|c2) & CONTENTS_SOLID )
- return false; // can't see through solid
-
- if (! (c1 ^ c2))
- return true; // identical on both sides
-
- if (!VisibleContents (c1^c2))
- return true;
- return false;
-} //end of the function Portal_VisFlood
-//===========================================================================
-// The entity flood determines which areas are
-// "outside" on the map, which are then filled in.
-// Flowing from side s to side !s
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-qboolean Portal_EntityFlood (portal_t *p, int s)
-{
- if (p->nodes[0]->planenum != PLANENUM_LEAF
- || p->nodes[1]->planenum != PLANENUM_LEAF)
- Error ("Portal_EntityFlood: not a leaf");
-
- // can never cross to a solid
- if ( (p->nodes[0]->contents & CONTENTS_SOLID)
- || (p->nodes[1]->contents & CONTENTS_SOLID) )
- return false;
-
- // can flood through everything else
- return true;
-}
-
-
-//=============================================================================
-
-int c_tinyportals;
-
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AddPortalToNodes (portal_t *p, node_t *front, node_t *back)
-{
- if (p->nodes[0] || p->nodes[1])
- Error ("AddPortalToNode: allready included");
-
- p->nodes[0] = front;
- p->next[0] = front->portals;
- front->portals = p;
-
- p->nodes[1] = back;
- p->next[1] = back->portals;
- back->portals = p;
-} //end of the function AddPortalToNodes
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void RemovePortalFromNode (portal_t *portal, node_t *l)
-{
- portal_t **pp, *t;
-
- int s, i, n;
- portal_t *p;
- portal_t *portals[4096];
-
-// remove reference to the current portal
- pp = &l->portals;
- while (1)
- {
- t = *pp;
- if (!t)
- Error ("RemovePortalFromNode: portal not in leaf");
-
- if ( t == portal )
- break;
-
- if (t->nodes[0] == l)
- pp = &t->next[0];
- else if (t->nodes[1] == l)
- pp = &t->next[1];
- else
- Error ("RemovePortalFromNode: portal not bounding leaf");
- }
-
- if (portal->nodes[0] == l)
- {
- *pp = portal->next[0];
- portal->nodes[0] = NULL;
- } //end if
- else if (portal->nodes[1] == l)
- {
- *pp = portal->next[1];
- portal->nodes[1] = NULL;
- } //end else if
- else
- {
- Error("RemovePortalFromNode: mislinked portal");
- } //end else
-//#ifdef ME
- n = 0;
- for (p = l->portals; p; p = p->next[s])
- {
- for (i = 0; i < n; i++)
- {
- if (p == portals[i]) Error("RemovePortalFromNode: circular linked\n");
- } //end for
- if (p->nodes[0] != l && p->nodes[1] != l)
- {
- Error("RemovePortalFromNodes: portal does not belong to node\n");
- } //end if
- portals[n] = p;
- s = (p->nodes[1] == l);
-// if (++n >= 4096) Error("RemovePortalFromNode: more than 4096 portals\n");
- } //end for
-//#endif
-} //end of the function RemovePortalFromNode
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void PrintPortal (portal_t *p)
-{
- int i;
- winding_t *w;
-
- w = p->winding;
- for (i=0 ; i<w->numpoints ; i++)
- printf ("(%5.0f,%5.0f,%5.0f)\n",w->p[i][0]
- , w->p[i][1], w->p[i][2]);
-} //end of the function PrintPortal
-//===========================================================================
-// The created portals will face the global outside_node
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-#define SIDESPACE 8
-
-void MakeHeadnodePortals (tree_t *tree)
-{
- vec3_t bounds[2];
- int i, j, n;
- portal_t *p, *portals[6];
- plane_t bplanes[6], *pl;
- node_t *node;
-
- node = tree->headnode;
-
-// pad with some space so there will never be null volume leaves
- for (i=0 ; i<3 ; i++)
- {
- bounds[0][i] = tree->mins[i] - SIDESPACE;
- bounds[1][i] = tree->maxs[i] + SIDESPACE;
- if ( bounds[0][i] > bounds[1][i] ) {
- Error("empty BSP tree");
- }
- }
-
- tree->outside_node.planenum = PLANENUM_LEAF;
- tree->outside_node.brushlist = NULL;
- tree->outside_node.portals = NULL;
- tree->outside_node.contents = 0;
-
- for (i=0 ; i<3 ; i++)
- for (j=0 ; j<2 ; j++)
- {
- n = j*3 + i;
-
- p = AllocPortal ();
- portals[n] = p;
-
- pl = &bplanes[n];
- memset (pl, 0, sizeof(*pl));
- if (j)
- {
- pl->normal[i] = -1;
- pl->dist = -bounds[j][i];
- }
- else
- {
- pl->normal[i] = 1;
- pl->dist = bounds[j][i];
- }
- p->plane = *pl;
- p->winding = BaseWindingForPlane (pl->normal, pl->dist);
- AddPortalToNodes (p, node, &tree->outside_node);
- }
-
-// clip the basewindings by all the other planes
- for (i=0 ; i<6 ; i++)
- {
- for (j=0 ; j<6 ; j++)
- {
- if (j == i) continue;
- ChopWindingInPlace (&portals[i]->winding, bplanes[j].normal, bplanes[j].dist, ON_EPSILON);
- } //end for
- } //end for
-} //end of the function MakeHeadNodePortals
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-#define BASE_WINDING_EPSILON 0.001
-#define SPLIT_WINDING_EPSILON 0.001
-
-winding_t *BaseWindingForNode (node_t *node)
-{
- winding_t *w;
- node_t *n;
- plane_t *plane;
- vec3_t normal;
- vec_t dist;
-
- w = BaseWindingForPlane (mapplanes[node->planenum].normal
- , mapplanes[node->planenum].dist);
-
- // clip by all the parents
- for (n=node->parent ; n && w ; )
- {
- plane = &mapplanes[n->planenum];
-
- if (n->children[0] == node)
- { // take front
- ChopWindingInPlace (&w, plane->normal, plane->dist, BASE_WINDING_EPSILON);
- }
- else
- { // take back
- VectorSubtract (vec3_origin, plane->normal, normal);
- dist = -plane->dist;
- ChopWindingInPlace (&w, normal, dist, BASE_WINDING_EPSILON);
- }
- node = n;
- n = n->parent;
- }
-
- return w;
-} //end of the function BaseWindingForNode
-//===========================================================================
-// create the new portal by taking the full plane winding for the cutting
-// plane and clipping it by all of parents of this node
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-qboolean WindingIsTiny (winding_t *w);
-
-void MakeNodePortal (node_t *node)
-{
- portal_t *new_portal, *p;
- winding_t *w;
- vec3_t normal;
- float dist;
- int side;
-
- w = BaseWindingForNode (node);
-
- // clip the portal by all the other portals in the node
- for (p = node->portals; p && w; p = p->next[side])
- {
- if (p->nodes[0] == node)
- {
- side = 0;
- VectorCopy (p->plane.normal, normal);
- dist = p->plane.dist;
- } //end if
- else if (p->nodes[1] == node)
- {
- side = 1;
- VectorSubtract (vec3_origin, p->plane.normal, normal);
- dist = -p->plane.dist;
- } //end else if
- else
- {
- Error ("MakeNodePortal: mislinked portal");
- } //end else
- ChopWindingInPlace (&w, normal, dist, 0.1);
- } //end for
-
- if (!w)
- {
- return;
- } //end if
-
- if (WindingIsTiny (w))
- {
- c_tinyportals++;
- FreeWinding(w);
- return;
- } //end if
-
-#ifdef DEBUG
-/* //NOTE: don't use this winding ok check
- // all the invalid windings only have a degenerate edge
- if (WindingError(w))
- {
- Log_Print("MakeNodePortal: %s\n", WindingErrorString());
- FreeWinding(w);
- return;
- } //end if*/
-#endif //DEBUG
-
-
- new_portal = AllocPortal();
- new_portal->plane = mapplanes[node->planenum];
-
-#ifdef ME
- new_portal->planenum = node->planenum;
-#endif //ME
-
- new_portal->onnode = node;
- new_portal->winding = w;
- AddPortalToNodes (new_portal, node->children[0], node->children[1]);
-} //end of the function MakeNodePortal
-//===========================================================================
-// Move or split the portals that bound node so that the node's
-// children have portals instead of node.
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void SplitNodePortals (node_t *node)
-{
- portal_t *p, *next_portal, *new_portal;
- node_t *f, *b, *other_node;
- int side;
- plane_t *plane;
- winding_t *frontwinding, *backwinding;
-
- plane = &mapplanes[node->planenum];
- f = node->children[0];
- b = node->children[1];
-
- for (p = node->portals ; p ; p = next_portal)
- {
- if (p->nodes[0] == node) side = 0;
- else if (p->nodes[1] == node) side = 1;
- else Error ("SplitNodePortals: mislinked portal");
- next_portal = p->next[side];
-
- other_node = p->nodes[!side];
- RemovePortalFromNode (p, p->nodes[0]);
- RemovePortalFromNode (p, p->nodes[1]);
-
-//
-// cut the portal into two portals, one on each side of the cut plane
-//
- ClipWindingEpsilon (p->winding, plane->normal, plane->dist,
- SPLIT_WINDING_EPSILON, &frontwinding, &backwinding);
-
- if (frontwinding && WindingIsTiny(frontwinding))
- {
- FreeWinding (frontwinding);
- frontwinding = NULL;
- c_tinyportals++;
- } //end if
-
- if (backwinding && WindingIsTiny(backwinding))
- {
- FreeWinding (backwinding);
- backwinding = NULL;
- c_tinyportals++;
- } //end if
-
-#ifdef DEBUG
-/* //NOTE: don't use this winding ok check
- // all the invalid windings only have a degenerate edge
- if (frontwinding && WindingError(frontwinding))
- {
- Log_Print("SplitNodePortals: front %s\n", WindingErrorString());
- FreeWinding(frontwinding);
- frontwinding = NULL;
- } //end if
- if (backwinding && WindingError(backwinding))
- {
- Log_Print("SplitNodePortals: back %s\n", WindingErrorString());
- FreeWinding(backwinding);
- backwinding = NULL;
- } //end if*/
-#endif //DEBUG
-
- if (!frontwinding && !backwinding)
- { // tiny windings on both sides
- continue;
- }
-
- if (!frontwinding)
- {
- FreeWinding (backwinding);
- if (side == 0) AddPortalToNodes (p, b, other_node);
- else AddPortalToNodes (p, other_node, b);
- continue;
- }
- if (!backwinding)
- {
- FreeWinding (frontwinding);
- if (side == 0) AddPortalToNodes (p, f, other_node);
- else AddPortalToNodes (p, other_node, f);
- continue;
- }
-
- // the winding is split
- new_portal = AllocPortal();
- *new_portal = *p;
- new_portal->winding = backwinding;
- FreeWinding (p->winding);
- p->winding = frontwinding;
-
- if (side == 0)
- {
- AddPortalToNodes (p, f, other_node);
- AddPortalToNodes (new_portal, b, other_node);
- } //end if
- else
- {
- AddPortalToNodes (p, other_node, f);
- AddPortalToNodes (new_portal, other_node, b);
- } //end else
- }
-
- node->portals = NULL;
-} //end of the function SplitNodePortals
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void CalcNodeBounds (node_t *node)
-{
- portal_t *p;
- int s;
- int i;
-
- // calc mins/maxs for both leaves and nodes
- ClearBounds (node->mins, node->maxs);
- for (p = node->portals ; p ; p = p->next[s])
- {
- s = (p->nodes[1] == node);
- for (i=0 ; i<p->winding->numpoints ; i++)
- AddPointToBounds (p->winding->p[i], node->mins, node->maxs);
- }
-} //end of the function CalcNodeBounds
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int c_numportalizednodes;
-
-void MakeTreePortals_r (node_t *node)
-{
- int i;
-
-#ifdef ME
- qprintf("\r%6d", ++c_numportalizednodes);
- if (cancelconversion) return;
-#endif //ME
-
- CalcNodeBounds (node);
- if (node->mins[0] >= node->maxs[0])
- {
- Log_Print("WARNING: node without a volume\n");
- }
-
- for (i=0 ; i<3 ; i++)
- {
- if (node->mins[i] < -MAX_MAP_BOUNDS || node->maxs[i] > MAX_MAP_BOUNDS)
- {
- Log_Print("WARNING: node with unbounded volume\n");
- break;
- }
- }
- if (node->planenum == PLANENUM_LEAF)
- return;
-
- MakeNodePortal (node);
- SplitNodePortals (node);
-
- MakeTreePortals_r (node->children[0]);
- MakeTreePortals_r (node->children[1]);
-} //end of the function MakeTreePortals_r
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void MakeTreePortals(tree_t *tree)
-{
-
-#ifdef ME
- Log_Print("---- Node Portalization ----\n");
- c_numportalizednodes = 0;
- c_portalmemory = 0;
- qprintf("%6d nodes portalized", c_numportalizednodes);
-#endif //ME
-
- MakeHeadnodePortals(tree);
- MakeTreePortals_r(tree->headnode);
-
-#ifdef ME
- qprintf("\n");
- Log_Write("%6d nodes portalized\r\n", c_numportalizednodes);
- Log_Print("%6d tiny portals\r\n", c_tinyportals);
- Log_Print("%6d KB of portal memory\r\n", c_portalmemory >> 10);
- Log_Print("%6i KB of winding memory\r\n", WindingMemory() >> 10);
-#endif //ME
-} //end of the function MakeTreePortals
-
-/*
-=========================================================
-
-FLOOD ENTITIES
-
-=========================================================
-*/
-//#define P_NODESTACK
-
-node_t *p_firstnode;
-node_t *p_lastnode;
-
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-#ifdef P_NODESTACK
-void P_AddNodeToList(node_t *node)
-{
- node->next = p_firstnode;
- p_firstnode = node;
- if (!p_lastnode) p_lastnode = node;
-} //end of the function P_AddNodeToList
-#else //it's a node queue
-//add the node to the end of the node list
-void P_AddNodeToList(node_t *node)
-{
- node->next = NULL;
- if (p_lastnode) p_lastnode->next = node;
- else p_firstnode = node;
- p_lastnode = node;
-} //end of the function P_AddNodeToList
-#endif //P_NODESTACK
-//===========================================================================
-// get the first node from the front of the node list
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-node_t *P_NextNodeFromList(void)
-{
- node_t *node;
-
- node = p_firstnode;
- if (p_firstnode) p_firstnode = p_firstnode->next;
- if (!p_firstnode) p_lastnode = NULL;
- return node;
-} //end of the function P_NextNodeFromList
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void FloodPortals(node_t *firstnode)
-{
- node_t *node;
- portal_t *p;
- int s;
-
- firstnode->occupied = 1;
- P_AddNodeToList(firstnode);
-
- for (node = P_NextNodeFromList(); node; node = P_NextNodeFromList())
- {
- for (p = node->portals; p; p = p->next[s])
- {
- s = (p->nodes[1] == node);
- //if the node at the other side of the portal is occupied already
- if (p->nodes[!s]->occupied) continue;
- //if it isn't possible to flood through this portal
- if (!Portal_EntityFlood(p, s)) continue;
- //
- p->nodes[!s]->occupied = node->occupied + 1;
- //
- P_AddNodeToList(p->nodes[!s]);
- } //end for
- } //end for
-} //end of the function FloodPortals
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int numrec;
-
-void FloodPortals_r (node_t *node, int dist)
-{
- portal_t *p;
- int s;
-// int i;
-
- Log_Print("\r%6d", ++numrec);
-
- if (node->occupied) Error("FloodPortals_r: node already occupied\n");
- if (!node)
- {
- Error("FloodPortals_r: NULL node\n");
- } //end if*/
- node->occupied = dist;
-
- for (p = node->portals; p; p = p->next[s])
- {
- s = (p->nodes[1] == node);
- //if the node at the other side of the portal is occupied already
- if (p->nodes[!s]->occupied) continue;
- //if it isn't possible to flood through this portal
- if (!Portal_EntityFlood(p, s)) continue;
- //flood recursively through the current portal
- FloodPortals_r(p->nodes[!s], dist+1);
- } //end for
- Log_Print("\r%6d", --numrec);
-} //end of the function FloodPortals_r
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-qboolean PlaceOccupant (node_t *headnode, vec3_t origin, entity_t *occupant)
-{
- node_t *node;
- vec_t d;
- plane_t *plane;
-
- //find the leaf to start in
- node = headnode;
- while(node->planenum != PLANENUM_LEAF)
- {
- if (node->planenum < 0 || node->planenum > nummapplanes)
- {
- Error("PlaceOccupant: invalid node->planenum\n");
- } //end if
- plane = &mapplanes[node->planenum];
- d = DotProduct(origin, plane->normal) - plane->dist;
- if (d >= 0) node = node->children[0];
- else node = node->children[1];
- if (!node)
- {
- Error("PlaceOccupant: invalid child %d\n", d < 0);
- } //end if
- } //end while
- //don't start in solid
-// if (node->contents == CONTENTS_SOLID)
- //ME: replaced because in LeafNode in brushbsp.c
- // some nodes have contents solid with other contents
- if (node->contents & CONTENTS_SOLID) return false;
- //if the node is already occupied
- if (node->occupied) return false;
-
- //place the occupant in the first leaf
- node->occupant = occupant;
-
- numrec = 0;
-// Log_Print("%6d recurses", numrec);
-// FloodPortals_r(node, 1);
-// Log_Print("\n");
- FloodPortals(node);
-
- return true;
-} //end of the function PlaceOccupant
-//===========================================================================
-// Marks all nodes that can be reached by entites
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-qboolean FloodEntities (tree_t *tree)
-{
- int i;
- int x, y;
- vec3_t origin;
- char *cl;
- qboolean inside;
- node_t *headnode;
-
- headnode = tree->headnode;
- Log_Print("------ FloodEntities -------\n");
- inside = false;
- tree->outside_node.occupied = 0;
-
- //start at entity 1 not the world ( = 0)
- for (i = 1; i < num_entities; i++)
- {
- GetVectorForKey(&entities[i], "origin", origin);
- if (VectorCompare(origin, vec3_origin)) continue;
-
- cl = ValueForKey(&entities[i], "classname");
- origin[2] += 1; //so objects on floor are ok
-
-// Log_Print("flooding from entity %d: %s\n", i, cl);
- //nudge playerstart around if needed so clipping hulls allways
- //have a valid point
- if (!strcmp(cl, "info_player_start"))
- {
- for (x = -16; x <= 16; x += 16)
- {
- for (y = -16; y <= 16; y += 16)
- {
- origin[0] += x;
- origin[1] += y;
- if (PlaceOccupant(headnode, origin, &entities[i]))
- {
- inside = true;
- x = 999; //stop for this info_player_start
- break;
- } //end if
- origin[0] -= x;
- origin[1] -= y;
- } //end for
- } //end for
- } //end if
- else
- {
- if (PlaceOccupant(headnode, origin, &entities[i]))
- {
- inside = true;
- } //end if
- } //end else
- } //end for
-
- if (!inside)
- {
- Log_Print("WARNING: no entities inside\n");
- } //end if
- else if (tree->outside_node.occupied)
- {
- Log_Print("WARNING: entity reached from outside\n");
- } //end else if
-
- return (qboolean)(inside && !tree->outside_node.occupied);
-} //end of the function FloodEntities
-
-/*
-=========================================================
-
-FILL OUTSIDE
-
-=========================================================
-*/
-
-int c_outside;
-int c_inside;
-int c_solid;
-
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void FillOutside_r (node_t *node)
-{
- if (node->planenum != PLANENUM_LEAF)
- {
- FillOutside_r (node->children[0]);
- FillOutside_r (node->children[1]);
- return;
- } //end if
- // anything not reachable by an entity
- // can be filled away (by setting solid contents)
- if (!node->occupied)
- {
- if (!(node->contents & CONTENTS_SOLID))
- {
- c_outside++;
- node->contents |= CONTENTS_SOLID;
- } //end if
- else
- {
- c_solid++;
- } //end else
- } //end if
- else
- {
- c_inside++;
- } //end else
-} //end of the function FillOutside_r
-//===========================================================================
-// Fill all nodes that can't be reached by entities
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void FillOutside (node_t *headnode)
-{
- c_outside = 0;
- c_inside = 0;
- c_solid = 0;
- Log_Print("------- FillOutside --------\n");
- FillOutside_r (headnode);
- Log_Print("%5i solid leaves\n", c_solid);
- Log_Print("%5i leaves filled\n", c_outside);
- Log_Print("%5i inside leaves\n", c_inside);
-} //end of the function FillOutside
-
-/*
-=========================================================
-
-FLOOD AREAS
-
-=========================================================
-*/
-
-int c_areas;
-
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void FloodAreas_r (node_t *node)
-{
- portal_t *p;
- int s;
- bspbrush_t *b;
- entity_t *e;
-
- if (node->contents == CONTENTS_AREAPORTAL)
- {
- // this node is part of an area portal
- b = node->brushlist;
- e = &entities[b->original->entitynum];
-
- // if the current area has allready touched this
- // portal, we are done
- if (e->portalareas[0] == c_areas || e->portalareas[1] == c_areas)
- return;
-
- // note the current area as bounding the portal
- if (e->portalareas[1])
- {
- Log_Print("WARNING: areaportal entity %i touches > 2 areas\n", b->original->entitynum);
- return;
- }
- if (e->portalareas[0])
- e->portalareas[1] = c_areas;
- else
- e->portalareas[0] = c_areas;
-
- return;
- } //end if
-
- if (node->area)
- return; // allready got it
- node->area = c_areas;
-
- for (p=node->portals ; p ; p = p->next[s])
- {
- s = (p->nodes[1] == node);
-#if 0
- if (p->nodes[!s]->occupied)
- continue;
-#endif
- if (!Portal_EntityFlood (p, s))
- continue;
-
- FloodAreas_r (p->nodes[!s]);
- } //end for
-} //end of the function FloodAreas_r
-//===========================================================================
-// Just decend the tree, and for each node that hasn't had an
-// area set, flood fill out from there
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void FindAreas_r (node_t *node)
-{
- if (node->planenum != PLANENUM_LEAF)
- {
- FindAreas_r (node->children[0]);
- FindAreas_r (node->children[1]);
- return;
- }
-
- if (node->area)
- return; // allready got it
-
- if (node->contents & CONTENTS_SOLID)
- return;
-
- if (!node->occupied)
- return; // not reachable by entities
-
- // area portals are allways only flooded into, never
- // out of
- if (node->contents == CONTENTS_AREAPORTAL)
- return;
-
- c_areas++;
- FloodAreas_r (node);
-} //end of the function FindAreas_r
-//===========================================================================
-// Just decend the tree, and for each node that hasn't had an
-// area set, flood fill out from there
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void SetAreaPortalAreas_r (node_t *node)
-{
- bspbrush_t *b;
- entity_t *e;
-
- if (node->planenum != PLANENUM_LEAF)
- {
- SetAreaPortalAreas_r (node->children[0]);
- SetAreaPortalAreas_r (node->children[1]);
- return;
- } //end if
-
- if (node->contents == CONTENTS_AREAPORTAL)
- {
- if (node->area)
- return; // allready set
-
- b = node->brushlist;
- e = &entities[b->original->entitynum];
- node->area = e->portalareas[0];
- if (!e->portalareas[1])
- {
- Log_Print("WARNING: areaportal entity %i doesn't touch two areas\n", b->original->entitynum);
- return;
- } //end if
- } //end if
-} //end of the function SetAreaPortalAreas_r
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-/*
-void EmitAreaPortals(node_t *headnode)
-{
- int i, j;
- entity_t *e;
- dareaportal_t *dp;
-
- if (c_areas > MAX_MAP_AREAS)
- Error ("MAX_MAP_AREAS");
- numareas = c_areas+1;
- numareaportals = 1; // leave 0 as an error
-
- for (i=1 ; i<=c_areas ; i++)
- {
- dareas[i].firstareaportal = numareaportals;
- for (j=0 ; j<num_entities ; j++)
- {
- e = &entities[j];
- if (!e->areaportalnum)
- continue;
- dp = &dareaportals[numareaportals];
- if (e->portalareas[0] == i)
- {
- dp->portalnum = e->areaportalnum;
- dp->otherarea = e->portalareas[1];
- numareaportals++;
- } //end if
- else if (e->portalareas[1] == i)
- {
- dp->portalnum = e->areaportalnum;
- dp->otherarea = e->portalareas[0];
- numareaportals++;
- } //end else if
- } //end for
- dareas[i].numareaportals = numareaportals - dareas[i].firstareaportal;
- } //end for
-
- Log_Print("%5i numareas\n", numareas);
- Log_Print("%5i numareaportals\n", numareaportals);
-} //end of the function EmitAreaPortals
-*/
-//===========================================================================
-// Mark each leaf with an area, bounded by CONTENTS_AREAPORTAL
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void FloodAreas (tree_t *tree)
-{
- Log_Print("--- FloodAreas ---\n");
- FindAreas_r (tree->headnode);
- SetAreaPortalAreas_r (tree->headnode);
- Log_Print("%5i areas\n", c_areas);
-} //end of the function FloodAreas
-//===========================================================================
-// Finds a brush side to use for texturing the given portal
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void FindPortalSide (portal_t *p)
-{
- int viscontents;
- bspbrush_t *bb;
- mapbrush_t *brush;
- node_t *n;
- int i,j;
- int planenum;
- side_t *side, *bestside;
- float dot, bestdot;
- plane_t *p1, *p2;
-
- // decide which content change is strongest
- // solid > lava > water, etc
- viscontents = VisibleContents (p->nodes[0]->contents ^ p->nodes[1]->contents);
- if (!viscontents)
- return;
-
- planenum = p->onnode->planenum;
- bestside = NULL;
- bestdot = 0;
-
- for (j=0 ; j<2 ; j++)
- {
- n = p->nodes[j];
- p1 = &mapplanes[p->onnode->planenum];
- for (bb=n->brushlist ; bb ; bb=bb->next)
- {
- brush = bb->original;
- if ( !(brush->contents & viscontents) )
- continue;
- for (i=0 ; i<brush->numsides ; i++)
- {
- side = &brush->original_sides[i];
- if (side->flags & SFL_BEVEL)
- continue;
- if (side->texinfo == TEXINFO_NODE)
- continue; // non-visible
- if ((side->planenum&~1) == planenum)
- { // exact match
- bestside = &brush->original_sides[i];
- goto gotit;
- } //end if
- // see how close the match is
- p2 = &mapplanes[side->planenum&~1];
- dot = DotProduct (p1->normal, p2->normal);
- if (dot > bestdot)
- {
- bestdot = dot;
- bestside = side;
- } //end if
- } //end for
- } //end for
- } //end for
-
-gotit:
- if (!bestside)
- Log_Print("WARNING: side not found for portal\n");
-
- p->sidefound = true;
- p->side = bestside;
-} //end of the function FindPortalSide
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void MarkVisibleSides_r (node_t *node)
-{
- portal_t *p;
- int s;
-
- if (node->planenum != PLANENUM_LEAF)
- {
- MarkVisibleSides_r (node->children[0]);
- MarkVisibleSides_r (node->children[1]);
- return;
- } //end if
-
- // empty leaves are never boundary leaves
- if (!node->contents) return;
-
- // see if there is a visible face
- for (p=node->portals ; p ; p = p->next[!s])
- {
- s = (p->nodes[0] == node);
- if (!p->onnode)
- continue; // edge of world
- if (!p->sidefound)
- FindPortalSide (p);
- if (p->side)
- p->side->flags |= SFL_VISIBLE;
- } //end for
-} //end of the function MarkVisibleSides_r
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void MarkVisibleSides(tree_t *tree, int startbrush, int endbrush)
-{
- int i, j;
- mapbrush_t *mb;
- int numsides;
-
- Log_Print("--- MarkVisibleSides ---\n");
-
- // clear all the visible flags
- for (i=startbrush ; i<endbrush ; i++)
- {
- mb = &mapbrushes[i];
-
- numsides = mb->numsides;
- for (j=0 ; j<numsides ; j++)
- mb->original_sides[j].flags &= ~SFL_VISIBLE;
- }
-
- // set visible flags on the sides that are used by portals
- MarkVisibleSides_r (tree->headnode);
-} //end of the function MarkVisibleSides
-
diff --git a/code/bspc/prtfile.c b/code/bspc/prtfile.c
deleted file mode 100644
index 9754ba7..0000000
--- a/code/bspc/prtfile.c
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-#include "qbsp.h"
-
-/*
-==============================================================================
-
-PORTAL FILE GENERATION
-
-Save out name.prt for qvis to read
-==============================================================================
-*/
-
-
-#define PORTALFILE "PRT1"
-
-FILE *pf;
-int num_visclusters; // clusters the player can be in
-int num_visportals;
-
-void WriteFloat2 (FILE *f, vec_t v)
-{
- if ( fabs(v - Q_rint(v)) < 0.001 )
- fprintf (f,"%i ",(int)Q_rint(v));
- else
- fprintf (f,"%f ",v);
-}
-
-/*
-=================
-WritePortalFile_r
-=================
-*/
-void WritePortalFile_r (node_t *node)
-{
- int i, s;
- portal_t *p;
- winding_t *w;
- vec3_t normal;
- vec_t dist;
-
- // decision node
- if (node->planenum != PLANENUM_LEAF && !node->detail_seperator)
- {
- WritePortalFile_r (node->children[0]);
- WritePortalFile_r (node->children[1]);
- return;
- }
-
- if (node->contents & CONTENTS_SOLID)
- return;
-
- for (p = node->portals ; p ; p=p->next[s])
- {
- w = p->winding;
- s = (p->nodes[1] == node);
- if (w && p->nodes[0] == node)
- {
- if (!Portal_VisFlood (p))
- continue;
- // write out to the file
-
- // sometimes planes get turned around when they are very near
- // the changeover point between different axis. interpret the
- // plane the same way vis will, and flip the side orders if needed
- // FIXME: is this still relevent?
- WindingPlane (w, normal, &dist);
- if ( DotProduct (p->plane.normal, normal) < 0.99 )
- { // backwards...
- fprintf (pf,"%i %i %i ",w->numpoints, p->nodes[1]->cluster, p->nodes[0]->cluster);
- }
- else
- fprintf (pf,"%i %i %i ",w->numpoints, p->nodes[0]->cluster, p->nodes[1]->cluster);
- for (i=0 ; i<w->numpoints ; i++)
- {
- fprintf (pf,"(");
- WriteFloat2 (pf, w->p[i][0]);
- WriteFloat2 (pf, w->p[i][1]);
- WriteFloat2 (pf, w->p[i][2]);
- fprintf (pf,") ");
- }
- fprintf (pf,"\n");
- }
- }
-
-}
-
-/*
-================
-FillLeafNumbers_r
-
-All of the leafs under node will have the same cluster
-================
-*/
-void FillLeafNumbers_r (node_t *node, int num)
-{
- if (node->planenum == PLANENUM_LEAF)
- {
- if (node->contents & CONTENTS_SOLID)
- node->cluster = -1;
- else
- node->cluster = num;
- return;
- }
- node->cluster = num;
- FillLeafNumbers_r (node->children[0], num);
- FillLeafNumbers_r (node->children[1], num);
-}
-
-/*
-================
-NumberLeafs_r
-================
-*/
-void NumberLeafs_r (node_t *node)
-{
- portal_t *p;
-
- if (node->planenum != PLANENUM_LEAF && !node->detail_seperator)
- { // decision node
- node->cluster = -99;
- NumberLeafs_r (node->children[0]);
- NumberLeafs_r (node->children[1]);
- return;
- }
-
- // either a leaf or a detail cluster
-
- if ( node->contents & CONTENTS_SOLID )
- { // solid block, viewpoint never inside
- node->cluster = -1;
- return;
- }
-
- FillLeafNumbers_r (node, num_visclusters);
- num_visclusters++;
-
- // count the portals
- for (p = node->portals ; p ; )
- {
- if (p->nodes[0] == node) // only write out from first leaf
- {
- if (Portal_VisFlood (p))
- num_visportals++;
- p = p->next[0];
- }
- else
- p = p->next[1];
- }
-
-}
-
-
-/*
-================
-CreateVisPortals_r
-================
-*/
-void CreateVisPortals_r (node_t *node)
-{
- // stop as soon as we get to a detail_seperator, which
- // means that everything below is in a single cluster
- if (node->planenum == PLANENUM_LEAF || node->detail_seperator )
- return;
-
- MakeNodePortal (node);
- SplitNodePortals (node);
-
- CreateVisPortals_r (node->children[0]);
- CreateVisPortals_r (node->children[1]);
-}
-
-/*
-================
-FinishVisPortals_r
-================
-*/
-void FinishVisPortals2_r (node_t *node)
-{
- if (node->planenum == PLANENUM_LEAF)
- return;
-
- MakeNodePortal (node);
- SplitNodePortals (node);
-
- FinishVisPortals2_r (node->children[0]);
- FinishVisPortals2_r (node->children[1]);
-}
-
-void FinishVisPortals_r (node_t *node)
-{
- if (node->planenum == PLANENUM_LEAF)
- return;
-
- if (node->detail_seperator)
- {
- FinishVisPortals2_r (node);
- return;
- }
-
- FinishVisPortals_r (node->children[0]);
- FinishVisPortals_r (node->children[1]);
-}
-
-
-int clusterleaf;
-void SaveClusters_r (node_t *node)
-{
- if (node->planenum == PLANENUM_LEAF)
- {
- dleafs[clusterleaf++].cluster = node->cluster;
- return;
- }
- SaveClusters_r (node->children[0]);
- SaveClusters_r (node->children[1]);
-}
-
-/*
-================
-WritePortalFile
-================
-*/
-void WritePortalFile (tree_t *tree)
-{
- char filename[1024];
- node_t *headnode;
-
- qprintf ("--- WritePortalFile ---\n");
-
- headnode = tree->headnode;
- num_visclusters = 0;
- num_visportals = 0;
-
- Tree_FreePortals_r (headnode);
-
- MakeHeadnodePortals (tree);
-
- CreateVisPortals_r (headnode);
-
-// set the cluster field in every leaf and count the total number of portals
-
- NumberLeafs_r (headnode);
-
-// write the file
- sprintf (filename, "%s.prt", source);
- printf ("writing %s\n", filename);
- pf = fopen (filename, "w");
- if (!pf)
- Error ("Error opening %s", filename);
-
- fprintf (pf, "%s\n", PORTALFILE);
- fprintf (pf, "%i\n", num_visclusters);
- fprintf (pf, "%i\n", num_visportals);
-
- qprintf ("%5i visclusters\n", num_visclusters);
- qprintf ("%5i visportals\n", num_visportals);
-
- WritePortalFile_r (headnode);
-
- fclose (pf);
-
- // we need to store the clusters out now because ordering
- // issues made us do this after writebsp...
- clusterleaf = 1;
- SaveClusters_r (headnode);
-}
-
diff --git a/code/bspc/q2files.h b/code/bspc/q2files.h
deleted file mode 100644
index b987f85..0000000
--- a/code/bspc/q2files.h
+++ /dev/null
@@ -1,487 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-//
-// qfiles.h: quake file formats
-// This file must be identical in the quake and utils directories
-//
-
-/*
-========================================================================
-
-The .pak files are just a linear collapse of a directory tree
-
-========================================================================
-*/
-
-#define IDPAKHEADER (('K'<<24)+('C'<<16)+('A'<<8)+'P')
-
-typedef struct
-{
- char name[56];
- int filepos, filelen;
-} dpackfile_t;
-
-typedef struct
-{
- int ident; // == IDPAKHEADER
- int dirofs;
- int dirlen;
-} dpackheader_t;
-
-#define MAX_FILES_IN_PACK 4096
-
-
-/*
-========================================================================
-
-PCX files are used for as many images as possible
-
-========================================================================
-*/
-
-typedef struct
-{
- char manufacturer;
- char version;
- char encoding;
- char bits_per_pixel;
- unsigned short xmin,ymin,xmax,ymax;
- unsigned short hres,vres;
- unsigned char palette[48];
- char reserved;
- char color_planes;
- unsigned short bytes_per_line;
- unsigned short palette_type;
- char filler[58];
- unsigned char data; // unbounded
-} pcx_t;
-
-
-/*
-========================================================================
-
-.MD2 triangle model file format
-
-========================================================================
-*/
-
-#define IDALIASHEADER (('2'<<24)+('P'<<16)+('D'<<8)+'I')
-#define ALIAS_VERSION 8
-
-#define MAX_TRIANGLES 4096
-#define MAX_VERTS 2048
-#define MAX_FRAMES 512
-#define MAX_MD2SKINS 32
-#define MAX_SKINNAME 64
-
-typedef struct
-{
- short s;
- short t;
-} dstvert_t;
-
-typedef struct
-{
- short index_xyz[3];
- short index_st[3];
-} dtriangle_t;
-
-typedef struct
-{
- byte v[3]; // scaled byte to fit in frame mins/maxs
- byte lightnormalindex;
-} dtrivertx_t;
-
-#define DTRIVERTX_V0 0
-#define DTRIVERTX_V1 1
-#define DTRIVERTX_V2 2
-#define DTRIVERTX_LNI 3
-#define DTRIVERTX_SIZE 4
-
-typedef struct
-{
- float scale[3]; // multiply byte verts by this
- float translate[3]; // then add this
- char name[16]; // frame name from grabbing
- dtrivertx_t verts[1]; // variable sized
-} daliasframe_t;
-
-
-// the glcmd format:
-// a positive integer starts a tristrip command, followed by that many
-// vertex structures.
-// a negative integer starts a trifan command, followed by -x vertexes
-// a zero indicates the end of the command list.
-// a vertex consists of a floating point s, a floating point t,
-// and an integer vertex index.
-
-
-typedef struct
-{
- int ident;
- int version;
-
- int skinwidth;
- int skinheight;
- int framesize; // byte size of each frame
-
- int num_skins;
- int num_xyz;
- int num_st; // greater than num_xyz for seams
- int num_tris;
- int num_glcmds; // dwords in strip/fan command list
- int num_frames;
-
- int ofs_skins; // each skin is a MAX_SKINNAME string
- int ofs_st; // byte offset from start for stverts
- int ofs_tris; // offset for dtriangles
- int ofs_frames; // offset for first frame
- int ofs_glcmds;
- int ofs_end; // end of file
-
-} dmdl_t;
-
-/*
-========================================================================
-
-.SP2 sprite file format
-
-========================================================================
-*/
-
-#define IDSPRITEHEADER (('2'<<24)+('S'<<16)+('D'<<8)+'I')
- // little-endian "IDS2"
-#define SPRITE_VERSION 2
-
-typedef struct
-{
- int width, height;
- int origin_x, origin_y; // raster coordinates inside pic
- char name[MAX_SKINNAME]; // name of pcx file
-} dsprframe_t;
-
-typedef struct {
- int ident;
- int version;
- int numframes;
- dsprframe_t frames[1]; // variable sized
-} dsprite_t;
-
-/*
-==============================================================================
-
- .WAL texture file format
-
-==============================================================================
-*/
-
-
-#define MIPLEVELS 4
-typedef struct miptex_s
-{
- char name[32];
- unsigned width, height;
- unsigned offsets[MIPLEVELS]; // four mip maps stored
- char animname[32]; // next frame in animation chain
- int flags;
- int contents;
- int value;
-} miptex_t;
-
-
-
-/*
-==============================================================================
-
- .BSP file format
-
-==============================================================================
-*/
-
-#define IDBSPHEADER (('P'<<24)+('S'<<16)+('B'<<8)+'I')
- // little-endian "IBSP"
-
-#define BSPVERSION 38
-
-
-// upper design bounds
-// leaffaces, leafbrushes, planes, and verts are still bounded by
-// 16 bit short limits
-#define MAX_MAP_MODELS 1024
-#define MAX_MAP_BRUSHES 8192
-#define MAX_MAP_ENTITIES 2048
-#define MAX_MAP_ENTSTRING 0x40000
-#define MAX_MAP_TEXINFO 8192
-
-#define MAX_MAP_AREAS 256
-#define MAX_MAP_AREAPORTALS 1024
-#define MAX_MAP_PLANES 65536
-#define MAX_MAP_NODES 65536
-#define MAX_MAP_BRUSHSIDES 65536
-#define MAX_MAP_LEAFS 65536
-#define MAX_MAP_VERTS 65536
-#define MAX_MAP_FACES 65536
-#define MAX_MAP_LEAFFACES 65536
-#define MAX_MAP_LEAFBRUSHES 65536
-#define MAX_MAP_PORTALS 65536
-#define MAX_MAP_EDGES 128000
-#define MAX_MAP_SURFEDGES 256000
-#define MAX_MAP_LIGHTING 0x320000
-#define MAX_MAP_VISIBILITY 0x280000
-
-// key / value pair sizes
-
-#define MAX_KEY 32
-#define MAX_VALUE 1024
-
-//=============================================================================
-
-typedef struct
-{
- int fileofs, filelen;
-} lump_t;
-
-#define LUMP_ENTITIES 0
-#define LUMP_PLANES 1
-#define LUMP_VERTEXES 2
-#define LUMP_VISIBILITY 3
-#define LUMP_NODES 4
-#define LUMP_TEXINFO 5
-#define LUMP_FACES 6
-#define LUMP_LIGHTING 7
-#define LUMP_LEAFS 8
-#define LUMP_LEAFFACES 9
-#define LUMP_LEAFBRUSHES 10
-#define LUMP_EDGES 11
-#define LUMP_SURFEDGES 12
-#define LUMP_MODELS 13
-#define LUMP_BRUSHES 14
-#define LUMP_BRUSHSIDES 15
-#define LUMP_POP 16
-#define LUMP_AREAS 17
-#define LUMP_AREAPORTALS 18
-#define HEADER_LUMPS 19
-
-typedef struct
-{
- int ident;
- int version;
- lump_t lumps[HEADER_LUMPS];
-} dheader_t;
-
-typedef struct
-{
- float mins[3], maxs[3];
- float origin[3]; // for sounds or lights
- int headnode;
- int firstface, numfaces; // submodels just draw faces
- // without walking the bsp tree
-} dmodel_t;
-
-
-typedef struct
-{
- float point[3];
-} dvertex_t;
-
-
-// 0-2 are axial planes
-#define PLANE_X 0
-#define PLANE_Y 1
-#define PLANE_Z 2
-
-// 3-5 are non-axial planes snapped to the nearest
-#define PLANE_ANYX 3
-#define PLANE_ANYY 4
-#define PLANE_ANYZ 5
-
-// planes (x&~1) and (x&~1)+1 are allways opposites
-
-typedef struct
-{
- float normal[3];
- float dist;
- int type; // PLANE_X - PLANE_ANYZ ?remove? trivial to regenerate
-} dplane_t;
-
-
-// contents flags are seperate bits
-// a given brush can contribute multiple content bits
-// multiple brushes can be in a single leaf
-
-// these definitions also need to be in q_shared.h!
-
-// lower bits are stronger, and will eat weaker brushes completely
-#define CONTENTS_SOLID 1 // an eye is never valid in a solid
-#define CONTENTS_WINDOW 2 // translucent, but not watery
-#define CONTENTS_AUX 4
-#define CONTENTS_LAVA 8
-#define CONTENTS_SLIME 16
-#define CONTENTS_WATER 32
-#define CONTENTS_MIST 64
-#define LAST_VISIBLE_CONTENTS 64
-
-// remaining contents are non-visible, and don't eat brushes
-
-#define CONTENTS_AREAPORTAL 0x8000
-
-#define CONTENTS_PLAYERCLIP 0x10000
-#define CONTENTS_MONSTERCLIP 0x20000
-
-// currents can be added to any other contents, and may be mixed
-#define CONTENTS_CURRENT_0 0x40000
-#define CONTENTS_CURRENT_90 0x80000
-#define CONTENTS_CURRENT_180 0x100000
-#define CONTENTS_CURRENT_270 0x200000
-#define CONTENTS_CURRENT_UP 0x400000
-#define CONTENTS_CURRENT_DOWN 0x800000
-
-#define CONTENTS_ORIGIN 0x1000000 // removed before bsping an entity
-
-#define CONTENTS_MONSTER 0x2000000 // should never be on a brush, only in game
-#define CONTENTS_DEADMONSTER 0x4000000
-#define CONTENTS_DETAIL 0x8000000 // brushes to be added after vis leafs
-//renamed because it's in conflict with the Q3A translucent contents
-#define CONTENTS_Q2TRANSLUCENT 0x10000000 // auto set if any surface has trans
-#define CONTENTS_LADDER 0x20000000
-
-
-
-#define SURF_LIGHT 0x1 // value will hold the light strength
-
-#define SURF_SLICK 0x2 // effects game physics
-
-#define SURF_SKY 0x4 // don't draw, but add to skybox
-#define SURF_WARP 0x8 // turbulent water warp
-#define SURF_TRANS33 0x10
-#define SURF_TRANS66 0x20
-#define SURF_FLOWING 0x40 // scroll towards angle
-#define SURF_NODRAW 0x80 // don't bother referencing the texture
-
-#define SURF_HINT 0x100 // make a primary bsp splitter
-#define SURF_SKIP 0x200 // completely ignore, allowing non-closed brushes
-
-
-
-typedef struct
-{
- int planenum;
- int children[2]; // negative numbers are -(leafs+1), not nodes
- short mins[3]; // for frustom culling
- short maxs[3];
- unsigned short firstface;
- unsigned short numfaces; // counting both sides
-} dnode_t;
-
-
-typedef struct texinfo_s
-{
- float vecs[2][4]; // [s/t][xyz offset]
- int flags; // miptex flags + overrides
- int value; // light emission, etc
- char texture[32]; // texture name (textures/*.wal)
- int nexttexinfo; // for animations, -1 = end of chain
-} texinfo_t;
-
-
-// note that edge 0 is never used, because negative edge nums are used for
-// counterclockwise use of the edge in a face
-typedef struct
-{
- unsigned short v[2]; // vertex numbers
-} dedge_t;
-
-#define MAXLIGHTMAPS 4
-typedef struct
-{
- unsigned short planenum;
- short side;
-
- int firstedge; // we must support > 64k edges
- short numedges;
- short texinfo;
-
-// lighting info
- byte styles[MAXLIGHTMAPS];
- int lightofs; // start of [numstyles*surfsize] samples
-} dface_t;
-
-typedef struct
-{
- int contents; // OR of all brushes (not needed?)
-
- short cluster;
- short area;
-
- short mins[3]; // for frustum culling
- short maxs[3];
-
- unsigned short firstleafface;
- unsigned short numleaffaces;
-
- unsigned short firstleafbrush;
- unsigned short numleafbrushes;
-} dleaf_t;
-
-typedef struct
-{
- unsigned short planenum; // facing out of the leaf
- short texinfo;
-} dbrushside_t;
-
-typedef struct
-{
- int firstside;
- int numsides;
- int contents;
-} dbrush_t;
-
-#define ANGLE_UP -1
-#define ANGLE_DOWN -2
-
-
-// the visibility lump consists of a header with a count, then
-// byte offsets for the PVS and PHS of each cluster, then the raw
-// compressed bit vectors
-#define DVIS_PVS 0
-#define DVIS_PHS 1
-typedef struct
-{
- int numclusters;
- int bitofs[8][2]; // bitofs[numclusters][2]
-} dvis_t;
-
-// each area has a list of portals that lead into other areas
-// when portals are closed, other areas may not be visible or
-// hearable even if the vis info says that it should be
-typedef struct
-{
- int portalnum;
- int otherarea;
-} dareaportal_t;
-
-typedef struct
-{
- int numareaportals;
- int firstareaportal;
-} darea_t;
diff --git a/code/bspc/q3files.h b/code/bspc/q3files.h
deleted file mode 100644
index ce2a3ad..0000000
--- a/code/bspc/q3files.h
+++ /dev/null
@@ -1,374 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-#ifndef __QFILES_H__
-#define __QFILES_H__
-
-//
-// qfiles.h: quake file formats
-// This file must be identical in the quake and utils directories
-//
-
-// surface geometry should not exceed these limits
-#define SHADER_MAX_VERTEXES 1000
-#define SHADER_MAX_INDEXES (6*SHADER_MAX_VERTEXES)
-
-
-// the maximum size of game reletive pathnames
-#define MAX_QPATH 64
-
-
-/*
-========================================================================
-
-PCX files are used for 8 bit images
-
-========================================================================
-*
-
-typedef struct {
- char manufacturer;
- char version;
- char encoding;
- char bits_per_pixel;
- unsigned short xmin,ymin,xmax,ymax;
- unsigned short hres,vres;
- unsigned char palette[48];
- char reserved;
- char color_planes;
- unsigned short bytes_per_line;
- unsigned short palette_type;
- char filler[58];
- unsigned char data; // unbounded
-} pcx_t;
-
-
-/*
-========================================================================
-
-TGA files are used for 24/32 bit images
-
-========================================================================
-*
-
-typedef struct _TargaHeader {
- unsigned char id_length, colormap_type, image_type;
- unsigned short colormap_index, colormap_length;
- unsigned char colormap_size;
- unsigned short x_origin, y_origin, width, height;
- unsigned char pixel_size, attributes;
-} TargaHeader;
-
-
-*/
-
-/*
-========================================================================
-
-.MD3 triangle model file format
-
-========================================================================
-*/
-
-#define MD3_IDENT (('3'<<24)+('P'<<16)+('D'<<8)+'I')
-#define MD3_VERSION 15
-
-// limits
-#define MD3_MAX_LODS 4
-#define MD3_MAX_TRIANGLES 8192 // per surface
-#define MD3_MAX_VERTS 4096 // per surface
-#define MD3_MAX_SHADERS 256 // per surface
-#define MD3_MAX_FRAMES 1024 // per model
-#define MD3_MAX_SURFACES 32 // per model
-#define MD3_MAX_TAGS 16 // per frame
-
-// vertex scales
-#define MD3_XYZ_SCALE (1.0/64)
-
-typedef struct md3Frame_s {
- vec3_t bounds[2];
- vec3_t localOrigin;
- float radius;
- char name[16];
-} md3Frame_t;
-
-typedef struct md3Tag_s {
- char name[MAX_QPATH]; // tag name
- vec3_t origin;
- vec3_t axis[3];
-} md3Tag_t;
-
-/*
-** md3Surface_t
-**
-** CHUNK SIZE
-** header sizeof( md3Surface_t )
-** shaders sizeof( md3Shader_t ) * numShaders
-** triangles[0] sizeof( md3Triangle_t ) * numTriangles
-** st sizeof( md3St_t ) * numVerts
-** XyzNormals sizeof( md3XyzNormal_t ) * numVerts * numFrames
-*/
-
-typedef struct {
- int ident; //
-
- char name[MAX_QPATH]; // polyset name
-
- int flags;
- int numFrames; // all surfaces in a model should have the same
-
- int numShaders; // all surfaces in a model should have the same
- int numVerts;
-
- int numTriangles;
- int ofsTriangles;
-
- int ofsShaders; // offset from start of md3Surface_t
- int ofsSt; // texture coords are common for all frames
- int ofsXyzNormals; // numVerts * numFrames
-
- int ofsEnd; // next surface follows
-} md3Surface_t;
-
-typedef struct {
- char name[MAX_QPATH];
- int shaderIndex; // for in-game use
-} md3Shader_t;
-
-typedef struct {
- int indexes[3];
-} md3Triangle_t;
-
-typedef struct {
- float st[2];
-} md3St_t;
-
-typedef struct {
- short xyz[3];
- short normal;
-} md3XyzNormal_t;
-
-typedef struct {
- int ident;
- int version;
-
- char name[MAX_QPATH]; // model name
-
- int flags;
-
- int numFrames;
- int numTags;
- int numSurfaces;
-
- int numSkins;
-
- int ofsFrames; // offset for first frame
- int ofsTags; // numFrames * numTags
- int ofsSurfaces; // first surface, others follow
-
- int ofsEnd; // end of file
-} md3Header_t;
-
-
-
-/*
-==============================================================================
-
- .BSP file format
-
-==============================================================================
-*/
-
-
-#define Q3_BSP_IDENT (('P'<<24)+('S'<<16)+('B'<<8)+'I')
- // little-endian "IBSP"
-
-#define Q3_BSP_VERSION 46
-
-
-// there shouldn't be any problem with increasing these values at the
-// expense of more memory allocation in the utilities
-#define Q3_MAX_MAP_MODELS 0x400
-#define Q3_MAX_MAP_BRUSHES 0x8000
-#define Q3_MAX_MAP_ENTITIES 0x800
-#define Q3_MAX_MAP_ENTSTRING 0x10000
-#define Q3_MAX_MAP_SHADERS 0x400
-
-#define Q3_MAX_MAP_AREAS 0x100 // MAX_MAP_AREA_BYTES in q_shared must match!
-#define Q3_MAX_MAP_FOGS 0x100
-#define Q3_MAX_MAP_PLANES 0x10000
-#define Q3_MAX_MAP_NODES 0x10000
-#define Q3_MAX_MAP_BRUSHSIDES 0x10000
-#define Q3_MAX_MAP_LEAFS 0x10000
-#define Q3_MAX_MAP_LEAFFACES 0x10000
-#define Q3_MAX_MAP_LEAFBRUSHES 0x10000
-#define Q3_MAX_MAP_PORTALS 0x10000
-#define Q3_MAX_MAP_LIGHTING 0x400000
-#define Q3_MAX_MAP_LIGHTGRID 0x400000
-#define Q3_MAX_MAP_VISIBILITY 0x200000
-
-#define Q3_MAX_MAP_DRAW_SURFS 0x20000
-#define Q3_MAX_MAP_DRAW_VERTS 0x80000
-#define Q3_MAX_MAP_DRAW_INDEXES 0x80000
-
-
-// key / value pair sizes in the entities lump
-#define Q3_MAX_KEY 32
-#define Q3_MAX_VALUE 1024
-
-// the editor uses these predefined yaw angles to orient entities up or down
-#define ANGLE_UP -1
-#define ANGLE_DOWN -2
-
-#define LIGHTMAP_WIDTH 128
-#define LIGHTMAP_HEIGHT 128
-
-
-//=============================================================================
-
-
-typedef struct {
- int fileofs, filelen;
-} q3_lump_t;
-
-#define Q3_LUMP_ENTITIES 0
-#define Q3_LUMP_SHADERS 1
-#define Q3_LUMP_PLANES 2
-#define Q3_LUMP_NODES 3
-#define Q3_LUMP_LEAFS 4
-#define Q3_LUMP_LEAFSURFACES 5
-#define Q3_LUMP_LEAFBRUSHES 6
-#define Q3_LUMP_MODELS 7
-#define Q3_LUMP_BRUSHES 8
-#define Q3_LUMP_BRUSHSIDES 9
-#define Q3_LUMP_DRAWVERTS 10
-#define Q3_LUMP_DRAWINDEXES 11
-#define Q3_LUMP_FOGS 12
-#define Q3_LUMP_SURFACES 13
-#define Q3_LUMP_LIGHTMAPS 14
-#define Q3_LUMP_LIGHTGRID 15
-#define Q3_LUMP_VISIBILITY 16
-#define Q3_HEADER_LUMPS 17
-
-typedef struct {
- int ident;
- int version;
-
- q3_lump_t lumps[Q3_HEADER_LUMPS];
-} q3_dheader_t;
-
-typedef struct {
- float mins[3], maxs[3];
- int firstSurface, numSurfaces;
- int firstBrush, numBrushes;
-} q3_dmodel_t;
-
-typedef struct {
- char shader[MAX_QPATH];
- int surfaceFlags;
- int contentFlags;
-} q3_dshader_t;
-
-// planes (x&~1) and (x&~1)+1 are allways opposites
-
-typedef struct {
- float normal[3];
- float dist;
-} q3_dplane_t;
-
-typedef struct {
- int planeNum;
- int children[2]; // negative numbers are -(leafs+1), not nodes
- int mins[3]; // for frustom culling
- int maxs[3];
-} q3_dnode_t;
-
-typedef struct {
- int cluster; // -1 = opaque cluster (do I still store these?)
- int area;
-
- int mins[3]; // for frustum culling
- int maxs[3];
-
- int firstLeafSurface;
- int numLeafSurfaces;
-
- int firstLeafBrush;
- int numLeafBrushes;
-} q3_dleaf_t;
-
-typedef struct {
- int planeNum; // positive plane side faces out of the leaf
- int shaderNum;
-} q3_dbrushside_t;
-
-typedef struct {
- int firstSide;
- int numSides;
- int shaderNum; // the shader that determines the contents flags
-} q3_dbrush_t;
-
-typedef struct {
- char shader[MAX_QPATH];
- int brushNum;
- int visibleSide; // the brush side that ray tests need to clip against (-1 == none)
-} q3_dfog_t;
-
-typedef struct {
- vec3_t xyz;
- float st[2];
- float lightmap[2];
- vec3_t normal;
- byte color[4];
-} q3_drawVert_t;
-
-typedef enum {
- MST_BAD,
- MST_PLANAR,
- MST_PATCH,
- MST_TRIANGLE_SOUP,
- MST_FLARE
-} q3_mapSurfaceType_t;
-
-typedef struct {
- int shaderNum;
- int fogNum;
- int surfaceType;
-
- int firstVert;
- int numVerts;
-
- int firstIndex;
- int numIndexes;
-
- int lightmapNum;
- int lightmapX, lightmapY;
- int lightmapWidth, lightmapHeight;
-
- vec3_t lightmapOrigin;
- vec3_t lightmapVecs[3]; // for patches, [0] and [1] are lodbounds
-
- int patchWidth;
- int patchHeight;
-} q3_dsurface_t;
-
-
-#endif
diff --git a/code/bspc/qbsp.h b/code/bspc/qbsp.h
deleted file mode 100644
index 9b50ef5..0000000
--- a/code/bspc/qbsp.h
+++ /dev/null
@@ -1,477 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-
-#if defined(WIN32) || defined(_WIN32)
-#include <io.h>
-#endif
-#include <malloc.h>
-#include "l_cmd.h"
-#include "l_math.h"
-#include "l_poly.h"
-#include "l_threads.h"
-#include "../botlib/l_script.h"
-#include "l_bsp_ent.h"
-#include "q2files.h"
-#include "l_mem.h"
-#include "l_utils.h"
-#include "l_log.h"
-#include "l_qfiles.h"
-
-#define BSPC_VERSION "2.1h"
-
-#define ME
-#define DEBUG
-#define NODELIST
-#define SIN
-
-#define MAX_BRUSH_SIDES 128 //maximum number of sides per brush
-#define CLIP_EPSILON 0.1
-#define MAX_MAP_BOUNDS 65535
-#define BOGUS_RANGE (MAX_MAP_BOUNDS+128) //somewhere outside the map
-#define TEXINFO_NODE -1 //side is allready on a node
-#define PLANENUM_LEAF -1 //used for leaf nodes
-#define MAXEDGES 20 //maximum number of face edges
-#define MAX_NODE_BRUSHES 8 //maximum brushes in a node
-//side flags
-#define SFL_TESTED 1
-#define SFL_VISIBLE 2
-#define SFL_BEVEL 4
-#define SFL_TEXTURED 8
-#define SFL_CURVE 16
-
-//map plane
-typedef struct plane_s
-{
- vec3_t normal;
- vec_t dist;
- int type;
- int signbits;
- struct plane_s *hash_chain;
-} plane_t;
-//brush texture
-typedef struct
-{
- vec_t shift[2];
- vec_t rotate;
- vec_t scale[2];
- char name[32];
- int flags;
- int value;
-} brush_texture_t;
-//brush side
-typedef struct side_s
-{
- int planenum; // map plane this side is in
- int texinfo; // texture reference
- winding_t *winding; // winding of this side
- struct side_s *original; // bspbrush_t sides will reference the mapbrush_t sides
- int lightinfo; // for SIN only
- int contents; // from miptex
- int surf; // from miptex
- unsigned short flags; // side flags
-} side_t; //sizeof(side_t) = 36
-//map brush
-typedef struct mapbrush_s
-{
- int entitynum;
- int brushnum;
-
- int contents;
-#ifdef ME
- int expansionbbox; //bbox used for expansion of the brush
- int leafnum;
- int modelnum;
-#endif
-
- vec3_t mins, maxs;
-
- int numsides;
- side_t *original_sides;
-} mapbrush_t;
-//bsp face
-typedef struct face_s
-{
- struct face_s *next; // on node
-
- // the chain of faces off of a node can be merged or split,
- // but each face_t along the way will remain in the chain
- // until the entire tree is freed
- struct face_s *merged; // if set, this face isn't valid anymore
- struct face_s *split[2]; // if set, this face isn't valid anymore
-
- struct portal_s *portal;
- int texinfo;
-#ifdef SIN
- int lightinfo;
-#endif
- int planenum;
- int contents; // faces in different contents can't merge
- int outputnumber;
- winding_t *w;
- int numpoints;
- qboolean badstartvert; // tjunctions cannot be fixed without a midpoint vertex
- int vertexnums[MAXEDGES];
-} face_t;
-//bsp brush
-typedef struct bspbrush_s
-{
- struct bspbrush_s *next;
- vec3_t mins, maxs;
- int side, testside; // side of node during construction
- mapbrush_t *original;
- int numsides;
- side_t sides[6]; // variably sized
-} bspbrush_t; //sizeof(bspbrush_t) = 44 + numsides * sizeof(side_t)
-//bsp node
-typedef struct node_s
-{
- //both leafs and nodes
- int planenum; // -1 = leaf node
- struct node_s *parent;
- vec3_t mins, maxs; // valid after portalization
- bspbrush_t *volume; // one for each leaf/node
-
- // nodes only
- qboolean detail_seperator; // a detail brush caused the split
- side_t *side; // the side that created the node
- struct node_s *children[2];
- face_t *faces;
-
- // leafs only
- bspbrush_t *brushlist; // fragments of all brushes in this leaf
- int contents; // OR of all brush contents
- int occupied; // 1 or greater can reach entity
- entity_t *occupant; // for leak file testing
- int cluster; // for portalfile writing
- int area; // for areaportals
- struct portal_s *portals; // also on nodes during construction
-#ifdef NODELIST
- struct node_s *next; //next node in the nodelist
-#endif
-#ifdef ME
- int expansionbboxes; //OR of all bboxes used for expansion of the brushes
- int modelnum;
-#endif
-} node_t; //sizeof(node_t) = 80 bytes
-//bsp portal
-typedef struct portal_s
-{
- plane_t plane;
- node_t *onnode; // NULL = outside box
- node_t *nodes[2]; // [0] = front side of plane
- struct portal_s *next[2];
- winding_t *winding;
-
- qboolean sidefound; // false if ->side hasn't been checked
- side_t *side; // NULL = non-visible
- face_t *face[2]; // output face in bsp file
-#ifdef ME
- struct tmp_face_s *tmpface; //pointer to the tmpface created for this portal
- int planenum; //number of the map plane used by the portal
-#endif
-} portal_t;
-//bsp tree
-typedef struct
-{
- node_t *headnode;
- node_t outside_node;
- vec3_t mins, maxs;
-} tree_t;
-
-//=============================================================================
-// bspc.c
-//=============================================================================
-
-extern qboolean noprune;
-extern qboolean nodetail;
-extern qboolean fulldetail;
-extern qboolean nomerge;
-extern qboolean nosubdiv;
-extern qboolean nowater;
-extern qboolean noweld;
-extern qboolean noshare;
-extern qboolean notjunc;
-extern qboolean onlyents;
-#ifdef ME
-extern qboolean nocsg;
-extern qboolean create_aas;
-extern qboolean freetree;
-extern qboolean lessbrushes;
-extern qboolean nobrushmerge;
-extern qboolean cancelconversion;
-extern qboolean noliquids;
-extern qboolean capsule_collision;
-#endif //ME
-
-extern float subdivide_size;
-extern vec_t microvolume;
-
-extern char outbase[32];
-extern char source[1024];
-
-//=============================================================================
-// map.c
-//=============================================================================
-
-#define MAX_MAPFILE_PLANES 256000
-#define MAX_MAPFILE_BRUSHES 65535
-#define MAX_MAPFILE_BRUSHSIDES (MAX_MAPFILE_BRUSHES*8)
-#define MAX_MAPFILE_TEXINFO 8192
-
-extern int entity_num;
-
-extern plane_t mapplanes[MAX_MAPFILE_PLANES];
-extern int nummapplanes;
-extern int mapplaneusers[MAX_MAPFILE_PLANES];
-
-extern int nummapbrushes;
-extern mapbrush_t mapbrushes[MAX_MAPFILE_BRUSHES];
-
-extern vec3_t map_mins, map_maxs;
-
-extern int nummapbrushsides;
-extern side_t brushsides[MAX_MAPFILE_BRUSHSIDES];
-extern brush_texture_t side_brushtextures[MAX_MAPFILE_BRUSHSIDES];
-
-#ifdef ME
-
-typedef struct
-{
- float vecs[2][4]; // [s/t][xyz offset]
- int flags; // miptex flags + overrides
- int value;
- char texture[64]; // texture name (textures/*.wal)
- int nexttexinfo; // for animations, -1 = end of chain
-} map_texinfo_t;
-
-extern map_texinfo_t map_texinfo[MAX_MAPFILE_TEXINFO];
-extern int map_numtexinfo;
-#define NODESTACKSIZE 1024
-
-#define MAPTYPE_QUAKE1 1
-#define MAPTYPE_QUAKE2 2
-#define MAPTYPE_QUAKE3 3
-#define MAPTYPE_HALFLIFE 4
-#define MAPTYPE_SIN 5
-
-extern int nodestack[NODESTACKSIZE];
-extern int *nodestackptr;
-extern int nodestacksize;
-extern int brushmodelnumbers[MAX_MAPFILE_BRUSHES];
-extern int dbrushleafnums[MAX_MAPFILE_BRUSHES];
-extern int dplanes2mapplanes[MAX_MAPFILE_PLANES];
-
-extern int loadedmaptype;
-#endif //ME
-
-extern int c_boxbevels;
-extern int c_edgebevels;
-extern int c_areaportals;
-extern int c_clipbrushes;
-extern int c_squattbrushes;
-
-//finds a float plane for the given normal and distance
-int FindFloatPlane(vec3_t normal, vec_t dist);
-//returns the plane type for the given normal
-int PlaneTypeForNormal(vec3_t normal);
-//returns the plane defined by the three given points
-int PlaneFromPoints(int *p0, int *p1, int *p2);
-//add bevels to the map brush
-void AddBrushBevels(mapbrush_t *b);
-//makes brush side windings for the brush
-qboolean MakeBrushWindings(mapbrush_t *ob);
-//marks brush bevels of the brush as bevel
-void MarkBrushBevels(mapbrush_t *brush);
-//returns true if the map brush already exists
-int BrushExists(mapbrush_t *brush);
-//loads a map from a bsp file
-int LoadMapFromBSP(struct quakefile_s *qf);
-//resets map loading
-void ResetMapLoading(void);
-//print some map info
-void PrintMapInfo(void);
-//writes a map file (type depending on loaded map type)
-void WriteMapFile(char *filename);
-
-//=============================================================================
-// map_q2.c
-//=============================================================================
-
-void Q2_ResetMapLoading(void);
-//loads a Quake2 map file
-void Q2_LoadMapFile(char *filename);
-//loads a map from a Quake2 bsp file
-void Q2_LoadMapFromBSP(char *filename, int offset, int length);
-
-//=============================================================================
-// map_q1.c
-//=============================================================================
-
-void Q1_ResetMapLoading(void);
-//loads a Quake2 map file
-void Q1_LoadMapFile(char *filename);
-//loads a map from a Quake1 bsp file
-void Q1_LoadMapFromBSP(char *filename, int offset, int length);
-
-//=============================================================================
-// map_q3.c
-//=============================================================================
-void Q3_ResetMapLoading(void);
-//loads a map from a Quake3 bsp file
-void Q3_LoadMapFromBSP(struct quakefile_s *qf);
-
-//=============================================================================
-// map_sin.c
-//=============================================================================
-
-void Sin_ResetMapLoading(void);
-//loads a Sin map file
-void Sin_LoadMapFile(char *filename);
-//loads a map from a Sin bsp file
-void Sin_LoadMapFromBSP(char *filename, int offset, int length);
-
-//=============================================================================
-// map_hl.c
-//=============================================================================
-
-void HL_ResetMapLoading(void);
-//loads a Half-Life map file
-void HL_LoadMapFile(char *filename);
-//loads a map from a Half-Life bsp file
-void HL_LoadMapFromBSP(char *filename, int offset, int length);
-
-//=============================================================================
-// textures.c
-//=============================================================================
-
-typedef struct
-{
- char name[64];
- int flags;
- int value;
- int contents;
- char animname[64];
-} textureref_t;
-
-#define MAX_MAP_TEXTURES 1024
-
-extern textureref_t textureref[MAX_MAP_TEXTURES];
-
-int FindMiptex(char *name);
-int TexinfoForBrushTexture(plane_t *plane, brush_texture_t *bt, vec3_t origin);
-void TextureAxisFromPlane(plane_t *pln, vec3_t xv, vec3_t yv);
-
-//=============================================================================
-// csg
-//=============================================================================
-
-bspbrush_t *MakeBspBrushList(int startbrush, int endbrush, vec3_t clipmins, vec3_t clipmaxs);
-bspbrush_t *ChopBrushes(bspbrush_t *head);
-bspbrush_t *InitialBrushList(bspbrush_t *list);
-bspbrush_t *OptimizedBrushList(bspbrush_t *list);
-void WriteBrushMap(char *name, bspbrush_t *list);
-void CheckBSPBrush(bspbrush_t *brush);
-void BSPBrushWindings(bspbrush_t *brush);
-bspbrush_t *TryMergeBrushes(bspbrush_t *brush1, bspbrush_t *brush2);
-tree_t *ProcessWorldBrushes(int brush_start, int brush_end);
-
-//=============================================================================
-// brushbsp
-//=============================================================================
-
-#define PSIDE_FRONT 1
-#define PSIDE_BACK 2
-#define PSIDE_BOTH (PSIDE_FRONT|PSIDE_BACK)
-#define PSIDE_FACING 4
-
-void WriteBrushList(char *name, bspbrush_t *brush, qboolean onlyvis);
-bspbrush_t *CopyBrush(bspbrush_t *brush);
-void SplitBrush(bspbrush_t *brush, int planenum, bspbrush_t **front, bspbrush_t **back);
-node_t *AllocNode(void);
-bspbrush_t *AllocBrush(int numsides);
-int CountBrushList(bspbrush_t *brushes);
-void FreeBrush(bspbrush_t *brushes);
-vec_t BrushVolume(bspbrush_t *brush);
-void BoundBrush(bspbrush_t *brush);
-void FreeBrushList(bspbrush_t *brushes);
-tree_t *BrushBSP(bspbrush_t *brushlist, vec3_t mins, vec3_t maxs);
-bspbrush_t *BrushFromBounds(vec3_t mins, vec3_t maxs);
-int BrushMostlyOnSide(bspbrush_t *brush, plane_t *plane);
-qboolean WindingIsHuge(winding_t *w);
-qboolean WindingIsTiny(winding_t *w);
-void ResetBrushBSP(void);
-
-//=============================================================================
-// portals.c
-//=============================================================================
-
-int VisibleContents (int contents);
-void MakeHeadnodePortals (tree_t *tree);
-void MakeNodePortal (node_t *node);
-void SplitNodePortals (node_t *node);
-qboolean Portal_VisFlood (portal_t *p);
-qboolean FloodEntities (tree_t *tree);
-void FillOutside (node_t *headnode);
-void FloodAreas (tree_t *tree);
-void MarkVisibleSides (tree_t *tree, int start, int end);
-void FreePortal (portal_t *p);
-void EmitAreaPortals (node_t *headnode);
-void MakeTreePortals (tree_t *tree);
-
-//=============================================================================
-// glfile.c
-//=============================================================================
-
-void OutputWinding(winding_t *w, FILE *glview);
-void WriteGLView(tree_t *tree, char *source);
-
-//=============================================================================
-// gldraw.c
-//=============================================================================
-
-extern vec3_t draw_mins, draw_maxs;
-extern qboolean drawflag;
-
-void Draw_ClearWindow (void);
-void DrawWinding (winding_t *w);
-void GLS_BeginScene (void);
-void GLS_Winding (winding_t *w, int code);
-void GLS_EndScene (void);
-
-//=============================================================================
-// leakfile.c
-//=============================================================================
-
-void LeakFile (tree_t *tree);
-
-//=============================================================================
-// tree.c
-//=============================================================================
-
-tree_t *Tree_Alloc(void);
-void Tree_Free(tree_t *tree);
-void Tree_Free_r(node_t *node);
-void Tree_Print_r(node_t *node, int depth);
-void Tree_FreePortals_r(node_t *node);
-void Tree_PruneNodes_r(node_t *node);
-void Tree_PruneNodes(node_t *node);
diff --git a/code/bspc/qfiles.h b/code/bspc/qfiles.h
deleted file mode 100644
index b987f85..0000000
--- a/code/bspc/qfiles.h
+++ /dev/null
@@ -1,487 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-//
-// qfiles.h: quake file formats
-// This file must be identical in the quake and utils directories
-//
-
-/*
-========================================================================
-
-The .pak files are just a linear collapse of a directory tree
-
-========================================================================
-*/
-
-#define IDPAKHEADER (('K'<<24)+('C'<<16)+('A'<<8)+'P')
-
-typedef struct
-{
- char name[56];
- int filepos, filelen;
-} dpackfile_t;
-
-typedef struct
-{
- int ident; // == IDPAKHEADER
- int dirofs;
- int dirlen;
-} dpackheader_t;
-
-#define MAX_FILES_IN_PACK 4096
-
-
-/*
-========================================================================
-
-PCX files are used for as many images as possible
-
-========================================================================
-*/
-
-typedef struct
-{
- char manufacturer;
- char version;
- char encoding;
- char bits_per_pixel;
- unsigned short xmin,ymin,xmax,ymax;
- unsigned short hres,vres;
- unsigned char palette[48];
- char reserved;
- char color_planes;
- unsigned short bytes_per_line;
- unsigned short palette_type;
- char filler[58];
- unsigned char data; // unbounded
-} pcx_t;
-
-
-/*
-========================================================================
-
-.MD2 triangle model file format
-
-========================================================================
-*/
-
-#define IDALIASHEADER (('2'<<24)+('P'<<16)+('D'<<8)+'I')
-#define ALIAS_VERSION 8
-
-#define MAX_TRIANGLES 4096
-#define MAX_VERTS 2048
-#define MAX_FRAMES 512
-#define MAX_MD2SKINS 32
-#define MAX_SKINNAME 64
-
-typedef struct
-{
- short s;
- short t;
-} dstvert_t;
-
-typedef struct
-{
- short index_xyz[3];
- short index_st[3];
-} dtriangle_t;
-
-typedef struct
-{
- byte v[3]; // scaled byte to fit in frame mins/maxs
- byte lightnormalindex;
-} dtrivertx_t;
-
-#define DTRIVERTX_V0 0
-#define DTRIVERTX_V1 1
-#define DTRIVERTX_V2 2
-#define DTRIVERTX_LNI 3
-#define DTRIVERTX_SIZE 4
-
-typedef struct
-{
- float scale[3]; // multiply byte verts by this
- float translate[3]; // then add this
- char name[16]; // frame name from grabbing
- dtrivertx_t verts[1]; // variable sized
-} daliasframe_t;
-
-
-// the glcmd format:
-// a positive integer starts a tristrip command, followed by that many
-// vertex structures.
-// a negative integer starts a trifan command, followed by -x vertexes
-// a zero indicates the end of the command list.
-// a vertex consists of a floating point s, a floating point t,
-// and an integer vertex index.
-
-
-typedef struct
-{
- int ident;
- int version;
-
- int skinwidth;
- int skinheight;
- int framesize; // byte size of each frame
-
- int num_skins;
- int num_xyz;
- int num_st; // greater than num_xyz for seams
- int num_tris;
- int num_glcmds; // dwords in strip/fan command list
- int num_frames;
-
- int ofs_skins; // each skin is a MAX_SKINNAME string
- int ofs_st; // byte offset from start for stverts
- int ofs_tris; // offset for dtriangles
- int ofs_frames; // offset for first frame
- int ofs_glcmds;
- int ofs_end; // end of file
-
-} dmdl_t;
-
-/*
-========================================================================
-
-.SP2 sprite file format
-
-========================================================================
-*/
-
-#define IDSPRITEHEADER (('2'<<24)+('S'<<16)+('D'<<8)+'I')
- // little-endian "IDS2"
-#define SPRITE_VERSION 2
-
-typedef struct
-{
- int width, height;
- int origin_x, origin_y; // raster coordinates inside pic
- char name[MAX_SKINNAME]; // name of pcx file
-} dsprframe_t;
-
-typedef struct {
- int ident;
- int version;
- int numframes;
- dsprframe_t frames[1]; // variable sized
-} dsprite_t;
-
-/*
-==============================================================================
-
- .WAL texture file format
-
-==============================================================================
-*/
-
-
-#define MIPLEVELS 4
-typedef struct miptex_s
-{
- char name[32];
- unsigned width, height;
- unsigned offsets[MIPLEVELS]; // four mip maps stored
- char animname[32]; // next frame in animation chain
- int flags;
- int contents;
- int value;
-} miptex_t;
-
-
-
-/*
-==============================================================================
-
- .BSP file format
-
-==============================================================================
-*/
-
-#define IDBSPHEADER (('P'<<24)+('S'<<16)+('B'<<8)+'I')
- // little-endian "IBSP"
-
-#define BSPVERSION 38
-
-
-// upper design bounds
-// leaffaces, leafbrushes, planes, and verts are still bounded by
-// 16 bit short limits
-#define MAX_MAP_MODELS 1024
-#define MAX_MAP_BRUSHES 8192
-#define MAX_MAP_ENTITIES 2048
-#define MAX_MAP_ENTSTRING 0x40000
-#define MAX_MAP_TEXINFO 8192
-
-#define MAX_MAP_AREAS 256
-#define MAX_MAP_AREAPORTALS 1024
-#define MAX_MAP_PLANES 65536
-#define MAX_MAP_NODES 65536
-#define MAX_MAP_BRUSHSIDES 65536
-#define MAX_MAP_LEAFS 65536
-#define MAX_MAP_VERTS 65536
-#define MAX_MAP_FACES 65536
-#define MAX_MAP_LEAFFACES 65536
-#define MAX_MAP_LEAFBRUSHES 65536
-#define MAX_MAP_PORTALS 65536
-#define MAX_MAP_EDGES 128000
-#define MAX_MAP_SURFEDGES 256000
-#define MAX_MAP_LIGHTING 0x320000
-#define MAX_MAP_VISIBILITY 0x280000
-
-// key / value pair sizes
-
-#define MAX_KEY 32
-#define MAX_VALUE 1024
-
-//=============================================================================
-
-typedef struct
-{
- int fileofs, filelen;
-} lump_t;
-
-#define LUMP_ENTITIES 0
-#define LUMP_PLANES 1
-#define LUMP_VERTEXES 2
-#define LUMP_VISIBILITY 3
-#define LUMP_NODES 4
-#define LUMP_TEXINFO 5
-#define LUMP_FACES 6
-#define LUMP_LIGHTING 7
-#define LUMP_LEAFS 8
-#define LUMP_LEAFFACES 9
-#define LUMP_LEAFBRUSHES 10
-#define LUMP_EDGES 11
-#define LUMP_SURFEDGES 12
-#define LUMP_MODELS 13
-#define LUMP_BRUSHES 14
-#define LUMP_BRUSHSIDES 15
-#define LUMP_POP 16
-#define LUMP_AREAS 17
-#define LUMP_AREAPORTALS 18
-#define HEADER_LUMPS 19
-
-typedef struct
-{
- int ident;
- int version;
- lump_t lumps[HEADER_LUMPS];
-} dheader_t;
-
-typedef struct
-{
- float mins[3], maxs[3];
- float origin[3]; // for sounds or lights
- int headnode;
- int firstface, numfaces; // submodels just draw faces
- // without walking the bsp tree
-} dmodel_t;
-
-
-typedef struct
-{
- float point[3];
-} dvertex_t;
-
-
-// 0-2 are axial planes
-#define PLANE_X 0
-#define PLANE_Y 1
-#define PLANE_Z 2
-
-// 3-5 are non-axial planes snapped to the nearest
-#define PLANE_ANYX 3
-#define PLANE_ANYY 4
-#define PLANE_ANYZ 5
-
-// planes (x&~1) and (x&~1)+1 are allways opposites
-
-typedef struct
-{
- float normal[3];
- float dist;
- int type; // PLANE_X - PLANE_ANYZ ?remove? trivial to regenerate
-} dplane_t;
-
-
-// contents flags are seperate bits
-// a given brush can contribute multiple content bits
-// multiple brushes can be in a single leaf
-
-// these definitions also need to be in q_shared.h!
-
-// lower bits are stronger, and will eat weaker brushes completely
-#define CONTENTS_SOLID 1 // an eye is never valid in a solid
-#define CONTENTS_WINDOW 2 // translucent, but not watery
-#define CONTENTS_AUX 4
-#define CONTENTS_LAVA 8
-#define CONTENTS_SLIME 16
-#define CONTENTS_WATER 32
-#define CONTENTS_MIST 64
-#define LAST_VISIBLE_CONTENTS 64
-
-// remaining contents are non-visible, and don't eat brushes
-
-#define CONTENTS_AREAPORTAL 0x8000
-
-#define CONTENTS_PLAYERCLIP 0x10000
-#define CONTENTS_MONSTERCLIP 0x20000
-
-// currents can be added to any other contents, and may be mixed
-#define CONTENTS_CURRENT_0 0x40000
-#define CONTENTS_CURRENT_90 0x80000
-#define CONTENTS_CURRENT_180 0x100000
-#define CONTENTS_CURRENT_270 0x200000
-#define CONTENTS_CURRENT_UP 0x400000
-#define CONTENTS_CURRENT_DOWN 0x800000
-
-#define CONTENTS_ORIGIN 0x1000000 // removed before bsping an entity
-
-#define CONTENTS_MONSTER 0x2000000 // should never be on a brush, only in game
-#define CONTENTS_DEADMONSTER 0x4000000
-#define CONTENTS_DETAIL 0x8000000 // brushes to be added after vis leafs
-//renamed because it's in conflict with the Q3A translucent contents
-#define CONTENTS_Q2TRANSLUCENT 0x10000000 // auto set if any surface has trans
-#define CONTENTS_LADDER 0x20000000
-
-
-
-#define SURF_LIGHT 0x1 // value will hold the light strength
-
-#define SURF_SLICK 0x2 // effects game physics
-
-#define SURF_SKY 0x4 // don't draw, but add to skybox
-#define SURF_WARP 0x8 // turbulent water warp
-#define SURF_TRANS33 0x10
-#define SURF_TRANS66 0x20
-#define SURF_FLOWING 0x40 // scroll towards angle
-#define SURF_NODRAW 0x80 // don't bother referencing the texture
-
-#define SURF_HINT 0x100 // make a primary bsp splitter
-#define SURF_SKIP 0x200 // completely ignore, allowing non-closed brushes
-
-
-
-typedef struct
-{
- int planenum;
- int children[2]; // negative numbers are -(leafs+1), not nodes
- short mins[3]; // for frustom culling
- short maxs[3];
- unsigned short firstface;
- unsigned short numfaces; // counting both sides
-} dnode_t;
-
-
-typedef struct texinfo_s
-{
- float vecs[2][4]; // [s/t][xyz offset]
- int flags; // miptex flags + overrides
- int value; // light emission, etc
- char texture[32]; // texture name (textures/*.wal)
- int nexttexinfo; // for animations, -1 = end of chain
-} texinfo_t;
-
-
-// note that edge 0 is never used, because negative edge nums are used for
-// counterclockwise use of the edge in a face
-typedef struct
-{
- unsigned short v[2]; // vertex numbers
-} dedge_t;
-
-#define MAXLIGHTMAPS 4
-typedef struct
-{
- unsigned short planenum;
- short side;
-
- int firstedge; // we must support > 64k edges
- short numedges;
- short texinfo;
-
-// lighting info
- byte styles[MAXLIGHTMAPS];
- int lightofs; // start of [numstyles*surfsize] samples
-} dface_t;
-
-typedef struct
-{
- int contents; // OR of all brushes (not needed?)
-
- short cluster;
- short area;
-
- short mins[3]; // for frustum culling
- short maxs[3];
-
- unsigned short firstleafface;
- unsigned short numleaffaces;
-
- unsigned short firstleafbrush;
- unsigned short numleafbrushes;
-} dleaf_t;
-
-typedef struct
-{
- unsigned short planenum; // facing out of the leaf
- short texinfo;
-} dbrushside_t;
-
-typedef struct
-{
- int firstside;
- int numsides;
- int contents;
-} dbrush_t;
-
-#define ANGLE_UP -1
-#define ANGLE_DOWN -2
-
-
-// the visibility lump consists of a header with a count, then
-// byte offsets for the PVS and PHS of each cluster, then the raw
-// compressed bit vectors
-#define DVIS_PVS 0
-#define DVIS_PHS 1
-typedef struct
-{
- int numclusters;
- int bitofs[8][2]; // bitofs[numclusters][2]
-} dvis_t;
-
-// each area has a list of portals that lead into other areas
-// when portals are closed, other areas may not be visible or
-// hearable even if the vis info says that it should be
-typedef struct
-{
- int portalnum;
- int otherarea;
-} dareaportal_t;
-
-typedef struct
-{
- int numareaportals;
- int firstareaportal;
-} darea_t;
diff --git a/code/bspc/sinfiles.h b/code/bspc/sinfiles.h
deleted file mode 100644
index a372d60..0000000
--- a/code/bspc/sinfiles.h
+++ /dev/null
@@ -1,365 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-/*
-==============================================================================
-
- .BSP file format
-
-==============================================================================
-*/
-
-#define SIN
-
-#define SINBSPVERSION 41
-
-// upper design bounds
-// leaffaces, leafbrushes, planes, and verts are still bounded by
-// 16 bit short limits
-#define SIN_MAX_MAP_MODELS 1024
-#define SIN_MAX_MAP_BRUSHES 8192
-#define SIN_MAX_MAP_ENTITIES 2048
-#define SIN_MAX_MAP_ENTSTRING 0x40000
-#define SIN_MAX_MAP_TEXINFO 8192
-
-#define SIN_MAX_MAP_AREAS 256
-#define SIN_MAX_MAP_AREAPORTALS 1024
-#define SIN_MAX_MAP_PLANES 65536
-#define SIN_MAX_MAP_NODES 65536
-#define SIN_MAX_MAP_BRUSHSIDES 65536
-#define SIN_MAX_MAP_LEAFS 65536
-#define SIN_MAX_MAP_VERTS 65536
-#define SIN_MAX_MAP_FACES 65536
-#define SIN_MAX_MAP_LEAFFACES 65536
-#define SIN_MAX_MAP_LEAFBRUSHES 65536
-#define SIN_MAX_MAP_PORTALS 65536
-#define SIN_MAX_MAP_EDGES 128000
-#define SIN_MAX_MAP_SURFEDGES 256000
-#define SIN_MAX_MAP_LIGHTING 0x320000
-#define SIN_MAX_MAP_VISIBILITY 0x280000
-
-#ifdef SIN
-#define SIN_MAX_MAP_LIGHTINFO 8192
-#endif
-
-#ifdef SIN
-#undef SIN_MAX_MAP_LIGHTING //undef the Quake2 bsp version
-#define SIN_MAX_MAP_LIGHTING 0x300000
-#endif
-
-#ifdef SIN
-#undef SIN_MAX_MAP_VISIBILITY //undef the Quake2 bsp version
-#define SIN_MAX_MAP_VISIBILITY 0x280000
-#endif
-
-//=============================================================================
-
-typedef struct
-{
- int fileofs, filelen;
-} sin_lump_t;
-
-#define SIN_LUMP_ENTITIES 0
-#define SIN_LUMP_PLANES 1
-#define SIN_LUMP_VERTEXES 2
-#define SIN_LUMP_VISIBILITY 3
-#define SIN_LUMP_NODES 4
-#define SIN_LUMP_TEXINFO 5
-#define SIN_LUMP_FACES 6
-#define SIN_LUMP_LIGHTING 7
-#define SIN_LUMP_LEAFS 8
-#define SIN_LUMP_LEAFFACES 9
-#define SIN_LUMP_LEAFBRUSHES 10
-#define SIN_LUMP_EDGES 11
-#define SIN_LUMP_SURFEDGES 12
-#define SIN_LUMP_MODELS 13
-#define SIN_LUMP_BRUSHES 14
-#define SIN_LUMP_BRUSHSIDES 15
-#define SIN_LUMP_POP 16
-#define SIN_LUMP_AREAS 17
-#define SIN_LUMP_AREAPORTALS 18
-
-#ifdef SIN
-#define SIN_LUMP_LIGHTINFO 19
-#define SINHEADER_LUMPS 20
-#endif
-
-typedef struct
-{
- int ident;
- int version;
- sin_lump_t lumps[SINHEADER_LUMPS];
-} sin_dheader_t;
-
-typedef struct
-{
- float mins[3], maxs[3];
- float origin[3]; // for sounds or lights
- int headnode;
- int firstface, numfaces; // submodels just draw faces
- // without walking the bsp tree
-} sin_dmodel_t;
-
-typedef struct
-{
- float point[3];
-} sin_dvertex_t;
-
-
-// 0-2 are axial planes
-#define PLANE_X 0
-#define PLANE_Y 1
-#define PLANE_Z 2
-
-// 3-5 are non-axial planes snapped to the nearest
-#define PLANE_ANYX 3
-#define PLANE_ANYY 4
-#define PLANE_ANYZ 5
-
-// planes (x&~1) and (x&~1)+1 are allways opposites
-
-typedef struct
-{
- float normal[3];
- float dist;
- int type; // PLANE_X - PLANE_ANYZ ?remove? trivial to regenerate
-} sin_dplane_t;
-
-
-// contents flags are seperate bits
-// a given brush can contribute multiple content bits
-// multiple brushes can be in a single leaf
-
-// these definitions also need to be in q_shared.h!
-
-// lower bits are stronger, and will eat weaker brushes completely
-#ifdef SIN
-#define CONTENTS_FENCE 4
-#endif
-// remaining contents are non-visible, and don't eat brushes
-
-#ifdef SIN
-#define CONTENTS_DUMMYFENCE 0x1000
-#endif
-
-#ifdef SIN
-#define SURF_MASKED 0x2 // surface texture is masked
-#endif
-
-#define SURF_SKY 0x4 // don't draw, but add to skybox
-#define SURF_WARP 0x8 // turbulent water warp
-
-#ifdef SIN
-#define SURF_NONLIT 0x10 // surface is not lit
-#define SURF_NOFILTER 0x20 // surface is not bi-linear filtered
-#endif
-
-#define SURF_FLOWING 0x40 // scroll towards angle
-#define SURF_NODRAW 0x80 // don't bother referencing the texture
-
-#define SURF_HINT 0x100 // make a primary bsp splitter
-#define SURF_SKIP 0x200 // completely ignore, allowing non-closed brushes
-
-#ifdef SIN
-#define SURF_CONVEYOR 0x40 // surface is not lit
-#endif
-
-#ifdef SIN
-#define SURF_WAVY 0x400 // surface has waves
-#define SURF_RICOCHET 0x800 // projectiles bounce literally bounce off this surface
-#define SURF_PRELIT 0x1000 // surface has intensity information for pre-lighting
-#define SURF_MIRROR 0x2000 // surface is a mirror
-#define SURF_CONSOLE 0x4000 // surface is a console
-#define SURF_USECOLOR 0x8000 // surface is lit with non-lit * color
-#define SURF_HARDWAREONLY 0x10000 // surface has been damaged
-#define SURF_DAMAGE 0x20000 // surface can be damaged
-#define SURF_WEAK 0x40000 // surface has weak hit points
-#define SURF_NORMAL 0x80000 // surface has normal hit points
-#define SURF_ADD 0x100000 // surface will be additive
-#define SURF_ENVMAPPED 0x200000 // surface is envmapped
-#define SURF_RANDOMANIMATE 0x400000 // surface start animating on a random frame
-#define SURF_ANIMATE 0x800000 // surface animates
-#define SURF_RNDTIME 0x1000000 // time between animations is random
-#define SURF_TRANSLATE 0x2000000 // surface translates
-#define SURF_NOMERGE 0x4000000 // surface is not merged in csg phase
-#define SURF_TYPE_BIT0 0x8000000 // 0 bit of surface type
-#define SURF_TYPE_BIT1 0x10000000 // 1 bit of surface type
-#define SURF_TYPE_BIT2 0x20000000 // 2 bit of surface type
-#define SURF_TYPE_BIT3 0x40000000 // 3 bit of surface type
-
-#define SURF_START_BIT 27
-#define SURFACETYPE_FROM_FLAGS( x ) ( ( x >> (SURF_START_BIT) ) & 0xf )
-
-
-#define SURF_TYPE_SHIFT(x) ( (x) << (SURF_START_BIT) ) // macro for getting proper bit mask
-
-#define SURF_TYPE_NONE SURF_TYPE_SHIFT(0)
-#define SURF_TYPE_WOOD SURF_TYPE_SHIFT(1)
-#define SURF_TYPE_METAL SURF_TYPE_SHIFT(2)
-#define SURF_TYPE_STONE SURF_TYPE_SHIFT(3)
-#define SURF_TYPE_CONCRETE SURF_TYPE_SHIFT(4)
-#define SURF_TYPE_DIRT SURF_TYPE_SHIFT(5)
-#define SURF_TYPE_FLESH SURF_TYPE_SHIFT(6)
-#define SURF_TYPE_GRILL SURF_TYPE_SHIFT(7)
-#define SURF_TYPE_GLASS SURF_TYPE_SHIFT(8)
-#define SURF_TYPE_FABRIC SURF_TYPE_SHIFT(9)
-#define SURF_TYPE_MONITOR SURF_TYPE_SHIFT(10)
-#define SURF_TYPE_GRAVEL SURF_TYPE_SHIFT(11)
-#define SURF_TYPE_VEGETATION SURF_TYPE_SHIFT(12)
-#define SURF_TYPE_PAPER SURF_TYPE_SHIFT(13)
-#define SURF_TYPE_DUCT SURF_TYPE_SHIFT(14)
-#define SURF_TYPE_WATER SURF_TYPE_SHIFT(15)
-#endif
-
-
-typedef struct
-{
- int planenum;
- int children[2]; // negative numbers are -(leafs+1), not nodes
- short mins[3]; // for frustom culling
- short maxs[3];
- unsigned short firstface;
- unsigned short numfaces; // counting both sides
-} sin_dnode_t;
-
-#ifdef SIN
-
-typedef struct sin_lightvalue_s
-{
- int value; // light emission, etc
- vec3_t color;
- float direct;
- float directangle;
- float directstyle;
- char directstylename[32];
-} sin_lightvalue_t;
-
-typedef struct sin_texinfo_s
-{
- float vecs[2][4]; // [s/t][xyz offset]
- int flags; // miptex flags + overrides
- char texture[64]; // texture name (textures/*.wal)
- int nexttexinfo; // for animations, -1 = end of chain
- float trans_mag;
- int trans_angle;
- int base_angle;
- float animtime;
- float nonlit;
- float translucence;
- float friction;
- float restitution;
- vec3_t color;
- char groupname[32];
-} sin_texinfo_t;
-
-#endif //SIN
-
-// note that edge 0 is never used, because negative edge nums are used for
-// counterclockwise use of the edge in a face
-typedef struct
-{
- unsigned short v[2]; // vertex numbers
-} sin_dedge_t;
-
-#ifdef MAXLIGHTMAPS
-#undef MAXLIGHTMAPS
-#endif
-#define MAXLIGHTMAPS 16
-typedef struct
-{
- unsigned short planenum;
- short side;
-
- int firstedge; // we must support > 64k edges
- short numedges;
- short texinfo;
-
-// lighting info
- byte styles[MAXLIGHTMAPS];
- int lightofs; // start of [numstyles*surfsize] samples
-#ifdef SIN
- int lightinfo;
-#endif
-} sin_dface_t;
-
-typedef struct
-{
- int contents; // OR of all brushes (not needed?)
-
- short cluster;
- short area;
-
- short mins[3]; // for frustum culling
- short maxs[3];
-
- unsigned short firstleafface;
- unsigned short numleaffaces;
-
- unsigned short firstleafbrush;
- unsigned short numleafbrushes;
-} sin_dleaf_t;
-
-typedef struct
-{
- unsigned short planenum; // facing out of the leaf
- short texinfo;
-#ifdef SIN
- int lightinfo;
-#endif
-} sin_dbrushside_t;
-
-typedef struct
-{
- int firstside;
- int numsides;
- int contents;
-} sin_dbrush_t;
-
-#define ANGLE_UP -1
-#define ANGLE_DOWN -2
-
-
-// the visibility lump consists of a header with a count, then
-// byte offsets for the PVS and PHS of each cluster, then the raw
-// compressed bit vectors
-#define DVIS_PVS 0
-#define DVIS_PHS 1
-typedef struct
-{
- int numclusters;
- int bitofs[8][2]; // bitofs[numclusters][2]
-} sin_dvis_t;
-
-// each area has a list of portals that lead into other areas
-// when portals are closed, other areas may not be visible or
-// hearable even if the vis info says that it should be
-typedef struct
-{
- int portalnum;
- int otherarea;
-} sin_dareaportal_t;
-
-typedef struct
-{
- int numareaportals;
- int firstareaportal;
-} sin_darea_t;
diff --git a/code/bspc/tetrahedron.c b/code/bspc/tetrahedron.c
deleted file mode 100644
index b5357c1..0000000
--- a/code/bspc/tetrahedron.c
+++ /dev/null
@@ -1,1389 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-#include "qbsp.h"
-#include "l_mem.h"
-#include "../botlib/aasfile.h"
-#include "aas_store.h"
-#include "aas_cfg.h"
-#include "aas_file.h"
-
-//
-// creating tetrahedrons from a arbitrary world bounded by triangles
-//
-// a triangle has 3 corners and 3 edges
-// a tetrahedron is build out of 4 triangles
-// a tetrahedron has 6 edges
-// we start with a world bounded by triangles, a side of a triangle facing
-// towards the oudside of the world is marked as part of tetrahedron -1
-//
-// a tetrahedron is defined by two non-coplanar triangles with a shared edge
-//
-// a tetrahedron is defined by one triangle and a vertex not in the triangle plane
-//
-// if all triangles using a specific vertex have tetrahedrons
-// at both sides then this vertex will never be part of a new tetrahedron
-//
-// if all triangles using a specific edge have tetrahedrons
-// at both sides then this vertex will never be part of a new tetrahedron
-//
-// each triangle can only be shared by two tetrahedrons
-// when all triangles have tetrahedrons at both sides then we're done
-//
-// if we cannot create any new tetrahedrons and there is at least one triangle
-// which has a tetrahedron only at one side then the world leaks
-//
-
-#define Sign(x) (x < 0 ? 1 : 0)
-
-#define MAX_TH_VERTEXES 128000
-#define MAX_TH_PLANES 128000
-#define MAX_TH_EDGES 512000
-#define MAX_TH_TRIANGLES 51200
-#define MAX_TH_TETRAHEDRONS 12800
-
-#define PLANEHASH_SIZE 1024
-#define EDGEHASH_SIZE 1024
-#define TRIANGLEHASH_SIZE 1024
-#define VERTEXHASH_SHIFT 7
-#define VERTEXHASH_SIZE ((MAX_MAP_BOUNDS>>(VERTEXHASH_SHIFT-1))+1) //was 64
-
-#define NORMAL_EPSILON 0.0001
-#define DIST_EPSILON 0.1
-#define VERTEX_EPSILON 0.01
-#define INTEGRAL_EPSILON 0.01
-
-
-//plane
-typedef struct th_plane_s
-{
- vec3_t normal;
- float dist;
- int type;
- int signbits;
- struct th_plane_s *hashnext; //next plane in hash
-} th_plane_t;
-
-//vertex
-typedef struct th_vertex_s
-{
- vec3_t v;
- int usercount; //2x the number of to be processed
- //triangles using this vertex
- struct th_vertex_s *hashnext; //next vertex in hash
-} th_vertex_t;
-
-//edge
-typedef struct th_edge_s
-{
- int v[2]; //vertex indexes
- int usercount; //number of to be processed
- //triangles using this edge
- struct th_edge_s *hashnext; //next edge in hash
-} th_edge_t;
-
-//triangle
-typedef struct th_triangle_s
-{
- int edges[3]; //negative if edge is flipped
- th_plane_t planes[3]; //triangle bounding planes
- int planenum; //plane the triangle is in
- int front; //tetrahedron at the front
- int back; //tetrahedron at the back
- vec3_t mins, maxs; //triangle bounding box
- struct th_triangle_s *prev, *next; //links in linked triangle lists
- struct th_triangle_s *hashnext; //next triangle in hash
-} th_triangle_t;
-
-//tetrahedron
-typedef struct th_tetrahedron_s
-{
- int triangles[4]; //negative if at backside of triangle
- float volume; //tetrahedron volume
-} th_tetrahedron_t;
-
-typedef struct th_s
-{
- //vertexes
- int numvertexes;
- th_vertex_t *vertexes;
- th_vertex_t *vertexhash[VERTEXHASH_SIZE * VERTEXHASH_SIZE];
- //planes
- int numplanes;
- th_plane_t *planes;
- th_plane_t *planehash[PLANEHASH_SIZE];
- //edges
- int numedges;
- th_edge_t *edges;
- th_edge_t *edgehash[EDGEHASH_SIZE];
- //triangles
- int numtriangles;
- th_triangle_t *triangles;
- th_triangle_t *trianglehash[TRIANGLEHASH_SIZE];
- //tetrahedrons
- int numtetrahedrons;
- th_tetrahedron_t *tetrahedrons;
-} th_t;
-
-th_t thworld;
-
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void TH_InitMaxTH(void)
-{
- //get memory for the tetrahedron data
- thworld.vertexes = (th_vertex_t *) GetClearedMemory(MAX_TH_VERTEXES * sizeof(th_vertex_t));
- thworld.planes = (th_plane_t *) GetClearedMemory(MAX_TH_PLANES * sizeof(th_plane_t));
- thworld.edges = (th_edge_t *) GetClearedMemory(MAX_TH_EDGES * sizeof(th_edge_t));
- thworld.triangles = (th_triangle_t *) GetClearedMemory(MAX_TH_TRIANGLES * sizeof(th_triangle_t));
- thworld.tetrahedrons = (th_tetrahedron_t *) GetClearedMemory(MAX_TH_TETRAHEDRONS * sizeof(th_tetrahedron_t));
- //reset the hash tables
- memset(thworld.vertexhash, 0, VERTEXHASH_SIZE * sizeof(th_vertex_t *));
- memset(thworld.planehash, 0, PLANEHASH_SIZE * sizeof(th_plane_t *));
- memset(thworld.edgehash, 0, EDGEHASH_SIZE * sizeof(th_edge_t *));
- memset(thworld.trianglehash, 0, TRIANGLEHASH_SIZE * sizeof(th_triangle_t *));
-} //end of the function TH_InitMaxTH
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void TH_FreeMaxTH(void)
-{
- if (thworld.vertexes) FreeMemory(thworld.vertexes);
- thworld.vertexes = NULL;
- thworld.numvertexes = 0;
- if (thworld.planes) FreeMemory(thworld.planes);
- thworld.planes = NULL;
- thworld.numplanes = 0;
- if (thworld.edges) FreeMemory(thworld.edges);
- thworld.edges = NULL;
- thworld.numedges = 0;
- if (thworld.triangles) FreeMemory(thworld.triangles);
- thworld.triangles = NULL;
- thworld.numtriangles = 0;
- if (thworld.tetrahedrons) FreeMemory(thworld.tetrahedrons);
- thworld.tetrahedrons = NULL;
- thworld.numtetrahedrons = 0;
-} //end of the function TH_FreeMaxTH
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-float TH_TriangleArea(th_triangle_t *tri)
-{
- return 0;
-} //end of the function TH_TriangleArea
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-float TH_TetrahedronVolume(th_tetrahedron_t *tetrahedron)
-{
- int edgenum, verts[3], i, j, v2;
- float volume, d;
- th_triangle_t *tri, *tri2;
- th_plane_t *plane;
-
- tri = &thworld.triangles[abs(tetrahedron->triangles[0])];
- for (i = 0; i < 3; i++)
- {
- edgenum = tri->edges[i];
- if (edgenum < 0) verts[i] = thworld.edges[abs(edgenum)].v[1];
- else verts[i] = thworld.edges[edgenum].v[0];
- } //end for
- //
- tri2 = &thworld.triangles[abs(tetrahedron->triangles[1])];
- for (j = 0; j < 3; j++)
- {
- edgenum = tri2->edges[i];
- if (edgenum < 0) v2 = thworld.edges[abs(edgenum)].v[1];
- else v2 = thworld.edges[edgenum].v[0];
- if (v2 != verts[0] &&
- v2 != verts[1] &&
- v2 != verts[2]) break;
- } //end for
-
- plane = &thworld.planes[tri->planenum];
- d = -(DotProduct (thworld.vertexes[v2].v, plane->normal) - plane->dist);
- volume = TH_TriangleArea(tri) * d / 3;
- return volume;
-} //end of the function TH_TetrahedronVolume
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int TH_PlaneSignBits(vec3_t normal)
-{
- int i, signbits;
-
- signbits = 0;
- for (i = 2; i >= 0; i--)
- {
- signbits = (signbits << 1) + Sign(normal[i]);
- } //end for
- return signbits;
-} //end of the function TH_PlaneSignBits
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int TH_PlaneTypeForNormal(vec3_t normal)
-{
- vec_t ax, ay, az;
-
-// NOTE: should these have an epsilon around 1.0?
- if (normal[0] == 1.0 || normal[0] == -1.0)
- return PLANE_X;
- if (normal[1] == 1.0 || normal[1] == -1.0)
- return PLANE_Y;
- if (normal[2] == 1.0 || normal[2] == -1.0)
- return PLANE_Z;
-
- ax = fabs(normal[0]);
- ay = fabs(normal[1]);
- az = fabs(normal[2]);
-
- if (ax >= ay && ax >= az)
- return PLANE_ANYX;
- if (ay >= ax && ay >= az)
- return PLANE_ANYY;
- return PLANE_ANYZ;
-} //end of the function TH_PlaneTypeForNormal
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-qboolean TH_PlaneEqual(th_plane_t *p, vec3_t normal, vec_t dist)
-{
- if (
- fabs(p->normal[0] - normal[0]) < NORMAL_EPSILON
- && fabs(p->normal[1] - normal[1]) < NORMAL_EPSILON
- && fabs(p->normal[2] - normal[2]) < NORMAL_EPSILON
- && fabs(p->dist - dist) < DIST_EPSILON )
- return true;
- return false;
-} //end of the function TH_PlaneEqual
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void TH_AddPlaneToHash(th_plane_t *p)
-{
- int hash;
-
- hash = (int)fabs(p->dist) / 8;
- hash &= (PLANEHASH_SIZE-1);
-
- p->hashnext = thworld.planehash[hash];
- thworld.planehash[hash] = p;
-} //end of the function TH_AddPlaneToHash
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int TH_CreateFloatPlane(vec3_t normal, vec_t dist)
-{
- th_plane_t *p, temp;
-
- if (VectorLength(normal) < 0.5)
- Error ("FloatPlane: bad normal");
- // create a new plane
- if (thworld.numplanes+2 > MAX_TH_PLANES)
- Error ("MAX_TH_PLANES");
-
- p = &thworld.planes[thworld.numplanes];
- VectorCopy (normal, p->normal);
- p->dist = dist;
- p->type = (p+1)->type = TH_PlaneTypeForNormal (p->normal);
- p->signbits = TH_PlaneSignBits(p->normal);
-
- VectorSubtract (vec3_origin, normal, (p+1)->normal);
- (p+1)->dist = -dist;
- (p+1)->signbits = TH_PlaneSignBits((p+1)->normal);
-
- thworld.numplanes += 2;
-
- // allways put axial planes facing positive first
- if (p->type < 3)
- {
- if (p->normal[0] < 0 || p->normal[1] < 0 || p->normal[2] < 0)
- {
- // flip order
- temp = *p;
- *p = *(p+1);
- *(p+1) = temp;
-
- TH_AddPlaneToHash(p);
- TH_AddPlaneToHash(p+1);
- return thworld.numplanes - 1;
- } //end if
- } //end if
-
- TH_AddPlaneToHash(p);
- TH_AddPlaneToHash(p+1);
- return thworld.numplanes - 2;
-} //end of the function TH_CreateFloatPlane
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void TH_SnapVector(vec3_t normal)
-{
- int i;
-
- for (i = 0; i < 3; i++)
- {
- if ( fabs(normal[i] - 1) < NORMAL_EPSILON )
- {
- VectorClear (normal);
- normal[i] = 1;
- break;
- } //end if
- if ( fabs(normal[i] - -1) < NORMAL_EPSILON )
- {
- VectorClear (normal);
- normal[i] = -1;
- break;
- } //end if
- } //end for
-} //end of the function TH_SnapVector
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void TH_SnapPlane(vec3_t normal, vec_t *dist)
-{
- TH_SnapVector(normal);
-
- if (fabs(*dist-Q_rint(*dist)) < DIST_EPSILON)
- *dist = Q_rint(*dist);
-} //end of the function TH_SnapPlane
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int TH_FindFloatPlane(vec3_t normal, vec_t dist)
-{
- int i;
- th_plane_t *p;
- int hash, h;
-
- TH_SnapPlane (normal, &dist);
- hash = (int)fabs(dist) / 8;
- hash &= (PLANEHASH_SIZE-1);
-
- // search the border bins as well
- for (i = -1; i <= 1; i++)
- {
- h = (hash+i)&(PLANEHASH_SIZE-1);
- for (p = thworld.planehash[h]; p; p = p->hashnext)
- {
- if (TH_PlaneEqual(p, normal, dist))
- {
- return p - thworld.planes;
- } //end if
- } //end for
- } //end for
- return TH_CreateFloatPlane(normal, dist);
-} //end of the function TH_FindFloatPlane
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int TH_PlaneFromPoints(int v1, int v2, int v3)
-{
- vec3_t t1, t2, normal;
- vec_t dist;
- float *p0, *p1, *p2;
-
- p0 = thworld.vertexes[v1].v;
- p1 = thworld.vertexes[v2].v;
- p2 = thworld.vertexes[v3].v;
-
- VectorSubtract(p0, p1, t1);
- VectorSubtract(p2, p1, t2);
- CrossProduct(t1, t2, normal);
- VectorNormalize(normal);
-
- dist = DotProduct(p0, normal);
-
- return TH_FindFloatPlane(normal, dist);
-} //end of the function TH_PlaneFromPoints
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void TH_AddEdgeUser(int edgenum)
-{
- th_edge_t *edge;
-
- edge = &thworld.edges[abs(edgenum)];
- //increase edge user count
- edge->usercount++;
- //increase vertex user count as well
- thworld.vertexes[edge->v[0]].usercount++;
- thworld.vertexes[edge->v[1]].usercount++;
-} //end of the function TH_AddEdgeUser
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void TH_RemoveEdgeUser(int edgenum)
-{
- th_edge_t *edge;
-
- edge = &thworld.edges[abs(edgenum)];
- //decrease edge user count
- edge->usercount--;
- //decrease vertex user count as well
- thworld.vertexes[edge->v[0]].usercount--;
- thworld.vertexes[edge->v[1]].usercount--;
-} //end of the function TH_RemoveEdgeUser
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void TH_FreeTriangleEdges(th_triangle_t *tri)
-{
- int i;
-
- for (i = 0; i < 3; i++)
- {
- TH_RemoveEdgeUser(abs(tri->edges[i]));
- } //end for
-} //end of the function TH_FreeTriangleEdges
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-unsigned TH_HashVec(vec3_t vec)
-{
- int x, y;
-
- x = (MAX_MAP_BOUNDS + (int)(vec[0]+0.5)) >> VERTEXHASH_SHIFT;
- y = (MAX_MAP_BOUNDS + (int)(vec[1]+0.5)) >> VERTEXHASH_SHIFT;
-
- if (x < 0 || x >= VERTEXHASH_SIZE || y < 0 || y >= VERTEXHASH_SIZE)
- Error("HashVec: point %f %f %f outside valid range", vec[0], vec[1], vec[2]);
-
- return y*VERTEXHASH_SIZE + x;
-} //end of the function TH_HashVec
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int TH_FindVertex(vec3_t v)
-{
- int i, h;
- th_vertex_t *vertex;
- vec3_t vert;
-
- for (i = 0; i < 3; i++)
- {
- if ( fabs(v[i] - Q_rint(v[i])) < INTEGRAL_EPSILON)
- vert[i] = Q_rint(v[i]);
- else
- vert[i] = v[i];
- } //end for
-
- h = TH_HashVec(vert);
-
- for (vertex = thworld.vertexhash[h]; vertex; vertex = vertex->hashnext)
- {
- if (fabs(vertex->v[0] - vert[0]) < VERTEX_EPSILON &&
- fabs(vertex->v[1] - vert[1]) < VERTEX_EPSILON &&
- fabs(vertex->v[2] - vert[2]) < VERTEX_EPSILON)
- {
- return vertex - thworld.vertexes;
- } //end if
- } //end for
- return 0;
-} //end of the function TH_FindVertex
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void TH_AddVertexToHash(th_vertex_t *vertex)
-{
- int hashvalue;
-
- hashvalue = TH_HashVec(vertex->v);
- vertex->hashnext = thworld.vertexhash[hashvalue];
- thworld.vertexhash[hashvalue] = vertex;
-} //end of the function TH_AddVertexToHash
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int TH_CreateVertex(vec3_t v)
-{
- if (thworld.numvertexes == 0) thworld.numvertexes = 1;
- if (thworld.numvertexes >= MAX_TH_VERTEXES)
- Error("MAX_TH_VERTEXES");
- VectorCopy(v, thworld.vertexes[thworld.numvertexes].v);
- thworld.vertexes[thworld.numvertexes].usercount = 0;
- TH_AddVertexToHash(&thworld.vertexes[thworld.numvertexes]);
- thworld.numvertexes++;
- return thworld.numvertexes-1;
-} //end of the function TH_CreateVertex
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int TH_FindOrCreateVertex(vec3_t v)
-{
- int vertexnum;
-
- vertexnum = TH_FindVertex(v);
- if (!vertexnum) vertexnum = TH_CreateVertex(v);
- return vertexnum;
-} //end of the function TH_FindOrCreateVertex
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int TH_FindEdge(int v1, int v2)
-{
- int hashvalue;
- th_edge_t *edge;
-
- hashvalue = (v1 + v2) & (EDGEHASH_SIZE-1);
-
- for (edge = thworld.edgehash[hashvalue]; edge; edge = edge->hashnext)
- {
- if (edge->v[0] == v1 && edge->v[1] == v2) return edge - thworld.edges;
- if (edge->v[1] == v1 && edge->v[0] == v2) return -(edge - thworld.edges);
- } //end for
- return 0;
-} //end of the function TH_FindEdge
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void TH_AddEdgeToHash(th_edge_t *edge)
-{
- int hashvalue;
-
- hashvalue = (edge->v[0] + edge->v[1]) & (EDGEHASH_SIZE-1);
- edge->hashnext = thworld.edgehash[hashvalue];
- thworld.edgehash[hashvalue] = edge;
-} //end of the function TH_AddEdgeToHash
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int TH_CreateEdge(int v1, int v2)
-{
- th_edge_t *edge;
-
- if (thworld.numedges == 0) thworld.numedges = 1;
- if (thworld.numedges >= MAX_TH_EDGES)
- Error("MAX_TH_EDGES");
- edge = &thworld.edges[thworld.numedges++];
- edge->v[0] = v1;
- edge->v[1] = v2;
- TH_AddEdgeToHash(edge);
- return thworld.numedges-1;
-} //end of the function TH_CreateEdge
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int TH_FindOrCreateEdge(int v1, int v2)
-{
- int edgenum;
-
- edgenum = TH_FindEdge(v1, v2);
- if (!edgenum) edgenum = TH_CreateEdge(v1, v2);
- return edgenum;
-} //end of the function TH_FindOrCreateEdge
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int TH_FindTriangle(int verts[3])
-{
- int i, hashvalue, edges[3];
- th_triangle_t *tri;
-
- for (i = 0; i < 3; i++)
- {
- edges[i] = TH_FindEdge(verts[i], verts[(i+1)%3]);
- if (!edges[i]) return false;
- } //end for
- hashvalue = (abs(edges[0]) + abs(edges[1]) + abs(edges[2])) & (TRIANGLEHASH_SIZE-1);
- for (tri = thworld.trianglehash[hashvalue]; tri; tri = tri->next)
- {
- for (i = 0; i < 3; i++)
- {
- if (abs(tri->edges[i]) != abs(edges[0]) &&
- abs(tri->edges[i]) != abs(edges[1]) &&
- abs(tri->edges[i]) != abs(edges[2])) break;
- } //end for
- if (i >= 3) return tri - thworld.triangles;
- } //end for
- return 0;
-} //end of the function TH_FindTriangle
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void TH_AddTriangleToHash(th_triangle_t *tri)
-{
- int hashvalue;
-
- hashvalue = (abs(tri->edges[0]) + abs(tri->edges[1]) + abs(tri->edges[2])) & (TRIANGLEHASH_SIZE-1);
- tri->hashnext = thworld.trianglehash[hashvalue];
- thworld.trianglehash[hashvalue] = tri;
-} //end of the function TH_AddTriangleToHash
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void TH_CreateTrianglePlanes(int verts[3], th_plane_t *triplane, th_plane_t *planes)
-{
- int i;
- vec3_t dir;
-
- for (i = 0; i < 3; i++)
- {
- VectorSubtract(thworld.vertexes[verts[(i+1)%3]].v, thworld.vertexes[verts[i]].v, dir);
- CrossProduct(dir, triplane->normal, planes[i].normal);
- VectorNormalize(planes[i].normal);
- planes[i].dist = DotProduct(thworld.vertexes[verts[i]].v, planes[i].normal);
- } //end for
-} //end of the function TH_CreateTrianglePlanes
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int TH_CreateTriangle(int verts[3])
-{
- th_triangle_t *tri;
- int i;
-
- if (thworld.numtriangles == 0) thworld.numtriangles = 1;
- if (thworld.numtriangles >= MAX_TH_TRIANGLES)
- Error("MAX_TH_TRIANGLES");
- tri = &thworld.triangles[thworld.numtriangles++];
- for (i = 0; i < 3; i++)
- {
- tri->edges[i] = TH_FindOrCreateEdge(verts[i], verts[(i+1)%3]);
- TH_AddEdgeUser(abs(tri->edges[i]));
- } //end for
- tri->front = 0;
- tri->back = 0;
- tri->planenum = TH_PlaneFromPoints(verts[0], verts[1], verts[2]);
- tri->prev = NULL;
- tri->next = NULL;
- tri->hashnext = NULL;
- TH_CreateTrianglePlanes(verts, &thworld.planes[tri->planenum], tri->planes);
- TH_AddTriangleToHash(tri);
- ClearBounds(tri->mins, tri->maxs);
- for (i = 0; i < 3; i++)
- {
- AddPointToBounds(thworld.vertexes[verts[i]].v, tri->mins, tri->maxs);
- } //end for
- return thworld.numtriangles-1;
-} //end of the function TH_CreateTriangle
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int TH_CreateTetrahedron(int triangles[4])
-{
- th_tetrahedron_t *tetrahedron;
- int i;
-
- if (thworld.numtetrahedrons == 0) thworld.numtetrahedrons = 1;
- if (thworld.numtetrahedrons >= MAX_TH_TETRAHEDRONS)
- Error("MAX_TH_TETRAHEDRONS");
- tetrahedron = &thworld.tetrahedrons[thworld.numtetrahedrons++];
- for (i = 0; i < 4; i++)
- {
- tetrahedron->triangles[i] = triangles[i];
- if (thworld.triangles[abs(triangles[i])].front)
- {
- thworld.triangles[abs(triangles[i])].back = thworld.numtetrahedrons-1;
- } //end if
- else
- {
- thworld.triangles[abs(triangles[i])].front = thworld.numtetrahedrons-1;
- } //end else
- } //end for
- tetrahedron->volume = 0;
- return thworld.numtetrahedrons-1;
-} //end of the function TH_CreateTetrahedron
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int TH_IntersectTrianglePlanes(int v1, int v2, th_plane_t *triplane, th_plane_t *planes)
-{
- float *p1, *p2, front, back, frac, d;
- int i, side, lastside;
- vec3_t mid;
-
- p1 = thworld.vertexes[v1].v;
- p2 = thworld.vertexes[v2].v;
-
- front = DotProduct(p1, triplane->normal) - triplane->dist;
- back = DotProduct(p2, triplane->normal) - triplane->dist;
- //if both points at the same side of the plane
- if (front < 0.1 && back < 0.1) return false;
- if (front > -0.1 && back > -0.1) return false;
- //
- frac = front/(front-back);
- mid[0] = p1[0] + (p2[0] - p1[0]) * frac;
- mid[1] = p1[1] + (p2[1] - p1[1]) * frac;
- mid[2] = p1[2] + (p2[2] - p1[2]) * frac;
- //if the mid point is at the same side of all the tri bounding planes
- lastside = 0;
- for (i = 0; i < 3; i++)
- {
- d = DotProduct(mid, planes[i].normal) - planes[i].dist;
- side = d < 0;
- if (i && side != lastside) return false;
- lastside = side;
- } //end for
- return true;
-} //end of the function TH_IntersectTrianglePlanes
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int TH_OutsideBoundingBox(int v1, int v2, vec3_t mins, vec3_t maxs)
-{
- float *p1, *p2;
- int i;
-
- p1 = thworld.vertexes[v1].v;
- p2 = thworld.vertexes[v2].v;
- //if both points are at the outer side of one of the bounding box planes
- for (i = 0; i < 3; i++)
- {
- if (p1[i] < mins[i] && p2[i] < mins[i]) return true;
- if (p1[i] > maxs[i] && p2[i] > maxs[i]) return true;
- } //end for
- return false;
-} //end of the function TH_OutsideBoundingBox
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int TH_TryEdge(int v1, int v2)
-{
- int i, j, v;
- th_plane_t *plane;
- th_triangle_t *tri;
-
- //if the edge already exists it must be valid
- if (TH_FindEdge(v1, v2)) return true;
- //test the edge with all existing triangles
- for (i = 1; i < thworld.numtriangles; i++)
- {
- tri = &thworld.triangles[i];
- //if triangle is enclosed by two tetrahedrons we don't have to test it
- //because the edge always has to go through another triangle of those
- //tetrahedrons first to reach the enclosed triangle
- if (tri->front && tri->back) continue;
- //if the edges is totally outside the triangle bounding box
- if (TH_OutsideBoundingBox(v1, v2, tri->mins, tri->maxs)) continue;
- //if one of the edge vertexes is used by this triangle
- for (j = 0; j < 3; j++)
- {
- v = thworld.edges[abs(tri->edges[j])].v[tri->edges[j] < 0];
- if (v == v1 || v == v2) break;
- } //end for
- if (j < 3) continue;
- //get the triangle plane
- plane = &thworld.planes[tri->planenum];
- //if the edge intersects with a triangle then it's not valid
- if (TH_IntersectTrianglePlanes(v1, v2, plane, tri->planes)) return false;
- } //end for
- return true;
-} //end of the function TH_TryEdge
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int TH_TryTriangle(int verts[3])
-{
- th_plane_t planes[3], triplane;
- vec3_t t1, t2;
- float *p0, *p1, *p2;
- int i, j;
-
- p0 = thworld.vertexes[verts[0]].v;
- p1 = thworld.vertexes[verts[1]].v;
- p2 = thworld.vertexes[verts[2]].v;
-
- VectorSubtract(p0, p1, t1);
- VectorSubtract(p2, p1, t2);
- CrossProduct(t1, t2, triplane.normal);
- VectorNormalize(triplane.normal);
- triplane.dist = DotProduct(p0, triplane.normal);
- //
- TH_CreateTrianglePlanes(verts, &triplane, planes);
- //test if any existing edge intersects with this triangle
- for (i = 1; i < thworld.numedges; i++)
- {
- //if the edge is only used by triangles with tetrahedrons at both sides
- if (!thworld.edges[i].usercount) continue;
- //if one of the triangle vertexes is used by this edge
- for (j = 0; j < 3; j++)
- {
- if (verts[j] == thworld.edges[j].v[0] ||
- verts[j] == thworld.edges[j].v[1]) break;
- } //end for
- if (j < 3) continue;
- //if this edge intersects with the triangle
- if (TH_IntersectTrianglePlanes(thworld.edges[i].v[0], thworld.edges[i].v[1], &triplane, planes)) return false;
- } //end for
- return true;
-} //end of the function TH_TryTriangle
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void TH_AddTriangleToList(th_triangle_t **trianglelist, th_triangle_t *tri)
-{
- tri->prev = NULL;
- tri->next = *trianglelist;
- if (*trianglelist) (*trianglelist)->prev = tri;
- *trianglelist = tri;
-} //end of the function TH_AddTriangleToList
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void TH_RemoveTriangleFromList(th_triangle_t **trianglelist, th_triangle_t *tri)
-{
- if (tri->next) tri->next->prev = tri->prev;
- if (tri->prev) tri->prev->next = tri->next;
- else *trianglelist = tri->next;
-} //end of the function TH_RemoveTriangleFromList
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int TH_FindTetrahedron1(th_triangle_t *tri, int *triangles)
-{
- int i, j, edgenum, side, v1, v2, v3, v4;
- int verts1[3], verts2[3];
- th_triangle_t *tri2;
-
- //find another triangle with a shared edge
- for (tri2 = tri->next; tri2; tri2 = tri2->next)
- {
- //if the triangles are in the same plane
- if ((tri->planenum & ~1) == (tri2->planenum & ~1)) continue;
- //try to find a shared edge
- for (i = 0; i < 3; i++)
- {
- edgenum = abs(tri->edges[i]);
- for (j = 0; j < 3; j++)
- {
- if (edgenum == abs(tri2->edges[j])) break;
- } //end for
- if (j < 3) break;
- } //end for
- //if the triangles have a shared edge
- if (i < 3)
- {
- edgenum = tri->edges[(i+1)%3];
- if (edgenum < 0) v1 = thworld.edges[abs(edgenum)].v[0];
- else v1 = thworld.edges[edgenum].v[1];
- edgenum = tri2->edges[(j+1)%3];
- if (edgenum < 0) v2 = thworld.edges[abs(edgenum)].v[0];
- else v2 = thworld.edges[edgenum].v[1];
- //try the new edge
- if (TH_TryEdge(v1, v2))
- {
- edgenum = tri->edges[i];
- side = edgenum < 0;
- //get the vertexes of the shared edge
- v3 = thworld.edges[abs(edgenum)].v[side];
- v4 = thworld.edges[abs(edgenum)].v[!side];
- //try the two new triangles
- verts1[0] = v1;
- verts1[1] = v2;
- verts1[2] = v3;
- triangles[2] = TH_FindTriangle(verts1);
- if (triangles[2] || TH_TryTriangle(verts1))
- {
- verts2[0] = v2;
- verts2[1] = v1;
- verts2[2] = v4;
- triangles[3] = TH_FindTriangle(verts2);
- if (triangles[3] || TH_TryTriangle(verts2))
- {
- triangles[0] = tri - thworld.triangles;
- triangles[1] = tri2 - thworld.triangles;
- if (!triangles[2]) triangles[2] = TH_CreateTriangle(verts1);
- if (!triangles[3]) triangles[3] = TH_CreateTriangle(verts2);
- return true;
- } //end if
- } //end if
- } //end if
- } //end if
- } //end for
- return false;
-} //end of the function TH_FindTetrahedron
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int TH_FindTetrahedron2(th_triangle_t *tri, int *triangles)
-{
- int i, edgenum, v1, verts[3], triverts[3];
- float d;
- th_plane_t *plane;
-
- //get the verts of this triangle
- for (i = 0; i < 3; i++)
- {
- edgenum = tri->edges[i];
- if (edgenum < 0) verts[i] = thworld.edges[abs(edgenum)].v[1];
- else verts[i] = thworld.edges[edgenum].v[0];
- } //end for
- //
- plane = &thworld.planes[tri->planenum];
- for (v1 = 0; v1 < thworld.numvertexes; v1++)
- {
- //if the vertex is only used by triangles with tetrahedrons at both sides
- if (!thworld.vertexes[v1].usercount) continue;
- //check if the vertex is not coplanar with the triangle
- d = DotProduct(thworld.vertexes[v1].v, plane->normal) - plane->dist;
- if (fabs(d) < 1) continue;
- //check if we can create edges from the triangle towards this new vertex
- for (i = 0; i < 3; i++)
- {
- if (v1 == verts[i]) break;
- if (!TH_TryEdge(v1, verts[i])) break;
- } //end for
- if (i < 3) continue;
- //check if the triangles are valid
- for (i = 0; i < 3; i++)
- {
- triverts[0] = v1;
- triverts[1] = verts[i];
- triverts[2] = verts[(i+1)%3];
- //if the triangle already exists then it is valid
- triangles[i] = TH_FindTriangle(triverts);
- if (!triangles[i])
- {
- if (!TH_TryTriangle(triverts)) break;
- } //end if
- } //end for
- if (i < 3) continue;
- //create the tetrahedron triangles using the new vertex
- for (i = 0; i < 3; i++)
- {
- if (!triangles[i])
- {
- triverts[0] = v1;
- triverts[1] = verts[i];
- triverts[2] = verts[(i+1)%3];
- triangles[i] = TH_CreateTriangle(triverts);
- } //end if
- } //end for
- //add the existing triangle
- triangles[3] = tri - thworld.triangles;
- //
- return true;
- } //end for
- return false;
-} //end of the function TH_FindTetrahedron2
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void TH_TetrahedralDecomposition(th_triangle_t *triangles)
-{
- int i, thtriangles[4], numtriangles;
- th_triangle_t *donetriangles, *tri;
-
- donetriangles = NULL;
-
- /*
- numtriangles = 0;
- qprintf("%6d triangles", numtriangles);
- for (tri = triangles; tri; tri = triangles)
- {
- qprintf("\r%6d", numtriangles++);
- if (!TH_FindTetrahedron1(tri, thtriangles))
- {
-// if (!TH_FindTetrahedron2(tri, thtriangles))
- {
-// Error("triangle without tetrahedron");
- TH_RemoveTriangleFromList(&triangles, tri);
- continue;
- } //end if
- } //end if
- //create a tetrahedron from the triangles
- TH_CreateTetrahedron(thtriangles);
- //
- for (i = 0; i < 4; i++)
- {
- if (thworld.triangles[abs(thtriangles[i])].front &&
- thworld.triangles[abs(thtriangles[i])].back)
- {
- TH_RemoveTriangleFromList(&triangles, &thworld.triangles[abs(thtriangles[i])]);
- TH_AddTriangleToList(&donetriangles, &thworld.triangles[abs(thtriangles[i])]);
- TH_FreeTriangleEdges(&thworld.triangles[abs(thtriangles[i])]);
- } //end if
- else
- {
- TH_AddTriangleToList(&triangles, &thworld.triangles[abs(thtriangles[i])]);
- } //end else
- } //end for
- } //end for*/
- qprintf("%6d tetrahedrons", thworld.numtetrahedrons);
- do
- {
- do
- {
- numtriangles = 0;
- for (i = 1; i < thworld.numtriangles; i++)
- {
- tri = &thworld.triangles[i];
- if (tri->front && tri->back) continue;
- //qprintf("\r%6d", numtriangles++);
- if (!TH_FindTetrahedron1(tri, thtriangles))
- {
-// if (!TH_FindTetrahedron2(tri, thtriangles))
- {
- continue;
- } //end if
- } //end if
- numtriangles++;
- //create a tetrahedron from the triangles
- TH_CreateTetrahedron(thtriangles);
- qprintf("\r%6d", thworld.numtetrahedrons);
- } //end for
- } while(numtriangles);
- for (i = 1; i < thworld.numtriangles; i++)
- {
- tri = &thworld.triangles[i];
- if (tri->front && tri->back) continue;
- //qprintf("\r%6d", numtriangles++);
-// if (!TH_FindTetrahedron1(tri, thtriangles))
- {
- if (!TH_FindTetrahedron2(tri, thtriangles))
- {
- continue;
- } //end if
- } //end if
- numtriangles++;
- //create a tetrahedron from the triangles
- TH_CreateTetrahedron(thtriangles);
- qprintf("\r%6d", thworld.numtetrahedrons);
- } //end for
- } while(numtriangles);
- //
- numtriangles = 0;
- for (i = 1; i < thworld.numtriangles; i++)
- {
- tri = &thworld.triangles[i];
- if (!tri->front && !tri->back) numtriangles++;
- } //end for
- Log_Print("\r%6d triangles with front only\n", numtriangles);
- Log_Print("\r%6d tetrahedrons\n", thworld.numtetrahedrons-1);
-} //end of the function TH_TetrahedralDecomposition
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void TH_AASFaceVertex(aas_face_t *face, int index, vec3_t vertex)
-{
- int edgenum, side;
-
- edgenum = aasworld.edgeindex[face->firstedge + index];
- side = edgenum < 0;
- VectorCopy(aasworld.vertexes[aasworld.edges[abs(edgenum)].v[side]], vertex);
-} //end of the function TH_AASFaceVertex
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int TH_Colinear(float *v0, float *v1, float *v2)
-{
- vec3_t t1, t2, vcross;
- float d;
-
- VectorSubtract(v1, v0, t1);
- VectorSubtract(v2, v0, t2);
- CrossProduct (t1, t2, vcross);
- d = VectorLength( vcross );
-
- // if cross product is zero point is colinear
- if (d < 10)
- {
- return true;
- } //end if
- return false;
-} //end of the function TH_Colinear
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void TH_FaceCenter(aas_face_t *face, vec3_t center)
-{
- int i, edgenum, side;
- aas_edge_t *edge;
-
- VectorClear(center);
- for (i = 0; i < face->numedges; i++)
- {
- edgenum = abs(aasworld.edgeindex[face->firstedge + i]);
- side = edgenum < 0;
- edge = &aasworld.edges[abs(edgenum)];
- VectorAdd(aasworld.vertexes[edge->v[side]], center, center);
- } //end for
- VectorScale(center, 1.0 / face->numedges, center);
-} //end of the function TH_FaceCenter
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-th_triangle_t *TH_CreateAASFaceTriangles(aas_face_t *face)
-{
- int i, first, verts[3], trinum;
- vec3_t p0, p1, p2, p3, p4, center;
- th_triangle_t *tri, *triangles;
-
- triangles = NULL;
- //find three points that are not colinear
- for (i = 0; i < face->numedges; i++)
- {
- TH_AASFaceVertex(face, (face->numedges + i-2)%face->numedges, p0);
- TH_AASFaceVertex(face, (face->numedges + i-1)%face->numedges, p1);
- TH_AASFaceVertex(face, (i )%face->numedges, p2);
- if (TH_Colinear(p2, p0, p1)) continue;
- TH_AASFaceVertex(face, (i+1)%face->numedges, p3);
- TH_AASFaceVertex(face, (i+2)%face->numedges, p4);
- if (TH_Colinear(p2, p3, p4)) continue;
- break;
- } //end for
- //if there are three points that are not colinear
- if (i < face->numedges)
- {
- //normal triangulation
- first = i; //left and right most point of three non-colinear points
- TH_AASFaceVertex(face, first, p0);
- verts[0] = TH_FindOrCreateVertex(p0);
- for (i = 1; i < face->numedges-1; i++)
- {
- TH_AASFaceVertex(face, (first+i )%face->numedges, p1);
- TH_AASFaceVertex(face, (first+i+1)%face->numedges, p2);
- verts[1] = TH_FindOrCreateVertex(p1);
- verts[2] = TH_FindOrCreateVertex(p2);
- trinum = TH_CreateTriangle(verts);
- tri = &thworld.triangles[trinum];
- tri->front = -1;
- TH_AddTriangleToList(&triangles, tri);
- } //end for
- } //end if
- else
- {
- //fan triangulation
- TH_FaceCenter(face, center);
- //
- verts[0] = TH_FindOrCreateVertex(center);
- for (i = 0; i < face->numedges; i++)
- {
- TH_AASFaceVertex(face, (i )%face->numedges, p1);
- TH_AASFaceVertex(face, (i+1)%face->numedges, p2);
- if (TH_Colinear(center, p1, p2)) continue;
- verts[1] = TH_FindOrCreateVertex(p1);
- verts[2] = TH_FindOrCreateVertex(p2);
- trinum = TH_CreateTriangle(verts);
- tri = &thworld.triangles[trinum];
- tri->front = -1;
- TH_AddTriangleToList(&triangles, tri);
- } //end for
- } //end else
- return triangles;
-} //end of the function TH_CreateAASFaceTriangles
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-th_triangle_t *TH_AASToTriangleMesh(void)
-{
- int i, j, facenum, otherareanum;
- aas_face_t *face;
- th_triangle_t *tri, *nexttri, *triangles;
-
- triangles = NULL;
- for (i = 1; i < aasworld.numareas; i++)
- {
- //if (!(aasworld.areasettings[i].presencetype & PRESENCE_NORMAL)) continue;
- for (j = 0; j < aasworld.areas[i].numfaces; j++)
- {
- facenum = abs(aasworld.faceindex[aasworld.areas[i].firstface + j]);
- face = &aasworld.faces[facenum];
- //only convert solid faces into triangles
- if (!(face->faceflags & FACE_SOLID))
- {
- /*
- if (face->frontarea == i) otherareanum = face->backarea;
- else otherareanum = face->frontarea;
- if (aasworld.areasettings[otherareanum].presencetype & PRESENCE_NORMAL) continue;
- */
- continue;
- } //end if
- //
- tri = TH_CreateAASFaceTriangles(face);
- for (; tri; tri = nexttri)
- {
- nexttri = tri->next;
- TH_AddTriangleToList(&triangles, tri);
- } //end for
- } //end if
- } //end for
- return triangles;
-} //end of the function TH_AASToTriangleMesh
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void TH_AASToTetrahedrons(char *filename)
-{
- th_triangle_t *triangles, *tri, *lasttri;
- int cnt;
-
- if (!AAS_LoadAASFile(filename, 0, 0))
- Error("couldn't load %s\n", filename);
-
- //
- TH_InitMaxTH();
- //create a triangle mesh from the solid faces in the AAS file
- triangles = TH_AASToTriangleMesh();
- //
- cnt = 0;
- lasttri = NULL;
- for (tri = triangles; tri; tri = tri->next)
- {
- cnt++;
- if (tri->prev != lasttri) Log_Print("BAH\n");
- lasttri = tri;
- } //end for
- Log_Print("%6d triangles\n", cnt);
- //create a tetrahedral decomposition of the world bounded by triangles
- TH_TetrahedralDecomposition(triangles);
- //
- TH_FreeMaxTH();
-} //end of the function TH_AASToTetrahedrons
diff --git a/code/bspc/tetrahedron.h b/code/bspc/tetrahedron.h
deleted file mode 100644
index bd70802..0000000
--- a/code/bspc/tetrahedron.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-void TH_AASToTetrahedrons(char *filename);
-
diff --git a/code/bspc/textures.c b/code/bspc/textures.c
deleted file mode 100644
index d3b70ad..0000000
--- a/code/bspc/textures.c
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-#include "qbsp.h"
-#include "l_bsp_q2.h"
-
-int nummiptex;
-textureref_t textureref[MAX_MAP_TEXTURES];
-
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int FindMiptex (char *name)
-{
- int i;
- char path[1024];
- miptex_t *mt;
-
- for (i = 0; i < nummiptex; i++)
- {
- if (!strcmp (name, textureref[i].name))
- {
- return i;
- } //end if
- } //end for
- if (nummiptex == MAX_MAP_TEXTURES)
- Error ("MAX_MAP_TEXTURES");
- strcpy (textureref[i].name, name);
-
- // load the miptex to get the flags and values
- sprintf (path, "%stextures/%s.wal", gamedir, name);
- if (TryLoadFile (path, (void **)&mt) != -1)
- {
- textureref[i].value = LittleLong (mt->value);
- textureref[i].flags = LittleLong (mt->flags);
- textureref[i].contents = LittleLong (mt->contents);
- strcpy (textureref[i].animname, mt->animname);
- FreeMemory(mt);
- } //end if
- nummiptex++;
-
- if (textureref[i].animname[0])
- FindMiptex (textureref[i].animname);
-
- return i;
-} //end of the function FindMipTex
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-vec3_t baseaxis[18] =
-{
-{0,0,1}, {1,0,0}, {0,-1,0}, // floor
-{0,0,-1}, {1,0,0}, {0,-1,0}, // ceiling
-{1,0,0}, {0,1,0}, {0,0,-1}, // west wall
-{-1,0,0}, {0,1,0}, {0,0,-1}, // east wall
-{0,1,0}, {1,0,0}, {0,0,-1}, // south wall
-{0,-1,0}, {1,0,0}, {0,0,-1} // north wall
-};
-
-void TextureAxisFromPlane(plane_t *pln, vec3_t xv, vec3_t yv)
-{
- int bestaxis;
- vec_t dot,best;
- int i;
-
- best = 0;
- bestaxis = 0;
-
- for (i=0 ; i<6 ; i++)
- {
- dot = DotProduct (pln->normal, baseaxis[i*3]);
- if (dot > best)
- {
- best = dot;
- bestaxis = i;
- }
- }
-
- VectorCopy (baseaxis[bestaxis*3+1], xv);
- VectorCopy (baseaxis[bestaxis*3+2], yv);
-} //end of the function TextureAxisFromPlane
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int TexinfoForBrushTexture(plane_t *plane, brush_texture_t *bt, vec3_t origin)
-{
- vec3_t vecs[2];
- int sv, tv;
- vec_t ang, sinv, cosv;
- vec_t ns, nt;
- texinfo_t tx, *tc;
- int i, j, k;
- float shift[2];
- brush_texture_t anim;
- int mt;
-
- if (!bt->name[0])
- return 0;
-
- memset (&tx, 0, sizeof(tx));
- strcpy (tx.texture, bt->name);
-
- TextureAxisFromPlane(plane, vecs[0], vecs[1]);
-
- shift[0] = DotProduct (origin, vecs[0]);
- shift[1] = DotProduct (origin, vecs[1]);
-
- if (!bt->scale[0])
- bt->scale[0] = 1;
- if (!bt->scale[1])
- bt->scale[1] = 1;
-
-
-// rotate axis
- if (bt->rotate == 0)
- { sinv = 0 ; cosv = 1; }
- else if (bt->rotate == 90)
- { sinv = 1 ; cosv = 0; }
- else if (bt->rotate == 180)
- { sinv = 0 ; cosv = -1; }
- else if (bt->rotate == 270)
- { sinv = -1 ; cosv = 0; }
- else
- {
- ang = bt->rotate / 180 * Q_PI;
- sinv = sin(ang);
- cosv = cos(ang);
- }
-
- if (vecs[0][0])
- sv = 0;
- else if (vecs[0][1])
- sv = 1;
- else
- sv = 2;
-
- if (vecs[1][0])
- tv = 0;
- else if (vecs[1][1])
- tv = 1;
- else
- tv = 2;
-
- for (i=0 ; i<2 ; i++)
- {
- ns = cosv * vecs[i][sv] - sinv * vecs[i][tv];
- nt = sinv * vecs[i][sv] + cosv * vecs[i][tv];
- vecs[i][sv] = ns;
- vecs[i][tv] = nt;
- }
-
- for (i=0 ; i<2 ; i++)
- for (j=0 ; j<3 ; j++)
- tx.vecs[i][j] = vecs[i][j] / bt->scale[i];
-
- tx.vecs[0][3] = bt->shift[0] + shift[0];
- tx.vecs[1][3] = bt->shift[1] + shift[1];
- tx.flags = bt->flags;
- tx.value = bt->value;
-
- //
- // find the texinfo
- //
- tc = texinfo;
- for (i=0 ; i<numtexinfo ; i++, tc++)
- {
- if (tc->flags != tx.flags)
- continue;
- if (tc->value != tx.value)
- continue;
- for (j=0 ; j<2 ; j++)
- {
- if (strcmp (tc->texture, tx.texture))
- goto skip;
- for (k=0 ; k<4 ; k++)
- {
- if (tc->vecs[j][k] != tx.vecs[j][k])
- goto skip;
- }
- }
- return i;
-skip:;
- }
- *tc = tx;
- numtexinfo++;
-
- // load the next animation
- mt = FindMiptex (bt->name);
- if (textureref[mt].animname[0])
- {
- anim = *bt;
- strcpy (anim.name, textureref[mt].animname);
- tc->nexttexinfo = TexinfoForBrushTexture (plane, &anim, origin);
- }
- else
- tc->nexttexinfo = -1;
-
-
- return i;
-} //end of the function TexinfoForBrushTexture
diff --git a/code/bspc/tree.c b/code/bspc/tree.c
deleted file mode 100644
index afa1b83..0000000
--- a/code/bspc/tree.c
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-#include "qbsp.h"
-
-extern int c_nodes;
-int c_pruned;
-int freedtreemem = 0;
-
-void RemovePortalFromNode (portal_t *portal, node_t *l);
-
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-node_t *NodeForPoint (node_t *node, vec3_t origin)
-{
- plane_t *plane;
- vec_t d;
-
- while (node->planenum != PLANENUM_LEAF)
- {
- plane = &mapplanes[node->planenum];
- d = DotProduct (origin, plane->normal) - plane->dist;
- if (d >= 0)
- node = node->children[0];
- else
- node = node->children[1];
- }
- return node;
-} //end of the function NodeForPoint
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void Tree_FreePortals_r (node_t *node)
-{
- portal_t *p, *nextp;
- int s;
-
- // free children
- if (node->planenum != PLANENUM_LEAF)
- {
- Tree_FreePortals_r(node->children[0]);
- Tree_FreePortals_r(node->children[1]);
- }
-
- // free portals
- for (p = node->portals; p; p = nextp)
- {
- s = (p->nodes[1] == node);
- nextp = p->next[s];
-
- RemovePortalFromNode (p, p->nodes[!s]);
-#ifdef ME
- if (p->winding) freedtreemem += MemorySize(p->winding);
- freedtreemem += MemorySize(p);
-#endif //ME
- FreePortal(p);
- }
- node->portals = NULL;
-} //end of the function Tree_FreePortals_r
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void Tree_Free_r (node_t *node)
-{
-// face_t *f, *nextf;
- bspbrush_t *brush, *nextbrush;
-
- //free children
- if (node->planenum != PLANENUM_LEAF)
- {
- Tree_Free_r (node->children[0]);
- Tree_Free_r (node->children[1]);
- } //end if
- //free bspbrushes
-// FreeBrushList (node->brushlist);
- for (brush = node->brushlist; brush; brush = nextbrush)
- {
- nextbrush = brush->next;
-#ifdef ME
- freedtreemem += MemorySize(brush);
-#endif //ME
- FreeBrush(brush);
- } //end for
- node->brushlist = NULL;
-
- /*
- NOTE: only used when creating Q2 bsp
- // free faces
- for (f = node->faces; f; f = nextf)
- {
- nextf = f->next;
-#ifdef ME
- if (f->w) freedtreemem += MemorySize(f->w);
- freedtreemem += sizeof(face_t);
-#endif //ME
- FreeFace(f);
- } //end for
- */
-
- // free the node
- if (node->volume)
- {
-#ifdef ME
- freedtreemem += MemorySize(node->volume);
-#endif //ME
- FreeBrush (node->volume);
- } //end if
-
- if (numthreads == 1) c_nodes--;
-#ifdef ME
- freedtreemem += MemorySize(node);
-#endif //ME
- FreeMemory(node);
-} //end of the function Tree_Free_r
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void Tree_Free(tree_t *tree)
-{
- //if no tree just return
- if (!tree) return;
- //
- freedtreemem = 0;
- //
- Tree_FreePortals_r(tree->headnode);
- Tree_Free_r(tree->headnode);
-#ifdef ME
- freedtreemem += MemorySize(tree);
-#endif //ME
- FreeMemory(tree);
-#ifdef ME
- Log_Print("freed ");
- PrintMemorySize(freedtreemem);
- Log_Print(" of tree memory\n");
-#endif //ME
-} //end of the function Tree_Free
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-tree_t *Tree_Alloc(void)
-{
- tree_t *tree;
-
- tree = GetMemory(sizeof(*tree));
- memset (tree, 0, sizeof(*tree));
- ClearBounds (tree->mins, tree->maxs);
-
- return tree;
-} //end of the function Tree_Alloc
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void Tree_Print_r (node_t *node, int depth)
-{
- int i;
- plane_t *plane;
- bspbrush_t *bb;
-
- for (i=0 ; i<depth ; i++)
- printf (" ");
- if (node->planenum == PLANENUM_LEAF)
- {
- if (!node->brushlist)
- printf ("NULL\n");
- else
- {
- for (bb=node->brushlist ; bb ; bb=bb->next)
- printf ("%i ", bb->original->brushnum);
- printf ("\n");
- }
- return;
- }
-
- plane = &mapplanes[node->planenum];
- printf ("#%i (%5.2f %5.2f %5.2f):%5.2f\n", node->planenum,
- plane->normal[0], plane->normal[1], plane->normal[2],
- plane->dist);
- Tree_Print_r (node->children[0], depth+1);
- Tree_Print_r (node->children[1], depth+1);
-} //end of the function Tree_Print_r
-//===========================================================================
-// NODES THAT DON'T SEPERATE DIFFERENT CONTENTS CAN BE PRUNED
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void Tree_PruneNodes_r (node_t *node)
-{
- bspbrush_t *b, *next;
-
- if (node->planenum == PLANENUM_LEAF) return;
-
- Tree_PruneNodes_r (node->children[0]);
- Tree_PruneNodes_r (node->children[1]);
-
- if (create_aas)
- {
- if ((node->children[0]->contents & CONTENTS_LADDER) ||
- (node->children[1]->contents & CONTENTS_LADDER)) return;
- }
-
- if ((node->children[0]->contents & CONTENTS_SOLID)
- && (node->children[1]->contents & CONTENTS_SOLID))
- {
- if (node->faces)
- Error ("node->faces seperating CONTENTS_SOLID");
- if (node->children[0]->faces || node->children[1]->faces)
- Error ("!node->faces with children");
- // FIXME: free stuff
- node->planenum = PLANENUM_LEAF;
- node->contents = CONTENTS_SOLID;
- node->detail_seperator = false;
-
- if (node->brushlist)
- Error ("PruneNodes: node->brushlist");
- // combine brush lists
- node->brushlist = node->children[1]->brushlist;
-
- for (b = node->children[0]->brushlist; b; b = next)
- {
- next = b->next;
- b->next = node->brushlist;
- node->brushlist = b;
- } //end for
- //free the child nodes
- FreeMemory(node->children[0]);
- FreeMemory(node->children[1]);
- //two nodes are cut away
- c_pruned += 2;
- } //end if
-} //end of the function Tree_PruneNodes_r
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void Tree_PruneNodes(node_t *node)
-{
- Log_Print("------- Prune Nodes --------\n");
- c_pruned = 0;
- Tree_PruneNodes_r(node);
- Log_Print("%5i pruned nodes\n", c_pruned);
-} //end of the function Tree_PruneNodes
diff --git a/code/bspc/writebsp.c b/code/bspc/writebsp.c
deleted file mode 100644
index a382000..0000000
--- a/code/bspc/writebsp.c
+++ /dev/null
@@ -1,595 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-
-This file is part of Quake III Arena source code.
-
-Quake III Arena source code is free software; you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-Quake III Arena source code is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Quake III Arena source code; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-#include "qbsp.h"
-
-int c_nofaces;
-int c_facenodes;
-
-
-/*
-=========================================================
-
-ONLY SAVE OUT PLANES THAT ARE ACTUALLY USED AS NODES
-
-=========================================================
-*/
-
-int planeused[MAX_MAP_PLANES];
-
-/*
-============
-EmitPlanes
-
-There is no oportunity to discard planes, because all of the original
-brushes will be saved in the map.
-============
-*/
-void EmitPlanes (void)
-{
- int i;
- dplane_t *dp;
- plane_t *mp;
- //ME: this causes a crash??
-// int planetranslate[MAX_MAP_PLANES];
-
- mp = mapplanes;
- for (i=0 ; i<nummapplanes ; i++, mp++)
- {
- dp = &dplanes[numplanes];
-// planetranslate[i] = numplanes;
- VectorCopy ( mp->normal, dp->normal);
- dp->dist = mp->dist;
- dp->type = mp->type;
- numplanes++;
- if (numplanes >= MAX_MAP_PLANES)
- Error("MAX_MAP_PLANES");
- }
-}
-
-
-//========================================================
-
-void EmitMarkFace (dleaf_t *leaf_p, face_t *f)
-{
- int i;
- int facenum;
-
- while (f->merged)
- f = f->merged;
-
- if (f->split[0])
- {
- EmitMarkFace (leaf_p, f->split[0]);
- EmitMarkFace (leaf_p, f->split[1]);
- return;
- }
-
- facenum = f->outputnumber;
- if (facenum == -1)
- return; // degenerate face
-
- if (facenum < 0 || facenum >= numfaces)
- Error ("Bad leafface");
- for (i=leaf_p->firstleafface ; i<numleaffaces ; i++)
- if (dleaffaces[i] == facenum)
- break; // merged out face
- if (i == numleaffaces)
- {
- if (numleaffaces >= MAX_MAP_LEAFFACES)
- Error ("MAX_MAP_LEAFFACES");
-
- dleaffaces[numleaffaces] = facenum;
- numleaffaces++;
- }
-
-}
-
-
-/*
-==================
-EmitLeaf
-==================
-*/
-void EmitLeaf (node_t *node)
-{
- dleaf_t *leaf_p;
- portal_t *p;
- int s;
- face_t *f;
- bspbrush_t *b;
- int i;
- int brushnum;
-
- // emit a leaf
- if (numleafs >= MAX_MAP_LEAFS)
- Error ("MAX_MAP_LEAFS");
-
- leaf_p = &dleafs[numleafs];
- numleafs++;
-
- leaf_p->contents = node->contents;
- leaf_p->cluster = node->cluster;
- leaf_p->area = node->area;
-
- //
- // write bounding box info
- //
- VectorCopy (node->mins, leaf_p->mins);
- VectorCopy (node->maxs, leaf_p->maxs);
-
- //
- // write the leafbrushes
- //
- leaf_p->firstleafbrush = numleafbrushes;
- for (b=node->brushlist ; b ; b=b->next)
- {
- if (numleafbrushes >= MAX_MAP_LEAFBRUSHES)
- Error ("MAX_MAP_LEAFBRUSHES");
-
- brushnum = b->original - mapbrushes;
- for (i=leaf_p->firstleafbrush ; i<numleafbrushes ; i++)
- if (dleafbrushes[i] == brushnum)
- break;
- if (i == numleafbrushes)
- {
- dleafbrushes[numleafbrushes] = brushnum;
- numleafbrushes++;
- }
- }
- leaf_p->numleafbrushes = numleafbrushes - leaf_p->firstleafbrush;
-
- //
- // write the leaffaces
- //
- if (leaf_p->contents & CONTENTS_SOLID)
- return; // no leaffaces in solids
-
- leaf_p->firstleafface = numleaffaces;
-
- for (p = node->portals ; p ; p = p->next[s])
- {
- s = (p->nodes[1] == node);
- f = p->face[s];
- if (!f)
- continue; // not a visible portal
-
- EmitMarkFace (leaf_p, f);
- }
-
- leaf_p->numleaffaces = numleaffaces - leaf_p->firstleafface;
-}
-
-
-/*
-==================
-EmitFace
-==================
-*/
-void EmitFace (face_t *f)
-{
- dface_t *df;
- int i;
- int e;
-
- f->outputnumber = -1;
-
- if (f->numpoints < 3)
- {
- return; // degenerated
- }
- if (f->merged || f->split[0] || f->split[1])
- {
- return; // not a final face
- }
-
- // save output number so leaffaces can use
- f->outputnumber = numfaces;
-
- if (numfaces >= MAX_MAP_FACES)
- Error ("numfaces == MAX_MAP_FACES");
- df = &dfaces[numfaces];
- numfaces++;
-
- // planenum is used by qlight, but not quake
- df->planenum = f->planenum & (~1);
- df->side = f->planenum & 1;
-
- df->firstedge = numsurfedges;
- df->numedges = f->numpoints;
- df->texinfo = f->texinfo;
- for (i=0 ; i<f->numpoints ; i++)
- {
-// e = GetEdge (f->pts[i], f->pts[(i+1)%f->numpoints], f);
- e = GetEdge2 (f->vertexnums[i], f->vertexnums[(i+1)%f->numpoints], f);
- if (numsurfedges >= MAX_MAP_SURFEDGES)
- Error ("numsurfedges == MAX_MAP_SURFEDGES");
- dsurfedges[numsurfedges] = e;
- numsurfedges++;
- }
-}
-
-/*
-============
-EmitDrawingNode_r
-============
-*/
-int EmitDrawNode_r (node_t *node)
-{
- dnode_t *n;
- face_t *f;
- int i;
-
- if (node->planenum == PLANENUM_LEAF)
- {
- EmitLeaf (node);
- return -numleafs;
- }
-
- // emit a node
- if (numnodes == MAX_MAP_NODES)
- Error ("MAX_MAP_NODES");
- n = &dnodes[numnodes];
- numnodes++;
-
- VectorCopy (node->mins, n->mins);
- VectorCopy (node->maxs, n->maxs);
-
- planeused[node->planenum]++;
- planeused[node->planenum^1]++;
-
- if (node->planenum & 1)
- Error ("WriteDrawNodes_r: odd planenum");
- n->planenum = node->planenum;
- n->firstface = numfaces;
-
- if (!node->faces)
- c_nofaces++;
- else
- c_facenodes++;
-
- for (f=node->faces ; f ; f=f->next)
- EmitFace (f);
-
- n->numfaces = numfaces - n->firstface;
-
-
- //
- // recursively output the other nodes
- //
- for (i=0 ; i<2 ; i++)
- {
- if (node->children[i]->planenum == PLANENUM_LEAF)
- {
- n->children[i] = -(numleafs + 1);
- EmitLeaf (node->children[i]);
- }
- else
- {
- n->children[i] = numnodes;
- EmitDrawNode_r (node->children[i]);
- }
- }
-
- return n - dnodes;
-}
-
-//=========================================================
-
-
-/*
-============
-WriteBSP
-============
-*/
-void WriteBSP (node_t *headnode)
-{
- int oldfaces;
-
- c_nofaces = 0;
- c_facenodes = 0;
-
- qprintf ("--- WriteBSP ---\n");
-
- oldfaces = numfaces;
- dmodels[nummodels].headnode = EmitDrawNode_r (headnode);
- EmitAreaPortals (headnode);
-
- qprintf ("%5i nodes with faces\n", c_facenodes);
- qprintf ("%5i nodes without faces\n", c_nofaces);
- qprintf ("%5i faces\n", numfaces-oldfaces);
-}
-
-//===========================================================
-
-/*
-============
-SetModelNumbers
-============
-*/
-void SetModelNumbers (void)
-{
- int i;
- int models;
- char value[10];
-
- models = 1;
- for (i=1 ; i<num_entities ; i++)
- {
- if (entities[i].numbrushes)
- {
- sprintf (value, "*%i", models);
- models++;
- SetKeyValue (&entities[i], "model", value);
- }
- }
-
-}
-
-/*
-============
-SetLightStyles
-============
-*/
-#define MAX_SWITCHED_LIGHTS 32
-void SetLightStyles (void)
-{
- int stylenum;
- char *t;
- entity_t *e;
- int i, j;
- char value[10];
- char lighttargets[MAX_SWITCHED_LIGHTS][64];
-
-
- // any light that is controlled (has a targetname)
- // must have a unique style number generated for it
-
- stylenum = 0;
- for (i=1 ; i<num_entities ; i++)
- {
- e = &entities[i];
-
- t = ValueForKey (e, "classname");
- if (Q_strncasecmp (t, "light", 5))
- continue;
- t = ValueForKey (e, "targetname");
- if (!t[0])
- continue;
-
- // find this targetname
- for (j=0 ; j<stylenum ; j++)
- if (!strcmp (lighttargets[j], t))
- break;
- if (j == stylenum)
- {
- if (stylenum == MAX_SWITCHED_LIGHTS)
- Error ("stylenum == MAX_SWITCHED_LIGHTS");
- strcpy (lighttargets[j], t);
- stylenum++;
- }
- sprintf (value, "%i", 32 + j);
- SetKeyValue (e, "style", value);
- }
-
-}
-
-//===========================================================
-
-/*
-============
-EmitBrushes
-============
-*/
-void EmitBrushes (void)
-{
- int i, j, bnum, s, x;
- dbrush_t *db;
- mapbrush_t *b;
- dbrushside_t *cp;
- vec3_t normal;
- vec_t dist;
- int planenum;
-
- numbrushsides = 0;
- numbrushes = nummapbrushes;
-
- for (bnum=0 ; bnum<nummapbrushes ; bnum++)
- {
- b = &mapbrushes[bnum];
- db = &dbrushes[bnum];
-
- db->contents = b->contents;
- db->firstside = numbrushsides;
- db->numsides = b->numsides;
- for (j=0 ; j<b->numsides ; j++)
- {
- if (numbrushsides == MAX_MAP_BRUSHSIDES)
- Error ("MAX_MAP_BRUSHSIDES");
- cp = &dbrushsides[numbrushsides];
- numbrushsides++;
- cp->planenum = b->original_sides[j].planenum;
- cp->texinfo = b->original_sides[j].texinfo;
- }
-
-#ifdef ME
- //for collision detection, bounding boxes are axial :)
- //brushes are convex so just add dot or line touching planes on the sides of
- //the brush parallell to the axis planes
-#endif
- // add any axis planes not contained in the brush to bevel off corners
- for (x=0 ; x<3 ; x++)
- for (s=-1 ; s<=1 ; s+=2)
- {
- // add the plane
- VectorCopy (vec3_origin, normal);
- normal[x] = s;
- if (s == -1)
- dist = -b->mins[x];
- else
- dist = b->maxs[x];
- planenum = FindFloatPlane (normal, dist);
- for (i=0 ; i<b->numsides ; i++)
- if (b->original_sides[i].planenum == planenum)
- break;
- if (i == b->numsides)
- {
- if (numbrushsides >= MAX_MAP_BRUSHSIDES)
- Error ("MAX_MAP_BRUSHSIDES");
-
- dbrushsides[numbrushsides].planenum = planenum;
- dbrushsides[numbrushsides].texinfo =
- dbrushsides[numbrushsides-1].texinfo;
- numbrushsides++;
- db->numsides++;
- }
- }
-
- }
-
-}
-
-//===========================================================
-
-/*
-==================
-BeginBSPFile
-==================
-*/
-void BeginBSPFile (void)
-{
- // these values may actually be initialized
- // if the file existed when loaded, so clear them explicitly
- nummodels = 0;
- numfaces = 0;
- numnodes = 0;
- numbrushsides = 0;
- numvertexes = 0;
- numleaffaces = 0;
- numleafbrushes = 0;
- numsurfedges = 0;
-
- // edge 0 is not used, because 0 can't be negated
- numedges = 1;
-
- // leave vertex 0 as an error
- numvertexes = 1;
-
- // leave leaf 0 as an error
- numleafs = 1;
- dleafs[0].contents = CONTENTS_SOLID;
-}
-
-
-/*
-============
-EndBSPFile
-============
-*/
-void EndBSPFile (void)
-{
-#if 0
- char path[1024];
- int len;
- byte *buf;
-#endif
-
-
- EmitBrushes ();
- EmitPlanes ();
- Q2_UnparseEntities ();
-
- // load the pop
-#if 0
- sprintf (path, "%s/pics/pop.lmp", gamedir);
- len = LoadFile (path, &buf);
- memcpy (dpop, buf, sizeof(dpop));
- FreeMemory(buf);
-#endif
-}
-
-
-/*
-==================
-BeginModel
-==================
-*/
-int firstmodleaf;
-extern int firstmodeledge;
-extern int firstmodelface;
-void BeginModel (void)
-{
- dmodel_t *mod;
- int start, end;
- mapbrush_t *b;
- int j;
- entity_t *e;
- vec3_t mins, maxs;
-
- if (nummodels == MAX_MAP_MODELS)
- Error ("MAX_MAP_MODELS");
- mod = &dmodels[nummodels];
-
- mod->firstface = numfaces;
-
- firstmodleaf = numleafs;
- firstmodeledge = numedges;
- firstmodelface = numfaces;
-
- //
- // bound the brushes
- //
- e = &entities[entity_num];
-
- start = e->firstbrush;
- end = start + e->numbrushes;
- ClearBounds (mins, maxs);
-
- for (j=start ; j<end ; j++)
- {
- b = &mapbrushes[j];
- if (!b->numsides)
- continue; // not a real brush (origin brush)
- AddPointToBounds (b->mins, mins, maxs);
- AddPointToBounds (b->maxs, mins, maxs);
- }
-
- VectorCopy (mins, mod->mins);
- VectorCopy (maxs, mod->maxs);
-}
-
-
-/*
-==================
-EndModel
-==================
-*/
-void EndModel (void)
-{
- dmodel_t *mod;
-
- mod = &dmodels[nummodels];
-
- mod->numfaces = numfaces - mod->firstface;
-
- nummodels++;
-}
-