From c285f38a02d8d21f0dc8debcae5d870c4c4a6095 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 21 Sep 2009 13:15:36 +0000 Subject: [PATCH] - Fixed: When drawing with a special colormap the quad's flags weren't cleared which could cause crashes. - Added custom special colormaps to DECORATE. - Cleaned up special colormap code and removed lots of dependencies on the knowledge of the tables' contents. SVN r1860 (trunk) --- docs/rh-log.txt | 7 ++ src/colormatcher.h | 5 ++ src/g_shared/a_artifacts.cpp | 45 +++--------- src/g_shared/a_artifacts.h | 8 --- src/p_lnspec.cpp | 11 ++- src/r_main.cpp | 6 +- src/r_things.cpp | 15 ++-- src/tarray.h | 4 +- src/textures/bitmap.cpp | 104 ++++++--------------------- src/textures/bitmap.h | 11 ++- src/textures/multipatchtexture.cpp | 43 ++++++----- src/thingdef/thingdef_properties.cpp | 61 +++++++++------- src/v_draw.cpp | 2 +- src/v_palette.cpp | 88 ++++++++++++++++------- src/v_palette.h | 40 ++++++++--- src/v_video.h | 2 +- src/win32/fb_d3d9.cpp | 3 +- 17 files changed, 224 insertions(+), 231 deletions(-) diff --git a/docs/rh-log.txt b/docs/rh-log.txt index 005aa5e1e4..8b26fa2e67 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,3 +1,10 @@ +September 21, 2009 (Changes by Graf Zahl) +- Fixed: When drawing with a special colormap the quad's flags weren't cleared + which could cause crashes. +- Added custom special colormaps to DECORATE. +- Cleaned up special colormap code and removed lots of dependencies on the + knowledge of the tables' contents. + September 20, 2009 (Changes by Graf Zahl) - Changed call to R_DrawRemainingPlayerSprites into a virtual function of DFrameBuffer because its implementation is specific to the software diff --git a/src/colormatcher.h b/src/colormatcher.h index ca7992d6dc..04b9f71988 100644 --- a/src/colormatcher.h +++ b/src/colormatcher.h @@ -43,6 +43,11 @@ public: void SetPalette (const DWORD *palette); BYTE Pick (int r, int g, int b); + BYTE Pick (PalEntry pe) + { + return Pick(pe.r, pe.g, pe.b); + } + FColorMatcher &operator= (const FColorMatcher &other); private: diff --git a/src/g_shared/a_artifacts.cpp b/src/g_shared/a_artifacts.cpp index 5b7f016cf8..fa2c1e59f6 100644 --- a/src/g_shared/a_artifacts.cpp +++ b/src/g_shared/a_artifacts.cpp @@ -139,14 +139,7 @@ PalEntry APowerup::GetBlend () if (EffectTics <= BLINKTHRESHOLD && !(EffectTics & 8)) return 0; - if (BlendColor == INVERSECOLOR || - BlendColor == GOLDCOLOR || - // [BC] HAX! - BlendColor == REDCOLOR || - BlendColor == GREENCOLOR || - BlendColor == BLUECOLOR) - return 0; - + if (IsSpecialColormap(BlendColor)) return 0; return BlendColor; } @@ -175,37 +168,19 @@ void APowerup::DoEffect () if (EffectTics > 0) { - int oldcolormap = Owner->player->fixedcolormap; - if (EffectTics > BLINKTHRESHOLD || (EffectTics & 8)) + int Colormap = GetSpecialColormap(BlendColor); + + if (Colormap != NOFIXEDCOLORMAP) { - if (BlendColor == INVERSECOLOR) + if (EffectTics > BLINKTHRESHOLD || (EffectTics & 8)) { - Owner->player->fixedcolormap = INVERSECOLORMAP; + Owner->player->fixedcolormap = Colormap; } - else if (BlendColor == GOLDCOLOR) + else if (Owner->player->fixedcolormap == Colormap) { - Owner->player->fixedcolormap = GOLDCOLORMAP; + // only unset if the fixed colormap comes from this item + Owner->player->fixedcolormap = NOFIXEDCOLORMAP; } - else if (BlendColor == REDCOLOR) - { - Owner->player->fixedcolormap = REDCOLORMAP; - } - else if (BlendColor == GREENCOLOR) - { - Owner->player->fixedcolormap = GREENCOLORMAP; - } - else if (BlendColor == BLUECOLOR) - { - Owner->player->fixedcolormap = BLUECOLORMAP; - } - } - else if ((BlendColor == INVERSECOLOR && Owner->player->fixedcolormap == INVERSECOLORMAP) || - (BlendColor == GOLDCOLOR && Owner->player->fixedcolormap == GOLDCOLORMAP) || - (BlendColor == REDCOLOR && Owner->player->fixedcolormap == REDCOLORMAP) || - (BlendColor == GREENCOLOR && Owner->player->fixedcolormap == GREENCOLORMAP) || - (BlendColor == BLUECOLOR && Owner->player->fixedcolormap == BLUECOLORMAP)) - { - Owner->player->fixedcolormap = NOFIXEDCOLORMAP; } } } @@ -711,7 +686,7 @@ int APowerInvisibility::AlterWeaponSprite (vissprite_t *vis) if ((vis->alpha < TRANSLUC25 && special1 > 0) || (vis->alpha == 0)) { vis->alpha = clamp((OPAQUE - Strength), 0, OPAQUE); - vis->colormap = SpecialColormaps[INVERSECOLORMAP]; + vis->colormap = SpecialColormaps[INVERSECOLORMAP].Colormap; } return -1; // This item is valid so another one shouldn't reset the translucency } diff --git a/src/g_shared/a_artifacts.h b/src/g_shared/a_artifacts.h index 1272de60de..93352a719c 100644 --- a/src/g_shared/a_artifacts.h +++ b/src/g_shared/a_artifacts.h @@ -3,14 +3,6 @@ #include "a_pickups.h" -#define INVERSECOLOR 0x00345678 -#define GOLDCOLOR 0x009abcde - -// [BC] More hacks! -#define REDCOLOR 0x00beefee -#define GREENCOLOR 0x00beefad -#define BLUECOLOR 0x00befeed - class player_t; // A powerup is a pseudo-inventory item that applies an effect to its diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index b34ed48789..17333f7d7b 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -2532,7 +2532,10 @@ FUNC(LS_SetPlayerProperty) if (power != 4) { APowerup *item = static_cast(it->GiveInventoryType (powers[power])); - if (item != NULL && power == 0) item->BlendColor = INVERSECOLOR; + if (item != NULL && power == 0 && arg1 == 1) + { + item->BlendColor = MakeSpecialColormap(INVERSECOLORMAP); + } } else if (it->player - players == consoleplayer) { @@ -2568,7 +2571,11 @@ FUNC(LS_SetPlayerProperty) { // Give power if (power != 4) { - players[i].mo->GiveInventoryType (powers[power]); + APowerup *item = static_cast(players[i].mo->GiveInventoryType (powers[power])); + if (item != NULL && power == 0 && arg1 == 1) + { + item->BlendColor = MakeSpecialColormap(INVERSECOLORMAP); + } } else if (i == consoleplayer) { diff --git a/src/r_main.cpp b/src/r_main.cpp index 00dfe83531..ea39367681 100644 --- a/src/r_main.cpp +++ b/src/r_main.cpp @@ -1163,9 +1163,9 @@ void R_SetupFrame (AActor *actor) if (player != NULL && camera == player->mo) { - if (player->fixedcolormap >= 0 && player->fixedcolormap < NUM_SPECIALCOLORMAPS) + if (player->fixedcolormap >= 0 && player->fixedcolormap < (int)SpecialColormaps.Size()) { - fixedcolormap = SpecialColormaps[player->fixedcolormap]; + fixedcolormap = SpecialColormaps[player->fixedcolormap].Colormap; } else if (player->fixedlightlevel >= 0 && player->fixedlightlevel < NUMCOLORMAPS) { @@ -1175,7 +1175,7 @@ void R_SetupFrame (AActor *actor) // [RH] Inverse light for shooting the Sigil if (fixedcolormap == NULL && extralight == INT_MIN) { - fixedcolormap = SpecialColormaps[INVERSECOLORMAP]; + fixedcolormap = SpecialColormaps[INVERSECOLORMAP].Colormap; extralight = 0; } diff --git a/src/r_things.cpp b/src/r_things.cpp index 552241be20..e0e6a63cc3 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -1680,7 +1680,8 @@ void R_DrawPSprite (pspdef_t* psp, int pspnum, AActor *owner, fixed_t sx, fixed_ // The colormap has changed. Is it one we can easily identify? // If not, then don't bother trying to identify it for // hardware accelerated drawing. - if (vis->colormap < SpecialColormaps[0] || vis->colormap >= SpecialColormaps[NUM_SPECIALCOLORMAPS]) + if (vis->colormap < SpecialColormaps[0].Colormap || + vis->colormap >= SpecialColormaps[SpecialColormaps.Size()].Colormap) { noaccel = true; } @@ -1812,19 +1813,21 @@ void R_DrawRemainingPlayerSprites() { FDynamicColormap *colormap = VisPSpritesBaseColormap[i]; bool flip = vis->xiscale < 0; - FSpecialColormapParameters *special = NULL; + FSpecialColormap *special = NULL; PalEntry overlay = 0; FColormapStyle colormapstyle; bool usecolormapstyle = false; - if (vis->colormap >= SpecialColormaps[0] && vis->colormap < SpecialColormaps[NUM_SPECIALCOLORMAPS]) + if (vis->colormap >= SpecialColormaps[0].Colormap && + vis->colormap < SpecialColormaps[SpecialColormaps.Size()].Colormap) { - ptrdiff_t specialmap = (vis->colormap - SpecialColormaps[0]) >> 8; - if (SpecialColormapParms[specialmap].Inverted) + // Yuck! There needs to be a better way to store colormaps in the vissprite... :( + ptrdiff_t specialmap = (vis->colormap - SpecialColormaps[0].Colormap) / sizeof(FSpecialColormap); + if (SpecialColormaps[specialmap].Inverted) { vis->RenderStyle.Flags ^= STYLEF_InvertSource; } - special = &SpecialColormapParms[specialmap]; + special = &SpecialColormaps[specialmap]; } else if (colormap->Color == PalEntry(255,255,255) && colormap->Desaturate == 0) diff --git a/src/tarray.h b/src/tarray.h index 72bbc5e61e..92a6552e47 100644 --- a/src/tarray.h +++ b/src/tarray.h @@ -120,12 +120,12 @@ public: } } // Return a reference to an element - T &operator[] (unsigned int index) const + T &operator[] (size_t index) const { return Array[index]; } // Returns the value of an element - TT operator() (unsigned int index) const + TT operator() (size_t index) const { return Array[index]; } diff --git a/src/textures/bitmap.cpp b/src/textures/bitmap.cpp index c985e14946..913aa507e7 100644 --- a/src/textures/bitmap.cpp +++ b/src/textures/bitmap.cpp @@ -35,6 +35,7 @@ #include "bitmap.h" #include "templates.h" #include "r_translate.h" +#include "v_palette.h" //=========================================================================== @@ -70,86 +71,6 @@ void iCopyColors(BYTE *pout, const BYTE *pin, int count, int step, FCopyInfo *in } break; - case BLEND_INVERSEMAP: - // Doom's inverted invulnerability map - for(i=0;i(255 - TSrc::Gray(pin),0,255); - - TBlend::OpC(pout[TDest::RED], gray, a, inf); - TBlend::OpC(pout[TDest::GREEN], gray, a, inf); - TBlend::OpC(pout[TDest::BLUE], gray, a, inf); - TBlend::OpA(pout[TDest::ALPHA], a, inf); - } - pout+=4; - pin+=step; - } - break; - - case BLEND_GOLDMAP: - // Heretic's golden invulnerability map - for(i=0;i(gray+(gray>>1),0,255); - g=clamp(gray-(gray>>2),0,255); - - TBlend::OpC(pout[TDest::RED], r, a, inf); - TBlend::OpC(pout[TDest::GREEN], g, a, inf); - TBlend::OpC(pout[TDest::BLUE], 0, a, inf); - TBlend::OpA(pout[TDest::ALPHA], a, inf); - } - pout+=4; - pin+=step; - } - break; - - case BLEND_REDMAP: - // Skulltag's red Doomsphere map - for(i=0;i(gray+(gray>>1),0,255); - - TBlend::OpC(pout[TDest::RED], r, a, inf); - TBlend::OpC(pout[TDest::GREEN], 0, a, inf); - TBlend::OpC(pout[TDest::BLUE], 0, a, inf); - TBlend::OpA(pout[TDest::ALPHA], a, inf); - } - pout+=4; - pin+=step; - } - break; - - case BLEND_GREENMAP: - // Skulltag's Guardsphere map - for(i=0;i(gray+(gray>>1),0,255); - - TBlend::OpC(pout[TDest::RED], r, a, inf); - TBlend::OpC(pout[TDest::GREEN], r, a, inf); - TBlend::OpC(pout[TDest::BLUE], gray, a, inf); - TBlend::OpA(pout[TDest::ALPHA], a, inf); - } - pout+=4; - pin+=step; - } - break; - case BLEND_ICEMAP: // Create the ice translation table, based on Hexen's. // Since this is done in True Color the purplish tint is fully preserved - even in Doom! @@ -171,7 +92,28 @@ void iCopyColors(BYTE *pout, const BYTE *pin, int count, int step, FCopyInfo *in break; default: - if (inf->blend >= BLEND_DESATURATE1 && inf->blend<=BLEND_DESATURATE31) + + if (inf->blend >= BLEND_SPECIALCOLORMAP1) + { + FSpecialColormap *cm = &SpecialColormaps[inf->blend - BLEND_SPECIALCOLORMAP1]; + for(i=0;i(255 - TSrc::Gray(pin),0,255); + + PalEntry pe = cm->GrayscaleToColor[gray]; + TBlend::OpC(pout[TDest::RED], pe.r , a, inf); + TBlend::OpC(pout[TDest::GREEN], pe.g, a, inf); + TBlend::OpC(pout[TDest::BLUE], pe.b, a, inf); + TBlend::OpA(pout[TDest::ALPHA], a, inf); + } + pout+=4; + pin+=step; + } + } + else if (inf->blend >= BLEND_DESATURATE1 && inf->blend<=BLEND_DESATURATE31) { // Desaturated light settings. fac=inf->blend-BLEND_DESATURATE1+1; diff --git a/src/textures/bitmap.h b/src/textures/bitmap.h index 5d9b58a6f2..04bd580cd8 100644 --- a/src/textures/bitmap.h +++ b/src/textures/bitmap.h @@ -262,13 +262,10 @@ enum ColorType enum EBlend { BLEND_NONE = 0, - BLEND_INVERSEMAP = 1, - BLEND_GOLDMAP = 2, - BLEND_REDMAP = 3, - BLEND_GREENMAP = 4, - BLEND_ICEMAP = 5, - BLEND_DESATURATE1 = 6, - BLEND_DESATURATE31 = 36, + BLEND_ICEMAP = 1, + BLEND_DESATURATE1 = 2, + BLEND_DESATURATE31 = 32, + BLEND_SPECIALCOLORMAP1 = 33, BLEND_MODULATE = -1, BLEND_OVERLAY = -2, }; diff --git a/src/textures/multipatchtexture.cpp b/src/textures/multipatchtexture.cpp index 86bab74f81..a52bd2e37a 100644 --- a/src/textures/multipatchtexture.cpp +++ b/src/textures/multipatchtexture.cpp @@ -425,23 +425,15 @@ BYTE *GetBlendMap(PalEntry blend, BYTE *blendwork) switch (blend.a==0 ? blend.r : -1) { - case BLEND_INVERSEMAP: - return SpecialColormaps[INVERSECOLORMAP]; - - case BLEND_GOLDMAP: - return SpecialColormaps[GOLDCOLORMAP]; - - case BLEND_REDMAP: - return SpecialColormaps[REDCOLORMAP]; - - case BLEND_GREENMAP: - return SpecialColormaps[GREENCOLORMAP]; - case BLEND_ICEMAP: return TranslationToTable(TRANSLATION(TRANSLATION_Standard, 7))->Remap; default: - if (blend.r >= BLEND_DESATURATE1 && blend.r <= BLEND_DESATURATE31) + if (blend.r >= BLEND_SPECIALCOLORMAP1) + { + return SpecialColormaps[blend.r - BLEND_SPECIALCOLORMAP1].Colormap; + } + else if (blend.r >= BLEND_DESATURATE1 && blend.r <= BLEND_DESATURATE31) { return DesaturateColormap[blend.r - BLEND_DESATURATE1]; } @@ -1044,22 +1036,29 @@ void FMultiPatchTexture::ParsePatch(FScanner &sc, TexPart & part) } else if (sc.Compare("Translation")) { + int match; + bComplex = true; if (part.Translation != NULL) delete part.Translation; part.Translation = NULL; part.Blend = 0; - static const char *maps[] = { "inverse", "gold", "red", "green", "ice", "desaturate", NULL }; + static const char *maps[] = { "inverse", "gold", "red", "green", "blue", NULL }; sc.MustGetString(); - int match = sc.MatchString(maps); + + match = sc.MatchString(maps); if (match >= 0) { - part.Blend.r = 1 + match; - if (part.Blend.r == BLEND_DESATURATE1) - { - sc.MustGetStringName(","); - sc.MustGetNumber(); - part.Blend.r += clamp(sc.Number-1, 0, 30); - } + part.Blend.r = BLEND_SPECIALCOLORMAP1 + match; + } + else if (sc.Compare("ICE")) + { + part.Blend.r = BLEND_ICEMAP; + } + else if (sc.Compare("DESATURATE")) + { + sc.MustGetStringName(","); + sc.MustGetNumber(); + part.Blend.r = BLEND_DESATURATE1 + clamp(sc.Number-1, 0, 30); } else { diff --git a/src/thingdef/thingdef_properties.cpp b/src/thingdef/thingdef_properties.cpp index 4f29d272c8..0c579efa28 100644 --- a/src/thingdef/thingdef_properties.cpp +++ b/src/thingdef/thingdef_properties.cpp @@ -1556,7 +1556,8 @@ DEFINE_CLASS_PROPERTY(weapon, S, WeaponPiece) //========================================================================== DEFINE_CLASS_PROPERTY_PREFIX(powerup, color, C_f, Inventory) { - PROP_INT_PARM(i, 0); + static const char *specialcolormapnames[] = { + "INVERSEMAP", "GOLDMAP", "REDMAP", "GREENMAP", "BLUEMAP", NULL }; int alpha; PalEntry * pBlendColor; @@ -1582,30 +1583,11 @@ DEFINE_CLASS_PROPERTY_PREFIX(powerup, color, C_f, Inventory) { PROP_STRING_PARM(name, 1); - if (!stricmp(name, "INVERSEMAP")) + // We must check the old special colormap names for compatibility + int v = MatchString(name, specialcolormapnames); + if (v >= 0) { - *pBlendColor = INVERSECOLOR; - return; - } - else if (!stricmp(name, "GOLDMAP")) - { - *pBlendColor = GOLDCOLOR; - return; - } - // [BC] Yay, more hacks. - else if (!stricmp(name, "REDMAP" )) - { - *pBlendColor = REDCOLOR; - return; - } - else if (!stricmp(name, "GREENMAP" )) - { - *pBlendColor = GREENCOLOR; - return; - } - else if (!stricmp(name, "BLUEMAP")) - { - *pBlendColor = BLUECOLOR; + *pBlendColor = MakeSpecialColormap(v); return; } @@ -1623,6 +1605,37 @@ DEFINE_CLASS_PROPERTY_PREFIX(powerup, color, C_f, Inventory) else *pBlendColor = 0; } +//========================================================================== +// +//========================================================================== +DEFINE_CLASS_PROPERTY_PREFIX(powerup, colormap, FFFI, Inventory) +{ + PalEntry * pBlendColor; + + if (info->Class->IsDescendantOf(RUNTIME_CLASS(APowerup))) + { + pBlendColor = &((APowerup*)defaults)->BlendColor; + } + else if (info->Class->IsDescendantOf(RUNTIME_CLASS(APowerupGiver))) + { + pBlendColor = &((APowerupGiver*)defaults)->BlendColor; + } + else + { + I_Error("\"powerup.colormap\" requires an actor of type \"Powerup\"\n"); + return; + } + + PROP_FLOAT_PARM(r, 0); + PROP_FLOAT_PARM(g, 1); + PROP_FLOAT_PARM(b, 2); + PROP_INT_PARM(inv, 3); + + + + *pBlendColor = MakeSpecialColormap(AddSpecialColormap(r, g, b, !!inv)); +} + //========================================================================== // //========================================================================== diff --git a/src/v_draw.cpp b/src/v_draw.cpp index 90fb4befff..05cd73c5c8 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -584,7 +584,7 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, int x, int y, DWORD tag, va_l break; case DTA_SpecialColormap: - parms->specialcolormap = va_arg (tags, FSpecialColormapParameters *); + parms->specialcolormap = va_arg (tags, FSpecialColormap *); break; case DTA_ColormapStyle: diff --git a/src/v_palette.cpp b/src/v_palette.cpp index d0d50efaa3..85570caa0f 100644 --- a/src/v_palette.cpp +++ b/src/v_palette.cpp @@ -61,10 +61,16 @@ extern "C" { FDynamicColormap NormalLight; } FPalette GPalette; -BYTE SpecialColormaps[NUM_SPECIALCOLORMAPS][256]; +TArray SpecialColormaps; BYTE DesaturateColormap[31][256]; -FSpecialColormapParameters SpecialColormapParms[NUM_SPECIALCOLORMAPS] = +struct FSpecialColormapParameters +{ + float Colorize[3]; + bool Inverted; +}; + +static FSpecialColormapParameters SpecialColormapParms[] = { // Doom invulnerability is an inverted grayscale. // Strife uses it when firing the Sigil @@ -355,10 +361,57 @@ static bool FixBuildPalette (BYTE *opal, int lump, bool blood) return true; } +int AddSpecialColormap(double r, double g, double b, bool inv) +{ + for(unsigned i=0; iColorize[0] = float(r); + cm->Colorize[1] = float(g); + cm->Colorize[2] = float(b); + cm->Inverted = inv; + + for (int c = 0; c < 256; c++) + { + double intensity = (GPalette.BaseColors[c].r * 77 + + GPalette.BaseColors[c].g * 143 + + GPalette.BaseColors[c].b * 37) / 256.0; + if (inv) + { + intensity = 255 - intensity; + } + + PalEntry pe = PalEntry( MIN(255, int(intensity*r)), + MIN(255, int(intensity*g)), + MIN(255, int(intensity*b))); + + cm->Colormap[c] = ColorMatcher.Pick(pe); + + // This table is used by the texture composition code + for(int i = 0;i < 256; i++) + { + intensity = inv? 255-i : i; + cm->GrayscaleToColor[i] = PalEntry( MIN(255, int(intensity*r)), + MIN(255, int(intensity*g)), + MIN(255, int(intensity*b))); + } + } + return SpecialColormaps.Size() - 1; +} + void InitPalette () { BYTE pal[768]; - BYTE *shade; int c; bool usingBuild = false; int lump; @@ -398,37 +451,18 @@ void InitPalette () NormalLight.Fade = 0; // NormalLight.Maps is set by R_InitColormaps() - // build special maps (e.g. invulnerability) - double intensity; + // build default special maps (e.g. invulnerability) + SpecialColormaps.Clear(); for (int i = 0; i < countof(SpecialColormapParms); ++i) { - double r, g, b; - bool inv; - - shade = SpecialColormaps[i]; - r = SpecialColormapParms[i].Colorize[0]; - g = SpecialColormapParms[i].Colorize[1]; - b = SpecialColormapParms[i].Colorize[2]; - inv = SpecialColormapParms[i].Inverted; - for (c = 0; c < 256; c++) - { - intensity = (GPalette.BaseColors[c].r * 77 + - GPalette.BaseColors[c].g * 143 + - GPalette.BaseColors[c].b * 37) / 256.0; - if (inv) - { - intensity = 255 - intensity; - } - shade[c] = ColorMatcher.Pick( - MIN(255, int(intensity*r)), MIN(255, int(intensity*g)), MIN(255, int(intensity*b))); - } + AddSpecialColormap(SpecialColormapParms[i].Colorize[0], SpecialColormapParms[i].Colorize[1], + SpecialColormapParms[i].Colorize[2], SpecialColormapParms[i].Inverted); } - // desaturated colormaps for(int m = 0; m < 31; m++) { - shade = DesaturateColormap[m]; + BYTE *shade = DesaturateColormap[m]; for (c = 0; c < 256; c++) { int intensity = (GPalette.BaseColors[c].r * 77 + diff --git a/src/v_palette.h b/src/v_palette.h index 160ef6ceac..a856de97d9 100644 --- a/src/v_palette.h +++ b/src/v_palette.h @@ -88,25 +88,43 @@ struct FColormapStyle float FadeLevel; }; -// Special colormaps, like invulnerability. enum { NOFIXEDCOLORMAP = -1, - INVERSECOLORMAP, - GOLDCOLORMAP, - REDCOLORMAP, // [BC] New Skulltag colormaps. - GREENCOLORMAP, - BLUECOLORMAP, - - NUM_SPECIALCOLORMAPS + INVERSECOLORMAP, // the inverse map is used explicitly in a few places. }; -struct FSpecialColormapParameters + + +struct FSpecialColormap { float Colorize[3]; bool Inverted; + BYTE Colormap[256]; + PalEntry GrayscaleToColor[256]; }; -extern FSpecialColormapParameters SpecialColormapParms[NUM_SPECIALCOLORMAPS]; -extern BYTE SpecialColormaps[NUM_SPECIALCOLORMAPS][256]; + +extern TArray SpecialColormaps; + +// some utility functions to store special colormaps in powerup blends +#define SPECIALCOLORMAP_MASK 0x00ff0000 + +inline int MakeSpecialColormap(int index) +{ + return index | SPECIALCOLORMAP_MASK; +} + +inline bool IsSpecialColormap(int map) +{ + return (map & SPECIALCOLORMAP_MASK) == SPECIALCOLORMAP_MASK; +} + +inline int GetSpecialColormap(int blend) +{ + return IsSpecialColormap(blend)? blend & ~SPECIALCOLORMAP_MASK : NOFIXEDCOLORMAP; +} + +int AddSpecialColormap(double r, double g, double b, bool inv); + extern BYTE DesaturateColormap[31][256]; diff --git a/src/v_video.h b/src/v_video.h index 3ce0e28498..a6f30a43af 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -227,7 +227,7 @@ public: INTBOOL masked; INTBOOL bilinear; FRenderStyle style; - struct FSpecialColormapParameters *specialcolormap; + struct FSpecialColormap *specialcolormap; struct FColormapStyle *colormapstyle; }; diff --git a/src/win32/fb_d3d9.cpp b/src/win32/fb_d3d9.cpp index a81c2ca7cf..519d690101 100644 --- a/src/win32/fb_d3d9.cpp +++ b/src/win32/fb_d3d9.cpp @@ -3089,6 +3089,7 @@ bool D3DFB::SetStyle(D3DTex *tex, DrawParms &parms, D3DCOLOR &color0, D3DCOLOR & stencilling = false; quad.Palette = NULL; + quad.Flags = 0; switch (style.BlendOp) { @@ -3124,7 +3125,7 @@ bool D3DFB::SetStyle(D3DTex *tex, DrawParms &parms, D3DCOLOR &color0, D3DCOLOR & quad.ShaderNum = BQS_SpecialColormap; color0 = D3DCOLOR_COLORVALUE(parms.specialcolormap->Colorize[0]/2, parms.specialcolormap->Colorize[1]/2, parms.specialcolormap->Colorize[2]/2, 1); - color1 = 0; + color1 = D3DCOLOR_ARGB(255,0,0,0); } else if (parms.colormapstyle != NULL) { // Emulate the fading from an in-game colormap (colorized, faded, and desaturated)