1 
2 #ifndef ROOM_H
3 #define ROOM_H
4 
5 #include <stdint.h>
6 
7 // Here you can specify the way OpenTomb processes room collision -
8 // in a classic TR way (floor data collision) or in a modern way
9 // (derived from actual room mesh).
10 
11 #define TR_MESH_ROOM_COLLISION 0
12 
13 // Metering step and sector size are basic Tomb Raider world metrics.
14 // Use these defines at all times, when you're referencing classic TR
15 // dimensions and terrain manipulations.
16 
17 #define TR_METERING_STEP        (256.0)
18 #define TR_METERING_SECTORSIZE  (1024.0)
19 
20 // Wall height is a magical constant which specifies that sector with such
21 // height contains impassable wall.
22 
23 #define TR_METERING_WALLHEIGHT  (32512)
24 
25 // Penetration configuration specifies collision type for floor and ceiling
26 // sectors (squares).
27 
28 #define TR_PENETRATION_CONFIG_SOLID             0   // Ordinary sector.
29 #define TR_PENETRATION_CONFIG_DOOR_VERTICAL_A   1   // TR3-5 triangulated door.
30 #define TR_PENETRATION_CONFIG_DOOR_VERTICAL_B   2   // TR3-5 triangulated door.
31 #define TR_PENETRATION_CONFIG_WALL              3   // Wall (0x81 == TR_METERING_WALLHEIGHT)
32 #define TR_PENETRATION_CONFIG_GHOST             4   // No collision.
33 
34 // There are two types of diagonal splits - we call them north-east (NE) and
35 // north-west (NW). In case there is no diagonal in sector (TR1-2 classic sector),
36 // then NONE type is used.
37 
38 #define TR_SECTOR_DIAGONAL_TYPE_NONE            0
39 #define TR_SECTOR_DIAGONAL_TYPE_NE              1
40 #define TR_SECTOR_DIAGONAL_TYPE_NW              2
41 
42 // Tween is a short word for "inbeTWEEN vertical polygon", which is needed to fill
43 // the gap between two sectors with different heights. If adjacent sector heights are
44 // similar, it means that tween is degenerated (doesn't exist physically) - in that
45 // case we use NONE type. If only one of two heights' pairs is similar, then tween is
46 // either right or left pointed triangle (where "left" or "right" is derived by viewing
47 // triangle from front side). If none of the heights are similar, we need quad tween.
48 
49 #define TR_SECTOR_TWEEN_TYPE_NONE               0   // Degenerated vertical polygon.
50 #define TR_SECTOR_TWEEN_TYPE_TRIANGLE_RIGHT     1   // Triangle pointing right (viewed front).
51 #define TR_SECTOR_TWEEN_TYPE_TRIANGLE_LEFT      2   // Triangle pointing left (viewed front).
52 #define TR_SECTOR_TWEEN_TYPE_QUAD               3   //
53 #define TR_SECTOR_TWEEN_TYPE_2TRIANGLES         4   // it looks like a butterfly
54 
55 
56 #define TR_ROOM_FLAG_WATER          0x0001
57 #define TR_ROOM_FLAG_QUICKSAND      0x0002  // Moved from 0x0080 to avoid confusion with NL.
58 #define TR_ROOM_FLAG_SKYBOX         0x0008
59 #define TR_ROOM_FLAG_UNKNOWN1       0x0010
60 #define TR_ROOM_FLAG_WIND           0x0020
61 #define TR_ROOM_FLAG_UNKNOWN2       0x0040  ///@FIXME: Find what it means!!! Always set by Dxtre3d.
62 #define TR_ROOM_FLAG_NO_LENSFLARE   0x0080  // In TR4-5. Was quicksand in TR3.
63 #define TR_ROOM_FLAG_MIST           0x0100  ///@FIXME: Unknown meaning in TR1!!!
64 #define TR_ROOM_FLAG_CAUSTICS       0x0200
65 #define TR_ROOM_FLAG_UNKNOWN3       0x0400
66 #define TR_ROOM_FLAG_DAMAGE         0x0800  ///@FIXME: Is it really damage (D)?
67 #define TR_ROOM_FLAG_POISON         0x1000  ///@FIXME: Is it really poison (P)?
68 
69 //Room light mode flags (TR2 ONLY)
70 
71 #define TR_ROOM_LIGHTMODE_FLICKER   0x1
72 
73 // Sector flags specify various unique sector properties.
74 // Derived from native TR floordata functions.
75 
76 #define SECTOR_FLAG_CLIMB_NORTH     0x00000001  // subfunction 0x01
77 #define SECTOR_FLAG_CLIMB_EAST      0x00000002  // subfunction 0x02
78 #define SECTOR_FLAG_CLIMB_SOUTH     0x00000004  // subfunction 0x04
79 #define SECTOR_FLAG_CLIMB_WEST      0x00000008  // subfunction 0x08
80 #define SECTOR_FLAG_CLIMB_CEILING   0x00000010
81 #define SECTOR_FLAG_MINECART_LEFT   0x00000020
82 #define SECTOR_FLAG_MINECART_RIGHT  0x00000040
83 #define SECTOR_FLAG_TRIGGERER_MARK  0x00000080
84 #define SECTOR_FLAG_BEETLE_MARK     0x00000100
85 #define SECTOR_FLAG_DEATH           0x00000200
86 
87 // Sector material specifies audio response from character footsteps, as well as
88 // footstep texture option, plus possible vehicle physics difference in the future.
89 
90 #define SECTOR_MATERIAL_MUD         0   // Classic one, TR1-2.
91 #define SECTOR_MATERIAL_SNOW        1
92 #define SECTOR_MATERIAL_SAND        2
93 #define SECTOR_MATERIAL_GRAVEL      3
94 #define SECTOR_MATERIAL_ICE         4
95 #define SECTOR_MATERIAL_WATER       5
96 #define SECTOR_MATERIAL_STONE       6
97 #define SECTOR_MATERIAL_WOOD        7
98 #define SECTOR_MATERIAL_METAL       8
99 #define SECTOR_MATERIAL_MARBLE      9
100 #define SECTOR_MATERIAL_GRASS       10
101 #define SECTOR_MATERIAL_CONCRETE    11
102 #define SECTOR_MATERIAL_OLDWOOD     12
103 #define SECTOR_MATERIAL_OLDMETAL    13
104 
105 
106 struct engine_container_s;
107 struct polygon_s;
108 struct camera_s;
109 struct portal_s;
110 struct frustum_s;
111 struct base_mesh_s;
112 struct physics_object_s;
113 struct trigger_header_s;
114 
115 
116 typedef struct room_zone_s
117 {
118     int16_t GroundZone1;
119     int16_t GroundZone2;
120     int16_t GroundZone3;
121     int16_t GroundZone4;
122     int16_t FlyZone;
123 }room_zone_t, *room_zone_p;
124 
125 
126 typedef struct box_overlap_s
127 {
128     uint16_t        box : 15;
129     uint16_t        end : 1;
130 }box_overlap_t, *box_overlap_p;
131 
132 
133 typedef struct room_box_s
134 {
135     uint32_t                id : 16;
136     uint32_t                is_blockable : 1;
137     uint32_t                is_blocked : 1;
138     uint32_t                 : 14;
139     float                   bb_min[3];
140     float                   bb_max[3];
141     struct box_overlap_s   *overlaps;
142     struct room_zone_s      zone[2];
143 }room_box_t, *room_box_p;
144 
145 
146 #define ZONE_TYPE_ALL       (0)
147 #define ZONE_TYPE_1         (1)
148 #define ZONE_TYPE_2         (2)
149 #define ZONE_TYPE_3         (3)
150 #define ZONE_TYPE_4         (4)
151 #define ZONE_TYPE_FLY       (5)
152 
153 typedef struct box_validition_options_s
154 {
155     uint16_t                step_up;
156     uint16_t                step_down;
157     uint16_t                zone_type : 15;
158     uint16_t                zone_alt : 1;
159     uint16_t                zone;
160 }box_validition_options_t, *box_validition_options_p;
161 
162 
163 typedef struct room_sector_s
164 {
165     uint32_t                    trig_index; // Trigger function index.
166 
167     uint32_t                    flags;      // Climbability, death etc.
168     uint32_t                    material;   // Footstep sound and footsteps.
169 
170     int32_t                     floor;
171     int32_t                     ceiling;
172 
173     struct trigger_header_s    *trigger;
174     struct room_box_s          *box;
175     struct room_s              *owner_room;    // Room that contain this sector
176     struct room_s              *portal_to_room;
177 
178     struct room_s              *room_below;
179     struct room_s              *room_above;
180     int16_t                     index_x;
181     int16_t                     index_y;
182     float                       pos[3];
183 
184     float                       ceiling_corners[4][3];
185     uint8_t                     ceiling_diagonal_type;
186     uint8_t                     ceiling_penetration_config;
187 
188     float                       floor_corners[4][3];
189     uint8_t                     floor_diagonal_type;
190     uint8_t                     floor_penetration_config;
191 }room_sector_t, *room_sector_p;
192 
193 
194 typedef struct sector_tween_s
195 {
196     float                       floor_corners[4][3];
197     uint8_t                     floor_tween_type;
198     uint8_t                     floor_tween_inverted;
199 
200     float                       ceiling_corners[4][3];
201     uint8_t                     ceiling_tween_type;
202     uint8_t                     ceiling_tween_inverted;
203 }sector_tween_t, *sector_tween_p;
204 
205 
206 typedef struct room_sprite_s
207 {
208     struct sprite_s            *sprite;
209     float                       pos[3];
210 }room_sprite_t, *room_sprite_p;
211 
212 
213 typedef struct static_mesh_s
214 {
215     uint32_t                    object_id;                                      //
216     uint8_t                     hide;                                           // disable static mesh rendering
217     float                       pos[3];                                         // model position
218     float                       rot[3];                                         // model angles
219     GLfloat                     tint[4];                                        // model tint
220 
221     float                       vbb_min[3];                                     // visible bounding box
222     float                       vbb_max[3];
223     float                       cbb_min[3];                                     // collision bounding box
224     float                       cbb_max[3];
225 
226     float                       transform[16]   __attribute__((packed, aligned(16)));   // gl transformation matrix
227     struct obb_s               *obb;
228     struct engine_container_s  *self;
229 
230     struct base_mesh_s         *mesh;                                           // base model
231     struct physics_object_s    *physics_body;
232 }static_mesh_t, *static_mesh_p;
233 
234 
235 typedef struct room_content_s
236 {
237     uint32_t                    original_room_id;
238     uint32_t                    room_flags;                                     // room's type + water, wind info
239     uint32_t                    portals_count;                                  // number of room portals
240     struct portal_s            *portals;                                        // room portals array
241     struct room_sector_s       *sectors;
242 
243     uint16_t                    near_room_list_size;
244     uint16_t                    overlapped_room_list_size;
245     struct room_s             **near_room_list;
246     struct room_s             **overlapped_room_list;
247 
248     uint32_t                    static_mesh_count;
249     struct static_mesh_s       *static_mesh;
250     uint32_t                    sprites_count;
251     struct room_sprite_s       *sprites;
252     struct vertex_s            *sprites_vertices;
253     uint32_t                    lights_count;
254     struct light_s             *lights;
255 
256     int16_t                     light_mode;                                     // (present only in TR2: 0 is normal, 1 is flickering(?), 2 and 3 are uncertain)
257     uint8_t                     reverb_info;                                    // room reverb type
258     uint8_t                     water_scheme;
259     uint8_t                     alternate_group;
260 
261     float                       ambient_lighting[3];
262     struct base_mesh_s         *mesh;                                           // room's base mesh
263     struct physics_object_s    *physics_body;                                   // static physics data
264     struct physics_object_s    *physics_alt_tween;                              // changable (alt room) tween physics data
265 }room_content_t, *room_content_p;
266 
267 
268 typedef struct room_s
269 {
270     uint32_t                    id;                                             // room's ID
271     uint32_t                    is_in_r_list : 1;                               // is room in render list
272     uint32_t                    is_swapped : 1;
273     struct room_s              *alternate_room_next;                            // alternative room pointer
274     struct room_s              *alternate_room_prev;                            // alternative room pointer
275     struct room_s              *real_room;                                      // real room, using in game
276     struct frustum_s           *frustum;
277 
278     struct obb_s               *obb;
279     float                       bb_min[3];                                      // effective room box, exclude portal sectors zones
280     float                       bb_max[3];                                      //
281     float                       transform[16] __attribute__((packed, aligned(16))); // GL transformation matrix
282     uint32_t                    sectors_count;
283     uint16_t                    sectors_x;
284     uint16_t                    sectors_y;
285     struct engine_container_s  *containers;                                     // engine containers with moveables objects
286     struct room_content_s      *content;
287     struct room_content_s      *original_content;
288 
289     struct engine_container_s  *self;
290 }room_t, *room_p;
291 
292 
293 void Room_Clear(struct room_s *room);
294 void Room_Enable(struct room_s *room);
295 void Room_Disable(struct room_s *room);
296 int  Room_AddObject(struct room_s *room, struct engine_container_s *cont);
297 int  Room_RemoveObject(struct room_s *room, struct engine_container_s *cont);
298 
299 void Room_SetActiveContent(struct room_s *room, struct room_s *room_with_content_from);
300 void Room_DoFlip(struct room_s *room1, struct room_s *room2);
301 
302 struct room_sector_s *Room_GetSectorRaw(struct room_s *room, float pos[3]);
303 struct room_sector_s *Room_GetSectorXYZ(struct room_s *room, float pos[3]);
304 
305 void Room_AddToNearRoomsList(struct room_s *room, struct room_s *r);
306 void Room_AddToOverlappedRoomsList(struct room_s *room, struct room_s *r);
307 int  Room_IsJoined(struct room_s *r1, struct room_s *r2);
308 int  Room_IsOverlapped(struct room_s *r0, struct room_s *r1);
309 int  Room_IsInNearRoomsList(struct room_s *r0, struct room_s *r1);
310 int  Room_IsInOverlappedRoomsList(struct room_s *r0, struct room_s *r1);
311 void Room_MoveActiveItems(struct room_s *room_to, struct room_s *room_from);
312 
313 void Room_GenSpritesBuffer(struct room_s *room);
314 
315 struct room_sector_s *Sector_GetNextSector(struct room_sector_s *rs, float dir[3]);
316 struct room_sector_s *Sector_GetPortalSectorTargetRaw(struct room_sector_s *rs);
317 
318 struct room_sector_s *Sector_GetLowest(struct room_sector_s *sector);
319 struct room_sector_s *Sector_GetHighest(struct room_sector_s *sector);
320 
321 void Sector_HighestFloorCorner(room_sector_p rs, float v[3]);
322 void Sector_LowestCeilingCorner(room_sector_p rs, float v[3]);
323 
324 int Sectors_SimilarFloor(room_sector_p s1, room_sector_p s2, int ignore_doors);
325 int Sectors_SimilarCeiling(room_sector_p s1, room_sector_p s2, int ignore_doors);
326 
327 int  Room_IsInBox(room_box_p box, float pos[3]);
328 int  Room_FindPath(room_box_p *path_buf, uint32_t max_boxes, room_sector_p from, room_sector_p to, box_validition_options_p op);
329 void Room_GetOverlapCenter(room_box_p b1, room_box_p b2, float pos[3]);
330 
331 #endif //ROOM_H
332