Itsa me, quake3io!

This commit is contained in:
Zachary Slater 2005-08-26 04:48:05 +00:00
parent dbe4ddb103
commit 5b755058f5
1409 changed files with 798983 additions and 798983 deletions

150
code/bspc/Conscript Normal file → Executable file
View file

@ -1,75 +1,75 @@
# bspc compile
Import qw( BSPC_BASE_CFLAGS BUILD_DIR INSTALL_DIR CC CXX LINK );
@BSPC_FILES = qw(
aas_areamerging.c
aas_cfg.c
aas_create.c
aas_edgemelting.c
aas_facemerging.c
aas_file.c
aas_gsubdiv.c
aas_map.c
aas_prunenodes.c
aas_store.c
be_aas_bspc.c
../botlib/be_aas_bspq3.c
../botlib/be_aas_cluster.c
../botlib/be_aas_move.c
../botlib/be_aas_optimize.c
../botlib/be_aas_reach.c
../botlib/be_aas_sample.c
brushbsp.c
bspc.c
../qcommon/cm_load.c
../qcommon/cm_patch.c
../qcommon/cm_test.c
../qcommon/cm_trace.c
csg.c
glfile.c
l_bsp_ent.c
l_bsp_hl.c
l_bsp_q1.c
l_bsp_q2.c
l_bsp_q3.c
l_bsp_sin.c
l_cmd.c
../botlib/l_libvar.c
l_log.c
l_math.c
l_mem.c
l_poly.c
../botlib/l_precomp.c
l_qfiles.c
../botlib/l_script.c
../botlib/l_struct.c
l_threads.c
l_utils.c
leakfile.c
map.c
map_hl.c
map_q1.c
map_q2.c
map_q3.c
map_sin.c
../qcommon/md4.c
nodraw.c
portals.c
textures.c
tree.c
../qcommon/unzip.c
);
$BSPC_REF = \@BSPC_FILES;
$env = new cons(
CC => $CC,
CXX => $CXX,
LINK => $LINK,
CFLAGS => $BSPC_BASE_CFLAGS,
LIBS => '-ldl -lm -lpthread'
);
Program $env 'bspc', @$BSPC_REF;
# this should install to Q3 or something?
Install $env $INSTALL_DIR, 'bspc';
# bspc compile
Import qw( BSPC_BASE_CFLAGS BUILD_DIR INSTALL_DIR CC CXX LINK );
@BSPC_FILES = qw(
aas_areamerging.c
aas_cfg.c
aas_create.c
aas_edgemelting.c
aas_facemerging.c
aas_file.c
aas_gsubdiv.c
aas_map.c
aas_prunenodes.c
aas_store.c
be_aas_bspc.c
../botlib/be_aas_bspq3.c
../botlib/be_aas_cluster.c
../botlib/be_aas_move.c
../botlib/be_aas_optimize.c
../botlib/be_aas_reach.c
../botlib/be_aas_sample.c
brushbsp.c
bspc.c
../qcommon/cm_load.c
../qcommon/cm_patch.c
../qcommon/cm_test.c
../qcommon/cm_trace.c
csg.c
glfile.c
l_bsp_ent.c
l_bsp_hl.c
l_bsp_q1.c
l_bsp_q2.c
l_bsp_q3.c
l_bsp_sin.c
l_cmd.c
../botlib/l_libvar.c
l_log.c
l_math.c
l_mem.c
l_poly.c
../botlib/l_precomp.c
l_qfiles.c
../botlib/l_script.c
../botlib/l_struct.c
l_threads.c
l_utils.c
leakfile.c
map.c
map_hl.c
map_q1.c
map_q2.c
map_q3.c
map_sin.c
../qcommon/md4.c
nodraw.c
portals.c
textures.c
tree.c
../qcommon/unzip.c
);
$BSPC_REF = \@BSPC_FILES;
$env = new cons(
CC => $CC,
CXX => $CXX,
LINK => $LINK,
CFLAGS => $BSPC_BASE_CFLAGS,
LIBS => '-ldl -lm -lpthread'
);
Program $env 'bspc', @$BSPC_REF;
# this should install to Q3 or something?
Install $env $INSTALL_DIR, 'bspc';

228
code/bspc/Makefile Normal file → Executable file
View file

@ -1,114 +1,114 @@
#
# 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"
#
#
# 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"
#

0
code/bspc/_files.c Normal file → Executable file
View file

780
code/bspc/aas_areamerging.c Normal file → Executable file
View file

@ -1,390 +1,390 @@
/*
===========================================================================
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 "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
/*
===========================================================================
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 "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

48
code/bspc/aas_areamerging.h Normal file → Executable file
View file

@ -1,24 +1,24 @@
/*
===========================================================================
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
===========================================================================
*/
void AAS_MergeAreas(void);
/*
===========================================================================
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
===========================================================================
*/
void AAS_MergeAreas(void);

504
code/bspc/aas_cfg.c Normal file → Executable file
View file

@ -1,252 +1,252 @@
/*
===========================================================================
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 "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
/*
===========================================================================
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 "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

146
code/bspc/aas_cfg.h Normal file → Executable file
View file

@ -1,73 +1,73 @@
/*
===========================================================================
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
===========================================================================
*/
#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);
/*
===========================================================================
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
===========================================================================
*/
#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);

2284
code/bspc/aas_create.c Normal file → Executable file

File diff suppressed because it is too large Load diff

272
code/bspc/aas_create.h Normal file → Executable file
View file

@ -1,136 +1,136 @@
/*
===========================================================================
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
===========================================================================
*/
#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);
/*
===========================================================================
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
===========================================================================
*/
#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);

216
code/bspc/aas_edgemelting.c Normal file → Executable file
View file

@ -1,108 +1,108 @@
/*
===========================================================================
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 "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
/*
===========================================================================
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 "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

48
code/bspc/aas_edgemelting.h Normal file → Executable file
View file

@ -1,24 +1,24 @@
/*
===========================================================================
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
===========================================================================
*/
void AAS_MeltAreaFaceWindings(void);
/*
===========================================================================
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
===========================================================================
*/
void AAS_MeltAreaFaceWindings(void);

564
code/bspc/aas_facemerging.c Normal file → Executable file
View file

@ -1,282 +1,282 @@
/*
===========================================================================
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 "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
/*
===========================================================================
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 "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

48
code/bspc/aas_facemerging.h Normal file → Executable file
View file

@ -1,24 +1,24 @@
/*
===========================================================================
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
===========================================================================
*/
void AAS_MergeAreaFaces(void);
void AAS_MergeAreaPlaneFaces(void);
/*
===========================================================================
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
===========================================================================
*/
void AAS_MergeAreaFaces(void);
void AAS_MergeAreaPlaneFaces(void);

1098
code/bspc/aas_file.c Normal file → Executable file

File diff suppressed because it is too large Load diff

50
code/bspc/aas_file.h Normal file → Executable file
View file

@ -1,25 +1,25 @@
/*
===========================================================================
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
===========================================================================
*/
qboolean AAS_WriteAASFile(char *filename);
qboolean AAS_LoadAASFile(char *filename, int fpoffset, int fplength);
/*
===========================================================================
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
===========================================================================
*/
qboolean AAS_WriteAASFile(char *filename);
qboolean AAS_LoadAASFile(char *filename, int fpoffset, int fplength);

1312
code/bspc/aas_gsubdiv.c Normal file → Executable file

File diff suppressed because it is too large Load diff

50
code/bspc/aas_gsubdiv.h Normal file → Executable file
View file

@ -1,25 +1,25 @@
/*
===========================================================================
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
===========================================================================
*/
//works with the global tmpaasworld
void AAS_GravitationalSubdivision(void);
void AAS_LadderSubdivision(void);
/*
===========================================================================
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
===========================================================================
*/
//works with the global tmpaasworld
void AAS_GravitationalSubdivision(void);
void AAS_LadderSubdivision(void);

1698
code/bspc/aas_map.c Normal file → Executable file

File diff suppressed because it is too large Load diff

46
code/bspc/aas_map.h Normal file → Executable file
View file

@ -1,23 +1,23 @@
/*
===========================================================================
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
===========================================================================
*/
void AAS_CreateMapBrushes(mapbrush_t *brush, entity_t *mapent, int addbevels);
/*
===========================================================================
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
===========================================================================
*/
void AAS_CreateMapBrushes(mapbrush_t *brush, entity_t *mapent, int addbevels);

178
code/bspc/aas_prunenodes.c Normal file → Executable file
View file

@ -1,89 +1,89 @@
/*
===========================================================================
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 "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
/*
===========================================================================
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 "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

48
code/bspc/aas_prunenodes.h Normal file → Executable file
View file

@ -1,24 +1,24 @@
/*
===========================================================================
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
===========================================================================
*/
void AAS_PruneNodes(void);
/*
===========================================================================
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
===========================================================================
*/
void AAS_PruneNodes(void);

2164
code/bspc/aas_store.c Normal file → Executable file

File diff suppressed because it is too large Load diff

214
code/bspc/aas_store.h Normal file → Executable file
View file

@ -1,107 +1,107 @@
/*
===========================================================================
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
===========================================================================
*/
#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 "../game/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);
/*
===========================================================================
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
===========================================================================
*/
#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 "../game/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);

504
code/bspc/aasfile.h Normal file → Executable file
View file

@ -1,252 +1,252 @@
/*
===========================================================================
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
===========================================================================
*/
//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
*/
/*
===========================================================================
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
===========================================================================
*/
//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
*/

584
code/bspc/be_aas_bspc.c Normal file → Executable file
View file

@ -1,292 +1,292 @@
/*
===========================================================================
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 "../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 "../game/botlib.h"
#include "../game/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
/*
===========================================================================
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 "../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 "../game/botlib.h"
#include "../game/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

46
code/bspc/be_aas_bspc.h Normal file → Executable file
View file

@ -1,23 +1,23 @@
/*
===========================================================================
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
===========================================================================
*/
void AAS_CalcReachAndClusters(struct quakefile_s *qf);
/*
===========================================================================
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
===========================================================================
*/
void AAS_CalcReachAndClusters(struct quakefile_s *qf);

3742
code/bspc/brushbsp.c Normal file → Executable file

File diff suppressed because it is too large Load diff

1982
code/bspc/bspc.c Normal file → Executable file

File diff suppressed because it is too large Load diff

56
code/bspc/bspc.sln Normal file → Executable file
View file

@ -1,28 +1,28 @@
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
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

2762
code/bspc/bspc.vcproj Normal file → Executable file

File diff suppressed because it is too large Load diff

168
code/bspc/cfgq3.c Normal file → Executable file
View file

@ -1,84 +1,84 @@
/*
===========================================================================
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
===========================================================================
*/
//===========================================================================
// 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
/*
===========================================================================
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
===========================================================================
*/
//===========================================================================
// 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

2010
code/bspc/csg.c Normal file → Executable file

File diff suppressed because it is too large Load diff

1956
code/bspc/faces.c Normal file → Executable file

File diff suppressed because it is too large Load diff

464
code/bspc/gldraw.c Normal file → Executable file
View file

