Rework implementation as per the new specification

The new specification is more flexible, and allows assigning additive 
colors to individual parts of a sector (walls, sprites, flats) and even 
individual parts of a side (top, middle, bottom)

Add AdditiveColors arrays to sector_t and side_t::part
Initialize AdditiveColors arrays to 0
Export AdditiveColors to ZScript
Save AdditiveColors in saved game files
Use colors from AdditiveColors arrays when setting the additive color 
for the render state
Add code to parse the new UDMF additive color properties
Remove additive color slot from sector color/part enum
Add SetAdditiveColor to sector_t and side_t
Add GetAdditiveColor to side_t
Export new methods and additive color arrays to ZScript
This commit is contained in:
Kevin Caccamo 2018-12-20 19:03:52 -05:00 committed by Christoph Oelckers
parent 60696c91a2
commit 0773e6a98e
10 changed files with 123 additions and 16 deletions

View file

@ -509,7 +509,7 @@ void GLFlat::ProcessSector(HWDrawInfo *di, sector_t * frontsector, int which)
lightlevel = hw_ClampLight(frontsector->GetFloorLight());
Colormap = frontsector->Colormap;
FlatColor = frontsector->SpecialColors[sector_t::floor];
AddColor = frontsector->SpecialColors[sector_t::add];
AddColor = frontsector->AdditiveColors[sector_t::floor];
port = frontsector->ValidatePortal(sector_t::floor);
if ((stack = (port != NULL)))
{
@ -565,7 +565,7 @@ void GLFlat::ProcessSector(HWDrawInfo *di, sector_t * frontsector, int which)
lightlevel = hw_ClampLight(frontsector->GetCeilingLight());
Colormap = frontsector->Colormap;
FlatColor = frontsector->SpecialColors[sector_t::ceiling];
AddColor = frontsector->SpecialColors[sector_t::add];
AddColor = frontsector->AdditiveColors[sector_t::ceiling];
port = frontsector->ValidatePortal(sector_t::ceiling);
if ((stack = (port != NULL)))
{

View file

@ -159,7 +159,7 @@ void GLSprite::DrawSprite(HWDrawInfo *di, FRenderState &state, bool translucent)
: ThingColor.Modulate(cursec->SpecialColors[sector_t::sprites]);
state.SetObjectColor(finalcol);
state.SetAddColor(cursec->SpecialColors[sector_t::add] | 0xff000000);
state.SetAddColor(cursec->AdditiveColors[sector_t::sprites] | 0xff000000);
}
state.SetColor(lightlevel, rel, di->isFullbrightScene(), Colormap, trans);
}

View file

