mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-10 23:02:08 +00:00
This commit is contained in:
commit
733cf1acc5
18 changed files with 676 additions and 416 deletions
|
@ -54,6 +54,7 @@
|
|||
#include "r_utility.h"
|
||||
#include "cmdlib.h"
|
||||
#include "g_levellocals.h"
|
||||
#include "virtual.h"
|
||||
|
||||
#include <time.h>
|
||||
|
||||
|
@ -1079,6 +1080,48 @@ bool ST_IsLatencyVisible()
|
|||
&& (hud_showlag <= 2);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// draw the overlay
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
static void DrawPowerups(player_t *CPlayer)
|
||||
{
|
||||
// Each icon gets a 32x32 block to draw itself in.
|
||||
int x, y;
|
||||
AInventory *item;
|
||||
const int yshift = SmallFont->GetHeight();
|
||||
const int POWERUPICONSIZE = 32;
|
||||
|
||||
x = hudwidth -20;
|
||||
y = POWERUPICONSIZE * 5/4
|
||||
+ (ST_IsTimeVisible() ? yshift : 0)
|
||||
+ (ST_IsLatencyVisible() ? yshift : 0);
|
||||
|
||||
for (item = CPlayer->mo->Inventory; item != NULL; item = item->Inventory)
|
||||
{
|
||||
IFVIRTUALPTR(item, AInventory, GetPowerupIcon)
|
||||
{
|
||||
VMValue param[] = { item };
|
||||
int rv;
|
||||
VMReturn ret(&rv);
|
||||
GlobalVMStack.Call(func, param, 1, &ret, 1);
|
||||
auto tex = FSetTextureID(rv);
|
||||
if (!tex.isValid()) continue;
|
||||
auto texture = TexMan(tex);
|
||||
|
||||
screen->DrawTexture(texture, x, y, DTA_KeepRatio, true, DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_CenterBottomOffset, true, TAG_DONE);
|
||||
|
||||
x -= POWERUPICONSIZE;
|
||||
if (x < -hudwidth / 2)
|
||||
{
|
||||
x = -20;
|
||||
y += POWERUPICONSIZE * 3 / 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
|
@ -1158,6 +1201,7 @@ void DrawHUD()
|
|||
|
||||
DrawTime();
|
||||
DrawLatency();
|
||||
DrawPowerups(CPlayer);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -443,6 +443,7 @@ public:
|
|||
double drawClip[4] = { 0,0,0,0 }; // defines a clipping rectangle (not used yet)
|
||||
bool fullscreenOffsets = false; // current screen is displayed with fullscreen behavior.
|
||||
DVector2 cleanScale; // factor for scaled fullscreen display.
|
||||
FMugShot mugshot;
|
||||
|
||||
private:
|
||||
bool RepositionCoords (int &x, int &y, int xo, int yo, const int w, const int h) const;
|
||||
|
|
|
@ -1317,7 +1317,6 @@ public:
|
|||
|
||||
adjustRelCenter(x.RelCenter(), y.RelCenter(), dx, dy, rx, ry, xScale, yScale);
|
||||
|
||||
// We can't use DTA_HUDRules since it forces a width and height.
|
||||
// Translation: No high res.
|
||||
bool xright = *x < 0 && !x.RelCenter();
|
||||
bool ybot = *y < 0 && !y.RelCenter();
|
||||
|
|
|
@ -431,6 +431,7 @@ void DBaseStatusBar::CallTick()
|
|||
GlobalVMStack.Call(func, params, countof(params), nullptr, 0);
|
||||
}
|
||||
else Tick();
|
||||
mugshot.Tick(CPlayer);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -1023,6 +1024,7 @@ void DBaseStatusBar::SetMugShotState(const char *stateName, bool waitTillDone, b
|
|||
VMValue params[] = { (DObject*)this, &statestring, waitTillDone, reset };
|
||||
GlobalVMStack.Call(func, params, countof(params), nullptr, 0);
|
||||
}
|
||||
mugshot.SetState(stateName, waitTillDone, reset);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -1052,7 +1054,18 @@ void DBaseStatusBar::DrawTopStuff (EHudState state)
|
|||
DTA_CleanNoMove, true, TAG_DONE);
|
||||
}
|
||||
|
||||
DrawPowerups ();
|
||||
if (state != HUD_AltHud)
|
||||
{
|
||||
auto saved = fullscreenOffsets;
|
||||
fullscreenOffsets = true;
|
||||
IFVIRTUAL(DBaseStatusBar, DrawPowerups)
|
||||
{
|
||||
VMValue params[] = { (DObject*)this };
|
||||
GlobalVMStack.Call(func, params, 1, nullptr, 0);
|
||||
}
|
||||
fullscreenOffsets = saved;
|
||||
}
|
||||
|
||||
if (automapactive && !viewactive)
|
||||
{
|
||||
DrawMessages (HUDMSGLayer_OverMap, (state == HUD_StatusBar) ? gST_Y : SCREENHEIGHT);
|
||||
|
@ -1068,46 +1081,6 @@ void DBaseStatusBar::DrawTopStuff (EHudState state)
|
|||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DrawPowerups
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void DBaseStatusBar::DrawPowerups ()
|
||||
{
|
||||
// Each icon gets a 32x32 block to draw itself in.
|
||||
int x, y;
|
||||
AInventory *item;
|
||||
const int yshift = SmallFont->GetHeight();
|
||||
|
||||
x = -20;
|
||||
y = 17
|
||||
+ (ST_IsTimeVisible() ? yshift : 0)
|
||||
+ (ST_IsLatencyVisible() ? yshift : 0);
|
||||
for (item = CPlayer->mo->Inventory; item != NULL; item = item->Inventory)
|
||||
{
|
||||
IFVIRTUALPTR(item, AInventory, DrawPowerup)
|
||||
{
|
||||
VMValue params[3] = { item, x, y };
|
||||
VMReturn ret;
|
||||
int retv;
|
||||
|
||||
ret.IntAt(&retv);
|
||||
GlobalVMStack.Call(func, params, 3, &ret, 1);
|
||||
if (retv)
|
||||
{
|
||||
x -= POWERUPICONSIZE;
|
||||
if (x < -POWERUPICONSIZE * 5)
|
||||
{
|
||||
x = -20;
|
||||
y += POWERUPICONSIZE * 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// BlendView
|
||||
|
@ -1225,6 +1198,7 @@ void DBaseStatusBar::NewGame ()
|
|||
VMValue params[] = { (DObject*)this };
|
||||
GlobalVMStack.Call(func, params, countof(params), nullptr, 0);
|
||||
}
|
||||
mugshot.Reset();
|
||||
}
|
||||
|
||||
void DBaseStatusBar::ShowPop(int pop)
|
||||
|
@ -1426,7 +1400,6 @@ void DBaseStatusBar::DrawGraphic(FTextureID texture, bool animate, double x, dou
|
|||
// Todo: Allow other scaling values, too.
|
||||
if (Scaled)
|
||||
{
|
||||
y += RelTop - VerticalResolution;
|
||||
screen->VirtualToRealCoords(x, y, width, height, HorizontalResolution, VerticalResolution, true, true);
|
||||
}
|
||||
}
|
||||
|
@ -1517,8 +1490,135 @@ void DBaseStatusBar::DrawString(FFont *font, const FString &cstring, double x, d
|
|||
x -= static_cast<int> ((spacing)* cstring.Len()) / 2;
|
||||
break;
|
||||
}
|
||||
|
||||
const uint8_t* str = (const uint8_t*)cstring.GetChars();
|
||||
const EColorRange boldTranslation = EColorRange(translation ? translation - 1 : NumTextColors - 1);
|
||||
int fontcolor = translation;
|
||||
double orgx = 0, orgy = 0;
|
||||
|
||||
if (fullscreenOffsets)
|
||||
{
|
||||
if (hud_scale)
|
||||
{
|
||||
shadowX *= (int)cleanScale.X;
|
||||
shadowY *= (int)cleanScale.Y;
|
||||
}
|
||||
|
||||
switch (screenalign & HMASK)
|
||||
{
|
||||
default: orgx = 0; break;
|
||||
case HCENTER: orgx = screen->GetWidth() / 2; break;
|
||||
case RIGHT: orgx = screen->GetWidth(); break;
|
||||
}
|
||||
|
||||
switch (screenalign & VMASK)
|
||||
{
|
||||
default: orgy = 0; break;
|
||||
case VCENTER: orgy = screen->GetHeight() / 2; break;
|
||||
case BOTTOM: orgy = screen->GetHeight(); break;
|
||||
}
|
||||
|
||||
if (screenalign == (RIGHT | TOP) && vid_fps) orgy += 10;
|
||||
}
|
||||
int ch;
|
||||
while (ch = *str++, ch != '\0')
|
||||
{
|
||||
if (ch == ' ')
|
||||
{
|
||||
x += monospaced ? spacing : font->GetSpaceWidth() + spacing;
|
||||
continue;
|
||||
}
|
||||
else if (ch == TEXTCOLOR_ESCAPE)
|
||||
{
|
||||
EColorRange newColor = V_ParseFontColor(str, translation, boldTranslation);
|
||||
if (newColor != CR_UNDEFINED)
|
||||
fontcolor = newColor;
|
||||
continue;
|
||||
}
|
||||
|
||||
int width;
|
||||
FTexture* c = font->GetChar((unsigned char)ch, &width);
|
||||
if (c == NULL) //missing character.
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!monospaced) //If we are monospaced lets use the offset
|
||||
x += (c->LeftOffset + 1); //ignore x offsets since we adapt to character size
|
||||
|
||||
double rx, ry, rw, rh;
|
||||
rx = x + drawOffset.X;
|
||||
ry = y + drawOffset.Y;
|
||||
rw = c->GetScaledWidthDouble();
|
||||
rh = c->GetScaledHeightDouble();
|
||||
|
||||
if (monospaced)
|
||||
{
|
||||
// align the character in the monospaced cell according to the general alignment to ensure that it gets positioned properly
|
||||
// (i.e. right aligned text aligns to the right edge of the character and not the empty part of the cell.)
|
||||
switch (align)
|
||||
{
|
||||
default:
|
||||
break;
|
||||
case ALIGN_CENTER:
|
||||
rx -= (spacing) / 2;
|
||||
break;
|
||||
case ALIGN_RIGHT:
|
||||
rx -= spacing;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!fullscreenOffsets)
|
||||
{
|
||||
rx += ST_X;
|
||||
ry += ST_Y;
|
||||
|
||||
// Todo: Allow other scaling values, too.
|
||||
if (Scaled)
|
||||
{
|
||||
screen->VirtualToRealCoords(rx, ry, rw, rh, HorizontalResolution, VerticalResolution, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (hud_scale)
|
||||
{
|
||||
rx *= cleanScale.X;
|
||||
ry *= cleanScale.Y;
|
||||
rw *= cleanScale.X;
|
||||
rh *= cleanScale.Y;
|
||||
}
|
||||
rx += orgx;
|
||||
ry += orgy;
|
||||
}
|
||||
// This is not really such a great way to draw shadows because they can overlap with previously drawn characters.
|
||||
// This may have to be changed to draw the shadow text up front separately.
|
||||
if (shadowX != 0 || shadowY != 0)
|
||||
{
|
||||
screen->DrawChar(font, CR_UNTRANSLATED, rx + shadowX, ry + shadowY, ch,
|
||||
DTA_DestWidthF, rw,
|
||||
DTA_DestHeightF, rh,
|
||||
DTA_Alpha, (Alpha * HR_SHADOW),
|
||||
DTA_FillColor, 0,
|
||||
TAG_DONE);
|
||||
}
|
||||
screen->DrawChar(font, fontcolor, rx, ry, ch,
|
||||
DTA_DestWidthF, rw,
|
||||
DTA_DestHeightF, rh,
|
||||
DTA_Alpha, Alpha,
|
||||
TAG_DONE);
|
||||
|
||||
if (!monospaced)
|
||||
x += width + spacing - (c->LeftOffset + 1);
|
||||
else
|
||||
x += spacing;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DBaseStatusBar, DrawString)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DBaseStatusBar);
|
||||
|
@ -1527,7 +1627,7 @@ DEFINE_ACTION_FUNCTION(DBaseStatusBar, DrawString)
|
|||
PARAM_FLOAT(x);
|
||||
PARAM_FLOAT(y);
|
||||
PARAM_FLOAT(alpha);
|
||||
PARAM_BOOL(trans);
|
||||
PARAM_INT(trans);
|
||||
PARAM_INT(ialign);
|
||||
PARAM_INT(salign);
|
||||
PARAM_INT_DEF(spacing);
|
||||
|
@ -1636,3 +1736,64 @@ DEFINE_ACTION_FUNCTION(DBaseStatusBar, GetGlobalACSArrayString)
|
|||
PARAM_INT(index);
|
||||
ACTION_RETURN_STRING(FBehavior::StaticLookupString(ACS_GlobalArrays[arrayno][index]));
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DBaseStatusBar, GetGlobalACSValue)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
PARAM_INT(index);
|
||||
ACTION_RETURN_INT(ACS_GlobalVars[index]);
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DBaseStatusBar, GetGlobalACSArrayValue)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
PARAM_INT(arrayno);
|
||||
PARAM_INT(index);
|
||||
ACTION_RETURN_INT(ACS_GlobalArrays[arrayno][index]);
|
||||
}
|
||||
|
||||
enum ENumFlags
|
||||
{
|
||||
FNF_FILLZEROS,
|
||||
FNF_WHENNOTZERO,
|
||||
};
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DBaseStatusBar, FormatNumber)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
PARAM_INT(number);
|
||||
PARAM_INT(minsize);
|
||||
PARAM_INT(maxsize);
|
||||
PARAM_INT(flags);
|
||||
PARAM_STRING_DEF(prefix);
|
||||
static int maxvals[] = { 1, 9, 99, 999, 9999, 99999, 999999, 9999999, 99999999, 999999999 };
|
||||
|
||||
if (number == 0 && (flags & FNF_WHENNOTZERO)) ACTION_RETURN_STRING("");
|
||||
if (maxsize > 0 && maxsize < 10)
|
||||
{
|
||||
number = clamp(number, -maxvals[maxsize - 1], maxvals[maxsize]);
|
||||
}
|
||||
FString fmt;
|
||||
if (minsize <= 1) fmt.Format("%s%d", prefix.GetChars(), number);
|
||||
else if (flags & FNF_FILLZEROS) fmt.Format("%s%0*d", prefix.GetChars(), minsize, number);
|
||||
else fmt.Format("%s%*d", prefix.GetChars(), minsize, number);
|
||||
ACTION_RETURN_STRING(fmt);
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DBaseStatusBar, ReceivedWeapon)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DBaseStatusBar);
|
||||
self->mugshot.Grin();
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DBaseStatusBar, GetMugshot)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DBaseStatusBar);
|
||||
PARAM_POINTER(player, player_t);
|
||||
PARAM_STRING(def_face);
|
||||
PARAM_INT(accuracy);
|
||||
PARAM_INT_DEF(stateflags);
|
||||
auto tex = self->mugshot.GetFace(player, def_face, accuracy, (FMugShot::StateFlags)stateflags);
|
||||
ACTION_RETURN_INT(tex ? tex->id.GetIndex() : -1);
|
||||
}
|
||||
|
|
|
@ -490,7 +490,7 @@ FMaterial::FMaterial(FTexture * tx, bool expanded)
|
|||
mSpriteU[1] = mSpriteV[1] = 1.f;
|
||||
|
||||
FTexture *basetex = (tx->bWarped && gl.legacyMode)? tx : tx->GetRedirect(false);
|
||||
// allow the redirect only if the textute is not expanded or the scale matches.
|
||||
// allow the redirect only if the texture is not expanded or the scale matches.
|
||||
if (!expanded || (tx->Scale.X == basetex->Scale.X && tx->Scale.Y == basetex->Scale.Y))
|
||||
{
|
||||
mBaseLayer = ValidateSysTexture(basetex, expanded);
|
||||
|
|
|
@ -287,6 +287,23 @@ bool PolyCull::GetAnglesForLine(double x1, double y1, double x2, double y2, angl
|
|||
return !IsSegmentCulled(angle1, angle2);
|
||||
}
|
||||
|
||||
void PolyCull::MarkViewFrustum()
|
||||
{
|
||||
// Clips things outside the viewing frustum.
|
||||
auto &viewpoint = PolyRenderer::Instance()->Viewpoint;
|
||||
auto &viewwindow = PolyRenderer::Instance()->Viewwindow;
|
||||
double tilt = fabs(viewpoint.Angles.Pitch.Degrees);
|
||||
if (tilt > 46.0) // If the pitch is larger than this you can look all around
|
||||
return;
|
||||
|
||||
double floatangle = 2.0 + (45.0 + ((tilt / 1.9)))*viewpoint.FieldOfView.Degrees*48.0 / AspectMultiplier(viewwindow.WidescreenRatio) / 90.0;
|
||||
angle_t a1 = DAngle(floatangle).BAMs();
|
||||
if (a1 < ANGLE_180)
|
||||
{
|
||||
MarkSegmentCulled(AngleToPseudo(viewpoint.Angles.Yaw.BAMs() + a1), AngleToPseudo(viewpoint.Angles.Yaw.BAMs() - a1));
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// ! Returns the pseudoangle between the line p1 to (infinity, p1.y) and the
|
||||
|
@ -320,3 +337,16 @@ angle_t PolyCull::PointToPseudoAngle(double x, double y)
|
|||
return xs_Fix<30>::ToFix(result);
|
||||
}
|
||||
}
|
||||
|
||||
angle_t PolyCull::AngleToPseudo(angle_t ang)
|
||||
{
|
||||
double vecx = cos(ang * M_PI / ANGLE_180);
|
||||
double vecy = sin(ang * M_PI / ANGLE_180);
|
||||
|
||||
double result = vecy / (fabs(vecx) + fabs(vecy));
|
||||
if (vecx < 0)
|
||||
{
|
||||
result = 2.f - result;
|
||||
}
|
||||
return xs_Fix<30>::ToFix(result);
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ public:
|
|||
void MarkSegmentCulled(angle_t angle1, angle_t angle2);
|
||||
bool IsSegmentCulled(angle_t angle1, angle_t angle2) const;
|
||||
void InvertSegments();
|
||||
void MarkViewFrustum();
|
||||
|
||||
std::vector<subsector_t *> PvsSectors;
|
||||
double MaxCeilingHeight = 0.0;
|
||||
|
@ -64,4 +65,5 @@ private:
|
|||
Vec4f PortalClipPlane;
|
||||
|
||||
static angle_t PointToPseudoAngle(double x, double y);
|
||||
static angle_t AngleToPseudo(angle_t ang);
|
||||
};
|
||||
|
|
|
@ -73,6 +73,7 @@ void RenderPolyScene::Render(int portalDepth)
|
|||
ClearBuffers();
|
||||
if (!PortalSegmentsAdded)
|
||||
Cull.ClearSolidSegments();
|
||||
Cull.MarkViewFrustum();
|
||||
Cull.CullScene(WorldToClip, PortalPlane);
|
||||
Cull.ClearSolidSegments();
|
||||
RenderSectors();
|
||||
|
@ -124,6 +125,8 @@ void RenderPolyScene::RenderSubsector(subsector_t *sub)
|
|||
}
|
||||
}
|
||||
|
||||
RenderMemory &memory = PolyRenderer::Instance()->FrameMemory;
|
||||
|
||||
bool mainBSP = ((unsigned int)(sub->Index()) < level.subsectors.Size());
|
||||
if (mainBSP)
|
||||
{
|
||||
|
@ -131,7 +134,7 @@ void RenderPolyScene::RenderSubsector(subsector_t *sub)
|
|||
for (int i = ParticlesInSubsec[subsectorIndex]; i != NO_PARTICLE; i = Particles[i].snext)
|
||||
{
|
||||
particle_t *particle = Particles + i;
|
||||
TranslucentObjects.push_back({ particle, sub, subsectorDepth });
|
||||
TranslucentObjects.push_back(memory.NewObject<PolyTranslucentObject>(particle, sub, subsectorDepth));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -146,7 +149,7 @@ void RenderPolyScene::RenderSprite(AActor *thing, double sortDistance, const DVe
|
|||
subsector_t *sub = &level.subsectors[0];
|
||||
auto it = SubsectorDepths.find(sub);
|
||||
if (it != SubsectorDepths.end())
|
||||
TranslucentObjects.push_back({ thing, sub, it->second, sortDistance, 0.0f, 1.0f });
|
||||
TranslucentObjects.push_back(PolyRenderer::Instance()->FrameMemory.NewObject<PolyTranslucentObject>(thing, sub, it->second, sortDistance, 0.0f, 1.0f));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -187,7 +190,7 @@ void RenderPolyScene::RenderSprite(AActor *thing, double sortDistance, DVector2
|
|||
|
||||
auto it = SubsectorDepths.find(sub);
|
||||
if (it != SubsectorDepths.end())
|
||||
TranslucentObjects.push_back({ thing, sub, it->second, sortDistance, (float)t1, (float)t2 });
|
||||
TranslucentObjects.push_back(PolyRenderer::Instance()->FrameMemory.NewObject<PolyTranslucentObject>(thing, sub, it->second, sortDistance, (float)t1, (float)t2));
|
||||
}
|
||||
|
||||
void RenderPolyScene::RenderLine(subsector_t *sub, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth)
|
||||
|
@ -347,29 +350,29 @@ void RenderPolyScene::RenderTranslucent(int portalDepth)
|
|||
}
|
||||
}
|
||||
|
||||
std::stable_sort(TranslucentObjects.begin(), TranslucentObjects.end());
|
||||
std::stable_sort(TranslucentObjects.begin(), TranslucentObjects.end(), [](auto a, auto b) { return *a < *b; });
|
||||
|
||||
for (auto it = TranslucentObjects.rbegin(); it != TranslucentObjects.rend(); ++it)
|
||||
{
|
||||
auto &obj = *it;
|
||||
if (obj.particle)
|
||||
PolyTranslucentObject *obj = *it;
|
||||
if (obj->particle)
|
||||
{
|
||||
RenderPolyParticle spr;
|
||||
spr.Render(WorldToClip, PortalPlane, obj.particle, obj.sub, obj.subsectorDepth, StencilValue + 1);
|
||||
spr.Render(WorldToClip, PortalPlane, obj->particle, obj->sub, obj->subsectorDepth, StencilValue + 1);
|
||||
}
|
||||
else if (!obj.thing)
|
||||
else if (!obj->thing)
|
||||
{
|
||||
obj.wall.Render(WorldToClip, PortalPlane, Cull);
|
||||
obj->wall.Render(WorldToClip, PortalPlane, Cull);
|
||||
}
|
||||
else if ((obj.thing->renderflags & RF_SPRITETYPEMASK) == RF_WALLSPRITE)
|
||||
else if ((obj->thing->renderflags & RF_SPRITETYPEMASK) == RF_WALLSPRITE)
|
||||
{
|
||||
RenderPolyWallSprite wallspr;
|
||||
wallspr.Render(WorldToClip, PortalPlane, obj.thing, obj.sub, obj.subsectorDepth, StencilValue + 1);
|
||||
wallspr.Render(WorldToClip, PortalPlane, obj->thing, obj->sub, obj->subsectorDepth, StencilValue + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
RenderPolySprite spr;
|
||||
spr.Render(WorldToClip, PortalPlane, obj.thing, obj.sub, obj.subsectorDepth, StencilValue + 1, obj.SpriteLeft, obj.SpriteRight);
|
||||
spr.Render(WorldToClip, PortalPlane, obj->thing, obj->sub, obj->subsectorDepth, StencilValue + 1, obj->SpriteLeft, obj->SpriteRight);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -97,7 +97,7 @@ private:
|
|||
uint32_t NextSubsectorDepth = 0;
|
||||
std::set<sector_t *> SeenSectors;
|
||||
std::unordered_map<subsector_t *, uint32_t> SubsectorDepths;
|
||||
std::vector<PolyTranslucentObject> TranslucentObjects;
|
||||
std::vector<PolyTranslucentObject *> TranslucentObjects;
|
||||
|
||||
std::vector<std::unique_ptr<PolyDrawSectorPortal>> SectorPortals;
|
||||
std::vector<std::unique_ptr<PolyDrawLinePortal>> LinePortals;
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
EXTERN_CVAR(Bool, r_drawmirrors)
|
||||
|
||||
bool RenderPolyWall::RenderLine(const TriMatrix &worldToClip, const Vec4f &clipPlane, PolyCull &cull, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, std::vector<PolyTranslucentObject> &translucentWallsOutput, std::vector<std::unique_ptr<PolyDrawLinePortal>> &linePortals)
|
||||
bool RenderPolyWall::RenderLine(const TriMatrix &worldToClip, const Vec4f &clipPlane, PolyCull &cull, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, std::vector<PolyTranslucentObject*> &translucentWallsOutput, std::vector<std::unique_ptr<PolyDrawLinePortal>> &linePortals)
|
||||
{
|
||||
PolyDrawLinePortal *polyportal = nullptr;
|
||||
if (line->backsector == nullptr && line->linedef && line->sidedef == line->linedef->sidedef[0] && (line->linedef->special == Line_Mirror && r_drawmirrors))
|
||||
|
@ -153,7 +153,7 @@ bool RenderPolyWall::RenderLine(const TriMatrix &worldToClip, const Vec4f &clipP
|
|||
|
||||
FTexture *midtex = TexMan(line->sidedef->GetTexture(side_t::mid), true);
|
||||
if (midtex && midtex->UseType != FTexture::TEX_Null)
|
||||
translucentWallsOutput.push_back({ wall });
|
||||
translucentWallsOutput.push_back(PolyRenderer::Instance()->FrameMemory.NewObject<PolyTranslucentObject>(wall));
|
||||
|
||||
if (polyportal)
|
||||
{
|
||||
|
@ -165,7 +165,7 @@ bool RenderPolyWall::RenderLine(const TriMatrix &worldToClip, const Vec4f &clipP
|
|||
return polyportal != nullptr;
|
||||
}
|
||||
|
||||
void RenderPolyWall::Render3DFloorLine(const TriMatrix &worldToClip, const Vec4f &clipPlane, PolyCull &cull, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, F3DFloor *fakeFloor, std::vector<PolyTranslucentObject> &translucentWallsOutput)
|
||||
void RenderPolyWall::Render3DFloorLine(const TriMatrix &worldToClip, const Vec4f &clipPlane, PolyCull &cull, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, F3DFloor *fakeFloor, std::vector<PolyTranslucentObject*> &translucentWallsOutput)
|
||||
{
|
||||
double frontceilz1 = fakeFloor->top.plane->ZatPoint(line->v1);
|
||||
double frontfloorz1 = fakeFloor->bottom.plane->ZatPoint(line->v1);
|
||||
|
|
|
@ -32,8 +32,8 @@ class Vec4f;
|
|||
class RenderPolyWall
|
||||
{
|
||||
public:
|
||||
static bool RenderLine(const TriMatrix &worldToClip, const Vec4f &clipPlane, PolyCull &cull, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, std::vector<PolyTranslucentObject> &translucentWallsOutput, std::vector<std::unique_ptr<PolyDrawLinePortal>> &linePortals);
|
||||
static void Render3DFloorLine(const TriMatrix &worldToClip, const Vec4f &clipPlane, PolyCull &cull, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, F3DFloor *fakeFloor, std::vector<PolyTranslucentObject> &translucentWallsOutput);
|
||||
static bool RenderLine(const TriMatrix &worldToClip, const Vec4f &clipPlane, PolyCull &cull, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, std::vector<PolyTranslucentObject*> &translucentWallsOutput, std::vector<std::unique_ptr<PolyDrawLinePortal>> &linePortals);
|
||||
static void Render3DFloorLine(const TriMatrix &worldToClip, const Vec4f &clipPlane, PolyCull &cull, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, F3DFloor *fakeFloor, std::vector<PolyTranslucentObject*> &translucentWallsOutput);
|
||||
|
||||
void SetCoords(const DVector2 &v1, const DVector2 &v2, double ceil1, double floor1, double ceil2, double floor2);
|
||||
void Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, PolyCull &cull);
|
||||
|
|
|
@ -144,16 +144,6 @@ DEFINE_ACTION_FUNCTION(_Screen, DrawTexture)
|
|||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(_Screen, DrawHUDTexture)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
PARAM_INT(texid);
|
||||
PARAM_FLOAT(x);
|
||||
PARAM_FLOAT(y);
|
||||
screen->DrawTexture(TexMan(FSetTextureID(texid)), x, y, DTA_HUDRules, HUD_Normal, TAG_END);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DCanvas::DrawTextureParms(FTexture *img, DrawParms &parms)
|
||||
{
|
||||
#ifndef NO_SWRENDER
|
||||
|
@ -220,6 +210,8 @@ bool DCanvas::SetTextureParms(DrawParms *parms, FTexture *img, double xx, double
|
|||
case DTA_HUDRules:
|
||||
case DTA_HUDRulesC:
|
||||
{
|
||||
// Note that this has been deprecated because it cannot intelligently decide what scale
|
||||
// actually needs to be used in conjunction with the active status bar.
|
||||
bool xright = parms->x < 0;
|
||||
bool ybot = parms->y < 0;
|
||||
|
||||
|
|
|
@ -61,6 +61,35 @@ INDEXFONT_DOOM
|
|||
9 STYSNUM9
|
||||
}
|
||||
|
||||
INDEXFONT_STRIFE_YELLOW
|
||||
{
|
||||
% INVFONY%
|
||||
0 INVFONY0
|
||||
1 INVFONY1
|
||||
2 INVFONY2
|
||||
3 INVFONY3
|
||||
4 INVFONY4
|
||||
5 INVFONY5
|
||||
6 INVFONY6
|
||||
7 INVFONY7
|
||||
8 INVFONY8
|
||||
9 INVFONY9
|
||||
}
|
||||
|
||||
INDEXFONT_STRIFE_GREEN
|
||||
{
|
||||
% INVFONG%
|
||||
0 INVFONG0
|
||||
1 INVFONG1
|
||||
2 INVFONG2
|
||||
3 INVFONG3
|
||||
4 INVFONG4
|
||||
5 INVFONG5
|
||||
6 INVFONG6
|
||||
7 INVFONG7
|
||||
8 INVFONG8
|
||||
9 INVFONG9
|
||||
}
|
||||
|
||||
// Doom and Chex intermissions use special text glyphs. The Raven and Strife
|
||||
// games just use the standard big font.
|
||||
|
|
|
@ -159,13 +159,18 @@ struct Screen native
|
|||
native static void Clear(int left, int top, int right, int bottom, Color color, int palcolor = -1);
|
||||
native static void Dim(Color col, double amount, int x, int y, int w, int h);
|
||||
|
||||
native static void DrawHUDTexture(TextureID tex, double x, double y);
|
||||
native static vararg void DrawTexture(TextureID tex, bool animate, double x, double y, ...);
|
||||
native static vararg void DrawChar(Font font, int normalcolor, double x, double y, int character, ...);
|
||||
native static vararg void DrawText(Font font, int normalcolor, double x, double y, String text, ...);
|
||||
native static void DrawFrame(int x, int y, int w, int h);
|
||||
native static Vector2, Vector2 VirtualToRealCoords(Vector2 pos, Vector2 size, Vector2 vsize, bool vbottom=false, bool handleaspect=true);
|
||||
native static double GetAspectRatio();
|
||||
|
||||
// This is a leftover of the abandoned Inventory.DrawPowerup method.
|
||||
deprecated("2.5") static ui void DrawHUDTexture(TextureID tex, double x, double y)
|
||||
{
|
||||
statusBar.DrawTexture(tex, (x, y), true, 1., BaseStatusBar.ALIGN_TOP|BaseStatusBar.ALIGN_RIGHT, (32, 32), BaseStatusBar.ALIGN_CENTER_BOTTOM);
|
||||
}
|
||||
}
|
||||
|
||||
struct Font native
|
||||
|
|
|
@ -820,13 +820,28 @@ class Inventory : Actor native
|
|||
//
|
||||
// AInventory :: DrawPowerup
|
||||
//
|
||||
// Gives self item a chance to draw a special status indicator on the screen.
|
||||
// Returns false if it didn't draw anything.
|
||||
// This has been deprecated because it is not how this should be done
|
||||
// Use GetPowerupIcon instead!
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
virtual ui version("2.4") bool DrawPowerup(int x, int y) { return false; }
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// AInventory :: GetPowerupIcon
|
||||
//
|
||||
// Returns the icon that should be drawn for an active powerup.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
virtual clearscope version("2.5") TextureID GetPowerupIcon() const
|
||||
{
|
||||
TextureID id;
|
||||
id.SetInvalid();
|
||||
return id;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// AInventory :: AbsorbDamage
|
||||
|
|
|
@ -273,17 +273,9 @@ class Powerup : Inventory
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
override bool DrawPowerup (int x, int y)
|
||||
override TextureID GetPowerupIcon()
|
||||
{
|
||||
if (!Icon.isValid())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!isBlinking())
|
||||
{
|
||||
screen.DrawHUDTexture(Icon, x, y);
|
||||
}
|
||||
return true;
|
||||
return Icon;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -292,7 +284,7 @@ class Powerup : Inventory
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
virtual bool isBlinking() const
|
||||
virtual clearscope bool isBlinking() const
|
||||
{
|
||||
return (EffectTics <= BLINKTHRESHOLD && (EffectTics & 8) && !bNoScreenBlink);
|
||||
}
|
||||
|
@ -941,7 +933,7 @@ class PowerFlight : Powerup
|
|||
+INVENTORY.HUBPOWER
|
||||
}
|
||||
|
||||
ui bool HitCenterFrame;
|
||||
clearscope bool HitCenterFrame;
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
|
@ -1011,50 +1003,46 @@ class PowerFlight : Powerup
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
override bool DrawPowerup (int x, int y)
|
||||
override TextureID GetPowerupIcon ()
|
||||
{
|
||||
// If this item got a valid icon use that instead of the default spinning wings.
|
||||
if (Icon.isValid())
|
||||
{
|
||||
return Super.DrawPowerup(x, y);
|
||||
return Icon;
|
||||
}
|
||||
|
||||
if (EffectTics > BLINKTHRESHOLD || !(EffectTics & 16))
|
||||
{
|
||||
TextureID picnum = TexMan.CheckForTexture ("SPFLY0", TexMan.Type_MiscPatch);
|
||||
int frame = (level.time/3) & 15;
|
||||
TextureID picnum = TexMan.CheckForTexture ("SPFLY0", TexMan.Type_MiscPatch);
|
||||
int frame = (level.time/3) & 15;
|
||||
|
||||
if (!picnum.isValid())
|
||||
if (!picnum.isValid())
|
||||
{
|
||||
return picnum;
|
||||
}
|
||||
if (Owner.bNoGravity)
|
||||
{
|
||||
if (HitCenterFrame && (frame != 15 && frame != 0))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (Owner.bNoGravity)
|
||||
{
|
||||
if (HitCenterFrame && (frame != 15 && frame != 0))
|
||||
{
|
||||
screen.DrawHUDTexture (picnum + 15, x, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
screen.DrawHUDTexture (picnum + frame, x, y);
|
||||
HitCenterFrame = false;
|
||||
}
|
||||
return picnum + 15;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!HitCenterFrame && (frame != 15 && frame != 0))
|
||||
{
|
||||
screen.DrawHUDTexture (picnum + frame, x, y);
|
||||
HitCenterFrame = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
screen.DrawHUDTexture (picnum+15, x, y);
|
||||
HitCenterFrame = true;
|
||||
}
|
||||
HitCenterFrame = false;
|
||||
return picnum + frame;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!HitCenterFrame && (frame != 15 && frame != 0))
|
||||
{
|
||||
HitCenterFrame = false;
|
||||
return picnum + frame;
|
||||
}
|
||||
else
|
||||
{
|
||||
HitCenterFrame = true;
|
||||
return picnum+15;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,21 @@
|
|||
|
||||
struct MugShot
|
||||
{
|
||||
enum StateFlags
|
||||
{
|
||||
STANDARD = 0x0,
|
||||
|
||||
XDEATHFACE = 0x1,
|
||||
ANIMATEDGODMODE = 0x2,
|
||||
DISABLEGRIN = 0x4,
|
||||
DISABLEOUCH = 0x8,
|
||||
DISABLEPAIN = 0x10,
|
||||
DISABLERAMPAGE = 0x20,
|
||||
CUSTOM = 0x40,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class BaseStatusBar native ui
|
||||
{
|
||||
enum EPop
|
||||
|
@ -46,19 +63,24 @@ class BaseStatusBar native ui
|
|||
DI_SKIPREADY = 0x8,
|
||||
DI_ALTICONFIRST = 0x10,
|
||||
DI_TRANSLATABLE = 0x20,
|
||||
DI_FORCESCALE = 0x40
|
||||
DI_FORCESCALE = 0x40,
|
||||
DI_DIM = 0x80,
|
||||
};
|
||||
|
||||
enum IconType
|
||||
{
|
||||
PLAYERICON = 1000,
|
||||
AMMO1,
|
||||
AMMO2,
|
||||
ARMOR,
|
||||
WEAPONICON,
|
||||
SIGIL,
|
||||
WEAPONSLOT,
|
||||
SELECTEDINVENTORYICON,
|
||||
ITYPE_PLAYERICON = 1000,
|
||||
ITYPE_AMMO1,
|
||||
ITYPE_AMMO2,
|
||||
ITYPE_ARMOR,
|
||||
ITYPE_WEAPON,
|
||||
ITYPE_SIGIL,
|
||||
ITYPE_WEAPONSLOT,
|
||||
ITYPE_SELECTEDINVENTORY,
|
||||
}
|
||||
|
||||
enum HexArmorType
|
||||
{
|
||||
HEXENARMOR_ARMOR,
|
||||
HEXENARMOR_SHIELD,
|
||||
HEXENARMOR_HELM,
|
||||
|
@ -67,35 +89,36 @@ class BaseStatusBar native ui
|
|||
|
||||
enum EAlign
|
||||
{
|
||||
TOP = 0,
|
||||
VCENTER = 1,
|
||||
BOTTOM = 2,
|
||||
VOFFSET = 3,
|
||||
VMASK = 3,
|
||||
ALIGN_TOP = 0,
|
||||
ALIGN_VCENTER = 1,
|
||||
ALIGN_BOTTOM = 2,
|
||||
ALIGN_VOFFSET = 3,
|
||||
ALIGN_VMASK = 3,
|
||||
|
||||
LEFT = 0,
|
||||
HCENTER = 4,
|
||||
RIGHT = 8,
|
||||
HOFFSET = 12,
|
||||
HMASK = 12,
|
||||
ALIGN_LEFT = 0,
|
||||
ALIGN_HCENTER = 4,
|
||||
ALIGN_RIGHT = 8,
|
||||
ALIGN_HOFFSET = 12,
|
||||
ALIGN_HMASK = 12,
|
||||
|
||||
CENTER = VCENTER|HCENTER,
|
||||
CENTER_BOTTOM = BOTTOM|HCENTER
|
||||
ALIGN_CENTER = ALIGN_VCENTER|ALIGN_HCENTER,
|
||||
ALIGN_CENTER_BOTTOM = ALIGN_BOTTOM|ALIGN_HCENTER,
|
||||
ALIGN_OFFSETS = ALIGN_HOFFSET|ALIGN_VOFFSET
|
||||
};
|
||||
|
||||
enum ETextAlign
|
||||
{
|
||||
ALIGN_LEFT = 0,
|
||||
ALIGN_CENTER = 1,
|
||||
ALIGN_RIGHT = 2
|
||||
TEXT_LEFT = 0,
|
||||
TEXT_CENTER = 1,
|
||||
TEXT_RIGHT = 2
|
||||
};
|
||||
|
||||
enum SBGameModes
|
||||
{
|
||||
SINGLEPLAYER = 0x1,
|
||||
COOPERATIVE = 0x2,
|
||||
DEATHMATCH = 0x4,
|
||||
TEAMGAME = 0x8
|
||||
GAMEMODE_SINGLEPLAYER = 0x1,
|
||||
GAMEMODE_COOPERATIVE = 0x2,
|
||||
GAMEMODE_DEATHMATCH = 0x4,
|
||||
GAMEMODE_TEAMGAME = 0x8
|
||||
};
|
||||
|
||||
enum AmmoModes
|
||||
|
@ -112,8 +135,15 @@ class BaseStatusBar native ui
|
|||
HUD_HorizCenter
|
||||
}
|
||||
|
||||
enum ENumFlags
|
||||
{
|
||||
FNF_FILLZEROS,
|
||||
FNF_WHENNOTZERO,
|
||||
}
|
||||
|
||||
const XHAIRSHRINKSIZE =(1./18);
|
||||
const XHAIRPICKUPSIZE = (2+XHAIRSHRINKSIZE);
|
||||
const POWERUPICONSIZE = 32;
|
||||
|
||||
|
||||
native int ST_X, ST_Y;
|
||||
|
@ -143,22 +173,25 @@ class BaseStatusBar native ui
|
|||
native virtual void Tick ();
|
||||
native virtual void Draw (int state, double TicFrac);
|
||||
native virtual void ScreenSizeChanged ();
|
||||
native virtual clearscope void ReceivedWeapon (Weapon weapn);
|
||||
|
||||
virtual void FlashItem (class<Inventory> itemtype) {}
|
||||
virtual void AttachToPlayer (PlayerInfo player) { CPlayer = player; }
|
||||
virtual void FlashCrosshair () { CrosshairSize = XHAIRPICKUPSIZE; }
|
||||
virtual void NewGame () {}
|
||||
virtual void ShowPop (int popnum) { ShowLog = (popnum == POP_Log && !ShowLog); }
|
||||
virtual clearscope void ReceivedWeapon (Weapon weapn) {}
|
||||
virtual bool MustDrawLog(int state) { return true; }
|
||||
virtual void SetMugShotState (String state_name, bool wait_till_done=false, bool reset=false) {}
|
||||
|
||||
native void RefreshBackground () const;
|
||||
native TextureID GetMugshot(PlayerInfo player, String default_face, int accuracy, int stateflags=MugShot.STANDARD);
|
||||
|
||||
// These functions are kept native solely for performance reasons. They get called repeatedly and can drag down performance easily if they get too slow.
|
||||
native Inventory ValidateInvFirst (int numVisible) const;
|
||||
native static TextureID, bool GetInventoryIcon(Inventory item, int flags);
|
||||
|
||||
native void DrawGraphic(TextureID texture, bool animate, Vector2 pos, double Alpha, bool translatable, bool dim, int imgAlign, int screenalign, bool alphamap, Vector2 box);
|
||||
native void DrawString(Font font, String string, Vector2 pos , double Alpha, int translation, int align, int screenalign, int spacing=0, bool monospaced = false, int shadowX=0, int shadowY=0, int wrapwidth = -1, int linespacing = 4);
|
||||
native static String FormatNumber(int number, int minsize, int maxsize, int format, String prefix = "");
|
||||
|
||||
|
||||
//============================================================================
|
||||
|
@ -243,10 +276,74 @@ class BaseStatusBar native ui
|
|||
if (w == null) return "";
|
||||
return w.GetTag();
|
||||
}
|
||||
|
||||
|
||||
// These cannot be done in ZScript.
|
||||
native String GetGlobalACSString(int index);
|
||||
native String GetGlobalACSArrayString(int arrayno, int index);
|
||||
native int GetGlobalACSValue(int index);
|
||||
native int GetGlobalACSArrayValue(int arrayno, int index);
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// Convenience functions to retrieve some numbers
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
int GetArmorAmount()
|
||||
{
|
||||
let armor = CPlayer.mo.FindInventory("BasicArmor");
|
||||
return armor? armor.Amount : 0;
|
||||
}
|
||||
|
||||
int GetMaxAmount(class<Inventory> item)
|
||||
{
|
||||
let it = CPlayer.mo.FindInventory(item);
|
||||
return it? it.MaxAmount : GetDefaultByType(item).MaxAmount;
|
||||
}
|
||||
|
||||
int GetArmorSavePercent()
|
||||
{
|
||||
double add = 0;
|
||||
let harmor = HexenArmor(CPlayer.mo.FindInventory("HexenArmor"));
|
||||
if(harmor != NULL)
|
||||
{
|
||||
add = harmor.Slots[0] + harmor.Slots[1] + harmor.Slots[2] + harmor.Slots[3] + harmor.Slots[4];
|
||||
}
|
||||
//Hexen counts basic armor also so we should too.
|
||||
let armor = BasicArmor(CPlayer.mo.FindInventory("BasicArmor"));
|
||||
if(armor != NULL)
|
||||
{
|
||||
add += armor.SavePercent * 100;
|
||||
}
|
||||
return int(add);
|
||||
}
|
||||
|
||||
// Note that this retrieves the value in tics, not seconds like the equivalent SBARINFO function.
|
||||
// The idea is to let the caller decide what to do with it instead of destroying accuracy here.
|
||||
int GetAirTime()
|
||||
{
|
||||
if(CPlayer.mo.waterlevel < 3)
|
||||
return level.airsupply;
|
||||
else
|
||||
return max(CPlayer.air_finished - level.time, 0);
|
||||
}
|
||||
|
||||
int GetSelectedInventoryAmount()
|
||||
{
|
||||
if(CPlayer.mo.InvSel != NULL) return CPlayer.mo.InvSel.Amount;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GetKeyCount()
|
||||
{
|
||||
int num = 0;
|
||||
for(Inventory item = CPlayer.mo.Inv;item != NULL;item = item.Inv)
|
||||
{
|
||||
if(item is "Key") num++;
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// various checker functions, based on SBARINFOs condition nodes.
|
||||
|
@ -261,10 +358,10 @@ class BaseStatusBar native ui
|
|||
|
||||
bool CheckGameMode(int ValidModes)
|
||||
{
|
||||
return (!multiplayer && (ValidModes & SINGLEPLAYER)) ||
|
||||
(deathmatch && (ValidModes & DEATHMATCH)) ||
|
||||
(multiplayer && !deathmatch && (ValidModes & COOPERATIVE)) ||
|
||||
(teamplay && (ValidModes & TEAMGAME));
|
||||
return (!multiplayer && (ValidModes & GAMEMODE_SINGLEPLAYER)) ||
|
||||
(deathmatch && (ValidModes & GAMEMODE_DEATHMATCH)) ||
|
||||
(multiplayer && !deathmatch && (ValidModes & GAMEMODE_COOPERATIVE)) ||
|
||||
(teamplay && (ValidModes & GAMEMODE_TEAMGAME));
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -416,6 +513,35 @@ class BaseStatusBar native ui
|
|||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// DrawPowerups
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
virtual void DrawPowerups ()
|
||||
{
|
||||
// The AltHUD specific adjustments have been removed here, because the AltHUD uses its own variant of this function
|
||||
// that can obey AltHUD rules - which this cannot.
|
||||
Vector2 pos = (-20, POWERUPICONSIZE * 5 / 4);
|
||||
double maxpos = screen.GetWidth() / 2;
|
||||
for (let item = CPlayer.mo.Inv; item != NULL; item = item.Inv)
|
||||
{
|
||||
let icon = item.GetPowerupIcon();
|
||||
if (icon.IsValid())
|
||||
{
|
||||
// Each icon gets a 32x32 block.
|
||||
DrawTexture(icon, pos, true, 1.0, ALIGN_TOP|ALIGN_RIGHT, (POWERUPICONSIZE, POWERUPICONSIZE), ALIGN_CENTER_BOTTOM);
|
||||
pos.x -= POWERUPICONSIZE;
|
||||
if (pos.x < -maxpos)
|
||||
{
|
||||
pos.x = -20;
|
||||
pos.y += POWERUPICONSIZE * 3 / 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// draw stuff
|
||||
|
@ -436,7 +562,7 @@ class BaseStatusBar native ui
|
|||
//
|
||||
//============================================================================
|
||||
|
||||
void DrawTexture(TextureID texture, Vector2 pos, bool animated = false, double alpha = 1.0, int screenalign = TOP|LEFT, Vector2 boxsize = (-1, -1), int itemAlign = TOP|LEFT, int flags = 0, Vector2 scale = (1., 1.) )
|
||||
void DrawTexture(TextureID texture, Vector2 pos, bool animated = false, double alpha = 1.0, int screenalign = ALIGN_TOP|ALIGN_LEFT, Vector2 boxsize = (-1, -1), int itemAlign = ALIGN_TOP|ALIGN_LEFT, int flags = 0, Vector2 scale = (1., 1.) )
|
||||
{
|
||||
if (!texture.IsValid()) return; // nothing to draw
|
||||
|
||||
|
@ -467,13 +593,12 @@ class BaseStatusBar native ui
|
|||
else scale1 = min(scale1, scale2);
|
||||
|
||||
boxsize = texsize * scale1;
|
||||
screenAlign = TOP|LEFT; // anything else makes no sense here.
|
||||
}
|
||||
else
|
||||
{
|
||||
boxsize = texsize;
|
||||
}
|
||||
DrawGraphic(texture, animated, pos, Alpha, !!(flags & DI_TRANSLATABLE), false, itemAlign, screenAlign, false, boxsize);
|
||||
DrawGraphic(texture, animated, pos, Alpha, !!(flags & DI_TRANSLATABLE), !!(flags & DI_DIM), itemAlign, screenAlign, false, boxsize);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -482,7 +607,7 @@ class BaseStatusBar native ui
|
|||
//
|
||||
//============================================================================
|
||||
|
||||
void DrawImage(String imagename, Vector2 pos, bool animated = false, double alpha = 1.0, int screenalign = TOP|LEFT, Vector2 boxsize = (-1, -1), int itemAlign = TOP|LEFT, int flags = 0, Vector2 scale = (1., 1.) )
|
||||
void DrawImage(String imagename, Vector2 pos, bool animated = false, double alpha = 1.0, int screenalign = ALIGN_TOP|ALIGN_LEFT, Vector2 boxsize = (-1, -1), int itemAlign = ALIGN_TOP|ALIGN_LEFT, int flags = 0, Vector2 scale = (1., 1.) )
|
||||
{
|
||||
let tex = TexMan.CheckForTexture(imagename, TexMan.TYPE_MiscPatch);
|
||||
DrawTexture(tex, pos, animated, screenalign, alpha, boxsize, itemAlign, flags, scale);
|
||||
|
@ -494,36 +619,36 @@ class BaseStatusBar native ui
|
|||
//
|
||||
//============================================================================
|
||||
|
||||
void DrawIcon(int icontype, Vector2 pos, bool animated = false, double alpha = 1.0, int screenalign = TOP|LEFT, Vector2 boxsize = (-1, -1), int itemAlign = TOP|LEFT, int flags = 0)
|
||||
void DrawIcon(int icontype, Vector2 pos, bool animated = false, double alpha = 1.0, int screenalign = ALIGN_TOP|ALIGN_LEFT, Vector2 boxsize = (-1, -1), int itemAlign = ALIGN_TOP|ALIGN_LEFT, int flags = 0)
|
||||
{
|
||||
TextureID texture;
|
||||
Vector2 applyscale = (1, 1);
|
||||
Inventory atype1, atype2;
|
||||
switch (icontype)
|
||||
{
|
||||
case PLAYERICON:
|
||||
case ITYPE_PLAYERICON:
|
||||
texture = CPlayer.mo.ScoreIcon;
|
||||
break;
|
||||
|
||||
case AMMO1:
|
||||
case AMMO2:
|
||||
case ITYPE_AMMO1:
|
||||
case ITYPE_AMMO2:
|
||||
[atype1, atype2] = GetCurrentAmmo();
|
||||
[texture, applyscale] = GetIcon(icontype == AMMO1? atype1 : atype2, flags, true);
|
||||
[texture, applyscale] = GetIcon(icontype == ITYPE_AMMO1? atype1 : atype2, flags, true);
|
||||
break;
|
||||
|
||||
case ARMOR:
|
||||
case ITYPE_ARMOR:
|
||||
[texture, applyscale] = GetIcon(CPlayer.mo.FindInventory("BasicArmor"), flags, false);
|
||||
break;
|
||||
|
||||
case WEAPONICON:
|
||||
case ITYPE_WEAPON:
|
||||
[texture, applyscale] = GetIcon(CPlayer.ReadyWeapon, flags, false);
|
||||
break;
|
||||
|
||||
case SIGIL:
|
||||
case ITYPE_SIGIL:
|
||||
[texture, applyscale] = GetIcon(CPlayer.mo.FindInventory("Sigil"), flags, false);
|
||||
break;
|
||||
|
||||
case SELECTEDINVENTORYICON:
|
||||
case ITYPE_SELECTEDINVENTORY:
|
||||
if (CPlayer.mo.InvSel != NULL)
|
||||
texture = CPlayer.mo.InvSel.Icon;
|
||||
break;
|
||||
|
@ -537,7 +662,7 @@ class BaseStatusBar native ui
|
|||
//
|
||||
//============================================================================
|
||||
|
||||
void DrawHexenArmor(int armortype, String image, Vector2 pos, bool animated = false, double alpha = 1.0, int screenalign = TOP|LEFT, Vector2 boxsize = (-1, -1), int itemAlign = TOP|LEFT, int flags = 0)
|
||||
void DrawHexenArmor(int armortype, String image, Vector2 pos, bool animated = false, double alpha = 1.0, int screenalign = ALIGN_TOP|ALIGN_LEFT, Vector2 boxsize = (-1, -1), int itemAlign = ALIGN_TOP|ALIGN_LEFT, int flags = 0)
|
||||
{
|
||||
let harmor = HexenArmor(statusBar.CPlayer.mo.FindInventory("HexenArmor"));
|
||||
if (harmor != NULL)
|
||||
|
@ -561,7 +686,7 @@ class BaseStatusBar native ui
|
|||
//
|
||||
//============================================================================
|
||||
|
||||
void DrawInventoryIcon(class<Inventory> item, String image, Vector2 pos, bool animated = false, double alpha = 1.0, int screenalign = TOP|LEFT, Vector2 boxsize = (-1, -1), int itemAlign = TOP|LEFT, int flags = 0)
|
||||
void DrawInventoryIcon(class<Inventory> item, String image, Vector2 pos, bool animated = false, double alpha = 1.0, int screenalign = ALIGN_TOP|ALIGN_LEFT, Vector2 boxsize = (-1, -1), int itemAlign = ALIGN_TOP|ALIGN_LEFT, int flags = 0)
|
||||
{
|
||||
let texture = GetDefaultByType(item).Icon;
|
||||
if (texture.IsValid())
|
||||
|
@ -569,4 +694,85 @@ class BaseStatusBar native ui
|
|||
DrawTexture(texture, pos, animated, screenalign, alpha, boxsize, itemAlign, flags);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// a generic value interpolator for status bar elements that can change
|
||||
// gradually to their new value.
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
class LinearValueInterpolator : Object
|
||||
{
|
||||
int mCurrentValue;
|
||||
int mMaxChange;
|
||||
|
||||
static LinearValueInterpolator Create(int startval, int maxchange)
|
||||
{
|
||||
let v = new("LinearValueInterpolator");
|
||||
v.mCurrentValue = startval;
|
||||
v.mMaxChange = maxchange;
|
||||
return v;
|
||||
}
|
||||
|
||||
// This must be called peroiodically in the status bar's Tick function.
|
||||
// Do not call this in the Draw function because that may skip some frames!
|
||||
void Update(int destvalue)
|
||||
{
|
||||
if (mCurrentValue > destvalue)
|
||||
{
|
||||
mCurrentValue = max(destvalue, mCurrentValue - mMaxChange);
|
||||
}
|
||||
else
|
||||
{
|
||||
mCurrentValue = min(destvalue, mCurrentValue + mMaxChange);
|
||||
}
|
||||
}
|
||||
|
||||
// This must be called in the draw function to retrieve the value for output.
|
||||
int GetValue()
|
||||
{
|
||||
return mCurrentValue;
|
||||
}
|
||||
}
|
||||
|
||||
class DynamicValueInterpolator : Object
|
||||
{
|
||||
int mCurrentValue;
|
||||
int mMinChange;
|
||||
double mChangeFactor;
|
||||
|
||||
|
||||
static DynamicValueInterpolator Create(int startval, double changefactor, int minchange)
|
||||
{
|
||||
let v = new("DynamicValueInterpolator");
|
||||
v.mCurrentValue = startval;
|
||||
v.mMinChange = minchange;
|
||||
v.mChangeFactor = changefactor;
|
||||
return v;
|
||||
}
|
||||
|
||||
// This must be called peroiodically in the status bar's Tick function.
|
||||
// Do not call this in the Draw function because that may skip some frames!
|
||||
void Update(int destvalue)
|
||||
{
|
||||
int diff = int(max(abs(destvalue - mCurrentValue) * mChangeFactor, mMinChange));
|
||||
if (mCurrentValue > destvalue)
|
||||
{
|
||||
mCurrentValue = max(destvalue, mCurrentValue - diff);
|
||||
}
|
||||
else
|
||||
{
|
||||
mCurrentValue = min(destvalue, mCurrentValue + diff);
|
||||
}
|
||||
}
|
||||
|
||||
// This must be called in the draw function to retrieve the value for output.
|
||||
int GetValue()
|
||||
{
|
||||
return mCurrentValue;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -48,7 +48,6 @@ class StrifeStatusBar : BaseStatusBar
|
|||
imgARM1,
|
||||
imgARM2,
|
||||
imgNEGATIVE,
|
||||
imgINumbers = imgFONG0,
|
||||
};
|
||||
|
||||
TextureID Images[imgNEGATIVE + 1];
|
||||
|
@ -79,18 +78,21 @@ class StrifeStatusBar : BaseStatusBar
|
|||
|
||||
if (state == HUD_StatusBar)
|
||||
{
|
||||
fullscreenoffsets = false;
|
||||
DrawMainBar (TicFrac);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (state == HUD_Fullscreen)
|
||||
{
|
||||
fullscreenoffsets = true;
|
||||
DrawFullScreenStuff ();
|
||||
}
|
||||
|
||||
// Draw pop screen (log, keys, and status)
|
||||
if (CurrentPop != POP_None && PopHeight < 0)
|
||||
{
|
||||
fullscreenoffsets = false;
|
||||
DrawPopScreen (screen.GetHeight(), TicFrac);
|
||||
}
|
||||
}
|
||||
|
@ -302,11 +304,11 @@ class StrifeStatusBar : BaseStatusBar
|
|||
DrawPopScreen (Scaled ? (ST_Y - 8) * screen.GetHeight() / 200 : ST_Y - 8, TicFrac);
|
||||
}
|
||||
|
||||
DrawImage (Images[imgINVBACK], 0, 0);
|
||||
DrawImage (Images[imgINVTOP], 0, -8);
|
||||
DrawTexture(Images[imgINVBACK], (0, 0), true, 1.0, itemAlign:ALIGN_OFFSETS);
|
||||
DrawTexture(Images[imgINVTOP], (0, -8), true, 1.0, itemAlign:ALIGN_OFFSETS);
|
||||
|
||||
// Health
|
||||
DrINumber (CPlayer.health, 79, -6, imgFONG0);
|
||||
DrawString("Indexfont_Strife_Green", FormatNumber(CPlayer.health, 3, 5, 0), (86, -6), 1.0, Font.CR_UNTRANSLATED, TEXT_RIGHT, 0, 7, true, 1, 1);
|
||||
int points;
|
||||
if (CPlayer.cheats & CF_GODMODE)
|
||||
{
|
||||
|
@ -323,8 +325,8 @@ class StrifeStatusBar : BaseStatusBar
|
|||
item = CPlayer.mo.FindInventory('BasicArmor');
|
||||
if (item != NULL && item.Amount > 0)
|
||||
{
|
||||
DrawImage (item.Icon, 2, 9);
|
||||
DrINumber (item.Amount, 27, 23, imgFONY0);
|
||||
DrawTexture(item.Icon, (2, 9), true, 1.0, itemAlign:ALIGN_OFFSETS);
|
||||
DrawString("Indexfont_Strife_Yellow", FormatNumber(item.Amount, 3, 5, 0), (34, 23), 1.0, Font.CR_UNTRANSLATED, TEXT_RIGHT, 0, 7, true, 1, 1);
|
||||
}
|
||||
|
||||
// Ammo
|
||||
|
@ -334,15 +336,15 @@ class StrifeStatusBar : BaseStatusBar
|
|||
[ammo1, ammo2, ammocount1, ammocount2] = GetCurrentAmmo ();
|
||||
if (ammo1 != NULL)
|
||||
{
|
||||
DrINumber (ammo1.Amount, 311, -6, imgFONG0);
|
||||
DrawImage (ammo1.Icon, 290, 13);
|
||||
DrawString("Indexfont_Strife_Green", FormatNumber(ammo1.Amount, 3, 5, 0), (318, -6), 1.0, Font.CR_UNTRANSLATED, TEXT_RIGHT, 0, 7, true, 1, 1);
|
||||
DrawTexture (ammo1.Icon, (290, 13), true, 1.0, itemAlign:ALIGN_OFFSETS);
|
||||
}
|
||||
|
||||
// Sigil
|
||||
item = CPlayer.mo.FindInventory('Sigil');
|
||||
if (item != NULL)
|
||||
{
|
||||
DrawImage (item.Icon, 253, 7);
|
||||
DrawTexture (item.Icon, (253, 7), true, 1.0, itemAlign:ALIGN_OFFSETS);
|
||||
}
|
||||
|
||||
// Inventory
|
||||
|
@ -353,33 +355,30 @@ class StrifeStatusBar : BaseStatusBar
|
|||
{
|
||||
if (item == CPlayer.mo.InvSel)
|
||||
{
|
||||
screen.DrawTexture (Images[CursorImage], true,
|
||||
42 + 35*i + ST_X, 12 + ST_Y,
|
||||
DTA_Bottom320x200, Scaled,
|
||||
DTA_Alpha, 1. - ItemFlash);
|
||||
DrawTexture (item.Icon, (42 + 35*i, 12), true, 1. - ItemFlash, itemAlign:ALIGN_OFFSETS, item.Amount <= 0? DI_DIM : 0);
|
||||
}
|
||||
if (item.Icon.isValid())
|
||||
{
|
||||
DrawDimImage (item.Icon, 48 + 35*i, 14, item.Amount <= 0);
|
||||
DrawTexture (item.Icon, (48 + 35*i, 14), true, 1.0, itemAlign:ALIGN_OFFSETS, item.Amount <= 0? DI_DIM : 0);
|
||||
}
|
||||
DrINumber (item.Amount, 74 + 35*i, 23, imgFONY0);
|
||||
DrawString("Indexfont_Strife_Yellow", FormatNumber(item.Amount, 3, 5, 0), (81 + 35*i, 23), 1.0, Font.CR_UNTRANSLATED, TEXT_RIGHT, 0, 7, true, 1, 1);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
protected void DrawFullScreenStuff ()
|
||||
{
|
||||
fullscreenoffsets = true;
|
||||
// Draw health
|
||||
DrINumberOuter (CPlayer.health, 4, -10, false, 7);
|
||||
DrawTexture(Images[imgMEDI], (14, -17), false, 1.0, BOTTOM|LEFT, itemalign: BOTTOM|HCENTER);
|
||||
|
||||
DrawString("Indexfont_Strife_Green", FormatNumber(CPlayer.health, 3, 0, 0), (4, -10), 1., (CPlayer.health < CPlayer.mo.RunHealth)? Font.CR_BRICK : Font.CR_UNTRANSLATED, TEXT_LEFT, ALIGN_LEFT|ALIGN_BOTTOM, 7, true, 1, 1);
|
||||
DrawTexture(Images[imgMEDI], (14, -17), false, 1.0, ALIGN_BOTTOM|ALIGN_LEFT, itemalign: ALIGN_BOTTOM|ALIGN_HCENTER);
|
||||
|
||||
// Draw armor
|
||||
let armor = CPlayer.mo.FindInventory('BasicArmor');
|
||||
if (armor != NULL && armor.Amount != 0)
|
||||
{
|
||||
DrINumberOuter (armor.Amount, 35, -10, false, 7);
|
||||
DrawTexture(armor.Icon, (45, -17), false, 1.0, BOTTOM|LEFT, itemalign: BOTTOM|HCENTER);
|
||||
DrawString("Indexfont_Strife_Yellow", FormatNumber(armor.Amount, 3, 0, 0), (35, -10), 1., Font.CR_UNTRANSLATED, TEXT_LEFT, ALIGN_LEFT|ALIGN_BOTTOM, 7, true, 1, 1);
|
||||
DrawTexture(armor.Icon, (45, -17), false, 1.0, ALIGN_BOTTOM|ALIGN_LEFT, itemalign: ALIGN_BOTTOM|ALIGN_HCENTER);
|
||||
}
|
||||
|
||||
// Draw ammo
|
||||
|
@ -390,19 +389,19 @@ class StrifeStatusBar : BaseStatusBar
|
|||
if (ammo1 != NULL)
|
||||
{
|
||||
// Draw primary ammo in the bottom-right corner
|
||||
DrINumberOuter (ammo1.Amount, -23, -10, false, 7);
|
||||
DrawTexture(ammo1.Icon, (-14, -17), false, 1.0, BOTTOM|RIGHT, itemalign: BOTTOM|HCENTER);
|
||||
DrawString("Indexfont_Strife_Green", FormatNumber(ammo1.Amount, 3, 0, 0), (-23, -10), 1., Font.CR_UNTRANSLATED, TEXT_LEFT, ALIGN_RIGHT|ALIGN_BOTTOM, 7, true, 1, 1);
|
||||
DrawTexture(ammo1.Icon, (-14, -17), false, 1.0, ALIGN_BOTTOM|ALIGN_RIGHT, itemalign: ALIGN_BOTTOM|ALIGN_HCENTER);
|
||||
if (ammo2 != NULL && ammo1!=ammo2)
|
||||
{
|
||||
// Draw secondary ammo just above the primary ammo
|
||||
DrINumberOuter (ammo2.Amount, -23, -48, false, 7);
|
||||
DrawTexture(ammo1.Icon, (-14, -55), false, 1.0, BOTTOM|RIGHT, itemalign: BOTTOM|HCENTER);
|
||||
DrawString("Indexfont_Strife_Green", FormatNumber(ammo1.Amount, 3, 0, 0), (-23, -48), 1., Font.CR_UNTRANSLATED, TEXT_LEFT, ALIGN_RIGHT|ALIGN_BOTTOM, 7, true, 1, 1);
|
||||
DrawTexture(ammo1.Icon, (-14, -55), false, 1.0, ALIGN_BOTTOM|ALIGN_RIGHT, itemalign: ALIGN_BOTTOM|ALIGN_HCENTER);
|
||||
}
|
||||
}
|
||||
|
||||
if (deathmatch)
|
||||
{ // Draw frags (in DM)
|
||||
DrBNumberOuterFont (CPlayer.fragcount, -44, 1);
|
||||
DrawString("BigFont", FormatNumber(CPlayer.FragCount, 3, 0, 0), (-44, 1), 1., Font.CR_UNTRANSLATED, TEXT_LEFT, ALIGN_RIGHT|ALIGN_TOP, 0, false, 2, 2);
|
||||
}
|
||||
|
||||
// Draw inventory
|
||||
|
@ -412,18 +411,10 @@ class StrifeStatusBar : BaseStatusBar
|
|||
{
|
||||
if (ItemFlash > 0)
|
||||
{
|
||||
vector2 size = TexMan.GetScaledSize(Images[CursorImage]);
|
||||
screen.DrawTexture (Images[CursorImage], true, -28, -15,
|
||||
DTA_HUDRules, HUD_Normal,
|
||||
DTA_LeftOffsetF, size.X,
|
||||
DTA_TopOffsetF, size.Y,
|
||||
DTA_Alpha, ItemFlash);
|
||||
DrawTexture(Images[CursorImage], (-28, -15), true, 1.0, ALIGN_BOTTOM|ALIGN_RIGHT, ItemAlign:ALIGN_BOTTOM|ALIGN_RIGHT);
|
||||
}
|
||||
DrINumberOuter (CPlayer.mo.InvSel.Amount, -51, -10, false, 7);
|
||||
screen.DrawTexture (CPlayer.mo.InvSel.Icon, true, -42, -17,
|
||||
DTA_HUDRules, HUD_Normal,
|
||||
DTA_CenterBottomOffset, true,
|
||||
DTA_ColorOverlay, CPlayer.mo.InvSel.Amount > 0 ? 0 : Color(170, 0, 0, 0));
|
||||
DrawString("Indexfont_Strife_Yellow", FormatNumber(CPlayer.mo.InvSel.Amount, 3, 5, 0), (-23, -10), 1.0, Font.CR_UNTRANSLATED, TEXT_RIGHT, ALIGN_BOTTOM|ALIGN_RIGHT, 7, true, 1, 1);
|
||||
DrawTexture(CPlayer.mo.InvSel.Icon, (-42, -17), true, 1.0, ALIGN_BOTTOM|ALIGN_RIGHT, ItemAlign:ALIGN_BOTTOM|ALIGN_HCENTER, CPlayer.mo.InvSel.Amount > 0 ? 0 : DI_DIM);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -431,23 +422,20 @@ class StrifeStatusBar : BaseStatusBar
|
|||
CPlayer.mo.InvFirst = ValidateInvFirst (6);
|
||||
int i = 0;
|
||||
Inventory item;
|
||||
Vector2 box = TexMan.GetScaledSize(Images[CursorImage]) - (4, 4); // Fit oversized icons into the box.
|
||||
if (CPlayer.mo.InvFirst != NULL)
|
||||
{
|
||||
for (item = CPlayer.mo.InvFirst; item != NULL && i < 6; item = item.NextInv())
|
||||
{
|
||||
if (item == CPlayer.mo.InvSel)
|
||||
{
|
||||
screen.DrawTexture (Images[CursorImage], true, -100+i*35, -21,
|
||||
DTA_HUDRules, HUD_HorizCenter,
|
||||
DTA_Alpha, 0.75);
|
||||
DrawTexture(Images[CursorImage], (-90+i*35, -3), true, 0.75, ALIGN_CENTER_BOTTOM, ItemAlign:ALIGN_CENTER_BOTTOM);
|
||||
}
|
||||
if (item.Icon.isValid())
|
||||
{
|
||||
screen.DrawTexture (item.Icon, true, -94 + i*35, -19,
|
||||
DTA_HUDRules, HUD_HorizCenter,
|
||||
DTA_ColorOverlay, CPlayer.mo.InvSel.Amount > 0 ? 0 : Color(170, 0, 0, 0));
|
||||
DrawTexture(item.Icon, (-90+i*35, -5), true, 0.75, ALIGN_CENTER_BOTTOM, box, ALIGN_CENTER_BOTTOM, CPlayer.mo.InvSel.Amount > 0 ? 0 : DI_DIM);
|
||||
}
|
||||
DrINumberOuter (item.Amount, -89 + i*35, -10, true, 7);
|
||||
DrawString("Indexfont_Strife_Yellow", FormatNumber(item.Amount, 3, 5, 0), (-65 + i*35, -8), 1.0, Font.CR_UNTRANSLATED, TEXT_RIGHT, ALIGN_CENTER_BOTTOM, 7, true, 1, 1);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
@ -480,14 +468,8 @@ class StrifeStatusBar : BaseStatusBar
|
|||
{
|
||||
case POP_Log:
|
||||
{
|
||||
int seconds = Thinker.Tics2Seconds(level.time);
|
||||
// Draw the latest log message.
|
||||
buff = String.Format("%02d:%02d:%02d",
|
||||
seconds / 3600,
|
||||
(seconds % 3600) / 60,
|
||||
(seconds) % 60);
|
||||
|
||||
screen.DrawText(SmallFont2, Font.CR_UNTRANSLATED, left + 210 * xscale, top + 8 * yscale, buff,
|
||||
screen.DrawText(SmallFont2, Font.CR_UNTRANSLATED, left + 210 * xscale, top + 8 * yscale, Level.TimeFormatted(),
|
||||
DTA_CleanNoMove, true);
|
||||
|
||||
if (CPlayer.LogText.Length() > 0)
|
||||
|
@ -640,25 +622,6 @@ class StrifeStatusBar : BaseStatusBar
|
|||
}
|
||||
}
|
||||
|
||||
void DrINumber (int val, int x, int y, int imgBase) const
|
||||
{
|
||||
x -= 7;
|
||||
|
||||
if (val == 0)
|
||||
{
|
||||
DrawImage (Images[imgBase], x, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
while (val != 0)
|
||||
{
|
||||
DrawImage (Images[imgBase+val%10], x, y);
|
||||
val /= 10;
|
||||
x -= 7;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DrINumber2 (int val, int x, int y, int width, int imgBase) const
|
||||
{
|
||||
x -= width;
|
||||
|
@ -677,183 +640,5 @@ class StrifeStatusBar : BaseStatusBar
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// PROC DrINumberOuter
|
||||
//
|
||||
// Draws a number outside the status bar, possibly scaled.
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void DrINumberOuter(int val, int x, int y, bool center, int w) const
|
||||
{
|
||||
bool negative = false;
|
||||
|
||||
x += w * 2;
|
||||
if (val < 0)
|
||||
{
|
||||
negative = true;
|
||||
val = -val;
|
||||
}
|
||||
else if (val == 0)
|
||||
{
|
||||
screen.DrawTexture(Images[imgINumbers], true, x + 1, y + 1,
|
||||
DTA_FillColor, 0, DTA_Alpha, HR_SHADOW,
|
||||
DTA_HUDRules, center ? HUD_HorizCenter : HUD_Normal);
|
||||
screen.DrawTexture(Images[imgINumbers], true, x, y,
|
||||
DTA_HUDRules, center ? HUD_HorizCenter : HUD_Normal);
|
||||
return;
|
||||
}
|
||||
|
||||
int oval = val;
|
||||
int ox = x;
|
||||
|
||||
// First the shadow
|
||||
while (val != 0)
|
||||
{
|
||||
screen.DrawTexture(Images[imgINumbers + val % 10], true, x + 1, y + 1,
|
||||
DTA_FillColor, 0, DTA_Alpha, HR_SHADOW,
|
||||
DTA_HUDRules, center ? HUD_HorizCenter : HUD_Normal);
|
||||
x -= w;
|
||||
val /= 10;
|
||||
}
|
||||
if (negative)
|
||||
{
|
||||
screen.DrawTexture(Images[imgNEGATIVE], true, x + 1, y + 1,
|
||||
DTA_FillColor, 0, DTA_Alpha, HR_SHADOW,
|
||||
DTA_HUDRules, center ? HUD_HorizCenter : HUD_Normal);
|
||||
}
|
||||
|
||||
// Then the real deal
|
||||
val = oval;
|
||||
x = ox;
|
||||
while (val != 0)
|
||||
{
|
||||
screen.DrawTexture(Images[imgINumbers + val % 10], true, x, y,
|
||||
DTA_HUDRules, center ? HUD_HorizCenter : HUD_Normal);
|
||||
x -= w;
|
||||
val /= 10;
|
||||
}
|
||||
if (negative)
|
||||
{
|
||||
screen.DrawTexture(Images[imgNEGATIVE], true, x, y,
|
||||
DTA_HUDRules, center ? HUD_HorizCenter : HUD_Normal);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// PROC DrBNumberOuter
|
||||
//
|
||||
// Draws a three digit number using the real big font outside the status bar.
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void DrBNumberOuterFont(int val, int x, int y, int size = 3) const
|
||||
{
|
||||
int v;
|
||||
bool negative = false;
|
||||
TextureID pic;
|
||||
|
||||
int w = BigFont.GetCharWidth("0");
|
||||
int ww = w;
|
||||
|
||||
if (w > 1)
|
||||
{
|
||||
w--;
|
||||
}
|
||||
int xpos = x + w / 2 + (size - 1)*w;
|
||||
|
||||
if (val == 0)
|
||||
{
|
||||
screen.DrawChar(BigFont, Font.CR_UNTRANSLATED, xpos - v / 2 + 2, y + 2, "0",
|
||||
DTA_HUDRules, HUD_Normal,
|
||||
DTA_Alpha, HR_SHADOW,
|
||||
DTA_FillColor, 0);
|
||||
screen.DrawChar(BigFont, Font.CR_UNTRANSLATED, xpos - v / 2, y, "0",
|
||||
DTA_HUDRules, HUD_Normal);
|
||||
return;
|
||||
}
|
||||
else if (val < 0)
|
||||
{
|
||||
negative = true;
|
||||
val = -val;
|
||||
}
|
||||
|
||||
int oval = val;
|
||||
int oxpos = xpos;
|
||||
|
||||
// First the shadow
|
||||
while (val != 0)
|
||||
{
|
||||
v = BigFont.GetCharWidth(int("0") + val % 10);
|
||||
screen.DrawChar(BigFont, Font.CR_UNTRANSLATED, xpos - v / 2 + 2, y + 2,
|
||||
DTA_HUDRules, HUD_Normal,
|
||||
DTA_Alpha, HR_SHADOW,
|
||||
DTA_FillColor, 0);
|
||||
val /= 10;
|
||||
xpos -= w;
|
||||
}
|
||||
if (negative)
|
||||
{
|
||||
v = BigFont.GetCharWidth("-");
|
||||
screen.DrawChar(BigFont, Font.CR_UNTRANSLATED, xpos - v / 2 + 2, y + 2, "-",
|
||||
DTA_HUDRules, HUD_Normal,
|
||||
DTA_Alpha, HR_SHADOW,
|
||||
DTA_FillColor, 0);
|
||||
}
|
||||
|
||||
// Then the foreground number
|
||||
val = oval;
|
||||
xpos = oxpos;
|
||||
while (val != 0)
|
||||
{
|
||||
v = BigFont.GetCharWidth(int("0") + val % 10);
|
||||
screen.DrawChar(BigFont, Font.CR_UNTRANSLATED, xpos - v / 2, y, "0", DTA_HUDRules, HUD_Normal);
|
||||
val /= 10;
|
||||
xpos -= w;
|
||||
}
|
||||
if (negative)
|
||||
{
|
||||
v = BigFont.GetCharWidth("-");
|
||||
screen.DrawChar(BigFont, Font.CR_UNTRANSLATED, xpos - v / 2, y, "-", DTA_HUDRules, HUD_Normal);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// PROC DrawImage
|
||||
//
|
||||
// Draws an image with the status bar's upper-left corner as the origin.
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void DrawImage(TextureID img, int x, int y) const
|
||||
{
|
||||
if (img.IsValid())
|
||||
{
|
||||
screen.DrawTexture(img, true, x + ST_X, y + ST_Y, DTA_Bottom320x200, Scaled);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// PROC DrawImage
|
||||
//
|
||||
// Draws an optionally dimmed image with the status bar's upper-left corner
|
||||
// as the origin.
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void DrawDimImage(TextureID img, int x, int y, bool dimmed) const
|
||||
{
|
||||
if (img.IsValid())
|
||||
{
|
||||
screen.DrawTexture(img, true, x + ST_X, y + ST_Y, DTA_ColorOverlay, dimmed ? Color(170, 0, 0, 0) : 0, DTA_Bottom320x200, Scaled);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue