l_bsp_q3.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825
  1. /*
  2. ===========================================================================
  3. Copyright (C) 1999-2005 Id Software, Inc.
  4. This file is part of Quake III Arena source code.
  5. Quake III Arena source code is free software; you can redistribute it
  6. and/or modify it under the terms of the GNU General Public License as
  7. published by the Free Software Foundation; either version 2 of the License,
  8. or (at your option) any later version.
  9. Quake III Arena source code is distributed in the hope that it will be
  10. useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with Foobar; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16. ===========================================================================
  17. */
  18. #include "l_cmd.h"
  19. #include "l_math.h"
  20. #include "l_mem.h"
  21. #include "l_log.h"
  22. #include "l_poly.h"
  23. #include "../botlib/l_script.h"
  24. #include "l_qfiles.h"
  25. #include "l_bsp_q3.h"
  26. #include "l_bsp_ent.h"
  27. void Q3_ParseEntities (void);
  28. void Q3_PrintBSPFileSizes(void);
  29. void GetLeafNums (void);
  30. //=============================================================================
  31. #define WCONVEX_EPSILON 0.5
  32. int q3_nummodels;
  33. q3_dmodel_t *q3_dmodels;//[MAX_MAP_MODELS];
  34. int q3_numShaders;
  35. q3_dshader_t *q3_dshaders;//[Q3_MAX_MAP_SHADERS];
  36. int q3_entdatasize;
  37. char *q3_dentdata;//[Q3_MAX_MAP_ENTSTRING];
  38. int q3_numleafs;
  39. q3_dleaf_t *q3_dleafs;//[Q3_MAX_MAP_LEAFS];
  40. int q3_numplanes;
  41. q3_dplane_t *q3_dplanes;//[Q3_MAX_MAP_PLANES];
  42. int q3_numnodes;
  43. q3_dnode_t *q3_dnodes;//[Q3_MAX_MAP_NODES];
  44. int q3_numleafsurfaces;
  45. int *q3_dleafsurfaces;//[Q3_MAX_MAP_LEAFFACES];
  46. int q3_numleafbrushes;
  47. int *q3_dleafbrushes;//[Q3_MAX_MAP_LEAFBRUSHES];
  48. int q3_numbrushes;
  49. q3_dbrush_t *q3_dbrushes;//[Q3_MAX_MAP_BRUSHES];
  50. int q3_numbrushsides;
  51. q3_dbrushside_t *q3_dbrushsides;//[Q3_MAX_MAP_BRUSHSIDES];
  52. int q3_numLightBytes;
  53. byte *q3_lightBytes;//[Q3_MAX_MAP_LIGHTING];
  54. int q3_numGridPoints;
  55. byte *q3_gridData;//[Q3_MAX_MAP_LIGHTGRID];
  56. int q3_numVisBytes;
  57. byte *q3_visBytes;//[Q3_MAX_MAP_VISIBILITY];
  58. int q3_numDrawVerts;
  59. q3_drawVert_t *q3_drawVerts;//[Q3_MAX_MAP_DRAW_VERTS];
  60. int q3_numDrawIndexes;
  61. int *q3_drawIndexes;//[Q3_MAX_MAP_DRAW_INDEXES];
  62. int q3_numDrawSurfaces;
  63. q3_dsurface_t *q3_drawSurfaces;//[Q3_MAX_MAP_DRAW_SURFS];
  64. int q3_numFogs;
  65. q3_dfog_t *q3_dfogs;//[Q3_MAX_MAP_FOGS];
  66. char q3_dbrushsidetextured[Q3_MAX_MAP_BRUSHSIDES];
  67. extern qboolean forcesidesvisible;
  68. //===========================================================================
  69. //
  70. // Parameter: -
  71. // Returns: -
  72. // Changes Globals: -
  73. //===========================================================================
  74. void Q3_FreeMaxBSP(void)
  75. {
  76. if (q3_dmodels) FreeMemory(q3_dmodels);
  77. q3_dmodels = NULL;
  78. q3_nummodels = 0;
  79. if (q3_dshaders) FreeMemory(q3_dshaders);
  80. q3_dshaders = NULL;
  81. q3_numShaders = 0;
  82. if (q3_dentdata) FreeMemory(q3_dentdata);
  83. q3_dentdata = NULL;
  84. q3_entdatasize = 0;
  85. if (q3_dleafs) FreeMemory(q3_dleafs);
  86. q3_dleafs = NULL;
  87. q3_numleafs = 0;
  88. if (q3_dplanes) FreeMemory(q3_dplanes);
  89. q3_dplanes = NULL;
  90. q3_numplanes = 0;
  91. if (q3_dnodes) FreeMemory(q3_dnodes);
  92. q3_dnodes = NULL;
  93. q3_numnodes = 0;
  94. if (q3_dleafsurfaces) FreeMemory(q3_dleafsurfaces);
  95. q3_dleafsurfaces = NULL;
  96. q3_numleafsurfaces = 0;
  97. if (q3_dleafbrushes) FreeMemory(q3_dleafbrushes);
  98. q3_dleafbrushes = NULL;
  99. q3_numleafbrushes = 0;
  100. if (q3_dbrushes) FreeMemory(q3_dbrushes);
  101. q3_dbrushes = NULL;
  102. q3_numbrushes = 0;
  103. if (q3_dbrushsides) FreeMemory(q3_dbrushsides);
  104. q3_dbrushsides = NULL;
  105. q3_numbrushsides = 0;
  106. if (q3_lightBytes) FreeMemory(q3_lightBytes);
  107. q3_lightBytes = NULL;
  108. q3_numLightBytes = 0;
  109. if (q3_gridData) FreeMemory(q3_gridData);
  110. q3_gridData = NULL;
  111. q3_numGridPoints = 0;
  112. if (q3_visBytes) FreeMemory(q3_visBytes);
  113. q3_visBytes = NULL;
  114. q3_numVisBytes = 0;
  115. if (q3_drawVerts) FreeMemory(q3_drawVerts);
  116. q3_drawVerts = NULL;
  117. q3_numDrawVerts = 0;
  118. if (q3_drawIndexes) FreeMemory(q3_drawIndexes);
  119. q3_drawIndexes = NULL;
  120. q3_numDrawIndexes = 0;
  121. if (q3_drawSurfaces) FreeMemory(q3_drawSurfaces);
  122. q3_drawSurfaces = NULL;
  123. q3_numDrawSurfaces = 0;
  124. if (q3_dfogs) FreeMemory(q3_dfogs);
  125. q3_dfogs = NULL;
  126. q3_numFogs = 0;
  127. } //end of the function Q3_FreeMaxBSP
  128. //===========================================================================
  129. //
  130. // Parameter: -
  131. // Returns: -
  132. // Changes Globals: -
  133. //===========================================================================
  134. void Q3_PlaneFromPoints(vec3_t p0, vec3_t p1, vec3_t p2, vec3_t normal, float *dist)
  135. {
  136. vec3_t t1, t2;
  137. VectorSubtract(p0, p1, t1);
  138. VectorSubtract(p2, p1, t2);
  139. CrossProduct(t1, t2, normal);
  140. VectorNormalize(normal);
  141. *dist = DotProduct(p0, normal);
  142. } //end of the function PlaneFromPoints
  143. //===========================================================================
  144. //
  145. // Parameter: -
  146. // Returns: -
  147. // Changes Globals: -
  148. //===========================================================================
  149. void Q3_SurfacePlane(q3_dsurface_t *surface, vec3_t normal, float *dist)
  150. {
  151. int i;
  152. float *p0, *p1, *p2;
  153. vec3_t t1, t2;
  154. p0 = q3_drawVerts[surface->firstVert].xyz;
  155. for (i = 1; i < surface->numVerts-1; i++)
  156. {
  157. p1 = q3_drawVerts[surface->firstVert + ((i) % surface->numVerts)].xyz;
  158. p2 = q3_drawVerts[surface->firstVert + ((i+1) % surface->numVerts)].xyz;
  159. VectorSubtract(p0, p1, t1);
  160. VectorSubtract(p2, p1, t2);
  161. CrossProduct(t1, t2, normal);
  162. VectorNormalize(normal);
  163. if (VectorLength(normal)) break;
  164. } //end for*/
  165. /*
  166. float dot;
  167. for (i = 0; i < surface->numVerts; i++)
  168. {
  169. p0 = q3_drawVerts[surface->firstVert + ((i) % surface->numVerts)].xyz;
  170. p1 = q3_drawVerts[surface->firstVert + ((i+1) % surface->numVerts)].xyz;
  171. p2 = q3_drawVerts[surface->firstVert + ((i+2) % surface->numVerts)].xyz;
  172. VectorSubtract(p0, p1, t1);
  173. VectorSubtract(p2, p1, t2);
  174. VectorNormalize(t1);
  175. VectorNormalize(t2);
  176. dot = DotProduct(t1, t2);
  177. if (dot > -0.9 && dot < 0.9 &&
  178. VectorLength(t1) > 0.1 && VectorLength(t2) > 0.1) break;
  179. } //end for
  180. CrossProduct(t1, t2, normal);
  181. VectorNormalize(normal);
  182. */
  183. if (VectorLength(normal) < 0.9)
  184. {
  185. printf("surface %d bogus normal vector %f %f %f\n", surface - q3_drawSurfaces, normal[0], normal[1], normal[2]);
  186. printf("t1 = %f %f %f, t2 = %f %f %f\n", t1[0], t1[1], t1[2], t2[0], t2[1], t2[2]);
  187. for (i = 0; i < surface->numVerts; i++)
  188. {
  189. p1 = q3_drawVerts[surface->firstVert + ((i) % surface->numVerts)].xyz;
  190. Log_Print("p%d = %f %f %f\n", i, p1[0], p1[1], p1[2]);
  191. } //end for
  192. } //end if
  193. *dist = DotProduct(p0, normal);
  194. } //end of the function Q3_SurfacePlane
  195. //===========================================================================
  196. //
  197. // Parameter: -
  198. // Returns: -
  199. // Changes Globals: -
  200. //===========================================================================
  201. q3_dplane_t *q3_surfaceplanes;
  202. void Q3_CreatePlanarSurfacePlanes(void)
  203. {
  204. int i;
  205. q3_dsurface_t *surface;
  206. Log_Print("creating planar surface planes...\n");
  207. q3_surfaceplanes = (q3_dplane_t *) GetClearedMemory(q3_numDrawSurfaces * sizeof(q3_dplane_t));
  208. for (i = 0; i < q3_numDrawSurfaces; i++)
  209. {
  210. surface = &q3_drawSurfaces[i];
  211. if (surface->surfaceType != MST_PLANAR) continue;
  212. Q3_SurfacePlane(surface, q3_surfaceplanes[i].normal, &q3_surfaceplanes[i].dist);
  213. //Log_Print("normal = %f %f %f, dist = %f\n", q3_surfaceplanes[i].normal[0],
  214. // q3_surfaceplanes[i].normal[1],
  215. // q3_surfaceplanes[i].normal[2], q3_surfaceplanes[i].dist);
  216. } //end for
  217. } //end of the function Q3_CreatePlanarSurfacePlanes
  218. //===========================================================================
  219. //
  220. // Parameter: -
  221. // Returns: -
  222. // Changes Globals: -
  223. //===========================================================================
  224. /*
  225. void Q3_SurfacePlane(q3_dsurface_t *surface, vec3_t normal, float *dist)
  226. {
  227. //take the plane information from the lightmap vector
  228. //VectorCopy(surface->lightmapVecs[2], normal);
  229. //calculate plane dist with first surface vertex
  230. //*dist = DotProduct(q3_drawVerts[surface->firstVert].xyz, normal);
  231. Q3_PlaneFromPoints(q3_drawVerts[surface->firstVert].xyz,
  232. q3_drawVerts[surface->firstVert+1].xyz,
  233. q3_drawVerts[surface->firstVert+2].xyz, normal, dist);
  234. } //end of the function Q3_SurfacePlane*/
  235. //===========================================================================
  236. // returns the amount the face and the winding overlap
  237. //
  238. // Parameter: -
  239. // Returns: -
  240. // Changes Globals: -
  241. //===========================================================================
  242. float Q3_FaceOnWinding(q3_dsurface_t *surface, winding_t *winding)
  243. {
  244. int i;
  245. float dist, area;
  246. q3_dplane_t plane;
  247. vec_t *v1, *v2;
  248. vec3_t normal, edgevec;
  249. winding_t *w;
  250. //copy the winding before chopping
  251. w = CopyWinding(winding);
  252. //retrieve the surface plane
  253. Q3_SurfacePlane(surface, plane.normal, &plane.dist);
  254. //chop the winding with the surface edge planes
  255. for (i = 0; i < surface->numVerts && w; i++)
  256. {
  257. v1 = q3_drawVerts[surface->firstVert + ((i) % surface->numVerts)].xyz;
  258. v2 = q3_drawVerts[surface->firstVert + ((i+1) % surface->numVerts)].xyz;
  259. //create a plane through the edge from v1 to v2, orthogonal to the
  260. //surface plane and with the normal vector pointing inward
  261. VectorSubtract(v2, v1, edgevec);
  262. CrossProduct(edgevec, plane.normal, normal);
  263. VectorNormalize(normal);
  264. dist = DotProduct(normal, v1);
  265. //
  266. ChopWindingInPlace(&w, normal, dist, -0.1); //CLIP_EPSILON
  267. } //end for
  268. if (w)
  269. {
  270. area = WindingArea(w);
  271. FreeWinding(w);
  272. return area;
  273. } //end if
  274. return 0;
  275. } //end of the function Q3_FaceOnWinding
  276. //===========================================================================
  277. // creates a winding for the given brush side on the given brush
  278. //
  279. // Parameter: -
  280. // Returns: -
  281. // Changes Globals: -
  282. //===========================================================================
  283. winding_t *Q3_BrushSideWinding(q3_dbrush_t *brush, q3_dbrushside_t *baseside)
  284. {
  285. int i;
  286. q3_dplane_t *baseplane, *plane;
  287. winding_t *w;
  288. q3_dbrushside_t *side;
  289. //create a winding for the brush side with the given planenumber
  290. baseplane = &q3_dplanes[baseside->planeNum];
  291. w = BaseWindingForPlane(baseplane->normal, baseplane->dist);
  292. for (i = 0; i < brush->numSides && w; i++)
  293. {
  294. side = &q3_dbrushsides[brush->firstSide + i];
  295. //don't chop with the base plane
  296. if (side->planeNum == baseside->planeNum) continue;
  297. //also don't use planes that are almost equal
  298. plane = &q3_dplanes[side->planeNum];
  299. if (DotProduct(baseplane->normal, plane->normal) > 0.999
  300. && fabs(baseplane->dist - plane->dist) < 0.01) continue;
  301. //
  302. plane = &q3_dplanes[side->planeNum^1];
  303. ChopWindingInPlace(&w, plane->normal, plane->dist, -0.1); //CLIP_EPSILON);
  304. } //end for
  305. return w;
  306. } //end of the function Q3_BrushSideWinding
  307. //===========================================================================
  308. // fix screwed brush texture references
  309. //
  310. // Parameter: -
  311. // Returns: -
  312. // Changes Globals: -
  313. //===========================================================================
  314. qboolean WindingIsTiny(winding_t *w);
  315. void Q3_FindVisibleBrushSides(void)
  316. {
  317. int i, j, k, we, numtextured, numsides;
  318. float dot;
  319. q3_dplane_t *plane;
  320. q3_dbrushside_t *brushside;
  321. q3_dbrush_t *brush;
  322. q3_dsurface_t *surface;
  323. winding_t *w;
  324. memset(q3_dbrushsidetextured, false, Q3_MAX_MAP_BRUSHSIDES);
  325. //
  326. numsides = 0;
  327. //create planes for the planar surfaces
  328. Q3_CreatePlanarSurfacePlanes();
  329. Log_Print("searching visible brush sides...\n");
  330. Log_Print("%6d brush sides", numsides);
  331. //go over all the brushes
  332. for (i = 0; i < q3_numbrushes; i++)
  333. {
  334. brush = &q3_dbrushes[i];
  335. //go over all the sides of the brush
  336. for (j = 0; j < brush->numSides; j++)
  337. {
  338. qprintf("\r%6d", numsides++);
  339. brushside = &q3_dbrushsides[brush->firstSide + j];
  340. //
  341. w = Q3_BrushSideWinding(brush, brushside);
  342. if (!w)
  343. {
  344. q3_dbrushsidetextured[brush->firstSide + j] = true;
  345. continue;
  346. } //end if
  347. else
  348. {
  349. //RemoveEqualPoints(w, 0.2);
  350. if (WindingIsTiny(w))
  351. {
  352. FreeWinding(w);
  353. q3_dbrushsidetextured[brush->firstSide + j] = true;
  354. continue;
  355. } //end if
  356. else
  357. {
  358. we = WindingError(w);
  359. if (we == WE_NOTENOUGHPOINTS
  360. || we == WE_SMALLAREA
  361. || we == WE_POINTBOGUSRANGE
  362. // || we == WE_NONCONVEX
  363. )
  364. {
  365. FreeWinding(w);
  366. q3_dbrushsidetextured[brush->firstSide + j] = true;
  367. continue;
  368. } //end if
  369. } //end else
  370. } //end else
  371. if (WindingArea(w) < 20)
  372. {
  373. q3_dbrushsidetextured[brush->firstSide + j] = true;
  374. continue;
  375. } //end if
  376. //find a face for texturing this brush
  377. for (k = 0; k < q3_numDrawSurfaces; k++)
  378. {
  379. surface = &q3_drawSurfaces[k];
  380. if (surface->surfaceType != MST_PLANAR) continue;
  381. //
  382. //Q3_SurfacePlane(surface, plane.normal, &plane.dist);
  383. plane = &q3_surfaceplanes[k];
  384. //the surface plane and the brush side plane should be pretty much the same
  385. if (fabs(fabs(plane->dist) - fabs(q3_dplanes[brushside->planeNum].dist)) > 5) continue;
  386. dot = DotProduct(plane->normal, q3_dplanes[brushside->planeNum].normal);
  387. if (dot > -0.9 && dot < 0.9) continue;
  388. //if the face is partly or totally on the brush side
  389. if (Q3_FaceOnWinding(surface, w))
  390. {
  391. q3_dbrushsidetextured[brush->firstSide + j] = true;
  392. //Log_Write("Q3_FaceOnWinding");
  393. break;
  394. } //end if
  395. } //end for
  396. FreeWinding(w);
  397. } //end for
  398. } //end for
  399. qprintf("\r%6d brush sides\n", numsides);
  400. numtextured = 0;
  401. for (i = 0; i < q3_numbrushsides; i++)
  402. {
  403. if (forcesidesvisible) q3_dbrushsidetextured[i] = true;
  404. if (q3_dbrushsidetextured[i]) numtextured++;
  405. } //end for
  406. Log_Print("%d brush sides textured out of %d\n", numtextured, q3_numbrushsides);
  407. } //end of the function Q3_FindVisibleBrushSides
  408. /*
  409. =============
  410. Q3_SwapBlock
  411. If all values are 32 bits, this can be used to swap everything
  412. =============
  413. */
  414. void Q3_SwapBlock( int *block, int sizeOfBlock ) {
  415. int i;
  416. sizeOfBlock >>= 2;
  417. for ( i = 0 ; i < sizeOfBlock ; i++ ) {
  418. block[i] = LittleLong( block[i] );
  419. }
  420. } //end of the function Q3_SwapBlock
  421. /*
  422. =============
  423. Q3_SwapBSPFile
  424. Byte swaps all data in a bsp file.
  425. =============
  426. */
  427. void Q3_SwapBSPFile( void ) {
  428. int i;
  429. // models
  430. Q3_SwapBlock( (int *)q3_dmodels, q3_nummodels * sizeof( q3_dmodels[0] ) );
  431. // shaders (don't swap the name)
  432. for ( i = 0 ; i < q3_numShaders ; i++ ) {
  433. q3_dshaders[i].contentFlags = LittleLong( q3_dshaders[i].contentFlags );
  434. q3_dshaders[i].surfaceFlags = LittleLong( q3_dshaders[i].surfaceFlags );
  435. }
  436. // planes
  437. Q3_SwapBlock( (int *)q3_dplanes, q3_numplanes * sizeof( q3_dplanes[0] ) );
  438. // nodes
  439. Q3_SwapBlock( (int *)q3_dnodes, q3_numnodes * sizeof( q3_dnodes[0] ) );
  440. // leafs
  441. Q3_SwapBlock( (int *)q3_dleafs, q3_numleafs * sizeof( q3_dleafs[0] ) );
  442. // leaffaces
  443. Q3_SwapBlock( (int *)q3_dleafsurfaces, q3_numleafsurfaces * sizeof( q3_dleafsurfaces[0] ) );
  444. // leafbrushes
  445. Q3_SwapBlock( (int *)q3_dleafbrushes, q3_numleafbrushes * sizeof( q3_dleafbrushes[0] ) );
  446. // brushes
  447. Q3_SwapBlock( (int *)q3_dbrushes, q3_numbrushes * sizeof( q3_dbrushes[0] ) );
  448. // brushsides
  449. Q3_SwapBlock( (int *)q3_dbrushsides, q3_numbrushsides * sizeof( q3_dbrushsides[0] ) );
  450. // vis
  451. ((int *)&q3_visBytes)[0] = LittleLong( ((int *)&q3_visBytes)[0] );
  452. ((int *)&q3_visBytes)[1] = LittleLong( ((int *)&q3_visBytes)[1] );
  453. // drawverts (don't swap colors )
  454. for ( i = 0 ; i < q3_numDrawVerts ; i++ ) {
  455. q3_drawVerts[i].lightmap[0] = LittleFloat( q3_drawVerts[i].lightmap[0] );
  456. q3_drawVerts[i].lightmap[1] = LittleFloat( q3_drawVerts[i].lightmap[1] );
  457. q3_drawVerts[i].st[0] = LittleFloat( q3_drawVerts[i].st[0] );
  458. q3_drawVerts[i].st[1] = LittleFloat( q3_drawVerts[i].st[1] );
  459. q3_drawVerts[i].xyz[0] = LittleFloat( q3_drawVerts[i].xyz[0] );
  460. q3_drawVerts[i].xyz[1] = LittleFloat( q3_drawVerts[i].xyz[1] );
  461. q3_drawVerts[i].xyz[2] = LittleFloat( q3_drawVerts[i].xyz[2] );
  462. q3_drawVerts[i].normal[0] = LittleFloat( q3_drawVerts[i].normal[0] );
  463. q3_drawVerts[i].normal[1] = LittleFloat( q3_drawVerts[i].normal[1] );
  464. q3_drawVerts[i].normal[2] = LittleFloat( q3_drawVerts[i].normal[2] );
  465. }
  466. // drawindexes
  467. Q3_SwapBlock( (int *)q3_drawIndexes, q3_numDrawIndexes * sizeof( q3_drawIndexes[0] ) );
  468. // drawsurfs
  469. Q3_SwapBlock( (int *)q3_drawSurfaces, q3_numDrawSurfaces * sizeof( q3_drawSurfaces[0] ) );
  470. // fogs
  471. for ( i = 0 ; i < q3_numFogs ; i++ ) {
  472. q3_dfogs[i].brushNum = LittleLong( q3_dfogs[i].brushNum );
  473. }
  474. }
  475. /*
  476. =============
  477. Q3_CopyLump
  478. =============
  479. */
  480. int Q3_CopyLump( q3_dheader_t *header, int lump, void **dest, int size ) {
  481. int length, ofs;
  482. length = header->lumps[lump].filelen;
  483. ofs = header->lumps[lump].fileofs;
  484. if ( length % size ) {
  485. Error ("Q3_LoadBSPFile: odd lump size");
  486. }
  487. *dest = GetMemory(length);
  488. memcpy( *dest, (byte *)header + ofs, length );
  489. return length / size;
  490. }
  491. /*
  492. =============
  493. CountTriangles
  494. =============
  495. */
  496. void CountTriangles( void ) {
  497. int i, numTris, numPatchTris;
  498. q3_dsurface_t *surface;
  499. numTris = numPatchTris = 0;
  500. for ( i = 0; i < q3_numDrawSurfaces; i++ ) {
  501. surface = &q3_drawSurfaces[i];
  502. numTris += surface->numIndexes / 3;
  503. if ( surface->patchWidth ) {
  504. numPatchTris += surface->patchWidth * surface->patchHeight * 2;
  505. }
  506. }
  507. Log_Print( "%6d triangles\n", numTris );
  508. Log_Print( "%6d patch tris\n", numPatchTris );
  509. }
  510. /*
  511. =============
  512. Q3_LoadBSPFile
  513. =============
  514. */
  515. void Q3_LoadBSPFile(struct quakefile_s *qf)
  516. {
  517. q3_dheader_t *header;
  518. // load the file header
  519. //LoadFile(filename, (void **)&header, offset, length);
  520. //
  521. LoadQuakeFile(qf, (void **)&header);
  522. // swap the header
  523. Q3_SwapBlock( (int *)header, sizeof(*header) );
  524. if ( header->ident != Q3_BSP_IDENT ) {
  525. Error( "%s is not a IBSP file", qf->filename );
  526. }
  527. if ( header->version != Q3_BSP_VERSION ) {
  528. Error( "%s is version %i, not %i", qf->filename, header->version, Q3_BSP_VERSION );
  529. }
  530. q3_numShaders = Q3_CopyLump( header, Q3_LUMP_SHADERS, (void *) &q3_dshaders, sizeof(q3_dshader_t) );
  531. q3_nummodels = Q3_CopyLump( header, Q3_LUMP_MODELS, (void *) &q3_dmodels, sizeof(q3_dmodel_t) );
  532. q3_numplanes = Q3_CopyLump( header, Q3_LUMP_PLANES, (void *) &q3_dplanes, sizeof(q3_dplane_t) );
  533. q3_numleafs = Q3_CopyLump( header, Q3_LUMP_LEAFS, (void *) &q3_dleafs, sizeof(q3_dleaf_t) );
  534. q3_numnodes = Q3_CopyLump( header, Q3_LUMP_NODES, (void *) &q3_dnodes, sizeof(q3_dnode_t) );
  535. q3_numleafsurfaces = Q3_CopyLump( header, Q3_LUMP_LEAFSURFACES, (void *) &q3_dleafsurfaces, sizeof(q3_dleafsurfaces[0]) );
  536. q3_numleafbrushes = Q3_CopyLump( header, Q3_LUMP_LEAFBRUSHES, (void *) &q3_dleafbrushes, sizeof(q3_dleafbrushes[0]) );
  537. q3_numbrushes = Q3_CopyLump( header, Q3_LUMP_BRUSHES, (void *) &q3_dbrushes, sizeof(q3_dbrush_t) );
  538. q3_numbrushsides = Q3_CopyLump( header, Q3_LUMP_BRUSHSIDES, (void *) &q3_dbrushsides, sizeof(q3_dbrushside_t) );
  539. q3_numDrawVerts = Q3_CopyLump( header, Q3_LUMP_DRAWVERTS, (void *) &q3_drawVerts, sizeof(q3_drawVert_t) );
  540. q3_numDrawSurfaces = Q3_CopyLump( header, Q3_LUMP_SURFACES, (void *) &q3_drawSurfaces, sizeof(q3_dsurface_t) );
  541. q3_numFogs = Q3_CopyLump( header, Q3_LUMP_FOGS, (void *) &q3_dfogs, sizeof(q3_dfog_t) );
  542. q3_numDrawIndexes = Q3_CopyLump( header, Q3_LUMP_DRAWINDEXES, (void *) &q3_drawIndexes, sizeof(q3_drawIndexes[0]) );
  543. q3_numVisBytes = Q3_CopyLump( header, Q3_LUMP_VISIBILITY, (void *) &q3_visBytes, 1 );
  544. q3_numLightBytes = Q3_CopyLump( header, Q3_LUMP_LIGHTMAPS, (void *) &q3_lightBytes, 1 );
  545. q3_entdatasize = Q3_CopyLump( header, Q3_LUMP_ENTITIES, (void *) &q3_dentdata, 1);
  546. q3_numGridPoints = Q3_CopyLump( header, Q3_LUMP_LIGHTGRID, (void *) &q3_gridData, 8 );
  547. CountTriangles();
  548. FreeMemory( header ); // everything has been copied out
  549. // swap everything
  550. Q3_SwapBSPFile();
  551. Q3_FindVisibleBrushSides();
  552. //Q3_PrintBSPFileSizes();
  553. }
  554. //============================================================================
  555. /*
  556. =============
  557. Q3_AddLump
  558. =============
  559. */
  560. void Q3_AddLump( FILE *bspfile, q3_dheader_t *header, int lumpnum, void *data, int len ) {
  561. q3_lump_t *lump;
  562. lump = &header->lumps[lumpnum];
  563. lump->fileofs = LittleLong( ftell(bspfile) );
  564. lump->filelen = LittleLong( len );
  565. SafeWrite( bspfile, data, (len+3)&~3 );
  566. }
  567. /*
  568. =============
  569. Q3_WriteBSPFile
  570. Swaps the bsp file in place, so it should not be referenced again
  571. =============
  572. */
  573. void Q3_WriteBSPFile( char *filename )
  574. {
  575. q3_dheader_t outheader, *header;
  576. FILE *bspfile;
  577. header = &outheader;
  578. memset( header, 0, sizeof(q3_dheader_t) );
  579. Q3_SwapBSPFile();
  580. header->ident = LittleLong( Q3_BSP_IDENT );
  581. header->version = LittleLong( Q3_BSP_VERSION );
  582. bspfile = SafeOpenWrite( filename );
  583. SafeWrite( bspfile, header, sizeof(q3_dheader_t) ); // overwritten later
  584. Q3_AddLump( bspfile, header, Q3_LUMP_SHADERS, q3_dshaders, q3_numShaders*sizeof(q3_dshader_t) );
  585. Q3_AddLump( bspfile, header, Q3_LUMP_PLANES, q3_dplanes, q3_numplanes*sizeof(q3_dplane_t) );
  586. Q3_AddLump( bspfile, header, Q3_LUMP_LEAFS, q3_dleafs, q3_numleafs*sizeof(q3_dleaf_t) );
  587. Q3_AddLump( bspfile, header, Q3_LUMP_NODES, q3_dnodes, q3_numnodes*sizeof(q3_dnode_t) );
  588. Q3_AddLump( bspfile, header, Q3_LUMP_BRUSHES, q3_dbrushes, q3_numbrushes*sizeof(q3_dbrush_t) );
  589. Q3_AddLump( bspfile, header, Q3_LUMP_BRUSHSIDES, q3_dbrushsides, q3_numbrushsides*sizeof(q3_dbrushside_t) );
  590. Q3_AddLump( bspfile, header, Q3_LUMP_LEAFSURFACES, q3_dleafsurfaces, q3_numleafsurfaces*sizeof(q3_dleafsurfaces[0]) );
  591. Q3_AddLump( bspfile, header, Q3_LUMP_LEAFBRUSHES, q3_dleafbrushes, q3_numleafbrushes*sizeof(q3_dleafbrushes[0]) );
  592. Q3_AddLump( bspfile, header, Q3_LUMP_MODELS, q3_dmodels, q3_nummodels*sizeof(q3_dmodel_t) );
  593. Q3_AddLump( bspfile, header, Q3_LUMP_DRAWVERTS, q3_drawVerts, q3_numDrawVerts*sizeof(q3_drawVert_t) );
  594. Q3_AddLump( bspfile, header, Q3_LUMP_SURFACES, q3_drawSurfaces, q3_numDrawSurfaces*sizeof(q3_dsurface_t) );
  595. Q3_AddLump( bspfile, header, Q3_LUMP_VISIBILITY, q3_visBytes, q3_numVisBytes );
  596. Q3_AddLump( bspfile, header, Q3_LUMP_LIGHTMAPS, q3_lightBytes, q3_numLightBytes );
  597. Q3_AddLump( bspfile, header, Q3_LUMP_LIGHTGRID, q3_gridData, 8 * q3_numGridPoints );
  598. Q3_AddLump( bspfile, header, Q3_LUMP_ENTITIES, q3_dentdata, q3_entdatasize );
  599. Q3_AddLump( bspfile, header, Q3_LUMP_FOGS, q3_dfogs, q3_numFogs * sizeof(q3_dfog_t) );
  600. Q3_AddLump( bspfile, header, Q3_LUMP_DRAWINDEXES, q3_drawIndexes, q3_numDrawIndexes * sizeof(q3_drawIndexes[0]) );
  601. fseek (bspfile, 0, SEEK_SET);
  602. SafeWrite (bspfile, header, sizeof(q3_dheader_t));
  603. fclose (bspfile);
  604. }
  605. //============================================================================
  606. /*
  607. =============
  608. Q3_PrintBSPFileSizes
  609. Dumps info about current file
  610. =============
  611. */
  612. void Q3_PrintBSPFileSizes( void )
  613. {
  614. if ( !num_entities )
  615. {
  616. Q3_ParseEntities();
  617. }
  618. Log_Print ("%6i models %7i\n"
  619. ,q3_nummodels, (int)(q3_nummodels*sizeof(q3_dmodel_t)));
  620. Log_Print ("%6i shaders %7i\n"
  621. ,q3_numShaders, (int)(q3_numShaders*sizeof(q3_dshader_t)));
  622. Log_Print ("%6i brushes %7i\n"
  623. ,q3_numbrushes, (int)(q3_numbrushes*sizeof(q3_dbrush_t)));
  624. Log_Print ("%6i brushsides %7i\n"
  625. ,q3_numbrushsides, (int)(q3_numbrushsides*sizeof(q3_dbrushside_t)));
  626. Log_Print ("%6i fogs %7i\n"
  627. ,q3_numFogs, (int)(q3_numFogs*sizeof(q3_dfog_t)));
  628. Log_Print ("%6i planes %7i\n"
  629. ,q3_numplanes, (int)(q3_numplanes*sizeof(q3_dplane_t)));
  630. Log_Print ("%6i entdata %7i\n", num_entities, q3_entdatasize);
  631. Log_Print ("\n");
  632. Log_Print ("%6i nodes %7i\n"
  633. ,q3_numnodes, (int)(q3_numnodes*sizeof(q3_dnode_t)));
  634. Log_Print ("%6i leafs %7i\n"
  635. ,q3_numleafs, (int)(q3_numleafs*sizeof(q3_dleaf_t)));
  636. Log_Print ("%6i leafsurfaces %7i\n"
  637. ,q3_numleafsurfaces, (int)(q3_numleafsurfaces*sizeof(q3_dleafsurfaces[0])));
  638. Log_Print ("%6i leafbrushes %7i\n"
  639. ,q3_numleafbrushes, (int)(q3_numleafbrushes*sizeof(q3_dleafbrushes[0])));
  640. Log_Print ("%6i drawverts %7i\n"
  641. ,q3_numDrawVerts, (int)(q3_numDrawVerts*sizeof(q3_drawVerts[0])));
  642. Log_Print ("%6i drawindexes %7i\n"
  643. ,q3_numDrawIndexes, (int)(q3_numDrawIndexes*sizeof(q3_drawIndexes[0])));
  644. Log_Print ("%6i drawsurfaces %7i\n"
  645. ,q3_numDrawSurfaces, (int)(q3_numDrawSurfaces*sizeof(q3_drawSurfaces[0])));
  646. Log_Print ("%6i lightmaps %7i\n"
  647. ,q3_numLightBytes / (LIGHTMAP_WIDTH*LIGHTMAP_HEIGHT*3), q3_numLightBytes );
  648. Log_Print (" visibility %7i\n"
  649. , q3_numVisBytes );
  650. }
  651. /*
  652. ================
  653. Q3_ParseEntities
  654. Parses the q3_dentdata string into entities
  655. ================
  656. */
  657. void Q3_ParseEntities (void)
  658. {
  659. script_t *script;
  660. num_entities = 0;
  661. script = LoadScriptMemory(q3_dentdata, q3_entdatasize, "*Quake3 bsp file");
  662. SetScriptFlags(script, SCFL_NOSTRINGWHITESPACES |
  663. SCFL_NOSTRINGESCAPECHARS);
  664. while(ParseEntity(script))
  665. {
  666. } //end while
  667. FreeScript(script);
  668. } //end of the function Q3_ParseEntities
  669. /*
  670. ================
  671. Q3_UnparseEntities
  672. Generates the q3_dentdata string from all the entities
  673. ================
  674. */
  675. void Q3_UnparseEntities (void)
  676. {
  677. char *buf, *end;
  678. epair_t *ep;
  679. char line[2048];
  680. int i;
  681. buf = q3_dentdata;
  682. end = buf;
  683. *end = 0;
  684. for (i=0 ; i<num_entities ; i++)
  685. {
  686. ep = entities[i].epairs;
  687. if (!ep)
  688. continue; // ent got removed
  689. strcat (end,"{\n");
  690. end += 2;
  691. for (ep = entities[i].epairs ; ep ; ep=ep->next)
  692. {
  693. sprintf (line, "\"%s\" \"%s\"\n", ep->key, ep->value);
  694. strcat (end, line);
  695. end += strlen(line);
  696. }
  697. strcat (end,"}\n");
  698. end += 2;
  699. if (end > buf + Q3_MAX_MAP_ENTSTRING)
  700. Error ("Entity text too long");
  701. }
  702. q3_entdatasize = end - buf + 1;
  703. } //end of the function Q3_UnparseEntities