@ -174,7 +174,7 @@ void GLWall::RenderTexturedWall(HWDrawInfo *di, FRenderState &state, int rflags)
PalEntry color2 = side->GetSpecialColor(tierndx, side_t::wallbottom, frontsector);
state.SetObjectColor(color1);
state.SetObjectColor2(color2);
state.SetAddColor(seg->frontsector->SpecialColors[sector_t::add] | 0xff000000);
state.SetAddColor(side->GetAdditiveColor(tierndx, frontsector));
if (color1 != color2)
{
// Do gradient setup only if there actually is a gradient.

View file

@ -72,9 +72,12 @@ void HWDrawInfo::DrawPSprite(HUDSprite *huds, FRenderState &state)
state.SetRenderStyle(huds->RenderStyle);
state.SetTextureMode(huds->RenderStyle);
state.SetObjectColor(huds->ObjectColor);
if (huds->owner->Sector) {
state.SetAddColor(huds->owner->Sector->SpecialColors[sector_t::add] | 0xff000000);
} else {
if (huds->owner->Sector)
{
state.SetAddColor(huds->owner->Sector->AdditiveColors[sector_t::sprites] | 0xff000000);
}
else
{
state.SetAddColor(0);
}
state.SetDynLight(huds->dynrgb[0], huds->dynrgb[1], huds->dynrgb[2]);

View file

@ -108,6 +108,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, side_t::part &part, si
("flags", part.flags, def->flags)
("color1", part.SpecialColors[0], def->SpecialColors[0])
("color2", part.SpecialColors[1], def->SpecialColors[1])
("addcolor", part.AdditiveColor, def->AdditiveColor)
.EndObject();
}
return arc;
@ -293,7 +294,8 @@ FSerializer &Serialize(FSerializer &arc, const char *key, sector_t &p, sector_t
("linked_floor", p.e->Linked.Floor.Sectors)
("linked_ceiling", p.e->Linked.Ceiling.Sectors)
("colormap", p.Colormap, def->Colormap)
.Array("specialcolors", p.SpecialColors, def->SpecialColors, 6, true)
.Array("specialcolors", p.SpecialColors, def->SpecialColors, 5, true)
.Array("additivecolors", p.AdditiveColors, def->AdditiveColors, 5, true)
("gravity", p.gravity, def->gravity)
.Terrain("floorterrain", p.terrainnum[0], &def->terrainnum[0])
.Terrain("ceilingterrain", p.terrainnum[1], &def->terrainnum[1])

View file

@ -1096,7 +1096,7 @@ void P_LoadSectors (MapData *map, FMissingTextureTracker &missingtex)
ss->nextsec = -1; //jff 2/26/98 add fields to support locking out
ss->prevsec = -1; // stair retriggering until build completes
memset(ss->SpecialColors, -1, sizeof(ss->SpecialColors));
ss->SpecialColors[sector_t::add] = 0;
memset(ss->AdditiveColors, 0, sizeof(ss->AdditiveColors));
ss->SetAlpha(sector_t::floor, 1.);
ss->SetAlpha(sector_t::ceiling, 1.);

View file

@ -1388,6 +1388,18 @@ public:
sd->SetSpecialColor(side_t::bottom, 1, CheckInt(key));
break;
case NAME_coloradd_top:
sd->SetAdditiveColor(side_t::top, CheckInt(key));
break;
case NAME_coloradd_mid:
sd->SetAdditiveColor(side_t::mid, CheckInt(key));
break;
case NAME_coloradd_bottom:
sd->SetAdditiveColor(side_t::bottom, CheckInt(key));
break;
default:
break;
@ -1453,7 +1465,7 @@ public:
sec->terrainnum[sector_t::ceiling] = sec->terrainnum[sector_t::floor] = -1;
sec->ibocount = -1;
memset(sec->SpecialColors, -1, sizeof(sec->SpecialColors));
sec->SpecialColors[sector_t::add] = 0;
memset(sec->AdditiveColors, 0, sizeof(sec->AdditiveColors));
if (floordrop) sec->Flags = SECF_FLOORDROP;
// killough 3/7/98: end changes
@ -1626,8 +1638,20 @@ public:
sec->SpecialColors[sector_t::sprites] = CheckInt(key) | 0xff000000;
break;
case NAME_Color_Add:
sec->SpecialColors[sector_t::add] = CheckInt(key) | 0xff000000;
case NAME_ColorAdd_Floor:
sec->AdditiveColors[sector_t::floor] = CheckInt(key) | 0xff000000; // Alpha is used to decide whether or not to use the color
break;
case NAME_ColorAdd_Ceiling:
sec->AdditiveColors[sector_t::ceiling] = CheckInt(key) | 0xff000000;
break;
case NAME_ColorAdd_Walls:
sec->AdditiveColors[sector_t::walltop] = CheckInt(key) | 0xff000000;
break;
case NAME_ColorAdd_Sprites:
sec->AdditiveColors[sector_t::sprites] = CheckInt(key) | 0xff000000;
break;
case NAME_Desaturation:

View file

@ -660,8 +660,8 @@ public:
// only used for specialcolors array
walltop,
wallbottom,
sprites,
add
sprites
};
struct splane
@ -914,6 +914,12 @@ public:
SpecialColors[slot] = rgb;
}
void SetAdditiveColor(int slot, PalEntry rgb)
{
rgb.a = 255;
AdditiveColors[slot] = rgb;
}
inline bool PortalBlocksView(int plane);
inline bool PortalBlocksSight(int plane);
inline bool PortalBlocksMovement(int plane);
@ -974,7 +980,8 @@ public:
secplane_t floorplane, ceilingplane;
// [RH] give floor and ceiling even more properties
PalEntry SpecialColors[6];
PalEntry SpecialColors[5];
PalEntry AdditiveColors[5];
FColormap Colormap;
TObjPtr<AActor*> SoundTarget;
@ -1153,6 +1160,7 @@ struct side_t
FTextureID texture;
int flags;
PalEntry SpecialColors[2];
PalEntry AdditiveColor;
void InitFrom(const part &other)
{
@ -1296,6 +1304,20 @@ struct side_t
return (part.flags & part::UseOwnColors) ? part.SpecialColors[slot] : frontsector->SpecialColors[sector_t::walltop + slot];
}
void SetAdditiveColor(int which, PalEntry rgb)
{
rgb.a = 255;
textures[which].AdditiveColor = rgb;
}
PalEntry GetAdditiveColor(int which, sector_t *frontsector) const
{
auto &color = textures[which].AdditiveColor;
if (color.a == 0) {
return frontsector->AdditiveColors[sector_t::walltop]; // Used as additive color for all walls
}
return color;
}
DInterpolation *SetInterpolation(int position);
void StopInterpolation(int position);

