am_map.c 40 KB

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