From 921bc763fbe6ec06535e91be0ea22a9bb7674e94 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 15 Mar 2017 22:04:23 +0100 Subject: [PATCH] - separated the software-renderer-specific parts of colormap processing from the common parts. - moved testcolor and test fades into SWRenderer files. These CCMDs work by hacking the default colormap and were never implemented for hardware rendering because they require many checks throughout the code. --- src/CMakeLists.txt | 1 + src/g_level.cpp | 14 - src/gl/scene/gl_scene.cpp | 21 - src/gl/system/gl_framebuffer.cpp | 13 - src/gl/system/gl_framebuffer.h | 1 - src/p_buildmap.cpp | 1 - src/polyrenderer/drawers/poly_draw_args.cpp | 1 + src/polyrenderer/poly_renderer.cpp | 6 + src/polyrenderer/scene/poly_playersprite.cpp | 12 +- src/r_data/colormaps.cpp | 417 +------------- src/r_data/colormaps.h | 58 +- src/r_renderer.h | 3 - src/r_utility.cpp | 4 +- src/serializer.h | 1 - src/st_start.h | 1 + src/swrenderer/line/r_renderdrawsegment.cpp | 7 +- src/swrenderer/r_all.cpp | 1 + src/swrenderer/r_swcanvas.cpp | 1 + src/swrenderer/r_swcolormaps.cpp | 544 +++++++++++++++++++ src/swrenderer/r_swcolormaps.h | 60 ++ src/swrenderer/r_swrenderer.cpp | 21 +- src/swrenderer/r_swrenderer.h | 3 - src/swrenderer/scene/r_light.cpp | 4 +- src/swrenderer/scene/r_scene.cpp | 4 + src/swrenderer/things/r_playersprite.cpp | 12 +- src/swrenderer/viewport/r_drawerargs.cpp | 1 + src/v_palette.cpp | 55 -- 27 files changed, 695 insertions(+), 572 deletions(-) create mode 100644 src/swrenderer/r_swcolormaps.cpp create mode 100644 src/swrenderer/r_swcolormaps.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1d8680a8b2..6eb2009437 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -806,6 +806,7 @@ file( GLOB HEADER_FILES set ( SWRENDER_SOURCES swrenderer/r_swcanvas.cpp + swrenderer/r_swcolormaps.cpp swrenderer/r_swrenderer.cpp swrenderer/r_memory.cpp swrenderer/r_renderthread.cpp diff --git a/src/g_level.cpp b/src/g_level.cpp index dce05bc994..e04eadba43 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -1390,10 +1390,6 @@ void G_InitLevelLocals () level_info_t *info; BaseBlendA = 0.0f; // Remove underwater blend effect, if any - NormalLight.Maps = realcolormaps.Maps; - - // [BB] Instead of just setting the color, we also have to reset Desaturate and build the lights. - NormalLight.ChangeColor (PalEntry (255, 255, 255), 0); level.gravity = sv_gravity * 35/TICRATE; level.aircontrol = sv_aircontrol; @@ -1415,18 +1411,10 @@ void G_InitLevelLocals () level.FromSnapshot = false; if (level.fadeto == 0) { - R_SetDefaultColormap (info->FadeTable); if (strnicmp (info->FadeTable, "COLORMAP", 8) != 0) { - level.fadeto = 0xff939393; //[SP] Hexen True-color compatibility, just use gray. level.flags |= LEVEL_HASFADETABLE; } - /* - } - else - { - NormalLight.ChangeFade (level.fadeto); - */ } level.airsupply = info->airsupply*TICRATE; level.outsidefog = info->outsidefog; @@ -1475,8 +1463,6 @@ void G_InitLevelLocals () compatflags.Callback(); compatflags2.Callback(); - NormalLight.ChangeFade (level.fadeto); - level.DefaultEnvironment = info->DefaultEnvironment; } diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index c7b06d8b77..a725a9d4f8 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -591,14 +591,6 @@ void GLSceneDrawer::DrawBlend(sector_t * viewsector) if (blendv.a == 0) { blendv = R_BlendForColormap(blendv); - if (blendv.a == 255) - { - // The calculated average is too dark so brighten it according to the palettes's overall brightness - int maxcol = MAX(MAX(GLRenderer->framebuffer->palette_brightness, blendv.r), MAX(blendv.g, blendv.b)); - blendv.r = blendv.r * 255 / maxcol; - blendv.g = blendv.g * 255 / maxcol; - blendv.b = blendv.b * 255 / maxcol; - } } if (blendv.a == 255) @@ -983,7 +975,6 @@ void GLSceneDrawer::WriteSavePic (player_t *player, FileWriter *file, int width, struct FGLInterface : public FRenderer { - bool UsesColormap() const override; void Precache(uint8_t *texhitlist, TMap &actorhitlist) override; void RenderView(player_t *player) override; void WriteSavePic (player_t *player, FileWriter *file, int width, int height) override; @@ -999,18 +990,6 @@ struct FGLInterface : public FRenderer void Init() override; }; -//=========================================================================== -// -// The GL renderer has no use for colormaps so let's -// not create them and save us some time. -// -//=========================================================================== - -bool FGLInterface::UsesColormap() const -{ - return false; -} - //========================================================================== // // DFrameBuffer :: Precache diff --git a/src/gl/system/gl_framebuffer.cpp b/src/gl/system/gl_framebuffer.cpp index 7a2d4f3f8f..aeffe5a7e6 100644 --- a/src/gl/system/gl_framebuffer.cpp +++ b/src/gl/system/gl_framebuffer.cpp @@ -308,19 +308,6 @@ bool OpenGLFrameBuffer::SetContrast(float contrast) void OpenGLFrameBuffer::UpdatePalette() { - int rr=0,gg=0,bb=0; - for(int x=0;x<256;x++) - { - rr+=GPalette.BaseColors[x].r; - gg+=GPalette.BaseColors[x].g; - bb+=GPalette.BaseColors[x].b; - } - rr>>=8; - gg>>=8; - bb>>=8; - - palette_brightness = (rr*77 + gg*143 + bb*35)/255; - if (GLRenderer) GLRenderer->ClearTonemapPalette(); } diff --git a/src/gl/system/gl_framebuffer.h b/src/gl/system/gl_framebuffer.h index c83bb0e503..67d5969e5a 100644 --- a/src/gl/system/gl_framebuffer.h +++ b/src/gl/system/gl_framebuffer.h @@ -84,7 +84,6 @@ public: void SetVSync(bool vsync); - int palette_brightness; // brightness of the active palette - this is used for screen blends bool HWGammaActive = false; // Are we using hardware or software gamma? std::shared_ptr mDebug; // Debug API private: diff --git a/src/p_buildmap.cpp b/src/p_buildmap.cpp index 3d4e53aa94..6949ce9373 100644 --- a/src/p_buildmap.cpp +++ b/src/p_buildmap.cpp @@ -385,7 +385,6 @@ static bool P_LoadBloodMap (uint8_t *data, size_t len, FMapThing **mapthings, in static void LoadSectors (sectortype *bsec, int count) { - FDynamicColormap *map = GetSpecialLights (PalEntry (255,255,255), level.fadeto, 0); sector_t *sec; char tnam[9]; diff --git a/src/polyrenderer/drawers/poly_draw_args.cpp b/src/polyrenderer/drawers/poly_draw_args.cpp index 8d7687f64d..89e5a69f34 100644 --- a/src/polyrenderer/drawers/poly_draw_args.cpp +++ b/src/polyrenderer/drawers/poly_draw_args.cpp @@ -33,6 +33,7 @@ #include "r_data/r_translate.h" #include "v_palette.h" #include "r_data/colormaps.h" +#include "swrenderer/r_swcolormaps.h" #include "poly_draw_args.h" #include "swrenderer/viewport/r_viewport.h" diff --git a/src/polyrenderer/poly_renderer.cpp b/src/polyrenderer/poly_renderer.cpp index 0dd147b122..23f6591747 100644 --- a/src/polyrenderer/poly_renderer.cpp +++ b/src/polyrenderer/poly_renderer.cpp @@ -37,6 +37,7 @@ #include "swrenderer/scene/r_light.h" #include "swrenderer/drawers/r_draw_rgba.h" #include "swrenderer/viewport/r_viewport.h" +#include "swrenderer/r_swcolormaps.h" EXTERN_CVAR(Bool, r_shadercolormaps) EXTERN_CVAR(Int, screenblocks) @@ -122,6 +123,11 @@ void PolyRenderer::RenderActorView(AActor *actor, bool dontmaplines) P_FindParticleSubsectors(); PO_LinkToSubsectors(); R_SetupFrame(Thread.Viewport->viewpoint, Thread.Viewport->viewwindow, actor); + + if (APART(R_OldBlend)) NormalLight.Maps = realcolormaps.Maps; + else NormalLight.Maps = realcolormaps.Maps + NUMCOLORMAPS * 256 * R_OldBlend; + + swrenderer::CameraLight::Instance()->SetCamera(Thread.Viewport.get(), actor); Thread.Viewport->SetupFreelook(); diff --git a/src/polyrenderer/scene/poly_playersprite.cpp b/src/polyrenderer/scene/poly_playersprite.cpp index 2b4e3cfb1b..851c57a640 100644 --- a/src/polyrenderer/scene/poly_playersprite.cpp +++ b/src/polyrenderer/scene/poly_playersprite.cpp @@ -308,7 +308,7 @@ void RenderPolyPlayerSprites::RenderSprite(DPSprite *sprite, AActor *owner, floa if (visstyle.Invert) { - BaseColormap = &SpecialColormaps[INVERSECOLORMAP]; + BaseColormap = &SpecialSWColormaps[INVERSECOLORMAP]; ColormapNum = 0; if (BaseColormap->Maps < mybasecolormap->Maps || BaseColormap->Maps >= mybasecolormap->Maps + NUMCOLORMAPS * 256) { @@ -319,8 +319,8 @@ void RenderPolyPlayerSprites::RenderSprite(DPSprite *sprite, AActor *owner, floa // If we're drawing with a special colormap, but shaders for them are disabled, do // not accelerate. - if (!r_shadercolormaps && (BaseColormap >= &SpecialColormaps[0] && - BaseColormap <= &SpecialColormaps.Last())) + if (!r_shadercolormaps && (BaseColormap >= &SpecialSWColormaps[0] && + BaseColormap <= &SpecialSWColormaps.Last())) { noaccel = true; } @@ -405,10 +405,10 @@ void PolyScreenSprite::Render() FColormapStyle colormapstyle; PalEntry overlay = 0; bool usecolormapstyle = false; - if (BaseColormap >= &SpecialColormaps[0] && - BaseColormap < &SpecialColormaps[SpecialColormaps.Size()]) + if (BaseColormap >= &SpecialSWColormaps[0] && + BaseColormap < &SpecialSWColormaps[SpecialColormaps.Size()]) { - special = static_cast(BaseColormap); + special = &SpecialColormaps[BaseColormap - &SpecialSWColormaps[0]]; } else if (Colormap->Color == PalEntry(255, 255, 255) && Colormap->Desaturate == 0) diff --git a/src/r_data/colormaps.cpp b/src/r_data/colormaps.cpp index f87a70c3ec..cce900a80b 100644 --- a/src/r_data/colormaps.cpp +++ b/src/r_data/colormaps.cpp @@ -1,5 +1,6 @@ /* -** r_data.cpp +** colormaps.cpp +** common Colormap handling ** **--------------------------------------------------------------------------- ** Copyright 1998-2008 Randy Heit @@ -54,27 +55,7 @@ #include "r_utility.h" #include "r_renderer.h" -static bool R_CheckForFixedLights(const uint8_t *colormaps); - - -FDynamicColormap NormalLight; -FDynamicColormap FullNormalLight; //[SP] Emulate GZDoom brightness -bool NormalLightHasFixedLights; - - -struct FakeCmap -{ - char name[8]; - PalEntry blend; - int lump; -}; - TArray fakecmaps; -FSWColormap realcolormaps; -FSWColormap realfbcolormaps; //[SP] For fullbright use -size_t numfakecmaps; - - TArray SpecialColormaps; uint8_t DesaturateColormap[31][256]; @@ -176,273 +157,6 @@ int AddSpecialColormap(float r1, float g1, float b1, float r2, float g2, float b return SpecialColormaps.Size() - 1; } - -//========================================================================== -// -// Colored Lighting Stuffs -// -//========================================================================== - -FDynamicColormap *GetSpecialLights (PalEntry color, PalEntry fade, int desaturate) -{ - FDynamicColormap *colormap; - - // If this colormap has already been created, just return it - for (colormap = &NormalLight; colormap != NULL; colormap = colormap->Next) - { - if (color == colormap->Color && - fade == colormap->Fade && - desaturate == colormap->Desaturate) - { - return colormap; - } - } - - // Not found. Create it. - colormap = new FDynamicColormap; - colormap->Next = NormalLight.Next; - colormap->Color = color; - colormap->Fade = fade; - colormap->Desaturate = desaturate; - NormalLight.Next = colormap; - - if (Renderer->UsesColormap()) - { - colormap->Maps = new uint8_t[NUMCOLORMAPS*256]; - colormap->BuildLights (); - } - else colormap->Maps = NULL; - return colormap; -} - -//========================================================================== -// -// Free all lights created with GetSpecialLights -// -//========================================================================== - -static void FreeSpecialLights() -{ - FDynamicColormap *colormap, *next; - - for (colormap = NormalLight.Next; colormap != NULL; colormap = next) - { - next = colormap->Next; - delete[] colormap->Maps; - delete colormap; - } - NormalLight.Next = NULL; -} - -//========================================================================== -// -// Builds NUMCOLORMAPS colormaps lit with the specified color -// -//========================================================================== - -void FDynamicColormap::BuildLights () -{ - int l, c; - int lr, lg, lb, ld, ild; - PalEntry colors[256], basecolors[256]; - uint8_t *shade; - - if (Maps == NULL) - return; - - // Scale light to the range 0-256, so we can avoid - // dividing by 255 in the bottom loop. - lr = Color.r*256/255; - lg = Color.g*256/255; - lb = Color.b*256/255; - ld = Desaturate*256/255; - if (ld < 0) // No negative desaturations, please. - { - ld = -ld; - } - ild = 256-ld; - - if (ld == 0) - { - memcpy (basecolors, GPalette.BaseColors, sizeof(basecolors)); - } - else - { - // Desaturate the palette before lighting it. - for (c = 0; c < 256; c++) - { - int r = GPalette.BaseColors[c].r; - int g = GPalette.BaseColors[c].g; - int b = GPalette.BaseColors[c].b; - int intensity = ((r * 77 + g * 143 + b * 37) >> 8) * ld; - basecolors[c].r = (r*ild + intensity) >> 8; - basecolors[c].g = (g*ild + intensity) >> 8; - basecolors[c].b = (b*ild + intensity) >> 8; - basecolors[c].a = 0; - } - } - - // build normal (but colored) light mappings - for (l = 0; l < NUMCOLORMAPS; l++) - { - DoBlending (basecolors, colors, 256, - Fade.r, Fade.g, Fade.b, l * (256 / NUMCOLORMAPS)); - - shade = Maps + 256*l; - if ((uint32_t)Color == MAKERGB(255,255,255)) - { // White light, so we can just pick the colors directly - for (c = 0; c < 256; c++) - { - *shade++ = ColorMatcher.Pick (colors[c].r, colors[c].g, colors[c].b); - } - } - else - { // Colored light, so do the (slightly) slower thing - for (c = 0; c < 256; c++) - { - *shade++ = ColorMatcher.Pick ( - (colors[c].r*lr)>>8, - (colors[c].g*lg)>>8, - (colors[c].b*lb)>>8); - } - } - } -} - -//========================================================================== -// -// -// -//========================================================================== - -void FDynamicColormap::ChangeColor (PalEntry lightcolor, int desaturate) -{ - if (lightcolor != Color || desaturate != Desaturate) - { - Color = lightcolor; - // [BB] desaturate must be in [0,255] - Desaturate = clamp(desaturate, 0, 255); - if (Maps) BuildLights (); - } -} - -//========================================================================== -// -// -// -//========================================================================== - -void FDynamicColormap::ChangeFade (PalEntry fadecolor) -{ - if (fadecolor != Fade) - { - Fade = fadecolor; - if (Maps) BuildLights (); - } -} - -//========================================================================== -// -// -// -//========================================================================== - -void FDynamicColormap::ChangeColorFade (PalEntry lightcolor, PalEntry fadecolor) -{ - if (lightcolor != Color || fadecolor != Fade) - { - Color = lightcolor; - Fade = fadecolor; - if (Maps) BuildLights (); - } -} - -//========================================================================== -// -// -// -//========================================================================== - -void FDynamicColormap::RebuildAllLights() -{ - if (Renderer->UsesColormap()) - { - FDynamicColormap *cm; - - for (cm = &NormalLight; cm != NULL; cm = cm->Next) - { - if (cm->Maps == NULL) - { - cm->Maps = new uint8_t[NUMCOLORMAPS*256]; - cm->BuildLights (); - } - } - } -} - -//========================================================================== -// -// R_SetDefaultColormap -// -//========================================================================== - -void R_SetDefaultColormap (const char *name) -{ - if (strnicmp (fakecmaps[0].name, name, 8) != 0) - { - int lump, i, j; - uint8_t map[256]; - uint8_t unremap[256]; - uint8_t remap[256]; - - lump = Wads.CheckNumForFullName (name, true, ns_colormaps); - if (lump == -1) - lump = Wads.CheckNumForName (name, ns_global); - - // [RH] If using BUILD's palette, generate the colormap - if (lump == -1 || Wads.CheckNumForFullName("palette.dat") >= 0 || Wads.CheckNumForFullName("blood.pal") >= 0) - { - Printf ("Make colormap\n"); - FDynamicColormap foo; - - foo.Color = 0xFFFFFF; - foo.Fade = 0; - foo.Maps = realcolormaps.Maps; - foo.Desaturate = 0; - foo.Next = NULL; - foo.BuildLights (); - } - else - { - FWadLump lumpr = Wads.OpenLumpNum (lump); - - // [RH] The colormap may not have been designed for the specific - // palette we are using, so remap it to match the current palette. - memcpy (remap, GPalette.Remap, 256); - memset (unremap, 0, 256); - for (i = 0; i < 256; ++i) - { - unremap[remap[i]] = i; - } - // Mapping to color 0 is okay, because the colormap won't be used to - // produce a masked texture. - remap[0] = 0; - for (i = 0; i < NUMCOLORMAPS; ++i) - { - uint8_t *map2 = &realcolormaps.Maps[i*256]; - lumpr.Read (map, 256); - for (j = 0; j < 256; ++j) - { - map2[j] = remap[map[unremap[j]]]; - } - } - } - - uppercopy (fakecmaps[0].name, name); - fakecmaps[0].blend = 0; - } -} - //========================================================================== // // R_DeinitColormaps @@ -453,13 +167,6 @@ void R_DeinitColormaps () { SpecialColormaps.Clear(); fakecmaps.Clear(); - delete[] realcolormaps.Maps; - if (realfbcolormaps.Maps) - { - delete[] realfbcolormaps.Maps; - realfbcolormaps.Maps = nullptr; - } - FreeSpecialLights(); } //========================================================================== @@ -501,41 +208,32 @@ void R_InitColormaps () } } } - realcolormaps.Maps = new uint8_t[256*NUMCOLORMAPS*fakecmaps.Size()]; - R_SetDefaultColormap ("COLORMAP"); + int rr = 0, gg = 0, bb = 0; + for(int x=0;x<256;x++) + { + rr += GPalette.BaseColors[x].r; + gg += GPalette.BaseColors[x].g; + bb += GPalette.BaseColors[x].b; + } + rr >>= 8; + gg >>= 8; + bb >>= 8; + + int palette_brightness = (rr*77 + gg*143 + bb*35) / 255; + + // To calculate the blend it will just average the colors of the first map if (fakecmaps.Size() > 1) { - uint8_t unremap[256], remap[256], mapin[256]; - int i; - unsigned j; + uint8_t map[256]; - memcpy (remap, GPalette.Remap, 256); - memset (unremap, 0, 256); - for (i = 0; i < 256; ++i) + for (unsigned j = 1; j < fakecmaps.Size(); j++) { - unremap[remap[i]] = i; - } - remap[0] = 0; - for (j = 1; j < fakecmaps.Size(); j++) - { - if (Wads.LumpLength (fakecmaps[j].lump) >= (NUMCOLORMAPS+1)*256) + if (Wads.LumpLength (fakecmaps[j].lump) >= 256) { int k, r, g, b; FWadLump lump = Wads.OpenLumpNum (fakecmaps[j].lump); - uint8_t *const map = realcolormaps.Maps + NUMCOLORMAPS*256*j; - - for (k = 0; k < NUMCOLORMAPS; ++k) - { - uint8_t *map2 = &map[k*256]; - lump.Read (mapin, 256); - map2[0] = 0; - for (r = 1; r < 256; ++r) - { - map2[r] = remap[mapin[unremap[r]]]; - } - } - + lump.Read(map, 256); r = g = b = 0; for (k = 0; k < 256; k++) @@ -544,27 +242,17 @@ void R_InitColormaps () g += GPalette.BaseColors[map[k]].g; b += GPalette.BaseColors[map[k]].b; } - fakecmaps[j].blend = PalEntry (255, r/256, g/256, b/256); + r /= 256; + g /= 256; + b /= 256; + // The calculated average is too dark so brighten it according to the palettes's overall brightness + int maxcol = MAX(MAX(palette_brightness, r), MAX(g, b)); + + fakecmaps[j].blend = PalEntry (255, r * 255 / maxcol, g * 255 / maxcol, b * 255 / maxcol); } } } - // [SP] Create a copy of the colormap - if (!realfbcolormaps.Maps) - { - realfbcolormaps.Maps = new uint8_t[256*NUMCOLORMAPS*fakecmaps.Size()]; - memcpy(realfbcolormaps.Maps, realcolormaps.Maps, 256*NUMCOLORMAPS*fakecmaps.Size()); - } - - NormalLight.Color = PalEntry (255, 255, 255); - NormalLight.Fade = 0; - NormalLight.Maps = realcolormaps.Maps; - FullNormalLight.Color = PalEntry (255, 255, 255); - FullNormalLight.Fade = 0; - FullNormalLight.Maps = realfbcolormaps.Maps; - NormalLightHasFixedLights = R_CheckForFixedLights(realcolormaps.Maps); - numfakecmaps = fakecmaps.Size(); - // build default special maps (e.g. invulnerability) for (unsigned i = 0; i < countof(SpecialColormapParms); ++i) @@ -591,54 +279,6 @@ void R_InitColormaps () } } -//========================================================================== -// -// R_CheckForFixedLights -// -// Returns true if there are any entries in the colormaps that are the -// same for every colormap and not the fade color. -// -//========================================================================== - -static bool R_CheckForFixedLights(const uint8_t *colormaps) -{ - const uint8_t *lastcolormap = colormaps + (NUMCOLORMAPS - 1) * 256; - uint8_t freq[256]; - int i, j; - - // Count the frequencies of different colors in the final colormap. - // If they occur more than X amount of times, we ignore them as a - // potential fixed light. - - memset(freq, 0, sizeof(freq)); - for (i = 0; i < 256; ++i) - { - freq[lastcolormap[i]]++; - } - - // Now check the colormaps for fixed lights that are uncommon in the - // final coloramp. - for (i = 255; i >= 0; --i) - { - uint8_t color = lastcolormap[i]; - if (freq[color] > 10) // arbitrary number to decide "common" colors - { - continue; - } - // It's rare in the final colormap. See if it's the same for all colormaps. - for (j = 0; j < NUMCOLORMAPS - 1; ++j) - { - if (colormaps[j * 256 + i] != color) - break; - } - if (j == NUMCOLORMAPS - 1) - { // It was the same all the way across. - return true; - } - } - return false; -} - //========================================================================== // // [RH] Returns an index into realcolormaps. Multiply it by @@ -675,4 +315,5 @@ uint32_t R_BlendForColormap (uint32_t map) { return APART(map) ? map : map < fakecmaps.Size() ? uint32_t(fakecmaps[map].blend) : 0; -} \ No newline at end of file +} + diff --git a/src/r_data/colormaps.h b/src/r_data/colormaps.h index cbb0bf1fad..dc6c51c327 100644 --- a/src/r_data/colormaps.h +++ b/src/r_data/colormaps.h @@ -1,9 +1,6 @@ #ifndef __RES_CMAP_H #define __RES_CMAP_H -#include "m_fixed.h" - -struct FSWColormap; struct lightlist_t; void R_InitColormaps (); @@ -12,8 +9,15 @@ void R_DeinitColormaps (); uint32_t R_ColormapNumForName(const char *name); // killough 4/4/98 void R_SetDefaultColormap (const char *name); // [RH] change normal fadetable uint32_t R_BlendForColormap (uint32_t map); // [RH] return calculated blend for a colormap -extern FSWColormap realcolormaps; // [RH] make the colormaps externally visible -extern size_t numfakecmaps; + +struct FakeCmap +{ + char name[8]; + PalEntry blend; + int lump; +}; + +extern TArray fakecmaps; // for internal use struct FColormap @@ -79,25 +83,6 @@ struct FColormap }; -struct FSWColormap -{ - uint8_t *Maps = nullptr; - PalEntry Color = 0xffffffff; - PalEntry Fade = 0xff000000; - int Desaturate = 0; -}; - -struct FDynamicColormap : FSWColormap -{ - void ChangeFade (PalEntry fadecolor); - void ChangeColor (PalEntry lightcolor, int desaturate); - void ChangeColorFade (PalEntry lightcolor, PalEntry fadecolor); - void ChangeFogDensity(int newdensity); - void BuildLights (); - static void RebuildAllLights(); - - FDynamicColormap *Next; -}; // For hardware-accelerated weapon sprites in colored sectors @@ -116,13 +101,8 @@ enum }; -struct FSpecialColormap : FSWColormap +struct FSpecialColormap { - FSpecialColormap() - { - Maps = Colormap; - } - float ColorizeStart[3]; float ColorizeEnd[3]; uint8_t Colormap[256]; @@ -145,23 +125,5 @@ int AddSpecialColormap(float r1, float g1, float b1, float r2, float g2, float b extern uint8_t DesaturateColormap[31][256]; -extern FDynamicColormap NormalLight; -extern FDynamicColormap FullNormalLight; -extern bool NormalLightHasFixedLights; - -FDynamicColormap *GetSpecialLights (PalEntry lightcolor, PalEntry fadecolor, int desaturate); - -__forceinline FDynamicColormap *GetColorTable(const FColormap &cm) -{ - auto p = &NormalLight; - if (cm.LightColor == p->Color && - cm.FadeColor == p->Fade && - cm.Desaturation == p->Desaturate) - { - return p; - } - - return GetSpecialLights(cm.LightColor, cm.FadeColor, cm.Desaturation); -} #endif diff --git a/src/r_renderer.h b/src/r_renderer.h index 1513430df9..3666638801 100644 --- a/src/r_renderer.h +++ b/src/r_renderer.h @@ -25,9 +25,6 @@ struct FRenderer Renderer = NULL; } - // Can be overridden so that the colormaps for sector color/fade won't be built. - virtual bool UsesColormap() const = 0; - // precache one texture virtual void Precache(uint8_t *texhitlist, TMap &actorhitlist) = 0; diff --git a/src/r_utility.cpp b/src/r_utility.cpp index a125fa3480..d2d80be661 100644 --- a/src/r_utility.cpp +++ b/src/r_utility.cpp @@ -871,7 +871,7 @@ void R_SetupFrame (FRenderViewpoint &viewpoint, FViewWindow &viewwindow, AActor : s->ceilingplane.PointOnSide(viewpoint.Pos) < 0 ? s->topmap : s->midmap; - if (APART(newblend) == 0 && newblend >= numfakecmaps) + if (APART(newblend) == 0 && newblend >= fakecmaps.Size()) newblend = 0; } } @@ -888,11 +888,9 @@ void R_SetupFrame (FRenderViewpoint &viewpoint, FViewWindow &viewwindow, AActor BaseBlendG = GPART(newblend); BaseBlendB = BPART(newblend); BaseBlendA = APART(newblend) / 255.f; - NormalLight.Maps = realcolormaps.Maps; } else { - NormalLight.Maps = realcolormaps.Maps + NUMCOLORMAPS*256*newblend; BaseBlendR = BaseBlendG = BaseBlendB = 0; BaseBlendA = 0.f; } diff --git a/src/serializer.h b/src/serializer.h index cea8df36d8..288296bc00 100644 --- a/src/serializer.h +++ b/src/serializer.h @@ -248,7 +248,6 @@ template<> FSerializer &Serialize(FSerializer &arc, const char *key, player_t *& template<> FSerializer &Serialize(FSerializer &arc, const char *key, line_t *&value, line_t **defval); template<> FSerializer &Serialize(FSerializer &arc, const char *key, side_t *&value, side_t **defval); template<> FSerializer &Serialize(FSerializer &arc, const char *key, vertex_t *&value, vertex_t **defval); -template<> FSerializer &Serialize(FSerializer &arc, const char *key, FDynamicColormap *&cm, FDynamicColormap **def); template<> FSerializer &Serialize(FSerializer &arc, const char *key, PClassActor *&clst, PClassActor **def); template<> FSerializer &Serialize(FSerializer &arc, const char *key, PClass *&clst, PClass **def); template<> FSerializer &Serialize(FSerializer &arc, const char *key, FStrifeDialogueNode *&node, FStrifeDialogueNode **def); diff --git a/src/st_start.h b/src/st_start.h index 8ee116b9ae..a55b471977 100644 --- a/src/st_start.h +++ b/src/st_start.h @@ -1,3 +1,4 @@ +#pragma once /* ** st_start.h ** Interface for the startup screen. diff --git a/src/swrenderer/line/r_renderdrawsegment.cpp b/src/swrenderer/line/r_renderdrawsegment.cpp index 5233bb94e8..a4b52bac00 100644 --- a/src/swrenderer/line/r_renderdrawsegment.cpp +++ b/src/swrenderer/line/r_renderdrawsegment.cpp @@ -691,7 +691,7 @@ namespace swrenderer } } // correct colors now - FDynamicColormap *basecolormap = GetColorTable(frontsector->Colormap); + FDynamicColormap *basecolormap = nullptr; wallshade = ds->shade; CameraLight *cameraLight = CameraLight::Instance(); if (cameraLight->FixedLightLevel() < 0) @@ -725,6 +725,8 @@ namespace swrenderer } } } + if (basecolormap == nullptr) basecolormap = GetColorTable(frontsector->Colormap); + if (rw_pic != DONT_DRAW) { RenderFakeWall(ds, x1, x2, fover ? fover : rover, wallshade, basecolormap); @@ -868,7 +870,7 @@ namespace swrenderer } } // correct colors now - FDynamicColormap *basecolormap = GetColorTable(frontsector->Colormap); + FDynamicColormap *basecolormap = nullptr; wallshade = ds->shade; CameraLight *cameraLight = CameraLight::Instance(); if (cameraLight->FixedLightLevel() < 0) @@ -902,6 +904,7 @@ namespace swrenderer } } } + if (basecolormap == nullptr) basecolormap = GetColorTable(frontsector->Colormap); if (rw_pic != DONT_DRAW) { diff --git a/src/swrenderer/r_all.cpp b/src/swrenderer/r_all.cpp index d2e4e97d4f..20a9f4ee85 100644 --- a/src/swrenderer/r_all.cpp +++ b/src/swrenderer/r_all.cpp @@ -2,6 +2,7 @@ #include "r_renderthread.cpp" #include "r_swcanvas.cpp" #include "r_swrenderer.cpp" +#include "r_swcolormaps.cpp" #include "drawers/r_draw.cpp" #include "drawers/r_draw_pal.cpp" #include "drawers/r_draw_rgba.cpp" diff --git a/src/swrenderer/r_swcanvas.cpp b/src/swrenderer/r_swcanvas.cpp index b70a6a9655..f888e34c4e 100644 --- a/src/swrenderer/r_swcanvas.cpp +++ b/src/swrenderer/r_swcanvas.cpp @@ -38,6 +38,7 @@ #include "v_palette.h" #include "v_video.h" #include "m_png.h" +#include "r_swcolormaps.h" #include "colormatcher.h" #include "r_swcanvas.h" #include "textures/textures.h" diff --git a/src/swrenderer/r_swcolormaps.cpp b/src/swrenderer/r_swcolormaps.cpp new file mode 100644 index 0000000000..f9d38f393a --- /dev/null +++ b/src/swrenderer/r_swcolormaps.cpp @@ -0,0 +1,544 @@ +/* +** r_swcolormaps.cpp +** Colormap handling for the software renderer +** +**--------------------------------------------------------------------------- +** Copyright 1998-2008 Randy Heit +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +** +*/ + +#include +#include +#include +#include + +#include "i_system.h" +#include "w_wad.h" +#include "doomdef.h" +#include "r_sky.h" +#include "c_dispatch.h" +#include "sc_man.h" +#include "v_text.h" +#include "st_start.h" +#include "doomstat.h" +#include "v_palette.h" +#include "colormatcher.h" +#include "r_data/colormaps.h" +#include "r_swcolormaps.h" +#include "v_video.h" +#include "templates.h" +#include "r_utility.h" +#include "r_renderer.h" + +FDynamicColormap NormalLight; +FDynamicColormap FullNormalLight; //[SP] Emulate GZDoom brightness +bool NormalLightHasFixedLights; + +FSWColormap realcolormaps; +FSWColormap realfbcolormaps; //[SP] For fullbright use +TArray SpecialSWColormaps; + +//========================================================================== +// +// Colored Lighting Stuffs +// +//========================================================================== + +FDynamicColormap *GetSpecialLights (PalEntry color, PalEntry fade, int desaturate) +{ + FDynamicColormap *colormap; + + // If this colormap has already been created, just return it + for (colormap = &NormalLight; colormap != NULL; colormap = colormap->Next) + { + if (color == colormap->Color && + fade == colormap->Fade && + desaturate == colormap->Desaturate) + { + return colormap; + } + } + + // Not found. Create it. + colormap = new FDynamicColormap; + colormap->Next = NormalLight.Next; + colormap->Color = color; + colormap->Fade = fade; + colormap->Desaturate = desaturate; + NormalLight.Next = colormap; + + colormap->Maps = new uint8_t[NUMCOLORMAPS*256]; + colormap->BuildLights (); + return colormap; +} + +//========================================================================== +// +// Free all lights created with GetSpecialLights +// +//========================================================================== + +static void FreeSpecialLights() +{ + FDynamicColormap *colormap, *next; + + for (colormap = NormalLight.Next; colormap != NULL; colormap = next) + { + next = colormap->Next; + delete[] colormap->Maps; + delete colormap; + } + NormalLight.Next = NULL; +} + +//========================================================================== +// +// Builds NUMCOLORMAPS colormaps lit with the specified color +// +//========================================================================== + +void FDynamicColormap::BuildLights () +{ + int l, c; + int lr, lg, lb, ld, ild; + PalEntry colors[256], basecolors[256]; + uint8_t *shade; + + if (Maps == NULL) + return; + + // Scale light to the range 0-256, so we can avoid + // dividing by 255 in the bottom loop. + lr = Color.r*256/255; + lg = Color.g*256/255; + lb = Color.b*256/255; + ld = Desaturate*256/255; + if (ld < 0) // No negative desaturations, please. + { + ld = -ld; + } + ild = 256-ld; + + if (ld == 0) + { + memcpy (basecolors, GPalette.BaseColors, sizeof(basecolors)); + } + else + { + // Desaturate the palette before lighting it. + for (c = 0; c < 256; c++) + { + int r = GPalette.BaseColors[c].r; + int g = GPalette.BaseColors[c].g; + int b = GPalette.BaseColors[c].b; + int intensity = ((r * 77 + g * 143 + b * 37) >> 8) * ld; + basecolors[c].r = (r*ild + intensity) >> 8; + basecolors[c].g = (g*ild + intensity) >> 8; + basecolors[c].b = (b*ild + intensity) >> 8; + basecolors[c].a = 0; + } + } + + // build normal (but colored) light mappings + for (l = 0; l < NUMCOLORMAPS; l++) + { + DoBlending (basecolors, colors, 256, + Fade.r, Fade.g, Fade.b, l * (256 / NUMCOLORMAPS)); + + shade = Maps + 256*l; + if ((uint32_t)Color == MAKERGB(255,255,255)) + { // White light, so we can just pick the colors directly + for (c = 0; c < 256; c++) + { + *shade++ = ColorMatcher.Pick (colors[c].r, colors[c].g, colors[c].b); + } + } + else + { // Colored light, so do the (slightly) slower thing + for (c = 0; c < 256; c++) + { + *shade++ = ColorMatcher.Pick ( + (colors[c].r*lr)>>8, + (colors[c].g*lg)>>8, + (colors[c].b*lb)>>8); + } + } + } +} + +//========================================================================== +// +// +// +//========================================================================== + +void FDynamicColormap::ChangeColor (PalEntry lightcolor, int desaturate) +{ + if (lightcolor != Color || desaturate != Desaturate) + { + Color = lightcolor; + // [BB] desaturate must be in [0,255] + Desaturate = clamp(desaturate, 0, 255); + if (Maps) BuildLights (); + } +} + +//========================================================================== +// +// +// +//========================================================================== + +void FDynamicColormap::ChangeFade (PalEntry fadecolor) +{ + if (fadecolor != Fade) + { + Fade = fadecolor; + if (Maps) BuildLights (); + } +} + +//========================================================================== +// +// +// +//========================================================================== + +void FDynamicColormap::ChangeColorFade (PalEntry lightcolor, PalEntry fadecolor) +{ + if (lightcolor != Color || fadecolor != Fade) + { + Color = lightcolor; + Fade = fadecolor; + if (Maps) BuildLights (); + } +} + +//========================================================================== +// +// +// +//========================================================================== + +void FDynamicColormap::RebuildAllLights() +{ + FDynamicColormap *cm; + + for (cm = &NormalLight; cm != NULL; cm = cm->Next) + { + if (cm->Maps == NULL) + { + cm->Maps = new uint8_t[NUMCOLORMAPS*256]; + cm->BuildLights (); + } + } +} + +//========================================================================== +// +// R_CheckForFixedLights +// +// Returns true if there are any entries in the colormaps that are the +// same for every colormap and not the fade color. +// +//========================================================================== + +static bool R_CheckForFixedLights(const uint8_t *colormaps) +{ + const uint8_t *lastcolormap = colormaps + (NUMCOLORMAPS - 1) * 256; + uint8_t freq[256]; + int i, j; + + // Count the frequencies of different colors in the final colormap. + // If they occur more than X amount of times, we ignore them as a + // potential fixed light. + + memset(freq, 0, sizeof(freq)); + for (i = 0; i < 256; ++i) + { + freq[lastcolormap[i]]++; + } + + // Now check the colormaps for fixed lights that are uncommon in the + // final coloramp. + for (i = 255; i >= 0; --i) + { + uint8_t color = lastcolormap[i]; + if (freq[color] > 10) // arbitrary number to decide "common" colors + { + continue; + } + // It's rare in the final colormap. See if it's the same for all colormaps. + for (j = 0; j < NUMCOLORMAPS - 1; ++j) + { + if (colormaps[j * 256 + i] != color) + break; + } + if (j == NUMCOLORMAPS - 1) + { // It was the same all the way across. + return true; + } + } + return false; +} + +//========================================================================== +// +// R_SetDefaultColormap +// +//========================================================================== + +static void SetDefaultColormap (const char *name) +{ + if (strnicmp (fakecmaps[0].name, name, 8) != 0) + { + int lump, i, j; + uint8_t map[256]; + uint8_t unremap[256]; + uint8_t remap[256]; + + lump = Wads.CheckNumForFullName (name, true, ns_colormaps); + if (lump == -1) + lump = Wads.CheckNumForName (name, ns_global); + + // [RH] If using BUILD's palette, generate the colormap + if (lump == -1 || Wads.CheckNumForFullName("palette.dat") >= 0 || Wads.CheckNumForFullName("blood.pal") >= 0) + { + Printf ("Make colormap\n"); + FDynamicColormap foo; + + foo.Color = 0xFFFFFF; + foo.Fade = 0; + foo.Maps = realcolormaps.Maps; + foo.Desaturate = 0; + foo.Next = NULL; + foo.BuildLights (); + } + else + { + FWadLump lumpr = Wads.OpenLumpNum (lump); + + // [RH] The colormap may not have been designed for the specific + // palette we are using, so remap it to match the current palette. + memcpy (remap, GPalette.Remap, 256); + memset (unremap, 0, 256); + for (i = 0; i < 256; ++i) + { + unremap[remap[i]] = i; + } + // Mapping to color 0 is okay, because the colormap won't be used to + // produce a masked texture. + remap[0] = 0; + for (i = 0; i < NUMCOLORMAPS; ++i) + { + uint8_t *map2 = &realcolormaps.Maps[i*256]; + lumpr.Read (map, 256); + for (j = 0; j < 256; ++j) + { + map2[j] = remap[map[unremap[j]]]; + } + } + } + } +} + +//========================================================================== +// +// R_InitColormaps +// +//========================================================================== + +static void InitBoomColormaps () +{ + // [RH] Try and convert BOOM colormaps into blending values. + // This is a really rough hack, but it's better than + // not doing anything with them at all (right?) + + uint32_t NumLumps = Wads.GetNumLumps(); + + realcolormaps.Maps = new uint8_t[256*NUMCOLORMAPS*fakecmaps.Size()]; + SetDefaultColormap ("COLORMAP"); + + if (fakecmaps.Size() > 1) + { + uint8_t unremap[256], remap[256], mapin[256]; + int i; + unsigned j; + + memcpy (remap, GPalette.Remap, 256); + memset (unremap, 0, 256); + for (i = 0; i < 256; ++i) + { + unremap[remap[i]] = i; + } + remap[0] = 0; + for (j = 1; j < fakecmaps.Size(); j++) + { + if (Wads.LumpLength (fakecmaps[j].lump) >= (NUMCOLORMAPS+1)*256) + { + int k, r; + FWadLump lump = Wads.OpenLumpNum (fakecmaps[j].lump); + uint8_t *const map = realcolormaps.Maps + NUMCOLORMAPS*256*j; + + for (k = 0; k < NUMCOLORMAPS; ++k) + { + uint8_t *map2 = &map[k*256]; + lump.Read (mapin, 256); + map2[0] = 0; + for (r = 1; r < 256; ++r) + { + map2[r] = remap[mapin[unremap[r]]]; + } + } + } + } + } +} + +//========================================================================== +// +// +// +//========================================================================== + +static void DeinitSWColorMaps() +{ + FreeSpecialLights(); + if (realcolormaps.Maps != nullptr) + { + delete[] realcolormaps.Maps; + realcolormaps.Maps = nullptr; + } + if (realfbcolormaps.Maps) + { + delete[] realfbcolormaps.Maps; + realfbcolormaps.Maps = nullptr; + } +} + +//========================================================================== +// +// +// +//========================================================================== + +void InitSWColorMaps() +{ + DeinitSWColorMaps(); + atterm(DeinitSWColorMaps); + InitBoomColormaps(); + NormalLight.Color = PalEntry (255, 255, 255); + NormalLight.Fade = 0; + NormalLight.Maps = realcolormaps.Maps; + NormalLightHasFixedLights = R_CheckForFixedLights(realcolormaps.Maps); + + // [SP] Create a copy of the colormap + if (!realfbcolormaps.Maps) + { + realfbcolormaps.Maps = new uint8_t[256*NUMCOLORMAPS*fakecmaps.Size()]; + memcpy(realfbcolormaps.Maps, realcolormaps.Maps, 256*NUMCOLORMAPS*fakecmaps.Size()); + } + FullNormalLight.Color = PalEntry(255, 255, 255); + FullNormalLight.Fade = 0; + FullNormalLight.Maps = realfbcolormaps.Maps; + + SpecialSWColormaps.Resize(SpecialColormaps.Size()); + for(unsigned i = 0; i < SpecialColormaps.Size(); i++) + { + SpecialSWColormaps[i].Maps = SpecialColormaps[i].Colormap; + } +} + +//========================================================================== +// +// +// +//========================================================================== + +CCMD (testfade) +{ + FString colorstring; + uint32_t color; + + if (argv.argc() < 2) + { + Printf ("testfade \n"); + } + else + { + if ( !(colorstring = V_GetColorStringByName (argv[1])).IsEmpty() ) + { + color = V_GetColorFromString (NULL, colorstring); + } + else + { + color = V_GetColorFromString (NULL, argv[1]); + } + level.fadeto = color; + NormalLight.ChangeFade (color); + } +} + +//========================================================================== +// +// +// +//========================================================================== + +CCMD (testcolor) +{ + FString colorstring; + uint32_t color; + int desaturate; + + if (argv.argc() < 2) + { + Printf ("testcolor [desaturation]\n"); + } + else + { + if ( !(colorstring = V_GetColorStringByName (argv[1])).IsEmpty() ) + { + color = V_GetColorFromString (NULL, colorstring); + } + else + { + color = V_GetColorFromString (NULL, argv[1]); + } + if (argv.argc() > 2) + { + desaturate = atoi (argv[2]); + } + else + { + desaturate = NormalLight.Desaturate; + } + NormalLight.ChangeColor (color, desaturate); + } +} diff --git a/src/swrenderer/r_swcolormaps.h b/src/swrenderer/r_swcolormaps.h new file mode 100644 index 0000000000..4b2e136044 --- /dev/null +++ b/src/swrenderer/r_swcolormaps.h @@ -0,0 +1,60 @@ +#pragma once + + + +struct FSWColormap +{ + uint8_t *Maps = nullptr; + PalEntry Color = 0xffffffff; + PalEntry Fade = 0xff000000; + int Desaturate = 0; +}; + +struct FDynamicColormap : FSWColormap +{ + void ChangeFade (PalEntry fadecolor); + void ChangeColor (PalEntry lightcolor, int desaturate); + void ChangeColorFade (PalEntry lightcolor, PalEntry fadecolor); + void ChangeFogDensity(int newdensity); + void BuildLights (); + static void RebuildAllLights(); + + FDynamicColormap *Next; +}; + +extern FSWColormap realcolormaps; // [RH] make the colormaps externally visible + +extern FDynamicColormap NormalLight; +extern FDynamicColormap FullNormalLight; +extern bool NormalLightHasFixedLights; +extern TArray SpecialSWColormaps; + +void InitSWColorMaps(); +FDynamicColormap *GetSpecialLights (PalEntry lightcolor, PalEntry fadecolor, int desaturate); +void SetDefaultColormap (const char *name); + + +// Give the compiler a strong hint we want these functions inlined: +#ifndef FORCEINLINE +#if defined(_MSC_VER) +#define FORCEINLINE __forceinline +#elif defined(__GNUC__) +#define FORCEINLINE __attribute__((always_inline)) inline +#else +#define FORCEINLINE inline +#endif +#endif + +// MSVC needs the forceinline here. +FORCEINLINE FDynamicColormap *GetColorTable(const FColormap &cm) +{ + auto p = &NormalLight; + if (cm.LightColor == p->Color && + cm.FadeColor == p->Fade && + cm.Desaturation == p->Desaturate) + { + return p; + } + + return GetSpecialLights(cm.LightColor, cm.FadeColor, cm.Desaturation); +} diff --git a/src/swrenderer/r_swrenderer.cpp b/src/swrenderer/r_swrenderer.cpp index 07b6480cfe..bfc17895ef 100644 --- a/src/swrenderer/r_swrenderer.cpp +++ b/src/swrenderer/r_swrenderer.cpp @@ -49,6 +49,7 @@ #include "drawers/r_draw_rgba.h" #include "polyrenderer/poly_renderer.h" #include "p_setup.h" +#include "g_levellocals.h" void gl_InitData(); void gl_PreprocessLevel(); @@ -84,11 +85,7 @@ FSoftwareRenderer::~FSoftwareRenderer() void FSoftwareRenderer::Init() { mScene.Init(); -} - -bool FSoftwareRenderer::UsesColormap() const -{ - return true; + InitSWColorMaps(); } void FSoftwareRenderer::PrecacheTexture(FTexture *tex, int cache) @@ -356,6 +353,19 @@ void FSoftwareRenderer::RenderTextureView (FCanvasTexture *tex, AActor *viewpoin void FSoftwareRenderer::PreprocessLevel() { gl_PreprocessLevel(); + // This just sets the default colormap for the spftware renderer. + NormalLight.Maps = realcolormaps.Maps; + NormalLight.ChangeColor(PalEntry(255, 255, 255), 0); + NormalLight.ChangeFade(level.fadeto); + + if (level.fadeto == 0) + { + SetDefaultColormap(level.info->FadeTable); + if (level.flags & LEVEL_HASFADETABLE) + { + level.fadeto = 0xff939393; //[SP] Hexen True-color compatibility, just use gray. + } + } } void FSoftwareRenderer::CleanLevelData() @@ -372,3 +382,4 @@ void FSoftwareRenderer::SetVisibility(double vis) { mScene.MainThread()->Light->SetVisibility(mScene.MainThread()->Viewport.get(), vis); } + diff --git a/src/swrenderer/r_swrenderer.h b/src/swrenderer/r_swrenderer.h index 640731ae3c..eeb6fd36c0 100644 --- a/src/swrenderer/r_swrenderer.h +++ b/src/swrenderer/r_swrenderer.h @@ -9,9 +9,6 @@ struct FSoftwareRenderer : public FRenderer FSoftwareRenderer(); ~FSoftwareRenderer(); - // Can be overridden so that the colormaps for sector color/fade won't be built. - bool UsesColormap() const override; - // precache textures void Precache(uint8_t *texhitlist, TMap &actorhitlist) override; diff --git a/src/swrenderer/scene/r_light.cpp b/src/swrenderer/scene/r_light.cpp index 97f09bad9c..6e61e3b99b 100644 --- a/src/swrenderer/scene/r_light.cpp +++ b/src/swrenderer/scene/r_light.cpp @@ -70,7 +70,7 @@ namespace swrenderer } else { - fixedcolormap = &SpecialColormaps[player->fixedcolormap]; + fixedcolormap = &SpecialSWColormaps[player->fixedcolormap]; } } else if (player->fixedlightlevel >= 0 && player->fixedlightlevel < NUMCOLORMAPS) @@ -86,7 +86,7 @@ namespace swrenderer // [RH] Inverse light for shooting the Sigil if (fixedcolormap == nullptr && viewport->viewpoint.extralight == INT_MIN) { - fixedcolormap = &SpecialColormaps[INVERSECOLORMAP]; + fixedcolormap = &SpecialSWColormaps[INVERSECOLORMAP]; viewport->viewpoint.extralight = 0; } } diff --git a/src/swrenderer/scene/r_scene.cpp b/src/swrenderer/scene/r_scene.cpp index f4ba352b70..0c9d6028d9 100644 --- a/src/swrenderer/scene/r_scene.cpp +++ b/src/swrenderer/scene/r_scene.cpp @@ -122,6 +122,10 @@ namespace swrenderer WallScanCycles.Reset(); R_SetupFrame(MainThread()->Viewport->viewpoint, MainThread()->Viewport->viewwindow, actor); + + if (APART(R_OldBlend)) NormalLight.Maps = realcolormaps.Maps; + else NormalLight.Maps = realcolormaps.Maps + NUMCOLORMAPS * 256 * R_OldBlend; + CameraLight::Instance()->SetCamera(MainThread()->Viewport.get(), actor); MainThread()->Viewport->SetupFreelook(); diff --git a/src/swrenderer/things/r_playersprite.cpp b/src/swrenderer/things/r_playersprite.cpp index ea0b2af24b..0a356f2bba 100644 --- a/src/swrenderer/things/r_playersprite.cpp +++ b/src/swrenderer/things/r_playersprite.cpp @@ -465,15 +465,15 @@ namespace swrenderer if (visstyle.Invert) { - vis.Light.BaseColormap = &SpecialColormaps[INVERSECOLORMAP]; + vis.Light.BaseColormap = &SpecialSWColormaps[INVERSECOLORMAP]; vis.Light.ColormapNum = 0; noaccel = true; } } // If we're drawing with a special colormap, but shaders for them are disabled, do // not accelerate. - if (!r_shadercolormaps && (vis.Light.BaseColormap >= &SpecialColormaps[0] && - vis.Light.BaseColormap <= &SpecialColormaps.Last())) + if (!r_shadercolormaps && (vis.Light.BaseColormap >= &SpecialSWColormaps[0] && + vis.Light.BaseColormap <= &SpecialSWColormaps.Last())) { noaccel = true; } @@ -524,10 +524,10 @@ namespace swrenderer accelSprite.x1 = x1; accelSprite.flip = vis.xiscale < 0; - if (vis.Light.BaseColormap >= &SpecialColormaps[0] && - vis.Light.BaseColormap < &SpecialColormaps[SpecialColormaps.Size()]) + if (vis.Light.BaseColormap >= &SpecialSWColormaps[0] && + vis.Light.BaseColormap < &SpecialSWColormaps[SpecialColormaps.Size()]) { - accelSprite.special = static_cast(vis.Light.BaseColormap); + accelSprite.special = &SpecialColormaps[vis.Light.BaseColormap - &SpecialSWColormaps[0]]; } else if (CameraLight::Instance()->ShaderColormap()) { diff --git a/src/swrenderer/viewport/r_drawerargs.cpp b/src/swrenderer/viewport/r_drawerargs.cpp index 78cc3ea8ff..f74565c4d9 100644 --- a/src/swrenderer/viewport/r_drawerargs.cpp +++ b/src/swrenderer/viewport/r_drawerargs.cpp @@ -19,6 +19,7 @@ namespace swrenderer void DrawerArgs::SetLight(FSWColormap *base_colormap, float light, int shade) { mBaseColormap = base_colormap; + assert(mBaseColormap->Maps != nullptr); mLight = light; mShade = shade; } diff --git a/src/v_palette.cpp b/src/v_palette.cpp index 0403dc4333..606826d13f 100644 --- a/src/v_palette.cpp +++ b/src/v_palette.cpp @@ -538,30 +538,6 @@ CCMD (testblend) } } -CCMD (testfade) -{ - FString colorstring; - uint32_t color; - - if (argv.argc() < 2) - { - Printf ("testfade \n"); - } - else - { - if ( !(colorstring = V_GetColorStringByName (argv[1])).IsEmpty() ) - { - color = V_GetColorFromString (NULL, colorstring); - } - else - { - color = V_GetColorFromString (NULL, argv[1]); - } - level.fadeto = color; - NormalLight.ChangeFade (color); - } -} - /****** Colorspace Conversion Functions ******/ // Code from http://www.cs.rit.edu/~yxv4997/t_convert.html @@ -637,34 +613,3 @@ void HSVtoRGB (float *r, float *g, float *b, float h, float s, float v) } } -CCMD (testcolor) -{ - FString colorstring; - uint32_t color; - int desaturate; - - if (argv.argc() < 2) - { - Printf ("testcolor [desaturation]\n"); - } - else - { - if ( !(colorstring = V_GetColorStringByName (argv[1])).IsEmpty() ) - { - color = V_GetColorFromString (NULL, colorstring); - } - else - { - color = V_GetColorFromString (NULL, argv[1]); - } - if (argv.argc() > 2) - { - desaturate = atoi (argv[2]); - } - else - { - desaturate = NormalLight.Desaturate; - } - NormalLight.ChangeColor (color, desaturate); - } -}