Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
298 serge 1
// Emacs style mode select   -*- C++ -*-
2
//-----------------------------------------------------------------------------
3
//
4
// $Id:$
5
//
6
// Copyright (C) 1993-1996 by id Software, Inc.
7
//
8
// This source is available for distribution and/or modification
9
// only under the terms of the DOOM Source Code License as
10
// published by id Software. All rights reserved.
11
//
12
// The source is distributed in the hope that it will be useful,
13
// but WITHOUT ANY WARRANTY; without even the implied warranty of
14
// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
15
// for more details.
16
//
17
// $Log:$
18
//
19
// DESCRIPTION:  Heads-up displays
20
//
21
//-----------------------------------------------------------------------------
22
 
23
static const char
24
rcsid[] = "$Id: hu_stuff.c,v 1.4 1997/02/03 16:47:52 b1 Exp $";
25
 
26
#include 
27
 
28
#include "doomdef.h"
29
 
30
#include "z_zone.h"
31
 
32
#include "m_swap.h"
33
 
34
#include "hu_stuff.h"
35
#include "hu_lib.h"
36
#include "w_wad.h"
37
 
38
#include "s_sound.h"
39
 
40
#include "doomstat.h"
41
 
42
// Data.
43
#include "dstrings.h"
44
#include "sounds.h"
45
 
46
//
47
// Locally used constants, shortcuts.
48
//
49
#define HU_TITLE	(mapnames[(gameepisode-1)*9+gamemap-1])
50
#define HU_TITLE2	(mapnames2[gamemap-1])
51
#define HU_TITLEP	(mapnamesp[gamemap-1])
52
#define HU_TITLET	(mapnamest[gamemap-1])
53
#define HU_TITLEHEIGHT	1
54
#define HU_TITLEX	0
55
#define HU_TITLEY	(167 - SHORT(hu_font[0]->height))
56
 
57
#define HU_INPUTTOGGLE	't'
58
#define HU_INPUTX	HU_MSGX
59
#define HU_INPUTY	(HU_MSGY + HU_MSGHEIGHT*(SHORT(hu_font[0]->height) +1))
60
#define HU_INPUTWIDTH	64
61
#define HU_INPUTHEIGHT	1
62
 
63
 
64
 
65
char*	chat_macros[] =
66
{
67
    HUSTR_CHATMACRO0,
68
    HUSTR_CHATMACRO1,
69
    HUSTR_CHATMACRO2,
70
    HUSTR_CHATMACRO3,
71
    HUSTR_CHATMACRO4,
72
    HUSTR_CHATMACRO5,
73
    HUSTR_CHATMACRO6,
74
    HUSTR_CHATMACRO7,
75
    HUSTR_CHATMACRO8,
76
    HUSTR_CHATMACRO9
77
};
78
 
79
char*	player_names[] =
80
{
81
    HUSTR_PLRGREEN,
82
    HUSTR_PLRINDIGO,
83
    HUSTR_PLRBROWN,
84
    HUSTR_PLRRED
85
};
86
 
87
 
88
char			chat_char; // remove later.
89
static player_t*	plr;
90
patch_t*		hu_font[HU_FONTSIZE];
91
static hu_textline_t	w_title;
92
boolean			chat_on;
93
static hu_itext_t	w_chat;
94
static boolean		always_off = false;
95
static char		chat_dest[MAXPLAYERS];
96
static hu_itext_t w_inputbuffer[MAXPLAYERS];
97
 
98
static boolean		message_on;
99
boolean			message_dontfuckwithme;
100
static boolean		message_nottobefuckedwith;
101
 
102
static hu_stext_t	w_message;
103
static int		message_counter;
104
 
105
extern int		showMessages;
106
extern boolean		automapactive;
107
 
108
static boolean		headsupactive = false;
109
 
110
//
111
// Builtin map names.
112
// The actual names can be found in DStrings.h.
113
//
114
 
