1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339
|
//------------------------------------------------------------------------
// LEVEL : Level structures & read/write functions.
//------------------------------------------------------------------------
//
// GL-Node Viewer (C) 2004-2007 Andrew Apted
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//------------------------------------------------------------------------
#ifndef __NODEVIEW_LEVEL_H__
#define __NODEVIEW_LEVEL_H__
class node_c;
class sector_c;
class vertex_c
{
public:
// coordinates
double x, y;
// vertex index. Always valid after loading and pruning of unused
// vertices has occurred. For GL vertices, bit 30 will be set.
int index;
vertex_c(int _idx, const raw_vertex_t *raw);
vertex_c(int _idx, const raw_v2_vertex_t *raw);
~vertex_c();
};
#define IS_GL_VERTEX (1 << 30)
class sector_c
{
public:
// sector index. Always valid after loading & pruning.
int index;
// heights
int floor_h, ceil_h;
// textures
char floor_tex[8];
char ceil_tex[8];
// attributes
int light;
int special;
int tag;
sector_c(int _idx, const raw_sector_t *raw);
~sector_c();
};
class sidedef_c
{
public:
// adjacent sector. Can be NULL (invalid sidedef)
sector_c *sector;
// offset values
int x_offset, y_offset;
// texture names
char upper_tex[8];
char lower_tex[8];
char mid_tex[8];
// sidedef index. Always valid after loading & pruning.
int index;
sidedef_c(int _idx, const raw_sidedef_t *raw);
~sidedef_c();
};
class linedef_c
{
public:
vertex_c *start; // from this vertex...
vertex_c *end; // ... to this vertex
sidedef_c *right; // right sidedef
sidedef_c *left; // left sidede, or NULL if none
// line is marked two-sided
char two_sided;
// zero length (line should be totally ignored)
char zero_len;
int flags;
int type;
int tag;
// Hexen support
int specials[5];
// linedef index. Always valid after loading & pruning of zero
// length lines has occurred.
int index;
linedef_c(int _idx, const raw_linedef_t *raw);
linedef_c(int _idx, const raw_hexen_linedef_t *raw);
~linedef_c();
};
class thing_c
{
public:
int x, y;
int type;
int options;
// other info (angle, and hexen stuff) omitted. We don't need to
// write the THING lump, only read it.
// Always valid (thing indices never change).
int index;
thing_c(int _idx, const raw_thing_t *raw);
thing_c(int _idx, const raw_hexen_thing_t *raw);
~thing_c();
};
class seg_c
{
public:
// link for list
struct seg_c *next;
vertex_c *start; // from this vertex...
vertex_c *end; // ... to this vertex
// linedef that this seg goes along, or NULL if miniseg
linedef_c *linedef;
// adjacent sector, or NULL if invalid sidedef or miniseg
sector_c *sector;
// 0 for right, 1 for left
int side;
// seg index. Only valid once the seg has been added to a
// subsector. A negative value means it is invalid -- there
// shouldn't be any of these once the BSP tree has been built.
int index;
// precomputed data for faster calculations
double psx, psy;
double pex, pey;
double pdx, pdy;
double p_length, p_angle;
double p_para, p_perp;
seg_c(int _idx, const raw_gl_seg_t *raw);
seg_c(int _idx, const raw_v3_seg_t *raw);
~seg_c();
void precompute_data();
};
class subsec_c
{
public:
// list of segs
seg_c *seg_list;
// count of segs
int seg_count;
// subsector index in lump.
int index;
// approximate middle point
double mid_x;
double mid_y;
subsec_c(int _idx, const raw_subsec_t *raw);
subsec_c(int _idx, const raw_v3_subsec_t *raw);
~subsec_c();
void append_seg(seg_c *cur);
void build_seg_list(int first, int count);
// builds the list of segs, and also determines mid point.
};
typedef struct bbox_s
{
int minx, miny;
int maxx, maxy;
void from_raw(const raw_bbox_t *raw);
}
bbox_t;
typedef struct child_s
{
// child node or subsector (one must be NULL)
node_c *node;
subsec_c *subsec;
// child bounding box
bbox_t bounds;
}
child_t;
class node_c
{
public:
int x, y; // starting point
int dx, dy; // offset to ending point
// right & left children
child_t r;
child_t l;
// node index in lump
int index;
node_c (int _idx, const raw_node_t *raw);
~node_c();
};
/* ----- Level data arrays ----------------------- */
template <typename TYPE> class container_tp
{
public:
int num;
private:
TYPE ** arr;
const char *const name;
public:
container_tp(const char *type_name) : num(0), arr(NULL), name(type_name)
{
}
~container_tp()
{
if (arr)
FreeAll();
}
void Allocate(int _num)
{
if (arr)
FreeAll();
num = _num;
arr = new TYPE* [num];
for (int i = 0; i < num; i++)
{
arr[i] = NULL;
}
}
void FreeAll()
{
for (int i = 0; i < num; i++)
{
if (arr[i] != NULL)
delete arr[i];
}
delete[] arr;
num = 0;
arr = NULL;
}
void Set(int index, TYPE *cur)
{
if (arr[index] != NULL)
delete arr[index];
arr[index] = cur;
}
TYPE *Get(int index)
{
if (index < 0 || index >= num)
{
FatalError("No such %s number #%d", name, index);
}
return arr[index];
}
};
#define EXTERN_LEVELARRAY(TYPE, BASEVAR) \
extern container_tp<TYPE> BASEVAR;
EXTERN_LEVELARRAY(vertex_c, lev_vertices)
EXTERN_LEVELARRAY(vertex_c, lev_gl_verts)
EXTERN_LEVELARRAY(linedef_c, lev_linedefs)
EXTERN_LEVELARRAY(sidedef_c, lev_sidedefs)
EXTERN_LEVELARRAY(sector_c, lev_sectors)
EXTERN_LEVELARRAY(thing_c, lev_things)
EXTERN_LEVELARRAY(seg_c, lev_segs)
EXTERN_LEVELARRAY(subsec_c, lev_subsecs)
EXTERN_LEVELARRAY(node_c, lev_nodes)
/* ----- function prototypes ----------------------- */
// load all level data for the current level
void LoadLevel(const char *name);
// free all level data
void FreeLevel(void);
void LevelGetBounds(double *lx, double *ly, double *hx, double *hy);
#endif /* __NODEVIEW_LEVEL_H__ */
|