~ubuntu-branches/ubuntu/precise/glbsp/precise

« back to all changes in this revision

Viewing changes to nodeview/level.cc

  • Committer: Bazaar Package Importer
  • Author(s): Darren Salt
  • Date: 2008-01-30 13:33:49 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20080130133349-kgojg33vyiu8xbvp
Tags: 2.24-1
* New upstream release.
* Bumped the lib soname and the library package name due to one silly
  little binary incompatibility caused by changes in an exported struct.
  (Safe; nothing else currently in the archive has ever used libglbsp2.)
* Removed my patches since they're all applied upstream.
* Updated the list of documentation files.
* Build-time changes:
  - Switched from dh_movefiles to dh_install.
  - Updated my makefile to cope with upstream changes.
  - Corrected for debian-rules-ignores-make-clean-error.
  - Corrected for substvar-source-version-is-deprecated.
  - Link libglbsp, rather than glbsp, with libm and libz.
* Fixed shlibdeps. (Closes: #460387)
* Bumped standards version to 3.7.3 (no other changes).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//------------------------------------------------------------------------
 
2
//  LEVEL : Level structure read/write functions.
 
3
//------------------------------------------------------------------------
 
4
//
 
5
//  GL-Node Viewer (C) 2004-2007 Andrew Apted
 
6
//
 
7
//  This program is free software; you can redistribute it and/or
 
8
//  modify it under the terms of the GNU General Public License
 
9
//  as published by the Free Software Foundation; either version 2
 
10
//  of the License, or (at your option) any later version.
 
11
//
 
12
//  This program is distributed in the hope that it will be useful,
 
13
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
//  GNU General Public License for more details.
 
16
//
 
17
//------------------------------------------------------------------------
 
18
 
 
19
// this includes everything we need
 
20
#include "defs.h"
 
21
 
 
22
#define DEBUG_LOAD      0
 
23
#define DEBUG_BSP       0
 
24
 
 
25
 
 
26
// per-level variables
 
27
 
 
28
bool lev_doing_hexen;
 
29
 
 
30
 
 
31
#define LEVELARRAY(TYPE, BASEVAR, NAMESTR)  \
 
32
    container_tp<TYPE> BASEVAR(NAMESTR);
 
33
 
 
34
LEVELARRAY(vertex_c,  lev_vertices, "vertex")
 
35
LEVELARRAY(vertex_c,  lev_gl_verts, "gl_vert")
 
36
LEVELARRAY(linedef_c, lev_linedefs, "linedef")
 
37
LEVELARRAY(sidedef_c, lev_sidedefs, "sidedef")
 
38
LEVELARRAY(sector_c,  lev_sectors,  "sector")
 
39
LEVELARRAY(thing_c,   lev_things,   "thing")
 
40
LEVELARRAY(seg_c,     lev_segs,     "seg")
 
41
LEVELARRAY(subsec_c,  lev_subsecs,  "subsector")
 
42
LEVELARRAY(node_c,    lev_nodes,    "node")
 
43
 
 
44
 
 
45
/* ----- reading routines ------------------------------ */
 
46
 
 
47
static const uint8_g *lev_v2_magic = (uint8_g *)"gNd2";
 
48
static const uint8_g *lev_v3_magic = (uint8_g *)"gNd3";
 
49
 
 
50
// forward decls
 
51
void GetLinedefsHexen(wad_c *base);
 
52
void GetThingsHexen(wad_c *base);
 
53
 
 
54
vertex_c::vertex_c(int _idx, const raw_vertex_t *raw)
 
55
{
 
56
  index = _idx;
 
57
 
 
58
  x = (double) SINT16(raw->x);
 
59
  y = (double) SINT16(raw->y);
 
60
}
 
61
 
 
62
vertex_c::vertex_c(int _idx, const raw_v2_vertex_t *raw)
 
63
{
 
64
  index = _idx;
 
65
 
 
66
  x = (double) SINT32(raw->x) / 65536.0;
 
67
  y = (double) SINT32(raw->y) / 65536.0;
 
68
}
 
69
 
 
70
vertex_c::~vertex_c()
 
71
{
 
72
}
 
73
 
 
74
//
 
75
// GetVertices
 
76
//
 
77
void GetVertices(wad_c *base)
 
78
{
 
79
  lump_c *lump = base->FindLumpInLevel("VERTEXES");
 
80
  int count = -1;
 
81
 
 
82
  if (lump)
 
83
  {
 
84
    base->CacheLump(lump);
 
85
    count = lump->length / sizeof(raw_vertex_t);
 
86
  }
 
87
 
 
88
# if DEBUG_LOAD
 
89
  PrintDebug("GetVertices: num = %d\n", count);
 
90
# endif
 
91
 
 
92
  if (!lump || count == 0)
 
93
    FatalError("Couldn't find any Vertices");
 
94
 
 
95
  lev_vertices.Allocate(count);
 
96
 
 
97
  raw_vertex_t *raw = (raw_vertex_t *) lump->data;
 
98
 
 
99
  for (int i = 0; i < count; i++, raw++)
 
100
  {
 
101
    lev_vertices.Set(i, new vertex_c(i, raw));
 
102
  }
 
103
}
 
104
 
 
105
//
 
106
// GetV2Verts
 
107
//
 
108
void GetV2Verts(const uint8_g *data, int length)
 
109
{
 
110
  int count = length / sizeof(raw_v2_vertex_t);
 
111
 
 
112
  lev_gl_verts.Allocate(count);
 
113
 
 
114
  raw_v2_vertex_t *raw = (raw_v2_vertex_t *) data;
 
115
 
 
116
  for (int i = 0; i < count; i++, raw++)
 
117
  {
 
118
    lev_gl_verts.Set(i, new vertex_c(i, raw));
 
119
  }
 
120
}
 
121
 
 
122
//
 
123
// GetGLVerts
 
124
//
 
125
void GetGLVerts(wad_c *base)
 
126
{
 
127
  lump_c *lump = base->FindLumpInLevel("GL_VERT");
 
128
 
 
129
# if DEBUG_LOAD
 
130
  PrintDebug("GetVertices: num = %d\n", count);
 
131
# endif
 
132
 
 
133
  if (!lump)
 
134
    FatalError("Couldn't find any GL Vertices");
 
135
 
 
136
  base->CacheLump(lump);
 
137
 
 
138
  if (lump->length >= 4 && memcmp(lump->data, lev_v2_magic, 4) == 0)
 
139
  {
 
140
    GetV2Verts((uint8_g *)lump->data + 4, lump->length - 4);
 
141
    return;
 
142
  }
 
143
 
 
144
  int count = lump->length / sizeof(raw_vertex_t);
 
145
 
 
146
  lev_gl_verts.Allocate(count);
 
147
 
 
148
  raw_vertex_t *raw = (raw_vertex_t *) lump->data;
 
149
 
 
150
  for (int i = 0; i < count; i++, raw++)
 
151
  {
 
152
    lev_gl_verts.Set(i, new vertex_c(i, raw));
 
153
  }
 
154
}
 
155
 
 
156
sector_c::sector_c(int _idx, const raw_sector_t *raw)
 
157
{
 
158
  index = _idx;
 
159
 
 
160
  floor_h = SINT16(raw->floor_h);
 
161
  ceil_h  = SINT16(raw->ceil_h);
 
162
 
 
163
  memcpy(floor_tex, raw->floor_tex, sizeof(floor_tex));
 
164
  memcpy(ceil_tex,  raw->ceil_tex,  sizeof(ceil_tex));
 
165
 
 
166
  light   = UINT16(raw->light);
 
167
  special = UINT16(raw->special);
 
168
  tag     = SINT16(raw->tag);
 
169
}
 
170
 
 
171
sector_c::~sector_c()
 
172
{
 
173
}
 
174
 
 
175
//
 
176
// GetSectors
 
177
//
 
178
void GetSectors(wad_c *base)
 
179
{
 
180
  int count = -1;
 
181
  lump_c *lump = base->FindLumpInLevel("SECTORS");
 
182
 
 
183
  if (lump)
 
184
  {
 
185
    base->CacheLump(lump);
 
186
    count = lump->length / sizeof(raw_sector_t);
 
187
  }
 
188
 
 
189
  if (!lump || count == 0)
 
190
    FatalError("Couldn't find any Sectors");
 
191
 
 
192
# if DEBUG_LOAD
 
193
  PrintDebug("GetSectors: num = %d\n", count);
 
194
# endif
 
195
 
 
196
  lev_sectors.Allocate(count);
 
197
 
 
198
  raw_sector_t *raw = (raw_sector_t *) lump->data;
 
199
 
 
200
  for (int i = 0; i < count; i++, raw++)
 
201
  {
 
202
    lev_sectors.Set(i, new sector_c(i, raw));
 
203
  }
 
204
}
 
205
 
 
206
thing_c::thing_c(int _idx, const raw_thing_t *raw)
 
207
{
 
208
  index = _idx;
 
209
 
 
210
  x = SINT16(raw->x);
 
211
  y = SINT16(raw->y);
 
212
 
 
213
  type    = UINT16(raw->type);
 
214
  options = UINT16(raw->options);
 
215
}
 
216
 
 
217
thing_c::thing_c(int _idx, const raw_hexen_thing_t *raw)
 
218
{
 
219
  index = _idx;
 
220
 
 
221
  x = SINT16(raw->x);
 
222
  y = SINT16(raw->y);
 
223
 
 
224
  type    = UINT16(raw->type);
 
225
  options = UINT16(raw->options);
 
226
}
 
227
 
 
228
thing_c::~thing_c()
 
229
{
 
230
}
 
231
 
 
232
//
 
233
// GetThings
 
234
//
 
235
void GetThings(wad_c *base)
 
236
{
 
237
  if (lev_doing_hexen)
 
238
  {
 
239
    GetThingsHexen(base);
 
240
    return;
 
241
  }
 
242
  
 
243
  int count = -1;
 
244
  lump_c *lump = base->FindLumpInLevel("THINGS");
 
245
 
 
246
  if (lump)
 
247
  {
 
248
    base->CacheLump(lump);
 
249
    count = lump->length / sizeof(raw_thing_t);
 
250
  }
 
251
 
 
252
  if (!lump || count == 0)
 
253
  {
 
254
    // Note: no error if no things exist, even though technically a map
 
255
    // will be unplayable without the player starts.
 
256
    PrintWarn("Couldn't find any Things");
 
257
    return;
 
258
  }
 
259
 
 
260
# if DEBUG_LOAD
 
261
  PrintDebug("GetThings: num = %d\n", count);
 
262
# endif
 
263
 
 
264
  lev_things.Allocate(count);
 
265
 
 
266
  raw_thing_t *raw = (raw_thing_t *) lump->data;
 
267
 
 
268
  for (int i = 0; i < count; i++, raw++)
 
269
  {
 
270
    lev_things.Set(i, new thing_c(i, raw));
 
271
  }
 
272
}
 
273
 
 
274
//
 
275
// GetThingsHexen
 
276
//
 
277
void GetThingsHexen(wad_c *base)
 
278
{
 
279
  int count = -1;
 
280
  lump_c *lump = base->FindLumpInLevel("THINGS");
 
281
 
 
282
  if (lump)
 
283
  {
 
284
    base->CacheLump(lump);
 
285
    count = lump->length / sizeof(raw_hexen_thing_t);
 
286
  }
 
287
 
 
288
  if (!lump || count == 0)
 
289
  {
 
290
    // Note: no error if no things exist, even though technically a map
 
291
    // will be unplayable without the player starts.
 
292
    PrintWarn("Couldn't find any Things");
 
293
    return;
 
294
  }
 
295
 
 
296
# if DEBUG_LOAD
 
297
  PrintDebug("GetThingsHexen: num = %d\n", count);
 
298
# endif
 
299
 
 
300
  lev_things.Allocate(count);
 
301
 
 
302
  raw_hexen_thing_t *raw = (raw_hexen_thing_t *) lump->data;
 
303
 
 
304
  for (int i = 0; i < count; i++, raw++)
 
305
  {
 
306
    lev_things.Set(i, new thing_c(i, raw));
 
307
  }
 
308
}
 
309
 
 
310
sidedef_c::sidedef_c(int _idx, const raw_sidedef_t *raw)
 
311
{
 
312
  index = _idx;
 
313
 
 
314
  sector = (SINT16(raw->sector) == -1) ? NULL :
 
315
    lev_sectors.Get(UINT16(raw->sector));
 
316
 
 
317
  x_offset = SINT16(raw->x_offset);
 
318
  y_offset = SINT16(raw->y_offset);
 
319
 
 
320
  memcpy(upper_tex, raw->upper_tex, sizeof(upper_tex));
 
321
  memcpy(lower_tex, raw->lower_tex, sizeof(lower_tex));
 
322
  memcpy(mid_tex,   raw->mid_tex,   sizeof(mid_tex));
 
323
}
 
324
 
 
325
sidedef_c::~sidedef_c()
 
326
{
 
327
}
 
328
 
 
329
//
 
330
// GetSidedefs
 
331
//
 
332
void GetSidedefs(wad_c *base)
 
333
{
 
334
  int count = -1;
 
335
  lump_c *lump = base->FindLumpInLevel("SIDEDEFS");
 
336
 
 
337
  if (lump)
 
338
  {
 
339
    base->CacheLump(lump);
 
340
    count = lump->length / sizeof(raw_sidedef_t);
 
341
  }
 
342
 
 
343
  if (!lump || count == 0)
 
344
    FatalError("Couldn't find any Sidedefs");
 
345
 
 
346
# if DEBUG_LOAD
 
347
  PrintDebug("GetSidedefs: num = %d\n", count);
 
348
# endif
 
349
 
 
350
  lev_sidedefs.Allocate(count);
 
351
 
 
352
  raw_sidedef_t *raw = (raw_sidedef_t *) lump->data;
 
353
 
 
354
  for (int i = 0; i < count; i++, raw++)
 
355
  {
 
356
    lev_sidedefs.Set(i, new sidedef_c(i, raw));
 
357
  }
 
358
}
 
359
 
 
360
static sidedef_c *SafeLookupSidedef(uint16_g num)
 
361
{
 
362
  if (num == 0xFFFF)
 
363
    return NULL;
 
364
 
 
365
  if ((int)num >= lev_sidedefs.num && (sint16_g)(num) < 0)
 
366
    return NULL;
 
367
 
 
368
  return lev_sidedefs.Get(num);
 
369
}
 
370
 
 
371
linedef_c::linedef_c(int _idx, const raw_linedef_t *raw)
 
372
{
 
373
  index = _idx;
 
374
 
 
375
  start = lev_vertices.Get(UINT16(raw->start));
 
376
  end   = lev_vertices.Get(UINT16(raw->end));
 
377
 
 
378
  /* check for zero-length line */
 
379
  zero_len = (fabs(start->x - end->x) < DIST_EPSILON) && 
 
380
         (fabs(start->y - end->y) < DIST_EPSILON);
 
381
 
 
382
  flags = UINT16(raw->flags);
 
383
  type  = UINT16(raw->type);
 
384
  tag   = SINT16(raw->tag);
 
385
 
 
386
  two_sided = (flags & LINEFLAG_TWO_SIDED) ? true : false;
 
387
 
 
388
  right = SafeLookupSidedef(UINT16(raw->sidedef1));
 
389
  left  = SafeLookupSidedef(UINT16(raw->sidedef2));
 
390
}
 
391
 
 
392
linedef_c::linedef_c(int _idx, const raw_hexen_linedef_t *raw)
 
393
{
 
394
  index = _idx;
 
395
 
 
396
  start = lev_vertices.Get(UINT16(raw->start));
 
397
  end   = lev_vertices.Get(UINT16(raw->end));
 
398
 
 
399
  // check for zero-length line
 
400
  zero_len = (fabs(start->x - end->x) < DIST_EPSILON) && 
 
401
             (fabs(start->y - end->y) < DIST_EPSILON);
 
402
 
 
403
  flags = UINT16(raw->flags);
 
404
  type  = UINT8(raw->type);
 
405
  tag   = 0;
 
406
 
 
407
  /* read specials */
 
408
  for (int j = 0; j < 5; j++)
 
409
    specials[j] = UINT8(raw->specials[j]);
 
410
 
 
411
  // -JL- Added missing twosided flag handling that caused a broken reject
 
412
  two_sided = (flags & LINEFLAG_TWO_SIDED) ? true : false;
 
413
 
 
414
  right = SafeLookupSidedef(UINT16(raw->sidedef1));
 
415
  left  = SafeLookupSidedef(UINT16(raw->sidedef2));
 
416
}
 
417
 
 
418
linedef_c::~linedef_c()
 
419
{
 
420
}
 
421
 
 
422
//
 
423
// GetLinedefs
 
424
//
 
425
void GetLinedefs(wad_c *base)
 
426
{
 
427
  if (lev_doing_hexen)
 
428
  {
 
429
    GetLinedefsHexen(base);
 
430
    return;
 
431
  }
 
432
  
 
433
  int count = -1;
 
434
  lump_c *lump = base->FindLumpInLevel("LINEDEFS");
 
435
 
 
436
  if (lump)
 
437
  {
 
438
    base->CacheLump(lump);
 
439
    count = lump->length / sizeof(raw_linedef_t);
 
440
  }
 
441
 
 
442
  if (!lump || count == 0)
 
443
    FatalError("Couldn't find any Linedefs");
 
444
 
 
445
# if DEBUG_LOAD
 
446
  PrintDebug("GetLinedefs: num = %d\n", count);
 
447
# endif
 
448
 
 
449
  lev_linedefs.Allocate(count);
 
450
 
 
451
  raw_linedef_t *raw = (raw_linedef_t *) lump->data;
 
452
 
 
453
  for (int i = 0; i < count; i++, raw++)
 
454
  {
 
455
    lev_linedefs.Set(i, new linedef_c(i, raw));
 
456
  }
 
457
}
 
458
 
 
459
//
 
460
// GetLinedefsHexen
 
461
//
 
462
void GetLinedefsHexen(wad_c *base)
 
463
{
 
464
  int count = -1;
 
465
  lump_c *lump = base->FindLumpInLevel("LINEDEFS");
 
466
 
 
467
  if (lump)
 
468
  {
 
469
    base->CacheLump(lump);
 
470
    count = lump->length / sizeof(raw_hexen_linedef_t);
 
471
  }
 
472
 
 
473
  if (!lump || count == 0)
 
474
    FatalError("Couldn't find any Linedefs");
 
475
 
 
476
# if DEBUG_LOAD
 
477
  PrintDebug("GetLinedefsHexen: num = %d\n", count);
 
478
# endif
 
479
 
 
480
  lev_linedefs.Allocate(count);
 
481
 
 
482
  raw_hexen_linedef_t *raw = (raw_hexen_linedef_t *) lump->data;
 
483
 
 
484
  for (int i = 0; i < count; i++, raw++)
 
485
  {
 
486
    lev_linedefs.Set(i, new linedef_c(i, raw));
 
487
  }
 
488
}
 
489
 
 
490
static vertex_c *FindVertex16(uint16_g index)
 
491
{
 
492
  if (index & 0x8000)
 
493
    return lev_gl_verts.Get(index & 0x7FFF);
 
494
 
 
495
  return lev_vertices.Get(index);
 
496
}
 
497
 
 
498
static vertex_c *FindVertex32(int index)
 
499
{
 
500
  if (index & IS_GL_VERTEX)
 
501
    return lev_gl_verts.Get(index & ~IS_GL_VERTEX);
 
502
 
 
503
  return lev_vertices.Get(index);
 
504
}
 
505
 
 
506
seg_c::seg_c(int _idx, const raw_gl_seg_t *raw)
 
507
{
 
508
  index = _idx;
 
509
 
 
510
  next = NULL;
 
511
 
 
512
/// fprintf(stderr, "SEG %d  V %d..%d line %d side %d\n",
 
513
/// index, UINT16(raw->start), UINT16(raw->end), SINT16(raw->linedef), SINT16(raw->side));
 
514
 
 
515
  start = FindVertex16(UINT16(raw->start));
 
516
  end   = FindVertex16(UINT16(raw->end));
 
517
 
 
518
  linedef = (SINT16(raw->linedef) == -1) ? NULL :
 
519
    lev_linedefs.Get(UINT16(raw->linedef));
 
520
 
 
521
  side = UINT16(raw->side);
 
522
 
 
523
  sidedef_c *sss = NULL;
 
524
 
 
525
  if (linedef)
 
526
    sss = side ? linedef->left : linedef->right;
 
527
  
 
528
  sector = sss ? sss->sector : NULL;
 
529
 
 
530
  // partner is currently ignored
 
531
 
 
532
  precompute_data();
 
533
}
 
534
 
 
535
seg_c::seg_c(int _idx, const raw_v3_seg_t *raw)
 
536
{
 
537
  index = _idx;
 
538
 
 
539
  next = NULL;
 
540
 
 
541
  start = FindVertex32(UINT32(raw->start));
 
542
  end   = FindVertex32(UINT32(raw->end));
 
543
 
 
544
  linedef = (SINT16(raw->linedef) == -1) ? NULL :
 
545
    lev_linedefs.Get(UINT16(raw->linedef));
 
546
 
 
547
  side = UINT16(raw->flags) & V3SEG_F_LEFT;
 
548
 
 
549
  sidedef_c *sss = NULL;
 
550
 
 
551
  if (linedef)
 
552
    sss = side ? linedef->left : linedef->right;
 
553
 
 
554
  sector = sss ? sss->sector : NULL;
 
555
 
 
556
  // partner is currently ignored
 
557
 
 
558
  precompute_data();
 
559
}
 
560
 
 
561
seg_c::~seg_c()
 
562
{
 
563
}
 
564
 
 
565
void seg_c::precompute_data()
 
566
{
 
567
  psx = start->x;
 
568
  psy = start->y;
 
569
 
 
570
  pex = end->x;
 
571
  pey = end->y;
 
572
 
 
573
  pdx = pex - psx;
 
574
  pdy = pey - psy;
 
575
 
 
576
  p_length = UtilComputeDist(pdx, pdy);
 
577
  p_angle  = UtilComputeAngle(pdx, pdy);
 
578
 
 
579
/// fprintf(stderr, "|  (%1.0f,%1.0f)->(%1.0f,%1.0f)  Delta (%1.6f, %1.6f)\n",
 
580
/// psx, psy, pex, pey, pdx, pdy);
 
581
 
 
582
  if (p_length <= 0)
 
583
    PrintWarn("Seg %d has zero p_length.\n", index);
 
584
 
 
585
  p_perp =  psy * pdx - psx * pdy;
 
586
  p_para = -psx * pdx - psy * pdy;
 
587
}
 
588
 
 
589
//
 
590
// GetV3Segs
 
591
//
 
592
void GetV3Segs(const uint8_g *data, int length)
 
593
{
 
594
  int count = length / sizeof(raw_v3_seg_t);
 
595
 
 
596
  lev_segs.Allocate(count);
 
597
 
 
598
  raw_v3_seg_t *raw = (raw_v3_seg_t *) data;
 
599
 
 
600
  for (int i = 0; i < count; i++, raw++)
 
601
  {
 
602
    lev_segs.Set(i, new seg_c(i, raw));
 
603
  }
 
604
}
 
605
 
 
606
//
 
607
// GetGLSegs
 
608
//
 
609
void GetGLSegs(wad_c *base)
 
610
{
 
611
  lump_c *lump = base->FindLumpInLevel("GL_SEGS");
 
612
 
 
613
# if DEBUG_LOAD
 
614
  PrintDebug("GetVertices: num = %d\n", count);
 
615
# endif
 
616
 
 
617
  if (!lump)
 
618
    FatalError("Couldn't find any GL Segs");
 
619
 
 
620
  base->CacheLump(lump);
 
621
 
 
622
  if (lump->length >= 4 && memcmp(lump->data, lev_v3_magic, 4) == 0)
 
623
  {
 
624
    GetV3Segs((uint8_g *)lump->data + 4, lump->length - 4);
 
625
    return;
 
626
  }
 
627
 
 
628
  int count = lump->length / sizeof(raw_gl_seg_t);
 
629
 
 
630
  lev_segs.Allocate(count);
 
631
 
 
632
  raw_gl_seg_t *raw = (raw_gl_seg_t *) lump->data;
 
633
 
 
634
  for (int i = 0; i < count; i++, raw++)
 
635
  {
 
636
    lev_segs.Set(i, new seg_c(i, raw));
 
637
  }
 
638
}
 
639
 
 
640
 
 
641
subsec_c::subsec_c(int _idx, const raw_subsec_t *raw)
 
642
{
 
643
  index = _idx;
 
644
 
 
645
  seg_count = UINT16(raw->num);
 
646
  int first = UINT16(raw->first);
 
647
 
 
648
  build_seg_list(first, seg_count);
 
649
}
 
650
 
 
651
subsec_c::subsec_c(int _idx, const raw_v3_subsec_t *raw)
 
652
{
 
653
  index = _idx;
 
654
 
 
655
  seg_count = UINT32(raw->num);
 
656
  int first = UINT32(raw->first);
 
657
 
 
658
  build_seg_list(first, seg_count);
 
659
}
 
660
 
 
661
subsec_c::~subsec_c()
 
662
{
 
663
}
 
664
 
 
665
void subsec_c::append_seg(seg_c *cur)
 
666
{
 
667
  if (! cur)
 
668
    InternalError("Missing seg for subsector !\n");
 
669
 
 
670
  mid_x += (cur->start->x + cur->end->x) / 2.0;
 
671
  mid_y += (cur->start->y + cur->end->y) / 2.0;
 
672
 
 
673
  // add it to the tail
 
674
 
 
675
  if (! seg_list)
 
676
  {
 
677
    seg_list = cur;
 
678
    return;
 
679
  }
 
680
 
 
681
  seg_c *tail = seg_list;
 
682
 
 
683
  while (tail->next)
 
684
    tail = tail->next;
 
685
  
 
686
  tail->next = cur;
 
687
}
 
688
 
 
689
void subsec_c::build_seg_list(int first, int count)
 
690
{
 
691
  seg_list = NULL;
 
692
 
 
693
  mid_x = 0;
 
694
  mid_y = 0;
 
695
 
 
696
  for (; count > 0; first++, count--)
 
697
  {
 
698
    seg_c *seg = lev_segs.Get(first);
 
699
 
 
700
    append_seg(seg);
 
701
  }
 
702
 
 
703
  mid_x /= count;
 
704
  mid_y /= count;
 
705
}
 
706
 
 
707
//
 
708
// GetV3Subsecs
 
709
//
 
710
void GetV3Subsecs(const uint8_g *data, int length)
 
711
{
 
712
  int count = length / sizeof(raw_v3_subsec_t);
 
713
 
 
714
  lev_subsecs.Allocate(count);
 
715
 
 
716
  raw_v3_subsec_t *raw = (raw_v3_subsec_t *) data;
 
717
 
 
718
  for (int i = 0; i < count; i++, raw++)
 
719
  {
 
720
    lev_subsecs.Set(i, new subsec_c(i, raw));
 
721
  }
 
722
}
 
723
 
 
724
//
 
725
// GetGLSubsecs
 
726
//
 
727
void GetGLSubsecs(wad_c *base)
 
728
{
 
729
  lump_c *lump = base->FindLumpInLevel("GL_SSECT");
 
730
 
 
731
# if DEBUG_LOAD
 
732
  PrintDebug("GetVertices: num = %d\n", count);
 
733
# endif
 
734
 
 
735
  if (!lump)
 
736
    FatalError("Couldn't find any GL Subsectors");
 
737
 
 
738
  base->CacheLump(lump);
 
739
 
 
740
  if (lump->length >= 4 && memcmp(lump->data, lev_v3_magic, 4) == 0)
 
741
  {
 
742
    GetV3Subsecs((uint8_g *)lump->data + 4, lump->length - 4);
 
743
    return;
 
744
  }
 
745
 
 
746
  int count = lump->length / sizeof(raw_subsec_t);
 
747
 
 
748
  lev_subsecs.Allocate(count);
 
749
 
 
750
  raw_subsec_t *raw = (raw_subsec_t *) lump->data;
 
751
 
 
752
  for (int i = 0; i < count; i++, raw++)
 
753
  {
 
754
    lev_subsecs.Set(i, new subsec_c(i, raw));
 
755
  }
 
756
}
 
757
 
 
758
void bbox_t::from_raw(const raw_bbox_t *raw)
 
759
{
 
760
  minx = SINT16(raw->minx);
 
761
  miny = SINT16(raw->miny);
 
762
  maxx = SINT16(raw->maxx);
 
763
  maxy = SINT16(raw->maxy);
 
764
}
 
765
 
 
766
node_c::node_c(int _idx, const raw_node_t *raw)
 
767
{
 
768
  index = _idx;
 
769
 
 
770
  x  = SINT16(raw->x);
 
771
  y  = SINT16(raw->y);
 
772
  dx = SINT16(raw->dx);
 
773
  dy = SINT16(raw->dy);
 
774
 
 
775
  r.bounds.from_raw(&raw->b1);
 
776
  l.bounds.from_raw(&raw->b2);
 
777
 
 
778
  r.node = l.node = NULL;
 
779
  r.subsec = l.subsec = NULL;
 
780
 
 
781
  int r_idx = UINT16(raw->right);
 
782
  int l_idx = UINT16(raw->left);
 
783
 
 
784
  if (r_idx & 0x8000)
 
785
    r.subsec = lev_subsecs.Get(r_idx & 0x7FFF);
 
786
  else
 
787
    r.node = lev_nodes.Get(r_idx);
 
788
 
 
789
  if (l_idx & 0x8000)
 
790
    l.subsec = lev_subsecs.Get(l_idx & 0x7FFF);
 
791
  else
 
792
    l.node = lev_nodes.Get(l_idx);
 
793
}
 
794
 
 
795
node_c::~node_c()
 
796
{
 
797
}
 
798
 
 
799
//
 
800
// GetGLNodes
 
801
//
 
802
void GetGLNodes(wad_c *base)
 
803
{
 
804
  int count = -1;
 
805
  lump_c *lump = base->FindLumpInLevel("GL_NODES");
 
806
 
 
807
  if (lump)
 
808
  {
 
809
    base->CacheLump(lump);
 
810
    count = lump->length / sizeof(raw_node_t);
 
811
  }
 
812
 
 
813
  if (!lump || count < 1)
 
814
    return;
 
815
 
 
816
# if DEBUG_LOAD
 
817
  PrintDebug("GetStaleNodes: num = %d\n", count);
 
818
# endif
 
819
 
 
820
  lev_nodes.Allocate(count);
 
821
 
 
822
  raw_node_t *raw = (raw_node_t *) lump->data;
 
823
 
 
824
  for (int i = 0; i < count; i++, raw++)
 
825
  {
 
826
    lev_nodes.Set(i, new node_c(i, raw));
 
827
  }
 
828
}
 
829
 
 
830
 
 
831
 
 
832
/* ----- whole-level routines --------------------------- */
 
833
 
 
834
//
 
835
// LoadLevel
 
836
//
 
837
void LoadLevel(const char *level_name)
 
838
{
 
839
  // ---- Normal stuff ----
 
840
 
 
841
  if (! the_wad->FindLevel(level_name))
 
842
    FatalError("Unable to find level: %s\n", level_name);
 
843
 
 
844
  // -JL- Identify Hexen mode by presence of BEHAVIOR lump
 
845
  lev_doing_hexen = (the_wad->FindLumpInLevel("BEHAVIOR") != NULL);
 
846
 
 
847
  GetVertices(the_wad);
 
848
  GetSectors(the_wad);
 
849
  GetSidedefs(the_wad);
 
850
  GetLinedefs(the_wad);
 
851
  GetThings(the_wad);
 
852
 
 
853
  // ---- GL stuff ----
 
854
 
 
855
  char gl_name[16];
 
856
  
 
857
  sprintf(gl_name, "GL_%s", the_wad->current_level->name);
 
858
 
 
859
  wad_c *gl_wad = the_wad;
 
860
 
 
861
  if (! gl_wad->FindLevel(gl_name))
 
862
  {
 
863
    gl_wad = the_gwa;
 
864
 
 
865
    if (! gl_wad || ! gl_wad->FindLevel(gl_name))
 
866
      FatalError("Unable to find GL info (%s lump)\n", gl_name);
 
867
  }
 
868
 
 
869
  GetGLVerts(gl_wad);
 
870
  GetGLSegs(gl_wad);
 
871
  GetGLSubsecs(gl_wad);
 
872
  GetGLNodes(gl_wad);
 
873
 
 
874
/// PrintMsg("Loaded %d vertices, %d sectors, %d sides, %d lines, %d things\n", 
 
875
///     num_vertices, num_sectors, num_sidedefs, num_linedefs, num_things);
 
876
 
 
877
}
 
878
 
 
879
//
 
880
// FreeLevel
 
881
//
 
882
void FreeLevel(void)
 
883
{
 
884
  lev_vertices.FreeAll();
 
885
  lev_gl_verts.FreeAll();
 
886
  lev_linedefs.FreeAll();
 
887
  lev_sidedefs.FreeAll();
 
888
  lev_sectors.FreeAll();
 
889
  lev_things.FreeAll();
 
890
  lev_segs.FreeAll();
 
891
  lev_subsecs.FreeAll();
 
892
  lev_nodes.FreeAll();
 
893
}
 
894
 
 
895
//
 
896
// LevelGetBounds
 
897
//
 
898
void LevelGetBounds(double *lx, double *ly, double *hx, double *hy)
 
899
{
 
900
  node_c *root = lev_nodes.Get(lev_nodes.num - 1);
 
901
 
 
902
  *lx = MIN(root->l.bounds.minx, root->r.bounds.minx);
 
903
  *ly = MIN(root->l.bounds.miny, root->r.bounds.miny);
 
904
  *hx = MAX(root->l.bounds.maxx, root->r.bounds.maxx);
 
905
  *hy = MAX(root->l.bounds.maxy, root->r.bounds.maxy);
 
906
}