Merge branch 'master' into asmjit

This commit is contained in:
Christoph Oelckers 2018-11-17 20:16:03 +01:00
commit 533f66396d
11 changed files with 211 additions and 161 deletions

View file

@ -225,7 +225,7 @@ DEFINE_ACTION_FUNCTION(_CVar, SetInt)
// Only menus are allowed to change non-mod CVARs. // Only menus are allowed to change non-mod CVARs.
if (DMenu::InMenu == 0) if (DMenu::InMenu == 0)
{ {
I_FatalError("Attempt to change CVAR '%s' outside of menu code", self->GetName()); ThrowAbortException(X_OTHER, "Attempt to change CVAR '%s' outside of menu code", self->GetName());
} }
} }
PARAM_INT(val); PARAM_INT(val);
@ -243,7 +243,7 @@ DEFINE_ACTION_FUNCTION(_CVar, SetFloat)
// Only menus are allowed to change non-mod CVARs. // Only menus are allowed to change non-mod CVARs.
if (DMenu::InMenu == 0) if (DMenu::InMenu == 0)
{ {
I_FatalError("Attempt to change CVAR '%s' outside of menu code", self->GetName()); ThrowAbortException(X_OTHER, "Attempt to change CVAR '%s' outside of menu code", self->GetName());
} }
} }
PARAM_FLOAT(val); PARAM_FLOAT(val);
@ -262,7 +262,7 @@ DEFINE_ACTION_FUNCTION(_CVar, SetString)
// Only menus are allowed to change non-mod CVARs. // Only menus are allowed to change non-mod CVARs.
if (DMenu::InMenu == 0) if (DMenu::InMenu == 0)
{ {
I_FatalError("Attempt to change CVAR '%s' outside of menu code", self->GetName()); ThrowAbortException(X_OTHER, "Attempt to change CVAR '%s' outside of menu code", self->GetName());
} }
} }
PARAM_STRING(val); PARAM_STRING(val);
@ -1161,6 +1161,15 @@ void FBaseCVar::ResetToDefault ()
DEFINE_ACTION_FUNCTION(_CVar, ResetToDefault) DEFINE_ACTION_FUNCTION(_CVar, ResetToDefault)
{ {
PARAM_SELF_STRUCT_PROLOGUE(FBaseCVar); PARAM_SELF_STRUCT_PROLOGUE(FBaseCVar);
if (!(self->GetFlags() & CVAR_MOD))
{
// Only menus are allowed to change non-mod CVARs.
if (DMenu::InMenu == 0)
{
ThrowAbortException(X_OTHER, "Attempt to change CVAR '%s' outside of menu code", self->GetName());
}
}
self->ResetToDefault(); self->ResetToDefault();
return 0; return 0;
} }

View file

