- Added optional offset parameters to the drawshadow flag.

- Added character alignment parameter to font monospacing.
- Fixed: character shadows were not scaled.
- Heretic keys now have an icon associated with them so that they can be drawn through drawkeybar.
- Replaced the built in Heretic and Hexen status bars with SBarInfo equivalents.

SVN r2353 (trunk)
This commit is contained in:
Braden Obrzut 2010-06-02 20:26:27 +00:00
parent d29123c511
commit d7686d0c26
14 changed files with 478 additions and 2020 deletions

View file

@ -664,9 +664,7 @@ add_executable( zdoom WIN32
zstring.cpp
g_doom/a_doommisc.cpp
g_heretic/a_hereticmisc.cpp
g_heretic/heretic_sbar.cpp
g_hexen/a_hexenmisc.cpp
g_hexen/hexen_sbar.cpp
g_raven/a_artitele.cpp
g_raven/a_minotaur.cpp
g_strife/a_strifestuff.cpp

View file

@ -1,795 +0,0 @@
#include <assert.h>
#include "doomtype.h"
#include "doomstat.h"
#include "v_font.h"
#include "sbar.h"
#include "r_defs.h"
#include "w_wad.h"
#include "m_random.h"
#include "d_player.h"
#include "st_stuff.h"
#include "v_video.h"
#include "r_draw.h"
#include "templates.h"
#include "a_keys.h"
#include "r_translate.h"
#include "g_level.h"
#include "v_palette.h"
static FRandom pr_chainwiggle;
// This texture is used to shade each end of the health chain
class FHereticShader : public FTexture
{
public:
FHereticShader ();
const BYTE *GetColumn (unsigned int column, const Span **spans_out);
const BYTE *GetPixels ();
void Unload ();
private:
static const BYTE Pixels[10*16];
static const Span DummySpan[2];
};
static FHereticShader ChainShade;
const FTexture::Span FHereticShader::DummySpan[2] = { { 0, 10 }, { 0, 0 } };
const BYTE FHereticShader::Pixels[10*16] =
{
254, 254, 254, 254, 254, 254, 254, 254, 254, 254,
240, 240, 240, 240, 240, 240, 240, 240, 240, 240,
224, 224, 224, 224, 224, 224, 224, 224, 224, 224,
208, 208, 208, 208, 208, 208, 208, 208, 208, 208,
192, 192, 192, 192, 192, 192, 192, 192, 192, 192,
176, 176, 176, 176, 176, 176, 176, 176, 176, 176,
160, 160, 160, 160, 160, 160, 160, 160, 160, 160,
144, 144, 144, 144, 144, 144, 144, 144, 144, 144,
128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
112, 112, 112, 112, 112, 112, 112, 112, 112, 112,
96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
};
FHereticShader::FHereticShader ()
{
Width = 16;
Height = 10;
WidthBits = 4;
HeightBits = 4;
WidthMask = 15;
}
void FHereticShader::Unload ()
{
}
const BYTE *FHereticShader::GetColumn (unsigned int column, const Span **spans_out)
{
if (spans_out != NULL)
{
*spans_out = DummySpan;
}
return Pixels + 10*(column & 15);
}
const BYTE *FHereticShader::GetPixels ()
{
return Pixels;
}
class DHereticStatusBar : public DBaseStatusBar
{
DECLARE_CLASS(DHereticStatusBar, DBaseStatusBar)
HAS_OBJECT_POINTERS
public:
DHereticStatusBar () : DBaseStatusBar (42)
{
static const char *hereticLumpNames[NUM_HERETICSB_IMAGES] =
{
"LTFACE", "RTFACE", "BARBACK", "INVBAR", "CHAIN",
NULL, "LIFEGEM2", "LTFCTOP", "RTFCTOP", "SELECTBO",
"INVGEML1", "INVGEML2", "INVGEMR1", "INVGEMR2", "BLACKSQ",
"ARMCLEAR", "CHAINBACK","GOD1", "GOD2", "USEARTIA",
"USEARTIB", "USEARTIC", "USEARTID", "YKEYICON", "GKEYICON",
"BKEYICON", "ARTIBOX", "PTN1A0", "PTN1B0", "PTN1C0"
};
static const char *sharedLumpNames[] =
{
"LAME", "NEGNUM", "IN0", "IN1", "IN2",
"IN3", "IN4", "IN5", "IN6", "IN7",
"IN8", "IN9", "FONTB13", "FONTB16", "FONTB17",
"FONTB18", "FONTB19", "FONTB20", "FONTB21", "FONTB22",
"FONTB23", "FONTB24", "FONTB25", "SMALLIN0", "SMALLIN1",
"SMALLIN2", "SMALLIN3", "SMALLIN4", "SMALLIN5", "SMALLIN6",
"SMALLIN7", "SMALLIN8", "SMALLIN9"
};
if (deathmatch)
{
hereticLumpNames[5] = "STATBAR";
}
else
{
hereticLumpNames[5] = "LIFEBAR";
}
DBaseStatusBar::Images.Init (sharedLumpNames, NUM_BASESB_IMAGES);
Images.Init (hereticLumpNames, NUM_HERETICSB_IMAGES);
oldarti = NULL;
oldammo1 = oldammo2 = NULL;
oldammocount1 = oldammocount2 = -1;
oldartiCount = 0;
oldfrags = -9999;
oldarmor = -1;
oldhealth = -1;
oldlife = -1;
oldkeys = -1;
HealthMarker = 0;
ChainWiggle = 0;
ArtifactFlash = 0;
}
~DHereticStatusBar ()
{
}
void Tick ()
{
int curHealth;
DBaseStatusBar::Tick ();
if (level.time & 1)
{
ChainWiggle = pr_chainwiggle() & 1;
}
curHealth = CPlayer->health;
if (curHealth < 0)
{
curHealth = 0;
}
if (curHealth < HealthMarker)
{
HealthMarker -= clamp ((HealthMarker - curHealth) >> 2, 1, 8);
}
else if (curHealth > HealthMarker)
{
HealthMarker += clamp ((curHealth - HealthMarker) >> 2, 1, 8);
}
if (ArtifactFlash > 0)
{
if (--ArtifactFlash == 0)
{
ArtiRefresh = screen->GetPageCount ();
}
}
}
void Draw (EHudState state)
{
DBaseStatusBar::Draw (state);
if (state == HUD_Fullscreen)
{
DrawFullScreenStuff ();
SB_state = screen->GetPageCount ();
}
else if (state == HUD_StatusBar)
{
if (SB_state > 0)
{
DrawImage (Images[imgBARBACK], 0, 0);
if (CPlayer->cheats&CF_GODMODE)
{
DrawImage (Images[imgGOD1], 16, 9);
DrawImage (Images[imgGOD2], 287, 9);
}
oldhealth = -1;
}
DrawCommonBar ();
if (CPlayer->inventorytics == 0)
{
if (SB_state < 0)
{
SB_state = screen->GetPageCount ();
}
if (SB_state != 0)
{
// Main interface
SB_state--;
DrawImage (Images[imgSTATBAR], 34, 2);
oldarti = NULL;
oldammo1 = oldammo2 = NULL;
oldammocount1 = oldammocount2 = -1;
oldarmor = -1;
oldfrags = -9999; //can't use -1, 'cuz of negative frags
oldlife = -1;
oldkeys = -1;
oldhealth = -1;
ArtiRefresh = 0;
}
DrawMainBar ();
}
else
{
if (SB_state > -1)
{
SB_state = -screen->GetPageCount () - 1;
}
if (SB_state < -1)
{
SB_state++;
DrawImage (Images[imgINVBAR], 34, 2);
}
DrawInventoryBar ();
}
}
}
private:
//---------------------------------------------------------------------------
//
// PROC DrawCommonBar
//
//---------------------------------------------------------------------------
void DrawCommonBar ()
{
int chainY;
int healthPos;
DrawImage (Images[imgLTFCTOP], 0, -10);
//DrawImage (Images[imgRTFCTOP], 290, -10);
screen->DrawTexture (Images[imgRTFCTOP], ST_X+290, ST_Y,
DTA_Bottom320x200, Scaled,
DTA_TopOffset, Images[imgRTFCTOP]->GetHeight(),
TAG_DONE);
if (oldhealth != HealthMarker)
{
oldhealth = HealthMarker;
HealthRefresh = screen->GetPageCount ();
}
if (HealthRefresh)
{
HealthRefresh--;
healthPos = HealthMarker;
if (healthPos < 0)
{
healthPos = 0;
}
if (healthPos > 100)
{
healthPos = 100;
}
healthPos = (healthPos * 256) / 100;
chainY = (HealthMarker == (CPlayer->health > 0 ? CPlayer->health : 0)) ? 33 : 33 + ChainWiggle;
DrawImage (Images[imgCHAINBACK], 0, 32);
DrawImage (Images[imgCHAIN], 2+(healthPos%17), chainY);
DrawImage (Images[imgLIFEGEM], 17+healthPos, chainY, multiplayer ?
translationtables[TRANSLATION_PlayersExtra][int(CPlayer - players)] : NULL);
DrawImage (Images[imgLTFACE], 0, 32);
DrawImage (Images[imgRTFACE], 276, 32);
screen->DrawTexture (&ChainShade, ST_X+19, ST_Y+32,
DTA_Bottom320x200, Scaled,
DTA_AlphaChannel, true,
DTA_FillColor, 0,
TAG_DONE);
screen->DrawTexture (&ChainShade, ST_X+277, ST_Y+32,
DTA_Bottom320x200, Scaled,
DTA_AlphaChannel, true,
DTA_FillColor, 0,
DTA_FlipX, true,
TAG_DONE);
}
}
//---------------------------------------------------------------------------
//
// PROC DrawMainBar
//
//---------------------------------------------------------------------------
void DrawMainBar ()
{
AInventory *item;
AAmmo *ammo1, *ammo2;
int ammocount1, ammocount2;
int temp;
int playerkeys;
// Ready artifact
if (ArtifactFlash)
{
DrawImage (Images[imgBLACKSQ], 180, 3);
DrawImage (Images[imgUSEARTIA + ArtifactFlash], 182, 3);
oldarti = NULL; // so that the correct artifact fills in after the flash
}
else if (oldarti != CPlayer->mo->InvSel
|| (oldarti != NULL && oldartiCount != oldarti->Amount))
{
oldarti = CPlayer->mo->InvSel;
GC::WriteBarrier(this, oldarti);
oldartiCount = oldarti != NULL ? oldarti->Amount : 0;
ArtiRefresh = screen->GetPageCount ();
}
if (ArtiRefresh)
{
ArtiRefresh--;
DrawImage (Images[imgBLACKSQ], 180, 3);
if (oldarti != NULL)
{
DrawDimImage (TexMan(oldarti->Icon), 179, 2, oldarti->Amount <= 0);
if (oldartiCount != 1)
{
DrSmallNumber (oldartiCount, 197, 24);
}
}
}
// Frags
if (deathmatch)
{
temp = CPlayer->fragcount;
if (temp != oldfrags)
{
oldfrags = temp;
FragHealthRefresh = screen->GetPageCount ();
}
if (FragHealthRefresh)
{
FragHealthRefresh--;
DrawImage (Images[imgARMCLEAR], 57, 13);
DrINumber (temp, 61, 12);
}
}
else
{
temp = MAX(0, HealthMarker);
if (oldlife != temp)
{
oldlife = temp;
FragHealthRefresh = screen->GetPageCount ();
}
if (FragHealthRefresh)
{
FragHealthRefresh--;
DrawImage (Images[imgARMCLEAR], 57, 13);
DrINumber (temp, 61, 12);
}
}
// Keys
playerkeys = 0;
for (item = CPlayer->mo->Inventory; item != NULL; item = item->Inventory)
{
if (item->IsKindOf (RUNTIME_CLASS(AKey)))
{
int keynum = static_cast<AKey*>(item)->KeyNumber;
if (keynum >= 1 && keynum <= 3)
{
playerkeys |= 1 << (keynum-1);
}
}
}
if (oldkeys != playerkeys)
{
oldkeys = playerkeys;
KeysRefresh = screen->GetPageCount ();
}
if (KeysRefresh)
{
KeysRefresh--;
// [RH] Erase the key images so the player can drop keys
// and see the status update.
screen->DrawTexture (Images[imgSTATBAR], ST_X+34, ST_Y+2,
DTA_WindowLeft, 119,
DTA_WindowRight, 129,
DTA_Bottom320x200, Scaled,
TAG_DONE);
if (playerkeys & 4)
{
DrawImage (Images[imgYKEYICON], 153, 6);
}
if (playerkeys & 1)
{
DrawImage (Images[imgGKEYICON], 153, 14);
}
if (playerkeys & 2)
{
DrawImage (Images[imgBKEYICON], 153, 22);
}
}
// Ammo
GetCurrentAmmo (ammo1, ammo2, ammocount1, ammocount2);
if (ammo1 == ammo2)
{
// Don't show the same ammo twice.
ammo2 = NULL;
}
if (oldammo1 != ammo1 || oldammo2 != ammo2 ||
oldammocount1 != ammocount1 || oldammocount2 != ammocount2)
{
oldammo1 = ammo1;
oldammo2 = ammo2;
oldammocount1 = ammocount1;
oldammocount2 = ammocount2;
GC::WriteBarrier(this, ammo1);
GC::WriteBarrier(this, ammo2);
AmmoRefresh = screen->GetPageCount ();
}
if (AmmoRefresh)
{
AmmoRefresh--;
DrawImage (Images[imgBLACKSQ], 108, 3);
if (ammo2 != NULL)
{ // Draw both ammos
screen->DrawTexture (TexMan[ammo1->Icon], 115+ST_X, 11+ST_Y,
DTA_CenterOffset, true,
DTA_Bottom320x200, Scaled,
TAG_DONE);
DrSmallNumber (ammo1->Amount, 124, 7);
screen->DrawTexture (TexMan[ammo2->Icon], 115+ST_X, 22+ST_Y,
DTA_CenterOffset, true,
DTA_Bottom320x200, Scaled,
TAG_DONE);
DrSmallNumber (ammo2->Amount, 124, 19);
}
else if (ammo1 != NULL)
{ // Draw just one ammo
DrINumber (ammo1->Amount, 109, 4);
screen->DrawTexture (TexMan[ammo1->Icon], 123+ST_X, 22+ST_Y,
DTA_CenterOffset, true,
DTA_Bottom320x200, Scaled,
TAG_DONE);
}
}
// Armor
AInventory *armor = CPlayer->mo->FindInventory<ABasicArmor>();
int armorpoints = armor != NULL ? armor->Amount : 0;
if (oldarmor != armorpoints)
{
oldarmor = armorpoints;
ArmorRefresh = screen->GetPageCount ();
}
if (ArmorRefresh)
{
ArmorRefresh--;
DrawImage (Images[imgARMCLEAR], 224, 13);
DrINumber (armorpoints, 228, 12);
}
}
//---------------------------------------------------------------------------
//
// PROC DrawInventoryBar
//
//---------------------------------------------------------------------------
void DrawInventoryBar ()
{
AInventory *item;
int i;
DrawImage (Images[imgINVBAR], 34, 2);
CPlayer->mo->InvFirst = ValidateInvFirst (7);
if (CPlayer->mo->InvFirst != NULL)
{
for (item = CPlayer->mo->InvFirst, i = 0; item != NULL && i < 7; item = item->NextInv(), ++i)
{
DrawDimImage (TexMan(item->Icon), 50+i*31, 2, item->Amount <= 0);
if (item->Amount != 1)
{
DrSmallNumber (item->Amount, 65+i*31, 24);
}
if (item == CPlayer->mo->InvSel)
{
DrawImage (Images[imgSELECTBOX], 50+i*31, 31);
}
}
// Is there something to the left?
if (CPlayer->mo->FirstInv() != CPlayer->mo->InvFirst)
{
DrawImage (Images[!(gametic & 4) ?
imgINVLFGEM1 : imgINVLFGEM2], 38, 1);
}
// Is there something to the right?
if (item != NULL)
{
DrawImage (Images[!(gametic & 4) ?
imgINVRTGEM1 : imgINVRTGEM2], 269, 1);
}
}
}
//---------------------------------------------------------------------------
//
// PROC DrawFullScreenStuff
//
//---------------------------------------------------------------------------
void DrawFullScreenStuff ()
{
AInventory *item;
FTexture *pic;
int i;
// Draw health
if (CPlayer->mo->health > 0)
{
pic = Images[imgPTN1 + gametic/3%3];
screen->DrawTexture (pic, 48, -3,
DTA_HUDRules, HUD_Normal,
DTA_LeftOffset, pic->GetWidth()/2,
DTA_TopOffset, pic->GetHeight(),
TAG_DONE);
DrBNumberOuter (CPlayer->mo->health, 5, -21);
}
else
{
DrBNumberOuter (0, 5, -20);
}
// Draw armor
ABasicArmor *armor = CPlayer->mo->FindInventory<ABasicArmor>();
if (armor != NULL && armor->Amount != 0)
{
pic = TexMan(armor->Icon);
if (pic != NULL)
{
screen->DrawTexture (pic, 56, -24,
DTA_HUDRules, HUD_Normal,
DTA_LeftOffset, pic->GetWidth()/2,
DTA_TopOffset, pic->GetHeight(),
TAG_DONE);
}
DrBNumberOuter (armor->Amount, 5, -43);
}
if (deathmatch)
{
// Draw frag count
DrINumberOuter (CPlayer->fragcount, 45, -16);
}
else
{
// Draw keys
int playerkeys = 0;
for (item = CPlayer->mo->Inventory; item != NULL; item = item->Inventory)
{
if (item->IsKindOf (RUNTIME_CLASS(AKey)))
{
int keynum = static_cast<const AKey*>(item)->KeyNumber;
if (keynum >= 1 && keynum <= 3)
{
playerkeys |= 1 << (keynum-1);
}
}
}
i = -7;
if (playerkeys & 2)
{
screen->DrawTexture (Images[imgBKEYICON], 54, i,
DTA_HUDRules, HUD_Normal,
TAG_DONE);
i -= 8;
}
if (playerkeys & 1)
{
screen->DrawTexture (Images[imgGKEYICON], 54, i,
DTA_HUDRules, HUD_Normal,
TAG_DONE);
i -= 8;
}
if (playerkeys & 4)
{
screen->DrawTexture (Images[imgYKEYICON], 54, i,
DTA_HUDRules, HUD_Normal,
TAG_DONE);
}
}
// Draw ammo
AAmmo *ammo1, *ammo2;
int ammocount1, ammocount2;
GetCurrentAmmo (ammo1, ammo2, ammocount1, ammocount2);
if (ammo1 != NULL)
{
// Draw primary ammo in the bottom-right corner
DrINumberOuter (ammo1->Amount, -29, -15);
screen->DrawTexture (TexMan(ammo1->Icon), -14, -22,
DTA_HUDRules, HUD_Normal,
DTA_CenterBottomOffset, true,
TAG_DONE);
if (ammo2 != NULL && ammo2!=ammo1)
{
// Draw secondary ammo just above the primary ammo
DrINumberOuter (ammo2->Amount, -29, -56);
screen->DrawTexture (TexMan(ammo2->Icon), -14, -63,
DTA_HUDRules, HUD_Normal,
DTA_CenterBottomOffset, true,
TAG_DONE);
}
}
// Draw inventory
if (CPlayer->inventorytics == 0)
{
if (ArtifactFlash)
{
screen->DrawTexture (Images[imgARTIBOX], -61, -31,
DTA_HUDRules, HUD_Normal,
DTA_Alpha, TRANSLUC50,
TAG_DONE);
screen->DrawTexture (Images[imgUSEARTIA + ArtifactFlash], -61, -31,
DTA_HUDRules, HUD_Normal,
TAG_DONE);
}
else if (CPlayer->mo->InvSel != NULL)
{
screen->DrawTexture (Images[imgARTIBOX], -61, -31,
DTA_HUDRules, HUD_Normal,
DTA_Alpha, TRANSLUC50,
TAG_DONE);
screen->DrawTexture (TexMan(CPlayer->mo->InvSel->Icon), -61, -31,
DTA_HUDRules, HUD_Normal,
DTA_ColorOverlay, CPlayer->mo->InvSel->Amount > 0 ? 0 : DIM_OVERLAY,
TAG_DONE);
if (CPlayer->mo->InvSel->Amount != 1)
{
DrSmallNumberOuter (CPlayer->mo->InvSel->Amount, -46, -9, false);
}
}
}
else
{
CPlayer->mo->InvFirst = ValidateInvFirst (7);
i = 0;
if (CPlayer->mo->InvFirst != NULL)
{
for (item = CPlayer->mo->InvFirst; item != NULL && i < 7; item = item->NextInv(), ++i)
{
screen->DrawTexture (Images[imgARTIBOX], -100+i*31, -32,
DTA_HUDRules, HUD_HorizCenter,
DTA_Alpha, HX_SHADOW,
TAG_DONE);
screen->DrawTexture (TexMan(item->Icon), -100+i*31, -32,
DTA_HUDRules, HUD_HorizCenter,
DTA_ColorOverlay, item->Amount > 0 ? 0 : DIM_OVERLAY,
TAG_DONE);
if (item->Amount != 1)
{
DrSmallNumberOuter (item->Amount, -84+i*31, -10, true);
}
if (item == CPlayer->mo->InvSel)
{
screen->DrawTexture (Images[imgSELECTBOX], -100+i*31, -3,
DTA_HUDRules, HUD_HorizCenter,
TAG_DONE);
}
}
// Is there something to the left?
if (CPlayer->mo->FirstInv() != CPlayer->mo->InvFirst)
{
screen->DrawTexture (Images[!(gametic & 4) ?
imgINVLFGEM1 : imgINVLFGEM2], -112, -33,
DTA_HUDRules, HUD_HorizCenter, TAG_DONE);
}
// Is there something to the right?
if (item != NULL)
{
screen->DrawTexture (Images[!(gametic & 4) ?
imgINVRTGEM1 : imgINVRTGEM2], 119, -33,
DTA_HUDRules, HUD_HorizCenter, TAG_DONE);
}
}
for (; i < 7; i++)
{
screen->DrawTexture (Images[imgARTIBOX], -100+i*31, -32,
DTA_HUDRules, HUD_HorizCenter,
DTA_Alpha, HX_SHADOW,
TAG_DONE);
}
}
}
//---------------------------------------------------------------------------
//
// PROC FlashItem
//
//---------------------------------------------------------------------------
void FlashItem (const PClass *itemtype)
{
ArtifactFlash = 4;
}
static const char patcharti[][10];
static const char ammopic[][10];
TObjPtr<AInventory> oldarti;
TObjPtr<AAmmo> oldammo1, oldammo2;
int oldammocount1, oldammocount2;
int oldartiCount;
int oldfrags;
int oldarmor;
int oldhealth;
int oldlife;
int oldkeys;
enum
{
imgLTFACE,
imgRTFACE,
imgBARBACK,
imgINVBAR,
imgCHAIN,
imgSTATBAR,
imgLIFEGEM,
imgLTFCTOP,
imgRTFCTOP,
imgSELECTBOX,
imgINVLFGEM1,
imgINVLFGEM2,
imgINVRTGEM1,
imgINVRTGEM2,
imgBLACKSQ,
imgARMCLEAR,
imgCHAINBACK,
imgGOD1,
imgGOD2,
imgUSEARTIA,
imgUSEARTIB,
imgUSEARTIC,
imgUSEARTID,
imgYKEYICON,
imgGKEYICON,
imgBKEYICON,
imgARTIBOX,
imgPTN1,
imgPTN2,
imgPTN3,
NUM_HERETICSB_IMAGES
};
FImageCollection Images;
int HealthMarker;
int ChainWiggle;
int ArtifactFlash;
char HealthRefresh;
char ArtiRefresh;
char FragHealthRefresh;
char KeysRefresh;
char AmmoRefresh;
char ArmorRefresh;
};
IMPLEMENT_POINTY_CLASS(DHereticStatusBar)
DECLARE_POINTER(oldarti)
DECLARE_POINTER(oldammo1)
DECLARE_POINTER(oldammo2)
END_POINTERS
DBaseStatusBar *CreateHereticStatusBar ()
{
return new DHereticStatusBar;
}

File diff suppressed because it is too large Load diff

View file

@ -419,15 +419,7 @@ void G_InitNew (const char *mapname, bool bTitleLevel)
int cstype = SBarInfoScript[SCRIPT_CUSTOM]->GetGameType();
//Did the user specify a "base"
if(cstype == GAME_Heretic)
{
StatusBar = CreateHereticStatusBar();
}
else if(cstype == GAME_Hexen)
{
StatusBar = CreateHexenStatusBar();
}
else if(cstype == GAME_Strife)
if(cstype == GAME_Strife)
{
StatusBar = CreateStrifeStatusBar();
}
@ -442,18 +434,10 @@ void G_InitNew (const char *mapname, bool bTitleLevel)
}
if (StatusBar == NULL)
{
if (gameinfo.gametype & GAME_DoomChex)
if (gameinfo.gametype & (GAME_DoomChex|GAME_Heretic|GAME_Hexen))
{
StatusBar = CreateCustomStatusBar (SCRIPT_DEFAULT);
}
else if (gameinfo.gametype == GAME_Heretic)
{
StatusBar = CreateHereticStatusBar ();
}
else if (gameinfo.gametype == GAME_Hexen)
{
StatusBar = CreateHexenStatusBar ();
}
else if (gameinfo.gametype == GAME_Strife)
{
StatusBar = CreateStrifeStatusBar ();

View file

@ -376,8 +376,6 @@ extern DBaseStatusBar *StatusBar;
// Status bar factories -----------------------------------------------------
DBaseStatusBar *CreateHereticStatusBar();
DBaseStatusBar *CreateHexenStatusBar();
DBaseStatusBar *CreateStrifeStatusBar();
DBaseStatusBar *CreateCustomStatusBar(int script=0);

View file

@ -483,9 +483,19 @@ void SBarInfo::ParseSBarInfo(int lump)
ParseSBarInfo(lump);
}
else if(sc.Compare("Heretic"))
gameType = GAME_Heretic;
{
int lump = Wads.CheckNumForFullName("sbarinfo/heretic.txt", true);
if(lump == -1)
sc.ScriptError("Standard Heretic Status Bar not found.");
ParseSBarInfo(lump);
}
else if(sc.Compare("Hexen"))
gameType = GAME_Hexen;
{
int lump = Wads.CheckNumForFullName("sbarinfo/hexen.txt", true);
if(lump == -1)
sc.ScriptError("Standard Hexen Status Bar not found.");
ParseSBarInfo(lump);
}
else if(sc.Compare("Strife"))
gameType = GAME_Strife;
else if(sc.Compare("None"))
@ -559,6 +569,19 @@ void SBarInfo::ParseSBarInfo(int lump)
sc.MustGetToken(',');
sc.MustGetToken(TK_StringConst); //Don't tell anyone we're just ignoring this ;)
}
if(sc.CheckToken(','))
{
// Character alignment
sc.MustGetToken(TK_Identifier);
if(sc.Compare("left"))
spacingAlignment = ALIGN_LEFT;
else if(sc.Compare("center"))
spacingAlignment = ALIGN_CENTER;
else if(sc.Compare("right"))
spacingAlignment = ALIGN_RIGHT;
else
sc.ScriptError("Unknown alignment '%s'.", sc.String);
}
sc.MustGetToken(';');
break;
case SBARINFO_LOWERHEALTHCAP:
@ -763,6 +786,7 @@ void SBarInfo::Init()
armorInterpolationSpeed = 8;
height = 0;
spacingCharacter = '\0';
spacingAlignment = ALIGN_CENTER;
resW = 320;
resH = 200;
@ -1295,7 +1319,7 @@ public:
}
}
void DrawString(FFont *font, const char* str, SBarInfoCoordinate x, SBarInfoCoordinate y, int xOffset, int yOffset, int alpha, bool fullScreenOffsets, EColorRange translation, int spacing=0, bool drawshadow=false) const
void DrawString(FFont *font, const char* str, SBarInfoCoordinate x, SBarInfoCoordinate y, int xOffset, int yOffset, int alpha, bool fullScreenOffsets, EColorRange translation, int spacing=0, bool drawshadow=false, int shadowX=2, int shadowY=2) const
{
x += spacing;
double ax = *x;
@ -1340,6 +1364,23 @@ public:
ry = ay + yOffset;
rw = character->GetScaledWidthDouble();
rh = character->GetScaledHeightDouble();
if(script->spacingCharacter != '\0')
{
double spacingSize = font->GetCharWidth((int) script->spacingCharacter);
switch(script->spacingAlignment)
{
default:
break;
case SBarInfo::ALIGN_CENTER:
rx += (spacingSize/2)-(rw/2);
break;
case SBarInfo::ALIGN_RIGHT:
rx += spacingSize-rw;
break;
}
}
if(!fullScreenOffsets)
{
rx += ST_X;
@ -1374,7 +1415,9 @@ public:
if(drawshadow)
{
int salpha = fixed_t(((double) alpha / (double) FRACUNIT) * ((double) HR_SHADOW / (double) FRACUNIT) * FRACUNIT);
screen->DrawTexture(character, rx+2, ry+2,
double srx = rx + (shadowX*xScale);
double sry = ry + (shadowY*yScale);
screen->DrawTexture(character, srx, sry,
DTA_DestWidthF, rw,
DTA_DestHeightF, rh,
DTA_Alpha, salpha,

View file

@ -84,6 +84,13 @@ struct Popup
struct SBarInfo
{
enum MonospaceAlignment
{
ALIGN_LEFT,
ALIGN_CENTER,
ALIGN_RIGHT
};
TArray<FString> Images;
SBarInfoMainBlock *huds[NUMHUDS];
Popup popups[NUMPOPUPS];
@ -93,6 +100,7 @@ struct SBarInfo
bool completeBorder;
bool lowerHealthCap;
char spacingCharacter;
MonospaceAlignment spacingAlignment;
int interpolationSpeed;
int armorInterpolationSpeed;
int height;

View file

@ -514,14 +514,15 @@ class CommandDrawString : public SBarInfoCommand
{
public:
CommandDrawString(SBarInfo *script) : SBarInfoCommand(script),
shadow(false), spacing(0), font(NULL), translation(CR_UNTRANSLATED),
cache(-1), strValue(CONSTANT), valueArgument(0)
shadow(false), shadowX(2), shadowY(2), spacing(0), font(NULL),
translation(CR_UNTRANSLATED), cache(-1), strValue(CONSTANT),
valueArgument(0)
{
}
void Draw(const SBarInfoMainBlock *block, const DSBarInfo *statusBar)
{
statusBar->DrawString(font, str.GetChars(), x, y, block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets(), translation, spacing, shadow);
statusBar->DrawString(font, str.GetChars(), x, y, block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets(), translation, spacing, shadow, shadowX, shadowY);
}
void Parse(FScanner &sc, bool fullScreenOffsets)
{
@ -695,6 +696,8 @@ class CommandDrawString : public SBarInfoCommand
};
bool shadow;
int shadowX;
int shadowY;
int spacing;
FFont *font;
EColorRange translation;
@ -850,7 +853,18 @@ class CommandDrawNumber : public CommandDrawString
else if(sc.Compare("whennotzero"))
whenNotZero = true;
else if(sc.Compare("drawshadow"))
{
if(sc.CheckToken('('))
{
sc.MustGetToken(TK_IntConst);
shadowX = sc.Number;
sc.MustGetToken(',');
sc.MustGetToken(TK_IntConst);
shadowY = sc.Number;
sc.MustGetToken(')');
}
shadow = true;
}
else if(sc.Compare("interpolate"))
{
sc.MustGetToken('(');
@ -1236,7 +1250,18 @@ class CommandDrawSelectedInventory : public SBarInfoCommandFlowControl, private
else if(sc.Compare("centerbottom"))
offset = static_cast<Offset> (HMIDDLE|BOTTOM);
else if(sc.Compare("drawshadow"))
{
if(sc.CheckToken('('))
{
sc.MustGetToken(TK_IntConst);
shadowX = sc.Number;
sc.MustGetToken(',');
sc.MustGetToken(TK_IntConst);
shadowY = sc.Number;
sc.MustGetToken(')');
}
shadow = true;
}
else
{
font = V_GetFont(sc.String);

View file

@ -13,6 +13,7 @@ ACTOR KeyGreen : HereticKey 73
Game Heretic
SpawnID 86
Inventory.PickupMessage "$TXT_GOTGREENKEY"
Inventory.Icon "GKEYICON"
States
{
Spawn:
@ -28,6 +29,7 @@ ACTOR KeyBlue : HereticKey 79
Game Heretic
SpawnID 85
Inventory.PickupMessage "$TXT_GOTBLUEKEY"
Inventory.Icon "BKEYICON"
States
{
Spawn:
@ -43,6 +45,7 @@ ACTOR KeyYellow : HereticKey 80
Game Heretic
SpawnID 87
Inventory.PickupMessage "$TXT_GOTYELLOWKEY"
Inventory.Icon "YKEYICON"
States
{
Spawn:

View file

@ -95,6 +95,12 @@ pic SPMINO13 tics 3
pic SPMINO14 tics 3
pic SPMINO15 tics 3
// Animate health vial for Heretic fullscreen HUD
texture optional PTN1A0
pic PTN1A0 tics 3
pic PTN1B0 tics 3
pic PTN1C0 tics 3
// The Wings of Wrath are not included, because they stop spinning when
// you stop flying, so they can't be a simple animation.

View file

@ -24,7 +24,7 @@ gameinfo
defaultbloodparticlecolor = "ff 00 00"
backpacktype = "BagOfHolding"
armoricons = "SHLDA0", 0.75, "SHD2A0"
statusbar = ""
statusbar = "sbarinfo/heretic.txt"
intermissionmusic = "mus_intr"
intermissioncounter = false
weaponslot = 1, "Staff", "Gauntlets"

View file

@ -26,7 +26,7 @@ gameinfo
defaultbloodcolor = "68 00 00"
defaultbloodparticlecolor = "ff 00 00"
backpacktype = "BagOfHolding" // Hexen doesn't have a backpack so use Heretic's.
statusbar = ""
statusbar = "sbarinfo/hexen.txt"
intermissionmusic = "hub"
intermissioncounter = false
weaponslot = 1, "FWeapFist", "CWeapMace", "MWeapWand"

View file

@ -0,0 +1,123 @@
/*******************************************************************************
* DEFAULT HERETIC STATUS BAR
*******************************************************************************
* If you wish to include this file into a custom status bar please use the
* following command:
*
* base Heretic;
*
* Using #include "sbarinfo/heretic.txt" will not be supported.
******************************************************************************/
height 42;
monospacefonts true, "0", center;
statusbar fullscreen, fullscreenoffsets
{
//health
drawimage "PTN1A0", 48, -3, centerbottom;
drawnumber 2147483647, BIGFONT, untranslated, health, drawshadow, interpolate(8), 41, -21, 1;
//armor
drawimage armoricon, 56, -24, centerbottom;
drawnumber 2147483647, BIGFONT, untranslated, armor, drawshadow, whennotzero, 41, -43, 1;
//frags/keys
gamemode deathmatch
drawnumber 2147483647, HUDFONT_RAVEN, untranslated, frags, drawshadow, 70, -16, 1;
else
drawkeybar 100, vertical, reverse, 8, 54, -7, 0, 3, auto;
//ammo
drawimage ammoicon1, -14, -22, centerbottom;
drawnumber 2147483647, HUDFONT_RAVEN, untranslated, ammo1, drawshadow(1, 1), -3, -15, 1;
//secondary ammo
usessecondaryammo
{
drawimage ammoicon2, -14, -63, centerbottom;
drawnumber 2147483647, HUDFONT_RAVEN, untranslated, ammo2, drawshadow(1, 1), -3, -56, 1;
}
inventorybarnotvisible
{
drawselectedinventory alternateonempty, artiflash, INDEXFONT_RAVEN, -61, -31, -34, -9, untranslated
{
}
else
{
alpha 0.6
drawimage "ARTIBOX", -61, -31;
}
}
}
statusbar normal
{
drawimage "BARBACK", 0, 158;
drawimage "LTFCTOP", 0, 148;
drawimage "RTFCTOP", 290, 148;
//god mode
drawswitchableimage invulnerable, "GOD1", "nullimage", 16, 167;
drawswitchableimage invulnerable, "GOD2", "nullimage", 287, 167;
//health
drawimage "CHAINBAC", 0, 190;
gamemode singleplayer
drawgem wiggle, interpolate(8), "CHAIN", "LIFEGEM2", 15, 25, 16, 2, 191;
else
drawgem wiggle, interpolate(8), translatable, "CHAIN", "LIFEGEM2", 15, 25, 16, 2, 191;
drawimage "LTFACE", 0, 190;
drawimage "RTFACE", 276, 190;
drawshader 16, 10, horizontal, 19, 190;
drawshader 16, 10, horizontal, reverse, 278, 190;
//statbar
gamemode singleplayer, cooperative
{
drawimage "LIFEBAR", 34, 160;
drawimage "ARMCLEAR", 57, 171;
drawnumber 3, HUDFONT_RAVEN, untranslated, health, interpolate(8), 87, 170, 1;
}
else
{
drawimage "STATBAR", 34, 160;
drawimage "ARMCLEAR", 57, 171;
drawnumber 3, HUDFONT_RAVEN, untranslated, frags, 87, 170, 1;
}
drawimage "ARMCLEAR", 224, 171;
drawnumber 3, HUDFONT_RAVEN, untranslated, armor, 254, 170, 1;
//ammo
usessecondaryammo not
{
drawnumber 3, HUDFONT_RAVEN, untranslated, ammo1, 135, 162, 1;
drawimage ammoicon1, 123, 180, center;
}
else
{
drawnumber 3, INDEXFONT_RAVEN, untranslated, ammo1, 137, 165;
drawnumber 3, INDEXFONT_RAVEN, untranslated, ammo2, 137, 177;
drawimage ammoicon1, 115, 169, center;
drawimage ammoicon2, 115, 180, center;
}
//keys
drawswitchableimage keyslot 3, "nullimage", "YKEYICON", 153, 164;
drawswitchableimage keyslot 1, "nullimage", "GKEYICON", 153, 172;
drawswitchableimage keyslot 2, "nullimage", "BKEYICON", 153, 180;
//inventory box
drawselectedinventory artiflash, INDEXFONT_RAVEN, 179, 160, 209, 182, untranslated;
}
statusbar inventory
{
drawimage "INVBAR", 34, 160;
drawinventorybar Heretic, noartibox, 7, INDEXFONT_RAVEN, 50, 160, 77, 182, untranslated;
}
statusbar inventoryfullscreen, fullscreenoffsets // ZDoom HUD overlay.
{
drawinventorybar Heretic, translucent, 7, INDEXFONT_RAVEN, -106+center, -31, -78+center, -9, untranslated;
}

259
wadsrc/static/sbarinfo/hexen.txt Executable file
View file

@ -0,0 +1,259 @@
/*******************************************************************************
* DEFAULT HEXEN STATUS BAR
*******************************************************************************
* If you wish to include this file into a custom status bar please use the
* following command:
*
* base Hexen;
*
* Using #include "sbarinfo/hexen.txt" will not be supported.
******************************************************************************/
height 38;
monospacefonts true, "0", center;
statusbar fullscreen, fullscreenoffsets
{
//health
drawnumber 2147483647, BIGFONT, untranslated, health, drawshadow, interpolate(8), 40, -20, 1;
//frags
gamemode deathmatch
drawnumber 2147483647, HUDFONT_RAVEN, untranslated, frags, drawshadow(1, 1), 70, -15, 1;
inventorybarnotvisible
{
drawselectedinventory alternateonempty, artiflash, INDEXFONT_RAVEN, -82, -31, -52, -8, untranslated
{
}
else
{
alpha 0.6
drawimage "ARTIBOX", -80, -30;
}
}
// Mana
weaponammo Mana1 && Mana2
{
weaponammo Mana1
drawimage "MANABRT1", -17, -30;
else
drawimage "MANADIM1", -17, -30;
weaponammo Mana2
drawimage "MANABRT2", -17, -15;
else
drawimage "MANADIM2", -17, -15;
drawnumber 2147483647, HUDFONT_RAVEN, untranslated, ammo Mana1, drawshadow(1, 1), -21, -30, 1;
drawnumber 2147483647, HUDFONT_RAVEN, untranslated, ammo Mana2, drawshadow(1, 1), -21, -15, 1;
}
}
statusbar Normal
{
drawimage "H2BAR", 0, 135;
drawimage "STATBAR", 38, 162;
drawselectedinventory artiflash, INDEXFONT_RAVEN, 143, 163, 174, 184, untranslated;
gamemode deathmatch, teamgame
{
drawimage "KILLS", 38, 163;
drawnumber 3, HUDFONT_RAVEN, untranslated, frags, 58, 163, 1;
}
else
{
drawimage "ARMCLS", 41, 178;
drawnumber 3, HUDFONT_RAVEN, untranslated, health, interpolate(6), 65, 176, 1, red, 25;
}
//mana bars
weaponammo Mana1 && Mana2
{
weaponammo Mana1
{
drawimage "MANABRT1", 77, 164;
drawbar "MANAVL1", "nullimage", ammo Mana1, vertical, 94, 164, 1;
}
else
{
drawimage "MANADIM1", 77, 164;
drawbar "MANAVL1D", "nullimage", ammo Mana1, vertical, 94, 164, 1;
}
weaponammo Mana2
{
drawimage "MANABRT2", 110, 164;
drawbar "MANAVL2", "nullimage", ammo Mana2, vertical, 102, 164, 1;
}
else
{
drawimage "MANADIM2", 110, 164;
drawbar "MANAVL2D", "nullimage", ammo Mana2, vertical, 102, 164, 1;
}
drawnumber 3, INDEXFONT_RAVEN, untranslated, ammo Mana1, 91, 181;
drawnumber 3, INDEXFONT_RAVEN, untranslated, ammo Mana2, 123, 181;
}
else //Weapon doesn't use ammo draw an alternative
{
drawimage "HAMOBACK", 77, 164;
usessecondaryammo
{
drawimage ammoicon1, 89, 172, center;
drawimage ammoicon2, 113, 172, center;
drawnumber 3, INDEXFONT_RAVEN, untranslated, ammo1, 98, 182;
drawnumber 3, INDEXFONT_RAVEN, untranslated, ammo2, 122, 182;
}
else
{
drawimage ammoicon1, 100, 172, center;
drawnumber 3, INDEXFONT_RAVEN, untranslated, ammo1, 109, 182;
}
}
//armor
drawimage "ARMCLS", 255, 178;
drawnumber 2, HUDFONT_RAVEN, untranslated, armorclass, 275, 176, 1;
playerclass Fighter
{
drawimage "WPSLOT0", 190, 162;
hasweaponpiece FWeapQuietus, 1
{
drawimage "WPIECEF1", 190, 162;
}
hasweaponpiece FWeapQuietus, 2
{
drawimage "WPIECEF2", 225, 162;
}
hasweaponpiece FWeapQuietus, 3
{
drawimage "WPIECEF3", 234, 162;
}
hasweaponpiece FWeapQuietus, 1
{
hasweaponpiece FWeapQuietus, 2
{
hasweaponpiece FWeapQuietus, 3
{
drawimage "WPFULL0", 190, 162;
}
}
}
gamemode singleplayer
drawgem interpolate(6), "CHAIN", "LIFEGMF2", -23, 49, 15, 30, 193;
else
drawgem translatable, interpolate(6), "CHAIN", "LIFEGMF2", -23, 49, 15, 30, 193;
}
else playerclass Cleric
{
drawimage "WPSLOT1", 190, 162;
hasweaponpiece CWeapWraithverge, 1
{
drawimage "WPIECEC1", 190, 162;
}
hasweaponpiece CWeapWraithverge, 2
{
drawimage "WPIECEC2", 212, 162;
}
hasweaponpiece CWeapWraithverge, 3
{
drawimage "WPIECEC3", 225, 162;
}
hasweaponpiece CWeapWraithverge, 1
{
hasweaponpiece CWeapWraithverge, 2
{
hasweaponpiece CWeapWraithverge, 3
{
drawimage "WPFULL1", 190, 162;
}
}
}
gamemode singleplayer
drawgem interpolate(6), "CHAIN2", "LIFEGMC2", -23, 49, 15, 30, 193;
else
drawgem translatable, interpolate(6), "CHAIN2", "LIFEGMC2", -23, 49, 15, 30, 193;
}
else playerclass Mage
{
drawimage "WPSLOT2", 190, 162;
hasweaponpiece MWeapBloodscourge, 1
{
drawimage "WPIECEM1", 190, 162;
}
hasweaponpiece MWeapBloodscourge, 2
{
drawimage "WPIECEM2", 205, 162;
}
hasweaponpiece MWeapBloodscourge, 3
{
drawimage "WPIECEM3", 224, 162;
}
hasweaponpiece MWeapBloodscourge, 1
{
hasweaponpiece MWeapBloodscourge, 2
{
hasweaponpiece MWeapBloodscourge, 3
{
drawimage "WPFULL2", 190, 162;
}
}
}
gamemode singleplayer
drawgem interpolate(6), "CHAIN3", "LIFEGMM2", -23, 49, 15, 30, 193;
else
drawgem translatable, interpolate(6), "CHAIN3", "LIFEGMM2", -23, 49, 15, 30, 193;
}
drawimage "LFEDGE", 0, 193;
drawimage "RTEDGE", 277, 193;
}
statusbar Automap
{
drawimage "H2BAR", 0, 135;
drawimage "KEYBAR", 38, 162;
drawkeybar 5, horizontal, 20, 46, 164;
drawimage hexenarmor armor, "ARMSLOT1", 150, 164;
drawimage hexenarmor shield, "ARMSLOT2", 181, 164;
drawimage hexenarmor helm, "ARMSLOT3", 212, 164;
drawimage hexenarmor amulet, "ARMSLOT4", 243, 164;
// Also draw the life gem here
playerclass Fighter
{
gamemode singleplayer
drawgem interpolate(6), "CHAIN", "LIFEGMF2", -23, 49, 15, 30, 193;
else
drawgem translatable, interpolate(6), "CHAIN", "LIFEGMF2", -23, 49, 15, 30, 193;
}
else playerclass Cleric
{
gamemode singleplayer
drawgem interpolate(6), "CHAIN2", "LIFEGMC2", -23, 49, 15, 30, 193;
else
drawgem translatable, interpolate(6), "CHAIN2", "LIFEGMC2", -23, 49, 15, 30, 193;
}
else playerclass Mage
{
gamemode singleplayer
drawgem interpolate(6), "CHAIN3", "LIFEGMM2", -23, 49, 15, 30, 193;
else
drawgem translatable, interpolate(6), "CHAIN3", "LIFEGMM2", -23, 49, 15, 30, 193;
}
drawimage "LFEDGE", 0, 193;
drawimage "RTEDGE", 277, 193;
}
statusbar inventory
{
drawimage "INVBAR", 38, 162;
drawinventorybar HexenStrict, noartibox, 7, INDEXFONT_RAVEN, 52, 164, 80, 185, untranslated;
}
statusbar inventoryfullscreen, fullscreenoffsets // ZDoom HUD overlay.
{
drawinventorybar HexenStrict, translucent, 7, INDEXFONT_RAVEN, -106+center, -31, -78+center, -10, untranslated;
}