Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

l_bsp_q2.c

Go to the documentation of this file.
00001 /*
00002 ===========================================================================
00003 Copyright (C) 1999-2005 Id Software, Inc.
00004 
00005 This file is part of Quake III Arena source code.
00006 
00007 Quake III Arena source code is free software; you can redistribute it
00008 and/or modify it under the terms of the GNU General Public License as
00009 published by the Free Software Foundation; either version 2 of the License,
00010 or (at your option) any later version.
00011 
00012 Quake III Arena source code is distributed in the hope that it will be
00013 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 GNU General Public License for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Foobar; if not, write to the Free Software
00019 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020 ===========================================================================
00021 */
00022 
00023 #include "l_cmd.h"
00024 #include "l_math.h"
00025 #include "l_mem.h"
00026 #include "l_log.h"
00027 #include "l_poly.h"
00028 #include "../botlib/l_script.h"
00029 #include "q2files.h"
00030 #include "l_bsp_q2.h"
00031 #include "l_bsp_ent.h"
00032 
00033 #define q2_dmodel_t         dmodel_t
00034 #define q2_lump_t               lump_t
00035 #define q2_dheader_t            dheader_t
00036 #define q2_dmodel_t         dmodel_t
00037 #define q2_dvertex_t            dvertex_t
00038 #define q2_dplane_t         dplane_t
00039 #define q2_dnode_t          dnode_t
00040 #define q2_texinfo_t            texinfo_t
00041 #define q2_dedge_t          dedge_t
00042 #define q2_dface_t          dface_t
00043 #define q2_dleaf_t          dleaf_t
00044 #define q2_dbrushside_t     dbrushside_t
00045 #define q2_dbrush_t         dbrush_t
00046 #define q2_dvis_t               dvis_t
00047 #define q2_dareaportal_t    dareaportal_t
00048 #define q2_darea_t          darea_t
00049 
00050 #define q2_nummodels            nummodels
00051 #define q2_dmodels          dmodels
00052 #define q2_numleafs         numleafs
00053 #define q2_dleafs               dleafs
00054 #define q2_numplanes            numplanes
00055 #define q2_dplanes          dplanes
00056 #define q2_numvertexes      numvertexes
00057 #define q2_dvertexes            dvertexes
00058 #define q2_numnodes         numnodes
00059 #define q2_dnodes               dnodes
00060 #define q2_numtexinfo       numtexinfo
00061 #define q2_texinfo          texinfo
00062 #define q2_numfaces         numfaces
00063 #define q2_dfaces               dfaces
00064 #define q2_numedges         numedges
00065 #define q2_dedges               dedges
00066 #define q2_numleaffaces     numleaffaces
00067 #define q2_dleaffaces       dleaffaces
00068 #define q2_numleafbrushes   numleafbrushes
00069 #define q2_dleafbrushes     dleafbrushes
00070 #define q2_dsurfedges       dsurfedges
00071 #define q2_numbrushes       numbrushes
00072 #define q2_dbrushes         dbrushes
00073 #define q2_numbrushsides    numbrushsides
00074 #define q2_dbrushsides      dbrushsides
00075 #define q2_numareas         numareas
00076 #define q2_dareas               dareas
00077 #define q2_numareaportals   numareaportals
00078 #define q2_dareaportals     dareaportals
00079 
00080 void GetLeafNums (void);
00081 
00082 //=============================================================================
00083 
00084 int             nummodels;
00085 dmodel_t            *dmodels;//[MAX_MAP_MODELS];
00086 
00087 int             visdatasize;
00088 byte                *dvisdata;//[MAX_MAP_VISIBILITY];
00089 dvis_t          *dvis;// = (dvis_t *)dvisdata;
00090 
00091 int             lightdatasize;
00092 byte                *dlightdata;//[MAX_MAP_LIGHTING];
00093 
00094 int             entdatasize;
00095 char                *dentdata;//[MAX_MAP_ENTSTRING];
00096 
00097 int             numleafs;
00098 dleaf_t         *dleafs;//[MAX_MAP_LEAFS];
00099 
00100 int             numplanes;
00101 dplane_t            *dplanes;//[MAX_MAP_PLANES];
00102 
00103 int             numvertexes;
00104 dvertex_t       *dvertexes;//[MAX_MAP_VERTS];
00105 
00106 int             numnodes;
00107 dnode_t         *dnodes;//[MAX_MAP_NODES];
00108 
00109 //NOTE: must be static for q2 .map to q2 .bsp
00110 int             numtexinfo;
00111 texinfo_t       texinfo[MAX_MAP_TEXINFO];
00112 
00113 int             numfaces;
00114 dface_t         *dfaces;//[MAX_MAP_FACES];
00115 
00116 int             numedges;
00117 dedge_t         *dedges;//[MAX_MAP_EDGES];
00118 
00119 int             numleaffaces;
00120 unsigned short  *dleaffaces;//[MAX_MAP_LEAFFACES];
00121 
00122 int             numleafbrushes;
00123 unsigned short  *dleafbrushes;//[MAX_MAP_LEAFBRUSHES];
00124 
00125 int             numsurfedges;
00126 int             *dsurfedges;//[MAX_MAP_SURFEDGES];
00127 
00128 int             numbrushes;
00129 dbrush_t            *dbrushes;//[MAX_MAP_BRUSHES];
00130 
00131 int             numbrushsides;
00132 dbrushside_t    *dbrushsides;//[MAX_MAP_BRUSHSIDES];
00133 
00134 int             numareas;
00135 darea_t         *dareas;//[MAX_MAP_AREAS];
00136 
00137 int             numareaportals;
00138 dareaportal_t   *dareaportals;//[MAX_MAP_AREAPORTALS];
00139 
00140 #define MAX_MAP_DPOP            256
00141 byte                dpop[MAX_MAP_DPOP];
00142 
00143 //
00144 char brushsidetextured[MAX_MAP_BRUSHSIDES];
00145 
00146 //#ifdef ME
00147 
00148 int bspallocated = false;
00149 int allocatedbspmem = 0;
00150 
00151 void Q2_AllocMaxBSP(void)
00152 {
00153     //models
00154     nummodels = 0;
00155     dmodels = (dmodel_t *) GetClearedMemory(MAX_MAP_MODELS * sizeof(dmodel_t));
00156     allocatedbspmem += MAX_MAP_MODELS * sizeof(dmodel_t);
00157     //vis data
00158     visdatasize = 0;
00159     dvisdata = (byte *) GetClearedMemory(MAX_MAP_VISIBILITY * sizeof(byte));
00160     dvis = (dvis_t *) dvisdata;
00161     allocatedbspmem += MAX_MAP_VISIBILITY * sizeof(byte);
00162     //light data
00163     lightdatasize = 0;
00164     dlightdata = (byte *) GetClearedMemory(MAX_MAP_LIGHTING * sizeof(byte));
00165     allocatedbspmem += MAX_MAP_LIGHTING * sizeof(byte);
00166     //entity data
00167     entdatasize = 0;
00168     dentdata = (char *) GetClearedMemory(MAX_MAP_ENTSTRING * sizeof(char));
00169     allocatedbspmem += MAX_MAP_ENTSTRING * sizeof(char);
00170     //leafs
00171     numleafs = 0;
00172     dleafs = (dleaf_t *) GetClearedMemory(MAX_MAP_LEAFS * sizeof(dleaf_t));
00173     allocatedbspmem += MAX_MAP_LEAFS * sizeof(dleaf_t);
00174     //planes
00175     numplanes = 0;
00176     dplanes = (dplane_t *) GetClearedMemory(MAX_MAP_PLANES * sizeof(dplane_t));
00177     allocatedbspmem += MAX_MAP_PLANES * sizeof(dplane_t);
00178     //vertexes
00179     numvertexes = 0;
00180     dvertexes = (dvertex_t *) GetClearedMemory(MAX_MAP_VERTS * sizeof(dvertex_t));
00181     allocatedbspmem += MAX_MAP_VERTS * sizeof(dvertex_t);
00182     //nodes
00183     numnodes = 0;
00184     dnodes = (dnode_t *) GetClearedMemory(MAX_MAP_NODES * sizeof(dnode_t));
00185     allocatedbspmem += MAX_MAP_NODES * sizeof(dnode_t);
00186     /*
00187     //texture info
00188     numtexinfo = 0;
00189     texinfo = (texinfo_t *) GetClearedMemory(MAX_MAP_TEXINFO * sizeof(texinfo_t));
00190     allocatedbspmem += MAX_MAP_TEXINFO * sizeof(texinfo_t);
00191     //*/
00192     //faces
00193     numfaces = 0;
00194     dfaces = (dface_t *) GetClearedMemory(MAX_MAP_FACES * sizeof(dface_t));
00195     allocatedbspmem += MAX_MAP_FACES * sizeof(dface_t);
00196     //edges
00197     numedges = 0;
00198     dedges = (dedge_t *) GetClearedMemory(MAX_MAP_EDGES * sizeof(dedge_t));
00199     allocatedbspmem += MAX_MAP_EDGES * sizeof(dedge_t);
00200     //leaf faces
00201     numleaffaces = 0;
00202     dleaffaces = (unsigned short *) GetClearedMemory(MAX_MAP_LEAFFACES * sizeof(unsigned short));
00203     allocatedbspmem += MAX_MAP_LEAFFACES * sizeof(unsigned short);
00204     //leaf brushes
00205     numleafbrushes = 0;
00206     dleafbrushes = (unsigned short *) GetClearedMemory(MAX_MAP_LEAFBRUSHES * sizeof(unsigned short));
00207     allocatedbspmem += MAX_MAP_LEAFBRUSHES * sizeof(unsigned short);
00208     //surface edges
00209     numsurfedges = 0;
00210     dsurfedges = (int *) GetClearedMemory(MAX_MAP_SURFEDGES * sizeof(int));
00211     allocatedbspmem += MAX_MAP_SURFEDGES * sizeof(int);
00212     //brushes
00213     numbrushes = 0;
00214     dbrushes = (dbrush_t *) GetClearedMemory(MAX_MAP_BRUSHES * sizeof(dbrush_t));
00215     allocatedbspmem += MAX_MAP_BRUSHES * sizeof(dbrush_t);
00216     //brushsides
00217     numbrushsides = 0;
00218     dbrushsides = (dbrushside_t *) GetClearedMemory(MAX_MAP_BRUSHSIDES * sizeof(dbrushside_t));
00219     allocatedbspmem += MAX_MAP_BRUSHSIDES * sizeof(dbrushside_t);
00220     //areas
00221     numareas = 0;
00222     dareas = (darea_t *) GetClearedMemory(MAX_MAP_AREAS * sizeof(darea_t));
00223     allocatedbspmem += MAX_MAP_AREAS * sizeof(darea_t);
00224     //area portals
00225     numareaportals = 0;
00226     dareaportals = (dareaportal_t *) GetClearedMemory(MAX_MAP_AREAPORTALS * sizeof(dareaportal_t));
00227     allocatedbspmem += MAX_MAP_AREAPORTALS * sizeof(dareaportal_t);
00228     //print allocated memory
00229     Log_Print("allocated ");
00230     PrintMemorySize(allocatedbspmem);
00231     Log_Print(" of BSP memory\n");
00232 } //end of the function Q2_AllocMaxBSP
00233 
00234 void Q2_FreeMaxBSP(void)
00235 {
00236     //models
00237     nummodels = 0;
00238     FreeMemory(dmodels);
00239     dmodels = NULL;
00240     //vis data
00241     visdatasize = 0;
00242     FreeMemory(dvisdata);
00243     dvisdata = NULL;
00244     dvis = NULL;
00245     //light data
00246     lightdatasize = 0;
00247     FreeMemory(dlightdata);
00248     dlightdata = NULL;
00249     //entity data
00250     entdatasize = 0;
00251     FreeMemory(dentdata);
00252     dentdata = NULL;
00253     //leafs
00254     numleafs = 0;
00255     FreeMemory(dleafs);
00256     dleafs = NULL;
00257     //planes
00258     numplanes = 0;
00259     FreeMemory(dplanes);
00260     dplanes = NULL;
00261     //vertexes
00262     numvertexes = 0;
00263     FreeMemory(dvertexes);
00264     dvertexes = NULL;
00265     //nodes
00266     numnodes = 0;
00267     FreeMemory(dnodes);
00268     dnodes = NULL;
00269     /*
00270     //texture info
00271     numtexinfo = 0;
00272     FreeMemory(texinfo);
00273     texinfo = NULL;
00274     //*/
00275     //faces
00276     numfaces = 0;
00277     FreeMemory(dfaces);
00278     dfaces = NULL;
00279     //edges
00280     numedges = 0;
00281     FreeMemory(dedges);
00282     dedges = NULL;
00283     //leaf faces
00284     numleaffaces = 0;
00285     FreeMemory(dleaffaces);
00286     dleaffaces = NULL;
00287     //leaf brushes
00288     numleafbrushes = 0;
00289     FreeMemory(dleafbrushes);
00290     dleafbrushes = NULL;
00291     //surface edges
00292     numsurfedges = 0;
00293     FreeMemory(dsurfedges);
00294     dsurfedges = NULL;
00295     //brushes
00296     numbrushes = 0;
00297     FreeMemory(dbrushes);
00298     dbrushes = NULL;
00299     //brushsides
00300     numbrushsides = 0;
00301     FreeMemory(dbrushsides);
00302     dbrushsides = NULL;
00303     //areas
00304     numareas = 0;
00305     FreeMemory(dareas);
00306     dareas = NULL;
00307     //area portals
00308     numareaportals = 0;
00309     FreeMemory(dareaportals);
00310     dareaportals = NULL;
00311     //
00312     Log_Print("freed ");
00313     PrintMemorySize(allocatedbspmem);
00314     Log_Print(" of BSP memory\n");
00315     allocatedbspmem = 0;
00316 } //end of the function Q2_FreeMaxBSP
00317 
00318 #define WCONVEX_EPSILON     0.5
00319 
00320 int InsideWinding(winding_t *w, vec3_t point, int planenum)
00321 {
00322     int i;
00323     float dist;
00324     vec_t *v1, *v2;
00325     vec3_t normal, edgevec;
00326     dplane_t *plane;
00327 
00328     for (i = 1; i <= w->numpoints; i++)
00329     {
00330         v1 = w->p[i % w->numpoints];
00331         v2 = w->p[(i + 1) % w->numpoints];
00332 
00333         VectorSubtract(v2, v1, edgevec);
00334         plane = &dplanes[planenum];
00335         CrossProduct(plane->normal, edgevec, normal);
00336         VectorNormalize(normal);
00337         dist = DotProduct(normal, v1);
00338         //
00339         if (DotProduct(normal, point) - dist > WCONVEX_EPSILON) return false;
00340     } //end for
00341     return true;
00342 } //end of the function InsideWinding
00343 
00344 int InsideFace(dface_t *face, vec3_t point)
00345 {
00346     int i, edgenum, side;
00347     float dist;
00348     vec_t *v1, *v2;
00349     vec3_t normal, edgevec;
00350     dplane_t *plane;
00351 
00352     for (i = 0; i < face->numedges; i++)
00353     {
00354         //get the first and second vertex of the edge
00355         edgenum = dsurfedges[face->firstedge + i];
00356         side = edgenum < 0;
00357         v1 = dvertexes[dedges[abs(edgenum)].v[side]].point;
00358         v2 = dvertexes[dedges[abs(edgenum)].v[!side]].point;
00359         //create a plane through the edge vector, orthogonal to the face plane
00360         //and with the normal vector pointing out of the face
00361         VectorSubtract(v1, v2, edgevec);
00362         plane = &dplanes[face->planenum];
00363         CrossProduct(plane->normal, edgevec, normal);
00364         VectorNormalize(normal);
00365         dist = DotProduct(normal, v1);
00366         //
00367         if (DotProduct(normal, point) - dist > WCONVEX_EPSILON) return false;
00368     } //end for
00369     return true;
00370 } //end of the function InsideFace
00371 //===========================================================================
00372 // returns the amount the face and the winding overlap
00373 //
00374 // Parameter:               -
00375 // Returns:                 -
00376 // Changes Globals:     -
00377 //===========================================================================
00378 float Q2_FaceOnWinding(q2_dface_t *face, winding_t *winding)
00379 {
00380     int i, edgenum, side;
00381     float dist, area;
00382     q2_dplane_t plane;
00383     vec_t *v1, *v2;
00384     vec3_t normal, edgevec;
00385     winding_t *w;
00386 
00387     //
00388     w = CopyWinding(winding);
00389     memcpy(&plane, &q2_dplanes[face->planenum], sizeof(q2_dplane_t));
00390     //check on which side of the plane the face is
00391     if (face->side)
00392     {
00393         VectorNegate(plane.normal, plane.normal);
00394         plane.dist = -plane.dist;
00395     } //end if
00396     for (i = 0; i < face->numedges && w; i++)
00397     {
00398         //get the first and second vertex of the edge
00399         edgenum = q2_dsurfedges[face->firstedge + i];
00400         side = edgenum > 0;
00401         //if the face plane is flipped
00402         v1 = q2_dvertexes[q2_dedges[abs(edgenum)].v[side]].point;
00403         v2 = q2_dvertexes[q2_dedges[abs(edgenum)].v[!side]].point;
00404         //create a plane through the edge vector, orthogonal to the face plane
00405         //and with the normal vector pointing inward
00406         VectorSubtract(v1, v2, edgevec);
00407         CrossProduct(edgevec, plane.normal, normal);
00408         VectorNormalize(normal);
00409         dist = DotProduct(normal, v1);
00410         //
00411         ChopWindingInPlace(&w, normal, dist, -0.1); //CLIP_EPSILON
00412     } //end for
00413     if (w)
00414     {
00415         area = WindingArea(w);
00416         FreeWinding(w);
00417         return area;
00418     } //end if
00419     return 0;
00420 } //end of the function Q2_FaceOnWinding
00421 //===========================================================================
00422 // creates a winding for the given brush side on the given brush
00423 //
00424 // Parameter:               -
00425 // Returns:                 -
00426 // Changes Globals:     -
00427 //===========================================================================
00428 winding_t *Q2_BrushSideWinding(dbrush_t *brush, dbrushside_t *baseside)
00429 {
00430     int i;
00431     dplane_t *baseplane, *plane;
00432     winding_t *w;
00433     dbrushside_t *side;
00434     
00435     //create a winding for the brush side with the given planenumber
00436     baseplane = &dplanes[baseside->planenum];
00437     w = BaseWindingForPlane(baseplane->normal, baseplane->dist);
00438     for (i = 0; i < brush->numsides && w; i++)
00439     {
00440         side = &dbrushsides[brush->firstside + i];
00441         //don't chop with the base plane
00442         if (side->planenum == baseside->planenum) continue;
00443         //also don't use planes that are almost equal
00444         plane = &dplanes[side->planenum];
00445         if (DotProduct(baseplane->normal, plane->normal) > 0.999
00446                 && fabs(baseplane->dist - plane->dist) < 0.01) continue;
00447         //
00448         plane = &dplanes[side->planenum^1];
00449         ChopWindingInPlace(&w, plane->normal, plane->dist, -0.1); //CLIP_EPSILON);
00450     } //end for
00451     return w;
00452 } //end of the function Q2_BrushSideWinding
00453 //===========================================================================
00454 //
00455 // Parameter:               -
00456 // Returns:                 -
00457 // Changes Globals:     -
00458 //===========================================================================
00459 int Q2_HintSkipBrush(dbrush_t *brush)
00460 {
00461     int j;
00462     dbrushside_t *brushside;
00463 
00464     for (j = 0; j < brush->numsides; j++)
00465     {
00466         brushside = &dbrushsides[brush->firstside + j];
00467         if (brushside->texinfo > 0)
00468         {
00469             if (texinfo[brushside->texinfo].flags & (SURF_SKIP|SURF_HINT))
00470             {
00471                 return true;
00472             } //end if
00473         } //end if
00474     } //end for
00475     return false;
00476 } //end of the function Q2_HintSkipBrush
00477 //===========================================================================
00478 // fix screwed brush texture references
00479 //
00480 // Parameter:               -
00481 // Returns:                 -
00482 // Changes Globals:     -
00483 //===========================================================================
00484 qboolean WindingIsTiny(winding_t *w);
00485 
00486 void Q2_FixTextureReferences(void)
00487 {
00488     int i, j, k, we;
00489     dbrushside_t *brushside;
00490     dbrush_t *brush;
00491     dface_t *face;
00492     winding_t *w;
00493 
00494     memset(brushsidetextured, false, MAX_MAP_BRUSHSIDES);
00495     //go over all the brushes
00496    for (i = 0; i < numbrushes; i++)
00497    {
00498         brush = &dbrushes[i];
00499         //hint brushes are not textured
00500         if (Q2_HintSkipBrush(brush)) continue;
00501         //go over all the sides of the brush
00502         for (j = 0; j < brush->numsides; j++)
00503         {
00504             brushside = &dbrushsides[brush->firstside + j];
00505             //
00506             w = Q2_BrushSideWinding(brush, brushside);
00507             if (!w)
00508             {
00509                 brushsidetextured[brush->firstside + j] = true;
00510                 continue;
00511             } //end if
00512             else
00513             {
00514                 //RemoveEqualPoints(w, 0.2);
00515                 if (WindingIsTiny(w))
00516                 {
00517                     FreeWinding(w);
00518                     brushsidetextured[brush->firstside + j] = true;
00519                     continue;
00520                 } //end if
00521                 else
00522                 {
00523                     we = WindingError(w);
00524                     if (we == WE_NOTENOUGHPOINTS
00525                         || we == WE_SMALLAREA
00526                         || we == WE_POINTBOGUSRANGE
00527 //                      || we == WE_NONCONVEX
00528                         )
00529                     {
00530                         FreeWinding(w);
00531                         brushsidetextured[brush->firstside + j] = true;
00532                         continue;
00533                     } //end if
00534                 } //end else
00535             } //end else
00536             if (WindingArea(w) < 20)
00537             {
00538                 brushsidetextured[brush->firstside + j] = true;
00539             } //end if
00540             //find a face for texturing this brush
00541             for (k = 0; k < numfaces; k++)
00542             {
00543                 face = &dfaces[k];
00544                 //if the face is in the same plane as the brush side
00545                 if ((face->planenum&~1) != (brushside->planenum&~1)) continue;
00546                 //if the face is partly or totally on the brush side
00547                 if (Q2_FaceOnWinding(face, w))
00548                 {
00549                     brushside->texinfo = face->texinfo;
00550                     brushsidetextured[brush->firstside + j] = true;
00551                     break;
00552                 } //end if
00553             } //end for
00554             FreeWinding(w);
00555         } //end for
00556     } //end for
00557 } //end of the function Q2_FixTextureReferences*/
00558 
00559 //#endif //ME
00560 
00561 
00562 /*
00563 ===============
00564 CompressVis
00565 
00566 ===============
00567 */
00568 int Q2_CompressVis (byte *vis, byte *dest)
00569 {
00570     int     j;
00571     int     rep;
00572     int     visrow;
00573     byte    *dest_p;
00574     
00575     dest_p = dest;
00576 //  visrow = (r_numvisleafs + 7)>>3;
00577     visrow = (dvis->numclusters + 7)>>3;
00578     
00579     for (j=0 ; j<visrow ; j++)
00580     {
00581         *dest_p++ = vis[j];
00582         if (vis[j])
00583             continue;
00584 
00585         rep = 1;
00586         for ( j++; j<visrow ; j++)
00587             if (vis[j] || rep == 255)
00588                 break;
00589             else
00590                 rep++;
00591         *dest_p++ = rep;
00592         j--;
00593     }
00594     
00595     return dest_p - dest;
00596 }
00597 
00598 
00599 /*
00600 ===================
00601 DecompressVis
00602 ===================
00603 */
00604 void Q2_DecompressVis (byte *in, byte *decompressed)
00605 {
00606     int     c;
00607     byte    *out;
00608     int     row;
00609 
00610 //  row = (r_numvisleafs+7)>>3; 
00611     row = (dvis->numclusters+7)>>3; 
00612     out = decompressed;
00613 
00614     do
00615     {
00616         if (*in)
00617         {
00618             *out++ = *in++;
00619             continue;
00620         }
00621     
00622         c = in[1];
00623         if (!c)
00624             Error ("DecompressVis: 0 repeat");
00625         in += 2;
00626         while (c)
00627         {
00628             *out++ = 0;
00629             c--;
00630         }
00631     } while (out - decompressed < row);
00632 }
00633 
00634 //=============================================================================
00635 
00636 /*
00637 =============
00638 SwapBSPFile
00639 
00640 Byte swaps all data in a bsp file.
00641 =============
00642 */
00643 void Q2_SwapBSPFile (qboolean todisk)
00644 {
00645     int             i, j;
00646     dmodel_t        *d;
00647 
00648     
00649 // models   
00650     for (i=0 ; i<nummodels ; i++)
00651     {
00652         d = &dmodels[i];
00653 
00654         d->firstface = LittleLong (d->firstface);
00655         d->numfaces = LittleLong (d->numfaces);
00656         d->headnode = LittleLong (d->headnode);
00657         
00658         for (j=0 ; j<3 ; j++)
00659         {
00660             d->mins[j] = LittleFloat(d->mins[j]);
00661             d->maxs[j] = LittleFloat(d->maxs[j]);
00662             d->origin[j] = LittleFloat(d->origin[j]);
00663         }
00664     }
00665 
00666 //
00667 // vertexes
00668 //
00669     for (i=0 ; i<numvertexes ; i++)
00670     {
00671         for (j=0 ; j<3 ; j++)
00672             dvertexes[i].point[j] = LittleFloat (dvertexes[i].point[j]);
00673     }
00674         
00675 //
00676 // planes
00677 //  
00678     for (i=0 ; i<numplanes ; i++)
00679     {
00680         for (j=0 ; j<3 ; j++)
00681             dplanes[i].normal[j] = LittleFloat (dplanes[i].normal[j]);
00682         dplanes[i].dist = LittleFloat (dplanes[i].dist);
00683         dplanes[i].type = LittleLong (dplanes[i].type);
00684     }
00685     
00686 //
00687 // texinfos
00688 //  
00689     for (i=0 ; i<numtexinfo ; i++)
00690     {
00691         for (j=0 ; j<8 ; j++)
00692             texinfo[i].vecs[0][j] = LittleFloat (texinfo[i].vecs[0][j]);
00693         texinfo[i].flags = LittleLong (texinfo[i].flags);
00694         texinfo[i].value = LittleLong (texinfo[i].value);
00695         texinfo[i].nexttexinfo = LittleLong (texinfo[i].nexttexinfo);
00696     }
00697     
00698 //
00699 // faces
00700 //
00701     for (i=0 ; i<numfaces ; i++)
00702     {
00703         dfaces[i].texinfo = LittleShort (dfaces[i].texinfo);
00704         dfaces[i].planenum = LittleShort (dfaces[i].planenum);
00705         dfaces[i].side = LittleShort (dfaces[i].side);
00706         dfaces[i].lightofs = LittleLong (dfaces[i].lightofs);
00707         dfaces[i].firstedge = LittleLong (dfaces[i].firstedge);
00708         dfaces[i].numedges = LittleShort (dfaces[i].numedges);
00709     }
00710 
00711 //
00712 // nodes
00713 //
00714     for (i=0 ; i<numnodes ; i++)
00715     {
00716         dnodes[i].planenum = LittleLong (dnodes[i].planenum);
00717         for (j=0 ; j<3 ; j++)
00718         {
00719             dnodes[i].mins[j] = LittleShort (dnodes[i].mins[j]);
00720             dnodes[i].maxs[j] = LittleShort (dnodes[i].maxs[j]);
00721         }
00722         dnodes[i].children[0] = LittleLong (dnodes[i].children[0]);
00723         dnodes[i].children[1] = LittleLong (dnodes[i].children[1]);
00724         dnodes[i].firstface = LittleShort (dnodes[i].firstface);
00725         dnodes[i].numfaces = LittleShort (dnodes[i].numfaces);
00726     }
00727 
00728 //
00729 // leafs
00730 //
00731     for (i=0 ; i<numleafs ; i++)
00732     {
00733         dleafs[i].contents = LittleLong (dleafs[i].contents);
00734         dleafs[i].cluster = LittleShort (dleafs[i].cluster);
00735         dleafs[i].area = LittleShort (dleafs[i].area);
00736         for (j=0 ; j<3 ; j++)
00737         {
00738             dleafs[i].mins[j] = LittleShort (dleafs[i].mins[j]);
00739             dleafs[i].maxs[j] = LittleShort (dleafs[i].maxs[j]);
00740         }
00741 
00742         dleafs[i].firstleafface = LittleShort (dleafs[i].firstleafface);
00743         dleafs[i].numleaffaces = LittleShort (dleafs[i].numleaffaces);
00744         dleafs[i].firstleafbrush = LittleShort (dleafs[i].firstleafbrush);
00745         dleafs[i].numleafbrushes = LittleShort (dleafs[i].numleafbrushes);
00746     }
00747 
00748 //
00749 // leaffaces
00750 //
00751     for (i=0 ; i<numleaffaces ; i++)
00752         dleaffaces[i] = LittleShort (dleaffaces[i]);
00753 
00754 //
00755 // leafbrushes
00756 //
00757     for (i=0 ; i<numleafbrushes ; i++)
00758         dleafbrushes[i] = LittleShort (dleafbrushes[i]);
00759 
00760 //
00761 // surfedges
00762 //
00763     for (i=0 ; i<numsurfedges ; i++)
00764         dsurfedges[i] = LittleLong (dsurfedges[i]);
00765 
00766 //
00767 // edges
00768 //
00769     for (i=0 ; i<numedges ; i++)
00770     {
00771         dedges[i].v[0] = LittleShort (dedges[i].v[0]);
00772         dedges[i].v[1] = LittleShort (dedges[i].v[1]);
00773     }
00774 
00775 //
00776 // brushes
00777 //
00778     for (i=0 ; i<numbrushes ; i++)
00779     {
00780         dbrushes[i].firstside = LittleLong (dbrushes[i].firstside);
00781         dbrushes[i].numsides = LittleLong (dbrushes[i].numsides);
00782         dbrushes[i].contents = LittleLong (dbrushes[i].contents);
00783     }
00784 
00785 //
00786 // areas
00787 //
00788     for (i=0 ; i<numareas ; i++)
00789     {
00790         dareas[i].numareaportals = LittleLong (dareas[i].numareaportals);
00791         dareas[i].firstareaportal = LittleLong (dareas[i].firstareaportal);
00792     }
00793 
00794 //
00795 // areasportals
00796 //
00797     for (i=0 ; i<numareaportals ; i++)
00798     {
00799         dareaportals[i].portalnum = LittleLong (dareaportals[i].portalnum);
00800         dareaportals[i].otherarea = LittleLong (dareaportals[i].otherarea);
00801     }
00802 
00803 //
00804 // brushsides
00805 //
00806     for (i=0 ; i<numbrushsides ; i++)
00807     {
00808         dbrushsides[i].planenum = LittleShort (dbrushsides[i].planenum);
00809         dbrushsides[i].texinfo = LittleShort (dbrushsides[i].texinfo);
00810     }
00811 
00812 //
00813 // visibility
00814 //
00815     if (todisk)
00816         j = dvis->numclusters;
00817     else
00818         j = LittleLong(dvis->numclusters);
00819     dvis->numclusters = LittleLong (dvis->numclusters);
00820     for (i=0 ; i<j ; i++)
00821     {
00822         dvis->bitofs[i][0] = LittleLong (dvis->bitofs[i][0]);
00823         dvis->bitofs[i][1] = LittleLong (dvis->bitofs[i][1]);
00824     }
00825 } //end of the function Q2_SwapBSPFile
00826 
00827 
00828 dheader_t   *header;
00829 
00830 int Q2_CopyLump (int lump, void *dest, int size, int maxsize)
00831 {
00832     int     length, ofs;
00833 
00834     length = header->lumps[lump].filelen;
00835     ofs = header->lumps[lump].fileofs;
00836     
00837     if (length % size)
00838         Error ("LoadBSPFile: odd lump size");
00839 
00840    if ((length/size) > maxsize)
00841       Error ("Q2_LoadBSPFile: exceeded max size for lump %d size %d > maxsize %d\n", lump, (length/size), maxsize);
00842 
00843     memcpy (dest, (byte *)header + ofs, length);
00844 
00845     return length / size;
00846 } //end of the function Q2_CopyLump
00847 
00848 /*
00849 =============
00850 LoadBSPFile
00851 =============
00852 */
00853 void Q2_LoadBSPFile(char *filename, int offset, int length)
00854 {
00855     int         i;
00856     
00857 //
00858 // load the file header
00859 //
00860     LoadFile (filename, (void **)&header, offset, length);
00861 
00862 // swap the header
00863     for (i=0 ; i< sizeof(dheader_t)/4 ; i++)
00864         ((int *)header)[i] = LittleLong ( ((int *)header)[i]);
00865 
00866     if (header->ident != IDBSPHEADER)
00867         Error ("%s is not a IBSP file", filename);
00868     if (header->version != BSPVERSION)
00869         Error ("%s is version %i, not %i", filename, header->version, BSPVERSION);
00870 
00871     nummodels = Q2_CopyLump (LUMP_MODELS, dmodels, sizeof(dmodel_t), MAX_MAP_MODELS);
00872     numvertexes = Q2_CopyLump (LUMP_VERTEXES, dvertexes, sizeof(dvertex_t), MAX_MAP_VERTS);
00873     numplanes = Q2_CopyLump (LUMP_PLANES, dplanes, sizeof(dplane_t), MAX_MAP_PLANES);
00874     numleafs = Q2_CopyLump (LUMP_LEAFS, dleafs, sizeof(dleaf_t), MAX_MAP_LEAFS);
00875     numnodes = Q2_CopyLump (LUMP_NODES, dnodes, sizeof(dnode_t), MAX_MAP_NODES);
00876     numtexinfo = Q2_CopyLump (LUMP_TEXINFO, texinfo, sizeof(texinfo_t), MAX_MAP_TEXINFO);
00877     numfaces = Q2_CopyLump (LUMP_FACES, dfaces, sizeof(dface_t), MAX_MAP_FACES);
00878     numleaffaces = Q2_CopyLump (LUMP_LEAFFACES, dleaffaces, sizeof(dleaffaces[0]), MAX_MAP_LEAFFACES);
00879     numleafbrushes = Q2_CopyLump (LUMP_LEAFBRUSHES, dleafbrushes, sizeof(dleafbrushes[0]), MAX_MAP_LEAFBRUSHES);
00880     numsurfedges = Q2_CopyLump (LUMP_SURFEDGES, dsurfedges, sizeof(dsurfedges[0]), MAX_MAP_SURFEDGES);
00881     numedges = Q2_CopyLump (LUMP_EDGES, dedges, sizeof(dedge_t), MAX_MAP_EDGES);
00882     numbrushes = Q2_CopyLump (LUMP_BRUSHES, dbrushes, sizeof(dbrush_t), MAX_MAP_BRUSHES);
00883     numbrushsides = Q2_CopyLump (LUMP_BRUSHSIDES, dbrushsides, sizeof(dbrushside_t), MAX_MAP_BRUSHSIDES);
00884     numareas = Q2_CopyLump (LUMP_AREAS, dareas, sizeof(darea_t), MAX_MAP_AREAS);
00885     numareaportals = Q2_CopyLump (LUMP_AREAPORTALS, dareaportals, sizeof(dareaportal_t), MAX_MAP_AREAPORTALS);
00886 
00887     visdatasize = Q2_CopyLump (LUMP_VISIBILITY, dvisdata, 1, MAX_MAP_VISIBILITY);
00888     lightdatasize = Q2_CopyLump (LUMP_LIGHTING, dlightdata, 1, MAX_MAP_LIGHTING);
00889     entdatasize = Q2_CopyLump (LUMP_ENTITIES, dentdata, 1, MAX_MAP_ENTSTRING);
00890 
00891     Q2_CopyLump (LUMP_POP, dpop, 1, MAX_MAP_DPOP);
00892 
00893     FreeMemory(header);     // everything has been copied out
00894         
00895 //
00896 // swap everything
00897 //  
00898     Q2_SwapBSPFile (false);
00899 
00900     Q2_FixTextureReferences();
00901 } //end of the function Q2_LoadBSPFile
00902 
00903 
00904 /*
00905 =============
00906 LoadBSPFileTexinfo
00907 
00908 Only loads the texinfo lump, so qdata can scan for textures
00909 =============
00910 */
00911 void    Q2_LoadBSPFileTexinfo (char *filename)
00912 {
00913     int         i;
00914     FILE        *f;
00915     int     length, ofs;
00916 
00917     header = GetMemory(sizeof(dheader_t));
00918 
00919     f = fopen (filename, "rb");
00920     fread (header, sizeof(dheader_t), 1, f);
00921 
00922 // swap the header
00923     for (i=0 ; i< sizeof(dheader_t)/4 ; i++)
00924         ((int *)header)[i] = LittleLong ( ((int *)header)[i]);
00925 
00926     if (header->ident != IDBSPHEADER)
00927         Error ("%s is not a IBSP file", filename);
00928     if (header->version != BSPVERSION)
00929         Error ("%s is version %i, not %i", filename, header->version, BSPVERSION);
00930 
00931 
00932     length = header->lumps[LUMP_TEXINFO].filelen;
00933     ofs = header->lumps[LUMP_TEXINFO].fileofs;
00934 
00935     fseek (f, ofs, SEEK_SET);
00936     fread (texinfo, length, 1, f);
00937     fclose (f);
00938 
00939     numtexinfo = length / sizeof(texinfo_t);
00940 
00941     FreeMemory(header);     // everything has been copied out
00942         
00943     Q2_SwapBSPFile (false);
00944 } //end of the function Q2_LoadBSPFileTexinfo
00945 
00946 
00947 //============================================================================
00948 
00949 FILE        *wadfile;
00950 dheader_t   outheader;
00951 
00952 void Q2_AddLump (int lumpnum, void *data, int len)
00953 {
00954     lump_t *lump;
00955 
00956     lump = &header->lumps[lumpnum];
00957     
00958     lump->fileofs = LittleLong( ftell(wadfile) );
00959     lump->filelen = LittleLong(len);
00960     SafeWrite (wadfile, data, (len+3)&~3);
00961 } //end of the function Q2_AddLump
00962 
00963 /*
00964 =============
00965 WriteBSPFile
00966 
00967 Swaps the bsp file in place, so it should not be referenced again
00968 =============
00969 */
00970 void    Q2_WriteBSPFile (char *filename)
00971 {       
00972     header = &outheader;
00973     memset (header, 0, sizeof(dheader_t));
00974     
00975     Q2_SwapBSPFile (true);
00976 
00977     header->ident = LittleLong (IDBSPHEADER);
00978     header->version = LittleLong (BSPVERSION);
00979     
00980     wadfile = SafeOpenWrite (filename);
00981     SafeWrite (wadfile, header, sizeof(dheader_t)); // overwritten later
00982 
00983     Q2_AddLump (LUMP_PLANES, dplanes, numplanes*sizeof(dplane_t));
00984     Q2_AddLump (LUMP_LEAFS, dleafs, numleafs*sizeof(dleaf_t));
00985     Q2_AddLump (LUMP_VERTEXES, dvertexes, numvertexes*sizeof(dvertex_t));
00986     Q2_AddLump (LUMP_NODES, dnodes, numnodes*sizeof(dnode_t));
00987     Q2_AddLump (LUMP_TEXINFO, texinfo, numtexinfo*sizeof(texinfo_t));
00988     Q2_AddLump (LUMP_FACES, dfaces, numfaces*sizeof(dface_t));
00989     Q2_AddLump (LUMP_BRUSHES, dbrushes, numbrushes*sizeof(dbrush_t));
00990     Q2_AddLump (LUMP_BRUSHSIDES, dbrushsides, numbrushsides*sizeof(dbrushside_t));
00991     Q2_AddLump (LUMP_LEAFFACES, dleaffaces, numleaffaces*sizeof(dleaffaces[0]));
00992     Q2_AddLump (LUMP_LEAFBRUSHES, dleafbrushes, numleafbrushes*sizeof(dleafbrushes[0]));
00993     Q2_AddLump (LUMP_SURFEDGES, dsurfedges, numsurfedges*sizeof(dsurfedges[0]));
00994     Q2_AddLump (LUMP_EDGES, dedges, numedges*sizeof(dedge_t));
00995     Q2_AddLump (LUMP_MODELS, dmodels, nummodels*sizeof(dmodel_t));
00996     Q2_AddLump (LUMP_AREAS, dareas, numareas*sizeof(darea_t));
00997     Q2_AddLump (LUMP_AREAPORTALS, dareaportals, numareaportals*sizeof(dareaportal_t));
00998 
00999     Q2_AddLump (LUMP_LIGHTING, dlightdata, lightdatasize);
01000     Q2_AddLump (LUMP_VISIBILITY, dvisdata, visdatasize);
01001     Q2_AddLump (LUMP_ENTITIES, dentdata, entdatasize);
01002     Q2_AddLump (LUMP_POP, dpop, sizeof(dpop));
01003     
01004     fseek (wadfile, 0, SEEK_SET);
01005     SafeWrite (wadfile, header, sizeof(dheader_t));
01006     fclose (wadfile);   
01007 } //end of the function Q2_WriteBSPFile
01008 
01009 //============================================================================
01010 
01011 /*
01012 =============
01013 PrintBSPFileSizes
01014 
01015 Dumps info about current file
01016 =============
01017 */
01018 void Q2_PrintBSPFileSizes (void)
01019 {
01020     if (!num_entities)
01021         Q2_ParseEntities();
01022 
01023     printf ("%6i models       %7i\n"
01024         ,nummodels, (int)(nummodels*sizeof(dmodel_t)));
01025     printf ("%6i brushes      %7i\n"
01026         ,numbrushes, (int)(numbrushes*sizeof(dbrush_t)));
01027     printf ("%6i brushsides   %7i\n"
01028         ,numbrushsides, (int)(numbrushsides*sizeof(dbrushside_t)));
01029     printf ("%6i planes       %7i\n"
01030         ,numplanes, (int)(numplanes*sizeof(dplane_t)));
01031     printf ("%6i texinfo      %7i\n"
01032         ,numtexinfo, (int)(numtexinfo*sizeof(texinfo_t)));
01033     printf ("%6i entdata      %7i\n", num_entities, entdatasize);
01034 
01035     printf ("\n");
01036 
01037     printf ("%6i vertexes     %7i\n"
01038         ,numvertexes, (int)(numvertexes*sizeof(dvertex_t)));
01039     printf ("%6i nodes        %7i\n"
01040         ,numnodes, (int)(numnodes*sizeof(dnode_t)));
01041     printf ("%6i faces        %7i\n"
01042         ,numfaces, (int)(numfaces*sizeof(dface_t)));
01043     printf ("%6i leafs        %7i\n"
01044         ,numleafs, (int)(numleafs*sizeof(dleaf_t)));
01045     printf ("%6i leaffaces    %7i\n"
01046         ,numleaffaces, (int)(numleaffaces*sizeof(dleaffaces[0])));
01047     printf ("%6i leafbrushes  %7i\n"
01048         ,numleafbrushes, (int)(numleafbrushes*sizeof(dleafbrushes[0])));
01049     printf ("%6i surfedges    %7i\n"
01050         ,numsurfedges, (int)(numsurfedges*sizeof(dsurfedges[0])));
01051     printf ("%6i edges        %7i\n"
01052         ,numedges, (int)(numedges*sizeof(dedge_t)));
01053 //NEW
01054     printf ("%6i areas        %7i\n"
01055         ,numareas, (int)(numareas*sizeof(darea_t)));
01056     printf ("%6i areaportals  %7i\n"
01057         ,numareaportals, (int)(numareaportals*sizeof(dareaportal_t)));
01058 //ENDNEW
01059     printf ("      lightdata    %7i\n", lightdatasize);
01060     printf ("      visdata      %7i\n", visdatasize);
01061 } //end of the function Q2_PrintBSPFileSizes
01062 
01063 /*
01064 ================
01065 ParseEntities
01066 
01067 Parses the dentdata string into entities
01068 ================
01069 */
01070 void Q2_ParseEntities (void)
01071 {
01072     script_t *script;
01073 
01074     num_entities = 0;
01075     script = LoadScriptMemory(dentdata, entdatasize, "*Quake2 bsp file");
01076     SetScriptFlags(script, SCFL_NOSTRINGWHITESPACES |
01077                                     SCFL_NOSTRINGESCAPECHARS);
01078 
01079     while(ParseEntity(script))
01080     {
01081     } //end while
01082 
01083     FreeScript(script);
01084 } //end of the function Q2_ParseEntities
01085 
01086 
01087 /*
01088 ================
01089 UnparseEntities
01090 
01091 Generates the dentdata string from all the entities
01092 ================
01093 */
01094 void Q2_UnparseEntities (void)
01095 {
01096     char    *buf, *end;
01097     epair_t *ep;
01098     char    line[2048];
01099     int     i;
01100     char    key[1024], value[1024];
01101 
01102     buf = dentdata;
01103     end = buf;
01104     *end = 0;
01105     
01106     for (i=0 ; i<num_entities ; i++)
01107     {
01108         ep = entities[i].epairs;
01109         if (!ep)
01110             continue;   // ent got removed
01111         
01112         strcat (end,"{\n");
01113         end += 2;
01114                 
01115         for (ep = entities[i].epairs ; ep ; ep=ep->next)
01116         {
01117             strcpy (key, ep->key);
01118             StripTrailing (key);
01119             strcpy (value, ep->value);
01120             StripTrailing (value);
01121                 
01122             sprintf (line, "\"%s\" \"%s\"\n", key, value);
01123             strcat (end, line);
01124             end += strlen(line);
01125         }
01126         strcat (end,"}\n");
01127         end += 2;
01128 
01129         if (end > buf + MAX_MAP_ENTSTRING)
01130             Error ("Entity text too long");
01131     }
01132     entdatasize = end - buf + 1;
01133 } //end of the function Q2_UnparseEntities
01134 

Generated on Thu Aug 25 12:37:16 2005 for Quake III Arena by  doxygen 1.3.9.1