From 6d6196388e336b5e4243729acf8785862830ae0f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 31 Mar 2018 10:37:46 +0200 Subject: [PATCH] - 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. --- src/d_main.cpp | 2 +- src/g_shared/a_decals.cpp | 2 +- src/g_shared/shared_hud.cpp | 4 +- src/g_statusbar/sbarinfo.cpp | 32 +++--- src/g_statusbar/shared_sbar.cpp | 8 +- src/gl/data/gl_data.cpp | 82 ------------- src/gl/textures/gl_material.cpp | 102 ++++++++++------- src/gl/textures/gl_material.h | 36 +----- src/gl/textures/gl_texture.cpp | 15 +++ src/hu_scores.cpp | 4 +- src/polyrenderer/scene/poly_decal.cpp | 5 +- src/polyrenderer/scene/poly_playersprite.cpp | 4 +- src/polyrenderer/scene/poly_sprite.cpp | 6 +- src/polyrenderer/scene/poly_wallsprite.cpp | 2 +- src/posix/cocoa/i_video.mm | 13 --- src/posix/sdl/sdlglvideo.cpp | 11 -- src/swrenderer/things/r_decal.cpp | 4 +- src/swrenderer/things/r_playersprite.cpp | 4 +- src/swrenderer/things/r_sprite.cpp | 6 +- src/swrenderer/things/r_wallsprite.cpp | 4 +- src/textures/buildtexture.cpp | 4 +- src/textures/canvastexture.cpp | 1 - src/textures/ddstexture.cpp | 2 - src/textures/imgztexture.cpp | 12 +- src/textures/jpegtexture.cpp | 2 - src/textures/multipatchtexture.cpp | 23 +++- src/textures/patchtexture.cpp | 8 +- src/textures/pngtexture.cpp | 6 +- src/textures/texture.cpp | 12 +- src/textures/texturemanager.cpp | 114 ++++++++++++++++++- src/textures/textures.h | 46 ++++++-- src/v_draw.cpp | 4 +- src/v_font.cpp | 8 +- src/wi_stuff.cpp | 4 +- src/win32/i_system.cpp | 4 +- 35 files changed, 322 insertions(+), 274 deletions(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index 1d857a8090..ac732ff21e 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -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) { diff --git a/src/g_shared/a_decals.cpp b/src/g_shared/a_decals.cpp index edc170294a..29807f5b36 100644 --- a/src/g_shared/a_decals.cpp +++ b/src/g_shared/a_decals.cpp @@ -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; diff --git a/src/g_shared/shared_hud.cpp b/src/g_shared/shared_hud.cpp index 34f5c3b65a..da66b9205e 100644 --- a/src/g_shared/shared_hud.cpp +++ b/src/g_shared/shared_hud.cpp @@ -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], diff --git a/src/g_statusbar/sbarinfo.cpp b/src/g_statusbar/sbarinfo.cpp index d048ffc0e4..277684a6a5 100644 --- a/src/g_statusbar/sbarinfo.cpp +++ b/src/g_statusbar/sbarinfo.cpp @@ -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++; diff --git a/src/g_statusbar/shared_sbar.cpp b/src/g_statusbar/shared_sbar.cpp index 054de4a2e0..440baf69eb 100644 --- a/src/g_statusbar/shared_sbar.cpp +++ b/src/g_statusbar/shared_sbar.cpp @@ -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; } diff --git a/src/gl/data/gl_data.cpp b/src/gl/data/gl_data.cpp index 6fb37c43f4..a773b337e4 100644 --- a/src/gl/data/gl_data.cpp +++ b/src/gl/data/gl_data.cpp @@ -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 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(); } diff --git a/src/gl/textures/gl_material.cpp b/src/gl/textures/gl_material.cpp index 9758486c5a..18beb4ded8 100644 --- a/src/gl/textures/gl_material.cpp +++ b/src/gl/textures/gl_material.cpp @@ -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; diff --git a/src/gl/textures/gl_material.h b/src/gl/textures/gl_material.h index 5bd3581762..a4852c7754 100644 --- a/src/gl/textures/gl_material.h +++ b/src/gl/textures/gl_material.h @@ -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; } diff --git a/src/gl/textures/gl_texture.cpp b/src/gl/textures/gl_texture.cpp index c313611172..430e68c386 100644 --- a/src/gl/textures/gl_texture.cpp +++ b/src/gl/textures/gl_texture.cpp @@ -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 diff --git a/src/hu_scores.cpp b/src/hu_scores.cpp index a399011812..45581bfc6b 100644 --- a/src/hu_scores.cpp +++ b/src/hu_scores.cpp @@ -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; diff --git a/src/polyrenderer/scene/poly_decal.cpp b/src/polyrenderer/scene/poly_decal.cpp index c158144603..81fe2d5cf3 100644 --- a/src/polyrenderer/scene/poly_decal.cpp +++ b/src/polyrenderer/scene/poly_decal.cpp @@ -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 }; diff --git a/src/polyrenderer/scene/poly_playersprite.cpp b/src/polyrenderer/scene/poly_playersprite.cpp index 6bf47f6cba..62173c1ac5 100644 --- a/src/polyrenderer/scene/poly_playersprite.cpp +++ b/src/polyrenderer/scene/poly_playersprite.cpp @@ -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(); diff --git a/src/polyrenderer/scene/poly_sprite.cpp b/src/polyrenderer/scene/poly_sprite.cpp index 1db0fc9510..e8cebae1ae 100644 --- a/src/polyrenderer/scene/poly_sprite.cpp +++ b/src/polyrenderer/scene/poly_sprite.cpp @@ -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; diff --git a/src/polyrenderer/scene/poly_wallsprite.cpp b/src/polyrenderer/scene/poly_wallsprite.cpp index 4f0e2ba52f..88362e1e6a 100644 --- a/src/polyrenderer/scene/poly_wallsprite.cpp +++ b/src/polyrenderer/scene/poly_wallsprite.cpp @@ -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; diff --git a/src/posix/cocoa/i_video.mm b/src/posix/cocoa/i_video.mm index d81bf3d8e3..62675f32eb 100644 --- a/src/posix/cocoa/i_video.mm +++ b/src/posix/cocoa/i_video.mm @@ -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() { diff --git a/src/posix/sdl/sdlglvideo.cpp b/src/posix/sdl/sdlglvideo.cpp index 8e5475fcd2..db73d944d1 100644 --- a/src/posix/sdl/sdlglvideo.cpp +++ b/src/posix/sdl/sdlglvideo.cpp @@ -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) { diff --git a/src/swrenderer/things/r_decal.cpp b/src/swrenderer/things/r_decal.cpp index ee5b10aebe..1f9dbf6a74 100644 --- a/src/swrenderer/things/r_decal.cpp +++ b/src/swrenderer/things/r_decal.cpp @@ -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(clipper->x1, x1); diff --git a/src/swrenderer/things/r_playersprite.cpp b/src/swrenderer/things/r_playersprite.cpp index 7be96ab948..30ef2a359b 100644 --- a/src/swrenderer/things/r_playersprite.cpp +++ b/src/swrenderer/things/r_playersprite.cpp @@ -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 || diff --git a/src/swrenderer/things/r_sprite.cpp b/src/swrenderer/things/r_sprite.cpp index be26ad7c2e..8f1a060cd1 100644 --- a/src/swrenderer/things/r_sprite.cpp +++ b/src/swrenderer/things/r_sprite.cpp @@ -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; diff --git a/src/swrenderer/things/r_wallsprite.cpp b/src/swrenderer/things/r_wallsprite.cpp index f44d88e2a5..a9f8154251 100644 --- a/src/swrenderer/things/r_wallsprite.cpp +++ b/src/swrenderer/things/r_wallsprite.cpp @@ -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; diff --git a/src/textures/buildtexture.cpp b/src/textures/buildtexture.cpp index 25c7868957..bc54a22ea6 100644 --- a/src/textures/buildtexture.cpp +++ b/src/textures/buildtexture.cpp @@ -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; diff --git a/src/textures/canvastexture.cpp b/src/textures/canvastexture.cpp index 6bf85bc794..f207593f06 100644 --- a/src/textures/canvastexture.cpp +++ b/src/textures/canvastexture.cpp @@ -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; diff --git a/src/textures/ddstexture.cpp b/src/textures/ddstexture.cpp index 0ad95f4b85..a7ed985474 100644 --- a/src/textures/ddstexture.cpp +++ b/src/textures/ddstexture.cpp @@ -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); diff --git a/src/textures/imgztexture.cpp b/src/textures/imgztexture.cpp index 5b5237d0de..b2cc67baaa 100644 --- a/src/textures/imgztexture.cpp +++ b/src/textures/imgztexture.cpp @@ -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; diff --git a/src/textures/jpegtexture.cpp b/src/textures/jpegtexture.cpp index a9658014df..1bb05265b9 100644 --- a/src/textures/jpegtexture.cpp +++ b/src/textures/jpegtexture.cpp @@ -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; diff --git a/src/textures/multipatchtexture.cpp b/src/textures/multipatchtexture.cpp index 1fe6637b53..9cb93cfcb2 100644 --- a/src/textures/multipatchtexture.cpp +++ b/src/textures/multipatchtexture.cpp @@ -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); } } } diff --git a/src/textures/patchtexture.cpp b/src/textures/patchtexture.cpp index eeb900266f..8b9045c0e7 100644 --- a/src/textures/patchtexture.cpp +++ b/src/textures/patchtexture.cpp @@ -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. } diff --git a/src/textures/pngtexture.cpp b/src/textures/pngtexture.cpp index 95dc3f3a63..71f906899f 100644 --- a/src/textures/pngtexture.cpp +++ b/src/textures/pngtexture.cpp @@ -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; diff --git a/src/textures/texture.cpp b/src/textures/texture.cpp index 49a87abda7..4de99daad2 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -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) { diff --git a/src/textures/texturemanager.cpp b/src/textures/texturemanager.cpp index 6902170cca..e2ec9770a6 100644 --- a/src/textures/texturemanager.cpp +++ b/src/textures/texturemanager.cpp @@ -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 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)); } diff --git a/src/textures/textures.h b/src/textures/textures.h index 302f9bd2d4..9f383f63d2 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -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); diff --git a/src/v_draw.cpp b/src/v_draw.cpp index 6927b714ad..757a315e0d 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -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) { diff --git a/src/v_font.cpp b/src/v_font.cpp index 28b93bf243..f352e06acd 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -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) { diff --git a/src/wi_stuff.cpp b/src/wi_stuff.cpp index d60af2165f..1c2530646f 100644 --- a/src/wi_stuff.cpp +++ b/src/wi_stuff.cpp @@ -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; diff --git a/src/win32/i_system.cpp b/src/win32/i_system.cpp index 8ae32ccd14..35416de78b 100644 --- a/src/win32/i_system.cpp +++ b/src/win32/i_system.cpp @@ -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); } //==========================================================================