- changed all texture access in the play code to use FGameTexture and redid Hexen's front sky layer by adding a new texture instead of hacking the existing one.

This commit is contained in:
Christoph Oelckers 2020-04-14 18:01:51 +02:00
parent 9e7094848c
commit b9b6a354c7
20 changed files with 91 additions and 77 deletions

View file

@ -214,6 +214,31 @@ FTexture *FTexture::GetRawTexture()
return OffsetLess;
}
//==========================================================================
//
// Same shit for a different hack, this time Hexen's front sky layers.
//
//==========================================================================
FTexture* FTexture::GetFrontSkyLayer()
{
if (FrontSkyLayer) return FrontSkyLayer;
// Reject anything that cannot have been a front layer for the sky in Hexen.
auto image = GetImage();
if (image == nullptr || !image->SupportRemap0() || UseType != ETextureType::Wall || Scale.X != 1 || Scale.Y != 1 || bWorldPanning || _TopOffset[0] != 0 ||
image->GetWidth() != GetTexelWidth() || image->GetHeight() != GetTexelHeight())
{
FrontSkyLayer = this;
return this;
}
FrontSkyLayer = new FImageTexture(image, "");
TexMan.AddTexture(FrontSkyLayer);
FrontSkyLayer->bNoRemap0 = true;
return FrontSkyLayer;
}
void FTexture::SetDisplaySize(int fitwidth, int fitheight)
{
Scale.X = double(Width) / fitwidth;
@ -849,6 +874,10 @@ void FTexCoordInfo::GetFromTexture(FTexture *tex, float x, float y, bool forcewo
mWidth = tex->GetTexelWidth();
}
void FTexCoordInfo::GetFromTexture(FGameTexture* tex, float x, float y, bool forceworldpanning)
{
GetFromTexture(tex->GetTexture(), x, y, forceworldpanning);
}
//==========================================================================
//

View file

@ -48,6 +48,7 @@
typedef TMap<int, bool> SpriteHits;
class FImageSource;
class FGameTexture;
enum MaterialShaderIndex
{
@ -263,7 +264,8 @@ public:
int GetDisplayTopOffset() { return GetScaledTopOffset(0); }
double GetDisplayLeftOffsetDouble(int adjusted = 0) { return _LeftOffset[adjusted] / Scale.X; }
double GetDisplayTopOffsetDouble(int adjusted = 0) { return _TopOffset[adjusted] / Scale.Y; }
FTexture* GetFrontSkyLayer();
int GetTexelWidth() { return Width; }
int GetTexelHeight() { return Height; }
int GetTexelLeftOffset(int adjusted) { return _LeftOffset[adjusted]; }
@ -308,8 +310,6 @@ public:
bool UseWorldPanning() const { return bWorldPanning; }
void SetWorldPanning(bool on) { bWorldPanning = on; }
void SetDisplaySize(int fitwidth, int fitheight);
void SetFrontSkyLayer(bool on = true) { bNoRemap0 = on; }
bool IsFrontSkyLayer() { return bNoRemap0; }
void CopySize(FTexture* BaseTexture)
@ -365,6 +365,8 @@ protected:
// Offset-less version for COMPATF_MASKEDMIDTEX
FTexture *OffsetLess = nullptr;
// Front sky layer variant where color 0 is transparent
FTexture* FrontSkyLayer = nullptr;
// Paletted variant
FTexture *PalVersion = nullptr;
// Material layers
@ -570,6 +572,7 @@ struct FTexCoordInfo
float TextureOffset(float ofs) const;
float TextureAdjustWidth() const;
void GetFromTexture(FTexture *tex, float x, float y, bool forceworldpanning);
void GetFromTexture(FGameTexture* tex, float x, float y, bool forceworldpanning);
};
// Refactoring helper to allow piece by piece adjustment of the API
@ -593,7 +596,8 @@ public:
bool isHardwareCanvas() const { return wrapped.isHardwareCanvas(); } // There's two here so that this can deal with software canvases in the hardware renderer later.
bool isSoftwareCanvas() const { return wrapped.isCanvas(); }
bool isMiscPatch() const { return wrapped.GetUseType() == ETextureType::MiscPatch; } // only used by the intermission screen to decide whether to tile the background image or not.
bool useWorldPanning() { return wrapped.UseWorldPanning(); }
bool useWorldPanning() const { return wrapped.UseWorldPanning(); }
bool allowNoDecals() const { return wrapped.allowNoDecals(); }
ETextureType GetUseType() const { return wrapped.GetUseType(); }
float GetShaderSpeed() const { return wrapped.GetShaderSpeed(); }
uint16_t GetRotations() const { return wrapped.GetRotations(); }
@ -602,10 +606,18 @@ public:
ISoftwareTexture* GetSoftwareTexture() { return wrapped.GetSoftwareTexture(); }
void SetSoftwareTexture(ISoftwareTexture* swtex) { wrapped.SetSoftwareTextue(swtex); }
void SetScale(DVector2 vec) { wrapped.SetScale(vec); }
const FString& GetName() const { return wrapped.GetName(); }
// These substitutions must be done on the material level because their sizes can differ. Substitution must happen before any coordinate calculations take place.
FGameTexture* GetPalVersion() { return reinterpret_cast<FGameTexture*>(wrapped.GetPalVersion()); }
FGameTexture* GetRawTexture() { return reinterpret_cast<FGameTexture*>(wrapped.GetRawTexture()); }
FGameTexture* GetFrontSkyLayer() { return reinterpret_cast<FGameTexture*>(wrapped.GetFrontSkyLayer()); }
// Glowing is a pure material property that should not filter down to the actual texture objects.
void GetGlowColor(float* data) { wrapped.GetGlowColor(data); }
bool isGlowing() const { return wrapped.isGlowing(); }
bool isAutoGlowing() const { return wrapped.isAutoGlowing(); }
int GetGlowHeight() const { return wrapped.GetGlowHeight(); }
bool isUserContent() const;
};

