Rearange menu of mpegplayer. Add new menu with "settings" and "quit", and remove...
[kugel-rb.git] / apps / plugins / doom / hu_stuff.c
blob5361435fd5a29680ac6a20c13a1fd713cc0ab944
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;
231 // Builtin map names.
232 // The actual names can be found in DStrings.h.
234 // Ty 03/27/98 - externalized map name arrays - now in d_deh.c
235 // and converted to arrays of pointers to char *
236 // See modified HUTITLEx macros
237 extern char **mapnames[];
238 extern char **mapnames2[];
239 extern char **mapnamesp[];
240 extern char **mapnamest[];
242 // key tables
243 // jff 5/10/98 french support removed,
244 // as it was not being used and couldn't be easily tested
246 const char* shiftxform;
248 const char english_shiftxform[] =
251 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
252 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
253 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
255 ' ', '!', '"', '#', '$', '%', '&',
256 '"', // shift-'
257 '(', ')', '*', '+',
258 '<', // shift-,
259 '_', // shift--
260 '>', // shift-.
261 '?', // shift-/
262 ')', // shift-0
263 '!', // shift-1
264 '@', // shift-2
265 '#', // shift-3
266 '$', // shift-4
267 '%', // shift-5
268 '^', // shift-6
269 '&', // shift-7
270 '*', // shift-8
271 '(', // shift-9
272 ':',
273 ':', // shift-;
274 '<',
275 '+', // shift-=
276 '>', '?', '@',
277 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
278 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
279 '[', // shift-[
280 '!', // shift-backslash - OH MY GOD DOES WATCOM SUCK
281 ']', // shift-]
282 '"', '_',
283 '\'', // shift-`
284 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
285 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
286 '{', '|', '}', '~', 127
290 // HU_Init()
292 // Initialize the heads-up display, text that overwrites the primary display
294 // Passed nothing, returns nothing
296 void HU_Init(void)
298 int i;
299 int j;
300 char buffer[9];
302 shiftxform = english_shiftxform;
304 // malloc all the strings, trying to get size down
305 hud_ammostr=malloc(80*sizeof(char));
306 hud_healthstr=malloc(80*sizeof(char));
307 hud_armorstr=malloc(80*sizeof(char));
308 hud_weapstr=malloc(80*sizeof(char));
309 hud_keysstr=malloc(80*sizeof(char));
310 hud_gkeysstr=malloc(80*sizeof(char));
311 hud_monsecstr=malloc(80*sizeof(char));
312 hud_coordstrx=malloc(32*sizeof(char));
313 hud_coordstry=malloc(32*sizeof(char));
314 hud_coordstrz=malloc(32*sizeof(char));
315 hu_fontk=malloc(HU_FONTSIZE*sizeof(patchnum_t));
316 hu_font2=malloc(HU_FONTSIZE*sizeof(patchnum_t));
318 // load the heads-up font
319 j = HU_FONTSTART;
320 for (i=0;i<HU_FONTSIZE;i++,j++)
322 if ('0'<=j && j<='9')
324 snprintf(buffer, sizeof(buffer), "DIG%d",j-48);
325 R_SetPatchNum(hu_font2 +i, buffer);
326 snprintf(buffer, sizeof(buffer), "STCFN%s%d", (j/10>0?"0":"00"), j); //NOTE ROCKHACK: "STCFN%.3d"
327 R_SetPatchNum(&hu_font[i], buffer);
329 else if ('A'<=j && j<='Z')
331 snprintf(buffer, sizeof(buffer), "DIG%c",j);
332 R_SetPatchNum(hu_font2 +i, buffer);
333 snprintf(buffer, sizeof(buffer), "STCFN%s%d", (j/10>0?"0":"00"), j); //NOTE ROCKHACK: "STCFN%.3d"
334 R_SetPatchNum(&hu_font[i], buffer);
336 else if (j=='-')
338 R_SetPatchNum(hu_font2 +i, "DIG45");
339 R_SetPatchNum(&hu_font[i], "STCFN045");
341 else if (j=='/')
343 R_SetPatchNum(hu_font2 +i, "DIG47");
344 R_SetPatchNum(&hu_font[i], "STCFN047");
346 else if (j==':')
348 R_SetPatchNum(hu_font2 +i, "DIG58");
349 R_SetPatchNum(&hu_font[i], "STCFN058");
351 else if (j=='[')
353 R_SetPatchNum(hu_font2 +i, "DIG91");
354 R_SetPatchNum(&hu_font[i], "STCFN091");
356 else if (j==']')
358 R_SetPatchNum(hu_font2 +i, "DIG93");
359 R_SetPatchNum(&hu_font[i], "STCFN093");
361 else if (j<97)
363 snprintf(buffer, sizeof(buffer), "STCFN%s%d", (j/10>0?"0":"00"), j); //NOTE ROCKHACK: "STCFN%.3d"
364 R_SetPatchNum(hu_font2 +i, buffer);
365 R_SetPatchNum(&hu_font[i], buffer);
366 //jff 2/23/98 make all font chars defined, useful or not
368 else if (j>122)
370 snprintf(buffer, sizeof(buffer), "STBR%d", j); //NOTE: "STBR%.3d"
371 R_SetPatchNum(hu_font2 +i, buffer);
372 R_SetPatchNum(&hu_font[i], buffer);
374 else
375 hu_font[i] = hu_font[0]; //jff 2/16/98 account for gap
378 // CPhipps - load patches for message background
379 for (i=0; i<9; i++) {
380 snprintf(buffer, sizeof(buffer), "BOX%c%c", "UCL"[i/3], "LCR"[i%3]);
381 R_SetPatchNum(&hu_msgbg[i], buffer);
384 // CPhipps - load patches for keys and double keys
385 for (i=0; i<6; i++) {
386 snprintf(buffer, sizeof(buffer), "STKEYS%d", i);
387 R_SetPatchNum(hu_fontk+i, buffer);
392 // HU_Stop()
394 // Make the heads-up displays inactive
396 // Passed nothing, returns nothing
398 void HU_Stop(void)
400 headsupactive = false;
404 // HU_Start(void)
406 // Create and initialize the heads-up widgets, software machines to
407 // maintain, update, and display information over the primary display
409 // This routine must be called after any change to the heads up configuration
410 // in order for the changes to take effect in the actual displays
412 // Passed nothing, returns nothing
414 void HU_Start(void)
417 int i;
418 const char* s; /* cph - const */
420 if (headsupactive) // stop before starting
421 HU_Stop();
423 plr = &players[displayplayer]; // killough 3/7/98
424 message_on = false;
425 message_dontfuckwithme = false;
426 message_nottobefuckedwith = false;
427 chat_on = false;
429 // create the message widget
430 // messages to player in upper-left of screen
431 HUlib_initSText
433 &w_message,
434 HU_MSGX,
435 HU_MSGY,
436 HU_MSGHEIGHT,
437 hu_font,
438 HU_FONTSTART,
439 hudcolor_mesg,
440 &message_on
443 //jff 2/16/98 added some HUD widgets
444 // create the map title widget - map title display in lower left of automap
445 HUlib_initTextLine
447 &w_title,
448 HU_TITLEX,
449 HU_TITLEY,
450 hu_font,
451 HU_FONTSTART,
452 hudcolor_titl
455 // create the hud health widget
456 // bargraph and number for amount of health,
457 // lower left or upper right of screen
458 HUlib_initTextLine
460 &w_health,
461 hud_distributed? HU_HEALTHX_D : HU_HEALTHX, //3/4/98 distribute
462 hud_distributed? HU_HEALTHY_D : HU_HEALTHY,
463 hu_font2,
464 HU_FONTSTART,
465 CR_GREEN
468 // create the hud armor widget
469 // bargraph and number for amount of armor,
470 // lower left or upper right of screen
471 HUlib_initTextLine
473 &w_armor,
474 hud_distributed? HU_ARMORX_D : HU_ARMORX, //3/4/98 distribute
475 hud_distributed? HU_ARMORY_D : HU_ARMORY,
476 hu_font2,
477 HU_FONTSTART,
478 CR_GREEN
481 // create the hud ammo widget
482 // bargraph and number for amount of ammo for current weapon,
483 // lower left or lower right of screen
484 HUlib_initTextLine
486 &w_ammo,
487 hud_distributed? HU_AMMOX_D : HU_AMMOX, //3/4/98 distribute
488 hud_distributed? HU_AMMOY_D : HU_AMMOY,
489 hu_font2,
490 HU_FONTSTART,
491 CR_GOLD
494 // create the hud weapons widget
495 // list of numbers of weapons possessed
496 // lower left or lower right of screen
497 HUlib_initTextLine
499 &w_weapon,
500 hud_distributed? HU_WEAPX_D : HU_WEAPX, //3/4/98 distribute
501 hud_distributed? HU_WEAPY_D : HU_WEAPY,
502 hu_font2,
503 HU_FONTSTART,
504 CR_GRAY
507 // create the hud keys widget
508 // display of key letters possessed
509 // lower left of screen
510 HUlib_initTextLine
512 &w_keys,
513 hud_distributed? HU_KEYSX_D : HU_KEYSX, //3/4/98 distribute
514 hud_distributed? HU_KEYSY_D : HU_KEYSY,
515 hu_font2,
516 HU_FONTSTART,
517 CR_GRAY
520 // create the hud graphic keys widget
521 // display of key graphics possessed
522 // lower left of screen
523 HUlib_initTextLine
525 &w_gkeys,
526 hud_distributed? HU_KEYSGX_D : HU_KEYSGX, //3/4/98 distribute
527 hud_distributed? HU_KEYSY_D : HU_KEYSY,
528 hu_fontk,
529 HU_FONTSTART,
530 CR_RED
533 // create the hud monster/secret widget
534 // totals and current values for kills, items, secrets
535 // lower left of screen
536 HUlib_initTextLine
538 &w_monsec,
539 hud_distributed? HU_MONSECX_D : HU_MONSECX, //3/4/98 distribute
540 hud_distributed? HU_MONSECY_D : HU_MONSECY,
541 hu_font2,
542 HU_FONTSTART,
543 CR_GRAY
546 // create the hud text refresh widget
547 // scrolling display of last hud_msg_lines messages received
548 if (hud_msg_lines>HU_MAXMESSAGES)
549 hud_msg_lines=HU_MAXMESSAGES;
550 //jff 4/21/98 if setup has disabled message list while active, turn it off
551 message_list = hud_msg_lines > 1; //jff 8/8/98 initialize both ways
552 //jff 2/26/98 add the text refresh widget initialization
553 HUlib_initMText
555 &w_rtext,
558 320,
559 // SCREENWIDTH,
560 (hud_msg_lines+2)*HU_REFRESHSPACING,
561 hu_font,
562 HU_FONTSTART,
563 hudcolor_list,
564 hu_msgbg,
565 &message_list
568 // initialize the automap's level title widget
569 if (gamestate == GS_LEVEL) /* cph - stop SEGV here when not in level */
570 switch (gamemode)
572 case shareware:
573 case registered:
574 case retail:
575 s = HU_TITLE;
576 break;
578 case commercial:
579 default: // Ty 08/27/98 - modified to check mission for TNT/Plutonia
580 s = (gamemission==pack_tnt) ? HU_TITLET :
581 (gamemission==pack_plut) ? HU_TITLEP : HU_TITLE2;
582 break;
583 } else s = "";
584 while (*s)
585 HUlib_addCharToTextLine(&w_title, *(s++));
587 // create the automaps coordinate widget
588 // jff 3/3/98 split coord widget into three lines: x,y,z
589 // jff 2/16/98 added
590 HUlib_initTextLine
592 &w_coordx,
593 HU_COORDX,
594 HU_COORDX_Y,
595 hu_font,
596 HU_FONTSTART,
597 hudcolor_xyco
599 HUlib_initTextLine
601 &w_coordy,
602 HU_COORDX,
603 HU_COORDY_Y,
604 hu_font,
605 HU_FONTSTART,
606 hudcolor_xyco
608 HUlib_initTextLine
610 &w_coordz,
611 HU_COORDX,
612 HU_COORDZ_Y,
613 hu_font,
614 HU_FONTSTART,
615 hudcolor_xyco
618 // initialize the automaps coordinate widget
619 //jff 3/3/98 split coordstr widget into 3 parts
620 snprintf(hud_coordstrx,32*sizeof(char),"X: %d",0); //jff 2/22/98 added z
621 s = hud_coordstrx;
622 while (*s)
623 HUlib_addCharToTextLine(&w_coordx, *(s++));
624 snprintf(hud_coordstry,32*sizeof(char),"Y: %d",0); //jff 3/3/98 split x,y,z
625 s = hud_coordstry;
626 while (*s)
627 HUlib_addCharToTextLine(&w_coordy, *(s++));
628 snprintf(hud_coordstrz,32*sizeof(char),"Z: %d",0); //jff 3/3/98 split x,y,z
629 s = hud_coordstrz;
630 while (*s)
631 HUlib_addCharToTextLine(&w_coordz, *(s++));
633 //jff 2/16/98 initialize ammo widget
634 strcpy(hud_ammostr,"AMM ");
635 s = hud_ammostr;
636 while (*s)
637 HUlib_addCharToTextLine(&w_ammo, *(s++));
639 //jff 2/16/98 initialize health widget
640 strcpy(hud_healthstr,"HEL ");
641 s = hud_healthstr;
642 while (*s)
643 HUlib_addCharToTextLine(&w_health, *(s++));
645 //jff 2/16/98 initialize armor widget
646 strcpy(hud_armorstr,"ARM ");
647 s = hud_armorstr;
648 while (*s)
649 HUlib_addCharToTextLine(&w_armor, *(s++));
651 //jff 2/17/98 initialize weapons widget
652 strcpy(hud_weapstr,"WEA ");
653 s = hud_weapstr;
654 while (*s)
655 HUlib_addCharToTextLine(&w_weapon, *(s++));
657 //jff 2/17/98 initialize keys widget
658 if (!deathmatch) //jff 3/17/98 show frags in deathmatch mode
659 strcpy(hud_keysstr,"KEY ");
660 else
661 strcpy(hud_keysstr,"FRG ");
662 s = hud_keysstr;
663 while (*s)
664 HUlib_addCharToTextLine(&w_keys, *(s++));
666 //jff 2/17/98 initialize graphic keys widget
667 strcpy(hud_gkeysstr," ");
668 s = hud_gkeysstr;
669 while (*s)
670 HUlib_addCharToTextLine(&w_gkeys, *(s++));
672 //jff 2/17/98 initialize kills/items/secret widget
673 strcpy(hud_monsecstr,"STS ");
674 s = hud_monsecstr;
675 while (*s)
676 HUlib_addCharToTextLine(&w_monsec, *(s++));
678 // create the chat widget
679 HUlib_initIText
681 &w_chat,
682 HU_INPUTX,
683 HU_INPUTY,
684 hu_font,
685 HU_FONTSTART,
686 hudcolor_chat,
687 &chat_on
690 // create the inputbuffer widgets, one per player
691 for (i=0 ; i<MAXPLAYERS ; i++)
692 HUlib_initIText
694 &w_inputbuffer[i],
699 hudcolor_chat,
700 &always_off
703 // now allow the heads-up display to run
704 headsupactive = true;
708 // HU_MoveHud()
710 // Move the HUD display from distributed to compact mode or vice-versa
712 // Passed nothing, returns nothing
714 //jff 3/9/98 create this externally callable to avoid glitch
715 // when menu scatter's HUD due to delay in change of position
717 void HU_MoveHud(void)
719 static int ohud_distributed=-1;
721 //jff 3/4/98 move displays around on F5 changing hud_distributed
722 if (hud_distributed!=ohud_distributed)
724 w_ammo.x = hud_distributed? HU_AMMOX_D : HU_AMMOX;
725 w_ammo.y = hud_distributed? HU_AMMOY_D : HU_AMMOY;
726 w_weapon.x = hud_distributed? HU_WEAPX_D : HU_WEAPX;
727 w_weapon.y = hud_distributed? HU_WEAPY_D : HU_WEAPY;
728 w_keys.x = hud_distributed? HU_KEYSX_D : HU_KEYSX;
729 w_keys.y = hud_distributed? HU_KEYSY_D : HU_KEYSY;
730 w_gkeys.x = hud_distributed? HU_KEYSGX_D : HU_KEYSGX;
731 w_gkeys.y = hud_distributed? HU_KEYSY_D : HU_KEYSY;
732 w_monsec.x = hud_distributed? HU_MONSECX_D : HU_MONSECX;
733 w_monsec.y = hud_distributed? HU_MONSECY_D : HU_MONSECY;
734 w_health.x = hud_distributed? HU_HEALTHX_D : HU_HEALTHX;
735 w_health.y = hud_distributed? HU_HEALTHY_D : HU_HEALTHY;
736 w_armor.x = hud_distributed? HU_ARMORX_D : HU_ARMORX;
737 w_armor.y = hud_distributed? HU_ARMORY_D : HU_ARMORY;
739 ohud_distributed = hud_distributed;
743 // HU_Drawer()
745 // Draw all the pieces of the heads-up display
747 // Passed nothing, returns nothing
749 void HU_Drawer(void)
751 char *s;
752 player_t *plr;
753 char ammostr[80]; //jff 3/8/98 allow plenty room for dehacked mods
754 char healthstr[80];//jff
755 char armorstr[80]; //jff
756 int i,doit;
758 plr = &players[displayplayer]; // killough 3/7/98
759 // draw the automap widgets if automap is displayed
760 if (automapmode & am_active)
762 // map title
763 HUlib_drawTextLine(&w_title, false);
765 //jff 2/16/98 output new coord display
766 // x-coord
767 snprintf(hud_coordstrx,32*sizeof(char),"X: %d", (plr->mo->x)>>FRACBITS);
768 HUlib_clearTextLine(&w_coordx);
769 s = hud_coordstrx;
770 while (*s)
771 HUlib_addCharToTextLine(&w_coordx, *(s++));
772 HUlib_drawTextLine(&w_coordx, false);
774 //jff 3/3/98 split coord display into x,y,z lines
775 // y-coord
776 snprintf(hud_coordstry,32*sizeof(char),"Y: %d", (plr->mo->y)>>FRACBITS);
777 HUlib_clearTextLine(&w_coordy);
778 s = hud_coordstry;
779 while (*s)
780 HUlib_addCharToTextLine(&w_coordy, *(s++));
781 HUlib_drawTextLine(&w_coordy, false);
783 //jff 3/3/98 split coord display into x,y,z lines
784 //jff 2/22/98 added z
785 // z-coord
786 snprintf(hud_coordstrz,32*sizeof(char),"Z: %d", (plr->mo->z)>>FRACBITS);
787 HUlib_clearTextLine(&w_coordz);
788 s = hud_coordstrz;
789 while (*s)
790 HUlib_addCharToTextLine(&w_coordz, *(s++));
791 HUlib_drawTextLine(&w_coordz, false);
794 // draw the weapon/health/ammo/armor/kills/keys displays if optioned
795 //jff 2/17/98 allow new hud stuff to be turned off
796 // killough 2/21/98: really allow new hud stuff to be turned off COMPLETELY
799 hud_active>0 && // hud optioned on
800 hud_displayed && // hud on from fullscreen key
801 viewheight==SCREENHEIGHT && // fullscreen mode is active
802 !(automapmode & am_active) // automap is not active
805 doit = !(gametic&1); //jff 3/4/98 speed update up for slow systems
806 if (doit) //jff 8/7/98 update every time, avoid lag in update
808 HU_MoveHud(); // insure HUD display coords are correct
810 // do the hud ammo display
811 // clear the widgets internal line
812 HUlib_clearTextLine(&w_ammo);
813 strcpy(hud_ammostr,"AMM ");
814 if (weaponinfo[plr->readyweapon].ammo == am_noammo)
815 { // special case for weapon with no ammo selected - blank bargraph + N/A
816 strcat(hud_ammostr,"\x7f\x7f\x7f\x7f\x7f\x7f\x7f N/A");
817 w_ammo.cm = CR_GRAY;
819 else
821 int ammo = plr->ammo[weaponinfo[plr->readyweapon].ammo];
822 int fullammo = plr->maxammo[weaponinfo[plr->readyweapon].ammo];
823 int ammopct = (100*ammo)/fullammo;
824 int ammobars = ammopct/4;
826 // build the numeric amount init string
827 snprintf(ammostr,sizeof(ammostr),"%d/%d",ammo,fullammo);
828 // build the bargraph string
829 // full bargraph chars
830 for (i=4;i<4+ammobars/4;)
831 hud_ammostr[i++] = 123;
832 // plus one last character with 0,1,2,3 bars
833 switch(ammobars%4)
835 case 0:
836 break;
837 case 1:
838 hud_ammostr[i++] = 126;
839 break;
840 case 2:
841 hud_ammostr[i++] = 125;
842 break;
843 case 3:
844 hud_ammostr[i++] = 124;
845 break;
847 // pad string with blank bar characters
848 while(i<4+7)
849 hud_ammostr[i++] = 127;
850 hud_ammostr[i] = '\0';
851 strcat(hud_ammostr,ammostr);
853 // set the display color from the percentage of total ammo held
854 if (ammopct<ammo_red)
855 w_ammo.cm = CR_RED;
856 else if (ammopct<ammo_yellow)
857 w_ammo.cm = CR_GOLD;
858 else
859 w_ammo.cm = CR_GREEN;
861 // transfer the init string to the widget
862 s = hud_ammostr;
863 while (*s)
864 HUlib_addCharToTextLine(&w_ammo, *(s++));
866 // display the ammo widget every frame
867 HUlib_drawTextLine(&w_ammo, false);
869 // do the hud health display
870 if (doit)
872 int health = plr->health;
873 int healthbars = health>100? 25 : health/4;
875 // clear the widgets internal line
876 HUlib_clearTextLine(&w_health);
878 // build the numeric amount init string
879 snprintf(healthstr,sizeof(healthstr),"%3d",health);
880 // build the bargraph string
881 // full bargraph chars
882 for (i=4;i<4+healthbars/4;)
883 hud_healthstr[i++] = 123;
884 // plus one last character with 0,1,2,3 bars
885 switch(healthbars%4)
887 case 0:
888 break;
889 case 1:
890 hud_healthstr[i++] = 126;
891 break;
892 case 2:
893 hud_healthstr[i++] = 125;
894 break;
895 case 3:
896 hud_healthstr[i++] = 124;
897 break;
899 // pad string with blank bar characters
900 while(i<4+7)
901 hud_healthstr[i++] = 127;
902 hud_healthstr[i] = '\0';
903 strcat(hud_healthstr,healthstr);
905 // set the display color from the amount of health posessed
906 if (health<health_red)
907 w_health.cm = CR_RED;
908 else if (health<health_yellow)
909 w_health.cm = CR_GOLD;
910 else if (health<=health_green)
911 w_health.cm = CR_GREEN;
912 else
913 w_health.cm = CR_BLUE;
915 // transfer the init string to the widget
916 s = hud_healthstr;
917 while (*s)
918 HUlib_addCharToTextLine(&w_health, *(s++));
920 // display the health widget every frame
921 HUlib_drawTextLine(&w_health, false);
923 // do the hud armor display
924 if (doit)
926 int armor = plr->armorpoints;
927 int armorbars = armor>100? 25 : armor/4;
929 // clear the widgets internal line
930 HUlib_clearTextLine(&w_armor);
931 // build the numeric amount init string
932 snprintf(armorstr,sizeof(armorstr),"%3d",armor);
933 // build the bargraph string
934 // full bargraph chars
935 for (i=4;i<4+armorbars/4;)
936 hud_armorstr[i++] = 123;
937 // plus one last character with 0,1,2,3 bars
938 switch(armorbars%4)
940 case 0:
941 break;
942 case 1:
943 hud_armorstr[i++] = 126;
944 break;
945 case 2:
946 hud_armorstr[i++] = 125;
947 break;
948 case 3:
949 hud_armorstr[i++] = 124;
950 break;
952 // pad string with blank bar characters
953 while(i<4+7)
954 hud_armorstr[i++] = 127;
955 hud_armorstr[i] = '\0';
956 strcat(hud_armorstr,armorstr);
958 // set the display color from the amount of armor posessed
959 if (armor<armor_red)
960 w_armor.cm = CR_RED;
961 else if (armor<armor_yellow)
962 w_armor.cm = CR_GOLD;
963 else if (armor<=armor_green)
964 w_armor.cm = CR_GREEN;
965 else
966 w_armor.cm = CR_BLUE;
968 // transfer the init string to the widget
969 s = hud_armorstr;
970 while (*s)
971 HUlib_addCharToTextLine(&w_armor, *(s++));
973 // display the armor widget every frame
974 HUlib_drawTextLine(&w_armor, false);
976 // do the hud weapon display
977 if (doit)
979 int w;
980 int ammo,fullammo,ammopct;
982 // clear the widgets internal line
983 HUlib_clearTextLine(&w_weapon);
984 i=4; hud_weapstr[i] = '\0'; //jff 3/7/98 make sure ammo goes away
986 // do each weapon that exists in current gamemode
987 for (w=0;w<=wp_supershotgun;w++) //jff 3/4/98 show fists too, why not?
989 int ok=1;
990 //jff avoid executing for weapons that do not exist
991 switch (gamemode)
993 case shareware:
994 if (w>=wp_plasma && w!=wp_chainsaw)
995 ok=0;
996 break;
997 case retail:
998 case registered:
999 if (w>=wp_supershotgun)
1000 ok=0;
1001 break;
1002 default:
1003 case commercial:
1004 break;
1006 if (!ok) continue;
1008 ammo = plr->ammo[weaponinfo[w].ammo];
1009 fullammo = plr->maxammo[weaponinfo[w].ammo];
1010 ammopct=0;
1012 // skip weapons not currently posessed
1013 if (!plr->weaponowned[w])
1014 continue;
1016 ammopct = fullammo? (100*ammo)/fullammo : 100;
1018 // display each weapon number in a color related to the ammo for it
1019 hud_weapstr[i++] = '\x1b'; //jff 3/26/98 use ESC not '\' for paths
1020 if (weaponinfo[w].ammo==am_noammo) //jff 3/14/98 show berserk on HUD
1021 hud_weapstr[i++] = plr->powers[pw_strength]? '0'+CR_GREEN : '0'+CR_GRAY;
1022 else if (ammopct<ammo_red)
1023 hud_weapstr[i++] = '0'+CR_RED;
1024 else if (ammopct<ammo_yellow)
1025 hud_weapstr[i++] = '0'+CR_GOLD;
1026 else
1027 hud_weapstr[i++] = '0'+CR_GREEN;
1028 hud_weapstr[i++] = '0'+w+1;
1029 hud_weapstr[i++] = ' ';
1030 hud_weapstr[i] = '\0';
1033 // transfer the init string to the widget
1034 s = hud_weapstr;
1035 while (*s)
1036 HUlib_addCharToTextLine(&w_weapon, *(s++));
1038 // display the weapon widget every frame
1039 HUlib_drawTextLine(&w_weapon, false);
1041 if (doit && hud_active>1)
1043 int k;
1045 hud_keysstr[4] = '\0'; //jff 3/7/98 make sure deleted keys go away
1046 //jff add case for graphic key display
1047 if (!deathmatch && hud_graph_keys)
1049 i=0;
1050 hud_gkeysstr[i] = '\0'; //jff 3/7/98 init graphic keys widget string
1051 // build text string whose characters call out graphic keys from fontk
1052 for (k=0;k<6;k++)
1054 // skip keys not possessed
1055 if (!plr->cards[k])
1056 continue;
1058 hud_gkeysstr[i++] = '!'+k; // key number plus '!' is char for key
1059 hud_gkeysstr[i++] = ' '; // spacing
1060 hud_gkeysstr[i++] = ' ';
1062 hud_gkeysstr[i]='\0';
1064 else // not possible in current code, unless deathmatching,
1066 i=4;
1067 hud_keysstr[i] = '\0'; //jff 3/7/98 make sure deleted keys go away
1069 // if deathmatch, build string showing top four frag counts
1070 if (deathmatch) //jff 3/17/98 show frags, not keys, in deathmatch
1072 int top1=-999,top2=-999,top3=-999,top4=-999;
1073 int idx1=-1,idx2=-1,idx3=-1,idx4=-1;
1074 int fragcount,m;
1075 char numbuf[32];
1077 // scan thru players
1078 for (k=0;k<MAXPLAYERS;k++)
1080 // skip players not in game
1081 if (!playeringame[k])
1082 continue;
1084 fragcount = 0;
1085 // compute number of times they've fragged each player
1086 // minus number of times they've been fragged by them
1087 for (m=0;m<MAXPLAYERS;m++)
1089 if (!playeringame[m]) continue;
1090 fragcount += (m!=k)? players[k].frags[m] : -players[k].frags[m];
1093 // very primitive sort of frags to find top four
1094 if (fragcount>top1)
1096 top4=top3; top3=top2; top2 = top1; top1=fragcount;
1097 idx4=idx3; idx3=idx2; idx2 = idx1; idx1=k;
1099 else if (fragcount>top2)
1101 top4=top3; top3=top2; top2=fragcount;
1102 idx4=idx3; idx3=idx2; idx2=k;
1104 else if (fragcount>top3)
1106 top4=top3; top3=fragcount;
1107 idx4=idx3; idx3=k;
1109 else if (fragcount>top4)
1111 top4=fragcount;
1112 idx4=k;
1115 // if the biggest number exists, put it in the init string
1116 if (idx1>-1)
1118 snprintf(numbuf,sizeof(numbuf),"%5d",top1);
1119 // make frag count in player's color via escape code
1120 hud_keysstr[i++] = '\x1b'; //jff 3/26/98 use ESC not '\' for paths
1121 hud_keysstr[i++] = '0'+plyrcoltran[idx1&3];
1122 s = numbuf;
1123 while (*s)
1124 hud_keysstr[i++] = *(s++);
1126 // if the second biggest number exists, put it in the init string
1127 if (idx2>-1)
1129 snprintf(numbuf,sizeof(numbuf),"%5d",top2);
1130 // make frag count in player's color via escape code
1131 hud_keysstr[i++] = '\x1b'; //jff 3/26/98 use ESC not '\' for paths
1132 hud_keysstr[i++] = '0'+plyrcoltran[idx2&3];
1133 s = numbuf;
1134 while (*s)
1135 hud_keysstr[i++] = *(s++);
1137 // if the third biggest number exists, put it in the init string
1138 if (idx3>-1)
1140 snprintf(numbuf,sizeof(numbuf),"%5d",top3);
1141 // make frag count in player's color via escape code
1142 hud_keysstr[i++] = '\x1b'; //jff 3/26/98 use ESC not '\' for paths
1143 hud_keysstr[i++] = '0'+plyrcoltran[idx3&3];
1144 s = numbuf;
1145 while (*s)
1146 hud_keysstr[i++] = *(s++);
1148 // if the fourth biggest number exists, put it in the init string
1149 if (idx4>-1)
1151 snprintf(numbuf,sizeof(numbuf),"%5d",top4);
1152 // make frag count in player's color via escape code
1153 hud_keysstr[i++] = '\x1b'; //jff 3/26/98 use ESC not '\' for paths
1154 hud_keysstr[i++] = '0'+plyrcoltran[idx4&3];
1155 s = numbuf;
1156 while (*s)
1157 hud_keysstr[i++] = *(s++);
1159 hud_keysstr[i] = '\0';
1160 } //jff 3/17/98 end of deathmatch clause
1161 else // build alphabetical key display (not used currently)
1163 // scan the keys
1164 for (k=0;k<6;k++)
1166 // skip any not possessed by the displayed player's stats
1167 if (!plr->cards[k])
1168 continue;
1170 // use color escapes to make text in key's color
1171 hud_keysstr[i++] = '\x1b'; //jff 3/26/98 use ESC not '\' for paths
1172 switch(k)
1174 case 0:
1175 hud_keysstr[i++] = '0'+CR_BLUE;
1176 hud_keysstr[i++] = 'B';
1177 hud_keysstr[i++] = 'C';
1178 hud_keysstr[i++] = ' ';
1179 break;
1180 case 1:
1181 hud_keysstr[i++] = '0'+CR_GOLD;
1182 hud_keysstr[i++] = 'Y';
1183 hud_keysstr[i++] = 'C';
1184 hud_keysstr[i++] = ' ';
1185 break;
1186 case 2:
1187 hud_keysstr[i++] = '0'+CR_RED;
1188 hud_keysstr[i++] = 'R';
1189 hud_keysstr[i++] = 'C';
1190 hud_keysstr[i++] = ' ';
1191 break;
1192 case 3:
1193 hud_keysstr[i++] = '0'+CR_BLUE;
1194 hud_keysstr[i++] = 'B';
1195 hud_keysstr[i++] = 'S';
1196 hud_keysstr[i++] = ' ';
1197 break;
1198 case 4:
1199 hud_keysstr[i++] = '0'+CR_GOLD;
1200 hud_keysstr[i++] = 'Y';
1201 hud_keysstr[i++] = 'S';
1202 hud_keysstr[i++] = ' ';
1203 break;
1204 case 5:
1205 hud_keysstr[i++] = '0'+CR_RED;
1206 hud_keysstr[i++] = 'R';
1207 hud_keysstr[i++] = 'S';
1208 hud_keysstr[i++] = ' ';
1209 break;
1211 hud_keysstr[i]='\0';
1216 // display the keys/frags line each frame
1217 if (hud_active>1)
1219 HUlib_clearTextLine(&w_keys); // clear the widget strings
1220 HUlib_clearTextLine(&w_gkeys);
1222 // transfer the built string (frags or key title) to the widget
1223 s = hud_keysstr; //jff 3/7/98 display key titles/key text or frags
1224 while (*s)
1225 HUlib_addCharToTextLine(&w_keys, *(s++));
1226 HUlib_drawTextLine(&w_keys, false);
1228 //jff 3/17/98 show graphic keys in non-DM only
1229 if (!deathmatch) //jff 3/7/98 display graphic keys
1231 // transfer the graphic key text to the widget
1232 s = hud_gkeysstr;
1233 while (*s)
1234 HUlib_addCharToTextLine(&w_gkeys, *(s++));
1235 // display the widget
1236 HUlib_drawTextLine(&w_gkeys, false);
1240 // display the hud kills/items/secret display if optioned
1241 if (!hud_nosecrets)
1243 if (hud_active>1 && doit)
1245 // clear the internal widget text buffer
1246 HUlib_clearTextLine(&w_monsec);
1247 //jff 3/26/98 use ESC not '\' for paths
1248 // build the init string with fixed colors
1249 snprintf
1251 hud_monsecstr,80*sizeof(char),
1252 "STS \x1b\x36K \x1b\x33%d \x1b\x36M \x1b\x33%d \x1b\x37I \x1b\x33%d/%d \x1b\x35S \x1b\x33%d/%d",
1253 plr->killcount,totallive,
1254 plr->itemcount,totalitems,
1255 plr->secretcount,totalsecret
1257 // transfer the init string to the widget
1258 s = hud_monsecstr;
1259 while (*s)
1260 HUlib_addCharToTextLine(&w_monsec, *(s++));
1262 // display the kills/items/secrets each frame, if optioned
1263 if (hud_active>1)
1264 HUlib_drawTextLine(&w_monsec, false);
1268 //jff 3/4/98 display last to give priority
1269 HU_Erase(); // jff 4/24/98 Erase current lines before drawing current
1270 // needed when screen not fullsize
1272 //jff 4/21/98 if setup has disabled message list while active, turn it off
1273 if (hud_msg_lines<=1)
1274 message_list = false;
1276 // if the message review not enabled, show the standard message widget
1277 if (!message_list)
1278 HUlib_drawSText(&w_message);
1280 // if the message review is enabled show the scrolling message review
1281 if (hud_msg_lines>1 && message_list)
1282 HUlib_drawMText(&w_rtext);
1284 // display the interactive buffer for chat entry
1285 HUlib_drawIText(&w_chat);
1289 // HU_Erase()
1291 // Erase hud display lines that can be trashed by small screen display
1293 // Passed nothing, returns nothing
1295 void HU_Erase(void)
1297 // erase the message display or the message review display
1298 if (!message_list)
1299 HUlib_eraseSText(&w_message);
1300 else
1301 HUlib_eraseMText(&w_rtext);
1303 // erase the interactive text buffer for chat entry
1304 HUlib_eraseIText(&w_chat);
1306 // erase the automap title
1307 HUlib_eraseTextLine(&w_title);
1311 // HU_Ticker()
1313 // Update the hud displays once per frame
1315 // Passed nothing, returns nothing
1317 static boolean bsdown; // Is backspace down?
1318 static int bscounter;
1320 void HU_Ticker(void)
1322 int i, rc;
1323 char c;
1325 // tick down message counter if message is up
1326 if (message_counter && !--message_counter)
1328 message_on = false;
1329 message_nottobefuckedwith = false;
1331 if (bsdown && bscounter++ > 9) {
1332 HUlib_keyInIText(&w_chat, (unsigned char)key_backspace);
1333 bscounter = 8;
1336 // if messages on, or "Messages Off" is being displayed
1337 // this allows the notification of turning messages off to be seen
1338 if (showMessages || message_dontfuckwithme)
1340 // display message if necessary
1341 if ((plr->message && !message_nottobefuckedwith)
1342 || (plr->message && message_dontfuckwithme))
1344 //post the message to the message widget
1345 HUlib_addMessageToSText(&w_message, 0, plr->message);
1346 //jff 2/26/98 add message to refresh text widget too
1347 HUlib_addMessageToMText(&w_rtext, 0, plr->message);
1349 // clear the message to avoid posting multiple times
1350 plr->message = 0;
1351 // note a message is displayed
1352 message_on = true;
1353 // start the message persistence counter
1354 message_counter = HU_MSGTIMEOUT;
1355 // transfer "Messages Off" exception to the "being displayed" variable
1356 message_nottobefuckedwith = message_dontfuckwithme;
1357 // clear the flag that "Messages Off" is being posted
1358 message_dontfuckwithme = 0;
1362 // check for incoming chat characters
1363 if (netgame)
1365 for (i=0; i<MAXPLAYERS; i++)
1367 if (!playeringame[i])
1368 continue;
1369 if (i != consoleplayer
1370 && (c = players[i].cmd.chatchar))
1372 if (c <= HU_BROADCAST)
1373 chat_dest[i] = c;
1374 else
1376 if (c >= 'a' && c <= 'z')
1377 c = (char) shiftxform[(unsigned char) c];
1378 rc = HUlib_keyInIText(&w_inputbuffer[i], c);
1379 if (rc && c == KEY_ENTER)
1381 if (w_inputbuffer[i].l.len
1382 && (chat_dest[i] == consoleplayer+1
1383 || chat_dest[i] == HU_BROADCAST))
1385 HUlib_addMessageToSText(&w_message,
1386 player_names[i],
1387 w_inputbuffer[i].l.l);
1389 message_nottobefuckedwith = true;
1390 message_on = true;
1391 message_counter = HU_MSGTIMEOUT;
1392 if ( gamemode == commercial )
1393 S_StartSound(0, sfx_radio);
1394 else
1395 S_StartSound(0, sfx_tink);
1397 HUlib_resetIText(&w_inputbuffer[i]);
1400 players[i].cmd.chatchar = 0;
1406 #define QUEUESIZE 128
1408 static char chatchars[QUEUESIZE];
1409 static int head = 0;
1410 static int tail = 0;
1413 // HU_queueChatChar()
1415 // Add an incoming character to the circular chat queue
1417 // Passed the character to queue, returns nothing
1419 void HU_queueChatChar(char c)
1421 if (((head + 1) & (QUEUESIZE-1)) == tail)
1423 plr->message = HUSTR_MSGU;
1425 else
1427 chatchars[head] = c;
1428 head = (head + 1) & (QUEUESIZE-1);
1433 // HU_dequeueChatChar()
1435 // Remove the earliest added character from the circular chat queue
1437 // Passed nothing, returns the character dequeued
1439 char HU_dequeueChatChar(void)
1441 char c;
1443 if (head != tail)
1445 c = chatchars[tail];
1446 tail = (tail + 1) & (QUEUESIZE-1);
1448 else
1450 c = 0;
1452 return c;
1456 // HU_Responder()
1458 // Responds to input events that affect the heads up displays
1460 // Passed the event to respond to, returns true if the event was handled
1462 boolean HU_Responder(event_t *ev)
1465 static char lastmessage[HU_MAXLINELENGTH+1];
1466 const char* macromessage; // CPhipps - const char*
1467 boolean eatkey = false;
1468 static boolean shiftdown = false;
1469 static boolean altdown = false;
1470 unsigned char c;
1471 int i;
1472 int numplayers;
1474 static int num_nobrainers = 0;
1476 numplayers = 0;
1477 for (i=0 ; i<MAXPLAYERS ; i++)
1478 numplayers += playeringame[i];
1480 if (ev->data1 == key_shift)
1482 shiftdown = ev->type == ev_keydown;
1483 return false;
1485 else if (ev->data1 == key_alt)
1487 altdown = ev->type == ev_keydown;
1488 return false;
1490 else if (ev->data1 == key_backspace)
1492 bsdown = ev->type == ev_keydown;
1493 bscounter = 0;
1496 if (ev->type != ev_keydown)
1497 return false;
1499 if (!chat_on)
1501 if (ev->data1 == key_enter) // phares
1503 #ifndef INSTRUMENTED // never turn on message review if INSTRUMENTED defined
1504 if (hud_msg_lines>1) // it posts multi-line messages that will trash
1506 if (message_list) HU_Erase(); //jff 4/28/98 erase behind messages
1507 message_list = !message_list; //jff 2/26/98 toggle list of messages
1509 #endif
1510 if (!message_list) // if not message list, refresh message
1512 message_on = true;
1513 message_counter = HU_MSGTIMEOUT;
1515 eatkey = true;
1516 }//jff 2/26/98 no chat if message review is displayed
1517 else if (!message_list && netgame && ev->data1 == key_chat)
1519 eatkey = chat_on = true;
1520 HUlib_resetIText(&w_chat);
1521 HU_queueChatChar(HU_BROADCAST);
1522 }//jff 2/26/98 no chat if message review is displayed
1523 // killough 10/02/98: no chat if demo playback
1524 else if (!demoplayback && !message_list && netgame && numplayers > 2)
1526 for (i=0; i<MAXPLAYERS ; i++)
1528 if (ev->data1 == destination_keys[i])
1530 if (playeringame[i] && i!=consoleplayer)
1532 eatkey = chat_on = true;
1533 HUlib_resetIText(&w_chat);
1534 HU_queueChatChar((char)(i+1));
1535 break;
1537 else if (i == consoleplayer)
1539 num_nobrainers++;
1540 if (num_nobrainers < 3)
1541 plr->message = HUSTR_TALKTOSELF1;
1542 else if (num_nobrainers < 6)
1543 plr->message = HUSTR_TALKTOSELF2;
1544 else if (num_nobrainers < 9)
1545 plr->message = HUSTR_TALKTOSELF3;
1546 else if (num_nobrainers < 32)
1547 plr->message = HUSTR_TALKTOSELF4;
1548 else
1549 plr->message = HUSTR_TALKTOSELF5;
1554 }//jff 2/26/98 no chat functions if message review is displayed
1555 else if (!message_list)
1557 c = ev->data1;
1558 // send a macro
1559 if (altdown)
1561 c = c - '0';
1562 if (c > 9)
1563 return false;
1564 macromessage = chat_macros[c];
1566 // kill last message with a '\n'
1567 HU_queueChatChar((char)key_enter); // DEBUG!!! // phares
1569 // send the macro message
1570 while (*macromessage)
1571 HU_queueChatChar(*macromessage++);
1572 HU_queueChatChar((char)key_enter); // phares
1574 // leave chat mode and notify that it was sent
1575 chat_on = false;
1576 strcpy(lastmessage, chat_macros[c]);
1577 plr->message = lastmessage;
1578 eatkey = true;
1580 else
1582 if (shiftdown || (c >= 'a' && c <= 'z'))
1583 c = shiftxform[c];
1584 eatkey = HUlib_keyInIText(&w_chat, c);
1585 if (eatkey)
1586 HU_queueChatChar(c);
1588 if (c == key_enter) // phares
1590 chat_on = false;
1591 if (w_chat.l.len)
1593 strcpy(lastmessage, w_chat.l.l);
1594 plr->message = lastmessage;
1597 else if (c == key_escape) // phares
1598 chat_on = false;
1601 return eatkey;