1 /*
2 OVERHEAD_MAP.C
3
4 Copyright (C) 1991-2001 and beyond by Bungie Studios, Inc.
5 and the "Aleph One" developers.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 This license is contained in the file "COPYING",
18 which is included with this source code; it is available online at
19 http://www.gnu.org/licenses/gpl.html
20
21 Friday, June 10, 1994 2:53:51 AM
22
23 Saturday, June 11, 1994 1:27:58 AM
24 the portable parts of this file should be moved into RENDER.C
25 Friday, August 12, 1994 7:57:00 PM
26 invisible polygons and lines are never drawn.
27 Thursday, September 8, 1994 8:19:15 PM (Jason)
28 changed behavior of landscaped lines
29 Monday, October 24, 1994 4:35:38 PM (Jason)
30 only draw the checkpoint at the origin.
31 Monday, October 31, 1994 3:52:00 PM (Jason)
32 draw name of map on overhead map, last.
33 Monday, August 28, 1995 1:44:43 PM (Jason)
34 toward portability; removed clip region from _render_overhead_map.
35
36 Feb 3, 2000 (Loren Petrich):
37 Jjaro-goo color is the same as the sewage color
38
39 Feb 4, 2000 (Loren Petrich):
40 Changed halt() to assert(false) for better debugging
41
42 Feb 18, 2000 (Loren Petrich):
43 Made VacBobs display properly
44
45 May 2, 2000 (Loren Petrich):
46 Added XML setting of overhead-map-display parameters;
47 also imported the number of paths for displaying them.
48
49 Can display alien monsters, items, projectiles, and paths.
50
51 Jul 4, 2000 (Loren Petrich):
52 Made XML map-display settings compatible with the map cheat.
53
54 Jul 8, 2000 (Loren Petrich):
55 Added support for OpenGL rendering;
56 in these routines, it's the global flag OGL_MapActive,
57 which indicates whether to do so in the overhead map
58
59 Jul 16, 2000 (Loren Petrich):
60 Added begin/end pairs for polygons and lines,
61 so that caching of them can be more efficient (important for OpenGL)
62
63 [Loren Petrich: notes for this file moved here]
64 OVERHEAD_MAP_MAC.C
65 Monday, August 28, 1995 1:41:36 PM (Jason)
66
67 Feb 3, 2000 (Loren Petrich):
68 Jjaro-goo color is the same as the sewage color
69
70 Feb 4, 2000 (Loren Petrich):
71 Changed halt() to assert(false) for better debugging
72
73 Jul 8, 2000 (Loren Petrich):
74 Added support for OpenGL rendering, in the form of calls to OpenGL versions
75
76 Jul 16, 2000 (Loren Petrich):
77 Added begin/end pairs for polygons and lines,
78 so that caching of them can be more efficient (important for OpenGL)
79
80 Aug 3, 2000 (Loren Petrich):
81 All the code here has been transferred to either OverheadMapRenderer.c/h or OverheadMap_QuickDraw.c/h
82 [End notes for overhead_map_macintosh.c]
83
84 Nov 12, 2000 (Loren Petrich):
85 Added automap reset function and XML parsing
86 */
87
88 #include "cseries.h"
89
90 #include "shell.h" // for _get_player_color
91
92 #include "map.h"
93 #include "monsters.h"
94 #include "overhead_map.h"
95 #include "player.h"
96 #include "render.h"
97 #include "flood_map.h"
98 #include "platforms.h"
99 #include "media.h"
100 #include "InfoTree.h"
101
102 // Object-oriented setup of overhead-map rendering
103 #include "OverheadMap_SDL.h"
104 #include "OverheadMap_OGL.h"
105
106 #include <string.h>
107 #include <stdlib.h>
108
109 #ifdef DEBUG
110 //#define PATH_DEBUG
111 //#define RENDER_DEBUG
112 #endif
113
114 #ifdef RENDER_DEBUG
115 extern struct view_data *world_view;
116 #endif
117
118 // Constants moved out to OverheadMapRender.h
119 // Render flags now in OverheadMapRender.c
120
121
122 // The configuration data
123 static OvhdMap_CfgDataStruct OvhdMap_ConfigData =
124 {
125 // Polygon colors
126 {
127 {0, 12000, 0}, // Plain polygon
128 {30000, 0, 0}, // Platform
129 {14*256, 37*256, 63*256}, // Water
130 {76*256, 27*256, 0}, // Lava
131 {70*256, 90*256, 0}, // Sewage
132 {70*256, 90*256, 0}, // JjaroGoo
133 {137*256, 0, 137*256}, // PfhorSlime
134 {0, 12000, 0}, // Hill
135 {76*256, 27*256, 0}, // Minor Damage
136 {137*256, 0, 137*256}, // Major Damage
137 {0, 12000, 0} // Teleporter
138 },
139 // Line definitions (color, 4 widths)
140 {
141 {{0, 65535, 0}, {1, 2, 2, 4}}, // Solid
142 {{0, 40000, 0}, {1, 1, 1, 2}}, // Elevation
143 {{65535, 0, 0}, {1, 2, 2, 4}} // Control-Panel
144 },
145 // Thing definitions (color, shape, 4 radii)
146 {
147 {{0, 0, 65535}, _rectangle_thing, {1, 2, 4, 8}}, /* civilian */
148 {{65535, 0, 0}, _rectangle_thing, {1, 2, 4, 8}}, /* non-player monster */
149 {{65535, 65535, 65535}, _rectangle_thing, {1, 2, 3, 4}}, /* item */
150 {{65535, 65535, 0}, _rectangle_thing, {1, 1, 2, 3}}, /* projectiles */
151 {{65535, 0, 0}, _circle_thing, {8, 16, 16, 16}} // LP note: this is for checkpoint locations
152 },
153 // Live-monster type assignments
154 {
155 // Marine
156 _civilian_thing,
157 // Ticks
158 _monster_thing,
159 _monster_thing,
160 _monster_thing,
161 // S'pht
162 _monster_thing,
163 _monster_thing,
164 _monster_thing,
165 _monster_thing,
166 // Pfhor
167 _monster_thing,
168 _monster_thing,
169 _monster_thing,
170 _monster_thing,
171 // Bob
172 _civilian_thing,
173 _civilian_thing,
174 _civilian_thing,
175 _civilian_thing,
176 // Drone
177 _monster_thing,
178 _monster_thing,
179 _monster_thing,
180 _monster_thing,
181 _monster_thing,
182 // Cyborg
183 _monster_thing,
184 _monster_thing,
185 _monster_thing,
186 _monster_thing,
187 // Enforcer
188 _monster_thing,
189 _monster_thing,
190 // Hunter
191 _monster_thing,
192 _monster_thing,
193 // Trooper
194 _monster_thing,
195 _monster_thing,
196 // Big Cyborg, Hunter
197 _monster_thing,
198 _monster_thing,
199 // F'lickta
200 _monster_thing,
201 _monster_thing,
202 _monster_thing,
203 // S'pht'Kr
204 _monster_thing,
205 _monster_thing,
206 // Juggernauts
207 _monster_thing,
208 _monster_thing,
209 // Tiny ones
210 _monster_thing,
211 _monster_thing,
212 _monster_thing,
213 // VacBobs
214 _civilian_thing,
215 _civilian_thing,
216 _civilian_thing,
217 _civilian_thing,
218 },
219 // Dead-monster type assignments
220 {
221 NONE, // Interface (what one sees in the HUD)
222 NONE, // Weapons in Hand
223
224 _monster_thing, // Juggernaut
225 _monster_thing, // Tick
226 _monster_thing, // Explosion effects
227 _monster_thing, // Hunter
228 NONE, // Player
229
230 _monster_thing, // Items
231 _monster_thing, // Trooper
232 _monster_thing, // Fighter
233 _monster_thing, // S'pht'Kr
234 _monster_thing, // F'lickta
235
236 _civilian_thing, // Bob
237 _civilian_thing, // VacBob
238 _monster_thing, // Enforcer
239 _monster_thing, // Drone
240 _monster_thing, // S'pht
241
242 NONE, // Water
243 NONE, // Lava
244 NONE, // Sewage
245 NONE, // Jjaro
246 NONE, // Pfhor
247
248 NONE, // Water Scenery
249 NONE, // Lava Scenery
250 NONE, // Sewage Scenery
251 NONE, // Jjaro Scenery
252 NONE, // Pfhor Scenery
253
254 NONE, // Day
255 NONE, // Night
256 NONE, // Moon
257 NONE, // Outer Space
258
259 _monster_thing // Cyborg
260 },
261 // Player-entity definition
262 {16, 10, (7*NUMBER_OF_ANGLES)/20},
263 // Annotations (color, 4 fonts)
264 {
265 {{0, 65535, 0},
266 {
267 {"Monaco", 5, styleBold, 0, "#4"},
268 {"Monaco", 9, styleBold, 0, "#4"},
269 {"Monaco", 12, styleBold, 0, "#4"},
270 {"Monaco", 18, styleBold, 0, "#4"},
271 }}
272 },
273 // Map name (color, font)
274 {{0, 65535, 0}, {"Monaco", 18, styleNormal, 0, "#4"}, 25},
275 // Path color
276 {65535, 65535, 65535},
277 // What to show (aliens, items, projectiles, paths)
278 false, false, false, false
279 };
280 static bool MapFontsInited = false;
281
282 // Is OpenGL rendering of the map currently active?
283 // Set this from outside, because we want to make an OpenGL rendering for the main view,
284 // yet a software rendering for an in-terminal checkpoint view
285 bool OGL_MapActive = false;
286
287 // Software rendering
288 static OverheadMap_SDL_Class OverheadMap_SW;
289 // OpenGL rendering
290 #ifdef HAVE_OPENGL
291 static OverheadMap_OGL_Class OverheadMap_OGL;
292 #endif
293
294 // Overhead-map-rendering mode
295 enum {
296 OverheadMap_Normal,
297 OverheadMap_CurrentlyVisible,
298 OverheadMap_All,
299 NUMBER_OF_OVERHEAD_MAP_MODES
300 };
301 static short OverheadMapMode = OverheadMap_Normal;
302
303
304 /* ---------- code */
305 // LP: most of it has been moved into OverheadMapRenderer.c
306
InitMapFonts()307 static void InitMapFonts()
308 {
309 // Init the fonts the first time through
310 if (!MapFontsInited)
311 {
312 for (int i=0; i<NUMBER_OF_ANNOTATION_DEFINITIONS; i++)
313 {
314 annotation_definition& NoteDef = OvhdMap_ConfigData.annotation_definitions[i];
315 for (int j=0; j<NUMBER_OF_ANNOTATION_SIZES; j++)
316 NoteDef.Fonts[j].Init();
317 }
318 OvhdMap_ConfigData.map_name_data.Font.Init();
319 MapFontsInited = true;
320 }
321 }
322
_render_overhead_map(struct overhead_map_data * data)323 void _render_overhead_map(
324 struct overhead_map_data *data)
325 {
326 InitMapFonts();
327
328 // Select which kind of rendering (OpenGL or software)
329 OverheadMapClass *OvhdMapPtr;
330 #ifdef HAVE_OPENGL
331 if (OGL_MapActive)
332 OvhdMapPtr = &OverheadMap_OGL;
333 else
334 #endif
335 OvhdMapPtr = &OverheadMap_SW;
336
337 // Do the rendering
338 OvhdMapPtr->ConfigPtr = &OvhdMap_ConfigData;
339 OvhdMapPtr->Render(*data);
340 }
341
342
ResetOverheadMap()343 void ResetOverheadMap()
344 {
345 // Default: nothing (mapping is cumulative)
346 switch(OverheadMapMode)
347 {
348 case OverheadMap_CurrentlyVisible:
349 // No previous visibility is carried over
350 memset(automap_lines, 0, (dynamic_world->line_count/8+((dynamic_world->line_count%8)?1:0)*sizeof(byte)));
351 memset(automap_polygons, 0, (dynamic_world->polygon_count/8+((dynamic_world->polygon_count%8)?1:0)*sizeof(byte)));
352
353 break;
354
355 case OverheadMap_All:
356 // Everything is assumed visible
357 memset(automap_lines, 0xff, (dynamic_world->line_count/8+((dynamic_world->line_count%8)?1:0)*sizeof(byte)));
358 memset(automap_polygons, 0xff, (dynamic_world->polygon_count/8+((dynamic_world->polygon_count%8)?1:0)*sizeof(byte)));
359
360 break;
361 };
362 }
363
364
365
366 // XML elements for parsing motion-sensor specification
367
368 // Subclassed to set the color objects appropriately
369 const int TOTAL_NUMBER_OF_COLORS =
370 NUMBER_OF_POLYGON_COLORS + NUMBER_OF_LINE_DEFINITIONS +
371 NUMBER_OF_THINGS + NUMBER_OF_ANNOTATION_DEFINITIONS + 2;
372
373 const int TOTAL_NUMBER_OF_FONTS =
374 NUMBER_OF_ANNOTATION_DEFINITIONS*(OVERHEAD_MAP_MAXIMUM_SCALE-OVERHEAD_MAP_MINIMUM_SCALE + 1) + 1;
375
376 static OvhdMap_CfgDataStruct original_OvhdMap_ConfigData = OvhdMap_ConfigData;
377 static short original_OverheadMapMode = OverheadMapMode;
378
reset_mml_overhead_map()379 void reset_mml_overhead_map()
380 {
381 OverheadMapMode = original_OverheadMapMode;
382 OvhdMap_ConfigData = original_OvhdMap_ConfigData;
383 }
384
parse_mml_overhead_map(const InfoTree & root)385 void parse_mml_overhead_map(const InfoTree& root)
386 {
387 root.read_indexed("mode", OverheadMapMode, NUMBER_OF_OVERHEAD_MAP_MODES);
388 root.read_attr("title_offset", OvhdMap_ConfigData.map_name_data.offset_down);
389
390 BOOST_FOREACH(InfoTree assign, root.children_named("assign_live"))
391 {
392 int16 monster;
393 if (!assign.read_indexed("monster", monster, NUMBER_OF_MONSTER_TYPES))
394 continue;
395 assign.read_attr_bounded<int16>("type", OvhdMap_ConfigData.monster_displays[monster], -1, 1);
396 }
397
398 BOOST_FOREACH(InfoTree assign, root.children_named("assign_dead"))
399 {
400 int16 coll;
401 if (!assign.read_indexed("coll", coll, NUMBER_OF_COLLECTIONS))
402 continue;
403 assign.read_attr_bounded<int16>("type", OvhdMap_ConfigData.dead_monster_displays[coll], -1, 1);
404 }
405
406 BOOST_FOREACH(InfoTree child, root.children_named("aliens"))
407 {
408 child.read_attr("on", OvhdMap_ConfigData.ShowAliens);
409 }
410 BOOST_FOREACH(InfoTree child, root.children_named("items"))
411 {
412 child.read_attr("on", OvhdMap_ConfigData.ShowItems);
413 }
414 BOOST_FOREACH(InfoTree child, root.children_named("projectiles"))
415 {
416 child.read_attr("on", OvhdMap_ConfigData.ShowProjectiles);
417 }
418 BOOST_FOREACH(InfoTree child, root.children_named("paths"))
419 {
420 child.read_attr("on", OvhdMap_ConfigData.ShowPaths);
421 }
422
423 BOOST_FOREACH(InfoTree line, root.children_named("line_width"))
424 {
425 int16 index;
426 if (!line.read_indexed("index", index, NUMBER_OF_LINE_DEFINITIONS))
427 continue;
428
429 int16 scale;
430 if (!line.read_indexed("scale", scale, OVERHEAD_MAP_MAXIMUM_SCALE-OVERHEAD_MAP_MINIMUM_SCALE))
431 continue;
432
433 line.read_attr("width", OvhdMap_ConfigData.line_definitions[index].pen_sizes[scale]);
434 }
435
436 BOOST_FOREACH(InfoTree color, root.children_named("color"))
437 {
438 int16 index;
439 if (!color.read_indexed("index", index, TOTAL_NUMBER_OF_COLORS))
440 continue;
441
442 if (index < NUMBER_OF_OLD_POLYGON_COLORS)
443 {
444 color.read_color(OvhdMap_ConfigData.polygon_colors[index]);
445 continue;
446 }
447 index -= NUMBER_OF_OLD_POLYGON_COLORS;
448
449 if (index < NUMBER_OF_LINE_DEFINITIONS)
450 {
451 color.read_color(OvhdMap_ConfigData.line_definitions[index].color);
452 continue;
453 }
454 index -= NUMBER_OF_LINE_DEFINITIONS;
455
456 if (index < NUMBER_OF_THINGS)
457 {
458 color.read_color(OvhdMap_ConfigData.thing_definitions[index].color);
459 continue;
460 }
461 index -= NUMBER_OF_THINGS;
462
463 if (index < NUMBER_OF_ANNOTATION_DEFINITIONS)
464 {
465 color.read_color(OvhdMap_ConfigData.annotation_definitions[index].color);
466 continue;
467 }
468 index -= NUMBER_OF_ANNOTATION_DEFINITIONS;
469
470 if (index == 0)
471 {
472 color.read_color(OvhdMap_ConfigData.map_name_data.color);
473 continue;
474 }
475 --index;
476
477 if (index == 0)
478 {
479 color.read_color(OvhdMap_ConfigData.path_color);
480 continue;
481 }
482 --index;
483
484 index += NUMBER_OF_OLD_POLYGON_COLORS;
485 if (index < NUMBER_OF_POLYGON_COLORS)
486 {
487 color.read_color(OvhdMap_ConfigData.polygon_colors[index]);
488 continue;
489 }
490 index -= NUMBER_OF_POLYGON_COLORS;
491 }
492
493 BOOST_FOREACH(InfoTree font, root.children_named("font"))
494 {
495 int16 index;
496 if (!font.read_indexed("index", index, TOTAL_NUMBER_OF_FONTS))
497 continue;
498
499 bool found = false;
500 for (int i = 0; !found && i < NUMBER_OF_ANNOTATION_DEFINITIONS; ++i)
501 {
502 if (index < NUMBER_OF_ANNOTATION_SIZES)
503 {
504 font.read_font(OvhdMap_ConfigData.annotation_definitions[i].Fonts[index]);
505 found = true;
506 }
507 index -= NUMBER_OF_ANNOTATION_SIZES;
508 }
509 if (found)
510 continue;
511
512 if (index == 0)
513 {
514 font.read_font(OvhdMap_ConfigData.map_name_data.Font);
515 continue;
516 }
517 --index;
518 }
519 }
520