completely redid the active powerup drawer for the HUD

- replaced Inventory.DrawPowerup with a GetPowerupIcon method so that the calling code can handle the drawing and apply its own rules. This was a major design flaw of allowing the inventory items to handle the drawing themselves, because they were unable to adjust to different HUD frontends. Note that any mod that overrides DrawPowerup will not draw any icon that expects to be handled that way!
- the alternative HUD now has its own, separate drawer that obeys the AltHUD's rules, and not the ones of the normal fullscreen HUD.
- the standard drawer has been scriptified as a virtual function.
- Both drawers now handle positioning of the icon inside its assigned box themselves instead of trusting the powerup item to do it correctly.
- DTA_HUDRules and Screen.DrawHUDTexture are to be considered deprecated because both do not integrate into the redesigned HUD code.
This commit is contained in:
Christoph Oelckers 2017-03-24 22:57:44 +01:00
parent 321e2da979
commit b17b8d32ad
8 changed files with 143 additions and 98 deletions

View File

@ -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
{

View File

@ -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();

View File

@ -1052,7 +1052,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 +1079,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

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -126,6 +126,7 @@ class BaseStatusBar native ui
const XHAIRSHRINKSIZE =(1./18);
const XHAIRPICKUPSIZE = (2+XHAIRSHRINKSIZE);
const POWERUPICONSIZE = 32;
native int ST_X, ST_Y;
@ -494,6 +495,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
@ -726,3 +756,4 @@ class DynamicValueInterpolator : Object
return mCurrentValue;
}
}