@ -185,6 +185,33 @@ void HWPortal::DrawPortalStencil(FRenderState &state, int pass)
mPrimIndices[i * 2] = lines[i].vertindex; mPrimIndices[i * 2] = lines[i].vertindex;
mPrimIndices[i * 2 + 1] = lines[i].vertcount; mPrimIndices[i * 2 + 1] = lines[i].vertcount;
} }
if (NeedCap() && lines.Size() > 1 && planesused != 0)
{
screen->mVertexData->Map();
if (planesused & (1 << sector_t::floor))
{
auto verts = screen->mVertexData->AllocVertices(4);
auto ptr = verts.first;
ptr[0].Set((float)boundingBox.left, -32767.f, (float)boundingBox.top, 0, 0);
ptr[1].Set((float)boundingBox.right, -32767.f, (float)boundingBox.top, 0, 0);
ptr[2].Set((float)boundingBox.left, -32767.f, (float)boundingBox.bottom, 0, 0);
ptr[3].Set((float)boundingBox.right, -32767.f, (float)boundingBox.bottom, 0, 0);
mBottomCap = verts.second;
}
if (planesused & (1 << sector_t::ceiling))
{
auto verts = screen->mVertexData->AllocVertices(4);
auto ptr = verts.first;
ptr[0].Set((float)boundingBox.left, 32767.f, (float)boundingBox.top, 0, 0);
ptr[1].Set((float)boundingBox.right, 32767.f, (float)boundingBox.top, 0, 0);
ptr[2].Set((float)boundingBox.left, 32767.f, (float)boundingBox.bottom, 0, 0);
ptr[3].Set((float)boundingBox.right, 32767.f, (float)boundingBox.bottom, 0, 0);
mTopCap = verts.second;
}
screen->mVertexData->Unmap();
}
} }
for (unsigned int i = 0; i < mPrimIndices.Size(); i += 2) for (unsigned int i = 0; i < mPrimIndices.Size(); i += 2)
@ -196,26 +223,15 @@ void HWPortal::DrawPortalStencil(FRenderState &state, int pass)
// The cap's depth handling needs special treatment so that it won't block further portal caps. // The cap's depth handling needs special treatment so that it won't block further portal caps.
if (pass == STP_DepthRestore) state.SetDepthRange(1, 1); if (pass == STP_DepthRestore) state.SetDepthRange(1, 1);
if (planesused & (1 << sector_t::floor)) if (mBottomCap != ~0u)
{ {
auto verts = screen->mVertexData->AllocVertices(4); state.Draw(DT_TriangleStrip, mBottomCap, 4, false);
auto ptr = verts.first;
ptr[0].Set((float)boundingBox.left, -32767.f, (float)boundingBox.top, 0, 0);
ptr[1].Set((float)boundingBox.right, -32767.f, (float)boundingBox.top, 0, 0);
ptr[2].Set((float)boundingBox.left, -32767.f, (float)boundingBox.bottom, 0, 0);
ptr[3].Set((float)boundingBox.right, -32767.f, (float)boundingBox.bottom, 0, 0);
state.Draw(DT_TriangleStrip, verts.second, 4, false);
} }
if (planesused & (1 << sector_t::ceiling)) if (mTopCap != ~0u)
{ {
auto verts = screen->mVertexData->AllocVertices(4); state.Draw(DT_TriangleStrip, mTopCap, 4, false);
auto ptr = verts.first;
ptr[0].Set((float)boundingBox.left, 32767.f, (float)boundingBox.top, 0, 0);
ptr[1].Set((float)boundingBox.right, 32767.f, (float)boundingBox.top, 0, 0);
ptr[2].Set((float)boundingBox.left, 32767.f, (float)boundingBox.bottom, 0, 0);
ptr[3].Set((float)boundingBox.right, 32767.f, (float)boundingBox.bottom, 0, 0);
state.Draw(DT_TriangleStrip, verts.second, 4, false);
} }
if (pass == STP_DepthRestore) state.SetDepthRange(0, 1); if (pass == STP_DepthRestore) state.SetDepthRange(0, 1);
} }
} }

View file

@ -55,6 +55,7 @@ class HWPortal
ActorRenderFlags savedvisibility; ActorRenderFlags savedvisibility;
TArray<unsigned int> mPrimIndices; TArray<unsigned int> mPrimIndices;
unsigned int mTopCap = ~0u, mBottomCap = ~0u;
void DrawPortalStencil(FRenderState &state, int pass); void DrawPortalStencil(FRenderState &state, int pass);

View file

