1 /* Emacs style mode select -*- C++ -*-
2 *-----------------------------------------------------------------------------
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
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.
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.
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., 59 Temple Place - Suite 330, Boston, MA
30 *-----------------------------------------------------------------------------
44 #include "d_deh.h" // Ty 03/27/98 - externalizations
46 #include "rockmacros.h"
49 //jff 1/7/98 default automap colors added
50 int mapcolor_back
; // map background
51 int mapcolor_grid
; // grid lines color
52 int mapcolor_wall
; // normal 1s wall color
53 int mapcolor_fchg
; // line at floor height change color
54 int mapcolor_cchg
; // line at ceiling height change color
55 int mapcolor_clsd
; // line at sector with floor=ceiling color
56 int mapcolor_rkey
; // red key color
57 int mapcolor_bkey
; // blue key color
58 int mapcolor_ykey
; // yellow key color
59 int mapcolor_rdor
; // red door color (diff from keys to allow option)
60 int mapcolor_bdor
; // blue door color (of enabling one but not other )
61 int mapcolor_ydor
; // yellow door color
62 int mapcolor_tele
; // teleporter line color
63 int mapcolor_secr
; // secret sector boundary color
64 int mapcolor_exit
; // jff 4/23/98 add exit line color
65 int mapcolor_unsn
; // computer map unseen line color
66 int mapcolor_flat
; // line with no floor/ceiling changes
67 int mapcolor_sprt
; // general sprite color
68 int mapcolor_item
; // item sprite color
69 int mapcolor_frnd
; // friendly sprite color
70 int mapcolor_hair
; // crosshair color
71 int mapcolor_sngl
; // single player arrow color
72 int mapcolor_plyr
[4] = { 112, 88, 64, 176 }; // colors for player arrows in multiplayer
74 //jff 3/9/98 add option to not show secret sectors until entered
76 //jff 4/3/98 add symbols for "no-color" for disable and "black color" for black
84 #define INITSCALEMTOF (.2*FRACUNIT)
85 // how much the automap moves window per tic in frame-buffer coordinates
86 // moves 140 pixels in 1 second
88 // how much zoom-in per tic
89 // goes to 2x in 1 second
90 #define M_ZOOMIN ((int) (1.02*FRACUNIT))
91 // how much zoom-out per tic
92 // pulls out to 0.5x in 1 second
93 #define M_ZOOMOUT ((int) (FRACUNIT/1.02))
95 // translates between frame-buffer and map distances
96 #define FTOM(x) FixedMul(((x)<<16),scale_ftom)
97 #define MTOF(x) (FixedMul((x),scale_mtof)>>16)
98 // translates between frame-buffer and map coordinates
99 #define CXMTOF(x) (f_x + MTOF((x)-m_x))
100 #define CYMTOF(y) (f_y + (f_h - MTOF((y)-m_y)))
123 // The vector graphics for the automap.
124 // A line drawing of the player pointing right,
125 // starting from the middle.
127 #define R ((8*PLAYERRADIUS)/7)
128 mline_t player_arrow
[] =
130 { { -R
+R
/8, 0 }, { R
, 0 } }, // -----
131 { { R
, 0 }, { R
-R
/2, R
/4 } }, // ----->
132 { { R
, 0 }, { R
-R
/2, -R
/4 } },
133 { { -R
+R
/8, 0 }, { -R
-R
/8, R
/4 } }, // >---->
134 { { -R
+R
/8, 0 }, { -R
-R
/8, -R
/4 } },
135 { { -R
+3*R
/8, 0 }, { -R
+R
/8, R
/4 } }, // >>--->
136 { { -R
+3*R
/8, 0 }, { -R
+R
/8, -R
/4 } }
139 #define NUMPLYRLINES (sizeof(player_arrow)/sizeof(mline_t))
141 #define R ((8*PLAYERRADIUS)/7)
142 mline_t cheat_player_arrow
[] =
143 { // killough 3/22/98: He's alive, Jim :)
144 { { -R
+R
/8, 0 }, { R
, 0 } }, // -----
145 { { R
, 0 }, { R
-R
/2, R
/4 } }, // ----->
146 { { R
, 0 }, { R
-R
/2, -R
/4 } },
147 { { -R
+R
/8, 0 }, { -R
-R
/8, R
/4 } }, // >---->
148 { { -R
+R
/8, 0 }, { -R
-R
/8, -R
/4 } },
149 { { -R
+3*R
/8, 0 }, { -R
+R
/8, R
/4 } }, // >>--->
150 { { -R
+3*R
/8, 0 }, { -R
+R
/8, -R
/4 } },
151 { { -R
/10-R
/6, R
/4}, {-R
/10-R
/6, -R
/4} }, // J
152 { { -R
/10-R
/6, -R
/4}, {-R
/10-R
/6-R
/8, -R
/4} },
153 { { -R
/10-R
/6-R
/8, -R
/4}, {-R
/10-R
/6-R
/8, -R
/8} },
154 { { -R
/10, R
/4}, {-R
/10, -R
/4}}, // F
155 { { -R
/10, R
/4}, {-R
/10+R
/8, R
/4}},
156 { { -R
/10+R
/4, R
/4}, {-R
/10+R
/4, -R
/4}}, // F
157 { { -R
/10+R
/4, R
/4}, {-R
/10+R
/4+R
/8, R
/4}},
160 #define NUMCHEATPLYRLINES (sizeof(cheat_player_arrow)/sizeof(mline_t))
163 mline_t triangle_guy
[] =
165 { { (fixed_t
)(-.867*R
), (fixed_t
)(-.5*R
) }, { (fixed_t
)( .867*R
), (fixed_t
)(-.5*R
) } },
166 { { (fixed_t
)( .867*R
), (fixed_t
)(-.5*R
) }, { (fixed_t
)(0 ), (fixed_t
)( R
) } },
167 { { (fixed_t
)(0 ), (fixed_t
)( R
) }, { (fixed_t
)(-.867*R
), (fixed_t
)(-.5*R
) } }
170 #define NUMTRIANGLEGUYLINES (sizeof(triangle_guy)/sizeof(mline_t))
172 //jff 1/5/98 new symbol for keys on automap
174 mline_t cross_mark
[] =
176 { { -R
, 0 }, { R
, 0} },
177 { { 0, -R
}, { 0, R
} },
180 #define NUMCROSSMARKLINES (sizeof(cross_mark)/sizeof(mline_t))
181 //jff 1/5/98 end of new symbol
184 mline_t thintriangle_guy
[] =
186 { { (fixed_t
)(-.5*R
), (fixed_t
)(-.7*R
) }, { (fixed_t
)( R
), (fixed_t
)( 0) } },
187 { { (fixed_t
)( R
), (fixed_t
)( 0) }, { (fixed_t
)(-.5*R
), (fixed_t
)( .7*R
) } },
188 { { (fixed_t
)(-.5*R
), (fixed_t
)( .7*R
) }, { (fixed_t
)(-.5*R
), (fixed_t
)(-.7*R
) } }
191 #define NUMTHINTRIANGLEGUYLINES (sizeof(thintriangle_guy)/sizeof(mline_t))
193 int ddt_cheating
= 0; // killough 2/7/98: make global, rename to ddt_*
195 static int leveljuststarted
= 1; // kluge until AM_LevelInit() is called
197 enum automapmode_e automapmode
; // Mode that the automap is in
199 // location of window on screen
203 // size of window on screen
207 static mpoint_t m_paninc
; // how far the window pans each tic (map coords)
208 static fixed_t mtof_zoommul
; // how far the window zooms each tic (map coords)
209 static fixed_t ftom_zoommul
; // how far the window zooms each tic (fb coords)
211 static fixed_t m_x
, m_y
; // LL x,y window location on the map (map coords)
212 static fixed_t m_x2
, m_y2
; // UR x,y window location on the map (map coords)
215 // width/height of window on map (map coords)
220 // based on level size
221 static fixed_t min_x
;
222 static fixed_t min_y
;
223 static fixed_t max_x
;
224 static fixed_t max_y
;
226 static fixed_t max_w
; // max_x-min_x,
227 static fixed_t max_h
; // max_y-min_y
229 // based on player size
230 static fixed_t min_w
;
231 static fixed_t min_h
;
234 static fixed_t min_scale_mtof
; // used to tell when to stop zooming out
235 static fixed_t max_scale_mtof
; // used to tell when to stop zooming in
237 // old stuff for recovery later
238 static fixed_t old_m_w
, old_m_h
;
239 static fixed_t old_m_x
, old_m_y
;
241 // old location used by the Follower routine
242 static mpoint_t f_oldloc
;
244 // used by MTOF to scale from map-to-frame-buffer coords
245 static fixed_t scale_mtof
= (fixed_t
)INITSCALEMTOF
;
246 // used by FTOM to scale from frame-buffer-to-map coords (=1/scale_mtof)
247 static fixed_t scale_ftom
;
249 static player_t
*plr
; // the player represented by an arrow
251 // killough 2/22/98: Remove limit on automap marks,
252 // and make variables external for use in savegames.
254 mpoint_t
*markpoints
= NULL
; // where the points are
255 int markpointnum
= 0; // next point to be assigned (also number of points now)
256 int markpointnum_max
= 0; // killough 2/22/98
258 static boolean stopped
= true;
263 // Calculates the slope and slope according to the x-axis of a line
264 // segment in map coordinates (with the upright y-axis n' all) so
265 // that it can be used with the brain-dead drawing stuff.
267 // Passed the line slope is desired for and an islope_t structure for return
276 dy
= ml
->a
.y
- ml
->b
.y
;
277 dx
= ml
->b
.x
- ml
->a
.x
;
279 is
->islp
= (dx
<0?-INT_MAX
:INT_MAX
);
281 is
->islp
= FixedDiv(dx
, dy
);
283 is
->slp
= (dy
<0?-INT_MAX
:INT_MAX
);
285 is
->slp
= FixedDiv(dy
, dx
);
289 // AM_activateNewScale()
291 // Changes the map scale after zooming or translating
293 // Passed nothing, returns nothing
295 void AM_activateNewScale(void)
308 // AM_saveScaleAndLoc()
310 // Saves the current center and zoom
311 // Affects the variables that remember old scale and loc
313 // Passed nothing, returns nothing
315 void AM_saveScaleAndLoc(void)
324 // AM_restoreScaleAndLoc()
326 // restores the center and zoom from locally saved values
327 // Affects global variables for location and scale
329 // Passed nothing, returns nothing
331 void AM_restoreScaleAndLoc(void)
335 if (!(automapmode
& am_follow
))
342 m_x
= plr
->mo
->x
- m_w
/2;
343 m_y
= plr
->mo
->y
- m_h
/2;
348 // Change the scaling multipliers
349 scale_mtof
= FixedDiv(f_w
<<FRACBITS
, m_w
);
350 scale_ftom
= FixedDiv(FRACUNIT
, scale_mtof
);
356 // Adds a marker at the current location
357 // Affects global variables for marked points
359 // Passed nothing, returns nothing
361 void AM_addMark(void)
364 // remove limit on automap marks
366 if (markpointnum
>= markpointnum_max
)
367 markpoints
= realloc(markpoints
,
368 (markpointnum_max
= markpointnum_max
?
369 markpointnum_max
*2 : 16) * sizeof(*markpoints
));
371 markpoints
[markpointnum
].x
= m_x
+ m_w
/2;
372 markpoints
[markpointnum
].y
= m_y
+ m_h
/2;
377 // AM_findMinMaxBoundaries()
379 // Determines bounding box of all vertices,
380 // sets global variables controlling zoom range.
382 // Passed nothing, returns nothing
384 void AM_findMinMaxBoundaries(void)
390 min_x
= min_y
= INT_MAX
;
391 max_x
= max_y
= -INT_MAX
;
393 for (i
=0;i
<numvertexes
;i
++)
395 if (vertexes
[i
].x
< min_x
)
396 min_x
= vertexes
[i
].x
;
397 else if (vertexes
[i
].x
> max_x
)
398 max_x
= vertexes
[i
].x
;
400 if (vertexes
[i
].y
< min_y
)
401 min_y
= vertexes
[i
].y
;
402 else if (vertexes
[i
].y
> max_y
)
403 max_y
= vertexes
[i
].y
;
406 max_w
= max_x
- min_x
;
407 max_h
= max_y
- min_y
;
409 min_w
= 2*PLAYERRADIUS
; // const? never changed?
410 min_h
= 2*PLAYERRADIUS
;
412 a
= FixedDiv(f_w
<<FRACBITS
, max_w
);
413 b
= FixedDiv(f_h
<<FRACBITS
, max_h
);
415 min_scale_mtof
= a
< b
? a
: b
;
416 max_scale_mtof
= FixedDiv(f_h
<<FRACBITS
, 2*PLAYERRADIUS
);
420 // AM_changeWindowLoc()
422 // Moves the map window by the global variables m_paninc.x, m_paninc.y
424 // Passed nothing, returns nothing
426 void AM_changeWindowLoc(void)
428 if (m_paninc
.x
|| m_paninc
.y
)
430 automapmode
&= ~am_follow
;
431 f_oldloc
.x
= INT_MAX
;
437 if (m_x
+ m_w
/2 > max_x
)
439 else if (m_x
+ m_w
/2 < min_x
)
442 if (m_y
+ m_h
/2 > max_y
)
444 else if (m_y
+ m_h
/2 < min_y
)
453 // AM_initVariables()
455 // Initialize the variables for the automap
457 // Affects the automap global variables
458 // Status bar is notified that the automap has been entered
459 // Passed nothing, returns nothing
461 void AM_initVariables(void)
464 static event_t st_notify
= { ev_keyup
, AM_MSGENTERED
, 0 , 0 };
466 automapmode
|= am_active
;
468 f_oldloc
.x
= INT_MAX
;
470 m_paninc
.x
= m_paninc
.y
= 0;
471 ftom_zoommul
= FRACUNIT
;
472 mtof_zoommul
= FRACUNIT
;
477 // find player to center on initially
478 if (!playeringame
[pnum
= consoleplayer
])
479 for (pnum
=0;pnum
<MAXPLAYERS
;pnum
++)
480 if (playeringame
[pnum
])
483 plr
= &players
[pnum
];
484 m_x
= plr
->mo
->x
- m_w
/2;
485 m_y
= plr
->mo
->y
- m_h
/2;
486 AM_changeWindowLoc();
488 // for saving & restoring
494 // inform the status bar of the change
495 ST_Responder(&st_notify
);
501 void AM_loadPics(void)
503 // cph - mark numbers no longer needed cached
509 void AM_unloadPics(void)
511 // cph - mark numbers no longer needed cached
517 // Sets the number of marks to 0, thereby clearing them from the display
519 // Affects the global variable markpointnum
520 // Passed nothing, returns nothing
522 void AM_clearMarks(void)
530 // Initialize the automap at the start of a new level
531 // should be called at the start of every level
533 // Passed nothing, returns nothing
534 // Affects automap's global variables
536 // CPhipps - get status bar height from status bar code
537 void AM_LevelInit(void)
539 leveljuststarted
= 0;
542 f_w
= SCREENWIDTH
; // killough 2/7/98: get rid of finit_ vars
543 f_h
= SCREENHEIGHT
-ST_SCALED_HEIGHT
;// to allow runtime setting of width/height
545 AM_findMinMaxBoundaries();
546 scale_mtof
= FixedDiv(min_scale_mtof
, (int) (0.7*FRACUNIT
));
547 if (scale_mtof
> max_scale_mtof
)
548 scale_mtof
= min_scale_mtof
;
549 scale_ftom
= FixedDiv(FRACUNIT
, scale_mtof
);
555 // Cease automap operations, unload patches, notify status bar
557 // Passed nothing, returns nothing
561 static event_t st_notify
= { 0, ev_keyup
, AM_MSGEXITED
, 0 };
564 automapmode
&= ~am_active
;
565 ST_Responder(&st_notify
);
572 // Start up automap operations,
573 // if a new level, or game start, (re)initialize level variables
574 // init map variables
577 // Passed nothing, returns nothing
581 static int lastlevel
= -1, lastepisode
= -1;
586 if (lastlevel
!= gamemap
|| lastepisode
!= gameepisode
)
590 lastepisode
= gameepisode
;
597 // AM_minOutWindowScale()
599 // Set the window scale to the maximum size
601 // Passed nothing, returns nothing
603 void AM_minOutWindowScale()
605 scale_mtof
= min_scale_mtof
;
606 scale_ftom
= FixedDiv(FRACUNIT
, scale_mtof
);
607 AM_activateNewScale();
611 // AM_maxOutWindowScale(void)
613 // Set the window scale to the minimum size
615 // Passed nothing, returns nothing
617 void AM_maxOutWindowScale(void)
619 scale_mtof
= max_scale_mtof
;
620 scale_ftom
= FixedDiv(FRACUNIT
, scale_mtof
);
621 AM_activateNewScale();
627 // Handle events (user inputs) in automap mode
629 // Passed an input event, returns true if its handled
635 static int cheatstate
=0;
636 static int bigstate
=0;
637 static char buffer
[20];
642 if (!(automapmode
& am_active
))
644 if (ev
->type
== ev_keydown
&& ev
->data1
== key_map
) // phares
650 else if (ev
->type
== ev_keydown
)
653 ch
= ev
->data1
; // phares
654 if (ch
== key_map_right
) // |
655 if (!(automapmode
& am_follow
)) // V
656 m_paninc
.x
= FTOM(F_PANINC
);
659 else if (ch
== key_map_left
)
660 if (!(automapmode
& am_follow
))
661 m_paninc
.x
= -FTOM(F_PANINC
);
664 else if (ch
== key_map_up
)
665 if (!(automapmode
& am_follow
))
666 m_paninc
.y
= FTOM(F_PANINC
);
669 else if (ch
== key_map_down
)
670 if (!(automapmode
& am_follow
))
671 m_paninc
.y
= -FTOM(F_PANINC
);
674 else if (ch
== key_map_zoomout
)
676 mtof_zoommul
= M_ZOOMOUT
;
677 ftom_zoommul
= M_ZOOMIN
;
679 else if (ch
== key_map_zoomin
)
681 mtof_zoommul
= M_ZOOMIN
;
682 ftom_zoommul
= M_ZOOMOUT
;
684 else if (ch
== key_map
)
689 else if (ch
== key_map_gobig
)
691 bigstate
= !bigstate
;
694 AM_saveScaleAndLoc();
695 AM_minOutWindowScale();
698 AM_restoreScaleAndLoc();
700 else if (ch
== key_map_follow
)
702 automapmode
^= am_follow
; // CPhipps - put all automap mode stuff into one enum
703 f_oldloc
.x
= INT_MAX
;
704 // Ty 03/27/98 - externalized
705 plr
->message
= (automapmode
& am_follow
) ? s_AMSTR_FOLLOWON
: s_AMSTR_FOLLOWOFF
;
707 else if (ch
== key_map_grid
)
709 automapmode
^= am_grid
; // CPhipps
710 // Ty 03/27/98 - *not* externalized
711 plr
->message
= (automapmode
& am_grid
) ? s_AMSTR_GRIDON
: s_AMSTR_GRIDOFF
;
713 else if (ch
== key_map_mark
)
715 // Ty 03/27/98 - *not* externalized
716 snprintf(buffer
, sizeof(buffer
), "%s %d", s_AMSTR_MARKEDSPOT
, markpointnum
);
717 plr
->message
= buffer
;
720 else if (ch
== key_map_clear
)
722 AM_clearMarks(); // Ty 03/27/98 - *not* externalized
723 plr
->message
= s_AMSTR_MARKSCLEARED
; // ^
725 else if (ch
== key_map_rotate
) {
726 automapmode
^= am_rotate
;
727 plr
->message
= (automapmode
& am_rotate
) ? s_AMSTR_ROTATEON
: s_AMSTR_ROTATEOFF
;
729 else if (ch
== key_map_overlay
) {
730 automapmode
^= am_overlay
;
731 plr
->message
= (automapmode
& am_overlay
) ? s_AMSTR_OVERLAYON
: s_AMSTR_OVERLAYOFF
;
739 else if (ev
->type
== ev_keyup
)
743 if (ch
== key_map_right
)
745 if (!(automapmode
& am_follow
))
748 else if (ch
== key_map_left
)
750 if (!(automapmode
& am_follow
))
753 else if (ch
== key_map_up
)
755 if (!(automapmode
& am_follow
))
758 else if (ch
== key_map_down
)
760 if (!(automapmode
& am_follow
))
763 else if ((ch
== key_map_zoomout
) || (ch
== key_map_zoomin
))
765 mtof_zoommul
= FRACUNIT
;
766 ftom_zoommul
= FRACUNIT
;
776 // Used to rotate player arrow line character.
778 // Passed the coordinates of a point, and an angle
779 // Returns the coordinates rotated by the angle
781 // CPhipps - made static & enhanced for automap rotation
783 static void AM_rotate(fixed_t
* x
, fixed_t
* y
, angle_t a
, fixed_t xorig
, fixed_t yorig
)
788 FixedMul(*x
- xorig
,finecosine
[a
>>ANGLETOFINESHIFT
])
789 - FixedMul(*y
- yorig
,finesine
[a
>>ANGLETOFINESHIFT
]);
792 FixedMul(*x
- xorig
,finesine
[a
>>ANGLETOFINESHIFT
])
793 + FixedMul(*y
- yorig
,finecosine
[a
>>ANGLETOFINESHIFT
]);
799 // AM_changeWindowScale()
803 // Passed nothing, returns nothing
805 void AM_changeWindowScale(void)
807 // Change the scaling multipliers
808 scale_mtof
= FixedMul(scale_mtof
, mtof_zoommul
);
809 scale_ftom
= FixedDiv(FRACUNIT
, scale_mtof
);
811 if (scale_mtof
< min_scale_mtof
)
812 AM_minOutWindowScale();
813 else if (scale_mtof
> max_scale_mtof
)
814 AM_maxOutWindowScale();
816 AM_activateNewScale();
820 // AM_doFollowPlayer()
822 // Turn on follow mode - the map scrolls opposite to player motion
824 // Passed nothing, returns nothing
826 void AM_doFollowPlayer(void)
828 if (f_oldloc
.x
!= plr
->mo
->x
|| f_oldloc
.y
!= plr
->mo
->y
)
830 m_x
= FTOM(MTOF(plr
->mo
->x
)) - m_w
/2;
831 m_y
= FTOM(MTOF(plr
->mo
->y
)) - m_h
/2;
834 f_oldloc
.x
= plr
->mo
->x
;
835 f_oldloc
.y
= plr
->mo
->y
;
842 // Updates on gametic - enter follow mode, zoom, or change map location
844 // Passed nothing, returns nothing
846 void AM_Ticker (void)
848 if (!(automapmode
& am_active
))
851 if (automapmode
& am_follow
)
854 // Change the zoom if necessary
855 if (ftom_zoommul
!= FRACUNIT
)
856 AM_changeWindowScale();
858 // Change x,y location
859 if (m_paninc
.x
|| m_paninc
.y
)
860 AM_changeWindowLoc();
866 // Automap clipping of lines.
868 // Based on Cohen-Sutherland clipping algorithm but with a slightly
869 // faster reject and precalculated slopes. If the speed is needed,
870 // use a hash algorithm to handle the common cases.
872 // Passed the line's coordinates on map and in the frame buffer performs
873 // clipping on them in the lines frame coordinates.
874 // Returns true if any part of line was not clipped
888 register int outcode1
= 0;
889 register int outcode2
= 0;
890 register int outside
;
892 fpoint_t tmp
= {0,0};
897 #define DOOUTCODE(oc, mx, my) \
899 if ((my) < 0) (oc) |= TOP; \
900 else if ((my) >= f_h) (oc) |= BOTTOM; \
901 if ((mx) < 0) (oc) |= LEFT; \
902 else if ((mx) >= f_w) (oc) |= RIGHT;
905 // do trivial rejects and outcodes
908 else if (ml
->a
.y
< m_y
)
913 else if (ml
->b
.y
< m_y
)
916 if (outcode1
& outcode2
)
917 return false; // trivially outside
921 else if (ml
->a
.x
> m_x2
)
926 else if (ml
->b
.x
> m_x2
)
929 if (outcode1
& outcode2
)
930 return false; // trivially outside
932 // transform to frame-buffer coordinates.
933 fl
->a
.x
= CXMTOF(ml
->a
.x
);
934 fl
->a
.y
= CYMTOF(ml
->a
.y
);
935 fl
->b
.x
= CXMTOF(ml
->b
.x
);
936 fl
->b
.y
= CYMTOF(ml
->b
.y
);
938 DOOUTCODE(outcode1
, fl
->a
.x
, fl
->a
.y
);
939 DOOUTCODE(outcode2
, fl
->b
.x
, fl
->b
.y
);
941 if (outcode1
& outcode2
)
944 while (outcode1
| outcode2
)
946 // may be partially inside box
947 // find an outside point
956 dy
= fl
->a
.y
- fl
->b
.y
;
957 dx
= fl
->b
.x
- fl
->a
.x
;
958 tmp
.x
= fl
->a
.x
+ (dx
*(fl
->a
.y
))/dy
;
961 else if (outside
& BOTTOM
)
963 dy
= fl
->a
.y
- fl
->b
.y
;
964 dx
= fl
->b
.x
- fl
->a
.x
;
965 tmp
.x
= fl
->a
.x
+ (dx
*(fl
->a
.y
-f_h
))/dy
;
968 else if (outside
& RIGHT
)
970 dy
= fl
->b
.y
- fl
->a
.y
;
971 dx
= fl
->b
.x
- fl
->a
.x
;
972 tmp
.y
= fl
->a
.y
+ (dy
*(f_w
-1 - fl
->a
.x
))/dx
;
975 else if (outside
& LEFT
)
977 dy
= fl
->b
.y
- fl
->a
.y
;
978 dx
= fl
->b
.x
- fl
->a
.x
;
979 tmp
.y
= fl
->a
.y
+ (dy
*(-fl
->a
.x
))/dx
;
983 if (outside
== outcode1
)
986 DOOUTCODE(outcode1
, fl
->a
.x
, fl
->a
.y
);
991 DOOUTCODE(outcode2
, fl
->b
.x
, fl
->b
.y
);
994 if (outcode1
& outcode2
)
995 return false; // trivially outside
1005 // Draw a line in the frame buffer.
1006 // Classic Bresenham w/ whatever optimizations needed for speed
1008 // Passed the frame coordinates of line, and the color to be drawn
1026 #ifdef RANGECHECK // killough 2/22/98
1027 static int fuck
= 0;
1029 // For debugging only
1032 fl
->a
.x
< 0 || fl
->a
.x
>= f_w
1033 || fl
->a
.y
< 0 || fl
->a
.y
>= f_h
1034 || fl
->b
.x
< 0 || fl
->b
.x
>= f_w
1035 || fl
->b
.y
< 0 || fl
->b
.y
>= f_h
1038 //jff 8/3/98 use logical output routine
1039 printf("fuck %d \r", fuck
++);
1044 #define PUTDOT(xx,yy,cc) V_PlotPixel(FB,xx,yy,(byte)cc)
1046 dx
= fl
->b
.x
- fl
->a
.x
;
1047 ax
= 2 * (dx
<0 ? -dx
: dx
);
1050 dy
= fl
->b
.y
- fl
->a
.y
;
1051 ay
= 2 * (dy
<0 ? -dy
: dy
);
1063 if (x
== fl
->b
.x
) return;
1078 PUTDOT(x
, y
, color
);
1079 if (y
== fl
->b
.y
) return;
1095 // Clip lines, draw visible parts of lines.
1097 // Passed the map coordinates of the line, and the color to draw it
1098 // Color -1 is special and prevents drawing. Color 247 is special and
1099 // is translated to black, allowing Color 0 to represent feature disable
1100 // in the defaults file.
1109 if (color
==-1) // jff 4/3/98 allow not drawing any sort of line
1110 return; // by setting its color to -1
1111 if (color
==247) // jff 4/3/98 if color is 247 (xparent), use black
1114 if (AM_clipMline(ml
, &fl
))
1115 AM_drawFline(&fl
, color
); // draws it on frame buffer using fb coords
1121 // Draws blockmap aligned grid lines.
1123 // Passed the color to draw the grid lines
1126 void AM_drawGrid(int color
)
1132 // Figure out start of vertical gridlines
1134 if ((start
-bmaporgx
)%(MAPBLOCKUNITS
<<FRACBITS
))
1135 start
+= (MAPBLOCKUNITS
<<FRACBITS
)
1136 - ((start
-bmaporgx
)%(MAPBLOCKUNITS
<<FRACBITS
));
1139 // draw vertical gridlines
1142 for (x
=start
; x
<end
; x
+=(MAPBLOCKUNITS
<<FRACBITS
))
1146 AM_drawMline(&ml
, color
);
1149 // Figure out start of horizontal gridlines
1151 if ((start
-bmaporgy
)%(MAPBLOCKUNITS
<<FRACBITS
))
1152 start
+= (MAPBLOCKUNITS
<<FRACBITS
)
1153 - ((start
-bmaporgy
)%(MAPBLOCKUNITS
<<FRACBITS
));
1156 // draw horizontal gridlines
1159 for (y
=start
; y
<end
; y
+=(MAPBLOCKUNITS
<<FRACBITS
))
1163 AM_drawMline(&ml
, color
);
1170 // Returns the 'color' or key needed for a door linedef type
1172 // Passed the type of linedef, returns:
1173 // -1 if not a keyed door
1174 // 0 if a red key required
1175 // 1 if a blue key required
1176 // 2 if a yellow key required
1177 // 3 if a multiple keys required
1179 // jff 4/3/98 add routine to get color of generalized keyed door
1181 int AM_DoorColor(int type
)
1183 if (GenLockedBase
<= type
&& type
< GenDoorBase
)
1185 type
-= GenLockedBase
;
1186 type
= (type
& LockedKey
) >> LockedKeyShift
;
1187 if (!type
|| type
==7)
1188 return 3; //any or all keys
1189 else return (type
-1)%3;
1191 switch (type
) // closed keyed door
1193 case 26: case 32: case 99: case 133:
1196 case 27: case 34: case 136: case 137:
1199 case 28: case 33: case 134: case 135:
1203 return -1; //not a keyed door
1205 return -1; //not a keyed door
1209 // Determines visible lines, draws them.
1210 // This is LineDef based, not LineSeg based.
1212 // jff 1/5/98 many changes in this routine
1213 // backward compatibility not needed, so just changes, no ifs
1214 // addition of clauses for:
1215 // doors opening, keyed door id, secret sectors,
1216 // teleports, exit lines, key things
1217 // ability to suppress any of added features or lines with no height changes
1219 // support for gamma correction in automap abandoned
1221 // jff 4/3/98 changed mapcolor_xxxx=0 as control to disable feature
1222 // jff 4/3/98 changed mapcolor_xxxx=-1 to disable drawing line completely
1224 void AM_drawWalls(void)
1229 // draw the unclipped visible portions of all lines
1230 for (i
=0;i
<numlines
;i
++)
1232 l
.a
.x
= lines
[i
].v1
->x
;
1233 l
.a
.y
= lines
[i
].v1
->y
;
1234 l
.b
.x
= lines
[i
].v2
->x
;
1235 l
.b
.y
= lines
[i
].v2
->y
;
1237 if (automapmode
& am_rotate
) {
1238 AM_rotate(&l
.a
.x
, &l
.a
.y
, ANG90
-plr
->mo
->angle
, plr
->mo
->x
, plr
->mo
->y
);
1239 AM_rotate(&l
.b
.x
, &l
.b
.y
, ANG90
-plr
->mo
->angle
, plr
->mo
->x
, plr
->mo
->y
);
1242 // if line has been seen or IDDT has been used
1243 if (ddt_cheating
|| (lines
[i
].flags
& ML_MAPPED
))
1245 if ((lines
[i
].flags
& ML_DONTDRAW
) && !ddt_cheating
)
1248 /* cph - show keyed doors and lines */
1250 if ((mapcolor_bdor
|| mapcolor_ydor
|| mapcolor_rdor
) &&
1251 !(lines
[i
].flags
& ML_SECRET
) && /* non-secret */
1252 (amd
= AM_DoorColor(lines
[i
].special
)) != -1
1256 switch (amd
) /* closed keyed door */
1261 mapcolor_bdor
? mapcolor_bdor
: mapcolor_cchg
);
1266 mapcolor_ydor
? mapcolor_ydor
: mapcolor_cchg
);
1271 mapcolor_rdor
? mapcolor_rdor
: mapcolor_cchg
);
1276 mapcolor_clsd
? mapcolor_clsd
: mapcolor_cchg
);
1282 if /* jff 4/23/98 add exit lines to automap */
1286 lines
[i
].special
==11 ||
1287 lines
[i
].special
==52 ||
1288 lines
[i
].special
==197 ||
1289 lines
[i
].special
==51 ||
1290 lines
[i
].special
==124 ||
1291 lines
[i
].special
==198
1294 AM_drawMline(&l
, mapcolor_exit
); /* exit line */
1298 if (!lines
[i
].backsector
)
1300 // jff 1/10/98 add new color for 1S secret sector boundary
1301 if (mapcolor_secr
&& //jff 4/3/98 0 is disable
1305 P_WasSecret(lines
[i
].frontsector
) &&
1306 !P_IsSecret(lines
[i
].frontsector
)
1310 !map_secret_after
&&
1311 P_WasSecret(lines
[i
].frontsector
)
1315 AM_drawMline(&l
, mapcolor_secr
); // line bounding secret sector
1316 else //jff 2/16/98 fixed bug
1317 AM_drawMline(&l
, mapcolor_wall
); // special was cleared
1319 else /* now for 2S lines */
1321 // jff 1/10/98 add color change for all teleporter types
1324 mapcolor_tele
&& !(lines
[i
].flags
& ML_SECRET
) &&
1325 (lines
[i
].special
== 39 || lines
[i
].special
== 97 ||
1326 lines
[i
].special
== 125 || lines
[i
].special
== 126)
1329 AM_drawMline(&l
, mapcolor_tele
);
1331 else if (lines
[i
].flags
& ML_SECRET
) // secret door
1333 AM_drawMline(&l
, mapcolor_wall
); // wall color
1338 !(lines
[i
].flags
& ML_SECRET
) && // non-secret closed door
1339 ((lines
[i
].backsector
->floorheight
==lines
[i
].backsector
->ceilingheight
) ||
1340 (lines
[i
].frontsector
->floorheight
==lines
[i
].frontsector
->ceilingheight
))
1343 AM_drawMline(&l
, mapcolor_clsd
); // non-secret closed door
1344 } //jff 1/6/98 show secret sector 2S lines
1347 mapcolor_secr
&& //jff 2/16/98 fixed bug
1348 ( // special was cleared after getting it
1349 (map_secret_after
&&
1351 (P_WasSecret(lines
[i
].frontsector
)
1352 && !P_IsSecret(lines
[i
].frontsector
)) ||
1353 (P_WasSecret(lines
[i
].backsector
)
1354 && !P_IsSecret(lines
[i
].backsector
))
1357 || //jff 3/9/98 add logic to not show secret til after entered
1358 ( // if map_secret_after is true
1359 !map_secret_after
&&
1360 (P_WasSecret(lines
[i
].frontsector
) ||
1361 P_WasSecret(lines
[i
].backsector
))
1366 AM_drawMline(&l
, mapcolor_secr
); // line bounding secret sector
1367 } //jff 1/6/98 end secret sector line change
1368 else if (lines
[i
].backsector
->floorheight
!=
1369 lines
[i
].frontsector
->floorheight
)
1371 AM_drawMline(&l
, mapcolor_fchg
); // floor level change
1373 else if (lines
[i
].backsector
->ceilingheight
!=
1374 lines
[i
].frontsector
->ceilingheight
)
1376 AM_drawMline(&l
, mapcolor_cchg
); // ceiling level change
1378 else if (mapcolor_flat
&& ddt_cheating
)
1380 AM_drawMline(&l
, mapcolor_flat
); //2S lines that appear only in IDDT
1383 } // now draw the lines only visible because the player has computermap
1384 else if (plr
->powers
[pw_allmap
]) // computermap visible lines
1386 if (!(lines
[i
].flags
& ML_DONTDRAW
)) // invisible flag lines do not show
1392 !lines
[i
].backsector
1394 lines
[i
].backsector
->floorheight
1395 != lines
[i
].frontsector
->floorheight
1397 lines
[i
].backsector
->ceilingheight
1398 != lines
[i
].frontsector
->ceilingheight
1400 AM_drawMline(&l
, mapcolor_unsn
);
1407 // AM_drawLineCharacter()
1409 // Draws a vector graphic according to numerous parameters
1411 // Passed the structure defining the vector graphic shape, the number
1412 // of vectors in it, the scale to draw it at, the angle to draw it at,
1413 // the color to draw it with, and the map coordinates to draw it at.
1416 void AM_drawLineCharacter
1428 if (automapmode
& am_rotate
) angle
-= plr
->mo
->angle
- ANG90
; // cph
1430 for (i
=0;i
<lineguylines
;i
++)
1432 l
.a
.x
= lineguy
[i
].a
.x
;
1433 l
.a
.y
= lineguy
[i
].a
.y
;
1437 l
.a
.x
= FixedMul(scale
, l
.a
.x
);
1438 l
.a
.y
= FixedMul(scale
, l
.a
.y
);
1442 AM_rotate(&l
.a
.x
, &l
.a
.y
, angle
, 0, 0);
1447 l
.b
.x
= lineguy
[i
].b
.x
;
1448 l
.b
.y
= lineguy
[i
].b
.y
;
1452 l
.b
.x
= FixedMul(scale
, l
.b
.x
);
1453 l
.b
.y
= FixedMul(scale
, l
.b
.y
);
1457 AM_rotate(&l
.b
.x
, &l
.b
.y
, angle
, 0, 0);
1462 AM_drawMline(&l
, color
);
1469 // Draws the player arrow in single player,
1470 // or all the player arrows in a netgame.
1472 // Passed nothing, returns nothing
1474 void AM_drawPlayers(void)
1481 AM_drawLineCharacter
1487 mapcolor_sngl
, //jff color
1492 AM_drawLineCharacter
1498 mapcolor_sngl
, //jff color
1504 for (i
=0;i
<MAXPLAYERS
;i
++) {
1505 player_t
* p
= &players
[i
];
1507 if ( (deathmatch
&& !singledemo
) && p
!= plr
)
1510 if (playeringame
[i
]) {
1511 fixed_t x
= p
->mo
->x
, y
= p
->mo
->y
;
1512 if (automapmode
& am_rotate
)
1513 AM_rotate(&x
, &y
, ANG90
-plr
->mo
->angle
, plr
->mo
->x
, plr
->mo
->y
);
1515 AM_drawLineCharacter (player_arrow
, NUMPLYRLINES
, 0, p
->mo
->angle
,
1516 p
->powers
[pw_invisibility
] ? 246 /* *close* to black */
1517 : mapcolor_plyr
[i
], //jff 1/6/98 use default color
1526 // Draws the things on the automap in double IDDT cheat mode
1528 // Passed colors and colorrange, no longer used
1541 for (i
=0;i
<numsectors
;i
++)
1543 t
= sectors
[i
].thinglist
;
1544 while (t
) // for all things in that sector
1546 fixed_t x
= t
->x
, y
= t
->y
;
1548 if (automapmode
& am_rotate
)
1549 AM_rotate(&x
, &y
, ANG90
-plr
->mo
->angle
, plr
->mo
->x
, plr
->mo
->y
);
1551 //jff 1/5/98 case over doomednum of thing being drawn
1552 if (mapcolor_rkey
|| mapcolor_ykey
|| mapcolor_bkey
)
1554 switch(t
->info
->doomednum
)
1556 //jff 1/5/98 treat keys special
1557 case 38: case 13: //jff red key
1558 AM_drawLineCharacter
1564 mapcolor_rkey
!=-1? mapcolor_rkey
: mapcolor_sprt
,
1569 case 39: case 6: //jff yellow key
1570 AM_drawLineCharacter
1576 mapcolor_ykey
!=-1? mapcolor_ykey
: mapcolor_sprt
,
1581 case 40: case 5: //jff blue key
1582 AM_drawLineCharacter
1588 mapcolor_bkey
!=-1? mapcolor_bkey
: mapcolor_sprt
,
1597 //jff 1/5/98 end added code for keys
1598 //jff previously entire code
1599 AM_drawLineCharacter
1602 NUMTHINTRIANGLEGUYLINES
,
1605 t
->flags
& MF_FRIEND
&& !t
->player
? mapcolor_frnd
:
1606 /* bbm 2/28/03 Show countable items in yellow. */
1607 t
->flags
& MF_COUNTITEM
? mapcolor_item
: mapcolor_sprt
,
1618 // Draw the marked locations on the automap
1620 // Passed nothing, returns nothing
1622 // killough 2/22/98:
1623 // Rewrote AM_drawMarks(). Removed limit on marks.
1625 void AM_drawMarks(void)
1628 for (i
=0;i
<markpointnum
;i
++) // killough 2/22/98: remove automap mark limit
1629 if (markpoints
[i
].x
!= -1)
1633 int fx
= markpoints
[i
].x
;
1634 int fy
= markpoints
[i
].y
;
1637 if (automapmode
& am_rotate
)
1638 AM_rotate(&fx
, &fy
, ANG90
-plr
->mo
->angle
, plr
->mo
->x
, plr
->mo
->y
);
1640 fx
= CXMTOF(fx
); fy
= CYMTOF(fy
);
1645 if (d
==1) // killough 2/22/98: less spacing for '1'
1648 if (fx
>= f_x
&& fx
< f_w
- w
&& fy
>= f_y
&& fy
< f_h
- h
) {
1649 // cph - construct patch name and draw marker
1650 char namebuf
[] = { 'A', 'M', 'M', 'N', 'U', 'M', '0'+d
, 0 };
1652 V_DrawNamePatch(fx
, fy
, FB
, namebuf
, CR_DEFAULT
, VPT_NONE
);
1654 fx
-= w
-1; // killough 2/22/98: 1 space backwards
1662 // AM_drawCrosshair()
1664 // Draw the single point crosshair representing map center
1666 // Passed the color to draw the pixel with
1669 // CPhipps - made static inline, and use the general pixel plotter function
1671 inline static void AM_drawCrosshair(int color
)
1673 // single point for now
1674 V_PlotPixel(FB
, f_w
/2, f_h
/2, (byte
)color
);
1680 // Draws the entire automap
1682 // Passed nothing, returns nothing
1684 void AM_Drawer (void)
1686 // CPhipps - all automap modes put into one enum
1687 if (!(automapmode
& am_active
)) return;
1689 if (!(automapmode
& am_overlay
)) // cph - If not overlay mode, clear background for the automap
1690 V_FillRect(FB
, f_x
, f_y
, f_w
, f_h
, (byte
)mapcolor_back
); //jff 1/5/98 background default color
1691 if (automapmode
& am_grid
)
1692 AM_drawGrid(mapcolor_grid
); //jff 1/7/98 grid default color
1695 if (ddt_cheating
==2)
1696 AM_drawThings(mapcolor_sprt
, 0); //jff 1/5/98 default double IDDT sprite
1697 AM_drawCrosshair(mapcolor_hair
); //jff 1/7/98 default crosshair color
1701 V_MarkRect(f_x
, f_y
, f_w
, f_h
);