From f929419a0abbd0c92e34ca6eeb7883e87bc726d4 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 23 May 2020 14:40:54 +0200 Subject: [PATCH] - refactoring of the lookup tables. --- source/blood/src/screen.cpp | 72 ++- source/build/include/build.h | 2 +- source/build/include/palette.h | 60 +-- source/build/include/polymost.h | 1 - source/build/src/defs.cpp | 40 +- source/build/src/engine.cpp | 15 +- source/build/src/mdsprite.cpp | 2 +- source/build/src/palette.cpp | 594 ++++++++-------------- source/build/src/polymost.cpp | 27 +- source/build/src/voxmodel.cpp | 2 +- source/common/engine/palettecontainer.cpp | 30 ++ source/common/engine/palettecontainer.h | 3 + source/core/2d/v_2ddrawer.cpp | 8 +- source/core/rendering/v_video.cpp | 2 + source/core/textures/buildtiles.cpp | 5 +- source/duke3d/src/common.cpp | 2 +- source/duke3d/src/game.cpp | 2 - source/exhumed/src/menu.cpp | 2 +- source/glbackend/gl_texture.cpp | 56 ++ source/glbackend/hw_draw2d.cpp | 7 +- source/rr/src/common.cpp | 6 +- source/rr/src/game.cpp | 2 - source/sw/src/game.cpp | 4 +- 23 files changed, 406 insertions(+), 538 deletions(-) diff --git a/source/blood/src/screen.cpp b/source/blood/src/screen.cpp index d013ad9d9..ebb684640 100644 --- a/source/blood/src/screen.cpp +++ b/source/blood/src/screen.cpp @@ -34,22 +34,22 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. BEGIN_BLD_NS -LOADITEM PLU[15] = { - { 0, "NORMAL" }, - { 1, "SATURATE" }, - { 2, "BEAST" }, - { 3, "TOMMY" }, - { 4, "SPIDER3" }, - { 5, "GRAY" }, - { 6, "GRAYISH" }, - { 7, "SPIDER1" }, - { 8, "SPIDER2" }, - { 9, "FLAME" }, - { 10, "COLD" }, - { 11, "P1" }, - { 12, "P2" }, - { 13, "P3" }, - { 14, "P4" } +const char * PLU[15] = { + "NORMAL.PLU", + "SATURATE.PLU", + "BEAST.PLU", + "TOMMY.PLU", + "SPIDER3.PLU", + "GRAY.PLU", + "GRAYISH.PLU", + "SPIDER1.PLU", + "SPIDER2.PLU", + "FLAME.PLU", + "COLD.PLU", + "P1.PLU", + "P2.PLU", + "P3.PLU", + "P4.PLU" }; const char *PAL[5] = { @@ -68,49 +68,39 @@ bool gFogMode = false; void scrLoadPLUs(void) { - // load default palookups - for (int i = 0; i < 15; i++) + // load lookup tables + for (int i = 0; i < MAXPALOOKUPS; i++) { - DICTNODE *pPlu = gSysRes.Lookup(PLU[i].name, "PLU"); - if (!pPlu) - ThrowError("%s.PLU not found", PLU[i].name); - if (pPlu->Size() / 256 != 64) - ThrowError("Incorrect PLU size"); - lookuptables[PLU[i].id] = (char*)gSysRes.Lock(pPlu); + int lump = i <= 15 ? fileSystem.FindFile(PLU[i]) : fileSystem.FindResource(i, "PLU"); + if (lump < 0) + { + if (i <= 15) I_FatalError("%s.PLU not found", PLU[i]); + else continue; + } + auto data = fileSystem.GetFileData(lump); + if (data.Size() != 64 * 256) + I_FatalError("Incorrect PLU size"); + paletteSetLookupTable(i, data.Data()); } - // by NoOne: load user palookups - for (int i = kUserPLUStart; i < MAXPALOOKUPS; i++) { - DICTNODE* pPlu = gSysRes.Lookup(i, "PLU"); - if (!pPlu) continue; - else if (pPlu->Size() / 256 != 64) { consoleSysMsg("Incorrect filesize of PLU#%d", i); } - else lookuptables[i] = (char*)gSysRes.Lock(pPlu); - } - -#ifdef USE_OPENGL palookupfog[1].r = 255; palookupfog[1].g = 255; palookupfog[1].b = 255; palookupfog[1].f = 1; -#endif } -#ifdef USE_OPENGL glblend_t const bloodglblend = { { - { 1.f/3.f, BLENDFACTOR_SRC_ALPHA, BLENDFACTOR_ONE_MINUS_SRC_ALPHA, 0 }, - { 2.f/3.f, BLENDFACTOR_SRC_ALPHA, BLENDFACTOR_ONE_MINUS_SRC_ALPHA, 0 }, + { 1.f/3.f, STYLEALPHA_Src, STYLEALPHA_InvSrc, 0 }, + { 2.f/3.f, STYLEALPHA_Src, STYLEALPHA_InvSrc, 0 }, }, }; -#endif void scrLoadPalette(void) { -#ifdef USE_OPENGL for (auto& x : glblend) x = bloodglblend; -#endif paletteloaded = 0; Printf("Loading palettes\n"); @@ -118,7 +108,7 @@ void scrLoadPalette(void) { auto pal = fileSystem.LoadFile(PAL[i]); if (pal.Size() < 768) I_FatalError("%s: file too small", PAL[i]); - paletteSetColorTable(i, pal.Data()); + paletteSetColorTable(i, pal.Data(), false, false); } numshades = 64; paletteloaded |= PALETTE_MAIN; diff --git a/source/build/include/build.h b/source/build/include/build.h index 31899566b..dc916c4a9 100644 --- a/source/build/include/build.h +++ b/source/build/include/build.h @@ -540,9 +540,9 @@ EXTERN int32_t numframes, randomseed; EXTERN int16_t sintable[2048]; EXTERN int16_t numshades; -EXTERN char *lookuptables[MAXPALOOKUPS]; EXTERN uint8_t paletteloaded; + EXTERN int32_t maxspritesonscreen; enum { diff --git a/source/build/include/palette.h b/source/build/include/palette.h index b2e1c84cf..ad3c082f8 100644 --- a/source/build/include/palette.h +++ b/source/build/include/palette.h @@ -28,6 +28,8 @@ #define NORMALPAL (MAXPALOOKUPS - 4) #define BRIGHTPAL (MAXPALOOKUPS) +extern FString LookupTables[MAXPALOOKUPS]; + enum { Translation_BasePalettes, @@ -35,35 +37,19 @@ enum }; extern uint8_t curbasepal; +extern FixedBitArray<256> FullbrightIndices; extern int32_t r_scenebrightness; -extern uint8_t PaletteIndexFullbrights[32]; - - -inline bool IsPaletteIndexFullbright(uint8_t col) -{ - return (PaletteIndexFullbrights[col >> 3] & (1u << (col & 7))); -} - -inline void SetPaletteIndexFullbright(int col) -{ - PaletteIndexFullbrights[col >> 3] |= (1u << (col & 7)); -} - struct palette_t { uint8_t r, g, b, f; }; -typedef struct { - uint8_t r, g, b; -} rgb24_t; -extern palette_t palfadergb; -extern unsigned char palfadedelta; +extern PalEntry palfadergb; + void paletteMakeLookupTable(int32_t palnum, const char *remapbuf, uint8_t r, uint8_t g, uint8_t b, char noFloorPal); -void paletteSetColorTable(int32_t id, uint8_t const *table, bool notransparency = false); +void paletteSetColorTable(int32_t id, uint8_t const* table, bool notransparency, bool twodonly); int32_t paletteSetLookupTable(int32_t palnum, const uint8_t *shtab); -void paletteFreeLookupTable(int32_t palnum); #include "tflags.h" enum ESetPalFlag @@ -79,10 +65,16 @@ inline void videoSetBrightness(int brightness) typedef TFlags ESetPalFlags; DEFINE_TFLAGS_OPERATORS(ESetPalFlags) -extern ESetPalFlags curpaletteflags; - void videoSetPalette(int dabrightness, int dapalid, ESetPalFlags flags); -void videoFadePalette(uint8_t r, uint8_t g, uint8_t b, uint8_t offset); +inline void videoFadePalette(uint8_t r, uint8_t g, uint8_t b, uint8_t offset) +{ + palfadergb.r = r; + palfadergb.g = g; + palfadergb.b = b; + palfadergb.a = offset; +} + + #ifdef USE_OPENGL void videoTintBlood(int32_t r, int32_t g, int32_t b); #endif @@ -91,7 +83,6 @@ extern int32_t globalpal; extern int32_t globalblend; extern void paletteLoadFromDisk(void); extern void palettePostLoadTables(void); -extern int32_t curbrightness; extern int32_t paletteLoadLookupTable(FileReader &fp); extern void paletteSetupDefaultFog(void); @@ -106,21 +97,6 @@ extern char britable[16][256]; #ifdef USE_OPENGL extern palette_t palookupfog[MAXPALOOKUPS]; -enum -{ - BLENDFACTOR_ZERO = 0, - BLENDFACTOR_ONE, - BLENDFACTOR_SRC_COLOR, - BLENDFACTOR_ONE_MINUS_SRC_COLOR, - BLENDFACTOR_SRC_ALPHA, - BLENDFACTOR_ONE_MINUS_SRC_ALPHA, - BLENDFACTOR_DST_ALPHA, - BLENDFACTOR_ONE_MINUS_DST_ALPHA, - BLENDFACTOR_DST_COLOR, - BLENDFACTOR_ONE_MINUS_DST_COLOR, - NUMBLENDFACTORS, -}; - typedef struct glblenddef_ { float alpha; @@ -135,9 +111,9 @@ typedef struct glblend_ extern glblend_t const nullglblend, defaultglblend; extern glblend_t glblend[MAXBLENDTABS]; -FRenderStyle GetBlend(int blend, int def); -extern void handle_blend(uint8_t enable, uint8_t blend, uint8_t def); -float float_trans(uint32_t maskprops, uint8_t blend); +FRenderStyle GetRenderStyle(int blend, int def); +extern void SetRenderStyleFromBlend(uint8_t enable, uint8_t blend, uint8_t def); +float GetAlphaFromBlend(uint32_t maskprops, uint32_t blend); #endif diff --git a/source/build/include/polymost.h b/source/build/include/polymost.h index a81226c39..ebe0cf335 100644 --- a/source/build/include/polymost.h +++ b/source/build/include/polymost.h @@ -24,7 +24,6 @@ void polymost_outputGLDebugMessage(uint8_t severity, const char* format, ...); //void phex(char v, char *s); void uploadbasepalette(int32_t basepalnum); -void uploadpalswaps(int count, int32_t *palookupnum); void polymost_drawsprite(int32_t snum); void polymost_drawmaskwall(int32_t damaskwallcnt); void polymost_dorotatespritemodel(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum, int8_t dashade, uint8_t dapalnum, int32_t dastat, uint8_t daalpha, uint8_t dablend, int32_t uniqid); diff --git a/source/build/src/defs.cpp b/source/build/src/defs.cpp index 6b1c14a0b..15cfe93df 100644 --- a/source/build/src/defs.cpp +++ b/source/build/src/defs.cpp @@ -2040,7 +2040,7 @@ static int32_t defsparser(scriptfile *script) // NOTE: all palookups are initialized, i.e. non-NULL! // NOTE2: aliasing (pal==remappal) is OK - paletteMakeLookupTable(pal, lookuptables[remappal], red<<2, green<<2, blue<<2, + paletteMakeLookupTable(pal, LookupTables[remappal].GetChars(), red<<2, green<<2, blue<<2, remappal==0 ? 1 : (nofloorpal == -1 ? g_noFloorPal[remappal] : nofloorpal)); } break; @@ -2658,7 +2658,7 @@ static int32_t defsparser(scriptfile *script) palbuf[k] <<= shiftleft; } - paletteSetColorTable(id, palbuf.Data()); + paletteSetColorTable(id, palbuf.Data(), false, false); didLoadPal = 1; break; } @@ -2862,15 +2862,8 @@ static int32_t defsparser(scriptfile *script) break; } - uint8_t const * const sourcepal = (uint8_t *)lookuptables[source]; - if (EDUKE32_PREDICT_FALSE(sourcepal == NULL)) - { - Printf("Error: palookup: Source palookup does not exist on line %s:%d\n", - script->filename, scriptfile_getlinum(script,cmdtokptr)); - break; - } - - paletteSetLookupTable(id, sourcepal); + if (LookupTables[source].IsNotEmpty() || id > 0) // do not overwrite the base with an empty table. + LookupTables[id] = LookupTables[source]; didLoadShade = 1; break; } @@ -2993,8 +2986,7 @@ static int32_t defsparser(scriptfile *script) } case T_UNDEF: { - paletteFreeLookupTable(id); - + LookupTables[id] = ""; didLoadShade = 0; if (id == 0) paletteloaded &= ~PALETTE_SHADE; @@ -3228,16 +3220,16 @@ static int32_t defsparser(scriptfile *script) uint8_t * const factor = glblenddeftoken == T_SRC ? &glbdef->src : &glbdef->dst; switch (factortoken) { - case T_ZERO: *factor = BLENDFACTOR_ZERO; break; - case T_ONE: *factor = BLENDFACTOR_ONE; break; - case T_SRC_COLOR: *factor = BLENDFACTOR_SRC_COLOR; break; - case T_ONE_MINUS_SRC_COLOR: *factor = BLENDFACTOR_ONE_MINUS_SRC_COLOR; break; - case T_SRC_ALPHA: *factor = BLENDFACTOR_SRC_ALPHA; break; - case T_ONE_MINUS_SRC_ALPHA: *factor = BLENDFACTOR_ONE_MINUS_SRC_ALPHA; break; - case T_DST_ALPHA: *factor = BLENDFACTOR_DST_ALPHA; break; - case T_ONE_MINUS_DST_ALPHA: *factor = BLENDFACTOR_ONE_MINUS_DST_ALPHA; break; - case T_DST_COLOR: *factor = BLENDFACTOR_DST_COLOR; break; - case T_ONE_MINUS_DST_COLOR: *factor = BLENDFACTOR_ONE_MINUS_DST_COLOR; break; + case T_ZERO: *factor = STYLEALPHA_Zero; break; + case T_ONE: *factor = STYLEALPHA_One; break; + case T_SRC_COLOR: *factor = STYLEALPHA_SrcCol; break; + case T_ONE_MINUS_SRC_COLOR: *factor = STYLEALPHA_InvSrcCol; break; + case T_SRC_ALPHA: *factor = STYLEALPHA_Src; break; + case T_ONE_MINUS_SRC_ALPHA: *factor = STYLEALPHA_InvSrc; break; + case T_DST_ALPHA: *factor = STYLEALPHA_Dst; break; + case T_ONE_MINUS_DST_ALPHA: *factor = STYLEALPHA_InvDst; break; + case T_DST_COLOR: *factor = STYLEALPHA_DstCol; break; + case T_ONE_MINUS_DST_COLOR: *factor = STYLEALPHA_InvDstCol; break; } #else UNREFERENCED_PARAMETER(factortoken); @@ -3349,7 +3341,7 @@ static int32_t defsparser(scriptfile *script) } for (bssize_t i = id0; i <= id1; i++) - paletteFreeLookupTable(i); + LookupTables[i] = ""; if (id0 == 0) paletteloaded &= ~PALETTE_SHADE; diff --git a/source/build/src/engine.cpp b/source/build/src/engine.cpp index 8915ee635..4bae07c39 100644 --- a/source/build/src/engine.cpp +++ b/source/build/src/engine.cpp @@ -69,7 +69,6 @@ bool playing_rr; bool playing_blood; int32_t rendmode=0; int32_t glrendmode = REND_POLYMOST; -int32_t r_scenebrightness = 0; int32_t r_rortexture = 0; int32_t r_rortexturerange = 0; int32_t r_rorphase = 0; @@ -2054,6 +2053,8 @@ int32_t enginePreInit(void) } +void (*paletteLoadFromDisk_replace)(void) = NULL; // replacement hook for Blood. + // // initengine // @@ -2094,7 +2095,14 @@ int32_t engineInit(void) maxspritesonscreen = MAXSPRITESONSCREEN; - paletteLoadFromDisk(); + if (paletteLoadFromDisk_replace) + { + paletteLoadFromDisk_replace(); + } + else + { + paletteLoadFromDisk(); + } #ifdef USE_OPENGL if (!mdinited) mdinit(); @@ -2123,7 +2131,6 @@ int32_t enginePostInit(void) // // uninitengine // -void paletteFreeAll(); void engineUnInit(void) { @@ -2138,8 +2145,6 @@ void engineUnInit(void) TileFiles.CloseAll(); - paletteFreeAll(); - for (bssize_t i = 0; i < num_usermaphacks; i++) { Xfree(usermaphacks[i].mhkfile); diff --git a/source/build/src/mdsprite.cpp b/source/build/src/mdsprite.cpp index a97932bbc..d0f8593d8 100644 --- a/source/build/src/mdsprite.cpp +++ b/source/build/src/mdsprite.cpp @@ -1602,7 +1602,7 @@ static int32_t polymost_md3draw(md3model_t *m, tspriteptr_t tspr) pc[3] = (tspr->cstat&2) ? glblend[tspr->blend].def[!!(tspr->cstat&512)].alpha : 1.0f; pc[3] *= 1.0f - sext->alpha; - handle_blend(!!(tspr->cstat & 2), tspr->blend, !!(tspr->cstat & 512)); + SetRenderStyleFromBlend(!!(tspr->cstat & 2), tspr->blend, !!(tspr->cstat & 512)); if (m->usesalpha) //Sprites with alpha in texture { diff --git a/source/build/src/palette.cpp b/source/build/src/palette.cpp index 9287ad006..50f9bc05f 100644 --- a/source/build/src/palette.cpp +++ b/source/build/src/palette.cpp @@ -19,16 +19,16 @@ #include "palettecontainer.h" #include "palutil.h" #include "colormatcher.h" +#include "m_swap.h" #include "../../glbackend/glbackend.h" -FMemArena lookuparena; +// FString is a nice and convenient way to have automatically managed shared storage. +FString LookupTables[MAXPALOOKUPS]; uint8_t curbasepal; int32_t globalblend; -palette_t palfadergb = { 0, 0, 0, 0 }; -unsigned char palfadedelta = 0; -ESetPalFlags curpaletteflags; +PalEntry palfadergb; #if defined(USE_OPENGL) palette_t palookupfog[MAXPALOOKUPS]; @@ -39,32 +39,15 @@ palette_t palookupfog[MAXPALOOKUPS]; // NOTE: g_noFloorPal[0] is irrelevant as it's never checked. int8_t g_noFloorPal[MAXPALOOKUPS]; -int32_t curbrightness = 0; +FixedBitArray<256> FullbrightIndices; -void setBlendFactor(int index, int alpha); +//========================================================================== +// +// Adds a palette to the global list of base palettes +// +//========================================================================== - -int DetermineTranslucency(const uint8_t *table) -{ - uint8_t index; - PalEntry newcolor; - PalEntry newcolor2; - - index = table[GPalette.BlackIndex * 256 + GPalette.WhiteIndex]; - newcolor = GPalette.BaseColors[index]; - - index = table[GPalette.WhiteIndex * 256 + GPalette.BlackIndex]; - newcolor2 = GPalette.BaseColors[index]; - if (newcolor2.r == 255) // if black on white results in white it's either - // fully transparent or additive - { - return -newcolor.r; - } - - return newcolor.r; -} - -void paletteSetColorTable(int32_t id, uint8_t const* table, bool notransparency) +void paletteSetColorTable(int32_t id, uint8_t const* table, bool notransparency, bool twodonly) { if (id == 0) { @@ -77,6 +60,7 @@ void paletteSetColorTable(int32_t id, uint8_t const* table, bool notransparency) remap.Palette[255] = 0; remap.Remap[255] = 255; } + remap.Inactive = twodonly; // use Inactive as a marker for the postprocessing so that for pure 2D palettes the creation of shade tables can be skipped. GPalette.UpdateTranslation(TRANSLATION(Translation_BasePalettes, id), &remap); // Todo: remove this once the texture code can use GPalette directly @@ -85,45 +69,18 @@ void paletteSetColorTable(int32_t id, uint8_t const* table, bool notransparency) #endif } - - -void fullscreen_tint_gl(PalEntry pe); - -static void alloc_palookup(int32_t pal) -{ - // The asm functions vlineasm1, mvlineasm1 (maybe others?) access the next - // lookuptables[...] shade entry for tilesizy==512 tiles. - // See DEBUG_TILESIZY_512 and the comment in a.nasm: vlineasm1. - lookuptables[pal] = (char *) Xaligned_alloc(16, (numshades + 1) * 256); - memset(lookuptables[pal], 0, (numshades + 1) * 256); -} - -static void maybe_alloc_palookup(int32_t palnum); - -void (*paletteLoadFromDisk_replace)(void) = NULL; - -inline bool read_and_test(FileReader& handle, void* buffer, int32_t leng) -{ - return handle.Read(buffer, leng) != leng; -}; - +//========================================================================== // -// loadpalette (internal) +// loads the main palette file. // +//========================================================================== + void paletteLoadFromDisk(void) { GPalette.Init(MAXPALOOKUPS + 1); // one slot for each translation, plus a separate one for the base palettes. -#ifdef USE_OPENGL for (auto & x : glblend) x = defaultglblend; -#endif - - if (paletteLoadFromDisk_replace) - { - paletteLoadFromDisk_replace(); - return; - } auto fil = fileSystem.OpenFileReader("palette.dat"); if (!fil.isOpen()) @@ -139,16 +96,11 @@ void paletteLoadFromDisk(void) for (unsigned char & k : palette) k <<= 2; - paletteSetColorTable(0, palette); + paletteSetColorTable(0, palette, false, false); paletteloaded |= PALETTE_MAIN; - // PALETTE_SHADES - - if (2 != fil.Read(&numshades, 2)) - return; - - numshades = B_LITTLE16(numshades); + numshades = fil.ReadInt16(); if (numshades <= 1) { @@ -157,397 +109,266 @@ void paletteLoadFromDisk(void) return; } - // Auto-detect LameDuke. Its PALETTE.DAT doesn't have a 'numshades' 16-bit - // int after the base palette, but starts directly with the shade tables. - // Thus, the first two bytes will be 00 01, which is 256 if read as - // little-endian int16_t. - int32_t lamedukep = 0; - if (numshades >= 256) +#if 0 + // Reminder: Witchaven's shade table has no index and no easy means to autodetect. + if (numshades == 0 && (g_gameType & GAMEFLAG_WITCHAVEN)) { - uint16_t temp; - if (read_and_test(fil, &temp, 2)) - return; - temp = B_LITTLE16(temp); - if (temp == 770 || numshades > 256) // 02 03 + numshades = 32; + fil.Seek(-2, FileReader::SeekCur); + } + else +#endif + { + // LameDuke's is yet another variant. + if (numshades >= 256) { - if (fil.Seek(-4, FileReader::SeekCur) < 0) + uint16_t temp = fil.ReadUInt16(); + if (temp == 770 || numshades > 256) // 02 03 { - Printf("Warning: seek failed in loadpalette()!\n"); - return; + fil.Seek(-4, FileReader::SeekCur); + numshades = 32; } - - numshades = 32; - lamedukep = 1; - } - else - { - if (fil.Seek(-2, FileReader::SeekCur) < 0) + else { - Printf("Warning: seek failed in loadpalette()!\n"); - return; + fil.Seek(-2, FileReader::SeekCur); } } } + // Read base shade table (lookuptables 0). - maybe_alloc_palookup(0); - if (read_and_test(fil, lookuptables[0], numshades<<8)) + int length = numshades * 256; + auto p = LookupTables[0].LockNewBuffer(length); + auto count = fil.Read(p, length); + LookupTables->UnlockBuffer(); + if (count != length) return; paletteloaded |= PALETTE_SHADE; paletteloaded |= PALETTE_TRANSLUC; - - - // additional blending tables - - uint8_t magic[12]; - if (!read_and_test(fil, magic, sizeof(magic)) && !Bmemcmp(magic, "MoreBlendTab", sizeof(magic))) - { - uint8_t addblendtabs; - if (read_and_test(fil, &addblendtabs, 1)) - { - Printf("Warning: failed reading additional blending table count\n"); - return; - } - - uint8_t blendnum; - char *tab = (char *) Xmalloc(256*256); - for (bssize_t i=0; i= 1 && lognumalphatabs <= 7)) - Printf("invalid lognumalphatabs value, must be in [1 .. 7]\n"); - else - numalphatabs = 1<: open file handle +// load the lookup tables from lookup.dat // -// Returns: -// - on success, 0 -// - on error, -1 (didn't read enough data) -// - -2: error, we already wrote an error message ourselves +//========================================================================== + int32_t paletteLoadLookupTable(FileReader &fp) { - uint8_t numlookups; char remapbuf[256]; - - if (1 != fp.Read(&numlookups, 1)) + int numlookups = fp.ReadUInt8(); + if (numlookups < 1) return -1; - for (bssize_t j=0; j= 256-RESERVEDPALS) - { - Printf("ERROR: attempt to load lookup at reserved pal %d\n", palnum); - return -2; - } + int palnum = fp.ReadUInt8(); if (256 != fp.Read(remapbuf, 256)) return -1; - paletteMakeLookupTable(palnum, remapbuf, 0, 0, 0, 0); + if (palnum >= 256 - RESERVEDPALS) + { + Printf("ERROR: attempt to load lookup at reserved pal %d\n", palnum); + } + else + paletteMakeLookupTable(palnum, remapbuf, 0, 0, 0, 0); } return 0; } +//========================================================================== +// +// Find a gap of four consecutive unused pal numbers to generate fog shade tables. +// +//========================================================================== + void paletteSetupDefaultFog(void) { - // Find a gap of four consecutive unused pal numbers to generate fog shade - // tables. - for (bssize_t j=1; j<=255-3; j++) - if (!lookuptables[j] && !lookuptables[j+1] && !lookuptables[j+2] && !lookuptables[j+3]) + for (int j = 1; j <= 255 - 3; j++) + { + if (!LookupTables[j].IsEmpty() && !LookupTables[j + 1].IsEmpty() && !LookupTables[j + 2].IsEmpty() && !LookupTables[j + 3].IsEmpty()) { paletteMakeLookupTable(j, NULL, 60, 60, 60, 1); - paletteMakeLookupTable(j+1, NULL, 60, 0, 0, 1); - paletteMakeLookupTable(j+2, NULL, 0, 60, 0, 1); - paletteMakeLookupTable(j+3, NULL, 0, 0, 60, 1); + paletteMakeLookupTable(j + 1, NULL, 60, 0, 0, 1); + paletteMakeLookupTable(j + 2, NULL, 0, 60, 0, 1); + paletteMakeLookupTable(j + 3, NULL, 0, 0, 60, 1); break; } + } } +//========================================================================== +// +// post process the lookup tables once everything has been loaded +// +//========================================================================== + void palettePostLoadLookups(void) { - // Alias remaining unused pal numbers to the base shade table. - for (bssize_t j=1; jInactive)) + { + memcpy(remap.Remap, lookup, 256); + for (int j = 0; j < 256; j++) + { + remap.Palette[j] = palette->Palette[remap.Remap[j]]; + } + remap.NumEntries = 256; + GPalette.UpdateTranslation(TRANSLATION(i + 1, l), &remap); + } + if (palette != basepalette) palette->Inactive = false; // clear the marker flag + } + } } + // todo: at this point we should swap colors 0 and 255 so that paletted images being created here have their transparent color at index 0. } -static int32_t palookup_isdefault(int32_t palnum) // KEEPINSYNC engine.lua -{ - return (lookuptables[palnum] == NULL || (palnum!=0 && lookuptables[palnum] == lookuptables[0])); -} - -static void maybe_alloc_palookup(int32_t palnum) -{ - if (palookup_isdefault(palnum)) - { - alloc_palookup(palnum); - if (lookuptables[palnum] == NULL) - Bexit(1); - } -} - -#ifdef USE_OPENGL -glblend_t const nullglblend = -{ - { - { 1.f, BLENDFACTOR_ONE, BLENDFACTOR_ZERO, 0 }, - { 1.f, BLENDFACTOR_ONE, BLENDFACTOR_ZERO, 0 }, - }, -}; -glblend_t const defaultglblend = -{ - { - { 2.f/3.f, BLENDFACTOR_SRC_ALPHA, BLENDFACTOR_ONE_MINUS_SRC_ALPHA, 0 }, - { 1.f/3.f, BLENDFACTOR_SRC_ALPHA, BLENDFACTOR_ONE_MINUS_SRC_ALPHA, 0 }, - }, -}; - -glblend_t glblend[MAXBLENDTABS]; - -void setBlendFactor(int index, int alpha) -{ - if (index >= 0 && index < MAXBLENDTABS) - { - auto& myblend = glblend[index]; - if (index >= 0) - { - myblend.def[0].alpha = index / 255.f; - myblend.def[1].alpha = 1.f - (index / 255.f); - myblend.def[0].src = myblend.def[1].src = BLENDFACTOR_ONE_MINUS_SRC_ALPHA; - myblend.def[0].dst = myblend.def[1].dst = BLENDFACTOR_ONE_MINUS_SRC_ALPHA; - } - else - { - myblend.def[0].alpha = 1; - myblend.def[1].alpha = 1; - myblend.def[0].src = myblend.def[1].src = BLENDFACTOR_ONE; - myblend.def[0].dst = myblend.def[1].dst = BLENDFACTOR_ONE; - } - } -} - -FRenderStyle GetBlend(int blend, int def) -{ - static uint8_t const blendFuncTokens[NUMBLENDFACTORS] = - { - STYLEALPHA_Zero, - STYLEALPHA_One, - STYLEALPHA_SrcCol, - STYLEALPHA_InvSrcCol, - STYLEALPHA_Src, - STYLEALPHA_InvSrc, - STYLEALPHA_Dst, - STYLEALPHA_InvDst, - STYLEALPHA_DstCol, - STYLEALPHA_InvDstCol, - }; - FRenderStyle rs; - rs.BlendOp = STYLEOP_Add; - glblenddef_t const* const glbdef = glblend[blend].def + def; - rs.SrcAlpha = blendFuncTokens[glbdef->src]; - rs.DestAlpha = blendFuncTokens[glbdef->dst]; - rs.Flags = 0; - return rs; -} - -void handle_blend(uint8_t enable, uint8_t blend, uint8_t def) -{ - if (!enable) - { - GLInterface.SetRenderStyle(LegacyRenderStyles[STYLE_Translucent]); - return; - } - auto rs = GetBlend(blend, def); - GLInterface.SetRenderStyle(rs); -} - -float float_trans(uint32_t maskprops, uint8_t blend) -{ - switch (maskprops) - { - case DAMETH_TRANS1: - case DAMETH_TRANS2: - return glblend[blend].def[maskprops - 2].alpha; - default: - return 1.0f; - } -} - -#endif +//========================================================================== +// +// set a lookup table from external data +// +//========================================================================== int32_t paletteSetLookupTable(int32_t palnum, const uint8_t *shtab) { if (shtab != NULL) { - maybe_alloc_palookup(palnum); - Bmemcpy(lookuptables[palnum], shtab, 256*numshades); + int length = numshades * 256; + auto p = LookupTables[palnum].LockNewBuffer(length); + memcpy(p, shtab, length); + LookupTables->UnlockBuffer(); } return 0; } -void paletteFreeLookupTable(int32_t const palnum) -{ - if (palnum == 0 && lookuptables[palnum] != NULL) - { - for (bssize_t i = 1; i < MAXPALOOKUPS; i++) - if (lookuptables[i] == lookuptables[palnum]) - lookuptables[i] = NULL; - - ALIGNED_FREE_AND_NULL(lookuptables[palnum]); - } - else if (lookuptables[palnum] == lookuptables[0]) - lookuptables[palnum] = NULL; - else - ALIGNED_FREE_AND_NULL(lookuptables[palnum]); -} - +//========================================================================== // -// makepalookup +// creates a lookup table from scratch // +//========================================================================== + void paletteMakeLookupTable(int32_t palnum, const char *remapbuf, uint8_t r, uint8_t g, uint8_t b, char noFloorPal) { - int32_t i, j; - - static char idmap[256] = { 1 }; - - if (paletteloaded == 0) - return; + char idmap[256]; // NOTE: palnum==0 is allowed - if ((unsigned) palnum >= MAXPALOOKUPS) + if (paletteloaded == 0 || (unsigned)palnum >= MAXPALOOKUPS) return; g_noFloorPal[palnum] = noFloorPal; - if (remapbuf==NULL) + if (remapbuf == nullptr) { - if ((r|g|b) == 0) + if (r == 0 || g == 0 || b == 0) { - lookuptables[palnum] = lookuptables[0]; // Alias to base shade table! + LookupTables[palnum] = ""; // clear this entry so that later it can be filled with the base remap. return; } - if (idmap[0]==1) // init identity map - for (i=0; i<256; i++) - idmap[i] = i; - + for (int i = 0; i < 256; i++) idmap[i] = i; remapbuf = idmap; } - maybe_alloc_palookup(palnum); - - if ((r|g|b) == 0) + int length = numshades * 256; + auto p = LookupTables[palnum].LockNewBuffer(length); + if (r == 0 || g == 0 || b == 0) { // "black fog"/visibility case -- only remap color indices - for (j=0; jsrc; + rs.DestAlpha = glbdef->dst; + rs.Flags = 0; + return rs; } -void paletteFreeAll() +void SetRenderStyleFromBlend(uint8_t enable, uint8_t blend, uint8_t def) { - paletteloaded = 0; + if (!enable) + { + GLInterface.SetRenderStyle(LegacyRenderStyles[STYLE_Translucent]); + return; + } + auto rs = GetRenderStyle(blend, def); + GLInterface.SetRenderStyle(rs); +} - for (bssize_t i = 0; i < MAXPALOOKUPS; i++) - if (i == 0 || lookuptables[i] != lookuptables[0]) - { - // Take care of handling aliased ^^^ cases! - Xaligned_free(lookuptables[i]); - } - Bmemset(lookuptables, 0, sizeof(lookuptables)); -} \ No newline at end of file +float GetAlphaFromBlend(uint32_t method, uint32_t blend) +{ + return method == DAMETH_TRANS1 || method == DAMETH_TRANS2 ? glblend[blend].def[method - DAMETH_TRANS1].alpha : 1.f; +} diff --git a/source/build/src/polymost.cpp b/source/build/src/polymost.cpp index 8fc8feaab..c2f725636 100644 --- a/source/build/src/polymost.cpp +++ b/source/build/src/polymost.cpp @@ -92,6 +92,7 @@ static float dxb1[MAXWALLSB], dxb2[MAXWALLSB]; #define SOFTROTMAT 0 static int32_t r_pogoDebug = 0; +int32_t r_scenebrightness = 0; static float gviewxrange; static float ghoriz, ghoriz2; @@ -232,7 +233,7 @@ static void polymost_glinit() } for (int palookupnum = 0; palookupnum < MAXPALOOKUPS; ++palookupnum) { - GLInterface.SetPalswapData(palookupnum, (uint8_t*)lookuptables[palookupnum], numshades+1, palookupfog[palookupnum]); + GLInterface.SetPalswapData(palookupnum, (uint8_t*)LookupTables[palookupnum].GetChars(), numshades+1, palookupfog[palookupnum]); } } @@ -289,22 +290,12 @@ void uploadbasepalette(int32_t basepalnum) basepalWFullBrightInfo[i*4+0] = remap->Palette[i].b; basepalWFullBrightInfo[i*4+1] = remap->Palette[i].g; basepalWFullBrightInfo[i*4+2] = remap->Palette[i].r; - basepalWFullBrightInfo[i*4+3] = 0-(IsPaletteIndexFullbright(i) != 0); + basepalWFullBrightInfo[i*4+3] = 0-(FullbrightIndices[i] != 0); } GLInterface.SetPaletteData(basepalnum, basepalWFullBrightInfo); } -// Used by RRRA fog hackery - the only place changing the palswaps at run time. -void uploadpalswaps(int count, int32_t* swaps) -{ - for (int i = 0; i < count; i++) - { - GLInterface.SetPalswapData(i, (uint8_t*)lookuptables[i], numshades + 1, palookupfog[i]); - } -} - - //(dpx,dpy) specifies an n-sided polygon. The polygon must be a convex clockwise loop. // n must be <= 8 (assume clipping can double number of vertices) //method: 0:solid, 1:masked(255 is transparent), 2:transluscent #1, 3:transluscent #2 @@ -415,7 +406,7 @@ static void polymost_drawpoly(vec2f_t const * const dpxy, int32_t const n, int32 return; } - if (lookuptables[globalpal] == NULL) + if (LookupTables[globalpal].IsEmpty()) globalpal = 0; //Load texture (globalpicnum) @@ -521,7 +512,7 @@ static void polymost_drawpoly(vec2f_t const * const dpxy, int32_t const n, int32 if (method & DAMETH_MASKPROPS) { - handle_blend((method & DAMETH_MASKPROPS) > DAMETH_MASK, drawpoly_blend, (method & DAMETH_MASKPROPS) == DAMETH_TRANS2); + SetRenderStyleFromBlend((method & DAMETH_MASKPROPS) > DAMETH_MASK, drawpoly_blend, (method & DAMETH_MASKPROPS) == DAMETH_TRANS2); } float pc[4]; @@ -530,7 +521,7 @@ static void polymost_drawpoly(vec2f_t const * const dpxy, int32_t const n, int32 pc[0] = (float)globalr * (1.f / 255.f); pc[1] = (float)globalg * (1.f / 255.f); pc[2] = (float)globalb * (1.f / 255.f); - pc[3] = float_trans(method & DAMETH_MASKPROPS, drawpoly_blend) * (1.f - drawpoly_alpha); + pc[3] = GetAlphaFromBlend(method & DAMETH_MASKPROPS, drawpoly_blend) * (1.f - drawpoly_alpha); if (skyzbufferhack_pass) pc[3] = 0.01f; @@ -3532,7 +3523,7 @@ static void polymost_drawmaskwallinternal(int32_t wallIndex) #else uint8_t const blend = wallext[wallIndex].blend; #endif - handle_blend(!!(wal->cstat & 128), blend, !!(wal->cstat & 512)); + SetRenderStyleFromBlend(!!(wal->cstat & 128), blend, !!(wal->cstat & 512)); drawpoly_alpha = 0.f; drawpoly_blend = blend; @@ -3839,7 +3830,7 @@ void polymost_drawsprite(int32_t snum) if (tspr->cstat & 2) method = DAMETH_CLAMPED | ((tspr->cstat & 512) ? DAMETH_TRANS2 : DAMETH_TRANS1); - handle_blend(!!(tspr->cstat & 2), tspr->blend, !!(tspr->cstat & 512)); + SetRenderStyleFromBlend(!!(tspr->cstat & 2), tspr->blend, !!(tspr->cstat & 512)); drawpoly_alpha = spriteext[spritenum].alpha; drawpoly_blend = tspr->blend; @@ -4610,7 +4601,7 @@ static void polymost_precache(int32_t dapicnum, int32_t dapalnum, int32_t datype // while sprites are clamped if (videoGetRenderMode() < REND_POLYMOST) return; - if ((dapalnum < (MAXPALOOKUPS - RESERVEDPALS)) && (lookuptables[dapalnum] == NULL)) return;//dapalnum = 0; + if ((dapalnum < (MAXPALOOKUPS - RESERVEDPALS)) && (LookupTables[dapalnum].IsEmpty())) return;//dapalnum = 0; //Printf("precached %d %d type %d\n", dapicnum, dapalnum, datype); hicprecaching = 1; diff --git a/source/build/src/voxmodel.cpp b/source/build/src/voxmodel.cpp index 265d5bc28..27a437810 100644 --- a/source/build/src/voxmodel.cpp +++ b/source/build/src/voxmodel.cpp @@ -1098,7 +1098,7 @@ int32_t polymost_voxdraw(voxmodel_t *m, tspriteptr_t const tspr) pc[3] = (tspr->cstat & 2) ? glblend[tspr->blend].def[!!(tspr->cstat & 512)].alpha : 1.0f; pc[3] *= 1.0f - spriteext[tspr->owner].alpha; - handle_blend(!!(tspr->cstat & 2), tspr->blend, !!(tspr->cstat & 512)); + SetRenderStyleFromBlend(!!(tspr->cstat & 2), tspr->blend, !!(tspr->cstat & 512)); if (!(tspr->cstat & 2) || spriteext[tspr->owner].alpha > 0.f || pc[3] < 1.0f) GLInterface.EnableBlend(true); // else GLInterface.EnableBlend(false); diff --git a/source/common/engine/palettecontainer.cpp b/source/common/engine/palettecontainer.cpp index 3103e7775..41e9a01ba 100644 --- a/source/common/engine/palettecontainer.cpp +++ b/source/common/engine/palettecontainer.cpp @@ -39,6 +39,7 @@ #include "colormatcher.h" #include "templates.h" #include "palettecontainer.h" +#include "files.h" PaletteContainer GPalette; FColorMatcher ColorMatcher; @@ -102,6 +103,35 @@ void PaletteContainer::Clear() TranslationTables.Reset(); } +//=========================================================================== +// +// +// +//=========================================================================== + +int PaletteContainer::DetermineTranslucency(FileReader& tranmap) +{ + uint8_t index; + PalEntry newcolor; + PalEntry newcolor2; + + if (!tranmap.isOpen()) return 255; + tranmap.Seek(GPalette.BlackIndex * 256 + GPalette.WhiteIndex, FileReader::SeekSet); + tranmap.Read(&index, 1); + + newcolor = GPalette.BaseColors[GPalette.Remap[index]]; + + tranmap.Seek(GPalette.WhiteIndex * 256 + GPalette.BlackIndex, FileReader::SeekSet); + tranmap.Read(&index, 1); + newcolor2 = GPalette.BaseColors[GPalette.Remap[index]]; + if (newcolor2.r == 255) // if black on white results in white it's either + // fully transparent or additive + { + return -newcolor.r; + } + return newcolor.r; +} + //---------------------------------------------------------------------------- // // diff --git a/source/common/engine/palettecontainer.h b/source/common/engine/palettecontainer.h index b178e0aa4..7b7143bae 100644 --- a/source/common/engine/palettecontainer.h +++ b/source/common/engine/palettecontainer.h @@ -4,6 +4,8 @@ #include "memarena.h" #include "palentry.h" +class FileReader; + struct FRemapTable { FRemapTable(int count = 256) { NumEntries = count; } @@ -81,6 +83,7 @@ public: void Init(int numslots); // This cannot be a constructor!!! void SetPalette(const uint8_t* colors, int transparent_index = -1); void Clear(); + int DetermineTranslucency(FileReader& file); FRemapTable* AddRemap(FRemapTable* remap); void UpdateTranslation(int trans, FRemapTable* remap); int AddTranslation(int slot, FRemapTable* remap, int count = 1); diff --git a/source/core/2d/v_2ddrawer.cpp b/source/core/2d/v_2ddrawer.cpp index 96589d6af..28df4497f 100644 --- a/source/core/2d/v_2ddrawer.cpp +++ b/source/core/2d/v_2ddrawer.cpp @@ -650,7 +650,7 @@ void F2DDrawer::rotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16 else method |= DAMETH_MASK; - dg.mRenderStyle = GetBlend(dablend, (dastat & RS_TRANS2) ? 1 : 0); + dg.mRenderStyle = GetRenderStyle(dablend, (dastat & RS_TRANS2) ? 1 : 0); } else { @@ -664,7 +664,7 @@ void F2DDrawer::rotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16 dg.mVertIndex = (int)mVertices.Reserve(4); auto ptr = &mVertices[dg.mVertIndex]; float drawpoly_alpha = daalpha * (1.0f / 255.0f); - float alpha = float_trans(method, dablend) * (1.f - drawpoly_alpha); // Hmmm... + float alpha = GetAlphaFromBlend(method, dablend) * (1.f - drawpoly_alpha); // Hmmm... p.a = (uint8_t)(alpha * 255); vec2_16_t const siz = dg.mTexture->GetSize(); @@ -749,8 +749,8 @@ void F2DDrawer::AddPoly(FTexture* img, FVector4* vt, size_t vtcount, unsigned in PalEntry p = 0xffffffff; if (maskprops > DAMETH_MASK) { - dg.mRenderStyle = GetBlend(0, maskprops == DAMETH_TRANS2); - p.a = (uint8_t)(float_trans(maskprops, 0) * 255); + dg.mRenderStyle = GetRenderStyle(0, maskprops == DAMETH_TRANS2); + p.a = (uint8_t)(GetAlphaFromBlend(maskprops, 0) * 255); } dg.mTexture = img; dg.mRemapIndex = palette | (shade << 16); diff --git a/source/core/rendering/v_video.cpp b/source/core/rendering/v_video.cpp index c60ff82e6..e460f7b2c 100644 --- a/source/core/rendering/v_video.cpp +++ b/source/core/rendering/v_video.cpp @@ -369,6 +369,8 @@ void V_InitScreen() void V_Init2() { + palettePostLoadLookups(); + float gamma = static_cast(screen)->Gamma; { diff --git a/source/core/textures/buildtiles.cpp b/source/core/textures/buildtiles.cpp index bcec6f39f..089c98ce0 100644 --- a/source/core/textures/buildtiles.cpp +++ b/source/core/textures/buildtiles.cpp @@ -50,7 +50,6 @@ enum MAXARTFILES_TOTAL = 220 }; -extern char* lookuptables[]; BuildTiles TileFiles; @@ -556,10 +555,10 @@ void tileCopy(int tile, int source, int pal, int xoffset, int yoffset, int flags if (pal != -1) { - auto remap = lookuptables[pal]; + auto remap = (const uint8_t*)LookupTables[pal].GetChars(); for (auto& pixel : buffer) { - pixel = lookuptables[pal][pixel]; + pixel = remap[pixel]; } } tex = new FLooseTile(buffer, tex->GetWidth(), tex->GetHeight()); diff --git a/source/duke3d/src/common.cpp b/source/duke3d/src/common.cpp index a5513988d..14406a643 100644 --- a/source/duke3d/src/common.cpp +++ b/source/duke3d/src/common.cpp @@ -133,7 +133,7 @@ void G_LoadLookups(void) for (unsigned char & k : paldata) k <<= 2; - paletteSetColorTable(basepalnum, paldata, basepalnum == DREALMSPAL || basepalnum == ENDINGPAL); + paletteSetColorTable(basepalnum, paldata, basepalnum == DREALMSPAL || basepalnum == ENDINGPAL, basepalnum < DREALMSPAL); } } diff --git a/source/duke3d/src/game.cpp b/source/duke3d/src/game.cpp index 336cad956..f156e1d72 100644 --- a/source/duke3d/src/game.cpp +++ b/source/duke3d/src/game.cpp @@ -5262,8 +5262,6 @@ static void G_PostLoadPalette(void) if (!(duke3d_globalflags & DUKE3D_NO_PALETTE_CHANGES)) paletteFixTranslucencyMask(); - - palettePostLoadLookups(); } #define SETFLAG(Tilenum, Flag) g_tile[Tilenum].flags |= Flag diff --git a/source/exhumed/src/menu.cpp b/source/exhumed/src/menu.cpp index 8bfac39a6..9abdbbbe6 100644 --- a/source/exhumed/src/menu.cpp +++ b/source/exhumed/src/menu.cpp @@ -1003,7 +1003,7 @@ void uploadCinemaPalettes() hFile.Read(palette, 768); for (auto& c : palette) c <<= 2; - paletteSetColorTable(ANIMPAL+i, palette); + paletteSetColorTable(ANIMPAL+i, palette, false, true); } } diff --git a/source/glbackend/gl_texture.cpp b/source/glbackend/gl_texture.cpp index 64edfaa2e..24e5ae45e 100644 --- a/source/glbackend/gl_texture.cpp +++ b/source/glbackend/gl_texture.cpp @@ -40,6 +40,7 @@ #include "textures.h" #include "bitmap.h" #include "v_font.h" +#include "palettecontainer.h" #include "../../glbackend/glbackend.h" // Test CVARs. @@ -152,6 +153,61 @@ FHardwareTexture* GLInstance::LoadTexture(FTexture* tex, int textype, int palid) // //=========================================================================== +struct TexturePick +{ + FTexture* texture; // which texture to use + int translation; // which translation table to use + int tintFlags; // which shader tinting options to use + PalEntry tintColor; // Tint color + PalEntry basepalTint; // can the base palette be done with a global tint effect? +}; + +TexturePick PickTexture(int tilenum, int basepal, int palette) +{ + TexturePick pick = { nullptr, 0, -1, 0xffffff, 0xffffff }; + int usepalette = fixpalette >= 0 ? fixpalette : basepal; + int usepalswap = fixpalswap >= 0 ? fixpalswap : palette; + auto& h = hictinting[palette]; + auto tex = TileFiles.tiles[tilenum]; + auto rep = (hw_hightile && !(h.f & HICTINT_ALWAYSUSEART)) ? tex->FindReplacement(usepalswap) : nullptr; + // Canvas textures must be treated like hightile replacements in the following code. + bool truecolor = rep || tex->GetUseType() == FTexture::Canvas; + bool applytint = false; + if (truecolor) + { + if (usepalette != 0) + { + // This is a global setting for the entire scene, so let's do it here, right at the start. (Fixme: Store this in a static table instead of reusing the same entry for all palettes.) + auto& hh = hictinting[MAXPALOOKUPS - 1]; + // This sets a tinting color for global palettes, e.g. water or slime - only used for hires replacements (also an option for low-resource hardware where duplicating the textures may be problematic.) + pick.basepalTint = hh.tint; + } + + if (rep) + { + tex = rep->faces[0]; + } + if (!rep || rep->palnum != palette || (h.f & HICTINT_APPLYOVERALTPAL)) applytint = true; + } + else + { + // Tinting is not used on indexed textures, unless explicitly requested + if (h.f & (HICTINT_ALWAYSUSEART | HICTINT_USEONART)) + { + applytint = true; + if (!(h.f & HICTINT_APPLYOVERPALSWAP)) usepalswap = 0; + } + pick.translation = TRANSLATION(usepalette + 1, usepalswap); + } + pick.texture = tex; + if (applytint && h.f) + { + pick.tintFlags = h.f; + pick.tintColor = h.tint; + } + return pick; +} + bool GLInstance::SetTextureInternal(int picnum, FTexture* tex, int palette, int method, int sampleroverride, FTexture *det, float detscale, FTexture *glow) { if (tex->GetWidth() <= 0 || tex->GetHeight() <= 0) return false; diff --git a/source/glbackend/hw_draw2d.cpp b/source/glbackend/hw_draw2d.cpp index cd226b5c6..44d01b112 100644 --- a/source/glbackend/hw_draw2d.cpp +++ b/source/glbackend/hw_draw2d.cpp @@ -241,8 +241,7 @@ void GLInstance::Draw2D(F2DDrawer *drawer) static int32_t tint_blood_r = 0, tint_blood_g = 0, tint_blood_b = 0; -extern palette_t palfadergb; -extern unsigned char palfadedelta ; +extern PalEntry palfadergb; void DrawFullscreenBlends() { @@ -255,11 +254,11 @@ void DrawFullscreenBlends() GLInterface.EnableBlend(true); GLInterface.UseColorOnly(true); - if (palfadedelta > 0) + if (palfadergb.a > 0) { // Todo: reroute to the 2D drawer GLInterface.SetRenderStyle(LegacyRenderStyles[STYLE_Translucent]); - GLInterface.SetColorub(palfadergb.r, palfadergb.g, palfadergb.b, palfadedelta); + GLInterface.SetColorub(palfadergb.r, palfadergb.g, palfadergb.b, palfadergb.a); GLInterface.Draw(DT_TRIANGLE_STRIP, FFlatVertexBuffer::PRESENT_INDEX, 4); } if (tint_blood_r | tint_blood_g | tint_blood_b) diff --git a/source/rr/src/common.cpp b/source/rr/src/common.cpp index 863d293ed..0c5757ea9 100644 --- a/source/rr/src/common.cpp +++ b/source/rr/src/common.cpp @@ -132,7 +132,7 @@ void G_LoadLookups(void) for (bssize_t k = 0; k < 768; k++) paldata[k] <<= 2; - paletteSetColorTable(basepalnum, paldata, basepalnum == DREALMSPAL || basepalnum == ENDINGPAL); + paletteSetColorTable(basepalnum, paldata, basepalnum == DREALMSPAL || basepalnum == ENDINGPAL, basepalnum < DREALMSPAL); } for (int i = 0; i < 256; i++) @@ -142,7 +142,7 @@ void G_LoadLookups(void) paldata[i * 3+1] = GPalette.BaseColors[i].g; paldata[i * 3+2] = GPalette.BaseColors[i].r; } - paletteSetColorTable(DRUGPAL, paldata); // todo: implement this as a shader effect + paletteSetColorTable(DRUGPAL, paldata, false, false); // todo: implement this as a shader effect (swap R and B in postprocessing.) if (RR) { @@ -186,7 +186,7 @@ void G_LoadLookups(void) { paletteMakeLookupTable(50, NULL, 12 * 4, 12 * 4, 12 * 4, 0); paletteMakeLookupTable(51, NULL, 12 * 4, 12 * 4, 12 * 4, 0); - paletteMakeLookupTable(54, lookuptables[8], 32 * 4, 32 * 4, 32 * 4, 0); + paletteMakeLookupTable(54, LookupTables[8].GetChars(), 32 * 4, 32 * 4, 32 * 4, 0); } } } diff --git a/source/rr/src/game.cpp b/source/rr/src/game.cpp index e3b377e3e..8e57538e6 100644 --- a/source/rr/src/game.cpp +++ b/source/rr/src/game.cpp @@ -6606,8 +6606,6 @@ static void G_PostLoadPalette(void) if (!(duke3d_globalflags & DUKE3D_NO_PALETTE_CHANGES)) paletteFixTranslucencyMask(); - - palettePostLoadLookups(); } #define SETFLAG(Tilenum, Flag) g_tile[Tilenum].flags |= Flag diff --git a/source/sw/src/game.cpp b/source/sw/src/game.cpp index 9d70227b0..83e221220 100644 --- a/source/sw/src/game.cpp +++ b/source/sw/src/game.cpp @@ -730,7 +730,7 @@ bool InitGame() for (auto& c : pal) c <<= 2; - paletteSetColorTable(DREALMSPAL, pal.Data(), true); + paletteSetColorTable(DREALMSPAL, pal.Data(), true, true); } } @@ -844,7 +844,7 @@ bool InitGame() enginePostInit(); - palettePostLoadLookups(); + paletteFixTranslucencyMask(); V_Init2(); DemoModeMenuInit = TRUE;