1 /* ResidualVM - A 3D game interpreter
2  *
3  * ResidualVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the AUTHORS
5  * file distributed with this source distribution.
6  *
7  * Additional copyright for this file:
8  * Copyright (C) 1999-2000 Revolution Software Ltd.
9  * This code is based on source code created by Revolution Software,
10  * used with permission.
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
25  *
26  */
27 
28 #ifndef ICB_PX_ROUTE_BARRIERS_H_INCLUDED
29 #define ICB_PX_ROUTE_BARRIERS_H_INCLUDED
30 
31 // Include headers needed by this file.
32 
33 #include "engines/icb/common/px_common.h"
34 
35 namespace ICB {
36 
37 // These define the filenames for files containing barrier maps and routing maps.
38 #define PX_FILENAME_LINEOFSIGHT "pxwglineofsight"
39 #define PX_FILENAME_ROUTING "pxwgrouting"
40 #define PX_FILENAME_BARRIERLIST "pxwgbarrierlist"
41 
42 #ifndef PC_EXT_LINKED
43 #define PC_EXT_LINKED "linked"
44 #endif
45 
46 #ifndef PSX_EXT_LINKED
47 #define PSX_EXT_LINKED "PSXlinked"
48 #endif
49 
50 #ifdef PX_EXT_LINKED
51 #undef PX_EXT_LINKED
52 #endif
53 
54 #define PX_EXT_LINKED PC_EXT_LINKED
55 
56 // This is the version for these files.  The engine checks this runtime to know that it is running with
57 // the correct version of file.
58 #define VERSION_PXWGLINEOFSIGHT 200
59 #define VERSION_PXWGROUTING 200
60 #define VERSION_PXWGBARRIERLIST 200
61 
62 // This is the size of the sides of the cubes that each floor is divided into in centimetres.
63 #define FLOOR_CUBE_SIZE 1000   // 10-metre sides.
64 #define ABOVE_ALL_MODELS 10000 // Set this to be higher than any model point ever.
65 
66 // This is an enumerated type for the barrier (the types listed are just illustrations - they may well be changed).
67 //  BRICK               -   can't walk through it, see through it or shoot through it.
68 //  GLASS               -   can't walk through it; can see through it; not sure about shooting (glass would need to break).
69 //  BULLET_PROOF_GLASS  -   can't walk through it or shoot through it, but can see through it.
70 //  THIN_STEEL          -   can't see through it or walk through it, but can shoot through it.
71 //  WIRE_FENCE          -   can't walk through it, but can see through it; can shoot through it with random success.
72 //  UNIT_HEIGHT         -   special one for stopping characters walking off the edge of ledges etc.
73 //  VIEW_FIELD          -   stops characters walking out of camera field-of-view.
74 //  LEFT_NUDGE          -   use to assist player control going through doors.
75 //  RIGHT_NUDGE         -   ditto last one.
76 enum _barrier_type { BRICK = 0, GLASS, BULLET_PROOF_GLASS, THIN_STEEL, WIRE_FENCE, UNIT_HEIGHT, VIEW_FIELD, LEFT_NUDGE, RIGHT_NUDGE };
77 
78 #define BARRIER_TYPE_CARDINALITY 9 // Must match number of enums in previous type (because C++
79 // doesn't provide a way to get this).
80 
81 // This is an enumerated type for the things that might try to pass through a barrier.  Note: the TEST_RAY
82 // is blocked by all types of barrier.
83 enum _barrier_ray_type { TEST_RAY, LIGHT, BULLET };
84 
85 #define RAY_TYPE_CARDINALITY 3
86 
87 // Defines a multi-state logic value for use with the barriers.
88 enum _barrier_logic_value { NO_IMPACT = 0, BLOCKS, ALLOWS, MAYBE, SPECIAL };
89 
90 // This is the truth table that states what kind of ray passes through what
91 // type of barrier.
92 static enum _barrier_logic_value _barrier_logic_table[BARRIER_TYPE_CARDINALITY][RAY_TYPE_CARDINALITY] = {
93 	{BLOCKS, BLOCKS, BLOCKS}, {BLOCKS, ALLOWS, SPECIAL}, {BLOCKS, ALLOWS, BLOCKS}, {BLOCKS, BLOCKS, ALLOWS}, {BLOCKS, ALLOWS, MAYBE},
94 	{BLOCKS, ALLOWS, ALLOWS}, {BLOCKS, ALLOWS, ALLOWS},  {BLOCKS, ALLOWS, ALLOWS}, {BLOCKS, ALLOWS, ALLOWS}};
95 
96 // simple, this is just for the converters
97 // Some extra figures to speed up barrier collision detection.
98 typedef struct {
99 	PXfloat linedist, alinedist, blinedist;
100 	PXfloat lpx, lpz;   // Main barrier
101 	PXfloat alpx, alpz; // End A.
102 	PXfloat blpx, blpz; // End B.
103 } _simple_barrier_collision_maths;
104 
105 // simple, this is just for the converters
106 // This holds one single barrier.
107 typedef struct {
108 	PXreal x1, z1;                       // Looking down on the model, the position of the first vertical edge of the barrier.
109 	PXreal x2, z2;                       // Looking down on the model, the position of the second vertical edge.
110 	PXreal bottom;                       // The bottom of the barrier.
111 	PXreal top;                          // The top of the barrier.
112 	_barrier_type material;              // The material the barrier is made of.
113 	PXfloat pan;                         // The barrier's pan value.
114 	_simple_barrier_collision_maths bcm; // Some extra figures to speed up barrier collision detection.
115 } _simple_route_barrier;
116 
117 class _barrier_collision_maths {
118 private:
119 	// these are in both versions
120 	PXfloat m_linedist, m_alinedist, m_blinedist;
121 
122 	PXfloat m_lpx, m_lpz;   // Main barrier
123 	PXfloat m_alpx, m_alpz; // End A.
124 	PXfloat m_blpx, m_blpz; // End B.
125 
126 public:
linedist()127 	inline PXfloat linedist() { return m_linedist; }
128 
alinedist()129 	inline PXfloat alinedist() { return m_alinedist; }
blinedist()130 	inline PXfloat blinedist() { return m_blinedist; }
131 
132 	// on pc these are pxfloats
133 
lpx()134 	inline PXfloat lpx() { return m_lpx; }
lpz()135 	inline PXfloat lpz() { return m_lpz; }
136 
alpx()137 	inline PXfloat alpx() {
138 		// return m_alpx;
139 		return -lpz();
140 	}
141 
alpz()142 	inline PXfloat alpz() {
143 		// return m_alpz;
144 		return lpx();
145 	}
146 
blpx()147 	inline PXfloat blpx() {
148 		// return m_blpx;
149 		return lpz();
150 	}
151 
blpz()152 	inline PXfloat blpz() {
153 		// return m_blpz;
154 		return -lpx();
155 	}
156 
Generate(PXreal x1,PXreal z1,PXreal x2,PXreal z2)157 	void Generate(PXreal x1, PXreal z1, PXreal x2, PXreal z2) {
158 		PXreal dx = x1 - x2;
159 		PXreal dz = z1 - z2;
160 
161 		int32 nLength = (int32)PXsqrt((PXdouble)(dx * dx + dz * dz));
162 
163 		PXfloat xunit = PXreal2PXfloat(dx) / nLength;
164 		PXfloat zunit = PXreal2PXfloat(dz) / nLength;
165 
166 		m_lpx = -zunit;
167 		m_lpz = xunit;
168 
169 		m_linedist = (x1 * lpx()) + (z1 * lpz());
170 
171 		m_alinedist = (x1 * alpx()) + (z1 * alpz());
172 
173 		m_blinedist = (x2 * blpx()) + (z2 * blpz());
174 	}
175 
_barrier_collision_maths()176 	_barrier_collision_maths() {
177 		(void)m_alpx; // shutup warning
178 		(void)m_alpz; // shutup warning
179 		(void)m_blpx; // shutup warning
180 		(void)m_blpz; // shutup warning
181 	}
182 };
183 
184 class _route_barrier {
185 
186 	PXreal m_x1, m_z1;        // Looking down on the model, the position of the first vertical edge of the barrier.
187 	PXreal m_x2, m_z2;        // Looking down on the model, the position of the second vertical edge.
188 	PXreal m_bottom;          // The bottom of the barrier.
189 	PXreal m_top;             // The top of the barrier.
190 	_barrier_type m_material; // The material the barrier is made of.
191 	PXfloat m_pan;            // The barrier's pan value.
192 	_barrier_collision_maths m_bcm; // Some extra figures to speed up barrier collision detection.
193 
194 public:
195 
Create_pan()196 	void Create_pan() { m_pan = PXAngleOfVector(m_z1 - m_z2, m_x1 - m_x2); }
197 
x1(PXreal x)198 	void x1(PXreal x) { m_x1 = x; }
z1(PXreal z)199 	void z1(PXreal z) { m_z1 = z; }
200 
x1()201 	inline PXreal x1() const { return m_x1; }
z1()202 	inline PXreal z1() const { return m_z1; }
203 
x2(PXreal x)204 	void x2(PXreal x) { m_x2 = x; }
z2(PXreal z)205 	void z2(PXreal z) { m_z2 = z; }
x2()206 	inline PXreal x2() const { return m_x2; }
z2()207 	inline PXreal z2() const { return m_z2; }
bottom()208 	inline PXreal bottom() const { return m_bottom; }
top()209 	inline PXreal top() const { return m_top; }
material()210 	inline _barrier_type material() const { return m_material; }
211 
pan()212 	inline PXfloat pan() const { return m_pan; }
213 
bcm()214 	inline _barrier_collision_maths &bcm() { return m_bcm; }
215 
_route_barrier()216 	_route_barrier() {}
217 
_route_barrier(PXreal inX1,PXreal inZ1,PXreal inX2,PXreal inZ2,PXreal inBottom,PXreal inTop,_barrier_type inMaterial)218 	_route_barrier(PXreal inX1, PXreal inZ1, PXreal inX2, PXreal inZ2, PXreal inBottom, PXreal inTop, _barrier_type inMaterial) {
219 		m_x1 = inX1;
220 		m_z1 = inZ1;
221 		m_x2 = inX2;
222 		m_z2 = inZ2;
223 		m_bottom = inBottom;
224 		m_top = inTop;
225 		m_material = inMaterial;
226 	}
227 };
228 
229 // This holds several barriers.  These barriers all at least partly occupy a given cube in space.  If one barrier passes
230 // through more than one cube, it will have a duplicate entry in each cube.
231 typedef struct {
232 	int32 num_barriers; // The number of barriers referenced in this cube.
233 	uint32 barriers;    // Offset to an array of barrier indices.
234 } _barrier_cube;
235 
236 // This is a horizontal slice through the Max model, containing all the route barriers that pass through this level.  The
237 // extremeties of the whole cuboid are given first so that a quick initial check can be done to see if there might be
238 // route barriers in the way.
239 typedef struct {
240 	PXreal bottom;          // The bottom of the slice.
241 	PXreal top;             // The top of the slice.
242 	PXreal left_edge;       // Leftmost edge of the cube of space occupied by this floor slice.
243 	PXreal right_edge;      // Ditto right edge.
244 	PXreal back_edge;       // Back edge.
245 	PXreal front_edge;      // Ditto front edge.
246 	uint32 num_cubes;       // Number of _route_cubes in this floor (could be calculated by dividing overall cube size by FLOOR_CUBE_SIZE).
247 	uint32 row_length;      // Size of the rows in the array (eg. 6 cubes could be 1X6, 2X3, 3X2 or 6X1).
248 	uint32 offset_cubes[1]; // An array of offsets to cubes (2D array of size row_length * (num_cubes / row_length) ).
249 } _barrier_slice;
250 
251 // This is used in the following definition of _parent_box, and holds one group of barriers.
252 typedef struct {
253 	PXreal back, left;   // Back/left of the bounding box holding this group of barriers (looking down into the model).
254 	PXreal front, right; // Ditto front/right.
255 	uint32 num_barriers; // Number of barriers in this group.
256 	uint32 barriers[1];  // Array of barrier indices.
257 
258 } _child_group;
259 
260 // This holds one parent box entry.
261 typedef struct {
262 	PXreal back, left;      // Top/left of the parent box (looking down into the model).
263 	PXreal front, right;    // Ditto bottom/right.
264 	uint32 num_barriers;    // Number of barriers in the parent (not its children).
265 	uint32 barriers;        // Offset to an array of barrier indices.
266 	uint32 num_specials;    // Number of special barriers (eg. field-of-view).
267 	uint32 specials;        // Offset of the array of special barrier indices.
268 	uint32 num_childgroups; // Number of child groups owned by this parent box.
269 	uint32 childgroups[1];  // Array of offsets to the child groups.
270 
271 } _parent_box;
272 
273 // This is also a slice through the model, but the data is grouped in a different way which is more suited to routing.
274 typedef struct {
275 	PXreal bottom;           // The bottom of the slice.
276 	PXreal top;              // The top of the slice.
277 	uint32 num_parent_boxes; // The number of parent boxes in this slice (same as the number of floor rectangles at this height).
278 	uint32 parent_boxes[1];  // An array of offsets to parent boxes.
279 
280 } _routing_slice;
281 
IsBarrierTo(_barrier_type eMaterial,_barrier_ray_type eRay)282 __inline _barrier_logic_value IsBarrierTo(_barrier_type eMaterial, _barrier_ray_type eRay) { return _barrier_logic_table[eMaterial][eRay]; }
283 
284 } // End of namespace ICB
285 
286 #endif // #ifndef _PX_ROUTE_BARRIERS_H_INCLUDED
287