- 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; class AActor;
struct FLevelLocals;
// //
// GAME // 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. SWRenderer->SetColormap(Level); //The SW renderer needs to do some special setup for the level's default colormap.
InitPortalGroups(Level); InitPortalGroups(Level);
P_InitHealthGroups(); P_InitHealthGroups(Level);
if (reloop) LoopSidedefs(false); if (reloop) LoopSidedefs(false);
PO_Init(); // Initialize the polyobjs PO_Init(); // Initialize the polyobjs

View file

@ -6633,17 +6633,17 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
FHealthGroup* grp; FHealthGroup* grp;
if (part == SECPART_Ceiling) 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; ? grp->health : ss->healthceiling;
} }
else if (part == SECPART_Floor) 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; ? grp->health : ss->healthfloor;
} }
else if (part == SECPART_3D) 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; ? grp->health : ss->health3d;
} }
return 0; return 0;
@ -6658,7 +6658,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
line_t* ll = &Level->lines[l]; line_t* ll = &Level->lines[l];
if (ll->healthgroup > 0) if (ll->healthgroup > 0)
{ {
FHealthGroup* grp = P_GetHealthGroup(ll->healthgroup); FHealthGroup* grp = P_GetHealthGroup(Level, ll->healthgroup);
if (grp) return grp->health; 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) 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; line->health -= damage;
if (line->health < 0) line->health = 0; if (line->health < 0) line->health = 0;
auto Level = line->GetLevel();
// callbacks here // callbacks here
// first off, call special if needed // 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) if (dogroups && line->healthgroup)
{ {
FHealthGroup* grp = P_GetHealthGroup(line->healthgroup); FHealthGroup* grp = P_GetHealthGroup(Level, line->healthgroup);
if (grp) if (grp)
grp->health = line->health; grp->health = line->health;
P_DamageHealthGroup(grp, line, source, damage, damagetype, side, -1, position, isradius); 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; if (!damage) return;
auto Level = sector->Level;
int* sectorhealth; int* sectorhealth;
int group; int group;
int dmg; int dmg;
@ -209,7 +211,7 @@ void P_DamageSector(sector_t* sector, AActor* source, int damage, FName damagety
if (dogroups && group) if (dogroups && group)
{ {
FHealthGroup* grp = P_GetHealthGroup(group); FHealthGroup* grp = P_GetHealthGroup(Level, group);
if (grp) if (grp)
grp->health = newhealth; grp->health = newhealth;
P_DamageHealthGroup(grp, sector, source, damage, damagetype, 0, part, position, isradius); 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; 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) if (!grp)
{ {
FHealthGroup newgrp; FHealthGroup newgrp;
newgrp.id = id; newgrp.id = id;
newgrp.health = health; newgrp.health = health;
grp = &(level.healthGroups.Insert(id, newgrp)); grp = &(Level->healthGroups.Insert(id, newgrp));
} }
return grp; return grp;
} }
void P_InitHealthGroups() void P_InitHealthGroups(FLevelLocals *Level)
{ {
level.healthGroups.Clear(); Level->healthGroups.Clear();
TArray<int> groupsInError; 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) 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) 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); 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); 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) 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) 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); 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) 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) 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); 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++) 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); 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; return arc;
} }
void P_SerializeHealthGroups(FSerializer& arc) void P_SerializeHealthGroups(FLevelLocals *Level, FSerializer& arc)
{ {
// todo : stuff // todo : stuff
if (arc.BeginArray("healthgroups")) if (arc.BeginArray("healthgroups"))
@ -853,7 +856,7 @@ void P_SerializeHealthGroups(FSerializer& arc)
{ {
FHealthGroup grp; FHealthGroup grp;
arc(nullptr, grp); arc(nullptr, grp);
FHealthGroup* existinggrp = P_GetHealthGroup(grp.id); FHealthGroup* existinggrp = P_GetHealthGroup(Level, grp.id);
if (!existinggrp) if (!existinggrp)
continue; continue;
existinggrp->health = grp.health; existinggrp->health = grp.health;
@ -861,7 +864,7 @@ void P_SerializeHealthGroups(FSerializer& arc)
} }
else else
{ {
TMap<int, FHealthGroup>::ConstIterator it(level.healthGroups); TMap<int, FHealthGroup>::ConstIterator it(Level->healthGroups);
TMap<int, FHealthGroup>::ConstPair* pair; TMap<int, FHealthGroup>::ConstPair* pair;
while (it.NextPair(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, sectors)
DEFINE_FIELD_X(HealthGroup, FHealthGroup, lines) 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); PARAM_INT(id);
FHealthGroup* grp = P_GetHealthGroup(id); FHealthGroup* grp = P_GetHealthGroup(self, id);
ACTION_RETURN_POINTER(grp); ACTION_RETURN_POINTER(grp);
} }
@ -993,7 +996,7 @@ DEFINE_ACTION_FUNCTION(_Line, GetHealth)
PARAM_SELF_STRUCT_PROLOGUE(line_t); PARAM_SELF_STRUCT_PROLOGUE(line_t);
if (self->healthgroup) if (self->healthgroup)
{ {
FHealthGroup* grp = P_GetHealthGroup(self->healthgroup); FHealthGroup* grp = P_GetHealthGroup(self->GetLevel(), self->healthgroup);
if (grp) ACTION_RETURN_INT(grp->health); if (grp) ACTION_RETURN_INT(grp->health);
} }
@ -1011,7 +1014,7 @@ DEFINE_ACTION_FUNCTION(_Line, SetHealth)
self->health = newhealth; self->health = newhealth;
if (self->healthgroup) if (self->healthgroup)
{ {
FHealthGroup* grp = P_GetHealthGroup(self->healthgroup); FHealthGroup* grp = P_GetHealthGroup(self->GetLevel(), self->healthgroup);
if (grp) P_SetHealthGroupHealth(grp, newhealth); if (grp) P_SetHealthGroupHealth(grp, newhealth);
} }
@ -1024,14 +1027,15 @@ DEFINE_ACTION_FUNCTION(_Sector, GetHealth)
PARAM_INT(part); PARAM_INT(part);
FHealthGroup* grp; FHealthGroup* grp;
auto Level = self->Level;
switch (part) switch (part)
{ {
case SECPART_Floor: 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: 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: 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: default:
ACTION_RETURN_INT(0); ACTION_RETURN_INT(0);
} }
@ -1066,7 +1070,7 @@ DEFINE_ACTION_FUNCTION(_Sector, SetHealth)
return 0; return 0;
} }
FHealthGroup* grp = group ? P_GetHealthGroup(group) : nullptr; FHealthGroup* grp = group ? P_GetHealthGroup(self->Level, group) : nullptr;
*health = newhealth; *health = newhealth;
if (grp) P_SetHealthGroupHealth(grp, newhealth); if (grp) P_SetHealthGroupHealth(grp, newhealth);
return 0; return 0;

