- refactored the owner index in tspritetype.

This is now a separate type from spritetype which contains an actor pointer instead so that sprite display can be handled without requiring a static sprite array.
This commit is contained in:
Christoph Oelckers 2021-12-04 19:08:50 +01:00
parent 793dd032b0
commit eaff9e359f
50 changed files with 473 additions and 364 deletions

View file

@ -154,27 +154,6 @@ EXTERN int leveltimer;
extern TArray<sectortype> sectorbackup;
extern TArray<walltype> wallbackup;
inline tspriteptr_t renderAddTSpriteFromSprite(spritetype* tsprite, int& spritesortcnt, uint16_t const spritenum)
{
auto tspr = &tsprite[spritesortcnt++];
auto const spr = &sprite[spritenum];
*tspr = *spr;
tspr->clipdist = 0;
tspr->owner = spritenum;
return tspr;
}
// returns: 0=continue sprite collecting;
// 1=break out of sprite collecting;
inline int32_t renderAddTsprite(spritetype* tsprite, int& spritesortcnt, int16_t z, int16_t sectnum)
{
if (spritesortcnt >= MAXSPRITESONSCREEN) return 1;
renderAddTSpriteFromSprite(tsprite, spritesortcnt, z);
return 0;
}
EXTERN int32_t xdim, ydim;
EXTERN int32_t yxaspect, viewingrange;
@ -505,7 +484,7 @@ int32_t lintersect(int32_t originX, int32_t originY, int32_t originZ,
int32_t lineStartX, int32_t lineStartY, int32_t lineEndX, int32_t lineEndY,
int32_t *intersectionX, int32_t *intersectionY, int32_t *intersectionZ);
int32_t insertsprite(int16_t sectnum, int16_t statnum);
int32_t insertsprite(int16_t sectnum, int16_t statnum, bool frominit = false);
int32_t deletesprite(int16_t spritenum);
int32_t changespritesect(int16_t spritenum, int16_t newsectnum);
@ -625,7 +604,6 @@ extern int32_t rintersect(int32_t x1, int32_t y1, int32_t z1,
int32_t x3, int32_t y3, int32_t x4, int32_t y4,
int32_t *intx, int32_t *inty, int32_t *intz);
extern int32_t(*animateoffs_replace)(int const tilenum, int fakevar);
extern void(*initspritelists_replace)(void);
extern int32_t(*changespritesect_replace)(int16_t spritenum, int16_t newsectnum);
@ -676,6 +654,25 @@ inline bool spritetype::insector() const
return validSectorIndex(sectnum);
}
inline sectortype* tspritetype::sector() const
{
return !validSectorIndex(sectnum) ? nullptr : &::sector[sectnum];
}
inline bool tspritetype::insector() const
{
return validSectorIndex(sectnum);
}
inline void tspritetype::setsector(sectortype* sect)
{
// place for asserts.
sectnum = sect ? ::sector.IndexOf(sect) : -1;
}
inline sectortype* walltype::nextSector() const
{
return !validSectorIndex(nextsector)? nullptr : &::sector[nextsector];

View file

@ -57,6 +57,7 @@ BEGIN_BLD_NS
END_BLD_NS
//40 bytes
class DCoreActor;
struct walltype;
struct sectortype
{
@ -369,9 +370,13 @@ struct spritetype
#endif
void clear()
{
int sect = sectnum;
int stat = statnum;
int save = time; // this may not be cleared ever!!!
memset(this, 0, sizeof(*this));
time = save;
sectnum = sect;
statnum = stat;
}
void backupx()
@ -459,7 +464,120 @@ struct spritetype
void setsector(sectortype*);
};
using tspritetype = spritetype;
// This is mostly the same, but it omits the 'owner' field in favor of a full actor pointer.
// Incompatibility with spritetype regarding assignments is deliberate as these serve a fundamentally different purpose!
struct tspritetype
{
union {
struct
{
int32_t x, y, z;
};
vec3_t pos;
};
union {
struct
{
int32_t ox, oy, oz;
};
vec3_t opos;
};
uint16_t cstat;
int16_t picnum;
int8_t shade;
uint8_t pal, clipdist, blend;
uint8_t xrepeat, yrepeat;
int8_t xoffset, yoffset;
int16_t sectnum, statnum;
int16_t oang, ang;
int16_t xvel;
int16_t yvel;
int16_t zvel;
union {
int16_t lotag, type;
};
union {
int16_t hitag, flags;
};
int16_t extra;
uint16_t cstat2;
int time;
DCoreActor* ownerActor;
sectortype* sector() const;
bool insector() const;
void setsector(sectortype*);
void copyfrom(spritetype* spr)
{
pos = spr->pos;
opos = spr->opos;
cstat = spr->cstat;
picnum = spr->picnum;
shade = spr->shade;
pal = spr->pal;
clipdist = spr->clipdist;
blend = spr->blend;
xrepeat = spr->xrepeat;
yrepeat = spr->yrepeat;
xoffset = spr->xoffset;
yoffset = spr->yoffset;
sectnum = spr->sectnum;
statnum = spr->statnum;
ang = spr->ang;
oang = spr->oang;
xvel = spr->xvel;
yvel = spr->yvel;
zvel = spr->zvel;
lotag = spr->lotag;
hitag = spr->hitag;
extra = spr->extra;
time = spr->time;
cstat2 = spr->cstat2;
ownerActor = nullptr;
}
int32_t interpolatedx(double const smoothratio, int const scale = 16)
{
return interpolatedvalue(ox, x, smoothratio, scale);
}
int32_t interpolatedy(double const smoothratio, int const scale = 16)
{
return interpolatedvalue(oy, y, smoothratio, scale);
}
int32_t interpolatedz(double const smoothratio, int const scale = 16)
{
return interpolatedvalue(oz, z, smoothratio, scale);
}
vec2_t interpolatedvec2(double const smoothratio, int const scale = 16)
{
return
{
interpolatedx(smoothratio, scale),
interpolatedy(smoothratio, scale)
};
}
vec3_t interpolatedvec3(double const smoothratio, int const scale = 16)
{
return
{
interpolatedx(smoothratio, scale),
interpolatedy(smoothratio, scale),
interpolatedz(smoothratio, scale)
};
}
int16_t interpolatedang(double const smoothratio)
{
return interpolatedangle(oang, ang, smoothratio, 16);
}
};
#endif
//////////////////// END Version 7 map format ////////////////

View file

@ -16,9 +16,6 @@ extern double gxyaspect;
extern float grhalfxdown10x;
extern float gcosang, gsinang, gcosang2, gsinang2;
extern void Polymost_prepare_loadboard(void);
//void phex(char v, char *s);
void polymost_drawsprite(int32_t snum);
void polymost_drawmaskwall(int32_t damaskwallcnt);
@ -27,7 +24,6 @@ void polymost_initosdfuncs(void);
void polymost_drawrooms(void);
void polymost_prepareMirror(int32_t dax, int32_t day, int32_t daz, fixed_t daang, fixed_t dahoriz, int16_t mirrorWall);
void polymost_completeMirror();
void polymost_deletesprite(int num);
int32_t polymost_maskWallHasTranslucency(walltype const * const wall);
int32_t polymost_spriteHasTranslucency(spritetype const * const tspr);

View file

@ -160,16 +160,18 @@ static int16_t numhits;
// Internal Engine Functions
//
BEGIN_BLD_NS
int qanimateoffs(int a1, int a2);
END_BLD_NS
//
// animateoffs (internal)
//
int32_t (*animateoffs_replace)(int const tilenum, int fakevar) = NULL;
int32_t animateoffs(int const tilenum, int fakevar)
{
if (animateoffs_replace)
if (isBlood())
{
return animateoffs_replace(tilenum, fakevar);
return Blood::qanimateoffs(tilenum, fakevar);
}
int const animnum = picanm[tilenum].num;
@ -311,13 +313,17 @@ static void do_deletespritestat(int16_t deleteme)
//
// insertsprite
//
int32_t insertsprite(int16_t sectnum, int16_t statnum)
int32_t insertsprite(int16_t sectnum, int16_t statnum, bool frominit)
{
// TODO: guard against bad sectnum?
int32_t const newspritenum = insertspritestat(statnum);
// Build's default init of sprites is insantity².
if (newspritenum >= 0)
{
// Make sure it's clear.
if (!frominit) sprite[newspritenum].clear();
assert(validSectorIndex(sectnum));
do_insertsprite_at_headofsect(newspritenum, sectnum);
@ -334,7 +340,6 @@ int32_t insertsprite(int16_t sectnum, int16_t statnum)
//
int32_t deletesprite(int16_t spritenum)
{
Polymost::polymost_deletesprite(spritenum);
assert((sprite[spritenum].statnum == MAXSTATUS)
== (sprite[spritenum].sectnum == MAXSECTORS));

View file

@ -36,7 +36,7 @@ inline int32_t bad_tspr(tspriteptr_t tspr)
{
// NOTE: tspr->owner >= MAXSPRITES (could be model) has to be handled by
// caller.
return (tspr->owner < 0 || (unsigned)tspr->picnum >= MAXTILES);
return (tspr->ownerActor == nullptr || (unsigned)tspr->picnum >= MAXTILES);
}
inline void set_globalpos(int32_t const x, int32_t const y, int32_t const z)

View file

@ -415,9 +415,10 @@ static void updateanimation(md2model_t *m, tspriteptr_t tspr, uint8_t lpal)
Printf("1: c > n\n");
#endif
auto ownerActor = tspr->ownerActor;
int32_t const smoothdurationp = (hw_animsmoothing && (tile2model[tile].smoothduration != 0));
spritesmooth_t * const smooth = &spritesmooth[((unsigned)tspr->owner < MAXSPRITES+MAXUNIQHUDID) ? tspr->owner : MAXSPRITES+MAXUNIQHUDID-1];
spriteext_t * const sprext = &spriteext[((unsigned)tspr->owner < MAXSPRITES) ? tspr->owner : MAXSPRITES-1];
spritesmooth_t* const smooth = &ownerActor->sm();
spriteext_t* const sprext = &ownerActor->sx();
const mdanim_t *anim;
for (anim = m->animations; anim && anim->startframe != m->cframe; anim = anim->next)
@ -1087,10 +1088,11 @@ void md3_vox_calcmat_common(tspriteptr_t tspr, const FVector3 *a0, float f, floa
{
float k0, k1, k2, k3, k4, k5, k6, k7;
k0 = ((float)(tspr->x+spriteext[tspr->owner].position_offset.x-globalposx))*f*(1.f/1024.f);
k1 = ((float)(tspr->y+spriteext[tspr->owner].position_offset.y-globalposy))*f*(1.f/1024.f);
k4 = -bsinf(tspr->ang+spriteext[tspr->owner].angoff, -14);
k5 = bcosf(tspr->ang+spriteext[tspr->owner].angoff, -14);
auto& sext = tspr->ownerActor->sx();
k0 = ((float)(tspr->x+sext.position_offset.x-globalposx))*f*(1.f/1024.f);
k1 = ((float)(tspr->y+sext.position_offset.y-globalposy))*f*(1.f/1024.f);
k4 = -bsinf(tspr->ang+sext.angoff, -14);
k5 = bcosf(tspr->ang+sext.angoff, -14);
k2 = k0*(1-k4)+k1*k5;
k3 = k1*(1-k4)-k0*k5;
k6 = - gsinang;
@ -1145,9 +1147,10 @@ static int32_t polymost_md3draw(md3model_t *m, tspriteptr_t tspr)
float pc[4];
// int32_t texunits = GL_TEXTURE0;
const int32_t owner = tspr->owner;
const spriteext_t *const sext = &spriteext[((unsigned)owner < MAXSPRITES) ? owner : MAXSPRITES-1];
const uint8_t lpal = ((unsigned)owner < MAXSPRITES) ? sprite[tspr->owner].pal : tspr->pal;
auto ownerActor = tspr->ownerActor;
const spritetype* const spr = &ownerActor->s();
const spriteext_t* const sext = &ownerActor->sx();
const uint8_t lpal = spr->pal;
const int32_t sizyrep = tileHeight(tspr->picnum) * tspr->yrepeat;
updateanimation((md2model_t *)m, tspr, lpal);
@ -1177,8 +1180,8 @@ static int32_t polymost_md3draw(md3model_t *m, tspriteptr_t tspr)
a0.Z = m->zadd * m->scale;
// Parkar: Moved up to be able to use k0 for the y-flipping code
k0 = (float)tspr->z+spriteext[tspr->owner].position_offset.z;
f = ((globalorientation&8) && (sprite[tspr->owner].cstat&48)!=0) ? -4.f : 4.f;
k0 = (float)tspr->z+sext->position_offset.z;
f = ((globalorientation&8) && (spr->cstat&48)!=0) ? -4.f : 4.f;
k0 -= (tspr->yoffset*tspr->yrepeat)*f;
if ((globalorientation&128) && !((globalorientation&48)==32))
k0 += (float)(sizyrep<<1);
@ -1202,7 +1205,7 @@ static int32_t polymost_md3draw(md3model_t *m, tspriteptr_t tspr)
m0.Z *= f; m1.Z *= f; a0.Z *= f;
// floor aligned
k1 = (float)tspr->y+spriteext[tspr->owner].position_offset.y;
k1 = (float)tspr->y+sext->position_offset.y;
if ((globalorientation&48)==32)
{
m0.Z = -m0.Z; m1.Z = -m1.Z; a0.Z = -a0.Z;
@ -1215,7 +1218,7 @@ static int32_t polymost_md3draw(md3model_t *m, tspriteptr_t tspr)
// calculations below again, but are needed for the base offsets.
f = (65536.f*512.f)/(fxdimen*fviewingrange);
g = 32.f/(fxdimen*gxyaspect);
m0.Y *= f; m1.Y *= f; a0.Y = (((float)(tspr->x+spriteext[tspr->owner].position_offset.x-globalposx))* (1.f/1024.f) + a0.Y)*f;
m0.Y *= f; m1.Y *= f; a0.Y = (((float)(tspr->x+sext->position_offset.x-globalposx))* (1.f/1024.f) + a0.Y)*f;
m0.X *=-f; m1.X *=-f; a0.X = ((k1 -fglobalposy) * -(1.f/1024.f) + a0.X)*-f;
m0.Z *= g; m1.Z *= g; a0.Z = ((k0 -fglobalposz) * -(1.f/16384.f) + a0.Z)*g;
@ -1237,11 +1240,9 @@ static int32_t polymost_md3draw(md3model_t *m, tspriteptr_t tspr)
// to use Z-buffer hacks to hide overdraw problems with the flat-tsprite-on-floor shadows,
// also disabling detail, glow, normal, and specular maps.
// WTF??? This should be done with proper math.
if (tspr->clipdist & TSPR_FLAGS_MDHACK)
{
double f = (double) (tspr->owner + 1) * (std::numeric_limits<double>::epsilon() * 8.0);
if (f != 0.0) f *= 1.0/(double) (FindDistance2D(globalposx - tspr->x, globalposy - tspr->y)>>5);
// What once was here had been neutered in EDuke32 already.
GLInterface.SetDepthFunc(DF_LEqual);
}
@ -1528,8 +1529,7 @@ int32_t polymost_mddraw(tspriteptr_t tspr)
allocmodelverts = maxmodelverts;
}
mdmodel_t *const vm = models[tile2model[Ptile2tile(tspr->picnum,
(tspr->owner >= MAXSPRITES) ? tspr->pal : sprite[tspr->owner].pal)].modelid];
mdmodel_t *const vm = models[tile2model[Ptile2tile(tspr->picnum, tspr->ownerActor->s().pal)].modelid];
if (vm->mdnum == 1)
return polymost_voxdraw((voxmodel_t *)vm,tspr, false); // can't access rotating info anymore
else if (vm->mdnum == 3)

View file

@ -282,10 +282,10 @@ int32_t polymost_maskWallHasTranslucency(walltype const * const wall)
return checkTranslucentReplacement(tileGetTexture(wall->picnum)->GetID(), wall->pal);
}
int32_t polymost_spriteHasTranslucency(spritetype const * const tspr)
int32_t polymost_spriteHasTranslucency(tspritetype const * const tspr)
{
if ((tspr->cstat & CSTAT_SPRITE_TRANSLUCENT) || (tspr->clipdist & TSPR_FLAGS_DRAW_LAST) ||
((unsigned)tspr->owner < MAXSPRITES && spriteext[tspr->owner].alpha))
(tspr->ownerActor && tspr->ownerActor->sx().alpha))
return true;
return checkTranslucentReplacement(tileGetTexture(tspr->picnum)->GetID(), tspr->pal);
@ -1926,7 +1926,7 @@ void polymost_scansector(int32_t sectnum)
(r_voxels && tiletovox[spr->picnum] >= 0 && voxmodels[tiletovox[spr->picnum]]) ||
(r_voxels && gi->Voxelize(spr->picnum) > -1) ||
DMulScale(bcos(spr->ang), -s.x, bsin(spr->ang), -s.y, 6) > 0)
if (renderAddTsprite(pm_tsprite, pm_spritesortcnt, act->GetSpriteIndex(), sectnum))
if (!renderAddTsprite(pm_tsprite, pm_spritesortcnt, act))
break;
}
}
@ -2603,26 +2603,6 @@ void polymost_completeMirror()
GLInterface.DisableStencil();
}
typedef struct
{
int16_t wall;
int8_t wdist;
int8_t filler;
} wallspriteinfo_t;
static wallspriteinfo_t wsprinfo[MAXSPRITES];
void Polymost_prepare_loadboard(void)
{
memset(wsprinfo, 0, sizeof(wsprinfo));
}
void polymost_deletesprite(int num)
{
wsprinfo[num].wall = -1;
}
static inline int32_t polymost_findwall(tspritetype const * const tspr, vec2_t const * const tsiz, int32_t * rd)
{
@ -2691,7 +2671,7 @@ static int32_t polymost_lintersect(int32_t x1, int32_t y1, int32_t x2, int32_t y
}
#define TSPR_OFFSET_FACTOR .0002f
#define TSPR_OFFSET(tspr) (TSPR_OFFSET_FACTOR + ((tspr->owner != -1 ? tspr->owner & 63 : 0) * TSPR_OFFSET_FACTOR))
#define TSPR_OFFSET(tspr) (TSPR_OFFSET_FACTOR + ((tspr->ownerActor ? tspr->ownerActor->GetIndex() & 63 : 0) * TSPR_OFFSET_FACTOR))
void polymost_drawsprite(int32_t snum)
{
@ -2702,10 +2682,10 @@ void polymost_drawsprite(int32_t snum)
usectorptr_t sec;
int32_t spritenum = tspr->owner;
auto actor = tspr->ownerActor;
if ((tspr->cstat&48) != 48)
tileUpdatePicnum(&tspr->picnum, spritenum + 32768);
tileUpdatePicnum(&tspr->picnum, (actor->GetIndex() & 16383) + 32768);
globalpicnum = tspr->picnum;
globalshade = tspr->shade;
@ -2731,12 +2711,12 @@ void polymost_drawsprite(int32_t snum)
SetRenderStyleFromBlend(!!(tspr->cstat & 2), tspr->blend, !!(tspr->cstat & 512));
drawpoly_alpha = spriteext[spritenum].alpha;
drawpoly_alpha = actor->sx().alpha;
drawpoly_blend = tspr->blend;
sec = (usectorptr_t)tspr->sector();
while (!(spriteext[spritenum].flags & SPREXT_NOTMD))
while (!(actor->sx().flags & SPREXT_NOTMD))
{
if (hw_models && tile2model[Ptile2tile(tspr->picnum, tspr->pal)].modelid >= 0 &&
tile2model[Ptile2tile(tspr->picnum, tspr->pal)].framenum >= 0)
@ -2768,12 +2748,12 @@ void polymost_drawsprite(int32_t snum)
vec3_t pos = tspr->pos;
if (spriteext[spritenum].flags & SPREXT_AWAY1)
if (actor->sx().flags & SPREXT_AWAY1)
{
pos.x += bcos(tspr->ang, -13);
pos.y += bsin(tspr->ang, -13);
}
else if (spriteext[spritenum].flags & SPREXT_AWAY2)
else if (actor->sx().flags & SPREXT_AWAY2)
{
pos.x -= bcos(tspr->ang, -13);
pos.y -= bsin(tspr->ang, -13);
@ -2918,29 +2898,8 @@ void polymost_drawsprite(int32_t snum)
FVector2 vec0 = { (float)(pos.x - globalposx) - vf.X,
(float)(pos.y - globalposy) - vf.Y };
int32_t const s = tspr->owner;
int32_t walldist = 1;
int32_t w = (s == -1) ? -1 : wsprinfo[s].wall;
// find the wall most likely to be what the sprite is supposed to be ornamented against
// this is really slow, so cache the result. Also assume that this association never changes once it is set up
if (s == -1 || !wsprinfo[s].wall)
{
w = polymost_findwall(tspr, &tsiz, &walldist);
if (s != -1)
{
wallspriteinfo_t *ws = &wsprinfo[s];
ws->wall = w;
if (w != -1)
{
ws->wdist = walldist;
}
}
}
else if (s != -1)
walldist = wsprinfo[s].wdist;
int w = polymost_findwall(tspr, &tsiz, &walldist);
// detect if the sprite is either on the wall line or the wall line and sprite intersect
if (w != -1)
@ -3172,10 +3131,10 @@ void polymost_drawsprite(int32_t snum)
// unfortunately, offsetting by only 1 isn't enough on most Android devices
if (pos.z == sec->ceilingz || pos.z == sec->ceilingz + 1)
pos.z = sec->ceilingz + 2, fadjust = (tspr->owner & 31);
pos.z = sec->ceilingz + 2, fadjust = (tspr->ownerActor->GetIndex() & 31);
if (pos.z == sec->floorz || pos.z == sec->floorz - 1)
pos.z = sec->floorz - 2, fadjust = -((tspr->owner & 31));
pos.z = sec->floorz - 2, fadjust = -((tspr->ownerActor->GetIndex() & 31));
float f = (float)(pos.z - globalposz + fadjust) * gyxscale;
@ -3247,8 +3206,7 @@ void polymost_drawsprite(int32_t snum)
break;
}
if ((unsigned)spritenum < MAXSPRITES)
sprite[spritenum].cstat2 |= CSTAT2_SPRITE_MAPPED;
actor->s().cstat2 |= CSTAT2_SPRITE_MAPPED;
_drawsprite_return:
;
@ -3309,6 +3267,7 @@ int32_t renderDrawRoomsQ16(int32_t daposx, int32_t daposy, int32_t daposz, fixed
int32_t renderDrawRoomsQ16(int32_t daposx, int32_t daposy, int32_t daposz,
fixed_t daang, fixed_t dahoriz, int dacursectnum, bool fromoutside)
{
memset(pm_tsprite, 0, sizeof(pm_tsprite));
pm_spritesortcnt = 0;
checkRotatedWalls();
@ -3386,12 +3345,14 @@ static inline int comparetsprites(int const k, int const l)
if (tspriteptr[k]->statnum != tspriteptr[l]->statnum)
return tspriteptr[k]->statnum - tspriteptr[l]->statnum;
if (!tspriteptr[k]->ownerActor || !tspriteptr[l]->ownerActor) return 0; // why are these getting dragged into here?
if (tspriteptr[k]->x == tspriteptr[l]->x &&
tspriteptr[k]->y == tspriteptr[l]->y &&
tspriteptr[k]->z == tspriteptr[l]->z &&
(tspriteptr[k]->cstat & 48) == (tspriteptr[l]->cstat & 48) &&
tspriteptr[k]->owner != tspriteptr[l]->owner)
return tspriteptr[k]->owner - tspriteptr[l]->owner;
tspriteptr[k]->ownerActor != tspriteptr[l]->ownerActor)
return tspriteptr[k]->ownerActor->GetIndex() - tspriteptr[l]->ownerActor->GetIndex();
if (abs(spritesxyz[k].z - globalposz) != abs(spritesxyz[l].z - globalposz))
return abs(spritesxyz[k].z - globalposz) - abs(spritesxyz[l].z - globalposz);
@ -3464,9 +3425,9 @@ static void sortsprites(int const start, int const end)
}
}
static bool spriteIsModelOrVoxel(const spritetype* tspr)
static bool spriteIsModelOrVoxel(const tspritetype* tspr)
{
if ((unsigned)tspr->owner < MAXSPRITES && spriteext[tspr->owner].flags & SPREXT_NOTMD)
if (!tspr->ownerActor || tspr->ownerActor->sx().flags & SPREXT_NOTMD)
return false;
if (hw_models)
@ -3818,11 +3779,11 @@ int32_t polymost_voxdraw(voxmodel_t* m, tspriteptr_t const tspr, bool rotate)
k0 = m->bscale / 64.f;
f = (float)tspr->xrepeat * (256.f / 320.f) * k0;
if ((sprite[tspr->owner].cstat & 48) == 16)
if ((tspr->ownerActor->s().cstat & 48) == 16)
{
f *= 1.25f;
a0.Y -= tspr->xoffset * bcosf(spriteext[tspr->owner].angoff, -20);
a0.X += tspr->xoffset * bsinf(spriteext[tspr->owner].angoff, -20);
a0.Y -= tspr->xoffset * bcosf(tspr->ownerActor->sx().angoff, -20);
a0.X += tspr->xoffset * bsinf(tspr->ownerActor->sx().angoff, -20);
}
if (globalorientation & 8) { m0.Z = -m0.Z; a0.Z = -a0.Z; } //y-flipping
@ -3833,8 +3794,8 @@ int32_t polymost_voxdraw(voxmodel_t* m, tspriteptr_t const tspr, bool rotate)
f = (float)tspr->yrepeat * k0;
m0.Z *= f; a0.Z *= f;
k0 = (float)(tspr->z + spriteext[tspr->owner].position_offset.z);
f = ((globalorientation & 8) && (sprite[tspr->owner].cstat & 48) != 0) ? -4.f : 4.f;
k0 = (float)(tspr->z + tspr->ownerActor->sx().position_offset.z);
f = ((globalorientation & 8) && (tspr->ownerActor->s().cstat & 48) != 0) ? -4.f : 4.f;
k0 -= (tspr->yoffset * tspr->yrepeat) * f * m->bscale;
zoff = m->siz.z * .5f;
if (!(tspr->cstat & 128))
@ -3851,8 +3812,8 @@ int32_t polymost_voxdraw(voxmodel_t* m, tspriteptr_t const tspr, bool rotate)
int const shadowHack = !!(tspr->clipdist & TSPR_FLAGS_MDHACK);
m0.Y *= f; a0.Y = (((float)(tspr->x + spriteext[tspr->owner].position_offset.x - globalposx)) * (1.f / 1024.f) + a0.Y) * f;
m0.X *= -f; a0.X = (((float)(tspr->y + spriteext[tspr->owner].position_offset.y - globalposy)) * -(1.f / 1024.f) + a0.X) * -f;
m0.Y *= f; a0.Y = (((float)(tspr->x + ownerActor->sx().position_offset.x - globalposx)) * (1.f / 1024.f) + a0.Y) * f;
m0.X *= -f; a0.X = (((float)(tspr->y + ownerActor->sx().position_offset.y - globalposy)) * -(1.f / 1024.f) + a0.X) * -f;
m0.Z *= g; a0.Z = (((float)(k0 - globalposz - shadowHack)) * -(1.f / 16384.f) + a0.Z) * g;
float mat[16];
@ -3884,11 +3845,11 @@ int32_t polymost_voxdraw(voxmodel_t* m, tspriteptr_t const tspr, bool rotate)
if (!shadowHack)
{
pc[3] = (tspr->cstat & 2) ? glblend[tspr->blend].def[!!(tspr->cstat & 512)].alpha : 1.0f;
pc[3] *= 1.0f - spriteext[tspr->owner].alpha;
pc[3] *= 1.0f - tspr->ownerActor->sx().alpha;
SetRenderStyleFromBlend(!!(tspr->cstat & 2), tspr->blend, !!(tspr->cstat & 512));
if (!(tspr->cstat & 2) || spriteext[tspr->owner].alpha > 0.f || pc[3] < 1.0f)
if (!(tspr->cstat & 2) || tspr->ownerActor->sx().alpha > 0.f || pc[3] < 1.0f)
GLInterface.EnableBlend(true); // else GLInterface.EnableBlend(false);
}
else pc[3] = 1.f;
@ -3948,7 +3909,7 @@ int32_t polymost_voxdraw(voxmodel_t* m, tspriteptr_t const tspr, bool rotate)
RenderStyle = LegacyRenderStyles[STYLE_Translucent];
alpha = 1.f;
}
alpha *= 1.f - spriteext[tspr->owner].alpha;
alpha *= 1.f - tspr->ownerActor->sx().alpha;
GLInterface.SetRenderStyle(RenderStyle);
GLInterface.SetColor(pc[0], pc[1], pc[2], alpha);

View file

@ -327,3 +327,14 @@ inline int pushmove(vec3_t* const vect, sectortype** const sect, int32_t const w
*sect = sectno == -1 ? nullptr : &sector[sectno];
return res;
}
inline tspriteptr_t renderAddTsprite(tspritetype* tsprite, int& spritesortcnt, DCoreActor* actor)
{
if (spritesortcnt >= MAXSPRITESONSCREEN) return nullptr;
auto tspr = &tsprite[spritesortcnt++];
tspr->copyfrom(&actor->s());
tspr->clipdist = 0;
tspr->ownerActor = actor;
return tspr;
}

View file

@ -182,7 +182,7 @@ void PlanesAtPoint(const sectortype* sec, int dax, int day, float* pceilz, float
//
//==========================================================================
void GetWallSpritePosition(const spritetype* spr, vec2_t pos, vec2_t* out, bool render)
void GetWallSpritePosition(const tspritetype* spr, vec2_t pos, vec2_t* out, bool render)
{
auto tex = tileGetTexture(spr->picnum);
@ -218,7 +218,8 @@ void GetWallSpritePosition(const spritetype* spr, vec2_t pos, vec2_t* out, bool
//
//==========================================================================
void GetFlatSpritePosition(const spritetype* spr, vec2_t pos, vec2_t* out, bool render)
template<class sprt>
void TGetFlatSpritePosition(const sprt* spr, vec2_t pos, vec2_t* out, bool render)
{
auto tex = tileGetTexture(spr->picnum);
@ -258,6 +259,15 @@ void GetFlatSpritePosition(const spritetype* spr, vec2_t pos, vec2_t* out, bool
out[3] = out[0] - sub;
}
void GetFlatSpritePosition(const spritetype* spr, vec2_t pos, vec2_t* out, bool render)
{
TGetFlatSpritePosition(spr, pos, out, render);
}
void GetFlatSpritePosition(const tspritetype* spr, vec2_t pos, vec2_t* out, bool render)
{
TGetFlatSpritePosition(spr, pos, out, render);
}
//==========================================================================
//

View file

@ -124,7 +124,8 @@ inline void PlanesAtPoint(const sectortype* sec, float dax, float day, float* ce
PlanesAtPoint(sec, int(dax), int(day), ceilz, florz);
}
void setWallSectors();
void GetWallSpritePosition(const spritetype* spr, vec2_t pos, vec2_t* out, bool render = false);
void GetWallSpritePosition(const tspritetype* spr, vec2_t pos, vec2_t* out, bool render = false);
void GetFlatSpritePosition(const tspritetype* spr, vec2_t pos, vec2_t* out, bool render = false);
void GetFlatSpritePosition(const spritetype* spr, vec2_t pos, vec2_t* out, bool render = false);
void checkRotatedWalls();
@ -232,6 +233,11 @@ inline void copyfloorpal(spritetype* spr, const sectortype* sect)
if (!lookups.noFloorPal(sect->floorpal)) spr->pal = sect->floorpal;
}
inline void copyfloorpal(tspritetype* spr, const sectortype* sect)
{
if (!lookups.noFloorPal(sect->floorpal)) spr->pal = sect->floorpal;
}
inline void spriteSetSlope(spritetype* spr, int heinum)
{
if (spr->cstat & CSTAT_SPRITE_ALIGNMENT_FLOOR)

View file

@ -14,6 +14,7 @@ class FSerializer;
struct FRenderViewpoint;
struct spritetype;
struct sectortype;
struct tspritetype;
struct GameStats
{
@ -115,7 +116,7 @@ struct GameInterface
virtual int chaseCamX(binangle ang) { return 0; }
virtual int chaseCamY(binangle ang) { return 0; }
virtual int chaseCamZ(fixedhoriz horiz) { return 0; }
virtual void processSprites(spritetype* tsprite, int& spritesortcnt, int viewx, int viewy, int viewz, binangle viewang, double smoothRatio) = 0;
virtual void processSprites(tspritetype* tsprite, int& spritesortcnt, int viewx, int viewy, int viewz, binangle viewang, double smoothRatio) = 0;
virtual void UpdateCameras(double smoothratio) {}
virtual void EnterPortal(spritetype* viewer, int type) {}
virtual void LeavePortal(spritetype* viewer, int type) {}

View file

@ -387,7 +387,7 @@ void insertAllSprites(SpawnSpriteDef& sprites)
removeit = true;
}
insertsprite(spr.sectnum, spr.statnum);
insertsprite(spr.sectnum, spr.statnum, true);
if (removeit)
{
@ -435,7 +435,6 @@ void allocateMapArrays(int numsprites)
memset(spritesmooth, 0, sizeof(spritesmooth_t) * (MAXSPRITES + MAXUNIQHUDID));
ClearAutomap();
Polymost::Polymost_prepare_loadboard();
}
void engineLoadBoard(const char* filename, int flags, vec3_t* pos, int16_t* ang, int* cursectnum, SpawnSpriteDef& sprites)
@ -471,6 +470,7 @@ void engineLoadBoard(const char* filename, int flags, vec3_t* pos, int16_t* ang,
allocateMapArrays(numsprites);
initspritelists(); // may not be used in Blood!
sprites.sprites.Resize(numsprites);
memset(sprites.sprites.Data(), 0, numsprites * sizeof(spritetype));
// Now load the actual data.
fr.Seek(sectorpos, FileReader::SeekSet);

View file

@ -44,6 +44,7 @@
#include "mapinfo.h"
#include "gamecontrol.h"
#include "hw_sections.h"
#include "coreactor.h"
extern TArray<TArray<int>> blockingpairs;
//==========================================================================
@ -559,15 +560,14 @@ void BunchDrawer::ProcessSection(int sectionnum, bool portal)
SetupSprite.Clock();
int z;
int sectnum = sections[sectionnum].sector;
if (!gotsector[sectnum])
{
gotsector.Set(sectnum);
SectIterator it(sectnum);
while ((z = it.NextIndex()) >= 0)
CoreSectIterator it(sectnum);
while (auto actor = it.Next())
{
auto const spr = (uspriteptr_t)&sprite[z];
auto const spr = &actor->s();
if ((spr->cstat & CSTAT_SPRITE_INVISIBLE) || spr->xrepeat == 0 || spr->yrepeat == 0) // skip invisible sprites
continue;
@ -581,7 +581,7 @@ void BunchDrawer::ProcessSection(int sectionnum, bool portal)
(r_voxels && tiletovox[spr->picnum] >= 0 && voxmodels[tiletovox[spr->picnum]]) ||
(r_voxels && gi->Voxelize(spr->picnum) > -1) ||
DMulScale(bcos(spr->ang), -sx, bsin(spr->ang), -sy, 6) > 0)
if (renderAddTsprite(di->tsprite, di->spritesortcnt, z, sectnum))
if (!renderAddTsprite(di->tsprite, di->spritesortcnt, actor))
break;
}
}

View file

@ -42,6 +42,7 @@
#include "gamestruct.h"
#include "automap.h"
#include "hw_voxels.h"
#include "coreactor.h"
EXTERN_CVAR(Float, r_visibility)
CVAR(Bool, gl_no_skyclear, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
@ -276,19 +277,18 @@ void HWDrawInfo::DispatchSprites()
{
auto tspr = &tsprite[i];
int tilenum = tspr->picnum;
int spritenum = tspr->owner;
auto actor = tspr->ownerActor;
if (spritenum < 0 || (unsigned)tilenum >= MAXTILES)
if (actor == nullptr || tspr->xrepeat == 0 || tspr->yrepeat == 0 || tilenum >= MAXTILES)
continue;
if ((unsigned)spritenum < MAXSPRITES)
sprite[spritenum].cstat2 |= CSTAT2_SPRITE_MAPPED;
actor->s().cstat2 |= CSTAT2_SPRITE_MAPPED;
tileUpdatePicnum(&tilenum, sprite->owner + 32768, 0);
tileUpdatePicnum(&tilenum, (actor->GetIndex() & 16383) + 32768, 0);
tspr->picnum = tilenum;
setgotpic(tilenum);
if (!(spriteext[spritenum].flags & SPREXT_NOTMD))
if (!(actor->sx().flags & SPREXT_NOTMD))
{
int pt = Ptile2tile(tilenum, tspr->pal);
if (hw_models && tile2model[pt].modelid >= 0 && tile2model[pt].framenum >= 0)
@ -315,12 +315,12 @@ void HWDrawInfo::DispatchSprites()
}
}
if (spriteext[spritenum].flags & SPREXT_AWAY1)
if (actor->sx().flags & SPREXT_AWAY1)
{
tspr->pos.x += bcos(tspr->ang, -13);
tspr->pos.y += bsin(tspr->ang, -13);
}
else if (spriteext[spritenum].flags & SPREXT_AWAY2)
else if (actor->sx().flags & SPREXT_AWAY2)
{
tspr->pos.x -= bcos(tspr->ang, -13);
tspr->pos.y -= bsin(tspr->ang, -13);
@ -377,6 +377,7 @@ void HWDrawInfo::CreateScene(bool portal)
screen->mVertexData->Map();
screen->mLights->Map();
memset(tsprite, 0, sizeof(tsprite));
spritesortcnt = 0;
ingeo = false;
geoofs = { 0,0 };

View file

@ -108,7 +108,7 @@ struct HWDrawInfo
FRenderViewpoint Viewpoint;
HWViewpointUniforms VPUniforms; // per-viewpoint uniform state
TArray<HWPortal *> Portals;
spritetype tsprite[MAXSPRITESONSCREEN];
tspritetype tsprite[MAXSPRITESONSCREEN];
int spritesortcnt;
// This is needed by the BSP traverser.

View file

@ -14,6 +14,7 @@
#include "gamecontrol.h"
#include "hw_renderstate.h"
#include "hw_cvars.h"
#include "coreactor.h"
#ifdef _MSC_VER
#pragma warning(disable:4244) // this gets a bit annoying in the renderer...
@ -187,7 +188,7 @@ public:
public:
walltype* seg;
spritetype* Sprite;
tspritetype* Sprite;
sectortype* frontsector, * backsector;
//private:
@ -231,7 +232,7 @@ public:
public:
void Process(HWDrawInfo* di, walltype* seg, sectortype* frontsector, sectortype* backsector);
void ProcessWallSprite(HWDrawInfo* di, spritetype* spr, sectortype* frontsector);
void ProcessWallSprite(HWDrawInfo* di, tspritetype* spr, sectortype* frontsector);
float PointOnSide(float x,float y)
{
@ -253,7 +254,7 @@ class HWFlat
public:
int section;
sectortype * sec;
spritetype* Sprite; // for flat sprites.
tspritetype* Sprite; // for flat sprites.
FGameTexture *texture;
float z; // the z position of the flat (only valid for non-sloped planes)
@ -279,7 +280,7 @@ public:
void PutFlat(HWDrawInfo* di, int whichplane);
void ProcessSector(HWDrawInfo *di, sectortype * frontsector, int sectionnum, int which = 7 /*SSRF_RENDERALL*/); // cannot use constant due to circular dependencies.
void ProcessFlatSprite(HWDrawInfo* di, spritetype* sprite, sectortype* sector);
void ProcessFlatSprite(HWDrawInfo* di, tspritetype* sprite, sectortype* sector);
void DrawSubsectors(HWDrawInfo *di, FRenderState &state);
void DrawFlat(HWDrawInfo* di, FRenderState& state, bool translucent);
@ -296,7 +297,7 @@ class HWSprite
{
public:
spritetype* Sprite;
tspritetype* Sprite;
PalEntry fade;
int shade, palette;
float visibility;
@ -334,8 +335,8 @@ public:
void CreateVertices(HWDrawInfo* di);
void PutSprite(HWDrawInfo *di, bool translucent);
void Process(HWDrawInfo *di, spritetype* thing,sectortype * sector, int thruportal = false);
bool ProcessVoxel(HWDrawInfo* di, voxmodel_t* voxel, spritetype* tspr, sectortype* sector, bool rotate);
void Process(HWDrawInfo *di, tspritetype* thing,sectortype * sector, int thruportal = false);
bool ProcessVoxel(HWDrawInfo* di, voxmodel_t* voxel, tspritetype* tspr, sectortype* sector, bool rotate);
void DrawSprite(HWDrawInfo* di, FRenderState& state, bool translucent);
};
@ -372,16 +373,16 @@ inline bool maskWallHasTranslucency(const walltype* wall)
return (wall->cstat & CSTAT_WALL_TRANSLUCENT) || checkTranslucentReplacement(tileGetTexture(wall->picnum)->GetID(), wall->pal);
}
inline bool spriteHasTranslucency(const spritetype* tspr)
inline bool spriteHasTranslucency(const tspritetype* tspr)
{
if ((tspr->cstat & CSTAT_SPRITE_TRANSLUCENT) || //(tspr->clipdist & TSPR_FLAGS_DRAW_LAST) ||
((unsigned)tspr->owner < MAXSPRITES && spriteext[tspr->owner].alpha))
(tspr->ownerActor->sx().alpha))
return true;
return checkTranslucentReplacement(tileGetTexture(tspr->picnum)->GetID(), tspr->pal);
}
inline void SetSpriteTranslucency(const spritetype* sprite, float& alpha, FRenderStyle& RenderStyle)
inline void SetSpriteTranslucency(const tspritetype* sprite, float& alpha, FRenderStyle& RenderStyle)
{
bool trans = (sprite->cstat & CSTAT_SPRITE_TRANSLUCENT);
if (trans)
@ -394,7 +395,7 @@ inline void SetSpriteTranslucency(const spritetype* sprite, float& alpha, FRende
RenderStyle = LegacyRenderStyles[STYLE_Translucent];
alpha = 1.f;
}
alpha *= 1.f - spriteext[sprite->owner].alpha;
alpha *= 1.f - sprite->ownerActor->sx().alpha;
}
//==========================================================================

View file

@ -346,7 +346,7 @@ void HWFlat::ProcessSector(HWDrawInfo *di, sectortype * frontsector, int section
}
}
void HWFlat::ProcessFlatSprite(HWDrawInfo* di, spritetype* sprite, sectortype* sector)
void HWFlat::ProcessFlatSprite(HWDrawInfo* di, tspritetype* sprite, sectortype* sector)
{
int tilenum = sprite->picnum;
texture = tileGetTexture(tilenum);

View file

@ -311,7 +311,7 @@ inline void HWSprite::PutSprite(HWDrawInfo* di, bool translucent)
//
//==========================================================================
void HWSprite::Process(HWDrawInfo* di, spritetype* spr, sectortype* sector, int thruportal)
void HWSprite::Process(HWDrawInfo* di, tspritetype* spr, sectortype* sector, int thruportal)
{
if (spr == nullptr)
return;
@ -445,10 +445,10 @@ void HWSprite::Process(HWDrawInfo* di, spritetype* spr, sectortype* sector, int
//
//==========================================================================
bool HWSprite::ProcessVoxel(HWDrawInfo* di, voxmodel_t* vox, spritetype* spr, sectortype* sector, bool rotate)
bool HWSprite::ProcessVoxel(HWDrawInfo* di, voxmodel_t* vox, tspritetype* spr, sectortype* sector, bool rotate)
{
Sprite = spr;
auto sprext = &spriteext[spr->owner];
auto sprext = &spr->ownerActor->sx();
texture = nullptr;
modelframe = -1;
@ -477,7 +477,7 @@ bool HWSprite::ProcessVoxel(HWDrawInfo* di, voxmodel_t* vox, spritetype* spr, se
float basescale = voxel->bscale / 64.f;
float sprxscale = (float)spr->xrepeat * (256.f / 320.f) * basescale;
if ((::sprite[spr->owner].cstat & CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_WALL)
if ((spr->ownerActor->s().cstat & CSTAT_SPRITE_ALIGNMENT) == CSTAT_SPRITE_ALIGNMENT_WALL)
{
sprxscale *= 1.25f;
translatevec.Y -= spr->xoffset * bcosf(sprext->angoff, -20);
@ -505,7 +505,7 @@ bool HWSprite::ProcessVoxel(HWDrawInfo* di, voxmodel_t* vox, spritetype* spr, se
translatevec.Z *= sprzscale;
float zpos = (float)(spr->z + sprext->position_offset.z);
float zscale = ((spr->cstat & CSTAT_SPRITE_YFLIP) && (::sprite[spr->owner].cstat & CSTAT_SPRITE_ALIGNMENT) != 0) ? -4.f : 4.f;
float zscale = ((spr->cstat & CSTAT_SPRITE_YFLIP) && (spr->ownerActor->s().cstat & CSTAT_SPRITE_ALIGNMENT) != 0) ? -4.f : 4.f;
zpos -= (spr->yoffset * spr->yrepeat) * zscale * voxel->bscale;
x = (spr->x + sprext->position_offset.x) * (1 / 16.f);

View file

@ -46,7 +46,7 @@
//
//==========================================================================
static int GetClosestPointOnWall(spritetype* spr, walltype* wal, vec2_t* const n)
static int GetClosestPointOnWall(tspritetype* spr, walltype* wal, vec2_t* const n)
{
auto w = wal->pos;
auto d = wal->point2Wall()->pos - w;
@ -106,7 +106,7 @@ static int GetClosestPointOnWall(spritetype* spr, walltype* wal, vec2_t* const n
//
//==========================================================================
static int IsOnWall(spritetype* tspr, int height)
static int IsOnWall(tspritetype* tspr, int height)
{
int dist = 3, closest = -1;
auto sect = tspr->sector();
@ -1124,7 +1124,7 @@ void HWWall::Process(HWDrawInfo* di, walltype* wal, sectortype* frontsector, sec
}
}
void HWWall::ProcessWallSprite(HWDrawInfo* di, spritetype* spr, sectortype* sector)
void HWWall::ProcessWallSprite(HWDrawInfo* di, tspritetype* spr, sectortype* sector)
{
auto tex = tileGetTexture(spr->picnum);
if (!tex || !tex->isValid()) return;

View file

@ -49,7 +49,7 @@ void collectTSpritesForPortal(int x, int y, int i, int interpolation)
pTSprite->yoffset = pSprite->yoffset;
pTSprite->cstat = pSprite->cstat;
pTSprite->statnum = kStatDecoration;
pTSprite->owner = actor->GetSpriteIndex();
pTSprite->ownerActor = actor;
pTSprite->flags = pSprite->hitag | 0x200;
pTSprite->x = dx + interpolatedvalue(pSprite->ox, pSprite->x, interpolation);
pTSprite->y = dy + interpolatedvalue(pSprite->oy, pSprite->y, interpolation);

View file

@ -67,7 +67,7 @@ static void RotateXZ(int *pX, int *, int *pZ, int ang)
*pZ = dmulscale30r(oX,angSin,oZ,angCos);
}
tspritetype* viewInsertTSprite(spritetype* tsprite, int& spritesortcnt, sectortype* pSector, int nStatnum, tspritetype const * const parentTSprite)
tspritetype* viewInsertTSprite(tspritetype* tsprite, int& spritesortcnt, sectortype* pSector, int nStatnum, tspritetype const * const parentTSprite)
{
if (spritesortcnt >= MAXSPRITESONSCREEN)
return nullptr;
@ -78,17 +78,15 @@ tspritetype* viewInsertTSprite(spritetype* tsprite, int& spritesortcnt, sectorty
pTSprite->cstat = 128;
pTSprite->xrepeat = 64;
pTSprite->yrepeat = 64;
pTSprite->owner = -1;
pTSprite->ownerActor = nullptr;
pTSprite->type = -spritesortcnt;
pTSprite->statnum = nStatnum;
pTSprite->setsector(pSector);
spritesortcnt++;
if (parentTSprite)
{
pTSprite->x = parentTSprite->x;
pTSprite->y = parentTSprite->y;
pTSprite->z = parentTSprite->z;
pTSprite->owner = parentTSprite->owner;
pTSprite->pos = parentTSprite->pos;
pTSprite->ownerActor = parentTSprite->ownerActor;
pTSprite->ang = parentTSprite->ang;
}
pTSprite->x += Cos(gCameraAng)>>25;
@ -124,11 +122,11 @@ static const WEAPONICON gWeaponIcon[] = {
};
static tspritetype *viewAddEffect(spritetype* tsprite, int& spritesortcnt, int nTSprite, VIEW_EFFECT nViewEffect)
static tspritetype *viewAddEffect(tspritetype* tsprite, int& spritesortcnt, int nTSprite, VIEW_EFFECT nViewEffect)
{
assert(nViewEffect >= 0 && nViewEffect < kViewEffectMax);
auto pTSprite = &tsprite[nTSprite];
auto owneractor = &bloodActors[pTSprite->owner];
auto owneractor = static_cast<DBloodActor*>(pTSprite->ownerActor);
if (gDetail < effectDetail[nViewEffect] || nTSprite >= MAXSPRITESONSCREEN) return NULL;
switch (nViewEffect)
{
@ -281,7 +279,7 @@ static tspritetype *viewAddEffect(spritetype* tsprite, int& spritesortcnt, int n
assert(pSector);
FindSector(pNSprite->x, pNSprite->y, pNSprite->z, &pSector);
pNSprite->setsector(pSector);
pNSprite->owner = pTSprite->owner;
pNSprite->ownerActor = pTSprite->ownerActor;
pNSprite->picnum = pTSprite->picnum;
pNSprite->cstat |= 2;
if (i < 2)
@ -424,7 +422,7 @@ static tspritetype *viewAddEffect(spritetype* tsprite, int& spritesortcnt, int n
pNSprite->xrepeat = pNSprite->yrepeat = 64;
pNSprite->cstat |= 106;
pNSprite->ang = pTSprite->ang;
pNSprite->owner = pTSprite->owner;
pNSprite->ownerActor = pTSprite->ownerActor;
break;
}
case kViewEffectFloorGlow:
@ -444,7 +442,7 @@ static tspritetype *viewAddEffect(spritetype* tsprite, int& spritesortcnt, int n
pNSprite->xrepeat = pNSprite->yrepeat = nShade;
pNSprite->cstat |= 98;
pNSprite->ang = pTSprite->ang;
pNSprite->owner = pTSprite->owner;
pNSprite->ownerActor = pTSprite->ownerActor;
break;
}
case kViewEffectSpear:
@ -511,7 +509,7 @@ static void viewApplyDefaultPal(tspritetype *pTSprite, sectortype const *pSector
}
}
void viewProcessSprites(spritetype* tsprite, int& spritesortcnt, int32_t cX, int32_t cY, int32_t cZ, int32_t cA, int32_t smoothratio)
void viewProcessSprites(tspritetype* tsprite, int& spritesortcnt, int32_t cX, int32_t cY, int32_t cZ, int32_t cA, int32_t smoothratio)
{
// shift before interpolating to increase precision.
int myclock = (PlayClock<<3) + MulScale(4<<3, smoothratio, 16);
@ -521,9 +519,9 @@ void viewProcessSprites(spritetype* tsprite, int& spritesortcnt, int32_t cX, int
for (int nTSprite = spritesortcnt-1; nTSprite >= 0; nTSprite--)
{
tspritetype *pTSprite = &tsprite[nTSprite];
auto owneractor = &bloodActors[pTSprite->owner];
auto owneractor = static_cast<DBloodActor*>(pTSprite->ownerActor);
XSPRITE *pTXSprite = NULL;
if (sprite[pTSprite->owner].detail > gDetail)
if (owneractor->s().detail > gDetail)
{
pTSprite->xrepeat = 0;
continue;
@ -547,7 +545,6 @@ void viewProcessSprites(spritetype* tsprite, int& spritesortcnt, int32_t cX, int
continue;
}
int nSprite = pTSprite->owner;
if (cl_interpolate && owneractor->interpolated && !(pTSprite->flags&512))
{
pTSprite->pos = pTSprite->interpolatedvec3(gInterpolate);
@ -569,7 +566,7 @@ void viewProcessSprites(spritetype* tsprite, int& spritesortcnt, int32_t cX, int
break;
case 1:
{
if (tilehasmodelorvoxel(pTSprite->picnum, pTSprite->pal) && !(spriteext[nSprite].flags&SPREXT_NOTMD))
if (tilehasmodelorvoxel(pTSprite->picnum, pTSprite->pal) && !(owneractor->sx().flags&SPREXT_NOTMD))
{
pTSprite->cstat &= ~4;
break;
@ -591,7 +588,7 @@ void viewProcessSprites(spritetype* tsprite, int& spritesortcnt, int32_t cX, int
}
case 2:
{
if (tilehasmodelorvoxel(pTSprite->picnum, pTSprite->pal) && !(spriteext[nSprite].flags&SPREXT_NOTMD))
if (tilehasmodelorvoxel(pTSprite->picnum, pTSprite->pal) && !(owneractor->sx().flags&SPREXT_NOTMD))
{
pTSprite->cstat &= ~4;
break;
@ -621,11 +618,11 @@ void viewProcessSprites(spritetype* tsprite, int& spritesortcnt, int32_t cX, int
case 6:
case 7:
{
if (hw_models && md_tilehasmodel(pTSprite->picnum, pTSprite->pal) >= 0 && !(spriteext[nSprite].flags&SPREXT_NOTMD))
if (hw_models && md_tilehasmodel(pTSprite->picnum, pTSprite->pal) >= 0 && !(owneractor->sx().flags&SPREXT_NOTMD))
break;
// Can be overridden by def script
if (r_voxels && tiletovox[pTSprite->picnum] == -1 && voxelIndex[pTSprite->picnum] != -1 && !(spriteext[nSprite].flags&SPREXT_NOTMD))
if (r_voxels && tiletovox[pTSprite->picnum] == -1 && voxelIndex[pTSprite->picnum] != -1 && !(owneractor->sx().flags&SPREXT_NOTMD))
{
if ((pTSprite->flags&kHitagRespawn) == 0)
{
@ -648,10 +645,10 @@ void viewProcessSprites(spritetype* tsprite, int& spritesortcnt, int32_t cX, int
nAnim--;
}
if ((pTSprite->cstat&48) != 48 && r_voxels && !(spriteext[nSprite].flags&SPREXT_NOTMD))
if ((pTSprite->cstat&48) != 48 && r_voxels && !(owneractor->sx().flags&SPREXT_NOTMD))
{
int const nRootTile = pTSprite->picnum;
int nAnimTile = pTSprite->picnum + animateoffs_replace(pTSprite->picnum, 32768+pTSprite->owner);
int nAnimTile = pTSprite->picnum + qanimateoffs(pTSprite->picnum, 32768 + (pTSprite->ownerActor->GetIndex() & 16383));
#if 0
if (tiletovox[nAnimTile] != -1)
@ -667,10 +664,10 @@ void viewProcessSprites(spritetype* tsprite, int& spritesortcnt, int32_t cX, int
pTSprite->cstat2 |= CSTAT2_SPRITE_MDLROTATE; // per-sprite rotation setting.
}
if ((pTSprite->cstat&48) != 48 && hw_models && !(spriteext[nSprite].flags&SPREXT_NOTMD))
if ((pTSprite->cstat&48) != 48 && hw_models && !(owneractor->sx().flags&SPREXT_NOTMD))
{
int const nRootTile = pTSprite->picnum;
int nAnimTile = pTSprite->picnum + animateoffs_replace(pTSprite->picnum, 32768+pTSprite->owner);
int nAnimTile = pTSprite->picnum + qanimateoffs(pTSprite->picnum, 32768 + (pTSprite->ownerActor->GetIndex() & 16383));
if (tile2model[Ptile2tile(nAnimTile, pTSprite->pal)].modelid >= 0 &&
tile2model[Ptile2tile(nAnimTile, pTSprite->pal)].framenum >= 0)
@ -697,7 +694,7 @@ void viewProcessSprites(spritetype* tsprite, int& spritesortcnt, int32_t cX, int
}
nShade += tileShade[pTSprite->picnum];
pTSprite->shade = ClipRange(nShade, -128, 127);
if ((pTSprite->flags&kHitagRespawn) && sprite[pTSprite->owner].owner == 3)
if ((pTSprite->flags&kHitagRespawn) && pTSprite->ownerActor->s().owner == 3) // Where does this 3 come from? Nothing sets it.
{
assert(pTXSprite != NULL);
pTSprite->xrepeat = 48;
@ -892,7 +889,7 @@ void viewProcessSprites(spritetype* tsprite, int& spritesortcnt, int32_t cX, int
}
}
if (pTSprite->owner != gView->actor->GetSpriteIndex() || gViewPos != VIEWPOS_0) {
if (pTSprite->ownerActor != gView->actor || gViewPos != VIEWPOS_0) {
if (getflorzofslopeptr(pTSprite->sector(), pTSprite->x, pTSprite->y) >= cZ)
{
viewAddEffect(tsprite, spritesortcnt, nTSprite, kViewEffectShadow);
@ -974,7 +971,7 @@ void viewProcessSprites(spritetype* tsprite, int& spritesortcnt, int32_t cX, int
}
void GameInterface::processSprites(spritetype* tsprite, int& spritesortcnt, int viewx, int viewy, int viewz, binangle viewang, double smoothRatio)
void GameInterface::processSprites(tspritetype* tsprite, int& spritesortcnt, int viewx, int viewy, int viewz, binangle viewang, double smoothRatio)
{
viewProcessSprites(tsprite, spritesortcnt, viewx, viewy, viewz, viewang.asbuild(), int(smoothRatio));
}

View file

@ -150,7 +150,7 @@ struct GameInterface : public ::GameInterface
int chaseCamX(binangle ang) override { return MulScale(-Cos(ang.asbuild()), 1280, 30); }
int chaseCamY(binangle ang) override { return MulScale(-Sin(ang.asbuild()), 1280, 30); }
int chaseCamZ(fixedhoriz horiz) override { return FixedToInt(MulScale(horiz.asq16(), 1280, 3)) - (16 << 8); }
void processSprites(spritetype* tsprite, int& spritesortcnt, int viewx, int viewy, int viewz, binangle viewang, double smoothRatio) override;
void processSprites(tspritetype* tsprite, int& spritesortcnt, int viewx, int viewy, int viewz, binangle viewang, double smoothRatio) override;
void EnterPortal(spritetype* viewer, int type) override;
void LeavePortal(spritetype* viewer, int type) override;
void LoadGameTextures() override;

View file

@ -352,10 +352,6 @@ void dbLoadMap(const char* pPath, int* pX, int* pY, int* pZ, short* pAngle, sect
#endif
#ifdef USE_OPENGL
Polymost::Polymost_prepare_loadboard();
#endif
FString mapname = pPath;
DefaultExtension(mapname, ".map");
auto fr = fileSystem.OpenFileReader(mapname);

View file

@ -751,7 +751,6 @@ void GameInterface::SerializeGameState(FSerializer& arc)
viewSetErrorMessage("");
Net_ClearFifo();
paused = 0;
Polymost::Polymost_prepare_loadboard();
Mus_ResumeSaved();
}
validateLinks();

View file

@ -66,7 +66,6 @@ int32_t qchangespritesect(int16_t nSprite, int16_t nSector);
void HookReplaceFunctions(void)
{
animateoffs_replace = qanimateoffs;
initspritelists_replace = qinitspritelists;
changespritesect_replace = qchangespritesect;
}

View file

@ -147,7 +147,7 @@ void viewCorrectViewOffsets(int nPlayer, vec3_t const *oldpos);
void InitStatusBar(void);
void UpdateStatusBar();
void viewInit(void);
void viewProcessSprites(spritetype* tsprite, int& spritesortcnt, int32_t cX, int32_t cY, int32_t cZ, int32_t cA, int32_t smooth);
void viewprocessSprites(tspritetype* tsprite, int& spritesortcnt, int32_t cX, int32_t cY, int32_t cZ, int32_t cA, int32_t smooth);
void viewSetMessage(const char *pMessage, const int pal = 0, const MESSAGE_PRIORITY priority = MESSAGE_PRIORITY_NORMAL);

View file

@ -44,9 +44,9 @@ EXTERN_CVAR(Bool, wt_commentary)
BEGIN_DUKE_NS
void animatesprites_d(spritetype* tsprite, int& spritesortcnt, int x, int y, int a, int smoothratio)
void animatesprites_d(tspritetype* tsprite, int& spritesortcnt, int x, int y, int a, int smoothratio)
{
int i, j, k, p;
int j, k, p;
int l, t1, t3, t4;
spritetype* s;
tspritetype* t;
@ -55,8 +55,7 @@ void animatesprites_d(spritetype* tsprite, int& spritesortcnt, int x, int y, int
for (j = 0; j < spritesortcnt; j++)
{
t = &tsprite[j];
i = t->owner;
h = &hittype[i];
h = static_cast<DDukeActor*>(t->ownerActor);
s = h->s;
switch (t->picnum)
@ -130,7 +129,7 @@ void animatesprites_d(spritetype* tsprite, int& spritesortcnt, int x, int y, int
case GREENSLIME + 7:
break;
default:
if (((t->cstat & 16)) || (badguy(t) && t->extra > 0) || t->statnum == 10)
if (((t->cstat & 16)) || (badguypic(t->picnum) && t->extra > 0) || t->statnum == 10)
continue;
}
@ -143,8 +142,7 @@ void animatesprites_d(spritetype* tsprite, int& spritesortcnt, int x, int y, int
for (j = 0; j < spritesortcnt; j++)
{
t = &tsprite[j];
i = t->owner;
h = &hittype[i];
h = static_cast<DDukeActor*>(t->ownerActor);
s = h->s;
auto OwnerAc = h->GetOwner();
auto Owner = OwnerAc ? OwnerAc->s : nullptr;
@ -334,8 +332,8 @@ void animatesprites_d(spritetype* tsprite, int& spritesortcnt, int x, int y, int
if ((display_mirror == 1 || screenpeek != p || !h->GetOwner()) && ud.multimode > 1 && cl_showweapon && ps[p].GetActor()->s->extra > 0 && ps[p].curr_weapon > 0)
{
auto newtspr = &tsprite[spritesortcnt];
memcpy(newtspr, t, sizeof(spritetype));
auto newtspr = &tsprite[spritesortcnt++];
newtspr = t;
newtspr->statnum = 99;
@ -378,7 +376,6 @@ void animatesprites_d(spritetype* tsprite, int& spritesortcnt, int x, int y, int
newtspr->yrepeat = 16;
}
newtspr->pal = 0;
spritesortcnt++;
}
if (!h->GetOwner())
@ -427,7 +424,7 @@ void animatesprites_d(spritetype* tsprite, int& spritesortcnt, int x, int y, int
if (h->GetOwner() && display_mirror == 0 && ps[p].over_shoulder_on == 0)
if (ud.multimode < 2 || (ud.multimode > 1 && p == screenpeek))
{
t->owner = -1;
t->ownerActor = nullptr;
t->xrepeat = t->yrepeat = 0;
continue;
}
@ -592,7 +589,7 @@ void animatesprites_d(spritetype* tsprite, int& spritesortcnt, int x, int y, int
if ((s->z - daz) < (8 << 8) && ps[screenpeek].pos.z < daz)
{
auto shadowspr = &tsprite[spritesortcnt];
auto shadowspr = &tsprite[spritesortcnt++];
*shadowspr = *t;
shadowspr->statnum = 99;
@ -620,7 +617,6 @@ void animatesprites_d(spritetype* tsprite, int& spritesortcnt, int x, int y, int
shadowspr->x += bcos(look, -9);
shadowspr->y += bsin(look, -9);
}
spritesortcnt++;
}
}
@ -717,7 +713,7 @@ void animatesprites_d(spritetype* tsprite, int& spritesortcnt, int x, int y, int
if (ud.cameraactor == nullptr)
if (screenpeek == Owner->yvel && display_mirror == 0)
{
t->owner = -1;
t->ownerActor = nullptr;
break;
}
if ((Owner->cstat & 32768) == 0)

View file

@ -37,9 +37,9 @@ Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
BEGIN_DUKE_NS
void animatesprites_r(spritetype* tsprite, int& spritesortcnt, int x, int y, int a, int smoothratio)
void animatesprites_r(tspritetype* tsprite, int& spritesortcnt, int x, int y, int a, int smoothratio)
{
int i, j, k, p;
int j, k, p;
int l, t1, t3, t4;
spritetype* s;
tspritetype* t;
@ -50,8 +50,7 @@ void animatesprites_r(spritetype* tsprite, int& spritesortcnt, int x, int y, int
for (j = 0; j < spritesortcnt; j++)
{
t = &tsprite[j];
i = t->owner;
h = &hittype[i];
h = static_cast<DDukeActor*>(t->ownerActor);
s = h->s;
switch (t->picnum)
@ -108,7 +107,7 @@ void animatesprites_r(spritetype* tsprite, int& spritesortcnt, int x, int y, int
case NEON6:
continue;
default:
if (((t->cstat & 16)) || (badguy(t) && t->extra > 0) || t->statnum == 10)
if (((t->cstat & 16)) || (badguypic(t->picnum) && t->extra > 0) || t->statnum == 10)
{
if (s->sector()->shadedsector == 1 && s->statnum != 1)
{
@ -128,8 +127,7 @@ void animatesprites_r(spritetype* tsprite, int& spritesortcnt, int x, int y, int
for (j = 0; j < spritesortcnt; j++)
{
t = &tsprite[j];
i = t->owner;
h = &hittype[i];
h = static_cast<DDukeActor*>(t->ownerActor);
s = h->s;
auto OwnerAc = h->GetOwner();
auto Owner = OwnerAc ? OwnerAc->s : nullptr;
@ -375,8 +373,8 @@ void animatesprites_r(spritetype* tsprite, int& spritesortcnt, int x, int y, int
if ((display_mirror == 1 || screenpeek != p || !h->GetOwner()) && ud.multimode > 1 && cl_showweapon && ps[p].GetActor()->s->extra > 0 && ps[p].curr_weapon > 0)
{
auto newtspr = &tsprite[spritesortcnt];
memcpy(newtspr, t, sizeof(spritetype));
auto newtspr = &tsprite[spritesortcnt++];
newtspr = t;
newtspr->statnum = 99;
@ -422,7 +420,6 @@ void animatesprites_r(spritetype* tsprite, int& spritesortcnt, int x, int y, int
newtspr->yrepeat = 16;
}
newtspr->pal = 0;
spritesortcnt++;
}
if (!h->GetOwner())
@ -470,7 +467,7 @@ void animatesprites_r(spritetype* tsprite, int& spritesortcnt, int x, int y, int
if (h->GetOwner() && display_mirror == 0 && ps[p].over_shoulder_on == 0)
if (ud.multimode < 2 || (ud.multimode > 1 && p == screenpeek))
{
t->owner = -1;
t->ownerActor = nullptr;
t->xrepeat = t->yrepeat = 0;
continue;
}
@ -747,7 +744,7 @@ void animatesprites_r(spritetype* tsprite, int& spritesortcnt, int x, int y, int
if ((s->z - daz) < (8 << 8))
if (ps[screenpeek].pos.z < daz)
{
auto shadowspr = &tsprite[spritesortcnt];
auto shadowspr = &tsprite[spritesortcnt++];
*shadowspr = *t;
shadowspr->statnum = 99;
@ -775,7 +772,6 @@ void animatesprites_r(spritetype* tsprite, int& spritesortcnt, int x, int y, int
shadowspr->x += bcos(look, -9);
shadowspr->y += bsin(look, -9);
}
spritesortcnt++;
}
}
}
@ -946,7 +942,7 @@ void animatesprites_r(spritetype* tsprite, int& spritesortcnt, int x, int y, int
if (ud.cameraactor == nullptr)
if (screenpeek == Owner->yvel && display_mirror == 0)
{
t->owner = -1;
t->ownerActor = nullptr;
break;
}
if ((Owner->cstat & 32768) == 0)

View file

@ -102,8 +102,8 @@ void displaymasks_d(int snum, int p, double smoothratio);
void displaymasks_r(int snum, int p, double smoothratio);
void think_d();
void think_r();
void animatesprites_d(spritetype* tsprite, int& spritesortcnt, int x, int y, int a, int smoothratio);
void animatesprites_r(spritetype* tsprite, int& spritesortcnt, int x, int y, int a, int smoothratio);
void animatesprites_d(tspritetype* tsprite, int& spritesortcnt, int x, int y, int a, int smoothratio);
void animatesprites_r(tspritetype* tsprite, int& spritesortcnt, int x, int y, int a, int smoothratio);
Dispatcher fi;

View file

@ -60,7 +60,7 @@ struct GameInterface : public ::GameInterface
int chaseCamX(binangle ang) { return -ang.bcos(-4); }
int chaseCamY(binangle ang) { return -ang.bsin(-4); }
int chaseCamZ(fixedhoriz horiz) { return horiz.asq16() >> 9; }
void processSprites(spritetype* tsprite, int& spritesortcnt, int viewx, int viewy, int viewz, binangle viewang, double smoothRatio) override;
void processSprites(tspritetype* tsprite, int& spritesortcnt, int viewx, int viewy, int viewz, binangle viewang, double smoothRatio) override;
void UpdateCameras(double smoothratio) override;
void EnterPortal(spritetype* viewer, int type) override;
void LeavePortal(spritetype* viewer, int type) override;
@ -113,7 +113,7 @@ struct Dispatcher
void (*displayweapon)(int snum, double smoothratio);
void (*displaymasks)(int snum, int p, double smoothratio);
void (*animatesprites)(spritetype* tsprite, int& spritesortcnt, int x, int y, int a, int smoothratio);
void (*animatesprites)(tspritetype* tsprite, int& spritesortcnt, int x, int y, int a, int smoothratio);
};

View file

@ -90,6 +90,14 @@ inline int ldist(const spritetype* s1, const spritetype* s2)
return(FindDistance2D(vx, vy) + 1);
}
inline int ldist(const spritetype* s1, const tspritetype* s2)
{
int vx, vy;
vx = s1->x - s2->x;
vy = s1->y - s2->y;
return(FindDistance2D(vx, vy) + 1);
}
inline int dist(const spritetype* s1, const spritetype* s2)
{
int vx, vy, vz;

View file

@ -433,7 +433,7 @@ bool GameInterface::GenerateSavePic()
return true;
}
void GameInterface::processSprites(spritetype* tsprite, int& spritesortcnt, int viewx, int viewy, int viewz, binangle viewang, double smoothRatio)
void GameInterface::processSprites(tspritetype* tsprite, int& spritesortcnt, int viewx, int viewy, int viewz, binangle viewang, double smoothRatio)
{
fi.animatesprites(tsprite, spritesortcnt, viewx, viewy, viewang.asbuild(), int(smoothRatio));
}

View file

@ -232,7 +232,7 @@ void AIAnim::Draw(RunListEvent* ev)
int nIndex2 = pActor->nIndex2;
seq_PlotSequence(ev->nParam, nIndex2, pActor->nIndex, 0x101);
ev->pTSprite->owner = -1;
ev->pTSprite->ownerActor = nullptr;
}
void BuildExplosion(DExhumedActor* pActor)

View file

@ -113,7 +113,7 @@ void AIBubble::Draw(RunListEvent* ev)
if (!pActor) return;
seq_PlotSequence(ev->nParam, pActor->nIndex, pActor->nFrame, 1);
ev->pTSprite->owner = -1;
ev->pTSprite->ownerActor = nullptr;
}

View file

@ -871,7 +871,7 @@ void AIBullet::Draw(RunListEvent* ev)
else
{
seq_PlotSequence(ev->nParam, nSeq, BulletList[nBullet].nFrame, 0);
ev->pTSprite->owner = -1;
ev->pTSprite->ownerActor = nullptr;
}
}

View file

@ -240,7 +240,7 @@ struct GameInterface : public ::GameInterface
int chaseCamX(binangle ang) { return -(ang.bcos() * 3) >> 5; }
int chaseCamY(binangle ang) { return -(ang.bsin() * 3) >> 5; }
int chaseCamZ(fixedhoriz horiz) { return (horiz.asq16() * 3) >> 10; }
void processSprites(spritetype* tsprite, int& spritesortcnt, int viewx, int viewy, int viewz, binangle viewang, double smoothRatio) override;
void processSprites(tspritetype* tsprite, int& spritesortcnt, int viewx, int viewy, int viewz, binangle viewang, double smoothRatio) override;
int GetCurrentSkill() override;
::GameStats getStats() override;

View file

@ -244,7 +244,7 @@ void AIFish::Draw(RunListEvent* ev)
int nAction = pActor->nAction;
seq_PlotSequence(ev->nParam, SeqOffsets[kSeqFish] + FishSeq[nAction].a, pActor->nFrame, FishSeq[nAction].b);
ev->pTSprite->owner = -1;
ev->pTSprite->ownerActor = nullptr;
return;
}

View file

@ -167,7 +167,7 @@ void AILavaDude::Draw(RunListEvent* ev)
int nSeq = LavadudeSeq[nAction].a + SeqOffsets[kSeqLavag];
seq_PlotSequence(ev->nParam, nSeq, pActor->nFrame, LavadudeSeq[nAction].b);
ev->pTSprite->owner = -1;
ev->pTSprite->ownerActor = nullptr;
return;
}

View file

@ -294,7 +294,7 @@ void AIRa::Draw(RunListEvent* ev)
int nSeq = SeqOffsets[kSeqEyeHit] + RaSeq[Ra[nPlayer].nAction].a;
seq_PlotSequence(ev->nParam, nSeq, Ra[nPlayer].nFrame, 1);
ev->pTSprite->owner = -1;
ev->pTSprite->ownerActor = nullptr;
}

View file

@ -561,7 +561,7 @@ int seq_PlotSequence(int nSprite, int16_t edx, int16_t nFrame, int16_t ecx)
esi += edx;
int var_14 = edx + 1;
int16_t nOwner = pTSprite->owner;
auto pOwner = pTSprite->ownerActor;
while (1)
{
@ -573,17 +573,18 @@ int seq_PlotSequence(int nSprite, int16_t edx, int16_t nFrame, int16_t ecx)
}
tspriteptr_t tsp = &mytsprite[(*myspritesortcnt)++];
tsp->x = pTSprite->x;
tsp->y = pTSprite->y;
tsp->z = pTSprite->z;
tsp->shade = shade;
tsp->pal = pTSprite->pal;
tsp->x = pTSprite->x;
tsp->y = pTSprite->y;
tsp->z = pTSprite->z;
tsp->shade = shade;
tsp->pal = pTSprite->pal;
tsp->xrepeat = pTSprite->xrepeat;
tsp->yrepeat = pTSprite->yrepeat;
tsp->ang = pTSprite->ang;
tsp->owner = pTSprite->owner;
tsp->ang = pTSprite->ang;
tsp->ownerActor = pTSprite->ownerActor;
tsp->sectnum = pTSprite->sectnum;
tsp->cstat = pTSprite->cstat |= 0x80;
tsp->cstat2 = pTSprite->cstat2;
tsp->statnum = esi;
if (ChunkFlag[nBase] & 1)
@ -602,9 +603,9 @@ int seq_PlotSequence(int nSprite, int16_t edx, int16_t nFrame, int16_t ecx)
nBase++;
}
if (!(pTSprite->cstat & 0x101) || (sprite[nOwner].statnum == 100 && nNetPlayerCount))
if (!(pTSprite->cstat & 0x101) || (pOwner->s().statnum == 100 && nNetPlayerCount))
{
pTSprite->owner = -1;
pTSprite->ownerActor = nullptr;
}
else
{
@ -612,7 +613,7 @@ int seq_PlotSequence(int nSprite, int16_t edx, int16_t nFrame, int16_t ecx)
int nFloorZ = pSector->floorz;
if (nFloorZ <= PlayerList[nLocalPlayer].eyelevel + initz) {
pTSprite->owner = -1;
pTSprite->ownerActor = nullptr;
}
else
{

View file

@ -406,7 +406,7 @@ void AISnake::Draw(RunListEvent* ev)
seq_PlotSequence(nSprite, SeqOffsets[kSeqSnakBody], 0, 0);
}
ev->pTSprite->owner = -1;
ev->pTSprite->ownerActor = nullptr;
}
END_PS_NS

View file

@ -64,11 +64,11 @@ DExhumedActor* pEnemy;
int nEnemyPal = 0;
// We cannot drag these through the entire event system... :(
spritetype* mytsprite;
tspritetype* mytsprite;
int* myspritesortcnt;
// NOTE - not to be confused with Ken's analyzesprites()
static void analyzesprites(spritetype* tsprite, int& spritesortcnt, int x, int y, int z, double const smoothratio)
static void analyzesprites(tspritetype* tsprite, int& spritesortcnt, int x, int y, int z, double const smoothratio)
{
tspritetype *pTSprite;
@ -78,7 +78,7 @@ static void analyzesprites(spritetype* tsprite, int& spritesortcnt, int x, int y
for (int i = 0; i < spritesortcnt; i++) {
pTSprite = &tsprite[i];
if (pTSprite->owner != -1)
if (pTSprite->ownerActor)
{
// interpolate sprite position
pTSprite->pos = pTSprite->interpolatedvec3(smoothratio);
@ -105,8 +105,7 @@ static void analyzesprites(spritetype* tsprite, int& spritesortcnt, int x, int y
for (nTSprite = spritesortcnt-1, pTSprite = &tsprite[nTSprite]; nTSprite >= 0; nTSprite--, pTSprite--)
{
int nSprite = pTSprite->owner;
auto pActor = &exhumedActors[nSprite];
auto pActor = static_cast<DExhumedActor*>(pTSprite->ownerActor);
spritetype *pSprite = &pActor->s();
if (pTSprite->sector() != nullptr)
@ -471,7 +470,7 @@ bool GameInterface::GenerateSavePic()
return true;
}
void GameInterface::processSprites(spritetype* tsprite, int& spritesortcnt, int viewx, int viewy, int viewz, binangle viewang, double smoothRatio)
void GameInterface::processSprites(tspritetype* tsprite, int& spritesortcnt, int viewx, int viewy, int viewz, binangle viewang, double smoothRatio)
{
analyzesprites(tsprite, spritesortcnt, viewx, viewy, viewz, smoothRatio);
}

View file

@ -40,7 +40,7 @@ extern bool bTouchFloor;
extern int nChunkTotal;
extern int gFov;
extern spritetype* mytsprite;
extern tspritetype* mytsprite;
extern int* myspritesortcnt;
END_PS_NS

View file

@ -1158,8 +1158,6 @@ void BunnyHatch(DSWActor* actor)
auto actorNew = InsertActor(sp->sector(), STAT_DEFAULT);
np = &actorNew->s();
np->clear();
np->setsector(sp->sector());
np->statnum = STAT_DEFAULT;
np->x = sp->x;
np->y = sp->y;
np->z = sp->z;
@ -1223,8 +1221,6 @@ DSWActor* BunnyHatch2(DSWActor* actor)
auto actorNew = InsertActor(wp->sector(), STAT_DEFAULT);
auto np = &actorNew->s();
np->clear();
np->setsector(wp->sector());
np->statnum = STAT_DEFAULT;
np->x = wp->x;
np->y = wp->y;
np->z = wp->z;

View file

@ -70,7 +70,6 @@ extern int f_c;
extern ParentalStruct aVoxelArray[MAXTILES];
DSWActor* ConnectCopySprite(spritetype const * tsp);
void PreDrawStackedWater(void);
void SW_InitMultiPsky(void)
@ -99,14 +98,14 @@ ShadeSprite(tspriteptr_t tsp)
#endif
int GetRotation(spritetype* tsprite, int& spritesortcnt, int tSpriteNum, int viewx, int viewy)
int GetRotation(tspritetype* tsprite, int& spritesortcnt, int tSpriteNum, int viewx, int viewy)
{
static const uint8_t RotTable8[] = {0, 7, 6, 5, 4, 3, 2, 1};
static const uint8_t RotTable5[] = {0, 1, 2, 3, 4, 3, 2, 1};
int rotation;
tspriteptr_t tsp = &tsprite[tSpriteNum];
USERp tu = swActors[tsp->owner].u();
USERp tu = static_cast<DSWActor*>(tsp->ownerActor)->u();
int angle2;
if (tu->RotNum == 0)
@ -169,10 +168,10 @@ directions was not standardized.
*/
int SetActorRotation(spritetype* tsprite, int& spritesortcnt, int tSpriteNum, int viewx, int viewy)
int SetActorRotation(tspritetype* tsprite, int& spritesortcnt, int tSpriteNum, int viewx, int viewy)
{
tspriteptr_t tsp = &tsprite[tSpriteNum];
USERp tu = swActors[tsp->owner].u();
USERp tu = static_cast<DSWActor*>(tsp->ownerActor)->u();
int StateOffset, Rotation;
// don't modify ANY tu vars - back them up!
@ -206,7 +205,7 @@ int SetActorRotation(spritetype* tsprite, int& spritesortcnt, int tSpriteNum, in
int DoShadowFindGroundPoint(tspriteptr_t sp)
{
// USES TSPRITE !!!!!
USERp u = swActors[sp->owner].u();
USERp u = static_cast<DSWActor*>(sp->ownerActor)->u();
SPRITEp hsp;
Collision ceilhit, florhit;
int hiz, loz = u->loz;
@ -259,10 +258,10 @@ int DoShadowFindGroundPoint(tspriteptr_t sp)
}
void
DoShadows(spritetype* tsprite, int& spritesortcnt, tspriteptr_t tsp, int viewz, int camang)
DoShadows(tspritetype* tsprite, int& spritesortcnt, tspriteptr_t tsp, int viewz, int camang)
{
tspriteptr_t tSpr = &tsprite[spritesortcnt];
USERp tu = swActors[tsp->owner].u();
USERp tu = static_cast<DSWActor*>(tsp->ownerActor)->u();
int ground_dist = 0;
int view_dist = 0;
int loz;
@ -357,9 +356,9 @@ DoShadows(spritetype* tsprite, int& spritesortcnt, tspriteptr_t tsp, int viewz,
}
void
DoMotionBlur(spritetype* tsprite, int& spritesortcnt, tspritetype const * const tsp)
DoMotionBlur(tspritetype* tsprite, int& spritesortcnt, tspritetype const * const tsp)
{
USERp tu = swActors[tsp->owner].u();
USERp tu = static_cast<DSWActor*>(tsp->ownerActor)->u();
int nx,ny,nz = 0,dx,dy,dz;
int i, ang;
int xrepeat, yrepeat, repeat_adj = 0;
@ -444,7 +443,7 @@ void SetVoxelSprite(SPRITEp sp, int pic)
sp->picnum = pic;
}
void WarpCopySprite(spritetype* tsprite, int& spritesortcnt)
void WarpCopySprite(tspritetype* tsprite, int& spritesortcnt)
{
SPRITEp sp1, sp2, sp;
int spnum;
@ -480,7 +479,7 @@ void WarpCopySprite(spritetype* tsprite, int& spritesortcnt)
if (spit->picnum == ST1)
continue;
tspriteptr_t newTSpr = renderAddTSpriteFromSprite(tsprite, spritesortcnt, itActor2->GetSpriteIndex());
tspriteptr_t newTSpr = renderAddTsprite(tsprite, spritesortcnt, itActor2);
newTSpr->statnum = 0;
xoff = sp1->x - newTSpr->x;
@ -503,7 +502,7 @@ void WarpCopySprite(spritetype* tsprite, int& spritesortcnt)
if (spit->picnum == ST1)
continue;
tspriteptr_t newTSpr = renderAddTSpriteFromSprite(tsprite, spritesortcnt, itActor2->GetSpriteIndex());
tspriteptr_t newTSpr = renderAddTsprite(tsprite, spritesortcnt, itActor2);
newTSpr->statnum = 0;
xoff = sp2->x - newTSpr->x;
@ -543,7 +542,74 @@ void DoStarView(tspriteptr_t tsp, USERp tu, int viewz)
}
}
void analyzesprites(spritetype* tsprite, int& spritesortcnt, int viewx, int viewy, int viewz, int camang)
template<class sprt>
DSWActor* CopySprite(sprt const* tsp, sectortype* newsector)
{
SPRITEp sp;
auto actorNew = InsertActor(newsector, STAT_FAF_COPY);
sp = &actorNew->s();
sp->x = tsp->x;
sp->y = tsp->y;
sp->z = tsp->z;
sp->cstat = tsp->cstat;
sp->picnum = tsp->picnum;
sp->pal = tsp->pal;
sp->xrepeat = tsp->xrepeat;
sp->yrepeat = tsp->yrepeat;
sp->xoffset = tsp->xoffset;
sp->yoffset = tsp->yoffset;
sp->ang = tsp->ang;
sp->xvel = tsp->xvel;
sp->yvel = tsp->yvel;
sp->zvel = tsp->zvel;
sp->shade = tsp->shade;
RESET(sp->cstat, CSTAT_SPRITE_BLOCK | CSTAT_SPRITE_BLOCK_HITSCAN);
return actorNew;
}
template<class sprt>
DSWActor* ConnectCopySprite(sprt const* tsp)
{
sectortype* newsector;
int testz;
if (FAF_ConnectCeiling(tsp->sector()))
{
newsector = tsp->sector();
testz = SPRITEp_TOS(tsp) - Z(10);
if (testz < tsp->sector()->ceilingz)
updatesectorz(tsp->x, tsp->y, testz, &newsector);
if (newsector != nullptr && newsector != tsp->sector())
{
return CopySprite(tsp, newsector);
}
}
if (FAF_ConnectFloor(tsp->sector()))
{
newsector = tsp->sector();
testz = SPRITEp_BOS(tsp) + Z(10);
if (testz > tsp->sector()->floorz)
updatesectorz(tsp->x, tsp->y, testz, &newsector);
if (newsector != nullptr && newsector != tsp->sector())
{
return CopySprite(tsp, newsector);
}
}
return nullptr;
}
void analyzesprites(tspritetype* tsprite, int& spritesortcnt, int viewx, int viewy, int viewz, int camang)
{
int tSpriteNum;
int smr4, smr2;
@ -562,9 +628,8 @@ void analyzesprites(spritetype* tsprite, int& spritesortcnt, int viewx, int view
for (tSpriteNum = spritesortcnt - 1; tSpriteNum >= 0; tSpriteNum--)
{
int SpriteNum = tsprite[tSpriteNum].owner;
auto tActor = &swActors[SpriteNum];
tspriteptr_t tsp = &tsprite[tSpriteNum];
auto tActor = static_cast<DSWActor*>(tsp->ownerActor);
tu = tActor->hasU()? tActor->u() : nullptr;
auto tsectp = tsp->sector();
@ -585,7 +650,7 @@ void analyzesprites(spritetype* tsprite, int& spritesortcnt, int viewx, int view
// don't draw these
if (tsp->statnum >= STAT_DONT_DRAW)
{
tsp->owner = -1;
tsp->ownerActor = nullptr;
continue;
}
@ -752,7 +817,7 @@ void analyzesprites(spritetype* tsprite, int& spritesortcnt, int viewx, int view
else
{
// dont draw your sprite
tsp->owner = -1;
tsp->ownerActor = nullptr;
//SET(tsp->cstat, CSTAT_SPRITE_INVISIBLE);
}
}
@ -767,7 +832,7 @@ void analyzesprites(spritetype* tsprite, int& spritesortcnt, int viewx, int view
}
}
if (OverlapDraw && FAF_ConnectArea(tsp->sector()) && tsp->owner >= 0)
if (OverlapDraw && FAF_ConnectArea(tsp->sector()) && tsp->ownerActor)
{
ConnectCopySprite(tsp);
}
@ -846,13 +911,13 @@ void analyzesprites(spritetype* tsprite, int& spritesortcnt, int viewx, int view
#if 1
tspriteptr_t get_tsprite(spritetype* tsprite, int& spritesortcnt, int SpriteNum)
tspriteptr_t get_tsprite(tspritetype* tsprite, int& spritesortcnt, DSWActor* actor)
{
int tSpriteNum;
for (tSpriteNum = spritesortcnt - 1; tSpriteNum >= 0; tSpriteNum--)
{
if (tsprite[tSpriteNum].owner == SpriteNum)
if (tsprite[tSpriteNum].ownerActor == actor)
return &tsprite[tSpriteNum];
}
@ -860,23 +925,23 @@ tspriteptr_t get_tsprite(spritetype* tsprite, int& spritesortcnt, int SpriteNum)
}
void
post_analyzesprites(spritetype* tsprite, int& spritesortcnt)
post_analyzesprites(tspritetype* tsprite, int& spritesortcnt)
{
int tSpriteNum;
USERp tu;
for (tSpriteNum = spritesortcnt - 1; tSpriteNum >= 0; tSpriteNum--)
{
int SpriteNum = tsprite[tSpriteNum].owner;
if (SpriteNum < 0) continue; // JBF: verify this is safe
auto actor = static_cast<DSWActor*>(tsprite[tSpriteNum].ownerActor);
if (!actor) continue; // JBF: verify this is safe
tspriteptr_t tsp = &tsprite[tSpriteNum];
tu = swActors[SpriteNum].u();
if (tu)
if (actor->hasU())
{
tu = actor->u();
if (tu->ID == FIREBALL_FLAMES && tu->attachActor != nullptr)
{
tspriteptr_t const atsp = get_tsprite(tsprite, spritesortcnt, tu->attachActor->GetSpriteIndex());
tspriteptr_t const atsp = get_tsprite(tsprite, spritesortcnt, tu->attachActor);
if (!atsp)
{
@ -1216,71 +1281,6 @@ PostDraw(void)
}
}
DSWActor* CopySprite(spritetype const * tsp, sectortype* newsector)
{
SPRITEp sp;
auto actorNew = InsertActor(newsector, STAT_FAF_COPY);
sp = &actorNew->s();
sp->x = tsp->x;
sp->y = tsp->y;
sp->z = tsp->z;
sp->cstat = tsp->cstat;
sp->picnum = tsp->picnum;
sp->pal = tsp->pal;
sp->xrepeat = tsp->xrepeat;
sp->yrepeat = tsp->yrepeat;
sp->xoffset = tsp->xoffset;
sp->yoffset = tsp->yoffset;
sp->ang = tsp->ang;
sp->xvel = tsp->xvel;
sp->yvel = tsp->yvel;
sp->zvel = tsp->zvel;
sp->shade = tsp->shade;
RESET(sp->cstat, CSTAT_SPRITE_BLOCK|CSTAT_SPRITE_BLOCK_HITSCAN);
return actorNew;
}
DSWActor* ConnectCopySprite(spritetype const * tsp)
{
sectortype* newsector;
int testz;
if (FAF_ConnectCeiling(tsp->sector()))
{
newsector = tsp->sector();
testz = SPRITEp_TOS(tsp) - Z(10);
if (testz < tsp->sector()->ceilingz)
updatesectorz(tsp->x, tsp->y, testz, &newsector);
if (newsector != nullptr && newsector != tsp->sector())
{
return CopySprite(tsp, newsector);
}
}
if (FAF_ConnectFloor(tsp->sector()))
{
newsector = tsp->sector();
testz = SPRITEp_BOS(tsp) + Z(10);
if (testz > tsp->sector()->floorz)
updatesectorz(tsp->x, tsp->y, testz, &newsector);
if (newsector != nullptr && newsector != tsp->sector())
{
return CopySprite(tsp, newsector);
}
}
return nullptr;
}
void PreDrawStackedWater(void)
{
SWStatIterator it(STAT_CEILING_FLOOR_PIC_OVERRIDE);
@ -1303,7 +1303,7 @@ void PreDrawStackedWater(void)
if (u->xchange == -989898)
continue;
auto actorNew = ConnectCopySprite((spritetype const *)sp);
auto actorNew = ConnectCopySprite(sp);
if (actorNew != nullptr)
{
// spawn a user
@ -1863,7 +1863,7 @@ bool GameInterface::DrawAutomapPlayer(int mx, int my, int cposx, int cposy, int
return true;
}
void GameInterface::processSprites(spritetype* tsprite, int& spritesortcnt, int viewx, int viewy, int viewz, binangle viewang, double smoothRatio)
void GameInterface::processSprites(tspritetype* tsprite, int& spritesortcnt, int viewx, int viewy, int viewz, binangle viewang, double smoothRatio)
{
analyzesprites(tsprite, spritesortcnt, viewx, viewy, viewz, viewang.asbuild());
post_analyzesprites(tsprite, spritesortcnt);

View file

@ -253,6 +253,17 @@ inline int SPRITEp_SIZE_Z(const spritetype* sp)
return (tileHeight(sp->picnum) * sp->yrepeat) << 2;
}
inline int SPRITEp_SIZE_Y(const tspritetype* sp)
{
return MulScale(tileHeight(sp->picnum), sp->yrepeat, 6);
}
inline int SPRITEp_SIZE_Z(const tspritetype* sp)
{
return (tileHeight(sp->picnum) * sp->yrepeat) << 2;
}
// Given a z height and sprite return the correct y repeat value
inline int SPRITEp_SIZE_Z_2_YREPEAT(const spritetype* sp, int zh)
@ -267,11 +278,21 @@ inline int SPRITEp_SIZE_TOS(const spritetype* sp)
return (DIV2(SPRITEp_SIZE_Z(sp)) + (tileTopOffset(sp->picnum) << 8));
}
inline int SPRITEp_SIZE_TOS(const tspritetype* sp)
{
return (DIV2(SPRITEp_SIZE_Z(sp)) + (tileTopOffset(sp->picnum) << 8));
}
inline int SPRITEp_SIZE_BOS(const spritetype* sp)
{
return (DIV2(SPRITEp_SIZE_Z(sp)) - (tileTopOffset(sp->picnum) << 8));
}
inline int SPRITEp_SIZE_BOS(const tspritetype* sp)
{
return (DIV2(SPRITEp_SIZE_Z(sp)) - (tileTopOffset(sp->picnum) << 8));
}
// actual Z for TOS and BOS - handles both WYSIWYG and old style
#define SPRITEp_TOS(sp) (TEST((sp)->cstat, CSTAT_SPRITE_YCENTER) ? \
((sp)->z - SPRITEp_SIZE_TOS(sp)) : \
@ -2153,7 +2174,7 @@ struct GameInterface : public ::GameInterface
int chaseCamX(binangle ang) override { return -ang.bcos(-3); }
int chaseCamY(binangle ang) override { return -ang.bsin(-3); }
int chaseCamZ(fixedhoriz horiz) override { return horiz.asq16() >> 8; }
void processSprites(spritetype* tsprite, int& spritesortcnt, int viewx, int viewy, int viewz, binangle viewang, double smoothRatio) override;
void processSprites(tspritetype* tsprite, int& spritesortcnt, int viewx, int viewy, int viewz, binangle viewang, double smoothRatio) override;
void UpdateCameras(double smoothratio) override;
void EnterPortal(spritetype* viewer, int type) override;
void LeavePortal(spritetype* viewer, int type) override;

View file

@ -868,7 +868,7 @@ JAnalyzeSprites(tspriteptr_t tspr)
//if (bVoxelsOn)
if (r_voxels)
{
if (aVoxelArray[tspr->picnum].Voxel >= 0 && !(spriteext[tspr->owner].flags & SPREXT_NOTMD))
if (aVoxelArray[tspr->picnum].Voxel >= 0 && !(tspr->ownerActor->sx().flags & SPREXT_NOTMD))
{
// Turn on voxels
tspr->picnum = aVoxelArray[tspr->picnum].Voxel; // Get the voxel number
@ -881,7 +881,7 @@ JAnalyzeSprites(tspriteptr_t tspr)
{
case 764: // Gun barrel
if (!r_voxels || (spriteext[tspr->owner].flags & SPREXT_NOTMD))
if (!r_voxels || (tspr->ownerActor->sx().flags & SPREXT_NOTMD))
{
tspr->cstat |= 16;
break;

View file

@ -1220,8 +1220,6 @@ void RipperHatch(DSWActor* actor)
np = &actorNew->s();
np->clear();
ClearOwner(actorNew);
np->setsector(wp->sector());
np->statnum = STAT_DEFAULT;
np->x = wp->x;
np->y = wp->y;
np->z = wp->z;

View file

@ -1238,8 +1238,6 @@ void Ripper2Hatch(DSWActor* actor)
np = &actorNew->s();
np->clear();
ClearOwner(actorNew);
np->setsector(wp->sector());
np->statnum = STAT_DEFAULT;
np->x = wp->x;
np->y = wp->y;
np->z = wp->z;

View file

@ -775,10 +775,8 @@ void KillActor(DSWActor* actor)
soundEngine->RelinkSound(SOURCE_Actor, &actor->s(), nullptr, &pos);
deletesprite(actor->GetSpriteIndex());
// shred your garbage - but not statnum and sectnum, which the backend needs to manage the sprite.
// shred your garbage
sp->clear();
sp->statnum = MAXSTATUS;
sp->sectnum = MAXSECTORS;
// Kill references in all users - slow but unavoidable if we don't want the game to crash on stale pointers.
SWSpriteIterator it;