115
char*	mapnames[] =	// DOOM shareware/registered/retail (Ultimate) names.
116
{
117
 
118
    HUSTR_E1M1,
119
    HUSTR_E1M2,
120
    HUSTR_E1M3,
121
    HUSTR_E1M4,
122
    HUSTR_E1M5,
123
    HUSTR_E1M6,
124
    HUSTR_E1M7,
125
    HUSTR_E1M8,
126
    HUSTR_E1M9,
127
 
128
    HUSTR_E2M1,
129
    HUSTR_E2M2,
130
    HUSTR_E2M3,
131
    HUSTR_E2M4,
132
    HUSTR_E2M5,
133
    HUSTR_E2M6,
134
    HUSTR_E2M7,
135
    HUSTR_E2M8,
136
    HUSTR_E2M9,
137
 
138
    HUSTR_E3M1,
139
    HUSTR_E3M2,
140
    HUSTR_E3M3,
141
    HUSTR_E3M4,
142
    HUSTR_E3M5,
143
    HUSTR_E3M6,
144
    HUSTR_E3M7,
145
    HUSTR_E3M8,
146
    HUSTR_E3M9,
147
 
148
    HUSTR_E4M1,
149
    HUSTR_E4M2,
150
    HUSTR_E4M3,
151
    HUSTR_E4M4,
152
    HUSTR_E4M5,
153
    HUSTR_E4M6,
154
    HUSTR_E4M7,
155
    HUSTR_E4M8,
156
    HUSTR_E4M9,
157
 
158
    "NEWLEVEL",
159
    "NEWLEVEL",
160
    "NEWLEVEL",
161
    "NEWLEVEL",
162
    "NEWLEVEL",
163
    "NEWLEVEL",
164
    "NEWLEVEL",
165
    "NEWLEVEL",
166
    "NEWLEVEL"
167
};
168
 
169
char*	mapnames2[] =	// DOOM 2 map names.
170
{
171
    HUSTR_1,
172
    HUSTR_2,
173
    HUSTR_3,
174
    HUSTR_4,
175
    HUSTR_5,
176
    HUSTR_6,
177
    HUSTR_7,
178
    HUSTR_8,
179
    HUSTR_9,
180
    HUSTR_10,
181
    HUSTR_11,
182
 
183
    HUSTR_12,
184
    HUSTR_13,
185
    HUSTR_14,
186
    HUSTR_15,
187
    HUSTR_16,
188
    HUSTR_17,
189
    HUSTR_18,
190
    HUSTR_19,
191
    HUSTR_20,
192
 
193
    HUSTR_21,
194
    HUSTR_22,
195
    HUSTR_23,
196
    HUSTR_24,
197
    HUSTR_25,
198
    HUSTR_26,
199
    HUSTR_27,
200
    HUSTR_28,
201
    HUSTR_29,
202
    HUSTR_30,
203
    HUSTR_31,
204
    HUSTR_32
205
};
206
 
207
 
208
char*	mapnamesp[] =	// Plutonia WAD map names.
209
{
210
    PHUSTR_1,
211
    PHUSTR_2,
212
    PHUSTR_3,
213
    PHUSTR_4,
214
    PHUSTR_5,
215
    PHUSTR_6,
216
    PHUSTR_7,
217
    PHUSTR_8,
218
    PHUSTR_9,
219
    PHUSTR_10,
220
    PHUSTR_11,
221
 
222
    PHUSTR_12,
223
    PHUSTR_13,
224
    PHUSTR_14,
225
    PHUSTR_15,
226
    PHUSTR_16,
227
    PHUSTR_17,
228
    PHUSTR_18,
229
    PHUSTR_19,
230
    PHUSTR_20,
231
 
232
    PHUSTR_21,
233
    PHUSTR_22,
234
    PHUSTR_23,
235
    PHUSTR_24,
236
    PHUSTR_25,
237
    PHUSTR_26,
238
    PHUSTR_27,
239
    PHUSTR_28,
240
    PHUSTR_29,
241
    PHUSTR_30,
242
    PHUSTR_31,
243
    PHUSTR_32
244
};
245
 
