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