aboutsummaryrefslogtreecommitdiff
path: root/src/am_map.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/am_map.c')
-rw-r--r--src/am_map.c1585
1 files changed, 1585 insertions, 0 deletions
diff --git a/src/am_map.c b/src/am_map.c
new file mode 100644
index 0000000..040c40b
--- /dev/null
+++ b/src/am_map.c
@@ -0,0 +1,1585 @@
1/* Emacs style mode select -*- C++ -*-
2 *-----------------------------------------------------------------------------
3 *
4 *
5 * PrBoom: a Doom port merged with LxDoom and LSDLDoom
6 * based on BOOM, a modified and improved DOOM engine
7 * Copyright (C) 1999 by
8 * id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
9 * Copyright (C) 1999-2000 by
10 * Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
11 * Copyright 2005, 2006 by
12 * Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
27 * 02111-1307, USA.
28 *
29 * DESCRIPTION:
30 * the automap code
31 *
32 *-----------------------------------------------------------------------------
33 */
34
35#ifdef HAVE_CONFIG_H
36#include "config.h"
37#endif
38
39#include "doomstat.h"
40#include "st_stuff.h"
41#include "r_main.h"
42#include "p_setup.h"
43#include "p_maputl.h"
44#include "w_wad.h"
45#include "v_video.h"
46#include "p_spec.h"
47#include "am_map.h"
48#include "dstrings.h"
49#include "d_deh.h" // Ty 03/27/98 - externalizations
50#include "lprintf.h" // jff 08/03/98 - declaration of lprintf
51#include "g_game.h"
52
53//jff 1/7/98 default automap colors added
54int mapcolor_back; // map background
55int mapcolor_grid; // grid lines color
56int mapcolor_wall; // normal 1s wall color
57int mapcolor_fchg; // line at floor height change color
58int mapcolor_cchg; // line at ceiling height change color
59int mapcolor_clsd; // line at sector with floor=ceiling color
60int mapcolor_rkey; // red key color
61int mapcolor_bkey; // blue key color
62int mapcolor_ykey; // yellow key color
63int mapcolor_rdor; // red door color (diff from keys to allow option)
64int mapcolor_bdor; // blue door color (of enabling one but not other )
65int mapcolor_ydor; // yellow door color
66int mapcolor_tele; // teleporter line color
67int mapcolor_secr; // secret sector boundary color
68int mapcolor_exit; // jff 4/23/98 add exit line color
69int mapcolor_unsn; // computer map unseen line color
70int mapcolor_flat; // line with no floor/ceiling changes
71int mapcolor_sprt; // general sprite color
72int mapcolor_item; // item sprite color
73int mapcolor_frnd; // friendly sprite color
74int mapcolor_enemy; // enemy sprite color
75int mapcolor_hair; // crosshair color
76int mapcolor_sngl; // single player arrow color
77int mapcolor_plyr[4] = { 112, 88, 64, 32 }; // colors for player arrows in multiplayer
78
79//jff 3/9/98 add option to not show secret sectors until entered
80int map_secret_after;
81//jff 4/3/98 add symbols for "no-color" for disable and "black color" for black
82#define NC 0
83#define BC 247
84
85// drawing stuff
86#define FB 0
87
88// scale on entry
89#define INITSCALEMTOF (.2*FRACUNIT)
90// how much the automap moves window per tic in frame-buffer coordinates
91// moves 140 pixels in 1 second
92#define F_PANINC 4
93// how much zoom-in per tic
94// goes to 2x in 1 second
95#define M_ZOOMIN ((int) (1.02*FRACUNIT))
96// how much zoom-out per tic
97// pulls out to 0.5x in 1 second
98#define M_ZOOMOUT ((int) (FRACUNIT/1.02))
99
100#define PLAYERRADIUS (16*(1<<MAPBITS)) // e6y
101
102// translates between frame-buffer and map distances
103#define FTOM(x) FixedMul(((x)<<16),scale_ftom)
104#define MTOF(x) (FixedMul((x),scale_mtof)>>16)
105// translates between frame-buffer and map coordinates
106#define CXMTOF(x) (f_x + MTOF((x)-m_x))
107#define CYMTOF(y) (f_y + (f_h - MTOF((y)-m_y)))
108
109typedef struct
110{
111 mpoint_t a, b;
112} mline_t;
113
114//
115// The vector graphics for the automap.
116// A line drawing of the player pointing right,
117// starting from the middle.
118//
119#define R ((8*PLAYERRADIUS)/7)
120mline_t player_arrow[] =
121{
122 { { -R+R/8, 0 }, { R, 0 } }, // -----
123 { { R, 0 }, { R-R/2, R/4 } }, // ----->
124 { { R, 0 }, { R-R/2, -R/4 } },
125 { { -R+R/8, 0 }, { -R-R/8, R/4 } }, // >---->
126 { { -R+R/8, 0 }, { -R-R/8, -R/4 } },
127 { { -R+3*R/8, 0 }, { -R+R/8, R/4 } }, // >>--->
128 { { -R+3*R/8, 0 }, { -R+R/8, -R/4 } }
129};
130#undef R
131#define NUMPLYRLINES (sizeof(player_arrow)/sizeof(mline_t))
132
133#define R ((8*PLAYERRADIUS)/7)
134mline_t cheat_player_arrow[] =
135{ // killough 3/22/98: He's alive, Jim :)
136 { { -R+R/8, 0 }, { R, 0 } }, // -----
137 { { R, 0 }, { R-R/2, R/4 } }, // ----->
138 { { R, 0 }, { R-R/2, -R/4 } },
139 { { -R+R/8, 0 }, { -R-R/8, R/4 } }, // >---->
140 { { -R+R/8, 0 }, { -R-R/8, -R/4 } },
141 { { -R+3*R/8, 0 }, { -R+R/8, R/4 } }, // >>--->
142 { { -R+3*R/8, 0 }, { -R+R/8, -R/4 } },
143 { { -R/10-R/6, R/4}, {-R/10-R/6, -R/4} }, // J
144 { { -R/10-R/6, -R/4}, {-R/10-R/6-R/8, -R/4} },
145 { { -R/10-R/6-R/8, -R/4}, {-R/10-R/6-R/8, -R/8} },
146 { { -R/10, R/4}, {-R/10, -R/4}}, // F
147 { { -R/10, R/4}, {-R/10+R/8, R/4}},
148 { { -R/10+R/4, R/4}, {-R/10+R/4, -R/4}}, // F
149 { { -R/10+R/4, R/4}, {-R/10+R/4+R/8, R/4}},
150};
151#undef R
152#define NUMCHEATPLYRLINES (sizeof(cheat_player_arrow)/sizeof(mline_t))
153
154#define R (FRACUNIT)
155mline_t triangle_guy[] =
156{
157{ { (fixed_t)(-.867*R), (fixed_t)(-.5*R) }, { (fixed_t)( .867*R), (fixed_t)(-.5*R) } },
158{ { (fixed_t)( .867*R), (fixed_t)(-.5*R) }, { (fixed_t)(0 ), (fixed_t)( R) } },
159{ { (fixed_t)(0 ), (fixed_t)( R) }, { (fixed_t)(-.867*R), (fixed_t)(-.5*R) } }
160};
161#undef R
162#define NUMTRIANGLEGUYLINES (sizeof(triangle_guy)/sizeof(mline_t))
163
164//jff 1/5/98 new symbol for keys on automap
165#define R (FRACUNIT)
166mline_t cross_mark[] =
167{
168 { { -R, 0 }, { R, 0} },
169 { { 0, -R }, { 0, R } },
170};
171#undef R
172#define NUMCROSSMARKLINES (sizeof(cross_mark)/sizeof(mline_t))
173//jff 1/5/98 end of new symbol
174
175#define R (FRACUNIT)
176mline_t thintriangle_guy[] =
177{
178{ { (fixed_t)(-.5*R), (fixed_t)(-.7*R) }, { (fixed_t)( R), (fixed_t)( 0) } },
179{ { (fixed_t)( R), (fixed_t)( 0) }, { (fixed_t)(-.5*R), (fixed_t)( .7*R) } },
180{ { (fixed_t)(-.5*R), (fixed_t)( .7*R) }, { (fixed_t)(-.5*R), (fixed_t)(-.7*R) } }
181};
182#undef R
183#define NUMTHINTRIANGLEGUYLINES (sizeof(thintriangle_guy)/sizeof(mline_t))
184
185int ddt_cheating = 0; // killough 2/7/98: make global, rename to ddt_*
186
187static int leveljuststarted = 1; // kluge until AM_LevelInit() is called
188
189enum automapmode_e automapmode; // Mode that the automap is in
190
191// location of window on screen
192static int f_x;
193static int f_y;
194
195// size of window on screen
196static int f_w;
197static int f_h;
198
199static mpoint_t m_paninc; // how far the window pans each tic (map coords)
200static fixed_t mtof_zoommul; // how far the window zooms each tic (map coords)
201static fixed_t ftom_zoommul; // how far the window zooms each tic (fb coords)
202
203static fixed_t m_x, m_y; // LL x,y window location on the map (map coords)
204static fixed_t m_x2, m_y2; // UR x,y window location on the map (map coords)
205
206//
207// width/height of window on map (map coords)
208//
209static fixed_t m_w;
210static fixed_t m_h;
211
212// based on level size
213static fixed_t min_x;
214static fixed_t min_y;
215static fixed_t max_x;
216static fixed_t max_y;
217
218static fixed_t max_w; // max_x-min_x,
219static fixed_t max_h; // max_y-min_y
220
221// based on player size
222static fixed_t min_w;
223static fixed_t min_h;
224
225
226static fixed_t min_scale_mtof; // used to tell when to stop zooming out
227static fixed_t max_scale_mtof; // used to tell when to stop zooming in
228
229// old stuff for recovery later
230static fixed_t old_m_w, old_m_h;
231static fixed_t old_m_x, old_m_y;
232
233// old location used by the Follower routine
234static mpoint_t f_oldloc;
235
236// used by MTOF to scale from map-to-frame-buffer coords
237static fixed_t scale_mtof = (fixed_t)INITSCALEMTOF;
238// used by FTOM to scale from frame-buffer-to-map coords (=1/scale_mtof)
239static fixed_t scale_ftom;
240
241static player_t *plr; // the player represented by an arrow
242
243// killough 2/22/98: Remove limit on automap marks,
244// and make variables external for use in savegames.
245
246mpoint_t *markpoints = NULL; // where the points are
247int markpointnum = 0; // next point to be assigned (also number of points now)
248int markpointnum_max = 0; // killough 2/22/98
249
250static boolean stopped = true;
251
252//
253// AM_activateNewScale()
254//
255// Changes the map scale after zooming or translating
256//
257// Passed nothing, returns nothing
258//
259static void AM_activateNewScale(void)
260{
261 m_x += m_w/2;
262 m_y += m_h/2;
263 m_w = FTOM(f_w);
264 m_h = FTOM(f_h);
265 m_x -= m_w/2;
266 m_y -= m_h/2;
267 m_x2 = m_x + m_w;
268 m_y2 = m_y + m_h;
269}
270
271//
272// AM_saveScaleAndLoc()
273//
274// Saves the current center and zoom
275// Affects the variables that remember old scale and loc
276//
277// Passed nothing, returns nothing
278//
279static void AM_saveScaleAndLoc(void)
280{
281 old_m_x = m_x;
282 old_m_y = m_y;
283 old_m_w = m_w;
284 old_m_h = m_h;
285}
286
287//
288// AM_restoreScaleAndLoc()
289//
290// restores the center and zoom from locally saved values
291// Affects global variables for location and scale
292//
293// Passed nothing, returns nothing
294//
295static void AM_restoreScaleAndLoc(void)
296{
297 m_w = old_m_w;
298 m_h = old_m_h;
299 if (!(automapmode & am_follow))
300 {
301 m_x = old_m_x;
302 m_y = old_m_y;
303 }
304 else
305 {
306 m_x = (plr->mo->x >> FRACTOMAPBITS) - m_w/2;//e6y
307 m_y = (plr->mo->y >> FRACTOMAPBITS) - m_h/2;//e6y
308 }
309 m_x2 = m_x + m_w;
310 m_y2 = m_y + m_h;
311
312 // Change the scaling multipliers
313 scale_mtof = FixedDiv(f_w<<FRACBITS, m_w);
314 scale_ftom = FixedDiv(FRACUNIT, scale_mtof);
315}
316
317//
318// AM_addMark()
319//
320// Adds a marker at the current location
321// Affects global variables for marked points
322//
323// Passed nothing, returns nothing
324//
325static void AM_addMark(void)
326{
327 // killough 2/22/98:
328 // remove limit on automap marks
329
330 if (markpointnum >= markpointnum_max)
331 markpoints = realloc(markpoints,
332 (markpointnum_max = markpointnum_max ?
333 markpointnum_max*2 : 16) * sizeof(*markpoints));
334
335 markpoints[markpointnum].x = m_x + m_w/2;
336 markpoints[markpointnum].y = m_y + m_h/2;
337 markpointnum++;
338}
339
340//
341// AM_findMinMaxBoundaries()
342//
343// Determines bounding box of all vertices,
344// sets global variables controlling zoom range.
345//
346// Passed nothing, returns nothing
347//
348static void AM_findMinMaxBoundaries(void)
349{
350 int i;
351 fixed_t a;
352 fixed_t b;
353
354 min_x = min_y = INT_MAX;
355 max_x = max_y = -INT_MAX;
356
357 for (i=0;i<numvertexes;i++)
358 {
359 if (vertexes[i].x < min_x)
360 min_x = vertexes[i].x;
361 else if (vertexes[i].x > max_x)
362 max_x = vertexes[i].x;
363
364 if (vertexes[i].y < min_y)
365 min_y = vertexes[i].y;
366 else if (vertexes[i].y > max_y)
367 max_y = vertexes[i].y;
368 }
369
370 max_w = (max_x >>= FRACTOMAPBITS) - (min_x >>= FRACTOMAPBITS);//e6y
371 max_h = (max_y >>= FRACTOMAPBITS) - (min_y >>= FRACTOMAPBITS);//e6y
372
373 min_w = 2*PLAYERRADIUS; // const? never changed?
374 min_h = 2*PLAYERRADIUS;
375
376 a = FixedDiv(f_w<<FRACBITS, max_w);
377 b = FixedDiv(f_h<<FRACBITS, max_h);
378
379 min_scale_mtof = a < b ? a : b;
380 max_scale_mtof = FixedDiv(f_h<<FRACBITS, 2*PLAYERRADIUS);
381}
382
383//
384// AM_changeWindowLoc()
385//
386// Moves the map window by the global variables m_paninc.x, m_paninc.y
387//
388// Passed nothing, returns nothing
389//
390static void AM_changeWindowLoc(void)
391{
392 if (m_paninc.x || m_paninc.y)
393 {
394 automapmode &= ~am_follow;
395 f_oldloc.x = INT_MAX;
396 }
397
398 m_x += m_paninc.x;
399 m_y += m_paninc.y;
400
401 if (m_x + m_w/2 > max_x)
402 m_x = max_x - m_w/2;
403 else if (m_x + m_w/2 < min_x)
404 m_x = min_x - m_w/2;
405
406 if (m_y + m_h/2 > max_y)
407 m_y = max_y - m_h/2;
408 else if (m_y + m_h/2 < min_y)
409 m_y = min_y - m_h/2;
410
411 m_x2 = m_x + m_w;
412 m_y2 = m_y + m_h;
413}
414
415
416//
417// AM_initVariables()
418//
419// Initialize the variables for the automap
420//
421// Affects the automap global variables
422// Status bar is notified that the automap has been entered
423// Passed nothing, returns nothing
424//
425static void AM_initVariables(void)
426{
427 int pnum;
428 static event_t st_notify = { ev_keyup, AM_MSGENTERED, 0, 0 };
429
430 automapmode |= am_active;
431
432 f_oldloc.x = INT_MAX;
433
434 m_paninc.x = m_paninc.y = 0;
435 ftom_zoommul = FRACUNIT;
436 mtof_zoommul = FRACUNIT;
437
438 m_w = FTOM(f_w);
439 m_h = FTOM(f_h);
440
441 // find player to center on initially
442 if (!playeringame[pnum = consoleplayer])
443 for (pnum=0;pnum<MAXPLAYERS;pnum++)
444 if (playeringame[pnum])
445 break;
446
447 plr = &players[pnum];
448 m_x = (plr->mo->x >> FRACTOMAPBITS) - m_w/2;//e6y
449 m_y = (plr->mo->y >> FRACTOMAPBITS) - m_h/2;//e6y
450 AM_changeWindowLoc();
451
452 // for saving & restoring
453 old_m_x = m_x;
454 old_m_y = m_y;
455 old_m_w = m_w;
456 old_m_h = m_h;
457
458 // inform the status bar of the change
459 ST_Responder(&st_notify);
460}
461
462//
463// AM_loadPics()
464//
465static void AM_loadPics(void)
466{
467 // cph - mark numbers no longer needed cached
468}
469
470//
471// AM_unloadPics()
472//
473static void AM_unloadPics(void)
474{
475 // cph - mark numbers no longer needed cached
476}
477
478//
479// AM_clearMarks()
480//
481// Sets the number of marks to 0, thereby clearing them from the display
482//
483// Affects the global variable markpointnum
484// Passed nothing, returns nothing
485//
486void AM_clearMarks(void)
487{
488 markpointnum = 0;
489}
490
491//
492// AM_LevelInit()
493//
494// Initialize the automap at the start of a new level
495// should be called at the start of every level
496//
497// Passed nothing, returns nothing
498// Affects automap's global variables
499//
500// CPhipps - get status bar height from status bar code
501static void AM_LevelInit(void)
502{
503 leveljuststarted = 0;
504
505 f_x = f_y = 0;
506 f_w = SCREENWIDTH; // killough 2/7/98: get rid of finit_ vars
507 f_h = SCREENHEIGHT-ST_SCALED_HEIGHT;// to allow runtime setting of width/height
508
509 AM_findMinMaxBoundaries();
510 scale_mtof = FixedDiv(min_scale_mtof, (int) (0.7*FRACUNIT));
511 if (scale_mtof > max_scale_mtof)
512 scale_mtof = min_scale_mtof;
513 scale_ftom = FixedDiv(FRACUNIT, scale_mtof);
514}
515
516//
517// AM_Stop()
518//
519// Cease automap operations, unload patches, notify status bar
520//
521// Passed nothing, returns nothing
522//
523void AM_Stop (void)
524{
525 static event_t st_notify = { 0, ev_keyup, AM_MSGEXITED, 0 };
526
527 AM_unloadPics();
528 automapmode &= ~am_active;
529 ST_Responder(&st_notify);
530 stopped = true;
531}
532
533//
534// AM_Start()
535//
536// Start up automap operations,
537// if a new level, or game start, (re)initialize level variables
538// init map variables
539// load mark patches
540//
541// Passed nothing, returns nothing
542//
543void AM_Start(void)
544{
545 static int lastlevel = -1, lastepisode = -1;
546
547 if (!stopped)
548 AM_Stop();
549 stopped = false;
550 if (lastlevel != gamemap || lastepisode != gameepisode)
551 {
552 AM_LevelInit();
553 lastlevel = gamemap;
554 lastepisode = gameepisode;
555 }
556 AM_initVariables();
557 AM_loadPics();
558}
559
560//
561// AM_minOutWindowScale()
562//
563// Set the window scale to the maximum size
564//
565// Passed nothing, returns nothing
566//
567static void AM_minOutWindowScale(void)
568{
569 scale_mtof = min_scale_mtof;
570 scale_ftom = FixedDiv(FRACUNIT, scale_mtof);
571 AM_activateNewScale();
572}
573
574//
575// AM_maxOutWindowScale(void)
576//
577// Set the window scale to the minimum size
578//
579// Passed nothing, returns nothing
580//
581static void AM_maxOutWindowScale(void)
582{
583 scale_mtof = max_scale_mtof;
584 scale_ftom = FixedDiv(FRACUNIT, scale_mtof);
585 AM_activateNewScale();
586}
587
588//
589// AM_Responder()
590//
591// Handle events (user inputs) in automap mode
592//
593// Passed an input event, returns true if its handled
594//
595boolean AM_Responder
596( event_t* ev )
597{
598 int rc;
599 static int cheatstate=0;
600 static int bigstate=0;
601 int ch; // phares
602
603 rc = false;
604
605 if (!(automapmode & am_active))
606 {
607 if (ev->type == ev_keydown && ev->data1 == key_map) // phares
608 {
609 AM_Start ();
610 rc = true;
611 }
612 }
613 else if (ev->type == ev_keydown)
614 {
615 rc = true;
616 ch = ev->data1; // phares
617 if (ch == key_map_right) // |
618 if (!(automapmode & am_follow)) // V
619 m_paninc.x = FTOM(F_PANINC);
620 else
621 rc = false;
622 else if (ch == key_map_left)
623 if (!(automapmode & am_follow))
624 m_paninc.x = -FTOM(F_PANINC);
625 else
626 rc = false;
627 else if (ch == key_map_up)
628 if (!(automapmode & am_follow))
629 m_paninc.y = FTOM(F_PANINC);
630 else
631 rc = false;
632 else if (ch == key_map_down)
633 if (!(automapmode & am_follow))
634 m_paninc.y = -FTOM(F_PANINC);
635 else
636 rc = false;
637 else if (ch == key_map_zoomout)
638 {
639 mtof_zoommul = M_ZOOMOUT;
640 ftom_zoommul = M_ZOOMIN;
641 }
642 else if (ch == key_map_zoomin)
643 {
644 mtof_zoommul = M_ZOOMIN;
645 ftom_zoommul = M_ZOOMOUT;
646 }
647 else if (ch == key_map)
648 {
649 bigstate = 0;
650 AM_Stop ();
651 }
652 else if (ch == key_map_gobig)
653 {
654 bigstate = !bigstate;
655 if (bigstate)
656 {
657 AM_saveScaleAndLoc();
658 AM_minOutWindowScale();
659 }
660 else
661 AM_restoreScaleAndLoc();
662 }
663 else if (ch == key_map_follow)
664 {
665 automapmode ^= am_follow; // CPhipps - put all automap mode stuff into one enum
666 f_oldloc.x = INT_MAX;
667 // Ty 03/27/98 - externalized
668 plr->message = (automapmode & am_follow) ? s_AMSTR_FOLLOWON : s_AMSTR_FOLLOWOFF;
669 }
670 else if (ch == key_map_grid)
671 {
672 automapmode ^= am_grid; // CPhipps
673 // Ty 03/27/98 - *not* externalized
674 plr->message = (automapmode & am_grid) ? s_AMSTR_GRIDON : s_AMSTR_GRIDOFF;
675 }
676 else if (ch == key_map_mark)
677 {
678 /* Ty 03/27/98 - *not* externalized
679 * cph 2001/11/20 - use doom_printf so we don't have our own buffer */
680 doom_printf("%s %d", s_AMSTR_MARKEDSPOT, markpointnum);
681 AM_addMark();
682 }
683 else if (ch == key_map_clear)
684 {
685 AM_clearMarks(); // Ty 03/27/98 - *not* externalized
686 plr->message = s_AMSTR_MARKSCLEARED; // ^
687 } // |
688 else if (ch == key_map_rotate) {
689 automapmode ^= am_rotate;
690 plr->message = (automapmode & am_rotate) ? s_AMSTR_ROTATEON : s_AMSTR_ROTATEOFF;
691 }
692 else if (ch == key_map_overlay) {
693 automapmode ^= am_overlay;
694 plr->message = (automapmode & am_overlay) ? s_AMSTR_OVERLAYON : s_AMSTR_OVERLAYOFF;
695 }
696 else // phares
697 {
698 cheatstate=0;
699 rc = false;
700 }
701 }
702 else if (ev->type == ev_keyup)
703 {
704 rc = false;
705 ch = ev->data1;
706 if (ch == key_map_right)
707 {
708 if (!(automapmode & am_follow))
709 m_paninc.x = 0;
710 }
711 else if (ch == key_map_left)
712 {
713 if (!(automapmode & am_follow))
714 m_paninc.x = 0;
715 }
716 else if (ch == key_map_up)
717 {
718 if (!(automapmode & am_follow))
719 m_paninc.y = 0;
720 }
721 else if (ch == key_map_down)
722 {
723 if (!(automapmode & am_follow))
724 m_paninc.y = 0;
725 }
726 else if ((ch == key_map_zoomout) || (ch == key_map_zoomin))
727 {
728 mtof_zoommul = FRACUNIT;
729 ftom_zoommul = FRACUNIT;
730 }
731 }
732 return rc;
733}
734
735//
736// AM_rotate()
737//
738// Rotation in 2D.
739// Used to rotate player arrow line character.
740//
741// Passed the coordinates of a point, and an angle
742// Returns the coordinates rotated by the angle
743//
744// CPhipps - made static & enhanced for automap rotation
745
746static void AM_rotate(fixed_t* x, fixed_t* y, angle_t a, fixed_t xorig, fixed_t yorig)
747{
748 fixed_t tmpx;
749
750 //e6y
751 xorig>>=FRACTOMAPBITS;
752 yorig>>=FRACTOMAPBITS;
753
754 tmpx =
755 FixedMul(*x - xorig,finecosine[a>>ANGLETOFINESHIFT])
756 - FixedMul(*y - yorig,finesine[a>>ANGLETOFINESHIFT]);
757
758 *y = yorig +
759 FixedMul(*x - xorig,finesine[a>>ANGLETOFINESHIFT])
760 + FixedMul(*y - yorig,finecosine[a>>ANGLETOFINESHIFT]);
761
762 *x = tmpx + xorig;
763}
764
765//
766// AM_changeWindowScale()
767//
768// Automap zooming
769//
770// Passed nothing, returns nothing
771//
772static void AM_changeWindowScale(void)
773{
774 // Change the scaling multipliers
775 scale_mtof = FixedMul(scale_mtof, mtof_zoommul);
776 scale_ftom = FixedDiv(FRACUNIT, scale_mtof);
777
778 if (scale_mtof < min_scale_mtof)
779 AM_minOutWindowScale();
780 else if (scale_mtof > max_scale_mtof)
781 AM_maxOutWindowScale();
782 else
783 AM_activateNewScale();
784}
785
786//
787// AM_doFollowPlayer()
788//
789// Turn on follow mode - the map scrolls opposite to player motion
790//
791// Passed nothing, returns nothing
792//
793static void AM_doFollowPlayer(void)
794{
795 if (f_oldloc.x != plr->mo->x || f_oldloc.y != plr->mo->y)
796 {
797 m_x = FTOM(MTOF(plr->mo->x >> FRACTOMAPBITS)) - m_w/2;//e6y
798 m_y = FTOM(MTOF(plr->mo->y >> FRACTOMAPBITS)) - m_h/2;//e6y
799 m_x2 = m_x + m_w;
800 m_y2 = m_y + m_h;
801 f_oldloc.x = plr->mo->x;
802 f_oldloc.y = plr->mo->y;
803 }
804}
805
806//
807// AM_Ticker()
808//
809// Updates on gametic - enter follow mode, zoom, or change map location
810//
811// Passed nothing, returns nothing
812//
813void AM_Ticker (void)
814{
815 if (!(automapmode & am_active))
816 return;
817
818 if (automapmode & am_follow)
819 AM_doFollowPlayer();
820
821 // Change the zoom if necessary
822 if (ftom_zoommul != FRACUNIT)
823 AM_changeWindowScale();
824
825 // Change x,y location
826 if (m_paninc.x || m_paninc.y)
827 AM_changeWindowLoc();
828}
829
830//
831// AM_clipMline()
832//
833// Automap clipping of lines.
834//
835// Based on Cohen-Sutherland clipping algorithm but with a slightly
836// faster reject and precalculated slopes. If the speed is needed,
837// use a hash algorithm to handle the common cases.
838//
839// Passed the line's coordinates on map and in the frame buffer performs
840// clipping on them in the lines frame coordinates.
841// Returns true if any part of line was not clipped
842//
843static boolean AM_clipMline
844( mline_t* ml,
845 fline_t* fl )
846{
847 enum
848 {
849 LEFT =1,
850 RIGHT =2,
851 BOTTOM =4,
852 TOP =8
853 };
854
855 register int outcode1 = 0;
856 register int outcode2 = 0;
857 register int outside;
858
859 fpoint_t tmp;
860 int dx;
861 int dy;
862
863
864#define DOOUTCODE(oc, mx, my) \
865 (oc) = 0; \
866 if ((my) < 0) (oc) |= TOP; \
867 else if ((my) >= f_h) (oc) |= BOTTOM; \
868 if ((mx) < 0) (oc) |= LEFT; \
869 else if ((mx) >= f_w) (oc) |= RIGHT;
870
871
872 // do trivial rejects and outcodes
873 if (ml->a.y > m_y2)
874 outcode1 = TOP;
875 else if (ml->a.y < m_y)
876 outcode1 = BOTTOM;
877
878 if (ml->b.y > m_y2)
879 outcode2 = TOP;
880 else if (ml->b.y < m_y)
881 outcode2 = BOTTOM;
882
883 if (outcode1 & outcode2)
884 return false; // trivially outside
885
886 if (ml->a.x < m_x)
887 outcode1 |= LEFT;
888 else if (ml->a.x > m_x2)
889 outcode1 |= RIGHT;
890
891 if (ml->b.x < m_x)
892 outcode2 |= LEFT;
893 else if (ml->b.x > m_x2)
894 outcode2 |= RIGHT;
895
896 if (outcode1 & outcode2)
897 return false; // trivially outside
898
899 // transform to frame-buffer coordinates.
900 fl->a.x = CXMTOF(ml->a.x);
901 fl->a.y = CYMTOF(ml->a.y);
902 fl->b.x = CXMTOF(ml->b.x);
903 fl->b.y = CYMTOF(ml->b.y);
904
905 DOOUTCODE(outcode1, fl->a.x, fl->a.y);
906 DOOUTCODE(outcode2, fl->b.x, fl->b.y);
907
908 if (outcode1 & outcode2)
909 return false;
910
911 while (outcode1 | outcode2)
912 {
913 // may be partially inside box
914 // find an outside point
915 if (outcode1)
916 outside = outcode1;
917 else
918 outside = outcode2;
919
920 // clip to each side
921 if (outside & TOP)
922 {
923 dy = fl->a.y - fl->b.y;
924 dx = fl->b.x - fl->a.x;
925 tmp.x = fl->a.x + (dx*(fl->a.y))/dy;
926 tmp.y = 0;
927 }
928 else if (outside & BOTTOM)
929 {
930 dy = fl->a.y - fl->b.y;
931 dx = fl->b.x - fl->a.x;
932 tmp.x = fl->a.x + (dx*(fl->a.y-f_h))/dy;
933 tmp.y = f_h-1;
934 }
935 else if (outside & RIGHT)
936 {
937 dy = fl->b.y - fl->a.y;
938 dx = fl->b.x - fl->a.x;
939 tmp.y = fl->a.y + (dy*(f_w-1 - fl->a.x))/dx;
940 tmp.x = f_w-1;
941 }
942 else if (outside & LEFT)
943 {
944 dy = fl->b.y - fl->a.y;
945 dx = fl->b.x - fl->a.x;
946 tmp.y = fl->a.y + (dy*(-fl->a.x))/dx;
947 tmp.x = 0;
948 }
949
950 if (outside == outcode1)
951 {
952 fl->a = tmp;
953 DOOUTCODE(outcode1, fl->a.x, fl->a.y);
954 }
955 else
956 {
957 fl->b = tmp;
958 DOOUTCODE(outcode2, fl->b.x, fl->b.y);
959 }
960
961 if (outcode1 & outcode2)
962 return false; // trivially outside
963 }
964
965 return true;
966}
967#undef DOOUTCODE
968
969//
970// AM_drawMline()
971//
972// Clip lines, draw visible parts of lines.
973//
974// Passed the map coordinates of the line, and the color to draw it
975// Color -1 is special and prevents drawing. Color 247 is special and
976// is translated to black, allowing Color 0 to represent feature disable
977// in the defaults file.
978// Returns nothing.
979//
980static void AM_drawMline
981( mline_t* ml,
982 int color )
983{
984 static fline_t fl;
985
986 if (color==-1) // jff 4/3/98 allow not drawing any sort of line
987 return; // by setting its color to -1
988 if (color==247) // jff 4/3/98 if color is 247 (xparent), use black
989 color=0;
990
991 if (AM_clipMline(ml, &fl))
992 V_DrawLine(&fl, color); // draws it on frame buffer using fb coords
993}
994
995//
996// AM_drawGrid()
997//
998// Draws blockmap aligned grid lines.
999//
1000// Passed the color to draw the grid lines
1001// Returns nothing
1002//
1003static void AM_drawGrid(int color)
1004{
1005 fixed_t x, y;
1006 fixed_t start, end;
1007 mline_t ml;
1008
1009 // Figure out start of vertical gridlines
1010 start = m_x;
1011 if ((start-bmaporgx)%(MAPBLOCKUNITS<<MAPBITS))//e6y
1012 start += (MAPBLOCKUNITS<<MAPBITS)//e6y
1013 - ((start-bmaporgx)%(MAPBLOCKUNITS<<MAPBITS));//e6y
1014 end = m_x + m_w;
1015
1016 // draw vertical gridlines
1017 ml.a.y = m_y;
1018 ml.b.y = m_y+m_h;
1019 for (x=start; x<end; x+=(MAPBLOCKUNITS<<MAPBITS))//e6y
1020 {
1021 ml.a.x = x;
1022 ml.b.x = x;
1023 AM_drawMline(&ml, color);
1024 }
1025
1026 // Figure out start of horizontal gridlines
1027 start = m_y;
1028 if ((start-bmaporgy)%(MAPBLOCKUNITS<<MAPBITS))//e6y
1029 start += (MAPBLOCKUNITS<<MAPBITS)//e6y
1030 - ((start-bmaporgy)%(MAPBLOCKUNITS<<MAPBITS));//e6y
1031 end = m_y + m_h;
1032
1033 // draw horizontal gridlines
1034 ml.a.x = m_x;
1035 ml.b.x = m_x + m_w;
1036 for (y=start; y<end; y+=(MAPBLOCKUNITS<<MAPBITS))//e6y
1037 {
1038 ml.a.y = y;
1039 ml.b.y = y;
1040 AM_drawMline(&ml, color);
1041 }
1042}
1043
1044//
1045// AM_DoorColor()
1046//
1047// Returns the 'color' or key needed for a door linedef type
1048//
1049// Passed the type of linedef, returns:
1050// -1 if not a keyed door
1051// 0 if a red key required
1052// 1 if a blue key required
1053// 2 if a yellow key required
1054// 3 if a multiple keys required
1055//
1056// jff 4/3/98 add routine to get color of generalized keyed door
1057//
1058static int AM_DoorColor(int type)
1059{
1060 if (GenLockedBase <= type && type< GenDoorBase)
1061 {
1062 type -= GenLockedBase;
1063 type = (type & LockedKey) >> LockedKeyShift;
1064 if (!type || type==7)
1065 return 3; //any or all keys
1066 else return (type-1)%3;
1067 }
1068 switch (type) // closed keyed door
1069 {
1070 case 26: case 32: case 99: case 133:
1071 /*bluekey*/
1072 return 1;
1073 case 27: case 34: case 136: case 137:
1074 /*yellowkey*/
1075 return 2;
1076 case 28: case 33: case 134: case 135:
1077 /*redkey*/
1078 return 0;
1079 default:
1080 return -1; //not a keyed door
1081 }
1082}
1083
1084//
1085// Determines visible lines, draws them.
1086// This is LineDef based, not LineSeg based.
1087//
1088// jff 1/5/98 many changes in this routine
1089// backward compatibility not needed, so just changes, no ifs
1090// addition of clauses for:
1091// doors opening, keyed door id, secret sectors,
1092// teleports, exit lines, key things
1093// ability to suppress any of added features or lines with no height changes
1094//
1095// support for gamma correction in automap abandoned
1096//
1097// jff 4/3/98 changed mapcolor_xxxx=0 as control to disable feature
1098// jff 4/3/98 changed mapcolor_xxxx=-1 to disable drawing line completely
1099//
1100static void AM_drawWalls(void)
1101{
1102 int i;
1103 static mline_t l;
1104
1105 // draw the unclipped visible portions of all lines
1106 for (i=0;i<numlines;i++)
1107 {
1108 l.a.x = lines[i].v1->x >> FRACTOMAPBITS;//e6y
1109 l.a.y = lines[i].v1->y >> FRACTOMAPBITS;//e6y
1110 l.b.x = lines[i].v2->x >> FRACTOMAPBITS;//e6y
1111 l.b.y = lines[i].v2->y >> FRACTOMAPBITS;//e6y
1112
1113 if (automapmode & am_rotate) {
1114 AM_rotate(&l.a.x, &l.a.y, ANG90-plr->mo->angle, plr->mo->x, plr->mo->y);
1115 AM_rotate(&l.b.x, &l.b.y, ANG90-plr->mo->angle, plr->mo->x, plr->mo->y);
1116 }
1117
1118 // if line has been seen or IDDT has been used
1119 if (ddt_cheating || (lines[i].flags & ML_MAPPED))
1120 {
1121 if ((lines[i].flags & ML_DONTDRAW) && !ddt_cheating)
1122 continue;
1123 {
1124 /* cph - show keyed doors and lines */
1125 int amd;
1126 if ((mapcolor_bdor || mapcolor_ydor || mapcolor_rdor) &&
1127 !(lines[i].flags & ML_SECRET) && /* non-secret */
1128 (amd = AM_DoorColor(lines[i].special)) != -1
1129 )
1130 {
1131 {
1132 switch (amd) /* closed keyed door */
1133 {
1134 case 1:
1135 /*bluekey*/
1136 AM_drawMline(&l,
1137 mapcolor_bdor? mapcolor_bdor : mapcolor_cchg);
1138 continue;
1139 case 2:
1140 /*yellowkey*/
1141 AM_drawMline(&l,
1142 mapcolor_ydor? mapcolor_ydor : mapcolor_cchg);
1143 continue;
1144 case 0:
1145 /*redkey*/
1146 AM_drawMline(&l,
1147 mapcolor_rdor? mapcolor_rdor : mapcolor_cchg);
1148 continue;
1149 case 3:
1150 /*any or all*/
1151 AM_drawMline(&l,
1152 mapcolor_clsd? mapcolor_clsd : mapcolor_cchg);
1153 continue;
1154 }
1155 }
1156 }
1157 }
1158 if /* jff 4/23/98 add exit lines to automap */
1159 (
1160 mapcolor_exit &&
1161 (
1162 lines[i].special==11 ||
1163 lines[i].special==52 ||
1164 lines[i].special==197 ||
1165 lines[i].special==51 ||
1166 lines[i].special==124 ||
1167 lines[i].special==198
1168 )
1169 ) {
1170 AM_drawMline(&l, mapcolor_exit); /* exit line */
1171 continue;
1172 }
1173
1174 if (!lines[i].backsector)
1175 {
1176 // jff 1/10/98 add new color for 1S secret sector boundary
1177 if (mapcolor_secr && //jff 4/3/98 0 is disable
1178 (
1179 (
1180 map_secret_after &&
1181 P_WasSecret(lines[i].frontsector) &&
1182 !P_IsSecret(lines[i].frontsector)
1183 )
1184 ||
1185 (
1186 !map_secret_after &&
1187 P_WasSecret(lines[i].frontsector)
1188 )
1189 )
1190 )
1191 AM_drawMline(&l, mapcolor_secr); // line bounding secret sector
1192 else //jff 2/16/98 fixed bug
1193 AM_drawMline(&l, mapcolor_wall); // special was cleared
1194 }
1195 else /* now for 2S lines */
1196 {
1197 // jff 1/10/98 add color change for all teleporter types
1198 if
1199 (
1200 mapcolor_tele && !(lines[i].flags & ML_SECRET) &&
1201 (lines[i].special == 39 || lines[i].special == 97 ||
1202 lines[i].special == 125 || lines[i].special == 126)
1203 )
1204 { // teleporters
1205 AM_drawMline(&l, mapcolor_tele);
1206 }
1207 else if (lines[i].flags & ML_SECRET) // secret door
1208 {
1209 AM_drawMline(&l, mapcolor_wall); // wall color
1210 }
1211 else if
1212 (
1213 mapcolor_clsd &&
1214 !(lines[i].flags & ML_SECRET) && // non-secret closed door
1215 ((lines[i].backsector->floorheight==lines[i].backsector->ceilingheight) ||
1216 (lines[i].frontsector->floorheight==lines[i].frontsector->ceilingheight))
1217 )
1218 {
1219 AM_drawMline(&l, mapcolor_clsd); // non-secret closed door
1220 } //jff 1/6/98 show secret sector 2S lines
1221 else if
1222 (
1223 mapcolor_secr && //jff 2/16/98 fixed bug
1224 ( // special was cleared after getting it
1225 (map_secret_after &&
1226 (
1227 (P_WasSecret(lines[i].frontsector)
1228 && !P_IsSecret(lines[i].frontsector)) ||
1229 (P_WasSecret(lines[i].backsector)
1230 && !P_IsSecret(lines[i].backsector))
1231 )
1232 )
1233 || //jff 3/9/98 add logic to not show secret til after entered
1234 ( // if map_secret_after is true
1235 !map_secret_after &&
1236 (P_WasSecret(lines[i].frontsector) ||
1237 P_WasSecret(lines[i].backsector))
1238 )
1239 )
1240 )
1241 {
1242 AM_drawMline(&l, mapcolor_secr); // line bounding secret sector
1243 } //jff 1/6/98 end secret sector line change
1244 else if (lines[i].backsector->floorheight !=
1245 lines[i].frontsector->floorheight)
1246 {
1247 AM_drawMline(&l, mapcolor_fchg); // floor level change
1248 }
1249 else if (lines[i].backsector->ceilingheight !=
1250 lines[i].frontsector->ceilingheight)
1251 {
1252 AM_drawMline(&l, mapcolor_cchg); // ceiling level change
1253 }
1254 else if (mapcolor_flat && ddt_cheating)
1255 {
1256 AM_drawMline(&l, mapcolor_flat); //2S lines that appear only in IDDT
1257 }
1258 }
1259 } // now draw the lines only visible because the player has computermap
1260 else if (plr->powers[pw_allmap]) // computermap visible lines
1261 {
1262 if (!(lines[i].flags & ML_DONTDRAW)) // invisible flag lines do not show
1263 {
1264 if
1265 (
1266 mapcolor_flat
1267 ||
1268 !lines[i].backsector
1269 ||
1270 lines[i].backsector->floorheight
1271 != lines[i].frontsector->floorheight
1272 ||
1273 lines[i].backsector->ceilingheight
1274 != lines[i].frontsector->ceilingheight
1275 )
1276 AM_drawMline(&l, mapcolor_unsn);
1277 }
1278 }
1279 }
1280}
1281
1282//
1283// AM_drawLineCharacter()
1284//
1285// Draws a vector graphic according to numerous parameters
1286//
1287// Passed the structure defining the vector graphic shape, the number
1288// of vectors in it, the scale to draw it at, the angle to draw it at,
1289// the color to draw it with, and the map coordinates to draw it at.
1290// Returns nothing
1291//
1292static void AM_drawLineCharacter
1293( mline_t* lineguy,
1294 int lineguylines,
1295 fixed_t scale,
1296 angle_t angle,
1297 int color,
1298 fixed_t x,
1299 fixed_t y )
1300{
1301 int i;
1302 mline_t l;
1303
1304 if (automapmode & am_rotate) angle -= plr->mo->angle - ANG90; // cph
1305
1306 for (i=0;i<lineguylines;i++)
1307 {
1308 l.a.x = lineguy[i].a.x;
1309 l.a.y = lineguy[i].a.y;
1310
1311 if (scale)
1312 {
1313 l.a.x = FixedMul(scale, l.a.x);
1314 l.a.y = FixedMul(scale, l.a.y);
1315 }
1316
1317 if (angle)
1318 AM_rotate(&l.a.x, &l.a.y, angle, 0, 0);
1319
1320 l.a.x += x;
1321 l.a.y += y;
1322
1323 l.b.x = lineguy[i].b.x;
1324 l.b.y = lineguy[i].b.y;
1325
1326 if (scale)
1327 {
1328 l.b.x = FixedMul(scale, l.b.x);
1329 l.b.y = FixedMul(scale, l.b.y);
1330 }
1331
1332 if (angle)
1333 AM_rotate(&l.b.x, &l.b.y, angle, 0, 0);
1334
1335 l.b.x += x;
1336 l.b.y += y;
1337
1338 AM_drawMline(&l, color);
1339 }
1340}
1341
1342//
1343// AM_drawPlayers()
1344//
1345// Draws the player arrow in single player,
1346// or all the player arrows in a netgame.
1347//
1348// Passed nothing, returns nothing
1349//
1350static void AM_drawPlayers(void)
1351{
1352 int i;
1353
1354 if (!netgame)
1355 {
1356 if (ddt_cheating)
1357 AM_drawLineCharacter
1358 (
1359 cheat_player_arrow,
1360 NUMCHEATPLYRLINES,
1361 0,
1362 plr->mo->angle,
1363 mapcolor_sngl, //jff color
1364 plr->mo->x >> FRACTOMAPBITS,//e6y
1365 plr->mo->y >> FRACTOMAPBITS//e6y
1366 );
1367 else
1368 AM_drawLineCharacter
1369 (
1370 player_arrow,
1371 NUMPLYRLINES,
1372 0,
1373 plr->mo->angle,
1374 mapcolor_sngl, //jff color
1375 plr->mo->x >> FRACTOMAPBITS,//e6y
1376 plr->mo->y >> FRACTOMAPBITS);//e6y
1377 return;
1378 }
1379
1380 for (i=0;i<MAXPLAYERS;i++) {
1381 player_t* p = &players[i];
1382
1383 if ( (deathmatch && !demoplayback) && p != plr)
1384 continue;
1385
1386 if (playeringame[i]) {
1387 fixed_t x = p->mo->x >> FRACTOMAPBITS, y = p->mo->y >> FRACTOMAPBITS;//e6y
1388 if (automapmode & am_rotate)
1389 AM_rotate(&x, &y, ANG90-plr->mo->angle, plr->mo->x, plr->mo->y);
1390
1391 AM_drawLineCharacter (player_arrow, NUMPLYRLINES, 0, p->mo->angle,
1392 p->powers[pw_invisibility] ? 246 /* *close* to black */
1393 : mapcolor_plyr[i], //jff 1/6/98 use default color
1394 x, y);
1395 }
1396 }
1397}
1398
1399//
1400// AM_drawThings()
1401//
1402// Draws the things on the automap in double IDDT cheat mode
1403//
1404// Passed colors and colorrange, no longer used
1405// Returns nothing
1406//
1407static void AM_drawThings(void)
1408{
1409 int i;
1410 mobj_t* t;
1411
1412 // for all sectors
1413 for (i=0;i<numsectors;i++)
1414 {
1415 t = sectors[i].thinglist;
1416 while (t) // for all things in that sector
1417 {
1418 fixed_t x = t->x >> FRACTOMAPBITS, y = t->y >> FRACTOMAPBITS;//e6y
1419
1420 if (automapmode & am_rotate)
1421 AM_rotate(&x, &y, ANG90-plr->mo->angle, plr->mo->x, plr->mo->y);
1422
1423 //jff 1/5/98 case over doomednum of thing being drawn
1424 if (mapcolor_rkey || mapcolor_ykey || mapcolor_bkey)
1425 {
1426 switch(t->info->doomednum)
1427 {
1428 //jff 1/5/98 treat keys special
1429 case 38: case 13: //jff red key
1430 AM_drawLineCharacter
1431 (
1432 cross_mark,
1433 NUMCROSSMARKLINES,
1434 16<<MAPBITS,//e6y
1435 t->angle,
1436 mapcolor_rkey!=-1? mapcolor_rkey : mapcolor_sprt,
1437 x, y
1438 );
1439 t = t->snext;
1440 continue;
1441 case 39: case 6: //jff yellow key
1442 AM_drawLineCharacter
1443 (
1444 cross_mark,
1445 NUMCROSSMARKLINES,
1446 16<<MAPBITS,//e6y
1447 t->angle,
1448 mapcolor_ykey!=-1? mapcolor_ykey : mapcolor_sprt,
1449 x, y
1450 );
1451 t = t->snext;
1452 continue;
1453 case 40: case 5: //jff blue key
1454 AM_drawLineCharacter
1455 (
1456 cross_mark,
1457 NUMCROSSMARKLINES,
1458 16<<MAPBITS,//e6y
1459 t->angle,
1460 mapcolor_bkey!=-1? mapcolor_bkey : mapcolor_sprt,
1461 x, y
1462 );
1463 t = t->snext;
1464 continue;
1465 default:
1466 break;
1467 }
1468 }
1469 //jff 1/5/98 end added code for keys
1470 //jff previously entire code
1471 AM_drawLineCharacter
1472 (
1473 thintriangle_guy,
1474 NUMTHINTRIANGLEGUYLINES,
1475 16<<MAPBITS,//e6y
1476 t->angle,
1477 t->flags & MF_FRIEND && !t->player ? mapcolor_frnd :
1478 /* cph 2006/07/30 - Show count-as-kills in red. */
1479 ((t->flags & (MF_COUNTKILL | MF_CORPSE)) == MF_COUNTKILL) ? mapcolor_enemy :
1480 /* bbm 2/28/03 Show countable items in yellow. */
1481 t->flags & MF_COUNTITEM ? mapcolor_item : mapcolor_sprt,
1482 x, y
1483 );
1484 t = t->snext;
1485 }
1486 }
1487}
1488
1489//
1490// AM_drawMarks()
1491//
1492// Draw the marked locations on the automap
1493//
1494// Passed nothing, returns nothing
1495//
1496// killough 2/22/98:
1497// Rewrote AM_drawMarks(). Removed limit on marks.
1498//
1499static void AM_drawMarks(void)
1500{
1501 int i;
1502 for (i=0;i<markpointnum;i++) // killough 2/22/98: remove automap mark limit
1503 if (markpoints[i].x != -1)
1504 {
1505 int w = 5;
1506 int h = 6;
1507 int fx = markpoints[i].x;
1508 int fy = markpoints[i].y;
1509 int j = i;
1510
1511 if (automapmode & am_rotate)
1512 AM_rotate(&fx, &fy, ANG90-plr->mo->angle, plr->mo->x, plr->mo->y);
1513
1514 fx = CXMTOF(fx); fy = CYMTOF(fy);
1515
1516 do
1517 {
1518 int d = j % 10;
1519 if (d==1) // killough 2/22/98: less spacing for '1'
1520 fx++;
1521
1522 if (fx >= f_x && fx < f_w - w && fy >= f_y && fy < f_h - h) {
1523 // cph - construct patch name and draw marker
1524 char namebuf[] = { 'A', 'M', 'M', 'N', 'U', 'M', '0'+d, 0 };
1525
1526 V_DrawNamePatch(fx, fy, FB, namebuf, CR_DEFAULT, VPT_NONE);
1527 }
1528 fx -= w-1; // killough 2/22/98: 1 space backwards
1529 j /= 10;
1530 }
1531 while (j>0);
1532 }
1533}
1534
1535//
1536// AM_drawCrosshair()
1537//
1538// Draw the single point crosshair representing map center
1539//
1540// Passed the color to draw the pixel with
1541// Returns nothing
1542//
1543// CPhipps - made static inline, and use the general pixel plotter function
1544
1545inline static void AM_drawCrosshair(int color)
1546{
1547 fline_t line;
1548
1549 line.a.x = (f_w/2)-1;
1550 line.a.y = (f_h/2);
1551 line.b.x = (f_w/2)+1;
1552 line.b.y = (f_h/2);
1553 V_DrawLine(&line, color);
1554
1555 line.a.x = (f_w/2);
1556 line.a.y = (f_h/2)-1;
1557 line.b.x = (f_w/2);
1558 line.b.y = (f_h/2)+1;
1559 V_DrawLine(&line, color);
1560}
1561
1562//
1563// AM_Drawer()
1564//
1565// Draws the entire automap
1566//
1567// Passed nothing, returns nothing
1568//
1569void AM_Drawer (void)
1570{
1571 // CPhipps - all automap modes put into one enum
1572 if (!(automapmode & am_active)) return;
1573
1574 if (!(automapmode & am_overlay)) // cph - If not overlay mode, clear background for the automap
1575 V_FillRect(FB, f_x, f_y, f_w, f_h, (byte)mapcolor_back); //jff 1/5/98 background default color
1576 if (automapmode & am_grid)
1577 AM_drawGrid(mapcolor_grid); //jff 1/7/98 grid default color
1578 AM_drawWalls();
1579 AM_drawPlayers();
1580 if (ddt_cheating==2)
1581 AM_drawThings(); //jff 1/5/98 default double IDDT sprite
1582 AM_drawCrosshair(mapcolor_hair); //jff 1/7/98 default crosshair color
1583
1584 AM_drawMarks();
1585}