- 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)
This commit is contained in:
Christoph Oelckers 2009-09-21 13:15:36 +00:00
parent d51c0c047d
commit c285f38a02
17 changed files with 224 additions and 231 deletions

View file

@ -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) September 20, 2009 (Changes by Graf Zahl)
- Changed call to R_DrawRemainingPlayerSprites into a virtual function - Changed call to R_DrawRemainingPlayerSprites into a virtual function
of DFrameBuffer because its implementation is specific to the software of DFrameBuffer because its implementation is specific to the software

View file

@ -43,6 +43,11 @@ public:
void SetPalette (const DWORD *palette); void SetPalette (const DWORD *palette);
BYTE Pick (int r, int g, int b); 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); FColorMatcher &operator= (const FColorMatcher &other);
private: private:

View file

@ -139,14 +139,7 @@ PalEntry APowerup::GetBlend ()
if (EffectTics <= BLINKTHRESHOLD && !(EffectTics & 8)) if (EffectTics <= BLINKTHRESHOLD && !(EffectTics & 8))
return 0; return 0;
if (BlendColor == INVERSECOLOR || if (IsSpecialColormap(BlendColor)) return 0;
BlendColor == GOLDCOLOR ||
// [BC] HAX!
BlendColor == REDCOLOR ||
BlendColor == GREENCOLOR ||
BlendColor == BLUECOLOR)
return 0;
return BlendColor; return BlendColor;
} }
@ -175,40 +168,22 @@ void APowerup::DoEffect ()
if (EffectTics > 0) if (EffectTics > 0)
{ {
int oldcolormap = Owner->player->fixedcolormap; int Colormap = GetSpecialColormap(BlendColor);
if (Colormap != NOFIXEDCOLORMAP)
{
if (EffectTics > BLINKTHRESHOLD || (EffectTics & 8)) if (EffectTics > BLINKTHRESHOLD || (EffectTics & 8))
{ {
if (BlendColor == INVERSECOLOR) Owner->player->fixedcolormap = Colormap;
{
Owner->player->fixedcolormap = INVERSECOLORMAP;
} }
else if (BlendColor == GOLDCOLOR) else if (Owner->player->fixedcolormap == Colormap)
{
Owner->player->fixedcolormap = GOLDCOLORMAP;
}
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))
{ {
// only unset if the fixed colormap comes from this item
Owner->player->fixedcolormap = NOFIXEDCOLORMAP; Owner->player->fixedcolormap = NOFIXEDCOLORMAP;
} }
} }
} }
}
//=========================================================================== //===========================================================================
// //
@ -711,7 +686,7 @@ int APowerInvisibility::AlterWeaponSprite (vissprite_t *vis)
if ((vis->alpha < TRANSLUC25 && special1 > 0) || (vis->alpha == 0)) if ((vis->alpha < TRANSLUC25 && special1 > 0) || (vis->alpha == 0))
{ {
vis->alpha = clamp<fixed_t>((OPAQUE - Strength), 0, OPAQUE); vis->alpha = clamp<fixed_t>((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 return -1; // This item is valid so another one shouldn't reset the translucency
} }

View file

@ -3,14 +3,6 @@
#include "a_pickups.h" #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; class player_t;
// A powerup is a pseudo-inventory item that applies an effect to its // A powerup is a pseudo-inventory item that applies an effect to its

View file

@ -2532,7 +2532,10 @@ FUNC(LS_SetPlayerProperty)
if (power != 4) if (power != 4)
{ {
APowerup *item = static_cast<APowerup*>(it->GiveInventoryType (powers[power])); APowerup *item = static_cast<APowerup*>(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) else if (it->player - players == consoleplayer)
{ {
@ -2568,7 +2571,11 @@ FUNC(LS_SetPlayerProperty)
{ // Give power { // Give power
if (power != 4) if (power != 4)
{ {
players[i].mo->GiveInventoryType (powers[power]); APowerup *item = static_cast<APowerup*>(players[i].mo->GiveInventoryType (powers[power]));
if (item != NULL && power == 0 && arg1 == 1)
{
item->BlendColor = MakeSpecialColormap(INVERSECOLORMAP);
}
} }
else if (i == consoleplayer) else if (i == consoleplayer)
{ {

View file

@ -1163,9 +1163,9 @@ void R_SetupFrame (AActor *actor)
if (player != NULL && camera == player->mo) 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) else if (player->fixedlightlevel >= 0 && player->fixedlightlevel < NUMCOLORMAPS)
{ {
@ -1175,7 +1175,7 @@ void R_SetupFrame (AActor *actor)
// [RH] Inverse light for shooting the Sigil // [RH] Inverse light for shooting the Sigil
if (fixedcolormap == NULL && extralight == INT_MIN) if (fixedcolormap == NULL && extralight == INT_MIN)
{ {
fixedcolormap = SpecialColormaps[INVERSECOLORMAP]; fixedcolormap = SpecialColormaps[INVERSECOLORMAP].Colormap;
extralight = 0; extralight = 0;
} }

View file

@ -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? // The colormap has changed. Is it one we can easily identify?
// If not, then don't bother trying to identify it for // If not, then don't bother trying to identify it for
// hardware accelerated drawing. // 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; noaccel = true;
} }
@ -1812,19 +1813,21 @@ void R_DrawRemainingPlayerSprites()
{ {
FDynamicColormap *colormap = VisPSpritesBaseColormap[i]; FDynamicColormap *colormap = VisPSpritesBaseColormap[i];
bool flip = vis->xiscale < 0; bool flip = vis->xiscale < 0;
FSpecialColormapParameters *special = NULL; FSpecialColormap *special = NULL;
PalEntry overlay = 0; PalEntry overlay = 0;
FColormapStyle colormapstyle; FColormapStyle colormapstyle;
bool usecolormapstyle = false; 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; // Yuck! There needs to be a better way to store colormaps in the vissprite... :(
if (SpecialColormapParms[specialmap].Inverted) ptrdiff_t specialmap = (vis->colormap - SpecialColormaps[0].Colormap) / sizeof(FSpecialColormap);
if (SpecialColormaps[specialmap].Inverted)
{ {
vis->RenderStyle.Flags ^= STYLEF_InvertSource; vis->RenderStyle.Flags ^= STYLEF_InvertSource;
} }
special = &SpecialColormapParms[specialmap]; special = &SpecialColormaps[specialmap];
} }
else if (colormap->Color == PalEntry(255,255,255) && else if (colormap->Color == PalEntry(255,255,255) &&
colormap->Desaturate == 0) colormap->Desaturate == 0)

View file

@ -120,12 +120,12 @@ public:
} }
} }
// Return a reference to an element // Return a reference to an element
T &operator[] (unsigned int index) const T &operator[] (size_t index) const
{ {
return Array[index]; return Array[index];
} }
// Returns the value of an element // Returns the value of an element
TT operator() (unsigned int index) const TT operator() (size_t index) const
{ {
return Array[index]; return Array[index];
} }

View file

@ -35,6 +35,7 @@
#include "bitmap.h" #include "bitmap.h"
#include "templates.h" #include "templates.h"
#include "r_translate.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; break;
case BLEND_INVERSEMAP:
// Doom's inverted invulnerability map
for(i=0;i<count;i++)
{
a = TSrc::A(pin);
if (TBlend::ProcessAlpha0() || a)
{
gray = clamp<int>(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<count;i++)
{
a = TSrc::A(pin);
if (TBlend::ProcessAlpha0() || a)
{
gray = TSrc::Gray(pin);
r=clamp<int>(gray+(gray>>1),0,255);
g=clamp<int>(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<count;i++)
{
a = TSrc::A(pin);
if (TBlend::ProcessAlpha0() || a)
{
gray = TSrc::Gray(pin);
r=clamp<int>(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<count;i++)
{
a = TSrc::A(pin);
if (TBlend::ProcessAlpha0() || a)
{
gray = TSrc::Gray(pin);
r=clamp<int>(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: case BLEND_ICEMAP:
// Create the ice translation table, based on Hexen's. // 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! // 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; break;
default: 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<count;i++)
{
a = TSrc::A(pin);
if (TBlend::ProcessAlpha0() || a)
{
gray = clamp<int>(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. // Desaturated light settings.
fac=inf->blend-BLEND_DESATURATE1+1; fac=inf->blend-BLEND_DESATURATE1+1;

View file

@ -262,13 +262,10 @@ enum ColorType
enum EBlend enum EBlend
{ {
BLEND_NONE = 0, BLEND_NONE = 0,
BLEND_INVERSEMAP = 1, BLEND_ICEMAP = 1,
BLEND_GOLDMAP = 2, BLEND_DESATURATE1 = 2,
BLEND_REDMAP = 3, BLEND_DESATURATE31 = 32,
BLEND_GREENMAP = 4, BLEND_SPECIALCOLORMAP1 = 33,
BLEND_ICEMAP = 5,
BLEND_DESATURATE1 = 6,
BLEND_DESATURATE31 = 36,
BLEND_MODULATE = -1, BLEND_MODULATE = -1,
BLEND_OVERLAY = -2, BLEND_OVERLAY = -2,
}; };

View file

@ -425,23 +425,15 @@ BYTE *GetBlendMap(PalEntry blend, BYTE *blendwork)
switch (blend.a==0 ? blend.r : -1) 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: case BLEND_ICEMAP:
return TranslationToTable(TRANSLATION(TRANSLATION_Standard, 7))->Remap; return TranslationToTable(TRANSLATION(TRANSLATION_Standard, 7))->Remap;
default: 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]; return DesaturateColormap[blend.r - BLEND_DESATURATE1];
} }
@ -1044,22 +1036,29 @@ void FMultiPatchTexture::ParsePatch(FScanner &sc, TexPart & part)
} }
else if (sc.Compare("Translation")) else if (sc.Compare("Translation"))
{ {
int match;
bComplex = true; bComplex = true;
if (part.Translation != NULL) delete part.Translation; if (part.Translation != NULL) delete part.Translation;
part.Translation = NULL; part.Translation = NULL;
part.Blend = 0; 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(); sc.MustGetString();
int match = sc.MatchString(maps);
match = sc.MatchString(maps);
if (match >= 0) if (match >= 0)
{ {
part.Blend.r = 1 + match; part.Blend.r = BLEND_SPECIALCOLORMAP1 + match;
if (part.Blend.r == BLEND_DESATURATE1) }
else if (sc.Compare("ICE"))
{
part.Blend.r = BLEND_ICEMAP;
}
else if (sc.Compare("DESATURATE"))
{ {
sc.MustGetStringName(","); sc.MustGetStringName(",");
sc.MustGetNumber(); sc.MustGetNumber();
part.Blend.r += clamp(sc.Number-1, 0, 30); part.Blend.r = BLEND_DESATURATE1 + clamp(sc.Number-1, 0, 30);
}
} }
else else
{ {

View file

@ -1556,7 +1556,8 @@ DEFINE_CLASS_PROPERTY(weapon, S, WeaponPiece)
//========================================================================== //==========================================================================
DEFINE_CLASS_PROPERTY_PREFIX(powerup, color, C_f, Inventory) 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; int alpha;
PalEntry * pBlendColor; PalEntry * pBlendColor;
@ -1582,30 +1583,11 @@ DEFINE_CLASS_PROPERTY_PREFIX(powerup, color, C_f, Inventory)
{ {
PROP_STRING_PARM(name, 1); 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; *pBlendColor = MakeSpecialColormap(v);
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;
return; return;
} }
@ -1623,6 +1605,37 @@ DEFINE_CLASS_PROPERTY_PREFIX(powerup, color, C_f, Inventory)
else *pBlendColor = 0; 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));
}
//========================================================================== //==========================================================================
// //
//========================================================================== //==========================================================================

View file

@ -584,7 +584,7 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, int x, int y, DWORD tag, va_l
break; break;
case DTA_SpecialColormap: case DTA_SpecialColormap:
parms->specialcolormap = va_arg (tags, FSpecialColormapParameters *); parms->specialcolormap = va_arg (tags, FSpecialColormap *);
break; break;
case DTA_ColormapStyle: case DTA_ColormapStyle:

View file

@ -61,10 +61,16 @@ extern "C" {
FDynamicColormap NormalLight; FDynamicColormap NormalLight;
} }
FPalette GPalette; FPalette GPalette;
BYTE SpecialColormaps[NUM_SPECIALCOLORMAPS][256]; TArray<FSpecialColormap> SpecialColormaps;
BYTE DesaturateColormap[31][256]; BYTE DesaturateColormap[31][256];
FSpecialColormapParameters SpecialColormapParms[NUM_SPECIALCOLORMAPS] = struct FSpecialColormapParameters
{
float Colorize[3];
bool Inverted;
};
static FSpecialColormapParameters SpecialColormapParms[] =
{ {
// Doom invulnerability is an inverted grayscale. // Doom invulnerability is an inverted grayscale.
// Strife uses it when firing the Sigil // Strife uses it when firing the Sigil
@ -355,10 +361,57 @@ static bool FixBuildPalette (BYTE *opal, int lump, bool blood)
return true; return true;
} }
int AddSpecialColormap(double r, double g, double b, bool inv)
{
for(unsigned i=0; i<SpecialColormaps.Size(); i++)
{
if (SpecialColormaps[i].Colorize[0] == r &&
SpecialColormaps[i].Colorize[1] == g &&
SpecialColormaps[i].Colorize[2] == b &&
SpecialColormaps[i].Inverted == inv)
{
return i; // The map already exists
}
}
FSpecialColormap *cm = &SpecialColormaps[SpecialColormaps.Reserve(1)];
cm->Colorize[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 () void InitPalette ()
{ {
BYTE pal[768]; BYTE pal[768];
BYTE *shade;
int c; int c;
bool usingBuild = false; bool usingBuild = false;
int lump; int lump;
@ -398,37 +451,18 @@ void InitPalette ()
NormalLight.Fade = 0; NormalLight.Fade = 0;
// NormalLight.Maps is set by R_InitColormaps() // NormalLight.Maps is set by R_InitColormaps()
// build special maps (e.g. invulnerability) // build default special maps (e.g. invulnerability)
double intensity; SpecialColormaps.Clear();
for (int i = 0; i < countof(SpecialColormapParms); ++i) for (int i = 0; i < countof(SpecialColormapParms); ++i)
{ {
double r, g, b; AddSpecialColormap(SpecialColormapParms[i].Colorize[0], SpecialColormapParms[i].Colorize[1],
bool inv; SpecialColormapParms[i].Colorize[2], SpecialColormapParms[i].Inverted);
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)));
}
}
// desaturated colormaps // desaturated colormaps
for(int m = 0; m < 31; m++) for(int m = 0; m < 31; m++)
{ {
shade = DesaturateColormap[m]; BYTE *shade = DesaturateColormap[m];
for (c = 0; c < 256; c++) for (c = 0; c < 256; c++)
{ {
int intensity = (GPalette.BaseColors[c].r * 77 + int intensity = (GPalette.BaseColors[c].r * 77 +

View file

@ -88,25 +88,43 @@ struct FColormapStyle
float FadeLevel; float FadeLevel;
}; };
// Special colormaps, like invulnerability.
enum enum
{ {
NOFIXEDCOLORMAP = -1, NOFIXEDCOLORMAP = -1,
INVERSECOLORMAP, INVERSECOLORMAP, // the inverse map is used explicitly in a few places.
GOLDCOLORMAP,
REDCOLORMAP, // [BC] New Skulltag colormaps.
GREENCOLORMAP,
BLUECOLORMAP,
NUM_SPECIALCOLORMAPS
}; };
struct FSpecialColormapParameters
struct FSpecialColormap
{ {
float Colorize[3]; float Colorize[3];
bool Inverted; bool Inverted;
BYTE Colormap[256];
PalEntry GrayscaleToColor[256];
}; };
extern FSpecialColormapParameters SpecialColormapParms[NUM_SPECIALCOLORMAPS];
extern BYTE SpecialColormaps[NUM_SPECIALCOLORMAPS][256]; extern TArray<FSpecialColormap> 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]; extern BYTE DesaturateColormap[31][256];

View file

@ -227,7 +227,7 @@ public:
INTBOOL masked; INTBOOL masked;
INTBOOL bilinear; INTBOOL bilinear;
FRenderStyle style; FRenderStyle style;
struct FSpecialColormapParameters *specialcolormap; struct FSpecialColormap *specialcolormap;
struct FColormapStyle *colormapstyle; struct FColormapStyle *colormapstyle;
}; };

View file

@ -3089,6 +3089,7 @@ bool D3DFB::SetStyle(D3DTex *tex, DrawParms &parms, D3DCOLOR &color0, D3DCOLOR &
stencilling = false; stencilling = false;
quad.Palette = NULL; quad.Palette = NULL;
quad.Flags = 0;
switch (style.BlendOp) switch (style.BlendOp)
{ {
@ -3124,7 +3125,7 @@ bool D3DFB::SetStyle(D3DTex *tex, DrawParms &parms, D3DCOLOR &color0, D3DCOLOR &
quad.ShaderNum = BQS_SpecialColormap; quad.ShaderNum = BQS_SpecialColormap;
color0 = D3DCOLOR_COLORVALUE(parms.specialcolormap->Colorize[0]/2, color0 = D3DCOLOR_COLORVALUE(parms.specialcolormap->Colorize[0]/2,
parms.specialcolormap->Colorize[1]/2, parms.specialcolormap->Colorize[2]/2, 1); 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) else if (parms.colormapstyle != NULL)
{ // Emulate the fading from an in-game colormap (colorized, faded, and desaturated) { // Emulate the fading from an in-game colormap (colorized, faded, and desaturated)