246
 
247
char *mapnamest[] =	// TNT WAD map names.
248
{
249
    THUSTR_1,
250
    THUSTR_2,
251
    THUSTR_3,
252
    THUSTR_4,
253
    THUSTR_5,
254
    THUSTR_6,
255
    THUSTR_7,
256
    THUSTR_8,
257
    THUSTR_9,
258
    THUSTR_10,
259
    THUSTR_11,
260
 
261
    THUSTR_12,
262
    THUSTR_13,
263
    THUSTR_14,
264
    THUSTR_15,
265
    THUSTR_16,
266
    THUSTR_17,
267
    THUSTR_18,
268
    THUSTR_19,
269
    THUSTR_20,
270
 
271
    THUSTR_21,
272
    THUSTR_22,
273
    THUSTR_23,
274
    THUSTR_24,
275
    THUSTR_25,
276
    THUSTR_26,
277
    THUSTR_27,
278
    THUSTR_28,
279
    THUSTR_29,
280
    THUSTR_30,
281
    THUSTR_31,
282
    THUSTR_32
283
};
284
 
285
 
286
const char*	shiftxform;
287
 
288
const char french_shiftxform[] =
289
{
290
    0,
291
    1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
292
    11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
293
    21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
294
    31,
295
    ' ', '!', '"', '#', '$', '%', '&',
296
    '"', // shift-'
297
    '(', ')', '*', '+',
298
    '?', // shift-,
299
    '_', // shift--
300
    '>', // shift-.
301
    '?', // shift-/
302
    '0', // shift-0
303
    '1', // shift-1
304
    '2', // shift-2
305
    '3', // shift-3
306
    '4', // shift-4
307
    '5', // shift-5
308
    '6', // shift-6
309
    '7', // shift-7
310
    '8', // shift-8
311
    '9', // shift-9
312
    '/',
313
    '.', // shift-;
314
    '<',
315
    '+', // shift-=
316
    '>', '?', '@',
317
    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
318
    'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
319
    '[', // shift-[
320
    '!', // shift-backslash - OH MY GOD DOES WATCOM SUCK
321
    ']', // shift-]
322
    '"', '_',
323
    '\'', // shift-`
324
    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
325
    'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
326
    '{', '|', '}', '~', 127
327
 
328
};
329
 
330
const char english_shiftxform[] =
331
{
332
 
333
    0,
334
    1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
335
    11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
336
    21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
337
    31,
338
    ' ', '!', '"', '#', '$', '%', '&',
339
    '"', // shift-'
340
    '(', ')', '*', '+',
341
    '<', // shift-,
342
    '_', // shift--
343
    '>', // shift-.
344
    '?', // shift-/
345
    ')', // shift-0
346
    '!', // shift-1
347
    '@', // shift-2
348
    '#', // shift-3
349
    '$', // shift-4
350
    '%', // shift-5
351
    '^', // shift-6
352
    '&', // shift-7
353
    '*', // shift-8
354
    '(', // shift-9
355
    ':',
356
    ':', // shift-;
357
    '<',
358
    '+', // shift-=
359
    '>', '?', '@',
360
    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
361
    'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
362
    '[', // shift-[
363
    '!', // shift-backslash - OH MY GOD DOES WATCOM SUCK
364
    ']', // shift-]
365
    '"', '_',
366
    '\'', // shift-`
367
    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
368
    'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
369
    '{', '|', '}', '~', 127
370
};
371
 
