diff --git a/src/basictypes.h b/src/basictypes.h index ff2cd972e..45e33a4a7 100644 --- a/src/basictypes.h +++ b/src/basictypes.h @@ -66,6 +66,12 @@ union QWORD_UNION typedef SDWORD fixed_t; typedef DWORD dsfixed_t; // fixedpt used by span drawer +#ifndef PALETTEOUTPUT +typedef uint32_t canvas_pixel_t; +#else +typedef BYTE canvas_pixel_t; +#endif + #define FIXED_MAX (signed)(0x7fffffff) #define FIXED_MIN (signed)(0x80000000) diff --git a/src/f_wipe.cpp b/src/f_wipe.cpp index a3ceb8d50..c6f20cadb 100644 --- a/src/f_wipe.cpp +++ b/src/f_wipe.cpp @@ -77,8 +77,10 @@ bool wipe_initMelt (int ticks) { int i, r; +#ifdef PALETTEOUTPUT // copy start screen to main screen screen->DrawBlock (0, 0, SCREENWIDTH, SCREENHEIGHT, (BYTE *)wipe_scr_start); +#endif // makes this wipe faster (in theory) // to have stuff in column-major format @@ -271,7 +273,8 @@ bool wipe_doBurn (int ticks) // Draw the screen int xstep, ystep, firex, firey; int x, y; - BYTE *to, *fromold, *fromnew; + canvas_pixel_t *to; + BYTE *fromold, *fromnew; const int SHIFT = 16; xstep = (FIREWIDTH << SHIFT) / SCREENWIDTH; @@ -298,6 +301,9 @@ bool wipe_doBurn (int ticks) } else { +#ifndef PALETTEOUTPUT + // TO DO: RGB32k.All +#else int bglevel = 64-fglevel; DWORD *fg2rgb = Col2RGB8[fglevel]; DWORD *bg2rgb = Col2RGB8[bglevel]; @@ -305,6 +311,7 @@ bool wipe_doBurn (int ticks) DWORD bg = bg2rgb[fromold[x]]; fg = (fg+bg) | 0x1f07c1f; to[x] = RGB32k.All[fg & (fg>>15)]; +#endif done = false; } } @@ -335,7 +342,9 @@ bool wipe_doFade (int ticks) fade += ticks * 2; if (fade > 64) { +#ifdef PALETTEOUTPUT screen->DrawBlock (0, 0, SCREENWIDTH, SCREENHEIGHT, (BYTE *)wipe_scr_end); +#endif return true; } else @@ -346,7 +355,7 @@ bool wipe_doFade (int ticks) DWORD *bg2rgb = Col2RGB8[bglevel]; BYTE *fromnew = (BYTE *)wipe_scr_end; BYTE *fromold = (BYTE *)wipe_scr_start; - BYTE *to = screen->GetBuffer(); + canvas_pixel_t *to = screen->GetBuffer(); for (y = 0; y < SCREENHEIGHT; y++) { @@ -387,7 +396,9 @@ bool wipe_StartScreen (int type) if (CurrentWipeType) { wipe_scr_start = new short[SCREENWIDTH * SCREENHEIGHT / 2]; +#ifdef PALETTEOUTPUT screen->GetBlock (0, 0, SCREENWIDTH, SCREENHEIGHT, (BYTE *)wipe_scr_start); +#endif return true; } return false; @@ -398,8 +409,10 @@ void wipe_EndScreen (void) if (CurrentWipeType) { wipe_scr_end = new short[SCREENWIDTH * SCREENHEIGHT / 2]; +#ifdef PALETTEOUTPUT screen->GetBlock (0, 0, SCREENWIDTH, SCREENHEIGHT, (BYTE *)wipe_scr_end); screen->DrawBlock (0, 0, SCREENWIDTH, SCREENHEIGHT, (BYTE *)wipe_scr_start); // restore start scr. +#endif // Initialize the wipe (*wipes[(CurrentWipeType-1)*3])(0); } diff --git a/src/m_misc.cpp b/src/m_misc.cpp index 87f61f253..79416c31d 100644 --- a/src/m_misc.cpp +++ b/src/m_misc.cpp @@ -655,6 +655,7 @@ static bool FindFreeName (FString &fullname, const char *extension) void M_ScreenShot (const char *filename) { +#ifdef PALETTEOUTPUT FILE *file; FString autoname; bool writepcx = (stricmp (screenshot_type, "pcx") == 0); // PNG is the default @@ -743,6 +744,7 @@ void M_ScreenShot (const char *filename) Printf ("Could not create screenshot.\n"); } } +#endif } CCMD (screenshot) diff --git a/src/r_draw.cpp b/src/r_draw.cpp index 80b91ed2d..044910008 100644 --- a/src/r_draw.cpp +++ b/src/r_draw.cpp @@ -42,6 +42,9 @@ #include "gi.h" #include "stats.h" #include "x86.h" +#ifndef NO_SSE +#include +#endif #undef RANGECHECK @@ -61,7 +64,7 @@ extern int ST_Y; BYTE* viewimage; extern "C" { int ylookup[MAXHEIGHT]; -BYTE *dc_destorg; +canvas_pixel_t *dc_destorg; } int scaledviewwidth; @@ -90,6 +93,7 @@ extern "C" { int dc_pitch=0xABadCafe; // [RH] Distance between rows lighttable_t* dc_colormap; +fixed_t dc_light; int dc_x; int dc_yl; int dc_yh; @@ -103,12 +107,13 @@ DWORD *dc_destblend; // blending lookups // first pixel in a column (possibly virtual) const BYTE* dc_source; -BYTE* dc_dest; +canvas_pixel_t* dc_dest; int dc_count; DWORD vplce[4]; DWORD vince[4]; BYTE* palookupoffse[4]; +fixed_t palookuplight[4]; const BYTE* bufplce[4]; // just for profiling @@ -180,7 +185,7 @@ void R_InitShadeMaps() void R_DrawColumnP_C (void) { int count; - BYTE* dest; + canvas_pixel_t* dest; fixed_t frac; fixed_t fracstep; @@ -193,6 +198,10 @@ void R_DrawColumnP_C (void) // Framebuffer destination address. dest = dc_dest; +#ifndef PALETTEOUTPUT + uint32_t light = calc_light_multiplier(dc_light); +#endif + // Determine scaling, // which is the only mapping to be done. fracstep = dc_iscale; @@ -212,7 +221,11 @@ void R_DrawColumnP_C (void) { // Re-map color indices from wall texture column // using a lighting/special effects LUT. - *dest = colormap[source[frac>>FRACBITS]]; +#ifndef PALETTEOUTPUT + *dest = shade_pal_index(colormap[source[frac>>FRACBITS]], light); +#else + *dest = colormap[source[frac >> FRACBITS]]; +#endif dest += pitch; frac += fracstep; @@ -226,7 +239,7 @@ void R_DrawColumnP_C (void) void R_FillColumnP (void) { int count; - BYTE* dest; + canvas_pixel_t* dest; count = dc_count; @@ -235,13 +248,21 @@ void R_FillColumnP (void) dest = dc_dest; +#ifndef PALETTEOUTPUT + uint32_t light = calc_light_multiplier(dc_light); +#endif + { int pitch = dc_pitch; BYTE color = dc_color; do { +#ifndef PALETTEOUTPUT + *dest = shade_pal_index(color, light); +#else *dest = color; +#endif dest += pitch; } while (--count); } @@ -250,19 +271,39 @@ void R_FillColumnP (void) void R_FillAddColumn (void) { int count; - BYTE *dest; + canvas_pixel_t *dest; count = dc_count; if (count <= 0) return; dest = dc_dest; + int pitch = dc_pitch; + +#ifndef PALETTEOUTPUT + uint32_t fg_red = (dc_srccolor >> 12) & 0xf8; + uint32_t fg_green = (dc_srccolor >> 2) & 0xf8; + uint32_t fg_blue = (dc_srccolor << 3) & 0xf8; + + do + { + 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 + 1) / 2; + uint32_t green = (fg_green + bg_green + 1) / 2; + uint32_t blue = (fg_blue + bg_blue + 1) / 2; + + *dest = 0xff000000 | (red << 16) | (green << 8) | blue; + dest += pitch; + } while (--count); +#else DWORD *bg2rgb; DWORD fg; bg2rgb = dc_destblend; fg = dc_srccolor; - int pitch = dc_pitch; do { @@ -271,25 +312,45 @@ void R_FillAddColumn (void) *dest = RGB32k.All[bg & (bg>>15)]; dest += pitch; } while (--count); - +#endif } void R_FillAddClampColumn (void) { int count; - BYTE *dest; + canvas_pixel_t *dest; count = dc_count; if (count <= 0) return; dest = dc_dest; + int pitch = dc_pitch; + +#ifndef PALETTEOUTPUT + uint32_t fg_red = (dc_srccolor >> 12) & 0xf8; + uint32_t fg_green = (dc_srccolor >> 2) & 0xf8; + uint32_t fg_blue = (dc_srccolor << 3) & 0xf8; + + do + { + uint32_t bg_red = (*dest >> 16) & 0xff; + uint32_t bg_green = (*dest >> 8) & 0xff; + uint32_t bg_blue = (*dest) & 0xff; + + uint32_t red = clamp(fg_red + bg_red, 0, 255); + uint32_t green = clamp(fg_green + bg_green, 0, 255); + uint32_t blue = clamp(fg_blue + bg_blue, 0, 255); + + *dest = 0xff000000 | (red << 16) | (green << 8) | blue; + dest += pitch; + } while (--count); +#else DWORD *bg2rgb; DWORD fg; bg2rgb = dc_destblend; fg = dc_srccolor; - int pitch = dc_pitch; do { @@ -304,25 +365,45 @@ void R_FillAddClampColumn (void) *dest = RGB32k.All[a & (a>>15)]; dest += pitch; } while (--count); - +#endif } void R_FillSubClampColumn (void) { int count; - BYTE *dest; + canvas_pixel_t *dest; count = dc_count; if (count <= 0) return; dest = dc_dest; + int pitch = dc_pitch; + +#ifndef PALETTEOUTPUT + uint32_t fg_red = (dc_srccolor >> 12) & 0xf8; + uint32_t fg_green = (dc_srccolor >> 2) & 0xf8; + uint32_t fg_blue = (dc_srccolor << 3) & 0xf8; + + do + { + uint32_t bg_red = (*dest >> 16) & 0xff; + uint32_t bg_green = (*dest >> 8) & 0xff; + uint32_t bg_blue = (*dest) & 0xff; + + uint32_t red = clamp(256 - fg_red + bg_red, 256, 256 + 255) - 255; + uint32_t green = clamp(256 - fg_green + bg_green, 256, 256 + 255) - 255; + uint32_t blue = clamp(256 - fg_blue + bg_blue, 256, 256 + 255) - 255; + + *dest = 0xff000000 | (red << 16) | (green << 8) | blue; + dest += pitch; + } while (--count); +#else DWORD *bg2rgb; DWORD fg; bg2rgb = dc_destblend; fg = dc_srccolor | 0x40100400; - int pitch = dc_pitch; do { @@ -336,25 +417,45 @@ void R_FillSubClampColumn (void) *dest = RGB32k.All[a & (a>>15)]; dest += pitch; } while (--count); - +#endif } void R_FillRevSubClampColumn (void) { int count; - BYTE *dest; + canvas_pixel_t *dest; count = dc_count; if (count <= 0) return; dest = dc_dest; + int pitch = dc_pitch; + +#ifndef PALETTEOUTPUT + uint32_t fg_red = (dc_srccolor >> 12) & 0xf8; + uint32_t fg_green = (dc_srccolor >> 2) & 0xf8; + uint32_t fg_blue = (dc_srccolor << 3) & 0xf8; + + do + { + uint32_t bg_red = (*dest >> 16) & 0xff; + uint32_t bg_green = (*dest >> 8) & 0xff; + uint32_t bg_blue = (*dest) & 0xff; + + uint32_t red = clamp(256 + fg_red - bg_red, 256, 256 + 255) - 255; + uint32_t green = clamp(256 + fg_green - bg_green, 256, 256 + 255) - 255; + uint32_t blue = clamp(256 + fg_blue - bg_blue, 256, 256 + 255) - 255; + + *dest = 0xff000000 | (red << 16) | (green << 8) | blue; + dest += pitch; + } while (--count); +#else DWORD *bg2rgb; DWORD fg; bg2rgb = dc_destblend; fg = dc_srccolor; - int pitch = dc_pitch; do { @@ -368,7 +469,7 @@ void R_FillRevSubClampColumn (void) *dest = RGB32k.All[a & (a>>15)]; dest += pitch; } while (--count); - +#endif } // @@ -421,7 +522,7 @@ void R_InitFuzzTable (int fuzzoff) void R_DrawFuzzColumnP_C (void) { int count; - BYTE *dest; + canvas_pixel_t *dest; // Adjust borders. Low... if (dc_yl == 0) @@ -441,6 +542,85 @@ void R_DrawFuzzColumnP_C (void) dest = ylookup[dc_yl] + dc_x + dc_destorg; +#ifndef PALETTEOUTPUT + + // Note: this implementation assumes this function is only used for the pinky shadow effect (i.e. no other fancy colormap than black) + // I'm not sure if this is really always the case or not. + + { + // [RH] Make local copies of global vars to try and improve + // the optimizations made by the compiler. + int pitch = dc_pitch; + int fuzz = fuzzpos; + int cnt; + + // [RH] Split this into three separate loops to minimize + // the number of times fuzzpos needs to be clamped. + if (fuzz) + { + cnt = MIN(FUZZTABLE - fuzz, count); + count -= cnt; + do + { + uint32_t bg = dest[fuzzoffset[fuzz++]]; + uint32_t bg_red = (bg >> 16) & 0xff; + uint32_t bg_green = (bg >> 8) & 0xff; + uint32_t bg_blue = (bg) & 0xff; + + uint32_t red = bg_red * 3 / 4; + uint32_t green = bg_green * 3 / 4; + uint32_t blue = bg_blue * 3 / 4; + + *dest = 0xff000000 | (red << 16) | (green << 8) | blue; + dest += pitch; + } while (--cnt); + } + if (fuzz == FUZZTABLE || count > 0) + { + while (count >= FUZZTABLE) + { + fuzz = 0; + cnt = FUZZTABLE; + count -= FUZZTABLE; + do + { + uint32_t bg = dest[fuzzoffset[fuzz++]]; + uint32_t bg_red = (bg >> 16) & 0xff; + uint32_t bg_green = (bg >> 8) & 0xff; + uint32_t bg_blue = (bg) & 0xff; + + uint32_t red = bg_red * 3 / 4; + uint32_t green = bg_green * 3 / 4; + uint32_t blue = bg_blue * 3 / 4; + + *dest = 0xff000000 | (red << 16) | (green << 8) | blue; + dest += pitch; + } while (--cnt); + } + fuzz = 0; + if (count > 0) + { + do + { + uint32_t bg = dest[fuzzoffset[fuzz++]]; + uint32_t bg_red = (bg >> 16) & 0xff; + uint32_t bg_green = (bg >> 8) & 0xff; + uint32_t bg_blue = (bg) & 0xff; + + uint32_t red = bg_red * 3 / 4; + uint32_t green = bg_green * 3 / 4; + uint32_t blue = bg_blue * 3 / 4; + + *dest = 0xff000000 | (red << 16) | (green << 8) | blue; + dest += pitch; + } while (--count); + } + } + fuzzpos = fuzz; + } + +#else + // colormap #6 is used for shading (of 0-31, a bit brighter than average) { // [RH] Make local copies of global vars to try and improve @@ -487,6 +667,7 @@ void R_DrawFuzzColumnP_C (void) } fuzzpos = fuzz; } +#endif } #endif @@ -539,7 +720,7 @@ algorithm that uses RGB tables. void R_DrawAddColumnP_C (void) { int count; - BYTE *dest; + canvas_pixel_t *dest; fixed_t frac; fixed_t fracstep; @@ -552,6 +733,34 @@ void R_DrawAddColumnP_C (void) fracstep = dc_iscale; frac = dc_texturefrac; +#ifndef PALETTEOUTPUT + { + const BYTE *source = dc_source; + int pitch = dc_pitch; + BYTE *colormap = dc_colormap; + + do + { + uint32_t fg = shade_pal_index(colormap[source[frac >> FRACBITS]], 0); + + 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(fg_red + bg_red, 0, 255); + uint32_t green = clamp(fg_green + bg_green, 0, 255); + uint32_t blue = clamp(fg_blue + bg_blue, 0, 255); + + *dest = 0xff000000 | (red << 16) | (green << 8) | blue; + dest += pitch; + frac += fracstep; + } while (--count); + } +#else { DWORD *fg2rgb = dc_srcblend; DWORD *bg2rgb = dc_destblend; @@ -572,6 +781,7 @@ void R_DrawAddColumnP_C (void) frac += fracstep; } while (--count); } +#endif } // @@ -585,7 +795,7 @@ void R_DrawAddColumnP_C (void) void R_DrawTranslatedColumnP_C (void) { int count; - BYTE* dest; + canvas_pixel_t* dest; fixed_t frac; fixed_t fracstep; @@ -593,6 +803,10 @@ void R_DrawTranslatedColumnP_C (void) if (count <= 0) return; +#ifndef PALETTEOUTPUT + uint32_t light = calc_light_multiplier(dc_light); +#endif + dest = dc_dest; fracstep = dc_iscale; @@ -607,7 +821,11 @@ void R_DrawTranslatedColumnP_C (void) do { +#ifndef PALETTEOUTPUT + *dest = shade_pal_index(colormap[translation[source[frac >> FRACBITS]]], light); +#else *dest = colormap[translation[source[frac>>FRACBITS]]]; +#endif dest += pitch; frac += fracstep; @@ -619,7 +837,7 @@ void R_DrawTranslatedColumnP_C (void) void R_DrawTlatedAddColumnP_C (void) { int count; - BYTE *dest; + canvas_pixel_t *dest; fixed_t frac; fixed_t fracstep; @@ -627,11 +845,44 @@ void R_DrawTlatedAddColumnP_C (void) if (count <= 0) return; +#ifndef PALETTEOUTPUT + uint32_t light = calc_light_multiplier(dc_light); +#endif + dest = dc_dest; fracstep = dc_iscale; frac = dc_texturefrac; +#ifndef PALETTEOUTPUT + { + BYTE *translation = dc_translation; + BYTE *colormap = dc_colormap; + const BYTE *source = dc_source; + int pitch = dc_pitch; + + do + { + uint32_t fg = shade_pal_index(colormap[translation[source[frac >> FRACBITS]]], 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(fg_red + bg_red, 0, 255); + uint32_t green = clamp(fg_green + bg_green, 0, 255); + uint32_t blue = clamp(fg_blue + bg_blue, 0, 255); + + *dest = 0xff000000 | (red << 16) | (green << 8) | blue; + dest += pitch; + frac += fracstep; + } while (--count); + } +#else { DWORD *fg2rgb = dc_srcblend; DWORD *bg2rgb = dc_destblend; @@ -647,12 +898,13 @@ void R_DrawTlatedAddColumnP_C (void) fg = fg2rgb[fg]; bg = bg2rgb[bg]; - fg = (fg+bg) | 0x1f07c1f; - *dest = RGB32k.All[fg & (fg>>15)]; + fg = (fg + bg) | 0x1f07c1f; + *dest = RGB32k.All[fg & (fg >> 15)]; dest += pitch; frac += fracstep; } while (--count); } +#endif } // Draw a column whose "color" values are actually translucency @@ -660,7 +912,7 @@ void R_DrawTlatedAddColumnP_C (void) void R_DrawShadedColumnP_C (void) { int count; - BYTE *dest; + canvas_pixel_t *dest; fixed_t frac, fracstep; count = dc_count; @@ -673,6 +925,36 @@ void R_DrawShadedColumnP_C (void) fracstep = dc_iscale; frac = dc_texturefrac; +#ifndef PALETTEOUTPUT + uint32_t fg = shade_pal_index(dc_color, calc_light_multiplier(dc_light)); + uint32_t fg_red = (fg >> 16) & 0xff; + uint32_t fg_green = (fg >> 8) & 0xff; + uint32_t fg_blue = fg & 0xff; + + { + const BYTE *source = dc_source; + BYTE *colormap = dc_colormap; + int pitch = dc_pitch; + + do + { + DWORD alpha = clamp(colormap[source[frac >> FRACBITS]], 0, 64); + DWORD 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; + dest += pitch; + frac += fracstep; + } while (--count); + } +#else { const BYTE *source = dc_source; BYTE *colormap = dc_colormap; @@ -690,13 +972,14 @@ void R_DrawShadedColumnP_C (void) frac += fracstep; } while (--count); } +#endif } // Add source to destination, clamping it to white void R_DrawAddClampColumnP_C () { int count; - BYTE *dest; + canvas_pixel_t *dest; fixed_t frac; fixed_t fracstep; @@ -709,6 +992,34 @@ void R_DrawAddClampColumnP_C () fracstep = dc_iscale; frac = dc_texturefrac; +#ifndef PALETTEOUTPUT + { + const BYTE *source = dc_source; + BYTE *colormap = dc_colormap; + int pitch = dc_pitch; + uint32_t light = calc_light_multiplier(dc_light); + + do + { + uint32_t fg = shade_pal_index(colormap[source[frac >> FRACBITS]], 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(fg_red + bg_red, 0, 255); + uint32_t green = clamp(fg_green + bg_green, 0, 255); + uint32_t blue = clamp(fg_blue + bg_blue, 0, 255); + + *dest = 0xff000000 | (red << 16) | (green << 8) | blue; + dest += pitch; + frac += fracstep; + } while (--count); + } +#else { BYTE *colormap = dc_colormap; const BYTE *source = dc_source; @@ -731,13 +1042,14 @@ void R_DrawAddClampColumnP_C () frac += fracstep; } while (--count); } +#endif } // Add translated source to destination, clamping it to white void R_DrawAddClampTranslatedColumnP_C () { int count; - BYTE *dest; + canvas_pixel_t *dest; fixed_t frac; fixed_t fracstep; @@ -750,6 +1062,35 @@ void R_DrawAddClampTranslatedColumnP_C () fracstep = dc_iscale; frac = dc_texturefrac; +#ifndef PALETTEOUTPUT + { + BYTE *translation = dc_translation; + BYTE *colormap = dc_colormap; + const BYTE *source = dc_source; + int pitch = dc_pitch; + uint32_t light = calc_light_multiplier(dc_light); + + do + { + uint32_t fg = shade_pal_index(colormap[translation[source[frac >> FRACBITS]]], 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(fg_red + bg_red, 0, 255); + uint32_t green = clamp(fg_green + bg_green, 0, 255); + uint32_t blue = clamp(fg_blue + bg_blue, 0, 255); + + *dest = 0xff000000 | (red << 16) | (green << 8) | blue; + dest += pitch; + frac += fracstep; + } while (--count); + } +#else { BYTE *translation = dc_translation; BYTE *colormap = dc_colormap; @@ -773,13 +1114,14 @@ void R_DrawAddClampTranslatedColumnP_C () frac += fracstep; } while (--count); } +#endif } // Subtract destination from source, clamping it to black void R_DrawSubClampColumnP_C () { int count; - BYTE *dest; + canvas_pixel_t *dest; fixed_t frac; fixed_t fracstep; @@ -792,6 +1134,34 @@ void R_DrawSubClampColumnP_C () fracstep = dc_iscale; frac = dc_texturefrac; +#ifndef PALETTEOUTPUT + { + BYTE *colormap = dc_colormap; + const BYTE *source = dc_source; + int pitch = dc_pitch; + uint32_t light = calc_light_multiplier(dc_light); + + do + { + uint32_t fg = shade_pal_index(colormap[source[frac >> FRACBITS]], 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(256 - fg_red + bg_red, 256, 256 + 255) - 256; + uint32_t green = clamp(256 - fg_green + bg_green, 256, 256 + 255) - 256; + uint32_t blue = clamp(256 - fg_blue + bg_blue, 256, 256 + 255) - 256; + + *dest = 0xff000000 | (red << 16) | (green << 8) | blue; + dest += pitch; + frac += fracstep; + } while (--count); + } +#else { BYTE *colormap = dc_colormap; const BYTE *source = dc_source; @@ -813,13 +1183,14 @@ void R_DrawSubClampColumnP_C () frac += fracstep; } while (--count); } +#endif } // Subtract destination from source, clamping it to black void R_DrawSubClampTranslatedColumnP_C () { int count; - BYTE *dest; + canvas_pixel_t *dest; fixed_t frac; fixed_t fracstep; @@ -832,6 +1203,35 @@ void R_DrawSubClampTranslatedColumnP_C () fracstep = dc_iscale; frac = dc_texturefrac; +#ifndef PALETTEOUTPUT + { + BYTE *translation = dc_translation; + BYTE *colormap = dc_colormap; + const BYTE *source = dc_source; + int pitch = dc_pitch; + uint32_t light = calc_light_multiplier(dc_light); + + do + { + uint32_t fg = shade_pal_index(colormap[translation[source[frac >> FRACBITS]]], 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(256 - fg_red + bg_red, 256, 256 + 255) - 256; + uint32_t green = clamp(256 - fg_green + bg_green, 256, 256 + 255) - 256; + uint32_t blue = clamp(256 - fg_blue + bg_blue, 256, 256 + 255) - 256; + + *dest = 0xff000000 | (red << 16) | (green << 8) | blue; + dest += pitch; + frac += fracstep; + } while (--count); + } +#else { BYTE *translation = dc_translation; BYTE *colormap = dc_colormap; @@ -854,13 +1254,14 @@ void R_DrawSubClampTranslatedColumnP_C () frac += fracstep; } while (--count); } +#endif } // Subtract source from destination, clamping it to black void R_DrawRevSubClampColumnP_C () { int count; - BYTE *dest; + canvas_pixel_t *dest; fixed_t frac; fixed_t fracstep; @@ -873,6 +1274,34 @@ void R_DrawRevSubClampColumnP_C () fracstep = dc_iscale; frac = dc_texturefrac; +#ifndef PALETTEOUTPUT + { + BYTE *colormap = dc_colormap; + const BYTE *source = dc_source; + int pitch = dc_pitch; + uint32_t light = calc_light_multiplier(dc_light); + + do + { + uint32_t fg = shade_pal_index(colormap[source[frac >> FRACBITS]], 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(256 + fg_red - bg_red, 256, 256 + 255) - 256; + uint32_t green = clamp(256 + fg_green - bg_green, 256, 256 + 255) - 256; + uint32_t blue = clamp(256 + fg_blue - bg_blue, 256, 256 + 255) - 256; + + *dest = 0xff000000 | (red << 16) | (green << 8) | blue; + dest += pitch; + frac += fracstep; + } while (--count); + } +#else { BYTE *colormap = dc_colormap; const BYTE *source = dc_source; @@ -894,13 +1323,14 @@ void R_DrawRevSubClampColumnP_C () frac += fracstep; } while (--count); } +#endif } // Subtract source from destination, clamping it to black void R_DrawRevSubClampTranslatedColumnP_C () { int count; - BYTE *dest; + canvas_pixel_t *dest; fixed_t frac; fixed_t fracstep; @@ -913,6 +1343,35 @@ void R_DrawRevSubClampTranslatedColumnP_C () fracstep = dc_iscale; frac = dc_texturefrac; +#ifndef PALETTEOUTPUT + { + BYTE *translation = dc_translation; + BYTE *colormap = dc_colormap; + const BYTE *source = dc_source; + int pitch = dc_pitch; + uint32_t light = calc_light_multiplier(dc_light); + + do + { + uint32_t fg = shade_pal_index(colormap[translation[source[frac >> FRACBITS]]], 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(256 + fg_red - bg_red, 256, 256 + 255) - 256; + uint32_t green = clamp(256 + fg_green - bg_green, 256, 256 + 255) - 256; + uint32_t blue = clamp(256 + fg_blue - bg_blue, 256, 256 + 255) - 256; + + *dest = 0xff000000 | (red << 16) | (green << 8) | blue; + dest += pitch; + frac += fracstep; + } while (--count); + } +#else { BYTE *translation = dc_translation; BYTE *colormap = dc_colormap; @@ -935,6 +1394,7 @@ void R_DrawRevSubClampTranslatedColumnP_C () frac += fracstep; } while (--count); } +#endif } @@ -967,6 +1427,7 @@ int ds_x1; int ds_x2; lighttable_t* ds_colormap; +//dsfixed_t ds_light; dsfixed_t ds_xfrac; dsfixed_t ds_yfrac; @@ -1019,6 +1480,7 @@ void R_SetSpanSource(const BYTE *pixels) void R_SetSpanColormap(BYTE *colormap) { ds_colormap = colormap; + ds_light = 0; #ifdef X86_ASM if (ds_colormap != ds_curcolormap) { @@ -1062,7 +1524,7 @@ void R_DrawSpanP_C (void) dsfixed_t yfrac; dsfixed_t xstep; dsfixed_t ystep; - BYTE* dest; + canvas_pixel_t* dest; const BYTE* source = ds_source; const BYTE* colormap = ds_colormap; int count; @@ -1087,9 +1549,64 @@ void R_DrawSpanP_C (void) xstep = ds_xstep; ystep = ds_ystep; +#ifndef PALETTEOUTPUT + uint32_t light = calc_light_multiplier(ds_light); +#endif + if (ds_xbits == 6 && ds_ybits == 6) { // 64x64 is the most common case by far, so special case it. + +#ifndef PALETTEOUTPUT +#ifndef NO_SSE + __m128i mlight = _mm_set_epi16(256, light, light, light, 256, light, light, light); + uint32_t *palette = (uint32_t*)GPalette.BaseColors; + + int sse_count = count / 4; + count -= sse_count * 4; + while (sse_count--) + { + // Current texture index in u,v. + spot = ((xfrac >> (32 - 6 - 6))&(63 * 64)) + (yfrac >> (32 - 6)); + uint32_t p0 = colormap[source[spot]]; + xfrac += xstep; + yfrac += ystep; + + spot = ((xfrac >> (32 - 6 - 6))&(63 * 64)) + (yfrac >> (32 - 6)); + uint32_t p1 = colormap[source[spot]]; + xfrac += xstep; + yfrac += ystep; + + spot = ((xfrac >> (32 - 6 - 6))&(63 * 64)) + (yfrac >> (32 - 6)); + uint32_t p2 = colormap[source[spot]]; + xfrac += xstep; + yfrac += ystep; + + spot = ((xfrac >> (32 - 6 - 6))&(63 * 64)) + (yfrac >> (32 - 6)); + uint32_t p3 = colormap[source[spot]]; + xfrac += xstep; + yfrac += ystep; + + // Lookup pixel from flat texture tile, + // re-index using light/colormap. + __m128i fg = _mm_set_epi32(palette[p0], palette[p1], palette[p2], palette[p3]); + __m128i fg_hi = _mm_unpackhi_epi8(fg, _mm_setzero_si128()); + __m128i fg_lo = _mm_unpacklo_epi8(fg, _mm_setzero_si128()); + fg_hi = _mm_mullo_epi16(fg_hi, mlight); + fg_hi = _mm_srli_epi16(fg_hi, 8); + fg_lo = _mm_mullo_epi16(fg_lo, mlight); + fg_lo = _mm_srli_epi16(fg_lo, 8); + fg = _mm_packus_epi16(fg_hi, fg_lo); + _mm_storeu_si128((__m128i*)dest, fg); + + // Next step in u,v. + dest += 4; + } + if (count == 0) + return; +#endif +#endif + do { // Current texture index in u,v. @@ -1097,7 +1614,11 @@ void R_DrawSpanP_C (void) // Lookup pixel from flat texture tile, // re-index using light/colormap. +#ifndef PALETTEOUTPUT + *dest++ = shade_pal_index(colormap[source[spot]], light); +#else *dest++ = colormap[source[spot]]; +#endif // Next step in u,v. xfrac += xstep; @@ -1117,7 +1638,11 @@ void R_DrawSpanP_C (void) // Lookup pixel from flat texture tile, // re-index using light/colormap. +#ifndef PALETTEOUTPUT + *dest++ = shade_pal_index(colormap[source[spot]], light); +#else *dest++ = colormap[source[spot]]; +#endif // Next step in u,v. xfrac += xstep; @@ -1133,12 +1658,16 @@ void R_DrawSpanMaskedP_C (void) dsfixed_t yfrac; dsfixed_t xstep; dsfixed_t ystep; - BYTE* dest; + canvas_pixel_t* dest; const BYTE* source = ds_source; const BYTE* colormap = ds_colormap; int count; int spot; +#ifndef PALETTEOUTPUT + uint32_t light = calc_light_multiplier(ds_light); +#endif + xfrac = ds_xfrac; yfrac = ds_yfrac; @@ -1160,7 +1689,11 @@ void R_DrawSpanMaskedP_C (void) texdata = source[spot]; if (texdata != 0) { +#ifndef PALETTEOUTPUT + *dest = shade_pal_index(colormap[texdata], light); +#else *dest = colormap[texdata]; +#endif } dest++; xfrac += xstep; @@ -1180,7 +1713,11 @@ void R_DrawSpanMaskedP_C (void) texdata = source[spot]; if (texdata != 0) { +#ifndef PALETTEOUTPUT + *dest = shade_pal_index(colormap[texdata], light); +#else *dest = colormap[texdata]; +#endif } dest++; xfrac += xstep; @@ -1196,7 +1733,7 @@ void R_DrawSpanTranslucentP_C (void) dsfixed_t yfrac; dsfixed_t xstep; dsfixed_t ystep; - BYTE* dest; + canvas_pixel_t* dest; const BYTE* source = ds_source; const BYTE* colormap = ds_colormap; int count; @@ -1214,9 +1751,35 @@ void R_DrawSpanTranslucentP_C (void) xstep = ds_xstep; ystep = ds_ystep; + uint32_t light = calc_light_multiplier(ds_light); + if (ds_xbits == 6 && ds_ybits == 6) { // 64x64 is the most common case by far, so special case it. +#ifndef PALETTEOUTPUT + do + { + spot = ((xfrac >> (32 - 6 - 6))&(63 * 64)) + (yfrac >> (32 - 6)); + + uint32_t fg = shade_pal_index(colormap[source[spot]], 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 = (fg_red + bg_red + 1) / 2; + uint32_t green = (fg_green + bg_green + 1) / 2; + uint32_t blue = (fg_blue + bg_blue + 1) / 2; + + *dest++ = 0xff000000 | (red << 16) | (green << 8) | blue; + + xfrac += xstep; + yfrac += ystep; + } while (--count); +#else do { spot = ((xfrac>>(32-6-6))&(63*64)) + (yfrac>>(32-6)); @@ -1229,9 +1792,37 @@ void R_DrawSpanTranslucentP_C (void) xfrac += xstep; yfrac += ystep; } while (--count); +#endif } else { +#ifndef PALETTEOUTPUT + BYTE yshift = 32 - ds_ybits; + BYTE xshift = yshift - ds_xbits; + int xmask = ((1 << ds_xbits) - 1) << ds_ybits; + do + { + spot = ((xfrac >> xshift) & xmask) + (yfrac >> yshift); + + uint32_t fg = shade_pal_index(colormap[source[spot]], 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 = (fg_red + bg_red + 1) / 2; + uint32_t green = (fg_green + bg_green + 1) / 2; + uint32_t blue = (fg_blue + bg_blue + 1) / 2; + + *dest++ = 0xff000000 | (red << 16) | (green << 8) | blue; + + xfrac += xstep; + yfrac += ystep; + } while (--count); +#else BYTE yshift = 32 - ds_ybits; BYTE xshift = yshift - ds_xbits; int xmask = ((1 << ds_xbits) - 1) << ds_ybits; @@ -1247,6 +1838,7 @@ void R_DrawSpanTranslucentP_C (void) xfrac += xstep; yfrac += ystep; } while (--count); +#endif } } @@ -1256,7 +1848,7 @@ void R_DrawSpanMaskedTranslucentP_C (void) dsfixed_t yfrac; dsfixed_t xstep; dsfixed_t ystep; - BYTE* dest; + canvas_pixel_t* dest; const BYTE* source = ds_source; const BYTE* colormap = ds_colormap; int count; @@ -1264,6 +1856,8 @@ void R_DrawSpanMaskedTranslucentP_C (void) DWORD *fg2rgb = dc_srcblend; DWORD *bg2rgb = dc_destblend; + uint32_t light = calc_light_multiplier(ds_light); + xfrac = ds_xfrac; yfrac = ds_yfrac; @@ -1285,12 +1879,29 @@ void R_DrawSpanMaskedTranslucentP_C (void) texdata = source[spot]; if (texdata != 0) { +#ifndef PALETTEOUTPUT + uint32_t fg = shade_pal_index(colormap[texdata], 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 = (fg_red + bg_red + 1) / 2; + uint32_t green = (fg_green + bg_green + 1) / 2; + uint32_t blue = (fg_blue + bg_blue + 1) / 2; + + *dest = 0xff000000 | (red << 16) | (green << 8) | blue; +#else DWORD fg = colormap[texdata]; DWORD bg = *dest; fg = fg2rgb[fg]; bg = bg2rgb[bg]; fg = (fg+bg) | 0x1f07c1f; *dest = RGB32k.All[fg & (fg>>15)]; +#endif } dest++; xfrac += xstep; @@ -1310,12 +1921,29 @@ void R_DrawSpanMaskedTranslucentP_C (void) texdata = source[spot]; if (texdata != 0) { +#ifndef PALETTEOUTPUT + uint32_t fg = shade_pal_index(colormap[texdata], 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 = (fg_red + bg_red + 1) / 2; + uint32_t green = (fg_green + bg_green + 1) / 2; + uint32_t blue = (fg_blue + bg_blue + 1) / 2; + + *dest = 0xff000000 | (red << 16) | (green << 8) | blue; +#else DWORD fg = colormap[texdata]; DWORD bg = *dest; fg = fg2rgb[fg]; bg = bg2rgb[bg]; fg = (fg+bg) | 0x1f07c1f; *dest = RGB32k.All[fg & (fg>>15)]; +#endif } dest++; xfrac += xstep; @@ -1330,7 +1958,7 @@ void R_DrawSpanAddClampP_C (void) dsfixed_t yfrac; dsfixed_t xstep; dsfixed_t ystep; - BYTE* dest; + canvas_pixel_t* dest; const BYTE* source = ds_source; const BYTE* colormap = ds_colormap; int count; @@ -1338,6 +1966,8 @@ void R_DrawSpanAddClampP_C (void) DWORD *fg2rgb = dc_srcblend; DWORD *bg2rgb = dc_destblend; + uint32_t light = calc_light_multiplier(ds_light); + xfrac = ds_xfrac; yfrac = ds_yfrac; @@ -1354,6 +1984,23 @@ void R_DrawSpanAddClampP_C (void) do { spot = ((xfrac>>(32-6-6))&(63*64)) + (yfrac>>(32-6)); + +#ifndef PALETTEOUTPUT + uint32_t fg = shade_pal_index(colormap[source[spot]], 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(fg_red + bg_red, 0, 255); + uint32_t green = clamp(fg_green + bg_green, 0, 255); + uint32_t blue = clamp(fg_blue + bg_blue, 0, 255); + + *dest++ = 0xff000000 | (red << 16) | (green << 8) | blue; +#else DWORD a = fg2rgb[colormap[source[spot]]] + bg2rgb[*dest]; DWORD b = a; @@ -1363,6 +2010,8 @@ void R_DrawSpanAddClampP_C (void) b = b - (b >> 5); a |= b; *dest++ = RGB32k.All[a & (a>>15)]; +#endif + xfrac += xstep; yfrac += ystep; } while (--count); @@ -1375,6 +2024,23 @@ void R_DrawSpanAddClampP_C (void) do { spot = ((xfrac >> xshift) & xmask) + (yfrac >> yshift); + +#ifndef PALETTEOUTPUT + uint32_t fg = shade_pal_index(colormap[source[spot]], 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(fg_red + bg_red, 0, 255); + uint32_t green = clamp(fg_green + bg_green, 0, 255); + uint32_t blue = clamp(fg_blue + bg_blue, 0, 255); + + *dest++ = 0xff000000 | (red << 16) | (green << 8) | blue; +#else DWORD a = fg2rgb[colormap[source[spot]]] + bg2rgb[*dest]; DWORD b = a; @@ -1384,6 +2050,8 @@ void R_DrawSpanAddClampP_C (void) b = b - (b >> 5); a |= b; *dest++ = RGB32k.All[a & (a>>15)]; +#endif + xfrac += xstep; yfrac += ystep; } while (--count); @@ -1396,7 +2064,7 @@ void R_DrawSpanMaskedAddClampP_C (void) dsfixed_t yfrac; dsfixed_t xstep; dsfixed_t ystep; - BYTE* dest; + canvas_pixel_t* dest; const BYTE* source = ds_source; const BYTE* colormap = ds_colormap; int count; @@ -1404,6 +2072,8 @@ void R_DrawSpanMaskedAddClampP_C (void) DWORD *fg2rgb = dc_srcblend; DWORD *bg2rgb = dc_destblend; + uint32_t light = calc_light_multiplier(ds_light); + xfrac = ds_xfrac; yfrac = ds_yfrac; @@ -1425,6 +2095,22 @@ void R_DrawSpanMaskedAddClampP_C (void) texdata = source[spot]; if (texdata != 0) { +#ifndef PALETTEOUTPUT + uint32_t fg = shade_pal_index(colormap[texdata], 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 = (fg_red + bg_red + 1) / 2; + uint32_t green = (fg_green + bg_green + 1) / 2; + uint32_t blue = (fg_blue + bg_blue + 1) / 2; + + *dest = 0xff000000 | (red << 16) | (green << 8) | blue; +#else DWORD a = fg2rgb[colormap[texdata]] + bg2rgb[*dest]; DWORD b = a; @@ -1434,6 +2120,7 @@ void R_DrawSpanMaskedAddClampP_C (void) b = b - (b >> 5); a |= b; *dest = RGB32k.All[a & (a>>15)]; +#endif } dest++; xfrac += xstep; @@ -1453,6 +2140,22 @@ void R_DrawSpanMaskedAddClampP_C (void) texdata = source[spot]; if (texdata != 0) { +#ifndef PALETTEOUTPUT + uint32_t fg = shade_pal_index(colormap[texdata], 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 = (fg_red + bg_red + 1) / 2; + uint32_t green = (fg_green + bg_green + 1) / 2; + uint32_t blue = (fg_blue + bg_blue + 1) / 2; + + *dest = 0xff000000 | (red << 16) | (green << 8) | blue; +#else DWORD a = fg2rgb[colormap[texdata]] + bg2rgb[*dest]; DWORD b = a; @@ -1462,6 +2165,7 @@ void R_DrawSpanMaskedAddClampP_C (void) b = b - (b >> 5); a |= b; *dest = RGB32k.All[a & (a>>15)]; +#endif } dest++; xfrac += xstep; @@ -1473,7 +2177,16 @@ void R_DrawSpanMaskedAddClampP_C (void) // [RH] Just fill a span with a color void R_FillSpan (void) { - memset (ylookup[ds_y] + ds_x1 + dc_destorg, ds_color, ds_x2 - ds_x1 + 1); +#ifndef PALETTEOUTPUT + canvas_pixel_t *dest = ylookup[ds_y] + ds_x1 + dc_destorg; + int count = (ds_x2 - ds_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[ds_y] + ds_x1 + dc_destorg, ds_color, (ds_x2 - ds_x1 + 1) * sizeof(canvas_pixel_t)); +#endif } // Draw a voxel slab @@ -1492,7 +2205,7 @@ extern "C" void R_SetupDrawSlabC(const BYTE *colormap) slabcolormap = colormap; } -extern "C" void R_DrawSlabC(int dx, fixed_t v, int dy, fixed_t vi, const BYTE *vptr, BYTE *p) +extern "C" void R_DrawSlabC(int dx, fixed_t v, int dy, fixed_t vi, const BYTE *vptr, canvas_pixel_t *p) { int x; const BYTE *colormap = slabcolormap; @@ -1666,13 +2379,21 @@ DWORD vlinec1 () BYTE *colormap = dc_colormap; int count = dc_count; const BYTE *source = dc_source; - BYTE *dest = dc_dest; + canvas_pixel_t *dest = dc_dest; int bits = vlinebits; int pitch = dc_pitch; +#ifndef PALETTEOUTPUT + uint32_t light = calc_light_multiplier(dc_light); +#endif + do { - *dest = colormap[source[frac>>bits]]; +#ifndef PALETTEOUTPUT + *dest = shade_pal_index(colormap[source[frac>>bits]], light); +#else + *dest = colormap[source[frac >> bits]]; +#endif frac += fracstep; dest += pitch; } while (--count); @@ -1682,19 +2403,83 @@ DWORD vlinec1 () void vlinec4 () { - BYTE *dest = dc_dest; + canvas_pixel_t *dest = dc_dest; int count = dc_count; int bits = vlinebits; DWORD place; +#ifndef PALETTEOUTPUT + uint32_t light0 = calc_light_multiplier(palookuplight[0]); + uint32_t light1 = calc_light_multiplier(palookuplight[1]); + uint32_t light2 = calc_light_multiplier(palookuplight[2]); + uint32_t light3 = calc_light_multiplier(palookuplight[3]); +#ifndef NO_SSE + __m128i mlight_hi = _mm_set_epi16(256, light0, light0, light0, 256, light1, light1, light1); + __m128i mlight_lo = _mm_set_epi16(256, light2, light2, light2, 256, light3, light3, light3); + uint32_t *palette = (uint32_t*)GPalette.BaseColors; + DWORD local_vplce[4] = { vplce[0], vplce[1], vplce[2], vplce[3] }; + DWORD local_vince[4] = { vince[0], vince[1], vince[2], vince[3] }; +#endif +#endif + do { +#ifndef PALETTEOUTPUT +#ifndef NO_SSE + + DWORD place0 = local_vplce[0]; + DWORD place1 = local_vplce[1]; + DWORD place2 = local_vplce[2]; + DWORD place3 = local_vplce[3]; + + BYTE p0 = palookupoffse[0][bufplce[0][place0 >> bits]]; + BYTE p1 = palookupoffse[1][bufplce[1][place1 >> bits]]; + BYTE p2 = palookupoffse[2][bufplce[2][place2 >> bits]]; + BYTE p3 = palookupoffse[3][bufplce[3][place3 >> bits]]; + + local_vplce[0] = place0 + local_vince[0]; + local_vplce[1] = place1 + local_vince[1]; + local_vplce[2] = place2 + local_vince[2]; + local_vplce[3] = place3 + local_vince[3]; + + __m128i fg = _mm_set_epi32(palette[p0], palette[p1], palette[p2], palette[p3]); + __m128i fg_hi = _mm_unpackhi_epi8(fg, _mm_setzero_si128()); + __m128i fg_lo = _mm_unpacklo_epi8(fg, _mm_setzero_si128()); + fg_hi = _mm_mullo_epi16(fg_hi, mlight_hi); + fg_hi = _mm_srli_epi16(fg_hi, 8); + fg_lo = _mm_mullo_epi16(fg_lo, mlight_lo); + fg_lo = _mm_srli_epi16(fg_lo, 8); + fg = _mm_packus_epi16(fg_hi, fg_lo); + _mm_storeu_si128((__m128i*)dest, fg); + +#else + dest[0] = shade_pal_index(palookupoffse[0][bufplce[0][(place = vplce[0]) >> bits]], light0); vplce[0] = place + vince[0]; + dest[1] = shade_pal_index(palookupoffse[1][bufplce[1][(place = vplce[1]) >> bits]], light1); vplce[1] = place + vince[1]; + dest[2] = shade_pal_index(palookupoffse[2][bufplce[2][(place = vplce[2]) >> bits]], light2); vplce[2] = place + vince[2]; + dest[3] = shade_pal_index(palookupoffse[3][bufplce[3][(place = vplce[3]) >> bits]], light3); vplce[3] = place + vince[3]; +#endif +#else dest[0] = palookupoffse[0][bufplce[0][(place=vplce[0])>>bits]]; vplce[0] = place+vince[0]; dest[1] = palookupoffse[1][bufplce[1][(place=vplce[1])>>bits]]; vplce[1] = place+vince[1]; dest[2] = palookupoffse[2][bufplce[2][(place=vplce[2])>>bits]]; vplce[2] = place+vince[2]; dest[3] = palookupoffse[3][bufplce[3][(place=vplce[3])>>bits]]; vplce[3] = place+vince[3]; +#endif dest += dc_pitch; } while (--count); + +#ifndef PALETTEOUTPUT +#ifndef NO_SSE + // Is this needed? Global variables makes it tricky to know.. + vplce[0] = local_vplce[0]; + vplce[1] = local_vplce[1]; + vplce[2] = local_vplce[2]; + vplce[3] = local_vplce[3]; + vince[0] = local_vince[0]; + vince[1] = local_vince[1]; + vince[2] = local_vince[2]; + vince[3] = local_vince[3]; +#endif +#endif } #endif @@ -1717,16 +2502,24 @@ DWORD mvlinec1 () BYTE *colormap = dc_colormap; int count = dc_count; const BYTE *source = dc_source; - BYTE *dest = dc_dest; + canvas_pixel_t *dest = dc_dest; int bits = mvlinebits; int pitch = dc_pitch; +#ifndef PALETTEOUTPUT + uint32_t light = calc_light_multiplier(dc_light); +#endif + do { BYTE pix = source[frac>>bits]; if (pix != 0) { +#ifndef PALETTEOUTPUT + *dest = shade_pal_index(colormap[pix], light); +#else *dest = colormap[pix]; +#endif } frac += fracstep; dest += pitch; @@ -1737,19 +2530,33 @@ DWORD mvlinec1 () void mvlinec4 () { - BYTE *dest = dc_dest; + canvas_pixel_t *dest = dc_dest; int count = dc_count; int bits = mvlinebits; DWORD place; +#ifndef PALETTEOUTPUT + uint32_t light0 = calc_light_multiplier(palookuplight[0]); + uint32_t light1 = calc_light_multiplier(palookuplight[1]); + uint32_t light2 = calc_light_multiplier(palookuplight[2]); + uint32_t light3 = calc_light_multiplier(palookuplight[3]); +#endif + do { BYTE pix; +#ifndef PALETTEOUTPUT + pix = bufplce[0][(place = vplce[0]) >> bits]; if (pix) dest[0] = shade_pal_index(palookupoffse[0][pix], light0); vplce[0] = place + vince[0]; + pix = bufplce[1][(place = vplce[1]) >> bits]; if (pix) dest[1] = shade_pal_index(palookupoffse[1][pix], light1); vplce[1] = place + vince[1]; + pix = bufplce[2][(place = vplce[2]) >> bits]; if (pix) dest[2] = shade_pal_index(palookupoffse[2][pix], light2); vplce[2] = place + vince[2]; + pix = bufplce[3][(place = vplce[3]) >> bits]; if (pix) dest[3] = shade_pal_index(palookupoffse[3][pix], light3); vplce[3] = place + vince[3]; +#else pix = bufplce[0][(place=vplce[0])>>bits]; if(pix) dest[0] = palookupoffse[0][pix]; vplce[0] = place+vince[0]; pix = bufplce[1][(place=vplce[1])>>bits]; if(pix) dest[1] = palookupoffse[1][pix]; vplce[1] = place+vince[1]; pix = bufplce[2][(place=vplce[2])>>bits]; if(pix) dest[2] = palookupoffse[2][pix]; vplce[2] = place+vince[2]; pix = bufplce[3][(place=vplce[3])>>bits]; if(pix) dest[3] = palookupoffse[3][pix]; vplce[3] = place+vince[3]; +#endif dest += dc_pitch; } while (--count); } @@ -1763,7 +2570,11 @@ extern int wallshade; static void R_DrawFogBoundarySection (int y, int y2, int x1) { BYTE *colormap = dc_colormap; - BYTE *dest = ylookup[y] + dc_destorg; + canvas_pixel_t *dest = ylookup[y] + dc_destorg; + +#ifndef PALETTEOUTPUT + uint32_t light = calc_light_multiplier(dc_light); +#endif for (; y < y2; ++y) { @@ -1771,7 +2582,11 @@ static void R_DrawFogBoundarySection (int y, int y2, int x1) int x = x1; do { +#ifndef PALETTEOUTPUT + dest[x] = shade_pal_index(colormap[dest[x]], light); +#else dest[x] = colormap[dest[x]]; +#endif } while (++x <= x2); dest += dc_pitch; } @@ -1781,10 +2596,19 @@ static void R_DrawFogBoundaryLine (int y, int x) { int x2 = spanend[y]; BYTE *colormap = dc_colormap; - BYTE *dest = ylookup[y] + dc_destorg; + canvas_pixel_t *dest = ylookup[y] + dc_destorg; + +#ifndef PALETTEOUTPUT + uint32_t light = calc_light_multiplier(dc_light); +#endif + do { +#ifndef PALETTEOUTPUT + dest[x] = shade_pal_index(colormap[dest[x]], light); +#else dest[x] = colormap[dest[x]]; +#endif } while (++x <= x2); } @@ -1809,6 +2633,7 @@ void R_DrawFogBoundary (int x1, int x2, short *uclip, short *dclip) } dc_colormap = basecolormapdata + (rcolormap << COLORMAPSHIFT); + dc_light = 0; for (--x; x >= x1; --x) { @@ -1834,6 +2659,7 @@ void R_DrawFogBoundary (int x1, int x2, short *uclip, short *dclip) } rcolormap = lcolormap; dc_colormap = basecolormapdata + (lcolormap << COLORMAPSHIFT); + dc_light = 0; } else { @@ -1891,15 +2717,37 @@ fixed_t tmvline1_add () BYTE *colormap = dc_colormap; int count = dc_count; const BYTE *source = dc_source; - BYTE *dest = dc_dest; + canvas_pixel_t *dest = dc_dest; int bits = tmvlinebits; int pitch = dc_pitch; DWORD *fg2rgb = dc_srcblend; DWORD *bg2rgb = dc_destblend; + uint32_t light = calc_light_multiplier(dc_light); + do { +#ifndef PALETTEOUTPUT + BYTE pix = source[frac >> bits]; + if (pix != 0) + { + uint32_t fg = shade_pal_index(colormap[pix], 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(fg_red + bg_red, 0, 255); + uint32_t green = clamp(fg_green + bg_green, 0, 255); + uint32_t blue = clamp(fg_blue + bg_blue, 0, 255); + + *dest = 0xff000000 | (red << 16) | (green << 8) | blue; + } +#else BYTE pix = source[frac>>bits]; if (pix != 0) { @@ -1908,6 +2756,7 @@ fixed_t tmvline1_add () fg = (fg+bg) | 0x1f07c1f; *dest = RGB32k.All[fg & (fg>>15)]; } +#endif frac += fracstep; dest += pitch; } while (--count); @@ -1917,13 +2766,19 @@ fixed_t tmvline1_add () void tmvline4_add () { - BYTE *dest = dc_dest; + canvas_pixel_t *dest = dc_dest; int count = dc_count; int bits = tmvlinebits; DWORD *fg2rgb = dc_srcblend; DWORD *bg2rgb = dc_destblend; + uint32_t light[4]; + light[0] = calc_light_multiplier(palookuplight[0]); + light[1] = calc_light_multiplier(palookuplight[1]); + light[2] = calc_light_multiplier(palookuplight[2]); + light[3] = calc_light_multiplier(palookuplight[3]); + do { for (int i = 0; i < 4; ++i) @@ -1931,10 +2786,27 @@ void tmvline4_add () BYTE pix = bufplce[i][vplce[i] >> bits]; if (pix != 0) { +#ifndef PALETTEOUTPUT + uint32_t fg = shade_pal_index(palookupoffse[i][pix], light[i]); + 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(fg_red + bg_red, 0, 255); + uint32_t green = clamp(fg_green + bg_green, 0, 255); + uint32_t blue = clamp(fg_blue + bg_blue, 0, 255); + + dest[i] = 0xff000000 | (red << 16) | (green << 8) | blue; +#else DWORD fg = fg2rgb[palookupoffse[i][pix]]; DWORD bg = bg2rgb[dest[i]]; fg = (fg+bg) | 0x1f07c1f; dest[i] = RGB32k.All[fg & (fg>>15)]; +#endif } vplce[i] += vince[i]; } @@ -1949,18 +2821,36 @@ fixed_t tmvline1_addclamp () BYTE *colormap = dc_colormap; int count = dc_count; const BYTE *source = dc_source; - BYTE *dest = dc_dest; + canvas_pixel_t *dest = dc_dest; int bits = tmvlinebits; int pitch = dc_pitch; DWORD *fg2rgb = dc_srcblend; DWORD *bg2rgb = dc_destblend; + uint32_t light = calc_light_multiplier(dc_light); + do { BYTE pix = source[frac>>bits]; if (pix != 0) { +#ifndef PALETTEOUTPUT + uint32_t fg = shade_pal_index(colormap[pix], 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(fg_red + bg_red, 0, 255); + uint32_t green = clamp(fg_green + bg_green, 0, 255); + uint32_t blue = clamp(fg_blue + bg_blue, 0, 255); + + *dest = 0xff000000 | (red << 16) | (green << 8) | blue; +#else DWORD a = fg2rgb[colormap[pix]] + bg2rgb[*dest]; DWORD b = a; @@ -1970,6 +2860,7 @@ fixed_t tmvline1_addclamp () b = b - (b >> 5); a |= b; *dest = RGB32k.All[a & (a>>15)]; +#endif } frac += fracstep; dest += pitch; @@ -1980,13 +2871,19 @@ fixed_t tmvline1_addclamp () void tmvline4_addclamp () { - BYTE *dest = dc_dest; + canvas_pixel_t *dest = dc_dest; int count = dc_count; int bits = tmvlinebits; DWORD *fg2rgb = dc_srcblend; DWORD *bg2rgb = dc_destblend; + uint32_t light[4]; + light[0] = calc_light_multiplier(palookuplight[0]); + light[1] = calc_light_multiplier(palookuplight[1]); + light[2] = calc_light_multiplier(palookuplight[2]); + light[3] = calc_light_multiplier(palookuplight[3]); + do { for (int i = 0; i < 4; ++i) @@ -1994,6 +2891,22 @@ void tmvline4_addclamp () BYTE pix = bufplce[i][vplce[i] >> bits]; if (pix != 0) { +#ifndef PALETTEOUTPUT + uint32_t fg = shade_pal_index(palookupoffse[i][pix], light[i]); + 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(fg_red + bg_red, 0, 255); + uint32_t green = clamp(fg_green + bg_green, 0, 255); + uint32_t blue = clamp(fg_blue + bg_blue, 0, 255); + + dest[i] = 0xff000000 | (red << 16) | (green << 8) | blue; +#else DWORD a = fg2rgb[palookupoffse[i][pix]] + bg2rgb[dest[i]]; DWORD b = a; @@ -2003,6 +2916,7 @@ void tmvline4_addclamp () b = b - (b >> 5); a |= b; dest[i] = RGB32k.All[a & (a>>15)]; +#endif } vplce[i] += vince[i]; } @@ -2017,18 +2931,36 @@ fixed_t tmvline1_subclamp () BYTE *colormap = dc_colormap; int count = dc_count; const BYTE *source = dc_source; - BYTE *dest = dc_dest; + canvas_pixel_t *dest = dc_dest; int bits = tmvlinebits; int pitch = dc_pitch; DWORD *fg2rgb = dc_srcblend; DWORD *bg2rgb = dc_destblend; + uint32_t light = calc_light_multiplier(dc_light); + do { BYTE pix = source[frac>>bits]; if (pix != 0) { +#ifndef PALETTEOUTPUT + uint32_t fg = shade_pal_index(colormap[pix], 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(256 - fg_red + bg_red, 256, 256 + 255) - 256; + uint32_t green = clamp(256 - fg_green + bg_green, 256, 256 + 255) - 256; + uint32_t blue = clamp(256 - fg_blue + bg_blue, 256, 256 + 255) - 256; + + *dest = 0xff000000 | (red << 16) | (green << 8) | blue; +#else DWORD a = (fg2rgb[colormap[pix]] | 0x40100400) - bg2rgb[*dest]; DWORD b = a; @@ -2037,6 +2969,7 @@ fixed_t tmvline1_subclamp () a &= b; a |= 0x01f07c1f; *dest = RGB32k.All[a & (a>>15)]; +#endif } frac += fracstep; dest += pitch; @@ -2047,13 +2980,19 @@ fixed_t tmvline1_subclamp () void tmvline4_subclamp () { - BYTE *dest = dc_dest; + canvas_pixel_t *dest = dc_dest; int count = dc_count; int bits = tmvlinebits; DWORD *fg2rgb = dc_srcblend; DWORD *bg2rgb = dc_destblend; + uint32_t light[4]; + light[0] = calc_light_multiplier(palookuplight[0]); + light[1] = calc_light_multiplier(palookuplight[1]); + light[2] = calc_light_multiplier(palookuplight[2]); + light[3] = calc_light_multiplier(palookuplight[3]); + do { for (int i = 0; i < 4; ++i) @@ -2061,6 +3000,22 @@ void tmvline4_subclamp () BYTE pix = bufplce[i][vplce[i] >> bits]; if (pix != 0) { +#ifndef PALETTEOUTPUT + uint32_t fg = shade_pal_index(palookupoffse[i][pix], light[i]); + 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(256 - fg_red + bg_red, 256, 256 + 255) - 256; + uint32_t green = clamp(256 - fg_green + bg_green, 256, 256 + 255) - 256; + uint32_t blue = clamp(256 - fg_blue + bg_blue, 256, 256 + 255) - 256; + + dest[i] = 0xff000000 | (red << 16) | (green << 8) | blue; +#else DWORD a = (fg2rgb[palookupoffse[i][pix]] | 0x40100400) - bg2rgb[dest[i]]; DWORD b = a; @@ -2069,6 +3024,7 @@ void tmvline4_subclamp () a &= b; a |= 0x01f07c1f; dest[i] = RGB32k.All[a & (a>>15)]; +#endif } vplce[i] += vince[i]; } @@ -2083,18 +3039,36 @@ fixed_t tmvline1_revsubclamp () BYTE *colormap = dc_colormap; int count = dc_count; const BYTE *source = dc_source; - BYTE *dest = dc_dest; + canvas_pixel_t *dest = dc_dest; int bits = tmvlinebits; int pitch = dc_pitch; DWORD *fg2rgb = dc_srcblend; DWORD *bg2rgb = dc_destblend; + uint32_t light = calc_light_multiplier(dc_light); + do { BYTE pix = source[frac>>bits]; if (pix != 0) { +#ifndef PALETTEOUTPUT + uint32_t fg = shade_pal_index(colormap[pix], 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(256 + fg_red - bg_red, 256, 256 + 255) - 256; + uint32_t green = clamp(256 + fg_green - bg_green, 256, 256 + 255) - 256; + uint32_t blue = clamp(256 + fg_blue - bg_blue, 256, 256 + 255) - 256; + + *dest = 0xff000000 | (red << 16) | (green << 8) | blue; +#else DWORD a = (bg2rgb[*dest] | 0x40100400) - fg2rgb[colormap[pix]]; DWORD b = a; @@ -2103,6 +3077,7 @@ fixed_t tmvline1_revsubclamp () a &= b; a |= 0x01f07c1f; *dest = RGB32k.All[a & (a>>15)]; +#endif } frac += fracstep; dest += pitch; @@ -2113,13 +3088,19 @@ fixed_t tmvline1_revsubclamp () void tmvline4_revsubclamp () { - BYTE *dest = dc_dest; + canvas_pixel_t *dest = dc_dest; int count = dc_count; int bits = tmvlinebits; DWORD *fg2rgb = dc_srcblend; DWORD *bg2rgb = dc_destblend; + uint32_t light[4]; + light[0] = calc_light_multiplier(palookuplight[0]); + light[1] = calc_light_multiplier(palookuplight[1]); + light[2] = calc_light_multiplier(palookuplight[2]); + light[3] = calc_light_multiplier(palookuplight[3]); + do { for (int i = 0; i < 4; ++i) @@ -2127,6 +3108,22 @@ void tmvline4_revsubclamp () BYTE pix = bufplce[i][vplce[i] >> bits]; if (pix != 0) { +#ifndef PALETTEOUTPUT + uint32_t fg = shade_pal_index(palookupoffse[i][pix], light[i]); + 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(256 + fg_red - bg_red, 256, 256 + 255) - 256; + uint32_t green = clamp(256 + fg_green - bg_green, 256, 256 + 255) - 256; + uint32_t blue = clamp(256 + fg_blue - bg_blue, 256, 256 + 255) - 256; + + dest[i] = 0xff000000 | (red << 16) | (green << 8) | blue; +#else DWORD a = (bg2rgb[dest[i]] | 0x40100400) - fg2rgb[palookupoffse[i][pix]]; DWORD b = a; @@ -2135,6 +3132,7 @@ void tmvline4_revsubclamp () a &= b; a |= 0x01f07c1f; dest[i] = RGB32k.All[a & (a>>15)]; +#endif } vplce[i] += vince[i]; } @@ -2418,6 +3416,7 @@ ESPSResult R_SetPatchStyle (FRenderStyle style, fixed_t alpha, int translation, { dc_colormap += fixedlightlev; } + dc_light = 0; return r_columnmethod ? DoDraw1 : DoDraw0; } @@ -2443,6 +3442,7 @@ ESPSResult R_SetPatchStyle (FRenderStyle style, fixed_t alpha, int translation, dc_srccolor = ((((r*x)>>4)<<20) | ((g*x)>>4) | ((((b)*x)>>4)<<10)) & 0x3feffbff; hcolfunc_pre = R_FillColumnHorizP; dc_colormap = identitymap; + dc_light = 0; } if (!R_SetBlendFunc (style.BlendOp, fglevel, bglevel, style.Flags)) diff --git a/src/r_draw.h b/src/r_draw.h index cb2f68f33..6f7a91154 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -30,6 +30,7 @@ extern "C" int ylookup[MAXHEIGHT]; extern "C" int dc_pitch; // [RH] Distance between rows extern "C" lighttable_t*dc_colormap; +extern "C" fixed_t dc_light; extern "C" int dc_x; extern "C" int dc_yl; extern "C" int dc_yh; @@ -44,16 +45,17 @@ extern "C" DWORD *dc_destblend; // first pixel in a column extern "C" const BYTE* dc_source; -extern "C" BYTE *dc_dest, *dc_destorg; +extern "C" canvas_pixel_t *dc_dest, *dc_destorg; extern "C" int dc_count; extern "C" DWORD vplce[4]; extern "C" DWORD vince[4]; extern "C" BYTE* palookupoffse[4]; +extern "C" fixed_t palookuplight[4]; extern "C" const BYTE* bufplce[4]; // [RH] Temporary buffer for column drawing -extern "C" BYTE *dc_temp; +extern "C" canvas_pixel_t *dc_temp; extern "C" unsigned int dc_tspans[4][MAXHEIGHT]; extern "C" unsigned int *dc_ctspan[4]; extern "C" unsigned int horizspans[4]; @@ -184,7 +186,7 @@ extern void (*rt_map4cols)(int sx, int yl, int yh); void rt_draw4cols (int sx); // [RH] Preps the temporary horizontal buffer. -void rt_initcols (BYTE *buffer=NULL); +void rt_initcols (canvas_pixel_t *buffer=NULL); void R_DrawFogBoundary (int x1, int x2, short *uclip, short *dclip); @@ -231,13 +233,15 @@ void R_FillSpan (void); #endif extern "C" void R_SetupDrawSlab(const BYTE *colormap); -extern "C" void R_DrawSlab(int dx, fixed_t v, int dy, fixed_t vi, const BYTE *vptr, BYTE *p); +extern "C" void R_DrawSlab(int dx, fixed_t v, int dy, fixed_t vi, const BYTE *vptr, canvas_pixel_t *p); extern "C" int ds_y; extern "C" int ds_x1; extern "C" int ds_x2; extern "C" lighttable_t* ds_colormap; +//extern "C" dsfixed_t ds_light; +#define ds_light dc_light extern "C" dsfixed_t ds_xfrac; extern "C" dsfixed_t ds_yfrac; diff --git a/src/r_drawt.cpp b/src/r_drawt.cpp index e8faff0ce..f5fc027b5 100644 --- a/src/r_drawt.cpp +++ b/src/r_drawt.cpp @@ -57,8 +57,8 @@ // dc_ctspan is advanced while drawing into dc_temp. // horizspan is advanced up to dc_ctspan when drawing from dc_temp to the screen. -BYTE dc_tempbuff[MAXHEIGHT*4]; -BYTE *dc_temp; +canvas_pixel_t dc_tempbuff[MAXHEIGHT*4]; +canvas_pixel_t *dc_temp; unsigned int dc_tspans[4][MAXHEIGHT]; unsigned int *dc_ctspan[4]; unsigned int *horizspan[4]; @@ -73,8 +73,8 @@ extern "C" void R_SetupAddClampCol(); // Copies one span at hx to the screen at sx. void rt_copy1col_c (int hx, int sx, int yl, int yh) { - BYTE *source; - BYTE *dest; + canvas_pixel_t *source; + canvas_pixel_t *dest; int count; int pitch; @@ -114,6 +114,13 @@ 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; @@ -142,14 +149,15 @@ 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. void rt_map1col_c (int hx, int sx, int yl, int yh) { BYTE *colormap; - BYTE *source; - BYTE *dest; + canvas_pixel_t *source; + canvas_pixel_t *dest; int count; int pitch; @@ -158,13 +166,21 @@ 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; } @@ -172,8 +188,13 @@ 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); @@ -183,8 +204,8 @@ void rt_map1col_c (int hx, int sx, int yl, int yh) void rt_map4cols_c (int sx, int yl, int yh) { BYTE *colormap; - BYTE *source; - BYTE *dest; + canvas_pixel_t *source; + canvas_pixel_t *dest; int count; int pitch; @@ -193,16 +214,27 @@ 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; } @@ -210,6 +242,16 @@ 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]]; @@ -218,6 +260,7 @@ 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); @@ -227,7 +270,7 @@ void rt_map4cols_c (int sx, int yl, int yh) void rt_Translate1col(const BYTE *translation, int hx, int yl, int yh) { int count = yh - yl + 1; - BYTE *source = &dc_temp[yl*4 + hx]; + canvas_pixel_t *source = &dc_temp[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 @@ -274,7 +317,7 @@ void rt_Translate1col(const BYTE *translation, int hx, int yl, int yh) void rt_Translate4cols(const BYTE *translation, int yl, int yh) { int count = yh - yl + 1; - BYTE *source = &dc_temp[yl*4]; + canvas_pixel_t *source = &dc_temp[yl*4]; int c0, c1; BYTE b0, b1; @@ -330,8 +373,8 @@ void rt_tlate4cols (int sx, int yl, int yh) void rt_add1col (int hx, int sx, int yl, int yh) { BYTE *colormap; - BYTE *source; - BYTE *dest; + canvas_pixel_t *source; + canvas_pixel_t *dest; int count; int pitch; @@ -340,13 +383,36 @@ void rt_add1col (int hx, int sx, int yl, int yh) return; count++; - DWORD *fg2rgb = dc_srcblend; - DWORD *bg2rgb = dc_destblend; dest = ylookup[yl] + sx + dc_destorg; source = &dc_temp[yl*4 + hx]; 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(fg_red + bg_red, 0, 255); + uint32_t green = clamp(fg_green + bg_green, 0, 255); + uint32_t blue = clamp(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 { DWORD fg = colormap[*source]; DWORD bg = *dest; @@ -358,14 +424,15 @@ 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. void rt_add4cols_c (int sx, int yl, int yh) { BYTE *colormap; - BYTE *source; - BYTE *dest; + canvas_pixel_t *source; + canvas_pixel_t *dest; int count; int pitch; @@ -374,13 +441,40 @@ void rt_add4cols_c (int sx, int yl, int yh) return; count++; - DWORD *fg2rgb = dc_srcblend; - DWORD *bg2rgb = dc_destblend; dest = ylookup[yl] + sx + dc_destorg; source = &dc_temp[yl*4]; 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(fg_red + bg_red, 0, 255); + uint32_t green = clamp(fg_green + bg_green, 0, 255); + uint32_t blue = clamp(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; + do { DWORD fg = colormap[source[0]]; DWORD bg = dest[0]; @@ -414,6 +508,7 @@ 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. @@ -433,10 +528,9 @@ void rt_tlateadd4cols (int sx, int yl, int yh) // Shades one span at hx to the screen at sx. void rt_shaded1col (int hx, int sx, int yl, int yh) { - DWORD *fgstart; BYTE *colormap; - BYTE *source; - BYTE *dest; + canvas_pixel_t *source; + canvas_pixel_t *dest; int count; int pitch; @@ -445,12 +539,37 @@ void rt_shaded1col (int hx, int sx, int yl, int yh) return; count++; - fgstart = &Col2RGB8[0][dc_color]; colormap = dc_colormap; dest = ylookup[yl] + sx + dc_destorg; 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]; + do { DWORD val = colormap[*source]; DWORD fg = fgstart[val<<8]; @@ -459,15 +578,15 @@ 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. void rt_shaded4cols_c (int sx, int yl, int yh) { - DWORD *fgstart; BYTE *colormap; - BYTE *source; - BYTE *dest; + canvas_pixel_t *source; + canvas_pixel_t *dest; int count; int pitch; @@ -476,12 +595,40 @@ void rt_shaded4cols_c (int sx, int yl, int yh) return; count++; - fgstart = &Col2RGB8[0][dc_color]; colormap = dc_colormap; dest = ylookup[yl] + sx + dc_destorg; 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]; + do { DWORD val; @@ -504,14 +651,15 @@ 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) { BYTE *colormap; - BYTE *source; - BYTE *dest; + canvas_pixel_t *source; + canvas_pixel_t *dest; int count; int pitch; @@ -520,13 +668,36 @@ void rt_addclamp1col (int hx, int sx, int yl, int yh) return; count++; - DWORD *fg2rgb = dc_srcblend; - DWORD *bg2rgb = dc_destblend; dest = ylookup[yl] + sx + dc_destorg; source = &dc_temp[yl*4 + hx]; 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(fg_red + bg_red, 0, 255); + uint32_t green = clamp(fg_green + bg_green, 0, 255); + uint32_t blue = clamp(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 { DWORD a = fg2rgb[colormap[*source]] + bg2rgb[*dest]; DWORD b = a; @@ -540,14 +711,15 @@ 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. void rt_addclamp4cols_c (int sx, int yl, int yh) { BYTE *colormap; - BYTE *source; - BYTE *dest; + canvas_pixel_t *source; + canvas_pixel_t *dest; int count; int pitch; @@ -556,13 +728,39 @@ void rt_addclamp4cols_c (int sx, int yl, int yh) return; count++; - DWORD *fg2rgb = dc_srcblend; - DWORD *bg2rgb = dc_destblend; dest = ylookup[yl] + sx + dc_destorg; source = &dc_temp[yl*4]; 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(fg_red + bg_red, 0, 255); + uint32_t green = clamp(fg_green + bg_green, 0, 255); + uint32_t blue = clamp(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; + do { DWORD a = fg2rgb[colormap[source[0]]] + bg2rgb[dest[0]]; DWORD b = a; @@ -604,6 +802,7 @@ 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. @@ -624,8 +823,8 @@ void rt_tlateaddclamp4cols (int sx, int yl, int yh) void rt_subclamp1col (int hx, int sx, int yl, int yh) { BYTE *colormap; - BYTE *source; - BYTE *dest; + canvas_pixel_t *source; + canvas_pixel_t *dest; int count; int pitch; @@ -634,13 +833,35 @@ void rt_subclamp1col (int hx, int sx, int yl, int yh) return; count++; - DWORD *fg2rgb = dc_srcblend; - DWORD *bg2rgb = dc_destblend; dest = ylookup[yl] + sx + dc_destorg; source = &dc_temp[yl*4 + hx]; 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(256 - fg_red + bg_red, 256, 256 + 255) - 256; + uint32_t green = clamp(256 - fg_green + bg_green, 256, 256 + 255) - 256; + uint32_t blue = clamp(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 { DWORD a = (fg2rgb[colormap[*source]] | 0x40100400) - bg2rgb[*dest]; DWORD b = a; @@ -653,14 +874,15 @@ 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) { BYTE *colormap; - BYTE *source; - BYTE *dest; + canvas_pixel_t *source; + canvas_pixel_t *dest; int count; int pitch; @@ -669,13 +891,39 @@ void rt_subclamp4cols (int sx, int yl, int yh) return; count++; - DWORD *fg2rgb = dc_srcblend; - DWORD *bg2rgb = dc_destblend; dest = ylookup[yl] + sx + dc_destorg; source = &dc_temp[yl*4]; 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(256 - fg_red + bg_red, 256, 256 + 255) - 256; + uint32_t green = clamp(256 - fg_green + bg_green, 256, 256 + 255) - 256; + uint32_t blue = clamp(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 { DWORD a = (fg2rgb[colormap[source[0]]] | 0x40100400) - bg2rgb[dest[0]]; DWORD b = a; @@ -713,6 +961,7 @@ 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. @@ -733,8 +982,8 @@ void rt_tlatesubclamp4cols (int sx, int yl, int yh) void rt_revsubclamp1col (int hx, int sx, int yl, int yh) { BYTE *colormap; - BYTE *source; - BYTE *dest; + canvas_pixel_t *source; + canvas_pixel_t *dest; int count; int pitch; @@ -750,6 +999,28 @@ 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(256 + fg_red - bg_red, 256, 256 + 255) - 256; + uint32_t green = clamp(256 + fg_green - bg_green, 256, 256 + 255) - 256; + uint32_t blue = clamp(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; @@ -762,14 +1033,15 @@ 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) { BYTE *colormap; - BYTE *source; - BYTE *dest; + canvas_pixel_t *source; + canvas_pixel_t *dest; int count; int pitch; @@ -785,6 +1057,32 @@ 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(256 + fg_red - bg_red, 256, 256 + 255) - 256; + uint32_t green = clamp(256 + fg_green - bg_green, 256, 256 + 255) - 256; + uint32_t blue = clamp(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; @@ -822,6 +1120,7 @@ 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. @@ -1002,7 +1301,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 (BYTE *buff) +void rt_initcols (canvas_pixel_t *buff) { int y; @@ -1016,7 +1315,7 @@ void rt_initcols (BYTE *buff) void R_DrawColumnHorizP_C (void) { int count = dc_count; - BYTE *dest; + canvas_pixel_t *dest; fixed_t fracstep; fixed_t frac; @@ -1077,7 +1376,7 @@ void R_FillColumnHorizP (void) { int count = dc_count; BYTE color = dc_color; - BYTE *dest; + canvas_pixel_t *dest; if (count <= 0) return; diff --git a/src/r_main.cpp b/src/r_main.cpp index ce4841a2e..04e798981 100644 --- a/src/r_main.cpp +++ b/src/r_main.cpp @@ -578,7 +578,7 @@ void R_HighlightPortal (PortalDrawseg* pds) BYTE color = (BYTE)BestColor((DWORD *)GPalette.BaseColors, 255, 0, 0, 0, 255); - BYTE* pixels = RenderTarget->GetBuffer(); + canvas_pixel_t* pixels = RenderTarget->GetBuffer(); // top edge for (int x = pds->x1; x < pds->x2; x++) { @@ -623,7 +623,7 @@ void R_EnterPortal (PortalDrawseg* pds, int depth) int Ytop = pds->ceilingclip[x-pds->x1]; int Ybottom = pds->floorclip[x-pds->x1]; - BYTE *dest = RenderTarget->GetBuffer() + x + Ytop * spacing; + canvas_pixel_t *dest = RenderTarget->GetBuffer() + x + Ytop * spacing; for (int y = Ytop; y <= Ybottom; y++) { @@ -794,10 +794,10 @@ void R_EnterPortal (PortalDrawseg* pds, int depth) void R_SetupBuffer () { - static BYTE *lastbuff = NULL; + static canvas_pixel_t *lastbuff = NULL; int pitch = RenderTarget->GetPitch(); - BYTE *lineptr = RenderTarget->GetBuffer() + viewwindowy*pitch + viewwindowx; + canvas_pixel_t *lineptr = RenderTarget->GetBuffer() + viewwindowy*pitch + viewwindowx; if (dc_pitch != pitch || lineptr != lastbuff) { diff --git a/src/r_main.h b/src/r_main.h index 24103393d..37a41a763 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -82,6 +82,34 @@ extern bool r_dontmaplines; // Change R_CalcTiltedLighting() when this changes. #define GETPALOOKUP(vis,shade) (clamp (((shade)-FLOAT2FIXED(MIN(MAXLIGHTVIS,double(vis))))>>FRACBITS, 0, NUMCOLORMAPS-1)) +// Calculate the light multiplier for ds_light +// This is used instead of GETPALOOKUP when ds_colormap+dc_colormap is set to the base colormap +#define LIGHTSCALE(vis,shade) ((shade)-FLOAT2FIXED(MIN(MAXLIGHTVIS,double(vis)))) + +#ifndef PALETTEOUTPUT + +// calculates the light constant passed to the shade_pal_index function +inline uint32_t calc_light_multiplier(dsfixed_t light) +{ + // the 0.70 multiplier shouldn't be needed - maybe the palette shades in doom weren't linear? + return (uint32_t)clamp((1.0 - FIXED2DBL(light) / MAXLIGHTVIS * 0.70) * 256 + 0.5, 0.0, 256.0); +} + +// Calculates a ARGB8 color for the given palette index and light multiplier +inline uint32_t shade_pal_index(uint32_t index, uint32_t light) +{ + const PalEntry &color = GPalette.BaseColors[index]; + uint32_t red = color.r; + uint32_t green = color.g; + uint32_t blue = color.b; + red = red * light / 256; + green = green * light / 256; + blue = blue * light / 256; + return 0xff000000 | (red << 16) | (green << 8) | blue; +} + +#endif + extern double GlobVis; void R_SetVisibility(double visibility); diff --git a/src/r_plane.cpp b/src/r_plane.cpp index d749319e3..b385302e5 100644 --- a/src/r_plane.cpp +++ b/src/r_plane.cpp @@ -227,8 +227,14 @@ void R_MapPlane (int y, int x1) if (plane_shade) { // Determine lighting based on the span's distance from the viewer. +#ifndef PALETTEOUTPUT + ds_colormap = basecolormap->Maps; + ds_light = LIGHTSCALE(GlobVis * fabs(CenterY - y), planeshade); +#else ds_colormap = basecolormap->Maps + (GETPALOOKUP ( GlobVis * fabs(CenterY - y), planeshade) << COLORMAPSHIFT); + ds_light = 0; +#endif } #ifdef X86_ASM @@ -360,7 +366,7 @@ void R_MapTiltedPlane (int y, int x1) int x2 = spanend[y]; int width = x2 - x1; double iz, uz, vz; - BYTE *fb; + canvas_pixel_t *fb; DWORD u, v; int i; @@ -393,6 +399,7 @@ void R_MapTiltedPlane (int y, int x1) u = SQWORD(uz*z) + pviewx; v = SQWORD(vz*z) + pviewy; ds_colormap = tiltlighting[i]; + ds_light = 0; fb[i++] = ds_colormap[ds_source[(v >> vshift) | ((u >> ushift) & umask)]]; iz += plane_sz[0]; uz += plane_su[0]; @@ -486,7 +493,16 @@ void R_MapTiltedPlane (int y, int x1) void R_MapColoredPlane (int y, int x1) { - memset (ylookup[y] + x1 + dc_destorg, ds_color, spanend[y] - x1 + 1); +#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 } //========================================================================== @@ -1462,11 +1478,13 @@ void R_DrawSkyPlane (visplane_t *pl) if (fixedcolormap) { dc_colormap = fixedcolormap; + dc_light = 0; } else { fakefixed = true; fixedcolormap = dc_colormap = NormalLight.Maps; + dc_light = 0; } R_DrawSky (pl); @@ -1547,6 +1565,7 @@ void R_DrawNormalPlane (visplane_t *pl, double _xscale, double _yscale, fixed_t planeheight = fabs(pl->height.Zat0() - ViewPos.Z); GlobVis = r_FloorVisibility / planeheight; + ds_light = 0; if (fixedlightlev >= 0) ds_colormap = basecolormap->Maps + fixedlightlev, plane_shade = false; else if (fixedcolormap) @@ -1707,6 +1726,7 @@ void R_DrawTiltedPlane (visplane_t *pl, double _xscale, double _yscale, fixed_t if (pl->height.fC() > 0) planelightfloat = -planelightfloat; + ds_light = 0; if (fixedlightlev >= 0) ds_colormap = basecolormap->Maps + fixedlightlev, plane_shade = false; else if (fixedcolormap) diff --git a/src/r_segs.cpp b/src/r_segs.cpp index 4eb3cb440..1cdb78555 100644 --- a/src/r_segs.cpp +++ b/src/r_segs.cpp @@ -178,6 +178,7 @@ static void BlastMaskedColumn (void (*blastfunc)(const BYTE *pixels, const FText if (fixedcolormap == NULL && fixedlightlev < 0) { dc_colormap = basecolormap->Maps + (GETPALOOKUP (rw_light, wallshade) << COLORMAPSHIFT); + dc_light = 0; } dc_iscale = xs_Fix<16>::ToFix(MaskedSWall[dc_x] * MaskedScaleY); @@ -316,6 +317,7 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2) dc_colormap = basecolormap->Maps + fixedlightlev; else if (fixedcolormap != NULL) dc_colormap = fixedcolormap; + dc_light = 0; // find positioning texheight = tex->GetScaledHeightDouble(); @@ -633,6 +635,7 @@ void R_RenderFakeWall(drawseg_t *ds, int x1, int x2, F3DFloor *rover) dc_colormap = basecolormap->Maps + fixedlightlev; else if (fixedcolormap != NULL) dc_colormap = fixedcolormap; + dc_light = 0; WallC.sz1 = ds->sz1; WallC.sz2 = ds->sz2; @@ -1066,10 +1069,11 @@ void R_RenderFakeWallRange (drawseg_t *ds, int x1, int x2) } // prevlineasm1 is like vlineasm1 but skips the loop if only drawing one pixel -inline fixed_t prevline1 (fixed_t vince, BYTE *colormap, int count, fixed_t vplce, const BYTE *bufplce, BYTE *dest) +inline fixed_t prevline1 (fixed_t vince, BYTE *colormap, fixed_t light, int count, fixed_t vplce, const BYTE *bufplce, canvas_pixel_t *dest) { dc_iscale = vince; dc_colormap = colormap; + dc_light = light; dc_count = count; dc_texturefrac = vplce; dc_source = bufplce; @@ -1117,6 +1121,10 @@ void wallscan (int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *l palookupoffse[1] = dc_colormap; palookupoffse[2] = dc_colormap; palookupoffse[3] = dc_colormap; + palookuplight[0] = 0; + palookuplight[1] = 0; + palookuplight[2] = 0; + palookuplight[3] = 0; } for(; (x < x2) && (x & 3); ++x) @@ -1130,7 +1138,13 @@ void wallscan (int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *l if (!fixed) { // calculate lighting +#ifndef PALETTEOUTPUT + dc_colormap = basecolormapdata; + dc_light = LIGHTSCALE(light, wallshade); +#else dc_colormap = basecolormapdata + (GETPALOOKUP (light, wallshade) << COLORMAPSHIFT); + dc_light = 0; +#endif } dc_source = getcol (rw_pic, (lwal[x] + xoffset) >> FRACBITS); @@ -1170,7 +1184,13 @@ void wallscan (int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *l for (z = 0; z < 4; ++z) { light += rw_lightstep; - palookupoffse[z] = basecolormapdata + (GETPALOOKUP (light, wallshade) << COLORMAPSHIFT); +#ifndef PALETTEOUTPUT + palookupoffse[z] = basecolormapdata; + palookuplight[z] = LIGHTSCALE(light, wallshade); +#else + palookupoffse[z] = basecolormapdata + (GETPALOOKUP(12/*light*/, wallshade) << COLORMAPSHIFT); + palookuplight[z] = 0; +#endif } } @@ -1183,7 +1203,7 @@ void wallscan (int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *l { if (!(bad & 1)) { - prevline1(vince[z],palookupoffse[z],y2ve[z]-y1ve[z],vplce[z],bufplce[z],ylookup[y1ve[z]]+x+z+dc_destorg); + prevline1(vince[z],palookupoffse[z],palookuplight[z],y2ve[z]-y1ve[z],vplce[z],bufplce[z],ylookup[y1ve[z]]+x+z+dc_destorg); } bad >>= 1; } @@ -1194,7 +1214,7 @@ void wallscan (int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *l { if (u4 > y1ve[z]) { - vplce[z] = prevline1(vince[z],palookupoffse[z],u4-y1ve[z],vplce[z],bufplce[z],ylookup[y1ve[z]]+x+z+dc_destorg); + vplce[z] = prevline1(vince[z],palookupoffse[z], palookuplight[z],u4-y1ve[z],vplce[z],bufplce[z],ylookup[y1ve[z]]+x+z+dc_destorg); } } @@ -1205,12 +1225,12 @@ void wallscan (int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *l dovline4(); } - BYTE *i = x+ylookup[d4]+dc_destorg; + canvas_pixel_t *i = x+ylookup[d4]+dc_destorg; for (z = 0; z < 4; ++z) { if (y2ve[z] > d4) { - prevline1(vince[z],palookupoffse[0],y2ve[z]-d4,vplce[z],bufplce[z],i+z); + prevline1(vince[z],palookupoffse[0],palookuplight[0],y2ve[z]-d4,vplce[z],bufplce[z],i+z); } } } @@ -1225,7 +1245,13 @@ void wallscan (int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *l if (!fixed) { // calculate lighting +#ifndef PALETTEOUTPUT + dc_colormap = basecolormapdata; + dc_light = LIGHTSCALE(light, wallshade); +#else dc_colormap = basecolormapdata + (GETPALOOKUP (light, wallshade) << COLORMAPSHIFT); + dc_light = 0; +#endif } dc_source = getcol (rw_pic, (lwal[x] + xoffset) >> FRACBITS); @@ -1416,10 +1442,11 @@ static void wallscan_np2_ds(drawseg_t *ds, int x1, int x2, short *uwal, short *d } } -inline fixed_t mvline1 (fixed_t vince, BYTE *colormap, int count, fixed_t vplce, const BYTE *bufplce, BYTE *dest) +inline fixed_t mvline1 (fixed_t vince, BYTE *colormap, int count, fixed_t vplce, const BYTE *bufplce, canvas_pixel_t *dest) { dc_iscale = vince; dc_colormap = colormap; + dc_light = 0; dc_count = count; dc_texturefrac = vplce; dc_source = bufplce; @@ -1431,7 +1458,7 @@ void maskwallscan (int x1, int x2, short *uwal, short *dwal, float *swal, fixed_ double yrepeat, const BYTE *(*getcol)(FTexture *tex, int x)) { int x, fracbits; - BYTE *p; + canvas_pixel_t *p; int y1ve[4], y2ve[4], u4, d4, startx, dax, z; char bad; float light = rw_light - rw_lightstep; @@ -1471,7 +1498,7 @@ void maskwallscan (int x1, int x2, short *uwal, short *dwal, float *swal, fixed_ palookupoffse[3] = dc_colormap; } - for(; (x < x2) && ((size_t)p & 3); ++x, ++p) + for(; (x < x2) && (((size_t)p/sizeof(canvas_pixel_t)) & 3); ++x, ++p) { light += rw_lightstep; y1ve[0] = uwal[x];//max(uwal[x],umost[x]); @@ -1481,6 +1508,7 @@ void maskwallscan (int x1, int x2, short *uwal, short *dwal, float *swal, fixed_ if (!fixed) { // calculate lighting dc_colormap = basecolormapdata + (GETPALOOKUP (light, wallshade) << COLORMAPSHIFT); + dc_light = 0; } dc_source = getcol (rw_pic, (lwal[x] + xoffset) >> FRACBITS); @@ -1553,7 +1581,7 @@ void maskwallscan (int x1, int x2, short *uwal, short *dwal, float *swal, fixed_ domvline4(); } - BYTE *i = p+ylookup[d4]; + canvas_pixel_t *i = p+ylookup[d4]; for (z = 0; z < 4; ++z) { if (y2ve[z] > d4) @@ -1572,6 +1600,7 @@ void maskwallscan (int x1, int x2, short *uwal, short *dwal, float *swal, fixed_ if (!fixed) { // calculate lighting dc_colormap = basecolormapdata + (GETPALOOKUP (light, wallshade) << COLORMAPSHIFT); + dc_light = 0; } dc_source = getcol (rw_pic, (lwal[x] + xoffset) >> FRACBITS); @@ -1589,10 +1618,11 @@ void maskwallscan (int x1, int x2, short *uwal, short *dwal, float *swal, fixed_ NetUpdate (); } -inline void preptmvline1 (fixed_t vince, BYTE *colormap, int count, fixed_t vplce, const BYTE *bufplce, BYTE *dest) +inline void preptmvline1 (fixed_t vince, BYTE *colormap, fixed_t light, int count, fixed_t vplce, const BYTE *bufplce, canvas_pixel_t *dest) { dc_iscale = vince; dc_colormap = colormap; + dc_light = light; dc_count = count; dc_texturefrac = vplce; dc_source = bufplce; @@ -1605,7 +1635,7 @@ void transmaskwallscan (int x1, int x2, short *uwal, short *dwal, float *swal, f fixed_t (*tmvline1)(); void (*tmvline4)(); int x, fracbits; - BYTE *p; + canvas_pixel_t *p; int y1ve[4], y2ve[4], u4, d4, startx, dax, z; char bad; float light = rw_light - rw_lightstep; @@ -1645,9 +1675,13 @@ void transmaskwallscan (int x1, int x2, short *uwal, short *dwal, float *swal, f palookupoffse[1] = dc_colormap; palookupoffse[2] = dc_colormap; palookupoffse[3] = dc_colormap; + palookuplight[0] = 0; + palookuplight[1] = 0; + palookuplight[2] = 0; + palookuplight[3] = 0; } - for(; (x < x2) && ((size_t)p & 3); ++x, ++p) + for(; (x < x2) && (((size_t)p / sizeof(canvas_pixel_t)) & 3); ++x, ++p) { light += rw_lightstep; y1ve[0] = uwal[x];//max(uwal[x],umost[x]); @@ -1656,7 +1690,13 @@ void transmaskwallscan (int x1, int x2, short *uwal, short *dwal, float *swal, f if (!fixed) { // calculate lighting +#ifndef PALETTEOUTPUT + dc_colormap = basecolormapdata; + dc_light = LIGHTSCALE(light, wallshade); +#else dc_colormap = basecolormapdata + (GETPALOOKUP (light, wallshade) << COLORMAPSHIFT); + dc_light = 0; +#endif } dc_source = getcol (rw_pic, (lwal[x] + xoffset) >> FRACBITS); @@ -1694,7 +1734,12 @@ void transmaskwallscan (int x1, int x2, short *uwal, short *dwal, float *swal, f for (z = 0; z < 4; ++z) { light += rw_lightstep; +#ifndef PALETTEOUTPUT + palookupoffse[z] = basecolormapdata; + palookuplight[z] = LIGHTSCALE(light, wallshade); +#else palookupoffse[z] = basecolormapdata + (GETPALOOKUP (light, wallshade) << COLORMAPSHIFT); +#endif } } @@ -1707,7 +1752,7 @@ void transmaskwallscan (int x1, int x2, short *uwal, short *dwal, float *swal, f { if (!(bad & 1)) { - preptmvline1(vince[z],palookupoffse[z],y2ve[z]-y1ve[z],vplce[z],bufplce[z],ylookup[y1ve[z]]+p+z); + preptmvline1(vince[z],palookupoffse[z],palookuplight[z],y2ve[z]-y1ve[z],vplce[z],bufplce[z],ylookup[y1ve[z]]+p+z); tmvline1(); } bad >>= 1; @@ -1719,7 +1764,7 @@ void transmaskwallscan (int x1, int x2, short *uwal, short *dwal, float *swal, f { if (u4 > y1ve[z]) { - preptmvline1(vince[z],palookupoffse[z],u4-y1ve[z],vplce[z],bufplce[z],ylookup[y1ve[z]]+p+z); + preptmvline1(vince[z],palookupoffse[z],palookuplight[z],u4-y1ve[z],vplce[z],bufplce[z],ylookup[y1ve[z]]+p+z); vplce[z] = tmvline1(); } } @@ -1731,12 +1776,12 @@ void transmaskwallscan (int x1, int x2, short *uwal, short *dwal, float *swal, f tmvline4(); } - BYTE *i = p+ylookup[d4]; + canvas_pixel_t *i = p+ylookup[d4]; for (z = 0; z < 4; ++z) { if (y2ve[z] > d4) { - preptmvline1(vince[z],palookupoffse[0],y2ve[z]-d4,vplce[z],bufplce[z],i+z); + preptmvline1(vince[z],palookupoffse[0],palookuplight[0],y2ve[z]-d4,vplce[z],bufplce[z],i+z); tmvline1(); } } @@ -1750,7 +1795,13 @@ void transmaskwallscan (int x1, int x2, short *uwal, short *dwal, float *swal, f if (!fixed) { // calculate lighting - dc_colormap = basecolormapdata + (GETPALOOKUP (light, wallshade) << COLORMAPSHIFT); +#ifndef PALETTEOUTPUT + dc_colormap = basecolormapdata; + dc_light = LIGHTSCALE(light, wallshade); +#else + dc_colormap = basecolormapdata + (GETPALOOKUP(light, wallshade) << COLORMAPSHIFT); + dc_light = 0; +#endif } dc_source = getcol (rw_pic, (lwal[x] + xoffset) >> FRACBITS); @@ -1791,6 +1842,7 @@ void R_RenderSegLoop () dc_colormap = basecolormap->Maps + fixedlightlev; else if (fixedcolormap != NULL) dc_colormap = fixedcolormap; + dc_light = 0; // clip wall to the floor and ceiling for (x = x1; x < x2; ++x) @@ -3194,6 +3246,7 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper, dc_colormap = usecolormap->Maps; else calclighting = true; + dc_light = 0; // Draw it if (decal->RenderFlags & RF_YFLIP) @@ -3242,7 +3295,13 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper, { if (calclighting) { // calculate lighting +#ifndef PALETTEOUTPUT + dc_colormap = usecolormap->Maps; + dc_light = LIGHTSCALE(rw_light, wallshade); +#else dc_colormap = usecolormap->Maps + (GETPALOOKUP (rw_light, wallshade) << COLORMAPSHIFT); + dc_light = 0; +#endif } R_WallSpriteColumn (R_DrawMaskedColumn); dc_x++; @@ -3252,7 +3311,13 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper, { if (calclighting) { // calculate lighting +#ifndef PALETTEOUTPUT + dc_colormap = usecolormap->Maps; + dc_light = LIGHTSCALE(rw_light, wallshade); +#else dc_colormap = usecolormap->Maps + (GETPALOOKUP (rw_light, wallshade) << COLORMAPSHIFT); + dc_light = 0; +#endif } rt_initcols(); for (int zz = 4; zz; --zz) @@ -3267,7 +3332,13 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper, { if (calclighting) { // calculate lighting +#ifndef PALETTEOUTPUT + dc_colormap = usecolormap->Maps; + dc_light = LIGHTSCALE(rw_light, wallshade); +#else dc_colormap = usecolormap->Maps + (GETPALOOKUP (rw_light, wallshade) << COLORMAPSHIFT); + dc_light = 0; +#endif } R_WallSpriteColumn (R_DrawMaskedColumn); dc_x++; diff --git a/src/r_swrenderer.cpp b/src/r_swrenderer.cpp index 07edf25e9..433007acb 100644 --- a/src/r_swrenderer.cpp +++ b/src/r_swrenderer.cpp @@ -182,6 +182,7 @@ void FSoftwareRenderer::RemapVoxels() void FSoftwareRenderer::WriteSavePic (player_t *player, FILE *file, int width, int height) { +#ifdef PALETTEOUTPUT DCanvas *pic = new DSimpleCanvas (width, height); PalEntry palette[256]; @@ -195,6 +196,7 @@ void FSoftwareRenderer::WriteSavePic (player_t *player, FILE *file, int width, i pic->Destroy(); pic->ObjectFlags |= OF_YesReallyDelete; delete pic; +#endif } //=========================================================================== @@ -311,6 +313,7 @@ void FSoftwareRenderer::CopyStackedViewParameters() void FSoftwareRenderer::RenderTextureView (FCanvasTexture *tex, AActor *viewpoint, int fov) { +#ifdef PALETTEOUTPUT BYTE *Pixels = const_cast(tex->GetPixels()); DSimpleCanvas *Canvas = tex->GetCanvas(); @@ -334,6 +337,7 @@ void FSoftwareRenderer::RenderTextureView (FCanvasTexture *tex, AActor *viewpoin tex->SetUpdated(); fixedcolormap = savecolormap; realfixedcolormap = savecm; +#endif } //========================================================================== diff --git a/src/r_things.cpp b/src/r_things.cpp index 427e61b06..0e55b45f9 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -132,7 +132,7 @@ EXTERN_CVAR (Bool, r_drawvoxels) // int OffscreenBufferWidth, OffscreenBufferHeight; -BYTE *OffscreenColorBuffer; +canvas_pixel_t *OffscreenColorBuffer; FCoverageBuffer *OffscreenCoverageBuffer; // @@ -408,6 +408,7 @@ void R_DrawVisSprite (vissprite_t *vis) fixed_t centeryfrac = FLOAT2FIXED(CenterY); dc_colormap = vis->Style.colormap; + dc_light = 0; mode = R_SetPatchStyle (vis->Style.RenderStyle, vis->Style.Alpha, vis->Translation, vis->FillColor); @@ -544,6 +545,7 @@ void R_DrawWallSprite(vissprite_t *spr) dc_colormap = usecolormap->Maps; else calclighting = true; + dc_light = 0; // Draw it WallSpriteTile = spr->pic; @@ -592,7 +594,13 @@ void R_DrawWallSprite(vissprite_t *spr) { if (calclighting) { // calculate lighting +#ifndef PALETTEOUTPUT + dc_colormap = usecolormap->Maps; + dc_light = LIGHTSCALE(rw_light, shade); +#else dc_colormap = usecolormap->Maps + (GETPALOOKUP (rw_light, shade) << COLORMAPSHIFT); + dc_light = FLOAT2FIXED(MAXLIGHTVIS); +#endif } if (!R_ClipSpriteColumnWithPortals(spr)) R_WallSpriteColumn(R_DrawMaskedColumn); @@ -603,7 +611,13 @@ void R_DrawWallSprite(vissprite_t *spr) { if (calclighting) { // calculate lighting +#ifndef PALETTEOUTPUT + dc_colormap = usecolormap->Maps; + dc_light = LIGHTSCALE(rw_light, shade); +#else dc_colormap = usecolormap->Maps + (GETPALOOKUP (rw_light, shade) << COLORMAPSHIFT); + dc_light = FLOAT2FIXED(MAXLIGHTVIS); +#endif } rt_initcols(); for (int zz = 4; zz; --zz) @@ -619,7 +633,13 @@ void R_DrawWallSprite(vissprite_t *spr) { if (calclighting) { // calculate lighting +#ifndef PALETTEOUTPUT + dc_colormap = usecolormap->Maps; + dc_light = LIGHTSCALE(rw_light, shade); +#else dc_colormap = usecolormap->Maps + (GETPALOOKUP (rw_light, shade) << COLORMAPSHIFT); + dc_light = FLOAT2FIXED(MAXLIGHTVIS); +#endif } if (!R_ClipSpriteColumnWithPortals(spr)) R_WallSpriteColumn(R_DrawMaskedColumn); @@ -654,6 +674,7 @@ void R_DrawVisVoxel(vissprite_t *spr, int minslabz, int maxslabz, short *cliptop // Do setup for blending. dc_colormap = spr->Style.colormap; + dc_light = 0; mode = R_SetPatchStyle(spr->Style.RenderStyle, spr->Style.Alpha, spr->Translation, spr->FillColor); if (mode == DontDraw) @@ -2598,10 +2619,8 @@ static void R_DrawMaskedSegsBehindParticle (const vissprite_t *vis) void R_DrawParticle (vissprite_t *vis) { - DWORD *bg2rgb; int spacing; - BYTE *dest; - DWORD fg; + canvas_pixel_t *dest; BYTE color = vis->Style.colormap[vis->startfrac]; int yl = vis->y1; int ycount = vis->y2 - yl + 1; @@ -2610,6 +2629,47 @@ 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; + // vis->renderflags holds translucency level (0-255) { fixed_t fglevel, bglevel; @@ -2659,6 +2719,7 @@ void R_DrawParticle (vissprite_t *vis) dest += spacing; } } +#endif } extern double BaseYaspectMul;; @@ -3189,12 +3250,12 @@ void R_CheckOffscreenBuffer(int width, int height, bool spansonly) { if (OffscreenColorBuffer == NULL) { - OffscreenColorBuffer = new BYTE[width * height]; + OffscreenColorBuffer = new canvas_pixel_t[width * height]; } else if (OffscreenBufferWidth != width || OffscreenBufferHeight != height) { delete[] OffscreenColorBuffer; - OffscreenColorBuffer = new BYTE[width * height]; + OffscreenColorBuffer = new canvas_pixel_t[width * height]; } } OffscreenBufferWidth = width; diff --git a/src/textures/canvastexture.cpp b/src/textures/canvastexture.cpp index 062c3af1d..7388c1306 100644 --- a/src/textures/canvastexture.cpp +++ b/src/textures/canvastexture.cpp @@ -106,6 +106,10 @@ void FCanvasTexture::MakeTexture () Canvas = new DSimpleCanvas (Width, Height); Canvas->Lock (); GC::AddSoftRoot(Canvas); +#ifndef PALETTEOUTPUT + Pixels = new BYTE[Width*Height]; + bPixelsAllocated = true; +#else if (Width != Height || Width != Canvas->GetPitch()) { Pixels = new BYTE[Width*Height]; @@ -116,6 +120,7 @@ void FCanvasTexture::MakeTexture () Pixels = Canvas->GetBuffer(); bPixelsAllocated = false; } +#endif // Draw a special "unrendered" initial texture into the buffer. memset (Pixels, 0, Width*Height/2); memset (Pixels+Width*Height/2, 255, Width*Height/2); diff --git a/src/v_draw.cpp b/src/v_draw.cpp index c7b62b0a6..fd14b5e0a 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -166,16 +166,18 @@ void DCanvas::DrawTextureParms(FTexture *img, DrawParms &parms) if (translation != NULL) { dc_colormap = (lighttable_t *)translation; + dc_light = 0; } else { dc_colormap = identitymap; + dc_light = 0; } fixedcolormap = dc_colormap; ESPSResult mode = R_SetPatchStyle (parms.style, parms.Alpha, 0, parms.fillcolor); - BYTE *destorgsave = dc_destorg; + canvas_pixel_t *destorgsave = dc_destorg; dc_destorg = screen->GetBuffer(); if (dc_destorg == NULL) { @@ -1015,13 +1017,32 @@ void DCanvas::PUTTRANSDOT (int xx, int yy, int basecolor, int level) oldyyshifted = yy * GetPitch(); } - BYTE *spot = GetBuffer() + oldyyshifted + xx; +#ifndef PALETTEOUTPUT + canvas_pixel_t *spot = GetBuffer() + oldyyshifted + xx; + + uint32_t fg = shade_pal_index(basecolor, calc_light_multiplier(0)); + uint32_t fg_red = (fg >> 16) & 0xff; + uint32_t fg_green = (fg >> 8) & 0xff; + uint32_t fg_blue = fg & 0xff; + + uint32_t bg_red = (*spot >> 16) & 0xff; + uint32_t bg_green = (*spot >> 8) & 0xff; + uint32_t bg_blue = (*spot) & 0xff; + + uint32_t red = (fg_red + bg_red + 1) / 2; + uint32_t green = (fg_green + bg_green + 1) / 2; + uint32_t blue = (fg_blue + bg_blue + 1) / 2; + + *spot = 0xff000000 | (red << 16) | (green << 8) | blue; +#else + canvas_pixel_t *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)]; +#endif } void DCanvas::DrawLine(int x0, int y0, int x1, int y1, int palColor, uint32 realcolor) @@ -1069,7 +1090,7 @@ void DCanvas::DrawLine(int x0, int y0, int x1, int y1, int palColor, uint32 real } else if (deltaX == 0) { // vertical line - BYTE *spot = GetBuffer() + y0*GetPitch() + x0; + canvas_pixel_t *spot = GetBuffer() + y0*GetPitch() + x0; int pitch = GetPitch (); do { @@ -1079,7 +1100,7 @@ void DCanvas::DrawLine(int x0, int y0, int x1, int y1, int palColor, uint32 real } else if (deltaX == deltaY) { // diagonal line. - BYTE *spot = GetBuffer() + y0*GetPitch() + x0; + canvas_pixel_t *spot = GetBuffer() + y0*GetPitch() + x0; int advance = GetPitch() + xDir; do { @@ -1205,7 +1226,7 @@ void DCanvas::DrawPixel(int x, int y, int palColor, uint32 realcolor) void DCanvas::Clear (int left, int top, int right, int bottom, int palcolor, uint32 color) { int x, y; - BYTE *dest; + canvas_pixel_t *dest; if (left == right || top == bottom) { @@ -1426,11 +1447,11 @@ void DCanvas::FillSimplePoly(FTexture *tex, FVector2 *points, int npoints, // V_DrawBlock // Draw a linear block of pixels into the view buffer. // -void DCanvas::DrawBlock (int x, int y, int _width, int _height, const BYTE *src) const +void DCanvas::DrawBlock (int x, int y, int _width, int _height, const canvas_pixel_t *src) const { int srcpitch = _width; int destpitch; - BYTE *dest; + canvas_pixel_t *dest; if (ClipBox (x, y, _width, _height, src, srcpitch)) { @@ -1442,7 +1463,7 @@ void DCanvas::DrawBlock (int x, int y, int _width, int _height, const BYTE *src) do { - memcpy (dest, src, _width); + memcpy (dest, src, _width * sizeof(canvas_pixel_t)); src += srcpitch; dest += destpitch; } while (--_height); @@ -1452,9 +1473,9 @@ void DCanvas::DrawBlock (int x, int y, int _width, int _height, const BYTE *src) // V_GetBlock // Gets a linear block of pixels from the view buffer. // -void DCanvas::GetBlock (int x, int y, int _width, int _height, BYTE *dest) const +void DCanvas::GetBlock (int x, int y, int _width, int _height, canvas_pixel_t *dest) const { - const BYTE *src; + const canvas_pixel_t *src; #ifdef RANGECHECK if (x<0 @@ -1470,14 +1491,14 @@ void DCanvas::GetBlock (int x, int y, int _width, int _height, BYTE *dest) const while (_height--) { - memcpy (dest, src, _width); + memcpy (dest, src, _width * sizeof(canvas_pixel_t)); src += Pitch; dest += _width; } } // Returns true if the box was completely clipped. False otherwise. -bool DCanvas::ClipBox (int &x, int &y, int &w, int &h, const BYTE *&src, const int srcpitch) const +bool DCanvas::ClipBox (int &x, int &y, int &w, int &h, const canvas_pixel_t *&src, const int srcpitch) const { if (x >= Width || y >= Height || x+w <= 0 || y+h <= 0) { // Completely clipped off screen diff --git a/src/v_video.cpp b/src/v_video.cpp index 01a73950b..b6a626753 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -343,10 +343,8 @@ 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; + canvas_pixel_t *spot; int x, y; if (x1 >= Width || y1 >= Height) @@ -366,6 +364,43 @@ void DCanvas::Dim (PalEntry color, float damount, int x1, int y1, int w, int h) return; } + spot = Buffer + x1 + y1*Pitch; + gap = Pitch - w; + +#ifndef PALETTEOUTPUT + uint32_t fg = color.d; + uint32_t fg_red = (fg >> 16) & 0xff; + uint32_t fg_green = (fg >> 8) & 0xff; + uint32_t fg_blue = fg & 0xff; + + uint32_t alpha = (uint32_t)clamp(damount * 256 + 0.5f, 0.0f, 256.0f); + uint32_t inv_alpha = 256 - alpha; + + fg_red *= alpha; + fg_green *= alpha; + fg_blue *= alpha; + + for (y = h; y != 0; y--) + { + for (x = w; x != 0; x--) + { + uint32_t bg_red = (*spot >> 16) & 0xff; + uint32_t bg_green = (*spot >> 8) & 0xff; + uint32_t bg_blue = (*spot) & 0xff; + + uint32_t red = (fg_red + bg_red * inv_alpha) / 256; + uint32_t green = (fg_green + bg_green * inv_alpha) / 256; + uint32_t blue = (fg_blue + bg_blue * inv_alpha) / 256; + + *spot = 0xff000000 | (red << 16) | (green << 8) | blue; + spot++; + } + spot += gap; + } +#else + DWORD *bg2rgb; + DWORD fg; + { int amount; @@ -377,8 +412,6 @@ void DCanvas::Dim (PalEntry color, float damount, int x1, int y1, int w, int h) (((color.b * amount) >> 4) << 10); } - spot = Buffer + x1 + y1*Pitch; - gap = Pitch - w; for (y = h; y != 0; y--) { for (x = w; x != 0; x--) @@ -392,6 +425,7 @@ void DCanvas::Dim (PalEntry color, float damount, int x1, int y1, int w, int h) } spot += gap; } +#endif } //========================================================================== @@ -403,7 +437,7 @@ void DCanvas::Dim (PalEntry color, float damount, int x1, int y1, int w, int h) // //========================================================================== -void DCanvas::GetScreenshotBuffer(const BYTE *&buffer, int &pitch, ESSType &color_type) +void DCanvas::GetScreenshotBuffer(const canvas_pixel_t *&buffer, int &pitch, ESSType &color_type) { Lock(true); buffer = GetBuffer(); @@ -759,8 +793,8 @@ DSimpleCanvas::DSimpleCanvas (int width, int height) Pitch = width + MAX(0, CPU.DataL1LineSize - 8); } } - MemBuffer = new BYTE[Pitch * height]; - memset (MemBuffer, 0, Pitch * height); + MemBuffer = new canvas_pixel_t[Pitch * height]; + memset (MemBuffer, 0, Pitch * height * sizeof(canvas_pixel_t)); } //========================================================================== @@ -879,7 +913,7 @@ void DFrameBuffer::DrawRateStuff () { int i = I_GetTime(false); int tics = i - LastTic; - BYTE *buffer = GetBuffer(); + canvas_pixel_t *buffer = GetBuffer(); LastTic = i; if (tics > 20) tics = 20; diff --git a/src/v_video.h b/src/v_video.h index fa1ce83df..27c09ee36 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -189,7 +189,7 @@ public: virtual ~DCanvas (); // Member variable access - inline BYTE *GetBuffer () const { return Buffer; } + inline canvas_pixel_t *GetBuffer () const { return Buffer; } inline int GetWidth () const { return Width; } inline int GetHeight () const { return Height; } inline int GetPitch () const { return Pitch; } @@ -202,10 +202,10 @@ public: virtual bool IsLocked () { return Buffer != NULL; } // Returns true if the surface is locked // Draw a linear block of pixels into the canvas - virtual void DrawBlock (int x, int y, int width, int height, const BYTE *src) const; + virtual void DrawBlock (int x, int y, int width, int height, const canvas_pixel_t *src) const; // Reads a linear block of pixels into the view buffer. - virtual void GetBlock (int x, int y, int width, int height, BYTE *dest) const; + virtual void GetBlock (int x, int y, int width, int height, canvas_pixel_t *dest) const; // Dim the entire canvas for the menus virtual void Dim (PalEntry color = 0); @@ -237,7 +237,7 @@ public: // Retrieves a buffer containing image data for a screenshot. // Hint: Pitch can be negative for upside-down images, in which case buffer // points to the last row in the buffer, which will be the first row output. - virtual void GetScreenshotBuffer(const BYTE *&buffer, int &pitch, ESSType &color_type); + virtual void GetScreenshotBuffer(const canvas_pixel_t *&buffer, int &pitch, ESSType &color_type); // Releases the screenshot buffer. virtual void ReleaseScreenshotBuffer(); @@ -262,13 +262,13 @@ public: void DrawChar (FFont *font, int normalcolor, int x, int y, BYTE character, int tag_first, ...); protected: - BYTE *Buffer; + canvas_pixel_t *Buffer; int Width; int Height; int Pitch; int LockCount; - bool ClipBox (int &left, int &top, int &width, int &height, const BYTE *&src, const int srcpitch) const; + bool ClipBox (int &left, int &top, int &width, int &height, const canvas_pixel_t *&src, const int srcpitch) const; void DrawTextureV(FTexture *img, double x, double y, uint32 tag, va_list tags) = delete; virtual void DrawTextureParms(FTexture *img, DrawParms &parms); bool ParseDrawTextureTags (FTexture *img, double x, double y, uint32 tag, va_list tags, DrawParms *parms, bool fortext) const; @@ -297,7 +297,7 @@ public: void Unlock (); protected: - BYTE *MemBuffer; + canvas_pixel_t *MemBuffer; DSimpleCanvas() {} }; diff --git a/src/win32/fb_d3d9.cpp b/src/win32/fb_d3d9.cpp index efdced151..14a78d4cd 100644 --- a/src/win32/fb_d3d9.cpp +++ b/src/win32/fb_d3d9.cpp @@ -765,14 +765,20 @@ void D3DFB::KillNativeTexs() bool D3DFB::CreateFBTexture () { - if (FAILED(D3DDevice->CreateTexture(Width, Height, 1, D3DUSAGE_DYNAMIC, D3DFMT_L8, D3DPOOL_DEFAULT, &FBTexture, NULL))) +#ifndef PALETTEOUTPUT + D3DFORMAT FBFormat = D3DFMT_A8R8G8B8; +#else + D3DFORMAT FBFormat = D3DFMT_L8; +#endif + + if (FAILED(D3DDevice->CreateTexture(Width, Height, 1, D3DUSAGE_DYNAMIC, FBFormat, D3DPOOL_DEFAULT, &FBTexture, NULL))) { int pow2width, pow2height, i; for (i = 1; i < Width; i <<= 1) {} pow2width = i; for (i = 1; i < Height; i <<= 1) {} pow2height = i; - if (FAILED(D3DDevice->CreateTexture(pow2width, pow2height, 1, D3DUSAGE_DYNAMIC, D3DFMT_L8, D3DPOOL_DEFAULT, &FBTexture, NULL))) + if (FAILED(D3DDevice->CreateTexture(pow2width, pow2height, 1, D3DUSAGE_DYNAMIC, FBFormat, D3DPOOL_DEFAULT, &FBTexture, NULL))) { return false; } @@ -1304,18 +1310,18 @@ void D3DFB::Draw3DPart(bool copy3d) SUCCEEDED(FBTexture->LockRect (0, &lockrect, NULL, D3DLOCK_DISCARD))) || SUCCEEDED(FBTexture->LockRect (0, &lockrect, &texrect, 0))) { - if (lockrect.Pitch == Pitch && Pitch == Width) + if (lockrect.Pitch == Pitch * sizeof(canvas_pixel_t) && Pitch == Width) { - memcpy (lockrect.pBits, MemBuffer, Width * Height); + memcpy (lockrect.pBits, MemBuffer, Width * Height * sizeof(canvas_pixel_t)); } else { - BYTE *dest = (BYTE *)lockrect.pBits; - BYTE *src = MemBuffer; + canvas_pixel_t *dest = (canvas_pixel_t *)lockrect.pBits; + canvas_pixel_t *src = MemBuffer; for (int y = 0; y < Height; y++) { - memcpy (dest, src, Width); - dest += lockrect.Pitch; + memcpy (dest, src, Width * sizeof(canvas_pixel_t)); + dest = reinterpret_cast(reinterpret_cast(dest) + lockrect.Pitch); src += Pitch; } } @@ -1349,7 +1355,11 @@ void D3DFB::Draw3DPart(bool copy3d) memset(Constant, 0, sizeof(Constant)); SetAlphaBlend(D3DBLENDOP(0)); EnableAlphaTest(FALSE); +#ifndef PALETTEOUTPUT + SetPixelShader(Shaders[SHADER_NormalColor]); +#else SetPixelShader(Shaders[SHADER_NormalColorPal]); +#endif if (copy3d) { FBVERTEX verts[4]; @@ -1367,7 +1377,11 @@ void D3DFB::Draw3DPart(bool copy3d) realfixedcolormap->ColorizeStart[1]/2, realfixedcolormap->ColorizeStart[2]/2, 0); color1 = D3DCOLOR_COLORVALUE(realfixedcolormap->ColorizeEnd[0]/2, realfixedcolormap->ColorizeEnd[1]/2, realfixedcolormap->ColorizeEnd[2]/2, 1); +#ifndef PALETTEOUTPUT + SetPixelShader(Shaders[SHADER_SpecialColormap]); +#else SetPixelShader(Shaders[SHADER_SpecialColormapPal]); +#endif } } else @@ -1378,7 +1392,11 @@ void D3DFB::Draw3DPart(bool copy3d) CalcFullscreenCoords(verts, Accel2D, false, color0, color1); D3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, verts, sizeof(FBVERTEX)); } +#ifndef PALETTEOUTPUT + SetPixelShader(Shaders[SHADER_NormalColor]); +#else SetPixelShader(Shaders[SHADER_NormalColorPal]); +#endif } //========================================================================== @@ -1707,7 +1725,7 @@ void D3DFB::SetBlendingRect(int x1, int y1, int x2, int y2) // //========================================================================== -void D3DFB::GetScreenshotBuffer(const BYTE *&buffer, int &pitch, ESSType &color_type) +void D3DFB::GetScreenshotBuffer(const canvas_pixel_t *&buffer, int &pitch, ESSType &color_type) { D3DLOCKED_RECT lrect; @@ -1733,7 +1751,7 @@ void D3DFB::GetScreenshotBuffer(const BYTE *&buffer, int &pitch, ESSType &color_ } else { - buffer = (const BYTE *)lrect.pBits; + buffer = (const canvas_pixel_t *)lrect.pBits; pitch = lrect.Pitch; color_type = SS_BGRA; } diff --git a/src/win32/fb_ddraw.cpp b/src/win32/fb_ddraw.cpp index 7cc603786..9be571f98 100644 --- a/src/win32/fb_ddraw.cpp +++ b/src/win32/fb_ddraw.cpp @@ -32,7 +32,6 @@ ** */ - // HEADER FILES ------------------------------------------------------------ #define DIRECTDRAW_VERSION 0x0300 @@ -61,7 +60,9 @@ // TYPES ------------------------------------------------------------------- +#ifdef USE_OBSOLETE_DDRAW IMPLEMENT_CLASS(DDrawFB) +#endif // EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- @@ -119,6 +120,8 @@ cycle_t BlitCycles; // CODE -------------------------------------------------------------------- +#ifdef USE_OBSOLETE_DDRAW + DDrawFB::DDrawFB (int width, int height, bool fullscreen) : BaseWinFB (width, height) { @@ -996,8 +999,8 @@ DDrawFB::LockSurfRes DDrawFB::LockSurf (LPRECT lockrect, LPDIRECTDRAWSURFACE toL LOG1 ("Final result after restoration attempts: %08lx\n", hr); return NoGood; } - Buffer = (BYTE *)desc.lpSurface; - Pitch = desc.lPitch; + Buffer = (canvas_pixel_t *)desc.lpSurface; + Pitch = desc.lPitch / sizeof(canvas_pixel_t); BufferingNow = false; return wasLost ? GoodWasLost : Good; } @@ -1327,6 +1330,7 @@ void DDrawFB::Blank () PrimarySurf->Blt (NULL, NULL, NULL, DDBLT_COLORFILL, &blitFX); } } +#endif ADD_STAT (blit) { diff --git a/src/win32/win32iface.h b/src/win32/win32iface.h index 9b2754eae..73a2c6966 100644 --- a/src/win32/win32iface.h +++ b/src/win32/win32iface.h @@ -142,6 +142,7 @@ protected: BaseWinFB() {} }; +#ifdef USE_OBSOLETE_DDRAW class DDrawFB : public BaseWinFB { DECLARE_CLASS(DDrawFB, BaseWinFB) @@ -223,6 +224,7 @@ private: DDrawFB() {} }; +#endif class D3DFB : public BaseWinFB { @@ -250,7 +252,7 @@ public: bool PaintToWindow (); void SetVSync (bool vsync); void NewRefreshRate(); - void GetScreenshotBuffer(const BYTE *&buffer, int &pitch, ESSType &color_type); + void GetScreenshotBuffer(const canvas_pixel_t *&buffer, int &pitch, ESSType &color_type); void ReleaseScreenshotBuffer(); void SetBlendingRect (int x1, int y1, int x2, int y2); bool Begin2D (bool copy3d); diff --git a/src/win32/win32video.cpp b/src/win32/win32video.cpp index 29bb905fb..3f3645d0b 100644 --- a/src/win32/win32video.cpp +++ b/src/win32/win32video.cpp @@ -221,8 +221,15 @@ bool Win32Video::InitD3D9 () // Enumerate available display modes. FreeModes (); +#ifndef PALETTEOUTPUT // To do: remove this again (AddD3DModes fails when there are too many modes available for videomenu to display) + AddMode(1920, 1080, 8, 1440, 0); // 1080p + AddMode(1920*2, 1080*2, 8, 1440, 0); // 4k + AddMode(2560, 1440, 8, 1440, 0); // 27" classic + AddMode(2560*2, 1440*2, 8, 1440*2, 0); // 5k +#else AddD3DModes (m_Adapter, D3DFMT_X8R8G8B8); AddD3DModes (m_Adapter, D3DFMT_R5G6B5); +#endif if (Args->CheckParm ("-2")) { // Force all modes to be pixel-doubled. ScaleModes (1); @@ -660,6 +667,10 @@ DFrameBuffer *Win32Video::CreateFrameBuffer (int width, int height, bool fullscr flashAmount = 0; } +#ifndef USE_OBSOLETE_DDRAW + fb = new D3DFB(m_Adapter, width, height, fullscreen); + LOG1("New fb created @ %p\n", fb); +#else if (D3D != NULL) { fb = new D3DFB (m_Adapter, width, height, fullscreen); @@ -668,6 +679,7 @@ DFrameBuffer *Win32Video::CreateFrameBuffer (int width, int height, bool fullscr { fb = new DDrawFB (width, height, fullscreen); } + LOG1 ("New fb created @ %p\n", fb); // If we could not create the framebuffer, try again with slightly @@ -729,6 +741,7 @@ DFrameBuffer *Win32Video::CreateFrameBuffer (int width, int height, bool fullscr fb = static_cast(CreateFrameBuffer (width, height, fullscreen, NULL)); } retry = 0; +#endif fb->SetFlash (flashColor, flashAmount); return fb;