@ -1,232 +1,232 @@
/*
===========================================================================
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 <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glaux.h>
#include "qbsp.h"
// can't use the glvertex3fv functions, because the vec3_t fields
// could be either floats or doubles, depending on DOUBLEVEC_T
qboolean drawflag;
vec3_t draw_mins, draw_maxs;
#define WIN_SIZE 512
void InitWindow (void)
{
auxInitDisplayMode (AUX_SINGLE | AUX_RGB);
auxInitPosition (0, 0, WIN_SIZE, WIN_SIZE);
auxInitWindow ("qcsg");
}
void Draw_ClearWindow (void)
{
static int init;
int w, h, g;
vec_t mx, my;
if (!drawflag)
return;
if (!init)
{
init = true;
InitWindow ();
}
glClearColor (1,0.8,0.8,0);
glClear (GL_COLOR_BUFFER_BIT);
w = (draw_maxs[0] - draw_mins[0]);
h = (draw_maxs[1] - draw_mins[1]);
mx = draw_mins[0] + w/2;
my = draw_mins[1] + h/2;
g = w > h ? w : h;
glLoadIdentity ();
gluPerspective (90, 1, 2, 16384);
gluLookAt (mx, my, draw_maxs[2] + g/2, mx , my, draw_maxs[2], 0, 1, 0);
glColor3f (0,0,0);
// glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
glDisable (GL_DEPTH_TEST);
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
#if 0
glColor4f (1,0,0,0.5);
glBegin (GL_POLYGON);
glVertex3f (0, 500, 0);
glVertex3f (0, 900, 0);
glVertex3f (0, 900, 100);
glVertex3f (0, 500, 100);
glEnd ();
#endif
glFlush ();
}
void Draw_SetRed (void)
{
if (!drawflag)
return;
glColor3f (1,0,0);
}
void Draw_SetGrey (void)
{
if (!drawflag)
return;
glColor3f (0.5,0.5,0.5);
}
void Draw_SetBlack (void)
{
if (!drawflag)
return;
glColor3f (0,0,0);
}
void DrawWinding (winding_t *w)
{
int i;
if (!drawflag)
return;
glColor4f (0,0,0,0.5);
glBegin (GL_LINE_LOOP);
for (i=0 ; i<w->numpoints ; i++)
glVertex3f (w->p[i][0],w->p[i][1],w->p[i][2] );
glEnd ();
glColor4f (0,1,0,0.3);
glBegin (GL_POLYGON);
for (i=0 ; i<w->numpoints ; i++)
glVertex3f (w->p[i][0],w->p[i][1],w->p[i][2] );
glEnd ();
glFlush ();
}
void DrawAuxWinding (winding_t *w)
{
int i;
if (!drawflag)
return;
glColor4f (0,0,0,0.5);
glBegin (GL_LINE_LOOP);
for (i=0 ; i<w->numpoints ; i++)
glVertex3f (w->p[i][0],w->p[i][1],w->p[i][2] );
glEnd ();
glColor4f (1,0,0,0.3);
glBegin (GL_POLYGON);
for (i=0 ; i<w->numpoints ; i++)
glVertex3f (w->p[i][0],w->p[i][1],w->p[i][2] );
glEnd ();
glFlush ();
}
//============================================================
#define GLSERV_PORT 25001
qboolean wins_init;
int draw_socket;
void GLS_BeginScene (void)
{
WSADATA winsockdata;
WORD wVersionRequested;
struct sockaddr_in address;
int r;
if (!wins_init)
{
wins_init = true;
wVersionRequested = MAKEWORD(1, 1);
r = WSAStartup (MAKEWORD(1, 1), &winsockdata);
if (r)
Error ("Winsock initialization failed.");
}
// connect a socket to the server
draw_socket = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (draw_socket == -1)
Error ("draw_socket failed");
address.sin_family = AF_INET;
address.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
address.sin_port = GLSERV_PORT;
r = connect (draw_socket, (struct sockaddr *)&address, sizeof(address));
if (r == -1)
{
closesocket (draw_socket);
draw_socket = 0;
}
}
void GLS_Winding (winding_t *w, int code)
{
byte buf[1024];
int i, j;
if (!draw_socket)
return;
((int *)buf)[0] = w->numpoints;
((int *)buf)[1] = code;
for (i=0 ; i<w->numpoints ; i++)
for (j=0 ; j<3 ; j++)
((float *)buf)[2+i*3+j] = w->p[i][j];
send (draw_socket, buf, w->numpoints*12+8, 0);
}
void GLS_EndScene (void)
{
closesocket (draw_socket);
draw_socket = 0;
}
/*
===========================================================================
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 <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glaux.h>
#include "qbsp.h"
// can't use the glvertex3fv functions, because the vec3_t fields
// could be either floats or doubles, depending on DOUBLEVEC_T
qboolean drawflag;
vec3_t draw_mins, draw_maxs;
#define WIN_SIZE 512
void InitWindow (void)
{
auxInitDisplayMode (AUX_SINGLE | AUX_RGB);
auxInitPosition (0, 0, WIN_SIZE, WIN_SIZE);
auxInitWindow ("qcsg");
}
void Draw_ClearWindow (void)
{
static int init;
int w, h, g;
vec_t mx, my;
if (!drawflag)
return;
if (!init)
{
init = true;
InitWindow ();
}
glClearColor (1,0.8,0.8,0);
glClear (GL_COLOR_BUFFER_BIT);
w = (draw_maxs[0] - draw_mins[0]);
h = (draw_maxs[1] - draw_mins[1]);
mx = draw_mins[0] + w/2;
my = draw_mins[1] + h/2;
g = w > h ? w : h;
glLoadIdentity ();
gluPerspective (90, 1, 2, 16384);
gluLookAt (mx, my, draw_maxs[2] + g/2, mx , my, draw_maxs[2], 0, 1, 0);
glColor3f (0,0,0);
// glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
glDisable (GL_DEPTH_TEST);
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
#if 0
glColor4f (1,0,0,0.5);
glBegin (GL_POLYGON);
glVertex3f (0, 500, 0);
glVertex3f (0, 900, 0);
glVertex3f (0, 900, 100);
glVertex3f (0, 500, 100);
glEnd ();
#endif
glFlush ();
}
void Draw_SetRed (void)
{
if (!drawflag)
return;
glColor3f (1,0,0);
}
void Draw_SetGrey (void)
{
if (!drawflag)
return;
glColor3f (0.5,0.5,0.5);
}
void Draw_SetBlack (void)
{
if (!drawflag)
return;
glColor3f (0,0,0);
}
void DrawWinding (winding_t *w)
{
int i;
if (!drawflag)
return;
glColor4f (0,0,0,0.5);
glBegin (GL_LINE_LOOP);
for (i=0 ; i<w->numpoints ; i++)
glVertex3f (w->p[i][0],w->p[i][1],w->p[i][2] );
glEnd ();
glColor4f (0,1,0,0.3);
glBegin (GL_POLYGON);
for (i=0 ; i<w->numpoints ; i++)
glVertex3f (w->p[i][0],w->p[i][1],w->p[i][2] );
glEnd ();
glFlush ();
}
void DrawAuxWinding (winding_t *w)
{
int i;
if (!drawflag)
return;
glColor4f (0,0,0,0.5);
glBegin (GL_LINE_LOOP);
for (i=0 ; i<w->numpoints ; i++)
glVertex3f (w->p[i][0],w->p[i][1],w->p[i][2] );
glEnd ();
glColor4f (1,0,0,0.3);
glBegin (GL_POLYGON);
for (i=0 ; i<w->numpoints ; i++)
glVertex3f (w->p[i][0],w->p[i][1],w->p[i][2] );
glEnd ();
glFlush ();
}
//============================================================
#define GLSERV_PORT 25001
qboolean wins_init;
int draw_socket;
void GLS_BeginScene (void)
{
WSADATA winsockdata;
WORD wVersionRequested;
struct sockaddr_in address;
int r;
if (!wins_init)
{
wins_init = true;
wVersionRequested = MAKEWORD(1, 1);
r = WSAStartup (MAKEWORD(1, 1), &winsockdata);
if (r)
Error ("Winsock initialization failed.");
}
// connect a socket to the server
draw_socket = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (draw_socket == -1)
Error ("draw_socket failed");
address.sin_family = AF_INET;
address.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
address.sin_port = GLSERV_PORT;
r = connect (draw_socket, (struct sockaddr *)&address, sizeof(address));
if (r == -1)
{
closesocket (draw_socket);
draw_socket = 0;
}
}
void GLS_Winding (winding_t *w, int code)
{
byte buf[1024];
int i, j;
if (!draw_socket)
return;
((int *)buf)[0] = w->numpoints;
((int *)buf)[1] = code;
for (i=0 ; i<w->numpoints ; i++)
for (j=0 ; j<3 ; j++)
((float *)buf)[2+i*3+j] = w->p[i][j];
send (draw_socket, buf, w->numpoints*12+8, 0);
}
void GLS_EndScene (void)
{
closesocket (draw_socket);
draw_socket = 0;
}

298
code/bspc/glfile.c Normal file → Executable file
View file

@ -1,149 +1,149 @@
/*
===========================================================================
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 "qbsp.h"
int c_glfaces;
int PortalVisibleSides (portal_t *p)
{
int fcon, bcon;
if (!p->onnode)
return 0; // outside
fcon = p->nodes[0]->contents;
bcon = p->nodes[1]->contents;
// same contents never create a face
if (fcon == bcon)
return 0;
// FIXME: is this correct now?
if (!fcon)
return 1;
if (!bcon)
return 2;
return 0;
}
void OutputWinding (winding_t *w, FILE *glview)
{
static int level = 128;
vec_t light;
int i;
fprintf (glview, "%i\n", w->numpoints);
level+=28;
light = (level&255)/255.0;
for (i=0 ; i<w->numpoints ; i++)
{
fprintf (glview, "%6.3f %6.3f %6.3f %6.3f %6.3f %6.3f\n",
w->p[i][0],
w->p[i][1],
w->p[i][2],
light,
light,
light);
}
fprintf (glview, "\n");
}
/*
=============
OutputPortal
=============
*/
void OutputPortal (portal_t *p, FILE *glview)
{
winding_t *w;
int sides;
sides = PortalVisibleSides (p);
if (!sides)
return;
c_glfaces++;
w = p->winding;
if (sides == 2) // back side
w = ReverseWinding (w);
OutputWinding (w, glview);
if (sides == 2)
FreeWinding(w);
}
/*
=============
WriteGLView_r
=============
*/
void WriteGLView_r (node_t *node, FILE *glview)
{
portal_t *p, *nextp;
if (node->planenum != PLANENUM_LEAF)
{
WriteGLView_r (node->children[0], glview);
WriteGLView_r (node->children[1], glview);
return;
}
// write all the portals
for (p=node->portals ; p ; p=nextp)
{
if (p->nodes[0] == node)
{
OutputPortal (p, glview);
nextp = p->next[0];
}
else
nextp = p->next[1];
}
}
/*
=============
WriteGLView
=============
*/
void WriteGLView (tree_t *tree, char *source)
{
char name[1024];
FILE *glview;
c_glfaces = 0;
sprintf (name, "%s%s.gl",outbase, source);
printf ("Writing %s\n", name);
glview = fopen (name, "w");
if (!glview)
Error ("Couldn't open %s", name);
WriteGLView_r (tree->headnode, glview);
fclose (glview);
printf ("%5i c_glfaces\n", c_glfaces);
}
/*
===========================================================================
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 "qbsp.h"
int c_glfaces;
int PortalVisibleSides (portal_t *p)
{
int fcon, bcon;
if (!p->onnode)
return 0; // outside
fcon = p->nodes[0]->contents;
bcon = p->nodes[1]->contents;
// same contents never create a face
if (fcon == bcon)
return 0;
// FIXME: is this correct now?
if (!fcon)
return 1;
if (!bcon)
return 2;
return 0;
}
void OutputWinding (winding_t *w, FILE *glview)
{
static int level = 128;
vec_t light;
int i;
fprintf (glview, "%i\n", w->numpoints);
level+=28;
light = (level&255)/255.0;
for (i=0 ; i<w->numpoints ; i++)
{
fprintf (glview, "%6.3f %6.3f %6.3f %6.3f %6.3f %6.3f\n",
w->p[i][0],
w->p[i][1],
w->p[i][2],
light,
light,
light);
}
fprintf (glview, "\n");
}
/*
=============
OutputPortal
=============
*/
void OutputPortal (portal_t *p, FILE *glview)
{
winding_t *w;
int sides;
sides = PortalVisibleSides (p);
if (!sides)
return;
c_glfaces++;
w = p->winding;
if (sides == 2) // back side
w = ReverseWinding (w);
OutputWinding (w, glview);
if (sides == 2)
FreeWinding(w);
}
/*
=============
WriteGLView_r
=============
*/
void WriteGLView_r (node_t *node, FILE *glview)
{
portal_t *p, *nextp;
if (node->planenum != PLANENUM_LEAF)
{
WriteGLView_r (node->children[0], glview);
WriteGLView_r (node->children[1], glview);
return;
}
// write all the portals
for (p=node->portals ; p ; p=nextp)
{
if (p->nodes[0] == node)
{
OutputPortal (p, glview);
nextp = p->next[0];
}
else
nextp = p->next[1];
}
}
/*
=============
WriteGLView
=============
*/
void WriteGLView (tree_t *tree, char *source)
{
char name[1024];
FILE *glview;
c_glfaces = 0;
sprintf (name, "%s%s.gl",outbase, source);
printf ("Writing %s\n", name);
glview = fopen (name, "w");
if (!glview)
Error ("Couldn't open %s", name);
WriteGLView_r (tree->headnode, glview);
fclose (glview);
printf ("%5i c_glfaces\n", c_glfaces);
}

360
code/bspc/l_bsp_ent.c Normal file → Executable file
View file

@ -1,180 +1,180 @@
/*
===========================================================================
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 "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;
}
/*
===========================================================================
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 "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;
}

116
code/bspc/l_bsp_ent.h Normal file → Executable file
View file

@ -1,58 +1,58 @@
/*
===========================================================================
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 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);
/*
===========================================================================
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 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);

1776
code/bspc/l_bsp_hl.c Normal file → Executable file

File diff suppressed because it is too large Load diff

628
code/bspc/l_bsp_hl.h Normal file → Executable file
View file

@ -1,314 +1,314 @@
/*
===========================================================================
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
===========================================================================
*/
// 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
/*
===========================================================================
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
===========================================================================
*/
// 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

1240
code/bspc/l_bsp_q1.c Normal file → Executable file

File diff suppressed because it is too large Load diff

550
code/bspc/l_bsp_q1.h Normal file → Executable file
View file

@ -1,275 +1,275 @@
/*
===========================================================================
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
===========================================================================
*/
// 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
/*
===========================================================================
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
===========================================================================
*/
// 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

2268
code/bspc/l_bsp_q2.c Normal file → Executable file

File diff suppressed because it is too large Load diff

196
code/bspc/l_bsp_q2.h Normal file → Executable file
View file

