- health groups and software rendering textures freed of 'level'

Edited cherry-pick of an older commit.
This commit is contained in:
Christoph Oelckers 2019-01-29 16:06:17 +01:00
parent eb5a39960e
commit 14101fa447
16 changed files with 79 additions and 64 deletions

View file

@ -34,6 +34,7 @@ struct event_t;
class AActor;
struct FLevelLocals;
//
// GAME

View file

@ -3285,7 +3285,7 @@ void MapLoader::LoadLevel(MapData *map, const char *lumpname, int position)
SWRenderer->SetColormap(Level); //The SW renderer needs to do some special setup for the level's default colormap.
InitPortalGroups(Level);
P_InitHealthGroups();
P_InitHealthGroups(Level);
if (reloop) LoopSidedefs(false);
PO_Init(); // Initialize the polyobjs

View file

@ -6633,17 +6633,17 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
FHealthGroup* grp;
if (part == SECPART_Ceiling)
{
return (ss->healthceilinggroup && (grp = P_GetHealthGroup(ss->healthceilinggroup)))
return (ss->healthceilinggroup && (grp = P_GetHealthGroup(Level, ss->healthceilinggroup)))
? grp->health : ss->healthceiling;
}
else if (part == SECPART_Floor)
{
return (ss->healthfloorgroup && (grp = P_GetHealthGroup(ss->healthfloorgroup)))
return (ss->healthfloorgroup && (grp = P_GetHealthGroup(Level, ss->healthfloorgroup)))
? grp->health : ss->healthfloor;
}
else if (part == SECPART_3D)
{
return (ss->health3dgroup && (grp = P_GetHealthGroup(ss->health3dgroup)))
return (ss->health3dgroup && (grp = P_GetHealthGroup(Level, ss->health3dgroup)))
? grp->health : ss->health3d;
}
return 0;
@ -6658,7 +6658,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
line_t* ll = &Level->lines[l];
if (ll->healthgroup > 0)
{
FHealthGroup* grp = P_GetHealthGroup(ll->healthgroup);
FHealthGroup* grp = P_GetHealthGroup(Level, ll->healthgroup);
if (grp) return grp->health;
}

View file

