DOOM-3-BFG

DOOM 3 BFG Edition
Log | Files | Refs

hu_stuff.cpp (11582B)


      1 /*
      2 ===========================================================================
      3 
      4 Doom 3 BFG Edition GPL Source Code
      5 Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. 
      6 
      7 This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").  
      8 
      9 Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
     10 it under the terms of the GNU General Public License as published by
     11 the Free Software Foundation, either version 3 of the License, or
     12 (at your option) any later version.
     13 
     14 Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
     15 but WITHOUT ANY WARRANTY; without even the implied warranty of
     16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17 GNU General Public License for more details.
     18 
     19 You should have received a copy of the GNU General Public License
     20 along with Doom 3 BFG Edition Source Code.  If not, see <http://www.gnu.org/licenses/>.
     21 
     22 In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code.  If not, please request a copy in writing from id Software at the address below.
     23 
     24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
     25 
     26 ===========================================================================
     27 */
     28 
     29 #include "Precompiled.h"
     30 #include "globaldata.h"
     31 
     32 #include <ctype.h>
     33 
     34 #include "doomdef.h"
     35 
     36 #include "z_zone.h"
     37 
     38 #include "m_swap.h"
     39 
     40 #include "hu_stuff.h"
     41 #include "hu_lib.h"
     42 #include "w_wad.h"
     43 
     44 #include "s_sound.h"
     45 
     46 #include "doomstat.h"
     47 
     48 // Data.
     49 #include "dstrings.h"
     50 #include "sounds.h"
     51 
     52 #include "Main.h"
     53 
     54 //
     55 // Locally used constants, shortcuts.
     56 //
     57 
     58 
     59 
     60 extern const char* const temp_chat_macros[];
     61 const char*	const temp_chat_macros[] =
     62 {
     63 	HUSTR_CHATMACRO0,
     64 	HUSTR_CHATMACRO1,
     65 	HUSTR_CHATMACRO2,
     66 	HUSTR_CHATMACRO3,
     67 	HUSTR_CHATMACRO4,
     68 	HUSTR_CHATMACRO5,
     69 	HUSTR_CHATMACRO6,
     70 	HUSTR_CHATMACRO7,
     71 	HUSTR_CHATMACRO8,
     72 	HUSTR_CHATMACRO9
     73 };
     74 
     75 extern const char* const player_names[];
     76 const char*	const player_names[] =
     77 {
     78 	HUSTR_PLRGREEN,
     79 	HUSTR_PLRINDIGO,
     80 	HUSTR_PLRBROWN,
     81 	HUSTR_PLRRED
     82 };
     83 
     84 
     85 
     86 
     87 
     88 
     89 
     90 //
     91 // Builtin map names.
     92 // The actual names can be found in DStrings.h.
     93 //
     94 
     95 const char*	mapnames[] =
     96 {
     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 
    108 		HUSTR_E2M1,
    109 		HUSTR_E2M2,
    110 		HUSTR_E2M3,
    111 		HUSTR_E2M4,
    112 		HUSTR_E2M5,
    113 		HUSTR_E2M6,
    114 		HUSTR_E2M7,
    115 		HUSTR_E2M8,
    116 		HUSTR_E2M9,
    117 
    118 		HUSTR_E3M1,
    119 		HUSTR_E3M2,
    120 		HUSTR_E3M3,
    121 		HUSTR_E3M4,
    122 		HUSTR_E3M5,
    123 		HUSTR_E3M6,
    124 		HUSTR_E3M7,
    125 		HUSTR_E3M8,
    126 		HUSTR_E3M9,
    127 
    128 		HUSTR_E4M1,
    129 		HUSTR_E4M2,
    130 		HUSTR_E4M3,
    131 		HUSTR_E4M4,
    132 		HUSTR_E4M5,
    133 		HUSTR_E4M6,
    134 		HUSTR_E4M7,
    135 		HUSTR_E4M8,
    136 		HUSTR_E4M9,
    137 
    138 		"NEWLEVEL",
    139 		"NEWLEVEL",
    140 		"NEWLEVEL",
    141 		"NEWLEVEL",
    142 		"NEWLEVEL",
    143 		"NEWLEVEL",
    144 		"NEWLEVEL",
    145 		"NEWLEVEL",
    146 		"NEWLEVEL"
    147 };
    148 
    149 const char*	mapnames2[] =
    150 {
    151 	HUSTR_1,
    152 		HUSTR_2,
    153 		HUSTR_3,
    154 		HUSTR_4,
    155 		HUSTR_5,
    156 		HUSTR_6,
    157 		HUSTR_7,
    158 		HUSTR_8,
    159 		HUSTR_9,
    160 		HUSTR_10,
    161 		HUSTR_11,
    162 
    163 		HUSTR_12,
    164 		HUSTR_13,
    165 		HUSTR_14,
    166 		HUSTR_15,
    167 		HUSTR_16,
    168 		HUSTR_17,
    169 		HUSTR_18,
    170 		HUSTR_19,
    171 		HUSTR_20,
    172 
    173 		HUSTR_21,
    174 		HUSTR_22,
    175 		HUSTR_23,
    176 		HUSTR_24,
    177 		HUSTR_25,
    178 		HUSTR_26,
    179 		HUSTR_27,
    180 		HUSTR_28,
    181 		HUSTR_29,
    182 		HUSTR_30,
    183 		HUSTR_31,
    184 		HUSTR_32,
    185 		HUSTR_33
    186 
    187 };
    188 
    189 
    190 const char*	mapnamesp[] =
    191 {
    192 	PHUSTR_1,
    193 		PHUSTR_2,
    194 		PHUSTR_3,
    195 		PHUSTR_4,
    196 		PHUSTR_5,
    197 		PHUSTR_6,
    198 		PHUSTR_7,
    199 		PHUSTR_8,
    200 		PHUSTR_9,
    201 		PHUSTR_10,
    202 		PHUSTR_11,
    203 
    204 		PHUSTR_12,
    205 		PHUSTR_13,
    206 		PHUSTR_14,
    207 		PHUSTR_15,
    208 		PHUSTR_16,
    209 		PHUSTR_17,
    210 		PHUSTR_18,
    211 		PHUSTR_19,
    212 		PHUSTR_20,
    213 
    214 		PHUSTR_21,
    215 		PHUSTR_22,
    216 		PHUSTR_23,
    217 		PHUSTR_24,
    218 		PHUSTR_25,
    219 		PHUSTR_26,
    220 		PHUSTR_27,
    221 		PHUSTR_28,
    222 		PHUSTR_29,
    223 		PHUSTR_30,
    224 		PHUSTR_31,
    225 		PHUSTR_32
    226 };
    227 
    228 	// TNT WAD map names.
    229 const char *mapnamest[] =
    230 {
    231 	THUSTR_1,
    232 		THUSTR_2,
    233 		THUSTR_3,
    234 		THUSTR_4,
    235 		THUSTR_5,
    236 		THUSTR_6,
    237 		THUSTR_7,
    238 		THUSTR_8,
    239 		THUSTR_9,
    240 		THUSTR_10,
    241 		THUSTR_11,
    242 
    243 		THUSTR_12,
    244 		THUSTR_13,
    245 		THUSTR_14,
    246 		THUSTR_15,
    247 		THUSTR_16,
    248 		THUSTR_17,
    249 		THUSTR_18,
    250 		THUSTR_19,
    251 		THUSTR_20,
    252 
    253 		THUSTR_21,
    254 		THUSTR_22,
    255 		THUSTR_23,
    256 		THUSTR_24,
    257 		THUSTR_25,
    258 		THUSTR_26,
    259 		THUSTR_27,
    260 		THUSTR_28,
    261 		THUSTR_29,
    262 		THUSTR_30,
    263 		THUSTR_31,
    264 		THUSTR_32
    265 };
    266 
    267 
    268 const char*	shiftxform;
    269 
    270 const char english_shiftxform[] =
    271 {
    272 
    273 	0,
    274 		1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
    275 		11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
    276 		21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
    277 		31,
    278 		' ', '!', '"', '#', '$', '%', '&',
    279 		'"', // shift-'
    280 		'(', ')', '*', '+',
    281 		'<', // shift-,
    282 		'_', // shift--
    283 		'>', // shift-.
    284 		'?', // shift-/
    285 		')', // shift-0
    286 		'!', // shift-1
    287 		'@', // shift-2
    288 		'#', // shift-3
    289 		'$', // shift-4
    290 		'%', // shift-5
    291 		'^', // shift-6
    292 		'&', // shift-7
    293 		'*', // shift-8
    294 		'(', // shift-9
    295 		':',
    296 		':', // shift-;
    297 		'<',
    298 		'+', // shift-=
    299 		'>', '?', '@',
    300 		'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
    301 		'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
    302 		'[', // shift-[
    303 		'!', // shift-backslash - OH MY GOD DOES WATCOM SUCK
    304 		']', // shift-]
    305 		'"', '_',
    306 		'\'', // shift-`
    307 		'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
    308 		'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
    309 		'{', '|', '}', '~', 127
    310 };
    311 
    312 char ForeignTranslation(unsigned char ch)
    313 {
    314 	return ch;
    315 }
    316 
    317 void HU_Init(void)
    318 {
    319 
    320 	int		i;
    321 	int		j;
    322 	char	buffer[9];
    323 
    324 	shiftxform = english_shiftxform;
    325 
    326 	// load the heads-up font
    327 	j = HU_FONTSTART;
    328 	for (i=0;i<HU_FONTSIZE;i++)
    329 	{
    330 		sprintf(buffer, "STCFN%.3d", j++);
    331 		::g->hu_font[i] = (patch_t *) W_CacheLumpName(buffer, PU_STATIC_SHARED);
    332 	}
    333 
    334 }
    335 
    336 void HU_Stop(void)
    337 {
    338 	::g->headsupactive = false;
    339 }
    340 
    341 void HU_Start(void)
    342 {
    343 
    344 	int		i;
    345 	const char*	s;
    346 
    347 	if (::g->headsupactive)
    348 		HU_Stop();
    349 
    350 	::g->plr = &::g->players[::g->consoleplayer];
    351 	::g->message_on = false;
    352 	::g->message_dontfuckwithme = false;
    353 	::g->message_nottobefuckedwith = false;
    354 	::g->chat_on = false;
    355 
    356 	// create the message widget
    357 	HUlib_initSText(&::g->w_message,
    358 		HU_MSGX, HU_MSGY, HU_MSGHEIGHT,
    359 		::g->hu_font,
    360 		HU_FONTSTART, &::g->message_on);
    361 
    362 	// create the map title widget
    363 	HUlib_initTextLine(&::g->w_title,
    364 		HU_TITLEX, HU_TITLEY,
    365 		::g->hu_font,
    366 		HU_FONTSTART);
    367 
    368 	switch ( ::g->gamemode )
    369 	{
    370 	case shareware:
    371 	case registered:
    372 	case retail:
    373 		s = HU_TITLE;
    374 		break;
    375 	case commercial:
    376 	default:
    377 		if( DoomLib::expansionSelected == 5 ) {
    378 			int map = ::g->gamemap;
    379 			if( ::g->gamemap > 9 ) {
    380 				map = 0;
    381 			} 
    382 
    383 			s = DoomLib::GetCurrentExpansion()->mapNames[ map - 1 ];
    384 		} else {
    385 			s = DoomLib::GetCurrentExpansion()->mapNames[ ::g->gamemap - 1 ];
    386 		}
    387 
    388 		
    389 		break;
    390 	}
    391 
    392 	while (*s)
    393 		HUlib_addCharToTextLine(&::g->w_title, *(s++));
    394 
    395 	// create the chat widget
    396 	HUlib_initIText(&::g->w_chat,
    397 		HU_INPUTX, HU_INPUTY,
    398 		::g->hu_font,
    399 		HU_FONTSTART, &::g->chat_on);
    400 
    401 	// create the inputbuffer widgets
    402 	for (i=0 ; i<MAXPLAYERS ; i++)
    403 		HUlib_initIText(&::g->w_inputbuffer[i], 0, 0, 0, 0, &::g->always_off);
    404 
    405 	::g->headsupactive = true;
    406 
    407 }
    408 
    409 void HU_Drawer(void)
    410 {
    411 
    412 	HUlib_drawSText(&::g->w_message);
    413 	HUlib_drawIText(&::g->w_chat);
    414 	if (::g->automapactive)
    415 		HUlib_drawTextLine(&::g->w_title, false);
    416 
    417 }
    418 
    419 void HU_Erase(void)
    420 {
    421 
    422 	HUlib_eraseSText(&::g->w_message);
    423 	HUlib_eraseIText(&::g->w_chat);
    424 	HUlib_eraseTextLine(&::g->w_title);
    425 
    426 }
    427 
    428 void HU_Ticker(void)
    429 {
    430 	// tick down message counter if message is up
    431 	if (::g->message_counter && !--::g->message_counter)
    432 	{
    433 		::g->message_on = false;
    434 		::g->message_nottobefuckedwith = false;
    435 	}
    436 
    437 	if ( ( m_inDemoMode.GetBool() == false && m_show_messages.GetBool() ) || ::g->message_dontfuckwithme)
    438 	{
    439 
    440 		// display message if necessary
    441 		if ((::g->plr->message && !::g->message_nottobefuckedwith)
    442 			|| (::g->plr->message && ::g->message_dontfuckwithme))
    443 		{
    444 			HUlib_addMessageToSText(&::g->w_message, 0, ::g->plr->message);
    445 			::g->plr->message = 0;
    446 			::g->message_on = true;
    447 			::g->message_counter = HU_MSGTIMEOUT;
    448 			::g->message_nottobefuckedwith = ::g->message_dontfuckwithme;
    449 			::g->message_dontfuckwithme = 0;
    450 		}
    451 
    452 	} // else ::g->message_on = false;
    453 }
    454 
    455 
    456 
    457 
    458 void HU_queueChatChar(char c)
    459 {
    460 	if (((::g->head + 1) & (QUEUESIZE-1)) == ::g->tail)
    461 	{
    462 		::g->plr->message = HUSTR_MSGU;
    463 	}
    464 	else
    465 	{
    466 		::g->chatchars[::g->head] = c;
    467 		::g->head = (::g->head + 1) & (QUEUESIZE-1);
    468 	}
    469 }
    470 
    471 char HU_dequeueChatChar(void)
    472 {
    473 	char c;
    474 
    475 	if (::g->head != ::g->tail)
    476 	{
    477 		c = ::g->chatchars[::g->tail];
    478 		::g->tail = (::g->tail + 1) & (QUEUESIZE-1);
    479 	}
    480 	else
    481 	{
    482 		c = 0;
    483 	}
    484 
    485 	return c;
    486 }
    487 
    488 qboolean HU_Responder(event_t *ev)
    489 {
    490 
    491 	const char*		macromessage;
    492 	qboolean		eatkey = false;
    493 	unsigned char 	c;
    494 	int			i;
    495 	int			numplayers;
    496 
    497 	const static char		destination_keys[MAXPLAYERS] =
    498 	{
    499 		HUSTR_KEYGREEN,
    500 			HUSTR_KEYINDIGO,
    501 			HUSTR_KEYBROWN,
    502 			HUSTR_KEYRED
    503 	};
    504 
    505 
    506 	numplayers = 0;
    507 	for (i=0 ; i<MAXPLAYERS ; i++)
    508 		numplayers += ::g->playeringame[i];
    509 
    510 	if (ev->data1 == KEY_RSHIFT)
    511 	{
    512 		::g->shiftdown = ev->type == ev_keydown;
    513 		return false;
    514 	}
    515 	else if (ev->data1 == KEY_RALT || ev->data1 == KEY_LALT)
    516 	{
    517 		::g->altdown = ev->type == ev_keydown;
    518 		return false;
    519 	}
    520 
    521 	if (ev->type != ev_keydown)
    522 		return false;
    523 
    524 	if (!::g->chat_on)
    525 	{
    526 		if (ev->data1 == HU_MSGREFRESH)
    527 		{
    528 			::g->message_on = true;
    529 			::g->message_counter = HU_MSGTIMEOUT;
    530 			eatkey = true;
    531 		}
    532 		else if (::g->netgame && ev->data1 == HU_INPUTTOGGLE)
    533 		{
    534 			eatkey = ::g->chat_on = true;
    535 			HUlib_resetIText(&::g->w_chat);
    536 			HU_queueChatChar(HU_BROADCAST);
    537 		}
    538 		else if (::g->netgame && numplayers > 2)
    539 		{
    540 			for (i=0; i<MAXPLAYERS ; i++)
    541 			{
    542 				if (ev->data1 == destination_keys[i])
    543 				{
    544 					if (::g->playeringame[i] && i!=::g->consoleplayer)
    545 					{
    546 						eatkey = ::g->chat_on = true;
    547 						HUlib_resetIText(&::g->w_chat);
    548 						HU_queueChatChar(i+1);
    549 						break;
    550 					}
    551 					else if (i == ::g->consoleplayer)
    552 					{
    553 						::g->num_nobrainers++;
    554 						if (::g->num_nobrainers < 3)
    555 							::g->plr->message = HUSTR_TALKTOSELF1;
    556 						else if (::g->num_nobrainers < 6)
    557 							::g->plr->message = HUSTR_TALKTOSELF2;
    558 						else if (::g->num_nobrainers < 9)
    559 							::g->plr->message = HUSTR_TALKTOSELF3;
    560 						else if (::g->num_nobrainers < 32)
    561 							::g->plr->message = HUSTR_TALKTOSELF4;
    562 						else
    563 							::g->plr->message = HUSTR_TALKTOSELF5;
    564 					}
    565 				}
    566 			}
    567 		}
    568 	}
    569 	else
    570 	{
    571 		c = ev->data1;
    572 		// send a macro
    573 		if (::g->altdown)
    574 		{
    575 			c = c - '0';
    576 			if (c > 9)
    577 				return false;
    578 			// I_PrintfE( "got here\n");
    579 			macromessage = temp_chat_macros[c];
    580 
    581 			// kill last message with a '\n'
    582 			HU_queueChatChar(KEY_ENTER); // DEBUG!!!
    583 
    584 			// send the macro message
    585 			while (*macromessage)
    586 				HU_queueChatChar(*macromessage++);
    587 			HU_queueChatChar(KEY_ENTER);
    588 
    589 			// leave chat mode and notify that it was sent
    590 			::g->chat_on = false;
    591 			strcpy(::g->lastmessage, temp_chat_macros[c]);
    592 			::g->plr->message = ::g->lastmessage;
    593 			eatkey = true;
    594 		}
    595 		else
    596 		{
    597 			if (::g->shiftdown || (c >= 'a' && c <= 'z'))
    598 				c = shiftxform[c];
    599 			eatkey = HUlib_keyInIText(&::g->w_chat, c);
    600 			if (eatkey)
    601 			{
    602 				// static unsigned char buf[20]; // DEBUG
    603 				HU_queueChatChar(c);
    604 
    605 				// sprintf(buf, "KEY: %d => %d", ev->data1, c);
    606 				//      ::g->plr->message = buf;
    607 			}
    608 			if (c == KEY_ENTER)
    609 			{
    610 				::g->chat_on = false;
    611 				if (::g->w_chat.l.len)
    612 				{
    613 					strcpy(::g->lastmessage, ::g->w_chat.l.l);
    614 					::g->plr->message = ::g->lastmessage;
    615 				}
    616 			}
    617 			else if (c == KEY_ESCAPE)
    618 				::g->chat_on = false;
    619 		}
    620 	}
    621 
    622 	return eatkey;
    623 
    624 }
    625