@ -1,98 +1,98 @@
/*
===========================================================================
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 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);
/*
===========================================================================
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 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);

1648
code/bspc/l_bsp_q3.c Normal file → Executable file

File diff suppressed because it is too large Load diff

162
code/bspc/l_bsp_q3.h Normal file → Executable file
View file

@ -1,81 +1,81 @@
/*
===========================================================================
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 "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);
/*
===========================================================================
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 "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);

2372
code/bspc/l_bsp_sin.c Normal file → Executable file

File diff suppressed because it is too large Load diff

212
code/bspc/l_bsp_sin.h Normal file → Executable file
View file

@ -1,106 +1,106 @@
/*
===========================================================================
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 "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);
/*
===========================================================================
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 "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);

2460
code/bspc/l_cmd.c Normal file → Executable file

File diff suppressed because it is too large Load diff

314
code/bspc/l_cmd.h Normal file → Executable file
View file

@ -1,157 +1,157 @@
/*
===========================================================================
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
===========================================================================
*/
// cmdlib.h
#ifndef SIN
#define SIN
#endif //SIN
#ifndef __CMDLIB__
#define __CMDLIB__
#ifdef _WIN32
#pragma warning(disable : 4244) // MIPS
#pragma warning(disable : 4136) // X86
#pragma warning(disable : 4051) // ALPHA
#pragma warning(disable : 4018) // signed/unsigned mismatch
#pragma warning(disable : 4305) // truncate from double to float
#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <ctype.h>
#include <time.h>
#include <stdarg.h>
#ifndef __BYTEBOOL__
#define __BYTEBOOL__
typedef enum {false, true} qboolean;
typedef unsigned char byte;
#endif
// the dec offsetof macro doesnt work very well...
#define myoffsetof(type,identifier) ((size_t)&((type *)0)->identifier)
// set these before calling CheckParm
extern int myargc;
extern char **myargv;
char *strupr (char *in);
char *strlower (char *in);
int Q_strncasecmp (char *s1, char *s2, int n);
int Q_strcasecmp (char *s1, char *s2);
void Q_getwd (char *out);
int Q_filelength (FILE *f);
int FileTime (char *path);
void Q_mkdir (char *path);
extern char qdir[1024];
extern char gamedir[1024];
void SetQdirFromPath (char *path);
char *ExpandArg (char *path); // from cmd line
char *ExpandPath (char *path); // from scripts
char *ExpandPathAndArchive (char *path);
double I_FloatTime (void);
void Error(char *error, ...);
void Warning(char *warning, ...);
int CheckParm (char *check);
FILE *SafeOpenWrite (char *filename);
FILE *SafeOpenRead (char *filename);
void SafeRead (FILE *f, void *buffer, int count);
void SafeWrite (FILE *f, void *buffer, int count);
int LoadFile (char *filename, void **bufferptr, int offset, int length);
int TryLoadFile (char *filename, void **bufferptr);
void SaveFile (char *filename, void *buffer, int count);
qboolean FileExists (char *filename);
void DefaultExtension (char *path, char *extension);
void DefaultPath (char *path, char *basepath);
void StripFilename (char *path);
void StripExtension (char *path);
void ExtractFilePath (char *path, char *dest);
void ExtractFileBase (char *path, char *dest);
void ExtractFileExtension (char *path, char *dest);
int ParseNum (char *str);
short BigShort (short l);
short LittleShort (short l);
int BigLong (int l);
int LittleLong (int l);
float BigFloat (float l);
float LittleFloat (float l);
#ifdef SIN
unsigned short BigUnsignedShort (unsigned short l);
unsigned short LittleUnsignedShort (unsigned short l);
unsigned BigUnsigned (unsigned l);
unsigned LittleUnsigned (unsigned l);
#endif
char *COM_Parse (char *data);
extern char com_token[1024];
extern qboolean com_eof;
char *copystring(char *s);
void CRC_Init(unsigned short *crcvalue);
void CRC_ProcessByte(unsigned short *crcvalue, byte data);
unsigned short CRC_Value(unsigned short crcvalue);
void CreatePath (char *path);
void QCopyFile (char *from, char *to);
extern qboolean archive;
extern char archivedir[1024];
extern qboolean verbose;
void qprintf (char *format, ...);
void ExpandWildcards (int *argc, char ***argv);
// for compression routines
typedef struct
{
byte *data;
int count;
} cblock_t;
#endif
/*
===========================================================================
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
===========================================================================
*/
// cmdlib.h
#ifndef SIN
#define SIN
#endif //SIN
#ifndef __CMDLIB__
#define __CMDLIB__
#ifdef _WIN32
#pragma warning(disable : 4244) // MIPS
#pragma warning(disable : 4136) // X86
#pragma warning(disable : 4051) // ALPHA
#pragma warning(disable : 4018) // signed/unsigned mismatch
#pragma warning(disable : 4305) // truncate from double to float
#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <ctype.h>
#include <time.h>
#include <stdarg.h>
#ifndef __BYTEBOOL__
#define __BYTEBOOL__
typedef enum {false, true} qboolean;
typedef unsigned char byte;
#endif
// the dec offsetof macro doesnt work very well...
#define myoffsetof(type,identifier) ((size_t)&((type *)0)->identifier)
// set these before calling CheckParm
extern int myargc;
extern char **myargv;
char *strupr (char *in);
char *strlower (char *in);
int Q_strncasecmp (char *s1, char *s2, int n);
int Q_strcasecmp (char *s1, char *s2);
void Q_getwd (char *out);
int Q_filelength (FILE *f);
int FileTime (char *path);
void Q_mkdir (char *path);
extern char qdir[1024];
extern char gamedir[1024];
void SetQdirFromPath (char *path);
char *ExpandArg (char *path); // from cmd line
char *ExpandPath (char *path); // from scripts
char *ExpandPathAndArchive (char *path);
double I_FloatTime (void);
void Error(char *error, ...);
void Warning(char *warning, ...);
int CheckParm (char *check);
FILE *SafeOpenWrite (char *filename);
FILE *SafeOpenRead (char *filename);
void SafeRead (FILE *f, void *buffer, int count);
void SafeWrite (FILE *f, void *buffer, int count);
int LoadFile (char *filename, void **bufferptr, int offset, int length);
int TryLoadFile (char *filename, void **bufferptr);
void SaveFile (char *filename, void *buffer, int count);
qboolean FileExists (char *filename);
void DefaultExtension (char *path, char *extension);
void DefaultPath (char *path, char *basepath);
void StripFilename (char *path);
void StripExtension (char *path);
void ExtractFilePath (char *path, char *dest);
void ExtractFileBase (char *path, char *dest);
void ExtractFileExtension (char *path, char *dest);
int ParseNum (char *str);
short BigShort (short l);
short LittleShort (short l);
int BigLong (int l);
int LittleLong (int l);
float BigFloat (float l);
float LittleFloat (float l);
#ifdef SIN
unsigned short BigUnsignedShort (unsigned short l);
unsigned short LittleUnsignedShort (unsigned short l);
unsigned BigUnsigned (unsigned l);
unsigned LittleUnsigned (unsigned l);
#endif
char *COM_Parse (char *data);
extern char com_token[1024];
extern qboolean com_eof;
char *copystring(char *s);
void CRC_Init(unsigned short *crcvalue);
void CRC_ProcessByte(unsigned short *crcvalue, byte data);
unsigned short CRC_Value(unsigned short crcvalue);
void CreatePath (char *path);
void QCopyFile (char *from, char *to);
extern qboolean archive;
extern char archivedir[1024];
extern qboolean verbose;
void qprintf (char *format, ...);
void ExpandWildcards (int *argc, char ***argv);
// for compression routines
typedef struct
{
byte *data;
int count;
} cblock_t;
#endif

430
code/bspc/l_log.c Normal file → Executable file
View file

@ -1,215 +1,215 @@
/*
===========================================================================
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 <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "qbsp.h"
#define MAX_LOGFILENAMESIZE 1024
typedef struct logfile_s
{
char filename[MAX_LOGFILENAMESIZE];
FILE *fp;
int numwrites;
} logfile_t;
logfile_t logfile;
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void Log_Open(char *filename)
{
if (!filename || !strlen(filename))
{
printf("openlog <filename>\n");
return;
} //end if
if (logfile.fp)
{
printf("log file %s is already opened\n", logfile.filename);
return;
} //end if
logfile.fp = fopen(filename, "wb");
if (!logfile.fp)
{
printf("can't open the log file %s\n", filename);
return;
} //end if
strncpy(logfile.filename, filename, MAX_LOGFILENAMESIZE);
printf("Opened log %s\n", logfile.filename);
} //end of the function Log_Create
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void Log_Close(void)
{
if (!logfile.fp)
{
printf("no log file to close\n");
return;
} //end if
if (fclose(logfile.fp))
{
printf("can't close log file %s\n", logfile.filename);
return;
} //end if
logfile.fp = NULL;
printf("Closed log %s\n", logfile.filename);
} //end of the function Log_Close
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void Log_Shutdown(void)
{
if (logfile.fp) Log_Close();
} //end of the function Log_Shutdown
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void Log_UnifyEndOfLine(char *buf)
{
int i;
for (i = 0; buf[i]; i++)
{
if (buf[i] == '\n')
{
if (i <= 0 || buf[i-1] != '\r')
{
memmove(&buf[i+1], &buf[i], strlen(&buf[i])+1);
buf[i] = '\r';
i++;
} //end if
} //end if
} //end for
} //end of the function Log_UnifyEndOfLine
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void Log_Print(char *fmt, ...)
{
va_list ap;
char buf[2048];
va_start(ap, fmt);
vsprintf(buf, fmt, ap);
va_end(ap);
if (verbose)
{
#ifdef WINBSPC
WinBSPCPrint(buf);
#else
printf("%s", buf);
#endif //WINBSPS
} //end if
if (logfile.fp)
{
Log_UnifyEndOfLine(buf);
fprintf(logfile.fp, "%s", buf);
fflush(logfile.fp);
} //end if
} //end of the function Log_Print
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void Log_Write(char *fmt, ...)
{
va_list ap;
char buf[2048];
if (!logfile.fp) return;
va_start(ap, fmt);
vsprintf(buf, fmt, ap);
va_end(ap);
Log_UnifyEndOfLine(buf);
fprintf(logfile.fp, "%s", buf);
fflush(logfile.fp);
} //end of the function Log_Write
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void Log_WriteTimeStamped(char *fmt, ...)
{
va_list ap;
if (!logfile.fp) return;
/* fprintf(logfile.fp, "%d %02d:%02d:%02d:%02d ",
logfile.numwrites,
(int) (botlibglobals.time / 60 / 60),
(int) (botlibglobals.time / 60),
(int) (botlibglobals.time),
(int) ((int) (botlibglobals.time * 100)) -
((int) botlibglobals.time) * 100);*/
va_start(ap, fmt);
vfprintf(logfile.fp, fmt, ap);
va_end(ap);
logfile.numwrites++;
fflush(logfile.fp);
} //end of the function Log_Write
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
FILE *Log_FileStruct(void)
{
return logfile.fp;
} //end of the function Log_FileStruct
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void Log_Flush(void)
{
if (logfile.fp) fflush(logfile.fp);
} //end of the function Log_Flush
/*
===========================================================================
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 <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "qbsp.h"
#define MAX_LOGFILENAMESIZE 1024
typedef struct logfile_s
{
char filename[MAX_LOGFILENAMESIZE];
FILE *fp;
int numwrites;
} logfile_t;
logfile_t logfile;
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void Log_Open(char *filename)
{
if (!filename || !strlen(filename))
{
printf("openlog <filename>\n");
return;
} //end if
if (logfile.fp)
{
printf("log file %s is already opened\n", logfile.filename);
return;
} //end if
logfile.fp = fopen(filename, "wb");
if (!logfile.fp)
{
printf("can't open the log file %s\n", filename);
return;
} //end if
strncpy(logfile.filename, filename, MAX_LOGFILENAMESIZE);
printf("Opened log %s\n", logfile.filename);
} //end of the function Log_Create
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void Log_Close(void)
{
if (!logfile.fp)
{
printf("no log file to close\n");
return;
} //end if
if (fclose(logfile.fp))
{
printf("can't close log file %s\n", logfile.filename);
return;
} //end if
logfile.fp = NULL;
printf("Closed log %s\n", logfile.filename);
} //end of the function Log_Close
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void Log_Shutdown(void)
{
if (logfile.fp) Log_Close();
} //end of the function Log_Shutdown
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void Log_UnifyEndOfLine(char *buf)
{
int i;
for (i = 0; buf[i]; i++)
{
if (buf[i] == '\n')
{
if (i <= 0 || buf[i-1] != '\r')
{
memmove(&buf[i+1], &buf[i], strlen(&buf[i])+1);
buf[i] = '\r';
i++;
} //end if
} //end if
} //end for
} //end of the function Log_UnifyEndOfLine
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void Log_Print(char *fmt, ...)
{
va_list ap;
char buf[2048];
va_start(ap, fmt);
vsprintf(buf, fmt, ap);
va_end(ap);
if (verbose)
{
#ifdef WINBSPC
WinBSPCPrint(buf);
#else
printf("%s", buf);
#endif //WINBSPS
} //end if
if (logfile.fp)
{
Log_UnifyEndOfLine(buf);
fprintf(logfile.fp, "%s", buf);
fflush(logfile.fp);
} //end if
} //end of the function Log_Print
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void Log_Write(char *fmt, ...)
{
va_list ap;
char buf[2048];
if (!logfile.fp) return;
va_start(ap, fmt);
vsprintf(buf, fmt, ap);
va_end(ap);
Log_UnifyEndOfLine(buf);
fprintf(logfile.fp, "%s", buf);
fflush(logfile.fp);
} //end of the function Log_Write
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void Log_WriteTimeStamped(char *fmt, ...)
{
va_list ap;
if (!logfile.fp) return;
/* fprintf(logfile.fp, "%d %02d:%02d:%02d:%02d ",
logfile.numwrites,
(int) (botlibglobals.time / 60 / 60),
(int) (botlibglobals.time / 60),
(int) (botlibglobals.time),
(int) ((int) (botlibglobals.time * 100)) -
((int) botlibglobals.time) * 100);*/
va_start(ap, fmt);
vfprintf(logfile.fp, fmt, ap);
va_end(ap);
logfile.numwrites++;
fflush(logfile.fp);
} //end of the function Log_Write
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
FILE *Log_FileStruct(void)
{
return logfile.fp;
} //end of the function Log_FileStruct
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void Log_Flush(void)
{
if (logfile.fp) fflush(logfile.fp);
} //end of the function Log_Flush

84
code/bspc/l_log.h Normal file → Executable file
View file

@ -1,42 +1,42 @@
/*
===========================================================================
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
===========================================================================
*/
//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
/*
===========================================================================
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
===========================================================================
*/
//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

578
code/bspc/l_math.c Normal file → Executable file
View file

@ -1,289 +1,289 @@
/*
===========================================================================
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
===========================================================================
*/
// 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;
}
}
/*
===========================================================================
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
===========================================================================
*/
// 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;
}
}

186
code/bspc/l_math.h Normal file → Executable file
View file

