From f64bdccacab206104b1299e7d3188f5a2dcf1f69 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 12 Apr 2020 08:21:50 +0200 Subject: [PATCH] - moved renderstyle to 'common' and use GZDoom's color table code unaltered. # Conflicts: # source/CMakeLists.txt # source/common/engine/serializer.h --- source/CMakeLists.txt | 4 +- source/common/engine/i_interface.cpp | 3 + source/common/engine/i_interface.h | 13 +++ source/common/engine/palettecontainer.cpp | 56 +++++++++- source/common/engine/palettecontainer.h | 4 + .../2d => common/engine}/renderstyle.cpp | 1 + .../{core/2d => common/engine}/renderstyle.h | 24 ++-- source/common/engine/serializer.h | 2 +- source/common/engine/v_colortables.cpp | 103 ++++++++++++++++++ source/common/engine/v_colortables.h | 57 ++++++++++ source/common/utility/palutil.h | 1 + source/core/textures/formats/jpegtexture.cpp | 2 +- source/core/textures/formats/pcxtexture.cpp | 4 +- source/core/textures/formats/pngtexture.cpp | 4 +- source/core/textures/formats/tgatexture.cpp | 2 +- source/core/textures/imagehelpers.cpp | 12 -- source/core/textures/imagehelpers.h | 20 +--- source/glbackend/gl_palmanager.cpp | 4 - 18 files changed, 259 insertions(+), 57 deletions(-) create mode 100644 source/common/engine/i_interface.cpp create mode 100644 source/common/engine/i_interface.h rename source/{core/2d => common/engine}/renderstyle.cpp (98%) rename source/{core/2d => common/engine}/renderstyle.h (95%) create mode 100644 source/common/engine/v_colortables.cpp create mode 100644 source/common/engine/v_colortables.h diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index bb7c054dc..de5e6e22f 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -727,7 +727,6 @@ set (PCH_SOURCES core/2d/v_2ddrawer.cpp core/2d/v_draw.cpp core/2d/v_drawtext.cpp - core/2d/renderstyle.cpp core/2d/screentext.cpp core/fonts/font.cpp @@ -793,6 +792,9 @@ set (PCH_SOURCES common/engine/sc_man.cpp common/engine/palettecontainer.cpp common/engine/stringtable.cpp + common/engine/i_interface.cpp + common/engine/renderstyle.cpp + common/engine/v_colortables.cpp common/engine/serializer.cpp common/engine/m_random.cpp common/objects/dobject.cpp diff --git a/source/common/engine/i_interface.cpp b/source/common/engine/i_interface.cpp new file mode 100644 index 000000000..b95563279 --- /dev/null +++ b/source/common/engine/i_interface.cpp @@ -0,0 +1,3 @@ +#include "i_interface.h" + +SystemCallbacks *sysCallbacks; diff --git a/source/common/engine/i_interface.h b/source/common/engine/i_interface.h new file mode 100644 index 000000000..0199f97ea --- /dev/null +++ b/source/common/engine/i_interface.h @@ -0,0 +1,13 @@ +#pragma once + + +struct SystemCallbacks +{ + bool (*WantGuiCapture)(); + bool (*WantLeftButton)(); + bool (*NetGame)(); + bool (*WantNativeMouse)(); + bool (*CaptureModeInGame)(); +}; + +extern SystemCallbacks *sysCallbacks; diff --git a/source/common/engine/palettecontainer.cpp b/source/common/engine/palettecontainer.cpp index 8d36af246..1f8732db9 100644 --- a/source/common/engine/palettecontainer.cpp +++ b/source/common/engine/palettecontainer.cpp @@ -43,6 +43,7 @@ PaletteContainer GPalette; FColorMatcher ColorMatcher; +extern uint8_t IcePalette[16][3]; //---------------------------------------------------------------------------- // @@ -90,6 +91,58 @@ void PaletteContainer::SetPalette(const uint8_t* colors, int transparent_index) // translucency map. WhiteIndex = BestColor((uint32_t*)RawColors, 255, 255, 255, 0, 255); BlackIndex = BestColor((uint32_t*)RawColors, 0, 0, 0, 0, 255); + + // The alphatexture translation. This is just a standard index as gray mapping and has no association with the palette. + auto remap = &GrayRamp; + remap->Remap[0] = 0; + remap->Palette[0] = 0; + for (int i = 1; i < 256; i++) + { + remap->Remap[i] = i; + remap->Palette[i] = PalEntry(255, i, i, i); + } + + // Palette to grayscale ramp. For internal use only, because the remap does not map to the palette. + remap = &GrayscaleMap; + remap->Remap[0] = 0; + remap->Palette[0] = 0; + for (int i = 1; i < 256; i++) + { + int r = GPalette.BaseColors[i].r; + int g = GPalette.BaseColors[i].g; + int b = GPalette.BaseColors[i].b; + int v = (r * 77 + g * 143 + b * 37) >> 8; + + remap->Remap[i] = v; + remap->Palette[i] = PalEntry(255, v, v, v); + } + + for (int i = 0; i < 256; ++i) + { + GrayMap[i] = ColorMatcher.Pick(i, i, i); + } + + // Create the ice translation table, based on Hexen's. Alas, the standard + // Doom palette has no good substitutes for these bluish-tinted grays, so + // they will just look gray unless you use a different PLAYPAL with Doom. + + uint8_t IcePaletteRemap[16]; + for (int i = 0; i < 16; ++i) + { + IcePaletteRemap[i] = ColorMatcher.Pick(IcePalette[i][0], IcePalette[i][1], IcePalette[i][2]); + } + remap = &IceMap; + remap->Remap[0] = 0; + remap->Palette[0] = 0; + for (int i = 1; i < 256; ++i) + { + int r = GPalette.BaseColors[i].r; + int g = GPalette.BaseColors[i].g; + int b = GPalette.BaseColors[i].b; + int v = (r * 77 + g * 143 + b * 37) >> 12; + remap->Remap[i] = IcePaletteRemap[v]; + remap->Palette[i] = PalEntry(255, IcePalette[v][0], IcePalette[v][1], IcePalette[v][2]); + } } @@ -276,8 +329,6 @@ void PaletteContainer::GenerateGlobalBrightmapFromColormap(const uint8_t *cmapda } } - - //---------------------------------------------------------------------------- // // @@ -768,3 +819,4 @@ bool FRemapTable::AddColors(int start, int count, const uint8_t*colors, int tran } + diff --git a/source/common/engine/palettecontainer.h b/source/common/engine/palettecontainer.h index 0abc00e26..90871863f 100644 --- a/source/common/engine/palettecontainer.h +++ b/source/common/engine/palettecontainer.h @@ -79,6 +79,10 @@ public: bool HasGlobalBrightmap; FRemapTable GlobalBrightmap; + FRemapTable GrayRamp; + FRemapTable GrayscaleMap; + FRemapTable IceMap; // This is used by the texture compositor so it must be globally accessible. + uint8_t GrayMap[256]; private: FMemArena remapArena; diff --git a/source/core/2d/renderstyle.cpp b/source/common/engine/renderstyle.cpp similarity index 98% rename from source/core/2d/renderstyle.cpp rename to source/common/engine/renderstyle.cpp index 3b491535d..1a29292ea 100644 --- a/source/core/2d/renderstyle.cpp +++ b/source/common/engine/renderstyle.cpp @@ -46,6 +46,7 @@ FRenderStyle LegacyRenderStyles[STYLE_Count] = { { STYLEOP_None, STYLEALPHA_Zero, STYLEALPHA_Zero, 0 } }, /* STYLE_None */ { { STYLEOP_Add, STYLEALPHA_Src, STYLEALPHA_InvSrc, STYLEF_Alpha1 } }, /* STYLE_Normal */ { { STYLEOP_Fuzz, STYLEALPHA_Src, STYLEALPHA_InvSrc, 0 } }, /* STYLE_Fuzzy */ + { { STYLEOP_Add, STYLEALPHA_Src, STYLEALPHA_InvSrc, STYLEF_TransSoulsAlpha } }, /* STYLE_SoulTrans */ { { STYLEOP_FuzzOrAdd, STYLEALPHA_Src, STYLEALPHA_InvSrc, 0 } }, /* STYLE_OptFuzzy */ { { STYLEOP_Add, STYLEALPHA_Src, STYLEALPHA_InvSrc, STYLEF_Alpha1 | STYLEF_ColorIsFixed } }, /* STYLE_Stencil */ { { STYLEOP_Add, STYLEALPHA_Src, STYLEALPHA_InvSrc, 0 } }, /* STYLE_Translucent */ diff --git a/source/core/2d/renderstyle.h b/source/common/engine/renderstyle.h similarity index 95% rename from source/core/2d/renderstyle.h rename to source/common/engine/renderstyle.h index 6579432ad..70ad5d561 100644 --- a/source/core/2d/renderstyle.h +++ b/source/common/engine/renderstyle.h @@ -63,6 +63,7 @@ enum ERenderStyle STYLE_None, // Do not draw STYLE_Normal, // Normal; just copy the image to the screen STYLE_Fuzzy, // Draw silhouette using "fuzz" effect + STYLE_SoulTrans, // Draw translucent with amount in r_transsouls STYLE_OptFuzzy, // Draw as fuzzy or translucent, based on user preference STYLE_Stencil, // Fill image interior with alphacolor STYLE_Translucent, // Draw translucent @@ -115,6 +116,9 @@ enum ERenderAlpha enum ERenderFlags { + // Use value of transsouls as alpha. + STYLEF_TransSoulsAlpha = 1, + // Force alpha to 1. Not the same as STYLEALPHA_One, since that also // ignores alpha from the texture. STYLEF_Alpha1 = 2, @@ -142,21 +146,16 @@ enum ERenderFlags STYLEF_FadeToBlack = 64, }; -struct FRenderStyle +union FRenderStyle { - union + struct { - struct - { - uint8_t BlendOp; // Of ERenderOp type - uint8_t SrcAlpha; // Of ERenderAlpha type - uint8_t DestAlpha; // Of ERenderAlpha type - uint8_t Flags; - }; - uint32_t AsDWORD; + uint8_t BlendOp; // Of ERenderOp type + uint8_t SrcAlpha; // Of ERenderAlpha type + uint8_t DestAlpha; // Of ERenderAlpha type + uint8_t Flags; }; - - FRenderStyle() = default; + uint32_t AsDWORD; inline FRenderStyle &operator= (ERenderStyle legacy); bool operator==(const FRenderStyle &o) const { return AsDWORD == o.AsDWORD; } @@ -186,3 +185,4 @@ inline FRenderStyle &FRenderStyle::operator= (ERenderStyle legacy) *this = LegacyRenderStyles[legacy]; return *this; } + diff --git a/source/common/engine/serializer.h b/source/common/engine/serializer.h index 517bad7b9..fe20f247b 100644 --- a/source/common/engine/serializer.h +++ b/source/common/engine/serializer.h @@ -18,7 +18,7 @@ struct FReader; class PClass; class FFont; class FSoundID; -struct FRenderStyle; +union FRenderStyle; class DObject; class FTextureID; diff --git a/source/common/engine/v_colortables.cpp b/source/common/engine/v_colortables.cpp new file mode 100644 index 000000000..36849862b --- /dev/null +++ b/source/common/engine/v_colortables.cpp @@ -0,0 +1,103 @@ +/* +** v_colortables.cpp +** Various color blending tables +** +**--------------------------------------------------------------------------- +** Copyright 1998-2006 Randy Heit +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + + +#include "v_colortables.h" +#include "colormatcher.h" + +uint32_t Col2RGB8[65][256]; +uint32_t *Col2RGB8_LessPrecision[65]; +uint32_t Col2RGB8_Inverse[65][256]; +uint32_t Col2RGB8_2[63][256]; // this array's second dimension is called up by pointer as Col2RGB8_LessPrecision[] elsewhere. +ColorTable32k RGB32k; +ColorTable256k RGB256k; + + + +//========================================================================== +// +// BuildTransTable +// +// Build the tables necessary for blending - used by software rendering and +// texture composition +// +//========================================================================== + +void BuildTransTable (const PalEntry *palette) +{ + int r, g, b; + + // create the RGB555 lookup table + for (r = 0; r < 32; r++) + for (g = 0; g < 32; g++) + for (b = 0; b < 32; b++) + RGB32k.RGB[r][g][b] = ColorMatcher.Pick ((r<<3)|(r>>2), (g<<3)|(g>>2), (b<<3)|(b>>2)); + // create the RGB666 lookup table + for (r = 0; r < 64; r++) + for (g = 0; g < 64; g++) + for (b = 0; b < 64; b++) + RGB256k.RGB[r][g][b] = ColorMatcher.Pick ((r<<2)|(r>>4), (g<<2)|(g>>4), (b<<2)|(b>>4)); + + int x, y; + + // create the swizzled palette + for (x = 0; x < 65; x++) + for (y = 0; y < 256; y++) + Col2RGB8[x][y] = (((palette[y].r*x)>>4)<<20) | + ((palette[y].g*x)>>4) | + (((palette[y].b*x)>>4)<<10); + + // create the swizzled palette with the lsb of red and blue forced to 0 + // (for green, a 1 is okay since it never gets added into) + for (x = 1; x < 64; x++) + { + Col2RGB8_LessPrecision[x] = Col2RGB8_2[x-1]; + for (y = 0; y < 256; y++) + { + Col2RGB8_2[x-1][y] = Col2RGB8[x][y] & 0x3feffbff; + } + } + Col2RGB8_LessPrecision[0] = Col2RGB8[0]; + Col2RGB8_LessPrecision[64] = Col2RGB8[64]; + + // create the inverse swizzled palette + for (x = 0; x < 65; x++) + for (y = 0; y < 256; y++) + { + Col2RGB8_Inverse[x][y] = (((((255-palette[y].r)*x)>>4)<<20) | + (((255-palette[y].g)*x)>>4) | + ((((255-palette[y].b)*x)>>4)<<10)) & 0x3feffbff; + } +} + diff --git a/source/common/engine/v_colortables.h b/source/common/engine/v_colortables.h new file mode 100644 index 000000000..3f237147f --- /dev/null +++ b/source/common/engine/v_colortables.h @@ -0,0 +1,57 @@ +#pragma once + +#include +#include "palentry.h" + +// extracted from v_video.h because this caused circular dependencies between v_video.h and textures.h + +// Translucency tables + +// RGB32k is a normal R5G5B5 -> palette lookup table. + +// Use a union so we can "overflow" without warnings. +// Otherwise, we get stuff like this from Clang (when compiled +// with -fsanitize=bounds) while running: +// src/v_video.cpp:390:12: runtime error: index 1068 out of bounds for type 'uint8_t [32]' +// src/r_draw.cpp:273:11: runtime error: index 1057 out of bounds for type 'uint8_t [32]' +union ColorTable32k +{ + uint8_t RGB[32][32][32]; + uint8_t All[32 *32 *32]; +}; +extern ColorTable32k RGB32k; + +// [SP] RGB666 support +union ColorTable256k +{ + uint8_t RGB[64][64][64]; + uint8_t All[64 *64 *64]; +}; +extern ColorTable256k RGB256k; + +// Col2RGB8 is a pre-multiplied palette for color lookup. It is stored in a +// special R10B10G10 format for efficient blending computation. +// --RRRRRrrr--BBBBBbbb--GGGGGggg-- at level 64 +// --------rrrr------bbbb------gggg at level 1 +extern uint32_t Col2RGB8[65][256]; + +// Col2RGB8_LessPrecision is the same as Col2RGB8, but the LSB for red +// and blue are forced to zero, so if the blend overflows, it won't spill +// over into the next component's value. +// --RRRRRrrr-#BBBBBbbb-#GGGGGggg-- at level 64 +// --------rrr#------bbb#------gggg at level 1 +extern uint32_t *Col2RGB8_LessPrecision[65]; + +// Col2RGB8_Inverse is the same as Col2RGB8_LessPrecision, except the source +// palette has been inverted. +extern uint32_t Col2RGB8_Inverse[65][256]; + +// "Magic" numbers used during the blending: +// --000001111100000111110000011111 = 0x01f07c1f +// -0111111111011111111101111111111 = 0x3FEFFBFF +// -1000000000100000000010000000000 = 0x40100400 +// ------10000000001000000000100000 = 0x40100400 >> 5 +// --11111-----11111-----11111----- = 0x40100400 - (0x40100400 >> 5) aka "white" +// --111111111111111111111111111111 = 0x3FFFFFFF + +void BuildTransTable (const PalEntry *palette); diff --git a/source/common/utility/palutil.h b/source/common/utility/palutil.h index 7e6e966cf..077c4c036 100644 --- a/source/common/utility/palutil.h +++ b/source/common/utility/palutil.h @@ -1,6 +1,7 @@ #pragma once #include +#include "zstring.h" #include "palentry.h" struct FScriptPosition; diff --git a/source/core/textures/formats/jpegtexture.cpp b/source/core/textures/formats/jpegtexture.cpp index a5795c2ff..243614e72 100644 --- a/source/core/textures/formats/jpegtexture.cpp +++ b/source/core/textures/formats/jpegtexture.cpp @@ -313,7 +313,7 @@ void FJPEGTexture::CreatePalettedPixels(uint8_t *buffer) case JCS_GRAYSCALE: { - auto remap = ImageHelpers::GetGraymap(); + auto remap = GPalette.GrayMap; for (int x = Width; x > 0; --x) { *out = remap[in[0]]; diff --git a/source/core/textures/formats/pcxtexture.cpp b/source/core/textures/formats/pcxtexture.cpp index 2db53f2e1..71f2df0cc 100644 --- a/source/core/textures/formats/pcxtexture.cpp +++ b/source/core/textures/formats/pcxtexture.cpp @@ -365,8 +365,8 @@ void FPCXTexture::CreatePalettedPixels(uint8_t *buffer) { default: case 1: - PaletteMap[0] = ImageHelpers::GrayMap[0]; - PaletteMap[1] = ImageHelpers::GrayMap[255]; + PaletteMap[0] = GPalette.GrayMap[0]; + PaletteMap[1] = GPalette.GrayMap[255]; ReadPCX1bit (buffer, lump, &header); break; diff --git a/source/core/textures/formats/pngtexture.cpp b/source/core/textures/formats/pngtexture.cpp index 2aaa14b7b..28d5b5e62 100644 --- a/source/core/textures/formats/pngtexture.cpp +++ b/source/core/textures/formats/pngtexture.cpp @@ -246,13 +246,13 @@ FPNGTexture::FPNGTexture (FileReader &lump, int width, int height, { bMasked = true; PaletteSize = 256; - memcpy (PaletteMap, ImageHelpers::GrayMap+1, 256); + memcpy (PaletteMap, GPalette.GrayMap+1, 256); PaletteMap[255] = 254; // cannot use 255. PaletteMap[NonPaletteTrans[0]] = 255; } else { - memcpy(PaletteMap, ImageHelpers::GrayMap, 256); + memcpy(PaletteMap, GPalette.GrayMap, 256); } break; diff --git a/source/core/textures/formats/tgatexture.cpp b/source/core/textures/formats/tgatexture.cpp index 1230e08f3..698526df0 100644 --- a/source/core/textures/formats/tgatexture.cpp +++ b/source/core/textures/formats/tgatexture.cpp @@ -339,7 +339,7 @@ void FTGATexture::CreatePalettedPixels(uint8_t *buffer) case 3: // Grayscale { - auto remap = ImageHelpers::GetGraymap(); + auto remap = GPalette.GrayMap; switch (hdr.bpp) { case 8: diff --git a/source/core/textures/imagehelpers.cpp b/source/core/textures/imagehelpers.cpp index 067fc8f82..fb70316be 100644 --- a/source/core/textures/imagehelpers.cpp +++ b/source/core/textures/imagehelpers.cpp @@ -41,18 +41,6 @@ namespace ImageHelpers { - uint8_t GrayMap[256]; int alphaThreshold; - ColorTable256k RGB256k; - void SetPalette(const PalEntry* colors) - { - // create the RGB666 lookup table - for (int r = 0; r < 64; r++) - for (int g = 0; g < 64; g++) - for (int b = 0; b < 64; b++) - RGB256k.RGB[r][g][b] = ColorMatcher.Pick((r<<2)|(r>>4), (g<<2)|(g>>4), (b<<2)|(b>>4)); - } - - } \ No newline at end of file diff --git a/source/core/textures/imagehelpers.h b/source/core/textures/imagehelpers.h index c5f6b5f2e..57878ea17 100644 --- a/source/core/textures/imagehelpers.h +++ b/source/core/textures/imagehelpers.h @@ -43,30 +43,12 @@ #include "bitmap.h" #include "palutil.h" #include "palettecontainer.h" +#include "v_colortables.h" namespace ImageHelpers { - union ColorTable256k - { - uint8_t RGB[64][64][64]; - uint8_t All[64 * 64 * 64]; - }; - - extern uint8_t GrayMap[256]; - extern int WhiteIndex, BlackIndex; - extern ColorTable256k RGB256k; extern int alphaThreshold; - // Todo: This should not pick fullbright colors. - void SetPalette(const PalEntry* colors); - - - // Helpers for creating paletted images. - inline uint8_t *GetGraymap() - { - return GrayMap; - } - inline uint8_t RGBToPalettePrecise(bool wantluminance, int r, int g, int b, int a = 255) { return BestColor((uint32_t*)GPalette.BaseColors, r, g, b); diff --git a/source/glbackend/gl_palmanager.cpp b/source/glbackend/gl_palmanager.cpp index bfba1a927..c790e2b0a 100644 --- a/source/glbackend/gl_palmanager.cpp +++ b/source/glbackend/gl_palmanager.cpp @@ -207,10 +207,6 @@ void PaletteManager::SetPalette(int index, const uint8_t* data) if (index < 0 || index > 255) return; // invalid index - ignore. palettemap[index] = FindPalette(data); - if (index == 0) - { - ImageHelpers::SetPalette((PalEntry*)data); // Palette 0 is always the reference for downconverting images - } } //===========================================================================