View file

@ -21,13 +21,14 @@ enum
SECPART_3D = 2 SECPART_3D = 2
}; };
void P_InitHealthGroups(); struct FLevelLocals;
void P_InitHealthGroups(FLevelLocals *Level);
void P_SetHealthGroupHealth(FHealthGroup* group, int health); 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_GetHealthGroup(FLevelLocals *Level, int id);
FHealthGroup* P_GetHealthGroupOrNew(int id, int startinghealth); 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_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); 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_CheckLinedefVulnerable(line_t* line, int side, int part = -1);
bool P_CheckSectorVulnerable(sector_t* sector, int part); 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_t* line = &Level->lines[l];
line->health = arg1; line->health = arg1;
if (line->healthgroup) if (line->healthgroup)
P_SetHealthGroupHealth(line->healthgroup, arg1); P_SetHealthGroupHealth(Level, line->healthgroup, arg1);
} }
return true; return true;
} }
@ -3512,19 +3512,19 @@ FUNC(LS_Sector_SetHealth)
{ {
sector->healthceiling = arg2; sector->healthceiling = arg2;
if (sector->healthceilinggroup) if (sector->healthceilinggroup)
P_SetHealthGroupHealth(sector->healthceilinggroup, arg2); P_SetHealthGroupHealth(Level, sector->healthceilinggroup, arg2);
} }
else if (arg1 == SECPART_Floor) else if (arg1 == SECPART_Floor)
{ {
sector->healthfloor = arg2; sector->healthfloor = arg2;
if (sector->healthfloorgroup) if (sector->healthfloorgroup)
P_SetHealthGroupHealth(sector->healthfloorgroup, arg2); P_SetHealthGroupHealth(Level, sector->healthfloorgroup, arg2);
} }
else if (arg1 == SECPART_3D) else if (arg1 == SECPART_3D)
{ {
sector->health3d = arg2; sector->health3d = arg2;
if (sector->health3dgroup) if (sector->health3dgroup)
P_SetHealthGroupHealth(sector->health3dgroup, arg2); P_SetHealthGroupHealth(Level, sector->health3dgroup, arg2);
} }
} }
return true; return true;

View file

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

View file

@ -996,7 +996,7 @@ void FLevelLocals::Serialize(FSerializer &arc, bool hubload)
} }
// [ZZ] serialize health groups // [ZZ] serialize health groups
P_SerializeHealthGroups(arc); P_SerializeHealthGroups(this, arc);
// [ZZ] serialize events // [ZZ] serialize events
E_SerializeEvents(arc); E_SerializeEvents(arc);
DThinker::SerializeThinkers(arc, hubload); 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) 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); double yoffset = side->GetTextureYOffset(wallpart);
if (tex->useWorldPanning()) if (tex->useWorldPanning(line->GetLevel()))
yoffset *= side->GetTextureYScale(wallpart) * tex->GetScale().Y; yoffset *= side->GetTextureYScale(wallpart) * tex->GetScale().Y;
switch (wallpart) switch (wallpart)

