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