A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 1153 lines 31 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: 28 * Status bar code. 29 * Does the face/direction indicator animatin. 30 * Does palette indicators as well (red pain/berserk, bright pickup) 31 * 32 *-----------------------------------------------------------------------------*/ 33 34#include "doomdef.h" 35#include "doomstat.h" 36#include "m_random.h" 37#include "i_video.h" 38#include "w_wad.h" 39#include "st_stuff.h" 40#include "st_lib.h" 41#include "r_main.h" 42#include "am_map.h" 43#include "m_cheat.h" 44#include "s_sound.h" 45#include "sounds.h" 46#include "dstrings.h" 47#include "r_draw.h" 48 49// 50// STATUS BAR DATA 51// 52 53// Palette indices. 54// For damage/bonus red-/gold-shifts 55#define STARTREDPALS 1 56#define STARTBONUSPALS 9 57#define NUMREDPALS 8 58#define NUMBONUSPALS 4 59// Radiation suit, green shift. 60#define RADIATIONPAL 13 61 62// Location of status bar 63#define ST_X 0 64#define ST_X2 104 65 66// proff 08/18/98: Changed for high-res 67#define ST_FX (ST_X+143) 68#define ST_FY (ST_Y+1) 69//#define ST_FX 143 70//#define ST_FY 169 71 72// Should be set to patch width 73// for tall numbers later on 74#define ST_TALLNUMWIDTH (tallnum[0]->width) 75 76// Number of status faces. 77#define ST_NUMPAINFACES 5 78#define ST_NUMSTRAIGHTFACES 3 79#define ST_NUMTURNFACES 2 80#define ST_NUMSPECIALFACES 3 81 82#define ST_FACESTRIDE \ 83 (ST_NUMSTRAIGHTFACES+ST_NUMTURNFACES+ST_NUMSPECIALFACES) 84 85#define ST_NUMEXTRAFACES 2 86 87#define ST_NUMFACES \ 88 (ST_FACESTRIDE*ST_NUMPAINFACES+ST_NUMEXTRAFACES) 89 90#define ST_TURNOFFSET (ST_NUMSTRAIGHTFACES) 91#define ST_OUCHOFFSET (ST_TURNOFFSET + ST_NUMTURNFACES) 92#define ST_EVILGRINOFFSET (ST_OUCHOFFSET + 1) 93#define ST_RAMPAGEOFFSET (ST_EVILGRINOFFSET + 1) 94#define ST_GODFACE (ST_NUMPAINFACES*ST_FACESTRIDE) 95#define ST_DEADFACE (ST_GODFACE+1) 96 97// proff 08/18/98: Changed for high-res 98#define ST_FACESX (ST_X+143) 99#define ST_FACESY (ST_Y) 100//#define ST_FACESX 143 101//#define ST_FACESY 168 102 103#define ST_EVILGRINCOUNT (2*TICRATE) 104#define ST_STRAIGHTFACECOUNT (TICRATE/2) 105#define ST_TURNCOUNT (1*TICRATE) 106#define ST_OUCHCOUNT (1*TICRATE) 107#define ST_RAMPAGEDELAY (2*TICRATE) 108 109#define ST_MUCHPAIN 20 110 111// Location and size of statistics, 112// justified according to widget type. 113// Problem is, within which space? STbar? Screen? 114// Note: this could be read in by a lump. 115// Problem is, is the stuff rendered 116// into a buffer, 117// or into the frame buffer? 118// I dunno, why don't you go and find out!!! killough 119 120// AMMO number pos. 121#define ST_AMMOWIDTH 3 122// proff 08/18/98: Changed for high-res 123#define ST_AMMOX (ST_X+44) 124#define ST_AMMOY (ST_Y+3) 125//#define ST_AMMOX 44 126//#define ST_AMMOY 171 127 128// HEALTH number pos. 129#define ST_HEALTHWIDTH 3 130// proff 08/18/98: Changed for high-res 131#define ST_HEALTHX (ST_X+90) 132#define ST_HEALTHY (ST_Y+3) 133//#define ST_HEALTHX 90 134//#define ST_HEALTHY 171 135 136// Weapon pos. 137// proff 08/18/98: Changed for high-res 138#define ST_ARMSX (ST_X+111) 139#define ST_ARMSY (ST_Y+4) 140#define ST_ARMSBGX (ST_X+104) 141#define ST_ARMSBGY (ST_Y) 142//#define ST_ARMSX 111 143//#define ST_ARMSY 172 144//#define ST_ARMSBGX 104 145//#define ST_ARMSBGY 168 146#define ST_ARMSXSPACE 12 147#define ST_ARMSYSPACE 10 148 149// Frags pos. 150// proff 08/18/98: Changed for high-res 151#define ST_FRAGSX (ST_X+138) 152#define ST_FRAGSY (ST_Y+3) 153//#define ST_FRAGSX 138 154//#define ST_FRAGSY 171 155#define ST_FRAGSWIDTH 2 156 157// ARMOR number pos. 158#define ST_ARMORWIDTH 3 159// proff 08/18/98: Changed for high-res 160#define ST_ARMORX (ST_X+221) 161#define ST_ARMORY (ST_Y+3) 162//#define ST_ARMORX 221 163//#define ST_ARMORY 171 164 165// Key icon positions. 166#define ST_KEY0WIDTH 8 167#define ST_KEY0HEIGHT 5 168// proff 08/18/98: Changed for high-res 169#define ST_KEY0X (ST_X+239) 170#define ST_KEY0Y (ST_Y+3) 171//#define ST_KEY0X 239 172//#define ST_KEY0Y 171 173#define ST_KEY1WIDTH ST_KEY0WIDTH 174// proff 08/18/98: Changed for high-res 175#define ST_KEY1X (ST_X+239) 176#define ST_KEY1Y (ST_Y+13) 177//#define ST_KEY1X 239 178//#define ST_KEY1Y 181 179#define ST_KEY2WIDTH ST_KEY0WIDTH 180// proff 08/18/98: Changed for high-res 181#define ST_KEY2X (ST_X+239) 182#define ST_KEY2Y (ST_Y+23) 183//#define ST_KEY2X 239 184//#define ST_KEY2Y 191 185 186// Ammunition counter. 187#define ST_AMMO0WIDTH 3 188#define ST_AMMO0HEIGHT 6 189// proff 08/18/98: Changed for high-res 190#define ST_AMMO0X (ST_X+288) 191#define ST_AMMO0Y (ST_Y+5) 192//#define ST_AMMO0X 288 193//#define ST_AMMO0Y 173 194#define ST_AMMO1WIDTH ST_AMMO0WIDTH 195// proff 08/18/98: Changed for high-res 196#define ST_AMMO1X (ST_X+288) 197#define ST_AMMO1Y (ST_Y+11) 198//#define ST_AMMO1X 288 199//#define ST_AMMO1Y 179 200#define ST_AMMO2WIDTH ST_AMMO0WIDTH 201// proff 08/18/98: Changed for high-res 202#define ST_AMMO2X (ST_X+288) 203#define ST_AMMO2Y (ST_Y+23) 204//#define ST_AMMO2X 288 205//#define ST_AMMO2Y 191 206#define ST_AMMO3WIDTH ST_AMMO0WIDTH 207// proff 08/18/98: Changed for high-res 208#define ST_AMMO3X (ST_X+288) 209#define ST_AMMO3Y (ST_Y+17) 210//#define ST_AMMO3X 288 211//#define ST_AMMO3Y 185 212 213// Indicate maximum ammunition. 214// Only needed because backpack exists. 215#define ST_MAXAMMO0WIDTH 3 216#define ST_MAXAMMO0HEIGHT 5 217// proff 08/18/98: Changed for high-res 218#define ST_MAXAMMO0X (ST_X+314) 219#define ST_MAXAMMO0Y (ST_Y+5) 220//#define ST_MAXAMMO0X 314 221//#define ST_MAXAMMO0Y 173 222#define ST_MAXAMMO1WIDTH ST_MAXAMMO0WIDTH 223// proff 08/18/98: Changed for high-res 224#define ST_MAXAMMO1X (ST_X+314) 225#define ST_MAXAMMO1Y (ST_Y+11) 226//#define ST_MAXAMMO1X 314 227//#define ST_MAXAMMO1Y 179 228#define ST_MAXAMMO2WIDTH ST_MAXAMMO0WIDTH 229// proff 08/18/98: Changed for high-res 230#define ST_MAXAMMO2X (ST_X+314) 231#define ST_MAXAMMO2Y (ST_Y+23) 232//#define ST_MAXAMMO2X 314 233//#define ST_MAXAMMO2Y 191 234#define ST_MAXAMMO3WIDTH ST_MAXAMMO0WIDTH 235// proff 08/18/98: Changed for high-res 236#define ST_MAXAMMO3X (ST_X+314) 237#define ST_MAXAMMO3Y (ST_Y+17) 238//#define ST_MAXAMMO3X 314 239//#define ST_MAXAMMO3Y 185 240 241// killough 2/8/98: weapon info position macros UNUSED, removed here 242 243// main player in game 244static player_t *plyr; 245 246// ST_Start() has just been called 247static boolean st_firsttime; 248 249// used to execute ST_Init() only once 250static int veryfirsttime = 1; 251 252// CPhipps - no longer do direct PLAYPAL handling here 253 254// used for timing 255static unsigned int st_clock; 256 257// used for making messages go away 258static int st_msgcounter=0; 259 260// used when in chat 261static st_chatstateenum_t st_chatstate; 262 263// whether in automap or first-person 264static st_stateenum_t st_gamestate; 265 266// whether left-side main status bar is active 267static boolean st_statusbaron; 268 269// whether status bar chat is active 270static boolean st_chat; 271 272// value of st_chat before message popped up 273static boolean st_oldchat; 274 275// whether chat window has the cursor on 276static boolean st_cursoron; 277 278// !deathmatch 279static boolean st_notdeathmatch; 280 281// !deathmatch && st_statusbaron 282static boolean st_armson; 283 284// !deathmatch 285static boolean st_fragson; 286 287// main bar left 288// CPhipps - convert to a bitmap 289static byte *sbar; 290static unsigned short sbar_width, sbar_height; 291 292// 0-9, tall numbers 293static patchnum_t tallnum[10]; 294 295// tall % sign 296static patchnum_t tallpercent; 297 298// 0-9, short, yellow (,different!) numbers 299static patchnum_t shortnum[10]; 300 301// 3 key-cards, 3 skulls, 3 card/skull combos 302// jff 2/24/98 extend number of patches by three skull/card combos 303static patchnum_t keys[NUMCARDS+3]; 304 305// face status patches 306static patchnum_t faces[ST_NUMFACES]; 307 308// face background 309static patchnum_t faceback; // CPhipps - single background, translated for different players 310 311// main bar right 312static patchnum_t armsbg; 313 314// weapon ownership patches 315static patchnum_t arms[6][2]; 316 317// ready-weapon widget 318static st_number_t w_ready; 319 320//jff 2/16/98 status color change levels 321int ammo_red; // ammo percent less than which status is red 322int ammo_yellow; // ammo percent less is yellow more green 323int health_red; // health amount less than which status is red 324int health_yellow; // health amount less than which status is yellow 325int health_green; // health amount above is blue, below is green 326int armor_red; // armor amount less than which status is red 327int armor_yellow; // armor amount less than which status is yellow 328int armor_green; // armor amount above is blue, below is green 329 330// in deathmatch only, summary of frags stats 331static st_number_t w_frags; 332 333// health widget 334static st_percent_t w_health; 335 336// arms background 337static st_binicon_t w_armsbg; 338 339// weapon ownership widgets 340static st_multicon_t w_arms[6]; 341 342// face status widget 343static st_multicon_t w_faces; 344 345// keycard widgets 346static st_multicon_t w_keyboxes[3]; 347 348// armor widget 349static st_percent_t w_armor; 350 351// ammo widgets 352static st_number_t w_ammo[4]; 353 354// max ammo widgets 355static st_number_t w_maxammo[4]; 356 357// number of frags so far in deathmatch 358static int st_fragscount; 359 360// used to use appopriately pained face 361static int st_oldhealth = -1; 362 363// used for evil grin 364static boolean oldweaponsowned[NUMWEAPONS]; 365 366// count until face changes 367static int st_facecount = 0; 368 369// current face index, used by w_faces 370static int st_faceindex = 0; 371 372// holds key-type for each key box on bar 373static int keyboxes[3]; 374 375// a random number per tick 376static int st_randomnumber; 377 378extern char *mapnames[]; 379 380 381// 382// STATUS BAR CODE 383// 384void ST_Stop(void); 385 386void ST_refreshBackground(void) 387{ 388 int y=0; 389 int screen=BG; 390 391 if (st_statusbaron) 392 { 393 V_DrawNamePatch(ST_X, y, screen, "STBAR", CR_DEFAULT, VPT_STRETCH); 394 395 // killough 3/7/98: make face background change with displayplayer 396 if (netgame) 397 { 398 V_DrawNumPatch(ST_FX, y, BG, faceback.lumpnum, 399 displayplayer ? CR_LIMIT+displayplayer : CR_DEFAULT, 400 displayplayer ? (VPT_TRANS | VPT_STRETCH) : VPT_STRETCH); 401 } 402 403 V_CopyRect(ST_X, y, screen, ST_SCALED_WIDTH, ST_SCALED_HEIGHT, ST_X, ST_SCALED_Y, FG, VPT_NONE); 404 } 405} 406 407 408// Respond to keyboard input events, 409// intercept cheats. 410boolean ST_Responder(event_t *ev) 411{ 412 // Filter automap on/off. 413 if (ev->type == ev_keyup && (ev->data1 & 0xffff0000) == AM_MSGHEADER) 414 { 415 switch(ev->data1) 416 { 417 case AM_MSGENTERED: 418 st_gamestate = AutomapState; 419 st_firsttime = true; 420 break; 421 422 case AM_MSGEXITED: 423 st_gamestate = FirstPersonState; 424 break; 425 } 426 } 427// else // if a user keypress... 428// if (ev->type == ev_keydown) // Try cheat responder in m_cheat.c 429// return M_FindCheats(ev->data1); // killough 4/17/98, 5/2/98 430 return false; 431} 432 433int ST_calcPainOffset(void) 434{ 435 static int lastcalc; 436 static int oldhealth = -1; 437 int health = plyr->health > 100 ? 100 : plyr->health; 438 439 if (health != oldhealth) 440 { 441 lastcalc = ST_FACESTRIDE * (((100 - health) * ST_NUMPAINFACES) / 101); 442 oldhealth = health; 443 } 444 return lastcalc; 445} 446 447 448// 449// This is a not-very-pretty routine which handles 450// the face states and their timing. 451// the precedence of expressions is: 452// dead > evil grin > turned head > straight ahead 453// 454 455void ST_updateFaceWidget(void) 456{ 457 int i; 458 angle_t badguyangle; 459 angle_t diffang; 460 static int lastattackdown = -1; 461 static int priority = 0; 462 boolean doevilgrin; 463 464 if (priority < 10) 465 { 466 // dead 467 if (!plyr->health) 468 { 469 priority = 9; 470 st_faceindex = ST_DEADFACE; 471 st_facecount = 1; 472 } 473 } 474 475 if (priority < 9) 476 { 477 if (plyr->bonuscount) 478 { 479 // picking up bonus 480 doevilgrin = false; 481 482 for (i=0;i<NUMWEAPONS;i++) 483 { 484 if (oldweaponsowned[i] != plyr->weaponowned[i]) 485 { 486 doevilgrin = true; 487 oldweaponsowned[i] = plyr->weaponowned[i]; 488 } 489 } 490 if (doevilgrin) 491 { 492 // evil grin if just picked up weapon 493 priority = 8; 494 st_facecount = ST_EVILGRINCOUNT; 495 st_faceindex = ST_calcPainOffset() + ST_EVILGRINOFFSET; 496 } 497 } 498 499 } 500 501 if (priority < 8) 502 { 503 if (plyr->damagecount && plyr->attacker && plyr->attacker != plyr->mo) 504 { 505 // being attacked 506 priority = 7; 507 508 if (plyr->health - st_oldhealth > ST_MUCHPAIN) 509 { 510 st_facecount = ST_TURNCOUNT; 511 st_faceindex = ST_calcPainOffset() + ST_OUCHOFFSET; 512 } 513 else 514 { 515 badguyangle = R_PointToAngle2(plyr->mo->x, 516 plyr->mo->y, 517 plyr->attacker->x, 518 plyr->attacker->y); 519 520 if (badguyangle > plyr->mo->angle) 521 { 522 // whether right or left 523 diffang = badguyangle - plyr->mo->angle; 524 i = diffang > ANG180; 525 } 526 else 527 { 528 // whether left or right 529 diffang = plyr->mo->angle - badguyangle; 530 i = diffang <= ANG180; 531 } // confusing, aint it? 532 533 534 st_facecount = ST_TURNCOUNT; 535 st_faceindex = ST_calcPainOffset(); 536 537 if (diffang < ANG45) 538 { 539 // head-on 540 st_faceindex += ST_RAMPAGEOFFSET; 541 } 542 else if (i) 543 { 544 // turn face right 545 st_faceindex += ST_TURNOFFSET; 546 } 547 else 548 { 549 // turn face left 550 st_faceindex += ST_TURNOFFSET+1; 551 } 552 } 553 } 554 } 555 556 if (priority < 7) 557 { 558 // getting hurt because of your own damn stupidity 559 if (plyr->damagecount) 560 { 561 if (plyr->health - st_oldhealth > ST_MUCHPAIN) 562 { 563 priority = 7; 564 st_facecount = ST_TURNCOUNT; 565 st_faceindex = ST_calcPainOffset() + ST_OUCHOFFSET; 566 } 567 else 568 { 569 priority = 6; 570 st_facecount = ST_TURNCOUNT; 571 st_faceindex = ST_calcPainOffset() + ST_RAMPAGEOFFSET; 572 } 573 574 } 575 576 } 577 578 if (priority < 6) 579 { 580 // rapid firing 581 if (plyr->attackdown) 582 { 583 if (lastattackdown==-1) 584 lastattackdown = ST_RAMPAGEDELAY; 585 else if (!--lastattackdown) 586 { 587 priority = 5; 588 st_faceindex = ST_calcPainOffset() + ST_RAMPAGEOFFSET; 589 st_facecount = 1; 590 lastattackdown = 1; 591 } 592 } 593 else 594 lastattackdown = -1; 595 596 } 597 598 if (priority < 5) 599 { 600 // invulnerability 601 if ((plyr->cheats & CF_GODMODE) 602 || plyr->powers[pw_invulnerability]) 603 { 604 priority = 4; 605 606 st_faceindex = ST_GODFACE; 607 st_facecount = 1; 608 609 } 610 611 } 612 613 // look left or look right if the facecount has timed out 614 if (!st_facecount) 615 { 616 st_faceindex = ST_calcPainOffset() + (st_randomnumber % 3); 617 st_facecount = ST_STRAIGHTFACECOUNT; 618 priority = 0; 619 } 620 621 st_facecount--; 622 623} 624 625int sts_traditional_keys; // killough 2/28/98: traditional status bar keys 626 627void ST_updateWidgets(void) 628{ 629 static int largeammo = 1994; // means "n/a" 630 int i; 631 632 // must redirect the pointer if the ready weapon has changed. 633 // if (w_ready.data != plyr->readyweapon) 634 // { 635 if (weaponinfo[plyr->readyweapon].ammo == am_noammo) 636 w_ready.num = &largeammo; 637 else 638 w_ready.num = &plyr->ammo[weaponinfo[plyr->readyweapon].ammo]; 639 //{ 640 // static int tic=0; 641 // static int dir=-1; 642 // if (!(tic&15)) 643 // plyr->ammo[weaponinfo[plyr->readyweapon].ammo]+=dir; 644 // if (plyr->ammo[weaponinfo[plyr->readyweapon].ammo] == -100) 645 // dir = 1; 646 // tic++; 647 // } 648 w_ready.data = plyr->readyweapon; 649 650 // if (*w_ready.on) 651 // STlib_updateNum(&w_ready, true); 652 // refresh weapon change 653 // } 654 655 // update keycard multiple widgets 656 for (i=0;i<3;i++) 657 { 658 keyboxes[i] = plyr->cards[i] ? i : -1; 659 660 //jff 2/24/98 select double key 661 //killough 2/28/98: preserve traditional keys by config option 662 663 if (plyr->cards[i+3]) 664 keyboxes[i] = keyboxes[i]==-1 || sts_traditional_keys ? i+3 : i+6; 665 } 666 667 // refresh everything if this is him coming back to life 668 ST_updateFaceWidget(); 669 670 // used by the w_armsbg widget 671 st_notdeathmatch = !deathmatch; 672 673 // used by w_arms[] widgets 674 st_armson = st_statusbaron && !deathmatch; 675 676 // used by w_frags widget 677 st_fragson = deathmatch && st_statusbaron; 678 st_fragscount = 0; 679 680 for (i=0 ; i<MAXPLAYERS ; i++) 681 { 682 if (i != displayplayer) // killough 3/7/98 683 st_fragscount += plyr->frags[i]; 684 else 685 st_fragscount -= plyr->frags[i]; 686 } 687 688 // get rid of chat window if up because of message 689 if (!--st_msgcounter) 690 st_chat = st_oldchat; 691 692} 693 694void ST_Ticker (void) 695{ 696 st_clock++; 697 st_randomnumber = M_Random(); 698 ST_updateWidgets(); 699 st_oldhealth = plyr->health; 700} 701 702static int st_palette = 0; 703 704void ST_doPaletteStuff(void) 705{ 706 int palette; 707 int cnt = plyr->damagecount; 708 709 if (plyr->powers[pw_strength]) 710 { 711 // slowly fade the berzerk out 712 int bzc = 12 - (plyr->powers[pw_strength]>>6); 713 if (bzc > cnt) 714 cnt = bzc; 715 } 716 717 if (cnt) 718 { 719 palette = (cnt+7)>>3; 720 if (palette >= NUMREDPALS) 721 palette = NUMREDPALS-1; 722 palette += STARTREDPALS; 723 } 724 else 725 if (plyr->bonuscount) 726 { 727 palette = (plyr->bonuscount+7)>>3; 728 if (palette >= NUMBONUSPALS) 729 palette = NUMBONUSPALS-1; 730 palette += STARTBONUSPALS; 731 } 732 else 733 if (plyr->powers[pw_ironfeet] > 4*32 || plyr->powers[pw_ironfeet] & 8) 734 palette = RADIATIONPAL; 735 else 736 palette = 0; 737 738 if (palette != st_palette) 739 V_SetPalette(st_palette = palette); // CPhipps - use new palette function 740} 741 742void ST_drawWidgets(boolean refresh) 743{ 744 int i; 745 746 // used by w_arms[] widgets 747 st_armson = st_statusbaron && !deathmatch; 748 749 // used by w_frags widget 750 st_fragson = deathmatch && st_statusbaron; 751 752 //jff 2/16/98 make color of ammo depend on amount 753 if (*w_ready.num*100 < ammo_red*plyr->maxammo[weaponinfo[w_ready.data].ammo]) 754 STlib_updateNum(&w_ready, CR_RED, refresh); 755 else 756 if (*w_ready.num*100 < 757 ammo_yellow*plyr->maxammo[weaponinfo[w_ready.data].ammo]) 758 STlib_updateNum(&w_ready, CR_GOLD, refresh); 759 else 760 STlib_updateNum(&w_ready, CR_GREEN, refresh); 761 762 for (i=0;i<4;i++) 763 { 764 STlib_updateNum(&w_ammo[i], CR_DEFAULT, refresh); 765 STlib_updateNum(&w_maxammo[i], CR_DEFAULT, refresh); 766 } 767 768 //jff 2/16/98 make color of health depend on amount 769 if (*w_health.n.num<health_red) 770 STlib_updatePercent(&w_health, CR_RED, refresh); 771 else if (*w_health.n.num<health_yellow) 772 STlib_updatePercent(&w_health, CR_GOLD, refresh); 773 else if (*w_health.n.num<=health_green) 774 STlib_updatePercent(&w_health, CR_GREEN, refresh); 775 else 776 STlib_updatePercent(&w_health, CR_BLUE2, refresh); //killough 2/28/98 777 778 //jff 2/16/98 make color of armor depend on amount 779 if (*w_armor.n.num<armor_red) 780 STlib_updatePercent(&w_armor, CR_RED, refresh); 781 else if (*w_armor.n.num<armor_yellow) 782 STlib_updatePercent(&w_armor, CR_GOLD, refresh); 783 else if (*w_armor.n.num<=armor_green) 784 STlib_updatePercent(&w_armor, CR_GREEN, refresh); 785 else 786 STlib_updatePercent(&w_armor, CR_BLUE2, refresh); //killough 2/28/98 787 788 STlib_updateBinIcon(&w_armsbg, refresh); 789 790 for (i=0;i<6;i++) 791 STlib_updateMultIcon(&w_arms[i], refresh); 792 793 STlib_updateMultIcon(&w_faces, refresh); 794 795 for (i=0;i<3;i++) 796 STlib_updateMultIcon(&w_keyboxes[i], refresh); 797 798 STlib_updateNum(&w_frags, CR_DEFAULT, refresh); 799 800} 801 802void ST_doRefresh(void) 803{ 804 805 st_firsttime = false; 806 807 // draw status bar background to off-screen buff 808 ST_refreshBackground(); 809 810 // and refresh all widgets 811 ST_drawWidgets(true); 812 813} 814 815void ST_diffDraw(void) 816{ 817 // update all widgets 818 ST_drawWidgets(false); 819} 820 821void ST_Drawer(boolean st_statusbaron, boolean refresh) 822{ 823 /* cph - let status bar on be controlled 824 * completely by the call from D_Display 825 * proff - really do it 826 */ 827 st_firsttime = st_firsttime || refresh; 828 829 ST_doPaletteStuff(); // Do red-/gold-shifts from damage/items 830 831 if (st_statusbaron) { 832 if (st_firsttime) 833 ST_doRefresh(); /* If just after ST_Start(), refresh all */ 834 else 835 ST_diffDraw(); /* Otherwise, update as little as possible */ 836 } 837} 838 839// 840// ST_loadGraphics 841// 842// CPhipps - Loads graphics needed for status bar if doload is true, 843// unloads them otherwise 844// 845static void ST_loadGraphics(boolean doload) 846{ 847 848 int i,facenum; 849 850 char namebuf[9]; 851 // cph - macro that either acquires a pointer and lock for a lump, or 852 // unlocks it. var is referenced exactly once in either case, so ++ in arg works 853 /* 854 #define LOADORFREE(var,name) \ 855 if (!doload) { W_UnlockLumpName(name); var = NULL; } \ 856 else var = (const patch_t*)W_CacheLumpName(name) 857 */ 858 859 // Load the numbers, tall and short 860 for (i=0;i<10;i++) 861 { 862 snprintf(namebuf, sizeof(namebuf),"STTNUM%d", i); 863 R_SetPatchNum(&tallnum[i],namebuf); 864 865 snprintf(namebuf, sizeof(namebuf),"STYSNUM%d", i); 866 R_SetPatchNum(&shortnum[i],namebuf); 867 } 868 869 // Load percent key. 870 R_SetPatchNum(&tallpercent,"STTPRCNT"); 871 872 // key cards 873 for (i=0;i<NUMCARDS+3;i++) //jff 2/23/98 show both keys too 874 { 875 snprintf(namebuf, sizeof(namebuf), "STKEYS%d", i); 876 R_SetPatchNum(&keys[i], namebuf); 877 } 878 879 // arms background 880 R_SetPatchNum(&armsbg, "STARMS"); 881 882 // arms ownership widgets 883 for (i=0;i<6;i++) 884 { 885 snprintf(namebuf, sizeof(namebuf),"STGNUM%d", i+2); 886 // gray # 887 R_SetPatchNum(&arms[i][0], namebuf); 888 889 // yellow # 890 arms[i][1] = shortnum[i+2]; 891 } 892 893 // face backgrounds for different color players 894 // killough 3/7/98: add better support for spy mode by loading all 895 // player face backgrounds and using displayplayer to choose them: 896 R_SetPatchNum(&faceback, "STFB0"); 897 898 // status bar background bits 899 if (doload) 900 sbar = V_PatchToBlock("STBAR", CR_DEFAULT, VPT_NONE, 901 &sbar_width, &sbar_height); 902 else { 903 free(sbar); sbar=NULL; 904 } 905 906 // face states 907 facenum = 0; 908 for (i=0;i<ST_NUMPAINFACES;i++) 909 { 910 int j; 911 for (j=0;j<ST_NUMSTRAIGHTFACES;j++) 912 { 913 snprintf(namebuf, sizeof(namebuf), "STFST%d%d", i, j); 914 R_SetPatchNum(&faces[facenum++], namebuf); 915 } 916 snprintf(namebuf, sizeof(namebuf), "STFTR%d0", i); // turn right 917 R_SetPatchNum(&faces[facenum++], namebuf); 918 snprintf(namebuf, sizeof(namebuf), "STFTL%d0", i); // turn left 919 R_SetPatchNum(&faces[facenum++], namebuf); 920 snprintf(namebuf, sizeof(namebuf), "STFOUCH%d", i); // ouch! 921 R_SetPatchNum(&faces[facenum++], namebuf); 922 snprintf(namebuf, sizeof(namebuf), "STFEVL%d", i); // evil grin ;) 923 R_SetPatchNum(&faces[facenum++], namebuf); 924 snprintf(namebuf, sizeof(namebuf), "STFKILL%d", i); // pissed off 925 R_SetPatchNum(&faces[facenum++], namebuf); 926 } 927 R_SetPatchNum(&faces[facenum++], "STFGOD0"); 928 R_SetPatchNum(&faces[facenum++], "STFDEAD0"); 929} 930 931void ST_loadData(void) 932{ 933 ST_loadGraphics(true); 934} 935 936void ST_unloadData(void) 937{ 938 ST_loadGraphics(false); 939} 940 941void ST_initData(void) 942{ 943 int i; 944 945 st_firsttime = true; 946 plyr = &players[displayplayer]; // killough 3/7/98 947 948 st_clock = 0; 949 st_chatstate = StartChatState; 950 st_gamestate = FirstPersonState; 951 952 st_statusbaron = true; 953 st_oldchat = st_chat = false; 954 st_cursoron = false; 955 956 st_faceindex = 0; 957 st_palette = -1; 958 959 st_oldhealth = -1; 960 961 for (i=0;i<NUMWEAPONS;i++) 962 oldweaponsowned[i] = plyr->weaponowned[i]; 963 964 for (i=0;i<3;i++) 965 keyboxes[i] = -1; 966 967 STlib_init(); 968} 969 970void ST_createWidgets(void) 971{ 972 int i; 973 974 // ready weapon ammo 975 STlib_initNum(&w_ready, 976 ST_AMMOX, 977 ST_AMMOY, 978 tallnum, 979 &plyr->ammo[weaponinfo[plyr->readyweapon].ammo], 980 &st_statusbaron, 981 ST_AMMOWIDTH ); 982 983 // the last weapon type 984 w_ready.data = plyr->readyweapon; 985 986 // health percentage 987 STlib_initPercent(&w_health, 988 ST_HEALTHX, 989 ST_HEALTHY, 990 tallnum, 991 &plyr->health, 992 &st_statusbaron, 993 &tallpercent); 994 995 // arms background 996 STlib_initBinIcon(&w_armsbg, 997 ST_ARMSBGX, 998 ST_ARMSBGY, 999 &armsbg, 1000 &st_notdeathmatch, 1001 &st_statusbaron); 1002 1003 // weapons owned 1004 for(i=0;i<6;i++) 1005 { 1006 STlib_initMultIcon(&w_arms[i], 1007 ST_ARMSX+(i%3)*ST_ARMSXSPACE, 1008 ST_ARMSY+(i/3)*ST_ARMSYSPACE, 1009 arms[i], (int *) &plyr->weaponowned[i+1], 1010 &st_armson); 1011 } 1012 1013 // frags sum 1014 STlib_initNum(&w_frags, 1015 ST_FRAGSX, 1016 ST_FRAGSY, 1017 tallnum, 1018 &st_fragscount, 1019 &st_fragson, 1020 ST_FRAGSWIDTH); 1021 1022 // faces 1023 STlib_initMultIcon(&w_faces, 1024 ST_FACESX, 1025 ST_FACESY, 1026 faces, 1027 &st_faceindex, 1028 &st_statusbaron); 1029 1030 // armor percentage - should be colored later 1031 STlib_initPercent(&w_armor, 1032 ST_ARMORX, 1033 ST_ARMORY, 1034 tallnum, 1035 &plyr->armorpoints, 1036 &st_statusbaron, &tallpercent); 1037 1038 // keyboxes 0-2 1039 STlib_initMultIcon(&w_keyboxes[0], 1040 ST_KEY0X, 1041 ST_KEY0Y, 1042 keys, 1043 &keyboxes[0], 1044 &st_statusbaron); 1045 1046 STlib_initMultIcon(&w_keyboxes[1], 1047 ST_KEY1X, 1048 ST_KEY1Y, 1049 keys, 1050 &keyboxes[1], 1051 &st_statusbaron); 1052 1053 STlib_initMultIcon(&w_keyboxes[2], 1054 ST_KEY2X, 1055 ST_KEY2Y, 1056 keys, 1057 &keyboxes[2], 1058 &st_statusbaron); 1059 1060 // ammo count (all four kinds) 1061 STlib_initNum(&w_ammo[0], 1062 ST_AMMO0X, 1063 ST_AMMO0Y, 1064 shortnum, 1065 &plyr->ammo[0], 1066 &st_statusbaron, 1067 ST_AMMO0WIDTH); 1068 1069 STlib_initNum(&w_ammo[1], 1070 ST_AMMO1X, 1071 ST_AMMO1Y, 1072 shortnum, 1073 &plyr->ammo[1], 1074 &st_statusbaron, 1075 ST_AMMO1WIDTH); 1076 1077 STlib_initNum(&w_ammo[2], 1078 ST_AMMO2X, 1079 ST_AMMO2Y, 1080 shortnum, 1081 &plyr->ammo[2], 1082 &st_statusbaron, 1083 ST_AMMO2WIDTH); 1084 1085 STlib_initNum(&w_ammo[3], 1086 ST_AMMO3X, 1087 ST_AMMO3Y, 1088 shortnum, 1089 &plyr->ammo[3], 1090 &st_statusbaron, 1091 ST_AMMO3WIDTH); 1092 1093 // max ammo count (all four kinds) 1094 STlib_initNum(&w_maxammo[0], 1095 ST_MAXAMMO0X, 1096 ST_MAXAMMO0Y, 1097 shortnum, 1098 &plyr->maxammo[0], 1099 &st_statusbaron, 1100 ST_MAXAMMO0WIDTH); 1101 1102 STlib_initNum(&w_maxammo[1], 1103 ST_MAXAMMO1X, 1104 ST_MAXAMMO1Y, 1105 shortnum, 1106 &plyr->maxammo[1], 1107 &st_statusbaron, 1108 ST_MAXAMMO1WIDTH); 1109 1110 STlib_initNum(&w_maxammo[2], 1111 ST_MAXAMMO2X, 1112 ST_MAXAMMO2Y, 1113 shortnum, 1114 &plyr->maxammo[2], 1115 &st_statusbaron, 1116 ST_MAXAMMO2WIDTH); 1117 1118 STlib_initNum(&w_maxammo[3], 1119 ST_MAXAMMO3X, 1120 ST_MAXAMMO3Y, 1121 shortnum, 1122 &plyr->maxammo[3], 1123 &st_statusbaron, 1124 ST_MAXAMMO3WIDTH); 1125} 1126 1127static boolean st_stopped = true; 1128 1129void ST_Start(void) 1130{ 1131 if (!st_stopped) 1132 ST_Stop(); 1133 ST_initData(); 1134 ST_createWidgets(); 1135 st_stopped = false; 1136} 1137 1138void ST_Stop(void) 1139{ 1140 if (st_stopped) 1141 return; 1142 V_SetPalette(0); 1143 st_stopped = true; 1144} 1145 1146void ST_Init(void) 1147{ 1148 veryfirsttime = 0; 1149 ST_loadData(); 1150 // proff 08/18/98: Changed for high-res 1151 d_screens[4] = Z_Malloc(SCREENWIDTH*(ST_SCALED_HEIGHT+1), PU_STATIC, 0); 1152 // d_screens[4] = Z_Malloc(ST_WIDTH*ST_HEIGHT, PU_STATIC, 0); 1153}