Created standalone rgba drawing functions

This commit is contained in:
Magnus Norddahl 2016-05-30 05:52:15 +02:00
parent 6e53c1bd12
commit 8aabc26cd9
12 changed files with 2896 additions and 1082 deletions

View file

@ -883,6 +883,7 @@ set( FASTMATH_PCH_SOURCES
r_bsp.cpp
r_draw.cpp
r_drawt.cpp
r_drawt_rgba.cpp
r_main.cpp
r_plane.cpp
r_segs.cpp

File diff suppressed because it is too large Load diff

View file

@ -127,33 +127,33 @@ extern "C"
void rt_copy1col_c (int hx, int sx, int yl, int yh);
void rt_copy4cols_c (int sx, int yl, int yh);
void rt_shaded1col (int hx, int sx, int yl, int yh);
void rt_shaded1col_c (int hx, int sx, int yl, int yh);
void rt_shaded4cols_c (int sx, int yl, int yh);
void rt_shaded4cols_asm (int sx, int yl, int yh);
void rt_map1col_c (int hx, int sx, int yl, int yh);
void rt_add1col (int hx, int sx, int yl, int yh);
void rt_addclamp1col (int hx, int sx, int yl, int yh);
void rt_subclamp1col (int hx, int sx, int yl, int yh);
void rt_revsubclamp1col (int hx, int sx, int yl, int yh);
void rt_add1col_c (int hx, int sx, int yl, int yh);
void rt_addclamp1col_c (int hx, int sx, int yl, int yh);
void rt_subclamp1col_c (int hx, int sx, int yl, int yh);
void rt_revsubclamp1col_c (int hx, int sx, int yl, int yh);
void rt_tlate1col (int hx, int sx, int yl, int yh);
void rt_tlateadd1col (int hx, int sx, int yl, int yh);
void rt_tlateaddclamp1col (int hx, int sx, int yl, int yh);
void rt_tlatesubclamp1col (int hx, int sx, int yl, int yh);
void rt_tlaterevsubclamp1col (int hx, int sx, int yl, int yh);
void rt_tlate1col_c (int hx, int sx, int yl, int yh);
void rt_tlateadd1col_c (int hx, int sx, int yl, int yh);
void rt_tlateaddclamp1col_c (int hx, int sx, int yl, int yh);
void rt_tlatesubclamp1col_c (int hx, int sx, int yl, int yh);
void rt_tlaterevsubclamp1col_c (int hx, int sx, int yl, int yh);
void rt_map4cols_c (int sx, int yl, int yh);
void rt_add4cols_c (int sx, int yl, int yh);
void rt_addclamp4cols_c (int sx, int yl, int yh);
void rt_subclamp4cols (int sx, int yl, int yh);
void rt_revsubclamp4cols (int sx, int yl, int yh);
void rt_subclamp4cols_c (int sx, int yl, int yh);
void rt_revsubclamp4cols_c (int sx, int yl, int yh);
void rt_tlate4cols (int sx, int yl, int yh);
void rt_tlateadd4cols (int sx, int yl, int yh);
void rt_tlateaddclamp4cols (int sx, int yl, int yh);
void rt_tlatesubclamp4cols (int sx, int yl, int yh);
void rt_tlaterevsubclamp4cols (int sx, int yl, int yh);
void rt_tlate4cols_c (int sx, int yl, int yh);
void rt_tlateadd4cols_c (int sx, int yl, int yh);
void rt_tlateaddclamp4cols_c (int sx, int yl, int yh);
void rt_tlatesubclamp4cols_c (int sx, int yl, int yh);
void rt_tlaterevsubclamp4cols_c (int sx, int yl, int yh);
void rt_copy1col_asm (int hx, int sx, int yl, int yh);
void rt_map1col_asm (int hx, int sx, int yl, int yh);
@ -163,32 +163,83 @@ void rt_map4cols_asm1 (int sx, int yl, int yh);
void rt_map4cols_asm2 (int sx, int yl, int yh);
void rt_add4cols_asm (int sx, int yl, int yh);
void rt_addclamp4cols_asm (int sx, int yl, int yh);
///
void rt_copy1col_RGBA_c (int hx, int sx, int yl, int yh);
void rt_copy4cols_RGBA_c (int sx, int yl, int yh);
void rt_shaded1col_RGBA_c (int hx, int sx, int yl, int yh);
void rt_shaded4cols_RGBA_c (int sx, int yl, int yh);
void rt_map1col_RGBA_c (int hx, int sx, int yl, int yh);
void rt_add1col_RGBA_c (int hx, int sx, int yl, int yh);
void rt_addclamp1col_RGBA_c (int hx, int sx, int yl, int yh);
void rt_subclamp1col_RGBA_c (int hx, int sx, int yl, int yh);
void rt_revsubclamp1col_RGBA_c (int hx, int sx, int yl, int yh);
void rt_tlate1col_RGBA_c (int hx, int sx, int yl, int yh);
void rt_tlateadd1col_RGBA_c (int hx, int sx, int yl, int yh);
void rt_tlateaddclamp1col_RGBA_c (int hx, int sx, int yl, int yh);
void rt_tlatesubclamp1col_RGBA_c (int hx, int sx, int yl, int yh);
void rt_tlaterevsubclamp1col_RGBA_c (int hx, int sx, int yl, int yh);
void rt_map4cols_RGBA_c (int sx, int yl, int yh);
void rt_add4cols_RGBA_c (int sx, int yl, int yh);
void rt_addclamp4cols_RGBA_c (int sx, int yl, int yh);
void rt_subclamp4cols_RGBA_c (int sx, int yl, int yh);
void rt_revsubclamp4cols_RGBA_c (int sx, int yl, int yh);
void rt_tlate4cols_RGBA_c (int sx, int yl, int yh);
void rt_tlateadd4cols_RGBA_c (int sx, int yl, int yh);
void rt_tlateaddclamp4cols_RGBA_c (int sx, int yl, int yh);
void rt_tlatesubclamp4cols_RGBA_c (int sx, int yl, int yh);
void rt_tlaterevsubclamp4cols_RGBA_c (int sx, int yl, int yh);
}
extern void (*rt_map4cols)(int sx, int yl, int yh);
extern void (*rt_copy1col)(int hx, int sx, int yl, int yh);
extern void (*rt_copy4cols)(int sx, int yl, int yh);
#ifdef X86_ASM
#define rt_copy1col rt_copy1col_asm
#define rt_copy4cols rt_copy4cols_asm
#define rt_map1col rt_map1col_asm
#define rt_shaded4cols rt_shaded4cols_asm
#define rt_add4cols rt_add4cols_asm
#define rt_addclamp4cols rt_addclamp4cols_asm
#else
#define rt_copy1col rt_copy1col_c
#define rt_copy4cols rt_copy4cols_c
#define rt_map1col rt_map1col_c
#define rt_shaded4cols rt_shaded4cols_c
#define rt_add4cols rt_add4cols_c
#define rt_addclamp4cols rt_addclamp4cols_c
#endif
extern void (*rt_shaded1col)(int hx, int sx, int yl, int yh);
extern void (*rt_shaded4cols)(int sx, int yl, int yh);
extern void (*rt_map1col)(int hx, int sx, int yl, int yh);
extern void (*rt_add1col)(int hx, int sx, int yl, int yh);
extern void (*rt_addclamp1col)(int hx, int sx, int yl, int yh);
extern void (*rt_subclamp1col)(int hx, int sx, int yl, int yh);
extern void (*rt_revsubclamp1col)(int hx, int sx, int yl, int yh);
extern void (*rt_tlate1col)(int hx, int sx, int yl, int yh);
extern void (*rt_tlateadd1col)(int hx, int sx, int yl, int yh);
extern void (*rt_tlateaddclamp1col)(int hx, int sx, int yl, int yh);
extern void (*rt_tlatesubclamp1col)(int hx, int sx, int yl, int yh);
extern void (*rt_tlaterevsubclamp1col)(int hx, int sx, int yl, int yh);
extern void (*rt_map4cols)(int sx, int yl, int yh);
extern void (*rt_add4cols)(int sx, int yl, int yh);
extern void (*rt_addclamp4cols)(int sx, int yl, int yh);
extern void (*rt_subclamp4cols)(int sx, int yl, int yh);
extern void (*rt_revsubclamp4cols)(int sx, int yl, int yh);
extern void (*rt_tlate4cols)(int sx, int yl, int yh);
extern void (*rt_tlateadd4cols)(int sx, int yl, int yh);
extern void (*rt_tlateaddclamp4cols)(int sx, int yl, int yh);
extern void (*rt_tlatesubclamp4cols)(int sx, int yl, int yh);
extern void (*rt_tlaterevsubclamp4cols)(int sx, int yl, int yh);
extern void (*rt_initcols)(canvas_pixel_t *buffer);
void rt_draw4cols (int sx);
// [RH] Preps the temporary horizontal buffer.
void rt_initcols (canvas_pixel_t *buffer=NULL);
void rt_initcols_pal (canvas_pixel_t *buffer);
void rt_initcols_rgba (canvas_pixel_t *buffer);
void R_DrawFogBoundary (int x1, int x2, short *uclip, short *dclip);
extern void (*R_DrawFogBoundary)(int x1, int x2, short *uclip, short *dclip);
void R_DrawFogBoundary_C (int x1, int x2, short *uclip, short *dclip);
#ifdef X86_ASM
@ -212,6 +263,14 @@ void R_DrawShadedColumnP_C (void);
void R_DrawSpanP_C (void);
void R_DrawSpanMaskedP_C (void);
void R_DrawColumnHorizP_RGBA_C (void);
void R_DrawColumnP_RGBA_C (void);
void R_DrawFuzzColumnP_RGBA_C (void);
void R_DrawTranslatedColumnP_RGBA_C (void);
void R_DrawShadedColumnP_RGBA_C (void);
void R_DrawSpanP_RGBA_C (void);
void R_DrawSpanMaskedP_RGBA_C (void);
#endif
void R_DrawSpanTranslucentP_C (void);
@ -220,9 +279,30 @@ void R_DrawSpanMaskedTranslucentP_C (void);
void R_DrawTlatedLucentColumnP_C (void);
#define R_DrawTlatedLucentColumn R_DrawTlatedLucentColumnP_C
void R_FillColumnP (void);
void R_FillColumnHorizP (void);
void R_FillSpan (void);
extern void(*R_FillColumn)(void);
extern void(*R_FillAddColumn)(void);
extern void(*R_FillAddClampColumn)(void);
extern void(*R_FillSubClampColumn)(void);
extern void(*R_FillRevSubClampColumn)(void);
extern void(*R_DrawAddColumn)(void);
extern void(*R_DrawTlatedAddColumn)(void);
extern void(*R_DrawAddClampColumn)(void);
extern void(*R_DrawAddClampTranslatedColumn)(void);
extern void(*R_DrawSubClampColumn)(void);
extern void(*R_DrawSubClampTranslatedColumn)(void);
extern void(*R_DrawRevSubClampColumn)(void);
extern void(*R_DrawRevSubClampTranslatedColumn)(void);
extern void(*R_FillSpan)(void);
extern void(*R_FillColumnHoriz)(void);
void R_FillColumnP_C (void);
void R_FillColumnHorizP_C (void);
void R_FillSpan_C (void);
void R_FillColumnHorizP_RGBA_C(void);
void R_FillSpan_RGBA_C(void);
#ifdef X86_ASM
#define R_SetupDrawSlab R_SetupDrawSlabA
@ -282,6 +362,15 @@ inline ESPSResult R_SetPatchStyle(FRenderStyle style, float alpha, int translati
// style was STYLE_Shade
void R_FinishSetPatchStyle ();
extern fixed_t(*tmvline1_add)();
extern void(*tmvline4_add)();
extern fixed_t(*tmvline1_addclamp)();
extern void(*tmvline4_addclamp)();
extern fixed_t(*tmvline1_subclamp)();
extern void(*tmvline4_subclamp)();
extern fixed_t(*tmvline1_revsubclamp)();
extern void(*tmvline4_revsubclamp)();
// transmaskwallscan calls this to find out what column drawers to use
bool R_GetTransMaskDrawers (fixed_t (**tmvline1)(), void (**tmvline4)());

View file

@ -114,13 +114,6 @@ void rt_copy1col_c (int hx, int sx, int yl, int yh)
// Copies all four spans to the screen starting at sx.
void rt_copy4cols_c (int sx, int yl, int yh)
{
#ifndef PALETTEOUTPUT
// To do: we could do this with SSE using __m128i
rt_copy1col_c(0, sx, yl, yh);
rt_copy1col_c(1, sx + 1, yl, yh);
rt_copy1col_c(2, sx + 2, yl, yh);
rt_copy1col_c(3, sx + 3, yl, yh);
#else
int *source;
int *dest;
int count;
@ -149,7 +142,6 @@ void rt_copy4cols_c (int sx, int yl, int yh)
source += 8/sizeof(int);
dest += pitch*2;
} while (--count);
#endif
}
// Maps one span at hx to the screen at sx.
@ -166,21 +158,13 @@ void rt_map1col_c (int hx, int sx, int yl, int yh)
return;
count++;
#ifndef PALETTEOUTPUT
uint32_t light = calc_light_multiplier(dc_light);
#endif
colormap = dc_colormap;
dest = ylookup[yl] + sx + dc_destorg;
source = &dc_temp[yl*4 + hx];
pitch = dc_pitch;
if (count & 1) {
#ifndef PALETTEOUTPUT
*dest = shade_pal_index(colormap[*source], light);
#else
*dest = colormap[*source];
#endif
source += 4;
dest += pitch;
}
@ -188,13 +172,8 @@ void rt_map1col_c (int hx, int sx, int yl, int yh)
return;
do {
#ifndef PALETTEOUTPUT
dest[0] = shade_pal_index(colormap[source[0]], light);
dest[pitch] = shade_pal_index(colormap[source[4]], light);
#else
dest[0] = colormap[source[0]];
dest[pitch] = colormap[source[4]];
#endif
source += 8;
dest += pitch*2;
} while (--count);
@ -214,27 +193,16 @@ void rt_map4cols_c (int sx, int yl, int yh)
return;
count++;
#ifndef PALETTEOUTPUT
uint32_t light = calc_light_multiplier(dc_light);
#endif
colormap = dc_colormap;
dest = ylookup[yl] + sx + dc_destorg;
source = &dc_temp[yl*4];
pitch = dc_pitch;
if (count & 1) {
#ifndef PALETTEOUTPUT
dest[0] = shade_pal_index(colormap[source[0]], light);
dest[1] = shade_pal_index(colormap[source[1]], light);
dest[2] = shade_pal_index(colormap[source[2]], light);
dest[3] = shade_pal_index(colormap[source[3]], light);
#else
dest[0] = colormap[source[0]];
dest[1] = colormap[source[1]];
dest[2] = colormap[source[2]];
dest[3] = colormap[source[3]];
#endif
source += 4;
dest += pitch;
}
@ -242,16 +210,6 @@ void rt_map4cols_c (int sx, int yl, int yh)
return;
do {
#ifndef PALETTEOUTPUT
dest[0] = shade_pal_index(colormap[source[0]], light);
dest[1] = shade_pal_index(colormap[source[1]], light);
dest[2] = shade_pal_index(colormap[source[2]], light);
dest[3] = shade_pal_index(colormap[source[3]], light);
dest[pitch] = shade_pal_index(colormap[source[4]], light);
dest[pitch + 1] = shade_pal_index(colormap[source[5]], light);
dest[pitch + 2] = shade_pal_index(colormap[source[6]], light);
dest[pitch + 3] = shade_pal_index(colormap[source[7]], light);
#else
dest[0] = colormap[source[0]];
dest[1] = colormap[source[1]];
dest[2] = colormap[source[2]];
@ -260,7 +218,6 @@ void rt_map4cols_c (int sx, int yl, int yh)
dest[pitch+1] = colormap[source[5]];
dest[pitch+2] = colormap[source[6]];
dest[pitch+3] = colormap[source[7]];
#endif
source += 8;
dest += pitch*2;
} while (--count);
@ -356,21 +313,21 @@ void rt_Translate4cols(const BYTE *translation, int yl, int yh)
}
// Translates one span at hx to the screen at sx.
void rt_tlate1col (int hx, int sx, int yl, int yh)
void rt_tlate1col_c (int hx, int sx, int yl, int yh)
{
rt_Translate1col(dc_translation, hx, yl, yh);
rt_map1col(hx, sx, yl, yh);
}
// Translates all four spans to the screen starting at sx.
void rt_tlate4cols (int sx, int yl, int yh)
void rt_tlate4cols_c (int sx, int yl, int yh)
{
rt_Translate4cols(dc_translation, yl, yh);
rt_map4cols(sx, yl, yh);
}
// Adds one span at hx to the screen at sx without clamping.
void rt_add1col (int hx, int sx, int yl, int yh)
void rt_add1col_c (int hx, int sx, int yl, int yh)
{
BYTE *colormap;
canvas_pixel_t *source;
@ -388,29 +345,6 @@ void rt_add1col (int hx, int sx, int yl, int yh)
pitch = dc_pitch;
colormap = dc_colormap;
#ifndef PALETTEOUTPUT
uint32_t light = calc_light_multiplier(dc_light);
do {
uint32_t fg = shade_pal_index(colormap[*source], light);
uint32_t fg_red = (fg >> 16) & 0xff;
uint32_t fg_green = (fg >> 8) & 0xff;
uint32_t fg_blue = fg & 0xff;
uint32_t bg_red = (*dest >> 16) & 0xff;
uint32_t bg_green = (*dest >> 8) & 0xff;
uint32_t bg_blue = (*dest) & 0xff;
uint32_t red = clamp<uint32_t>(fg_red + bg_red, 0, 255);
uint32_t green = clamp<uint32_t>(fg_green + bg_green, 0, 255);
uint32_t blue = clamp<uint32_t>(fg_blue + bg_blue, 0, 255);
*dest = 0xff000000 | (red << 16) | (green << 8) | blue;
source += 4;
dest += pitch;
} while (--count);
#else
DWORD *fg2rgb = dc_srcblend;
DWORD *bg2rgb = dc_destblend;
do {
@ -424,7 +358,6 @@ void rt_add1col (int hx, int sx, int yl, int yh)
source += 4;
dest += pitch;
} while (--count);
#endif
}
// Adds all four spans to the screen starting at sx without clamping.
@ -446,32 +379,6 @@ void rt_add4cols_c (int sx, int yl, int yh)
pitch = dc_pitch;
colormap = dc_colormap;
#ifndef PALETTEOUTPUT
uint32_t light = calc_light_multiplier(dc_light);
do {
for (int i = 0; i < 4; i++)
{
uint32_t fg = shade_pal_index(colormap[source[i]], light);
uint32_t fg_red = (fg >> 16) & 0xff;
uint32_t fg_green = (fg >> 8) & 0xff;
uint32_t fg_blue = fg & 0xff;
uint32_t bg_red = (dest[i] >> 16) & 0xff;
uint32_t bg_green = (dest[i] >> 8) & 0xff;
uint32_t bg_blue = (dest[i]) & 0xff;
uint32_t red = clamp<uint32_t>(fg_red + bg_red, 0, 255);
uint32_t green = clamp<uint32_t>(fg_green + bg_green, 0, 255);
uint32_t blue = clamp<uint32_t>(fg_blue + bg_blue, 0, 255);
dest[i] = 0xff000000 | (red << 16) | (green << 8) | blue;
}
source += 4;
dest += pitch;
} while (--count);
#else
DWORD *fg2rgb = dc_srcblend;
DWORD *bg2rgb = dc_destblend;
@ -508,25 +415,24 @@ void rt_add4cols_c (int sx, int yl, int yh)
source += 4;
dest += pitch;
} while (--count);
#endif
}
// Translates and adds one span at hx to the screen at sx without clamping.
void rt_tlateadd1col (int hx, int sx, int yl, int yh)
void rt_tlateadd1col_c (int hx, int sx, int yl, int yh)
{
rt_Translate1col(dc_translation, hx, yl, yh);
rt_add1col(hx, sx, yl, yh);
}
// Translates and adds all four spans to the screen starting at sx without clamping.
void rt_tlateadd4cols (int sx, int yl, int yh)
void rt_tlateadd4cols_c (int sx, int yl, int yh)
{
rt_Translate4cols(dc_translation, yl, yh);
rt_add4cols(sx, yl, yh);
}
// Shades one span at hx to the screen at sx.
void rt_shaded1col (int hx, int sx, int yl, int yh)
void rt_shaded1col_c (int hx, int sx, int yl, int yh)
{
BYTE *colormap;
canvas_pixel_t *source;
@ -544,29 +450,6 @@ void rt_shaded1col (int hx, int sx, int yl, int yh)
source = &dc_temp[yl*4 + hx];
pitch = dc_pitch;
#ifndef PALETTEOUTPUT
uint32_t fg = shade_pal_index(dc_color, calc_light_multiplier(0));
uint32_t fg_red = (fg >> 16) & 0xff;
uint32_t fg_green = (fg >> 8) & 0xff;
uint32_t fg_blue = fg & 0xff;
do {
uint32_t alpha = colormap[*source];
uint32_t inv_alpha = 64 - alpha;
uint32_t bg_red = (*dest >> 16) & 0xff;
uint32_t bg_green = (*dest >> 8) & 0xff;
uint32_t bg_blue = (*dest) & 0xff;
uint32_t red = (fg_red * alpha + bg_red * inv_alpha) / 64;
uint32_t green = (fg_green * alpha + bg_green * inv_alpha) / 64;
uint32_t blue = (fg_blue * alpha + bg_blue * inv_alpha) / 64;
*dest = 0xff000000 | (red << 16) | (green << 8) | blue;
source += 4;
dest += pitch;
} while (--count);
#else
DWORD *fgstart;
fgstart = &Col2RGB8[0][dc_color];
@ -578,7 +461,6 @@ void rt_shaded1col (int hx, int sx, int yl, int yh)
source += 4;
dest += pitch;
} while (--count);
#endif
}
// Shades all four spans to the screen starting at sx.
@ -600,32 +482,6 @@ void rt_shaded4cols_c (int sx, int yl, int yh)
source = &dc_temp[yl*4];
pitch = dc_pitch;
#ifndef PALETTEOUTPUT
uint32_t fg = shade_pal_index(dc_color, calc_light_multiplier(0));
uint32_t fg_red = (fg >> 16) & 0xff;
uint32_t fg_green = (fg >> 8) & 0xff;
uint32_t fg_blue = fg & 0xff;
do {
for (int i = 0; i < 4; i++)
{
uint32_t alpha = colormap[source[i]];
uint32_t inv_alpha = 64 - alpha;
uint32_t bg_red = (dest[i] >> 16) & 0xff;
uint32_t bg_green = (dest[i] >> 8) & 0xff;
uint32_t bg_blue = (dest[i]) & 0xff;
uint32_t red = (fg_red * alpha + bg_red * inv_alpha) / 64;
uint32_t green = (fg_green * alpha + bg_green * inv_alpha) / 64;
uint32_t blue = (fg_blue * alpha + bg_blue * inv_alpha) / 64;
dest[i] = 0xff000000 | (red << 16) | (green << 8) | blue;
}
source += 4;
dest += pitch;
} while (--count);
#else
DWORD *fgstart;
fgstart = &Col2RGB8[0][dc_color];
@ -651,11 +507,10 @@ void rt_shaded4cols_c (int sx, int yl, int yh)
source += 4;
dest += pitch;
} while (--count);
#endif
}
// Adds one span at hx to the screen at sx with clamping.
void rt_addclamp1col (int hx, int sx, int yl, int yh)
void rt_addclamp1col_c (int hx, int sx, int yl, int yh)
{
BYTE *colormap;
canvas_pixel_t *source;
@ -673,28 +528,6 @@ void rt_addclamp1col (int hx, int sx, int yl, int yh)
pitch = dc_pitch;
colormap = dc_colormap;
#ifndef PALETTEOUTPUT
uint32_t light = calc_light_multiplier(dc_light);
do {
uint32_t fg = shade_pal_index(colormap[*source], light);
uint32_t fg_red = (fg >> 16) & 0xff;
uint32_t fg_green = (fg >> 8) & 0xff;
uint32_t fg_blue = fg & 0xff;
uint32_t bg_red = (*dest >> 16) & 0xff;
uint32_t bg_green = (*dest >> 8) & 0xff;
uint32_t bg_blue = (*dest) & 0xff;
uint32_t red = clamp<uint32_t>(fg_red + bg_red, 0, 255);
uint32_t green = clamp<uint32_t>(fg_green + bg_green, 0, 255);
uint32_t blue = clamp<uint32_t>(fg_blue + bg_blue, 0, 255);
*dest = 0xff000000 | (red << 16) | (green << 8) | blue;
source += 4;
dest += pitch;
} while (--count);
#else
DWORD *fg2rgb = dc_srcblend;
DWORD *bg2rgb = dc_destblend;
@ -711,7 +544,6 @@ void rt_addclamp1col (int hx, int sx, int yl, int yh)
source += 4;
dest += pitch;
} while (--count);
#endif
}
// Adds all four spans to the screen starting at sx with clamping.
@ -733,31 +565,6 @@ void rt_addclamp4cols_c (int sx, int yl, int yh)
pitch = dc_pitch;
colormap = dc_colormap;
#ifndef PALETTEOUTPUT
uint32_t light = calc_light_multiplier(dc_light);
do {
for (int i = 0; i < 4; i++)
{
uint32_t fg = shade_pal_index(colormap[source[i]], light);
uint32_t fg_red = (fg >> 16) & 0xff;
uint32_t fg_green = (fg >> 8) & 0xff;
uint32_t fg_blue = fg & 0xff;
uint32_t bg_red = (dest[i] >> 16) & 0xff;
uint32_t bg_green = (dest[i] >> 8) & 0xff;
uint32_t bg_blue = (dest[i]) & 0xff;
uint32_t red = clamp<uint32_t>(fg_red + bg_red, 0, 255);
uint32_t green = clamp<uint32_t>(fg_green + bg_green, 0, 255);
uint32_t blue = clamp<uint32_t>(fg_blue + bg_blue, 0, 255);
dest[i] = 0xff000000 | (red << 16) | (green << 8) | blue;
}
source += 4;
dest += pitch;
} while (--count);
#else
DWORD *fg2rgb = dc_srcblend;
DWORD *bg2rgb = dc_destblend;
@ -802,25 +609,24 @@ void rt_addclamp4cols_c (int sx, int yl, int yh)
source += 4;
dest += pitch;
} while (--count);
#endif
}
// Translates and adds one span at hx to the screen at sx with clamping.
void rt_tlateaddclamp1col (int hx, int sx, int yl, int yh)
void rt_tlateaddclamp1col_c (int hx, int sx, int yl, int yh)
{
rt_Translate1col(dc_translation, hx, yl, yh);
rt_addclamp1col(hx, sx, yl, yh);
}
// Translates and adds all four spans to the screen starting at sx with clamping.
void rt_tlateaddclamp4cols (int sx, int yl, int yh)
void rt_tlateaddclamp4cols_c (int sx, int yl, int yh)
{
rt_Translate4cols(dc_translation, yl, yh);
rt_addclamp4cols(sx, yl, yh);
}
// Subtracts one span at hx to the screen at sx with clamping.
void rt_subclamp1col (int hx, int sx, int yl, int yh)
void rt_subclamp1col_c (int hx, int sx, int yl, int yh)
{
BYTE *colormap;
canvas_pixel_t *source;
@ -838,28 +644,6 @@ void rt_subclamp1col (int hx, int sx, int yl, int yh)
pitch = dc_pitch;
colormap = dc_colormap;
#ifndef PALETTEOUTPUT
uint32_t light = calc_light_multiplier(dc_light);
do {
uint32_t fg = shade_pal_index(colormap[*source], light);
uint32_t fg_red = (fg >> 16) & 0xff;
uint32_t fg_green = (fg >> 8) & 0xff;
uint32_t fg_blue = fg & 0xff;
uint32_t bg_red = (*dest >> 16) & 0xff;
uint32_t bg_green = (*dest >> 8) & 0xff;
uint32_t bg_blue = (*dest) & 0xff;
uint32_t red = clamp<uint32_t>(256 - fg_red + bg_red, 256, 256 + 255) - 256;
uint32_t green = clamp<uint32_t>(256 - fg_green + bg_green, 256, 256 + 255) - 256;
uint32_t blue = clamp<uint32_t>(256 - fg_blue + bg_blue, 256, 256 + 255) - 256;
*dest = 0xff000000 | (red << 16) | (green << 8) | blue;
source += 4;
dest += pitch;
} while (--count);
#else
DWORD *fg2rgb = dc_srcblend;
DWORD *bg2rgb = dc_destblend;
do {
@ -874,11 +658,10 @@ void rt_subclamp1col (int hx, int sx, int yl, int yh)
source += 4;
dest += pitch;
} while (--count);
#endif
}
// Subtracts all four spans to the screen starting at sx with clamping.
void rt_subclamp4cols (int sx, int yl, int yh)
void rt_subclamp4cols_c (int sx, int yl, int yh)
{
BYTE *colormap;
canvas_pixel_t *source;
@ -896,32 +679,6 @@ void rt_subclamp4cols (int sx, int yl, int yh)
pitch = dc_pitch;
colormap = dc_colormap;
#ifndef PALETTEOUTPUT
uint32_t light = calc_light_multiplier(dc_light);
do {
for (int i = 0; i < 4; i++)
{
uint32_t fg = shade_pal_index(colormap[source[i]], light);
uint32_t fg_red = (fg >> 16) & 0xff;
uint32_t fg_green = (fg >> 8) & 0xff;
uint32_t fg_blue = fg & 0xff;
uint32_t bg_red = (dest[i] >> 16) & 0xff;
uint32_t bg_green = (dest[i] >> 8) & 0xff;
uint32_t bg_blue = (dest[i]) & 0xff;
uint32_t red = clamp<uint32_t>(256 - fg_red + bg_red, 256, 256 + 255) - 256;
uint32_t green = clamp<uint32_t>(256 - fg_green + bg_green, 256, 256 + 255) - 256;
uint32_t blue = clamp<uint32_t>(256 - fg_blue + bg_blue, 256, 256 + 255) - 256;
dest[i] = 0xff000000 | (red << 16) | (green << 8) | blue;
}
source += 4;
dest += pitch;
} while (--count);
#else
DWORD *fg2rgb = dc_srcblend;
DWORD *bg2rgb = dc_destblend;
do {
@ -961,25 +718,24 @@ void rt_subclamp4cols (int sx, int yl, int yh)
source += 4;
dest += pitch;
} while (--count);
#endif
}
// Translates and subtracts one span at hx to the screen at sx with clamping.
void rt_tlatesubclamp1col (int hx, int sx, int yl, int yh)
void rt_tlatesubclamp1col_c (int hx, int sx, int yl, int yh)
{
rt_Translate1col(dc_translation, hx, yl, yh);
rt_subclamp1col(hx, sx, yl, yh);
}
// Translates and subtracts all four spans to the screen starting at sx with clamping.
void rt_tlatesubclamp4cols (int sx, int yl, int yh)
void rt_tlatesubclamp4cols_c (int sx, int yl, int yh)
{
rt_Translate4cols(dc_translation, yl, yh);
rt_subclamp4cols(sx, yl, yh);
}
// Subtracts one span at hx from the screen at sx with clamping.
void rt_revsubclamp1col (int hx, int sx, int yl, int yh)
void rt_revsubclamp1col_c (int hx, int sx, int yl, int yh)
{
BYTE *colormap;
canvas_pixel_t *source;
@ -999,28 +755,6 @@ void rt_revsubclamp1col (int hx, int sx, int yl, int yh)
pitch = dc_pitch;
colormap = dc_colormap;
#ifndef PALETTEOUTPUT
uint32_t light = calc_light_multiplier(dc_light);
do {
uint32_t fg = shade_pal_index(colormap[*source], light);
uint32_t fg_red = (fg >> 16) & 0xff;
uint32_t fg_green = (fg >> 8) & 0xff;
uint32_t fg_blue = fg & 0xff;
uint32_t bg_red = (*dest >> 16) & 0xff;
uint32_t bg_green = (*dest >> 8) & 0xff;
uint32_t bg_blue = (*dest) & 0xff;
uint32_t red = clamp<uint32_t>(256 + fg_red - bg_red, 256, 256 + 255) - 256;
uint32_t green = clamp<uint32_t>(256 + fg_green - bg_green, 256, 256 + 255) - 256;
uint32_t blue = clamp<uint32_t>(256 + fg_blue - bg_blue, 256, 256 + 255) - 256;
*dest = 0xff000000 | (red << 16) | (green << 8) | blue;
source += 4;
dest += pitch;
} while (--count);
#else
do {
DWORD a = (bg2rgb[*dest] | 0x40100400) - fg2rgb[colormap[*source]];
DWORD b = a;
@ -1033,11 +767,10 @@ void rt_revsubclamp1col (int hx, int sx, int yl, int yh)
source += 4;
dest += pitch;
} while (--count);
#endif
}
// Subtracts all four spans from the screen starting at sx with clamping.
void rt_revsubclamp4cols (int sx, int yl, int yh)
void rt_revsubclamp4cols_c (int sx, int yl, int yh)
{
BYTE *colormap;
canvas_pixel_t *source;
@ -1057,32 +790,6 @@ void rt_revsubclamp4cols (int sx, int yl, int yh)
pitch = dc_pitch;
colormap = dc_colormap;
#ifndef PALETTEOUTPUT
uint32_t light = calc_light_multiplier(dc_light);
do {
for (int i = 0; i < 4; i++)
{
uint32_t fg = shade_pal_index(colormap[source[i]], light);
uint32_t fg_red = (fg >> 16) & 0xff;
uint32_t fg_green = (fg >> 8) & 0xff;
uint32_t fg_blue = fg & 0xff;
uint32_t bg_red = (dest[i] >> 16) & 0xff;
uint32_t bg_green = (dest[i] >> 8) & 0xff;
uint32_t bg_blue = (dest[i]) & 0xff;
uint32_t red = clamp<uint32_t>(256 + fg_red - bg_red, 256, 256 + 255) - 256;
uint32_t green = clamp<uint32_t>(256 + fg_green - bg_green, 256, 256 + 255) - 256;
uint32_t blue = clamp<uint32_t>(256 + fg_blue - bg_blue, 256, 256 + 255) - 256;
dest[i] = 0xff000000 | (red << 16) | (green << 8) | blue;
}
source += 4;
dest += pitch;
} while (--count);
#else
do {
DWORD a = (bg2rgb[dest[0]] | 0x40100400) - fg2rgb[colormap[source[0]]];
DWORD b = a;
@ -1120,18 +827,17 @@ void rt_revsubclamp4cols (int sx, int yl, int yh)
source += 4;
dest += pitch;
} while (--count);
#endif
}
// Translates and subtracts one span at hx from the screen at sx with clamping.
void rt_tlaterevsubclamp1col (int hx, int sx, int yl, int yh)
void rt_tlaterevsubclamp1col_c (int hx, int sx, int yl, int yh)
{
rt_Translate1col(dc_translation, hx, yl, yh);
rt_revsubclamp1col(hx, sx, yl, yh);
}
// Translates and subtracts all four spans from the screen starting at sx with clamping.
void rt_tlaterevsubclamp4cols (int sx, int yl, int yh)
void rt_tlaterevsubclamp4cols_c (int sx, int yl, int yh)
{
rt_Translate4cols(dc_translation, yl, yh);
rt_revsubclamp4cols(sx, yl, yh);
@ -1301,7 +1007,7 @@ void rt_draw4cols (int sx)
// Before each pass through a rendering loop that uses these routines,
// call this function to set up the span pointers.
void rt_initcols (canvas_pixel_t *buff)
void rt_initcols_pal (canvas_pixel_t *buff)
{
int y;
@ -1372,7 +1078,7 @@ void R_DrawColumnHorizP_C (void)
}
// [RH] Just fills a column with a given color
void R_FillColumnHorizP (void)
void R_FillColumnHorizP_C (void)
{
int count = dc_count;
BYTE color = dc_color;

883
src/r_drawt_rgba.cpp Normal file
View file

@ -0,0 +1,883 @@
/*
** r_drawt_rgba.cpp
** Faster column drawers for modern processors, true color edition
**
**---------------------------------------------------------------------------
** Copyright 1998-2006 Randy Heit
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
**
** 1. Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** 3. The name of the author may not be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**---------------------------------------------------------------------------
**
** True color versions of the similar functions in r_drawt.cpp
** Please see r_drawt.cpp for a description of the globals used.
*/
#include "templates.h"
#include "doomtype.h"
#include "doomdef.h"
#include "r_defs.h"
#include "r_draw.h"
#include "r_main.h"
#include "r_things.h"
#include "v_video.h"
canvas_pixel_t dc_temp_rgbabuff_rgba[MAXHEIGHT*4];
canvas_pixel_t *dc_temp_rgba;
// Defined in r_draw_t.cpp:
extern unsigned int dc_tspans[4][MAXHEIGHT];
extern unsigned int *dc_ctspan[4];
extern unsigned int *horizspan[4];
// Copies one span at hx to the screen at sx.
void rt_copy1col_RGBA_c (int hx, int sx, int yl, int yh)
{
canvas_pixel_t *source;
canvas_pixel_t *dest;
int count;
int pitch;
count = yh-yl;
if (count < 0)
return;
count++;
dest = ylookup[yl] + sx + dc_destorg;
source = &dc_temp_rgba[yl*4 + hx];
pitch = dc_pitch;
if (count & 1) {
*dest = *source;
source += 4;
dest += pitch;
}
if (count & 2) {
dest[0] = source[0];
dest[pitch] = source[4];
source += 8;
dest += pitch*2;
}
if (!(count >>= 2))
return;
do {
dest[0] = source[0];
dest[pitch] = source[4];
dest[pitch*2] = source[8];
dest[pitch*3] = source[12];
source += 16;
dest += pitch*4;
} while (--count);
}
// Copies all four spans to the screen starting at sx.
void rt_copy4cols_RGBA_c (int sx, int yl, int yh)
{
// To do: we could do this with SSE using __m128i
rt_copy1col_RGBA_c(0, sx, yl, yh);
rt_copy1col_RGBA_c(1, sx + 1, yl, yh);
rt_copy1col_RGBA_c(2, sx + 2, yl, yh);
rt_copy1col_RGBA_c(3, sx + 3, yl, yh);
}
// Maps one span at hx to the screen at sx.
void rt_map1col_RGBA_c (int hx, int sx, int yl, int yh)
{
BYTE *colormap;
canvas_pixel_t *source;
canvas_pixel_t *dest;
int count;
int pitch;
count = yh-yl;
if (count < 0)
return;
count++;
uint32_t light = calc_light_multiplier(dc_light);
colormap = dc_colormap;
dest = ylookup[yl] + sx + dc_destorg;
source = &dc_temp_rgba[yl*4 + hx];
pitch = dc_pitch;
if (count & 1) {
*dest = shade_pal_index(colormap[*source], light);
source += 4;
dest += pitch;
}
if (!(count >>= 1))
return;
do {
dest[0] = shade_pal_index(colormap[source[0]], light);
dest[pitch] = shade_pal_index(colormap[source[4]], light);
source += 8;
dest += pitch*2;
} while (--count);
}
// Maps all four spans to the screen starting at sx.
void rt_map4cols_RGBA_c (int sx, int yl, int yh)
{
BYTE *colormap;
canvas_pixel_t *source;
canvas_pixel_t *dest;
int count;
int pitch;
count = yh-yl;
if (count < 0)
return;
count++;
uint32_t light = calc_light_multiplier(dc_light);
colormap = dc_colormap;
dest = ylookup[yl] + sx + dc_destorg;
source = &dc_temp_rgba[yl*4];
pitch = dc_pitch;
if (count & 1) {
dest[0] = shade_pal_index(colormap[source[0]], light);
dest[1] = shade_pal_index(colormap[source[1]], light);
dest[2] = shade_pal_index(colormap[source[2]], light);
dest[3] = shade_pal_index(colormap[source[3]], light);
source += 4;
dest += pitch;
}
if (!(count >>= 1))
return;
do {
dest[0] = shade_pal_index(colormap[source[0]], light);
dest[1] = shade_pal_index(colormap[source[1]], light);
dest[2] = shade_pal_index(colormap[source[2]], light);
dest[3] = shade_pal_index(colormap[source[3]], light);
dest[pitch] = shade_pal_index(colormap[source[4]], light);
dest[pitch + 1] = shade_pal_index(colormap[source[5]], light);
dest[pitch + 2] = shade_pal_index(colormap[source[6]], light);
dest[pitch + 3] = shade_pal_index(colormap[source[7]], light);
source += 8;
dest += pitch*2;
} while (--count);
}
void rt_Translate1col_RGBA_c(const BYTE *translation, int hx, int yl, int yh)
{
int count = yh - yl + 1;
canvas_pixel_t *source = &dc_temp_rgba[yl*4 + hx];
// Things we do to hit the compiler's optimizer with a clue bat:
// 1. Parallelism is explicitly spelled out by using a separate
// C instruction for each assembly instruction. GCC lets me
// have four temporaries, but VC++ spills to the stack with
// more than two. Two is probably optimal, anyway.
// 2. The results of the translation lookups are explicitly
// stored in byte-sized variables. This causes the VC++ code
// to use byte mov instructions in most cases; for apparently
// random reasons, it will use movzx for some places. GCC
// ignores this and uses movzx always.
// Do 8 rows at a time.
for (int count8 = count >> 3; count8; --count8)
{
int c0, c1;
BYTE b0, b1;
c0 = source[0]; c1 = source[4];
b0 = translation[c0]; b1 = translation[c1];
source[0] = b0; source[4] = b1;
c0 = source[8]; c1 = source[12];
b0 = translation[c0]; b1 = translation[c1];
source[8] = b0; source[12] = b1;
c0 = source[16]; c1 = source[20];
b0 = translation[c0]; b1 = translation[c1];
source[16] = b0; source[20] = b1;
c0 = source[24]; c1 = source[28];
b0 = translation[c0]; b1 = translation[c1];
source[24] = b0; source[28] = b1;
source += 32;
}
// Finish by doing 1 row at a time.
for (count &= 7; count; --count, source += 4)
{
source[0] = translation[source[0]];
}
}
void rt_Translate4cols_RGBA_c(const BYTE *translation, int yl, int yh)
{
int count = yh - yl + 1;
canvas_pixel_t *source = &dc_temp_rgba[yl*4];
int c0, c1;
BYTE b0, b1;
// Do 2 rows at a time.
for (int count8 = count >> 1; count8; --count8)
{
c0 = source[0]; c1 = source[1];
b0 = translation[c0]; b1 = translation[c1];
source[0] = b0; source[1] = b1;
c0 = source[2]; c1 = source[3];
b0 = translation[c0]; b1 = translation[c1];
source[2] = b0; source[3] = b1;
c0 = source[4]; c1 = source[5];
b0 = translation[c0]; b1 = translation[c1];
source[4] = b0; source[5] = b1;
c0 = source[6]; c1 = source[7];
b0 = translation[c0]; b1 = translation[c1];
source[6] = b0; source[7] = b1;
source += 8;
}
// Do the final row if count was odd.
if (count & 1)
{
c0 = source[0]; c1 = source[1];
b0 = translation[c0]; b1 = translation[c1];
source[0] = b0; source[1] = b1;
c0 = source[2]; c1 = source[3];
b0 = translation[c0]; b1 = translation[c1];
source[2] = b0; source[3] = b1;
}
}
// Translates one span at hx to the screen at sx.
void rt_tlate1col_RGBA_c (int hx, int sx, int yl, int yh)
{
rt_Translate1col_RGBA_c(dc_translation, hx, yl, yh);
rt_map1col(hx, sx, yl, yh);
}
// Translates all four spans to the screen starting at sx.
void rt_tlate4cols_RGBA_c (int sx, int yl, int yh)
{
rt_Translate4cols_RGBA_c(dc_translation, yl, yh);
rt_map4cols(sx, yl, yh);
}
// Adds one span at hx to the screen at sx without clamping.
void rt_add1col_RGBA_c (int hx, int sx, int yl, int yh)
{
BYTE *colormap;
canvas_pixel_t *source;
canvas_pixel_t *dest;
int count;
int pitch;
count = yh-yl;
if (count < 0)
return;
count++;
dest = ylookup[yl] + sx + dc_destorg;
source = &dc_temp_rgba[yl*4 + hx];
pitch = dc_pitch;
colormap = dc_colormap;
uint32_t light = calc_light_multiplier(dc_light);
do {
uint32_t fg = shade_pal_index(colormap[*source], light);
uint32_t fg_red = (fg >> 16) & 0xff;
uint32_t fg_green = (fg >> 8) & 0xff;
uint32_t fg_blue = fg & 0xff;
uint32_t bg_red = (*dest >> 16) & 0xff;
uint32_t bg_green = (*dest >> 8) & 0xff;
uint32_t bg_blue = (*dest) & 0xff;
uint32_t red = clamp<uint32_t>(fg_red + bg_red, 0, 255);
uint32_t green = clamp<uint32_t>(fg_green + bg_green, 0, 255);
uint32_t blue = clamp<uint32_t>(fg_blue + bg_blue, 0, 255);
*dest = 0xff000000 | (red << 16) | (green << 8) | blue;
source += 4;
dest += pitch;
} while (--count);
}
// Adds all four spans to the screen starting at sx without clamping.
void rt_add4cols_RGBA_c (int sx, int yl, int yh)
{
BYTE *colormap;
canvas_pixel_t *source;
canvas_pixel_t *dest;
int count;
int pitch;
count = yh-yl;
if (count < 0)
return;
count++;
dest = ylookup[yl] + sx + dc_destorg;
source = &dc_temp_rgba[yl*4];
pitch = dc_pitch;
colormap = dc_colormap;
uint32_t light = calc_light_multiplier(dc_light);
do {
for (int i = 0; i < 4; i++)
{
uint32_t fg = shade_pal_index(colormap[source[i]], light);
uint32_t fg_red = (fg >> 16) & 0xff;
uint32_t fg_green = (fg >> 8) & 0xff;
uint32_t fg_blue = fg & 0xff;
uint32_t bg_red = (dest[i] >> 16) & 0xff;
uint32_t bg_green = (dest[i] >> 8) & 0xff;
uint32_t bg_blue = (dest[i]) & 0xff;
uint32_t red = clamp<uint32_t>(fg_red + bg_red, 0, 255);
uint32_t green = clamp<uint32_t>(fg_green + bg_green, 0, 255);
uint32_t blue = clamp<uint32_t>(fg_blue + bg_blue, 0, 255);
dest[i] = 0xff000000 | (red << 16) | (green << 8) | blue;
}
source += 4;
dest += pitch;
} while (--count);
}
// Translates and adds one span at hx to the screen at sx without clamping.
void rt_tlateadd1col_RGBA_c (int hx, int sx, int yl, int yh)
{
rt_Translate1col_RGBA_c(dc_translation, hx, yl, yh);
rt_add1col(hx, sx, yl, yh);
}
// Translates and adds all four spans to the screen starting at sx without clamping.
void rt_tlateadd4cols_RGBA_c(int sx, int yl, int yh)
{
rt_Translate4cols_RGBA_c(dc_translation, yl, yh);
rt_add4cols(sx, yl, yh);
}
// Shades one span at hx to the screen at sx.
void rt_shaded1col_RGBA_c (int hx, int sx, int yl, int yh)
{
BYTE *colormap;
canvas_pixel_t *source;
canvas_pixel_t *dest;
int count;
int pitch;
count = yh-yl;
if (count < 0)
return;
count++;
colormap = dc_colormap;
dest = ylookup[yl] + sx + dc_destorg;
source = &dc_temp_rgba[yl*4 + hx];
pitch = dc_pitch;
uint32_t fg = shade_pal_index(dc_color, calc_light_multiplier(0));
uint32_t fg_red = (fg >> 16) & 0xff;
uint32_t fg_green = (fg >> 8) & 0xff;
uint32_t fg_blue = fg & 0xff;
do {
uint32_t alpha = colormap[*source];
uint32_t inv_alpha = 64 - alpha;
uint32_t bg_red = (*dest >> 16) & 0xff;
uint32_t bg_green = (*dest >> 8) & 0xff;
uint32_t bg_blue = (*dest) & 0xff;
uint32_t red = (fg_red * alpha + bg_red * inv_alpha) / 64;
uint32_t green = (fg_green * alpha + bg_green * inv_alpha) / 64;
uint32_t blue = (fg_blue * alpha + bg_blue * inv_alpha) / 64;
*dest = 0xff000000 | (red << 16) | (green << 8) | blue;
source += 4;
dest += pitch;
} while (--count);
}
// Shades all four spans to the screen starting at sx.
void rt_shaded4cols_RGBA_c (int sx, int yl, int yh)
{
BYTE *colormap;
canvas_pixel_t *source;
canvas_pixel_t *dest;
int count;
int pitch;
count = yh-yl;
if (count < 0)
return;
count++;
colormap = dc_colormap;
dest = ylookup[yl] + sx + dc_destorg;
source = &dc_temp_rgba[yl*4];
pitch = dc_pitch;
uint32_t fg = shade_pal_index(dc_color, calc_light_multiplier(0));
uint32_t fg_red = (fg >> 16) & 0xff;
uint32_t fg_green = (fg >> 8) & 0xff;
uint32_t fg_blue = fg & 0xff;
do {
for (int i = 0; i < 4; i++)
{
uint32_t alpha = colormap[source[i]];
uint32_t inv_alpha = 64 - alpha;
uint32_t bg_red = (dest[i] >> 16) & 0xff;
uint32_t bg_green = (dest[i] >> 8) & 0xff;
uint32_t bg_blue = (dest[i]) & 0xff;
uint32_t red = (fg_red * alpha + bg_red * inv_alpha) / 64;
uint32_t green = (fg_green * alpha + bg_green * inv_alpha) / 64;
uint32_t blue = (fg_blue * alpha + bg_blue * inv_alpha) / 64;
dest[i] = 0xff000000 | (red << 16) | (green << 8) | blue;
}
source += 4;
dest += pitch;
} while (--count);
}
// Adds one span at hx to the screen at sx with clamping.
void rt_addclamp1col_RGBA_c (int hx, int sx, int yl, int yh)
{
BYTE *colormap;
canvas_pixel_t *source;
canvas_pixel_t *dest;
int count;
int pitch;
count = yh-yl;
if (count < 0)
return;
count++;
dest = ylookup[yl] + sx + dc_destorg;
source = &dc_temp_rgba[yl*4 + hx];
pitch = dc_pitch;
colormap = dc_colormap;
uint32_t light = calc_light_multiplier(dc_light);
do {
uint32_t fg = shade_pal_index(colormap[*source], light);
uint32_t fg_red = (fg >> 16) & 0xff;
uint32_t fg_green = (fg >> 8) & 0xff;
uint32_t fg_blue = fg & 0xff;
uint32_t bg_red = (*dest >> 16) & 0xff;
uint32_t bg_green = (*dest >> 8) & 0xff;
uint32_t bg_blue = (*dest) & 0xff;
uint32_t red = clamp<uint32_t>(fg_red + bg_red, 0, 255);
uint32_t green = clamp<uint32_t>(fg_green + bg_green, 0, 255);
uint32_t blue = clamp<uint32_t>(fg_blue + bg_blue, 0, 255);
*dest = 0xff000000 | (red << 16) | (green << 8) | blue;
source += 4;
dest += pitch;
} while (--count);
}
// Adds all four spans to the screen starting at sx with clamping.
void rt_addclamp4cols_RGBA_c (int sx, int yl, int yh)
{
BYTE *colormap;
canvas_pixel_t *source;
canvas_pixel_t *dest;
int count;
int pitch;
count = yh-yl;
if (count < 0)
return;
count++;
dest = ylookup[yl] + sx + dc_destorg;
source = &dc_temp_rgba[yl*4];
pitch = dc_pitch;
colormap = dc_colormap;
uint32_t light = calc_light_multiplier(dc_light);
do {
for (int i = 0; i < 4; i++)
{
uint32_t fg = shade_pal_index(colormap[source[i]], light);
uint32_t fg_red = (fg >> 16) & 0xff;
uint32_t fg_green = (fg >> 8) & 0xff;
uint32_t fg_blue = fg & 0xff;
uint32_t bg_red = (dest[i] >> 16) & 0xff;
uint32_t bg_green = (dest[i] >> 8) & 0xff;
uint32_t bg_blue = (dest[i]) & 0xff;
uint32_t red = clamp<uint32_t>(fg_red + bg_red, 0, 255);
uint32_t green = clamp<uint32_t>(fg_green + bg_green, 0, 255);
uint32_t blue = clamp<uint32_t>(fg_blue + bg_blue, 0, 255);
dest[i] = 0xff000000 | (red << 16) | (green << 8) | blue;
}
source += 4;
dest += pitch;
} while (--count);
}
// Translates and adds one span at hx to the screen at sx with clamping.
void rt_tlateaddclamp1col_RGBA_c (int hx, int sx, int yl, int yh)
{
rt_Translate1col_RGBA_c(dc_translation, hx, yl, yh);
rt_addclamp1col_RGBA_c(hx, sx, yl, yh);
}
// Translates and adds all four spans to the screen starting at sx with clamping.
void rt_tlateaddclamp4cols_RGBA_c (int sx, int yl, int yh)
{
rt_Translate4cols_RGBA_c(dc_translation, yl, yh);
rt_addclamp4cols(sx, yl, yh);
}
// Subtracts one span at hx to the screen at sx with clamping.
void rt_subclamp1col_RGBA_c (int hx, int sx, int yl, int yh)
{
BYTE *colormap;
canvas_pixel_t *source;
canvas_pixel_t *dest;
int count;
int pitch;
count = yh-yl;
if (count < 0)
return;
count++;
dest = ylookup[yl] + sx + dc_destorg;
source = &dc_temp_rgba[yl*4 + hx];
pitch = dc_pitch;
colormap = dc_colormap;
uint32_t light = calc_light_multiplier(dc_light);
do {
uint32_t fg = shade_pal_index(colormap[*source], light);
uint32_t fg_red = (fg >> 16) & 0xff;
uint32_t fg_green = (fg >> 8) & 0xff;
uint32_t fg_blue = fg & 0xff;
uint32_t bg_red = (*dest >> 16) & 0xff;
uint32_t bg_green = (*dest >> 8) & 0xff;
uint32_t bg_blue = (*dest) & 0xff;
uint32_t red = clamp<uint32_t>(256 - fg_red + bg_red, 256, 256 + 255) - 256;
uint32_t green = clamp<uint32_t>(256 - fg_green + bg_green, 256, 256 + 255) - 256;
uint32_t blue = clamp<uint32_t>(256 - fg_blue + bg_blue, 256, 256 + 255) - 256;
*dest = 0xff000000 | (red << 16) | (green << 8) | blue;
source += 4;
dest += pitch;
} while (--count);
}
// Subtracts all four spans to the screen starting at sx with clamping.
void rt_subclamp4cols_RGBA_c (int sx, int yl, int yh)
{
BYTE *colormap;
canvas_pixel_t *source;
canvas_pixel_t *dest;
int count;
int pitch;
count = yh-yl;
if (count < 0)
return;
count++;
dest = ylookup[yl] + sx + dc_destorg;
source = &dc_temp_rgba[yl*4];
pitch = dc_pitch;
colormap = dc_colormap;
uint32_t light = calc_light_multiplier(dc_light);
do {
for (int i = 0; i < 4; i++)
{
uint32_t fg = shade_pal_index(colormap[source[i]], light);
uint32_t fg_red = (fg >> 16) & 0xff;
uint32_t fg_green = (fg >> 8) & 0xff;
uint32_t fg_blue = fg & 0xff;
uint32_t bg_red = (dest[i] >> 16) & 0xff;
uint32_t bg_green = (dest[i] >> 8) & 0xff;
uint32_t bg_blue = (dest[i]) & 0xff;
uint32_t red = clamp<uint32_t>(256 - fg_red + bg_red, 256, 256 + 255) - 256;
uint32_t green = clamp<uint32_t>(256 - fg_green + bg_green, 256, 256 + 255) - 256;
uint32_t blue = clamp<uint32_t>(256 - fg_blue + bg_blue, 256, 256 + 255) - 256;
dest[i] = 0xff000000 | (red << 16) | (green << 8) | blue;
}
source += 4;
dest += pitch;
} while (--count);
}
// Translates and subtracts one span at hx to the screen at sx with clamping.
void rt_tlatesubclamp1col_RGBA_c (int hx, int sx, int yl, int yh)
{
rt_Translate1col_RGBA_c(dc_translation, hx, yl, yh);
rt_subclamp1col_RGBA_c(hx, sx, yl, yh);
}
// Translates and subtracts all four spans to the screen starting at sx with clamping.
void rt_tlatesubclamp4cols_RGBA_c (int sx, int yl, int yh)
{
rt_Translate4cols_RGBA_c(dc_translation, yl, yh);
rt_subclamp4cols_RGBA_c(sx, yl, yh);
}
// Subtracts one span at hx from the screen at sx with clamping.
void rt_revsubclamp1col_RGBA_c (int hx, int sx, int yl, int yh)
{
BYTE *colormap;
canvas_pixel_t *source;
canvas_pixel_t *dest;
int count;
int pitch;
count = yh-yl;
if (count < 0)
return;
count++;
DWORD *fg2rgb = dc_srcblend;
DWORD *bg2rgb = dc_destblend;
dest = ylookup[yl] + sx + dc_destorg;
source = &dc_temp_rgba[yl*4 + hx];
pitch = dc_pitch;
colormap = dc_colormap;
uint32_t light = calc_light_multiplier(dc_light);
do {
uint32_t fg = shade_pal_index(colormap[*source], light);
uint32_t fg_red = (fg >> 16) & 0xff;
uint32_t fg_green = (fg >> 8) & 0xff;
uint32_t fg_blue = fg & 0xff;
uint32_t bg_red = (*dest >> 16) & 0xff;
uint32_t bg_green = (*dest >> 8) & 0xff;
uint32_t bg_blue = (*dest) & 0xff;
uint32_t red = clamp<uint32_t>(256 + fg_red - bg_red, 256, 256 + 255) - 256;
uint32_t green = clamp<uint32_t>(256 + fg_green - bg_green, 256, 256 + 255) - 256;
uint32_t blue = clamp<uint32_t>(256 + fg_blue - bg_blue, 256, 256 + 255) - 256;
*dest = 0xff000000 | (red << 16) | (green << 8) | blue;
source += 4;
dest += pitch;
} while (--count);
}
// Subtracts all four spans from the screen starting at sx with clamping.
void rt_revsubclamp4cols_RGBA_c (int sx, int yl, int yh)
{
BYTE *colormap;
canvas_pixel_t *source;
canvas_pixel_t *dest;
int count;
int pitch;
count = yh-yl;
if (count < 0)
return;
count++;
DWORD *fg2rgb = dc_srcblend;
DWORD *bg2rgb = dc_destblend;
dest = ylookup[yl] + sx + dc_destorg;
source = &dc_temp_rgba[yl*4];
pitch = dc_pitch;
colormap = dc_colormap;
uint32_t light = calc_light_multiplier(dc_light);
do {
for (int i = 0; i < 4; i++)
{
uint32_t fg = shade_pal_index(colormap[source[i]], light);
uint32_t fg_red = (fg >> 16) & 0xff;
uint32_t fg_green = (fg >> 8) & 0xff;
uint32_t fg_blue = fg & 0xff;
uint32_t bg_red = (dest[i] >> 16) & 0xff;
uint32_t bg_green = (dest[i] >> 8) & 0xff;
uint32_t bg_blue = (dest[i]) & 0xff;
uint32_t red = clamp<uint32_t>(256 + fg_red - bg_red, 256, 256 + 255) - 256;
uint32_t green = clamp<uint32_t>(256 + fg_green - bg_green, 256, 256 + 255) - 256;
uint32_t blue = clamp<uint32_t>(256 + fg_blue - bg_blue, 256, 256 + 255) - 256;
dest[i] = 0xff000000 | (red << 16) | (green << 8) | blue;
}
source += 4;
dest += pitch;
} while (--count);
}
// Translates and subtracts one span at hx from the screen at sx with clamping.
void rt_tlaterevsubclamp1col_RGBA_c (int hx, int sx, int yl, int yh)
{
rt_Translate1col_RGBA_c(dc_translation, hx, yl, yh);
rt_revsubclamp1col_RGBA_c(hx, sx, yl, yh);
}
// Translates and subtracts all four spans from the screen starting at sx with clamping.
void rt_tlaterevsubclamp4cols_RGBA_c (int sx, int yl, int yh)
{
rt_Translate4cols_RGBA_c(dc_translation, yl, yh);
rt_revsubclamp4cols_RGBA_c(sx, yl, yh);
}
// Before each pass through a rendering loop that uses these routines,
// call this function to set up the span pointers.
void rt_initcols_rgba (canvas_pixel_t *buff)
{
int y;
dc_temp_rgba = buff == NULL ? dc_temp_rgbabuff_rgba : buff;
for (y = 3; y >= 0; y--)
horizspan[y] = dc_ctspan[y] = &dc_tspans[y][0];
}
// Stretches a column into a temporary buffer which is later
// drawn to the screen along with up to three other columns.
void R_DrawColumnHorizP_RGBA_C (void)
{
int count = dc_count;
canvas_pixel_t *dest;
fixed_t fracstep;
fixed_t frac;
if (count <= 0)
return;
{
int x = dc_x & 3;
unsigned int **span;
span = &dc_ctspan[x];
(*span)[0] = dc_yl;
(*span)[1] = dc_yh;
*span += 2;
dest = &dc_temp_rgba[x + 4*dc_yl];
}
fracstep = dc_iscale;
frac = dc_texturefrac;
{
const BYTE *source = dc_source;
if (count & 1) {
*dest = source[frac>>FRACBITS]; dest += 4; frac += fracstep;
}
if (count & 2) {
dest[0] = source[frac>>FRACBITS]; frac += fracstep;
dest[4] = source[frac>>FRACBITS]; frac += fracstep;
dest += 8;
}
if (count & 4) {
dest[0] = source[frac>>FRACBITS]; frac += fracstep;
dest[4] = source[frac>>FRACBITS]; frac += fracstep;
dest[8] = source[frac>>FRACBITS]; frac += fracstep;
dest[12]= source[frac>>FRACBITS]; frac += fracstep;
dest += 16;
}
count >>= 3;
if (!count) return;
do
{
dest[0] = source[frac>>FRACBITS]; frac += fracstep;
dest[4] = source[frac>>FRACBITS]; frac += fracstep;
dest[8] = source[frac>>FRACBITS]; frac += fracstep;
dest[12]= source[frac>>FRACBITS]; frac += fracstep;
dest[16]= source[frac>>FRACBITS]; frac += fracstep;
dest[20]= source[frac>>FRACBITS]; frac += fracstep;
dest[24]= source[frac>>FRACBITS]; frac += fracstep;
dest[28]= source[frac>>FRACBITS]; frac += fracstep;
dest += 32;
} while (--count);
}
}
// [RH] Just fills a column with a given color
void R_FillColumnHorizP_RGBA_C (void)
{
int count = dc_count;
BYTE color = dc_color;
canvas_pixel_t *dest;
if (count <= 0)
return;
{
int x = dc_x & 3;
unsigned int **span = &dc_ctspan[x];
(*span)[0] = dc_yl;
(*span)[1] = dc_yh;
*span += 2;
dest = &dc_temp_rgba[x + 4*dc_yl];
}
if (count & 1) {
*dest = color;
dest += 4;
}
if (!(count >>= 1))
return;
do {
dest[0] = color; dest[4] = color;
dest += 8;
} while (--count);
}

View file

@ -847,10 +847,10 @@ void R_RenderActorView (AActor *actor, bool dontmaplines)
// [RH] Show off segs if r_drawflat is 1
if (r_drawflat)
{
hcolfunc_pre = R_FillColumnHorizP;
hcolfunc_pre = R_FillColumnHoriz;
hcolfunc_post1 = rt_copy1col;
hcolfunc_post4 = rt_copy4cols;
colfunc = R_FillColumnP;
colfunc = R_FillColumn;
spanfunc = R_FillSpan;
}
else

View file

@ -491,18 +491,19 @@ void R_MapTiltedPlane (int y, int x1)
//
//==========================================================================
void R_MapColoredPlane (int y, int x1)
void R_MapColoredPlane_C (int y, int x1)
{
memset (ylookup[y] + x1 + dc_destorg, ds_color, (spanend[y] - x1 + 1));
}
void R_MapColoredPlane_RGBA(int y, int x1)
{
#ifndef PALETTEOUTPUT
canvas_pixel_t *dest = ylookup[y] + x1 + dc_destorg;
int count = (spanend[y] - x1 + 1);
uint32_t light = calc_light_multiplier(ds_light);
uint32_t color = shade_pal_index(ds_color, light);
for (int i = 0; i < count; i++)
dest[i] = color;
#else
memset (ylookup[y] + x1 + dc_destorg, ds_color, (spanend[y] - x1 + 1) * sizeof(canvas_pixel_t));
#endif
}
//==========================================================================

View file

@ -93,6 +93,10 @@ void R_DrawNormalPlane (visplane_t *pl, double xscale, double yscale, fixed_t al
void R_DrawTiltedPlane (visplane_t *pl, double xscale, double yscale, fixed_t alpha, bool additive, bool masked);
void R_MapVisPlane (visplane_t *pl, void (*mapfunc)(int y, int x1));
extern void(*R_MapColoredPlane)(int y, int x1);
void R_MapColoredPlane_C(int y, int x1);
void R_MapColoredPlane_RGBA(int y, int x1);
visplane_t *R_FindPlane
( const secplane_t &height,
FTextureID picnum,

View file

@ -463,7 +463,7 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2)
while (dc_x < stop)
{
rt_initcols();
rt_initcols(nullptr);
BlastMaskedColumn (R_DrawMaskedColumnHoriz, tex); dc_x++;
BlastMaskedColumn (R_DrawMaskedColumnHoriz, tex); dc_x++;
BlastMaskedColumn (R_DrawMaskedColumnHoriz, tex); dc_x++;
@ -3319,7 +3319,7 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper,
dc_light = 0;
#endif
}
rt_initcols();
rt_initcols(nullptr);
for (int zz = 4; zz; --zz)
{
R_WallSpriteColumn (R_DrawMaskedColumnHoriz);

View file

@ -470,7 +470,7 @@ void R_DrawVisSprite (vissprite_t *vis)
while (dc_x < stop4)
{
rt_initcols();
rt_initcols(nullptr);
for (int zz = 4; zz; --zz)
{
pixels = tex->GetColumn (frac >> FRACBITS, &spans);
@ -619,7 +619,7 @@ void R_DrawWallSprite(vissprite_t *spr)
dc_light = FLOAT2FIXED(MAXLIGHTVIS);
#endif
}
rt_initcols();
rt_initcols(nullptr);
for (int zz = 4; zz; --zz)
{
if (!R_ClipSpriteColumnWithPortals(spr))
@ -681,7 +681,7 @@ void R_DrawVisVoxel(vissprite_t *spr, int minslabz, int maxslabz, short *cliptop
{
return;
}
if (colfunc == fuzzcolfunc || colfunc == R_FillColumnP)
if (colfunc == fuzzcolfunc || colfunc == R_FillColumn)
{
flags = DVF_OFFSCREEN | DVF_SPANSONLY;
}
@ -2617,7 +2617,7 @@ static void R_DrawMaskedSegsBehindParticle (const vissprite_t *vis)
}
}
void R_DrawParticle (vissprite_t *vis)
void R_DrawParticle_C (vissprite_t *vis)
{
int spacing;
canvas_pixel_t *dest;
@ -2629,44 +2629,6 @@ void R_DrawParticle (vissprite_t *vis)
R_DrawMaskedSegsBehindParticle (vis);
#ifndef PALETTEOUTPUT
uint32_t fg = shade_pal_index(color, calc_light_multiplier(0));
uint32_t fg_red = (fg >> 16) & 0xff;
uint32_t fg_green = (fg >> 8) & 0xff;
uint32_t fg_blue = fg & 0xff;
// vis->renderflags holds translucency level (0-255)
fixed_t fglevel = ((vis->renderflags + 1) << 8) & ~0x3ff;
uint32_t alpha = fglevel * 256 / FRACUNIT;
uint32_t inv_alpha = 256 - alpha;
fg_red *= alpha;
fg_green *= alpha;
fg_blue *= alpha;
spacing = RenderTarget->GetPitch();
for (int x = x1; x < (x1 + countbase); x++)
{
dc_x = x;
if (R_ClipSpriteColumnWithPortals(vis))
continue;
dest = ylookup[yl] + x + dc_destorg;
for (int y = 0; y < ycount; y++)
{
uint32_t bg_red = (*dest >> 16) & 0xff;
uint32_t bg_green = (*dest >> 8) & 0xff;
uint32_t bg_blue = (*dest) & 0xff;
uint32_t red = (fg_red + bg_red * alpha) / 256;
uint32_t green = (fg_green + bg_green * alpha) / 256;
uint32_t blue = (fg_blue + bg_blue * alpha) / 256;
*dest = 0xff000000 | (red << 16) | (green << 8) | blue;
dest += spacing;
}
}
#else
DWORD *bg2rgb;
DWORD fg;
@ -2719,7 +2681,56 @@ void R_DrawParticle (vissprite_t *vis)
dest += spacing;
}
}
#endif
}
void R_DrawParticle_RGBA(vissprite_t *vis)
{
int spacing;
canvas_pixel_t *dest;
BYTE color = vis->Style.colormap[vis->startfrac];
int yl = vis->y1;
int ycount = vis->y2 - yl + 1;
int x1 = vis->x1;
int countbase = vis->x2 - x1;
R_DrawMaskedSegsBehindParticle(vis);
uint32_t fg = shade_pal_index(color, calc_light_multiplier(0));
uint32_t fg_red = (fg >> 16) & 0xff;
uint32_t fg_green = (fg >> 8) & 0xff;
uint32_t fg_blue = fg & 0xff;
// vis->renderflags holds translucency level (0-255)
fixed_t fglevel = ((vis->renderflags + 1) << 8) & ~0x3ff;
uint32_t alpha = fglevel * 256 / FRACUNIT;
uint32_t inv_alpha = 256 - alpha;
fg_red *= alpha;
fg_green *= alpha;
fg_blue *= alpha;
spacing = RenderTarget->GetPitch();
for (int x = x1; x < (x1 + countbase); x++)
{
dc_x = x;
if (R_ClipSpriteColumnWithPortals(vis))
continue;
dest = ylookup[yl] + x + dc_destorg;
for (int y = 0; y < ycount; y++)
{
uint32_t bg_red = (*dest >> 16) & 0xff;
uint32_t bg_green = (*dest >> 8) & 0xff;
uint32_t bg_blue = (*dest) & 0xff;
uint32_t red = (fg_red + bg_red * alpha) / 256;
uint32_t green = (fg_green + bg_green * alpha) / 256;
uint32_t blue = (fg_blue + bg_blue * alpha) / 256;
*dest = 0xff000000 | (red << 16) | (green << 8) | blue;
dest += spacing;
}
}
}
extern double BaseYaspectMul;;

View file

@ -97,7 +97,10 @@ struct vissprite_t
struct particle_t;
void R_DrawParticle (vissprite_t *);
extern void(*R_DrawParticle)(vissprite_t *);
void R_DrawParticle_C (vissprite_t *);
void R_DrawParticle_RGBA (vissprite_t *);
void R_ProjectParticle (particle_t *, const sector_t *sector, int shade, int fakeside);
extern int MaxVisSprites;

View file

@ -300,7 +300,7 @@ void DCanvas::DrawTextureParms(FTexture *img, DrawParms &parms)
while (dc_x < stop4)
{
rt_initcols();
rt_initcols(nullptr);
for (int zz = 4; zz; --zz)
{
pixels = img->GetColumn(frac >> FRACBITS, spanptr);