summaryrefslogtreecommitdiff
path: root/apps/plugins/doom/hu_stuff.c
diff options
context:
space:
mode:
authorDave Chapman <dave@dchapman.com>2006-03-28 15:44:01 +0000
committerDave Chapman <dave@dchapman.com>2006-03-28 15:44:01 +0000
commit47f4a458d636a889e955e68f896708f1276febc0 (patch)
tree99f770c02ef606f0abbdcd332ac39e69830d8007 /apps/plugins/doom/hu_stuff.c
parentfff7d6157d56f233cad5c2003475e47a5ff809a7 (diff)
downloadrockbox-47f4a458d636a889e955e68f896708f1276febc0.tar.gz
rockbox-47f4a458d636a889e955e68f896708f1276febc0.zip
Patch #2969 - Doom! Currently only working on the H300.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@9312 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/doom/hu_stuff.c')
-rw-r--r--apps/plugins/doom/hu_stuff.c1753
1 files changed, 1753 insertions, 0 deletions
diff --git a/apps/plugins/doom/hu_stuff.c b/apps/plugins/doom/hu_stuff.c
new file mode 100644
index 0000000000..fd7bd0d4f4
--- /dev/null
+++ b/apps/plugins/doom/hu_stuff.c
@@ -0,0 +1,1753 @@
1/* Emacs style mode select -*- C++ -*-
2 *-----------------------------------------------------------------------------
3 *
4 *
5 * PrBoom a Doom port merged with LxDoom and LSDLDoom
6 * based on BOOM, a modified and improved DOOM engine
7 * Copyright (C) 1999 by
8 * id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
9 * Copyright (C) 1999-2000 by
10 * Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25 * 02111-1307, USA.
26 *
27 * DESCRIPTION: Heads-up displays
28 *
29 *-----------------------------------------------------------------------------
30 */
31
32// killough 5/3/98: remove unnecessary headers
33
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"
45
46// global heads up display controls
47
48int hud_active; //jff 2/17/98 controls heads-up display mode
49int hud_displayed; //jff 2/23/98 turns heads-up display on/off
50int hud_nosecrets; //jff 2/18/98 allows secrets line to be disabled in HUD
51int hud_distributed; //jff 3/4/98 display HUD in different places on screen
52int hud_graph_keys=1; //jff 3/7/98 display HUD keys as graphics
53
54//
55// Locally used constants, shortcuts.
56//
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))
69
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))
77
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)
97
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)
120
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
126
127#define key_alt KEY_RALT
128#define key_shift KEY_RSHIFT
129
130const char* chat_macros[] =
131 // Ty 03/27/98 - *not* externalized
132 // CPhipps - const char*
133 {
134 HUSTR_CHATMACRO0,
135 HUSTR_CHATMACRO1,
136 HUSTR_CHATMACRO2,
137 HUSTR_CHATMACRO3,
138 HUSTR_CHATMACRO4,
139 HUSTR_CHATMACRO5,
140 HUSTR_CHATMACRO6,
141 HUSTR_CHATMACRO7,
142 HUSTR_CHATMACRO8,
143 HUSTR_CHATMACRO9
144 };
145
146const char* player_names[] =
147 // Ty 03/27/98 - *not* externalized
148 // CPhipps - const char*
149 {
150 HUSTR_PLRGREEN,
151 HUSTR_PLRINDIGO,
152 HUSTR_PLRBROWN,
153 HUSTR_PLRRED
154 };
155
156//jff 3/17/98 translate player colmap to text color ranges
157int plyrcoltran[MAXPLAYERS]={CR_GREEN,CR_GRAY,CR_BROWN,CR_RED};
158
159char chat_char; // remove later.
160static player_t* plr;
161
162// font sets
163patchnum_t hu_font[HU_FONTSIZE];
164patchnum_t hu_font2[HU_FONTSIZE];
165patchnum_t hu_fontk[HU_FONTSIZE];//jff 3/7/98 added for graphic key indicators
166patchnum_t hu_msgbg[9]; //jff 2/26/98 add patches for message background
167
168// widgets
169static hu_textline_t w_title;
170static hu_stext_t w_message;
171static hu_itext_t w_chat;
172static hu_itext_t w_inputbuffer[MAXPLAYERS];
173static hu_textline_t w_coordx; //jff 2/16/98 new coord widget for automap
174static hu_textline_t w_coordy; //jff 3/3/98 split coord widgets automap
175static hu_textline_t w_coordz; //jff 3/3/98 split coord widgets automap
176static hu_textline_t w_ammo; //jff 2/16/98 new ammo widget for hud
177static hu_textline_t w_health; //jff 2/16/98 new health widget for hud
178static hu_textline_t w_armor; //jff 2/16/98 new armor widget for hud
179static hu_textline_t w_weapon; //jff 2/16/98 new weapon widget for hud
180static hu_textline_t w_keys; //jff 2/16/98 new keys widget for hud
181static hu_textline_t w_gkeys; //jff 3/7/98 graphic keys widget for hud
182static hu_textline_t w_monsec; //jff 2/16/98 new kill/secret widget for hud
183static hu_mtext_t w_rtext; //jff 2/26/98 text message refresh widget
184
185static boolean always_off = false;
186static char chat_dest[MAXPLAYERS];
187boolean chat_on;
188static boolean message_on;
189static boolean message_list; //2/26/98 enable showing list of messages
190boolean message_dontfuckwithme;
191static boolean message_nottobefuckedwith;
192static int message_counter;
193extern int showMessages;
194extern boolean automapactive;
195static boolean headsupactive = false;
196
197//jff 2/16/98 hud supported automap colors added
198int hudcolor_titl; // color range of automap level title
199int hudcolor_xyco; // color range of new coords on automap
200//jff 2/16/98 hud text colors, controls added
201int hudcolor_mesg; // color range of scrolling messages
202int hudcolor_chat; // color range of chat lines
203int hud_msg_lines; // number of message lines in window
204//jff 2/26/98 hud text colors, controls added
205int hudcolor_list; // list of messages color
206int hud_list_bgon; // enable for solid window background for message list
207
208//jff 2/16/98 initialization strings for ammo, health, armor widgets
209static char hud_coordstrx[32];
210static char hud_coordstry[32];
211static char hud_coordstrz[32];
212static char hud_ammostr[80];
213static char hud_healthstr[80];
214static char hud_armorstr[80];
215static char hud_weapstr[80];
216static char hud_keysstr[80];
217static char hud_gkeysstr[80]; //jff 3/7/98 add support for graphic key display
218static char hud_monsecstr[80];
219
220//jff 2/16/98 declaration of color switch points
221extern int ammo_red;
222extern int ammo_yellow;
223extern int health_red;
224extern int health_yellow;
225extern int health_green;
226extern int armor_red;
227extern int armor_yellow;
228extern int armor_green;
229
230//
231// Builtin map names.
232// The actual names can be found in DStrings.h.
233//
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
237char* mapnames[] = // DOOM shareware/registered/retail (Ultimate) names.
238 {
239
240 HUSTR_E1M1,
241 HUSTR_E1M2,
242 HUSTR_E1M3,
243 HUSTR_E1M4,
244 HUSTR_E1M5,
245 HUSTR_E1M6,
246 HUSTR_E1M7,
247 HUSTR_E1M8,
248 HUSTR_E1M9,
249
250 HUSTR_E2M1,
251 HUSTR_E2M2,
252 HUSTR_E2M3,
253 HUSTR_E2M4,
254 HUSTR_E2M5,
255 HUSTR_E2M6,
256 HUSTR_E2M7,
257 HUSTR_E2M8,
258 HUSTR_E2M9,
259
260 HUSTR_E3M1,
261 HUSTR_E3M2,
262 HUSTR_E3M3,
263 HUSTR_E3M4,
264 HUSTR_E3M5,
265 HUSTR_E3M6,
266 HUSTR_E3M7,
267 HUSTR_E3M8,
268 HUSTR_E3M9,
269
270 HUSTR_E4M1,
271 HUSTR_E4M2,
272 HUSTR_E4M3,
273 HUSTR_E4M4,
274 HUSTR_E4M5,
275 HUSTR_E4M6,
276 HUSTR_E4M7,
277 HUSTR_E4M8,
278 HUSTR_E4M9,
279
280 "NEWLEVEL",
281 "NEWLEVEL",
282 "NEWLEVEL",
283 "NEWLEVEL",
284 "NEWLEVEL",
285 "NEWLEVEL",
286 "NEWLEVEL",
287 "NEWLEVEL",
288 "NEWLEVEL"
289 };
290
291char* mapnames2[] = // DOOM 2 map names.
292 {
293 HUSTR_1,
294 HUSTR_2,
295 HUSTR_3,
296 HUSTR_4,
297 HUSTR_5,
298 HUSTR_6,
299 HUSTR_7,
300 HUSTR_8,
301 HUSTR_9,
302 HUSTR_10,
303 HUSTR_11,
304
305 HUSTR_12,
306 HUSTR_13,
307 HUSTR_14,
308 HUSTR_15,
309 HUSTR_16,
310 HUSTR_17,
311 HUSTR_18,
312 HUSTR_19,
313 HUSTR_20,
314
315 HUSTR_21,
316 HUSTR_22,
317 HUSTR_23,
318 HUSTR_24,
319 HUSTR_25,
320 HUSTR_26,
321 HUSTR_27,
322 HUSTR_28,
323 HUSTR_29,
324 HUSTR_30,
325 HUSTR_31,
326 HUSTR_32
327 };
328
329
330char* mapnamesp[] = // Plutonia WAD map names.
331 {
332 PHUSTR_1,
333 PHUSTR_2,
334 PHUSTR_3,
335 PHUSTR_4,
336 PHUSTR_5,
337 PHUSTR_6,
338 PHUSTR_7,
339 PHUSTR_8,
340 PHUSTR_9,
341 PHUSTR_10,
342 PHUSTR_11,
343
344 PHUSTR_12,
345 PHUSTR_13,
346 PHUSTR_14,
347 PHUSTR_15,
348 PHUSTR_16,
349 PHUSTR_17,
350 PHUSTR_18,
351 PHUSTR_19,
352 PHUSTR_20,
353
354 PHUSTR_21,
355 PHUSTR_22,
356 PHUSTR_23,
357 PHUSTR_24,
358 PHUSTR_25,
359 PHUSTR_26,
360 PHUSTR_27,
361 PHUSTR_28,
362 PHUSTR_29,
363 PHUSTR_30,
364 PHUSTR_31,
365 PHUSTR_32
366 };
367
368
369char *mapnamest[] = // TNT WAD map names.
370 {
371 THUSTR_1,
372 THUSTR_2,
373 THUSTR_3,
374 THUSTR_4,
375 THUSTR_5,
376 THUSTR_6,
377 THUSTR_7,
378 THUSTR_8,
379 THUSTR_9,
380 THUSTR_10,
381 THUSTR_11,
382
383 THUSTR_12,
384 THUSTR_13,
385 THUSTR_14,
386 THUSTR_15,
387 THUSTR_16,
388 THUSTR_17,
389 THUSTR_18,
390 THUSTR_19,
391 THUSTR_20,
392
393 THUSTR_21,
394 THUSTR_22,
395 THUSTR_23,
396 THUSTR_24,
397 THUSTR_25,
398 THUSTR_26,
399 THUSTR_27,
400 THUSTR_28,
401 THUSTR_29,
402 THUSTR_30,
403 THUSTR_31,
404 THUSTR_32
405 };
406
407// key tables
408// jff 5/10/98 french support removed,
409// as it was not being used and couldn't be easily tested
410//
411const char* shiftxform;
412
413const char english_shiftxform[] =
414 {
415 0,
416 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
417 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
418 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
419 31,
420 ' ', '!', '"', '#', '$', '%', '&',
421 '"', // shift-'
422 '(', ')', '*', '+',
423 '<', // shift-,
424 '_', // shift--
425 '>', // shift-.
426 '?', // shift-/
427 ')', // shift-0
428 '!', // shift-1
429 '@', // shift-2
430 '#', // shift-3
431 '$', // shift-4
432 '%', // shift-5
433 '^', // shift-6
434 '&', // shift-7
435 '*', // shift-8
436 '(', // shift-9
437 ':',
438 ':', // shift-;
439 '<',
440 '+', // shift-=
441 '>', '?', '@',
442 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
443 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
444 '[', // shift-[
445 '!', // shift-backslash - OH MY GOD DOES WATCOM SUCK
446 ']', // shift-]
447 '"', '_',
448 '\'', // shift-`
449 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
450 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
451 '{', '|', '}', '~', 127
452 };
453
454//
455// HU_Init()
456//
457// Initialize the heads-up display, text that overwrites the primary display
458//
459// Passed nothing, returns nothing
460//
461void HU_Init(void)
462{
463 int i;
464 int j;
465 char buffer[9];
466
467 shiftxform = english_shiftxform;
468
469 // load the heads-up font
470 j = HU_FONTSTART;
471 for (i=0;i<HU_FONTSIZE;i++,j++)
472 {
473 if ('0'<=j && j<='9')
474 {
475 snprintf(buffer, sizeof(buffer), "DIG%d",j-48);
476 R_SetPatchNum(&hu_font2[i], buffer);
477 snprintf(buffer, sizeof(buffer), "STCFN%s%d", (j/10>0?"0":"00"), j); //NOTE ROCKHACK: "STCFN%.3d"
478 R_SetPatchNum(&hu_font[i], buffer);
479 }
480 else if ('A'<=j && j<='Z')
481 {
482 snprintf(buffer, sizeof(buffer), "DIG%c",j);
483 R_SetPatchNum(&hu_font2[i], buffer);
484 snprintf(buffer, sizeof(buffer), "STCFN%s%d", (j/10>0?"0":"00"), j); //NOTE ROCKHACK: "STCFN%.3d"
485 R_SetPatchNum(&hu_font[i], buffer);
486 }
487 else if (j=='-')
488 {
489 R_SetPatchNum(&hu_font2[i], "DIG45");
490 R_SetPatchNum(&hu_font[i], "STCFN045");
491 }
492 else if (j=='/')
493 {
494 R_SetPatchNum(&hu_font2[i], "DIG47");
495 R_SetPatchNum(&hu_font[i], "STCFN047");
496 }
497 else if (j==':')
498 {
499 R_SetPatchNum(&hu_font2[i], "DIG58");
500 R_SetPatchNum(&hu_font[i], "STCFN058");
501 }
502 else if (j=='[')
503 {
504 R_SetPatchNum(&hu_font2[i], "DIG91");
505 R_SetPatchNum(&hu_font[i], "STCFN091");
506 }
507 else if (j==']')
508 {
509 R_SetPatchNum(&hu_font2[i], "DIG93");
510 R_SetPatchNum(&hu_font[i], "STCFN093");
511 }
512 else if (j<97)
513 {
514 snprintf(buffer, sizeof(buffer), "STCFN%s%d", (j/10>0?"0":"00"), j); //NOTE ROCKHACK: "STCFN%.3d"
515 R_SetPatchNum(&hu_font2[i], buffer);
516 R_SetPatchNum(&hu_font[i], buffer);
517 //jff 2/23/98 make all font chars defined, useful or not
518 }
519 else if (j>122)
520 {
521 snprintf(buffer, sizeof(buffer), "STBR%d", j); //NOTE: "STBR%.3d"
522 R_SetPatchNum(&hu_font2[i], buffer);
523 R_SetPatchNum(&hu_font[i], buffer);
524 }
525 else
526 hu_font[i] = hu_font[0]; //jff 2/16/98 account for gap
527 }
528
529 // CPhipps - load patches for message background
530 for (i=0; i<9; i++) {
531 snprintf(buffer, sizeof(buffer), "BOX%c%c", "UCL"[i/3], "LCR"[i%3]);
532 R_SetPatchNum(&hu_msgbg[i], buffer);
533 }
534
535 // CPhipps - load patches for keys and double keys
536 for (i=0; i<6; i++) {
537 snprintf(buffer, sizeof(buffer), "STKEYS%d", i);
538 R_SetPatchNum(&hu_fontk[i], buffer);
539 }
540}
541
542//
543// HU_Stop()
544//
545// Make the heads-up displays inactive
546//
547// Passed nothing, returns nothing
548//
549void HU_Stop(void)
550{
551 headsupactive = false;
552}
553
554//
555// HU_Start(void)
556//
557// Create and initialize the heads-up widgets, software machines to
558// maintain, update, and display information over the primary display
559//
560// This routine must be called after any change to the heads up configuration
561// in order for the changes to take effect in the actual displays
562//
563// Passed nothing, returns nothing
564//
565void HU_Start(void)
566{
567
568 int i;
569 const char* s; /* cph - const */
570
571 if (headsupactive) // stop before starting
572 HU_Stop();
573
574 plr = &players[displayplayer]; // killough 3/7/98
575 message_on = false;
576 message_dontfuckwithme = false;
577 message_nottobefuckedwith = false;
578 chat_on = false;
579
580 // create the message widget
581 // messages to player in upper-left of screen
582 HUlib_initSText
583 (
584 &w_message,
585 HU_MSGX,
586 HU_MSGY,
587 HU_MSGHEIGHT,
588 hu_font,
589 HU_FONTSTART,
590 hudcolor_mesg,
591 &message_on
592 );
593
594 //jff 2/16/98 added some HUD widgets
595 // create the map title widget - map title display in lower left of automap
596 HUlib_initTextLine
597 (
598 &w_title,
599 HU_TITLEX,
600 HU_TITLEY,
601 hu_font,
602 HU_FONTSTART,
603 hudcolor_titl
604 );
605
606 // create the hud health widget
607 // bargraph and number for amount of health,
608 // lower left or upper right of screen
609 HUlib_initTextLine
610 (
611 &w_health,
612 hud_distributed? HU_HEALTHX_D : HU_HEALTHX, //3/4/98 distribute
613 hud_distributed? HU_HEALTHY_D : HU_HEALTHY,
614 hu_font2,
615 HU_FONTSTART,
616 CR_GREEN
617 );
618
619 // create the hud armor widget
620 // bargraph and number for amount of armor,
621 // lower left or upper right of screen
622 HUlib_initTextLine
623 (
624 &w_armor,
625 hud_distributed? HU_ARMORX_D : HU_ARMORX, //3/4/98 distribute
626 hud_distributed? HU_ARMORY_D : HU_ARMORY,
627 hu_font2,
628 HU_FONTSTART,
629 CR_GREEN
630 );
631
632 // create the hud ammo widget
633 // bargraph and number for amount of ammo for current weapon,
634 // lower left or lower right of screen
635 HUlib_initTextLine
636 (
637 &w_ammo,
638 hud_distributed? HU_AMMOX_D : HU_AMMOX, //3/4/98 distribute
639 hud_distributed? HU_AMMOY_D : HU_AMMOY,
640 hu_font2,
641 HU_FONTSTART,
642 CR_GOLD
643 );
644
645 // create the hud weapons widget
646 // list of numbers of weapons possessed
647 // lower left or lower right of screen
648 HUlib_initTextLine
649 (
650 &w_weapon,
651 hud_distributed? HU_WEAPX_D : HU_WEAPX, //3/4/98 distribute
652 hud_distributed? HU_WEAPY_D : HU_WEAPY,
653 hu_font2,
654 HU_FONTSTART,
655 CR_GRAY
656 );
657
658 // create the hud keys widget
659 // display of key letters possessed
660 // lower left of screen
661 HUlib_initTextLine
662 (
663 &w_keys,
664 hud_distributed? HU_KEYSX_D : HU_KEYSX, //3/4/98 distribute
665 hud_distributed? HU_KEYSY_D : HU_KEYSY,
666 hu_font2,
667 HU_FONTSTART,
668 CR_GRAY
669 );
670
671 // create the hud graphic keys widget
672 // display of key graphics possessed
673 // lower left of screen
674 HUlib_initTextLine
675 (
676 &w_gkeys,
677 hud_distributed? HU_KEYSGX_D : HU_KEYSGX, //3/4/98 distribute
678 hud_distributed? HU_KEYSY_D : HU_KEYSY,
679 hu_fontk,
680 HU_FONTSTART,
681 CR_RED
682 );
683
684 // create the hud monster/secret widget
685 // totals and current values for kills, items, secrets
686 // lower left of screen
687 HUlib_initTextLine
688 (
689 &w_monsec,
690 hud_distributed? HU_MONSECX_D : HU_MONSECX, //3/4/98 distribute
691 hud_distributed? HU_MONSECY_D : HU_MONSECY,
692 hu_font2,
693 HU_FONTSTART,
694 CR_GRAY
695 );
696
697 // create the hud text refresh widget
698 // scrolling display of last hud_msg_lines messages received
699 if (hud_msg_lines>HU_MAXMESSAGES)
700 hud_msg_lines=HU_MAXMESSAGES;
701 //jff 4/21/98 if setup has disabled message list while active, turn it off
702 message_list = hud_msg_lines > 1; //jff 8/8/98 initialize both ways
703 //jff 2/26/98 add the text refresh widget initialization
704 HUlib_initMText
705 (
706 &w_rtext,
707 0,
708 0,
709 320,
710 // SCREENWIDTH,
711 (hud_msg_lines+2)*HU_REFRESHSPACING,
712 hu_font,
713 HU_FONTSTART,
714 hudcolor_list,
715 hu_msgbg,
716 &message_list
717 );
718
719 // initialize the automap's level title widget
720 if (gamestate == GS_LEVEL) /* cph - stop SEGV here when not in level */
721 switch (gamemode)
722 {
723 case shareware:
724 case registered:
725 case retail:
726 s = HU_TITLE;
727 break;
728
729 case commercial:
730 default: // Ty 08/27/98 - modified to check mission for TNT/Plutonia
731 s = (gamemission==pack_tnt) ? HU_TITLET :
732 (gamemission==pack_plut) ? HU_TITLEP : HU_TITLE2;
733 break;
734 } else s = "";
735 while (*s)
736 HUlib_addCharToTextLine(&w_title, *(s++));
737
738 // create the automaps coordinate widget
739 // jff 3/3/98 split coord widget into three lines: x,y,z
740 // jff 2/16/98 added
741 HUlib_initTextLine
742 (
743 &w_coordx,
744 HU_COORDX,
745 HU_COORDX_Y,
746 hu_font,
747 HU_FONTSTART,
748 hudcolor_xyco
749 );
750 HUlib_initTextLine
751 (
752 &w_coordy,
753 HU_COORDX,
754 HU_COORDY_Y,
755 hu_font,
756 HU_FONTSTART,
757 hudcolor_xyco
758 );
759 HUlib_initTextLine
760 (
761 &w_coordz,
762 HU_COORDX,
763 HU_COORDZ_Y,
764 hu_font,
765 HU_FONTSTART,
766 hudcolor_xyco
767 );
768
769 // initialize the automaps coordinate widget
770 //jff 3/3/98 split coordstr widget into 3 parts
771 snprintf(hud_coordstrx,sizeof(hud_coordstrx),"X: %-5d",0); //jff 2/22/98 added z
772 s = hud_coordstrx;
773 while (*s)
774 HUlib_addCharToTextLine(&w_coordx, *(s++));
775 snprintf(hud_coordstry,sizeof(hud_coordstry),"Y: %-5d",0); //jff 3/3/98 split x,y,z
776 s = hud_coordstry;
777 while (*s)
778 HUlib_addCharToTextLine(&w_coordy, *(s++));
779 snprintf(hud_coordstrz,sizeof(hud_coordstrz),"Z: %-5d",0); //jff 3/3/98 split x,y,z
780 s = hud_coordstrz;
781 while (*s)
782 HUlib_addCharToTextLine(&w_coordz, *(s++));
783
784 //jff 2/16/98 initialize ammo widget
785 strcpy(hud_ammostr,"AMM ");
786 s = hud_ammostr;
787 while (*s)
788 HUlib_addCharToTextLine(&w_ammo, *(s++));
789
790 //jff 2/16/98 initialize health widget
791 strcpy(hud_healthstr,"HEL ");
792 s = hud_healthstr;
793 while (*s)
794 HUlib_addCharToTextLine(&w_health, *(s++));
795
796 //jff 2/16/98 initialize armor widget
797 strcpy(hud_armorstr,"ARM ");
798 s = hud_armorstr;
799 while (*s)
800 HUlib_addCharToTextLine(&w_armor, *(s++));
801
802 //jff 2/17/98 initialize weapons widget
803 strcpy(hud_weapstr,"WEA ");
804 s = hud_weapstr;
805 while (*s)
806 HUlib_addCharToTextLine(&w_weapon, *(s++));
807
808 //jff 2/17/98 initialize keys widget
809 if (!deathmatch) //jff 3/17/98 show frags in deathmatch mode
810 strcpy(hud_keysstr,"KEY ");
811 else
812 strcpy(hud_keysstr,"FRG ");
813 s = hud_keysstr;
814 while (*s)
815 HUlib_addCharToTextLine(&w_keys, *(s++));
816
817 //jff 2/17/98 initialize graphic keys widget
818 strcpy(hud_gkeysstr," ");
819 s = hud_gkeysstr;
820 while (*s)
821 HUlib_addCharToTextLine(&w_gkeys, *(s++));
822
823 //jff 2/17/98 initialize kills/items/secret widget
824 strcpy(hud_monsecstr,"STS ");
825 s = hud_monsecstr;
826 while (*s)
827 HUlib_addCharToTextLine(&w_monsec, *(s++));
828
829 // create the chat widget
830 HUlib_initIText
831 (
832 &w_chat,
833 HU_INPUTX,
834 HU_INPUTY,
835 hu_font,
836 HU_FONTSTART,
837 hudcolor_chat,
838 &chat_on
839 );
840
841 // create the inputbuffer widgets, one per player
842 for (i=0 ; i<MAXPLAYERS ; i++)
843 HUlib_initIText
844 (
845 &w_inputbuffer[i],
846 0,
847 0,
848 0,
849 0,
850 hudcolor_chat,
851 &always_off
852 );
853
854 // now allow the heads-up display to run
855 headsupactive = true;
856}
857
858//
859// HU_MoveHud()
860//
861// Move the HUD display from distributed to compact mode or vice-versa
862//
863// Passed nothing, returns nothing
864//
865//jff 3/9/98 create this externally callable to avoid glitch
866// when menu scatter's HUD due to delay in change of position
867//
868void HU_MoveHud(void)
869{
870 static int ohud_distributed=-1;
871
872 //jff 3/4/98 move displays around on F5 changing hud_distributed
873 if (hud_distributed!=ohud_distributed)
874 {
875 w_ammo.x = hud_distributed? HU_AMMOX_D : HU_AMMOX;
876 w_ammo.y = hud_distributed? HU_AMMOY_D : HU_AMMOY;
877 w_weapon.x = hud_distributed? HU_WEAPX_D : HU_WEAPX;
878 w_weapon.y = hud_distributed? HU_WEAPY_D : HU_WEAPY;
879 w_keys.x = hud_distributed? HU_KEYSX_D : HU_KEYSX;
880 w_keys.y = hud_distributed? HU_KEYSY_D : HU_KEYSY;
881 w_gkeys.x = hud_distributed? HU_KEYSGX_D : HU_KEYSGX;
882 w_gkeys.y = hud_distributed? HU_KEYSY_D : HU_KEYSY;
883 w_monsec.x = hud_distributed? HU_MONSECX_D : HU_MONSECX;
884 w_monsec.y = hud_distributed? HU_MONSECY_D : HU_MONSECY;
885 w_health.x = hud_distributed? HU_HEALTHX_D : HU_HEALTHX;
886 w_health.y = hud_distributed? HU_HEALTHY_D : HU_HEALTHY;
887 w_armor.x = hud_distributed? HU_ARMORX_D : HU_ARMORX;
888 w_armor.y = hud_distributed? HU_ARMORY_D : HU_ARMORY;
889 }
890 ohud_distributed = hud_distributed;
891}
892
893//
894// HU_Drawer()
895//
896// Draw all the pieces of the heads-up display
897//
898// Passed nothing, returns nothing
899//
900void HU_Drawer(void)
901{
902 char *s;
903 player_t *plr;
904 char ammostr[80]; //jff 3/8/98 allow plenty room for dehacked mods
905 char healthstr[80];//jff
906 char armorstr[80]; //jff
907 int i,doit;
908
909 plr = &players[displayplayer]; // killough 3/7/98
910 // draw the automap widgets if automap is displayed
911 if (automapmode & am_active)
912 {
913 // map title
914 HUlib_drawTextLine(&w_title, false);
915
916 //jff 2/16/98 output new coord display
917 // x-coord
918 snprintf(hud_coordstrx,sizeof(hud_coordstrx),"X: %-5d", (plr->mo->x)>>FRACBITS);
919 HUlib_clearTextLine(&w_coordx);
920 s = hud_coordstrx;
921 while (*s)
922 HUlib_addCharToTextLine(&w_coordx, *(s++));
923 HUlib_drawTextLine(&w_coordx, false);
924
925 //jff 3/3/98 split coord display into x,y,z lines
926 // y-coord
927 snprintf(hud_coordstry,sizeof(hud_coordstry),"Y: %-5d", (plr->mo->y)>>FRACBITS);
928 HUlib_clearTextLine(&w_coordy);
929 s = hud_coordstry;
930 while (*s)
931 HUlib_addCharToTextLine(&w_coordy, *(s++));
932 HUlib_drawTextLine(&w_coordy, false);
933
934 //jff 3/3/98 split coord display into x,y,z lines
935 //jff 2/22/98 added z
936 // z-coord
937 snprintf(hud_coordstrz,sizeof(hud_coordstrz),"Z: %-5d", (plr->mo->z)>>FRACBITS);
938 HUlib_clearTextLine(&w_coordz);
939 s = hud_coordstrz;
940 while (*s)
941 HUlib_addCharToTextLine(&w_coordz, *(s++));
942 HUlib_drawTextLine(&w_coordz, false);
943 }
944
945 // draw the weapon/health/ammo/armor/kills/keys displays if optioned
946 //jff 2/17/98 allow new hud stuff to be turned off
947 // killough 2/21/98: really allow new hud stuff to be turned off COMPLETELY
948 if
949 (
950 hud_active>0 && // hud optioned on
951 hud_displayed && // hud on from fullscreen key
952 viewheight==SCREENHEIGHT && // fullscreen mode is active
953 !(automapmode & am_active) // automap is not active
954 )
955 {
956 doit = !(gametic&1); //jff 3/4/98 speed update up for slow systems
957 if (doit) //jff 8/7/98 update every time, avoid lag in update
958 {
959 HU_MoveHud(); // insure HUD display coords are correct
960
961 // do the hud ammo display
962 // clear the widgets internal line
963 HUlib_clearTextLine(&w_ammo);
964 strcpy(hud_ammostr,"AMM ");
965 if (weaponinfo[plr->readyweapon].ammo == am_noammo)
966 { // special case for weapon with no ammo selected - blank bargraph + N/A
967 strcat(hud_ammostr,"\x7f\x7f\x7f\x7f\x7f\x7f\x7f N/A");
968 w_ammo.cm = CR_GRAY;
969 }
970 else
971 {
972 int ammo = plr->ammo[weaponinfo[plr->readyweapon].ammo];
973 int fullammo = plr->maxammo[weaponinfo[plr->readyweapon].ammo];
974 int ammopct = (100*ammo)/fullammo;
975 int ammobars = ammopct/4;
976
977 // build the numeric amount init string
978 snprintf(ammostr,sizeof(ammostr),"%d/%d",ammo,fullammo);
979 // build the bargraph string
980 // full bargraph chars
981 for (i=4;i<4+ammobars/4;)
982 hud_ammostr[i++] = 123;
983 // plus one last character with 0,1,2,3 bars
984 switch(ammobars%4)
985 {
986 case 0:
987 break;
988 case 1:
989 hud_ammostr[i++] = 126;
990 break;
991 case 2:
992 hud_ammostr[i++] = 125;
993 break;
994 case 3:
995 hud_ammostr[i++] = 124;
996 break;
997 }
998 // pad string with blank bar characters
999 while(i<4+7)
1000 hud_ammostr[i++] = 127;
1001 hud_ammostr[i] = '\0';
1002 strcat(hud_ammostr,ammostr);
1003
1004 // set the display color from the percentage of total ammo held
1005 if (ammopct<ammo_red)
1006 w_ammo.cm = CR_RED;
1007 else if (ammopct<ammo_yellow)
1008 w_ammo.cm = CR_GOLD;
1009 else
1010 w_ammo.cm = CR_GREEN;
1011 }
1012 // transfer the init string to the widget
1013 s = hud_ammostr;
1014 while (*s)
1015 HUlib_addCharToTextLine(&w_ammo, *(s++));
1016 }
1017 // display the ammo widget every frame
1018 HUlib_drawTextLine(&w_ammo, false);
1019
1020 // do the hud health display
1021 if (doit)
1022 {
1023 int health = plr->health;
1024 int healthbars = health>100? 25 : health/4;
1025
1026 // clear the widgets internal line
1027 HUlib_clearTextLine(&w_health);
1028
1029 // build the numeric amount init string
1030 snprintf(healthstr,sizeof(healthstr),"%3d",health);
1031 // build the bargraph string
1032 // full bargraph chars
1033 for (i=4;i<4+healthbars/4;)
1034 hud_healthstr[i++] = 123;
1035 // plus one last character with 0,1,2,3 bars
1036 switch(healthbars%4)
1037 {
1038 case 0:
1039 break;
1040 case 1:
1041 hud_healthstr[i++] = 126;
1042 break;
1043 case 2:
1044 hud_healthstr[i++] = 125;
1045 break;
1046 case 3:
1047 hud_healthstr[i++] = 124;
1048 break;
1049 }
1050 // pad string with blank bar characters
1051 while(i<4+7)
1052 hud_healthstr[i++] = 127;
1053 hud_healthstr[i] = '\0';
1054 strcat(hud_healthstr,healthstr);
1055
1056 // set the display color from the amount of health posessed
1057 if (health<health_red)
1058 w_health.cm = CR_RED;
1059 else if (health<health_yellow)
1060 w_health.cm = CR_GOLD;
1061 else if (health<=health_green)
1062 w_health.cm = CR_GREEN;
1063 else
1064 w_health.cm = CR_BLUE;
1065
1066 // transfer the init string to the widget
1067 s = hud_healthstr;
1068 while (*s)
1069 HUlib_addCharToTextLine(&w_health, *(s++));
1070 }
1071 // display the health widget every frame
1072 HUlib_drawTextLine(&w_health, false);
1073
1074 // do the hud armor display
1075 if (doit)
1076 {
1077 int armor = plr->armorpoints;
1078 int armorbars = armor>100? 25 : armor/4;
1079
1080 // clear the widgets internal line
1081 HUlib_clearTextLine(&w_armor);
1082 // build the numeric amount init string
1083 snprintf(armorstr,sizeof(armorstr),"%3d",armor);
1084 // build the bargraph string
1085 // full bargraph chars
1086 for (i=4;i<4+armorbars/4;)
1087 hud_armorstr[i++] = 123;
1088 // plus one last character with 0,1,2,3 bars
1089 switch(armorbars%4)
1090 {
1091 case 0:
1092 break;
1093 case 1:
1094 hud_armorstr[i++] = 126;
1095 break;
1096 case 2:
1097 hud_armorstr[i++] = 125;
1098 break;
1099 case 3:
1100 hud_armorstr[i++] = 124;
1101 break;
1102 }
1103 // pad string with blank bar characters
1104 while(i<4+7)
1105 hud_armorstr[i++] = 127;
1106 hud_armorstr[i] = '\0';
1107 strcat(hud_armorstr,armorstr);
1108
1109 // set the display color from the amount of armor posessed
1110 if (armor<armor_red)
1111 w_armor.cm = CR_RED;
1112 else if (armor<armor_yellow)
1113 w_armor.cm = CR_GOLD;
1114 else if (armor<=armor_green)
1115 w_armor.cm = CR_GREEN;
1116 else
1117 w_armor.cm = CR_BLUE;
1118
1119 // transfer the init string to the widget
1120 s = hud_armorstr;
1121 while (*s)
1122 HUlib_addCharToTextLine(&w_armor, *(s++));
1123 }
1124 // display the armor widget every frame
1125 HUlib_drawTextLine(&w_armor, false);
1126
1127 // do the hud weapon display
1128 if (doit)
1129 {
1130 int w;
1131 int ammo,fullammo,ammopct;
1132
1133 // clear the widgets internal line
1134 HUlib_clearTextLine(&w_weapon);
1135 i=4; hud_weapstr[i] = '\0'; //jff 3/7/98 make sure ammo goes away
1136
1137 // do each weapon that exists in current gamemode
1138 for (w=0;w<=wp_supershotgun;w++) //jff 3/4/98 show fists too, why not?
1139 {
1140 int ok=1;
1141 //jff avoid executing for weapons that do not exist
1142 switch (gamemode)
1143 {
1144 case shareware:
1145 if (w>=wp_plasma && w!=wp_chainsaw)
1146 ok=0;
1147 break;
1148 case retail:
1149 case registered:
1150 if (w>=wp_supershotgun)
1151 ok=0;
1152 break;
1153 default:
1154 case commercial:
1155 break;
1156 }
1157 if (!ok) continue;
1158
1159 ammo = plr->ammo[weaponinfo[w].ammo];
1160 fullammo = plr->maxammo[weaponinfo[w].ammo];
1161 ammopct=0;
1162
1163 // skip weapons not currently posessed
1164 if (!plr->weaponowned[w])
1165 continue;
1166
1167 ammopct = fullammo? (100*ammo)/fullammo : 100;
1168
1169 // display each weapon number in a color related to the ammo for it
1170 hud_weapstr[i++] = '\x1b'; //jff 3/26/98 use ESC not '\' for paths
1171 if (weaponinfo[w].ammo==am_noammo) //jff 3/14/98 show berserk on HUD
1172 hud_weapstr[i++] = plr->powers[pw_strength]? '0'+CR_GREEN : '0'+CR_GRAY;
1173 else if (ammopct<ammo_red)
1174 hud_weapstr[i++] = '0'+CR_RED;
1175 else if (ammopct<ammo_yellow)
1176 hud_weapstr[i++] = '0'+CR_GOLD;
1177 else
1178 hud_weapstr[i++] = '0'+CR_GREEN;
1179 hud_weapstr[i++] = '0'+w+1;
1180 hud_weapstr[i++] = ' ';
1181 hud_weapstr[i] = '\0';
1182 }
1183
1184 // transfer the init string to the widget
1185 s = hud_weapstr;
1186 while (*s)
1187 HUlib_addCharToTextLine(&w_weapon, *(s++));
1188 }
1189 // display the weapon widget every frame
1190 HUlib_drawTextLine(&w_weapon, false);
1191
1192 if (doit && hud_active>1)
1193 {
1194 int k;
1195
1196 hud_keysstr[4] = '\0'; //jff 3/7/98 make sure deleted keys go away
1197 //jff add case for graphic key display
1198 if (!deathmatch && hud_graph_keys)
1199 {
1200 i=0;
1201 hud_gkeysstr[i] = '\0'; //jff 3/7/98 init graphic keys widget string
1202 // build text string whose characters call out graphic keys from fontk
1203 for (k=0;k<6;k++)
1204 {
1205 // skip keys not possessed
1206 if (!plr->cards[k])
1207 continue;
1208
1209 hud_gkeysstr[i++] = '!'+k; // key number plus '!' is char for key
1210 hud_gkeysstr[i++] = ' '; // spacing
1211 hud_gkeysstr[i++] = ' ';
1212 }
1213 hud_gkeysstr[i]='\0';
1214 }
1215 else // not possible in current code, unless deathmatching,
1216 {
1217 i=4;
1218 hud_keysstr[i] = '\0'; //jff 3/7/98 make sure deleted keys go away
1219
1220 // if deathmatch, build string showing top four frag counts
1221 if (deathmatch) //jff 3/17/98 show frags, not keys, in deathmatch
1222 {
1223 int top1=-999,top2=-999,top3=-999,top4=-999;
1224 int idx1=-1,idx2=-1,idx3=-1,idx4=-1;
1225 int fragcount,m;
1226 char numbuf[32];
1227
1228 // scan thru players
1229 for (k=0;k<MAXPLAYERS;k++)
1230 {
1231 // skip players not in game
1232 if (!playeringame[k])
1233 continue;
1234
1235 fragcount = 0;
1236 // compute number of times they've fragged each player
1237 // minus number of times they've been fragged by them
1238 for (m=0;m<MAXPLAYERS;m++)
1239 {
1240 if (!playeringame[m]) continue;
1241 fragcount += (m!=k)? players[k].frags[m] : -players[k].frags[m];
1242 }
1243
1244 // very primitive sort of frags to find top four
1245 if (fragcount>top1)
1246 {
1247 top4=top3; top3=top2; top2 = top1; top1=fragcount;
1248 idx4=idx3; idx3=idx2; idx2 = idx1; idx1=k;
1249 }
1250 else if (fragcount>top2)
1251 {
1252 top4=top3; top3=top2; top2=fragcount;
1253 idx4=idx3; idx3=idx2; idx2=k;
1254 }
1255 else if (fragcount>top3)
1256 {
1257 top4=top3; top3=fragcount;
1258 idx4=idx3; idx3=k;
1259 }
1260 else if (fragcount>top4)
1261 {
1262 top4=fragcount;
1263 idx4=k;
1264 }
1265 }
1266 // if the biggest number exists, put it in the init string
1267 if (idx1>-1)
1268 {
1269 snprintf(numbuf,sizeof(numbuf),"%5d",top1);
1270 // make frag count in player's color via escape code
1271 hud_keysstr[i++] = '\x1b'; //jff 3/26/98 use ESC not '\' for paths
1272 hud_keysstr[i++] = '0'+plyrcoltran[idx1&3];
1273 s = numbuf;
1274 while (*s)
1275 hud_keysstr[i++] = *(s++);
1276 }
1277 // if the second biggest number exists, put it in the init string
1278 if (idx2>-1)
1279 {
1280 snprintf(numbuf,sizeof(numbuf),"%5d",top2);
1281 // make frag count in player's color via escape code
1282 hud_keysstr[i++] = '\x1b'; //jff 3/26/98 use ESC not '\' for paths
1283 hud_keysstr[i++] = '0'+plyrcoltran[idx2&3];
1284 s = numbuf;
1285 while (*s)
1286 hud_keysstr[i++] = *(s++);
1287 }
1288 // if the third biggest number exists, put it in the init string
1289 if (idx3>-1)
1290 {
1291 snprintf(numbuf,sizeof(numbuf),"%5d",top3);
1292 // make frag count in player's color via escape code
1293 hud_keysstr[i++] = '\x1b'; //jff 3/26/98 use ESC not '\' for paths
1294 hud_keysstr[i++] = '0'+plyrcoltran[idx3&3];
1295 s = numbuf;
1296 while (*s)
1297 hud_keysstr[i++] = *(s++);
1298 }
1299 // if the fourth biggest number exists, put it in the init string
1300 if (idx4>-1)
1301 {
1302 snprintf(numbuf,sizeof(numbuf),"%5d",top4);
1303 // make frag count in player's color via escape code
1304 hud_keysstr[i++] = '\x1b'; //jff 3/26/98 use ESC not '\' for paths
1305 hud_keysstr[i++] = '0'+plyrcoltran[idx4&3];
1306 s = numbuf;
1307 while (*s)
1308 hud_keysstr[i++] = *(s++);
1309 }
1310 hud_keysstr[i] = '\0';
1311 } //jff 3/17/98 end of deathmatch clause
1312 else // build alphabetical key display (not used currently)
1313 {
1314 // scan the keys
1315 for (k=0;k<6;k++)
1316 {
1317 // skip any not possessed by the displayed player's stats
1318 if (!plr->cards[k])
1319 continue;
1320
1321 // use color escapes to make text in key's color
1322 hud_keysstr[i++] = '\x1b'; //jff 3/26/98 use ESC not '\' for paths
1323 switch(k)
1324 {
1325 case 0:
1326 hud_keysstr[i++] = '0'+CR_BLUE;
1327 hud_keysstr[i++] = 'B';
1328 hud_keysstr[i++] = 'C';
1329 hud_keysstr[i++] = ' ';
1330 break;
1331 case 1:
1332 hud_keysstr[i++] = '0'+CR_GOLD;
1333 hud_keysstr[i++] = 'Y';
1334 hud_keysstr[i++] = 'C';
1335 hud_keysstr[i++] = ' ';
1336 break;
1337 case 2:
1338 hud_keysstr[i++] = '0'+CR_RED;
1339 hud_keysstr[i++] = 'R';
1340 hud_keysstr[i++] = 'C';
1341 hud_keysstr[i++] = ' ';
1342 break;
1343 case 3:
1344 hud_keysstr[i++] = '0'+CR_BLUE;
1345 hud_keysstr[i++] = 'B';
1346 hud_keysstr[i++] = 'S';
1347 hud_keysstr[i++] = ' ';
1348 break;
1349 case 4:
1350 hud_keysstr[i++] = '0'+CR_GOLD;
1351 hud_keysstr[i++] = 'Y';
1352 hud_keysstr[i++] = 'S';
1353 hud_keysstr[i++] = ' ';
1354 break;
1355 case 5:
1356 hud_keysstr[i++] = '0'+CR_RED;
1357 hud_keysstr[i++] = 'R';
1358 hud_keysstr[i++] = 'S';
1359 hud_keysstr[i++] = ' ';
1360 break;
1361 }
1362 hud_keysstr[i]='\0';
1363 }
1364 }
1365 }
1366 }
1367 // display the keys/frags line each frame
1368 if (hud_active>1)
1369 {
1370 HUlib_clearTextLine(&w_keys); // clear the widget strings
1371 HUlib_clearTextLine(&w_gkeys);
1372
1373 // transfer the built string (frags or key title) to the widget
1374 s = hud_keysstr; //jff 3/7/98 display key titles/key text or frags
1375 while (*s)
1376 HUlib_addCharToTextLine(&w_keys, *(s++));
1377 HUlib_drawTextLine(&w_keys, false);
1378
1379 //jff 3/17/98 show graphic keys in non-DM only
1380 if (!deathmatch) //jff 3/7/98 display graphic keys
1381 {
1382 // transfer the graphic key text to the widget
1383 s = hud_gkeysstr;
1384 while (*s)
1385 HUlib_addCharToTextLine(&w_gkeys, *(s++));
1386 // display the widget
1387 HUlib_drawTextLine(&w_gkeys, false);
1388 }
1389 }
1390
1391 // display the hud kills/items/secret display if optioned
1392 if (!hud_nosecrets)
1393 {
1394 if (hud_active>1 && doit)
1395 {
1396 // clear the internal widget text buffer
1397 HUlib_clearTextLine(&w_monsec);
1398 //jff 3/26/98 use ESC not '\' for paths
1399 // build the init string with fixed colors
1400 snprintf
1401 (
1402 hud_monsecstr,sizeof(hud_monsecstr),
1403 "STS \x1b\x36K \x1b\x33%d \x1b\x36M \x1b\x33%d \x1b\x37I \x1b\x33%d/%d \x1b\x35S \x1b\x33%d/%d",
1404 plr->killcount,totallive,
1405 plr->itemcount,totalitems,
1406 plr->secretcount,totalsecret
1407 );
1408 // transfer the init string to the widget
1409 s = hud_monsecstr;
1410 while (*s)
1411 HUlib_addCharToTextLine(&w_monsec, *(s++));
1412 }
1413 // display the kills/items/secrets each frame, if optioned
1414 if (hud_active>1)
1415 HUlib_drawTextLine(&w_monsec, false);
1416 }
1417 }
1418
1419 //jff 3/4/98 display last to give priority
1420 HU_Erase(); // jff 4/24/98 Erase current lines before drawing current
1421 // needed when screen not fullsize
1422
1423 //jff 4/21/98 if setup has disabled message list while active, turn it off
1424 if (hud_msg_lines<=1)
1425 message_list = false;
1426
1427 // if the message review not enabled, show the standard message widget
1428 if (!message_list)
1429 HUlib_drawSText(&w_message);
1430
1431 // if the message review is enabled show the scrolling message review
1432 if (hud_msg_lines>1 && message_list)
1433 HUlib_drawMText(&w_rtext);
1434
1435 // display the interactive buffer for chat entry
1436 HUlib_drawIText(&w_chat);
1437}
1438
1439//
1440// HU_Erase()
1441//
1442// Erase hud display lines that can be trashed by small screen display
1443//
1444// Passed nothing, returns nothing
1445//
1446void HU_Erase(void)
1447{
1448 // erase the message display or the message review display
1449 if (!message_list)
1450 HUlib_eraseSText(&w_message);
1451 else
1452 HUlib_eraseMText(&w_rtext);
1453
1454 // erase the interactive text buffer for chat entry
1455 HUlib_eraseIText(&w_chat);
1456
1457 // erase the automap title
1458 HUlib_eraseTextLine(&w_title);
1459}
1460
1461//
1462// HU_Ticker()
1463//
1464// Update the hud displays once per frame
1465//
1466// Passed nothing, returns nothing
1467//
1468static boolean bsdown; // Is backspace down?
1469static int bscounter;
1470
1471void HU_Ticker(void)
1472{
1473 int i, rc;
1474 char c;
1475
1476 // tick down message counter if message is up
1477 if (message_counter && !--message_counter)
1478 {
1479 message_on = false;
1480 message_nottobefuckedwith = false;
1481 }
1482 if (bsdown && bscounter++ > 9) {
1483 HUlib_keyInIText(&w_chat, (unsigned char)key_backspace);
1484 bscounter = 8;
1485 }
1486
1487 // if messages on, or "Messages Off" is being displayed
1488 // this allows the notification of turning messages off to be seen
1489 if (showMessages || message_dontfuckwithme)
1490 {
1491 // display message if necessary
1492 if ((plr->message && !message_nottobefuckedwith)
1493 || (plr->message && message_dontfuckwithme))
1494 {
1495 //post the message to the message widget
1496 HUlib_addMessageToSText(&w_message, 0, plr->message);
1497 //jff 2/26/98 add message to refresh text widget too
1498 HUlib_addMessageToMText(&w_rtext, 0, plr->message);
1499
1500 // clear the message to avoid posting multiple times
1501 plr->message = 0;
1502 // note a message is displayed
1503 message_on = true;
1504 // start the message persistence counter
1505 message_counter = HU_MSGTIMEOUT;
1506 // transfer "Messages Off" exception to the "being displayed" variable
1507 message_nottobefuckedwith = message_dontfuckwithme;
1508 // clear the flag that "Messages Off" is being posted
1509 message_dontfuckwithme = 0;
1510 }
1511 }
1512
1513 // check for incoming chat characters
1514 if (netgame)
1515 {
1516 for (i=0; i<MAXPLAYERS; i++)
1517 {
1518 if (!playeringame[i])
1519 continue;
1520 if (i != consoleplayer
1521 && (c = players[i].cmd.chatchar))
1522 {
1523 if (c <= HU_BROADCAST)
1524 chat_dest[i] = c;
1525 else
1526 {
1527 if (c >= 'a' && c <= 'z')
1528 c = (char) shiftxform[(unsigned char) c];
1529 rc = HUlib_keyInIText(&w_inputbuffer[i], c);
1530 if (rc && c == KEY_ENTER)
1531 {
1532 if (w_inputbuffer[i].l.len
1533 && (chat_dest[i] == consoleplayer+1
1534 || chat_dest[i] == HU_BROADCAST))
1535 {
1536 HUlib_addMessageToSText(&w_message,
1537 player_names[i],
1538 w_inputbuffer[i].l.l);
1539
1540 message_nottobefuckedwith = true;
1541 message_on = true;
1542 message_counter = HU_MSGTIMEOUT;
1543 if ( gamemode == commercial )
1544 S_StartSound(0, sfx_radio);
1545 else
1546 S_StartSound(0, sfx_tink);
1547 }
1548 HUlib_resetIText(&w_inputbuffer[i]);
1549 }
1550 }
1551 players[i].cmd.chatchar = 0;
1552 }
1553 }
1554 }
1555}
1556
1557#define QUEUESIZE 128
1558
1559static char chatchars[QUEUESIZE];
1560static int head = 0;
1561static int tail = 0;
1562
1563//
1564// HU_queueChatChar()
1565//
1566// Add an incoming character to the circular chat queue
1567//
1568// Passed the character to queue, returns nothing
1569//
1570void HU_queueChatChar(char c)
1571{
1572 if (((head + 1) & (QUEUESIZE-1)) == tail)
1573 {
1574 plr->message = HUSTR_MSGU;
1575 }
1576 else
1577 {
1578 chatchars[head] = c;
1579 head = (head + 1) & (QUEUESIZE-1);
1580 }
1581}
1582
1583//
1584// HU_dequeueChatChar()
1585//
1586// Remove the earliest added character from the circular chat queue
1587//
1588// Passed nothing, returns the character dequeued
1589//
1590char HU_dequeueChatChar(void)
1591{
1592 char c;
1593
1594 if (head != tail)
1595 {
1596 c = chatchars[tail];
1597 tail = (tail + 1) & (QUEUESIZE-1);
1598 }
1599 else
1600 {
1601 c = 0;
1602 }
1603 return c;
1604}
1605
1606//
1607// HU_Responder()
1608//
1609// Responds to input events that affect the heads up displays
1610//
1611// Passed the event to respond to, returns true if the event was handled
1612//
1613boolean HU_Responder(event_t *ev)
1614{
1615
1616 static char lastmessage[HU_MAXLINELENGTH+1];
1617 const char* macromessage; // CPhipps - const char*
1618 boolean eatkey = false;
1619 static boolean shiftdown = false;
1620 static boolean altdown = false;
1621 unsigned char c;
1622 int i;
1623 int numplayers;
1624
1625 static int num_nobrainers = 0;
1626
1627 numplayers = 0;
1628 for (i=0 ; i<MAXPLAYERS ; i++)
1629 numplayers += playeringame[i];
1630
1631 if (ev->data1 == key_shift)
1632 {
1633 shiftdown = ev->type == ev_keydown;
1634 return false;
1635 }
1636 else if (ev->data1 == key_alt)
1637 {
1638 altdown = ev->type == ev_keydown;
1639 return false;
1640 }
1641 else if (ev->data1 == key_backspace)
1642 {
1643 bsdown = ev->type == ev_keydown;
1644 bscounter = 0;
1645 }
1646
1647 if (ev->type != ev_keydown)
1648 return false;
1649
1650 if (!chat_on)
1651 {
1652 if (ev->data1 == key_enter) // phares
1653 {
1654#ifndef INSTRUMENTED // never turn on message review if INSTRUMENTED defined
1655 if (hud_msg_lines>1) // it posts multi-line messages that will trash
1656 {
1657 if (message_list) HU_Erase(); //jff 4/28/98 erase behind messages
1658 message_list = !message_list; //jff 2/26/98 toggle list of messages
1659 }
1660#endif
1661 if (!message_list) // if not message list, refresh message
1662 {
1663 message_on = true;
1664 message_counter = HU_MSGTIMEOUT;
1665 }
1666 eatkey = true;
1667 }//jff 2/26/98 no chat if message review is displayed
1668 else if (!message_list && netgame && ev->data1 == key_chat)
1669 {
1670 eatkey = chat_on = true;
1671 HUlib_resetIText(&w_chat);
1672 HU_queueChatChar(HU_BROADCAST);
1673 }//jff 2/26/98 no chat if message review is displayed
1674 // killough 10/02/98: no chat if demo playback
1675 else if (!demoplayback && !message_list && netgame && numplayers > 2)
1676 {
1677 for (i=0; i<MAXPLAYERS ; i++)
1678 {
1679 if (ev->data1 == destination_keys[i])
1680 {
1681 if (playeringame[i] && i!=consoleplayer)
1682 {
1683 eatkey = chat_on = true;
1684 HUlib_resetIText(&w_chat);
1685 HU_queueChatChar((char)(i+1));
1686 break;
1687 }
1688 else if (i == consoleplayer)
1689 {
1690 num_nobrainers++;
1691 if (num_nobrainers < 3)
1692 plr->message = HUSTR_TALKTOSELF1;
1693 else if (num_nobrainers < 6)
1694 plr->message = HUSTR_TALKTOSELF2;
1695 else if (num_nobrainers < 9)
1696 plr->message = HUSTR_TALKTOSELF3;
1697 else if (num_nobrainers < 32)
1698 plr->message = HUSTR_TALKTOSELF4;
1699 else
1700 plr->message = HUSTR_TALKTOSELF5;
1701 }
1702 }
1703 }
1704 }
1705 }//jff 2/26/98 no chat functions if message review is displayed
1706 else if (!message_list)
1707 {
1708 c = ev->data1;
1709 // send a macro
1710 if (altdown)
1711 {
1712 c = c - '0';
1713 if (c > 9)
1714 return false;
1715 macromessage = chat_macros[c];
1716
1717 // kill last message with a '\n'
1718 HU_queueChatChar((char)key_enter); // DEBUG!!! // phares
1719
1720 // send the macro message
1721 while (*macromessage)
1722 HU_queueChatChar(*macromessage++);
1723 HU_queueChatChar((char)key_enter); // phares
1724
1725 // leave chat mode and notify that it was sent
1726 chat_on = false;
1727 strcpy(lastmessage, chat_macros[c]);
1728 plr->message = lastmessage;
1729 eatkey = true;
1730 }
1731 else
1732 {
1733 if (shiftdown || (c >= 'a' && c <= 'z'))
1734 c = shiftxform[c];
1735 eatkey = HUlib_keyInIText(&w_chat, c);
1736 if (eatkey)
1737 HU_queueChatChar(c);
1738
1739 if (c == key_enter) // phares
1740 {
1741 chat_on = false;
1742 if (w_chat.l.len)
1743 {
1744 strcpy(lastmessage, w_chat.l.l);
1745 plr->message = lastmessage;
1746 }
1747 }
1748 else if (c == key_escape) // phares
1749 chat_on = false;
1750 }
1751 }
1752 return eatkey;
1753}