@ -1,93 +1,93 @@
/*
===========================================================================
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 __MATHLIB__
#define __MATHLIB__
// mathlib.h
#include <math.h>
#ifdef DOUBLEVEC_T
typedef double vec_t;
#else
typedef float vec_t;
#endif
typedef vec_t vec3_t[3];
typedef vec_t vec4_t[4];
#define SIDE_FRONT 0
#define SIDE_ON 2
#define SIDE_BACK 1
#define SIDE_CROSS -2
#define PITCH 0
#define YAW 1
#define ROLL 2
#define Q_PI 3.14159265358979323846
#define DEG2RAD( a ) ( a * M_PI ) / 180.0F
#ifndef M_PI
#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h
#endif
extern vec3_t vec3_origin;
#define EQUAL_EPSILON 0.001
qboolean VectorCompare (vec3_t v1, vec3_t v2);
#define DotProduct(x,y) (x[0]*y[0]+x[1]*y[1]+x[2]*y[2])
#define VectorSubtract(a,b,c) {c[0]=a[0]-b[0];c[1]=a[1]-b[1];c[2]=a[2]-b[2];}
#define VectorAdd(a,b,c) {c[0]=a[0]+b[0];c[1]=a[1]+b[1];c[2]=a[2]+b[2];}
#define VectorCopy(a,b) {b[0]=a[0];b[1]=a[1];b[2]=a[2];}
#define Vector4Copy(a,b) {b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];}
#define VectorScale(v, s, o) ((o)[0]=(v)[0]*(s),(o)[1]=(v)[1]*(s),(o)[2]=(v)[2]*(s))
#define VectorClear(x) {x[0] = x[1] = x[2] = 0;}
#define VectorNegate(x, y) {y[0]=-x[0];y[1]=-x[1];y[2]=-x[2];}
#define VectorMA(v, s, b, o) ((o)[0]=(v)[0]+(b)[0]*(s),(o)[1]=(v)[1]+(b)[1]*(s),(o)[2]=(v)[2]+(b)[2]*(s))
vec_t Q_rint (vec_t in);
vec_t _DotProduct (vec3_t v1, vec3_t v2);
void _VectorSubtract (vec3_t va, vec3_t vb, vec3_t out);
void _VectorAdd (vec3_t va, vec3_t vb, vec3_t out);
void _VectorCopy (vec3_t in, vec3_t out);
void _VectorScale (vec3_t v, vec_t scale, vec3_t out);
void _VectorMA(vec3_t va, double scale, vec3_t vb, vec3_t vc);
double VectorLength(vec3_t v);
void CrossProduct(const vec3_t v1, const vec3_t v2, vec3_t cross);
vec_t VectorNormalize(vec3_t inout);
vec_t ColorNormalize(vec3_t in, vec3_t out);
vec_t VectorNormalize2(const vec3_t v, vec3_t out);
void VectorInverse (vec3_t v);
void ClearBounds (vec3_t mins, vec3_t maxs);
void AddPointToBounds (const vec3_t v, vec3_t mins, vec3_t maxs);
void AngleVectors (const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up);
void R_ConcatRotations (float in1[3][3], float in2[3][3], float out[3][3]);
void RotatePoint(vec3_t point, float matrix[3][3]);
void CreateRotationMatrix(vec3_t angles, float matrix[3][3]);
#endif
/*
===========================================================================
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 __MATHLIB__
#define __MATHLIB__
// mathlib.h
#include <math.h>
#ifdef DOUBLEVEC_T
typedef double vec_t;
#else
typedef float vec_t;
#endif
typedef vec_t vec3_t[3];
typedef vec_t vec4_t[4];
#define SIDE_FRONT 0
#define SIDE_ON 2
#define SIDE_BACK 1
#define SIDE_CROSS -2
#define PITCH 0
#define YAW 1
#define ROLL 2
#define Q_PI 3.14159265358979323846
#define DEG2RAD( a ) ( a * M_PI ) / 180.0F
#ifndef M_PI
#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h
#endif
extern vec3_t vec3_origin;
#define EQUAL_EPSILON 0.001
qboolean VectorCompare (vec3_t v1, vec3_t v2);
#define DotProduct(x,y) (x[0]*y[0]+x[1]*y[1]+x[2]*y[2])
#define VectorSubtract(a,b,c) {c[0]=a[0]-b[0];c[1]=a[1]-b[1];c[2]=a[2]-b[2];}
#define VectorAdd(a,b,c) {c[0]=a[0]+b[0];c[1]=a[1]+b[1];c[2]=a[2]+b[2];}
#define VectorCopy(a,b) {b[0]=a[0];b[1]=a[1];b[2]=a[2];}
#define Vector4Copy(a,b) {b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];}
#define VectorScale(v, s, o) ((o)[0]=(v)[0]*(s),(o)[1]=(v)[1]*(s),(o)[2]=(v)[2]*(s))
#define VectorClear(x) {x[0] = x[1] = x[2] = 0;}
#define VectorNegate(x, y) {y[0]=-x[0];y[1]=-x[1];y[2]=-x[2];}
#define VectorMA(v, s, b, o) ((o)[0]=(v)[0]+(b)[0]*(s),(o)[1]=(v)[1]+(b)[1]*(s),(o)[2]=(v)[2]+(b)[2]*(s))
vec_t Q_rint (vec_t in);
vec_t _DotProduct (vec3_t v1, vec3_t v2);
void _VectorSubtract (vec3_t va, vec3_t vb, vec3_t out);
void _VectorAdd (vec3_t va, vec3_t vb, vec3_t out);
void _VectorCopy (vec3_t in, vec3_t out);
void _VectorScale (vec3_t v, vec_t scale, vec3_t out);
void _VectorMA(vec3_t va, double scale, vec3_t vb, vec3_t vc);
double VectorLength(vec3_t v);
void CrossProduct(const vec3_t v1, const vec3_t v2, vec3_t cross);
vec_t VectorNormalize(vec3_t inout);
vec_t ColorNormalize(vec3_t in, vec3_t out);
vec_t VectorNormalize2(const vec3_t v, vec3_t out);
void VectorInverse (vec3_t v);
void ClearBounds (vec3_t mins, vec3_t maxs);
void AddPointToBounds (const vec3_t v, vec3_t mins, vec3_t maxs);
void AngleVectors (const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up);
void R_ConcatRotations (float in1[3][3], float in2[3][3], float out[3][3]);
void RotatePoint(vec3_t point, float matrix[3][3]);
void CreateRotationMatrix(vec3_t angles, float matrix[3][3]);
#endif

882
code/bspc/l_mem.c Normal file → Executable file
View file

@ -1,441 +1,441 @@
/*
===========================================================================
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 "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
/*
===========================================================================
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 "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

102
code/bspc/l_mem.h Normal file → Executable file
View file

@ -1,51 +1,51 @@
/*
===========================================================================
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
===========================================================================
*/
//=============================================================================
// 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);
/*
===========================================================================
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
===========================================================================
*/
//=============================================================================
// 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);

2822
code/bspc/l_poly.c Normal file → Executable file

File diff suppressed because it is too large Load diff

240
code/bspc/l_poly.h Normal file → Executable file
View file

@ -1,120 +1,120 @@
/*
===========================================================================
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
===========================================================================
*/
//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
/*
===========================================================================
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
===========================================================================
*/
//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

1326
code/bspc/l_qfiles.c Normal file → Executable file

File diff suppressed because it is too large Load diff

182
code/bspc/l_qfiles.h Normal file → Executable file
View file

@ -1,91 +1,91 @@
/*
===========================================================================
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 "../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);
/*
===========================================================================
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 "../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);

3020
code/bspc/l_threads.c Normal file → Executable file

File diff suppressed because it is too large Load diff

90
code/bspc/l_threads.h Normal file → Executable file
View file

@ -1,45 +1,45 @@
/*
===========================================================================
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
===========================================================================
*/
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);
/*
===========================================================================
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
===========================================================================
*/
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);

518
code/bspc/l_utils.c Normal file → Executable file
View file

@ -1,259 +1,259 @@
/*
===========================================================================
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 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
/*
===========================================================================
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 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

158
code/bspc/l_utils.h Normal file → Executable file
View file

@ -1,79 +1,79 @@
/*
===========================================================================
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 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
/*
===========================================================================
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 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

122
code/bspc/lcc.mak Normal file → Executable file
View file

@ -1,61 +1,61 @@
#
# 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) $<
#
# 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) $<

202
code/bspc/leakfile.c Normal file → Executable file
View file

@ -1,101 +1,101 @@
/*
===========================================================================
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 "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);
}
/*
===========================================================================
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 "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);
}

218
code/bspc/linux-i386.mak Normal file → Executable file
View file

@ -1,109 +1,109 @@
#
# 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"
#
#
# 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"
#

2534
code/bspc/map.c Normal file → Executable file

File diff suppressed because it is too large Load diff

2228
code/bspc/map_hl.c Normal file → Executable file

File diff suppressed because it is too large Load diff

2348
code/bspc/map_q1.c Normal file → Executable file

File diff suppressed because it is too large Load diff

2324
code/bspc/map_q2.c Normal file → Executable file

File diff suppressed because it is too large Load diff

1362
code/bspc/map_q3.c Normal file → Executable file

File diff suppressed because it is too large Load diff

2422
code/bspc/map_sin.c Normal file → Executable file

File diff suppressed because it is too large Load diff

94
code/bspc/nodraw.c Normal file → Executable file
View file

@ -1,47 +1,47 @@
/*
===========================================================================
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 "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)
{
}
/*
===========================================================================
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 "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)
{
}

2594
code/bspc/portals.c Normal file → Executable file

File diff suppressed because it is too large Load diff

574
code/bspc/prtfile.c Normal file → Executable file
View file

@ -1,287 +1,287 @@
/*
===========================================================================
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 "qbsp.h"
/*
==============================================================================
PORTAL FILE GENERATION
Save out name.prt for qvis to read
==============================================================================
*/
#define PORTALFILE "PRT1"
FILE *pf;
int num_visclusters; // clusters the player can be in
int num_visportals;
void WriteFloat2 (FILE *f, vec_t v)
{
if ( fabs(v - Q_rint(v)) < 0.001 )
fprintf (f,"%i ",(int)Q_rint(v));
else
fprintf (f,"%f ",v);
}
/*
=================
WritePortalFile_r
=================
*/
void WritePortalFile_r (node_t *node)
{
int i, s;
portal_t *p;
winding_t *w;
vec3_t normal;
vec_t dist;
// decision node
if (node->planenum != PLANENUM_LEAF && !node->detail_seperator)
{
WritePortalFile_r (node->children[0]);
WritePortalFile_r (node->children[1]);
return;
}
if (node->contents & CONTENTS_SOLID)
return;
for (p = node->portals ; p ; p=p->next[s])
{
w = p->winding;
s = (p->nodes[1] == node);
if (w && p->nodes[0] == node)
{
if (!Portal_VisFlood (p))
continue;
// write out to the file
// sometimes planes get turned around when they are very near
// the changeover point between different axis. interpret the
// plane the same way vis will, and flip the side orders if needed
// FIXME: is this still relevent?
WindingPlane (w, normal, &dist);
if ( DotProduct (p->plane.normal, normal) < 0.99 )
{ // backwards...
fprintf (pf,"%i %i %i ",w->numpoints, p->nodes[1]->cluster, p->nodes[0]->cluster);
}
else
fprintf (pf,"%i %i %i ",w->numpoints, p->nodes[0]->cluster, p->nodes[1]->cluster);
for (i=0 ; i<w->numpoints ; i++)
{
fprintf (pf,"(");
WriteFloat2 (pf, w->p[i][0]);
WriteFloat2 (pf, w->p[i][1]);
WriteFloat2 (pf, w->p[i][2]);
fprintf (pf,") ");
}
fprintf (pf,"\n");
}
}
}
/*
================
FillLeafNumbers_r
All of the leafs under node will have the same cluster
================
*/
void FillLeafNumbers_r (node_t *node, int num)
{
if (node->planenum == PLANENUM_LEAF)
{
if (node->contents & CONTENTS_SOLID)
node->cluster = -1;
else
node->cluster = num;
return;
}
node->cluster = num;
FillLeafNumbers_r (node->children[0], num);
FillLeafNumbers_r (node->children[1], num);
}
/*
================
NumberLeafs_r
================
*/
void NumberLeafs_r (node_t *node)
{
portal_t *p;
if (node->planenum != PLANENUM_LEAF && !node->detail_seperator)
{ // decision node
node->cluster = -99;
NumberLeafs_r (node->children[0]);
NumberLeafs_r (node->children[1]);
return;
}
// either a leaf or a detail cluster
if ( node->contents & CONTENTS_SOLID )
{ // solid block, viewpoint never inside
node->cluster = -1;
return;
}
FillLeafNumbers_r (node, num_visclusters);
num_visclusters++;
// count the portals
for (p = node->portals ; p ; )
{
if (p->nodes[0] == node) // only write out from first leaf
{
if (Portal_VisFlood (p))
num_visportals++;
p = p->next[0];
}
else
p = p->next[1];
}
}
/*
================
CreateVisPortals_r
================
*/
void CreateVisPortals_r (node_t *node)
{
// stop as soon as we get to a detail_seperator, which
// means that everything below is in a single cluster
if (node->planenum == PLANENUM_LEAF || node->detail_seperator )
return;
MakeNodePortal (node);
SplitNodePortals (node);
CreateVisPortals_r (node->children[0]);
CreateVisPortals_r (node->children[1]);
}
/*
================
FinishVisPortals_r
================
*/
void FinishVisPortals2_r (node_t *node)
{
if (node->planenum == PLANENUM_LEAF)
return;
MakeNodePortal (node);
SplitNodePortals (node);
FinishVisPortals2_r (node->children[0]);
FinishVisPortals2_r (node->children[1]);
}
void FinishVisPortals_r (node_t *node)
{
if (node->planenum == PLANENUM_LEAF)
return;
if (node->detail_seperator)
{
FinishVisPortals2_r (node);
return;
}
FinishVisPortals_r (node->children[0]);
FinishVisPortals_r (node->children[1]);
}
int clusterleaf;
void SaveClusters_r (node_t *node)
{
if (node->planenum == PLANENUM_LEAF)
{
dleafs[clusterleaf++].cluster = node->cluster;
return;
}
SaveClusters_r (node->children[0]);
SaveClusters_r (node->children[1]);
}
/*
================
WritePortalFile
================
*/
void WritePortalFile (tree_t *tree)
{
char filename[1024];
node_t *headnode;
qprintf ("--- WritePortalFile ---\n");
headnode = tree->headnode;
num_visclusters = 0;
num_visportals = 0;
Tree_FreePortals_r (headnode);
MakeHeadnodePortals (tree);
CreateVisPortals_r (headnode);
// set the cluster field in every leaf and count the total number of portals
NumberLeafs_r (headnode);
// write the file
sprintf (filename, "%s.prt", source);
printf ("writing %s\n", filename);
pf = fopen (filename, "w");
if (!pf)
Error ("Error opening %s", filename);
fprintf (pf, "%s\n", PORTALFILE);
fprintf (pf, "%i\n", num_visclusters);
fprintf (pf, "%i\n", num_visportals);
qprintf ("%5i visclusters\n", num_visclusters);
qprintf ("%5i visportals\n", num_visportals);
WritePortalFile_r (headnode);
fclose (pf);
// we need to store the clusters out now because ordering
// issues made us do this after writebsp...
clusterleaf = 1;
SaveClusters_r (headnode);
}
/*
===========================================================================
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 "qbsp.h"
/*
==============================================================================
PORTAL FILE GENERATION
Save out name.prt for qvis to read
==============================================================================
*/
#define PORTALFILE "PRT1"
FILE *pf;
int num_visclusters; // clusters the player can be in
int num_visportals;
void WriteFloat2 (FILE *f, vec_t v)
{
if ( fabs(v - Q_rint(v)) < 0.001 )
fprintf (f,"%i ",(int)Q_rint(v));
else
fprintf (f,"%f ",v);
}
/*
=================
WritePortalFile_r
=================
*/
void WritePortalFile_r (node_t *node)
{
int i, s;
portal_t *p;
winding_t *w;
vec3_t normal;
vec_t dist;
// decision node
if (node->planenum != PLANENUM_LEAF && !node->detail_seperator)
{
WritePortalFile_r (node->children[0]);
WritePortalFile_r (node->children[1]);
return;
}
if (node->contents & CONTENTS_SOLID)
return;
for (p = node->portals ; p ; p=p->next[s])
{
w = p->winding;
s = (p->nodes[1] == node);
if (w && p->nodes[0] == node)
{
if (!Portal_VisFlood (p))
continue;
// write out to the file
// sometimes planes get turned around when they are very near
// the changeover point between different axis. interpret the
// plane the same way vis will, and flip the side orders if needed
// FIXME: is this still relevent?
WindingPlane (w, normal, &dist);
if ( DotProduct (p->plane.normal, normal) < 0.99 )
{ // backwards...
fprintf (pf,"%i %i %i ",w->numpoints, p->nodes[1]->cluster, p->nodes[0]->cluster);
}
else
fprintf (pf,"%i %i %i ",w->numpoints, p->nodes[0]->cluster, p->nodes[1]->cluster);
for (i=0 ; i<w->numpoints ; i++)
{
fprintf (pf,"(");
WriteFloat2 (pf, w->p[i][0]);
WriteFloat2 (pf, w->p[i][1]);
WriteFloat2 (pf, w->p[i][2]);
fprintf (pf,") ");
}
fprintf (pf,"\n");
}
}
}
/*
================
FillLeafNumbers_r
All of the leafs under node will have the same cluster
================
*/
void FillLeafNumbers_r (node_t *node, int num)
{
if (node->planenum == PLANENUM_LEAF)
{
if (node->contents & CONTENTS_SOLID)
node->cluster = -1;
else
node->cluster = num;
return;
}
node->cluster = num;
FillLeafNumbers_r (node->children[0], num);
FillLeafNumbers_r (node->children[1], num);
}
/*
================
NumberLeafs_r
================
*/
void NumberLeafs_r (node_t *node)
{
portal_t *p;
if (node->planenum != PLANENUM_LEAF && !node->detail_seperator)
{ // decision node
node->cluster = -99;
NumberLeafs_r (node->children[0]);
NumberLeafs_r (node->children[1]);
return;
}
// either a leaf or a detail cluster
if ( node->contents & CONTENTS_SOLID )
{ // solid block, viewpoint never inside
node->cluster = -1;
return;
}
FillLeafNumbers_r (node, num_visclusters);
num_visclusters++;
// count the portals
for (p = node->portals ; p ; )
{
if (p->nodes[0] == node) // only write out from first leaf
{
if (Portal_VisFlood (p))
num_visportals++;
p = p->next[0];
}
else
p = p->next[1];
}
}
/*
================
CreateVisPortals_r
================
*/
void CreateVisPortals_r (node_t *node)
{
// stop as soon as we get to a detail_seperator, which
// means that everything below is in a single cluster
if (node->planenum == PLANENUM_LEAF || node->detail_seperator )
return;
MakeNodePortal (node);
SplitNodePortals (node);
CreateVisPortals_r (node->children[0]);
CreateVisPortals_r (node->children[1]);
}
/*
================
FinishVisPortals_r
================
*/
void FinishVisPortals2_r (node_t *node)
{
if (node->planenum == PLANENUM_LEAF)
return;
MakeNodePortal (node);
SplitNodePortals (node);
FinishVisPortals2_r (node->children[0]);
FinishVisPortals2_r (node->children[1]);
}
void FinishVisPortals_r (node_t *node)
{
if (node->planenum == PLANENUM_LEAF)
return;
if (node->detail_seperator)
{
FinishVisPortals2_r (node);
return;
}
FinishVisPortals_r (node->children[0]);
FinishVisPortals_r (node->children[1]);
}
int clusterleaf;
void SaveClusters_r (node_t *node)
{
if (node->planenum == PLANENUM_LEAF)
{
dleafs[clusterleaf++].cluster = node->cluster;
return;
}
SaveClusters_r (node->children[0]);
SaveClusters_r (node->children[1]);
}
/*
================
WritePortalFile
================
*/
void WritePortalFile (tree_t *tree)
{
char filename[1024];
node_t *headnode;
qprintf ("--- WritePortalFile ---\n");
headnode = tree->headnode;
num_visclusters = 0;
num_visportals = 0;
Tree_FreePortals_r (headnode);
MakeHeadnodePortals (tree);
CreateVisPortals_r (headnode);
// set the cluster field in every leaf and count the total number of portals
NumberLeafs_r (headnode);
// write the file
sprintf (filename, "%s.prt", source);
printf ("writing %s\n", filename);
pf = fopen (filename, "w");
if (!pf)
Error ("Error opening %s", filename);
fprintf (pf, "%s\n", PORTALFILE);
fprintf (pf, "%i\n", num_visclusters);
fprintf (pf, "%i\n", num_visportals);
qprintf ("%5i visclusters\n", num_visclusters);
qprintf ("%5i visportals\n", num_visportals);
WritePortalFile_r (headnode);
fclose (pf);
// we need to store the clusters out now because ordering
// issues made us do this after writebsp...
clusterleaf = 1;
SaveClusters_r (headnode);
}

