From 9cd751ae7ac1316209b0ed20eebae45d2b57a696 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Tue, 5 Jun 2018 15:16:04 +0200 Subject: [PATCH] - fix softpoly colored fog bug in the new drawers --- src/polyrenderer/drawers/poly_draw_args.cpp | 19 +- src/polyrenderer/drawers/screen_triangle.cpp | 414 +++++++++++-------- 2 files changed, 257 insertions(+), 176 deletions(-) diff --git a/src/polyrenderer/drawers/poly_draw_args.cpp b/src/polyrenderer/drawers/poly_draw_args.cpp index 3e02940cd6..3a921ae0aa 100644 --- a/src/polyrenderer/drawers/poly_draw_args.cpp +++ b/src/polyrenderer/drawers/poly_draw_args.cpp @@ -106,15 +106,24 @@ void PolyDrawArgs::SetLight(FSWColormap *base_colormap, uint32_t lightlevel, dou mLight = clamp(lightlevel, 0, 255); mFixedLight = fixed; - mLightRed = base_colormap->Color.r * 256 / 255; - mLightGreen = base_colormap->Color.g * 256 / 255; - mLightBlue = base_colormap->Color.b * 256 / 255; - mLightAlpha = base_colormap->Color.a * 256 / 255; + mLightRed = base_colormap->Color.r; + mLightRed += mLightRed >> 7; + mLightGreen = base_colormap->Color.g; + 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 += mFadeRed >> 7; mFadeGreen = base_colormap->Fade.g; + mFadeGreen += mFadeGreen >> 7; mFadeBlue = base_colormap->Fade.b; + mFadeBlue += mFadeBlue >> 7; 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); mColormaps = base_colormap->Maps; } diff --git a/src/polyrenderer/drawers/screen_triangle.cpp b/src/polyrenderer/drawers/screen_triangle.cpp index 858ed06339..98d8ecbf02 100644 --- a/src/polyrenderer/drawers/screen_triangle.cpp +++ b/src/polyrenderer/drawers/screen_triangle.cpp @@ -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 startX, startY; - float stepXW, stepXU, stepXV, stepWorldX, stepWorldY, stepWorldZ; - float posXW, posXU, posXV, posWorldX, posWorldY, posWorldZ; + float stepW, stepU, stepV, stepWorldX, stepWorldY, stepWorldZ; + float posW, posU, posV, posWorldX, posWorldY, posWorldZ; PolyLight *lights; int num_lights; @@ -410,12 +410,12 @@ void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args) v1V = args->v1->v * v1W; startX = x0 + (0.5f - v1X); startY = y + (0.5f - v1Y); - stepXW = args->gradientX.W; - stepXU = args->gradientX.U; - stepXV = args->gradientX.V; - posXW = v1W + stepXW * startX + args->gradientY.W * startY; - posXU = v1U + stepXU * startX + args->gradientY.U * startY; - posXV = v1V + stepXV * startX + args->gradientY.V * startY; + stepW = args->gradientX.W; + stepU = args->gradientX.U; + stepV = args->gradientX.V; + posW = v1W + stepW * startX + args->gradientY.W * startY; + posU = v1U + stepU * startX + args->gradientY.U * startY; + posV = v1V + stepV * startX + args->gradientY.V * startY; texPixels = (const uint32_t*)args->uniforms->TexturePixels(); 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); shade = (fixed_t)((2.0f - (light + 12.0f) / 128.0f) * (float)FRACUNIT); - lightpos = (fixed_t)(globVis * posXW * (float)FRACUNIT); - lightstep = (fixed_t)(globVis * stepXW * (float)FRACUNIT); + lightpos = (fixed_t)(globVis * posW * (float)FRACUNIT); + lightstep = (fixed_t)(globVis * stepW * (float)FRACUNIT); int affineOffset = x0 / 16 * 16 - x0; lightpos = lightpos + lightstep * affineOffset; @@ -481,11 +481,11 @@ void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args) dynlightcolor = args->uniforms->DynLightColor(); int affineOffset = x0 / 16 * 16 - x0; - float posLightW = posXW + stepXW * affineOffset; + float posLightW = posW + stepW * affineOffset; posWorldX = posWorldX + stepWorldX * affineOffset; posWorldY = posWorldY + stepWorldY * affineOffset; posWorldZ = posWorldZ + stepWorldZ * affineOffset; - float stepLightW = stepXW * 16.0f; + float stepLightW = stepW * 16.0f; stepWorldX *= 16.0f; stepWorldY *= 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_b = BPART(dynlightcolor); - float rcp_posXW = 1.0f / posLightW; - float worldposX = posWorldX * rcp_posXW; - float worldposY = posWorldY * rcp_posXW; - float worldposZ = posWorldZ * rcp_posXW; + float rcp_posW = 1.0f / posLightW; + float worldposX = posWorldX * rcp_posW; + float worldposY = posWorldY * rcp_posW; + float worldposZ = posWorldZ * rcp_posW; for (int i = 0; i < num_lights; i++) { float lightposX = lights[i].x; @@ -592,45 +592,13 @@ void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args) int x = x0; 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) { using namespace swrenderer; - float rcpW = 0x01000000 / posXW; - int32_t u = (int32_t)(posXU * rcpW); - int32_t v = (int32_t)(posXV * rcpW); + 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; 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) { - float rcpW = 0x01000000 / posXW; - int32_t v = (int32_t)(posXV * rcpW); + 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; + + uint32_t fg = texPixels[texelX * texHeight + texelY]; int start_fade = 2; // How fast it should fade out 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); } } + 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 { + 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_RedIsAlpha) @@ -713,14 +749,6 @@ void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args) 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; 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_b = BPART(fg); 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; - shadedfg_g = (((shade_fade_g + ((fg_g * inv_desaturate + intensity) >> 8) * lightshade) >> 8) * shade_light_g) >> 8; - shadedfg_b = (((shade_fade_b + ((fg_b * inv_desaturate + intensity) >> 8) * lightshade) >> 8) * shade_light_b) >> 8; + 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; - 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); + if (OptT::Flags & SWOPT_DynLights) + { + 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 { - 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; + if (OptT::Flags & SWOPT_DynLights) + { + 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) @@ -852,9 +899,9 @@ void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args) } } - posXW += stepXW; - posXU += stepXU; - posXV += stepXV; + posW += stepW; + posU += stepU; + posV += stepV; if (OptT::Flags & SWOPT_DynLights) { 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 startX, startY; - float stepXW, stepXU, stepXV, stepWorldX, stepWorldY, stepWorldZ; - float posXW, posXU, posXV, posWorldX, posWorldY, posWorldZ; + float stepW, stepU, stepV, stepWorldX, stepWorldY, stepWorldZ; + float posW, posU, posV, posWorldX, posWorldY, posWorldZ; PolyLight *lights; int num_lights; @@ -939,12 +986,12 @@ void DrawSpanOpt8(int y, int x0, int x1, const TriDrawTriangleArgs *args) v1V = args->v1->v * v1W; startX = x0 + (0.5f - v1X); startY = y + (0.5f - v1Y); - stepXW = args->gradientX.W; - stepXU = args->gradientX.U; - stepXV = args->gradientX.V; - posXW = v1W + stepXW * startX + args->gradientY.W * startY; - posXU = v1U + stepXU * startX + args->gradientY.U * startY; - posXV = v1V + stepXV * startX + args->gradientY.V * startY; + stepW = args->gradientX.W; + stepU = args->gradientX.U; + stepV = args->gradientX.V; + posW = v1W + stepW * startX + args->gradientY.W * startY; + posU = v1U + stepU * startX + args->gradientY.U * startY; + posV = v1V + stepV * startX + args->gradientY.V * startY; texPixels = args->uniforms->TexturePixels(); 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); shade = (fixed_t)((2.0f - (light + 12.0f) / 128.0f) * (float)FRACUNIT); - lightpos = (fixed_t)(globVis * posXW * (float)FRACUNIT); - lightstep = (fixed_t)(globVis * stepXW * (float)FRACUNIT); + lightpos = (fixed_t)(globVis * posW * (float)FRACUNIT); + lightstep = (fixed_t)(globVis * stepW * (float)FRACUNIT); int affineOffset = x0 / 16 * 16 - x0; lightpos = lightpos + lightstep * affineOffset; @@ -1015,11 +1062,11 @@ void DrawSpanOpt8(int y, int x0, int x1, const TriDrawTriangleArgs *args) dynlightcolor = args->uniforms->DynLightColor(); int affineOffset = x0 / 16 * 16 - x0; - float posLightW = posXW + stepXW * affineOffset; + float posLightW = posW + stepW * affineOffset; posWorldX = posWorldX + stepWorldX * affineOffset; posWorldY = posWorldY + stepWorldY * affineOffset; posWorldZ = posWorldZ + stepWorldZ * affineOffset; - float stepLightW = stepXW * 16.0f; + float stepLightW = stepW * 16.0f; stepWorldX *= 16.0f; stepWorldY *= 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_b = BPART(dynlightcolor); - float rcp_posXW = 1.0f / posLightW; - float worldposX = posWorldX * rcp_posXW; - float worldposY = posWorldY * rcp_posXW; - float worldposZ = posWorldZ * rcp_posXW; + float rcp_posW = 1.0f / posLightW; + float worldposX = posWorldX * rcp_posW; + float worldposY = posWorldY * rcp_posW; + float worldposZ = posWorldZ * rcp_posW; for (int i = 0; i < num_lights; i++) { float lightposX = lights[i].x; @@ -1114,39 +1161,13 @@ void DrawSpanOpt8(int y, int x0, int x1, const TriDrawTriangleArgs *args) int x = x0; 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) { using namespace swrenderer; - float rcpW = 0x01000000 / posXW; - int32_t u = (int32_t)(posXU * rcpW); - int32_t v = (int32_t)(posXV * rcpW); + 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; 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) { - float rcpW = 0x01000000 / posXW; - int32_t v = (int32_t)(posXV * rcpW); + 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; + int fg = texPixels[texelX * texHeight + texelY]; int start_fade = 2; // How fast it should fade out 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)]; } } + 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 { + 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_RedIsAlpha) @@ -1217,6 +1282,9 @@ void DrawSpanOpt8(int y, int x0, int x1, const TriDrawTriangleArgs *args) fgalpha = (fgalpha * alpha) >> 8; } + if (ModeT::SWFlags & SWSTYLEF_Translated) + fg = translation[fg]; + uint8_t shadedfg; if (OptT::Flags & SWOPT_FixedLight) { @@ -1359,9 +1427,9 @@ void DrawSpanOpt8(int y, int x0, int x1, const TriDrawTriangleArgs *args) } } - posXW += stepXW; - posXU += stepXU; - posXV += stepXV; + posW += stepW; + posU += stepU; + posV += stepV; if (OptT::Flags & SWOPT_DynLights) { 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; 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) { using namespace swrenderer; @@ -1492,6 +1541,26 @@ void DrawRect8(const void *destOrg, int destWidth, int destHeight, int destPitch } 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_RedIsAlpha) @@ -1504,6 +1573,9 @@ void DrawRect8(const void *destOrg, int destWidth, int destHeight, int destPitch fgalpha = (fgalpha * alpha) >> 8; } + if (ModeT::SWFlags & SWSTYLEF_Translated) + fg = translation[fg]; + uint8_t shadedfg = colormaps[light + fg]; 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; 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) { using namespace swrenderer; @@ -1743,6 +1786,35 @@ void DrawRectOpt32(const void *destOrg, int destWidth, int destHeight, int destP } 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_RedIsAlpha)