@ -75,9 +75,9 @@ void P_SetHealthGroupHealth(FHealthGroup* grp, int health)
}
}
void P_SetHealthGroupHealth(int id, int health)
void P_SetHealthGroupHealth(FLevelLocals *Level, int id, int health)
{
P_SetHealthGroupHealth(P_GetHealthGroup(id), health);
P_SetHealthGroupHealth(P_GetHealthGroup(Level, id), health);
}
void P_DamageHealthGroup(FHealthGroup* grp, void* object, AActor* source, int damage, FName damagetype, int side, int part, DVector3 position, bool isradius)
@ -133,6 +133,7 @@ void P_DamageLinedef(line_t* line, AActor* source, int damage, FName damagetype,
line->health -= damage;
if (line->health < 0) line->health = 0;
auto Level = line->GetLevel();
// callbacks here
// first off, call special if needed
@ -145,7 +146,7 @@ void P_DamageLinedef(line_t* line, AActor* source, int damage, FName damagetype,
if (dogroups && line->healthgroup)
{
FHealthGroup* grp = P_GetHealthGroup(line->healthgroup);
FHealthGroup* grp = P_GetHealthGroup(Level, line->healthgroup);
if (grp)
grp->health = line->health;
P_DamageHealthGroup(grp, line, source, damage, damagetype, side, -1, position, isradius);
@ -166,6 +167,7 @@ void P_DamageSector(sector_t* sector, AActor* source, int damage, FName damagety
if (!damage) return;
auto Level = sector->Level;
int* sectorhealth;
int group;
int dmg;
@ -209,7 +211,7 @@ void P_DamageSector(sector_t* sector, AActor* source, int damage, FName damagety
if (dogroups && group)
{
FHealthGroup* grp = P_GetHealthGroup(group);
FHealthGroup* grp = P_GetHealthGroup(Level, group);
if (grp)
grp->health = newhealth;
P_DamageHealthGroup(grp, sector, source, damage, damagetype, 0, part, position, isradius);
@ -225,35 +227,36 @@ void P_DamageSector(sector_t* sector, AActor* source, int damage, FName damagety
//
//===========================================================================
FHealthGroup* P_GetHealthGroup(int id)
FHealthGroup* P_GetHealthGroup(FLevelLocals *Level, int id)
{
FHealthGroup* grp = level.healthGroups.CheckKey(id);
FHealthGroup* grp = Level->healthGroups.CheckKey(id);
return grp;
}
FHealthGroup* P_GetHealthGroupOrNew(int id, int health)
FHealthGroup* P_GetHealthGroupOrNew(FLevelLocals *Level, int id, int health)
{
FHealthGroup* grp = level.healthGroups.CheckKey(id);
FHealthGroup* grp = Level->healthGroups.CheckKey(id);
if (!grp)
{
FHealthGroup newgrp;
newgrp.id = id;
newgrp.health = health;
grp = &(level.healthGroups.Insert(id, newgrp));
grp = &(Level->healthGroups.Insert(id, newgrp));
}
return grp;
}
void P_InitHealthGroups()
void P_InitHealthGroups(FLevelLocals *Level)
{
level.healthGroups.Clear();
Level->healthGroups.Clear();
TArray<int> groupsInError;
for (unsigned i = 0; i < level.lines.Size(); i++)
for (unsigned i = 0; i < Level->lines.Size(); i++)
{
line_t* lline = &level.lines[i];
line_t* lline = &Level->lines[i];
if (lline->healthgroup > 0)
{
FHealthGroup* grp = P_GetHealthGroupOrNew(lline->healthgroup, lline->health);
FHealthGroup* grp = P_GetHealthGroupOrNew(Level, lline->healthgroup, lline->health);
if (grp->health != lline->health)
{
Printf(TEXTCOLOR_RED "Warning: line %d in health group %d has different starting health (line health = %d, group health = %d)\n", i, lline->healthgroup, lline->health, grp->health);
@ -264,12 +267,12 @@ void P_InitHealthGroups()
grp->lines.Push(lline);
}
}
for (unsigned i = 0; i < level.sectors.Size(); i++)
for (unsigned i = 0; i < Level->sectors.Size(); i++)
{
sector_t* lsector = &level.sectors[i];
sector_t* lsector = &Level->sectors[i];
if (lsector->healthceilinggroup > 0)
{
FHealthGroup* grp = P_GetHealthGroupOrNew(lsector->healthceilinggroup, lsector->healthceiling);
FHealthGroup* grp = P_GetHealthGroupOrNew(Level, lsector->healthceilinggroup, lsector->healthceiling);
if (grp->health != lsector->healthceiling)
{
Printf(TEXTCOLOR_RED "Warning: sector ceiling %d in health group %d has different starting health (ceiling health = %d, group health = %d)\n", i, lsector->healthceilinggroup, lsector->healthceiling, grp->health);
@ -281,7 +284,7 @@ void P_InitHealthGroups()
}
if (lsector->healthfloorgroup > 0)
{
FHealthGroup* grp = P_GetHealthGroupOrNew(lsector->healthfloorgroup, lsector->healthfloor);
FHealthGroup* grp = P_GetHealthGroupOrNew(Level, lsector->healthfloorgroup, lsector->healthfloor);
if (grp->health != lsector->healthfloor)
{
Printf(TEXTCOLOR_RED "Warning: sector floor %d in health group %d has different starting health (floor health = %d, group health = %d)\n", i, lsector->healthfloorgroup, lsector->healthfloor, grp->health);
@ -295,7 +298,7 @@ void P_InitHealthGroups()
}
for (unsigned i = 0; i < groupsInError.Size(); i++)
{
FHealthGroup* grp = P_GetHealthGroup(groupsInError[i]);
FHealthGroup* grp = P_GetHealthGroup(Level, groupsInError[i]);
Printf(TEXTCOLOR_GOLD "Health group %d is using the highest found health value of %d", groupsInError[i], grp->health);
}
}
@ -840,7 +843,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FHealthGroup& g, FHeal
return arc;
}
void P_SerializeHealthGroups(FSerializer& arc)
void P_SerializeHealthGroups(FLevelLocals *Level, FSerializer& arc)
{
// todo : stuff
if (arc.BeginArray("healthgroups"))
@ -853,7 +856,7 @@ void P_SerializeHealthGroups(FSerializer& arc)
{
FHealthGroup grp;
arc(nullptr, grp);
FHealthGroup* existinggrp = P_GetHealthGroup(grp.id);
FHealthGroup* existinggrp = P_GetHealthGroup(Level, grp.id);
if (!existinggrp)
continue;
existinggrp->health = grp.health;
@ -861,7 +864,7 @@ void P_SerializeHealthGroups(FSerializer& arc)
}
else
{
TMap<int, FHealthGroup>::ConstIterator it(level.healthGroups);
TMap<int, FHealthGroup>::ConstIterator it(Level->healthGroups);
TMap<int, FHealthGroup>::ConstPair* pair;
while (it.NextPair(pair))
{
@ -883,11 +886,11 @@ DEFINE_FIELD_X(HealthGroup, FHealthGroup, health)
DEFINE_FIELD_X(HealthGroup, FHealthGroup, sectors)
DEFINE_FIELD_X(HealthGroup, FHealthGroup, lines)
DEFINE_ACTION_FUNCTION(FHealthGroup, Find)
DEFINE_ACTION_FUNCTION(FLevelLocals, FindHealthGroup)
{
PARAM_PROLOGUE;
PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals);
PARAM_INT(id);
FHealthGroup* grp = P_GetHealthGroup(id);
FHealthGroup* grp = P_GetHealthGroup(self, id);
ACTION_RETURN_POINTER(grp);
}
@ -993,7 +996,7 @@ DEFINE_ACTION_FUNCTION(_Line, GetHealth)
PARAM_SELF_STRUCT_PROLOGUE(line_t);
if (self->healthgroup)
{
FHealthGroup* grp = P_GetHealthGroup(self->healthgroup);
FHealthGroup* grp = P_GetHealthGroup(self->GetLevel(), self->healthgroup);
if (grp) ACTION_RETURN_INT(grp->health);
}
@ -1011,7 +1014,7 @@ DEFINE_ACTION_FUNCTION(_Line, SetHealth)
self->health = newhealth;
if (self->healthgroup)
{
FHealthGroup* grp = P_GetHealthGroup(self->healthgroup);
FHealthGroup* grp = P_GetHealthGroup(self->GetLevel(), self->healthgroup);
if (grp) P_SetHealthGroupHealth(grp, newhealth);
}
@ -1024,14 +1027,15 @@ DEFINE_ACTION_FUNCTION(_Sector, GetHealth)
PARAM_INT(part);
FHealthGroup* grp;
auto Level = self->Level;
switch (part)
{
case SECPART_Floor:
ACTION_RETURN_INT((self->healthfloorgroup && (grp = P_GetHealthGroup(self->healthfloorgroup))) ? grp->health : self->healthfloor);
ACTION_RETURN_INT((self->healthfloorgroup && (grp = P_GetHealthGroup(Level, self->healthfloorgroup))) ? grp->health : self->healthfloor);
case SECPART_Ceiling:
ACTION_RETURN_INT((self->healthceilinggroup && (grp = P_GetHealthGroup(self->healthceilinggroup))) ? grp->health : self->healthceiling);
ACTION_RETURN_INT((self->healthceilinggroup && (grp = P_GetHealthGroup(Level, self->healthceilinggroup))) ? grp->health : self->healthceiling);
case SECPART_3D:
ACTION_RETURN_INT((self->health3dgroup && (grp = P_GetHealthGroup(self->health3dgroup))) ? grp->health : self->health3d);
ACTION_RETURN_INT((self->health3dgroup && (grp = P_GetHealthGroup(Level, self->health3dgroup))) ? grp->health : self->health3d);
default:
ACTION_RETURN_INT(0);
}
@ -1066,7 +1070,7 @@ DEFINE_ACTION_FUNCTION(_Sector, SetHealth)
return 0;
}
FHealthGroup* grp = group ? P_GetHealthGroup(group) : nullptr;
FHealthGroup* grp = group ? P_GetHealthGroup(self->Level, group) : nullptr;
*health = newhealth;
if (grp) P_SetHealthGroupHealth(grp, newhealth);
return 0;

View file

@ -21,13 +21,14 @@ enum
SECPART_3D = 2
};
void P_InitHealthGroups();
struct FLevelLocals;
void P_InitHealthGroups(FLevelLocals *Level);
void P_SetHealthGroupHealth(FHealthGroup* group, int health);
void P_SetHealthGroupHealth(int group, int health);
void P_SetHealthGroupHealth(FLevelLocals *Level, int group, int health);
FHealthGroup* P_GetHealthGroup(int id);
FHealthGroup* P_GetHealthGroupOrNew(int id, int startinghealth);
FHealthGroup* P_GetHealthGroup(FLevelLocals *Level, int id);
FHealthGroup* P_GetHealthGroupOrNew(FLevelLocals *Level, int id, int startinghealth);
void P_DamageSector(sector_t* sector, AActor* source, int damage, FName damagetype, int part, DVector3 position, bool isradius, bool dogroups);
void P_DamageLinedef(line_t* line, AActor* source, int damage, FName damagetype, int side, DVector3 position, bool isradius, bool dogroups);
@ -40,4 +41,4 @@ bool P_ProjectileHitPlane(AActor* projectile, int part);
bool P_CheckLinedefVulnerable(line_t* line, int side, int part = -1);
bool P_CheckSectorVulnerable(sector_t* sector, int part);
void P_SerializeHealthGroups(FSerializer& arc);
void P_SerializeHealthGroups(FLevelLocals *Level, FSerializer& arc);

View file

@ -3491,7 +3491,7 @@ FUNC(LS_Line_SetHealth)
line_t* line = &Level->lines[l];
line->health = arg1;
if (line->healthgroup)
P_SetHealthGroupHealth(line->healthgroup, arg1);
P_SetHealthGroupHealth(Level, line->healthgroup, arg1);
}
return true;
}
@ -3512,19 +3512,19 @@ FUNC(LS_Sector_SetHealth)
{
sector->healthceiling = arg2;
if (sector->healthceilinggroup)
P_SetHealthGroupHealth(sector->healthceilinggroup, arg2);
P_SetHealthGroupHealth(Level, sector->healthceilinggroup, arg2);
}
else if (arg1 == SECPART_Floor)
{
sector->healthfloor = arg2;
if (sector->healthfloorgroup)
P_SetHealthGroupHealth(sector->healthfloorgroup, arg2);
P_SetHealthGroupHealth(Level, sector->healthfloorgroup, arg2);
}
else if (arg1 == SECPART_3D)
{
sector->health3d = arg2;
if (sector->health3dgroup)
P_SetHealthGroupHealth(sector->health3dgroup, arg2);
P_SetHealthGroupHealth(Level, sector->health3dgroup, arg2);
}
}
return true;

View file

@ -117,7 +117,7 @@ struct FLineOpening
static const double LINEOPEN_MIN = -FLT_MAX;
static const double LINEOPEN_MAX = FLT_MAX;
void P_LineOpening(FLineOpening &open, AActor *thing, const line_t *linedef, const DVector2 &xy, const DVector2 *ref = NULL, int flags = 0);
void P_LineOpening(FLineOpening &open, AActor *thing, const line_t *linedef, const DVector2 &xy, const DVector2 *ref = nullptr, int flags = 0);
inline void P_LineOpening(FLineOpening &open, AActor *thing, const line_t *linedef, const DVector2 &xy, const DVector3 *ref, int flags = 0)
{
P_LineOpening(open, thing, linedef, xy, reinterpret_cast<const DVector2*>(ref), flags);
@ -383,7 +383,7 @@ public:
init(x1, y1, x2, y2, flags, startfrac);
}
void init(double x1, double y1, double x2, double y2, int flags, double startfrac = 0);
int PortalRelocate(intercept_t *in, int flags, DVector3 *optpos = NULL);
int PortalRelocate(intercept_t *in, int flags, DVector3 *optpos = nullptr);
void PortalRelocate(const DVector2 &disp, int flags, double hitfrac);
virtual ~FPathTraverse();
const divline_t &Trace() const { return trace; }

View file

@ -996,7 +996,7 @@ void FLevelLocals::Serialize(FSerializer &arc, bool hubload)
}
// [ZZ] serialize health groups
P_SerializeHealthGroups(arc);
P_SerializeHealthGroups(this, arc);
// [ZZ] serialize events
E_SerializeEvents(arc);
DThinker::SerializeThinkers(arc, hubload);

View file

@ -637,7 +637,7 @@ PolyWallTextureCoordsU::PolyWallTextureCoordsU(FSoftwareTexture *tex, const seg_
PolyWallTextureCoordsV::PolyWallTextureCoordsV(FSoftwareTexture *tex, const line_t *line, const side_t *side, side_t::ETexpart wallpart, double topz, double bottomz, double unpeggedceil, double topTexZ, double bottomTexZ)
{
double yoffset = side->GetTextureYOffset(wallpart);
if (tex->useWorldPanning())
if (tex->useWorldPanning(line->GetLevel()))
yoffset *= side->GetTextureYScale(wallpart) * tex->GetScale().Y;
switch (wallpart)

View file

@ -101,7 +101,7 @@ void RenderPolyWallSprite::Render(PolyRenderThread *thread, AActor *thing, subse
int lightlevel = fullbrightSprite ? 255 : thing->Sector->lightlevel + actualextralight;
PolyDrawArgs args;
auto nc = !!(sub->sector->Level->flags3 & LEVEL3_NOCOLOREDSPRITELIGHTING);
auto nc = !!(thing->Level->flags3 & LEVEL3_NOCOLOREDSPRITELIGHTING);
args.SetLight(GetSpriteColorTable(sub->sector->Colormap, sub->sector->SpecialColors[sector_t::sprites], nc), lightlevel, PolyRenderer::Instance()->Light.WallGlobVis(foggy), fullbrightSprite); args.SetStencilTestValue(stencilValue);
args.SetTexture(tex, thing->RenderStyle);
args.SetDepthTest(true);

View file

@ -1497,6 +1497,11 @@ struct seg_t
int segnum;
int Index() const { return segnum; }
FLevelLocals *GetLevel() const
{
return frontsector->Level;
}
};
//extern seg_t *segs;

View file

@ -444,7 +444,7 @@ namespace swrenderer
double yscale = (pic ? pic->GetScale().Y : 1.0) * sidedef->GetTextureYScale(side_t::mid);
fixed_t xoffset = FLOAT2FIXED(sidedef->GetTextureXOffset(side_t::mid));
if (pic && pic->useWorldPanning())
if (pic && pic->useWorldPanning(sidedef->GetLevel()))
{
xoffset = xs_RoundToInt(xoffset * lwallscale);
}
@ -822,7 +822,7 @@ namespace swrenderer
mTopPart.TextureMid = (mBackSector->GetPlaneTexZ(sector_t::ceiling) - Thread->Viewport->viewpoint.Pos.Z) * yrepeat;
}
}
if (mTopPart.Texture->useWorldPanning())
if (mTopPart.Texture->useWorldPanning(mLineSegment->GetLevel()))
{
mTopPart.TextureMid += rowoffset * yrepeat;
}
@ -880,7 +880,7 @@ namespace swrenderer
mMiddlePart.TextureMid = (mFrontSector->GetPlaneTexZ(sector_t::ceiling) - Thread->Viewport->viewpoint.Pos.Z) * yrepeat + mMiddlePart.Texture->GetHeight();
}
}
if (mMiddlePart.Texture->useWorldPanning())
if (mMiddlePart.Texture->useWorldPanning(mLineSegment->GetLevel()))
{
mMiddlePart.TextureMid += rowoffset * yrepeat;
}
@ -947,7 +947,7 @@ namespace swrenderer
mBottomPart.TextureMid = (mBackSector->GetPlaneTexZ(sector_t::floor) - Thread->Viewport->viewpoint.Pos.Z) * yrepeat + mBottomPart.Texture->GetHeight();
}
}
if (mBottomPart.Texture->useWorldPanning())
if (mBottomPart.Texture->useWorldPanning(mLineSegment->GetLevel()))
{
mBottomPart.TextureMid += rowoffset * yrepeat;
}
@ -1122,7 +1122,7 @@ namespace swrenderer
lwallscale = xscale;
}
fixed_t offset;
if (mTopPart.Texture->useWorldPanning())
if (mTopPart.Texture->useWorldPanning(mLineSegment->GetLevel()))
{
offset = xs_RoundToInt(mTopPart.TextureOffsetU * xscale);
}
@ -1153,7 +1153,7 @@ namespace swrenderer
lwallscale = xscale;
}
fixed_t offset;
if (mMiddlePart.Texture->useWorldPanning())
if (mMiddlePart.Texture->useWorldPanning(mLineSegment->GetLevel()))
{
offset = xs_RoundToInt(mMiddlePart.TextureOffsetU * xscale);
}
@ -1185,7 +1185,7 @@ namespace swrenderer
lwallscale = xscale;
}
fixed_t offset;
if (mBottomPart.Texture->useWorldPanning())
if (mBottomPart.Texture->useWorldPanning(mLineSegment->GetLevel()))
{
offset = xs_RoundToInt(mBottomPart.TextureOffsetU * xscale);
}

