mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-10 23:01:50 +00:00
This commit is contained in:
commit
9da596cd9c
82 changed files with 3514 additions and 1619 deletions
|
@ -1190,6 +1190,7 @@ set (PCH_SOURCES
|
|||
textures/rawpagetexture.cpp
|
||||
textures/emptytexture.cpp
|
||||
textures/backdroptexture.cpp
|
||||
textures/shadertexture.cpp
|
||||
textures/texture.cpp
|
||||
textures/texturemanager.cpp
|
||||
textures/tgatexture.cpp
|
||||
|
|
|
@ -734,6 +734,8 @@ static int grid = 0;
|
|||
|
||||
bool automapactive = false;
|
||||
|
||||
DEFINE_GLOBAL(automapactive);
|
||||
|
||||
// location of window on screen
|
||||
static int f_x;
|
||||
static int f_y;
|
||||
|
|
|
@ -2568,14 +2568,8 @@ void D_DoomMain (void)
|
|||
|
||||
P_SetupWeapons_ntohton();
|
||||
|
||||
//SBarInfo support.
|
||||
// This needs special checking because there are two distinct methods of defining status bars.
|
||||
// SBARINFO should only be picked if it is the most recently defined one, so that both
|
||||
// methods can override each other if loaded in sequence.
|
||||
if (gameinfo.statusbarfile > gameinfo.statusbarclassfile)
|
||||
{
|
||||
SBarInfo::Load();
|
||||
}
|
||||
//SBarInfo support. Note that the first SBARINFO lump contains the mugshot definition so it even needs to be read when a regular status bar is being used.
|
||||
SBarInfo::Load();
|
||||
HUD_InitHud();
|
||||
|
||||
if (!batchrun)
|
||||
|
|
|
@ -532,6 +532,8 @@ public:
|
|||
|
||||
// [Nash] set player FOV
|
||||
void SetFOV(float fov);
|
||||
bool HasWeaponsInSlot(int slot) const;
|
||||
bool Resurrect();
|
||||
};
|
||||
|
||||
// Bookkeeping on players - state.
|
||||
|
|
|
@ -234,8 +234,6 @@ FString shotfile;
|
|||
AActor* bodyque[BODYQUESIZE];
|
||||
int bodyqueslot;
|
||||
|
||||
void R_ExecuteSetViewSize (FViewWindow &viewwindow);
|
||||
|
||||
FString savename;
|
||||
FString BackupSaveName;
|
||||
|
||||
|
|
|
@ -464,7 +464,7 @@ void P_DeinitKeyMessages()
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
bool P_CheckKeys (AActor *owner, int keynum, bool remote)
|
||||
bool P_CheckKeys (AActor *owner, int keynum, bool remote, bool quiet)
|
||||
{
|
||||
const char *failtext = NULL;
|
||||
FSoundID *failsound;
|
||||
|
@ -479,6 +479,7 @@ bool P_CheckKeys (AActor *owner, int keynum, bool remote)
|
|||
|
||||
if (!locks[keynum])
|
||||
{
|
||||
if (quiet) return false;
|
||||
if (keynum == 103 && (gameinfo.flags & GI_SHAREWARE))
|
||||
failtext = "$TXT_RETAIL_ONLY";
|
||||
else
|
||||
|
@ -490,6 +491,7 @@ bool P_CheckKeys (AActor *owner, int keynum, bool remote)
|
|||
else
|
||||
{
|
||||
if (locks[keynum]->check(owner)) return true;
|
||||
if (quiet) return false;
|
||||
failtext = remote? locks[keynum]->RemoteMsg : locks[keynum]->Message;
|
||||
failsound = &locks[keynum]->locksound[0];
|
||||
numfailsounds = locks[keynum]->locksound.Size();
|
||||
|
@ -519,6 +521,15 @@ bool P_CheckKeys (AActor *owner, int keynum, bool remote)
|
|||
return false;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, CheckKeys)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_INT(locknum);
|
||||
PARAM_BOOL(remote);
|
||||
PARAM_BOOL_DEF(quiet);
|
||||
ACTION_RETURN_BOOL(P_CheckKeys(self, locknum, remote, quiet));
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// These functions can be used to get color information for
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
class AActor;
|
||||
class AInventory;
|
||||
|
||||
bool P_CheckKeys (AActor *owner, int keynum, bool remote);
|
||||
bool P_CheckKeys (AActor *owner, int keynum, bool remote, bool quiet = false);
|
||||
void P_InitKeyMessages ();
|
||||
void P_DeinitKeyMessages ();
|
||||
int P_GetMapColorForLock (int lock);
|
||||
|
|
|
@ -1028,7 +1028,10 @@ void G_DoLoadLevel (int position, bool autosave)
|
|||
{
|
||||
players[ii].camera = players[ii].mo;
|
||||
}
|
||||
E_PlayerEntered(ii, finishstate == FINISH_SameHub);
|
||||
if (!savegamerestore)
|
||||
{
|
||||
E_PlayerEntered(ii, finishstate == FINISH_SameHub);
|
||||
}
|
||||
// ENTER scripts are being handled when the player gets spawned, this cannot be changed due to its effect on voodoo dolls.
|
||||
if (level.FromSnapshot && !savegamerestore) FBehavior::StaticStartTypedScripts(SCRIPT_Return, players[ii].mo, true);
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ enum
|
|||
#define MF4_DONTLIGHTSELF MF4_SEESDAGGERS
|
||||
#define MF4_ATTENUATE MF4_INCOMBAT
|
||||
#define MF4_NOSHADOWMAP MF4_STANDSTILL
|
||||
#define MF4_DONTLIGHTACTORS MF4_EXTREMEDEATH
|
||||
|
||||
enum ELightType
|
||||
{
|
||||
|
|
|
@ -127,6 +127,7 @@ public:
|
|||
void SetDontLightSelf(bool add) { m_dontlightself = add; }
|
||||
void SetAttenuate(bool on) { m_attenuate = on; }
|
||||
void SetHalo(bool halo) { m_halo = halo; }
|
||||
void SetDontLightActors(bool on) { m_dontlightactors = on; }
|
||||
|
||||
void OrderIntensities()
|
||||
{
|
||||
|
@ -144,7 +145,7 @@ protected:
|
|||
DVector3 m_Pos;
|
||||
ELightType m_type;
|
||||
int8_t m_attenuate;
|
||||
bool m_subtractive, m_additive, m_halo, m_dontlightself;
|
||||
bool m_subtractive, m_additive, m_halo, m_dontlightself, m_dontlightactors;
|
||||
bool m_swapped = false;
|
||||
};
|
||||
|
||||
|
@ -187,6 +188,7 @@ void FLightDefaults::ApplyProperties(ADynamicLight * light) const
|
|||
if (m_subtractive) light->flags4 |= MF4_SUBTRACTIVE;
|
||||
if (m_additive) light->flags4 |= MF4_ADDITIVE;
|
||||
if (m_dontlightself) light->flags4 |= MF4_DONTLIGHTSELF;
|
||||
if (m_dontlightactors) light->flags4 |= MF4_DONTLIGHTACTORS;
|
||||
light->m_tickCount = 0;
|
||||
if (m_type == PulseLight)
|
||||
{
|
||||
|
@ -236,6 +238,7 @@ static const char *LightTags[]=
|
|||
"halo",
|
||||
"dontlightself",
|
||||
"attenuate",
|
||||
"dontlightactors",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -256,7 +259,8 @@ enum {
|
|||
LIGHTTAG_ADDITIVE,
|
||||
LIGHTTAG_HALO,
|
||||
LIGHTTAG_DONTLIGHTSELF,
|
||||
LIGHTTAG_ATTENUATE
|
||||
LIGHTTAG_ATTENUATE,
|
||||
LIGHTTAG_DONTLIGHTACTORS,
|
||||
};
|
||||
|
||||
|
||||
|
@ -394,6 +398,9 @@ static void ParsePointLight(FScanner &sc)
|
|||
case LIGHTTAG_ATTENUATE:
|
||||
defaults->SetAttenuate(ParseInt(sc) != 0);
|
||||
break;
|
||||
case LIGHTTAG_DONTLIGHTACTORS:
|
||||
defaults->SetDontLightActors(ParseInt(sc) != 0);
|
||||
break;
|
||||
default:
|
||||
sc.ScriptError("Unknown tag: %s\n", sc.String);
|
||||
}
|
||||
|
@ -476,6 +483,9 @@ static void ParsePulseLight(FScanner &sc)
|
|||
case LIGHTTAG_ATTENUATE:
|
||||
defaults->SetAttenuate(ParseInt(sc) != 0);
|
||||
break;
|
||||
case LIGHTTAG_DONTLIGHTACTORS:
|
||||
defaults->SetDontLightActors(ParseInt(sc) != 0);
|
||||
break;
|
||||
default:
|
||||
sc.ScriptError("Unknown tag: %s\n", sc.String);
|
||||
}
|
||||
|
@ -560,6 +570,9 @@ void ParseFlickerLight(FScanner &sc)
|
|||
case LIGHTTAG_ATTENUATE:
|
||||
defaults->SetAttenuate(ParseInt(sc) != 0);
|
||||
break;
|
||||
case LIGHTTAG_DONTLIGHTACTORS:
|
||||
defaults->SetDontLightActors(ParseInt(sc) != 0);
|
||||
break;
|
||||
default:
|
||||
sc.ScriptError("Unknown tag: %s\n", sc.String);
|
||||
}
|
||||
|
@ -643,6 +656,9 @@ void ParseFlickerLight2(FScanner &sc)
|
|||
case LIGHTTAG_ATTENUATE:
|
||||
defaults->SetAttenuate(ParseInt(sc) != 0);
|
||||
break;
|
||||
case LIGHTTAG_DONTLIGHTACTORS:
|
||||
defaults->SetDontLightActors(ParseInt(sc) != 0);
|
||||
break;
|
||||
default:
|
||||
sc.ScriptError("Unknown tag: %s\n", sc.String);
|
||||
}
|
||||
|
@ -723,6 +739,9 @@ static void ParseSectorLight(FScanner &sc)
|
|||
case LIGHTTAG_ATTENUATE:
|
||||
defaults->SetAttenuate(ParseInt(sc) != 0);
|
||||
break;
|
||||
case LIGHTTAG_DONTLIGHTACTORS:
|
||||
defaults->SetDontLightActors(ParseInt(sc) != 0);
|
||||
break;
|
||||
default:
|
||||
sc.ScriptError("Unknown tag: %s\n", sc.String);
|
||||
}
|
||||
|
|
|
@ -115,7 +115,7 @@ static FFont * IndexFont; // The font for the inventory indices
|
|||
static FTexture * healthpic; // Health icon
|
||||
static FTexture * berserkpic; // Berserk icon (Doom only)
|
||||
static FTexture * fragpic; // Frags icon
|
||||
static FTexture * invgems[4]; // Inventory arrows
|
||||
static FTexture * invgems[2]; // Inventory arrows
|
||||
|
||||
static int hudwidth, hudheight; // current width/height for HUD display
|
||||
static int statspace;
|
||||
|
@ -816,7 +816,7 @@ static void DrawInventory(player_t * CPlayer, int x,int y)
|
|||
{
|
||||
if(rover->PrevInv())
|
||||
{
|
||||
screen->DrawTexture(invgems[!!(level.time&4)], x-10, y,
|
||||
screen->DrawTexture(invgems[0], x-10, y,
|
||||
DTA_KeepRatio, true,
|
||||
DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_Alpha, 0.4, TAG_DONE);
|
||||
}
|
||||
|
@ -852,7 +852,7 @@ static void DrawInventory(player_t * CPlayer, int x,int y)
|
|||
}
|
||||
if(rover)
|
||||
{
|
||||
screen->DrawTexture(invgems[2 + !!(level.time&4)], x-10, y,
|
||||
screen->DrawTexture(invgems[1], x-10, y,
|
||||
DTA_KeepRatio, true,
|
||||
DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_Alpha, 0.4, TAG_DONE);
|
||||
}
|
||||
|
@ -1279,9 +1279,7 @@ void HUD_InitHud()
|
|||
if (IndexFont == NULL) IndexFont = ConFont; // Emergency fallback
|
||||
|
||||
invgems[0] = TexMan.FindTexture("INVGEML1");
|
||||
invgems[1] = TexMan.FindTexture("INVGEML2");
|
||||
invgems[2] = TexMan.FindTexture("INVGEMR1");
|
||||
invgems[3] = TexMan.FindTexture("INVGEMR2");
|
||||
invgems[1] = TexMan.FindTexture("INVGEMR1");
|
||||
|
||||
fragpic = TexMan.FindTexture("HU_FRAGS"); // Sadly, I don't have anything usable for this. :(
|
||||
|
||||
|
|
|
@ -356,13 +356,6 @@ public:
|
|||
CENTER_BOTTOM = BOTTOM | HCENTER
|
||||
};
|
||||
|
||||
enum ETextAlign
|
||||
{
|
||||
ALIGN_LEFT = 0,
|
||||
ALIGN_CENTER = 1,
|
||||
ALIGN_RIGHT = 2
|
||||
};
|
||||
|
||||
DBaseStatusBar ();
|
||||
void SetSize(int reltop = 32, int hres = 320, int vres = 200);
|
||||
void OnDestroy() override;
|
||||
|
@ -402,10 +395,9 @@ public:
|
|||
void DrawLog();
|
||||
uint32_t GetTranslation() const;
|
||||
|
||||
void DrawGraphic(FTextureID texture, bool animate, double x, double y, double Alpha = 1., bool translatable = false, bool dim = false,
|
||||
int imgAlign = TOP | LEFT, int screenalign = TOP | LEFT, bool alphamap = false, double width = -1, double height = -1);
|
||||
|
||||
void DrawString(FFont *font, const FString &cstring, double x, double y, double Alpha, int translation, int align, int screenalign, int spacing = 0, bool monospaced = false, int shadowX = 0, int shadowY = 0);
|
||||
void DrawGraphic(FTextureID texture, double x, double y, int flags, double Alpha, double boxwidth, double boxheight, double scaleX, double scaleY);
|
||||
void DrawString(FFont *font, const FString &cstring, double x, double y, int flags, double Alpha, int translation, int spacing, bool monospaced, int shadowX, int shadowY);
|
||||
void Fill(PalEntry color, double x, double y, double w, double h, int flags = 0);
|
||||
|
||||
void BeginStatusBar(int resW, int resH, int relTop, bool completeborder = false, bool forceScaled = false);
|
||||
void BeginHUD(int resW, int resH, double Alpha, bool forceScaled = false);
|
||||
|
@ -435,8 +427,8 @@ public:
|
|||
double CrosshairSize;
|
||||
double Displacement;
|
||||
bool ShowLog;
|
||||
|
||||
FImageCollection Images;
|
||||
int artiflashTick = 0;
|
||||
double itemflashFade = 0.75;
|
||||
|
||||
player_t *CPlayer;
|
||||
|
||||
|
@ -471,6 +463,7 @@ extern FTexture *CrosshairImage;
|
|||
|
||||
FTextureID GetInventoryIcon(AInventory *item, uint32_t flags, bool *applyscale);
|
||||
|
||||
|
||||
enum DI_Flags
|
||||
{
|
||||
DI_SKIPICON = 0x1,
|
||||
|
@ -478,11 +471,74 @@ enum DI_Flags
|
|||
DI_SKIPSPAWN = 0x4,
|
||||
DI_SKIPREADY = 0x8,
|
||||
DI_ALTICONFIRST = 0x10,
|
||||
|
||||
DI_DRAWINBOX = 0x20, // Set when either width or height is not zero
|
||||
|
||||
DI_TRANSLATABLE = 0x20,
|
||||
DI_FORCESCALE = 0x40,
|
||||
DI_ALTERNATEONFAIL = 0x80
|
||||
DI_DIM = 0x80,
|
||||
DI_DRAWCURSORFIRST = 0x100, // only for DrawInventoryBar.
|
||||
DI_ALWAYSSHOWCOUNT = 0x200, // only for DrawInventoryBar.
|
||||
DI_DIMDEPLETED = 0x400,
|
||||
DI_DONTANIMATE = 0x800, // do not animate the texture
|
||||
|
||||
DI_SCREEN_AUTO = 0, // decide based on given offsets.
|
||||
DI_SCREEN_MANUAL_ALIGN = 0x4000, // If this is on, the following flags will have an effect
|
||||
|
||||
DI_SCREEN_TOP = DI_SCREEN_MANUAL_ALIGN,
|
||||
DI_SCREEN_VCENTER = 0x8000 | DI_SCREEN_MANUAL_ALIGN,
|
||||
DI_SCREEN_BOTTOM = 0x10000 | DI_SCREEN_MANUAL_ALIGN,
|
||||
DI_SCREEN_VOFFSET = 0x18000 | DI_SCREEN_MANUAL_ALIGN,
|
||||
DI_SCREEN_VMASK = 0x18000 | DI_SCREEN_MANUAL_ALIGN,
|
||||
|
||||
DI_SCREEN_LEFT = DI_SCREEN_MANUAL_ALIGN,
|
||||
DI_SCREEN_HCENTER = 0x20000 | DI_SCREEN_MANUAL_ALIGN,
|
||||
DI_SCREEN_RIGHT = 0x40000 | DI_SCREEN_MANUAL_ALIGN,
|
||||
DI_SCREEN_HOFFSET = 0x60000 | DI_SCREEN_MANUAL_ALIGN,
|
||||
DI_SCREEN_HMASK = 0x60000 | DI_SCREEN_MANUAL_ALIGN,
|
||||
|
||||
DI_SCREEN_LEFT_TOP = DI_SCREEN_TOP|DI_SCREEN_LEFT,
|
||||
DI_SCREEN_RIGHT_TOP = DI_SCREEN_TOP|DI_SCREEN_RIGHT,
|
||||
DI_SCREEN_LEFT_BOTTOM = DI_SCREEN_BOTTOM|DI_SCREEN_LEFT,
|
||||
DI_SCREEN_RIGHT_BOTTOM = DI_SCREEN_BOTTOM|DI_SCREEN_RIGHT,
|
||||
DI_SCREEN_CENTER = DI_SCREEN_VCENTER|DI_SCREEN_HCENTER,
|
||||
DI_SCREEN_CENTER_BOTTOM = DI_SCREEN_BOTTOM|DI_SCREEN_HCENTER,
|
||||
DI_SCREEN_OFFSETS = DI_SCREEN_HOFFSET|DI_SCREEN_VOFFSET,
|
||||
|
||||
DI_ITEM_AUTO = 0, // equivalent with bottom center, which is the default alignment.
|
||||
|
||||
DI_ITEM_TOP = 0x80000,
|
||||
DI_ITEM_VCENTER = 0x100000,
|
||||
DI_ITEM_BOTTOM = 0, // this is the default vertical alignment
|
||||
DI_ITEM_VOFFSET = 0x180000,
|
||||
DI_ITEM_VMASK = 0x180000,
|
||||
|
||||
DI_ITEM_LEFT = 0x200000,
|
||||
DI_ITEM_HCENTER = 0, // this is the deafault horizontal alignment
|
||||
DI_ITEM_RIGHT = 0x400000,
|
||||
DI_ITEM_HOFFSET = 0x600000,
|
||||
DI_ITEM_HMASK = 0x600000,
|
||||
|
||||
DI_ITEM_LEFT_TOP = DI_ITEM_TOP|DI_ITEM_LEFT,
|
||||
DI_ITEM_RIGHT_TOP = DI_ITEM_TOP|DI_ITEM_RIGHT,
|
||||
DI_ITEM_LEFT_BOTTOM = DI_ITEM_BOTTOM|DI_ITEM_LEFT,
|
||||
DI_ITEM_RIGHT_BOTTOM = DI_ITEM_BOTTOM|DI_ITEM_RIGHT,
|
||||
DI_ITEM_CENTER = DI_ITEM_VCENTER|DI_ITEM_HCENTER,
|
||||
DI_ITEM_CENTER_BOTTOM = DI_ITEM_BOTTOM|DI_ITEM_HCENTER,
|
||||
DI_ITEM_OFFSETS = DI_ITEM_HOFFSET|DI_ITEM_VOFFSET,
|
||||
|
||||
DI_TEXT_ALIGN_LEFT = 0,
|
||||
DI_TEXT_ALIGN_RIGHT = 0x800000,
|
||||
DI_TEXT_ALIGN_CENTER = 0x1000000,
|
||||
DI_TEXT_ALIGN = 0x1800000,
|
||||
|
||||
DI_ALPHAMAPPED = 0x2000000,
|
||||
DI_NOSHADOW = 0x4000000,
|
||||
DI_ALWAYSSHOWCOUNTERS = 0x8000000,
|
||||
DI_ARTIFLASH = 0x10000000,
|
||||
DI_FORCEFILL = 0x20000000,
|
||||
|
||||
// These 2 flags are only used by SBARINFO so these duplicate other flags not used by SBARINFO
|
||||
DI_DRAWINBOX = DI_TEXT_ALIGN_RIGHT,
|
||||
DI_ALTERNATEONFAIL = DI_TEXT_ALIGN_CENTER,
|
||||
|
||||
};
|
||||
|
||||
#endif /* __SBAR_H__ */
|
||||
|
|
|
@ -65,9 +65,7 @@ enum
|
|||
imgSELECTBOX,
|
||||
imgCURSOR,
|
||||
imgINVLFGEM1,
|
||||
imgINVLFGEM2,
|
||||
imgINVRTGEM1,
|
||||
imgINVRTGEM2,
|
||||
};
|
||||
|
||||
EXTERN_CVAR(Int, fraglimit)
|
||||
|
@ -448,6 +446,7 @@ void SBarInfo::Load()
|
|||
{
|
||||
FreeSBarInfoScript();
|
||||
MugShotStates.Clear();
|
||||
|
||||
if(gameinfo.statusbar.IsNotEmpty())
|
||||
{
|
||||
int lump = Wads.CheckNumForFullName(gameinfo.statusbar, true);
|
||||
|
@ -981,18 +980,17 @@ public:
|
|||
|
||||
static const char *InventoryBarLumps[] =
|
||||
{
|
||||
"ARTIBOX", "SELECTBO", "INVCURS", "INVGEML1",
|
||||
"INVGEML2", "INVGEMR1", "INVGEMR2",
|
||||
"ARTIBOX", "SELECTBO", "INVCURS", "INVGEML1", "INVGEMR1",
|
||||
"USEARTIA", "USEARTIB", "USEARTIC", "USEARTID",
|
||||
};
|
||||
TArray<const char *> patchnames;
|
||||
patchnames.Resize(script->Images.Size()+10);
|
||||
patchnames.Resize(script->Images.Size()+9);
|
||||
unsigned int i = 0;
|
||||
for(i = 0;i < script->Images.Size();i++)
|
||||
{
|
||||
patchnames[i] = script->Images[i];
|
||||
}
|
||||
for(i = 0;i < 10;i++)
|
||||
for(i = 0;i < 9;i++)
|
||||
{
|
||||
patchnames[i+script->Images.Size()] = InventoryBarLumps[i];
|
||||
}
|
||||
|
@ -1163,9 +1161,6 @@ public:
|
|||
lastInventoryBar->Tick(NULL, this, false);
|
||||
}
|
||||
|
||||
// void DSBarInfo::FlashItem(const PClass *itemtype) - Is defined with CommandDrawSelectedInventory
|
||||
void _FlashItem(const PClass *itemtype);
|
||||
|
||||
void _ShowPop(int popnum)
|
||||
{
|
||||
if(popnum != currentPopup)
|
||||
|
@ -1606,14 +1601,6 @@ DEFINE_ACTION_FUNCTION(DSBarInfo, Tick)
|
|||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DSBarInfo, FlashItem)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(DSBarInfo);
|
||||
PARAM_CLASS(w, AInventory);
|
||||
self->_FlashItem(w);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DSBarInfo, ShowPop)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(DSBarInfo);
|
||||
|
|
|
@ -1691,16 +1691,16 @@ class CommandDrawSelectedInventory : public CommandDrawImage, private CommandDra
|
|||
|
||||
if(statusBar->CPlayer->mo->InvSel != NULL && !(level.flags & LEVEL_NOINVENTORYBAR))
|
||||
{
|
||||
if(artiflash && artiflashTick)
|
||||
if(artiflash && statusBar->wrapper->artiflashTick)
|
||||
{
|
||||
statusBar->DrawGraphic(statusBar->Images[ARTIFLASH_OFFSET+(4-artiflashTick)], imgx, imgy, block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets(),
|
||||
statusBar->DrawGraphic(statusBar->Images[ARTIFLASH_OFFSET+(4- statusBar->wrapper->artiflashTick)], imgx, imgy, block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets(),
|
||||
translatable, false, offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(itemflash && itemflashFade != 0)
|
||||
if(itemflash && statusBar->wrapper->itemflashFade != 0)
|
||||
{
|
||||
double flashAlpha = block->Alpha() * itemflashFade;
|
||||
double flashAlpha = block->Alpha() * statusBar->wrapper->itemflashFade;
|
||||
statusBar->DrawGraphic(statusBar->Images[statusBar->invBarOffset + imgCURSOR], imgx-4, imgy+2, block->XOffset(), block->YOffset(), flashAlpha, block->FullScreenOffsets(),
|
||||
translatable, false, offset);
|
||||
}
|
||||
|
@ -1789,38 +1789,18 @@ class CommandDrawSelectedInventory : public CommandDrawImage, private CommandDra
|
|||
{
|
||||
SBarInfoCommandFlowControl::Tick(block, statusBar, hudChanged);
|
||||
|
||||
if(artiflashTick > 0)
|
||||
artiflashTick--;
|
||||
if(itemflashFade > 0)
|
||||
{
|
||||
itemflashFade -= 1./14;
|
||||
if(itemflashFade < 0)
|
||||
itemflashFade = 0;
|
||||
}
|
||||
|
||||
SetTruth(statusBar->CPlayer->mo->InvSel == NULL || (level.flags & LEVEL_NOINVENTORYBAR), block, statusBar);
|
||||
|
||||
CommandDrawImage::Tick(block, statusBar, hudChanged);
|
||||
CommandDrawNumber::Tick(block, statusBar, hudChanged);
|
||||
}
|
||||
|
||||
static void Flash() { artiflashTick = 4; itemflashFade = 0.75; }
|
||||
protected:
|
||||
bool alternateOnEmpty;
|
||||
bool artiflash;
|
||||
bool alwaysShowCounter;
|
||||
bool itemflash;
|
||||
|
||||
static int artiflashTick;
|
||||
static double itemflashFade;
|
||||
};
|
||||
int CommandDrawSelectedInventory::artiflashTick = 0;
|
||||
double CommandDrawSelectedInventory::itemflashFade = 0.75;
|
||||
|
||||
void DSBarInfo::_FlashItem(const PClass *itemtype)
|
||||
{
|
||||
CommandDrawSelectedInventory::Flash();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -2032,7 +2012,7 @@ class CommandDrawShader : public SBarInfoCommand
|
|||
|
||||
void Draw(const SBarInfoMainBlock *block, const DSBarInfo *statusBar)
|
||||
{
|
||||
statusBar->DrawGraphic(&shaders[(vertical<<1) + reverse], x, y, block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets(), false, false, 0, true, width, height);
|
||||
statusBar->DrawGraphic(shaders[(vertical<<1) + reverse], x, y, block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets(), false, false, 0, true, width, height);
|
||||
}
|
||||
void Parse(FScanner &sc, bool fullScreenOffsets)
|
||||
{
|
||||
|
@ -2063,6 +2043,10 @@ class CommandDrawShader : public SBarInfoCommand
|
|||
}
|
||||
GetCoordinates(sc, fullScreenOffsets, x, y);
|
||||
sc.MustGetToken(';');
|
||||
shaders[0] = TexMan.FindTexture("BarShaderHF");
|
||||
shaders[1] = TexMan.FindTexture("BarShaderHR");
|
||||
shaders[2] = TexMan.FindTexture("BarShaderVF");
|
||||
shaders[3] = TexMan.FindTexture("BarShaderVR");
|
||||
}
|
||||
protected:
|
||||
bool vertical;
|
||||
|
@ -2072,87 +2056,8 @@ class CommandDrawShader : public SBarInfoCommand
|
|||
SBarInfoCoordinate x;
|
||||
SBarInfoCoordinate y;
|
||||
private:
|
||||
class FBarShader : public FTexture
|
||||
{
|
||||
public:
|
||||
FBarShader(bool vertical, bool reverse)
|
||||
{
|
||||
int i;
|
||||
|
||||
Width = vertical ? 2 : 256;
|
||||
Height = vertical ? 256 : 2;
|
||||
CalcBitSize();
|
||||
|
||||
// Fill the column/row with shading values.
|
||||
// Vertical shaders have have minimum alpha at the top
|
||||
// and maximum alpha at the bottom, unless flipped by
|
||||
// setting reverse to true. Horizontal shaders are just
|
||||
// the opposite.
|
||||
if (vertical)
|
||||
{
|
||||
if (!reverse)
|
||||
{
|
||||
for (i = 0; i < 256; ++i)
|
||||
{
|
||||
Pixels[i] = i;
|
||||
Pixels[256+i] = i;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < 256; ++i)
|
||||
{
|
||||
Pixels[i] = 255 - i;
|
||||
Pixels[256+i] = 255 -i;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!reverse)
|
||||
{
|
||||
for (i = 0; i < 256; ++i)
|
||||
{
|
||||
Pixels[i*2] = 255 - i;
|
||||
Pixels[i*2+1] = 255 - i;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < 256; ++i)
|
||||
{
|
||||
Pixels[i*2] = i;
|
||||
Pixels[i*2+1] = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
DummySpan[0].TopOffset = 0;
|
||||
DummySpan[0].Length = vertical ? 256 : 2;
|
||||
DummySpan[1].TopOffset = 0;
|
||||
DummySpan[1].Length = 0;
|
||||
}
|
||||
const uint8_t *GetColumn(unsigned int column, const Span **spans_out)
|
||||
{
|
||||
if (spans_out != NULL)
|
||||
{
|
||||
*spans_out = DummySpan;
|
||||
}
|
||||
return Pixels + ((column & WidthMask) << HeightBits);
|
||||
}
|
||||
const uint8_t *GetPixels() { return Pixels; }
|
||||
void Unload() {}
|
||||
private:
|
||||
uint8_t Pixels[512];
|
||||
Span DummySpan[2];
|
||||
};
|
||||
|
||||
static FBarShader shaders[4];
|
||||
};
|
||||
|
||||
CommandDrawShader::FBarShader CommandDrawShader::shaders[4] =
|
||||
{
|
||||
FBarShader(false, false), FBarShader(false, true),
|
||||
FBarShader(true, false), FBarShader(true, true)
|
||||
FTexture *shaders[4];
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -2230,16 +2135,14 @@ class CommandDrawInventoryBar : public SBarInfoCommand
|
|||
{
|
||||
int offset = (style != STYLE_Strife ? (style != STYLE_HexenStrict ? -12 : -10) : 14);
|
||||
int yOffset = style != STYLE_HexenStrict ? 0 : -1;
|
||||
statusBar->DrawGraphic(statusBar->Images[!(gametic & 4) ?
|
||||
statusBar->invBarOffset + imgINVLFGEM1 : statusBar->invBarOffset + imgINVLFGEM2], x + (!vertical ? offset : yOffset), y + (vertical ? offset : yOffset), block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets());
|
||||
statusBar->DrawGraphic(statusBar->Images[statusBar->invBarOffset + imgINVLFGEM1], x + (!vertical ? offset : yOffset), y + (vertical ? offset : yOffset), block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets());
|
||||
}
|
||||
// Is there something to the right?
|
||||
if (!noArrows && item != NULL)
|
||||
{
|
||||
int offset = (style != STYLE_Strife ? (style != STYLE_HexenStrict ? size*31+2 : size*31) : size*35-4);
|
||||
int yOffset = style != STYLE_HexenStrict ? 0 : -1;
|
||||
statusBar->DrawGraphic(statusBar->Images[!(gametic & 4) ?
|
||||
statusBar->invBarOffset + imgINVRTGEM1 : statusBar->invBarOffset + imgINVRTGEM2], x + (!vertical ? offset : yOffset), y + (vertical ? offset : yOffset), block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets());
|
||||
statusBar->DrawGraphic(statusBar->Images[statusBar->invBarOffset + imgINVRTGEM1], x + (!vertical ? offset : yOffset), y + (vertical ? offset : yOffset), block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -243,16 +243,24 @@ void ST_CreateStatusBar(bool bTitleLevel)
|
|||
StatusBar = new DBaseStatusBar();
|
||||
StatusBar->SetSize(0);
|
||||
}
|
||||
else if (gameinfo.statusbarclassfile >= gameinfo.statusbarfile)
|
||||
else
|
||||
{
|
||||
auto cls = PClass::FindClass(gameinfo.statusbarclass);
|
||||
if (cls != nullptr)
|
||||
// The old rule of 'what came last wins' goes here, as well.
|
||||
// If the most recent SBARINFO definition comes before a status bar class definition it will be picked,
|
||||
// if the class is defined later, this will be picked. If both come from the same file, the class definition will win.
|
||||
int sbarinfolump = Wads.CheckNumForName("SBARINFO");
|
||||
int sbarinfofile = Wads.GetLumpFile(sbarinfolump);
|
||||
if (gameinfo.statusbarclassfile >= gameinfo.statusbarfile && gameinfo.statusbarclassfile >= sbarinfofile)
|
||||
{
|
||||
StatusBar = (DBaseStatusBar *)cls->CreateNew();
|
||||
IFVIRTUALPTR(StatusBar, DBaseStatusBar, Init)
|
||||
auto cls = PClass::FindClass(gameinfo.statusbarclass);
|
||||
if (cls != nullptr)
|
||||
{
|
||||
VMValue params[] = { StatusBar };
|
||||
GlobalVMStack.Call(func, params, 1, nullptr, 0);
|
||||
StatusBar = (DBaseStatusBar *)cls->CreateNew();
|
||||
IFVIRTUALPTR(StatusBar, DBaseStatusBar, Init)
|
||||
{
|
||||
VMValue params[] = { StatusBar };
|
||||
GlobalVMStack.Call(func, params, 1, nullptr, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -283,7 +291,6 @@ void ST_CreateStatusBar(bool bTitleLevel)
|
|||
auto cls = PClass::FindClass(defname);
|
||||
if (cls != nullptr)
|
||||
{
|
||||
|
||||
StatusBar = (DBaseStatusBar *)cls->CreateNew();
|
||||
IFVIRTUALPTR(StatusBar, DBaseStatusBar, Init)
|
||||
{
|
||||
|
@ -327,6 +334,9 @@ void DBaseStatusBar::SetSize(int reltop, int hres, int vres)
|
|||
RelTop = reltop;
|
||||
HorizontalResolution = hres;
|
||||
VerticalResolution = vres;
|
||||
int x, y;
|
||||
V_CalcCleanFacs(hres, vres, SCREENWIDTH, SCREENHEIGHT, &x, &y);
|
||||
defaultScale = { (double)x, (double)y };
|
||||
|
||||
CallSetScaled(st_scale);
|
||||
}
|
||||
|
@ -500,7 +510,7 @@ DEFINE_ACTION_FUNCTION(DBaseStatusBar, BeginStatusBar)
|
|||
|
||||
void DBaseStatusBar::BeginHUD(int resW, int resH, double Alpha, bool forcescaled)
|
||||
{
|
||||
SetSize(0, resW, resH); // this intentionally resets the relative top to force the caller to go through BeginStatusBar and not just reset some variables.
|
||||
SetSize(RelTop, resW, resH);
|
||||
this->Alpha = Alpha;
|
||||
ForcedScale = forcescaled;
|
||||
CompleteBorder = false;
|
||||
|
@ -583,6 +593,19 @@ void DBaseStatusBar::Tick ()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (artiflashTick > 0)
|
||||
artiflashTick--;
|
||||
|
||||
if (itemflashFade > 0)
|
||||
{
|
||||
itemflashFade -= 1 / 14.;
|
||||
if (itemflashFade < 0)
|
||||
{
|
||||
itemflashFade = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DBaseStatusBar, Tick)
|
||||
|
@ -1112,6 +1135,7 @@ void DBaseStatusBar::CallDraw(EHudState state)
|
|||
GlobalVMStack.Call(func, params, countof(params), nullptr, 0);
|
||||
}
|
||||
else Draw(state);
|
||||
screen->ClearClipRect(); // make sure the scripts don't leave a valid clipping rect behind.
|
||||
}
|
||||
|
||||
|
||||
|
@ -1397,11 +1421,8 @@ void DBaseStatusBar::SerializeMessages(FSerializer &arc)
|
|||
|
||||
void DBaseStatusBar::ScreenSizeChanged ()
|
||||
{
|
||||
st_scale.Callback ();
|
||||
|
||||
int x, y;
|
||||
V_CalcCleanFacs(HorizontalResolution, VerticalResolution, SCREENWIDTH, SCREENHEIGHT, &x, &y);
|
||||
defaultScale = { (double)x, (double)y };
|
||||
// We need to recalculate the sizing info
|
||||
SetSize(RelTop, HorizontalResolution, VerticalResolution);
|
||||
|
||||
for (size_t i = 0; i < countof(Messages); ++i)
|
||||
{
|
||||
|
@ -1543,124 +1564,221 @@ uint32_t DBaseStatusBar::GetTranslation() const
|
|||
//
|
||||
//============================================================================
|
||||
|
||||
void DBaseStatusBar::DrawGraphic(FTextureID texture, bool animate, double x, double y, double Alpha, bool translatable, bool dim,
|
||||
int imgAlign, int screenalign, bool alphamap, double width, double height)
|
||||
void DBaseStatusBar::DrawGraphic(FTextureID texture, double x, double y, int flags, double Alpha, double boxwidth, double boxheight, double scaleX, double scaleY)
|
||||
{
|
||||
if (!texture.isValid())
|
||||
return;
|
||||
|
||||
FTexture *tex = (flags & DI_DONTANIMATE)? TexMan[texture] : TexMan(texture);
|
||||
|
||||
double texwidth = tex->GetScaledWidthDouble() * scaleX;
|
||||
double texheight = tex->GetScaledHeightDouble() * scaleY;
|
||||
|
||||
if (boxwidth > 0 || boxheight > 0)
|
||||
{
|
||||
if (!(flags & DI_FORCEFILL))
|
||||
{
|
||||
double scale1 = 1., scale2 = 1.;
|
||||
|
||||
if (boxwidth > 0 && (boxwidth < texwidth || (flags & DI_FORCESCALE)))
|
||||
{
|
||||
scale1 = boxwidth / texwidth;
|
||||
}
|
||||
if (boxheight != -1 && (boxheight < texheight || (flags & DI_FORCESCALE)))
|
||||
{
|
||||
scale2 = boxheight / texheight;
|
||||
}
|
||||
|
||||
if (flags & DI_FORCESCALE)
|
||||
{
|
||||
if (boxwidth <= 0 || (boxheight > 0 && scale2 < scale1))
|
||||
scale1 = scale2;
|
||||
}
|
||||
else scale1 = MIN(scale1, scale2);
|
||||
|
||||
boxwidth = texwidth * scale1;
|
||||
boxheight = texheight * scale1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
boxwidth = texwidth;
|
||||
boxheight = texheight;
|
||||
}
|
||||
|
||||
// resolve auto-alignment before making any adjustments to the position values.
|
||||
if (!(flags & DI_SCREEN_MANUAL_ALIGN))
|
||||
{
|
||||
if (x < 0) flags |= DI_SCREEN_RIGHT;
|
||||
else flags |= DI_SCREEN_LEFT;
|
||||
if (y < 0) flags |= DI_SCREEN_BOTTOM;
|
||||
else flags |= DI_SCREEN_TOP;
|
||||
}
|
||||
|
||||
Alpha *= this->Alpha;
|
||||
if (Alpha <= 0) return;
|
||||
x += drawOffset.X;
|
||||
y += drawOffset.Y;
|
||||
|
||||
FTexture *tex = animate ? TexMan(texture) : TexMan[texture];
|
||||
|
||||
switch (imgAlign & HMASK)
|
||||
switch (flags & DI_ITEM_HMASK)
|
||||
{
|
||||
case HCENTER: x -= width / 2; break;
|
||||
case RIGHT: x -= width; break;
|
||||
case HOFFSET: x -= tex->GetScaledLeftOffsetDouble() * width / tex->GetScaledWidthDouble(); break;
|
||||
case DI_ITEM_HCENTER: x -= boxwidth / 2; break;
|
||||
case DI_ITEM_RIGHT: x -= boxwidth; break;
|
||||
case DI_ITEM_HOFFSET: x -= tex->GetScaledLeftOffsetDouble() * boxwidth / texwidth; break;
|
||||
}
|
||||
|
||||
switch (imgAlign & VMASK)
|
||||
switch (flags & DI_ITEM_VMASK)
|
||||
{
|
||||
case VCENTER: y -= height / 2; break;
|
||||
case BOTTOM: y -= height; break;
|
||||
case VOFFSET: y -= tex->GetScaledTopOffsetDouble() * height / tex->GetScaledHeightDouble(); break;
|
||||
case DI_ITEM_VCENTER: y -= boxheight / 2; break;
|
||||
case DI_ITEM_BOTTOM: y -= boxheight; break;
|
||||
case DI_ITEM_VOFFSET: y -= tex->GetScaledTopOffsetDouble() * boxheight / texheight; break;
|
||||
}
|
||||
|
||||
if (!fullscreenOffsets)
|
||||
{
|
||||
x += ST_X;
|
||||
y += ST_Y;
|
||||
//y += ST_Y;
|
||||
|
||||
// Todo: Allow other scaling values, too.
|
||||
if (Scaled)
|
||||
{
|
||||
screen->VirtualToRealCoords(x, y, width, height, HorizontalResolution, VerticalResolution, true, true);
|
||||
screen->VirtualToRealCoords(x, y, boxwidth, boxheight, HorizontalResolution, VerticalResolution, true, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
double orgx, orgy;
|
||||
|
||||
switch (screenalign & HMASK)
|
||||
switch (flags & DI_SCREEN_HMASK)
|
||||
{
|
||||
default: orgx = 0; break;
|
||||
case HCENTER: orgx = screen->GetWidth() / 2; break;
|
||||
case RIGHT: orgx = screen->GetWidth(); break;
|
||||
case DI_SCREEN_HCENTER: orgx = screen->GetWidth() / 2; break;
|
||||
case DI_SCREEN_RIGHT: orgx = screen->GetWidth(); break;
|
||||
}
|
||||
|
||||
switch (screenalign & VMASK)
|
||||
switch (flags & DI_SCREEN_VMASK)
|
||||
{
|
||||
default: orgy = 0; break;
|
||||
case VCENTER: orgy = screen->GetHeight() / 2; break;
|
||||
case BOTTOM: orgy = screen->GetHeight(); break;
|
||||
case DI_SCREEN_VCENTER: orgy = screen->GetHeight() / 2; break;
|
||||
case DI_SCREEN_BOTTOM: orgy = screen->GetHeight(); break;
|
||||
}
|
||||
|
||||
if (screenalign == (RIGHT | TOP) && vid_fps) y += 10;
|
||||
// move stuff in the top right corner a bit down if the fps counter is on.
|
||||
if ((flags & (DI_SCREEN_HMASK|DI_SCREEN_VMASK)) == DI_SCREEN_RIGHT_TOP && vid_fps) y += 10;
|
||||
|
||||
DVector2 Scale = GetHUDScale();
|
||||
|
||||
x *= Scale.X;
|
||||
y *= Scale.Y;
|
||||
width *= Scale.X;
|
||||
height *= Scale.Y;
|
||||
boxwidth *= Scale.X;
|
||||
boxheight *= Scale.Y;
|
||||
x += orgx;
|
||||
y += orgy;
|
||||
}
|
||||
screen->DrawTexture(tex, x, y,
|
||||
DTA_TopOffset, 0,
|
||||
DTA_LeftOffset, 0,
|
||||
DTA_DestWidthF, width,
|
||||
DTA_DestHeightF, height,
|
||||
DTA_TranslationIndex, translatable ? GetTranslation() : 0,
|
||||
DTA_ColorOverlay, dim ? MAKEARGB(170, 0, 0, 0) : 0,
|
||||
DTA_DestWidthF, boxwidth,
|
||||
DTA_DestHeightF, boxheight,
|
||||
DTA_TranslationIndex, (flags & DI_TRANSLATABLE) ? GetTranslation() : 0,
|
||||
DTA_ColorOverlay, (flags & DI_DIM) ? MAKEARGB(170, 0, 0, 0) : 0,
|
||||
DTA_Alpha, Alpha,
|
||||
DTA_AlphaChannel, alphamap,
|
||||
DTA_FillColor, alphamap ? 0 : -1);
|
||||
DTA_AlphaChannel, !!(flags & DI_ALPHAMAPPED),
|
||||
DTA_FillColor, (flags & DI_ALPHAMAPPED) ? 0 : -1);
|
||||
}
|
||||
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DBaseStatusBar, DrawGraphic)
|
||||
DEFINE_ACTION_FUNCTION(DBaseStatusBar, DrawTexture)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DBaseStatusBar);
|
||||
PARAM_INT(texid);
|
||||
PARAM_BOOL(animate);
|
||||
PARAM_FLOAT(x);
|
||||
PARAM_FLOAT(y);
|
||||
PARAM_FLOAT(alpha);
|
||||
PARAM_BOOL(translatable);
|
||||
PARAM_BOOL(dim);
|
||||
PARAM_INT(ialign);
|
||||
PARAM_INT(salign);
|
||||
PARAM_BOOL(alphamap);
|
||||
PARAM_FLOAT(w);
|
||||
PARAM_FLOAT(h);
|
||||
self->DrawGraphic(FSetTextureID(texid), animate, x, y, alpha, translatable, dim, ialign, salign, alphamap, w, h);
|
||||
PARAM_INT_DEF(flags);
|
||||
PARAM_FLOAT_DEF(alpha);
|
||||
PARAM_FLOAT_DEF(w);
|
||||
PARAM_FLOAT_DEF(h);
|
||||
PARAM_FLOAT_DEF(scaleX);
|
||||
PARAM_FLOAT_DEF(scaleY);
|
||||
if (!screen->IsLocked()) ThrowAbortException(X_OTHER, "Attempt to draw to screen outside a draw function");
|
||||
self->DrawGraphic(FSetTextureID(texid), x, y, flags, alpha, w, h, scaleX, scaleY);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DBaseStatusBar, DrawImage)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DBaseStatusBar);
|
||||
PARAM_STRING(texid);
|
||||
PARAM_FLOAT(x);
|
||||
PARAM_FLOAT(y);
|
||||
PARAM_INT_DEF(flags);
|
||||
PARAM_FLOAT_DEF(alpha);
|
||||
PARAM_FLOAT_DEF(w);
|
||||
PARAM_FLOAT_DEF(h);
|
||||
PARAM_FLOAT_DEF(scaleX);
|
||||
PARAM_FLOAT_DEF(scaleY);
|
||||
if (!screen->IsLocked()) ThrowAbortException(X_OTHER, "Attempt to draw to screen outside a draw function");
|
||||
self->DrawGraphic(TexMan.CheckForTexture(texid, FTexture::TEX_Any), x, y, flags, alpha, w, h, scaleX, scaleY);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// draw stuff
|
||||
// encapsulates all settings a HUD font may need
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
void DBaseStatusBar::DrawString(FFont *font, const FString &cstring, double x, double y, double Alpha, int translation, int align, int screenalign, int spacing, bool monospaced, int shadowX, int shadowY)
|
||||
class DHUDFont : public DObject
|
||||
{
|
||||
switch (align)
|
||||
// this blocks CreateNew on this class which is the intent here.
|
||||
DECLARE_ABSTRACT_CLASS(DHUDFont, DObject);
|
||||
|
||||
public:
|
||||
FFont *mFont;
|
||||
int mSpacing;
|
||||
bool mMonospaced;
|
||||
int mShadowX;
|
||||
int mShadowY;
|
||||
|
||||
DHUDFont(FFont *f, int sp, bool ms, int sx, int sy)
|
||||
: mFont(f), mSpacing(sp), mMonospaced(ms), mShadowX(sx), mShadowY(sy)
|
||||
{}
|
||||
};
|
||||
|
||||
IMPLEMENT_CLASS(DHUDFont, true, false);
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DHUDFont, Create)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
PARAM_POINTER(fnt, FFont);
|
||||
PARAM_INT_DEF(spac);
|
||||
PARAM_BOOL_DEF(mono);
|
||||
PARAM_INT_DEF(sx);
|
||||
PARAM_INT_DEF(sy);
|
||||
ACTION_RETURN_POINTER(new DHUDFont(fnt, spac, mono, sy, sy));
|
||||
}
|
||||
|
||||
DEFINE_FIELD(DHUDFont, mFont);
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// draw a string
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
void DBaseStatusBar::DrawString(FFont *font, const FString &cstring, double x, double y, int flags, double Alpha, int translation, int spacing, bool monospaced, int shadowX, int shadowY)
|
||||
{
|
||||
switch (flags & DI_TEXT_ALIGN)
|
||||
{
|
||||
default:
|
||||
break;
|
||||
case ALIGN_RIGHT:
|
||||
case DI_TEXT_ALIGN_RIGHT:
|
||||
if (!monospaced)
|
||||
x -= static_cast<int> (font->StringWidth(cstring) + (spacing * cstring.Len()));
|
||||
else //monospaced, so just multiply the character size
|
||||
x -= static_cast<int> ((spacing) * cstring.Len());
|
||||
break;
|
||||
case ALIGN_CENTER:
|
||||
case DI_TEXT_ALIGN_CENTER:
|
||||
if (!monospaced)
|
||||
x -= static_cast<int> (font->StringWidth(cstring) + (spacing * cstring.Len())) / 2;
|
||||
else //monospaced, so just multiply the character size
|
||||
|
@ -1680,21 +1798,22 @@ void DBaseStatusBar::DrawString(FFont *font, const FString &cstring, double x, d
|
|||
shadowX *= (int)Scale.X;
|
||||
shadowY *= (int)Scale.Y;
|
||||
|
||||
switch (screenalign & HMASK)
|
||||
switch (flags & DI_SCREEN_HMASK)
|
||||
{
|
||||
default: orgx = 0; break;
|
||||
case HCENTER: orgx = screen->GetWidth() / 2; break;
|
||||
case RIGHT: orgx = screen->GetWidth(); break;
|
||||
case DI_SCREEN_HCENTER: orgx = screen->GetWidth() / 2; break;
|
||||
case DI_SCREEN_RIGHT: orgx = screen->GetWidth(); break;
|
||||
}
|
||||
|
||||
switch (screenalign & VMASK)
|
||||
switch (flags & DI_SCREEN_VMASK)
|
||||
{
|
||||
default: orgy = 0; break;
|
||||
case VCENTER: orgy = screen->GetHeight() / 2; break;
|
||||
case BOTTOM: orgy = screen->GetHeight(); break;
|
||||
case DI_SCREEN_VCENTER: orgy = screen->GetHeight() / 2; break;
|
||||
case DI_SCREEN_BOTTOM: orgy = screen->GetHeight(); break;
|
||||
}
|
||||
|
||||
if (screenalign == (RIGHT | TOP) && vid_fps) orgy += 10;
|
||||
// move stuff in the top right corner a bit down if the fps counter is on.
|
||||
if ((flags & (DI_SCREEN_HMASK | DI_SCREEN_VMASK)) == DI_SCREEN_RIGHT_TOP && vid_fps) y += 10;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1732,27 +1851,10 @@ void DBaseStatusBar::DrawString(FFont *font, const FString &cstring, double x, d
|
|||
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;
|
||||
//ry += ST_Y;
|
||||
|
||||
// Todo: Allow other scaling values, too.
|
||||
if (Scaled)
|
||||
|
@ -1772,7 +1874,7 @@ void DBaseStatusBar::DrawString(FFont *font, const FString &cstring, double x, d
|
|||
}
|
||||
// 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)
|
||||
if ((shadowX != 0 || shadowY != 0) && !(flags & DI_NOSHADOW))
|
||||
{
|
||||
screen->DrawChar(font, CR_UNTRANSLATED, rx + shadowX, ry + shadowY, ch,
|
||||
DTA_DestWidthF, rw,
|
||||
|
@ -1795,44 +1897,129 @@ void DBaseStatusBar::DrawString(FFont *font, const FString &cstring, double x, d
|
|||
|
||||
}
|
||||
|
||||
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DBaseStatusBar, DrawString)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DBaseStatusBar);
|
||||
PARAM_POINTER(font, FFont);
|
||||
PARAM_POINTER(font, DHUDFont);
|
||||
PARAM_STRING(string);
|
||||
PARAM_FLOAT(x);
|
||||
PARAM_FLOAT(y);
|
||||
PARAM_FLOAT(alpha);
|
||||
PARAM_INT(trans);
|
||||
PARAM_INT(ialign);
|
||||
PARAM_INT(salign);
|
||||
PARAM_INT_DEF(spacing);
|
||||
PARAM_BOOL_DEF(monospaced);
|
||||
PARAM_INT_DEF(shadowX);
|
||||
PARAM_INT_DEF(shadowY);
|
||||
PARAM_INT_DEF(flags);
|
||||
PARAM_INT_DEF(trans);
|
||||
PARAM_FLOAT_DEF(alpha);
|
||||
PARAM_INT_DEF(wrapwidth);
|
||||
PARAM_INT_DEF(linespacing);
|
||||
|
||||
if (!screen->IsLocked()) ThrowAbortException(X_OTHER, "Attempt to draw to screen outside a draw function");
|
||||
|
||||
// resolve auto-alignment before making any adjustments to the position values.
|
||||
if (!(flags & DI_SCREEN_MANUAL_ALIGN))
|
||||
{
|
||||
if (x < 0) flags |= DI_SCREEN_RIGHT;
|
||||
else flags |= DI_SCREEN_LEFT;
|
||||
if (y < 0) flags |= DI_SCREEN_BOTTOM;
|
||||
else flags |= DI_SCREEN_TOP;
|
||||
}
|
||||
|
||||
if (wrapwidth > 0)
|
||||
{
|
||||
FBrokenLines *brk = V_BreakLines(font, wrapwidth, string, true);
|
||||
FBrokenLines *brk = V_BreakLines(font->mFont, wrapwidth, string, true);
|
||||
for (int i = 0; brk[i].Width >= 0; i++)
|
||||
{
|
||||
self->DrawString(font, brk[i].Text, x, y, alpha, trans, ialign, salign, spacing, monospaced, shadowX, shadowY);
|
||||
y += font->GetHeight() + linespacing;
|
||||
self->DrawString(font->mFont, brk[i].Text, x, y, flags, alpha, trans, font->mSpacing, font->mMonospaced, font->mShadowX, font->mShadowY);
|
||||
y += font->mFont->GetHeight() + linespacing;
|
||||
}
|
||||
V_FreeBrokenLines(brk);
|
||||
}
|
||||
else
|
||||
{
|
||||
self->DrawString(font, string, x, y, alpha, trans, ialign, salign, spacing, monospaced, shadowX, shadowY);
|
||||
self->DrawString(font->mFont, string, x, y, flags, alpha, trans, font->mSpacing, font->mMonospaced, font->mShadowX, font->mShadowY);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// draw stuff
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
void DBaseStatusBar::Fill(PalEntry color, double x, double y, double w, double h, int flags)
|
||||
{
|
||||
// resolve auto-alignment before making any adjustments to the position values.
|
||||
if (!(flags & DI_SCREEN_MANUAL_ALIGN))
|
||||
{
|
||||
if (x < 0) flags |= DI_SCREEN_RIGHT;
|
||||
else flags |= DI_SCREEN_LEFT;
|
||||
if (y < 0) flags |= DI_SCREEN_BOTTOM;
|
||||
else flags |= DI_SCREEN_TOP;
|
||||
}
|
||||
|
||||
double Alpha = color.a * this->Alpha / 255;
|
||||
if (Alpha <= 0) return;
|
||||
x += drawOffset.X;
|
||||
y += drawOffset.Y;
|
||||
|
||||
if (!fullscreenOffsets)
|
||||
{
|
||||
x += ST_X;
|
||||
//y += ST_Y;
|
||||
|
||||
// Todo: Allow other scaling values, too.
|
||||
if (Scaled)
|
||||
{
|
||||
screen->VirtualToRealCoords(x, y, w, h, HorizontalResolution, VerticalResolution, true, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
double orgx, orgy;
|
||||
|
||||
switch (flags & DI_SCREEN_HMASK)
|
||||
{
|
||||
default: orgx = 0; break;
|
||||
case DI_SCREEN_HCENTER: orgx = screen->GetWidth() / 2; break;
|
||||
case DI_SCREEN_RIGHT: orgx = screen->GetWidth(); break;
|
||||
}
|
||||
|
||||
switch (flags & DI_SCREEN_VMASK)
|
||||
{
|
||||
default: orgy = 0; break;
|
||||
case DI_SCREEN_VCENTER: orgy = screen->GetHeight() / 2; break;
|
||||
case DI_SCREEN_BOTTOM: orgy = screen->GetHeight(); break;
|
||||
}
|
||||
|
||||
// move stuff in the top right corner a bit down if the fps counter is on.
|
||||
if ((flags & (DI_SCREEN_HMASK | DI_SCREEN_VMASK)) == DI_SCREEN_RIGHT_TOP && vid_fps) y += 10;
|
||||
|
||||
DVector2 Scale = GetHUDScale();
|
||||
|
||||
x *= Scale.X;
|
||||
y *= Scale.Y;
|
||||
w *= Scale.X;
|
||||
h *= Scale.Y;
|
||||
x += orgx;
|
||||
y += orgy;
|
||||
}
|
||||
screen->Dim(color, float(Alpha), int(x), int(y), int(w), int(h));
|
||||
}
|
||||
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DBaseStatusBar, Fill)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DBaseStatusBar);
|
||||
PARAM_COLOR(color);
|
||||
PARAM_FLOAT(x);
|
||||
PARAM_FLOAT(y);
|
||||
PARAM_FLOAT(w);
|
||||
PARAM_FLOAT(h);
|
||||
PARAM_INT_DEF(flags);
|
||||
if (!screen->IsLocked()) ThrowAbortException(X_OTHER, "Attempt to draw to screen outside a draw function");
|
||||
self->Fill(color, x, y, w, h);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// CCMD showpop
|
||||
|
@ -1876,6 +2063,8 @@ DEFINE_FIELD(DBaseStatusBar, drawOffset);
|
|||
DEFINE_FIELD(DBaseStatusBar, drawClip);
|
||||
DEFINE_FIELD(DBaseStatusBar, fullscreenOffsets);
|
||||
DEFINE_FIELD(DBaseStatusBar, defaultScale);
|
||||
DEFINE_FIELD(DBaseStatusBar, artiflashTick);
|
||||
DEFINE_FIELD(DBaseStatusBar, itemflashFade);
|
||||
|
||||
DEFINE_GLOBAL(StatusBar);
|
||||
|
||||
|
@ -1928,9 +2117,9 @@ DEFINE_ACTION_FUNCTION(DBaseStatusBar, FormatNumber)
|
|||
{
|
||||
PARAM_PROLOGUE;
|
||||
PARAM_INT(number);
|
||||
PARAM_INT(minsize);
|
||||
PARAM_INT(maxsize);
|
||||
PARAM_INT(flags);
|
||||
PARAM_INT_DEF(minsize);
|
||||
PARAM_INT_DEF(maxsize);
|
||||
PARAM_INT_DEF(flags);
|
||||
PARAM_STRING_DEF(prefix);
|
||||
static int maxvals[] = { 1, 9, 99, 999, 9999, 99999, 999999, 9999999, 99999999, 999999999 };
|
||||
|
||||
|
@ -1956,10 +2145,10 @@ DEFINE_ACTION_FUNCTION(DBaseStatusBar, ReceivedWeapon)
|
|||
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);
|
||||
PARAM_STRING_DEF(def_face);
|
||||
auto tex = self->mugshot.GetFace(self->CPlayer, def_face, accuracy, (FMugShot::StateFlags)stateflags);
|
||||
ACTION_RETURN_INT(tex ? tex->id.GetIndex() : -1);
|
||||
}
|
||||
|
||||
|
|
|
@ -424,7 +424,7 @@ void GLFlat::Draw(int pass, bool trans) // trans only has meaning for GLPASS_LIG
|
|||
else gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
|
||||
gl_RenderState.SetMaterial(gltexture, CLAMP_NONE, 0, -1, false);
|
||||
gl_SetPlaneTextureRotation(&plane, gltexture);
|
||||
DrawSubsectors(pass, !gl.legacyMode, true);
|
||||
DrawSubsectors(pass, !gl.legacyMode && (gl.lightmethod == LM_DIRECT || dynlightindex > -1), true);
|
||||
gl_RenderState.EnableTextureMatrix(false);
|
||||
}
|
||||
if (renderstyle==STYLE_Add) gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
|
|
@ -62,7 +62,7 @@ void gl_SetDynSpriteLight(AActor *self, float x, float y, float z, subsector_t *
|
|||
while (node)
|
||||
{
|
||||
light=node->lightsource;
|
||||
if (light->visibletoplayer && !(light->flags2&MF2_DORMANT) && (!(light->flags4&MF4_DONTLIGHTSELF) || light->target != self))
|
||||
if (light->visibletoplayer && !(light->flags2&MF2_DORMANT) && (!(light->flags4&MF4_DONTLIGHTSELF) || light->target != self) && !(light->flags4&MF4_DONTLIGHTACTORS))
|
||||
{
|
||||
float dist;
|
||||
|
||||
|
|
|
@ -361,6 +361,7 @@ FNativePalette *OpenGLFrameBuffer::CreatePalette(FRemapTable *remap)
|
|||
//==========================================================================
|
||||
bool OpenGLFrameBuffer::Begin2D(bool)
|
||||
{
|
||||
ClearClipRect();
|
||||
gl_RenderState.mViewMatrix.loadIdentity();
|
||||
gl_RenderState.mProjectionMatrix.ortho(0, GetWidth(), GetHeight(), 0, -1.0f, 1.0f);
|
||||
gl_RenderState.ApplyMatrices();
|
||||
|
@ -428,7 +429,7 @@ void OpenGLFrameBuffer::Dim(PalEntry)
|
|||
Super::Dim(0);
|
||||
}
|
||||
|
||||
void OpenGLFrameBuffer::Dim(PalEntry color, float damount, int x1, int y1, int w, int h)
|
||||
void OpenGLFrameBuffer::DoDim(PalEntry color, float damount, int x1, int y1, int w, int h)
|
||||
{
|
||||
if (GLRenderer != nullptr && GLRenderer->m2DDrawer != nullptr)
|
||||
GLRenderer->m2DDrawer->AddDim(color, damount, x1, y1, w, h);
|
||||
|
@ -451,7 +452,7 @@ void OpenGLFrameBuffer::FlatFill (int left, int top, int right, int bottom, FTex
|
|||
//
|
||||
//
|
||||
//==========================================================================
|
||||
void OpenGLFrameBuffer::Clear(int left, int top, int right, int bottom, int palcolor, uint32_t color)
|
||||
void OpenGLFrameBuffer::DoClear(int left, int top, int right, int bottom, int palcolor, uint32_t color)
|
||||
{
|
||||
if (GLRenderer != nullptr && GLRenderer->m2DDrawer != nullptr)
|
||||
GLRenderer->m2DDrawer->AddClear(left, top, right, bottom, palcolor, color);
|
||||
|
|
|
@ -63,9 +63,9 @@ public:
|
|||
void DrawTextureParms(FTexture *img, DrawParms &parms);
|
||||
void DrawLine(int x1, int y1, int x2, int y2, int palcolor, uint32_t color);
|
||||
void DrawPixel(int x1, int y1, int palcolor, uint32_t color);
|
||||
void Clear(int left, int top, int right, int bottom, int palcolor, uint32_t color);
|
||||
void DoClear(int left, int top, int right, int bottom, int palcolor, uint32_t color);
|
||||
void Dim(PalEntry color=0);
|
||||
void Dim (PalEntry color, float damount, int x1, int y1, int w, int h);
|
||||
void DoDim (PalEntry color, float damount, int x1, int y1, int w, int h);
|
||||
void FlatFill (int left, int top, int right, int bottom, FTexture *src, bool local_origin=false);
|
||||
|
||||
void FillSimplePoly(FTexture *tex, FVector2 *points, int npoints,
|
||||
|
|
|
@ -2410,6 +2410,7 @@ bool OpenGLSWFrameBuffer::OpenGLPal::Update()
|
|||
|
||||
bool OpenGLSWFrameBuffer::Begin2D(bool copy3d)
|
||||
{
|
||||
ClearClipRect();
|
||||
if (!Accel2D)
|
||||
{
|
||||
return false;
|
||||
|
@ -2488,7 +2489,7 @@ FNativePalette *OpenGLSWFrameBuffer::CreatePalette(FRemapTable *remap)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void OpenGLSWFrameBuffer::Clear(int left, int top, int right, int bottom, int palcolor, uint32_t color)
|
||||
void OpenGLSWFrameBuffer::DoClear(int left, int top, int right, int bottom, int palcolor, uint32_t color)
|
||||
{
|
||||
if (In2D < 2)
|
||||
{
|
||||
|
@ -2517,7 +2518,7 @@ void OpenGLSWFrameBuffer::Clear(int left, int top, int right, int bottom, int pa
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void OpenGLSWFrameBuffer::Dim(PalEntry color, float amount, int x1, int y1, int w, int h)
|
||||
void OpenGLSWFrameBuffer::DoDim(PalEntry color, float amount, int x1, int y1, int w, int h)
|
||||
{
|
||||
if (amount <= 0)
|
||||
{
|
||||
|
|
|
@ -55,8 +55,8 @@ public:
|
|||
FNativeTexture *CreateTexture(FTexture *gametex, bool wrapping) override;
|
||||
FNativePalette *CreatePalette(FRemapTable *remap) override;
|
||||
void DrawTextureParms(FTexture *img, DrawParms &parms) override;
|
||||
void Clear(int left, int top, int right, int bottom, int palcolor, uint32_t color) override;
|
||||
void Dim(PalEntry color, float amount, int x1, int y1, int w, int h) override;
|
||||
void DoClear(int left, int top, int right, int bottom, int palcolor, uint32_t color) override;
|
||||
void DoDim(PalEntry color, float amount, int x1, int y1, int w, int h) override;
|
||||
void FlatFill(int left, int top, int right, int bottom, FTexture *src, bool local_origin) override;
|
||||
void DrawLine(int x0, int y0, int x1, int y1, int palColor, uint32_t realcolor) override;
|
||||
void DrawPixel(int x, int y, int palcolor, uint32_t rgbcolor) override;
|
||||
|
|
|
@ -339,35 +339,7 @@ void cht_DoCheat (player_t *player, int cheat)
|
|||
}
|
||||
else
|
||||
{
|
||||
player->mo->Revive();
|
||||
player->playerstate = PST_LIVE;
|
||||
player->health = player->mo->health = player->mo->GetDefault()->health;
|
||||
player->viewheight = ((APlayerPawn *)player->mo->GetDefault())->ViewHeight;
|
||||
player->mo->renderflags &= ~RF_INVISIBLE;
|
||||
player->mo->Height = player->mo->GetDefault()->Height;
|
||||
player->mo->radius = player->mo->GetDefault()->radius;
|
||||
player->mo->special1 = 0; // required for the Hexen fighter's fist attack.
|
||||
// This gets set by AActor::Die as flag for the wimpy death and must be reset here.
|
||||
player->mo->SetState (player->mo->SpawnState);
|
||||
if (!(player->mo->flags2 & MF2_DONTTRANSLATE))
|
||||
{
|
||||
player->mo->Translation = TRANSLATION(TRANSLATION_Players, uint8_t(player-players));
|
||||
}
|
||||
if (player->ReadyWeapon != nullptr)
|
||||
{
|
||||
P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->GetUpState());
|
||||
}
|
||||
|
||||
if (player->morphTics)
|
||||
{
|
||||
P_UndoPlayerMorph(player, player);
|
||||
}
|
||||
|
||||
// player is now alive.
|
||||
// fire E_PlayerRespawned and start the ACS SCRIPT_Respawn.
|
||||
E_PlayerRespawned(int(player - players));
|
||||
//
|
||||
FBehavior::StaticStartTypedScripts(SCRIPT_Respawn, player->mo, true);
|
||||
player->Resurrect();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -280,6 +280,7 @@ void DMenu::CallDrawer()
|
|||
{
|
||||
VMValue params[] = { (DObject*)this };
|
||||
GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr);
|
||||
screen->ClearClipRect(); // make sure the scripts don't leave a valid clipping rect behind.
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -901,3 +901,4 @@ xx(Player5)
|
|||
xx(Player6)
|
||||
xx(Player7)
|
||||
xx(Player8)
|
||||
xx(PlayerChunk)
|
||||
|
|
|
@ -654,6 +654,36 @@ DEFINE_ACTION_FUNCTION(AActor, GetCVar)
|
|||
return 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// GetCVar
|
||||
//
|
||||
// NON-ACTION function that works like ACS's GetCVar.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, GetCVarString)
|
||||
{
|
||||
if (numret > 0)
|
||||
{
|
||||
assert(ret != nullptr);
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_STRING(cvarname);
|
||||
|
||||
FBaseCVar *cvar = GetCVar(self, cvarname);
|
||||
if (cvar == nullptr)
|
||||
{
|
||||
ret->SetString("");
|
||||
}
|
||||
else
|
||||
{
|
||||
ret->SetString(cvar->GetGenericRep(CVAR_String).String);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// GetPlayerInput
|
||||
|
|
|
@ -1045,6 +1045,12 @@ AInventory *AActor::FirstInv ()
|
|||
return Inventory->NextInv ();
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, FirstInv)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
ACTION_RETURN_OBJECT(self->FirstInv());
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// AActor :: UseInventory
|
||||
|
|
|
@ -62,6 +62,8 @@
|
|||
#include "g_levellocals.h"
|
||||
#include "actorinlines.h"
|
||||
#include "r_data/r_translate.h"
|
||||
#include "p_acs.h"
|
||||
#include "events.h"
|
||||
|
||||
static FRandom pr_skullpop ("SkullPop");
|
||||
|
||||
|
@ -707,6 +709,65 @@ void player_t::SendPitchLimits() const
|
|||
}
|
||||
|
||||
|
||||
bool player_t::HasWeaponsInSlot(int slot) const
|
||||
{
|
||||
for (int i = 0; i < weapons.Slots[slot].Size(); i++)
|
||||
{
|
||||
PClassActor *weap = weapons.Slots[slot].GetWeapon(i);
|
||||
if (weap != NULL && mo->FindInventory(weap)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(_PlayerInfo, HasWeaponsInSlot)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(player_t);
|
||||
PARAM_INT(slot);
|
||||
ACTION_RETURN_BOOL(self->HasWeaponsInSlot(slot));
|
||||
}
|
||||
|
||||
|
||||
bool player_t::Resurrect()
|
||||
{
|
||||
if (mo == nullptr || mo->IsKindOf(NAME_PlayerChunk)) return false;
|
||||
mo->Revive();
|
||||
playerstate = PST_LIVE;
|
||||
health = mo->health = mo->GetDefault()->health;
|
||||
viewheight = ((APlayerPawn *)mo->GetDefault())->ViewHeight;
|
||||
mo->renderflags &= ~RF_INVISIBLE;
|
||||
mo->Height = mo->GetDefault()->Height;
|
||||
mo->radius = mo->GetDefault()->radius;
|
||||
mo->special1 = 0; // required for the Hexen fighter's fist attack.
|
||||
// This gets set by AActor::Die as flag for the wimpy death and must be reset here.
|
||||
mo->SetState(mo->SpawnState);
|
||||
if (!(mo->flags2 & MF2_DONTTRANSLATE))
|
||||
{
|
||||
mo->Translation = TRANSLATION(TRANSLATION_Players, uint8_t(this - players));
|
||||
}
|
||||
if (ReadyWeapon != nullptr)
|
||||
{
|
||||
P_SetPsprite(this, PSP_WEAPON, ReadyWeapon->GetUpState());
|
||||
}
|
||||
|
||||
if (morphTics)
|
||||
{
|
||||
P_UndoPlayerMorph(this, this);
|
||||
}
|
||||
|
||||
// player is now alive.
|
||||
// fire E_PlayerRespawned and start the ACS SCRIPT_Respawn.
|
||||
E_PlayerRespawned(int(this - players));
|
||||
//
|
||||
FBehavior::StaticStartTypedScripts(SCRIPT_Respawn, mo, true);
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(_PlayerInfo, Resurrect)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(player_t);
|
||||
ACTION_RETURN_BOOL(self->Resurrect());
|
||||
}
|
||||
|
||||
|
||||
DEFINE_ACTION_FUNCTION(_PlayerInfo, GetUserName)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(player_t);
|
||||
|
|
|
@ -45,6 +45,14 @@ void PolyDrawArgs::SetClipPlane(const PolyClipPlane &plane)
|
|||
mClipPlane[3] = plane.D;
|
||||
}
|
||||
|
||||
void PolyDrawArgs::SetTexture(const uint8_t *texels, int width, int height)
|
||||
{
|
||||
mTexturePixels = texels;
|
||||
mTextureWidth = width;
|
||||
mTextureHeight = height;
|
||||
mTranslation = nullptr;
|
||||
}
|
||||
|
||||
void PolyDrawArgs::SetTexture(FTexture *texture)
|
||||
{
|
||||
mTextureWidth = texture->GetWidth();
|
||||
|
@ -132,3 +140,214 @@ void PolyDrawArgs::DrawArray(const TriVertex *vertices, int vcount, PolyDrawMode
|
|||
mDrawMode = mode;
|
||||
PolyRenderer::Instance()->DrawQueue->Push<DrawPolyTrianglesCommand>(*this, PolyTriangleDrawer::is_mirror());
|
||||
}
|
||||
|
||||
void PolyDrawArgs::SetStyle(const FRenderStyle &renderstyle, double alpha, uint32_t fillcolor, uint32_t translationID, FTexture *tex, bool fullbright)
|
||||
{
|
||||
bool forcePal = (renderstyle == LegacyRenderStyles[STYLE_Shaded] || renderstyle == LegacyRenderStyles[STYLE_AddShaded]);
|
||||
SetTexture(tex, translationID, forcePal);
|
||||
|
||||
if (renderstyle == LegacyRenderStyles[STYLE_Normal] || (r_drawfuzz == 0 && renderstyle == LegacyRenderStyles[STYLE_OptFuzzy]))
|
||||
{
|
||||
SetStyle(Translation() ? TriBlendMode::TranslatedAdd : TriBlendMode::TextureAdd, 1.0, 0.0);
|
||||
}
|
||||
else if (renderstyle == LegacyRenderStyles[STYLE_Add] && fullbright && alpha == 1.0 && !Translation())
|
||||
{
|
||||
SetStyle(TriBlendMode::TextureAddSrcColor, 1.0, 1.0);
|
||||
}
|
||||
else if (renderstyle == LegacyRenderStyles[STYLE_Add])
|
||||
{
|
||||
SetStyle(Translation() ? TriBlendMode::TranslatedAdd : TriBlendMode::TextureAdd, alpha, 1.0);
|
||||
}
|
||||
else if (renderstyle == LegacyRenderStyles[STYLE_Subtract])
|
||||
{
|
||||
SetStyle(Translation() ? TriBlendMode::TranslatedRevSub : TriBlendMode::TextureRevSub, alpha, 1.0);
|
||||
}
|
||||
else if (renderstyle == LegacyRenderStyles[STYLE_SoulTrans])
|
||||
{
|
||||
SetStyle(Translation() ? TriBlendMode::TranslatedAdd : TriBlendMode::TextureAdd, transsouls, 1.0 - transsouls);
|
||||
}
|
||||
else if (renderstyle == LegacyRenderStyles[STYLE_Fuzzy] || (r_drawfuzz == 2 && renderstyle == LegacyRenderStyles[STYLE_OptFuzzy]))
|
||||
{ // NYI - Fuzzy - for now, just a copy of "Shadow"
|
||||
SetStyle(Translation() ? TriBlendMode::TranslatedAdd : TriBlendMode::TextureAdd, 0.0, 160 / 255.0);
|
||||
}
|
||||
else if (renderstyle == LegacyRenderStyles[STYLE_Shadow] || (r_drawfuzz == 1 && renderstyle == LegacyRenderStyles[STYLE_OptFuzzy]))
|
||||
{
|
||||
SetStyle(Translation() ? TriBlendMode::TranslatedAdd : TriBlendMode::TextureAdd, 0.0, 160 / 255.0);
|
||||
}
|
||||
else if (renderstyle == LegacyRenderStyles[STYLE_TranslucentStencil])
|
||||
{
|
||||
SetColor(0xff000000 | fillcolor, fillcolor >> 24);
|
||||
SetStyle(TriBlendMode::Stencil, alpha, 1.0 - alpha);
|
||||
}
|
||||
else if (renderstyle == LegacyRenderStyles[STYLE_AddStencil])
|
||||
{
|
||||
SetColor(0xff000000 | fillcolor, fillcolor >> 24);
|
||||
SetStyle(TriBlendMode::AddStencil, alpha, 1.0);
|
||||
}
|
||||
else if (renderstyle == LegacyRenderStyles[STYLE_Shaded])
|
||||
{
|
||||
SetColor(0xff000000 | fillcolor, fillcolor >> 24);
|
||||
SetStyle(TriBlendMode::Shaded, alpha, 1.0 - alpha);
|
||||
}
|
||||
else if (renderstyle == LegacyRenderStyles[STYLE_AddShaded])
|
||||
{
|
||||
SetColor(0xff000000 | fillcolor, fillcolor >> 24);
|
||||
SetStyle(TriBlendMode::AddShaded, alpha, 1.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetStyle(Translation() ? TriBlendMode::TranslatedAdd : TriBlendMode::TextureAdd, alpha, 1.0 - alpha);
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void RectDrawArgs::SetTexture(const uint8_t *texels, int width, int height)
|
||||
{
|
||||
mTexturePixels = texels;
|
||||
mTextureWidth = width;
|
||||
mTextureHeight = height;
|
||||
mTranslation = nullptr;
|
||||
}
|
||||
|
||||
void RectDrawArgs::SetTexture(FTexture *texture)
|
||||
{
|
||||
mTextureWidth = texture->GetWidth();
|
||||
mTextureHeight = texture->GetHeight();
|
||||
if (PolyRenderer::Instance()->RenderTarget->IsBgra())
|
||||
mTexturePixels = (const uint8_t *)texture->GetPixelsBgra();
|
||||
else
|
||||
mTexturePixels = texture->GetPixels();
|
||||
mTranslation = nullptr;
|
||||
}
|
||||
|
||||
void RectDrawArgs::SetTexture(FTexture *texture, uint32_t translationID, bool forcePal)
|
||||
{
|
||||
if (translationID != 0xffffffff && translationID != 0)
|
||||
{
|
||||
FRemapTable *table = TranslationToTable(translationID);
|
||||
if (table != nullptr && !table->Inactive)
|
||||
{
|
||||
if (PolyRenderer::Instance()->RenderTarget->IsBgra())
|
||||
mTranslation = (uint8_t*)table->Palette;
|
||||
else
|
||||
mTranslation = table->Remap;
|
||||
|
||||
mTextureWidth = texture->GetWidth();
|
||||
mTextureHeight = texture->GetHeight();
|
||||
mTexturePixels = texture->GetPixels();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (forcePal)
|
||||
{
|
||||
mTextureWidth = texture->GetWidth();
|
||||
mTextureHeight = texture->GetHeight();
|
||||
mTexturePixels = texture->GetPixels();
|
||||
}
|
||||
else
|
||||
{
|
||||
SetTexture(texture);
|
||||
}
|
||||
}
|
||||
|
||||
void RectDrawArgs::SetLight(FSWColormap *base_colormap, uint32_t lightlevel)
|
||||
{
|
||||
mLight = clamp<uint32_t>(lightlevel, 0, 255);
|
||||
mLightRed = base_colormap->Color.r * 256 / 255;
|
||||
mLightGreen = base_colormap->Color.g * 256 / 255;
|
||||
mLightBlue = base_colormap->Color.b * 256 / 255;
|
||||
mLightAlpha = base_colormap->Color.a * 256 / 255;
|
||||
mFadeRed = base_colormap->Fade.r;
|
||||
mFadeGreen = base_colormap->Fade.g;
|
||||
mFadeBlue = base_colormap->Fade.b;
|
||||
mFadeAlpha = base_colormap->Fade.a;
|
||||
mDesaturate = MIN(abs(base_colormap->Desaturate), 255) * 255 / 256;
|
||||
mSimpleShade = (base_colormap->Color.d == 0x00ffffff && base_colormap->Fade.d == 0x00000000 && base_colormap->Desaturate == 0);
|
||||
mColormaps = base_colormap->Maps;
|
||||
}
|
||||
|
||||
void RectDrawArgs::SetColor(uint32_t bgra, uint8_t palindex)
|
||||
{
|
||||
if (PolyRenderer::Instance()->RenderTarget->IsBgra())
|
||||
{
|
||||
mColor = bgra;
|
||||
}
|
||||
else
|
||||
{
|
||||
mColor = palindex;
|
||||
}
|
||||
}
|
||||
|
||||
void RectDrawArgs::Draw(double x0, double x1, double y0, double y1, double u0, double u1, double v0, double v1)
|
||||
{
|
||||
mX0 = (float)x0;
|
||||
mX1 = (float)x1;
|
||||
mY0 = (float)y0;
|
||||
mY1 = (float)y1;
|
||||
mU0 = (float)u0;
|
||||
mU1 = (float)u1;
|
||||
mV0 = (float)v0;
|
||||
mV1 = (float)v1;
|
||||
PolyRenderer::Instance()->DrawQueue->Push<DrawRectCommand>(*this);
|
||||
}
|
||||
|
||||
void RectDrawArgs::SetStyle(const FRenderStyle &renderstyle, double alpha, uint32_t fillcolor, uint32_t translationID, FTexture *tex, bool fullbright)
|
||||
{
|
||||
bool forcePal = (renderstyle == LegacyRenderStyles[STYLE_Shaded] || renderstyle == LegacyRenderStyles[STYLE_AddShaded]);
|
||||
SetTexture(tex, translationID, forcePal);
|
||||
|
||||
if (renderstyle == LegacyRenderStyles[STYLE_Normal] || (r_drawfuzz == 0 && renderstyle == LegacyRenderStyles[STYLE_OptFuzzy]))
|
||||
{
|
||||
SetStyle(Translation() ? TriBlendMode::TranslatedAdd : TriBlendMode::TextureAdd, 1.0, 0.0);
|
||||
}
|
||||
else if (renderstyle == LegacyRenderStyles[STYLE_Add] && fullbright && alpha == 1.0 && !Translation())
|
||||
{
|
||||
SetStyle(TriBlendMode::TextureAddSrcColor, 1.0, 1.0);
|
||||
}
|
||||
else if (renderstyle == LegacyRenderStyles[STYLE_Add])
|
||||
{
|
||||
SetStyle(Translation() ? TriBlendMode::TranslatedAdd : TriBlendMode::TextureAdd, alpha, 1.0);
|
||||
}
|
||||
else if (renderstyle == LegacyRenderStyles[STYLE_Subtract])
|
||||
{
|
||||
SetStyle(Translation() ? TriBlendMode::TranslatedRevSub : TriBlendMode::TextureRevSub, alpha, 1.0);
|
||||
}
|
||||
else if (renderstyle == LegacyRenderStyles[STYLE_SoulTrans])
|
||||
{
|
||||
SetStyle(Translation() ? TriBlendMode::TranslatedAdd : TriBlendMode::TextureAdd, transsouls, 1.0 - transsouls);
|
||||
}
|
||||
else if (renderstyle == LegacyRenderStyles[STYLE_Fuzzy] || (r_drawfuzz == 2 && renderstyle == LegacyRenderStyles[STYLE_OptFuzzy]))
|
||||
{ // NYI - Fuzzy - for now, just a copy of "Shadow"
|
||||
SetStyle(Translation() ? TriBlendMode::TranslatedAdd : TriBlendMode::TextureAdd, 0.0, 160 / 255.0);
|
||||
}
|
||||
else if (renderstyle == LegacyRenderStyles[STYLE_Shadow] || (r_drawfuzz == 1 && renderstyle == LegacyRenderStyles[STYLE_OptFuzzy]))
|
||||
{
|
||||
SetStyle(Translation() ? TriBlendMode::TranslatedAdd : TriBlendMode::TextureAdd, 0.0, 160 / 255.0);
|
||||
}
|
||||
else if (renderstyle == LegacyRenderStyles[STYLE_TranslucentStencil])
|
||||
{
|
||||
SetColor(0xff000000 | fillcolor, fillcolor >> 24);
|
||||
SetStyle(TriBlendMode::Stencil, alpha, 1.0 - alpha);
|
||||
}
|
||||
else if (renderstyle == LegacyRenderStyles[STYLE_AddStencil])
|
||||
{
|
||||
SetColor(0xff000000 | fillcolor, fillcolor >> 24);
|
||||
SetStyle(TriBlendMode::AddStencil, alpha, 1.0);
|
||||
}
|
||||
else if (renderstyle == LegacyRenderStyles[STYLE_Shaded])
|
||||
{
|
||||
SetColor(0xff000000 | fillcolor, fillcolor >> 24);
|
||||
SetStyle(TriBlendMode::Shaded, alpha, 1.0 - alpha);
|
||||
}
|
||||
else if (renderstyle == LegacyRenderStyles[STYLE_AddShaded])
|
||||
{
|
||||
SetColor(0xff000000 | fillcolor, fillcolor >> 24);
|
||||
SetStyle(TriBlendMode::AddShaded, alpha, 1.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetStyle(Translation() ? TriBlendMode::TranslatedAdd : TriBlendMode::TextureAdd, alpha, 1.0 - alpha);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@ class PolyDrawArgs
|
|||
{
|
||||
public:
|
||||
void SetClipPlane(const PolyClipPlane &plane);
|
||||
void SetTexture(const uint8_t *texels, int width, int height);
|
||||
void SetTexture(FTexture *texture);
|
||||
void SetTexture(FTexture *texture, uint32_t translationID, bool forcePal = false);
|
||||
void SetLight(FSWColormap *basecolormap, uint32_t lightlevel, double globVis, bool fixed);
|
||||
|
@ -60,6 +61,7 @@ public:
|
|||
void SetWriteSubsectorDepth(bool enable) { mWriteSubsector = enable; }
|
||||
void SetFaceCullCCW(bool counterclockwise) { mFaceCullCCW = counterclockwise; }
|
||||
void SetStyle(TriBlendMode blendmode, double srcalpha = 1.0, double destalpha = 1.0) { mBlendMode = blendmode; mSrcAlpha = (uint32_t)(srcalpha * 256.0 + 0.5); mDestAlpha = (uint32_t)(destalpha * 256.0 + 0.5); }
|
||||
void SetStyle(const FRenderStyle &renderstyle, double alpha, uint32_t fillcolor, uint32_t translationID, FTexture *texture, bool fullbright);
|
||||
void SetTransform(const TriMatrix *objectToClip) { mObjectToClip = objectToClip; }
|
||||
void SetColor(uint32_t bgra, uint8_t palindex);
|
||||
void DrawArray(const TriVertex *vertices, int vcount, PolyDrawMode mode = PolyDrawMode::Triangles);
|
||||
|
@ -127,7 +129,7 @@ private:
|
|||
uint8_t mStencilWriteValue = 0;
|
||||
const uint8_t *mColormaps = nullptr;
|
||||
float mClipPlane[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
|
||||
TriBlendMode mBlendMode = TriBlendMode::Copy;
|
||||
TriBlendMode mBlendMode = TriBlendMode::FillOpaque;
|
||||
uint32_t mLight = 0;
|
||||
uint32_t mSubsectorDepth = 0;
|
||||
uint32_t mColor = 0;
|
||||
|
@ -147,3 +149,71 @@ private:
|
|||
bool mNearestFilter = true;
|
||||
bool mFixedLight = false;
|
||||
};
|
||||
|
||||
class RectDrawArgs
|
||||
{
|
||||
public:
|
||||
void SetTexture(const uint8_t *texels, int width, int height);
|
||||
void SetTexture(FTexture *texture);
|
||||
void SetTexture(FTexture *texture, uint32_t translationID, bool forcePal = false);
|
||||
void SetLight(FSWColormap *basecolormap, uint32_t lightlevel);
|
||||
void SetStyle(TriBlendMode blendmode, double srcalpha = 1.0, double destalpha = 1.0) { mBlendMode = blendmode; mSrcAlpha = (uint32_t)(srcalpha * 256.0 + 0.5); mDestAlpha = (uint32_t)(destalpha * 256.0 + 0.5); }
|
||||
void SetStyle(const FRenderStyle &renderstyle, double alpha, uint32_t fillcolor, uint32_t translationID, FTexture *texture, bool fullbright);
|
||||
void SetColor(uint32_t bgra, uint8_t palindex);
|
||||
void Draw(double x0, double x1, double y0, double y1, double u0, double u1, double v0, double v1);
|
||||
|
||||
const uint8_t *TexturePixels() const { return mTexturePixels; }
|
||||
int TextureWidth() const { return mTextureWidth; }
|
||||
int TextureHeight() const { return mTextureHeight; }
|
||||
const uint8_t *Translation() const { return mTranslation; }
|
||||
|
||||
TriBlendMode BlendMode() const { return mBlendMode; }
|
||||
uint32_t Color() const { return mColor; }
|
||||
uint32_t SrcAlpha() const { return mSrcAlpha; }
|
||||
uint32_t DestAlpha() const { return mDestAlpha; }
|
||||
|
||||
uint32_t Light() const { return mLight; }
|
||||
const uint8_t *BaseColormap() const { return mColormaps; }
|
||||
uint16_t ShadeLightAlpha() const { return mLightAlpha; }
|
||||
uint16_t ShadeLightRed() const { return mLightRed; }
|
||||
uint16_t ShadeLightGreen() const { return mLightGreen; }
|
||||
uint16_t ShadeLightBlue() const { return mLightBlue; }
|
||||
uint16_t ShadeFadeAlpha() const { return mFadeAlpha; }
|
||||
uint16_t ShadeFadeRed() const { return mFadeRed; }
|
||||
uint16_t ShadeFadeGreen() const { return mFadeGreen; }
|
||||
uint16_t ShadeFadeBlue() const { return mFadeBlue; }
|
||||
uint16_t ShadeDesaturate() const { return mDesaturate; }
|
||||
bool SimpleShade() const { return mSimpleShade; }
|
||||
|
||||
float X0() const { return mX0; }
|
||||
float X1() const { return mX1; }
|
||||
float Y0() const { return mY0; }
|
||||
float Y1() const { return mY1; }
|
||||
float U0() const { return mU0; }
|
||||
float U1() const { return mU1; }
|
||||
float V0() const { return mV0; }
|
||||
float V1() const { return mV1; }
|
||||
|
||||
private:
|
||||
const uint8_t *mTexturePixels = nullptr;
|
||||
int mTextureWidth = 0;
|
||||
int mTextureHeight = 0;
|
||||
const uint8_t *mTranslation = nullptr;
|
||||
const uint8_t *mColormaps = nullptr;
|
||||
TriBlendMode mBlendMode = TriBlendMode::FillOpaque;
|
||||
uint32_t mLight = 0;
|
||||
uint32_t mColor = 0;
|
||||
uint32_t mSrcAlpha = 0;
|
||||
uint32_t mDestAlpha = 0;
|
||||
uint16_t mLightAlpha = 0;
|
||||
uint16_t mLightRed = 0;
|
||||
uint16_t mLightGreen = 0;
|
||||
uint16_t mLightBlue = 0;
|
||||
uint16_t mFadeAlpha = 0;
|
||||
uint16_t mFadeRed = 0;
|
||||
uint16_t mFadeGreen = 0;
|
||||
uint16_t mFadeBlue = 0;
|
||||
uint16_t mDesaturate = 0;
|
||||
bool mSimpleShade = true;
|
||||
float mX0, mX1, mY0, mY1, mU0, mU1, mV0, mV1;
|
||||
};
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -24,255 +24,13 @@
|
|||
|
||||
#include "screen_triangle.h"
|
||||
|
||||
template<typename BlendT, typename SamplerT>
|
||||
class TriScreenDrawer8
|
||||
namespace TriScreenDrawerModes
|
||||
{
|
||||
public:
|
||||
static void Execute(const TriDrawTriangleArgs *args, WorkerThreadData *thread)
|
||||
template<typename SamplerT>
|
||||
FORCEINLINE unsigned int Sample8(int32_t u, int32_t v, const uint8_t *texPixels, int texWidth, int texHeight, uint32_t color, const uint8_t *translation)
|
||||
{
|
||||
using namespace TriScreenDrawerModes;
|
||||
|
||||
int numSpans = thread->NumFullSpans;
|
||||
auto fullSpans = thread->FullSpans;
|
||||
int numBlocks = thread->NumPartialBlocks;
|
||||
auto partialBlocks = thread->PartialBlocks;
|
||||
int startX = thread->StartX;
|
||||
int startY = thread->StartY;
|
||||
|
||||
bool is_fixed_light = args->uniforms->FixedLight();
|
||||
uint32_t lightmask = is_fixed_light ? 0 : 0xffffffff;
|
||||
auto colormaps = args->uniforms->BaseColormap();
|
||||
uint32_t srcalpha = args->uniforms->SrcAlpha();
|
||||
uint32_t destalpha = args->uniforms->DestAlpha();
|
||||
|
||||
// Calculate gradients
|
||||
const TriVertex &v1 = *args->v1;
|
||||
const TriVertex &v2 = *args->v2;
|
||||
const TriVertex &v3 = *args->v3;
|
||||
ScreenTriangleStepVariables gradientX;
|
||||
ScreenTriangleStepVariables gradientY;
|
||||
ScreenTriangleStepVariables start;
|
||||
gradientX.W = FindGradientX(v1.x, v1.y, v2.x, v2.y, v3.x, v3.y, v1.w, v2.w, v3.w);
|
||||
gradientY.W = FindGradientY(v1.x, v1.y, v2.x, v2.y, v3.x, v3.y, v1.w, v2.w, v3.w);
|
||||
start.W = v1.w + gradientX.W * (startX - v1.x) + gradientY.W * (startY - v1.y);
|
||||
for (int i = 0; i < TriVertex::NumVarying; i++)
|
||||
{
|
||||
gradientX.Varying[i] = FindGradientX(v1.x, v1.y, v2.x, v2.y, v3.x, v3.y, v1.varying[i] * v1.w, v2.varying[i] * v2.w, v3.varying[i] * v3.w);
|
||||
gradientY.Varying[i] = FindGradientY(v1.x, v1.y, v2.x, v2.y, v3.x, v3.y, v1.varying[i] * v1.w, v2.varying[i] * v2.w, v3.varying[i] * v3.w);
|
||||
start.Varying[i] = v1.varying[i] * v1.w + gradientX.Varying[i] * (startX - v1.x) + gradientY.Varying[i] * (startY - v1.y);
|
||||
}
|
||||
|
||||
// Output
|
||||
uint8_t * RESTRICT destOrg = args->dest;
|
||||
int pitch = args->pitch;
|
||||
|
||||
// Light
|
||||
uint32_t light = args->uniforms->Light();
|
||||
float shade = 2.0f - (light + 12.0f) / 128.0f;
|
||||
float globVis = args->uniforms->GlobVis() * (1.0f / 32.0f);
|
||||
light += light >> 7; // 255 -> 256
|
||||
|
||||
// Sampling stuff
|
||||
uint32_t color = args->uniforms->Color();
|
||||
const uint8_t * RESTRICT translation = args->uniforms->Translation();
|
||||
const uint8_t * RESTRICT texPixels = args->uniforms->TexturePixels();
|
||||
uint32_t texWidth = args->uniforms->TextureWidth();
|
||||
uint32_t texHeight = args->uniforms->TextureHeight();
|
||||
|
||||
for (int i = 0; i < numSpans; i++)
|
||||
{
|
||||
const auto &span = fullSpans[i];
|
||||
|
||||
uint8_t *dest = destOrg + span.X + span.Y * pitch;
|
||||
int width = span.Length;
|
||||
int height = 8;
|
||||
|
||||
ScreenTriangleStepVariables blockPosY;
|
||||
blockPosY.W = start.W + gradientX.W * (span.X - startX) + gradientY.W * (span.Y - startY);
|
||||
for (int j = 0; j < TriVertex::NumVarying; j++)
|
||||
blockPosY.Varying[j] = start.Varying[j] + gradientX.Varying[j] * (span.X - startX) + gradientY.Varying[j] * (span.Y - startY);
|
||||
|
||||
for (int y = 0; y < height; y++)
|
||||
{
|
||||
ScreenTriangleStepVariables blockPosX = blockPosY;
|
||||
|
||||
float rcpW = 0x01000000 / blockPosX.W;
|
||||
int32_t varyingPos[TriVertex::NumVarying];
|
||||
for (int j = 0; j < TriVertex::NumVarying; j++)
|
||||
varyingPos[j] = (int32_t)(blockPosX.Varying[j] * rcpW);
|
||||
|
||||
fixed_t lightpos = FRACUNIT - (int)(clamp(shade - MIN(24.0f / 32.0f, globVis * blockPosY.W), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT);
|
||||
lightpos = (lightpos & lightmask) | ((light << 8) & ~lightmask);
|
||||
|
||||
for (int x = 0; x < width; x++)
|
||||
{
|
||||
blockPosX.W += gradientX.W * 8;
|
||||
for (int j = 0; j < TriVertex::NumVarying; j++)
|
||||
blockPosX.Varying[j] += gradientX.Varying[j] * 8;
|
||||
|
||||
rcpW = 0x01000000 / blockPosX.W;
|
||||
int32_t varyingStep[TriVertex::NumVarying];
|
||||
for (int j = 0; j < TriVertex::NumVarying; j++)
|
||||
{
|
||||
int32_t nextPos = (int32_t)(blockPosX.Varying[j] * rcpW);
|
||||
varyingStep[j] = (nextPos - varyingPos[j]) / 8;
|
||||
}
|
||||
|
||||
fixed_t lightnext = FRACUNIT - (fixed_t)(clamp(shade - MIN(24.0f / 32.0f, globVis * blockPosX.W), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT);
|
||||
fixed_t lightstep = (lightnext - lightpos) / 8;
|
||||
lightstep = lightstep & lightmask;
|
||||
|
||||
for (int ix = 0; ix < 8; ix++)
|
||||
{
|
||||
int lightshade = lightpos >> 8;
|
||||
uint8_t bgcolor = dest[x * 8 + ix];
|
||||
uint8_t fgcolor = Sample(varyingPos[0], varyingPos[1], texPixels, texWidth, texHeight, color, translation);
|
||||
uint32_t fgshade = SampleShade(varyingPos[0], varyingPos[1], texPixels, texWidth, texHeight);
|
||||
dest[x * 8 + ix] = ShadeAndBlend(fgcolor, bgcolor, fgshade, lightshade, colormaps, srcalpha, destalpha);
|
||||
for (int j = 0; j < TriVertex::NumVarying; j++)
|
||||
varyingPos[j] += varyingStep[j];
|
||||
lightpos += lightstep;
|
||||
}
|
||||
}
|
||||
|
||||
blockPosY.W += gradientY.W;
|
||||
for (int j = 0; j < TriVertex::NumVarying; j++)
|
||||
blockPosY.Varying[j] += gradientY.Varying[j];
|
||||
|
||||
dest += pitch;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < numBlocks; i++)
|
||||
{
|
||||
const auto &block = partialBlocks[i];
|
||||
|
||||
ScreenTriangleStepVariables blockPosY;
|
||||
blockPosY.W = start.W + gradientX.W * (block.X - startX) + gradientY.W * (block.Y - startY);
|
||||
for (int j = 0; j < TriVertex::NumVarying; j++)
|
||||
blockPosY.Varying[j] = start.Varying[j] + gradientX.Varying[j] * (block.X - startX) + gradientY.Varying[j] * (block.Y - startY);
|
||||
|
||||
uint8_t *dest = destOrg + block.X + block.Y * pitch;
|
||||
uint32_t mask0 = block.Mask0;
|
||||
uint32_t mask1 = block.Mask1;
|
||||
|
||||
// mask0 loop:
|
||||
for (int y = 0; y < 4; y++)
|
||||
{
|
||||
ScreenTriangleStepVariables blockPosX = blockPosY;
|
||||
|
||||
float rcpW = 0x01000000 / blockPosX.W;
|
||||
int32_t varyingPos[TriVertex::NumVarying];
|
||||
for (int j = 0; j < TriVertex::NumVarying; j++)
|
||||
varyingPos[j] = (int32_t)(blockPosX.Varying[j] * rcpW);
|
||||
|
||||
fixed_t lightpos = FRACUNIT - (fixed_t)(clamp(shade - MIN(24.0f / 32.0f, globVis * blockPosY.W), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT);
|
||||
lightpos = (lightpos & lightmask) | ((light << 8) & ~lightmask);
|
||||
|
||||
blockPosX.W += gradientX.W * 8;
|
||||
for (int j = 0; j < TriVertex::NumVarying; j++)
|
||||
blockPosX.Varying[j] += gradientX.Varying[j] * 8;
|
||||
|
||||
rcpW = 0x01000000 / blockPosX.W;
|
||||
int32_t varyingStep[TriVertex::NumVarying];
|
||||
for (int j = 0; j < TriVertex::NumVarying; j++)
|
||||
{
|
||||
int32_t nextPos = (int32_t)(blockPosX.Varying[j] * rcpW);
|
||||
varyingStep[j] = (nextPos - varyingPos[j]) / 8;
|
||||
}
|
||||
|
||||
fixed_t lightnext = FRACUNIT - (fixed_t)(clamp(shade - MIN(24.0f / 32.0f, globVis * blockPosX.W), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT);
|
||||
fixed_t lightstep = (lightnext - lightpos) / 8;
|
||||
lightstep = lightstep & lightmask;
|
||||
|
||||
for (int x = 0; x < 8; x++)
|
||||
{
|
||||
if (mask0 & (1 << 31))
|
||||
{
|
||||
int lightshade = lightpos >> 8;
|
||||
uint8_t bgcolor = dest[x];
|
||||
uint8_t fgcolor = Sample(varyingPos[0], varyingPos[1], texPixels, texWidth, texHeight, color, translation);
|
||||
uint32_t fgshade = SampleShade(varyingPos[0], varyingPos[1], texPixels, texWidth, texHeight);
|
||||
dest[x] = ShadeAndBlend(fgcolor, bgcolor, fgshade, lightshade, colormaps, srcalpha, destalpha);
|
||||
}
|
||||
|
||||
for (int j = 0; j < TriVertex::NumVarying; j++)
|
||||
varyingPos[j] += varyingStep[j];
|
||||
lightpos += lightstep;
|
||||
|
||||
mask0 <<= 1;
|
||||
}
|
||||
|
||||
blockPosY.W += gradientY.W;
|
||||
for (int j = 0; j < TriVertex::NumVarying; j++)
|
||||
blockPosY.Varying[j] += gradientY.Varying[j];
|
||||
|
||||
dest += pitch;
|
||||
}
|
||||
|
||||
// mask1 loop:
|
||||
for (int y = 0; y < 4; y++)
|
||||
{
|
||||
ScreenTriangleStepVariables blockPosX = blockPosY;
|
||||
|
||||
float rcpW = 0x01000000 / blockPosX.W;
|
||||
int32_t varyingPos[TriVertex::NumVarying];
|
||||
for (int j = 0; j < TriVertex::NumVarying; j++)
|
||||
varyingPos[j] = (int32_t)(blockPosX.Varying[j] * rcpW);
|
||||
|
||||
fixed_t lightpos = FRACUNIT - (fixed_t)(clamp(shade - MIN(24.0f / 32.0f, globVis * blockPosY.W), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT);
|
||||
lightpos = (lightpos & lightmask) | ((light << 8) & ~lightmask);
|
||||
|
||||
blockPosX.W += gradientX.W * 8;
|
||||
for (int j = 0; j < TriVertex::NumVarying; j++)
|
||||
blockPosX.Varying[j] += gradientX.Varying[j] * 8;
|
||||
|
||||
rcpW = 0x01000000 / blockPosX.W;
|
||||
int32_t varyingStep[TriVertex::NumVarying];
|
||||
for (int j = 0; j < TriVertex::NumVarying; j++)
|
||||
{
|
||||
int32_t nextPos = (int32_t)(blockPosX.Varying[j] * rcpW);
|
||||
varyingStep[j] = (nextPos - varyingPos[j]) / 8;
|
||||
}
|
||||
|
||||
fixed_t lightnext = FRACUNIT - (fixed_t)(clamp(shade - MIN(24.0f / 32.0f, globVis * blockPosX.W), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT);
|
||||
fixed_t lightstep = (lightnext - lightpos) / 8;
|
||||
lightstep = lightstep & lightmask;
|
||||
|
||||
for (int x = 0; x < 8; x++)
|
||||
{
|
||||
if (mask1 & (1 << 31))
|
||||
{
|
||||
int lightshade = lightpos >> 8;
|
||||
uint8_t bgcolor = dest[x];
|
||||
uint8_t fgcolor = Sample(varyingPos[0], varyingPos[1], texPixels, texWidth, texHeight, color, translation);
|
||||
uint32_t fgshade = SampleShade(varyingPos[0], varyingPos[1], texPixels, texWidth, texHeight);
|
||||
dest[x] = ShadeAndBlend(fgcolor, bgcolor, fgshade, lightshade, colormaps, srcalpha, destalpha);
|
||||
}
|
||||
|
||||
for (int j = 0; j < TriVertex::NumVarying; j++)
|
||||
varyingPos[j] += varyingStep[j];
|
||||
lightpos += lightstep;
|
||||
|
||||
mask1 <<= 1;
|
||||
}
|
||||
|
||||
blockPosY.W += gradientY.W;
|
||||
for (int j = 0; j < TriVertex::NumVarying; j++)
|
||||
blockPosY.Varying[j] += gradientY.Varying[j];
|
||||
|
||||
dest += pitch;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
FORCEINLINE static unsigned int Sample(int32_t u, int32_t v, const uint8_t *texPixels, int texWidth, int texHeight, uint32_t color, const uint8_t *translation)
|
||||
{
|
||||
using namespace TriScreenDrawerModes;
|
||||
|
||||
uint8_t texel;
|
||||
if (SamplerT::Mode == (int)Samplers::Shaded || SamplerT::Mode == (int)Samplers::Fill)
|
||||
if (SamplerT::Mode == (int)Samplers::Shaded || SamplerT::Mode == (int)Samplers::Stencil || SamplerT::Mode == (int)Samplers::Fill)
|
||||
{
|
||||
return color;
|
||||
}
|
||||
|
@ -301,13 +59,14 @@ private:
|
|||
if (a == 256)
|
||||
return texel;
|
||||
|
||||
uint32_t capcolor = GPalette.BaseColors[color].d;
|
||||
uint32_t texelrgb = GPalette.BaseColors[texel].d;
|
||||
uint32_t r = RPART(texelrgb);
|
||||
uint32_t g = GPART(texelrgb);
|
||||
uint32_t b = BPART(texelrgb);
|
||||
uint32_t capcolor_red = RPART(color);
|
||||
uint32_t capcolor_green = GPART(color);
|
||||
uint32_t capcolor_blue = BPART(color);
|
||||
uint32_t capcolor_red = RPART(capcolor);
|
||||
uint32_t capcolor_green = GPART(capcolor);
|
||||
uint32_t capcolor_blue = BPART(capcolor);
|
||||
r = (r * a + capcolor_red * inv_a + 127) >> 8;
|
||||
g = (g * a + capcolor_green * inv_a + 127) >> 8;
|
||||
b = (b * a + capcolor_blue * inv_a + 127) >> 8;
|
||||
|
@ -319,10 +78,9 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
FORCEINLINE static unsigned int SampleShade(int32_t u, int32_t v, const uint8_t *texPixels, int texWidth, int texHeight)
|
||||
template<typename SamplerT>
|
||||
FORCEINLINE unsigned int SampleShade8(int32_t u, int32_t v, const uint8_t *texPixels, int texWidth, int texHeight)
|
||||
{
|
||||
using namespace TriScreenDrawerModes;
|
||||
|
||||
if (SamplerT::Mode == (int)Samplers::Shaded)
|
||||
{
|
||||
uint32_t texelX = ((((uint32_t)u << 8) >> 16) * texWidth) >> 16;
|
||||
|
@ -331,16 +89,21 @@ private:
|
|||
sampleshadeout += sampleshadeout >> 7; // 255 -> 256
|
||||
return sampleshadeout;
|
||||
}
|
||||
else if (SamplerT::Mode == (int)Samplers::Stencil)
|
||||
{
|
||||
uint32_t texelX = ((((uint32_t)u << 8) >> 16) * texWidth) >> 16;
|
||||
uint32_t texelY = ((((uint32_t)v << 8) >> 16) * texHeight) >> 16;
|
||||
return texPixels[texelX * texHeight + texelY] != 0 ? 256 : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
FORCEINLINE static uint8_t ShadeAndBlend(uint8_t fgcolor, uint8_t bgcolor, uint32_t fgshade, uint32_t lightshade, const uint8_t *colormaps, uint32_t srcalpha, uint32_t destalpha)
|
||||
template<typename BlendT>
|
||||
FORCEINLINE uint8_t ShadeAndBlend8(uint8_t fgcolor, uint8_t bgcolor, uint32_t fgshade, uint32_t lightshade, const uint8_t *colormaps, uint32_t srcalpha, uint32_t destalpha)
|
||||
{
|
||||
using namespace TriScreenDrawerModes;
|
||||
|
||||
lightshade = ((256 - lightshade) * NUMCOLORMAPS) & 0xffffff00;
|
||||
uint8_t shadedfg = colormaps[lightshade + fgcolor];
|
||||
|
||||
|
@ -372,6 +135,7 @@ private:
|
|||
}
|
||||
else if (BlendT::Mode == (int)BlendModes::Shaded)
|
||||
{
|
||||
fgshade = (fgshade * srcalpha + 128) >> 8;
|
||||
uint32_t alpha = fgshade;
|
||||
uint32_t inv_alpha = 256 - fgshade;
|
||||
int32_t fg_r = GPalette.BaseColors[shadedfg].r;
|
||||
|
@ -390,6 +154,7 @@ private:
|
|||
}
|
||||
else if (BlendT::Mode == (int)BlendModes::AddClampShaded)
|
||||
{
|
||||
fgshade = (fgshade * srcalpha + 128) >> 8;
|
||||
uint32_t alpha = fgshade;
|
||||
int32_t fg_r = GPalette.BaseColors[shadedfg].r;
|
||||
int32_t fg_g = GPalette.BaseColors[shadedfg].g;
|
||||
|
@ -417,28 +182,263 @@ private:
|
|||
|
||||
if (BlendT::Mode == (int)BlendModes::AddClamp)
|
||||
{
|
||||
fg_r = MIN<int32_t>((fg_r * srcalpha + bg_r * destalpha + 127) >> 8, 255);
|
||||
fg_g = MIN<int32_t>((fg_g * srcalpha + bg_g * destalpha + 127) >> 8, 255);
|
||||
fg_b = MIN<int32_t>((fg_b * srcalpha + bg_b * destalpha + 127) >> 8, 255);
|
||||
fg_r = MIN(int32_t(fg_r * srcalpha + bg_r * destalpha + 127) >> 8, 255);
|
||||
fg_g = MIN(int32_t(fg_g * srcalpha + bg_g * destalpha + 127) >> 8, 255);
|
||||
fg_b = MIN(int32_t(fg_b * srcalpha + bg_b * destalpha + 127) >> 8, 255);
|
||||
}
|
||||
else if (BlendT::Mode == (int)BlendModes::SubClamp)
|
||||
{
|
||||
fg_r = MAX<int32_t>((fg_r * srcalpha - bg_r * destalpha + 127) >> 8, 0);
|
||||
fg_g = MAX<int32_t>((fg_g * srcalpha - bg_g * destalpha + 127) >> 8, 0);
|
||||
fg_b = MAX<int32_t>((fg_b * srcalpha - bg_b * destalpha + 127) >> 8, 0);
|
||||
fg_r = MAX(int32_t(fg_r * srcalpha - bg_r * destalpha + 127) >> 8, 0);
|
||||
fg_g = MAX(int32_t(fg_g * srcalpha - bg_g * destalpha + 127) >> 8, 0);
|
||||
fg_b = MAX(int32_t(fg_b * srcalpha - bg_b * destalpha + 127) >> 8, 0);
|
||||
}
|
||||
else if (BlendT::Mode == (int)BlendModes::RevSubClamp)
|
||||
{
|
||||
fg_r = MAX<int32_t>((bg_r * srcalpha - fg_r * destalpha + 127) >> 8, 0);
|
||||
fg_g = MAX<int32_t>((bg_g * srcalpha - fg_g * destalpha + 127) >> 8, 0);
|
||||
fg_b = MAX<int32_t>((bg_b * srcalpha - fg_b * destalpha + 127) >> 8, 0);
|
||||
fg_r = MAX(int32_t(bg_r * srcalpha - fg_r * destalpha + 127) >> 8, 0);
|
||||
fg_g = MAX(int32_t(bg_g * srcalpha - fg_g * destalpha + 127) >> 8, 0);
|
||||
fg_b = MAX(int32_t(bg_b * srcalpha - fg_b * destalpha + 127) >> 8, 0);
|
||||
}
|
||||
|
||||
shadedfg = RGB256k.All[((fg_r >> 2) << 12) | ((fg_g >> 2) << 6) | (fg_b >> 2)];
|
||||
return (fgcolor != 0) ? shadedfg : bgcolor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename BlendT, typename SamplerT>
|
||||
class TriScreenDrawer8
|
||||
{
|
||||
public:
|
||||
static void Execute(const TriDrawTriangleArgs *args, WorkerThreadData *thread)
|
||||
{
|
||||
using namespace TriScreenDrawerModes;
|
||||
|
||||
int numSpans = thread->NumFullSpans;
|
||||
auto fullSpans = thread->FullSpans;
|
||||
int numBlocks = thread->NumPartialBlocks;
|
||||
auto partialBlocks = thread->PartialBlocks;
|
||||
int startX = thread->StartX;
|
||||
int startY = thread->StartY;
|
||||
|
||||
bool is_fixed_light = args->uniforms->FixedLight();
|
||||
uint32_t lightmask = is_fixed_light ? 0 : 0xffffffff;
|
||||
auto colormaps = args->uniforms->BaseColormap();
|
||||
uint32_t srcalpha = args->uniforms->SrcAlpha();
|
||||
uint32_t destalpha = args->uniforms->DestAlpha();
|
||||
|
||||
// Calculate gradients
|
||||
const TriVertex &v1 = *args->v1;
|
||||
const TriVertex &v2 = *args->v2;
|
||||
const TriVertex &v3 = *args->v3;
|
||||
ScreenTriangleStepVariables gradientX;
|
||||
ScreenTriangleStepVariables gradientY;
|
||||
ScreenTriangleStepVariables start;
|
||||
gradientX.W = FindGradientX(v1.x, v1.y, v2.x, v2.y, v3.x, v3.y, v1.w, v2.w, v3.w);
|
||||
gradientY.W = FindGradientY(v1.x, v1.y, v2.x, v2.y, v3.x, v3.y, v1.w, v2.w, v3.w);
|
||||
gradientX.U = FindGradientX(v1.x, v1.y, v2.x, v2.y, v3.x, v3.y, v1.u * v1.w, v2.u * v2.w, v3.u * v3.w);
|
||||
gradientY.U = FindGradientY(v1.x, v1.y, v2.x, v2.y, v3.x, v3.y, v1.u * v1.w, v2.u * v2.w, v3.u * v3.w);
|
||||
gradientX.V = FindGradientX(v1.x, v1.y, v2.x, v2.y, v3.x, v3.y, v1.v * v1.w, v2.v * v2.w, v3.v * v3.w);
|
||||
gradientY.V = FindGradientY(v1.x, v1.y, v2.x, v2.y, v3.x, v3.y, v1.v * v1.w, v2.v * v2.w, v3.v * v3.w);
|
||||
start.W = v1.w + gradientX.W * (startX - v1.x) + gradientY.W * (startY - v1.y);
|
||||
start.U = v1.u * v1.w + gradientX.U * (startX - v1.x) + gradientY.U * (startY - v1.y);
|
||||
start.V = v1.v * v1.w + gradientX.V * (startX - v1.x) + gradientY.V * (startY - v1.y);
|
||||
|
||||
// Output
|
||||
uint8_t * RESTRICT destOrg = args->dest;
|
||||
int pitch = args->pitch;
|
||||
|
||||
// Light
|
||||
uint32_t light = args->uniforms->Light();
|
||||
float shade = 2.0f - (light + 12.0f) / 128.0f;
|
||||
float globVis = args->uniforms->GlobVis() * (1.0f / 32.0f);
|
||||
light += light >> 7; // 255 -> 256
|
||||
|
||||
// Sampling stuff
|
||||
uint32_t color = args->uniforms->Color();
|
||||
const uint8_t * RESTRICT translation = args->uniforms->Translation();
|
||||
const uint8_t * RESTRICT texPixels = args->uniforms->TexturePixels();
|
||||
uint32_t texWidth = args->uniforms->TextureWidth();
|
||||
uint32_t texHeight = args->uniforms->TextureHeight();
|
||||
|
||||
for (int i = 0; i < numSpans; i++)
|
||||
{
|
||||
const auto &span = fullSpans[i];
|
||||
|
||||
uint8_t *dest = destOrg + span.X + span.Y * pitch;
|
||||
int width = span.Length;
|
||||
int height = 8;
|
||||
|
||||
ScreenTriangleStepVariables blockPosY;
|
||||
blockPosY.W = start.W + gradientX.W * (span.X - startX) + gradientY.W * (span.Y - startY);
|
||||
blockPosY.U = start.U + gradientX.U * (span.X - startX) + gradientY.U * (span.Y - startY);
|
||||
blockPosY.V = start.V + gradientX.V * (span.X - startX) + gradientY.V * (span.Y - startY);
|
||||
|
||||
for (int y = 0; y < height; y++)
|
||||
{
|
||||
ScreenTriangleStepVariables blockPosX = blockPosY;
|
||||
|
||||
float rcpW = 0x01000000 / blockPosX.W;
|
||||
int32_t posU = (int32_t)(blockPosX.U * rcpW);
|
||||
int32_t posV = (int32_t)(blockPosX.V * rcpW);
|
||||
|
||||
fixed_t lightpos = FRACUNIT - (int)(clamp(shade - MIN(24.0f / 32.0f, globVis * blockPosY.W), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT);
|
||||
lightpos = (lightpos & lightmask) | ((light << 8) & ~lightmask);
|
||||
|
||||
for (int x = 0; x < width; x++)
|
||||
{
|
||||
blockPosX.W += gradientX.W * 8;
|
||||
blockPosX.U += gradientX.U * 8;
|
||||
blockPosX.V += gradientX.V * 8;
|
||||
|
||||
rcpW = 0x01000000 / blockPosX.W;
|
||||
int32_t nextU = (int32_t)(blockPosX.U * rcpW);
|
||||
int32_t nextV = (int32_t)(blockPosX.V * rcpW);
|
||||
int32_t stepU = (nextU - posU) / 8;
|
||||
int32_t stepV = (nextV - posV) / 8;
|
||||
|
||||
fixed_t lightnext = FRACUNIT - (fixed_t)(clamp(shade - MIN(24.0f / 32.0f, globVis * blockPosX.W), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT);
|
||||
fixed_t lightstep = (lightnext - lightpos) / 8;
|
||||
lightstep = lightstep & lightmask;
|
||||
|
||||
for (int ix = 0; ix < 8; ix++)
|
||||
{
|
||||
int lightshade = lightpos >> 8;
|
||||
uint8_t bgcolor = dest[x * 8 + ix];
|
||||
uint8_t fgcolor = Sample8<SamplerT>(posU, posV, texPixels, texWidth, texHeight, color, translation);
|
||||
uint32_t fgshade = SampleShade8<SamplerT>(posU, posV, texPixels, texWidth, texHeight);
|
||||
dest[x * 8 + ix] = ShadeAndBlend8<BlendT>(fgcolor, bgcolor, fgshade, lightshade, colormaps, srcalpha, destalpha);
|
||||
posU += stepU;
|
||||
posV += stepV;
|
||||
lightpos += lightstep;
|
||||
}
|
||||
}
|
||||
|
||||
blockPosY.W += gradientY.W;
|
||||
blockPosY.U += gradientY.U;
|
||||
blockPosY.V += gradientY.V;
|
||||
|
||||
dest += pitch;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < numBlocks; i++)
|
||||
{
|
||||
const auto &block = partialBlocks[i];
|
||||
|
||||
ScreenTriangleStepVariables blockPosY;
|
||||
blockPosY.W = start.W + gradientX.W * (block.X - startX) + gradientY.W * (block.Y - startY);
|
||||
blockPosY.U = start.U + gradientX.U * (block.X - startX) + gradientY.U * (block.Y - startY);
|
||||
blockPosY.V = start.V + gradientX.V * (block.X - startX) + gradientY.V * (block.Y - startY);
|
||||
|
||||
uint8_t *dest = destOrg + block.X + block.Y * pitch;
|
||||
uint32_t mask0 = block.Mask0;
|
||||
uint32_t mask1 = block.Mask1;
|
||||
|
||||
// mask0 loop:
|
||||
for (int y = 0; y < 4; y++)
|
||||
{
|
||||
ScreenTriangleStepVariables blockPosX = blockPosY;
|
||||
|
||||
float rcpW = 0x01000000 / blockPosX.W;
|
||||
int32_t posU = (int32_t)(blockPosX.U * rcpW);
|
||||
int32_t posV = (int32_t)(blockPosX.V * rcpW);
|
||||
|
||||
fixed_t lightpos = FRACUNIT - (fixed_t)(clamp(shade - MIN(24.0f / 32.0f, globVis * blockPosY.W), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT);
|
||||
lightpos = (lightpos & lightmask) | ((light << 8) & ~lightmask);
|
||||
|
||||
blockPosX.W += gradientX.W * 8;
|
||||
blockPosX.U += gradientX.U * 8;
|
||||
blockPosX.V += gradientX.V * 8;
|
||||
|
||||
rcpW = 0x01000000 / blockPosX.W;
|
||||
int32_t nextU = (int32_t)(blockPosX.U * rcpW);
|
||||
int32_t nextV = (int32_t)(blockPosX.V * rcpW);
|
||||
int32_t stepU = (nextU - posU) / 8;
|
||||
int32_t stepV = (nextV - posV) / 8;
|
||||
|
||||
fixed_t lightnext = FRACUNIT - (fixed_t)(clamp(shade - MIN(24.0f / 32.0f, globVis * blockPosX.W), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT);
|
||||
fixed_t lightstep = (lightnext - lightpos) / 8;
|
||||
lightstep = lightstep & lightmask;
|
||||
|
||||
for (int x = 0; x < 8; x++)
|
||||
{
|
||||
if (mask0 & (1 << 31))
|
||||
{
|
||||
int lightshade = lightpos >> 8;
|
||||
uint8_t bgcolor = dest[x];
|
||||
uint8_t fgcolor = Sample8<SamplerT>(posU, posV, texPixels, texWidth, texHeight, color, translation);
|
||||
uint32_t fgshade = SampleShade8<SamplerT>(posU, posV, texPixels, texWidth, texHeight);
|
||||
dest[x] = ShadeAndBlend8<BlendT>(fgcolor, bgcolor, fgshade, lightshade, colormaps, srcalpha, destalpha);
|
||||
}
|
||||
|
||||
posU += stepU;
|
||||
posV += stepV;
|
||||
lightpos += lightstep;
|
||||
|
||||
mask0 <<= 1;
|
||||
}
|
||||
|
||||
blockPosY.W += gradientY.W;
|
||||
blockPosY.U += gradientY.U;
|
||||
blockPosY.V += gradientY.V;
|
||||
|
||||
dest += pitch;
|
||||
}
|
||||
|
||||
// mask1 loop:
|
||||
for (int y = 0; y < 4; y++)
|
||||
{
|
||||
ScreenTriangleStepVariables blockPosX = blockPosY;
|
||||
|
||||
float rcpW = 0x01000000 / blockPosX.W;
|
||||
int32_t posU = (int32_t)(blockPosX.U * rcpW);
|
||||
int32_t posV = (int32_t)(blockPosX.V * rcpW);
|
||||
|
||||
fixed_t lightpos = FRACUNIT - (fixed_t)(clamp(shade - MIN(24.0f / 32.0f, globVis * blockPosY.W), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT);
|
||||
lightpos = (lightpos & lightmask) | ((light << 8) & ~lightmask);
|
||||
|
||||
blockPosX.W += gradientX.W * 8;
|
||||
blockPosX.U += gradientX.U * 8;
|
||||
blockPosX.V += gradientX.V * 8;
|
||||
|
||||
rcpW = 0x01000000 / blockPosX.W;
|
||||
int32_t nextU = (int32_t)(blockPosX.U * rcpW);
|
||||
int32_t nextV = (int32_t)(blockPosX.V * rcpW);
|
||||
int32_t stepU = (nextU - posU) / 8;
|
||||
int32_t stepV = (nextV - posV) / 8;
|
||||
|
||||
fixed_t lightnext = FRACUNIT - (fixed_t)(clamp(shade - MIN(24.0f / 32.0f, globVis * blockPosX.W), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT);
|
||||
fixed_t lightstep = (lightnext - lightpos) / 8;
|
||||
lightstep = lightstep & lightmask;
|
||||
|
||||
for (int x = 0; x < 8; x++)
|
||||
{
|
||||
if (mask1 & (1 << 31))
|
||||
{
|
||||
int lightshade = lightpos >> 8;
|
||||
uint8_t bgcolor = dest[x];
|
||||
uint8_t fgcolor = Sample8<SamplerT>(posU, posV, texPixels, texWidth, texHeight, color, translation);
|
||||
uint32_t fgshade = SampleShade8<SamplerT>(posU, posV, texPixels, texWidth, texHeight);
|
||||
dest[x] = ShadeAndBlend8<BlendT>(fgcolor, bgcolor, fgshade, lightshade, colormaps, srcalpha, destalpha);
|
||||
}
|
||||
|
||||
posU += stepU;
|
||||
posV += stepV;
|
||||
lightpos += lightstep;
|
||||
|
||||
mask1 <<= 1;
|
||||
}
|
||||
|
||||
blockPosY.W += gradientY.W;
|
||||
blockPosY.U += gradientY.U;
|
||||
blockPosY.V += gradientY.V;
|
||||
|
||||
dest += pitch;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
static float FindGradientX(float x0, float y0, float x1, float y1, float x2, float y2, float c0, float c1, float c2)
|
||||
{
|
||||
float top = (c1 - c2) * (y0 - y2) - (c0 - c2) * (y1 - y2);
|
||||
|
@ -453,3 +453,68 @@ private:
|
|||
return top / bottom;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename BlendT, typename SamplerT>
|
||||
class RectScreenDrawer8
|
||||
{
|
||||
public:
|
||||
static void Execute(const void *destOrg, int destWidth, int destHeight, int destPitch, const RectDrawArgs *args, WorkerThreadData *thread)
|
||||
{
|
||||
using namespace TriScreenDrawerModes;
|
||||
|
||||
int x0 = clamp((int)(args->X0() + 0.5f), 0, destWidth);
|
||||
int x1 = clamp((int)(args->X1() + 0.5f), 0, destWidth);
|
||||
int y0 = clamp((int)(args->Y0() + 0.5f), 0, destHeight);
|
||||
int y1 = clamp((int)(args->Y1() + 0.5f), 0, destHeight);
|
||||
|
||||
if (x1 <= x0 || y1 <= y0)
|
||||
return;
|
||||
|
||||
auto colormaps = args->BaseColormap();
|
||||
uint32_t srcalpha = args->SrcAlpha();
|
||||
uint32_t destalpha = args->DestAlpha();
|
||||
|
||||
// Setup step variables
|
||||
float fstepU = (args->U1() - args->U0()) / (args->X1() - args->X0());
|
||||
float fstepV = (args->V1() - args->V0()) / (args->Y1() - args->Y0());
|
||||
uint32_t startU = (int32_t)((args->U0() + (x0 + 0.5f - args->X0()) * fstepU) * 0x1000000);
|
||||
uint32_t startV = (int32_t)((args->V0() + (y0 + 0.5f - args->Y0()) * fstepV) * 0x1000000);
|
||||
uint32_t stepU = (int32_t)(fstepU * 0x1000000);
|
||||
uint32_t stepV = (int32_t)(fstepV * 0x1000000);
|
||||
|
||||
// Sampling stuff
|
||||
uint32_t color = args->Color();
|
||||
const uint8_t * RESTRICT translation = args->Translation();
|
||||
const uint8_t * RESTRICT texPixels = args->TexturePixels();
|
||||
uint32_t texWidth = args->TextureWidth();
|
||||
uint32_t texHeight = args->TextureHeight();
|
||||
|
||||
// Setup light
|
||||
uint32_t lightshade = args->Light();
|
||||
lightshade += lightshade >> 7; // 255 -> 256
|
||||
|
||||
int count = x1 - x0;
|
||||
|
||||
uint32_t posV = startV;
|
||||
for (int y = y0; y < y1; y++, posV += stepV)
|
||||
{
|
||||
int coreBlock = y / 8;
|
||||
if (coreBlock % thread->num_cores != thread->core)
|
||||
continue;
|
||||
|
||||
uint8_t *dest = ((uint8_t*)destOrg) + y * destPitch + x0;
|
||||
|
||||
uint32_t posU = startU;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
uint8_t bgcolor = *dest;
|
||||
uint8_t fgcolor = Sample8<SamplerT>(posU, posV, texPixels, texWidth, texHeight, color, translation);
|
||||
uint32_t fgshade = SampleShade8<SamplerT>(posU, posV, texPixels, texWidth, texHeight);
|
||||
*dest = ShadeAndBlend8<BlendT>(fgcolor, bgcolor, fgshade, lightshade, colormaps, srcalpha, destalpha);
|
||||
|
||||
posU += stepU;
|
||||
dest++;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -99,10 +99,8 @@ void PolyTriangleDrawer::draw_arrays(const PolyDrawArgs &drawargs, WorkerThreadD
|
|||
{
|
||||
int bmode = (int)drawargs.BlendMode();
|
||||
|
||||
if (drawargs.WriteColor() && drawargs.TexturePixels())
|
||||
drawfuncs[num_drawfuncs++] = dest_bgra ? ScreenTriangle::TriDraw32[bmode] : ScreenTriangle::TriDraw8[bmode];
|
||||
else if (drawargs.WriteColor())
|
||||
drawfuncs[num_drawfuncs++] = dest_bgra ? ScreenTriangle::TriFill32[bmode] : ScreenTriangle::TriFill8[bmode];
|
||||
if (drawargs.WriteColor())
|
||||
drawfuncs[num_drawfuncs++] = dest_bgra ? ScreenTriangle::TriDrawers32[bmode] : ScreenTriangle::TriDrawers8[bmode];
|
||||
}
|
||||
|
||||
if (drawargs.WriteStencil())
|
||||
|
@ -234,13 +232,12 @@ void PolyTriangleDrawer::draw_shaded_triangle(const ShadedTriVertex *vert, bool
|
|||
// Keep varyings in -128 to 128 range if possible
|
||||
if (numclipvert > 0)
|
||||
{
|
||||
for (int j = 0; j < TriVertex::NumVarying; j++)
|
||||
float newOriginU = floorf(clippedvert[0].u * 0.1f) * 10.0f;
|
||||
float newOriginV = floorf(clippedvert[0].v * 0.1f) * 10.0f;
|
||||
for (int i = 0; i < numclipvert; i++)
|
||||
{
|
||||
float newOrigin = floorf(clippedvert[0].varying[j] * 0.1f) * 10.0f;
|
||||
for (int i = 0; i < numclipvert; i++)
|
||||
{
|
||||
clippedvert[i].varying[j] -= newOrigin;
|
||||
}
|
||||
clippedvert[i].u -= newOriginU;
|
||||
clippedvert[i].v -= newOriginV;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -426,8 +423,8 @@ int PolyTriangleDrawer::clipedge(const ShadedTriVertex *verts, TriVertex *clippe
|
|||
v.y += verts[w].y * weight;
|
||||
v.z += verts[w].z * weight;
|
||||
v.w += verts[w].w * weight;
|
||||
for (int iv = 0; iv < TriVertex::NumVarying; iv++)
|
||||
v.varying[iv] += verts[w].varying[iv] * weight;
|
||||
v.u += verts[w].u * weight;
|
||||
v.v += verts[w].v * weight;
|
||||
}
|
||||
}
|
||||
return inputverts;
|
||||
|
@ -452,3 +449,23 @@ void DrawPolyTrianglesCommand::Execute(DrawerThread *thread)
|
|||
|
||||
PolyTriangleDrawer::draw_arrays(args, &thread_data);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void DrawRectCommand::Execute(DrawerThread *thread)
|
||||
{
|
||||
WorkerThreadData thread_data;
|
||||
thread_data.core = thread->core;
|
||||
thread_data.num_cores = thread->num_cores;
|
||||
|
||||
auto renderTarget = PolyRenderer::Instance()->RenderTarget;
|
||||
const void *destOrg = renderTarget->GetBuffer();
|
||||
int destWidth = renderTarget->GetWidth();
|
||||
int destHeight = renderTarget->GetHeight();
|
||||
int destPitch = renderTarget->GetPitch();
|
||||
int blendmode = (int)args.BlendMode();
|
||||
if (renderTarget->IsBgra())
|
||||
ScreenTriangle::RectDrawers32[blendmode](destOrg, destWidth, destHeight, destPitch, &args, &thread_data);
|
||||
else
|
||||
ScreenTriangle::RectDrawers8[blendmode](destOrg, destWidth, destHeight, destPitch, &args, &thread_data);
|
||||
}
|
||||
|
|
|
@ -71,3 +71,15 @@ public:
|
|||
private:
|
||||
PolyDrawArgs args;
|
||||
};
|
||||
|
||||
class DrawRectCommand : public DrawerCommand
|
||||
{
|
||||
public:
|
||||
DrawRectCommand(const RectDrawArgs &args) : args(args) { }
|
||||
|
||||
void Execute(DrawerThread *thread) override;
|
||||
FString DebugInfo() override { return "DrawRect"; }
|
||||
|
||||
private:
|
||||
RectDrawArgs args;
|
||||
};
|
||||
|
|
|
@ -922,87 +922,128 @@ void ScreenTriangle::SubsectorWrite(const TriDrawTriangleArgs *args, WorkerThrea
|
|||
}
|
||||
}
|
||||
|
||||
std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> ScreenTriangle::TriDraw8 =
|
||||
void(*ScreenTriangle::TriDrawers8[])(const TriDrawTriangleArgs *, WorkerThreadData *) =
|
||||
{
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::TextureSampler>::Execute, // "Copy", "opaque", false
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::MaskedBlend, TriScreenDrawerModes::TextureSampler>::Execute, // "AlphaBlend", "masked", false
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::TextureSampler>::Execute, // "AddSolid", "translucent", false
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::TextureSampler>::Execute, // "Add", "add", false
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::SubClampBlend, TriScreenDrawerModes::TextureSampler>::Execute, // "Sub", "sub", false
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::RevSubClampBlend, TriScreenDrawerModes::TextureSampler>::Execute, // "RevSub", "revsub", false
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::ShadedBlend, TriScreenDrawerModes::ShadedSampler>::Execute, // "Stencil", "stencil", false
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::ShadedBlend, TriScreenDrawerModes::ShadedSampler>::Execute, // "Shaded", "shaded", false
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // "TranslateCopy", "opaque", true
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::MaskedBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // "TranslateAlphaBlend", "masked", true
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // "TranslateAdd", "add", true
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::SubClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // "TranslateSub", "sub", true
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::RevSubClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // "TranslateRevSub", "revsub", true
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::AddSrcColorBlend, TriScreenDrawerModes::TextureSampler>::Execute, // "AddSrcColorOneMinusSrcColor", "addsrccolor", false
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::SkycapSampler>::Execute // "Skycap", "skycap", false
|
||||
};
|
||||
|
||||
std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> ScreenTriangle::TriFill8 =
|
||||
{
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::FillSampler>::Execute, // "Copy", "opaque", false
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::MaskedBlend, TriScreenDrawerModes::FillSampler>::Execute, // "AlphaBlend", "masked", false
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::FillSampler>::Execute, // "AddSolid", "translucent", false
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::FillSampler>::Execute, // "Add", "add", false
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::SubClampBlend, TriScreenDrawerModes::FillSampler>::Execute, // "Sub", "sub", false
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::RevSubClampBlend, TriScreenDrawerModes::FillSampler>::Execute, // "RevSub", "revsub", false
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::ShadedBlend, TriScreenDrawerModes::ShadedSampler>::Execute, // "Stencil", "stencil", false
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::ShadedBlend, TriScreenDrawerModes::ShadedSampler>::Execute, // "Shaded", "shaded", false
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // "TranslateCopy", "opaque", true
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::MaskedBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // "TranslateAlphaBlend", "masked", true
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // "TranslateAdd", "add", true
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::SubClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // "TranslateSub", "sub", true
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::RevSubClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // "TranslateRevSub", "revsub", true
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::AddSrcColorBlend, TriScreenDrawerModes::FillSampler>::Execute, // "AddSrcColorOneMinusSrcColor", "addsrccolor", false
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::FillSampler>::Execute // "Skycap", "skycap", false
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureOpaque
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::MaskedBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureMasked
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureAdd
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::SubClampBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureSub
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::RevSubClampBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureRevSub
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::AddSrcColorBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureAddSrcColor
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedOpaque
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::MaskedBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedMasked
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedAdd
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::SubClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedSub
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::RevSubClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedRevSub
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::AddSrcColorBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedAddSrcColor
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::ShadedBlend, TriScreenDrawerModes::ShadedSampler>::Execute, // Shaded
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::AddClampShadedBlend, TriScreenDrawerModes::ShadedSampler>::Execute, // AddShaded
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::ShadedBlend, TriScreenDrawerModes::StencilSampler>::Execute, // Stencil
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::AddClampShadedBlend, TriScreenDrawerModes::StencilSampler>::Execute, // AddStencil
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::FillSampler>::Execute, // FillOpaque
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::FillSampler>::Execute, // FillAdd
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::SubClampBlend, TriScreenDrawerModes::FillSampler>::Execute, // FillSub
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::RevSubClampBlend, TriScreenDrawerModes::FillSampler>::Execute, // FillRevSub
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::AddSrcColorBlend, TriScreenDrawerModes::FillSampler>::Execute, // FillAddSrcColor
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::SkycapSampler>::Execute // Skycap
|
||||
};
|
||||
|
||||
#ifdef NO_SSE
|
||||
|
||||
std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> ScreenTriangle::TriDraw32;
|
||||
std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> ScreenTriangle::TriFill32;
|
||||
void(*ScreenTriangle::TriDrawers32[])(const TriDrawTriangleArgs *, WorkerThreadData *) =
|
||||
{
|
||||
nullptr
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> ScreenTriangle::TriDraw32 =
|
||||
void(*ScreenTriangle::TriDrawers32[])(const TriDrawTriangleArgs *, WorkerThreadData *) =
|
||||
{
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::TextureSampler>::Execute, // "Copy", "opaque", false
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::MaskedBlend, TriScreenDrawerModes::TextureSampler>::Execute, // "AlphaBlend", "masked", false
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::TextureSampler>::Execute, // "AddSolid", "translucent", false
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::TextureSampler>::Execute, // "Add", "add", false
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::SubClampBlend, TriScreenDrawerModes::TextureSampler>::Execute, // "Sub", "sub", false
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::RevSubClampBlend, TriScreenDrawerModes::TextureSampler>::Execute, // "RevSub", "revsub", false
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::ShadedBlend, TriScreenDrawerModes::ShadedSampler>::Execute, // "Stencil", "stencil", false
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::ShadedBlend, TriScreenDrawerModes::ShadedSampler>::Execute, // "Shaded", "shaded", false
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // "TranslateCopy", "opaque", true
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::MaskedBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // "TranslateAlphaBlend", "masked", true
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // "TranslateAdd", "add", true
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::SubClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // "TranslateSub", "sub", true
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::RevSubClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // "TranslateRevSub", "revsub", true
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::AddSrcColorBlend, TriScreenDrawerModes::TextureSampler>::Execute, // "AddSrcColorOneMinusSrcColor", "addsrccolor", false
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::SkycapSampler>::Execute // "Skycap", "skycap", false
|
||||
};
|
||||
|
||||
std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> ScreenTriangle::TriFill32 =
|
||||
{
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::FillSampler>::Execute, // "Copy", "opaque", false
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::MaskedBlend, TriScreenDrawerModes::FillSampler>::Execute, // "AlphaBlend", "masked", false
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::FillSampler>::Execute, // "AddSolid", "translucent", false
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::FillSampler>::Execute, // "Add", "add", false
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::SubClampBlend, TriScreenDrawerModes::FillSampler>::Execute, // "Sub", "sub", false
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::RevSubClampBlend, TriScreenDrawerModes::FillSampler>::Execute, // "RevSub", "revsub", false
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::ShadedBlend, TriScreenDrawerModes::ShadedSampler>::Execute, // "Stencil", "stencil", false
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::ShadedBlend, TriScreenDrawerModes::ShadedSampler>::Execute, // "Shaded", "shaded", false
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // "TranslateCopy", "opaque", true
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::MaskedBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // "TranslateAlphaBlend", "masked", true
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // "TranslateAdd", "add", true
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::SubClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // "TranslateSub", "sub", true
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::RevSubClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // "TranslateRevSub", "revsub", true
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::AddSrcColorBlend, TriScreenDrawerModes::FillSampler>::Execute, // "AddSrcColorOneMinusSrcColor", "addsrccolor", false
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::FillSampler>::Execute // "Skycap", "skycap", false
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureOpaque
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::MaskedBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureMasked
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureAdd
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::SubClampBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureSub
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::RevSubClampBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureRevSub
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::AddSrcColorBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureAddSrcColor
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedOpaque
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::MaskedBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedMasked
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedAdd
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::SubClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedSub
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::RevSubClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedRevSub
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::AddSrcColorBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedAddSrcColor
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::ShadedBlend, TriScreenDrawerModes::ShadedSampler>::Execute, // Shaded
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::AddClampShadedBlend, TriScreenDrawerModes::ShadedSampler>::Execute, // AddShaded
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::ShadedBlend, TriScreenDrawerModes::StencilSampler>::Execute, // Stencil
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::AddClampShadedBlend, TriScreenDrawerModes::StencilSampler>::Execute, // AddStencil
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::FillSampler>::Execute, // FillOpaque
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::FillSampler>::Execute, // FillAdd
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::SubClampBlend, TriScreenDrawerModes::FillSampler>::Execute, // FillSub
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::RevSubClampBlend, TriScreenDrawerModes::FillSampler>::Execute, // FillRevSub
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::AddSrcColorBlend, TriScreenDrawerModes::FillSampler>::Execute, // FillAddSrcColor
|
||||
&TriScreenDrawer32<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::SkycapSampler>::Execute // Skycap
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
void(*ScreenTriangle::RectDrawers8[])(const void *, int, int, int, const RectDrawArgs *, WorkerThreadData *) =
|
||||
{
|
||||
&RectScreenDrawer8<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureOpaque
|
||||
&RectScreenDrawer8<TriScreenDrawerModes::MaskedBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureMasked
|
||||
&RectScreenDrawer8<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureAdd
|
||||
&RectScreenDrawer8<TriScreenDrawerModes::SubClampBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureSub
|
||||
&RectScreenDrawer8<TriScreenDrawerModes::RevSubClampBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureRevSub
|
||||
&RectScreenDrawer8<TriScreenDrawerModes::AddSrcColorBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureAddSrcColor
|
||||
&RectScreenDrawer8<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedOpaque
|
||||
&RectScreenDrawer8<TriScreenDrawerModes::MaskedBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedMasked
|
||||
&RectScreenDrawer8<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedAdd
|
||||
&RectScreenDrawer8<TriScreenDrawerModes::SubClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedSub
|
||||
&RectScreenDrawer8<TriScreenDrawerModes::RevSubClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedRevSub
|
||||
&RectScreenDrawer8<TriScreenDrawerModes::AddSrcColorBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedAddSrcColor
|
||||
&RectScreenDrawer8<TriScreenDrawerModes::ShadedBlend, TriScreenDrawerModes::ShadedSampler>::Execute, // Shaded
|
||||
&RectScreenDrawer8<TriScreenDrawerModes::AddClampShadedBlend, TriScreenDrawerModes::ShadedSampler>::Execute, // AddShaded
|
||||
&RectScreenDrawer8<TriScreenDrawerModes::ShadedBlend, TriScreenDrawerModes::StencilSampler>::Execute, // Stencil
|
||||
&RectScreenDrawer8<TriScreenDrawerModes::AddClampShadedBlend, TriScreenDrawerModes::StencilSampler>::Execute, // AddStencil
|
||||
&RectScreenDrawer8<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::FillSampler>::Execute, // FillOpaque
|
||||
&RectScreenDrawer8<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::FillSampler>::Execute, // FillAdd
|
||||
&RectScreenDrawer8<TriScreenDrawerModes::SubClampBlend, TriScreenDrawerModes::FillSampler>::Execute, // FillSub
|
||||
&RectScreenDrawer8<TriScreenDrawerModes::RevSubClampBlend, TriScreenDrawerModes::FillSampler>::Execute, // FillRevSub
|
||||
&RectScreenDrawer8<TriScreenDrawerModes::AddSrcColorBlend, TriScreenDrawerModes::FillSampler>::Execute, // FillAddSrcColor
|
||||
&RectScreenDrawer8<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::SkycapSampler>::Execute // Skycap
|
||||
};
|
||||
|
||||
#ifdef NO_SSE
|
||||
|
||||
void(*ScreenTriangle::RectDrawers32[])(const void *, int, int, int, const RectDrawArgs *, WorkerThreadData *) =
|
||||
{
|
||||
nullptr
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
void(*ScreenTriangle::RectDrawers32[])(const void *, int, int, int, const RectDrawArgs *, WorkerThreadData *) =
|
||||
{
|
||||
&RectScreenDrawer32<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureOpaque
|
||||
&RectScreenDrawer32<TriScreenDrawerModes::MaskedBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureMasked
|
||||
&RectScreenDrawer32<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureAdd
|
||||
&RectScreenDrawer32<TriScreenDrawerModes::SubClampBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureSub
|
||||
&RectScreenDrawer32<TriScreenDrawerModes::RevSubClampBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureRevSub
|
||||
&RectScreenDrawer32<TriScreenDrawerModes::AddSrcColorBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureAddSrcColor
|
||||
&RectScreenDrawer32<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedOpaque
|
||||
&RectScreenDrawer32<TriScreenDrawerModes::MaskedBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedMasked
|
||||
&RectScreenDrawer32<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedAdd
|
||||
&RectScreenDrawer32<TriScreenDrawerModes::SubClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedSub
|
||||
&RectScreenDrawer32<TriScreenDrawerModes::RevSubClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedRevSub
|
||||
&RectScreenDrawer32<TriScreenDrawerModes::AddSrcColorBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedAddSrcColor
|
||||
&RectScreenDrawer32<TriScreenDrawerModes::ShadedBlend, TriScreenDrawerModes::ShadedSampler>::Execute, // Shaded
|
||||
&RectScreenDrawer32<TriScreenDrawerModes::AddClampShadedBlend, TriScreenDrawerModes::ShadedSampler>::Execute, // AddShaded
|
||||
&RectScreenDrawer32<TriScreenDrawerModes::ShadedBlend, TriScreenDrawerModes::StencilSampler>::Execute, // Stencil
|
||||
&RectScreenDrawer32<TriScreenDrawerModes::AddClampShadedBlend, TriScreenDrawerModes::StencilSampler>::Execute, // AddStencil
|
||||
&RectScreenDrawer32<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::FillSampler>::Execute, // FillOpaque
|
||||
&RectScreenDrawer32<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::FillSampler>::Execute, // FillAdd
|
||||
&RectScreenDrawer32<TriScreenDrawerModes::SubClampBlend, TriScreenDrawerModes::FillSampler>::Execute, // FillSub
|
||||
&RectScreenDrawer32<TriScreenDrawerModes::RevSubClampBlend, TriScreenDrawerModes::FillSampler>::Execute, // FillRevSub
|
||||
&RectScreenDrawer32<TriScreenDrawerModes::AddSrcColorBlend, TriScreenDrawerModes::FillSampler>::Execute, // FillAddSrcColor
|
||||
&RectScreenDrawer32<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::SkycapSampler>::Execute // Skycap
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -61,11 +61,10 @@ struct WorkerThreadData
|
|||
struct TriVertex
|
||||
{
|
||||
TriVertex() { }
|
||||
TriVertex(float x, float y, float z, float w, float u, float v) : x(x), y(y), z(z), w(w) { varying[0] = u; varying[1] = v; }
|
||||
TriVertex(float x, float y, float z, float w, float u, float v) : x(x), y(y), z(z), w(w), u(u), v(v) { }
|
||||
|
||||
enum { NumVarying = 2 };
|
||||
float x, y, z, w;
|
||||
float varying[NumVarying];
|
||||
float u, v;
|
||||
};
|
||||
|
||||
struct TriDrawTriangleArgs
|
||||
|
@ -86,27 +85,34 @@ struct TriDrawTriangleArgs
|
|||
const PolyDrawArgs *uniforms;
|
||||
};
|
||||
|
||||
class RectDrawArgs;
|
||||
|
||||
enum class TriBlendMode
|
||||
{
|
||||
Copy, // blend_copy(shade(fg))
|
||||
AlphaBlend, // blend_alpha_blend(shade(fg), bg)
|
||||
AddSolid, // blend_add(shade(fg), bg, srcalpha, destalpha)
|
||||
Add, // blend_add(shade(fg), bg, srcalpha, calc_blend_bgalpha(fg, destalpha))
|
||||
Sub, // blend_sub(shade(fg), bg, srcalpha, calc_blend_bgalpha(fg, destalpha))
|
||||
RevSub, // blend_revsub(shade(fg), bg, srcalpha, calc_blend_bgalpha(fg, destalpha))
|
||||
Stencil, // blend_stencil(shade(color), fg.a, bg, srcalpha, calc_blend_bgalpha(fg, destalpha))
|
||||
Shaded, // blend_stencil(shade(color), fg.index, bg, srcalpha, calc_blend_bgalpha(fg, destalpha))
|
||||
TranslateCopy, // blend_copy(shade(translate(fg)))
|
||||
TranslateAlphaBlend, // blend_alpha_blend(shade(translate(fg)), bg)
|
||||
TranslateAdd, // blend_add(shade(translate(fg)), bg, srcalpha, calc_blend_bgalpha(fg, destalpha))
|
||||
TranslateSub, // blend_sub(shade(translate(fg)), bg, srcalpha, calc_blend_bgalpha(fg, destalpha))
|
||||
TranslateRevSub,// blend_revsub(shade(translate(fg)), bg, srcalpha, calc_blend_bgalpha(fg, destalpha))
|
||||
AddSrcColorOneMinusSrcColor, // glBlendMode(GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR) used by GZDoom's fullbright additive sprites
|
||||
Skycap // Fade to sky color when the V texture coordinate go beyond the [-1, 1] range
|
||||
TextureOpaque,
|
||||
TextureMasked,
|
||||
TextureAdd,
|
||||
TextureSub,
|
||||
TextureRevSub,
|
||||
TextureAddSrcColor,
|
||||
TranslatedOpaque,
|
||||
TranslatedMasked,
|
||||
TranslatedAdd,
|
||||
TranslatedSub,
|
||||
TranslatedRevSub,
|
||||
TranslatedAddSrcColor,
|
||||
Shaded,
|
||||
AddShaded,
|
||||
Stencil,
|
||||
AddStencil,
|
||||
FillOpaque,
|
||||
FillAdd,
|
||||
FillSub,
|
||||
FillRevSub,
|
||||
FillAddSrcColor,
|
||||
Skycap
|
||||
};
|
||||
|
||||
inline int NumTriBlendModes() { return (int)TriBlendMode::Skycap + 1; }
|
||||
|
||||
class ScreenTriangle
|
||||
{
|
||||
public:
|
||||
|
@ -115,16 +121,15 @@ public:
|
|||
static void StencilWrite(const TriDrawTriangleArgs *args, WorkerThreadData *thread);
|
||||
static void SubsectorWrite(const TriDrawTriangleArgs *args, WorkerThreadData *thread);
|
||||
|
||||
static std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> TriDraw8;
|
||||
static std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> TriDraw32;
|
||||
static std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> TriFill8;
|
||||
static std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> TriFill32;
|
||||
static void(*TriDrawers8[])(const TriDrawTriangleArgs *, WorkerThreadData *);
|
||||
static void(*TriDrawers32[])(const TriDrawTriangleArgs *, WorkerThreadData *);
|
||||
static void(*RectDrawers8[])(const void *, int, int, int, const RectDrawArgs *, WorkerThreadData *);
|
||||
static void(*RectDrawers32[])(const void *, int, int, int, const RectDrawArgs *, WorkerThreadData *);
|
||||
};
|
||||
|
||||
struct ScreenTriangleStepVariables
|
||||
{
|
||||
float W;
|
||||
float Varying[TriVertex::NumVarying];
|
||||
float W, U, V;
|
||||
};
|
||||
|
||||
namespace TriScreenDrawerModes
|
||||
|
@ -147,10 +152,11 @@ namespace TriScreenDrawerModes
|
|||
struct SimpleShade { static const int Mode = (int)ShadeMode::Simple; };
|
||||
struct AdvancedShade { static const int Mode = (int)ShadeMode::Advanced; };
|
||||
|
||||
enum class Samplers { Texture, Fill, Shaded, Translated, Skycap };
|
||||
enum class Samplers { Texture, Fill, Shaded, Stencil, Translated, Skycap };
|
||||
struct TextureSampler { static const int Mode = (int)Samplers::Texture; };
|
||||
struct FillSampler { static const int Mode = (int)Samplers::Fill; };
|
||||
struct ShadedSampler { static const int Mode = (int)Samplers::Shaded; };
|
||||
struct StencilSampler { static const int Mode = (int)Samplers::Stencil; };
|
||||
struct TranslatedSampler { static const int Mode = (int)Samplers::Translated; };
|
||||
struct SkycapSampler { static const int Mode = (int)Samplers::Skycap; };
|
||||
}
|
||||
|
|
|
@ -199,7 +199,7 @@ ShadedTriVertex TriMatrix::operator*(TriVertex v) const
|
|||
ShadedTriVertex sv;
|
||||
_mm_storeu_ps(&sv.x, mv);
|
||||
#endif
|
||||
for (int i = 0; i < TriVertex::NumVarying; i++)
|
||||
sv.varying[i] = v.varying[i];
|
||||
sv.u = v.u;
|
||||
sv.v = v.v;
|
||||
return sv;
|
||||
}
|
||||
|
|
|
@ -63,7 +63,6 @@ void PolyRenderer::RenderView(player_t *player)
|
|||
|
||||
int width = SCREENWIDTH;
|
||||
int height = SCREENHEIGHT;
|
||||
int stHeight = gST_Y;
|
||||
float trueratio;
|
||||
ActiveRatio(width, height, &trueratio);
|
||||
//viewport->SetViewport(&Thread, width, height, trueratio);
|
||||
|
|
|
@ -123,10 +123,10 @@ void RenderPolyDecal::Render(const TriMatrix &worldToClip, const PolyClipPlane &
|
|||
vertices[i].y = (float)p.Y;
|
||||
vertices[i].z = (float)(zpos + spriteHeight * offsets[i].second - spriteHeight * 0.5);
|
||||
vertices[i].w = 1.0f;
|
||||
vertices[i].varying[0] = (float)(offsets[i].first * tex->Scale.X);
|
||||
vertices[i].varying[1] = (float)((1.0f - offsets[i].second) * tex->Scale.Y);
|
||||
vertices[i].u = (float)(offsets[i].first * tex->Scale.X);
|
||||
vertices[i].v = (float)((1.0f - offsets[i].second) * tex->Scale.Y);
|
||||
if (flipTextureX)
|
||||
vertices[i].varying[0] = 1.0f - vertices[i].varying[0];
|
||||
vertices[i].u = 1.0f - vertices[i].u;
|
||||
}
|
||||
|
||||
bool fullbrightSprite = (decal->RenderFlags & RF_FULLBRIGHT) == RF_FULLBRIGHT;
|
||||
|
@ -134,10 +134,9 @@ void RenderPolyDecal::Render(const TriMatrix &worldToClip, const PolyClipPlane &
|
|||
|
||||
PolyDrawArgs args;
|
||||
args.SetLight(GetColorTable(front->Colormap), lightlevel, PolyRenderer::Instance()->Light.WallGlobVis(foggy), fullbrightSprite);
|
||||
args.SetTexture(tex, decal->Translation, true);
|
||||
args.SetSubsectorDepth(subsectorDepth);
|
||||
args.SetColor(0xff000000 | decal->AlphaColor, decal->AlphaColor >> 24);
|
||||
args.SetStyle(TriBlendMode::Shaded, decal->Alpha, 1.0 - decal->Alpha); // R_SetPatchStyle (decal->RenderStyle, (float)decal->Alpha, decal->Translation, decal->AlphaColor);
|
||||
args.SetStyle(decal->RenderStyle, decal->Alpha, decal->AlphaColor, decal->Translation, tex, false);
|
||||
args.SetTransform(&worldToClip);
|
||||
args.SetFaceCullCCW(true);
|
||||
args.SetStencilTestValue(stencilValue);
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
#include "polyrenderer/poly_renderer.h"
|
||||
#include "polyrenderer/scene/poly_light.h"
|
||||
|
||||
EXTERN_CVAR(Int, gl_particles_style)
|
||||
|
||||
void RenderPolyParticle::Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, particle_t *particle, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue)
|
||||
{
|
||||
DVector3 pos = particle->Pos;
|
||||
|
@ -64,8 +66,8 @@ void RenderPolyParticle::Render(const TriMatrix &worldToClip, const PolyClipPlan
|
|||
vertices[i].y = (float)p.Y;
|
||||
vertices[i].z = (float)(zpos + psize * (2.0 * offsets[i].second - 1.0));
|
||||
vertices[i].w = 1.0f;
|
||||
vertices[i].varying[0] = (float)(offsets[i].first);
|
||||
vertices[i].varying[1] = (float)(1.0f - offsets[i].second);
|
||||
vertices[i].u = (float)(offsets[i].first);
|
||||
vertices[i].v = (float)(1.0f - offsets[i].second);
|
||||
}
|
||||
|
||||
bool fullbrightSprite = particle->bright != 0;
|
||||
|
@ -76,12 +78,40 @@ void RenderPolyParticle::Render(const TriMatrix &worldToClip, const PolyClipPlan
|
|||
args.SetSubsectorDepth(subsectorDepth);
|
||||
args.SetSubsectorDepthTest(true);
|
||||
args.SetColor(particle->color | 0xff000000, particle->color >> 24);
|
||||
args.SetStyle(TriBlendMode::AlphaBlend, particle->alpha, 1.0 - particle->alpha);
|
||||
args.SetStyle(TriBlendMode::Shaded, particle->alpha, 1.0 - particle->alpha);
|
||||
args.SetTransform(&worldToClip);
|
||||
args.SetFaceCullCCW(true);
|
||||
args.SetStencilTestValue(stencilValue);
|
||||
args.SetWriteStencil(false);
|
||||
args.SetWriteSubsectorDepth(false);
|
||||
args.SetClipPlane(clipPlane);
|
||||
args.SetTexture(GetParticleTexture(), ParticleTextureSize, ParticleTextureSize);
|
||||
args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan);
|
||||
}
|
||||
|
||||
uint8_t *RenderPolyParticle::GetParticleTexture()
|
||||
{
|
||||
static uint8_t particle_texture[NumParticleTextures][ParticleTextureSize * ParticleTextureSize];
|
||||
static bool first_call = true;
|
||||
if (first_call)
|
||||
{
|
||||
double center = ParticleTextureSize * 0.5f;
|
||||
for (int y = 0; y < ParticleTextureSize; y++)
|
||||
{
|
||||
for (int x = 0; x < ParticleTextureSize; x++)
|
||||
{
|
||||
double dx = (center - x - 0.5f) / center;
|
||||
double dy = (center - y - 0.5f) / center;
|
||||
double dist2 = dx * dx + dy * dy;
|
||||
double round_alpha = clamp<double>(1.7f - dist2 * 1.7f, 0.0f, 1.0f);
|
||||
double smooth_alpha = clamp<double>(1.1f - dist2 * 1.1f, 0.0f, 1.0f);
|
||||
|
||||
particle_texture[0][x + y * ParticleTextureSize] = 255;
|
||||
particle_texture[1][x + y * ParticleTextureSize] = (int)(round_alpha * 255.0f + 0.5f);
|
||||
particle_texture[2][x + y * ParticleTextureSize] = (int)(smooth_alpha * 255.0f + 0.5f);
|
||||
}
|
||||
}
|
||||
first_call = false;
|
||||
}
|
||||
return particle_texture[MIN<int>(gl_particles_style, NumParticleTextures)];
|
||||
}
|
||||
|
|
|
@ -29,4 +29,13 @@ class RenderPolyParticle
|
|||
{
|
||||
public:
|
||||
void Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, particle_t *particle, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue);
|
||||
|
||||
private:
|
||||
static uint8_t *GetParticleTexture();
|
||||
|
||||
enum
|
||||
{
|
||||
NumParticleTextures = 3,
|
||||
ParticleTextureSize = 64
|
||||
};
|
||||
};
|
||||
|
|
|
@ -133,7 +133,7 @@ void RenderPolyPlane::Render3DFloor(const TriMatrix &worldToClip, const PolyClip
|
|||
args.SetLight(GetColorTable(sub->sector->Colormap), lightlevel, PolyRenderer::Instance()->Light.WallGlobVis(foggy), false);
|
||||
args.SetSubsectorDepth(subsectorDepth);
|
||||
args.SetTransform(&worldToClip);
|
||||
args.SetStyle(TriBlendMode::Copy);
|
||||
args.SetStyle(TriBlendMode::TextureOpaque);
|
||||
args.SetFaceCullCCW(true);
|
||||
args.SetStencilTestValue(stencilValue);
|
||||
args.SetWriteStencil(true, stencilValue + 1);
|
||||
|
@ -312,7 +312,7 @@ void RenderPolyPlane::Render(const TriMatrix &worldToClip, const PolyClipPlane &
|
|||
if (!isSky)
|
||||
{
|
||||
args.SetTexture(tex);
|
||||
args.SetStyle(TriBlendMode::Copy);
|
||||
args.SetStyle(TriBlendMode::TextureOpaque);
|
||||
args.DrawArray(vertices, sub->numlines, PolyDrawMode::TriangleFan);
|
||||
}
|
||||
else
|
||||
|
@ -410,8 +410,8 @@ TriVertex RenderPolyPlane::PlaneVertex(vertex_t *v1, double height, const UVTran
|
|||
v.y = (float)v1->fPos().Y;
|
||||
v.z = (float)height;
|
||||
v.w = 1.0f;
|
||||
v.varying[0] = transform.GetU(v.x, v.y);
|
||||
v.varying[1] = transform.GetV(v.x, v.y);
|
||||
v.u = transform.GetU(v.x, v.y);
|
||||
v.v = transform.GetV(v.x, v.y);
|
||||
return v;
|
||||
}
|
||||
|
||||
|
|
|
@ -576,52 +576,28 @@ fixed_t RenderPolyPlayerSprites::LightLevelToShade(int lightlevel, bool foggy)
|
|||
|
||||
void PolyNoAccelPlayerSprite::Render()
|
||||
{
|
||||
#if 0
|
||||
if (xscale == 0 || fabs(yscale) < (1.0f / 32000.0f))
|
||||
{ // scaled to 0; can't see
|
||||
return;
|
||||
}
|
||||
|
||||
SpriteDrawerArgs drawerargs;
|
||||
drawerargs.SetLight(Light.BaseColormap, 0, Light.ColormapNum << FRACBITS);
|
||||
|
||||
FDynamicColormap *basecolormap = static_cast<FDynamicColormap*>(Light.BaseColormap);
|
||||
|
||||
bool visible = drawerargs.SetStyle(RenderStyle, Alpha, Translation, FillColor, basecolormap, Light.ColormapNum << FRACBITS);
|
||||
if (!visible)
|
||||
return;
|
||||
|
||||
double spryscale = yscale;
|
||||
bool sprflipvert = false;
|
||||
fixed_t iscale = FLOAT2FIXED(1 / yscale);
|
||||
RectDrawArgs args;
|
||||
args.SetStyle(RenderStyle, Alpha, FillColor, Translation, pic, false);
|
||||
args.SetLight(Light.BaseColormap, 255 - (Light.ColormapNum << 3));
|
||||
|
||||
double centerY = viewheight / 2;
|
||||
|
||||
double sprtopscreen;
|
||||
double y1, y2;
|
||||
if (renderflags & RF_YFLIP)
|
||||
{
|
||||
sprflipvert = true;
|
||||
spryscale = -spryscale;
|
||||
iscale = -iscale;
|
||||
sprtopscreen = centerY + (texturemid - pic->GetHeight()) * spryscale;
|
||||
y1 = centerY + (texturemid - pic->GetHeight()) * (-yscale);
|
||||
y2 = y1 + pic->GetHeight() * (-yscale);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprflipvert = false;
|
||||
sprtopscreen = centerY - texturemid * spryscale;
|
||||
y1 = centerY - texturemid * yscale;
|
||||
y2 = y1 + pic->GetHeight() * yscale;
|
||||
}
|
||||
|
||||
// clip to screen bounds
|
||||
short *mfloorclip = screenheightarray;
|
||||
short *mceilingclip = zeroarray;
|
||||
|
||||
fixed_t frac = startfrac;
|
||||
for (int x = x1; x < x2; x++)
|
||||
{
|
||||
drawerargs.DrawMaskedColumn(x, iscale, pic, frac, spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, false);
|
||||
frac += xiscale;
|
||||
}
|
||||
#endif
|
||||
args.Draw(x1, x2, y1, y2, 0.0f, 1.0f, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -253,7 +253,7 @@ void RenderPolyScene::RenderPortals(int portalDepth)
|
|||
args.SetLight(&NormalLight, 255, PolyRenderer::Instance()->Light.WallGlobVis(foggy), true);
|
||||
args.SetColor(0, 0);
|
||||
args.SetClipPlane(PortalPlane);
|
||||
args.SetStyle(TriBlendMode::Copy);
|
||||
args.SetStyle(TriBlendMode::FillOpaque);
|
||||
|
||||
for (auto &portal : SectorPortals)
|
||||
{
|
||||
|
|
|
@ -70,18 +70,20 @@ void PolySkyDome::Render(const TriMatrix &worldToClip)
|
|||
|
||||
uint32_t topcapcolor = frontskytex->GetSkyCapColor(false);
|
||||
uint32_t bottomcapcolor = frontskytex->GetSkyCapColor(true);
|
||||
uint8_t topcapindex = RGB256k.All[((RPART(topcapcolor) >> 2) << 12) | ((GPART(topcapcolor) >> 2) << 6) | (BPART(topcapcolor) >> 2)];
|
||||
uint8_t bottomcapindex = RGB256k.All[((RPART(bottomcapcolor) >> 2) << 12) | ((GPART(bottomcapcolor) >> 2) << 6) | (BPART(bottomcapcolor) >> 2)];
|
||||
|
||||
for (int i = 1; i <= mRows; i++)
|
||||
{
|
||||
RenderRow(args, i, topcapcolor);
|
||||
RenderRow(args, rc + i, bottomcapcolor);
|
||||
RenderRow(args, i, topcapcolor, topcapindex);
|
||||
RenderRow(args, rc + i, bottomcapcolor, bottomcapindex);
|
||||
}
|
||||
}
|
||||
|
||||
void PolySkyDome::RenderRow(PolyDrawArgs &args, int row, uint32_t capcolor)
|
||||
void PolySkyDome::RenderRow(PolyDrawArgs &args, int row, uint32_t capcolor, uint8_t capcolorindex)
|
||||
{
|
||||
args.SetFaceCullCCW(false);
|
||||
args.SetColor(capcolor, 0);
|
||||
args.SetColor(capcolor, capcolorindex);
|
||||
args.SetStyle(TriBlendMode::Skycap);
|
||||
args.DrawArray(&mVertices[mPrimStart[row]], mPrimStart[row + 1] - mPrimStart[row], PolyDrawMode::TriangleStrip);
|
||||
}
|
||||
|
@ -93,7 +95,7 @@ void PolySkyDome::RenderCapColorRow(PolyDrawArgs &args, FTexture *skytex, int ro
|
|||
|
||||
args.SetFaceCullCCW(bottomCap);
|
||||
args.SetColor(solid, palsolid);
|
||||
args.SetStyle(TriBlendMode::Copy);
|
||||
args.SetStyle(TriBlendMode::FillOpaque);
|
||||
args.DrawArray(&mVertices[mPrimStart[row]], mPrimStart[row + 1] - mPrimStart[row], PolyDrawMode::TriangleFan);
|
||||
}
|
||||
|
||||
|
@ -137,8 +139,8 @@ TriVertex PolySkyDome::SetVertexXYZ(float xx, float yy, float zz, float uu, floa
|
|||
v.y = zz;
|
||||
v.z = yy;
|
||||
v.w = 1.0f;
|
||||
v.varying[0] = uu;
|
||||
v.varying[1] = vv;
|
||||
v.u = uu;
|
||||
v.v = vv;
|
||||
return v;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ private:
|
|||
void SkyVertex(int r, int c, bool yflip);
|
||||
void CreateSkyHemisphere(bool zflip);
|
||||
void CreateDome();
|
||||
void RenderRow(PolyDrawArgs &args, int row, uint32_t capcolor);
|
||||
void RenderRow(PolyDrawArgs &args, int row, uint32_t capcolor, uint8_t capcolorindex);
|
||||
void RenderCapColorRow(PolyDrawArgs &args, FTexture *skytex, int row, bool bottomCap);
|
||||
|
||||
TriVertex SetVertexXYZ(float xx, float yy, float zz, float uu = 0, float vv = 0);
|
||||
|
|
|
@ -128,10 +128,10 @@ void RenderPolySprite::Render(const TriMatrix &worldToClip, const PolyClipPlane
|
|||
vertices[i].y = (float)p.Y;
|
||||
vertices[i].z = (float)(pos.Z + spriteHeight * offsets[i].second);
|
||||
vertices[i].w = 1.0f;
|
||||
vertices[i].varying[0] = (float)(offsets[i].first * tex->Scale.X);
|
||||
vertices[i].varying[1] = (float)((1.0f - offsets[i].second) * tex->Scale.Y);
|
||||
vertices[i].u = (float)(offsets[i].first * tex->Scale.X);
|
||||
vertices[i].v = (float)((1.0f - offsets[i].second) * tex->Scale.Y);
|
||||
if (flipTextureX)
|
||||
vertices[i].varying[0] = 1.0f - vertices[i].varying[0];
|
||||
vertices[i].u = 1.0f - vertices[i].u;
|
||||
}
|
||||
|
||||
bool fullbrightSprite = ((thing->renderflags & RF_FULLBRIGHT) || (thing->flags5 & MF5_BRIGHT));
|
||||
|
@ -144,67 +144,8 @@ void RenderPolySprite::Render(const TriMatrix &worldToClip, const PolyClipPlane
|
|||
args.SetFaceCullCCW(true);
|
||||
args.SetStencilTestValue(stencilValue);
|
||||
args.SetWriteStencil(true, stencilValue);
|
||||
args.SetTexture(tex, thing->Translation);
|
||||
args.SetClipPlane(clipPlane);
|
||||
|
||||
if (thing->RenderStyle == LegacyRenderStyles[STYLE_Normal] ||
|
||||
(r_drawfuzz == 0 && thing->RenderStyle == LegacyRenderStyles[STYLE_OptFuzzy]))
|
||||
{
|
||||
args.SetStyle(args.Translation() ? TriBlendMode::TranslateAdd : TriBlendMode::Add, 1.0, 0.0);
|
||||
}
|
||||
else if (thing->RenderStyle == LegacyRenderStyles[STYLE_Add] && fullbrightSprite && thing->Alpha == 1.0 && !args.Translation())
|
||||
{
|
||||
args.SetStyle(TriBlendMode::AddSrcColorOneMinusSrcColor, 1.0, 1.0);
|
||||
}
|
||||
else if (thing->RenderStyle == LegacyRenderStyles[STYLE_Add])
|
||||
{
|
||||
args.SetStyle(args.Translation() ? TriBlendMode::TranslateAdd : TriBlendMode::Add, thing->Alpha, 1.0);
|
||||
}
|
||||
else if (thing->RenderStyle == LegacyRenderStyles[STYLE_Subtract])
|
||||
{
|
||||
args.SetStyle(args.Translation() ? TriBlendMode::TranslateRevSub : TriBlendMode::RevSub, thing->Alpha, 1.0);
|
||||
}
|
||||
else if (thing->RenderStyle == LegacyRenderStyles[STYLE_SoulTrans])
|
||||
{
|
||||
args.SetStyle(args.Translation() ? TriBlendMode::TranslateAdd : TriBlendMode::Add, transsouls, 1.0 - transsouls);
|
||||
}
|
||||
else if (thing->RenderStyle == LegacyRenderStyles[STYLE_Fuzzy] ||
|
||||
(r_drawfuzz == 2 && thing->RenderStyle == LegacyRenderStyles[STYLE_OptFuzzy]))
|
||||
{ // NYI - Fuzzy - for now, just a copy of "Shadow"
|
||||
args.SetStyle(args.Translation() ? TriBlendMode::TranslateAdd : TriBlendMode::Add, 0.0, 160 / 255.0);
|
||||
}
|
||||
else if (thing->RenderStyle == LegacyRenderStyles[STYLE_Shadow] ||
|
||||
(r_drawfuzz == 1 && thing->RenderStyle == LegacyRenderStyles[STYLE_OptFuzzy]))
|
||||
{
|
||||
args.SetStyle(args.Translation() ? TriBlendMode::TranslateAdd : TriBlendMode::Add, 0.0, 160 / 255.0);
|
||||
}
|
||||
else if (thing->RenderStyle == LegacyRenderStyles[STYLE_TranslucentStencil])
|
||||
{
|
||||
args.SetColor(0xff000000 | thing->fillcolor, thing->fillcolor >> 24);
|
||||
args.SetStyle(TriBlendMode::Stencil, thing->Alpha, 1.0 - thing->Alpha);
|
||||
}
|
||||
else if (thing->RenderStyle == LegacyRenderStyles[STYLE_AddStencil])
|
||||
{
|
||||
args.SetColor(0xff000000 | thing->fillcolor, thing->fillcolor >> 24);
|
||||
args.SetStyle(TriBlendMode::Stencil, thing->Alpha, 1.0 - thing->Alpha);
|
||||
}
|
||||
else if (thing->RenderStyle == LegacyRenderStyles[STYLE_Shaded])
|
||||
{
|
||||
args.SetColor(0, 0);
|
||||
args.SetStyle(TriBlendMode::Shaded, thing->Alpha, 1.0 - thing->Alpha);
|
||||
args.SetTexture(tex, thing->Translation, true);
|
||||
}
|
||||
else if (thing->RenderStyle == LegacyRenderStyles[STYLE_AddShaded])
|
||||
{
|
||||
args.SetColor(0, 0);
|
||||
args.SetStyle(TriBlendMode::Shaded, thing->Alpha, 1.0 - thing->Alpha);
|
||||
args.SetTexture(tex, thing->Translation, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
args.SetStyle(args.Translation() ? TriBlendMode::TranslateAdd : TriBlendMode::Add, thing->Alpha, 1.0 - thing->Alpha);
|
||||
}
|
||||
|
||||
args.SetStyle(thing->RenderStyle, thing->Alpha, thing->fillcolor, thing->Translation, tex, fullbrightSprite);
|
||||
args.SetSubsectorDepthTest(true);
|
||||
args.SetWriteSubsectorDepth(false);
|
||||
args.SetWriteStencil(false);
|
||||
|
|
|
@ -230,14 +230,14 @@ void RenderPolyWall::Render(const TriMatrix &worldToClip, const PolyClipPlane &c
|
|||
if (tex)
|
||||
{
|
||||
PolyWallTextureCoords texcoords(tex, LineSeg, Line, Side, Texpart, TopZ, BottomZ, UnpeggedCeil);
|
||||
vertices[0].varying[0] = (float)texcoords.u1;
|
||||
vertices[0].varying[1] = (float)texcoords.v1;
|
||||
vertices[1].varying[0] = (float)texcoords.u2;
|
||||
vertices[1].varying[1] = (float)texcoords.v1;
|
||||
vertices[2].varying[0] = (float)texcoords.u2;
|
||||
vertices[2].varying[1] = (float)texcoords.v2;
|
||||
vertices[3].varying[0] = (float)texcoords.u1;
|
||||
vertices[3].varying[1] = (float)texcoords.v2;
|
||||
vertices[0].u = (float)texcoords.u1;
|
||||
vertices[0].v = (float)texcoords.v1;
|
||||
vertices[1].u = (float)texcoords.u2;
|
||||
vertices[1].v = (float)texcoords.v1;
|
||||
vertices[2].u = (float)texcoords.u2;
|
||||
vertices[2].v = (float)texcoords.v2;
|
||||
vertices[3].u = (float)texcoords.u1;
|
||||
vertices[3].v = (float)texcoords.v2;
|
||||
}
|
||||
|
||||
// Masked walls clamp to the 0-1 range (no texture repeat)
|
||||
|
@ -272,12 +272,15 @@ void RenderPolyWall::Render(const TriMatrix &worldToClip, const PolyClipPlane &c
|
|||
}
|
||||
else if (!Masked)
|
||||
{
|
||||
args.SetStyle(TriBlendMode::Copy);
|
||||
args.SetStyle(TriBlendMode::TextureOpaque);
|
||||
args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan);
|
||||
}
|
||||
else
|
||||
{
|
||||
args.SetStyle((Line->flags & ML_ADDTRANS) ? TriBlendMode::Add : TriBlendMode::AlphaBlend, Line->alpha, 1.0);
|
||||
bool addtrans = !!(Line->flags & ML_ADDTRANS);
|
||||
double srcalpha = MIN(Line->alpha, 1.0);
|
||||
double destalpha = addtrans ? 1.0 : 1.0 - srcalpha;
|
||||
args.SetStyle(TriBlendMode::TextureAdd, srcalpha, destalpha);
|
||||
args.SetSubsectorDepthTest(true);
|
||||
args.SetWriteSubsectorDepth(true);
|
||||
args.SetWriteStencil(false);
|
||||
|
@ -291,8 +294,8 @@ void RenderPolyWall::ClampHeight(TriVertex &v1, TriVertex &v2)
|
|||
{
|
||||
float top = v1.z;
|
||||
float bottom = v2.z;
|
||||
float texv1 = v1.varying[1];
|
||||
float texv2 = v2.varying[1];
|
||||
float texv1 = v1.v;
|
||||
float texv2 = v2.v;
|
||||
float delta = (texv2 - texv1);
|
||||
|
||||
float t1 = texv1 < 0.0f ? -texv1 / delta : 0.0f;
|
||||
|
@ -301,10 +304,10 @@ void RenderPolyWall::ClampHeight(TriVertex &v1, TriVertex &v2)
|
|||
float inv_t2 = 1.0f - t2;
|
||||
|
||||
v1.z = top * inv_t1 + bottom * t1;
|
||||
v1.varying[1] = texv1 * inv_t1 + texv2 * t1;
|
||||
v1.v = texv1 * inv_t1 + texv2 * t1;
|
||||
|
||||
v2.z = top * inv_t2 + bottom * t2;
|
||||
v2.varying[1] = texv1 * inv_t2 + texv2 * t2;
|
||||
v2.v = texv1 * inv_t2 + texv2 * t2;
|
||||
}
|
||||
|
||||
FTexture *RenderPolyWall::GetTexture()
|
||||
|
|
|
@ -90,10 +90,10 @@ void RenderPolyWallSprite::Render(const TriMatrix &worldToClip, const PolyClipPl
|
|||
vertices[i].y = (float)p.Y;
|
||||
vertices[i].z = (float)(pos.Z + spriteHeight * offsets[i].second);
|
||||
vertices[i].w = 1.0f;
|
||||
vertices[i].varying[0] = (float)(offsets[i].first * tex->Scale.X);
|
||||
vertices[i].varying[1] = (float)((1.0f - offsets[i].second) * tex->Scale.Y);
|
||||
vertices[i].u = (float)(offsets[i].first * tex->Scale.X);
|
||||
vertices[i].v = (float)((1.0f - offsets[i].second) * tex->Scale.Y);
|
||||
if (flipTextureX)
|
||||
vertices[i].varying[0] = 1.0f - vertices[i].varying[0];
|
||||
vertices[i].u = 1.0f - vertices[i].u;
|
||||
}
|
||||
|
||||
bool fullbrightSprite = ((thing->renderflags & RF_FULLBRIGHT) || (thing->flags5 & MF5_BRIGHT));
|
||||
|
@ -109,6 +109,6 @@ void RenderPolyWallSprite::Render(const TriMatrix &worldToClip, const PolyClipPl
|
|||
args.SetSubsectorDepthTest(true);
|
||||
args.SetWriteSubsectorDepth(false);
|
||||
args.SetWriteStencil(false);
|
||||
args.SetStyle(TriBlendMode::AlphaBlend);
|
||||
args.SetStyle(TriBlendMode::TextureMasked);
|
||||
args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan);
|
||||
}
|
||||
|
|
|
@ -167,7 +167,7 @@ static void BuildBlockmap()
|
|||
|
||||
void FLinePortalTraverse::AddLineIntercepts(int bx, int by)
|
||||
{
|
||||
if (by < 0 || by >= PortalBlockmap.dx || bx < 0 || bx >= PortalBlockmap.dy) return;
|
||||
if (by < 0 || by >= PortalBlockmap.dy || bx < 0 || bx >= PortalBlockmap.dx) return;
|
||||
|
||||
FPortalBlock &block = PortalBlockmap(bx, by);
|
||||
|
||||
|
|
|
@ -508,7 +508,6 @@ public:
|
|||
|
||||
FxConstant(PType *type, VMValue &vmval, const FScriptPosition &pos) : FxExpression(EFX_Constant, pos)
|
||||
{
|
||||
ValueType = value.Type = type;
|
||||
isresolved = true;
|
||||
switch (vmval.Type)
|
||||
{
|
||||
|
@ -522,13 +521,14 @@ public:
|
|||
break;
|
||||
|
||||
case REGT_STRING:
|
||||
value = ExpVal(vmval.s());
|
||||
new(&value) ExpVal(vmval.s());
|
||||
break;
|
||||
|
||||
case REGT_POINTER:
|
||||
value.pointer = vmval.a;
|
||||
break;
|
||||
}
|
||||
ValueType = value.Type = type;
|
||||
}
|
||||
|
||||
static FxExpression *MakeConstant(PSymbol *sym, const FScriptPosition &pos);
|
||||
|
|
|
@ -488,6 +488,7 @@ static FFlagDef DynLightFlagDefs[] =
|
|||
DEFINE_FLAG(MF4, DONTLIGHTSELF, ADynamicLight, flags4),
|
||||
DEFINE_FLAG(MF4, ATTENUATE, ADynamicLight, flags4),
|
||||
DEFINE_FLAG(MF4, NOSHADOWMAP, ADynamicLight, flags4),
|
||||
DEFINE_FLAG(MF4, DONTLIGHTACTORS, ADynamicLight, flags4),
|
||||
};
|
||||
|
||||
static FFlagDef PowerSpeedFlagDefs[] =
|
||||
|
|
|
@ -64,7 +64,7 @@ namespace swrenderer
|
|||
int fuzzpos;
|
||||
int fuzzviewheight;
|
||||
|
||||
uint32_t particle_texture[PARTICLE_TEXTURE_SIZE * PARTICLE_TEXTURE_SIZE];
|
||||
uint32_t particle_texture[NUM_PARTICLE_TEXTURES][PARTICLE_TEXTURE_SIZE * PARTICLE_TEXTURE_SIZE];
|
||||
|
||||
short zeroarray[MAXWIDTH];
|
||||
short screenheightarray[MAXWIDTH];
|
||||
|
@ -139,6 +139,8 @@ namespace swrenderer
|
|||
|
||||
void R_InitParticleTexture()
|
||||
{
|
||||
static_assert(NUM_PARTICLE_TEXTURES == 3, "R_InitParticleTexture must be updated if NUM_PARTICLE_TEXTURES is changed");
|
||||
|
||||
double center = PARTICLE_TEXTURE_SIZE * 0.5f;
|
||||
for (int y = 0; y < PARTICLE_TEXTURE_SIZE; y++)
|
||||
{
|
||||
|
@ -147,9 +149,12 @@ namespace swrenderer
|
|||
double dx = (center - x - 0.5f) / center;
|
||||
double dy = (center - y - 0.5f) / center;
|
||||
double dist2 = dx * dx + dy * dy;
|
||||
double alpha = clamp<double>(1.1f - dist2 * 1.1f, 0.0f, 1.0f);
|
||||
double round_alpha = clamp<double>(1.7f - dist2 * 1.7f, 0.0f, 1.0f);
|
||||
double smooth_alpha = clamp<double>(1.1f - dist2 * 1.1f, 0.0f, 1.0f);
|
||||
|
||||
particle_texture[x + y * PARTICLE_TEXTURE_SIZE] = (int)(alpha * 128.0f + 0.5f);
|
||||
particle_texture[0][x + y * PARTICLE_TEXTURE_SIZE] = 128;
|
||||
particle_texture[1][x + y * PARTICLE_TEXTURE_SIZE] = (int)(round_alpha * 128.0f + 0.5f);
|
||||
particle_texture[2][x + y * PARTICLE_TEXTURE_SIZE] = (int)(smooth_alpha * 128.0f + 0.5f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,8 +44,9 @@ namespace swrenderer
|
|||
extern int fuzzpos;
|
||||
extern int fuzzviewheight;
|
||||
|
||||
#define NUM_PARTICLE_TEXTURES 3
|
||||
#define PARTICLE_TEXTURE_SIZE 64
|
||||
extern uint32_t particle_texture[PARTICLE_TEXTURE_SIZE * PARTICLE_TEXTURE_SIZE];
|
||||
extern uint32_t particle_texture[NUM_PARTICLE_TEXTURES][PARTICLE_TEXTURE_SIZE * PARTICLE_TEXTURE_SIZE];
|
||||
|
||||
class SWPixelFormatDrawers
|
||||
{
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
|
||||
// [SP] r_blendmethod - false = rgb555 matching (ZDoom classic), true = rgb666 (refactored)
|
||||
CVAR(Bool, r_blendmethod, false, CVAR_GLOBALCONFIG | CVAR_ARCHIVE)
|
||||
EXTERN_CVAR(Int, gl_particles_style)
|
||||
|
||||
/*
|
||||
[RH] This translucency algorithm is based on DOSDoom 0.65's, but uses
|
||||
|
@ -2946,7 +2947,8 @@ namespace swrenderer
|
|||
uint8_t *dest = thread->dest_for_thread(_dest_y, pitch, _dest);
|
||||
pitch = pitch * thread->num_cores;
|
||||
|
||||
const uint32_t *source = &particle_texture[(_fracposx >> FRACBITS) * PARTICLE_TEXTURE_SIZE];
|
||||
int particle_texture_index = MIN<int>(gl_particles_style, NUM_PARTICLE_TEXTURES - 1);
|
||||
const uint32_t *source = &particle_texture[particle_texture_index][(_fracposx >> FRACBITS) * PARTICLE_TEXTURE_SIZE];
|
||||
uint32_t particle_alpha = _alpha;
|
||||
|
||||
uint32_t fracstep = PARTICLE_TEXTURE_SIZE * FRACUNIT / _count;
|
||||
|
|
|
@ -780,7 +780,8 @@ namespace swrenderer
|
|||
uint32_t *dest = thread->dest_for_thread(_dest_y, _pitch, _dest);
|
||||
int pitch = _pitch * thread->num_cores;
|
||||
|
||||
const uint32_t *source = &particle_texture[(_fracposx >> FRACBITS) * PARTICLE_TEXTURE_SIZE];
|
||||
int particle_texture_index = MIN<int>(gl_particles_style, NUM_PARTICLE_TEXTURES - 1);
|
||||
const uint32_t *source = &particle_texture[particle_texture_index][(_fracposx >> FRACBITS) * PARTICLE_TEXTURE_SIZE];
|
||||
uint32_t particle_alpha = _alpha;
|
||||
|
||||
uint32_t fracstep = PARTICLE_TEXTURE_SIZE * FRACUNIT / _count;
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <cmath>
|
||||
|
||||
#include "doomdef.h"
|
||||
#include "doomstat.h"
|
||||
|
@ -99,7 +100,7 @@ namespace swrenderer
|
|||
v = v - floor(v);
|
||||
double v_step = uv_stepd / texture->GetHeight();
|
||||
|
||||
if (isnan(v) || isnan(v_step)) // this should never happen, but it apparently does..
|
||||
if (std::isnan(v) || std::isnan(v_step)) // this should never happen, but it apparently does..
|
||||
{
|
||||
uv_stepd = 0.0;
|
||||
v = 0.0;
|
||||
|
|
|
@ -237,7 +237,7 @@ namespace swrenderer
|
|||
while (node != nullptr)
|
||||
{
|
||||
ADynamicLight *light = node->lightsource;
|
||||
if (light->visibletoplayer && !(light->flags2&MF2_DORMANT) && (!(light->flags4&MF4_DONTLIGHTSELF) || light->target != thing))
|
||||
if (light->visibletoplayer && !(light->flags2&MF2_DORMANT) && (!(light->flags4&MF4_DONTLIGHTSELF) || light->target != thing) && !(light->flags4&MF4_DONTLIGHTACTORS))
|
||||
{
|
||||
float lx = (float)(light->X() - thing->X());
|
||||
float ly = (float)(light->Y() - thing->Y());
|
||||
|
|
133
src/textures/shadertexture.cpp
Normal file
133
src/textures/shadertexture.cpp
Normal file
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
** shadertexture.cpp
|
||||
**
|
||||
** simple shader gradient textures, used by the status bars.
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2008 Braden Obrzut
|
||||
** Copyright 2017 Christoph Oelckers
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions
|
||||
** are met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** 2. Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** 3. The name of the author may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
*/
|
||||
|
||||
#include "doomtype.h"
|
||||
#include "doomstat.h"
|
||||
#include "d_player.h"
|
||||
#include "templates.h"
|
||||
#include "menu/menu.h"
|
||||
#include "colormatcher.h"
|
||||
#include "textures/textures.h"
|
||||
#include "w_wad.h"
|
||||
#include "v_font.h"
|
||||
#include "v_video.h"
|
||||
#include "g_level.h"
|
||||
#include "gi.h"
|
||||
#include "r_defs.h"
|
||||
#include "r_state.h"
|
||||
#include "r_data/r_translate.h"
|
||||
|
||||
|
||||
class FBarShader : public FTexture
|
||||
{
|
||||
public:
|
||||
FBarShader(bool vertical, bool reverse)
|
||||
{
|
||||
int i;
|
||||
|
||||
Name.Format("BarShader%c%c", vertical ? 'v' : 'h', reverse ? 'r' : 'f');
|
||||
Width = vertical ? 2 : 256;
|
||||
Height = vertical ? 256 : 2;
|
||||
CalcBitSize();
|
||||
|
||||
// Fill the column/row with shading values.
|
||||
// Vertical shaders have have minimum alpha at the top
|
||||
// and maximum alpha at the bottom, unless flipped by
|
||||
// setting reverse to true. Horizontal shaders are just
|
||||
// the opposite.
|
||||
if (vertical)
|
||||
{
|
||||
if (!reverse)
|
||||
{
|
||||
for (i = 0; i < 256; ++i)
|
||||
{
|
||||
Pixels[i] = i;
|
||||
Pixels[256+i] = i;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < 256; ++i)
|
||||
{
|
||||
Pixels[i] = 255 - i;
|
||||
Pixels[256+i] = 255 -i;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!reverse)
|
||||
{
|
||||
for (i = 0; i < 256; ++i)
|
||||
{
|
||||
Pixels[i*2] = 255 - i;
|
||||
Pixels[i*2+1] = 255 - i;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < 256; ++i)
|
||||
{
|
||||
Pixels[i*2] = i;
|
||||
Pixels[i*2+1] = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
DummySpan[0].TopOffset = 0;
|
||||
DummySpan[0].Length = vertical ? 256 : 2;
|
||||
DummySpan[1].TopOffset = 0;
|
||||
DummySpan[1].Length = 0;
|
||||
}
|
||||
const uint8_t *GetColumn(unsigned int column, const Span **spans_out)
|
||||
{
|
||||
if (spans_out != NULL)
|
||||
{
|
||||
*spans_out = DummySpan;
|
||||
}
|
||||
return Pixels + ((column & WidthMask) << HeightBits);
|
||||
}
|
||||
const uint8_t *GetPixels() { return Pixels; }
|
||||
void Unload() {}
|
||||
private:
|
||||
uint8_t Pixels[512];
|
||||
Span DummySpan[2];
|
||||
};
|
||||
|
||||
|
||||
FTexture *CreateShaderTexture(bool vertical, bool reverse)
|
||||
{
|
||||
return new FBarShader(vertical, reverse);
|
||||
}
|
|
@ -977,6 +977,7 @@ void FTextureManager::SortTexturesByType(int start, int end)
|
|||
//
|
||||
//==========================================================================
|
||||
FTexture *GetBackdropTexture();
|
||||
FTexture *CreateShaderTexture(bool, bool);
|
||||
|
||||
void FTextureManager::Init()
|
||||
{
|
||||
|
@ -988,7 +989,12 @@ void FTextureManager::Init()
|
|||
|
||||
// Texture 0 is a dummy texture used to indicate "no texture"
|
||||
AddTexture (new FDummyTexture);
|
||||
// some special textures used in the game.
|
||||
AddTexture(GetBackdropTexture());
|
||||
AddTexture(CreateShaderTexture(false, false));
|
||||
AddTexture(CreateShaderTexture(false, true));
|
||||
AddTexture(CreateShaderTexture(true, false));
|
||||
AddTexture(CreateShaderTexture(true, true));
|
||||
|
||||
int wadcnt = Wads.GetNumWads();
|
||||
for(int i = 0; i< wadcnt; i++)
|
||||
|
|
112
src/v_draw.cpp
112
src/v_draw.cpp
|
@ -137,6 +137,8 @@ DEFINE_ACTION_FUNCTION(_Screen, DrawTexture)
|
|||
PARAM_FLOAT(x);
|
||||
PARAM_FLOAT(y);
|
||||
|
||||
if (!screen->IsLocked()) ThrowAbortException(X_OTHER, "Attempt to draw to screen outside a draw function");
|
||||
|
||||
FTexture *tex = animate ? TexMan(FSetTextureID(texid)) : TexMan[FSetTextureID(texid)];
|
||||
VMVa_List args = { param + 4, 0, numparam - 4 };
|
||||
screen->DrawTexture(tex, x, y, args);
|
||||
|
@ -155,6 +157,22 @@ void DCanvas::DrawTextureParms(FTexture *img, DrawParms &parms)
|
|||
}
|
||||
}
|
||||
|
||||
void DCanvas::SetClipRect(int x, int y, int w, int h)
|
||||
{
|
||||
clipleft = clamp(x, 0, GetWidth());
|
||||
clipwidth = clamp(w, 0, GetWidth() - x);
|
||||
cliptop = clamp(y, 0, GetHeight());
|
||||
clipwidth = clamp(w, 0, GetHeight() - y);
|
||||
}
|
||||
|
||||
void DCanvas::GetClipRect(int *x, int *y, int *w, int *h)
|
||||
{
|
||||
if (x) *x = clipleft;
|
||||
if (y) *y = cliptop;
|
||||
if (w) *w = clipwidth;
|
||||
if (h) *h = clipheight;
|
||||
}
|
||||
|
||||
bool DCanvas::SetTextureParms(DrawParms *parms, FTexture *img, double xx, double yy) const
|
||||
{
|
||||
if (img != NULL)
|
||||
|
@ -692,6 +710,15 @@ bool DCanvas::ParseDrawTextureTags(FTexture *img, double x, double y, uint32_t t
|
|||
parms->remap = nullptr;
|
||||
}
|
||||
|
||||
// intersect with the canvas's clipping rectangle.
|
||||
if (clipwidth >= 0 && clipheight >= 0)
|
||||
{
|
||||
if (parms->lclip < clipleft) parms->lclip = clipleft;
|
||||
if (parms->rclip > clipleft + clipwidth) parms->rclip = clipleft + clipwidth;
|
||||
if (parms->uclip < cliptop) parms->uclip = cliptop;
|
||||
if (parms->dclip < cliptop + clipheight) parms->uclip = cliptop + clipheight;
|
||||
}
|
||||
|
||||
if (parms->uclip >= parms->dclip || parms->lclip >= parms->rclip)
|
||||
{
|
||||
return false;
|
||||
|
@ -800,22 +827,6 @@ DEFINE_ACTION_FUNCTION(_Screen, VirtualToRealCoords)
|
|||
return MIN(numret, 2);
|
||||
}
|
||||
|
||||
void DCanvas::VirtualToRealCoordsFixed(fixed_t &x, fixed_t &y, fixed_t &w, fixed_t &h,
|
||||
int vwidth, int vheight, bool vbottom, bool handleaspect) const
|
||||
{
|
||||
double dx, dy, dw, dh;
|
||||
|
||||
dx = FIXED2DBL(x);
|
||||
dy = FIXED2DBL(y);
|
||||
dw = FIXED2DBL(w);
|
||||
dh = FIXED2DBL(h);
|
||||
VirtualToRealCoords(dx, dy, dw, dh, vwidth, vheight, vbottom, handleaspect);
|
||||
x = FLOAT2FIXED(dx);
|
||||
y = FLOAT2FIXED(dy);
|
||||
w = FLOAT2FIXED(dw);
|
||||
h = FLOAT2FIXED(dh);
|
||||
}
|
||||
|
||||
void DCanvas::VirtualToRealCoordsInt(int &x, int &y, int &w, int &h,
|
||||
int vwidth, int vheight, bool vbottom, bool handleaspect) const
|
||||
{
|
||||
|
@ -900,7 +911,7 @@ void DCanvas::DrawPixel(int x, int y, int palColor, uint32_t realcolor)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void DCanvas::Clear (int left, int top, int right, int bottom, int palcolor, uint32_t color)
|
||||
void DCanvas::DoClear (int left, int top, int right, int bottom, int palcolor, uint32_t color)
|
||||
{
|
||||
#ifndef NO_SWRENDER
|
||||
if (palcolor < 0 && APART(color) != 255)
|
||||
|
@ -914,6 +925,33 @@ void DCanvas::Clear (int left, int top, int right, int bottom, int palcolor, uin
|
|||
#endif
|
||||
}
|
||||
|
||||
void DCanvas::Clear(int left, int top, int right, int bottom, int palcolor, uint32_t color)
|
||||
{
|
||||
if (clipwidth >= 0 && clipheight >= 0)
|
||||
{
|
||||
int w = right - left;
|
||||
int h = bottom - top;
|
||||
if (left < clipleft)
|
||||
{
|
||||
w -= (clipleft - left);
|
||||
left = clipleft;
|
||||
}
|
||||
if (w > clipwidth) w = clipwidth;
|
||||
if (w <= 0) return;
|
||||
|
||||
if (top < cliptop)
|
||||
{
|
||||
h -= (cliptop - top);
|
||||
top = cliptop;
|
||||
}
|
||||
if (h > clipheight) w = clipheight;
|
||||
if (h <= 0) return;
|
||||
right = left + w;
|
||||
bottom = top + h;
|
||||
}
|
||||
DoClear(left, top, right, bottom, palcolor, color);
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(_Screen, Clear)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
|
@ -923,6 +961,7 @@ DEFINE_ACTION_FUNCTION(_Screen, Clear)
|
|||
PARAM_INT(y2);
|
||||
PARAM_INT(color);
|
||||
PARAM_INT_DEF(palcol);
|
||||
if (!screen->IsLocked()) ThrowAbortException(X_OTHER, "Attempt to draw to screen outside a draw function");
|
||||
screen->Clear(x1, y1, x2, y2, palcol, color);
|
||||
return 0;
|
||||
}
|
||||
|
@ -935,13 +974,50 @@ DEFINE_ACTION_FUNCTION(_Screen, Clear)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void DCanvas::Dim(PalEntry color, float damount, int x1, int y1, int w, int h)
|
||||
void DCanvas::DoDim(PalEntry color, float damount, int x1, int y1, int w, int h)
|
||||
{
|
||||
#ifndef NO_SWRENDER
|
||||
SWCanvas::Dim(this, color, damount, x1, y1, w, h);
|
||||
#endif
|
||||
}
|
||||
|
||||
void DCanvas::Dim(PalEntry color, float damount, int x1, int y1, int w, int h)
|
||||
{
|
||||
if (clipwidth >= 0 && clipheight >= 0)
|
||||
{
|
||||
if (x1 < clipleft)
|
||||
{
|
||||
w -= (clipleft - x1);
|
||||
x1 = clipleft;
|
||||
}
|
||||
if (w > clipwidth) w = clipwidth;
|
||||
if (w <= 0) return;
|
||||
|
||||
if (y1 < cliptop)
|
||||
{
|
||||
h -= (cliptop - y1);
|
||||
y1 = cliptop;
|
||||
}
|
||||
if (h > clipheight) w = clipheight;
|
||||
if (h <= 0) return;
|
||||
}
|
||||
DoDim(color, damount, x1, y1, w, h);
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(_Screen, Dim)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
PARAM_INT(color);
|
||||
PARAM_FLOAT(amount);
|
||||
PARAM_INT(x1);
|
||||
PARAM_INT(y1);
|
||||
PARAM_INT(w);
|
||||
PARAM_INT(h);
|
||||
if (!screen->IsLocked()) ThrowAbortException(X_OTHER, "Attempt to draw to screen outside a draw function");
|
||||
screen->Dim(color, float(amount), x1, y1, w, h);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// DCanvas :: FillSimplePoly
|
||||
|
|
|
@ -116,6 +116,7 @@ DEFINE_ACTION_FUNCTION(_Screen, DrawChar)
|
|||
PARAM_FLOAT(y);
|
||||
PARAM_INT(chr);
|
||||
|
||||
if (!screen->IsLocked()) ThrowAbortException(X_OTHER, "Attempt to draw to screen outside a draw function");
|
||||
VMVa_List args = { param + 5, 0, numparam - 5 };
|
||||
screen->DrawChar(font, cr, x, y, chr, args);
|
||||
return 0;
|
||||
|
@ -241,6 +242,7 @@ DEFINE_ACTION_FUNCTION(_Screen, DrawText)
|
|||
PARAM_FLOAT(y);
|
||||
PARAM_STRING(chr);
|
||||
|
||||
if (!screen->IsLocked()) ThrowAbortException(X_OTHER, "Attempt to draw to screen outside a draw function");
|
||||
VMVa_List args = { param + 5, 0, numparam - 5 };
|
||||
const char *txt = chr[0] == '$' ? GStrings(&chr[1]) : chr.GetChars();
|
||||
screen->DrawText(font, cr, x, y, txt, args);
|
||||
|
|
|
@ -204,8 +204,6 @@ void V_MarkRect (int x, int y, int width, int height)
|
|||
{
|
||||
}
|
||||
|
||||
DCanvas *DCanvas::CanvasChain = NULL;
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// DCanvas Constructor
|
||||
|
@ -220,10 +218,6 @@ DCanvas::DCanvas (int _width, int _height, bool _bgra)
|
|||
Width = _width;
|
||||
Height = _height;
|
||||
Bgra = _bgra;
|
||||
|
||||
// Add to list of active canvases
|
||||
Next = CanvasChain;
|
||||
CanvasChain = this;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -234,22 +228,6 @@ DCanvas::DCanvas (int _width, int _height, bool _bgra)
|
|||
|
||||
DCanvas::~DCanvas ()
|
||||
{
|
||||
// Remove from list of active canvases
|
||||
DCanvas *probe = CanvasChain, **prev;
|
||||
|
||||
prev = &CanvasChain;
|
||||
probe = CanvasChain;
|
||||
|
||||
while (probe != NULL)
|
||||
{
|
||||
if (probe == this)
|
||||
{
|
||||
*prev = probe->Next;
|
||||
break;
|
||||
}
|
||||
prev = &probe->Next;
|
||||
probe = probe->Next;
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -336,20 +314,6 @@ void DCanvas::Dim (PalEntry color)
|
|||
Dim (dimmer, amount, 0, 0, Width, Height);
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(_Screen, Dim)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
PARAM_INT(color);
|
||||
PARAM_FLOAT(amount);
|
||||
PARAM_INT(x1);
|
||||
PARAM_INT(y1);
|
||||
PARAM_INT(w);
|
||||
PARAM_INT(h);
|
||||
screen->Dim(color, float(amount), x1, y1, w, h);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// DCanvas :: GetScreenshotBuffer
|
||||
|
@ -1168,6 +1132,7 @@ void DFrameBuffer::SetBlendingRect (int x1, int y1, int x2, int y2)
|
|||
|
||||
bool DFrameBuffer::Begin2D (bool copy3d)
|
||||
{
|
||||
ClearClipRect();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -225,7 +225,8 @@ public:
|
|||
virtual void Dim (PalEntry color = 0);
|
||||
|
||||
// Dim part of the canvas
|
||||
virtual void Dim (PalEntry color, float amount, int x1, int y1, int w, int h);
|
||||
virtual void Dim (PalEntry color, float amount, int x1, int y1, int w, int h) final;
|
||||
virtual void DoDim(PalEntry color, float amount, int x1, int y1, int w, int h);
|
||||
|
||||
// Fill an area with a texture
|
||||
virtual void FlatFill (int left, int top, int right, int bottom, FTexture *src, bool local_origin=false);
|
||||
|
@ -236,7 +237,8 @@ public:
|
|||
const FColormap &colormap, PalEntry flatcolor, int lightlevel, int bottomclip);
|
||||
|
||||
// Set an area to a specified color
|
||||
virtual void Clear (int left, int top, int right, int bottom, int palcolor, uint32_t color);
|
||||
virtual void Clear (int left, int top, int right, int bottom, int palcolor, uint32_t color) final;
|
||||
virtual void DoClear(int left, int top, int right, int bottom, int palcolor, uint32_t color);
|
||||
|
||||
// Draws a line
|
||||
virtual void DrawLine(int x0, int y0, int x1, int y1, int palColor, uint32_t realcolor);
|
||||
|
@ -259,6 +261,10 @@ public:
|
|||
// Text drawing functions -----------------------------------------------
|
||||
|
||||
// 2D Texture drawing
|
||||
void ClearClipRect() { clipleft = cliptop = 0; clipwidth = clipheight = -1; }
|
||||
void SetClipRect(int x, int y, int w, int h);
|
||||
void GetClipRect(int *x, int *y, int *w, int *h);
|
||||
|
||||
bool SetTextureParms(DrawParms *parms, FTexture *img, double x, double y) const;
|
||||
void DrawTexture (FTexture *img, double x, double y, int tags, ...);
|
||||
void DrawTexture(FTexture *img, double x, double y, VMVa_List &);
|
||||
|
@ -266,7 +272,6 @@ public:
|
|||
void VirtualToRealCoords(double &x, double &y, double &w, double &h, double vwidth, double vheight, bool vbottom=false, bool handleaspect=true) const;
|
||||
|
||||
// Code that uses these (i.e. SBARINFO) should probably be evaluated for using doubles all around instead.
|
||||
void VirtualToRealCoordsFixed(fixed_t &x, fixed_t &y, fixed_t &w, fixed_t &h, int vwidth, int vheight, bool vbottom=false, bool handleaspect=true) const;
|
||||
void VirtualToRealCoordsInt(int &x, int &y, int &w, int &h, int vwidth, int vheight, bool vbottom=false, bool handleaspect=true) const;
|
||||
|
||||
#ifdef DrawText
|
||||
|
@ -285,6 +290,7 @@ protected:
|
|||
int Pitch;
|
||||
int LockCount;
|
||||
bool Bgra;
|
||||
int clipleft = 0, cliptop = 0, clipwidth = -1, clipheight = -1;
|
||||
|
||||
void DrawTextCommon(FFont *font, int normalcolor, double x, double y, const char *string, DrawParms &parms);
|
||||
|
||||
|
|
|
@ -730,6 +730,7 @@ void WI_Drawer()
|
|||
{
|
||||
VMValue self = WI_Screen;
|
||||
GlobalVMStack.Call(func, &self, 1, nullptr, 0);
|
||||
screen->ClearClipRect(); // make sure the scripts don't leave a valid clipping rect behind.
|
||||
|
||||
// The internal handling here is somewhat poor. After being set to 'LeavingIntermission'
|
||||
// the screen is needed for one more draw operation so we cannot delete it right away but only here.
|
||||
|
|
|
@ -2557,6 +2557,7 @@ bool D3DPal::Update()
|
|||
|
||||
bool D3DFB::Begin2D(bool copy3d)
|
||||
{
|
||||
ClearClipRect();
|
||||
if (!Accel2D)
|
||||
{
|
||||
return false;
|
||||
|
@ -2635,11 +2636,11 @@ FNativePalette *D3DFB::CreatePalette(FRemapTable *remap)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void D3DFB::Clear (int left, int top, int right, int bottom, int palcolor, uint32_t color)
|
||||
void D3DFB::DoClear (int left, int top, int right, int bottom, int palcolor, uint32_t color)
|
||||
{
|
||||
if (In2D < 2)
|
||||
{
|
||||
Super::Clear(left, top, right, bottom, palcolor, color);
|
||||
//Super::Clear(left, top, right, bottom, palcolor, color);
|
||||
return;
|
||||
}
|
||||
if (!InScene)
|
||||
|
@ -2664,7 +2665,7 @@ void D3DFB::Clear (int left, int top, int right, int bottom, int palcolor, uint3
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void D3DFB::Dim (PalEntry color, float amount, int x1, int y1, int w, int h)
|
||||
void D3DFB::DoDim (PalEntry color, float amount, int x1, int y1, int w, int h)
|
||||
{
|
||||
if (amount <= 0)
|
||||
{
|
||||
|
|
|
@ -1153,7 +1153,7 @@ void Win32GLFrameBuffer::Unlock ()
|
|||
|
||||
bool Win32GLFrameBuffer::IsLocked ()
|
||||
{
|
||||
return m_Lock>0;// true;
|
||||
return m_Lock > 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -132,8 +132,8 @@ public:
|
|||
FNativeTexture *CreateTexture (FTexture *gametex, bool wrapping);
|
||||
FNativePalette *CreatePalette (FRemapTable *remap);
|
||||
void DrawTextureParms (FTexture *img, DrawParms &parms);
|
||||
void Clear (int left, int top, int right, int bottom, int palcolor, uint32_t color);
|
||||
void Dim (PalEntry color, float amount, int x1, int y1, int w, int h);
|
||||
void DoClear (int left, int top, int right, int bottom, int palcolor, uint32_t color);
|
||||
void DoDim (PalEntry color, float amount, int x1, int y1, int w, int h);
|
||||
void FlatFill (int left, int top, int right, int bottom, FTexture *src, bool local_origin);
|
||||
void DrawLine(int x0, int y0, int x1, int y1, int palColor, uint32_t realcolor);
|
||||
void DrawPixel(int x, int y, int palcolor, uint32_t rgbcolor);
|
||||
|
|
|
@ -183,6 +183,14 @@ texture optional FBULB0
|
|||
// The Wings of Wrath are not included, because they stop spinning when
|
||||
// you stop flying, so they can't be a simple animation.
|
||||
|
||||
texture optional INVGEML1
|
||||
pic INVGEML1 tics 4
|
||||
pic INVGEML2 tics 4
|
||||
|
||||
texture optional INVGEMR1
|
||||
pic INVGEMR1 tics 4
|
||||
pic INVGEMR2 tics 4
|
||||
|
||||
switch doom 1 SW1BRCOM on pic SW2BRCOM tics 0
|
||||
switch doom 1 SW1BRN1 on pic SW2BRN1 tics 0
|
||||
switch doom 1 SW1BRN2 on pic SW2BRN2 tics 0
|
||||
|
|
|
@ -26,8 +26,8 @@ gameinfo
|
|||
defaultbloodparticlecolor = "ff 00 00"
|
||||
backpacktype = "Backpack"
|
||||
armoricons = "ARM1A0", 0.5, "ARM2A0"
|
||||
statusbar = "sbarinfo/doom.txt"
|
||||
//statusbarclass = "DoomStatusBar"
|
||||
//statusbar = "sbarinfo/doom.txt"
|
||||
statusbarclass = "DoomStatusBar"
|
||||
intermissionmusic = "$MUSIC_DM2INT"
|
||||
intermissioncounter = true
|
||||
weaponslot = 1, "Fist", "Chainsaw"
|
||||
|
|
|
@ -25,7 +25,8 @@ gameinfo
|
|||
defaultbloodparticlecolor = "ff 00 00"
|
||||
backpacktype = "BagOfHolding"
|
||||
armoricons = "SHLDA0", 0.75, "SHD2A0"
|
||||
statusbar = "sbarinfo/heretic.txt"
|
||||
//statusbar = "sbarinfo/heretic.txt"
|
||||
statusbarclass = "HereticStatusBar"
|
||||
intermissionmusic = "mus_intr"
|
||||
intermissioncounter = false
|
||||
weaponslot = 1, "Staff", "Gauntlets"
|
||||
|
|
|
@ -27,7 +27,8 @@ gameinfo
|
|||
defaultbloodcolor = "68 00 00"
|
||||
defaultbloodparticlecolor = "ff 00 00"
|
||||
backpacktype = "BagOfHolding" // Hexen doesn't have a backpack so use Heretic's.
|
||||
statusbar = "sbarinfo/hexen.txt"
|
||||
//statusbar = "sbarinfo/hexen.txt"
|
||||
statusbarclass = "HexenStatusBar"
|
||||
intermissionmusic = "hub"
|
||||
intermissioncounter = false
|
||||
weaponslot = 1, "FWeapFist", "CWeapMace", "MWeapWand"
|
||||
|
|
|
@ -33,6 +33,9 @@ version "2.5"
|
|||
#include "zscript/statscreen/statscreen_coop.txt"
|
||||
|
||||
#include "zscript/statusbar/statusbar.txt"
|
||||
#include "zscript/statusbar/doom_sbar.txt"
|
||||
#include "zscript/statusbar/heretic_sbar.txt"
|
||||
#include "zscript/statusbar/hexen_sbar.txt"
|
||||
#include "zscript/statusbar/strife_sbar.txt"
|
||||
#include "zscript/statusbar/sbarinfowrapper.txt"
|
||||
|
||||
|
|
|
@ -501,6 +501,8 @@ class Actor : Thinker native
|
|||
native static int FindUniqueTid(int start = 0, int limit = 0);
|
||||
native void SetShade(color col);
|
||||
native clearscope int GetRenderStyle() const;
|
||||
native clearscope bool CheckKeys(int locknum, bool remote, bool quiet = false);
|
||||
native clearscope Inventory FirstInv() const;
|
||||
|
||||
native clearscope string GetTag(string defstr = "") const;
|
||||
native void SetTag(string defstr = "");
|
||||
|
@ -669,6 +671,7 @@ class Actor : Thinker native
|
|||
native clearscope int GetSpawnHealth() const;
|
||||
native double GetCrouchFactor(int ptr = AAPTR_PLAYER1);
|
||||
native double GetCVar(string cvar);
|
||||
native double GetCVarString(string cvar);
|
||||
native int GetPlayerInput(int inputnum, int ptr = AAPTR_DEFAULT);
|
||||
native int CountProximity(class<Actor> classname, double distance, int flags = 0, int ptr = AAPTR_DEFAULT);
|
||||
native double GetSpriteAngle(int ptr = AAPTR_DEFAULT);
|
||||
|
|
|
@ -14,6 +14,7 @@ struct _ native // These are the global variables, the struct is only here to av
|
|||
native play @PlayerInfo players[MAXPLAYERS];
|
||||
native readonly bool playeringame[MAXPLAYERS];
|
||||
|
||||
native readonly bool automapactive;
|
||||
native play uint gameaction;
|
||||
native readonly int gamestate;
|
||||
native readonly TextureID skyflatnum;
|
||||
|
@ -169,7 +170,7 @@ struct Screen native
|
|||
// 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);
|
||||
statusBar.DrawTexture(tex, (x, y), BaseStatusBar.DI_SCREEN_RIGHT_TOP, 1., (32, 32));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
|
||||
class ListMenuItem : MenuItemBase
|
||||
{
|
||||
void DrawSelector(double xofs, double yofs, TextureID tex)
|
||||
virtual void DrawSelector(double xofs, double yofs, TextureID tex)
|
||||
{
|
||||
if (tex.isNull())
|
||||
{
|
||||
|
|
|
@ -360,6 +360,7 @@ usercmd_t original_cmd;
|
|||
native void SetLogText (String text);
|
||||
native void DropWeapon();
|
||||
native void BringUpWeapon();
|
||||
native bool Resurrect();
|
||||
|
||||
native String GetUserName() const;
|
||||
native Color GetColor() const;
|
||||
|
@ -373,6 +374,28 @@ usercmd_t original_cmd;
|
|||
native float GetAutoaim() const;
|
||||
native bool GetNoAutostartMap() const;
|
||||
native void SetFOV(float fov);
|
||||
native clearscope bool HasWeaponsInSlot(int slot) const;
|
||||
|
||||
clearscope int fragSum () const
|
||||
{
|
||||
int i;
|
||||
int allfrags = 0;
|
||||
int playernum = mo.PlayerNumber();
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (playeringame[i]
|
||||
&& i!=playernum)
|
||||
{
|
||||
allfrags += frags[i];
|
||||
}
|
||||
}
|
||||
|
||||
// JDC hack - negative frags.
|
||||
allfrags -= frags[playernum];
|
||||
return allfrags;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
struct PlayerClass native
|
||||
|
|
195
wadsrc/static/zscript/statusbar/doom_sbar.txt
Normal file
195
wadsrc/static/zscript/statusbar/doom_sbar.txt
Normal file
|
@ -0,0 +1,195 @@
|
|||
class DoomStatusBar : BaseStatusBar
|
||||
{
|
||||
HUDFont mHUDFont;
|
||||
HUDFont mIndexFont;
|
||||
HUDFont mAmountFont;
|
||||
InventoryBarState diparms;
|
||||
|
||||
|
||||
override void Init()
|
||||
{
|
||||
Super.Init();
|
||||
SetSize(32, 320, 200);
|
||||
|
||||
// Create the font used for the fullscreen HUD
|
||||
Font fnt = "HUDFONT_DOOM";
|
||||
mHUDFont = HUDFont.Create(fnt, fnt.GetCharWidth("0"), true, 1, 1);
|
||||
fnt = "INDEXFONT_DOOM";
|
||||
mIndexFont = HUDFont.Create(fnt, fnt.GetCharWidth("0"), true);
|
||||
mAmountFont = HUDFont.Create("INDEXFONT");
|
||||
diparms = InventoryBarState.Create();
|
||||
}
|
||||
|
||||
override void Draw (int state, double TicFrac)
|
||||
{
|
||||
Super.Draw (state, TicFrac);
|
||||
|
||||
if (state == HUD_StatusBar)
|
||||
{
|
||||
BeginStatusBar(320, 200, 32);
|
||||
DrawMainBar (TicFrac);
|
||||
}
|
||||
else if (state == HUD_Fullscreen)
|
||||
{
|
||||
BeginHUD(320, 200, 1., false);
|
||||
DrawFullScreenStuff ();
|
||||
}
|
||||
}
|
||||
|
||||
protected void DrawMainBar (double TicFrac)
|
||||
{
|
||||
DrawImage("STBAR", (0, 168), DI_ITEM_OFFSETS);
|
||||
DrawImage("STTPRCNT", (90, 171), DI_ITEM_OFFSETS);
|
||||
DrawImage("STTPRCNT", (221, 171), DI_ITEM_OFFSETS);
|
||||
|
||||
Inventory a1, a2;
|
||||
int amt1;
|
||||
[a1, a2, amt1] = GetCurrentAmmo();
|
||||
DrawString(mHUDFont, FormatNumber(amt1, 3), (44, 171), DI_TEXT_ALIGN_RIGHT|DI_NOSHADOW);
|
||||
DrawString(mHUDFont, FormatNumber(CPlayer.health, 3), (90, 171), DI_TEXT_ALIGN_RIGHT|DI_NOSHADOW);
|
||||
DrawString(mHUDFont, FormatNumber(GetArmorAmount(), 3), (221, 171), DI_TEXT_ALIGN_RIGHT|DI_NOSHADOW);
|
||||
|
||||
bool locks[6];
|
||||
String image;
|
||||
for(int i = 0; i < 6; i++) locks[i] = CPlayer.mo.CheckKeys(i + 1, false, true);
|
||||
// key 1
|
||||
if (locks[1] && locks[4]) image = "STKEYS6";
|
||||
else if (locks[1]) image = "STKEYS0";
|
||||
else if (locks[4]) image = "STKEYS3";
|
||||
DrawImage(image, (239, 171), DI_ITEM_OFFSETS);
|
||||
// key 2
|
||||
if (locks[2] && locks[5]) image = "STKEYS7";
|
||||
else if (locks[2]) image = "STKEYS1";
|
||||
else if (locks[5]) image = "STKEYS4";
|
||||
else image = "";
|
||||
DrawImage(image, (239, 181), DI_ITEM_OFFSETS);
|
||||
// key 3
|
||||
if (locks[0] && locks[3]) image = "STKEYS8";
|
||||
else if (locks[0]) image = "STKEYS2";
|
||||
else if (locks[3]) image = "STKEYS5";
|
||||
else image = "";
|
||||
DrawImage(image, (239, 191), DI_ITEM_OFFSETS);
|
||||
|
||||
int maxamt;
|
||||
[amt1, maxamt] = GetAmount("Clip");
|
||||
DrawString(mIndexFont, FormatNumber(amt1, 3), (288, 173), DI_TEXT_ALIGN_RIGHT);
|
||||
DrawString(mIndexFont, FormatNumber(maxamt, 3), (314, 173), DI_TEXT_ALIGN_RIGHT);
|
||||
|
||||
[amt1, maxamt] = GetAmount("Shell");
|
||||
DrawString(mIndexFont, FormatNumber(amt1, 3), (288, 179), DI_TEXT_ALIGN_RIGHT);
|
||||
DrawString(mIndexFont, FormatNumber(maxamt, 3), (314, 179), DI_TEXT_ALIGN_RIGHT);
|
||||
|
||||
[amt1, maxamt] = GetAmount("RocketAmmo");
|
||||
DrawString(mIndexFont, FormatNumber(amt1, 3), (288, 185), DI_TEXT_ALIGN_RIGHT);
|
||||
DrawString(mIndexFont, FormatNumber(maxamt, 3), (314, 185), DI_TEXT_ALIGN_RIGHT);
|
||||
|
||||
[amt1, maxamt] = GetAmount("Cell");
|
||||
DrawString(mIndexFont, FormatNumber(amt1, 3), (288, 191), DI_TEXT_ALIGN_RIGHT);
|
||||
DrawString(mIndexFont, FormatNumber(maxamt, 3), (314, 191), DI_TEXT_ALIGN_RIGHT);
|
||||
|
||||
if (deathmatch || teamplay)
|
||||
{
|
||||
DrawString(mHUDFont, FormatNumber(CPlayer.FragCount, 3), (138, 171), DI_TEXT_ALIGN_RIGHT);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawImage("STARMS", (104, 168), DI_ITEM_OFFSETS);
|
||||
DrawImage(CPlayer.HasWeaponsInSlot(2)? "STYSNUM2" : "STGNUM2", (111, 171), DI_ITEM_OFFSETS);
|
||||
DrawImage(CPlayer.HasWeaponsInSlot(3)? "STYSNUM3" : "STGNUM3", (123, 171), DI_ITEM_OFFSETS);
|
||||
DrawImage(CPlayer.HasWeaponsInSlot(4)? "STYSNUM4" : "STGNUM4", (135, 171), DI_ITEM_OFFSETS);
|
||||
DrawImage(CPlayer.HasWeaponsInSlot(5)? "STYSNUM5" : "STGNUM5", (111, 181), DI_ITEM_OFFSETS);
|
||||
DrawImage(CPlayer.HasWeaponsInSlot(6)? "STYSNUM6" : "STGNUM6", (123, 181), DI_ITEM_OFFSETS);
|
||||
DrawImage(CPlayer.HasWeaponsInSlot(7)? "STYSNUM7" : "STGNUM7", (135, 181), DI_ITEM_OFFSETS);
|
||||
}
|
||||
|
||||
if (multiplayer)
|
||||
{
|
||||
DrawImage("STFBANY", (143, 168), DI_ITEM_OFFSETS|DI_TRANSLATABLE);
|
||||
}
|
||||
|
||||
if (CPlayer.mo.InvSel != null && !level.NoInventoryBar)
|
||||
{
|
||||
DrawInventoryIcon(CPlayer.mo.InvSel, (160, 198));
|
||||
if (CPlayer.mo.InvSel.Amount > 0)
|
||||
{
|
||||
DrawString(mAmountFont, FormatNumber(CPlayer.mo.InvSel.Amount), (175, 198-mIndexFont.mFont.GetHeight()), DI_TEXT_ALIGN_RIGHT, Font.CR_GOLD);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawTexture(GetMugShot(5), (143, 168), DI_ITEM_OFFSETS);
|
||||
}
|
||||
if (isInventoryBarVisible())
|
||||
{
|
||||
DrawInventoryBar(diparms, (48, 169), 7, DI_ITEM_LEFT_TOP);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void DrawFullScreenStuff ()
|
||||
{
|
||||
Vector2 iconbox = (40, 20);
|
||||
// Draw health
|
||||
let berserk = CPlayer.mo.FindInventory("PowerStrength");
|
||||
DrawImage(berserk? "PSTRA0" : "MEDIA0", (20, -2));
|
||||
DrawString(mHUDFont, FormatNumber(CPlayer.health, 3), (44, -20));
|
||||
|
||||
let armor = CPlayer.mo.FindInventory("BasicArmor");
|
||||
if (armor != null)
|
||||
{
|
||||
DrawInventoryIcon(armor, (20, -22));
|
||||
DrawString(mHUDFont, FormatNumber(armor.Amount, 3), (44, -40));
|
||||
}
|
||||
Inventory ammotype1, ammotype2;
|
||||
[ammotype1, ammotype2] = GetCurrentAmmo();
|
||||
int invY = -20;
|
||||
if (ammotype1 != null)
|
||||
{
|
||||
DrawInventoryIcon(ammotype1, (-14, -4));
|
||||
DrawString(mHUDFont, FormatNumber(ammotype1.Amount, 3), (-30, -20), DI_TEXT_ALIGN_RIGHT);
|
||||
invY -= 20;
|
||||
}
|
||||
if (ammotype2 != null && ammotype2 != ammotype1)
|
||||
{
|
||||
DrawInventoryIcon(ammotype2, (-14, invY + 17));
|
||||
DrawString(mHUDFont, FormatNumber(ammotype2.Amount, 3), (-30, invY), DI_TEXT_ALIGN_RIGHT);
|
||||
invY -= 20;
|
||||
}
|
||||
if (!isInventoryBarVisible() && !level.NoInventoryBar && CPlayer.mo.InvSel != null)
|
||||
{
|
||||
DrawInventoryIcon(CPlayer.mo.InvSel, (-14, invY + 17));
|
||||
DrawString(mHUDFont, FormatNumber(CPlayer.mo.InvSel.Amount, 3), (-30, invY), DI_TEXT_ALIGN_RIGHT);
|
||||
}
|
||||
if (deathmatch)
|
||||
{
|
||||
DrawString(mHUDFont, FormatNumber(CPlayer.FragCount, 3), (-3, 1), DI_TEXT_ALIGN_RIGHT, Font.CR_GOLD);
|
||||
}
|
||||
|
||||
// Draw the keys. This does not use a special draw function like SBARINFO because the specifics will be different for each mod
|
||||
// so it's easier to copy or reimplement the following piece of code instead of trying to write a complicated all-encompassing solution.
|
||||
Vector2 keypos = (-10, 2);
|
||||
int rowc = 0;
|
||||
double roww = 0;
|
||||
for(let i = CPlayer.mo.Inv; i != null; i = i.Inv)
|
||||
{
|
||||
if (i is "Key" && i.Icon.IsValid())
|
||||
{
|
||||
DrawTexture(i.Icon, keypos, DI_SCREEN_RIGHT_TOP|DI_ITEM_LEFT_TOP);
|
||||
Vector2 size = TexMan.GetScaledSize(i.Icon);
|
||||
keypos.Y += size.Y + 2;
|
||||
roww = max(roww, size.X);
|
||||
if (++rowc == 3)
|
||||
{
|
||||
keypos.Y = 2;
|
||||
keypos.X -= roww + 2;
|
||||
roww = 0;
|
||||
rowc = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isInventoryBarVisible())
|
||||
{
|
||||
DrawInventoryBar(diparms, (0, 0), 7, DI_SCREEN_CENTER_BOTTOM, HX_SHADOW);
|
||||
}
|
||||
}
|
||||
}
|
208
wadsrc/static/zscript/statusbar/heretic_sbar.txt
Normal file
208
wadsrc/static/zscript/statusbar/heretic_sbar.txt
Normal file
|
@ -0,0 +1,208 @@
|
|||
class HereticStatusBar : BaseStatusBar
|
||||
{
|
||||
DynamicValueInterpolator mHealthInterpolator;
|
||||
HUDFont mHUDFont;
|
||||
HUDFont mIndexFont;
|
||||
HUDFont mBigFont;
|
||||
InventoryBarState diparms;
|
||||
InventoryBarState diparms_sbar;
|
||||
|
||||
|
||||
override void Init()
|
||||
{
|
||||
Super.Init();
|
||||
SetSize(42, 320, 200);
|
||||
|
||||
// Create the font used for the fullscreen HUD
|
||||
Font fnt = "HUDFONT_RAVEN";
|
||||
mHUDFont = HUDFont.Create(fnt, fnt.GetCharWidth("0") + 1, true, 1, 1);
|
||||
fnt = "INDEXFONT_RAVEN";
|
||||
mIndexFont = HUDFont.Create(fnt, fnt.GetCharWidth("0"), true);
|
||||
fnt = "BIGFONT";
|
||||
mBigFont = HUDFont.Create(fnt, fnt.GetCharWidth("0"), true, 2, 2);
|
||||
diparms = InventoryBarState.Create(mIndexFont);
|
||||
diparms_sbar = InventoryBarState.CreateNoBox(mIndexFont, boxsize:(31, 31), arrowoffs:(0,-10));
|
||||
mHealthInterpolator = DynamicValueInterpolator.Create(0, 0.25, 1, 8);
|
||||
}
|
||||
|
||||
override void NewGame ()
|
||||
{
|
||||
Super.NewGame();
|
||||
mHealthInterpolator.Reset (0);
|
||||
}
|
||||
|
||||
override void Tick()
|
||||
{
|
||||
Super.Tick();
|
||||
mHealthInterpolator.Update(CPlayer.health);
|
||||
}
|
||||
|
||||
override void Draw (int state, double TicFrac)
|
||||
{
|
||||
Super.Draw (state, TicFrac);
|
||||
|
||||
if (state == HUD_StatusBar)
|
||||
{
|
||||
BeginStatusBar(320, 200, 42);
|
||||
DrawMainBar (TicFrac);
|
||||
}
|
||||
else if (state == HUD_Fullscreen)
|
||||
{
|
||||
BeginHUD(320, 200, 1., false);
|
||||
DrawFullScreenStuff ();
|
||||
}
|
||||
}
|
||||
|
||||
protected void DrawMainBar (double TicFrac)
|
||||
{
|
||||
DrawImage("BARBACK", (0, 158), DI_ITEM_OFFSETS);
|
||||
DrawImage("LTFCTOP", (0, 148), DI_ITEM_OFFSETS);
|
||||
DrawImage("RTFCTOP", (290, 148), DI_ITEM_OFFSETS);
|
||||
if (isInvulnerable())
|
||||
{
|
||||
//god mode
|
||||
DrawImage("GOD1", (16, 167), DI_ITEM_OFFSETS);
|
||||
DrawImage("GOD2", (287, 167), DI_ITEM_OFFSETS);
|
||||
}
|
||||
//health
|
||||
DrawImage("CHAINCAC", (0, 190), DI_ITEM_OFFSETS);
|
||||
// wiggle the chain if it moves
|
||||
int inthealth = mHealthInterpolator.GetValue();
|
||||
int wiggle = (inthealth != CPlayer.health) && Random[ChainWiggle](0, 1);
|
||||
DrawGem("CHAIN", "LIFEGEM2",inthealth, CPlayer.mo.GetMaxHealth(true), (2, 191 + wiggle), 15, 25, 16, (multiplayer? DI_TRANSLATABLE : 0) | DI_ITEM_LEFT_TOP);
|
||||
DrawImage("LTFACE", (0, 190), DI_ITEM_OFFSETS);
|
||||
DrawImage("RTFACE", (276, 190), DI_ITEM_OFFSETS);
|
||||
DrawShader(SHADER_HORZ, (19, 190), (16, 10));
|
||||
DrawShader(SHADER_HORZ|SHADER_REVERSE, (278, 190), (16, 10));
|
||||
|
||||
if (!isInventoryBarVisible())
|
||||
{
|
||||
//statbar
|
||||
if (!deathmatch)
|
||||
{
|
||||
DrawImage("LIFEBAR", (34, 160), DI_ITEM_OFFSETS);
|
||||
DrawImage("ARMCLEAR", (57, 171), DI_ITEM_OFFSETS);
|
||||
DrawString(mHUDFont, FormatNumber(mHealthInterpolator.GetValue(), 3), (88, 170), DI_TEXT_ALIGN_RIGHT);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawImage("STATBAR", (34, 160), DI_ITEM_OFFSETS);
|
||||
DrawImage("ARMCLEAR", (57, 171), DI_ITEM_OFFSETS);
|
||||
DrawString(mHUDFont, FormatNumber(CPlayer.FragCount, 3), (88, 170), DI_TEXT_ALIGN_RIGHT);
|
||||
}
|
||||
DrawString(mHUDFont, FormatNumber(GetArmorAmount(), 3), (255, 170), DI_TEXT_ALIGN_RIGHT);
|
||||
|
||||
//ammo
|
||||
Ammo ammo1, ammo2;
|
||||
[ammo1, ammo2] = GetCurrentAmmo();
|
||||
if (ammo1 != null && ammo2 == null)
|
||||
{
|
||||
DrawString(mHUDFont, FormatNumber(ammo1.Amount, 3), (136, 162), DI_TEXT_ALIGN_RIGHT);
|
||||
DrawTexture(ammo1.icon, (123, 180), DI_ITEM_CENTER);
|
||||
}
|
||||
else if (ammo2 != null)
|
||||
{
|
||||
DrawString(mIndexFont, FormatNumber(ammo1.Amount, 3), (137, 165), DI_TEXT_ALIGN_RIGHT);
|
||||
DrawString(mIndexFont, FormatNumber(ammo2.Amount, 3), (137, 177), DI_TEXT_ALIGN_RIGHT);
|
||||
DrawTexture(ammo1.icon, (115, 169), DI_ITEM_CENTER);
|
||||
DrawTexture(ammo2.icon, (115, 180), DI_ITEM_CENTER);
|
||||
}
|
||||
|
||||
//keys
|
||||
if (CPlayer.mo.CheckKeys(3, false, true)) DrawImage("YKEYICON", (153, 164), DI_ITEM_OFFSETS);
|
||||
if (CPlayer.mo.CheckKeys(1, false, true)) DrawImage("GKEYICON", (153, 172), DI_ITEM_OFFSETS);
|
||||
if (CPlayer.mo.CheckKeys(2, false, true)) DrawImage("BKEYICON", (153, 180), DI_ITEM_OFFSETS);
|
||||
|
||||
//inventory box
|
||||
if (CPlayer.mo.InvSel != null)
|
||||
{
|
||||
DrawInventoryIcon(CPlayer.mo.InvSel, (194, 175), DI_ARTIFLASH|DI_ITEM_CENTER, boxsize:(28, 28));
|
||||
if (CPlayer.mo.InvSel.Amount > 1)
|
||||
{
|
||||
DrawString(mIndexFont, FormatNumber(CPlayer.mo.InvSel.Amount, 3), (209, 182), DI_TEXT_ALIGN_RIGHT);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawImage("INVBAR", (34, 160), DI_ITEM_OFFSETS);
|
||||
DrawInventoryBar(diparms_sbar, (49, 160), 7, DI_ITEM_LEFT_TOP, HX_SHADOW);
|
||||
}
|
||||
}
|
||||
|
||||
protected void DrawFullScreenStuff ()
|
||||
{
|
||||
//health
|
||||
DrawImage("PTN1A0", (51, -3));
|
||||
DrawString(mBigFont, FormatNumber(mHealthInterpolator.GetValue()), (41, -21), DI_TEXT_ALIGN_RIGHT);
|
||||
|
||||
//armor
|
||||
let armor = CPlayer.mo.FindInventory("BasicArmor");
|
||||
if (armor != null)
|
||||
{
|
||||
DrawInventoryIcon(armor, (58, -24));
|
||||
DrawString(mBigFont, FormatNumber(armor.Amount, 3), (41, -43), DI_TEXT_ALIGN_RIGHT);
|
||||
}
|
||||
//frags/keys
|
||||
if (deathmatch)
|
||||
{
|
||||
DrawString(mHUDFont, FormatNumber(CPlayer.FragCount, 3), (70, -16));
|
||||
}
|
||||
else
|
||||
{
|
||||
Vector2 keypos = (60, -1);
|
||||
int rowc = 0;
|
||||
double roww = 0;
|
||||
for(let i = CPlayer.mo.Inv; i != null; i = i.Inv)
|
||||
{
|
||||
if (i is "Key" && i.Icon.IsValid())
|
||||
{
|
||||
DrawTexture(i.Icon, keypos, DI_ITEM_LEFT_BOTTOM);
|
||||
Vector2 size = TexMan.GetScaledSize(i.Icon);
|
||||
keypos.Y -= size.Y + 2;
|
||||
roww = max(roww, size.X);
|
||||
if (++rowc == 3)
|
||||
{
|
||||
keypos.Y = -1;
|
||||
keypos.X += roww + 2;
|
||||
roww = 0;
|
||||
rowc = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//ammo
|
||||
Ammo ammo1, ammo2;
|
||||
[ammo1, ammo2] = GetCurrentAmmo();
|
||||
int y = -22;
|
||||
if (ammo1 != null)
|
||||
{
|
||||
DrawTexture(ammo1.Icon, (-17, y));
|
||||
DrawString(mHUDFont, FormatNumber(ammo1.Amount, 3), (-3, y+7), DI_TEXT_ALIGN_RIGHT);
|
||||
y -= 40;
|
||||
}
|
||||
if (ammo2 != null)
|
||||
{
|
||||
DrawTexture(ammo2.Icon, (-14, y));
|
||||
DrawString(mHUDFont, FormatNumber(ammo2.Amount, 3), (-3, y+7), DI_TEXT_ALIGN_RIGHT);
|
||||
y -= 40;
|
||||
}
|
||||
|
||||
if (!isInventoryBarVisible() && !level.NoInventoryBar && CPlayer.mo.InvSel != null)
|
||||
{
|
||||
// This code was changed to always fit the item into the box, regardless of alignment or sprite size.
|
||||
// Heretic's ARTIBOX is 30x30 pixels.
|
||||
DrawImage("ARTIBOX", (-46, -1), 0, HX_SHADOW);
|
||||
DrawInventoryIcon(CPlayer.mo.InvSel, (-46, -15), DI_ARTIFLASH|DI_ITEM_CENTER, boxsize:(28, 28));
|
||||
if (CPlayer.mo.InvSel.Amount > 1)
|
||||
{
|
||||
DrawString(mIndexFont, FormatNumber(CPlayer.mo.InvSel.Amount, 3), (-32, -2 - mIndexFont.mFont.GetHeight()), DI_TEXT_ALIGN_RIGHT);
|
||||
}
|
||||
}
|
||||
if (isInventoryBarVisible())
|
||||
{
|
||||
DrawInventoryBar(diparms, (0, 0), 7, DI_SCREEN_CENTER_BOTTOM, HX_SHADOW);
|
||||
}
|
||||
}
|
||||
}
|
258
wadsrc/static/zscript/statusbar/hexen_sbar.txt
Normal file
258
wadsrc/static/zscript/statusbar/hexen_sbar.txt
Normal file
|
@ -0,0 +1,258 @@
|
|||
class HexenStatusBar : BaseStatusBar
|
||||
{
|
||||
DynamicValueInterpolator mHealthInterpolator;
|
||||
DynamicValueInterpolator mHealthInterpolator2;
|
||||
HUDFont mHUDFont;
|
||||
HUDFont mIndexFont;
|
||||
HUDFont mBigFont;
|
||||
InventoryBarState diparms;
|
||||
InventoryBarState diparms_sbar;
|
||||
|
||||
|
||||
override void Init()
|
||||
{
|
||||
Super.Init();
|
||||
SetSize(38, 320, 200);
|
||||
|
||||
// Create the font used for the fullscreen HUD
|
||||
Font fnt = "HUDFONT_RAVEN";
|
||||
mHUDFont = HUDFont.Create(fnt, fnt.GetCharWidth("0") + 1, true, 1, 1);
|
||||
fnt = "INDEXFONT_RAVEN";
|
||||
mIndexFont = HUDFont.Create(fnt, fnt.GetCharWidth("0"), true);
|
||||
fnt = "BIGFONT";
|
||||
mBigFont = HUDFont.Create(fnt, fnt.GetCharWidth("0"), true, 2, 2);
|
||||
diparms = InventoryBarState.Create(mIndexFont);
|
||||
diparms_sbar = InventoryBarState.CreateNoBox(mIndexFont, boxsize:(31, 31), arrowoffs:(0,-10));
|
||||
mHealthInterpolator = DynamicValueInterpolator.Create(0, 0.25, 1, 8);
|
||||
mHealthInterpolator2 = DynamicValueInterpolator.Create(0, 0.25, 1, 6); // the chain uses a maximum of 6, not 8.
|
||||
}
|
||||
|
||||
override void NewGame ()
|
||||
{
|
||||
Super.NewGame();
|
||||
mHealthInterpolator.Reset (0);
|
||||
mHealthInterpolator2.Reset (0);
|
||||
}
|
||||
|
||||
override void Tick()
|
||||
{
|
||||
Super.Tick();
|
||||
mHealthInterpolator.Update(CPlayer.health);
|
||||
mHealthInterpolator2.Update(CPlayer.health);
|
||||
}
|
||||
|
||||
override void Draw (int state, double TicFrac)
|
||||
{
|
||||
Super.Draw (state, TicFrac);
|
||||
|
||||
if (state == HUD_StatusBar)
|
||||
{
|
||||
BeginStatusBar(320, 200, 38);
|
||||
DrawMainBar (TicFrac);
|
||||
}
|
||||
else if (state == HUD_Fullscreen)
|
||||
{
|
||||
BeginHUD(320, 200, 1., false);
|
||||
DrawFullScreenStuff ();
|
||||
}
|
||||
}
|
||||
|
||||
protected void DrawFullScreenStuff ()
|
||||
{
|
||||
//health
|
||||
DrawImage("PTN1A0", (51, -3));
|
||||
DrawString(mBigFont, FormatNumber(mHealthInterpolator.GetValue()), (41, -21), DI_TEXT_ALIGN_RIGHT);
|
||||
|
||||
//frags/keys
|
||||
if (deathmatch)
|
||||
{
|
||||
DrawString(mHUDFont, FormatNumber(CPlayer.FragCount, 3), (70, -16));
|
||||
}
|
||||
|
||||
if (!isInventoryBarVisible() && !level.NoInventoryBar && CPlayer.mo.InvSel != null)
|
||||
{
|
||||
// This code was changed to always fit the item into the box, regardless of alignment or sprite size.
|
||||
// Heretic's ARTIBOX is 30x30 pixels.
|
||||
DrawImage("ARTIBOX", (-66, -1), 0, HX_SHADOW);
|
||||
DrawInventoryIcon(CPlayer.mo.InvSel, (-66, -15), DI_ARTIFLASH|DI_ITEM_CENTER, boxsize:(28, 28));
|
||||
if (CPlayer.mo.InvSel.Amount > 1)
|
||||
{
|
||||
DrawString(mIndexFont, FormatNumber(CPlayer.mo.InvSel.Amount, 3), (-52, -2 - mIndexFont.mFont.GetHeight()), DI_TEXT_ALIGN_RIGHT);
|
||||
}
|
||||
}
|
||||
|
||||
Ammo ammo1, ammo2;
|
||||
[ammo1, ammo2] = GetCurrentAmmo();
|
||||
if ((ammo1 is "Mana1") || (ammo2 is "Mana1")) DrawImage("MANABRT1", (-17, -30), DI_ITEM_OFFSETS);
|
||||
else DrawImage("MANADIM1", (-17, -30), DI_ITEM_OFFSETS);
|
||||
if ((ammo1 is "Mana2") || (ammo2 is "Mana2")) DrawImage("MANABRT2", (-17, -15), DI_ITEM_OFFSETS);
|
||||
else DrawImage("MANADIM2", (-17, -15), DI_ITEM_OFFSETS);
|
||||
DrawString(mHUDFont, FormatNumber(GetAmount("Mana1"), 3), (-21, -30), DI_TEXT_ALIGN_RIGHT);
|
||||
DrawString(mHUDFont, FormatNumber(GetAmount("Mana2"), 3), (-21, -15), DI_TEXT_ALIGN_RIGHT);
|
||||
|
||||
if (isInventoryBarVisible())
|
||||
{
|
||||
DrawInventoryBar(diparms, (0, 0), 7, DI_SCREEN_CENTER_BOTTOM, HX_SHADOW);
|
||||
}
|
||||
}
|
||||
|
||||
protected void DrawMainBar (double TicFrac)
|
||||
{
|
||||
DrawImage("H2BAR", (0, 134), DI_ITEM_OFFSETS);
|
||||
if (!automapactive)
|
||||
{
|
||||
if (isInventoryBarVisible())
|
||||
{
|
||||
DrawImage("INVBAR", (38, 162), DI_ITEM_OFFSETS);
|
||||
DrawInventoryBar(diparms_sbar, (52, 163), 7, DI_ITEM_LEFT_TOP, HX_SHADOW);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawImage("STATBAR", (38, 162), DI_ITEM_OFFSETS);
|
||||
|
||||
//inventory box
|
||||
if (CPlayer.mo.InvSel != null)
|
||||
{
|
||||
DrawInventoryIcon(CPlayer.mo.InvSel, (159.5, 177), DI_ARTIFLASH|DI_ITEM_CENTER, boxsize:(28, 28));
|
||||
if (CPlayer.mo.InvSel.Amount > 1)
|
||||
{
|
||||
DrawString(mIndexFont, FormatNumber(CPlayer.mo.InvSel.Amount, 3), (174, 184), DI_TEXT_ALIGN_RIGHT);
|
||||
}
|
||||
}
|
||||
|
||||
if (deathmatch || teamplay)
|
||||
{
|
||||
DrawImage("KILLS", (38, 163), DI_ITEM_OFFSETS);
|
||||
DrawString(mHUDFont, FormatNumber(CPlayer.FragCount, 3), (66, 176), DI_TEXT_ALIGN_RIGHT);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawImage("ARMCLS", (41, 178), DI_ITEM_OFFSETS);
|
||||
// Note that this has been changed to use red only if the REAL health is below 25, not when an interpolated value is below 25!
|
||||
DrawString(mHUDFont, FormatNumber(mHealthInterpolator.GetValue(), 3), (66, 176), DI_TEXT_ALIGN_RIGHT, CPlayer.Health < 25? Font.CR_RED : Font.CR_UNTRANSLATED);
|
||||
}
|
||||
|
||||
//armor
|
||||
DrawImage("ARMCLS", (255, 178), DI_ITEM_OFFSETS);
|
||||
DrawString(mHUDFont, FormatNumber(GetArmorSavePercent() / 5, 2), (276, 176), DI_TEXT_ALIGN_RIGHT);
|
||||
|
||||
Ammo ammo1, ammo2;
|
||||
[ammo1, ammo2] = GetCurrentAmmo();
|
||||
|
||||
if (ammo1 != null && !(ammo1 is "Mana1") && !(ammo1 is "Mana2"))
|
||||
{
|
||||
DrawImage("HAMOBACK", (77, 164), DI_ITEM_OFFSETS);
|
||||
if (ammo2 != null)
|
||||
{
|
||||
DrawTexture(ammo1.icon, (89, 172), DI_ITEM_CENTER);
|
||||
DrawTexture(ammo2.icon, (113, 172), DI_ITEM_CENTER);
|
||||
DrawString(mIndexFont, FormatNumber(ammo1.amount, 3), ( 98, 182), DI_TEXT_ALIGN_RIGHT);
|
||||
DrawString(mIndexFont, FormatNumber(ammo2.amount, 3), (122, 182), DI_TEXT_ALIGN_RIGHT);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawTexture(ammo1.icon, (100, 172), DI_ITEM_CENTER);
|
||||
DrawString(mIndexFont, FormatNumber(ammo1.amount, 3), (109, 182), DI_TEXT_ALIGN_RIGHT);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int amt1, maxamt1, amt2, maxamt2;
|
||||
[amt1, maxamt1] = GetAmount("Mana1");
|
||||
[amt2, maxamt2] = GetAmount("Mana2");
|
||||
if ((ammo1 is "Mana1") || (ammo2 is "Mana1"))
|
||||
{
|
||||
DrawImage("MANABRT1", (77, 164), DI_ITEM_OFFSETS);
|
||||
DrawBar("MANAVL1", "", amt1, maxamt1, (94, 164), 1, SHADER_VERT, DI_ITEM_OFFSETS);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawImage("MANADIM1", (77, 164), DI_ITEM_OFFSETS);
|
||||
DrawBar("MANAVL1D", "", amt1, maxamt1, (94, 164), 1, SHADER_VERT, DI_ITEM_OFFSETS);
|
||||
}
|
||||
if ((ammo1 is "Mana2") || (ammo2 is "Mana2"))
|
||||
{
|
||||
DrawImage("MANABRT2", (110, 164), DI_ITEM_OFFSETS);
|
||||
DrawBar("MANAVL2", "", amt2, maxamt2, (102, 164), 1, SHADER_VERT, DI_ITEM_OFFSETS);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawImage("MANADIM2", (110, 164), DI_ITEM_OFFSETS);
|
||||
DrawBar("MANAVL2D", "", amt2, maxamt2, (102, 164), 1, SHADER_VERT, DI_ITEM_OFFSETS);
|
||||
}
|
||||
DrawString(mIndexFont, FormatNumber(amt1, 3), ( 92, 181), DI_TEXT_ALIGN_RIGHT);
|
||||
DrawString(mIndexFont, FormatNumber(amt2, 3), (124, 181), DI_TEXT_ALIGN_RIGHT);
|
||||
}
|
||||
if (CPlayer.mo is "ClericPlayer")
|
||||
{
|
||||
DrawImage("WPSLOT1", (190, 162), DI_ITEM_OFFSETS);
|
||||
if (CheckInventory("CWeapWraithverge")) DrawImage("WPFULL1", (190, 162), DI_ITEM_OFFSETS);
|
||||
else
|
||||
{
|
||||
int pieces = GetWeaponPieceMask("CWeapWraithverge");
|
||||
if (pieces & 1) DrawImage("WPIECEC1", (190, 162), DI_ITEM_OFFSETS);
|
||||
if (pieces & 2) DrawImage("WPIECEC2", (212, 162), DI_ITEM_OFFSETS);
|
||||
if (pieces & 4) DrawImage("WPIECEC3", (225, 162), DI_ITEM_OFFSETS);
|
||||
}
|
||||
}
|
||||
else if (CPlayer.mo is "MagePlayer")
|
||||
{
|
||||
DrawImage("WPSLOT2", (190, 162), DI_ITEM_OFFSETS);
|
||||
if (CheckInventory("MWeapBloodscourge")) DrawImage("WPFULL2", (190, 162), DI_ITEM_OFFSETS);
|
||||
else
|
||||
{
|
||||
int pieces = GetWeaponPieceMask("MWeapBloodscourge");
|
||||
if (pieces & 1) DrawImage("WPIECEM1", (190, 162), DI_ITEM_OFFSETS);
|
||||
if (pieces & 2) DrawImage("WPIECEM2", (205, 162), DI_ITEM_OFFSETS);
|
||||
if (pieces & 4) DrawImage("WPIECEM3", (224, 162), DI_ITEM_OFFSETS);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawImage("WPSLOT0", (190, 162), DI_ITEM_OFFSETS);
|
||||
if (CheckInventory("FWeapQuietus")) DrawImage("WPFULL0", (190, 162), DI_ITEM_OFFSETS);
|
||||
else
|
||||
{
|
||||
int pieces = GetWeaponPieceMask("FWeapQuietus");
|
||||
if (pieces & 1) DrawImage("WPIECEF1", (190, 162), DI_ITEM_OFFSETS);
|
||||
if (pieces & 2) DrawImage("WPIECEF2", (225, 162), DI_ITEM_OFFSETS);
|
||||
if (pieces & 4) DrawImage("WPIECEF3", (234, 162), DI_ITEM_OFFSETS);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else // automap
|
||||
{
|
||||
DrawImage("H2BAR", (0, 134), DI_ITEM_OFFSETS);
|
||||
DrawImage("KEYBAR", (38, 162), DI_ITEM_OFFSETS);
|
||||
int cnt = 0;
|
||||
Vector2 keypos = (46, 164);
|
||||
for(let i = CPlayer.mo.Inv; i != null; i = i.Inv)
|
||||
{
|
||||
if (i is "Key" && i.Icon.IsValid())
|
||||
{
|
||||
DrawTexture(i.Icon, keypos, DI_ITEM_OFFSETS);
|
||||
keypos.X += 20;
|
||||
if (++cnt >= 5) break;
|
||||
}
|
||||
}
|
||||
DrawHexenArmor(HEXENARMOR_ARMOR, "ARMSLOT1", (150, 164), DI_ITEM_OFFSETS);
|
||||
DrawHexenArmor(HEXENARMOR_SHIELD, "ARMSLOT2", (181, 164), DI_ITEM_OFFSETS);
|
||||
DrawHexenArmor(HEXENARMOR_HELM, "ARMSLOT3", (212, 164), DI_ITEM_OFFSETS);
|
||||
DrawHexenArmor(HEXENARMOR_AMULET, "ARMSLOT4", (243, 164), DI_ITEM_OFFSETS);
|
||||
}
|
||||
|
||||
String Gem;
|
||||
if (CPlayer.mo is "ClericPlayer") Gem = "LIFEGMC2";
|
||||
else if (CPlayer.mo is "MagePlayer") Gem = "LIFEGMM2";
|
||||
else Gem = "LIFEGMF2";
|
||||
|
||||
int inthealth = mHealthInterpolator2.GetValue();
|
||||
DrawGem("CHAIN", "LIFEGMF2", inthealth, CPlayer.mo.GetMaxHealth(true), (30, 193), -23, 49, 15, (multiplayer? DI_TRANSLATABLE : 0) | DI_ITEM_LEFT_TOP);
|
||||
|
||||
DrawImage("LFEDGE", (0, 193), DI_ITEM_OFFSETS);
|
||||
DrawImage("RTEDGE", (277, 193), DI_ITEM_OFFSETS);
|
||||
}
|
||||
}
|
||||
|
|
@ -8,7 +8,6 @@ struct SBarInfo native ui
|
|||
native void NewGame();
|
||||
native bool MustDrawLog(int state);
|
||||
native void Tick();
|
||||
native void FlashItem(class<Inventory> itemtype);
|
||||
native void ShowPop(int popnum);
|
||||
}
|
||||
|
||||
|
@ -49,7 +48,6 @@ class SBarInfoWrapper : BaseStatusBar
|
|||
Super.NewGame();
|
||||
if (CPlayer != NULL)
|
||||
{
|
||||
AttachToPlayer(CPlayer);
|
||||
core.NewGame();
|
||||
}
|
||||
}
|
||||
|
@ -65,11 +63,6 @@ class SBarInfoWrapper : BaseStatusBar
|
|||
core.Tick();
|
||||
}
|
||||
|
||||
override void FlashItem(class<Inventory> itemtype)
|
||||
{
|
||||
core.FlashItem(itemtype);
|
||||
}
|
||||
|
||||
override void ShowPop(int popnum)
|
||||
{
|
||||
Super.ShowPop(popnum);
|
||||
|
|
|
@ -15,6 +15,92 @@ struct MugShot
|
|||
}
|
||||
}
|
||||
|
||||
class HUDFont native ui
|
||||
{
|
||||
native Font mFont;
|
||||
native static HUDFont Create(Font fnt, int spacing = 0, bool monospaced = false, int shadowx = 0, int shadowy = 0);
|
||||
}
|
||||
|
||||
class InventoryBarState ui
|
||||
{
|
||||
TextureID box;
|
||||
TextureID selector;
|
||||
Vector2 boxsize;
|
||||
Vector2 boxofs;
|
||||
Vector2 selectofs;
|
||||
Vector2 innersize;
|
||||
|
||||
TextureID left;
|
||||
TextureID right;
|
||||
Vector2 arrowoffset;
|
||||
|
||||
double itemalpha;
|
||||
|
||||
HUDFont amountfont;
|
||||
int cr;
|
||||
int flags;
|
||||
|
||||
private static void Init(InventoryBarState me, HUDFont indexfont, int cr, double itemalpha, Vector2 innersize, String leftgfx, String rightgfx, Vector2 arrowoffs, int flags)
|
||||
{
|
||||
me.itemalpha = itemalpha;
|
||||
if (innersize == (0, 0))
|
||||
{
|
||||
me.boxofs = (2, 2);
|
||||
me.innersize = me.boxsize - (4, 4); // Default is based on Heretic's and Hexens icons.
|
||||
}
|
||||
else
|
||||
{
|
||||
me.innersize = innersize;
|
||||
me.boxofs = (me.boxsize - me.innersize) / 2;
|
||||
}
|
||||
if (me.selector.IsValid())
|
||||
{
|
||||
Vector2 sel = TexMan.GetScaledSize(me.selector);
|
||||
me.selectofs = (me.boxsize - sel) / 2;
|
||||
}
|
||||
me.left = TexMan.CheckForTexture(leftgfx, TexMan.TYPE_MiscPatch);
|
||||
me.right = TexMan.CheckForTexture(rightgfx, TexMan.TYPE_MiscPatch);
|
||||
me.arrowoffset = arrowoffs;
|
||||
me.arrowoffset.Y += me.boxsize.Y/2; // default is centered to the side of the box.
|
||||
if (indexfont == null)
|
||||
{
|
||||
me.amountfont = HUDFont.Create("INDEXFONT");
|
||||
if (cr == Font.CR_UNTRANSLATED) cr = Font.CR_GOLD;
|
||||
}
|
||||
else me.amountfont = indexfont;
|
||||
me.cr = cr;
|
||||
me.flags = flags;
|
||||
}
|
||||
|
||||
// The default settings here are what SBARINFO is using.
|
||||
static InventoryBarState Create(HUDFont indexfont = null, int cr = Font.CR_UNTRANSLATED, double itemalpha = 1.,
|
||||
String boxgfx = "ARTIBOX", String selgfx = "SELECTBO", Vector2 innersize = (0, 0),
|
||||
String leftgfx = "INVGEML1", String rightgfx = "INVGEMR1", Vector2 arrowoffs = (0, 0), int flags = 0)
|
||||
{
|
||||
let me = new ("InventoryBarState");
|
||||
me.box = TexMan.CheckForTexture(boxgfx, TexMan.TYPE_MiscPatch);
|
||||
me.selector = TexMan.CheckForTexture(selgfx, TexMan.TYPE_MiscPatch);
|
||||
if (me.box.IsValid() || me.selector.IsValid()) me.boxsize = TexMan.GetScaledSize(me.box.IsValid()? me.box : me.selector);
|
||||
else me.boxsize = (32., 32.);
|
||||
Init(me, indexfont, cr, itemalpha, innersize, leftgfx, rightgfx, arrowoffs, flags);
|
||||
return me;
|
||||
}
|
||||
|
||||
// The default settings here are what SBARINFO is using.
|
||||
static InventoryBarState CreateNoBox(HUDFont indexfont = null, int cr = Font.CR_UNTRANSLATED, double itemalpha = 1.,
|
||||
Vector2 boxsize = (32, 32), String selgfx = "SELECTBO", Vector2 innersize = (0, 0),
|
||||
String leftgfx = "INVGEML1", String rightgfx = "INVGEMR1", Vector2 arrowoffs = (0, 0), int flags = 0)
|
||||
{
|
||||
let me = new ("InventoryBarState");
|
||||
me.box.SetInvalid();
|
||||
me.selector = TexMan.CheckForTexture(selgfx, TexMan.TYPE_MiscPatch);
|
||||
me.boxsize = boxsize;
|
||||
Init(me, indexfont, cr, itemalpha, innersize, leftgfx, rightgfx, arrowoffs, flags);
|
||||
return me;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class BaseStatusBar native ui
|
||||
{
|
||||
|
@ -65,8 +151,73 @@ class BaseStatusBar native ui
|
|||
DI_TRANSLATABLE = 0x20,
|
||||
DI_FORCESCALE = 0x40,
|
||||
DI_DIM = 0x80,
|
||||
};
|
||||
DI_DRAWCURSORFIRST = 0x100, // only for DrawInventoryBar.
|
||||
DI_ALWAYSSHOWCOUNT = 0x200, // only for DrawInventoryBar.
|
||||
DI_DIMDEPLETED = 0x400,
|
||||
DI_DONTANIMATE = 0x800, // do not animate the texture
|
||||
|
||||
DI_SCREEN_AUTO = 0, // decide based on given offsets.
|
||||
DI_SCREEN_MANUAL_ALIGN = 0x4000, // If this is on, the following flags will have an effect
|
||||
|
||||
DI_SCREEN_TOP = DI_SCREEN_MANUAL_ALIGN,
|
||||
DI_SCREEN_VCENTER = 0x8000 | DI_SCREEN_MANUAL_ALIGN,
|
||||
DI_SCREEN_BOTTOM = 0x10000 | DI_SCREEN_MANUAL_ALIGN,
|
||||
DI_SCREEN_VOFFSET = 0x18000 | DI_SCREEN_MANUAL_ALIGN,
|
||||
DI_SCREEN_VMASK = 0x18000 | DI_SCREEN_MANUAL_ALIGN,
|
||||
|
||||
DI_SCREEN_LEFT = DI_SCREEN_MANUAL_ALIGN,
|
||||
DI_SCREEN_HCENTER = 0x20000 | DI_SCREEN_MANUAL_ALIGN,
|
||||
DI_SCREEN_RIGHT = 0x40000 | DI_SCREEN_MANUAL_ALIGN,
|
||||
DI_SCREEN_HOFFSET = 0x60000 | DI_SCREEN_MANUAL_ALIGN,
|
||||
DI_SCREEN_HMASK = 0x60000 | DI_SCREEN_MANUAL_ALIGN,
|
||||
|
||||
DI_SCREEN_LEFT_TOP = DI_SCREEN_TOP|DI_SCREEN_LEFT,
|
||||
DI_SCREEN_RIGHT_TOP = DI_SCREEN_TOP|DI_SCREEN_RIGHT,
|
||||
DI_SCREEN_LEFT_BOTTOM = DI_SCREEN_BOTTOM|DI_SCREEN_LEFT,
|
||||
DI_SCREEN_RIGHT_BOTTOM = DI_SCREEN_BOTTOM|DI_SCREEN_RIGHT,
|
||||
DI_SCREEN_CENTER = DI_SCREEN_VCENTER|DI_SCREEN_HCENTER,
|
||||
DI_SCREEN_CENTER_BOTTOM = DI_SCREEN_BOTTOM|DI_SCREEN_HCENTER,
|
||||
DI_SCREEN_OFFSETS = DI_SCREEN_HOFFSET|DI_SCREEN_VOFFSET,
|
||||
|
||||
DI_ITEM_AUTO = 0, // equivalent with bottom center, which is the default alignment.
|
||||
|
||||
DI_ITEM_TOP = 0x80000,
|
||||
DI_ITEM_VCENTER = 0x100000,
|
||||
DI_ITEM_BOTTOM = 0, // this is the default vertical alignment
|
||||
DI_ITEM_VOFFSET = 0x180000,
|
||||
DI_ITEM_VMASK = 0x180000,
|
||||
|
||||
DI_ITEM_LEFT = 0x200000,
|
||||
DI_ITEM_HCENTER = 0, // this is the deafault horizontal alignment
|
||||
DI_ITEM_RIGHT = 0x400000,
|
||||
DI_ITEM_HOFFSET = 0x600000,
|
||||
DI_ITEM_HMASK = 0x600000,
|
||||
|
||||
DI_ITEM_LEFT_TOP = DI_ITEM_TOP|DI_ITEM_LEFT,
|
||||
DI_ITEM_RIGHT_TOP = DI_ITEM_TOP|DI_ITEM_RIGHT,
|
||||
DI_ITEM_LEFT_BOTTOM = DI_ITEM_BOTTOM|DI_ITEM_LEFT,
|
||||
DI_ITEM_RIGHT_BOTTOM = DI_ITEM_BOTTOM|DI_ITEM_RIGHT,
|
||||
DI_ITEM_CENTER = DI_ITEM_VCENTER|DI_ITEM_HCENTER,
|
||||
DI_ITEM_CENTER_BOTTOM = DI_ITEM_BOTTOM|DI_ITEM_HCENTER,
|
||||
DI_ITEM_OFFSETS = DI_ITEM_HOFFSET|DI_ITEM_VOFFSET,
|
||||
|
||||
DI_TEXT_ALIGN_LEFT = 0,
|
||||
DI_TEXT_ALIGN_RIGHT = 0x800000,
|
||||
DI_TEXT_ALIGN_CENTER = 0x1000000,
|
||||
DI_TEXT_ALIGN = 0x1800000,
|
||||
|
||||
DI_ALPHAMAPPED = 0x2000000,
|
||||
DI_NOSHADOW = 0x4000000,
|
||||
DI_ALWAYSSHOWCOUNTERS = 0x8000000,
|
||||
DI_ARTIFLASH = 0x10000000,
|
||||
DI_FORCEFILL = 0x20000000,
|
||||
|
||||
// These 2 flags are only used by SBARINFO so these duplicate other flags not used by SBARINFO
|
||||
DI_DRAWINBOX = DI_TEXT_ALIGN_RIGHT,
|
||||
DI_ALTERNATEONFAIL = DI_TEXT_ALIGN_CENTER,
|
||||
|
||||
};
|
||||
|
||||
enum IconType
|
||||
{
|
||||
ITYPE_PLAYERICON = 1000,
|
||||
|
@ -87,40 +238,6 @@ class BaseStatusBar native ui
|
|||
HEXENARMOR_AMULET,
|
||||
};
|
||||
|
||||
enum EAlign
|
||||
{
|
||||
ALIGN_TOP = 0,
|
||||
ALIGN_VCENTER = 1,
|
||||
ALIGN_BOTTOM = 2,
|
||||
ALIGN_VOFFSET = 3,
|
||||
ALIGN_VMASK = 3,
|
||||
|
||||
ALIGN_LEFT = 0,
|
||||
ALIGN_HCENTER = 4,
|
||||
ALIGN_RIGHT = 8,
|
||||
ALIGN_HOFFSET = 12,
|
||||
ALIGN_HMASK = 12,
|
||||
|
||||
ALIGN_CENTER = ALIGN_VCENTER|ALIGN_HCENTER,
|
||||
ALIGN_CENTER_BOTTOM = ALIGN_BOTTOM|ALIGN_HCENTER,
|
||||
ALIGN_OFFSETS = ALIGN_HOFFSET|ALIGN_VOFFSET
|
||||
};
|
||||
|
||||
enum ETextAlign
|
||||
{
|
||||
TEXT_LEFT = 0,
|
||||
TEXT_CENTER = 1,
|
||||
TEXT_RIGHT = 2
|
||||
};
|
||||
|
||||
enum SBGameModes
|
||||
{
|
||||
GAMEMODE_SINGLEPLAYER = 0x1,
|
||||
GAMEMODE_COOPERATIVE = 0x2,
|
||||
GAMEMODE_DEATHMATCH = 0x4,
|
||||
GAMEMODE_TEAMGAME = 0x8
|
||||
};
|
||||
|
||||
enum AmmoModes
|
||||
{
|
||||
AMMO_PRIMARY,
|
||||
|
@ -141,6 +258,13 @@ class BaseStatusBar native ui
|
|||
FNF_WHENNOTZERO,
|
||||
}
|
||||
|
||||
enum EShade
|
||||
{
|
||||
SHADER_HORZ = 0,
|
||||
SHADER_VERT = 2,
|
||||
SHADER_REVERSE = 1
|
||||
}
|
||||
|
||||
const XHAIRSHRINKSIZE =(1./18);
|
||||
const XHAIRPICKUPSIZE = (2+XHAIRSHRINKSIZE);
|
||||
const POWERUPICONSIZE = 32;
|
||||
|
@ -158,6 +282,8 @@ class BaseStatusBar native ui
|
|||
native PlayerInfo CPlayer;
|
||||
native bool ShowLog;
|
||||
native Vector2 defaultScale; // factor for fully scaled fullscreen display.
|
||||
native int artiflashTick;
|
||||
native double itemflashFade;
|
||||
|
||||
// These are block properties for the drawers. A child class can set them to have a block of items use the same settings.
|
||||
native double Alpha;
|
||||
|
@ -180,22 +306,24 @@ class BaseStatusBar native ui
|
|||
native virtual clearscope void ReceivedWeapon (Weapon weapn);
|
||||
native virtual clearscope void SetMugShotState (String state_name, bool wait_till_done=false, bool reset=false);
|
||||
|
||||
virtual void FlashItem (class<Inventory> itemtype) {}
|
||||
virtual void FlashItem (class<Inventory> itemtype) { artiflashTick = 4; itemflashFade = 0.75; }
|
||||
virtual void AttachToPlayer (PlayerInfo player) { CPlayer = player; }
|
||||
virtual void FlashCrosshair () { CrosshairSize = XHAIRPICKUPSIZE; }
|
||||
virtual void NewGame () {}
|
||||
virtual void NewGame () { if (CPlayer != null) AttachToPlayer(CPlayer); }
|
||||
virtual void ShowPop (int popnum) { ShowLog = (popnum == POP_Log && !ShowLog); }
|
||||
virtual bool MustDrawLog(int state) { return true; }
|
||||
|
||||
native void RefreshBackground () const;
|
||||
native TextureID GetMugshot(PlayerInfo player, String default_face, int accuracy, int stateflags=MugShot.STANDARD);
|
||||
native TextureID GetMugshot(int accuracy, int stateflags=MugShot.STANDARD, String default_face = "STF");
|
||||
|
||||
// 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 = "");
|
||||
native void DrawTexture(TextureID texture, Vector2 pos, int flags = 0, double Alpha = 1., Vector2 box = (-1, -1), Vector2 scale = (1, 1));
|
||||
native void DrawImage(String texture, Vector2 pos, int flags = 0, double Alpha = 1., Vector2 box = (-1, -1), Vector2 scale = (1, 1));
|
||||
native void DrawString(HUDFont font, String string, Vector2 pos, int flags = 0, int translation = Font.CR_UNTRANSLATED, double Alpha = 1., int wrapwidth = -1, int linespacing = 4);
|
||||
native void Fill(Color col, double x, double y, double w, double h, int flags = 0);
|
||||
native static String FormatNumber(int number, int minsize = 0, int maxsize = 0, int format = 0, String prefix = "");
|
||||
|
||||
|
||||
//============================================================================
|
||||
|
@ -207,7 +335,7 @@ class BaseStatusBar native ui
|
|||
//
|
||||
//============================================================================
|
||||
|
||||
Inventory, Inventory, int, int GetCurrentAmmo () const
|
||||
Ammo, Ammo, int, int GetCurrentAmmo () const
|
||||
{
|
||||
Ammo ammo1, ammo2;
|
||||
if (CPlayer.ReadyWeapon != NULL)
|
||||
|
@ -235,7 +363,7 @@ class BaseStatusBar native ui
|
|||
//
|
||||
//============================================================================
|
||||
|
||||
TextureID, Vector2 GetIcon(Inventory item, int flags, bool showdepleted = false)
|
||||
TextureID, Vector2 GetIcon(Inventory item, int flags, bool showdepleted = true)
|
||||
{
|
||||
TextureID icon;
|
||||
Vector2 scale = (1,1);
|
||||
|
@ -245,12 +373,12 @@ class BaseStatusBar native ui
|
|||
bool applyscale;
|
||||
[icon, applyscale] = GetInventoryIcon(item, flags);
|
||||
|
||||
if (item.Amount == 0 && !showdepleted) return icon;
|
||||
if (item.Amount == 0 && !showdepleted) return icon, scale;
|
||||
|
||||
if (applyscale)
|
||||
scale = item.Scale;
|
||||
}
|
||||
return icon;
|
||||
return icon, scale;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -299,6 +427,14 @@ class BaseStatusBar native ui
|
|||
return armor? armor.Amount : 0;
|
||||
}
|
||||
|
||||
int, int GetAmount(class<Inventory> item)
|
||||
{
|
||||
let it = CPlayer.mo.FindInventory(item);
|
||||
int ret1 = it? it.Amount : GetDefaultByType(item).Amount;
|
||||
int ret2 = it? it.MaxAmount : GetDefaultByType(item).MaxAmount;
|
||||
return ret1, ret2;
|
||||
}
|
||||
|
||||
int GetMaxAmount(class<Inventory> item)
|
||||
{
|
||||
let it = CPlayer.mo.FindInventory(item);
|
||||
|
@ -354,20 +490,6 @@ class BaseStatusBar native ui
|
|||
//
|
||||
//============================================================================
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// checks current game mode against a flag mask
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
bool CheckGameMode(int ValidModes)
|
||||
{
|
||||
return (!multiplayer && (ValidModes & GAMEMODE_SINGLEPLAYER)) ||
|
||||
(deathmatch && (ValidModes & GAMEMODE_DEATHMATCH)) ||
|
||||
(multiplayer && !deathmatch && (ValidModes & GAMEMODE_COOPERATIVE)) ||
|
||||
(teamplay && (ValidModes & GAMEMODE_TEAMGAME));
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// checks ammo use of current weapon
|
||||
|
@ -398,7 +520,7 @@ class BaseStatusBar native ui
|
|||
bool isInventoryBarVisible()
|
||||
{
|
||||
if (CPlayer == null) return false;
|
||||
return (CPlayer.inventorytics <= 0 || level.NoInventoryBar);
|
||||
return (CPlayer.inventorytics > 0 && !level.NoInventoryBar);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -448,7 +570,7 @@ class BaseStatusBar native ui
|
|||
//
|
||||
//============================================================================
|
||||
|
||||
bool CheckWeaponPiece(class<Weapon> weap, int piecenum)
|
||||
int CheckWeaponPiece(class<Weapon> weap, int piecenum)
|
||||
{
|
||||
if (CPlayer == null) return false;
|
||||
for(let inv = CPlayer.mo.Inv; inv != NULL; inv = inv.Inv)
|
||||
|
@ -468,6 +590,26 @@ class BaseStatusBar native ui
|
|||
//
|
||||
//============================================================================
|
||||
|
||||
int GetWeaponPieceMask(class<Weapon> weap)
|
||||
{
|
||||
if (CPlayer == null) return false;
|
||||
for(let inv = CPlayer.mo.Inv; inv != NULL; inv = inv.Inv)
|
||||
{
|
||||
let wh = WeaponHolder(inv);
|
||||
if (wh != null && wh.PieceWeapon == weap)
|
||||
{
|
||||
return wh.PieceMask;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// checks if player has the given weapon piece
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
bool WeaponUsesAmmoType(class<Ammo> ammotype)
|
||||
{
|
||||
if (CPlayer == null) return false;
|
||||
|
@ -535,7 +677,7 @@ class BaseStatusBar native ui
|
|||
if (icon.IsValid())
|
||||
{
|
||||
// Each icon gets a 32x32 block.
|
||||
DrawTexture(icon, pos, true, 1.0, ALIGN_TOP|ALIGN_RIGHT, (POWERUPICONSIZE, POWERUPICONSIZE), ALIGN_CENTER_BOTTOM);
|
||||
DrawTexture(icon, pos, DI_SCREEN_RIGHT_TOP, 1.0, (POWERUPICONSIZE, POWERUPICONSIZE));
|
||||
pos.x -= POWERUPICONSIZE;
|
||||
if (pos.x < -maxpos)
|
||||
{
|
||||
|
@ -560,113 +702,13 @@ class BaseStatusBar native ui
|
|||
return Translation.MakeID(TRANSLATION_Players, CPlayer.mo.PlayerNumber());
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// draw stuff
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
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
|
||||
|
||||
alpha *= self.alpha;
|
||||
if (alpha <= 0) return; // invisible
|
||||
|
||||
Vector2 texsize = TexMan.GetScaledSize(texture);
|
||||
texsize.X *= scale.X;
|
||||
texsize.Y *= scale.Y;
|
||||
if (boxsize.X > 0 || boxsize.Y > 0)
|
||||
{
|
||||
double scale1 = 1., scale2 = 1.;
|
||||
|
||||
if (boxsize.X != -1 && (boxsize.X < texsize.X || (flags & DI_FORCESCALE)))
|
||||
{
|
||||
scale1 = boxsize.X / texsize.X;
|
||||
}
|
||||
if (boxsize.Y != -1 && (boxsize.Y < texsize.Y || (flags & DI_FORCESCALE)))
|
||||
{
|
||||
scale2 = boxsize.Y / texsize.Y;
|
||||
}
|
||||
|
||||
if (flags & DI_FORCESCALE)
|
||||
{
|
||||
if (boxsize.X == -1 || (boxsize.Y != -1 && scale2 < scale1))
|
||||
scale1 = scale2;
|
||||
}
|
||||
else scale1 = min(scale1, scale2);
|
||||
|
||||
boxsize = texsize * scale1;
|
||||
}
|
||||
else
|
||||
{
|
||||
boxsize = texsize;
|
||||
}
|
||||
DrawGraphic(texture, animated, pos, Alpha, !!(flags & DI_TRANSLATABLE), !!(flags & DI_DIM), itemAlign, screenAlign, false, boxsize);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
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 ITYPE_PLAYERICON:
|
||||
texture = CPlayer.mo.ScoreIcon;
|
||||
break;
|
||||
|
||||
case ITYPE_AMMO1:
|
||||
case ITYPE_AMMO2:
|
||||
[atype1, atype2] = GetCurrentAmmo();
|
||||
[texture, applyscale] = GetIcon(icontype == ITYPE_AMMO1? atype1 : atype2, flags, true);
|
||||
break;
|
||||
|
||||
case ITYPE_ARMOR:
|
||||
[texture, applyscale] = GetIcon(CPlayer.mo.FindInventory("BasicArmor"), flags, false);
|
||||
break;
|
||||
|
||||
case ITYPE_WEAPON:
|
||||
[texture, applyscale] = GetIcon(CPlayer.ReadyWeapon, flags, false);
|
||||
break;
|
||||
|
||||
case ITYPE_SIGIL:
|
||||
[texture, applyscale] = GetIcon(CPlayer.mo.FindInventory("Sigil"), flags, false);
|
||||
break;
|
||||
|
||||
case ITYPE_SELECTEDINVENTORY:
|
||||
if (CPlayer.mo.InvSel != NULL)
|
||||
texture = CPlayer.mo.InvSel.Icon;
|
||||
break;
|
||||
}
|
||||
DrawTexture(texture, pos, animated, screenalign, alpha, boxsize, itemAlign, flags, applyscale);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
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)
|
||||
void DrawHexenArmor(int armortype, String image, Vector2 pos, int flags = 0, double alpha = 1.0, Vector2 boxsize = (-1, -1), Vector2 scale = (1.,1.))
|
||||
{
|
||||
let harmor = HexenArmor(statusBar.CPlayer.mo.FindInventory("HexenArmor"));
|
||||
if (harmor != NULL)
|
||||
|
@ -681,7 +723,7 @@ class BaseStatusBar native ui
|
|||
}
|
||||
else return;
|
||||
}
|
||||
DrawImage(image, pos, animated, screenalign, alpha, boxsize, itemAlign, flags);
|
||||
DrawImage(image, pos, flags, alpha, boxsize, scale);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -690,15 +732,212 @@ class BaseStatusBar native ui
|
|||
//
|
||||
//============================================================================
|
||||
|
||||
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)
|
||||
void DrawInventoryIcon(Inventory item, Vector2 pos, int flags = 0, double alpha = 1.0, Vector2 boxsize = (-1, -1), Vector2 scale = (1.,1.))
|
||||
{
|
||||
let texture = GetDefaultByType(item).Icon;
|
||||
if (texture.IsValid())
|
||||
static const String flashimgs[]= { "USEARTID", "USEARTIC", "USEARTIB", "USEARTIA" };
|
||||
TextureID texture;
|
||||
Vector2 applyscale;
|
||||
[texture, applyscale] = GetIcon(item, flags, false);
|
||||
|
||||
if((flags & DI_ARTIFLASH) && artiflashTick > 0)
|
||||
{
|
||||
DrawTexture(texture, pos, animated, screenalign, alpha, boxsize, itemAlign, flags);
|
||||
DrawImage(flashimgs[artiflashTick-1], pos, flags | DI_TRANSLATABLE, alpha, boxsize);
|
||||
}
|
||||
else if (texture.IsValid())
|
||||
{
|
||||
if ((flags & DI_DIMDEPLETED) && item.Amount <= 0) flags |= DI_DIM;
|
||||
applyscale.X *= scale.X;
|
||||
applyscale.Y *= scale.Y;
|
||||
DrawTexture(texture, pos, flags, alpha, boxsize, applyscale);
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
void DrawShader(int which, Vector2 pos, Vector2 size, int flags = 0, double alpha = 1.)
|
||||
{
|
||||
static const String texnames[] = {"BarShaderHF", "BarShaderHR", "BarShaderVF", "BarShaderVR" };
|
||||
DrawImage(texnames[which], pos, DI_ITEM_LEFT_TOP|DI_ALPHAMAPPED|DI_FORCEFILL | (flags & ~(DI_ITEM_HMASK|DI_ITEM_VMASK)), alpha, size);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
Vector2, int AdjustPosition(Vector2 position, int flags, double width, double height)
|
||||
{
|
||||
// This must be done here, before altered coordinates get sent to the draw functions.
|
||||
if (!(flags & DI_SCREEN_MANUAL_ALIGN))
|
||||
{
|
||||
if (position.x < 0) flags |= DI_SCREEN_RIGHT;
|
||||
else flags |= DI_SCREEN_LEFT;
|
||||
if (position.y < 0) flags |= DI_SCREEN_BOTTOM;
|
||||
else flags |= DI_SCREEN_TOP;
|
||||
}
|
||||
|
||||
// placement by offset is not supported because the inventory bar is a composite.
|
||||
switch (flags & DI_ITEM_HMASK)
|
||||
{
|
||||
case DI_ITEM_HCENTER: position.x -= width / 2; break;
|
||||
case DI_ITEM_RIGHT: position.x -= width; break;
|
||||
}
|
||||
|
||||
switch (flags & DI_ITEM_VMASK)
|
||||
{
|
||||
case DI_ITEM_VCENTER: position.y -= height / 2; break;
|
||||
case DI_ITEM_BOTTOM: position.y -= height; break;
|
||||
}
|
||||
|
||||
// clear all alignment flags so that the following code only passes on the rest
|
||||
flags &= ~(DI_ITEM_VMASK|DI_ITEM_HMASK);
|
||||
return position, flags;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// note that this does not implement chain wiggling, this is because
|
||||
// it would severely complicate the parameter list. The calling code is
|
||||
// normally in a better position to do the needed calculations anyway.
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
void DrawGem(String chain, String gem, int displayvalue, int maxrange, Vector2 pos, int leftpadding, int rightpadding, int chainmod, int flags = 0)
|
||||
{
|
||||
TextureID chaintex = TexMan.CheckForTexture(chain, TexMan.TYPE_MiscPatch);
|
||||
if (!chaintex.IsValid()) return;
|
||||
Vector2 chainsize = TexMan.GetScaledSize(chaintex);
|
||||
[pos, flags] = AdjustPosition(pos, flags, chainsize.X, chainsize.Y);
|
||||
|
||||
displayvalue = clamp(displayvalue, 0, maxrange);
|
||||
int offset = int(double(chainsize.X - leftpadding - rightpadding) * displayvalue / maxrange);
|
||||
|
||||
DrawTexture(chaintex, pos + (offset % chainmod, 0), flags | DI_ITEM_LEFT_TOP);
|
||||
DrawImage(gem, pos + (offset + leftPadding, 0), flags | DI_ITEM_LEFT_TOP);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// DrawBar
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
void DrawBar(String ongfx, String offgfx, double curval, double maxval, Vector2 position, int border, int vertical, int flags = 0, double alpha = 1.)
|
||||
{
|
||||
let ontex = TexMan.CheckForTexture(ongfx, TexMan.TYPE_MiscPatch);
|
||||
if (!ontex.IsValid()) return;
|
||||
let offtex = TexMan.CheckForTexture(offgfx, TexMan.TYPE_MiscPatch);
|
||||
|
||||
Vector2 texsize = TexMan.GetScaledSize(ontex);
|
||||
[position, flags] = AdjustPosition(position, flags, texsize.X, texsize.Y);
|
||||
|
||||
double value = clamp(curval / maxval, 0, 1);
|
||||
if(border != 0) value = 1. - value; //invert since the new drawing method requires drawing the bg on the fg.
|
||||
|
||||
|
||||
// {cx, cb, cr, cy}
|
||||
double Clip[4];
|
||||
Clip[0] = Clip[1] = Clip[2] = Clip[3] = 0;
|
||||
|
||||
bool horizontal = !(vertical & SHADER_VERT);
|
||||
bool reverse = !!(vertical & SHADER_REVERSE);
|
||||
double sizeOfImage = (horizontal ? texsize.X - border*2 : texsize.Y - border*2);
|
||||
Clip[(!horizontal) | ((!reverse)<<1)] = sizeOfImage - sizeOfImage *value;
|
||||
|
||||
if(border != 0)
|
||||
{
|
||||
for(int i = 0; i < 4; i++) Clip[i] += border;
|
||||
|
||||
//Draw the whole foreground
|
||||
DrawTexture(ontex, position, flags | DI_ITEM_LEFT_TOP);
|
||||
// SetClip
|
||||
}
|
||||
|
||||
if (offtex.IsValid() && TexMan.GetScaledSize(offtex) == texsize) DrawTexture(offtex, position, flags | DI_ITEM_LEFT_TOP);
|
||||
else Fill(color(255,0,0,0), position.X + Clip[0], position.Y + Clip[1], texsize.X - Clip[0] - Clip[2], texsize.Y - Clip[1] - Clip[3]);
|
||||
|
||||
if (border == 0)
|
||||
{
|
||||
// SetClip
|
||||
DrawTexture(ontex, position, flags | DI_ITEM_LEFT_TOP);
|
||||
}
|
||||
// UnsetClip
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// DrawInventoryBar
|
||||
//
|
||||
// This function needs too many parameters, so most have been offloaded to
|
||||
// a struct to keep code readable and allow initialization somewhere outside
|
||||
// the actual drawing code.
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
// Except for the placement information this gets all info from the struct that gets passed in.
|
||||
void DrawInventoryBar(InventoryBarState parms, Vector2 position, int numfields, int flags = 0, double bgalpha = 1.)
|
||||
{
|
||||
double width = parms.boxsize.X * numfields;
|
||||
[position, flags] = AdjustPosition(position, flags, width, parms.boxsize.Y);
|
||||
|
||||
CPlayer.mo.InvFirst = ValidateInvFirst(numfields);
|
||||
if (CPlayer.mo.InvFirst == null) return; // Player has no listed inventory items.
|
||||
|
||||
Vector2 boxsize = parms.boxsize;
|
||||
// First draw all the boxes
|
||||
for(int i = 0; i < numfields; i++)
|
||||
{
|
||||
DrawTexture(parms.box, position + (boxsize.X * i, 0), flags | DI_ITEM_LEFT_TOP, bgalpha);
|
||||
}
|
||||
|
||||
// now the items and the rest
|
||||
|
||||
Vector2 itempos = position + boxsize / 2;
|
||||
Vector2 textpos = position + boxsize - (1, 1 + parms.amountfont.mFont.GetHeight());
|
||||
|
||||
int i = 0;
|
||||
Inventory item;
|
||||
for(item = CPlayer.mo.InvFirst; item != NULL && i < numfields; item = item.NextInv())
|
||||
{
|
||||
for(int j = 0; j < 2; j++)
|
||||
{
|
||||
if (j ^ !!(parms.flags & DI_DRAWCURSORFIRST))
|
||||
{
|
||||
if (item == CPlayer.mo.InvSel)
|
||||
{
|
||||
double flashAlpha = bgalpha;
|
||||
if (flags & DI_ARTIFLASH) flashAlpha *= itemflashFade;
|
||||
DrawTexture(parms.selector, position + parms.selectofs + (boxsize.X * i, 0), flags | DI_ITEM_LEFT_TOP, flashAlpha);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawInventoryIcon(item, itempos + (boxsize.X * i, 0), flags | DI_ITEM_CENTER );
|
||||
}
|
||||
}
|
||||
|
||||
if (parms.amountfont != null && (item.Amount > 1 || (parms.flags & DI_ALWAYSSHOWCOUNTERS)))
|
||||
{
|
||||
DrawString(parms.amountfont, FormatNumber(item.Amount, 0, 5), textpos + (boxsize.X * i, 0), flags | DI_TEXT_ALIGN_RIGHT, parms.cr, parms.itemalpha);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
// Is there something to the left?
|
||||
if (CPlayer.mo.FirstInv() != CPlayer.mo.InvFirst)
|
||||
{
|
||||
DrawTexture(parms.left, position + (-parms.arrowoffset.X, parms.arrowoffset.Y), flags | DI_ITEM_RIGHT|DI_ITEM_VCENTER);
|
||||
}
|
||||
// Is there something to the right?
|
||||
if (item != NULL)
|
||||
{
|
||||
DrawTexture(parms.right, position + parms.arrowoffset + (width, 0), flags | DI_ITEM_LEFT|DI_ITEM_VCENTER);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -721,6 +960,11 @@ class LinearValueInterpolator : Object
|
|||
return v;
|
||||
}
|
||||
|
||||
void Reset(int value)
|
||||
{
|
||||
mCurrentValue = value;
|
||||
}
|
||||
|
||||
// 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)
|
||||
|
@ -746,23 +990,30 @@ class DynamicValueInterpolator : Object
|
|||
{
|
||||
int mCurrentValue;
|
||||
int mMinChange;
|
||||
int mMaxChange;
|
||||
double mChangeFactor;
|
||||
|
||||
|
||||
static DynamicValueInterpolator Create(int startval, double changefactor, int minchange)
|
||||
static DynamicValueInterpolator Create(int startval, double changefactor, int minchange, int maxchange)
|
||||
{
|
||||
let v = new("DynamicValueInterpolator");
|
||||
v.mCurrentValue = startval;
|
||||
v.mMinChange = minchange;
|
||||
v.mMaxChange = maxchange;
|
||||
v.mChangeFactor = changefactor;
|
||||
return v;
|
||||
}
|
||||
|
||||
void Reset(int value)
|
||||
{
|
||||
mCurrentValue = value;
|
||||
}
|
||||
|
||||
// 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));
|
||||
int diff = int(clamp(abs(destvalue - mCurrentValue) * mChangeFactor, mMinChange, mMaxChange));
|
||||
if (mCurrentValue > destvalue)
|
||||
{
|
||||
mCurrentValue = max(destvalue, mCurrentValue - diff);
|
||||
|
|
|
@ -15,23 +15,10 @@ class StrifeStatusBar : BaseStatusBar
|
|||
{
|
||||
imgINVCURS,
|
||||
imgCURSOR01,
|
||||
imgINVBACK,
|
||||
imgINVTOP,
|
||||
imgINVPOP,
|
||||
imgINVPOP2,
|
||||
imgINVPBAK,
|
||||
imgINVPBAK2,
|
||||
imgFONG0,
|
||||
imgFONG1,
|
||||
imgFONG2,
|
||||
imgFONG3,
|
||||
imgFONG4,
|
||||
imgFONG5,
|
||||
imgFONG6,
|
||||
imgFONG7,
|
||||
imgFONG8,
|
||||
imgFONG9,
|
||||
imgFONG_PERCENT,
|
||||
imgFONY0,
|
||||
imgFONY1,
|
||||
imgFONY2,
|
||||
|
@ -43,10 +30,6 @@ class StrifeStatusBar : BaseStatusBar
|
|||
imgFONY8,
|
||||
imgFONY9,
|
||||
imgFONY_PERCENT,
|
||||
imgCOMM,
|
||||
imgMEDI,
|
||||
imgARM1,
|
||||
imgARM2,
|
||||
imgNEGATIVE,
|
||||
};
|
||||
|
||||
|
@ -54,22 +37,41 @@ class StrifeStatusBar : BaseStatusBar
|
|||
int CursorImage;
|
||||
int CurrentPop, PendingPop, PopHeight, PopHeightChange;
|
||||
int KeyPopPos, KeyPopScroll;
|
||||
double ItemFlash;
|
||||
|
||||
HUDFont mYelFont, mGrnFont, mBigFont;
|
||||
|
||||
override void Init()
|
||||
{
|
||||
static const Name strifeLumpNames[] =
|
||||
{
|
||||
"INVCURS", "CURSOR01", "INVPOP", "INVPOP2",
|
||||
"INVPBAK", "INVPBAK2",
|
||||
"INVFONY0", "INVFONY1", "INVFONY2", "INVFONY3", "INVFONY4",
|
||||
"INVFONY5", "INVFONY6", "INVFONY7", "INVFONY8", "INVFONY9",
|
||||
"INVFONY%", ""
|
||||
|
||||
};
|
||||
|
||||
Super.Init();
|
||||
SetSize(32, 320, 200);
|
||||
DoCommonInit();
|
||||
Reset();
|
||||
|
||||
for(int i = 0; i <= imgNEGATIVE; i++)
|
||||
{
|
||||
Images[i] = TexMan.CheckForTexture(strifeLumpNames[i], TexMan.TYPE_MiscPatch);
|
||||
}
|
||||
|
||||
CursorImage = Images[imgINVCURS].IsValid() ? imgINVCURS : imgCURSOR01;
|
||||
|
||||
mYelFont = HUDFont.Create("Indexfont_Strife_Yellow", 7, true, 1, 1);
|
||||
mGrnFont = HUDFont.Create("Indexfont_Strife_Green", 7, true, 1, 1);
|
||||
mBigFont = HUDFont.Create("BigFont", 0, false, 2, 2);
|
||||
}
|
||||
|
||||
override void NewGame ()
|
||||
{
|
||||
DoCommonInit ();
|
||||
if (CPlayer != NULL)
|
||||
{
|
||||
AttachToPlayer (CPlayer);
|
||||
}
|
||||
Super.NewGame();
|
||||
Reset ();
|
||||
}
|
||||
|
||||
override void Draw (int state, double TicFrac)
|
||||
|
@ -78,21 +80,22 @@ class StrifeStatusBar : BaseStatusBar
|
|||
|
||||
if (state == HUD_StatusBar)
|
||||
{
|
||||
fullscreenoffsets = false;
|
||||
BeginStatusBar(320, 200, 32);
|
||||
DrawMainBar (TicFrac);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (state == HUD_Fullscreen)
|
||||
{
|
||||
fullscreenoffsets = true;
|
||||
BeginHUD(320, 200, 1., false);
|
||||
DrawFullScreenStuff ();
|
||||
}
|
||||
|
||||
// Draw pop screen (log, keys, and status)
|
||||
if (CurrentPop != POP_None && PopHeight < 0)
|
||||
{
|
||||
fullscreenoffsets = false;
|
||||
// This uses direct low level draw commands and would otherwise require calling
|
||||
// BeginStatusBar(320, 200, false, true);
|
||||
DrawPopScreen (screen.GetHeight(), TicFrac);
|
||||
}
|
||||
}
|
||||
|
@ -141,50 +144,19 @@ class StrifeStatusBar : BaseStatusBar
|
|||
return false;
|
||||
}
|
||||
|
||||
void DoCommonInit ()
|
||||
void Reset ()
|
||||
{
|
||||
static const String strifeLumpNames[] =
|
||||
{
|
||||
"INVCURS", "CURSOR01", "INVBACK", "INVTOP", "INVPOP", "INVPOP2",
|
||||
"INVPBAK", "INVPBAK2",
|
||||
"INVFONG0", "INVFONG1", "INVFONG2", "INVFONG3", "INVFONG4",
|
||||
"INVFONG5", "INVFONG6", "INVFONG7", "INVFONG8", "INVFONG9",
|
||||
"INVFONG%",
|
||||
"INVFONY0", "INVFONY1", "INVFONY2", "INVFONY3", "INVFONY4",
|
||||
"INVFONY5", "INVFONY6", "INVFONY7", "INVFONY8", "INVFONY9",
|
||||
"INVFONY%",
|
||||
"I_COMM", "I_MDKT", "I_ARM1", "I_ARM2", ""
|
||||
|
||||
};
|
||||
|
||||
for(int i = 0; i <= imgNEGATIVE; i++)
|
||||
{
|
||||
Images[i] = TexMan.CheckForTexture(strifeLumpNames[i], TexMan.TYPE_MiscPatch);
|
||||
}
|
||||
|
||||
CursorImage = Images[imgINVCURS].IsValid() ? imgINVCURS : imgCURSOR01;
|
||||
|
||||
CurrentPop = POP_None;
|
||||
PendingPop = POP_NoChange;
|
||||
PopHeight = 0;
|
||||
KeyPopPos = 0;
|
||||
KeyPopScroll = 0;
|
||||
ItemFlash = 0;
|
||||
}
|
||||
|
||||
override void Tick ()
|
||||
{
|
||||
Super.Tick ();
|
||||
|
||||
if (ItemFlash > 0)
|
||||
{
|
||||
ItemFlash -= 1/14.;
|
||||
if (ItemFlash < 0)
|
||||
{
|
||||
ItemFlash = 0;
|
||||
}
|
||||
}
|
||||
|
||||
PopHeightChange = 0;
|
||||
if (PendingPop != POP_NoChange)
|
||||
{
|
||||
|
@ -228,11 +200,6 @@ class StrifeStatusBar : BaseStatusBar
|
|||
}
|
||||
}
|
||||
|
||||
override void FlashItem (Class<Inventory> itemtype)
|
||||
{
|
||||
ItemFlash = 0.75;
|
||||
}
|
||||
|
||||
private void FillBar(double x, double y, double start, double stopp, Color color1, Color color2)
|
||||
{
|
||||
Vector2 virt = Scaled? (320., 200.) : (screen.GetWidth(), screen.GetHeight());
|
||||
|
@ -304,11 +271,11 @@ class StrifeStatusBar : BaseStatusBar
|
|||
DrawPopScreen (Scaled ? (ST_Y - 8) * screen.GetHeight() / 200 : ST_Y - 8, TicFrac);
|
||||
}
|
||||
|
||||
DrawTexture(Images[imgINVBACK], (0, 0), true, 1.0, itemAlign:ALIGN_OFFSETS);
|
||||
DrawTexture(Images[imgINVTOP], (0, -8), true, 1.0, itemAlign:ALIGN_OFFSETS);
|
||||
DrawImage("INVBACK", (0, 168), DI_ITEM_OFFSETS);
|
||||
DrawImage("INVTOP", (0, 160), DI_ITEM_OFFSETS);
|
||||
|
||||
// Health
|
||||
DrawString("Indexfont_Strife_Green", FormatNumber(CPlayer.health, 3, 5, 0), (86, -6), 1.0, Font.CR_UNTRANSLATED, TEXT_RIGHT, 0, 7, true, 1, 1);
|
||||
DrawString(mGrnFont, FormatNumber(CPlayer.health, 3, 5), (79, 162), DI_TEXT_ALIGN_RIGHT);
|
||||
int points;
|
||||
if (CPlayer.cheats & CF_GODMODE)
|
||||
{
|
||||
|
@ -318,33 +285,30 @@ class StrifeStatusBar : BaseStatusBar
|
|||
{
|
||||
points = min(CPlayer.health, 200);
|
||||
}
|
||||
DrawHealthBar (points, 49, 4);
|
||||
DrawHealthBar (points, 49, 7);
|
||||
DrawHealthBar (points, 49, 172);
|
||||
DrawHealthBar (points, 49, 175);
|
||||
|
||||
// Armor
|
||||
item = CPlayer.mo.FindInventory('BasicArmor');
|
||||
if (item != NULL && item.Amount > 0)
|
||||
{
|
||||
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);
|
||||
DrawInventoryIcon(item, (2, 177), DI_ITEM_OFFSETS);
|
||||
DrawString(mYelFont, FormatNumber(item.Amount, 3, 5), (27, 191), DI_TEXT_ALIGN_RIGHT);
|
||||
}
|
||||
|
||||
// Ammo
|
||||
Inventory ammo1, ammo2;
|
||||
int ammocount1, ammocount2;
|
||||
|
||||
[ammo1, ammo2, ammocount1, ammocount2] = GetCurrentAmmo ();
|
||||
Inventory ammo1 = GetCurrentAmmo ();
|
||||
if (ammo1 != NULL)
|
||||
{
|
||||
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);
|
||||
DrawString(mGrnFont, FormatNumber(ammo1.Amount, 3, 5), (311, 162), DI_TEXT_ALIGN_RIGHT);
|
||||
DrawInventoryIcon (ammo1, (290, 181), DI_ITEM_OFFSETS);
|
||||
}
|
||||
|
||||
// Sigil
|
||||
item = CPlayer.mo.FindInventory('Sigil');
|
||||
if (item != NULL)
|
||||
{
|
||||
DrawTexture (item.Icon, (253, 7), true, 1.0, itemAlign:ALIGN_OFFSETS);
|
||||
DrawInventoryIcon (item, (253, 175), DI_ITEM_OFFSETS);
|
||||
}
|
||||
|
||||
// Inventory
|
||||
|
@ -353,32 +317,29 @@ class StrifeStatusBar : BaseStatusBar
|
|||
i = 0;
|
||||
for (item = CPlayer.mo.InvFirst; item != NULL && i < 6; item = item.NextInv())
|
||||
{
|
||||
int flags = item.Amount <= 0? DI_ITEM_OFFSETS|DI_DIM : DI_ITEM_OFFSETS;
|
||||
if (item == CPlayer.mo.InvSel)
|
||||
{
|
||||
DrawTexture (item.Icon, (42 + 35*i, 12), true, 1. - ItemFlash, itemAlign:ALIGN_OFFSETS, item.Amount <= 0? DI_DIM : 0);
|
||||
DrawTexture (Images[CursorImage], (42 + 35*i, 180), flags, 1. - itemflashFade);
|
||||
}
|
||||
if (item.Icon.isValid())
|
||||
{
|
||||
DrawTexture (item.Icon, (48 + 35*i, 14), true, 1.0, itemAlign:ALIGN_OFFSETS, item.Amount <= 0? DI_DIM : 0);
|
||||
}
|
||||
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);
|
||||
DrawInventoryIcon (item, (48 + 35*i, 182), flags);
|
||||
DrawString(mYelFont, FormatNumber(item.Amount, 3, 5), (75 + 35*i, 191), DI_TEXT_ALIGN_RIGHT);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
protected void DrawFullScreenStuff ()
|
||||
{
|
||||
// Draw health
|
||||
|
||||
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 health (use red color if health is below the run health threashold.)
|
||||
DrawString(mGrnFont, FormatNumber(CPlayer.health, 3), (4, -10), DI_TEXT_ALIGN_LEFT, (CPlayer.health < CPlayer.mo.RunHealth)? Font.CR_BRICK : Font.CR_UNTRANSLATED);
|
||||
DrawImage("I_MDKT", (14, -17));
|
||||
|
||||
// Draw armor
|
||||
let armor = CPlayer.mo.FindInventory('BasicArmor');
|
||||
if (armor != NULL && armor.Amount != 0)
|
||||
{
|
||||
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);
|
||||
DrawString(mYelFont, FormatNumber(armor.Amount, 3), (35, -10));
|
||||
DrawInventoryIcon(armor, (45, -17));
|
||||
}
|
||||
|
||||
// Draw ammo
|
||||
|
@ -389,19 +350,19 @@ class StrifeStatusBar : BaseStatusBar
|
|||
if (ammo1 != NULL)
|
||||
{
|
||||
// Draw primary ammo in the bottom-right corner
|
||||
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);
|
||||
DrawString(mGrnFont, FormatNumber(ammo1.Amount, 3), (-23, -10));
|
||||
DrawInventoryIcon(ammo1, (-14, -17));
|
||||
if (ammo2 != NULL && ammo1!=ammo2)
|
||||
{
|
||||
// Draw secondary ammo just above the primary ammo
|
||||
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);
|
||||
DrawString(mGrnFont, FormatNumber(ammo1.Amount, 3), (-23, -48));
|
||||
DrawInventoryIcon(ammo1, (-14, -55));
|
||||
}
|
||||
}
|
||||
|
||||
if (deathmatch)
|
||||
{ // Draw frags (in DM)
|
||||
DrawString("BigFont", FormatNumber(CPlayer.FragCount, 3, 0, 0), (-44, 1), 1., Font.CR_UNTRANSLATED, TEXT_LEFT, ALIGN_RIGHT|ALIGN_TOP, 0, false, 2, 2);
|
||||
DrawString(mBigFont, FormatNumber(CPlayer.FragCount, 3), (4, 1));
|
||||
}
|
||||
|
||||
// Draw inventory
|
||||
|
@ -409,12 +370,12 @@ class StrifeStatusBar : BaseStatusBar
|
|||
{
|
||||
if (CPlayer.mo.InvSel != null)
|
||||
{
|
||||
if (ItemFlash > 0)
|
||||
if (itemflashFade > 0)
|
||||
{
|
||||
DrawTexture(Images[CursorImage], (-28, -15), true, 1.0, ALIGN_BOTTOM|ALIGN_RIGHT, ItemAlign:ALIGN_BOTTOM|ALIGN_RIGHT);
|
||||
DrawTexture(Images[CursorImage], (-42, -15));
|
||||
}
|
||||
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);
|
||||
DrawString(mYelFont, FormatNumber(CPlayer.mo.InvSel.Amount, 3, 5), (-30, -10), DI_TEXT_ALIGN_RIGHT);
|
||||
DrawInventoryIcon(CPlayer.mo.InvSel, (-42, -17), DI_DIMDEPLETED);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -429,18 +390,17 @@ class StrifeStatusBar : BaseStatusBar
|
|||
{
|
||||
if (item == CPlayer.mo.InvSel)
|
||||
{
|
||||
DrawTexture(Images[CursorImage], (-90+i*35, -3), true, 0.75, ALIGN_CENTER_BOTTOM, ItemAlign:ALIGN_CENTER_BOTTOM);
|
||||
DrawTexture(Images[CursorImage], (-90+i*35, -3), DI_SCREEN_CENTER_BOTTOM, 0.75);
|
||||
}
|
||||
if (item.Icon.isValid())
|
||||
{
|
||||
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);
|
||||
DrawInventoryIcon(item, (-90+i*35, -5), DI_SCREEN_CENTER_BOTTOM|DI_DIMDEPLETED, 0.75);
|
||||
}
|
||||
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);
|
||||
DrawString(mYelFont, FormatNumber(item.Amount, 3, 5), (-72 + i*35, -8), DI_TEXT_ALIGN_RIGHT|DI_SCREEN_CENTER_BOTTOM);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
fullscreenoffsets = false;
|
||||
}
|
||||
|
||||
protected void DrawPopScreen (int bottom, double TicFrac)
|
||||
|
|
Loading…
Reference in a new issue