View file

@ -542,6 +542,23 @@ DEFINE_ACTION_FUNCTION_NATIVE(_Sector, SetSpecialColor, SetSpecialColor)
return 0;
}
static void SetAdditiveColor(sector_t *self, int pos, int color)
{
if (pos >= 0 && pos < 5)
{
self->SetAdditiveColor(pos, color);
}
}
DEFINE_ACTION_FUNCTION_NATIVE(_Sector, SetAdditiveColor, SetAdditiveColor)
{
PARAM_SELF_STRUCT_PROLOGUE(sector_t);
PARAM_INT(pos);
PARAM_COLOR(color);
SetSpecialColor(self, pos, color);
return 0;
}
static void SetFogDensity(sector_t *self, int dens)
{
self->Colormap.FogDensity = dens;
@ -1524,6 +1541,40 @@ DEFINE_ACTION_FUNCTION_NATIVE(_Sector, RemoveForceField, RemoveForceField)
return 0;
}
static int GetSideAdditiveColor(side_t *self, int tier)
{
if (tier >= 0 && tier < 3)
{
return self->GetAdditiveColor(tier, self->sector);
}
return 0;
}
DEFINE_ACTION_FUNCTION_NATIVE(_Side, GetAdditiveColor, GetSideAdditiveColor)
{
PARAM_SELF_STRUCT_PROLOGUE(side_t);
PARAM_INT(tier);
ACTION_RETURN_INT(GetSideAdditiveColor(self, tier));
return 0;
}
static void SetSideAdditiveColor(side_t *self, int tier, int color)
{
if (tier >= 0 && tier < 3)
{
self->SetAdditiveColor(tier, color);
}
}
DEFINE_ACTION_FUNCTION_NATIVE(_Side, SetAdditiveColor, SetSideAdditiveColor)
{
PARAM_SELF_STRUCT_PROLOGUE(side_t);
PARAM_INT(tier);
PARAM_COLOR(color);
SetSideAdditiveColor(self, tier, color);
return 0;
}
static int SideIndex(side_t *self)
{
unsigned ndx = self->Index();
@ -2701,6 +2752,7 @@ DEFINE_FIELD_X(Sector, sector_t, floorplane)
DEFINE_FIELD_X(Sector, sector_t, ceilingplane)
DEFINE_FIELD_X(Sector, sector_t, Colormap)
DEFINE_FIELD_X(Sector, sector_t, SpecialColors)
DEFINE_FIELD_X(Sector, sector_t, AdditiveColors)
DEFINE_FIELD_X(Sector, sector_t, SoundTarget)
DEFINE_FIELD_X(Sector, sector_t, special)
DEFINE_FIELD_X(Sector, sector_t, lightlevel)

View file

@ -86,6 +86,8 @@ struct Side native play
native double GetTextureYScale(int which);
native void MultiplyTextureYScale(int which, double delta);
native void SetSpecialColor(int tier, int position, Color scolor);
native Color GetAdditiveColor(int tier);
native void SetAdditiveColor(int tier, Color color);
//native DInterpolation *SetInterpolation(int position);
//native void StopInterpolation(int position);
@ -235,7 +237,8 @@ struct Sector native play
{
native readonly FColormap ColorMap;
native readonly Color SpecialColors[6];
native readonly Color SpecialColors[5];
native readonly Color AdditiveColors[5];
native Actor SoundTarget;
@ -409,6 +412,7 @@ struct Sector native play
native void SetGlowHeight(int pos, double height);
native void SetGlowColor(int pos, color color);
native void SetSpecialColor(int pos, color color);
native void SetAdditiveColor(int pos, Color color);
native TextureID GetTexture(int pos);
native void SetTexture(int pos, TextureID tex, bool floorclip = true);