1 /*
2 
3 Copyright (C) 2015-2018 Night Dive Studios, LLC.
4 
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 
18 */
19 #ifndef __MAP_H
20 #define __MAP_H
21 
22 /*
23  *
24  *
25  * $Source: r:/prj/cit/src/inc/RCS/map.h $
26  * $Revision: 1.41 $
27  * $Author: minman $
28  * $Date: 1994/08/28 02:38:51 $
29  *
30  * $Log: map.h $
31  * Revision 1.41  1994/08/28  02:38:51  minman
32  * hey / we have a correct macro for changing fixang to objang
33  *
34  * Revision 1.40  1994/07/21  16:28:25  dc
35  * im a moron, forgot to add reshifting to flags and all last night
36  * now ALL MUST PAY
37  * AND PAY
38  * BLOOD
39  * HAH HAH HAH HAH GURGLE
40  *
41  * Revision 1.39  1994/07/21  01:51:20  dc
42  * wanted to change some #defines
43  *
44  * Revision 1.38  1994/01/26  23:34:08  mahk
45  * Changed hazard bit stuff.
46  *
47  * Revision 1.37  1994/01/22  18:56:59  dc
48  * new map regieme, take 4
49  *
50  * Revision 1.36  1994/01/02  17:17:09  dc
51  * indoor terrain renderer
52  *
53  * Revision 1.35  1993/10/18  03:35:49  dc
54  * adding dumb-o @ifndef __SPEW
55  *
56  * Revision 1.34  1993/09/08  00:59:21  xemu
57  * increase map number...EIT!
58  * sorry, had to do it for loved_textures
59  *
60  * Revision 1.33  1993/09/06  05:57:19  mahk
61  * Map has been packed.
62  *
63  * Revision 1.31  1993/09/05  21:01:52  dc
64  * added the great "pile of translations"
65  * soon tilenames will get taken out, but not yet
66  *
67  */
68 #include "schedtyp.h"
69 
70 #define MAP_TYPES 32
71 #define MAP_NUM_TMAP1 128
72 #define MAP_NUM_TMAP2 32
73 #define MAP_NUM_TMAP3 16
74 #define MAP_HEIGHTS 32
75 #define MAP_PARAMS 16
76 
77 #define TMAP_FLR 0
78 #define TMAP_WALL 1
79 #define TMAP_CEIL 2
80 
81 #define HGT_CEIL 0
82 #define HGT_FLOOR 1
83 
84 #define LITE_FLOOR 0
85 #define LITE_CEIL 1
86 
87 #define MAP_SCHEDULE_GAMETIME 0
88 #define NUM_MAP_SCHEDULES 1
89 
90 // CC: simplified savegames version
91 #define MAP_EASYSAVES_VERSION_NUMBER ((int)12)
92 
93 #define MAP_VERSION_NUMBER ((int)11)
94 // so we auto convert from it
95 #define OLD_MAP
96 #define OLD_MAP_VERSION_NUMBER ((int)10)
97 
98 // probably should kick it up to 16 bytes, expand one of the bitfields to three uchars instead
99 typedef struct _map_element {
100     //   struct _bitfields
101     //   {
102     //      ushort tiletype:6;
103     //      ushort flr_height:5;
104     //      ushort ceil_height:5;
105     //   };
106     uchar tiletype;     // 2 free bits
107     uchar flr_rotnhgt;  // 1 free bit
108     uchar ceil_rotnhgt; // 1 free bit
109     uchar param;
110     short objRef;
111     //   struct _lighting
112     //   {
113     //      uchar floor:4;
114     //      uchar ceil:4;
115     //   } templight;
116     ushort tmap_ccolor;
117     //   union _space
118     //      {
119     //         struct _tmaps
120     //         {
121     //            ushort floor:5;
122     //            ushort ceil:5;
123     //            ushort wall:6;
124     //         } real;
125     //         struct _cybcolors
126     //         {
127     //            uchar floor;
128     //            uchar ceil;
129     //         } cyber;
130     //      } space;
131     uchar flag1; // KLC swapped around
132     uchar flag2;
133     uchar flag3;
134     uchar flag4; // rename these, perhaps
135                  //   ulong flags;
136     uchar sub_clip;
137     uchar clearsolid;
138     uchar flick_qclip;
139     uchar templight;
140     //   struct _render_info {
141     //      uchar sub_clip;
142     //      uchar clear;
143     //      uchar rotflr:2;
144     //      uchar rotceil:2;
145     //      uchar flicker:4;
146     //   } rinfo;
147 } MapElem;
148 
149 #ifdef OLD_MAP
150 typedef struct _omap_element {
151     //struct _bitfields {
152     //    ushort tiletype : 6;
153     //    ushort flr_height : 5;
154     //    ushort ceil_height : 5;
155     //};
156     uchar param;
157     struct _lighting {
158         uchar floor : 4;
159         uchar ceil : 4;
160     } templight;
161     union _space {
162         struct _tmaps {
163             ushort floor : 5;
164             ushort ceil : 5;
165             ushort wall : 6;
166         } real;
167         struct _cybcolors {
168             uchar floor;
169             uchar ceil;
170         } cyber;
171     } space;
172     ulong flags;
173     short objRef;
174     struct _render_info {
175         uchar sub_clip;
176         uchar clear;
177         uchar rotflr : 2;
178         uchar rotceil : 2;
179         uchar flicker : 4;
180     } rinfo;
181 } oMapElem;
182 
183 typedef struct {
184     int x_size, y_size;
185     int x_shft, y_shft, z_shft;
186     oMapElem *map;
187     uchar cyber;
188     int x_scale, y_scale, z_scale;
189     Schedule sched[NUM_MAP_SCHEDULES];
190 } oFullMap;
191 
192 #define ome_tiletype(me_ptr)             ((me_ptr)->tiletype)
193 #define ome_tmap_flr(me_ptr)             ((me_ptr)->space.real.floor)
194 #define ome_tmap_wall(me_ptr)            ((me_ptr)->space.real.wall)
195 #define ome_tmap_ceil(me_ptr)            ((me_ptr)->space.real.ceil)
196 #define ome_tmap(me_ptr, idx) \
197     (((idx) == TMAP_FLR) ? me_tmap_flr(me_ptr) : (((idx) == TMAP_CEIL) ? me_tmap_ceil(me_ptr) : me_tmap_wall(me_ptr)))
198 #define ome_objref(me_ptr)               ((me_ptr)->objRef)
199 #define ome_flags(me_ptr)                ((me_ptr)->flags)
200 #define ome_height_flr(me_ptr)           ((me_ptr)->flr_height)
201 #define ome_height_ceil(me_ptr)          ((me_ptr)->ceil_height)
202 #define ome_param(me_ptr)                ((me_ptr)->param)
203 #define ome_height(me_ptr,idx)           (((idx) == HGT_FLOOR) ? me_height_flr(me_ptr) : me_height_ceil(me_ptr))
204 #define ome_cybcolor_flr(me_ptr)         ((me_ptr)->space.cyber.floor)
205 #define ome_cybcolor_ceil(me_ptr)        ((me_ptr)->space.cyber.ceil)
206 #define ome_templight_flr(me_ptr)        ((me_ptr)->templight.floor)
207 #define ome_templight_ceil(me_ptr)       ((me_ptr)->templight.ceil)
208 #define ome_subclip(me_ptr)              ((me_ptr)->rinfo.sub_clip)
209 #define ome_clearsolid(me_ptr)           ((me_ptr)->rinfo.clear)
210 #define ome_rotflr(me_ptr)               ((me_ptr)->rinfo.rotflr)
211 #define ome_rotceil(me_ptr)              ((me_ptr)->rinfo.rotceil)
212 #define ome_flicker(me_ptr)              ((me_ptr)->rinfo.flicker)
213 #endif
214 
215 typedef struct {
216     int32_t x_size, y_size;
217     int32_t x_shft, y_shft, z_shft;
218     MapElem *map;
219     uchar cyber;
220     int32_t x_scale, y_scale, z_scale;
221     Schedule sched[NUM_MAP_SCHEDULES];
222 } FullMap;
223 
224 #define _me_normal_x(me_ptr, strname, maskname) ((me_ptr)->strname & (maskname##_MASK))
225 #define _me_normal_n(me_ptr, strname, maskname) (_me_normal_x(me_ptr, strname, maskname) >> maskname##_SHF)
226 
227 #define _me_tiletype(me_ptr) ((me_ptr)->tiletype)
228 
229 #define MAP_HGT_MASK 0x1f
230 #define MAP_HGT_SHF  0
231 #define _me_height_flr(me_ptr)  _me_normal_x(me_ptr, flr_rotnhgt, MAP_HGT)
232 #define _me_height_ceil(me_ptr) _me_normal_x(me_ptr, ceil_rotnhgt, MAP_HGT)
233 #define _me_height(me_ptr, idx) (((idx) == HGT_FLOOR) ? me_height_flr(me_ptr) : me_height_ceil(me_ptr))
234 
235 #define _me_param(me_ptr)  ((me_ptr)->param)
236 #define _me_objref(me_ptr) ((me_ptr)->objRef)
237 
238 #define MAP_TM_FLOOR_MASK 0xF800
239 #define MAP_TM_FLOOR_SHF  11
240 #define MAP_TM_CEIL_MASK  0x07C0
241 #define MAP_TM_CEIL_SHF   6
242 #define MAP_TM_WALL_MASK  0x003F
243 #define MAP_TM_WALL_SHF   0
244 #define _me_tmap_flr_x(me_ptr)  _me_normal_x(me_ptr, tmap_ccolor, MAP_TM_FLOOR)
245 #define _me_tmap_flr(me_ptr)    _me_normal_n(me_ptr, tmap_ccolor, MAP_TM_FLOOR)
246 #define _me_tmap_ceil_x(me_ptr) _me_normal_x(me_ptr, tmap_ccolor, MAP_TM_CEIL)
247 #define _me_tmap_ceil(me_ptr)   _me_normal_n(me_ptr, tmap_ccolor, MAP_TM_CEIL)
248 #define _me_tmap_wall_x(me_ptr) _me_normal_x(me_ptr, tmap_ccolor, MAP_TM_WALL)
249 #define _me_tmap_wall(me_ptr)   _me_normal_n(me_ptr, tmap_ccolor, MAP_TM_WALL)
250 #define _me_tmap(me_ptr, idx) \
251     (((idx) == TMAP_FLR) ? me_tmap_flr(me_ptr) : (((idx) == TMAP_CEIL) ? me_tmap_ceil(me_ptr) : me_tmap_wall(me_ptr)))
252 #define _me_cybcolor_flr(me_ptr)  (*((uchar *)(&((me_ptr)->tmap_ccolor))))
253 #define _me_cybcolor_ceil(me_ptr) (*((uchar *)(&((me_ptr)->tmap_ccolor)) + 1))
254 
255 // note this returns a long of form f4f3f2f1, so flag4 is most significant, as it were
256 #define _me_flags(me_ptr) (*((ulong *)(&((me_ptr)->flag1)))) // KLC changed
257 #define _me_flag1(me_ptr) ((me_ptr)->flag1)
258 #define _me_flag2(me_ptr) ((me_ptr)->flag2)
259 #define _me_flag3(me_ptr) ((me_ptr)->flag3)
260 #define _me_flag4(me_ptr) ((me_ptr)->flag4)
261 
262 #define _me_subclip(me_ptr)    ((me_ptr)->sub_clip)
263 #define _me_clearsolid(me_ptr) ((me_ptr)->clearsolid)
264 
265 #define MAP_ROT_MASK 0x60
266 #define MAP_ROT_SHF 5
267 #define _me_rotflr_x(me_ptr)  _me_normal_x(me_ptr, flr_rotnhgt, MAP_ROT)
268 #define _me_rotflr(me_ptr)    _me_normal_n(me_ptr, flr_rotnhgt, MAP_ROT)
269 #define _me_rotceil_x(me_ptr) _me_normal_x(me_ptr, ceil_rotnhgt, MAP_ROT)
270 #define _me_rotceil(me_ptr)   _me_normal_n(me_ptr, ceil_rotnhgt, MAP_ROT)
271 
272 #define MAP_HAZARD_MASK 0x80
273 #define MAP_HAZARD_SHF  7
274 #define _me_hazard_bio_x(me_ptr) _me_normal_x(me_ptr, flr_rotnhgt, MAP_HAZARD)
275 #define _me_hazard_bio(me_ptr)   _me_normal_n(me_ptr, flr_rotnhgt, MAP_HAZARD)
276 #define _me_hazard_rad_x(me_ptr) _me_normal_x(me_ptr, ceil_rotnhgt, MAP_HAZARD)
277 #define _me_hazard_rad(me_ptr)   _me_normal_n(me_ptr, ceil_rotnhgt, MAP_HAZARD)
278 
279 #define MAP_FLICKER_MASK   0xF0
280 #define MAP_FLICKER_SHF    4
281 #define MAP_QUICKCLIP_MASK 0x0F
282 #define MAP_QUICKCLIP_SHF  0
283 #define _me_flicker_x(me_ptr)   _me_normal_x(me_ptr, flick_qclip, MAP_FLICKER)
284 #define _me_flicker(me_ptr)     _me_normal_n(me_ptr, flick_qclip, MAP_FLICKER)
285 #define _me_quickclip_x(me_ptr) _me_normal_x(me_ptr, flick_qclip, MAP_QUICKCLIP)
286 #define _me_quickclip(me_ptr)   _me_normal_n(me_ptr, flick_qclip, MAP_QUICKCLIP)
287 
288 #define MAP_TLGHT_CEIL_MASK  0xF0
289 #define MAP_TLGHT_CEIL_SHF   4
290 #define MAP_TLGHT_FLOOR_MASK 0x0F
291 #define MAP_TLGHT_FLOOR_SHF  0
292 #define _me_templight_ceil_x(me_ptr) _me_normal_x(me_ptr, templight, MAP_TLGHT_CEIL)
293 #define _me_templight_ceil(me_ptr)   _me_normal_n(me_ptr, templight, MAP_TLGHT_CEIL)
294 #define _me_templight_flr_x(me_ptr)  _me_normal_x(me_ptr, templight, MAP_TLGHT_FLOOR)
295 #define _me_templight_flr(me_ptr)    _me_normal_n(me_ptr, templight, MAP_TLGHT_FLOOR)
296 
297 // implicit me_ptr and v
298 #define _me_merge_set(me_ptr, v, strname, maskname) \
299     ((me_ptr)->strname = ((me_ptr)->strname & ~(maskname##_MASK)) | ((v) << (maskname##_SHF)))
300 
301 // Now all the set primitives
302 #define _me_tiletype_set(me_ptr, v)      ((me_ptr)->tiletype = (v))
303 #define _me_height_flr_set(me_ptr, v)    _me_merge_set(me_ptr, v, flr_rotnhgt, MAP_HGT)
304 #define _me_height_ceil_set(me_ptr, v)   _me_merge_set(me_ptr, v, ceil_rotnhgt, MAP_HGT)
305 #define _me_height_set(me_ptr, idx, v) \
306     (((idx) == HGT_FLOOR) ? me_height_flr_set(me_ptr, v) : me_height_ceil_set(me_ptr, v))
307 #define _me_param_set(me_ptr, v)         ((me_ptr)->param = (v))
308 #define _me_objref_set(me_ptr, v)        ((me_ptr)->objRef = (v))
309 #define _me_tmap_flr_set(me_ptr, v)      _me_merge_set(me_ptr, v, tmap_ccolor, MAP_TM_FLOOR)
310 #define _me_tmap_ceil_set(me_ptr, v)     _me_merge_set(me_ptr, v, tmap_ccolor, MAP_TM_CEIL)
311 #define _me_tmap_wall_set(me_ptr, v)     _me_merge_set(me_ptr, v, tmap_ccolor, MAP_TM_WALL)
312 #define _me_tmap_set(me_ptr, idx, v)                  \
313     (((idx) == TMAP_FLR) ? me_tmap_flr_set(me_ptr, v) \
314                          : (((idx) == TMAP_CEIL) ? me_tmap_ceil_set(me_ptr, v) : me_tmap_wall_set(me_ptr, v)))
315 #define _me_cybcolor_flr_set(me_ptr, v)  (_me_cybcolor_flr(me_ptr) = (v))
316 #define _me_cybcolor_ceil_set(me_ptr, v) (_me_cybcolor_ceil(me_ptr) = (v))
317 #define _me_flags_set(me_ptr, v)         (_me_flags(me_ptr) = (v))
318 #define _me_flag1_set(me_ptr, v)         ((me_ptr)->flag1 = (v))
319 #define _me_flag2_set(me_ptr, v)         ((me_ptr)->flag2 = (v))
320 #define _me_flag3_set(me_ptr, v)         ((me_ptr)->flag3 = (v))
321 #define _me_flag4_set(me_ptr, v)         ((me_ptr)->flag4 = (v))
322 #define _me_subclip_set(me_ptr, v)       ((me_ptr)->sub_clip = (v))
323 #define _me_clearsolid_set(me_ptr, v)    ((me_ptr)->clearsolid = (v))
324 #define _me_rotflr_set(me_ptr, v)        _me_merge_set(me_ptr, v, flr_rotnhgt, MAP_ROT)
325 #define _me_rotceil_set(me_ptr, v)       _me_merge_set(me_ptr, v, ceil_rotnhgt, MAP_ROT)
326 #define _me_hazard_bio_set(me_ptr, v)    _me_merge_set(me_ptr, v, flr_rotnhgt, MAP_HAZARD)
327 #define _me_hazard_rad_set(me_ptr, v)    _me_merge_set(me_ptr, v, ceil_rotnhgt, MAP_HAZARD)
328 #define _me_flicker_set(me_ptr, v)       _me_merge_set(me_ptr, v, flick_qclip, MAP_FLICKER)
329 #define _me_quickclip_set(me_ptr, v)      _me_merge_set(me_ptr, v, flick_qclip, MAP_QUICKCLIP)
330 #define _me_templight_ceil_set(me_ptr, v) _me_merge_set(me_ptr, v, templight, MAP_TLGHT_CEIL)
331 #define _me_templight_flr_set(me_ptr, v)  _me_merge_set(me_ptr, v, templight, MAP_TLGHT_FLOOR)
332 
333 // bind the non _ version of the macros correctly
334 #ifdef MAP_ACCESS_COUNT
335 #include "mapcount.h"
336 #else
337 #include "mapnorm.h"
338 #endif
339 
340 #ifdef __MAP_SRC
341 MapElem *global_map;
342 FullMap *global_fullmap;
343 #else
344 extern MapElem *global_map;
345 extern FullMap *global_fullmap;
346 #endif
347 
348 FullMap *map_create(int xshf, int yshf, int zshf, uchar cyb);
349 uchar map_set_default(FullMap *fmap);
350 void map_init(void);
351 void map_free(void);
352 
353 #define DEFAULT_XSHF 6u
354 #define DEFAULT_YSHF 6u
355 #define DEFAULT_ZSHF 3u
356 
357 #ifndef MAP_RESIZING
358 #define fm_x_sz(fm_ptr)   (1u << DEFAULT_XSHF)
359 #define fm_y_sz(fm_ptr)   (1u << DEFAULT_YSHF)
360 #define fm_x_shft(fm_ptr) (DEFAULT_XSHF)
361 #define fm_y_shft(fm_ptr) (DEFAULT_YSHF)
362 #else
363 #define fm_x_sz(fm_ptr)   ((fm_ptr)->x_size)
364 #define fm_y_sz(fm_ptr)   ((fm_ptr)->y_size)
365 #define fm_x_shft(fm_ptr) ((fm_ptr)->x_shft)
366 #define fm_y_shft(fm_ptr) ((fm_ptr)->y_shft)
367 #endif
368 
369 #ifndef MAP_RESHIFTING
370 #define fm_z_shft(fm_ptr) (DEFAULT_ZSHF)
371 #else
372 #define fm_z_shft(fm_ptr) ((fm_ptr)->z_shft)
373 #endif
374 
375 // look, non stupid non hardcoded defines, how wacky!
376 #define MAP_YSIZE (fm_y_sz(global_fullmap))
377 #define MAP_XSIZE (fm_x_sz(global_fullmap))
378 #define MAP_YSHF  (fm_y_shft(global_fullmap))
379 #define MAP_XSHF  (fm_x_shft(global_fullmap))
380 #define MAP_ZSHF  (fm_z_shft(global_fullmap))
381 
382 #define fm_map(fm_ptr) ((fm_ptr)->map)
383 #define MAP_MAP        (fm_map(global_fullmap))
384 
385 #define FULLMAP_GET_XY(fmap, x, y) ((fmap)->map + (x) + ((y) << fm_x_shft(fmap)))
386 #define MAP_GET_XY(x, y)           FULLMAP_GET_XY(global_fullmap, x, y)
387 
388 // who uses these?
389 #define MAP_ROWS 64
390 #define MAP_COLS 64
391 
392 #define SLOPE_TOTAL 5u
393 #define SLOPE_SHIFT MAP_ZSHF
394 #define SLOPE_SHIFT_U SLOPE_SHIFT
395 #define SLOPE_SHIFT_D (SLOPE_TOTAL - SLOPE_SHIFT_U)
396 
397 #define MAP_SC 256
398 #define MAP_SH 8
399 #define MAP_MK 0xff
400 #define MAP_MS 8
401 
402 #ifdef SAFE_FIX
403 #define obj_coord_from_fix(fixval)    ((fix_int((fixval)) & 0xFF) << 8) + (fix_frac((fixval)) >> 8)
404 #define obj_height_from_fix(fixval)   (fix_int((fixval) * (1 << 8 - SLOPE_SHIFT_D)))
405 #define obj_angle_from_fix(fixval)    (fix_int(fix_div((fixval), fix_2pi) * 255))
406 #define obj_angle_from_fixang(fixval) (fix_div((fixval), FIXANG_PI) >> 9)
407 #define fix_from_obj_coord(sval)      (fix_make((sval) >> 8, ((sval)&0xFF) << 8))
408 #define fix_from_obj_height(oid)      (ACK)
409 #define fix_from_obj_height_val(hval) (ACK)
410 #define fix_from_obj_angle(byteval)   ((255 - fix_make(byteval, 0)) / 64)
411 #else
412 #define obj_coord_from_fix(fixval)    ((int)(fixval) >> 8)
413 #define obj_height_from_fix(fixval)   ((fixval) >> (8 + SLOPE_SHIFT_D))
414 #define obj_angle_from_fix(fixval)    (fix_int(fix_div((fixval), fix_2pi) * 255))
415 #define obj_angle_from_fixang(fixval) (fix_div((fixval), FIXANG_PI) >> 9)
416 #define fix_from_obj_coord(sval)      ((fix)(sval) << 8)
417 #define fix_from_obj_height(oid)      ((fix)objs[(oid)].loc.z << (8u + SLOPE_SHIFT_D))
418 #define fix_from_obj_height_val(hval) ((hval) << (8 + SLOPE_SHIFT_D))
419 #define fix_from_obj_angle(byteval)   ((255 - fix_make(byteval, 0)) / 64)
420 #endif
421 
422 #define fix_inv2pi                        (fix_make(0, 10430))
423 #define obj_angle_from_phys(fixinrad)     (64 - (((ushort)fix_div(fixinrad, fix_2pi)) >> 8))
424 #define phys_angle_from_obj(citang)       (fix_mul((64 - citang) << 16, fix_2pi) >> 8)
425 #define phys_angle_from_fixang(fang)      (fixang_to_fixrad(FIXANG_PI/2 - (fang))
426 #define fixang_from_phys_angle(fixdingus) (FIXANG_PI / 2 - fixrad_to_fixang(fixdingus))
427 
428 // this stuff needs a safe fix version
429 #define fix_from_map_height(mht) (fix_make((mht), 0) >> SLOPE_SHIFT)
430 #define map_height_from_fix(fht) (fix_int(fht << SLOPE_SHIFT))
431 
432 #endif // __MAP_H
433