From cf6cf4bf906201cf63782245a3391c5d18104bcf Mon Sep 17 00:00:00 2001 From: Alaux <73968015+MrAlaux@users.noreply.github.com> Date: Tue, 14 Jan 2025 08:52:42 -0300 Subject: [PATCH 01/11] Initial implementation of true-color rendering --- src/am_map.c | 17 +++-- src/doomtype.h | 2 +- src/f_wipe.c | 22 +++--- src/i_video.c | 47 ++++--------- src/i_video.h | 10 ++- src/mn_snapshot.c | 14 ++-- src/r_draw.c | 65 +++++++++-------- src/r_main.c | 4 +- src/r_voxel.c | 8 +-- src/st_stuff.c | 24 ++++--- src/v_video.c | 173 ++++++++++++++++++++++++++++++++++++++-------- src/v_video.h | 45 +++++++++++- 12 files changed, 301 insertions(+), 130 deletions(-) diff --git a/src/am_map.c b/src/am_map.c index b4d6a2d7d..0143b4bc1 100644 --- a/src/am_map.c +++ b/src/am_map.c @@ -1445,10 +1445,10 @@ static void AM_clearFB(int color) { // [Nugget] Minimap: take `f_x` and `f_y` into account int h = f_h; - byte *src = I_VideoBuffer + ((f_y * video.pitch) + f_x); + pixel_t *src = I_VideoBuffer + ((f_y * video.pitch) + f_x); while (h--) { - memset(src, color, f_w); + V_IndexSet(src, color, f_w); src += video.pitch; } } @@ -1601,7 +1601,7 @@ static void PUTDOT(int xx, int yy, int cc) // [Nugget] Minimap: take `f_x` and `f_y` into account if ((f_x <= xx && xx < f_x+f_w) && (f_y <= yy && yy < f_y+f_h)) - I_VideoBuffer[(yy) * video.pitch + (xx)] = (cc); + I_VideoBuffer[(yy) * video.pitch + (xx)] = V_IndexToRGB(cc); } @@ -1697,19 +1697,25 @@ static void AM_putWuDot(int x, int y, int color, int weight) { if (STRICTMODE(flip_levels)) { x = f_x*2 + f_w - 1 - x; } // [Nugget] Flip levels - byte *dest = &I_VideoBuffer[y * video.pitch + x]; + pixel_t *dest = &I_VideoBuffer[y * video.pitch + x]; + #if 0 unsigned int *fg2rgb = Col2RGB8[weight]; unsigned int *bg2rgb = Col2RGB8[64 - weight]; unsigned int fg, bg; + #endif // [Nugget] Minimap: take `f_x` and `f_y` into account if (!((f_x <= x && x < f_x+f_w) && (f_y <= y && y < f_y+f_h))) { return; } + #if 0 fg = fg2rgb[color]; bg = bg2rgb[*dest]; fg = (fg + bg) | 0x1f07c1f; *dest = RGB32k[0][0][fg & (fg >> 15)]; + #endif + + if (weight) { *dest = V_LerpRGB(*dest, V_IndexToRGB(color), weight, 64); } } @@ -2795,7 +2801,10 @@ void AM_shadeScreen(void) for (int y = f_y; y < f_y+f_h; y++) { const int pixel = y * video.pitch + x; + #if 0 I_VideoBuffer[pixel] = colormaps[0][automap_overlay_darkening * 256 + I_VideoBuffer[pixel]]; + #endif + I_VideoBuffer[pixel] = V_ShadeRGB(I_VideoBuffer[pixel], automap_overlay_darkening, 32); } } } diff --git a/src/doomtype.h b/src/doomtype.h index 68c8c1daa..3ab7e5457 100644 --- a/src/doomtype.h +++ b/src/doomtype.h @@ -34,7 +34,7 @@ typedef enum {false, true} boolean; typedef uint8_t byte; -typedef byte pixel_t; +typedef uint32_t pixel_t; // This could be wider for >8 bit display. Indeed, true color support is // posibble precalculating 24bpp lightmap/colormap LUT. from darkening PLAYPAL diff --git a/src/f_wipe.c b/src/f_wipe.c index de0284fdd..27f934842 100644 --- a/src/f_wipe.c +++ b/src/f_wipe.c @@ -48,9 +48,9 @@ static int wipe_columns; // SCREEN WIPE PACKAGE // -static byte *wipe_scr_start; -static byte *wipe_scr_end; -static byte *wipe_scr; +static pixel_t *wipe_scr_start; +static pixel_t *wipe_scr_end; +static pixel_t *wipe_scr; // [FG] cross-fading screen wipe implementation @@ -76,12 +76,13 @@ static int wipe_doColorXForm(int width, int height, int ticks) for (int y = 0; y < height; y++) { - byte *sta = wipe_scr_start + y * width; - byte *end = wipe_scr_end + y * width; - byte *dst = wipe_scr + y * video.pitch; + pixel_t *sta = wipe_scr_start + y * width; + pixel_t *end = wipe_scr_end + y * width; + pixel_t *dst = wipe_scr + y * video.pitch; for (int x = 0; x < width; x++) { + #if 0 unsigned int *fg2rgb = Col2RGB8[fade_tick]; unsigned int *bg2rgb = Col2RGB8[64 - fade_tick]; unsigned int fg, bg; @@ -90,6 +91,9 @@ static int wipe_doColorXForm(int width, int height, int ticks) bg = bg2rgb[sta[x]]; fg = (fg + bg) | 0x1f07c1f; dst[x] = RGB32k[0][0][fg & (fg >> 15)]; + #endif + + if (fade_tick) { dst[x] = V_LerpRGB(sta[x], end[x], fade_tick, 64); } } } @@ -406,12 +410,12 @@ static int wipe_doFizzle(int width, int height, int ticks) vrect_t rect = {x, y, 1, 1}; V_ScaleRect(&rect); - byte *src = wipe_scr_end + rect.sy * width + rect.sx; - byte *dest = wipe_scr + rect.sy * video.pitch + rect.sx; + pixel_t *src = wipe_scr_end + rect.sy * width + rect.sx; + pixel_t *dest = wipe_scr + rect.sy * video.pitch + rect.sx; while (rect.sh--) { - memcpy(dest, src, rect.sw); + V_RGBCopy(dest, src, rect.sw); src += width; dest += video.pitch; } diff --git a/src/i_video.c b/src/i_video.c index 42ebcbc73..c23f34b11 100644 --- a/src/i_video.c +++ b/src/i_video.c @@ -101,8 +101,8 @@ static boolean disk_icon; // killough 10/98 static const char *sdl_renderdriver = ""; -static int red_intensity, green_intensity, blue_intensity; -static int color_saturation, color_contrast; +int red_intensity, green_intensity, blue_intensity; +int color_saturation, color_contrast; // [Nugget] -----------------------------------------------------------------/ @@ -897,7 +897,7 @@ void I_FinishUpdate(void) // I_ReadScreen // -void I_ReadScreen(byte *dst) +void I_ReadScreen(pixel_t *dst) { V_GetBlock(0, 0, video.width, video.height, dst); } @@ -997,36 +997,10 @@ static void I_RestoreDiskBackground(void) int gamma2; -// [Nugget]: -// [JN] Saturation percent array. -// 0.66 = 0% saturation, 0.0 = 100% saturation. -const float I_SaturationPercent[101] = -{ - 0.660000f, 0.653400f, 0.646800f, 0.640200f, 0.633600f, - 0.627000f, 0.620400f, 0.613800f, 0.607200f, 0.600600f, - 0.594000f, 0.587400f, 0.580800f, 0.574200f, 0.567600f, - 0.561000f, 0.554400f, 0.547800f, 0.541200f, 0.534600f, - 0.528000f, 0.521400f, 0.514800f, 0.508200f, 0.501600f, - 0.495000f, 0.488400f, 0.481800f, 0.475200f, 0.468600f, - 0.462000f, 0.455400f, 0.448800f, 0.442200f, 0.435600f, - 0.429000f, 0.422400f, 0.415800f, 0.409200f, 0.402600f, - 0.396000f, 0.389400f, 0.382800f, 0.376200f, 0.369600f, - 0.363000f, 0.356400f, 0.349800f, 0.343200f, 0.336600f, - 0.330000f, 0.323400f, 0.316800f, 0.310200f, 0.303600f, - 0.297000f, 0.290400f, 0.283800f, 0.277200f, 0.270600f, - 0.264000f, 0.257400f, 0.250800f, 0.244200f, 0.237600f, - 0.231000f, 0.224400f, 0.217800f, 0.211200f, 0.204600f, - 0.198000f, 0.191400f, 0.184800f, 0.178200f, 0.171600f, - 0.165000f, 0.158400f, 0.151800f, 0.145200f, 0.138600f, - 0.132000f, 0.125400f, 0.118800f, 0.112200f, 0.105600f, - 0.099000f, 0.092400f, 0.085800f, 0.079200f, 0.072600f, - 0.066000f, 0.059400f, 0.052800f, 0.046200f, 0.039600f, - 0.033000f, 0.026400f, 0.019800f, 0.013200f, 0, - 0 -}; - void I_SetPalette(byte *palette) { + #if 0 + // haleyjd int i; const byte *const gamma = gammatable[gamma2]; @@ -1080,11 +1054,18 @@ void I_SetPalette(byte *palette) SDL_SetPaletteColors(screenbuffer->format->palette, colors, 0, 256); + #endif + + V_InitPalsColors(); + if (vga_porch_flash) { // "flash" the pillars/letterboxes with palette changes, // emulating VGA "porch" behaviour - SDL_SetRenderDrawColor(renderer, colors[0].r, colors[0].g, colors[0].b, + SDL_SetRenderDrawColor(renderer, + (palscolors[0][0] & 0xFF0000) >> 16, + (palscolors[0][0] & 0x00FF00) >> 8, + (palscolors[0][0] & 0x0000FF), SDL_ALPHA_OPAQUE); } } @@ -1850,7 +1831,7 @@ static void CreateSurfaces(int w, int h) SDL_FreeSurface(screenbuffer); } - screenbuffer = SDL_CreateRGBSurface(0, w, h, 8, 0, 0, 0, 0); + screenbuffer = SDL_CreateRGBSurface(0, w, h, 32, 0, 0, 0, 0); SDL_FillRect(screenbuffer, NULL, 0); I_VideoBuffer = screenbuffer->pixels; diff --git a/src/i_video.h b/src/i_video.h index 2e4e4ceef..eb8a54cc4 100644 --- a/src/i_video.h +++ b/src/i_video.h @@ -60,7 +60,7 @@ void I_SetPalette(byte *palette); void I_FinishUpdate(void); -void I_ReadScreen(byte *dst); +void I_ReadScreen(pixel_t *dst); void I_ResetScreen(void); // killough 10/98 void I_ToggleVsync(void); // [JN] Calls native SDL vsync toggle @@ -81,10 +81,16 @@ extern boolean toggle_exclusive_fullscreen; extern boolean correct_aspect_ratio; extern boolean screenvisible; -// [Nugget] +// [Nugget] /----------------------------------------------------------------- + +extern int red_intensity, green_intensity, blue_intensity; +extern int color_saturation, color_contrast; + #define GAMMA2MAX 30 extern const float gammalevels[GAMMA2MAX+1]; +// [Nugget] -----------------------------------------------------------------/ + extern int gamma2; byte I_GetNearestColor(byte *palette, int r, int g, int b); diff --git a/src/mn_snapshot.c b/src/mn_snapshot.c index c8f1bd841..6ffc184ee 100644 --- a/src/mn_snapshot.c +++ b/src/mn_snapshot.c @@ -31,10 +31,10 @@ static const char snapshot_str[] = "NUGGETDOOM_SNAPSHOT"; static const int snapshot_len = arrlen(snapshot_str); -static const int snapshot_size = SCREENWIDTH * SCREENHEIGHT; +static const int snapshot_size = (SCREENWIDTH * SCREENHEIGHT) * sizeof(pixel_t); -static byte *snapshots[10]; -static byte *current_snapshot; +static pixel_t *snapshots[10]; +static pixel_t *current_snapshot; static char savegametimes[10][32]; const int MN_SnapshotDataSize(void) @@ -132,9 +132,9 @@ static void TakeSnapshot(void) current_snapshot = malloc(snapshot_size * sizeof(**snapshots)); } - byte *p = current_snapshot; + pixel_t *p = current_snapshot; - const byte *s = I_VideoBuffer; + const pixel_t *s = I_VideoBuffer; int x, y; for (y = 0; y < SCREENHEIGHT; y++) @@ -181,11 +181,11 @@ boolean MN_DrawSnapshot(int n, int x, int y, int w, int h) const fixed_t step_x = (SCREENWIDTH << FRACBITS) / rect.sw; const fixed_t step_y = (SCREENHEIGHT << FRACBITS) / rect.sh; - byte *dest = I_VideoBuffer + rect.sy * video.pitch + rect.sx; + pixel_t *dest = I_VideoBuffer + rect.sy * video.pitch + rect.sx; fixed_t srcx, srcy; int destx, desty; - byte *destline, *srcline; + pixel_t *destline, *srcline; for (desty = 0, srcy = 0; desty < rect.sh; desty++, srcy += step_y) { diff --git a/src/r_draw.c b/src/r_draw.c index 81011d60d..61b0842c2 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -57,7 +57,7 @@ int viewwidth; int viewheight; int viewwindowx; int viewwindowy; -static byte **ylookup = NULL; +static pixel_t **ylookup = NULL; static int *columnofs = NULL; static int linesize; // killough 11/98 @@ -115,7 +115,7 @@ byte dc_skycolor; dc_x); \ } \ \ - byte *dest = ylookup[dc_yl] + columnofs[dc_x]; \ + pixel_t *dest = ylookup[dc_yl] + columnofs[dc_x]; \ \ const fixed_t fracstep = dc_iscale; \ fixed_t frac = dc_texturemid + (dc_yl - centery) * fracstep; \ @@ -136,7 +136,7 @@ byte dc_skycolor; do \ { \ byte src = dc_source[frac >> FRACBITS]; \ - *dest = SRCPIXEL; \ + *dest = V_IndexToRGB(SRCPIXEL); \ dest += linesize; \ if ((frac += fracstep) >= heightmask) \ frac -= heightmask; \ @@ -147,18 +147,18 @@ byte dc_skycolor; while ((count -= 2) >= 0) \ { \ byte src = dc_source[(frac >> FRACBITS) & heightmask]; \ - *dest = SRCPIXEL; \ + *dest = V_IndexToRGB(SRCPIXEL); \ dest += linesize; \ frac += fracstep; \ src = dc_source[(frac >> FRACBITS) & heightmask]; \ - *dest = SRCPIXEL; \ + *dest = V_IndexToRGB(SRCPIXEL); \ dest += linesize; \ frac += fracstep; \ } \ if (count & 1) \ { \ byte src = dc_source[(frac >> FRACBITS) & heightmask]; \ - *dest = SRCPIXEL; \ + *dest = V_IndexToRGB(SRCPIXEL); \ } \ } \ } @@ -179,9 +179,9 @@ DRAW_COLUMN(Brightmap, dc_colormap[dc_brightmap[src]][src]) // actual code differences are. DRAW_COLUMN(TL, - tranmap[(*dest << 8) + dc_colormap[0][src]]) + tranmap[(V_IndexFromRGB(*dest) << 8) + dc_colormap[0][src]]) DRAW_COLUMN(TLBrightmap, - tranmap[(*dest << 8) + dc_colormap[dc_brightmap[src]][src]]) + tranmap[(V_IndexFromRGB(*dest) << 8) + dc_colormap[dc_brightmap[src]][src]]) // // Sky drawing: for showing just a color above the texture @@ -203,7 +203,7 @@ void R_DrawSkyColumn(void) } #endif - byte *dest = ylookup[dc_yl] + columnofs[dc_x]; + pixel_t *dest = ylookup[dc_yl] + columnofs[dc_x]; const fixed_t fracstep = dc_iscale; fixed_t frac = dc_texturemid + (dc_yl - centery) * fracstep; @@ -228,6 +228,7 @@ void R_DrawSkyColumn(void) for (i = 0; i < n; ++i) { *dest = colormap[skycolor]; + *dest = V_IndexToRGB(*dest); dest += linesize; frac += fracstep; } @@ -252,6 +253,7 @@ void R_DrawSkyColumn(void) [(main_tranmap[(colormap[source[0]] << 8) + colormap[skycolor]] << 8) + colormap[skycolor]]; + *dest = V_IndexToRGB(*dest); dest += linesize; frac += fracstep; } @@ -275,6 +277,7 @@ void R_DrawSkyColumn(void) { *dest = main_tranmap[(colormap[source[0]] << 8) + colormap[skycolor]]; + *dest = V_IndexToRGB(*dest); dest += linesize; frac += fracstep; } @@ -300,6 +303,7 @@ void R_DrawSkyColumn(void) do { *dest = colormap[source[frac >> FRACBITS]]; + *dest = V_IndexToRGB(*dest); dest += linesize; // killough 11/98 if ((frac += fracstep) >= heightmask) { @@ -312,15 +316,18 @@ void R_DrawSkyColumn(void) while ((count -= 2) >= 0) // texture height is a power of 2 -- killough { *dest = colormap[source[(frac >> FRACBITS) & heightmask]]; + *dest = V_IndexToRGB(*dest); dest += linesize; // killough 11/98 frac += fracstep; *dest = colormap[source[(frac >> FRACBITS) & heightmask]]; + *dest = V_IndexToRGB(*dest); dest += linesize; // killough 11/98 frac += fracstep; } if (count & 1) { *dest = colormap[source[(frac >> FRACBITS) & heightmask]]; + *dest = V_IndexToRGB(*dest); } } } @@ -409,7 +416,7 @@ static void R_DrawFuzzColumn_orig(void) // or blocky mode removed. // Does not work with blocky mode. - byte *dest = ylookup[dc_yl] + columnofs[dc_x]; + pixel_t *dest = ylookup[dc_yl] + columnofs[dc_x]; // Looks like an attempt at dithering, // using the colormap #6 (of 0-31, a bit brighter than average). @@ -429,7 +436,8 @@ static void R_DrawFuzzColumn_orig(void) // why_i_left_doom.html *dest = - fullcolormap[6 * 256 + dest[linesize * fuzzoffset[fuzzpos]]]; + fullcolormap[6 * 256 + V_IndexFromRGB(dest[linesize * fuzzoffset[fuzzpos]])]; + *dest = V_IndexToRGB(*dest); dest += linesize; // killough 11/98 ++fuzzpos; @@ -443,7 +451,8 @@ static void R_DrawFuzzColumn_orig(void) if (cutoff) { *dest = fullcolormap - [6 * 256 + dest[linesize * (fuzzoffset[fuzzpos] - FUZZOFF) / 2]]; + [6 * 256 + V_IndexFromRGB(dest[linesize * (fuzzoffset[fuzzpos] - FUZZOFF) / 2])]; + *dest = V_IndexToRGB(*dest); } } @@ -487,7 +496,7 @@ static void R_DrawFuzzColumn_block(void) ++count; - byte *dest = ylookup[dc_yl] + columnofs[dc_x]; + pixel_t *dest = ylookup[dc_yl] + columnofs[dc_x]; int lines = fuzzblocksize - (dc_yl % fuzzblocksize); @@ -505,11 +514,11 @@ static void R_DrawFuzzColumn_block(void) count &= ~mask; const byte fuzz = - fullcolormap[6 * 256 + dest[linesize * fuzzoffset[fuzzpos]]]; + fullcolormap[6 * 256 + V_IndexFromRGB(dest[linesize * fuzzoffset[fuzzpos]])]; do { - memset(dest, fuzz, fuzzblocksize); + V_IndexSet(dest, fuzz, fuzzblocksize); dest += linesize; } while (--lines); @@ -524,8 +533,8 @@ static void R_DrawFuzzColumn_block(void) if (cutoff) { const byte fuzz = fullcolormap - [6 * 256 + dest[linesize * (fuzzoffset[fuzzpos] - FUZZOFF) / 2]]; - memset(dest, fuzz, fuzzblocksize); + [6 * 256 + V_IndexFromRGB(dest[linesize * (fuzzoffset[fuzzpos] - FUZZOFF) / 2])]; + V_IndexSet(dest, fuzz, fuzzblocksize); } } @@ -541,7 +550,7 @@ boolean fuzzdark_mode; static void R_DrawSelectiveFuzzColumn(void) { int count; - byte *dest; + pixel_t *dest; boolean cutoff = false; if (fuzzblocksize > 1 && dc_x % fuzzblocksize) @@ -583,11 +592,11 @@ static void R_DrawSelectiveFuzzColumn(void) lines += count & mask; count &= ~mask; - const byte fuzz = fullcolormap[FUZZSELECT + dest[linesize * fuzzoffset[fuzzpos]]]; + const byte fuzz = fullcolormap[FUZZSELECT + V_IndexFromRGB(dest[linesize * fuzzoffset[fuzzpos]])]; do { - memset(dest, fuzz, fuzzblocksize); + V_IndexSet(dest, fuzz, fuzzblocksize); dest += linesize; } while (--lines); @@ -601,9 +610,9 @@ static void R_DrawSelectiveFuzzColumn(void) if (cutoff) { - const byte fuzz = fullcolormap[FUZZSELECT + dest[linesize * (fuzzoffset[fuzzpos] - FUZZOFF) / 2]]; + const byte fuzz = fullcolormap[FUZZSELECT + V_IndexFromRGB(dest[linesize * (fuzzoffset[fuzzpos] - FUZZOFF) / 2])]; - memset(dest, fuzz, fuzzblocksize); + V_IndexSet(dest, fuzz, fuzzblocksize); } } @@ -725,7 +734,7 @@ byte *ds_source; #define R_DRAW_SPAN(NAME, SRCPIXEL) \ static void DrawSpan##NAME(void) \ { \ - byte *dest = ylookup[ds_y] + columnofs[ds_x1]; \ + pixel_t *dest = ylookup[ds_y] + columnofs[ds_x1]; \ \ unsigned count = ds_x2 - ds_x1 + 1; \ \ @@ -740,7 +749,7 @@ byte *ds_source; ds_xfrac += ds_xstep; \ ds_yfrac += ds_ystep; \ src = ds_source[spot]; \ - dest[0] = SRCPIXEL; \ + dest[0] = V_IndexToRGB(SRCPIXEL); \ \ ytemp = (ds_yfrac >> 10) & 0x0FC0; \ xtemp = (ds_xfrac >> 16) & 0x003F; \ @@ -748,7 +757,7 @@ byte *ds_source; ds_xfrac += ds_xstep; \ ds_yfrac += ds_ystep; \ src = ds_source[spot]; \ - dest[1] = SRCPIXEL; \ + dest[1] = V_IndexToRGB(SRCPIXEL); \ \ ytemp = (ds_yfrac >> 10) & 0x0FC0; \ xtemp = (ds_xfrac >> 16) & 0x003F; \ @@ -756,7 +765,7 @@ byte *ds_source; ds_xfrac += ds_xstep; \ ds_yfrac += ds_ystep; \ src = ds_source[spot]; \ - dest[2] = SRCPIXEL; \ + dest[2] = V_IndexToRGB(SRCPIXEL); \ \ ytemp = (ds_yfrac >> 10) & 0x0FC0; \ xtemp = (ds_xfrac >> 16) & 0x003F; \ @@ -764,7 +773,7 @@ byte *ds_source; ds_xfrac += ds_xstep; \ ds_yfrac += ds_ystep; \ src = ds_source[spot]; \ - dest[3] = SRCPIXEL; \ + dest[3] = V_IndexToRGB(SRCPIXEL); \ \ dest += 4; \ count -= 4; \ @@ -779,7 +788,7 @@ byte *ds_source; ds_xfrac += ds_xstep; \ ds_yfrac += ds_ystep; \ src = ds_source[spot]; \ - *dest++ = SRCPIXEL; \ + *dest++ = V_IndexToRGB(SRCPIXEL); \ count--; \ } \ } diff --git a/src/r_main.c b/src/r_main.c index 7f3e136ad..5ca9aaa3c 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1771,7 +1771,7 @@ void R_RenderPlayerView (player_t* player) int first_y = ((viewheight % ph) / 2), first_x; - byte *const dest = I_VideoBuffer; + pixel_t *const dest = I_VideoBuffer; for (y = viewwindowy; y < (viewwindowy + viewheight);) { @@ -1781,7 +1781,7 @@ void R_RenderPlayerView (player_t* player) { for (y2 = 0; y2 < (first_y ? first_y : MIN(ph, (viewwindowy + viewheight) - y)); y2++) { - memset( + V_RGBSet( dest + ((y + y2) * video.pitch) + x, dest[ ( (first_y ? viewwindowy + first_y diff --git a/src/r_voxel.c b/src/r_voxel.c index 19dd0abff..89b68e1ab 100644 --- a/src/r_voxel.c +++ b/src/r_voxel.c @@ -832,7 +832,7 @@ static void VX_DrawColumn (vissprite_t * spr, int x, int y) boolean shadow = ((spr->mobjflags & MF_SHADOW) != 0); int linesize = video.pitch; - byte * dest = I_VideoBuffer + viewwindowy * linesize + viewwindowx; + pixel_t * dest = I_VideoBuffer + viewwindowy * linesize + viewwindowx; // iterate over screen columns fixed_t ux = ((Ax - 1) | FRACMASK) + 1; @@ -927,7 +927,7 @@ static void VX_DrawColumn (vissprite_t * spr, int x, int y) for (; uy < uy1 ; uy += FRACUNIT) { - dest[(uy >> FRACBITS) * linesize + (ux >> FRACBITS)] = pix; + dest[(uy >> FRACBITS) * linesize + (ux >> FRACBITS)] = V_IndexToRGB(pix); } } else if (has_bottom) @@ -942,7 +942,7 @@ static void VX_DrawColumn (vissprite_t * spr, int x, int y) for (; uy > uy2 ; uy -= FRACUNIT) { - dest[(uy >> FRACBITS) * linesize + (ux >> FRACBITS)] = pix; + dest[(uy >> FRACBITS) * linesize + (ux >> FRACBITS)] = V_IndexToRGB(pix); } } @@ -960,7 +960,7 @@ static void VX_DrawColumn (vissprite_t * spr, int x, int y) byte src = slab[i]; byte pix = spr->colormap[spr->brightmap[src]][src]; - dest[(uy >> FRACBITS) * linesize + (ux >> FRACBITS)] = pix; + dest[(uy >> FRACBITS) * linesize + (ux >> FRACBITS)] = V_IndexToRGB(pix); } } } diff --git a/src/st_stuff.c b/src/st_stuff.c index 2ae3b6e21..6b034f942 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1780,7 +1780,9 @@ static void DrawSolidBackground(void) // [FG] temporarily draw status bar to background buffer V_DrawPatch(-video.deltaw, 0, sbar); + #if 0 byte *pal = W_CacheLumpName("PLAYPAL", PU_CACHE); + #endif const int width = MIN(SHORT(sbar->width), video.unscaledw); const int depth = 16; @@ -1792,22 +1794,22 @@ static void DrawSolidBackground(void) int x, y; const int v0 = vstep[v][0], v1 = vstep[v][1]; unsigned r = 0, g = 0, b = 0; - byte col; + pixel_t col; for (y = v0; y < v1; y++) { for (x = 0; x < depth; x++) { - byte *c = st_backing_screen + V_ScaleY(y) * video.pitch + pixel_t *c = st_backing_screen + V_ScaleY(y) * video.pitch + V_ScaleX(x); - r += pal[3 * c[0] + 0]; - g += pal[3 * c[0] + 1]; - b += pal[3 * c[0] + 2]; + r += (*c & 0xFF0000) >> 16; + g += (*c & 0x00FF00) >> 8; + b += (*c & 0x0000FF); c += V_ScaleX(width - 2 * x - 1); - r += pal[3 * c[0] + 0]; - g += pal[3 * c[0] + 1]; - b += pal[3 * c[0] + 2]; + r += (*c & 0xFF0000) >> 16; + g += (*c & 0x00FF00) >> 8; + b += (*c & 0x0000FF); } } @@ -1816,9 +1818,9 @@ static void DrawSolidBackground(void) b /= 2 * depth * (v1 - v0); // [FG] tune down to half saturation (for empiric reasons) - col = I_GetNearestColor(pal, r / 2, g / 2, b / 2); + col = ((r/2) << 16) + ((g/2) << 8) + ((b/2)); - V_FillRect(0, v0, video.unscaledw, v1 - v0, col); + V_FillRectRGB(0, v0, video.unscaledw, v1 - v0, col); } } @@ -2124,6 +2126,8 @@ static void DoPaletteStuff(player_t *player) // a GNU C extension I_SetPalette((byte *)W_CacheLumpName("PLAYPAL", PU_CACHE) + palette * 768); + + V_SetPalColors(palette); } } diff --git a/src/v_video.c b/src/v_video.c index a6b499300..b6dfe6b08 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -46,6 +46,9 @@ #include "w_wad.h" // needed for color translation lump lookup #include "z_zone.h" +// [Nugget] +#include "i_gamma.h" + pixel_t *I_VideoBuffer; // The screen buffer that the v_video.c code draws to. @@ -164,6 +167,106 @@ byte cr_allblack[256], cr_gray_vc[256], // `V_Colorize()` only nightvision[256]; // Night-vision visor +// True color ---------------------------------------------------------------- + +int *palcolors, palscolors[14][256]; + +// [JN] Saturation percent array. +// 0.66 = 0% saturation, 0.0 = 100% saturation. +const float I_SaturationPercent[101] = +{ + 0.660000f, 0.653400f, 0.646800f, 0.640200f, 0.633600f, + 0.627000f, 0.620400f, 0.613800f, 0.607200f, 0.600600f, + 0.594000f, 0.587400f, 0.580800f, 0.574200f, 0.567600f, + 0.561000f, 0.554400f, 0.547800f, 0.541200f, 0.534600f, + 0.528000f, 0.521400f, 0.514800f, 0.508200f, 0.501600f, + 0.495000f, 0.488400f, 0.481800f, 0.475200f, 0.468600f, + 0.462000f, 0.455400f, 0.448800f, 0.442200f, 0.435600f, + 0.429000f, 0.422400f, 0.415800f, 0.409200f, 0.402600f, + 0.396000f, 0.389400f, 0.382800f, 0.376200f, 0.369600f, + 0.363000f, 0.356400f, 0.349800f, 0.343200f, 0.336600f, + 0.330000f, 0.323400f, 0.316800f, 0.310200f, 0.303600f, + 0.297000f, 0.290400f, 0.283800f, 0.277200f, 0.270600f, + 0.264000f, 0.257400f, 0.250800f, 0.244200f, 0.237600f, + 0.231000f, 0.224400f, 0.217800f, 0.211200f, 0.204600f, + 0.198000f, 0.191400f, 0.184800f, 0.178200f, 0.171600f, + 0.165000f, 0.158400f, 0.151800f, 0.145200f, 0.138600f, + 0.132000f, 0.125400f, 0.118800f, 0.112200f, 0.105600f, + 0.099000f, 0.092400f, 0.085800f, 0.079200f, 0.072600f, + 0.066000f, 0.059400f, 0.052800f, 0.046200f, 0.039600f, + 0.033000f, 0.026400f, 0.019800f, 0.013200f, 0, + 0 +}; + +void V_InitPalsColors(void) +{ + const byte *const playpal = W_CacheLumpName("PLAYPAL", PU_CACHE); + const byte *const gamma = gammatable[gamma2]; + + for (int i = 0; i < 14; i++) + { + int *const pc = palscolors[i]; + const byte *const pal = playpal + (768 * i); + + for (int j = 0; j < 256; j++) + { + // [Nugget] Color settings + + const byte r = gamma[pal[(j * 3) + 0]] * red_intensity / 100, + g = gamma[pal[(j * 3) + 1]] * green_intensity / 100, + b = gamma[pal[(j * 3) + 2]] * blue_intensity / 100; + + // [PN] Contrast adjustment + + const int contrast_adjustment = 128 * (100 - color_contrast) / 100; + + int channels[3] = { + ((int) r * color_contrast / 100) + contrast_adjustment, + ((int) g * color_contrast / 100) + contrast_adjustment, + ((int) b * color_contrast / 100) + contrast_adjustment + }; + + channels[0] = BETWEEN(0, 255, channels[0]); + channels[1] = BETWEEN(0, 255, channels[1]); + channels[2] = BETWEEN(0, 255, channels[2]); + + // [JN] Saturation floats, high and low. + // If saturation has been modified (< 100), set high and low + // values according to saturation level. Sum of r,g,b channels + // and floats must be 1.0 to get proper colors. + + float a_hi = I_SaturationPercent[color_saturation], + a_lo = a_hi / 2.0f; + + a_hi = 1.0f - a_hi; + a_lo = 0.0f + a_lo; + + // Calculate final color values + pc[j] = ((byte) ((a_hi * channels[0]) + (a_lo * channels[1]) + (a_lo * channels[2])) << 16) + + ((byte) ((a_lo * channels[0]) + (a_hi * channels[1]) + (a_lo * channels[2])) << 8) + + ((byte) ((a_lo * channels[0]) + (a_lo * channels[1]) + (a_hi * channels[2])) ); + } + } +} + +void V_SetPalColors(const int palette_index) +{ + palcolors = palscolors[palette_index]; +} + +pixel_t V_ShadeRGB(const pixel_t rgb, const int level, const int maxlevel) +{ + short r = (rgb & 0xFF0000) >> 16, + g = (rgb & 0x00FF00) >> 8, + b = (rgb & 0x0000FF); + + r = r * (maxlevel - level) / maxlevel; + g = g * (maxlevel - level) / maxlevel; + b = b * (maxlevel - level) / maxlevel; + + return (r << 16) + (g << 8) + (b); +} + // [Nugget] -----------------------------------------------------------------/ // killough 5/2/98: tiny engine driven by table above @@ -332,7 +435,7 @@ static void (*drawcolfunc)(const patch_column_t *patchcol); patchcol->y2, patchcol->x); \ } \ \ - byte *dest = V_ADDRESS(dest_screen, patchcol->x, patchcol->y1); \ + pixel_t *dest = V_ADDRESS(dest_screen, patchcol->x, patchcol->y1); \ \ const fixed_t fracstep = patchcol->step; \ fixed_t frac = \ @@ -342,33 +445,33 @@ static void (*drawcolfunc)(const patch_column_t *patchcol); \ while ((count -= 2) >= 0) \ { \ - *dest = SRCPIXEL; \ + *dest = V_IndexToRGB(SRCPIXEL); \ dest += linesize; \ frac += fracstep; \ - *dest = SRCPIXEL; \ + *dest = V_IndexToRGB(SRCPIXEL); \ dest += linesize; \ frac += fracstep; \ } \ if (count & 1) \ { \ - *dest = SRCPIXEL; \ + *dest = V_IndexToRGB(SRCPIXEL); \ } \ } DRAW_COLUMN(, source[frac >> FRACBITS]) DRAW_COLUMN(TR, translation[source[frac >> FRACBITS]]) DRAW_COLUMN(TRTR, translation2[translation1[source[frac >> FRACBITS]]]) -DRAW_COLUMN(TL, tranmap[(*dest << 8) + source[frac >> FRACBITS]]) -DRAW_COLUMN(TRTL, tranmap[(*dest << 8) + translation[source[frac >> FRACBITS]]]) +DRAW_COLUMN(TL, tranmap[(V_IndexFromRGB(*dest) << 8) + source[frac >> FRACBITS]]) +DRAW_COLUMN(TRTL, tranmap[(V_IndexFromRGB(*dest) << 8) + translation[source[frac >> FRACBITS]]]) // [Nugget] /----------------------------------------------------------------- -DRAW_COLUMN(TRTRTL, tranmap[(*dest << 8) + translation2[translation1[source[frac >> FRACBITS]]]]) +DRAW_COLUMN(TRTRTL, tranmap[(V_IndexFromRGB(*dest) << 8) + translation2[translation1[source[frac >> FRACBITS]]]]) DRAW_COLUMN( Translucent2, tranmap[ - (*dest << 8) + (V_IndexFromRGB(*dest) << 8) + (translation2 ? translation2[translation1[source[frac >> FRACBITS]]] : translation1 ? translation1[source[frac >> FRACBITS]] : source[frac >> FRACBITS] ) @@ -743,19 +846,24 @@ void V_DrawPatchFullScreen(patch_t *patch) void V_ShadeScreen(const int level) // [Nugget] { + #if 0 const byte *darkcolormap = &colormaps[0][level * 256]; + #endif - byte *row = dest_screen; + pixel_t *row = dest_screen; int height = video.height; while (height--) { int width = video.width; - byte *col = row; + pixel_t *col = row; while (width--) { + #if 0 *col = darkcolormap[*col]; + #endif + *col = V_ShadeRGB(*col, level, 32); ++col; } @@ -814,7 +922,7 @@ static void ScaleClippedRect(vrect_t *rect) rect->sh = y2lookup[rect->cy2] - rect->sy + 1; } -void V_FillRect(int x, int y, int width, int height, byte color) +void V_FillRectRGB(int x, int y, int width, int height, pixel_t color) { vrect_t dstrect; @@ -833,11 +941,11 @@ void V_FillRect(int x, int y, int width, int height, byte color) ScaleClippedRect(&dstrect); - byte *dest = V_ADDRESS(dest_screen, dstrect.sx, dstrect.sy); + pixel_t *dest = V_ADDRESS(dest_screen, dstrect.sx, dstrect.sy); while (dstrect.sh--) { - memset(dest, color, dstrect.sw); + V_RGBSet(dest, color, dstrect.sw); dest += linesize; } } @@ -862,15 +970,18 @@ void V_ShadowRect(int x, int y, int width, int height) ScaleClippedRect(&dstrect); - byte *dest = V_ADDRESS(dest_screen, dstrect.sx, dstrect.sy); + pixel_t *dest = V_ADDRESS(dest_screen, dstrect.sx, dstrect.sy); while (dstrect.sh--) { for (int x = 0; x < dstrect.sw; x++) { - byte *const d = &dest[x]; + pixel_t *const d = &dest[x]; - *d = R_GetGenericTranMap(hud_menu_shadows_filter_pct)[*d << 8]; + *d = V_IndexToRGB( + R_GetGenericTranMap(hud_menu_shadows_filter_pct) + [V_IndexFromRGB(*d) << 8] + ); } dest += linesize; @@ -889,7 +1000,7 @@ void V_CopyRect(int srcx, int srcy, pixel_t *source, int width, int height, int destx, int desty) { vrect_t srcrect, dstrect; - byte *src, *dest; + pixel_t *src, *dest; int usew, useh; #ifdef RANGECHECK @@ -940,7 +1051,7 @@ void V_CopyRect(int srcx, int srcy, pixel_t *source, int width, int height, while (useh--) { - memcpy(dest, src, usew); + V_RGBCopy(dest, src, usew); src += linesize; dest += linesize; } @@ -957,8 +1068,8 @@ void V_CopyRect(int srcx, int srcy, pixel_t *source, int width, int height, void V_DrawBlock(int x, int y, int width, int height, pixel_t *src) { - const byte *source; - byte *dest; + const pixel_t *source; + pixel_t *dest; vrect_t dstrect; dstrect.x = x; @@ -987,7 +1098,7 @@ void V_DrawBlock(int x, int y, int width, int height, pixel_t *src) int w; fixed_t xfrac, yfrac; int xtex, ytex; - byte *row; + pixel_t *row; yfrac = 0; @@ -1013,7 +1124,7 @@ void V_DrawBlock(int x, int y, int width, int height, pixel_t *src) void V_TileBlock64(int line, int width, int height, const byte *src) { - byte *dest, *row; + pixel_t *dest, *row; fixed_t xfrac, yfrac; int xtex, ytex, h; vrect_t dstrect; @@ -1040,7 +1151,7 @@ void V_TileBlock64(int line, int width, int height, const byte *src) while (w--) { xtex = (xfrac >> FRACBITS) & 63; - *row++ = src[ytex + xtex]; + *row++ = V_IndexToRGB(src[ytex + xtex]); xfrac += video.xstep; } @@ -1059,9 +1170,9 @@ void V_TileBlock64(int line, int width, int height, const byte *src) // No return value // -void V_GetBlock(int x, int y, int width, int height, byte *dest) +void V_GetBlock(int x, int y, int width, int height, pixel_t *dest) { - byte *src; + pixel_t *src; #ifdef RANGECHECK if (x < 0 || x + width > video.width || y < 0 || y + height > video.height) @@ -1074,7 +1185,7 @@ void V_GetBlock(int x, int y, int width, int height, byte *dest) while (height--) { - memcpy(dest, src, width); + V_RGBCopy(dest, src, width); src += linesize; dest += width; } @@ -1082,9 +1193,9 @@ void V_GetBlock(int x, int y, int width, int height, byte *dest) // [FG] non hires-scaling variant of V_DrawBlock, used in disk icon drawing -void V_PutBlock(int x, int y, int width, int height, byte *src) +void V_PutBlock(int x, int y, int width, int height, pixel_t *src) { - byte *dest; + pixel_t *dest; #ifdef RANGECHECK if (x < 0 || x + width > video.width || y < 0 || y + height > video.height) @@ -1097,7 +1208,7 @@ void V_PutBlock(int x, int y, int width, int height, byte *src) while (height--) { - memcpy(dest, src, width); + V_RGBCopy(dest, src, width); dest += linesize; src += width; } @@ -1163,6 +1274,10 @@ void V_Init(void) } y2lookup[SCREENHEIGHT - 1] = video.height - 1; y1lookup[SCREENHEIGHT] = y2lookup[SCREENHEIGHT] = video.height; + + // [Nugget] True color + V_InitPalsColors(); + V_SetPalColors(0); } // Set the buffer that the code draws to. diff --git a/src/v_video.h b/src/v_video.h index 6c11fc6b0..9b3f0258e 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -182,6 +182,46 @@ void V_DrawPatchTRTL(int x, int y, struct patch_s *patch, byte *outr, byte *tl); extern int automap_overlay_darkening; extern int menu_backdrop_darkening; +// True color ---------------------------------------------------------------- + +extern int *palcolors, palscolors[14][256]; + +void V_InitPalsColors(void); +void V_SetPalColors(const int palette_index); + +// The upper byte corresponding to the alpha channel +// actually stores the index from which the color derives + +inline static pixel_t V_IndexToRGB(const byte index) +{ + return (index << 24) + palcolors[index]; +} + +inline static byte V_IndexFromRGB(const pixel_t rgb) +{ + return rgb >> 24; +} + +#define V_IndexSet(dest, color, count) V_RGBSet(dest, V_IndexToRGB(color), count) +inline static void V_RGBSet(pixel_t *const dest, const pixel_t color, const int count) +{ + for (int i = 0; i < count; i++) { dest[i] = color; } +} + +inline static void V_RGBCopy(pixel_t *const dest, const pixel_t *const src, const int count) +{ + for (int i = 0; i < count; i++) { dest[i] = src[i]; } +} + +inline static pixel_t V_LerpRGB(const pixel_t a, const pixel_t b, const int level, const int maxlevel) +{ + return (((((a & 0xFF0000) >> 16) * (maxlevel - level) / maxlevel) + (((b & 0xFF0000) >> 16) * level / maxlevel)) << 16) + + (((((a & 0x00FF00) >> 8) * (maxlevel - level) / maxlevel) + (((b & 0x00FF00) >> 8) * level / maxlevel)) << 8) + + (((((a & 0x0000FF) ) * (maxlevel - level) / maxlevel) + (((b & 0x0000FF) ) * level / maxlevel)) ); +} + +pixel_t V_ShadeRGB(const pixel_t rgb, const int level, const int maxlevel); + // HUD/menu shadows ---------------------------------------------------------- extern boolean hud_menu_shadows; @@ -263,7 +303,10 @@ void V_GetBlock(int x, int y, int width, int height, pixel_t *dest); void V_PutBlock(int x, int y, int width, int height, pixel_t *src); -void V_FillRect(int x, int y, int width, int height, byte color); +#define V_FillRect(x, y, w, h, c) \ + V_FillRectRGB(x, y, w, h, V_IndexToRGB(c)) + +void V_FillRectRGB(int x, int y, int width, int height, pixel_t color); void V_TileBlock64(int line, int width, int height, const byte *src); From 1058f8ab51522d7d09f3ae63986390f47a41f778 Mon Sep 17 00:00:00 2001 From: Alaux <73968015+MrAlaux@users.noreply.github.com> Date: Wed, 15 Jan 2025 00:37:29 -0300 Subject: [PATCH 02/11] Refactoring --- src/i_video.c | 6 +++--- src/st_stuff.c | 16 +++++++++------- src/v_video.c | 17 ++++++++++------- src/v_video.h | 38 +++++++++++++++++++++++++++++++++----- 4 files changed, 55 insertions(+), 22 deletions(-) diff --git a/src/i_video.c b/src/i_video.c index c23f34b11..51f7662fd 100644 --- a/src/i_video.c +++ b/src/i_video.c @@ -1063,9 +1063,9 @@ void I_SetPalette(byte *palette) // "flash" the pillars/letterboxes with palette changes, // emulating VGA "porch" behaviour SDL_SetRenderDrawColor(renderer, - (palscolors[0][0] & 0xFF0000) >> 16, - (palscolors[0][0] & 0x00FF00) >> 8, - (palscolors[0][0] & 0x0000FF), + V_RedFromRGB(palscolors[0][0]), + V_GreenFromRGB(palscolors[0][0]), + V_BlueFromRGB(palscolors[0][0]), SDL_ALPHA_OPAQUE); } } diff --git a/src/st_stuff.c b/src/st_stuff.c index 6b034f942..c034e3fa2 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1802,14 +1802,14 @@ static void DrawSolidBackground(void) { pixel_t *c = st_backing_screen + V_ScaleY(y) * video.pitch + V_ScaleX(x); - r += (*c & 0xFF0000) >> 16; - g += (*c & 0x00FF00) >> 8; - b += (*c & 0x0000FF); + r += V_RedFromRGB(*c); + g += V_GreenFromRGB(*c); + b += V_BlueFromRGB(*c); c += V_ScaleX(width - 2 * x - 1); - r += (*c & 0xFF0000) >> 16; - g += (*c & 0x00FF00) >> 8; - b += (*c & 0x0000FF); + r += V_RedFromRGB(*c); + g += V_GreenFromRGB(*c); + b += V_BlueFromRGB(*c); } } @@ -1818,7 +1818,9 @@ static void DrawSolidBackground(void) b /= 2 * depth * (v1 - v0); // [FG] tune down to half saturation (for empiric reasons) - col = ((r/2) << 16) + ((g/2) << 8) + ((b/2)); + col = ((r / 2) << PIXEL_RED_SHIFT) + + ((g / 2) << PIXEL_GREEN_SHIFT) + + ((b / 2) << PIXEL_BLUE_SHIFT); V_FillRectRGB(0, v0, video.unscaledw, v1 - v0, col); } diff --git a/src/v_video.c b/src/v_video.c index b6dfe6b08..ec7876757 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -242,9 +242,12 @@ void V_InitPalsColors(void) a_lo = 0.0f + a_lo; // Calculate final color values - pc[j] = ((byte) ((a_hi * channels[0]) + (a_lo * channels[1]) + (a_lo * channels[2])) << 16) - + ((byte) ((a_lo * channels[0]) + (a_hi * channels[1]) + (a_lo * channels[2])) << 8) - + ((byte) ((a_lo * channels[0]) + (a_lo * channels[1]) + (a_hi * channels[2])) ); + pc[j] = ((byte) ((a_hi * channels[0]) + (a_lo * channels[1]) + (a_lo * channels[2])) + << PIXEL_RED_SHIFT) + + ((byte) ((a_lo * channels[0]) + (a_hi * channels[1]) + (a_lo * channels[2])) + << PIXEL_GREEN_SHIFT) + + ((byte) ((a_lo * channels[0]) + (a_lo * channels[1]) + (a_hi * channels[2])) + << PIXEL_BLUE_SHIFT); } } } @@ -256,15 +259,15 @@ void V_SetPalColors(const int palette_index) pixel_t V_ShadeRGB(const pixel_t rgb, const int level, const int maxlevel) { - short r = (rgb & 0xFF0000) >> 16, - g = (rgb & 0x00FF00) >> 8, - b = (rgb & 0x0000FF); + short r = V_RedFromRGB(rgb), + g = V_GreenFromRGB(rgb), + b = V_BlueFromRGB(rgb); r = r * (maxlevel - level) / maxlevel; g = g * (maxlevel - level) / maxlevel; b = b * (maxlevel - level) / maxlevel; - return (r << 16) + (g << 8) + (b); + return (r << PIXEL_RED_SHIFT) + (g << PIXEL_GREEN_SHIFT) + (b << PIXEL_BLUE_SHIFT); } // [Nugget] -----------------------------------------------------------------/ diff --git a/src/v_video.h b/src/v_video.h index 9b3f0258e..0eab5f13b 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -192,14 +192,39 @@ void V_SetPalColors(const int palette_index); // The upper byte corresponding to the alpha channel // actually stores the index from which the color derives +#define PIXEL_INDEX_SHIFT 24 +#define PIXEL_RED_SHIFT 16 +#define PIXEL_GREEN_SHIFT 8 +#define PIXEL_BLUE_SHIFT 0 + +#define PIXEL_INDEX_MASK (0xFF << PIXEL_INDEX_SHIFT) +#define PIXEL_RED_MASK (0xFF << PIXEL_RED_SHIFT) +#define PIXEL_GREEN_MASK (0xFF << PIXEL_GREEN_SHIFT) +#define PIXEL_BLUE_MASK (0xFF << PIXEL_BLUE_SHIFT) + inline static pixel_t V_IndexToRGB(const byte index) { - return (index << 24) + palcolors[index]; + return (index << PIXEL_INDEX_SHIFT) + palcolors[index]; } inline static byte V_IndexFromRGB(const pixel_t rgb) { - return rgb >> 24; + return (rgb & PIXEL_INDEX_MASK) >> PIXEL_INDEX_SHIFT; +} + +inline static byte V_RedFromRGB(const pixel_t rgb) +{ + return (rgb & PIXEL_RED_MASK) >> PIXEL_RED_SHIFT; +} + +inline static byte V_GreenFromRGB(const pixel_t rgb) +{ + return (rgb & PIXEL_GREEN_MASK) >> PIXEL_GREEN_SHIFT; +} + +inline static byte V_BlueFromRGB(const pixel_t rgb) +{ + return (rgb & PIXEL_BLUE_MASK) >> PIXEL_BLUE_SHIFT; } #define V_IndexSet(dest, color, count) V_RGBSet(dest, V_IndexToRGB(color), count) @@ -215,9 +240,12 @@ inline static void V_RGBCopy(pixel_t *const dest, const pixel_t *const src, cons inline static pixel_t V_LerpRGB(const pixel_t a, const pixel_t b, const int level, const int maxlevel) { - return (((((a & 0xFF0000) >> 16) * (maxlevel - level) / maxlevel) + (((b & 0xFF0000) >> 16) * level / maxlevel)) << 16) - + (((((a & 0x00FF00) >> 8) * (maxlevel - level) / maxlevel) + (((b & 0x00FF00) >> 8) * level / maxlevel)) << 8) - + (((((a & 0x0000FF) ) * (maxlevel - level) / maxlevel) + (((b & 0x0000FF) ) * level / maxlevel)) ); + return (((V_RedFromRGB(a) * (maxlevel - level) / maxlevel) + + (V_RedFromRGB(b) * level / maxlevel)) << PIXEL_RED_SHIFT) + + (((V_GreenFromRGB(a) * (maxlevel - level) / maxlevel) + + (V_GreenFromRGB(b) * level / maxlevel)) << PIXEL_GREEN_SHIFT) + + (((V_BlueFromRGB(a) * (maxlevel - level) / maxlevel) + + (V_BlueFromRGB(b) * level / maxlevel)) << PIXEL_BLUE_SHIFT); } pixel_t V_ShadeRGB(const pixel_t rgb, const int level, const int maxlevel); From af70c9fdf16431eafe8bb20e2579d6d7bd01a760 Mon Sep 17 00:00:00 2001 From: Alaux <73968015+MrAlaux@users.noreply.github.com> Date: Wed, 15 Jan 2025 01:13:56 -0300 Subject: [PATCH 03/11] CVAR, restore some palette-based code --- src/am_map.c | 29 +++++++++++++++-------------- src/f_wipe.c | 26 ++++++++++++++------------ src/i_video.c | 5 +++++ src/i_video.h | 2 ++ src/mn_setup.c | 4 +++- src/st_stuff.c | 45 ++++++++++++++++++++++++++++++++++----------- src/v_video.c | 15 +++++++++------ 7 files changed, 82 insertions(+), 44 deletions(-) diff --git a/src/am_map.c b/src/am_map.c index 0143b4bc1..1cbff2650 100644 --- a/src/am_map.c +++ b/src/am_map.c @@ -1697,25 +1697,26 @@ static void AM_putWuDot(int x, int y, int color, int weight) { if (STRICTMODE(flip_levels)) { x = f_x*2 + f_w - 1 - x; } // [Nugget] Flip levels - pixel_t *dest = &I_VideoBuffer[y * video.pitch + x]; - #if 0 - unsigned int *fg2rgb = Col2RGB8[weight]; - unsigned int *bg2rgb = Col2RGB8[64 - weight]; - unsigned int fg, bg; - #endif - // [Nugget] Minimap: take `f_x` and `f_y` into account if (!((f_x <= x && x < f_x+f_w) && (f_y <= y && y < f_y+f_h))) { return; } - #if 0 - fg = fg2rgb[color]; - bg = bg2rgb[*dest]; - fg = (fg + bg) | 0x1f07c1f; - *dest = RGB32k[0][0][fg & (fg >> 15)]; - #endif + pixel_t *dest = &I_VideoBuffer[y * video.pitch + x]; - if (weight) { *dest = V_LerpRGB(*dest, V_IndexToRGB(color), weight, 64); } + if (truecolor_rendering) + { + if (weight) { *dest = V_LerpRGB(*dest, V_IndexToRGB(color), weight, 64); } + } + else { + unsigned int *fg2rgb = Col2RGB8[weight]; + unsigned int *bg2rgb = Col2RGB8[64 - weight]; + unsigned int fg, bg; + + fg = fg2rgb[color]; + bg = bg2rgb[V_IndexFromRGB(*dest)]; + fg = (fg + bg) | 0x1f07c1f; + *dest = V_IndexToRGB(RGB32k[0][0][fg & (fg >> 15)]); + } } diff --git a/src/f_wipe.c b/src/f_wipe.c index 27f934842..720e89617 100644 --- a/src/f_wipe.c +++ b/src/f_wipe.c @@ -82,18 +82,20 @@ static int wipe_doColorXForm(int width, int height, int ticks) for (int x = 0; x < width; x++) { - #if 0 - unsigned int *fg2rgb = Col2RGB8[fade_tick]; - unsigned int *bg2rgb = Col2RGB8[64 - fade_tick]; - unsigned int fg, bg; - - fg = fg2rgb[end[x]]; - bg = bg2rgb[sta[x]]; - fg = (fg + bg) | 0x1f07c1f; - dst[x] = RGB32k[0][0][fg & (fg >> 15)]; - #endif - - if (fade_tick) { dst[x] = V_LerpRGB(sta[x], end[x], fade_tick, 64); } + if (truecolor_rendering) + { + if (fade_tick) { dst[x] = V_LerpRGB(sta[x], end[x], fade_tick, 64); } + } + else { + unsigned int *fg2rgb = Col2RGB8[fade_tick]; + unsigned int *bg2rgb = Col2RGB8[64 - fade_tick]; + unsigned int fg, bg; + + fg = fg2rgb[V_IndexFromRGB(end[x])]; + bg = bg2rgb[V_IndexFromRGB(sta[x])]; + fg = (fg + bg) | 0x1f07c1f; + dst[x] = V_IndexToRGB(RGB32k[0][0][fg & (fg >> 15)]); + } } } diff --git a/src/i_video.c b/src/i_video.c index 51f7662fd..60ffdbfcf 100644 --- a/src/i_video.c +++ b/src/i_video.c @@ -99,6 +99,8 @@ static boolean disk_icon; // killough 10/98 // [Nugget] /----------------------------------------------------------------- +boolean truecolor_rendering; + static const char *sdl_renderdriver = ""; int red_intensity, green_intensity, blue_intensity; @@ -1955,6 +1957,9 @@ void I_InitGraphics(void) void I_BindVideoVariables(void) { + // [Nugget] True color + BIND_BOOL_GENERAL(truecolor_rendering, true, "True-color rendering"); + M_BindNum("current_video_height", &default_current_video_height, ¤t_video_height, 600, 200, UL, ss_none, wad_no, "Vertical resolution"); diff --git a/src/i_video.h b/src/i_video.h index eb8a54cc4..78fd913ce 100644 --- a/src/i_video.h +++ b/src/i_video.h @@ -83,6 +83,8 @@ extern boolean screenvisible; // [Nugget] /----------------------------------------------------------------- +extern boolean truecolor_rendering; + extern int red_intensity, green_intensity, blue_intensity; extern int color_saturation, color_contrast; diff --git a/src/mn_setup.c b/src/mn_setup.c index 21f9cbe7a..d8f4879b8 100644 --- a/src/mn_setup.c +++ b/src/mn_setup.c @@ -2818,7 +2818,9 @@ void MN_ResetGamma(void) static setup_menu_t gen_settings1[] = { - // [Nugget] These first three items now report + {"True-color Rendering", S_ONOFF, CNTR_X, M_SPC, {"truecolor_rendering"}}, + + // [Nugget] The following three items now report // the current resolution when sitting on them {"Resolution Scale", S_THERMO | S_THRM_SIZE11 | S_ACTION | S_RES, CNTR_X, diff --git a/src/st_stuff.c b/src/st_stuff.c index c034e3fa2..482cab820 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1780,9 +1780,7 @@ static void DrawSolidBackground(void) // [FG] temporarily draw status bar to background buffer V_DrawPatch(-video.deltaw, 0, sbar); - #if 0 byte *pal = W_CacheLumpName("PLAYPAL", PU_CACHE); - #endif const int width = MIN(SHORT(sbar->width), video.unscaledw); const int depth = 16; @@ -1802,14 +1800,32 @@ static void DrawSolidBackground(void) { pixel_t *c = st_backing_screen + V_ScaleY(y) * video.pitch + V_ScaleX(x); - r += V_RedFromRGB(*c); - g += V_GreenFromRGB(*c); - b += V_BlueFromRGB(*c); + + if (truecolor_rendering) + { + r += V_RedFromRGB(*c); + g += V_GreenFromRGB(*c); + b += V_BlueFromRGB(*c); + } + else { + r += pal[3 * V_IndexFromRGB(c[0]) + 0]; + g += pal[3 * V_IndexFromRGB(c[0]) + 1]; + b += pal[3 * V_IndexFromRGB(c[0]) + 2]; + } c += V_ScaleX(width - 2 * x - 1); - r += V_RedFromRGB(*c); - g += V_GreenFromRGB(*c); - b += V_BlueFromRGB(*c); + + if (truecolor_rendering) + { + r += V_RedFromRGB(*c); + g += V_GreenFromRGB(*c); + b += V_BlueFromRGB(*c); + } + else { + r += pal[3 * V_IndexFromRGB(c[0]) + 0]; + g += pal[3 * V_IndexFromRGB(c[0]) + 1]; + b += pal[3 * V_IndexFromRGB(c[0]) + 2]; + } } } @@ -1818,9 +1834,16 @@ static void DrawSolidBackground(void) b /= 2 * depth * (v1 - v0); // [FG] tune down to half saturation (for empiric reasons) - col = ((r / 2) << PIXEL_RED_SHIFT) - + ((g / 2) << PIXEL_GREEN_SHIFT) - + ((b / 2) << PIXEL_BLUE_SHIFT); + if (truecolor_rendering) + { + col = ((r / 2) << PIXEL_RED_SHIFT) + + ((g / 2) << PIXEL_GREEN_SHIFT) + + ((b / 2) << PIXEL_BLUE_SHIFT); + } + else + { + col = V_IndexToRGB(I_GetNearestColor(pal, r / 2, g / 2, b / 2)); + } V_FillRectRGB(0, v0, video.unscaledw, v1 - v0, col); } diff --git a/src/v_video.c b/src/v_video.c index ec7876757..21d051206 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -849,9 +849,7 @@ void V_DrawPatchFullScreen(patch_t *patch) void V_ShadeScreen(const int level) // [Nugget] { - #if 0 const byte *darkcolormap = &colormaps[0][level * 256]; - #endif pixel_t *row = dest_screen; int height = video.height; @@ -863,10 +861,15 @@ void V_ShadeScreen(const int level) // [Nugget] while (width--) { - #if 0 - *col = darkcolormap[*col]; - #endif - *col = V_ShadeRGB(*col, level, 32); + if (truecolor_rendering) + { + *col = V_ShadeRGB(*col, level, 32); + } + else + { + *col = V_IndexToRGB(darkcolormap[V_IndexFromRGB(*col)]); + } + ++col; } From b8c378013008ee293cd754e2596c7b03d7812f0a Mon Sep 17 00:00:00 2001 From: Alaux <73968015+MrAlaux@users.noreply.github.com> Date: Wed, 15 Jan 2025 01:42:09 -0300 Subject: [PATCH 04/11] Restore missing palette-based code --- src/am_map.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/am_map.c b/src/am_map.c index 1cbff2650..763ef1550 100644 --- a/src/am_map.c +++ b/src/am_map.c @@ -2802,10 +2802,17 @@ void AM_shadeScreen(void) for (int y = f_y; y < f_y+f_h; y++) { const int pixel = y * video.pitch + x; - #if 0 - I_VideoBuffer[pixel] = colormaps[0][automap_overlay_darkening * 256 + I_VideoBuffer[pixel]]; - #endif - I_VideoBuffer[pixel] = V_ShadeRGB(I_VideoBuffer[pixel], automap_overlay_darkening, 32); + + if (truecolor_rendering) + { + I_VideoBuffer[pixel] = V_ShadeRGB(I_VideoBuffer[pixel], automap_overlay_darkening, 32); + } + else + { + I_VideoBuffer[pixel] = V_IndexToRGB( + colormaps[0][automap_overlay_darkening * 256 + V_IndexFromRGB(I_VideoBuffer[pixel])] + ); + } } } } From 19e709b9e67b0d7500b198ebb07f3ab5f97304a4 Mon Sep 17 00:00:00 2001 From: Alaux <73968015+MrAlaux@users.noreply.github.com> Date: Wed, 15 Jan 2025 03:18:41 -0300 Subject: [PATCH 05/11] Different `screenbuffer` creation Seems to improve performance slightly. --- src/i_video.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/i_video.c b/src/i_video.c index 60ffdbfcf..7f89744ec 100644 --- a/src/i_video.c +++ b/src/i_video.c @@ -1833,7 +1833,8 @@ static void CreateSurfaces(int w, int h) SDL_FreeSurface(screenbuffer); } - screenbuffer = SDL_CreateRGBSurface(0, w, h, 32, 0, 0, 0, 0); + screenbuffer = SDL_CreateRGBSurfaceWithFormat(0, w, h, 32, SDL_PIXELFORMAT_ARGB8888); + SDL_SetSurfaceBlendMode(screenbuffer, SDL_BLENDMODE_NONE); SDL_FillRect(screenbuffer, NULL, 0); I_VideoBuffer = screenbuffer->pixels; From 37f4cb72500342f21bb18251a2827d260765a24c Mon Sep 17 00:00:00 2001 From: Alaux <73968015+MrAlaux@users.noreply.github.com> Date: Wed, 15 Jan 2025 03:35:02 -0300 Subject: [PATCH 06/11] Use bitwise OR instead of addition where prudent --- src/st_stuff.c | 4 ++-- src/v_video.c | 6 +++--- src/v_video.h | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/st_stuff.c b/src/st_stuff.c index 482cab820..4acb561d7 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1837,8 +1837,8 @@ static void DrawSolidBackground(void) if (truecolor_rendering) { col = ((r / 2) << PIXEL_RED_SHIFT) - + ((g / 2) << PIXEL_GREEN_SHIFT) - + ((b / 2) << PIXEL_BLUE_SHIFT); + | ((g / 2) << PIXEL_GREEN_SHIFT) + | ((b / 2) << PIXEL_BLUE_SHIFT); } else { diff --git a/src/v_video.c b/src/v_video.c index 21d051206..7d6160f9f 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -244,9 +244,9 @@ void V_InitPalsColors(void) // Calculate final color values pc[j] = ((byte) ((a_hi * channels[0]) + (a_lo * channels[1]) + (a_lo * channels[2])) << PIXEL_RED_SHIFT) - + ((byte) ((a_lo * channels[0]) + (a_hi * channels[1]) + (a_lo * channels[2])) + | ((byte) ((a_lo * channels[0]) + (a_hi * channels[1]) + (a_lo * channels[2])) << PIXEL_GREEN_SHIFT) - + ((byte) ((a_lo * channels[0]) + (a_lo * channels[1]) + (a_hi * channels[2])) + | ((byte) ((a_lo * channels[0]) + (a_lo * channels[1]) + (a_hi * channels[2])) << PIXEL_BLUE_SHIFT); } } @@ -267,7 +267,7 @@ pixel_t V_ShadeRGB(const pixel_t rgb, const int level, const int maxlevel) g = g * (maxlevel - level) / maxlevel; b = b * (maxlevel - level) / maxlevel; - return (r << PIXEL_RED_SHIFT) + (g << PIXEL_GREEN_SHIFT) + (b << PIXEL_BLUE_SHIFT); + return (r << PIXEL_RED_SHIFT) | (g << PIXEL_GREEN_SHIFT) | (b << PIXEL_BLUE_SHIFT); } // [Nugget] -----------------------------------------------------------------/ diff --git a/src/v_video.h b/src/v_video.h index 0eab5f13b..afd388df8 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -204,7 +204,7 @@ void V_SetPalColors(const int palette_index); inline static pixel_t V_IndexToRGB(const byte index) { - return (index << PIXEL_INDEX_SHIFT) + palcolors[index]; + return (index << PIXEL_INDEX_SHIFT) | palcolors[index]; } inline static byte V_IndexFromRGB(const pixel_t rgb) @@ -242,9 +242,9 @@ inline static pixel_t V_LerpRGB(const pixel_t a, const pixel_t b, const int leve { return (((V_RedFromRGB(a) * (maxlevel - level) / maxlevel) + (V_RedFromRGB(b) * level / maxlevel)) << PIXEL_RED_SHIFT) - + (((V_GreenFromRGB(a) * (maxlevel - level) / maxlevel) + | (((V_GreenFromRGB(a) * (maxlevel - level) / maxlevel) + (V_GreenFromRGB(b) * level / maxlevel)) << PIXEL_GREEN_SHIFT) - + (((V_BlueFromRGB(a) * (maxlevel - level) / maxlevel) + | (((V_BlueFromRGB(a) * (maxlevel - level) / maxlevel) + (V_BlueFromRGB(b) * level / maxlevel)) << PIXEL_BLUE_SHIFT); } From 5ecedb1a34b454fcf79af3d39482e68047234f36 Mon Sep 17 00:00:00 2001 From: Alaux <73968015+MrAlaux@users.noreply.github.com> Date: Fri, 17 Jan 2025 04:29:46 -0300 Subject: [PATCH 07/11] Colormap interpolation --- src/r_defs.h | 7 ++++- src/r_draw.c | 75 +++++++++++++++++++++++++++++++++++++++----------- src/r_draw.h | 8 ++++++ src/r_main.c | 18 +++++++++++- src/r_main.h | 2 ++ src/r_plane.c | 20 ++++++++++++++ src/r_segs.c | 27 ++++++++++++++++++ src/r_things.c | 20 ++++++++++++++ src/v_video.h | 5 ++-- 9 files changed, 162 insertions(+), 20 deletions(-) diff --git a/src/r_defs.h b/src/r_defs.h index 5525e59b3..db6828d75 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -388,8 +388,13 @@ typedef struct vissprite_s // andrewj: voxel support int voxel_index; - // [Nugget] + // [Nugget] ---------------------------------------------------------------- + byte *tranmap; + + // True color + byte lightindex, maxlightindex; + lighttable_t *nextcolormap; } vissprite_t; // diff --git a/src/r_draw.c b/src/r_draw.c index 61b0842c2..226465c4c 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -84,6 +84,10 @@ int dc_texheight; // killough byte *dc_source; // first pixel in a column (possibly virtual) byte dc_skycolor; +// [Nugget] True color +byte dc_lightindex, dc_maxlightindex; +lighttable_t *dc_nextcolormap; + // // A column is a vertical slice/span from a wall texture that, // given the DOOM style restrictions on the view orientation, @@ -115,7 +119,7 @@ byte dc_skycolor; dc_x); \ } \ \ - pixel_t *dest = ylookup[dc_yl] + columnofs[dc_x]; \ + pixel_t *dest = ylookup[dc_yl] + columnofs[dc_x]; \ \ const fixed_t fracstep = dc_iscale; \ fixed_t frac = dc_texturemid + (dc_yl - centery) * fracstep; \ @@ -136,7 +140,7 @@ byte dc_skycolor; do \ { \ byte src = dc_source[frac >> FRACBITS]; \ - *dest = V_IndexToRGB(SRCPIXEL); \ + *dest = SRCPIXEL; \ dest += linesize; \ if ((frac += fracstep) >= heightmask) \ frac -= heightmask; \ @@ -147,24 +151,39 @@ byte dc_skycolor; while ((count -= 2) >= 0) \ { \ byte src = dc_source[(frac >> FRACBITS) & heightmask]; \ - *dest = V_IndexToRGB(SRCPIXEL); \ + *dest = SRCPIXEL; \ dest += linesize; \ frac += fracstep; \ src = dc_source[(frac >> FRACBITS) & heightmask]; \ - *dest = V_IndexToRGB(SRCPIXEL); \ + *dest = SRCPIXEL; \ dest += linesize; \ frac += fracstep; \ } \ if (count & 1) \ { \ byte src = dc_source[(frac >> FRACBITS) & heightmask]; \ - *dest = V_IndexToRGB(SRCPIXEL); \ + *dest = SRCPIXEL; \ } \ } \ } -DRAW_COLUMN(, dc_colormap[0][src]) -DRAW_COLUMN(Brightmap, dc_colormap[dc_brightmap[src]][src]) +DRAW_COLUMN(, + (dc_nextcolormap) + ? V_LerpRGB(V_IndexToRGB(dc_colormap[0][src]), + V_IndexToRGB(dc_nextcolormap[src]), + dc_lightindex, + dc_maxlightindex) + : V_IndexToRGB(dc_colormap[0][src]) +) + +DRAW_COLUMN(Brightmap, + (dc_nextcolormap && !dc_brightmap[src]) + ? V_LerpRGB(V_IndexToRGB(dc_colormap[0][src]), + V_IndexToRGB(dc_nextcolormap[src]), + dc_lightindex, + dc_maxlightindex) + : V_IndexToRGB(dc_colormap[dc_brightmap[src]][src]) +) // Here is the version of R_DrawColumn that deals with translucent // phares // textures and sprites. It's identical to R_DrawColumn except // | @@ -179,9 +198,14 @@ DRAW_COLUMN(Brightmap, dc_colormap[dc_brightmap[src]][src]) // actual code differences are. DRAW_COLUMN(TL, - tranmap[(V_IndexFromRGB(*dest) << 8) + dc_colormap[0][src]]) + V_IndexToRGB(tranmap[(V_IndexFromRGB(*dest) << 8) + + dc_colormap[0][src]]) +) + DRAW_COLUMN(TLBrightmap, - tranmap[(V_IndexFromRGB(*dest) << 8) + dc_colormap[dc_brightmap[src]][src]]) + V_IndexToRGB(tranmap[(V_IndexFromRGB(*dest) << 8) + + dc_colormap[dc_brightmap[src]][src]]) +) // // Sky drawing: for showing just a color above the texture @@ -728,6 +752,10 @@ fixed_t ds_yfrac; fixed_t ds_xstep; fixed_t ds_ystep; +// [Nugget] True color +byte ds_lightindex, ds_maxlightindex; +lighttable_t *ds_nextcolormap; + // start of a 64*64 tile image byte *ds_source; @@ -749,7 +777,7 @@ byte *ds_source; ds_xfrac += ds_xstep; \ ds_yfrac += ds_ystep; \ src = ds_source[spot]; \ - dest[0] = V_IndexToRGB(SRCPIXEL); \ + dest[0] = SRCPIXEL; \ \ ytemp = (ds_yfrac >> 10) & 0x0FC0; \ xtemp = (ds_xfrac >> 16) & 0x003F; \ @@ -757,7 +785,7 @@ byte *ds_source; ds_xfrac += ds_xstep; \ ds_yfrac += ds_ystep; \ src = ds_source[spot]; \ - dest[1] = V_IndexToRGB(SRCPIXEL); \ + dest[1] = SRCPIXEL; \ \ ytemp = (ds_yfrac >> 10) & 0x0FC0; \ xtemp = (ds_xfrac >> 16) & 0x003F; \ @@ -765,7 +793,7 @@ byte *ds_source; ds_xfrac += ds_xstep; \ ds_yfrac += ds_ystep; \ src = ds_source[spot]; \ - dest[2] = V_IndexToRGB(SRCPIXEL); \ + dest[2] = SRCPIXEL; \ \ ytemp = (ds_yfrac >> 10) & 0x0FC0; \ xtemp = (ds_xfrac >> 16) & 0x003F; \ @@ -773,7 +801,7 @@ byte *ds_source; ds_xfrac += ds_xstep; \ ds_yfrac += ds_ystep; \ src = ds_source[spot]; \ - dest[3] = V_IndexToRGB(SRCPIXEL); \ + dest[3] = SRCPIXEL; \ \ dest += 4; \ count -= 4; \ @@ -788,13 +816,28 @@ byte *ds_source; ds_xfrac += ds_xstep; \ ds_yfrac += ds_ystep; \ src = ds_source[spot]; \ - *dest++ = V_IndexToRGB(SRCPIXEL); \ + *dest++ = SRCPIXEL; \ count--; \ } \ } -R_DRAW_SPAN(, ds_colormap[0][src]) -R_DRAW_SPAN(Brightmap, ds_colormap[ds_brightmap[src]][src]) +R_DRAW_SPAN(, + (ds_nextcolormap) + ? V_LerpRGB(V_IndexToRGB(ds_colormap[0][src]), + V_IndexToRGB(ds_nextcolormap[src]), + ds_lightindex, + ds_maxlightindex) + : V_IndexToRGB(ds_colormap[0][src]) +) + +R_DRAW_SPAN(Brightmap, + (ds_nextcolormap && !ds_brightmap[src]) + ? V_LerpRGB(V_IndexToRGB(ds_colormap[0][src]), + V_IndexToRGB(ds_nextcolormap[src]), + ds_lightindex, + ds_maxlightindex) + : V_IndexToRGB(ds_colormap[ds_brightmap[src]][src]) +) void (*R_DrawColumn)(void) = DrawColumn; void (*R_DrawTLColumn)(void) = DrawColumnTL; diff --git a/src/r_draw.h b/src/r_draw.h index b6602fb46..fa52ddba8 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -32,6 +32,10 @@ extern fixed_t dc_texturemid; extern int dc_texheight; // killough extern byte dc_skycolor; +// [Nugget] True color +extern byte dc_lightindex, dc_maxlightindex; +extern lighttable_t *dc_nextcolormap; + // first pixel in a column extern byte *dc_source; extern const byte *dc_brightmap; @@ -72,6 +76,10 @@ extern fixed_t ds_yfrac; extern fixed_t ds_xstep; extern fixed_t ds_ystep; +// [Nugget] True color +extern byte ds_lightindex, ds_maxlightindex; +extern lighttable_t *ds_nextcolormap; + // start of a 64*64 tile image extern byte *ds_source; extern byte *translationtables; diff --git a/src/r_main.c b/src/r_main.c index 5ca9aaa3c..d2d31be7b 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -847,12 +847,28 @@ void R_SmoothLight(void) P_SegLengths(true); } +// [Nugget] +static int64_t temp_lightindex = 0; + int R_GetLightIndex(fixed_t scale) { - const int index = ((int64_t)scale * (160 << FRACBITS) / lightfocallength) >> LIGHTSCALESHIFT; + // [Nugget] True color: calculate part of `dc_lightindex` here + const int index = (temp_lightindex = (int64_t)scale * (160 << FRACBITS) / lightfocallength) >> LIGHTSCALESHIFT; return BETWEEN(0, MAXLIGHTSCALE - 1, index); } +// [Nugget] True color +byte R_GetLightIndexFrac(void) +{ + #define INDEX_PRECISION 255 + + dc_maxlightindex = INDEX_PRECISION; + + return (temp_lightindex % (1 << LIGHTSCALESHIFT)) * INDEX_PRECISION / (1 << LIGHTSCALESHIFT); + + #undef INDEX_PRECISION +} + static fixed_t viewpitch; static void R_SetupFreelook(void) diff --git a/src/r_main.h b/src/r_main.h index 8c513cb4c..24832ce47 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -140,6 +140,8 @@ extern boolean have_crouch_sprites; #define POWER_RUNOUT(power) \ ((STRICTMODE(comp_powerrunout) ? (power) >= 4*32 : (power) > 4*32) || (power) & 8) +byte R_GetLightIndexFrac(void); + // FOV effects --------------------------------------------------------------- enum { diff --git a/src/r_plane.c b/src/r_plane.c index bdc14a63e..8597fa8cd 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -209,6 +209,8 @@ static void R_MapPlane(int y, int x1, int x2) ds_xfrac = viewx + FixedMul(viewcos, distance) + (dx * ds_xstep) + xoffs; ds_yfrac = -viewy - FixedMul(viewsin, distance) + (dx * ds_ystep) + yoffs; + ds_nextcolormap = NULL; // [Nugget] True color + if (!(ds_colormap[0] = ds_colormap[1] = fixedcolormap)) { index = distance >> LIGHTZSHIFT; @@ -219,6 +221,22 @@ static void R_MapPlane(int y, int x1, int x2) ds_colormap[0] = planezlight[index]; ds_colormap[1] = fullcolormap; + + // [Nugget] True color ------------------------------------------- + + if (truecolor_rendering + && 0 < index + && ds_colormap[0] != planezlight[index - 1]) + { + #define INDEX_PRECISION 255 + + ds_maxlightindex = INDEX_PRECISION; + ds_lightindex = INDEX_PRECISION-1 - (distance % (1 << LIGHTZSHIFT)) * INDEX_PRECISION / (1 << LIGHTZSHIFT); + + #undef INDEX_PRECISION + + ds_nextcolormap = planezlight[index - 1]; + } } ds_y = y; @@ -590,6 +608,8 @@ static void do_draw_plane(visplane_t *pl) return; } + ds_nextcolormap = NULL; // [Nugget] True color + // sky flat if (pl->picnum == skyflatnum && sky) diff --git a/src/r_segs.c b/src/r_segs.c index c74aedd63..aefa465dc 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -41,6 +41,9 @@ #include "w_wad.h" #include "z_zone.h" +// [Nugget] +#include "i_video.h" + // OPTIMIZE: closed two sided lines as single sided // killough 1/6/98: replaced globals with statics where appropriate @@ -171,6 +174,8 @@ void R_RenderMaskedSegRange(drawseg_t *ds, int x1, int x2) for (dc_x = x1 ; dc_x <= x2 ; dc_x++, spryscale += rw_scalestep) if (maskedtexturecol[dc_x] != INT_MAX) // [FG] 32-bit integer math { + dc_nextcolormap = NULL; // [Nugget] True color + if (!fixedcolormap) // calculate lighting { // killough 11/98: const int index = STRICTMODE(!diminished_lighting) // [Nugget] @@ -180,6 +185,16 @@ void R_RenderMaskedSegRange(drawseg_t *ds, int x1, int x2) dc_brightmap = texturebrightmap[texnum]; dc_colormap[0] = walllights[index]; dc_colormap[1] = STRICTMODE(brightmaps) ? fullcolormap : dc_colormap[0]; + + // [Nugget] True color ------------------------------------------- + + if (truecolor_rendering + && index < MAXLIGHTSCALE-1 + && dc_colormap[0] != walllights[index + 1]) + { + dc_lightindex = R_GetLightIndexFrac(); + dc_nextcolormap = walllights[index + 1]; + } } // killough 3/2/98: @@ -398,6 +413,18 @@ static void R_RenderSegLoop (void) fullcolormap : dc_colormap[0]; dc_x = rw_x; dc_iscale = 0xffffffffu / (unsigned)rw_scale; + + // [Nugget] True color --------------------------------------------- + + dc_nextcolormap = NULL; + + if (truecolor_rendering + && index < MAXLIGHTSCALE-1 + && dc_colormap[0] != walllights[index + 1]) + { + dc_lightindex = R_GetLightIndexFrac(); + dc_nextcolormap = walllights[index + 1]; + } } // draw the wall tiers diff --git a/src/r_things.c b/src/r_things.c index cb6b9bb25..5d03eab61 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -437,6 +437,11 @@ void R_DrawVisSprite(vissprite_t *vis, int x1, int x2) dc_colormap[1] = vis->colormap[1]; dc_brightmap = vis->brightmap; + // [Nugget] True color + dc_lightindex = vis->lightindex; + dc_maxlightindex = vis->maxlightindex; + dc_nextcolormap = vis->nextcolormap; + // killough 4/11/98: rearrange and handle translucent sprites // mixed with translucent/non-translucent 2s normals @@ -709,6 +714,8 @@ static void R_ProjectSprite (mobj_t* thing) vis->startfrac += vis->xiscale*(vis->x1-x1); vis->patch = lump; + vis->nextcolormap = NULL; // [Nugget] True color + // get light level if (thing->flags & MF_SHADOW) vis->colormap[0] = vis->colormap[1] = NULL; // shadow draw @@ -723,6 +730,17 @@ static void R_ProjectSprite (mobj_t* thing) vis->colormap[0] = spritelights[index]; vis->colormap[1] = fullcolormap; + + // [Nugget] True color ------------------------------------------------- + + if (truecolor_rendering + && index < MAXLIGHTSCALE-1 + && vis->colormap[0] != spritelights[index + 1]) + { + vis->lightindex = R_GetLightIndexFrac(); + vis->maxlightindex = dc_maxlightindex; + vis->nextcolormap = spritelights[index + 1]; + } } vis->brightmap = R_BrightmapForState(thing->state - states); @@ -944,6 +962,8 @@ void R_DrawPSprite (pspdef_t *psp, boolean translucent) // [Nugget] Translucent vis->patch = lump; + vis->nextcolormap = NULL; // [Nugget] True color + // killough 7/11/98: beta psprites did not draw shadows if (POWER_RUNOUT(viewplayer->powers[pw_invisibility]) && !beta_emulation) diff --git a/src/v_video.h b/src/v_video.h index afd388df8..26f019edc 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -238,9 +238,10 @@ inline static void V_RGBCopy(pixel_t *const dest, const pixel_t *const src, cons for (int i = 0; i < count; i++) { dest[i] = src[i]; } } -inline static pixel_t V_LerpRGB(const pixel_t a, const pixel_t b, const int level, const int maxlevel) +inline static pixel_t V_LerpRGB(const pixel_t a, const pixel_t b, const byte level, const byte maxlevel) { - return (((V_RedFromRGB(a) * (maxlevel - level) / maxlevel) + return (a & PIXEL_INDEX_MASK) + | (((V_RedFromRGB(a) * (maxlevel - level) / maxlevel) + (V_RedFromRGB(b) * level / maxlevel)) << PIXEL_RED_SHIFT) | (((V_GreenFromRGB(a) * (maxlevel - level) / maxlevel) + (V_GreenFromRGB(b) * level / maxlevel)) << PIXEL_GREEN_SHIFT) From 8227862c4dd436d2e32b8d4abc62f412dd470c65 Mon Sep 17 00:00:00 2001 From: Alaux <73968015+MrAlaux@users.noreply.github.com> Date: Sun, 19 Jan 2025 15:04:51 -0300 Subject: [PATCH 08/11] Fix MSVC builds --- src/r_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/r_main.c b/src/r_main.c index d2d31be7b..69d2a2aea 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -864,7 +864,8 @@ byte R_GetLightIndexFrac(void) dc_maxlightindex = INDEX_PRECISION; - return (temp_lightindex % (1 << LIGHTSCALESHIFT)) * INDEX_PRECISION / (1 << LIGHTSCALESHIFT); + return (temp_lightindex % ((int64_t) 1 << LIGHTSCALESHIFT)) + * INDEX_PRECISION / ((int64_t) 1 << LIGHTSCALESHIFT); #undef INDEX_PRECISION } From 026763eb2243de1f60e68fee72f5fd3da4aafd52 Mon Sep 17 00:00:00 2001 From: Alaux <73968015+MrAlaux@users.noreply.github.com> Date: Sun, 26 Jan 2025 03:45:48 -0300 Subject: [PATCH 09/11] Full true-color for segs --- src/i_video.c | 6 ++-- src/i_video.h | 10 ++++++- src/m_cheat.c | 4 +-- src/mn_setup.c | 10 ++++++- src/r_draw.c | 18 ++++++------ src/r_draw.h | 4 +-- src/r_main.c | 5 +++- src/r_plane.c | 2 +- src/r_segs.c | 74 ++++++++++++++++++++++++++++++++++++-------------- src/r_things.c | 2 +- src/v_video.c | 13 --------- src/v_video.h | 8 +++++- 12 files changed, 103 insertions(+), 53 deletions(-) diff --git a/src/i_video.c b/src/i_video.c index 7f89744ec..424ed5301 100644 --- a/src/i_video.c +++ b/src/i_video.c @@ -99,7 +99,7 @@ static boolean disk_icon; // killough 10/98 // [Nugget] /----------------------------------------------------------------- -boolean truecolor_rendering; +truecolormode_t truecolor_rendering; static const char *sdl_renderdriver = ""; @@ -1959,7 +1959,9 @@ void I_InitGraphics(void) void I_BindVideoVariables(void) { // [Nugget] True color - BIND_BOOL_GENERAL(truecolor_rendering, true, "True-color rendering"); + BIND_NUM_GENERAL(truecolor_rendering, + TRUECOLOR_OFF, TRUECOLOR_OFF, NUM_TRUECOLOR_MODES-1, + "True-color rendering (0 = Off; 1 = Hybrid; 2 = Full"); M_BindNum("current_video_height", &default_current_video_height, ¤t_video_height, 600, 200, UL, ss_none, wad_no, diff --git a/src/i_video.h b/src/i_video.h index 78fd913ce..11dafe25d 100644 --- a/src/i_video.h +++ b/src/i_video.h @@ -83,7 +83,15 @@ extern boolean screenvisible; // [Nugget] /----------------------------------------------------------------- -extern boolean truecolor_rendering; +typedef enum truecolormode_s { + TRUECOLOR_OFF, + TRUECOLOR_HYBRID, + TRUECOLOR_FULL, + + NUM_TRUECOLOR_MODES +} truecolormode_t; + +extern truecolormode_t truecolor_rendering; extern int red_intensity, green_intensity, blue_intensity; extern int color_saturation, color_contrast; diff --git a/src/m_cheat.c b/src/m_cheat.c index fb4579f5e..52d7ad2c8 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -62,13 +62,13 @@ // [Nugget] Testing cheat /------------ -//#define NUGMAGIC +#define NUGMAGIC #ifdef NUGMAGIC static void cheat_magic(void) { - + displaymsg("Light %s", (diminished_lighting = !diminished_lighting) ? "ON" : "OFF"); } static void cheat_magic2(void) diff --git a/src/mn_setup.c b/src/mn_setup.c index d8f4879b8..c5d159719 100644 --- a/src/mn_setup.c +++ b/src/mn_setup.c @@ -366,6 +366,7 @@ enum // [Nugget] -------------------------------------------------------------- + str_truecolor_mode, str_bobbing_style, str_force_carousel, str_hud_type, @@ -2684,6 +2685,11 @@ static setup_tab_t gen_tabs[] = { {NULL} }; +// [Nugget] True color +static const char *truecolor_mode_strings[] = { + "Off", "Hybrid", "Full" +}; + static int resolution_scale; static const char **GetResolutionScaleStrings(void) @@ -2818,7 +2824,8 @@ void MN_ResetGamma(void) static setup_menu_t gen_settings1[] = { - {"True-color Rendering", S_ONOFF, CNTR_X, M_SPC, {"truecolor_rendering"}}, + {"True-color Rendering", S_CHOICE, CNTR_X, M_SPC, {"truecolor_rendering"}, + .strings_id = str_truecolor_mode}, // [Nugget] The following three items now report // the current resolution when sitting on them @@ -5609,6 +5616,7 @@ static const char **selectstrings[] = { // [Nugget] -------------------------------------------------------------- + truecolor_mode_strings, bobbing_style_strings, force_carousel_strings, hud_type_strings, diff --git a/src/r_draw.c b/src/r_draw.c index 226465c4c..613f88ac1 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -85,7 +85,7 @@ byte *dc_source; // first pixel in a column (possibly virtual) byte dc_skycolor; // [Nugget] True color -byte dc_lightindex, dc_maxlightindex; +short dc_lightindex, dc_minlightindex, dc_maxlightindex; lighttable_t *dc_nextcolormap; // @@ -168,12 +168,14 @@ lighttable_t *dc_nextcolormap; } DRAW_COLUMN(, - (dc_nextcolormap) - ? V_LerpRGB(V_IndexToRGB(dc_colormap[0][src]), - V_IndexToRGB(dc_nextcolormap[src]), - dc_lightindex, - dc_maxlightindex) - : V_IndexToRGB(dc_colormap[0][src]) + (truecolor_rendering == TRUECOLOR_FULL) + ? V_ShadeRGB(V_IndexToRGB(src), 255 - dc_lightindex, 255) + : (dc_nextcolormap) + ? V_LerpRGB(V_IndexToRGB(dc_colormap[0][src]), + V_IndexToRGB(dc_nextcolormap[src]), + dc_lightindex, + dc_maxlightindex) + : V_IndexToRGB(dc_colormap[0][src]) ) DRAW_COLUMN(Brightmap, @@ -753,7 +755,7 @@ fixed_t ds_xstep; fixed_t ds_ystep; // [Nugget] True color -byte ds_lightindex, ds_maxlightindex; +byte ds_lightindex, ds_minlightindex, ds_maxlightindex; lighttable_t *ds_nextcolormap; // start of a 64*64 tile image diff --git a/src/r_draw.h b/src/r_draw.h index fa52ddba8..b245ff4d8 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -33,7 +33,7 @@ extern int dc_texheight; // killough extern byte dc_skycolor; // [Nugget] True color -extern byte dc_lightindex, dc_maxlightindex; +extern short dc_lightindex, dc_minlightindex, dc_maxlightindex; extern lighttable_t *dc_nextcolormap; // first pixel in a column @@ -77,7 +77,7 @@ extern fixed_t ds_xstep; extern fixed_t ds_ystep; // [Nugget] True color -extern byte ds_lightindex, ds_maxlightindex; +extern byte ds_lightindex, ds_minlightindex, ds_maxlightindex; extern lighttable_t *ds_nextcolormap; // start of a 64*64 tile image diff --git a/src/r_main.c b/src/r_main.c index d2d31be7b..09604f8f9 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -864,7 +864,10 @@ byte R_GetLightIndexFrac(void) dc_maxlightindex = INDEX_PRECISION; - return (temp_lightindex % (1 << LIGHTSCALESHIFT)) * INDEX_PRECISION / (1 << LIGHTSCALESHIFT); + if (truecolor_rendering == TRUECOLOR_FULL) + return BETWEEN(0, 255, temp_lightindex / 772); + else + return (temp_lightindex % (1 << LIGHTSCALESHIFT)) * INDEX_PRECISION / (1 << LIGHTSCALESHIFT); #undef INDEX_PRECISION } diff --git a/src/r_plane.c b/src/r_plane.c index 8597fa8cd..a17382823 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -224,7 +224,7 @@ static void R_MapPlane(int y, int x1, int x2) // [Nugget] True color ------------------------------------------- - if (truecolor_rendering + if (truecolor_rendering == TRUECOLOR_HYBRID && 0 < index && ds_colormap[0] != planezlight[index - 1]) { diff --git a/src/r_segs.c b/src/r_segs.c index aefa465dc..f694084f0 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -188,7 +188,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, int x1, int x2) // [Nugget] True color ------------------------------------------- - if (truecolor_rendering + if (truecolor_rendering == TRUECOLOR_HYBRID && index < MAXLIGHTSCALE-1 && dc_colormap[0] != walllights[index + 1]) { @@ -418,7 +418,13 @@ static void R_RenderSegLoop (void) dc_nextcolormap = NULL; - if (truecolor_rendering + if (truecolor_rendering == TRUECOLOR_FULL) + { + dc_lightindex = dc_minlightindex + R_GetLightIndexFrac(); + + dc_lightindex = BETWEEN(0, 255, dc_lightindex); + } + else if (truecolor_rendering == TRUECOLOR_HYBRID && index < MAXLIGHTSCALE-1 && dc_colormap[0] != walllights[index + 1]) { @@ -824,28 +830,56 @@ void R_StoreWallRange(const int start, const int stop) // OPTIMIZE: get rid of LIGHTSEGSHIFT globally if (!fixedcolormap) { - int lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT)+extralight; - - // [crispy] smoother fake contrast - if (BETWEEN(strictmode, 2, fake_contrast) == 1) // [Nugget] + // [Nugget] True color + if (truecolor_rendering == TRUECOLOR_FULL) { - lightnum += curline->fakecontrast; + dc_minlightindex = frontsector->lightlevel + (extralight * 16); + + int fakecontrast = 0; + + // [crispy] smoother fake contrast + if (BETWEEN(strictmode, 2, fake_contrast) == 1) // [Nugget] + { + fakecontrast = curline->fakecontrast; + } + // [Nugget] Vanilla effect + else if (BETWEEN(strictmode, 2, fake_contrast) == 2) + { + if (curline->v1->y == curline->v2->y) + fakecontrast = -1; + else if (curline->v1->x == curline->v2->x) + fakecontrast = 1; + } + + dc_minlightindex += fakecontrast * 16; + + dc_minlightindex = BETWEEN(0, 255, dc_minlightindex); } - // [Nugget] Vanilla effect - else if (BETWEEN(strictmode, 2, fake_contrast) == 2) + //else { - if (curline->v1->y == curline->v2->y) - lightnum--; - else if (curline->v1->x == curline->v2->x) - lightnum++; - } + int lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT)+extralight; - if (lightnum < 0) - walllights = scalelight[0]; - else if (lightnum >= LIGHTLEVELS) - walllights = scalelight[LIGHTLEVELS-1]; - else - walllights = scalelight[lightnum]; + // [crispy] smoother fake contrast + if (BETWEEN(strictmode, 2, fake_contrast) == 1) // [Nugget] + { + lightnum += curline->fakecontrast; + } + // [Nugget] Vanilla effect + else if (BETWEEN(strictmode, 2, fake_contrast) == 2) + { + if (curline->v1->y == curline->v2->y) + lightnum--; + else if (curline->v1->x == curline->v2->x) + lightnum++; + } + + if (lightnum < 0) + walllights = scalelight[0]; + else if (lightnum >= LIGHTLEVELS) + walllights = scalelight[LIGHTLEVELS-1]; + else + walllights = scalelight[lightnum]; + } } } diff --git a/src/r_things.c b/src/r_things.c index 5d03eab61..bb897f4ab 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -733,7 +733,7 @@ static void R_ProjectSprite (mobj_t* thing) // [Nugget] True color ------------------------------------------------- - if (truecolor_rendering + if (truecolor_rendering == TRUECOLOR_HYBRID && index < MAXLIGHTSCALE-1 && vis->colormap[0] != spritelights[index + 1]) { diff --git a/src/v_video.c b/src/v_video.c index 7d6160f9f..bc67f5b92 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -257,19 +257,6 @@ void V_SetPalColors(const int palette_index) palcolors = palscolors[palette_index]; } -pixel_t V_ShadeRGB(const pixel_t rgb, const int level, const int maxlevel) -{ - short r = V_RedFromRGB(rgb), - g = V_GreenFromRGB(rgb), - b = V_BlueFromRGB(rgb); - - r = r * (maxlevel - level) / maxlevel; - g = g * (maxlevel - level) / maxlevel; - b = b * (maxlevel - level) / maxlevel; - - return (r << PIXEL_RED_SHIFT) | (g << PIXEL_GREEN_SHIFT) | (b << PIXEL_BLUE_SHIFT); -} - // [Nugget] -----------------------------------------------------------------/ // killough 5/2/98: tiny engine driven by table above diff --git a/src/v_video.h b/src/v_video.h index 26f019edc..decb560f3 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -249,7 +249,13 @@ inline static pixel_t V_LerpRGB(const pixel_t a, const pixel_t b, const byte lev + (V_BlueFromRGB(b) * level / maxlevel)) << PIXEL_BLUE_SHIFT); } -pixel_t V_ShadeRGB(const pixel_t rgb, const int level, const int maxlevel); +inline static pixel_t V_ShadeRGB(const pixel_t rgb, const int level, const int maxlevel) +{ + return (colormaps[0][(level * 256) + V_IndexFromRGB(rgb)] << PIXEL_INDEX_SHIFT) + | ((V_RedFromRGB(rgb) * (maxlevel - level) / maxlevel) << PIXEL_RED_SHIFT) + | ((V_GreenFromRGB(rgb) * (maxlevel - level) / maxlevel) << PIXEL_GREEN_SHIFT) + | ((V_BlueFromRGB(rgb) * (maxlevel - level) / maxlevel) << PIXEL_BLUE_SHIFT); +} // HUD/menu shadows ---------------------------------------------------------- From c03023b35ee7061dc336e2f5b9b206ddbc947720 Mon Sep 17 00:00:00 2001 From: Alaux <73968015+MrAlaux@users.noreply.github.com> Date: Sun, 26 Jan 2025 04:15:10 -0300 Subject: [PATCH 10/11] Merge addendum --- src/st_widgets.c | 10 +++++----- src/v_video.h | 3 +++ 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/st_widgets.c b/src/st_widgets.c index b3a4b8960..f2f1b9dbb 100644 --- a/src/st_widgets.c +++ b/src/st_widgets.c @@ -487,7 +487,7 @@ typedef struct int pos; } chatline_t; -static chatline_t lines[MAXPLAYERS]; +static chatline_t chatlines[MAXPLAYERS]; static void ClearChatLine(chatline_t *line) { @@ -560,20 +560,20 @@ void ST_UpdateChatMessage(void) ch = (char)shiftxform[(unsigned char)ch]; } - if (AddKeyToChatLine(&lines[p], ch) && ch == KEY_ENTER) + if (AddKeyToChatLine(&chatlines[p], ch) && ch == KEY_ENTER) { - if (lines[p].pos && (chat_dest[p] == consoleplayer + 1 + if (chatlines[p].pos && (chat_dest[p] == consoleplayer + 1 || chat_dest[p] == HU_BROADCAST)) { M_snprintf(message_string, sizeof(message_string), - "%s%s", *player_names[p], lines[p].string); + "%s%s", *player_names[p], chatlines[p].string); S_StartSoundPitch(0, gamemode == commercial ? sfx_radio : sfx_tink, PITCH_NONE); } - ClearChatLine(&lines[p]); + ClearChatLine(&chatlines[p]); } } players[p].cmd.chatchar = 0; diff --git a/src/v_video.h b/src/v_video.h index decb560f3..7bb0c8027 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -26,6 +26,9 @@ #include "doomtype.h" #include "m_fixed.h" +// [Nugget] +#include "r_state.h" + struct patch_s; // From 1610ad67ede183c00fbba66b059f4b46c2f2feac Mon Sep 17 00:00:00 2001 From: Alaux <73968015+MrAlaux@users.noreply.github.com> Date: Mon, 27 Jan 2025 20:06:39 -0300 Subject: [PATCH 11/11] Fix up full true color --- src/r_defs.h | 2 +- src/r_draw.c | 66 +++++++++++++------- src/r_draw.h | 2 +- src/r_main.c | 6 +- src/r_plane.c | 72 +++++++++++++++------- src/r_segs.c | 163 +++++++++++++++++++++++++++++++++++-------------- src/r_things.c | 107 +++++++++++++++++++++++--------- src/v_video.h | 2 +- 8 files changed, 295 insertions(+), 125 deletions(-) diff --git a/src/r_defs.h b/src/r_defs.h index db6828d75..62686b4a9 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -393,7 +393,7 @@ typedef struct vissprite_s byte *tranmap; // True color - byte lightindex, maxlightindex; + short lightindex; lighttable_t *nextcolormap; } vissprite_t; diff --git a/src/r_draw.c b/src/r_draw.c index 0d8225406..711b161c8 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -82,7 +82,7 @@ byte *dc_source; // first pixel in a column (possibly virtual) byte dc_skycolor; // [Nugget] True color -short dc_lightindex, dc_minlightindex, dc_maxlightindex; +short dc_lightindex, dc_minlightindex, dc_maxlightindex = 255; lighttable_t *dc_nextcolormap; // @@ -165,8 +165,12 @@ lighttable_t *dc_nextcolormap; } DRAW_COLUMN(, - (truecolor_rendering == TRUECOLOR_FULL) - ? V_ShadeRGB(V_IndexToRGB(src), 255 - dc_lightindex, 255) + (truecolor_rendering == TRUECOLOR_FULL && !fixedcolormap) + ? V_ShadeRGB( + V_IndexToRGB(src), + dc_maxlightindex - dc_lightindex, + dc_maxlightindex + ) : (dc_nextcolormap) ? V_LerpRGB(V_IndexToRGB(dc_colormap[0][src]), V_IndexToRGB(dc_nextcolormap[src]), @@ -176,12 +180,18 @@ DRAW_COLUMN(, ) DRAW_COLUMN(Brightmap, - (dc_nextcolormap && !dc_brightmap[src]) - ? V_LerpRGB(V_IndexToRGB(dc_colormap[0][src]), - V_IndexToRGB(dc_nextcolormap[src]), - dc_lightindex, - dc_maxlightindex) - : V_IndexToRGB(dc_colormap[dc_brightmap[src]][src]) + (truecolor_rendering == TRUECOLOR_FULL && !fixedcolormap) + ? V_ShadeRGB( + V_IndexToRGB(src), + dc_brightmap[src] ? 0 : dc_maxlightindex - dc_lightindex, + dc_maxlightindex + ) + : (dc_nextcolormap && !dc_brightmap[src]) + ? V_LerpRGB(V_IndexToRGB(dc_colormap[0][src]), + V_IndexToRGB(dc_nextcolormap[src]), + dc_lightindex, + dc_maxlightindex) + : V_IndexToRGB(dc_colormap[dc_brightmap[src]][src]) ) // Here is the version of R_DrawColumn that deals with translucent // phares @@ -799,7 +809,7 @@ fixed_t ds_xstep; fixed_t ds_ystep; // [Nugget] True color -byte ds_lightindex, ds_minlightindex, ds_maxlightindex; +short ds_lightindex, ds_minlightindex, ds_maxlightindex = 255; lighttable_t *ds_nextcolormap; // start of a 64*64 tile image @@ -868,21 +878,33 @@ byte *ds_source; } R_DRAW_SPAN(, - (ds_nextcolormap) - ? V_LerpRGB(V_IndexToRGB(ds_colormap[0][src]), - V_IndexToRGB(ds_nextcolormap[src]), - ds_lightindex, - ds_maxlightindex) - : V_IndexToRGB(ds_colormap[0][src]) + (truecolor_rendering == TRUECOLOR_FULL && !fixedcolormap) + ? V_ShadeRGB( + V_IndexToRGB(src), + ds_maxlightindex - ds_lightindex, + ds_maxlightindex + ) + : (ds_nextcolormap) + ? V_LerpRGB(V_IndexToRGB(ds_colormap[0][src]), + V_IndexToRGB(ds_nextcolormap[src]), + ds_lightindex, + ds_maxlightindex) + : V_IndexToRGB(ds_colormap[0][src]) ) R_DRAW_SPAN(Brightmap, - (ds_nextcolormap && !ds_brightmap[src]) - ? V_LerpRGB(V_IndexToRGB(ds_colormap[0][src]), - V_IndexToRGB(ds_nextcolormap[src]), - ds_lightindex, - ds_maxlightindex) - : V_IndexToRGB(ds_colormap[ds_brightmap[src]][src]) + (truecolor_rendering == TRUECOLOR_FULL && !fixedcolormap) + ? V_ShadeRGB( + V_IndexToRGB(src), + dc_brightmap[src] ? 0 : ds_maxlightindex - ds_lightindex, + ds_maxlightindex + ) + : (ds_nextcolormap && !ds_brightmap[src]) + ? V_LerpRGB(V_IndexToRGB(ds_colormap[0][src]), + V_IndexToRGB(ds_nextcolormap[src]), + ds_lightindex, + ds_maxlightindex) + : V_IndexToRGB(ds_colormap[ds_brightmap[src]][src]) ) void (*R_DrawColumn)(void) = DrawColumn; diff --git a/src/r_draw.h b/src/r_draw.h index 653a3fb7f..2f5360b03 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -84,7 +84,7 @@ extern fixed_t ds_xstep; extern fixed_t ds_ystep; // [Nugget] True color -extern byte ds_lightindex, ds_minlightindex, ds_maxlightindex; +extern short ds_lightindex, ds_minlightindex, ds_maxlightindex; extern lighttable_t *ds_nextcolormap; // start of a 64*64 tile image diff --git a/src/r_main.c b/src/r_main.c index 039c184cd..e9cfa4073 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -869,13 +869,11 @@ byte R_GetLightIndexFrac(void) { #define INDEX_PRECISION 255 - dc_maxlightindex = INDEX_PRECISION; - if (truecolor_rendering == TRUECOLOR_FULL) { - int64_t temp_lightindex_scaled = temp_lightindex / 772; + int64_t temp_lightindex_scaled = temp_lightindex / (MAXLIGHTSCALE * (1 << LIGHTSCALESHIFT) / 32); - return BETWEEN(0, 255, temp_lightindex_scaled); + return BETWEEN(0, INDEX_PRECISION, temp_lightindex_scaled); } else { return (temp_lightindex % ((int64_t) 1 << LIGHTSCALESHIFT)) diff --git a/src/r_plane.c b/src/r_plane.c index 82f035b7e..d5dca36ee 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -214,30 +214,49 @@ static void R_MapPlane(int y, int x1, int x2) if (!(ds_colormap[0] = ds_colormap[1] = fixedcolormap)) { - index = distance >> LIGHTZSHIFT; - if (index >= MAXLIGHTZ ) - index = MAXLIGHTZ-1; + // [Nugget] True color - if (STRICTMODE(!diminished_lighting)) { index = MAXLIGHTZ-1; } // [Nugget] + #define INDEX_PRECISION 255 - ds_colormap[0] = planezlight[index]; - ds_colormap[1] = fullcolormap; + if (truecolor_rendering == TRUECOLOR_FULL) + { + ds_lightindex = ds_minlightindex; + + if (!STRICTMODE(!diminished_lighting)) + { + const fixed_t max = MAXLIGHTZ * (1 << LIGHTZSHIFT), + step = max / 32; - // [Nugget] True color ------------------------------------------- + const fixed_t invdistance = max - distance; + + if (invdistance > step) + { ds_lightindex += invdistance / step; } + } - if (truecolor_rendering == TRUECOLOR_HYBRID - && 0 < index - && ds_colormap[0] != planezlight[index - 1]) + ds_lightindex = BETWEEN(0, INDEX_PRECISION, ds_lightindex); + } + else { - #define INDEX_PRECISION 255 + index = distance >> LIGHTZSHIFT; + if (index >= MAXLIGHTZ ) + index = MAXLIGHTZ-1; + + if (STRICTMODE(!diminished_lighting)) { index = MAXLIGHTZ-1; } // [Nugget] - ds_maxlightindex = INDEX_PRECISION; - ds_lightindex = INDEX_PRECISION-1 - (distance % (1 << LIGHTZSHIFT)) * INDEX_PRECISION / (1 << LIGHTZSHIFT); + ds_colormap[0] = planezlight[index]; + ds_colormap[1] = fullcolormap; - #undef INDEX_PRECISION + if (truecolor_rendering == TRUECOLOR_HYBRID + && 0 < index + && ds_colormap[0] != planezlight[index - 1]) + { + ds_lightindex = INDEX_PRECISION-1 - ((distance % (1 << LIGHTZSHIFT)) * INDEX_PRECISION / (1 << LIGHTZSHIFT)); - ds_nextcolormap = planezlight[index - 1]; + ds_nextcolormap = planezlight[index - 1]; + } } + + #undef INDEX_PRECISION } ds_y = y; @@ -659,20 +678,29 @@ static void do_draw_plane(visplane_t *pl) xoffs = pl->xoffs; // killough 2/28/98: Add offsets yoffs = pl->yoffs; planeheight = abs(pl->height - viewz); - light = (pl->lightlevel >> LIGHTSEGSHIFT) + extralight; - if (light >= LIGHTLEVELS) + if (truecolor_rendering == TRUECOLOR_FULL) { - light = LIGHTLEVELS - 1; + ds_minlightindex = pl->lightlevel + (extralight * 16); } - - if (light < 0) + else { - light = 0; + light = (pl->lightlevel >> LIGHTSEGSHIFT) + extralight; + + if (light >= LIGHTLEVELS) + { + light = LIGHTLEVELS - 1; + } + + if (light < 0) + { + light = 0; + } + + planezlight = zlight[light]; } stop = pl->maxx + 1; - planezlight = zlight[light]; pl->top[pl->minx - 1] = pl->top[stop] = USHRT_MAX; for (int x = pl->minx; x <= stop; x++) diff --git a/src/r_segs.c b/src/r_segs.c index f694084f0..4d0fcdb3c 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -122,27 +122,60 @@ void R_RenderMaskedSegRange(drawseg_t *ds, int x1, int x2) texnum = texturetranslation[curline->sidedef->midtexture]; - // killough 4/13/98: get correct lightlevel for 2s normal textures - lightnum = (R_FakeFlat(frontsector, &tempsec, NULL, NULL, false) - ->lightlevel >> LIGHTSEGSHIFT)+extralight; + const int lightlevel = R_FakeFlat(frontsector, &tempsec, NULL, NULL, false)->lightlevel; - // [crispy] smoother fake contrast - if (BETWEEN(strictmode, 2, fake_contrast) == 1) // [Nugget] + // [Nugget] True color + if (truecolor_rendering == TRUECOLOR_FULL) { - lightnum += curline->fakecontrast; + #define INDEX_PRECISION 255 + + dc_minlightindex = lightlevel + (extralight * 16); + + int fakecontrast = 0; + + // [crispy] smoother fake contrast + if (BETWEEN(strictmode, 2, fake_contrast) == 1) // [Nugget] + { + fakecontrast = curline->fakecontrast; + } + // [Nugget] Vanilla effect + else if (BETWEEN(strictmode, 2, fake_contrast) == 2) + { + if (curline->v1->y == curline->v2->y) + fakecontrast = -1; + else if (curline->v1->x == curline->v2->x) + fakecontrast = 1; + } + + dc_minlightindex += fakecontrast * 16; + + dc_minlightindex = BETWEEN(0, INDEX_PRECISION, dc_minlightindex); + + #undef INDEX_PRECISION } - // [Nugget] Vanilla effect - else if (BETWEEN(strictmode, 2, fake_contrast) == 2) + else { - if (curline->v1->y == curline->v2->y) - lightnum--; - else - if (curline->v1->x == curline->v2->x) - lightnum++; - } + // killough 4/13/98: get correct lightlevel for 2s normal textures + lightnum = (lightlevel >> LIGHTSEGSHIFT)+extralight; + + // [crispy] smoother fake contrast + if (BETWEEN(strictmode, 2, fake_contrast) == 1) // [Nugget] + { + lightnum += curline->fakecontrast; + } + // [Nugget] Vanilla effect + else if (BETWEEN(strictmode, 2, fake_contrast) == 2) + { + if (curline->v1->y == curline->v2->y) + lightnum--; + else + if (curline->v1->x == curline->v2->x) + lightnum++; + } - walllights = lightnum >= LIGHTLEVELS ? scalelight[LIGHTLEVELS-1] : - lightnum < 0 ? scalelight[0] : scalelight[lightnum]; + walllights = lightnum >= LIGHTLEVELS ? scalelight[LIGHTLEVELS-1] : + lightnum < 0 ? scalelight[0] : scalelight[lightnum]; + } maskedtexturecol = ds->maskedtexturecol; @@ -177,23 +210,43 @@ void R_RenderMaskedSegRange(drawseg_t *ds, int x1, int x2) dc_nextcolormap = NULL; // [Nugget] True color if (!fixedcolormap) // calculate lighting - { // killough 11/98: - const int index = STRICTMODE(!diminished_lighting) // [Nugget] - ? 0 : R_GetLightIndex(spryscale); - + { // [crispy] brightmaps for two sided mid-textures dc_brightmap = texturebrightmap[texnum]; - dc_colormap[0] = walllights[index]; - dc_colormap[1] = STRICTMODE(brightmaps) ? fullcolormap : dc_colormap[0]; - // [Nugget] True color ------------------------------------------- + // [Nugget] True color - if (truecolor_rendering == TRUECOLOR_HYBRID - && index < MAXLIGHTSCALE-1 - && dc_colormap[0] != walllights[index + 1]) + if (truecolor_rendering == TRUECOLOR_FULL) { - dc_lightindex = R_GetLightIndexFrac(); - dc_nextcolormap = walllights[index + 1]; + #define INDEX_PRECISION 255 + + dc_lightindex = dc_minlightindex; + + if (!STRICTMODE(!diminished_lighting)) + { + R_GetLightIndex(spryscale); + dc_lightindex += R_GetLightIndexFrac(); + } + + dc_lightindex = BETWEEN(0, INDEX_PRECISION, dc_lightindex); + + #undef INDEX_PRECISION + } + else + { + const int index = STRICTMODE(!diminished_lighting) // [Nugget] + ? 0 : R_GetLightIndex(spryscale); + + dc_colormap[0] = walllights[index]; + dc_colormap[1] = STRICTMODE(brightmaps) ? fullcolormap : dc_colormap[0]; + + if (truecolor_rendering == TRUECOLOR_HYBRID + && index < MAXLIGHTSCALE-1 + && dc_colormap[0] != walllights[index + 1]) + { + dc_lightindex = R_GetLightIndexFrac(); + dc_nextcolormap = walllights[index + 1]; + } } } @@ -398,38 +451,52 @@ static void R_RenderSegLoop (void) // texturecolumn and lighting are independent of wall tiers if (segtextured) { - const int index = STRICTMODE(!diminished_lighting) // [Nugget] - ? 0 : R_GetLightIndex(rw_scale); - // calculate texture offset angle_t angle =(rw_centerangle+xtoviewangle[rw_x])>>ANGLETOFINESHIFT; angle &= 0xFFF; // Prevent finetangent overflow. texturecolumn = rw_offset-FixedMul(finetangent[angle],rw_distance); texturecolumn >>= FRACBITS; - // calculate lighting - dc_colormap[0] = walllights[index]; - dc_colormap[1] = (!fixedcolormap && STRICTMODE(brightmaps)) ? - fullcolormap : dc_colormap[0]; dc_x = rw_x; dc_iscale = 0xffffffffu / (unsigned)rw_scale; - // [Nugget] True color --------------------------------------------- + // calculate lighting + // [Nugget] True color dc_nextcolormap = NULL; - if (truecolor_rendering == TRUECOLOR_FULL) + if (truecolor_rendering == TRUECOLOR_FULL && !fixedcolormap) { - dc_lightindex = dc_minlightindex + R_GetLightIndexFrac(); + #define INDEX_PRECISION 255 + + dc_lightindex = dc_minlightindex; + + if (!STRICTMODE(!diminished_lighting)) + { + R_GetLightIndex(spryscale); + dc_lightindex += R_GetLightIndexFrac(); + } - dc_lightindex = BETWEEN(0, 255, dc_lightindex); + dc_lightindex = BETWEEN(0, INDEX_PRECISION, dc_lightindex); + + #undef INDEX_PRECISION } - else if (truecolor_rendering == TRUECOLOR_HYBRID - && index < MAXLIGHTSCALE-1 - && dc_colormap[0] != walllights[index + 1]) + else { - dc_lightindex = R_GetLightIndexFrac(); - dc_nextcolormap = walllights[index + 1]; + const int index = STRICTMODE(!diminished_lighting) // [Nugget] + ? 0 : R_GetLightIndex(rw_scale); + + dc_colormap[0] = walllights[index]; + dc_colormap[1] = (!fixedcolormap && STRICTMODE(brightmaps)) ? + fullcolormap : dc_colormap[0]; + + if (truecolor_rendering == TRUECOLOR_HYBRID + && index < MAXLIGHTSCALE-1 + && dc_colormap[0] != walllights[index + 1]) + { + dc_lightindex = R_GetLightIndexFrac(); + dc_nextcolormap = walllights[index + 1]; + } } } @@ -833,6 +900,8 @@ void R_StoreWallRange(const int start, const int stop) // [Nugget] True color if (truecolor_rendering == TRUECOLOR_FULL) { + #define INDEX_PRECISION 255 + dc_minlightindex = frontsector->lightlevel + (extralight * 16); int fakecontrast = 0; @@ -853,9 +922,11 @@ void R_StoreWallRange(const int start, const int stop) dc_minlightindex += fakecontrast * 16; - dc_minlightindex = BETWEEN(0, 255, dc_minlightindex); + dc_minlightindex = BETWEEN(0, INDEX_PRECISION, dc_minlightindex); + + #undef INDEX_PRECISION } - //else + else { int lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT)+extralight; diff --git a/src/r_things.c b/src/r_things.c index 98d96a5e4..d37dc817c 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -444,7 +444,6 @@ void R_DrawVisSprite(vissprite_t *vis, int x1, int x2) // [Nugget] True color dc_lightindex = vis->lightindex; - dc_maxlightindex = vis->maxlightindex; dc_nextcolormap = vis->nextcolormap; // killough 4/11/98: rearrange and handle translucent sprites @@ -727,24 +726,49 @@ static void R_ProjectSprite (mobj_t* thing) else if (fixedcolormap) vis->colormap[0] = vis->colormap[1] = fixedcolormap; // fixed map else if (frame & FF_FULLBRIGHT) + { vis->colormap[0] = vis->colormap[1] = fullcolormap; // full bright // killough 3/20/98 + vis->lightindex = 255; // [Nugget] True color + } else - { // diminished light - const int index = STRICTMODE(!diminished_lighting) // [Nugget] - ? 0 : R_GetLightIndex(xscale); + { + // diminished light + // [Nugget] True color + + if (truecolor_rendering == TRUECOLOR_FULL) + { + #define INDEX_PRECISION 255 + + vis->lightindex = dc_minlightindex; + + if (!STRICTMODE(!diminished_lighting)) + { + R_GetLightIndex(xscale); + vis->lightindex += R_GetLightIndexFrac(); + } - vis->colormap[0] = spritelights[index]; - vis->colormap[1] = fullcolormap; + vis->lightindex = BETWEEN(0, INDEX_PRECISION, vis->lightindex); - // [Nugget] True color ------------------------------------------------- + #undef INDEX_PRECISION - if (truecolor_rendering == TRUECOLOR_HYBRID - && index < MAXLIGHTSCALE-1 - && vis->colormap[0] != spritelights[index + 1]) + // Assign a colormap so that it doesn't apply the fuzz effect + vis->colormap[0] = scalelight[0][0]; + } + else { - vis->lightindex = R_GetLightIndexFrac(); - vis->maxlightindex = dc_maxlightindex; - vis->nextcolormap = spritelights[index + 1]; + const int index = STRICTMODE(!diminished_lighting) // [Nugget] + ? 0 : R_GetLightIndex(xscale); + + vis->colormap[0] = spritelights[index]; + vis->colormap[1] = fullcolormap; + + if (truecolor_rendering == TRUECOLOR_HYBRID + && index < MAXLIGHTSCALE-1 + && vis->colormap[0] != spritelights[index + 1]) + { + vis->lightindex = R_GetLightIndexFrac(); + vis->nextcolormap = spritelights[index + 1]; + } } } @@ -799,14 +823,22 @@ void R_AddSprites(sector_t* sec, int lightlevel) if (demo_version <= DV_BOOM) lightlevel = sec->lightlevel; - lightnum = (lightlevel >> LIGHTSEGSHIFT)+extralight; - - if (lightnum < 0) - spritelights = scalelight[0]; - else if (lightnum >= LIGHTLEVELS) - spritelights = scalelight[LIGHTLEVELS-1]; + // [Nugget] True color + if (truecolor_rendering == TRUECOLOR_FULL) + { + dc_minlightindex = lightlevel + (extralight * 16); + } else - spritelights = scalelight[lightnum]; + { + lightnum = (lightlevel >> LIGHTSEGSHIFT)+extralight; + + if (lightnum < 0) + spritelights = scalelight[0]; + else if (lightnum >= LIGHTLEVELS) + spritelights = scalelight[LIGHTLEVELS-1]; + else + spritelights = scalelight[lightnum]; + } // Handle all things in sector. @@ -993,6 +1025,15 @@ void R_DrawPSprite (pspdef_t *psp, boolean translucent) // [Nugget] Translucent vis->colormap[0] = spritelights[index]; // local light vis->colormap[1] = fullcolormap; + + // [Nugget] True color ------------------------------------------------- + + if (truecolor_rendering == TRUECOLOR_FULL) + { + vis->lightindex = dc_minlightindex + index; + + vis->lightindex = BETWEEN(0, 255, vis->lightindex); + } } vis->brightmap = R_BrightmapForState(psp->state - states); @@ -1030,15 +1071,25 @@ void R_DrawPlayerSprites(void) R_FakeFlat(viewplayer->mo->subsector->sector, &tmpsec, &floorlightlevel, &ceilinglightlevel, 0); - lightnum = ((floorlightlevel+ceilinglightlevel) >> (LIGHTSEGSHIFT+1)) - + extralight; - if (lightnum < 0) - spritelights = scalelight[0]; - else if (lightnum >= LIGHTLEVELS) - spritelights = scalelight[LIGHTLEVELS-1]; - else - spritelights = scalelight[lightnum]; + // [Nugget] True color + if (truecolor_rendering == TRUECOLOR_FULL) + { + dc_minlightindex = ((floorlightlevel + ceilinglightlevel) >> 1) + + (extralight * 16); + } + //else + { + lightnum = ((floorlightlevel+ceilinglightlevel) >> (LIGHTSEGSHIFT+1)) + + extralight; + + if (lightnum < 0) + spritelights = scalelight[0]; + else if (lightnum >= LIGHTLEVELS) + spritelights = scalelight[LIGHTLEVELS-1]; + else + spritelights = scalelight[lightnum]; + } // clip to screen bounds mfloorclip = screenheightarray; diff --git a/src/v_video.h b/src/v_video.h index 7bb0c8027..0adc51485 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -254,7 +254,7 @@ inline static pixel_t V_LerpRGB(const pixel_t a, const pixel_t b, const byte lev inline static pixel_t V_ShadeRGB(const pixel_t rgb, const int level, const int maxlevel) { - return (colormaps[0][(level * 256) + V_IndexFromRGB(rgb)] << PIXEL_INDEX_SHIFT) + return (rgb & PIXEL_INDEX_MASK) | ((V_RedFromRGB(rgb) * (maxlevel - level) / maxlevel) << PIXEL_RED_SHIFT) | ((V_GreenFromRGB(rgb) * (maxlevel - level) / maxlevel) << PIXEL_GREEN_SHIFT) | ((V_BlueFromRGB(rgb) * (maxlevel - level) / maxlevel) << PIXEL_BLUE_SHIFT);