- 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); tex = TexMan(gameinfo.PauseSign);
x = (SCREENWIDTH - tex->GetScaledWidth() * CleanXfac)/2 + x = (SCREENWIDTH - tex->GetScaledWidth() * CleanXfac)/2 +
tex->GetScaledLeftOffset() * CleanXfac; tex->GetScaledLeftOffset(0) * CleanXfac;
screen->DrawTexture (tex, x, 4, DTA_CleanNoMove, true, TAG_DONE); screen->DrawTexture (tex, x, 4, DTA_CleanNoMove, true, TAG_DONE);
if (paused && multiplayer) 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 (); int dwidth = tex->GetWidth ();
DecalWidth = dwidth * ScaleX; DecalWidth = dwidth * ScaleX;
DecalLeft = tex->LeftOffset * ScaleX; DecalLeft = tex->GetLeftOffset(0) * ScaleX;
DecalRight = DecalWidth - DecalLeft; DecalRight = DecalWidth - DecalLeft;
SpreadSource = this; SpreadSource = this;
SpreadTemplate = tpl; 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); FTexture *texc = font->GetChar(text[i], &width);
if (texc != NULL) if (texc != NULL)
{ {
double offset = texc->GetScaledTopOffsetDouble() double offset = texc->GetScaledTopOffsetDouble(0)
- tex_zero->GetScaledTopOffsetDouble() - tex_zero->GetScaledTopOffsetDouble(0)
+ tex_zero->GetScaledHeightDouble(); + tex_zero->GetScaledHeightDouble();
screen->DrawChar(font, color, x, y, text[i], screen->DrawChar(font, color, x, y, text[i],

View file

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

View file

@ -70,87 +70,6 @@ CUSTOM_CVAR(Bool, gl_notexturefill, false, 0)
void gl_CreateSections(); void gl_CreateSections();
void AddAutoMaterials(); 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() void gl_InitData()
{ {
AdjustSpriteOffsets();
AddAutoMaterials(); AddAutoMaterials();
} }

View file

@ -520,8 +520,8 @@ FMaterial::FMaterial(FTexture * tx, bool expanded)
mWidth = tx->GetWidth(); mWidth = tx->GetWidth();
mHeight = tx->GetHeight(); mHeight = tx->GetHeight();
mLeftOffset = tx->LeftOffset; mLeftOffset = tx->GetLeftOffset(0); // These only get used by decals and decals should not use renderer-specific offsets.
mTopOffset = tx->TopOffset; mTopOffset = tx->GetTopOffset(0);
mRenderWidth = tx->GetScaledWidth(); mRenderWidth = tx->GetScaledWidth();
mRenderHeight = tx->GetScaledHeight(); mRenderHeight = tx->GetScaledHeight();
mSpriteU[0] = mSpriteV[0] = 0.f; mSpriteU[0] = mSpriteV[0] = 0.f;
@ -534,59 +534,26 @@ FMaterial::FMaterial(FTexture * tx, bool expanded)
mBaseLayer = ValidateSysTexture(basetex, expanded); mBaseLayer = ValidateSysTexture(basetex, expanded);
} }
float fxScale = tx->Scale.X; mExpanded = expanded;
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;
if (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 oldwidth = mWidth;
int oldheight = mHeight; int oldheight = mHeight;
mWidth+=2; mTrimResult = TrimBorders(trim); // get the trim size before adding the empty frame
mHeight+=2; mWidth += 2;
mLeftOffset+=1; mHeight += 2;
mTopOffset+=1;
mRenderWidth = mRenderWidth * mWidth / oldwidth; mRenderWidth = mRenderWidth * mWidth / oldwidth;
mRenderHeight = mRenderHeight * mHeight / oldheight; 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(); mTextureLayers.ShrinkToFit();
mMaxBound = -1; mMaxBound = -1;
mMaterials.Push(this); mMaterials.Push(this);
tx->gl_info.Material[expanded] = this; tx->gl_info.Material[expanded] = this;
if (tx->bHasCanvas) tx->gl_info.mIsTransparent = 0; 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; PalEntry col;
int w; int w;

View file

@ -122,18 +122,21 @@ class FMaterial
short mRenderWidth; short mRenderWidth;
short mRenderHeight; short mRenderHeight;
bool mExpanded; bool mExpanded;
bool mTrimResult;
uint16_t trim[4];
float mSpriteU[2], mSpriteV[2]; float mSpriteU[2], mSpriteV[2];
FloatRect mSpriteRect; FloatRect mSpriteRect;
FGLTexture * ValidateSysTexture(FTexture * tex, bool expand); FGLTexture * ValidateSysTexture(FTexture * tex, bool expand);
bool TrimBorders(int *rect); bool TrimBorders(uint16_t *rect);
public: public:
FTexture *tex; FTexture *tex;
FMaterial(FTexture *tex, bool forceexpand); FMaterial(FTexture *tex, bool forceexpand);
~FMaterial(); ~FMaterial();
void SetSpriteRect();
void Precache(); void Precache();
void PrecacheList(SpriteHits &translations); void PrecacheList(SpriteHits &translations);
bool isMasked() const bool isMasked() const
@ -199,37 +202,6 @@ public:
return mTopOffset; 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 // Get right/bottom UV coordinates for patch drawing
float GetUL() const { return 0; } float GetUL() const { return 0; }
float GetVT() 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; 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 // fake brightness maps

View file

@ -213,14 +213,14 @@ void HU_GetPlayerWidths(int &maxnamewidth, int &maxscorewidth, int &maxiconheigh
if (players[i].mo->ScoreIcon.isValid()) if (players[i].mo->ScoreIcon.isValid())
{ {
FTexture *pic = TexMan[players[i].mo->ScoreIcon]; FTexture *pic = TexMan[players[i].mo->ScoreIcon];
width = pic->GetScaledWidth() - pic->GetScaledLeftOffset() + 2; width = pic->GetScaledWidth() - pic->GetScaledLeftOffset(0) + 2;
if (width > maxscorewidth) if (width > maxscorewidth)
{ {
maxscorewidth = width; maxscorewidth = width;
} }
// The icon's top offset does not count toward its height, because // The icon's top offset does not count toward its height, because
// zdoom.pk3's standard Hexen class icons are designed that way. // 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) if (height > maxiconheight)
{ {
maxiconheight = height; maxiconheight = height;

View file

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

View file

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

View file

@ -63,9 +63,9 @@ bool RenderPolySprite::GetLine(AActor *thing, DVector2 &left, DVector2 &right)
double offsetX; double offsetX;
if (flipTextureX) if (flipTextureX)
offsetX = (tex->GetWidth() - tex->LeftOffset) * thingxscalemul; offsetX = (tex->GetWidth() - tex->GetLeftOffsetPo()) * thingxscalemul;
else else
offsetX = tex->LeftOffset * thingxscalemul; offsetX = tex->GetLeftOffsetPo() * thingxscalemul;
left = DVector2(pos.X - viewpoint.Sin * offsetX, pos.Y + viewpoint.Cos * offsetX); left = DVector2(pos.X - viewpoint.Sin * offsetX, pos.Y + viewpoint.Cos * offsetX);
right = DVector2(left.X + viewpoint.Sin * spriteWidth, left.Y - viewpoint.Cos * spriteWidth); 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 thingyscalemul = thing->Scale.Y / tex->Scale.Y;
double spriteHeight = thingyscalemul * tex->GetHeight(); double spriteHeight = thingyscalemul * tex->GetHeight();
posZ -= (tex->GetHeight() - tex->TopOffset) * thingyscalemul; posZ -= (tex->GetHeight() - tex->GetTopOffsetPo()) * thingyscalemul;
posZ = PerformSpriteClipAdjustment(thing, thingpos, spriteHeight, posZ); posZ = PerformSpriteClipAdjustment(thing, thingpos, spriteHeight, posZ);
//double depth = 1.0; //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, // Determine left and right edges of sprite. The sprite's angle is its normal,
// so the edges are 90 degrees each side of it. // so the edges are 90 degrees each side of it.
double x2 = tex->GetScaledWidth() * spriteScale.X; double x2 = tex->GetScaledWidth() * spriteScale.X;
double x1 = tex->GetScaledLeftOffset() * spriteScale.X; double x1 = tex->GetScaledLeftOffsetPo() * spriteScale.X;
DVector2 left, right; DVector2 left, right;
left.X = pos.X - x1 * angcos; left.X = pos.X - x1 * angcos;
left.Y = pos.Y - x1 * angsin; left.Y = pos.Y - x1 * angsin;

View file

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

View file

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

View file

@ -142,7 +142,7 @@ namespace swrenderer
// pretty much the same as what R_AddLine() does. // pretty much the same as what R_AddLine() does.
double edge_right = WallSpriteTile->GetWidth(); 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_right = (edge_right - edge_left) * decal->ScaleX;
edge_left *= decal->ScaleX; edge_left *= decal->ScaleX;
@ -233,7 +233,7 @@ namespace swrenderer
} }
yscale = decal->ScaleY; 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 // Clip sprite to drawseg
x1 = MAX<int>(clipper->x1, x1); 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 pspriteyscale = pspritexscale * viewport->BaseYaspectMul * ((double)SCREENHEIGHT / SCREENWIDTH) * r_viewwindow.WidescreenRatio;
double pspritexiscale = 1 / pspritexscale; double pspritexiscale = 1 / pspritexscale;
int tleft = tex->GetScaledLeftOffset(); int tleft = tex->GetScaledLeftOffset(0);
int twidth = tex->GetScaledWidth(); int twidth = tex->GetScaledWidth();
// calculate edges of the shape // calculate edges of the shape
@ -287,7 +287,7 @@ namespace swrenderer
vis.renderflags = owner->renderflags; 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(); auto screencanvas = screen->GetCanvas();
if (Thread->Viewport->viewpoint.camera->player && (viewport->RenderTarget != screencanvas || if (Thread->Viewport->viewpoint.camera->player && (viewport->RenderTarget != screencanvas ||

View file

@ -101,7 +101,7 @@ namespace swrenderer
} }
// [RH] Added scaling // [RH] Added scaling
int scaled_to = tex->GetScaledTopOffset(); int scaled_to = tex->GetScaledTopOffsetSW();
int scaled_bo = scaled_to - tex->GetScaledHeight(); int scaled_bo = scaled_to - tex->GetScaledHeight();
double gzt = pos.Z + spriteScale.Y * scaled_to; double gzt = pos.Z + spriteScale.Y * scaled_to;
double gzb = pos.Z + spriteScale.Y * scaled_bo; double gzb = pos.Z + spriteScale.Y * scaled_bo;
@ -153,7 +153,7 @@ namespace swrenderer
// calculate edges of the shape // calculate edges of the shape
const double thingxscalemul = spriteScale.X / tex->Scale.X; 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; double dtx1 = tx * xscale;
int x1 = viewport->viewwindow.centerx + xs_RoundToInt(dtx1); int x1 = viewport->viewwindow.centerx + xs_RoundToInt(dtx1);
@ -181,7 +181,7 @@ namespace swrenderer
vis->yscale = float(viewport->InvZtoScale * yscale / tz); vis->yscale = float(viewport->InvZtoScale * yscale / tz);
vis->idepth = float(1 / tz); vis->idepth = float(1 / tz);
vis->floorclip = thing->Floorclip / yscale; 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->x1 = x1 < renderportal->WindowLeft ? renderportal->WindowLeft : x1;
vis->x2 = x2 > renderportal->WindowRight ? renderportal->WindowRight : x2; vis->x2 = x2 > renderportal->WindowRight ? renderportal->WindowRight : x2;
//vis->Angle = thing->Angles.Yaw; //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, // Determine left and right edges of sprite. The sprite's angle is its normal,
// so the edges are 90 degrees each side of it. // so the edges are 90 degrees each side of it.
x2 = pic->GetScaledWidth(); x2 = pic->GetScaledWidth();
x1 = pic->GetScaledLeftOffset(); x1 = pic->GetScaledLeftOffsetSW();
x1 *= scale.X; x1 *= scale.X;
x2 *= scale.X; x2 *= scale.X;
@ -107,7 +107,7 @@ namespace swrenderer
// but right now, I just want to get them drawing. // 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; 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(); int scaled_bo = scaled_to - pic->GetScaledHeight();
gzt = pos.Z + scale.Y * scaled_to; gzt = pos.Z + scale.Y * scaled_to;
gzb = pos.Z + scale.Y * scaled_bo; gzb = pos.Z + scale.Y * scaled_bo;

View file

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

View file

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

View file

@ -290,8 +290,6 @@ FDDSTexture::FDDSTexture (FileReader &lump, int lumpnum, void *vsurfdesc)
DDSURFACEDESC2 *surf = (DDSURFACEDESC2 *)vsurfdesc; DDSURFACEDESC2 *surf = (DDSURFACEDESC2 *)vsurfdesc;
UseType = ETextureType::MiscPatch; UseType = ETextureType::MiscPatch;
LeftOffset = 0;
TopOffset = 0;
bMasked = false; bMasked = false;
Width = uint16_t(surf->Width); 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); Wads.GetLumpName (Name, lumpnum);
Width = w; Width = w;
Height = h; Height = h;
LeftOffset = l; _LeftOffset[1] = _LeftOffset[0] = l;
TopOffset = t; _TopOffset[1] = _TopOffset[0] = t;
isalpha = _isalpha; isalpha = _isalpha;
CalcBitSize (); CalcBitSize ();
} }
@ -131,14 +131,6 @@ uint8_t *FIMGZTexture::MakeTexture (FRenderStyle style)
const ImageHeader *imgz = (const ImageHeader *)lump.GetMem(); const ImageHeader *imgz = (const ImageHeader *)lump.GetMem();
const uint8_t *data = (const uint8_t *)&imgz[1]; 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; uint8_t *dest_p;
int dest_adv = Height; int dest_adv = Height;
int dest_rew = Width * Height - 1; int dest_rew = Width * Height - 1;

View file

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

View file

@ -1100,6 +1100,7 @@ FMultiPatchTexture::FMultiPatchTexture (FScanner &sc, ETextureType usetype)
Height = sc.Number; Height = sc.Number;
UseType = usetype; UseType = usetype;
bool offset2set = false;
if (sc.CheckString("{")) if (sc.CheckString("{"))
{ {
while (!sc.CheckString("}")) while (!sc.CheckString("}"))
@ -1183,10 +1184,24 @@ FMultiPatchTexture::FMultiPatchTexture (FScanner &sc, ETextureType usetype)
else if (sc.Compare("Offset")) else if (sc.Compare("Offset"))
{ {
sc.MustGetNumber(); sc.MustGetNumber();
LeftOffset = sc.Number; _LeftOffset[0] = sc.Number;
sc.MustGetStringName(","); sc.MustGetStringName(",");
sc.MustGetNumber(); 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 else
{ {
@ -1264,8 +1279,8 @@ void FMultiPatchTexture::ResolvePatches()
Parts[i].Texture->bKeepAround = true; Parts[i].Texture->bKeepAround = true;
if (Inits[i].UseOffsets) if (Inits[i].UseOffsets)
{ {
Parts[i].OriginX -= Parts[i].Texture->LeftOffset; Parts[i].OriginX -= Parts[i].Texture->GetLeftOffset(0);
Parts[i].OriginY -= Parts[i].Texture->TopOffset; 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; isalpha = isalphatex;
Width = header->width; Width = header->width;
Height = header->height; Height = header->height;
LeftOffset = header->leftoffset; _LeftOffset[1] = _LeftOffset[0] = header->leftoffset;
TopOffset = header->topoffset; _TopOffset[1] = _TopOffset[0] = header->topoffset;
DetectBadPatches(); DetectBadPatches();
CalcBitSize (); CalcBitSize ();
} }
@ -310,8 +310,8 @@ void FPatchTexture::DetectBadPatches ()
return; // More than one post in a column! return; // More than one post in a column!
} }
} }
LeftOffset = 0; _LeftOffset[1] = _LeftOffset[0] = 0;
TopOffset = 0; _TopOffset[1] = _TopOffset[0] = 0;
badflag = true; badflag = true;
bMasked = false; // Hacked textures don't have transparent parts. 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; int i;
UseType = ETextureType::MiscPatch; UseType = ETextureType::MiscPatch;
LeftOffset = 0;
TopOffset = 0;
bMasked = false; bMasked = false;
Width = width; 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); Printf ("Y-Offset for PNG texture %s is bad: %d (0x%08x)\n", Wads.GetLumpFullName (lumpnum), ihoty, ihoty);
ihoty = 0; ihoty = 0;
} }
LeftOffset = ihotx; _LeftOffset[1] = _LeftOffset[0] = ihotx;
TopOffset = ihoty; _TopOffset[1] = _TopOffset[0] = ihoty;
} }
break; break;

View file

@ -47,6 +47,15 @@
#include "textures/textures.h" #include "textures/textures.h"
#include "v_palette.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); typedef FTexture * (*CreateFunc)(FileReader & file, int lumpnum);
struct TexCreateInfo struct TexCreateInfo
@ -146,12 +155,13 @@ FTexture * FTexture::CreateTexture (const char *name, int lumpnum, ETextureType
FTexture::FTexture (const char *name, int lumpnum) FTexture::FTexture (const char *name, int lumpnum)
: LeftOffset(0), TopOffset(0), :
WidthBits(0), HeightBits(0), Scale(1,1), SourceLump(lumpnum), WidthBits(0), HeightBits(0), Scale(1,1), SourceLump(lumpnum),
UseType(ETextureType::Any), bNoDecals(false), bNoRemap0(false), bWorldPanning(false), UseType(ETextureType::Any), bNoDecals(false), bNoRemap0(false), bWorldPanning(false),
bMasked(true), bAlphaTexture(false), bHasCanvas(false), bWarped(0), bComplex(false), bMultiPatch(false), bKeepAround(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) Rotations(0xFFFF), SkyOffset(0), Width(0), Height(0), WidthMask(0)
{ {
_LeftOffset[0] = _LeftOffset[1] = _TopOffset[0] = _TopOffset[1] = 0;
id.SetInvalid(); id.SetInvalid();
if (name != NULL) 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. // Replace the entire texture and adjust the scaling and offset factors.
newtex->bWorldPanning = true; newtex->bWorldPanning = true;
newtex->SetScaledSize(oldtex->GetScaledWidth(), oldtex->GetScaledHeight()); newtex->SetScaledSize(oldtex->GetScaledWidth(), oldtex->GetScaledHeight());
newtex->LeftOffset = int(oldtex->GetScaledLeftOffset() * newtex->Scale.X); newtex->_LeftOffset[0] = int(oldtex->GetScaledLeftOffset(0) * newtex->Scale.X);
newtex->TopOffset = int(oldtex->GetScaledTopOffset() * newtex->Scale.Y); 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); 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. // Replace the entire texture and adjust the scaling and offset factors.
newtex->bWorldPanning = true; newtex->bWorldPanning = true;
newtex->SetScaledSize(oldtex->GetScaledWidth(), oldtex->GetScaledHeight()); newtex->SetScaledSize(oldtex->GetScaledWidth(), oldtex->GetScaledHeight());
newtex->LeftOffset = int(oldtex->GetScaledLeftOffset() * newtex->Scale.X); newtex->_LeftOffset[0] = int(oldtex->GetScaledLeftOffset(0) * newtex->Scale.X);
newtex->TopOffset = int(oldtex->GetScaledTopOffset() * newtex->Scale.Y); 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); ReplaceTexture(tlist[i], newtex, true);
} }
} }
@ -1040,6 +1044,7 @@ void FTextureManager::Init()
FixAnimations(); FixAnimations();
InitSwitchList(); InitSwitchList();
InitPalettedVersions(); InitPalettedVersions();
AdjustSpriteOffsets();
} }
//========================================================================== //==========================================================================
@ -1188,6 +1193,105 @@ int FTextureManager::CountLumpTextures (int lumpnum)
return 0; 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); auto tex = TexMan.ByIndex(texid);
if (tex != nullptr) 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)); ACTION_RETURN_VEC2(DVector2(-1, -1));
} }

