diff --git a/source/build/include/build.h b/source/build/include/build.h index 4861c3c7d..d272f168a 100644 --- a/source/build/include/build.h +++ b/source/build/include/build.h @@ -154,27 +154,6 @@ EXTERN int leveltimer; extern TArray sectorbackup; extern TArray 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]; diff --git a/source/build/include/buildtypes.h b/source/build/include/buildtypes.h index 24e13b915..eb4cfc39d 100644 --- a/source/build/include/buildtypes.h +++ b/source/build/include/buildtypes.h @@ -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 //////////////// diff --git a/source/build/include/polymost.h b/source/build/include/polymost.h index 8b8b2d9db..dfdd98375 100644 --- a/source/build/include/polymost.h +++ b/source/build/include/polymost.h @@ -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); diff --git a/source/build/src/engine.cpp b/source/build/src/engine.cpp index 5e82481ad..124d4002d 100644 --- a/source/build/src/engine.cpp +++ b/source/build/src/engine.cpp @@ -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)); diff --git a/source/build/src/engine_priv.h b/source/build/src/engine_priv.h index 4613b9fbb..3df72f31b 100644 --- a/source/build/src/engine_priv.h +++ b/source/build/src/engine_priv.h @@ -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) diff --git a/source/build/src/mdsprite.cpp b/source/build/src/mdsprite.cpp index 406c971c2..0e14ce075 100644 --- a/source/build/src/mdsprite.cpp +++ b/source/build/src/mdsprite.cpp @@ -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::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) diff --git a/source/build/src/polymost.cpp b/source/build/src/polymost.cpp index 10c1d6cbb..a7c3b064b 100644 --- a/source/build/src/polymost.cpp +++ b/source/build/src/polymost.cpp @@ -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); diff --git a/source/core/coreactor.h b/source/core/coreactor.h index 0793ce29e..f0e8ebbcc 100644 --- a/source/core/coreactor.h +++ b/source/core/coreactor.h @@ -327,3 +327,14 @@ inline int pushmove(vec3_t* const vect, sectortype** const sect, int32_t const w *sect = sectno == -1 ? nullptr : §or[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; +} + diff --git a/source/core/gamefuncs.cpp b/source/core/gamefuncs.cpp index 1780aef32..a529e8b25 100644 --- a/source/core/gamefuncs.cpp +++ b/source/core/gamefuncs.cpp @@ -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 +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); +} //========================================================================== // diff --git a/source/core/gamefuncs.h b/source/core/gamefuncs.h index 0b2f87f9b..fa65f5d77 100644 --- a/source/core/gamefuncs.h +++ b/source/core/gamefuncs.h @@ -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) diff --git a/source/core/gamestruct.h b/source/core/gamestruct.h index a682a21db..2b1aad6e5 100644 --- a/source/core/gamestruct.h +++ b/source/core/gamestruct.h @@ -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) {} diff --git a/source/core/maploader.cpp b/source/core/maploader.cpp index fbc0d5aaf..480f4f62c 100644 --- a/source/core/maploader.cpp +++ b/source/core/maploader.cpp @@ -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); diff --git a/source/core/rendering/scene/hw_bunchdrawer.cpp b/source/core/rendering/scene/hw_bunchdrawer.cpp index ea79b2b7e..03027697d 100644 --- a/source/core/rendering/scene/hw_bunchdrawer.cpp +++ b/source/core/rendering/scene/hw_bunchdrawer.cpp @@ -44,6 +44,7 @@ #include "mapinfo.h" #include "gamecontrol.h" #include "hw_sections.h" +#include "coreactor.h" extern TArray> 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; } } diff --git a/source/core/rendering/scene/hw_drawinfo.cpp b/source/core/rendering/scene/hw_drawinfo.cpp index 678008752..c3d8464cc 100644 --- a/source/core/rendering/scene/hw_drawinfo.cpp +++ b/source/core/rendering/scene/hw_drawinfo.cpp @@ -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 }; diff --git a/source/core/rendering/scene/hw_drawinfo.h b/source/core/rendering/scene/hw_drawinfo.h index 9e7995f0a..dc33cf645 100644 --- a/source/core/rendering/scene/hw_drawinfo.h +++ b/source/core/rendering/scene/hw_drawinfo.h @@ -108,7 +108,7 @@ struct HWDrawInfo FRenderViewpoint Viewpoint; HWViewpointUniforms VPUniforms; // per-viewpoint uniform state TArray Portals; - spritetype tsprite[MAXSPRITESONSCREEN]; + tspritetype tsprite[MAXSPRITESONSCREEN]; int spritesortcnt; // This is needed by the BSP traverser. diff --git a/source/core/rendering/scene/hw_drawstructs.h b/source/core/rendering/scene/hw_drawstructs.h index f6ff80e89..010cd5b1e 100644 --- a/source/core/rendering/scene/hw_drawstructs.h +++ b/source/core/rendering/scene/hw_drawstructs.h @@ -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; } //========================================================================== diff --git a/source/core/rendering/scene/hw_flats.cpp b/source/core/rendering/scene/hw_flats.cpp index b829a06a1..fb25260df 100644 --- a/source/core/rendering/scene/hw_flats.cpp +++ b/source/core/rendering/scene/hw_flats.cpp @@ -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); diff --git a/source/core/rendering/scene/hw_sprites.cpp b/source/core/rendering/scene/hw_sprites.cpp index ac2031b45..508b0c0fa 100644 --- a/source/core/rendering/scene/hw_sprites.cpp +++ b/source/core/rendering/scene/hw_sprites.cpp @@ -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); diff --git a/source/core/rendering/scene/hw_walls.cpp b/source/core/rendering/scene/hw_walls.cpp index ea5cd3c78..c4db42858 100644 --- a/source/core/rendering/scene/hw_walls.cpp +++ b/source/core/rendering/scene/hw_walls.cpp @@ -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; diff --git a/source/games/blood/src/_polymost.cpp b/source/games/blood/src/_polymost.cpp index 87e6024e7..26e36b8d7 100644 --- a/source/games/blood/src/_polymost.cpp +++ b/source/games/blood/src/_polymost.cpp @@ -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); diff --git a/source/games/blood/src/animatesprite.cpp b/source/games/blood/src/animatesprite.cpp index 50816e897..c5929841b 100644 --- a/source/games/blood/src/animatesprite.cpp +++ b/source/games/blood/src/animatesprite.cpp @@ -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(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(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)); } diff --git a/source/games/blood/src/blood.h b/source/games/blood/src/blood.h index de4f7038b..63fad4aac 100644 --- a/source/games/blood/src/blood.h +++ b/source/games/blood/src/blood.h @@ -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; diff --git a/source/games/blood/src/db.cpp b/source/games/blood/src/db.cpp index 073d56990..e2368e72d 100644 --- a/source/games/blood/src/db.cpp +++ b/source/games/blood/src/db.cpp @@ -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); diff --git a/source/games/blood/src/loadsave.cpp b/source/games/blood/src/loadsave.cpp index 212c3eb95..3cc5f96fd 100644 --- a/source/games/blood/src/loadsave.cpp +++ b/source/games/blood/src/loadsave.cpp @@ -751,7 +751,6 @@ void GameInterface::SerializeGameState(FSerializer& arc) viewSetErrorMessage(""); Net_ClearFifo(); paused = 0; - Polymost::Polymost_prepare_loadboard(); Mus_ResumeSaved(); } validateLinks(); diff --git a/source/games/blood/src/replace.cpp b/source/games/blood/src/replace.cpp index cfd1b4e08..a0dd38290 100644 --- a/source/games/blood/src/replace.cpp +++ b/source/games/blood/src/replace.cpp @@ -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; } diff --git a/source/games/blood/src/view.h b/source/games/blood/src/view.h index 87abfe03a..100407287 100644 --- a/source/games/blood/src/view.h +++ b/source/games/blood/src/view.h @@ -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); diff --git a/source/games/duke/src/animatesprites_d.cpp b/source/games/duke/src/animatesprites_d.cpp index 1f7d1ed3d..7048f5150 100644 --- a/source/games/duke/src/animatesprites_d.cpp +++ b/source/games/duke/src/animatesprites_d.cpp @@ -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(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(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) diff --git a/source/games/duke/src/animatesprites_r.cpp b/source/games/duke/src/animatesprites_r.cpp index 8df428988..802f810d9 100644 --- a/source/games/duke/src/animatesprites_r.cpp +++ b/source/games/duke/src/animatesprites_r.cpp @@ -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(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(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) diff --git a/source/games/duke/src/dispatch.cpp b/source/games/duke/src/dispatch.cpp index b740decb6..4087dde6d 100644 --- a/source/games/duke/src/dispatch.cpp +++ b/source/games/duke/src/dispatch.cpp @@ -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; diff --git a/source/games/duke/src/duke3d.h b/source/games/duke/src/duke3d.h index c36768701..c798f413a 100644 --- a/source/games/duke/src/duke3d.h +++ b/source/games/duke/src/duke3d.h @@ -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); }; diff --git a/source/games/duke/src/inlines.h b/source/games/duke/src/inlines.h index 9dc221612..19fe5e965 100644 --- a/source/games/duke/src/inlines.h +++ b/source/games/duke/src/inlines.h @@ -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; diff --git a/source/games/duke/src/render.cpp b/source/games/duke/src/render.cpp index 848fa1e0e..a320c027d 100644 --- a/source/games/duke/src/render.cpp +++ b/source/games/duke/src/render.cpp @@ -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)); } diff --git a/source/games/exhumed/src/anims.cpp b/source/games/exhumed/src/anims.cpp index af846c1eb..e8b1867e4 100644 --- a/source/games/exhumed/src/anims.cpp +++ b/source/games/exhumed/src/anims.cpp @@ -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) diff --git a/source/games/exhumed/src/bubbles.cpp b/source/games/exhumed/src/bubbles.cpp index c1ca7e4f3..1aad7a45d 100644 --- a/source/games/exhumed/src/bubbles.cpp +++ b/source/games/exhumed/src/bubbles.cpp @@ -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; } diff --git a/source/games/exhumed/src/bullet.cpp b/source/games/exhumed/src/bullet.cpp index 0fa270dd2..aa7072724 100644 --- a/source/games/exhumed/src/bullet.cpp +++ b/source/games/exhumed/src/bullet.cpp @@ -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; } } diff --git a/source/games/exhumed/src/exhumed.h b/source/games/exhumed/src/exhumed.h index 9f9ba48de..53881ca23 100644 --- a/source/games/exhumed/src/exhumed.h +++ b/source/games/exhumed/src/exhumed.h @@ -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; diff --git a/source/games/exhumed/src/fish.cpp b/source/games/exhumed/src/fish.cpp index 0e4371776..1359b43a0 100644 --- a/source/games/exhumed/src/fish.cpp +++ b/source/games/exhumed/src/fish.cpp @@ -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; } diff --git a/source/games/exhumed/src/lavadude.cpp b/source/games/exhumed/src/lavadude.cpp index 46643a47e..643ef91f7 100644 --- a/source/games/exhumed/src/lavadude.cpp +++ b/source/games/exhumed/src/lavadude.cpp @@ -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; } diff --git a/source/games/exhumed/src/ra.cpp b/source/games/exhumed/src/ra.cpp index 10e0a6921..4b4cbb39e 100644 --- a/source/games/exhumed/src/ra.cpp +++ b/source/games/exhumed/src/ra.cpp @@ -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; } diff --git a/source/games/exhumed/src/sequence.cpp b/source/games/exhumed/src/sequence.cpp index 4636b756e..66b07fe63 100644 --- a/source/games/exhumed/src/sequence.cpp +++ b/source/games/exhumed/src/sequence.cpp @@ -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 { diff --git a/source/games/exhumed/src/snake.cpp b/source/games/exhumed/src/snake.cpp index aaeb2dd62..1d4963c55 100644 --- a/source/games/exhumed/src/snake.cpp +++ b/source/games/exhumed/src/snake.cpp @@ -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 diff --git a/source/games/exhumed/src/view.cpp b/source/games/exhumed/src/view.cpp index 83a213795..7fe77dc04 100644 --- a/source/games/exhumed/src/view.cpp +++ b/source/games/exhumed/src/view.cpp @@ -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(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); } diff --git a/source/games/exhumed/src/view.h b/source/games/exhumed/src/view.h index da537671b..1feef03dc 100644 --- a/source/games/exhumed/src/view.h +++ b/source/games/exhumed/src/view.h @@ -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 diff --git a/source/games/sw/src/bunny.cpp b/source/games/sw/src/bunny.cpp index 17ad139be..2e766a839 100644 --- a/source/games/sw/src/bunny.cpp +++ b/source/games/sw/src/bunny.cpp @@ -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; diff --git a/source/games/sw/src/draw.cpp b/source/games/sw/src/draw.cpp index 1aa5de9d3..67514965c 100644 --- a/source/games/sw/src/draw.cpp +++ b/source/games/sw/src/draw.cpp @@ -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(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(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(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(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(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 +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 +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(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(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); diff --git a/source/games/sw/src/game.h b/source/games/sw/src/game.h index ea10f3702..d346ad967 100644 --- a/source/games/sw/src/game.h +++ b/source/games/sw/src/game.h @@ -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; diff --git a/source/games/sw/src/jsector.cpp b/source/games/sw/src/jsector.cpp index db2a92d93..19e1bdb94 100644 --- a/source/games/sw/src/jsector.cpp +++ b/source/games/sw/src/jsector.cpp @@ -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; diff --git a/source/games/sw/src/ripper.cpp b/source/games/sw/src/ripper.cpp index 6fc5a6ef7..b757bf7cf 100644 --- a/source/games/sw/src/ripper.cpp +++ b/source/games/sw/src/ripper.cpp @@ -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; diff --git a/source/games/sw/src/ripper2.cpp b/source/games/sw/src/ripper2.cpp index f720b1d7d..63cf0a4cb 100644 --- a/source/games/sw/src/ripper2.cpp +++ b/source/games/sw/src/ripper2.cpp @@ -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; diff --git a/source/games/sw/src/sprite.cpp b/source/games/sw/src/sprite.cpp index f854b57ef..ed3cc7e7e 100644 --- a/source/games/sw/src/sprite.cpp +++ b/source/games/sw/src/sprite.cpp @@ -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;