Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
298 | serge | 1 | // Emacs style mode select -*- C++ -*- |
2 | //----------------------------------------------------------------------------- |
||
3 | // |
||
4 | // $Id:$ |
||
5 | // |
||
6 | // Copyright (C) 1993-1996 by id Software, Inc. |
||
7 | // |
||
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. |
||
11 | // |
||
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 |
||
15 | // for more details. |
||
16 | // |
||
17 | // |
||
18 | // $Log:$ |
||
19 | // |
||
20 | // DESCRIPTION: the automap code |
||
21 | // |
||
22 | //----------------------------------------------------------------------------- |
||
23 | |||
24 | static const char rcsid[] = "$Id: am_map.c,v 1.4 1997/02/03 21:24:33 b1 Exp $"; |
||
25 | |||
26 | #include |
||
27 | |||
28 | |||
29 | #include "z_zone.h" |
||
30 | #include "doomdef.h" |
||
31 | #include "st_stuff.h" |
||
32 | #include "p_local.h" |
||
33 | #include "w_wad.h" |
||
34 | |||
35 | #include "m_cheat.h" |
||
36 | #include "i_system.h" |
||
37 | |||
38 | // Needs access to LFB. |
||
39 | #include "v_video.h" |
||
40 | |||
41 | // State. |
||
42 | #include "doomstat.h" |
||
43 | #include "r_state.h" |
||
44 | |||
45 | // Data. |
||
46 | #include "dstrings.h" |
||
47 | |||
48 | #include "am_map.h" |
||
49 | |||
50 | |||
51 | // For use if I do walls with outsides/insides |
||
52 | #define REDS (256-5*16) |
||
53 | #define REDRANGE 16 |
||
54 | #define BLUES (256-4*16+8) |
||
55 | #define BLUERANGE 8 |
||
56 | #define GREENS (7*16) |
||
57 | #define GREENRANGE 16 |
||
58 | #define GRAYS (6*16) |
||
59 | #define GRAYSRANGE 16 |
||
60 | #define BROWNS (4*16) |
||
61 | #define BROWNRANGE 16 |
||
62 | #define YELLOWS (256-32+7) |
||
63 | #define YELLOWRANGE 1 |
||
64 | #define BLACK 0 |
||
65 | #define WHITE (256-47) |
||
66 | |||
67 | // Automap colors |
||
68 | #define BACKGROUND BLACK |
||
69 | #define YOURCOLORS WHITE |
||
70 | #define YOURRANGE 0 |
||
71 | #define WALLCOLORS REDS |
||
72 | #define WALLRANGE REDRANGE |
||
73 | #define TSWALLCOLORS GRAYS |
||
74 | #define TSWALLRANGE GRAYSRANGE |
||
75 | #define FDWALLCOLORS BROWNS |
||
76 | #define FDWALLRANGE BROWNRANGE |
||
77 | #define CDWALLCOLORS YELLOWS |
||
78 | #define CDWALLRANGE YELLOWRANGE |
||
79 | #define THINGCOLORS GREENS |
||
80 | #define THINGRANGE GREENRANGE |
||
81 | #define SECRETWALLCOLORS WALLCOLORS |
||
82 | #define SECRETWALLRANGE WALLRANGE |
||
83 | #define GRIDCOLORS (GRAYS + GRAYSRANGE/2) |
||
84 | #define GRIDRANGE 0 |
||
85 | #define XHAIRCOLORS GRAYS |
||
86 | |||
87 | // drawing stuff |
||
88 | #define FB 0 |
||
89 | |||
90 | #define AM_PANDOWNKEY KEY_DOWNARROW |
||
91 | #define AM_PANUPKEY KEY_UPARROW |
||
92 | #define AM_PANRIGHTKEY KEY_RIGHTARROW |
||
93 | #define AM_PANLEFTKEY KEY_LEFTARROW |
||
94 | #define AM_ZOOMINKEY '=' |
||
95 | #define AM_ZOOMOUTKEY '-' |
||
96 | #define AM_STARTKEY KEY_TAB |
||
97 | #define AM_ENDKEY KEY_TAB |
||
98 | #define AM_GOBIGKEY '0' |
||
99 | #define AM_FOLLOWKEY 'f' |
||
100 | #define AM_GRIDKEY 'g' |
||
101 | #define AM_MARKKEY 'm' |
||
102 | #define AM_CLEARMARKKEY 'c' |
||
103 | |||
104 | #define AM_NUMMARKPOINTS 10 |
||
105 | |||
106 | // scale on entry |
||
107 | #define INITSCALEMTOF (.2*FRACUNIT) |
||
108 | // how much the automap moves window per tic in frame-buffer coordinates |
||
109 | // moves 140 pixels in 1 second |
||
110 | #define F_PANINC 4 |
||
111 | // how much zoom-in per tic |
||
112 | // goes to 2x in 1 second |
||
113 | #define M_ZOOMIN ((int) (1.02*FRACUNIT)) |
||
114 | // how much zoom-out per tic |
||
115 | // pulls out to 0.5x in 1 second |
||
116 | #define M_ZOOMOUT ((int) (FRACUNIT/1.02)) |
||
117 | |||
118 | // translates between frame-buffer and map distances |
||
119 | #define FTOM(x) FixedMul(((x)<<16),scale_ftom) |
||
120 | #define MTOF(x) (FixedMul((x),scale_mtof)>>16) |
||
121 | // translates between frame-buffer and map coordinates |
||
122 | #define CXMTOF(x) (f_x + MTOF((x)-m_x)) |
||
123 | #define CYMTOF(y) (f_y + (f_h - MTOF((y)-m_y))) |
||
124 | |||
125 | // the following is crap |
||
126 | #define LINE_NEVERSEE ML_DONTDRAW |
||
127 | |||
128 | typedef struct |
||
129 | { |
||
130 | int x, y; |
||
131 | } fpoint_t; |
||
132 | |||
133 | typedef struct |
||
134 | { |
||
135 | fpoint_t a, b; |
||
136 | } fline_t; |
||
137 | |||
138 | typedef struct |
||
139 | { |
||
140 | fixed_t x,y; |
||
141 | } mpoint_t; |
||
142 | |||
143 | typedef struct |
||
144 | { |
||
145 | mpoint_t a, b; |
||
146 | } mline_t; |
||
147 | |||
148 | typedef struct |
||
149 | { |
||
150 | fixed_t slp, islp; |
||
151 | } islope_t; |
||
152 | |||
153 | |||
154 | |||
155 | // |
||
156 | // The vector graphics for the automap. |
||
157 | // A line drawing of the player pointing right, |
||
158 | // starting from the middle. |
||
159 | // |
||
160 | #define R ((8*PLAYERRADIUS)/7) |
||
161 | mline_t player_arrow[] = { |
||
162 | { { -R+R/8, 0 }, { R, 0 } }, // ----- |
||
163 | { { R, 0 }, { R-R/2, R/4 } }, // -----> |
||
164 | { { R, 0 }, { R-R/2, -R/4 } }, |
||
165 | { { -R+R/8, 0 }, { -R-R/8, R/4 } }, // >----> |
||
166 | { { -R+R/8, 0 }, { -R-R/8, -R/4 } }, |
||
167 | { { -R+3*R/8, 0 }, { -R+R/8, R/4 } }, // >>---> |
||
168 | { { -R+3*R/8, 0 }, { -R+R/8, -R/4 } } |
||
169 | }; |
||
170 | #undef R |
||
171 | #define NUMPLYRLINES (sizeof(player_arrow)/sizeof(mline_t)) |
||
172 | |||
173 | #define R ((8*PLAYERRADIUS)/7) |
||
174 | mline_t cheat_player_arrow[] = { |
||
175 | { { -R+R/8, 0 }, { R, 0 } }, // ----- |
||
176 | { { R, 0 }, { R-R/2, R/6 } }, // -----> |
||
177 | { { R, 0 }, { R-R/2, -R/6 } }, |
||
178 | { { -R+R/8, 0 }, { -R-R/8, R/6 } }, // >-----> |
||
179 | { { -R+R/8, 0 }, { -R-R/8, -R/6 } }, |
||
180 | { { -R+3*R/8, 0 }, { -R+R/8, R/6 } }, // >>-----> |
||
181 | { { -R+3*R/8, 0 }, { -R+R/8, -R/6 } }, |
||
182 | { { -R/2, 0 }, { -R/2, -R/6 } }, // >>-d---> |
||
183 | { { -R/2, -R/6 }, { -R/2+R/6, -R/6 } }, |
||
184 | { { -R/2+R/6, -R/6 }, { -R/2+R/6, R/4 } }, |
||
185 | { { -R/6, 0 }, { -R/6, -R/6 } }, // >>-dd--> |
||
186 | { { -R/6, -R/6 }, { 0, -R/6 } }, |
||
187 | { { 0, -R/6 }, { 0, R/4 } }, |
||
188 | { { R/6, R/4 }, { R/6, -R/7 } }, // >>-ddt-> |
||
189 | { { R/6, -R/7 }, { R/6+R/32, -R/7-R/32 } }, |
||
190 | { { R/6+R/32, -R/7-R/32 }, { R/6+R/10, -R/7 } } |
||
191 | }; |
||
192 | #undef R |
||
193 | #define NUMCHEATPLYRLINES (sizeof(cheat_player_arrow)/sizeof(mline_t)) |
||
194 | |||
195 | #define R (FRACUNIT) |
||
196 | mline_t triangle_guy[] = { |
||
197 | { { -.867*R, -.5*R }, { .867*R, -.5*R } }, |
||
198 | { { .867*R, -.5*R } , { 0, R } }, |
||
199 | { { 0, R }, { -.867*R, -.5*R } } |
||
200 | }; |
||
201 | #undef R |
||
202 | #define NUMTRIANGLEGUYLINES (sizeof(triangle_guy)/sizeof(mline_t)) |
||
203 | |||
204 | #define R (FRACUNIT) |
||
205 | mline_t thintriangle_guy[] = { |
||
206 | { { -.5*R, -.7*R }, { R, 0 } }, |
||
207 | { { R, 0 }, { -.5*R, .7*R } }, |
||
208 | { { -.5*R, .7*R }, { -.5*R, -.7*R } } |
||
209 | }; |
||
210 | #undef R |
||
211 | #define NUMTHINTRIANGLEGUYLINES (sizeof(thintriangle_guy)/sizeof(mline_t)) |
||
212 | |||
213 | |||
214 | |||
215 | |||
216 | static int cheating = 0; |
||
217 | static int grid = 0; |
||
218 | |||
219 | static int leveljuststarted = 1; // kluge until AM_LevelInit() is called |
||
220 | |||
221 | boolean automapactive = false; |
||
222 | static int finit_width = SCREENWIDTH; |
||
223 | static int finit_height = SCREENHEIGHT - 32; |
||
224 | |||
225 | // location of window on screen |
||
226 | static int f_x; |
||
227 | static int f_y; |
||
228 | |||
229 | // size of window on screen |
||
230 | static int f_w; |
||
231 | static int f_h; |
||
232 | |||
233 | static int lightlev; // used for funky strobing effect |
||
234 | static byte* fb; // pseudo-frame buffer |
||
235 | static int amclock; |
||
236 | |||
237 | static mpoint_t m_paninc; // how far the window pans each tic (map coords) |
||
238 | static fixed_t mtof_zoommul; // how far the window zooms in each tic (map coords) |
||
239 | static fixed_t ftom_zoommul; // how far the window zooms in each tic (fb coords) |
||
240 | |||
241 | static fixed_t m_x, m_y; // LL x,y where the window is on the map (map coords) |
||
242 | static fixed_t m_x2, m_y2; // UR x,y where the window is on the map (map coords) |
||
243 | |||
244 | // |
||
245 | // width/height of window on map (map coords) |
||
246 | // |
||
247 | static fixed_t m_w; |
||
248 | static fixed_t m_h; |
||
249 | |||
250 | // based on level size |
||
251 | static fixed_t min_x; |
||
252 | static fixed_t min_y; |
||
253 | static fixed_t max_x; |
||
254 | static fixed_t max_y; |
||
255 | |||
256 | static fixed_t max_w; // max_x-min_x, |
||
257 | static fixed_t max_h; // max_y-min_y |
||
258 | |||
259 | // based on player size |
||
260 | static fixed_t min_w; |
||
261 | static fixed_t min_h; |
||
262 | |||
263 | |||
264 | static fixed_t min_scale_mtof; // used to tell when to stop zooming out |
||
265 | static fixed_t max_scale_mtof; // used to tell when to stop zooming in |
||
266 | |||
267 | // old stuff for recovery later |
||
268 | static fixed_t old_m_w, old_m_h; |
||
269 | static fixed_t old_m_x, old_m_y; |
||
270 | |||
271 | // old location used by the Follower routine |
||
272 | static mpoint_t f_oldloc; |
||
273 | |||
274 | // used by MTOF to scale from map-to-frame-buffer coords |
||
275 | static fixed_t scale_mtof = INITSCALEMTOF; |
||
276 | // used by FTOM to scale from frame-buffer-to-map coords (=1/scale_mtof) |
||
277 | static fixed_t scale_ftom; |
||
278 | |||
279 | static player_t *plr; // the player represented by an arrow |
||
280 | |||
281 | static patch_t *marknums[10]; // numbers used for marking by the automap |
||
282 | static mpoint_t markpoints[AM_NUMMARKPOINTS]; // where the points are |
||
283 | static int markpointnum = 0; // next point to be assigned |
||
284 | |||
285 | static int followplayer = 1; // specifies whether to follow the player around |
||
286 | |||
287 | static unsigned char cheat_amap_seq[] = { 0xb2, 0x26, 0x26, 0x2e, 0xff }; |
||
288 | static cheatseq_t cheat_amap = { cheat_amap_seq, 0 }; |
||
289 | |||
290 | static boolean stopped = true; |
||
291 | |||
292 | extern boolean viewactive; |
||
293 | //extern byte screens[][SCREENWIDTH*SCREENHEIGHT]; |
||
294 | |||
295 | |||
296 | |||
297 | void |
||
298 | V_MarkRect |
||
299 | ( int x, |
||
300 | int y, |
||
301 | int width, |
||
302 | int height ); |
||
303 | |||
304 | // Calculates the slope and slope according to the x-axis of a line |
||
305 | // segment in map coordinates (with the upright y-axis n' all) so |
||
306 | // that it can be used with the brain-dead drawing stuff. |
||
307 | |||
308 | void |
||
309 | AM_getIslope |
||
310 | ( mline_t* ml, |
||
311 | islope_t* is ) |
||
312 | { |
||
313 | int dx, dy; |
||
314 | |||
315 | dy = ml->a.y - ml->b.y; |
||
316 | dx = ml->b.x - ml->a.x; |
||
317 | if (!dy) is->islp = (dx<0?-MAXINT:MAXINT); |
||
318 | else is->islp = FixedDiv(dx, dy); |
||
319 | if (!dx) is->slp = (dy<0?-MAXINT:MAXINT); |
||
320 | else is->slp = FixedDiv(dy, dx); |
||
321 | |||
322 | } |
||
323 | |||
324 | // |
||
325 | // |
||
326 | // |
||
327 | void AM_activateNewScale(void) |
||
328 | { |
||
329 | m_x += m_w/2; |
||
330 | m_y += m_h/2; |
||
331 | m_w = FTOM(f_w); |
||
332 | m_h = FTOM(f_h); |
||
333 | m_x -= m_w/2; |
||
334 | m_y -= m_h/2; |
||
335 | m_x2 = m_x + m_w; |
||
336 | m_y2 = m_y + m_h; |
||
337 | } |
||
338 | |||
339 | // |
||
340 | // |
||
341 | // |
||
342 | void AM_saveScaleAndLoc(void) |
||
343 | { |
||
344 | old_m_x = m_x; |
||
345 | old_m_y = m_y; |
||
346 | old_m_w = m_w; |
||
347 | old_m_h = m_h; |
||
348 | } |
||
349 | |||
350 | // |
||
351 | // |
||
352 | // |
||
353 | void AM_restoreScaleAndLoc(void) |
||
354 | { |
||
355 | |||
356 | m_w = old_m_w; |
||
357 | m_h = old_m_h; |
||
358 | if (!followplayer) |
||
359 | { |
||
360 | m_x = old_m_x; |
||
361 | m_y = old_m_y; |
||
362 | } else { |
||
363 | m_x = plr->mo->x - m_w/2; |
||
364 | m_y = plr->mo->y - m_h/2; |
||
365 | } |
||
366 | m_x2 = m_x + m_w; |
||
367 | m_y2 = m_y + m_h; |
||
368 | |||
369 | // Change the scaling multipliers |
||
370 | scale_mtof = FixedDiv(f_w< |
||
371 | scale_ftom = FixedDiv(FRACUNIT, scale_mtof); |
||
372 | } |
||
373 | |||
374 | // |
||
375 | // adds a marker at the current location |
||
376 | // |
||
377 | void AM_addMark(void) |
||
378 | { |
||
379 | markpoints[markpointnum].x = m_x + m_w/2; |
||
380 | markpoints[markpointnum].y = m_y + m_h/2; |
||
381 | markpointnum = (markpointnum + 1) % AM_NUMMARKPOINTS; |
||
382 | |||
383 | } |
||
384 | |||
385 | // |
||
386 | // Determines bounding box of all vertices, |
||
387 | // sets global variables controlling zoom range. |
||
388 | // |
||
389 | void AM_findMinMaxBoundaries(void) |
||
390 | { |
||
391 | int i; |
||
392 | fixed_t a; |
||
393 | fixed_t b; |
||
394 | |||
395 | min_x = min_y = MAXINT; |
||
396 | max_x = max_y = -MAXINT; |
||
397 | |||
398 | for (i=0;i |
||
399 | { |
||
400 | if (vertexes[i].x < min_x) |
||
401 | min_x = vertexes[i].x; |
||
402 | else if (vertexes[i].x > max_x) |
||
403 | max_x = vertexes[i].x; |
||
404 | |||
405 | if (vertexes[i].y < min_y) |
||
406 | min_y = vertexes[i].y; |
||
407 | else if (vertexes[i].y > max_y) |
||
408 | max_y = vertexes[i].y; |
||
409 | } |
||
410 | |||
411 | max_w = max_x - min_x; |
||
412 | max_h = max_y - min_y; |
||
413 | |||
414 | min_w = 2*PLAYERRADIUS; // const? never changed? |
||
415 | min_h = 2*PLAYERRADIUS; |
||
416 | |||
417 | a = FixedDiv(f_w< |
||
418 | b = FixedDiv(f_h< |
||
419 | |||
420 | min_scale_mtof = a < b ? a : b; |
||
421 | max_scale_mtof = FixedDiv(f_h< |
||
422 | |||
423 | } |
||
424 | |||
425 | |||
426 | // |
||
427 | // |
||
428 | // |
||
429 | void AM_changeWindowLoc(void) |
||
430 | { |
||
431 | if (m_paninc.x || m_paninc.y) |
||
432 | { |
||
433 | followplayer = 0; |
||
434 | f_oldloc.x = MAXINT; |
||
435 | } |
||
436 | |||
437 | m_x += m_paninc.x; |
||
438 | m_y += m_paninc.y; |
||
439 | |||
440 | if (m_x + m_w/2 > max_x) |
||
441 | m_x = max_x - m_w/2; |
||
442 | else if (m_x + m_w/2 < min_x) |
||
443 | m_x = min_x - m_w/2; |
||
444 | |||
445 | if (m_y + m_h/2 > max_y) |
||
446 | m_y = max_y - m_h/2; |
||
447 | else if (m_y + m_h/2 < min_y) |
||
448 | m_y = min_y - m_h/2; |
||
449 | |||
450 | m_x2 = m_x + m_w; |
||
451 | m_y2 = m_y + m_h; |
||
452 | } |
||
453 | |||
454 | |||
455 | // |
||
456 | // |
||
457 | // |
||
458 | void AM_initVariables(void) |
||
459 | { |
||
460 | int pnum; |
||
461 | static event_t st_notify = { ev_keyup, AM_MSGENTERED }; |
||
462 | |||
463 | automapactive = true; |
||
464 | fb = screens[0]; |
||
465 | |||
466 | f_oldloc.x = MAXINT; |
||
467 | amclock = 0; |
||
468 | lightlev = 0; |
||
469 | |||
470 | m_paninc.x = m_paninc.y = 0; |
||
471 | ftom_zoommul = FRACUNIT; |
||
472 | mtof_zoommul = FRACUNIT; |
||
473 | |||
474 | m_w = FTOM(f_w); |
||
475 | m_h = FTOM(f_h); |
||
476 | |||
477 | // find player to center on initially |
||
478 | if (!playeringame[pnum = consoleplayer]) |
||
479 | for (pnum=0;pnum |
||
480 | if (playeringame[pnum]) |
||
481 | break; |
||
482 | |||
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(); |
||
487 | |||
488 | // for saving & restoring |
||
489 | old_m_x = m_x; |
||
490 | old_m_y = m_y; |
||
491 | old_m_w = m_w; |
||
492 | old_m_h = m_h; |
||
493 | |||
494 | // inform the status bar of the change |
||
495 | ST_Responder(&st_notify); |
||
496 | |||
497 | } |
||
498 | |||
499 | // |
||
500 | // |
||
501 | // |
||
502 | void AM_loadPics(void) |
||
503 | { |
||
504 | int i; |
||
505 | char namebuf[9]; |
||
506 | |||
507 | for (i=0;i<10;i++) |
||
508 | { |
||
509 | sprintf(namebuf, "AMMNUM%d", i); |
||
510 | marknums[i] = W_CacheLumpName(namebuf, PU_STATIC); |
||
511 | } |
||
512 | |||
513 | } |
||
514 | |||
515 | void AM_unloadPics(void) |
||
516 | { |
||
517 | int i; |
||
518 | |||
519 | for (i=0;i<10;i++) |
||
520 | Z_ChangeTag(marknums[i], PU_CACHE); |
||
521 | |||
522 | } |
||
523 | |||
524 | void AM_clearMarks(void) |
||
525 | { |
||
526 | int i; |
||
527 | |||
528 | for (i=0;i |
||
529 | markpoints[i].x = -1; // means empty |
||
530 | markpointnum = 0; |
||
531 | } |
||
532 | |||
533 | // |
||
534 | // should be called at the start of every level |
||
535 | // right now, i figure it out myself |
||
536 | // |
||
537 | void AM_LevelInit(void) |
||
538 | { |
||
539 | leveljuststarted = 0; |
||
540 | |||
541 | f_x = f_y = 0; |
||
542 | f_w = finit_width; |
||
543 | f_h = finit_height; |
||
544 | |||
545 | AM_clearMarks(); |
||
546 | |||
547 | AM_findMinMaxBoundaries(); |
||
548 | scale_mtof = FixedDiv(min_scale_mtof, (int) (0.7*FRACUNIT)); |
||
549 | if (scale_mtof > max_scale_mtof) |
||
550 | scale_mtof = min_scale_mtof; |
||
551 | scale_ftom = FixedDiv(FRACUNIT, scale_mtof); |
||
552 | } |
||
553 | |||
554 | |||
555 | |||
556 | |||
557 | // |
||
558 | // |
||
559 | // |
||
560 | void AM_Stop (void) |
||
561 | { |
||
562 | static event_t st_notify = { 0, ev_keyup, AM_MSGEXITED }; |
||
563 | |||
564 | AM_unloadPics(); |
||
565 | automapactive = false; |
||
566 | ST_Responder(&st_notify); |
||
567 | stopped = true; |
||
568 | } |
||
569 | |||
570 | // |
||
571 | // |
||
572 | // |
||
573 | void AM_Start (void) |
||
574 | { |
||
575 | static int lastlevel = -1, lastepisode = -1; |
||
576 | |||
577 | if (!stopped) AM_Stop(); |
||
578 | stopped = false; |
||
579 | if (lastlevel != gamemap || lastepisode != gameepisode) |
||
580 | { |
||
581 | AM_LevelInit(); |
||
582 | lastlevel = gamemap; |
||
583 | lastepisode = gameepisode; |
||
584 | } |
||
585 | AM_initVariables(); |
||
586 | AM_loadPics(); |
||
587 | } |
||
588 | |||
589 | // |
||
590 | // set the window scale to the maximum size |
||
591 | // |
||
592 | void AM_minOutWindowScale(void) |
||
593 | { |
||
594 | scale_mtof = min_scale_mtof; |
||
595 | scale_ftom = FixedDiv(FRACUNIT, scale_mtof); |
||
596 | AM_activateNewScale(); |
||
597 | } |
||
598 | |||
599 | // |
||
600 | // set the window scale to the minimum size |
||
601 | // |
||
602 | void AM_maxOutWindowScale(void) |
||
603 | { |
||
604 | scale_mtof = max_scale_mtof; |
||
605 | scale_ftom = FixedDiv(FRACUNIT, scale_mtof); |
||
606 | AM_activateNewScale(); |
||
607 | } |
||
608 | |||
609 | |||
610 | // |
||
611 | // Handle events (user inputs) in automap mode |
||
612 | // |
||
613 | boolean |
||
614 | AM_Responder |
||
615 | ( event_t* ev ) |
||
616 | { |
||
617 | |||
618 | int rc; |
||
619 | static int cheatstate=0; |
||
620 | static int bigstate=0; |
||
621 | static char buffer[20]; |
||
622 | |||
623 | rc = false; |
||
624 | |||
625 | if (!automapactive) |
||
626 | { |
||
627 | if (ev->type == ev_keydown && ev->data1 == AM_STARTKEY) |
||
628 | { |
||
629 | AM_Start (); |
||
630 | viewactive = false; |
||
631 | rc = true; |
||
632 | } |
||
633 | } |
||
634 | |||
635 | else if (ev->type == ev_keydown) |
||
636 | { |
||
637 | |||
638 | rc = true; |
||
639 | switch(ev->data1) |
||
640 | { |
||
641 | case AM_PANRIGHTKEY: // pan right |
||
642 | if (!followplayer) m_paninc.x = FTOM(F_PANINC); |
||
643 | else rc = false; |
||
644 | break; |
||
645 | case AM_PANLEFTKEY: // pan left |
||
646 | if (!followplayer) m_paninc.x = -FTOM(F_PANINC); |
||
647 | else rc = false; |
||
648 | break; |
||
649 | case AM_PANUPKEY: // pan up |
||
650 | if (!followplayer) m_paninc.y = FTOM(F_PANINC); |
||
651 | else rc = false; |
||
652 | break; |
||
653 | case AM_PANDOWNKEY: // pan down |
||
654 | if (!followplayer) m_paninc.y = -FTOM(F_PANINC); |
||
655 | else rc = false; |
||
656 | break; |
||
657 | case AM_ZOOMOUTKEY: // zoom out |
||
658 | mtof_zoommul = M_ZOOMOUT; |
||
659 | ftom_zoommul = M_ZOOMIN; |
||
660 | break; |
||
661 | case AM_ZOOMINKEY: // zoom in |
||
662 | mtof_zoommul = M_ZOOMIN; |
||
663 | ftom_zoommul = M_ZOOMOUT; |
||
664 | break; |
||
665 | case AM_ENDKEY: |
||
666 | bigstate = 0; |
||
667 | viewactive = true; |
||
668 | AM_Stop (); |
||
669 | break; |
||
670 | case AM_GOBIGKEY: |
||
671 | bigstate = !bigstate; |
||
672 | if (bigstate) |
||
673 | { |
||
674 | AM_saveScaleAndLoc(); |
||
675 | AM_minOutWindowScale(); |
||
676 | } |
||
677 | else AM_restoreScaleAndLoc(); |
||
678 | break; |
||
679 | case AM_FOLLOWKEY: |
||
680 | followplayer = !followplayer; |
||
681 | f_oldloc.x = MAXINT; |
||
682 | plr->message = followplayer ? AMSTR_FOLLOWON : AMSTR_FOLLOWOFF; |
||
683 | break; |
||
684 | case AM_GRIDKEY: |
||
685 | grid = !grid; |
||
686 | plr->message = grid ? AMSTR_GRIDON : AMSTR_GRIDOFF; |
||
687 | break; |
||
688 | case AM_MARKKEY: |
||
689 | sprintf(buffer, "%s %d", AMSTR_MARKEDSPOT, markpointnum); |
||
690 | plr->message = buffer; |
||
691 | AM_addMark(); |
||
692 | break; |
||
693 | case AM_CLEARMARKKEY: |
||
694 | AM_clearMarks(); |
||
695 | plr->message = AMSTR_MARKSCLEARED; |
||
696 | break; |
||
697 | default: |
||
698 | cheatstate=0; |
||
699 | rc = false; |
||
700 | } |
||
701 | if (!deathmatch && cht_CheckCheat(&cheat_amap, ev->data1)) |
||
702 | { |
||
703 | rc = false; |
||
704 | cheating = (cheating+1) % 3; |
||
705 | } |
||
706 | } |
||
707 | |||
708 | else if (ev->type == ev_keyup) |
||
709 | { |
||
710 | rc = false; |
||
711 | switch (ev->data1) |
||
712 | { |
||
713 | case AM_PANRIGHTKEY: |
||
714 | if (!followplayer) m_paninc.x = 0; |
||
715 | break; |
||
716 | case AM_PANLEFTKEY: |
||
717 | if (!followplayer) m_paninc.x = 0; |
||
718 | break; |
||
719 | case AM_PANUPKEY: |
||
720 | if (!followplayer) m_paninc.y = 0; |
||
721 | break; |
||
722 | case AM_PANDOWNKEY: |
||
723 | if (!followplayer) m_paninc.y = 0; |
||
724 | break; |
||
725 | case AM_ZOOMOUTKEY: |
||
726 | case AM_ZOOMINKEY: |
||
727 | mtof_zoommul = FRACUNIT; |
||
728 | ftom_zoommul = FRACUNIT; |
||
729 | break; |
||
730 | } |
||
731 | } |
||
732 | |||
733 | return rc; |
||
734 | |||
735 | } |
||
736 | |||
737 | |||
738 | // |
||
739 | // Zooming |
||
740 | // |
||
741 | void AM_changeWindowScale(void) |
||
742 | { |
||
743 | |||
744 | // Change the scaling multipliers |
||
745 | scale_mtof = FixedMul(scale_mtof, mtof_zoommul); |
||
746 | scale_ftom = FixedDiv(FRACUNIT, scale_mtof); |
||
747 | |||
748 | if (scale_mtof < min_scale_mtof) |
||
749 | AM_minOutWindowScale(); |
||
750 | else if (scale_mtof > max_scale_mtof) |
||
751 | AM_maxOutWindowScale(); |
||
752 | else |
||
753 | AM_activateNewScale(); |
||
754 | } |
||
755 | |||
756 | |||
757 | // |
||
758 | // |
||
759 | // |
||
760 | void AM_doFollowPlayer(void) |
||
761 | { |
||
762 | |||
763 | if (f_oldloc.x != plr->mo->x || f_oldloc.y != plr->mo->y) |
||
764 | { |
||
765 | m_x = FTOM(MTOF(plr->mo->x)) - m_w/2; |
||
766 | m_y = FTOM(MTOF(plr->mo->y)) - m_h/2; |
||
767 | m_x2 = m_x + m_w; |
||
768 | m_y2 = m_y + m_h; |
||
769 | f_oldloc.x = plr->mo->x; |
||
770 | f_oldloc.y = plr->mo->y; |
||
771 | |||
772 | // m_x = FTOM(MTOF(plr->mo->x - m_w/2)); |
||
773 | // m_y = FTOM(MTOF(plr->mo->y - m_h/2)); |
||
774 | // m_x = plr->mo->x - m_w/2; |
||
775 | // m_y = plr->mo->y - m_h/2; |
||
776 | |||
777 | } |
||
778 | |||
779 | } |
||
780 | |||
781 | // |
||
782 | // |
||
783 | // |
||
784 | void AM_updateLightLev(void) |
||
785 | { |
||
786 | static nexttic = 0; |
||
787 | //static int litelevels[] = { 0, 3, 5, 6, 6, 7, 7, 7 }; |
||
788 | static int litelevels[] = { 0, 4, 7, 10, 12, 14, 15, 15 }; |
||
789 | static int litelevelscnt = 0; |
||
790 | |||
791 | // Change light level |
||
792 | if (amclock>nexttic) |
||
793 | { |
||
794 | lightlev = litelevels[litelevelscnt++]; |
||
795 | if (litelevelscnt == sizeof(litelevels)/sizeof(int)) litelevelscnt = 0; |
||
796 | nexttic = amclock + 6 - (amclock % 6); |
||
797 | } |
||
798 | |||
799 | } |
||
800 | |||
801 | |||
802 | // |
||
803 | // Updates on Game Tick |
||
804 | // |
||
805 | void AM_Ticker (void) |
||
806 | { |
||
807 | |||
808 | if (!automapactive) |
||
809 | return; |
||
810 | |||
811 | amclock++; |
||
812 | |||
813 | if (followplayer) |
||
814 | AM_doFollowPlayer(); |
||
815 | |||
816 | // Change the zoom if necessary |
||
817 | if (ftom_zoommul != FRACUNIT) |
||
818 | AM_changeWindowScale(); |
||
819 | |||
820 | // Change x,y location |
||
821 | if (m_paninc.x || m_paninc.y) |
||
822 | AM_changeWindowLoc(); |
||
823 | |||
824 | // Update light level |
||
825 | // AM_updateLightLev(); |
||
826 | |||
827 | } |
||
828 | |||
829 | |||
830 | // |
||
831 | // Clear automap frame buffer. |
||
832 | // |
||
833 | void AM_clearFB(int color) |
||
834 | { |
||
835 | memset(fb, color, f_w*f_h); |
||
836 | } |
||
837 | |||
838 | |||
839 | // |
||
840 | // Automap clipping of lines. |
||
841 | // |
||
842 | // Based on Cohen-Sutherland clipping algorithm but with a slightly |
||
843 | // faster reject and precalculated slopes. If the speed is needed, |
||
844 | // use a hash algorithm to handle the common cases. |
||
845 | // |
||
846 | boolean |
||
847 | AM_clipMline |
||
848 | ( mline_t* ml, |
||
849 | fline_t* fl ) |
||
850 | { |
||
851 | enum |
||
852 | { |
||
853 | LEFT =1, |
||
854 | RIGHT =2, |
||
855 | BOTTOM =4, |
||
856 | TOP =8 |
||
857 | }; |
||
858 | |||
859 | register outcode1 = 0; |
||
860 | register outcode2 = 0; |
||
861 | register outside; |
||
862 | |||
863 | fpoint_t tmp; |
||
864 | int dx; |
||
865 | int dy; |
||
866 | |||
867 | |||
868 | #define DOOUTCODE(oc, mx, my) \ |
||
869 | (oc) = 0; \ |
||
870 | if ((my) < 0) (oc) |= TOP; \ |
||
871 | else if ((my) >= f_h) (oc) |= BOTTOM; \ |
||
872 | if ((mx) < 0) (oc) |= LEFT; \ |
||
873 | else if ((mx) >= f_w) (oc) |= RIGHT; |
||
874 | |||
875 | |||
876 | // do trivial rejects and outcodes |
||
877 | if (ml->a.y > m_y2) |
||
878 | outcode1 = TOP; |
||
879 | else if (ml->a.y < m_y) |
||
880 | outcode1 = BOTTOM; |
||
881 | |||
882 | if (ml->b.y > m_y2) |
||
883 | outcode2 = TOP; |
||
884 | else if (ml->b.y < m_y) |
||
885 | outcode2 = BOTTOM; |
||
886 | |||
887 | if (outcode1 & outcode2) |
||
888 | return false; // trivially outside |
||
889 | |||
890 | if (ml->a.x < m_x) |
||
891 | outcode1 |= LEFT; |
||
892 | else if (ml->a.x > m_x2) |
||
893 | outcode1 |= RIGHT; |
||
894 | |||
895 | if (ml->b.x < m_x) |
||
896 | outcode2 |= LEFT; |
||
897 | else if (ml->b.x > m_x2) |
||
898 | outcode2 |= RIGHT; |
||
899 | |||
900 | if (outcode1 & outcode2) |
||
901 | return false; // trivially outside |
||
902 | |||
903 | // transform to frame-buffer coordinates. |
||
904 | fl->a.x = CXMTOF(ml->a.x); |
||
905 | fl->a.y = CYMTOF(ml->a.y); |
||
906 | fl->b.x = CXMTOF(ml->b.x); |
||
907 | fl->b.y = CYMTOF(ml->b.y); |
||
908 | |||
909 | DOOUTCODE(outcode1, fl->a.x, fl->a.y); |
||
910 | DOOUTCODE(outcode2, fl->b.x, fl->b.y); |
||
911 | |||
912 | if (outcode1 & outcode2) |
||
913 | return false; |
||
914 | |||
915 | while (outcode1 | outcode2) |
||
916 | { |
||
917 | // may be partially inside box |
||
918 | // find an outside point |
||
919 | if (outcode1) |
||
920 | outside = outcode1; |
||
921 | else |
||
922 | outside = outcode2; |
||
923 | |||
924 | // clip to each side |
||
925 | if (outside & TOP) |
||
926 | { |
||
927 | dy = fl->a.y - fl->b.y; |
||
928 | dx = fl->b.x - fl->a.x; |
||
929 | tmp.x = fl->a.x + (dx*(fl->a.y))/dy; |
||
930 | tmp.y = 0; |
||
931 | } |
||
932 | else if (outside & BOTTOM) |
||
933 | { |
||
934 | dy = fl->a.y - fl->b.y; |
||
935 | dx = fl->b.x - fl->a.x; |
||
936 | tmp.x = fl->a.x + (dx*(fl->a.y-f_h))/dy; |
||
937 | tmp.y = f_h-1; |
||
938 | } |
||
939 | else if (outside & RIGHT) |
||
940 | { |
||
941 | dy = fl->b.y - fl->a.y; |
||
942 | dx = fl->b.x - fl->a.x; |
||
943 | tmp.y = fl->a.y + (dy*(f_w-1 - fl->a.x))/dx; |
||
944 | tmp.x = f_w-1; |
||
945 | } |
||
946 | else if (outside & LEFT) |
||
947 | { |
||
948 | dy = fl->b.y - fl->a.y; |
||
949 | dx = fl->b.x - fl->a.x; |
||
950 | tmp.y = fl->a.y + (dy*(-fl->a.x))/dx; |
||
951 | tmp.x = 0; |
||
952 | } |
||
953 | |||
954 | if (outside == outcode1) |
||
955 | { |
||
956 | fl->a = tmp; |
||
957 | DOOUTCODE(outcode1, fl->a.x, fl->a.y); |
||
958 | } |
||
959 | else |
||
960 | { |
||
961 | fl->b = tmp; |
||
962 | DOOUTCODE(outcode2, fl->b.x, fl->b.y); |
||
963 | } |
||
964 | |||
965 | if (outcode1 & outcode2) |
||
966 | return false; // trivially outside |
||
967 | } |
||
968 | |||
969 | return true; |
||
970 | } |
||
971 | #undef DOOUTCODE |
||
972 | |||
973 | |||
974 | // |
||
975 | // Classic Bresenham w/ whatever optimizations needed for speed |
||
976 | // |
||
977 | void |
||
978 | AM_drawFline |
||
979 | ( fline_t* fl, |
||
980 | int color ) |
||
981 | { |
||
982 | register int x; |
||
983 | register int y; |
||
984 | register int dx; |
||
985 | register int dy; |
||
986 | register int sx; |
||
987 | register int sy; |
||
988 | register int ax; |
||
989 | register int ay; |
||
990 | register int d; |
||
991 | |||
992 | static fuck = 0; |
||
993 | |||
994 | // For debugging only |
||
995 | if ( fl->a.x < 0 || fl->a.x >= f_w |
||
996 | || fl->a.y < 0 || fl->a.y >= f_h |
||
997 | || fl->b.x < 0 || fl->b.x >= f_w |
||
998 | || fl->b.y < 0 || fl->b.y >= f_h) |
||
999 | { |
||
1000 | // __libclog_printf("fuck %d \r", fuck++); |
||
1001 | return; |
||
1002 | } |
||
1003 | |||
1004 | #define PUTDOT(xx,yy,cc) fb[(yy)*f_w+(xx)]=(cc) |
||
1005 | |||
1006 | dx = fl->b.x - fl->a.x; |
||
1007 | ax = 2 * (dx<0 ? -dx : dx); |
||
1008 | sx = dx<0 ? -1 : 1; |
||
1009 | |||
1010 | dy = fl->b.y - fl->a.y; |
||
1011 | ay = 2 * (dy<0 ? -dy : dy); |
||
1012 | sy = dy<0 ? -1 : 1; |
||
1013 | |||
1014 | x = fl->a.x; |
||
1015 | y = fl->a.y; |
||
1016 | |||
1017 | if (ax > ay) |
||
1018 | { |
||
1019 | d = ay - ax/2; |
||
1020 | while (1) |
||
1021 | { |
||
1022 | PUTDOT(x,y,color); |
||
1023 | if (x == fl->b.x) return; |
||
1024 | if (d>=0) |
||
1025 | { |
||
1026 | y += sy; |
||
1027 | d -= ax; |
||
1028 | } |
||
1029 | x += sx; |
||
1030 | d += ay; |
||
1031 | } |
||
1032 | } |
||
1033 | else |
||
1034 | { |
||
1035 | d = ax - ay/2; |
||
1036 | while (1) |
||
1037 | { |
||
1038 | PUTDOT(x, y, color); |
||
1039 | if (y == fl->b.y) return; |
||
1040 | if (d >= 0) |
||
1041 | { |
||
1042 | x += sx; |
||
1043 | d -= ay; |
||
1044 | } |
||
1045 | y += sy; |
||
1046 | d += ax; |
||
1047 | } |
||
1048 | } |
||
1049 | } |
||
1050 | |||
1051 | |||
1052 | // |
||
1053 | // Clip lines, draw visible part sof lines. |
||
1054 | // |
||
1055 | void |
||
1056 | AM_drawMline |
||
1057 | ( mline_t* ml, |
||
1058 | int color ) |
||
1059 | { |
||
1060 | static fline_t fl; |
||
1061 | |||
1062 | if (AM_clipMline(ml, &fl)) |
||
1063 | AM_drawFline(&fl, color); // draws it on frame buffer using fb coords |
||
1064 | } |
||
1065 | |||
1066 | |||
1067 | |||
1068 | // |
||
1069 | // Draws flat (floor/ceiling tile) aligned grid lines. |
||
1070 | // |
||
1071 | void AM_drawGrid(int color) |
||
1072 | { |
||
1073 | fixed_t x, y; |
||
1074 | fixed_t start, end; |
||
1075 | mline_t ml; |
||
1076 | |||
1077 | // Figure out start of vertical gridlines |
||
1078 | start = m_x; |
||
1079 | if ((start-bmaporgx)%(MAPBLOCKUNITS< |
||
1080 | start += (MAPBLOCKUNITS< |
||
1081 | - ((start-bmaporgx)%(MAPBLOCKUNITS< |
||
1082 | end = m_x + m_w; |
||
1083 | |||
1084 | // draw vertical gridlines |
||
1085 | ml.a.y = m_y; |
||
1086 | ml.b.y = m_y+m_h; |
||
1087 | for (x=start; x |
||
1088 | { |
||
1089 | ml.a.x = x; |
||
1090 | ml.b.x = x; |
||
1091 | AM_drawMline(&ml, color); |
||
1092 | } |
||
1093 | |||
1094 | // Figure out start of horizontal gridlines |
||
1095 | start = m_y; |
||
1096 | if ((start-bmaporgy)%(MAPBLOCKUNITS< |
||
1097 | start += (MAPBLOCKUNITS< |
||
1098 | - ((start-bmaporgy)%(MAPBLOCKUNITS< |
||
1099 | end = m_y + m_h; |
||
1100 | |||
1101 | // draw horizontal gridlines |
||
1102 | ml.a.x = m_x; |
||
1103 | ml.b.x = m_x + m_w; |
||
1104 | for (y=start; y |
||
1105 | { |
||
1106 | ml.a.y = y; |
||
1107 | ml.b.y = y; |
||
1108 | AM_drawMline(&ml, color); |
||
1109 | } |
||
1110 | |||
1111 | } |
||
1112 | |||
1113 | // |
||
1114 | // Determines visible lines, draws them. |
||
1115 | // This is LineDef based, not LineSeg based. |
||
1116 | // |
||
1117 | void AM_drawWalls(void) |
||
1118 | { |
||
1119 | int i; |
||
1120 | static mline_t l; |
||
1121 | |||
1122 | for (i=0;i |
||
1123 | { |
||
1124 | l.a.x = lines[i].v1->x; |
||
1125 | l.a.y = lines[i].v1->y; |
||
1126 | l.b.x = lines[i].v2->x; |
||
1127 | l.b.y = lines[i].v2->y; |
||
1128 | if (cheating || (lines[i].flags & ML_MAPPED)) |
||
1129 | { |
||
1130 | if ((lines[i].flags & LINE_NEVERSEE) && !cheating) |
||
1131 | continue; |
||
1132 | if (!lines[i].backsector) |
||
1133 | { |
||
1134 | AM_drawMline(&l, WALLCOLORS+lightlev); |
||
1135 | } |
||
1136 | else |
||
1137 | { |
||
1138 | if (lines[i].special == 39) |
||
1139 | { // teleporters |
||
1140 | AM_drawMline(&l, WALLCOLORS+WALLRANGE/2); |
||
1141 | } |
||
1142 | else if (lines[i].flags & ML_SECRET) // secret door |
||
1143 | { |
||
1144 | if (cheating) AM_drawMline(&l, SECRETWALLCOLORS + lightlev); |
||
1145 | else AM_drawMline(&l, WALLCOLORS+lightlev); |
||
1146 | } |
||
1147 | else if (lines[i].backsector->floorheight |
||
1148 | != lines[i].frontsector->floorheight) { |
||
1149 | AM_drawMline(&l, FDWALLCOLORS + lightlev); // floor level change |
||
1150 | } |
||
1151 | else if (lines[i].backsector->ceilingheight |
||
1152 | != lines[i].frontsector->ceilingheight) { |
||
1153 | AM_drawMline(&l, CDWALLCOLORS+lightlev); // ceiling level change |
||
1154 | } |
||
1155 | else if (cheating) { |
||
1156 | AM_drawMline(&l, TSWALLCOLORS+lightlev); |
||
1157 | } |
||
1158 | } |
||
1159 | } |
||
1160 | else if (plr->powers[pw_allmap]) |
||
1161 | { |
||
1162 | if (!(lines[i].flags & LINE_NEVERSEE)) AM_drawMline(&l, GRAYS+3); |
||
1163 | } |
||
1164 | } |
||
1165 | } |
||
1166 | |||
1167 | |||
1168 | // |
||
1169 | // Rotation in 2D. |
||
1170 | // Used to rotate player arrow line character. |
||
1171 | // |
||
1172 | void |
||
1173 | AM_rotate |
||
1174 | ( fixed_t* x, |
||
1175 | fixed_t* y, |
||
1176 | angle_t a ) |
||
1177 | { |
||
1178 | fixed_t tmpx; |
||
1179 | |||
1180 | tmpx = |
||
1181 | FixedMul(*x,finecosine[a>>ANGLETOFINESHIFT]) |
||
1182 | - FixedMul(*y,finesine[a>>ANGLETOFINESHIFT]); |
||
1183 | |||
1184 | *y = |
||
1185 | FixedMul(*x,finesine[a>>ANGLETOFINESHIFT]) |
||
1186 | + FixedMul(*y,finecosine[a>>ANGLETOFINESHIFT]); |
||
1187 | |||
1188 | *x = tmpx; |
||
1189 | } |
||
1190 | |||
1191 | void |
||
1192 | AM_drawLineCharacter |
||
1193 | ( mline_t* lineguy, |
||
1194 | int lineguylines, |
||
1195 | fixed_t scale, |
||
1196 | angle_t angle, |
||
1197 | int color, |
||
1198 | fixed_t x, |
||
1199 | fixed_t y ) |
||
1200 | { |
||
1201 | int i; |
||
1202 | mline_t l; |
||
1203 | |||
1204 | for (i=0;i |
||
1205 | { |
||
1206 | l.a.x = lineguy[i].a.x; |
||
1207 | l.a.y = lineguy[i].a.y; |
||
1208 | |||
1209 | if (scale) |
||
1210 | { |
||
1211 | l.a.x = FixedMul(scale, l.a.x); |
||
1212 | l.a.y = FixedMul(scale, l.a.y); |
||
1213 | } |
||
1214 | |||
1215 | if (angle) |
||
1216 | AM_rotate(&l.a.x, &l.a.y, angle); |
||
1217 | |||
1218 | l.a.x += x; |
||
1219 | l.a.y += y; |
||
1220 | |||
1221 | l.b.x = lineguy[i].b.x; |
||
1222 | l.b.y = lineguy[i].b.y; |
||
1223 | |||
1224 | if (scale) |
||
1225 | { |
||
1226 | l.b.x = FixedMul(scale, l.b.x); |
||
1227 | l.b.y = FixedMul(scale, l.b.y); |
||
1228 | } |
||
1229 | |||
1230 | if (angle) |
||
1231 | AM_rotate(&l.b.x, &l.b.y, angle); |
||
1232 | |||
1233 | l.b.x += x; |
||
1234 | l.b.y += y; |
||
1235 | |||
1236 | AM_drawMline(&l, color); |
||
1237 | } |
||
1238 | } |
||
1239 | |||
1240 | void AM_drawPlayers(void) |
||
1241 | { |
||
1242 | int i; |
||
1243 | player_t* p; |
||
1244 | static int their_colors[] = { GREENS, GRAYS, BROWNS, REDS }; |
||
1245 | int their_color = -1; |
||
1246 | int color; |
||
1247 | |||
1248 | if (!netgame) |
||
1249 | { |
||
1250 | if (cheating) |
||
1251 | AM_drawLineCharacter |
||
1252 | (cheat_player_arrow, NUMCHEATPLYRLINES, 0, |
||
1253 | plr->mo->angle, WHITE, plr->mo->x, plr->mo->y); |
||
1254 | else |
||
1255 | AM_drawLineCharacter |
||
1256 | (player_arrow, NUMPLYRLINES, 0, plr->mo->angle, |
||
1257 | WHITE, plr->mo->x, plr->mo->y); |
||
1258 | return; |
||
1259 | } |
||
1260 | |||
1261 | for (i=0;i |
||
1262 | { |
||
1263 | their_color++; |
||
1264 | p = &players[i]; |
||
1265 | |||
1266 | if ( (deathmatch && !singledemo) && p != plr) |
||
1267 | continue; |
||
1268 | |||
1269 | if (!playeringame[i]) |
||
1270 | continue; |
||
1271 | |||
1272 | if (p->powers[pw_invisibility]) |
||
1273 | color = 246; // *close* to black |
||
1274 | else |
||
1275 | color = their_colors[their_color]; |
||
1276 | |||
1277 | AM_drawLineCharacter |
||
1278 | (player_arrow, NUMPLYRLINES, 0, p->mo->angle, |
||
1279 | color, p->mo->x, p->mo->y); |
||
1280 | } |
||
1281 | |||
1282 | } |
||
1283 | |||
1284 | void |
||
1285 | AM_drawThings |
||
1286 | ( int colors, |
||
1287 | int colorrange) |
||
1288 | { |
||
1289 | int i; |
||
1290 | mobj_t* t; |
||
1291 | |||
1292 | for (i=0;i |
||
1293 | { |
||
1294 | t = sectors[i].thinglist; |
||
1295 | while (t) |
||
1296 | { |
||
1297 | AM_drawLineCharacter |
||
1298 | (thintriangle_guy, NUMTHINTRIANGLEGUYLINES, |
||
1299 | 16< |
||
1300 | t = t->snext; |
||
1301 | } |
||
1302 | } |
||
1303 | } |
||
1304 | |||
1305 | void AM_drawMarks(void) |
||
1306 | { |
||
1307 | int i, fx, fy, w, h; |
||
1308 | |||
1309 | for (i=0;i |
||
1310 | { |
||
1311 | if (markpoints[i].x != -1) |
||
1312 | { |
||
1313 | // w = SHORT(marknums[i]->width); |
||
1314 | // h = SHORT(marknums[i]->height); |
||
1315 | w = 5; // because something's wrong with the wad, i guess |
||
1316 | h = 6; // because something's wrong with the wad, i guess |
||
1317 | fx = CXMTOF(markpoints[i].x); |
||
1318 | fy = CYMTOF(markpoints[i].y); |
||
1319 | if (fx >= f_x && fx <= f_w - w && fy >= f_y && fy <= f_h - h) |
||
1320 | V_DrawPatch(fx, fy, FB, marknums[i]); |
||
1321 | } |
||
1322 | } |
||
1323 | |||
1324 | } |
||
1325 | |||
1326 | void AM_drawCrosshair(int color) |
||
1327 | { |
||
1328 | fb[(f_w*(f_h+1))/2] = color; // single point for now |
||
1329 | |||
1330 | } |
||
1331 | |||
1332 | void AM_Drawer (void) |
||
1333 | { |
||
1334 | if (!automapactive) return; |
||
1335 | |||
1336 | AM_clearFB(BACKGROUND); |
||
1337 | if (grid) |
||
1338 | AM_drawGrid(GRIDCOLORS); |
||
1339 | AM_drawWalls(); |
||
1340 | AM_drawPlayers(); |
||
1341 | if (cheating==2) |
||
1342 | AM_drawThings(THINGCOLORS, THINGRANGE); |
||
1343 | AM_drawCrosshair(XHAIRCOLORS); |
||
1344 | |||
1345 | AM_drawMarks(); |
||
1346 | |||
1347 | V_MarkRect(f_x, f_y, f_w, f_h); |
||
1348 | |||
1349 | }=>=> |