@ -128,70 +128,6 @@ void IHardwareTexture::Resize(int swidth, int sheight, int width, int height, un
} }
} }
//===========================================================================
//
//
//
//===========================================================================
float FTexCoordInfo::RowOffset(float rowoffset) const
{
float tscale = fabs(mTempScale.Y);
float scale = fabs(mScale.Y);
if (tscale == 1.f)
{
if (scale == 1.f || mWorldPanning) return rowoffset;
else return rowoffset / scale;
}
else
{
if (mWorldPanning) return rowoffset / tscale;
else return rowoffset / scale;
}
}
//===========================================================================
//
//
//
//===========================================================================
float FTexCoordInfo::TextureOffset(float textureoffset) const
{
float tscale = fabs(mTempScale.X);
float scale = fabs(mScale.X);
if (tscale == 1.f)
{
if (scale == 1.f || mWorldPanning) return textureoffset;
else return textureoffset / scale;
}
else
{
if (mWorldPanning) return textureoffset / tscale;
else return textureoffset / scale;
}
}
//===========================================================================
//
// Returns the size for which texture offset coordinates are used.
//
//===========================================================================
float FTexCoordInfo::TextureAdjustWidth() const
{
if (mWorldPanning)
{
float tscale = fabs(mTempScale.X);
if (tscale == 1.f) return (float)mRenderWidth;
else return mWidth / fabs(tscale);
}
else return (float)mWidth;
}
//=========================================================================== //===========================================================================
// //
// //
@ -522,50 +458,6 @@ void FMaterial::PrecacheList(SpriteHits &translations)
while(it.NextPair(pair)) screen->PrecacheMaterial(this, pair->Key); while(it.NextPair(pair)) screen->PrecacheMaterial(this, pair->Key);
} }
//===========================================================================
//
// Retrieve texture coordinate info for per-wall scaling
//
//===========================================================================
void FMaterial::GetTexCoordInfo(FTexCoordInfo *tci, float x, float y) const
{
if (x == 1.f)
{
tci->mRenderWidth = mRenderWidth;
tci->mScale.X = (float)tex->Scale.X;
tci->mTempScale.X = 1.f;
}
else
{
float scale_x = x * (float)tex->Scale.X;
tci->mRenderWidth = xs_CeilToInt(mWidth / scale_x);
tci->mScale.X = scale_x;
tci->mTempScale.X = x;
}
if (y == 1.f)
{
tci->mRenderHeight = mRenderHeight;
tci->mScale.Y = (float)tex->Scale.Y;
tci->mTempScale.Y = 1.f;
}
else
{
float scale_y = y * (float)tex->Scale.Y;
tci->mRenderHeight = xs_CeilToInt(mHeight / scale_y);
tci->mScale.Y = scale_y;
tci->mTempScale.Y = y;
}
if (tex->bHasCanvas)
{
tci->mScale.Y = -tci->mScale.Y;
tci->mRenderHeight = -tci->mRenderHeight;
}
tci->mWorldPanning = tex->bWorldPanning;
tci->mWidth = mWidth;
}
//=========================================================================== //===========================================================================
// //
// //

View file

