From 821b10a254867350af85e4d273b50fc920ac4577 Mon Sep 17 00:00:00 2001 From: Rachael Alexanderson Date: Sat, 17 Dec 2016 04:11:52 -0500 Subject: [PATCH] - Implementing RGB666 colormatching to replace less precise RGB555 in some parts of the code. --- src/f_wipe.cpp | 29 +- src/r_draw.cpp | 12 +- src/r_draw.h | 1 - src/r_draw_pal.cpp | 436 +++++++++++++---------------- src/r_draw_pal.h | 6 + src/r_drawt_pal.cpp | 272 ++++++------------ src/r_plane.cpp | 16 +- src/r_things.cpp | 43 +-- src/r_things.h | 2 +- src/textures/ddstexture.cpp | 8 +- src/textures/jpegtexture.cpp | 4 +- src/textures/multipatchtexture.cpp | 2 +- src/textures/pcxtexture.cpp | 2 +- src/textures/pngtexture.cpp | 6 +- src/textures/tgatexture.cpp | 8 +- src/v_draw.cpp | 33 +-- src/v_video.cpp | 70 ++--- src/v_video.h | 41 +-- 18 files changed, 366 insertions(+), 625 deletions(-) diff --git a/src/f_wipe.cpp b/src/f_wipe.cpp index a3ceb8d50..8d5f072f6 100644 --- a/src/f_wipe.cpp +++ b/src/f_wipe.cpp @@ -28,6 +28,7 @@ #include "f_wipe.h" #include "c_cvars.h" #include "templates.h" +#include "v_palette.h" // // SCREEN WIPE PACKAGE @@ -299,12 +300,15 @@ bool wipe_doBurn (int ticks) else { int bglevel = 64-fglevel; - DWORD *fg2rgb = Col2RGB8[fglevel]; - DWORD *bg2rgb = Col2RGB8[bglevel]; - DWORD fg = fg2rgb[fromnew[x]]; - DWORD bg = bg2rgb[fromold[x]]; - fg = (fg+bg) | 0x1f07c1f; - to[x] = RGB32k.All[fg & (fg>>15)]; + + const PalEntry* pal = GPalette.BaseColors; + + DWORD fg = fromnew[x]; + DWORD bg = fromold[x]; + int r = MIN((pal[fg].r * fglevel + pal[bg].r * bglevel) >> 8, 63); + int g = MIN((pal[fg].g * fglevel + pal[bg].g * bglevel) >> 8, 63); + int b = MIN((pal[fg].b * fglevel + pal[bg].b * bglevel) >> 8, 63); + to[x] = RGB256k.RGB[r][g][b]; done = false; } } @@ -342,20 +346,21 @@ bool wipe_doFade (int ticks) { int x, y; int bglevel = 64 - fade; - DWORD *fg2rgb = Col2RGB8[fade]; - DWORD *bg2rgb = Col2RGB8[bglevel]; BYTE *fromnew = (BYTE *)wipe_scr_end; BYTE *fromold = (BYTE *)wipe_scr_start; BYTE *to = screen->GetBuffer(); + const PalEntry *pal = GPalette.BaseColors; for (y = 0; y < SCREENHEIGHT; y++) { for (x = 0; x < SCREENWIDTH; x++) { - DWORD fg = fg2rgb[fromnew[x]]; - DWORD bg = bg2rgb[fromold[x]]; - fg = (fg+bg) | 0x1f07c1f; - to[x] = RGB32k.All[fg & (fg>>15)]; + DWORD fg = fromnew[x]; + DWORD bg = fromold[x]; + int r = MIN((pal[fg].r * (64-bglevel) + pal[bg].r * bglevel) >> 8, 63); + int g = MIN((pal[fg].g * (64-bglevel) + pal[bg].g * bglevel) >> 8, 63); + int b = MIN((pal[fg].b * (64-bglevel) + pal[bg].b * bglevel) >> 8, 63); + to[x] = RGB256k.RGB[r][g][b]; } fromnew += SCREENWIDTH; fromold += SCREENWIDTH; diff --git a/src/r_draw.cpp b/src/r_draw.cpp index 25297f6c8..20127f50d 100644 --- a/src/r_draw.cpp +++ b/src/r_draw.cpp @@ -238,22 +238,16 @@ namespace swrenderer } if (flags & STYLEF_InvertSource) { - dc_srcblend = Col2RGB8_Inverse[fglevel >> 10]; - dc_destblend = Col2RGB8_LessPrecision[bglevel >> 10]; dc_srcalpha = fglevel; dc_destalpha = bglevel; } else if (op == STYLEOP_Add && fglevel + bglevel <= FRACUNIT) { - dc_srcblend = Col2RGB8[fglevel >> 10]; - dc_destblend = Col2RGB8[bglevel >> 10]; dc_srcalpha = fglevel; dc_destalpha = bglevel; } else { - dc_srcblend = Col2RGB8_LessPrecision[fglevel >> 10]; - dc_destblend = Col2RGB8_LessPrecision[bglevel >> 10]; dc_srcalpha = fglevel; dc_destalpha = bglevel; } @@ -450,7 +444,7 @@ namespace swrenderer uint32_t g = GPART(color); uint32_t b = BPART(color); // dc_color is used by the rt_* routines. It is indexed into dc_srcblend. - dc_color = RGB32k.RGB[r >> 3][g >> 3][b >> 3]; + dc_color = RGB256k.RGB[r >> 2][g >> 2][b >> 2]; if (style.Flags & STYLEF_InvertSource) { r = 255 - r; @@ -1362,8 +1356,4 @@ namespace swrenderer } } - void R_DrawParticle(vissprite_t *sprite) - { - R_DrawParticle_C(sprite); - } } diff --git a/src/r_draw.h b/src/r_draw.h index ab430d2af..d9ad7a2da 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -203,5 +203,4 @@ namespace swrenderer void R_MapTiltedPlane(int y, int x1); void R_MapColoredPlane(int y, int x1); - void R_DrawParticle(vissprite_t *); } diff --git a/src/r_draw_pal.cpp b/src/r_draw_pal.cpp index cfb55a670..fe6c63b6d 100644 --- a/src/r_draw_pal.cpp +++ b/src/r_draw_pal.cpp @@ -4,6 +4,7 @@ **--------------------------------------------------------------------------- ** Copyright 1998-2016 Randy Heit ** Copyright 2016 Magnus Norddahl +** Copyright 2016 Rachael Alexanderson ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without @@ -314,10 +315,10 @@ namespace swrenderer uint8_t pix = source[frac >> bits]; if (pix != 0) { - uint32_t fg = fg2rgb[colormap[pix]]; - uint32_t bg = bg2rgb[*dest]; - fg = (fg + bg) | 0x1f07c1f; - *dest = RGB32k.All[fg & (fg >> 15)]; + uint32_t r = MIN(GPalette.BaseColors[colormap[pix]].r + GPalette.BaseColors[*dest].r, 255); + uint32_t g = MIN(GPalette.BaseColors[colormap[pix]].g + GPalette.BaseColors[*dest].g, 255); + uint32_t b = MIN(GPalette.BaseColors[colormap[pix]].b + GPalette.BaseColors[*dest].b, 255); + *dest = RGB256k.RGB[r>>2][g>>2][b>>2]; } frac += fracstep; dest += pitch; @@ -357,10 +358,10 @@ namespace swrenderer uint8_t pix = _bufplce[i][vplce[i] >> bits]; if (pix != 0) { - uint32_t fg = fg2rgb[_palookupoffse[i][pix]]; - uint32_t bg = bg2rgb[dest[i]]; - fg = (fg + bg) | 0x1f07c1f; - dest[i] = RGB32k.All[fg & (fg >> 15)]; + uint32_t r = MIN(GPalette.BaseColors[_palookupoffse[i][pix]].r + GPalette.BaseColors[dest[i]].r, 255); + uint32_t g = MIN(GPalette.BaseColors[_palookupoffse[i][pix]].g + GPalette.BaseColors[dest[i]].g, 255); + uint32_t b = MIN(GPalette.BaseColors[_palookupoffse[i][pix]].b + GPalette.BaseColors[dest[i]].b, 255); + dest[i] = RGB256k.RGB[r>>2][g>>2][b>>2]; } vplce[i] += vince[i]; } @@ -396,15 +397,10 @@ namespace swrenderer uint8_t pix = source[frac >> bits]; if (pix != 0) { - uint32_t a = fg2rgb[colormap[pix]] + bg2rgb[*dest]; - uint32_t b = a; - - a |= 0x01f07c1f; - b &= 0x40100400; - a &= 0x3fffffff; - b = b - (b >> 5); - a |= b; - *dest = RGB32k.All[a & (a >> 15)]; + uint32_t r = MIN(GPalette.BaseColors[colormap[pix]].r + GPalette.BaseColors[*dest].r, 255); + uint32_t g = MIN(GPalette.BaseColors[colormap[pix]].g + GPalette.BaseColors[*dest].g, 255); + uint32_t b = MIN(GPalette.BaseColors[colormap[pix]].b + GPalette.BaseColors[*dest].b, 255); + *dest = RGB256k.RGB[r>>2][g>>2][b>>2]; } frac += fracstep; dest += pitch; @@ -444,15 +440,10 @@ namespace swrenderer uint8_t pix = _bufplce[i][vplce[i] >> bits]; if (pix != 0) { - uint32_t a = fg2rgb[_palookupoffse[i][pix]] + bg2rgb[dest[i]]; - uint32_t b = a; - - a |= 0x01f07c1f; - b &= 0x40100400; - a &= 0x3fffffff; - b = b - (b >> 5); - a |= b; - dest[i] = RGB32k.All[a & (a >> 15)]; + uint32_t r = MIN(GPalette.BaseColors[_palookupoffse[i][pix]].r + GPalette.BaseColors[dest[i]].r, 255); + uint32_t g = MIN(GPalette.BaseColors[_palookupoffse[i][pix]].g + GPalette.BaseColors[dest[i]].g, 255); + uint32_t b = MIN(GPalette.BaseColors[_palookupoffse[i][pix]].b + GPalette.BaseColors[dest[i]].b, 255); + dest[i] = RGB256k.RGB[r>>2][g>>2][b>>2]; } vplce[i] += vince[i]; } @@ -488,14 +479,10 @@ namespace swrenderer uint8_t pix = source[frac >> bits]; if (pix != 0) { - uint32_t a = (fg2rgb[colormap[pix]] | 0x40100400) - bg2rgb[*dest]; - uint32_t b = a; - - b &= 0x40100400; - b = b - (b >> 5); - a &= b; - a |= 0x01f07c1f; - *dest = RGB32k.All[a & (a >> 15)]; + int r = clamp(-GPalette.BaseColors[colormap[pix]].r + GPalette.BaseColors[*dest].r, 0, 255); + int g = clamp(-GPalette.BaseColors[colormap[pix]].g + GPalette.BaseColors[*dest].g, 0, 255); + int b = clamp(-GPalette.BaseColors[colormap[pix]].b + GPalette.BaseColors[*dest].b, 0, 255); + *dest = RGB256k.RGB[r>>2][g>>2][b>>2]; } frac += fracstep; dest += pitch; @@ -535,14 +522,10 @@ namespace swrenderer uint8_t pix = _bufplce[i][vplce[i] >> bits]; if (pix != 0) { - uint32_t a = (fg2rgb[_palookupoffse[i][pix]] | 0x40100400) - bg2rgb[dest[i]]; - uint32_t b = a; - - b &= 0x40100400; - b = b - (b >> 5); - a &= b; - a |= 0x01f07c1f; - dest[i] = RGB32k.All[a & (a >> 15)]; + int r = clamp(-GPalette.BaseColors[_palookupoffse[i][pix]].r + GPalette.BaseColors[dest[i]].r, 0, 255); + int g = clamp(-GPalette.BaseColors[_palookupoffse[i][pix]].g + GPalette.BaseColors[dest[i]].g, 0, 255); + int b = clamp(-GPalette.BaseColors[_palookupoffse[i][pix]].b + GPalette.BaseColors[dest[i]].b, 0, 255); + dest[i] = RGB256k.RGB[r>>2][g>>2][b>>2]; } vplce[i] += vince[i]; } @@ -578,14 +561,10 @@ namespace swrenderer uint8_t pix = source[frac >> bits]; if (pix != 0) { - uint32_t a = (bg2rgb[*dest] | 0x40100400) - fg2rgb[colormap[pix]]; - uint32_t b = a; - - b &= 0x40100400; - b = b - (b >> 5); - a &= b; - a |= 0x01f07c1f; - *dest = RGB32k.All[a & (a >> 15)]; + int r = clamp(GPalette.BaseColors[colormap[pix]].r - GPalette.BaseColors[*dest].r, 0, 255); + int g = clamp(GPalette.BaseColors[colormap[pix]].g - GPalette.BaseColors[*dest].g, 0, 255); + int b = clamp(GPalette.BaseColors[colormap[pix]].b - GPalette.BaseColors[*dest].b, 0, 255); + *dest = RGB256k.RGB[r>>2][g>>2][b>>2]; } frac += fracstep; dest += pitch; @@ -625,14 +604,10 @@ namespace swrenderer uint8_t pix = _bufplce[i][vplce[i] >> bits]; if (pix != 0) { - uint32_t a = (bg2rgb[dest[i]] | 0x40100400) - fg2rgb[_palookupoffse[i][pix]]; - uint32_t b = a; - - b &= 0x40100400; - b = b - (b >> 5); - a &= b; - a |= 0x01f07c1f; - dest[i] = RGB32k.All[a & (a >> 15)]; + uint32_t r = clamp(GPalette.BaseColors[_palookupoffse[i][pix]].r - GPalette.BaseColors[dest[i]].r, 0, 255); + uint32_t g = clamp(GPalette.BaseColors[_palookupoffse[i][pix]].g - GPalette.BaseColors[dest[i]].g, 0, 255); + uint32_t b = clamp(GPalette.BaseColors[_palookupoffse[i][pix]].b - GPalette.BaseColors[dest[i]].b, 0, 255); + dest[i] = RGB256k.RGB[r>>2][g>>2][b>>2]; } vplce[i] += vince[i]; } @@ -716,7 +691,7 @@ namespace swrenderer 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)]; + *dest = RGB256k.RGB[(c_red >> 2)][(c_green >> 2)][(c_blue >> 2)]; } frac += fracstep; @@ -744,8 +719,8 @@ namespace swrenderer int solid_bottom_r = RPART(solid_bottom); int solid_bottom_g = GPART(solid_bottom); int solid_bottom_b = BPART(solid_bottom); - uint32_t solid_top_fill = RGB32k.RGB[(solid_top_r >> 3)][(solid_top_g >> 3)][(solid_top_b >> 3)]; - uint32_t solid_bottom_fill = RGB32k.RGB[(solid_bottom_r >> 3)][(solid_bottom_g >> 3)][(solid_bottom_b >> 3)]; + uint32_t solid_top_fill = RGB256k.RGB[(solid_top_r >> 2)][(solid_top_g >> 2)][(solid_top_b >> 2)]; + uint32_t solid_bottom_fill = RGB256k.RGB[(solid_bottom_r >> 2)][(solid_bottom_g >> 2)][(solid_bottom_b >> 2)]; solid_top_fill = (solid_top_fill << 24) | (solid_top_fill << 16) | (solid_top_fill << 8) | solid_top_fill; solid_bottom_fill = (solid_bottom_fill << 24) | (solid_bottom_fill << 16) | (solid_bottom_fill << 8) | solid_bottom_fill; @@ -805,8 +780,7 @@ namespace swrenderer 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; - output[col] = RGB32k.RGB[(c_red >> 3)][(c_green >> 3)][(c_blue >> 3)]; - + output[col] = RGB256k.RGB[(c_red >> 2)][(c_green >> 2)][(c_blue >> 2)]; frac[col] += fracstep[col]; } *((uint32_t*)dest) = *((uint32_t*)output); @@ -847,7 +821,7 @@ namespace swrenderer 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; - output[col] = RGB32k.RGB[(c_red >> 3)][(c_green >> 3)][(c_blue >> 3)]; + output[col] = RGB256k.RGB[(c_red >> 2)][(c_green >> 2)][(c_blue >> 2)]; frac[col] += fracstep[col]; } @@ -929,7 +903,7 @@ namespace swrenderer 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)]; + *dest = RGB256k.RGB[(c_red >> 2)][(c_green >> 2)][(c_blue >> 2)]; } frac += fracstep; @@ -959,8 +933,8 @@ namespace swrenderer int solid_bottom_r = RPART(solid_bottom); int solid_bottom_g = GPART(solid_bottom); int solid_bottom_b = BPART(solid_bottom); - uint32_t solid_top_fill = RGB32k.RGB[(solid_top_r >> 3)][(solid_top_g >> 3)][(solid_top_b >> 3)]; - uint32_t solid_bottom_fill = RGB32k.RGB[(solid_bottom_r >> 3)][(solid_bottom_g >> 3)][(solid_bottom_b >> 3)]; + uint32_t solid_top_fill = RGB256k.RGB[(solid_top_r >> 2)][(solid_top_g >> 2)][(solid_top_b >> 2)]; + uint32_t solid_bottom_fill = RGB256k.RGB[(solid_bottom_r >> 2)][(solid_bottom_g >> 2)][(solid_bottom_b >> 2)]; solid_top_fill = (solid_top_fill << 24) | (solid_top_fill << 16) | (solid_top_fill << 8) | solid_top_fill; solid_bottom_fill = (solid_bottom_fill << 24) | (solid_bottom_fill << 16) | (solid_bottom_fill << 8) | solid_bottom_fill; @@ -1026,7 +1000,7 @@ namespace swrenderer 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; - output[col] = RGB32k.RGB[(c_red >> 3)][(c_green >> 3)][(c_blue >> 3)]; + output[col] = RGB256k.RGB[(c_red >> 2)][(c_green >> 2)][(c_blue >> 2)]; frac[col] += fracstep[col]; } @@ -1080,7 +1054,7 @@ namespace swrenderer 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; - output[col] = RGB32k.RGB[(c_red >> 3)][(c_green >> 3)][(c_blue >> 3)]; + output[col] = RGB256k.RGB[(c_red >> 2)][(c_green >> 2)][(c_blue >> 2)]; frac[col] += fracstep[col]; } @@ -1116,6 +1090,8 @@ namespace swrenderer _srcblend = dc_srcblend; _destblend = dc_destblend; _srccolor = dc_srccolor; + _srcalpha = dc_srcalpha; + _destalpha = dc_destalpha; } void DrawColumnPalCommand::Execute(DrawerThread *thread) @@ -1210,11 +1186,17 @@ namespace swrenderer dest = thread->dest_for_thread(_dest_y, pitch, dest); pitch *= thread->num_cores; + const PalEntry* pal = GPalette.BaseColors; + do { - uint32_t bg; - bg = (fg + bg2rgb[*dest]) | 0x1f07c1f; - *dest = RGB32k.All[bg & (bg >> 15)]; + int src_r = ((_srccolor >> 16) & 0xff) * _srcalpha; + int src_g = ((_srccolor >> 0) & 0xff) * _srcalpha; + int src_b = ((_srccolor >> 8) & 0xff) * _srcalpha; + int r = clamp((src_r + pal[*dest].r * _destalpha)>>18, 0, 255); + int g = clamp((src_g + pal[*dest].g * _destalpha)>>18, 0, 255); + int b = clamp((src_b + pal[*dest].b * _destalpha)>>18, 0, 255); + *dest = RGB256k.RGB[r][g][b]; dest += pitch; } while (--count); @@ -1242,17 +1224,17 @@ namespace swrenderer dest = thread->dest_for_thread(_dest_y, pitch, dest); pitch *= thread->num_cores; + const PalEntry* pal = GPalette.BaseColors; + do { - uint32_t a = fg + bg2rgb[*dest]; - uint32_t b = a; - - a |= 0x01f07c1f; - b &= 0x40100400; - a &= 0x3fffffff; - b = b - (b >> 5); - a |= b; - *dest = RGB32k.All[a & (a >> 15)]; + int src_r = ((_srccolor >> 16) & 0xff) * _srcalpha; + int src_g = ((_srccolor >> 0) & 0xff) * _srcalpha; + int src_b = ((_srccolor >> 8) & 0xff) * _srcalpha; + int r = clamp((src_r + pal[*dest].r * _destalpha)>>18, 0, 255); + int g = clamp((src_g + pal[*dest].g * _destalpha)>>18, 0, 255); + int b = clamp((src_b + pal[*dest].b * _destalpha)>>18, 0, 255); + *dest = RGB256k.RGB[r][g][b]; dest += pitch; } while (--count); } @@ -1265,11 +1247,7 @@ namespace swrenderer count = _count; dest = _dest; - uint32_t *bg2rgb; - uint32_t fg; - bg2rgb = _destblend; - fg = _srccolor | 0x40100400; int pitch = _pitch; count = thread->count_for_thread(_dest_y, count); @@ -1279,16 +1257,19 @@ namespace swrenderer dest = thread->dest_for_thread(_dest_y, pitch, dest); pitch *= thread->num_cores; + const PalEntry* palette = GPalette.BaseColors; + do { - uint32_t a = fg - bg2rgb[*dest]; - uint32_t b = a; + int src_r = ((_srccolor >> 16) & 0xff) * _srcalpha; + int src_g = ((_srccolor >> 0) & 0xff) * _srcalpha; + int src_b = ((_srccolor >> 8) & 0xff) * _srcalpha; + int bg = *dest; + int r = MAX((src_r * _srcalpha - palette[bg].r * _destalpha)>>18, 0); + int g = MAX((src_g * _srcalpha - palette[bg].g * _destalpha)>>18, 0); + int b = MAX((src_b * _srcalpha - palette[bg].b * _destalpha)>>18, 0); - b &= 0x40100400; - b = b - (b >> 5); - a &= b; - a |= 0x01f07c1f; - *dest = RGB32k.All[a & (a >> 15)]; + *dest = RGB256k.RGB[r][g][b]; dest += pitch; } while (--count); } @@ -1303,11 +1284,7 @@ namespace swrenderer return; dest = _dest; - uint32_t *bg2rgb; - uint32_t fg; - bg2rgb = _destblend; - fg = _srccolor; int pitch = _pitch; count = thread->count_for_thread(_dest_y, count); @@ -1317,16 +1294,19 @@ namespace swrenderer dest = thread->dest_for_thread(_dest_y, pitch, dest); pitch *= thread->num_cores; + const PalEntry *palette = GPalette.BaseColors; + do { - uint32_t a = (bg2rgb[*dest] | 0x40100400) - fg; - uint32_t b = a; + int src_r = ((_srccolor >> 16) & 0xff) * _srcalpha; + int src_g = ((_srccolor >> 0) & 0xff) * _srcalpha; + int src_b = ((_srccolor >> 8) & 0xff) * _srcalpha; + int bg = *dest; + int r = MAX((src_r * _srcalpha - palette[bg].r * _destalpha)>>18, 0); + int g = MAX((src_g * _srcalpha - palette[bg].g * _destalpha)>>18, 0); + int b = MAX((src_b * _srcalpha - palette[bg].b * _destalpha)>>18, 0); - b &= 0x40100400; - b = b - (b >> 5); - a &= b; - a |= 0x01f07c1f; - *dest = RGB32k.All[a & (a >> 15)]; + *dest = RGB256k.RGB[r][g][b]; dest += pitch; } while (--count); } @@ -1354,20 +1334,18 @@ namespace swrenderer fracstep *= thread->num_cores; pitch *= thread->num_cores; - uint32_t *fg2rgb = _srcblend; - uint32_t *bg2rgb = _destblend; const uint8_t *colormap = _colormap; const uint8_t *source = _source; + const PalEntry *palette = GPalette.BaseColors; do { uint32_t fg = colormap[source[frac >> FRACBITS]]; uint32_t bg = *dest; - - fg = fg2rgb[fg]; - bg = bg2rgb[bg]; - fg = (fg + bg) | 0x1f07c1f; - *dest = RGB32k.All[fg & (fg >> 15)]; + uint32_t r = MIN((palette[fg].r * _srcalpha + palette[bg].r * _destalpha)>>18, 63); + uint32_t g = MIN((palette[fg].g * _srcalpha + palette[bg].g * _destalpha)>>18, 63); + uint32_t b = MIN((palette[fg].b * _srcalpha + palette[bg].b * _destalpha)>>18, 63); + *dest = RGB256k.RGB[r][g][b]; dest += pitch; frac += fracstep; } while (--count); @@ -1434,21 +1412,20 @@ namespace swrenderer fracstep *= thread->num_cores; pitch *= thread->num_cores; - uint32_t *fg2rgb = _srcblend; - uint32_t *bg2rgb = _destblend; const uint8_t *translation = _translation; const uint8_t *colormap = _colormap; const uint8_t *source = _source; + const PalEntry *palette = GPalette.BaseColors; + do { uint32_t fg = colormap[translation[source[frac >> FRACBITS]]]; uint32_t bg = *dest; - - fg = fg2rgb[fg]; - bg = bg2rgb[bg]; - fg = (fg + bg) | 0x1f07c1f; - *dest = RGB32k.All[fg & (fg >> 15)]; + uint32_t r = MIN((palette[fg].r * _srcalpha + palette[bg].r * _destalpha)>>18, 63); + uint32_t g = MIN((palette[fg].g * _srcalpha + palette[bg].g * _destalpha)>>18, 63); + uint32_t b = MIN((palette[fg].b * _srcalpha + palette[bg].b * _destalpha)>>18, 63); + *dest = RGB256k.RGB[r][g][b]; dest += pitch; frac += fracstep; } while (--count); @@ -1478,14 +1455,17 @@ namespace swrenderer const uint8_t *source = _source; const uint8_t *colormap = _colormap; - uint32_t *fgstart = &Col2RGB8[0][_color]; + + const PalEntry *palette = GPalette.BaseColors; do { - uint32_t val = colormap[source[frac >> FRACBITS]]; - uint32_t fg = fgstart[val << 8]; - val = (Col2RGB8[64 - val][*dest] + fg) | 0x1f07c1f; - *dest = RGB32k.All[val & (val >> 15)]; + uint32_t val = source[frac >> FRACBITS]; + + int r = (palette[*dest].r * (255-val) + palette[_color].r * val) >> 10; + int g = (palette[*dest].g * (255-val) + palette[_color].g * val) >> 10; + int b = (palette[*dest].b * (255-val) + palette[_color].b * val) >> 10; + *dest = RGB256k.RGB[clamp(r,0,63)][clamp(g,0,63)][clamp(b,0,63)]; dest += pitch; frac += fracstep; @@ -1517,20 +1497,16 @@ namespace swrenderer const uint8_t *colormap = _colormap; const uint8_t *source = _source; - uint32_t *fg2rgb = _srcblend; - uint32_t *bg2rgb = _destblend; + const PalEntry *palette = GPalette.BaseColors; do { - uint32_t a = fg2rgb[colormap[source[frac >> FRACBITS]]] + bg2rgb[*dest]; - uint32_t b = a; - - a |= 0x01f07c1f; - b &= 0x40100400; - a &= 0x3fffffff; - b = b - (b >> 5); - a |= b; - *dest = RGB32k.All[a & (a >> 15)]; + int fg = colormap[source[frac >> FRACBITS]]; + int bg = *dest; + int r = MIN((palette[fg].r * _srcalpha + palette[bg].r * _destalpha)>>18, 63); + int g = MIN((palette[fg].g * _srcalpha + palette[bg].g * _destalpha)>>18, 63); + int b = MIN((palette[fg].b * _srcalpha + palette[bg].b * _destalpha)>>18, 63); + *dest = RGB256k.RGB[r][g][b]; dest += pitch; frac += fracstep; } while (--count); @@ -1562,20 +1538,16 @@ namespace swrenderer const uint8_t *translation = _translation; const uint8_t *colormap = _colormap; const uint8_t *source = _source; - uint32_t *fg2rgb = _srcblend; - uint32_t *bg2rgb = _destblend; + const PalEntry *palette = GPalette.BaseColors; do { - uint32_t a = fg2rgb[colormap[translation[source[frac >> FRACBITS]]]] + bg2rgb[*dest]; - uint32_t b = a; - - a |= 0x01f07c1f; - b &= 0x40100400; - a &= 0x3fffffff; - b = b - (b >> 5); - a |= b; - *dest = RGB32k.All[(a >> 15) & a]; + int fg = colormap[translation[source[frac >> FRACBITS]]]; + int bg = *dest; + int r = MIN((palette[fg].r * _srcalpha + palette[bg].r * _destalpha)>>18, 63); + int g = MIN((palette[fg].g * _srcalpha + palette[bg].g * _destalpha)>>18, 63); + int b = MIN((palette[fg].b * _srcalpha + palette[bg].b * _destalpha)>>18, 63); + *dest = RGB256k.RGB[r][g][b]; dest += pitch; frac += fracstep; } while (--count); @@ -1606,19 +1578,16 @@ namespace swrenderer const uint8_t *colormap = _colormap; const uint8_t *source = _source; - uint32_t *fg2rgb = _srcblend; - uint32_t *bg2rgb = _destblend; + const PalEntry *palette = GPalette.BaseColors; do { - uint32_t a = (fg2rgb[colormap[source[frac >> FRACBITS]]] | 0x40100400) - bg2rgb[*dest]; - uint32_t b = a; - - b &= 0x40100400; - b = b - (b >> 5); - a &= b; - a |= 0x01f07c1f; - *dest = RGB32k.All[a & (a >> 15)]; + int fg = colormap[source[frac >> FRACBITS]]; + int bg = *dest; + int r = MAX((palette[fg].r * _srcalpha - palette[bg].r * _destalpha)>>18, 0); + int g = MAX((palette[fg].g * _srcalpha - palette[bg].g * _destalpha)>>18, 0); + int b = MAX((palette[fg].b * _srcalpha - palette[bg].b * _destalpha)>>18, 0); + *dest = RGB256k.RGB[r][g][b]; dest += pitch; frac += fracstep; } while (--count); @@ -1650,19 +1619,16 @@ namespace swrenderer const uint8_t *translation = _translation; const uint8_t *colormap = _colormap; const uint8_t *source = _source; - uint32_t *fg2rgb = _srcblend; - uint32_t *bg2rgb = _destblend; + const PalEntry *palette = GPalette.BaseColors; do { - uint32_t a = (fg2rgb[colormap[translation[source[frac >> FRACBITS]]]] | 0x40100400) - bg2rgb[*dest]; - uint32_t b = a; - - b &= 0x40100400; - b = b - (b >> 5); - a &= b; - a |= 0x01f07c1f; - *dest = RGB32k.All[(a >> 15) & a]; + int fg = colormap[translation[source[frac >> FRACBITS]]]; + int bg = *dest; + int r = MAX((palette[fg].r * _srcalpha - palette[bg].r * _destalpha)>>18, 0); + int g = MAX((palette[fg].g * _srcalpha - palette[bg].g * _destalpha)>>18, 0); + int b = MAX((palette[fg].b * _srcalpha - palette[bg].b * _destalpha)>>18, 0); + *dest = RGB256k.RGB[r][g][b]; dest += pitch; frac += fracstep; } while (--count); @@ -1693,19 +1659,16 @@ namespace swrenderer const uint8_t *colormap = _colormap; const uint8_t *source = _source; - uint32_t *fg2rgb = _srcblend; - uint32_t *bg2rgb = _destblend; + const PalEntry *palette = GPalette.BaseColors; do { - uint32_t a = (bg2rgb[*dest] | 0x40100400) - fg2rgb[colormap[source[frac >> FRACBITS]]]; - uint32_t b = a; - - b &= 0x40100400; - b = b - (b >> 5); - a &= b; - a |= 0x01f07c1f; - *dest = RGB32k.All[a & (a >> 15)]; + int fg = colormap[source[frac >> FRACBITS]]; + int bg = *dest; + int r = MAX((-palette[fg].r * _srcalpha + palette[bg].r * _destalpha)>>18, 0); + int g = MAX((-palette[fg].g * _srcalpha + palette[bg].g * _destalpha)>>18, 0); + int b = MAX((-palette[fg].b * _srcalpha + palette[bg].b * _destalpha)>>18, 0); + *dest = RGB256k.RGB[r][g][b]; dest += pitch; frac += fracstep; } while (--count); @@ -1737,19 +1700,16 @@ namespace swrenderer const uint8_t *translation = _translation; const uint8_t *colormap = _colormap; const uint8_t *source = _source; - uint32_t *fg2rgb = _srcblend; - uint32_t *bg2rgb = _destblend; + const PalEntry *palette = GPalette.BaseColors; do { - uint32_t a = (bg2rgb[*dest] | 0x40100400) - fg2rgb[colormap[translation[source[frac >> FRACBITS]]]]; - uint32_t b = a; - - b &= 0x40100400; - b = b - (b >> 5); - a &= b; - a |= 0x01f07c1f; - *dest = RGB32k.All[(a >> 15) & a]; + int fg = colormap[translation[source[frac >> FRACBITS]]]; + int bg = *dest; + int r = MAX((-palette[fg].r * _srcalpha + palette[bg].r * _destalpha)>>18, 0); + int g = MAX((-palette[fg].g * _srcalpha + palette[bg].g * _destalpha)>>18, 0); + int b = MAX((-palette[fg].b * _srcalpha + palette[bg].b * _destalpha)>>18, 0); + *dest = RGB256k.RGB[r][g][b]; dest += pitch; frac += fracstep; } while (--count); @@ -1865,6 +1825,8 @@ namespace swrenderer _srcblend = dc_srcblend; _destblend = dc_destblend; _color = ds_color; + _srcalpha = dc_srcalpha; + _destalpha = dc_destalpha; } void DrawSpanPalCommand::Execute(DrawerThread *thread) @@ -2010,8 +1972,6 @@ namespace swrenderer const uint8_t *colormap = _colormap; int count; int spot; - uint32_t *fg2rgb = _srcblend; - uint32_t *bg2rgb = _destblend; xfrac = _xfrac; yfrac = _yfrac; @@ -2023,6 +1983,8 @@ namespace swrenderer xstep = _xstep; ystep = _ystep; + const PalEntry *palette = GPalette.BaseColors; + if (_xbits == 6 && _ybits == 6) { // 64x64 is the most common case by far, so special case it. @@ -2031,10 +1993,11 @@ namespace swrenderer spot = ((xfrac >> (32 - 6 - 6))&(63 * 64)) + (yfrac >> (32 - 6)); uint32_t fg = colormap[source[spot]]; uint32_t bg = *dest; - fg = fg2rgb[fg]; - bg = bg2rgb[bg]; - fg = (fg + bg) | 0x1f07c1f; - *dest++ = RGB32k.All[fg & (fg >> 15)]; + int r = MAX((palette[fg].r * _srcalpha + palette[bg].r * _destalpha)>>18, 0); + int g = MAX((palette[fg].g * _srcalpha + palette[bg].g * _destalpha)>>18, 0); + int b = MAX((palette[fg].b * _srcalpha + palette[bg].b * _destalpha)>>18, 0); + *dest++ = RGB256k.RGB[r][g][b]; + xfrac += xstep; yfrac += ystep; } while (--count); @@ -2049,10 +2012,11 @@ namespace swrenderer spot = ((xfrac >> xshift) & xmask) + (yfrac >> yshift); uint32_t fg = colormap[source[spot]]; uint32_t bg = *dest; - fg = fg2rgb[fg]; - bg = bg2rgb[bg]; - fg = (fg + bg) | 0x1f07c1f; - *dest++ = RGB32k.All[fg & (fg >> 15)]; + int r = MAX((palette[fg].r * _srcalpha + palette[bg].r * _destalpha)>>18, 0); + int g = MAX((palette[fg].g * _srcalpha + palette[bg].g * _destalpha)>>18, 0); + int b = MAX((palette[fg].b * _srcalpha + palette[bg].b * _destalpha)>>18, 0); + *dest++ = RGB256k.RGB[r][g][b]; + xfrac += xstep; yfrac += ystep; } while (--count); @@ -2073,8 +2037,8 @@ namespace swrenderer const uint8_t *colormap = _colormap; int count; int spot; - uint32_t *fg2rgb = _srcblend; - uint32_t *bg2rgb = _destblend; + + const PalEntry *palette = GPalette.BaseColors; xfrac = _xfrac; yfrac = _yfrac; @@ -2099,10 +2063,10 @@ namespace swrenderer { uint32_t fg = colormap[texdata]; uint32_t bg = *dest; - fg = fg2rgb[fg]; - bg = bg2rgb[bg]; - fg = (fg + bg) | 0x1f07c1f; - *dest = RGB32k.All[fg & (fg >> 15)]; + int r = MAX((palette[fg].r * _srcalpha + palette[bg].r * _destalpha)>>18, 0); + int g = MAX((palette[fg].g * _srcalpha + palette[bg].g * _destalpha)>>18, 0); + int b = MAX((palette[fg].b * _srcalpha + palette[bg].b * _destalpha)>>18, 0); + *dest = RGB256k.RGB[r][g][b]; } dest++; xfrac += xstep; @@ -2124,10 +2088,10 @@ namespace swrenderer { uint32_t fg = colormap[texdata]; uint32_t bg = *dest; - fg = fg2rgb[fg]; - bg = bg2rgb[bg]; - fg = (fg + bg) | 0x1f07c1f; - *dest = RGB32k.All[fg & (fg >> 15)]; + int r = MAX((palette[fg].r * _srcalpha + palette[bg].r * _destalpha)>>18, 0); + int g = MAX((palette[fg].g * _srcalpha + palette[bg].g * _destalpha)>>18, 0); + int b = MAX((palette[fg].b * _srcalpha + palette[bg].b * _destalpha)>>18, 0); + *dest = RGB256k.RGB[r][g][b]; } dest++; xfrac += xstep; @@ -2150,8 +2114,7 @@ namespace swrenderer const uint8_t *colormap = _colormap; int count; int spot; - uint32_t *fg2rgb = _srcblend; - uint32_t *bg2rgb = _destblend; + const PalEntry *palette = GPalette.BaseColors; xfrac = _xfrac; yfrac = _yfrac; @@ -2169,15 +2132,13 @@ namespace swrenderer do { spot = ((xfrac >> (32 - 6 - 6))&(63 * 64)) + (yfrac >> (32 - 6)); - uint32_t a = fg2rgb[colormap[source[spot]]] + bg2rgb[*dest]; - uint32_t b = a; + uint32_t fg = colormap[source[spot]]; + uint32_t bg = *dest; + int r = MAX((palette[fg].r * _srcalpha + palette[bg].r * _destalpha)>>18, 0); + int g = MAX((palette[fg].g * _srcalpha + palette[bg].g * _destalpha)>>18, 0); + int b = MAX((palette[fg].b * _srcalpha + palette[bg].b * _destalpha)>>18, 0); + *dest++ = RGB256k.RGB[r][g][b]; - a |= 0x01f07c1f; - b &= 0x40100400; - a &= 0x3fffffff; - b = b - (b >> 5); - a |= b; - *dest++ = RGB32k.All[a & (a >> 15)]; xfrac += xstep; yfrac += ystep; } while (--count); @@ -2190,15 +2151,13 @@ namespace swrenderer do { spot = ((xfrac >> xshift) & xmask) + (yfrac >> yshift); - uint32_t a = fg2rgb[colormap[source[spot]]] + bg2rgb[*dest]; - uint32_t b = a; + uint32_t fg = colormap[source[spot]]; + uint32_t bg = *dest; + int r = MAX((palette[fg].r * _srcalpha + palette[bg].r * _destalpha)>>18, 0); + int g = MAX((palette[fg].g * _srcalpha + palette[bg].g * _destalpha)>>18, 0); + int b = MAX((palette[fg].b * _srcalpha + palette[bg].b * _destalpha)>>18, 0); + *dest++ = RGB256k.RGB[r][g][b]; - a |= 0x01f07c1f; - b &= 0x40100400; - a &= 0x3fffffff; - b = b - (b >> 5); - a |= b; - *dest++ = RGB32k.All[a & (a >> 15)]; xfrac += xstep; yfrac += ystep; } while (--count); @@ -2219,8 +2178,7 @@ namespace swrenderer const uint8_t *colormap = _colormap; int count; int spot; - uint32_t *fg2rgb = _srcblend; - uint32_t *bg2rgb = _destblend; + const PalEntry *palette = GPalette.BaseColors; xfrac = _xfrac; yfrac = _yfrac; @@ -2243,15 +2201,12 @@ namespace swrenderer texdata = source[spot]; if (texdata != 0) { - uint32_t a = fg2rgb[colormap[texdata]] + bg2rgb[*dest]; - uint32_t b = a; - - a |= 0x01f07c1f; - b &= 0x40100400; - a &= 0x3fffffff; - b = b - (b >> 5); - a |= b; - *dest = RGB32k.All[a & (a >> 15)]; + uint32_t fg = colormap[texdata]; + uint32_t bg = *dest; + int r = MAX((palette[fg].r * _srcalpha + palette[bg].r * _destalpha)>>18, 0); + int g = MAX((palette[fg].g * _srcalpha + palette[bg].g * _destalpha)>>18, 0); + int b = MAX((palette[fg].b * _srcalpha + palette[bg].b * _destalpha)>>18, 0); + *dest = RGB256k.RGB[r][g][b]; } dest++; xfrac += xstep; @@ -2271,15 +2226,12 @@ namespace swrenderer texdata = source[spot]; if (texdata != 0) { - uint32_t a = fg2rgb[colormap[texdata]] + bg2rgb[*dest]; - uint32_t b = a; - - a |= 0x01f07c1f; - b &= 0x40100400; - a &= 0x3fffffff; - b = b - (b >> 5); - a |= b; - *dest = RGB32k.All[a & (a >> 15)]; + uint32_t fg = colormap[texdata]; + uint32_t bg = *dest; + int r = MAX((palette[fg].r * _srcalpha + palette[bg].r * _destalpha)>>18, 0); + int g = MAX((palette[fg].g * _srcalpha + palette[bg].g * _destalpha)>>18, 0); + int b = MAX((palette[fg].b * _srcalpha + palette[bg].b * _destalpha)>>18, 0); + *dest = RGB256k.RGB[r][g][b]; } dest++; xfrac += xstep; diff --git a/src/r_draw_pal.h b/src/r_draw_pal.h index f2b1f0571..0b1a5eebf 100644 --- a/src/r_draw_pal.h +++ b/src/r_draw_pal.h @@ -106,6 +106,8 @@ namespace swrenderer uint32_t *_srcblend; uint32_t *_destblend; uint32_t _srccolor; + fixed_t _srcalpha; + fixed_t _destalpha; }; class DrawColumnPalCommand : public PalColumnCommand { public: void Execute(DrawerThread *thread) override; }; @@ -164,6 +166,8 @@ namespace swrenderer uint32_t *_srcblend; uint32_t *_destblend; int _color; + fixed_t _srcalpha; + fixed_t _destalpha; }; class DrawSpanPalCommand : public PalSpanCommand { public: void Execute(DrawerThread *thread) override; }; @@ -303,6 +307,8 @@ namespace swrenderer const uint32_t *_srcblend; const uint32_t *_destblend; const uint8_t *_translation; + fixed_t _srcalpha; + fixed_t _destalpha; int _color; }; diff --git a/src/r_drawt_pal.cpp b/src/r_drawt_pal.cpp index 3356592d2..e2af7bbf1 100644 --- a/src/r_drawt_pal.cpp +++ b/src/r_drawt_pal.cpp @@ -4,6 +4,8 @@ ** **--------------------------------------------------------------------------- ** Copyright 1998-2006 Randy Heit +** Copyright 2016 Magnus Norddahl +** Copyright 2016 Rachael Alexanderson ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without @@ -173,6 +175,8 @@ namespace swrenderer _colormap = dc_colormap; _srcblend = dc_srcblend; _destblend = dc_destblend; + _srcalpha = dc_srcalpha; + _destalpha = dc_destalpha; _translation = dc_translation; _color = dc_color; } @@ -440,21 +444,20 @@ namespace swrenderer if (count <= 0) return; - const uint32_t *fg2rgb = _srcblend; - const uint32_t *bg2rgb = _destblend; dest = ylookup[yl + thread->skipped_by_thread(yl)] + sx + _destorg; source = &thread->dc_temp[thread->temp_line_for_thread(yl)*4 + hx]; pitch = _pitch * thread->num_cores; colormap = _colormap; + const PalEntry *palette = GPalette.BaseColors; do { uint32_t fg = colormap[*source]; uint32_t bg = *dest; - fg = fg2rgb[fg]; - bg = bg2rgb[bg]; - fg = (fg+bg) | 0x1f07c1f; - *dest = RGB32k.All[fg & (fg>>15)]; + int r = MIN((palette[fg].r * _srcalpha + palette[bg].r * _destalpha)>>18, 63); + int g = MIN((palette[fg].g * _srcalpha + palette[bg].g * _destalpha)>>18, 63); + int b = MIN((palette[fg].b * _srcalpha + palette[bg].b * _destalpha)>>18, 63); + *dest = RGB256k.RGB[r][g][b]; source += 4; dest += pitch; } while (--count); @@ -472,42 +475,22 @@ namespace swrenderer if (count <= 0) return; - const uint32_t *fg2rgb = _srcblend; - const uint32_t *bg2rgb = _destblend; dest = ylookup[yl + thread->skipped_by_thread(yl)] + sx + _destorg; source = &thread->dc_temp[thread->temp_line_for_thread(yl)*4]; pitch = _pitch * thread->num_cores; colormap = _colormap; + const PalEntry *palette = GPalette.BaseColors; do { - uint32_t fg = colormap[source[0]]; - uint32_t bg = dest[0]; - fg = fg2rgb[fg]; - bg = bg2rgb[bg]; - fg = (fg+bg) | 0x1f07c1f; - dest[0] = RGB32k.All[fg & (fg>>15)]; - - fg = colormap[source[1]]; - bg = dest[1]; - fg = fg2rgb[fg]; - bg = bg2rgb[bg]; - fg = (fg+bg) | 0x1f07c1f; - dest[1] = RGB32k.All[fg & (fg>>15)]; - - - fg = colormap[source[2]]; - bg = dest[2]; - fg = fg2rgb[fg]; - bg = bg2rgb[bg]; - fg = (fg+bg) | 0x1f07c1f; - dest[2] = RGB32k.All[fg & (fg>>15)]; - - fg = colormap[source[3]]; - bg = dest[3]; - fg = fg2rgb[fg]; - bg = bg2rgb[bg]; - fg = (fg+bg) | 0x1f07c1f; - dest[3] = RGB32k.All[fg & (fg>>15)]; + for (int ks = 0; ks < 4; ks++) + { // [SP] this 4col function was a block of copy-pasted code. 4 times. I regret nothing. + uint32_t fg = colormap[source[ks]]; + uint32_t bg = dest[ks]; + int r = MIN((palette[fg].r * _srcalpha + palette[bg].r * _destalpha)>>18, 63); + int g = MIN((palette[fg].g * _srcalpha + palette[bg].g * _destalpha)>>18, 63); + int b = MIN((palette[fg].b * _srcalpha + palette[bg].b * _destalpha)>>18, 63); + dest[ks] = RGB256k.RGB[r][g][b]; + } source += 4; dest += pitch; @@ -527,17 +510,18 @@ namespace swrenderer if (count <= 0) return; - fgstart = &Col2RGB8[0][_color]; colormap = _colormap; dest = ylookup[yl + thread->skipped_by_thread(yl)] + sx + _destorg; source = &thread->dc_temp[thread->temp_line_for_thread(yl)*4 + hx]; pitch = _pitch * thread->num_cores; + const PalEntry *palette = GPalette.BaseColors; do { - uint32_t val = colormap[*source]; - uint32_t fg = fgstart[val<<8]; - val = (Col2RGB8[64-val][*dest] + fg) | 0x1f07c1f; - *dest = RGB32k.All[val & (val>>15)]; + uint32_t val = *source; + int r = (palette[*dest].r * (255-val) + palette[_color].r * val) >> 10; + int g = (palette[*dest].g * (255-val) + palette[_color].g * val) >> 10; + int b = (palette[*dest].b * (255-val) + palette[_color].b * val) >> 10; + *dest = RGB256k.RGB[clamp(r,0,63)][clamp(g,0,63)][clamp(b,0,63)]; source += 4; dest += pitch; } while (--count); @@ -556,30 +540,23 @@ namespace swrenderer if (count <= 0) return; - fgstart = &Col2RGB8[0][_color]; colormap = _colormap; dest = ylookup[yl + thread->skipped_by_thread(yl)] + sx + _destorg; source = &thread->dc_temp[thread->temp_line_for_thread(yl)*4]; pitch = _pitch * thread->num_cores; + const PalEntry *palette = GPalette.BaseColors; do { uint32_t val; - - val = colormap[source[0]]; - val = (Col2RGB8[64-val][dest[0]] + fgstart[val<<8]) | 0x1f07c1f; - dest[0] = RGB32k.All[val & (val>>15)]; - val = colormap[source[1]]; - val = (Col2RGB8[64-val][dest[1]] + fgstart[val<<8]) | 0x1f07c1f; - dest[1] = RGB32k.All[val & (val>>15)]; - - val = colormap[source[2]]; - val = (Col2RGB8[64-val][dest[2]] + fgstart[val<<8]) | 0x1f07c1f; - dest[2] = RGB32k.All[val & (val>>15)]; - - val = colormap[source[3]]; - val = (Col2RGB8[64-val][dest[3]] + fgstart[val<<8]) | 0x1f07c1f; - dest[3] = RGB32k.All[val & (val>>15)]; + for (int ks = 0; ks < 4; ks++) + { + val = source[ks]; + int r = (palette[dest[ks]].r * (255-val) + palette[_color].r * val) >> 10; + int g = (palette[dest[ks]].g * (255-val) + palette[_color].g * val) >> 10; + int b = (palette[dest[ks]].b * (255-val) + palette[_color].b * val) >> 10; + dest[ks] = RGB256k.RGB[clamp(r,0,63)][clamp(g,0,63)][clamp(b,0,63)]; + } source += 4; dest += pitch; @@ -598,23 +575,19 @@ namespace swrenderer if (count <= 0) return; - const uint32_t *fg2rgb = _srcblend; - const uint32_t *bg2rgb = _destblend; dest = ylookup[yl + thread->skipped_by_thread(yl)] + sx + _destorg; source = &thread->dc_temp[thread->temp_line_for_thread(yl)*4 + hx]; pitch = _pitch * thread->num_cores; colormap = _colormap; + const PalEntry *palette = GPalette.BaseColors; do { - uint32_t a = fg2rgb[colormap[*source]] + bg2rgb[*dest]; - uint32_t b = a; - - a |= 0x01f07c1f; - b &= 0x40100400; - a &= 0x3fffffff; - b = b - (b >> 5); - a |= b; - *dest = RGB32k.All[(a>>15) & a]; + int fg = colormap[*source]; + int bg = *dest; + int r = MIN((palette[fg].r * _srcalpha + palette[bg].r * _destalpha)>>18, 63); + int g = MIN((palette[fg].g * _srcalpha + palette[bg].g * _destalpha)>>18, 63); + int b = MIN((palette[fg].b * _srcalpha + palette[bg].b * _destalpha)>>18, 63); + *dest = RGB256k.RGB[r][g][b]; source += 4; dest += pitch; } while (--count); @@ -636,47 +609,18 @@ namespace swrenderer source = &thread->dc_temp[thread->temp_line_for_thread(yl)*4]; pitch = _pitch * thread->num_cores; colormap = _colormap; - - const uint32_t *fg2rgb = _srcblend; - const uint32_t *bg2rgb = _destblend; + const PalEntry *palette = GPalette.BaseColors; do { - uint32_t a = fg2rgb[colormap[source[0]]] + bg2rgb[dest[0]]; - uint32_t b = a; - - a |= 0x01f07c1f; - b &= 0x40100400; - a &= 0x3fffffff; - b = b - (b >> 5); - a |= b; - dest[0] = RGB32k.All[(a>>15) & a]; - - a = fg2rgb[colormap[source[1]]] + bg2rgb[dest[1]]; - b = a; - a |= 0x01f07c1f; - b &= 0x40100400; - a &= 0x3fffffff; - b = b - (b >> 5); - a |= b; - dest[1] = RGB32k.All[(a>>15) & a]; - - a = fg2rgb[colormap[source[2]]] + bg2rgb[dest[2]]; - b = a; - a |= 0x01f07c1f; - b &= 0x40100400; - a &= 0x3fffffff; - b = b - (b >> 5); - a |= b; - dest[2] = RGB32k.All[(a>>15) & a]; - - a = fg2rgb[colormap[source[3]]] + bg2rgb[dest[3]]; - b = a; - a |= 0x01f07c1f; - b &= 0x40100400; - a &= 0x3fffffff; - b = b - (b >> 5); - a |= b; - dest[3] = RGB32k.All[(a>>15) & a]; + for (int ks = 0; ks < 4; ks++) + { + int fg = colormap[source[ks]]; + int bg = dest[ks]; + int r = MIN((palette[fg].r * _srcalpha + palette[bg].r * _destalpha)>>18, 63); + int g = MIN((palette[fg].g * _srcalpha + palette[bg].g * _destalpha)>>18, 63); + int b = MIN((palette[fg].b * _srcalpha + palette[bg].b * _destalpha)>>18, 63); + dest[ks] = RGB256k.RGB[r][g][b]; + } source += 4; dest += pitch; @@ -701,16 +645,15 @@ namespace swrenderer source = &thread->dc_temp[thread->temp_line_for_thread(yl)*4 + hx]; pitch = _pitch * thread->num_cores; colormap = _colormap; + const PalEntry *palette = GPalette.BaseColors; do { - uint32_t a = (fg2rgb[colormap[*source]] | 0x40100400) - bg2rgb[*dest]; - uint32_t b = a; - - b &= 0x40100400; - b = b - (b >> 5); - a &= b; - a |= 0x01f07c1f; - *dest = RGB32k.All[(a>>15) & a]; + int fg = colormap[*source]; + int bg = *dest; + int r = MAX((palette[fg].r * _srcalpha - palette[bg].r * _destalpha)>>18, 0); + int g = MAX((palette[fg].g * _srcalpha - palette[bg].g * _destalpha)>>18, 0); + int b = MAX((palette[fg].b * _srcalpha - palette[bg].b * _destalpha)>>18, 0); + *dest = RGB256k.RGB[r][g][b]; source += 4; dest += pitch; } while (--count); @@ -734,40 +677,18 @@ namespace swrenderer source = &thread->dc_temp[thread->temp_line_for_thread(yl)*4]; pitch = _pitch * thread->num_cores; colormap = _colormap; + const PalEntry *palette = GPalette.BaseColors; do { - uint32_t a = (fg2rgb[colormap[source[0]]] | 0x40100400) - bg2rgb[dest[0]]; - uint32_t b = a; - - b &= 0x40100400; - b = b - (b >> 5); - a &= b; - a |= 0x01f07c1f; - dest[0] = RGB32k.All[(a>>15) & a]; - - a = (fg2rgb[colormap[source[1]]] | 0x40100400) - bg2rgb[dest[1]]; - b = a; - b &= 0x40100400; - b = b - (b >> 5); - a &= b; - a |= 0x01f07c1f; - dest[1] = RGB32k.All[(a>>15) & a]; - - a = (fg2rgb[colormap[source[2]]] | 0x40100400) - bg2rgb[dest[2]]; - b = a; - b &= 0x40100400; - b = b - (b >> 5); - a &= b; - a |= 0x01f07c1f; - dest[2] = RGB32k.All[(a>>15) & a]; - - a = (fg2rgb[colormap[source[3]]] | 0x40100400) - bg2rgb[dest[3]]; - b = a; - b &= 0x40100400; - b = b - (b >> 5); - a &= b; - a |= 0x01f07c1f; - dest[3] = RGB32k.All[(a>>15) & a]; + for (int ks = 0; ks < 4; ks++) + { + int fg = colormap[source[ks]]; + int bg = dest[ks]; + int r = MAX((palette[fg].r * _srcalpha - palette[bg].r * _destalpha)>>18, 0); + int g = MAX((palette[fg].g * _srcalpha - palette[bg].g * _destalpha)>>18, 0); + int b = MAX((palette[fg].b * _srcalpha - palette[bg].b * _destalpha)>>18, 0); + dest[ks] = RGB256k.RGB[r][g][b]; + } source += 4; dest += pitch; @@ -792,16 +713,15 @@ namespace swrenderer source = &thread->dc_temp[thread->temp_line_for_thread(yl)*4 + hx]; pitch = _pitch * thread->num_cores; colormap = _colormap; + const PalEntry *palette = GPalette.BaseColors; do { - uint32_t a = (bg2rgb[*dest] | 0x40100400) - fg2rgb[colormap[*source]]; - uint32_t b = a; - - b &= 0x40100400; - b = b - (b >> 5); - a &= b; - a |= 0x01f07c1f; - *dest = RGB32k.All[(a>>15) & a]; + int fg = colormap[*source]; + int bg = *dest; + int r = MAX((-palette[fg].r * _srcalpha + palette[bg].r * _destalpha)>>18, 0); + int g = MAX((-palette[fg].g * _srcalpha + palette[bg].g * _destalpha)>>18, 0); + int b = MAX((-palette[fg].b * _srcalpha + palette[bg].b * _destalpha)>>18, 0); + *dest = RGB256k.RGB[r][g][b]; source += 4; dest += pitch; } while (--count); @@ -825,40 +745,18 @@ namespace swrenderer source = &thread->dc_temp[thread->temp_line_for_thread(yl)*4]; pitch = _pitch * thread->num_cores; colormap = _colormap; + const PalEntry *palette = GPalette.BaseColors; do { - uint32_t a = (bg2rgb[dest[0]] | 0x40100400) - fg2rgb[colormap[source[0]]]; - uint32_t b = a; - - b &= 0x40100400; - b = b - (b >> 5); - a &= b; - a |= 0x01f07c1f; - dest[0] = RGB32k.All[(a>>15) & a]; - - a = (bg2rgb[dest[1]] | 0x40100400) - fg2rgb[colormap[source[1]]]; - b = a; - b &= 0x40100400; - b = b - (b >> 5); - a &= b; - a |= 0x01f07c1f; - dest[1] = RGB32k.All[(a>>15) & a]; - - a = (bg2rgb[dest[2]] | 0x40100400) - fg2rgb[colormap[source[2]]]; - b = a; - b &= 0x40100400; - b = b - (b >> 5); - a &= b; - a |= 0x01f07c1f; - dest[2] = RGB32k.All[(a>>15) & a]; - - a = (bg2rgb[dest[3]] | 0x40100400) - fg2rgb[colormap[source[3]]]; - b = a; - b &= 0x40100400; - b = b - (b >> 5); - a &= b; - a |= 0x01f07c1f; - dest[3] = RGB32k.All[(a>>15) & a]; + for (int ks = 0; ks < 4; ks++) + { + int fg = colormap[source[ks]]; + int bg = dest[ks]; + int r = MAX((-palette[fg].r * _srcalpha + palette[bg].r * _destalpha)>>18, 0); + int g = MAX((-palette[fg].g * _srcalpha + palette[bg].g * _destalpha)>>18, 0); + int b = MAX((-palette[fg].b * _srcalpha + palette[bg].b * _destalpha)>>18, 0); + dest[ks] = RGB256k.RGB[r][g][b]; + } source += 4; dest += pitch; diff --git a/src/r_plane.cpp b/src/r_plane.cpp index cd378aec1..865517dd1 100644 --- a/src/r_plane.cpp +++ b/src/r_plane.cpp @@ -1509,14 +1509,14 @@ void R_DrawNormalPlane (visplane_t *pl, double _xscale, double _yscale, fixed_t if (!additive) { spanfunc = R_DrawSpanMaskedTranslucent; - dc_srcblend = Col2RGB8[alpha>>10]; - dc_destblend = Col2RGB8[(OPAQUE-alpha)>>10]; + dc_srcalpha = alpha; + dc_destalpha = OPAQUE-alpha; } else { spanfunc = R_DrawSpanMaskedAddClamp; - dc_srcblend = Col2RGB8_LessPrecision[alpha>>10]; - dc_destblend = Col2RGB8_LessPrecision[FRACUNIT>>10]; + dc_srcalpha = alpha; + dc_destalpha = FRACUNIT; } } else @@ -1531,14 +1531,14 @@ void R_DrawNormalPlane (visplane_t *pl, double _xscale, double _yscale, fixed_t if (!additive) { spanfunc = R_DrawSpanTranslucent; - dc_srcblend = Col2RGB8[alpha>>10]; - dc_destblend = Col2RGB8[(OPAQUE-alpha)>>10]; + dc_srcalpha = alpha; + dc_destalpha = OPAQUE-alpha; } else { spanfunc = R_DrawSpanAddClamp; - dc_srcblend = Col2RGB8_LessPrecision[alpha>>10]; - dc_destblend = Col2RGB8_LessPrecision[FRACUNIT>>10]; + dc_srcalpha = alpha; + dc_destalpha = FRACUNIT; } } else diff --git a/src/r_things.cpp b/src/r_things.cpp index a1ace0d49..61da979da 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -2636,12 +2636,12 @@ static void R_DrawMaskedSegsBehindParticle (const vissprite_t *vis) } } -void R_DrawParticle_C (vissprite_t *vis) +//inline int clamp(int x, int y, int z) { return ((x < y) ? x : (z < y) ? z : y); } + +void R_DrawParticle (vissprite_t *vis) { - DWORD *bg2rgb; int spacing; BYTE *dest; - DWORD fg; BYTE color = vis->Style.colormap[vis->startfrac]; int yl = vis->y1; int ycount = vis->y2 - yl + 1; @@ -2653,33 +2653,10 @@ void R_DrawParticle_C (vissprite_t *vis) DrawerCommandQueue::WaitForWorkers(); // vis->renderflags holds translucency level (0-255) - { - fixed_t fglevel, bglevel; - DWORD *fg2rgb; + fixed_t fglevel, bglevel; - fglevel = ((vis->renderflags + 1) << 8) & ~0x3ff; - bglevel = FRACUNIT-fglevel; - fg2rgb = Col2RGB8[fglevel>>10]; - bg2rgb = Col2RGB8[bglevel>>10]; - fg = fg2rgb[color]; - } - - /* - - spacing = RenderTarget->GetPitch() - countbase; - dest = ylookup[yl] + x1 + dc_destorg; - - do - { - int count = countbase; - do - { - DWORD bg = bg2rgb[*dest]; - bg = (fg+bg) | 0x1f07c1f; - *dest++ = RGB32k.All[bg & (bg>>15)]; - } while (--count); - dest += spacing; - } while (--ycount);*/ + fglevel = ((vis->renderflags + 1) << 8) & ~0x3ff; + bglevel = FRACUNIT-fglevel; // original was row-wise // width = countbase @@ -2695,9 +2672,11 @@ void R_DrawParticle_C (vissprite_t *vis) dest = ylookup[yl] + x + dc_destorg; for (int y = 0; y < ycount; y++) { - DWORD bg = bg2rgb[*dest]; - bg = (fg+bg) | 0x1f07c1f; - *dest = RGB32k.All[bg & (bg>>15)]; + uint32_t dest_r = MIN((GPalette.BaseColors[*dest].r * bglevel + GPalette.BaseColors[color].r * fglevel) >> 18, 63); + uint32_t dest_g = MIN((GPalette.BaseColors[*dest].g * bglevel + GPalette.BaseColors[color].g * fglevel) >> 18, 63); + uint32_t dest_b = MIN((GPalette.BaseColors[*dest].b * bglevel + GPalette.BaseColors[color].b * fglevel) >> 18, 63); + + *dest = RGB256k.RGB[dest_r][dest_g][dest_b]; dest += spacing; } } diff --git a/src/r_things.h b/src/r_things.h index 6d694b8fd..740af279a 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -101,7 +101,7 @@ struct vissprite_t vissprite_t() {} }; -void R_DrawParticle_C (vissprite_t *); +void R_DrawParticle (vissprite_t *); void R_ProjectParticle (particle_t *, const sector_t *sector, int shade, int fakeside); extern int MaxVisSprites; diff --git a/src/textures/ddstexture.cpp b/src/textures/ddstexture.cpp index 31e748022..a2c69b38b 100644 --- a/src/textures/ddstexture.cpp +++ b/src/textures/ddstexture.cpp @@ -551,7 +551,7 @@ void FDDSTexture::ReadRGB (FWadLump &lump, BYTE *tcbuf) DWORD r = (c & RMask) << RShiftL; r |= r >> RShiftR; DWORD g = (c & GMask) << GShiftL; g |= g >> GShiftR; DWORD b = (c & BMask) << BShiftL; b |= b >> BShiftR; - *pixelp = RGB32k.RGB[r >> 27][g >> 27][b >> 27]; + *pixelp = RGB256k.RGB[r >> 26][g >> 26][b >> 26]; } else { @@ -637,7 +637,7 @@ void FDDSTexture::DecompressDXT1 (FWadLump &lump, BYTE *tcbuf) // Pick colors from the palette for each of the four colors. /*if (!tcbuf)*/ for (i = 3; i >= 0; --i) { - palcol[i] = color[i].a ? RGB32k.RGB[color[i].r >> 3][color[i].g >> 3][color[i].b >> 3] : 0; + palcol[i] = color[i].a ? RGB256k.RGB[color[i].r >> 2][color[i].g >> 2][color[i].b >> 2] : 0; } // Now decode this 4x4 block to the pixel buffer. for (y = 0; y < 4; ++y) @@ -717,7 +717,7 @@ void FDDSTexture::DecompressDXT3 (FWadLump &lump, bool premultiplied, BYTE *tcbu // Pick colors from the palette for each of the four colors. if (!tcbuf) for (i = 3; i >= 0; --i) { - palcol[i] = RGB32k.RGB[color[i].r >> 3][color[i].g >> 3][color[i].b >> 3]; + palcol[i] = RGB256k.RGB[color[i].r >> 2][color[i].g >> 2][color[i].b >> 2]; } // Now decode this 4x4 block to the pixel buffer. for (y = 0; y < 4; ++y) @@ -822,7 +822,7 @@ void FDDSTexture::DecompressDXT5 (FWadLump &lump, bool premultiplied, BYTE *tcbu // Pick colors from the palette for each of the four colors. if (!tcbuf) for (i = 3; i >= 0; --i) { - palcol[i] = RGB32k.RGB[color[i].r >> 3][color[i].g >> 3][color[i].b >> 3]; + palcol[i] = RGB256k.RGB[color[i].r >> 2][color[i].g >> 2][color[i].b >> 2]; } // Now decode this 4x4 block to the pixel buffer. for (y = 0; y < 4; ++y) diff --git a/src/textures/jpegtexture.cpp b/src/textures/jpegtexture.cpp index 225396598..c138edbfa 100644 --- a/src/textures/jpegtexture.cpp +++ b/src/textures/jpegtexture.cpp @@ -406,7 +406,7 @@ void FJPEGTexture::MakeTexture () case JCS_RGB: for (int x = Width; x > 0; --x) { - *out = RGB32k.RGB[in[0]>>3][in[1]>>3][in[2]>>3]; + *out = RGB256k.RGB[in[0]>>2][in[1]>>2][in[2]>>2]; out += Height; in += 3; } @@ -430,7 +430,7 @@ void FJPEGTexture::MakeTexture () int r = in[3] - (((256-in[0])*in[3]) >> 8); int g = in[3] - (((256-in[1])*in[3]) >> 8); int b = in[3] - (((256-in[2])*in[3]) >> 8); - *out = RGB32k.RGB[r >> 3][g >> 3][b >> 3]; + *out = RGB256k.RGB[r >> 2][g >> 2][b >> 2]; out += Height; in += 4; } diff --git a/src/textures/multipatchtexture.cpp b/src/textures/multipatchtexture.cpp index e68c4e20f..991893845 100644 --- a/src/textures/multipatchtexture.cpp +++ b/src/textures/multipatchtexture.cpp @@ -531,7 +531,7 @@ void FMultiPatchTexture::MakeTexture () { if (*out == 0 && in[3] != 0) { - *out = RGB32k.RGB[in[2]>>3][in[1]>>3][in[0]>>3]; + *out = RGB256k.RGB[in[2]>>2][in[1]>>2][in[0]>>2]; } out += Height; in += 4; diff --git a/src/textures/pcxtexture.cpp b/src/textures/pcxtexture.cpp index 0ec5d2933..dda431993 100644 --- a/src/textures/pcxtexture.cpp +++ b/src/textures/pcxtexture.cpp @@ -528,7 +528,7 @@ void FPCXTexture::MakeTexture() { for(int x=0; x < Width; x++) { - Pixels[y+Height*x] = RGB32k.RGB[row[0]>>3][row[1]>>3][row[2]>>3]; + Pixels[y+Height*x] = RGB256k.RGB[row[0]>>2][row[1]>>2][row[2]>>2]; row+=3; } } diff --git a/src/textures/pngtexture.cpp b/src/textures/pngtexture.cpp index d24cd92d1..414c424b8 100644 --- a/src/textures/pngtexture.cpp +++ b/src/textures/pngtexture.cpp @@ -536,7 +536,7 @@ void FPNGTexture::MakeTexture () { if (!HaveTrans) { - *out++ = RGB32k.RGB[in[0]>>3][in[1]>>3][in[2]>>3]; + *out++ = RGB256k.RGB[in[0]>>2][in[1]>>2][in[2]>>2]; } else { @@ -548,7 +548,7 @@ void FPNGTexture::MakeTexture () } else { - *out++ = RGB32k.RGB[in[0]>>3][in[1]>>3][in[2]>>3]; + *out++ = RGB256k.RGB[in[0]>>2][in[1]>>2][in[2]>>2]; } } in += pitch; @@ -593,7 +593,7 @@ void FPNGTexture::MakeTexture () { for (y = Height; y > 0; --y) { - *out++ = in[3] < 128 ? 0 : RGB32k.RGB[in[0]>>3][in[1]>>3][in[2]>>3]; + *out++ = in[3] < 128 ? 0 : RGB256k.RGB[in[0]>>2][in[1]>>2][in[2]>>2]; in += pitch; } in -= backstep; diff --git a/src/textures/tgatexture.cpp b/src/textures/tgatexture.cpp index b208a51a3..331747cfe 100644 --- a/src/textures/tgatexture.cpp +++ b/src/textures/tgatexture.cpp @@ -393,7 +393,7 @@ void FTGATexture::MakeTexture () for(int x=0;x>10) & 0x1f][(v>>5) & 0x1f][v & 0x1f]; + Pixels[x*Height+y] = RGB256k.RGB[((v>>10) & 0x1f)*2][((v>>5) & 0x1f)*2][(v & 0x1f)*2]; p+=step_x; } } @@ -405,7 +405,7 @@ void FTGATexture::MakeTexture () BYTE * p = ptr + y * Pitch; for(int x=0;x>3][p[1]>>3][p[0]>>3]; + Pixels[x*Height+y] = RGB256k.RGB[p[2]>>2][p[1]>>2][p[0]>>2]; p+=step_x; } } @@ -419,7 +419,7 @@ void FTGATexture::MakeTexture () BYTE * p = ptr + y * Pitch; for(int x=0;x>3][p[1]>>3][p[0]>>3]; + Pixels[x*Height+y] = RGB256k.RGB[p[2]>>2][p[1]>>2][p[0]>>2]; p+=step_x; } } @@ -431,7 +431,7 @@ void FTGATexture::MakeTexture () BYTE * p = ptr + y * Pitch; for(int x=0;x= 128? RGB32k.RGB[p[2]>>3][p[1]>>3][p[0]>>3] : 0; + Pixels[x*Height+y] = p[3] >= 128? RGB256k.RGB[p[2]>>2][p[1]>>2][p[0]>>2] : 0; p+=step_x; } } diff --git a/src/v_draw.cpp b/src/v_draw.cpp index 6f8bc5198..5f0d39d4f 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -965,27 +965,6 @@ void DCanvas::PUTTRANSDOT (int xx, int yy, int basecolor, int level) static int oldyy; static int oldyyshifted; -#if 0 - if(xx < 32) - cc += 7-(xx>>2); - else if(xx > (finit_width - 32)) - cc += 7-((finit_width-xx) >> 2); -// if(cc==oldcc) //make sure that we don't double fade the corners. -// { - if(yy < 32) - cc += 7-(yy>>2); - else if(yy > (finit_height - 32)) - cc += 7-((finit_height-yy) >> 2); -// } - if(cc > cm && cm != NULL) - { - cc = cm; - } - else if(cc > oldcc+6) // don't let the color escape from the fade table... - { - cc=oldcc+6; - } -#endif if (yy == oldyy+1) { oldyy++; @@ -1003,12 +982,12 @@ void DCanvas::PUTTRANSDOT (int xx, int yy, int basecolor, int level) } BYTE *spot = GetBuffer() + oldyyshifted + xx; - DWORD *bg2rgb = Col2RGB8[1+level]; - DWORD *fg2rgb = Col2RGB8[63-level]; - DWORD fg = fg2rgb[basecolor]; - DWORD bg = bg2rgb[*spot]; - bg = (fg+bg) | 0x1f07c1f; - *spot = RGB32k.All[bg&(bg>>15)]; + + uint32_t r = (GPalette.BaseColors[*spot].r * (64 - level) + GPalette.BaseColors[basecolor].r * level) / 64; + uint32_t g = (GPalette.BaseColors[*spot].g * (64 - level) + GPalette.BaseColors[basecolor].g * level) / 64; + uint32_t b = (GPalette.BaseColors[*spot].b * (64 - level) + GPalette.BaseColors[basecolor].b * level) / 64; + + *spot = (BYTE)RGB256k.RGB[r][g][b]; } void DCanvas::DrawLine(int x0, int y0, int x1, int y1, int palColor, uint32 realcolor) diff --git a/src/v_video.cpp b/src/v_video.cpp index efe93aa04..b639939ee 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -143,9 +143,10 @@ extern "C" { DWORD Col2RGB8[65][256]; DWORD *Col2RGB8_LessPrecision[65]; DWORD Col2RGB8_Inverse[65][256]; -ColorTable32k RGB32k; +ColorTable256k RGB256k; } + static DWORD Col2RGB8_2[63][256]; // [RH] The framebuffer is no longer a mere byte array. @@ -345,8 +346,6 @@ void DCanvas::Dim (PalEntry color, float damount, int x1, int y1, int w, int h) if (damount == 0.f) return; - DWORD *bg2rgb; - DWORD fg; int gap; BYTE *spot; int x, y; @@ -368,28 +367,23 @@ void DCanvas::Dim (PalEntry color, float damount, int x1, int y1, int w, int h) return; } - { - int amount; - - amount = (int)(damount * 64); - bg2rgb = Col2RGB8[64-amount]; - - fg = (((color.r * amount) >> 4) << 20) | - ((color.g * amount) >> 4) | - (((color.b * amount) >> 4) << 10); - } spot = Buffer + x1 + y1*Pitch; gap = Pitch - w; + + int alpha = (int)((float)64 * damount); + int ialpha = 64 - alpha; + int dimmedcolor_r = color.r * alpha; + int dimmedcolor_g = color.g * alpha; + int dimmedcolor_b = color.b * alpha; for (y = h; y != 0; y--) { for (x = w; x != 0; x--) { - DWORD bg; - - bg = bg2rgb[(*spot)&0xff]; - bg = (fg+bg) | 0x1f07c1f; - *spot = RGB32k.All[bg&(bg>>15)]; + uint32_t r = (dimmedcolor_r + GPalette.BaseColors[*spot].r * ialpha) >> 8; + uint32_t g = (dimmedcolor_g + GPalette.BaseColors[*spot].g * ialpha) >> 8; + uint32_t b = (dimmedcolor_b + GPalette.BaseColors[*spot].b * ialpha) >> 8; + *spot = (BYTE)RGB256k.RGB[r][g][b]; spot++; } spot += gap; @@ -664,42 +658,12 @@ static void BuildTransTable (const PalEntry *palette) { int r, g, b; - // create the RGB555 lookup table - for (r = 0; r < 32; r++) - for (g = 0; g < 32; g++) - for (b = 0; b < 32; b++) - RGB32k.RGB[r][g][b] = ColorMatcher.Pick ((r<<3)|(r>>2), (g<<3)|(g>>2), (b<<3)|(b>>2)); + // create the RGB666 lookup table + for (r = 0; r < 64; r++) + for (g = 0; g < 64; g++) + for (b = 0; b < 64; b++) + RGB256k.RGB[r][g][b] = ColorMatcher.Pick ((r<<2)|(r>>4), (g<<2)|(g>>4), (b<<2)|(b>>4)); - int x, y; - - // create the swizzled palette - for (x = 0; x < 65; x++) - for (y = 0; y < 256; y++) - Col2RGB8[x][y] = (((palette[y].r*x)>>4)<<20) | - ((palette[y].g*x)>>4) | - (((palette[y].b*x)>>4)<<10); - - // create the swizzled palette with the lsb of red and blue forced to 0 - // (for green, a 1 is okay since it never gets added into) - for (x = 1; x < 64; x++) - { - Col2RGB8_LessPrecision[x] = Col2RGB8_2[x-1]; - for (y = 0; y < 256; y++) - { - Col2RGB8_2[x-1][y] = Col2RGB8[x][y] & 0x3feffbff; - } - } - Col2RGB8_LessPrecision[0] = Col2RGB8[0]; - Col2RGB8_LessPrecision[64] = Col2RGB8[64]; - - // create the inverse swizzled palette - for (x = 0; x < 65; x++) - for (y = 0; y < 256; y++) - { - Col2RGB8_Inverse[x][y] = (((((255-palette[y].r)*x)>>4)<<20) | - (((255-palette[y].g)*x)>>4) | - ((((255-palette[y].b)*x)>>4)<<10)) & 0x3feffbff; - } } //========================================================================== diff --git a/src/v_video.h b/src/v_video.h index b72f67094..0da6b9b50 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -448,44 +448,13 @@ EXTERN_CVAR (Float, Gamma) // Translucency tables -// RGB32k is a normal R5G5B5 -> palette lookup table. - -// Use a union so we can "overflow" without warnings. -// Otherwise, we get stuff like this from Clang (when compiled -// with -fsanitize=bounds) while running: -// src/v_video.cpp:390:12: runtime error: index 1068 out of bounds for type 'BYTE [32]' -// src/r_draw.cpp:273:11: runtime error: index 1057 out of bounds for type 'BYTE [32]' -union ColorTable32k +// [SP] RGB666 support +union ColorTable256k { - BYTE RGB[32][32][32]; - BYTE All[32 *32 *32]; + BYTE RGB[64][64][64]; + BYTE All[64 *64 *64]; }; -extern "C" ColorTable32k RGB32k; - -// Col2RGB8 is a pre-multiplied palette for color lookup. It is stored in a -// special R10B10G10 format for efficient blending computation. -// --RRRRRrrr--BBBBBbbb--GGGGGggg-- at level 64 -// --------rrrr------bbbb------gggg at level 1 -extern "C" DWORD Col2RGB8[65][256]; - -// Col2RGB8_LessPrecision is the same as Col2RGB8, but the LSB for red -// and blue are forced to zero, so if the blend overflows, it won't spill -// over into the next component's value. -// --RRRRRrrr-#BBBBBbbb-#GGGGGggg-- at level 64 -// --------rrr#------bbb#------gggg at level 1 -extern "C" DWORD *Col2RGB8_LessPrecision[65]; - -// Col2RGB8_Inverse is the same as Col2RGB8_LessPrecision, except the source -// palette has been inverted. -extern "C" DWORD Col2RGB8_Inverse[65][256]; - -// "Magic" numbers used during the blending: -// --000001111100000111110000011111 = 0x01f07c1f -// -0111111111011111111101111111111 = 0x3FEFFBFF -// -1000000000100000000010000000000 = 0x40100400 -// ------10000000001000000000100000 = 0x40100400 >> 5 -// --11111-----11111-----11111----- = 0x40100400 - (0x40100400 >> 5) aka "white" -// --111111111111111111111111111111 = 0x3FFFFFFF +extern "C" ColorTable256k RGB256k; // Allocates buffer screens, call before R_Init. void V_Init (bool restart);