From 0773e6a98e8709868fcd64aa5eb659af97b67d0e Mon Sep 17 00:00:00 2001 From: Kevin Caccamo Date: Thu, 20 Dec 2018 19:03:52 -0500 Subject: [PATCH] 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 --- src/hwrenderer/scene/hw_flats.cpp | 4 +-- src/hwrenderer/scene/hw_sprites.cpp | 2 +- src/hwrenderer/scene/hw_walls.cpp | 2 +- src/hwrenderer/scene/hw_weapon.cpp | 9 +++-- src/p_saveg.cpp | 4 ++- src/p_setup.cpp | 2 +- src/p_udmf.cpp | 30 +++++++++++++++-- src/r_defs.h | 28 ++++++++++++++-- src/scripting/vmthunks.cpp | 52 +++++++++++++++++++++++++++++ wadsrc/static/zscript/mapdata.txt | 6 +++- 10 files changed, 123 insertions(+), 16 deletions(-) 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);