mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-10 14:51:40 +00:00
- 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:
parent
d51c0c047d
commit
c285f38a02
17 changed files with 224 additions and 231 deletions
|
@ -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
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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];
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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));
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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 +
|
||||||
|
|
|
@ -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];
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in a new issue