- made SPROFS a more usable feature.

This was originally invented to fix the sprite offsets for the hardware renderer.
Changed it so that it doesn't override the original offsets but acts as a second set.
A new CVAR has been added to allow controlling the behavior per renderer.
This commit is contained in:
Christoph Oelckers 2018-03-31 10:37:46 +02:00
parent 5bdea6278c
commit 6d6196388e
35 changed files with 322 additions and 274 deletions

View File

@ -889,7 +889,7 @@ void D_Display ()
tex = TexMan(gameinfo.PauseSign);
x = (SCREENWIDTH - tex->GetScaledWidth() * CleanXfac)/2 +
tex->GetScaledLeftOffset() * CleanXfac;
tex->GetScaledLeftOffset(0) * CleanXfac;
screen->DrawTexture (tex, x, 4, DTA_CleanNoMove, true, TAG_DONE);
if (paused && multiplayer)
{

View File

@ -504,7 +504,7 @@ void DBaseDecal::Spread (const FDecalTemplate *tpl, side_t *wall, double x, doub
int dwidth = tex->GetWidth ();
DecalWidth = dwidth * ScaleX;
DecalLeft = tex->LeftOffset * ScaleX;
DecalLeft = tex->GetLeftOffset(0) * ScaleX;
DecalRight = DecalWidth - DecalLeft;
SpreadSource = this;
SpreadTemplate = tpl;

View File

@ -178,8 +178,8 @@ static void DrawHudText(FFont *font, int color, char * text, int x, int y, doubl
FTexture *texc = font->GetChar(text[i], &width);
if (texc != NULL)
{
double offset = texc->GetScaledTopOffsetDouble()
- tex_zero->GetScaledTopOffsetDouble()
double offset = texc->GetScaledTopOffsetDouble(0)
- tex_zero->GetScaledTopOffsetDouble(0)
+ tex_zero->GetScaledHeightDouble();
screen->DrawChar(font, color, x, y, text[i],

View File

@ -1199,12 +1199,12 @@ public:
if((offsetflags & SBarInfoCommand::CENTER) == SBarInfoCommand::CENTER)
{
if (forceWidth < 0) dx -= (texture->GetScaledWidthDouble()/2.0)-texture->GetScaledLeftOffsetDouble();
else dx -= forceWidth*(0.5-(texture->GetScaledLeftOffsetDouble()/texture->GetScaledWidthDouble()));
if (forceWidth < 0) dx -= (texture->GetScaledWidthDouble()/2.0)-texture->GetScaledLeftOffsetDouble(0);
else dx -= forceWidth*(0.5-(texture->GetScaledLeftOffsetDouble(0)/texture->GetScaledWidthDouble()));
//Unoptimalized ^^formula is dx -= forceWidth/2.0-(texture->GetScaledLeftOffsetDouble()*forceWidth/texture->GetScaledWidthDouble());
if (forceHeight < 0) dy -= (texture->GetScaledHeightDouble()/2.0)-texture->GetScaledTopOffsetDouble();
else dy -= forceHeight*(0.5-(texture->GetScaledTopOffsetDouble()/texture->GetScaledHeightDouble()));
if (forceHeight < 0) dy -= (texture->GetScaledHeightDouble()/2.0)-texture->GetScaledTopOffsetDouble(0);
else dy -= forceHeight*(0.5-(texture->GetScaledTopOffsetDouble(0)/texture->GetScaledHeightDouble()));
}
dx += xOffset;
@ -1215,10 +1215,10 @@ public:
double tmp = 0;
w = forceWidth < 0 ? texture->GetScaledWidthDouble() : forceWidth;
h = forceHeight < 0 ? texture->GetScaledHeightDouble() : forceHeight;
double dcx = clip[0] == 0 ? 0 : dx + clip[0] - texture->GetScaledLeftOffsetDouble();
double dcy = clip[1] == 0 ? 0 : dy + clip[1] - texture->GetScaledTopOffsetDouble();
double dcr = clip[2] == 0 ? INT_MAX : dx + w - clip[2] - texture->GetScaledLeftOffsetDouble();
double dcb = clip[3] == 0 ? INT_MAX : dy + h - clip[3] - texture->GetScaledTopOffsetDouble();
double dcx = clip[0] == 0 ? 0 : dx + clip[0] - texture->GetScaledLeftOffsetDouble(0);
double dcy = clip[1] == 0 ? 0 : dy + clip[1] - texture->GetScaledTopOffsetDouble(0);
double dcr = clip[2] == 0 ? INT_MAX : dx + w - clip[2] - texture->GetScaledLeftOffsetDouble(0);
double dcb = clip[3] == 0 ? INT_MAX : dy + h - clip[3] - texture->GetScaledTopOffsetDouble(0);
if(clip[0] != 0 || clip[1] != 0)
{
@ -1300,10 +1300,10 @@ public:
// Check for clipping
if(clip[0] != 0 || clip[1] != 0 || clip[2] != 0 || clip[3] != 0)
{
rcx = clip[0] == 0 ? 0 : rx+((clip[0] - texture->GetScaledLeftOffsetDouble())*Scale.X);
rcy = clip[1] == 0 ? 0 : ry+((clip[1] - texture->GetScaledTopOffsetDouble())*Scale.Y);
rcr = clip[2] == 0 ? INT_MAX : rx+w-((clip[2] + texture->GetScaledLeftOffsetDouble())*Scale.X);
rcb = clip[3] == 0 ? INT_MAX : ry+h-((clip[3] + texture->GetScaledTopOffsetDouble())*Scale.Y);
rcx = clip[0] == 0 ? 0 : rx+((clip[0] - texture->GetScaledLeftOffsetDouble(0))*Scale.X);
rcy = clip[1] == 0 ? 0 : ry+((clip[1] - texture->GetScaledTopOffsetDouble(0))*Scale.Y);
rcr = clip[2] == 0 ? INT_MAX : rx+w-((clip[2] + texture->GetScaledLeftOffsetDouble(0))*Scale.X);
rcb = clip[3] == 0 ? INT_MAX : ry+h-((clip[3] + texture->GetScaledTopOffsetDouble(0))*Scale.Y);
}
if(clearDontDraw)
@ -1399,8 +1399,8 @@ public:
}
int character = (unsigned char)*str;
if(script->spacingCharacter == '\0') //If we are monospaced lets use the offset
ax += (c->LeftOffset+1); //ignore x offsets since we adapt to character size
if (script->spacingCharacter == '\0') //If we are monospaced lets use the offset
ax += (c->GetLeftOffset(0) + 1); //ignore x offsets since we adapt to character size
double rx, ry, rw, rh;
rx = ax + xOffset;
@ -1463,8 +1463,8 @@ public:
DTA_DestHeightF, rh,
DTA_Alpha, Alpha,
TAG_DONE);
if(script->spacingCharacter == '\0')
ax += width + spacing - (c->LeftOffset+1);
if (script->spacingCharacter == '\0')
ax += width + spacing - (c->GetLeftOffset(0) + 1);
else //width gets changed at the call to GetChar()
ax += font->GetCharWidth((unsigned char) script->spacingCharacter) + spacing;
str++;

View File

@ -1578,14 +1578,14 @@ void DBaseStatusBar::DrawGraphic(FTextureID texture, double x, double y, int fla
{
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;
case DI_ITEM_HOFFSET: x -= tex->GetScaledLeftOffsetDouble(0) * boxwidth / texwidth; break;
}
switch (flags & DI_ITEM_VMASK)
{
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;
case DI_ITEM_VOFFSET: y -= tex->GetScaledTopOffsetDouble(0) * boxheight / texheight; break;
}
if (!fullscreenOffsets)
@ -1792,7 +1792,7 @@ void DBaseStatusBar::DrawString(FFont *font, const FString &cstring, double x, d
}
if (!monospaced) //If we are monospaced lets use the offset
x += (c->LeftOffset + 1); //ignore x offsets since we adapt to character size
x += (c->GetLeftOffset(0) + 1); //ignore x offsets since we adapt to character size
double rx, ry, rw, rh;
rx = x + drawOffset.X;
@ -1832,7 +1832,7 @@ void DBaseStatusBar::DrawString(FFont *font, const FString &cstring, double x, d
TAG_DONE);
if (!monospaced)
x += width + spacing - (c->LeftOffset + 1);
x += width + spacing - (c->GetLeftOffset(0) + 1);
else
x += spacing;
}

View File

@ -70,87 +70,6 @@ CUSTOM_CVAR(Bool, gl_notexturefill, false, 0)
void gl_CreateSections();
void AddAutoMaterials();
//-----------------------------------------------------------------------------
//
// Adjust sprite offsets for GL rendering (IWAD resources only)
//
//-----------------------------------------------------------------------------
void AdjustSpriteOffsets()
{
int lump, lastlump = 0;
int sprid;
TMap<int, bool> donotprocess;
int numtex = Wads.GetNumLumps();
for (int i = 0; i < numtex; i++)
{
if (Wads.GetLumpFile(i) > Wads.GetIwadNum()) break; // we are past the IWAD
if (Wads.GetLumpNamespace(i) == ns_sprites && Wads.GetLumpFile(i) == Wads.GetIwadNum())
{
char str[9];
Wads.GetLumpName(str, i);
str[8] = 0;
FTextureID texid = TexMan.CheckForTexture(str, ETextureType::Sprite, 0);
if (texid.isValid() && Wads.GetLumpFile(TexMan[texid]->SourceLump) > Wads.GetIwadNum())
{
// This texture has been replaced by some PWAD.
memcpy(&sprid, str, 4);
donotprocess[sprid] = true;
}
}
}
while ((lump = Wads.FindLump("SPROFS", &lastlump, false)) != -1)
{
FScanner sc;
sc.OpenLumpNum(lump);
sc.SetCMode(true);
GLRenderer->FlushTextures();
int ofslumpno = Wads.GetLumpFile(lump);
while (sc.GetString())
{
int x,y;
bool iwadonly = false;
bool forced = false;
FTextureID texno = TexMan.CheckForTexture(sc.String, ETextureType::Sprite);
sc.MustGetStringName(",");
sc.MustGetNumber();
x=sc.Number;
sc.MustGetStringName(",");
sc.MustGetNumber();
y=sc.Number;
if (sc.CheckString(","))
{
sc.MustGetString();
if (sc.Compare("iwad")) iwadonly = true;
if (sc.Compare("iwadforced")) forced = iwadonly = true;
}
if (texno.isValid())
{
FTexture * tex = TexMan[texno];
int lumpnum = tex->GetSourceLump();
// We only want to change texture offsets for sprites in the IWAD or the file this lump originated from.
if (lumpnum >= 0 && lumpnum < Wads.GetNumLumps())
{
int wadno = Wads.GetLumpFile(lumpnum);
if ((iwadonly && wadno==Wads.GetIwadNum()) || (!iwadonly && wadno == ofslumpno))
{
if (wadno == Wads.GetIwadNum() && !forced && iwadonly)
{
memcpy(&sprid, &tex->Name[0], 4);
if (donotprocess.CheckKey(sprid)) continue; // do not alter sprites that only get partially replaced.
}
tex->LeftOffset=x;
tex->TopOffset=y;
}
}
}
}
}
}
@ -362,7 +281,6 @@ void gl_RecalcVertexHeights(vertex_t * v)
void gl_InitData()
{
AdjustSpriteOffsets();
AddAutoMaterials();
}

View File

@ -520,8 +520,8 @@ FMaterial::FMaterial(FTexture * tx, bool expanded)
mWidth = tx->GetWidth();
mHeight = tx->GetHeight();
mLeftOffset = tx->LeftOffset;
mTopOffset = tx->TopOffset;
mLeftOffset = tx->GetLeftOffset(0); // These only get used by decals and decals should not use renderer-specific offsets.
mTopOffset = tx->GetTopOffset(0);
mRenderWidth = tx->GetScaledWidth();
mRenderHeight = tx->GetScaledHeight();
mSpriteU[0] = mSpriteV[0] = 0.f;
@ -534,59 +534,26 @@ FMaterial::FMaterial(FTexture * tx, bool expanded)
mBaseLayer = ValidateSysTexture(basetex, expanded);
}
float fxScale = tx->Scale.X;
float fyScale = tx->Scale.Y;
// mSpriteRect is for positioning the sprite in the scene.
mSpriteRect.left = -mLeftOffset / fxScale;
mSpriteRect.top = -mTopOffset / fyScale;
mSpriteRect.width = mWidth / fxScale;
mSpriteRect.height = mHeight / fyScale;
mExpanded = expanded;
if (expanded)
{
// a little adjustment to make sprites look better with texture filtering:
// create a 1 pixel wide empty frame around them.
int trim[4];
bool trimmed = TrimBorders(trim); // get the trim size before adding the empty frame
int oldwidth = mWidth;
int oldheight = mHeight;
mWidth+=2;
mHeight+=2;
mLeftOffset+=1;
mTopOffset+=1;
mTrimResult = TrimBorders(trim); // get the trim size before adding the empty frame
mWidth += 2;
mHeight += 2;
mRenderWidth = mRenderWidth * mWidth / oldwidth;
mRenderHeight = mRenderHeight * mHeight / oldheight;
// Reposition the sprite with the frame considered
mSpriteRect.left = -mLeftOffset / fxScale;
mSpriteRect.top = -mTopOffset / fyScale;
mSpriteRect.width = mWidth / fxScale;
mSpriteRect.height = mHeight / fyScale;
if (trimmed)
{
mSpriteRect.left += trim[0] / fxScale;
mSpriteRect.top += trim[1] / fyScale;
mSpriteRect.width -= (oldwidth - trim[2]) / fxScale;
mSpriteRect.height -= (oldheight - trim[3]) / fyScale;
mSpriteU[0] = trim[0] / (float)mWidth;
mSpriteV[0] = trim[1] / (float)mHeight;
mSpriteU[1] -= (oldwidth - trim[0] - trim[2]) / (float)mWidth;
mSpriteV[1] -= (oldheight - trim[1] - trim[3]) / (float)mHeight;
}
}
SetSpriteRect();
mTextureLayers.ShrinkToFit();
mMaxBound = -1;
mMaterials.Push(this);
tx->gl_info.Material[expanded] = this;
if (tx->bHasCanvas) tx->gl_info.mIsTransparent = 0;
mExpanded = expanded;
}
//===========================================================================
@ -608,6 +575,59 @@ FMaterial::~FMaterial()
}
//===========================================================================
//
// Set the sprite rectangle
//
//===========================================================================
void FMaterial::SetSpriteRect()
{
auto leftOffset = tex->GetLeftOffsetHW();
auto topOffset = tex->GetTopOffsetHW();
float fxScale = tex->Scale.X;
float fyScale = tex->Scale.Y;
// mSpriteRect is for positioning the sprite in the scene.
mSpriteRect.left = -leftOffset / fxScale;
mSpriteRect.top = -topOffset / fyScale;
mSpriteRect.width = mWidth / fxScale;
mSpriteRect.height = mHeight / fyScale;
if (mExpanded)
{
// a little adjustment to make sprites look better with texture filtering:
// create a 1 pixel wide empty frame around them.
int oldwidth = mWidth - 2;
int oldheight = mHeight - 2;
leftOffset += 1;
topOffset += 1;
// Reposition the sprite with the frame considered
mSpriteRect.left = -leftOffset / fxScale;
mSpriteRect.top = -topOffset / fyScale;
mSpriteRect.width = mWidth / fxScale;
mSpriteRect.height = mHeight / fyScale;
if (mTrimResult)
{
mSpriteRect.left += trim[0] / fxScale;
mSpriteRect.top += trim[1] / fyScale;
mSpriteRect.width -= (oldwidth - trim[2]) / fxScale;
mSpriteRect.height -= (oldheight - trim[3]) / fyScale;
mSpriteU[0] = trim[0] / (float)mWidth;
mSpriteV[0] = trim[1] / (float)mHeight;
mSpriteU[1] -= (oldwidth - trim[0] - trim[2]) / (float)mWidth;
mSpriteV[1] -= (oldheight - trim[1] - trim[3]) / (float)mHeight;
}
}
}
//===========================================================================
//
@ -616,7 +636,7 @@ FMaterial::~FMaterial()
//
//===========================================================================
bool FMaterial::TrimBorders(int *rect)
bool FMaterial::TrimBorders(uint16_t *rect)
{
PalEntry col;
int w;

View File

@ -122,18 +122,21 @@ class FMaterial
short mRenderWidth;
short mRenderHeight;
bool mExpanded;
bool mTrimResult;
uint16_t trim[4];
float mSpriteU[2], mSpriteV[2];
FloatRect mSpriteRect;
FGLTexture * ValidateSysTexture(FTexture * tex, bool expand);
bool TrimBorders(int *rect);
bool TrimBorders(uint16_t *rect);
public:
FTexture *tex;
FMaterial(FTexture *tex, bool forceexpand);
~FMaterial();
void SetSpriteRect();
void Precache();
void PrecacheList(SpriteHits &translations);
bool isMasked() const
@ -199,37 +202,6 @@ public:
return mTopOffset;
}
int GetScaledLeftOffset() const
{
return int(mLeftOffset / tex->Scale.X);
}
int GetScaledTopOffset() const
{
return int(mTopOffset / tex->Scale.Y);
}
float GetScaledLeftOffsetFloat() const
{
return float(mLeftOffset / tex->Scale.X);
}
float GetScaledTopOffsetFloat() const
{
return float(mTopOffset/ tex->Scale.Y);
}
// This is scaled size in floating point as needed by sprites
float GetScaledWidthFloat() const
{
return float(mWidth / tex->Scale.X);
}
float GetScaledHeightFloat() const
{
return float(mHeight / tex->Scale.Y);
}
// Get right/bottom UV coordinates for patch drawing
float GetUL() const { return 0; }
float GetVT() const { return 0; }

View File

@ -500,6 +500,21 @@ bool FTexture::ProcessData(unsigned char * buffer, int w, int h, bool ispatch)
return true;
}
//===========================================================================
//
// Sprite adjust has changed.
// This needs to alter the material's sprite rect.
//
//===========================================================================
void FTexture::SetSpriteAdjust()
{
for(auto mat : gl_info.Material)
{
if (mat != nullptr) mat->SetSpriteRect();
}
}
//===========================================================================
//
// fake brightness maps