View file

@ -2646,22 +2646,6 @@ static void PatchTextures()
texture->SetUseType(ETextureType::Null);
}
}
// Hexen parallax skies use color 0 to indicate transparency on the front
// layer, so we must not remap color 0 on these textures. Unfortunately,
// the only way to identify these textures is to check the MAPINFO.
for (unsigned int i = 0; i < wadlevelinfos.Size(); ++i)
{
if (wadlevelinfos[i].flags & LEVEL_DOUBLESKY)
{
FTextureID picnum = TexMan.CheckForTexture(wadlevelinfos[i].SkyPic1, ETextureType::Wall, false);
if (picnum.isValid())
{
TexMan.GetTexture(picnum)->SetFrontSkyLayer();
}
}
}
}
//==========================================================================

View file

@ -75,7 +75,7 @@ CCMD(listlights)
if (dl->target)
{
FTextureID spr = sprites[dl->target->sprite].GetSpriteFrame(dl->target->frame, 0, 0., nullptr);
Printf(", frame = %s ", TexMan.GetTexture(spr)->GetName().GetChars());
Printf(", frame = %s ", TexMan.GetGameTexture(spr)->GetName().GetChars());
}

View file

@ -772,17 +772,7 @@ void FTextureAnimator::FixAnimations ()
for (i = 0; i < mAnimations.Size(); ++i)
{
FAnimDef *anim = mAnimations[i];
if (anim->bDiscrete)
{
if (TexMan.Texture(anim->BasePic)->IsFrontSkyLayer())
{
for (j = 0; j < anim->NumFrames; ++j)
{
TexMan.Texture(anim->Frames[j].FramePic)->SetFrontSkyLayer ();
}
}
}
else
if (!anim->bDiscrete)
{
bool nodecals;
bool noremap = false;
@ -793,16 +783,8 @@ void FTextureAnimator::FixAnimations ()
for (j = 0; j < anim->NumFrames; ++j)
{
FTexture *tex = TexMan.Texture(anim->BasePic + j);
noremap |= tex->IsFrontSkyLayer();
tex->SetNoDecals(nodecals);
}
if (noremap)
{
for (j = 0; j < anim->NumFrames; ++j)
{
TexMan.Texture(anim->BasePic + j)->SetFrontSkyLayer ();
}
}
}
}
}

View file