View file

@ -101,7 +101,7 @@ void RenderPolyWallSprite::Render(PolyRenderThread *thread, AActor *thing, subse
int lightlevel = fullbrightSprite ? 255 : thing->Sector->lightlevel + actualextralight; int lightlevel = fullbrightSprite ? 255 : thing->Sector->lightlevel + actualextralight;
PolyDrawArgs args; 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.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.SetTexture(tex, thing->RenderStyle);
args.SetDepthTest(true); args.SetDepthTest(true);

View file

@ -1497,6 +1497,11 @@ struct seg_t
int segnum; int segnum;
int Index() const { return segnum; } int Index() const { return segnum; }
FLevelLocals *GetLevel() const
{
return frontsector->Level;
}
}; };
//extern seg_t *segs; //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); double yscale = (pic ? pic->GetScale().Y : 1.0) * sidedef->GetTextureYScale(side_t::mid);
fixed_t xoffset = FLOAT2FIXED(sidedef->GetTextureXOffset(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); xoffset = xs_RoundToInt(xoffset * lwallscale);
} }
@ -822,7 +822,7 @@ namespace swrenderer
mTopPart.TextureMid = (mBackSector->GetPlaneTexZ(sector_t::ceiling) - Thread->Viewport->viewpoint.Pos.Z) * yrepeat; 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; 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(); 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; 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(); 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; mBottomPart.TextureMid += rowoffset * yrepeat;
} }
@ -1122,7 +1122,7 @@ namespace swrenderer
lwallscale = xscale; lwallscale = xscale;
} }
fixed_t offset; fixed_t offset;
if (mTopPart.Texture->useWorldPanning()) if (mTopPart.Texture->useWorldPanning(mLineSegment->GetLevel()))
{ {
offset = xs_RoundToInt(mTopPart.TextureOffsetU * xscale); offset = xs_RoundToInt(mTopPart.TextureOffsetU * xscale);
} }
@ -1153,7 +1153,7 @@ namespace swrenderer
lwallscale = xscale; lwallscale = xscale;
} }
fixed_t offset; fixed_t offset;
if (mMiddlePart.Texture->useWorldPanning()) if (mMiddlePart.Texture->useWorldPanning(mLineSegment->GetLevel()))
{ {
offset = xs_RoundToInt(mMiddlePart.TextureOffsetU * xscale); offset = xs_RoundToInt(mMiddlePart.TextureOffsetU * xscale);
} }
@ -1185,7 +1185,7 @@ namespace swrenderer
lwallscale = xscale; lwallscale = xscale;
} }
fixed_t offset; fixed_t offset;
if (mBottomPart.Texture->useWorldPanning()) if (mBottomPart.Texture->useWorldPanning(mLineSegment->GetLevel()))
{ {
offset = xs_RoundToInt(mBottomPart.TextureOffsetU * xscale); offset = xs_RoundToInt(mBottomPart.TextureOffsetU * xscale);
} }

View file

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

View file

@ -45,9 +45,9 @@ public:
} }
// The feature from hell... :( // 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() bool isMasked()

View file

@ -697,7 +697,7 @@ struct LevelLocals native
native void GiveSecret(Actor activator, bool printmsg = true, bool playsound = true); native void GiveSecret(Actor activator, bool printmsg = true, bool playsound = true);
native void StartSlideshow(Name whichone = 'none'); native void StartSlideshow(Name whichone = 'none');
native void WorldDone(); 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 ui Vector2 GetAutomapPosition();
native void SetInterMusic(String nextmap); native void SetInterMusic(String nextmap);
native String FormatMapName(int mapnamecolor); native String FormatMapName(int mapnamecolor);
@ -709,6 +709,7 @@ struct LevelLocals native
native int FindUniqueTid(int start = 0, int limit = 0); native int FindUniqueTid(int start = 0, int limit = 0);
native uint GetSkyboxPortal(Actor actor); native uint GetSkyboxPortal(Actor actor);
native void ReplaceTextures(String from, String to, int flags); native void ReplaceTextures(String from, String to, int flags);
clearscope native HealthGroup FindHealthGroup(int id);
native vector3, int PickDeathmatchStart(); native vector3, int PickDeathmatchStart();
native vector3, int PickPlayerStart(int pnum, int flags = 0); native vector3, int PickPlayerStart(int pnum, int flags = 0);
native int isFrozen(); native int isFrozen();

View file

@ -1,6 +1,9 @@
struct HealthGroup native play 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 id;
readonly int health; readonly int health;