974
code/bspc/q2files.h Normal file → Executable file
View file

@ -1,487 +1,487 @@
/*
===========================================================================
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
===========================================================================
*/
//
// 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;
/*
===========================================================================
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
===========================================================================
*/
//
// 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;

748
code/bspc/q3files.h Normal file → Executable file
View file

@ -1,374 +1,374 @@
/*
===========================================================================
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 __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
/*
===========================================================================
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 __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

954
code/bspc/qbsp.h Normal file → Executable file
View file

@ -1,477 +1,477 @@
/*
===========================================================================
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
===========================================================================
*/
#if defined(WIN32) || defined(_WIN32)
#include <io.h>
#endif
#include <malloc.h>
#include "l_cmd.h"
#include "l_math.h"
#include "l_poly.h"
#include "l_threads.h"
#include "../botlib/l_script.h"
#include "l_bsp_ent.h"
#include "q2files.h"
#include "l_mem.h"
#include "l_utils.h"
#include "l_log.h"
#include "l_qfiles.h"
#define BSPC_VERSION "2.1h"
#define ME
#define DEBUG
#define NODELIST
#define SIN
#define MAX_BRUSH_SIDES 128 //maximum number of sides per brush
#define CLIP_EPSILON 0.1
#define MAX_MAP_BOUNDS 65535
#define BOGUS_RANGE (MAX_MAP_BOUNDS+128) //somewhere outside the map
#define TEXINFO_NODE -1 //side is allready on a node
#define PLANENUM_LEAF -1 //used for leaf nodes
#define MAXEDGES 20 //maximum number of face edges
#define MAX_NODE_BRUSHES 8 //maximum brushes in a node
//side flags
#define SFL_TESTED 1
#define SFL_VISIBLE 2
#define SFL_BEVEL 4
#define SFL_TEXTURED 8
#define SFL_CURVE 16
//map plane
typedef struct plane_s
{
vec3_t normal;
vec_t dist;
int type;
int signbits;
struct plane_s *hash_chain;
} plane_t;
//brush texture
typedef struct
{
vec_t shift[2];
vec_t rotate;
vec_t scale[2];
char name[32];
int flags;
int value;
} brush_texture_t;
//brush side
typedef struct side_s
{
int planenum; // map plane this side is in
int texinfo; // texture reference
winding_t *winding; // winding of this side
struct side_s *original; // bspbrush_t sides will reference the mapbrush_t sides
int lightinfo; // for SIN only
int contents; // from miptex
int surf; // from miptex
unsigned short flags; // side flags
} side_t; //sizeof(side_t) = 36
//map brush
typedef struct mapbrush_s
{
int entitynum;
int brushnum;
int contents;
#ifdef ME
int expansionbbox; //bbox used for expansion of the brush
int leafnum;
int modelnum;
#endif
vec3_t mins, maxs;
int numsides;
side_t *original_sides;
} mapbrush_t;
//bsp face
typedef struct face_s
{
struct face_s *next; // on node
// the chain of faces off of a node can be merged or split,
// but each face_t along the way will remain in the chain
// until the entire tree is freed
struct face_s *merged; // if set, this face isn't valid anymore
struct face_s *split[2]; // if set, this face isn't valid anymore
struct portal_s *portal;
int texinfo;
#ifdef SIN
int lightinfo;
#endif
int planenum;
int contents; // faces in different contents can't merge
int outputnumber;
winding_t *w;
int numpoints;
qboolean badstartvert; // tjunctions cannot be fixed without a midpoint vertex
int vertexnums[MAXEDGES];
} face_t;
//bsp brush
typedef struct bspbrush_s
{
struct bspbrush_s *next;
vec3_t mins, maxs;
int side, testside; // side of node during construction
mapbrush_t *original;
int numsides;
side_t sides[6]; // variably sized
} bspbrush_t; //sizeof(bspbrush_t) = 44 + numsides * sizeof(side_t)
//bsp node
typedef struct node_s
{
//both leafs and nodes
int planenum; // -1 = leaf node
struct node_s *parent;
vec3_t mins, maxs; // valid after portalization
bspbrush_t *volume; // one for each leaf/node
// nodes only
qboolean detail_seperator; // a detail brush caused the split
side_t *side; // the side that created the node
struct node_s *children[2];
face_t *faces;
// leafs only
bspbrush_t *brushlist; // fragments of all brushes in this leaf
int contents; // OR of all brush contents
int occupied; // 1 or greater can reach entity
entity_t *occupant; // for leak file testing
int cluster; // for portalfile writing
int area; // for areaportals
struct portal_s *portals; // also on nodes during construction
#ifdef NODELIST
struct node_s *next; //next node in the nodelist
#endif
#ifdef ME
int expansionbboxes; //OR of all bboxes used for expansion of the brushes
int modelnum;
#endif
} node_t; //sizeof(node_t) = 80 bytes
//bsp portal
typedef struct portal_s
{
plane_t plane;
node_t *onnode; // NULL = outside box
node_t *nodes[2]; // [0] = front side of plane
struct portal_s *next[2];
winding_t *winding;
qboolean sidefound; // false if ->side hasn't been checked
side_t *side; // NULL = non-visible
face_t *face[2]; // output face in bsp file
#ifdef ME
struct tmp_face_s *tmpface; //pointer to the tmpface created for this portal
int planenum; //number of the map plane used by the portal
#endif
} portal_t;
//bsp tree
typedef struct
{
node_t *headnode;
node_t outside_node;
vec3_t mins, maxs;
} tree_t;
//=============================================================================
// bspc.c
//=============================================================================
extern qboolean noprune;
extern qboolean nodetail;
extern qboolean fulldetail;
extern qboolean nomerge;
extern qboolean nosubdiv;
extern qboolean nowater;
extern qboolean noweld;
extern qboolean noshare;
extern qboolean notjunc;
extern qboolean onlyents;
#ifdef ME
extern qboolean nocsg;
extern qboolean create_aas;
extern qboolean freetree;
extern qboolean lessbrushes;
extern qboolean nobrushmerge;
extern qboolean cancelconversion;
extern qboolean noliquids;
extern qboolean capsule_collision;
#endif //ME
extern float subdivide_size;
extern vec_t microvolume;
extern char outbase[32];
extern char source[1024];
//=============================================================================
// map.c
//=============================================================================
#define MAX_MAPFILE_PLANES 256000
#define MAX_MAPFILE_BRUSHES 65535
#define MAX_MAPFILE_BRUSHSIDES (MAX_MAPFILE_BRUSHES*8)
#define MAX_MAPFILE_TEXINFO 8192
extern int entity_num;
extern plane_t mapplanes[MAX_MAPFILE_PLANES];
extern int nummapplanes;
extern int mapplaneusers[MAX_MAPFILE_PLANES];
extern int nummapbrushes;
extern mapbrush_t mapbrushes[MAX_MAPFILE_BRUSHES];
extern vec3_t map_mins, map_maxs;
extern int nummapbrushsides;
extern side_t brushsides[MAX_MAPFILE_BRUSHSIDES];
extern brush_texture_t side_brushtextures[MAX_MAPFILE_BRUSHSIDES];
#ifdef ME
typedef struct
{
float vecs[2][4]; // [s/t][xyz offset]
int flags; // miptex flags + overrides
int value;
char texture[64]; // texture name (textures/*.wal)
int nexttexinfo; // for animations, -1 = end of chain
} map_texinfo_t;
extern map_texinfo_t map_texinfo[MAX_MAPFILE_TEXINFO];
extern int map_numtexinfo;
#define NODESTACKSIZE 1024
#define MAPTYPE_QUAKE1 1
#define MAPTYPE_QUAKE2 2
#define MAPTYPE_QUAKE3 3
#define MAPTYPE_HALFLIFE 4
#define MAPTYPE_SIN 5
extern int nodestack[NODESTACKSIZE];
extern int *nodestackptr;
extern int nodestacksize;
extern int brushmodelnumbers[MAX_MAPFILE_BRUSHES];
extern int dbrushleafnums[MAX_MAPFILE_BRUSHES];
extern int dplanes2mapplanes[MAX_MAPFILE_PLANES];
extern int loadedmaptype;
#endif //ME
extern int c_boxbevels;
extern int c_edgebevels;
extern int c_areaportals;
extern int c_clipbrushes;
extern int c_squattbrushes;
//finds a float plane for the given normal and distance
int FindFloatPlane(vec3_t normal, vec_t dist);
//returns the plane type for the given normal
int PlaneTypeForNormal(vec3_t normal);
//returns the plane defined by the three given points
int PlaneFromPoints(int *p0, int *p1, int *p2);
//add bevels to the map brush
void AddBrushBevels(mapbrush_t *b);
//makes brush side windings for the brush
qboolean MakeBrushWindings(mapbrush_t *ob);
//marks brush bevels of the brush as bevel
void MarkBrushBevels(mapbrush_t *brush);
//returns true if the map brush already exists
int BrushExists(mapbrush_t *brush);
//loads a map from a bsp file
int LoadMapFromBSP(struct quakefile_s *qf);
//resets map loading
void ResetMapLoading(void);
//print some map info
void PrintMapInfo(void);
//writes a map file (type depending on loaded map type)
void WriteMapFile(char *filename);
//=============================================================================
// map_q2.c
//=============================================================================
void Q2_ResetMapLoading(void);
//loads a Quake2 map file
void Q2_LoadMapFile(char *filename);
//loads a map from a Quake2 bsp file
void Q2_LoadMapFromBSP(char *filename, int offset, int length);
//=============================================================================
// map_q1.c
//=============================================================================
void Q1_ResetMapLoading(void);
//loads a Quake2 map file
void Q1_LoadMapFile(char *filename);
//loads a map from a Quake1 bsp file
void Q1_LoadMapFromBSP(char *filename, int offset, int length);
//=============================================================================
// map_q3.c
//=============================================================================
void Q3_ResetMapLoading(void);
//loads a map from a Quake3 bsp file
void Q3_LoadMapFromBSP(struct quakefile_s *qf);
//=============================================================================
// map_sin.c
//=============================================================================
void Sin_ResetMapLoading(void);
//loads a Sin map file
void Sin_LoadMapFile(char *filename);
//loads a map from a Sin bsp file
void Sin_LoadMapFromBSP(char *filename, int offset, int length);
//=============================================================================
// map_hl.c
//=============================================================================
void HL_ResetMapLoading(void);
//loads a Half-Life map file
void HL_LoadMapFile(char *filename);
//loads a map from a Half-Life bsp file
void HL_LoadMapFromBSP(char *filename, int offset, int length);
//=============================================================================
// textures.c
//=============================================================================
typedef struct
{
char name[64];
int flags;
int value;
int contents;
char animname[64];
} textureref_t;
#define MAX_MAP_TEXTURES 1024
extern textureref_t textureref[MAX_MAP_TEXTURES];
int FindMiptex(char *name);
int TexinfoForBrushTexture(plane_t *plane, brush_texture_t *bt, vec3_t origin);
void TextureAxisFromPlane(plane_t *pln, vec3_t xv, vec3_t yv);
//=============================================================================
// csg
//=============================================================================
bspbrush_t *MakeBspBrushList(int startbrush, int endbrush, vec3_t clipmins, vec3_t clipmaxs);
bspbrush_t *ChopBrushes(bspbrush_t *head);
bspbrush_t *InitialBrushList(bspbrush_t *list);
bspbrush_t *OptimizedBrushList(bspbrush_t *list);
void WriteBrushMap(char *name, bspbrush_t *list);
void CheckBSPBrush(bspbrush_t *brush);
void BSPBrushWindings(bspbrush_t *brush);
bspbrush_t *TryMergeBrushes(bspbrush_t *brush1, bspbrush_t *brush2);
tree_t *ProcessWorldBrushes(int brush_start, int brush_end);
//=============================================================================
// brushbsp
//=============================================================================
#define PSIDE_FRONT 1
#define PSIDE_BACK 2
#define PSIDE_BOTH (PSIDE_FRONT|PSIDE_BACK)
#define PSIDE_FACING 4
void WriteBrushList(char *name, bspbrush_t *brush, qboolean onlyvis);
bspbrush_t *CopyBrush(bspbrush_t *brush);
void SplitBrush(bspbrush_t *brush, int planenum, bspbrush_t **front, bspbrush_t **back);
node_t *AllocNode(void);
bspbrush_t *AllocBrush(int numsides);
int CountBrushList(bspbrush_t *brushes);
void FreeBrush(bspbrush_t *brushes);
vec_t BrushVolume(bspbrush_t *brush);
void BoundBrush(bspbrush_t *brush);
void FreeBrushList(bspbrush_t *brushes);
tree_t *BrushBSP(bspbrush_t *brushlist, vec3_t mins, vec3_t maxs);
bspbrush_t *BrushFromBounds(vec3_t mins, vec3_t maxs);
int BrushMostlyOnSide(bspbrush_t *brush, plane_t *plane);
qboolean WindingIsHuge(winding_t *w);
qboolean WindingIsTiny(winding_t *w);
void ResetBrushBSP(void);
//=============================================================================
// portals.c
//=============================================================================
int VisibleContents (int contents);
void MakeHeadnodePortals (tree_t *tree);
void MakeNodePortal (node_t *node);
void SplitNodePortals (node_t *node);
qboolean Portal_VisFlood (portal_t *p);
qboolean FloodEntities (tree_t *tree);
void FillOutside (node_t *headnode);
void FloodAreas (tree_t *tree);
void MarkVisibleSides (tree_t *tree, int start, int end);
void FreePortal (portal_t *p);
void EmitAreaPortals (node_t *headnode);
void MakeTreePortals (tree_t *tree);
//=============================================================================
// glfile.c
//=============================================================================
void OutputWinding(winding_t *w, FILE *glview);
void WriteGLView(tree_t *tree, char *source);
//=============================================================================
// gldraw.c
//=============================================================================
extern vec3_t draw_mins, draw_maxs;
extern qboolean drawflag;
void Draw_ClearWindow (void);
void DrawWinding (winding_t *w);
void GLS_BeginScene (void);
void GLS_Winding (winding_t *w, int code);
void GLS_EndScene (void);
//=============================================================================
// leakfile.c
//=============================================================================
void LeakFile (tree_t *tree);
//=============================================================================
// tree.c
//=============================================================================
tree_t *Tree_Alloc(void);
void Tree_Free(tree_t *tree);
void Tree_Free_r(node_t *node);
void Tree_Print_r(node_t *node, int depth);
void Tree_FreePortals_r(node_t *node);
void Tree_PruneNodes_r(node_t *node);
void Tree_PruneNodes(node_t *node);
/*
===========================================================================
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
===========================================================================
*/
#if defined(WIN32) || defined(_WIN32)
#include <io.h>
#endif
#include <malloc.h>
#include "l_cmd.h"
#include "l_math.h"
#include "l_poly.h"
#include "l_threads.h"
#include "../botlib/l_script.h"
#include "l_bsp_ent.h"
#include "q2files.h"
#include "l_mem.h"
#include "l_utils.h"
#include "l_log.h"
#include "l_qfiles.h"
#define BSPC_VERSION "2.1h"
#define ME
#define DEBUG
#define NODELIST
#define SIN
#define MAX_BRUSH_SIDES 128 //maximum number of sides per brush
#define CLIP_EPSILON 0.1
#define MAX_MAP_BOUNDS 65535
#define BOGUS_RANGE (MAX_MAP_BOUNDS+128) //somewhere outside the map
#define TEXINFO_NODE -1 //side is allready on a node
#define PLANENUM_LEAF -1 //used for leaf nodes
#define MAXEDGES 20 //maximum number of face edges
#define MAX_NODE_BRUSHES 8 //maximum brushes in a node
//side flags
#define SFL_TESTED 1
#define SFL_VISIBLE 2
#define SFL_BEVEL 4
#define SFL_TEXTURED 8
#define SFL_CURVE 16
//map plane
typedef struct plane_s
{
vec3_t normal;
vec_t dist;
int type;
int signbits;
struct plane_s *hash_chain;
} plane_t;
//brush texture
typedef struct
{
vec_t shift[2];
vec_t rotate;
vec_t scale[2];
char name[32];
int flags;
int value;
} brush_texture_t;
//brush side
typedef struct side_s
{
int planenum; // map plane this side is in
int texinfo; // texture reference
winding_t *winding; // winding of this side
struct side_s *original; // bspbrush_t sides will reference the mapbrush_t sides
int lightinfo; // for SIN only
int contents; // from miptex
int surf; // from miptex
unsigned short flags; // side flags
} side_t; //sizeof(side_t) = 36
//map brush
typedef struct mapbrush_s
{
int entitynum;
int brushnum;
int contents;
#ifdef ME
int expansionbbox; //bbox used for expansion of the brush
int leafnum;
int modelnum;
#endif
vec3_t mins, maxs;
int numsides;
side_t *original_sides;
} mapbrush_t;
//bsp face
typedef struct face_s
{
struct face_s *next; // on node
// the chain of faces off of a node can be merged or split,
// but each face_t along the way will remain in the chain
// until the entire tree is freed
struct face_s *merged; // if set, this face isn't valid anymore
struct face_s *split[2]; // if set, this face isn't valid anymore
struct portal_s *portal;
int texinfo;
#ifdef SIN
int lightinfo;
#endif
int planenum;
int contents; // faces in different contents can't merge
int outputnumber;
winding_t *w;
int numpoints;
qboolean badstartvert; // tjunctions cannot be fixed without a midpoint vertex
int vertexnums[MAXEDGES];
} face_t;
//bsp brush
typedef struct bspbrush_s
{
struct bspbrush_s *next;
vec3_t mins, maxs;
int side, testside; // side of node during construction
mapbrush_t *original;
int numsides;
side_t sides[6]; // variably sized
} bspbrush_t; //sizeof(bspbrush_t) = 44 + numsides * sizeof(side_t)
//bsp node
typedef struct node_s
{
//both leafs and nodes
int planenum; // -1 = leaf node
struct node_s *parent;
vec3_t mins, maxs; // valid after portalization
bspbrush_t *volume; // one for each leaf/node
// nodes only
qboolean detail_seperator; // a detail brush caused the split
side_t *side; // the side that created the node
struct node_s *children[2];
face_t *faces;
// leafs only
bspbrush_t *brushlist; // fragments of all brushes in this leaf
int contents; // OR of all brush contents
int occupied; // 1 or greater can reach entity
entity_t *occupant; // for leak file testing
int cluster; // for portalfile writing
int area; // for areaportals
struct portal_s *portals; // also on nodes during construction
#ifdef NODELIST
struct node_s *next; //next node in the nodelist
#endif
#ifdef ME
int expansionbboxes; //OR of all bboxes used for expansion of the brushes
int modelnum;
#endif
} node_t; //sizeof(node_t) = 80 bytes
//bsp portal
typedef struct portal_s
{
plane_t plane;
node_t *onnode; // NULL = outside box
node_t *nodes[2]; // [0] = front side of plane
struct portal_s *next[2];
winding_t *winding;
qboolean sidefound; // false if ->side hasn't been checked
side_t *side; // NULL = non-visible
face_t *face[2]; // output face in bsp file
#ifdef ME
struct tmp_face_s *tmpface; //pointer to the tmpface created for this portal
int planenum; //number of the map plane used by the portal
#endif
} portal_t;
//bsp tree
typedef struct
{
node_t *headnode;
node_t outside_node;
vec3_t mins, maxs;
} tree_t;
//=============================================================================
// bspc.c
//=============================================================================
extern qboolean noprune;
extern qboolean nodetail;
extern qboolean fulldetail;
extern qboolean nomerge;
extern qboolean nosubdiv;
extern qboolean nowater;
extern qboolean noweld;
extern qboolean noshare;
extern qboolean notjunc;
extern qboolean onlyents;
#ifdef ME
extern qboolean nocsg;
extern qboolean create_aas;
extern qboolean freetree;
extern qboolean lessbrushes;
extern qboolean nobrushmerge;
extern qboolean cancelconversion;
extern qboolean noliquids;
extern qboolean capsule_collision;
#endif //ME
extern float subdivide_size;
extern vec_t microvolume;
extern char outbase[32];
extern char source[1024];
//=============================================================================
// map.c
//=============================================================================
#define MAX_MAPFILE_PLANES 256000
#define MAX_MAPFILE_BRUSHES 65535
#define MAX_MAPFILE_BRUSHSIDES (MAX_MAPFILE_BRUSHES*8)
#define MAX_MAPFILE_TEXINFO 8192
extern int entity_num;
extern plane_t mapplanes[MAX_MAPFILE_PLANES];
extern int nummapplanes;
extern int mapplaneusers[MAX_MAPFILE_PLANES];
extern int nummapbrushes;
extern mapbrush_t mapbrushes[MAX_MAPFILE_BRUSHES];
extern vec3_t map_mins, map_maxs;
extern int nummapbrushsides;
extern side_t brushsides[MAX_MAPFILE_BRUSHSIDES];
extern brush_texture_t side_brushtextures[MAX_MAPFILE_BRUSHSIDES];
#ifdef ME
typedef struct
{
float vecs[2][4]; // [s/t][xyz offset]
int flags; // miptex flags + overrides
int value;
char texture[64]; // texture name (textures/*.wal)
int nexttexinfo; // for animations, -1 = end of chain
} map_texinfo_t;
extern map_texinfo_t map_texinfo[MAX_MAPFILE_TEXINFO];
extern int map_numtexinfo;
#define NODESTACKSIZE 1024
#define MAPTYPE_QUAKE1 1
#define MAPTYPE_QUAKE2 2
#define MAPTYPE_QUAKE3 3
#define MAPTYPE_HALFLIFE 4
#define MAPTYPE_SIN 5
extern int nodestack[NODESTACKSIZE];
extern int *nodestackptr;
extern int nodestacksize;
extern int brushmodelnumbers[MAX_MAPFILE_BRUSHES];
extern int dbrushleafnums[MAX_MAPFILE_BRUSHES];
extern int dplanes2mapplanes[MAX_MAPFILE_PLANES];
extern int loadedmaptype;
#endif //ME
extern int c_boxbevels;
extern int c_edgebevels;
extern int c_areaportals;
extern int c_clipbrushes;
extern int c_squattbrushes;
//finds a float plane for the given normal and distance
int FindFloatPlane(vec3_t normal, vec_t dist);
//returns the plane type for the given normal
int PlaneTypeForNormal(vec3_t normal);
//returns the plane defined by the three given points
int PlaneFromPoints(int *p0, int *p1, int *p2);
//add bevels to the map brush
void AddBrushBevels(mapbrush_t *b);
//makes brush side windings for the brush
qboolean MakeBrushWindings(mapbrush_t *ob);
//marks brush bevels of the brush as bevel
void MarkBrushBevels(mapbrush_t *brush);
//returns true if the map brush already exists
int BrushExists(mapbrush_t *brush);
//loads a map from a bsp file
int LoadMapFromBSP(struct quakefile_s *qf);
//resets map loading
void ResetMapLoading(void);
//print some map info
void PrintMapInfo(void);
//writes a map file (type depending on loaded map type)
void WriteMapFile(char *filename);
//=============================================================================
// map_q2.c
//=============================================================================
void Q2_ResetMapLoading(void);
//loads a Quake2 map file
void Q2_LoadMapFile(char *filename);
//loads a map from a Quake2 bsp file
void Q2_LoadMapFromBSP(char *filename, int offset, int length);
//=============================================================================
// map_q1.c
//=============================================================================
void Q1_ResetMapLoading(void);
//loads a Quake2 map file
void Q1_LoadMapFile(char *filename);
//loads a map from a Quake1 bsp file
void Q1_LoadMapFromBSP(char *filename, int offset, int length);
//=============================================================================
// map_q3.c
//=============================================================================
void Q3_ResetMapLoading(void);
//loads a map from a Quake3 bsp file
void Q3_LoadMapFromBSP(struct quakefile_s *qf);
//=============================================================================
// map_sin.c
//=============================================================================
void Sin_ResetMapLoading(void);
//loads a Sin map file
void Sin_LoadMapFile(char *filename);
//loads a map from a Sin bsp file
void Sin_LoadMapFromBSP(char *filename, int offset, int length);
//=============================================================================
// map_hl.c
//=============================================================================
void HL_ResetMapLoading(void);
//loads a Half-Life map file
void HL_LoadMapFile(char *filename);
//loads a map from a Half-Life bsp file
void HL_LoadMapFromBSP(char *filename, int offset, int length);
//=============================================================================
// textures.c
//=============================================================================
typedef struct
{
char name[64];
int flags;
int value;
int contents;
char animname[64];
} textureref_t;
#define MAX_MAP_TEXTURES 1024
extern textureref_t textureref[MAX_MAP_TEXTURES];
int FindMiptex(char *name);
int TexinfoForBrushTexture(plane_t *plane, brush_texture_t *bt, vec3_t origin);
void TextureAxisFromPlane(plane_t *pln, vec3_t xv, vec3_t yv);
//=============================================================================
// csg
//=============================================================================
bspbrush_t *MakeBspBrushList(int startbrush, int endbrush, vec3_t clipmins, vec3_t clipmaxs);
bspbrush_t *ChopBrushes(bspbrush_t *head);
bspbrush_t *InitialBrushList(bspbrush_t *list);
bspbrush_t *OptimizedBrushList(bspbrush_t *list);
void WriteBrushMap(char *name, bspbrush_t *list);
void CheckBSPBrush(bspbrush_t *brush);
void BSPBrushWindings(bspbrush_t *brush);
bspbrush_t *TryMergeBrushes(bspbrush_t *brush1, bspbrush_t *brush2);
tree_t *ProcessWorldBrushes(int brush_start, int brush_end);
//=============================================================================
// brushbsp
//=============================================================================
#define PSIDE_FRONT 1
#define PSIDE_BACK 2
#define PSIDE_BOTH (PSIDE_FRONT|PSIDE_BACK)
#define PSIDE_FACING 4
void WriteBrushList(char *name, bspbrush_t *brush, qboolean onlyvis);
bspbrush_t *CopyBrush(bspbrush_t *brush);
void SplitBrush(bspbrush_t *brush, int planenum, bspbrush_t **front, bspbrush_t **back);
node_t *AllocNode(void);
bspbrush_t *AllocBrush(int numsides);
int CountBrushList(bspbrush_t *brushes);
void FreeBrush(bspbrush_t *brushes);
vec_t BrushVolume(bspbrush_t *brush);
void BoundBrush(bspbrush_t *brush);
void FreeBrushList(bspbrush_t *brushes);
tree_t *BrushBSP(bspbrush_t *brushlist, vec3_t mins, vec3_t maxs);
bspbrush_t *BrushFromBounds(vec3_t mins, vec3_t maxs);
int BrushMostlyOnSide(bspbrush_t *brush, plane_t *plane);
qboolean WindingIsHuge(winding_t *w);
qboolean WindingIsTiny(winding_t *w);
void ResetBrushBSP(void);
//=============================================================================
// portals.c
//=============================================================================
int VisibleContents (int contents);
void MakeHeadnodePortals (tree_t *tree);
void MakeNodePortal (node_t *node);
void SplitNodePortals (node_t *node);
qboolean Portal_VisFlood (portal_t *p);
qboolean FloodEntities (tree_t *tree);
void FillOutside (node_t *headnode);
void FloodAreas (tree_t *tree);
void MarkVisibleSides (tree_t *tree, int start, int end);
void FreePortal (portal_t *p);
void EmitAreaPortals (node_t *headnode);
void MakeTreePortals (tree_t *tree);
//=============================================================================
// glfile.c
//=============================================================================
void OutputWinding(winding_t *w, FILE *glview);
void WriteGLView(tree_t *tree, char *source);
//=============================================================================
// gldraw.c
//=============================================================================
extern vec3_t draw_mins, draw_maxs;
extern qboolean drawflag;
void Draw_ClearWindow (void);
void DrawWinding (winding_t *w);
void GLS_BeginScene (void);
void GLS_Winding (winding_t *w, int code);
void GLS_EndScene (void);
//=============================================================================
// leakfile.c
//=============================================================================
void LeakFile (tree_t *tree);
//=============================================================================
// tree.c
//=============================================================================
tree_t *Tree_Alloc(void);
void Tree_Free(tree_t *tree);
void Tree_Free_r(node_t *node);
void Tree_Print_r(node_t *node, int depth);
void Tree_FreePortals_r(node_t *node);
void Tree_PruneNodes_r(node_t *node);
void Tree_PruneNodes(node_t *node);

