diff --git a/src/r_draw.cpp b/src/r_draw.cpp index 9d7160d012..45758ee610 100644 --- a/src/r_draw.cpp +++ b/src/r_draw.cpp @@ -2235,6 +2235,246 @@ void tmvline4_revsubclamp_C () } while (--count); } +void R_DrawSingleSkyCol1(uint32_t solid_top, uint32_t solid_bottom) +{ + uint8_t *dest = dc_dest; + int count = dc_count; + int pitch = dc_pitch; + const uint8_t *source0 = bufplce[0]; + int textureheight0 = bufheight[0]; + + int32_t frac = vplce[0]; + int32_t fracstep = vince[0]; + + int start_fade = 2; // How fast it should fade out + + int solid_top_r = RPART(solid_top); + int solid_top_g = GPART(solid_top); + int solid_top_b = BPART(solid_top); + int solid_bottom_r = RPART(solid_bottom); + int solid_bottom_g = GPART(solid_bottom); + int solid_bottom_b = BPART(solid_bottom); + + for (int index = 0; index < count; index++) + { + uint32_t sample_index = (((((uint32_t)frac) << 8) >> FRACBITS) * textureheight0) >> FRACBITS; + uint8_t fg = source0[sample_index]; + + int alpha_top = MAX(MIN(frac >> (16 - start_fade), 256), 0); + int alpha_bottom = MAX(MIN(((2 << 24) - frac) >> (16 - start_fade), 256), 0); + + if (alpha_top == 256 && alpha_bottom == 256) + { + *dest = fg; + } + else + { + int inv_alpha_top = 256 - alpha_top; + int inv_alpha_bottom = 256 - alpha_bottom; + + const auto &c = GPalette.BaseColors[fg]; + int c_red = c.r; + int c_green = c.g; + int c_blue = c.b; + c_red = (c_red * alpha_top + solid_top_r * inv_alpha_top) >> 8; + c_green = (c_green * alpha_top + solid_top_g * inv_alpha_top) >> 8; + c_blue = (c_blue * alpha_top + solid_top_b * inv_alpha_top) >> 8; + c_red = (c_red * alpha_bottom + solid_bottom_r * inv_alpha_bottom) >> 8; + c_green = (c_green * alpha_bottom + solid_bottom_g * inv_alpha_bottom) >> 8; + c_blue = (c_blue * alpha_bottom + solid_bottom_b * inv_alpha_bottom) >> 8; + *dest = RGB32k.RGB[(c_red >> 3)][(c_green >> 3)][(c_blue >> 3)]; + } + + frac += fracstep; + dest += pitch; + } +} + +void R_DrawSingleSkyCol4(uint32_t solid_top, uint32_t solid_bottom) +{ + for (int col = 0; col < 4; col++) + { + uint8_t *dest = dc_dest + col; + int count = dc_count; + int pitch = dc_pitch; + const uint8_t *source0 = bufplce[col]; + int textureheight0 = bufheight[0]; + + int32_t frac = vplce[col]; + int32_t fracstep = vince[col]; + + int start_fade = 2; // How fast it should fade out + + int solid_top_r = RPART(solid_top); + int solid_top_g = GPART(solid_top); + int solid_top_b = BPART(solid_top); + int solid_bottom_r = RPART(solid_bottom); + int solid_bottom_g = GPART(solid_bottom); + int solid_bottom_b = BPART(solid_bottom); + + for (int index = 0; index < count; index++) + { + uint32_t sample_index = (((((uint32_t)frac) << 8) >> FRACBITS) * textureheight0) >> FRACBITS; + uint8_t fg = source0[sample_index]; + + int alpha_top = MAX(MIN(frac >> (16 - start_fade), 256), 0); + int alpha_bottom = MAX(MIN(((2 << 24) - frac) >> (16 - start_fade), 256), 0); + + if (alpha_top == 256 && alpha_bottom == 256) + { + *dest = fg; + } + else + { + int inv_alpha_top = 256 - alpha_top; + int inv_alpha_bottom = 256 - alpha_bottom; + + const auto &c = GPalette.BaseColors[fg]; + int c_red = c.r; + int c_green = c.g; + int c_blue = c.b; + c_red = (c_red * alpha_top + solid_top_r * inv_alpha_top) >> 8; + c_green = (c_green * alpha_top + solid_top_g * inv_alpha_top) >> 8; + c_blue = (c_blue * alpha_top + solid_top_b * inv_alpha_top) >> 8; + c_red = (c_red * alpha_bottom + solid_bottom_r * inv_alpha_bottom) >> 8; + c_green = (c_green * alpha_bottom + solid_bottom_g * inv_alpha_bottom) >> 8; + c_blue = (c_blue * alpha_bottom + solid_bottom_b * inv_alpha_bottom) >> 8; + *dest = RGB32k.RGB[(c_red >> 3)][(c_green >> 3)][(c_blue >> 3)]; + } + + frac += fracstep; + dest += pitch; + } + } +} + +void R_DrawDoubleSkyCol1(uint32_t solid_top, uint32_t solid_bottom) +{ + uint8_t *dest = dc_dest; + int count = dc_count; + int pitch = dc_pitch; + const uint8_t *source0 = bufplce[0]; + const uint8_t *source1 = bufplce2[0]; + int textureheight0 = bufheight[0]; + uint32_t maxtextureheight1 = bufheight[1] - 1; + + int32_t frac = vplce[0]; + int32_t fracstep = vince[0]; + + int start_fade = 2; // How fast it should fade out + + int solid_top_r = RPART(solid_top); + int solid_top_g = GPART(solid_top); + int solid_top_b = BPART(solid_top); + int solid_bottom_r = RPART(solid_bottom); + int solid_bottom_g = GPART(solid_bottom); + int solid_bottom_b = BPART(solid_bottom); + + for (int index = 0; index < count; index++) + { + uint32_t sample_index = (((((uint32_t)frac) << 8) >> FRACBITS) * textureheight0) >> FRACBITS; + uint8_t fg = source0[sample_index]; + if (fg == 0) + { + uint32_t sample_index2 = MIN(sample_index, maxtextureheight1); + fg = source1[sample_index2]; + } + + int alpha_top = MAX(MIN(frac >> (16 - start_fade), 256), 0); + int alpha_bottom = MAX(MIN(((2 << 24) - frac) >> (16 - start_fade), 256), 0); + + if (alpha_top == 256 && alpha_bottom == 256) + { + *dest = fg; + } + else + { + int inv_alpha_top = 256 - alpha_top; + int inv_alpha_bottom = 256 - alpha_bottom; + + const auto &c = GPalette.BaseColors[fg]; + int c_red = c.r; + int c_green = c.g; + int c_blue = c.b; + c_red = (c_red * alpha_top + solid_top_r * inv_alpha_top) >> 8; + c_green = (c_green * alpha_top + solid_top_g * inv_alpha_top) >> 8; + c_blue = (c_blue * alpha_top + solid_top_b * inv_alpha_top) >> 8; + c_red = (c_red * alpha_bottom + solid_bottom_r * inv_alpha_bottom) >> 8; + c_green = (c_green * alpha_bottom + solid_bottom_g * inv_alpha_bottom) >> 8; + c_blue = (c_blue * alpha_bottom + solid_bottom_b * inv_alpha_bottom) >> 8; + *dest = RGB32k.RGB[(c_red >> 3)][(c_green >> 3)][(c_blue >> 3)]; + } + + frac += fracstep; + dest += pitch; + } +} + +void R_DrawDoubleSkyCol4(uint32_t solid_top, uint32_t solid_bottom) +{ + for (int col = 0; col < 4; col++) + { + uint8_t *dest = dc_dest + col; + int count = dc_count; + int pitch = dc_pitch; + const uint8_t *source0 = bufplce[col]; + const uint8_t *source1 = bufplce2[col]; + int textureheight0 = bufheight[0]; + uint32_t maxtextureheight1 = bufheight[1] - 1; + + int32_t frac = vplce[col]; + int32_t fracstep = vince[col]; + + int start_fade = 2; // How fast it should fade out + + int solid_top_r = RPART(solid_top); + int solid_top_g = GPART(solid_top); + int solid_top_b = BPART(solid_top); + int solid_bottom_r = RPART(solid_bottom); + int solid_bottom_g = GPART(solid_bottom); + int solid_bottom_b = BPART(solid_bottom); + + for (int index = 0; index < count; index++) + { + uint32_t sample_index = (((((uint32_t)frac) << 8) >> FRACBITS) * textureheight0) >> FRACBITS; + uint8_t fg = source0[sample_index]; + if (fg == 0) + { + uint32_t sample_index2 = MIN(sample_index, maxtextureheight1); + fg = source1[sample_index2]; + } + + int alpha_top = MAX(MIN(frac >> (16 - start_fade), 256), 0); + int alpha_bottom = MAX(MIN(((2 << 24) - frac) >> (16 - start_fade), 256), 0); + + if (alpha_top == 256 && alpha_bottom == 256) + { + *dest = fg; + } + else + { + int inv_alpha_top = 256 - alpha_top; + int inv_alpha_bottom = 256 - alpha_bottom; + + const auto &c = GPalette.BaseColors[fg]; + int c_red = c.r; + int c_green = c.g; + int c_blue = c.b; + c_red = (c_red * alpha_top + solid_top_r * inv_alpha_top) >> 8; + c_green = (c_green * alpha_top + solid_top_g * inv_alpha_top) >> 8; + c_blue = (c_blue * alpha_top + solid_top_b * inv_alpha_top) >> 8; + c_red = (c_red * alpha_bottom + solid_bottom_r * inv_alpha_bottom) >> 8; + c_green = (c_green * alpha_bottom + solid_bottom_g * inv_alpha_bottom) >> 8; + c_blue = (c_blue * alpha_bottom + solid_bottom_b * inv_alpha_bottom) >> 8; + *dest = RGB32k.RGB[(c_red >> 3)][(c_green >> 3)][(c_blue >> 3)]; + } + + frac += fracstep; + dest += pitch; + } + } +} + //========================================================================== // // R_GetColumn diff --git a/src/r_draw.h b/src/r_draw.h index 7b12c43bb1..601962809b 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -387,6 +387,11 @@ void R_DrawSingleSkyCol4(uint32_t solid_top, uint32_t solid_bottom); void R_DrawDoubleSkyCol1(uint32_t solid_top, uint32_t solid_bottom); void R_DrawDoubleSkyCol4(uint32_t solid_top, uint32_t solid_bottom); +void R_DrawSingleSkyCol1_rgba(uint32_t solid_top, uint32_t solid_bottom); +void R_DrawSingleSkyCol4_rgba(uint32_t solid_top, uint32_t solid_bottom); +void R_DrawDoubleSkyCol1_rgba(uint32_t solid_top, uint32_t solid_bottom); +void R_DrawDoubleSkyCol4_rgba(uint32_t solid_top, uint32_t solid_bottom); + struct TriVertex { TriVertex() { } diff --git a/src/r_draw_rgba.cpp b/src/r_draw_rgba.cpp index 9b15d06cef..2b9eb86e75 100644 --- a/src/r_draw_rgba.cpp +++ b/src/r_draw_rgba.cpp @@ -1692,22 +1692,22 @@ void R_DrawTriangles(const VSMatrix &objectToWorld, const TriVertex *vertices, i ///////////////////////////////////////////////////////////////////////////// -void R_DrawSingleSkyCol1(uint32_t solid_top, uint32_t solid_bottom) +void R_DrawSingleSkyCol1_rgba(uint32_t solid_top, uint32_t solid_bottom) { DrawerCommandQueue::QueueCommand(solid_top, solid_bottom); } -void R_DrawSingleSkyCol4(uint32_t solid_top, uint32_t solid_bottom) +void R_DrawSingleSkyCol4_rgba(uint32_t solid_top, uint32_t solid_bottom) { DrawerCommandQueue::QueueCommand(solid_top, solid_bottom); } -void R_DrawDoubleSkyCol1(uint32_t solid_top, uint32_t solid_bottom) +void R_DrawDoubleSkyCol1_rgba(uint32_t solid_top, uint32_t solid_bottom) { DrawerCommandQueue::QueueCommand(solid_top, solid_bottom); } -void R_DrawDoubleSkyCol4(uint32_t solid_top, uint32_t solid_bottom) +void R_DrawDoubleSkyCol4_rgba(uint32_t solid_top, uint32_t solid_bottom) { DrawerCommandQueue::QueueCommand(solid_top, solid_bottom); } diff --git a/src/r_plane.cpp b/src/r_plane.cpp index b8cda2fcb1..e8fc31ec1d 100644 --- a/src/r_plane.cpp +++ b/src/r_plane.cpp @@ -1020,30 +1020,55 @@ static void R_DrawSkyColumnStripe(int start_x, int y1, int y2, int columns, doub angle1 = (DWORD)((UMulScale16(ang, frontcyl) + frontpos) >> FRACBITS); angle2 = (DWORD)((UMulScale16(ang, backcyl) + backpos) >> FRACBITS); - bufplce[i] = (const BYTE *)frontskytex->GetColumnBgra(angle1, nullptr); - bufplce2[i] = backskytex ? (const BYTE *)backskytex->GetColumnBgra(angle2, nullptr) : nullptr; + if (r_swtruecolor) + { + bufplce[i] = (const BYTE *)frontskytex->GetColumnBgra(angle1, nullptr); + bufplce2[i] = backskytex ? (const BYTE *)backskytex->GetColumnBgra(angle2, nullptr) : nullptr; + } + else + { + bufplce[i] = (const BYTE *)frontskytex->GetColumn(angle1, nullptr); + bufplce2[i] = backskytex ? (const BYTE *)backskytex->GetColumn(angle2, nullptr) : nullptr; + } vince[i] = uv_step; vplce[i] = uv_pos; } bufheight[0] = height; bufheight[1] = backskytex ? backskytex->GetHeight() : height; - dc_dest = (ylookup[y1] + start_x) * 4 + dc_destorg; + int pixelsize = r_swtruecolor ? 4 : 1; + dc_dest = (ylookup[y1] + start_x) * pixelsize + dc_destorg; dc_count = y2 - y1; uint32_t solid_top = frontskytex->GetSkyCapColor(false); uint32_t solid_bottom = frontskytex->GetSkyCapColor(true); - if (columns == 4) - if (!backskytex) - R_DrawSingleSkyCol4(solid_top, solid_bottom); + if (r_swtruecolor) + { + if (columns == 4) + if (!backskytex) + R_DrawSingleSkyCol4_rgba(solid_top, solid_bottom); + else + R_DrawDoubleSkyCol4_rgba(solid_top, solid_bottom); else - R_DrawDoubleSkyCol4(solid_top, solid_bottom); + if (!backskytex) + R_DrawSingleSkyCol1_rgba(solid_top, solid_bottom); + else + R_DrawDoubleSkyCol1_rgba(solid_top, solid_bottom); + } else - if (!backskytex) - R_DrawSingleSkyCol1(solid_top, solid_bottom); + { + if (columns == 4) + if (!backskytex) + R_DrawSingleSkyCol4(solid_top, solid_bottom); + else + R_DrawDoubleSkyCol4(solid_top, solid_bottom); else - R_DrawDoubleSkyCol1(solid_top, solid_bottom); + if (!backskytex) + R_DrawSingleSkyCol1(solid_top, solid_bottom); + else + R_DrawDoubleSkyCol1(solid_top, solid_bottom); + } } static void R_DrawSkyColumn(int start_x, int y1, int y2, int columns) @@ -1253,7 +1278,7 @@ static void R_DrawSky (visplane_t *pl) R_DrawCubeSky(pl); return; } - else if (r_swtruecolor && r_capsky) + else if (r_capsky) { R_DrawCapSky(pl); return;