]> git.lizzy.rs Git - plan9front.git/blob - sys/src/games/doom/hu_stuff.c
bring games/swar from 1ed sources.
[plan9front.git] / sys / src / games / doom / hu_stuff.c
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 <ctype.h>
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 void HU_Init(void)
287 {
288
289     int         i;
290     int         j;
291     char        buffer[9];
292
293     // load the heads-up font
294     j = HU_FONTSTART;
295     for (i=0;i<HU_FONTSIZE;i++)
296     {
297         sprintf(buffer, "STCFN%.3d", j++);
298         hu_font[i] = (patch_t *) W_CacheLumpName(buffer, PU_STATIC);
299     }
300
301 }
302
303 void HU_Stop(void)
304 {
305     headsupactive = false;
306 }
307
308 void HU_Start(void)
309 {
310
311     int         i;
312     char*       s;
313
314     if (headsupactive)
315         HU_Stop();
316
317     plr = &players[consoleplayer];
318     message_on = false;
319     message_dontfuckwithme = false;
320     message_nottobefuckedwith = false;
321     chat_on = false;
322
323     // create the message widget
324     HUlib_initSText(&w_message,
325                     HU_MSGX, HU_MSGY, HU_MSGHEIGHT,
326                     hu_font,
327                     HU_FONTSTART, &message_on);
328
329     // create the map title widget
330     HUlib_initTextLine(&w_title,
331                        HU_TITLEX, HU_TITLEY,
332                        hu_font,
333                        HU_FONTSTART);
334     
335     switch ( gamemode )
336     {
337       case shareware:
338       case registered:
339       case retail:
340         s = HU_TITLE;
341         break;
342
343 /* FIXME
344       case pack_plut:
345         s = HU_TITLEP;
346         break;
347       case pack_tnt:
348         s = HU_TITLET;
349         break;
350 */
351         
352       case commercial:
353       default:
354          s = HU_TITLE2;
355          break;
356     }
357     
358     while (*s)
359         HUlib_addCharToTextLine(&w_title, *(s++));
360
361     // create the chat widget
362     HUlib_initIText(&w_chat,
363                     HU_INPUTX, HU_INPUTY,
364                     hu_font,
365                     HU_FONTSTART, &chat_on);
366
367     // create the inputbuffer widgets
368     for (i=0 ; i<MAXPLAYERS ; i++)
369         HUlib_initIText(&w_inputbuffer[i], 0, 0, 0, 0, &always_off);
370
371     headsupactive = true;
372
373 }
374
375 void HU_Drawer(void)
376 {
377
378     HUlib_drawSText(&w_message);
379     HUlib_drawIText(&w_chat);
380     if (automapactive)
381         HUlib_drawTextLine(&w_title, false);
382
383 }
384
385 void HU_Erase(void)
386 {
387
388     HUlib_eraseSText(&w_message);
389     HUlib_eraseIText(&w_chat);
390     HUlib_eraseTextLine(&w_title);
391
392 }
393
394 void HU_Ticker(void)
395 {
396
397     int i, rc;
398     char c;
399
400     // tick down message counter if message is up
401     if (message_counter && !--message_counter)
402     {
403         message_on = false;
404         message_nottobefuckedwith = false;
405     }
406
407     if (showMessages || message_dontfuckwithme)
408     {
409
410         // display message if necessary
411         if ((plr->message && !message_nottobefuckedwith)
412             || (plr->message && message_dontfuckwithme))
413         {
414             HUlib_addMessageToSText(&w_message, 0, plr->message);
415             plr->message = 0;
416             message_on = true;
417             message_counter = HU_MSGTIMEOUT;
418             message_nottobefuckedwith = message_dontfuckwithme;
419             message_dontfuckwithme = 0;
420         }
421
422     } // else message_on = false;
423
424     // check for incoming chat characters
425     if (netgame)
426     {
427         for (i=0 ; i<MAXPLAYERS; i++)
428         {
429             if (!playeringame[i])
430                 continue;
431             if (i != consoleplayer
432                 && (c = players[i].cmd.chatchar))
433             {
434                 if (c <= HU_BROADCAST)
435                     chat_dest[i] = c;
436                 else
437                 {
438                     rc = HUlib_keyInIText(&w_inputbuffer[i], c);
439                     if (rc && c == KEY_ENTER)
440                     {
441                         if (w_inputbuffer[i].l.len
442                             && (chat_dest[i] == consoleplayer+1
443                                 || chat_dest[i] == HU_BROADCAST))
444                         {
445                             HUlib_addMessageToSText(&w_message,
446                                                     player_names[i],
447                                                     w_inputbuffer[i].l.l);
448                             
449                             message_nottobefuckedwith = true;
450                             message_on = true;
451                             message_counter = HU_MSGTIMEOUT;
452                             if ( gamemode == commercial )
453                               S_StartSound(0, sfx_radio);
454                             else
455                               S_StartSound(0, sfx_tink);
456                         }
457                         HUlib_resetIText(&w_inputbuffer[i]);
458                     }
459                 }
460                 players[i].cmd.chatchar = 0;
461             }
462         }
463     }
464
465 }
466
467 #define QUEUESIZE               128
468
469 static char     chatchars[QUEUESIZE];
470 static int      head = 0;
471 static int      tail = 0;
472
473
474 void HU_queueChatChar(char c)
475 {
476     if (((head + 1) & (QUEUESIZE-1)) == tail)
477     {
478         plr->message = HUSTR_MSGU;
479     }
480     else
481     {
482         chatchars[head] = c;
483         head = (head + 1) & (QUEUESIZE-1);
484     }
485 }
486
487 char HU_dequeueChatChar(void)
488 {
489     char c;
490
491     if (head != tail)
492     {
493         c = chatchars[tail];
494         tail = (tail + 1) & (QUEUESIZE-1);
495     }
496     else
497     {
498         c = 0;
499     }
500
501     return c;
502 }
503
504 boolean HU_Responder(event_t *ev)
505 {
506
507     static char         lastmessage[HU_MAXLINELENGTH+1];
508     char*               macromessage;
509     boolean             eatkey = false;
510     static boolean      altdown = false;
511     int                 c;
512     int                 i;
513     int                 numplayers;
514     
515     static char         destination_keys[MAXPLAYERS] =
516     {
517         HUSTR_KEYGREEN,
518         HUSTR_KEYINDIGO,
519         HUSTR_KEYBROWN,
520         HUSTR_KEYRED
521     };
522     
523     static int          num_nobrainers = 0;
524
525     numplayers = 0;
526     for (i=0 ; i<MAXPLAYERS ; i++)
527         numplayers += playeringame[i];
528
529     switch(ev->type){
530     case ev_keydown:
531     case ev_keyup:
532         if (ev->data1 == KEY_RALT || ev->data1 == KEY_LALT)
533         {
534         altdown = ev->type == ev_keydown;
535         return false;
536         }
537         /* no break */
538     case ev_char:
539         break;
540     default:
541         return false;
542     }
543
544     if (!chat_on)
545     {
546         if (ev->data1 == HU_MSGREFRESH)
547         {
548             message_on = true;
549             message_counter = HU_MSGTIMEOUT;
550             eatkey = true;
551         }
552         else if (netgame && ev->data1 == HU_INPUTTOGGLE)
553         {
554             eatkey = chat_on = true;
555             HUlib_resetIText(&w_chat);
556             HU_queueChatChar(HU_BROADCAST);
557         }
558         else if (netgame && numplayers > 2)
559         {
560             for (i=0; i<MAXPLAYERS ; i++)
561             {
562                 if (ev->data1 == destination_keys[i])
563                 {
564                     if (playeringame[i] && i!=consoleplayer)
565                     {
566                         eatkey = chat_on = true;
567                         HUlib_resetIText(&w_chat);
568                         HU_queueChatChar(i+1);
569                         break;
570                     }
571                     else if (i == consoleplayer)
572                     {
573                         num_nobrainers++;
574                         if (num_nobrainers < 3)
575                             plr->message = HUSTR_TALKTOSELF1;
576                         else if (num_nobrainers < 6)
577                             plr->message = HUSTR_TALKTOSELF2;
578                         else if (num_nobrainers < 9)
579                             plr->message = HUSTR_TALKTOSELF3;
580                         else if (num_nobrainers < 32)
581                             plr->message = HUSTR_TALKTOSELF4;
582                         else
583                             plr->message = HUSTR_TALKTOSELF5;
584                     }
585                 }
586             }
587         }
588     }
589     else
590     {
591         c = ev->data1;
592
593         // send a macro
594         if (altdown)
595         {
596             c = c - '0';
597             if (c < 0 || c > 9)
598                 return false;
599             macromessage = chat_macros[c];
600             
601             // kill last message with a '\n'
602             HU_queueChatChar(KEY_ENTER); // DEBUG!!!
603             
604             // send the macro message
605             while (*macromessage)
606                 HU_queueChatChar(*macromessage++);
607             HU_queueChatChar(KEY_ENTER);
608             
609             // leave chat mode and notify that it was sent
610             chat_on = false;
611             strcpy(lastmessage, chat_macros[c]);
612             plr->message = lastmessage;
613             eatkey = true;
614         }
615         else
616         {
617             eatkey = HUlib_keyInIText(&w_chat, c);
618             if (eatkey)
619             {
620                 HU_queueChatChar(c);
621             }
622             if (c == KEY_ENTER)
623             {
624                 chat_on = false;
625                 if (w_chat.l.len)
626                 {
627                     strcpy(lastmessage, w_chat.l.l);
628                     plr->message = lastmessage;
629                 }
630             }
631             else if (c == KEY_ESCAPE)
632                 chat_on = false;
633         }
634     }
635
636     return eatkey;
637
638 }