372
char frenchKeyMap[128]=
373
{
374
    0,
375
    1,2,3,4,5,6,7,8,9,10,
376
    11,12,13,14,15,16,17,18,19,20,
377
    21,22,23,24,25,26,27,28,29,30,
378
    31,
379
    ' ','!','"','#','$','%','&','%','(',')','*','+',';','-',':','!',
380
    '0','1','2','3','4','5','6','7','8','9',':','M','<','=','>','?',
381
    '@','Q','B','C','D','E','F','G','H','I','J','K','L',',','N','O',
382
    'P','A','R','S','T','U','V','Z','X','Y','W','^','\\','$','^','_',
383
    '@','Q','B','C','D','E','F','G','H','I','J','K','L',',','N','O',
384
    'P','A','R','S','T','U','V','Z','X','Y','W','^','\\','$','^',127
385
};
386
 
387
char ForeignTranslation(unsigned char ch)
388
{
389
    return ch < 128 ? frenchKeyMap[ch] : ch;
390
}
391
 
392
void HU_Init(void)
393
{
394
 
395
    int		i;
396
    int		j;
397
    char	buffer[9];
398
 
399
    if (french)
400
	shiftxform = french_shiftxform;
401
    else
402
	shiftxform = english_shiftxform;
403
 
404
    // load the heads-up font
405
    j = HU_FONTSTART;
406
    for (i=0;i
407
    {
408
	sprintf(buffer, "STCFN%.3d", j++);
409
	hu_font[i] = (patch_t *) W_CacheLumpName(buffer, PU_STATIC);
410
    }
411
 
412
}
413
 
414
void HU_Stop(void)
415
{
416
    headsupactive = false;
417
}
418
 
419
void HU_Start(void)
420
{
421
 
422
    int		i;
423
    char*	s;
424
 
425
    if (headsupactive)
426
	HU_Stop();
427
 
428
    plr = &players[consoleplayer];
429
    message_on = false;
430
    message_dontfuckwithme = false;
431
    message_nottobefuckedwith = false;
432
    chat_on = false;
433
 
434
    // create the message widget
435
    HUlib_initSText(&w_message,
436
		    HU_MSGX, HU_MSGY, HU_MSGHEIGHT,
437
		    hu_font,
438
		    HU_FONTSTART, &message_on);
439
 
440
    // create the map title widget
441
    HUlib_initTextLine(&w_title,
442
		       HU_TITLEX, HU_TITLEY,
443
		       hu_font,
444
		       HU_FONTSTART);
445
 
446
    switch ( gamemode )
447
    {
448
      case shareware:
449
      case registered:
450
      case retail:
451
	s = HU_TITLE;
452
	break;
453
 
454
/* FIXME
455
      case pack_plut:
456
	s = HU_TITLEP;
457
	break;
458
      case pack_tnt:
459
	s = HU_TITLET;
460
	break;
461
*/
462
 
463
      case commercial:
464
      default:
465
	 s = HU_TITLE2;
466
	 break;
467
    }
468
 
469
    while (*s)
470
	HUlib_addCharToTextLine(&w_title, *(s++));
471
 
472
    // create the chat widget
473
    HUlib_initIText(&w_chat,
474
		    HU_INPUTX, HU_INPUTY,
475
		    hu_font,
476
		    HU_FONTSTART, &chat_on);
477
 
478
    // create the inputbuffer widgets
479
    for (i=0 ; i
480
	HUlib_initIText(&w_inputbuffer[i], 0, 0, 0, 0, &always_off);
481
 
482
    headsupactive = true;
483
 
484
}
485
 
486
void HU_Drawer(void)
487
{
488
 
489
    HUlib_drawSText(&w_message);
490
    HUlib_drawIText(&w_chat);
491
    if (automapactive)
492
	HUlib_drawTextLine(&w_title, false);
493
 
494
}
495
 
496
void HU_Erase(void)
497
{
498
 
499
    HUlib_eraseSText(&w_message);
500
    HUlib_eraseIText(&w_chat);
501
    HUlib_eraseTextLine(&w_title);
502
 
503
}
504
 
505
void HU_Ticker(void)
506
{
507
 
508
    int i, rc;
509
    char c;
510
 
511
    // tick down message counter if message is up
512
    if (message_counter && !--message_counter)
513
    {
514
	message_on = false;
515
	message_nottobefuckedwith = false;
516
    }
517
 
518
    if (showMessages || message_dontfuckwithme)
519
    {
520
 
521
	// display message if necessary
522
	if ((plr->message && !message_nottobefuckedwith)
523
	    || (plr->message && message_dontfuckwithme))
524
	{
525
	    HUlib_addMessageToSText(&w_message, 0, plr->message);
526
	    plr->message = 0;
527
	    message_on = true;
528
	    message_counter = HU_MSGTIMEOUT;
529
	    message_nottobefuckedwith = message_dontfuckwithme;
530
	    message_dontfuckwithme = 0;
531
	}
532
 
533
    } // else message_on = false;
534
 
535
    // check for incoming chat characters
536
    if (netgame)
537
    {
538
	for (i=0 ; i
539
	{
540
	    if (!playeringame[i])
541
		continue;
542
	    if (i != consoleplayer
543
		&& (c = players[i].cmd.chatchar))
544
	    {
545
		if (c <= HU_BROADCAST)
546
		    chat_dest[i] = c;
547
		else
548
		{
549
		    if (c >= 'a' && c <= 'z')
550
			c = (char) shiftxform[(unsigned char) c];
551
		    rc = HUlib_keyInIText(&w_inputbuffer[i], c);
552
		    if (rc && c == KEY_ENTER)
553
		    {
554
			if (w_inputbuffer[i].l.len
555
			    && (chat_dest[i] == consoleplayer+1
556
				|| chat_dest[i] == HU_BROADCAST))
557
			{
558
			    HUlib_addMessageToSText(&w_message,
559
						    player_names[i],
560
						    w_inputbuffer[i].l.l);
561
 
562
			    message_nottobefuckedwith = true;
563
			    message_on = true;
564
			    message_counter = HU_MSGTIMEOUT;
565
			    if ( gamemode == commercial )
566
			      S_StartSound(0, sfx_radio);
567
			    else
568
			      S_StartSound(0, sfx_tink);
569
			}
570
			HUlib_resetIText(&w_inputbuffer[i]);
571
		    }
572
		}
573
		players[i].cmd.chatchar = 0;
574
	    }
575
	}
576
    }
577
 
578
}
579
 
580
#define QUEUESIZE		128
581
 
582
static char	chatchars[QUEUESIZE];
583
static int	head = 0;
584
static int	tail = 0;
585
 
586
 
587
void HU_queueChatChar(char c)
588
{
589
    if (((head + 1) & (QUEUESIZE-1)) == tail)
590
    {
591
	plr->message = HUSTR_MSGU;
592
    }
593
    else
594
    {
595
	chatchars[head] = c;
596
	head = (head + 1) & (QUEUESIZE-1);
597
    }
598
}
599
 
600
char HU_dequeueChatChar(void)
601
{
602
    char c;
603
 
604
    if (head != tail)
605
    {
606
	c = chatchars[tail];
607
	tail = (tail + 1) & (QUEUESIZE-1);
608
    }
609
    else
610
    {
611
	c = 0;
612
    }
613
 
614
    return c;
615
}
616
 
617
boolean HU_Responder(event_t *ev)
618
{
619
 
620
    static char		lastmessage[HU_MAXLINELENGTH+1];
621
    char*		macromessage;
622
    boolean		eatkey = false;
623
    static boolean	shiftdown = false;
624
    static boolean	altdown = false;
625
    unsigned char 	c;
626
    int			i;
627
    int			numplayers;
628
 
629
    static char		destination_keys[MAXPLAYERS] =
630
    {
631
	HUSTR_KEYGREEN,
632
	HUSTR_KEYINDIGO,
633
	HUSTR_KEYBROWN,
634
	HUSTR_KEYRED
635
    };
636
 
637
    static int		num_nobrainers = 0;
638
 
639
    numplayers = 0;
640
    for (i=0 ; i
641
	numplayers += playeringame[i];
642
 
643
    if (ev->data1 == KEY_RSHIFT)
644
    {
645
	shiftdown = ev->type == ev_keydown;
646
	return false;
647
    }
648
    else if (ev->data1 == KEY_RALT || ev->data1 == KEY_LALT)
649
    {
650
	altdown = ev->type == ev_keydown;
651
	return false;
652
    }
653
 
654
    if (ev->type != ev_keydown)
655
	return false;
656
 
657
    if (!chat_on)
658
    {
659
	if (ev->data1 == HU_MSGREFRESH)
660
	{
661
	    message_on = true;
662
	    message_counter = HU_MSGTIMEOUT;
663
	    eatkey = true;
664
	}
665
	else if (netgame && ev->data1 == HU_INPUTTOGGLE)
666
	{
667
	    eatkey = chat_on = true;
668
	    HUlib_resetIText(&w_chat);
669
	    HU_queueChatChar(HU_BROADCAST);
670
	}
671
	else if (netgame && numplayers > 2)
672
	{
673
	    for (i=0; i
674
	    {
675
		if (ev->data1 == destination_keys[i])
676
		{
677
		    if (playeringame[i] && i!=consoleplayer)
678
		    {
679
			eatkey = chat_on = true;
680
			HUlib_resetIText(&w_chat);
681
			HU_queueChatChar(i+1);
682
			break;
683
		    }
684
		    else if (i == consoleplayer)
685
		    {
686
			num_nobrainers++;
687
			if (num_nobrainers < 3)
688
			    plr->message = HUSTR_TALKTOSELF1;
689
			else if (num_nobrainers < 6)
690
			    plr->message = HUSTR_TALKTOSELF2;
691
			else if (num_nobrainers < 9)
692
			    plr->message = HUSTR_TALKTOSELF3;
693
			else if (num_nobrainers < 32)
694
			    plr->message = HUSTR_TALKTOSELF4;
695
			else
696
			    plr->message = HUSTR_TALKTOSELF5;
697
		    }
698
		}
699
	    }
700
	}
701
    }
702
    else
703
    {
704
	c = ev->data1;
705
	// send a macro
706
	if (altdown)
707
	{
708
	    c = c - '0';
709
	    if (c > 9)
710
		return false;
711
	    // fprintf(stderr, "got here\n");
712
	    macromessage = chat_macros[c];
713
 
714
	    // kill last message with a '\n'
715
	    HU_queueChatChar(KEY_ENTER); // DEBUG!!!
716
 
717
	    // send the macro message
718
	    while (*macromessage)
719
		HU_queueChatChar(*macromessage++);
720
	    HU_queueChatChar(KEY_ENTER);
721
 
722
	    // leave chat mode and notify that it was sent
723
	    chat_on = false;
724
	    strcpy(lastmessage, chat_macros[c]);
725
	    plr->message = lastmessage;
726
	    eatkey = true;
727
	}
728
	else
729
	{
730
	    if (french)
731
		c = ForeignTranslation(c);
732
	    if (shiftdown || (c >= 'a' && c <= 'z'))
733
		c = shiftxform[c];
734
	    eatkey = HUlib_keyInIText(&w_chat, c);
735
	    if (eatkey)
736
	    {
737
		// static unsigned char buf[20]; // DEBUG
738
		HU_queueChatChar(c);
739
 
740
		// sprintf(buf, "KEY: %d => %d", ev->data1, c);
741
		//      plr->message = buf;
742
	    }
743
	    if (c == KEY_ENTER)
744
	    {
745
		chat_on = false;
746
		if (w_chat.l.len)
747
		{
748
		    strcpy(lastmessage, w_chat.l.l);
749
		    plr->message = lastmessage;
750
		}
751
	    }
752
	    else if (c == KEY_ESCAPE)
753
		chat_on = false;
754
	}
755
    }
756
 
757
    return eatkey;
758
 
759
}