mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2025-01-18 22:51:39 +00:00
- more options for Doom 64 style gradients on walls:
* Colors can npw be defined per sidedef, not only per sector. * Gradients can be selectively disabled or vertically flipped per wall tier. * Gradients can be clamped to their respective tier, i.e top and bottom of the tier, not the front sector defines where it starts. The per-wall colors are implemented for hardware and softpoly renderer only, but not for the classic software renderer, because its code is far too scattered to do this efficiently. # Conflicts: # src/hwrenderer/scene/hw_renderstate.h # src/hwrenderer/scene/hw_walls.cpp # Conflicts: # src/gl/scene/gl_walls_draw.cpp
This commit is contained in:
parent
e00db66432
commit
8368331481
15 changed files with 390 additions and 135 deletions
|
@ -154,31 +154,52 @@ Note: All <bool> fields default to false unless mentioned otherwise.
|
||||||
|
|
||||||
sidedef
|
sidedef
|
||||||
{
|
{
|
||||||
scalex_top = <float>; // X scale for upper texture, Default = 1.0.
|
scalex_top = <float>; // X scale for upper texture, Default = 1.0.
|
||||||
scaley_top = <float>; // y scale for upper texture, Default = 1.0.
|
scaley_top = <float>; // y scale for upper texture, Default = 1.0.
|
||||||
scalex_mid = <float>; // X scale for mid texture, Default = 1.0.
|
scalex_mid = <float>; // X scale for mid texture, Default = 1.0.
|
||||||
scaley_mid = <float>; // y scale for mid texture, Default = 1.0.
|
scaley_mid = <float>; // y scale for mid texture, Default = 1.0.
|
||||||
scalex_bottom = <float>; // X scale for lower texture, Default = 1.0.
|
scalex_bottom = <float>; // X scale for lower texture, Default = 1.0.
|
||||||
scaley_bottom = <float>; // y scale for lower texture, Default = 1.0.
|
scaley_bottom = <float>; // y scale for lower texture, Default = 1.0.
|
||||||
offsetx_top = <float>; // X offset for upper texture, Default = 0.0.
|
offsetx_top = <float>; // X offset for upper texture, Default = 0.0.
|
||||||
offsety_top = <float>; // y offset for upper texture, Default = 0.0.
|
offsety_top = <float>; // y offset for upper texture, Default = 0.0.
|
||||||
offsetx_mid = <float>; // X offset for mid texture, Default = 0.0.
|
offsetx_mid = <float>; // X offset for mid texture, Default = 0.0.
|
||||||
offsety_mid = <float>; // y offset for mid texture, Default = 0.0.
|
offsety_mid = <float>; // y offset for mid texture, Default = 0.0.
|
||||||
offsetx_bottom = <float>; // X offset for lower texture, Default = 0.0.
|
offsetx_bottom = <float>; // X offset for lower texture, Default = 0.0.
|
||||||
offsety_bottom = <float>; // y offset for lower texture, Default = 0.0.
|
offsety_bottom = <float>; // y offset for lower texture, Default = 0.0.
|
||||||
// When global texture offsets are used they will
|
// When global texture offsets are used they will
|
||||||
// be added on top of these values.
|
// be added on top of these values.
|
||||||
light = <integer>; // This side's light level. Default is 0.
|
light = <integer>; // This side's light level. Default is 0.
|
||||||
lightabsolute = <bool>; // true = 'light' is an absolute value. Default is
|
lightabsolute = <bool>; // true = 'light' is an absolute value. Default is
|
||||||
// relative to the owning sector's light level.
|
// relative to the owning sector's light level.
|
||||||
lightfog = <bool>; // true = This side's relative lighting is used even in
|
lightfog = <bool>; // true = This side's relative lighting is used even in
|
||||||
// foggy sectors. Default is to disable relative
|
// foggy sectors. Default is to disable relative
|
||||||
// lighting in foggy sectors.
|
// lighting in foggy sectors.
|
||||||
nofakecontrast = <bool>; // Disables use of fake contrast on this sidedef.
|
nofakecontrast = <bool>; // Disables use of fake contrast on this sidedef.
|
||||||
smoothlighting = <bool>; // Use smooth fake contrast.
|
smoothlighting = <bool>; // Use smooth fake contrast.
|
||||||
clipmidtex = <bool>; // Side's mid textures are clipped to floor and ceiling.
|
clipmidtex = <bool>; // Side's mid textures are clipped to floor and ceiling.
|
||||||
wrapmidtex = <bool>; // Side's mid textures are wrapped.
|
wrapmidtex = <bool>; // Side's mid textures are wrapped.
|
||||||
nodecals = <bool>; // Disables decals on the sidedef.
|
nodecals = <bool>; // Disables decals on the sidedef.
|
||||||
|
|
||||||
|
nogradient_top = <bool>; // disables color gradient on upper tier. (Hardware rendering only.)
|
||||||
|
flipgradient_top = <bool>; // flips gradient colors on upper tier. (Hardware rendering only.)
|
||||||
|
clampgradient_top = <bool>; // clamps gradient on upper tier to actual bounds (default is the entire front sector height, hardware rendering only.)
|
||||||
|
useowncolors_top = <bool>; // Set to 1 to use the colors set in the sidedef. Default is using the colors from the owning sector.
|
||||||
|
uppercolor_top = <int>; // Material color of the top of the upper tier.
|
||||||
|
lowercolor_top = <int>; // Material color of the bottom of the upper tier. (Hardware rendering only.)
|
||||||
|
|
||||||
|
nogradient_mid = <bool>; // disables color gradient on middle tier. (Hardware rendering only.)
|
||||||
|
flipgradient_mid = <bool>; // flips gradient colors on middle tier. (Hardware rendering only.)
|
||||||
|
clampgradient_mid = <bool>; // clamps gradient on middle tier to actual bounds (default is the entire front sector height, hardware rendering only.)
|
||||||
|
useowncolors_mid = <bool>; // Set to 1 to use the colors set in the sidedef. Default is using the colors from the owning sector.
|
||||||
|
uppercolor_mid = <int>; // Material color of the top of the middle tier.
|
||||||
|
lowercolor_mid = <int>; // Material color of the bottom of the middle tier. (Hardware rendering only.)
|
||||||
|
|
||||||
|
nogradient_bottom = <bool>; // disables color gradient on lower tier. (Hardware rendering only.)
|
||||||
|
flipgradient_bottom = <bool>; // flips gradient colors on lower tier. (Hardware rendering only.)
|
||||||
|
clampgradient_bottom = <bool>;// clamps gradient on lower tier to actual bounds (default is the entire front sector height, hardware rendering only.)
|
||||||
|
useowncolors_bottom = <bool>; // Set to 1 to use the colors set in the sidedef. Default is using the colors from the owning sector.
|
||||||
|
uppercolor_bottom = <int>; // Material color of the top of the lower tier.
|
||||||
|
lowercolor_bottom = <int>; // Material color of the bottom of the lower tier. (Hardware rendering only.)
|
||||||
}
|
}
|
||||||
|
|
||||||
sector
|
sector
|
||||||
|
|
|
@ -68,7 +68,7 @@ static void matrixToGL(const VSMatrix &mat, int loc)
|
||||||
void FRenderState::Reset()
|
void FRenderState::Reset()
|
||||||
{
|
{
|
||||||
mTextureEnabled = true;
|
mTextureEnabled = true;
|
||||||
mClipLineEnabled = mSplitEnabled = mBrightmapEnabled = mFogEnabled = mGlowEnabled = false;
|
mClipLineEnabled = mSplitEnabled = mGradientEnabled = mBrightmapEnabled = mFogEnabled = mGlowEnabled = false;
|
||||||
mColorMask[0] = mColorMask[1] = mColorMask[2] = mColorMask[3] = true;
|
mColorMask[0] = mColorMask[1] = mColorMask[2] = mColorMask[3] = true;
|
||||||
currentColorMask[0] = currentColorMask[1] = currentColorMask[2] = currentColorMask[3] = true;
|
currentColorMask[0] = currentColorMask[1] = currentColorMask[2] = currentColorMask[3] = true;
|
||||||
mFogColor.d = -1;
|
mFogColor.d = -1;
|
||||||
|
@ -109,6 +109,8 @@ void FRenderState::Reset()
|
||||||
mGlowBottom.Set(0.0f, 0.0f, 0.0f, 0.0f);
|
mGlowBottom.Set(0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
mGlowTopPlane.Set(0.0f, 0.0f, 0.0f, 0.0f);
|
mGlowTopPlane.Set(0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
mGlowBottomPlane.Set(0.0f, 0.0f, 0.0f, 0.0f);
|
mGlowBottomPlane.Set(0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
|
mGradientTopPlane.Set(0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
|
mGradientBottomPlane.Set(0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
mSplitTopPlane.Set(0.0f, 0.0f, 0.0f, 0.0f);
|
mSplitTopPlane.Set(0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
mSplitBottomPlane.Set(0.0f, 0.0f, 0.0f, 0.0f);
|
mSplitBottomPlane.Set(0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
mClipLine.Set(0.0f, 0.0f, 0.0f, 0.0f);
|
mClipLine.Set(0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
|
|
|
@ -75,6 +75,7 @@ class FRenderState
|
||||||
bool mTextureEnabled;
|
bool mTextureEnabled;
|
||||||
bool mFogEnabled;
|
bool mFogEnabled;
|
||||||
bool mGlowEnabled;
|
bool mGlowEnabled;
|
||||||
|
bool mGradientEnabled;
|
||||||
bool mSplitEnabled;
|
bool mSplitEnabled;
|
||||||
bool mClipLineEnabled;
|
bool mClipLineEnabled;
|
||||||
bool mBrightmapEnabled;
|
bool mBrightmapEnabled;
|
||||||
|
@ -103,6 +104,7 @@ class FRenderState
|
||||||
FStateVec4 mCameraPos;
|
FStateVec4 mCameraPos;
|
||||||
FStateVec4 mGlowTop, mGlowBottom;
|
FStateVec4 mGlowTop, mGlowBottom;
|
||||||
FStateVec4 mGlowTopPlane, mGlowBottomPlane;
|
FStateVec4 mGlowTopPlane, mGlowBottomPlane;
|
||||||
|
FStateVec4 mGradientTopPlane, mGradientBottomPlane;
|
||||||
FStateVec4 mSplitTopPlane, mSplitBottomPlane;
|
FStateVec4 mSplitTopPlane, mSplitBottomPlane;
|
||||||
FStateVec4 mClipLine;
|
FStateVec4 mClipLine;
|
||||||
PalEntry mFogColor;
|
PalEntry mFogColor;
|
||||||
|
@ -285,6 +287,11 @@ public:
|
||||||
mGlowEnabled = on;
|
mGlowEnabled = on;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EnableGradient(bool on)
|
||||||
|
{
|
||||||
|
mGradientEnabled = on;
|
||||||
|
}
|
||||||
|
|
||||||
void EnableSplit(bool on)
|
void EnableSplit(bool on)
|
||||||
{
|
{
|
||||||
if (!(gl.flags & RFL_NO_CLIP_PLANES))
|
if (!(gl.flags & RFL_NO_CLIP_PLANES))
|
||||||
|
@ -369,6 +376,14 @@ public:
|
||||||
mGlowBottomPlane.Set(bn.X, bn.Y, 1. / bn.Z, bottom.fD());
|
mGlowBottomPlane.Set(bn.X, bn.Y, 1. / bn.Z, bottom.fD());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetGradientPlanes(const secplane_t &top, const secplane_t &bottom)
|
||||||
|
{
|
||||||
|
DVector3 tn = top.Normal();
|
||||||
|
DVector3 bn = bottom.Normal();
|
||||||
|
mGradientTopPlane.Set(tn.X, tn.Y, 1. / tn.Z, top.fD());
|
||||||
|
mGradientBottomPlane.Set(bn.X, bn.Y, 1. / bn.Z, bottom.fD());
|
||||||
|
}
|
||||||
|
|
||||||
void SetSplitPlanes(const secplane_t &top, const secplane_t &bottom)
|
void SetSplitPlanes(const secplane_t &top, const secplane_t &bottom)
|
||||||
{
|
{
|
||||||
DVector3 tn = top.Normal();
|
DVector3 tn = top.Normal();
|
||||||
|
|
|
@ -324,6 +324,20 @@ void GLWall::RenderMirrorSurface()
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
|
static const uint8_t renderwalltotier[] =
|
||||||
|
{
|
||||||
|
side_t::none,
|
||||||
|
side_t::top,
|
||||||
|
side_t::mid,
|
||||||
|
side_t::mid,
|
||||||
|
side_t::bottom,
|
||||||
|
side_t::none,
|
||||||
|
side_t::none,
|
||||||
|
side_t::mid,
|
||||||
|
side_t::none,
|
||||||
|
side_t::mid,
|
||||||
|
};
|
||||||
|
|
||||||
void GLWall::RenderTextured(int rflags)
|
void GLWall::RenderTextured(int rflags)
|
||||||
{
|
{
|
||||||
int tmode = gl_RenderState.GetTextureMode();
|
int tmode = gl_RenderState.GetTextureMode();
|
||||||
|
@ -333,8 +347,8 @@ void GLWall::RenderTextured(int rflags)
|
||||||
{
|
{
|
||||||
gl_RenderState.EnableGlow(true);
|
gl_RenderState.EnableGlow(true);
|
||||||
gl_RenderState.SetGlowParams(topglowcolor, bottomglowcolor);
|
gl_RenderState.SetGlowParams(topglowcolor, bottomglowcolor);
|
||||||
|
gl_RenderState.SetGlowPlanes(frontsector->ceilingplane, frontsector->floorplane);
|
||||||
}
|
}
|
||||||
gl_RenderState.SetGlowPlanes(frontsector->ceilingplane, frontsector->floorplane);
|
|
||||||
gl_RenderState.SetMaterial(gltexture, flags & 3, 0, -1, false);
|
gl_RenderState.SetMaterial(gltexture, flags & 3, 0, -1, false);
|
||||||
|
|
||||||
if (type == RENDERWALL_M2SNF)
|
if (type == RENDERWALL_M2SNF)
|
||||||
|
@ -345,11 +359,44 @@ void GLWall::RenderTextured(int rflags)
|
||||||
}
|
}
|
||||||
mDrawer->SetFog(255, 0, NULL, false);
|
mDrawer->SetFog(255, 0, NULL, false);
|
||||||
}
|
}
|
||||||
gl_RenderState.SetObjectColor(seg->frontsector->SpecialColors[sector_t::walltop] | 0xff000000);
|
if (type != RENDERWALL_COLOR)
|
||||||
gl_RenderState.SetObjectColor2(seg->frontsector->SpecialColors[sector_t::wallbottom] | 0xff000000);
|
{
|
||||||
|
auto side = seg->sidedef;
|
||||||
|
auto tierndx = renderwalltotier[type];
|
||||||
|
auto &tier = side->textures[tierndx];
|
||||||
|
PalEntry color1 = side->GetSpecialColor(tierndx, side_t::walltop, frontsector);
|
||||||
|
PalEntry color2 = side->GetSpecialColor(tierndx, side_t::wallbottom, frontsector);
|
||||||
|
gl_RenderState.SetObjectColor(color1);
|
||||||
|
gl_RenderState.SetObjectColor2(color2);
|
||||||
|
if (color1 != color2)
|
||||||
|
{
|
||||||
|
// Do gradient setup only if there actually is a gradient.
|
||||||
|
|
||||||
|
gl_RenderState.EnableGradient(true);
|
||||||
|
if ((tier.flags & side_t::part::ClampGradient) && backsector)
|
||||||
|
{
|
||||||
|
if (tierndx == side_t::top)
|
||||||
|
{
|
||||||
|
gl_RenderState.SetGradientPlanes(frontsector->ceilingplane, backsector->ceilingplane);
|
||||||
|
}
|
||||||
|
else if (tierndx == side_t::mid)
|
||||||
|
{
|
||||||
|
gl_RenderState.SetGradientPlanes(backsector->ceilingplane, backsector->floorplane);
|
||||||
|
}
|
||||||
|
else // side_t::bottom:
|
||||||
|
{
|
||||||
|
gl_RenderState.SetGradientPlanes(backsector->floorplane, frontsector->floorplane);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gl_RenderState.SetGradientPlanes(frontsector->ceilingplane, frontsector->floorplane);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
float absalpha = fabsf(alpha);
|
float absalpha = fabsf(alpha);
|
||||||
if (lightlist == NULL)
|
if (lightlist == nullptr)
|
||||||
{
|
{
|
||||||
if (type != RENDERWALL_M2SNF) mDrawer->SetFog(lightlevel, rel, &Colormap, RenderStyle == STYLE_Add);
|
if (type != RENDERWALL_M2SNF) mDrawer->SetFog(lightlevel, rel, &Colormap, RenderStyle == STYLE_Add);
|
||||||
mDrawer->SetColor(lightlevel, rel, Colormap, absalpha);
|
mDrawer->SetColor(lightlevel, rel, Colormap, absalpha);
|
||||||
|
@ -368,7 +415,7 @@ void GLWall::RenderTextured(int rflags)
|
||||||
|
|
||||||
if (low1 < ztop[0] || low2 < ztop[1])
|
if (low1 < ztop[0] || low2 < ztop[1])
|
||||||
{
|
{
|
||||||
int thisll = (*lightlist)[i].caster != NULL ? gl_ClampLight(*(*lightlist)[i].p_lightlevel) : lightlevel;
|
int thisll = (*lightlist)[i].caster != nullptr ? gl_ClampLight(*(*lightlist)[i].p_lightlevel) : lightlevel;
|
||||||
FColormap thiscm;
|
FColormap thiscm;
|
||||||
thiscm.FadeColor = Colormap.FadeColor;
|
thiscm.FadeColor = Colormap.FadeColor;
|
||||||
thiscm.FogDensity = Colormap.FogDensity;
|
thiscm.FogDensity = Colormap.FogDensity;
|
||||||
|
@ -387,6 +434,7 @@ void GLWall::RenderTextured(int rflags)
|
||||||
gl_RenderState.SetObjectColor2(0);
|
gl_RenderState.SetObjectColor2(0);
|
||||||
gl_RenderState.SetTextureMode(tmode);
|
gl_RenderState.SetTextureMode(tmode);
|
||||||
gl_RenderState.EnableGlow(false);
|
gl_RenderState.EnableGlow(false);
|
||||||
|
gl_RenderState.EnableGradient(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
|
@ -173,6 +173,9 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
|
||||||
i_data += "uniform vec4 uGlowBottomPlane;\n";
|
i_data += "uniform vec4 uGlowBottomPlane;\n";
|
||||||
i_data += "uniform vec4 uGlowBottomColor;\n";
|
i_data += "uniform vec4 uGlowBottomColor;\n";
|
||||||
|
|
||||||
|
i_data += "uniform vec4 uGradientTopPlane;\n";
|
||||||
|
i_data += "uniform vec4 uGradientBottomPlane;\n";
|
||||||
|
|
||||||
i_data += "uniform vec4 uSplitTopPlane;\n";
|
i_data += "uniform vec4 uSplitTopPlane;\n";
|
||||||
i_data += "uniform vec4 uSplitBottomPlane;\n";
|
i_data += "uniform vec4 uSplitBottomPlane;\n";
|
||||||
|
|
||||||
|
@ -461,6 +464,8 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
|
||||||
muGlowTopColor.Init(hShader, "uGlowTopColor");
|
muGlowTopColor.Init(hShader, "uGlowTopColor");
|
||||||
muGlowBottomPlane.Init(hShader, "uGlowBottomPlane");
|
muGlowBottomPlane.Init(hShader, "uGlowBottomPlane");
|
||||||
muGlowTopPlane.Init(hShader, "uGlowTopPlane");
|
muGlowTopPlane.Init(hShader, "uGlowTopPlane");
|
||||||
|
muGradientBottomPlane.Init(hShader, "uGradientBottomPlane");
|
||||||
|
muGradientTopPlane.Init(hShader, "uGradientTopPlane");
|
||||||
muSplitBottomPlane.Init(hShader, "uSplitBottomPlane");
|
muSplitBottomPlane.Init(hShader, "uSplitBottomPlane");
|
||||||
muSplitTopPlane.Init(hShader, "uSplitTopPlane");
|
muSplitTopPlane.Init(hShader, "uSplitTopPlane");
|
||||||
muClipLine.Init(hShader, "uClipLine");
|
muClipLine.Init(hShader, "uClipLine");
|
||||||
|
|
|
@ -277,6 +277,8 @@ class FShader
|
||||||
FUniform4f muGlowTopColor;
|
FUniform4f muGlowTopColor;
|
||||||
FUniform4f muGlowBottomPlane;
|
FUniform4f muGlowBottomPlane;
|
||||||
FUniform4f muGlowTopPlane;
|
FUniform4f muGlowTopPlane;
|
||||||
|
FUniform4f muGradientBottomPlane;
|
||||||
|
FUniform4f muGradientTopPlane;
|
||||||
FUniform4f muSplitBottomPlane;
|
FUniform4f muSplitBottomPlane;
|
||||||
FUniform4f muSplitTopPlane;
|
FUniform4f muSplitTopPlane;
|
||||||
FUniform4f muClipLine;
|
FUniform4f muClipLine;
|
||||||
|
@ -303,6 +305,7 @@ public:
|
||||||
int fakevb_index;
|
int fakevb_index;
|
||||||
private:
|
private:
|
||||||
int currentglowstate = 0;
|
int currentglowstate = 0;
|
||||||
|
int currentgradientstate = 0;
|
||||||
int currentsplitstate = 0;
|
int currentsplitstate = 0;
|
||||||
int currentcliplinestate = 0;
|
int currentcliplinestate = 0;
|
||||||
int currentfixedcolormap = 0;
|
int currentfixedcolormap = 0;
|
||||||
|
|
|
@ -630,6 +630,26 @@ xx(hidden)
|
||||||
xx(blocksight)
|
xx(blocksight)
|
||||||
xx(blockhitscan)
|
xx(blockhitscan)
|
||||||
|
|
||||||
|
xx(nogradient_top)
|
||||||
|
xx(flipgradient_top)
|
||||||
|
xx(clampgradient_top)
|
||||||
|
xx(useowncolors_top)
|
||||||
|
xx(uppercolor_top)
|
||||||
|
xx(lowercolor_top)
|
||||||
|
xx(nogradient_mid)
|
||||||
|
xx(flipgradient_mid)
|
||||||
|
xx(clampgradient_mid)
|
||||||
|
xx(useowncolors_mid)
|
||||||
|
xx(uppercolor_mid)
|
||||||
|
xx(lowercolor_mid)
|
||||||
|
xx(nogradient_bottom)
|
||||||
|
xx(flipgradient_bottom)
|
||||||
|
xx(clampgradient_bottom)
|
||||||
|
xx(useowncolors_bottom)
|
||||||
|
xx(uppercolor_bottom)
|
||||||
|
xx(lowercolor_bottom)
|
||||||
|
|
||||||
|
|
||||||
xx(Renderstyle)
|
xx(Renderstyle)
|
||||||
|
|
||||||
xx(ceilingplane_a)
|
xx(ceilingplane_a)
|
||||||
|
|
|
@ -113,6 +113,9 @@ FSerializer &Serialize(FSerializer &arc, const char *key, side_t::part &part, si
|
||||||
("yscale", part.yScale, def->yScale)
|
("yscale", part.yScale, def->yScale)
|
||||||
("texture", part.texture, def->texture)
|
("texture", part.texture, def->texture)
|
||||||
("interpolation", part.interpolation)
|
("interpolation", part.interpolation)
|
||||||
|
("flags", part.flags, def->flags)
|
||||||
|
("color1", part.SpecialColors[0], def->SpecialColors[0])
|
||||||
|
("color2", part.SpecialColors[1], def->SpecialColors[1])
|
||||||
.EndObject();
|
.EndObject();
|
||||||
}
|
}
|
||||||
return arc;
|
return arc;
|
||||||
|
|
|
@ -879,17 +879,6 @@ DEFINE_ACTION_FUNCTION(_Sector, SetFade)
|
||||||
//
|
//
|
||||||
//=====================================================================================
|
//=====================================================================================
|
||||||
|
|
||||||
void sector_t::SetSpecialColor(int slot, int r, int g, int b)
|
|
||||||
{
|
|
||||||
SpecialColors[slot] = PalEntry(255, r, g, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sector_t::SetSpecialColor(int slot, PalEntry rgb)
|
|
||||||
{
|
|
||||||
rgb.a = 255;
|
|
||||||
SpecialColors[slot] = rgb;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION(_Sector, SetSpecialColor)
|
DEFINE_ACTION_FUNCTION(_Sector, SetSpecialColor)
|
||||||
{
|
{
|
||||||
PARAM_SELF_STRUCT_PROLOGUE(sector_t);
|
PARAM_SELF_STRUCT_PROLOGUE(sector_t);
|
||||||
|
|
170
src/p_setup.cpp
170
src/p_setup.cpp
|
@ -3608,7 +3608,7 @@ void P_FreeExtraLevelData()
|
||||||
//
|
//
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
void P_SetupLevel (const char *lumpname, int position, bool newGame)
|
void P_SetupLevel(const char *lumpname, int position, bool newGame)
|
||||||
{
|
{
|
||||||
cycle_t times[20];
|
cycle_t times[20];
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -3638,7 +3638,7 @@ void P_SetupLevel (const char *lumpname, int position, bool newGame)
|
||||||
level.SetMusicVolume(level.MusicVolume);
|
level.SetMusicVolume(level.MusicVolume);
|
||||||
for (i = 0; i < MAXPLAYERS; ++i)
|
for (i = 0; i < MAXPLAYERS; ++i)
|
||||||
{
|
{
|
||||||
players[i].killcount = players[i].secretcount
|
players[i].killcount = players[i].secretcount
|
||||||
= players[i].itemcount = 0;
|
= players[i].itemcount = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3659,16 +3659,16 @@ void P_SetupLevel (const char *lumpname, int position, bool newGame)
|
||||||
translationtables[TRANSLATION_LevelScripted].Clear();
|
translationtables[TRANSLATION_LevelScripted].Clear();
|
||||||
|
|
||||||
// Initial height of PointOfView will be set by player think.
|
// Initial height of PointOfView will be set by player think.
|
||||||
players[consoleplayer].viewz = NO_VALUE;
|
players[consoleplayer].viewz = NO_VALUE;
|
||||||
|
|
||||||
// Make sure all sounds are stopped before Z_FreeTags.
|
// Make sure all sounds are stopped before Z_FreeTags.
|
||||||
S_Start ();
|
S_Start();
|
||||||
|
|
||||||
// [RH] clear out the mid-screen message
|
// [RH] clear out the mid-screen message
|
||||||
C_MidPrint (NULL, NULL);
|
C_MidPrint(NULL, NULL);
|
||||||
|
|
||||||
// Free all level data from the previous map
|
// Free all level data from the previous map
|
||||||
P_FreeLevelData ();
|
P_FreeLevelData();
|
||||||
|
|
||||||
MapData *map = P_OpenMapData(lumpname, true);
|
MapData *map = P_OpenMapData(lumpname, true);
|
||||||
if (map == NULL)
|
if (map == NULL)
|
||||||
|
@ -3700,7 +3700,7 @@ void P_SetupLevel (const char *lumpname, int position, bool newGame)
|
||||||
uint8_t *mapdata = new uint8_t[map->Size(0)];
|
uint8_t *mapdata = new uint8_t[map->Size(0)];
|
||||||
map->Read(0, mapdata);
|
map->Read(0, mapdata);
|
||||||
times[0].Clock();
|
times[0].Clock();
|
||||||
buildmap = P_LoadBuildMap (mapdata, map->Size(0), &buildthings, &numbuildthings);
|
buildmap = P_LoadBuildMap(mapdata, map->Size(0), &buildthings, &numbuildthings);
|
||||||
times[0].Unclock();
|
times[0].Unclock();
|
||||||
delete[] mapdata;
|
delete[] mapdata;
|
||||||
}
|
}
|
||||||
|
@ -3712,10 +3712,10 @@ void P_SetupLevel (const char *lumpname, int position, bool newGame)
|
||||||
ForceNodeBuild = gennodes;
|
ForceNodeBuild = gennodes;
|
||||||
|
|
||||||
// [RH] Load in the BEHAVIOR lump
|
// [RH] Load in the BEHAVIOR lump
|
||||||
FBehavior::StaticUnloadModules ();
|
FBehavior::StaticUnloadModules();
|
||||||
if (map->HasBehavior)
|
if (map->HasBehavior)
|
||||||
{
|
{
|
||||||
P_LoadBehavior (map);
|
P_LoadBehavior(map);
|
||||||
level.maptype = MAPTYPE_HEXEN;
|
level.maptype = MAPTYPE_HEXEN;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -3732,7 +3732,7 @@ void P_SetupLevel (const char *lumpname, int position, bool newGame)
|
||||||
{
|
{
|
||||||
// Has the user overridden the game's default translator with a commandline parameter?
|
// Has the user overridden the game's default translator with a commandline parameter?
|
||||||
translator = Args->CheckValue("-xlat");
|
translator = Args->CheckValue("-xlat");
|
||||||
if (translator == NULL)
|
if (translator == NULL)
|
||||||
{
|
{
|
||||||
// Use the game's default.
|
// Use the game's default.
|
||||||
translator = gameinfo.translator.GetChars();
|
translator = gameinfo.translator.GetChars();
|
||||||
|
@ -3772,25 +3772,25 @@ void P_SetupLevel (const char *lumpname, int position, bool newGame)
|
||||||
level.flags2 |= LEVEL2_DUMMYSWITCHES;
|
level.flags2 |= LEVEL2_DUMMYSWITCHES;
|
||||||
}
|
}
|
||||||
|
|
||||||
FBehavior::StaticLoadDefaultModules ();
|
FBehavior::StaticLoadDefaultModules();
|
||||||
#ifndef NO_EDATA
|
#ifndef NO_EDATA
|
||||||
LoadMapinfoACSLump();
|
LoadMapinfoACSLump();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
P_LoadStrifeConversations (map, lumpname);
|
P_LoadStrifeConversations(map, lumpname);
|
||||||
|
|
||||||
FMissingTextureTracker missingtex;
|
FMissingTextureTracker missingtex;
|
||||||
|
|
||||||
if (!map->isText)
|
if (!map->isText)
|
||||||
{
|
{
|
||||||
times[0].Clock();
|
times[0].Clock();
|
||||||
P_LoadVertexes (map);
|
P_LoadVertexes(map);
|
||||||
times[0].Unclock();
|
times[0].Unclock();
|
||||||
|
|
||||||
// Check for maps without any BSP data at all (e.g. SLIGE)
|
// Check for maps without any BSP data at all (e.g. SLIGE)
|
||||||
times[1].Clock();
|
times[1].Clock();
|
||||||
P_LoadSectors (map, missingtex);
|
P_LoadSectors(map, missingtex);
|
||||||
times[1].Unclock();
|
times[1].Unclock();
|
||||||
|
|
||||||
times[2].Clock();
|
times[2].Clock();
|
||||||
|
@ -3798,23 +3798,23 @@ void P_SetupLevel (const char *lumpname, int position, bool newGame)
|
||||||
|
|
||||||
times[3].Clock();
|
times[3].Clock();
|
||||||
if (!map->HasBehavior)
|
if (!map->HasBehavior)
|
||||||
P_LoadLineDefs (map);
|
P_LoadLineDefs(map);
|
||||||
else
|
else
|
||||||
P_LoadLineDefs2 (map); // [RH] Load Hexen-style linedefs
|
P_LoadLineDefs2(map); // [RH] Load Hexen-style linedefs
|
||||||
times[3].Unclock();
|
times[3].Unclock();
|
||||||
|
|
||||||
times[4].Clock();
|
times[4].Clock();
|
||||||
P_LoadSideDefs2 (map, missingtex);
|
P_LoadSideDefs2(map, missingtex);
|
||||||
times[4].Unclock();
|
times[4].Unclock();
|
||||||
|
|
||||||
times[5].Clock();
|
times[5].Clock();
|
||||||
P_FinishLoadingLineDefs ();
|
P_FinishLoadingLineDefs();
|
||||||
times[5].Unclock();
|
times[5].Unclock();
|
||||||
|
|
||||||
if (!map->HasBehavior)
|
if (!map->HasBehavior)
|
||||||
P_LoadThings (map);
|
P_LoadThings(map);
|
||||||
else
|
else
|
||||||
P_LoadThings2 (map); // [RH] Load Hexen-style things
|
P_LoadThings2(map); // [RH] Load Hexen-style things
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -3826,7 +3826,7 @@ void P_SetupLevel (const char *lumpname, int position, bool newGame)
|
||||||
SetCompatibilityParams(checksum);
|
SetCompatibilityParams(checksum);
|
||||||
|
|
||||||
times[6].Clock();
|
times[6].Clock();
|
||||||
P_LoopSidedefs (true);
|
P_LoopSidedefs(true);
|
||||||
times[6].Unclock();
|
times[6].Unclock();
|
||||||
|
|
||||||
linemap.Clear();
|
linemap.Clear();
|
||||||
|
@ -3845,36 +3845,36 @@ void P_SetupLevel (const char *lumpname, int position, bool newGame)
|
||||||
{
|
{
|
||||||
// Check for compressed nodes first, then uncompressed nodes
|
// Check for compressed nodes first, then uncompressed nodes
|
||||||
FileReader *fr = nullptr;
|
FileReader *fr = nullptr;
|
||||||
uint32_t id = MAKE_ID('X','x','X','x'), idcheck = 0, idcheck2 = 0, idcheck3 = 0, idcheck4 = 0, idcheck5 = 0, idcheck6 = 0;
|
uint32_t id = MAKE_ID('X', 'x', 'X', 'x'), idcheck = 0, idcheck2 = 0, idcheck3 = 0, idcheck4 = 0, idcheck5 = 0, idcheck6 = 0;
|
||||||
|
|
||||||
if (map->Size(ML_ZNODES) != 0)
|
if (map->Size(ML_ZNODES) != 0)
|
||||||
{
|
{
|
||||||
// Test normal nodes first
|
// Test normal nodes first
|
||||||
fr = &map->Reader(ML_ZNODES);
|
fr = &map->Reader(ML_ZNODES);
|
||||||
idcheck = MAKE_ID('Z','N','O','D');
|
idcheck = MAKE_ID('Z', 'N', 'O', 'D');
|
||||||
idcheck2 = MAKE_ID('X','N','O','D');
|
idcheck2 = MAKE_ID('X', 'N', 'O', 'D');
|
||||||
}
|
}
|
||||||
else if (map->Size(ML_GLZNODES) != 0)
|
else if (map->Size(ML_GLZNODES) != 0)
|
||||||
{
|
{
|
||||||
fr = &map->Reader(ML_GLZNODES);
|
fr = &map->Reader(ML_GLZNODES);
|
||||||
idcheck = MAKE_ID('Z','G','L','N');
|
idcheck = MAKE_ID('Z', 'G', 'L', 'N');
|
||||||
idcheck2 = MAKE_ID('Z','G','L','2');
|
idcheck2 = MAKE_ID('Z', 'G', 'L', '2');
|
||||||
idcheck3 = MAKE_ID('Z','G','L','3');
|
idcheck3 = MAKE_ID('Z', 'G', 'L', '3');
|
||||||
idcheck4 = MAKE_ID('X','G','L','N');
|
idcheck4 = MAKE_ID('X', 'G', 'L', 'N');
|
||||||
idcheck5 = MAKE_ID('X','G','L','2');
|
idcheck5 = MAKE_ID('X', 'G', 'L', '2');
|
||||||
idcheck6 = MAKE_ID('X','G','L','3');
|
idcheck6 = MAKE_ID('X', 'G', 'L', '3');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fr != nullptr && fr->isOpen()) fr->Read (&id, 4);
|
if (fr != nullptr && fr->isOpen()) fr->Read(&id, 4);
|
||||||
if (id != 0 && (id == idcheck || id == idcheck2 || id == idcheck3 || id == idcheck4 || id == idcheck5 || id == idcheck6))
|
if (id != 0 && (id == idcheck || id == idcheck2 || id == idcheck3 || id == idcheck4 || id == idcheck5 || id == idcheck6))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
P_LoadZNodes (*fr, id);
|
P_LoadZNodes(*fr, id);
|
||||||
}
|
}
|
||||||
catch (CRecoverableError &error)
|
catch (CRecoverableError &error)
|
||||||
{
|
{
|
||||||
Printf ("Error loading nodes: %s\n", error.GetMessage());
|
Printf("Error loading nodes: %s\n", error.GetMessage());
|
||||||
|
|
||||||
ForceNodeBuild = true;
|
ForceNodeBuild = true;
|
||||||
level.subsectors.Clear();
|
level.subsectors.Clear();
|
||||||
|
@ -3891,29 +3891,29 @@ void P_SetupLevel (const char *lumpname, int position, bool newGame)
|
||||||
if (!P_CheckV4Nodes(map))
|
if (!P_CheckV4Nodes(map))
|
||||||
{
|
{
|
||||||
times[7].Clock();
|
times[7].Clock();
|
||||||
P_LoadSubsectors<mapsubsector_t, mapseg_t> (map);
|
P_LoadSubsectors<mapsubsector_t, mapseg_t>(map);
|
||||||
times[7].Unclock();
|
times[7].Unclock();
|
||||||
|
|
||||||
times[8].Clock();
|
times[8].Clock();
|
||||||
if (!ForceNodeBuild) P_LoadNodes<mapnode_t, mapsubsector_t> (map);
|
if (!ForceNodeBuild) P_LoadNodes<mapnode_t, mapsubsector_t>(map);
|
||||||
times[8].Unclock();
|
times[8].Unclock();
|
||||||
|
|
||||||
times[9].Clock();
|
times[9].Clock();
|
||||||
if (!ForceNodeBuild) P_LoadSegs<mapseg_t> (map);
|
if (!ForceNodeBuild) P_LoadSegs<mapseg_t>(map);
|
||||||
times[9].Unclock();
|
times[9].Unclock();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
times[7].Clock();
|
times[7].Clock();
|
||||||
P_LoadSubsectors<mapsubsector4_t, mapseg4_t> (map);
|
P_LoadSubsectors<mapsubsector4_t, mapseg4_t>(map);
|
||||||
times[7].Unclock();
|
times[7].Unclock();
|
||||||
|
|
||||||
times[8].Clock();
|
times[8].Clock();
|
||||||
if (!ForceNodeBuild) P_LoadNodes<mapnode4_t, mapsubsector4_t> (map);
|
if (!ForceNodeBuild) P_LoadNodes<mapnode4_t, mapsubsector4_t>(map);
|
||||||
times[8].Unclock();
|
times[8].Unclock();
|
||||||
|
|
||||||
times[9].Clock();
|
times[9].Clock();
|
||||||
if (!ForceNodeBuild) P_LoadSegs<mapseg4_t> (map);
|
if (!ForceNodeBuild) P_LoadSegs<mapseg4_t>(map);
|
||||||
times[9].Unclock();
|
times[9].Unclock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3924,7 +3924,7 @@ void P_SetupLevel (const char *lumpname, int position, bool newGame)
|
||||||
// If loading the regular nodes failed try GL nodes before considering a rebuild
|
// If loading the regular nodes failed try GL nodes before considering a rebuild
|
||||||
if (ForceNodeBuild)
|
if (ForceNodeBuild)
|
||||||
{
|
{
|
||||||
if (P_LoadGLNodes(map))
|
if (P_LoadGLNodes(map))
|
||||||
{
|
{
|
||||||
ForceNodeBuild = false;
|
ForceNodeBuild = false;
|
||||||
reloop = true;
|
reloop = true;
|
||||||
|
@ -3933,16 +3933,16 @@ void P_SetupLevel (const char *lumpname, int position, bool newGame)
|
||||||
}
|
}
|
||||||
else reloop = true;
|
else reloop = true;
|
||||||
|
|
||||||
uint64_t startTime=0, endTime=0;
|
uint64_t startTime = 0, endTime = 0;
|
||||||
|
|
||||||
bool BuildGLNodes;
|
bool BuildGLNodes;
|
||||||
if (ForceNodeBuild)
|
if (ForceNodeBuild)
|
||||||
{
|
{
|
||||||
BuildGLNodes = RequireGLNodes || multiplayer || demoplayback || demorecording || genglnodes;
|
BuildGLNodes = RequireGLNodes || multiplayer || demoplayback || demorecording || genglnodes;
|
||||||
|
|
||||||
startTime = I_msTime ();
|
startTime = I_msTime();
|
||||||
TArray<FNodeBuilder::FPolyStart> polyspots, anchors;
|
TArray<FNodeBuilder::FPolyStart> polyspots, anchors;
|
||||||
P_GetPolySpots (map, polyspots, anchors);
|
P_GetPolySpots(map, polyspots, anchors);
|
||||||
FNodeBuilder::FLevel leveldata =
|
FNodeBuilder::FLevel leveldata =
|
||||||
{
|
{
|
||||||
&level.vertexes[0], (int)level.vertexes.Size(),
|
&level.vertexes[0], (int)level.vertexes.Size(),
|
||||||
|
@ -3950,14 +3950,14 @@ void P_SetupLevel (const char *lumpname, int position, bool newGame)
|
||||||
&level.lines[0], (int)level.lines.Size(),
|
&level.lines[0], (int)level.lines.Size(),
|
||||||
0, 0, 0, 0
|
0, 0, 0, 0
|
||||||
};
|
};
|
||||||
leveldata.FindMapBounds ();
|
leveldata.FindMapBounds();
|
||||||
// We need GL nodes if am_textured is on.
|
// We need GL nodes if am_textured is on.
|
||||||
// In case a sync critical game mode is started, also build GL nodes to avoid problems
|
// In case a sync critical game mode is started, also build GL nodes to avoid problems
|
||||||
// if the different machines' am_textured setting differs.
|
// if the different machines' am_textured setting differs.
|
||||||
FNodeBuilder builder (leveldata, polyspots, anchors, BuildGLNodes);
|
FNodeBuilder builder(leveldata, polyspots, anchors, BuildGLNodes);
|
||||||
builder.Extract (level);
|
builder.Extract(level);
|
||||||
endTime = I_msTime ();
|
endTime = I_msTime();
|
||||||
DPrintf (DMSG_NOTIFY, "BSP generation took %.3f sec (%d segs)\n", (endTime - startTime) * 0.001, level.segs.Size());
|
DPrintf(DMSG_NOTIFY, "BSP generation took %.3f sec (%d segs)\n", (endTime - startTime) * 0.001, level.segs.Size());
|
||||||
oldvertextable = builder.GetOldVertexTable();
|
oldvertextable = builder.GetOldVertexTable();
|
||||||
reloop = true;
|
reloop = true;
|
||||||
}
|
}
|
||||||
|
@ -3965,14 +3965,14 @@ void P_SetupLevel (const char *lumpname, int position, bool newGame)
|
||||||
{
|
{
|
||||||
BuildGLNodes = false;
|
BuildGLNodes = false;
|
||||||
// Older ZDBSPs had problems with compressed sidedefs and assigned wrong sides to the segs if both sides were the same sidedef.
|
// Older ZDBSPs had problems with compressed sidedefs and assigned wrong sides to the segs if both sides were the same sidedef.
|
||||||
for(auto &seg : level.segs)
|
for (auto &seg : level.segs)
|
||||||
{
|
{
|
||||||
if (seg.backsector == seg.frontsector && seg.linedef)
|
if (seg.backsector == seg.frontsector && seg.linedef)
|
||||||
{
|
{
|
||||||
double d1 = (seg.v1->fPos() - seg.linedef->v1->fPos()).LengthSquared();
|
double d1 = (seg.v1->fPos() - seg.linedef->v1->fPos()).LengthSquared();
|
||||||
double d2 = (seg.v2->fPos() - seg.linedef->v1->fPos()).LengthSquared();
|
double d2 = (seg.v2->fPos() - seg.linedef->v1->fPos()).LengthSquared();
|
||||||
|
|
||||||
if (d2<d1) // backside
|
if (d2 < d1) // backside
|
||||||
{
|
{
|
||||||
seg.sidedef = seg.linedef->sidedef[1];
|
seg.sidedef = seg.linedef->sidedef[1];
|
||||||
}
|
}
|
||||||
|
@ -3999,22 +3999,22 @@ void P_SetupLevel (const char *lumpname, int position, bool newGame)
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the head node for gameplay purposes. If the separate gamenodes array is not empty, use that, otherwise use the render nodes.
|
// set the head node for gameplay purposes. If the separate gamenodes array is not empty, use that, otherwise use the render nodes.
|
||||||
level.headgamenode = level.gamenodes.Size() > 0 ? &level.gamenodes[level.gamenodes.Size() - 1] : level.nodes.Size()? &level.nodes[level.nodes.Size() - 1] : nullptr;
|
level.headgamenode = level.gamenodes.Size() > 0 ? &level.gamenodes[level.gamenodes.Size() - 1] : level.nodes.Size() ? &level.nodes[level.nodes.Size() - 1] : nullptr;
|
||||||
|
|
||||||
times[10].Clock();
|
times[10].Clock();
|
||||||
P_LoadBlockMap (map);
|
P_LoadBlockMap(map);
|
||||||
times[10].Unclock();
|
times[10].Unclock();
|
||||||
|
|
||||||
times[11].Clock();
|
times[11].Clock();
|
||||||
P_LoadReject (map, buildmap);
|
P_LoadReject(map, buildmap);
|
||||||
times[11].Unclock();
|
times[11].Unclock();
|
||||||
|
|
||||||
times[12].Clock();
|
times[12].Clock();
|
||||||
P_GroupLines (buildmap);
|
P_GroupLines(buildmap);
|
||||||
times[12].Unclock();
|
times[12].Unclock();
|
||||||
|
|
||||||
times[13].Clock();
|
times[13].Clock();
|
||||||
P_FloodZones ();
|
P_FloodZones();
|
||||||
times[13].Unclock();
|
times[13].Unclock();
|
||||||
|
|
||||||
if (hasglnodes)
|
if (hasglnodes)
|
||||||
|
@ -4023,8 +4023,8 @@ void P_SetupLevel (const char *lumpname, int position, bool newGame)
|
||||||
}
|
}
|
||||||
|
|
||||||
bodyqueslot = 0;
|
bodyqueslot = 0;
|
||||||
// phares 8/10/98: Clear body queue so the corpses from previous games are
|
// phares 8/10/98: Clear body queue so the corpses from previous games are
|
||||||
// not assumed to be from this one.
|
// not assumed to be from this one.
|
||||||
|
|
||||||
for (i = 0; i < BODYQUESIZE; i++)
|
for (i = 0; i < BODYQUESIZE; i++)
|
||||||
bodyque[i] = NULL;
|
bodyque[i] = NULL;
|
||||||
|
@ -4032,7 +4032,7 @@ void P_SetupLevel (const char *lumpname, int position, bool newGame)
|
||||||
if (!buildmap)
|
if (!buildmap)
|
||||||
{
|
{
|
||||||
// [RH] Spawn slope creating things first.
|
// [RH] Spawn slope creating things first.
|
||||||
P_SpawnSlopeMakers (&MapThingsConverted[0], &MapThingsConverted[MapThingsConverted.Size()], oldvertextable);
|
P_SpawnSlopeMakers(&MapThingsConverted[0], &MapThingsConverted[MapThingsConverted.Size()], oldvertextable);
|
||||||
P_CopySlopes();
|
P_CopySlopes();
|
||||||
|
|
||||||
// Spawn 3d floors - must be done before spawning things so it can't be done in P_SpawnSpecials
|
// Spawn 3d floors - must be done before spawning things so it can't be done in P_SpawnSpecials
|
||||||
|
@ -4050,7 +4050,7 @@ void P_SetupLevel (const char *lumpname, int position, bool newGame)
|
||||||
|
|
||||||
times[15].Clock();
|
times[15].Clock();
|
||||||
if (!map->HasBehavior && !map->isText)
|
if (!map->HasBehavior && !map->isText)
|
||||||
P_TranslateTeleportThings (); // [RH] Assign teleport destination TIDs
|
P_TranslateTeleportThings(); // [RH] Assign teleport destination TIDs
|
||||||
times[15].Unclock();
|
times[15].Unclock();
|
||||||
}
|
}
|
||||||
#if 0 // There is no such thing as a build map.
|
#if 0 // There is no such thing as a build map.
|
||||||
|
@ -4058,7 +4058,7 @@ void P_SetupLevel (const char *lumpname, int position, bool newGame)
|
||||||
{
|
{
|
||||||
for (i = 0; i < numbuildthings; ++i)
|
for (i = 0; i < numbuildthings; ++i)
|
||||||
{
|
{
|
||||||
SpawnMapThing (i, &buildthings[i], 0);
|
SpawnMapThing(i, &buildthings[i], 0);
|
||||||
}
|
}
|
||||||
delete[] buildthings;
|
delete[] buildthings;
|
||||||
}
|
}
|
||||||
|
@ -4070,7 +4070,7 @@ void P_SetupLevel (const char *lumpname, int position, bool newGame)
|
||||||
}
|
}
|
||||||
|
|
||||||
// set up world state
|
// set up world state
|
||||||
P_SpawnSpecials ();
|
P_SpawnSpecials();
|
||||||
|
|
||||||
// disable reflective planes on sloped sectors.
|
// disable reflective planes on sloped sectors.
|
||||||
for (auto &sec : level.sectors)
|
for (auto &sec : level.sectors)
|
||||||
|
@ -4090,8 +4090,8 @@ void P_SetupLevel (const char *lumpname, int position, bool newGame)
|
||||||
P_InitHealthGroups();
|
P_InitHealthGroups();
|
||||||
|
|
||||||
times[16].Clock();
|
times[16].Clock();
|
||||||
if (reloop) P_LoopSidedefs (false);
|
if (reloop) P_LoopSidedefs(false);
|
||||||
PO_Init (); // Initialize the polyobjs
|
PO_Init(); // Initialize the polyobjs
|
||||||
if (!level.IsReentering())
|
if (!level.IsReentering())
|
||||||
P_FinalizePortals(); // finalize line portals after polyobjects have been initialized. This info is needed for properly flagging them.
|
P_FinalizePortals(); // finalize line portals after polyobjects have been initialized. This info is needed for properly flagging them.
|
||||||
times[16].Unclock();
|
times[16].Unclock();
|
||||||
|
@ -4103,12 +4103,12 @@ void P_SetupLevel (const char *lumpname, int position, bool newGame)
|
||||||
// if deathmatch, randomly spawn the active players
|
// if deathmatch, randomly spawn the active players
|
||||||
if (deathmatch)
|
if (deathmatch)
|
||||||
{
|
{
|
||||||
for (i=0 ; i<MAXPLAYERS ; i++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
{
|
{
|
||||||
if (playeringame[i])
|
if (playeringame[i])
|
||||||
{
|
{
|
||||||
players[i].mo = NULL;
|
players[i].mo = NULL;
|
||||||
G_DeathMatchSpawnPlayer (i);
|
G_DeathMatchSpawnPlayer(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4128,7 +4128,7 @@ void P_SetupLevel (const char *lumpname, int position, bool newGame)
|
||||||
|
|
||||||
// [SP] move unfriendly players around
|
// [SP] move unfriendly players around
|
||||||
// horribly hacky - yes, this needs rewritten.
|
// horribly hacky - yes, this needs rewritten.
|
||||||
if (level.deathmatchstarts.Size () > 0)
|
if (level.deathmatchstarts.Size() > 0)
|
||||||
{
|
{
|
||||||
for (i = 0; i < MAXPLAYERS; ++i)
|
for (i = 0; i < MAXPLAYERS; ++i)
|
||||||
{
|
{
|
||||||
|
@ -4137,7 +4137,7 @@ void P_SetupLevel (const char *lumpname, int position, bool newGame)
|
||||||
if (!(players[i].mo->flags & MF_FRIENDLY))
|
if (!(players[i].mo->flags & MF_FRIENDLY))
|
||||||
{
|
{
|
||||||
AActor * oldSpawn = players[i].mo;
|
AActor * oldSpawn = players[i].mo;
|
||||||
G_DeathMatchSpawnPlayer (i);
|
G_DeathMatchSpawnPlayer(i);
|
||||||
oldSpawn->Destroy();
|
oldSpawn->Destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4151,11 +4151,11 @@ void P_SetupLevel (const char *lumpname, int position, bool newGame)
|
||||||
TThinkerIterator<AActor> it;
|
TThinkerIterator<AActor> it;
|
||||||
AActor * mo;
|
AActor * mo;
|
||||||
|
|
||||||
while ((mo=it.Next()))
|
while ((mo = it.Next()))
|
||||||
{
|
{
|
||||||
if (mo->flags & MF_COUNTKILL)
|
if (mo->flags & MF_COUNTKILL)
|
||||||
{
|
{
|
||||||
if (mo->Sector->damageamount > 0 && (mo->Sector->Flags & (SECF_ENDGODMODE|SECF_ENDLEVEL)) == (SECF_ENDGODMODE|SECF_ENDLEVEL))
|
if (mo->Sector->damageamount > 0 && (mo->Sector->Flags & (SECF_ENDGODMODE | SECF_ENDLEVEL)) == (SECF_ENDGODMODE | SECF_ENDLEVEL))
|
||||||
{
|
{
|
||||||
mo->ClearCounters();
|
mo->ClearCounters();
|
||||||
}
|
}
|
||||||
|
@ -4171,20 +4171,20 @@ void P_SetupLevel (const char *lumpname, int position, bool newGame)
|
||||||
R_OldBlend = 0xffffffff;
|
R_OldBlend = 0xffffffff;
|
||||||
|
|
||||||
// [RH] Remove all particles
|
// [RH] Remove all particles
|
||||||
P_ClearParticles ();
|
P_ClearParticles();
|
||||||
|
|
||||||
times[17].Clock();
|
times[17].Clock();
|
||||||
// preload graphics and sounds
|
// preload graphics and sounds
|
||||||
if (precache)
|
if (precache)
|
||||||
{
|
{
|
||||||
P_PrecacheLevel ();
|
P_PrecacheLevel();
|
||||||
S_PrecacheLevel ();
|
S_PrecacheLevel();
|
||||||
}
|
}
|
||||||
times[17].Unclock();
|
times[17].Unclock();
|
||||||
|
|
||||||
if (deathmatch)
|
if (deathmatch)
|
||||||
{
|
{
|
||||||
AnnounceGameStart ();
|
AnnounceGameStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
// This check was previously done at run time each time the heightsec was checked.
|
// This check was previously done at run time each time the heightsec was checked.
|
||||||
|
@ -4204,12 +4204,12 @@ void P_SetupLevel (const char *lumpname, int position, bool newGame)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
P_ResetSightCounters (true);
|
P_ResetSightCounters(true);
|
||||||
//Printf ("free memory: 0x%x\n", Z_FreeMemory());
|
//Printf ("free memory: 0x%x\n", Z_FreeMemory());
|
||||||
|
|
||||||
if (showloadtimes)
|
if (showloadtimes)
|
||||||
{
|
{
|
||||||
Printf ("---Total load times---\n");
|
Printf("---Total load times---\n");
|
||||||
for (i = 0; i < 18; ++i)
|
for (i = 0; i < 18; ++i)
|
||||||
{
|
{
|
||||||
static const char *timenames[] =
|
static const char *timenames[] =
|
||||||
|
@ -4233,7 +4233,7 @@ void P_SetupLevel (const char *lumpname, int position, bool newGame)
|
||||||
"init polys",
|
"init polys",
|
||||||
"precache"
|
"precache"
|
||||||
};
|
};
|
||||||
Printf ("Time%3d:%9.4f ms (%s)\n", i, times[i].TimeMS(), timenames[i]);
|
Printf("Time%3d:%9.4f ms (%s)\n", i, times[i].TimeMS(), timenames[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MapThingsConverted.Clear();
|
MapThingsConverted.Clear();
|
||||||
|
@ -4249,10 +4249,22 @@ void P_SetupLevel (const char *lumpname, int position, bool newGame)
|
||||||
memcpy(&level.loadlines[0], &level.lines[0], level.lines.Size() * sizeof(level.lines[0]));
|
memcpy(&level.loadlines[0], &level.lines[0], level.lines.Size() * sizeof(level.lines[0]));
|
||||||
level.loadsides.Resize(level.sides.Size());
|
level.loadsides.Resize(level.sides.Size());
|
||||||
memcpy(&level.loadsides[0], &level.sides[0], level.sides.Size() * sizeof(level.sides[0]));
|
memcpy(&level.loadsides[0], &level.sides[0], level.sides.Size() * sizeof(level.sides[0]));
|
||||||
|
|
||||||
|
|
||||||
|
for (auto i : { 29, 30 })
|
||||||
|
{
|
||||||
|
level.lines[i].sidedef[0]->SetSpecialColor(side_t::top, side_t::walltop, PalEntry(255, 255, 0));
|
||||||
|
level.lines[i].sidedef[0]->SetSpecialColor(side_t::top, side_t::wallbottom, PalEntry(0, 255, 255));
|
||||||
|
level.lines[i].sidedef[0]->SetSpecialColor(side_t::bottom, side_t::walltop, PalEntry(255, 0, 0));
|
||||||
|
level.lines[i].sidedef[0]->SetSpecialColor(side_t::bottom, side_t::wallbottom, PalEntry(0, 0, 255));
|
||||||
|
}
|
||||||
|
level.lines[29].sidedef[0]->textures[side_t::top].flags = side_t::part::UseOwnColors;
|
||||||
|
level.lines[30].sidedef[0]->textures[side_t::top].flags = side_t::part::UseOwnColors | side_t::part::ClampGradient;
|
||||||
|
level.lines[29].sidedef[0]->textures[side_t::bottom].flags = side_t::part::UseOwnColors;
|
||||||
|
level.lines[30].sidedef[0]->textures[side_t::bottom].flags = side_t::part::UseOwnColors | side_t::part::ClampGradient;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// P_Init
|
// P_Init
|
||||||
//
|
//
|
||||||
|
|
|
@ -1226,6 +1226,7 @@ public:
|
||||||
{
|
{
|
||||||
FName key = ParseKey();
|
FName key = ParseKey();
|
||||||
switch(key)
|
switch(key)
|
||||||
|
|
||||||
{
|
{
|
||||||
case NAME_Offsetx:
|
case NAME_Offsetx:
|
||||||
texOfs[0] = CheckInt(key);
|
texOfs[0] = CheckInt(key);
|
||||||
|
@ -1337,6 +1338,79 @@ public:
|
||||||
Flag(sd->Flags, WALLF_NOAUTODECALS, key);
|
Flag(sd->Flags, WALLF_NOAUTODECALS, key);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
case NAME_nogradient_top:
|
||||||
|
Flag(sd->textures[side_t::top].flags, side_t::part::NoGradient, key);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NAME_flipgradient_top:
|
||||||
|
Flag(sd->textures[side_t::top].flags, side_t::part::FlipGradient, key);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NAME_clampgradient_top:
|
||||||
|
Flag(sd->textures[side_t::top].flags, side_t::part::ClampGradient, key);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NAME_useowncolors_top:
|
||||||
|
Flag(sd->textures[side_t::top].flags, side_t::part::UseOwnColors, key);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NAME_uppercolor_top:
|
||||||
|
sd->SetSpecialColor(side_t::top, 0, CheckInt(key));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NAME_lowercolor_top:
|
||||||
|
sd->SetSpecialColor(side_t::top, 1, CheckInt(key));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NAME_nogradient_mid:
|
||||||
|
Flag(sd->textures[side_t::mid].flags, side_t::part::NoGradient, key);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NAME_flipgradient_mid:
|
||||||
|
Flag(sd->textures[side_t::mid].flags, side_t::part::FlipGradient, key);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NAME_clampgradient_mid:
|
||||||
|
Flag(sd->textures[side_t::mid].flags, side_t::part::ClampGradient, key);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NAME_useowncolors_mid:
|
||||||
|
Flag(sd->textures[side_t::mid].flags, side_t::part::UseOwnColors, key);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NAME_uppercolor_mid:
|
||||||
|
sd->SetSpecialColor(side_t::mid, 0, CheckInt(key));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NAME_lowercolor_mid:
|
||||||
|
sd->SetSpecialColor(side_t::mid, 1, CheckInt(key));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NAME_nogradient_bottom:
|
||||||
|
Flag(sd->textures[side_t::bottom].flags, side_t::part::NoGradient, key);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NAME_flipgradient_bottom:
|
||||||
|
Flag(sd->textures[side_t::bottom].flags, side_t::part::FlipGradient, key);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NAME_clampgradient_bottom:
|
||||||
|
Flag(sd->textures[side_t::bottom].flags, side_t::part::ClampGradient, key);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NAME_useowncolors_bottom:
|
||||||
|
Flag(sd->textures[side_t::bottom].flags, side_t::part::UseOwnColors, key);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NAME_uppercolor_bottom:
|
||||||
|
sd->SetSpecialColor(side_t::bottom, 0, CheckInt(key));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NAME_lowercolor_bottom:
|
||||||
|
sd->SetSpecialColor(side_t::bottom, 1, CheckInt(key));
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -88,7 +88,6 @@ bool RenderPolyWall::RenderLine(PolyRenderThread *thread, seg_t *line, sector_t
|
||||||
wall.Line = line->linedef;
|
wall.Line = line->linedef;
|
||||||
wall.Side = line->sidedef;
|
wall.Side = line->sidedef;
|
||||||
wall.LineSegLine = line->linedef;
|
wall.LineSegLine = line->linedef;
|
||||||
wall.Colormap = GetColorTable(frontsector->Colormap, frontsector->SpecialColors[sector_t::walltop]);
|
|
||||||
wall.Masked = false;
|
wall.Masked = false;
|
||||||
wall.SubsectorDepth = subsectorDepth;
|
wall.SubsectorDepth = subsectorDepth;
|
||||||
wall.StencilValue = stencilValue;
|
wall.StencilValue = stencilValue;
|
||||||
|
@ -102,6 +101,7 @@ bool RenderPolyWall::RenderLine(PolyRenderThread *thread, seg_t *line, sector_t
|
||||||
wall.TopTexZ = topTexZ;
|
wall.TopTexZ = topTexZ;
|
||||||
wall.BottomTexZ = bottomTexZ;
|
wall.BottomTexZ = bottomTexZ;
|
||||||
wall.Wallpart = side_t::mid;
|
wall.Wallpart = side_t::mid;
|
||||||
|
wall.Colormap = GetColorTable(frontsector->Colormap, wall.Side->GetSpecialColor(wall.Wallpart, side_t::walltop, frontsector));
|
||||||
wall.Texture = GetTexture(wall.Line, wall.Side, side_t::mid);
|
wall.Texture = GetTexture(wall.Line, wall.Side, side_t::mid);
|
||||||
wall.Polyportal = polyportal;
|
wall.Polyportal = polyportal;
|
||||||
wall.Render(thread);
|
wall.Render(thread);
|
||||||
|
@ -140,6 +140,7 @@ bool RenderPolyWall::RenderLine(PolyRenderThread *thread, seg_t *line, sector_t
|
||||||
wall.TopTexZ = topTexZ;
|
wall.TopTexZ = topTexZ;
|
||||||
wall.BottomTexZ = MIN(MIN(backceilz1, frontceilz1), MIN(backceilz2, frontceilz2));
|
wall.BottomTexZ = MIN(MIN(backceilz1, frontceilz1), MIN(backceilz2, frontceilz2));
|
||||||
wall.Wallpart = side_t::top;
|
wall.Wallpart = side_t::top;
|
||||||
|
wall.Colormap = GetColorTable(frontsector->Colormap, wall.Side->GetSpecialColor(wall.Wallpart, side_t::walltop, frontsector));
|
||||||
wall.Texture = GetTexture(wall.Line, wall.Side, side_t::top);
|
wall.Texture = GetTexture(wall.Line, wall.Side, side_t::top);
|
||||||
wall.Render(thread);
|
wall.Render(thread);
|
||||||
}
|
}
|
||||||
|
@ -152,6 +153,7 @@ bool RenderPolyWall::RenderLine(PolyRenderThread *thread, seg_t *line, sector_t
|
||||||
wall.UnpeggedCeil1 = topceilz1;
|
wall.UnpeggedCeil1 = topceilz1;
|
||||||
wall.UnpeggedCeil2 = topceilz2;
|
wall.UnpeggedCeil2 = topceilz2;
|
||||||
wall.Wallpart = side_t::bottom;
|
wall.Wallpart = side_t::bottom;
|
||||||
|
wall.Colormap = GetColorTable(frontsector->Colormap, wall.Side->GetSpecialColor(wall.Wallpart, side_t::walltop, frontsector));
|
||||||
wall.Texture = GetTexture(wall.Line, wall.Side, side_t::bottom);
|
wall.Texture = GetTexture(wall.Line, wall.Side, side_t::bottom);
|
||||||
wall.Render(thread);
|
wall.Render(thread);
|
||||||
}
|
}
|
||||||
|
@ -162,6 +164,7 @@ bool RenderPolyWall::RenderLine(PolyRenderThread *thread, seg_t *line, sector_t
|
||||||
wall.TopTexZ = MAX(middleceilz1, middleceilz2);
|
wall.TopTexZ = MAX(middleceilz1, middleceilz2);
|
||||||
wall.BottomTexZ = MIN(middlefloorz1, middlefloorz2);
|
wall.BottomTexZ = MIN(middlefloorz1, middlefloorz2);
|
||||||
wall.Wallpart = side_t::mid;
|
wall.Wallpart = side_t::mid;
|
||||||
|
wall.Colormap = GetColorTable(frontsector->Colormap, wall.Side->GetSpecialColor(wall.Wallpart, side_t::walltop, frontsector));
|
||||||
wall.Texture = GetTexture(wall.Line, wall.Side, side_t::mid);
|
wall.Texture = GetTexture(wall.Line, wall.Side, side_t::mid);
|
||||||
wall.Masked = true;
|
wall.Masked = true;
|
||||||
wall.Additive = !!(wall.Line->flags & ML_ADDTRANS);
|
wall.Additive = !!(wall.Line->flags & ML_ADDTRANS);
|
||||||
|
@ -212,7 +215,6 @@ void RenderPolyWall::Render3DFloorLine(PolyRenderThread *thread, seg_t *line, se
|
||||||
wall.LineSegLine = line->linedef;
|
wall.LineSegLine = line->linedef;
|
||||||
wall.Line = fakeFloor->master;
|
wall.Line = fakeFloor->master;
|
||||||
wall.Side = fakeFloor->master->sidedef[0];
|
wall.Side = fakeFloor->master->sidedef[0];
|
||||||
wall.Colormap = GetColorTable(frontsector->Colormap, frontsector->SpecialColors[sector_t::walltop]);
|
|
||||||
wall.SectorLightLevel = frontsector->lightlevel;
|
wall.SectorLightLevel = frontsector->lightlevel;
|
||||||
wall.Additive = !!(fakeFloor->flags & FF_ADDITIVETRANS);
|
wall.Additive = !!(fakeFloor->flags & FF_ADDITIVETRANS);
|
||||||
if (!wall.Additive && fakeFloor->alpha == 255)
|
if (!wall.Additive && fakeFloor->alpha == 255)
|
||||||
|
@ -231,6 +233,7 @@ void RenderPolyWall::Render3DFloorLine(PolyRenderThread *thread, seg_t *line, se
|
||||||
wall.TopTexZ = topTexZ;
|
wall.TopTexZ = topTexZ;
|
||||||
wall.BottomTexZ = bottomTexZ;
|
wall.BottomTexZ = bottomTexZ;
|
||||||
wall.Wallpart = side_t::mid;
|
wall.Wallpart = side_t::mid;
|
||||||
|
wall.Colormap = GetColorTable(frontsector->Colormap, wall.Side->GetSpecialColor(wall.Wallpart, side_t::walltop, frontsector));
|
||||||
if (fakeFloor->flags & FF_UPPERTEXTURE)
|
if (fakeFloor->flags & FF_UPPERTEXTURE)
|
||||||
wall.Texture = GetTexture(line->linedef, line->sidedef, side_t::top);
|
wall.Texture = GetTexture(line->linedef, line->sidedef, side_t::top);
|
||||||
else if (fakeFloor->flags & FF_LOWERTEXTURE)
|
else if (fakeFloor->flags & FF_LOWERTEXTURE)
|
||||||
|
|
54
src/r_defs.h
54
src/r_defs.h
|
@ -325,7 +325,7 @@ public:
|
||||||
return !normal.XY().isZero();
|
return !normal.XY().isZero();
|
||||||
}
|
}
|
||||||
|
|
||||||
DVector3 Normal() const
|
const DVector3 &Normal() const
|
||||||
{
|
{
|
||||||
return normal;
|
return normal;
|
||||||
}
|
}
|
||||||
|
@ -645,8 +645,6 @@ public:
|
||||||
void SetColor(int r, int g, int b, int desat);
|
void SetColor(int r, int g, int b, int desat);
|
||||||
void SetFade(int r, int g, int b);
|
void SetFade(int r, int g, int b);
|
||||||
void SetFogDensity(int dens);
|
void SetFogDensity(int dens);
|
||||||
void SetSpecialColor(int num, int r, int g, int b);
|
|
||||||
void SetSpecialColor(int num, PalEntry rgb);
|
|
||||||
void ClosestPoint(const DVector2 &pos, DVector2 &out) const;
|
void ClosestPoint(const DVector2 &pos, DVector2 &out) const;
|
||||||
int GetFloorLight () const;
|
int GetFloorLight () const;
|
||||||
int GetCeilingLight () const;
|
int GetCeilingLight () const;
|
||||||
|
@ -914,6 +912,17 @@ public:
|
||||||
Flags &= ~SECF_SPECIALFLAGS;
|
Flags &= ~SECF_SPECIALFLAGS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetSpecialColor(int slot, int r, int g, int b)
|
||||||
|
{
|
||||||
|
SpecialColors[slot] = PalEntry(255, r, g, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetSpecialColor(int slot, PalEntry rgb)
|
||||||
|
{
|
||||||
|
rgb.a = 255;
|
||||||
|
SpecialColors[slot] = rgb;
|
||||||
|
}
|
||||||
|
|
||||||
inline bool PortalBlocksView(int plane);
|
inline bool PortalBlocksView(int plane);
|
||||||
inline bool PortalBlocksSight(int plane);
|
inline bool PortalBlocksSight(int plane);
|
||||||
inline bool PortalBlocksMovement(int plane);
|
inline bool PortalBlocksMovement(int plane);
|
||||||
|
@ -1149,16 +1158,31 @@ struct side_t
|
||||||
{
|
{
|
||||||
top=0,
|
top=0,
|
||||||
mid=1,
|
mid=1,
|
||||||
bottom=2
|
bottom=2,
|
||||||
|
none = 1, // this is just for clarification in a mapping table
|
||||||
|
};
|
||||||
|
enum EColorSlot
|
||||||
|
{
|
||||||
|
walltop = 0,
|
||||||
|
wallbottom = 1,
|
||||||
};
|
};
|
||||||
struct part
|
struct part
|
||||||
{
|
{
|
||||||
|
enum EPartFlags
|
||||||
|
{
|
||||||
|
NoGradient = 1,
|
||||||
|
FlipGradient = 2,
|
||||||
|
ClampGradient = 4,
|
||||||
|
UseOwnColors = 8,
|
||||||
|
};
|
||||||
double xOffset;
|
double xOffset;
|
||||||
double yOffset;
|
double yOffset;
|
||||||
double xScale;
|
double xScale;
|
||||||
double yScale;
|
double yScale;
|
||||||
TObjPtr<DInterpolation*> interpolation;
|
TObjPtr<DInterpolation*> interpolation;
|
||||||
FTextureID texture;
|
FTextureID texture;
|
||||||
|
int flags;
|
||||||
|
PalEntry SpecialColors[2];
|
||||||
|
|
||||||
void InitFrom(const part &other)
|
void InitFrom(const part &other)
|
||||||
{
|
{
|
||||||
|
@ -1281,6 +1305,28 @@ struct side_t
|
||||||
textures[which].yScale *= delta;
|
textures[which].yScale *= delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetSpecialColor(int which, int slot, int r, int g, int b)
|
||||||
|
{
|
||||||
|
textures[which].SpecialColors[slot] = PalEntry(255, r, g, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetSpecialColor(int which, int slot, PalEntry rgb)
|
||||||
|
{
|
||||||
|
rgb.a = 255;
|
||||||
|
textures[which].SpecialColors[slot] = rgb;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note that the sector being passed in here may not be the actual sector this sidedef belongs to
|
||||||
|
// (either for polyobjects or FakeFlat'ed temporaries.)
|
||||||
|
PalEntry GetSpecialColor(int which, int slot, sector_t *frontsector) const
|
||||||
|
{
|
||||||
|
auto &part = textures[which];
|
||||||
|
if (part.flags & part::NoGradient) slot = 0;
|
||||||
|
if (part.flags & part::FlipGradient) slot ^= 1;
|
||||||
|
return (part.flags & part::UseOwnColors) ? part.SpecialColors[slot] : frontsector->SpecialColors[sector_t::walltop + slot];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
DInterpolation *SetInterpolation(int position);
|
DInterpolation *SetInterpolation(int position);
|
||||||
void StopInterpolation(int position);
|
void StopInterpolation(int position);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
in vec4 pixelpos;
|
in vec4 pixelpos;
|
||||||
in vec3 glowdist;
|
in vec3 glowdist;
|
||||||
|
in vec3 gradientdist;
|
||||||
|
|
||||||
in vec4 vWorldNormal;
|
in vec4 vWorldNormal;
|
||||||
in vec4 vEyeNormal;
|
in vec4 vEyeNormal;
|
||||||
|
@ -90,7 +91,7 @@ vec4 getTexel(vec2 st)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (uObjectColor2.a == 0.0) texel *= uObjectColor;
|
if (uObjectColor2.a == 0.0) texel *= uObjectColor;
|
||||||
else texel *= mix(uObjectColor, uObjectColor2, glowdist.z);
|
else texel *= mix(uObjectColor, uObjectColor2, gradientdist.z);
|
||||||
|
|
||||||
return desaturate(texel);
|
return desaturate(texel);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ in vec4 aVertex2;
|
||||||
in vec4 aNormal;
|
in vec4 aNormal;
|
||||||
out vec4 pixelpos;
|
out vec4 pixelpos;
|
||||||
out vec3 glowdist;
|
out vec3 glowdist;
|
||||||
|
out vec3 gradientdist;
|
||||||
|
|
||||||
out vec4 vWorldNormal;
|
out vec4 vWorldNormal;
|
||||||
out vec4 vEyeNormal;
|
out vec4 vEyeNormal;
|
||||||
|
@ -50,16 +51,28 @@ void main()
|
||||||
pixelpos.xyz = worldcoord.xyz;
|
pixelpos.xyz = worldcoord.xyz;
|
||||||
pixelpos.w = -eyeCoordPos.z/eyeCoordPos.w;
|
pixelpos.w = -eyeCoordPos.z/eyeCoordPos.w;
|
||||||
|
|
||||||
float topatpoint = -((uGlowTopPlane.w + uGlowTopPlane.x * worldcoord.x + uGlowTopPlane.y * worldcoord.z) * uGlowTopPlane.z);
|
if (uGlowTopColor.a > 0 || uGlowBottomColor.a > 0)
|
||||||
float bottomatpoint = -((uGlowBottomPlane.w + uGlowBottomPlane.x * worldcoord.x + uGlowBottomPlane.y * worldcoord.z) * uGlowBottomPlane.z);
|
{
|
||||||
glowdist.x = topatpoint - worldcoord.y;
|
float topatpoint = (uGlowTopPlane.w + uGlowTopPlane.x * worldcoord.x + uGlowTopPlane.y * worldcoord.z) * uGlowTopPlane.z;
|
||||||
glowdist.y = worldcoord.y - bottomatpoint;
|
float bottomatpoint = (uGlowBottomPlane.w + uGlowBottomPlane.x * worldcoord.x + uGlowBottomPlane.y * worldcoord.z) * uGlowBottomPlane.z;
|
||||||
glowdist.z = clamp(glowdist.x / (topatpoint - bottomatpoint), 0.0, 1.0);
|
glowdist.x = topatpoint - worldcoord.y;
|
||||||
|
glowdist.y = worldcoord.y - bottomatpoint;
|
||||||
|
glowdist.z = clamp(glowdist.x / (topatpoint - bottomatpoint), 0.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uObjectColor2.a != 0)
|
||||||
|
{
|
||||||
|
float topatpoint = (uGradientTopPlane.w + uGradientTopPlane.x * worldcoord.x + uGradientTopPlane.y * worldcoord.z) * uGradientTopPlane.z;
|
||||||
|
float bottomatpoint = (uGradientBottomPlane.w + uGradientBottomPlane.x * worldcoord.x + uGradientBottomPlane.y * worldcoord.z) * uGradientBottomPlane.z;
|
||||||
|
gradientdist.x = topatpoint - worldcoord.y;
|
||||||
|
gradientdist.y = worldcoord.y - bottomatpoint;
|
||||||
|
gradientdist.z = clamp(gradientdist.x / (topatpoint - bottomatpoint), 0.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
if (uSplitBottomPlane.z != 0.0)
|
if (uSplitBottomPlane.z != 0.0)
|
||||||
{
|
{
|
||||||
gl_ClipDistance[3] = -((uSplitTopPlane.w + uSplitTopPlane.x * worldcoord.x + uSplitTopPlane.y * worldcoord.z) * uSplitTopPlane.z) - worldcoord.y;
|
gl_ClipDistance[3] = ((uSplitTopPlane.w + uSplitTopPlane.x * worldcoord.x + uSplitTopPlane.y * worldcoord.z) * uSplitTopPlane.z) - worldcoord.y;
|
||||||
gl_ClipDistance[4] = worldcoord.y + ((uSplitBottomPlane.w + uSplitBottomPlane.x * worldcoord.x + uSplitBottomPlane.y * worldcoord.z) * uSplitBottomPlane.z);
|
gl_ClipDistance[4] = worldcoord.y - ((uSplitBottomPlane.w + uSplitBottomPlane.x * worldcoord.x + uSplitBottomPlane.y * worldcoord.z) * uSplitBottomPlane.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
vWorldNormal = NormalModelMatrix * vec4(normalize(aNormal.xyz), 1.0);
|
vWorldNormal = NormalModelMatrix * vec4(normalize(aNormal.xyz), 1.0);
|
||||||
|
|
Loading…
Reference in a new issue