hu_stuff.c 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602
  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: Heads-up displays
  30. *
  31. *-----------------------------------------------------------------------------
  32. */
  33. // killough 5/3/98: remove unnecessary headers
  34. #include "doomstat.h"
  35. #include "hu_stuff.h"
  36. #include "hu_lib.h"
  37. #include "st_stuff.h" /* jff 2/16/98 need loc of status bar */
  38. #include "w_wad.h"
  39. #include "s_sound.h"
  40. #include "dstrings.h"
  41. #include "sounds.h"
  42. #include "d_deh.h" /* Ty 03/27/98 - externalization of mapnamesx arrays */
  43. #include "g_game.h"
  44. #include "r_main.h"
  45. #include "doomiphone.h"
  46. #include <stdbool.h>
  47. // global heads up display controls
  48. int hud_active; //jff 2/17/98 controls heads-up display mode
  49. int hud_displayed; //jff 2/23/98 turns heads-up display on/off
  50. int hud_nosecrets; //jff 2/18/98 allows secrets line to be disabled in HUD
  51. int hud_distributed; //jff 3/4/98 display HUD in different places on screen
  52. int hud_graph_keys=1; //jff 3/7/98 display HUD keys as graphics
  53. //
  54. // Locally used constants, shortcuts.
  55. //
  56. // Ty 03/28/98 -
  57. // These four shortcuts modifed to reflect char ** of mapnamesx[]
  58. #define HU_TITLE (*mapnames[(gameepisode-1)*9+gamemap-1])
  59. #define HU_TITLE2 (*mapnames2[gamemap-1])
  60. #define HU_TITLEP (*mapnamesp[gamemap-1])
  61. #define HU_TITLET (*mapnamest[gamemap-1])
  62. #define HU_TITLEHEIGHT 1
  63. #define HU_TITLEX 0
  64. //jff 2/16/98 change 167 to ST_Y-1
  65. // CPhipps - changed to ST_TY
  66. // proff - changed to 200-ST_HEIGHT for stretching
  67. #define HU_TITLEY ((200-ST_HEIGHT) - 1 - hu_font[0].height)
  68. //jff 2/16/98 add coord text widget coordinates
  69. // proff - changed to SCREENWIDTH to 320 for stretching
  70. #define HU_COORDX (320 - 13*hu_font2['A'-HU_FONTSTART].width)
  71. //jff 3/3/98 split coord widget into three lines in upper right of screen
  72. #define HU_COORDX_Y (1 + 0*hu_font['A'-HU_FONTSTART].height)
  73. #define HU_COORDY_Y (2 + 1*hu_font['A'-HU_FONTSTART].height)
  74. #define HU_COORDZ_Y (3 + 2*hu_font['A'-HU_FONTSTART].height)
  75. //jff 2/16/98 add ammo, health, armor widgets, 2/22/98 less gap
  76. #define HU_GAPY 8
  77. #define HU_HUDHEIGHT (6*HU_GAPY)
  78. #define HU_HUDX 2
  79. #define HU_HUDY (200-HU_HUDHEIGHT-1)
  80. #define HU_MONSECX (HU_HUDX)
  81. #define HU_MONSECY (HU_HUDY+0*HU_GAPY)
  82. #define HU_KEYSX (HU_HUDX)
  83. //jff 3/7/98 add offset for graphic key widget
  84. #define HU_KEYSGX (HU_HUDX+4*hu_font2['A'-HU_FONTSTART].width)
  85. #define HU_KEYSY (HU_HUDY+1*HU_GAPY)
  86. #define HU_WEAPX (HU_HUDX)
  87. #define HU_WEAPY (HU_HUDY+2*HU_GAPY)
  88. #define HU_AMMOX (HU_HUDX)
  89. #define HU_AMMOY (HU_HUDY+3*HU_GAPY)
  90. #define HU_HEALTHX (HU_HUDX)
  91. #define HU_HEALTHY (HU_HUDY+4*HU_GAPY)
  92. #define HU_ARMORX (HU_HUDX)
  93. #define HU_ARMORY (HU_HUDY+5*HU_GAPY)
  94. //jff 3/4/98 distributed HUD positions
  95. #define HU_HUDX_LL 2
  96. #define HU_HUDY_LL (200-2*HU_GAPY-1)
  97. // proff/nicolas 09/20/98: Changed for high-res
  98. #define HU_HUDX_LR (320-120)
  99. #define HU_HUDY_LR (200-2*HU_GAPY-1)
  100. // proff/nicolas 09/20/98: Changed for high-res
  101. #define HU_HUDX_UR (320-96)
  102. #define HU_HUDY_UR 2
  103. #define HU_MONSECX_D (HU_HUDX_LL)
  104. #define HU_MONSECY_D (HU_HUDY_LL+0*HU_GAPY)
  105. #define HU_KEYSX_D (HU_HUDX_LL)
  106. #define HU_KEYSGX_D (HU_HUDX_LL+4*hu_font2['A'-HU_FONTSTART].width)
  107. #define HU_KEYSY_D (HU_HUDY_LL+1*HU_GAPY)
  108. #define HU_WEAPX_D (HU_HUDX_LR)
  109. #define HU_WEAPY_D (HU_HUDY_LR+0*HU_GAPY)
  110. #define HU_AMMOX_D (HU_HUDX_LR)
  111. #define HU_AMMOY_D (HU_HUDY_LR+1*HU_GAPY)
  112. #define HU_HEALTHX_D (HU_HUDX_UR)
  113. #define HU_HEALTHY_D (HU_HUDY_UR+0*HU_GAPY)
  114. #define HU_ARMORX_D (HU_HUDX_UR)
  115. #define HU_ARMORY_D (HU_HUDY_UR+1*HU_GAPY)
  116. //#define HU_INPUTTOGGLE 't' // not used // phares
  117. #define HU_INPUTX HU_MSGX
  118. #define HU_INPUTY (HU_MSGY + HU_MSGHEIGHT*(hu_font[0].height) +1)
  119. #define HU_INPUTWIDTH 64
  120. #define HU_INPUTHEIGHT 1
  121. #define key_alt KEYD_RALT
  122. #define key_shift KEYD_RSHIFT
  123. const char* chat_macros[] =
  124. // Ty 03/27/98 - *not* externalized
  125. // CPhipps - const char*
  126. {
  127. HUSTR_CHATMACRO0,
  128. HUSTR_CHATMACRO1,
  129. HUSTR_CHATMACRO2,
  130. HUSTR_CHATMACRO3,
  131. HUSTR_CHATMACRO4,
  132. HUSTR_CHATMACRO5,
  133. HUSTR_CHATMACRO6,
  134. HUSTR_CHATMACRO7,
  135. HUSTR_CHATMACRO8,
  136. HUSTR_CHATMACRO9
  137. };
  138. const char* player_names[] =
  139. // Ty 03/27/98 - *not* externalized
  140. // CPhipps - const char*
  141. {
  142. HUSTR_PLRGREEN,
  143. HUSTR_PLRINDIGO,
  144. HUSTR_PLRBROWN,
  145. HUSTR_PLRRED
  146. };
  147. //jff 3/17/98 translate player colmap to text color ranges
  148. int plyrcoltran[MAXPLAYERS]={CR_GREEN,CR_GRAY,CR_BROWN,CR_RED};
  149. char chat_char; // remove later.
  150. static player_t* plr;
  151. // font sets
  152. patchnum_t hu_font[HU_FONTSIZE];
  153. patchnum_t hu_font2[HU_FONTSIZE];
  154. patchnum_t hu_fontk[HU_FONTSIZE];//jff 3/7/98 added for graphic key indicators
  155. patchnum_t hu_msgbg[9]; //jff 2/26/98 add patches for message background
  156. // widgets
  157. static hu_textline_t w_title;
  158. static hu_stext_t w_message;
  159. static hu_itext_t w_chat;
  160. static hu_itext_t w_inputbuffer[MAXPLAYERS];
  161. static hu_textline_t w_coordx; //jff 2/16/98 new coord widget for automap
  162. static hu_textline_t w_coordy; //jff 3/3/98 split coord widgets automap
  163. static hu_textline_t w_coordz; //jff 3/3/98 split coord widgets automap
  164. static hu_textline_t w_ammo; //jff 2/16/98 new ammo widget for hud
  165. static hu_textline_t w_health; //jff 2/16/98 new health widget for hud
  166. static hu_textline_t w_armor; //jff 2/16/98 new armor widget for hud
  167. static hu_textline_t w_weapon; //jff 2/16/98 new weapon widget for hud
  168. static hu_textline_t w_keys; //jff 2/16/98 new keys widget for hud
  169. static hu_textline_t w_gkeys; //jff 3/7/98 graphic keys widget for hud
  170. static hu_textline_t w_monsec; //jff 2/16/98 new kill/secret widget for hud
  171. static hu_mtext_t w_rtext; //jff 2/26/98 text message refresh widget
  172. static boolean always_off = false;
  173. static char chat_dest[MAXPLAYERS];
  174. boolean chat_on;
  175. static boolean message_on;
  176. static boolean message_list; //2/26/98 enable showing list of messages
  177. boolean message_dontfuckwithme;
  178. static boolean message_nottobefuckedwith;
  179. static int message_counter;
  180. extern int showMessages;
  181. extern boolean automapactive;
  182. static boolean headsupactive = false;
  183. //jff 2/16/98 hud supported automap colors added
  184. int hudcolor_titl; // color range of automap level title
  185. int hudcolor_xyco; // color range of new coords on automap
  186. //jff 2/16/98 hud text colors, controls added
  187. int hudcolor_mesg; // color range of scrolling messages
  188. int hudcolor_chat; // color range of chat lines
  189. int hud_msg_lines; // number of message lines in window
  190. //jff 2/26/98 hud text colors, controls added
  191. int hudcolor_list; // list of messages color
  192. int hud_list_bgon; // enable for solid window background for message list
  193. //jff 2/16/98 initialization strings for ammo, health, armor widgets
  194. static char hud_coordstrx[32];
  195. static char hud_coordstry[32];
  196. static char hud_coordstrz[32];
  197. static char hud_ammostr[80];
  198. static char hud_healthstr[80];
  199. static char hud_armorstr[80];
  200. static char hud_weapstr[80];
  201. static char hud_keysstr[80];
  202. static char hud_gkeysstr[80]; //jff 3/7/98 add support for graphic key display
  203. static char hud_monsecstr[80];
  204. //
  205. // Builtin map names.
  206. // The actual names can be found in DStrings.h.
  207. //
  208. // Ty 03/27/98 - externalized map name arrays - now in d_deh.c
  209. // and converted to arrays of pointers to char *
  210. // See modified HUTITLEx macros
  211. extern char **mapnames[];
  212. extern char **mapnames2[];
  213. extern char **mapnamesp[];
  214. extern char **mapnamest[];
  215. extern int map_point_coordinates;
  216. // key tables
  217. // jff 5/10/98 french support removed,
  218. // as it was not being used and couldn't be easily tested
  219. //
  220. const char* shiftxform;
  221. const char english_shiftxform[] =
  222. {
  223. 0,
  224. 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
  225. 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
  226. 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
  227. 31,
  228. ' ', '!', '"', '#', '$', '%', '&',
  229. '"', // shift-'
  230. '(', ')', '*', '+',
  231. '<', // shift-,
  232. '_', // shift--
  233. '>', // shift-.
  234. '?', // shift-/
  235. ')', // shift-0
  236. '!', // shift-1
  237. '@', // shift-2
  238. '#', // shift-3
  239. '$', // shift-4
  240. '%', // shift-5
  241. '^', // shift-6
  242. '&', // shift-7
  243. '*', // shift-8
  244. '(', // shift-9
  245. ':',
  246. ':', // shift-;
  247. '<',
  248. '+', // shift-=
  249. '>', '?', '@',
  250. 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
  251. 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
  252. '[', // shift-[
  253. '!', // shift-backslash - OH MY GOD DOES WATCOM SUCK
  254. ']', // shift-]
  255. '"', '_',
  256. '\'', // shift-`
  257. 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
  258. 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
  259. '{', '|', '}', '~', 127
  260. };
  261. //
  262. // HU_Init()
  263. //
  264. // Initialize the heads-up display, text that overwrites the primary display
  265. //
  266. // Passed nothing, returns nothing
  267. //
  268. void HU_Init(void)
  269. {
  270. int i;
  271. int j;
  272. char buffer[9];
  273. shiftxform = english_shiftxform;
  274. // load the heads-up font
  275. j = HU_FONTSTART;
  276. for (i=0;i<HU_FONTSIZE;i++,j++)
  277. {
  278. if ('0'<=j && j<='9')
  279. {
  280. sprintf(buffer, "DIG%.1d",j-48);
  281. R_SetPatchNum(&hu_font2[i], buffer);
  282. sprintf(buffer, "STCFN%.3d",j);
  283. R_SetPatchNum(&hu_font[i], buffer);
  284. }
  285. else if ('A'<=j && j<='Z')
  286. {
  287. sprintf(buffer, "DIG%c",j);
  288. R_SetPatchNum(&hu_font2[i], buffer);
  289. sprintf(buffer, "STCFN%.3d",j);
  290. R_SetPatchNum(&hu_font[i], buffer);
  291. }
  292. else if (j=='-')
  293. {
  294. R_SetPatchNum(&hu_font2[i], "DIG45");
  295. R_SetPatchNum(&hu_font[i], "STCFN045");
  296. }
  297. else if (j=='/')
  298. {
  299. R_SetPatchNum(&hu_font2[i], "DIG47");
  300. R_SetPatchNum(&hu_font[i], "STCFN047");
  301. }
  302. else if (j==':')
  303. {
  304. R_SetPatchNum(&hu_font2[i], "DIG58");
  305. R_SetPatchNum(&hu_font[i], "STCFN058");
  306. }
  307. else if (j=='[')
  308. {
  309. R_SetPatchNum(&hu_font2[i], "DIG91");
  310. R_SetPatchNum(&hu_font[i], "STCFN091");
  311. }
  312. else if (j==']')
  313. {
  314. R_SetPatchNum(&hu_font2[i], "DIG93");
  315. R_SetPatchNum(&hu_font[i], "STCFN093");
  316. }
  317. else if (j<97)
  318. {
  319. sprintf(buffer, "STCFN%.3d",j);
  320. R_SetPatchNum(&hu_font2[i], buffer);
  321. R_SetPatchNum(&hu_font[i], buffer);
  322. //jff 2/23/98 make all font chars defined, useful or not
  323. }
  324. else if (j>122)
  325. {
  326. sprintf(buffer, "STBR%.3d",j);
  327. R_SetPatchNum(&hu_font2[i], buffer);
  328. R_SetPatchNum(&hu_font[i], buffer);
  329. }
  330. else
  331. hu_font[i] = hu_font[0]; //jff 2/16/98 account for gap
  332. }
  333. // CPhipps - load patches for message background
  334. for (i=0; i<9; i++) {
  335. sprintf(buffer, "BOX%c%c", "UCL"[i/3], "LCR"[i%3]);
  336. R_SetPatchNum(&hu_msgbg[i], buffer);
  337. }
  338. // CPhipps - load patches for keys and double keys
  339. for (i=0; i<6; i++) {
  340. sprintf(buffer, "STKEYS%d", i);
  341. R_SetPatchNum(&hu_fontk[i], buffer);
  342. }
  343. }
  344. //
  345. // HU_Stop()
  346. //
  347. // Make the heads-up displays inactive
  348. //
  349. // Passed nothing, returns nothing
  350. //
  351. static void HU_Stop(void)
  352. {
  353. headsupactive = false;
  354. }
  355. //
  356. // HU_Start(void)
  357. //
  358. // Create and initialize the heads-up widgets, software machines to
  359. // maintain, update, and display information over the primary display
  360. //
  361. // This routine must be called after any change to the heads up configuration
  362. // in order for the changes to take effect in the actual displays
  363. //
  364. // Passed nothing, returns nothing
  365. //
  366. void HU_Start(void)
  367. {
  368. int i;
  369. const char* s; /* cph - const */
  370. if (headsupactive) // stop before starting
  371. HU_Stop();
  372. plr = &players[displayplayer]; // killough 3/7/98
  373. message_on = false;
  374. message_dontfuckwithme = false;
  375. message_nottobefuckedwith = false;
  376. chat_on = false;
  377. // create the message widget
  378. // messages to player in upper-left of screen
  379. HUlib_initSText
  380. (
  381. &w_message,
  382. HU_MSGX,
  383. HU_MSGY,
  384. HU_MSGHEIGHT,
  385. hu_font,
  386. HU_FONTSTART,
  387. hudcolor_mesg,
  388. &message_on
  389. );
  390. //jff 2/16/98 added some HUD widgets
  391. // create the map title widget - map title display in lower left of automap
  392. HUlib_initTextLine
  393. (
  394. &w_title,
  395. HU_TITLEX,
  396. HU_TITLEY,
  397. hu_font,
  398. HU_FONTSTART,
  399. hudcolor_titl
  400. );
  401. // create the hud health widget
  402. // bargraph and number for amount of health,
  403. // lower left or upper right of screen
  404. HUlib_initTextLine
  405. (
  406. &w_health,
  407. hud_distributed? HU_HEALTHX_D : HU_HEALTHX, //3/4/98 distribute
  408. hud_distributed? HU_HEALTHY_D : HU_HEALTHY,
  409. hu_font2,
  410. HU_FONTSTART,
  411. CR_GREEN
  412. );
  413. // create the hud armor widget
  414. // bargraph and number for amount of armor,
  415. // lower left or upper right of screen
  416. HUlib_initTextLine
  417. (
  418. &w_armor,
  419. hud_distributed? HU_ARMORX_D : HU_ARMORX, //3/4/98 distribute
  420. hud_distributed? HU_ARMORY_D : HU_ARMORY,
  421. hu_font2,
  422. HU_FONTSTART,
  423. CR_GREEN
  424. );
  425. // create the hud ammo widget
  426. // bargraph and number for amount of ammo for current weapon,
  427. // lower left or lower right of screen
  428. HUlib_initTextLine
  429. (
  430. &w_ammo,
  431. hud_distributed? HU_AMMOX_D : HU_AMMOX, //3/4/98 distribute
  432. hud_distributed? HU_AMMOY_D : HU_AMMOY,
  433. hu_font2,
  434. HU_FONTSTART,
  435. CR_GOLD
  436. );
  437. // create the hud weapons widget
  438. // list of numbers of weapons possessed
  439. // lower left or lower right of screen
  440. HUlib_initTextLine
  441. (
  442. &w_weapon,
  443. hud_distributed? HU_WEAPX_D : HU_WEAPX, //3/4/98 distribute
  444. hud_distributed? HU_WEAPY_D : HU_WEAPY,
  445. hu_font2,
  446. HU_FONTSTART,
  447. CR_GRAY
  448. );
  449. // create the hud keys widget
  450. // display of key letters possessed
  451. // lower left of screen
  452. HUlib_initTextLine
  453. (
  454. &w_keys,
  455. hud_distributed? HU_KEYSX_D : HU_KEYSX, //3/4/98 distribute
  456. hud_distributed? HU_KEYSY_D : HU_KEYSY,
  457. hu_font2,
  458. HU_FONTSTART,
  459. CR_GRAY
  460. );
  461. // create the hud graphic keys widget
  462. // display of key graphics possessed
  463. // lower left of screen
  464. HUlib_initTextLine
  465. (
  466. &w_gkeys,
  467. hud_distributed? HU_KEYSGX_D : HU_KEYSGX, //3/4/98 distribute
  468. hud_distributed? HU_KEYSY_D : HU_KEYSY,
  469. hu_fontk,
  470. HU_FONTSTART,
  471. CR_RED
  472. );
  473. // create the hud monster/secret widget
  474. // totals and current values for kills, items, secrets
  475. // lower left of screen
  476. HUlib_initTextLine
  477. (
  478. &w_monsec,
  479. hud_distributed? HU_MONSECX_D : HU_MONSECX, //3/4/98 distribute
  480. hud_distributed? HU_MONSECY_D : HU_MONSECY,
  481. hu_font2,
  482. HU_FONTSTART,
  483. CR_GRAY
  484. );
  485. // create the hud text refresh widget
  486. // scrolling display of last hud_msg_lines messages received
  487. if (hud_msg_lines>HU_MAXMESSAGES)
  488. hud_msg_lines=HU_MAXMESSAGES;
  489. //jff 4/21/98 if setup has disabled message list while active, turn it off
  490. message_list = hud_msg_lines > 1; //jff 8/8/98 initialize both ways
  491. //jff 2/26/98 add the text refresh widget initialization
  492. HUlib_initMText
  493. (
  494. &w_rtext,
  495. 0,
  496. 0,
  497. 320,
  498. // SCREENWIDTH,
  499. (hud_msg_lines+2)*HU_REFRESHSPACING,
  500. hu_font,
  501. HU_FONTSTART,
  502. hudcolor_list,
  503. hu_msgbg,
  504. &message_list
  505. );
  506. // initialize the automap's level title widget
  507. if (gamestate == GS_LEVEL) /* cph - stop SEGV here when not in level */
  508. switch (gamemode)
  509. {
  510. case shareware:
  511. case registered:
  512. case retail:
  513. s = HU_TITLE;
  514. break;
  515. case commercial:
  516. default: // Ty 08/27/98 - modified to check mission for TNT/Plutonia
  517. s = (gamemission==pack_tnt) ? HU_TITLET :
  518. (gamemission==pack_plut) ? HU_TITLEP : HU_TITLE2;
  519. break;
  520. } else s = "";
  521. while (*s)
  522. HUlib_addCharToTextLine(&w_title, *(s++));
  523. // create the automaps coordinate widget
  524. // jff 3/3/98 split coord widget into three lines: x,y,z
  525. // jff 2/16/98 added
  526. HUlib_initTextLine
  527. (
  528. &w_coordx,
  529. HU_COORDX,
  530. HU_COORDX_Y,
  531. hu_font,
  532. HU_FONTSTART,
  533. hudcolor_xyco
  534. );
  535. HUlib_initTextLine
  536. (
  537. &w_coordy,
  538. HU_COORDX,
  539. HU_COORDY_Y,
  540. hu_font,
  541. HU_FONTSTART,
  542. hudcolor_xyco
  543. );
  544. HUlib_initTextLine
  545. (
  546. &w_coordz,
  547. HU_COORDX,
  548. HU_COORDZ_Y,
  549. hu_font,
  550. HU_FONTSTART,
  551. hudcolor_xyco
  552. );
  553. // initialize the automaps coordinate widget
  554. //jff 3/3/98 split coordstr widget into 3 parts
  555. if (map_point_coordinates)
  556. {
  557. sprintf(hud_coordstrx,"X: %-5d",0); //jff 2/22/98 added z
  558. s = hud_coordstrx;
  559. while (*s)
  560. HUlib_addCharToTextLine(&w_coordx, *(s++));
  561. sprintf(hud_coordstry,"Y: %-5d",0); //jff 3/3/98 split x,y,z
  562. s = hud_coordstry;
  563. while (*s)
  564. HUlib_addCharToTextLine(&w_coordy, *(s++));
  565. sprintf(hud_coordstrz,"Z: %-5d",0); //jff 3/3/98 split x,y,z
  566. s = hud_coordstrz;
  567. while (*s)
  568. HUlib_addCharToTextLine(&w_coordz, *(s++));
  569. }
  570. //jff 2/16/98 initialize ammo widget
  571. strcpy(hud_ammostr,"AMM ");
  572. s = hud_ammostr;
  573. while (*s)
  574. HUlib_addCharToTextLine(&w_ammo, *(s++));
  575. //jff 2/16/98 initialize health widget
  576. strcpy(hud_healthstr,"HEL ");
  577. s = hud_healthstr;
  578. while (*s)
  579. HUlib_addCharToTextLine(&w_health, *(s++));
  580. //jff 2/16/98 initialize armor widget
  581. strcpy(hud_armorstr,"ARM ");
  582. s = hud_armorstr;
  583. while (*s)
  584. HUlib_addCharToTextLine(&w_armor, *(s++));
  585. //jff 2/17/98 initialize weapons widget
  586. strcpy(hud_weapstr,"WEA ");
  587. s = hud_weapstr;
  588. while (*s)
  589. HUlib_addCharToTextLine(&w_weapon, *(s++));
  590. //jff 2/17/98 initialize keys widget
  591. if (!deathmatch) //jff 3/17/98 show frags in deathmatch mode
  592. strcpy(hud_keysstr,"KEY ");
  593. else
  594. strcpy(hud_keysstr,"FRG ");
  595. s = hud_keysstr;
  596. while (*s)
  597. HUlib_addCharToTextLine(&w_keys, *(s++));
  598. //jff 2/17/98 initialize graphic keys widget
  599. strcpy(hud_gkeysstr," ");
  600. s = hud_gkeysstr;
  601. while (*s)
  602. HUlib_addCharToTextLine(&w_gkeys, *(s++));
  603. //jff 2/17/98 initialize kills/items/secret widget
  604. strcpy(hud_monsecstr,"STS ");
  605. s = hud_monsecstr;
  606. while (*s)
  607. HUlib_addCharToTextLine(&w_monsec, *(s++));
  608. // create the chat widget
  609. HUlib_initIText
  610. (
  611. &w_chat,
  612. HU_INPUTX,
  613. HU_INPUTY,
  614. hu_font,
  615. HU_FONTSTART,
  616. hudcolor_chat,
  617. &chat_on
  618. );
  619. // create the inputbuffer widgets, one per player
  620. for (i=0 ; i<MAXPLAYERS ; i++)
  621. HUlib_initIText
  622. (
  623. &w_inputbuffer[i],
  624. 0,
  625. 0,
  626. 0,
  627. 0,
  628. hudcolor_chat,
  629. &always_off
  630. );
  631. // now allow the heads-up display to run
  632. headsupactive = true;
  633. }
  634. //
  635. // HU_MoveHud()
  636. //
  637. // Move the HUD display from distributed to compact mode or vice-versa
  638. //
  639. // Passed nothing, returns nothing
  640. //
  641. //jff 3/9/98 create this externally callable to avoid glitch
  642. // when menu scatter's HUD due to delay in change of position
  643. //
  644. void HU_MoveHud(void)
  645. {
  646. static int ohud_distributed=-1;
  647. //jff 3/4/98 move displays around on F5 changing hud_distributed
  648. if (hud_distributed!=ohud_distributed)
  649. {
  650. w_ammo.x = hud_distributed? HU_AMMOX_D : HU_AMMOX;
  651. w_ammo.y = hud_distributed? HU_AMMOY_D : HU_AMMOY;
  652. w_weapon.x = hud_distributed? HU_WEAPX_D : HU_WEAPX;
  653. w_weapon.y = hud_distributed? HU_WEAPY_D : HU_WEAPY;
  654. w_keys.x = hud_distributed? HU_KEYSX_D : HU_KEYSX;
  655. w_keys.y = hud_distributed? HU_KEYSY_D : HU_KEYSY;
  656. w_gkeys.x = hud_distributed? HU_KEYSGX_D : HU_KEYSGX;
  657. w_gkeys.y = hud_distributed? HU_KEYSY_D : HU_KEYSY;
  658. w_monsec.x = hud_distributed? HU_MONSECX_D : HU_MONSECX;
  659. w_monsec.y = hud_distributed? HU_MONSECY_D : HU_MONSECY;
  660. w_health.x = hud_distributed? HU_HEALTHX_D : HU_HEALTHX;
  661. w_health.y = hud_distributed? HU_HEALTHY_D : HU_HEALTHY;
  662. w_armor.x = hud_distributed? HU_ARMORX_D : HU_ARMORX;
  663. w_armor.y = hud_distributed? HU_ARMORY_D : HU_ARMORY;
  664. }
  665. ohud_distributed = hud_distributed;
  666. }
  667. //
  668. // HU_Drawer()
  669. //
  670. // Draw all the pieces of the heads-up display
  671. //
  672. // Passed nothing, returns nothing
  673. //
  674. void HU_Drawer(void)
  675. {
  676. char *s;
  677. player_t *player;
  678. char ammostr[80]; //jff 3/8/98 allow plenty room for dehacked mods
  679. char healthstr[80];//jff
  680. char armorstr[80]; //jff
  681. int i,doit;
  682. player = &players[displayplayer]; // killough 3/7/98
  683. // draw the automap widgets if automap is displayed
  684. if (automapmode & am_active)
  685. {
  686. // map title
  687. HUlib_drawTextLine(&w_title, false);
  688. //jff 2/16/98 output new coord display
  689. // x-coord
  690. if (map_point_coordinates)
  691. {
  692. sprintf(hud_coordstrx,"X: %-5d", (player->mo->x)>>FRACBITS);
  693. HUlib_clearTextLine(&w_coordx);
  694. s = hud_coordstrx;
  695. while (*s)
  696. HUlib_addCharToTextLine(&w_coordx, *(s++));
  697. HUlib_drawTextLine(&w_coordx, false);
  698. //jff 3/3/98 split coord display into x,y,z lines
  699. // y-coord
  700. sprintf(hud_coordstry,"Y: %-5d", (player->mo->y)>>FRACBITS);
  701. HUlib_clearTextLine(&w_coordy);
  702. s = hud_coordstry;
  703. while (*s)
  704. HUlib_addCharToTextLine(&w_coordy, *(s++));
  705. HUlib_drawTextLine(&w_coordy, false);
  706. //jff 3/3/98 split coord display into x,y,z lines
  707. //jff 2/22/98 added z
  708. // z-coord
  709. sprintf(hud_coordstrz,"Z: %-5d", (player->mo->z)>>FRACBITS);
  710. HUlib_clearTextLine(&w_coordz);
  711. s = hud_coordstrz;
  712. while (*s)
  713. HUlib_addCharToTextLine(&w_coordz, *(s++));
  714. HUlib_drawTextLine(&w_coordz, false);
  715. }
  716. }
  717. // draw the weapon/health/ammo/armor/kills/keys displays if optioned
  718. //jff 2/17/98 allow new hud stuff to be turned off
  719. // killough 2/21/98: really allow new hud stuff to be turned off COMPLETELY
  720. if
  721. (
  722. hud_active>0 && // hud optioned on
  723. hud_displayed && // hud on from fullscreen key
  724. viewheight==SCREENHEIGHT && // fullscreen mode is active
  725. !(automapmode & am_active) // automap is not active
  726. )
  727. {
  728. doit = !(gametic&1); //jff 3/4/98 speed update up for slow systems
  729. if (doit) //jff 8/7/98 update every time, avoid lag in update
  730. {
  731. HU_MoveHud(); // insure HUD display coords are correct
  732. // do the hud ammo display
  733. // clear the widgets internal line
  734. HUlib_clearTextLine(&w_ammo);
  735. strcpy(hud_ammostr,"AMM ");
  736. if (weaponinfo[player->readyweapon].ammo == am_noammo)
  737. { // special case for weapon with no ammo selected - blank bargraph + N/A
  738. strcat(hud_ammostr,"\x7f\x7f\x7f\x7f\x7f\x7f\x7f N/A");
  739. w_ammo.cm = CR_GRAY;
  740. }
  741. else
  742. {
  743. int ammo = player->ammo[weaponinfo[player->readyweapon].ammo];
  744. int fullammo = player->maxammo[weaponinfo[player->readyweapon].ammo];
  745. int ammopct = (100*ammo)/fullammo;
  746. int ammobars = ammopct/4;
  747. // build the numeric amount init string
  748. sprintf(ammostr,"%d/%d",ammo,fullammo);
  749. // build the bargraph string
  750. // full bargraph chars
  751. for (i=4;i<4+ammobars/4;)
  752. hud_ammostr[i++] = 123;
  753. // plus one last character with 0,1,2,3 bars
  754. switch(ammobars%4)
  755. {
  756. case 0:
  757. break;
  758. case 1:
  759. hud_ammostr[i++] = 126;
  760. break;
  761. case 2:
  762. hud_ammostr[i++] = 125;
  763. break;
  764. case 3:
  765. hud_ammostr[i++] = 124;
  766. break;
  767. }
  768. // pad string with blank bar characters
  769. while(i<4+7)
  770. hud_ammostr[i++] = 127;
  771. hud_ammostr[i] = '\0';
  772. strcat(hud_ammostr,ammostr);
  773. // set the display color from the percentage of total ammo held
  774. if (ammopct<ammo_red)
  775. w_ammo.cm = CR_RED;
  776. else if (ammopct<ammo_yellow)
  777. w_ammo.cm = CR_GOLD;
  778. else
  779. w_ammo.cm = CR_GREEN;
  780. }
  781. // transfer the init string to the widget
  782. s = hud_ammostr;
  783. while (*s)
  784. HUlib_addCharToTextLine(&w_ammo, *(s++));
  785. }
  786. // display the ammo widget every frame
  787. HUlib_drawTextLine(&w_ammo, false);
  788. // do the hud health display
  789. if (doit)
  790. {
  791. int health = player->health;
  792. int healthbars = health>100? 25 : health/4;
  793. // clear the widgets internal line
  794. HUlib_clearTextLine(&w_health);
  795. // build the numeric amount init string
  796. sprintf(healthstr,"%3d",health);
  797. // build the bargraph string
  798. // full bargraph chars
  799. for (i=4;i<4+healthbars/4;)
  800. hud_healthstr[i++] = 123;
  801. // plus one last character with 0,1,2,3 bars
  802. switch(healthbars%4)
  803. {
  804. case 0:
  805. break;
  806. case 1:
  807. hud_healthstr[i++] = 126;
  808. break;
  809. case 2:
  810. hud_healthstr[i++] = 125;
  811. break;
  812. case 3:
  813. hud_healthstr[i++] = 124;
  814. break;
  815. }
  816. // pad string with blank bar characters
  817. while(i<4+7)
  818. hud_healthstr[i++] = 127;
  819. hud_healthstr[i] = '\0';
  820. strcat(hud_healthstr,healthstr);
  821. // set the display color from the amount of health posessed
  822. if (health<health_red)
  823. w_health.cm = CR_RED;
  824. else if (health<health_yellow)
  825. w_health.cm = CR_GOLD;
  826. else if (health<=health_green)
  827. w_health.cm = CR_GREEN;
  828. else
  829. w_health.cm = CR_BLUE;
  830. // transfer the init string to the widget
  831. s = hud_healthstr;
  832. while (*s)
  833. HUlib_addCharToTextLine(&w_health, *(s++));
  834. }
  835. // display the health widget every frame
  836. HUlib_drawTextLine(&w_health, false);
  837. // do the hud armor display
  838. if (doit)
  839. {
  840. int armor = player->armorpoints;
  841. int armorbars = armor>100? 25 : armor/4;
  842. // clear the widgets internal line
  843. HUlib_clearTextLine(&w_armor);
  844. // build the numeric amount init string
  845. sprintf(armorstr,"%3d",armor);
  846. // build the bargraph string
  847. // full bargraph chars
  848. for (i=4;i<4+armorbars/4;)
  849. hud_armorstr[i++] = 123;
  850. // plus one last character with 0,1,2,3 bars
  851. switch(armorbars%4)
  852. {
  853. case 0:
  854. break;
  855. case 1:
  856. hud_armorstr[i++] = 126;
  857. break;
  858. case 2:
  859. hud_armorstr[i++] = 125;
  860. break;
  861. case 3:
  862. hud_armorstr[i++] = 124;
  863. break;
  864. }
  865. // pad string with blank bar characters
  866. while(i<4+7)
  867. hud_armorstr[i++] = 127;
  868. hud_armorstr[i] = '\0';
  869. strcat(hud_armorstr,armorstr);
  870. // set the display color from the amount of armor posessed
  871. if (armor<armor_red)
  872. w_armor.cm = CR_RED;
  873. else if (armor<armor_yellow)
  874. w_armor.cm = CR_GOLD;
  875. else if (armor<=armor_green)
  876. w_armor.cm = CR_GREEN;
  877. else
  878. w_armor.cm = CR_BLUE;
  879. // transfer the init string to the widget
  880. s = hud_armorstr;
  881. while (*s)
  882. HUlib_addCharToTextLine(&w_armor, *(s++));
  883. }
  884. // display the armor widget every frame
  885. HUlib_drawTextLine(&w_armor, false);
  886. // do the hud weapon display
  887. if (doit)
  888. {
  889. int w;
  890. int ammo,fullammo,ammopct;
  891. // clear the widgets internal line
  892. HUlib_clearTextLine(&w_weapon);
  893. i=4; hud_weapstr[i] = '\0'; //jff 3/7/98 make sure ammo goes away
  894. // do each weapon that exists in current gamemode
  895. for (w=0;w<=wp_supershotgun;w++) //jff 3/4/98 show fists too, why not?
  896. {
  897. int ok=1;
  898. //jff avoid executing for weapons that do not exist
  899. switch (gamemode)
  900. {
  901. case shareware:
  902. if (w>=wp_plasma && w!=wp_chainsaw)
  903. ok=0;
  904. break;
  905. case retail:
  906. case registered:
  907. if (w>=wp_supershotgun)
  908. ok=0;
  909. break;
  910. default:
  911. case commercial:
  912. break;
  913. }
  914. if (!ok) continue;
  915. ammo = player->ammo[weaponinfo[w].ammo];
  916. fullammo = player->maxammo[weaponinfo[w].ammo];
  917. ammopct=0;
  918. // skip weapons not currently posessed
  919. if (!player->weaponowned[w])
  920. continue;
  921. ammopct = fullammo? (100*ammo)/fullammo : 100;
  922. // display each weapon number in a color related to the ammo for it
  923. hud_weapstr[i++] = '\x1b'; //jff 3/26/98 use ESC not '\' for paths
  924. if (weaponinfo[w].ammo==am_noammo) //jff 3/14/98 show berserk on HUD
  925. hud_weapstr[i++] = player->powers[pw_strength]? '0'+CR_GREEN : '0'+CR_GRAY;
  926. else if (ammopct<ammo_red)
  927. hud_weapstr[i++] = '0'+CR_RED;
  928. else if (ammopct<ammo_yellow)
  929. hud_weapstr[i++] = '0'+CR_GOLD;
  930. else
  931. hud_weapstr[i++] = '0'+CR_GREEN;
  932. hud_weapstr[i++] = '0'+w+1;
  933. hud_weapstr[i++] = ' ';
  934. hud_weapstr[i] = '\0';
  935. }
  936. // transfer the init string to the widget
  937. s = hud_weapstr;
  938. while (*s)
  939. HUlib_addCharToTextLine(&w_weapon, *(s++));
  940. }
  941. // display the weapon widget every frame
  942. HUlib_drawTextLine(&w_weapon, false);
  943. if (doit && hud_active>1)
  944. {
  945. int k;
  946. hud_keysstr[4] = '\0'; //jff 3/7/98 make sure deleted keys go away
  947. //jff add case for graphic key display
  948. if (!deathmatch && hud_graph_keys)
  949. {
  950. i=0;
  951. hud_gkeysstr[i] = '\0'; //jff 3/7/98 init graphic keys widget string
  952. // build text string whose characters call out graphic keys from fontk
  953. for (k=0;k<6;k++)
  954. {
  955. // skip keys not possessed
  956. if (!player->cards[k])
  957. continue;
  958. hud_gkeysstr[i++] = '!'+k; // key number plus '!' is char for key
  959. hud_gkeysstr[i++] = ' '; // spacing
  960. hud_gkeysstr[i++] = ' ';
  961. }
  962. hud_gkeysstr[i]='\0';
  963. }
  964. else // not possible in current code, unless deathmatching,
  965. {
  966. i=4;
  967. hud_keysstr[i] = '\0'; //jff 3/7/98 make sure deleted keys go away
  968. // if deathmatch, build string showing top four frag counts
  969. if (deathmatch) //jff 3/17/98 show frags, not keys, in deathmatch
  970. {
  971. int top1=-999,top2=-999,top3=-999,top4=-999;
  972. int idx1=-1,idx2=-1,idx3=-1,idx4=-1;
  973. int fragcount,m;
  974. char numbuf[32];
  975. // scan thru players
  976. for (k=0;k<MAXPLAYERS;k++)
  977. {
  978. // skip players not in game
  979. if (!playeringame[k])
  980. continue;
  981. fragcount = 0;
  982. // compute number of times they've fragged each player
  983. // minus number of times they've been fragged by them
  984. for (m=0;m<MAXPLAYERS;m++)
  985. {
  986. if (!playeringame[m]) continue;
  987. fragcount += (m!=k)? players[k].frags[m] : -players[k].frags[m];
  988. }
  989. // very primitive sort of frags to find top four
  990. if (fragcount>top1)
  991. {
  992. top4=top3; top3=top2; top2 = top1; top1=fragcount;
  993. idx4=idx3; idx3=idx2; idx2 = idx1; idx1=k;
  994. }
  995. else if (fragcount>top2)
  996. {
  997. top4=top3; top3=top2; top2=fragcount;
  998. idx4=idx3; idx3=idx2; idx2=k;
  999. }
  1000. else if (fragcount>top3)
  1001. {
  1002. top4=top3; top3=fragcount;
  1003. idx4=idx3; idx3=k;
  1004. }
  1005. else if (fragcount>top4)
  1006. {
  1007. top4=fragcount;
  1008. idx4=k;
  1009. }
  1010. }
  1011. // if the biggest number exists, put it in the init string
  1012. if (idx1>-1)
  1013. {
  1014. sprintf(numbuf,"%5d",top1);
  1015. // make frag count in player's color via escape code
  1016. hud_keysstr[i++] = '\x1b'; //jff 3/26/98 use ESC not '\' for paths
  1017. hud_keysstr[i++] = '0'+plyrcoltran[idx1&3];
  1018. s = numbuf;
  1019. while (*s)
  1020. hud_keysstr[i++] = *(s++);
  1021. }
  1022. // if the second biggest number exists, put it in the init string
  1023. if (idx2>-1)
  1024. {
  1025. sprintf(numbuf,"%5d",top2);
  1026. // make frag count in player's color via escape code
  1027. hud_keysstr[i++] = '\x1b'; //jff 3/26/98 use ESC not '\' for paths
  1028. hud_keysstr[i++] = '0'+plyrcoltran[idx2&3];
  1029. s = numbuf;
  1030. while (*s)
  1031. hud_keysstr[i++] = *(s++);
  1032. }
  1033. // if the third biggest number exists, put it in the init string
  1034. if (idx3>-1)
  1035. {
  1036. sprintf(numbuf,"%5d",top3);
  1037. // make frag count in player's color via escape code
  1038. hud_keysstr[i++] = '\x1b'; //jff 3/26/98 use ESC not '\' for paths
  1039. hud_keysstr[i++] = '0'+plyrcoltran[idx3&3];
  1040. s = numbuf;
  1041. while (*s)
  1042. hud_keysstr[i++] = *(s++);
  1043. }
  1044. // if the fourth biggest number exists, put it in the init string
  1045. if (idx4>-1)
  1046. {
  1047. sprintf(numbuf,"%5d",top4);
  1048. // make frag count in player's color via escape code
  1049. hud_keysstr[i++] = '\x1b'; //jff 3/26/98 use ESC not '\' for paths
  1050. hud_keysstr[i++] = '0'+plyrcoltran[idx4&3];
  1051. s = numbuf;
  1052. while (*s)
  1053. hud_keysstr[i++] = *(s++);
  1054. }
  1055. hud_keysstr[i] = '\0';
  1056. } //jff 3/17/98 end of deathmatch clause
  1057. else // build alphabetical key display (not used currently)
  1058. {
  1059. // scan the keys
  1060. for (k=0;k<6;k++)
  1061. {
  1062. // skip any not possessed by the displayed player's stats
  1063. if (!player->cards[k])
  1064. continue;
  1065. // use color escapes to make text in key's color
  1066. hud_keysstr[i++] = '\x1b'; //jff 3/26/98 use ESC not '\' for paths
  1067. switch(k)
  1068. {
  1069. case 0:
  1070. hud_keysstr[i++] = '0'+CR_BLUE;
  1071. hud_keysstr[i++] = 'B';
  1072. hud_keysstr[i++] = 'C';
  1073. hud_keysstr[i++] = ' ';
  1074. break;
  1075. case 1:
  1076. hud_keysstr[i++] = '0'+CR_GOLD;
  1077. hud_keysstr[i++] = 'Y';
  1078. hud_keysstr[i++] = 'C';
  1079. hud_keysstr[i++] = ' ';
  1080. break;
  1081. case 2:
  1082. hud_keysstr[i++] = '0'+CR_RED;
  1083. hud_keysstr[i++] = 'R';
  1084. hud_keysstr[i++] = 'C';
  1085. hud_keysstr[i++] = ' ';
  1086. break;
  1087. case 3:
  1088. hud_keysstr[i++] = '0'+CR_BLUE;
  1089. hud_keysstr[i++] = 'B';
  1090. hud_keysstr[i++] = 'S';
  1091. hud_keysstr[i++] = ' ';
  1092. break;
  1093. case 4:
  1094. hud_keysstr[i++] = '0'+CR_GOLD;
  1095. hud_keysstr[i++] = 'Y';
  1096. hud_keysstr[i++] = 'S';
  1097. hud_keysstr[i++] = ' ';
  1098. break;
  1099. case 5:
  1100. hud_keysstr[i++] = '0'+CR_RED;
  1101. hud_keysstr[i++] = 'R';
  1102. hud_keysstr[i++] = 'S';
  1103. hud_keysstr[i++] = ' ';
  1104. break;
  1105. }
  1106. hud_keysstr[i]='\0';
  1107. }
  1108. }
  1109. }
  1110. }
  1111. // display the keys/frags line each frame
  1112. if (hud_active>1)
  1113. {
  1114. HUlib_clearTextLine(&w_keys); // clear the widget strings
  1115. HUlib_clearTextLine(&w_gkeys);
  1116. // transfer the built string (frags or key title) to the widget
  1117. s = hud_keysstr; //jff 3/7/98 display key titles/key text or frags
  1118. while (*s)
  1119. HUlib_addCharToTextLine(&w_keys, *(s++));
  1120. HUlib_drawTextLine(&w_keys, false);
  1121. //jff 3/17/98 show graphic keys in non-DM only
  1122. if (!deathmatch) //jff 3/7/98 display graphic keys
  1123. {
  1124. // transfer the graphic key text to the widget
  1125. s = hud_gkeysstr;
  1126. while (*s)
  1127. HUlib_addCharToTextLine(&w_gkeys, *(s++));
  1128. // display the widget
  1129. HUlib_drawTextLine(&w_gkeys, false);
  1130. }
  1131. }
  1132. // display the hud kills/items/secret display if optioned
  1133. if (!hud_nosecrets)
  1134. {
  1135. if (hud_active>1 && doit)
  1136. {
  1137. // clear the internal widget text buffer
  1138. HUlib_clearTextLine(&w_monsec);
  1139. //jff 3/26/98 use ESC not '\' for paths
  1140. // build the init string with fixed colors
  1141. sprintf
  1142. (
  1143. hud_monsecstr,
  1144. "STS \x1b\x36K \x1b\x33%d \x1b\x36M \x1b\x33%d \x1b\x37I \x1b\x33%d/%d \x1b\x35S \x1b\x33%d/%d",
  1145. player->killcount,totallive,
  1146. player->itemcount,totalitems,
  1147. player->secretcount,totalsecret
  1148. );
  1149. // transfer the init string to the widget
  1150. s = hud_monsecstr;
  1151. while (*s)
  1152. HUlib_addCharToTextLine(&w_monsec, *(s++));
  1153. }
  1154. // display the kills/items/secrets each frame, if optioned
  1155. if (hud_active>1)
  1156. HUlib_drawTextLine(&w_monsec, false);
  1157. }
  1158. }
  1159. //jff 3/4/98 display last to give priority
  1160. HU_Erase(); // jff 4/24/98 Erase current lines before drawing current
  1161. // needed when screen not fullsize
  1162. //jff 4/21/98 if setup has disabled message list while active, turn it off
  1163. if (hud_msg_lines<=1)
  1164. message_list = false;
  1165. // if the message review not enabled, show the standard message widget
  1166. if (!message_list)
  1167. HUlib_drawSText(&w_message);
  1168. // if the message review is enabled show the scrolling message review
  1169. if (hud_msg_lines>1 && message_list)
  1170. HUlib_drawMText(&w_rtext);
  1171. // display the interactive buffer for chat entry
  1172. HUlib_drawIText(&w_chat);
  1173. }
  1174. //
  1175. // HU_Erase()
  1176. //
  1177. // Erase hud display lines that can be trashed by small screen display
  1178. //
  1179. // Passed nothing, returns nothing
  1180. //
  1181. void HU_Erase(void)
  1182. {
  1183. // erase the message display or the message review display
  1184. if (!message_list)
  1185. HUlib_eraseSText(&w_message);
  1186. else
  1187. HUlib_eraseMText(&w_rtext);
  1188. // erase the interactive text buffer for chat entry
  1189. HUlib_eraseIText(&w_chat);
  1190. // erase the automap title
  1191. HUlib_eraseTextLine(&w_title);
  1192. }
  1193. //
  1194. // HU_Ticker()
  1195. //
  1196. // Update the hud displays once per frame
  1197. //
  1198. // Passed nothing, returns nothing
  1199. //
  1200. static boolean bsdown; // Is backspace down?
  1201. static int bscounter;
  1202. void HU_Ticker(void)
  1203. {
  1204. int i, rc;
  1205. char c;
  1206. // tick down message counter if message is up
  1207. if (message_counter && !--message_counter)
  1208. {
  1209. message_on = false;
  1210. message_nottobefuckedwith = false;
  1211. }
  1212. if (bsdown && bscounter++ > 9) {
  1213. HUlib_keyInIText(&w_chat, (unsigned char)key_backspace);
  1214. bscounter = 8;
  1215. }
  1216. // if messages on, or "Messages Off" is being displayed
  1217. // this allows the notification of turning messages off to be seen
  1218. if (showMessages || message_dontfuckwithme)
  1219. {
  1220. // display message if necessary
  1221. if ((plr->message && !message_nottobefuckedwith)
  1222. || (plr->message && message_dontfuckwithme))
  1223. {
  1224. #ifdef IPHONE
  1225. // draw with the high quality font, above all UI elements
  1226. iphoneSetNotifyText( "%s", plr->message );
  1227. #else
  1228. //post the message to the message widget
  1229. HUlib_addMessageToSText(&w_message, 0, plr->message);
  1230. //jff 2/26/98 add message to refresh text widget too
  1231. HUlib_addMessageToMText(&w_rtext, 0, plr->message);
  1232. #endif
  1233. // clear the message to avoid posting multiple times
  1234. plr->message = 0;
  1235. // note a message is displayed
  1236. message_on = true;
  1237. // start the message persistence counter
  1238. message_counter = HU_MSGTIMEOUT;
  1239. // transfer "Messages Off" exception to the "being displayed" variable
  1240. message_nottobefuckedwith = message_dontfuckwithme;
  1241. // clear the flag that "Messages Off" is being posted
  1242. message_dontfuckwithme = 0;
  1243. }
  1244. }
  1245. // check for incoming chat characters
  1246. if (netgame)
  1247. {
  1248. for (i=0; i<MAXPLAYERS; i++)
  1249. {
  1250. if (!playeringame[i])
  1251. continue;
  1252. if (i != consoleplayer
  1253. && (c = players[i].cmd.chatchar))
  1254. {
  1255. if (c <= HU_BROADCAST)
  1256. chat_dest[i] = c;
  1257. else
  1258. {
  1259. if (c >= 'a' && c <= 'z')
  1260. c = (char) shiftxform[(unsigned char) c];
  1261. rc = HUlib_keyInIText(&w_inputbuffer[i], c);
  1262. if (rc && c == KEYD_ENTER)
  1263. {
  1264. if (w_inputbuffer[i].l.len
  1265. && (chat_dest[i] == consoleplayer+1
  1266. || chat_dest[i] == HU_BROADCAST))
  1267. {
  1268. HUlib_addMessageToSText(&w_message,
  1269. player_names[i],
  1270. w_inputbuffer[i].l.l);
  1271. message_nottobefuckedwith = true;
  1272. message_on = true;
  1273. message_counter = HU_MSGTIMEOUT;
  1274. if ( gamemode == commercial )
  1275. S_StartSound(0, sfx_radio);
  1276. else
  1277. S_StartSound(0, sfx_tink);
  1278. }
  1279. HUlib_resetIText(&w_inputbuffer[i]);
  1280. }
  1281. }
  1282. players[i].cmd.chatchar = 0;
  1283. }
  1284. }
  1285. }
  1286. }
  1287. #define QUEUESIZE 128
  1288. static char chatchars[QUEUESIZE];
  1289. static int head = 0;
  1290. static int tail = 0;
  1291. //
  1292. // HU_queueChatChar()
  1293. //
  1294. // Add an incoming character to the circular chat queue
  1295. //
  1296. // Passed the character to queue, returns nothing
  1297. //
  1298. static void HU_queueChatChar(char c)
  1299. {
  1300. if (((head + 1) & (QUEUESIZE-1)) == tail)
  1301. {
  1302. plr->message = HUSTR_MSGU;
  1303. }
  1304. else
  1305. {
  1306. chatchars[head] = c;
  1307. head = (head + 1) & (QUEUESIZE-1);
  1308. }
  1309. }
  1310. //
  1311. // HU_dequeueChatChar()
  1312. //
  1313. // Remove the earliest added character from the circular chat queue
  1314. //
  1315. // Passed nothing, returns the character dequeued
  1316. //
  1317. char HU_dequeueChatChar(void)
  1318. {
  1319. char c;
  1320. if (head != tail)
  1321. {
  1322. c = chatchars[tail];
  1323. tail = (tail + 1) & (QUEUESIZE-1);
  1324. }
  1325. else
  1326. {
  1327. c = 0;
  1328. }
  1329. return c;
  1330. }
  1331. //
  1332. // HU_Responder()
  1333. //
  1334. // Responds to input events that affect the heads up displays
  1335. //
  1336. // Passed the event to respond to, returns true if the event was handled
  1337. //
  1338. boolean HU_Responder(event_t *ev)
  1339. {
  1340. static char lastmessage[HU_MAXLINELENGTH+1];
  1341. const char* macromessage; // CPhipps - const char*
  1342. boolean eatkey = false;
  1343. static boolean shiftdown = false;
  1344. static boolean altdown = false;
  1345. unsigned char c;
  1346. int i;
  1347. int numplayers;
  1348. static int num_nobrainers = 0;
  1349. numplayers = 0;
  1350. for (i=0 ; i<MAXPLAYERS ; i++)
  1351. numplayers += playeringame[i];
  1352. if (ev->data1 == key_shift)
  1353. {
  1354. shiftdown = ev->type == ev_keydown;
  1355. return false;
  1356. }
  1357. else if (ev->data1 == key_alt)
  1358. {
  1359. altdown = ev->type == ev_keydown;
  1360. return false;
  1361. }
  1362. else if (ev->data1 == key_backspace)
  1363. {
  1364. bsdown = ev->type == ev_keydown;
  1365. bscounter = 0;
  1366. }
  1367. if (ev->type != ev_keydown)
  1368. return false;
  1369. if (!chat_on)
  1370. {
  1371. if (ev->data1 == key_enter) // phares
  1372. {
  1373. #ifndef INSTRUMENTED // never turn on message review if INSTRUMENTED defined
  1374. if (hud_msg_lines>1) // it posts multi-line messages that will trash
  1375. {
  1376. if (message_list) HU_Erase(); //jff 4/28/98 erase behind messages
  1377. message_list = !message_list; //jff 2/26/98 toggle list of messages
  1378. }
  1379. #endif
  1380. if (!message_list) // if not message list, refresh message
  1381. {
  1382. message_on = true;
  1383. message_counter = HU_MSGTIMEOUT;
  1384. }
  1385. eatkey = true;
  1386. }//jff 2/26/98 no chat if message review is displayed
  1387. // killough 10/02/98: no chat if demo playback
  1388. // no chat in -solo-net mode
  1389. else if (!demoplayback && !message_list && netgame && numplayers > 1)
  1390. {
  1391. if (ev->data1 == key_chat)
  1392. {
  1393. eatkey = chat_on = true;
  1394. HUlib_resetIText(&w_chat);
  1395. HU_queueChatChar(HU_BROADCAST);
  1396. }
  1397. else if (numplayers > 2)
  1398. {
  1399. for (i=0; i<MAXPLAYERS ; i++)
  1400. {
  1401. if (ev->data1 == destination_keys[i])
  1402. {
  1403. if (playeringame[i] && i!=consoleplayer)
  1404. {
  1405. eatkey = chat_on = true;
  1406. HUlib_resetIText(&w_chat);
  1407. HU_queueChatChar((char)(i+1));
  1408. break;
  1409. }
  1410. else if (i == consoleplayer)
  1411. {
  1412. num_nobrainers++;
  1413. if (num_nobrainers < 3)
  1414. plr->message = HUSTR_TALKTOSELF1;
  1415. else if (num_nobrainers < 6)
  1416. plr->message = HUSTR_TALKTOSELF2;
  1417. else if (num_nobrainers < 9)
  1418. plr->message = HUSTR_TALKTOSELF3;
  1419. else if (num_nobrainers < 32)
  1420. plr->message = HUSTR_TALKTOSELF4;
  1421. else
  1422. plr->message = HUSTR_TALKTOSELF5;
  1423. }
  1424. }
  1425. }
  1426. }
  1427. }
  1428. }//jff 2/26/98 no chat functions if message review is displayed
  1429. else if (!message_list)
  1430. {
  1431. c = ev->data1;
  1432. // send a macro
  1433. if (altdown)
  1434. {
  1435. c = c - '0';
  1436. if (c > 9)
  1437. return false;
  1438. macromessage = chat_macros[c];
  1439. // kill last message with a '\n'
  1440. HU_queueChatChar((char)key_enter); // DEBUG!!! // phares
  1441. // send the macro message
  1442. while (*macromessage)
  1443. HU_queueChatChar(*macromessage++);
  1444. HU_queueChatChar((char)key_enter); // phares
  1445. // leave chat mode and notify that it was sent
  1446. chat_on = false;
  1447. strcpy(lastmessage, chat_macros[c]);
  1448. plr->message = lastmessage;
  1449. eatkey = true;
  1450. }
  1451. else
  1452. {
  1453. if (shiftdown || (c >= 'a' && c <= 'z'))
  1454. c = shiftxform[c];
  1455. eatkey = HUlib_keyInIText(&w_chat, c);
  1456. if (eatkey)
  1457. HU_queueChatChar(c);
  1458. if (c == key_enter) // phares
  1459. {
  1460. chat_on = false;
  1461. if (w_chat.l.len)
  1462. {
  1463. strcpy(lastmessage, w_chat.l.l);
  1464. plr->message = lastmessage;
  1465. }
  1466. }
  1467. else if (c == key_escape) // phares
  1468. chat_on = false;
  1469. }
  1470. }
  1471. return eatkey;
  1472. }