hu_stuff.c
上传用户:xuyinpeng
上传日期:2021-05-12
资源大小:455k
文件大小:21k
源码类别:

射击游戏

开发平台:

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