A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 1590 lines 50 kB view raw
1/* Emacs style mode select -*- C++ -*- 2 *----------------------------------------------------------------------------- 3 * 4 * 5 * PrBoom a Doom port merged with LxDoom and LSDLDoom 6 * based on BOOM, a modified and improved DOOM engine 7 * Copyright (C) 1999 by 8 * id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman 9 * Copyright (C) 1999-2000 by 10 * Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze 11 * 12 * This program is free software; you can redistribute it and/or 13 * modify it under the terms of the GNU General Public License 14 * as published by the Free Software Foundation; either version 2 15 * of the License, or (at your option) any later version. 16 * 17 * This program is distributed in the hope that it will be useful, 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 * GNU General Public License for more details. 21 * 22 * You should have received a copy of the GNU General Public License 23 * along with this program; if not, write to the Free Software 24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 25 * 02111-1307, USA. 26 * 27 * DESCRIPTION: Heads-up displays 28 * 29 *----------------------------------------------------------------------------- 30 */ 31 32// killough 5/3/98: remove unnecessary headers 33 34#include "doomstat.h" 35#include "hu_stuff.h" 36#include "hu_lib.h" 37#include "st_stuff.h" /* jff 2/16/98 need loc of status bar */ 38#include "w_wad.h" 39#include "s_sound.h" 40#include "dstrings.h" 41#include "sounds.h" 42//#include "d_deh.h" /* Ty 03/27/98 - externalization of mapnamesx arrays */ 43#include "g_game.h" 44#include "m_swap.h" 45 46// global heads up display controls 47 48int hud_active; //jff 2/17/98 controls heads-up display mode 49int hud_displayed; //jff 2/23/98 turns heads-up display on/off 50int hud_nosecrets; //jff 2/18/98 allows secrets line to be disabled in HUD 51int hud_distributed; //jff 3/4/98 display HUD in different places on screen 52int hud_graph_keys=1; //jff 3/7/98 display HUD keys as graphics 53 54// 55// Locally used constants, shortcuts. 56// 57// Ty 03/28/98 - 58// These four shortcuts modifed to reflect char ** of mapnamesx[] 59#define HU_TITLE (*mapnames[(gameepisode-1)*9+gamemap-1]) 60#define HU_TITLE2 (*mapnames2[gamemap-1]) 61#define HU_TITLEP (*mapnamesp[gamemap-1]) 62#define HU_TITLET (*mapnamest[gamemap-1]) 63#define HU_TITLEHEIGHT 1 64#define HU_TITLEX 0 65//jff 2/16/98 change 167 to ST_Y-1 66// CPhipps - changed to ST_TY 67// proff - changed to 200-ST_HEIGHT for stretching 68#define HU_TITLEY ((200-ST_HEIGHT) - 1 - SHORT(hu_font[0].height)) 69 70//jff 2/16/98 add coord text widget coordinates 71// proff - changed to SCREENWIDTH to 320 for stretching 72#define HU_COORDX (320 - 13*SHORT(hu_font2['A'-HU_FONTSTART].width)) 73//jff 3/3/98 split coord widget into three lines in upper right of screen 74#define HU_COORDX_Y (1 + 0*SHORT(hu_font['A'-HU_FONTSTART].height)) 75#define HU_COORDY_Y (2 + 1*SHORT(hu_font['A'-HU_FONTSTART].height)) 76#define HU_COORDZ_Y (3 + 2*SHORT(hu_font['A'-HU_FONTSTART].height)) 77 78//jff 2/16/98 add ammo, health, armor widgets, 2/22/98 less gap 79#define HU_GAPY 8 80#define HU_HUDHEIGHT (6*HU_GAPY) 81#define HU_HUDX 2 82#define HU_HUDY (200-HU_HUDHEIGHT-1) 83#define HU_MONSECX (HU_HUDX) 84#define HU_MONSECY (HU_HUDY+0*HU_GAPY) 85#define HU_KEYSX (HU_HUDX) 86//jff 3/7/98 add offset for graphic key widget 87#define HU_KEYSGX (HU_HUDX+4*SHORT(hu_font2['A'-HU_FONTSTART].width)) 88#define HU_KEYSY (HU_HUDY+1*HU_GAPY) 89#define HU_WEAPX (HU_HUDX) 90#define HU_WEAPY (HU_HUDY+2*HU_GAPY) 91#define HU_AMMOX (HU_HUDX) 92#define HU_AMMOY (HU_HUDY+3*HU_GAPY) 93#define HU_HEALTHX (HU_HUDX) 94#define HU_HEALTHY (HU_HUDY+4*HU_GAPY) 95#define HU_ARMORX (HU_HUDX) 96#define HU_ARMORY (HU_HUDY+5*HU_GAPY) 97 98//jff 3/4/98 distributed HUD positions 99#define HU_HUDX_LL 2 100#define HU_HUDY_LL (200-2*HU_GAPY-1) 101// proff/nicolas 09/20/98: Changed for high-res 102#define HU_HUDX_LR (320-120) 103#define HU_HUDY_LR (200-2*HU_GAPY-1) 104// proff/nicolas 09/20/98: Changed for high-res 105#define HU_HUDX_UR (320-96) 106#define HU_HUDY_UR 2 107#define HU_MONSECX_D (HU_HUDX_LL) 108#define HU_MONSECY_D (HU_HUDY_LL+0*HU_GAPY) 109#define HU_KEYSX_D (HU_HUDX_LL) 110#define HU_KEYSGX_D (HU_HUDX_LL+4*SHORT(hu_font2['A'-HU_FONTSTART].width)) 111#define HU_KEYSY_D (HU_HUDY_LL+1*HU_GAPY) 112#define HU_WEAPX_D (HU_HUDX_LR) 113#define HU_WEAPY_D (HU_HUDY_LR+0*HU_GAPY) 114#define HU_AMMOX_D (HU_HUDX_LR) 115#define HU_AMMOY_D (HU_HUDY_LR+1*HU_GAPY) 116#define HU_HEALTHX_D (HU_HUDX_UR) 117#define HU_HEALTHY_D (HU_HUDY_UR+0*HU_GAPY) 118#define HU_ARMORX_D (HU_HUDX_UR) 119#define HU_ARMORY_D (HU_HUDY_UR+1*HU_GAPY) 120 121//#define HU_INPUTTOGGLE 't' // not used // phares 122#define HU_INPUTX HU_MSGX 123#define HU_INPUTY (HU_MSGY + HU_MSGHEIGHT*(SHORT(hu_font[0].height) +1)) 124#define HU_INPUTWIDTH 64 125#define HU_INPUTHEIGHT 1 126 127#define key_alt KEY_RALT 128#define key_shift KEY_RSHIFT 129 130const char* chat_macros[] = 131 // Ty 03/27/98 - *not* externalized 132 // CPhipps - const char* 133 { 134 HUSTR_CHATMACRO1, 135 HUSTR_CHATMACRO1, 136 HUSTR_CHATMACRO1, 137 HUSTR_CHATMACRO1, 138 HUSTR_CHATMACRO1, 139 HUSTR_CHATMACRO1, 140 HUSTR_CHATMACRO1, 141 HUSTR_CHATMACRO1, 142 HUSTR_CHATMACRO1, 143 HUSTR_CHATMACRO1 144 }; 145 146const char* player_names[] = 147 // Ty 03/27/98 - *not* externalized 148 // CPhipps - const char* 149 { 150 HUSTR_PLRGREEN, 151 HUSTR_PLRINDIGO, 152 HUSTR_PLRBROWN, 153 HUSTR_PLRRED 154 }; 155 156//jff 3/17/98 translate player colmap to text color ranges 157int plyrcoltran[MAXPLAYERS]={CR_GREEN,CR_GRAY,CR_BROWN,CR_RED}; 158 159char chat_char; // remove later. 160static player_t* plr; 161 162// font sets 163patchnum_t hu_font[HU_FONTSIZE]; 164patchnum_t *hu_font2; 165patchnum_t *hu_fontk;//jff 3/7/98 added for graphic key indicators 166patchnum_t hu_msgbg[9]; //jff 2/26/98 add patches for message background 167 168// widgets 169static hu_textline_t w_title; 170static hu_stext_t w_message; 171static hu_itext_t w_chat; 172static hu_itext_t w_inputbuffer[MAXPLAYERS]; 173static hu_textline_t w_coordx; //jff 2/16/98 new coord widget for automap 174static hu_textline_t w_coordy; //jff 3/3/98 split coord widgets automap 175static hu_textline_t w_coordz; //jff 3/3/98 split coord widgets automap 176static hu_textline_t w_ammo; //jff 2/16/98 new ammo widget for hud 177static hu_textline_t w_health; //jff 2/16/98 new health widget for hud 178static hu_textline_t w_armor; //jff 2/16/98 new armor widget for hud 179static hu_textline_t w_weapon; //jff 2/16/98 new weapon widget for hud 180static hu_textline_t w_keys; //jff 2/16/98 new keys widget for hud 181static hu_textline_t w_gkeys; //jff 3/7/98 graphic keys widget for hud 182static hu_textline_t w_monsec; //jff 2/16/98 new kill/secret widget for hud 183static hu_mtext_t w_rtext; //jff 2/26/98 text message refresh widget 184 185static boolean always_off = false; 186static char chat_dest[MAXPLAYERS]; 187boolean chat_on; 188static boolean message_on; 189static boolean message_list; //2/26/98 enable showing list of messages 190boolean message_dontfuckwithme; 191static boolean message_nottobefuckedwith; 192static int message_counter; 193extern int showMessages; 194extern boolean automapactive; 195static boolean headsupactive = false; 196 197//jff 2/16/98 hud supported automap colors added 198int hudcolor_titl; // color range of automap level title 199int hudcolor_xyco; // color range of new coords on automap 200//jff 2/16/98 hud text colors, controls added 201int hudcolor_mesg; // color range of scrolling messages 202int hudcolor_chat; // color range of chat lines 203int hud_msg_lines; // number of message lines in window 204//jff 2/26/98 hud text colors, controls added 205int hudcolor_list; // list of messages color 206int hud_list_bgon; // enable for solid window background for message list 207 208//jff 2/16/98 initialization strings for ammo, health, armor widgets 209static char *hud_coordstrx; 210static char *hud_coordstry; 211static char *hud_coordstrz; 212static char *hud_ammostr; 213static char *hud_healthstr; 214static char *hud_armorstr; 215static char *hud_weapstr; 216static char *hud_keysstr; 217static char *hud_gkeysstr; //jff 3/7/98 add support for graphic key display 218static char *hud_monsecstr; 219 220//jff 2/16/98 declaration of color switch points 221extern int ammo_red; 222extern int ammo_yellow; 223extern int health_red; 224extern int health_yellow; 225extern int health_green; 226extern int armor_red; 227extern int armor_yellow; 228extern int armor_green; 229 230// key tables 231// jff 5/10/98 french support removed, 232// as it was not being used and couldn't be easily tested 233// 234const char* shiftxform; 235 236const char english_shiftxform[] = 237 { 238 0, 239 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 240 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 241 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 242 31, 243 ' ', '!', '"', '#', '$', '%', '&', 244 '"', // shift-' 245 '(', ')', '*', '+', 246 '<', // shift-, 247 '_', // shift-- 248 '>', // shift-. 249 '?', // shift-/ 250 ')', // shift-0 251 '!', // shift-1 252 '@', // shift-2 253 '#', // shift-3 254 '$', // shift-4 255 '%', // shift-5 256 '^', // shift-6 257 '&', // shift-7 258 '*', // shift-8 259 '(', // shift-9 260 ':', 261 ':', // shift-; 262 '<', 263 '+', // shift-= 264 '>', '?', '@', 265 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 266 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 267 '[', // shift-[ 268 '!', // shift-backslash - OH MY GOD DOES WATCOM SUCK 269 ']', // shift-] 270 '"', '_', 271 '\'', // shift-` 272 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 273 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 274 '{', '|', '}', '~', 127 275 }; 276 277// 278// HU_Init() 279// 280// Initialize the heads-up display, text that overwrites the primary display 281// 282// Passed nothing, returns nothing 283// 284void HU_Init(void) 285{ 286 int i; 287 int j; 288 char buffer[9]; 289 290 shiftxform = english_shiftxform; 291 292 // malloc all the strings, trying to get size down 293 hud_ammostr=malloc(80*sizeof(char)); 294 hud_healthstr=malloc(80*sizeof(char)); 295 hud_armorstr=malloc(80*sizeof(char)); 296 hud_weapstr=malloc(80*sizeof(char)); 297 hud_keysstr=malloc(80*sizeof(char)); 298 hud_gkeysstr=malloc(80*sizeof(char)); 299 hud_monsecstr=malloc(80*sizeof(char)); 300 hud_coordstrx=malloc(32*sizeof(char)); 301 hud_coordstry=malloc(32*sizeof(char)); 302 hud_coordstrz=malloc(32*sizeof(char)); 303 hu_fontk=malloc(HU_FONTSIZE*sizeof(patchnum_t)); 304 hu_font2=malloc(HU_FONTSIZE*sizeof(patchnum_t)); 305 306 // load the heads-up font 307 j = HU_FONTSTART; 308 for (i=0;i<HU_FONTSIZE;i++,j++) 309 { 310 if ('0'<=j && j<='9') 311 { 312 snprintf(buffer, sizeof(buffer), "DIG%d",j-48); 313 R_SetPatchNum(hu_font2 +i, buffer); 314 snprintf(buffer, sizeof(buffer), "STCFN%.3d", j); 315 R_SetPatchNum(&hu_font[i], buffer); 316 } 317 else if ('A'<=j && j<='Z') 318 { 319 snprintf(buffer, sizeof(buffer), "DIG%c",j); 320 R_SetPatchNum(hu_font2 +i, buffer); 321 snprintf(buffer, sizeof(buffer), "STCFN%.3d", j); 322 R_SetPatchNum(&hu_font[i], buffer); 323 } 324 else if (j=='-') 325 { 326 R_SetPatchNum(hu_font2 +i, "DIG45"); 327 R_SetPatchNum(&hu_font[i], "STCFN045"); 328 } 329 else if (j=='/') 330 { 331 R_SetPatchNum(hu_font2 +i, "DIG47"); 332 R_SetPatchNum(&hu_font[i], "STCFN047"); 333 } 334 else if (j==':') 335 { 336 R_SetPatchNum(hu_font2 +i, "DIG58"); 337 R_SetPatchNum(&hu_font[i], "STCFN058"); 338 } 339 else if (j=='[') 340 { 341 R_SetPatchNum(hu_font2 +i, "DIG91"); 342 R_SetPatchNum(&hu_font[i], "STCFN091"); 343 } 344 else if (j==']') 345 { 346 R_SetPatchNum(hu_font2 +i, "DIG93"); 347 R_SetPatchNum(&hu_font[i], "STCFN093"); 348 } 349 else if (j<97) 350 { 351 snprintf(buffer, sizeof(buffer), "STCFN%.3d", j); 352 R_SetPatchNum(hu_font2 +i, buffer); 353 R_SetPatchNum(&hu_font[i], buffer); 354 //jff 2/23/98 make all font chars defined, useful or not 355 } 356 else if (j>122) 357 { 358 snprintf(buffer, sizeof(buffer), "STBR%.3d", j); 359 R_SetPatchNum(hu_font2 +i, buffer); 360 R_SetPatchNum(&hu_font[i], buffer); 361 } 362 else 363 hu_font[i] = hu_font[0]; //jff 2/16/98 account for gap 364 } 365 366 // CPhipps - load patches for message background 367 for (i=0; i<9; i++) { 368 snprintf(buffer, sizeof(buffer), "BOX%c%c", "UCL"[i/3], "LCR"[i%3]); 369 R_SetPatchNum(&hu_msgbg[i], buffer); 370 } 371 372 // CPhipps - load patches for keys and double keys 373 for (i=0; i<6; i++) { 374 snprintf(buffer, sizeof(buffer), "STKEYS%d", i); 375 R_SetPatchNum(hu_fontk+i, buffer); 376 } 377} 378 379// 380// HU_Stop() 381// 382// Make the heads-up displays inactive 383// 384// Passed nothing, returns nothing 385// 386void HU_Stop(void) 387{ 388 headsupactive = false; 389} 390 391// 392// HU_Start(void) 393// 394// Create and initialize the heads-up widgets, software machines to 395// maintain, update, and display information over the primary display 396// 397// This routine must be called after any change to the heads up configuration 398// in order for the changes to take effect in the actual displays 399// 400// Passed nothing, returns nothing 401// 402void HU_Start(void) 403{ 404 405 int i; 406 const char* s; /* cph - const */ 407 408 if (headsupactive) // stop before starting 409 HU_Stop(); 410 411 plr = &players[displayplayer]; // killough 3/7/98 412 message_on = false; 413 message_dontfuckwithme = false; 414 message_nottobefuckedwith = false; 415 chat_on = false; 416 417 // create the message widget 418 // messages to player in upper-left of screen 419 HUlib_initSText 420 ( 421 &w_message, 422 HU_MSGX, 423 HU_MSGY, 424 HU_MSGHEIGHT, 425 hu_font, 426 HU_FONTSTART, 427 hudcolor_mesg, 428 &message_on 429 ); 430 431 //jff 2/16/98 added some HUD widgets 432 // create the map title widget - map title display in lower left of automap 433 HUlib_initTextLine 434 ( 435 &w_title, 436 HU_TITLEX, 437 HU_TITLEY, 438 hu_font, 439 HU_FONTSTART, 440 hudcolor_titl 441 ); 442 443 // create the hud health widget 444 // bargraph and number for amount of health, 445 // lower left or upper right of screen 446 HUlib_initTextLine 447 ( 448 &w_health, 449 hud_distributed? HU_HEALTHX_D : HU_HEALTHX, //3/4/98 distribute 450 hud_distributed? HU_HEALTHY_D : HU_HEALTHY, 451 hu_font2, 452 HU_FONTSTART, 453 CR_GREEN 454 ); 455 456 // create the hud armor widget 457 // bargraph and number for amount of armor, 458 // lower left or upper right of screen 459 HUlib_initTextLine 460 ( 461 &w_armor, 462 hud_distributed? HU_ARMORX_D : HU_ARMORX, //3/4/98 distribute 463 hud_distributed? HU_ARMORY_D : HU_ARMORY, 464 hu_font2, 465 HU_FONTSTART, 466 CR_GREEN 467 ); 468 469 // create the hud ammo widget 470 // bargraph and number for amount of ammo for current weapon, 471 // lower left or lower right of screen 472 HUlib_initTextLine 473 ( 474 &w_ammo, 475 hud_distributed? HU_AMMOX_D : HU_AMMOX, //3/4/98 distribute 476 hud_distributed? HU_AMMOY_D : HU_AMMOY, 477 hu_font2, 478 HU_FONTSTART, 479 CR_GOLD 480 ); 481 482 // create the hud weapons widget 483 // list of numbers of weapons possessed 484 // lower left or lower right of screen 485 HUlib_initTextLine 486 ( 487 &w_weapon, 488 hud_distributed? HU_WEAPX_D : HU_WEAPX, //3/4/98 distribute 489 hud_distributed? HU_WEAPY_D : HU_WEAPY, 490 hu_font2, 491 HU_FONTSTART, 492 CR_GRAY 493 ); 494 495 // create the hud keys widget 496 // display of key letters possessed 497 // lower left of screen 498 HUlib_initTextLine 499 ( 500 &w_keys, 501 hud_distributed? HU_KEYSX_D : HU_KEYSX, //3/4/98 distribute 502 hud_distributed? HU_KEYSY_D : HU_KEYSY, 503 hu_font2, 504 HU_FONTSTART, 505 CR_GRAY 506 ); 507 508 // create the hud graphic keys widget 509 // display of key graphics possessed 510 // lower left of screen 511 HUlib_initTextLine 512 ( 513 &w_gkeys, 514 hud_distributed? HU_KEYSGX_D : HU_KEYSGX, //3/4/98 distribute 515 hud_distributed? HU_KEYSY_D : HU_KEYSY, 516 hu_fontk, 517 HU_FONTSTART, 518 CR_RED 519 ); 520 521 // create the hud monster/secret widget 522 // totals and current values for kills, items, secrets 523 // lower left of screen 524 HUlib_initTextLine 525 ( 526 &w_monsec, 527 hud_distributed? HU_MONSECX_D : HU_MONSECX, //3/4/98 distribute 528 hud_distributed? HU_MONSECY_D : HU_MONSECY, 529 hu_font2, 530 HU_FONTSTART, 531 CR_GRAY 532 ); 533 534 // create the hud text refresh widget 535 // scrolling display of last hud_msg_lines messages received 536 if (hud_msg_lines>HU_MAXMESSAGES) 537 hud_msg_lines=HU_MAXMESSAGES; 538 //jff 4/21/98 if setup has disabled message list while active, turn it off 539 message_list = hud_msg_lines > 1; //jff 8/8/98 initialize both ways 540 //jff 2/26/98 add the text refresh widget initialization 541 HUlib_initMText 542 ( 543 &w_rtext, 544 0, 545 0, 546 320, 547 // SCREENWIDTH, 548 (hud_msg_lines+2)*HU_REFRESHSPACING, 549 hu_font, 550 HU_FONTSTART, 551 hudcolor_list, 552 hu_msgbg, 553 &message_list 554 ); 555 556 // initialize the automap's level title widget 557 if (gamestate == GS_LEVEL) /* cph - stop SEGV here when not in level */ 558 switch (gamemode) 559 { 560 case shareware: 561 case registered: 562 case retail: 563 s = HU_TITLE; 564 break; 565 566 case commercial: 567 default: // Ty 08/27/98 - modified to check mission for TNT/Plutonia 568 s = (gamemission==pack_tnt) ? HU_TITLET : 569 (gamemission==pack_plut) ? HU_TITLEP : HU_TITLE2; 570 break; 571 } else s = ""; 572 while (*s) 573 HUlib_addCharToTextLine(&w_title, *(s++)); 574 575 // create the automaps coordinate widget 576 // jff 3/3/98 split coord widget into three lines: x,y,z 577 // jff 2/16/98 added 578 HUlib_initTextLine 579 ( 580 &w_coordx, 581 HU_COORDX, 582 HU_COORDX_Y, 583 hu_font, 584 HU_FONTSTART, 585 hudcolor_xyco 586 ); 587 HUlib_initTextLine 588 ( 589 &w_coordy, 590 HU_COORDX, 591 HU_COORDY_Y, 592 hu_font, 593 HU_FONTSTART, 594 hudcolor_xyco 595 ); 596 HUlib_initTextLine 597 ( 598 &w_coordz, 599 HU_COORDX, 600 HU_COORDZ_Y, 601 hu_font, 602 HU_FONTSTART, 603 hudcolor_xyco 604 ); 605 606 // initialize the automaps coordinate widget 607 //jff 3/3/98 split coordstr widget into 3 parts 608 snprintf(hud_coordstrx,32*sizeof(char),"X: %d",0); //jff 2/22/98 added z 609 s = hud_coordstrx; 610 while (*s) 611 HUlib_addCharToTextLine(&w_coordx, *(s++)); 612 snprintf(hud_coordstry,32*sizeof(char),"Y: %d",0); //jff 3/3/98 split x,y,z 613 s = hud_coordstry; 614 while (*s) 615 HUlib_addCharToTextLine(&w_coordy, *(s++)); 616 snprintf(hud_coordstrz,32*sizeof(char),"Z: %d",0); //jff 3/3/98 split x,y,z 617 s = hud_coordstrz; 618 while (*s) 619 HUlib_addCharToTextLine(&w_coordz, *(s++)); 620 621 //jff 2/16/98 initialize ammo widget 622 strcpy(hud_ammostr,"AMM "); 623 s = hud_ammostr; 624 while (*s) 625 HUlib_addCharToTextLine(&w_ammo, *(s++)); 626 627 //jff 2/16/98 initialize health widget 628 strcpy(hud_healthstr,"HEL "); 629 s = hud_healthstr; 630 while (*s) 631 HUlib_addCharToTextLine(&w_health, *(s++)); 632 633 //jff 2/16/98 initialize armor widget 634 strcpy(hud_armorstr,"ARM "); 635 s = hud_armorstr; 636 while (*s) 637 HUlib_addCharToTextLine(&w_armor, *(s++)); 638 639 //jff 2/17/98 initialize weapons widget 640 strcpy(hud_weapstr,"WEA "); 641 s = hud_weapstr; 642 while (*s) 643 HUlib_addCharToTextLine(&w_weapon, *(s++)); 644 645 //jff 2/17/98 initialize keys widget 646 if (!deathmatch) //jff 3/17/98 show frags in deathmatch mode 647 strcpy(hud_keysstr,"KEY "); 648 else 649 strcpy(hud_keysstr,"FRG "); 650 s = hud_keysstr; 651 while (*s) 652 HUlib_addCharToTextLine(&w_keys, *(s++)); 653 654 //jff 2/17/98 initialize graphic keys widget 655 strcpy(hud_gkeysstr," "); 656 s = hud_gkeysstr; 657 while (*s) 658 HUlib_addCharToTextLine(&w_gkeys, *(s++)); 659 660 //jff 2/17/98 initialize kills/items/secret widget 661 strcpy(hud_monsecstr,"STS "); 662 s = hud_monsecstr; 663 while (*s) 664 HUlib_addCharToTextLine(&w_monsec, *(s++)); 665 666 // create the chat widget 667 HUlib_initIText 668 ( 669 &w_chat, 670 HU_INPUTX, 671 HU_INPUTY, 672 hu_font, 673 HU_FONTSTART, 674 hudcolor_chat, 675 &chat_on 676 ); 677 678 // create the inputbuffer widgets, one per player 679 for (i=0 ; i<MAXPLAYERS ; i++) 680 HUlib_initIText 681 ( 682 &w_inputbuffer[i], 683 0, 684 0, 685 0, 686 0, 687 hudcolor_chat, 688 &always_off 689 ); 690 691 // now allow the heads-up display to run 692 headsupactive = true; 693} 694 695// 696// HU_MoveHud() 697// 698// Move the HUD display from distributed to compact mode or vice-versa 699// 700// Passed nothing, returns nothing 701// 702//jff 3/9/98 create this externally callable to avoid glitch 703// when menu scatter's HUD due to delay in change of position 704// 705void HU_MoveHud(void) 706{ 707 static int ohud_distributed=-1; 708 709 //jff 3/4/98 move displays around on F5 changing hud_distributed 710 if (hud_distributed!=ohud_distributed) 711 { 712 w_ammo.x = hud_distributed? HU_AMMOX_D : HU_AMMOX; 713 w_ammo.y = hud_distributed? HU_AMMOY_D : HU_AMMOY; 714 w_weapon.x = hud_distributed? HU_WEAPX_D : HU_WEAPX; 715 w_weapon.y = hud_distributed? HU_WEAPY_D : HU_WEAPY; 716 w_keys.x = hud_distributed? HU_KEYSX_D : HU_KEYSX; 717 w_keys.y = hud_distributed? HU_KEYSY_D : HU_KEYSY; 718 w_gkeys.x = hud_distributed? HU_KEYSGX_D : HU_KEYSGX; 719 w_gkeys.y = hud_distributed? HU_KEYSY_D : HU_KEYSY; 720 w_monsec.x = hud_distributed? HU_MONSECX_D : HU_MONSECX; 721 w_monsec.y = hud_distributed? HU_MONSECY_D : HU_MONSECY; 722 w_health.x = hud_distributed? HU_HEALTHX_D : HU_HEALTHX; 723 w_health.y = hud_distributed? HU_HEALTHY_D : HU_HEALTHY; 724 w_armor.x = hud_distributed? HU_ARMORX_D : HU_ARMORX; 725 w_armor.y = hud_distributed? HU_ARMORY_D : HU_ARMORY; 726 } 727 ohud_distributed = hud_distributed; 728} 729 730// 731// HU_Drawer() 732// 733// Draw all the pieces of the heads-up display 734// 735// Passed nothing, returns nothing 736// 737void HU_Drawer(void) 738{ 739 char *s; 740 player_t *plr; 741 char ammostr[80]; //jff 3/8/98 allow plenty room for dehacked mods 742 char healthstr[80];//jff 743 char armorstr[80]; //jff 744 int i,doit; 745 746 plr = &players[displayplayer]; // killough 3/7/98 747 // draw the automap widgets if automap is displayed 748 if (automapmode & am_active) 749 { 750 // map title 751 HUlib_drawTextLine(&w_title, false); 752 753 //jff 2/16/98 output new coord display 754 // x-coord 755 snprintf(hud_coordstrx,32*sizeof(char),"X: %d", (plr->mo->x)>>FRACBITS); 756 HUlib_clearTextLine(&w_coordx); 757 s = hud_coordstrx; 758 while (*s) 759 HUlib_addCharToTextLine(&w_coordx, *(s++)); 760 HUlib_drawTextLine(&w_coordx, false); 761 762 //jff 3/3/98 split coord display into x,y,z lines 763 // y-coord 764 snprintf(hud_coordstry,32*sizeof(char),"Y: %d", (plr->mo->y)>>FRACBITS); 765 HUlib_clearTextLine(&w_coordy); 766 s = hud_coordstry; 767 while (*s) 768 HUlib_addCharToTextLine(&w_coordy, *(s++)); 769 HUlib_drawTextLine(&w_coordy, false); 770 771 //jff 3/3/98 split coord display into x,y,z lines 772 //jff 2/22/98 added z 773 // z-coord 774 snprintf(hud_coordstrz,32*sizeof(char),"Z: %d", (plr->mo->z)>>FRACBITS); 775 HUlib_clearTextLine(&w_coordz); 776 s = hud_coordstrz; 777 while (*s) 778 HUlib_addCharToTextLine(&w_coordz, *(s++)); 779 HUlib_drawTextLine(&w_coordz, false); 780 } 781 782 // draw the weapon/health/ammo/armor/kills/keys displays if optioned 783 //jff 2/17/98 allow new hud stuff to be turned off 784 // killough 2/21/98: really allow new hud stuff to be turned off COMPLETELY 785 if 786 ( 787 hud_active>0 && // hud optioned on 788 hud_displayed && // hud on from fullscreen key 789 viewheight==SCREENHEIGHT && // fullscreen mode is active 790 !(automapmode & am_active) // automap is not active 791 ) 792 { 793 doit = !(gametic&1); //jff 3/4/98 speed update up for slow systems 794 if (doit) //jff 8/7/98 update every time, avoid lag in update 795 { 796 HU_MoveHud(); // insure HUD display coords are correct 797 798 // do the hud ammo display 799 // clear the widgets internal line 800 HUlib_clearTextLine(&w_ammo); 801 strcpy(hud_ammostr,"AMM "); 802 if (weaponinfo[plr->readyweapon].ammo == am_noammo) 803 { // special case for weapon with no ammo selected - blank bargraph + N/A 804 strcat(hud_ammostr,"\x7f\x7f\x7f\x7f\x7f\x7f\x7f N/A"); 805 w_ammo.cm = CR_GRAY; 806 } 807 else 808 { 809 int ammo = plr->ammo[weaponinfo[plr->readyweapon].ammo]; 810 int fullammo = plr->maxammo[weaponinfo[plr->readyweapon].ammo]; 811 int ammopct = (100*ammo)/fullammo; 812 int ammobars = ammopct/4; 813 814 // build the numeric amount init string 815 snprintf(ammostr,sizeof(ammostr),"%d/%d",ammo,fullammo); 816 // build the bargraph string 817 // full bargraph chars 818 for (i=4;i<4+ammobars/4;) 819 hud_ammostr[i++] = 123; 820 // plus one last character with 0,1,2,3 bars 821 switch(ammobars%4) 822 { 823 case 0: 824 break; 825 case 1: 826 hud_ammostr[i++] = 126; 827 break; 828 case 2: 829 hud_ammostr[i++] = 125; 830 break; 831 case 3: 832 hud_ammostr[i++] = 124; 833 break; 834 } 835 // pad string with blank bar characters 836 while(i<4+7) 837 hud_ammostr[i++] = 127; 838 hud_ammostr[i] = '\0'; 839 strcat(hud_ammostr,ammostr); 840 841 // set the display color from the percentage of total ammo held 842 if (ammopct<ammo_red) 843 w_ammo.cm = CR_RED; 844 else if (ammopct<ammo_yellow) 845 w_ammo.cm = CR_GOLD; 846 else 847 w_ammo.cm = CR_GREEN; 848 } 849 // transfer the init string to the widget 850 s = hud_ammostr; 851 while (*s) 852 HUlib_addCharToTextLine(&w_ammo, *(s++)); 853 } 854 // display the ammo widget every frame 855 HUlib_drawTextLine(&w_ammo, false); 856 857 // do the hud health display 858 if (doit) 859 { 860 int health = plr->health; 861 int healthbars = health>100? 25 : health/4; 862 863 // clear the widgets internal line 864 HUlib_clearTextLine(&w_health); 865 866 // build the numeric amount init string 867 snprintf(healthstr,sizeof(healthstr),"%3d",health); 868 // build the bargraph string 869 // full bargraph chars 870 for (i=4;i<4+healthbars/4;) 871 hud_healthstr[i++] = 123; 872 // plus one last character with 0,1,2,3 bars 873 switch(healthbars%4) 874 { 875 case 0: 876 break; 877 case 1: 878 hud_healthstr[i++] = 126; 879 break; 880 case 2: 881 hud_healthstr[i++] = 125; 882 break; 883 case 3: 884 hud_healthstr[i++] = 124; 885 break; 886 } 887 // pad string with blank bar characters 888 while(i<4+7) 889 hud_healthstr[i++] = 127; 890 hud_healthstr[i] = '\0'; 891 strcat(hud_healthstr,healthstr); 892 893 // set the display color from the amount of health posessed 894 if (health<health_red) 895 w_health.cm = CR_RED; 896 else if (health<health_yellow) 897 w_health.cm = CR_GOLD; 898 else if (health<=health_green) 899 w_health.cm = CR_GREEN; 900 else 901 w_health.cm = CR_BLUE; 902 903 // transfer the init string to the widget 904 s = hud_healthstr; 905 while (*s) 906 HUlib_addCharToTextLine(&w_health, *(s++)); 907 } 908 // display the health widget every frame 909 HUlib_drawTextLine(&w_health, false); 910 911 // do the hud armor display 912 if (doit) 913 { 914 int armor = plr->armorpoints; 915 int armorbars = armor>100? 25 : armor/4; 916 917 // clear the widgets internal line 918 HUlib_clearTextLine(&w_armor); 919 // build the numeric amount init string 920 snprintf(armorstr,sizeof(armorstr),"%3d",armor); 921 // build the bargraph string 922 // full bargraph chars 923 for (i=4;i<4+armorbars/4;) 924 hud_armorstr[i++] = 123; 925 // plus one last character with 0,1,2,3 bars 926 switch(armorbars%4) 927 { 928 case 0: 929 break; 930 case 1: 931 hud_armorstr[i++] = 126; 932 break; 933 case 2: 934 hud_armorstr[i++] = 125; 935 break; 936 case 3: 937 hud_armorstr[i++] = 124; 938 break; 939 } 940 // pad string with blank bar characters 941 while(i<4+7) 942 hud_armorstr[i++] = 127; 943 hud_armorstr[i] = '\0'; 944 strcat(hud_armorstr,armorstr); 945 946 // set the display color from the amount of armor posessed 947 if (armor<armor_red) 948 w_armor.cm = CR_RED; 949 else if (armor<armor_yellow) 950 w_armor.cm = CR_GOLD; 951 else if (armor<=armor_green) 952 w_armor.cm = CR_GREEN; 953 else 954 w_armor.cm = CR_BLUE; 955 956 // transfer the init string to the widget 957 s = hud_armorstr; 958 while (*s) 959 HUlib_addCharToTextLine(&w_armor, *(s++)); 960 } 961 // display the armor widget every frame 962 HUlib_drawTextLine(&w_armor, false); 963 964 // do the hud weapon display 965 if (doit) 966 { 967 int w; 968 int ammo,fullammo,ammopct; 969 970 // clear the widgets internal line 971 HUlib_clearTextLine(&w_weapon); 972 i=4; hud_weapstr[i] = '\0'; //jff 3/7/98 make sure ammo goes away 973 974 // do each weapon that exists in current gamemode 975 for (w=0;w<=wp_supershotgun;w++) //jff 3/4/98 show fists too, why not? 976 { 977 int ok=1; 978 //jff avoid executing for weapons that do not exist 979 switch (gamemode) 980 { 981 case shareware: 982 if (w>=wp_plasma && w!=wp_chainsaw) 983 ok=0; 984 break; 985 case retail: 986 case registered: 987 if (w>=wp_supershotgun) 988 ok=0; 989 break; 990 default: 991 case commercial: 992 break; 993 } 994 if (!ok) continue; 995 996 ammo = plr->ammo[weaponinfo[w].ammo]; 997 fullammo = plr->maxammo[weaponinfo[w].ammo]; 998 ammopct=0; 999 1000 // skip weapons not currently posessed 1001 if (!plr->weaponowned[w]) 1002 continue; 1003 1004 ammopct = fullammo? (100*ammo)/fullammo : 100; 1005 1006 // display each weapon number in a color related to the ammo for it 1007 hud_weapstr[i++] = '\x1b'; //jff 3/26/98 use ESC not '\' for paths 1008 if (weaponinfo[w].ammo==am_noammo) //jff 3/14/98 show berserk on HUD 1009 hud_weapstr[i++] = plr->powers[pw_strength]? '0'+CR_GREEN : '0'+CR_GRAY; 1010 else if (ammopct<ammo_red) 1011 hud_weapstr[i++] = '0'+CR_RED; 1012 else if (ammopct<ammo_yellow) 1013 hud_weapstr[i++] = '0'+CR_GOLD; 1014 else 1015 hud_weapstr[i++] = '0'+CR_GREEN; 1016 hud_weapstr[i++] = '0'+w+1; 1017 hud_weapstr[i++] = ' '; 1018 hud_weapstr[i] = '\0'; 1019 } 1020 1021 // transfer the init string to the widget 1022 s = hud_weapstr; 1023 while (*s) 1024 HUlib_addCharToTextLine(&w_weapon, *(s++)); 1025 } 1026 // display the weapon widget every frame 1027 HUlib_drawTextLine(&w_weapon, false); 1028 1029 if (doit && hud_active>1) 1030 { 1031 int k; 1032 1033 hud_keysstr[4] = '\0'; //jff 3/7/98 make sure deleted keys go away 1034 //jff add case for graphic key display 1035 if (!deathmatch && hud_graph_keys) 1036 { 1037 i=0; 1038 hud_gkeysstr[i] = '\0'; //jff 3/7/98 init graphic keys widget string 1039 // build text string whose characters call out graphic keys from fontk 1040 for (k=0;k<6;k++) 1041 { 1042 // skip keys not possessed 1043 if (!plr->cards[k]) 1044 continue; 1045 1046 hud_gkeysstr[i++] = '!'+k; // key number plus '!' is char for key 1047 hud_gkeysstr[i++] = ' '; // spacing 1048 hud_gkeysstr[i++] = ' '; 1049 } 1050 hud_gkeysstr[i]='\0'; 1051 } 1052 else // not possible in current code, unless deathmatching, 1053 { 1054 i=4; 1055 hud_keysstr[i] = '\0'; //jff 3/7/98 make sure deleted keys go away 1056 1057 // if deathmatch, build string showing top four frag counts 1058 if (deathmatch) //jff 3/17/98 show frags, not keys, in deathmatch 1059 { 1060 int top1=-999,top2=-999,top3=-999,top4=-999; 1061 int idx1=-1,idx2=-1,idx3=-1,idx4=-1; 1062 int fragcount,m; 1063 char numbuf[32]; 1064 1065 // scan thru players 1066 for (k=0;k<MAXPLAYERS;k++) 1067 { 1068 // skip players not in game 1069 if (!playeringame[k]) 1070 continue; 1071 1072 fragcount = 0; 1073 // compute number of times they've fragged each player 1074 // minus number of times they've been fragged by them 1075 for (m=0;m<MAXPLAYERS;m++) 1076 { 1077 if (!playeringame[m]) continue; 1078 fragcount += (m!=k)? players[k].frags[m] : -players[k].frags[m]; 1079 } 1080 1081 // very primitive sort of frags to find top four 1082 if (fragcount>top1) 1083 { 1084 top4=top3; top3=top2; top2 = top1; top1=fragcount; 1085 idx4=idx3; idx3=idx2; idx2 = idx1; idx1=k; 1086 } 1087 else if (fragcount>top2) 1088 { 1089 top4=top3; top3=top2; top2=fragcount; 1090 idx4=idx3; idx3=idx2; idx2=k; 1091 } 1092 else if (fragcount>top3) 1093 { 1094 top4=top3; top3=fragcount; 1095 idx4=idx3; idx3=k; 1096 } 1097 else if (fragcount>top4) 1098 { 1099 top4=fragcount; 1100 idx4=k; 1101 } 1102 } 1103 // if the biggest number exists, put it in the init string 1104 if (idx1>-1) 1105 { 1106 snprintf(numbuf,sizeof(numbuf),"%5d",top1); 1107 // make frag count in player's color via escape code 1108 hud_keysstr[i++] = '\x1b'; //jff 3/26/98 use ESC not '\' for paths 1109 hud_keysstr[i++] = '0'+plyrcoltran[idx1&3]; 1110 s = numbuf; 1111 while (*s) 1112 hud_keysstr[i++] = *(s++); 1113 } 1114 // if the second biggest number exists, put it in the init string 1115 if (idx2>-1) 1116 { 1117 snprintf(numbuf,sizeof(numbuf),"%5d",top2); 1118 // make frag count in player's color via escape code 1119 hud_keysstr[i++] = '\x1b'; //jff 3/26/98 use ESC not '\' for paths 1120 hud_keysstr[i++] = '0'+plyrcoltran[idx2&3]; 1121 s = numbuf; 1122 while (*s) 1123 hud_keysstr[i++] = *(s++); 1124 } 1125 // if the third biggest number exists, put it in the init string 1126 if (idx3>-1) 1127 { 1128 snprintf(numbuf,sizeof(numbuf),"%5d",top3); 1129 // make frag count in player's color via escape code 1130 hud_keysstr[i++] = '\x1b'; //jff 3/26/98 use ESC not '\' for paths 1131 hud_keysstr[i++] = '0'+plyrcoltran[idx3&3]; 1132 s = numbuf; 1133 while (*s) 1134 hud_keysstr[i++] = *(s++); 1135 } 1136 // if the fourth biggest number exists, put it in the init string 1137 if (idx4>-1) 1138 { 1139 snprintf(numbuf,sizeof(numbuf),"%5d",top4); 1140 // make frag count in player's color via escape code 1141 hud_keysstr[i++] = '\x1b'; //jff 3/26/98 use ESC not '\' for paths 1142 hud_keysstr[i++] = '0'+plyrcoltran[idx4&3]; 1143 s = numbuf; 1144 while (*s) 1145 hud_keysstr[i++] = *(s++); 1146 } 1147 hud_keysstr[i] = '\0'; 1148 } //jff 3/17/98 end of deathmatch clause 1149 else // build alphabetical key display (not used currently) 1150 { 1151 // scan the keys 1152 for (k=0;k<6;k++) 1153 { 1154 // skip any not possessed by the displayed player's stats 1155 if (!plr->cards[k]) 1156 continue; 1157 1158 // use color escapes to make text in key's color 1159 hud_keysstr[i++] = '\x1b'; //jff 3/26/98 use ESC not '\' for paths 1160 switch(k) 1161 { 1162 case 0: 1163 hud_keysstr[i++] = '0'+CR_BLUE; 1164 hud_keysstr[i++] = 'B'; 1165 hud_keysstr[i++] = 'C'; 1166 hud_keysstr[i++] = ' '; 1167 break; 1168 case 1: 1169 hud_keysstr[i++] = '0'+CR_GOLD; 1170 hud_keysstr[i++] = 'Y'; 1171 hud_keysstr[i++] = 'C'; 1172 hud_keysstr[i++] = ' '; 1173 break; 1174 case 2: 1175 hud_keysstr[i++] = '0'+CR_RED; 1176 hud_keysstr[i++] = 'R'; 1177 hud_keysstr[i++] = 'C'; 1178 hud_keysstr[i++] = ' '; 1179 break; 1180 case 3: 1181 hud_keysstr[i++] = '0'+CR_BLUE; 1182 hud_keysstr[i++] = 'B'; 1183 hud_keysstr[i++] = 'S'; 1184 hud_keysstr[i++] = ' '; 1185 break; 1186 case 4: 1187 hud_keysstr[i++] = '0'+CR_GOLD; 1188 hud_keysstr[i++] = 'Y'; 1189 hud_keysstr[i++] = 'S'; 1190 hud_keysstr[i++] = ' '; 1191 break; 1192 case 5: 1193 hud_keysstr[i++] = '0'+CR_RED; 1194 hud_keysstr[i++] = 'R'; 1195 hud_keysstr[i++] = 'S'; 1196 hud_keysstr[i++] = ' '; 1197 break; 1198 } 1199 hud_keysstr[i]='\0'; 1200 } 1201 } 1202 } 1203 } 1204 // display the keys/frags line each frame 1205 if (hud_active>1) 1206 { 1207 HUlib_clearTextLine(&w_keys); // clear the widget strings 1208 HUlib_clearTextLine(&w_gkeys); 1209 1210 // transfer the built string (frags or key title) to the widget 1211 s = hud_keysstr; //jff 3/7/98 display key titles/key text or frags 1212 while (*s) 1213 HUlib_addCharToTextLine(&w_keys, *(s++)); 1214 HUlib_drawTextLine(&w_keys, false); 1215 1216 //jff 3/17/98 show graphic keys in non-DM only 1217 if (!deathmatch) //jff 3/7/98 display graphic keys 1218 { 1219 // transfer the graphic key text to the widget 1220 s = hud_gkeysstr; 1221 while (*s) 1222 HUlib_addCharToTextLine(&w_gkeys, *(s++)); 1223 // display the widget 1224 HUlib_drawTextLine(&w_gkeys, false); 1225 } 1226 } 1227 1228 // display the hud kills/items/secret display if optioned 1229 if (!hud_nosecrets) 1230 { 1231 if (hud_active>1 && doit) 1232 { 1233 // clear the internal widget text buffer 1234 HUlib_clearTextLine(&w_monsec); 1235 //jff 3/26/98 use ESC not '\' for paths 1236 // build the init string with fixed colors 1237 snprintf 1238 ( 1239 hud_monsecstr,80*sizeof(char), 1240 "STS \x1b\x36K \x1b\x33%d \x1b\x36M \x1b\x33%d \x1b\x37I \x1b\x33%d/%d \x1b\x35S \x1b\x33%d/%d", 1241 plr->killcount,totallive, 1242 plr->itemcount,totalitems, 1243 plr->secretcount,totalsecret 1244 ); 1245 // transfer the init string to the widget 1246 s = hud_monsecstr; 1247 while (*s) 1248 HUlib_addCharToTextLine(&w_monsec, *(s++)); 1249 } 1250 // display the kills/items/secrets each frame, if optioned 1251 if (hud_active>1) 1252 HUlib_drawTextLine(&w_monsec, false); 1253 } 1254 } 1255 1256 //jff 3/4/98 display last to give priority 1257 HU_Erase(); // jff 4/24/98 Erase current lines before drawing current 1258 // needed when screen not fullsize 1259 1260 //jff 4/21/98 if setup has disabled message list while active, turn it off 1261 if (hud_msg_lines<=1) 1262 message_list = false; 1263 1264 // if the message review not enabled, show the standard message widget 1265 if (!message_list) 1266 HUlib_drawSText(&w_message); 1267 1268 // if the message review is enabled show the scrolling message review 1269 if (hud_msg_lines>1 && message_list) 1270 HUlib_drawMText(&w_rtext); 1271 1272 // display the interactive buffer for chat entry 1273 HUlib_drawIText(&w_chat); 1274} 1275 1276// 1277// HU_Erase() 1278// 1279// Erase hud display lines that can be trashed by small screen display 1280// 1281// Passed nothing, returns nothing 1282// 1283void HU_Erase(void) 1284{ 1285 // erase the message display or the message review display 1286 if (!message_list) 1287 HUlib_eraseSText(&w_message); 1288 else 1289 HUlib_eraseMText(&w_rtext); 1290 1291 // erase the interactive text buffer for chat entry 1292 HUlib_eraseIText(&w_chat); 1293 1294 // erase the automap title 1295 HUlib_eraseTextLine(&w_title); 1296} 1297 1298// 1299// HU_Ticker() 1300// 1301// Update the hud displays once per frame 1302// 1303// Passed nothing, returns nothing 1304// 1305static boolean bsdown; // Is backspace down? 1306static int bscounter; 1307 1308void HU_Ticker(void) 1309{ 1310 int i, rc; 1311 char c; 1312 1313 // tick down message counter if message is up 1314 if (message_counter && !--message_counter) 1315 { 1316 message_on = false; 1317 message_nottobefuckedwith = false; 1318 } 1319 if (bsdown && bscounter++ > 9) { 1320 HUlib_keyInIText(&w_chat, (unsigned char)key_backspace); 1321 bscounter = 8; 1322 } 1323 1324 // if messages on, or "Messages Off" is being displayed 1325 // this allows the notification of turning messages off to be seen 1326 if (showMessages || message_dontfuckwithme) 1327 { 1328 // display message if necessary 1329 if ((plr->message && !message_nottobefuckedwith) 1330 || (plr->message && message_dontfuckwithme)) 1331 { 1332 //post the message to the message widget 1333 HUlib_addMessageToSText(&w_message, 0, plr->message); 1334 //jff 2/26/98 add message to refresh text widget too 1335 HUlib_addMessageToMText(&w_rtext, 0, plr->message); 1336 1337 // clear the message to avoid posting multiple times 1338 plr->message = 0; 1339 // note a message is displayed 1340 message_on = true; 1341 // start the message persistence counter 1342 message_counter = HU_MSGTIMEOUT; 1343 // transfer "Messages Off" exception to the "being displayed" variable 1344 message_nottobefuckedwith = message_dontfuckwithme; 1345 // clear the flag that "Messages Off" is being posted 1346 message_dontfuckwithme = 0; 1347 } 1348 } 1349 1350 // check for incoming chat characters 1351 if (netgame) 1352 { 1353 for (i=0; i<MAXPLAYERS; i++) 1354 { 1355 if (!playeringame[i]) 1356 continue; 1357 if (i != consoleplayer 1358 && (c = players[i].cmd.chatchar)) 1359 { 1360 if (c <= HU_BROADCAST) 1361 chat_dest[i] = c; 1362 else 1363 { 1364 if (c >= 'a' && c <= 'z') 1365 c = (char) shiftxform[(unsigned char) c]; 1366 rc = HUlib_keyInIText(&w_inputbuffer[i], c); 1367 if (rc && c == KEY_ENTER) 1368 { 1369 if (w_inputbuffer[i].l.len 1370 && (chat_dest[i] == consoleplayer+1 1371 || chat_dest[i] == HU_BROADCAST)) 1372 { 1373 HUlib_addMessageToSText(&w_message, 1374 player_names[i], 1375 w_inputbuffer[i].l.l); 1376 1377 message_nottobefuckedwith = true; 1378 message_on = true; 1379 message_counter = HU_MSGTIMEOUT; 1380 if ( gamemode == commercial ) 1381 S_StartSound(0, sfx_radio); 1382 else 1383 S_StartSound(0, sfx_tink); 1384 } 1385 HUlib_resetIText(&w_inputbuffer[i]); 1386 } 1387 } 1388 players[i].cmd.chatchar = 0; 1389 } 1390 } 1391 } 1392} 1393 1394#define QUEUESIZE 128 1395 1396static char chatchars[QUEUESIZE]; 1397static int head = 0; 1398static int tail = 0; 1399 1400// 1401// HU_queueChatChar() 1402// 1403// Add an incoming character to the circular chat queue 1404// 1405// Passed the character to queue, returns nothing 1406// 1407void HU_queueChatChar(char c) 1408{ 1409 if (((head + 1) & (QUEUESIZE-1)) == tail) 1410 { 1411 plr->message = HUSTR_MSGU; 1412 } 1413 else 1414 { 1415 chatchars[head] = c; 1416 head = (head + 1) & (QUEUESIZE-1); 1417 } 1418} 1419 1420// 1421// HU_dequeueChatChar() 1422// 1423// Remove the earliest added character from the circular chat queue 1424// 1425// Passed nothing, returns the character dequeued 1426// 1427char HU_dequeueChatChar(void) 1428{ 1429 char c; 1430 1431 if (head != tail) 1432 { 1433 c = chatchars[tail]; 1434 tail = (tail + 1) & (QUEUESIZE-1); 1435 } 1436 else 1437 { 1438 c = 0; 1439 } 1440 return c; 1441} 1442 1443// 1444// HU_Responder() 1445// 1446// Responds to input events that affect the heads up displays 1447// 1448// Passed the event to respond to, returns true if the event was handled 1449// 1450boolean HU_Responder(event_t *ev) 1451{ 1452 1453 static char lastmessage[HU_MAXLINELENGTH+1]; 1454 const char* macromessage; // CPhipps - const char* 1455 boolean eatkey = false; 1456 static boolean shiftdown = false; 1457 static boolean altdown = false; 1458 unsigned char c; 1459 int i; 1460 int numplayers; 1461 1462 static int num_nobrainers = 0; 1463 1464 numplayers = 0; 1465 for (i=0 ; i<MAXPLAYERS ; i++) 1466 numplayers += playeringame[i]; 1467 1468 if (ev->data1 == key_shift) 1469 { 1470 shiftdown = ev->type == ev_keydown; 1471 return false; 1472 } 1473 else if (ev->data1 == key_alt) 1474 { 1475 altdown = ev->type == ev_keydown; 1476 return false; 1477 } 1478 else if (ev->data1 == key_backspace) 1479 { 1480 bsdown = ev->type == ev_keydown; 1481 bscounter = 0; 1482 } 1483 1484 if (ev->type != ev_keydown) 1485 return false; 1486 1487 if (!chat_on) 1488 { 1489 if (ev->data1 == key_enter) // phares 1490 { 1491#ifndef INSTRUMENTED // never turn on message review if INSTRUMENTED defined 1492 if (hud_msg_lines>1) // it posts multi-line messages that will trash 1493 { 1494 if (message_list) HU_Erase(); //jff 4/28/98 erase behind messages 1495 message_list = !message_list; //jff 2/26/98 toggle list of messages 1496 } 1497#endif 1498 if (!message_list) // if not message list, refresh message 1499 { 1500 message_on = true; 1501 message_counter = HU_MSGTIMEOUT; 1502 } 1503 eatkey = true; 1504 }//jff 2/26/98 no chat if message review is displayed 1505 else if (!message_list && netgame && ev->data1 == key_chat) 1506 { 1507 eatkey = chat_on = true; 1508 HUlib_resetIText(&w_chat); 1509 HU_queueChatChar(HU_BROADCAST); 1510 }//jff 2/26/98 no chat if message review is displayed 1511 // killough 10/02/98: no chat if demo playback 1512 else if (!demoplayback && !message_list && netgame && numplayers > 2) 1513 { 1514 for (i=0; i<MAXPLAYERS ; i++) 1515 { 1516 if (ev->data1 == destination_keys[i]) 1517 { 1518 if (playeringame[i] && i!=consoleplayer) 1519 { 1520 eatkey = chat_on = true; 1521 HUlib_resetIText(&w_chat); 1522 HU_queueChatChar((char)(i+1)); 1523 break; 1524 } 1525 else if (i == consoleplayer) 1526 { 1527 num_nobrainers++; 1528 if (num_nobrainers < 3) 1529 plr->message = HUSTR_TALKTOSELF1; 1530 else if (num_nobrainers < 6) 1531 plr->message = HUSTR_TALKTOSELF2; 1532 else if (num_nobrainers < 9) 1533 plr->message = HUSTR_TALKTOSELF3; 1534 else if (num_nobrainers < 32) 1535 plr->message = HUSTR_TALKTOSELF4; 1536 else 1537 plr->message = HUSTR_TALKTOSELF5; 1538 } 1539 } 1540 } 1541 } 1542 }//jff 2/26/98 no chat functions if message review is displayed 1543 else if (!message_list) 1544 { 1545 c = ev->data1; 1546 // send a macro 1547 if (altdown) 1548 { 1549 c = c - '0'; 1550 if (c > 9) 1551 return false; 1552 macromessage = chat_macros[c]; 1553 1554 // kill last message with a '\n' 1555 HU_queueChatChar((char)key_enter); // DEBUG!!! // phares 1556 1557 // send the macro message 1558 while (*macromessage) 1559 HU_queueChatChar(*macromessage++); 1560 HU_queueChatChar((char)key_enter); // phares 1561 1562 // leave chat mode and notify that it was sent 1563 chat_on = false; 1564 strcpy(lastmessage, chat_macros[c]); 1565 plr->message = lastmessage; 1566 eatkey = true; 1567 } 1568 else 1569 { 1570 if (shiftdown || (c >= 'a' && c <= 'z')) 1571 c = shiftxform[c]; 1572 eatkey = HUlib_keyInIText(&w_chat, c); 1573 if (eatkey) 1574 HU_queueChatChar(c); 1575 1576 if (c == key_enter) // phares 1577 { 1578 chat_on = false; 1579 if (w_chat.l.len) 1580 { 1581 strcpy(lastmessage, w_chat.l.l); 1582 plr->message = lastmessage; 1583 } 1584 } 1585 else if (c == key_escape) // phares 1586 chat_on = false; 1587 } 1588 } 1589 return eatkey; 1590}