mirror of
https://github.com/ZDoom/qzdoom.git
synced 2025-03-17 00:11:05 +00:00
Merge commit 'refs/pull/495/head' of https://github.com/coelckers/gzdoom
This commit is contained in:
commit
c745e9f3e6
15 changed files with 885 additions and 307 deletions
|
@ -266,5 +266,7 @@ DEFINE_SPECIAL(Sector_SetFloorGlow, 277, 5, 5, 5)
|
|||
DEFINE_SPECIAL(Sector_SetCeilingGlow, 278, 5, 5, 5)
|
||||
DEFINE_SPECIAL(Floor_MoveToValueAndCrush, 279, 4, 5, 5)
|
||||
DEFINE_SPECIAL(Ceiling_MoveToValueAndCrush, 280, 4, 5, 5)
|
||||
DEFINE_SPECIAL(Line_SetAutomapFlags, 281, 3, 3, 3)
|
||||
DEFINE_SPECIAL(Line_SetAutomapStyle, 282, 2, 2, 2)
|
||||
|
||||
#undef DEFINE_SPECIAL
|
||||
|
|
|
@ -2730,6 +2730,7 @@ void D_DoomMain (void)
|
|||
ST_Clear();
|
||||
D_ErrorCleanup ();
|
||||
DThinker::DestroyThinkersInList(STAT_STATIC);
|
||||
E_Shutdown(false);
|
||||
P_FreeLevelData();
|
||||
P_FreeExtraLevelData();
|
||||
|
||||
|
@ -2775,6 +2776,8 @@ void D_DoomMain (void)
|
|||
restart++;
|
||||
PClass::bShutdown = false;
|
||||
PClass::bVMOperational = false;
|
||||
|
||||
gamestate = GS_STARTUP;
|
||||
}
|
||||
while (1);
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ bool FDynLightData::GetLight(int group, Plane & p, ADynamicLight * light, bool c
|
|||
return false;
|
||||
}
|
||||
|
||||
AddLightToList(group, light);
|
||||
AddLightToList(group, light, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -72,7 +72,7 @@ bool FDynLightData::GetLight(int group, Plane & p, ADynamicLight * light, bool c
|
|||
// Add one dynamic light to the light data list
|
||||
//
|
||||
//==========================================================================
|
||||
void FDynLightData::AddLightToList(int group, ADynamicLight * light)
|
||||
void FDynLightData::AddLightToList(int group, ADynamicLight * light, bool forceAttenuate)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
|
@ -109,7 +109,7 @@ void FDynLightData::AddLightToList(int group, ADynamicLight * light)
|
|||
bool attenuate;
|
||||
|
||||
// Store attenuate flag in the sign bit of the float.
|
||||
if (gl_attenuate == -1) attenuate = !!(light->lightflags & LF_ATTENUATE);
|
||||
if (gl_attenuate == -1) attenuate = !!(light->lightflags & LF_ATTENUATE) || forceAttenuate;
|
||||
else attenuate = !!gl_attenuate;
|
||||
|
||||
if (attenuate) shadowIndex = -shadowIndex;
|
||||
|
|
|
@ -54,7 +54,7 @@ struct FDynLightData
|
|||
}
|
||||
|
||||
bool GetLight(int group, Plane & p, ADynamicLight * light, bool checkside);
|
||||
void AddLightToList(int group, ADynamicLight * light);
|
||||
void AddLightToList(int group, ADynamicLight * light, bool forceAttenuate);
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -220,7 +220,7 @@ void hw_GetDynModelLight(AActor *self, FDynLightData &modellightdata)
|
|||
{
|
||||
if (std::find(addedLights.begin(), addedLights.end(), light) == addedLights.end()) // Check if we already added this light from a different subsector
|
||||
{
|
||||
modellightdata.AddLightToList(group, light);
|
||||
modellightdata.AddLightToList(group, light, true);
|
||||
addedLights.Push(light);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2765,6 +2765,55 @@ FUNC(LS_Line_SetBlocking)
|
|||
return true;
|
||||
}
|
||||
|
||||
FUNC(LS_Line_SetAutomapFlags)
|
||||
// Line_SetAutomapFlags (id, setflags, clearflags)
|
||||
{
|
||||
static const int flagtrans[] =
|
||||
{
|
||||
ML_SECRET,
|
||||
ML_DONTDRAW,
|
||||
ML_MAPPED,
|
||||
ML_REVEALED,
|
||||
-1
|
||||
};
|
||||
|
||||
if (arg0 == 0) return false;
|
||||
|
||||
int setflags = 0;
|
||||
int clearflags = 0;
|
||||
|
||||
for (int i = 0; flagtrans[i] != -1; i++, arg1 >>= 1, arg2 >>= 1)
|
||||
{
|
||||
if (arg1 & 1) setflags |= flagtrans[i];
|
||||
if (arg2 & 1) clearflags |= flagtrans[i];
|
||||
}
|
||||
|
||||
FLineIdIterator itr(arg0);
|
||||
int line;
|
||||
while ((line = itr.Next()) >= 0)
|
||||
{
|
||||
level.lines[line].flags = (level.lines[line].flags & ~clearflags) | setflags;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
FUNC(LS_Line_SetAutomapStyle)
|
||||
// Line_SetAutomapStyle (id, style)
|
||||
{
|
||||
if (arg1 < AMLS_COUNT && arg1 >= 0)
|
||||
{
|
||||
FLineIdIterator itr(arg0);
|
||||
int line;
|
||||
while ((line = itr.Next()) >= 0)
|
||||
{
|
||||
level.lines[line].automapstyle = (AutomapLineStyle) arg1;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
FUNC(LS_ChangeCamera)
|
||||
|
@ -3713,6 +3762,8 @@ static lnSpecFunc LineSpecials[] =
|
|||
/* 278 */ LS_Sector_SetCeilingGlow,
|
||||
/* 279 */ LS_Floor_MoveToValueAndCrush,
|
||||
/* 280 */ LS_Ceiling_MoveToValueAndCrush,
|
||||
/* 281 */ LS_Line_SetAutomapFlags,
|
||||
/* 282 */ LS_Line_SetAutomapStyle,
|
||||
|
||||
|
||||
};
|
||||
|
|
|
@ -1163,7 +1163,8 @@ void ScreenTriangle::DrawSWRender(const TriDrawTriangleArgs *args, PolyTriangleT
|
|||
|
||||
// Draw the triangle:
|
||||
|
||||
auto drawfunc = (args->destBgra) ? DrawSpan32 : DrawSpan8;
|
||||
int bmode = (int)args->uniforms->BlendMode();
|
||||
auto drawfunc = args->destBgra ? ScreenTriangle::SpanDrawers32[bmode] : ScreenTriangle::SpanDrawers8[bmode];
|
||||
|
||||
float stepXW = args->gradientX.W;
|
||||
float v1X = args->v1->x;
|
||||
|
@ -1248,10 +1249,11 @@ void ScreenTriangle::DrawSWRender(const TriDrawTriangleArgs *args, PolyTriangleT
|
|||
}
|
||||
}
|
||||
|
||||
#ifndef NO_SSE
|
||||
|
||||
void ScreenTriangle::DrawSpan32(int y, int x0, int x1, const TriDrawTriangleArgs *args)
|
||||
template<typename ModeT>
|
||||
void DrawSpan32(int y, int x0, int x1, const TriDrawTriangleArgs *args)
|
||||
{
|
||||
using namespace TriScreenDrawerModes;
|
||||
|
||||
float v1X = args->v1->x;
|
||||
float v1Y = args->v1->y;
|
||||
float v1W = args->v1->w;
|
||||
|
@ -1267,9 +1269,13 @@ void ScreenTriangle::DrawSpan32(int y, int x0, int x1, const TriDrawTriangleArgs
|
|||
float posXV = v1V + stepXV * startX + args->gradientY.V * startY;
|
||||
|
||||
const uint32_t *texPixels = (const uint32_t*)args->uniforms->TexturePixels();
|
||||
const uint32_t *translation = (const uint32_t*)args->uniforms->Translation();
|
||||
int texWidth = args->uniforms->TextureWidth();
|
||||
int texHeight = args->uniforms->TextureHeight();
|
||||
|
||||
int fillcolor = args->uniforms->Color();
|
||||
int alpha = args->uniforms->SrcAlpha();
|
||||
|
||||
bool is_fixed_light = args->uniforms->FixedLight();
|
||||
uint32_t lightmask = is_fixed_light ? 0 : 0xffffffff;
|
||||
uint32_t light = args->uniforms->Light();
|
||||
|
@ -1281,163 +1287,376 @@ void ScreenTriangle::DrawSpan32(int y, int x0, int x1, const TriDrawTriangleArgs
|
|||
uint32_t *destLine = dest + args->pitch * y;
|
||||
|
||||
int x = x0;
|
||||
|
||||
#ifndef NO_SSE
|
||||
__m128i mfillcolor = _mm_set1_epi32(fillcolor);
|
||||
__m128i mcapcolor = _mm_unpacklo_epi8(mfillcolor, _mm_setzero_si128());
|
||||
__m128i malpha = _mm_set1_epi32(alpha);
|
||||
|
||||
int sseEnd = x0 + ((x1 - x0) & ~3);
|
||||
while (x < sseEnd)
|
||||
{
|
||||
uint32_t fgcolor[2];
|
||||
int32_t lightshade[2];
|
||||
__m128i fg;
|
||||
|
||||
float rcpW = 0x01000000 / posXW;
|
||||
int32_t u = (int32_t)(posXU * rcpW);
|
||||
int32_t v = (int32_t)(posXV * rcpW);
|
||||
uint32_t texelX = ((((uint32_t)u << 8) >> 16) * texWidth) >> 16;
|
||||
uint32_t texelY = ((((uint32_t)v << 8) >> 16) * texHeight) >> 16;
|
||||
fgcolor[0] = texPixels[texelX * texHeight + texelY];
|
||||
if (ModeT::SWFlags & SWSTYLEF_Fill)
|
||||
{
|
||||
fg = mfillcolor;
|
||||
}
|
||||
else if (ModeT::SWFlags & SWSTYLEF_FogBoundary)
|
||||
{
|
||||
fg = _mm_loadl_epi64((const __m128i*)(destLine + x));
|
||||
}
|
||||
else
|
||||
{
|
||||
float rcpW0 = 0x01000000 / posXW;
|
||||
float rcpW1 = 0x01000000 / (posXW + stepXW);
|
||||
|
||||
fixed_t lightpos = FRACUNIT - (int)(clamp(shade - MIN(24.0f / 32.0f, globVis * posXW), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT);
|
||||
lightpos = (lightpos & lightmask) | ((light << 8) & ~lightmask);
|
||||
lightshade[0] = lightpos >> 8;
|
||||
int32_t u0 = (int32_t)(posXU * rcpW0);
|
||||
int32_t u1 = (int32_t)((posXU + stepXU) * rcpW1);
|
||||
int32_t v0 = (int32_t)(posXV * rcpW0);
|
||||
int32_t v1 = (int32_t)((posXV + stepXV) * rcpW1);
|
||||
uint32_t texelX0 = ((((uint32_t)u0 << 8) >> 16) * texWidth) >> 16;
|
||||
uint32_t texelX1 = ((((uint32_t)u1 << 8) >> 16) * texWidth) >> 16;
|
||||
uint32_t texelY0 = ((((uint32_t)v0 << 8) >> 16) * texHeight) >> 16;
|
||||
uint32_t texelY1 = ((((uint32_t)v1 << 8) >> 16) * texHeight) >> 16;
|
||||
|
||||
posXW += stepXW;
|
||||
posXU += stepXU;
|
||||
posXV += stepXV;
|
||||
if (ModeT::SWFlags & SWSTYLEF_Translated)
|
||||
{
|
||||
uint32_t fg0 = translation[((const uint8_t*)texPixels)[texelX0 * texHeight + texelY0]];
|
||||
uint32_t fg1 = translation[((const uint8_t*)texPixels)[texelX1 * texHeight + texelY1]];
|
||||
fg = _mm_setr_epi32(fg0, fg1, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t fg0 = texPixels[texelX0 * texHeight + texelY0];
|
||||
uint32_t fg1 = texPixels[texelX1 * texHeight + texelY1];
|
||||
fg = _mm_setr_epi32(fg0, fg1, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
rcpW = 0x01000000 / posXW;
|
||||
u = (int32_t)(posXU * rcpW);
|
||||
v = (int32_t)(posXV * rcpW);
|
||||
texelX = ((((uint32_t)u << 8) >> 16) * texWidth) >> 16;
|
||||
texelY = ((((uint32_t)v << 8) >> 16) * texHeight) >> 16;
|
||||
fgcolor[1] = texPixels[texelX * texHeight + texelY];
|
||||
if (ModeT::SWFlags & SWSTYLEF_Skycap)
|
||||
{
|
||||
float rcpW0 = 0x01000000 / posXW;
|
||||
float rcpW1 = 0x01000000 / (posXW + stepXW);
|
||||
int32_t v0 = (int32_t)(posXV * rcpW0);
|
||||
int32_t v1 = (int32_t)((posXV + stepXV) * rcpW1);
|
||||
|
||||
lightpos = FRACUNIT - (int)(clamp(shade - MIN(24.0f / 32.0f, globVis * posXW), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT);
|
||||
lightpos = (lightpos & lightmask) | ((light << 8) & ~lightmask);
|
||||
lightshade[1] = lightpos >> 8;
|
||||
int start_fade = 2; // How fast it should fade out
|
||||
__m128i v = _mm_setr_epi32(v0, v0, v1, v1);
|
||||
__m128i alpha_top = _mm_min_epi16(_mm_max_epi16(_mm_srai_epi32(v, 16 - start_fade), _mm_setzero_si128()), _mm_set1_epi16(256));
|
||||
__m128i alpha_bottom = _mm_min_epi16(_mm_max_epi16(_mm_srai_epi32(_mm_sub_epi32(_mm_set1_epi32(2 << 24), v), 16 - start_fade), _mm_setzero_si128()), _mm_set1_epi16(256));
|
||||
__m128i a = _mm_min_epi16(alpha_top, alpha_bottom);
|
||||
a = _mm_shufflelo_epi16(_mm_shufflehi_epi16(a, _MM_SHUFFLE(0, 0, 0, 0)), _MM_SHUFFLE(0, 0, 0, 0));
|
||||
__m128i inv_a = _mm_sub_epi32(_mm_set1_epi32(256), a);
|
||||
|
||||
posXW += stepXW;
|
||||
posXU += stepXU;
|
||||
posXV += stepXV;
|
||||
fg = _mm_unpacklo_epi8(fg, _mm_setzero_si128());
|
||||
__m128i c = _mm_srli_epi16(_mm_add_epi16(_mm_add_epi16(_mm_mullo_epi16(fg, a), _mm_mullo_epi16(mcapcolor, inv_a)), _mm_set1_epi16(127)), 8);
|
||||
_mm_storel_epi64((__m128i*)(destLine + x), _mm_packus_epi16(c, c));
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((ModeT::Flags & STYLEF_ColorIsFixed) && !(ModeT::SWFlags & SWSTYLEF_Fill))
|
||||
{
|
||||
__m128i rgbmask = _mm_set1_epi32(0x00ffffff);
|
||||
if (ModeT::Flags & STYLEF_RedIsAlpha)
|
||||
fg = _mm_or_si128(_mm_andnot_si128(rgbmask, _mm_slli_epi32(fg, 8)), _mm_and_si128(rgbmask, mfillcolor));
|
||||
else
|
||||
fg = _mm_or_si128(_mm_andnot_si128(rgbmask, fg), _mm_and_si128(rgbmask, mfillcolor));
|
||||
}
|
||||
|
||||
__m128i mfgcolor = _mm_loadl_epi64((const __m128i*)fgcolor);
|
||||
mfgcolor = _mm_unpacklo_epi8(mfgcolor, _mm_setzero_si128());
|
||||
if (!(ModeT::Flags & STYLEF_Alpha1))
|
||||
{
|
||||
__m128i a = _mm_srli_epi32(fg, 24);
|
||||
a = _mm_srli_epi32(_mm_mullo_epi16(a, malpha), 8);
|
||||
fg = _mm_or_si128(_mm_and_si128(fg, _mm_set1_epi32(0x00ffffff)), _mm_slli_epi32(a, 24));
|
||||
}
|
||||
|
||||
__m128i mlightshade = _mm_loadl_epi64((const __m128i*)lightshade);
|
||||
mlightshade = _mm_shuffle_epi32(mlightshade, _MM_SHUFFLE(1, 0, 1, 0));
|
||||
mlightshade = _mm_packs_epi32(mlightshade, mlightshade);
|
||||
fg = _mm_unpacklo_epi8(fg, _mm_setzero_si128());
|
||||
|
||||
__m128i mdestcolor = _mm_srli_epi16(_mm_mullo_epi16(mfgcolor, mlightshade), 8);
|
||||
mdestcolor = _mm_packus_epi16(mdestcolor, _mm_setzero_si128());
|
||||
mdestcolor = _mm_or_si128(mdestcolor, _mm_set1_epi32(0xff000000));
|
||||
fixed_t lightpos0 = FRACUNIT - (int)(clamp(shade - MIN(24.0f / 32.0f, globVis * posXW), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT);
|
||||
fixed_t lightpos1 = FRACUNIT - (int)(clamp(shade - MIN(24.0f / 32.0f, globVis * (posXW + stepXW)), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT);
|
||||
lightpos0 = (lightpos0 & lightmask) | ((light << 8) & ~lightmask);
|
||||
lightpos1 = (lightpos1 & lightmask) | ((light << 8) & ~lightmask);
|
||||
int lightshade0 = lightpos0 >> 8;
|
||||
int lightshade1 = lightpos1 >> 8;
|
||||
__m128i shadedfg = _mm_srli_epi16(_mm_mullo_epi16(fg, _mm_setr_epi16(lightshade0, lightshade0, lightshade0, 256, lightshade1, lightshade1, lightshade1, 256)), 8);
|
||||
|
||||
_mm_storel_epi64((__m128i*)(destLine + x), mdestcolor);
|
||||
__m128i out;
|
||||
if (ModeT::BlendSrc == STYLEALPHA_One && ModeT::BlendDest == STYLEALPHA_Zero)
|
||||
{
|
||||
out = shadedfg;
|
||||
}
|
||||
else if (ModeT::BlendSrc == STYLEALPHA_One && ModeT::BlendDest == STYLEALPHA_One)
|
||||
{
|
||||
__m128i dest = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i*)(destLine + x)), _mm_setzero_si128());
|
||||
if (ModeT::BlendOp == STYLEOP_Add)
|
||||
{
|
||||
out = _mm_add_epi16(dest, shadedfg);
|
||||
}
|
||||
else if (ModeT::BlendOp == STYLEOP_RevSub)
|
||||
{
|
||||
out = _mm_sub_epi16(dest, shadedfg);
|
||||
}
|
||||
else //if (ModeT::BlendOp == STYLEOP_Sub)
|
||||
{
|
||||
out = _mm_sub_epi16(shadedfg, dest);
|
||||
}
|
||||
}
|
||||
else if (ModeT::SWFlags & SWSTYLEF_SrcColorOneMinusSrcColor)
|
||||
{
|
||||
__m128i dest = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i*)(destLine + x)), _mm_setzero_si128());
|
||||
__m128i sfactor = _mm_add_epi16(shadedfg, _mm_srli_epi16(shadedfg, 7));
|
||||
__m128i dfactor = _mm_sub_epi16(_mm_set1_epi16(256), sfactor);
|
||||
out = _mm_srli_epi16(_mm_add_epi16(_mm_add_epi16(_mm_mullo_epi16(dest, dfactor), _mm_mullo_epi16(shadedfg, sfactor)), _mm_set1_epi16(127)), 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
__m128i dest = _mm_unpacklo_epi8(_mm_loadl_epi64((const __m128i*)(destLine + x)), _mm_setzero_si128());
|
||||
|
||||
__m128i sfactor = _mm_shufflehi_epi16(_mm_shufflelo_epi16(shadedfg, _MM_SHUFFLE(3, 3, 3, 3)), _MM_SHUFFLE(3, 3, 3, 3));
|
||||
sfactor = _mm_add_epi16(sfactor, _mm_srli_epi16(sfactor, 7)); // 255 -> 256
|
||||
__m128i dfactor = _mm_sub_epi16(_mm_set1_epi16(256), sfactor);
|
||||
__m128i src = _mm_mullo_epi16(shadedfg, sfactor);
|
||||
if (ModeT::BlendDest == STYLEALPHA_One)
|
||||
{
|
||||
dest = _mm_slli_epi16(dest, 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
__m128i dfactor = _mm_sub_epi16(_mm_set1_epi16(256), sfactor);
|
||||
dest = _mm_mullo_epi16(dest, dfactor);
|
||||
}
|
||||
|
||||
if (ModeT::BlendOp == STYLEOP_Add)
|
||||
{
|
||||
out = _mm_srli_epi16(_mm_add_epi16(_mm_add_epi16(dest, src), _mm_set1_epi16(127)), 8);
|
||||
}
|
||||
else if (ModeT::BlendOp == STYLEOP_RevSub)
|
||||
{
|
||||
out = _mm_srli_epi16(_mm_add_epi16(_mm_sub_epi16(dest, src), _mm_set1_epi16(127)), 8);
|
||||
}
|
||||
else //if (ModeT::BlendOp == STYLEOP_Sub)
|
||||
{
|
||||
out = _mm_srli_epi16(_mm_add_epi16(_mm_sub_epi16(src, dest), _mm_set1_epi16(127)), 8);
|
||||
}
|
||||
}
|
||||
_mm_storel_epi64((__m128i*)(destLine + x), _mm_or_si128(_mm_packus_epi16(out, out), _mm_set1_epi32(0xff000000)));
|
||||
}
|
||||
|
||||
posXW += stepXW + stepXW;
|
||||
posXU += stepXU + stepXU;
|
||||
posXV += stepXV + stepXV;
|
||||
x += 2;
|
||||
}
|
||||
|
||||
while (x < x1)
|
||||
{
|
||||
float rcpW = 0x01000000 / posXW;
|
||||
int32_t u = (int32_t)(posXU * rcpW);
|
||||
int32_t v = (int32_t)(posXV * rcpW);
|
||||
|
||||
uint32_t texelX = ((((uint32_t)u << 8) >> 16) * texWidth) >> 16;
|
||||
uint32_t texelY = ((((uint32_t)v << 8) >> 16) * texHeight) >> 16;
|
||||
uint32_t fgcolor = texPixels[texelX * texHeight + texelY];
|
||||
|
||||
uint32_t fgcolor_r = RPART(fgcolor);
|
||||
uint32_t fgcolor_g = GPART(fgcolor);
|
||||
uint32_t fgcolor_b = BPART(fgcolor);
|
||||
uint32_t fgcolor_a = APART(fgcolor);
|
||||
if (fgcolor_a > 127)
|
||||
{
|
||||
fixed_t lightpos = FRACUNIT - (int)(clamp(shade - MIN(24.0f / 32.0f, globVis * posXW), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT);
|
||||
lightpos = (lightpos & lightmask) | ((light << 8) & ~lightmask);
|
||||
int lightshade = lightpos >> 8;
|
||||
|
||||
fgcolor_r = (fgcolor_r * lightshade) >> 8;
|
||||
fgcolor_g = (fgcolor_g * lightshade) >> 8;
|
||||
fgcolor_b = (fgcolor_b * lightshade) >> 8;
|
||||
|
||||
destLine[x] = 0xff000000 | (fgcolor_r << 16) | (fgcolor_g << 8) | fgcolor_b;
|
||||
}
|
||||
|
||||
posXW += stepXW;
|
||||
posXU += stepXU;
|
||||
posXV += stepXV;
|
||||
x++;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void ScreenTriangle::DrawSpan32(int y, int x0, int x1, const TriDrawTriangleArgs *args)
|
||||
{
|
||||
float v1X = args->v1->x;
|
||||
float v1Y = args->v1->y;
|
||||
float v1W = args->v1->w;
|
||||
float v1U = args->v1->u * v1W;
|
||||
float v1V = args->v1->v * v1W;
|
||||
float stepXW = args->gradientX.W;
|
||||
float stepXU = args->gradientX.U;
|
||||
float stepXV = args->gradientX.V;
|
||||
float startX = x0 + (0.5f - v1X);
|
||||
float startY = y + (0.5f - v1Y);
|
||||
float posXW = v1W + stepXW * startX + args->gradientY.W * startY;
|
||||
float posXU = v1U + stepXU * startX + args->gradientY.U * startY;
|
||||
float posXV = v1V + stepXV * startX + args->gradientY.V * startY;
|
||||
|
||||
const uint32_t *texPixels = (const uint32_t*)args->uniforms->TexturePixels();
|
||||
int texWidth = args->uniforms->TextureWidth();
|
||||
int texHeight = args->uniforms->TextureHeight();
|
||||
|
||||
bool is_fixed_light = args->uniforms->FixedLight();
|
||||
uint32_t lightmask = is_fixed_light ? 0 : 0xffffffff;
|
||||
uint32_t light = args->uniforms->Light();
|
||||
float shade = 2.0f - (light + 12.0f) / 128.0f;
|
||||
float globVis = args->uniforms->GlobVis() * (1.0f / 32.0f);
|
||||
light += light >> 7; // 255 -> 256
|
||||
|
||||
uint32_t *dest = (uint32_t*)args->dest;
|
||||
uint32_t *destLine = dest + args->pitch * y;
|
||||
|
||||
int x = x0;
|
||||
while (x < x1)
|
||||
{
|
||||
float rcpW = 0x01000000 / posXW;
|
||||
int32_t u = (int32_t)(posXU * rcpW);
|
||||
int32_t v = (int32_t)(posXV * rcpW);
|
||||
|
||||
uint32_t texelX = ((((uint32_t)u << 8) >> 16) * texWidth) >> 16;
|
||||
uint32_t texelY = ((((uint32_t)v << 8) >> 16) * texHeight) >> 16;
|
||||
uint32_t fgcolor = texPixels[texelX * texHeight + texelY];
|
||||
|
||||
uint32_t fgcolor_r = RPART(fgcolor);
|
||||
uint32_t fgcolor_g = GPART(fgcolor);
|
||||
uint32_t fgcolor_b = BPART(fgcolor);
|
||||
uint32_t fgcolor_a = APART(fgcolor);
|
||||
if (fgcolor_a > 127)
|
||||
{
|
||||
fixed_t lightpos = FRACUNIT - (int)(clamp(shade - MIN(24.0f / 32.0f, globVis * posXW), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT);
|
||||
lightpos = (lightpos & lightmask) | ((light << 8) & ~lightmask);
|
||||
int lightshade = lightpos >> 8;
|
||||
|
||||
fgcolor_r = (fgcolor_r * lightshade) >> 8;
|
||||
fgcolor_g = (fgcolor_g * lightshade) >> 8;
|
||||
fgcolor_b = (fgcolor_b * lightshade) >> 8;
|
||||
|
||||
destLine[x] = 0xff000000 | (fgcolor_r << 16) | (fgcolor_g << 8) | fgcolor_b;
|
||||
}
|
||||
|
||||
posXW += stepXW;
|
||||
posXU += stepXU;
|
||||
posXV += stepXV;
|
||||
x++;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void ScreenTriangle::DrawSpan8(int y, int x0, int x1, const TriDrawTriangleArgs *args)
|
||||
while (x < x1)
|
||||
{
|
||||
uint32_t fg;
|
||||
|
||||
if (ModeT::SWFlags & SWSTYLEF_Fill)
|
||||
{
|
||||
fg = fillcolor;
|
||||
}
|
||||
else if (ModeT::SWFlags & SWSTYLEF_FogBoundary)
|
||||
{
|
||||
fg = destLine[x];
|
||||
}
|
||||
else
|
||||
{
|
||||
float rcpW = 0x01000000 / posXW;
|
||||
int32_t u = (int32_t)(posXU * rcpW);
|
||||
int32_t v = (int32_t)(posXV * rcpW);
|
||||
uint32_t texelX = ((((uint32_t)u << 8) >> 16) * texWidth) >> 16;
|
||||
uint32_t texelY = ((((uint32_t)v << 8) >> 16) * texHeight) >> 16;
|
||||
|
||||
if (ModeT::SWFlags & SWSTYLEF_Translated)
|
||||
{
|
||||
fg = translation[((const uint8_t*)texPixels)[texelX * texHeight + texelY]];
|
||||
}
|
||||
else
|
||||
{
|
||||
fg = texPixels[texelX * texHeight + texelY];
|
||||
}
|
||||
}
|
||||
|
||||
if (ModeT::SWFlags & SWSTYLEF_Skycap)
|
||||
{
|
||||
float rcpW = 0x01000000 / posXW;
|
||||
int32_t v = (int32_t)(posXV * rcpW);
|
||||
|
||||
int start_fade = 2; // How fast it should fade out
|
||||
int alpha_top = clamp(v >> (16 - start_fade), 0, 256);
|
||||
int alpha_bottom = clamp(((2 << 24) - v) >> (16 - start_fade), 0, 256);
|
||||
int a = MIN(alpha_top, alpha_bottom);
|
||||
int inv_a = 256 - a;
|
||||
|
||||
if (a == 256)
|
||||
{
|
||||
destLine[x] = fg;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t r = RPART(fg);
|
||||
uint32_t g = GPART(fg);
|
||||
uint32_t b = BPART(fg);
|
||||
uint32_t fg_a = APART(fg);
|
||||
uint32_t bg_red = RPART(fillcolor);
|
||||
uint32_t bg_green = GPART(fillcolor);
|
||||
uint32_t bg_blue = BPART(fillcolor);
|
||||
r = (r * a + bg_red * inv_a + 127) >> 8;
|
||||
g = (g * a + bg_green * inv_a + 127) >> 8;
|
||||
b = (b * a + bg_blue * inv_a + 127) >> 8;
|
||||
|
||||
destLine[x] = MAKEARGB(255, r, g, b);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((ModeT::Flags & STYLEF_ColorIsFixed) && !(ModeT::SWFlags & SWSTYLEF_Fill))
|
||||
{
|
||||
if (ModeT::Flags & STYLEF_RedIsAlpha)
|
||||
fg = ((fg << 8) & 0xff000000) | (fillcolor & 0x00ffffff);
|
||||
else
|
||||
fg = (fg & 0xff000000) | (fillcolor & 0x00ffffff);
|
||||
}
|
||||
|
||||
uint32_t fgalpha = fg >> 24;
|
||||
|
||||
if (!(ModeT::Flags & STYLEF_Alpha1))
|
||||
{
|
||||
fgalpha = (fgalpha * alpha) >> 8;
|
||||
}
|
||||
|
||||
fixed_t lightpos = FRACUNIT - (int)(clamp(shade - MIN(24.0f / 32.0f, globVis * posXW), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT);
|
||||
lightpos = (lightpos & lightmask) | ((light << 8) & ~lightmask);
|
||||
int lightshade = lightpos >> 8;
|
||||
uint32_t shadedfg_r = (RPART(fg) * lightshade) >> 8;
|
||||
uint32_t shadedfg_g = (GPART(fg) * lightshade) >> 8;
|
||||
uint32_t shadedfg_b = (BPART(fg) * lightshade) >> 8;
|
||||
|
||||
if (ModeT::BlendSrc == STYLEALPHA_One && ModeT::BlendDest == STYLEALPHA_Zero)
|
||||
{
|
||||
destLine[x] = MAKEARGB(255, shadedfg_r, shadedfg_g, shadedfg_b);
|
||||
}
|
||||
else if (ModeT::BlendSrc == STYLEALPHA_One && ModeT::BlendDest == STYLEALPHA_One)
|
||||
{
|
||||
uint32_t dest = destLine[x];
|
||||
|
||||
if (ModeT::BlendOp == STYLEOP_Add)
|
||||
{
|
||||
uint32_t out_r = MIN<uint32_t>(RPART(dest) + shadedfg_r, 255);
|
||||
uint32_t out_g = MIN<uint32_t>(GPART(dest) + shadedfg_g, 255);
|
||||
uint32_t out_b = MIN<uint32_t>(BPART(dest) + shadedfg_b, 255);
|
||||
destLine[x] = MAKEARGB(255, out_r, out_g, out_b);
|
||||
}
|
||||
else if (ModeT::BlendOp == STYLEOP_RevSub)
|
||||
{
|
||||
uint32_t out_r = MAX<uint32_t>(RPART(dest) - shadedfg_r, 0);
|
||||
uint32_t out_g = MAX<uint32_t>(GPART(dest) - shadedfg_g, 0);
|
||||
uint32_t out_b = MAX<uint32_t>(BPART(dest) - shadedfg_b, 0);
|
||||
destLine[x] = MAKEARGB(255, out_r, out_g, out_b);
|
||||
}
|
||||
else //if (ModeT::BlendOp == STYLEOP_Sub)
|
||||
{
|
||||
uint32_t out_r = MAX<uint32_t>(shadedfg_r - RPART(dest), 0);
|
||||
uint32_t out_g = MAX<uint32_t>(shadedfg_g - GPART(dest), 0);
|
||||
uint32_t out_b = MAX<uint32_t>(shadedfg_b - BPART(dest), 0);
|
||||
destLine[x] = MAKEARGB(255, out_r, out_g, out_b);
|
||||
}
|
||||
}
|
||||
else if (ModeT::SWFlags & SWSTYLEF_SrcColorOneMinusSrcColor)
|
||||
{
|
||||
uint32_t dest = destLine[x];
|
||||
|
||||
uint32_t sfactor_r = shadedfg_r; sfactor_r += sfactor_r >> 7; // 255 -> 256
|
||||
uint32_t sfactor_g = shadedfg_g; sfactor_g += sfactor_g >> 7; // 255 -> 256
|
||||
uint32_t sfactor_b = shadedfg_b; sfactor_b += sfactor_b >> 7; // 255 -> 256
|
||||
uint32_t sfactor_a = fgalpha; sfactor_a += sfactor_a >> 7; // 255 -> 256
|
||||
uint32_t dfactor_r = 256 - sfactor_r;
|
||||
uint32_t dfactor_g = 256 - sfactor_g;
|
||||
uint32_t dfactor_b = 256 - sfactor_b;
|
||||
uint32_t out_r = (RPART(dest) * dfactor_r + shadedfg_r * sfactor_r + 128) >> 8;
|
||||
uint32_t out_g = (GPART(dest) * dfactor_g + shadedfg_g * sfactor_g + 128) >> 8;
|
||||
uint32_t out_b = (BPART(dest) * dfactor_b + shadedfg_b * sfactor_b + 128) >> 8;
|
||||
|
||||
destLine[x] = MAKEARGB(255, out_r, out_g, out_b);
|
||||
}
|
||||
else if (fgalpha == 255)
|
||||
{
|
||||
destLine[x] = MAKEARGB(255, shadedfg_r, shadedfg_g, shadedfg_b);
|
||||
}
|
||||
else if (fgalpha != 0)
|
||||
{
|
||||
uint32_t dest = destLine[x];
|
||||
|
||||
uint32_t sfactor = fgalpha; sfactor += sfactor >> 7; // 255 -> 256
|
||||
uint32_t dfactor = 256 - sfactor;
|
||||
uint32_t src_r = shadedfg_r * sfactor;
|
||||
uint32_t src_g = shadedfg_g * sfactor;
|
||||
uint32_t src_b = shadedfg_b * sfactor;
|
||||
uint32_t dest_r = RPART(dest);
|
||||
uint32_t dest_g = GPART(dest);
|
||||
uint32_t dest_b = BPART(dest);
|
||||
if (ModeT::BlendDest == STYLEALPHA_One)
|
||||
{
|
||||
dest_r <<= 8;
|
||||
dest_g <<= 8;
|
||||
dest_b <<= 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t dfactor = 256 - sfactor;
|
||||
dest_r *= dfactor;
|
||||
dest_g *= dfactor;
|
||||
dest_b *= dfactor;
|
||||
}
|
||||
|
||||
uint32_t out_r, out_g, out_b;
|
||||
if (ModeT::BlendOp == STYLEOP_Add)
|
||||
{
|
||||
if (ModeT::BlendDest == STYLEALPHA_One)
|
||||
{
|
||||
out_r = MIN<int32_t>((dest_r + src_r + 128) >> 8, 255);
|
||||
out_g = MIN<int32_t>((dest_g + src_g + 128) >> 8, 255);
|
||||
out_b = MIN<int32_t>((dest_b + src_b + 128) >> 8, 255);
|
||||
}
|
||||
else
|
||||
{
|
||||
out_r = (dest_r + src_r + 128) >> 8;
|
||||
out_g = (dest_g + src_g + 128) >> 8;
|
||||
out_b = (dest_b + src_b + 128) >> 8;
|
||||
}
|
||||
}
|
||||
else if (ModeT::BlendOp == STYLEOP_RevSub)
|
||||
{
|
||||
out_r = MAX<int32_t>(static_cast<int32_t>(dest_r - src_r + 128) >> 8, 0);
|
||||
out_g = MAX<int32_t>(static_cast<int32_t>(dest_g - src_g + 128) >> 8, 0);
|
||||
out_b = MAX<int32_t>(static_cast<int32_t>(dest_b - src_b + 128) >> 8, 0);
|
||||
}
|
||||
else //if (ModeT::BlendOp == STYLEOP_Sub)
|
||||
{
|
||||
out_r = MAX<int32_t>(static_cast<int32_t>(src_r - dest_r + 128) >> 8, 0);
|
||||
out_g = MAX<int32_t>(static_cast<int32_t>(src_g - dest_g + 128) >> 8, 0);
|
||||
out_b = MAX<int32_t>(static_cast<int32_t>(src_b - dest_b + 128) >> 8, 0);
|
||||
}
|
||||
|
||||
destLine[x] = MAKEARGB(255, out_r, out_g, out_b);
|
||||
}
|
||||
}
|
||||
|
||||
posXW += stepXW;
|
||||
posXU += stepXU;
|
||||
posXV += stepXV;
|
||||
x++;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename ModeT>
|
||||
void DrawSpan8(int y, int x0, int x1, const TriDrawTriangleArgs *args)
|
||||
{
|
||||
using namespace TriScreenDrawerModes;
|
||||
|
||||
float v1X = args->v1->x;
|
||||
float v1Y = args->v1->y;
|
||||
float v1W = args->v1->w;
|
||||
|
@ -1455,9 +1674,17 @@ void ScreenTriangle::DrawSpan8(int y, int x0, int x1, const TriDrawTriangleArgs
|
|||
auto colormaps = args->uniforms->BaseColormap();
|
||||
|
||||
const uint8_t *texPixels = args->uniforms->TexturePixels();
|
||||
const uint8_t *translation = args->uniforms->Translation();
|
||||
int texWidth = args->uniforms->TextureWidth();
|
||||
int texHeight = args->uniforms->TextureHeight();
|
||||
|
||||
int fillcolor = args->uniforms->Color();
|
||||
int alpha = args->uniforms->SrcAlpha();
|
||||
|
||||
uint32_t capcolor = fillcolor;
|
||||
if (ModeT::SWFlags & SWSTYLEF_Skycap)
|
||||
capcolor = GPalette.BaseColors[capcolor].d;
|
||||
|
||||
bool is_fixed_light = args->uniforms->FixedLight();
|
||||
uint32_t lightmask = is_fixed_light ? 0 : 0xffffffff;
|
||||
uint32_t light = args->uniforms->Light();
|
||||
|
@ -1471,23 +1698,197 @@ void ScreenTriangle::DrawSpan8(int y, int x0, int x1, const TriDrawTriangleArgs
|
|||
int x = x0;
|
||||
while (x < x1)
|
||||
{
|
||||
float rcpW = 0x01000000 / posXW;
|
||||
int32_t u = (int32_t)(posXU * rcpW);
|
||||
int32_t v = (int32_t)(posXV * rcpW);
|
||||
int fg;
|
||||
int fgalpha = 255;
|
||||
|
||||
uint32_t texelX = ((((uint32_t)u << 8) >> 16) * texWidth) >> 16;
|
||||
uint32_t texelY = ((((uint32_t)v << 8) >> 16) * texHeight) >> 16;
|
||||
uint8_t fgcolor = texPixels[texelX * texHeight + texelY];
|
||||
if (ModeT::SWFlags & SWSTYLEF_Fill)
|
||||
{
|
||||
fg = fillcolor;
|
||||
}
|
||||
else if (ModeT::SWFlags & SWSTYLEF_FogBoundary)
|
||||
{
|
||||
fg = destLine[x];
|
||||
}
|
||||
else
|
||||
{
|
||||
float rcpW = 0x01000000 / posXW;
|
||||
int32_t u = (int32_t)(posXU * rcpW);
|
||||
int32_t v = (int32_t)(posXV * rcpW);
|
||||
uint32_t texelX = ((((uint32_t)u << 8) >> 16) * texWidth) >> 16;
|
||||
uint32_t texelY = ((((uint32_t)v << 8) >> 16) * texHeight) >> 16;
|
||||
fg = texPixels[texelX * texHeight + texelY];
|
||||
|
||||
fixed_t lightpos = FRACUNIT - (int)(clamp(shade - MIN(24.0f / 32.0f, globVis * posXW), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT);
|
||||
lightpos = (lightpos & lightmask) | ((light << 8) & ~lightmask);
|
||||
int lightshade = lightpos >> 8;
|
||||
if (ModeT::SWFlags & SWSTYLEF_Translated)
|
||||
fg = translation[fg];
|
||||
|
||||
lightshade = ((256 - lightshade) * NUMCOLORMAPS) & 0xffffff00;
|
||||
uint8_t shadedfg = colormaps[lightshade + fgcolor];
|
||||
fgalpha = (fg != 0) ? 255 : 0;
|
||||
}
|
||||
|
||||
if (fgcolor != 0)
|
||||
destLine[x] = shadedfg;
|
||||
if (ModeT::SWFlags & SWSTYLEF_Skycap)
|
||||
{
|
||||
float rcpW = 0x01000000 / posXW;
|
||||
int32_t v = (int32_t)(posXV * rcpW);
|
||||
|
||||
int start_fade = 2; // How fast it should fade out
|
||||
int alpha_top = clamp(v >> (16 - start_fade), 0, 256);
|
||||
int alpha_bottom = clamp(((2 << 24) - v) >> (16 - start_fade), 0, 256);
|
||||
int a = MIN(alpha_top, alpha_bottom);
|
||||
int inv_a = 256 - a;
|
||||
|
||||
if (a == 256)
|
||||
{
|
||||
destLine[x] = fg;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t texelrgb = GPalette.BaseColors[fg].d;
|
||||
|
||||
uint32_t r = RPART(texelrgb);
|
||||
uint32_t g = GPART(texelrgb);
|
||||
uint32_t b = BPART(texelrgb);
|
||||
uint32_t fg_a = APART(texelrgb);
|
||||
uint32_t bg_red = RPART(capcolor);
|
||||
uint32_t bg_green = GPART(capcolor);
|
||||
uint32_t bg_blue = BPART(capcolor);
|
||||
r = (r * a + bg_red * inv_a + 127) >> 8;
|
||||
g = (g * a + bg_green * inv_a + 127) >> 8;
|
||||
b = (b * a + bg_blue * inv_a + 127) >> 8;
|
||||
|
||||
destLine[x] = RGB256k.All[((r >> 2) << 12) | ((g >> 2) << 6) | (b >> 2)];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((ModeT::Flags & STYLEF_ColorIsFixed) && !(ModeT::SWFlags & SWSTYLEF_Fill))
|
||||
{
|
||||
if (ModeT::Flags & STYLEF_RedIsAlpha)
|
||||
fgalpha = fg;
|
||||
fg = fillcolor;
|
||||
}
|
||||
|
||||
if (!(ModeT::Flags & STYLEF_Alpha1))
|
||||
{
|
||||
fgalpha = (fgalpha * alpha) >> 8;
|
||||
}
|
||||
|
||||
fixed_t lightpos = FRACUNIT - (int)(clamp(shade - MIN(24.0f / 32.0f, globVis * posXW), 0.0f, 31.0f / 32.0f) * (float)FRACUNIT);
|
||||
lightpos = (lightpos & lightmask) | ((light << 8) & ~lightmask);
|
||||
int lightshade = lightpos >> 8;
|
||||
lightshade = ((256 - lightshade) * NUMCOLORMAPS) & 0xffffff00;
|
||||
uint8_t shadedfg = colormaps[lightshade + fg];
|
||||
|
||||
if (ModeT::BlendSrc == STYLEALPHA_One && ModeT::BlendDest == STYLEALPHA_Zero)
|
||||
{
|
||||
destLine[x] = shadedfg;
|
||||
}
|
||||
else if (ModeT::BlendSrc == STYLEALPHA_One && ModeT::BlendDest == STYLEALPHA_One)
|
||||
{
|
||||
uint32_t src = GPalette.BaseColors[shadedfg];
|
||||
uint32_t dest = GPalette.BaseColors[destLine[x]];
|
||||
|
||||
if (ModeT::BlendOp == STYLEOP_Add)
|
||||
{
|
||||
uint32_t out_r = MIN<uint32_t>(RPART(dest) + RPART(src), 255);
|
||||
uint32_t out_g = MIN<uint32_t>(GPART(dest) + GPART(src), 255);
|
||||
uint32_t out_b = MIN<uint32_t>(BPART(dest) + BPART(src), 255);
|
||||
destLine[x] = RGB256k.All[((out_r >> 2) << 12) | ((out_g >> 2) << 6) | (out_b >> 2)];
|
||||
}
|
||||
else if (ModeT::BlendOp == STYLEOP_RevSub)
|
||||
{
|
||||
uint32_t out_r = MAX<uint32_t>(RPART(dest) - RPART(src), 0);
|
||||
uint32_t out_g = MAX<uint32_t>(GPART(dest) - GPART(src), 0);
|
||||
uint32_t out_b = MAX<uint32_t>(BPART(dest) - BPART(src), 0);
|
||||
destLine[x] = RGB256k.All[((out_r >> 2) << 12) | ((out_g >> 2) << 6) | (out_b >> 2)];
|
||||
}
|
||||
else //if (ModeT::BlendOp == STYLEOP_Sub)
|
||||
{
|
||||
uint32_t out_r = MAX<uint32_t>(RPART(src) - RPART(dest), 0);
|
||||
uint32_t out_g = MAX<uint32_t>(GPART(src) - GPART(dest), 0);
|
||||
uint32_t out_b = MAX<uint32_t>(BPART(src) - BPART(dest), 0);
|
||||
destLine[x] = RGB256k.All[((out_r >> 2) << 12) | ((out_g >> 2) << 6) | (out_b >> 2)];
|
||||
}
|
||||
}
|
||||
else if (ModeT::SWFlags & SWSTYLEF_SrcColorOneMinusSrcColor)
|
||||
{
|
||||
uint32_t src = GPalette.BaseColors[shadedfg];
|
||||
uint32_t dest = GPalette.BaseColors[destLine[x]];
|
||||
|
||||
uint32_t sfactor_r = RPART(src); sfactor_r += sfactor_r >> 7; // 255 -> 256
|
||||
uint32_t sfactor_g = GPART(src); sfactor_g += sfactor_g >> 7; // 255 -> 256
|
||||
uint32_t sfactor_b = BPART(src); sfactor_b += sfactor_b >> 7; // 255 -> 256
|
||||
uint32_t sfactor_a = fgalpha; sfactor_a += sfactor_a >> 7; // 255 -> 256
|
||||
uint32_t dfactor_r = 256 - sfactor_r;
|
||||
uint32_t dfactor_g = 256 - sfactor_g;
|
||||
uint32_t dfactor_b = 256 - sfactor_b;
|
||||
uint32_t out_r = (RPART(dest) * dfactor_r + RPART(src) * sfactor_r + 128) >> 8;
|
||||
uint32_t out_g = (GPART(dest) * dfactor_g + GPART(src) * sfactor_g + 128) >> 8;
|
||||
uint32_t out_b = (BPART(dest) * dfactor_b + BPART(src) * sfactor_b + 128) >> 8;
|
||||
|
||||
destLine[x] = RGB256k.All[((out_r >> 2) << 12) | ((out_g >> 2) << 6) | (out_b >> 2)];
|
||||
}
|
||||
else if (fgalpha == 255)
|
||||
{
|
||||
destLine[x] = shadedfg;
|
||||
}
|
||||
else if (fgalpha != 0)
|
||||
{
|
||||
uint32_t src = GPalette.BaseColors[shadedfg];
|
||||
uint32_t dest = GPalette.BaseColors[destLine[x]];
|
||||
|
||||
uint32_t sfactor = fgalpha; sfactor += sfactor >> 7; // 255 -> 256
|
||||
uint32_t dfactor = 256 - sfactor;
|
||||
uint32_t src_r = RPART(src) * sfactor;
|
||||
uint32_t src_g = GPART(src) * sfactor;
|
||||
uint32_t src_b = BPART(src) * sfactor;
|
||||
uint32_t dest_r = RPART(dest);
|
||||
uint32_t dest_g = GPART(dest);
|
||||
uint32_t dest_b = BPART(dest);
|
||||
if (ModeT::BlendDest == STYLEALPHA_One)
|
||||
{
|
||||
dest_r <<= 8;
|
||||
dest_g <<= 8;
|
||||
dest_b <<= 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t dfactor = 256 - sfactor;
|
||||
dest_r *= dfactor;
|
||||
dest_g *= dfactor;
|
||||
dest_b *= dfactor;
|
||||
}
|
||||
|
||||
uint32_t out_r, out_g, out_b;
|
||||
if (ModeT::BlendOp == STYLEOP_Add)
|
||||
{
|
||||
if (ModeT::BlendDest == STYLEALPHA_One)
|
||||
{
|
||||
out_r = MIN<int32_t>((dest_r + src_r + 128) >> 8, 255);
|
||||
out_g = MIN<int32_t>((dest_g + src_g + 128) >> 8, 255);
|
||||
out_b = MIN<int32_t>((dest_b + src_b + 128) >> 8, 255);
|
||||
}
|
||||
else
|
||||
{
|
||||
out_r = (dest_r + src_r + 128) >> 8;
|
||||
out_g = (dest_g + src_g + 128) >> 8;
|
||||
out_b = (dest_b + src_b + 128) >> 8;
|
||||
}
|
||||
}
|
||||
else if (ModeT::BlendOp == STYLEOP_RevSub)
|
||||
{
|
||||
out_r = MAX<int32_t>(static_cast<int32_t>(dest_r - src_r + 128) >> 8, 0);
|
||||
out_g = MAX<int32_t>(static_cast<int32_t>(dest_g - src_g + 128) >> 8, 0);
|
||||
out_b = MAX<int32_t>(static_cast<int32_t>(dest_b - src_b + 128) >> 8, 0);
|
||||
}
|
||||
else //if (ModeT::BlendOp == STYLEOP_Sub)
|
||||
{
|
||||
out_r = MAX<int32_t>(static_cast<int32_t>(src_r - dest_r + 128) >> 8, 0);
|
||||
out_g = MAX<int32_t>(static_cast<int32_t>(src_g - dest_g + 128) >> 8, 0);
|
||||
out_b = MAX<int32_t>(static_cast<int32_t>(src_b - dest_b + 128) >> 8, 0);
|
||||
}
|
||||
|
||||
destLine[x] = RGB256k.All[((out_r >> 2) << 12) | ((out_g >> 2) << 6) | (out_b >> 2)];
|
||||
}
|
||||
}
|
||||
|
||||
posXW += stepXW;
|
||||
posXU += stepXU;
|
||||
|
@ -1496,6 +1897,70 @@ void ScreenTriangle::DrawSpan8(int y, int x0, int x1, const TriDrawTriangleArgs
|
|||
}
|
||||
}
|
||||
|
||||
void(*ScreenTriangle::SpanDrawers8[])(int, int, int, const TriDrawTriangleArgs *) =
|
||||
{
|
||||
&DrawSpan8<TriScreenDrawerModes::StyleOpaque>,
|
||||
&DrawSpan8<TriScreenDrawerModes::StyleSkycap>,
|
||||
&DrawSpan8<TriScreenDrawerModes::StyleFogBoundary>,
|
||||
&DrawSpan8<TriScreenDrawerModes::StyleSrcColor>,
|
||||
&DrawSpan8<TriScreenDrawerModes::StyleFill>,
|
||||
&DrawSpan8<TriScreenDrawerModes::StyleNormal>,
|
||||
&DrawSpan8<TriScreenDrawerModes::StyleFuzzy>,
|
||||
&DrawSpan8<TriScreenDrawerModes::StyleStencil>,
|
||||
&DrawSpan8<TriScreenDrawerModes::StyleTranslucent>,
|
||||
&DrawSpan8<TriScreenDrawerModes::StyleAdd>,
|
||||
&DrawSpan8<TriScreenDrawerModes::StyleShaded>,
|
||||
&DrawSpan8<TriScreenDrawerModes::StyleTranslucentStencil>,
|
||||
&DrawSpan8<TriScreenDrawerModes::StyleShadow>,
|
||||
&DrawSpan8<TriScreenDrawerModes::StyleSubtract>,
|
||||
&DrawSpan8<TriScreenDrawerModes::StyleAddStencil>,
|
||||
&DrawSpan8<TriScreenDrawerModes::StyleAddShaded>,
|
||||
&DrawSpan8<TriScreenDrawerModes::StyleOpaqueTranslated>,
|
||||
&DrawSpan8<TriScreenDrawerModes::StyleSrcColorTranslated>,
|
||||
&DrawSpan8<TriScreenDrawerModes::StyleNormalTranslated>,
|
||||
&DrawSpan8<TriScreenDrawerModes::StyleStencilTranslated>,
|
||||
&DrawSpan8<TriScreenDrawerModes::StyleTranslucentTranslated>,
|
||||
&DrawSpan8<TriScreenDrawerModes::StyleAddTranslated>,
|
||||
&DrawSpan8<TriScreenDrawerModes::StyleShadedTranslated>,
|
||||
&DrawSpan8<TriScreenDrawerModes::StyleTranslucentStencilTranslated>,
|
||||
&DrawSpan8<TriScreenDrawerModes::StyleShadowTranslated>,
|
||||
&DrawSpan8<TriScreenDrawerModes::StyleSubtractTranslated>,
|
||||
&DrawSpan8<TriScreenDrawerModes::StyleAddStencilTranslated>,
|
||||
&DrawSpan8<TriScreenDrawerModes::StyleAddShadedTranslated>
|
||||
};
|
||||
|
||||
void(*ScreenTriangle::SpanDrawers32[])(int, int, int, const TriDrawTriangleArgs *) =
|
||||
{
|
||||
&DrawSpan32<TriScreenDrawerModes::StyleOpaque>,
|
||||
&DrawSpan32<TriScreenDrawerModes::StyleSkycap>,
|
||||
&DrawSpan32<TriScreenDrawerModes::StyleFogBoundary>,
|
||||
&DrawSpan32<TriScreenDrawerModes::StyleSrcColor>,
|
||||
&DrawSpan32<TriScreenDrawerModes::StyleFill>,
|
||||
&DrawSpan32<TriScreenDrawerModes::StyleNormal>,
|
||||
&DrawSpan32<TriScreenDrawerModes::StyleFuzzy>,
|
||||
&DrawSpan32<TriScreenDrawerModes::StyleStencil>,
|
||||
&DrawSpan32<TriScreenDrawerModes::StyleTranslucent>,
|
||||
&DrawSpan32<TriScreenDrawerModes::StyleAdd>,
|
||||
&DrawSpan32<TriScreenDrawerModes::StyleShaded>,
|
||||
&DrawSpan32<TriScreenDrawerModes::StyleTranslucentStencil>,
|
||||
&DrawSpan32<TriScreenDrawerModes::StyleShadow>,
|
||||
&DrawSpan32<TriScreenDrawerModes::StyleSubtract>,
|
||||
&DrawSpan32<TriScreenDrawerModes::StyleAddStencil>,
|
||||
&DrawSpan32<TriScreenDrawerModes::StyleAddShaded>,
|
||||
&DrawSpan32<TriScreenDrawerModes::StyleOpaqueTranslated>,
|
||||
&DrawSpan32<TriScreenDrawerModes::StyleSrcColorTranslated>,
|
||||
&DrawSpan32<TriScreenDrawerModes::StyleNormalTranslated>,
|
||||
&DrawSpan32<TriScreenDrawerModes::StyleStencilTranslated>,
|
||||
&DrawSpan32<TriScreenDrawerModes::StyleTranslucentTranslated>,
|
||||
&DrawSpan32<TriScreenDrawerModes::StyleAddTranslated>,
|
||||
&DrawSpan32<TriScreenDrawerModes::StyleShadedTranslated>,
|
||||
&DrawSpan32<TriScreenDrawerModes::StyleTranslucentStencilTranslated>,
|
||||
&DrawSpan32<TriScreenDrawerModes::StyleShadowTranslated>,
|
||||
&DrawSpan32<TriScreenDrawerModes::StyleSubtractTranslated>,
|
||||
&DrawSpan32<TriScreenDrawerModes::StyleAddStencilTranslated>,
|
||||
&DrawSpan32<TriScreenDrawerModes::StyleAddShadedTranslated>
|
||||
};
|
||||
|
||||
void(*ScreenTriangle::TriDrawers8[])(int, int, uint32_t, uint32_t, const TriDrawTriangleArgs *) =
|
||||
{
|
||||
&TriScreenDrawer8<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureOpaque
|
||||
|
|
|
@ -139,9 +139,9 @@ class ScreenTriangle
|
|||
public:
|
||||
static void Draw(const TriDrawTriangleArgs *args, PolyTriangleThreadData *thread);
|
||||
static void DrawSWRender(const TriDrawTriangleArgs *args, PolyTriangleThreadData *thread);
|
||||
static void DrawSpan8(int y, int x0, int x1, const TriDrawTriangleArgs *args);
|
||||
static void DrawSpan32(int y, int x0, int x1, const TriDrawTriangleArgs *args);
|
||||
|
||||
static void(*SpanDrawers8[])(int y, int x0, int x1, const TriDrawTriangleArgs *args);
|
||||
static void(*SpanDrawers32[])(int y, int x0, int x1, const TriDrawTriangleArgs *args);
|
||||
static void(*TriDrawers8[])(int, int, uint32_t, uint32_t, const TriDrawTriangleArgs *);
|
||||
static void(*TriDrawers32[])(int, int, uint32_t, uint32_t, const TriDrawTriangleArgs *);
|
||||
static void(*RectDrawers8[])(const void *, int, int, int, const RectDrawArgs *, PolyTriangleThreadData *);
|
||||
|
@ -152,6 +152,46 @@ public:
|
|||
|
||||
namespace TriScreenDrawerModes
|
||||
{
|
||||
enum SWStyleFlags
|
||||
{
|
||||
SWSTYLEF_Translated = 1,
|
||||
SWSTYLEF_Skycap = 2,
|
||||
SWSTYLEF_FogBoundary = 4,
|
||||
SWSTYLEF_Fill = 8,
|
||||
SWSTYLEF_SrcColorOneMinusSrcColor = 16
|
||||
};
|
||||
|
||||
struct StyleOpaque { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_One, BlendDest = STYLEALPHA_Zero, Flags = STYLEF_Alpha1, SWFlags = 0; };
|
||||
struct StyleSkycap { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_One, BlendDest = STYLEALPHA_Zero, Flags = STYLEF_Alpha1, SWFlags = SWSTYLEF_Skycap; };
|
||||
struct StyleFogBoundary { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_One, BlendDest = STYLEALPHA_Zero, Flags = STYLEF_Alpha1, SWFlags = SWSTYLEF_FogBoundary; };
|
||||
struct StyleSrcColor { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_InvSrc, Flags = STYLEF_Alpha1, SWFlags = SWSTYLEF_SrcColorOneMinusSrcColor; };
|
||||
struct StyleFill { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_One, BlendDest = STYLEALPHA_Zero, Flags = STYLEF_Alpha1, SWFlags = SWSTYLEF_Fill; };
|
||||
|
||||
struct StyleNormal { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_InvSrc, Flags = STYLEF_Alpha1, SWFlags = 0; };
|
||||
struct StyleFuzzy { static const int BlendOp = STYLEOP_Fuzz, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_InvSrc, Flags = 0, SWFlags = 0; };
|
||||
struct StyleStencil { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_InvSrc, Flags = STYLEF_Alpha1 | STYLEF_ColorIsFixed, SWFlags = 0; };
|
||||
struct StyleTranslucent { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_InvSrc, Flags = 0, SWFlags = 0; };
|
||||
struct StyleAdd { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_One, Flags = 0, SWFlags = 0; };
|
||||
struct StyleShaded { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_InvSrc, Flags = STYLEF_RedIsAlpha | STYLEF_ColorIsFixed, SWFlags = 0; };
|
||||
struct StyleTranslucentStencil { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_InvSrc, Flags = STYLEF_ColorIsFixed, SWFlags = 0; };
|
||||
struct StyleShadow { static const int BlendOp = STYLEOP_Shadow, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_InvSrc, Flags = 0, SWFlags = 0; };
|
||||
struct StyleSubtract { static const int BlendOp = STYLEOP_RevSub, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_One, Flags = 0, SWFlags = 0; };
|
||||
struct StyleAddStencil { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_One, Flags = STYLEF_ColorIsFixed, SWFlags = 0; };
|
||||
struct StyleAddShaded { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_One, Flags = STYLEF_RedIsAlpha | STYLEF_ColorIsFixed, SWFlags = 0; };
|
||||
|
||||
struct StyleOpaqueTranslated { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_One, BlendDest = STYLEALPHA_Zero, Flags = STYLEF_Alpha1, SWFlags = SWSTYLEF_Translated; };
|
||||
struct StyleSrcColorTranslated { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_InvSrc, Flags = STYLEF_Alpha1, SWFlags = SWSTYLEF_Translated|SWSTYLEF_SrcColorOneMinusSrcColor; };
|
||||
struct StyleNormalTranslated { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_InvSrc, Flags = STYLEF_Alpha1, SWFlags = SWSTYLEF_Translated; };
|
||||
struct StyleStencilTranslated { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_InvSrc, Flags = STYLEF_Alpha1 | STYLEF_ColorIsFixed, SWFlags = SWSTYLEF_Translated; };
|
||||
struct StyleTranslucentTranslated { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_InvSrc, Flags = 0, SWFlags = SWSTYLEF_Translated; };
|
||||
struct StyleAddTranslated { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_One, Flags = 0, SWFlags = SWSTYLEF_Translated; };
|
||||
struct StyleShadedTranslated { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_InvSrc, Flags = STYLEF_RedIsAlpha | STYLEF_ColorIsFixed, SWFlags = SWSTYLEF_Translated; };
|
||||
struct StyleTranslucentStencilTranslated { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_InvSrc, Flags = STYLEF_ColorIsFixed, SWFlags = SWSTYLEF_Translated; };
|
||||
struct StyleShadowTranslated { static const int BlendOp = STYLEOP_Shadow, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_InvSrc, Flags = 0, SWFlags = SWSTYLEF_Translated; };
|
||||
struct StyleSubtractTranslated { static const int BlendOp = STYLEOP_RevSub, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_One, Flags = 0, SWFlags = SWSTYLEF_Translated; };
|
||||
struct StyleAddStencilTranslated { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_One, Flags = STYLEF_ColorIsFixed, SWFlags = SWSTYLEF_Translated; };
|
||||
struct StyleAddShadedTranslated { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_One, Flags = STYLEF_RedIsAlpha | STYLEF_ColorIsFixed, SWFlags = SWSTYLEF_Translated; };
|
||||
|
||||
enum class BlendModes { Opaque, Masked, AddClamp, SubClamp, RevSubClamp, AddSrcColorOneMinusSrcColor, Shaded, AddClampShaded };
|
||||
struct OpaqueBlend { static const int Mode = (int)BlendModes::Opaque; };
|
||||
struct MaskedBlend { static const int Mode = (int)BlendModes::Masked; };
|
||||
|
|
|
@ -139,7 +139,7 @@ void PolyDrawLinePortal::Render(int portalDepth)
|
|||
DVector2 pt2 = clipLine->v2->fPos() - PolyRenderer::Instance()->Viewpoint.Pos;
|
||||
bool backfacing = (pt1.Y * (pt1.X - pt2.X) + pt1.X * (pt2.Y - pt1.Y) >= 0);
|
||||
|
||||
PortalViewpoint = PolyRenderer::Instance()->SetupPerspectiveMatrix(Mirror);
|
||||
PortalViewpoint = PolyRenderer::Instance()->SetupPerspectiveMatrix(Mirror != nullptr);
|
||||
PortalViewpoint.StencilValue = StencilValue;
|
||||
PortalViewpoint.PortalDepth = portalDepth;
|
||||
PortalViewpoint.PortalEnterLine = clipLine;
|
||||
|
|
|
@ -29,11 +29,11 @@ float unpackuvert( uint32_t n, int c )
|
|||
switch( c )
|
||||
{
|
||||
case 2:
|
||||
return ((int16_t)((n&0x7ff)<<5))/127.f;
|
||||
return ((int16_t)((n&0x7ff)<<5))/128.f;
|
||||
case 1:
|
||||
return ((int16_t)(((n>>11)&0x7ff)<<5))/127.f;
|
||||
return ((int16_t)(((n>>11)&0x7ff)<<5))/128.f;
|
||||
case 0:
|
||||
return ((int16_t)(((n>>22)&0x3ff)<<6))/127.f;
|
||||
return ((int16_t)(((n>>22)&0x3ff)<<6))/128.f;
|
||||
default:
|
||||
return 0.f;
|
||||
}
|
||||
|
@ -98,9 +98,9 @@ void FUE1Model::LoadGeometry()
|
|||
{
|
||||
UE1Vertex Vert;
|
||||
// unpack position
|
||||
Vert.Pos = FVector3(unpackuvert(averts[j+i*numVerts],0),
|
||||
unpackuvert(averts[j+i*numVerts],1),
|
||||
unpackuvert(averts[j+i*numVerts],2));
|
||||
Vert.Pos = FVector3(unpackuvert(averts[j+i*numVerts],2),
|
||||
unpackuvert(averts[j+i*numVerts],0),
|
||||
-unpackuvert(averts[j+i*numVerts],1));
|
||||
// push vertex (without normals, will be calculated later)
|
||||
verts.Push(Vert);
|
||||
}
|
||||
|
@ -136,8 +136,6 @@ void FUE1Model::LoadGeometry()
|
|||
vert[l] = verts[polys[k].V[l]+numVerts*i].Pos;
|
||||
dir[0] = vert[1]-vert[0];
|
||||
dir[1] = vert[2]-vert[0];
|
||||
dir[0].MakeUnit();
|
||||
dir[1].MakeUnit();
|
||||
norm = dir[0]^dir[1];
|
||||
nsum += norm.Unit();
|
||||
}
|
||||
|
@ -223,7 +221,7 @@ void FUE1Model::BuildVertexBuffer( FModelRenderer *renderer )
|
|||
{
|
||||
for ( int k=0; k<groups[j].numPolys; k++ )
|
||||
{
|
||||
for ( int l=2; l>=0; l-- )
|
||||
for ( int l=0; l<3; l++ )
|
||||
{
|
||||
UE1Vertex V = verts[polys[groups[j].P[k]].V[l]+i*numVerts];
|
||||
FVector2 C = polys[groups[j].P[k]].C[l];
|
||||
|
|
|
@ -102,7 +102,7 @@ bool ViewportIsScaled43()
|
|||
|
||||
void R_ShowCurrentScaling()
|
||||
{
|
||||
int x1 = screen->GetClientWidth(), y1 = screen->GetClientHeight(), x2 = x1 * vid_scalefactor, y2 = y1 * vid_scalefactor;
|
||||
int x1 = screen->GetClientWidth(), y1 = screen->GetClientHeight(), x2 = int(x1 * vid_scalefactor), y2 = int(y1 * vid_scalefactor);
|
||||
Printf("Current Scale: %f\n", (float)(vid_scalefactor));
|
||||
Printf("Real resolution: %i x %i\nEmulated resolution: %i x %i\n", x1, y1, x2, y2);
|
||||
}
|
||||
|
|
|
@ -607,12 +607,6 @@ void FTextureManager::AddHiresTextures (int wadnum)
|
|||
void FTextureManager::LoadTextureDefs(int wadnum, const char *lumpname)
|
||||
{
|
||||
int remapLump, lastLump;
|
||||
FString src;
|
||||
bool is32bit;
|
||||
int width, height;
|
||||
ETextureType type;
|
||||
int mode;
|
||||
TArray<FTextureID> tlist;
|
||||
|
||||
lastLump = 0;
|
||||
|
||||
|
@ -620,142 +614,166 @@ void FTextureManager::LoadTextureDefs(int wadnum, const char *lumpname)
|
|||
{
|
||||
if (Wads.GetLumpFile(remapLump) == wadnum)
|
||||
{
|
||||
FScanner sc(remapLump);
|
||||
while (sc.GetString())
|
||||
ParseTextureDef(remapLump);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FTextureManager::ParseTextureDef(int lump)
|
||||
{
|
||||
TArray<FTextureID> tlist;
|
||||
|
||||
FScanner sc(lump);
|
||||
while (sc.GetString())
|
||||
{
|
||||
if (sc.Compare("remap")) // remap an existing texture
|
||||
{
|
||||
sc.MustGetString();
|
||||
|
||||
// allow selection by type
|
||||
int mode;
|
||||
ETextureType type;
|
||||
if (sc.Compare("wall")) type=ETextureType::Wall, mode=FTextureManager::TEXMAN_Overridable;
|
||||
else if (sc.Compare("flat")) type=ETextureType::Flat, mode=FTextureManager::TEXMAN_Overridable;
|
||||
else if (sc.Compare("sprite")) type=ETextureType::Sprite, mode=0;
|
||||
else type = ETextureType::Any, mode = 0;
|
||||
|
||||
if (type != ETextureType::Any) sc.MustGetString();
|
||||
|
||||
sc.String[8]=0;
|
||||
|
||||
tlist.Clear();
|
||||
int amount = ListTextures(sc.String, tlist);
|
||||
FName texname = sc.String;
|
||||
|
||||
sc.MustGetString();
|
||||
int lumpnum = Wads.CheckNumForFullName(sc.String, true, ns_patches);
|
||||
if (lumpnum == -1) lumpnum = Wads.CheckNumForFullName(sc.String, true, ns_graphics);
|
||||
|
||||
if (tlist.Size() == 0)
|
||||
{
|
||||
if (sc.Compare("remap")) // remap an existing texture
|
||||
Printf("Attempting to remap non-existent texture %s to %s\n",
|
||||
texname.GetChars(), sc.String);
|
||||
}
|
||||
else if (lumpnum == -1)
|
||||
{
|
||||
Printf("Attempting to remap texture %s to non-existent lump %s\n",
|
||||
texname.GetChars(), sc.String);
|
||||
}
|
||||
else
|
||||
{
|
||||
for(unsigned int i = 0; i < tlist.Size(); i++)
|
||||
{
|
||||
sc.MustGetString();
|
||||
FTexture * oldtex = Textures[tlist[i].GetIndex()].Texture;
|
||||
int sl;
|
||||
|
||||
// allow selection by type
|
||||
if (sc.Compare("wall")) type=ETextureType::Wall, mode=FTextureManager::TEXMAN_Overridable;
|
||||
else if (sc.Compare("flat")) type=ETextureType::Flat, mode=FTextureManager::TEXMAN_Overridable;
|
||||
else if (sc.Compare("sprite")) type=ETextureType::Sprite, mode=0;
|
||||
else type = ETextureType::Any, mode = 0;
|
||||
|
||||
if (type != ETextureType::Any) sc.MustGetString();
|
||||
|
||||
sc.String[8]=0;
|
||||
|
||||
tlist.Clear();
|
||||
int amount = ListTextures(sc.String, tlist);
|
||||
FName texname = sc.String;
|
||||
|
||||
sc.MustGetString();
|
||||
int lumpnum = Wads.CheckNumForFullName(sc.String, true, ns_patches);
|
||||
if (lumpnum == -1) lumpnum = Wads.CheckNumForFullName(sc.String, true, ns_graphics);
|
||||
|
||||
if (tlist.Size() == 0)
|
||||
// only replace matching types. For sprites also replace any MiscPatches
|
||||
// based on the same lump. These can be created for icons.
|
||||
if (oldtex->UseType == type || type == ETextureType::Any ||
|
||||
(mode == TEXMAN_Overridable && oldtex->UseType == ETextureType::Override) ||
|
||||
(type == ETextureType::Sprite && oldtex->UseType == ETextureType::MiscPatch &&
|
||||
(sl=oldtex->GetSourceLump()) >= 0 && Wads.GetLumpNamespace(sl) == ns_sprites)
|
||||
)
|
||||
{
|
||||
Printf("Attempting to remap non-existent texture %s to %s\n",
|
||||
texname.GetChars(), sc.String);
|
||||
}
|
||||
else if (lumpnum == -1)
|
||||
{
|
||||
Printf("Attempting to remap texture %s to non-existent lump %s\n",
|
||||
texname.GetChars(), sc.String);
|
||||
}
|
||||
else
|
||||
{
|
||||
for(unsigned int i = 0; i < tlist.Size(); i++)
|
||||
FTexture * newtex = FTexture::CreateTexture (lumpnum, ETextureType::Any);
|
||||
if (newtex != NULL)
|
||||
{
|
||||
FTexture * oldtex = Textures[tlist[i].GetIndex()].Texture;
|
||||
int sl;
|
||||
|
||||
// only replace matching types. For sprites also replace any MiscPatches
|
||||
// based on the same lump. These can be created for icons.
|
||||
if (oldtex->UseType == type || type == ETextureType::Any ||
|
||||
(mode == TEXMAN_Overridable && oldtex->UseType == ETextureType::Override) ||
|
||||
(type == ETextureType::Sprite && oldtex->UseType == ETextureType::MiscPatch &&
|
||||
(sl=oldtex->GetSourceLump()) >= 0 && Wads.GetLumpNamespace(sl) == ns_sprites)
|
||||
)
|
||||
{
|
||||
FTexture * newtex = FTexture::CreateTexture (lumpnum, ETextureType::Any);
|
||||
if (newtex != NULL)
|
||||
{
|
||||
// Replace the entire texture and adjust the scaling and offset factors.
|
||||
newtex->bWorldPanning = true;
|
||||
newtex->SetScaledSize(oldtex->GetScaledWidth(), oldtex->GetScaledHeight());
|
||||
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);
|
||||
}
|
||||
}
|
||||
// Replace the entire texture and adjust the scaling and offset factors.
|
||||
newtex->bWorldPanning = true;
|
||||
newtex->SetScaledSize(oldtex->GetScaledWidth(), oldtex->GetScaledHeight());
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (sc.Compare("define")) // define a new "fake" texture
|
||||
{
|
||||
sc.GetString();
|
||||
|
||||
FString base = ExtractFileBase(sc.String, false);
|
||||
if (!base.IsEmpty())
|
||||
{
|
||||
src = base.Left(8);
|
||||
|
||||
int lumpnum = Wads.CheckNumForFullName(sc.String, true, ns_patches);
|
||||
if (lumpnum == -1) lumpnum = Wads.CheckNumForFullName(sc.String, true, ns_graphics);
|
||||
|
||||
sc.GetString();
|
||||
is32bit = !!sc.Compare("force32bit");
|
||||
if (!is32bit) sc.UnGet();
|
||||
|
||||
sc.MustGetNumber();
|
||||
width = sc.Number;
|
||||
sc.MustGetNumber();
|
||||
height = sc.Number;
|
||||
|
||||
if (lumpnum>=0)
|
||||
{
|
||||
FTexture *newtex = FTexture::CreateTexture(lumpnum, ETextureType::Override);
|
||||
|
||||
if (newtex != NULL)
|
||||
{
|
||||
// Replace the entire texture and adjust the scaling and offset factors.
|
||||
newtex->bWorldPanning = true;
|
||||
newtex->SetScaledSize(width, height);
|
||||
newtex->Name = src;
|
||||
|
||||
FTextureID oldtex = TexMan.CheckForTexture(src, ETextureType::MiscPatch);
|
||||
if (oldtex.isValid())
|
||||
{
|
||||
ReplaceTexture(oldtex, newtex, true);
|
||||
newtex->UseType = ETextureType::Override;
|
||||
}
|
||||
else AddTexture(newtex);
|
||||
}
|
||||
}
|
||||
}
|
||||
//else Printf("Unable to define hires texture '%s'\n", tex->Name);
|
||||
}
|
||||
else if (sc.Compare("texture"))
|
||||
{
|
||||
ParseXTexture(sc, ETextureType::Override);
|
||||
}
|
||||
else if (sc.Compare("sprite"))
|
||||
{
|
||||
ParseXTexture(sc, ETextureType::Sprite);
|
||||
}
|
||||
else if (sc.Compare("walltexture"))
|
||||
{
|
||||
ParseXTexture(sc, ETextureType::Wall);
|
||||
}
|
||||
else if (sc.Compare("flat"))
|
||||
{
|
||||
ParseXTexture(sc, ETextureType::Flat);
|
||||
}
|
||||
else if (sc.Compare("graphic"))
|
||||
{
|
||||
ParseXTexture(sc, ETextureType::MiscPatch);
|
||||
}
|
||||
else
|
||||
{
|
||||
sc.ScriptError("Texture definition expected, found '%s'", sc.String);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (sc.Compare("define")) // define a new "fake" texture
|
||||
{
|
||||
sc.GetString();
|
||||
|
||||
FString base = ExtractFileBase(sc.String, false);
|
||||
if (!base.IsEmpty())
|
||||
{
|
||||
FString src = base.Left(8);
|
||||
|
||||
int lumpnum = Wads.CheckNumForFullName(sc.String, true, ns_patches);
|
||||
if (lumpnum == -1) lumpnum = Wads.CheckNumForFullName(sc.String, true, ns_graphics);
|
||||
|
||||
sc.GetString();
|
||||
bool is32bit = !!sc.Compare("force32bit");
|
||||
if (!is32bit) sc.UnGet();
|
||||
|
||||
sc.MustGetNumber();
|
||||
int width = sc.Number;
|
||||
sc.MustGetNumber();
|
||||
int height = sc.Number;
|
||||
|
||||
if (lumpnum>=0)
|
||||
{
|
||||
FTexture *newtex = FTexture::CreateTexture(lumpnum, ETextureType::Override);
|
||||
|
||||
if (newtex != NULL)
|
||||
{
|
||||
// Replace the entire texture and adjust the scaling and offset factors.
|
||||
newtex->bWorldPanning = true;
|
||||
newtex->SetScaledSize(width, height);
|
||||
newtex->Name = src;
|
||||
|
||||
FTextureID oldtex = TexMan.CheckForTexture(src, ETextureType::MiscPatch);
|
||||
if (oldtex.isValid())
|
||||
{
|
||||
ReplaceTexture(oldtex, newtex, true);
|
||||
newtex->UseType = ETextureType::Override;
|
||||
}
|
||||
else AddTexture(newtex);
|
||||
}
|
||||
}
|
||||
}
|
||||
//else Printf("Unable to define hires texture '%s'\n", tex->Name);
|
||||
}
|
||||
else if (sc.Compare("texture"))
|
||||
{
|
||||
ParseXTexture(sc, ETextureType::Override);
|
||||
}
|
||||
else if (sc.Compare("sprite"))
|
||||
{
|
||||
ParseXTexture(sc, ETextureType::Sprite);
|
||||
}
|
||||
else if (sc.Compare("walltexture"))
|
||||
{
|
||||
ParseXTexture(sc, ETextureType::Wall);
|
||||
}
|
||||
else if (sc.Compare("flat"))
|
||||
{
|
||||
ParseXTexture(sc, ETextureType::Flat);
|
||||
}
|
||||
else if (sc.Compare("graphic"))
|
||||
{
|
||||
ParseXTexture(sc, ETextureType::MiscPatch);
|
||||
}
|
||||
else if (sc.Compare("#include"))
|
||||
{
|
||||
sc.MustGetString();
|
||||
|
||||
// This is not using sc.Open because it can print a more useful error message when done here
|
||||
int includelump = Wads.CheckNumForFullName(sc.String, true);
|
||||
if (includelump == -1)
|
||||
{
|
||||
sc.ScriptError("Lump '%s' not found", sc.String);
|
||||
}
|
||||
else
|
||||
{
|
||||
ParseTextureDef(includelump);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sc.ScriptError("Texture definition expected, found '%s'", sc.String);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -584,6 +584,7 @@ public:
|
|||
void AddPatches (int lumpnum);
|
||||
void AddHiresTextures (int wadnum);
|
||||
void LoadTextureDefs(int wadnum, const char *lumpname);
|
||||
void ParseTextureDef(int remapLump);
|
||||
void ParseXTexture(FScanner &sc, ETextureType usetype);
|
||||
void SortTexturesByType(int start, int end);
|
||||
bool AreTexturesCompatible (FTextureID picnum1, FTextureID picnum2);
|
||||
|
|
|
@ -754,7 +754,7 @@ void WI_Start(wbstartstruct_t *wbstartstruct)
|
|||
cls = PClass::FindClass(screenclass);
|
||||
if (cls == nullptr)
|
||||
{
|
||||
I_FatalError("Cannot create statis screen");
|
||||
I_FatalError("Cannot create status screen");
|
||||
}
|
||||
}
|
||||
// Set up some global stuff that is always needed.
|
||||
|
|
|
@ -12,7 +12,7 @@ vec3 lightContribution(int i, vec3 normal)
|
|||
|
||||
vec3 lightdir = normalize(lightpos.xyz - pixelpos.xyz);
|
||||
float dotprod = dot(normal, lightdir);
|
||||
if (dotprod < 0.0) return vec3(0.0); // light hits from the backside. This can happen with full sector light lists and must be rejected for all cases.
|
||||
if (dotprod < -0.0001) return vec3(0.0); // light hits from the backside. This can happen with full sector light lists and must be rejected for all cases. Note that this can cause precision issues.
|
||||
|
||||
float attenuation = clamp((lightpos.w - lightdistance) / lightpos.w, 0.0, 1.0);
|
||||
|
||||
|
|
Loading…
Reference in a new issue