FS#12756 by Marek Salaba - update Czech translation
[maemo-rb.git] / apps / plugins / doom / hu_stuff.c
blob639c963f724a382c21e83b7e76cafa11d57dc940
1 /* Emacs style mode select -*- C++ -*-
2 *-----------------------------------------------------------------------------
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
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25 * 02111-1307, USA.
27 * DESCRIPTION: Heads-up displays
29 *-----------------------------------------------------------------------------
32 // 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 "m_swap.h"
46 // 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
55 // Locally used constants, shortcuts.
57 // Ty 03/28/98 -
58 // These four shortcuts modifed to reflect char ** of mapnamesx[]
59 #define HU_TITLE (*mapnames[(gameepisode-1)*9+gamemap-1])
60 #define HU_TITLE2 (*mapnames2[gamemap-1])
61 #define HU_TITLEP (*mapnamesp[gamemap-1])
62 #define HU_TITLET (*mapnamest[gamemap-1])
63 #define HU_TITLEHEIGHT 1
64 #define HU_TITLEX 0
65 //jff 2/16/98 change 167 to ST_Y-1
66 // CPhipps - changed to ST_TY
67 // proff - changed to 200-ST_HEIGHT for stretching
68 #define HU_TITLEY ((200-ST_HEIGHT) - 1 - SHORT(hu_font[0].height))
70 //jff 2/16/98 add coord text widget coordinates
71 // proff - changed to SCREENWIDTH to 320 for stretching
72 #define HU_COORDX (320 - 13*SHORT(hu_font2['A'-HU_FONTSTART].width))
73 //jff 3/3/98 split coord widget into three lines in upper right of screen
74 #define HU_COORDX_Y (1 + 0*SHORT(hu_font['A'-HU_FONTSTART].height))
75 #define HU_COORDY_Y (2 + 1*SHORT(hu_font['A'-HU_FONTSTART].height))
76 #define HU_COORDZ_Y (3 + 2*SHORT(hu_font['A'-HU_FONTSTART].height))
78 //jff 2/16/98 add ammo, health, armor widgets, 2/22/98 less gap
79 #define HU_GAPY 8
80 #define HU_HUDHEIGHT (6*HU_GAPY)
81 #define HU_HUDX 2
82 #define HU_HUDY (200-HU_HUDHEIGHT-1)
83 #define HU_MONSECX (HU_HUDX)
84 #define HU_MONSECY (HU_HUDY+0*HU_GAPY)
85 #define HU_KEYSX (HU_HUDX)
86 //jff 3/7/98 add offset for graphic key widget
87 #define HU_KEYSGX (HU_HUDX+4*SHORT(hu_font2['A'-HU_FONTSTART].width))
88 #define HU_KEYSY (HU_HUDY+1*HU_GAPY)
89 #define HU_WEAPX (HU_HUDX)
90 #define HU_WEAPY (HU_HUDY+2*HU_GAPY)
91 #define HU_AMMOX (HU_HUDX)
92 #define HU_AMMOY (HU_HUDY+3*HU_GAPY)
93 #define HU_HEALTHX (HU_HUDX)
94 #define HU_HEALTHY (HU_HUDY+4*HU_GAPY)
95 #define HU_ARMORX (HU_HUDX)
96 #define HU_ARMORY (HU_HUDY+5*HU_GAPY)
98 //jff 3/4/98 distributed HUD positions
99 #define HU_HUDX_LL 2
100 #define HU_HUDY_LL (200-2*HU_GAPY-1)
101 // proff/nicolas 09/20/98: Changed for high-res
102 #define HU_HUDX_LR (320-120)
103 #define HU_HUDY_LR (200-2*HU_GAPY-1)
104 // proff/nicolas 09/20/98: Changed for high-res
105 #define HU_HUDX_UR (320-96)
106 #define HU_HUDY_UR 2
107 #define HU_MONSECX_D (HU_HUDX_LL)
108 #define HU_MONSECY_D (HU_HUDY_LL+0*HU_GAPY)
109 #define HU_KEYSX_D (HU_HUDX_LL)
110 #define HU_KEYSGX_D (HU_HUDX_LL+4*SHORT(hu_font2['A'-HU_FONTSTART].width))
111 #define HU_KEYSY_D (HU_HUDY_LL+1*HU_GAPY)
112 #define HU_WEAPX_D (HU_HUDX_LR)
113 #define HU_WEAPY_D (HU_HUDY_LR+0*HU_GAPY)
114 #define HU_AMMOX_D (HU_HUDX_LR)
115 #define HU_AMMOY_D (HU_HUDY_LR+1*HU_GAPY)
116 #define HU_HEALTHX_D (HU_HUDX_UR)
117 #define HU_HEALTHY_D (HU_HUDY_UR+0*HU_GAPY)
118 #define HU_ARMORX_D (HU_HUDX_UR)
119 #define HU_ARMORY_D (HU_HUDY_UR+1*HU_GAPY)
121 //#define HU_INPUTTOGGLE 't' // not used // phares
122 #define HU_INPUTX HU_MSGX
123 #define HU_INPUTY (HU_MSGY + HU_MSGHEIGHT*(SHORT(hu_font[0].height) +1))
124 #define HU_INPUTWIDTH 64
125 #define HU_INPUTHEIGHT 1
127 #define key_alt KEY_RALT
128 #define key_shift KEY_RSHIFT
130 const char* chat_macros[] =
131 // Ty 03/27/98 - *not* externalized
132 // CPhipps - const char*
134 HUSTR_CHATMACRO1,
135 HUSTR_CHATMACRO1,
136 HUSTR_CHATMACRO1,
137 HUSTR_CHATMACRO1,
138 HUSTR_CHATMACRO1,
139 HUSTR_CHATMACRO1,
140 HUSTR_CHATMACRO1,
141 HUSTR_CHATMACRO1,
142 HUSTR_CHATMACRO1,
143 HUSTR_CHATMACRO1
146 const char* player_names[] =
147 // Ty 03/27/98 - *not* externalized
148 // CPhipps - const char*
150 HUSTR_PLRGREEN,
151 HUSTR_PLRINDIGO,
152 HUSTR_PLRBROWN,
153 HUSTR_PLRRED
156 //jff 3/17/98 translate player colmap to text color ranges
157 int plyrcoltran[MAXPLAYERS]={CR_GREEN,CR_GRAY,CR_BROWN,CR_RED};
159 char chat_char; // remove later.
160 static player_t* plr;
162 // font sets
163 patchnum_t hu_font[HU_FONTSIZE];
164 patchnum_t *hu_font2;
165 patchnum_t *hu_fontk;//jff 3/7/98 added for graphic key indicators
166 patchnum_t hu_msgbg[9]; //jff 2/26/98 add patches for message background
168 // widgets
169 static hu_textline_t w_title;
170 static hu_stext_t w_message;
171 static hu_itext_t w_chat;
172 static hu_itext_t w_inputbuffer[MAXPLAYERS];
173 static hu_textline_t w_coordx; //jff 2/16/98 new coord widget for automap
174 static hu_textline_t w_coordy; //jff 3/3/98 split coord widgets automap
175 static hu_textline_t w_coordz; //jff 3/3/98 split coord widgets automap
176 static hu_textline_t w_ammo; //jff 2/16/98 new ammo widget for hud
177 static hu_textline_t w_health; //jff 2/16/98 new health widget for hud
178 static hu_textline_t w_armor; //jff 2/16/98 new armor widget for hud
179 static hu_textline_t w_weapon; //jff 2/16/98 new weapon widget for hud
180 static hu_textline_t w_keys; //jff 2/16/98 new keys widget for hud
181 static hu_textline_t w_gkeys; //jff 3/7/98 graphic keys widget for hud
182 static hu_textline_t w_monsec; //jff 2/16/98 new kill/secret widget for hud
183 static hu_mtext_t w_rtext; //jff 2/26/98 text message refresh widget
185 static boolean always_off = false;
186 static char chat_dest[MAXPLAYERS];
187 boolean chat_on;
188 static boolean message_on;
189 static boolean message_list; //2/26/98 enable showing list of messages
190 boolean message_dontfuckwithme;
191 static boolean message_nottobefuckedwith;
192 static int message_counter;
193 extern int showMessages;
194 extern boolean automapactive;
195 static boolean headsupactive = false;
197 //jff 2/16/98 hud supported automap colors added
198 int hudcolor_titl; // color range of automap level title
199 int hudcolor_xyco; // color range of new coords on automap
200 //jff 2/16/98 hud text colors, controls added
201 int hudcolor_mesg; // color range of scrolling messages
202 int hudcolor_chat; // color range of chat lines
203 int hud_msg_lines; // number of message lines in window
204 //jff 2/26/98 hud text colors, controls added
205 int hudcolor_list; // list of messages color
206 int hud_list_bgon; // enable for solid window background for message list
208 //jff 2/16/98 initialization strings for ammo, health, armor widgets
209 static char *hud_coordstrx;
210 static char *hud_coordstry;
211 static char *hud_coordstrz;
212 static char *hud_ammostr;
213 static char *hud_healthstr;
214 static char *hud_armorstr;
215 static char *hud_weapstr;
216 static char *hud_keysstr;
217 static char *hud_gkeysstr; //jff 3/7/98 add support for graphic key display
218 static char *hud_monsecstr;
220 //jff 2/16/98 declaration of color switch points
221 extern int ammo_red;
222 extern int ammo_yellow;
223 extern int health_red;
224 extern int health_yellow;
225 extern int health_green;
226 extern int armor_red;
227 extern int armor_yellow;
228 extern int armor_green;
230 // key tables
231 // jff 5/10/98 french support removed,
232 // as it was not being used and couldn't be easily tested
234 const char* shiftxform;
236 const char english_shiftxform[] =
239 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
240 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
241 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
243 ' ', '!', '"', '#', '$', '%', '&',
244 '"', // shift-'
245 '(', ')', '*', '+',
246 '<', // shift-,
247 '_', // shift--
248 '>', // shift-.
249 '?', // shift-/
250 ')', // shift-0
251 '!', // shift-1
252 '@', // shift-2
253 '#', // shift-3
254 '$', // shift-4
255 '%', // shift-5
256 '^', // shift-6
257 '&', // shift-7
258 '*', // shift-8
259 '(', // shift-9
260 ':',
261 ':', // shift-;
262 '<',
263 '+', // shift-=
264 '>', '?', '@',
265 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
266 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
267 '[', // shift-[
268 '!', // shift-backslash - OH MY GOD DOES WATCOM SUCK
269 ']', // shift-]
270 '"', '_',
271 '\'', // shift-`
272 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
273 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
274 '{', '|', '}', '~', 127
278 // HU_Init()
280 // Initialize the heads-up display, text that overwrites the primary display
282 // Passed nothing, returns nothing
284 void HU_Init(void)
286 int i;
287 int j;
288 char buffer[9];
290 shiftxform = english_shiftxform;
292 // malloc all the strings, trying to get size down
293 hud_ammostr=malloc(80*sizeof(char));
294 hud_healthstr=malloc(80*sizeof(char));
295 hud_armorstr=malloc(80*sizeof(char));
296 hud_weapstr=malloc(80*sizeof(char));
297 hud_keysstr=malloc(80*sizeof(char));
298 hud_gkeysstr=malloc(80*sizeof(char));
299 hud_monsecstr=malloc(80*sizeof(char));
300 hud_coordstrx=malloc(32*sizeof(char));
301 hud_coordstry=malloc(32*sizeof(char));
302 hud_coordstrz=malloc(32*sizeof(char));
303 hu_fontk=malloc(HU_FONTSIZE*sizeof(patchnum_t));
304 hu_font2=malloc(HU_FONTSIZE*sizeof(patchnum_t));
306 // load the heads-up font
307 j = HU_FONTSTART;
308 for (i=0;i<HU_FONTSIZE;i++,j++)
310 if ('0'<=j && j<='9')
312 snprintf(buffer, sizeof(buffer), "DIG%d",j-48);
313 R_SetPatchNum(hu_font2 +i, buffer);
314 snprintf(buffer, sizeof(buffer), "STCFN%s%d", (j/10>0?"0":"00"), j); //NOTE ROCKHACK: "STCFN%.3d"
315 R_SetPatchNum(&hu_font[i], buffer);
317 else if ('A'<=j && j<='Z')
319 snprintf(buffer, sizeof(buffer), "DIG%c",j);
320 R_SetPatchNum(hu_font2 +i, buffer);
321 snprintf(buffer, sizeof(buffer), "STCFN%s%d", (j/10>0?"0":"00"), j); //NOTE ROCKHACK: "STCFN%.3d"
322 R_SetPatchNum(&hu_font[i], buffer);
324 else if (j=='-')
326 R_SetPatchNum(hu_font2 +i, "DIG45");
327 R_SetPatchNum(&hu_font[i], "STCFN045");
329 else if (j=='/')
331 R_SetPatchNum(hu_font2 +i, "DIG47");
332 R_SetPatchNum(&hu_font[i], "STCFN047");
334 else if (j==':')
336 R_SetPatchNum(hu_font2 +i, "DIG58");
337 R_SetPatchNum(&hu_font[i], "STCFN058");
339 else if (j=='[')
341 R_SetPatchNum(hu_font2 +i, "DIG91");
342 R_SetPatchNum(&hu_font[i], "STCFN091");
344 else if (j==']')
346 R_SetPatchNum(hu_font2 +i, "DIG93");
347 R_SetPatchNum(&hu_font[i], "STCFN093");
349 else if (j<97)
351 snprintf(buffer, sizeof(buffer), "STCFN%s%d", (j/10>0?"0":"00"), j); //NOTE ROCKHACK: "STCFN%.3d"
352 R_SetPatchNum(hu_font2 +i, buffer);
353 R_SetPatchNum(&hu_font[i], buffer);
354 //jff 2/23/98 make all font chars defined, useful or not
356 else if (j>122)
358 snprintf(buffer, sizeof(buffer), "STBR%d", j); //NOTE: "STBR%.3d"
359 R_SetPatchNum(hu_font2 +i, buffer);
360 R_SetPatchNum(&hu_font[i], buffer);
362 else
363 hu_font[i] = hu_font[0]; //jff 2/16/98 account for gap
366 // CPhipps - load patches for message background
367 for (i=0; i<9; i++) {
368 snprintf(buffer, sizeof(buffer), "BOX%c%c", "UCL"[i/3], "LCR"[i%3]);
369 R_SetPatchNum(&hu_msgbg[i], buffer);
372 // CPhipps - load patches for keys and double keys
373 for (i=0; i<6; i++) {
374 snprintf(buffer, sizeof(buffer), "STKEYS%d", i);
375 R_SetPatchNum(hu_fontk+i, buffer);
380 // HU_Stop()
382 // Make the heads-up displays inactive
384 // Passed nothing, returns nothing
386 void HU_Stop(void)
388 headsupactive = false;
392 // HU_Start(void)
394 // Create and initialize the heads-up widgets, software machines to
395 // maintain, update, and display information over the primary display
397 // This routine must be called after any change to the heads up configuration
398 // in order for the changes to take effect in the actual displays
400 // Passed nothing, returns nothing
402 void HU_Start(void)
405 int i;
406 const char* s; /* cph - const */
408 if (headsupactive) // stop before starting
409 HU_Stop();
411 plr = &players[displayplayer]; // killough 3/7/98
412 message_on = false;
413 message_dontfuckwithme = false;
414 message_nottobefuckedwith = false;
415 chat_on = false;
417 // create the message widget
418 // messages to player in upper-left of screen
419 HUlib_initSText
421 &w_message,
422 HU_MSGX,
423 HU_MSGY,
424 HU_MSGHEIGHT,
425 hu_font,
426 HU_FONTSTART,
427 hudcolor_mesg,
428 &message_on
431 //jff 2/16/98 added some HUD widgets
432 // create the map title widget - map title display in lower left of automap
433 HUlib_initTextLine
435 &w_title,
436 HU_TITLEX,
437 HU_TITLEY,
438 hu_font,
439 HU_FONTSTART,
440 hudcolor_titl
443 // create the hud health widget
444 // bargraph and number for amount of health,
445 // lower left or upper right of screen
446 HUlib_initTextLine
448 &w_health,
449 hud_distributed? HU_HEALTHX_D : HU_HEALTHX, //3/4/98 distribute
450 hud_distributed? HU_HEALTHY_D : HU_HEALTHY,
451 hu_font2,
452 HU_FONTSTART,
453 CR_GREEN
456 // create the hud armor widget
457 // bargraph and number for amount of armor,
458 // lower left or upper right of screen
459 HUlib_initTextLine
461 &w_armor,
462 hud_distributed? HU_ARMORX_D : HU_ARMORX, //3/4/98 distribute
463 hud_distributed? HU_ARMORY_D : HU_ARMORY,
464 hu_font2,
465 HU_FONTSTART,
466 CR_GREEN
469 // create the hud ammo widget
470 // bargraph and number for amount of ammo for current weapon,
471 // lower left or lower right of screen
472 HUlib_initTextLine
474 &w_ammo,
475 hud_distributed? HU_AMMOX_D : HU_AMMOX, //3/4/98 distribute
476 hud_distributed? HU_AMMOY_D : HU_AMMOY,
477 hu_font2,
478 HU_FONTSTART,
479 CR_GOLD
482 // create the hud weapons widget
483 // list of numbers of weapons possessed
484 // lower left or lower right of screen
485 HUlib_initTextLine
487 &w_weapon,
488 hud_distributed? HU_WEAPX_D : HU_WEAPX, //3/4/98 distribute
489 hud_distributed? HU_WEAPY_D : HU_WEAPY,
490 hu_font2,
491 HU_FONTSTART,
492 CR_GRAY
495 // create the hud keys widget
496 // display of key letters possessed
497 // lower left of screen
498 HUlib_initTextLine
500 &w_keys,
501 hud_distributed? HU_KEYSX_D : HU_KEYSX, //3/4/98 distribute
502 hud_distributed? HU_KEYSY_D : HU_KEYSY,
503 hu_font2,
504 HU_FONTSTART,
505 CR_GRAY
508 // create the hud graphic keys widget
509 // display of key graphics possessed
510 // lower left of screen
511 HUlib_initTextLine
513 &w_gkeys,
514 hud_distributed? HU_KEYSGX_D : HU_KEYSGX, //3/4/98 distribute
515 hud_distributed? HU_KEYSY_D : HU_KEYSY,
516 hu_fontk,
517 HU_FONTSTART,
518 CR_RED
521 // create the hud monster/secret widget
522 // totals and current values for kills, items, secrets
523 // lower left of screen
524 HUlib_initTextLine
526 &w_monsec,
527 hud_distributed? HU_MONSECX_D : HU_MONSECX, //3/4/98 distribute
528 hud_distributed? HU_MONSECY_D : HU_MONSECY,
529 hu_font2,
530 HU_FONTSTART,
531 CR_GRAY
534 // create the hud text refresh widget
535 // scrolling display of last hud_msg_lines messages received
536 if (hud_msg_lines>HU_MAXMESSAGES)
537 hud_msg_lines=HU_MAXMESSAGES;
538 //jff 4/21/98 if setup has disabled message list while active, turn it off
539 message_list = hud_msg_lines > 1; //jff 8/8/98 initialize both ways
540 //jff 2/26/98 add the text refresh widget initialization
541 HUlib_initMText
543 &w_rtext,
546 320,
547 // SCREENWIDTH,
548 (hud_msg_lines+2)*HU_REFRESHSPACING,
549 hu_font,
550 HU_FONTSTART,
551 hudcolor_list,
552 hu_msgbg,
553 &message_list
556 // initialize the automap's level title widget
557 if (gamestate == GS_LEVEL) /* cph - stop SEGV here when not in level */
558 switch (gamemode)
560 case shareware:
561 case registered:
562 case retail:
563 s = HU_TITLE;
564 break;
566 case commercial:
567 default: // Ty 08/27/98 - modified to check mission for TNT/Plutonia
568 s = (gamemission==pack_tnt) ? HU_TITLET :
569 (gamemission==pack_plut) ? HU_TITLEP : HU_TITLE2;
570 break;
571 } else s = "";
572 while (*s)
573 HUlib_addCharToTextLine(&w_title, *(s++));
575 // create the automaps coordinate widget
576 // jff 3/3/98 split coord widget into three lines: x,y,z
577 // jff 2/16/98 added
578 HUlib_initTextLine
580 &w_coordx,
581 HU_COORDX,
582 HU_COORDX_Y,
583 hu_font,
584 HU_FONTSTART,
585 hudcolor_xyco
587 HUlib_initTextLine
589 &w_coordy,
590 HU_COORDX,
591 HU_COORDY_Y,
592 hu_font,
593 HU_FONTSTART,
594 hudcolor_xyco
596 HUlib_initTextLine
598 &w_coordz,
599 HU_COORDX,
600 HU_COORDZ_Y,
601 hu_font,
602 HU_FONTSTART,
603 hudcolor_xyco
606 // initialize the automaps coordinate widget
607 //jff 3/3/98 split coordstr widget into 3 parts
608 snprintf(hud_coordstrx,32*sizeof(char),"X: %d",0); //jff 2/22/98 added z
609 s = hud_coordstrx;
610 while (*s)
611 HUlib_addCharToTextLine(&w_coordx, *(s++));
612 snprintf(hud_coordstry,32*sizeof(char),"Y: %d",0); //jff 3/3/98 split x,y,z
613 s = hud_coordstry;
614 while (*s)
615 HUlib_addCharToTextLine(&w_coordy, *(s++));
616 snprintf(hud_coordstrz,32*sizeof(char),"Z: %d",0); //jff 3/3/98 split x,y,z
617 s = hud_coordstrz;
618 while (*s)
619 HUlib_addCharToTextLine(&w_coordz, *(s++));
621 //jff 2/16/98 initialize ammo widget
622 strcpy(hud_ammostr,"AMM ");
623 s = hud_ammostr;
624 while (*s)
625 HUlib_addCharToTextLine(&w_ammo, *(s++));
627 //jff 2/16/98 initialize health widget
628 strcpy(hud_healthstr,"HEL ");
629 s = hud_healthstr;
630 while (*s)
631 HUlib_addCharToTextLine(&w_health, *(s++));
633 //jff 2/16/98 initialize armor widget
634 strcpy(hud_armorstr,"ARM ");
635 s = hud_armorstr;
636 while (*s)
637 HUlib_addCharToTextLine(&w_armor, *(s++));
639 //jff 2/17/98 initialize weapons widget
640 strcpy(hud_weapstr,"WEA ");
641 s = hud_weapstr;
642 while (*s)
643 HUlib_addCharToTextLine(&w_weapon, *(s++));
645 //jff 2/17/98 initialize keys widget
646 if (!deathmatch) //jff 3/17/98 show frags in deathmatch mode
647 strcpy(hud_keysstr,"KEY ");
648 else
649 strcpy(hud_keysstr,"FRG ");
650 s = hud_keysstr;
651 while (*s)
652 HUlib_addCharToTextLine(&w_keys, *(s++));
654 //jff 2/17/98 initialize graphic keys widget
655 strcpy(hud_gkeysstr," ");
656 s = hud_gkeysstr;
657 while (*s)
658 HUlib_addCharToTextLine(&w_gkeys, *(s++));
660 //jff 2/17/98 initialize kills/items/secret widget
661 strcpy(hud_monsecstr,"STS ");
662 s = hud_monsecstr;
663 while (*s)
664 HUlib_addCharToTextLine(&w_monsec, *(s++));
666 // create the chat widget
667 HUlib_initIText
669 &w_chat,
670 HU_INPUTX,
671 HU_INPUTY,
672 hu_font,
673 HU_FONTSTART,
674 hudcolor_chat,
675 &chat_on
678 // create the inputbuffer widgets, one per player
679 for (i=0 ; i<MAXPLAYERS ; i++)
680 HUlib_initIText
682 &w_inputbuffer[i],
687 hudcolor_chat,
688 &always_off
691 // now allow the heads-up display to run
692 headsupactive = true;
696 // HU_MoveHud()
698 // Move the HUD display from distributed to compact mode or vice-versa
700 // Passed nothing, returns nothing
702 //jff 3/9/98 create this externally callable to avoid glitch
703 // when menu scatter's HUD due to delay in change of position
705 void HU_MoveHud(void)
707 static int ohud_distributed=-1;
709 //jff 3/4/98 move displays around on F5 changing hud_distributed
710 if (hud_distributed!=ohud_distributed)
712 w_ammo.x = hud_distributed? HU_AMMOX_D : HU_AMMOX;
713 w_ammo.y = hud_distributed? HU_AMMOY_D : HU_AMMOY;
714 w_weapon.x = hud_distributed? HU_WEAPX_D : HU_WEAPX;
715 w_weapon.y = hud_distributed? HU_WEAPY_D : HU_WEAPY;
716 w_keys.x = hud_distributed? HU_KEYSX_D : HU_KEYSX;
717 w_keys.y = hud_distributed? HU_KEYSY_D : HU_KEYSY;
718 w_gkeys.x = hud_distributed? HU_KEYSGX_D : HU_KEYSGX;
719 w_gkeys.y = hud_distributed? HU_KEYSY_D : HU_KEYSY;
720 w_monsec.x = hud_distributed? HU_MONSECX_D : HU_MONSECX;
721 w_monsec.y = hud_distributed? HU_MONSECY_D : HU_MONSECY;
722 w_health.x = hud_distributed? HU_HEALTHX_D : HU_HEALTHX;
723 w_health.y = hud_distributed? HU_HEALTHY_D : HU_HEALTHY;
724 w_armor.x = hud_distributed? HU_ARMORX_D : HU_ARMORX;
725 w_armor.y = hud_distributed? HU_ARMORY_D : HU_ARMORY;
727 ohud_distributed = hud_distributed;
731 // HU_Drawer()
733 // Draw all the pieces of the heads-up display
735 // Passed nothing, returns nothing
737 void HU_Drawer(void)
739 char *s;
740 player_t *plr;
741 char ammostr[80]; //jff 3/8/98 allow plenty room for dehacked mods
742 char healthstr[80];//jff
743 char armorstr[80]; //jff
744 int i,doit;
746 plr = &players[displayplayer]; // killough 3/7/98
747 // draw the automap widgets if automap is displayed
748 if (automapmode & am_active)
750 // map title
751 HUlib_drawTextLine(&w_title, false);
753 //jff 2/16/98 output new coord display
754 // x-coord
755 snprintf(hud_coordstrx,32*sizeof(char),"X: %d", (plr->mo->x)>>FRACBITS);
756 HUlib_clearTextLine(&w_coordx);
757 s = hud_coordstrx;
758 while (*s)
759 HUlib_addCharToTextLine(&w_coordx, *(s++));
760 HUlib_drawTextLine(&w_coordx, false);
762 //jff 3/3/98 split coord display into x,y,z lines
763 // y-coord
764 snprintf(hud_coordstry,32*sizeof(char),"Y: %d", (plr->mo->y)>>FRACBITS);
765 HUlib_clearTextLine(&w_coordy);
766 s = hud_coordstry;
767 while (*s)
768 HUlib_addCharToTextLine(&w_coordy, *(s++));
769 HUlib_drawTextLine(&w_coordy, false);
771 //jff 3/3/98 split coord display into x,y,z lines
772 //jff 2/22/98 added z
773 // z-coord
774 snprintf(hud_coordstrz,32*sizeof(char),"Z: %d", (plr->mo->z)>>FRACBITS);
775 HUlib_clearTextLine(&w_coordz);
776 s = hud_coordstrz;
777 while (*s)
778 HUlib_addCharToTextLine(&w_coordz, *(s++));
779 HUlib_drawTextLine(&w_coordz, false);
782 // draw the weapon/health/ammo/armor/kills/keys displays if optioned
783 //jff 2/17/98 allow new hud stuff to be turned off
784 // killough 2/21/98: really allow new hud stuff to be turned off COMPLETELY
787 hud_active>0 && // hud optioned on
788 hud_displayed && // hud on from fullscreen key
789 viewheight==SCREENHEIGHT && // fullscreen mode is active
790 !(automapmode & am_active) // automap is not active
793 doit = !(gametic&1); //jff 3/4/98 speed update up for slow systems
794 if (doit) //jff 8/7/98 update every time, avoid lag in update
796 HU_MoveHud(); // insure HUD display coords are correct
798 // do the hud ammo display
799 // clear the widgets internal line
800 HUlib_clearTextLine(&w_ammo);
801 strcpy(hud_ammostr,"AMM ");
802 if (weaponinfo[plr->readyweapon].ammo == am_noammo)
803 { // special case for weapon with no ammo selected - blank bargraph + N/A
804 strcat(hud_ammostr,"\x7f\x7f\x7f\x7f\x7f\x7f\x7f N/A");
805 w_ammo.cm = CR_GRAY;
807 else
809 int ammo = plr->ammo[weaponinfo[plr->readyweapon].ammo];
810 int fullammo = plr->maxammo[weaponinfo[plr->readyweapon].ammo];
811 int ammopct = (100*ammo)/fullammo;
812 int ammobars = ammopct/4;
814 // build the numeric amount init string
815 snprintf(ammostr,sizeof(ammostr),"%d/%d",ammo,fullammo);
816 // build the bargraph string
817 // full bargraph chars
818 for (i=4;i<4+ammobars/4;)
819 hud_ammostr[i++] = 123;
820 // plus one last character with 0,1,2,3 bars
821 switch(ammobars%4)
823 case 0:
824 break;
825 case 1:
826 hud_ammostr[i++] = 126;
827 break;
828 case 2:
829 hud_ammostr[i++] = 125;
830 break;
831 case 3:
832 hud_ammostr[i++] = 124;
833 break;
835 // pad string with blank bar characters
836 while(i<4+7)
837 hud_ammostr[i++] = 127;
838 hud_ammostr[i] = '\0';
839 strcat(hud_ammostr,ammostr);
841 // set the display color from the percentage of total ammo held
842 if (ammopct<ammo_red)
843 w_ammo.cm = CR_RED;
844 else if (ammopct<ammo_yellow)
845 w_ammo.cm = CR_GOLD;
846 else
847 w_ammo.cm = CR_GREEN;
849 // transfer the init string to the widget
850 s = hud_ammostr;
851 while (*s)
852 HUlib_addCharToTextLine(&w_ammo, *(s++));
854 // display the ammo widget every frame
855 HUlib_drawTextLine(&w_ammo, false);
857 // do the hud health display
858 if (doit)
860 int health = plr->health;
861 int healthbars = health>100? 25 : health/4;
863 // clear the widgets internal line
864 HUlib_clearTextLine(&w_health);
866 // build the numeric amount init string
867 snprintf(healthstr,sizeof(healthstr),"%3d",health);
868 // build the bargraph string
869 // full bargraph chars
870 for (i=4;i<4+healthbars/4;)
871 hud_healthstr[i++] = 123;
872 // plus one last character with 0,1,2,3 bars
873 switch(healthbars%4)
875 case 0:
876 break;
877 case 1:
878 hud_healthstr[i++] = 126;
879 break;
880 case 2:
881 hud_healthstr[i++] = 125;
882 break;
883 case 3:
884 hud_healthstr[i++] = 124;
885 break;
887 // pad string with blank bar characters
888 while(i<4+7)
889 hud_healthstr[i++] = 127;
890 hud_healthstr[i] = '\0';
891 strcat(hud_healthstr,healthstr);
893 // set the display color from the amount of health posessed
894 if (health<health_red)
895 w_health.cm = CR_RED;
896 else if (health<health_yellow)
897 w_health.cm = CR_GOLD;
898 else if (health<=health_green)
899 w_health.cm = CR_GREEN;
900 else
901 w_health.cm = CR_BLUE;
903 // transfer the init string to the widget
904 s = hud_healthstr;
905 while (*s)
906 HUlib_addCharToTextLine(&w_health, *(s++));
908 // display the health widget every frame
909 HUlib_drawTextLine(&w_health, false);
911 // do the hud armor display
912 if (doit)
914 int armor = plr->armorpoints;
915 int armorbars = armor>100? 25 : armor/4;
917 // clear the widgets internal line
918 HUlib_clearTextLine(&w_armor);
919 // build the numeric amount init string
920 snprintf(armorstr,sizeof(armorstr),"%3d",armor);
921 // build the bargraph string
922 // full bargraph chars
923 for (i=4;i<4+armorbars/4;)
924 hud_armorstr[i++] = 123;
925 // plus one last character with 0,1,2,3 bars
926 switch(armorbars%4)
928 case 0:
929 break;
930 case 1:
931 hud_armorstr[i++] = 126;
932 break;
933 case 2:
934 hud_armorstr[i++] = 125;
935 break;
936 case 3:
937 hud_armorstr[i++] = 124;
938 break;
940 // pad string with blank bar characters
941 while(i<4+7)
942 hud_armorstr[i++] = 127;
943 hud_armorstr[i] = '\0';
944 strcat(hud_armorstr,armorstr);
946 // set the display color from the amount of armor posessed
947 if (armor<armor_red)
948 w_armor.cm = CR_RED;
949 else if (armor<armor_yellow)
950 w_armor.cm = CR_GOLD;
951 else if (armor<=armor_green)
952 w_armor.cm = CR_GREEN;
953 else
954 w_armor.cm = CR_BLUE;
956 // transfer the init string to the widget
957 s = hud_armorstr;
958 while (*s)
959 HUlib_addCharToTextLine(&w_armor, *(s++));
961 // display the armor widget every frame
962 HUlib_drawTextLine(&w_armor, false);
964 // do the hud weapon display
965 if (doit)
967 int w;
968 int ammo,fullammo,ammopct;
970 // clear the widgets internal line
971 HUlib_clearTextLine(&w_weapon);
972 i=4; hud_weapstr[i] = '\0'; //jff 3/7/98 make sure ammo goes away
974 // do each weapon that exists in current gamemode
975 for (w=0;w<=wp_supershotgun;w++) //jff 3/4/98 show fists too, why not?
977 int ok=1;
978 //jff avoid executing for weapons that do not exist
979 switch (gamemode)
981 case shareware:
982 if (w>=wp_plasma && w!=wp_chainsaw)
983 ok=0;
984 break;
985 case retail:
986 case registered:
987 if (w>=wp_supershotgun)
988 ok=0;
989 break;
990 default:
991 case commercial:
992 break;
994 if (!ok) continue;
996 ammo = plr->ammo[weaponinfo[w].ammo];
997 fullammo = plr->maxammo[weaponinfo[w].ammo];
998 ammopct=0;
1000 // skip weapons not currently posessed
1001 if (!plr->weaponowned[w])
1002 continue;
1004 ammopct = fullammo? (100*ammo)/fullammo : 100;
1006 // display each weapon number in a color related to the ammo for it
1007 hud_weapstr[i++] = '\x1b'; //jff 3/26/98 use ESC not '\' for paths
1008 if (weaponinfo[w].ammo==am_noammo) //jff 3/14/98 show berserk on HUD
1009 hud_weapstr[i++] = plr->powers[pw_strength]? '0'+CR_GREEN : '0'+CR_GRAY;
1010 else if (ammopct<ammo_red)
1011 hud_weapstr[i++] = '0'+CR_RED;
1012 else if (ammopct<ammo_yellow)
1013 hud_weapstr[i++] = '0'+CR_GOLD;
1014 else
1015 hud_weapstr[i++] = '0'+CR_GREEN;
1016 hud_weapstr[i++] = '0'+w+1;
1017 hud_weapstr[i++] = ' ';
1018 hud_weapstr[i] = '\0';
1021 // transfer the init string to the widget
1022 s = hud_weapstr;
1023 while (*s)
1024 HUlib_addCharToTextLine(&w_weapon, *(s++));
1026 // display the weapon widget every frame
1027 HUlib_drawTextLine(&w_weapon, false);
1029 if (doit && hud_active>1)
1031 int k;
1033 hud_keysstr[4] = '\0'; //jff 3/7/98 make sure deleted keys go away
1034 //jff add case for graphic key display
1035 if (!deathmatch && hud_graph_keys)
1037 i=0;
1038 hud_gkeysstr[i] = '\0'; //jff 3/7/98 init graphic keys widget string
1039 // build text string whose characters call out graphic keys from fontk
1040 for (k=0;k<6;k++)
1042 // skip keys not possessed
1043 if (!plr->cards[k])
1044 continue;
1046 hud_gkeysstr[i++] = '!'+k; // key number plus '!' is char for key
1047 hud_gkeysstr[i++] = ' '; // spacing
1048 hud_gkeysstr[i++] = ' ';
1050 hud_gkeysstr[i]='\0';
1052 else // not possible in current code, unless deathmatching,
1054 i=4;
1055 hud_keysstr[i] = '\0'; //jff 3/7/98 make sure deleted keys go away
1057 // if deathmatch, build string showing top four frag counts
1058 if (deathmatch) //jff 3/17/98 show frags, not keys, in deathmatch
1060 int top1=-999,top2=-999,top3=-999,top4=-999;
1061 int idx1=-1,idx2=-1,idx3=-1,idx4=-1;
1062 int fragcount,m;
1063 char numbuf[32];
1065 // scan thru players
1066 for (k=0;k<MAXPLAYERS;k++)
1068 // skip players not in game
1069 if (!playeringame[k])
1070 continue;
1072 fragcount = 0;
1073 // compute number of times they've fragged each player
1074 // minus number of times they've been fragged by them
1075 for (m=0;m<MAXPLAYERS;m++)
1077 if (!playeringame[m]) continue;
1078 fragcount += (m!=k)? players[k].frags[m] : -players[k].frags[m];
1081 // very primitive sort of frags to find top four
1082 if (fragcount>top1)
1084 top4=top3; top3=top2; top2 = top1; top1=fragcount;
1085 idx4=idx3; idx3=idx2; idx2 = idx1; idx1=k;
1087 else if (fragcount>top2)
1089 top4=top3; top3=top2; top2=fragcount;
1090 idx4=idx3; idx3=idx2; idx2=k;
1092 else if (fragcount>top3)
1094 top4=top3; top3=fragcount;
1095 idx4=idx3; idx3=k;
1097 else if (fragcount>top4)
1099 top4=fragcount;
1100 idx4=k;
1103 // if the biggest number exists, put it in the init string
1104 if (idx1>-1)
1106 snprintf(numbuf,sizeof(numbuf),"%5d",top1);
1107 // make frag count in player's color via escape code
1108 hud_keysstr[i++] = '\x1b'; //jff 3/26/98 use ESC not '\' for paths
1109 hud_keysstr[i++] = '0'+plyrcoltran[idx1&3];
1110 s = numbuf;
1111 while (*s)
1112 hud_keysstr[i++] = *(s++);
1114 // if the second biggest number exists, put it in the init string
1115 if (idx2>-1)
1117 snprintf(numbuf,sizeof(numbuf),"%5d",top2);
1118 // make frag count in player's color via escape code
1119 hud_keysstr[i++] = '\x1b'; //jff 3/26/98 use ESC not '\' for paths
1120 hud_keysstr[i++] = '0'+plyrcoltran[idx2&3];
1121 s = numbuf;
1122 while (*s)
1123 hud_keysstr[i++] = *(s++);
1125 // if the third biggest number exists, put it in the init string
1126 if (idx3>-1)
1128 snprintf(numbuf,sizeof(numbuf),"%5d",top3);
1129 // make frag count in player's color via escape code
1130 hud_keysstr[i++] = '\x1b'; //jff 3/26/98 use ESC not '\' for paths
1131 hud_keysstr[i++] = '0'+plyrcoltran[idx3&3];
1132 s = numbuf;
1133 while (*s)
1134 hud_keysstr[i++] = *(s++);
1136 // if the fourth biggest number exists, put it in the init string
1137 if (idx4>-1)
1139 snprintf(numbuf,sizeof(numbuf),"%5d",top4);
1140 // make frag count in player's color via escape code
1141 hud_keysstr[i++] = '\x1b'; //jff 3/26/98 use ESC not '\' for paths
1142 hud_keysstr[i++] = '0'+plyrcoltran[idx4&3];
1143 s = numbuf;
1144 while (*s)
1145 hud_keysstr[i++] = *(s++);
1147 hud_keysstr[i] = '\0';
1148 } //jff 3/17/98 end of deathmatch clause
1149 else // build alphabetical key display (not used currently)
1151 // scan the keys
1152 for (k=0;k<6;k++)
1154 // skip any not possessed by the displayed player's stats
1155 if (!plr->cards[k])
1156 continue;
1158 // use color escapes to make text in key's color
1159 hud_keysstr[i++] = '\x1b'; //jff 3/26/98 use ESC not '\' for paths
1160 switch(k)
1162 case 0:
1163 hud_keysstr[i++] = '0'+CR_BLUE;
1164 hud_keysstr[i++] = 'B';
1165 hud_keysstr[i++] = 'C';
1166 hud_keysstr[i++] = ' ';
1167 break;
1168 case 1:
1169 hud_keysstr[i++] = '0'+CR_GOLD;
1170 hud_keysstr[i++] = 'Y';
1171 hud_keysstr[i++] = 'C';
1172 hud_keysstr[i++] = ' ';
1173 break;
1174 case 2:
1175 hud_keysstr[i++] = '0'+CR_RED;
1176 hud_keysstr[i++] = 'R';
1177 hud_keysstr[i++] = 'C';
1178 hud_keysstr[i++] = ' ';
1179 break;
1180 case 3:
1181 hud_keysstr[i++] = '0'+CR_BLUE;
1182 hud_keysstr[i++] = 'B';
1183 hud_keysstr[i++] = 'S';
1184 hud_keysstr[i++] = ' ';
1185 break;
1186 case 4:
1187 hud_keysstr[i++] = '0'+CR_GOLD;
1188 hud_keysstr[i++] = 'Y';
1189 hud_keysstr[i++] = 'S';
1190 hud_keysstr[i++] = ' ';
1191 break;
1192 case 5:
1193 hud_keysstr[i++] = '0'+CR_RED;
1194 hud_keysstr[i++] = 'R';
1195 hud_keysstr[i++] = 'S';
1196 hud_keysstr[i++] = ' ';
1197 break;
1199 hud_keysstr[i]='\0';
1204 // display the keys/frags line each frame
1205 if (hud_active>1)
1207 HUlib_clearTextLine(&w_keys); // clear the widget strings
1208 HUlib_clearTextLine(&w_gkeys);
1210 // transfer the built string (frags or key title) to the widget
1211 s = hud_keysstr; //jff 3/7/98 display key titles/key text or frags
1212 while (*s)
1213 HUlib_addCharToTextLine(&w_keys, *(s++));
1214 HUlib_drawTextLine(&w_keys, false);
1216 //jff 3/17/98 show graphic keys in non-DM only
1217 if (!deathmatch) //jff 3/7/98 display graphic keys
1219 // transfer the graphic key text to the widget
1220 s = hud_gkeysstr;
1221 while (*s)
1222 HUlib_addCharToTextLine(&w_gkeys, *(s++));
1223 // display the widget
1224 HUlib_drawTextLine(&w_gkeys, false);
1228 // display the hud kills/items/secret display if optioned
1229 if (!hud_nosecrets)
1231 if (hud_active>1 && doit)
1233 // clear the internal widget text buffer
1234 HUlib_clearTextLine(&w_monsec);
1235 //jff 3/26/98 use ESC not '\' for paths
1236 // build the init string with fixed colors
1237 snprintf
1239 hud_monsecstr,80*sizeof(char),
1240 "STS \x1b\x36K \x1b\x33%d \x1b\x36M \x1b\x33%d \x1b\x37I \x1b\x33%d/%d \x1b\x35S \x1b\x33%d/%d",
1241 plr->killcount,totallive,
1242 plr->itemcount,totalitems,
1243 plr->secretcount,totalsecret
1245 // transfer the init string to the widget
1246 s = hud_monsecstr;
1247 while (*s)
1248 HUlib_addCharToTextLine(&w_monsec, *(s++));
1250 // display the kills/items/secrets each frame, if optioned
1251 if (hud_active>1)
1252 HUlib_drawTextLine(&w_monsec, false);
1256 //jff 3/4/98 display last to give priority
1257 HU_Erase(); // jff 4/24/98 Erase current lines before drawing current
1258 // needed when screen not fullsize
1260 //jff 4/21/98 if setup has disabled message list while active, turn it off
1261 if (hud_msg_lines<=1)
1262 message_list = false;
1264 // if the message review not enabled, show the standard message widget
1265 if (!message_list)
1266 HUlib_drawSText(&w_message);
1268 // if the message review is enabled show the scrolling message review
1269 if (hud_msg_lines>1 && message_list)
1270 HUlib_drawMText(&w_rtext);
1272 // display the interactive buffer for chat entry
1273 HUlib_drawIText(&w_chat);
1277 // HU_Erase()
1279 // Erase hud display lines that can be trashed by small screen display
1281 // Passed nothing, returns nothing
1283 void HU_Erase(void)
1285 // erase the message display or the message review display
1286 if (!message_list)
1287 HUlib_eraseSText(&w_message);
1288 else
1289 HUlib_eraseMText(&w_rtext);
1291 // erase the interactive text buffer for chat entry
1292 HUlib_eraseIText(&w_chat);
1294 // erase the automap title
1295 HUlib_eraseTextLine(&w_title);
1299 // HU_Ticker()
1301 // Update the hud displays once per frame
1303 // Passed nothing, returns nothing
1305 static boolean bsdown; // Is backspace down?
1306 static int bscounter;
1308 void HU_Ticker(void)
1310 int i, rc;
1311 char c;
1313 // tick down message counter if message is up
1314 if (message_counter && !--message_counter)
1316 message_on = false;
1317 message_nottobefuckedwith = false;
1319 if (bsdown && bscounter++ > 9) {
1320 HUlib_keyInIText(&w_chat, (unsigned char)key_backspace);
1321 bscounter = 8;
1324 // if messages on, or "Messages Off" is being displayed
1325 // this allows the notification of turning messages off to be seen
1326 if (showMessages || message_dontfuckwithme)
1328 // display message if necessary
1329 if ((plr->message && !message_nottobefuckedwith)
1330 || (plr->message && message_dontfuckwithme))
1332 //post the message to the message widget
1333 HUlib_addMessageToSText(&w_message, 0, plr->message);
1334 //jff 2/26/98 add message to refresh text widget too
1335 HUlib_addMessageToMText(&w_rtext, 0, plr->message);
1337 // clear the message to avoid posting multiple times
1338 plr->message = 0;
1339 // note a message is displayed
1340 message_on = true;
1341 // start the message persistence counter
1342 message_counter = HU_MSGTIMEOUT;
1343 // transfer "Messages Off" exception to the "being displayed" variable
1344 message_nottobefuckedwith = message_dontfuckwithme;
1345 // clear the flag that "Messages Off" is being posted
1346 message_dontfuckwithme = 0;
1350 // check for incoming chat characters
1351 if (netgame)
1353 for (i=0; i<MAXPLAYERS; i++)
1355 if (!playeringame[i])
1356 continue;
1357 if (i != consoleplayer
1358 && (c = players[i].cmd.chatchar))
1360 if (c <= HU_BROADCAST)
1361 chat_dest[i] = c;
1362 else
1364 if (c >= 'a' && c <= 'z')
1365 c = (char) shiftxform[(unsigned char) c];
1366 rc = HUlib_keyInIText(&w_inputbuffer[i], c);
1367 if (rc && c == KEY_ENTER)
1369 if (w_inputbuffer[i].l.len
1370 && (chat_dest[i] == consoleplayer+1
1371 || chat_dest[i] == HU_BROADCAST))
1373 HUlib_addMessageToSText(&w_message,
1374 player_names[i],
1375 w_inputbuffer[i].l.l);
1377 message_nottobefuckedwith = true;
1378 message_on = true;
1379 message_counter = HU_MSGTIMEOUT;
1380 if ( gamemode == commercial )
1381 S_StartSound(0, sfx_radio);
1382 else
1383 S_StartSound(0, sfx_tink);
1385 HUlib_resetIText(&w_inputbuffer[i]);
1388 players[i].cmd.chatchar = 0;
1394 #define QUEUESIZE 128
1396 static char chatchars[QUEUESIZE];
1397 static int head = 0;
1398 static int tail = 0;
1401 // HU_queueChatChar()
1403 // Add an incoming character to the circular chat queue
1405 // Passed the character to queue, returns nothing
1407 void HU_queueChatChar(char c)
1409 if (((head + 1) & (QUEUESIZE-1)) == tail)
1411 plr->message = HUSTR_MSGU;
1413 else
1415 chatchars[head] = c;
1416 head = (head + 1) & (QUEUESIZE-1);
1421 // HU_dequeueChatChar()
1423 // Remove the earliest added character from the circular chat queue
1425 // Passed nothing, returns the character dequeued
1427 char HU_dequeueChatChar(void)
1429 char c;
1431 if (head != tail)
1433 c = chatchars[tail];
1434 tail = (tail + 1) & (QUEUESIZE-1);
1436 else
1438 c = 0;
1440 return c;
1444 // HU_Responder()
1446 // Responds to input events that affect the heads up displays
1448 // Passed the event to respond to, returns true if the event was handled
1450 boolean HU_Responder(event_t *ev)
1453 static char lastmessage[HU_MAXLINELENGTH+1];
1454 const char* macromessage; // CPhipps - const char*
1455 boolean eatkey = false;
1456 static boolean shiftdown = false;
1457 static boolean altdown = false;
1458 unsigned char c;
1459 int i;
1460 int numplayers;
1462 static int num_nobrainers = 0;
1464 numplayers = 0;
1465 for (i=0 ; i<MAXPLAYERS ; i++)
1466 numplayers += playeringame[i];
1468 if (ev->data1 == key_shift)
1470 shiftdown = ev->type == ev_keydown;
1471 return false;
1473 else if (ev->data1 == key_alt)
1475 altdown = ev->type == ev_keydown;
1476 return false;
1478 else if (ev->data1 == key_backspace)
1480 bsdown = ev->type == ev_keydown;
1481 bscounter = 0;
1484 if (ev->type != ev_keydown)
1485 return false;
1487 if (!chat_on)
1489 if (ev->data1 == key_enter) // phares
1491 #ifndef INSTRUMENTED // never turn on message review if INSTRUMENTED defined
1492 if (hud_msg_lines>1) // it posts multi-line messages that will trash
1494 if (message_list) HU_Erase(); //jff 4/28/98 erase behind messages
1495 message_list = !message_list; //jff 2/26/98 toggle list of messages
1497 #endif
1498 if (!message_list) // if not message list, refresh message
1500 message_on = true;
1501 message_counter = HU_MSGTIMEOUT;
1503 eatkey = true;
1504 }//jff 2/26/98 no chat if message review is displayed
1505 else if (!message_list && netgame && ev->data1 == key_chat)
1507 eatkey = chat_on = true;
1508 HUlib_resetIText(&w_chat);
1509 HU_queueChatChar(HU_BROADCAST);
1510 }//jff 2/26/98 no chat if message review is displayed
1511 // killough 10/02/98: no chat if demo playback
1512 else if (!demoplayback && !message_list && netgame && numplayers > 2)
1514 for (i=0; i<MAXPLAYERS ; i++)
1516 if (ev->data1 == destination_keys[i])
1518 if (playeringame[i] && i!=consoleplayer)
1520 eatkey = chat_on = true;
1521 HUlib_resetIText(&w_chat);
1522 HU_queueChatChar((char)(i+1));
1523 break;
1525 else if (i == consoleplayer)
1527 num_nobrainers++;
1528 if (num_nobrainers < 3)
1529 plr->message = HUSTR_TALKTOSELF1;
1530 else if (num_nobrainers < 6)
1531 plr->message = HUSTR_TALKTOSELF2;
1532 else if (num_nobrainers < 9)
1533 plr->message = HUSTR_TALKTOSELF3;
1534 else if (num_nobrainers < 32)
1535 plr->message = HUSTR_TALKTOSELF4;
1536 else
1537 plr->message = HUSTR_TALKTOSELF5;
1542 }//jff 2/26/98 no chat functions if message review is displayed
1543 else if (!message_list)
1545 c = ev->data1;
1546 // send a macro
1547 if (altdown)
1549 c = c - '0';
1550 if (c > 9)
1551 return false;
1552 macromessage = chat_macros[c];
1554 // kill last message with a '\n'
1555 HU_queueChatChar((char)key_enter); // DEBUG!!! // phares
1557 // send the macro message
1558 while (*macromessage)
1559 HU_queueChatChar(*macromessage++);
1560 HU_queueChatChar((char)key_enter); // phares
1562 // leave chat mode and notify that it was sent
1563 chat_on = false;
1564 strcpy(lastmessage, chat_macros[c]);
1565 plr->message = lastmessage;
1566 eatkey = true;
1568 else
1570 if (shiftdown || (c >= 'a' && c <= 'z'))
1571 c = shiftxform[c];
1572 eatkey = HUlib_keyInIText(&w_chat, c);
1573 if (eatkey)
1574 HU_queueChatChar(c);
1576 if (c == key_enter) // phares
1578 chat_on = false;
1579 if (w_chat.l.len)
1581 strcpy(lastmessage, w_chat.l.l);
1582 plr->message = lastmessage;
1585 else if (c == key_escape) // phares
1586 chat_on = false;
1589 return eatkey;