set the include directory
[AROS-Contrib.git] / Games / Doom / hu_stuff.c
blob7029d07425a33a6cdd9a2c883974ca2556853d3c
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.
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.
17 // $Log$
18 // Revision 1.1 2000/02/29 18:21:04 stegerg
19 // Doom port based on ADoomPPC. Read README.AROS!
22 // DESCRIPTION: Heads-up displays
24 //-----------------------------------------------------------------------------
26 static const char
27 rcsid[] = "$Id$";
29 #include <ctype.h>
31 #include "doomdef.h"
33 #include "z_zone.h"
35 #include "m_swap.h"
37 #include "hu_stuff.h"
38 #include "hu_lib.h"
39 #include "w_wad.h"
41 #include "s_sound.h"
43 #include "doomstat.h"
45 // Data.
46 #include "dstrings.h"
47 #include "sounds.h"
50 // Locally used constants, shortcuts.
52 #define HU_TITLE (mapnames[(gameepisode-1)*9+gamemap-1])
53 #define HU_TITLE2 (mapnames2[gamemap-1])
54 #define HU_TITLEP (mapnamesp[gamemap-1])
55 #define HU_TITLET (mapnamest[gamemap-1])
56 #define HU_TITLEHEIGHT 1
57 #define HU_TITLEX 0
58 //#define HU_TITLEY (167 - SWAPSHORT(hu_font[0]->height))
59 #define HU_TITLEY (SCREENHEIGHT-(200-(167 - SWAPSHORT(hu_font[0]->height))))
61 #define HU_INPUTTOGGLE 't'
62 #define HU_INPUTX HU_MSGX
63 #define HU_INPUTY (HU_MSGY + HU_MSGHEIGHT*(SWAPSHORT(hu_font[0]->height) +1))
64 #define HU_INPUTWIDTH 64
65 #define HU_INPUTHEIGHT 1
69 char* chat_macros[] =
71 HUSTR_CHATMACRO0,
72 HUSTR_CHATMACRO1,
73 HUSTR_CHATMACRO2,
74 HUSTR_CHATMACRO3,
75 HUSTR_CHATMACRO4,
76 HUSTR_CHATMACRO5,
77 HUSTR_CHATMACRO6,
78 HUSTR_CHATMACRO7,
79 HUSTR_CHATMACRO8,
80 HUSTR_CHATMACRO9
83 char* player_names[] =
85 HUSTR_PLRGREEN,
86 HUSTR_PLRINDIGO,
87 HUSTR_PLRBROWN,
88 HUSTR_PLRRED
92 char chat_char; // remove later.
93 static player_t* plr;
94 patch_t* hu_font[HU_FONTSIZE];
95 static hu_textline_t w_title;
96 boolean chat_on;
97 static hu_itext_t w_chat;
98 static boolean always_off = false;
99 static char chat_dest[MAXPLAYERS];
100 static hu_itext_t w_inputbuffer[MAXPLAYERS];
102 static boolean message_on;
103 boolean message_dontfuckwithme;
104 static boolean message_nottobefuckedwith;
106 static hu_stext_t w_message;
107 static int message_counter;
109 extern int showMessages;
110 extern boolean automapactive;
112 static boolean headsupactive = false;
115 // Builtin map names.
116 // The actual names can be found in DStrings.h.
119 char* mapnames[] = // DOOM shareware/registered/retail (Ultimate) names.
122 HUSTR_E1M1,
123 HUSTR_E1M2,
124 HUSTR_E1M3,
125 HUSTR_E1M4,
126 HUSTR_E1M5,
127 HUSTR_E1M6,
128 HUSTR_E1M7,
129 HUSTR_E1M8,
130 HUSTR_E1M9,
132 HUSTR_E2M1,
133 HUSTR_E2M2,
134 HUSTR_E2M3,
135 HUSTR_E2M4,
136 HUSTR_E2M5,
137 HUSTR_E2M6,
138 HUSTR_E2M7,
139 HUSTR_E2M8,
140 HUSTR_E2M9,
142 HUSTR_E3M1,
143 HUSTR_E3M2,
144 HUSTR_E3M3,
145 HUSTR_E3M4,
146 HUSTR_E3M5,
147 HUSTR_E3M6,
148 HUSTR_E3M7,
149 HUSTR_E3M8,
150 HUSTR_E3M9,
152 HUSTR_E4M1,
153 HUSTR_E4M2,
154 HUSTR_E4M3,
155 HUSTR_E4M4,
156 HUSTR_E4M5,
157 HUSTR_E4M6,
158 HUSTR_E4M7,
159 HUSTR_E4M8,
160 HUSTR_E4M9,
162 "NEWLEVEL",
163 "NEWLEVEL",
164 "NEWLEVEL",
165 "NEWLEVEL",
166 "NEWLEVEL",
167 "NEWLEVEL",
168 "NEWLEVEL",
169 "NEWLEVEL",
170 "NEWLEVEL"
173 char* mapnames2[] = // DOOM 2 map names.
175 HUSTR_1,
176 HUSTR_2,
177 HUSTR_3,
178 HUSTR_4,
179 HUSTR_5,
180 HUSTR_6,
181 HUSTR_7,
182 HUSTR_8,
183 HUSTR_9,
184 HUSTR_10,
185 HUSTR_11,
187 HUSTR_12,
188 HUSTR_13,
189 HUSTR_14,
190 HUSTR_15,
191 HUSTR_16,
192 HUSTR_17,
193 HUSTR_18,
194 HUSTR_19,
195 HUSTR_20,
197 HUSTR_21,
198 HUSTR_22,
199 HUSTR_23,
200 HUSTR_24,
201 HUSTR_25,
202 HUSTR_26,
203 HUSTR_27,
204 HUSTR_28,
205 HUSTR_29,
206 HUSTR_30,
207 HUSTR_31,
208 HUSTR_32
212 char* mapnamesp[] = // Plutonia WAD map names.
214 PHUSTR_1,
215 PHUSTR_2,
216 PHUSTR_3,
217 PHUSTR_4,
218 PHUSTR_5,
219 PHUSTR_6,
220 PHUSTR_7,
221 PHUSTR_8,
222 PHUSTR_9,
223 PHUSTR_10,
224 PHUSTR_11,
226 PHUSTR_12,
227 PHUSTR_13,
228 PHUSTR_14,
229 PHUSTR_15,
230 PHUSTR_16,
231 PHUSTR_17,
232 PHUSTR_18,
233 PHUSTR_19,
234 PHUSTR_20,
236 PHUSTR_21,
237 PHUSTR_22,
238 PHUSTR_23,
239 PHUSTR_24,
240 PHUSTR_25,
241 PHUSTR_26,
242 PHUSTR_27,
243 PHUSTR_28,
244 PHUSTR_29,
245 PHUSTR_30,
246 PHUSTR_31,
247 PHUSTR_32
251 char *mapnamest[] = // TNT WAD map names.
253 THUSTR_1,
254 THUSTR_2,
255 THUSTR_3,
256 THUSTR_4,
257 THUSTR_5,
258 THUSTR_6,
259 THUSTR_7,
260 THUSTR_8,
261 THUSTR_9,
262 THUSTR_10,
263 THUSTR_11,
265 THUSTR_12,
266 THUSTR_13,
267 THUSTR_14,
268 THUSTR_15,
269 THUSTR_16,
270 THUSTR_17,
271 THUSTR_18,
272 THUSTR_19,
273 THUSTR_20,
275 THUSTR_21,
276 THUSTR_22,
277 THUSTR_23,
278 THUSTR_24,
279 THUSTR_25,
280 THUSTR_26,
281 THUSTR_27,
282 THUSTR_28,
283 THUSTR_29,
284 THUSTR_30,
285 THUSTR_31,
286 THUSTR_32
290 const char* shiftxform;
292 const char french_shiftxform[] =
295 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
296 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
297 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
299 ' ', '!', '"', '#', '$', '%', '&',
300 '"', // shift-'
301 '(', ')', '*', '+',
302 '?', // shift-,
303 '_', // shift--
304 '>', // shift-.
305 '?', // shift-/
306 '0', // shift-0
307 '1', // shift-1
308 '2', // shift-2
309 '3', // shift-3
310 '4', // shift-4
311 '5', // shift-5
312 '6', // shift-6
313 '7', // shift-7
314 '8', // shift-8
315 '9', // shift-9
316 '/',
317 '.', // shift-;
318 '<',
319 '+', // shift-=
320 '>', '?', '@',
321 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
322 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
323 '[', // shift-[
324 '!', // shift-backslash - OH MY GOD DOES WATCOM SUCK
325 ']', // shift-]
326 '"', '_',
327 '\'', // shift-`
328 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
329 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
330 '{', '|', '}', '~', 127
334 const char english_shiftxform[] =
338 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
339 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
340 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
342 ' ', '!', '"', '#', '$', '%', '&',
343 '"', // shift-'
344 '(', ')', '*', '+',
345 '<', // shift-,
346 '_', // shift--
347 '>', // shift-.
348 '?', // shift-/
349 ')', // shift-0
350 '!', // shift-1
351 '@', // shift-2
352 '#', // shift-3
353 '$', // shift-4
354 '%', // shift-5
355 '^', // shift-6
356 '&', // shift-7
357 '*', // shift-8
358 '(', // shift-9
359 ':',
360 ':', // shift-;
361 '<',
362 '+', // shift-=
363 '>', '?', '@',
364 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
365 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
366 '[', // shift-[
367 '!', // shift-backslash - OH MY GOD DOES WATCOM SUCK
368 ']', // shift-]
369 '"', '_',
370 '\'', // shift-`
371 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
372 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
373 '{', '|', '}', '~', 127
376 char frenchKeyMap[128]=
379 1,2,3,4,5,6,7,8,9,10,
380 11,12,13,14,15,16,17,18,19,20,
381 21,22,23,24,25,26,27,28,29,30,
383 ' ','!','"','#','$','%','&','%','(',')','*','+',';','-',':','!',
384 '0','1','2','3','4','5','6','7','8','9',':','M','<','=','>','?',
385 '@','Q','B','C','D','E','F','G','H','I','J','K','L',',','N','O',
386 'P','A','R','S','T','U','V','Z','X','Y','W','^','\\','$','^','_',
387 '@','Q','B','C','D','E','F','G','H','I','J','K','L',',','N','O',
388 'P','A','R','S','T','U','V','Z','X','Y','W','^','\\','$','^',127
391 char ForeignTranslation(unsigned char ch)
393 return ch < 128 ? frenchKeyMap[ch] : ch;
396 void HU_Init(void)
399 int i;
400 int j;
401 char buffer[9];
403 if (language==french)
404 shiftxform = french_shiftxform;
405 else
406 shiftxform = english_shiftxform;
408 // load the heads-up font
409 j = HU_FONTSTART;
410 for (i=0;i<HU_FONTSIZE;i++)
412 sprintf(buffer, "STCFN%.3d", j++);
413 hu_font[i] = (patch_t *) W_CacheLumpName(buffer, PU_STATIC);
418 void HU_Stop(void)
420 headsupactive = false;
423 void HU_Start(void)
426 int i;
427 char* s;
429 if (headsupactive)
430 HU_Stop();
432 plr = &players[consoleplayer];
433 message_on = false;
434 message_dontfuckwithme = false;
435 message_nottobefuckedwith = false;
436 chat_on = false;
438 // create the message widget
439 HUlib_initSText(&w_message,
440 HU_MSGX, HU_MSGY, HU_MSGHEIGHT,
441 hu_font,
442 HU_FONTSTART, &message_on);
444 // create the map title widget
445 HUlib_initTextLine(&w_title,
446 HU_TITLEX, HU_TITLEY,
447 hu_font,
448 HU_FONTSTART);
450 switch ( gamemode )
452 case shareware:
453 case registered:
454 case retail:
455 s = HU_TITLE;
456 break;
458 /* FIXME
459 case pack_plut:
460 s = HU_TITLEP;
461 break;
462 case pack_tnt:
463 s = HU_TITLET;
464 break;
467 case commercial:
468 default:
469 s = HU_TITLE2;
470 break;
473 while (*s)
474 HUlib_addCharToTextLine(&w_title, *(s++));
476 // create the chat widget
477 HUlib_initIText(&w_chat,
478 HU_INPUTX, HU_INPUTY,
479 hu_font,
480 HU_FONTSTART, &chat_on);
482 // create the inputbuffer widgets
483 for (i=0 ; i<MAXPLAYERS ; i++)
484 HUlib_initIText(&w_inputbuffer[i], 0, 0, 0, 0, &always_off);
486 headsupactive = true;
490 void HU_Drawer(void)
493 HUlib_drawSText(&w_message);
494 HUlib_drawIText(&w_chat);
495 if (automapactive)
496 HUlib_drawTextLine(&w_title, false);
500 void HU_Erase(void)
503 HUlib_eraseSText(&w_message);
504 HUlib_eraseIText(&w_chat);
505 HUlib_eraseTextLine(&w_title);
509 void HU_Ticker(void)
512 int i, rc;
513 char c;
515 // tick down message counter if message is up
516 if (message_counter && !--message_counter)
518 message_on = false;
519 message_nottobefuckedwith = false;
522 if (showMessages || message_dontfuckwithme)
525 // display message if necessary
526 if ((plr->message && !message_nottobefuckedwith)
527 || (plr->message && message_dontfuckwithme))
529 HUlib_addMessageToSText(&w_message, 0, plr->message);
530 plr->message = 0;
531 message_on = true;
532 message_counter = HU_MSGTIMEOUT;
533 message_nottobefuckedwith = message_dontfuckwithme;
534 message_dontfuckwithme = 0;
537 } // else message_on = false;
539 // check for incoming chat characters
540 if (netgame)
542 for (i=0 ; i<MAXPLAYERS; i++)
544 if (!playeringame[i])
545 continue;
546 if (i != consoleplayer
547 && (c = players[i].cmd.chatchar))
549 if (c <= HU_BROADCAST)
550 chat_dest[i] = c;
551 else
553 if (c >= 'a' && c <= 'z')
554 c = (char) shiftxform[(unsigned char) c];
555 rc = HUlib_keyInIText(&w_inputbuffer[i], c);
556 if (rc && c == KEY_ENTER)
558 if (w_inputbuffer[i].l.len
559 && (chat_dest[i] == consoleplayer+1
560 || chat_dest[i] == HU_BROADCAST))
562 HUlib_addMessageToSText(&w_message,
563 player_names[i],
564 w_inputbuffer[i].l.l);
566 message_nottobefuckedwith = true;
567 message_on = true;
568 message_counter = HU_MSGTIMEOUT;
569 if ( gamemode == commercial )
570 S_StartSound(0, sfx_radio);
571 else
572 S_StartSound(0, sfx_tink);
574 HUlib_resetIText(&w_inputbuffer[i]);
577 players[i].cmd.chatchar = 0;
584 #define QUEUESIZE 128
586 static char chatchars[QUEUESIZE];
587 static int head = 0;
588 static int tail = 0;
591 void HU_queueChatChar(char c)
593 if (((head + 1) & (QUEUESIZE-1)) == tail)
595 plr->message = HUSTR_MSGU;
597 else
599 chatchars[head] = c;
600 head = (head + 1) & (QUEUESIZE-1);
604 char HU_dequeueChatChar(void)
606 char c;
608 if (head != tail)
610 c = chatchars[tail];
611 tail = (tail + 1) & (QUEUESIZE-1);
613 else
615 c = 0;
618 return c;
621 boolean HU_Responder(event_t *ev)
624 static char lastmessage[HU_MAXLINELENGTH+1];
625 char* macromessage;
626 boolean eatkey = false;
627 static boolean shiftdown = false;
628 static boolean altdown = false;
629 unsigned char c;
630 int i;
631 int numplayers;
633 static char destination_keys[MAXPLAYERS] =
635 HUSTR_KEYGREEN,
636 HUSTR_KEYINDIGO,
637 HUSTR_KEYBROWN,
638 HUSTR_KEYRED
641 static int num_nobrainers = 0;
643 numplayers = 0;
644 for (i=0 ; i<MAXPLAYERS ; i++)
645 numplayers += playeringame[i];
647 if (ev->data1 == KEY_RSHIFT)
649 shiftdown = ev->type == ev_keydown;
650 return false;
652 else if (ev->data1 == KEY_RALT || ev->data1 == KEY_LALT)
654 altdown = ev->type == ev_keydown;
655 return false;
658 if (ev->type != ev_keydown)
659 return false;
661 if (!chat_on)
663 if (ev->data1 == HU_MSGREFRESH)
665 message_on = true;
666 message_counter = HU_MSGTIMEOUT;
667 eatkey = true;
669 else if (netgame && ev->data1 == HU_INPUTTOGGLE)
671 eatkey = chat_on = true;
672 HUlib_resetIText(&w_chat);
673 HU_queueChatChar(HU_BROADCAST);
675 else if (netgame && numplayers > 2)
677 for (i=0; i<MAXPLAYERS ; i++)
679 if (ev->data1 == destination_keys[i])
681 if (playeringame[i] && i!=consoleplayer)
683 eatkey = chat_on = true;
684 HUlib_resetIText(&w_chat);
685 HU_queueChatChar(i+1);
686 break;
688 else if (i == consoleplayer)
690 num_nobrainers++;
691 if (num_nobrainers < 3)
692 plr->message = HUSTR_TALKTOSELF1;
693 else if (num_nobrainers < 6)
694 plr->message = HUSTR_TALKTOSELF2;
695 else if (num_nobrainers < 9)
696 plr->message = HUSTR_TALKTOSELF3;
697 else if (num_nobrainers < 32)
698 plr->message = HUSTR_TALKTOSELF4;
699 else
700 plr->message = HUSTR_TALKTOSELF5;
706 else
708 c = ev->data1;
709 // send a macro
710 if (altdown)
712 c = c - '0';
713 if (c > 9)
714 return false;
715 // fprintf(stderr, "got here\n");
716 macromessage = chat_macros[c];
718 // kill last message with a '\n'
719 HU_queueChatChar(KEY_ENTER); // DEBUG!!!
721 // send the macro message
722 while (*macromessage)
723 HU_queueChatChar(*macromessage++);
724 HU_queueChatChar(KEY_ENTER);
726 // leave chat mode and notify that it was sent
727 chat_on = false;
728 strcpy(lastmessage, chat_macros[c]);
729 plr->message = lastmessage;
730 eatkey = true;
732 else
734 if (language==french)
735 c = ForeignTranslation(c);
736 if (shiftdown || (c >= 'a' && c <= 'z'))
737 c = shiftxform[c];
738 eatkey = HUlib_keyInIText(&w_chat, c);
739 if (eatkey)
741 // static unsigned char buf[20]; // DEBUG
742 HU_queueChatChar(c);
744 // sprintf(buf, "KEY: %d => %d", ev->data1, c);
745 // plr->message = buf;
747 if (c == KEY_ENTER)
749 chat_on = false;
750 if (w_chat.l.len)
752 strcpy(lastmessage, w_chat.l.l);
753 plr->message = lastmessage;
756 else if (c == KEY_ESCAPE)
757 chat_on = false;
761 return eatkey;