View File

@ -213,14 +213,14 @@ void HU_GetPlayerWidths(int &maxnamewidth, int &maxscorewidth, int &maxiconheigh
if (players[i].mo->ScoreIcon.isValid())
{
FTexture *pic = TexMan[players[i].mo->ScoreIcon];
width = pic->GetScaledWidth() - pic->GetScaledLeftOffset() + 2;
width = pic->GetScaledWidth() - pic->GetScaledLeftOffset(0) + 2;
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->GetScaledHeight() - pic->GetScaledTopOffset();
int height = pic->GetScaledHeight() - pic->GetScaledTopOffset(0);
if (height > maxiconheight)
{
maxiconheight = height;

View File

@ -58,8 +58,9 @@ void RenderPolyDecal::Render(PolyRenderThread *thread, const TriMatrix &worldToC
// Calculate unclipped position and UV coordinates
double edge_left = tex->LeftOffset * decal->ScaleX;
double edge_right = (tex->GetWidth() - tex->LeftOffset) * decal->ScaleX;
// decals should not use renderer specific offsets.
double edge_left = tex->GetLeftOffset(0) * decal->ScaleX;
double edge_right = (tex->GetWidth() - tex->GetLeftOffset(0)) * decal->ScaleX;
DVector2 angvec = (line->v2->fPos() - line->v1->fPos()).Unit();
DVector2 normal = { angvec.Y, -angvec.X };

View File

@ -261,7 +261,7 @@ void RenderPolyPlayerSprites::RenderSprite(PolyRenderThread *thread, DPSprite *p
double pspriteyscale = pspritexscale * yaspectMul;
double pspritexiscale = 1 / pspritexscale;
int tleft = tex->GetScaledLeftOffset();
int tleft = tex->GetScaledLeftOffsetPo();
int twidth = tex->GetScaledWidth();
// calculate edges of the shape
@ -286,7 +286,7 @@ void RenderPolyPlayerSprites::RenderSprite(PolyRenderThread *thread, DPSprite *p
vis.renderflags = owner->renderflags;
vis.texturemid = (BASEYCENTER - sy) * tex->Scale.Y + tex->TopOffset;
vis.texturemid = (BASEYCENTER - sy) * tex->Scale.Y + tex->GetTopOffsetPo();
auto screencanvas = screen->GetCanvas();

View File

@ -63,9 +63,9 @@ bool RenderPolySprite::GetLine(AActor *thing, DVector2 &left, DVector2 &right)
double offsetX;
if (flipTextureX)
offsetX = (tex->GetWidth() - tex->LeftOffset) * thingxscalemul;
offsetX = (tex->GetWidth() - tex->GetLeftOffsetPo()) * thingxscalemul;
else
offsetX = tex->LeftOffset * thingxscalemul;
offsetX = tex->GetLeftOffsetPo() * thingxscalemul;
left = DVector2(pos.X - viewpoint.Sin * offsetX, pos.Y + viewpoint.Cos * offsetX);
right = DVector2(left.X + viewpoint.Sin * spriteWidth, left.Y - viewpoint.Cos * spriteWidth);
@ -110,7 +110,7 @@ void RenderPolySprite::Render(PolyRenderThread *thread, const TriMatrix &worldTo
double thingyscalemul = thing->Scale.Y / tex->Scale.Y;
double spriteHeight = thingyscalemul * tex->GetHeight();
posZ -= (tex->GetHeight() - tex->TopOffset) * thingyscalemul;
posZ -= (tex->GetHeight() - tex->GetTopOffsetPo()) * thingyscalemul;
posZ = PerformSpriteClipAdjustment(thing, thingpos, spriteHeight, posZ);
//double depth = 1.0;

View File

@ -56,7 +56,7 @@ void RenderPolyWallSprite::Render(PolyRenderThread *thread, const TriMatrix &wor
// Determine left and right edges of sprite. The sprite's angle is its normal,
// so the edges are 90 degrees each side of it.
double x2 = tex->GetScaledWidth() * spriteScale.X;
double x1 = tex->GetScaledLeftOffset() * spriteScale.X;
double x1 = tex->GetScaledLeftOffsetPo() * spriteScale.X;
DVector2 left, right;
left.X = pos.X - x1 * angcos;
left.Y = pos.Y - x1 * angsin;

View File

@ -755,23 +755,10 @@ void SDLGLFB::InitializeState()
{
}
#if 0
bool SDLGLFB::CanUpdate()
{
if (m_Lock != 1)
{
if (m_Lock > 0)
{
UpdatePending = true;
--m_Lock;
}
return false;
}
return true;
}
#endif
void SDLGLFB::SwapBuffers()
{

View File

@ -374,21 +374,10 @@ void SDLGLFB::InitializeState()
{
}
#if 0
bool SDLGLFB::CanUpdate ()
{
if (m_Lock != 1)
{
if (m_Lock > 0)
{
UpdatePending = true;
--m_Lock;
}
return false;
}
return true;
}
#endif
void SDLGLFB::SetGammaTable(uint16_t *tbl)
{

View File

@ -142,7 +142,7 @@ namespace swrenderer
// pretty much the same as what R_AddLine() does.
double edge_right = WallSpriteTile->GetWidth();
double edge_left = WallSpriteTile->LeftOffset;
double edge_left = WallSpriteTile->GetLeftOffset(0); // decals should not use renderer-specific offsets.
edge_right = (edge_right - edge_left) * decal->ScaleX;
edge_left *= decal->ScaleX;
@ -233,7 +233,7 @@ namespace swrenderer
}
yscale = decal->ScaleY;
texturemid = WallSpriteTile->TopOffset + (zpos - thread->Viewport->viewpoint.Pos.Z) / yscale;
texturemid = WallSpriteTile->GetTopOffset(0) + (zpos - thread->Viewport->viewpoint.Pos.Z) / yscale;
// Clip sprite to drawseg
x1 = MAX<int>(clipper->x1, x1);

View File

@ -264,7 +264,7 @@ namespace swrenderer
double pspriteyscale = pspritexscale * viewport->BaseYaspectMul * ((double)SCREENHEIGHT / SCREENWIDTH) * r_viewwindow.WidescreenRatio;
double pspritexiscale = 1 / pspritexscale;
int tleft = tex->GetScaledLeftOffset();
int tleft = tex->GetScaledLeftOffset(0);
int twidth = tex->GetScaledWidth();
// calculate edges of the shape
@ -287,7 +287,7 @@ namespace swrenderer
vis.renderflags = owner->renderflags;
vis.texturemid = (BASEYCENTER - sy) * tex->Scale.Y + tex->TopOffset;
vis.texturemid = (BASEYCENTER - sy) * tex->Scale.Y + tex->GetTopOffset(0);
auto screencanvas = screen->GetCanvas();
if (Thread->Viewport->viewpoint.camera->player && (viewport->RenderTarget != screencanvas ||

View File

@ -101,7 +101,7 @@ namespace swrenderer
}
// [RH] Added scaling
int scaled_to = tex->GetScaledTopOffset();
int scaled_to = tex->GetScaledTopOffsetSW();
int scaled_bo = scaled_to - tex->GetScaledHeight();
double gzt = pos.Z + spriteScale.Y * scaled_to;
double gzb = pos.Z + spriteScale.Y * scaled_bo;
@ -153,7 +153,7 @@ namespace swrenderer
// calculate edges of the shape
const double thingxscalemul = spriteScale.X / tex->Scale.X;
tx -= ((renderflags & RF_XFLIP) ? (tex->GetWidth() - tex->LeftOffset - 1) : tex->LeftOffset) * thingxscalemul;
tx -= ((renderflags & RF_XFLIP) ? (tex->GetWidth() - tex->GetLeftOffsetSW() - 1) : tex->GetLeftOffsetSW()) * thingxscalemul;
double dtx1 = tx * xscale;
int x1 = viewport->viewwindow.centerx + xs_RoundToInt(dtx1);
@ -181,7 +181,7 @@ namespace swrenderer
vis->yscale = float(viewport->InvZtoScale * yscale / tz);
vis->idepth = float(1 / tz);
vis->floorclip = thing->Floorclip / yscale;
vis->texturemid = tex->TopOffset - (viewport->viewpoint.Pos.Z - pos.Z + thing->Floorclip) / yscale;
vis->texturemid = tex->GetTopOffsetSW() - (viewport->viewpoint.Pos.Z - pos.Z + thing->Floorclip) / yscale;
vis->x1 = x1 < renderportal->WindowLeft ? renderportal->WindowLeft : x1;
vis->x2 = x2 > renderportal->WindowRight ? renderportal->WindowRight : x2;
//vis->Angle = thing->Angles.Yaw;

View File

@ -84,7 +84,7 @@ namespace swrenderer
// Determine left and right edges of sprite. The sprite's angle is its normal,
// so the edges are 90 degrees each side of it.
x2 = pic->GetScaledWidth();
x1 = pic->GetScaledLeftOffset();
x1 = pic->GetScaledLeftOffsetSW();
x1 *= scale.X;
x2 *= scale.X;
@ -107,7 +107,7 @@ namespace swrenderer
// but right now, I just want to get them drawing.
tz = (pos.X - thread->Viewport->viewpoint.Pos.X) * thread->Viewport->viewpoint.TanCos + (pos.Y - thread->Viewport->viewpoint.Pos.Y) * thread->Viewport->viewpoint.TanSin;
int scaled_to = pic->GetScaledTopOffset();
int scaled_to = pic->GetScaledTopOffsetSW();
int scaled_bo = scaled_to - pic->GetScaledHeight();
gzt = pos.Z + scale.Y * scaled_to;
gzb = pos.Z + scale.Y * scaled_bo;

View File

@ -81,8 +81,8 @@ FBuildTexture::FBuildTexture(const FString &pathprefix, int tilenum, const uint8
PixelsAreStatic = 3;
Width = width;
Height = height;
LeftOffset = left;
TopOffset = top;
_LeftOffset[1] = _LeftOffset[0] = left;
_TopOffset[1] = _TopOffset[0] = top;
CalcBitSize ();
Name.Format("%sBTIL%04d", pathprefix.GetChars(), tilenum);
UseType = ETextureType::Override;

View File

@ -44,7 +44,6 @@ FCanvasTexture::FCanvasTexture (const char *name, int width, int height)
Name = name;
Width = width;
Height = height;
LeftOffset = TopOffset = 0;
CalcBitSize ();
bMasked = false;

View File

@ -290,8 +290,6 @@ FDDSTexture::FDDSTexture (FileReader &lump, int lumpnum, void *vsurfdesc)
DDSURFACEDESC2 *surf = (DDSURFACEDESC2 *)vsurfdesc;
UseType = ETextureType::MiscPatch;
LeftOffset = 0;
TopOffset = 0;
bMasked = false;
Width = uint16_t(surf->Width);

View File

@ -113,8 +113,8 @@ FIMGZTexture::FIMGZTexture (int lumpnum, uint16_t w, uint16_t h, int16_t l, int1
Wads.GetLumpName (Name, lumpnum);
Width = w;
Height = h;
LeftOffset = l;
TopOffset = t;
_LeftOffset[1] = _LeftOffset[0] = l;
_TopOffset[1] = _TopOffset[0] = t;
isalpha = _isalpha;
CalcBitSize ();
}
@ -131,14 +131,6 @@ uint8_t *FIMGZTexture::MakeTexture (FRenderStyle style)
const ImageHeader *imgz = (const ImageHeader *)lump.GetMem();
const uint8_t *data = (const uint8_t *)&imgz[1];
if (Width != 0xFFFF)
{
Width = LittleShort(imgz->Width);
Height = LittleShort(imgz->Height);
LeftOffset = LittleShort(imgz->LeftOffset);
TopOffset = LittleShort(imgz->TopOffset);
}
uint8_t *dest_p;
int dest_adv = Height;
int dest_rew = Width * Height - 1;

View File

@ -250,8 +250,6 @@ FJPEGTexture::FJPEGTexture (int lumpnum, int width, int height)
: FWorldTexture(NULL, lumpnum)
{
UseType = ETextureType::MiscPatch;
LeftOffset = 0;
TopOffset = 0;
bMasked = false;
Width = width;

View File

@ -1100,6 +1100,7 @@ FMultiPatchTexture::FMultiPatchTexture (FScanner &sc, ETextureType usetype)
Height = sc.Number;
UseType = usetype;
bool offset2set = false;
if (sc.CheckString("{"))
{
while (!sc.CheckString("}"))
@ -1183,10 +1184,24 @@ FMultiPatchTexture::FMultiPatchTexture (FScanner &sc, ETextureType usetype)
else if (sc.Compare("Offset"))
{
sc.MustGetNumber();
LeftOffset = sc.Number;
_LeftOffset[0] = sc.Number;
sc.MustGetStringName(",");
sc.MustGetNumber();
TopOffset = sc.Number;
_TopOffset[0] = sc.Number;
if (!offset2set)
{
_LeftOffset[1] = _LeftOffset[0];
_TopOffset[1] = _TopOffset[0];
}
}
else if (sc.Compare("Offset2"))
{
sc.MustGetNumber();
_LeftOffset[1] = sc.Number;
sc.MustGetStringName(",");
sc.MustGetNumber();
_TopOffset[1] = sc.Number;
offset2set = true;
}
else
{
@ -1264,8 +1279,8 @@ void FMultiPatchTexture::ResolvePatches()
Parts[i].Texture->bKeepAround = true;
if (Inits[i].UseOffsets)
{
Parts[i].OriginX -= Parts[i].Texture->LeftOffset;
Parts[i].OriginY -= Parts[i].Texture->TopOffset;
Parts[i].OriginX -= Parts[i].Texture->GetLeftOffset(0);
Parts[i].OriginY -= Parts[i].Texture->GetTopOffset(0);
}
}
}

View File

@ -159,8 +159,8 @@ FPatchTexture::FPatchTexture (int lumpnum, patch_t * header, bool isalphatex)
isalpha = isalphatex;
Width = header->width;
Height = header->height;
LeftOffset = header->leftoffset;
TopOffset = header->topoffset;
_LeftOffset[1] = _LeftOffset[0] = header->leftoffset;
_TopOffset[1] = _TopOffset[0] = header->topoffset;
DetectBadPatches();
CalcBitSize ();
}
@ -310,8 +310,8 @@ void FPatchTexture::DetectBadPatches ()
return; // More than one post in a column!
}
}
LeftOffset = 0;
TopOffset = 0;
_LeftOffset[1] = _LeftOffset[0] = 0;
_TopOffset[1] = _TopOffset[0] = 0;
badflag = true;
bMasked = false; // Hacked textures don't have transparent parts.
}

View File

@ -207,8 +207,6 @@ FPNGTexture::FPNGTexture (FileReader &lump, int lumpnum, const FString &filename
int i;
UseType = ETextureType::MiscPatch;
LeftOffset = 0;
TopOffset = 0;
bMasked = false;
Width = width;
@ -251,8 +249,8 @@ FPNGTexture::FPNGTexture (FileReader &lump, int lumpnum, const FString &filename
Printf ("Y-Offset for PNG texture %s is bad: %d (0x%08x)\n", Wads.GetLumpFullName (lumpnum), ihoty, ihoty);
ihoty = 0;
}
LeftOffset = ihotx;
TopOffset = ihoty;
_LeftOffset[1] = _LeftOffset[0] = ihotx;
_TopOffset[1] = _TopOffset[0] = ihoty;
}
break;

View File

@ -47,6 +47,15 @@
#include "textures/textures.h"
#include "v_palette.h"
// Make sprite offset adjustment user-configurable per renderer.
int r_spriteadjustSW, r_spriteadjustHW;
CUSTOM_CVAR(Int, r_spriteadjust, 2, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
{
r_spriteadjustHW = !!(self & 2);
r_spriteadjustSW = !!(self & 1);
TexMan.SpriteAdjustChanged();
}
typedef FTexture * (*CreateFunc)(FileReader & file, int lumpnum);
struct TexCreateInfo
@ -146,12 +155,13 @@ FTexture * FTexture::CreateTexture (const char *name, int lumpnum, ETextureType
FTexture::FTexture (const char *name, int lumpnum)
: LeftOffset(0), TopOffset(0),
:
WidthBits(0), HeightBits(0), Scale(1,1), SourceLump(lumpnum),
UseType(ETextureType::Any), bNoDecals(false), bNoRemap0(false), bWorldPanning(false),
bMasked(true), bAlphaTexture(false), bHasCanvas(false), bWarped(0), bComplex(false), bMultiPatch(false), bKeepAround(false),
Rotations(0xFFFF), SkyOffset(0), Width(0), Height(0), WidthMask(0)
{
_LeftOffset[0] = _LeftOffset[1] = _TopOffset[0] = _TopOffset[1] = 0;
id.SetInvalid();
if (name != NULL)
{

View File

@ -581,8 +581,10 @@ void FTextureManager::AddHiresTextures (int wadnum)
// Replace the entire texture and adjust the scaling and offset factors.
newtex->bWorldPanning = true;
newtex->SetScaledSize(oldtex->GetScaledWidth(), oldtex->GetScaledHeight());
newtex->LeftOffset = int(oldtex->GetScaledLeftOffset() * newtex->Scale.X);
newtex->TopOffset = int(oldtex->GetScaledTopOffset() * newtex->Scale.Y);
newtex->_LeftOffset[0] = int(oldtex->GetScaledLeftOffset(0) * newtex->Scale.X);
newtex->_LeftOffset[1] = int(oldtex->GetScaledLeftOffset(1) * newtex->Scale.X);
newtex->_TopOffset[0] = int(oldtex->GetScaledTopOffset(0) * newtex->Scale.Y);
newtex->_TopOffset[1] = int(oldtex->GetScaledTopOffset(1) * newtex->Scale.Y);
ReplaceTexture(tlist[i], newtex, true);
}
}
@ -671,8 +673,10 @@ void FTextureManager::LoadTextureDefs(int wadnum, const char *lumpname)
// Replace the entire texture and adjust the scaling and offset factors.
newtex->bWorldPanning = true;
newtex->SetScaledSize(oldtex->GetScaledWidth(), oldtex->GetScaledHeight());
newtex->LeftOffset = int(oldtex->GetScaledLeftOffset() * newtex->Scale.X);
newtex->TopOffset = int(oldtex->GetScaledTopOffset() * newtex->Scale.Y);
newtex->_LeftOffset[0] = int(oldtex->GetScaledLeftOffset(0) * newtex->Scale.X);
newtex->_LeftOffset[1] = int(oldtex->GetScaledLeftOffset(1) * newtex->Scale.X);
newtex->_TopOffset[0] = int(oldtex->GetScaledTopOffset(0) * newtex->Scale.Y);
newtex->_TopOffset[1] = int(oldtex->GetScaledTopOffset(1) * newtex->Scale.Y);
ReplaceTexture(tlist[i], newtex, true);
}
}
@ -1040,6 +1044,7 @@ void FTextureManager::Init()
FixAnimations();
InitSwitchList();
InitPalettedVersions();
AdjustSpriteOffsets();
}
//==========================================================================
@ -1188,6 +1193,105 @@ int FTextureManager::CountLumpTextures (int lumpnum)
return 0;
}
//-----------------------------------------------------------------------------
//
// Adjust sprite offsets for GL rendering (IWAD resources only)
//
//-----------------------------------------------------------------------------
void FTextureManager::AdjustSpriteOffsets()
{
int lump, lastlump = 0;
int sprid;
TMap<int, bool> donotprocess;
int numtex = Wads.GetNumLumps();
for (int i = 0; i < numtex; i++)
{
if (Wads.GetLumpFile(i) > Wads.GetIwadNum()) break; // we are past the IWAD
if (Wads.GetLumpNamespace(i) == ns_sprites && Wads.GetLumpFile(i) == Wads.GetIwadNum())
{
char str[9];
Wads.GetLumpName(str, i);
str[8] = 0;
FTextureID texid = TexMan.CheckForTexture(str, ETextureType::Sprite, 0);
if (texid.isValid() && Wads.GetLumpFile(TexMan[texid]->SourceLump) > Wads.GetIwadNum())
{
// This texture has been replaced by some PWAD.
memcpy(&sprid, str, 4);
donotprocess[sprid] = true;
}
}
}
while ((lump = Wads.FindLump("SPROFS", &lastlump, false)) != -1)
{
FScanner sc;
sc.OpenLumpNum(lump);
sc.SetCMode(true);
int ofslumpno = Wads.GetLumpFile(lump);
while (sc.GetString())
{
int x, y;
bool iwadonly = false;
bool forced = false;
FTextureID texno = TexMan.CheckForTexture(sc.String, ETextureType::Sprite);
sc.MustGetStringName(",");
sc.MustGetNumber();
x = sc.Number;
sc.MustGetStringName(",");
sc.MustGetNumber();
y = sc.Number;
if (sc.CheckString(","))
{
sc.MustGetString();
if (sc.Compare("iwad")) iwadonly = true;
if (sc.Compare("iwadforced")) forced = iwadonly = true;
}
if (texno.isValid())
{
FTexture * tex = TexMan[texno];
int lumpnum = tex->GetSourceLump();
// We only want to change texture offsets for sprites in the IWAD or the file this lump originated from.
if (lumpnum >= 0 && lumpnum < Wads.GetNumLumps())
{
int wadno = Wads.GetLumpFile(lumpnum);
if ((iwadonly && wadno == Wads.GetIwadNum()) || (!iwadonly && wadno == ofslumpno))
{
if (wadno == Wads.GetIwadNum() && !forced && iwadonly)
{
memcpy(&sprid, &tex->Name[0], 4);
if (donotprocess.CheckKey(sprid)) continue; // do not alter sprites that only get partially replaced.
}
tex->_LeftOffset[1] = x;
tex->_TopOffset[1] = y;
}
}
}
}
}
}
//-----------------------------------------------------------------------------
//
//
//
//-----------------------------------------------------------------------------
void FTextureManager::SpriteAdjustChanged()
{
for (auto &texi : Textures)
{
auto tex = texi.Texture;
if (tex->GetLeftOffset(0) != tex->GetLeftOffset(1) || tex->GetTopOffset(0) != tex->GetTopOffset(1))
{
tex->SetSpriteAdjust();
}
}
}
//==========================================================================
//
//
@ -1269,7 +1373,7 @@ DEFINE_ACTION_FUNCTION(_TexMan, GetScaledOffset)
auto tex = TexMan.ByIndex(texid);
if (tex != nullptr)
{
ACTION_RETURN_VEC2(DVector2(tex->GetScaledLeftOffsetDouble(), tex->GetScaledTopOffsetDouble()));
ACTION_RETURN_VEC2(DVector2(tex->GetScaledLeftOffsetDouble(0), tex->GetScaledTopOffsetDouble(0)));
}
ACTION_RETURN_VEC2(DVector2(-1, -1));
}

View File

@ -75,6 +75,7 @@ class FTextureManager;
class FTerrainTypeArray;
class FGLTexture;
class FMaterial;
extern int r_spriteadjustSW, r_spriteadjustHW;
class FNullTextureID : public FTextureID
{
@ -171,7 +172,7 @@ public:
static FTexture *CreateTexture(int lumpnum, ETextureType usetype);
virtual ~FTexture ();
int16_t LeftOffset, TopOffset;
//int16_t LeftOffset, TopOffset;
uint8_t WidthBits, HeightBits;
@ -245,10 +246,33 @@ public:
double GetScaledHeightDouble () { return Height / Scale.Y; }
double GetScaleY() const { return Scale.Y; }
int GetScaledLeftOffset () { int foo = int((LeftOffset * 2) / Scale.X); return (foo >> 1) + (foo & 1); }
int GetScaledTopOffset () { int foo = int((TopOffset * 2) / Scale.Y); return (foo >> 1) + (foo & 1); }
double GetScaledLeftOffsetDouble() { return LeftOffset / Scale.X; }
double GetScaledTopOffsetDouble() { return TopOffset / Scale.Y; }
// Now with improved offset adjustment.
int GetLeftOffset(int adjusted) { return _LeftOffset[adjusted]; }
int GetTopOffset(int adjusted) { return _TopOffset[adjusted]; }
int GetScaledLeftOffset (int adjusted) { int foo = int((_LeftOffset[adjusted] * 2) / Scale.X); return (foo >> 1) + (foo & 1); }
int GetScaledTopOffset (int adjusted) { int foo = int((_TopOffset[adjusted] * 2) / Scale.Y); return (foo >> 1) + (foo & 1); }
double GetScaledLeftOffsetDouble(int adjusted) { return _LeftOffset[adjusted] / Scale.X; }
double GetScaledTopOffsetDouble(int adjusted) { return _TopOffset[adjusted] / Scale.Y; }
// Interfaces for the different renderers. Everything that needs to check renderer-dependent offsets
// should use these, so that if changes are needed, this is the only place to edit.
// For the original software renderer
int GetLeftOffsetSW() { return _LeftOffset[r_spriteadjustSW]; }
int GetTopOffsetSW() { return _TopOffset[r_spriteadjustSW]; }
int GetScaledLeftOffsetSW() { return GetScaledLeftOffset(r_spriteadjustSW); }
int GetScaledTopOffsetSW() { return GetScaledTopOffset(r_spriteadjustSW); }
// For the softpoly renderer, in case it wants adjustment
int GetLeftOffsetPo() { return _LeftOffset[r_spriteadjustSW]; }
int GetTopOffsetPo() { return _TopOffset[r_spriteadjustSW]; }
int GetScaledLeftOffsetPo() { return GetScaledLeftOffset(r_spriteadjustSW); }
int GetScaledTopOffsetPo() { return GetScaledTopOffset(r_spriteadjustSW); }
// For the hardware renderer
int GetLeftOffsetHW() { return _LeftOffset[r_spriteadjustHW]; }
int GetTopOffsetHW() { return _TopOffset[r_spriteadjustHW]; }
virtual void ResolvePatches() {}
virtual void SetFrontSkyLayer();
@ -266,8 +290,10 @@ public:
{
Width = BaseTexture->GetWidth();
Height = BaseTexture->GetHeight();
TopOffset = BaseTexture->TopOffset;
LeftOffset = BaseTexture->LeftOffset;
_TopOffset[0] = BaseTexture->_TopOffset[0];
_TopOffset[1] = BaseTexture->_TopOffset[1];
_LeftOffset[0] = BaseTexture->_LeftOffset[0];
_LeftOffset[1] = BaseTexture->_LeftOffset[1];
WidthBits = BaseTexture->WidthBits;
HeightBits = BaseTexture->HeightBits;
Scale = BaseTexture->Scale;
@ -280,6 +306,7 @@ public:
protected:
uint16_t Width, Height, WidthMask;
int16_t _LeftOffset[2], _TopOffset[2];
static uint8_t GrayMap[256];
uint8_t *GetRemap(FRenderStyle style, bool srcisgrayscale = false)
{
@ -414,6 +441,9 @@ public:
void CheckTrans(unsigned char * buffer, int size, int trans);
bool ProcessData(unsigned char * buffer, int w, int h, bool ispatch);
int CheckRealHeight();
void SetSpriteAdjust();
friend class FTextureManager;
};
class FxAddSub;
@ -514,6 +544,7 @@ public:
void AddTexturesForWad(int wadnum);
void Init();
void DeleteAll();
void SpriteAdjustChanged();
// Replaces one texture with another. The new texture will be assigned
// the same name, slot, and use type as the texture it is replacing.
@ -539,6 +570,7 @@ private:
// texture counting
int CountTexturesX ();
int CountLumpTextures (int lumpnum);
void AdjustSpriteOffsets();
// Build tiles
void AddTiles (const FString &pathprefix, const void *, int translation);

View File

@ -274,11 +274,11 @@ bool DFrameBuffer::SetTextureParms(DrawParms *parms, FTexture *img, double xx, d
parms->texheight = img->GetScaledHeightDouble();
if (parms->top == INT_MAX || parms->fortext)
{
parms->top = img->GetScaledTopOffset();
parms->top = img->GetScaledTopOffset(0);
}
if (parms->left == INT_MAX || parms->fortext)
{
parms->left = img->GetScaledLeftOffset();
parms->left = img->GetScaledLeftOffset(0);
}
if (parms->destwidth == INT_MAX || parms->fortext)
{

View File

@ -417,7 +417,7 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count,
charlumps[i] = pic;
int height = pic->GetScaledHeight();
int yoffs = pic->GetScaledTopOffset();
int yoffs = pic->GetScaledTopOffset(0);
if (yoffs > maxyoffs)
{
@ -1713,8 +1713,8 @@ FFontChar2::FFontChar2 (int sourcelump, int sourcepos, int width, int height, in
UseType = ETextureType::FontChar;
Width = width;
Height = height;
LeftOffset = leftofs;
TopOffset = topofs;
_LeftOffset[1] = _LeftOffset[0] = leftofs;
_TopOffset[1] = _TopOffset[0] = topofs;
CalcBitSize ();
}
@ -1964,7 +1964,7 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **l
if (pic != NULL)
{
int height = pic->GetScaledHeight();
int yoffs = pic->GetScaledTopOffset();
int yoffs = pic->GetScaledTopOffset(0);
if (yoffs > maxyoffs)
{

View File

@ -228,8 +228,8 @@ private:
right = c[i]->GetScaledWidth();
bottom = c[i]->GetScaledHeight();
left = lnodes[n].x - c[i]->GetScaledLeftOffset();
top = lnodes[n].y - c[i]->GetScaledTopOffset();
left = lnodes[n].x - c[i]->GetScaledLeftOffset(0);
top = lnodes[n].y - c[i]->GetScaledTopOffset(0);
right += left;
bottom += top;

View File

@ -1041,7 +1041,7 @@ static HCURSOR CreateCompatibleCursor(FTexture *cursorpic)
DeleteDC(xor_mask_dc);
// Create the cursor from the bitmaps.
return CreateBitmapCursor(cursorpic->LeftOffset, cursorpic->TopOffset, and_mask, xor_mask);
return CreateBitmapCursor(cursorpic->GetLeftOffset(0), cursorpic->GetTopOffset(0), and_mask, xor_mask);
}
//==========================================================================
@ -1125,7 +1125,7 @@ static HCURSOR CreateAlphaCursor(FTexture *cursorpic)
}
}
return CreateBitmapCursor(cursorpic->LeftOffset * scale, cursorpic->TopOffset * scale, mono, color);
return CreateBitmapCursor(cursorpic->GetLeftOffset(0) * scale, cursorpic->GetTopOffset(0) * scale, mono, color);
}
//==========================================================================