1 // Emacs style mode select -*- C++ -*-
2 //-----------------------------------------------------------------------------
6 // Copyright (C) 1993-1996 by id Software, Inc.
8 // This source is available for distribution and/or modification
9 // only under the terms of the DOOM Source Code License as
10 // published by id Software. All rights reserved.
12 // The source is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
19 // Revision 1.1 2000/02/29 18:21:03 stegerg
20 // Doom port based on ADoomPPC. Read README.AROS!
23 // DESCRIPTION: the automap code
25 //-----------------------------------------------------------------------------
27 static const char rcsid
[] = "$Id$";
41 // Needs access to LFB.
54 // For use if I do walls with outsides/insides
55 #define REDS (256-5*16)
57 #define BLUES (256-4*16+8)
65 #define YELLOWS (256-32+7)
68 #define WHITE (256-47)
71 #define BACKGROUND BLACK
72 #define YOURCOLORS WHITE
74 #define WALLCOLORS REDS
75 #define WALLRANGE REDRANGE
76 #define TSWALLCOLORS GRAYS
77 #define TSWALLRANGE GRAYSRANGE
78 #define FDWALLCOLORS BROWNS
79 #define FDWALLRANGE BROWNRANGE
80 #define CDWALLCOLORS YELLOWS
81 #define CDWALLRANGE YELLOWRANGE
82 #define THINGCOLORS GREENS
83 #define THINGRANGE GREENRANGE
84 #define SECRETWALLCOLORS WALLCOLORS
85 #define SECRETWALLRANGE WALLRANGE
86 #define GRIDCOLORS (GRAYS + GRAYSRANGE/2)
88 #define XHAIRCOLORS GRAYS
93 #define AM_PANDOWNKEY KEY_DOWNARROW
94 #define AM_PANUPKEY KEY_UPARROW
95 #define AM_PANRIGHTKEY KEY_RIGHTARROW
96 #define AM_PANLEFTKEY KEY_LEFTARROW
97 #define AM_ZOOMINKEY '='
98 #define AM_ZOOMOUTKEY '-'
99 #define AM_STARTKEY KEY_TAB
100 #define AM_ENDKEY KEY_TAB
101 #define AM_GOBIGKEY '0'
102 #define AM_FOLLOWKEY 'f'
103 #define AM_GRIDKEY 'g'
104 #define AM_MARKKEY 'm'
105 #define AM_CLEARMARKKEY 'c'
106 #define AM_CHANGETYPE 'z' /* 't' conflicts with HU_INPUTTOGGLE, hu_stuff.c */
108 #define AM_NUMMARKPOINTS 10
111 #define INITSCALEMTOF (.2*FRACUNIT)
112 // how much the automap moves window per tic in frame-buffer coordinates
113 // moves 140 pixels in 1 second
115 // how much zoom-in per tic
116 // goes to 2x in 1 second
117 #define M_ZOOMIN ((int) (1.02*FRACUNIT))
118 // how much zoom-out per tic
119 // pulls out to 0.5x in 1 second
120 #define M_ZOOMOUT ((int) (FRACUNIT/1.02))
122 // translates between frame-buffer and map distances
123 #define FTOM(x) FixedMul(((x)<<16),scale_ftom)
124 #define MTOF(x) (FixedMul((x),scale_mtof)>>16)
125 // translates between frame-buffer and map coordinates
126 #define CXMTOF(x) (f_x + MTOF((x)-m_x))
127 #define CYMTOF(y) (f_y + (f_h - MTOF((y)-m_y)))
129 // the following is crap
130 #define LINE_NEVERSEE ML_DONTDRAW
160 // The vector graphics for the automap.
161 // A line drawing of the player pointing right,
162 // starting from the middle.
164 #define R ((8*PLAYERRADIUS)/7)
165 mline_t player_arrow
[] = {
166 { { -R
+R
/8, 0 }, { R
, 0 } }, // -----
167 { { R
, 0 }, { R
-R
/2, R
/4 } }, // ----->
168 { { R
, 0 }, { R
-R
/2, -R
/4 } },
169 { { -R
+R
/8, 0 }, { -R
-R
/8, R
/4 } }, // >---->
170 { { -R
+R
/8, 0 }, { -R
-R
/8, -R
/4 } },
171 { { -R
+3*R
/8, 0 }, { -R
+R
/8, R
/4 } }, // >>--->
172 { { -R
+3*R
/8, 0 }, { -R
+R
/8, -R
/4 } }
175 #define NUMPLYRLINES (sizeof(player_arrow)/sizeof(mline_t))
177 #define R ((8*PLAYERRADIUS)/7)
178 mline_t cheat_player_arrow
[] = {
179 { { -R
+R
/8, 0 }, { R
, 0 } }, // -----
180 { { R
, 0 }, { R
-R
/2, R
/6 } }, // ----->
181 { { R
, 0 }, { R
-R
/2, -R
/6 } },
182 { { -R
+R
/8, 0 }, { -R
-R
/8, R
/6 } }, // >----->
183 { { -R
+R
/8, 0 }, { -R
-R
/8, -R
/6 } },
184 { { -R
+3*R
/8, 0 }, { -R
+R
/8, R
/6 } }, // >>----->
185 { { -R
+3*R
/8, 0 }, { -R
+R
/8, -R
/6 } },
186 { { -R
/2, 0 }, { -R
/2, -R
/6 } }, // >>-d--->
187 { { -R
/2, -R
/6 }, { -R
/2+R
/6, -R
/6 } },
188 { { -R
/2+R
/6, -R
/6 }, { -R
/2+R
/6, R
/4 } },
189 { { -R
/6, 0 }, { -R
/6, -R
/6 } }, // >>-dd-->
190 { { -R
/6, -R
/6 }, { 0, -R
/6 } },
191 { { 0, -R
/6 }, { 0, R
/4 } },
192 { { R
/6, R
/4 }, { R
/6, -R
/7 } }, // >>-ddt->
193 { { R
/6, -R
/7 }, { R
/6+R
/32, -R
/7-R
/32 } },
194 { { R
/6+R
/32, -R
/7-R
/32 }, { R
/6+R
/10, -R
/7 } }
197 #define NUMCHEATPLYRLINES (sizeof(cheat_player_arrow)/sizeof(mline_t))
200 mline_t triangle_guy
[] = {
201 { { -.867*R
, -.5*R
}, { .867*R
, -.5*R
} },
202 { { .867*R
, -.5*R
} , { 0, R
} },
203 { { 0, R
}, { -.867*R
, -.5*R
} }
206 #define NUMTRIANGLEGUYLINES (sizeof(triangle_guy)/sizeof(mline_t))
209 mline_t thintriangle_guy
[] = {
210 { { -.5*R
, -.7*R
}, { R
, 0 } },
211 { { R
, 0 }, { -.5*R
, .7*R
} },
212 { { -.5*R
, .7*R
}, { -.5*R
, -.7*R
} }
215 #define NUMTHINTRIANGLEGUYLINES (sizeof(thintriangle_guy)/sizeof(mline_t))
220 static int cheating
= 0;
223 static int leveljuststarted
= 1; // kluge until AM_LevelInit() is called
225 boolean automapactive
= false;
227 static int finit_width
;
228 static int finit_height
;
230 extern int viewwidth
; /* CDE'98 - Need this for maponhu */
231 extern int viewheight
; /* CDE'98 - Need this for maponhu */
232 extern int viewwindowx
; /* CDE'98 - Need this for maponhu */
233 extern int viewwindowy
; /* CDE'98 - Need this for maponhu */
235 int wx
; /* CDE'98 - x offset from view */
236 int wy
; /* CDE'98 - y offset from view */
238 // location of window on screen
242 // size of window on screen
246 static int lightlev
; // used for funky strobing effect
247 static byte
* fb
; // pseudo-frame buffer
250 static mpoint_t m_paninc
; // how far the window pans each tic (map coords)
251 static fixed_t mtof_zoommul
; // how far the window zooms in each tic (map coords)
252 static fixed_t ftom_zoommul
; // how far the window zooms in each tic (fb coords)
254 static fixed_t m_x
, m_y
; // LL x,y where the window is on the map (map coords)
255 static fixed_t m_x2
, m_y2
; // UR x,y where the window is on the map (map coords)
258 // width/height of window on map (map coords)
263 // based on level size
264 static fixed_t min_x
;
265 static fixed_t min_y
;
266 static fixed_t max_x
;
267 static fixed_t max_y
;
269 static fixed_t max_w
; // max_x-min_x,
270 static fixed_t max_h
; // max_y-min_y
272 // based on player size
273 static fixed_t min_w
;
274 static fixed_t min_h
;
277 static fixed_t min_scale_mtof
; // used to tell when to stop zooming out
278 static fixed_t max_scale_mtof
; // used to tell when to stop zooming in
280 // old stuff for recovery later
281 static fixed_t old_m_w
, old_m_h
;
282 static fixed_t old_m_x
, old_m_y
;
284 // old location used by the Follower routine
285 static mpoint_t f_oldloc
;
287 // used by MTOF to scale from map-to-frame-buffer coords
288 static fixed_t scale_mtof
= INITSCALEMTOF
;
289 // used by FTOM to scale from frame-buffer-to-map coords (=1/scale_mtof)
290 static fixed_t scale_ftom
;
292 static player_t
*plr
; // the player represented by an arrow
294 static patch_t
*marknums
[10]; // numbers used for marking by the automap
295 static mpoint_t markpoints
[AM_NUMMARKPOINTS
]; // where the points are
296 static int markpointnum
= 0; // next point to be assigned
298 static int followplayer
= 1; // specifies whether to follow the player around
301 unsigned char cheat_amap_seq
[] = { 0xb2, 0x26, 0x26, 0x2e, 0xff };
302 static cheatseq_t cheat_amap
= { cheat_amap_seq
, 0 };
304 static boolean stopped
= true;
306 extern boolean viewactive
;
307 extern boolean rotatemap
;
311 //extern byte screens[][SCREENWIDTH*SCREENHEIGHT];
324 // Used to rotate player arrow line character.
335 FixedMul(*x
,finecosine
[a
>>ANGLETOFINESHIFT
])
336 - FixedMul(*y
,finesine
[a
>>ANGLETOFINESHIFT
]);
339 FixedMul(*x
,finesine
[a
>>ANGLETOFINESHIFT
])
340 + FixedMul(*y
,finecosine
[a
>>ANGLETOFINESHIFT
]);
345 // Calculates the slope and slope according to the x-axis of a line
346 // segment in map coordinates (with the upright y-axis n' all) so
347 // that it can be used with the brain-dead drawing stuff.
356 dy
= ml
->a
.y
- ml
->b
.y
;
357 dx
= ml
->b
.x
- ml
->a
.x
;
358 if (!dy
) is
->islp
= (dx
<0?-MAXINT
:MAXINT
);
359 else is
->islp
= FixedDiv(dx
, dy
);
360 if (!dx
) is
->slp
= (dy
<0?-MAXINT
:MAXINT
);
361 else is
->slp
= FixedDiv(dy
, dx
);
368 void AM_activateNewScale(void)
372 m_x
= plr
->mo
->x
- m_w
/2;
373 m_y
= plr
->mo
->y
- m_h
/2;
392 void AM_saveScaleAndLoc(void)
403 void AM_restoreScaleAndLoc(void)
413 m_x
= plr
->mo
->x
- m_w
/2;
414 m_y
= plr
->mo
->y
- m_h
/2;
419 // Change the scaling multipliers
420 scale_mtof
= FixedDiv(f_w
<<FRACBITS
, m_w
);
421 scale_ftom
= FixedDiv(FRACUNIT
, scale_mtof
);
425 // adds a marker at the current location
427 void AM_addMark(void)
429 markpoints
[markpointnum
].x
= m_x
+ m_w
/2;
430 markpoints
[markpointnum
].y
= m_y
+ m_h
/2;
431 markpointnum
= (markpointnum
+ 1) % AM_NUMMARKPOINTS
;
436 // Determines bounding box of all vertices,
437 // sets global variables controlling zoom range.
439 void AM_findMinMaxBoundaries(void)
445 min_x
= min_y
= MAXINT
;
446 max_x
= max_y
= -MAXINT
;
448 for (i
=0;i
<numvertexes
;i
++)
450 if (vertexes
[i
].x
< min_x
)
451 min_x
= vertexes
[i
].x
;
452 else if (vertexes
[i
].x
> max_x
)
453 max_x
= vertexes
[i
].x
;
455 if (vertexes
[i
].y
< min_y
)
456 min_y
= vertexes
[i
].y
;
457 else if (vertexes
[i
].y
> max_y
)
458 max_y
= vertexes
[i
].y
;
461 max_w
= max_x
- min_x
;
462 max_h
= max_y
- min_y
;
464 min_w
= 2*PLAYERRADIUS
; // const? never changed?
465 min_h
= 2*PLAYERRADIUS
;
467 a
= FixedDiv(f_w
<<FRACBITS
, max_w
);
468 b
= FixedDiv(f_h
<<FRACBITS
, max_h
);
470 min_scale_mtof
= a
< b
? a
: b
;
471 max_scale_mtof
= FixedDiv(f_h
<<FRACBITS
, 2*PLAYERRADIUS
);
479 void AM_changeWindowLoc(void)
481 if (m_paninc
.x
|| m_paninc
.y
)
487 /* CDE'98 Rotate Map Patch - Rotate paninc or not ?? make your choice ... */
494 AM_rotate(&x, &y, ANG90-plr->mo->angle);
505 /* CDE'98 - checking for limit is disabled while in rotate mode */
506 /* should not cause any problem */
509 if (m_x
+ m_w
/2 > max_x
)
511 else if (m_x
+ m_w
/2 < min_x
)
514 if (m_y
+ m_h
/2 > max_y
)
516 else if (m_y
+ m_h
/2 < min_y
)
530 void AM_initMapSize(void)
532 /* CDE'98 - Calculate view position and size */
548 wx
= viewwindowx
+viewwidth
/14;
549 wy
= viewwindowy
+viewheight
/14;
554 wx
= viewwindowx
+viewwidth
/14;
555 wy
= viewwindowy
+viewheight
/14;
560 wx
= viewwindowx
+viewwidth
/14;
561 wy
= viewwindowy
+viewheight
/14;
574 void resinit_am_map (void)
576 finit_width
= SCREENWIDTH
;
577 finit_height
= SCREENHEIGHT
- 32;
583 void AM_initVariables(void)
586 static event_t st_notify
= { ev_keyup
, AM_MSGENTERED
};
591 automapactive
= true;
598 m_paninc
.x
= m_paninc
.y
= 0;
599 ftom_zoommul
= FRACUNIT
;
600 mtof_zoommul
= FRACUNIT
;
602 // CDE'98 Should make this first to avoid plr=NULL :)
603 // Find player to center on initially
604 if (!playeringame
[pnum
= consoleplayer
])
605 for (pnum
=0;pnum
<MAXPLAYERS
;pnum
++)
606 if (playeringame
[pnum
])
609 plr
= &players
[pnum
];
611 // CDE'98 - Calculate view position and size/scale
617 // CDE'98 Change the scaling multipliers
620 a
= FixedDiv(f_w
<<FRACBITS
, max_w
);
621 b
= FixedDiv(f_h
<<FRACBITS
, max_h
);
623 min_scale_mtof
= a
< b
? a
: b
;
624 max_scale_mtof
= FixedDiv(f_h
<<FRACBITS
, 2*PLAYERRADIUS
);
626 scale_mtof
= FixedDiv(f_w
<<FRACBITS
, m_w_old
);
627 scale_ftom
= FixedDiv(FRACUNIT
, scale_mtof
);
628 AM_activateNewScale();
631 // CDE'98 Center on our player
632 m_x
= plr
->mo
->x
- m_w
/2;
633 m_y
= plr
->mo
->y
- m_h
/2;
634 AM_changeWindowLoc();
636 // for saving & restoring
642 // inform the status bar of the change
643 ST_Responder(&st_notify
);
649 void AM_loadPics(void)
656 sprintf(namebuf
, "AMMNUM%d", i
);
657 marknums
[i
] = W_CacheLumpName(namebuf
, PU_STATIC
);
662 void AM_unloadPics(void)
667 Z_ChangeTag(marknums
[i
], PU_CACHE
);
671 void AM_clearMarks(void)
675 for (i
=0;i
<AM_NUMMARKPOINTS
;i
++)
676 markpoints
[i
].x
= -1; // means empty
683 // should be called at the start of every level
684 // right now, i figure it out myself
686 void AM_LevelInit(void)
688 leveljuststarted
= 0;
696 AM_findMinMaxBoundaries();
697 scale_mtof
= FixedDiv(min_scale_mtof
, (int) (0.7*FRACUNIT
));
698 if (scale_mtof
> max_scale_mtof
)
699 scale_mtof
= min_scale_mtof
;
700 scale_ftom
= FixedDiv(FRACUNIT
, scale_mtof
);
711 static event_t st_notify
= { 0, ev_keyup
, AM_MSGEXITED
};
714 automapactive
= false;
715 ST_Responder(&st_notify
);
724 static int lastlevel
= -1, lastepisode
= -1;
726 if (!stopped
) AM_Stop();
728 if (lastlevel
!= gamemap
|| lastepisode
!= gameepisode
)
732 lastepisode
= gameepisode
;
739 // set the window scale to the maximum size
741 void AM_minOutWindowScale(void)
743 scale_mtof
= min_scale_mtof
;
744 scale_ftom
= FixedDiv(FRACUNIT
, scale_mtof
);
745 AM_activateNewScale();
749 // set the window scale to the minimum size
751 void AM_maxOutWindowScale(void)
753 scale_mtof
= max_scale_mtof
;
754 scale_ftom
= FixedDiv(FRACUNIT
, scale_mtof
);
755 AM_activateNewScale();
760 // Handle events (user inputs) in automap mode
768 static int cheatstate
=0;
769 static int bigstate
=0;
770 static char buffer
[20];
776 if (ev
->type
== ev_keydown
&& ev
->data1
== AM_STARTKEY
)
779 /* CDE'98 Map on Headup Patch */
780 viewactive
= (maponhu
!= 0);
785 else if (ev
->type
== ev_keydown
)
791 case AM_PANRIGHTKEY
: // pan right
792 if (!followplayer
) m_paninc
.x
= FTOM(F_PANINC
);
795 case AM_PANLEFTKEY
: // pan left
796 if (!followplayer
) m_paninc
.x
= -FTOM(F_PANINC
);
799 case AM_PANUPKEY
: // pan up
800 if (!followplayer
) m_paninc
.y
= FTOM(F_PANINC
);
803 case AM_PANDOWNKEY
: // pan down
804 if (!followplayer
) m_paninc
.y
= -FTOM(F_PANINC
);
807 case AM_ZOOMOUTKEY
: // zoom out
808 mtof_zoommul
= M_ZOOMOUT
;
809 ftom_zoommul
= M_ZOOMIN
;
811 case AM_ZOOMINKEY
: // zoom in
812 mtof_zoommul
= M_ZOOMIN
;
813 ftom_zoommul
= M_ZOOMOUT
;
816 bigstate
= !bigstate
;
819 AM_saveScaleAndLoc();
820 AM_minOutWindowScale();
822 else AM_restoreScaleAndLoc();
825 followplayer
= !followplayer
;
827 plr
->message
= followplayer
? AMSTR_FOLLOWON
: AMSTR_FOLLOWOFF
;
831 plr
->message
= grid
? AMSTR_GRIDON
: AMSTR_GRIDOFF
;
834 sprintf(buffer
, "%s %d", AMSTR_MARKEDSPOT
, markpointnum
);
835 plr
->message
= buffer
;
838 case AM_CLEARMARKKEY
:
840 plr
->message
= AMSTR_MARKSCLEARED
;
844 if(maponhu
>=MAX_HUTYPE
)
847 viewactive
= (maponhu
!= 0);
859 if (!deathmatch
&& cht_CheckCheat(&cheat_amap
, ev
->data1
))
862 cheating
= (cheating
+1) % 3;
866 else if (ev
->type
== ev_keyup
)
872 if (!followplayer
) m_paninc
.x
= 0;
875 if (!followplayer
) m_paninc
.x
= 0;
878 if (!followplayer
) m_paninc
.y
= 0;
881 if (!followplayer
) m_paninc
.y
= 0;
885 mtof_zoommul
= FRACUNIT
;
886 ftom_zoommul
= FRACUNIT
;
899 void AM_changeWindowScale(void)
902 // Change the scaling multipliers
903 scale_mtof
= FixedMul(scale_mtof
, mtof_zoommul
);
904 scale_ftom
= FixedDiv(FRACUNIT
, scale_mtof
);
906 if (scale_mtof
< min_scale_mtof
)
907 AM_minOutWindowScale();
908 else if (scale_mtof
> max_scale_mtof
)
909 AM_maxOutWindowScale();
911 AM_activateNewScale();
918 void AM_doFollowPlayer(void)
921 if (f_oldloc
.x
!= plr
->mo
->x
|| f_oldloc
.y
!= plr
->mo
->y
)
923 m_x
= FTOM(MTOF(plr
->mo
->x
)) - m_w
/2;
924 m_y
= FTOM(MTOF(plr
->mo
->y
)) - m_h
/2;
927 f_oldloc
.x
= plr
->mo
->x
;
928 f_oldloc
.y
= plr
->mo
->y
;
930 // m_x = FTOM(MTOF(plr->mo->x - m_w/2));
931 // m_y = FTOM(MTOF(plr->mo->y - m_h/2));
932 // m_x = plr->mo->x - m_w/2;
933 // m_y = plr->mo->y - m_h/2;
942 void AM_updateLightLev(void)
944 static int nexttic
= 0;
945 //static int litelevels[] = { 0, 3, 5, 6, 6, 7, 7, 7 };
946 static int litelevels
[] = { 0, 4, 7, 10, 12, 14, 15, 15 };
947 static int litelevelscnt
= 0;
949 // Change light level
952 lightlev
= litelevels
[litelevelscnt
++];
953 if (litelevelscnt
== sizeof(litelevels
)/sizeof(int)) litelevelscnt
= 0;
954 nexttic
= amclock
+ 6 - (amclock
% 6);
961 // Updates on Game Tick
963 void AM_Ticker (void)
974 // Change the zoom if necessary
975 if (ftom_zoommul
!= FRACUNIT
)
976 AM_changeWindowScale();
978 // Change x,y location
979 if (m_paninc
.x
|| m_paninc
.y
)
980 AM_changeWindowLoc();
982 // Update light level
983 // AM_updateLightLev();
989 // Clear automap frame buffer.
991 void AM_clearFB(int color
)
993 memset(fb
, color
, f_w
*f_h
);
998 // Automap clipping of lines.
1000 // Based on Cohen-Sutherland clipping algorithm but with a slightly
1001 // faster reject and precalculated slopes. If the speed is needed,
1002 // use a hash algorithm to handle the common cases.
1017 register int outcode1
= 0;
1018 register int outcode2
= 0;
1019 register int outside
;
1026 #define DOOUTCODE(oc, mx, my) \
1028 if ((my) < 0) (oc) |= TOP; \
1029 else if ((my) >= f_h) (oc) |= BOTTOM; \
1030 if ((mx) < 0) (oc) |= LEFT; \
1031 else if ((mx) >= f_w) (oc) |= RIGHT;
1034 // do trivial rejects and outcodes
1037 else if (ml
->a
.y
< m_y
)
1042 else if (ml
->b
.y
< m_y
)
1045 if (outcode1
& outcode2
)
1046 return false; // trivially outside
1050 else if (ml
->a
.x
> m_x2
)
1055 else if (ml
->b
.x
> m_x2
)
1058 if (outcode1
& outcode2
)
1059 return false; // trivially outside
1061 // transform to frame-buffer coordinates.
1062 fl
->a
.x
= CXMTOF(ml
->a
.x
);
1063 fl
->a
.y
= CYMTOF(ml
->a
.y
);
1064 fl
->b
.x
= CXMTOF(ml
->b
.x
);
1065 fl
->b
.y
= CYMTOF(ml
->b
.y
);
1067 DOOUTCODE(outcode1
, fl
->a
.x
, fl
->a
.y
);
1068 DOOUTCODE(outcode2
, fl
->b
.x
, fl
->b
.y
);
1070 if (outcode1
& outcode2
)
1073 while (outcode1
| outcode2
)
1075 // may be partially inside box
1076 // find an outside point
1082 // clip to each side
1085 dy
= fl
->a
.y
- fl
->b
.y
;
1086 dx
= fl
->b
.x
- fl
->a
.x
;
1087 tmp
.x
= fl
->a
.x
+ (dx
*(fl
->a
.y
))/dy
;
1090 else if (outside
& BOTTOM
)
1092 dy
= fl
->a
.y
- fl
->b
.y
;
1093 dx
= fl
->b
.x
- fl
->a
.x
;
1094 tmp
.x
= fl
->a
.x
+ (dx
*(fl
->a
.y
-f_h
))/dy
;
1097 else if (outside
& RIGHT
)
1099 dy
= fl
->b
.y
- fl
->a
.y
;
1100 dx
= fl
->b
.x
- fl
->a
.x
;
1101 tmp
.y
= fl
->a
.y
+ (dy
*(f_w
-1 - fl
->a
.x
))/dx
;
1104 else if (outside
& LEFT
)
1106 dy
= fl
->b
.y
- fl
->a
.y
;
1107 dx
= fl
->b
.x
- fl
->a
.x
;
1108 tmp
.y
= fl
->a
.y
+ (dy
*(-fl
->a
.x
))/dx
;
1112 if (outside
== outcode1
)
1115 DOOUTCODE(outcode1
, fl
->a
.x
, fl
->a
.y
);
1120 DOOUTCODE(outcode2
, fl
->b
.x
, fl
->b
.y
);
1123 if (outcode1
& outcode2
)
1124 return false; // trivially outside
1133 // Classic Bresenham w/ whatever optimizations needed for speed
1152 // For debugging only
1154 if ( fl->a.x < 0 || fl->a.x >= f_w
1155 || fl->a.y < 0 || fl->a.y >= f_h
1156 || fl->b.x < 0 || fl->b.x >= f_w
1157 || fl->b.y < 0 || fl->b.y >= f_h)
1159 fprintf(stderr, "fuck %d \r", fuck++);
1164 #define PUTDOT(xx,yy,cc) fb[(yy+wy)*finit_width+(xx+wx)]=(cc)
1166 dx
= fl
->b
.x
- fl
->a
.x
;
1167 ax
= 2 * (dx
<0 ? -dx
: dx
);
1170 dy
= fl
->b
.y
- fl
->a
.y
;
1171 ay
= 2 * (dy
<0 ? -dy
: dy
);
1183 if (x
== fl
->b
.x
) return;
1198 PUTDOT(x
, y
, color
);
1199 if (y
== fl
->b
.y
) return;
1214 // Clip lines, draw visible part sof lines.
1224 /* Rotate Map Patch - CDE 98' */
1226 l
.a
.x
= ml
->a
.x
-plr
->mo
->x
;
1227 l
.a
.y
= ml
->a
.y
-plr
->mo
->y
;
1228 l
.b
.x
= ml
->b
.x
-plr
->mo
->x
;
1229 l
.b
.y
= ml
->b
.y
-plr
->mo
->y
;
1231 AM_rotate(&l
.a
.x
, &l
.a
.y
, ANG90
-plr
->mo
->angle
);
1232 AM_rotate(&l
.b
.x
, &l
.b
.y
, ANG90
-plr
->mo
->angle
);
1234 l
.a
.x
+= plr
->mo
->x
;
1235 l
.a
.y
+= plr
->mo
->y
;
1236 l
.b
.x
+= plr
->mo
->x
;
1237 l
.b
.y
+= plr
->mo
->y
;
1239 if (AM_clipMline(&l
, &fl
))
1240 AM_drawFline(&fl
, color
); // draws it on frame buffer using fb coords
1242 if (AM_clipMline(ml
, &fl
))
1243 AM_drawFline(&fl
, color
); // draws it on frame buffer using fb coords
1250 // Draws flat (floor/ceiling tile) aligned grid lines.
1252 void AM_drawGrid(int color
)
1258 // Figure out start of vertical gridlines
1260 if ((start
-bmaporgx
)%(MAPBLOCKUNITS
<<FRACBITS
))
1261 start
+= (MAPBLOCKUNITS
<<FRACBITS
)
1262 - ((start
-bmaporgx
)%(MAPBLOCKUNITS
<<FRACBITS
));
1265 // draw vertical gridlines
1268 for (x
=start
; x
<end
; x
+=(MAPBLOCKUNITS
<<FRACBITS
))
1272 AM_drawMline(&ml
, color
);
1275 // Figure out start of horizontal gridlines
1277 if ((start
-bmaporgy
)%(MAPBLOCKUNITS
<<FRACBITS
))
1278 start
+= (MAPBLOCKUNITS
<<FRACBITS
)
1279 - ((start
-bmaporgy
)%(MAPBLOCKUNITS
<<FRACBITS
));
1282 // draw horizontal gridlines
1285 for (y
=start
; y
<end
; y
+=(MAPBLOCKUNITS
<<FRACBITS
))
1289 AM_drawMline(&ml
, color
);
1295 // Determines visible lines, draws them.
1296 // This is LineDef based, not LineSeg based.
1298 void AM_drawWalls(void)
1303 for (i
=0;i
<numlines
;i
++)
1305 l
.a
.x
= lines
[i
].v1
->x
;
1306 l
.a
.y
= lines
[i
].v1
->y
;
1307 l
.b
.x
= lines
[i
].v2
->x
;
1308 l
.b
.y
= lines
[i
].v2
->y
;
1309 if (cheating
|| (lines
[i
].flags
& ML_MAPPED
))
1311 if ((lines
[i
].flags
& LINE_NEVERSEE
) && !cheating
)
1313 if (!lines
[i
].backsector
)
1315 AM_drawMline(&l
, WALLCOLORS
+lightlev
);
1319 if (lines
[i
].special
== 39)
1321 AM_drawMline(&l
, WALLCOLORS
+WALLRANGE
/2);
1323 else if (lines
[i
].flags
& ML_SECRET
) // secret door
1325 if (cheating
) AM_drawMline(&l
, SECRETWALLCOLORS
+ lightlev
);
1326 else AM_drawMline(&l
, WALLCOLORS
+lightlev
);
1328 else if (lines
[i
].backsector
->floorheight
1329 != lines
[i
].frontsector
->floorheight
) {
1330 AM_drawMline(&l
, FDWALLCOLORS
+ lightlev
); // floor level change
1332 else if (lines
[i
].backsector
->ceilingheight
1333 != lines
[i
].frontsector
->ceilingheight
) {
1334 AM_drawMline(&l
, CDWALLCOLORS
+lightlev
); // ceiling level change
1336 else if (cheating
) {
1337 AM_drawMline(&l
, TSWALLCOLORS
+lightlev
);
1341 else if (plr
->powers
[pw_allmap
])
1343 if (!(lines
[i
].flags
& LINE_NEVERSEE
)) AM_drawMline(&l
, GRAYS
+3);
1349 AM_drawLineCharacter
1361 for (i
=0;i
<lineguylines
;i
++)
1363 l
.a
.x
= lineguy
[i
].a
.x
;
1364 l
.a
.y
= lineguy
[i
].a
.y
;
1368 l
.a
.x
= FixedMul(scale
, l
.a
.x
);
1369 l
.a
.y
= FixedMul(scale
, l
.a
.y
);
1373 AM_rotate(&l
.a
.x
, &l
.a
.y
, angle
);
1378 l
.b
.x
= lineguy
[i
].b
.x
;
1379 l
.b
.y
= lineguy
[i
].b
.y
;
1383 l
.b
.x
= FixedMul(scale
, l
.b
.x
);
1384 l
.b
.y
= FixedMul(scale
, l
.b
.y
);
1388 AM_rotate(&l
.b
.x
, &l
.b
.y
, angle
);
1393 AM_drawMline(&l
, color
);
1397 void AM_drawPlayers(void)
1401 static int their_colors
[] = { GREENS
, GRAYS
, BROWNS
, REDS
};
1402 int their_color
= -1;
1408 AM_drawLineCharacter
1409 (cheat_player_arrow
, NUMCHEATPLYRLINES
, 0,
1410 plr
->mo
->angle
, WHITE
, plr
->mo
->x
, plr
->mo
->y
);
1412 AM_drawLineCharacter
1413 (player_arrow
, NUMPLYRLINES
, 0, plr
->mo
->angle
,
1414 WHITE
, plr
->mo
->x
, plr
->mo
->y
);
1418 for (i
=0;i
<MAXPLAYERS
;i
++)
1423 if ( (deathmatch
&& !singledemo
) && p
!= plr
)
1426 if (!playeringame
[i
])
1429 if (p
->powers
[pw_invisibility
])
1430 color
= 246; // *close* to black
1432 color
= their_colors
[their_color
];
1434 AM_drawLineCharacter
1435 (player_arrow
, NUMPLYRLINES
, 0, p
->mo
->angle
,
1436 color
, p
->mo
->x
, p
->mo
->y
);
1449 for (i
=0;i
<numsectors
;i
++)
1451 t
= sectors
[i
].thinglist
;
1454 AM_drawLineCharacter
1455 (thintriangle_guy
, NUMTHINTRIANGLEGUYLINES
,
1456 16<<FRACBITS
, t
->angle
, colors
+lightlev
, t
->x
, t
->y
);
1462 void AM_drawMarks(void)
1464 int i
, fx
, fy
, w
, h
;
1468 for (i
=0;i
<AM_NUMMARKPOINTS
;i
++)
1470 if (markpoints
[i
].x
!= -1)
1472 // w = SWAPSHORT(marknums[i]->width);
1473 // h = SWAPSHORT(marknums[i]->height);
1474 w
= 5; // because something's wrong with the wad, i guess
1475 h
= 6; // because something's wrong with the wad, i guess
1477 /* CDE'98 Rotate Map Patch - Now rotate marks :) */
1480 x
=markpoints
[i
].x
-plr
->mo
->x
;
1481 y
=markpoints
[i
].y
-plr
->mo
->y
;
1482 AM_rotate(&x
, &y
, ANG90
-plr
->mo
->angle
);
1488 fx
= CXMTOF(markpoints
[i
].x
);
1489 fy
= CYMTOF(markpoints
[i
].y
);
1492 if (fx
>= f_x
&& fx
<= f_w
- w
&& fy
>= f_y
&& fy
<= f_h
- h
)
1493 V_DrawPatch(fx
+wx
, fy
+wy
, FB
, marknums
[i
]);
1498 void AM_drawCrosshair(int color
)
1500 /* CDE'98 - Crosshair on the view center whatever size/mode ! */
1503 //fb[((viewwidth+2*viewwindowx)*(viewheight+2*viewwindowy+1))/2] = color; // single point for now
1504 fb
[(viewwidth
+2*viewwindowx
)*(wy
+f_h
/2)+(wx
+f_w
/2)] = color
; // single point for now
1506 /* wx = viewwindowx;
1511 void AM_drawBox(int color
, int x
, int y
, int w
, int h
)
1516 /* First draw the background */
1519 for(k
=x
-wx
-1; k
<x
+w
-wx
; k
++)
1523 AM_drawFline(&l
, BLACK
);
1526 /* Draw white border */
1531 AM_drawFline(&l
, color
);
1537 AM_drawFline(&l
, color
);
1543 AM_drawFline(&l
, color
);
1549 AM_drawFline(&l
, color
);
1553 void AM_Drawer (void)
1555 if (!automapactive
) return;
1557 /* Map On HeadUp Patch - CDE 98' */
1559 AM_clearFB(BACKGROUND
);
1562 AM_drawBox(WHITE
, wx
, wy
, f_w
, f_h
);
1565 AM_drawGrid(GRIDCOLORS
);
1569 AM_drawThings(THINGCOLORS
, THINGRANGE
);
1570 AM_drawCrosshair(XHAIRCOLORS
);
1574 I_MarkRect(f_x
, f_y
, f_w
, f_h
);