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

l_bsp_q3.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 "l_qfiles.h"
00030 #include "l_bsp_q3.h"
00031 #include "l_bsp_ent.h"
00032 
00033 void Q3_ParseEntities (void);
00034 void Q3_PrintBSPFileSizes(void);
00035 
00036 void GetLeafNums (void);
00037 
00038 //=============================================================================
00039 
00040 #define WCONVEX_EPSILON     0.5
00041 
00042 
00043 int             q3_nummodels;
00044 q3_dmodel_t     *q3_dmodels;//[MAX_MAP_MODELS];
00045 
00046 int             q3_numShaders;
00047 q3_dshader_t    *q3_dshaders;//[Q3_MAX_MAP_SHADERS];
00048 
00049 int             q3_entdatasize;
00050 char            *q3_dentdata;//[Q3_MAX_MAP_ENTSTRING];
00051 
00052 int             q3_numleafs;
00053 q3_dleaf_t      *q3_dleafs;//[Q3_MAX_MAP_LEAFS];
00054 
00055 int             q3_numplanes;
00056 q3_dplane_t     *q3_dplanes;//[Q3_MAX_MAP_PLANES];
00057 
00058 int             q3_numnodes;
00059 q3_dnode_t      *q3_dnodes;//[Q3_MAX_MAP_NODES];
00060 
00061 int             q3_numleafsurfaces;
00062 int             *q3_dleafsurfaces;//[Q3_MAX_MAP_LEAFFACES];
00063 
00064 int             q3_numleafbrushes;
00065 int             *q3_dleafbrushes;//[Q3_MAX_MAP_LEAFBRUSHES];
00066 
00067 int             q3_numbrushes;
00068 q3_dbrush_t     *q3_dbrushes;//[Q3_MAX_MAP_BRUSHES];
00069 
00070 int             q3_numbrushsides;
00071 q3_dbrushside_t *q3_dbrushsides;//[Q3_MAX_MAP_BRUSHSIDES];
00072 
00073 int             q3_numLightBytes;
00074 byte            *q3_lightBytes;//[Q3_MAX_MAP_LIGHTING];
00075 
00076 int             q3_numGridPoints;
00077 byte            *q3_gridData;//[Q3_MAX_MAP_LIGHTGRID];
00078 
00079 int             q3_numVisBytes;
00080 byte            *q3_visBytes;//[Q3_MAX_MAP_VISIBILITY];
00081 
00082 int             q3_numDrawVerts;
00083 q3_drawVert_t   *q3_drawVerts;//[Q3_MAX_MAP_DRAW_VERTS];
00084 
00085 int             q3_numDrawIndexes;
00086 int             *q3_drawIndexes;//[Q3_MAX_MAP_DRAW_INDEXES];
00087 
00088 int             q3_numDrawSurfaces;
00089 q3_dsurface_t   *q3_drawSurfaces;//[Q3_MAX_MAP_DRAW_SURFS];
00090 
00091 int             q3_numFogs;
00092 q3_dfog_t       *q3_dfogs;//[Q3_MAX_MAP_FOGS];
00093 
00094 char            q3_dbrushsidetextured[Q3_MAX_MAP_BRUSHSIDES];
00095 
00096 extern qboolean forcesidesvisible;
00097 
00098 //===========================================================================
00099 //
00100 // Parameter:           -
00101 // Returns:             -
00102 // Changes Globals:     -
00103 //===========================================================================
00104 void Q3_FreeMaxBSP(void)
00105 {
00106     if (q3_dmodels) FreeMemory(q3_dmodels);
00107     q3_dmodels = NULL;
00108     q3_nummodels = 0;
00109     if (q3_dshaders) FreeMemory(q3_dshaders);
00110     q3_dshaders = NULL;
00111     q3_numShaders = 0;
00112     if (q3_dentdata) FreeMemory(q3_dentdata);
00113     q3_dentdata = NULL;
00114     q3_entdatasize = 0;
00115     if (q3_dleafs) FreeMemory(q3_dleafs);
00116     q3_dleafs = NULL;
00117     q3_numleafs = 0;
00118     if (q3_dplanes) FreeMemory(q3_dplanes);
00119     q3_dplanes = NULL;
00120     q3_numplanes = 0;
00121     if (q3_dnodes) FreeMemory(q3_dnodes);
00122     q3_dnodes = NULL;
00123     q3_numnodes = 0;
00124     if (q3_dleafsurfaces) FreeMemory(q3_dleafsurfaces);
00125     q3_dleafsurfaces = NULL;
00126     q3_numleafsurfaces = 0;
00127     if (q3_dleafbrushes) FreeMemory(q3_dleafbrushes);
00128     q3_dleafbrushes = NULL;
00129     q3_numleafbrushes = 0;
00130     if (q3_dbrushes) FreeMemory(q3_dbrushes);
00131     q3_dbrushes = NULL;
00132     q3_numbrushes = 0;
00133     if (q3_dbrushsides) FreeMemory(q3_dbrushsides);
00134     q3_dbrushsides = NULL;
00135     q3_numbrushsides = 0;
00136     if (q3_lightBytes) FreeMemory(q3_lightBytes);
00137     q3_lightBytes = NULL;
00138     q3_numLightBytes = 0;
00139     if (q3_gridData) FreeMemory(q3_gridData);
00140     q3_gridData = NULL;
00141     q3_numGridPoints = 0;
00142     if (q3_visBytes) FreeMemory(q3_visBytes);
00143     q3_visBytes = NULL;
00144     q3_numVisBytes = 0;
00145     if (q3_drawVerts) FreeMemory(q3_drawVerts);
00146     q3_drawVerts = NULL;
00147     q3_numDrawVerts = 0;
00148     if (q3_drawIndexes) FreeMemory(q3_drawIndexes);
00149     q3_drawIndexes = NULL;
00150     q3_numDrawIndexes = 0;
00151     if (q3_drawSurfaces) FreeMemory(q3_drawSurfaces);
00152     q3_drawSurfaces = NULL;
00153     q3_numDrawSurfaces = 0;
00154     if (q3_dfogs) FreeMemory(q3_dfogs);
00155     q3_dfogs = NULL;
00156     q3_numFogs = 0;
00157 } //end of the function Q3_FreeMaxBSP
00158 
00159 
00160 //===========================================================================
00161 //
00162 // Parameter:           -
00163 // Returns:             -
00164 // Changes Globals:     -
00165 //===========================================================================
00166 void Q3_PlaneFromPoints(vec3_t p0, vec3_t p1, vec3_t p2, vec3_t normal, float *dist)
00167 {
00168     vec3_t t1, t2;
00169 
00170     VectorSubtract(p0, p1, t1);
00171     VectorSubtract(p2, p1, t2);
00172     CrossProduct(t1, t2, normal);
00173     VectorNormalize(normal);
00174 
00175     *dist = DotProduct(p0, normal);
00176 } //end of the function PlaneFromPoints
00177 //===========================================================================
00178 //
00179 // Parameter:               -
00180 // Returns:                 -
00181 // Changes Globals:     -
00182 //===========================================================================
00183 void Q3_SurfacePlane(q3_dsurface_t *surface, vec3_t normal, float *dist)
00184 {
00185     int i;
00186     float *p0, *p1, *p2;
00187     vec3_t t1, t2;
00188 
00189     p0 = q3_drawVerts[surface->firstVert].xyz;
00190     for (i = 1; i < surface->numVerts-1; i++)
00191     {
00192         p1 = q3_drawVerts[surface->firstVert + ((i) % surface->numVerts)].xyz;
00193         p2 = q3_drawVerts[surface->firstVert + ((i+1) % surface->numVerts)].xyz;
00194         VectorSubtract(p0, p1, t1);
00195         VectorSubtract(p2, p1, t2);
00196         CrossProduct(t1, t2, normal);
00197         VectorNormalize(normal);
00198         if (VectorLength(normal)) break;
00199     } //end for*/
00200 /*
00201     float dot;
00202     for (i = 0; i < surface->numVerts; i++)
00203     {
00204         p0 = q3_drawVerts[surface->firstVert + ((i) % surface->numVerts)].xyz;
00205         p1 = q3_drawVerts[surface->firstVert + ((i+1) % surface->numVerts)].xyz;
00206         p2 = q3_drawVerts[surface->firstVert + ((i+2) % surface->numVerts)].xyz;
00207         VectorSubtract(p0, p1, t1);
00208         VectorSubtract(p2, p1, t2);
00209         VectorNormalize(t1);
00210         VectorNormalize(t2);
00211         dot = DotProduct(t1, t2);
00212         if (dot > -0.9 && dot < 0.9 &&
00213             VectorLength(t1) > 0.1 && VectorLength(t2) > 0.1) break;
00214     } //end for
00215     CrossProduct(t1, t2, normal);
00216     VectorNormalize(normal);
00217 */
00218     if (VectorLength(normal) < 0.9)
00219     {
00220         printf("surface %d bogus normal vector %f %f %f\n", surface - q3_drawSurfaces, normal[0], normal[1], normal[2]);
00221         printf("t1 = %f %f %f, t2 = %f %f %f\n", t1[0], t1[1], t1[2], t2[0], t2[1], t2[2]);
00222         for (i = 0; i < surface->numVerts; i++)
00223         {
00224             p1 = q3_drawVerts[surface->firstVert + ((i) % surface->numVerts)].xyz;
00225             Log_Print("p%d = %f %f %f\n", i, p1[0], p1[1], p1[2]);
00226         } //end for
00227     } //end if
00228     *dist = DotProduct(p0, normal);
00229 } //end of the function Q3_SurfacePlane
00230 //===========================================================================
00231 //
00232 // Parameter:               -
00233 // Returns:                 -
00234 // Changes Globals:     -
00235 //===========================================================================
00236 q3_dplane_t *q3_surfaceplanes;
00237 
00238 void Q3_CreatePlanarSurfacePlanes(void)
00239 {
00240     int i;
00241     q3_dsurface_t *surface;
00242 
00243     Log_Print("creating planar surface planes...\n");
00244     q3_surfaceplanes = (q3_dplane_t *) GetClearedMemory(q3_numDrawSurfaces * sizeof(q3_dplane_t));
00245 
00246     for (i = 0; i < q3_numDrawSurfaces; i++)
00247     {
00248         surface = &q3_drawSurfaces[i];
00249         if (surface->surfaceType != MST_PLANAR) continue;
00250         Q3_SurfacePlane(surface, q3_surfaceplanes[i].normal, &q3_surfaceplanes[i].dist);
00251         //Log_Print("normal = %f %f %f, dist = %f\n", q3_surfaceplanes[i].normal[0],
00252         //                                          q3_surfaceplanes[i].normal[1],
00253         //                                          q3_surfaceplanes[i].normal[2], q3_surfaceplanes[i].dist);
00254     } //end for
00255 } //end of the function Q3_CreatePlanarSurfacePlanes
00256 //===========================================================================
00257 //
00258 // Parameter:               -
00259 // Returns:                 -
00260 // Changes Globals:     -
00261 //===========================================================================
00262 /*
00263 void Q3_SurfacePlane(q3_dsurface_t *surface, vec3_t normal, float *dist)
00264 {
00265     //take the plane information from the lightmap vector
00266     //VectorCopy(surface->lightmapVecs[2], normal);
00267     //calculate plane dist with first surface vertex
00268     //*dist = DotProduct(q3_drawVerts[surface->firstVert].xyz, normal);
00269     Q3_PlaneFromPoints(q3_drawVerts[surface->firstVert].xyz,
00270                         q3_drawVerts[surface->firstVert+1].xyz,
00271                         q3_drawVerts[surface->firstVert+2].xyz, normal, dist);
00272 } //end of the function Q3_SurfacePlane*/
00273 //===========================================================================
00274 // returns the amount the face and the winding overlap
00275 //
00276 // Parameter:               -
00277 // Returns:                 -
00278 // Changes Globals:     -
00279 //===========================================================================
00280 float Q3_FaceOnWinding(q3_dsurface_t *surface, winding_t *winding)
00281 {
00282     int i;
00283     float dist, area;
00284     q3_dplane_t plane;
00285     vec_t *v1, *v2;
00286     vec3_t normal, edgevec;
00287     winding_t *w;
00288 
00289     //copy the winding before chopping
00290     w = CopyWinding(winding);
00291     //retrieve the surface plane
00292     Q3_SurfacePlane(surface, plane.normal, &plane.dist);
00293     //chop the winding with the surface edge planes
00294     for (i = 0; i < surface->numVerts && w; i++)
00295     {
00296         v1 = q3_drawVerts[surface->firstVert + ((i) % surface->numVerts)].xyz;
00297         v2 = q3_drawVerts[surface->firstVert + ((i+1) % surface->numVerts)].xyz;
00298         //create a plane through the edge from v1 to v2, orthogonal to the
00299         //surface plane and with the normal vector pointing inward
00300         VectorSubtract(v2, v1, edgevec);
00301         CrossProduct(edgevec, plane.normal, normal);
00302         VectorNormalize(normal);
00303         dist = DotProduct(normal, v1);
00304         //
00305         ChopWindingInPlace(&w, normal, dist, -0.1); //CLIP_EPSILON
00306     } //end for
00307     if (w)
00308     {
00309         area = WindingArea(w);
00310         FreeWinding(w);
00311         return area;
00312     } //end if
00313     return 0;
00314 } //end of the function Q3_FaceOnWinding
00315 //===========================================================================
00316 // creates a winding for the given brush side on the given brush
00317 //
00318 // Parameter:               -
00319 // Returns:                 -
00320 // Changes Globals:     -
00321 //===========================================================================
00322 winding_t *Q3_BrushSideWinding(q3_dbrush_t *brush, q3_dbrushside_t *baseside)
00323 {
00324     int i;
00325     q3_dplane_t *baseplane, *plane;
00326     winding_t *w;
00327     q3_dbrushside_t *side;
00328     
00329     //create a winding for the brush side with the given planenumber
00330     baseplane = &q3_dplanes[baseside->planeNum];
00331     w = BaseWindingForPlane(baseplane->normal, baseplane->dist);
00332     for (i = 0; i < brush->numSides && w; i++)
00333     {
00334         side = &q3_dbrushsides[brush->firstSide + i];
00335         //don't chop with the base plane
00336         if (side->planeNum == baseside->planeNum) continue;
00337         //also don't use planes that are almost equal
00338         plane = &q3_dplanes[side->planeNum];
00339         if (DotProduct(baseplane->normal, plane->normal) > 0.999
00340                 && fabs(baseplane->dist - plane->dist) < 0.01) continue;
00341         //
00342         plane = &q3_dplanes[side->planeNum^1];
00343         ChopWindingInPlace(&w, plane->normal, plane->dist, -0.1); //CLIP_EPSILON);
00344     } //end for
00345     return w;
00346 } //end of the function Q3_BrushSideWinding
00347 //===========================================================================
00348 // fix screwed brush texture references
00349 //
00350 // Parameter:               -
00351 // Returns:                 -
00352 // Changes Globals:     -
00353 //===========================================================================
00354 qboolean WindingIsTiny(winding_t *w);
00355 
00356 void Q3_FindVisibleBrushSides(void)
00357 {
00358     int i, j, k, we, numtextured, numsides;
00359     float dot;
00360     q3_dplane_t *plane;
00361     q3_dbrushside_t *brushside;
00362     q3_dbrush_t *brush;
00363     q3_dsurface_t *surface;
00364     winding_t *w;
00365 
00366     memset(q3_dbrushsidetextured, false, Q3_MAX_MAP_BRUSHSIDES);
00367     //
00368     numsides = 0;
00369     //create planes for the planar surfaces
00370     Q3_CreatePlanarSurfacePlanes();
00371     Log_Print("searching visible brush sides...\n");
00372     Log_Print("%6d brush sides", numsides);
00373     //go over all the brushes
00374     for (i = 0; i < q3_numbrushes; i++)
00375     {
00376         brush = &q3_dbrushes[i];
00377         //go over all the sides of the brush
00378         for (j = 0; j < brush->numSides; j++)
00379         {
00380             qprintf("\r%6d", numsides++);
00381             brushside = &q3_dbrushsides[brush->firstSide + j];
00382             //
00383             w = Q3_BrushSideWinding(brush, brushside);
00384             if (!w)
00385             {
00386                 q3_dbrushsidetextured[brush->firstSide + j] = true;
00387                 continue;
00388             } //end if
00389             else
00390             {
00391                 //RemoveEqualPoints(w, 0.2);
00392                 if (WindingIsTiny(w))
00393                 {
00394                     FreeWinding(w);
00395                     q3_dbrushsidetextured[brush->firstSide + j] = true;
00396                     continue;
00397                 } //end if
00398                 else
00399                 {
00400                     we = WindingError(w);
00401                     if (we == WE_NOTENOUGHPOINTS
00402                         || we == WE_SMALLAREA
00403                         || we == WE_POINTBOGUSRANGE
00404 //                      || we == WE_NONCONVEX
00405                         )
00406                     {
00407                         FreeWinding(w);
00408                         q3_dbrushsidetextured[brush->firstSide + j] = true;
00409                         continue;
00410                     } //end if
00411                 } //end else
00412             } //end else
00413             if (WindingArea(w) < 20)
00414             {
00415                 q3_dbrushsidetextured[brush->firstSide + j] = true;
00416                 continue;
00417             } //end if
00418             //find a face for texturing this brush
00419             for (k = 0; k < q3_numDrawSurfaces; k++)
00420             {
00421                 surface = &q3_drawSurfaces[k];
00422                 if (surface->surfaceType != MST_PLANAR) continue;
00423                 //
00424                 //Q3_SurfacePlane(surface, plane.normal, &plane.dist);
00425                 plane = &q3_surfaceplanes[k];
00426                 //the surface plane and the brush side plane should be pretty much the same
00427                 if (fabs(fabs(plane->dist) - fabs(q3_dplanes[brushside->planeNum].dist)) > 5) continue;
00428                 dot = DotProduct(plane->normal, q3_dplanes[brushside->planeNum].normal);
00429                 if (dot > -0.9 && dot < 0.9) continue;
00430                 //if the face is partly or totally on the brush side
00431                 if (Q3_FaceOnWinding(surface, w))
00432                 {
00433                     q3_dbrushsidetextured[brush->firstSide + j] = true;
00434                     //Log_Write("Q3_FaceOnWinding");
00435                     break;
00436                 } //end if
00437             } //end for
00438             FreeWinding(w);
00439         } //end for
00440     } //end for
00441     qprintf("\r%6d brush sides\n", numsides);
00442     numtextured = 0;
00443     for (i = 0; i < q3_numbrushsides; i++)
00444     {
00445         if (forcesidesvisible) q3_dbrushsidetextured[i] = true;
00446         if (q3_dbrushsidetextured[i]) numtextured++;
00447     } //end for
00448     Log_Print("%d brush sides textured out of %d\n", numtextured, q3_numbrushsides);
00449 } //end of the function Q3_FindVisibleBrushSides
00450 
00451 /*
00452 =============
00453 Q3_SwapBlock
00454 
00455 If all values are 32 bits, this can be used to swap everything
00456 =============
00457 */
00458 void Q3_SwapBlock( int *block, int sizeOfBlock ) {
00459     int     i;
00460 
00461     sizeOfBlock >>= 2;
00462     for ( i = 0 ; i < sizeOfBlock ; i++ ) {
00463         block[i] = LittleLong( block[i] );
00464     }
00465 } //end of the function Q3_SwapBlock
00466 
00467 /*
00468 =============
00469 Q3_SwapBSPFile
00470 
00471 Byte swaps all data in a bsp file.
00472 =============
00473 */
00474 void Q3_SwapBSPFile( void ) {
00475     int             i;
00476     
00477     // models   
00478     Q3_SwapBlock( (int *)q3_dmodels, q3_nummodels * sizeof( q3_dmodels[0] ) );
00479 
00480     // shaders (don't swap the name)
00481     for ( i = 0 ; i < q3_numShaders ; i++ ) {
00482         q3_dshaders[i].contentFlags = LittleLong( q3_dshaders[i].contentFlags );
00483         q3_dshaders[i].surfaceFlags = LittleLong( q3_dshaders[i].surfaceFlags );
00484     }
00485 
00486     // planes
00487     Q3_SwapBlock( (int *)q3_dplanes, q3_numplanes * sizeof( q3_dplanes[0] ) );
00488     
00489     // nodes
00490     Q3_SwapBlock( (int *)q3_dnodes, q3_numnodes * sizeof( q3_dnodes[0] ) );
00491 
00492     // leafs
00493     Q3_SwapBlock( (int *)q3_dleafs, q3_numleafs * sizeof( q3_dleafs[0] ) );
00494 
00495     // leaffaces
00496     Q3_SwapBlock( (int *)q3_dleafsurfaces, q3_numleafsurfaces * sizeof( q3_dleafsurfaces[0] ) );
00497 
00498     // leafbrushes
00499     Q3_SwapBlock( (int *)q3_dleafbrushes, q3_numleafbrushes * sizeof( q3_dleafbrushes[0] ) );
00500 
00501     // brushes
00502     Q3_SwapBlock( (int *)q3_dbrushes, q3_numbrushes * sizeof( q3_dbrushes[0] ) );
00503 
00504     // brushsides
00505     Q3_SwapBlock( (int *)q3_dbrushsides, q3_numbrushsides * sizeof( q3_dbrushsides[0] ) );
00506 
00507     // vis
00508     ((int *)&q3_visBytes)[0] = LittleLong( ((int *)&q3_visBytes)[0] );
00509     ((int *)&q3_visBytes)[1] = LittleLong( ((int *)&q3_visBytes)[1] );
00510 
00511     // drawverts (don't swap colors )
00512     for ( i = 0 ; i < q3_numDrawVerts ; i++ ) {
00513         q3_drawVerts[i].lightmap[0] = LittleFloat( q3_drawVerts[i].lightmap[0] );
00514         q3_drawVerts[i].lightmap[1] = LittleFloat( q3_drawVerts[i].lightmap[1] );
00515         q3_drawVerts[i].st[0] = LittleFloat( q3_drawVerts[i].st[0] );
00516         q3_drawVerts[i].st[1] = LittleFloat( q3_drawVerts[i].st[1] );
00517         q3_drawVerts[i].xyz[0] = LittleFloat( q3_drawVerts[i].xyz[0] );
00518         q3_drawVerts[i].xyz[1] = LittleFloat( q3_drawVerts[i].xyz[1] );
00519         q3_drawVerts[i].xyz[2] = LittleFloat( q3_drawVerts[i].xyz[2] );
00520         q3_drawVerts[i].normal[0] = LittleFloat( q3_drawVerts[i].normal[0] );
00521         q3_drawVerts[i].normal[1] = LittleFloat( q3_drawVerts[i].normal[1] );
00522         q3_drawVerts[i].normal[2] = LittleFloat( q3_drawVerts[i].normal[2] );
00523     }
00524 
00525     // drawindexes
00526     Q3_SwapBlock( (int *)q3_drawIndexes, q3_numDrawIndexes * sizeof( q3_drawIndexes[0] ) );
00527 
00528     // drawsurfs
00529     Q3_SwapBlock( (int *)q3_drawSurfaces, q3_numDrawSurfaces * sizeof( q3_drawSurfaces[0] ) );
00530 
00531     // fogs
00532     for ( i = 0 ; i < q3_numFogs ; i++ ) {
00533         q3_dfogs[i].brushNum = LittleLong( q3_dfogs[i].brushNum );
00534     }
00535 }
00536 
00537 
00538 
00539 /*
00540 =============
00541 Q3_CopyLump
00542 =============
00543 */
00544 int Q3_CopyLump( q3_dheader_t   *header, int lump, void **dest, int size ) {
00545     int     length, ofs;
00546 
00547     length = header->lumps[lump].filelen;
00548     ofs = header->lumps[lump].fileofs;
00549     
00550     if ( length % size ) {
00551         Error ("Q3_LoadBSPFile: odd lump size");
00552     }
00553 
00554     *dest = GetMemory(length);
00555 
00556     memcpy( *dest, (byte *)header + ofs, length );
00557 
00558     return length / size;
00559 }
00560 
00561 /*
00562 =============
00563 CountTriangles
00564 =============
00565 */
00566 void CountTriangles( void ) {
00567     int i, numTris, numPatchTris;
00568     q3_dsurface_t *surface;
00569 
00570     numTris = numPatchTris = 0;
00571     for ( i = 0; i < q3_numDrawSurfaces; i++ ) {
00572         surface = &q3_drawSurfaces[i];
00573 
00574         numTris += surface->numIndexes / 3;
00575 
00576         if ( surface->patchWidth ) {
00577             numPatchTris += surface->patchWidth * surface->patchHeight * 2;
00578         }
00579     }
00580 
00581     Log_Print( "%6d triangles\n", numTris );
00582     Log_Print( "%6d patch tris\n", numPatchTris );
00583 }
00584 
00585 /*
00586 =============
00587 Q3_LoadBSPFile
00588 =============
00589 */
00590 void    Q3_LoadBSPFile(struct quakefile_s *qf)
00591 {
00592     q3_dheader_t    *header;
00593 
00594     // load the file header
00595     //LoadFile(filename, (void **)&header, offset, length);
00596     //
00597     LoadQuakeFile(qf, (void **)&header);
00598 
00599     // swap the header
00600     Q3_SwapBlock( (int *)header, sizeof(*header) );
00601 
00602     if ( header->ident != Q3_BSP_IDENT ) {
00603         Error( "%s is not a IBSP file", qf->filename );
00604     }
00605     if ( header->version != Q3_BSP_VERSION ) {
00606         Error( "%s is version %i, not %i", qf->filename, header->version, Q3_BSP_VERSION );
00607     }
00608 
00609     q3_numShaders = Q3_CopyLump( header, Q3_LUMP_SHADERS, (void *) &q3_dshaders, sizeof(q3_dshader_t) );
00610     q3_nummodels = Q3_CopyLump( header, Q3_LUMP_MODELS, (void *) &q3_dmodels, sizeof(q3_dmodel_t) );
00611     q3_numplanes = Q3_CopyLump( header, Q3_LUMP_PLANES, (void *) &q3_dplanes, sizeof(q3_dplane_t) );
00612     q3_numleafs = Q3_CopyLump( header, Q3_LUMP_LEAFS, (void *) &q3_dleafs, sizeof(q3_dleaf_t) );
00613     q3_numnodes = Q3_CopyLump( header, Q3_LUMP_NODES, (void *) &q3_dnodes, sizeof(q3_dnode_t) );
00614     q3_numleafsurfaces = Q3_CopyLump( header, Q3_LUMP_LEAFSURFACES, (void *) &q3_dleafsurfaces, sizeof(q3_dleafsurfaces[0]) );
00615     q3_numleafbrushes = Q3_CopyLump( header, Q3_LUMP_LEAFBRUSHES, (void *) &q3_dleafbrushes, sizeof(q3_dleafbrushes[0]) );
00616     q3_numbrushes = Q3_CopyLump( header, Q3_LUMP_BRUSHES, (void *) &q3_dbrushes, sizeof(q3_dbrush_t) );
00617     q3_numbrushsides = Q3_CopyLump( header, Q3_LUMP_BRUSHSIDES, (void *) &q3_dbrushsides, sizeof(q3_dbrushside_t) );
00618     q3_numDrawVerts = Q3_CopyLump( header, Q3_LUMP_DRAWVERTS, (void *) &q3_drawVerts, sizeof(q3_drawVert_t) );
00619     q3_numDrawSurfaces = Q3_CopyLump( header, Q3_LUMP_SURFACES, (void *) &q3_drawSurfaces, sizeof(q3_dsurface_t) );
00620     q3_numFogs = Q3_CopyLump( header, Q3_LUMP_FOGS, (void *) &q3_dfogs, sizeof(q3_dfog_t) );
00621     q3_numDrawIndexes = Q3_CopyLump( header, Q3_LUMP_DRAWINDEXES, (void *) &q3_drawIndexes, sizeof(q3_drawIndexes[0]) );
00622 
00623     q3_numVisBytes = Q3_CopyLump( header, Q3_LUMP_VISIBILITY, (void *) &q3_visBytes, 1 );
00624     q3_numLightBytes = Q3_CopyLump( header, Q3_LUMP_LIGHTMAPS, (void *) &q3_lightBytes, 1 );
00625     q3_entdatasize = Q3_CopyLump( header, Q3_LUMP_ENTITIES, (void *) &q3_dentdata, 1);
00626 
00627     q3_numGridPoints = Q3_CopyLump( header, Q3_LUMP_LIGHTGRID, (void *) &q3_gridData, 8 );
00628 
00629     CountTriangles();
00630 
00631     FreeMemory( header );       // everything has been copied out
00632         
00633     // swap everything
00634     Q3_SwapBSPFile();
00635 
00636     Q3_FindVisibleBrushSides();
00637 
00638     //Q3_PrintBSPFileSizes();
00639 }
00640 
00641 
00642 //============================================================================
00643 
00644 /*
00645 =============
00646 Q3_AddLump
00647 =============
00648 */
00649 void Q3_AddLump( FILE *bspfile, q3_dheader_t *header, int lumpnum, void *data, int len ) {
00650     q3_lump_t *lump;
00651 
00652     lump = &header->lumps[lumpnum];
00653     
00654     lump->fileofs = LittleLong( ftell(bspfile) );
00655     lump->filelen = LittleLong( len );
00656     SafeWrite( bspfile, data, (len+3)&~3 );
00657 }
00658 
00659 /*
00660 =============
00661 Q3_WriteBSPFile
00662 
00663 Swaps the bsp file in place, so it should not be referenced again
00664 =============
00665 */
00666 void    Q3_WriteBSPFile( char *filename )
00667 {
00668     q3_dheader_t    outheader, *header;
00669     FILE        *bspfile;
00670 
00671     header = &outheader;
00672     memset( header, 0, sizeof(q3_dheader_t) );
00673     
00674     Q3_SwapBSPFile();
00675 
00676     header->ident = LittleLong( Q3_BSP_IDENT );
00677     header->version = LittleLong( Q3_BSP_VERSION );
00678     
00679     bspfile = SafeOpenWrite( filename );
00680     SafeWrite( bspfile, header, sizeof(q3_dheader_t) ); // overwritten later
00681 
00682     Q3_AddLump( bspfile, header, Q3_LUMP_SHADERS, q3_dshaders, q3_numShaders*sizeof(q3_dshader_t) );
00683     Q3_AddLump( bspfile, header, Q3_LUMP_PLANES, q3_dplanes, q3_numplanes*sizeof(q3_dplane_t) );
00684     Q3_AddLump( bspfile, header, Q3_LUMP_LEAFS, q3_dleafs, q3_numleafs*sizeof(q3_dleaf_t) );
00685     Q3_AddLump( bspfile, header, Q3_LUMP_NODES, q3_dnodes, q3_numnodes*sizeof(q3_dnode_t) );
00686     Q3_AddLump( bspfile, header, Q3_LUMP_BRUSHES, q3_dbrushes, q3_numbrushes*sizeof(q3_dbrush_t) );
00687     Q3_AddLump( bspfile, header, Q3_LUMP_BRUSHSIDES, q3_dbrushsides, q3_numbrushsides*sizeof(q3_dbrushside_t) );
00688     Q3_AddLump( bspfile, header, Q3_LUMP_LEAFSURFACES, q3_dleafsurfaces, q3_numleafsurfaces*sizeof(q3_dleafsurfaces[0]) );
00689     Q3_AddLump( bspfile, header, Q3_LUMP_LEAFBRUSHES, q3_dleafbrushes, q3_numleafbrushes*sizeof(q3_dleafbrushes[0]) );
00690     Q3_AddLump( bspfile, header, Q3_LUMP_MODELS, q3_dmodels, q3_nummodels*sizeof(q3_dmodel_t) );
00691     Q3_AddLump( bspfile, header, Q3_LUMP_DRAWVERTS, q3_drawVerts, q3_numDrawVerts*sizeof(q3_drawVert_t) );
00692     Q3_AddLump( bspfile, header, Q3_LUMP_SURFACES, q3_drawSurfaces, q3_numDrawSurfaces*sizeof(q3_dsurface_t) );
00693     Q3_AddLump( bspfile, header, Q3_LUMP_VISIBILITY, q3_visBytes, q3_numVisBytes );
00694     Q3_AddLump( bspfile, header, Q3_LUMP_LIGHTMAPS, q3_lightBytes, q3_numLightBytes );
00695     Q3_AddLump( bspfile, header, Q3_LUMP_LIGHTGRID, q3_gridData, 8 * q3_numGridPoints );
00696     Q3_AddLump( bspfile, header, Q3_LUMP_ENTITIES, q3_dentdata, q3_entdatasize );
00697     Q3_AddLump( bspfile, header, Q3_LUMP_FOGS, q3_dfogs, q3_numFogs * sizeof(q3_dfog_t) );
00698     Q3_AddLump( bspfile, header, Q3_LUMP_DRAWINDEXES, q3_drawIndexes, q3_numDrawIndexes * sizeof(q3_drawIndexes[0]) );
00699     
00700     fseek (bspfile, 0, SEEK_SET);
00701     SafeWrite (bspfile, header, sizeof(q3_dheader_t));
00702     fclose (bspfile);   
00703 }
00704 
00705 //============================================================================
00706 
00707 /*
00708 =============
00709 Q3_PrintBSPFileSizes
00710 
00711 Dumps info about current file
00712 =============
00713 */
00714 void Q3_PrintBSPFileSizes( void )
00715 {
00716     if ( !num_entities )
00717     {
00718         Q3_ParseEntities();
00719     }
00720 
00721     Log_Print ("%6i models       %7i\n"
00722         ,q3_nummodels, (int)(q3_nummodels*sizeof(q3_dmodel_t)));
00723     Log_Print ("%6i shaders      %7i\n"
00724         ,q3_numShaders, (int)(q3_numShaders*sizeof(q3_dshader_t)));
00725     Log_Print ("%6i brushes      %7i\n"
00726         ,q3_numbrushes, (int)(q3_numbrushes*sizeof(q3_dbrush_t)));
00727     Log_Print ("%6i brushsides   %7i\n"
00728         ,q3_numbrushsides, (int)(q3_numbrushsides*sizeof(q3_dbrushside_t)));
00729     Log_Print ("%6i fogs         %7i\n"
00730         ,q3_numFogs, (int)(q3_numFogs*sizeof(q3_dfog_t)));
00731     Log_Print ("%6i planes       %7i\n"
00732         ,q3_numplanes, (int)(q3_numplanes*sizeof(q3_dplane_t)));
00733     Log_Print ("%6i entdata      %7i\n", num_entities, q3_entdatasize);
00734 
00735     Log_Print ("\n");
00736 
00737     Log_Print ("%6i nodes        %7i\n"
00738         ,q3_numnodes, (int)(q3_numnodes*sizeof(q3_dnode_t)));
00739     Log_Print ("%6i leafs        %7i\n"
00740         ,q3_numleafs, (int)(q3_numleafs*sizeof(q3_dleaf_t)));
00741     Log_Print ("%6i leafsurfaces %7i\n"
00742         ,q3_numleafsurfaces, (int)(q3_numleafsurfaces*sizeof(q3_dleafsurfaces[0])));
00743     Log_Print ("%6i leafbrushes  %7i\n"
00744         ,q3_numleafbrushes, (int)(q3_numleafbrushes*sizeof(q3_dleafbrushes[0])));
00745     Log_Print ("%6i drawverts    %7i\n"
00746         ,q3_numDrawVerts, (int)(q3_numDrawVerts*sizeof(q3_drawVerts[0])));
00747     Log_Print ("%6i drawindexes  %7i\n"
00748         ,q3_numDrawIndexes, (int)(q3_numDrawIndexes*sizeof(q3_drawIndexes[0])));
00749     Log_Print ("%6i drawsurfaces %7i\n"
00750         ,q3_numDrawSurfaces, (int)(q3_numDrawSurfaces*sizeof(q3_drawSurfaces[0])));
00751 
00752     Log_Print ("%6i lightmaps    %7i\n"
00753         ,q3_numLightBytes / (LIGHTMAP_WIDTH*LIGHTMAP_HEIGHT*3), q3_numLightBytes );
00754     Log_Print ("       visibility   %7i\n"
00755         , q3_numVisBytes );
00756 }
00757 
00758 /*
00759 ================
00760 Q3_ParseEntities
00761 
00762 Parses the q3_dentdata string into entities
00763 ================
00764 */
00765 void Q3_ParseEntities (void)
00766 {
00767     script_t *script;
00768 
00769     num_entities = 0;
00770     script = LoadScriptMemory(q3_dentdata, q3_entdatasize, "*Quake3 bsp file");
00771     SetScriptFlags(script, SCFL_NOSTRINGWHITESPACES |
00772                                     SCFL_NOSTRINGESCAPECHARS);
00773 
00774     while(ParseEntity(script))
00775     {
00776     } //end while
00777 
00778     FreeScript(script);
00779 } //end of the function Q3_ParseEntities
00780 
00781 
00782 /*
00783 ================
00784 Q3_UnparseEntities
00785 
00786 Generates the q3_dentdata string from all the entities
00787 ================
00788 */
00789 void Q3_UnparseEntities (void)
00790 {
00791     char *buf, *end;
00792     epair_t *ep;
00793     char line[2048];
00794     int i;
00795     
00796     buf = q3_dentdata;
00797     end = buf;
00798     *end = 0;
00799     
00800     for (i=0 ; i<num_entities ; i++)
00801     {
00802         ep = entities[i].epairs;
00803         if (!ep)
00804             continue;   // ent got removed
00805         
00806         strcat (end,"{\n");
00807         end += 2;
00808                 
00809         for (ep = entities[i].epairs ; ep ; ep=ep->next)
00810         {
00811             sprintf (line, "\"%s\" \"%s\"\n", ep->key, ep->value);
00812             strcat (end, line);
00813             end += strlen(line);
00814         }
00815         strcat (end,"}\n");
00816         end += 2;
00817 
00818         if (end > buf + Q3_MAX_MAP_ENTSTRING)
00819             Error ("Entity text too long");
00820     }
00821     q3_entdatasize = end - buf + 1;
00822 } //end of the function Q3_UnparseEntities
00823 
00824 

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