@ -25,23 +25,6 @@ enum
}; };
struct FTexCoordInfo
{
int mRenderWidth;
int mRenderHeight;
int mWidth;
FVector2 mScale;
FVector2 mTempScale;
bool mWorldPanning;
float FloatToTexU(float v) const { return v / mRenderWidth; }
float FloatToTexV(float v) const { return v / mRenderHeight; }
float RowOffset(float ofs) const;
float TextureOffset(float ofs) const;
float TextureAdjustWidth() const;
};
//=========================================================================== //===========================================================================
// //
// this is the material class for OpenGL. // this is the material class for OpenGL.
@ -93,7 +76,7 @@ public:
} }
bool isMasked() const bool isMasked() const
{ {
return !!sourcetex->bMasked; return sourcetex->bMasked;
} }
bool isExpanded() const bool isExpanded() const
{ {
@ -130,7 +113,10 @@ public:
*r = mSpriteRect; *r = mSpriteRect;
} }
void GetTexCoordInfo(FTexCoordInfo *tci, float x, float y) const; void GetTexCoordInfo(FTexCoordInfo *tci, float x, float y) const
{
tci->GetFromTexture(tex, x, y);
}
void GetTexCoordInfo(FTexCoordInfo *tci, side_t *side, int texpos) const void GetTexCoordInfo(FTexCoordInfo *tci, side_t *side, int texpos) const
{ {

View file

@ -232,13 +232,12 @@ bool P_GetMidTexturePosition(const line_t *line, int sideno, double *ptextop, do
FTexture * tex= TexMan(texnum); FTexture * tex= TexMan(texnum);
if (!tex) return false; if (!tex) return false;
double totalscale = fabs(side->GetTextureYScale(side_t::mid)) * tex->GetScaleY(); FTexCoordInfo tci;
double y_offset = side->GetTextureYOffset(side_t::mid);
double textureheight = tex->GetHeight() / totalscale; // We only need the vertical positioning info here.
if (totalscale != 1. && !tex->bWorldPanning) tci.GetFromTexture(tex, 1., (float)side->GetTextureYScale(side_t::mid));
{ double y_offset = tci.RowOffset((float)side->GetTextureYOffset(side_t::mid));
y_offset /= totalscale; double textureheight = tci.mRenderHeight;
}
if(line->flags & ML_DONTPEGBOTTOM) if(line->flags & ML_DONTPEGBOTTOM)
{ {

View file

@ -2767,9 +2767,9 @@ void A_DoChase (AActor *actor, bool fastchase, FState *meleestate, FState *missi
//========================================================================== //==========================================================================
// [MC] Code is almost a duplicate of CanCollideWith but with changes to // [MC] Code is almost a duplicate of CanCollideWith but with changes to
// accommodate checking of just one actor. // accommodate checking of just one actor.
bool P_CanResurrect(AActor *tmthing, AActor *thing) bool P_CanResurrect(AActor *raiser, AActor *thing)
{ {
if (tmthing == nullptr) if (raiser == nullptr)
return false; return false;
static unsigned VIndex = ~0u; static unsigned VIndex = ~0u;
@ -2779,12 +2779,12 @@ bool P_CanResurrect(AActor *tmthing, AActor *thing)
assert(VIndex != ~0u); assert(VIndex != ~0u);
} }
VMValue params[3] = { tmthing, thing, false }; VMValue params[3] = { raiser, thing, false };
VMReturn ret; VMReturn ret;
int retval; int retval;
ret.IntAt(&retval); ret.IntAt(&retval);
auto clss = tmthing->GetClass(); auto clss = raiser->GetClass();
VMFunction *func = clss->Virtuals.Size() > VIndex ? clss->Virtuals[VIndex] : nullptr; VMFunction *func = clss->Virtuals.Size() > VIndex ? clss->Virtuals[VIndex] : nullptr;
if (func != nullptr) if (func != nullptr)
{ {
@ -2793,7 +2793,7 @@ bool P_CanResurrect(AActor *tmthing, AActor *thing)
} }
// Pointless to be running it again if it's just self. // Pointless to be running it again if it's just self.
if (thing == nullptr || thing == tmthing) if (thing == nullptr || thing == raiser)
return true; return true;
std::swap(params[0].a, params[1].a); std::swap(params[0].a, params[1].a);

View file

@ -463,7 +463,7 @@ bool P_Thing_Raise(AActor *thing, AActor *raiser, int nocheck)
return false; return false;
} }
if (!P_CanResurrect(thing, raiser)) if (!P_CanResurrect(raiser, thing))
return false; return false;
S_Sound (thing, CHAN_BODY, "vile/raise", 1, ATTN_IDLE); S_Sound (thing, CHAN_BODY, "vile/raise", 1, ATTN_IDLE);

View file

@ -1351,6 +1351,11 @@ bool FTexture::ProcessData(unsigned char * buffer, int w, int h, bool ispatch)
if (bMasked) if (bMasked)
{ {
bMasked = SmoothEdges(buffer, w, h); bMasked = SmoothEdges(buffer, w, h);
if (!bMasked)
{
auto stex = GetRedirect();
stex->bMasked = false; // also clear in the base texture if there is a redirection.
}
if (bMasked && !ispatch) FindHoles(buffer, w, h); if (bMasked && !ispatch) FindHoles(buffer, w, h);
} }
return true; return true;
@ -1543,3 +1548,119 @@ CCMD (printspans)
#endif #endif
//===========================================================================
//
// Coordinate helper.
// The only reason this is even needed is that many years ago someone
// was convinced that having per-texel panning on walls was a good idea.
// If it wasn't for this relatively useless feature the entire positioning
// code for wall textures could be a lot simpler.
//
//===========================================================================
//===========================================================================
//
//
//
//===========================================================================
float FTexCoordInfo::RowOffset(float rowoffset) const
{
float tscale = fabs(mTempScale.Y);
float scale = fabs(mScale.Y);
if (tscale == 1.f)
{
if (scale == 1.f || mWorldPanning) return rowoffset;
else return rowoffset / scale;
}
else
{
if (mWorldPanning) return rowoffset / tscale;
else return rowoffset / scale;
}
}
//===========================================================================
//
//
//
//===========================================================================
float FTexCoordInfo::TextureOffset(float textureoffset) const
{
float tscale = fabs(mTempScale.X);
float scale = fabs(mScale.X);
if (tscale == 1.f)
{
if (scale == 1.f || mWorldPanning) return textureoffset;
else return textureoffset / scale;
}
else
{
if (mWorldPanning) return textureoffset / tscale;
else return textureoffset / scale;
}
}
//===========================================================================
//
// Returns the size for which texture offset coordinates are used.
//
//===========================================================================
float FTexCoordInfo::TextureAdjustWidth() const
{
if (mWorldPanning)
{
float tscale = fabs(mTempScale.X);
if (tscale == 1.f) return (float)mRenderWidth;
else return mWidth / fabs(tscale);
}
else return (float)mWidth;
}
//===========================================================================
//
// Retrieve texture coordinate info for per-wall scaling
//
//===========================================================================
void FTexCoordInfo::GetFromTexture(FTexture *tex, float x, float y)
{
if (x == 1.f)
{
mRenderWidth = tex->GetScaledWidth();
mScale.X = (float)tex->Scale.X;
mTempScale.X = 1.f;
}
else
{
float scale_x = x * (float)tex->Scale.X;
mRenderWidth = xs_CeilToInt(tex->GetWidth() / scale_x);
mScale.X = scale_x;
mTempScale.X = x;
}
if (y == 1.f)
{
mRenderHeight = tex->GetScaledHeight();
mScale.Y = (float)tex->Scale.Y;
mTempScale.Y = 1.f;
}
else
{
float scale_y = y * (float)tex->Scale.Y;
mRenderHeight = xs_CeilToInt(tex->GetHeight() / scale_y);
mScale.Y = scale_y;
mTempScale.Y = y;
}
if (tex->bHasCanvas)
{
mScale.Y = -mScale.Y;
mRenderHeight = -mRenderHeight;
}
mWorldPanning = tex->bWorldPanning;
mWidth = tex->GetWidth();
}

View file

@ -211,6 +211,7 @@ enum FTextureFormat : uint32_t
TEX_Count TEX_Count
}; };
// Base texture class // Base texture class
class FTexture class FTexture
{ {
@ -802,6 +803,24 @@ public:
extern FTextureManager TexMan; extern FTextureManager TexMan;
struct FTexCoordInfo
{
int mRenderWidth;
int mRenderHeight;
int mWidth;
FVector2 mScale;
FVector2 mTempScale;
bool mWorldPanning;
float FloatToTexU(float v) const { return v / mRenderWidth; }
float FloatToTexV(float v) const { return v / mRenderHeight; }
float RowOffset(float ofs) const;
float TextureOffset(float ofs) const;
float TextureAdjustWidth() const;
void GetFromTexture(FTexture *tex, float x, float y);
};
#endif #endif

View file

@ -244,11 +244,18 @@ class PhosphorousFire : Actor
override int DoSpecialDamage (Actor target, int damage, Name damagetype) override int DoSpecialDamage (Actor target, int damage, Name damagetype)
{ {
// This may look a bit weird but is the same as in SVE:
// For the bosses, only their regular 0.5 damage factor for fire applies.
let firedamage = target.ApplyDamageFactor('Fire', damage);
if (firedamage != damage) return damage; // if the target has a factor, do nothing here. The factor will be applied elsewhere.
// For everything else damage is halved, for robots quartered.
damage >>= 1;
if (target.bNoBlood) if (target.bNoBlood)
{ {
return damage / 2; damage >>= 1;
} }
return Super.DoSpecialDamage (target, damage, damagetype); return damage;
} }
// This function is mostly redundant and only kept in case some mod references it. // This function is mostly redundant and only kept in case some mod references it.