File: | tools/ufo2map/common/bspfile.cpp |
Location: | line 60, column 4 |
Description: | Value stored to 'count_p' is never read |
1 | /** |
2 | * @file |
3 | * @brief |
4 | */ |
5 | |
6 | /* |
7 | Copyright (C) 1997-2001 Id Software, Inc. |
8 | |
9 | This program is free software; you can redistribute it and/or |
10 | modify it under the terms of the GNU General Public License |
11 | as published by the Free Software Foundation; either version 2 |
12 | of the License, or (at your option) any later version. |
13 | |
14 | This program is distributed in the hope that it will be useful, |
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | |
18 | See the GNU General Public License for more details. |
19 | |
20 | You should have received a copy of the GNU General Public License |
21 | along with this program; if not, write to the Free Software |
22 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
23 | |
24 | */ |
25 | |
26 | #include "shared.h" |
27 | #include "bspfile.h" |
28 | #include "scriplib.h" |
29 | #include "../bsp.h" |
30 | #include <errno(*__error()).h> |
31 | |
32 | /** |
33 | * @brief Compress the routing data of a map |
34 | * @sa CMod_DeCompressRouting |
35 | * @sa CMod_LoadRouting |
36 | */ |
37 | byte *CompressRouting (byte *dataStart, byte *destStart, int l) |
38 | { |
39 | int c; |
40 | byte val; |
41 | byte *data, *dend, *dest_p, *count_p; |
42 | |
43 | dest_p = destStart; |
44 | data = dataStart; |
45 | dend = dataStart + l; |
46 | |
47 | while (data < dend) { |
48 | if (data + 1 < dend && *data == *(data + 1)) { |
49 | /* repetitions */ |
50 | val = *data++; |
51 | data++; /* Advance data again. The first two bytes are identical!!! */ |
52 | c = 0; /* This means 2 bytes are the same. Total bytes the same is 2 + c */ |
53 | /* Loop while the piece of data being looked at equals val */ |
54 | while (data + 1 < dend && val == *(data)) { |
55 | if (c >= SCHAR_MAX127) /* must fit into one byte */ |
56 | break; |
57 | data++; |
58 | c++; |
59 | } |
60 | count_p = dest_p; |
Value stored to 'count_p' is never read | |
61 | *dest_p++ = (byte)(c) | 0x80; |
62 | *dest_p++ = val; |
63 | } else { |
64 | /* identities */ |
65 | count_p = dest_p++; |
66 | c = 0; |
67 | while ((data + 1 < dend && *data != *(data + 1)) || data == dend - 1) { |
68 | if (c >= SCHAR_MAX127) /* must fit into one byte */ |
69 | break; |
70 | *dest_p++ = *data++; |
71 | c++; |
72 | } |
73 | *count_p = (byte)c; |
74 | } |
75 | } |
76 | |
77 | /* terminate compressed data */ |
78 | *dest_p++ = 0; |
79 | |
80 | return dest_p; |
81 | } |
82 | |
83 | /** |
84 | * @brief Byte swaps all data in a bsp file. |
85 | */ |
86 | static void SwapBSPFile (void) |
87 | { |
88 | int i, j, k; |
89 | |
90 | /* models */ |
91 | for (i = 0; i < curTile->nummodels; i++) { |
92 | dBspModel_t *d = &curTile->models[i]; |
93 | |
94 | d->firstface = LittleLong(d->firstface)(int)(d->firstface); |
95 | d->numfaces = LittleLong(d->numfaces)(int)(d->numfaces); |
96 | d->headnode = LittleLong(d->headnode)(int)(d->headnode); |
97 | |
98 | for (j = 0; j < 3; j++) { |
99 | d->mins[j] = LittleFloat(d->mins[j])(d->mins[j]); |
100 | d->maxs[j] = LittleFloat(d->maxs[j])(d->maxs[j]); |
101 | d->origin[j] = LittleFloat(d->origin[j])(d->origin[j]); |
102 | } |
103 | } |
104 | |
105 | /* vertexes */ |
106 | for (i = 0; i < curTile->numvertexes; i++) { |
107 | dBspVertex_t *vertexes = &curTile->vertexes[i]; |
108 | for (j = 0; j < 3; j++) |
109 | vertexes->point[j] = LittleFloat(vertexes->point[j])(vertexes->point[j]); |
110 | } |
111 | |
112 | /* planes */ |
113 | for (i = 0; i < curTile->numplanes; i++) { |
114 | dBspPlane_t *plane = &curTile->planes[i]; |
115 | for (j = 0; j < 3; j++) |
116 | plane->normal[j] = LittleFloat(plane->normal[j])(plane->normal[j]); |
117 | plane->dist = LittleFloat(plane->dist)(plane->dist); |
118 | plane->type = LittleLong(plane->type)(int)(plane->type); |
119 | } |
120 | |
121 | /* texinfos */ |
122 | for (i = 0; i < curTile->numtexinfo; i++) { |
123 | dBspTexinfo_t *texinfo = &curTile->texinfo[i]; |
124 | for (j = 0; j < 2; j++) |
125 | for (k = 0; k < 4; k++) |
126 | texinfo->vecs[j][k] = LittleFloat(texinfo->vecs[j][k])(texinfo->vecs[j][k]); |
127 | texinfo->surfaceFlags = LittleLong(texinfo->surfaceFlags)(int)(texinfo->surfaceFlags); |
128 | texinfo->value = LittleLong(texinfo->value)(int)(texinfo->value); |
129 | } |
130 | |
131 | /* faces */ |
132 | for (i = 0; i < curTile->numfaces; i++) { |
133 | dBspSurface_t *face = &curTile->faces[i]; |
134 | face->texinfo = LittleShort(face->texinfo)(short)(face->texinfo); |
135 | face->planenum = LittleShort(face->planenum)(short)(face->planenum); |
136 | face->side = LittleShort(face->side)(short)(face->side); |
137 | for (j = 0; j < LIGHTMAP_MAX2; j++) |
138 | face->lightofs[j] = LittleLong(face->lightofs[j])(int)(face->lightofs[j]); |
139 | face->firstedge = LittleLong(face->firstedge)(int)(face->firstedge); |
140 | face->numedges = LittleShort(face->numedges)(short)(face->numedges); |
141 | } |
142 | |
143 | /* nodes */ |
144 | for (i = 0; i < curTile->numnodes; i++) { |
145 | dBspNode_t *node = &curTile->nodes[i]; |
146 | /* planenum might be -1 here - special case for pathfinding nodes */ |
147 | node->planenum = LittleLong(node->planenum)(int)(node->planenum); |
148 | for (j = 0; j < 3; j++) { |
149 | node->mins[j] = LittleShort(node->mins[j])(short)(node->mins[j]); |
150 | node->maxs[j] = LittleShort(node->maxs[j])(short)(node->maxs[j]); |
151 | } |
152 | node->children[0] = LittleLong(node->children[0])(int)(node->children[0]); |
153 | node->children[1] = LittleLong(node->children[1])(int)(node->children[1]); |
154 | node->firstface = LittleShort(node->firstface)(short)(node->firstface); |
155 | node->numfaces = LittleShort(node->numfaces)(short)(node->numfaces); |
156 | } |
157 | |
158 | /* leafs */ |
159 | for (i = 0; i < curTile->numleafs; i++) { |
160 | dBspLeaf_t *leaf = &curTile->leafs[i]; |
161 | leaf->contentFlags = LittleLong(leaf->contentFlags)(int)(leaf->contentFlags); |
162 | leaf->area = LittleShort(leaf->area)(short)(leaf->area); |
163 | for (j = 0; j < 3; j++) { |
164 | leaf->mins[j] = LittleShort(leaf->mins[j])(short)(leaf->mins[j]); |
165 | leaf->maxs[j] = LittleShort(leaf->maxs[j])(short)(leaf->maxs[j]); |
166 | } |
167 | |
168 | leaf->firstleafbrush = LittleShort(leaf->firstleafbrush)(short)(leaf->firstleafbrush); |
169 | leaf->numleafbrushes = LittleShort(leaf->numleafbrushes)(short)(leaf->numleafbrushes); |
170 | } |
171 | |
172 | /* leafbrushes */ |
173 | for (i = 0; i < curTile->numleafbrushes; i++) |
174 | curTile->leafbrushes[i] = LittleShort(curTile->leafbrushes[i])(short)(curTile->leafbrushes[i]); |
175 | |
176 | /* surfedges */ |
177 | for (i = 0; i < curTile->numsurfedges; i++) |
178 | curTile->surfedges[i] = LittleLong(curTile->surfedges[i])(int)(curTile->surfedges[i]); |
179 | |
180 | /* edges */ |
181 | for (i = 0; i < curTile->numedges; i++) { |
182 | dBspEdge_t *edge = &curTile->edges[i]; |
183 | edge->v[0] = LittleShort(edge->v[0])(short)(edge->v[0]); |
184 | edge->v[1] = LittleShort(edge->v[1])(short)(edge->v[1]); |
185 | } |
186 | |
187 | /* dbrushes */ |
188 | for (i = 0; i < curTile->numbrushes; i++) { |
189 | dBspBrush_t *dbrush = &curTile->dbrushes[i]; |
190 | dbrush->firstbrushside = LittleLong(dbrush->firstbrushside)(int)(dbrush->firstbrushside); |
191 | dbrush->numsides = LittleLong(dbrush->numsides)(int)(dbrush->numsides); |
192 | dbrush->contentFlags = LittleLong(dbrush->contentFlags)(int)(dbrush->contentFlags); |
193 | } |
194 | |
195 | /* brushes */ |
196 | for (i = 0; i < curTile->numbrushes; i++) { |
197 | cBspBrush_t *cbrush = &curTile->brushes[i]; |
198 | cbrush->firstbrushside = LittleLong(cbrush->firstbrushside)(int)(cbrush->firstbrushside); |
199 | cbrush->numsides = LittleLong(cbrush->numsides)(int)(cbrush->numsides); |
200 | cbrush->contentFlags = LittleLong(cbrush->contentFlags)(int)(cbrush->contentFlags); |
201 | } |
202 | |
203 | /* brushsides */ |
204 | for (i = 0; i < curTile->numbrushsides; i++) { |
205 | dBspBrushSide_t *brushSide = &curTile->brushsides[i]; |
206 | brushSide->planenum = LittleShort(brushSide->planenum)(short)(brushSide->planenum); |
207 | brushSide->texinfo = LittleShort(brushSide->texinfo)(short)(brushSide->texinfo); |
208 | } |
209 | } |
210 | |
211 | static uint32_t CopyLump (const dBspHeader_t *header, int lumpIdx, void *dest, size_t size) |
212 | { |
213 | const lump_t *lump = &header->lumps[lumpIdx]; |
214 | const uint32_t length = lump->filelen; |
215 | const uint32_t ofs = lump->fileofs; |
216 | |
217 | if (length == 0) |
218 | return 0; |
219 | if (length % size) |
220 | Sys_Error("LoadBSPFile: odd lump size"); |
221 | |
222 | memcpy(dest, (const byte *)header + ofs, length); |
223 | |
224 | return length / size; |
225 | } |
226 | |
227 | /** |
228 | * @sa WriteBSPFile |
229 | */ |
230 | dMapTile_t *LoadBSPFile (const char *filename) |
231 | { |
232 | int size; |
233 | unsigned int i; |
234 | dBspHeader_t *header; |
235 | |
236 | /* Create this shortcut to mapTiles[0] */ |
237 | curTile = &mapTiles.mapTiles[0]; |
238 | /* Set the number of tiles to 1. */ |
239 | mapTiles.numTiles = 1; |
240 | |
241 | /* load the file header */ |
242 | size = FS_LoadFile(filename, (byte **)&header); |
243 | if (size == -1) |
244 | Sys_Error("'%s' doesn't exist", filename); |
245 | |
246 | /* swap the header */ |
247 | BSP_SwapHeader(header, filename){ unsigned int i; (header)->ident = (int)((header)->ident ); (header)->version = (int)((header)->version); for (i = 0; i < 17; i++) { lump_t *l = &(header)->lumps[i ]; l->filelen = (int)(l->filelen); l->fileofs = (int )(l->fileofs); if (l->fileofs == (uint32_t) -1) Sys_Error ("Invalid bsp header found (lump overflow %i): '%s'", i, (filename )); } }; |
248 | |
249 | if (header->ident != IDBSPHEADER(('P'<<24)+('S'<<16)+('B'<<8)+'I')) |
250 | Sys_Error("%s is not a IBSP file", filename); |
251 | if (header->version != BSPVERSION78) |
252 | Sys_Error("%s is version %i, not %i", filename, header->version, BSPVERSION78); |
253 | |
254 | curTile->nummodels = CopyLump(header, LUMP_MODELS13, curTile->models, sizeof(dBspModel_t)); |
255 | curTile->numvertexes = CopyLump(header, LUMP_VERTEXES2, curTile->vertexes, sizeof(dBspVertex_t)); |
256 | curTile->numplanes = CopyLump(header, LUMP_PLANES1, curTile->planes, sizeof(dBspPlane_t)); |
257 | curTile->numleafs = CopyLump(header, LUMP_LEAFS9, curTile->leafs, sizeof(dBspLeaf_t)); |
258 | curTile->numnormals = CopyLump(header, LUMP_NORMALS16, curTile->normals, sizeof(dBspNormal_t)); |
259 | curTile->numnodes = CopyLump(header, LUMP_NODES4, curTile->nodes, sizeof(dBspNode_t)); |
260 | curTile->numtexinfo = CopyLump(header, LUMP_TEXINFO5, curTile->texinfo, sizeof(dBspTexinfo_t)); |
261 | curTile->numfaces = CopyLump(header, LUMP_FACES6, curTile->faces, sizeof(dBspSurface_t)); |
262 | curTile->numleafbrushes = CopyLump(header, LUMP_LEAFBRUSHES10, curTile->leafbrushes, sizeof(curTile->leafbrushes[0])); |
263 | curTile->numsurfedges = CopyLump(header, LUMP_SURFEDGES12, curTile->surfedges, sizeof(curTile->surfedges[0])); |
264 | curTile->numedges = CopyLump(header, LUMP_EDGES11, curTile->edges, sizeof(dBspEdge_t)); |
265 | curTile->numbrushes = CopyLump(header, LUMP_BRUSHES14, curTile->dbrushes, sizeof(dBspBrush_t)); |
266 | curTile->numbrushsides = CopyLump(header, LUMP_BRUSHSIDES15, curTile->brushsides, sizeof(dBspBrushSide_t)); |
267 | curTile->routedatasize = CopyLump(header, LUMP_ROUTING3, curTile->routedata, 1); |
268 | curTile->lightdatasize[LIGHTMAP_NIGHT0] = CopyLump(header, LUMP_LIGHTING_NIGHT7, curTile->lightdata[LIGHTMAP_NIGHT0], 1); |
269 | curTile->lightdatasize[LIGHTMAP_DAY1] = CopyLump(header, LUMP_LIGHTING_DAY8, curTile->lightdata[LIGHTMAP_DAY1], 1); |
270 | curTile->entdatasize = CopyLump(header, LUMP_ENTITIES0, curTile->entdata, 1); |
271 | |
272 | /* Because the tracing functions use cBspBrush_t and not dBspBrush_t, |
273 | * copy data from curTile->dbrushes into curTile->cbrushes */ |
274 | OBJZERO(curTile->brushes)(memset(&((curTile->brushes)), (0), sizeof((curTile-> brushes)))); |
275 | for (i = 0; i < curTile->numbrushes; i++) { |
276 | dBspBrush_t *dbrush = &curTile->dbrushes[i]; |
277 | cBspBrush_t *brush = &curTile->brushes[i]; |
278 | brush->firstbrushside = dbrush->firstbrushside; |
279 | brush->numsides = dbrush->numsides; |
280 | brush->contentFlags = dbrush->contentFlags; |
281 | } |
282 | |
283 | /* everything has been copied out */ |
284 | FS_FreeFile(header); |
285 | |
286 | /* swap everything */ |
287 | SwapBSPFile(); |
288 | |
289 | return curTile; |
290 | } |
291 | |
292 | /** |
293 | * @sa WriteBSPFile |
294 | * @todo Implement this without the ftell stuff - don't write the bsp file twice |
295 | */ |
296 | static void AddLump (qFILE *bspfile, dBspHeader_t *header, int lumpnum, void *data, int len) |
297 | { |
298 | lump_t *lump; |
299 | long offset; |
300 | |
301 | lump = &header->lumps[lumpnum]; |
302 | |
303 | offset = ftell(bspfile->f); |
304 | if (offset == -1) { |
305 | Sys_Error("Overflow in AddLump for lump %i (%s) %s", lumpnum, bspfile->name, strerror(errno(*__error()))); |
306 | } |
307 | lump->fileofs = LittleLong(offset)(int)(offset); |
308 | lump->filelen = LittleLong(len)(int)(len); |
309 | /* 4 byte align */ |
310 | FS_Write(data, (len + 3) &~ 3, bspfile); |
311 | } |
312 | |
313 | /** |
314 | * @brief Swaps the bsp file in place, so it should not be referenced again |
315 | * @sa LoadBSPFile |
316 | */ |
317 | long WriteBSPFile (const char *filename) |
318 | { |
319 | qFILE bspfile; |
320 | dBspHeader_t outheader; |
321 | long size; |
322 | |
323 | OBJZERO(outheader)(memset(&((outheader)), (0), sizeof((outheader)))); |
324 | OBJZERO(bspfile)(memset(&((bspfile)), (0), sizeof((bspfile)))); |
325 | |
326 | SwapBSPFile(); |
327 | |
328 | outheader.ident = LittleLong(IDBSPHEADER)(int)((('P'<<24)+('S'<<16)+('B'<<8)+'I')); |
329 | outheader.version = LittleLong(BSPVERSION)(int)(78); |
330 | |
331 | FS_OpenFile(filename, &bspfile, FILE_WRITE); |
332 | if (!bspfile.f) |
333 | Sys_Error("Could not write bsp file"); |
334 | FS_Write(&outheader, sizeof(outheader), &bspfile); /* overwritten later */ |
335 | |
336 | AddLump(&bspfile, &outheader, LUMP_PLANES1, curTile->planes, curTile->numplanes * sizeof(dBspPlane_t)); |
337 | AddLump(&bspfile, &outheader, LUMP_LEAFS9, curTile->leafs, curTile->numleafs * sizeof(dBspLeaf_t)); |
338 | AddLump(&bspfile, &outheader, LUMP_VERTEXES2, curTile->vertexes, curTile->numvertexes * sizeof(dBspVertex_t)); |
339 | AddLump(&bspfile, &outheader, LUMP_NORMALS16, curTile->normals, curTile->numnormals * sizeof(dBspNormal_t)); |
340 | AddLump(&bspfile, &outheader, LUMP_NODES4, curTile->nodes, curTile->numnodes * sizeof(dBspNode_t)); |
341 | AddLump(&bspfile, &outheader, LUMP_TEXINFO5, curTile->texinfo, curTile->numtexinfo * sizeof(dBspTexinfo_t)); |
342 | AddLump(&bspfile, &outheader, LUMP_FACES6, curTile->faces, curTile->numfaces * sizeof(dBspSurface_t)); |
343 | AddLump(&bspfile, &outheader, LUMP_BRUSHES14, curTile->dbrushes, curTile->numbrushes * sizeof(dBspBrush_t)); |
344 | AddLump(&bspfile, &outheader, LUMP_BRUSHSIDES15, curTile->brushsides, curTile->numbrushsides * sizeof(dBspBrushSide_t)); |
345 | AddLump(&bspfile, &outheader, LUMP_LEAFBRUSHES10, curTile->leafbrushes, curTile->numleafbrushes * sizeof(curTile->leafbrushes[0])); |
346 | AddLump(&bspfile, &outheader, LUMP_SURFEDGES12, curTile->surfedges, curTile->numsurfedges * sizeof(curTile->surfedges[0])); |
347 | AddLump(&bspfile, &outheader, LUMP_EDGES11, curTile->edges, curTile->numedges * sizeof(dBspEdge_t)); |
348 | AddLump(&bspfile, &outheader, LUMP_MODELS13, curTile->models, curTile->nummodels * sizeof(dBspModel_t)); |
349 | AddLump(&bspfile, &outheader, LUMP_LIGHTING_NIGHT7, curTile->lightdata[0], curTile->lightdatasize[0]); |
350 | AddLump(&bspfile, &outheader, LUMP_LIGHTING_DAY8, curTile->lightdata[1], curTile->lightdatasize[1]); |
351 | AddLump(&bspfile, &outheader, LUMP_ROUTING3, curTile->routedata, curTile->routedatasize); |
352 | AddLump(&bspfile, &outheader, LUMP_ENTITIES0, curTile->entdata, curTile->entdatasize); |
353 | size = ftell(bspfile.f); |
354 | |
355 | fseek(bspfile.f, 0L, SEEK_SET0); |
356 | FS_Write(&outheader, sizeof(outheader), &bspfile); |
357 | FS_CloseFile(&bspfile); |
358 | |
359 | SwapBSPFile(); |
360 | |
361 | return size; |
362 | } |
363 | |
364 | /** |
365 | * @brief Dumps info about current file |
366 | */ |
367 | void PrintBSPFileSizes (void) |
368 | { |
369 | if (!num_entities) |
370 | ParseEntities(); |
371 | |
372 | Com_Printf("amount type size in bytes\n"); |
373 | Com_Printf("================================\n"); |
374 | Com_Printf("%5i models %7i\n", curTile->nummodels, (int)(curTile->nummodels * sizeof(cBspModel_t))); |
375 | Com_Printf("%5i brushes %7i\n", curTile->numbrushes, (int)(curTile->numbrushes * sizeof(dBspBrush_t))); |
376 | Com_Printf("%5i brushsides %7i\n", curTile->numbrushsides, (int)(curTile->numbrushsides * sizeof(dBspBrushSide_t))); |
377 | Com_Printf("%5i planes %7i\n", curTile->numplanes, (int)(curTile->numplanes * sizeof(dBspPlane_t))); |
378 | Com_Printf("%5i texinfo %7i\n", curTile->numtexinfo, (int)(curTile->numtexinfo * sizeof(dBspTexinfo_t))); |
379 | Com_Printf("%5i entdata %7i\n", num_entities, curTile->entdatasize); |
380 | |
381 | Com_Printf("\n"); |
382 | |
383 | Com_Printf("%5i normales %7i\n", curTile->numnormals, (int)(curTile->numnormals * sizeof(dBspNormal_t))); |
384 | Com_Printf("%5i vertexes %7i\n", curTile->numvertexes, (int)(curTile->numvertexes * sizeof(dBspVertex_t))); |
385 | Com_Printf("%5i nodes %7i\n", curTile->numnodes, (int)(curTile->numnodes * sizeof(dBspNode_t))); |
386 | Com_Printf("%5i faces %7i\n", curTile->numfaces, (int)(curTile->numfaces * sizeof(dBspSurface_t))); |
387 | Com_Printf("%5i leafs %7i\n", curTile->numleafs, (int)(curTile->numleafs * sizeof(dBspLeaf_t))); |
388 | Com_Printf("%5i leafbrushes %7i\n", curTile->numleafbrushes, (int)(curTile->numleafbrushes * sizeof(curTile->leafbrushes[0]))); |
389 | Com_Printf("%5i surfedges %7i\n", curTile->numsurfedges, (int)(curTile->numsurfedges * sizeof(curTile->surfedges[0]))); |
390 | Com_Printf("%5i edges %7i\n", curTile->numedges, (int)(curTile->numedges * sizeof(dBspEdge_t))); |
391 | Com_Printf("night lightdata %7i\n", curTile->lightdatasize[0]); |
392 | Com_Printf(" day lightdata %7i\n", curTile->lightdatasize[1]); |
393 | Com_Printf(" routedata %7i\n", curTile->routedatasize); |
394 | } |
395 | |
396 | |
397 | int num_entities; |
398 | entity_t entities[MAX_MAP_ENTITIES2048]; |
399 | |
400 | /** |
401 | * @brief Removes trailing whitespaces from the given string |
402 | * @param[in,out] str The string to clean up |
403 | * @note Whitespaces are converted to \\0 |
404 | */ |
405 | static void StripTrailingWhitespaces (char *str) |
406 | { |
407 | char *s; |
408 | |
409 | s = str + strlen(str) - 1; |
410 | while (s >= str && *s <= ' ') { |
411 | *s = '\0'; |
412 | s--; |
413 | } |
414 | } |
415 | |
416 | /** |
417 | * @brief Parses one key and value for an entity from the current tokens |
418 | * @sa parsedToken |
419 | * @sa GetToken |
420 | * @sa ParseEntity |
421 | * @sa ParseMapEntity |
422 | */ |
423 | epair_t *ParseEpair (void) |
424 | { |
425 | epair_t *e; |
426 | |
427 | e = Mem_AllocType(epair_t)((epair_t*)_Mem_Alloc(((sizeof(epair_t))),true,(com_genericPool ),(0),"src/tools/ufo2map/common/bspfile.cpp",427)); |
428 | |
429 | if (strlen(parsedToken) >= MAX_KEY32 - 1) |
430 | Sys_Error("ParseEpar: token too long"); |
431 | e->key = Mem_StrDup(parsedToken)_Mem_PoolStrDup((parsedToken),com_genericPool,0,"src/tools/ufo2map/common/bspfile.cpp" ,431); |
432 | GetToken(false); |
433 | if (strlen(parsedToken) >= MAX_VALUE1024 - 1) |
434 | Sys_Error("ParseEpar: token too long"); |
435 | e->value = Mem_StrDup(parsedToken)_Mem_PoolStrDup((parsedToken),com_genericPool,0,"src/tools/ufo2map/common/bspfile.cpp" ,435); |
436 | |
437 | /* strip trailing spaces */ |
438 | StripTrailingWhitespaces(e->key); |
439 | StripTrailingWhitespaces(e->value); |
440 | |
441 | return e; |
442 | } |
443 | |
444 | |
445 | /** |
446 | * @sa ParseEntities |
447 | */ |
448 | static entity_t* ParseEntity (void) |
449 | { |
450 | entity_t *mapent; |
451 | |
452 | if (!GetToken(true)) |
453 | return NULL__null; |
454 | |
455 | if (parsedToken[0] != '{') |
456 | Sys_Error("ParseEntity: { not found"); |
457 | |
458 | if (num_entities >= MAX_MAP_ENTITIES2048) |
459 | Sys_Error("num_entities >= MAX_MAP_ENTITIES (%i)", num_entities); |
460 | |
461 | mapent = &entities[num_entities]; |
462 | num_entities++; |
463 | |
464 | do { |
465 | if (!GetToken(true)) |
466 | Sys_Error("ParseEntity: EOF without closing brace"); |
467 | if (*parsedToken == '}') { |
468 | break; |
469 | } else { |
470 | epair_t *e = ParseEpair(); |
471 | e->next = mapent->epairs; |
472 | mapent->epairs = e; |
473 | } |
474 | } while (1); |
475 | |
476 | return mapent; |
477 | } |
478 | |
479 | /** |
480 | * @brief Parses the curTile->entdata string into entities |
481 | * @sa UnparseEntities |
482 | * @sa ParseEntity |
483 | */ |
484 | void ParseEntities (void) |
485 | { |
486 | num_entities = 0; |
487 | ParseFromMemory(curTile->entdata, curTile->entdatasize); |
488 | |
489 | while (ParseEntity() != NULL__null) { |
490 | } |
491 | } |
492 | |
493 | |
494 | /** |
495 | * @brief Generates the curTile->entdata string from all the entities |
496 | * @sa ParseEntities |
497 | */ |
498 | const char *UnparseEntities (void) |
499 | { |
500 | char line[2048], key[1024], value[1024]; |
501 | int i; |
502 | |
503 | curTile->entdata[0] = '\0'; |
504 | |
505 | for (i = 0; i < num_entities; i++) { |
506 | const epair_t *ep = entities[i].epairs; |
507 | if (!ep) |
508 | continue; /* ent got removed */ |
509 | |
510 | Q_strcat(curTile->entdata, "{\n", sizeof(curTile->entdata)); |
511 | |
512 | for (ep = entities[i].epairs; ep; ep = ep->next) { |
513 | Q_strncpyz(key, ep->key, sizeof(key))Q_strncpyzDebug( key, ep->key, sizeof(key), "src/tools/ufo2map/common/bspfile.cpp" , 513 ); |
514 | StripTrailingWhitespaces(key); |
515 | Q_strncpyz(value, ep->value, sizeof(value))Q_strncpyzDebug( value, ep->value, sizeof(value), "src/tools/ufo2map/common/bspfile.cpp" , 515 ); |
516 | StripTrailingWhitespaces(value); |
517 | |
518 | Com_sprintf(line, sizeof(line), "\"%s\" \"%s\"\n", key, value); |
519 | Q_strcat(curTile->entdata, line, sizeof(curTile->entdata)); |
520 | } |
521 | Q_strcat(curTile->entdata, "}\n", sizeof(curTile->entdata)); |
522 | } |
523 | curTile->entdatasize = strlen(curTile->entdata); |
524 | |
525 | return curTile->entdata; |
526 | } |
527 | |
528 | void SetKeyValue (entity_t *ent, const char *key, const char *value) |
529 | { |
530 | epair_t *ep; |
531 | |
532 | for (ep = ent->epairs; ep; ep = ep->next) |
533 | if (Q_streq(ep->key, key)(strcmp(ep->key, key) == 0)) { |
534 | Mem_Free(ep->value)_Mem_Free((ep->value),"src/tools/ufo2map/common/bspfile.cpp" ,534); |
535 | ep->value = Mem_StrDup(value)_Mem_PoolStrDup((value),com_genericPool,0,"src/tools/ufo2map/common/bspfile.cpp" ,535); |
536 | return; |
537 | } |
538 | ep = Mem_AllocType(epair_t)((epair_t*)_Mem_Alloc(((sizeof(epair_t))),true,(com_genericPool ),(0),"src/tools/ufo2map/common/bspfile.cpp",538)); |
539 | ep->next = ent->epairs; |
540 | ent->epairs = ep; |
541 | ep->key = Mem_StrDup(key)_Mem_PoolStrDup((key),com_genericPool,0,"src/tools/ufo2map/common/bspfile.cpp" ,541); |
542 | ep->value = Mem_StrDup(value)_Mem_PoolStrDup((value),com_genericPool,0,"src/tools/ufo2map/common/bspfile.cpp" ,542); |
543 | } |
544 | |
545 | const char *ValueForKey (const entity_t *ent, const char *key) |
546 | { |
547 | const epair_t *ep; |
548 | |
549 | for (ep = ent->epairs; ep; ep = ep->next) |
550 | if (Q_streq(ep->key, key)(strcmp(ep->key, key) == 0)) |
551 | return ep->value; |
552 | return ""; |
553 | } |
554 | |
555 | vec_t FloatForKey (const entity_t *ent, const char *key) |
556 | { |
557 | const char *k; |
558 | |
559 | k = ValueForKey(ent, key); |
560 | return atof(k); |
561 | } |
562 | |
563 | /** |
564 | * @brief Converts a string into a @c vec3_t |
565 | */ |
566 | void GetVectorFromString (const char *value, vec3_t vec) |
567 | { |
568 | if (value[0] != '\0') { |
569 | double v1, v2, v3; |
570 | |
571 | /* scanf into doubles, then assign, so it is vec_t size independent */ |
572 | v1 = v2 = v3 = 0; |
573 | if (sscanf(value, "%lf %lf %lf", &v1, &v2, &v3) != 3) |
574 | Sys_Error("invalid vector statement given: '%s'", value); |
575 | VectorSet(vec, v1, v2, v3)((vec)[0]=(v1), (vec)[1]=(v2), (vec)[2]=(v3)); |
576 | } else |
577 | VectorClear(vec)((vec)[0]=(vec)[1]=(vec)[2]=0); |
578 | } |
579 | |
580 | /** |
581 | * @brief Converts the value of a entity parameter into a @c vec3_t |
582 | */ |
583 | void GetVectorForKey (const entity_t *ent, const char *key, vec3_t vec) |
584 | { |
585 | const char *k = ValueForKey(ent, key); |
586 | GetVectorFromString(k, vec); |
587 | } |