diff --git a/src/hwrenderer/scene/hw_flats.cpp b/src/hwrenderer/scene/hw_flats.cpp index b609847fd..71e90a80f 100644 --- a/src/hwrenderer/scene/hw_flats.cpp +++ b/src/hwrenderer/scene/hw_flats.cpp @@ -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))) { diff --git a/src/hwrenderer/scene/hw_sprites.cpp b/src/hwrenderer/scene/hw_sprites.cpp index 42286aab7..e56a77dab 100644 --- a/src/hwrenderer/scene/hw_sprites.cpp +++ b/src/hwrenderer/scene/hw_sprites.cpp @@ -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); } diff --git a/src/hwrenderer/scene/hw_walls.cpp b/src/hwrenderer/scene/hw_walls.cpp index e71f94ad3..66275f963 100644 --- a/src/hwrenderer/scene/hw_walls.cpp +++ b/src/hwrenderer/scene/hw_walls.cpp @@ -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. diff --git a/src/hwrenderer/scene/hw_weapon.cpp b/src/hwrenderer/scene/hw_weapon.cpp index 4c585a74d..e242ed7b6 100644 --- a/src/hwrenderer/scene/hw_weapon.cpp +++ b/src/hwrenderer/scene/hw_weapon.cpp @@ -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]); diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index 2d83a1545..663b6b328 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -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]) diff --git a/src/p_setup.cpp b/src/p_setup.cpp index f25a2050e..0cb8894da 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -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.); diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index 2c1bd13e0..e2d3ebdff 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -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: diff --git a/src/r_defs.h b/src/r_defs.h index c445c1800..d152bf0e8 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -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 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); diff --git a/src/scripting/vmthunks.cpp b/src/scripting/vmthunks.cpp index c7cadf8e2..efee33215 100644 --- a/src/scripting/vmthunks.cpp +++ b/src/scripting/vmthunks.cpp @@ -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) diff --git a/wadsrc/static/zscript/mapdata.txt b/wadsrc/static/zscript/mapdata.txt index 5ae796b04..a63c95f0e 100644 --- a/wadsrc/static/zscript/mapdata.txt +++ b/wadsrc/static/zscript/mapdata.txt @@ -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);