- fix softpoly colored fog bug in the new drawers

This commit is contained in:
Magnus Norddahl 2018-06-05 15:16:04 +02:00
parent 7009755c52
commit 9cd751ae7a
2 changed files with 257 additions and 176 deletions

View file

@ -106,15 +106,24 @@ void PolyDrawArgs::SetLight(FSWColormap *base_colormap, uint32_t lightlevel, dou
mLight = clamp<uint32_t>(lightlevel, 0, 255); mLight = clamp<uint32_t>(lightlevel, 0, 255);
mFixedLight = fixed; mFixedLight = fixed;
mLightRed = base_colormap->Color.r * 256 / 255; mLightRed = base_colormap->Color.r;
mLightGreen = base_colormap->Color.g * 256 / 255; mLightRed += mLightRed >> 7;
mLightBlue = base_colormap->Color.b * 256 / 255; mLightGreen = base_colormap->Color.g;
mLightAlpha = base_colormap->Color.a * 256 / 255; mLightGreen += mLightGreen >> 7;
mLightBlue = base_colormap->Color.b;
mLightBlue += mLightBlue >> 7;
mLightAlpha = base_colormap->Color.a;
mLightAlpha += mLightAlpha >> 7;
mFadeRed = base_colormap->Fade.r; mFadeRed = base_colormap->Fade.r;
mFadeRed += mFadeRed >> 7;
mFadeGreen = base_colormap->Fade.g; mFadeGreen = base_colormap->Fade.g;
mFadeGreen += mFadeGreen >> 7;
mFadeBlue = base_colormap->Fade.b; mFadeBlue = base_colormap->Fade.b;
mFadeBlue += mFadeBlue >> 7;
mFadeAlpha = base_colormap->Fade.a; mFadeAlpha = base_colormap->Fade.a;
mDesaturate = MIN(abs(base_colormap->Desaturate), 255) * 255 / 256; mFadeAlpha += mFadeAlpha >> 7;
mDesaturate = MIN(abs(base_colormap->Desaturate), 255);
mDesaturate += mDesaturate >> 7;
mSimpleShade = (base_colormap->Color.d == 0x00ffffff && base_colormap->Fade.d == 0x00000000 && base_colormap->Desaturate == 0); mSimpleShade = (base_colormap->Color.d == 0x00ffffff && base_colormap->Fade.d == 0x00000000 && base_colormap->Desaturate == 0);
mColormaps = base_colormap->Maps; mColormaps = base_colormap->Maps;
} }

View file

