diff options
Diffstat (limited to 'demos/3rdparty/doom/hu_stuff.c')
-rw-r--r-- | demos/3rdparty/doom/hu_stuff.c | 759 |
1 files changed, 759 insertions, 0 deletions
diff --git a/demos/3rdparty/doom/hu_stuff.c b/demos/3rdparty/doom/hu_stuff.c new file mode 100644 index 00000000..efb13967 --- /dev/null +++ b/demos/3rdparty/doom/hu_stuff.c @@ -0,0 +1,759 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// $Id:$ +// +// Copyright (C) 1993-1996 by id Software, Inc. +// +// This source is available for distribution and/or modification +// only under the terms of the DOOM Source Code License as +// published by id Software. All rights reserved. +// +// The source is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License +// for more details. +// +// $Log:$ +// +// DESCRIPTION: Heads-up displays +// +//----------------------------------------------------------------------------- + +static const char +rcsid[] = "$Id: hu_stuff.c,v 1.4 1997/02/03 16:47:52 b1 Exp $"; + +#include <ctype.h> + +#include "doomdef.h" + +#include "z_zone.h" + +#include "m_swap.h" + +#include "hu_stuff.h" +#include "hu_lib.h" +#include "w_wad.h" + +#include "s_sound.h" + +#include "doomstat.h" + +// Data. +#include "dstrings.h" +#include "sounds.h" + +// +// Locally used constants, shortcuts. +// +#define HU_TITLE (mapnames[(gameepisode-1)*9+gamemap-1]) +#define HU_TITLE2 (mapnames2[gamemap-1]) +#define HU_TITLEP (mapnamesp[gamemap-1]) +#define HU_TITLET (mapnamest[gamemap-1]) +#define HU_TITLEHEIGHT 1 +#define HU_TITLEX 0 +#define HU_TITLEY (167 - SHORT(hu_font[0]->height)) + +#define HU_INPUTTOGGLE 't' +#define HU_INPUTX HU_MSGX +#define HU_INPUTY (HU_MSGY + HU_MSGHEIGHT*(SHORT(hu_font[0]->height) +1)) +#define HU_INPUTWIDTH 64 +#define HU_INPUTHEIGHT 1 + + + +char* chat_macros[] = +{ + HUSTR_CHATMACRO0, + HUSTR_CHATMACRO1, + HUSTR_CHATMACRO2, + HUSTR_CHATMACRO3, + HUSTR_CHATMACRO4, + HUSTR_CHATMACRO5, + HUSTR_CHATMACRO6, + HUSTR_CHATMACRO7, + HUSTR_CHATMACRO8, + HUSTR_CHATMACRO9 +}; + +char* player_names[] = +{ + HUSTR_PLRGREEN, + HUSTR_PLRINDIGO, + HUSTR_PLRBROWN, + HUSTR_PLRRED +}; + + +char chat_char; // remove later. +static player_t* plr; +patch_t* hu_font[HU_FONTSIZE]; +static hu_textline_t w_title; +boolean chat_on; +static hu_itext_t w_chat; +static boolean always_off = false; +static char chat_dest[MAXPLAYERS]; +static hu_itext_t w_inputbuffer[MAXPLAYERS]; + +static boolean message_on; +boolean message_dontfuckwithme; +static boolean message_nottobefuckedwith; + +static hu_stext_t w_message; +static int message_counter; + +extern int showMessages; +extern boolean automapactive; + +static boolean headsupactive = false; + +// +// Builtin map names. +// The actual names can be found in DStrings.h. +// + +char* mapnames[] = // DOOM shareware/registered/retail (Ultimate) names. +{ + + HUSTR_E1M1, + HUSTR_E1M2, + HUSTR_E1M3, + HUSTR_E1M4, + HUSTR_E1M5, + HUSTR_E1M6, + HUSTR_E1M7, + HUSTR_E1M8, + HUSTR_E1M9, + + HUSTR_E2M1, + HUSTR_E2M2, + HUSTR_E2M3, + HUSTR_E2M4, + HUSTR_E2M5, + HUSTR_E2M6, + HUSTR_E2M7, + HUSTR_E2M8, + HUSTR_E2M9, + + HUSTR_E3M1, + HUSTR_E3M2, + HUSTR_E3M3, + HUSTR_E3M4, + HUSTR_E3M5, + HUSTR_E3M6, + HUSTR_E3M7, + HUSTR_E3M8, + HUSTR_E3M9, + + HUSTR_E4M1, + HUSTR_E4M2, + HUSTR_E4M3, + HUSTR_E4M4, + HUSTR_E4M5, + HUSTR_E4M6, + HUSTR_E4M7, + HUSTR_E4M8, + HUSTR_E4M9, + + "NEWLEVEL", + "NEWLEVEL", + "NEWLEVEL", + "NEWLEVEL", + "NEWLEVEL", + "NEWLEVEL", + "NEWLEVEL", + "NEWLEVEL", + "NEWLEVEL" +}; + +char* mapnames2[] = // DOOM 2 map names. +{ + HUSTR_1, + HUSTR_2, + HUSTR_3, + HUSTR_4, + HUSTR_5, + HUSTR_6, + HUSTR_7, + HUSTR_8, + HUSTR_9, + HUSTR_10, + HUSTR_11, + + HUSTR_12, + HUSTR_13, + HUSTR_14, + HUSTR_15, + HUSTR_16, + HUSTR_17, + HUSTR_18, + HUSTR_19, + HUSTR_20, + + HUSTR_21, + HUSTR_22, + HUSTR_23, + HUSTR_24, + HUSTR_25, + HUSTR_26, + HUSTR_27, + HUSTR_28, + HUSTR_29, + HUSTR_30, + HUSTR_31, + HUSTR_32 +}; + + +char* mapnamesp[] = // Plutonia WAD map names. +{ + PHUSTR_1, + PHUSTR_2, + PHUSTR_3, + PHUSTR_4, + PHUSTR_5, + PHUSTR_6, + PHUSTR_7, + PHUSTR_8, + PHUSTR_9, + PHUSTR_10, + PHUSTR_11, + + PHUSTR_12, + PHUSTR_13, + PHUSTR_14, + PHUSTR_15, + PHUSTR_16, + PHUSTR_17, + PHUSTR_18, + PHUSTR_19, + PHUSTR_20, + + PHUSTR_21, + PHUSTR_22, + PHUSTR_23, + PHUSTR_24, + PHUSTR_25, + PHUSTR_26, + PHUSTR_27, + PHUSTR_28, + PHUSTR_29, + PHUSTR_30, + PHUSTR_31, + PHUSTR_32 +}; + + +char *mapnamest[] = // TNT WAD map names. +{ + THUSTR_1, + THUSTR_2, + THUSTR_3, + THUSTR_4, + THUSTR_5, + THUSTR_6, + THUSTR_7, + THUSTR_8, + THUSTR_9, + THUSTR_10, + THUSTR_11, + + THUSTR_12, + THUSTR_13, + THUSTR_14, + THUSTR_15, + THUSTR_16, + THUSTR_17, + THUSTR_18, + THUSTR_19, + THUSTR_20, + + THUSTR_21, + THUSTR_22, + THUSTR_23, + THUSTR_24, + THUSTR_25, + THUSTR_26, + THUSTR_27, + THUSTR_28, + THUSTR_29, + THUSTR_30, + THUSTR_31, + THUSTR_32 +}; + + +const char* shiftxform; + +const char french_shiftxform[] = +{ + 0, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, + ' ', '!', '"', '#', '$', '%', '&', + '"', // shift-' + '(', ')', '*', '+', + '?', // shift-, + '_', // shift-- + '>', // shift-. + '?', // shift-/ + '0', // shift-0 + '1', // shift-1 + '2', // shift-2 + '3', // shift-3 + '4', // shift-4 + '5', // shift-5 + '6', // shift-6 + '7', // shift-7 + '8', // shift-8 + '9', // shift-9 + '/', + '.', // shift-; + '<', + '+', // shift-= + '>', '?', '@', + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', + 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + '[', // shift-[ + '!', // shift-backslash - OH MY GOD DOES WATCOM SUCK + ']', // shift-] + '"', '_', + '\'', // shift-` + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', + 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + '{', '|', '}', '~', 127 + +}; + +const char english_shiftxform[] = +{ + + 0, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, + ' ', '!', '"', '#', '$', '%', '&', + '"', // shift-' + '(', ')', '*', '+', + '<', // shift-, + '_', // shift-- + '>', // shift-. + '?', // shift-/ + ')', // shift-0 + '!', // shift-1 + '@', // shift-2 + '#', // shift-3 + '$', // shift-4 + '%', // shift-5 + '^', // shift-6 + '&', // shift-7 + '*', // shift-8 + '(', // shift-9 + ':', + ':', // shift-; + '<', + '+', // shift-= + '>', '?', '@', + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', + 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + '[', // shift-[ + '!', // shift-backslash - OH MY GOD DOES WATCOM SUCK + ']', // shift-] + '"', '_', + '\'', // shift-` + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', + 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + '{', '|', '}', '~', 127 +}; + +char frenchKeyMap[128]= +{ + 0, + 1,2,3,4,5,6,7,8,9,10, + 11,12,13,14,15,16,17,18,19,20, + 21,22,23,24,25,26,27,28,29,30, + 31, + ' ','!','"','#','$','%','&','%','(',')','*','+',';','-',':','!', + '0','1','2','3','4','5','6','7','8','9',':','M','<','=','>','?', + '@','Q','B','C','D','E','F','G','H','I','J','K','L',',','N','O', + 'P','A','R','S','T','U','V','Z','X','Y','W','^','\\','$','^','_', + '@','Q','B','C','D','E','F','G','H','I','J','K','L',',','N','O', + 'P','A','R','S','T','U','V','Z','X','Y','W','^','\\','$','^',127 +}; + +char ForeignTranslation(unsigned char ch) +{ + return ch < 128 ? frenchKeyMap[ch] : ch; +} + +void HU_Init(void) +{ + + int i; + int j; + char buffer[9]; + + if (french) + shiftxform = french_shiftxform; + else + shiftxform = english_shiftxform; + + // load the heads-up font + j = HU_FONTSTART; + for (i=0;i<HU_FONTSIZE;i++) + { + sprintf(buffer, "STCFN%.3d", j++); + hu_font[i] = (patch_t *) W_CacheLumpName(buffer, PU_STATIC); + } + +} + +void HU_Stop(void) +{ + headsupactive = false; +} + +void HU_Start(void) +{ + + int i; + char* s; + + if (headsupactive) + HU_Stop(); + + plr = &players[consoleplayer]; + message_on = false; + message_dontfuckwithme = false; + message_nottobefuckedwith = false; + chat_on = false; + + // create the message widget + HUlib_initSText(&w_message, + HU_MSGX, HU_MSGY, HU_MSGHEIGHT, + hu_font, + HU_FONTSTART, &message_on); + + // create the map title widget + HUlib_initTextLine(&w_title, + HU_TITLEX, HU_TITLEY, + hu_font, + HU_FONTSTART); + + switch ( gamemode ) + { + case shareware: + case registered: + case retail: + s = HU_TITLE; + break; + +/* FIXME + case pack_plut: + s = HU_TITLEP; + break; + case pack_tnt: + s = HU_TITLET; + break; +*/ + + case commercial: + default: + s = HU_TITLE2; + break; + } + + while (*s) + HUlib_addCharToTextLine(&w_title, *(s++)); + + // create the chat widget + HUlib_initIText(&w_chat, + HU_INPUTX, HU_INPUTY, + hu_font, + HU_FONTSTART, &chat_on); + + // create the inputbuffer widgets + for (i=0 ; i<MAXPLAYERS ; i++) + HUlib_initIText(&w_inputbuffer[i], 0, 0, 0, 0, &always_off); + + headsupactive = true; + +} + +void HU_Drawer(void) +{ + + HUlib_drawSText(&w_message); + HUlib_drawIText(&w_chat); + if (automapactive) + HUlib_drawTextLine(&w_title, false); + +} + +void HU_Erase(void) +{ + + HUlib_eraseSText(&w_message); + HUlib_eraseIText(&w_chat); + HUlib_eraseTextLine(&w_title); + +} + +void HU_Ticker(void) +{ + + int i, rc; + char c; + + // tick down message counter if message is up + if (message_counter && !--message_counter) + { + message_on = false; + message_nottobefuckedwith = false; + } + + if (showMessages || message_dontfuckwithme) + { + + // display message if necessary + if ((plr->message && !message_nottobefuckedwith) + || (plr->message && message_dontfuckwithme)) + { + HUlib_addMessageToSText(&w_message, 0, plr->message); + plr->message = 0; + message_on = true; + message_counter = HU_MSGTIMEOUT; + message_nottobefuckedwith = message_dontfuckwithme; + message_dontfuckwithme = 0; + } + + } // else message_on = false; + + // check for incoming chat characters + if (netgame) + { + for (i=0 ; i<MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + if (i != consoleplayer + && (c = players[i].cmd.chatchar)) + { + if (c <= HU_BROADCAST) + chat_dest[i] = c; + else + { + if (c >= 'a' && c <= 'z') + c = (char) shiftxform[(unsigned char) c]; + rc = HUlib_keyInIText(&w_inputbuffer[i], c); + if (rc && c == KEY_ENTER) + { + if (w_inputbuffer[i].l.len + && (chat_dest[i] == consoleplayer+1 + || chat_dest[i] == HU_BROADCAST)) + { + HUlib_addMessageToSText(&w_message, + player_names[i], + w_inputbuffer[i].l.l); + + message_nottobefuckedwith = true; + message_on = true; + message_counter = HU_MSGTIMEOUT; + if ( gamemode == commercial ) + S_StartSound(0, sfx_radio); + else + S_StartSound(0, sfx_tink); + } + HUlib_resetIText(&w_inputbuffer[i]); + } + } + players[i].cmd.chatchar = 0; + } + } + } + +} + +#define QUEUESIZE 128 + +static char chatchars[QUEUESIZE]; +static int head = 0; +static int tail = 0; + + +void HU_queueChatChar(char c) +{ + if (((head + 1) & (QUEUESIZE-1)) == tail) + { + plr->message = HUSTR_MSGU; + } + else + { + chatchars[head] = c; + head = (head + 1) & (QUEUESIZE-1); + } +} + +char HU_dequeueChatChar(void) +{ + char c; + + if (head != tail) + { + c = chatchars[tail]; + tail = (tail + 1) & (QUEUESIZE-1); + } + else + { + c = 0; + } + + return c; +} + +boolean HU_Responder(event_t *ev) +{ + + static char lastmessage[HU_MAXLINELENGTH+1]; + char* macromessage; + boolean eatkey = false; + static boolean shiftdown = false; + static boolean altdown = false; + unsigned char c; + int i; + int numplayers; + + static char destination_keys[MAXPLAYERS] = + { + HUSTR_KEYGREEN, + HUSTR_KEYINDIGO, + HUSTR_KEYBROWN, + HUSTR_KEYRED + }; + + static int num_nobrainers = 0; + + numplayers = 0; + for (i=0 ; i<MAXPLAYERS ; i++) + numplayers += playeringame[i]; + + if (ev->data1 == KEY_RSHIFT) + { + shiftdown = ev->type == ev_keydown; + return false; + } + else if (ev->data1 == KEY_RALT || ev->data1 == KEY_LALT) + { + altdown = ev->type == ev_keydown; + return false; + } + + if (ev->type != ev_keydown) + return false; + + if (!chat_on) + { + if (ev->data1 == HU_MSGREFRESH) + { + message_on = true; + message_counter = HU_MSGTIMEOUT; + eatkey = true; + } + else if (netgame && ev->data1 == HU_INPUTTOGGLE) + { + eatkey = chat_on = true; + HUlib_resetIText(&w_chat); + HU_queueChatChar(HU_BROADCAST); + } + else if (netgame && numplayers > 2) + { + for (i=0; i<MAXPLAYERS ; i++) + { + if (ev->data1 == destination_keys[i]) + { + if (playeringame[i] && i!=consoleplayer) + { + eatkey = chat_on = true; + HUlib_resetIText(&w_chat); + HU_queueChatChar(i+1); + break; + } + else if (i == consoleplayer) + { + num_nobrainers++; + if (num_nobrainers < 3) + plr->message = HUSTR_TALKTOSELF1; + else if (num_nobrainers < 6) + plr->message = HUSTR_TALKTOSELF2; + else if (num_nobrainers < 9) + plr->message = HUSTR_TALKTOSELF3; + else if (num_nobrainers < 32) + plr->message = HUSTR_TALKTOSELF4; + else + plr->message = HUSTR_TALKTOSELF5; + } + } + } + } + } + else + { + c = ev->data1; + // send a macro + if (altdown) + { + c = c - '0'; + if (c > 9) + return false; + // fprintf(stderr, "got here\n"); + macromessage = chat_macros[c]; + + // kill last message with a '\n' + HU_queueChatChar(KEY_ENTER); // DEBUG!!! + + // send the macro message + while (*macromessage) + HU_queueChatChar(*macromessage++); + HU_queueChatChar(KEY_ENTER); + + // leave chat mode and notify that it was sent + chat_on = false; + strcpy(lastmessage, chat_macros[c]); + plr->message = lastmessage; + eatkey = true; + } + else + { + if (french) + c = ForeignTranslation(c); + if (shiftdown || (c >= 'a' && c <= 'z')) + c = shiftxform[c]; + eatkey = HUlib_keyInIText(&w_chat, c); + if (eatkey) + { + // static unsigned char buf[20]; // DEBUG + HU_queueChatChar(c); + + // sprintf(buf, "KEY: %d => %d", ev->data1, c); + // plr->message = buf; + } + if (c == KEY_ENTER) + { + chat_on = false; + if (w_chat.l.len) + { + strcpy(lastmessage, w_chat.l.l); + plr->message = lastmessage; + } + } + else if (c == KEY_ESCAPE) + chat_on = false; + } + } + + return eatkey; + +} |