summaryrefslogtreecommitdiff
path: root/src/game/world/map.h
blob: 8e6444e8ad8f8e043bb0c86e01401a5fb61d0938 (plain)
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
#pragma once

#include "../../util/allocator.h"
#include "../../util/vector.h"
#include "../../util/color.h"
#include "../../util/fnv.h"
#include "../../editor/properties.h"

enum MapPropId_t {
  MAPPROP_SKYBOX = -1,
  MAPPROP_CLIPBRUSH = -2,
};

struct SURF_PROPS : public EOBJECT {
  EPROP( GL_TEX2D*, tex, {}, "texture" );
  EPROP( CLR, clr, {}, "color" );
};

struct MAP_VERTEX : public EOBJECT {
  EPROP( VEC3, pos,    {}, "position" );
  EPROP( VEC3, normal, {}, "normal" );
  EPROP( VEC2, uv,     {}, "uv" );
  EPROP( CLR,  clr,    {}, "color" );
};

enum MapPolygonType_t {
  MPT_FLOOR,
  MPT_CEILING
};

struct MAP_PROPREF {
  operator I32&() { return id; }
  operator I32() const { return id; }

  MAP_PROPREF() {}
  MAP_PROPREF( U32 id ) : id( id ) {}

  I32 id;
};

struct MAP_POLYGON : public EOBJECT {
  EPROP( MAP_PROPREF, propid, {}, "prop id" );
  EPROP( LIST<MAP_VERTEX>, vertices, {}, "vertices" );

  VEC3 mins;
  VEC3 maxs;
  U8  type;
};

struct MAP_WALL : public EOBJECT {
  EPROP( MAP_PROPREF, propid, {}, "prop id" );

  EPROP( VEC3, start, {}, "start pos" );
  EPROP( VEC3, end,   {}, "end pos" );

  EPROP( VEC2, uvstart, {}, "uv start offset" );
  EPROP( VEC2, uvend,   {}, "uv end offset" );
};

struct MAP_TEXTURE_ENTRY {
  char name[256];
  struct GL_TEX2D* tex;
  FNV1A hash;
};

struct MAP_SPRITE : public EOBJECT {
  EPROP( GL_TEX2D*, tex,  {}, "texture" );
  EPROP( VEC3,      pos,  {}, "position" );
  EPROP( VEC2,      size, {}, "size" );
  EPROP( CLR,       clr,  {}, "color" );
};

struct MAP_ENTITY : public EOBJECT {
  EPROP( VEC3, pos,     {}, "position" );
  EPROP( U32,  classid, {}, "entity class" );

  EPROP( LIST<struct OBJECT_PROP*>, props, {}, "entity properties" );
};

struct MAP_SKYBOX : public EOBJECT {
  EPROP( SURF_PROPS, props, {}, "skybox surface properties" );
  MAP_WALL walls[4];
  MAP_POLYGON polygons[2];
};

struct WORLD_MAP : public EOBJECT {
  EPROP( LIST<MAP_WALL>   , walls,    {}, "walls" );
  EPROP( LIST<MAP_POLYGON>, polygons, {}, "polygons" );
  EPROP( LIST<MAP_SPRITE> , sprites,  {}, "sprites" );
  EPROP( LIST<MAP_ENTITY> , entities, {}, "entities" );
  EPROP( LIST<SURF_PROPS> , props,    {}, "surface properties" );
  EPROP( MAP_SKYBOX, skybox, {}, "skybox" );
  F32 w;
  F32 h;

  VEC3 mins;
  VEC3 maxs;
  EPROP( STR, name, {}, "name" );

  EPROP( VEC3, startpos, {}, "spawn position" );
  EPROP( F32,  startang, {}, "spawn angle" );

  struct BSP* bsp{};

  EPROP( LIST<MAP_TEXTURE_ENTRY*>, textures, {}, "textures" );
};

extern WORLD_MAP*           map_from_file( struct GAME_DATA* game, const char* filename );
extern struct CFG_SECTION*  map_serialize( WORLD_MAP* map );
extern STAT                 map_add_texture_ref( WORLD_MAP* map, GL_TEX2D* tex );
extern GL_TEX2D*            map_find_texture( WORLD_MAP* map, const char* name );
extern void                 map_free( struct GAME_DATA* game, WORLD_MAP* map );

// checks mins/maxs and recreates skybox if needed
extern void                 map_check_bounds( WORLD_MAP* map );
extern void                 map_calc_bounds( WORLD_MAP* map );
extern void                 map_polygon_calc_bounds( MAP_POLYGON* p );


inline SURF_PROPS* map_props_get_special( WORLD_MAP* w, I32 prop ) {
  switch( prop ) {
    case MAPPROP_SKYBOX: return &w->skybox.props;
  };
  dlog( "map_props_get_special(): unknown special prop %d\n", prop );
  return 0;
}

inline SURF_PROPS* map_get_props( WORLD_MAP* m, I32 idx ) {
  return idx < 0 ?
    map_props_get_special( m, idx ) :
    &m->props[idx];
}

inline SURF_PROPS* wall_get_props( WORLD_MAP* w, MAP_WALL* s ) {
  return s->propid < 0 ?
    map_props_get_special( w, s->propid ) :
    &w->props[s->propid];
}
inline SURF_PROPS* polygon_get_props( WORLD_MAP* w, MAP_POLYGON* s ) {
  return s->propid < 0 ?
    map_props_get_special( w, s->propid ) :
    &w->props[s->propid];
}