From ce25a7def5dc658d78c06016494b90972f1cf973 Mon Sep 17 00:00:00 2001 From: tma Date: Sat, 29 Oct 2005 23:13:09 +0000 Subject: * General decrufting: * Removed Q3_STATIC and associated defines * Removed MAC_STATIC * Replaced __LCC__ with Q3_VM * Removed bspc and splines directories git-svn-id: svn://svn.icculus.org/quake3/trunk@201 edf5b092-35ff-0310-97b2-ce42778d08ea --- code/bspc/Makefile | 114 --- code/bspc/_files.c | 63 -- code/bspc/aas_areamerging.c | 390 -------- code/bspc/aas_areamerging.h | 24 - code/bspc/aas_cfg.c | 252 ----- code/bspc/aas_cfg.h | 73 -- code/bspc/aas_create.c | 1142 ----------------------- code/bspc/aas_create.h | 136 --- code/bspc/aas_edgemelting.c | 108 --- code/bspc/aas_edgemelting.h | 24 - code/bspc/aas_facemerging.c | 282 ------ code/bspc/aas_facemerging.h | 24 - code/bspc/aas_file.c | 549 ----------- code/bspc/aas_file.h | 25 - code/bspc/aas_gsubdiv.c | 656 ------------- code/bspc/aas_gsubdiv.h | 25 - code/bspc/aas_map.c | 849 ----------------- code/bspc/aas_map.h | 23 - code/bspc/aas_prunenodes.c | 89 -- code/bspc/aas_prunenodes.h | 24 - code/bspc/aas_store.c | 1082 ---------------------- code/bspc/aas_store.h | 107 --- code/bspc/aasfile.h | 252 ----- code/bspc/be_aas_bspc.c | 292 ------ code/bspc/be_aas_bspc.h | 23 - code/bspc/brushbsp.c | 1871 -------------------------------------- code/bspc/bspc.c | 991 -------------------- code/bspc/bspc.sln | 28 - code/bspc/bspc.vcproj | 1381 ---------------------------- code/bspc/cfgq3.c | 84 -- code/bspc/csg.c | 1005 -------------------- code/bspc/faces.c | 978 -------------------- code/bspc/gldraw.c | 232 ----- code/bspc/glfile.c | 149 --- code/bspc/l_bsp_ent.c | 180 ---- code/bspc/l_bsp_ent.h | 58 -- code/bspc/l_bsp_hl.c | 888 ------------------ code/bspc/l_bsp_hl.h | 314 ------- code/bspc/l_bsp_q1.c | 620 ------------- code/bspc/l_bsp_q1.h | 275 ------ code/bspc/l_bsp_q2.c | 1134 ----------------------- code/bspc/l_bsp_q2.h | 98 -- code/bspc/l_bsp_q3.c | 824 ----------------- code/bspc/l_bsp_q3.h | 81 -- code/bspc/l_bsp_sin.c | 1186 ------------------------ code/bspc/l_bsp_sin.h | 106 --- code/bspc/l_cmd.c | 1230 ------------------------- code/bspc/l_cmd.h | 157 ---- code/bspc/l_log.c | 215 ----- code/bspc/l_log.h | 42 - code/bspc/l_math.c | 289 ------ code/bspc/l_math.h | 93 -- code/bspc/l_mem.c | 441 --------- code/bspc/l_mem.h | 51 -- code/bspc/l_poly.c | 1411 ---------------------------- code/bspc/l_poly.h | 120 --- code/bspc/l_qfiles.c | 663 -------------- code/bspc/l_qfiles.h | 91 -- code/bspc/l_threads.c | 1510 ------------------------------ code/bspc/l_threads.h | 45 - code/bspc/l_utils.c | 259 ------ code/bspc/l_utils.h | 79 -- code/bspc/lcc.mak | 61 -- code/bspc/leakfile.c | 101 -- code/bspc/linux-i386.mak | 109 --- code/bspc/map.c | 1267 -------------------------- code/bspc/map_hl.c | 1114 ----------------------- code/bspc/map_q1.c | 1174 ------------------------ code/bspc/map_q2.c | 1162 ----------------------- code/bspc/map_q3.c | 681 -------------- code/bspc/map_sin.c | 1211 ------------------------ code/bspc/nodraw.c | 47 - code/bspc/portals.c | 1297 -------------------------- code/bspc/prtfile.c | 287 ------ code/bspc/q2files.h | 487 ---------- code/bspc/q3files.h | 374 -------- code/bspc/qbsp.h | 477 ---------- code/bspc/qfiles.h | 487 ---------- code/bspc/sinfiles.h | 365 -------- code/bspc/tetrahedron.c | 1389 ---------------------------- code/bspc/tetrahedron.h | 24 - code/bspc/textures.c | 228 ----- code/bspc/tree.c | 283 ------ code/bspc/writebsp.c | 595 ------------ code/cgame/cg_drawtools.c | 3 - code/cgame/cg_main.c | 5 - code/client/cl_console.c | 2 +- code/game/bg_lib.c | 2 +- code/game/g_main.c | 5 - code/q3_ui/ui_atoms.c | 5 - code/qcommon/cm_patch.c | 4 +- code/qcommon/q_math.c | 4 +- code/qcommon/q_shared.h | 29 +- code/renderer/tr_bsp.c | 4 +- code/renderer/tr_curve.c | 6 +- code/renderer/tr_shade.c | 2 +- code/server/sv_client.c | 2 +- code/splines/Splines.vcproj | 296 ------ code/splines/math_angles.cpp | 150 --- code/splines/math_angles.h | 195 ---- code/splines/math_matrix.cpp | 134 --- code/splines/math_matrix.h | 223 ----- code/splines/math_quaternion.cpp | 78 -- code/splines/math_quaternion.h | 190 ---- code/splines/math_vector.cpp | 144 --- code/splines/math_vector.h | 574 ------------ code/splines/q_parse.cpp | 535 ----------- code/splines/q_shared.cpp | 976 -------------------- code/splines/q_shared.h | 850 ----------------- code/splines/q_shared.hpp | 841 ----------------- code/splines/splines.cpp | 1250 ------------------------- code/splines/splines.h | 1075 ---------------------- code/splines/util_list.h | 346 ------- code/splines/util_str.cpp | 620 ------------- code/splines/util_str.h | 817 ----------------- code/ui/ui_atoms.c | 5 - 116 files changed, 16 insertions(+), 48383 deletions(-) delete mode 100644 code/bspc/Makefile delete mode 100644 code/bspc/_files.c delete mode 100644 code/bspc/aas_areamerging.c delete mode 100644 code/bspc/aas_areamerging.h delete mode 100644 code/bspc/aas_cfg.c delete mode 100644 code/bspc/aas_cfg.h delete mode 100644 code/bspc/aas_create.c delete mode 100644 code/bspc/aas_create.h delete mode 100644 code/bspc/aas_edgemelting.c delete mode 100644 code/bspc/aas_edgemelting.h delete mode 100644 code/bspc/aas_facemerging.c delete mode 100644 code/bspc/aas_facemerging.h delete mode 100644 code/bspc/aas_file.c delete mode 100644 code/bspc/aas_file.h delete mode 100644 code/bspc/aas_gsubdiv.c delete mode 100644 code/bspc/aas_gsubdiv.h delete mode 100644 code/bspc/aas_map.c delete mode 100644 code/bspc/aas_map.h delete mode 100644 code/bspc/aas_prunenodes.c delete mode 100644 code/bspc/aas_prunenodes.h delete mode 100644 code/bspc/aas_store.c delete mode 100644 code/bspc/aas_store.h delete mode 100644 code/bspc/aasfile.h delete mode 100644 code/bspc/be_aas_bspc.c delete mode 100644 code/bspc/be_aas_bspc.h delete mode 100644 code/bspc/brushbsp.c delete mode 100644 code/bspc/bspc.c delete mode 100644 code/bspc/bspc.sln delete mode 100644 code/bspc/bspc.vcproj delete mode 100644 code/bspc/cfgq3.c delete mode 100644 code/bspc/csg.c delete mode 100644 code/bspc/faces.c delete mode 100644 code/bspc/gldraw.c delete mode 100644 code/bspc/glfile.c delete mode 100644 code/bspc/l_bsp_ent.c delete mode 100644 code/bspc/l_bsp_ent.h delete mode 100644 code/bspc/l_bsp_hl.c delete mode 100644 code/bspc/l_bsp_hl.h delete mode 100644 code/bspc/l_bsp_q1.c delete mode 100644 code/bspc/l_bsp_q1.h delete mode 100644 code/bspc/l_bsp_q2.c delete mode 100644 code/bspc/l_bsp_q2.h delete mode 100644 code/bspc/l_bsp_q3.c delete mode 100644 code/bspc/l_bsp_q3.h delete mode 100644 code/bspc/l_bsp_sin.c delete mode 100644 code/bspc/l_bsp_sin.h delete mode 100644 code/bspc/l_cmd.c delete mode 100644 code/bspc/l_cmd.h delete mode 100644 code/bspc/l_log.c delete mode 100644 code/bspc/l_log.h delete mode 100644 code/bspc/l_math.c delete mode 100644 code/bspc/l_math.h delete mode 100644 code/bspc/l_mem.c delete mode 100644 code/bspc/l_mem.h delete mode 100644 code/bspc/l_poly.c delete mode 100644 code/bspc/l_poly.h delete mode 100644 code/bspc/l_qfiles.c delete mode 100644 code/bspc/l_qfiles.h delete mode 100644 code/bspc/l_threads.c delete mode 100644 code/bspc/l_threads.h delete mode 100644 code/bspc/l_utils.c delete mode 100644 code/bspc/l_utils.h delete mode 100644 code/bspc/lcc.mak delete mode 100644 code/bspc/leakfile.c delete mode 100644 code/bspc/linux-i386.mak delete mode 100644 code/bspc/map.c delete mode 100644 code/bspc/map_hl.c delete mode 100644 code/bspc/map_q1.c delete mode 100644 code/bspc/map_q2.c delete mode 100644 code/bspc/map_q3.c delete mode 100644 code/bspc/map_sin.c delete mode 100644 code/bspc/nodraw.c delete mode 100644 code/bspc/portals.c delete mode 100644 code/bspc/prtfile.c delete mode 100644 code/bspc/q2files.h delete mode 100644 code/bspc/q3files.h delete mode 100644 code/bspc/qbsp.h delete mode 100644 code/bspc/qfiles.h delete mode 100644 code/bspc/sinfiles.h delete mode 100644 code/bspc/tetrahedron.c delete mode 100644 code/bspc/tetrahedron.h delete mode 100644 code/bspc/textures.c delete mode 100644 code/bspc/tree.c delete mode 100644 code/bspc/writebsp.c delete mode 100644 code/splines/Splines.vcproj delete mode 100644 code/splines/math_angles.cpp delete mode 100644 code/splines/math_angles.h delete mode 100644 code/splines/math_matrix.cpp delete mode 100644 code/splines/math_matrix.h delete mode 100644 code/splines/math_quaternion.cpp delete mode 100644 code/splines/math_quaternion.h delete mode 100644 code/splines/math_vector.cpp delete mode 100644 code/splines/math_vector.h delete mode 100644 code/splines/q_parse.cpp delete mode 100644 code/splines/q_shared.cpp delete mode 100644 code/splines/q_shared.h delete mode 100644 code/splines/q_shared.hpp delete mode 100644 code/splines/splines.cpp delete mode 100644 code/splines/splines.h delete mode 100644 code/splines/util_list.h delete mode 100644 code/splines/util_str.cpp delete mode 100644 code/splines/util_str.h 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 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 - -/* -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 ; inumsides ; 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 ; inumsides ; 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;inumsides ; 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 ; inumsides ; i++) - { - w = brush->sides[i].winding; - if (!w) - continue; - for (j=0 ; jnumpoints ; 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 ; inumsides ; i++) - { - side = &brush->sides[i]; - plane = &mapplanes[side->planenum]; - w = BaseWindingForPlane (plane->normal, plane->dist); - for (j=0 ; jnumsides && 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 ; inumsides ; 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 ; inumsides ; 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 ; inumpoints ; 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 ; inumpoints ; 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 ; inumsides ; 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 ; inumsides ; i++) - { - w = brush->sides[i].winding; - if (!w) - continue; - for (j=0 ; jnumpoints ; 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 ; inumsides ; i++) - { - w = brush->sides[i].winding; - if (!w) - continue; - for (j=0 ; jnumpoints ; 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 ; inumsides && 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 ; inumsides ; 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 ; inumsides ; 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 ; inumsides ; 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 -#include -#include -#include -#else -#include -#include -#include -#include -#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 [- [- ...]]\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 = create AAS files for all BSPs\n" - " bsp2aas <[pakfilter/]filter.bsp> = convert BSP to AAS\n" - " reach = compute reachability & clusters\n" - " cluster = compute clusters\n" - " aasopt = optimize aas file\n" - " aasinfo = show AAS file info\n" - " output = set output path\n" - " threads = set number of threads to X\n" - " cfg = 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 \n" - " = sets the micro volume to the given float\n" - " leaktest = perform a leak test\n" - " verboseentities\n" - " = enable entity verbose mode\n" - " chop \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 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 ; inumsides && 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 ; inumsides ; i++) - { - for (j=0 ; jnumsides ; 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 ; inumsides ; 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 ; inumsides; - if (!numsides) - continue; - - // make sure the brush has at least one face showing - vis = 0; - for (j=0 ; joriginal_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 ; jsides[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 ; inumsides ; 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 ; inumsides ; 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 ; inumsides ; 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 ; inumsides ; 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]) 4096) - Error ("GetVertexnum: outside +/- 4096"); - } - - // search for an existing vertex match - for (i=0, dv=dvertexes ; ipoint[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 ; ivertexnums[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 ; ivertexnums[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 ; inumpoints ; 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> 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= 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 ; inumpoints ; 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 ; inumpoints ; 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 - 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 ; inumpoints ; 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 -#include -#include -#include - -#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 ; inumpoints ; 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 ; inumpoints ; 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 ; inumpoints ; 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 ; inumpoints ; 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 ; inumpoints ; 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 ; inumpoints ; 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>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 ; inummiptex; - else - c = LittleLong(mtl->nummiptex); - mtl->nummiptex = LittleLong (mtl->nummiptex); - for (i=0 ; idataofs[i] = LittleLong(mtl->dataofs[i]); - } - -// -// marksurfaces -// - for (i=0 ; ilumps[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 ; inext) - { - 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 ; iheadnode[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 ; inummiptex; - else - c = LittleLong(mtl->nummiptex); - mtl->nummiptex = LittleLong (mtl->nummiptex); - for (i=0 ; idataofs[i] = LittleLong(mtl->dataofs[i]); - } - -// -// marksurfaces -// - for (i=0 ; ilumps[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 ; inext) - { - 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>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 ; ifirstface = 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 ; inumclusters; - else - j = LittleLong(dvis->numclusters); - dvis->numclusters = LittleLong (dvis->numclusters); - for (i=0 ; ibitofs[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 ; inext) - { - 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 ; inext) - { - 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>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 ; ifirstface = 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 ; inumclusters; - else - j = LittleLong(sin_dvis->numclusters); - sin_dvis->numclusters = LittleLong (sin_dvis->numclusters); - for (i=0 ; ibitofs[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 ; inext) - { - 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 -#include - -#ifndef SIN -#define SIN -#endif //SIN - -#if defined(WIN32) || defined(_WIN32) -#include -#else -#include -#endif - -#ifdef NeXT -#include -#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 - -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 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 -#include -#include -#include -#include -#include -#include - -#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 -#include -#include - -#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 \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 - -#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 -#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 ; inumpoints ; 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 ; inumpoints ; 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 ; inumpoints ; 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 ; inumpoints ; 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 ; inumpoints ; 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 ; inumpoints ; 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 ; inumpoints ; 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 ; inumpoints ; 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 ; inumpoints ; 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 ; inumpoints ; 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 ; inumpoints ; 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 ; jnumpoints ; 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 ; inumpoints ; 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 ; inumpoints ; 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 ; jnumpoints ; 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 -#include -#include -#else -#include -#include -#include -#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 - -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 - -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) 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 -#include - -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) 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 -#include -#include -#include - -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) 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 ; inumsides ; 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 ; inumsides ; i++) - { - s = b->original_sides + i; - w = s->winding; - if (!w) - continue; - for (j=0 ; jnumpoints ; 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 ; knumsides ; 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 ; lnumpoints ; 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 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 ; inumsides ; i++) - { - w = brush->sides[i].winding; - if (!w) - continue; - for (j=0 ; jnumpoints ; 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 ; inumsides ; 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 ; inumsides ; i++) - { - w = brush->sides[i].winding; - if (!w) - continue; - for (j=0 ; jnumpoints ; 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 ; inumsides ; 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 ; knumsides ; 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 ; inumsides ; 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 ; inumbrushes = 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 ; inumbrushes ; i++) - { - b = &mapbrushes[mapent->firstbrush + i]; - for (j=0 ; jnumsides ; 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 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 ; bnnumsides ; 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 ; inumsides ; 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 ; knumsides ; 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 ; inumsides ; 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 ; inumbrushes = 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 ; jnumsides) - 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 ; inumbrushes ; i++) - { - b = &mapbrushes[mapent->firstbrush + i]; - for (j=0 ; jnumsides ; 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 ; inumbrushes ; 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 ; jnumsides ; 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 ; jnumsides ; 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 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; jnumsides && b->contents & CONTENTS_DETAIL) - num_detailbrushes++; - else if (b->numsides) - num_worldbrushes++; - for (k=0, s=b->original_sides ; knumsides ; 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 ; inumpoints ; 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 ; iwinding->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 ; jareaportalnum) - 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 ; inumsides ; 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 ; inumsides; - for (j=0 ; joriginal_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 ; inumpoints ; 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 -#endif -#include -#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 ; iflags != 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 ; iplanenum == 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 ; inormal, 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= 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 ; inumleafbrushes = 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 ; inumpoints ; 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 ; icontents = b->contents; - db->firstside = numbrushsides; - db->numsides = b->numsides; - for (j=0 ; jnumsides ; 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 ; inumsides ; 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 ; jnumsides) - 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++; -} - diff --git a/code/cgame/cg_drawtools.c b/code/cgame/cg_drawtools.c index 03c8a24..1409ec1 100644 --- a/code/cgame/cg_drawtools.c +++ b/code/cgame/cg_drawtools.c @@ -435,8 +435,6 @@ void CG_ColorForHealth( vec4_t hcolor ) { // bk001205 - code below duplicated in q3_ui/ui-atoms.c // bk001205 - FIXME: does this belong in ui_shared.c? -// bk001205 - FIXME: HARD_LINKED flags not visible here -#ifndef Q3_STATIC // bk001205 - q_shared defines not visible here /* ================= UI_DrawProportionalString2 @@ -821,4 +819,3 @@ void UI_DrawProportionalString( int x, int y, const char* str, int style, vec4_t UI_DrawProportionalString2( x, y, str, color, sizeScale, cgs.media.charsetProp ); } -#endif // Q3STATIC diff --git a/code/cgame/cg_main.c b/code/cgame/cg_main.c index c5ea090..b4c3e13 100644 --- a/code/cgame/cg_main.c +++ b/code/cgame/cg_main.c @@ -438,9 +438,6 @@ void QDECL CG_Error( const char *msg, ... ) { trap_Error( text ); } -#ifndef CGAME_HARD_LINKED -// this is only here so the functions in q_shared.c and bg_*.c can link (FIXME) - void QDECL Com_Error( int level, const char *error, ... ) { va_list argptr; char text[1024]; @@ -463,8 +460,6 @@ void QDECL Com_Printf( const char *msg, ... ) { CG_Printf ("%s", text); } -#endif - /* ================ CG_Argv diff --git a/code/client/cl_console.c b/code/client/cl_console.c index 06f16eb..46438d7 100644 --- a/code/client/cl_console.c +++ b/code/client/cl_console.c @@ -248,7 +248,7 @@ If the line width has changed, reformat the buffer. void Con_CheckResize (void) { int i, j, width, oldwidth, oldtotallines, numlines, numchars; - MAC_STATIC short tbuf[CON_TEXTSIZE]; + short tbuf[CON_TEXTSIZE]; width = (SCREEN_WIDTH / SMALLCHAR_WIDTH) - 2; diff --git a/code/game/bg_lib.c b/code/game/bg_lib.c index e313087..88a2c88 100644 --- a/code/game/bg_lib.c +++ b/code/game/bg_lib.c @@ -1257,7 +1257,7 @@ reswitch: break; case 'f': AddFloat( &buf_p, *(double *)arg, width, prec ); -#ifdef __LCC__ +#ifdef Q3_VM arg += 1; // everything is 32 bit in my compiler #else arg += 2; diff --git a/code/game/g_main.c b/code/game/g_main.c index 8b8f954..a8819ff 100644 --- a/code/game/g_main.c +++ b/code/game/g_main.c @@ -536,9 +536,6 @@ void G_ShutdownGame( int restart ) { //=================================================================== -#ifndef GAME_HARD_LINKED -// this is only here so the functions in q_shared.c and bg_*.c can link - void QDECL Com_Error ( int level, const char *error, ... ) { va_list argptr; char text[1024]; @@ -561,8 +558,6 @@ void QDECL Com_Printf( const char *msg, ... ) { G_Printf ("%s", text); } -#endif - /* ======================================================================== diff --git a/code/q3_ui/ui_atoms.c b/code/q3_ui/ui_atoms.c index 1d0b5d8..0e1775f 100644 --- a/code/q3_ui/ui_atoms.c +++ b/code/q3_ui/ui_atoms.c @@ -30,9 +30,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA uiStatic_t uis; qboolean m_entersound; // after a frame, so caching won't disrupt the sound -// these are here so the functions in q_shared.c can link -#ifndef UI_HARD_LINKED - void QDECL Com_Error( int level, const char *error, ... ) { va_list argptr; char text[1024]; @@ -55,8 +52,6 @@ void QDECL Com_Printf( const char *msg, ... ) { trap_Print( va("%s", text) ); } -#endif - /* ================= UI_ClampCvar diff --git a/code/qcommon/cm_patch.c b/code/qcommon/cm_patch.c index fd0cd4c..6fe9a75 100644 --- a/code/qcommon/cm_patch.c +++ b/code/qcommon/cm_patch.c @@ -980,7 +980,7 @@ CM_PatchCollideFromGrid static void CM_PatchCollideFromGrid( cGrid_t *grid, patchCollide_t *pf ) { int i, j; float *p1, *p2, *p3; - MAC_STATIC int gridPlanes[MAX_GRID_SIZE][MAX_GRID_SIZE][2]; + int gridPlanes[MAX_GRID_SIZE][MAX_GRID_SIZE][2]; facet_t *facet; int borders[4]; int noAdjust[4]; @@ -1147,7 +1147,7 @@ Points is packed as concatenated rows. */ struct patchCollide_s *CM_GeneratePatchCollide( int width, int height, vec3_t *points ) { patchCollide_t *pf; - MAC_STATIC cGrid_t grid; + cGrid_t grid; int i, j; if ( width <= 2 || height <= 2 || !points ) { diff --git a/code/qcommon/q_math.c b/code/qcommon/q_math.c index 4c35730..da3044e 100644 --- a/code/qcommon/q_math.c +++ b/code/qcommon/q_math.c @@ -153,7 +153,7 @@ float Q_crandom( int *seed ) { return 2.0 * ( Q_random( seed ) - 0.5 ); } -#ifdef __LCC__ +#ifdef Q3_VM int VectorCompare( const vec3_t v1, const vec3_t v2 ) { if (v1[0] != v2[0] || v1[1] != v2[1] || v1[2] != v2[2]) { @@ -739,7 +739,7 @@ int BoxOnPlaneSide2 (vec3_t emins, vec3_t emaxs, struct cplane_s *p) // if not GNU x86 and configured to use asm #if !( (defined __GNUC__) && (defined __i386__) && (!defined C_ONLY)) -#if defined __LCC__ || defined C_ONLY || !id386 || defined __VECTORC +#if defined Q3_VM || defined C_ONLY || !id386 || defined __VECTORC int BoxOnPlaneSide (vec3_t emins, vec3_t emaxs, struct cplane_s *p) { diff --git a/code/qcommon/q_shared.h b/code/qcommon/q_shared.h index 08d4c23..39b4973 100644 --- a/code/qcommon/q_shared.h +++ b/code/qcommon/q_shared.h @@ -105,7 +105,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // this is the define for determining if we have an asm version of a C function -#if (defined _M_IX86 || defined __i386__) && !defined __sun && !defined __LCC__ +#if (defined _M_IX86 || defined __i386__) && !defined __sun && !defined Q3_VM #define id386 1 #else #define id386 0 @@ -135,8 +135,6 @@ float FloatSwap (const float *f); #ifdef WIN32 -#define MAC_STATIC - #undef QDECL #define QDECL __cdecl @@ -184,7 +182,6 @@ static ID_INLINE float BigFloat(const float l) { return FloatSwap(&l); } #if defined(MACOS_X) -#define MAC_STATIC #define __cdecl #define __declspec(x) #define stricmp strcasecmp @@ -239,7 +236,6 @@ static inline float LittleFloat (const float l) { return FloatSwap(&l); } #ifdef __MACOS__ #include -#define MAC_STATIC #define ID_INLINE inline #define CPUSTRING "MacOS-PPC" @@ -266,7 +262,6 @@ static inline float LittleFloat (const float l) { return FloatSwap(&l); } // bk001205 - from Makefile #define stricmp strcasecmp -#define MAC_STATIC // bk: FIXME #define ID_INLINE inline #ifdef __i386__ @@ -291,14 +286,6 @@ static inline float LittleFloat (const float l) { return FloatSwap(&l); } #define PATH_SEP '/' -// bk001205 - try -#ifdef Q3_STATIC -#define GAME_HARD_LINKED -#define CGAME_HARD_LINKED -#define UI_HARD_LINKED -#define BOTLIB_HARD_LINKED -#endif - #if __FLOAT_WORD_ORDER == __LITTLE_ENDIAN inline static short BigShort( short l) { return ShortSwap(l); } #define LittleShort @@ -322,7 +309,6 @@ inline static float LittleFloat (const float l) { return FloatSwap(&l); } #define stricmp strcasecmp -#define MAC_STATIC #define ID_INLINE inline #ifdef __i386__ @@ -364,7 +350,6 @@ static float LittleFloat (const float l) { return FloatSwap(&l); } // bk001205 - from Makefile #define stricmp strcasecmp -#define MAC_STATIC #define ID_INLINE inline #ifdef __i386__ @@ -375,14 +360,6 @@ static float LittleFloat (const float l) { return FloatSwap(&l); } #define PATH_SEP '/' -// bk001205 - try -#ifdef Q3_STATIC -#define GAME_HARD_LINKED -#define CGAME_HARD_LINKED -#define UI_HARD_LINKED -#define BOTLIB_HARD_LINKED -#endif - #if defined(_LITTLE_ENDIAN) inline static short BigShort( short l) { return ShortSwap(l); } #define LittleShort @@ -703,7 +680,7 @@ void ByteToDir( int b, vec3_t dir ); #endif -#ifdef __LCC__ +#ifdef Q3_VM #ifdef VectorCopy #undef VectorCopy // this is a little hack to get more efficient copies in our interpreter @@ -738,7 +715,7 @@ float RadiusFromBounds( const vec3_t mins, const vec3_t maxs ); void ClearBounds( vec3_t mins, vec3_t maxs ); void AddPointToBounds( const vec3_t v, vec3_t mins, vec3_t maxs ); -#ifndef __LCC__ +#ifndef Q3_VM static ID_INLINE int VectorCompare( const vec3_t v1, const vec3_t v2 ) { if (v1[0] != v2[0] || v1[1] != v2[1] || v1[2] != v2[2]) { return 0; diff --git a/code/renderer/tr_bsp.c b/code/renderer/tr_bsp.c index c237c8b..b0cbe50 100644 --- a/code/renderer/tr_bsp.c +++ b/code/renderer/tr_bsp.c @@ -135,7 +135,7 @@ R_LoadLightmaps static void R_LoadLightmaps( lump_t *l ) { byte *buf, *buf_p; int len; - MAC_STATIC byte image[LIGHTMAP_SIZE*LIGHTMAP_SIZE*4]; + byte image[LIGHTMAP_SIZE*LIGHTMAP_SIZE*4]; int i, j; float maxIntensity = 0; double sumIntensity = 0; @@ -379,7 +379,7 @@ static void ParseMesh ( dsurface_t *ds, drawVert_t *verts, msurface_t *surf ) { srfGridMesh_t *grid; int i, j; int width, height, numPoints; - MAC_STATIC drawVert_t points[MAX_PATCH_SIZE*MAX_PATCH_SIZE]; + drawVert_t points[MAX_PATCH_SIZE*MAX_PATCH_SIZE]; int lightmapNum; vec3_t bounds[2]; vec3_t tmpVec; diff --git a/code/renderer/tr_curve.c b/code/renderer/tr_curve.c index f241dbe..d57c99f 100644 --- a/code/renderer/tr_curve.c +++ b/code/renderer/tr_curve.c @@ -366,7 +366,7 @@ srfGridMesh_t *R_SubdividePatchToGrid( int width, int height, float len, maxLen; int dir; int t; - MAC_STATIC drawVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE]; + drawVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE]; float errorTable[2][MAX_GRID_SIZE]; for ( i = 0 ; i < width ; i++ ) { @@ -525,7 +525,7 @@ R_GridInsertColumn srfGridMesh_t *R_GridInsertColumn( srfGridMesh_t *grid, int column, int row, vec3_t point, float loderror ) { int i, j; int width, height, oldwidth; - MAC_STATIC drawVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE]; + drawVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE]; float errorTable[2][MAX_GRID_SIZE]; float lodRadius; vec3_t lodOrigin; @@ -579,7 +579,7 @@ R_GridInsertRow srfGridMesh_t *R_GridInsertRow( srfGridMesh_t *grid, int row, int column, vec3_t point, float loderror ) { int i, j; int width, height, oldheight; - MAC_STATIC drawVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE]; + drawVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE]; float errorTable[2][MAX_GRID_SIZE]; float lodRadius; vec3_t lodOrigin; diff --git a/code/renderer/tr_shade.c b/code/renderer/tr_shade.c index 16a2147..f85d336 100644 --- a/code/renderer/tr_shade.c +++ b/code/renderer/tr_shade.c @@ -422,7 +422,7 @@ static void ProjectDlightTexture( void ) { float *texCoords; byte *colors; byte clipBits[SHADER_MAX_VERTEXES]; - MAC_STATIC float texCoordsArray[SHADER_MAX_VERTEXES][2]; + float texCoordsArray[SHADER_MAX_VERTEXES][2]; byte colorArray[SHADER_MAX_VERTEXES][4]; unsigned hitIndexes[SHADER_MAX_INDEXES]; int numIndexes; diff --git a/code/server/sv_client.c b/code/server/sv_client.c index ba9d445..d7a755b 100644 --- a/code/server/sv_client.c +++ b/code/server/sv_client.c @@ -231,7 +231,7 @@ void SV_DirectConnect( netadr_t from ) { char userinfo[MAX_INFO_STRING]; int i; client_t *cl, *newcl; - MAC_STATIC client_t temp; + client_t temp; sharedEntity_t *ent; int clientNum; int version; diff --git a/code/splines/Splines.vcproj b/code/splines/Splines.vcproj deleted file mode 100644 index b39ad18..0000000 --- a/code/splines/Splines.vcproj +++ /dev/null @@ -1,296 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/code/splines/math_angles.cpp b/code/splines/math_angles.cpp deleted file mode 100644 index 5e6b597..0000000 --- a/code/splines/math_angles.cpp +++ /dev/null @@ -1,150 +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 Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -#include "q_shared.h" -#include - -angles_t ang_zero( 0.0f, 0.0f, 0.0f ); - -void toAngles( mat3_t &src, angles_t &dst ) { - double theta; - double cp; - double sp; - - sp = src[ 0 ][ 2 ]; - - // cap off our sin value so that we don't get any NANs - if ( sp > 1.0 ) { - sp = 1.0; - } else if ( sp < -1.0 ) { - sp = -1.0; - } - - theta = -asin( sp ); - cp = cos( theta ); - - if ( cp > 8192 * FLT_EPSILON ) { - dst.pitch = theta * 180 / M_PI; - dst.yaw = atan2( src[ 0 ][ 1 ], src[ 0 ][ 0 ] ) * 180 / M_PI; - dst.roll = atan2( src[ 1 ][ 2 ], src[ 2 ][ 2 ] ) * 180 / M_PI; - } else { - dst.pitch = theta * 180 / M_PI; - dst.yaw = -atan2( src[ 1 ][ 0 ], src[ 1 ][ 1 ] ) * 180 / M_PI; - dst.roll = 0; - } -} - -void toAngles( quat_t &src, angles_t &dst ) { - mat3_t temp; - - toMatrix( src, temp ); - toAngles( temp, dst ); -} - -void toAngles( idVec3_t &src, angles_t &dst ) { - dst.pitch = src[ 0 ]; - dst.yaw = src[ 1 ]; - dst.roll = src[ 2 ]; -} - -void angles_t::toVectors( idVec3_t *forward, idVec3_t *right, idVec3_t *up ) { - float angle; - static float sr, sp, sy, cr, cp, cy; // static to help MS compiler fp bugs - - angle = yaw * ( M_PI * 2 / 360 ); - sy = sin( angle ); - cy = cos( angle ); - - angle = pitch * ( M_PI * 2 / 360 ); - sp = sin( angle ); - cp = cos( angle ); - - angle = roll * ( M_PI * 2 / 360 ); - sr = sin( angle ); - cr = cos( angle ); - - if ( forward ) { - forward->set( cp * cy, cp * sy, -sp ); - } - - if ( right ) { - right->set( -sr * sp * cy + cr * sy, -sr * sp * sy + -cr * cy, -sr * cp ); - } - - if ( up ) { - up->set( cr * sp * cy + -sr * -sy, cr * sp * sy + -sr * cy, cr * cp ); - } -} - -idVec3_t angles_t::toForward( void ) { - float angle; - static float sp, sy, cp, cy; // static to help MS compiler fp bugs - - angle = yaw * ( M_PI * 2 / 360 ); - sy = sin( angle ); - cy = cos( angle ); - - angle = pitch * ( M_PI * 2 / 360 ); - sp = sin( angle ); - cp = cos( angle ); - - return idVec3_t( cp * cy, cp * sy, -sp ); -} - -/* -================= -Normalize360 - -returns angles normalized to the range [0 <= angle < 360] -================= -*/ -angles_t& angles_t::Normalize360( void ) { - pitch = (360.0 / 65536) * ( ( int )( pitch * ( 65536 / 360.0 ) ) & 65535 ); - yaw = (360.0 / 65536) * ( ( int )( yaw * ( 65536 / 360.0 ) ) & 65535 ); - roll = (360.0 / 65536) * ( ( int )( roll * ( 65536 / 360.0 ) ) & 65535 ); - - return *this; -} - - -/* -================= -Normalize180 - -returns angles normalized to the range [-180 < angle <= 180] -================= -*/ -angles_t& angles_t::Normalize180( void ) { - Normalize360(); - - if ( pitch > 180.0 ) { - pitch -= 360.0; - } - - if ( yaw > 180.0 ) { - yaw -= 360.0; - } - - if ( roll > 180.0 ) { - roll -= 360.0; - } - return *this; -} diff --git a/code/splines/math_angles.h b/code/splines/math_angles.h deleted file mode 100644 index 513ccc6..0000000 --- a/code/splines/math_angles.h +++ /dev/null @@ -1,195 +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 __MATH_ANGLES_H__ -#define __MATH_ANGLES_H__ - -#include -#include - -#include "math_vector.h" - -class mat3_t; -class quat_t; -class idVec3_t; -typedef idVec3_t &vec3_p; - -class angles_t { -public: - float pitch; - float yaw; - float roll; - - angles_t(); - angles_t( float pitch, float yaw, float roll ); - angles_t( const idVec3_t &vec ); - - friend void toAngles( idVec3_t &src, angles_t &dst ); - friend void toAngles( quat_t &src, angles_t &dst ); - friend void toAngles( mat3_t &src, angles_t &dst ); - - operator vec3_p(); - - float operator[]( int index ) const; - float& operator[]( int index ); - - void set( float pitch, float yaw, float roll ); - - void operator=( angles_t const &a ); - void operator=( idVec3_t const &a ); - - friend angles_t operator+( const angles_t &a, const angles_t &b ); - angles_t &operator+=( angles_t const &a ); - angles_t &operator+=( idVec3_t const &a ); - - friend angles_t operator-( angles_t &a, angles_t &b ); - angles_t &operator-=( angles_t &a ); - - friend angles_t operator*( const angles_t &a, float b ); - friend angles_t operator*( float a, const angles_t &b ); - angles_t &operator*=( float a ); - - friend int operator==( angles_t &a, angles_t &b ); - - friend int operator!=( angles_t &a, angles_t &b ); - - void toVectors( idVec3_t *forward, idVec3_t *right = NULL, idVec3_t *up = NULL ); - idVec3_t toForward( void ); - - angles_t &Zero( void ); - - angles_t &Normalize360( void ); - angles_t &Normalize180( void ); -}; - -extern angles_t ang_zero; - -inline angles_t::angles_t() {} - -inline angles_t::angles_t( float pitch, float yaw, float roll ) { - this->pitch = pitch; - this->yaw = yaw; - this->roll = roll; -} - -inline angles_t::angles_t( const idVec3_t &vec ) { - this->pitch = vec.x; - this->yaw = vec.y; - this->roll = vec.z; -} - -inline float angles_t::operator[]( int index ) const { - assert( ( index >= 0 ) && ( index < 3 ) ); - return ( &pitch )[ index ]; -} - -inline float& angles_t::operator[]( int index ) { - assert( ( index >= 0 ) && ( index < 3 ) ); - return ( &pitch )[ index ]; -} - -inline angles_t::operator vec3_p( void ) { - return *( idVec3_t * )&pitch; -} - -inline void angles_t::set( float pitch, float yaw, float roll ) { - this->pitch = pitch; - this->yaw = yaw; - this->roll = roll; -} - -inline void angles_t::operator=( angles_t const &a ) { - pitch = a.pitch; - yaw = a.yaw; - roll = a.roll; -} - -inline void angles_t::operator=( idVec3_t const &a ) { - pitch = a[ 0 ]; - yaw = a[ 1 ]; - roll = a[ 2 ]; -} - -inline angles_t operator+( const angles_t &a, const angles_t &b ) { - return angles_t( a.pitch + b.pitch, a.yaw + b.yaw, a.roll + b.roll ); -} - -inline angles_t& angles_t::operator+=( angles_t const &a ) { - pitch += a.pitch; - yaw += a.yaw; - roll += a.roll; - - return *this; -} - -inline angles_t& angles_t::operator+=( idVec3_t const &a ) { - pitch += a.x; - yaw += a.y; - roll += a.z; - - return *this; -} - -inline angles_t operator-( angles_t &a, angles_t &b ) { - return angles_t( a.pitch - b.pitch, a.yaw - b.yaw, a.roll - b.roll ); -} - -inline angles_t& angles_t::operator-=( angles_t &a ) { - pitch -= a.pitch; - yaw -= a.yaw; - roll -= a.roll; - - return *this; -} - -inline angles_t operator*( const angles_t &a, float b ) { - return angles_t( a.pitch * b, a.yaw * b, a.roll * b ); -} - -inline angles_t operator*( float a, const angles_t &b ) { - return angles_t( a * b.pitch, a * b.yaw, a * b.roll ); -} - -inline angles_t& angles_t::operator*=( float a ) { - pitch *= a; - yaw *= a; - roll *= a; - - return *this; -} - -inline int operator==( angles_t &a, angles_t &b ) { - return ( ( a.pitch == b.pitch ) && ( a.yaw == b.yaw ) && ( a.roll == b.roll ) ); -} - -inline int operator!=( angles_t &a, angles_t &b ) { - return ( ( a.pitch != b.pitch ) || ( a.yaw != b.yaw ) || ( a.roll != b.roll ) ); -} - -inline angles_t& angles_t::Zero( void ) { - pitch = 0.0f; - yaw = 0.0f; - roll = 0.0f; - - return *this; -} - -#endif /* !__MATH_ANGLES_H__ */ diff --git a/code/splines/math_matrix.cpp b/code/splines/math_matrix.cpp deleted file mode 100644 index 5f8181a..0000000 --- a/code/splines/math_matrix.cpp +++ /dev/null @@ -1,134 +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 Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -#include "q_shared.h" - -mat3_t mat3_default( idVec3_t( 1, 0, 0 ), idVec3_t( 0, 1, 0 ), idVec3_t( 0, 0, 1 ) ); - -void toMatrix( quat_t const &src, mat3_t &dst ) { - float wx, wy, wz; - float xx, yy, yz; - float xy, xz, zz; - float x2, y2, z2; - - x2 = src.x + src.x; - y2 = src.y + src.y; - z2 = src.z + src.z; - - xx = src.x * x2; - xy = src.x * y2; - xz = src.x * z2; - - yy = src.y * y2; - yz = src.y * z2; - zz = src.z * z2; - - wx = src.w * x2; - wy = src.w * y2; - wz = src.w * z2; - - dst[ 0 ][ 0 ] = 1.0f - ( yy + zz ); - dst[ 0 ][ 1 ] = xy - wz; - dst[ 0 ][ 2 ] = xz + wy; - - dst[ 1 ][ 0 ] = xy + wz; - dst[ 1 ][ 1 ] = 1.0f - ( xx + zz ); - dst[ 1 ][ 2 ] = yz - wx; - - dst[ 2 ][ 0 ] = xz - wy; - dst[ 2 ][ 1 ] = yz + wx; - dst[ 2 ][ 2 ] = 1.0f - ( xx + yy ); -} - -void toMatrix( angles_t const &src, mat3_t &dst ) { - float angle; - static float sr, sp, sy, cr, cp, cy; // static to help MS compiler fp bugs - - angle = src.yaw * ( M_PI * 2.0f / 360.0f ); - sy = sin( angle ); - cy = cos( angle ); - - angle = src.pitch * ( M_PI * 2.0f / 360.0f ); - sp = sin( angle ); - cp = cos( angle ); - - angle = src.roll * ( M_PI * 2.0f / 360.0f ); - sr = sin( angle ); - cr = cos( angle ); - - dst[ 0 ].set( cp * cy, cp * sy, -sp ); - dst[ 1 ].set( sr * sp * cy + cr * -sy, sr * sp * sy + cr * cy, sr * cp ); - dst[ 2 ].set( cr * sp * cy + -sr * -sy, cr * sp * sy + -sr * cy, cr * cp ); -} - -void toMatrix( idVec3_t const &src, mat3_t &dst ) { - angles_t sup = src; - toMatrix(sup, dst); -} - -void mat3_t::ProjectVector( const idVec3_t &src, idVec3_t &dst ) const { - dst.x = src * mat[ 0 ]; - dst.y = src * mat[ 1 ]; - dst.z = src * mat[ 2 ]; -} - -void mat3_t::UnprojectVector( const idVec3_t &src, idVec3_t &dst ) const { - dst = mat[ 0 ] * src.x + mat[ 1 ] * src.y + mat[ 2 ] * src.z; -} - -void mat3_t::Transpose( mat3_t &matrix ) { - int i; - int j; - - for( i = 0; i < 3; i++ ) { - for( j = 0; j < 3; j++ ) { - matrix[ i ][ j ] = mat[ j ][ i ]; - } - } -} - -void mat3_t::Transpose( void ) { - float temp; - int i; - int j; - - for( i = 0; i < 3; i++ ) { - for( j = i + 1; j < 3; j++ ) { - temp = mat[ i ][ j ]; - mat[ i ][ j ] = mat[ j ][ i ]; - mat[ j ][ i ] = temp; - } - } -} - -mat3_t mat3_t::Inverse( void ) const { - mat3_t inv( *this ); - - inv.Transpose(); - - return inv; -} - -void mat3_t::Clear( void ) { - mat[0].set( 1, 0, 0 ); - mat[1].set( 0, 1, 0 ); - mat[2].set( 0, 0, 1 ); -} diff --git a/code/splines/math_matrix.h b/code/splines/math_matrix.h deleted file mode 100644 index 4c5b0d4..0000000 --- a/code/splines/math_matrix.h +++ /dev/null @@ -1,223 +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 __MATH_MATRIX_H__ -#define __MATH_MATRIX_H__ - -#include -#include "math_vector.h" - -#ifndef ID_INLINE -#ifdef _WIN32 -#define ID_INLINE __inline -#else -#define ID_INLINE inline -#endif -#endif - -class quat_t; -class angles_t; - -class mat3_t { -public: - idVec3_t mat[ 3 ]; - - mat3_t(); - mat3_t( float src[ 3 ][ 3 ] ); - mat3_t( idVec3_t const &x, idVec3_t const &y, idVec3_t const &z ); - mat3_t( const float xx, const float xy, const float xz, const float yx, const float yy, const float yz, const float zx, const float zy, const float zz ); - - friend void toMatrix( quat_t const &src, mat3_t &dst ); - friend void toMatrix( angles_t const &src, mat3_t &dst ); - friend void toMatrix( idVec3_t const &src, mat3_t &dst ); - - idVec3_t operator[]( int index ) const; - idVec3_t &operator[]( int index ); - - idVec3_t operator*( const idVec3_t &vec ) const; - mat3_t operator*( const mat3_t &a ) const; - mat3_t operator*( float a ) const; - mat3_t operator+( mat3_t const &a ) const; - mat3_t operator-( mat3_t const &a ) const; - - friend idVec3_t operator*( const idVec3_t &vec, const mat3_t &mat ); - friend mat3_t operator*( float a, mat3_t const &b ); - - mat3_t &operator*=( float a ); - mat3_t &operator+=( mat3_t const &a ); - mat3_t &operator-=( mat3_t const &a ); - - void Clear( void ); - - void ProjectVector( const idVec3_t &src, idVec3_t &dst ) const; - void UnprojectVector( const idVec3_t &src, idVec3_t &dst ) const; - - void OrthoNormalize( void ); - void Transpose( mat3_t &matrix ); - void Transpose( void ); - mat3_t Inverse( void ) const; - void Identity( void ); - - friend void InverseMultiply( const mat3_t &inv, const mat3_t &b, mat3_t &dst ); - friend mat3_t SkewSymmetric( idVec3_t const &src ); -}; - -ID_INLINE mat3_t::mat3_t() { -} - -ID_INLINE mat3_t::mat3_t( float src[ 3 ][ 3 ] ) { - memcpy( mat, src, sizeof( src ) ); -} - -ID_INLINE mat3_t::mat3_t( idVec3_t const &x, idVec3_t const &y, idVec3_t const &z ) { - mat[ 0 ].x = x.x; mat[ 0 ].y = x.y; mat[ 0 ].z = x.z; - mat[ 1 ].x = y.x; mat[ 1 ].y = y.y; mat[ 1 ].z = y.z; - mat[ 2 ].x = z.x; mat[ 2 ].y = z.y; mat[ 2 ].z = z.z; -} - -ID_INLINE mat3_t::mat3_t( const float xx, const float xy, const float xz, const float yx, const float yy, const float yz, const float zx, const float zy, const float zz ) { - mat[ 0 ].x = xx; mat[ 0 ].y = xy; mat[ 0 ].z = xz; - mat[ 1 ].x = yx; mat[ 1 ].y = yy; mat[ 1 ].z = yz; - mat[ 2 ].x = zx; mat[ 2 ].y = zy; mat[ 2 ].z = zz; -} - -ID_INLINE idVec3_t mat3_t::operator[]( int index ) const { - assert( ( index >= 0 ) && ( index < 3 ) ); - return mat[ index ]; -} - -ID_INLINE idVec3_t& mat3_t::operator[]( int index ) { - assert( ( index >= 0 ) && ( index < 3 ) ); - return mat[ index ]; -} - -ID_INLINE idVec3_t mat3_t::operator*( const idVec3_t &vec ) const { - return idVec3_t( - mat[ 0 ].x * vec.x + mat[ 1 ].x * vec.y + mat[ 2 ].x * vec.z, - mat[ 0 ].y * vec.x + mat[ 1 ].y * vec.y + mat[ 2 ].y * vec.z, - mat[ 0 ].z * vec.x + mat[ 1 ].z * vec.y + mat[ 2 ].z * vec.z ); -} - -ID_INLINE mat3_t mat3_t::operator*( const mat3_t &a ) const { - return mat3_t( - mat[0].x * a[0].x + mat[0].y * a[1].x + mat[0].z * a[2].x, - mat[0].x * a[0].y + mat[0].y * a[1].y + mat[0].z * a[2].y, - mat[0].x * a[0].z + mat[0].y * a[1].z + mat[0].z * a[2].z, - mat[1].x * a[0].x + mat[1].y * a[1].x + mat[1].z * a[2].x, - mat[1].x * a[0].y + mat[1].y * a[1].y + mat[1].z * a[2].y, - mat[1].x * a[0].z + mat[1].y * a[1].z + mat[1].z * a[2].z, - mat[2].x * a[0].x + mat[2].y * a[1].x + mat[2].z * a[2].x, - mat[2].x * a[0].y + mat[2].y * a[1].y + mat[2].z * a[2].y, - mat[2].x * a[0].z + mat[2].y * a[1].z + mat[2].z * a[2].z ); -} - -ID_INLINE mat3_t mat3_t::operator*( float a ) const { - return mat3_t( - mat[0].x * a, mat[0].y * a, mat[0].z * a, - mat[1].x * a, mat[1].y * a, mat[1].z * a, - mat[2].x * a, mat[2].y * a, mat[2].z * a ); -} - -ID_INLINE mat3_t mat3_t::operator+( mat3_t const &a ) const { - return mat3_t( - mat[0].x + a[0].x, mat[0].y + a[0].y, mat[0].z + a[0].z, - mat[1].x + a[1].x, mat[1].y + a[1].y, mat[1].z + a[1].z, - mat[2].x + a[2].x, mat[2].y + a[2].y, mat[2].z + a[2].z ); -} - -ID_INLINE mat3_t mat3_t::operator-( mat3_t const &a ) const { - return mat3_t( - mat[0].x - a[0].x, mat[0].y - a[0].y, mat[0].z - a[0].z, - mat[1].x - a[1].x, mat[1].y - a[1].y, mat[1].z - a[1].z, - mat[2].x - a[2].x, mat[2].y - a[2].y, mat[2].z - a[2].z ); -} - -ID_INLINE idVec3_t operator*( const idVec3_t &vec, const mat3_t &mat ) { - return idVec3_t( - mat[ 0 ].x * vec.x + mat[ 1 ].x * vec.y + mat[ 2 ].x * vec.z, - mat[ 0 ].y * vec.x + mat[ 1 ].y * vec.y + mat[ 2 ].y * vec.z, - mat[ 0 ].z * vec.x + mat[ 1 ].z * vec.y + mat[ 2 ].z * vec.z ); -} - -ID_INLINE mat3_t operator*( float a, mat3_t const &b ) { - return mat3_t( - b[0].x * a, b[0].y * a, b[0].z * a, - b[1].x * a, b[1].y * a, b[1].z * a, - b[2].x * a, b[2].y * a, b[2].z * a ); -} - -ID_INLINE mat3_t &mat3_t::operator*=( float a ) { - mat[0].x *= a; mat[0].y *= a; mat[0].z *= a; - mat[1].x *= a; mat[1].y *= a; mat[1].z *= a; - mat[2].x *= a; mat[2].y *= a; mat[2].z *= a; - - return *this; -} - -ID_INLINE mat3_t &mat3_t::operator+=( mat3_t const &a ) { - mat[0].x += a[0].x; mat[0].y += a[0].y; mat[0].z += a[0].z; - mat[1].x += a[1].x; mat[1].y += a[1].y; mat[1].z += a[1].z; - mat[2].x += a[2].x; mat[2].y += a[2].y; mat[2].z += a[2].z; - - return *this; -} - -ID_INLINE mat3_t &mat3_t::operator-=( mat3_t const &a ) { - mat[0].x -= a[0].x; mat[0].y -= a[0].y; mat[0].z -= a[0].z; - mat[1].x -= a[1].x; mat[1].y -= a[1].y; mat[1].z -= a[1].z; - mat[2].x -= a[2].x; mat[2].y -= a[2].y; mat[2].z -= a[2].z; - - return *this; -} - -ID_INLINE void mat3_t::OrthoNormalize( void ) { - mat[ 0 ].Normalize(); - mat[ 2 ].Cross( mat[ 0 ], mat[ 1 ] ); - mat[ 2 ].Normalize(); - mat[ 1 ].Cross( mat[ 2 ], mat[ 0 ] ); - mat[ 1 ].Normalize(); -} - -ID_INLINE void mat3_t::Identity( void ) { - mat[ 0 ].x = 1.f; mat[ 0 ].y = 0.f; mat[ 0 ].z = 0.f; - mat[ 1 ].x = 0.f; mat[ 1 ].y = 1.f; mat[ 1 ].z = 0.f; - mat[ 2 ].x = 0.f; mat[ 2 ].y = 0.f; mat[ 2 ].z = 1.f; -} - -ID_INLINE void InverseMultiply( const mat3_t &inv, const mat3_t &b, mat3_t &dst ) { - dst[0].x = inv[0].x * b[0].x + inv[1].x * b[1].x + inv[2].x * b[2].x; - dst[0].y = inv[0].x * b[0].y + inv[1].x * b[1].y + inv[2].x * b[2].y; - dst[0].z = inv[0].x * b[0].z + inv[1].x * b[1].z + inv[2].x * b[2].z; - dst[1].x = inv[0].y * b[0].x + inv[1].y * b[1].x + inv[2].y * b[2].x; - dst[1].y = inv[0].y * b[0].y + inv[1].y * b[1].y + inv[2].y * b[2].y; - dst[1].z = inv[0].y * b[0].z + inv[1].y * b[1].z + inv[2].y * b[2].z; - dst[2].x = inv[0].z * b[0].x + inv[1].z * b[1].x + inv[2].z * b[2].x; - dst[2].y = inv[0].z * b[0].y + inv[1].z * b[1].y + inv[2].z * b[2].y; - dst[2].z = inv[0].z * b[0].z + inv[1].z * b[1].z + inv[2].z * b[2].z; -} - -ID_INLINE mat3_t SkewSymmetric( idVec3_t const &src ) { - return mat3_t( 0.0f, -src.z, src.y, src.z, 0.0f, -src.x, -src.y, src.x, 0.0f ); -} - -extern mat3_t mat3_default; - -#endif /* !__MATH_MATRIX_H__ */ diff --git a/code/splines/math_quaternion.cpp b/code/splines/math_quaternion.cpp deleted file mode 100644 index d799ce9..0000000 --- a/code/splines/math_quaternion.cpp +++ /dev/null @@ -1,78 +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 Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -#include "math_quaternion.h" -#include "math_matrix.h" - -void toQuat( idVec3_t &src, quat_t &dst ) { - dst.x = src.x; - dst.y = src.y; - dst.z = src.z; - dst.w = 0.0f; -} - -void toQuat( angles_t &src, quat_t &dst ) { - mat3_t temp; - - toMatrix( src, temp ); - toQuat( temp, dst ); -} - -void toQuat( mat3_t &src, quat_t &dst ) { - float trace; - float s; - int i; - int j; - int k; - - static int next[ 3 ] = { 1, 2, 0 }; - - trace = src[ 0 ][ 0 ] + src[ 1 ][ 1 ] + src[ 2 ][ 2 ]; - if ( trace > 0.0f ) { - s = ( float )sqrt( trace + 1.0f ); - dst.w = s * 0.5f; - s = 0.5f / s; - - dst.x = ( src[ 2 ][ 1 ] - src[ 1 ][ 2 ] ) * s; - dst.y = ( src[ 0 ][ 2 ] - src[ 2 ][ 0 ] ) * s; - dst.z = ( src[ 1 ][ 0 ] - src[ 0 ][ 1 ] ) * s; - } else { - i = 0; - if ( src[ 1 ][ 1 ] > src[ 0 ][ 0 ] ) { - i = 1; - } - if ( src[ 2 ][ 2 ] > src[ i ][ i ] ) { - i = 2; - } - - j = next[ i ]; - k = next[ j ]; - - s = ( float )sqrt( ( src[ i ][ i ] - ( src[ j ][ j ] + src[ k ][ k ] ) ) + 1.0f ); - dst[ i ] = s * 0.5f; - - s = 0.5f / s; - - dst.w = ( src[ k ][ j ] - src[ j ][ k ] ) * s; - dst[ j ] = ( src[ j ][ i ] + src[ i ][ j ] ) * s; - dst[ k ] = ( src[ k ][ i ] + src[ i ][ k ] ) * s; - } -} diff --git a/code/splines/math_quaternion.h b/code/splines/math_quaternion.h deleted file mode 100644 index 7ff7e81..0000000 --- a/code/splines/math_quaternion.h +++ /dev/null @@ -1,190 +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 __MATH_QUATERNION_H__ -#define __MATH_QUATERNION_H__ - -#include -#include - -class idVec3_t; -class angles_t; -class mat3_t; - -class quat_t { -public: - float x; - float y; - float z; - float w; - - quat_t(); - quat_t( float x, float y, float z, float w ); - - friend void toQuat( idVec3_t &src, quat_t &dst ); - friend void toQuat( angles_t &src, quat_t &dst ); - friend void toQuat( mat3_t &src, quat_t &dst ); - - float *vec4( void ); - - float operator[]( int index ) const; - float &operator[]( int index ); - - void set( float x, float y, float z, float w ); - - void operator=( quat_t a ); - - friend quat_t operator+( quat_t a, quat_t b ); - quat_t &operator+=( quat_t a ); - - friend quat_t operator-( quat_t a, quat_t b ); - quat_t &operator-=( quat_t a ); - - friend quat_t operator*( quat_t a, float b ); - friend quat_t operator*( float a, quat_t b ); - quat_t &operator*=( float a ); - - friend int operator==( quat_t a, quat_t b ); - friend int operator!=( quat_t a, quat_t b ); - - float Length( void ); - quat_t &Normalize( void ); - - quat_t operator-(); -}; - -inline quat_t::quat_t() { -} - -inline quat_t::quat_t( float x, float y, float z, float w ) { - this->x = x; - this->y = y; - this->z = z; - this->w = w; -} - -inline float *quat_t::vec4( void ) { - return &x; -} - -inline float quat_t::operator[]( int index ) const { - assert( ( index >= 0 ) && ( index < 4 ) ); - return ( &x )[ index ]; -} - -inline float& quat_t::operator[]( int index ) { - assert( ( index >= 0 ) && ( index < 4 ) ); - return ( &x )[ index ]; -} - -inline void quat_t::set( float x, float y, float z, float w ) { - this->x = x; - this->y = y; - this->z = z; - this->w = w; -} - -inline void quat_t::operator=( quat_t a ) { - x = a.x; - y = a.y; - z = a.z; - w = a.w; -} - -inline quat_t operator+( quat_t a, quat_t b ) { - return quat_t( a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w ); -} - -inline quat_t& quat_t::operator+=( quat_t a ) { - x += a.x; - y += a.y; - z += a.z; - w += a.w; - - return *this; -} - -inline quat_t operator-( quat_t a, quat_t b ) { - return quat_t( a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w ); -} - -inline quat_t& quat_t::operator-=( quat_t a ) { - x -= a.x; - y -= a.y; - z -= a.z; - w -= a.w; - - return *this; -} - -inline quat_t operator*( quat_t a, float b ) { - return quat_t( a.x * b, a.y * b, a.z * b, a.w * b ); -} - -inline quat_t operator*( float a, quat_t b ) { - return b * a; -} - -inline quat_t& quat_t::operator*=( float a ) { - x *= a; - y *= a; - z *= a; - w *= a; - - return *this; -} - -inline int operator==( quat_t a, quat_t b ) { - return ( ( a.x == b.x ) && ( a.y == b.y ) && ( a.z == b.z ) && ( a.w == b.w ) ); -} - -inline int operator!=( quat_t a, quat_t b ) { - return ( ( a.x != b.x ) || ( a.y != b.y ) || ( a.z != b.z ) && ( a.w != b.w ) ); -} - -inline float quat_t::Length( void ) { - float length; - - length = x * x + y * y + z * z + w * w; - return ( float )sqrt( length ); -} - -inline quat_t& quat_t::Normalize( void ) { - float length; - float ilength; - - length = this->Length(); - if ( length ) { - ilength = 1 / length; - x *= ilength; - y *= ilength; - z *= ilength; - w *= ilength; - } - - return *this; -} - -inline quat_t quat_t::operator-() { - return quat_t( -x, -y, -z, -w ); -} - -#endif /* !__MATH_QUATERNION_H__ */ diff --git a/code/splines/math_vector.cpp b/code/splines/math_vector.cpp deleted file mode 100644 index baa93d3..0000000 --- a/code/splines/math_vector.cpp +++ /dev/null @@ -1,144 +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 Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -//#include "../game/q_shared.h" -#include "math_vector.h" -#include -#include -#include -#include -#include -#include -#include -#include - -#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h - -#define LERP_DELTA 1e-6 - -idVec3_t vec_zero( 0.0f, 0.0f, 0.0f ); - -Bounds boundsZero; - -float idVec3_t::toYaw( void ) { - float yaw; - - if ( ( y == 0 ) && ( x == 0 ) ) { - yaw = 0; - } else { - yaw = atan2( y, x ) * 180 / M_PI; - if ( yaw < 0 ) { - yaw += 360; - } - } - - return yaw; -} - -float idVec3_t::toPitch( void ) { - float forward; - float pitch; - - if ( ( x == 0 ) && ( y == 0 ) ) { - if ( z > 0 ) { - pitch = 90; - } else { - pitch = 270; - } - } else { - forward = ( float )idSqrt( x * x + y * y ); - pitch = atan2( z, forward ) * 180 / M_PI; - if ( pitch < 0 ) { - pitch += 360; - } - } - - return pitch; -} - -/* -angles_t idVec3_t::toAngles( void ) { - float forward; - float yaw; - float pitch; - - if ( ( x == 0 ) && ( y == 0 ) ) { - yaw = 0; - if ( z > 0 ) { - pitch = 90; - } else { - pitch = 270; - } - } else { - yaw = atan2( y, x ) * 180 / M_PI; - if ( yaw < 0 ) { - yaw += 360; - } - - forward = ( float )idSqrt( x * x + y * y ); - pitch = atan2( z, forward ) * 180 / M_PI; - if ( pitch < 0 ) { - pitch += 360; - } - } - - return angles_t( -pitch, yaw, 0 ); -} -*/ - -idVec3_t LerpVector( idVec3_t &w1, idVec3_t &w2, const float t ) { - float omega, cosom, sinom, scale0, scale1; - - cosom = w1 * w2; - if ( ( 1.0 - cosom ) > LERP_DELTA ) { - omega = acos( cosom ); - sinom = sin( omega ); - scale0 = sin( ( 1.0 - t ) * omega ) / sinom; - scale1 = sin( t * omega ) / sinom; - } else { - scale0 = 1.0 - t; - scale1 = t; - } - - return ( w1 * scale0 + w2 * scale1 ); -} - -/* -============= -idVec3_t::string - -This is just a convenience function -for printing vectors -============= -*/ -char *idVec3_t::string( void ) { - static int index = 0; - static char str[ 8 ][ 36 ]; - char *s; - - // use an array so that multiple toString's won't collide - s = str[ index ]; - index = (index + 1)&7; - - sprintf( s, "%.2f %.2f %.2f", x, y, z ); - - return s; -} diff --git a/code/splines/math_vector.h b/code/splines/math_vector.h deleted file mode 100644 index 3e04074..0000000 --- a/code/splines/math_vector.h +++ /dev/null @@ -1,574 +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 __MATH_VECTOR_H__ -#define __MATH_VECTOR_H__ - -#if defined(_WIN32) -#pragma warning(disable : 4244) -#endif - -#include -#include - -//#define DotProduct(a,b) ((a)[0]*(b)[0]+(a)[1]*(b)[1]+(a)[2]*(b)[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 VectorCopy(a,b) ((b).x=(a).x,(b).y=(a).y,(b).z=(a).z]) - -//#define VectorScale(v, s, o) ((o)[0]=(v)[0]*(s),(o)[1]=(v)[1]*(s),(o)[2]=(v)[2]*(s)) -#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)) -//#define CrossProduct(a,b,c) ((c)[0]=(a)[1]*(b)[2]-(a)[2]*(b)[1],(c)[1]=(a)[2]*(b)[0]-(a)[0]*(b)[2],(c)[2]=(a)[0]*(b)[1]-(a)[1]*(b)[0]) - -#define DotProduct4(x,y) ((x)[0]*(y)[0]+(x)[1]*(y)[1]+(x)[2]*(y)[2]+(x)[3]*(y)[3]) -#define VectorSubtract4(a,b,c) ((c)[0]=(a)[0]-(b)[0],(c)[1]=(a)[1]-(b)[1],(c)[2]=(a)[2]-(b)[2],(c)[3]=(a)[3]-(b)[3]) -#define VectorAdd4(a,b,c) ((c)[0]=(a)[0]+(b)[0],(c)[1]=(a)[1]+(b)[1],(c)[2]=(a)[2]+(b)[2],(c)[3]=(a)[3]+(b)[3]) -#define VectorCopy4(a,b) ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2],(b)[3]=(a)[3]) -#define VectorScale4(v, s, o) ((o)[0]=(v)[0]*(s),(o)[1]=(v)[1]*(s),(o)[2]=(v)[2]*(s),(o)[3]=(v)[3]*(s)) -#define VectorMA4(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),(o)[3]=(v)[3]+(b)[3]*(s)) - - -//#define VectorClear(a) ((a)[0]=(a)[1]=(a)[2]=0) -#define VectorNegate(a,b) ((b)[0]=-(a)[0],(b)[1]=-(a)[1],(b)[2]=-(a)[2]) -//#define VectorSet(v, x, y, z) ((v)[0]=(x), (v)[1]=(y), (v)[2]=(z)) -#define Vector4Copy(a,b) ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2],(b)[3]=(a)[3]) - -#define SnapVector(v) {v[0]=(int)v[0];v[1]=(int)v[1];v[2]=(int)v[2];} - - -//#include "util_heap.h" - -#ifndef EQUAL_EPSILON -#define EQUAL_EPSILON 0.001 -#endif - -float Q_fabs( float f ); - -#ifndef ID_INLINE -#ifdef _WIN32 -#define ID_INLINE __inline -#else -#define ID_INLINE inline -#endif -#endif - -// if this is defined, vec3 will take four elements, which may allow -// easier SIMD optimizations -//#define FAT_VEC3 -//#ifdef __ppc__ -//#pragma align(16) -//#endif - -class angles_t; -#ifdef __ppc__ -// Vanilla PPC code, but since PPC has a reciprocal square root estimate instruction, -// runs *much* faster than calling sqrt(). We'll use two Newton-Raphson -// refinement steps to get bunch more precision in the 1/sqrt() value for very little cost. -// We'll then multiply 1/sqrt times the original value to get the sqrt. -// This is about 12.4 times faster than sqrt() and according to my testing (not exhaustive) -// it returns fairly accurate results (error below 1.0e-5 up to 100000.0 in 0.1 increments). - -static inline float idSqrt(float x) { - const float half = 0.5; - const float one = 1.0; - float B, y0, y1; - - // This'll NaN if it hits frsqrte. Handle both +0.0 and -0.0 - if (fabs(x) == 0.0) - return x; - B = x; - -#ifdef __GNUC__ - asm("frsqrte %0,%1" : "=f" (y0) : "f" (B)); -#else - y0 = __frsqrte(B); -#endif - /* First refinement step */ - - y1 = y0 + half*y0*(one - B*y0*y0); - - /* Second refinement step -- copy the output of the last step to the input of this step */ - - y0 = y1; - y1 = y0 + half*y0*(one - B*y0*y0); - - /* Get sqrt(x) from x * 1/sqrt(x) */ - return x * y1; -} -#else -static inline double idSqrt(double x) { - return sqrt(x); -} -#endif - - -//class idVec3_t : public idHeap { -class idVec3_t { -public: -#ifndef FAT_VEC3 - float x,y,z; -#else - float x,y,z,dist; -#endif - -#ifndef FAT_VEC3 - idVec3_t() {}; -#else - idVec3_t() {dist = 0.0f;}; -#endif - idVec3_t( const float x, const float y, const float z ); - - operator float *(); - - float operator[]( const int index ) const; - float &operator[]( const int index ); - - void set( const float x, const float y, const float z ); - - idVec3_t operator-() const; - - idVec3_t &operator=( const idVec3_t &a ); - - float operator*( const idVec3_t &a ) const; - idVec3_t operator*( const float a ) const; - friend idVec3_t operator*( float a, idVec3_t b ); - - idVec3_t operator+( const idVec3_t &a ) const; - idVec3_t operator-( const idVec3_t &a ) const; - - idVec3_t &operator+=( const idVec3_t &a ); - idVec3_t &operator-=( const idVec3_t &a ); - idVec3_t &operator*=( const float a ); - - int operator==( const idVec3_t &a ) const; - int operator!=( const idVec3_t &a ) const; - - idVec3_t Cross( const idVec3_t &a ) const; - idVec3_t &Cross( const idVec3_t &a, const idVec3_t &b ); - - float Length( void ) const; - float Normalize( void ); - - void Zero( void ); - void Snap( void ); - void SnapTowards( const idVec3_t &to ); - - float toYaw( void ); - float toPitch( void ); - angles_t toAngles( void ); - friend idVec3_t LerpVector( const idVec3_t &w1, const idVec3_t &w2, const float t ); - - char *string( void ); -}; - -extern idVec3_t vec_zero; - -ID_INLINE idVec3_t::idVec3_t( const float x, const float y, const float z ) { - this->x = x; - this->y = y; - this->z = z; -#ifdef FAT_VEC3 - this->dist = 0.0f; -#endif -} - -ID_INLINE float idVec3_t::operator[]( const int index ) const { - return ( &x )[ index ]; -} - -ID_INLINE float &idVec3_t::operator[]( const int index ) { - return ( &x )[ index ]; -} - -ID_INLINE idVec3_t::operator float *( void ) { - return &x; -} - -ID_INLINE idVec3_t idVec3_t::operator-() const { - return idVec3_t( -x, -y, -z ); -} - -ID_INLINE idVec3_t &idVec3_t::operator=( const idVec3_t &a ) { - x = a.x; - y = a.y; - z = a.z; - - return *this; -} - -ID_INLINE void idVec3_t::set( const float x, const float y, const float z ) { - this->x = x; - this->y = y; - this->z = z; -} - -ID_INLINE idVec3_t idVec3_t::operator-( const idVec3_t &a ) const { - return idVec3_t( x - a.x, y - a.y, z - a.z ); -} - -ID_INLINE float idVec3_t::operator*( const idVec3_t &a ) const { - return x * a.x + y * a.y + z * a.z; -} - -ID_INLINE idVec3_t idVec3_t::operator*( const float a ) const { - return idVec3_t( x * a, y * a, z * a ); -} - -ID_INLINE idVec3_t operator*( const float a, const idVec3_t b ) { - return idVec3_t( b.x * a, b.y * a, b.z * a ); -} - -ID_INLINE idVec3_t idVec3_t::operator+( const idVec3_t &a ) const { - return idVec3_t( x + a.x, y + a.y, z + a.z ); -} - -ID_INLINE idVec3_t &idVec3_t::operator+=( const idVec3_t &a ) { - x += a.x; - y += a.y; - z += a.z; - - return *this; -} - -ID_INLINE idVec3_t &idVec3_t::operator-=( const idVec3_t &a ) { - x -= a.x; - y -= a.y; - z -= a.z; - - return *this; -} - -ID_INLINE idVec3_t &idVec3_t::operator*=( const float a ) { - x *= a; - y *= a; - z *= a; - - return *this; -} - -ID_INLINE int idVec3_t::operator==( const idVec3_t &a ) const { - if ( Q_fabs( x - a.x ) > EQUAL_EPSILON ) { - return false; - } - - if ( Q_fabs( y - a.y ) > EQUAL_EPSILON ) { - return false; - } - - if ( Q_fabs( z - a.z ) > EQUAL_EPSILON ) { - return false; - } - - return true; -} - -ID_INLINE int idVec3_t::operator!=( const idVec3_t &a ) const { - if ( Q_fabs( x - a.x ) > EQUAL_EPSILON ) { - return true; - } - - if ( Q_fabs( y - a.y ) > EQUAL_EPSILON ) { - return true; - } - - if ( Q_fabs( z - a.z ) > EQUAL_EPSILON ) { - return true; - } - - return false; -} - -ID_INLINE idVec3_t idVec3_t::Cross( const idVec3_t &a ) const { - return idVec3_t( y * a.z - z * a.y, z * a.x - x * a.z, x * a.y - y * a.x ); -} - -ID_INLINE idVec3_t &idVec3_t::Cross( const idVec3_t &a, const idVec3_t &b ) { - x = a.y * b.z - a.z * b.y; - y = a.z * b.x - a.x * b.z; - z = a.x * b.y - a.y * b.x; - - return *this; -} - -ID_INLINE float idVec3_t::Length( void ) const { - float length; - - length = x * x + y * y + z * z; - return ( float )idSqrt( length ); -} - -ID_INLINE float idVec3_t::Normalize( void ) { - float length; - float ilength; - - length = this->Length(); - if ( length ) { - ilength = 1.0f / length; - x *= ilength; - y *= ilength; - z *= ilength; - } - - return length; -} - -ID_INLINE void idVec3_t::Zero( void ) { - x = 0.0f; - y = 0.0f; - z = 0.0f; -} - -ID_INLINE void idVec3_t::Snap( void ) { - x = float( int( x ) ); - y = float( int( y ) ); - z = float( int( z ) ); -} - -/* -====================== -SnapTowards - -Round a vector to integers for more efficient network -transmission, but make sure that it rounds towards a given point -rather than blindly truncating. This prevents it from truncating -into a wall. -====================== -*/ -ID_INLINE void idVec3_t::SnapTowards( const idVec3_t &to ) { - if ( to.x <= x ) { - x = float( int( x ) ); - } else { - x = float( int( x ) + 1 ); - } - - if ( to.y <= y ) { - y = float( int( y ) ); - } else { - y = float( int( y ) + 1 ); - } - - if ( to.z <= z ) { - z = float( int( z ) ); - } else { - z = float( int( z ) + 1 ); - } -} - -//=============================================================== - -class Bounds { -public: - idVec3_t b[2]; - - Bounds(); - Bounds( const idVec3_t &mins, const idVec3_t &maxs ); - - void Clear(); - void Zero(); - float Radius(); // radius from origin, not from center - idVec3_t Center(); - void AddPoint( const idVec3_t &v ); - void AddBounds( const Bounds &bb ); - bool IsCleared(); - bool ContainsPoint( const idVec3_t &p ); - bool IntersectsBounds( const Bounds &b2 ); // touching is NOT intersecting -}; - -extern Bounds boundsZero; - -ID_INLINE Bounds::Bounds(){ -} - -ID_INLINE bool Bounds::IsCleared() { - return b[0][0] > b[1][0]; -} - -ID_INLINE bool Bounds::ContainsPoint( const idVec3_t &p ) { - if ( p[0] < b[0][0] || p[1] < b[0][1] || p[2] < b[0][2] - || p[0] > b[1][0] || p[1] > b[1][1] || p[2] > b[1][2] ) { - return false; - } - return true; -} - -ID_INLINE bool Bounds::IntersectsBounds( const Bounds &b2 ) { - if ( b2.b[1][0] < b[0][0] || b2.b[1][1] < b[0][1] || b2.b[1][2] < b[0][2] - || b2.b[0][0] > b[1][0] || b2.b[0][1] > b[1][1] || b2.b[0][2] > b[1][2] ) { - return false; - } - return true; -} - -ID_INLINE Bounds::Bounds( const idVec3_t &mins, const idVec3_t &maxs ) { - b[0] = mins; - b[1] = maxs; -} - -ID_INLINE idVec3_t Bounds::Center() { - return idVec3_t( ( b[1][0] + b[0][0] ) * 0.5f, ( b[1][1] + b[0][1] ) * 0.5f, ( b[1][2] + b[0][2] ) * 0.5f ); -} - -ID_INLINE void Bounds::Clear() { - b[0][0] = b[0][1] = b[0][2] = 99999; - b[1][0] = b[1][1] = b[1][2] = -99999; -} - -ID_INLINE void Bounds::Zero() { - b[0][0] = b[0][1] = b[0][2] = - b[1][0] = b[1][1] = b[1][2] = 0; -} - -ID_INLINE void Bounds::AddPoint( const idVec3_t &v ) { - if ( v[0] < b[0][0]) { - b[0][0] = v[0]; - } - if ( v[0] > b[1][0]) { - b[1][0] = v[0]; - } - if ( v[1] < b[0][1] ) { - b[0][1] = v[1]; - } - if ( v[1] > b[1][1]) { - b[1][1] = v[1]; - } - if ( v[2] < b[0][2] ) { - b[0][2] = v[2]; - } - if ( v[2] > b[1][2]) { - b[1][2] = v[2]; - } -} - - -ID_INLINE void Bounds::AddBounds( const Bounds &bb ) { - if ( bb.b[0][0] < b[0][0]) { - b[0][0] = bb.b[0][0]; - } - if ( bb.b[0][1] < b[0][1]) { - b[0][1] = bb.b[0][1]; - } - if ( bb.b[0][2] < b[0][2]) { - b[0][2] = bb.b[0][2]; - } - - if ( bb.b[1][0] > b[1][0]) { - b[1][0] = bb.b[1][0]; - } - if ( bb.b[1][1] > b[1][1]) { - b[1][1] = bb.b[1][1]; - } - if ( bb.b[1][2] > b[1][2]) { - b[1][2] = bb.b[1][2]; - } -} - -ID_INLINE float Bounds::Radius( ) { - int i; - float total; - float a, aa; - - total = 0; - for (i=0 ; i<3 ; i++) { - a = (float)fabs( b[0][i] ); - aa = (float)fabs( b[1][i] ); - if ( aa > a ) { - a = aa; - } - total += a * a; - } - - return (float)idSqrt( total ); -} - -//=============================================================== - - -class idVec2_t { -public: - float x; - float y; - - operator float *(); - float operator[]( int index ) const; - float &operator[]( int index ); -}; - -ID_INLINE float idVec2_t::operator[]( int index ) const { - return ( &x )[ index ]; -} - -ID_INLINE float& idVec2_t::operator[]( int index ) { - return ( &x )[ index ]; -} - -ID_INLINE idVec2_t::operator float *( void ) { - return &x; -} - -class vec4_t : public idVec3_t { -public: -#ifndef FAT_VEC3 - float dist; -#endif - vec4_t(); - ~vec4_t() {}; - - vec4_t( float x, float y, float z, float dist ); - float operator[]( int index ) const; - float &operator[]( int index ); -}; - -ID_INLINE vec4_t::vec4_t() {} -ID_INLINE vec4_t::vec4_t( float x, float y, float z, float dist ) { - this->x = x; - this->y = y; - this->z = z; - this->dist = dist; -} - -ID_INLINE float vec4_t::operator[]( int index ) const { - return ( &x )[ index ]; -} - -ID_INLINE float& vec4_t::operator[]( int index ) { - return ( &x )[ index ]; -} - - -class idVec5_t : public idVec3_t { -public: - float s; - float t; - float operator[]( int index ) const; - float &operator[]( int index ); -}; - - -ID_INLINE float idVec5_t::operator[]( int index ) const { - return ( &x )[ index ]; -} - -ID_INLINE float& idVec5_t::operator[]( int index ) { - return ( &x )[ index ]; -} - -#endif /* !__MATH_VECTOR_H__ */ diff --git a/code/splines/q_parse.cpp b/code/splines/q_parse.cpp deleted file mode 100644 index 33b6b4b..0000000 --- a/code/splines/q_parse.cpp +++ /dev/null @@ -1,535 +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 Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// q_parse.c -- support for parsing text files - -#include "q_shared.hpp" - -/* -============================================================================ - -PARSING - -============================================================================ -*/ - -// multiple character punctuation tokens -static const char *punctuation[] = { - "+=", "-=", "*=", "/=", "&=", "|=", "++", "--", - "&&", "||", "<=", ">=", "==", "!=", - NULL -}; - -typedef struct { - char token[MAX_TOKEN_CHARS]; - int lines; - qboolean ungetToken; - char parseFile[MAX_QPATH]; -} parseInfo_t; - -#define MAX_PARSE_INFO 16 -static parseInfo_t parseInfo[MAX_PARSE_INFO]; -static int parseInfoNum; -static parseInfo_t *pi = &parseInfo[0]; - -/* -=================== -Com_BeginParseSession -=================== -*/ -void Com_BeginParseSession( const char *filename ) { - if ( parseInfoNum == MAX_PARSE_INFO - 1 ) { - Com_Error( ERR_FATAL, "Com_BeginParseSession: session overflow" ); - } - parseInfoNum++; - pi = &parseInfo[parseInfoNum]; - - pi->lines = 1; - Q_strncpyz( pi->parseFile, filename, sizeof( pi->parseFile ) ); -} - -/* -=================== -Com_EndParseSession -=================== -*/ -void Com_EndParseSession( void ) { - if ( parseInfoNum == 0 ) { - Com_Error( ERR_FATAL, "Com_EndParseSession: session underflow" ); - } - parseInfoNum--; - pi = &parseInfo[parseInfoNum]; -} - -/* -=================== -Com_GetCurrentParseLine -=================== -*/ -int Com_GetCurrentParseLine( void ) { - return pi->lines; -} - -/* -=================== -Com_ScriptError - -Prints the script name and line number in the message -=================== -*/ -void Com_ScriptError( const char *msg, ... ) { - va_list argptr; - char string[32000]; - - va_start( argptr, msg ); - vsprintf( string, msg,argptr ); - va_end( argptr ); - - Com_Error( ERR_DROP, "File %s, line %i: %s", pi->parseFile, pi->lines, string ); -} - -void Com_ScriptWarning( const char *msg, ... ) { - va_list argptr; - char string[32000]; - - va_start( argptr, msg ); - vsprintf( string, msg,argptr ); - va_end( argptr ); - - Com_Printf( "File %s, line %i: %s", pi->parseFile, pi->lines, string ); -} - - -/* -=================== -Com_UngetToken - -Calling this will make the next Com_Parse return -the current token instead of advancing the pointer -=================== -*/ -void Com_UngetToken( void ) { - if ( pi->ungetToken ) { - Com_ScriptError( "UngetToken called twice" ); - } - pi->ungetToken = qtrue; -} - - -static const char *SkipWhitespace( const char (*data), qboolean *hasNewLines ) { - int c; - - while( (c = *data) <= ' ') { - if( !c ) { - return NULL; - } - if( c == '\n' ) { - pi->lines++; - *hasNewLines = qtrue; - } - data++; - } - - return data; -} - -/* -============== -Com_ParseExt - -Parse a token out of a string -Will never return NULL, just empty strings. -An empty string will only be returned at end of file. - -If "allowLineBreaks" is qtrue then an empty -string will be returned if the next token is -a newline. -============== -*/ -static char *Com_ParseExt( const char *(*data_p), qboolean allowLineBreaks ) { - int c = 0, len; - qboolean hasNewLines = qfalse; - const char *data; - const char **punc; - - if ( !data_p ) { - Com_Error( ERR_FATAL, "Com_ParseExt: NULL data_p" ); - } - - data = *data_p; - len = 0; - pi->token[0] = 0; - - // make sure incoming data is valid - if ( !data ) { - *data_p = NULL; - return pi->token; - } - - // skip any leading whitespace - while ( 1 ) { - // skip whitespace - data = SkipWhitespace( data, &hasNewLines ); - if ( !data ) { - *data_p = NULL; - return pi->token; - } - if ( hasNewLines && !allowLineBreaks ) { - *data_p = data; - return pi->token; - } - - c = *data; - - // skip double slash comments - if ( c == '/' && data[1] == '/' ) { - while (*data && *data != '\n') { - data++; - } - continue; - } - - // skip /* */ comments - if ( c=='/' && data[1] == '*' ) { - while ( *data && ( *data != '*' || data[1] != '/' ) ) { - if( *data == '\n' ) { - pi->lines++; - } - data++; - } - if ( *data ) { - data += 2; - } - continue; - } - - // a real token to parse - break; - } - - // handle quoted strings - if ( c == '\"' ) { - data++; - while( 1 ) { - c = *data++; - if ( ( c=='\\' ) && ( *data == '\"' ) ) { - // allow quoted strings to use \" to indicate the " character - data++; - } else if ( c=='\"' || !c ) { - pi->token[len] = 0; - *data_p = ( char * ) data; - return pi->token; - } else if( *data == '\n' ) { - pi->lines++; - } - if ( len < MAX_TOKEN_CHARS - 1 ) { - pi->token[len] = c; - len++; - } - } - } - - // check for a number - // is this parsing of negative numbers going to cause expression problems - if ( ( c >= '0' && c <= '9' ) || ( c == '-' && data[ 1 ] >= '0' && data[ 1 ] <= '9' ) || - ( c == '.' && data[ 1 ] >= '0' && data[ 1 ] <= '9' ) ) { - do { - - if (len < MAX_TOKEN_CHARS - 1) { - pi->token[len] = c; - len++; - } - data++; - - c = *data; - } while ( ( c >= '0' && c <= '9' ) || c == '.' ); - - // parse the exponent - if ( c == 'e' || c == 'E' ) { - if (len < MAX_TOKEN_CHARS - 1) { - pi->token[len] = c; - len++; - } - data++; - c = *data; - - if ( c == '-' || c == '+' ) { - if (len < MAX_TOKEN_CHARS - 1) { - pi->token[len] = c; - len++; - } - data++; - c = *data; - } - - do { - if (len < MAX_TOKEN_CHARS - 1) { - pi->token[len] = c; - len++; - } - data++; - - c = *data; - } while ( c >= '0' && c <= '9' ); - } - - if (len == MAX_TOKEN_CHARS) { - len = 0; - } - pi->token[len] = 0; - - *data_p = ( char * ) data; - return pi->token; - } - - // check for a regular word - // we still allow forward and back slashes in name tokens for pathnames - // and also colons for drive letters - if ( ( c >= 'a' && c <= 'z' ) || ( c >= 'A' && c <= 'Z' ) || c == '_' || c == '/' || c == '\\' ) { - do { - if (len < MAX_TOKEN_CHARS - 1) { - pi->token[len] = c; - len++; - } - data++; - - c = *data; - } while ( ( c >= 'a' && c <= 'z' ) || ( c >= 'A' && c <= 'Z' ) || c == '_' - || ( c >= '0' && c <= '9' ) || c == '/' || c == '\\' || c == ':' || c == '.' ); - - if (len == MAX_TOKEN_CHARS) { - len = 0; - } - pi->token[len] = 0; - - *data_p = ( char * ) data; - return pi->token; - } - - // check for multi-character punctuation token - for ( punc = punctuation ; *punc ; punc++ ) { - int l; - int j; - - l = strlen( *punc ); - for ( j = 0 ; j < l ; j++ ) { - if ( data[j] != (*punc)[j] ) { - break; - } - } - if ( j == l ) { - // a valid multi-character punctuation - memcpy( pi->token, *punc, l ); - pi->token[l] = 0; - data += l; - *data_p = (char *)data; - return pi->token; - } - } - - // single character punctuation - pi->token[0] = *data; - pi->token[1] = 0; - data++; - *data_p = (char *)data; - - return pi->token; -} - -/* -=================== -Com_Parse -=================== -*/ -const char *Com_Parse( const char *(*data_p) ) { - if ( pi->ungetToken ) { - pi->ungetToken = qfalse; - return pi->token; - } - return Com_ParseExt( data_p, qtrue ); -} - -/* -=================== -Com_ParseOnLine -=================== -*/ -const char *Com_ParseOnLine( const char *(*data_p) ) { - if ( pi->ungetToken ) { - pi->ungetToken = qfalse; - return pi->token; - } - return Com_ParseExt( data_p, qfalse ); -} - - - -/* -================== -Com_MatchToken -================== -*/ -void Com_MatchToken( const char *(*buf_p), const char *match, qboolean warning ) { - const char *token; - - token = Com_Parse( buf_p ); - if ( strcmp( token, match ) ) { - if (warning) { - Com_ScriptWarning( "MatchToken: %s != %s", token, match ); - } else { - Com_ScriptError( "MatchToken: %s != %s", token, match ); - } - } -} - - -/* -================= -Com_SkipBracedSection - -The next token should be an open brace. -Skips until a matching close brace is found. -Internal brace depths are properly skipped. -================= -*/ -void Com_SkipBracedSection( const char *(*program) ) { - const char *token; - int depth; - - depth = 0; - do { - token = Com_Parse( program ); - if( token[1] == 0 ) { - if( token[0] == '{' ) { - depth++; - } - else if( token[0] == '}' ) { - depth--; - } - } - } while( depth && *program ); -} - -/* -================= -Com_SkipRestOfLine -================= -*/ -void Com_SkipRestOfLine ( const char *(*data) ) { - const char *p; - int c; - - p = *data; - while ( (c = *p++) != 0 ) { - if ( c == '\n' ) { - pi->lines++; - break; - } - } - - *data = p; -} - -/* -==================== -Com_ParseRestOfLine -==================== -*/ -const char *Com_ParseRestOfLine( const char *(*data_p) ) { - static char line[MAX_TOKEN_CHARS]; - const char *token; - - line[0] = 0; - while( 1 ) { - token = Com_ParseOnLine( data_p ); - if ( !token[0] ) { - break; - } - if ( line[0] ) { - Q_strcat( line, sizeof(line), " " ); - } - Q_strcat( line, sizeof(line), token ); - } - - return line; -} - - -float Com_ParseFloat( const char *(*buf_p) ) { - const char *token; - - token = Com_Parse( buf_p ); - if ( !token[0] ) { - return 0; - } - return atof( token ); -} - -int Com_ParseInt( const char *(*buf_p) ) { - const char *token; - - token = Com_Parse( buf_p ); - if ( !token[0] ) { - return 0; - } - return atoi( token ); -} - - - -void Com_Parse1DMatrix( const char *(*buf_p), int x, float *m ) { - const char *token; - int i; - - Com_MatchToken( buf_p, "(" ); - - for (i = 0 ; i < x ; i++) { - token = Com_Parse(buf_p); - m[i] = atof(token); - } - - Com_MatchToken( buf_p, ")" ); -} - -void Com_Parse2DMatrix( const char *(*buf_p), int y, int x, float *m ) { - int i; - - Com_MatchToken( buf_p, "(" ); - - for (i = 0 ; i < y ; i++) { - Com_Parse1DMatrix (buf_p, x, m + i * x); - } - - Com_MatchToken( buf_p, ")" ); -} - -void Com_Parse3DMatrix( const char *(*buf_p), int z, int y, int x, float *m ) { - int i; - - Com_MatchToken( buf_p, "(" ); - - for (i = 0 ; i < z ; i++) { - Com_Parse2DMatrix (buf_p, y, x, m + i * x*y); - } - - Com_MatchToken( buf_p, ")" ); -} - diff --git a/code/splines/q_shared.cpp b/code/splines/q_shared.cpp deleted file mode 100644 index ecd2342..0000000 --- a/code/splines/q_shared.cpp +++ /dev/null @@ -1,976 +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 Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// q_shared.c -- stateless support routines that are included in each code dll -#include "q_shared.hpp" - -/* -============================================================================ - -GROWLISTS - -============================================================================ -*/ - -// malloc / free all in one place for debugging -extern "C" void *Com_Allocate( int bytes ); -extern "C" void Com_Dealloc( void *ptr ); - -void Com_InitGrowList( growList_t *list, int maxElements ) { - list->maxElements = maxElements; - list->currentElements = 0; - list->elements = (void **)Com_Allocate( list->maxElements * sizeof( void * ) ); -} - -int Com_AddToGrowList( growList_t *list, void *data ) { - void **old; - - if ( list->currentElements != list->maxElements ) { - list->elements[list->currentElements] = data; - return list->currentElements++; - } - - // grow, reallocate and move - old = list->elements; - - if ( list->maxElements < 0 ) { - Com_Error( ERR_FATAL, "Com_AddToGrowList: maxElements = %i", list->maxElements ); - } - - if ( list->maxElements == 0 ) { - // initialize the list to hold 100 elements - Com_InitGrowList( list, 100 ); - return Com_AddToGrowList( list, data ); - } - - list->maxElements *= 2; - - Com_DPrintf( "Resizing growlist to %i maxElements\n", list->maxElements ); - - list->elements = (void **)Com_Allocate( list->maxElements * sizeof( void * ) ); - - if ( !list->elements ) { - Com_Error( ERR_DROP, "Growlist alloc failed" ); - } - - memcpy( list->elements, old, list->currentElements * sizeof( void * ) ); - - Com_Dealloc( old ); - - return Com_AddToGrowList( list, data ); -} - -void *Com_GrowListElement( const growList_t *list, int index ) { - if ( index < 0 || index >= list->currentElements ) { - Com_Error( ERR_DROP, "Com_GrowListElement: %i out of range of %i", - index, list->currentElements ); - } - return list->elements[index]; -} - -int Com_IndexForGrowListElement( const growList_t *list, const void *element ) { - int i; - - for ( i = 0 ; i < list->currentElements ; i++ ) { - if ( list->elements[i] == element ) { - return i; - } - } - return -1; -} - -//============================================================================ - - -float Com_Clamp( float min, float max, float value ) { - if ( value < min ) { - return min; - } - if ( value > max ) { - return max; - } - return value; -} - -/* -============ -Com_StringContains -============ -*/ -const char *Com_StringContains( const char *str1, const 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; - } - } - else { - if (toupper(str1[j]) != toupper(str2[j])) { - break; - } - } - } - if (!str2[j]) { - return str1; - } - } - return NULL; -} - -/* -============ -Com_Filter -============ -*/ -int Com_Filter( const char *filter, const char *name, int casesensitive) -{ - char buf[MAX_TOKEN_CHARS]; - const char *ptr; - int i, found; - - while(*filter) { - if (*filter == '*') { - filter++; - for (i = 0; *filter; i++) { - if (*filter == '*' || *filter == '?') break; - buf[i] = *filter; - filter++; - } - buf[i] = '\0'; - if (strlen(buf)) { - ptr = Com_StringContains(name, buf, casesensitive); - if (!ptr) return qfalse; - name = ptr + strlen(buf); - } - } - else if (*filter == '?') { - filter++; - name++; - } - else if (*filter == '[' && *(filter+1) == '[') { - filter++; - } - else if (*filter == '[') { - filter++; - found = qfalse; - while(*filter && !found) { - if (*filter == ']' && *(filter+1) != ']') break; - if (*(filter+1) == '-' && *(filter+2) && (*(filter+2) != ']' || *(filter+3) == ']')) { - if (casesensitive) { - if (*name >= *filter && *name <= *(filter+2)) found = qtrue; - } - else { - if (toupper(*name) >= toupper(*filter) && - toupper(*name) <= toupper(*(filter+2))) found = qtrue; - } - filter += 3; - } - else { - if (casesensitive) { - if (*filter == *name) found = qtrue; - } - else { - if (toupper(*filter) == toupper(*name)) found = qtrue; - } - filter++; - } - } - if (!found) return qfalse; - while(*filter) { - if (*filter == ']' && *(filter+1) != ']') break; - filter++; - } - filter++; - name++; - } - else { - if (casesensitive) { - if (*filter != *name) return qfalse; - } - else { - if (toupper(*filter) != toupper(*name)) return qfalse; - } - filter++; - name++; - } - } - return qtrue; -} - - -/* -================ -Com_HashString - -================ -*/ -int Com_HashString( const char *fname ) { - int i; - long hash; - char letter; - - hash = 0; - i = 0; - while (fname[i] != '\0') { - letter = tolower(fname[i]); - if (letter =='.') break; // don't include extension - if (letter =='\\') letter = '/'; // damn path names - hash+=(long)(letter)*(i+119); - i++; - } - hash &= (FILE_HASH_SIZE-1); - return hash; -} - - -/* -============ -Com_SkipPath -============ -*/ -char *Com_SkipPath (char *pathname) -{ - char *last; - - last = pathname; - while (*pathname) - { - if (*pathname=='/') - last = pathname+1; - pathname++; - } - return last; -} - -/* -============ -Com_StripExtension -============ -*/ -void Com_StripExtension( const char *in, char *out ) { - while ( *in && *in != '.' ) { - *out++ = *in++; - } - *out = 0; -} - - -/* -================== -Com_DefaultExtension -================== -*/ -void Com_DefaultExtension (char *path, int maxSize, const char *extension ) { - char oldPath[MAX_QPATH]; - char *src; - -// -// if path doesn't have a .EXT, append extension -// (extension should include the .) -// - src = path + strlen(path) - 1; - - while (*src != '/' && src != path) { - if ( *src == '.' ) { - return; // it has an extension - } - src--; - } - - Q_strncpyz( oldPath, path, sizeof( oldPath ) ); - Com_sprintf( path, maxSize, "%s%s", oldPath, extension ); -} - -/* -============================================================================ - - BYTE ORDER FUNCTIONS - -============================================================================ -*/ - -// can't just use function pointers, or dll linkage can -// mess up when qcommon is included in multiple places -static short (*_BigShort) (short l); -static short (*_LittleShort) (short l); -static int (*_BigLong) (int l); -static int (*_LittleLong) (int l); -static float (*_BigFloat) (float l); -static float (*_LittleFloat) (float l); - -short BigShort(short l){return _BigShort(l);} -short LittleShort(short l) {return _LittleShort(l);} -int BigLong (int l) {return _BigLong(l);} -int LittleLong (int l) {return _LittleLong(l);} -float BigFloat (float l) {return _BigFloat(l);} -float LittleFloat (float l) {return _LittleFloat(l);} - -short ShortSwap (short l) -{ - byte b1,b2; - - b1 = l&255; - b2 = (l>>8)&255; - - return (b1<<8) + b2; -} - -short ShortNoSwap (short l) -{ - return l; -} - -int LongSwap (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 LongNoSwap (int l) -{ - return l; -} - -float FloatSwap (float f) -{ - union - { - float f; - byte b[4]; - } dat1, dat2; - - - dat1.f = f; - dat2.b[0] = dat1.b[3]; - dat2.b[1] = dat1.b[2]; - dat2.b[2] = dat1.b[1]; - dat2.b[3] = dat1.b[0]; - return dat2.f; -} - -float FloatNoSwap (float f) -{ - return f; -} - -/* -================ -Swap_Init -================ -*/ -void Swap_Init (void) -{ - byte swaptest[2] = {1,0}; - -// set the byte swapping variables in a portable manner - if ( *(short *)swaptest == 1) - { - _BigShort = ShortSwap; - _LittleShort = ShortNoSwap; - _BigLong = LongSwap; - _LittleLong = LongNoSwap; - _BigFloat = FloatSwap; - _LittleFloat = FloatNoSwap; - } - else - { - _BigShort = ShortNoSwap; - _LittleShort = ShortSwap; - _BigLong = LongNoSwap; - _LittleLong = LongSwap; - _BigFloat = FloatNoSwap; - _LittleFloat = FloatSwap; - } - -} - -/* -=============== -Com_ParseInfos -=============== -*/ -int Com_ParseInfos( const char *buf, int max, char infos[][MAX_INFO_STRING] ) { - const char *token; - int count; - char key[MAX_TOKEN_CHARS]; - - count = 0; - - while ( 1 ) { - token = Com_Parse( &buf ); - if ( !token[0] ) { - break; - } - if ( strcmp( token, "{" ) ) { - Com_Printf( "Missing { in info file\n" ); - break; - } - - if ( count == max ) { - Com_Printf( "Max infos exceeded\n" ); - break; - } - - infos[count][0] = 0; - while ( 1 ) { - token = Com_Parse( &buf ); - if ( !token[0] ) { - Com_Printf( "Unexpected end of info file\n" ); - break; - } - if ( !strcmp( token, "}" ) ) { - break; - } - Q_strncpyz( key, token, sizeof( key ) ); - - token = Com_ParseOnLine( &buf ); - if ( !token[0] ) { - token = ""; - } - Info_SetValueForKey( infos[count], key, token ); - } - count++; - } - - return count; -} - - - -/* -============================================================================ - - LIBRARY REPLACEMENT FUNCTIONS - -============================================================================ -*/ - -int Q_isprint( int c ) -{ - if ( c >= 0x20 && c <= 0x7E ) - return ( 1 ); - return ( 0 ); -} - -int Q_islower( int c ) -{ - if (c >= 'a' && c <= 'z') - return ( 1 ); - return ( 0 ); -} - -int Q_isupper( int c ) -{ - if (c >= 'A' && c <= 'Z') - return ( 1 ); - return ( 0 ); -} - -int Q_isalpha( int c ) -{ - if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) - return ( 1 ); - return ( 0 ); -} - -char* Q_strrchr( const char* string, int c ) -{ - char cc = c; - char *s; - char *sp=(char *)0; - - s = (char*)string; - - while (*s) - { - if (*s == cc) - sp = s; - s++; - } - if (cc == 0) - sp = s; - - return sp; -} - -/* -============= -Q_strncpyz - -Safe strncpy that ensures a trailing zero -============= -*/ -void Q_strncpyz( char *dest, const char *src, int destsize ) { - if ( !src ) { - Com_Error( ERR_FATAL, "Q_strncpyz: NULL src" ); - } - if ( destsize < 1 ) { - Com_Error(ERR_FATAL,"Q_strncpyz: destsize < 1" ); - } - - strncpy( dest, src, destsize-1 ); - dest[destsize-1] = 0; -} - -int Q_stricmpn (const char *s1, const 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 c1 < c2 ? -1 : 1; - } - } - } while (c1); - - return 0; // strings are equal -} - -int Q_strncmp (const char *s1, const 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) { - return c1 < c2 ? -1 : 1; - } - } while (c1); - - return 0; // strings are equal -} - -int Q_stricmp (const char *s1, const char *s2) { - return Q_stricmpn (s1, s2, 99999); -} - - -char *Q_strlwr( char *s1 ) { - char *s; - - s = s1; - while ( *s ) { - *s = tolower(*s); - s++; - } - return s1; -} - -char *Q_strupr( char *s1 ) { - char *s; - - s = s1; - while ( *s ) { - *s = toupper(*s); - s++; - } - return s1; -} - - -// never goes past bounds or leaves without a terminating 0 -void Q_strcat( char *dest, int size, const char *src ) { - int l1; - - l1 = strlen( dest ); - if ( l1 >= size ) { - Com_Error( ERR_FATAL, "Q_strcat: already overflowed" ); - } - Q_strncpyz( dest + l1, src, size - l1 ); -} - - -int Q_PrintStrlen( const char *string ) { - int len; - const char *p; - - if( !string ) { - return 0; - } - - len = 0; - p = string; - while( *p ) { - if( Q_IsColorString( p ) ) { - p += 2; - continue; - } - p++; - len++; - } - - return len; -} - - -char *Q_CleanStr( char *string ) { - char* d; - char* s; - int c; - - s = string; - d = string; - while ((c = *s) != 0 ) { - if ( Q_IsColorString( s ) ) { - s++; - } - else if ( c >= 0x20 && c <= 0x7E ) { - *d++ = c; - } - s++; - } - *d = '\0'; - - return string; -} - - -void QDECL Com_sprintf( char *dest, int size, const char *fmt, ...) { - int len; - va_list argptr; - char bigbuffer[32000]; // big, but small enough to fit in PPC stack - - va_start (argptr,fmt); - len = vsprintf (bigbuffer,fmt,argptr); - va_end (argptr); - if ( len >= sizeof( bigbuffer ) ) { - Com_Error( ERR_FATAL, "Com_sprintf: overflowed bigbuffer" ); - } - if (len >= size) { - Com_Printf ("Com_sprintf: overflow of %i in %i\n", len, size); - } - Q_strncpyz (dest, bigbuffer, size ); -} - - -/* -============ -va - -does a varargs printf into a temp buffer, so I don't need to have -varargs versions of all text functions. -FIXME: make this buffer size safe someday -============ -*/ -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; -} - - -/* -===================================================================== - - INFO STRINGS - -===================================================================== -*/ - -/* -=============== -Info_ValueForKey - -Searches the string for the given -key and returns the associated value, or an empty string. -FIXME: overflow check? -=============== -*/ -char *Info_ValueForKey( const char *s, const char *key ) { - char pkey[MAX_INFO_KEY]; - static char value[2][MAX_INFO_VALUE]; // use two buffers so compares - // work without stomping on each other - static int valueindex = 0; - char *o; - - if ( !s || !key ) { - return ""; - } - - if ( strlen( s ) >= MAX_INFO_STRING ) { - Com_Error( ERR_DROP, "Info_ValueForKey: oversize infostring" ); - } - - valueindex ^= 1; - if (*s == '\\') - s++; - while (1) - { - o = pkey; - while (*s != '\\') - { - if (!*s) - return ""; - *o++ = *s++; - } - *o = 0; - s++; - - o = value[valueindex]; - - while (*s != '\\' && *s) - { - *o++ = *s++; - } - *o = 0; - - if (!Q_stricmp (key, pkey) ) - return value[valueindex]; - - if (!*s) - break; - s++; - } - - return ""; -} - - -/* -=================== -Info_NextPair - -Used to itterate through all the key/value pairs in an info string -=================== -*/ -void Info_NextPair( const char *(*head), char key[MAX_INFO_KEY], char value[MAX_INFO_VALUE] ) { - char *o; - const char *s; - - s = *head; - - if ( *s == '\\' ) { - s++; - } - key[0] = 0; - value[0] = 0; - - o = key; - while ( *s != '\\' ) { - if ( !*s ) { - *o = 0; - *head = s; - return; - } - *o++ = *s++; - } - *o = 0; - s++; - - o = value; - while ( *s != '\\' && *s ) { - *o++ = *s++; - } - *o = 0; - - *head = s; -} - - -/* -=================== -Info_RemoveKey -=================== -*/ -void Info_RemoveKey( char *s, const char *key ) { - char *start; - char pkey[MAX_INFO_KEY]; - char value[MAX_INFO_VALUE]; - char *o; - - if ( strlen( s ) >= MAX_INFO_STRING ) { - Com_Error( ERR_DROP, "Info_RemoveKey: oversize infostring" ); - } - - if (strchr (key, '\\')) { - return; - } - - while (1) - { - start = s; - if (*s == '\\') - s++; - o = pkey; - while (*s != '\\') - { - if (!*s) - return; - *o++ = *s++; - } - *o = 0; - s++; - - o = value; - while (*s != '\\' && *s) - { - if (!*s) - return; - *o++ = *s++; - } - *o = 0; - - if (!strcmp (key, pkey) ) - { - strcpy (start, s); // remove this part - return; - } - - if (!*s) - return; - } - -} - - -/* -================== -Info_Validate - -Some characters are illegal in info strings because they -can mess up the server's parsing -================== -*/ -qboolean Info_Validate( const char *s ) { - if ( strchr( s, '\"' ) ) { - return qfalse; - } - if ( strchr( s, ';' ) ) { - return qfalse; - } - return qtrue; -} - -/* -================== -Info_SetValueForKey - -Changes or adds a key/value pair -================== -*/ -void Info_SetValueForKey( char *s, const char *key, const char *value ) { - char newi[MAX_INFO_STRING]; - - if ( strlen( s ) >= MAX_INFO_STRING ) { - Com_Error( ERR_DROP, "Info_SetValueForKey: oversize infostring" ); - } - - if (strchr (key, '\\') || strchr (value, '\\')) - { - Com_Printf ("Can't use keys or values with a \\\n"); - return; - } - - if (strchr (key, ';') || strchr (value, ';')) - { - Com_Printf ("Can't use keys or values with a semicolon\n"); - return; - } - - if (strchr (key, '\"') || strchr (value, '\"')) - { - Com_Printf ("Can't use keys or values with a \"\n"); - return; - } - - Info_RemoveKey (s, key); - if (!value || !strlen(value)) - return; - - Com_sprintf (newi, sizeof(newi), "\\%s\\%s", key, value); - - if (strlen(newi) + strlen(s) > MAX_INFO_STRING) - { - Com_Printf ("Info string length exceeded\n"); - return; - } - - strcat (s, newi); -} - -//==================================================================== - - -/* -=============== -ParseHex -=============== -*/ -int ParseHex( const char *text ) { - int value; - int c; - - value = 0; - while ( ( c = *text++ ) != 0 ) { - if ( c >= '0' && c <= '9' ) { - value = value * 16 + c - '0'; - continue; - } - if ( c >= 'a' && c <= 'f' ) { - value = value * 16 + 10 + c - 'a'; - continue; - } - if ( c >= 'A' && c <= 'F' ) { - value = value * 16 + 10 + c - 'A'; - continue; - } - } - - return value; -} diff --git a/code/splines/q_shared.h b/code/splines/q_shared.h deleted file mode 100644 index 674f0aa..0000000 --- a/code/splines/q_shared.h +++ /dev/null @@ -1,850 +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 __Q_SHARED_H -#define __Q_SHARED_H - -// q_shared.h -- included first by ALL program modules. -// these are the definitions that have no dependance on -// central system services, and can be used by any part -// of the program without any state issues. - -// A user mod should never modify this file - -// incursion of DOOM code into the Q3A codebase -//#define Q3_VERSION "DOOM 0.01" - -// alignment macros for SIMD -#define ALIGN_ON -#define ALIGN_OFF - -#ifdef _WIN32 - -#pragma warning(disable : 4018) // signed/unsigned mismatch -#pragma warning(disable : 4032) -#pragma warning(disable : 4051) -#pragma warning(disable : 4057) // slightly different base types -#pragma warning(disable : 4100) // unreferenced formal parameter -#pragma warning(disable : 4115) -#pragma warning(disable : 4125) // decimal digit terminates octal escape sequence -#pragma warning(disable : 4127) // conditional expression is constant -#pragma warning(disable : 4136) -#pragma warning(disable : 4201) -#pragma warning(disable : 4214) -#pragma warning(disable : 4244) -#pragma warning(disable : 4305) // truncation from const double to float -#pragma warning(disable : 4310) // cast truncates constant value -#pragma warning(disable : 4514) -#pragma warning(disable : 4711) // selected for automatic inline expansion -#pragma warning(disable : 4220) // varargs matches remaining parameters - -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef WIN32 // mac doesn't have malloc.h -#include // for _alloca() -#endif -#ifdef _WIN32 - -//#pragma intrinsic( memset, memcpy ) - -#endif - - -// this is the define for determining if we have an asm version of a C function -#if (defined _M_IX86 || defined __i386__) && !defined __sun__ && !defined __LCC__ -#define id386 1 -#else -#define id386 0 -#endif - -// for windows fastcall option - -#define QDECL - -//======================= WIN32 DEFINES ================================= - -#ifdef WIN32 - -#define MAC_STATIC - -#undef QDECL -#define QDECL __cdecl - -// buildstring will be incorporated into the version string -#ifdef NDEBUG -#ifdef _M_IX86 -#define CPUSTRING "win-x86" -#elif defined _M_ALPHA -#define CPUSTRING "win-AXP" -#endif -#else -#ifdef _M_IX86 -#define CPUSTRING "win-x86-debug" -#elif defined _M_ALPHA -#define CPUSTRING "win-AXP-debug" -#endif -#endif - - -#define PATH_SEP '\\' - -#endif - -//======================= MAC OS X SERVER DEFINES ===================== - -#if defined(__MACH__) && defined(__APPLE__) - -#define MAC_STATIC - -#ifdef __ppc__ -#define CPUSTRING "MacOSXS-ppc" -#elif defined __i386__ -#define CPUSTRING "MacOSXS-i386" -#else -#define CPUSTRING "MacOSXS-other" -#endif - -#define PATH_SEP '/' - -#define GAME_HARD_LINKED -#define CGAME_HARD_LINKED -#define UI_HARD_LINKED -#define _alloca alloca - -#undef ALIGN_ON -#undef ALIGN_OFF -#define ALIGN_ON #pragma align(16) -#define ALIGN_OFF #pragma align() - -#ifdef __cplusplus - extern "C" { -#endif - -void *osxAllocateMemory(long size); -void osxFreeMemory(void *pointer); - -#ifdef __cplusplus - } -#endif - -#endif - -//======================= MAC DEFINES ================================= - -#ifdef __MACOS__ - -#define MAC_STATIC static - -#define CPUSTRING "MacOS-PPC" - -#define PATH_SEP ':' - -void Sys_PumpEvents( void ); - -#endif - -#ifdef __MRC__ - -#define MAC_STATIC - -#define CPUSTRING "MacOS-PPC" - -#define PATH_SEP ':' - -void Sys_PumpEvents( void ); - -#undef QDECL -#define QDECL __cdecl - -#define _alloca alloca -#endif - -//======================= LINUX DEFINES ================================= - -// the mac compiler can't handle >32k of locals, so we -// just waste space and make big arrays static... -#ifdef __linux__ - -// bk001205 - from Makefile -#define stricmp strcasecmp - -#define MAC_STATIC // bk: FIXME - -#ifdef __i386__ -#define CPUSTRING "linux-i386" -#elif defined __axp__ -#define CPUSTRING "linux-alpha" -#elif defined __x86_64__ -#define CPUSTRING "linux-x86_64" -#elif defined __powerpc64__ -#define CPUSTRING "linux-ppc64" -#elif defined __powerpc__ -#define CPUSTRING "linux-ppc" -#elif defined __s390__ -#define CPUSTRING "linux-s390" -#elif defined __s390x__ -#define CPUSTRING "linux-s390x" -#elif defined __ia64__ -#define CPUSTRING "linux-ia64" -#else -#define CPUSTRING "linux-other" -#endif - -#define PATH_SEP '/' - -// bk001205 - try -#ifdef Q3_STATIC -#define GAME_HARD_LINKED -#define CGAME_HARD_LINKED -#define UI_HARD_LINKED -#define BOTLIB_HARD_LINKED -#endif - -#endif - -//======================= FreeBSD DEFINES ===================== -/* Adapted from game/q_shared.h */ -#ifdef __FreeBSD__ // rb010123 - -#define stricmp strcasecmp - -#define MAC_STATIC -#define ID_INLINE inline - -#ifdef __i386__ -#define CPUSTRING "freebsd-i386" -#elif defined __axp__ -#define CPUSTRING "freebsd-alpha" -#else -#define CPUSTRING "freebsd-other" -#endif - -#define PATH_SEP '/' - -#ifdef Q3_STATIC -#define GAME_HARD_LINKED -#define CGAME_HARD_LINKED -#define UI_HARD_LINKED -#define BOTLIB_HARD_LINKED -#endif - -#endif - -//============================================================= - - - -typedef enum {qfalse, qtrue} qboolean; - -typedef unsigned char byte; - -#define EQUAL_EPSILON 0.001 - -typedef int qhandle_t; -typedef int sfxHandle_t; -typedef int fileHandle_t; -typedef int clipHandle_t; - -typedef enum { - INVALID_JOINT = -1 -} jointHandle_t; - -#ifndef NULL -#define NULL ((void *)0) -#endif - -#define MAX_QINT 0x7fffffff -#define MIN_QINT (-MAX_QINT-1) - -#ifndef max -#define max( x, y ) ( ( ( x ) > ( y ) ) ? ( x ) : ( y ) ) -#define min( x, y ) ( ( ( x ) < ( y ) ) ? ( x ) : ( y ) ) -#endif - -#ifndef sign -#define sign( f ) ( ( f > 0 ) ? 1 : ( ( f < 0 ) ? -1 : 0 ) ) -#endif - -// angle indexes -#define PITCH 0 // up / down -#define YAW 1 // left / right -#define ROLL 2 // fall over - -// the game guarantees that no string from the network will ever -// exceed MAX_STRING_CHARS -#define MAX_STRING_CHARS 1024 // max length of a string passed to Cmd_TokenizeString -#define MAX_STRING_TOKENS 256 // max tokens resulting from Cmd_TokenizeString -#define MAX_TOKEN_CHARS 1024 // max length of an individual token - -#define MAX_INFO_STRING 1024 -#define MAX_INFO_KEY 1024 -#define MAX_INFO_VALUE 1024 - - -#define MAX_QPATH 64 // max length of a quake game pathname -#define MAX_OSPATH 128 // max length of a filesystem pathname - -#define MAX_NAME_LENGTH 32 // max length of a client name - -// paramters for command buffer stuffing -typedef enum { - EXEC_NOW, // don't return until completed, a VM should NEVER use this, - // because some commands might cause the VM to be unloaded... - EXEC_INSERT, // insert at current position, but don't run yet - EXEC_APPEND // add to end of the command buffer (normal case) -} cbufExec_t; - - -// -// these aren't needed by any of the VMs. put in another header? -// -#define MAX_MAP_AREA_BYTES 32 // bit vector of area visibility - -#undef ERR_FATAL // malloc.h on unix - -// parameters to the main Error routine -typedef enum { - ERR_NONE, - ERR_FATAL, // exit the entire game with a popup window - ERR_DROP, // print to console and disconnect from game - ERR_DISCONNECT, // don't kill server - ERR_NEED_CD // pop up the need-cd dialog -} errorParm_t; - - -// font rendering values used by ui and cgame - -#define PROP_GAP_WIDTH 3 -#define PROP_SPACE_WIDTH 8 -#define PROP_HEIGHT 27 -#define PROP_SMALL_SIZE_SCALE 0.75 - -#define BLINK_DIVISOR 200 -#define PULSE_DIVISOR 75 - -#define UI_LEFT 0x00000000 // default -#define UI_CENTER 0x00000001 -#define UI_RIGHT 0x00000002 -#define UI_FORMATMASK 0x00000007 -#define UI_SMALLFONT 0x00000010 -#define UI_BIGFONT 0x00000020 // default -#define UI_GIANTFONT 0x00000040 -#define UI_DROPSHADOW 0x00000800 -#define UI_BLINK 0x00001000 -#define UI_INVERSE 0x00002000 -#define UI_PULSE 0x00004000 - - -/* -============================================================== - -MATHLIB - -============================================================== -*/ -#ifdef __cplusplus // so we can include this in C code -#define SIDE_FRONT 0 -#define SIDE_BACK 1 -#define SIDE_ON 2 -#define SIDE_CROSS 3 - -#define Q_PI 3.14159265358979323846 -#ifndef M_PI -#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h -#endif - -#include "math_vector.h" -#include "math_angles.h" -#include "math_matrix.h" -#include "math_quaternion.h" - -class idVec3_t; // for defining vectors -typedef idVec3_t &vec3_p; // for passing vectors as function arguments -typedef const idVec3_t &vec3_c; // for passing vectors as const function arguments - -class angles_t; // for defining angle vectors -typedef angles_t &angles_p; // for passing angles as function arguments -typedef const angles_t &angles_c; // for passing angles as const function arguments - -class mat3_t; // for defining matrices -typedef mat3_t &mat3_p; // for passing matrices as function arguments -typedef const mat3_t &mat3_c; // for passing matrices as const function arguments - - - -#define NUMVERTEXNORMALS 162 -extern idVec3_t bytedirs[NUMVERTEXNORMALS]; - -// all drawing is done to a 640*480 virtual screen size -// and will be automatically scaled to the real resolution -#define SCREEN_WIDTH 640 -#define SCREEN_HEIGHT 480 - -#define TINYCHAR_WIDTH (SMALLCHAR_WIDTH) -#define TINYCHAR_HEIGHT (SMALLCHAR_HEIGHT/2) - -#define SMALLCHAR_WIDTH 8 -#define SMALLCHAR_HEIGHT 16 - -#define BIGCHAR_WIDTH 16 -#define BIGCHAR_HEIGHT 16 - -#define GIANTCHAR_WIDTH 32 -#define GIANTCHAR_HEIGHT 48 - -extern vec4_t colorBlack; -extern vec4_t colorRed; -extern vec4_t colorGreen; -extern vec4_t colorBlue; -extern vec4_t colorYellow; -extern vec4_t colorMagenta; -extern vec4_t colorCyan; -extern vec4_t colorWhite; -extern vec4_t colorLtGrey; -extern vec4_t colorMdGrey; -extern vec4_t colorDkGrey; - -#define Q_COLOR_ESCAPE '^' -#define Q_IsColorString(p) ( p && *(p) == Q_COLOR_ESCAPE && *((p)+1) && *((p)+1) != Q_COLOR_ESCAPE ) - -#define COLOR_BLACK '0' -#define COLOR_RED '1' -#define COLOR_GREEN '2' -#define COLOR_YELLOW '3' -#define COLOR_BLUE '4' -#define COLOR_CYAN '5' -#define COLOR_MAGENTA '6' -#define COLOR_WHITE '7' -#define ColorIndex(c) ( ( (c) - '0' ) & 7 ) - -#define S_COLOR_BLACK "^0" -#define S_COLOR_RED "^1" -#define S_COLOR_GREEN "^2" -#define S_COLOR_YELLOW "^3" -#define S_COLOR_BLUE "^4" -#define S_COLOR_CYAN "^5" -#define S_COLOR_MAGENTA "^6" -#define S_COLOR_WHITE "^7" - -extern vec4_t g_color_table[8]; - -#define MAKERGB( v, r, g, b ) v[0]=r;v[1]=g;v[2]=b -#define MAKERGBA( v, r, g, b, a ) v[0]=r;v[1]=g;v[2]=b;v[3]=a - -#define DEG2RAD( a ) ( ( (a) * M_PI ) / 180.0F ) -#define RAD2DEG( a ) ( ( (a) * 180.0f ) / M_PI ) - -struct cplane_s; - -extern idVec3_t vec3_origin; -extern vec4_t vec4_origin; -extern mat3_t axisDefault; - -#define nanmask (255<<23) - -#define IS_NAN(x) (((*(int *)&x)&nanmask)==nanmask) - -float Q_fabs( float f ); -float Q_rsqrt( float f ); // reciprocal square root - -#define SQRTFAST( x ) ( 1.0f / Q_rsqrt( x ) ) - -signed char ClampChar( int i ); -signed short ClampShort( int i ); - -// this isn't a real cheap function to call! -int DirToByte( const idVec3_t &dir ); -void ByteToDir( int b, vec3_p dir ); - -#define DotProduct(a,b) ((a)[0]*(b)[0]+(a)[1]*(b)[1]+(a)[2]*(b)[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 VectorCopy(a,b) ((b).x=(a).x,(b).y=(a).y,(b).z=(a).z]) - -#define VectorScale(v, s, o) ((o)[0]=(v)[0]*(s),(o)[1]=(v)[1]*(s),(o)[2]=(v)[2]*(s)) -#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)) -#define CrossProduct(a,b,c) ((c)[0]=(a)[1]*(b)[2]-(a)[2]*(b)[1],(c)[1]=(a)[2]*(b)[0]-(a)[0]*(b)[2],(c)[2]=(a)[0]*(b)[1]-(a)[1]*(b)[0]) - -#define DotProduct4(x,y) ((x)[0]*(y)[0]+(x)[1]*(y)[1]+(x)[2]*(y)[2]+(x)[3]*(y)[3]) -#define VectorSubtract4(a,b,c) ((c)[0]=(a)[0]-(b)[0],(c)[1]=(a)[1]-(b)[1],(c)[2]=(a)[2]-(b)[2],(c)[3]=(a)[3]-(b)[3]) -#define VectorAdd4(a,b,c) ((c)[0]=(a)[0]+(b)[0],(c)[1]=(a)[1]+(b)[1],(c)[2]=(a)[2]+(b)[2],(c)[3]=(a)[3]+(b)[3]) -#define VectorCopy4(a,b) ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2],(b)[3]=(a)[3]) -#define VectorScale4(v, s, o) ((o)[0]=(v)[0]*(s),(o)[1]=(v)[1]*(s),(o)[2]=(v)[2]*(s),(o)[3]=(v)[3]*(s)) -#define VectorMA4(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),(o)[3]=(v)[3]+(b)[3]*(s)) - - -#define VectorClear(a) ((a)[0]=(a)[1]=(a)[2]=0) -#define VectorNegate(a,b) ((b)[0]=-(a)[0],(b)[1]=-(a)[1],(b)[2]=-(a)[2]) -#define VectorSet(v, x, y, z) ((v)[0]=(x), (v)[1]=(y), (v)[2]=(z)) -#define Vector4Copy(a,b) ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2],(b)[3]=(a)[3]) - -#define SnapVector(v) {v[0]=(int)v[0];v[1]=(int)v[1];v[2]=(int)v[2];} - -float NormalizeColor( vec3_c in, vec3_p out ); - -int VectorCompare( vec3_c v1, vec3_c v2 ); -float VectorLength( vec3_c v ); -float Distance( vec3_c p1, vec3_c p2 ); -float DistanceSquared( vec3_c p1, vec3_c p2 ); -float VectorNormalize (vec3_p v); // returns vector length -void VectorNormalizeFast(vec3_p v); // does NOT return vector length, uses rsqrt approximation -float VectorNormalize2( vec3_c v, vec3_p out ); -void VectorInverse (vec3_p v); -void VectorRotate( vec3_c in, mat3_c matrix, vec3_p out ); -void VectorPolar(vec3_p v, float radius, float theta, float phi); -void VectorSnap(vec3_p v); -void Vector53Copy( const idVec5_t &in, vec3_p out); -void Vector5Scale( const idVec5_t &v, float scale, idVec5_t &out); -void Vector5Add( const idVec5_t &va, const idVec5_t &vb, idVec5_t &out); -void VectorRotate3( vec3_c vIn, vec3_c vRotation, vec3_p out); -void VectorRotate3Origin(vec3_c vIn, vec3_c vRotation, vec3_c vOrigin, vec3_p out); - - -int Q_log2(int val); - -int Q_rand( int *seed ); -float Q_random( int *seed ); -float Q_crandom( int *seed ); - -#define random() ((rand () & 0x7fff) / ((float)0x7fff)) -#define crandom() (2.0 * (random() - 0.5)) - -float Q_rint( float in ); - -void vectoangles( vec3_c value1, angles_p angles); -void AnglesToAxis( angles_c angles, mat3_p axis ); - -void AxisCopy( mat3_c in, mat3_p out ); -qboolean AxisRotated( mat3_c in ); // assumes a non-degenerate axis - -int SignbitsForNormal( vec3_c normal ); -int BoxOnPlaneSide( const Bounds &b, struct cplane_s *p ); - -float AngleMod(float a); -float LerpAngle (float from, float to, float frac); -float AngleSubtract( float a1, float a2 ); -void AnglesSubtract( angles_c v1, angles_c v2, angles_p v3 ); - -float AngleNormalize360 ( float angle ); -float AngleNormalize180 ( float angle ); -float AngleDelta ( float angle1, float angle2 ); - -qboolean PlaneFromPoints( vec4_t &plane, vec3_c a, vec3_c b, vec3_c c ); -void ProjectPointOnPlane( vec3_p dst, vec3_c p, vec3_c normal ); -void RotatePointAroundVector( vec3_p dst, vec3_c dir, vec3_c point, float degrees ); -void RotateAroundDirection( mat3_p axis, float yaw ); -void MakeNormalVectors( vec3_c forward, vec3_p right, vec3_p up ); -// perpendicular vector could be replaced by this - -int PlaneTypeForNormal( vec3_c normal ); - -void MatrixMultiply( mat3_c in1, mat3_c in2, mat3_p out ); -void MatrixInverseMultiply( mat3_c in1, mat3_c in2, mat3_p out ); // in2 is transposed during multiply -void MatrixTransformVector( vec3_c in, mat3_c matrix, vec3_p out ); -void MatrixProjectVector( vec3_c in, mat3_c matrix, vec3_p out ); // Places the vector into a new coordinate system. -void AngleVectors( angles_c angles, vec3_p forward, vec3_p right, vec3_p up); -void PerpendicularVector( vec3_p dst, vec3_c src ); - -float TriangleArea( vec3_c a, vec3_c b, vec3_c c ); -#endif // __cplusplus - -//============================================= - -float Com_Clamp( float min, float max, float value ); - -#define FILE_HASH_SIZE 1024 -int Com_HashString( const char *fname ); - -char *Com_SkipPath( char *pathname ); - -// it is ok for out == in -void Com_StripExtension( const char *in, char *out ); - -// "extension" should include the dot: ".map" -void Com_DefaultExtension( char *path, int maxSize, const char *extension ); - -int Com_ParseInfos( const char *buf, int max, char infos[][MAX_INFO_STRING] ); - -/* -===================================================================================== - -SCRIPT PARSING - -===================================================================================== -*/ - -// this just controls the comment printing, it doesn't actually load a file -void Com_BeginParseSession( const char *filename ); -void Com_EndParseSession( void ); - -int Com_GetCurrentParseLine( void ); - -// Will never return NULL, just empty strings. -// An empty string will only be returned at end of file. -// ParseOnLine will return empty if there isn't another token on this line - -// this funny typedef just means a moving pointer into a const char * buffer -const char *Com_Parse( const char *(*data_p) ); -const char *Com_ParseOnLine( const char *(*data_p) ); -const char *Com_ParseRestOfLine( const char *(*data_p) ); - -void Com_UngetToken( void ); - -#ifdef __cplusplus -void Com_MatchToken( const char *(*buf_p), const char *match, qboolean warning = qfalse ); -#else -void Com_MatchToken( const char *(*buf_p), const char *match, qboolean warning ); -#endif - -void Com_ScriptError( const char *msg, ... ); -void Com_ScriptWarning( const char *msg, ... ); - -void Com_SkipBracedSection( const char *(*program) ); -void Com_SkipRestOfLine( const char *(*data) ); - -float Com_ParseFloat( const char *(*buf_p) ); -int Com_ParseInt( const char *(*buf_p) ); - -void Com_Parse1DMatrix( const char *(*buf_p), int x, float *m ); -void Com_Parse2DMatrix( const char *(*buf_p), int y, int x, float *m ); -void Com_Parse3DMatrix( const char *(*buf_p), int z, int y, int x, float *m ); - -//===================================================================================== -#ifdef __cplusplus - extern "C" { -#endif - -void QDECL Com_sprintf (char *dest, int size, const char *fmt, ...); - - -// mode parm for FS_FOpenFile -typedef enum { - FS_READ, - FS_WRITE, - FS_APPEND, - FS_APPEND_SYNC -} fsMode_t; - -typedef enum { - FS_SEEK_CUR, - FS_SEEK_END, - FS_SEEK_SET -} fsOrigin_t; - -//============================================= - -int Q_isprint( int c ); -int Q_islower( int c ); -int Q_isupper( int c ); -int Q_isalpha( int c ); - -// portable case insensitive compare -int Q_stricmp (const char *s1, const char *s2); -int Q_strncmp (const char *s1, const char *s2, int n); -int Q_stricmpn (const char *s1, const char *s2, int n); -char *Q_strlwr( char *s1 ); -char *Q_strupr( char *s1 ); -char *Q_strrchr( const char* string, int c ); - -// buffer size safe library replacements -void Q_strncpyz( char *dest, const char *src, int destsize ); -void Q_strcat( char *dest, int size, const char *src ); - -// strlen that discounts Quake color sequences -int Q_PrintStrlen( const char *string ); -// removes color sequences from string -char *Q_CleanStr( char *string ); - -int Com_Filter( const char *filter, const char *name, int casesensitive ); -const char *Com_StringContains( const char *str1, const char *str2, int casesensitive ); - - -//============================================= - -short BigShort(short l); -short LittleShort(short l); -int BigLong (int l); -int LittleLong (int l); -float BigFloat (float l); -float LittleFloat (float l); - -void Swap_Init (void); -char * QDECL va(char *format, ...); - -#ifdef __cplusplus - } -#endif - - -//============================================= -#ifdef __cplusplus -// -// mapfile parsing -// -typedef struct ePair_s { - char *key; - char *value; -} ePair_t; - -typedef struct mapSide_s { - char material[MAX_QPATH]; - vec4_t plane; - vec4_t textureVectors[2]; -} mapSide_t; - -typedef struct { - int numSides; - mapSide_t **sides; -} mapBrush_t; - -typedef struct { - idVec3_t xyz; - float st[2]; -} patchVertex_t; - -typedef struct { - char material[MAX_QPATH]; - int width, height; - patchVertex_t *patchVerts; -} mapPatch_t; - -typedef struct { - char modelName[MAX_QPATH]; - float matrix[16]; -} mapModel_t; - -typedef struct mapPrimitive_s { - int numEpairs; - ePair_t **ePairs; - - // only one of these will be non-NULL - mapBrush_t *brush; - mapPatch_t *patch; - mapModel_t *model; -} mapPrimitive_t; - -typedef struct mapEntity_s { - int numPrimitives; - mapPrimitive_t **primitives; - - int numEpairs; - ePair_t **ePairs; -} mapEntity_t; - -typedef struct { - int numEntities; - mapEntity_t **entities; -} mapFile_t; - - -// the order of entities, brushes, and sides will be maintained, the -// lists won't be swapped on each load or save -mapFile_t *ParseMapFile( const char *text ); -void FreeMapFile( mapFile_t *mapFile ); -void WriteMapFile( const mapFile_t *mapFile, FILE *f ); - -// key names are case-insensitive -const char *ValueForMapEntityKey( const mapEntity_t *ent, const char *key ); -float FloatForMapEntityKey( const mapEntity_t *ent, const char *key ); -qboolean GetVectorForMapEntityKey( const mapEntity_t *ent, const char *key, idVec3_t &vec ); - -typedef struct { - idVec3_t xyz; - idVec2_t st; - idVec3_t normal; - idVec3_t tangents[2]; - byte smoothing[4]; // colors for silhouette smoothing -} drawVert_t; - -typedef struct { - int width, height; - drawVert_t *verts; -} drawVertMesh_t; - -// Tesselate a map patch into smoothed, drawable vertexes -// MaxError of around 4 is reasonable -drawVertMesh_t *SubdivideMapPatch( const mapPatch_t *patch, float maxError ); -#endif // __cplusplus - -//========================================= - -#ifdef __cplusplus - extern "C" { -#endif - -void QDECL Com_Error( int level, const char *error, ... ); -void QDECL Com_Printf( const char *msg, ... ); -void QDECL Com_DPrintf( const char *msg, ... ); - -#ifdef __cplusplus - } -#endif - - -typedef struct { - qboolean frameMemory; - int currentElements; - int maxElements; // will reallocate and move when exceeded - void **elements; -} growList_t; - -// you don't need to init the growlist if you don't mind it growing and moving -// the list as it expands -void Com_InitGrowList( growList_t *list, int maxElements ); -int Com_AddToGrowList( growList_t *list, void *data ); -void *Com_GrowListElement( const growList_t *list, int index ); -int Com_IndexForGrowListElement( const growList_t *list, const void *element ); - - -// -// key / value info strings -// -char *Info_ValueForKey( const char *s, const char *key ); -void Info_RemoveKey( char *s, const char *key ); -void Info_SetValueForKey( char *s, const char *key, const char *value ); -qboolean Info_Validate( const char *s ); -void Info_NextPair( const char *(*s), char key[MAX_INFO_KEY], char value[MAX_INFO_VALUE] ); - -// get cvar defs, collision defs, etc -//#include "../shared/interface.h" - -// get key code numbers for events -//#include "../shared/keycodes.h" - -#ifdef __cplusplus -// get the polygon winding functions -//#include "../shared/windings.h" - -// get the flags class -//#include "../shared/idflags.h" -#endif // __cplusplus - -#endif // __Q_SHARED_H - diff --git a/code/splines/q_shared.hpp b/code/splines/q_shared.hpp deleted file mode 100644 index 31ae71a..0000000 --- a/code/splines/q_shared.hpp +++ /dev/null @@ -1,841 +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 Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -#ifndef __Q_SHARED_H -#define __Q_SHARED_H - -// q_shared.h -- included first by ALL program modules. -// these are the definitions that have no dependance on -// central system services, and can be used by any part -// of the program without any state issues. - -// A user mod should never modify this file - -// incursion of DOOM code into the Q3A codebase -//#define Q3_VERSION "DOOM 0.01" - -// alignment macros for SIMD -#define ALIGN_ON -#define ALIGN_OFF - -#ifdef _WIN32 - -#pragma warning(disable : 4018) // signed/unsigned mismatch -#pragma warning(disable : 4032) -#pragma warning(disable : 4051) -#pragma warning(disable : 4057) // slightly different base types -#pragma warning(disable : 4100) // unreferenced formal parameter -#pragma warning(disable : 4115) -#pragma warning(disable : 4125) // decimal digit terminates octal escape sequence -#pragma warning(disable : 4127) // conditional expression is constant -#pragma warning(disable : 4136) -#pragma warning(disable : 4201) -#pragma warning(disable : 4214) -#pragma warning(disable : 4244) -#pragma warning(disable : 4305) // truncation from const double to float -#pragma warning(disable : 4310) // cast truncates constant value -#pragma warning(disable : 4514) -#pragma warning(disable : 4711) // selected for automatic inline expansion -#pragma warning(disable : 4220) // varargs matches remaining parameters - -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef WIN32 // mac doesn't have malloc.h -#include // for _alloca() -#endif -#ifdef _WIN32 - -//#pragma intrinsic( memset, memcpy ) - -#endif - - -// this is the define for determining if we have an asm version of a C function -#if (defined _M_IX86 || defined __i386__) && !defined __sun__ && !defined __LCC__ -#define id386 1 -#else -#define id386 0 -#endif - -// for windows fastcall option - -#define QDECL - -//======================= WIN32 DEFINES ================================= - -#ifdef WIN32 - -#define MAC_STATIC - -#undef QDECL -#define QDECL __cdecl - -// buildstring will be incorporated into the version string -#ifdef NDEBUG -#ifdef _M_IX86 -#define CPUSTRING "win-x86" -#elif defined _M_ALPHA -#define CPUSTRING "win-AXP" -#endif -#else -#ifdef _M_IX86 -#define CPUSTRING "win-x86-debug" -#elif defined _M_ALPHA -#define CPUSTRING "win-AXP-debug" -#endif -#endif - - -#define PATH_SEP '\\' - -#endif - -//======================= MAC OS X SERVER DEFINES ===================== - -#if defined(__MACH__) && defined(__APPLE__) - -#define MAC_STATIC - -#ifdef __ppc__ -#define CPUSTRING "MacOSXS-ppc" -#elif defined __i386__ -#define CPUSTRING "MacOSXS-i386" -#else -#define CPUSTRING "MacOSXS-other" -#endif - -#define PATH_SEP '/' - -#define GAME_HARD_LINKED -#define CGAME_HARD_LINKED -#define UI_HARD_LINKED -#define _alloca alloca - -#undef ALIGN_ON -#undef ALIGN_OFF -#define ALIGN_ON #pragma align(16) -#define ALIGN_OFF #pragma align() - -#ifdef __cplusplus - extern "C" { -#endif - -void *osxAllocateMemory(long size); -void osxFreeMemory(void *pointer); - -#ifdef __cplusplus - } -#endif - -#endif - -//======================= MAC DEFINES ================================= - -#ifdef __MACOS__ - -#define MAC_STATIC static - -#define CPUSTRING "MacOS-PPC" - -#define PATH_SEP ':' - -void Sys_PumpEvents( void ); - -#endif - -#ifdef __MRC__ - -#define MAC_STATIC - -#define CPUSTRING "MacOS-PPC" - -#define PATH_SEP ':' - -void Sys_PumpEvents( void ); - -#undef QDECL -#define QDECL __cdecl - -#define _alloca alloca -#endif - -//======================= LINUX DEFINES ================================= - -// the mac compiler can't handle >32k of locals, so we -// just waste space and make big arrays static... -#ifdef __linux__ - -// bk001205 - from Makefile -#define stricmp strcasecmp - -#define MAC_STATIC // bk: FIXME - -#ifdef __i386__ -#define CPUSTRING "linux-i386" -#elif defined __axp__ -#define CPUSTRING "linux-alpha" -#else -#define CPUSTRING "linux-other" -#endif - -#define PATH_SEP '/' - -// bk001205 - try -#ifdef Q3_STATIC -#define GAME_HARD_LINKED -#define CGAME_HARD_LINKED -#define UI_HARD_LINKED -#define BOTLIB_HARD_LINKED -#endif - -#endif - -//======================= FreeBSD DEFINES ================================= - -// the mac compiler can't handle >32k of locals, so we -// just waste space and make big arrays static... -#ifdef __FreeBSD__ - -// bk001205 - from Makefile -#define stricmp strcasecmp - -#define MAC_STATIC // bk: FIXME - -#ifdef __i386__ -#define CPUSTRING "freebsd-i386" -#elif defined __axp__ -#define CPUSTRING "freebsd-alpha" -#else -#define CPUSTRING "freebsd-other" -#endif - -#define PATH_SEP '/' - -// bk001205 - try -#ifdef Q3_STATIC -#define GAME_HARD_LINKED -#define CGAME_HARD_LINKED -#define UI_HARD_LINKED -#define BOTLIB_HARD_LINKED -#endif - -#endif - -//============================================================= - - - -typedef enum {qfalse, qtrue} qboolean; - -typedef unsigned char byte; - -#define EQUAL_EPSILON 0.001 - -typedef int qhandle_t; -typedef int sfxHandle_t; -typedef int fileHandle_t; -typedef int clipHandle_t; - -typedef enum { - INVALID_JOINT = -1 -} jointHandle_t; - -#ifndef NULL -#define NULL ((void *)0) -#endif - -#define MAX_QINT 0x7fffffff -#define MIN_QINT (-MAX_QINT-1) - -#ifndef max -#define max( x, y ) ( ( ( x ) > ( y ) ) ? ( x ) : ( y ) ) -#define min( x, y ) ( ( ( x ) < ( y ) ) ? ( x ) : ( y ) ) -#endif - -#ifndef sign -#define sign( f ) ( ( f > 0 ) ? 1 : ( ( f < 0 ) ? -1 : 0 ) ) -#endif - -// angle indexes -#define PITCH 0 // up / down -#define YAW 1 // left / right -#define ROLL 2 // fall over - -// the game guarantees that no string from the network will ever -// exceed MAX_STRING_CHARS -#define MAX_STRING_CHARS 1024 // max length of a string passed to Cmd_TokenizeString -#define MAX_STRING_TOKENS 256 // max tokens resulting from Cmd_TokenizeString -#define MAX_TOKEN_CHARS 1024 // max length of an individual token - -#define MAX_INFO_STRING 1024 -#define MAX_INFO_KEY 1024 -#define MAX_INFO_VALUE 1024 - - -#define MAX_QPATH 64 // max length of a quake game pathname -#define MAX_OSPATH 128 // max length of a filesystem pathname - -#define MAX_NAME_LENGTH 32 // max length of a client name - -// paramters for command buffer stuffing -typedef enum { - EXEC_NOW, // don't return until completed, a VM should NEVER use this, - // because some commands might cause the VM to be unloaded... - EXEC_INSERT, // insert at current position, but don't run yet - EXEC_APPEND // add to end of the command buffer (normal case) -} cbufExec_t; - - -// -// these aren't needed by any of the VMs. put in another header? -// -#define MAX_MAP_AREA_BYTES 32 // bit vector of area visibility - -#undef ERR_FATAL // malloc.h on unix - -// parameters to the main Error routine -typedef enum { - ERR_NONE, - ERR_FATAL, // exit the entire game with a popup window - ERR_DROP, // print to console and disconnect from game - ERR_DISCONNECT, // don't kill server - ERR_NEED_CD // pop up the need-cd dialog -} errorParm_t; - - -// font rendering values used by ui and cgame - -#define PROP_GAP_WIDTH 3 -#define PROP_SPACE_WIDTH 8 -#define PROP_HEIGHT 27 -#define PROP_SMALL_SIZE_SCALE 0.75 - -#define BLINK_DIVISOR 200 -#define PULSE_DIVISOR 75 - -#define UI_LEFT 0x00000000 // default -#define UI_CENTER 0x00000001 -#define UI_RIGHT 0x00000002 -#define UI_FORMATMASK 0x00000007 -#define UI_SMALLFONT 0x00000010 -#define UI_BIGFONT 0x00000020 // default -#define UI_GIANTFONT 0x00000040 -#define UI_DROPSHADOW 0x00000800 -#define UI_BLINK 0x00001000 -#define UI_INVERSE 0x00002000 -#define UI_PULSE 0x00004000 - - -/* -============================================================== - -MATHLIB - -============================================================== -*/ -#ifdef __cplusplus // so we can include this in C code -#define SIDE_FRONT 0 -#define SIDE_BACK 1 -#define SIDE_ON 2 -#define SIDE_CROSS 3 - -#define Q_PI 3.14159265358979323846 -#ifndef M_PI -#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h -#endif - -#include "math_vector.h" -#include "math_angles.h" -#include "math_matrix.h" -#include "math_quaternion.h" - -class idVec3_t; // for defining vectors -typedef idVec3_t &vec3_p; // for passing vectors as function arguments -typedef const idVec3_t &vec3_c; // for passing vectors as const function arguments - -class angles_t; // for defining angle vectors -typedef angles_t &angles_p; // for passing angles as function arguments -typedef const angles_t &angles_c; // for passing angles as const function arguments - -class mat3_t; // for defining matrices -typedef mat3_t &mat3_p; // for passing matrices as function arguments -typedef const mat3_t &mat3_c; // for passing matrices as const function arguments - - - -#define NUMVERTEXNORMALS 162 -extern idVec3_t bytedirs[NUMVERTEXNORMALS]; - -// all drawing is done to a 640*480 virtual screen size -// and will be automatically scaled to the real resolution -#define SCREEN_WIDTH 640 -#define SCREEN_HEIGHT 480 - -#define TINYCHAR_WIDTH (SMALLCHAR_WIDTH) -#define TINYCHAR_HEIGHT (SMALLCHAR_HEIGHT/2) - -#define SMALLCHAR_WIDTH 8 -#define SMALLCHAR_HEIGHT 16 - -#define BIGCHAR_WIDTH 16 -#define BIGCHAR_HEIGHT 16 - -#define GIANTCHAR_WIDTH 32 -#define GIANTCHAR_HEIGHT 48 - -extern vec4_t colorBlack; -extern vec4_t colorRed; -extern vec4_t colorGreen; -extern vec4_t colorBlue; -extern vec4_t colorYellow; -extern vec4_t colorMagenta; -extern vec4_t colorCyan; -extern vec4_t colorWhite; -extern vec4_t colorLtGrey; -extern vec4_t colorMdGrey; -extern vec4_t colorDkGrey; - -#define Q_COLOR_ESCAPE '^' -#define Q_IsColorString(p) ( p && *(p) == Q_COLOR_ESCAPE && *((p)+1) && *((p)+1) != Q_COLOR_ESCAPE ) - -#define COLOR_BLACK '0' -#define COLOR_RED '1' -#define COLOR_GREEN '2' -#define COLOR_YELLOW '3' -#define COLOR_BLUE '4' -#define COLOR_CYAN '5' -#define COLOR_MAGENTA '6' -#define COLOR_WHITE '7' -#define ColorIndex(c) ( ( (c) - '0' ) & 7 ) - -#define S_COLOR_BLACK "^0" -#define S_COLOR_RED "^1" -#define S_COLOR_GREEN "^2" -#define S_COLOR_YELLOW "^3" -#define S_COLOR_BLUE "^4" -#define S_COLOR_CYAN "^5" -#define S_COLOR_MAGENTA "^6" -#define S_COLOR_WHITE "^7" - -extern vec4_t g_color_table[8]; - -#define MAKERGB( v, r, g, b ) v[0]=r;v[1]=g;v[2]=b -#define MAKERGBA( v, r, g, b, a ) v[0]=r;v[1]=g;v[2]=b;v[3]=a - -#define DEG2RAD( a ) ( ( (a) * M_PI ) / 180.0F ) -#define RAD2DEG( a ) ( ( (a) * 180.0f ) / M_PI ) - -struct cplane_s; - -extern idVec3_t vec3_origin; -extern vec4_t vec4_origin; -extern mat3_t axisDefault; - -#define nanmask (255<<23) - -#define IS_NAN(x) (((*(int *)&x)&nanmask)==nanmask) - -float Q_fabs( float f ); -float Q_rsqrt( float f ); // reciprocal square root - -#define SQRTFAST( x ) ( 1.0f / Q_rsqrt( x ) ) - -signed char ClampChar( int i ); -signed short ClampShort( int i ); - -// this isn't a real cheap function to call! -int DirToByte( const idVec3_t &dir ); -void ByteToDir( int b, vec3_p dir ); - -#define DotProduct(a,b) ((a)[0]*(b)[0]+(a)[1]*(b)[1]+(a)[2]*(b)[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 VectorCopy(a,b) ((b).x=(a).x,(b).y=(a).y,(b).z=(a).z]) - -#define VectorScale(v, s, o) ((o)[0]=(v)[0]*(s),(o)[1]=(v)[1]*(s),(o)[2]=(v)[2]*(s)) -#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)) -#define CrossProduct(a,b,c) ((c)[0]=(a)[1]*(b)[2]-(a)[2]*(b)[1],(c)[1]=(a)[2]*(b)[0]-(a)[0]*(b)[2],(c)[2]=(a)[0]*(b)[1]-(a)[1]*(b)[0]) - -#define DotProduct4(x,y) ((x)[0]*(y)[0]+(x)[1]*(y)[1]+(x)[2]*(y)[2]+(x)[3]*(y)[3]) -#define VectorSubtract4(a,b,c) ((c)[0]=(a)[0]-(b)[0],(c)[1]=(a)[1]-(b)[1],(c)[2]=(a)[2]-(b)[2],(c)[3]=(a)[3]-(b)[3]) -#define VectorAdd4(a,b,c) ((c)[0]=(a)[0]+(b)[0],(c)[1]=(a)[1]+(b)[1],(c)[2]=(a)[2]+(b)[2],(c)[3]=(a)[3]+(b)[3]) -#define VectorCopy4(a,b) ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2],(b)[3]=(a)[3]) -#define VectorScale4(v, s, o) ((o)[0]=(v)[0]*(s),(o)[1]=(v)[1]*(s),(o)[2]=(v)[2]*(s),(o)[3]=(v)[3]*(s)) -#define VectorMA4(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),(o)[3]=(v)[3]+(b)[3]*(s)) - - -#define VectorClear(a) ((a)[0]=(a)[1]=(a)[2]=0) -#define VectorNegate(a,b) ((b)[0]=-(a)[0],(b)[1]=-(a)[1],(b)[2]=-(a)[2]) -#define VectorSet(v, x, y, z) ((v)[0]=(x), (v)[1]=(y), (v)[2]=(z)) -#define Vector4Copy(a,b) ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2],(b)[3]=(a)[3]) - -#define SnapVector(v) {v[0]=(int)v[0];v[1]=(int)v[1];v[2]=(int)v[2];} - -float NormalizeColor( vec3_c in, vec3_p out ); - -int VectorCompare( vec3_c v1, vec3_c v2 ); -float VectorLength( vec3_c v ); -float Distance( vec3_c p1, vec3_c p2 ); -float DistanceSquared( vec3_c p1, vec3_c p2 ); -float VectorNormalize (vec3_p v); // returns vector length -void VectorNormalizeFast(vec3_p v); // does NOT return vector length, uses rsqrt approximation -float VectorNormalize2( vec3_c v, vec3_p out ); -void VectorInverse (vec3_p v); -void VectorRotate( vec3_c in, mat3_c matrix, vec3_p out ); -void VectorPolar(vec3_p v, float radius, float theta, float phi); -void VectorSnap(vec3_p v); -void Vector53Copy( const idVec5_t &in, vec3_p out); -void Vector5Scale( const idVec5_t &v, float scale, idVec5_t &out); -void Vector5Add( const idVec5_t &va, const idVec5_t &vb, idVec5_t &out); -void VectorRotate3( vec3_c vIn, vec3_c vRotation, vec3_p out); -void VectorRotate3Origin(vec3_c vIn, vec3_c vRotation, vec3_c vOrigin, vec3_p out); - - -int Q_log2(int val); - -int Q_rand( int *seed ); -float Q_random( int *seed ); -float Q_crandom( int *seed ); - -#define random() ((rand () & 0x7fff) / ((float)0x7fff)) -#define crandom() (2.0 * (random() - 0.5)) - -float Q_rint( float in ); - -void vectoangles( vec3_c value1, angles_p angles); -void AnglesToAxis( angles_c angles, mat3_p axis ); - -void AxisCopy( mat3_c in, mat3_p out ); -qboolean AxisRotated( mat3_c in ); // assumes a non-degenerate axis - -int SignbitsForNormal( vec3_c normal ); -int BoxOnPlaneSide( const Bounds &b, struct cplane_s *p ); - -float AngleMod(float a); -float LerpAngle (float from, float to, float frac); -float AngleSubtract( float a1, float a2 ); -void AnglesSubtract( angles_c v1, angles_c v2, angles_p v3 ); - -float AngleNormalize360 ( float angle ); -float AngleNormalize180 ( float angle ); -float AngleDelta ( float angle1, float angle2 ); - -qboolean PlaneFromPoints( vec4_t &plane, vec3_c a, vec3_c b, vec3_c c ); -void ProjectPointOnPlane( vec3_p dst, vec3_c p, vec3_c normal ); -void RotatePointAroundVector( vec3_p dst, vec3_c dir, vec3_c point, float degrees ); -void RotateAroundDirection( mat3_p axis, float yaw ); -void MakeNormalVectors( vec3_c forward, vec3_p right, vec3_p up ); -// perpendicular vector could be replaced by this - -int PlaneTypeForNormal( vec3_c normal ); - -void MatrixMultiply( mat3_c in1, mat3_c in2, mat3_p out ); -void MatrixInverseMultiply( mat3_c in1, mat3_c in2, mat3_p out ); // in2 is transposed during multiply -void MatrixTransformVector( vec3_c in, mat3_c matrix, vec3_p out ); -void MatrixProjectVector( vec3_c in, mat3_c matrix, vec3_p out ); // Places the vector into a new coordinate system. -void AngleVectors( angles_c angles, vec3_p forward, vec3_p right, vec3_p up); -void PerpendicularVector( vec3_p dst, vec3_c src ); - -float TriangleArea( vec3_c a, vec3_c b, vec3_c c ); -#endif // __cplusplus - -//============================================= - -float Com_Clamp( float min, float max, float value ); - -#define FILE_HASH_SIZE 1024 -int Com_HashString( const char *fname ); - -char *Com_SkipPath( char *pathname ); - -// it is ok for out == in -void Com_StripExtension( const char *in, char *out ); - -// "extension" should include the dot: ".map" -void Com_DefaultExtension( char *path, int maxSize, const char *extension ); - -int Com_ParseInfos( const char *buf, int max, char infos[][MAX_INFO_STRING] ); - -/* -===================================================================================== - -SCRIPT PARSING - -===================================================================================== -*/ - -// this just controls the comment printing, it doesn't actually load a file -void Com_BeginParseSession( const char *filename ); -void Com_EndParseSession( void ); - -int Com_GetCurrentParseLine( void ); - -// Will never return NULL, just empty strings. -// An empty string will only be returned at end of file. -// ParseOnLine will return empty if there isn't another token on this line - -// this funny typedef just means a moving pointer into a const char * buffer -const char *Com_Parse( const char *(*data_p) ); -const char *Com_ParseOnLine( const char *(*data_p) ); -const char *Com_ParseRestOfLine( const char *(*data_p) ); - -void Com_UngetToken( void ); - -#ifdef __cplusplus -void Com_MatchToken( const char *(*buf_p), const char *match, qboolean warning = qfalse ); -#else -void Com_MatchToken( const char *(*buf_p), const char *match, qboolean warning ); -#endif - -void Com_ScriptError( const char *msg, ... ); -void Com_ScriptWarning( const char *msg, ... ); - -void Com_SkipBracedSection( const char *(*program) ); -void Com_SkipRestOfLine( const char *(*data) ); - -float Com_ParseFloat( const char *(*buf_p) ); -int Com_ParseInt( const char *(*buf_p) ); - -void Com_Parse1DMatrix( const char *(*buf_p), int x, float *m ); -void Com_Parse2DMatrix( const char *(*buf_p), int y, int x, float *m ); -void Com_Parse3DMatrix( const char *(*buf_p), int z, int y, int x, float *m ); - -//===================================================================================== -#ifdef __cplusplus - extern "C" { -#endif - -void QDECL Com_sprintf (char *dest, int size, const char *fmt, ...); - - -// mode parm for FS_FOpenFile -typedef enum { - FS_READ, - FS_WRITE, - FS_APPEND, - FS_APPEND_SYNC -} fsMode_t; - -typedef enum { - FS_SEEK_CUR, - FS_SEEK_END, - FS_SEEK_SET -} fsOrigin_t; - -//============================================= - -int Q_isprint( int c ); -int Q_islower( int c ); -int Q_isupper( int c ); -int Q_isalpha( int c ); - -// portable case insensitive compare -int Q_stricmp (const char *s1, const char *s2); -int Q_strncmp (const char *s1, const char *s2, int n); -int Q_stricmpn (const char *s1, const char *s2, int n); -char *Q_strlwr( char *s1 ); -char *Q_strupr( char *s1 ); -char *Q_strrchr( const char* string, int c ); - -// buffer size safe library replacements -void Q_strncpyz( char *dest, const char *src, int destsize ); -void Q_strcat( char *dest, int size, const char *src ); - -// strlen that discounts Quake color sequences -int Q_PrintStrlen( const char *string ); -// removes color sequences from string -char *Q_CleanStr( char *string ); - -int Com_Filter( const char *filter, const char *name, int casesensitive ); -const char *Com_StringContains( const char *str1, const char *str2, int casesensitive ); - - -//============================================= - -short BigShort(short l); -short LittleShort(short l); -int BigLong (int l); -int LittleLong (int l); -float BigFloat (float l); -float LittleFloat (float l); - -void Swap_Init (void); -char * QDECL va(char *format, ...); - -#ifdef __cplusplus - } -#endif - - -//============================================= -#ifdef __cplusplus -// -// mapfile parsing -// -typedef struct ePair_s { - char *key; - char *value; -} ePair_t; - -typedef struct mapSide_s { - char material[MAX_QPATH]; - vec4_t plane; - vec4_t textureVectors[2]; -} mapSide_t; - -typedef struct { - int numSides; - mapSide_t **sides; -} mapBrush_t; - -typedef struct { - idVec3_t xyz; - float st[2]; -} patchVertex_t; - -typedef struct { - char material[MAX_QPATH]; - int width, height; - patchVertex_t *patchVerts; -} mapPatch_t; - -typedef struct { - char modelName[MAX_QPATH]; - float matrix[16]; -} mapModel_t; - -typedef struct mapPrimitive_s { - int numEpairs; - ePair_t **ePairs; - - // only one of these will be non-NULL - mapBrush_t *brush; - mapPatch_t *patch; - mapModel_t *model; -} mapPrimitive_t; - -typedef struct mapEntity_s { - int numPrimitives; - mapPrimitive_t **primitives; - - int numEpairs; - ePair_t **ePairs; -} mapEntity_t; - -typedef struct { - int numEntities; - mapEntity_t **entities; -} mapFile_t; - - -// the order of entities, brushes, and sides will be maintained, the -// lists won't be swapped on each load or save -mapFile_t *ParseMapFile( const char *text ); -void FreeMapFile( mapFile_t *mapFile ); -void WriteMapFile( const mapFile_t *mapFile, FILE *f ); - -// key names are case-insensitive -const char *ValueForMapEntityKey( const mapEntity_t *ent, const char *key ); -float FloatForMapEntityKey( const mapEntity_t *ent, const char *key ); -qboolean GetVectorForMapEntityKey( const mapEntity_t *ent, const char *key, idVec3_t &vec ); - -typedef struct { - idVec3_t xyz; - idVec2_t st; - idVec3_t normal; - idVec3_t tangents[2]; - byte smoothing[4]; // colors for silhouette smoothing -} drawVert_t; - -typedef struct { - int width, height; - drawVert_t *verts; -} drawVertMesh_t; - -// Tesselate a map patch into smoothed, drawable vertexes -// MaxError of around 4 is reasonable -drawVertMesh_t *SubdivideMapPatch( const mapPatch_t *patch, float maxError ); -#endif // __cplusplus - -//========================================= - -#ifdef __cplusplus - extern "C" { -#endif - -void QDECL Com_Error( int level, const char *error, ... ); -void QDECL Com_Printf( const char *msg, ... ); -void QDECL Com_DPrintf( const char *msg, ... ); - -#ifdef __cplusplus - } -#endif - - -typedef struct { - qboolean frameMemory; - int currentElements; - int maxElements; // will reallocate and move when exceeded - void **elements; -} growList_t; - -// you don't need to init the growlist if you don't mind it growing and moving -// the list as it expands -void Com_InitGrowList( growList_t *list, int maxElements ); -int Com_AddToGrowList( growList_t *list, void *data ); -void *Com_GrowListElement( const growList_t *list, int index ); -int Com_IndexForGrowListElement( const growList_t *list, const void *element ); - - -// -// key / value info strings -// -char *Info_ValueForKey( const char *s, const char *key ); -void Info_RemoveKey( char *s, const char *key ); -void Info_SetValueForKey( char *s, const char *key, const char *value ); -qboolean Info_Validate( const char *s ); -void Info_NextPair( const char *(*s), char key[MAX_INFO_KEY], char value[MAX_INFO_VALUE] ); - -// get cvar defs, collision defs, etc -//#include "../shared/interface.h" - -// get key code numbers for events -//#include "../shared/keycodes.h" - -#ifdef __cplusplus -// get the polygon winding functions -//#include "../shared/windings.h" - -// get the flags class -//#include "../shared/idflags.h" -#endif // __cplusplus - -#endif // __Q_SHARED_H - diff --git a/code/splines/splines.cpp b/code/splines/splines.cpp deleted file mode 100644 index 9bcef08..0000000 --- a/code/splines/splines.cpp +++ /dev/null @@ -1,1250 +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 Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ - -//#include "stdafx.h" -//#include "qe3.h" - -#include "q_shared.hpp" -#include "splines.h" - -extern "C" { -int FS_Write( const void *buffer, int len, fileHandle_t h ); -int FS_ReadFile( const char *qpath, void **buffer ); -void FS_FreeFile( void *buffer ); -fileHandle_t FS_FOpenFileWrite( const char *filename ); -void FS_FCloseFile( fileHandle_t f ); -} - -float Q_fabs( float f ) { - int tmp = * ( int * ) &f; - tmp &= 0x7FFFFFFF; - return * ( float * ) &tmp; -} - - -//#include "../shared/windings.h" -//#include "../qcommon/qcommon.h" -//#include "../sys/sys_public.h" -//#include "../game/game_entity.h" - -idCameraDef splineList; -idCameraDef *g_splineList = &splineList; - -idVec3_t idSplineList::zero(0,0,0); -/* -void glLabeledPoint(idVec3_t &color, idVec3_t &point, float size, const char *label) { - qglColor3fv(color); - qglPointSize(size); - qglBegin(GL_POINTS); - qglVertex3fv(point); - qglEnd(); - idVec3_t v = point; - v.x += 1; - v.y += 1; - v.z += 1; - qglRasterPos3fv (v); - qglCallLists (strlen(label), GL_UNSIGNED_BYTE, label); -} - - -void glBox(idVec3_t &color, idVec3_t &point, float size) { - idVec3_t mins(point); - idVec3_t maxs(point); - mins[0] -= size; - mins[1] += size; - mins[2] -= size; - maxs[0] += size; - maxs[1] -= size; - maxs[2] += size; - qglColor3fv(color); - qglBegin(GL_LINE_LOOP); - qglVertex3f(mins[0],mins[1],mins[2]); - qglVertex3f(maxs[0],mins[1],mins[2]); - qglVertex3f(maxs[0],maxs[1],mins[2]); - qglVertex3f(mins[0],maxs[1],mins[2]); - qglEnd(); - qglBegin(GL_LINE_LOOP); - qglVertex3f(mins[0],mins[1],maxs[2]); - qglVertex3f(maxs[0],mins[1],maxs[2]); - qglVertex3f(maxs[0],maxs[1],maxs[2]); - qglVertex3f(mins[0],maxs[1],maxs[2]); - qglEnd(); - - qglBegin(GL_LINES); - qglVertex3f(mins[0],mins[1],mins[2]); - qglVertex3f(mins[0],mins[1],maxs[2]); - qglVertex3f(mins[0],maxs[1],maxs[2]); - qglVertex3f(mins[0],maxs[1],mins[2]); - qglVertex3f(maxs[0],mins[1],mins[2]); - qglVertex3f(maxs[0],mins[1],maxs[2]); - qglVertex3f(maxs[0],maxs[1],maxs[2]); - qglVertex3f(maxs[0],maxs[1],mins[2]); - qglEnd(); - -} - -void splineTest() { - //g_splineList->load("p:/doom/base/maps/test_base1.camera"); -} - -void splineDraw() { - //g_splineList->addToRenderer(); -} - - -//extern void D_DebugLine( const idVec3_t &color, const idVec3_t &start, const idVec3_t &end ); - -void debugLine(idVec3_t &color, float x, float y, float z, float x2, float y2, float z2) { - //idVec3_t from(x, y, z); - //idVec3_t to(x2, y2, z2); - //D_DebugLine(color, from, to); -} - - -void idSplineList::addToRenderer() { - - if (controlPoints.Num() == 0) { - return; - } - - idVec3_t mins, maxs; - idVec3_t yellow(1.0, 1.0, 0); - idVec3_t white(1.0, 1.0, 1.0); - int i; - - for(i = 0; i < controlPoints.Num(); i++) { - VectorCopy(*controlPoints[i], mins); - VectorCopy(mins, maxs); - mins[0] -= 8; - mins[1] += 8; - mins[2] -= 8; - maxs[0] += 8; - maxs[1] -= 8; - maxs[2] += 8; - debugLine( yellow, mins[0], mins[1], mins[2], maxs[0], mins[1], mins[2]); - debugLine( yellow, maxs[0], mins[1], mins[2], maxs[0], maxs[1], mins[2]); - debugLine( yellow, maxs[0], maxs[1], mins[2], mins[0], maxs[1], mins[2]); - debugLine( yellow, mins[0], maxs[1], mins[2], mins[0], mins[1], mins[2]); - - debugLine( yellow, mins[0], mins[1], maxs[2], maxs[0], mins[1], maxs[2]); - debugLine( yellow, maxs[0], mins[1], maxs[2], maxs[0], maxs[1], maxs[2]); - debugLine( yellow, maxs[0], maxs[1], maxs[2], mins[0], maxs[1], maxs[2]); - debugLine( yellow, mins[0], maxs[1], maxs[2], mins[0], mins[1], maxs[2]); - - } - - int step = 0; - idVec3_t step1; - for(i = 3; i < controlPoints.Num(); i++) { - for (float tension = 0.0f; tension < 1.001f; tension += 0.1f) { - float x = 0; - float y = 0; - float z = 0; - for (int j = 0; j < 4; j++) { - x += controlPoints[i - (3 - j)]->x * calcSpline(j, tension); - y += controlPoints[i - (3 - j)]->y * calcSpline(j, tension); - z += controlPoints[i - (3 - j)]->z * calcSpline(j, tension); - } - if (step == 0) { - step1[0] = x; - step1[1] = y; - step1[2] = z; - step = 1; - } else { - debugLine( white, step1[0], step1[1], step1[2], x, y, z); - step = 0; - } - - } - } -} -*/ - -void idSplineList::buildSpline() { - //int start = Sys_Milliseconds(); - clearSpline(); - for(int i = 3; i < controlPoints.Num(); i++) { - for (float tension = 0.0f; tension < 1.001f; tension += granularity) { - float x = 0; - float y = 0; - float z = 0; - for (int j = 0; j < 4; j++) { - x += controlPoints[i - (3 - j)]->x * calcSpline(j, tension); - y += controlPoints[i - (3 - j)]->y * calcSpline(j, tension); - z += controlPoints[i - (3 - j)]->z * calcSpline(j, tension); - } - splinePoints.Append(new idVec3_t(x, y, z)); - } - } - dirty = false; - //Com_Printf("Spline build took %f seconds\n", (float)(Sys_Milliseconds() - start) / 1000); -} - -/* -void idSplineList::draw(bool editMode) { - int i; - vec4_t yellow(1, 1, 0, 1); - - if (controlPoints.Num() == 0) { - return; - } - - if (dirty) { - buildSpline(); - } - - - qglColor3fv(controlColor); - qglPointSize(5); - - qglBegin(GL_POINTS); - for (i = 0; i < controlPoints.Num(); i++) { - qglVertex3fv(*controlPoints[i]); - } - qglEnd(); - - if (editMode) { - for(i = 0; i < controlPoints.Num(); i++) { - glBox(activeColor, *controlPoints[i], 4); - } - } - - //Draw the curve - qglColor3fv(pathColor); - qglBegin(GL_LINE_STRIP); - int count = splinePoints.Num(); - for (i = 0; i < count; i++) { - qglVertex3fv(*splinePoints[i]); - } - qglEnd(); - - if (editMode) { - qglColor3fv(segmentColor); - qglPointSize(3); - qglBegin(GL_POINTS); - for (i = 0; i < count; i++) { - qglVertex3fv(*splinePoints[i]); - } - qglEnd(); - } - if (count > 0) { - //assert(activeSegment >=0 && activeSegment < count); - if (activeSegment >=0 && activeSegment < count) { - glBox(activeColor, *splinePoints[activeSegment], 6); - glBox(yellow, *splinePoints[activeSegment], 8); - } - } - -} -*/ - -float idSplineList::totalDistance() { - - if (controlPoints.Num() == 0) { - return 0.0; - } - - if (dirty) { - buildSpline(); - } - - float dist = 0.0; - idVec3_t temp; - int count = splinePoints.Num(); - for(int i = 1; i < count; i++) { - temp = *splinePoints[i-1]; - temp -= *splinePoints[i]; - dist += temp.Length(); - } - return dist; -} - -void idSplineList::initPosition(long bt, long totalTime) { - - if (dirty) { - buildSpline(); - } - - if (splinePoints.Num() == 0) { - return; - } - - baseTime = bt; - time = totalTime; - - // calc distance to travel ( this will soon be broken into time segments ) - splineTime.Clear(); - splineTime.Append(bt); - double dist = totalDistance(); - double distSoFar = 0.0; - idVec3_t temp; - int count = splinePoints.Num(); - //for(int i = 2; i < count - 1; i++) { - for(int i = 1; i < count; i++) { - temp = *splinePoints[i-1]; - temp -= *splinePoints[i]; - distSoFar += temp.Length(); - double percent = distSoFar / dist; - percent *= totalTime; - splineTime.Append(percent + bt); - } - assert(splineTime.Num() == splinePoints.Num()); - activeSegment = 0; -} - - - -float idSplineList::calcSpline(int step, float tension) { - switch(step) { - case 0: return (pow(1 - tension, 3)) / 6; - case 1: return (3 * pow(tension, 3) - 6 * pow(tension, 2) + 4) / 6; - case 2: return (-3 * pow(tension, 3) + 3 * pow(tension, 2) + 3 * tension + 1) / 6; - case 3: return pow(tension, 3) / 6; - } - return 0.0; -} - - - -void idSplineList::updateSelection(const idVec3_t &move) { - if (selected) { - dirty = true; - VectorAdd(*selected, move, *selected); - } -} - - -void idSplineList::setSelectedPoint(idVec3_t *p) { - if (p) { - p->Snap(); - for(int i = 0; i < controlPoints.Num(); i++) { - if (*p == *controlPoints[i]) { - selected = controlPoints[i]; - } - } - } else { - selected = NULL; - } -} - -const idVec3_t *idSplineList::getPosition(long t) { - static idVec3_t interpolatedPos; - //static long lastTime = -1; - - int count = splineTime.Num(); - if (count == 0) { - return &zero; - } - - Com_Printf("Time: %d\n", t); - assert(splineTime.Num() == splinePoints.Num()); - - while (activeSegment < count) { - if (splineTime[activeSegment] >= t) { - if (activeSegment > 0 && activeSegment < count - 1) { - double timeHi = splineTime[activeSegment + 1]; - double timeLo = splineTime[activeSegment - 1]; - double percent = (timeHi - t) / (timeHi - timeLo); - // pick two bounding points - idVec3_t v1 = *splinePoints[activeSegment-1]; - idVec3_t v2 = *splinePoints[activeSegment+1]; - v2 *= (1.0 - percent); - v1 *= percent; - v2 += v1; - interpolatedPos = v2; - return &interpolatedPos; - } - return splinePoints[activeSegment]; - } else { - activeSegment++; - } - } - return splinePoints[count-1]; -} - -void idSplineList::parse(const char *(*text) ) { - const char *token; - //Com_MatchToken( text, "{" ); - do { - token = Com_Parse( text ); - - if ( !token[0] ) { - break; - } - if ( !Q_stricmp (token, "}") ) { - break; - } - - do { - // if token is not a brace, it is a key for a key/value pair - if ( !token[0] || !Q_stricmp (token, "(") || !Q_stricmp(token, "}")) { - break; - } - - Com_UngetToken(); - idStr key = Com_ParseOnLine(text); - const char *token = Com_Parse(text); - if (Q_stricmp(key.c_str(), "granularity") == 0) { - granularity = atof(token); - } else if (Q_stricmp(key.c_str(), "name") == 0) { - name = token; - } - token = Com_Parse(text); - - } while (1); - - if ( !Q_stricmp (token, "}") ) { - break; - } - - Com_UngetToken(); - // read the control point - idVec3_t point; - Com_Parse1DMatrix( text, 3, point ); - addPoint(point.x, point.y, point.z); - } while (1); - - //Com_UngetToken(); - //Com_MatchToken( text, "}" ); - dirty = true; -} - -void idSplineList::write(fileHandle_t file, const char *p) { - idStr s = va("\t\t%s {\n", p); - FS_Write(s.c_str(), s.length(), file); - //s = va("\t\tname %s\n", name.c_str()); - //FS_Write(s.c_str(), s.length(), file); - s = va("\t\t\tgranularity %f\n", granularity); - FS_Write(s.c_str(), s.length(), file); - int count = controlPoints.Num(); - for (int i = 0; i < count; i++) { - s = va("\t\t\t( %f %f %f )\n", controlPoints[i]->x, controlPoints[i]->y, controlPoints[i]->z); - FS_Write(s.c_str(), s.length(), file); - } - s = "\t\t}\n"; - FS_Write(s.c_str(), s.length(), file); -} - - -void idCameraDef::getActiveSegmentInfo(int segment, idVec3_t &origin, idVec3_t &direction, float *fov) { -#if 0 - if (!cameraSpline.validTime()) { - buildCamera(); - } - double d = (double)segment / numSegments(); - getCameraInfo(d * totalTime * 1000, origin, direction, fov); -#endif -/* - if (!cameraSpline.validTime()) { - buildCamera(); - } - origin = *cameraSpline.getSegmentPoint(segment); - - - idVec3_t temp; - - int numTargets = getTargetSpline()->controlPoints.Num(); - int count = cameraSpline.splineTime.Num(); - if (numTargets == 0) { - // follow the path - if (cameraSpline.getActiveSegment() < count - 1) { - temp = *cameraSpline.splinePoints[cameraSpline.getActiveSegment()+1]; - } - } else if (numTargets == 1) { - temp = *getTargetSpline()->controlPoints[0]; - } else { - temp = *getTargetSpline()->getSegmentPoint(segment); - } - - temp -= origin; - temp.Normalize(); - direction = temp; -*/ -} - -bool idCameraDef::getCameraInfo(long time, idVec3_t &origin, idVec3_t &direction, float *fv) { - - - if ((time - startTime) / 1000 > totalTime) { - return false; - } - - - for (int i = 0; i < events.Num(); i++) { - if (time >= startTime + events[i]->getTime() && !events[i]->getTriggered()) { - events[i]->setTriggered(true); - if (events[i]->getType() == idCameraEvent::EVENT_TARGET) { - setActiveTargetByName(events[i]->getParam()); - getActiveTarget()->start(startTime + events[i]->getTime()); - //Com_Printf("Triggered event switch to target: %s\n",events[i]->getParam()); - } else if (events[i]->getType() == idCameraEvent::EVENT_TRIGGER) { - //idEntity *ent = NULL; - //ent = level.FindTarget( ent, events[i]->getParam()); - //if (ent) { - // ent->signal( SIG_TRIGGER ); - // ent->ProcessEvent( &EV_Activate, world ); - //} - } else if (events[i]->getType() == idCameraEvent::EVENT_FOV) { - //*fv = fov = atof(events[i]->getParam()); - } else if (events[i]->getType() == idCameraEvent::EVENT_STOP) { - return false; - } - } - } - - origin = *cameraPosition->getPosition(time); - - *fv = fov.getFOV(time); - - idVec3_t temp = origin; - - int numTargets = targetPositions.Num(); - if (numTargets == 0) { -/* - // follow the path - if (cameraSpline.getActiveSegment() < count - 1) { - temp = *cameraSpline.splinePoints[cameraSpline.getActiveSegment()+1]; - if (temp == origin) { - int index = cameraSpline.getActiveSegment() + 2; - while (temp == origin && index < count - 1) { - temp = *cameraSpline.splinePoints[index++]; - } - } - } -*/ - } else { - temp = *getActiveTarget()->getPosition(time); - } - - temp -= origin; - temp.Normalize(); - direction = temp; - - return true; -} - -bool idCameraDef::waitEvent(int index) { - //for (int i = 0; i < events.Num(); i++) { - // if (events[i]->getSegment() == index && events[i]->getType() == idCameraEvent::EVENT_WAIT) { - // return true; - // } - //} - return false; -} - - -#define NUM_CCELERATION_SEGS 10 -#define CELL_AMT 5 - -void idCameraDef::buildCamera() { - int i; - //int lastSwitch = 0; - idList waits; - idList targets; - - totalTime = baseTime; - cameraPosition->setTime(totalTime * 1000); - // we have a base time layout for the path and the target path - // now we need to layer on any wait or speed changes - for (i = 0; i < events.Num(); i++) { - //idCameraEvent *ev = events[i]; - events[i]->setTriggered(false); - switch (events[i]->getType()) { - case idCameraEvent::EVENT_TARGET : { - targets.Append(i); - break; - } - case idCameraEvent::EVENT_WAIT : { - waits.Append(atof(events[i]->getParam())); - cameraPosition->addVelocity(events[i]->getTime(), atof(events[i]->getParam()) * 1000, 0); - break; - } - case idCameraEvent::EVENT_TARGETWAIT : { - //targetWaits.Append(i); - break; - } - case idCameraEvent::EVENT_SPEED : { -/* - // take the average delay between up to the next five segments - float adjust = atof(events[i]->getParam()); - int index = events[i]->getSegment(); - total = 0; - count = 0; - - // get total amount of time over the remainder of the segment - for (j = index; j < cameraSpline.numSegments() - 1; j++) { - total += cameraSpline.getSegmentTime(j + 1) - cameraSpline.getSegmentTime(j); - count++; - } - - // multiply that by the adjustment - double newTotal = total * adjust; - // what is the difference.. - newTotal -= total; - totalTime += newTotal / 1000; - - // per segment difference - newTotal /= count; - int additive = newTotal; - - // now propogate that difference out to each segment - for (j = index; j < cameraSpline.numSegments(); j++) { - cameraSpline.addSegmentTime(j, additive); - additive += newTotal; - } - break; -*/ - } - default: break; // FIXME: what about other idCameraEvent? - } - } - - - for (i = 0; i < waits.Num(); i++) { - totalTime += waits[i]; - } - - // on a new target switch, we need to take time to this point ( since last target switch ) - // and allocate it across the active target, then reset time to this point - long timeSoFar = 0; - long total = (int)(totalTime * 1000); - for (i = 0; i < targets.Num(); i++) { - long t; - if (i < targets.Num() - 1) { - t = events[targets[i+1]]->getTime(); - } else { - t = total - timeSoFar; - } - // t is how much time to use for this target - setActiveTargetByName(events[targets[i]]->getParam()); - getActiveTarget()->setTime(t); - timeSoFar += t; - } - - -} - -void idCameraDef::startCamera(long t) { - buildCamera(); - cameraPosition->start(t); - //for (int i = 0; i < targetPositions.Num(); i++) { - // targetPositions[i]-> - //} - startTime = t; - cameraRunning = true; -} - - -void idCameraDef::parse(const char *(*text) ) { - - const char *token; - do { - token = Com_Parse( text ); - - if ( !token[0] ) { - break; - } - if ( !Q_stricmp (token, "}") ) { - break; - } - - if (Q_stricmp(token, "time") == 0) { - baseTime = Com_ParseFloat(text); - } - - if (Q_stricmp(token, "camera_fixed") == 0) { - cameraPosition = new idFixedPosition(); - cameraPosition->parse(text); - } - - if (Q_stricmp(token, "camera_interpolated") == 0) { - cameraPosition = new idInterpolatedPosition(); - cameraPosition->parse(text); - } - - if (Q_stricmp(token, "camera_spline") == 0) { - cameraPosition = new idSplinePosition(); - cameraPosition->parse(text); - } - - if (Q_stricmp(token, "target_fixed") == 0) { - idFixedPosition *pos = new idFixedPosition(); - pos->parse(text); - targetPositions.Append(pos); - } - - if (Q_stricmp(token, "target_interpolated") == 0) { - idInterpolatedPosition *pos = new idInterpolatedPosition(); - pos->parse(text); - targetPositions.Append(pos); - } - - if (Q_stricmp(token, "target_spline") == 0) { - idSplinePosition *pos = new idSplinePosition(); - pos->parse(text); - targetPositions.Append(pos); - } - - if (Q_stricmp(token, "fov") == 0) { - fov.parse(text); - } - - if (Q_stricmp(token, "event") == 0) { - idCameraEvent *event = new idCameraEvent(); - event->parse(text); - addEvent(event); - } - - - } while (1); - - Com_UngetToken(); - Com_MatchToken( text, "}" ); - -} - -qboolean idCameraDef::load(const char *filename) { - char *buf; - const char *buf_p; - //int length = - FS_ReadFile( filename, (void **)&buf ); - if ( !buf ) { - return qfalse; - } - - clear(); - Com_BeginParseSession( filename ); - buf_p = buf; - parse(&buf_p); - Com_EndParseSession(); - FS_FreeFile( buf ); - - return qtrue; -} - -void idCameraDef::save(const char *filename) { - fileHandle_t file = FS_FOpenFileWrite(filename); - if (file) { - int i; - idStr s = "cameraPathDef { \n"; - FS_Write(s.c_str(), s.length(), file); - s = va("\ttime %f\n", baseTime); - FS_Write(s.c_str(), s.length(), file); - - cameraPosition->write(file, va("camera_%s",cameraPosition->typeStr())); - - for (i = 0; i < numTargets(); i++) { - targetPositions[i]->write(file, va("target_%s", targetPositions[i]->typeStr())); - } - - for (i = 0; i < events.Num(); i++) { - events[i]->write(file, "event"); - } - - fov.write(file, "fov"); - - s = "}\n"; - FS_Write(s.c_str(), s.length(), file); - } - FS_FCloseFile(file); -} - -int idCameraDef::sortEvents(const void *p1, const void *p2) { - idCameraEvent *ev1 = (idCameraEvent*)(p1); - idCameraEvent *ev2 = (idCameraEvent*)(p2); - - if (ev1->getTime() > ev2->getTime()) { - return -1; - } - if (ev1->getTime() < ev2->getTime()) { - return 1; - } - return 0; -} - -void idCameraDef::addEvent(idCameraEvent *event) { - events.Append(event); - //events.Sort(&sortEvents); - -} -void idCameraDef::addEvent(idCameraEvent::eventType t, const char *param, long time) { - addEvent(new idCameraEvent(t, param, time)); - buildCamera(); -} - - -const char *idCameraEvent::eventStr[] = { - "NA", - "WAIT", - "TARGETWAIT", - "SPEED", - "TARGET", - "SNAPTARGET", - "FOV", - "SCRIPT", - "TRIGGER", - "STOP" -}; - -void idCameraEvent::parse(const char *(*text) ) { - const char *token; - Com_MatchToken( text, "{" ); - do { - token = Com_Parse( text ); - - if ( !token[0] ) { - break; - } - if ( !strcmp (token, "}") ) { - break; - } - - // here we may have to jump over brush epairs ( only used in editor ) - do { - // if token is not a brace, it is a key for a key/value pair - if ( !token[0] || !strcmp (token, "(") || !strcmp(token, "}")) { - break; - } - - Com_UngetToken(); - idStr key = Com_ParseOnLine(text); - const char *token = Com_Parse(text); - if (Q_stricmp(key.c_str(), "type") == 0) { - type = static_cast(atoi(token)); - } else if (Q_stricmp(key.c_str(), "param") == 0) { - paramStr = token; - } else if (Q_stricmp(key.c_str(), "time") == 0) { - time = atoi(token); - } - token = Com_Parse(text); - - } while (1); - - if ( !strcmp (token, "}") ) { - break; - } - - } while (1); - - Com_UngetToken(); - Com_MatchToken( text, "}" ); -} - -void idCameraEvent::write(fileHandle_t file, const char *name) { - idStr s = va("\t%s {\n", name); - FS_Write(s.c_str(), s.length(), file); - s = va("\t\ttype %d\n", static_cast(type)); - FS_Write(s.c_str(), s.length(), file); - s = va("\t\tparam %s\n", paramStr.c_str()); - FS_Write(s.c_str(), s.length(), file); - s = va("\t\ttime %d\n", time); - FS_Write(s.c_str(), s.length(), file); - s = "\t}\n"; - FS_Write(s.c_str(), s.length(), file); -} - - -const char *idCameraPosition::positionStr[] = { - "Fixed", - "Interpolated", - "Spline", -}; - - - -const idVec3_t *idInterpolatedPosition::getPosition(long t) { - static idVec3_t interpolatedPos; - - float velocity = getVelocity(t); - float timePassed = t - lastTime; - lastTime = t; - - // convert to seconds - timePassed /= 1000; - - float distToTravel = timePassed *= velocity; - - idVec3_t temp = startPos; - temp -= endPos; - float distance = temp.Length(); - - distSoFar += distToTravel; - float percent = (float)(distSoFar) / distance; - - if (percent > 1.0) { - percent = 1.0; - } else if (percent < 0.0) { - percent = 0.0; - } - - // the following line does a straigt calc on percentage of time - // float percent = (float)(startTime + time - t) / time; - - idVec3_t v1 = startPos; - idVec3_t v2 = endPos; - v1 *= (1.0 - percent); - v2 *= percent; - v1 += v2; - interpolatedPos = v1; - return &interpolatedPos; -} - - -void idCameraFOV::parse(const char *(*text) ) { - const char *token; - Com_MatchToken( text, "{" ); - do { - token = Com_Parse( text ); - - if ( !token[0] ) { - break; - } - if ( !strcmp (token, "}") ) { - break; - } - - // here we may have to jump over brush epairs ( only used in editor ) - do { - // if token is not a brace, it is a key for a key/value pair - if ( !token[0] || !strcmp (token, "(") || !strcmp(token, "}")) { - break; - } - - Com_UngetToken(); - idStr key = Com_ParseOnLine(text); - const char *token = Com_Parse(text); - if (Q_stricmp(key.c_str(), "fov") == 0) { - fov = atof(token); - } else if (Q_stricmp(key.c_str(), "startFOV") == 0) { - startFOV = atof(token); - } else if (Q_stricmp(key.c_str(), "endFOV") == 0) { - endFOV = atof(token); - } else if (Q_stricmp(key.c_str(), "time") == 0) { - time = atoi(token); - } - token = Com_Parse(text); - - } while (1); - - if ( !strcmp (token, "}") ) { - break; - } - - } while (1); - - Com_UngetToken(); - Com_MatchToken( text, "}" ); -} - -bool idCameraPosition::parseToken(const char *key, const char *(*text)) { - const char *token = Com_Parse(text); - if (Q_stricmp(key, "time") == 0) { - time = atol(token); - return true; - } else if (Q_stricmp(key, "type") == 0) { - type = static_cast(atoi(token)); - return true; - } else if (Q_stricmp(key, "velocity") == 0) { - long t = atol(token); - token = Com_Parse(text); - long d = atol(token); - token = Com_Parse(text); - float s = atof(token); - addVelocity(t, d, s); - return true; - } else if (Q_stricmp(key, "baseVelocity") == 0) { - baseVelocity = atof(token); - return true; - } else if (Q_stricmp(key, "name") == 0) { - name = token; - return true; - } else if (Q_stricmp(key, "time") == 0) { - time = atoi(token); - return true; - } - Com_UngetToken(); - return false; -} - - - -void idFixedPosition::parse(const char *(*text) ) { - const char *token; - Com_MatchToken( text, "{" ); - do { - token = Com_Parse( text ); - - if ( !token[0] ) { - break; - } - if ( !strcmp (token, "}") ) { - break; - } - - // here we may have to jump over brush epairs ( only used in editor ) - do { - // if token is not a brace, it is a key for a key/value pair - if ( !token[0] || !strcmp (token, "(") || !strcmp(token, "}")) { - break; - } - - Com_UngetToken(); - idStr key = Com_ParseOnLine(text); - - const char *token = Com_Parse(text); - if (Q_stricmp(key.c_str(), "pos") == 0) { - Com_UngetToken(); - Com_Parse1DMatrix( text, 3, pos ); - } else { - Com_UngetToken(); - idCameraPosition::parseToken(key.c_str(), text); - } - token = Com_Parse(text); - - } while (1); - - if ( !strcmp (token, "}") ) { - break; - } - - } while (1); - - Com_UngetToken(); - Com_MatchToken( text, "}" ); -} - -void idInterpolatedPosition::parse(const char *(*text) ) { - const char *token; - Com_MatchToken( text, "{" ); - do { - token = Com_Parse( text ); - - if ( !token[0] ) { - break; - } - if ( !strcmp (token, "}") ) { - break; - } - - // here we may have to jump over brush epairs ( only used in editor ) - do { - // if token is not a brace, it is a key for a key/value pair - if ( !token[0] || !strcmp (token, "(") || !strcmp(token, "}")) { - break; - } - - Com_UngetToken(); - idStr key = Com_ParseOnLine(text); - - const char *token = Com_Parse(text); - if (Q_stricmp(key.c_str(), "startPos") == 0) { - Com_UngetToken(); - Com_Parse1DMatrix( text, 3, startPos ); - } else if (Q_stricmp(key.c_str(), "endPos") == 0) { - Com_UngetToken(); - Com_Parse1DMatrix( text, 3, endPos ); - } else { - Com_UngetToken(); - idCameraPosition::parseToken(key.c_str(), text); - } - token = Com_Parse(text); - - } while (1); - - if ( !strcmp (token, "}") ) { - break; - } - - } while (1); - - Com_UngetToken(); - Com_MatchToken( text, "}" ); -} - - -void idSplinePosition::parse(const char *(*text) ) { - const char *token; - Com_MatchToken( text, "{" ); - do { - token = Com_Parse( text ); - - if ( !token[0] ) { - break; - } - if ( !strcmp (token, "}") ) { - break; - } - - // here we may have to jump over brush epairs ( only used in editor ) - do { - // if token is not a brace, it is a key for a key/value pair - if ( !token[0] || !strcmp (token, "(") || !strcmp(token, "}")) { - break; - } - - Com_UngetToken(); - idStr key = Com_ParseOnLine(text); - - const char *token = Com_Parse(text); - if (Q_stricmp(key.c_str(), "target") == 0) { - target.parse(text); - } else { - Com_UngetToken(); - idCameraPosition::parseToken(key.c_str(), text); - } - token = Com_Parse(text); - - } while (1); - - if ( !strcmp (token, "}") ) { - break; - } - - } while (1); - - Com_UngetToken(); - Com_MatchToken( text, "}" ); -} - - - -void idCameraFOV::write(fileHandle_t file, const char *p) { - idStr s = va("\t%s {\n", p); - FS_Write(s.c_str(), s.length(), file); - - s = va("\t\tfov %f\n", fov); - FS_Write(s.c_str(), s.length(), file); - - s = va("\t\tstartFOV %f\n", startFOV); - FS_Write(s.c_str(), s.length(), file); - - s = va("\t\tendFOV %f\n", endFOV); - FS_Write(s.c_str(), s.length(), file); - - s = va("\t\ttime %i\n", time); - FS_Write(s.c_str(), s.length(), file); - - s = "\t}\n"; - FS_Write(s.c_str(), s.length(), file); -} - - -void idCameraPosition::write(fileHandle_t file, const char *p) { - - idStr s = va("\t\ttime %i\n", time); - FS_Write(s.c_str(), s.length(), file); - - s = va("\t\ttype %i\n", static_cast(type)); - FS_Write(s.c_str(), s.length(), file); - - s = va("\t\tname %s\n", name.c_str()); - FS_Write(s.c_str(), s.length(), file); - - s = va("\t\tbaseVelocity %f\n", baseVelocity); - FS_Write(s.c_str(), s.length(), file); - - for (int i = 0; i < velocities.Num(); i++) { - s = va("\t\tvelocity %i %i %f\n", velocities[i]->startTime, velocities[i]->time, velocities[i]->speed); - FS_Write(s.c_str(), s.length(), file); - } - -} - -void idFixedPosition::write(fileHandle_t file, const char *p) { - idStr s = va("\t%s {\n", p); - FS_Write(s.c_str(), s.length(), file); - idCameraPosition::write(file, p); - s = va("\t\tpos ( %f %f %f )\n", pos.x, pos.y, pos.z); - FS_Write(s.c_str(), s.length(), file); - s = "\t}\n"; - FS_Write(s.c_str(), s.length(), file); -} - -void idInterpolatedPosition::write(fileHandle_t file, const char *p) { - idStr s = va("\t%s {\n", p); - FS_Write(s.c_str(), s.length(), file); - idCameraPosition::write(file, p); - s = va("\t\tstartPos ( %f %f %f )\n", startPos.x, startPos.y, startPos.z); - FS_Write(s.c_str(), s.length(), file); - s = va("\t\tendPos ( %f %f %f )\n", endPos.x, endPos.y, endPos.z); - FS_Write(s.c_str(), s.length(), file); - s = "\t}\n"; - FS_Write(s.c_str(), s.length(), file); -} - -void idSplinePosition::write(fileHandle_t file, const char *p) { - idStr s = va("\t%s {\n", p); - FS_Write(s.c_str(), s.length(), file); - idCameraPosition::write(file, p); - target.write(file, "target"); - s = "\t}\n"; - FS_Write(s.c_str(), s.length(), file); -} - -void idCameraDef::addTarget(const char *name, idCameraPosition::positionType type) { - //const char *text = (name == NULL) ? va("target0%d", numTargets()+1) : name; // TTimo: unused - idCameraPosition *pos = newFromType(type); - if (pos) { - pos->setName(name); - targetPositions.Append(pos); - activeTarget = numTargets()-1; - if (activeTarget == 0) { - // first one - addEvent(idCameraEvent::EVENT_TARGET, name, 0); - } - } -} - - - -idCameraDef camera; - -extern "C" { -qboolean loadCamera(const char *name) { - camera.clear(); - return static_cast(camera.load(name)); -} - -qboolean getCameraInfo(int time, float *origin, float*angles) { - idVec3_t dir, org; - org[0] = origin[0]; - org[1] = origin[1]; - org[2] = origin[2]; - float fov = 90; - if (camera.getCameraInfo(time, org, dir, &fov)) { - origin[0] = org[0]; - origin[1] = org[1]; - origin[2] = org[2]; - angles[1] = atan2 (dir[1], dir[0])*180/3.14159; - angles[0] = asin (dir[2])*180/3.14159; - return qtrue; - } - return qfalse; -} - -void startCamera(int time) { - camera.startCamera(time); -} - -} - - diff --git a/code/splines/splines.h b/code/splines/splines.h deleted file mode 100644 index ad2ace5..0000000 --- a/code/splines/splines.h +++ /dev/null @@ -1,1075 +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 __SPLINES_H -#define __SPLINES_H - -extern "C" { -#ifdef Q3RADIANT -#include "../qgl.h" -#else -//#include "../renderer/qgl.h" -#endif -} -#include "util_list.h" -#include "util_str.h" -#include "math_vector.h" - -typedef int fileHandle_t; - -//extern void glBox(idVec3_t &color, idVec3_t &point, float size); -//extern void glLabeledPoint(idVec3_t &color, idVec3_t &point, float size, const char *label); - -static vec4_t blue(0, 0, 1, 1); -static vec4_t red(1, 0, 0, 1); - -class idPointListInterface { -public: - idPointListInterface() { - selectedPoints.Clear(); - } - virtual ~idPointListInterface() {} - - virtual int numPoints() { - return 0; - } - - virtual void addPoint(const float x, const float y, const float z) {} - virtual void addPoint(const idVec3_t &v) {} - virtual void removePoint(int index) {} - virtual idVec3_t *getPoint(int index) { return NULL; } - - int selectPointByRay(float ox, float oy, float oz, float dx, float dy, float dz, bool single) { - idVec3_t origin(ox, oy, oz); - idVec3_t dir(dx, dy, dz); - return selectPointByRay(origin, dir, single); - } - - int selectPointByRay(const idVec3_t origin, const idVec3_t direction, bool single) { - int i, besti, count; - float d, bestd; - idVec3_t temp, temp2; - - // find the point closest to the ray - besti = -1; - bestd = 8; - count = numPoints(); - - for (i=0; i < count; i++) { - temp = *getPoint(i); - temp2 = temp; - temp -= origin; - d = DotProduct(temp, direction); - __VectorMA (origin, d, direction, temp); - temp2 -= temp; - d = temp2.Length(); - if (d <= bestd) { - bestd = d; - besti = i; - } - } - - if (besti >= 0) { - selectPoint(besti, single); - } - - return besti; - } - - int isPointSelected(int index) { - int count = selectedPoints.Num(); - for (int i = 0; i < count; i++) { - if (selectedPoints[i] == index) { - return i; - } - } - return -1; - } - - int selectPoint(int index, bool single) { - if (index >= 0 && index < numPoints()) { - if (single) { - deselectAll(); - } else { - if (isPointSelected(index) >= 0) { - selectedPoints.Remove(index); - } - } - return selectedPoints.Append(index); - } - return -1; - } - - void selectAll() { - selectedPoints.Clear(); - for (int i = 0; i < numPoints(); i++) { - selectedPoints.Append(i); - } - } - - void deselectAll() { - selectedPoints.Clear(); - } - - virtual void updateSelection(float x, float y, float z) { - idVec3_t move(x, y, z); - updateSelection(move); - } - - virtual void updateSelection(const idVec3_t &move) { - int count = selectedPoints.Num(); - for (int i = 0; i < count; i++) { - *getPoint(selectedPoints[i]) += move; - } - } -/* - void drawSelection() { - int count = selectedPoints.Num(); - for (int i = 0; i < count; i++) { - glBox(red, *getPoint(selectedPoints[i]), 4); - } - } -*/ -protected: - idList selectedPoints; - -}; - - -class idSplineList { - -public: - - idSplineList() { - clear(); - } - - idSplineList(const char *p) { - clear(); - name = p; - }; - - ~idSplineList() { - clear(); - }; - - void clearControl() { - for (int i = 0; i < controlPoints.Num(); i++) { - delete controlPoints[i]; - } - controlPoints.Clear(); - } - - void clearSpline() { - for (int i = 0; i < splinePoints.Num(); i++) { - delete splinePoints[i]; - } - splinePoints.Clear(); - } - - void parse(const char *(*text)); - void write(fileHandle_t file, const char *name); - - void clear() { - clearControl(); - clearSpline(); - splineTime.Clear(); - selected = NULL; - dirty = true; - activeSegment = 0; - granularity = 0.025; - pathColor.set(1.0, 0.5, 0.0); - controlColor.set(0.7, 0.0, 1.0); - segmentColor.set(0.0, 0.0, 1.0); - activeColor.set(1.0, 0.0, 0.0); - } - - void initPosition(long startTime, long totalTime); - const idVec3_t *getPosition(long time); - - -// void draw(bool editMode); - void addToRenderer(); - - void setSelectedPoint(idVec3_t *p); - idVec3_t *getSelectedPoint() { - return selected; - } - - void addPoint(const idVec3_t &v) { - controlPoints.Append(new idVec3_t(v)); - dirty = true; - } - - void addPoint(float x, float y, float z) { - controlPoints.Append(new idVec3_t(x, y, z)); - dirty = true; - } - - void updateSelection(const idVec3_t &move); - - void startEdit() { - editMode = true; - } - - void stopEdit() { - editMode = false; - } - - void buildSpline(); - - void setGranularity(float f) { - granularity = f; - } - - float getGranularity() { - return granularity; - } - - int numPoints() { - return controlPoints.Num(); - } - - idVec3_t *getPoint(int index) { - assert(index >= 0 && index < controlPoints.Num()); - return controlPoints[index]; - } - - idVec3_t *getSegmentPoint(int index) { - assert(index >= 0 && index < splinePoints.Num()); - return splinePoints[index]; - } - - - void setSegmentTime(int index, int time) { - assert(index >= 0 && index < splinePoints.Num()); - splineTime[index] = time; - } - - double getSegmentTime(int index) { - assert(index >= 0 && index < splinePoints.Num()); - return splineTime[index]; - } - void addSegmentTime(int index, int time) { - assert(index >= 0 && index < splinePoints.Num()); - splineTime[index] += time; - } - - float totalDistance(); - - static idVec3_t zero; - - int getActiveSegment() { - return activeSegment; - } - - void setActiveSegment(int i) { - //assert(i >= 0 && (splinePoints.Num() > 0 && i < splinePoints.Num())); - activeSegment = i; - } - - int numSegments() { - return splinePoints.Num(); - } - - void setColors(idVec3_t &path, idVec3_t &segment, idVec3_t &control, idVec3_t &active) { - pathColor = path; - segmentColor = segment; - controlColor = control; - activeColor = active; - } - - const char *getName() { - return name.c_str(); - } - - void setName(const char *p) { - name = p; - } - - bool validTime() { - if (dirty) { - buildSpline(); - } - // gcc doesn't allow static casting away from bools - // why? I've no idea... - return (bool)(splineTime.Num() > 0 && splineTime.Num() == splinePoints.Num()); - } - - void setTime(long t) { - time = t; - } - - void setBaseTime(long t) { - baseTime = t; - } - -protected: - idStr name; - float calcSpline(int step, float tension); - idList controlPoints; - idList splinePoints; - idList splineTime; - idVec3_t *selected; - idVec3_t pathColor, segmentColor, controlColor, activeColor; - float granularity; - bool editMode; - bool dirty; - int activeSegment; - long baseTime; - long time; - friend class idCamera; -}; - -// time in milliseconds -// velocity where 1.0 equal rough walking speed -struct idVelocity { - idVelocity(long start, long duration, float s) { - startTime = start; - time = duration; - speed = s; - } - long startTime; - long time; - float speed; -}; - -// can either be a look at or origin position for a camera -// -class idCameraPosition : public idPointListInterface { -public: - - virtual void clear() { - editMode = false; - for (int i = 0; i < velocities.Num(); i++) { - delete velocities[i]; - velocities[i] = NULL; - } - velocities.Clear(); - } - - idCameraPosition(const char *p) { - name = p; - } - - idCameraPosition() { - time = 0; - name = "position"; - } - - idCameraPosition(long t) { - time = t; - } - - virtual ~idCameraPosition() { - clear(); - } - - - // this can be done with RTTI syntax but i like the derived classes setting a type - // makes serialization a bit easier to see - // - enum positionType { - FIXED = 0x00, - INTERPOLATED, - SPLINE, - POSITION_COUNT - }; - - - virtual void start(long t) { - startTime = t; - } - - long getTime() { - return time; - } - - virtual void setTime(long t) { - time = t; - } - - float getVelocity(long t) { - long check = t - startTime; - for (int i = 0; i < velocities.Num(); i++) { - if (check >= velocities[i]->startTime && check <= velocities[i]->startTime + velocities[i]->time) { - return velocities[i]->speed; - } - } - return baseVelocity; - } - - void addVelocity(long start, long duration, float speed) { - velocities.Append(new idVelocity(start, duration, speed)); - } - - virtual const idVec3_t *getPosition(long t) { - assert(true); - return NULL; - } - -// virtual void draw(bool editMode) {}; - - virtual void parse(const char *(*text)) {}; - virtual void write(fileHandle_t file, const char *name); - virtual bool parseToken(const char *key, const char *(*text)); - - const char *getName() { - return name.c_str(); - } - - void setName(const char *p) { - name = p; - } - - virtual void startEdit() { - editMode = true; - } - - virtual void stopEdit() { - editMode = false; - } - -// virtual void draw() {}; - - const char *typeStr() { - return positionStr[static_cast(type)]; - } - - void calcVelocity(float distance) { - float secs = (float)time / 1000; - baseVelocity = distance / secs; - } - -protected: - static const char* positionStr[POSITION_COUNT]; - long startTime; - long time; - idCameraPosition::positionType type; - idStr name; - bool editMode; - idList velocities; - float baseVelocity; -}; - -class idFixedPosition : public idCameraPosition { -public: - - void init() { - pos.Zero(); - type = idCameraPosition::FIXED; - } - - idFixedPosition() : idCameraPosition() { - init(); - } - - idFixedPosition(idVec3_t p) : idCameraPosition() { - init(); - pos = p; - } - - virtual void addPoint(const idVec3_t &v) { - pos = v; - } - - virtual void addPoint(const float x, const float y, const float z) { - pos.set(x, y, z); - } - - - ~idFixedPosition() { - } - - virtual const idVec3_t *getPosition(long t) { - return &pos; - } - - void parse(const char *(*text)); - void write(fileHandle_t file, const char *name); - - virtual int numPoints() { - return 1; - } - - virtual idVec3_t *getPoint(int index) { - if (index != 0) { - assert(true); - }; - return &pos; - } -/* - virtual void draw(bool editMode) { - glLabeledPoint(blue, pos, (editMode) ? 5 : 3, "Fixed point"); - } -*/ -protected: - idVec3_t pos; -}; - -class idInterpolatedPosition : public idCameraPosition { -public: - - void init() { - type = idCameraPosition::INTERPOLATED; - first = true; - startPos.Zero(); - endPos.Zero(); - } - - idInterpolatedPosition() : idCameraPosition() { - init(); - } - - idInterpolatedPosition(idVec3_t start, idVec3_t end, long time) : idCameraPosition(time) { - init(); - startPos = start; - endPos = end; - } - - ~idInterpolatedPosition() { - } - - virtual const idVec3_t *getPosition(long t); - - void parse(const char *(*text)); - void write(fileHandle_t file, const char *name); - - virtual int numPoints() { - return 2; - } - - virtual idVec3_t *getPoint(int index) { - assert(index >= 0 && index < 2); - if (index == 0) { - return &startPos; - } - return &endPos; - } - - virtual void addPoint(const float x, const float y, const float z) { - if (first) { - startPos.set(x, y, z); - first = false; - } else { - endPos.set(x, y, z); - first = true; - } - } - - virtual void addPoint(const idVec3_t &v) { - if (first) { - startPos = v; - first = false; - } else { - endPos = v; - first = true; - } - } -/* - virtual void draw(bool editMode) { - glLabeledPoint(blue, startPos, (editMode) ? 5 : 3, "Start interpolated"); - glLabeledPoint(blue, endPos, (editMode) ? 5 : 3, "End interpolated"); - qglBegin(GL_LINES); - qglVertex3fv(startPos); - qglVertex3fv(endPos); - qglEnd(); - } -*/ - virtual void start(long t) { - idCameraPosition::start(t); - lastTime = startTime; - distSoFar = 0.0; - idVec3_t temp = startPos; - temp -= endPos; - calcVelocity(temp.Length()); - } - -protected: - bool first; - idVec3_t startPos; - idVec3_t endPos; - long lastTime; - float distSoFar; -}; - -class idSplinePosition : public idCameraPosition { -public: - - void init() { - type = idCameraPosition::SPLINE; - } - - idSplinePosition() : idCameraPosition() { - init(); - } - - idSplinePosition(long time) : idCameraPosition(time) { - init(); - } - - ~idSplinePosition() { - } - - virtual void start(long t) { - idCameraPosition::start(t); - target.initPosition(t, time); - calcVelocity(target.totalDistance()); - } - - virtual const idVec3_t *getPosition(long t) { - return target.getPosition(t); - } - - //virtual const idVec3_t *getPosition(long t) const { - - void addControlPoint(idVec3_t &v) { - target.addPoint(v); - } - - void parse(const char *(*text)); - void write(fileHandle_t file, const char *name); - - virtual int numPoints() { - return target.numPoints(); - } - - virtual idVec3_t *getPoint(int index) { - return target.getPoint(index); - } - - virtual void addPoint(const idVec3_t &v) { - target.addPoint(v); - } - - virtual void addPoint(const float x, const float y, const float z) { - target.addPoint(x, y, z); - } - -/* virtual void draw(bool editMode) { - target.draw(editMode); - } -*/ - virtual void updateSelection(const idVec3_t &move) { - idCameraPosition::updateSelection(move); - target.buildSpline(); - } - -protected: - idSplineList target; -}; - -class idCameraFOV { -public: - - idCameraFOV() { - time = 0; - fov = 90; - } - - idCameraFOV(int v) { - time = 0; - fov = v; - } - - idCameraFOV(int s, int e, long t) { - startFOV = s; - endFOV = e; - time = t; - } - - - ~idCameraFOV(){} - - void setFOV(float f) { - fov = f; - } - - float getFOV(long t) { - if (time) { - assert(startTime); - float percent = t / startTime; - float temp = startFOV - endFOV; - temp *= percent; - fov = startFOV + temp; - } - return fov; - } - - void start(long t) { - startTime = t; - } - - void parse(const char *(*text)); - void write(fileHandle_t file, const char *name); - -protected: - float fov; - float startFOV; - float endFOV; - int startTime; - int time; -}; - - - - -class idCameraEvent { -public: - enum eventType { - EVENT_NA = 0x00, - EVENT_WAIT, - EVENT_TARGETWAIT, - EVENT_SPEED, - EVENT_TARGET, - EVENT_SNAPTARGET, - EVENT_FOV, - EVENT_SCRIPT, - EVENT_TRIGGER, - EVENT_STOP, - EVENT_COUNT - }; - - static const char* eventStr[EVENT_COUNT]; - - idCameraEvent() { - paramStr = ""; - type = EVENT_NA; - time = 0; - } - - idCameraEvent(eventType t, const char *param, long n) { - type = t; - paramStr = param; - time = n; - } - - ~idCameraEvent() {}; - - eventType getType() { - return type; - } - - const char *typeStr() { - return eventStr[static_cast(type)]; - } - - const char *getParam() { - return paramStr.c_str(); - } - - long getTime() { - return time; - } - - void setTime(long n) { - time = n; - } - - void parse(const char *(*text)); - void write(fileHandle_t file, const char *name); - - void setTriggered(bool b) { - triggered = b; - } - - bool getTriggered() { - return triggered; - } - -protected: - eventType type; - idStr paramStr; - long time; - bool triggered; - -}; - -class idCameraDef { -public: - - void clear() { - currentCameraPosition = 0; - cameraRunning = false; - lastDirection.Zero(); - baseTime = 30; - activeTarget = 0; - name = "camera01"; - fov.setFOV(90); - int i; - for (i = 0; i < targetPositions.Num(); i++) { - delete targetPositions[i]; - } - for (i = 0; i < events.Num(); i++) { - delete events[i]; - } - delete cameraPosition; - cameraPosition = NULL; - events.Clear(); - targetPositions.Clear(); - } - - idCameraPosition *startNewCamera(idCameraPosition::positionType type) { - clear(); - if (type == idCameraPosition::SPLINE) { - cameraPosition = new idSplinePosition(); - } else if (type == idCameraPosition::INTERPOLATED) { - cameraPosition = new idInterpolatedPosition(); - } else { - cameraPosition = new idFixedPosition(); - } - return cameraPosition; - } - - idCameraDef() { - clear(); - } - - ~idCameraDef() { - clear(); - } - - void addEvent(idCameraEvent::eventType t, const char *param, long time); - - void addEvent(idCameraEvent *event); - - static int sortEvents(const void *p1, const void *p2); - - int numEvents() { - return events.Num(); - } - - idCameraEvent *getEvent(int index) { - assert(index >= 0 && index < events.Num()); - return events[index]; - } - - void parse(const char *(*text)); - qboolean load(const char *filename); - void save(const char *filename); - - void buildCamera(); - - //idSplineList *getcameraPosition() { - // return &cameraPosition; - //} - - static idCameraPosition *newFromType(idCameraPosition::positionType t) { - switch (t) { - case idCameraPosition::FIXED : return new idFixedPosition(); - case idCameraPosition::INTERPOLATED : return new idInterpolatedPosition(); - case idCameraPosition::SPLINE : return new idSplinePosition(); - default: - break; - }; - return NULL; - } - - void addTarget(const char *name, idCameraPosition::positionType type); - - idCameraPosition *getActiveTarget() { - if (targetPositions.Num() == 0) { - addTarget(NULL, idCameraPosition::FIXED); - } - return targetPositions[activeTarget]; - } - - idCameraPosition *getActiveTarget(int index) { - if (targetPositions.Num() == 0) { - addTarget(NULL, idCameraPosition::FIXED); - return targetPositions[0]; - } - return targetPositions[index]; - } - - int numTargets() { - return targetPositions.Num(); - } - - - void setActiveTargetByName(const char *name) { - for (int i = 0; i < targetPositions.Num(); i++) { - if (Q_stricmp(name, targetPositions[i]->getName()) == 0) { - setActiveTarget(i); - return; - } - } - } - - void setActiveTarget(int index) { - assert(index >= 0 && index < targetPositions.Num()); - activeTarget = index; - } - - void setRunning(bool b) { - cameraRunning = b; - } - - void setBaseTime(float f) { - baseTime = f; - } - - float getBaseTime() { - return baseTime; - } - - float getTotalTime() { - return totalTime; - } - - void startCamera(long t); - void stopCamera() { - cameraRunning = true; - } - void getActiveSegmentInfo(int segment, idVec3_t &origin, idVec3_t &direction, float *fv); - - bool getCameraInfo(long time, idVec3_t &origin, idVec3_t &direction, float *fv); - bool getCameraInfo(long time, float *origin, float *direction, float *fv) { - idVec3_t org, dir; - org[0] = origin[0]; - org[1] = origin[1]; - org[2] = origin[2]; - dir[0] = direction[0]; - dir[1] = direction[1]; - dir[2] = direction[2]; - bool b = getCameraInfo(time, org, dir, fv); - origin[0] = org[0]; - origin[1] = org[1]; - origin[2] = org[2]; - direction[0] = dir[0]; - direction[1] = dir[1]; - direction[2] = dir[2]; - return b; - } -/* - void draw(bool editMode) { - // gcc doesn't allow casting away from bools - // why? I've no idea... - if (cameraPosition) { - cameraPosition->draw((bool)((editMode || cameraRunning) && cameraEdit)); - int count = targetPositions.Num(); - for (int i = 0; i < count; i++) { - targetPositions[i]->draw((bool)((editMode || cameraRunning) && i == activeTarget && !cameraEdit)); - } - } - } -*/ -/* - int numSegments() { - if (cameraEdit) { - return cameraPosition.numSegments(); - } - return getTargetSpline()->numSegments(); - } - - int getActiveSegment() { - if (cameraEdit) { - return cameraPosition.getActiveSegment(); - } - return getTargetSpline()->getActiveSegment(); - } - - void setActiveSegment(int i) { - if (cameraEdit) { - cameraPosition.setActiveSegment(i); - } else { - getTargetSpline()->setActiveSegment(i); - } - } -*/ - int numPoints() { - if (cameraEdit) { - return cameraPosition->numPoints(); - } - return getActiveTarget()->numPoints(); - } - - const idVec3_t *getPoint(int index) { - if (cameraEdit) { - return cameraPosition->getPoint(index); - } - return getActiveTarget()->getPoint(index); - } - - void stopEdit() { - editMode = false; - if (cameraEdit) { - cameraPosition->stopEdit(); - } else { - getActiveTarget()->stopEdit(); - } - } - - void startEdit(bool camera) { - cameraEdit = camera; - if (camera) { - cameraPosition->startEdit(); - for (int i = 0; i < targetPositions.Num(); i++) { - targetPositions[i]->stopEdit(); - } - } else { - getActiveTarget()->startEdit(); - cameraPosition->stopEdit(); - } - editMode = true; - } - - bool waitEvent(int index); - - const char *getName() { - return name.c_str(); - } - - void setName(const char *p) { - name = p; - } - - idCameraPosition *getPositionObj() { - if (cameraPosition == NULL) { - cameraPosition = new idFixedPosition(); - } - return cameraPosition; - } - -protected: - idStr name; - int currentCameraPosition; - idVec3_t lastDirection; - bool cameraRunning; - idCameraPosition *cameraPosition; - idList targetPositions; - idList events; - idCameraFOV fov; - int activeTarget; - float totalTime; - float baseTime; - long startTime; - - bool cameraEdit; - bool editMode; -}; - -extern bool g_splineMode; - -extern idCameraDef *g_splineList; - - -#endif diff --git a/code/splines/util_list.h b/code/splines/util_list.h deleted file mode 100644 index 8107f77..0000000 --- a/code/splines/util_list.h +++ /dev/null @@ -1,346 +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 __UTIL_LIST_H__ -#define __UTIL_LIST_H__ - -#include -#include - -template< class type > -class idList { -private: - int m_num; - int m_size; - int m_granularity; - type *m_list; - -public: - idList( int granularity = 16 ); - ~idList(); - void Clear( void ); - int Num( void ); - void SetNum( int num ); - void SetGranularity( int granularity ); - void Condense( void ); - int Size( void ); - void Resize( int size ); - type operator[]( int index ) const; - type &operator[]( int index ); - int Append( type const & obj ); - int AddUnique( type const & obj ); - type *Find( type const & obj, int *index = NULL ); - bool RemoveIndex( int index ); - bool Remove( type const & obj ); - typedef int cmp_t(const void *, const void *); - void Sort( cmp_t *compare ); -}; - -/* -================ -idList::idList( int ) -================ -*/ -template< class type > -inline idList::idList( int granularity ) { - assert( granularity > 0 ); - - m_list = NULL; - m_granularity = granularity; - Clear(); -} - -/* -================ -idList::~idList -================ -*/ -template< class type > -inline idList::~idList() { - Clear(); -} - -/* -================ -idList::Clear -================ -*/ -template< class type > -inline void idList::Clear( void ) { - if ( m_list ) { - delete[] m_list; - } - - m_list = NULL; - m_num = 0; - m_size = 0; -} - -/* -================ -idList::Num -================ -*/ -template< class type > -inline int idList::Num( void ) { - return m_num; -} - -/* -================ -idList::SetNum -================ -*/ -template< class type > -inline void idList::SetNum( int num ) { - assert( num >= 0 ); - if ( num > m_size ) { - // resize it up to the closest level of granularity - Resize( ( ( num + m_granularity - 1 ) / m_granularity ) * m_granularity ); - } - m_num = num; -} - -/* -================ -idList::SetGranularity -================ -*/ -template< class type > -inline void idList::SetGranularity( int granularity ) { - int newsize; - - assert( granularity > 0 ); - m_granularity = granularity; - - if ( m_list ) { - // resize it to the closest level of granularity - newsize = ( ( m_num + m_granularity - 1 ) / m_granularity ) * m_granularity; - if ( newsize != m_size ) { - Resize( newsize ); - } - } -} - -/* -================ -idList::Condense - -Resizes the array to exactly the number of elements it contains -================ -*/ -template< class type > -inline void idList::Condense( void ) { - if ( m_list ) { - if ( m_num ) { - Resize( m_num ); - } else { - Clear(); - } - } -} - -/* -================ -idList::Size -================ -*/ -template< class type > -inline int idList::Size( void ) { - return m_size; -} - -/* -================ -idList::Resize -================ -*/ -template< class type > -inline void idList::Resize( int size ) { - type *temp; - int i; - - assert( size > 0 ); - - if ( size <= 0 ) { - Clear(); - return; - } - - temp = m_list; - m_size = size; - if ( m_size < m_num ) { - m_num = m_size; - } - - m_list = new type[ m_size ]; - for( i = 0; i < m_num; i++ ) { - m_list[ i ] = temp[ i ]; - } - - if ( temp ) { - delete[] temp; - } -} - -/* -================ -idList::operator[] const -================ -*/ -template< class type > -inline type idList::operator[]( int index ) const { - assert( index >= 0 ); - assert( index < m_num ); - - return m_list[ index ]; -} - -/* -================ -idList::operator[] -================ -*/ -template< class type > -inline type &idList::operator[]( int index ) { - assert( index >= 0 ); - assert( index < m_num ); - - return m_list[ index ]; -} - -/* -================ -idList::Append -================ -*/ -template< class type > -inline int idList::Append( type const & obj ) { - if ( !m_list ) { - Resize( m_granularity ); - } - - if ( m_num == m_size ) { - Resize( m_size + m_granularity ); - } - - m_list[ m_num ] = obj; - m_num++; - - return m_num - 1; -} - -/* -================ -idList::AddUnique -================ -*/ -template< class type > -inline int idList::AddUnique( type const & obj ) { - int index; - - if ( !Find( obj, &index ) ) { - index = Append( obj ); - } - - return index; -} - -/* -================ -idList::Find -================ -*/ -template< class type > -inline type *idList::Find( type const & obj, int *index ) { - int i; - - for( i = 0; i < m_num; i++ ) { - if ( m_list[ i ] == obj ) { - if ( index ) { - *index = i; - } - return &m_list[ i ]; - } - } - - return NULL; -} - -/* -================ -idList::RemoveIndex -================ -*/ -template< class type > -inline bool idList::RemoveIndex( int index ) { - int i; - - if ( !m_list || !m_num ) { - return false; - } - - assert( index >= 0 ); - assert( index < m_num ); - - if ( ( index < 0 ) || ( index >= m_num ) ) { - return false; - } - - m_num--; - for( i = index; i < m_num; i++ ) { - m_list[ i ] = m_list[ i + 1 ]; - } - - return true; -} - -/* -================ -idList::Remove -================ -*/ -template< class type > -inline bool idList::Remove( type const & obj ) { - int index; - - if ( Find( obj, &index ) ) { - return RemoveIndex( index ); - } - - return false; -} - -/* -================ -idList::Sort -================ -*/ -template< class type > -inline void idList::Sort( cmp_t *compare ) { - if ( !m_list ) { - return; - } - - qsort( ( void * )m_list, ( size_t )m_num, sizeof( type ), compare ); -} - -#endif /* !__UTIL_LIST_H__ */ diff --git a/code/splines/util_str.cpp b/code/splines/util_str.cpp deleted file mode 100644 index 395f62b..0000000 --- a/code/splines/util_str.cpp +++ /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 Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -//need to rewrite this - -#include "util_str.h" -#include -#include -#include -#include - -#ifdef _WIN32 -#pragma warning(disable : 4244) // 'conversion' conversion from 'type1' to 'type2', possible loss of data -#pragma warning(disable : 4710) // function 'blah' not inlined -#endif - -static const int STR_ALLOC_GRAN = 20; - -char *idStr::toLower - ( - char *s1 - ) - - { - char *s; - - s = s1; - while( *s ) - { - *s = ::tolower( *s ); - s++; - } - - return s1; - } - -char *idStr::toUpper - ( - char *s1 - ) - - { - char *s; - - s = s1; - while( *s ) - { - *s = ::toupper( *s ); - s++; - } - - return s1; - } - - -int idStr::icmpn - ( - const char *s1, - const char *s2, - int n - ) - - { - int c1; - int c2; - - do - { - c1 = *s1++; - c2 = *s2++; - - if ( !n-- ) - { - // idStrings are equal until end point - return 0; - } - - if ( c1 != c2 ) - { - if ( c1 >= 'a' && c1 <= 'z' ) - { - c1 -= ( 'a' - 'A' ); - } - - if ( c2 >= 'a' && c2 <= 'z' ) - { - c2 -= ( 'a' - 'A' ); - } - - if ( c1 < c2 ) - { - // strings less than - return -1; - } - else if ( c1 > c2 ) - { - // strings greater than - return 1; - } - } - } - while( c1 ); - - // strings are equal - return 0; - } - -int idStr::icmp - ( - const char *s1, - const char *s2 - ) - - { - int c1; - int c2; - - do - { - c1 = *s1++; - c2 = *s2++; - - if ( c1 != c2 ) - { - if ( c1 >= 'a' && c1 <= 'z' ) - { - c1 -= ( 'a' - 'A' ); - } - - if ( c2 >= 'a' && c2 <= 'z' ) - { - c2 -= ( 'a' - 'A' ); - } - - if ( c1 < c2 ) - { - // strings less than - return -1; - } - else if ( c1 > c2 ) - { - // strings greater than - return 1; - } - } - } - while( c1 ); - - // strings are equal - return 0; - } - -int idStr::cmpn - ( - const char *s1, - const char *s2, - int n - ) - - { - int c1; - int c2; - - do - { - c1 = *s1++; - c2 = *s2++; - - if ( !n-- ) - { - // strings are equal until end point - return 0; - } - - if ( c1 < c2 ) - { - // strings less than - return -1; - } - else if ( c1 > c2 ) - { - // strings greater than - return 1; - } - } - while( c1 ); - - // strings are equal - return 0; - } - -int idStr::cmp - ( - const char *s1, - const char *s2 - ) - - { - int c1; - int c2; - - do - { - c1 = *s1++; - c2 = *s2++; - - if ( c1 < c2 ) - { - // strings less than - return -1; - } - else if ( c1 > c2 ) - { - // strings greater than - return 1; - } - } - while( c1 ); - - // strings are equal - return 0; - } - -/* -============ -IsNumeric - -Checks a string to see if it contains only numerical values. -============ -*/ -bool idStr::isNumeric - ( - const char *str - ) - - { - int len; - int i; - bool dot; - - if ( *str == '-' ) - { - str++; - } - - dot = false; - len = strlen( str ); - for( i = 0; i < len; i++ ) - { - if ( !isdigit( str[ i ] ) ) - { - if ( ( str[ i ] == '.' ) && !dot ) - { - dot = true; - continue; - } - return false; - } - } - - return true; - } - -idStr operator+ - ( - const idStr& a, - const float b - ) - - { - char text[ 20 ]; - - idStr result( a ); - - sprintf( text, "%f", b ); - result.append( text ); - - return result; - } - -idStr operator+ - ( - const idStr& a, - const int b - ) - - { - char text[ 20 ]; - - idStr result( a ); - - sprintf( text, "%d", b ); - result.append( text ); - - return result; - } - -idStr operator+ - ( - const idStr& a, - const unsigned b - ) - - { - char text[ 20 ]; - - idStr result( a ); - - sprintf( text, "%u", b ); - result.append( text ); - - return result; - } - -idStr& idStr::operator+= - ( - const float a - ) - - { - char text[ 20 ]; - - sprintf( text, "%f", a ); - append( text ); - - return *this; - } - -idStr& idStr::operator+= - ( - const int a - ) - - { - char text[ 20 ]; - - sprintf( text, "%d", a ); - append( text ); - - return *this; - } - -idStr& idStr::operator+= - ( - const unsigned a - ) - - { - char text[ 20 ]; - - sprintf( text, "%u", a ); - append( text ); - - return *this; - } - -void idStr::CapLength - ( - int newlen - ) - - { - assert ( m_data ); - - if ( length() <= newlen ) - return; - - EnsureDataWritable (); - - m_data->data[newlen] = 0; - m_data->len = newlen; - } - -void idStr::EnsureDataWritable - ( - void - ) - - { - assert ( m_data ); - strdata *olddata; - int len; - - if ( !m_data->refcount ) - return; - - olddata = m_data; - len = length(); - - m_data = new strdata; - - EnsureAlloced ( len + 1, false ); - strncpy ( m_data->data, olddata->data, len+1 ); - m_data->len = len; - - olddata->DelRef (); - } - -void idStr::EnsureAlloced (int amount, bool keepold) { - - if ( !m_data ) { - m_data = new strdata(); - } - - // Now, let's make sure it's writable - EnsureDataWritable (); - - char *newbuffer; - bool wasalloced = ( m_data->alloced != 0 ); - - if ( amount < m_data->alloced ) { - return; - } - - assert ( amount ); - if ( amount == 1 ) { - m_data->alloced = 1; - } else { - int newsize, mod; - mod = amount % STR_ALLOC_GRAN; - if ( !mod ) { - newsize = amount; - } else { - newsize = amount + STR_ALLOC_GRAN - mod; - } - m_data->alloced = newsize; - } - - newbuffer = new char[m_data->alloced]; - if ( wasalloced && keepold ) { - strcpy ( newbuffer, m_data->data ); - } - - if ( m_data->data ) { - delete [] m_data->data; - } - m_data->data = newbuffer; -} - -void idStr::BackSlashesToSlashes - ( - void - ) - - { - int i; - - EnsureDataWritable (); - - for ( i=0; i < m_data->len; i++ ) - { - if ( m_data->data[i] == '\\' ) - m_data->data[i] = '/'; - } - } - -void idStr::snprintf - ( - char *dst, - int size, - const char *fmt, - ... - ) - - { - char buffer[0x10000]; - int len; - va_list argptr; - - va_start (argptr,fmt); - len = vsprintf (buffer,fmt,argptr); - va_end (argptr); - - assert ( len < size ); - - strncpy (dst, buffer, size-1); - } - -#ifdef _WIN32 -#pragma warning(disable : 4189) // local variable is initialized but not referenced -#endif - -/* -================= -TestStringClass - -This is a fairly rigorous test of the idStr class's functionality. -Because of the fairly global and subtle ramifications of a bug occuring -in this class, it should be run after any changes to the class. -Add more tests as functionality is changed. Tests should include -any possible bounds violation and NULL data tests. -================= -*/ -void TestStringClass - ( - void - ) - - { - char ch; // ch == ? - idStr *t; // t == ? - idStr a; // a.len == 0, a.data == "\0" - idStr b; // b.len == 0, b.data == "\0" - idStr c( "test" ); // c.len == 4, c.data == "test\0" - idStr d( c ); // d.len == 4, d.data == "test\0" - idStr e( reinterpret_cast(NULL) ); - // e.len == 0, e.data == "\0" ASSERT! - int i; // i == ? - - i = a.length(); // i == 0 - i = c.length(); // i == 4 - - // TTimo: not used -// const char *s1 = a.c_str(); // s1 == "\0" -// const char *s2 = c.c_str(); // s2 == "test\0" - - t = new idStr(); // t->len == 0, t->data == "\0" - delete t; // t == ? - - b = "test"; // b.len == 4, b.data == "test\0" - t = new idStr( "test" ); // t->len == 4, t->data == "test\0" - delete t; // t == ? - - a = c; // a.len == 4, a.data == "test\0" -// a = ""; - a = NULL; // a.len == 0, a.data == "\0" ASSERT! - a = c + d; // a.len == 8, a.data == "testtest\0" - a = c + "wow"; // a.len == 7, a.data == "testwow\0" - a = c + reinterpret_cast(NULL); - // a.len == 4, a.data == "test\0" ASSERT! - a = "this" + d; // a.len == 8, a.data == "thistest\0" - a = reinterpret_cast(NULL) + d; - // a.len == 4, a.data == "test\0" ASSERT! - a += c; // a.len == 8, a.data == "testtest\0" - a += "wow"; // a.len == 11, a.data == "testtestwow\0" - a += reinterpret_cast(NULL); - // a.len == 11, a.data == "testtestwow\0" ASSERT! - - a = "test"; // a.len == 4, a.data == "test\0" - ch = a[ 0 ]; // ch == 't' - ch = a[ -1 ]; // ch == 0 ASSERT! - ch = a[ 1000 ]; // ch == 0 ASSERT! - ch = a[ 0 ]; // ch == 't' - ch = a[ 1 ]; // ch == 'e' - ch = a[ 2 ]; // ch == 's' - ch = a[ 3 ]; // ch == 't' - ch = a[ 4 ]; // ch == '\0' ASSERT! - ch = a[ 5 ]; // ch == '\0' ASSERT! - - a[ 1 ] = 'b'; // a.len == 4, a.data == "tbst\0" - a[ -1 ] = 'b'; // a.len == 4, a.data == "tbst\0" ASSERT! - a[ 0 ] = '0'; // a.len == 4, a.data == "0bst\0" - a[ 1 ] = '1'; // a.len == 4, a.data == "01st\0" - a[ 2 ] = '2'; // a.len == 4, a.data == "012t\0" - a[ 3 ] = '3'; // a.len == 4, a.data == "0123\0" - a[ 4 ] = '4'; // a.len == 4, a.data == "0123\0" ASSERT! - a[ 5 ] = '5'; // a.len == 4, a.data == "0123\0" ASSERT! - a[ 7 ] = '7'; // a.len == 4, a.data == "0123\0" ASSERT! - - a = "test"; // a.len == 4, a.data == "test\0" - b = "no"; // b.len == 2, b.data == "no\0" - - i = ( a == b ); // i == 0 - i = ( a == c ); // i == 1 - - i = ( a == "blow" ); // i == 0 - i = ( a == "test" ); // i == 1 - i = ( a == NULL ); // i == 0 ASSERT! - - i = ( "test" == b ); // i == 0 - i = ( "test" == a ); // i == 1 - i = ( NULL == a ); // i == 0 ASSERT! - - i = ( a != b ); // i == 1 - i = ( a != c ); // i == 0 - - i = ( a != "blow" ); // i == 1 - i = ( a != "test" ); // i == 0 - i = ( a != NULL ); // i == 1 ASSERT! - - i = ( "test" != b ); // i == 1 - i = ( "test" != a ); // i == 0 - i = ( NULL != a ); // i == 1 ASSERT! - - a = "test"; // a.data == "test" - b = a; // b.data == "test" - - a = "not"; // a.data == "not", b.data == "test" - - a = b; // a.data == b.data == "test" - - a += b; // a.data == "testtest", b.data = "test" - - a = b; - - a[1] = '1'; // a.data = "t1st", b.data = "test" - } - -#ifdef _WIN32 -#pragma warning(default : 4189) // local variable is initialized but not referenced -#pragma warning(disable : 4514) // unreferenced inline function has been removed -#endif diff --git a/code/splines/util_str.h b/code/splines/util_str.h deleted file mode 100644 index 2283160..0000000 --- a/code/splines/util_str.h +++ /dev/null @@ -1,817 +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 -=========================================================================== -*/ -//need to rewrite this - -#ifndef __UTIL_STR_H__ -#define __UTIL_STR_H__ - -#include -#include -#include - -#ifdef _WIN32 -#pragma warning(disable : 4710) // function 'blah' not inlined -#endif - -void TestStringClass (); - -class strdata - { - public: - strdata () : len( 0 ), refcount ( 0 ), data ( NULL ), alloced ( 0 ) {} - ~strdata () - { - if ( data ) - delete [] data; - } - - void AddRef () { refcount++; } - bool DelRef () // True if killed - { - refcount--; - if ( refcount < 0 ) - { - delete this; - return true; - } - - return false; - } - - int len; - int refcount; - char *data; - int alloced; - }; - -class idStr { -protected: - strdata *m_data; - void EnsureAlloced ( int, bool keepold = true ); - void EnsureDataWritable (); - -public: - ~idStr(); - idStr(); - idStr( const char *text ); - idStr( const idStr& string ); - idStr( const idStr string, int start, int end ); - idStr( const char ch ); - idStr( const int num ); - idStr( const float num ); - idStr( const unsigned num ); - int length( void ) const; - int allocated( void ) const; - const char * c_str( void ) const; - - void append( const char *text ); - void append( const idStr& text ); - char operator[]( int index ) const; - char& operator[]( int index ); - - void operator=( const idStr& text ); - void operator=( const char *text ); - - friend idStr operator+( const idStr& a, const idStr& b ); - friend idStr operator+( const idStr& a, const char *b ); - friend idStr operator+( const char *a, const idStr& b ); - - friend idStr operator+( const idStr& a, const float b ); - friend idStr operator+( const idStr& a, const int b ); - friend idStr operator+( const idStr& a, const unsigned b ); - friend idStr operator+( const idStr& a, const bool b ); - friend idStr operator+( const idStr& a, const char b ); - - idStr& operator+=( const idStr& a ); - idStr& operator+=( const char *a ); - idStr& operator+=( const float a ); - idStr& operator+=( const char a ); - idStr& operator+=( const int a ); - idStr& operator+=( const unsigned a ); - idStr& operator+=( const bool a ); - - static char *toLower( char *s1 ); - static char *toUpper( char *s1 ); - - friend bool operator==( const idStr& a, const idStr& b ); - friend bool operator==( const idStr& a, const char *b ); - friend bool operator==( const char *a, const idStr& b ); - - friend bool operator!=( const idStr& a, const idStr& b ); - friend bool operator!=( const idStr& a, const char *b ); - friend bool operator!=( const char *a, const idStr& b ); - - operator const char * () const; - operator const char * (); - - int icmpn( const char *text, int n ) const; - int icmpn( const idStr& text, int n ) const; - int icmp( const char *text ) const; - int icmp( const idStr& text ) const; - int cmpn( const char *text, int n ) const; - int cmpn( const idStr& text, int n ) const; - int cmp( const char *text ) const; - int cmp( const idStr& text ) const; - - void tolower( void ); - void toupper( void ); - - static int icmpn( const char *s1, const char *s2, int n ); - static int icmp( const char *s1, const char *s2 ); - static int cmpn( const char *s1, const char *s2, int n ); - static int cmp( const char *s1, const char *s2 ); - - static void snprintf ( char *dst, int size, const char *fmt, ... ); - - static bool isNumeric( const char *str ); - bool isNumeric( void ) const; - - void CapLength ( int ); - - void BackSlashesToSlashes (); - -}; - -inline idStr::~idStr() - { - if ( m_data ) - { - m_data->DelRef (); - m_data = NULL; - } - } - -inline idStr::idStr() : m_data ( NULL ) - { - EnsureAlloced ( 1 ); - m_data->data[ 0 ] = 0; - } - -inline idStr::idStr - ( - const char *text - ) : m_data ( NULL ) - - { - int len; - - assert( text ); - - if ( text ) - { - len = strlen( text ); - EnsureAlloced ( len + 1 ); - strcpy( m_data->data, text ); - m_data->len = len; - } - else - { - EnsureAlloced ( 1 ); - m_data->data[ 0 ] = 0; - m_data->len = 0; - } - } - -inline idStr::idStr - ( - const idStr& text - ) : m_data ( NULL ) - - { - m_data = text.m_data; - m_data->AddRef (); - } - -inline idStr::idStr - ( - const idStr text, - int start, - int end - ) : m_data ( NULL ) - - { - int i; - int len; - - if ( end > text.length() ) - { - end = text.length(); - } - - if ( start > text.length() ) - { - start = text.length(); - } - - len = end - start; - if ( len < 0 ) - { - len = 0; - } - - EnsureAlloced ( len + 1 ); - - for( i = 0; i < len; i++ ) - { - m_data->data[ i ] = text[ start + i ]; - } - - m_data->data[ len ] = 0; - m_data->len = len; - } - -inline idStr::idStr - ( - const char ch - ) : m_data ( NULL ) - - { - EnsureAlloced ( 2 ); - - m_data->data[ 0 ] = ch; - m_data->data[ 1 ] = 0; - m_data->len = 1; - } - -inline idStr::idStr - ( - const float num - ) : m_data ( NULL ) - - { - char text[ 32 ]; - int len; - - sprintf( text, "%.3f", num ); - len = strlen( text ); - EnsureAlloced( len + 1 ); - strcpy( m_data->data, text ); - m_data->len = len; - } - -inline idStr::idStr - ( - const int num - ) : m_data ( NULL ) - - { - char text[ 32 ]; - int len; - - sprintf( text, "%d", num ); - len = strlen( text ); - EnsureAlloced( len + 1 ); - strcpy( m_data->data, text ); - m_data->len = len; - } - -inline idStr::idStr - ( - const unsigned num - ) : m_data ( NULL ) - - { - char text[ 32 ]; - int len; - - sprintf( text, "%u", num ); - len = strlen( text ); - EnsureAlloced( len + 1 ); - strcpy( m_data->data, text ); - m_data->len = len; - } - -inline int idStr::length( void ) const - { - return ( m_data != NULL ) ? m_data->len : 0; - } - -inline int idStr::allocated( void ) const - { - return ( m_data != NULL ) ? m_data->alloced + sizeof( *m_data ) : 0; - } - -inline const char *idStr::c_str( void ) const - { - assert( m_data ); - - return m_data->data; - } - -inline void idStr::append - ( - const char *text - ) - - { - int len; - - assert( text ); - - if ( text ) - { - len = length() + strlen( text ); - EnsureAlloced( len + 1 ); - - strcat( m_data->data, text ); - m_data->len = len; - } - } - -inline void idStr::append - ( - const idStr& text - ) - - { - int len; - - len = length() + text.length(); - EnsureAlloced ( len + 1 ); - - strcat ( m_data->data, text.c_str () ); - m_data->len = len; - } - -inline char idStr::operator[]( int index ) const - { - assert ( m_data ); - - if ( !m_data ) - return 0; - - // don't include the '/0' in the test, because technically, it's out of bounds - assert( ( index >= 0 ) && ( index < m_data->len ) ); - - // In release mode, give them a null character - // don't include the '/0' in the test, because technically, it's out of bounds - if ( ( index < 0 ) || ( index >= m_data->len ) ) - { - return 0; - } - - return m_data->data[ index ]; - } - -inline char& idStr::operator[] - ( - int index - ) - - { - // Used for result for invalid indices - static char dummy = 0; - assert ( m_data ); - - // We don't know if they'll write to it or not - // if it's not a const object - EnsureDataWritable (); - - if ( !m_data ) - return dummy; - - // don't include the '/0' in the test, because technically, it's out of bounds - assert( ( index >= 0 ) && ( index < m_data->len ) ); - - // In release mode, let them change a safe variable - // don't include the '/0' in the test, because technically, it's out of bounds - if ( ( index < 0 ) || ( index >= m_data->len ) ) - { - return dummy; - } - - return m_data->data[ index ]; - } - -inline void idStr::operator= - ( - const idStr& text - ) - - { - // adding the reference before deleting our current reference prevents - // us from deleting our string if we are copying from ourself - text.m_data->AddRef(); - m_data->DelRef(); - m_data = text.m_data; - } - -inline void idStr::operator= - ( - const char *text - ) - - { - int len; - - assert( text ); - - if ( !text ) - { - // safe behaviour if NULL - EnsureAlloced ( 1, false ); - m_data->data[0] = 0; - m_data->len = 0; - return; - } - - if ( !m_data ) - { - len = strlen ( text ); - EnsureAlloced( len + 1, false ); - strcpy ( m_data->data, text ); - m_data->len = len; - return; - } - - if ( text == m_data->data ) - return; // Copying same thing. Punt. - - // If we alias and I don't do this, I could corrupt other strings... This - // will get called with EnsureAlloced anyway - EnsureDataWritable (); - - // Now we need to check if we're aliasing.. - if ( text >= m_data->data && text <= m_data->data + m_data->len ) - { - // Great, we're aliasing. We're copying from inside ourselves. - // This means that I don't have to ensure that anything is alloced, - // though I'll assert just in case. - int diff = text - m_data->data; - int i; - - assert ( strlen ( text ) < (unsigned) m_data->len ); - - for ( i = 0; text[i]; i++ ) - { - m_data->data[i] = text[i]; - } - - m_data->data[i] = 0; - - m_data->len -= diff; - - return; - } - - len = strlen( text ); - EnsureAlloced ( len + 1, false ); - strcpy( m_data->data, text ); - m_data->len = len; - } - -inline idStr operator+ - ( - const idStr& a, - const idStr& b - ) - - { - idStr result( a ); - - result.append( b ); - - return result; - } - -inline idStr operator+ - ( - const idStr& a, - const char *b - ) - - { - idStr result( a ); - - result.append( b ); - - return result; - } - -inline idStr operator+ - ( - const char *a, - const idStr& b - ) - - { - idStr result( a ); - - result.append( b ); - - return result; - } - -inline idStr operator+ - ( - const idStr& a, - const bool b - ) - - { - idStr result( a ); - - result.append( b ? "true" : "false" ); - - return result; - } - -inline idStr operator+ - ( - const idStr& a, - const char b - ) - - { - char text[ 2 ]; - - text[ 0 ] = b; - text[ 1 ] = 0; - - return a + text; - } - -inline idStr& idStr::operator+= - ( - const idStr& a - ) - - { - append( a ); - return *this; - } - -inline idStr& idStr::operator+= - ( - const char *a - ) - - { - append( a ); - return *this; - } - -inline idStr& idStr::operator+= - ( - const char a - ) - - { - char text[ 2 ]; - - text[ 0 ] = a; - text[ 1 ] = 0; - append( text ); - - return *this; - } - -inline idStr& idStr::operator+= - ( - const bool a - ) - - { - append( a ? "true" : "false" ); - return *this; - } - -inline bool operator== - ( - const idStr& a, - const idStr& b - ) - - { - return ( !strcmp( a.c_str(), b.c_str() ) ); - } - -inline bool operator== - ( - const idStr& a, - const char *b - ) - - { - assert( b ); - if ( !b ) - { - return false; - } - return ( !strcmp( a.c_str(), b ) ); - } - -inline bool operator== - ( - const char *a, - const idStr& b - ) - - { - assert( a ); - if ( !a ) - { - return false; - } - return ( !strcmp( a, b.c_str() ) ); - } - -inline bool operator!= - ( - const idStr& a, - const idStr& b - ) - - { - return !( a == b ); - } - -inline bool operator!= - ( - const idStr& a, - const char *b - ) - - { - return !( a == b ); - } - -inline bool operator!= - ( - const char *a, - const idStr& b - ) - - { - return !( a == b ); - } - -inline int idStr::icmpn - ( - const char *text, - int n - ) const - - { - assert( m_data ); - assert( text ); - - return idStr::icmpn( m_data->data, text, n ); - } - -inline int idStr::icmpn - ( - const idStr& text, - int n - ) const - - { - assert( m_data ); - assert( text.m_data ); - - return idStr::icmpn( m_data->data, text.m_data->data, n ); - } - -inline int idStr::icmp - ( - const char *text - ) const - - { - assert( m_data ); - assert( text ); - - return idStr::icmp( m_data->data, text ); - } - -inline int idStr::icmp - ( - const idStr& text - ) const - - { - assert( c_str () ); - assert( text.c_str () ); - - return idStr::icmp( c_str () , text.c_str () ); - } - -inline int idStr::cmp - ( - const char *text - ) const - - { - assert( m_data ); - assert( text ); - - return idStr::cmp( m_data->data, text ); - } - -inline int idStr::cmp - ( - const idStr& text - ) const - - { - assert( c_str () ); - assert( text.c_str () ); - - return idStr::cmp( c_str () , text.c_str () ); - } - -inline int idStr::cmpn - ( - const char *text, - int n - ) const - - { - assert( c_str () ); - assert( text ); - - return idStr::cmpn( c_str () , text, n ); - } - -inline int idStr::cmpn - ( - const idStr& text, - int n - ) const - - { - assert( c_str () ); - assert( text.c_str () ); - - return idStr::cmpn( c_str () , text.c_str () , n ); - } - -inline void idStr::tolower - ( - void - ) - - { - assert( m_data ); - - EnsureDataWritable (); - - idStr::toLower( m_data->data ); - } - -inline void idStr::toupper - ( - void - ) - - { - assert( m_data ); - - EnsureDataWritable (); - - idStr::toUpper( m_data->data ); - } - -inline bool idStr::isNumeric - ( - void - ) const - - { - assert( m_data ); - return idStr::isNumeric( m_data->data ); - } - -inline idStr::operator const char *() { - return c_str(); -} - -inline idStr::operator const char * - ( - void - ) const - - { - return c_str (); - } - -#endif diff --git a/code/ui/ui_atoms.c b/code/ui/ui_atoms.c index 01f77d5..760e686 100644 --- a/code/ui/ui_atoms.c +++ b/code/ui/ui_atoms.c @@ -29,9 +29,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA qboolean m_entersound; // after a frame, so caching won't disrupt the sound -// these are here so the functions in q_shared.c can link -#ifndef UI_HARD_LINKED - void QDECL Com_Error( int level, const char *error, ... ) { va_list argptr; char text[1024]; @@ -54,8 +51,6 @@ void QDECL Com_Printf( const char *msg, ... ) { trap_Print( va("%s", text) ); } -#endif - qboolean newUI = qfalse; -- cgit v1.2.3