@ -219,15 +219,15 @@ void HU_GetPlayerWidths(int &maxnamewidth, int &maxscorewidth, int &maxiconheigh
auto icon = FSetTextureID(players[i].mo->IntVar(NAME_ScoreIcon));
if (icon.isValid())
{
FTexture *pic = TexMan.GetTexture(icon);
width = pic->GetDisplayWidth() - pic->GetDisplayLeftOffset() + 2;
auto pic = TexMan.GetGameTexture(icon);
width = int(pic->GetDisplayWidth() - pic->GetDisplayLeftOffset() + 2.5);
if (width > maxscorewidth)
{
maxscorewidth = width;
}
// The icon's top offset does not count toward its height, because
// zdoom.pk3's standard Hexen class icons are designed that way.
int height = pic->GetDisplayHeight() - pic->GetDisplayTopOffset();
int height = int(pic->GetDisplayHeight() - pic->GetDisplayTopOffset() + 0.5);
if (height > maxiconheight)
{
maxiconheight = height;

View file

@ -341,7 +341,7 @@ FTextureID DBaseDecal::StickToWall (side_t *wall, double x, double y, F3DFloor *
else return FNullTextureID();
CalcFracPos (wall, x, y);
FTexture *texture = TexMan.GetTexture(tex);
auto texture = TexMan.GetGameTexture(tex);
if (texture == NULL || texture->allowNoDecals())
{
@ -613,19 +613,19 @@ void DBaseDecal::SpreadRight (double r, side_t *feelwall, double wallsize, F3DFl
void DBaseDecal::Spread (const FDecalTemplate *tpl, side_t *wall, double x, double y, double z, F3DFloor * ffloor)
{
SpreadInfo spread;
FTexture *tex;
FGameTexture *tex;
vertex_t *v1;
double rorg, ldx, ldy;
GetWallStuff (wall, v1, ldx, ldy);
rorg = Length (x - v1->fX(), y - v1->fY());
if ((tex = TexMan.GetTexture(PicNum)) == NULL)
if ((tex = TexMan.GetGameTexture(PicNum)) == NULL)
{
return;
}
int dwidth = tex->GetDisplayWidth ();
double dwidth = tex->GetDisplayWidth ();
spread.DecalWidth = dwidth * ScaleX;
spread.DecalLeft = tex->GetDisplayLeftOffset() * ScaleX;

View file

@ -1878,7 +1878,7 @@ void FParser::SF_FloorTexture(void)
}
t_return.type = svt_string;
FTexture * tex = TexMan.GetTexture(sector->GetTexture(sector_t::floor));
auto tex = TexMan.GetGameTexture(sector->GetTexture(sector_t::floor));
t_return.string = tex? tex->GetName() : "";
}
}
@ -1968,7 +1968,7 @@ void FParser::SF_CeilingTexture(void)
}
t_return.type = svt_string;
FTexture * tex = TexMan.GetTexture(sector->GetTexture(sector_t::ceiling));
auto tex = TexMan.GetGameTexture(sector->GetTexture(sector_t::ceiling));
t_return.string = tex? tex->GetName() : "";
}
}

View file

@ -291,7 +291,7 @@ void DDoor::DoorSound(bool raise, DSeqNode *curseq) const
if (line->backsector == NULL)
continue;
FTexture *tex = TexMan.GetTexture(line->sidedef[0]->GetTexture(side_t::top));
auto tex = TexMan.GetGameTexture(line->sidedef[0]->GetTexture(side_t::top));
texname = tex ? tex->GetName().GetChars() : NULL;
if (texname != NULL && texname[0] == 'D' && texname[1] == 'O' && texname[2] == 'R')
{
@ -716,7 +716,7 @@ void DAnimatedDoor::Construct(sector_t *sec, line_t *line, int speed, int delay,
picnum = tex1[side_t::top].texture;
FTexture *tex = TexMan.GetTexture(picnum);
auto tex = TexMan.GetGameTexture(picnum);
topdist = tex ? tex->GetDisplayHeight() : 64;
topdist = m_Sector->ceilingplane.fD() - topdist * m_Sector->ceilingplane.fC();

View file

@ -231,7 +231,7 @@ bool P_GetMidTexturePosition(const line_t *line, int sideno, double *ptextop, do
side_t *side = line->sidedef[sideno];
FTextureID texnum = side->GetTexture(side_t::mid);
if (!texnum.isValid()) return false;
FTexture * tex= TexMan.GetTexture(texnum, true);
FGameTexture * tex= TexMan.GetGameTexture(texnum, true);
if (!tex) return false;
FTexCoordInfo tci;

View file

@ -6597,7 +6597,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
auto a = Level->SingleActorFromTID(args[0], activator);
if (a != nullptr)
{
return GlobalACSStrings.AddString(TexMan.GetTexture(a->floorpic)->GetName());
return GlobalACSStrings.AddString(TexMan.GetGameTexture(a->floorpic)->GetName());
}
else
{

View file

@ -489,7 +489,7 @@ static inline void CheckShortestTex (FLevelLocals *Level, FTextureID texnum, dou
{
if (texnum.isValid() || (texnum.isNull() && (Level->i_compatflags & COMPATF_SHORTTEX)))
{
FTexture *tex = TexMan.GetTexture(texnum);
auto tex = TexMan.GetGameTexture(texnum);
if (tex != NULL)
{
double h = tex->GetDisplayHeight();
@ -1156,10 +1156,10 @@ double GetFriction(const sector_t *self, int plane, double *pMoveFac)
auto c = planes[sector_t::floor].GlowColor;
if (c == 0)
{
FTexture *tex = TexMan.GetTexture(GetTexture(sector_t::floor));
auto tex = TexMan.GetGameTexture(GetTexture(sector_t::floor));
if (tex != NULL && tex->isGlowing())
{
if (!tex->isAutoGlowing()) tex = TexMan.GetTexture(GetTexture(sector_t::floor), true);
if (!tex->isAutoGlowing()) tex = TexMan.GetGameTexture(GetTexture(sector_t::floor), true);
if (tex->isGlowing()) // recheck the current animation frame.
{
tex->GetGlowColor(bottomglowcolor);
@ -1201,10 +1201,10 @@ double GetFriction(const sector_t *self, int plane, double *pMoveFac)
auto c = planes[sector_t::ceiling].GlowColor;
if (c == 0)
{
FTexture *tex = TexMan.GetTexture(GetTexture(sector_t::ceiling));
auto tex = TexMan.GetGameTexture(GetTexture(sector_t::ceiling));
if (tex != NULL && tex->isGlowing())
{
if (!tex->isAutoGlowing()) tex = TexMan.GetTexture(GetTexture(sector_t::ceiling), true);
if (!tex->isAutoGlowing()) tex = TexMan.GetGameTexture(GetTexture(sector_t::ceiling), true);
if (tex->isGlowing()) // recheck the current animation frame.
{
ret = true;
@ -1225,10 +1225,10 @@ double GetFriction(const sector_t *self, int plane, double *pMoveFac)
c = planes[sector_t::floor].GlowColor;
if (c == 0)
{
FTexture *tex = TexMan.GetTexture(GetTexture(sector_t::floor));
auto tex = TexMan.GetGameTexture(GetTexture(sector_t::floor));
if (tex != NULL && tex->isGlowing())
{
if (!tex->isAutoGlowing()) tex = TexMan.GetTexture(GetTexture(sector_t::floor), true);
if (!tex->isAutoGlowing()) tex = TexMan.GetGameTexture(GetTexture(sector_t::floor), true);
if (tex->isGlowing()) // recheck the current animation frame.
{
ret = true;

View file

@ -333,7 +333,7 @@ void R_InitSpriteDefs ()
memset(hashes.Data(), -1, sizeof(Hasher)*smax);
for (i = 0; i < smax; ++i)
{
FTexture *tex = TexMan.ByIndex(i);
auto tex = TexMan.GameByIndex(i);
if (tex->GetUseType() == ETextureType::Sprite && strlen(tex->GetName()) >= 6)
{
size_t bucket = TEX_DWNAME(tex) % smax;
@ -415,7 +415,7 @@ void R_InitSpriteDefs ()
int hash = hashes[intname % smax].Head;
while (hash != -1)
{
FTexture *tex = TexMan.GetTexture(hash);
auto tex = TexMan.GetGameTexture(hash);
if (TEX_DWNAME(tex) == intname)
{
bool res = R_InstallSpriteLump (FTextureID(hash), tex->GetName()[4] - 'A', tex->GetName()[5], false, sprtemp, maxframe);

View file

@ -74,7 +74,9 @@ void HWSkyInfo::init(HWDrawInfo *di, int sky1, PalEntry FadeColor)
normalsky:
if (di->Level->flags&LEVEL_DOUBLESKY)
{
texture[1] = FMaterial::ValidateTexture(di->Level->skytexture1, false, true);
auto tex1 = TexMan.GetTexture(di->Level->skytexture1, true);
if (tex1) tex1 = tex1->GetFrontSkyLayer();
texture[1] = FMaterial::ValidateTexture(tex1, false);
x_offset[1] = di->Level->hw_sky1pos;
doublesky = true;
}

View file

@ -64,8 +64,7 @@ CVAR(Float, skyoffset, 0, 0) // for testing
void InitSkyMap(FLevelLocals *Level)
{
int skyheight;
FTexture *skytex1, *skytex2;
FGameTexture *skytex1, *skytex2;
// Do not allow the null texture which has no bitmap and will crash.
if (Level->skytexture1.isNull())
@ -77,12 +76,17 @@ void InitSkyMap(FLevelLocals *Level)
Level->skytexture2 = TexMan.CheckForTexture("-noflat-", ETextureType::Any);
}
skytex1 = TexMan.GetTexture(Level->skytexture1, false);
skytex2 = TexMan.GetTexture(Level->skytexture2, false);
skytex1 = TexMan.GetGameTexture(Level->skytexture1, false);
skytex2 = TexMan.GetGameTexture(Level->skytexture2, false);
if (skytex1 == nullptr)
return;
if (Level->flags & LEVEL_DOUBLESKY)
{
skytex1 = skytex1->GetFrontSkyLayer();
}
if ((Level->flags & LEVEL_DOUBLESKY) && skytex1->GetDisplayHeight() != skytex2->GetDisplayHeight())
{
Printf(TEXTCOLOR_BOLD "Both sky textures must be the same height." TEXTCOLOR_NORMAL "\n");
@ -103,7 +107,7 @@ void InitSkyMap(FLevelLocals *Level)
// the screen when looking fully up.
// h > 200: Unstretched, but the baseline is shifted down so that the top
// of the texture is at the top of the screen when looking fully up.
skyheight = skytex1->GetDisplayHeight();
auto skyheight = skytex1->GetDisplayHeight();
Level->skystretch = (r_skymode == 1
&& skyheight >= 128 && skyheight <= 256

View file

@ -71,7 +71,7 @@ namespace swrenderer
Thread = thread;
auto Level = Thread->Viewport->Level();
auto sskytex1 = GetPalettedSWTexture(Level->skytexture1, true, nullptr, true);
auto sskytex1 = GetPalettedSWTexture(Level->skytexture1, true, nullptr, true, !!(Level->flags & LEVEL_DOUBLESKY));
auto sskytex2 = GetPalettedSWTexture(Level->skytexture2, true, nullptr, true);
if (sskytex1 == nullptr)

View file

@ -621,14 +621,18 @@ static FGameTexture* PalCheck(FGameTexture* tex)
return tex;
}
FSoftwareTexture* GetPalettedSWTexture(FTextureID texid, bool animate, FLevelLocals *checkcompat, bool allownull)
FSoftwareTexture* GetPalettedSWTexture(FTextureID texid, bool animate, FLevelLocals *checkcompat, bool allownull, bool frontsky)
{
auto tex = PalCheck(TexMan.GetGameTexture(texid, true));
if (checkcompat && tex && tex->isValid() && checkcompat->i_compatflags & COMPATF_MASKEDMIDTEX)
if (tex == nullptr || (!allownull && !tex->isValid())) return nullptr;
if (frontsky)
{
tex = tex->GetFrontSkyLayer();
}
else if (checkcompat && checkcompat->i_compatflags & COMPATF_MASKEDMIDTEX)
{
tex = tex->GetRawTexture();
}
FSoftwareTexture* pic = tex && (allownull || tex->isValid()) ? GetSoftwareTexture(tex) : nullptr;
return pic;
return GetSoftwareTexture(tex);
}

View file

@ -193,4 +193,4 @@ public:
};
FSoftwareTexture* GetSoftwareTexture(FGameTexture* tex);
FSoftwareTexture* GetPalettedSWTexture(FTextureID texid, bool animate, FLevelLocals *checkcompat = nullptr, bool allownull = false);
FSoftwareTexture* GetPalettedSWTexture(FTextureID texid, bool animate, FLevelLocals *checkcompat = nullptr, bool allownull = false, bool frontsky = false);

View file

@ -56,7 +56,6 @@ static const int VID_MIN_UI_HEIGHT = 400;
class player_t;
struct sector_t;
class FTexture;
struct FPortalSceneState;
class FSkyVertexBuffer;
class IIndexBuffer;
@ -148,7 +147,6 @@ inline bool V_IsTrueColor()
}
class FTexture;
struct FColormap;
class FileWriter;
enum FTextureFormat : uint32_t;

View file

@ -29,7 +29,6 @@
#include "doomdef.h"
class FTexture;
struct FLevelLocals;
//