View file

@ -197,7 +197,7 @@ namespace swrenderer
MaskedScaleY = -MaskedScaleY;
sprflipvert = true;
}
if (tex->useWorldPanning())
if (tex->useWorldPanning(curline->GetLevel()))
{
// rowoffset is added before the multiply so that the masked texture will
// still be positioned in world units rather than texels.
@ -332,7 +332,7 @@ namespace swrenderer
}
else
{ // Texture does wrap vertically.
if (tex->useWorldPanning())
if (tex->useWorldPanning(curline->GetLevel()))
{
// rowoffset is added before the multiply so that the masked texture will
// still be positioned in world units rather than texels.
@ -447,7 +447,7 @@ namespace swrenderer
rowoffset += rw_pic->GetHeight();
}
double texturemid = (planez - Thread->Viewport->viewpoint.Pos.Z) * yscale;
if (rw_pic->useWorldPanning())
if (rw_pic->useWorldPanning(curline->GetLevel()))
{
// rowoffset is added before the multiply so that the masked texture will
// still be positioned in world units rather than texels.

View file

@ -45,9 +45,9 @@ public:
}
// The feature from hell... :(
bool useWorldPanning() const
bool useWorldPanning(FLevelLocals *Level) const
{
return mTexture->bWorldPanning || (level.flags3 & LEVEL3_FORCEWORLDPANNING);
return mTexture->bWorldPanning || (Level->flags3 & LEVEL3_FORCEWORLDPANNING);
}
bool isMasked()

View file

@ -697,7 +697,7 @@ struct LevelLocals native
native void GiveSecret(Actor activator, bool printmsg = true, bool playsound = true);
native void StartSlideshow(Name whichone = 'none');
native void WorldDone();
deprecated("3.8") native static void RemoveAllBots(bool fromlist) { /* intentionally left as no-op. */ }
deprecated("3.8") static void RemoveAllBots(bool fromlist) { /* intentionally left as no-op. */ }
native ui Vector2 GetAutomapPosition();
native void SetInterMusic(String nextmap);
native String FormatMapName(int mapnamecolor);
@ -709,6 +709,7 @@ struct LevelLocals native
native int FindUniqueTid(int start = 0, int limit = 0);
native uint GetSkyboxPortal(Actor actor);
native void ReplaceTextures(String from, String to, int flags);
clearscope native HealthGroup FindHealthGroup(int id);
native vector3, int PickDeathmatchStart();
native vector3, int PickPlayerStart(int pnum, int flags = 0);
native int isFrozen();

View file

@ -1,6 +1,9 @@
struct HealthGroup native play
{
static clearscope native HealthGroup Find(int id);
deprecated("3.8") static clearscope HealthGroup Find(int id)
{
return level.FindHealthGroup(id);
}
readonly int id;
readonly int health;