1 /*
2 bspfile.c
3
4 DESCRIPTION
5
6 Copyright (C) 1996-1997 Id Software, Inc.
7
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16
17 See the GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to:
21
22 Free Software Foundation, Inc.
23 59 Temple Place - Suite 330
24 Boston, MA 02111-1307, USA
25
26 */
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30
31 #ifdef HAVE_STRING_H
32 # include <string.h>
33 #endif
34 #ifdef HAVE_STRINGS_H
35 # include <strings.h>
36 #endif
37
38 #include <stdlib.h>
39
40 #include "QF/bspfile.h"
41 #include "QF/qendian.h"
42 #include "QF/qtypes.h"
43 #include "QF/quakefs.h"
44 #include "QF/sys.h"
45
46 typedef struct dnode29_s {
47 int32_t planenum;
48 int16_t children[2]; // negative numbers are -(leafs+1), not nodes
49 int16_t mins[3]; // for sphere culling
50 int16_t maxs[3];
51 uint16_t firstface;
52 uint16_t numfaces; // counting both sides
53 } dnode29_t;
54
55 typedef struct dclipnode29_s {
56 int32_t planenum;
57 int16_t children[2]; // negative numbers are contents
58 } dclipnode29_t;
59
60 typedef struct dedge29_s {
61 uint16_t v[2]; // vertex numbers
62 } dedge29_t;
63
64 typedef struct dface29_s {
65 int16_t planenum;
66 int16_t side;
67
68 int32_t firstedge; // we must support > 64k edges
69 int16_t numedges;
70 int16_t texinfo;
71
72 // lighting info
73 byte styles[MAXLIGHTMAPS];
74 int32_t lightofs; // start of [numstyles*surfsize] samples
75 } dface29_t;
76
77 typedef struct dleaf29_s {
78 int32_t contents;
79 int32_t visofs; // -1 = no visibility info
80
81 int16_t mins[3]; // for frustum culling
82 int16_t maxs[3];
83
84 uint16_t firstmarksurface;
85 uint16_t nummarksurfaces;
86
87 byte ambient_level[NUM_AMBIENTS];
88 } dleaf29_t;
89
90 typedef struct bsp29_s {
91 int own_header;
92 dheader_t *header;
93
94 int own_models;
95 int nummodels;
96 dmodel_t *models;
97
98 int own_visdata;
99 size_t visdatasize;
100 byte *visdata;
101
102 int own_lightdata;
103 size_t lightdatasize;
104 byte *lightdata;
105
106 int own_texdata;
107 size_t texdatasize;
108 byte *texdata; // (dmiptexlump_t)
109
110 int own_entdata;
111 size_t entdatasize;
112 char *entdata;
113
114 int own_leafs;
115 int numleafs;
116 dleaf29_t *leafs;
117
118 int own_planes;
119 int numplanes;
120 dplane_t *planes;
121
122 int own_vertexes;
123 int numvertexes;
124 dvertex_t *vertexes;
125
126 int own_nodes;
127 int numnodes;
128 dnode29_t *nodes;
129
130 int own_texinfo;
131 int numtexinfo;
132 texinfo_t *texinfo;
133
134 int own_faces;
135 int numfaces;
136 dface29_t *faces;
137
138 int own_clipnodes;
139 int numclipnodes;
140 dclipnode29_t *clipnodes;
141
142 int own_edges;
143 int numedges;
144 dedge29_t *edges;
145
146 int own_marksurfaces;
147 int nummarksurfaces;
148 uint16_t *marksurfaces;
149
150 int own_surfedges;
151 int numsurfedges;
152 int32_t *surfedges;
153 } bsp29_t;
154
155 static void
swap_to_bsp29(bsp29_t * bsp29,const bsp_t * bsp2)156 swap_to_bsp29 (bsp29_t *bsp29, const bsp_t *bsp2)
157 {
158 int c, i, j;
159 dmiptexlump_t *mtl;
160 dmodel_t *d;
161
162 if (bsp29->header) {
163 bsp29->header->version = LittleLong (bsp29->header->version);
164 for (i = 0; i < HEADER_LUMPS; i++) {
165 bsp29->header->lumps[i].fileofs =
166 LittleLong (bsp29->header->lumps[i].fileofs);
167 bsp29->header->lumps[i].filelen =
168 LittleLong (bsp29->header->lumps[i].filelen);
169 }
170 }
171
172 // models
173 for (i=0 ; i<bsp29->nummodels ; i++) {
174 d = &bsp29->models[i];
175
176 for (j=0 ; j<MAX_MAP_HULLS ; j++)
177 d->headnode[j] = LittleLong (d->headnode[j]);
178
179 d->visleafs = LittleLong (d->visleafs);
180 d->firstface = LittleLong (d->firstface);
181 d->numfaces = LittleLong (d->numfaces);
182
183 for (j=0 ; j<3 ; j++) {
184 d->mins[j] = LittleFloat(d->mins[j]);
185 d->maxs[j] = LittleFloat(d->maxs[j]);
186 d->origin[j] = LittleFloat(d->origin[j]);
187 }
188 }
189
190 // vertexes
191 for (i=0 ; i<bsp29->numvertexes ; i++) {
192 dvertex_t *vertex = &bsp29->vertexes[i];
193 for (j=0 ; j<3 ; j++)
194 vertex->point[j] = LittleFloat (vertex->point[j]);
195 }
196
197 // planes
198 for (i=0 ; i<bsp29->numplanes ; i++) {
199 dplane_t *plane = &bsp29->planes[i];
200 for (j=0 ; j<3 ; j++)
201 plane->normal[j] = LittleFloat (plane->normal[j]);
202 plane->dist = LittleFloat (plane->dist);
203 plane->type = LittleLong (plane->type);
204 }
205
206 // texinfos
207 for (i=0 ; i<bsp29->numtexinfo ; i++) {
208 texinfo_t *texinfo = &bsp29->texinfo[i];
209 for (j=0 ; j < 4 ; j++) {
210 texinfo->vecs[0][j] = LittleFloat (texinfo->vecs[0][j]);
211 texinfo->vecs[1][j] = LittleFloat (texinfo->vecs[1][j]);
212 }
213 texinfo->miptex = LittleLong (texinfo->miptex);
214 texinfo->flags = LittleLong (texinfo->flags);
215 }
216
217 // faces
218 for (i=0 ; i<bsp29->numfaces ; i++) {
219 const dface_t *face2 = &bsp2->faces[i];
220 dface29_t *face29 = &bsp29->faces[i];
221 face29->planenum = LittleShort (face2->planenum);
222 face29->side = LittleShort (face2->side);
223 face29->firstedge = LittleLong (face2->firstedge);
224 face29->numedges = LittleShort (face2->numedges);
225 face29->texinfo = LittleShort (face2->texinfo);
226 memcpy (face29->styles, face2->styles, sizeof(face29->styles));
227 face29->lightofs = LittleLong (face2->lightofs);
228 }
229
230 // nodes
231 for (i=0 ; i<bsp29->numnodes ; i++) {
232 const dnode_t *node2 = &bsp2->nodes[i];
233 dnode29_t *node29 = &bsp29->nodes[i];
234 node29->planenum = LittleLong (node2->planenum);
235 for (j=0 ; j<3 ; j++) {
236 node29->mins[j] = LittleShort (node2->mins[j]);
237 node29->maxs[j] = LittleShort (node2->maxs[j]);
238 }
239 node29->children[0] = (uint16_t) LittleShort (node2->children[0]);
240 node29->children[1] = (uint16_t) LittleShort (node2->children[1]);
241 node29->firstface = LittleShort (node2->firstface);
242 node29->numfaces = LittleShort (node2->numfaces);
243 }
244
245 // leafs
246 for (i=0 ; i<bsp29->numleafs ; i++) {
247 const dleaf_t *leaf2 = &bsp2->leafs[i];
248 dleaf29_t *leaf29 = &bsp29->leafs[i];
249 leaf29->contents = LittleLong (leaf2->contents);
250 for (j=0 ; j<3 ; j++) {
251 leaf29->mins[j] = LittleShort (leaf2->mins[j]);
252 leaf29->maxs[j] = LittleShort (leaf2->maxs[j]);
253 }
254
255 leaf29->firstmarksurface = LittleShort (leaf2->firstmarksurface);
256 leaf29->nummarksurfaces = LittleShort (leaf2->nummarksurfaces);
257 leaf29->visofs = LittleLong (leaf2->visofs);
258 memcpy (leaf29->ambient_level, leaf2->ambient_level,
259 sizeof(leaf29->ambient_level));
260 }
261
262 // clipnodes
263 for (i=0 ; i<bsp29->numclipnodes ; i++) {
264 const dclipnode_t *clipnode2 = &bsp2->clipnodes[i];
265 dclipnode29_t *clipnode29 = (dclipnode29_t *) &bsp29->clipnodes[i];
266 clipnode29->planenum = LittleLong (clipnode2->planenum);
267 clipnode29->children[0] = (uint16_t) LittleShort (clipnode2->children[0]);
268 clipnode29->children[1] = (uint16_t) LittleShort (clipnode2->children[1]);
269 }
270
271 // miptex
272 if (bsp29->texdatasize) {
273 mtl = (dmiptexlump_t *)bsp29->texdata;
274 //miptexlumps have not yet been swapped
275 c = mtl->nummiptex;
276 mtl->nummiptex = LittleLong (mtl->nummiptex);
277 for (i=0 ; i<c ; i++)
278 mtl->dataofs[i] = LittleLong(mtl->dataofs[i]);
279 }
280
281 // marksurfaces
282 for (i=0 ; i<bsp29->nummarksurfaces ; i++) {
283 const uint32_t *marksurface2 = &bsp2->marksurfaces[i];
284 uint16_t *marksurface29 = (uint16_t *) &bsp29->marksurfaces[i];
285 *marksurface29 = LittleShort (*marksurface2);
286 }
287
288 // surfedges
289 for (i=0 ; i<bsp29->numsurfedges ; i++) {
290 int32_t *surfedge = &bsp29->surfedges[i];
291 *surfedge = LittleLong (*surfedge);
292 }
293
294 // edges
295 for (i=0 ; i<bsp29->numedges ; i++) {
296 const dedge_t *edge2 = &bsp2->edges[i];
297 dedge29_t *edge29 = (dedge29_t *) &bsp29->edges[i];
298 edge29->v[0] = LittleShort (edge2->v[0]);
299 edge29->v[1] = LittleShort (edge2->v[1]);
300 }
301 }
302
303 static void
swap_from_bsp29(bsp_t * bsp2,const bsp29_t * bsp29,void (* cb)(const bsp_t *,void *),void * cbdata)304 swap_from_bsp29 (bsp_t *bsp2, const bsp29_t *bsp29,
305 void (*cb) (const bsp_t *, void *), void *cbdata)
306 {
307 int c, i, j;
308 dmiptexlump_t *mtl;
309 dmodel_t *d;
310
311 if (bsp2->header) {
312 bsp2->header->version = LittleLong (bsp2->header->version);
313 for (i = 0; i < HEADER_LUMPS; i++) {
314 bsp2->header->lumps[i].fileofs =
315 LittleLong (bsp2->header->lumps[i].fileofs);
316 bsp2->header->lumps[i].filelen =
317 LittleLong (bsp2->header->lumps[i].filelen);
318 }
319 if (cb)
320 cb (bsp2, cbdata);
321 }
322
323 // models
324 for (i=0 ; i<bsp2->nummodels ; i++) {
325 d = &bsp2->models[i];
326
327 for (j=0 ; j<MAX_MAP_HULLS ; j++)
328 d->headnode[j] = LittleLong (d->headnode[j]);
329
330 d->visleafs = LittleLong (d->visleafs);
331 d->firstface = LittleLong (d->firstface);
332 d->numfaces = LittleLong (d->numfaces);
333
334 for (j=0 ; j<3 ; j++) {
335 d->mins[j] = LittleFloat(d->mins[j]);
336 d->maxs[j] = LittleFloat(d->maxs[j]);
337 d->origin[j] = LittleFloat(d->origin[j]);
338 }
339 }
340
341 // vertexes
342 for (i=0 ; i<bsp2->numvertexes ; i++) {
343 dvertex_t *vertex = &bsp2->vertexes[i];
344 for (j=0 ; j<3 ; j++)
345 vertex->point[j] = LittleFloat (vertex->point[j]);
346 }
347
348 // planes
349 for (i=0 ; i<bsp2->numplanes ; i++) {
350 dplane_t *plane = &bsp2->planes[i];
351 for (j=0 ; j<3 ; j++)
352 plane->normal[j] = LittleFloat (plane->normal[j]);
353 plane->dist = LittleFloat (plane->dist);
354 plane->type = LittleLong (plane->type);
355 }
356
357 // texinfos
358 for (i=0 ; i<bsp2->numtexinfo ; i++) {
359 texinfo_t *texinfo = &bsp2->texinfo[i];
360 for (j=0 ; j < 4 ; j++) {
361 texinfo->vecs[0][j] = LittleFloat (texinfo->vecs[0][j]);
362 texinfo->vecs[1][j] = LittleFloat (texinfo->vecs[1][j]);
363 }
364 texinfo->miptex = LittleLong (texinfo->miptex);
365 texinfo->flags = LittleLong (texinfo->flags);
366 }
367
368 // faces
369 for (i=0 ; i<bsp2->numfaces ; i++) {
370 dface_t *face2 = &bsp2->faces[i];
371 const dface29_t *face29 = &bsp29->faces[i];
372 face2->planenum = LittleShort (face29->planenum);
373 face2->side = LittleShort (face29->side);
374 face2->firstedge = LittleLong (face29->firstedge);
375 face2->numedges = LittleShort (face29->numedges);
376 face2->texinfo = LittleShort (face29->texinfo);
377 memcpy (face2->styles, face29->styles, sizeof(face2->styles));
378 face2->lightofs = LittleLong (face29->lightofs);
379 }
380
381 // nodes
382 for (i=0 ; i<bsp2->numnodes ; i++) {
383 dnode_t *node2 = &bsp2->nodes[i];
384 const dnode29_t *node29 = &bsp29->nodes[i];
385 node2->planenum = LittleLong (node29->planenum);
386 for (j=0 ; j<3 ; j++) {
387 node2->mins[j] = (int16_t) LittleShort (node29->mins[j]);
388 node2->maxs[j] = (int16_t) LittleShort (node29->maxs[j]);
389 }
390 for (j = 0; j < 2; j++) {
391 node2->children[j] = LittleShort (node29->children[j]);
392 if (node2->children[j] >= bsp2->numnodes)
393 node2->children[j] = (int16_t) node2->children[j];
394 }
395 node2->firstface = LittleShort (node29->firstface);
396 node2->numfaces = LittleShort (node29->numfaces);
397 }
398
399 // leafs
400 for (i=0 ; i<bsp2->numleafs ; i++) {
401 dleaf_t *leaf2 = &bsp2->leafs[i];
402 const dleaf29_t *leaf29 = &bsp29->leafs[i];
403 leaf2->contents = LittleLong (leaf29->contents);
404 for (j=0 ; j<3 ; j++) {
405 leaf2->mins[j] = LittleShort (leaf29->mins[j]);
406 leaf2->maxs[j] = LittleShort (leaf29->maxs[j]);
407 }
408
409 leaf2->firstmarksurface = LittleShort (leaf29->firstmarksurface);
410 leaf2->nummarksurfaces = LittleShort (leaf29->nummarksurfaces);
411 leaf2->visofs = LittleLong (leaf29->visofs);
412 memcpy (leaf2->ambient_level, leaf29->ambient_level,
413 sizeof(leaf2->ambient_level));
414 }
415
416 // clipnodes
417 for (i=0 ; i<bsp2->numclipnodes ; i++) {
418 dclipnode_t *clipnode2 = &bsp2->clipnodes[i];
419 const dclipnode29_t *clipnode29 = &bsp29->clipnodes[i];
420 clipnode2->planenum = LittleLong (clipnode29->planenum);
421 clipnode2->children[0] = (uint16_t) LittleShort (clipnode29->children[0]);
422 clipnode2->children[1] = (uint16_t) LittleShort (clipnode29->children[1]);
423 }
424
425 // miptex
426 if (bsp2->texdatasize) {
427 mtl = (dmiptexlump_t *)bsp2->texdata;
428 c = LittleLong(mtl->nummiptex);
429 mtl->nummiptex = LittleLong (mtl->nummiptex);
430 for (i=0 ; i<c ; i++)
431 mtl->dataofs[i] = LittleLong(mtl->dataofs[i]);
432 }
433
434 // marksurfaces
435 for (i=0 ; i<bsp2->nummarksurfaces ; i++) {
436 uint32_t *marksurface2 = &bsp2->marksurfaces[i];
437 const uint16_t *marksurface29 = &bsp29->marksurfaces[i];
438 *marksurface2 = LittleShort (*marksurface29);
439 }
440
441 // surfedges
442 for (i=0 ; i<bsp2->numsurfedges ; i++) {
443 int32_t *surfedge = &bsp2->surfedges[i];
444 *surfedge = LittleLong (*surfedge);
445 }
446
447 // edges
448 for (i=0 ; i<bsp2->numedges ; i++) {
449 dedge_t *edge2 = &bsp2->edges[i];
450 const dedge29_t *edge29 = &bsp29->edges[i];
451 edge2->v[0] = LittleShort (edge29->v[0]);
452 edge2->v[1] = LittleShort (edge29->v[1]);
453 }
454 }
455
456 static void
swap_bsp(bsp_t * bsp,int todisk,void (* cb)(const bsp_t *,void *),void * cbdata)457 swap_bsp (bsp_t *bsp, int todisk, void (*cb) (const bsp_t *, void *),
458 void *cbdata)
459 {
460 int c, i, j;
461 dmiptexlump_t *mtl;
462 dmodel_t *d;
463
464 if (bsp->header) {
465 bsp->header->version = LittleLong (bsp->header->version);
466 for (i = 0; i < HEADER_LUMPS; i++) {
467 bsp->header->lumps[i].fileofs =
468 LittleLong (bsp->header->lumps[i].fileofs);
469 bsp->header->lumps[i].filelen =
470 LittleLong (bsp->header->lumps[i].filelen);
471 }
472 if (cb)
473 cb (bsp, cbdata);
474 }
475
476 // models
477 for (i=0 ; i<bsp->nummodels ; i++) {
478 d = &bsp->models[i];
479
480 for (j=0 ; j<MAX_MAP_HULLS ; j++)
481 d->headnode[j] = LittleLong (d->headnode[j]);
482
483 d->visleafs = LittleLong (d->visleafs);
484 d->firstface = LittleLong (d->firstface);
485 d->numfaces = LittleLong (d->numfaces);
486
487 for (j=0 ; j<3 ; j++) {
488 d->mins[j] = LittleFloat(d->mins[j]);
489 d->maxs[j] = LittleFloat(d->maxs[j]);
490 d->origin[j] = LittleFloat(d->origin[j]);
491 }
492 }
493
494 // vertexes
495 for (i=0 ; i<bsp->numvertexes ; i++) {
496 dvertex_t *vertex = &bsp->vertexes[i];
497 for (j=0 ; j<3 ; j++)
498 vertex->point[j] = LittleFloat (vertex->point[j]);
499 }
500
501 // planes
502 for (i=0 ; i<bsp->numplanes ; i++) {
503 dplane_t *plane = &bsp->planes[i];
504 for (j=0 ; j<3 ; j++)
505 plane->normal[j] = LittleFloat (plane->normal[j]);
506 plane->dist = LittleFloat (plane->dist);
507 plane->type = LittleLong (plane->type);
508 }
509
510 // texinfos
511 for (i=0 ; i<bsp->numtexinfo ; i++) {
512 texinfo_t *texinfo = &bsp->texinfo[i];
513 for (j=0 ; j < 4 ; j++) {
514 texinfo->vecs[0][j] = LittleFloat (texinfo->vecs[0][j]);
515 texinfo->vecs[1][j] = LittleFloat (texinfo->vecs[1][j]);
516 }
517 texinfo->miptex = LittleLong (texinfo->miptex);
518 texinfo->flags = LittleLong (texinfo->flags);
519 }
520
521 // faces
522 for (i=0 ; i<bsp->numfaces ; i++) {
523 dface_t *face = &bsp->faces[i];
524 face->texinfo = LittleLong (face->texinfo);
525 face->planenum = LittleLong (face->planenum);
526 face->side = LittleLong (face->side);
527 face->lightofs = LittleLong (face->lightofs);
528 face->firstedge = LittleLong (face->firstedge);
529 face->numedges = LittleLong (face->numedges);
530 }
531
532 // nodes
533 for (i=0 ; i<bsp->numnodes ; i++) {
534 dnode_t *node = &bsp->nodes[i];
535 node->planenum = LittleLong (node->planenum);
536 for (j=0 ; j<3 ; j++) {
537 node->mins[j] = LittleFloat (node->mins[j]);
538 node->maxs[j] = LittleFloat (node->maxs[j]);
539 }
540 node->children[0] = LittleLong (node->children[0]);
541 node->children[1] = LittleLong (node->children[1]);
542 node->firstface = LittleLong (node->firstface);
543 node->numfaces = LittleLong (node->numfaces);
544 }
545
546 // leafs
547 for (i=0 ; i<bsp->numleafs ; i++) {
548 dleaf_t *leaf = &bsp->leafs[i];
549 leaf->contents = LittleLong (leaf->contents);
550 for (j=0 ; j<3 ; j++) {
551 leaf->mins[j] = LittleFloat (leaf->mins[j]);
552 leaf->maxs[j] = LittleFloat (leaf->maxs[j]);
553 }
554
555 leaf->firstmarksurface = LittleLong (leaf->firstmarksurface);
556 leaf->nummarksurfaces = LittleLong (leaf->nummarksurfaces);
557 leaf->visofs = LittleLong (leaf->visofs);
558 }
559
560 // clipnodes
561 for (i=0 ; i<bsp->numclipnodes ; i++) {
562 dclipnode_t *clipnode = &bsp->clipnodes[i];
563 clipnode->planenum = LittleLong (clipnode->planenum);
564 clipnode->children[0] = LittleLong (clipnode->children[0]);
565 clipnode->children[1] = LittleLong (clipnode->children[1]);
566 }
567
568 // miptex
569 if (bsp->texdatasize) {
570 mtl = (dmiptexlump_t *)bsp->texdata;
571 if (todisk)
572 c = mtl->nummiptex;
573 else
574 c = LittleLong(mtl->nummiptex);
575 mtl->nummiptex = LittleLong (mtl->nummiptex);
576 for (i=0 ; i<c ; i++)
577 mtl->dataofs[i] = LittleLong(mtl->dataofs[i]);
578 }
579
580 // marksurfaces
581 for (i=0 ; i<bsp->nummarksurfaces ; i++) {
582 uint32_t *marksurface = &bsp->marksurfaces[i];
583 *marksurface = LittleLong (*marksurface);
584 }
585
586 // surfedges
587 for (i=0 ; i<bsp->numsurfedges ; i++) {
588 int32_t *surfedge = &bsp->surfedges[i];
589 *surfedge = LittleLong (*surfedge);
590 }
591
592 // edges
593 for (i=0 ; i<bsp->numedges ; i++) {
594 dedge_t *edge = &bsp->edges[i];
595 edge->v[0] = LittleLong (edge->v[0]);
596 edge->v[1] = LittleLong (edge->v[1]);
597 }
598 }
599
600 static void
set_bsp2_read(void * mem,size_t mem_size,bsp_t * bsp)601 set_bsp2_read (void *mem, size_t mem_size, bsp_t *bsp)
602 {
603 #undef SET_LUMP
604 #define SET_LUMP(l,n) \
605 do { \
606 size_t size = LittleLong (bsp->header->lumps[l].filelen); \
607 size_t offs = LittleLong (bsp->header->lumps[l].fileofs); \
608 void *data = (byte *) mem + offs; \
609 if (offs >= mem_size || (offs + size) > mem_size) \
610 Sys_Error ("invalid lump"); \
611 if (size % sizeof (bsp->n[0])) \
612 Sys_Error ("funny lump size"); \
613 bsp->n = 0; \
614 if (size) \
615 bsp->n = (void *) data; \
616 bsp->num##n = size / sizeof (bsp->n[0]); \
617 } while (0)
618
619 SET_LUMP (LUMP_PLANES, planes);
620 SET_LUMP (LUMP_LEAFS, leafs);
621 SET_LUMP (LUMP_VERTEXES, vertexes);
622 SET_LUMP (LUMP_NODES, nodes);
623 SET_LUMP (LUMP_TEXINFO, texinfo);
624 SET_LUMP (LUMP_FACES, faces);
625 SET_LUMP (LUMP_CLIPNODES, clipnodes);
626 SET_LUMP (LUMP_MARKSURFACES, marksurfaces);
627 SET_LUMP (LUMP_SURFEDGES, surfedges);
628 SET_LUMP (LUMP_EDGES, edges);
629 SET_LUMP (LUMP_MODELS, models);
630
631 #undef SET_LUMP
632 #define SET_LUMP(l,n) \
633 do { \
634 size_t size = LittleLong (bsp->header->lumps[l].filelen); \
635 size_t offs = LittleLong (bsp->header->lumps[l].fileofs); \
636 void *data = (byte *) mem + offs; \
637 if (offs >= mem_size || (offs + size) > mem_size) \
638 Sys_Error ("invalid lump"); \
639 bsp->n = 0; \
640 if (size) \
641 bsp->n = (void *) data; \
642 bsp->n##size = size; \
643 } while (0)
644
645 SET_LUMP (LUMP_LIGHTING, lightdata);
646 SET_LUMP (LUMP_VISIBILITY, visdata);
647 SET_LUMP (LUMP_ENTITIES, entdata);
648 SET_LUMP (LUMP_TEXTURES, texdata);
649 }
650
651 static void
set_bsp29_read(void * mem,size_t mem_size,bsp29_t * bsp29)652 set_bsp29_read (void *mem, size_t mem_size, bsp29_t *bsp29)
653 {
654 #undef SET_LUMP
655 #define SET_LUMP(l,n) \
656 do { \
657 size_t size = LittleLong (bsp29->header->lumps[l].filelen); \
658 size_t offs = LittleLong (bsp29->header->lumps[l].fileofs); \
659 void *data = (byte *) mem + offs; \
660 if (offs >= mem_size || (offs + size) > mem_size) \
661 Sys_Error ("invalid lump"); \
662 if (size % sizeof (bsp29->n[0])) \
663 Sys_Error ("funny lump size"); \
664 bsp29->n = 0; \
665 if (size) \
666 bsp29->n = (void *) data; \
667 bsp29->num##n = size / sizeof (bsp29->n[0]); \
668 } while (0)
669
670 SET_LUMP (LUMP_PLANES, planes);
671 SET_LUMP (LUMP_LEAFS, leafs);
672 SET_LUMP (LUMP_VERTEXES, vertexes);
673 SET_LUMP (LUMP_NODES, nodes);
674 SET_LUMP (LUMP_TEXINFO, texinfo);
675 SET_LUMP (LUMP_FACES, faces);
676 SET_LUMP (LUMP_CLIPNODES, clipnodes);
677 SET_LUMP (LUMP_MARKSURFACES, marksurfaces);
678 SET_LUMP (LUMP_SURFEDGES, surfedges);
679 SET_LUMP (LUMP_EDGES, edges);
680 SET_LUMP (LUMP_MODELS, models);
681
682 #undef SET_LUMP
683 #define SET_LUMP(l,n) \
684 do { \
685 size_t size = LittleLong (bsp29->header->lumps[l].filelen); \
686 size_t offs = LittleLong (bsp29->header->lumps[l].fileofs); \
687 void *data = (byte *) mem + offs; \
688 if (offs >= mem_size || (offs + size) > mem_size) \
689 Sys_Error ("invalid lump"); \
690 bsp29->n = 0; \
691 if (size) \
692 bsp29->n = (void *) data; \
693 bsp29->n##size = size; \
694 } while (0)
695
696 SET_LUMP (LUMP_LIGHTING, lightdata);
697 SET_LUMP (LUMP_VISIBILITY, visdata);
698 SET_LUMP (LUMP_ENTITIES, entdata);
699 SET_LUMP (LUMP_TEXTURES, texdata);
700 }
701
702 bsp_t *
LoadBSPMem(void * mem,size_t mem_size,void (* cb)(const bsp_t *,void *),void * cbdata)703 LoadBSPMem (void *mem, size_t mem_size, void (*cb) (const bsp_t *, void *),
704 void *cbdata)
705 {
706 bsp_t *bsp;
707 int version;
708 qboolean bsp2 = false;
709
710 bsp = calloc (sizeof (bsp_t), 1);
711
712 bsp->header = mem;
713
714 version = LittleLong (bsp->header->version);
715 if (!memcmp (&bsp->header->version, BSP2VERSION, 4)) {
716 bsp2 = true;
717 } else if (version != BSPVERSION)
718 Sys_Error ("version %i, neither %i nor %s", version, BSPVERSION,
719 BSP2VERSION);
720
721 if (bsp2) {
722 set_bsp2_read (mem, mem_size, bsp);
723 swap_bsp (bsp, 0, cb, cbdata);
724 } else {
725 bsp29_t bsp29;
726
727 if (sizeof (bsp29) != sizeof (*bsp))
728 Sys_Error ("taniwha's being lazy about bsp29 support");
729 memcpy (&bsp29, bsp, sizeof (bsp29));
730 set_bsp29_read (mem, mem_size, &bsp29);
731 memcpy (bsp, &bsp29, sizeof (bsp29));
732
733 #undef SET_LUMP
734 #define SET_LUMP(n) \
735 do { \
736 if (bsp->num##n) {\
737 bsp->n = (void *) malloc (bsp->num##n * sizeof (bsp->n[0])); \
738 bsp->own_##n = 1; \
739 } \
740 } while (0)
741
742 SET_LUMP (nodes);
743 SET_LUMP (clipnodes);
744 SET_LUMP (edges);
745 SET_LUMP (faces);
746 SET_LUMP (leafs);
747 SET_LUMP (marksurfaces);
748 swap_from_bsp29 (bsp, &bsp29, cb, cbdata);
749 }
750 return bsp;
751 }
752
753 VISIBLE bsp_t *
LoadBSPFile(QFile * file,size_t size)754 LoadBSPFile (QFile *file, size_t size)
755 {
756 void *buf;
757 bsp_t *bsp;
758
759 buf = malloc (size);
760 Qread (file, buf, size);
761 bsp = LoadBSPMem (buf, size, 0, 0);
762 bsp->own_header = 1;
763 return bsp;
764 }
765
766 #define ROUND(x) (((x) + 3) & ~3)
767
768 static bsp_t *
set_bsp2_write(const bsp_t * bsp,size_t * _size)769 set_bsp2_write (const bsp_t *bsp, size_t *_size)
770 {
771 size_t size;
772 byte *data;
773 bsp_t *tbsp;
774
775 size = sizeof (*tbsp);
776 size += ROUND (sizeof (dheader_t));
777 size += ROUND (bsp->nummodels * sizeof (dmodel_t));
778 size += ROUND (bsp->visdatasize);
779 size += ROUND (bsp->lightdatasize);
780 size += ROUND (bsp->texdatasize);
781 size += ROUND (bsp->entdatasize);
782 size += ROUND (bsp->numleafs * sizeof (dleaf_t));
783 size += ROUND (bsp->numplanes * sizeof (dplane_t));
784 size += ROUND (bsp->numvertexes * sizeof (dvertex_t));
785 size += ROUND (bsp->numnodes * sizeof (dnode_t));
786 size += ROUND (bsp->numtexinfo * sizeof (texinfo_t));
787 size += ROUND (bsp->numfaces * sizeof (dface_t));
788 size += ROUND (bsp->numclipnodes * sizeof (dclipnode_t));
789 size += ROUND (bsp->numedges * sizeof (dedge_t));
790 size += ROUND (bsp->nummarksurfaces * sizeof (uint32_t));
791 size += ROUND (bsp->numsurfedges * sizeof (uint32_t));
792
793 tbsp = calloc (size, 1);
794 tbsp->header = (dheader_t *) &tbsp[1];
795
796 #undef SET_LUMP
797 #define SET_LUMP(l,n) \
798 do { \
799 tbsp->num##n = bsp->num##n; \
800 if (tbsp->num##n) {\
801 tbsp->n = (void *) data; \
802 tbsp->header->lumps[l].fileofs = data - (byte *) tbsp->header; \
803 tbsp->header->lumps[l].filelen = tbsp->num##n * sizeof (tbsp->n[0]); \
804 memcpy (data, bsp->n, tbsp->header->lumps[l].filelen); \
805 data += ROUND (tbsp->header->lumps[l].filelen); \
806 } else {\
807 tbsp->n = 0; \
808 tbsp->header->lumps[l].fileofs = 0; \
809 tbsp->header->lumps[l].filelen = 0; \
810 } \
811 } while (0)
812
813 tbsp->header->version = BSPVERSION;
814
815 data = (byte *) &tbsp->header[1];
816 SET_LUMP (LUMP_PLANES, planes);
817 SET_LUMP (LUMP_LEAFS, leafs);
818 SET_LUMP (LUMP_VERTEXES, vertexes);
819 SET_LUMP (LUMP_NODES, nodes);
820 SET_LUMP (LUMP_TEXINFO, texinfo);
821 SET_LUMP (LUMP_FACES, faces);
822 SET_LUMP (LUMP_CLIPNODES, clipnodes);
823 SET_LUMP (LUMP_MARKSURFACES, marksurfaces);
824 SET_LUMP (LUMP_SURFEDGES, surfedges);
825 SET_LUMP (LUMP_EDGES, edges);
826 SET_LUMP (LUMP_MODELS, models);
827
828 #undef SET_LUMP
829 #define SET_LUMP(l,n) \
830 do { \
831 tbsp->n##size = bsp->n##size; \
832 if (tbsp->n##size) { \
833 tbsp->n = (void *) data; \
834 tbsp->header->lumps[l].fileofs = data - (byte *) tbsp->header; \
835 tbsp->header->lumps[l].filelen = tbsp->n##size; \
836 memcpy (data, bsp->n, tbsp->n##size); \
837 data += ROUND (tbsp->header->lumps[l].filelen); \
838 } else {\
839 tbsp->n = 0; \
840 tbsp->header->lumps[l].fileofs = 0; \
841 tbsp->header->lumps[l].filelen = 0; \
842 } \
843 } while (0)
844
845 SET_LUMP (LUMP_LIGHTING, lightdata);
846 SET_LUMP (LUMP_VISIBILITY, visdata);
847 SET_LUMP (LUMP_ENTITIES, entdata);
848 SET_LUMP (LUMP_TEXTURES, texdata);
849
850 *_size = size - sizeof (*tbsp);
851 return tbsp;
852 }
853
854 static bsp29_t *
set_bsp29_write(const bsp_t * bsp,size_t * _size)855 set_bsp29_write (const bsp_t *bsp, size_t *_size)
856 {
857 size_t size;
858 byte *data;
859 bsp29_t *tbsp;
860
861 size = sizeof (*tbsp);
862 size += ROUND (sizeof (dheader_t));
863 size += ROUND (bsp->nummodels * sizeof (dmodel_t));
864 size += ROUND (bsp->visdatasize);
865 size += ROUND (bsp->lightdatasize);
866 size += ROUND (bsp->texdatasize);
867 size += ROUND (bsp->entdatasize);
868 size += ROUND (bsp->numleafs * sizeof (dleaf29_t));
869 size += ROUND (bsp->numplanes * sizeof (dplane_t));
870 size += ROUND (bsp->numvertexes * sizeof (dvertex_t));
871 size += ROUND (bsp->numnodes * sizeof (dnode29_t));
872 size += ROUND (bsp->numtexinfo * sizeof (texinfo_t));
873 size += ROUND (bsp->numfaces * sizeof (dface29_t));
874 size += ROUND (bsp->numclipnodes * sizeof (dclipnode29_t));
875 size += ROUND (bsp->numedges * sizeof (dedge29_t));
876 size += ROUND (bsp->nummarksurfaces * sizeof (uint16_t));
877 size += ROUND (bsp->numsurfedges * sizeof (uint32_t));
878
879 tbsp = calloc (size, 1);
880 tbsp->header = (dheader_t *) &tbsp[1];
881
882 #undef SET_LUMP
883 #define SET_LUMP(l,n) \
884 do { \
885 tbsp->num##n = bsp->num##n; \
886 if (tbsp->num##n) {\
887 tbsp->n = (void *) data; \
888 tbsp->header->lumps[l].fileofs = data - (byte *) tbsp->header; \
889 tbsp->header->lumps[l].filelen = tbsp->num##n * sizeof (tbsp->n[0]); \
890 memcpy (data, bsp->n, tbsp->header->lumps[l].filelen); \
891 data += ROUND (tbsp->header->lumps[l].filelen); \
892 } else {\
893 tbsp->n = 0; \
894 tbsp->header->lumps[l].fileofs = 0; \
895 tbsp->header->lumps[l].filelen = 0; \
896 } \
897 } while (0)
898
899 tbsp->header->version = BSPVERSION;
900
901 data = (byte *) &tbsp->header[1];
902 SET_LUMP (LUMP_PLANES, planes);
903 SET_LUMP (LUMP_LEAFS, leafs);
904 SET_LUMP (LUMP_VERTEXES, vertexes);
905 SET_LUMP (LUMP_NODES, nodes);
906 SET_LUMP (LUMP_TEXINFO, texinfo);
907 SET_LUMP (LUMP_FACES, faces);
908 SET_LUMP (LUMP_CLIPNODES, clipnodes);
909 SET_LUMP (LUMP_MARKSURFACES, marksurfaces);
910 SET_LUMP (LUMP_SURFEDGES, surfedges);
911 SET_LUMP (LUMP_EDGES, edges);
912 SET_LUMP (LUMP_MODELS, models);
913
914 #undef SET_LUMP
915 #define SET_LUMP(l,n) \
916 do { \
917 tbsp->n##size = bsp->n##size; \
918 if (tbsp->n##size) { \
919 tbsp->n = (void *) data; \
920 tbsp->header->lumps[l].fileofs = data - (byte *) tbsp->header; \
921 tbsp->header->lumps[l].filelen = tbsp->n##size; \
922 memcpy (data, bsp->n, tbsp->n##size); \
923 data += ROUND (tbsp->header->lumps[l].filelen); \
924 } else {\
925 tbsp->n = 0; \
926 tbsp->header->lumps[l].fileofs = 0; \
927 tbsp->header->lumps[l].filelen = 0; \
928 } \
929 } while (0)
930
931 SET_LUMP (LUMP_LIGHTING, lightdata);
932 SET_LUMP (LUMP_VISIBILITY, visdata);
933 SET_LUMP (LUMP_ENTITIES, entdata);
934 SET_LUMP (LUMP_TEXTURES, texdata);
935
936 *_size = size - sizeof (*tbsp);
937 return tbsp;
938 }
939
940 /*
941 WriteBSPFile
942 */
943 VISIBLE void
WriteBSPFile(const bsp_t * bsp,QFile * file)944 WriteBSPFile (const bsp_t *bsp, QFile *file)
945 {
946 qboolean bsp2 = ( bsp->models[0].mins[0] < -32768.0f
947 || bsp->models[0].mins[1] < -32768.0f
948 || bsp->models[0].mins[2] < -32768.0f
949 || bsp->models[0].mins[0] >= 32768.0f
950 || bsp->models[0].mins[1] >= 32768.0f
951 || bsp->models[0].mins[2] >= 32768.0f
952 || bsp->nummarksurfaces >= 32768
953 || bsp->numvertexes >= 32768
954 || bsp->numnodes >= 32768
955 || bsp->numleafs >= 32768
956 || bsp->numplanes >= 32768
957 || bsp->numtexinfo >= 32768
958 || bsp->numclipnodes >= 32768);
959
960 if (bsp2) {
961 bsp_t *tbsp;
962 size_t size;
963
964 tbsp = set_bsp2_write (bsp, &size);
965 swap_bsp (tbsp, 1, 0, 0);
966 Qwrite (file, tbsp->header, size);
967 free (tbsp);
968 } else {
969 bsp29_t *tbsp;
970 size_t size;
971
972 tbsp = set_bsp29_write (bsp, &size);
973 swap_to_bsp29 (tbsp, bsp);
974 Qwrite (file, tbsp->header, size);
975 free (tbsp);
976 }
977 }
978
979 VISIBLE bsp_t *
BSP_New(void)980 BSP_New (void)
981 {
982 return calloc (1, sizeof (bsp_t));
983 }
984
985 VISIBLE void
BSP_Free(bsp_t * bsp)986 BSP_Free (bsp_t *bsp)
987 {
988 #define FREE(X) \
989 do { \
990 if (bsp->own_##X && bsp->X) \
991 free (bsp->X); \
992 } while (0)
993
994 FREE (models);
995 FREE (visdata);
996 FREE (lightdata);
997 FREE (texdata);
998 FREE (entdata);
999 FREE (leafs);
1000 FREE (planes);
1001 FREE (vertexes);
1002 FREE (nodes);
1003 FREE (texinfo);
1004 FREE (faces);
1005 FREE (clipnodes);
1006 FREE (edges);
1007 FREE (marksurfaces);
1008 FREE (surfedges);
1009 FREE (header);
1010
1011 free (bsp);
1012 }
1013
1014 #define REALLOC(X) \
1015 do { \
1016 if (!bsp->own_##X) { \
1017 bsp->own_##X = 1; \
1018 bsp->X = 0; \
1019 } \
1020 bsp->X = realloc (bsp->X, (bsp->num##X + 1) * sizeof (bsp->X[0])); \
1021 } while (0)
1022
1023 VISIBLE void
BSP_AddPlane(bsp_t * bsp,const dplane_t * plane)1024 BSP_AddPlane (bsp_t *bsp, const dplane_t *plane)
1025 {
1026 REALLOC (planes);
1027 bsp->planes[bsp->numplanes++] = *plane;
1028 }
1029
1030 VISIBLE void
BSP_AddLeaf(bsp_t * bsp,const dleaf_t * leaf)1031 BSP_AddLeaf (bsp_t *bsp, const dleaf_t *leaf)
1032 {
1033 REALLOC (leafs);
1034 bsp->leafs[bsp->numleafs++] = *leaf;
1035 }
1036
1037 VISIBLE void
BSP_AddVertex(bsp_t * bsp,const dvertex_t * vertex)1038 BSP_AddVertex (bsp_t *bsp, const dvertex_t *vertex)
1039 {
1040 REALLOC (vertexes);
1041 bsp->vertexes[bsp->numvertexes++] = *vertex;
1042 }
1043
1044 VISIBLE void
BSP_AddNode(bsp_t * bsp,const dnode_t * node)1045 BSP_AddNode (bsp_t *bsp, const dnode_t *node)
1046 {
1047 REALLOC (nodes);
1048 bsp->nodes[bsp->numnodes++] = *node;
1049 }
1050
1051 VISIBLE void
BSP_AddTexinfo(bsp_t * bsp,const texinfo_t * texinfo)1052 BSP_AddTexinfo (bsp_t *bsp, const texinfo_t *texinfo)
1053 {
1054 REALLOC (texinfo);
1055 bsp->texinfo[bsp->numtexinfo++] = *texinfo;
1056 }
1057
1058 VISIBLE void
BSP_AddFace(bsp_t * bsp,const dface_t * face)1059 BSP_AddFace (bsp_t *bsp, const dface_t *face)
1060 {
1061 REALLOC (faces);
1062 bsp->faces[bsp->numfaces++] = *face;
1063 }
1064
1065 VISIBLE void
BSP_AddClipnode(bsp_t * bsp,const dclipnode_t * clipnode)1066 BSP_AddClipnode (bsp_t *bsp, const dclipnode_t *clipnode)
1067 {
1068 REALLOC (clipnodes);
1069 bsp->clipnodes[bsp->numclipnodes++] = *clipnode;
1070 }
1071
1072 VISIBLE void
BSP_AddMarkSurface(bsp_t * bsp,int marksurface)1073 BSP_AddMarkSurface (bsp_t *bsp, int marksurface)
1074 {
1075 REALLOC (marksurfaces);
1076 bsp->marksurfaces[bsp->nummarksurfaces++] = marksurface;
1077 }
1078
1079 VISIBLE void
BSP_AddSurfEdge(bsp_t * bsp,int surfedge)1080 BSP_AddSurfEdge (bsp_t *bsp, int surfedge)
1081 {
1082 REALLOC (surfedges);
1083 bsp->surfedges[bsp->numsurfedges++] = surfedge;
1084 }
1085
1086 VISIBLE void
BSP_AddEdge(bsp_t * bsp,const dedge_t * edge)1087 BSP_AddEdge (bsp_t *bsp, const dedge_t *edge)
1088 {
1089 REALLOC (edges);
1090 bsp->edges[bsp->numedges++] = *edge;
1091 }
1092
1093 VISIBLE void
BSP_AddModel(bsp_t * bsp,const dmodel_t * model)1094 BSP_AddModel (bsp_t *bsp, const dmodel_t *model)
1095 {
1096 REALLOC (models);
1097 bsp->models[bsp->nummodels++] = *model;
1098 }
1099
1100 #define OWN(X) \
1101 do { \
1102 FREE(X); \
1103 bsp->own_##X = 1; \
1104 } while (0)
1105
1106 VISIBLE void
BSP_AddLighting(bsp_t * bsp,const byte * lightdata,size_t lightdatasize)1107 BSP_AddLighting (bsp_t *bsp, const byte *lightdata, size_t lightdatasize)
1108 {
1109 OWN (lightdata);
1110 bsp->lightdatasize = lightdatasize;
1111 bsp->lightdata = malloc (lightdatasize);
1112 memcpy (bsp->lightdata, lightdata, lightdatasize);
1113 }
1114
1115 VISIBLE void
BSP_AddVisibility(bsp_t * bsp,const byte * visdata,size_t visdatasize)1116 BSP_AddVisibility (bsp_t *bsp, const byte *visdata, size_t visdatasize)
1117 {
1118 OWN (visdata);
1119 bsp->visdatasize = visdatasize;
1120 bsp->visdata = malloc (visdatasize);
1121 memcpy (bsp->visdata, visdata, visdatasize);
1122 }
1123
1124 VISIBLE void
BSP_AddEntities(bsp_t * bsp,const char * entdata,size_t entdatasize)1125 BSP_AddEntities (bsp_t *bsp, const char *entdata, size_t entdatasize)
1126 {
1127 OWN (entdata);
1128 bsp->entdatasize = entdatasize;
1129 bsp->entdata = malloc (entdatasize);
1130 memcpy (bsp->entdata, entdata, entdatasize);
1131 }
1132
1133 VISIBLE void
BSP_AddTextures(bsp_t * bsp,const byte * texdata,size_t texdatasize)1134 BSP_AddTextures (bsp_t *bsp, const byte *texdata, size_t texdatasize)
1135 {
1136 OWN (texdata);
1137 bsp->texdatasize = texdatasize;
1138 bsp->texdata = malloc (texdatasize);
1139 memcpy (bsp->texdata, texdata, texdatasize);
1140 }
1141