974
code/bspc/qfiles.h Normal file → Executable file
View file

@ -1,487 +1,487 @@
/*
===========================================================================
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
===========================================================================
*/
//
// 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;
/*
===========================================================================
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
===========================================================================
*/
//
// 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;

730
code/bspc/sinfiles.h Normal file → Executable file
View file

@ -1,365 +1,365 @@
/*
===========================================================================
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
===========================================================================
*/
/*
==============================================================================
.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;
/*
===========================================================================
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
===========================================================================
*/
/*
==============================================================================
.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;

2778
code/bspc/tetrahedron.c Normal file → Executable file

File diff suppressed because it is too large Load diff

48
code/bspc/tetrahedron.h Normal file → Executable file
View file

@ -1,24 +1,24 @@
/*
===========================================================================
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
===========================================================================
*/
void TH_AASToTetrahedrons(char *filename);
/*
===========================================================================
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
===========================================================================
*/
void TH_AASToTetrahedrons(char *filename);

456
code/bspc/textures.c Normal file → Executable file
View file

@ -1,228 +1,228 @@
/*
===========================================================================
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 "qbsp.h"
#include "l_bsp_q2.h"
int nummiptex;
textureref_t textureref[MAX_MAP_TEXTURES];
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int FindMiptex (char *name)
{
int i;
char path[1024];
miptex_t *mt;
for (i = 0; i < nummiptex; i++)
{
if (!strcmp (name, textureref[i].name))
{
return i;
} //end if
} //end for
if (nummiptex == MAX_MAP_TEXTURES)
Error ("MAX_MAP_TEXTURES");
strcpy (textureref[i].name, name);
// load the miptex to get the flags and values
sprintf (path, "%stextures/%s.wal", gamedir, name);
if (TryLoadFile (path, (void **)&mt) != -1)
{
textureref[i].value = LittleLong (mt->value);
textureref[i].flags = LittleLong (mt->flags);
textureref[i].contents = LittleLong (mt->contents);
strcpy (textureref[i].animname, mt->animname);
FreeMemory(mt);
} //end if
nummiptex++;
if (textureref[i].animname[0])
FindMiptex (textureref[i].animname);
return i;
} //end of the function FindMipTex
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
vec3_t baseaxis[18] =
{
{0,0,1}, {1,0,0}, {0,-1,0}, // floor
{0,0,-1}, {1,0,0}, {0,-1,0}, // ceiling
{1,0,0}, {0,1,0}, {0,0,-1}, // west wall
{-1,0,0}, {0,1,0}, {0,0,-1}, // east wall
{0,1,0}, {1,0,0}, {0,0,-1}, // south wall
{0,-1,0}, {1,0,0}, {0,0,-1} // north wall
};
void TextureAxisFromPlane(plane_t *pln, vec3_t xv, vec3_t yv)
{
int bestaxis;
vec_t dot,best;
int i;
best = 0;
bestaxis = 0;
for (i=0 ; i<6 ; i++)
{
dot = DotProduct (pln->normal, baseaxis[i*3]);
if (dot > best)
{
best = dot;
bestaxis = i;
}
}
VectorCopy (baseaxis[bestaxis*3+1], xv);
VectorCopy (baseaxis[bestaxis*3+2], yv);
} //end of the function TextureAxisFromPlane
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int TexinfoForBrushTexture(plane_t *plane, brush_texture_t *bt, vec3_t origin)
{
vec3_t vecs[2];
int sv, tv;
vec_t ang, sinv, cosv;
vec_t ns, nt;
texinfo_t tx, *tc;
int i, j, k;
float shift[2];
brush_texture_t anim;
int mt;
if (!bt->name[0])
return 0;
memset (&tx, 0, sizeof(tx));
strcpy (tx.texture, bt->name);
TextureAxisFromPlane(plane, vecs[0], vecs[1]);
shift[0] = DotProduct (origin, vecs[0]);
shift[1] = DotProduct (origin, vecs[1]);
if (!bt->scale[0])
bt->scale[0] = 1;
if (!bt->scale[1])
bt->scale[1] = 1;
// rotate axis
if (bt->rotate == 0)
{ sinv = 0 ; cosv = 1; }
else if (bt->rotate == 90)
{ sinv = 1 ; cosv = 0; }
else if (bt->rotate == 180)
{ sinv = 0 ; cosv = -1; }
else if (bt->rotate == 270)
{ sinv = -1 ; cosv = 0; }
else
{
ang = bt->rotate / 180 * Q_PI;
sinv = sin(ang);
cosv = cos(ang);
}
if (vecs[0][0])
sv = 0;
else if (vecs[0][1])
sv = 1;
else
sv = 2;
if (vecs[1][0])
tv = 0;
else if (vecs[1][1])
tv = 1;
else
tv = 2;
for (i=0 ; i<2 ; i++)
{
ns = cosv * vecs[i][sv] - sinv * vecs[i][tv];
nt = sinv * vecs[i][sv] + cosv * vecs[i][tv];
vecs[i][sv] = ns;
vecs[i][tv] = nt;
}
for (i=0 ; i<2 ; i++)
for (j=0 ; j<3 ; j++)
tx.vecs[i][j] = vecs[i][j] / bt->scale[i];
tx.vecs[0][3] = bt->shift[0] + shift[0];
tx.vecs[1][3] = bt->shift[1] + shift[1];
tx.flags = bt->flags;
tx.value = bt->value;
//
// find the texinfo
//
tc = texinfo;
for (i=0 ; i<numtexinfo ; i++, tc++)
{
if (tc->flags != tx.flags)
continue;
if (tc->value != tx.value)
continue;
for (j=0 ; j<2 ; j++)
{
if (strcmp (tc->texture, tx.texture))
goto skip;
for (k=0 ; k<4 ; k++)
{
if (tc->vecs[j][k] != tx.vecs[j][k])
goto skip;
}
}
return i;
skip:;
}
*tc = tx;
numtexinfo++;
// load the next animation
mt = FindMiptex (bt->name);
if (textureref[mt].animname[0])
{
anim = *bt;
strcpy (anim.name, textureref[mt].animname);
tc->nexttexinfo = TexinfoForBrushTexture (plane, &anim, origin);
}
else
tc->nexttexinfo = -1;
return i;
} //end of the function TexinfoForBrushTexture
/*
===========================================================================
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 "qbsp.h"
#include "l_bsp_q2.h"
int nummiptex;
textureref_t textureref[MAX_MAP_TEXTURES];
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int FindMiptex (char *name)
{
int i;
char path[1024];
miptex_t *mt;
for (i = 0; i < nummiptex; i++)
{
if (!strcmp (name, textureref[i].name))
{
return i;
} //end if
} //end for
if (nummiptex == MAX_MAP_TEXTURES)
Error ("MAX_MAP_TEXTURES");
strcpy (textureref[i].name, name);
// load the miptex to get the flags and values
sprintf (path, "%stextures/%s.wal", gamedir, name);
if (TryLoadFile (path, (void **)&mt) != -1)
{
textureref[i].value = LittleLong (mt->value);
textureref[i].flags = LittleLong (mt->flags);
textureref[i].contents = LittleLong (mt->contents);
strcpy (textureref[i].animname, mt->animname);
FreeMemory(mt);
} //end if
nummiptex++;
if (textureref[i].animname[0])
FindMiptex (textureref[i].animname);
return i;
} //end of the function FindMipTex
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
vec3_t baseaxis[18] =
{
{0,0,1}, {1,0,0}, {0,-1,0}, // floor
{0,0,-1}, {1,0,0}, {0,-1,0}, // ceiling
{1,0,0}, {0,1,0}, {0,0,-1}, // west wall
{-1,0,0}, {0,1,0}, {0,0,-1}, // east wall
{0,1,0}, {1,0,0}, {0,0,-1}, // south wall
{0,-1,0}, {1,0,0}, {0,0,-1} // north wall
};
void TextureAxisFromPlane(plane_t *pln, vec3_t xv, vec3_t yv)
{
int bestaxis;
vec_t dot,best;
int i;
best = 0;
bestaxis = 0;
for (i=0 ; i<6 ; i++)
{
dot = DotProduct (pln->normal, baseaxis[i*3]);
if (dot > best)
{
best = dot;
bestaxis = i;
}
}
VectorCopy (baseaxis[bestaxis*3+1], xv);
VectorCopy (baseaxis[bestaxis*3+2], yv);
} //end of the function TextureAxisFromPlane
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int TexinfoForBrushTexture(plane_t *plane, brush_texture_t *bt, vec3_t origin)
{
vec3_t vecs[2];
int sv, tv;
vec_t ang, sinv, cosv;
vec_t ns, nt;
texinfo_t tx, *tc;
int i, j, k;
float shift[2];
brush_texture_t anim;
int mt;
if (!bt->name[0])
return 0;
memset (&tx, 0, sizeof(tx));
strcpy (tx.texture, bt->name);
TextureAxisFromPlane(plane, vecs[0], vecs[1]);
shift[0] = DotProduct (origin, vecs[0]);
shift[1] = DotProduct (origin, vecs[1]);
if (!bt->scale[0])
bt->scale[0] = 1;
if (!bt->scale[1])
bt->scale[1] = 1;
// rotate axis
if (bt->rotate == 0)
{ sinv = 0 ; cosv = 1; }
else if (bt->rotate == 90)
{ sinv = 1 ; cosv = 0; }
else if (bt->rotate == 180)
{ sinv = 0 ; cosv = -1; }
else if (bt->rotate == 270)
{ sinv = -1 ; cosv = 0; }
else
{
ang = bt->rotate / 180 * Q_PI;
sinv = sin(ang);
cosv = cos(ang);
}
if (vecs[0][0])
sv = 0;
else if (vecs[0][1])
sv = 1;
else
sv = 2;
if (vecs[1][0])
tv = 0;
else if (vecs[1][1])
tv = 1;
else
tv = 2;
for (i=0 ; i<2 ; i++)
{
ns = cosv * vecs[i][sv] - sinv * vecs[i][tv];
nt = sinv * vecs[i][sv] + cosv * vecs[i][tv];
vecs[i][sv] = ns;
vecs[i][tv] = nt;
}
for (i=0 ; i<2 ; i++)
for (j=0 ; j<3 ; j++)
tx.vecs[i][j] = vecs[i][j] / bt->scale[i];
tx.vecs[0][3] = bt->shift[0] + shift[0];
tx.vecs[1][3] = bt->shift[1] + shift[1];
tx.flags = bt->flags;
tx.value = bt->value;
//
// find the texinfo
//
tc = texinfo;
for (i=0 ; i<numtexinfo ; i++, tc++)
{
if (tc->flags != tx.flags)
continue;
if (tc->value != tx.value)
continue;
for (j=0 ; j<2 ; j++)
{
if (strcmp (tc->texture, tx.texture))
goto skip;
for (k=0 ; k<4 ; k++)
{
if (tc->vecs[j][k] != tx.vecs[j][k])
goto skip;
}
}
return i;
skip:;
}
*tc = tx;
numtexinfo++;
// load the next animation
mt = FindMiptex (bt->name);
if (textureref[mt].animname[0])
{
anim = *bt;
strcpy (anim.name, textureref[mt].animname);
tc->nexttexinfo = TexinfoForBrushTexture (plane, &anim, origin);
}
else
tc->nexttexinfo = -1;
return i;
} //end of the function TexinfoForBrushTexture

566
code/bspc/tree.c Normal file → Executable file
View file

@ -1,283 +1,283 @@
/*
===========================================================================
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 "qbsp.h"
extern int c_nodes;
int c_pruned;
int freedtreemem = 0;
void RemovePortalFromNode (portal_t *portal, node_t *l);
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
node_t *NodeForPoint (node_t *node, vec3_t origin)
{
plane_t *plane;
vec_t d;
while (node->planenum != PLANENUM_LEAF)
{
plane = &mapplanes[node->planenum];
d = DotProduct (origin, plane->normal) - plane->dist;
if (d >= 0)
node = node->children[0];
else
node = node->children[1];
}
return node;
} //end of the function NodeForPoint
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void Tree_FreePortals_r (node_t *node)
{
portal_t *p, *nextp;
int s;
// free children
if (node->planenum != PLANENUM_LEAF)
{
Tree_FreePortals_r(node->children[0]);
Tree_FreePortals_r(node->children[1]);
}
// free portals
for (p = node->portals; p; p = nextp)
{
s = (p->nodes[1] == node);
nextp = p->next[s];
RemovePortalFromNode (p, p->nodes[!s]);
#ifdef ME
if (p->winding) freedtreemem += MemorySize(p->winding);
freedtreemem += MemorySize(p);
#endif //ME
FreePortal(p);
}
node->portals = NULL;
} //end of the function Tree_FreePortals_r
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void Tree_Free_r (node_t *node)
{
// face_t *f, *nextf;
bspbrush_t *brush, *nextbrush;
//free children
if (node->planenum != PLANENUM_LEAF)
{
Tree_Free_r (node->children[0]);
Tree_Free_r (node->children[1]);
} //end if
//free bspbrushes
// FreeBrushList (node->brushlist);
for (brush = node->brushlist; brush; brush = nextbrush)
{
nextbrush = brush->next;
#ifdef ME
freedtreemem += MemorySize(brush);
#endif //ME
FreeBrush(brush);
} //end for
node->brushlist = NULL;
/*
NOTE: only used when creating Q2 bsp
// free faces
for (f = node->faces; f; f = nextf)
{
nextf = f->next;
#ifdef ME
if (f->w) freedtreemem += MemorySize(f->w);
freedtreemem += sizeof(face_t);
#endif //ME
FreeFace(f);
} //end for
*/
// free the node
if (node->volume)
{
#ifdef ME
freedtreemem += MemorySize(node->volume);
#endif //ME
FreeBrush (node->volume);
} //end if
if (numthreads == 1) c_nodes--;
#ifdef ME
freedtreemem += MemorySize(node);
#endif //ME
FreeMemory(node);
} //end of the function Tree_Free_r
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void Tree_Free(tree_t *tree)
{
//if no tree just return
if (!tree) return;
//
freedtreemem = 0;
//
Tree_FreePortals_r(tree->headnode);
Tree_Free_r(tree->headnode);
#ifdef ME
freedtreemem += MemorySize(tree);
#endif //ME
FreeMemory(tree);
#ifdef ME
Log_Print("freed ");
PrintMemorySize(freedtreemem);
Log_Print(" of tree memory\n");
#endif //ME
} //end of the function Tree_Free
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
tree_t *Tree_Alloc(void)
{
tree_t *tree;
tree = GetMemory(sizeof(*tree));
memset (tree, 0, sizeof(*tree));
ClearBounds (tree->mins, tree->maxs);
return tree;
} //end of the function Tree_Alloc
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void Tree_Print_r (node_t *node, int depth)
{
int i;
plane_t *plane;
bspbrush_t *bb;
for (i=0 ; i<depth ; i++)
printf (" ");
if (node->planenum == PLANENUM_LEAF)
{
if (!node->brushlist)
printf ("NULL\n");
else
{
for (bb=node->brushlist ; bb ; bb=bb->next)
printf ("%i ", bb->original->brushnum);
printf ("\n");
}
return;
}
plane = &mapplanes[node->planenum];
printf ("#%i (%5.2f %5.2f %5.2f):%5.2f\n", node->planenum,
plane->normal[0], plane->normal[1], plane->normal[2],
plane->dist);
Tree_Print_r (node->children[0], depth+1);
Tree_Print_r (node->children[1], depth+1);
} //end of the function Tree_Print_r
//===========================================================================
// NODES THAT DON'T SEPERATE DIFFERENT CONTENTS CAN BE PRUNED
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void Tree_PruneNodes_r (node_t *node)
{
bspbrush_t *b, *next;
if (node->planenum == PLANENUM_LEAF) return;
Tree_PruneNodes_r (node->children[0]);
Tree_PruneNodes_r (node->children[1]);
if (create_aas)
{
if ((node->children[0]->contents & CONTENTS_LADDER) ||
(node->children[1]->contents & CONTENTS_LADDER)) return;
}
if ((node->children[0]->contents & CONTENTS_SOLID)
&& (node->children[1]->contents & CONTENTS_SOLID))
{
if (node->faces)
Error ("node->faces seperating CONTENTS_SOLID");
if (node->children[0]->faces || node->children[1]->faces)
Error ("!node->faces with children");
// FIXME: free stuff
node->planenum = PLANENUM_LEAF;
node->contents = CONTENTS_SOLID;
node->detail_seperator = false;
if (node->brushlist)
Error ("PruneNodes: node->brushlist");
// combine brush lists
node->brushlist = node->children[1]->brushlist;
for (b = node->children[0]->brushlist; b; b = next)
{
next = b->next;
b->next = node->brushlist;
node->brushlist = b;
} //end for
//free the child nodes
FreeMemory(node->children[0]);
FreeMemory(node->children[1]);
//two nodes are cut away
c_pruned += 2;
} //end if
} //end of the function Tree_PruneNodes_r
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void Tree_PruneNodes(node_t *node)
{
Log_Print("------- Prune Nodes --------\n");
c_pruned = 0;
Tree_PruneNodes_r(node);
Log_Print("%5i pruned nodes\n", c_pruned);
} //end of the function Tree_PruneNodes
/*
===========================================================================
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 "qbsp.h"
extern int c_nodes;
int c_pruned;
int freedtreemem = 0;
void RemovePortalFromNode (portal_t *portal, node_t *l);
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
node_t *NodeForPoint (node_t *node, vec3_t origin)
{
plane_t *plane;
vec_t d;
while (node->planenum != PLANENUM_LEAF)
{
plane = &mapplanes[node->planenum];
d = DotProduct (origin, plane->normal) - plane->dist;
if (d >= 0)
node = node->children[0];
else
node = node->children[1];
}
return node;
} //end of the function NodeForPoint
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void Tree_FreePortals_r (node_t *node)
{
portal_t *p, *nextp;
int s;
// free children
if (node->planenum != PLANENUM_LEAF)
{
Tree_FreePortals_r(node->children[0]);
Tree_FreePortals_r(node->children[1]);
}
// free portals
for (p = node->portals; p; p = nextp)
{
s = (p->nodes[1] == node);
nextp = p->next[s];
RemovePortalFromNode (p, p->nodes[!s]);
#ifdef ME
if (p->winding) freedtreemem += MemorySize(p->winding);
freedtreemem += MemorySize(p);
#endif //ME
FreePortal(p);
}
node->portals = NULL;
} //end of the function Tree_FreePortals_r
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void Tree_Free_r (node_t *node)
{
// face_t *f, *nextf;
bspbrush_t *brush, *nextbrush;
//free children
if (node->planenum != PLANENUM_LEAF)
{
Tree_Free_r (node->children[0]);
Tree_Free_r (node->children[1]);
} //end if
//free bspbrushes
// FreeBrushList (node->brushlist);
for (brush = node->brushlist; brush; brush = nextbrush)
{
nextbrush = brush->next;
#ifdef ME
freedtreemem += MemorySize(brush);
#endif //ME
FreeBrush(brush);
} //end for
node->brushlist = NULL;
/*
NOTE: only used when creating Q2 bsp
// free faces
for (f = node->faces; f; f = nextf)
{
nextf = f->next;
#ifdef ME
if (f->w) freedtreemem += MemorySize(f->w);
freedtreemem += sizeof(face_t);
#endif //ME
FreeFace(f);
} //end for
*/
// free the node
if (node->volume)
{
#ifdef ME
freedtreemem += MemorySize(node->volume);
#endif //ME
FreeBrush (node->volume);
} //end if
if (numthreads == 1) c_nodes--;
#ifdef ME
freedtreemem += MemorySize(node);
#endif //ME
FreeMemory(node);
} //end of the function Tree_Free_r
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void Tree_Free(tree_t *tree)
{
//if no tree just return
if (!tree) return;
//
freedtreemem = 0;
//
Tree_FreePortals_r(tree->headnode);
Tree_Free_r(tree->headnode);
#ifdef ME
freedtreemem += MemorySize(tree);
#endif //ME
FreeMemory(tree);
#ifdef ME
Log_Print("freed ");
PrintMemorySize(freedtreemem);
Log_Print(" of tree memory\n");
#endif //ME
} //end of the function Tree_Free
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
tree_t *Tree_Alloc(void)
{
tree_t *tree;
tree = GetMemory(sizeof(*tree));
memset (tree, 0, sizeof(*tree));
ClearBounds (tree->mins, tree->maxs);
return tree;
} //end of the function Tree_Alloc
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void Tree_Print_r (node_t *node, int depth)
{
int i;
plane_t *plane;
bspbrush_t *bb;
for (i=0 ; i<depth ; i++)
printf (" ");
if (node->planenum == PLANENUM_LEAF)
{
if (!node->brushlist)
printf ("NULL\n");
else
{
for (bb=node->brushlist ; bb ; bb=bb->next)
printf ("%i ", bb->original->brushnum);
printf ("\n");
}
return;
}
plane = &mapplanes[node->planenum];
printf ("#%i (%5.2f %5.2f %5.2f):%5.2f\n", node->planenum,
plane->normal[0], plane->normal[1], plane->normal[2],
plane->dist);
Tree_Print_r (node->children[0], depth+1);
Tree_Print_r (node->children[1], depth+1);
} //end of the function Tree_Print_r
//===========================================================================
// NODES THAT DON'T SEPERATE DIFFERENT CONTENTS CAN BE PRUNED
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void Tree_PruneNodes_r (node_t *node)
{
bspbrush_t *b, *next;
if (node->planenum == PLANENUM_LEAF) return;
Tree_PruneNodes_r (node->children[0]);
Tree_PruneNodes_r (node->children[1]);
if (create_aas)
{
if ((node->children[0]->contents & CONTENTS_LADDER) ||
(node->children[1]->contents & CONTENTS_LADDER)) return;
}
if ((node->children[0]->contents & CONTENTS_SOLID)
&& (node->children[1]->contents & CONTENTS_SOLID))
{
if (node->faces)
Error ("node->faces seperating CONTENTS_SOLID");
if (node->children[0]->faces || node->children[1]->faces)
Error ("!node->faces with children");
// FIXME: free stuff
node->planenum = PLANENUM_LEAF;
node->contents = CONTENTS_SOLID;
node->detail_seperator = false;
if (node->brushlist)
Error ("PruneNodes: node->brushlist");
// combine brush lists
node->brushlist = node->children[1]->brushlist;
for (b = node->children[0]->brushlist; b; b = next)
{
next = b->next;
b->next = node->brushlist;
node->brushlist = b;
} //end for
//free the child nodes
FreeMemory(node->children[0]);
FreeMemory(node->children[1]);
//two nodes are cut away
c_pruned += 2;
} //end if
} //end of the function Tree_PruneNodes_r
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void Tree_PruneNodes(node_t *node)
{
Log_Print("------- Prune Nodes --------\n");
c_pruned = 0;
Tree_PruneNodes_r(node);
Log_Print("%5i pruned nodes\n", c_pruned);
} //end of the function Tree_PruneNodes

1190
code/bspc/writebsp.c Normal file → Executable file

File diff suppressed because it is too large Load diff