// 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 #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_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_MAXFONTSIZE]; 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 mapnames1[48][35] = // 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", "NEWLEVEL", "NEWLEVEL", "NEWLEVEL" }; char mapnamesh[48][35] = // Heretic names. { HUSTR_E1M1_HERETIC, HUSTR_E1M2_HERETIC, HUSTR_E1M3_HERETIC, HUSTR_E1M4_HERETIC, HUSTR_E1M5_HERETIC, HUSTR_E1M6_HERETIC, HUSTR_E1M7_HERETIC, HUSTR_E1M8_HERETIC, HUSTR_E1M9_HERETIC, HUSTR_E2M1_HERETIC, HUSTR_E2M2_HERETIC, HUSTR_E2M3_HERETIC, HUSTR_E2M4_HERETIC, HUSTR_E2M5_HERETIC, HUSTR_E2M6_HERETIC, HUSTR_E2M7_HERETIC, HUSTR_E2M8_HERETIC, HUSTR_E2M9_HERETIC, HUSTR_E3M1_HERETIC, HUSTR_E3M2_HERETIC, HUSTR_E3M3_HERETIC, HUSTR_E3M4_HERETIC, HUSTR_E3M5_HERETIC, HUSTR_E3M6_HERETIC, HUSTR_E3M7_HERETIC, HUSTR_E3M8_HERETIC, HUSTR_E3M9_HERETIC, HUSTR_E4M1_HERETIC, HUSTR_E4M2_HERETIC, HUSTR_E4M3_HERETIC, HUSTR_E4M4_HERETIC, HUSTR_E4M5_HERETIC, HUSTR_E4M6_HERETIC, HUSTR_E4M7_HERETIC, HUSTR_E4M8_HERETIC, HUSTR_E4M9_HERETIC, HUSTR_E5M1_HERETIC, HUSTR_E5M2_HERETIC, HUSTR_E5M3_HERETIC, HUSTR_E5M4_HERETIC, HUSTR_E5M5_HERETIC, HUSTR_E5M6_HERETIC, HUSTR_E5M7_HERETIC, HUSTR_E5M8_HERETIC, HUSTR_E5M9_HERETIC, HUSTR_E6M1_HERETIC, HUSTR_E6M2_HERETIC, HUSTR_E6M3_HERETIC, }; char mapnamesd2[32][35] = // 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[32][35] = // 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[32][35] = // 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 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; } int HU_FONTSIZE; char* getMapName(int ge, int gm) { char* s; if(gametype) s = mapnamesh[9*(ge-1)+gm-1]; else switch ( gamemode ) { case shareware: case registered: case retail: s = mapnames1[9*(ge-1)+gm-1]; break; case commercial: default: s = mapnamesd2[gm-1]; break; } return s; } void HU_Init(void) { char* pref; int j; if(gametype==1) { // HU_FONTSTART =1; // HU_FONTEND =59; pref="FONTA"; HU_FONTSIZE = (HU_FONTEND - HU_FONTSTART + 1 - 4); j = 1; } else { // HU_FONTSTART ='!'; // 33 // HU_FONTEND ='_'; // 95 pref="STCFN"; HU_FONTSIZE = (HU_FONTEND - HU_FONTSTART + 1); j = HU_FONTSTART; } int i; char buffer[9]; shiftxform = english_shiftxform; // load the heads-up font for (i=0;imessage && !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; } #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 ; idata1 == KEY_RSHIFT) { shiftdown = ev->type == ev_keydown; return false; } else if (ev->data1 == KEY_RALT) { 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; idata1 == 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; }