View file

@ -75,6 +75,7 @@ class FTextureManager;
class FTerrainTypeArray; class FTerrainTypeArray;
class FGLTexture; class FGLTexture;
class FMaterial; class FMaterial;
extern int r_spriteadjustSW, r_spriteadjustHW;
class FNullTextureID : public FTextureID class FNullTextureID : public FTextureID
{ {
@ -171,7 +172,7 @@ public:
static FTexture *CreateTexture(int lumpnum, ETextureType usetype); static FTexture *CreateTexture(int lumpnum, ETextureType usetype);
virtual ~FTexture (); virtual ~FTexture ();
int16_t LeftOffset, TopOffset; //int16_t LeftOffset, TopOffset;
uint8_t WidthBits, HeightBits; uint8_t WidthBits, HeightBits;
@ -245,10 +246,33 @@ public:
double GetScaledHeightDouble () { return Height / Scale.Y; } double GetScaledHeightDouble () { return Height / Scale.Y; }
double GetScaleY() const { return Scale.Y; } double GetScaleY() const { return Scale.Y; }
int GetScaledLeftOffset () { int foo = int((LeftOffset * 2) / Scale.X); return (foo >> 1) + (foo & 1); } // Now with improved offset adjustment.
int GetScaledTopOffset () { int foo = int((TopOffset * 2) / Scale.Y); return (foo >> 1) + (foo & 1); } int GetLeftOffset(int adjusted) { return _LeftOffset[adjusted]; }
double GetScaledLeftOffsetDouble() { return LeftOffset / Scale.X; } int GetTopOffset(int adjusted) { return _TopOffset[adjusted]; }
double GetScaledTopOffsetDouble() { return TopOffset / Scale.Y; } 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 ResolvePatches() {}
virtual void SetFrontSkyLayer(); virtual void SetFrontSkyLayer();
@ -266,8 +290,10 @@ public:
{ {
Width = BaseTexture->GetWidth(); Width = BaseTexture->GetWidth();
Height = BaseTexture->GetHeight(); Height = BaseTexture->GetHeight();
TopOffset = BaseTexture->TopOffset; _TopOffset[0] = BaseTexture->_TopOffset[0];
LeftOffset = BaseTexture->LeftOffset; _TopOffset[1] = BaseTexture->_TopOffset[1];
_LeftOffset[0] = BaseTexture->_LeftOffset[0];
_LeftOffset[1] = BaseTexture->_LeftOffset[1];
WidthBits = BaseTexture->WidthBits; WidthBits = BaseTexture->WidthBits;
HeightBits = BaseTexture->HeightBits; HeightBits = BaseTexture->HeightBits;
Scale = BaseTexture->Scale; Scale = BaseTexture->Scale;
@ -280,6 +306,7 @@ public:
protected: protected:
uint16_t Width, Height, WidthMask; uint16_t Width, Height, WidthMask;
int16_t _LeftOffset[2], _TopOffset[2];
static uint8_t GrayMap[256]; static uint8_t GrayMap[256];
uint8_t *GetRemap(FRenderStyle style, bool srcisgrayscale = false) uint8_t *GetRemap(FRenderStyle style, bool srcisgrayscale = false)
{ {
@ -414,6 +441,9 @@ public:
void CheckTrans(unsigned char * buffer, int size, int trans); void CheckTrans(unsigned char * buffer, int size, int trans);
bool ProcessData(unsigned char * buffer, int w, int h, bool ispatch); bool ProcessData(unsigned char * buffer, int w, int h, bool ispatch);
int CheckRealHeight(); int CheckRealHeight();
void SetSpriteAdjust();
friend class FTextureManager;
}; };
class FxAddSub; class FxAddSub;
@ -514,6 +544,7 @@ public:
void AddTexturesForWad(int wadnum); void AddTexturesForWad(int wadnum);
void Init(); void Init();
void DeleteAll(); void DeleteAll();
void SpriteAdjustChanged();
// Replaces one texture with another. The new texture will be assigned // Replaces one texture with another. The new texture will be assigned
// the same name, slot, and use type as the texture it is replacing. // the same name, slot, and use type as the texture it is replacing.
@ -539,6 +570,7 @@ private:
// texture counting // texture counting
int CountTexturesX (); int CountTexturesX ();
int CountLumpTextures (int lumpnum); int CountLumpTextures (int lumpnum);
void AdjustSpriteOffsets();
// Build tiles // Build tiles
void AddTiles (const FString &pathprefix, const void *, int translation); 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(); parms->texheight = img->GetScaledHeightDouble();
if (parms->top == INT_MAX || parms->fortext) if (parms->top == INT_MAX || parms->fortext)
{ {
parms->top = img->GetScaledTopOffset(); parms->top = img->GetScaledTopOffset(0);
} }
if (parms->left == INT_MAX || parms->fortext) if (parms->left == INT_MAX || parms->fortext)
{ {
parms->left = img->GetScaledLeftOffset(); parms->left = img->GetScaledLeftOffset(0);
} }
if (parms->destwidth == INT_MAX || parms->fortext) 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; charlumps[i] = pic;
int height = pic->GetScaledHeight(); int height = pic->GetScaledHeight();
int yoffs = pic->GetScaledTopOffset(); int yoffs = pic->GetScaledTopOffset(0);
if (yoffs > maxyoffs) if (yoffs > maxyoffs)
{ {
@ -1713,8 +1713,8 @@ FFontChar2::FFontChar2 (int sourcelump, int sourcepos, int width, int height, in
UseType = ETextureType::FontChar; UseType = ETextureType::FontChar;
Width = width; Width = width;
Height = height; Height = height;
LeftOffset = leftofs; _LeftOffset[1] = _LeftOffset[0] = leftofs;
TopOffset = topofs; _TopOffset[1] = _TopOffset[0] = topofs;
CalcBitSize (); CalcBitSize ();
} }
@ -1964,7 +1964,7 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **l
if (pic != NULL) if (pic != NULL)
{ {
int height = pic->GetScaledHeight(); int height = pic->GetScaledHeight();
int yoffs = pic->GetScaledTopOffset(); int yoffs = pic->GetScaledTopOffset(0);
if (yoffs > maxyoffs) if (yoffs > maxyoffs)
{ {

View file

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

View file

@ -1041,7 +1041,7 @@ static HCURSOR CreateCompatibleCursor(FTexture *cursorpic)
DeleteDC(xor_mask_dc); DeleteDC(xor_mask_dc);
// Create the cursor from the bitmaps. // 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);
} }
//========================================================================== //==========================================================================