@ -385,8 +385,8 @@ void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args)
float v1X, v1Y, v1W, v1U, v1V, v1WorldX, v1WorldY, v1WorldZ; float v1X, v1Y, v1W, v1U, v1V, v1WorldX, v1WorldY, v1WorldZ;
float startX, startY; float startX, startY;
float stepXW, stepXU, stepXV, stepWorldX, stepWorldY, stepWorldZ; float stepW, stepU, stepV, stepWorldX, stepWorldY, stepWorldZ;
float posXW, posXU, posXV, posWorldX, posWorldY, posWorldZ; float posW, posU, posV, posWorldX, posWorldY, posWorldZ;
PolyLight *lights; PolyLight *lights;
int num_lights; int num_lights;
@ -410,12 +410,12 @@ void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args)
v1V = args->v1->v * v1W; v1V = args->v1->v * v1W;
startX = x0 + (0.5f - v1X); startX = x0 + (0.5f - v1X);
startY = y + (0.5f - v1Y); startY = y + (0.5f - v1Y);
stepXW = args->gradientX.W; stepW = args->gradientX.W;
stepXU = args->gradientX.U; stepU = args->gradientX.U;
stepXV = args->gradientX.V; stepV = args->gradientX.V;
posXW = v1W + stepXW * startX + args->gradientY.W * startY; posW = v1W + stepW * startX + args->gradientY.W * startY;
posXU = v1U + stepXU * startX + args->gradientY.U * startY; posU = v1U + stepU * startX + args->gradientY.U * startY;
posXV = v1V + stepXV * startX + args->gradientY.V * startY; posV = v1V + stepV * startX + args->gradientY.V * startY;
texPixels = (const uint32_t*)args->uniforms->TexturePixels(); texPixels = (const uint32_t*)args->uniforms->TexturePixels();
translation = (const uint32_t*)args->uniforms->Translation(); translation = (const uint32_t*)args->uniforms->Translation();
@ -434,8 +434,8 @@ void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args)
float globVis = args->uniforms->GlobVis() * (1.0f / 32.0f); float globVis = args->uniforms->GlobVis() * (1.0f / 32.0f);
shade = (fixed_t)((2.0f - (light + 12.0f) / 128.0f) * (float)FRACUNIT); shade = (fixed_t)((2.0f - (light + 12.0f) / 128.0f) * (float)FRACUNIT);
lightpos = (fixed_t)(globVis * posXW * (float)FRACUNIT); lightpos = (fixed_t)(globVis * posW * (float)FRACUNIT);
lightstep = (fixed_t)(globVis * stepXW * (float)FRACUNIT); lightstep = (fixed_t)(globVis * stepW * (float)FRACUNIT);
int affineOffset = x0 / 16 * 16 - x0; int affineOffset = x0 / 16 * 16 - x0;
lightpos = lightpos + lightstep * affineOffset; lightpos = lightpos + lightstep * affineOffset;
@ -481,11 +481,11 @@ void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args)
dynlightcolor = args->uniforms->DynLightColor(); dynlightcolor = args->uniforms->DynLightColor();
int affineOffset = x0 / 16 * 16 - x0; int affineOffset = x0 / 16 * 16 - x0;
float posLightW = posXW + stepXW * affineOffset; float posLightW = posW + stepW * affineOffset;
posWorldX = posWorldX + stepWorldX * affineOffset; posWorldX = posWorldX + stepWorldX * affineOffset;
posWorldY = posWorldY + stepWorldY * affineOffset; posWorldY = posWorldY + stepWorldY * affineOffset;
posWorldZ = posWorldZ + stepWorldZ * affineOffset; posWorldZ = posWorldZ + stepWorldZ * affineOffset;
float stepLightW = stepXW * 16.0f; float stepLightW = stepW * 16.0f;
stepWorldX *= 16.0f; stepWorldX *= 16.0f;
stepWorldY *= 16.0f; stepWorldY *= 16.0f;
stepWorldZ *= 16.0f; stepWorldZ *= 16.0f;
@ -496,10 +496,10 @@ void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args)
uint32_t lit_g = GPART(dynlightcolor); uint32_t lit_g = GPART(dynlightcolor);
uint32_t lit_b = BPART(dynlightcolor); uint32_t lit_b = BPART(dynlightcolor);
float rcp_posXW = 1.0f / posLightW; float rcp_posW = 1.0f / posLightW;
float worldposX = posWorldX * rcp_posXW; float worldposX = posWorldX * rcp_posW;
float worldposY = posWorldY * rcp_posXW; float worldposY = posWorldY * rcp_posW;
float worldposZ = posWorldZ * rcp_posXW; float worldposZ = posWorldZ * rcp_posW;
for (int i = 0; i < num_lights; i++) for (int i = 0; i < num_lights; i++)
{ {
float lightposX = lights[i].x; float lightposX = lights[i].x;
@ -592,45 +592,13 @@ void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args)
int x = x0; int x = x0;
while (x < x1) while (x < x1)
{ {
uint32_t fg = 0;
if (ModeT::SWFlags & SWSTYLEF_Fill)
{
fg = fillcolor;
}
else if (ModeT::SWFlags & SWSTYLEF_FogBoundary)
{
fg = destLine[x];
}
else if (ModeT::BlendOp != STYLEOP_Fuzz)
{
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 if (ModeT::Flags & STYLEF_RedIsAlpha)
{
fg = ((const uint8_t*)texPixels)[texelX * texHeight + texelY];
}
else
{
fg = texPixels[texelX * texHeight + texelY];
}
}
if (ModeT::BlendOp == STYLEOP_Fuzz) if (ModeT::BlendOp == STYLEOP_Fuzz)
{ {
using namespace swrenderer; using namespace swrenderer;
float rcpW = 0x01000000 / posXW; float rcpW = 0x01000000 / posW;
int32_t u = (int32_t)(posXU * rcpW); int32_t u = (int32_t)(posU * rcpW);
int32_t v = (int32_t)(posXV * rcpW); int32_t v = (int32_t)(posV * rcpW);
uint32_t texelX = ((((uint32_t)u << 8) >> 16) * texWidth) >> 16; uint32_t texelX = ((((uint32_t)u << 8) >> 16) * texWidth) >> 16;
uint32_t texelY = ((((uint32_t)v << 8) >> 16) * texHeight) >> 16; uint32_t texelY = ((((uint32_t)v << 8) >> 16) * texHeight) >> 16;
unsigned int sampleshadeout = APART(texPixels[texelX * texHeight + texelY]); unsigned int sampleshadeout = APART(texPixels[texelX * texHeight + texelY]);
@ -657,8 +625,13 @@ void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args)
} }
else if (ModeT::SWFlags & SWSTYLEF_Skycap) else if (ModeT::SWFlags & SWSTYLEF_Skycap)
{ {
float rcpW = 0x01000000 / posXW; float rcpW = 0x01000000 / posW;
int32_t v = (int32_t)(posXV * rcpW); int32_t u = (int32_t)(posU * rcpW);
int32_t v = (int32_t)(posV * rcpW);
uint32_t texelX = ((((uint32_t)u << 8) >> 16) * texWidth) >> 16;
uint32_t texelY = ((((uint32_t)v << 8) >> 16) * texHeight) >> 16;
uint32_t fg = texPixels[texelX * texHeight + texelY];
int start_fade = 2; // How fast it should fade out int start_fade = 2; // How fast it should fade out
int alpha_top = clamp(v >> (16 - start_fade), 0, 256); int alpha_top = clamp(v >> (16 - start_fade), 0, 256);
@ -686,8 +659,71 @@ void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args)
destLine[x] = MAKEARGB(255, r, g, b); destLine[x] = MAKEARGB(255, r, g, b);
} }
} }
else if (ModeT::SWFlags & SWSTYLEF_FogBoundary)
{
uint32_t fg = destLine[x];
int lightshade;
if (OptT::Flags & SWOPT_FixedLight)
{
lightshade = light;
}
else
{
lightshade = lightpos >> 4;
}
uint32_t shadedfg_r, shadedfg_g, shadedfg_b;
if (OptT::Flags & SWOPT_ColoredFog)
{
uint32_t fg_r = RPART(fg);
uint32_t fg_g = GPART(fg);
uint32_t fg_b = BPART(fg);
uint32_t intensity = ((fg_r * 77 + fg_g * 143 + fg_b * 37) >> 8) * desaturate;
int inv_light = 256 - lightshade;
shadedfg_r = (((shade_fade_r * inv_light + ((fg_r * inv_desaturate + intensity) >> 8) * lightshade) >> 8) * shade_light_r) >> 8;
shadedfg_g = (((shade_fade_g * inv_light + ((fg_g * inv_desaturate + intensity) >> 8) * lightshade) >> 8) * shade_light_g) >> 8;
shadedfg_b = (((shade_fade_b * inv_light + ((fg_b * inv_desaturate + intensity) >> 8) * lightshade) >> 8) * shade_light_b) >> 8;
}
else
{
shadedfg_r = (RPART(fg) * lightshade) >> 8;
shadedfg_g = (GPART(fg) * lightshade) >> 8;
shadedfg_b = (BPART(fg) * lightshade) >> 8;
}
destLine[x] = MAKEARGB(255, shadedfg_r, shadedfg_g, shadedfg_b);
}
else else
{ {
uint32_t fg = 0;
if (ModeT::SWFlags & SWSTYLEF_Fill)
{
fg = fillcolor;
}
else
{
float rcpW = 0x01000000 / posW;
int32_t u = (int32_t)(posU * rcpW);
int32_t v = (int32_t)(posV * 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 if (ModeT::Flags & STYLEF_RedIsAlpha)
{
fg = ((const uint8_t*)texPixels)[texelX * texHeight + texelY];
}
else
{
fg = texPixels[texelX * texHeight + texelY];
}
}
if ((ModeT::Flags & STYLEF_ColorIsFixed) && !(ModeT::SWFlags & SWSTYLEF_Fill)) if ((ModeT::Flags & STYLEF_ColorIsFixed) && !(ModeT::SWFlags & SWSTYLEF_Fill))
{ {
if (ModeT::Flags & STYLEF_RedIsAlpha) if (ModeT::Flags & STYLEF_RedIsAlpha)
@ -713,14 +749,6 @@ void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args)
lightshade = lightpos >> 4; lightshade = lightpos >> 4;
} }
uint32_t lit_r = 0, lit_g = 0, lit_b = 0;
if (OptT::Flags & SWOPT_DynLights)
{
lit_r = posdynlight_r >> 4;
lit_g = posdynlight_g >> 4;
lit_b = posdynlight_b >> 4;
}
uint32_t shadedfg_r, shadedfg_g, shadedfg_b; uint32_t shadedfg_r, shadedfg_g, shadedfg_b;
if (OptT::Flags & SWOPT_ColoredFog) if (OptT::Flags & SWOPT_ColoredFog)
{ {
@ -728,19 +756,38 @@ void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args)
uint32_t fg_g = GPART(fg); uint32_t fg_g = GPART(fg);
uint32_t fg_b = BPART(fg); uint32_t fg_b = BPART(fg);
uint32_t intensity = ((fg_r * 77 + fg_g * 143 + fg_b * 37) >> 8) * desaturate; uint32_t intensity = ((fg_r * 77 + fg_g * 143 + fg_b * 37) >> 8) * desaturate;
shadedfg_r = (((shade_fade_r + ((fg_r * inv_desaturate + intensity) >> 8) * lightshade) >> 8) * shade_light_r) >> 8; int inv_light = 256 - lightshade;
shadedfg_g = (((shade_fade_g + ((fg_g * inv_desaturate + intensity) >> 8) * lightshade) >> 8) * shade_light_g) >> 8; shadedfg_r = (((shade_fade_r * inv_light + ((fg_r * inv_desaturate + intensity) >> 8) * lightshade) >> 8) * shade_light_r) >> 8;
shadedfg_b = (((shade_fade_b + ((fg_b * inv_desaturate + intensity) >> 8) * lightshade) >> 8) * shade_light_b) >> 8; shadedfg_g = (((shade_fade_g * inv_light + ((fg_g * inv_desaturate + intensity) >> 8) * lightshade) >> 8) * shade_light_g) >> 8;
shadedfg_b = (((shade_fade_b * inv_light + ((fg_b * inv_desaturate + intensity) >> 8) * lightshade) >> 8) * shade_light_b) >> 8;
shadedfg_r = MIN(shadedfg_r + ((fg_r * lit_r) >> 8), (uint32_t)255); if (OptT::Flags & SWOPT_DynLights)
shadedfg_g = MIN(shadedfg_g + ((fg_g * lit_g) >> 8), (uint32_t)255); {
shadedfg_b = MIN(shadedfg_b + ((fg_b * lit_b) >> 8), (uint32_t)255); uint32_t lit_r = posdynlight_r >> 4;
uint32_t lit_g = posdynlight_g >> 4;
uint32_t lit_b = posdynlight_b >> 4;
shadedfg_r = MIN(shadedfg_r + ((fg_r * lit_r) >> 8), (uint32_t)255);
shadedfg_g = MIN(shadedfg_g + ((fg_g * lit_g) >> 8), (uint32_t)255);
shadedfg_b = MIN(shadedfg_b + ((fg_b * lit_b) >> 8), (uint32_t)255);
}
} }
else else
{ {
shadedfg_r = (RPART(fg) * MIN(lightshade + lit_r, (uint32_t)256)) >> 8; if (OptT::Flags & SWOPT_DynLights)
shadedfg_g = (GPART(fg) * MIN(lightshade + lit_g, (uint32_t)256)) >> 8; {
shadedfg_b = (BPART(fg) * MIN(lightshade + lit_b, (uint32_t)256)) >> 8; uint32_t lit_r = posdynlight_r >> 4;
uint32_t lit_g = posdynlight_g >> 4;
uint32_t lit_b = posdynlight_b >> 4;
shadedfg_r = (RPART(fg) * MIN(lightshade + lit_r, (uint32_t)256)) >> 8;
shadedfg_g = (GPART(fg) * MIN(lightshade + lit_g, (uint32_t)256)) >> 8;
shadedfg_b = (BPART(fg) * MIN(lightshade + lit_b, (uint32_t)256)) >> 8;
}
else
{
shadedfg_r = (RPART(fg) * lightshade) >> 8;
shadedfg_g = (GPART(fg) * lightshade) >> 8;
shadedfg_b = (BPART(fg) * lightshade) >> 8;
}
} }
if (ModeT::BlendSrc == STYLEALPHA_One && ModeT::BlendDest == STYLEALPHA_Zero) if (ModeT::BlendSrc == STYLEALPHA_One && ModeT::BlendDest == STYLEALPHA_Zero)
@ -852,9 +899,9 @@ void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args)
} }
} }
posXW += stepXW; posW += stepW;
posXU += stepXU; posU += stepU;
posXV += stepXV; posV += stepV;
if (OptT::Flags & SWOPT_DynLights) if (OptT::Flags & SWOPT_DynLights)
{ {
posdynlight_r += dynlights_r[x >> 4]; posdynlight_r += dynlights_r[x >> 4];
@ -915,8 +962,8 @@ void DrawSpanOpt8(int y, int x0, int x1, const TriDrawTriangleArgs *args)
float v1X, v1Y, v1W, v1U, v1V, v1WorldX, v1WorldY, v1WorldZ; float v1X, v1Y, v1W, v1U, v1V, v1WorldX, v1WorldY, v1WorldZ;
float startX, startY; float startX, startY;
float stepXW, stepXU, stepXV, stepWorldX, stepWorldY, stepWorldZ; float stepW, stepU, stepV, stepWorldX, stepWorldY, stepWorldZ;
float posXW, posXU, posXV, posWorldX, posWorldY, posWorldZ; float posW, posU, posV, posWorldX, posWorldY, posWorldZ;
PolyLight *lights; PolyLight *lights;
int num_lights; int num_lights;
@ -939,12 +986,12 @@ void DrawSpanOpt8(int y, int x0, int x1, const TriDrawTriangleArgs *args)
v1V = args->v1->v * v1W; v1V = args->v1->v * v1W;
startX = x0 + (0.5f - v1X); startX = x0 + (0.5f - v1X);
startY = y + (0.5f - v1Y); startY = y + (0.5f - v1Y);
stepXW = args->gradientX.W; stepW = args->gradientX.W;
stepXU = args->gradientX.U; stepU = args->gradientX.U;
stepXV = args->gradientX.V; stepV = args->gradientX.V;
posXW = v1W + stepXW * startX + args->gradientY.W * startY; posW = v1W + stepW * startX + args->gradientY.W * startY;
posXU = v1U + stepXU * startX + args->gradientY.U * startY; posU = v1U + stepU * startX + args->gradientY.U * startY;
posXV = v1V + stepXV * startX + args->gradientY.V * startY; posV = v1V + stepV * startX + args->gradientY.V * startY;
texPixels = args->uniforms->TexturePixels(); texPixels = args->uniforms->TexturePixels();
translation = args->uniforms->Translation(); translation = args->uniforms->Translation();
@ -968,8 +1015,8 @@ void DrawSpanOpt8(int y, int x0, int x1, const TriDrawTriangleArgs *args)
float globVis = args->uniforms->GlobVis() * (1.0f / 32.0f); float globVis = args->uniforms->GlobVis() * (1.0f / 32.0f);
shade = (fixed_t)((2.0f - (light + 12.0f) / 128.0f) * (float)FRACUNIT); shade = (fixed_t)((2.0f - (light + 12.0f) / 128.0f) * (float)FRACUNIT);
lightpos = (fixed_t)(globVis * posXW * (float)FRACUNIT); lightpos = (fixed_t)(globVis * posW * (float)FRACUNIT);
lightstep = (fixed_t)(globVis * stepXW * (float)FRACUNIT); lightstep = (fixed_t)(globVis * stepW * (float)FRACUNIT);
int affineOffset = x0 / 16 * 16 - x0; int affineOffset = x0 / 16 * 16 - x0;
lightpos = lightpos + lightstep * affineOffset; lightpos = lightpos + lightstep * affineOffset;
@ -1015,11 +1062,11 @@ void DrawSpanOpt8(int y, int x0, int x1, const TriDrawTriangleArgs *args)
dynlightcolor = args->uniforms->DynLightColor(); dynlightcolor = args->uniforms->DynLightColor();
int affineOffset = x0 / 16 * 16 - x0; int affineOffset = x0 / 16 * 16 - x0;
float posLightW = posXW + stepXW * affineOffset; float posLightW = posW + stepW * affineOffset;
posWorldX = posWorldX + stepWorldX * affineOffset; posWorldX = posWorldX + stepWorldX * affineOffset;
posWorldY = posWorldY + stepWorldY * affineOffset; posWorldY = posWorldY + stepWorldY * affineOffset;
posWorldZ = posWorldZ + stepWorldZ * affineOffset; posWorldZ = posWorldZ + stepWorldZ * affineOffset;
float stepLightW = stepXW * 16.0f; float stepLightW = stepW * 16.0f;
stepWorldX *= 16.0f; stepWorldX *= 16.0f;
stepWorldY *= 16.0f; stepWorldY *= 16.0f;
stepWorldZ *= 16.0f; stepWorldZ *= 16.0f;
@ -1030,10 +1077,10 @@ void DrawSpanOpt8(int y, int x0, int x1, const TriDrawTriangleArgs *args)
uint32_t lit_g = GPART(dynlightcolor); uint32_t lit_g = GPART(dynlightcolor);
uint32_t lit_b = BPART(dynlightcolor); uint32_t lit_b = BPART(dynlightcolor);
float rcp_posXW = 1.0f / posLightW; float rcp_posW = 1.0f / posLightW;
float worldposX = posWorldX * rcp_posXW; float worldposX = posWorldX * rcp_posW;
float worldposY = posWorldY * rcp_posXW; float worldposY = posWorldY * rcp_posW;
float worldposZ = posWorldZ * rcp_posXW; float worldposZ = posWorldZ * rcp_posW;
for (int i = 0; i < num_lights; i++) for (int i = 0; i < num_lights; i++)
{ {
float lightposX = lights[i].x; float lightposX = lights[i].x;
@ -1114,39 +1161,13 @@ void DrawSpanOpt8(int y, int x0, int x1, const TriDrawTriangleArgs *args)
int x = x0; int x = x0;
while (x < x1) while (x < x1)
{ {
int fg = 0;
int fgalpha = 255;
if (ModeT::SWFlags & SWSTYLEF_Fill)
{
fg = fillcolor;
}
else if (ModeT::SWFlags & SWSTYLEF_FogBoundary)
{
fg = destLine[x];
}
else if (ModeT::BlendOp != STYLEOP_Fuzz)
{
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];
if (ModeT::SWFlags & SWSTYLEF_Translated)
fg = translation[fg];
fgalpha = (fg != 0) ? 255 : 0;
}
if (ModeT::BlendOp == STYLEOP_Fuzz) if (ModeT::BlendOp == STYLEOP_Fuzz)
{ {
using namespace swrenderer; using namespace swrenderer;
float rcpW = 0x01000000 / posXW; float rcpW = 0x01000000 / posW;
int32_t u = (int32_t)(posXU * rcpW); int32_t u = (int32_t)(posU * rcpW);
int32_t v = (int32_t)(posXV * rcpW); int32_t v = (int32_t)(posV * rcpW);
uint32_t texelX = ((((uint32_t)u << 8) >> 16) * texWidth) >> 16; uint32_t texelX = ((((uint32_t)u << 8) >> 16) * texWidth) >> 16;
uint32_t texelY = ((((uint32_t)v << 8) >> 16) * texHeight) >> 16; uint32_t texelY = ((((uint32_t)v << 8) >> 16) * texHeight) >> 16;
unsigned int sampleshadeout = (texPixels[texelX * texHeight + texelY] != 0) ? 256 : 0; unsigned int sampleshadeout = (texPixels[texelX * texHeight + texelY] != 0) ? 256 : 0;
@ -1172,8 +1193,12 @@ void DrawSpanOpt8(int y, int x0, int x1, const TriDrawTriangleArgs *args)
} }
else if (ModeT::SWFlags & SWSTYLEF_Skycap) else if (ModeT::SWFlags & SWSTYLEF_Skycap)
{ {
float rcpW = 0x01000000 / posXW; float rcpW = 0x01000000 / posW;
int32_t v = (int32_t)(posXV * rcpW); int32_t u = (int32_t)(posU * rcpW);
int32_t v = (int32_t)(posV * rcpW);
uint32_t texelX = ((((uint32_t)u << 8) >> 16) * texWidth) >> 16;
uint32_t texelY = ((((uint32_t)v << 8) >> 16) * texHeight) >> 16;
int fg = texPixels[texelX * texHeight + texelY];
int start_fade = 2; // How fast it should fade out int start_fade = 2; // How fast it should fade out
int alpha_top = clamp(v >> (16 - start_fade), 0, 256); int alpha_top = clamp(v >> (16 - start_fade), 0, 256);
@ -1203,8 +1228,48 @@ void DrawSpanOpt8(int y, int x0, int x1, const TriDrawTriangleArgs *args)
destLine[x] = RGB256k.All[((r >> 2) << 12) | ((g >> 2) << 6) | (b >> 2)]; destLine[x] = RGB256k.All[((r >> 2) << 12) | ((g >> 2) << 6) | (b >> 2)];
} }
} }
else if (ModeT::SWFlags & SWSTYLEF_FogBoundary)
{
int fg = destLine[x];
uint8_t shadedfg;
if (OptT::Flags & SWOPT_FixedLight)
{
shadedfg = colormaps[light + fg];
}
else
{
int lightshade = (lightpos >> 4) & 0xffffff00;
shadedfg = colormaps[lightshade + fg];
}
destLine[x] = shadedfg;
}
else else
{ {
int fg;
if (ModeT::SWFlags & SWSTYLEF_Fill)
{
fg = fillcolor;
}
else
{
float rcpW = 0x01000000 / posW;
int32_t u = (int32_t)(posU * rcpW);
int32_t v = (int32_t)(posV * 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];
}
int fgalpha = 255;
if (ModeT::BlendDest == STYLEALPHA_InvSrc)
{
if (fg == 0)
fgalpha = 0;
}
if ((ModeT::Flags & STYLEF_ColorIsFixed) && !(ModeT::SWFlags & SWSTYLEF_Fill)) if ((ModeT::Flags & STYLEF_ColorIsFixed) && !(ModeT::SWFlags & SWSTYLEF_Fill))
{ {
if (ModeT::Flags & STYLEF_RedIsAlpha) if (ModeT::Flags & STYLEF_RedIsAlpha)
@ -1217,6 +1282,9 @@ void DrawSpanOpt8(int y, int x0, int x1, const TriDrawTriangleArgs *args)
fgalpha = (fgalpha * alpha) >> 8; fgalpha = (fgalpha * alpha) >> 8;
} }
if (ModeT::SWFlags & SWSTYLEF_Translated)
fg = translation[fg];
uint8_t shadedfg; uint8_t shadedfg;
if (OptT::Flags & SWOPT_FixedLight) if (OptT::Flags & SWOPT_FixedLight)
{ {
@ -1359,9 +1427,9 @@ void DrawSpanOpt8(int y, int x0, int x1, const TriDrawTriangleArgs *args)
} }
} }
posXW += stepXW; posW += stepW;
posXU += stepXU; posU += stepU;
posXV += stepXV; posV += stepV;
if (OptT::Flags & SWOPT_DynLights) if (OptT::Flags & SWOPT_DynLights)
{ {
posdynlight_r += dynlights_r[x >> 4]; posdynlight_r += dynlights_r[x >> 4];
@ -1444,25 +1512,6 @@ void DrawRect8(const void *destOrg, int destWidth, int destHeight, int destPitch
uint32_t posU = startU; uint32_t posU = startU;
for (int x = x0; x < x1; x++) for (int x = x0; x < x1; x++)
{ {
int fg = 0;
int fgalpha = 255;
if (ModeT::SWFlags & SWSTYLEF_Fill)
{
fg = fillcolor;
}
else if (ModeT::BlendOp != STYLEOP_Fuzz)
{
uint32_t texelX = (((posU << 8) >> 16) * texWidth) >> 16;
uint32_t texelY = (((posV << 8) >> 16) * texHeight) >> 16;
fg = texPixels[texelX * texHeight + texelY];
if (ModeT::SWFlags & SWSTYLEF_Translated)
fg = translation[fg];
fgalpha = (fg != 0) ? 255 : 0;
}
if (ModeT::BlendOp == STYLEOP_Fuzz) if (ModeT::BlendOp == STYLEOP_Fuzz)
{ {
using namespace swrenderer; using namespace swrenderer;
@ -1492,6 +1541,26 @@ void DrawRect8(const void *destOrg, int destWidth, int destHeight, int destPitch
} }
else else
{ {
int fg = 0;
if (ModeT::SWFlags & SWSTYLEF_Fill)
{
fg = fillcolor;
}
else
{
uint32_t texelX = (((posU << 8) >> 16) * texWidth) >> 16;
uint32_t texelY = (((posV << 8) >> 16) * texHeight) >> 16;
fg = texPixels[texelX * texHeight + texelY];
}
int fgalpha = 255;
if (ModeT::BlendDest == STYLEALPHA_InvSrc)
{
if (fg == 0)
fgalpha = 0;
}
if ((ModeT::Flags & STYLEF_ColorIsFixed) && !(ModeT::SWFlags & SWSTYLEF_Fill)) if ((ModeT::Flags & STYLEF_ColorIsFixed) && !(ModeT::SWFlags & SWSTYLEF_Fill))
{ {
if (ModeT::Flags & STYLEF_RedIsAlpha) if (ModeT::Flags & STYLEF_RedIsAlpha)
@ -1504,6 +1573,9 @@ void DrawRect8(const void *destOrg, int destWidth, int destHeight, int destPitch
fgalpha = (fgalpha * alpha) >> 8; fgalpha = (fgalpha * alpha) >> 8;
} }
if (ModeT::SWFlags & SWSTYLEF_Translated)
fg = translation[fg];
uint8_t shadedfg = colormaps[light + fg]; uint8_t shadedfg = colormaps[light + fg];
if (ModeT::BlendSrc == STYLEALPHA_One && ModeT::BlendDest == STYLEALPHA_Zero) if (ModeT::BlendSrc == STYLEALPHA_One && ModeT::BlendDest == STYLEALPHA_Zero)
@ -1684,35 +1756,6 @@ void DrawRectOpt32(const void *destOrg, int destWidth, int destHeight, int destP
uint32_t posU = startU; uint32_t posU = startU;
for (int x = x0; x < x1; x++) for (int x = x0; x < x1; x++)
{ {
uint32_t fg = 0;
if (ModeT::SWFlags & SWSTYLEF_Fill)
{
fg = fillcolor;
}
else if (ModeT::SWFlags & SWSTYLEF_FogBoundary)
{
fg = destLine[x];
}
else if (ModeT::BlendOp != STYLEOP_Fuzz)
{
uint32_t texelX = (((posU << 8) >> 16) * texWidth) >> 16;
uint32_t texelY = (((posV << 8) >> 16) * texHeight) >> 16;
if (ModeT::SWFlags & SWSTYLEF_Translated)
{
fg = translation[((const uint8_t*)texPixels)[texelX * texHeight + texelY]];
}
else if (ModeT::Flags & STYLEF_RedIsAlpha)
{
fg = ((const uint8_t*)texPixels)[texelX * texHeight + texelY];
}
else
{
fg = texPixels[texelX * texHeight + texelY];
}
}
if (ModeT::BlendOp == STYLEOP_Fuzz) if (ModeT::BlendOp == STYLEOP_Fuzz)
{ {
using namespace swrenderer; using namespace swrenderer;
@ -1743,6 +1786,35 @@ void DrawRectOpt32(const void *destOrg, int destWidth, int destHeight, int destP
} }
else else
{ {
uint32_t fg = 0;
if (ModeT::SWFlags & SWSTYLEF_Fill)
{
fg = fillcolor;
}
else if (ModeT::SWFlags & SWSTYLEF_FogBoundary)
{
fg = destLine[x];
}
else
{
uint32_t texelX = (((posU << 8) >> 16) * texWidth) >> 16;
uint32_t texelY = (((posV << 8) >> 16) * texHeight) >> 16;
if (ModeT::SWFlags & SWSTYLEF_Translated)
{
fg = translation[((const uint8_t*)texPixels)[texelX * texHeight + texelY]];
}
else if (ModeT::Flags & STYLEF_RedIsAlpha)
{
fg = ((const uint8_t*)texPixels)[texelX * texHeight + texelY];
}
else
{
fg = texPixels[texelX * texHeight + texelY];
}
}
if ((ModeT::Flags & STYLEF_ColorIsFixed) && !(ModeT::SWFlags & SWSTYLEF_Fill)) if ((ModeT::Flags & STYLEF_ColorIsFixed) && !(ModeT::SWFlags & SWSTYLEF_Fill))
{ {
if (ModeT::Flags & STYLEF_RedIsAlpha) if (ModeT::Flags & STYLEF_RedIsAlpha)